Quantum
  • Welcome to Quantum
  • Developer portal
    • Pricing
  • Self-Custody Infrastructure
    • Pincode Management
    • Private Key Management
  • Quickstart guide
  • Authentication
    • API Authentication
  • Faucets
  • Networks & URLs
  • Walletify Api
    • Overview
    • Getting started
    • User Management
    • Signing Methods
    • Testnet Assets
    • Basic Guides
      • Create a user
      • Retrieve a user
      • Update a user
      • Delete a user
      • Create a signing method
      • Update a signing method
      • Delete a signing method
      • Create a wallet
      • Retrieve wallet
      • Archive a wallet
      • Import a wallet
      • Export a wallet
      • Retrieve native balance
      • Retrieve ERC20 tokens
      • Retrieve NFTs
      • Transfer a native token
      • Transfer an ERC20 token
      • Transfer an NFT
      • Transfer a fungible token
      • Signatures
      • Read a contract
      • Execute a contract call
      • Get Transaction status
      • Resubmit a transaction
      • Get wallet events
      • Webhooks
    • Advanced Guides
      • Burn an NFT
      • Filter Spam NFTs
      • Filter NSFW NFTs
      • SWAP Token Pairs
      • Gasless/Meta Transactions
      • Sign RAW Transactions
      • Using Fiat Onramp with Walletify-API
      • Deploy an Ethereum contract
      • Integrate with WalletConnect
      • Set Up NFT Token Gating
      • Chain Specific Fields
      • Integrate with WalletConnect
      • Encrypted PIN Transfer
  • Nft Wizard Api
    • Overview
    • Getting started
    • Basic Guides
      • Get any NFT info
      • Get any NFT contract
      • Get NFTs by any wallet
      • Get wallets by any NFT
      • Create contract
      • Retrieve Contract
      • Delete Contract
      • Check Contract Status
      • Retrieve Contract Metadata
      • Update Contract Metadata
      • Create Token-type (NFT template)
      • Retrieve Token-type (NFT template)
      • Delete Token-type (NFT Template)
      • Check Token-type Status
      • Retrieve Token-type Metadata
      • Update Token-type Metadata
      • Mint an NFT
      • Batch Mint NFTs
      • Update NFT Metadata
      • Retrieve NFT Metadata
      • Add Audio to your NFTs
      • Add Video to your NFTs
      • Store NFT Media
      • Webhooks
    • Advanced Guides
      • Mass Minting
      • Speed Up Minting
      • Dynamic NFTs
      • Configure Royalties
      • Create Company Minter Wallet
      • Retrieve Company Minter Wallets
      • Store NFT Metadata on IPFS
      • View NFT on sandbox/testnet
    • NFT Configuration
      • Attributes
      • Animation & Media
      • Collection Info
      • Max Supply
      • Mint Number
      • Burnable
      • Metadata Storage
  • TMINTER API
    • Overview
    • Getting started
    • Basic Guide
      • Retrieve Any NFT Information
      • Retrieve NFT Contract Information
      • Retrieve NFTs by Wallet Address
      • Retrieve Wallets by NFT
      • Create a New NFT Contract
      • Retrieve a Contract
      • Delete a Contract
      • Check Contract Status
      • Retrieve Contract Metadata
      • Update Contract Metadata
      • Create Token-Type
      • Retrieve Token-Type
      • Delete Token-Type
      • Check Token-Type Status
      • Retrieve Token-Type Metadata
      • Update Token-Type Metadata
      • Mint a Single NFT
      • Batch Mint Multiple NFTs
      • Update NFT Metadata
      • Retrieve NFT Metadata
      • Add Audio to Your NFTs
      • Add Video to Your NFTs
      • Store NFT Media
      • Webhooks for NFT Events
    • Advance Guide
      • Dynamic NFT Creation
      • Token Economics and Supply Control
      • Advanced Minting: Royalty Distribution
      • Cross-Chain NFT Minting
      • NFT Sharding (Fractional Ownership)
      • Batch NFT Minting with Custom Metadata
      • Add Interactivity to NFTs
      • Advanced Media Integration: VR and AR
      • Webhook Triggers for Automated Processes
Powered by GitBook
On this page
  • What are Gasless/Meta transactions?
  • Prerequisites
  • Basic flow
  • The specifics
  1. Walletify Api
  2. Advanced Guides

Gasless/Meta Transactions

What are Gasless/Meta transactions?

Gasless or meta transactions are a way to handle transaction costs more simply for users who are not familiar with the technical details of the cryptocurrency world. In these transactions, someone else covers the transaction fees, making it more convenient for users. This helps create a smoother experience, especially for those who are new to the crypto world.

Gasless or Meta transactions allow a wallet to do contract executions on behalf of another wallet and (most importantly) thus pay that transaction's gas fee.

So for example if wallet-A owns an NFT, the owner of wallet-A could allow wallet-B to transfer that NFT to wherever necessary and let wallet-B pay for the gas fee.

🚧

The gasless/meta transactions are only supported for the following chains:

  • Polygon (MATIC)

  • Avalanche

  • Binance Smart Chain

  • Arbitrum

Terminologies Explained

  • User Wallet: The user wallet is the wallet associated with the end-user or the person who holds the NFT.

  • Payer Wallet: The wallet that pays for the transaction fees associated with the execution of a smart contract or a transaction on the blockchain.

  • from address: The public wallet address of the user wallet.

  • to address: The public wallet address where the NFT will be transferred to.

  • tokenId: The ID of the NFT that is to be transferred.

  • userAddress: The public wallet address of the user wallet.

Prerequisites

  • Meta transactions can only be used on contracts and thus cannot be used with native tokens (e.g. Ether, Matic, …)

  • The (token) contract needs an executeMetaTransaction (write) and a getNonce (read) function

Basic flow

  1. An EIP712 JSON document is generated specifying the contract, method, and parameters that are allowed to be executed on the user wallet’s behalf

  2. The user wallet signs this JSON document using our Widget or Wallet-API and supplies the signature to the owner of the payer wallet (gas fee payer)

  3. Using the payer wallet, the executeMetaTransaction function on the contract needs to be called supplying the signature of the EIP712 document

  4. The method specified in step 1 will be executed using the parameters also supplied in step 1 (The payer wallet pays for the GAS fees of the transaction)

An example of how this could look like for an NFT transfer:

📘

The specifics

1. Building the EIP712 JSON document

Below you can find an example of such an EIP712 document, calling safeTransferFrom on the contract 0x0096100f27d5ed9a3455b54af3934df07b58b506

JSON

{
  "types": {
    "EIP712Domain": [
      {
        "name": "name",
        "type": "string"
      },
      {
        "name": "version",
        "type": "string"
      },
      {
        "name": "verifyingContract",
        "type": "address"
      },
      {
        "name": "salt",
        "type": "bytes32"
      }
    ],
    "MetaTransaction": [
      {
        "name": "nonce",
        "type": "uint256"
      },
      {
        "name": "from",
        "type": "address"
      },
      {
        "name": "functionSignature",
        "type": "bytes"
      }
    ]
  },
  "domain": {
    "name": "Digimon",
    "version": "1",
    "verifyingContract": "0x0096100f27d5ed9a3455b54af3934df07b58b506",
    "salt": "0x0000000000000000000000000000000000000000000000000000000000013882"
  },
  "primaryType": "MetaTransaction",
  "message": {
    "nonce": 0,
    "from": "0xeB947ED047020F3C2982d35Ac2a8EbE8A7330282",
    "functionSignature": "0xf242432a000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a73302820000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad274050000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000"
  }
}

1.1 types

types is about defining the structure and data types of the document. This part you should take as is.

1.2 domain

domain is about describing the contract you want to interact with. Here are some customizations that need to be done:

Property
Description

name

The name of the (NFT) contract you want to interact with

version

This should always be 1

verifyingContract

The contract address you want to interact with e.g. the NFT contract address

salt

1.3 primaryType

primaryType needs to be MetaTransaction

1.4 message

message is about defining which contract call to execute and what parameters should be used.

Property
Description

nonce

This is a contract + wallet specific sequence number that needs to be fetched from the contract. This can be done by calling the getNonce(address user) function and supplying it with the wallet address that needs to sign the message (_user wallet_)

from

The address of the signer (_user wallet_)

functionSignature

The encoded function + parameters that need to be executed. This depends on which contract call you want to do. Below you will find a breakdown on how to build this signature for calling safeTransferFrom(address,address,uint256,uint256,bytes)

2. Building the functionSignature

The functionSignature defines what the signer allows to be executed by a third party. To explain how it is built we’ll work with an example:

JSON

0xf242432a000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a73302820000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad274050000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000

This is the functionSignature for safeTransferFrom(address,address,uint256,uint256,bytes) + input data and is build as follows:

functionSignature Part
Description
Example

Method ID

0xf242432a = ABI encoded signature for the function safeTransferFrom(address,address,uint256,uint256,bytes)

input data for each of the inputs of the function you want to call

These always need to be 64 chars long and to achieve this, they are pre-padded with 0 until 64 chars

  1. 000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a7330282: the “from address” (input 1) of the transfer (0x stripped). This is the user wallet, so wallet A

  2. 0000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad27405: the “to address” (input 2) of the transfer (0x stripped). Where the nft needs to go to, so wallet X

  3. 0000000000000000000000000000000000000000000000000000000000000065: the token id (input 3) that needs to be transferred as a hex value (101 dec = 65 hex)

  4. 0000000000000000000000000000000000000000000000000000000000000001: the amount of tokens (input 4) that need to be transferred. Also as a hex value, but that remains 1 in this case

  5. 00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000: empty calldata bytes (input 5)

Input data breakdown

In the below table, a breakdown is done of the input data section of the functionSignature, specifically for the safeTransferFrom(address,address,uint256,uint256,bytes)

Suppose we want to perform the function with the following parameters.

Send an NFT

  • from 0xeb947ed047020f3c2982d35ac2a8ebe8a7330282

  • to 0x8fe26c6ff544bee01f41e6f87e6d0ead0ad27405

  • tokenId 101

  • amount 1

This translates to the following input data breakdown:

Input
Input safeTransferFrom
Rule
functionSignature encoded

1

from address from = 0xeb947ed047020f3c2982d35ac2a8ebe8a7330282

0x stripped, zero left-padded until 64 chars

000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a7330282

2

to address to = 0x8fe26c6ff544bee01f41e6f87e6d0ead0ad27405

0x stripped, zero left-padded until 64 chars

0000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad27405

3

token id that needs to be transferred tokenId = 101

HEXdecimal encoded, zero lef-padded until 64 chars

0000000000000000000000000000000000000000000000000000000000000065

4

amount of tokens to be transferred amount = 1

HEXdecimal encoded, zero lef-padded until 64 chars

0000000000000000000000000000000000000000000000000000000000000001

5

calldata bytes

in this case a fixed stream (128 chars, notice the a in the middle)

00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000

Putting all of the above together we get the followingfunctionSignature (methodID and input data):

0xf242432a000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a73302820000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad274050000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000

📘

3. Signing the EIP712 JSON document

🚧

  • This has to be done by the user wallet!

  • Signing is done off chain, so no gas fee has to be paid.

4. Executing the transaction

🚧

This has to be done by the payer wallet (who will be paying for the gas fee)!

JSON

function executeMetaTransaction(
    address userAddress,
    bytes memory functionSignature,
    bytes32 sigR,
    bytes32 sigS,
    uint8 sigV
)

The executeMetaTransaction method looks like this:

Where:

  • userAddress = the address from which the transaction must appear to be originating. I.e. the address of the wallet that signed the EIP712 document (user wallet)

  • functionSignature = the functionSignature that was also included in the EIP712 document

  • sigR = the r value of the signature from step 2

  • sigS = the s value of the signature from step 2

  • sigV = the v value of the signature from step 2

📘

Note that the executeMetaTransaction function needs to be called on the specific smart contract, so the to in the transaction-execution should reflect the address of the relevant smart contract.

In our example we have to perform the following call:

HTTP

POST /api/transactions/execute
Parameter
Param Type
Value
Description
Example Value

Signing-Method

Header

id:value

id: This is the ID of the signing method value: This is the value of the signing method

756ae7a7-3713-43ee-9936-0dff50306488:123456

JSON

{
    "transactionRequest":
    {
        "type": "CONTRACT_EXECUTION",
        "functionName": "executeMetaTransaction",
        "value": 0.0,
        "inputs":
        [
            {
                "type": "address", // the from address
                "value": "0xeb947ed047020f3c2982d35ac2a8ebe8a7330282"
            },
            {
                "type": "bytes", // the functionSignature
                "value": "0xf242432a000000000000000000000000eb947ed047020f3c2982d35ac2a8ebe8a73302820000000000000000000000008fe26c6ff544bee01f41e6f87e6d0ead0ad274050000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000"
            },
            {
                "type": "bytes32",
                "value": "0xc469e9bdc3419aa6e6dac835e94c41f9deae82566fc0e4ecf80fa5c5f3eaa017"
            },
            {
                "type": "bytes32",
                "value": "0x3d01d29561920e8bb610cc6fc04f2e003f7bfb400e906d6605699b9377b425a5"
            },
            {
                "type": "uint8",
                "value": "0x1c"
            }
        ],
        "walletId": "252a4dab-2b98-4745-9c92-2d3fdef9b95e",
        "to": "0x88f9564d3894d66b4406c673b37bb8f91cce452f", // the contract address for which we want to do a safeTransferFrom
        "secretType": "MATIC"
    }
PreviousSWAP Token PairsNextSign RAW Transactions

Last updated 10 months ago

Execute Meta Transactions

View the for gasless/meta transaction.

The defines a way to structure a document that needs a signature in such a way that wallets can parse and show it in a readable way to their end users that need to sign.

The hex value of the chainId, left padded with 0 until its length equals 64 chars, then prepended with 0x. In this case 80002 = Polygon Amoy Testnet, an overview can be found at

This is the method ID of the function you want to call (ABI encoded function signature). You can get this in several ways, but to make it easy we’ve created a jsFiddle that can help you with that: . In the fiddle you can input your function signature e.g. safeTransferFrom(address,address,uint256,uint256,bytes) and it will return you the method ID (0xf242432a for the above).

All blockchain contracts are public. You can lookup the possible functions and their arguments through the relevant blockexplorers. For example, here you can find the contract code for our own Metaring collection (you will find the safeTransferFrom function inside this contract):

Signing the EIP712 JSON document can be done very easily either by using the or by using the .

After the user wallet has signed the EIP712 document, it needs to provide the signature to the payer wallet which can then use it as input to call the executeMetaTransaction method on the specific contract. Calling this is again easy using the or the .

code example
EIP712 standard
https://polygonscan.com/address/0xba8c3db050dd99cbe7f980f3d8f48084c6dcc20b/transactions#code
Venly API
Venly Widget
Venly API
Venly Widget
https://chainlist.org/
https://jsfiddle.net/nipee/sanjmtu7/
Execute Meta Transactions