Skip to content

Gas Sponsorship

The MemForks sponsor service covers all gas fees so developers can use MemForks on mainnet without holding any SUI.

It handles two distinct cases:

  • /drip — sends a small SUI amount to a fresh address during memfork init --quick so the two MemWal bootstrap transactions (account creation and delegate key registration) can self-pay gas. This is a one-time transfer.
  • /sponsor — co-signs all subsequent MemForks transactions (branch, commit, merge, etc.) so the user never needs gas again.

The user's address remains the transaction sender in both cases.

How It Works

Bootstrap drip (memfork init --quick)

Ongoing sponsorship

Service Setup

bash
cd services/sponsor
npm install
cp .env.example .env
npm start

Required environment:

VariableRequiredDefaultDescription
SPONSOR_PRIVATE_KEYYesSponsor wallet private key.
SUI_NETWORKYesmainnetmainnet, testnet, or devnet.
SUI_RPC_URLNoautoOverride RPC endpoint.
MEMFORK_PACKAGE_IDNoproduction IDAllowed MemForks Move package ID.
RATE_MAX_PER_WINNo10Max sponsored txs per sender per window.
RATE_WINDOW_MSNo60000Rate limit window in ms.
RATE_IP_MAX_PER_WINNo40Max txs per IP per window.
RATE_DAILY_MAX_TXNo5000Global daily transaction cap.
RATE_INIT_TREE_PER_IP_DAYNo1Max tree creations per IP per day.
SPONSOR_GAS_BUDGETNo90000000Gas budget per tx in MIST.
DRIP_AMOUNT_MISTNo20000000SUI sent per /drip (0.02 SUI).
DRIP_MIN_BALANCE_MISTNo5000000Skip drip if address already has this.
DRIP_IP_DAILY_MAXNo1Max drips per IP per 24 h.
PORTNo3100HTTP port.

API

Health

http
GET /health

Returns:

json
{ "ok": true, "network": "mainnet" }

Bootstrap Drip

http
POST /drip

Sends a small SUI amount to a fresh address so it can self-pay for the two MemWal bootstrap transactions during memfork init --quick. Called automatically by the CLI — you don't need to call this directly.

Request:

json
{ "address": "0x<new address>" }

Success (drip sent):

json
{ "digest": "<tx digest>", "amount": 20000000 }

Success (already funded, skipped):

json
{ "skipped": true, "message": "address already has sufficient balance", "balance": "25000000" }
StatusMeaning
429Rate limit: 1 drip per IP per 24 h.
500Sponsor wallet error.
http
POST /sponsor

Request:

json
{
  "tx": "<serialized Transaction string>",
  "sender": "0x<user address>"
}

Success:

json
{
  "txBytes": "<base64>",
  "sponsorSig": "<base64 signature>"
}

Common errors:

StatusMeaning
400Invalid transaction or disallowed package call.
429Sender exceeded rate limit.
503Sponsor gas pool unavailable.

Configure The SDK

The CLI sets this automatically. For SDK usage in your own app:

bash
export MEMFORK_SPONSOR_URL=https://memforks-sponsor-production.up.railway.app/sponsor

Or explicitly in code:

ts
const client = await MemForksClient.connect({
  treeId,
  signer,
  memwal,
  sponsorUrl: "https://memforks-sponsor-production.up.railway.app/sponsor",
});

TIP

MEMFORK_SPONSOR_URL must point to the full /sponsor endpoint path. The SDK POSTs directly to the URL with no path appended.

Funding The Sponsor

Each MemForks transaction is small, but high-concurrency services should pre-split SUI into multiple gas coins to avoid contention.

bash
sui client split-coin \
  --coin-id <COIN_ID> \
  --amounts 20000000 20000000 20000000 \
  --gas-budget 10000000

Deployment Notes

  • The service is stateless.
  • Deploy on Railway, Fly.io, a VPS, or any Node.js host.
  • Keep SPONSOR_PRIVATE_KEY in a secret manager.
  • Use an external rate limiter such as Redis if you scale horizontally.
  • Restrict sponsored calls to the expected MemForks package.

Built on MemWal, Walrus, and Sui.