-
Sender signs a
DelegateAction(their actions + nonce +maxBlockHeight) withnear.signDelegate— offline-friendly, no gas. -
Relayer wraps it in an ordinary transaction and broadcasts it with
near.relayDelegate, paying the gas from a full-access key. -
Everything out is a decimal string:
nonceandmaxBlockHeightare strings, andborshBase64is the signed delegate a relayer transports.
Sign now, let a relayer pay the gas.
A NEP-366 meta-transaction lets one account sign a delegate action while a
different account broadcasts it and pays the gas. With @fastnear/api
you sign the delegate from a local key — no wallet — and hand the result to any relayer. The
sender needs a key, but not a yoctoNEAR of balance.
near.signDelegate signs with a local key and never opens a wallet. The
nonce comes from the sender's access key; maxBlockHeight defaults to the
final block height plus blockHeightTtl.
import * as near from "@fastnear/api";
import { signerFromPrivateKey } from "@fastnear/utils";
// The sender holds a key but shouldn't pay gas.
const signed = await near.signDelegate({
signerId: "alice.near",
signer: signerFromPrivateKey(alicePrivateKey),
receiverId: "guest-book.near",
actions: [
near.actions.functionCall({
methodName: "add_message",
args: { text: "gasless hello" },
gas: "30 Tgas",
deposit: "0",
}),
],
blockHeightTtl: 600,
});
// nonce + maxBlockHeight are decimal strings; borshBase64 is what a relayer sends.
near.print(signed.delegateAction);
A relayer pays and sends.
near.relayDelegate wraps the signed delegate in an ordinary transaction sent to
the delegate's sender, signed and paid for by a full-access relayer key. Or POST
signed.borshBase64 to a remote relayer service — the delegate is
self-contained.
Pass a full-access relayerSigner/relayerId to pay the gas from
a different account. The relayer never learns the sender's key.
// A relayer with a full-access key broadcasts it and pays the gas.
const result = await near.relayDelegate({
delegateAction: signed.delegateAction,
signature: signed.signatureBytes,
relayerSigner: signerFromPrivateKey(relayerPrivateKey),
relayerId: "relayer.near",
waitUntil: "FINAL",
});
near.print(result);
-
Server / agent:
near.signDelegatesigns with a local key — this page. -
Browser wallet:
nearWallet.signDelegateActionsasks the connected wallet to sign instead. Same NEP-366 delegate, but it comes back asborshSerializedBase64only — hand those bytes to a relayer that speaks raw NEP-366.near.relayDelegatetakes the structured{ delegateAction, signature }thatnear.signDelegatereturns. -
Either way the relayer pays; the sender authorizes the exact actions and a
maxBlockHeightdeadline.
AI agents:
recipes.json
carries the sign-delegate-local recipe (local key) and
sign-delegate-actions (wallet). Preview the wrapped actions first with
near.explain.tx. Rate-limited? Free trial
credits are at
dashboard.fastnear.com.