Transfers

The transfer system allows you to send tokens to other addresses. You can transfer tokens using a saved beneficiary or by using a recipient's nickname. This guide covers how to create transfers, including balance validation, fee calculation, and transaction signing.

Overview

The transfer system provides two ways to send tokens:

  • Transfer to Beneficiary - Transfer to a saved beneficiary address
  • Transfer to Nickname - Transfer to another user by their nickname

Both methods include:

  • Balance Validation - Ensures you have sufficient balance
  • Fee Calculation - Automatically calculates and deducts fees
  • Transaction Signing - Returns signature data for transaction execution
  • Gas Fee Handling - Gas fees are deducted from the transfer amount

Prerequisites

Before making transfers, ensure you have:

  • Completed authentication and have a valid access token
  • Created a wallet
  • Have sufficient balance for the transfer amount plus fees
  • For beneficiary transfers: Created at least one beneficiary
  • For nickname transfers: The recipient must have a nickname and wallet

Transfer to Beneficiary

Transfer tokens to a saved beneficiary address. This method uses a beneficiary ID that you've previously created.

Transfer to beneficiary

curl -X POST https://api.example.com/api/transfer \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: {tenant-id}" \
  -d '{
    "amount": "1.0",
    "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "beneficiaryId": "beneficiary-id",
    "chainId": 137
  }'

Required Fields:

  • amount - Amount to transfer (humanized format, e.g., "1.0" for 1 token)
  • token - Token contract address
  • beneficiaryId - ID of the saved beneficiary
  • chainId - Chain ID where the transfer will occur (e.g., 137 for Polygon)

Response:

{
  "status": 200,
  "message": "Transfer created successfully",
  "data": {
    "transfer": {
      "userOperationHash": "0xabcdef1234567890...",
      "payGasFeeToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "amount": "1.0",
      "walletAddress": "0x1234...",
      "toAddress": "0x5678...",
      "chainId": 137,
      "gasFeePaymentMethod": "DEDUCT_FROM_AMOUNT",
      "transactionFeePercent": 0.5
    },
    "signature": {
      "signature": "0x...",
      "message": "..."
    }
  }
}

Response Fields:

  • transfer - Transfer details including user operation hash
  • signature - Signature data needed to execute the transaction
  • userOperationHash - Hash of the user operation (for account abstraction)

Transfer to Nickname

Transfer tokens to another user by their nickname. This is useful for sending tokens to users without needing their wallet address.

Transfer to nickname

curl -X POST https://api.example.com/api/transfer/nickname \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: {tenant-id}" \
  -d '{
    "amount": "1.0",
    "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "nicknameToTransfer": "johndoe",
    "chainId": 137
  }'

Required Fields:

  • amount - Amount to transfer (humanized format, e.g., "1.0" for 1 token)
  • token - Token contract address
  • nicknameToTransfer - Nickname of the recipient
  • chainId - Chain ID where the transfer will occur

Response:

{
  "status": 200,
  "message": "Transfer created successfully",
  "data": {
    "transfer": {
      "userOperationHash": "0xabcdef1234567890...",
      "payGasFeeToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "amount": "1.0",
      "walletAddress": "0x1234...",
      "toAddress": "0x5678...",
      "chainId": 137,
      "gasFeePaymentMethod": "DEDUCT_FROM_AMOUNT",
      "transactionFeePercent": 0.5
    },
    "signature": {
      "signature": "0x...",
      "message": "..."
    }
  }
}

Amount Format

The amount field should be provided in humanized format (decimal number as string). The API automatically converts the humanized amount to the token's smallest unit based on the token's decimals:

  • ETH and most tokens: Provide amount as decimal (e.g., "1.0" for 1 ETH, "0.5" for 0.5 ETH)
  • USDC/USDT: Provide amount as decimal (e.g., "1000.0" for 1000 USDC)
  • Other tokens: Provide amount as decimal string

Examples:

  • 1 ETH = "1.0"
  • 1000 USDC = "1000.0"
  • 0.5 ETH = "0.5"

Supported Chains

The system supports transfers on various EVM-compatible chains. Common chain IDs:

  • Polygon: 137
  • Ethereum Mainnet: 1
  • BSC: 56
  • Arbitrum: 42161
  • Optimism: 10

Check the tokens list to see which chains are supported for each token.

Fee Structure

Transfers include two types of fees:

  1. Transaction Fee - A percentage fee deducted from the transfer amount

    • Regular transfers: Uses TRANSFER_FEE_PERCENTAGE
    • Nickname transfers: Uses TRANSFER_NICKNAME_FEE_PERCENTAGE
    • Fee percentage is configurable per tenant
  2. Gas Fee - Network gas fees for executing the transaction

    • Payment method: DEDUCT_FROM_AMOUNT (deducted from transfer amount)
    • Paid in the same token as the transfer

Example: If transferring 1000 tokens with a 0.5% fee:

  • Transaction fee: 5 tokens
  • Gas fee: Variable (depends on network conditions)
  • Recipient receives: ~995 tokens minus gas

Balance Validation

Before creating a transfer, the system validates:

  1. Wallet Exists - Your wallet must be created
  2. Sufficient Balance - You must have enough tokens for:
    • Transfer amount
    • Transaction fee
    • Gas fee

If balance is insufficient, the transfer will be rejected.

Transaction Signing

After creating a transfer, you receive signature data that must be used to execute the transaction. The signature is generated using your wallet's private key through the signing service.

The signature includes:

  • signature - The cryptographic signature
  • message - The message that was signed

Note: The transfer is not executed automatically. You need to use the signature data to complete the transaction on-chain.

Error Handling

Wallet Not Found

{
  "status": 404,
  "message": "Wallet not found"
}

This error occurs when you haven't created a wallet yet.

Beneficiary Not Found

{
  "status": 404,
  "message": "Beneficiary not found"
}

This error occurs when the beneficiary ID doesn't exist or doesn't belong to you.

Invalid Wallet Address

{
  "status": 400,
  "message": "Wallet address must be a valid EVM address"
}

This error occurs when the beneficiary address format is invalid.

Invalid Chain

{
  "status": 400,
  "message": "Invalid chain"
}

This error occurs when the chainId is not supported.

Token Not Found

{
  "status": 404,
  "message": "Token in not found on the list"
}

This error occurs when the token address is not supported on the specified chain.

Insufficient Balance

{
  "status": 400,
  "message": "Insufficient balance to transfer"
}

This error occurs when you don't have enough balance for the transfer amount plus fees.

Nickname Not Found

{
  "status": 404,
  "message": "Nickname not found"
}

This error occurs when transferring to a nickname that doesn't exist.

Cannot Transfer to Yourself

{
  "status": 400,
  "message": "You cannot transfer to yourself"
}

This error occurs when trying to transfer to your own nickname.

Recipient Wallet Not Found

{
  "status": 404,
  "message": "Wallet to transfer not found"
}

This error occurs when the recipient hasn't created a wallet yet.

Error Getting User Operation Hash

{
  "status": 500,
  "message": "Error getting user operation hash"
}

This error occurs when there's an issue creating the transfer operation.

Error Signing Transaction

{
  "status": 500,
  "message": "Error signing transaction"
}

This error occurs when there's an issue generating the transaction signature.

Complete Flow Example

Here's a complete example of making a transfer:

# 1. Create wallet (if not already created)
curl -X POST https://api.example.com/api/wallet \
  -H "Authorization: Bearer {access_token}" \
  -H "x-tenant-id: {tenant-id}"

# 2. Create beneficiary (for beneficiary transfer)
curl -X POST https://api.example.com/api/beneficiary/onchain \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: {tenant-id}" \
  -d '{
    "address": "0x9876543210987654321098765432109876543210",
    "network": "EVM",
    "name": "Recipient Wallet"
  }'

# 3. Transfer to beneficiary
curl -X POST https://api.example.com/api/transfer \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: {tenant-id}" \
  -d '{
    "amount": "1.0",
    "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "beneficiaryId": "beneficiary-id-from-step-2",
    "chainId": 137
  }'

# Alternative: Transfer to nickname
curl -X POST https://api.example.com/api/transfer/nickname \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: {tenant-id}" \
  -d '{
    "amount": "1.0",
    "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "nicknameToTransfer": "johndoe",
    "chainId": 137
  }'

Important Notes

  1. Account Abstraction: Transfers use account abstraction technology, which means transactions are executed through user operations rather than traditional transactions.

  2. Balance Requirements: Make sure you have sufficient balance for the transfer amount plus all fees. The system checks balance before creating the transfer.

  3. Fee Deduction: Both transaction fees and gas fees are deducted from the transfer amount. The recipient receives the amount minus these fees.

  4. Token Validation: Only tokens that are in the supported tokens list can be transferred. Make sure the token address and chain ID combination is valid.

  5. Beneficiary Validation: When using beneficiary transfers, the beneficiary must exist and belong to your account. The beneficiary address must be a valid EVM address.

  6. Nickname Validation: When transferring to a nickname, the recipient must:

    • Have created a nickname
    • Have created a wallet
    • Not be yourself
  7. Transaction Execution: The transfer endpoint creates the transfer and returns signature data. You need to use this signature to execute the transaction on-chain. The transfer is not automatically executed.

  8. Gas Fee Payment: Gas fees are paid using the same token as the transfer (payGasFeeToken). The payment method is DEDUCT_FROM_AMOUNT, meaning gas is deducted from the transfer amount.

  9. User Operation Hash: The userOperationHash is used to track the transaction in account abstraction systems. You'll need this for transaction status queries.

  10. Metadata: Transfer metadata includes beneficiary information (ID, name, address, network) for tracking and auditing purposes.

  11. Chain Compatibility: Both transfer methods work on EVM-compatible chains. Make sure the chain ID matches a supported chain.

  12. Amount Format: Always provide amounts in humanized format (decimal string). The API automatically handles conversion to the token's smallest unit based on token decimals.

Security Considerations

  1. Verify Recipients: Always verify beneficiary addresses and nicknames before transferring large amounts.

  2. Test Transfers: Consider making a small test transfer first to verify everything works correctly.

  3. Monitor Balances: Keep track of your balances to ensure you have enough for transfers and fees.

  4. Transaction Fees: Be aware that fees reduce the amount received by the recipient.

  5. Network Conditions: Gas fees vary based on network congestion. Consider network conditions when making transfers.

  6. Signature Security: The signature data is sensitive. Handle it securely and use it only to execute the intended transaction.

Was this page helpful?