1.0.17 • Published 7 months ago

@blockend/compass-sdk v1.0.17

Weekly downloads
-
License
ISC
Repository
-
Last release
7 months ago

Compass SDK

Compass SDK is a powerful cross-chain transaction SDK that provides a unified liquidity layer by aggregating multiple liquidity sources across blockchain networks. It seamlessly integrates DEXs (Decentralized Exchanges), Cross-chain Bridges, RFQ (Request for Quote) systems, and Intent Protocols into a single, reliable interface. This enables developers to easily implement cross-chain token swaps, transfers, and complex DeFi operations across EVM chains, Solana, and Cosmos ecosystems.

The SDK automatically optimizes routes for the best rates and lowest fees by splitting transactions across multiple liquidity sources, handling complex cross-chain operations, and managing transaction sequences. It provides real-time price quotes, gas estimations, and transaction status tracking while abstracting away the complexity of cross-chain interactions.

Features

  • Cross-chain token swaps and transfers with optimal routing
  • Unified access to multiple liquidity sources:
    • DEXs (Uniswap, PancakeSwap, etc.)
    • Cross-chain bridges (Wormhole, LayerZero, etc.)
    • RFQ systems for better pricing on large trades
    • Intent Protocols for complex DeFi operations
  • Support for multiple blockchain networks:
    • EVM chains (Ethereum, BSC, Polygon, etc.)
    • Solana
    • Cosmos ecosystem
  • Real-time transaction status tracking and notifications
  • Comprehensive token and chain information with metadata
  • Advanced gas fee estimation and optimization
  • Built-in caching system for improved performance
  • Flexible configuration options for different environments
  • Robust error handling and transaction recovery

Installation

npm install @blockend/compass-sdk
# or
yarn add @blockend/compass-sdk

Quick Start

import { initializeSDK, getQuotes, executeTransaction, createTransaction, getNextTxn, checkStatus } from "@blockend/compass-sdk";

// Initialize the SDK with your API key
initializeSDK({
  apiKey: "YOUR_API_KEY",
  integratorId: "YOUR_INTEGRATOR_ID",
});

// Get quotes for a token swap
const quotes = await getQuotes({
  fromChainId: "137",
  fromAssetAddress: "0x...",
  toChainId: "sol",
  toAssetAddress: "...",
  inputAmount: "1000000000000000000", // Amount in wei
  inputAmountDisplay: "1.0", // Human readable amount
  userWalletAddress: "0x...",
  recipient: "0x...",
});

// Execute the transaction with the best quote
const result = await executeTransaction({
  quote: quotes.data.quotes[0],
  provider: ethersProvider, // For EVM chains
  walletAdapter: solanaWallet, // For Solana
  cosmosClient: cosmosClient, // For Cosmos
  onStatusUpdate: (status, data) => {
    console.log(`Transaction status: ${status}`, data);
  },
});

// Check transaction status, poll the status until the status is "success" or "failed" or "partial-success". "in-progress" means the transaction is still being processed.
const status = await checkStatus({
  routeId: transaction.routeId,
  stepId: transaction.steps[0].id,
  txnHash: result.hash,
});

See checkStatus example implementation using while loop below.

API Reference

Configuration

initializeSDK(config)

Initialize the SDK with your credentials and configuration.

initializeSDK({
  apiKey: string;
  integratorId: string;
  baseURL?: string;
  enableCache?: boolean;
  cacheTimeout:number;
});

To get config, use the getConfig() method.

const config = getConfig();

To update config, use the updateConfig() method. You can update one or more parameters mentioned in the Configuration Parameters section.

updateConfig({
  apiKey: "YOUR_API_KEY",
});

Configuration Parameters

apiKey (required)

  • Your unique API key for authentication with the Blockend API
  • Must be obtained through the Blockend platform
  • Used to track API usage and enforce rate limits

integratorId (required)

  • A unique identifier for your integration/application
  • Used for analytics, tracking, and support purposes
  • Helps identify your specific implementation when interacting with Blockend services

errorHandler (optional)

  • A callback function to handle SDK errors globally
  • Receives a BlockendError object with properties:
    • message: Description of the error
    • code: Error code (e.g., "CONFIGURATION_ERROR", "NETWORK_ERROR", "VALIDATION_ERROR")
    • data: Additional error context (if available)
  • Useful for centralized error handling, logging, and error reporting
  • Example usage:
initializeSDK({
  apiKey: "YOUR_API_KEY",
  integratorId: "YOUR_INTEGRATOR_ID",
  errorHandler: (error) => {
    console.error(`[Compass SDK Error] ${error.code}: ${error.message}`, error.data);
    // Custom error handling logic (e.g., reporting to monitoring service)
  },
});

baseURL (optional)

  • The base URL endpoint for the Blockend API
  • Defaults to https://api2.blockend.com/v1
  • Can be modified for different environments (staging, testing, etc.)
  • Should include the version prefix (/v1)

enableCache (optional)

  • Boolean flag to enable/disable SDK's built-in caching mechanism
  • When enabled, caches API responses to reduce network requests
  • Particularly useful for frequently accessed data like token lists and chain information
  • Defaults to false if not specified

cacheTimeout (optional)

  • Duration in milliseconds for how long cached items should remain valid
  • Only applies when enableCache is true
  • Defaults to 1 hour (3600000 milliseconds)
  • Can be adjusted based on your application's needs and data freshness requirements

Core Methods

getQuotes

Gets quotes for cross-chain token swaps or transfers by aggregating liquidity from multiple sources including DEXs, Bridges, RFQs, and Intent Protocols.

interface QuoteParams {
  // Chain ID of the source blockchain (e.g., "ethereum", "solana", "bsc")
  fromChainId: string;

  // Token contract address on source chain (use native token address for chain's native currency)
  fromAssetAddress: string;

  // Chain ID of the destination blockchain
  toChainId: string;

  // Token contract address on destination chain
  toAssetAddress: string;

  // Amount in smallest unit (wei, lamports, etc.)
  inputAmount: string;

  // Human readable amount (e.g., "1.0" ETH)
  inputAmountDisplay: string;

  // Source wallet address that will initiate the transaction
  userWalletAddress: string;

  // Optional: Destination wallet address (defaults to userWalletAddress if not specified)
  recipient?: string;

  // Optional: Solana priority fee in lamports or predefined level ("LOW" | "MEDIUM" | "HIGH")
  solanaPriorityFee?: number | PriorityLevel;

  // Optional: Solana Jito MEV tip in lamports or predefined level
  solanaJitoTip?: number | PriorityLevel;

  // Optional: EVM priority fee in gwei or predefined level
  evmPriorityFee?: number | PriorityLevel;

  // Optional: Maximum allowed slippage in BPS (default: 50)
  slippage?: number;

  // Optional: Skip certain validation checks for faster response
  skipChecks?: boolean;

  // Optional: Comma-separated list of preferred liquidity sources
  include?: string;

  // Optional: Comma-separated list of liquidity sources to exclude
  exclude?: string;

  // Optional: Use recommended liquidity provider
  recommendedProvider?: boolean;

  // Optional: To get gasless (approval + swap) transaction quotes.
  gasless?:boolean;

  // Optional: To  get  gasless transaction for swaps, but approvals may or may not require gas.
  gaslessSwap:boolean;

  // Optional: To set fee in BPS
  feeBps: number | string;
}

//Example implementation
const quotes = await getQuotes({
  fromChainId: "137",
  fromAssetAddress: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
  toChainId: "137",
  toAssetAddress: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f.",
  inputAmountDisplay: "1.0",
  userWalletAddress: "0x...",
  recipient: "0x...",
});

// Example Response (shortened)
{
  "status": "success",
  "data": {
    "quotes": [{
      "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
      "from": {
        "chainId": "1",
        "symbol": "ETH",
        // ... other token details
      },
      "to": {
        "chainId": "sol",
        "symbol": "USDC",
        // ... other token details
      },
      "outputAmountDisplay": "1459.244847",
      "estimatedTimeInSeconds": 900
    }]
  }
}

View full quotes response example

createTransaction(params)

Creates a transaction from a selected quote, preparing all necessary steps for the cross-chain transfer.

interface CreateTransactionParams {
  // Route ID obtained from getQuotes response
  routeId: string;
}

//Example implementation
const transaction = await createTransaction({
  routeId: quotes.data.quotes[0].routeId,
});

// Example Response (shortened)
{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "steps": [{
      "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
      "stepType": "bridge",
      "chainId": "1"
    }]
  }
}

View full createTransaction response example

getNextTxn(params)

Retrieves the raw transaction data for the next pending step in the transaction sequence. The response format varies based on the blockchain network:

interface TransactionDataParams {
  routeId: string; // Route ID from createTransaction
  stepId: string; // Step ID from the transaction steps array
}

//Example implementation
const nextTxn = await getNextTxn({
  routeId: transaction.routeId,
  stepId: transaction.steps[0].id,
});

// Example Response (shortened)
{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
    "networkType": "evm",
    "txnData": {
      "txnType": "on-chain" | "sign-typed" | "sign-untyped"
      "txnEvm": {
        "to": "0x...",
        "value": "420000000000000000",
        // ... other transaction details
      }
    }
  }
}

Transaction Types

The SDK supports multiple transaction types that are automatically handled based on the protocol and requirements:

  1. On-chain Transactions (txnType: "on-chain"):

    • Regular blockchain transactions that require gas fees
    • Used for standard token transfers and swaps
    // Example response for on-chain transaction
    {
      "txnType": "on-chain",
      "txnEvm": {
        "from": "0x17e7c3DD600529F34eFA1310f00996709FfA8d5c",
        "to": "0x1234567890abcdef1234567890abcdef12345678",
        "value": "420000000000000000",
        "data": "0x095ea7b3...",
        "gasPrice": "30000000000",
        "gasLimit": "250000"
      }
    }
    
    // Execute using wagmi/viem
    import { getWalletClient } from "wagmi";
    const client = await getWalletClient();
    const hash = await client.sendTransaction({
      to: txnEvm.to as `0x${string}`,
      data: txnEvm.data as `0x${string}`,
      value: BigInt(txnEvm.value),
      gas: BigInt(txnEvm.gasLimit),
      gasPrice: BigInt(txnEvm.gasPrice),
    });
    
    // Execute using ethers.js
    import { BrowserProvider } from "ethers";
    const provider = new BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    const transaction = await signer.sendTransaction({
      from: txnEvm.from,
      to: txnEvm.to,
      data: txnEvm.data,
      gasLimit: txnEvm.gasLimit,
      gasPrice: txnEvm.gasPrice,
      value: txnEvm.value,
    });
    const hash = transaction.hash;
  2. EIP-712 Typed Data Signing (txnType: "sign-typed"):

    • Implements EIP-712 for structured data signing on EVM chains
    • Used for permit-style approvals and meta-transactions (for gasless)
    // Example response for typed data signing
    {
      "txnType": "sign-typed",
      "txnEvm": {
        "domain": {
          "name": "Permit2",
          "version": "1",
          "chainId": 1,
          "verifyingContract": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
        },
        "types": {
          "PermitSingle": [
            { "name": "details", "type": "PermitDetails" },
            { "name": "spender", "type": "address" },
            { "name": "sigDeadline", "type": "uint256" }
          ],
          "PermitDetails": [
            { "name": "token", "type": "address" },
            { "name": "amount", "type": "uint160" },
            { "name": "expiration", "type": "uint48" },
            { "name": "nonce", "type": "uint48" }
          ]
        },
        "message": {
          "details": {
            "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
            "amount": "1461501637330902918203684832716283019655932542975",
            "expiration": "1747836789",
            "nonce": "0"
          },
          "spender": "0x1234567890123456789012345678901234567890",
          "sigDeadline": "1747836789"
        },
        "primaryType": "PermitSingle"
      }
    }
    
    // Execute using wagmi/viem
    import { getWalletClient } from "wagmi";
    const client = await getWalletClient();
    const signature = await client.signTypedData({
      account, // userWalletAddress
      domain: txnEvm.domain,
      types: txnEvm.types,
      primaryType: txnEvm.primaryType,
      message: txnEvm.message,
    });
    
    // Execute using ethers.js
    import { BrowserProvider } from "ethers";
    const provider = new BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    // Remove EIP712Domain from types before signing
    delete txnEvm.types.EIP712Domain;
    const signature = await signer.signTypedData(
      txnEvm.domain,
      {
        [txnEvm.primaryType]: txnEvm.types[txnEvm.primaryType],
        ...txnEvm.types,
      },
      txnEvm.message
    );
  3. Untyped Message Signing (txnType: "sign-untyped"):

    • Used for protocols like Meson.fi that require message signing
    • Supports cross-chain message verification
    // Example response for untyped message signing
    {
      "txnType": "sign-untyped",
      "txnEvm": {
        "message": "0x1901c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f4fc3",
      }
    }
    
    // Execute using wagmi/viem
    import { getWalletClient } from "wagmi";
    const client = await getWalletClient();
    const signature = await client.request({
      method: "personal_sign",
      params: [txnEvm.message, account],
    });
    
    // Execute using ethers.js
    import { BrowserProvider } from "ethers";
    const provider = new BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    const signature = await provider.send("personal_sign", [
      txnEvm.message,
      account,
    ]);

The transaction type is automatically determined based on the quote and protocol being used. The SDK handles all the necessary signing logic internally, including:

  • Proper formatting of typed and untyped data
  • Chain-specific signature requirements
  • Protocol-specific message formatting
  • Gasless transaction handling

Transaction Data Response Examples

Send txnEvm or txnSol or txnCosmos to the appropriate wallet/provider based on the networkType and get the transaction hash to monitor the status of the transaction.

EVM Chain Response

{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
    "networkType": "evm",
    "txnData": {
      "txnEvm": {
        "from": "0x17e7c3DD600529F34eFA1310f00996709FfA8d5c",
        "to": "0x1234567890abcdef1234567890abcdef12345678",
        "value": "420000000000000000",
        "data": "0x095ea7b3...",
        "gasPrice": "30000000000",
        "gasLimit": "250000"
      }
    }
  }
}

Solana Chain Response

{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
    "networkType": "sol",
    "txnData": {
      "txnSol": {
        "data": "base64EncodedTransactionData...",
      }
    }
  }
}

Cosmos Chain Response

{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
    "networkType": "cosmos",
    "txnData": {
      "txnCosmos": {
        "data": "{"typeUrl":"/ibc.applications.trans"}",
        "value": "0",
        "gasLimit": "250000",
        "gasPrice": "0.025",
      }
    }
  }
}

View full getNextTxn response example

checkStatus(params)

Monitors the status of a transaction step, providing detailed information about its progress.

interface StatusCheckParams {
  // Route ID of the transaction
  routeId: string;

  // Step ID being checked
  stepId: string;

  // Transaction hash from the blockchain
  txnHash: string;
}

//Example implementation
const status = await checkStatus({
  routeId: transaction.routeId,
  stepId: transaction.steps[0].id,
  txnHash: result.hash,
});

// Example Response (shortened)
{
  "status": "success",
  "data": {
    "status": "success",
    "outputAmount": "1459244847",
    "outputAmountDisplay": "1459.244847"
  }
}
type TransactionStatus = "not-started" | "in-progress" | "success" | "failed";

See checkStatus example implementation using while loop below.

View full checkStatus response example

Here's a simpler example to poll the transaction status:

async function pollWithWhileLoop(routeId: string, stepId: string, txnHash: string) {
  const POLLING_INTERVAL = 3000; // 3 seconds
  const MAX_ATTEMPTS = 200; // Maximum number of attempts (10 minutes with 3s interval)
  let attempts = 0;

  while (attempts < MAX_ATTEMPTS) {
    try {
      const response = await checkStatus({ routeId, stepId, txnHash });
      const status = response.data.status;

      console.log(`Current status: ${status}`);

      if (["success", "failed", "partial-success"].includes(status)) {
        return response.data;
      }

      // Wait for the polling interval
      await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL));
      attempts++;
    } catch (error) {
      console.error("Error checking status:", error);
      throw error;
    }
  }

  throw new Error("Polling timeout: Maximum attempts reached");
}

// Usage example:
try {
  const result = await pollWithWhileLoop("your-route-id", "your-step-id", "your-transaction-hash");
  console.log("Final result:", result);
} catch (error) {
  console.error("Polling failed:", error);
}

pollTransactionStatus(params)

Continuously monitors a transaction's status by polling at regular intervals until a final state is reached or timeout occurs. This method provides a convenient way to track cross-chain transactions through their entire lifecycle.

interface PollTransactionStatusParams {
  // Route ID of the transaction
  routeId: string;

  // Step ID being monitored
  stepId: string;

  // Transaction hash from the blockchain
  txnHash: string;

  // Optional: Interval between status checks in milliseconds (default: 2000ms)
  pollingIntervalMs?: number;

  // Optional: Maximum time to poll before timing out in milliseconds (default: 600000ms / 10 minutes)
  timeoutMs?: number;

  // Optional: Callback function for real-time status updates
  onStatusUpdate?: (status: TransactionStatus, data?: ExecuteTransactionResult) => void;
}

// Example usage:
const result = await pollTransactionStatus({
  routeId: "your-route-id",
  stepId: "your-step-id",
  txnHash: "your-transaction-hash",
  pollingIntervalMs: 3000, // Poll every 3 seconds, by default it's 2 seconds
  timeoutMs: 300000, // Timeout after 5 minutes, by default it's 10 minutes
  onStatusUpdate: (status, data) => {
    console.log(`Transaction status updated: ${status}`);
    if (data) {
      console.log("Transaction data:", data);
    }
  },
});

// Example Response
{
  "status": "success",
  "data": {
    "status": "success",
    "outputAmount": "1459244847",
    "outputAmountDisplay": "1459.244847",
    "srcTxnHash": "0x...",
    "dstTxnHash": "0x...",
  "srcTxnUrl": "https://etherscan.io/tx/0x...",
  "dstTxnUrl": "https://etherscan.io/tx/0x...",
  "points": 100,
  "warnings": [],
  }
}

The method will continue polling until one of these conditions is met:

  • Transaction reaches a final status ("success", "failed", or "partial-success")
  • Polling timeout is reached
  • An error occurs during status checking

Status Types:

  • "not-started": Transaction has not been initiated
  • "in-progress": Transaction is being processed
  • "success": Transaction completed successfully
  • "failed": Transaction failed
  • "partial-success": Transaction partially succeeded (some steps completed)

Error Handling:

  • Throws a timeout error if timeoutMs is exceeded
  • Throws any errors encountered during status checking
  • Provides detailed error information through the BlockendError class

Best Practices:

  1. Set appropriate pollingIntervalMs based on chain block times
  2. Configure reasonable timeoutMs for your use case
  3. Implement proper error handling
  4. Use the onStatusUpdate callback for real-time UI updates

executeQuote(params)

Executes a complete transaction flow based on a quote, handling all necessary steps including approvals, swaps, and bridges.

interface ExecuteTransactionParams {
  quote: Quote;
  provider?: Provider | WalletClient;
  walletAdapter?: WalletAdapter;
  cosmosClient?: SigningStargateClient | SigningCosmWasmClient;
  solanaRpcUrl?: string;
  onStatusUpdate?: (status: TransactionStatus, data?: ExecuteTransactionResult) => void;
  onCreateTxComplete?: (tx: CreateTransactionResponse) => void;
  onNextTxComplete?: (tx: TransactionDataResponse) => void;
  onSignComplete?: (txDetail: { stepId: string; txHash: string }) => void;
}

interface ExecuteTransactionResult {
  routeId: string;
  status: TransactionStatus;
  srcTxnHash?: string;
  srcTxnUrl?: string;
  destTxnHash?: string;
  destTxnUrl?: string;
  outputAmount: string;
  outputToken: Token;
  warnings?: string[];
  points?: number;
}

// Example implementation
const result = await executeQuote({
  quote: quotes.data.quotes[0],
  provider: ethersProvider, // For EVM chains
  walletAdapter: solanaWallet, // For Solana
  cosmosClient: cosmosClient, // For Cosmos
  onStatusUpdate: (status, data) => {
    console.log(`Transaction status: ${status}`, data);
  },
  onCreateTxComplete: (tx) => {
    console.log("Transaction created:", tx);
  },
  onNextTxComplete: (tx) => {
    console.log("Next transaction data:", tx);
  },
  onSignComplete: (txDetail) => {
    console.log("Transaction signed:", txDetail);
  },
});

executeTransaction(params)

Executes a single transaction step with the provided transaction data. This method is used internally by executeQuote but can also be used directly for more granular control over transaction execution.

interface ExecuteTransactionParams {
  txDataResponse: TransactionDataResponse;
  quote: Quote;
  step: TransactionStep;
  provider: BrowserProvider | WalletClient;
  walletAdapter: WalletAdapter;
  cosmosClient: SigningStargateClient | SigningCosmWasmClient;
  solanaRpcUrl?: string;
}

const txnResponse = await getNextTxn({
  routeId: quote.routeId,
  stepId: step.stepId,
});
// Example implementation
const txHash = await executeTransaction({
  txDataResponse,
  quote,
  step,
  provider: ethersProvider,
  walletAdapter: solanaWallet,
  cosmosClient: cosmosClient,
  solanaRpcUrl: "https://api.mainnet-beta.solana.com",
});

The method handles different transaction types based on the network:

  • For EVM chains: Supports regular transactions, EIP-712 typed data signing, and untyped message signing
  • For Solana: Handles Solana-specific transaction formats
  • For Cosmos: Manages Cosmos SDK transaction types

The method returns the transaction hash of the executed transaction, which can be used to monitor its status using checkStatus or pollTransactionStatus.

Advanced Transaction Features

Gasless Transactions

The SDK supports gasless transactions through two options in the QuoteParams:

interface QuoteParams {
  // ... other params ...

  // Optional: Get fully gasless transactions (both approval and swap)
  gasless?: boolean;

  // Optional: Get gasless swap transactions (approvals may still require gas)
  gaslessSwap?: boolean;
}

Example of requesting a gasless quote:

const gaslessQuote = await getQuotes({
  fromChainId: "137",
  fromAssetAddress: "0x...",
  toChainId: "1",
  toAssetAddress: "0x...",
  inputAmount: "1000000000000000000",
  inputAmountDisplay: "1.0",
  userWalletAddress: "0x...",
  gasless: true, // Enable gasless(approval+swap) transactions
  gaslessSwap: true, // Enable gasless atleast for swaps and approval may or not be gasless based on the tokens selected
});

Example response for a gasless quote:

{
  "status": "success",
  "data": {
    "quotes": [{
      "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
      "from": {
        "chainId": "137",
        "symbol": "MATIC",
        "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
        "decimals": 18,
        "name": "Polygon",
        "blockchain": "Polygon",
        "isNative": true
      },
      "to": {
        "chainId": "1",
        "symbol": "USDC",
        "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "decimals": 6,
        "name": "USD Coin",
        "blockchain": "Ethereum"
      },
      "steps": [{
        "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
        "stepType": "swap",
        "protocolsUsed": ["uniswap-v3"],
        "provider": "uniswap",
        "gasless": true, // Indicates this step is gasless
        "from": {
          // Token details same as above
        },
        "to": {
          // Token details same as above
        },
        "fee": [{
          "name": "Protocol Fee",
          "value": "0.3",
          "token": "MATIC"
        }],
        "inputAmount": "1000000000000000000",
        "outputAmount": "1459244847",
        "estimatedTimeInSeconds": 300
      }],
      "outputAmountDisplay": "1.459244847",
      "outputAmount": "1459244847",
      "estimatedTimeInSeconds": 300,
      "fee": [{
        "name": "Protocol Fee",
        "value": "0.3",
        "token": "MATIC"
      }],
      "gasless": true // Indicates the entire route is gasless
    }]
  }
}

Example response for a gasless create transaction:

{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "steps": [{
      "stepId": "01J2WB1NY64MKVCM8FM994WMZV",
      "stepType": "approval",
      "protocolsUsed": ["permit2"],
      "provider": "permit2",
      "gasless": true,
      "chainId": "137"
    },
    {
      "stepId": "01J2WB1NY64MKVCM8FM994WMZW",
      "stepType": "swap",
      "protocolsUsed": ["uniswap-v3"],
      "provider": "uniswap",
      "gasless": true,
      "chainId": "137"
    }]
  }
}

Example response for a gasless transaction step (swap):

{
  "status": "success",
  "data": {
    "routeId": "01J2WB1NY6MD3F25CJTTB01D8F",
    "stepId": "01J2WB1NY64MKVCM8FM994WMZW",
    "networkType": "evm",
    "txnData": {
      "txnType": "sign-typed",
      "txnEvm": {
        "domain": {
          "name": "Gasless Swap",
          "version": "1",
          "chainId": 137,
          "verifyingContract": "0x9876543210987654321098765432109876543210"
        },
        "types": {
          "MetaTransaction": [
            { "name": "from", "type": "address" },
            { "name": "to", "type": "address" },
            { "name": "value", "type": "uint256" },
            { "name": "nonce", "type": "uint256" },
            { "name": "deadline", "type": "uint256" }
          ]
        },
        "message": {
          "from": "0x17e7c3DD600529F34eFA1310f00996709FfA8d5c",
          "to": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
          "value": "1000000000000000000",
          "nonce": "1",
          "deadline": "1747836789"
        },
        "primaryType": "MetaTransaction"
      }
    },
    "gasless": true
  }
}

Example code to execute a gasless transaction :

// wagami / viem
import { getWalletClient } from "wagmi";
import { config } from "./config";

const client = getWalletClient(config);
const signature = await client.signTypedData({
  account, // userWalletAddress
  domain,
  types,
  primaryType,
  message,
});

// Ethers
import { BrowserProvider } from "ethers";
const provider = new BrowserProvider(window.ethereum);
//make sure the wallet is connected before executing this step
delete types.EIP712Domain;
const signer = await provider.getSigner();
const signature = await signer.signTypedData(
  domain,
  {
    [primaryType]: types[primaryType],
    ...types,
  },
  message
);

Token and Chain Information

getTokens(chainId?)

Get a list of supported tokens, optionally filtered by chain ID.

interface TokensParams {
  chainId?: string;
}

//Example implementation
const tokens = await getTokens();// to fetch all tokens from all chains
const tokens = await getTokens("1");// to fetch all tokens from chain 1

//Example response
{
  "status": "success",
  "data":{
    "1":[
      {
    "networkType": "evm",
    "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
    "chainId": "1",
    "blockchain": "Ethereum",
    "decimals": 18,
    "name": "Ethereum",
    "symbol": "ETH",
    "image": "https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1595348880",
    "lastPrice": 2703.62,
    "isEnabled": true,
    "isFlagged": false,
    "isNative": true,
    "isPopular": true
},
//other coins on chain 1
    ]
  }
}

getChains()

Get a list of supported blockchain networks.

interface Chain {
  id: string;
  name: string;
  networkType: "evm" | "sol" | "cosmos";
  nativeCurrency: {
    name: string;
    symbol: string;
    decimals: number;
  };
  blockExplorer: string;
  rpcUrls: string[];
}
//Example implementation
const chains = await getChains(); // to fetch all chains

//Example response
{
  "status": "success",
  "data": [
    {
  "chainId": "sol",
  "symbol": "sol",
  "name": "Solana",
  "networkType": "sol",
  "image": "https://assets.coingecko.com/coins/images/4128/large/solana.png?1696504756",
  "explorer": {
    "address": "https://solscan.io/account/{address}",
    "token": "https://solscan.io/token/{tokenAddress}",
    "txn": "https://solscan.io/tx/{txnHash}"
  },
  "isPopular": true,
  "tokenCount": 946,
  "isEnabled": true
},
//other supported chains
  ]
}

Error Handling

The SDK uses a custom BlockendError class for error handling. All errors will be instances of this class and include:

  • message: Human-readable error message
  • code: Error code for programmatic handling
  • data: Additional error context (if available)

Best Practices

  1. Always handle transaction status updates using the onStatusUpdate callback
  2. Implement proper error handling for failed transactions
  3. Use appropriate slippage tolerance for volatile tokens
  4. Cache chain and token information when possible
  5. Verify wallet connections before executing transactions
1.0.17

7 months ago

1.0.16

7 months ago

1.0.15

7 months ago

1.0.14

7 months ago

1.0.13

7 months ago

1.0.12

7 months ago

1.0.11

7 months ago

1.0.10

7 months ago

1.0.9

8 months ago

1.0.8

8 months ago

1.0.7

8 months ago

1.0.6

8 months ago

1.0.5

8 months ago

1.0.4

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

9 months ago

1.0.0

9 months ago