Skip to main content
Meta-transactions (NEP-366) allow a user to sign a transaction off-chain, which is then submitted and paid for by a separate “Relayer” account.

How it Works

  1. User (Client): Constructs a transaction and calls .delegate(). This returns a typed object (for UI/validation) and a serialized string (for transport).
  2. Transport: The user sends the serialized string (payload) to your backend.
  3. Relayer (Server): Your server decodes the payload back into an object, validates it, wraps it, and submits it.

1. Client Side: Signing the Action

On the frontend, use the .delegate() method. This works exactly like .send(), but implies no network activity and no gas cost for the signer. It returns two properties:
  • signedDelegateAction: The raw JS object. Useful for debugging or showing details in your UI.
  • payload: A Base64-encoded string. This is what you send to the server.

2. Server Side: The Relayer

The server receives the Base64 string (payload). It must decode this string back into a typed object to inspect it before submitting. Use near-kit’s decodeSignedDelegateAction helper for this.

Example: Express.js Route

Security Checklist

Running a relayer makes you a target.
  1. Whitelist Receivers: Always check userAction.delegateAction.receiverId.
  2. Whitelist Methods: Inspect userAction.delegateAction.actions to ensure users are only calling allowed methods (e.g., “move” vs “withdraw”).
  3. Rate Limiting: Rate limit your API endpoint to prevent draining your relayer’s funds.