# Rath Documentation (/) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Welcome to Rath Developer Docs [#welcome-to-rath-developer-docs] Rath is the universal liquidity and execution layer for modern DeFi applications. We provide high-performance rails for execution, routing, and yield—without deep protocol integrations. Get Started [#get-started] Choose what you want to build with: # Resources for AI Agents (/resources-for-ai-agents) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Fetch the complete documentation index at [https://docs.rath.fi/llms.txt](https://docs.rath.fi/llms.txt). Use this file to discover all available pages before exploring further. Resources for AI agents [#resources-for-ai-agents] Use this page as the starting point when you want an AI assistant to build with Rath infrastructure — Tachyon, Rath APIs, or xPath. It covers how to give an assistant Rath context through static docs files and recommended entry points for common workflows. Static docs files [#static-docs-files] Use these when you want to load context in a single fetch. Global (all products) [#global-all-products] | File | What it contains | When to use it | | ----------------------------------------------------- | --------------------------------------- | ------------------------------------------------ | | [`llms.txt`](https://docs.rath.fi/llms.txt) | Page index with titles and descriptions | Discovering which docs exist before going deeper | | [`llms-full.txt`](https://docs.rath.fi/llms-full.txt) | Complete documentation in one file | Giving an assistant broad context in one shot | Per-product [#per-product] Each product also exposes its own index and full-text files: | Product | Index | Full text | | --------- | --------------------------------------------------------------- | ------------------------------------------------------------------------- | | Tachyon | [`tachyon/llms.txt`](https://docs.rath.fi/tachyon/llms.txt) | [`tachyon/llms-full.txt`](https://docs.rath.fi/tachyon/llms-full.txt) | | Rath APIs | [`rathintro/llms.txt`](https://docs.rath.fi/rathintro/llms.txt) | [`rathintro/llms-full.txt`](https://docs.rath.fi/rathintro/llms-full.txt) | | xPath | [`xPath/llms.txt`](https://docs.rath.fi/xPath/llms.txt) | [`xPath/llms-full.txt`](https://docs.rath.fi/xPath/llms-full.txt) | Individual pages [#individual-pages] Every docs page is also available as plain Markdown. Use the `/llms/page/` prefix with slugs joined by `--`: ```txt https://docs.rath.fi/llms/page/tachyon--quickstart.mdx https://docs.rath.fi/llms/page/tachyon--core-concepts.mdx ``` Recommended starting points [#recommended-starting-points] Once your agent has docs context, point it at the section that matches what you're building: | What you're doing | Start here | | ---------------------------------- | ----------------------------------------------------------- | | Understanding Rath's product suite | [Rath Documentation](/index) | | Getting started with Tachyon | [Tachyon Quickstart](/tachyon/quickstart) | | Learning Tachyon concepts | [Core Concepts](/tachyon/core-concepts) | | Relaying a transaction | [Relay a Transaction](/tachyon/how-to-guides/relay-tx) | | Making a contract call | [Contract Call Guide](/tachyon/how-to-guides/contract-call) | | Setting up webhooks or websockets | [Register Webhook](/tachyon/how-to-guides/register-webhook) | | Batching multiple transactions | [Batch Transactions](/tachyon/features/batch_transactions) | | Using EIP-7702 delegation | [EIP-7702](/tachyon/features/eip-7702) | | Checking supported chains | [Supported Networks](/tachyon/supported-networks) | | Using the Tachyon SDK | [Tachyon SDK Reference](/tachyon/tachyon-sdk) | | Using the Tachyon REST API | [Tachyon API Reference](/tachyon/tachyon-api) | # Rath APIs (Coming Soon) (/rathintro) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Rath APIs (Coming Soon) [#rath-apis-coming-soon] Welcome to the official Rath Docs. Rath is the universal liquidity auction protocol enabling wallets, fintechs, and consumer apps to natively integrate DeFi yield without direct protocol integrations. Overview [#overview] Rath introduces a competitive auction-based liquidity layer that allows any frontend to tap into DeFi strategies for their users' assets — no vaults, no custody, no manual bridging. Our architecture integrates: * Real-time yield bidding engine * Support for EIP-7702 transactions * Competitive solvers that source optimal DeFi opportunities Coming soon: Access to permissionless and multi-chain deployments. How It Works [#how-it-works] Rath allows frontends (wallets, apps) to: * Request yield strategies for any user asset * Receive signed transaction payloads from solvers * Relay them via Tachyon, our low-latency execution network Solvers compete to fulfill user intents by bidding to offer the best APY or structure, factoring in risk, strategy, and DeFi protocols’ health. All interactions remain non-custodial, preserving end-user control through EIP-7702. Get Access [#get-access] We’re granting early access to selected wallets, fintechs, and apps building with embedded DeFi experiences. To request API access: **Access Request Form:** [🔗 Request Access](https://forms.gle/168rHtEcrWeey6Bz8)\ You’ll receive sandbox credentials and developer onboarding within 2–3 business days. For additional queries: `hey@rath.fi` Technical Standards [#technical-standards] * **EIP-7702**: Enables native, temporary delegation of access without needing third-party vaults * **Cross-chain Ready**: Built with abstractions for multi-chain deployments via Tachyon * **Solver Marketplace**: Competitive backend layer that constantly optimizes APY based on protocol health, yield dynamics, and transaction cost Use Cases [#use-cases] * Native yield on idle user balances * Structured products with auto-compounding * User-customized strategies based on risk and goals * Passive access to top DeFi protocols with zero integration lift # Core Concepts (/tachyon/core-concepts) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. What is a Relayer? [#what-is-a-relayer] A relayer is a backend system that submits transactions to blockchain networks on behalf of users or applications. How Tachyon Works [#how-tachyon-works] 1. You send a signed or unsigned tx payload to Tachyon. 2. Tachyon estimates gas if needed and submits to chain. 3. It retries on failure, bumps gas if needed, and guarantees propagation. 4. Once mined, it returns the transaction hash. # Error Codes (/tachyon/error-codes) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Error Codes Reference [#error-codes-reference] This document provides a comprehensive reference for all error codes used in the API. Each error includes a unique code, message, HTTP status, and category for easier debugging and error handling. Error Structure [#error-structure] All errors follow a consistent structure: ```typescript { code: string; // Unique error identifier (e.g., "AUTH_001") message: string; // Human-readable error message httpStatus: number; // HTTP status code category: string; // Error category (e.g., "AUTH", "VALIDATION") } ``` Error Categories [#error-categories]
**AUTH** \- Authentication & Authorization Errors Errors related to authentication, authorization, and access control. | Code | Message | HTTP Status | Description | | ---------- | ------------------------------------- | ----------- | --------------------------------------------------------------------------- | | `AUTH_001` | Unauthorized access | 401 | The request requires authentication or the provided credentials are invalid | | `AUTH_002` | Invalid API key provided | 401 | The API key is malformed, expired, or doesn't exist | | `AUTH_003` | Admin key required for this operation | 401 | This operation requires admin-level privileges | | `AUTH_004` | Invalid or malformed JWT token | 401 | The JWT token structure is invalid or corrupted | | `AUTH_005` | JWT token has expired | 401 | The JWT token has passed its expiration time | | `AUTH_006` | Invalid nonce provided | 401 | The nonce value is incorrect or doesn't match | | `AUTH_007` | Nonce has expired | 401 | The nonce has exceeded its time-to-live | | `AUTH_008` | Invalid wallet signature | 401 | The cryptographic signature verification failed |
**VALIDATION** \- Input Validation Errors Errors related to request data validation and format checking. | Code | Message | HTTP Status | Description | | ---------------- | ------------------------------- | ----------- | ----------------------------------------------- | | `VALIDATION_001` | Invalid input data | 400 | The provided input data is malformed or invalid | | `VALIDATION_002` | Invalid address format | 400 | The blockchain address format is incorrect | | `VALIDATION_003` | Invalid or unsupported chain ID | 400 | The chain ID is not recognized or supported | | `VALIDATION_004` | Request validation failed | 400 | The request failed schema validation |
**TRANSACTION** \- Transaction Processing Errors Errors related to blockchain transactions and processing. | Code | Message | HTTP Status | Description | | ----------------- | ------------------------------------------------- | ----------- | ---------------------------------------------------------- | | `TRANSACTION_001` | Transaction cost exceeds maximum allowed limit | 400 | The transaction cost is higher than the configured maximum | | `TRANSACTION_002` | Insufficient balance to process transaction | 400 | The account doesn't have enough funds | | `TRANSACTION_003` | Transaction not found | 404 | The requested transaction doesn't exist | | `TRANSACTION_004` | Error processing transaction | 500 | An unexpected error occurred during transaction processing | | `TRANSACTION_005` | Invalid gas parameters provided | 400 | Gas price or gas limit values are invalid | | `TRANSACTION_006` | Daily limit exceeded, can not process transaction | 400 | The daily transaction limit has been reached |
**USER** \- User Management Errors Errors related to user accounts and management. | Code | Message | HTTP Status | Description | | ---------- | ------------------------------ | ----------- | ---------------------------------------------- | | `USER_001` | User not found | 404 | The specified user doesn't exist in the system | | `USER_002` | User already exists | 400 | A user with this identifier already exists | | `USER_003` | Invalid user address | 400 | The user's address is malformed or invalid | | `USER_004` | User account has been disabled | 403 | The user account has been deactivated |
**SYSTEM** \- System-Level Errors Errors related to system operations and infrastructure. | Code | Message | HTTP Status | Description | | ------------ | ------------------------------- | ----------- | --------------------------------------------- | | `SYSTEM_001` | Database operation failed | 500 | A database query or operation failed | | `SYSTEM_002` | Internal server error | 500 | An unexpected internal error occurred | | `SYSTEM_003` | Service temporarily unavailable | 503 | The service is temporarily down or overloaded |
**CHAIN** \- Blockchain Errors Errors related to blockchain network operations. | Code | Message | HTTP Status | Description | | ----------- | ------------------------------ | ----------- | --------------------------------------------- | | `CHAIN_001` | Unsupported blockchain network | 400 | The specified blockchain is not supported | | `CHAIN_002` | Chain adapter operation failed | 500 | The blockchain adapter encountered an error | | `CHAIN_003` | Blockchain RPC error | 500 | Communication with the blockchain node failed | | `CHAIN_004` | Network connectivity error | 503 | Unable to connect to the blockchain network |
**RESOURCE** \- Resource Management Errors Errors related to resource access and limits. | Code | Message | HTTP Status | Description | | -------------- | ---------------------------- | ----------- | ------------------------------------------ | | `RESOURCE_001` | Requested resource not found | 404 | The requested resource doesn't exist | | `RESOURCE_002` | Resource conflict detected | 409 | A conflict occurred with the current state | | `RESOURCE_003` | Resource limit exceeded | 429 | Rate limit or resource quota exceeded |
Usage Examples [#usage-examples] Handling Errors in TypeScript [#handling-errors-in-typescript] ```typescript import { ErrorCodes } from './error-codes'; try { // API call } catch (error) { if (error.code === ErrorCodes.AUTH_TOKEN_EXPIRED.code) { // Refresh token and retry } else if (error.code === ErrorCodes.TRANSACTION_INSUFFICIENT_BALANCE.code) { // Show insufficient balance error to user } else { // Handle other errors } } ``` Filtering by Category [#filtering-by-category] ```typescript import { getErrorCodesByCategory } from './error-codes'; // Get all authentication errors const authErrors = getErrorCodesByCategory('AUTH'); console.log(authErrors); ``` Getting All Categories [#getting-all-categories] ```typescript import { getErrorCategories } from './error-codes'; const categories = getErrorCategories(); // Returns: ['AUTH', 'VALIDATION', 'TRANSACTION', 'USER', 'SYSTEM', 'CHAIN', 'RESOURCE'] ``` HTTP Status Code Summary [#http-status-code-summary] | Status | Meaning | Error Categories | | ------ | --------------------- | ---------------------------------------------- | | 400 | Bad Request | VALIDATION, TRANSACTION, USER, CHAIN, RESOURCE | | 401 | Unauthorized | AUTH | | 403 | Forbidden | USER | | 404 | Not Found | TRANSACTION, USER, RESOURCE | | 409 | Conflict | RESOURCE | | 429 | Too Many Requests | RESOURCE | | 500 | Internal Server Error | TRANSACTION, SYSTEM, CHAIN | | 503 | Service Unavailable | SYSTEM, CHAIN | Best Practices [#best-practices] 1. **Always check the error code** - Use the specific error code rather than just the HTTP status for precise error handling 2. **Log error codes** - Include error codes in your logs for easier debugging and monitoring 3. **User-friendly messages** - Map error codes to user-friendly messages in your frontend 4. **Retry logic** - Implement appropriate retry logic for transient errors (503, CHAIN\_004) 5. **Rate limiting** - Handle `RESOURCE_003` by implementing exponential backoff Common Error Scenarios [#common-error-scenarios] Authentication Flow [#authentication-flow] 1. `AUTH_006` → `AUTH_007` → `AUTH_008` → Success 2. If any step fails, return the appropriate auth error Transaction Processing [#transaction-processing] 1. Validate input → `VALIDATION_*` errors 2. Check balance → `TRANSACTION_002` 3. Check limits → `TRANSACTION_001` or `TRANSACTION_006` 4. Process → `TRANSACTION_004` or `CHAIN_*` errors User Operations [#user-operations] 1. Validate address → `USER_003` 2. Check existence → `USER_001` or `USER_002` 3. Check status → `USER_004` 4. Process operation # Overview (/tachyon/introduction-overview) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Tachyon Documentation [#tachyon-documentation] **Tachyon** is a high-speed transaction relayer and bundler designed for the modern multichain world. It simplifies blockchain development by abstracting away gas estimation, nonce management, retries, and RPC reliability. With Tachyon, you can submit transactions to over 30 chains — including Ethereum, Arbitrum, Optimism, Base, Polygon, zkSync, Scroll, Linea, Sui, and NEAR — using a single, simple HTTP API. Key Features [#key-features] * Batch transaction relay support * EIP-1559 gas pricing support * Automatic retries, nonce handling, and gas bumping * SINGLE API interface * Multichain coverage (EVM + alt-VM chains) * Webhook and websocket notification support * Unified bundler for multi-call support (coming soon) # Quickstart Guide (/tachyon/quickstart) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Quickstart Guide [#quickstart-guide] The Tachyon SDK is a TypeScript/JavaScript library that provides a simple interface to interact with the Tachyon API. It allows you to relay transactions, check their status, and manage account information across multiple blockchain networks. Getting Your API Key [#getting-your-api-key] To use Tachyon, you'll need an API key: 1. Apply for the [API KEY](https://forms.gle/L2AqkS2GtN9HJKnY6) 2. Sign up or log in to your [Tachyon account](https://accounts.rath.fi) Installation [#installation] Install the Tachyon SDK using your preferred package manager: ```bash npm install @rathfi/tachyon ethers ``` ```bash yarn add @rathfi/tachyon ethers ``` ```bash pnpm add @rathfi/tachyon ethers ``` **Requirements:** Node.js 16+, TypeScript 4.5+ No installation required. Use cURL or any HTTP client to interact with the Tachyon API directly. Complete Example [#complete-example] ```typescript filename="example.ts" import { Tachyon, ChainId } from '@rathfi/tachyon'; import { ethers } from 'ethers'; async function relayTransaction() { // Initialize SDK const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY! }); // Encode contract call const abi = ["function transfer(address to, uint256 amount)"]; const iface = new ethers.Interface(abi); const callData = iface.encodeFunctionData("transfer", [ "0x742d35cc6634C0532925a3b8D1C9b53e6aC3", ethers.parseUnits("10", 18) // 10 tokens with 18 decimals ]); // Submit transaction const txId = await tachyon.relay({ chainId: ChainId.BASE, // or use 8453 to: "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7", value: "0", callData, label: "Token Transfer" }); console.log('Transaction ID:', txId); // Check status const status = await tachyon.getRelayStatus(txId); console.log('Status:', status.status); // Wait for execution const result = await tachyon.waitForExecutionHash(txId); console.log('Executed:', result.executionTxHash); } relayTransaction().catch(console.error); ``` **Submit a Transaction** ```bash filename="submit-transaction.sh" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7", "value": "0", "callData": "0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b8d1c9b53e6ac30000000000000000000000000000000000000000000000008ac7230489e80000", "label": "Token Transfer" }' ``` **Track the Transaction** ```bash filename="track-transaction.sh" curl "https://tachyon.rath.fi/api/tx?id=YOUR_TX_ID" \ -H "api-key: YOUR_API_KEY" ``` Key Parameters [#key-parameters] | Parameter | Type | Required | Description | Example | | ---------- | -------- | -------- | -------------------------- | --------------- | | `chainId` | `number` | Yes | Target blockchain network | `8453` (Base) | | `to` | `string` | Yes | Contract/recipient address | `"0xA7A8..."` | | `value` | `string` | Yes | Amount in wei | `"0"` | | `callData` | `string` | Yes | Encoded function call | `"0x..."` | | `label` | `string` | No | Custom label for tracking | `"My Transfer"` | | `gasLimit` | `string` | No | Gas limit override | `"100000"` | Transaction Lifecycle [#transaction-lifecycle] 1. **Submit** → Returns a unique `txId` 2. **Queue** → Transaction enters relay queue (`NOT_PICKED_UP`) 3. **Process** → Relay node broadcasts to blockchain 4. **Execute** → Transaction confirmed on-chain with execution hash # Supported Networks (/tachyon/supported-networks) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Supported Networks [#supported-networks] Tachyon supports a wide range of blockchain networks, including EVM-compatible chains and an expanding set of non-EVM networks. Below is a categorized list of currently supported networks. If your preferred chain isn’t listed, please mail us at [hey@rath.fi](mailto:hey@rath.fi) # Why Tachyon? (/tachyon/why-tachyon) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. TL;DR [#tldr] * **Blazing-Fast & High-Throughput:** Submit any transaction in under 150ms and process up to 50 transactions in a single block. * **Unified Multi-VM Development:** Interact with 16+ chains across EVM and alternative VMs through a single API and pay for all transactions from one unified balance. * **Focus on Your Product, Not Infrastructure:** We handle the complexities of nonce management, gas bidding, and transaction retries so you can ship faster. * **Battle-Tested Reliability:** Built on the same infrastructure that powers mission-critical operations for top DeFi protocols like Synthetix and Polynomial. A Platform for High-Performance dApps [#a-platform-for-high-performance-dapps] Tachyon is a transaction execution layer engineered for speed and reliability, enabling developers to build the next generation of high-performance decentralized applications. It empowers builders to: * Create highly responsive and engaging user experiences. * Power high-volume use cases like NFT mints and airdrops with confidence. * Abstract away the complexities of gas fees for a seamless, Web2-like feel. * Build sophisticated cross-chain applications with a single, unified interface, regardless of the underlying virtual machine. Tachyon is fast, reliable, and designed to scale. By handling the low-level details of blockchain interaction, it frees you to focus on solving real user problems and innovating on your core product. For example, a DeFi protocol can use Tachyon to execute time-sensitive liquidations with near-instantaneous speed, ensuring the protocol remains solvent. A Web3 game can use our high-throughput capabilities to manage in-game asset transfers for thousands of players simultaneously, without compromising on performance. An Unparalleled Developer Experience [#an-unparalleled-developer-experience] Developers choose Tachyon for its simplicity and power: * **Single API for All VMs:** No need to manage multiple RPC endpoints or learn the intricacies of different blockchain clients across EVM, SVM, and other virtual machines. * **Unified Balance:** Say goodbye to managing dozens of gas tokens. Fund a single account and relay transactions on any supported network. * **Flexible Fee Payments:** Pay for transaction fees using the token of your choice, fully on-chain. * **Automatic Infrastructure Management:** Tachyon automatically handles nonce management, transaction repricing, and failover, ensuring your transactions get mined reliably and efficiently. Built for and by Developers [#built-for-and-by-developers] Tachyon was born out of the need for a robust, high-performance transaction relayer to support our own complex DeFi operations. We built it to be the service we always wished we had. We are committed to supporting the builders who use our platform. By choosing Tachyon, you gain access to: * **Expert Support:** Get help from the same team that builds and maintains the core Tachyon infrastructure. * **A Reliable Partner:** We have a proven track record of 99.99% uptime, giving you the confidence to build mission-critical applications on our platform. * **Continuous Innovation:** We are constantly working to improve our service, add support for new chains, and provide more tools to help you succeed. We believe that by providing a world-class developer experience, we can empower builders to create the applications that will bring the next billion users onchain. # Fspot APIs (/xPath/f-spot) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Flash API Integration Guide [#flash-api-integration-guide] Complete documentation for integrating with the Flash API backend for cross-chain swap applications. Table of Contents [#table-of-contents] * [Overview](#overview) * [Base URL](#base-url) * [Authentication](#authentication) * [Chain Configuration](#chain-configuration) * [API Endpoints](#api-endpoints) * [Supported Chains](#1-supported-chains) * [Authentication](#2-authentication) * [Token List](#3-token-list) * [Quote](#4-quote) * [Gateway Balance](#5-gateway-balance) * [Swap Execution](#6-swap-execution) * [Search Token](#7-search-token) * [Swap History](#8-swap-history) * [Leaderboard](#10-leaderboard) * [User Referrals](#11-user-referrals) * [TypeScript Integration](#typescript-integration) *** Overview [#overview] The Flash API provides a comprehensive backend service for cross-chain USDC swaps using the Gateway protocol. It handles: * Chain configuration management * Token listings and prices * Quote generation for swaps * Swap execution and tracking * User authentication and referrals * Transaction history *** Base URL [#base-url] ``` Production: https://flash.rath.fi ``` *** Authentication [#authentication] Flash API uses wallet signature-based authentication. Flow: [#flow] 1. Request a message to sign 2. Sign the message with user's wallet 3. Verify signature to receive JWT token 4. Include token in subsequent requests Headers: [#headers] ``` Authorization: Bearer Content-Type: application/json ``` *** Chain Configuration [#chain-configuration] Dynamic Chain Support [#dynamic-chain-support] All chain configurations are fetched from the backend, making it easy to add/remove chains without frontend changes. **Key Features:** * Gateway wallet addresses * Gateway minter addresses * USDC contract addresses * Chain metadata (logo, explorer, name) * Domain numbers for Gateway protocol *** API Endpoints [#api-endpoints] 1\. Supported Chains [#1-supported-chains] Get all supported chains with their configuration. **Endpoint:** `GET /supported-chains` **Response:** ```typescript [ { "id": 8453, // Chain ID "name": "Base", // Chain name "displayName": "Base", // Display name "logoUrl": "https://...", // Chain logo URL "explorerUrl": "https://...", // Block explorer URL "domain": 6, // Gateway protocol domain "routerAddress": "0x...", // Swap router address "gatewayWallet": "0x...", // Gateway wallet contract "gatewayMinter": "0x...", // Gateway minter contract "nativeToken": { "address": "0x0000000000000000000000000000000000000000", "name": "Ethereum", "symbol": "ETH", "decimals": 18, "logoUrl": "https://..." }, "usdc": { "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "name": "USD Coin", "symbol": "USDC", "decimals": 6, "logoUrl": "https://..." } } ] ``` **Example:** ```typescript const chains = await fetch('https://flash.rath.fi/supported-chains') .then(res => res.json()); ``` *** 2\. Authentication [#2-authentication] 2.1 Request Sign Message [#21-request-sign-message] **Endpoint:** `POST /auth/message` **Request:** ```typescript { "userAddress": "0x1234567890abcdef1234567890abcdef12345678" } ``` **Response:** ```typescript { "message": "Sign this message to authenticate with Flash Computer...", "expiry": 1705449600, "messageId": "550e8400-e29b-41d4-a716-446655440000" } ``` 2.2 Verify Signature [#22-verify-signature] **Endpoint:** `POST /auth/verify` **Request:** ```typescript { "signature": "0xabcdef...", "messageId": "550e8400-e29b-41d4-a716-446655440000", "referredByCode": "REFERRAL123" // Optional } ``` **Response:** ```typescript { "token": "eyJhbGciOiJIUzI1NiIs...", "user_address": "0x1234567890abcdef1234567890abcdef12345678", "referralCode": "ABC123XYZ", "is_new_user": true } ``` **Complete Flow Example:** ```typescript // 1. Request message const { message, messageId } = await fetch('https://flash.rath.fi/auth/message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userAddress: address }) }).then(res => res.json()); // 2. Sign message with wallet const signature = await walletClient.signMessage({ message }); // 3. Verify and get token const { token } = await fetch('https://flash.rath.fi/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ signature, messageId }) }).then(res => res.json()); // 4. Use token for authenticated requests const authenticatedHeaders = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }; ``` *** 3\. Token List [#3-token-list] Get available tokens for swapping. **Endpoint:** `GET /token-list?chain_id={chainId}` **Query Parameters:** * `chain_id` (optional): Filter tokens by chain ID. Omit for all chains. **Response:** ```typescript { "tokens": [ { "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "symbol": "USDC", "decimals": 6, "logo_url": "https://...", "name": "USD Coin", "chain_id": 8453, "in_rath_token_list": true } ] } ``` **Examples:** ```typescript // Get all tokens const { tokens } = await fetch('https://flash.rath.fi/token-list') .then(res => res.json()); // Get tokens for Base (chain ID 8453) const { tokens } = await fetch('https://flash.rath.fi/token-list?chain_id=8453') .then(res => res.json()); ``` *** 4\. Quote [#4-quote] Get a quote for a swap. **Endpoint:** `GET /quote` **Query Parameters:** * `inputAmount`: Amount in USDC smallest units (1 USDC = 1000000) * `outputToken`: Output token address * `chainId`: Destination chain ID * `from`: User wallet address * `slippage`: Slippage tolerance (1.5 = 1.5%) * `recipient`: Recipient address (optional if not passed, defaults to `from`) **Example Request:** ``` GET /quote?inputAmount=1000000&outputToken=0x...&chainId=8453&from=0x...&slippage=1.5&recipient=0x... ``` **Response:** ```typescript { "token_in": { "address": "0x...", "amount": "1000000", "decimals": 6, "logo_url": "https://...", "price_usd": "1.00", "usd_amount": "1.00" }, "token_out": { "address": "0x...", "amount": "998500", "decimals": 6, "logo_url": "https://...", "price_usd": "1.00", "usd_amount": "0.9985" }, "fees": { "total_fee": "1500", "gateway_fee": "1000", "execution_fee": "500" }, "single_swap_router": "0x...", "hook_data": "0x...", "swap_router_address": "0x...", "swap_calldata": "0x...", "expires_at": 1705449600 } ``` **Example:** ```typescript const params = new URLSearchParams({ inputAmount: '1000000', // 1 USDC outputToken: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', chainId: '8453', from: userAddress, slippage: '1.5' }); const quote = await fetch(`https://flash.rath.fi/quote?${params}`) .then(res => res.json()); ``` *** 5\. Gateway Balance [#5-gateway-balance] Get user's balance across all chains in the Gateway protocol. **Endpoint:** `GET /balance/{address}` **Response:** ```typescript { "balances": [ { "domain": 6, "depositor": "0x...", "balance": "5000000", // Balance in USDC smallest units "chainId": 8453, "chainName": "Base" } ], "totalBalance": "5000000" // Total across all chains } ``` **Example:** ```typescript const { balances, totalBalance } = await fetch( `https://flash.rath.fi/balance/${userAddress}` ).then(res => res.json()); ``` *** 6\. Swap Execution [#6-swap-execution] Execute a swap transaction. **Endpoint:** `POST /swap` **Authentication:** Required (Bearer token) **Request:** ```typescript { "signedOrder": [...], // Array of signed burn intents "userAddress": "0x...", "chainId": 8453, "swapRouterAddress": "0x...", "swapCalldata": "0x...", "slippageBps": 150 // 150 basis points = 1.5% } ``` **Response:** ```typescript { "transactionHash": "0xabcdef...", "status": "pending", "message": "Swap initiated successfully" } ``` **Example:** ```typescript // After creating and signing burn intents const result = await fetch('https://flash.rath.fi/swap', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ signedOrder: signedBurnIntents, userAddress: address, chainId: destinationChainId, swapRouterAddress: quote.swap_router_address, swapCalldata: quote.swap_calldata, slippageBps: 150 }) }).then(res => res.json()); ``` *** 7\. Search Token [#7-search-token] Search for a token by address. **Endpoint:** `POST /search-token` **Request:** ```typescript { "chainId": 8453, "address": "0x..." } ``` **Response:** ```typescript { "address": "0x...", "symbol": "UNI", "decimals": 18, "name": "Uniswap", "chainId": 8453, "logoUrl": "https://...", "inRathTokenList": false } ``` **Example:** ```typescript const token = await fetch('https://flash.rath.fi/search-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chainId: 8453, address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984' }) }).then(res => res.json()); ``` *** 8\. Swap History [#8-swap-history] Get user's swap transaction history. **Endpoint:** `GET /history?page={page}&page_size={size}&status={status}` **Authentication:** Required (Bearer token) **Query Parameters:** * `page` (optional): Page number (default: 1) * `page_size` (optional): Items per page (default: 20) * `status` (optional): Filter by status (`pending`, `completed`, `failed`) **Response:** ```typescript { "swaps": [ { "id": "uuid", "sourceDomain": 6, "destinationDomain": 3, "sourceToken": "0x...", "destinationToken": "0x...", "tokenIn": { "address": "0x...", "symbol": "USDC", "decimals": 6, "logo_url": "https://...", "name": "USD Coin", "chain_id": 8453, "in_rath_token_list": true }, "tokenOut": { "address": "0x...", "symbol": "UNI", "decimals": 18, "logo_url": "https://...", "name": "Uniswap", "chain_id": 42161, "in_rath_token_list": true }, "amountUsdc": "1.00", "amountUsdcRaw": "1000000", "chainId": 42161, "minAmountOut": "0.9985", "rathFee": "0.0015", "rathFeeRaw": "1500", "transactionHash": "0x...", "status": "completed", "txId": "gateway-tx-id", "createdAt": "2024-01-17T10:00:00Z", "updatedAt": "2024-01-17T10:05:00Z" } ], "pagination": { "current_page": 1, "page_size": 20, "total_entries": 45, "total_pages": 3, "has_next": true, "has_previous": false }, "summary": { "totalSwaps": 45, "totalVolume": "12500.50", "totalVolumeRaw": "12500500000", "totalFees": "18.75", "totalFeesRaw": "18750000" } } ``` **Example:** ```typescript const history = await fetch( 'https://flash.rath.fi/history?page=1&page_size=20', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } } ).then(res => res.json()); ``` 9\. Leaderboard [#9-leaderboard] Get trading leaderboard rankings. **Endpoint:** `GET /leaderboard?page={page}&page_size={size}&time_range={range}` **Query Parameters:** * `page` (optional): Page number (default: 1) * `page_size` (optional): Items per page (default: 50) * `time_range` (optional): Time filter (`all`, `30d`, `7d`, `24h`) **Response:** ```typescript { "entries": [ { "rank": 1, "walletAddress": "0x...", "totalVolume": "50000.00", "totalVolumeRaw": "50000000000", "swapCount": 150, "referralCount": 25, "referralVolume": "5000.00", "referralVolumeRaw": "5000000000", "combined_volume": "55000.00", "referralCode": "ABC123", "lastSwapAt": "2024-01-17T10:00:00Z" } ], "pagination": { "current_page": 1, "page_size": 50, "total_entries": 250, "total_pages": 5, "has_next": true, "has_previous": false } } ``` **Example:** ```typescript const leaderboard = await fetch( 'https://flash.rath.fi/leaderboard?time_range=7d' ).then(res => res.json()); ``` *** 10\. User Referrals [#10-user-referrals] Get user's referral information. **Endpoint:** `GET /referrals` **Authentication:** Required (Bearer token) **Response:** ```typescript { "referrals": [ { "user_address": "0x...", "total_volume_usdc": 1500.25 } ], "total_referral_volume": 5250.75, "total_referrals_count": 3, "remaining_referral_limit": 7 } ``` **Example:** ```typescript const referrals = await fetch('https://flash.rath.fi/referrals', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }).then(res => res.json()); ``` *** TypeScript Integration [#typescript-integration] Gateway Protocol Integration [#gateway-protocol-integration] Creating Burn Intents (Signed Orders) [#creating-burn-intents-signed-orders] Burn intents are EIP-712 signed messages that authorize cross-chain USDC transfers via the Gateway protocol. Step 1: Define EIP-712 Types [#step-1-define-eip-712-types] ```typescript const EIP712Domain = [ { name: "name", type: "string" }, { name: "version", type: "string" }, ]; const TransferSpec = [ { name: "version", type: "uint32" }, { name: "sourceDomain", type: "uint32" }, { name: "destinationDomain", type: "uint32" }, { name: "sourceContract", type: "bytes32" }, { name: "destinationContract", type: "bytes32" }, { name: "sourceToken", type: "bytes32" }, { name: "destinationToken", type: "bytes32" }, { name: "sourceDepositor", type: "bytes32" }, { name: "destinationRecipient", type: "bytes32" }, { name: "sourceSigner", type: "bytes32" }, { name: "destinationCaller", type: "bytes32" }, { name: "value", type: "uint256" }, { name: "salt", type: "bytes32" }, { name: "hookData", type: "bytes" }, ]; const BurnIntent = [ { name: "maxBlockHeight", type: "uint256" }, { name: "maxFee", type: "uint256" }, { name: "spec", type: "TransferSpec" }, ]; const BurnIntentSet = [ { name: "intents", type: "BurnIntent[]" } ]; const domain = { name: "GatewayWallet", version: "1" }; ``` Step 2: Create Burn Intent [#step-2-create-burn-intent] ```typescript import { pad, maxUint256 } from 'viem'; // Helper to convert address to bytes32 function addressToBytes32(address: string): string { return pad(address.toLowerCase() as `0x${string}`, { size: 32 }); } // Generate random salt function generateRandomSalt(): string { const bytes = new Uint8Array(32); crypto.getRandomValues(bytes); return '0x' + Array.from(bytes) .map(b => b.toString(16).padStart(2, '0')) .join(''); } // Create a burn intent function createBurnIntent({ userAddress, sourceChain, destinationChain, amount, recipient, hookData = '0x', maxFee = '2010000' // Gateway fee in smallest units }: { userAddress: string; sourceChain: ChainConfig; destinationChain: ChainConfig; amount: string; // Amount in smallest units (e.g., 1000000 for 1 USDC) recipient: string; hookData?: string; maxFee?: string; }) { return { maxBlockHeight: maxUint256, // Far future block maxFee: BigInt(maxFee), spec: { version: 1, sourceDomain: sourceChain.domain, destinationDomain: destinationChain.domain, sourceContract: sourceChain.gatewayWallet, destinationContract: destinationChain.gatewayMinter, sourceToken: sourceChain.usdc.address, destinationToken: destinationChain.usdc.address, sourceDepositor: userAddress, destinationRecipient: recipient, sourceSigner: userAddress, destinationCaller: recipient, value: BigInt(amount), salt: generateRandomSalt(), hookData: hookData, }, }; } ``` Step 3: Create Typed Data for Signing [#step-3-create-typed-data-for-signing] ```typescript function createBurnIntentTypedData(burnIntent: any) { return { types: { EIP712Domain, TransferSpec, BurnIntent }, domain, primaryType: "BurnIntent", message: { maxBlockHeight: burnIntent.maxBlockHeight, maxFee: burnIntent.maxFee, spec: { ...burnIntent.spec, sourceContract: addressToBytes32(burnIntent.spec.sourceContract), destinationContract: addressToBytes32(burnIntent.spec.destinationContract), sourceToken: addressToBytes32(burnIntent.spec.sourceToken), destinationToken: addressToBytes32(burnIntent.spec.destinationToken), sourceDepositor: addressToBytes32(burnIntent.spec.sourceDepositor), destinationRecipient: addressToBytes32(burnIntent.spec.destinationRecipient), sourceSigner: addressToBytes32(burnIntent.spec.sourceSigner), destinationCaller: addressToBytes32(burnIntent.spec.destinationCaller), }, }, }; } // For multiple intents (burn intent set) function createBurnIntentSetTypedData(burnIntents: any[]) { return { types: { EIP712Domain, TransferSpec, BurnIntent, BurnIntentSet }, domain, primaryType: "BurnIntentSet", message: { intents: burnIntents.map(intent => createBurnIntentTypedData(intent).message ), }, }; } ``` Step 4: Sign Burn Intent(s) [#step-4-sign-burn-intents] ```typescript // Using ethers.js import { ethers } from 'ethers'; async function signBurnIntent( wallet: ethers.Wallet, burnIntent: any ): Promise { const typedData = createBurnIntentTypedData(burnIntent); const signature = await wallet._signTypedData( typedData.domain, { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent }, typedData.message ); return signature; } // Using viem import { signTypedData } from 'viem/accounts'; async function signBurnIntentViem( walletClient: any, burnIntent: any ): Promise { const typedData = createBurnIntentTypedData(burnIntent); const signature = await walletClient.signTypedData({ domain: typedData.domain, types: { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent }, primaryType: 'BurnIntent', message: typedData.message }); return signature; } ``` Complete Example: Creating Signed Order for Swap [#complete-example-creating-signed-order-for-swap] ```typescript async function createSignedSwapOrder({ walletClient, userAddress, sourceChains, // Array of chains to pull USDC from destinationChain, // Chain to swap on allocations, // Amount to pull from each source chain recipient, // Swap router address (from quote) hookData, // Hook data from quote gatewayFee // Gateway fee from quote }: { walletClient: any; userAddress: string; sourceChains: ChainConfig[]; destinationChain: ChainConfig; allocations: { chainId: number; amount: string }[]; recipient: string; hookData: string; gatewayFee: string; }) { // Create burn intents for each source chain const burnIntents = allocations.map((allocation, index) => { const sourceChain = sourceChains[index]; return createBurnIntent({ userAddress, sourceChain, destinationChain, amount: allocation.amount, recipient, hookData, maxFee: gatewayFee }); }); // Create typed data for signing const typedData = createBurnIntentSetTypedData(burnIntents); // Sign the burn intent set const signature = await walletClient.signTypedData({ domain: typedData.domain, types: { TransferSpec: typedData.types.TransferSpec, BurnIntent: typedData.types.BurnIntent, BurnIntentSet: typedData.types.BurnIntentSet }, primaryType: 'BurnIntentSet', message: typedData.message }); // Format for API const signedOrder = burnIntents.map((intent, index) => ({ intent, signature: index === 0 ? signature : undefined // Only first intent needs signature })); return signedOrder; } ``` Depositing USDC to Gateway Wallet [#depositing-usdc-to-gateway-wallet] To deposit USDC into the Gateway wallet, you can use the `depositWithPermit` function which combines USDC approval and deposit in a single transaction using EIP-2612 permits. Gateway Wallet ABI [#gateway-wallet-abi] ```typescript const gatewayWalletAbi = [ { inputs: [ { internalType: "address", name: "token", type: "address" }, { internalType: "address", name: "owner", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint8", name: "v", type: "uint8" }, { internalType: "bytes32", name: "r", type: "bytes32" }, { internalType: "bytes32", name: "s", type: "bytes32" } ], name: "depositWithPermit", outputs: [], stateMutability: "nonpayable", type: "function" } ]; ``` Step 1: Generate USDC Permit Signature [#step-1-generate-usdc-permit-signature] ```typescript import { parseUnits } from 'viem'; async function generateUSDCPermit({ walletClient, publicClient, chainId, usdcAddress, usdcName, usdcVersion, ownerAddress, spenderAddress, // Gateway wallet address amount }: { walletClient: any; publicClient: any; chainId: number; usdcAddress: string; usdcName: string; usdcVersion: string; ownerAddress: string; spenderAddress: string; amount: bigint; }) { // Get current nonce const nonce = await publicClient.readContract({ address: usdcAddress, abi: [{ inputs: [{ name: 'owner', type: 'address' }], name: 'nonces', outputs: [{ name: '', type: 'uint256' }], stateMutability: 'view', type: 'function', }], functionName: 'nonces', args: [ownerAddress], }); // Set deadline (e.g., 1 hour from now) const deadline = BigInt(Math.floor(Date.now() / 1000) + 3600); // EIP-2612 Permit types const types = { Permit: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" } ] }; // Domain const domain = { name: usdcName, version: usdcVersion, chainId, verifyingContract: usdcAddress }; // Sign permit const signature = await walletClient.signTypedData({ domain, types, primaryType: 'Permit', message: { owner: ownerAddress, spender: spenderAddress, value: amount, nonce, deadline } }); // Parse signature const { r, s, v } = parseSignature(signature); return { deadline, v, r, s }; } function parseSignature(signature: string) { const r = `0x${signature.slice(2, 66)}`; const s = `0x${signature.slice(66, 130)}`; const v = parseInt(signature.slice(130, 132), 16); return { r, s, v }; } ``` Step 2: Execute depositWithPermit [#step-2-execute-depositwithpermit] ```typescript import { writeContract, waitForTransactionReceipt } from 'viem'; async function depositWithPermit({ walletClient, publicClient, chainConfig, amount, // Amount in USDC (e.g., "1.5" for 1.5 USDC) ownerAddress }: { walletClient: any; publicClient: any; chainConfig: ChainConfig; amount: string; ownerAddress: string; }) { // Convert amount to smallest units (USDC has 6 decimals) const amountInWei = parseUnits(amount, 6); // Generate permit signature const { deadline, v, r, s } = await generateUSDCPermit({ walletClient, publicClient, chainId: chainConfig.id, usdcAddress: chainConfig.usdc.address, usdcName: chainConfig.usdc.name, usdcVersion: chainConfig.usdc.version.toString(), ownerAddress, spenderAddress: chainConfig.gatewayWallet, amount: amountInWei }); // Execute depositWithPermit const hash = await walletClient.writeContract({ address: chainConfig.gatewayWallet, abi: gatewayWalletAbi, functionName: 'depositWithPermit', args: [ chainConfig.usdc.address, ownerAddress, amountInWei, deadline, v, r, s ] }); console.log('Transaction hash:', hash); // Wait for confirmation const receipt = await waitForTransactionReceipt(publicClient, { hash }); console.log('Deposit confirmed:', receipt); return receipt; } ``` Complete Deposit Example [#complete-deposit-example] ```typescript // Example: Deposit 10 USDC on Base chain async function depositExample() { // Get chain config from API const chains = await flashApi.getSupportedChains(); const baseChain = chains.find(c => c.id === 8453); if (!baseChain) { throw new Error('Base chain not found'); } // Deposit 10 USDC const receipt = await depositWithPermit({ walletClient, publicClient, chainConfig: baseChain, amount: '10', ownerAddress: userAddress }); console.log('✅ Deposited 10 USDC to Gateway wallet'); console.log('Transaction:', receipt.transactionHash); // Check new balance const balance = await flashApi.getGatewayBalance(userAddress); console.log('New Gateway balance:', balance.totalBalance); } ``` # xPath APIs (/xPath) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. xPath is Rath’s high-performance cross-chain routing engine. *(Coming soon)* xPath APIs compute the fastest and most capital-efficient execution paths across chains, bridges, and execution environments. They abstract fragmented liquidity, variable fees, and latency differences into a single deterministic routing interface. xPath will power instant cross-chain transfers, multi-hop execution, and optimal routing for wallets, solvers, and DeFi applications. # Authenticated Transaction Feature (/tachyon/features/authenticated-tx) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Authenticated Transaction Feature powered by NEAR Chain Signatures [#authenticated-transaction-feature-powered-by-near-chain-signatures] Overview [#overview] The Authenticated Transaction feature in Tachyon API enables cross-chain transaction signing using NEAR Protocol's Chain Signatures technology. When a transaction is submitted with `isAuthenticatedTx: true`, Tachyon leverages NEAR's Multi-Party Computation (MPC) service to sign transactions for external blockchains while maintaining security and decentralization. How It Works [#how-it-works] Transaction Flow [#transaction-flow] 1. **Transaction Submission**: A user submits a transaction with `isAuthenticatedTx: true` 2. **Transaction Type Assignment**: The transaction is automatically classified as `TransactionType.AUTHENTICATED` 3. **Chain Signature Process**: * The transaction is prepared for signing on the target blockchain * NEAR's Chain Signature contract (`v1.signer`) is invoked * The MPC service generates signatures using the specified derivation path 4. **Funding Transaction**: The newly derived address is funded with the required amount of native tokens for gas fees 5. **Transaction Finalization**: The signed transaction is broadcast to the target blockchain Supported Blockchains [#supported-blockchains] Chain Signatures work with any blockchain that uses ECDSA signatures, including: * Ethereum and EVM-compatible networks * Solana * Aptos * Sui Security Features [#security-features] * **Decentralized Signing**: No single entity controls the signing process * **Multi-Party Computation**: Signatures are generated by multiple independent nodes * **Derivation Path Security**: Each user gets unique derived addresses per blockchain * **On-Chain Verification**: All signature requests are processed on NEAR blockchain Usage Example [#usage-example] Submitting an Authenticated Transaction [#submitting-an-authenticated-transaction] ```javascript filename="authenticated-transaction.js" const transactionData = { to: "0x1234567890abcdef1234567890abcdef12345678", callData: "0x", value: "1", // 1 Wei in wei chainId: 1, // Ethereum mainnet isAuthenticatedTx: true, // Enable Chain Signatures maxFeePerGas: "20000000000", maxPriorityFeePerGas: "2000000000", gasLimit: "21000", userId: "your-user-id", label: "default" }; const response = await fetch('/submit-tx', { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': 'your-api-key' }, body: JSON.stringify(transactionData) }); ``` Benefits [#benefits] 1. **Unified Key Management**: Control multiple blockchain accounts from a single Tachyon account 2. **Enhanced Security**: Leverage NEAR's decentralized MPC infrastructure 3. **Cross-Chain Interoperability**: Sign transactions for any ECDSA-compatible blockchain 4. **Simplified Integration**: Single API call handles complex multi-chain operations 5. **Cost Efficiency**: Batch multiple signatures in a single MPC request Limitations [#limitations] * Requires Tachyon account and availability of Rath Services * Dependent on NEAR network availability and MPC service uptime For more information about NEAR Chain Signatures, see the [official NEAR documentation](https://docs.near.org/concepts/abstraction/chain-signatures). # Batch Transactions (/tachyon/features/batch_transactions) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Batch Transactions [#batch-transactions] Combine multiple transaction calls into a single on-chain transaction using Tachyon's multicall feature. Reduce gas costs, improve efficiency, and ensure atomic execution of related operations. Overview [#overview] Batch Transactions allow you to group multiple contract calls into a single transaction using the `shouldBatchInMulticall` parameter. Tachyon automatically optimizes compatible transactions for gas savings. How It Works [#how-it-works] When you enable batching, Tachyon groups your transaction with other compatible transactions and executes them together using a multicall contract, providing: * **Gas Optimization**: Significant savings by reducing per-transaction overhead * **Automatic Grouping**: Tachyon intelligently batches compatible transactions Usage [#usage] ```bash filename="Terminal" {9} curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1", "callData": "0x", "shouldBatchInMulticall": true, "gasLimit": "30000", "label": "Batched Transfer" }' ``` ```typescript filename="batch-transactions.ts" {14,23} import { Tachyon, ChainId } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY! }); // Submit multiple transactions for batching const transfers = [ { chainId: ChainId.BASE, to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', callData: '0x', shouldBatchInMulticall: true, gasLimit: "30000", label: 'Transfer 1' }, { chainId: ChainId.BASE, to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', value: '1', callData: '0x', shouldBatchInMulticall: true, gasLimit: "30000", label: 'Transfer 2' } ]; // Tachyon automatically batches compatible transactions const txIds = await Promise.all( transfers.map(tx => tachyon.relay(tx)) ); console.log('Batched transactions submitted:', txIds); ``` Use Cases [#use-cases] * **DeFi Operations**: Approve + swap, multiple token transfers * **NFT Operations**: Batch minting, bulk transfers * **Multi-token Actions**: Distribute tokens to multiple recipients * **Contract Interactions**: Execute multiple contract calls atomically Benefits [#benefits] * **Gas Savings**: Typically 10-20% reduction in gas costs * **Atomic Execution**: All operations succeed or fail together * **Simplified Flow**: Single transaction for multiple operations * **Automatic Optimization**: Tachyon handles the batching logic Key Parameters [#key-parameters] | Parameter | Description | | ------------------------------ | ------------------------------------------------ | | `shouldBatchInMulticall: true` | Enable transaction batching | | Same `chainId` | All batched transactions must be on same network | # EIP-7702 Authorization (/tachyon/features/eip-7702) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. EIP-7702 Authorization [#eip-7702-authorization] Leverage EIP-7702 to temporarily delegate your EOA (Externally Owned Account) to a smart contract, enabling advanced features like batched operations, gas sponsorship, and custom validation logic—all without deploying a separate smart contract wallet. Overview [#overview] EIP-7702 introduces a new transaction type that allows EOAs to temporarily adopt smart contract code for a single transaction. This enables: * **Smart Account Features**: Access batching, session keys, and spending limits without migrating to a new wallet * **Gas Sponsorship**: Allow third parties to pay for transaction gas * **Atomic Operations**: Execute multiple operations in a single transaction * **Custom Validation**: Implement custom signature schemes or multi-sig logic How It Works [#how-it-works] Authorization Flow [#authorization-flow] 1. **Sign Authorization**: The EOA owner signs an authorization tuple specifying the contract code to delegate to 2. **Submit Transaction**: The authorization is included in the transaction's `authorizationList` 3. **Temporary Delegation**: For the duration of the transaction, the EOA behaves like a smart contract 4. **Code Execution**: The delegated code executes with the EOA as the context 5. **State Reset**: After the transaction, the EOA returns to its normal state (unless the code modifies storage) Authorization Tuple Structure [#authorization-tuple-structure] Each authorization in the `authorizationList` contains: | Field | Type | Description | | --------- | ------ | ------------------------------------------------- | | `chainId` | number | The chain ID where the authorization is valid | | `address` | string | The contract address to delegate to | | `nonce` | number | The EOA's current nonce (prevents replay attacks) | | `r` | string | ECDSA signature r component | | `s` | string | ECDSA signature s component | | `yParity` | number | Signature recovery parameter (0 or 1) | Usage with Tachyon [#usage-with-tachyon] API Request [#api-request] ```bash filename="eip-7702-request.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0xYourEOAAddress", "callData": "0xEncodedBatchCallData", "value": "0", "authorizationList": [ { "chainId": 8453, "address": "0xDelegateContractAddress", "nonce": 0, "r": "0x...", "s": "0x...", "yParity": 0 } ], "label": "EIP-7702 Batch Transaction" }' ``` Example with Viem [#example-with-viem] Here's a complete example using [viem](https://viem.sh/) to create and sign an EIP-7702 authorization, then submit it through Tachyon: ```typescript filename="eip-7702-sdk.ts" import { createWalletClient, http, zeroAddress } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { base } from 'viem/chains'; import { Tachyon } from '@rathfi/tachyon'; // Create wallet client with your EOA const walletClient = createWalletClient({ account: privateKeyToAccount('0xYOUR_PRIVATE_KEY'), transport: http(), chain: base, }); // The contract address to delegate to (e.g., a batch executor contract) const delegateContractAddress = '0xDelegateContractAddress'; async function createEIP7702Transaction() { // Sign the authorization - viem handles nonce automatically const authorization = await walletClient.signAuthorization({ contractAddress: delegateContractAddress, }); // Format authorization for Tachyon const auth = { chainId: authorization.chainId, address: authorization.address, nonce: Number(authorization.nonce), r: authorization.r, s: authorization.s, v: Number(authorization.v), yParity: Number(authorization.yParity) as 0 | 1, }; // Initialize Tachyon SDK const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, }); // Submit transaction with authorization const taskId = await tachyon.relay({ chainId: base.id, to: zeroAddress, // Or your target contract callData: '0x', // Encoded function call value: '0', gasLimit: '1000000', authorizationList: [auth], }); console.log('Task ID:', taskId); // Wait for the transaction to be executed const tx = await tachyon.waitForExecutionHash(taskId, 30_000); console.log('Transaction executed:', tx); return tx; } createEIP7702Transaction(); ``` ```typescript filename="eip-7702-api.ts" import { createWalletClient, http, zeroAddress } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { base } from 'viem/chains'; // Create wallet client with your EOA const walletClient = createWalletClient({ account: privateKeyToAccount('0xYOUR_PRIVATE_KEY'), transport: http(), chain: base, }); const delegateContractAddress = '0xDelegateContractAddress'; async function createEIP7702Transaction() { // Sign the authorization const authorization = await walletClient.signAuthorization({ contractAddress: delegateContractAddress, }); // Format authorization for the API const auth = { chainId: authorization.chainId, address: authorization.address, nonce: Number(authorization.nonce), r: authorization.r, s: authorization.s, v: Number(authorization.v), yParity: Number(authorization.yParity) as 0 | 1, }; // Submit to Tachyon API const response = await fetch('https://tachyon.rath.fi/api/submit-tx', { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': process.env.TACHYON_API_KEY!, }, body: JSON.stringify({ chainId: base.id, to: zeroAddress, callData: '0x', value: '0', gasLimit: '1000000', authorizationList: [auth], label: 'EIP-7702 Authorization', }), }); const result = await response.json(); console.log('Transaction submitted:', result.data.txId); return result; } createEIP7702Transaction(); ``` Use Cases [#use-cases] 1\. Batched Token Operations [#1-batched-token-operations] Execute multiple token transfers or approvals in a single transaction, saving gas and ensuring atomicity. 2\. Gas Sponsorship [#2-gas-sponsorship] Allow a relayer (like Tachyon) to pay for transaction gas while your EOA executes the operation. 3\. Session Keys [#3-session-keys] Temporarily delegate specific permissions to a session key for gaming or dApp interactions. 4\. Account Recovery [#4-account-recovery] Implement social recovery mechanisms without pre-deploying a smart contract wallet. 5\. Conditional Execution [#5-conditional-execution] Add custom validation logic that must pass before the transaction executes. Benefits [#benefits] | Feature | Traditional EOA | EIP-7702 EOA | | -------------------- | --------------- | -------------- | | Batched transactions | ❌ | ✅ | | Custom validation | ❌ | ✅ | | Gas sponsorship | Limited | ✅ Full support | | Session keys | ❌ | ✅ | | Atomic operations | ❌ | ✅ | | No migration needed | ✅ | ✅ | Important Considerations [#important-considerations]
**Security Notes:** * Only delegate to audited, trusted contracts * The authorization is valid for the specific chain ID and nonce * After the transaction, verify the EOA state is as expected * Be cautious with contracts that modify EOA storage permanently
Supported Networks [#supported-networks] EIP-7702 is supported on networks that have implemented the Pectra upgrade: * Ethereum Mainnet * Base * Optimism * Arbitrum * And other EVM chains with Pectra support Limitations [#limitations] * **Not compatible with flash-blocks**: The `authorizationList` parameter cannot be used with `transactionType: "flash-blocks"` * **Nonce sensitivity**: The authorization nonce must match the EOA's current nonce exactly * **Chain-specific**: Each authorization is only valid for the specified chain ID SDK Support [#sdk-support] ```typescript filename="tachyon-sdk-eip7702.ts" import { Tachyon } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, }); // Authorization object from viem's signAuthorization const auth = { chainId: 8453, // Base address: '0xDelegateContractAddress', nonce: 0, r: '0x...', s: '0x...', v: 27, yParity: 0 as 0 | 1, }; // Submit transaction with EIP-7702 authorization const taskId = await tachyon.relay({ chainId: 8453, to: '0xTargetAddress', callData: '0xEncodedCallData', value: '0', gasLimit: '1000000', authorizationList: [auth], }); console.log('Task ID:', taskId); // Wait for execution const tx = await tachyon.waitForExecutionHash(taskId, 30_000); console.log('Execution hash:', tx); ``` Further Reading [#further-reading] * [EIP-7702 Specification](https://eips.ethereum.org/EIPS/eip-7702) * [Viem EIP-7702 Documentation](https://viem.sh/docs/eip7702) * [Discussion on Ethereum Magicians](https://ethereum-magicians.org/t/eip-7702-set-eoa-account-code/19923) * [Account Abstraction Overview](https://ethereum.org/en/roadmap/account-abstraction/) # Flashblocks (/tachyon/features/flashblocks) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Flashblocks [#flashblocks] Ultra-fast transaction execution on Flash-Blocks supported chains with Tachyon's flashblocks feature. Reduce transaction latency from 150ms to under 50ms for lightning-fast user experiences. Overview [#overview] Flashblocks is Tachyon's high-speed transaction type that delivers ultra-low latency execution on Flash-Blocks supported chains. While standard Tachyon transactions already execute in under 150ms, flashblocks push the boundaries further with sub-50ms average latency, making them perfect for real-time applications, gaming, and high-frequency trading where every millisecond counts. Performance Comparison [#performance-comparison] | Transaction Type | Average Latency | Best Use Cases | | ---------------- | --------------- | --------------------------------------------------- | | Standard Relay | Under 150ms | General transactions, DeFi operations | | Flashblocks | Under 50ms | Gaming, real-time trading, time-critical operations | Supported Networks [#supported-networks] Currently available on: * **Base Mainnet** (Chain ID: 8453) * **Base Sepolia Testnet** (Chain ID: 84532) Flashblocks support is expanding to all EVM-compatible networks in Tachyon's ecosystem. Additional chains will be added progressively. Usage [#usage] ```bash filename="Terminal" {10} curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1", "callData": "0x", "gasLimit": "30000", "transactionType": "flash-blocks", "label": "Ultra-fast transaction" }' ``` ```typescript filename="flashblocks-example.ts" {12} import { Tachyon, ChainId } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY! }); const txId = await tachyon.relay({ chainId: ChainId.BASE, to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', callData: '0x', transactionType: 'flash-blocks', gasLimit: "30000", label: 'Flashblocks Transfer' }); console.log('Transaction submitted:', txId); ``` Use Cases [#use-cases] * **Gaming**: Instant in-game transactions and real-time state updates * **High-Frequency Trading**: Ultra-fast order execution and arbitrage opportunities * **Live Applications**: Real-time chat, social interactions, and instant feedback * **Time-Critical DeFi**: MEV strategies, liquidations, and flash loans * **Competitive Applications**: Any use case where 50ms vs 150ms makes a difference Key Benefits [#key-benefits] * **Sub-50ms Latency**: 3x faster than standard Tachyon transactions * **Enhanced UX**: Near-instantaneous transaction confirmations * **Base Optimized**: Specifically designed for Base network infrastructure * **Same Reliability**: Maintains Tachyon's 99.99% success rate # Non-Custodial Transactions (/tachyon/features/non-custodial-tx) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Doing Non-Custodial Transactions on Tachyon [#doing-non-custodial-transactions-on-tachyon] Overview [#overview] The Tachyon API provides a powerful combination of the `/quote` endpoint and `/submit-signed-tx` endpoint that works seamlessly with NEAR's Chain Signatures technology. This approach allows users to get accurate cost estimates upfront and then submit pre-signed transactions that can be funded and executed efficiently. Workflow Overview [#workflow-overview] Step-by-Step Integration [#step-by-step-integration] Get Transaction Quote [#get-transaction-quote] First, obtain a quote for your transaction to understand the costs and gas requirements: ```javascript filename="get-quote.js" const quoteRequest = { to: "0x1234567890abcdef1234567890abcdef12345678", callData: "0xa9059cbb000000000000000000000000742d35cc...", // ERC20 transfer data value: "0", chainId: 1, // Ethereum mainnet maxFeePerGas: "20000000000", maxPriorityFeePerGas: "2000000000", gasLimit: "21000", }; const quoteResponse = await fetch('https://tachyon.rath.fi/api/quote', { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': 'your-api-key' }, body: JSON.stringify(quoteRequest) }); const quote = await quoteResponse.json(); console.log('Estimated cost:', quote.costUSD); console.log('Min Balance Required:', quote.minBalanceRequired); ``` Sign Transaction with Chain Signatures [#sign-transaction-with-chain-signatures] Use NEAR's Chain Signatures to sign the transaction. This can be done through: 1. **Direct NEAR Integration**: Use NEAR wallet or account to call the MPC service 2. **Tachyon's Chain Signature Integration**: For users who have configured Tachyon with NEAR accounts ```javascript filename="sign-transaction.js" // Example using NEAR wallet selector const signTransaction = async (transactionData, derivationPath) => { const wallet = await selector.wallet(); // Prepare transaction for signing const unsignedTx = { to: transactionData.to, value: BigInt(transactionData.value), data: transactionData.callData, gasLimit: BigInt(transactionData.gasLimit), maxFeePerGas: BigInt(transactionData.maxFeePerGas), maxPriorityFeePerGas: BigInt(transactionData.maxPriorityFeePerGas) }; // Sign with MPC const signature = await wallet.signAndSendTransaction({ receiverId: 'v1.signer', actions: [{ type: 'FunctionCall', params: { methodName: 'sign', args: { payload: [hashToSign], path: derivationPath, key_type: 'Ecdsa' }, gas: '300000000000000', deposit: '1' } }] }); return signature; }; ``` Submit Signed Transaction [#submit-signed-transaction] Submit the signed transaction along with funding requirements: ```javascript filename="submit-signed-tx.js" const submitSignedRequest = { signedTx: "0x02f8b20180843b9aca0085174876e800825208942c169...", // Your signed tx chainId: 1, fromAddress: "0xYourDerivedAddress", // Address derived from Chain Signatures minBalanceRequired: "${quote.minBalanceRequired}", // Minimum balance needed // Optional: Reference the quote for cost tracking quoteReference: quote.id, estimatedCost: quote.estimatedCost }; const submitResponse = await fetch('https://tachyon.rath.fi/api/submit-signed-tx', { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': 'your-api-key' }, body: JSON.stringify(submitSignedRequest) }); const result = await submitResponse.json(); console.log('Transaction submitted:', result.transactionId); ``` # Get Account Info (/tachyon/tachyon-api/check-account-info) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Get Account Info [#get-account-info] Endpoint [#endpoint] ``` GET https://tachyon.rath.fi/api/user ``` Query Parameters [#query-parameters] | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------ | | `address` | string | Yes | The wallet address to retrieve account information for | Response [#response] Success Response [#success-response] ```json filename="chains-response.json" { "success": true, "data": { "userId": "usr_123456789", "address": "0x1234567890abcdef1234567890abcdef12345678", "availableBalance": 1000.50, "pendingBalance": 50.25, "defaultTachyonAccount": { "address": "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", "token": { "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "symbol": "USDC", "name": "USD Coin", "decimals": 6, "iconUrl": "https://example.com/usdc-icon.png" }, "chainId": 1 } }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Response Fields [#response-fields] AccountInfo Object [#accountinfo-object] | Field | Type | Description | | ----------------------- | ------ | -------------------------------------------- | | `userId` | string | Unique identifier for the user | | `address` | string | The wallet address of the account | | `availableBalance` | number | The current available balance in the account | | `pendingBalance` | number | The balance that is currently pending | | `defaultTachyonAccount` | object | Default Tachyon account configuration | defaultTachyonAccount Object [#defaulttachyonaccount-object] | Field | Type | Description | | --------- | ------ | ----------------------------------------- | | `address` | string | The default account address | | `token` | object | Token information for the default account | | `chainId` | number | The blockchain network chain ID | token Object [#token-object] | Field | Type | Description | | ---------- | ------ | -------------------------------------- | | `address` | string | The token contract address | | `symbol` | string | The token symbol (e.g., "USDC", "ETH") | | `name` | string | The full name of the token | | `decimals` | number | Number of decimal places for the token | | `iconUrl` | string | URL to the token's icon image | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "INVALID_ADDRESS", "message": "The provided address is invalid", "category": "VALIDATION_ERROR", "details": { "field": "address", "message": "Address must be a valid Ethereum address" }, "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` TachyonError Object [#tachyonerror-object] | Field | Type | Description | | ---------- | ------ | ---------------------------------------------- | | `code` | string | Error code identifier | | `message` | string | Human-readable error message | | `category` | string | Error category classification | | `details` | object | Additional error details (optional) | | `traceId` | string | Unique trace identifier for debugging purposes | Error Details Object (Optional) [#error-details-object-optional] | Field | Type | Description | | ------------------ | ------ | --------------------------------- | | `field` | string | The field that caused the error | | `message` | string | Detailed error message | | `validationErrors` | array | Array of validation error objects | Example Usage [#example-usage] cURL [#curl] ```bash filename="api-request.sh" curl "https://tachyon.rath.fi/api/user?address=0x1234567890abcdef1234567890abcdef12345678" ``` Status Codes [#status-codes] | Status Code | Description | | ----------- | --------------------------------------- | | 200 | Success - Account information retrieved | | 400 | Bad Request - Invalid address format | | 404 | Not Found - Account not found | | 500 | Internal Server Error | # Connect to WebSocket (/tachyon/tachyon-api/connect-websocket) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Connect to WebSocket [#connect-to-websocket] Establish a WebSocket connection to Tachyon to receive real-time transaction status updates via persistent connection. WebSocket URL [#websocket-url] ``` wss://tachyon.rath.fi/ws ``` Authentication [#authentication] Authenticate using the `x-ws-token` header with your WebSocket API key obtained from [Register WebSocket](/api-reference/register-websocket). Connection Example [#connection-example] ```bash filename="api-request.sh" # First, register to get API key response=$(curl -s -X POST "https://tachyon.rath.fi/api/user/register-websocket" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{}') WS_API_KEY=$(echo $response | jq -r '.data.apiKey') # Connect using websocat with custom header websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" ``` Message Types [#message-types] Transaction Notification [#transaction-notification] Sent when a transaction status changes: ```json filename="status-response.json" { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "chainId": 8453, "status": "EXECUTED", "costUSD": 0.8400561743999754, "totalNativeTokenUsed": "1000000000000000", "gasPrice": "1000000000", "txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "submittedAt": "2025-10-23T13:57:36.672Z", "updatedAt": "2025-10-23T13:57:39.172Z", "retries": 0 } } ``` Transaction Notification Fields [#transaction-notification-fields] | Field | Type | Description | | ---------------------- | ------ | -------------------------------------------------------------------------- | | `txId` | string | Transaction ID | | `chainId` | number | Blockchain network ID | | `status` | string | Transaction status: `PENDING`, `EXECUTED`, `FAILED`, `NEEDS_TO_BE_RETRIED` | | `costUSD` | number | Execution cost in USD | | `totalNativeTokenUsed` | string | Total native token spent (in smallest unit) | | `gasPrice` | string | Gas price used for the transaction | | `txHash` | string | On-chain transaction hash | | `submittedAt` | string | ISO 8601 timestamp of submission | | `updatedAt` | string | ISO 8601 timestamp of last update | | `retries` | number | Number of retry attempts | System Message [#system-message] System-level messages from the server: ```json filename="response.json" { "type": "system", "data": { "message": "Connection established successfully" } } ``` System Message Fields [#system-message-fields] | Field | Type | Description | | --------- | ------ | ---------------------- | | `message` | string | System message content | Raw Message [#raw-message] Fallback for unparsed or unknown message types: ```json filename="response.json" { "type": "raw", "data": { // Any data that doesn't match known types } } ``` Transaction Status Values [#transaction-status-values] | Status | Description | | --------------------- | ------------------------------------------ | | `PENDING` | Transaction is being processed | | `EXECUTED` | Transaction successfully executed on-chain | | `FAILED` | Transaction execution failed | | `NEEDS_TO_BE_RETRIED` | Transaction will be retried automatically | Complete Connection Flow [#complete-connection-flow] ```bash filename="api-request.sh" #!/bin/bash API_KEY="YOUR_API_KEY" # Register WebSocket and get credentials echo "Registering WebSocket..." ws_response=$(curl -s -X POST "https://tachyon.rath.fi/api/user/register-websocket" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d '{}') WS_API_KEY=$(echo $ws_response | jq -r '.data.apiKey') echo "WebSocket API Key: $WS_API_KEY" # Connect to WebSocket with authentication header echo "Connecting to WebSocket..." websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" ``` Message Handling Examples [#message-handling-examples] Filter by Message Type [#filter-by-message-type] ```bash filename="terminal" # Connect and filter for transaction notifications only websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq 'select(.type == "notification")' ``` Monitor Specific Transaction [#monitor-specific-transaction] ```bash filename="terminal" # Filter messages for a specific transaction ID TX_ID="68fa3450539a3c9d28bbca33" websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq --arg txid "$TX_ID" 'select(.data.txId == $txid)' ``` Extract Execution Hashes [#extract-execution-hashes] ```bash filename="terminal" # Extract only executed transaction hashes websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq 'select(.data.status == "EXECUTED") | .data.txHash' ``` Monitor Transaction Costs [#monitor-transaction-costs] ```bash filename="terminal" # Monitor transaction costs in real-time websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq 'select(.type == "notification") | {txId: .data.txId, cost: .data.costUSD}' ``` Connection Parameters [#connection-parameters] | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------ | | `apiKey` | string | Yes | WebSocket API key from registration (sent via `x-ws-token` header) | Example Message Flows [#example-message-flows] Successful Transaction [#successful-transaction] ```json filename="status-response.json" // 1. Transaction submitted { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "status": "PENDING", "submittedAt": "2025-10-23T13:57:36.672Z" } } // 2. Transaction executed { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "status": "EXECUTED", "txHash": "0xabcdef...", "costUSD": 0.84, "updatedAt": "2025-10-23T13:57:39.172Z" } } ``` Failed Transaction with Retry [#failed-transaction-with-retry] ```json filename="status-response.json" // 1. Transaction submitted { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "status": "PENDING", "retries": 0 } } // 2. Transaction needs retry { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "status": "NEEDS_TO_BE_RETRIED", "retries": 1 } } // 3. Transaction executed after retry { "type": "notification", "data": { "txId": "68fa3450539a3c9d28bbca33", "status": "EXECUTED", "txHash": "0xabcdef...", "retries": 1 } } ``` Connection Management [#connection-management] Using wscat [#using-wscat] ```bash filename="install-dependencies.sh" # Install wscat npm install -g wscat # Connect with custom header wscat -c "wss://tachyon.rath.fi/ws" -H "x-ws-token: $WS_API_KEY" ``` Using websocat [#using-websocat] ```bash filename="terminal" # Install websocat # macOS: brew install websocat # Linux: cargo install websocat # Connect with custom header websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" ``` Use Cases [#use-cases] Real-Time Dashboard [#real-time-dashboard] Monitor all transaction activity: ```bash filename="terminal" websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq '{ time: .data.updatedAt, txId: .data.txId, status: .data.status, chain: .data.chainId, cost: .data.costUSD }' ``` Alert on Failures [#alert-on-failures] Get notified of failed transactions: ```bash filename="terminal" websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq 'select(.data.status == "FAILED")' ``` Cost Tracking [#cost-tracking] Track total transaction costs: ```bash filename="terminal" websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" | \ jq -r 'select(.data.status == "EXECUTED") | .data.costUSD' | \ awk '{sum+=$1} END {print "Total Cost: $" sum}' ``` Related Endpoints [#related-endpoints] * [Register WebSocket](/api-reference/register-websocket) - Get WebSocket credentials * [Register Webhooks](/api-reference/register-webhooks) - Alternative notification method * [Submit Relay Transaction](/api-reference/submit-relay-transaction) - Submit transactions Troubleshooting [#troubleshooting] Authentication Failed [#authentication-failed] Ensure you're using the correct API key in the `x-ws-token` header: ```bash filename="terminal" # Verify your API key echo $WS_API_KEY ``` Connection Closed [#connection-closed] Implement reconnection logic if connection drops: ```bash filename="terminal" #!/bin/bash while true; do echo "Connecting to WebSocket..." websocat -H="x-ws-token: $WS_API_KEY" "wss://tachyon.rath.fi/ws" echo "Connection closed. Reconnecting in 5 seconds..." sleep 5 done ``` No Messages Received [#no-messages-received] Verify: 1. WebSocket connection is established 2. API key is valid 3. Transactions are being submitted for your account # Get Supported Chains (/tachyon/tachyon-api/get-supported-chains) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Get Supported Chains [#get-supported-chains] Get a list of all blockchain networks supported by the Tachyon relay service, including chain details, native currency information, and block explorer URLs. Endpoint [#endpoint] ```http filename="endpoint" GET https://tachyon.rath.fi/api/supported-chains ``` Parameters [#parameters] This endpoint requires no parameters. Response [#response] Success Response [#success-response] ```json filename="response.json" { "success": true, "data": [ { "id": 8453, "name": "Base", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/Base.png", "isTestnet": false, "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 }, "blockExplorers": { "default": { "name": "Basescan", "url": "https://basescan.org", "apiUrl": "https://api.basescan.org/api" } } }, { "id": 1, "name": "Ethereum", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/Ethereum.png", "isTestnet": false, "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 }, "blockExplorers": { "default": { "name": "Etherscan", "url": "https://etherscan.io", "apiUrl": "https://api.etherscan.io/api" } } }, { "id": 137, "name": "Polygon", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/Polygon.png", "isTestnet": false, "nativeCurrency": { "name": "MATIC", "symbol": "MATIC", "decimals": 18 }, "blockExplorers": { "default": { "name": "PolygonScan", "url": "https://polygonscan.com", "apiUrl": "https://api.polygonscan.com/api" } } }, { "id": 88888888, "name": "Aptos", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/APT.png", "isTestnet": false, "nativeCurrency": { "name": "Aptos Coin", "symbol": "APT", "decimals": 8 }, "blockExplorers": { "default": { "name": "Aptos Explorer", "url": "https://explorer.aptoslabs.com", "apiUrl": "https://api.mainnet.aptoslabs.com/v1" } } }, { "id": 10100000, "name": "Solana", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/Solana.png", "isTestnet": false, "nativeCurrency": { "name": "Solana", "symbol": "SOL", "decimals": 9 }, "blockExplorers": { "default": { "name": "Solscan", "url": "https://solscan.io", "apiUrl": "https://api.solscan.io" } } }, { "id": 7777777, "name": "NEAR", "iconUrl": "https://d1tmxgi96tgufh.cloudfront.net/chains/NEAR.png", "isTestnet": false, "nativeCurrency": { "name": "NEAR", "symbol": "NEAR", "decimals": 24 }, "blockExplorers": { "default": { "name": "NEAR Explorer", "url": "https://nearblocks.io", "apiUrl": "https://api.nearblocks.io/v1" } } } ], "timestamp": "2025-10-24T12:34:56.789Z" } ``` Chain Object Fields [#chain-object-fields] | Field | Type | Description | | ---------------- | ------- | ------------------------------------------------------- | | `id` | number | Unique blockchain network identifier (chain ID) | | `name` | string | Human-readable name of the blockchain | | `iconUrl` | string | URL to the chain's icon/logo image | | `isTestnet` | boolean | Whether this is a testnet (`true`) or mainnet (`false`) | | `nativeCurrency` | object | Information about the chain's native currency | | `blockExplorers` | object | Block explorer information for the chain | Native Currency Object [#native-currency-object] | Field | Type | Description | | ---------- | ------ | ----------------------------------------- | | `name` | string | Full name of the native currency | | `symbol` | string | Symbol/ticker of the native currency | | `decimals` | number | Number of decimal places for the currency | Block Explorers Object [#block-explorers-object] | Field | Type | Description | | ---------------- | ------ | --------------------------------------- | | `default.name` | string | Name of the default block explorer | | `default.url` | string | URL of the block explorer website | | `default.apiUrl` | string | API endpoint URL for the block explorer | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Failed to fetch supported chains", "category": "SERVER_ERROR", "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Request [#example-request] ```bash filename="terminal" curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" ``` With Formatted Output (jq) [#with-formatted-output-jq] ```bash filename="terminal" curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | { id: .id, name: .name, isTestnet: .isTestnet, currency: .nativeCurrency.symbol }' ``` **Example Output:** ```json filename="example-output.json" { "id": 8453, "name": "Base", "isTestnet": false, "currency": "ETH" } { "id": 1, "name": "Ethereum", "isTestnet": false, "currency": "ETH" } { "id": 137, "name": "Polygon", "isTestnet": false, "currency": "MATIC" } ``` Filter Mainnet Chains Only [#filter-mainnet-chains-only] ```bash filename="terminal" curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | select(.isTestnet == false)' ``` Filter Testnet Chains Only [#filter-testnet-chains-only] ```bash filename="terminal" curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | select(.isTestnet == true)' ``` Get Chain by ID [#get-chain-by-id] ```bash filename="terminal" # Get information for Base (chain ID 8453) curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | select(.id == 8453)' ``` List All Chain IDs and Names [#list-all-chain-ids-and-names] ```bash filename="terminal" curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq -r '.data[] | "\(.id) - \(.name)"' ``` **Example Output:** ```text filename="output.txt" 8453 - Base 1 - Ethereum 137 - Polygon 42161 - Arbitrum One 10 - Optimism 88888888 - Aptos 10100000 - Solana 7777777 - NEAR ``` Use Cases [#use-cases] Dynamic Chain Selection [#dynamic-chain-selection] Populate a chain selector in your application UI: ```bash filename="terminal" # Get chain data for a dropdown menu curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | { value: .id, label: .name, icon: .iconUrl, disabled: .isTestnet }' ``` Chain Validation [#chain-validation] Validate if a chain ID is supported before submitting transactions: ```bash filename="chain-validation.sh" #!/bin/bash CHAIN_ID=8453 RESPONSE=$(curl -s "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY") IS_SUPPORTED=$(echo $RESPONSE | jq --arg id "$CHAIN_ID" '.data[] | select(.id == ($id | tonumber)) | .id') if [ -n "$IS_SUPPORTED" ]; then echo "Chain ID $CHAIN_ID is supported" else echo "Chain ID $CHAIN_ID is not supported" fi ``` Get Block Explorer URLs [#get-block-explorer-urls] Retrieve block explorer information for transaction tracking: ```bash filename="terminal" # Get block explorer for Base curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | select(.id == 8453) | .blockExplorers.default' ``` **Example Output:** ```json filename="block-explorer.json" { "name": "Basescan", "url": "https://basescan.org", "apiUrl": "https://api.basescan.org/api" } ``` Currency Information Lookup [#currency-information-lookup] Get native currency details for balance display: ```bash filename="terminal" # Get currency info for multiple chains curl "https://tachyon.rath.fi/api/supported-chains" \ -H "api-key: YOUR_API_KEY" | jq '.data[] | { chain: .name, currency: .nativeCurrency.symbol, decimals: .nativeCurrency.decimals }' ``` Response Notes [#response-notes] * **Chain IDs**: Unique identifiers following blockchain standards * EVM chains use standard chain IDs (e.g., 1 for Ethereum, 8453 for Base) * Non-EVM chains use custom identifiers (e.g., 88888888 for Aptos) * **Decimals**: Important for amount conversion * EVM chains typically use 18 decimals * Solana uses 9 decimals (lamports) * NEAR uses 24 decimals (yoctoNEAR) * Aptos uses 8 decimals (octas) * **Testnet Chains**: Can be filtered using the `isTestnet` field * `false`: Mainnet chain (production use) * `true`: Testnet chain (development/testing) # Register Webhooks (/tachyon/tachyon-api/reg-webhook) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Register Webhooks [#register-webhooks] Register one or more webhook endpoints to receive real-time notifications about transaction events and status updates. Endpoint [#endpoint] ```http filename="endpoint" POST /api/user/register-webhooks ``` Quick Start [#quick-start] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://myapp.com/webhook", "authType": "bearer", "secret": "my-bearer-token" }, { "url": "https://api.example.com/tachyon-events", "authType": "api-key", "apiKeyPlacement": "header", "apiKeyVar": "X-API-Key", "secret": "my-api-key-value" }, { "url": "https://myapp.com/public-webhook", "authType": "none" } ]' ``` Request [#request] Headers [#headers] | Header | Required | Description | | --------------- | -------- | ------------------------------------------------------------- | | `Content-Type` | Yes | Must be `application/json` | | `Authorization` | Yes | Bearer token with your Tachyon API key: `Bearer YOUR_API_KEY` | Body [#body] The request body must be a JSON array of webhook registration objects. Each object must conform to the following schema: | Name | Type | Required | Description | | ----------------- | -------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `url` | `string` | Yes | Webhook endpoint URL. Must be a valid URL starting with `http://` or `https://`. | | `authType` | `"none"` \| `"bearer"` \| `"basic"` \| `"api-key"` | Yes | Authentication method for securing webhook requests. | | `secret` | `string` | Conditional | Secret/token value used for authentication. Required for `bearer` and `basic` auth types. For `api-key`, this is the API key value. | | `apiKeyVar` | `string` | No | The header name or query parameter name where the API key should be sent. Used with `api-key` auth type. | | `apiKeyPlacement` | `"header"` \| `"query"` | Conditional | Where to place the API key in the request. **Required** when `authType` is `"api-key"`. | Authentication Types [#authentication-types] | Auth Type | Description | Required Fields | | --------- | ------------------------------------------------------------------------------------------- | --------------------------- | | `none` | No authentication. Webhook endpoint is publicly accessible. | None | | `bearer` | Bearer token authentication. Token sent in `Authorization: Bearer {token}` header. | `secret` | | `basic` | HTTP Basic authentication. Credentials sent in `Authorization: Basic {credentials}` header. | `secret` | | `api-key` | API key authentication. Key can be sent in header or query parameter. | `secret`, `apiKeyPlacement` | Important Constraints [#important-constraints] * **URL Validation**: Webhook URL must start with `http://` or `https://` and be a valid URL format * **API Key Placement**: When using `authType: "api-key"`, the `apiKeyPlacement` field is **required** * **Secret Requirement**: `secret` field is required for `bearer`, `basic`, and `api-key` authentication types Response [#response] **Status Code:** `200 OK` Response Body [#response-body] | Property | Type | Description | | ---------- | ----------------- | -------------------------------------------------------------- | | `userId` | `string` | The unique identifier of the user who registered the webhooks. | | `address` | `string` | The wallet address associated with the user account. | | `webhooks` | `WebhookConfig[]` | Array of registered webhook configurations. | WebhookConfig Object [#webhookconfig-object] Each webhook in the `webhooks` array contains: | Property | Type | Description | | ----------------- | -------------------------------------------------- | --------------------------------------------------------------- | | `url` | `string` | The registered webhook endpoint URL. | | `authType` | `"none"` \| `"bearer"` \| `"basic"` \| `"api-key"` | The authentication method configured for this webhook. | | `secret` | `string` (optional) | The secret/token value (may be masked or omitted for security). | | `apiKeyVar` | `string` (optional) | The header or query parameter name for API key authentication. | | `apiKeyPlacement` | `"header"` \| `"query"` (optional) | Where the API key is placed in requests. | Example Response [#example-response] ```json filename="response.json" { "userId": "68c275846a6ba1c9a2198a8c", "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "webhooks": [ { "url": "https://myapp.com/webhook", "authType": "bearer" }, { "url": "https://api.example.com/tachyon-events", "authType": "api-key", "apiKeyPlacement": "header", "apiKeyVar": "X-API-Key" }, { "url": "https://myapp.com/public-webhook", "authType": "none" } ] } ``` Examples [#examples] Bearer Token Authentication [#bearer-token-authentication] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://myapp.com/webhook", "authType": "bearer", "secret": "my-secure-bearer-token" } ]' ``` Your webhook will receive requests with header: ``` Authorization: Bearer my-secure-bearer-token ``` API Key in Header [#api-key-in-header] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://api.example.com/webhooks", "authType": "api-key", "apiKeyPlacement": "header", "apiKeyVar": "X-API-Key", "secret": "my-api-key-12345" } ]' ``` Your webhook will receive requests with header: ``` X-API-Key: my-api-key-12345 ``` API Key in Query Parameter [#api-key-in-query-parameter] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://api.example.com/webhooks", "authType": "api-key", "apiKeyPlacement": "query", "apiKeyVar": "apiKey", "secret": "my-api-key-12345" } ]' ``` Your webhook will receive requests at: ```text filename="webhook-url.txt" https://api.example.com/webhooks?apiKey=my-api-key-12345 ``` Basic Authentication [#basic-authentication] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://myapp.com/webhook", "authType": "basic", "secret": "username:password" } ]' ``` Your webhook will receive requests with header: ```text filename="auth-header.txt" Authorization: Basic base64(username:password) ``` No Authentication (Public Endpoint) [#no-authentication-public-endpoint] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://myapp.com/public-webhook", "authType": "none" } ]' ``` Your webhook receives requests without authentication headers. Multiple Webhooks [#multiple-webhooks] ```bash filename="terminal" curl -X POST https://api.tachyon.xyz/api/user/register-webhooks \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '[ { "url": "https://myapp.com/webhook-1", "authType": "bearer", "secret": "token-1" }, { "url": "https://myapp.com/webhook-2", "authType": "api-key", "apiKeyPlacement": "header", "apiKeyVar": "X-API-Key", "secret": "key-2" }, { "url": "https://myapp.com/webhook-3", "authType": "none" } ]' ``` Use Cases [#use-cases] * **Transaction Monitoring**: Receive real-time notifications when transactions are submitted, executed, or fail * **Status Updates**: Get notified about changes in transaction status across multiple chains * **Event Tracking**: Track specific events related to your relay transactions * **Multi-Environment Setup**: Register different webhooks for development, staging, and production environments * **Microservices Architecture**: Route transaction events to different services based on their purpose # Register WebSocket (/tachyon/tachyon-api/reg-websocket) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Register WebSocket [#register-websocket] Register a WebSocket connection to receive real-time transaction status updates via persistent connection. Endpoint [#endpoint] ``` POST https://tachyon.rath.fi/api/user/register-websocket ``` Request Body [#request-body] ```json filename="websocket-response.json" {} ``` Response [#response] Success Response [#success-response] ```json filename="websocket-response.json" { "success": true, "data": { "wsUrl": "wss://tachyon.rath.fi/ws", "apiKey": "ws_1234567890abcdef1234567890abcdef" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Response Fields [#response-fields] | Field | Type | Description | | -------- | ------ | ------------------------------------------------------------- | | `wsUrl` | string | WebSocket server URL to connect to | | `apiKey` | string | Persistent user-specific API key for WebSocket authentication | Error Response [#error-response] ```json filename="websocket-response.json" { "success": false, "error": { "code": "WEBSOCKET_REGISTRATION_FAILED", "message": "Failed to register websocket", "category": "SERVER_ERROR", "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Request [#example-request] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/user/register-websocket" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{}' ``` Connecting to WebSocket [#connecting-to-websocket] After registration, use the returned credentials to connect: ```bash filename="api-request.sh" # Register and extract credentials response=$(curl -s -X POST "https://tachyon.rath.fi/api/user/register-websocket" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{}') WS_URL=$(echo $response | jq -r '.data.wsUrl') WS_API_KEY=$(echo $response | jq -r '.data.apiKey') # Connect using websocat websocat "$WS_URL?apiKey=$WS_API_KEY" ``` WebSocket Message Format [#websocket-message-format] Incoming Messages [#incoming-messages] ```json filename="status-response.json" { "event": "transaction.status_changed", "timestamp": "2025-10-24T12:34:56.789Z", "data": { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "status": "EXECUTED", "executionTxHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "timestamp": "2025-10-23T13:57:36.672Z", "latency": 2500, "costUSD": 0.8400561743999754, "error": null } } ``` Event Types [#event-types] | Event | Description | | ---------------------------- | ------------------------------ | | `transaction.status_changed` | Transaction status has changed | Transaction Status Values [#transaction-status-values] | Status | Description | | --------------------- | ------------------------------------------- | | `NOT_PICKED_UP` | Transaction submitted but not yet picked up | | `PICKED_UP` | Transaction picked up by relayer | | `PENDING` | Transaction being processed | | `EXECUTED` | Transaction successfully executed | | `FAILED` | Transaction execution failed | | `NEEDS_TO_BE_RETRIED` | Transaction will be retried | Authentication [#authentication] Connect to WebSocket using the API key as a query parameter: ``` wss://tachyon.rath.fi/ws?apiKey=ws_1234567890abcdef1234567890abcdef ``` The `apiKey` is: * **Persistent**: Can be reused for multiple connections * **User-specific**: Tied to your account * **Long-lived**: Does not expire unless regenerated Complete Example [#complete-example] ```bash filename="terminal" #!/bin/bash API_KEY="YOUR_API_KEY" # Register WebSocket echo "Registering WebSocket..." ws_response=$(curl -s -X POST "https://tachyon.rath.fi/api/user/register-websocket" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d '{}') # Extract credentials WS_URL=$(echo $ws_response | jq -r '.data.wsUrl') WS_API_KEY=$(echo $ws_response | jq -r '.data.apiKey') echo "WebSocket URL: $WS_URL" echo "WebSocket API Key: $WS_API_KEY" # Connect to WebSocket echo "Connecting to WebSocket..." websocat "$WS_URL?apiKey=$WS_API_KEY" ``` # Submit Signed Transaction API (/tachyon/tachyon-api/relay-tx-signed) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Submit Signed Transaction API [#submit-signed-transaction-api] Submit a pre-signed transaction to the Tachyon relay network. Tachyon will automatically fund the sender address with the required balance before broadcasting the transaction. Endpoint [#endpoint] ``` POST /api/submit-signed-tx ``` Authentication [#authentication] This endpoint requires API key authentication via the `api-key` header. **Headers:** ``` api-key: YOUR_API_KEY Content-Type: application/json ``` Request Body [#request-body] | Field | Type | Required | Description | | -------------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------- | | `signedTx` | `string` | Yes | The complete signed transaction data in hexadecimal format, ready for broadcast. | | `minBalanceRequired` | `string` | Yes | The minimum balance required in the sender's account (in smallest unit - wei for EVM). Typically `gasLimit * maxFeePerGas`. | | `fromAddress` | `string` | Yes | The address that signed the transaction. Must be a valid address for the specified chain. | | `chainId` | `number` | Yes | The blockchain network ID. Must be a supported chain. | | `label` | `string` | No | Human-readable label for transaction identification and tracking. | Request Example [#request-example] ```bash filename="api-request.sh" curl -X POST https://api.tachyon.xyz/api/submit-signed-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "signedTx": "0x02f8730182...", "minBalanceRequired": "42000000000000", "fromAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "chainId": 8453, "label": "Token Transfer" }' ``` **JavaScript Example:** ```javascript filename="submit-signed-tx.js" const response = await fetch('https://api.tachyon.xyz/api/submit-signed-tx', { method: 'POST', headers: { 'api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ signedTx: '0x02f8730182...', minBalanceRequired: '42000000000000', fromAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', chainId: 8453, label: 'Token Transfer', }), }) const data = await response.json() console.log('Transaction ID:', data.data.txId) ``` Response [#response] Success Response (201 Created) [#success-response-201-created] ```json filename="response.json" { "success": true, "data": { "txId": "671a2b4c539a3c9d28bbca33" }, "error": null } ``` **Response Fields:** * `success` (boolean): Indicates if the request was successful * `data.txId` (string): Unique transaction identifier for tracking * `error` (null): No error on success Error Responses [#error-responses] 400 Bad Request - Validation Error [#400-bad-request---validation-error] **Invalid Address:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "VALIDATION_INVALID_ADDRESS", "message": "Invalid from address", "details": { "address": "0xinvalid" } } } ``` **Missing Required Field:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "VALIDATION_ERROR", "message": "Missing signed transaction data" } } ``` **Unsupported Chain:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "CHAIN_UNSUPPORTED", "message": "Unsupported chainId", "details": { "chainId": 999999 } } } ``` 401 Unauthorized [#401-unauthorized] **Invalid API Key:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "AUTH_UNAUTHORIZED", "message": "Invalid API key" } } ``` **Account Disabled:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "AUTH_UNAUTHORIZED", "message": "Account is disabled" } } ``` 403 Forbidden [#403-forbidden] **Chain Disabled:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "CHAIN_UNSUPPORTED", "message": "Chain is disabled for this account", "details": { "chainId": 8453 } } } ``` **Cost Exceeded:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "TRANSACTION_COST_EXCEEDED", "message": "Transaction cost exceeds maximum allowed", "details": { "estimatedCost": 15.5, "maxFee": 10.0 } } } ``` **Insufficient Balance:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "TRANSACTION_INSUFFICIENT_BALANCE", "message": "Insufficient account balance", "details": { "requiredBalance": 10.5, "availableBalance": 5.0 } } } ``` **Daily Limit Exceeded:** ```json filename="error-response.json" { "success": false, "data": null, "error": { "code": "TRANSACTION_DAILY_LIMIT_EXCEEDED", "message": "Daily spending limit exceeded", "details": { "requiredDailyLimit": 150.0, "currentDailyLimit": 100.0 } } } ``` How It Works [#how-it-works] 1. **Authentication**: Your API key is validated and account status is checked 2. **Validation**: Request body is validated against the schema, including address format 3. **Cost Estimation**: Funding cost is calculated based on `minBalanceRequired` and current token prices 4. **Limit Checks**: Per-transaction and daily spending limits are verified 5. **Balance Check**: Your Tachyon account balance is verified against the funding cost 6. **Transaction Creation**: A funding-signed transaction is created with status `NOT_PICKED_UP` 7. **Queue Submission**: Transaction is added to the relay queue for processing 8. **Response**: Transaction ID is returned for status tracking Cost Calculation [#cost-calculation] The cost for a signed transaction includes: * **Funding Cost**: The `minBalanceRequired` converted to USD using current token prices * **Service Fee**: 8% markup applied to the funding cost **Formula:** ``` Total Cost (USD) = minBalanceRequired (in native tokens) × Token Price (USD) × 1.08 ``` **Example (Base Mainnet):** ```javascript filename="example.js" // Transaction details gasLimit = 21000 maxFeePerGas = 2 gwei (0.000000002 ETH) minBalanceRequired = 21000 × 0.000000002 = 0.000042 ETH // If ETH price = $3,000 fundingCost = 0.000042 × 3000 = $0.126 totalCost = $0.126 × 1.08 = $0.13608 ``` Transaction Lifecycle [#transaction-lifecycle] After submission, the transaction goes through these stages: 1. **NOT\_PICKED\_UP**: Transaction is queued and waiting to be processed 2. **PENDING**: Relay service is funding the address and preparing to broadcast 3. **EXECUTED**: Transaction has been broadcast and confirmed on-chain 4. **FAILED**: Transaction failed (with error details) Track transaction status using the [Get Relay Status API](/api/relay-status) or the [SDK status methods](/sdk/relay-transactions#getrelaystatus). *** Rate Limits [#rate-limits] This endpoint is subject to the following limits: * **Account Balance**: Must have sufficient balance for the funding cost * **Per-Transaction Limit**: Default $100 per transaction (configurable per account) * **Daily Limit**: Account-specific daily spending limit * **Rate Limiting**: Standard API rate limits apply *** Notes [#notes] * The `fromAddress` will be automatically funded with `minBalanceRequired` before broadcasting * The signed transaction must be valid and ready for broadcast * Ensure `minBalanceRequired` covers the maximum possible gas cost * Transaction type is automatically set to `FUNDING_SIGNED` * Sepolia testnet has a higher limit of $100 per transaction * Daily limits reset at midnight UTC # Relay Transaction Sync (/tachyon/tachyon-api/relay-tx-sync) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Submit Relay Transaction Sync [#submit-relay-transaction-sync] Submit a transaction to the Tachyon relay network and keep the request open until the transaction reaches a terminal state or the sync timeout expires. This endpoint is useful when you want submission and the latest known transaction status in a single API call. Endpoint [#endpoint] ``` POST https://tachyon.rath.fi/api/submit-tx-sync ``` Request Body [#request-body] | Parameter | Type | Required | Description | | ------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------- | | `tx` | object | Yes | Transaction payload. Uses the same transaction fields as `/api/submit-tx`. | | `timeoutMs` | number | No | Maximum time to wait before returning. Defaults to `30000`. Minimum `1000`, maximum `120000`. | | `includeReceipt` | boolean | No | Include the transaction receipt when available. Defaults to `false`. | | `includeRevertInfo` | boolean | No | Include decoded revert information for failed transactions when available. Defaults to `false`. | tx Object [#tx-object] | Parameter | Type | Required | Description | | ------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | number | Yes | The blockchain network ID where the transaction will be executed | | `to` | string | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR) | | `callData` | string | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers) | | `value` | string | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Defaults to '0' | | `label` | string | No | Optional human-readable label for easier transaction identification and tracking | | `gasLimit` | string | No | Optional gas limit for the transaction. If not specified, it will be estimated automatically. Required for Aptos and Sui transactions | | `gasPrice` | string | No | Gas price in wei (for legacy transactions). Cannot be used with maxFeePerGas or maxPriorityFeePerGas | | `maxFeePerGas` | string | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with maxPriorityFeePerGas | | `maxPriorityFeePerGas` | string | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with maxFeePerGas | | `maxUSD` | number | No | Maximum cost in USD that you're willing to pay for this transaction | | `shouldBatchInMulticall` | boolean | No | Whether to batch this transaction in a multicall | | `retries` | number | No | Number of retries if transaction fails. Defaults to 0 | | `isAuthenticatedTx` | boolean | No | Enable authenticated relay mode for additional security and verification. Defaults to false | | `derivationPath` | string | No | Optional HD wallet derivation path for transaction signing (useful for multi-account setups) | | `transactionType` | string | No | Type of relay transaction: `"flash"` (default), `"authenticated"`, `"funding-signed"`, or `"flash-blocks"` (Base/Base Sepolia only) | | `authorizationList` | array | No | Optional list of authorization entries for delegated transactions or batched operations (EIP-7702). Not allowed for flash-blocks transactions | AuthorizationListItem Object [#authorizationlistitem-object] When using `authorizationList`, each item should contain: | Field | Type | Required | Description | | --------- | ------------- | -------- | -------------------------------------------- | | `chainId` | number | Yes | Chain ID for the authorization | | `address` | string | Yes | Ethereum address (must start with "0x") | | `nonce` | number | Yes | Nonce for the authorization | | `r` | string | Yes | Signature r component (must start with "0x") | | `s` | string | Yes | Signature s component (must start with "0x") | | `yParity` | number | Yes | Signature y parity (0 or 1) | | `v` | number/bigint | No | Optional signature v value | Gas Parameter Rules [#gas-parameter-rules] * **Legacy transactions**: Use `gasPrice` only * **EIP-1559 transactions**: Use both `maxFeePerGas` and `maxPriorityFeePerGas` together * You cannot mix `gasPrice` with `maxFeePerGas` or `maxPriorityFeePerGas` Response [#response] If the transaction reaches a terminal state within the timeout, the API returns `200 OK`. If the timeout expires first, the API returns the latest known status with `202 Accepted` and `timedOut: true`. Success Response (`200 OK`) [#success-response-200-ok] ```json filename="response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": "21000", "label": "My Base Transaction", "status": "EXECUTED", "executionTxHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "timestamp": "2025-10-24T12:34:56.789Z", "latency": 2500, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": true, "extraData": null, "transactionType": "flash" }, "timestamp": "2025-10-24T12:34:59.500Z" } ``` Timed Out Response (`202 Accepted`) [#timed-out-response-202-accepted] ```json filename="timeout-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": "21000", "label": "My Base Transaction", "status": "PENDING", "executionTxHash": null, "timestamp": "2025-10-24T12:34:56.789Z", "latency": null, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": false, "extraData": null, "transactionType": "flash", "timedOut": true }, "timestamp": "2025-10-24T12:35:26.789Z" } ``` Response Fields [#response-fields] | Field | Type | Description | | ---------------------- | -------------- | ---------------------------------------------------------------------------- | | `id` | string | Unique transaction identifier | | `userId` | string | User ID associated with the transaction | | `to` | string | Recipient address | | `callData` | string | Encoded transaction data in hexadecimal format | | `value` | string | Amount transferred in the smallest unit for the target chain | | `chainId` | number | Blockchain network ID where the transaction was submitted | | `gasPrice` | string \| null | Gas price used for the transaction | | `maxFeePerGas` | string \| null | Maximum fee per gas unit for EIP-1559 transactions | | `maxPriorityFeePerGas` | string \| null | Maximum priority fee per gas for EIP-1559 transactions | | `gasLimit` | string \| null | Gas limit for the transaction | | `label` | string | Human-readable transaction label | | `status` | string | Current transaction status (see status values below) | | `executionTxHash` | string \| null | On-chain transaction hash (null until available) | | `timestamp` | string | ISO 8601 timestamp of transaction submission | | `latency` | number \| null | Time taken for execution in milliseconds | | `costUSD` | number | Transaction cost in USD | | `retries` | number | Number of retry attempts made | | `isAccountCharged` | boolean | Whether the account has been charged for the transaction | | `extraData` | any | Additional transaction metadata | | `transactionType` | string | Relay transaction type used for execution | | `error` | string \| null | Error message if the transaction failed | | `timedOut` | boolean | Present when the sync wait window expires before a terminal state is reached | | `receipt` | object | Present when `includeReceipt` is `true` and a receipt is available | | `revert` | object | Present when `includeRevertInfo` is `true` and revert data is available | Transaction Status Values [#transaction-status-values] | Status | Description | | --------------------- | ------------------------------------------------------ | | `NOT_PICKED_UP` | Transaction submitted but not yet picked up by relayer | | `PICKED_UP` | Transaction picked up by relayer, awaiting execution | | `PENDING` | Transaction is being processed | | `NEEDS_TO_BE_RETRIED` | Transaction execution failed and will be retried | | `EXECUTED` | Transaction successfully executed on-chain | | `FAILED` | Transaction execution failed permanently | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "INVALID_PARAMETERS", "message": "Missing required transaction parameters", "category": "VALIDATION_ERROR", "details": { "field": "chainId", "message": "chainId is required" }, "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Requests [#example-requests] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "label": "My Base Transaction" }, "timeoutMs": 30000 }' ``` **Aptos** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 88888888, "to": "0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219", "value": "1", "callData": "0x", "gasLimit": "100", "label": "My Aptos Transaction" }, "timeoutMs": 30000 }' ```
**Note:** Gas limit is required for Aptos transactions.
**Solana** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 10100000, "to": "BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm", "value": "1000000", "callData": "0x", "label": "My Solana Transaction" }, "timeoutMs": 30000 }' ``` **Sui** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 897796746, "to": "0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0", "value": "100000000", "callData": "0x", "gasLimit": "3000000", "label": "send-native-sui" }, "timeoutMs": 30000 }' ```
**Note:** Gas limit is required for Sui transactions. Value is denominated in MIST (1 SUI = 10^9 MIST).
**NEAR** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 7777777, "to": "deeprice6887.near", "value": "1000000000000000000000000", "callData": "0x", "label": "My NEAR Transaction" }, "timeoutMs": 30000 }' ``` **Starknet** ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "to": "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", "callData": "0x", "value": "1", "chainId": 23448594291968334, "label": "send strk", "retries": 0 }, "timeoutMs": 30000 }' ```
Advanced Examples [#advanced-examples] Include Receipt [#include-receipt] ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "label": "Receipt Example" }, "timeoutMs": 45000, "includeReceipt": true }' ``` Include Revert Information [#include-revert-information] ```bash filename="submit-transaction-sync.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx-sync" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "tx": { "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "0", "callData": "0xdeadbeef", "label": "Failed Transaction Example" }, "timeoutMs": 45000, "includeRevertInfo": true }' ``` Continue Tracking After Timeout [#continue-tracking-after-timeout] If the response includes `timedOut: true`, continue checking the transaction with the standard relay status endpoint using the returned `id`: ```bash filename="check-status.sh" curl "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY" ``` # Relay Transaction (/tachyon/tachyon-api/relay-tx) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Submit Relay Transaction [#submit-relay-transaction] Submit a transaction to the Tachyon relay network for execution. The relay service handles gas payments and transaction submission on your behalf, returning a unique transaction ID for tracking. Endpoint [#endpoint] ``` POST https://tachyon.rath.fi/api/submit-tx ``` Request Body [#request-body] | Parameter | Type | Required | Description | | ------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | number | Yes | The blockchain network ID where the transaction will be executed | | `to` | string | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR) | | `callData` | string | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers) | | `value` | string | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Defaults to '0' | | `label` | string | No | Optional human-readable label for easier transaction identification and tracking | | `gasLimit` | string | No | Optional gas limit for the transaction. If not specified, it will be estimated automatically. Required for Aptos and Sui transactions | | `gasPrice` | string | No | Gas price in wei (for legacy transactions). Cannot be used with maxFeePerGas or maxPriorityFeePerGas | | `maxFeePerGas` | string | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with maxPriorityFeePerGas | | `maxPriorityFeePerGas` | string | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with maxFeePerGas | | `maxUSD` | number | No | Maximum cost in USD that you're willing to pay for this transaction | | `shouldBatchInMulticall` | boolean | No | Whether to batch this transaction in a multicall | | `retries` | number | No | Number of retries if transaction fails. Defaults to 0 | | `isAuthenticatedTx` | boolean | No | Enable authenticated relay mode for additional security and verification. Defaults to false | | `derivationPath` | string | No | Optional HD wallet derivation path for transaction signing (useful for multi-account setups) | | `transactionType` | string | No | Type of relay transaction: `"flash"` (default), `"authenticated"`, `"funding-signed"`, or `"flash-blocks"` (Base/Base Sepolia only) | | `authorizationList` | array | No | Optional list of authorization entries for delegated transactions or batched operations (EIP-7702). Not allowed for flash-blocks transactions | AuthorizationListItem Object [#authorizationlistitem-object] When using `authorizationList`, each item should contain: | Field | Type | Required | Description | | --------- | ------------- | -------- | -------------------------------------------- | | `chainId` | number | Yes | Chain ID for the authorization | | `address` | string | Yes | Ethereum address (must start with "0x") | | `nonce` | number | Yes | Nonce for the authorization | | `r` | string | Yes | Signature r component (must start with "0x") | | `s` | string | Yes | Signature s component (must start with "0x") | | `yParity` | number | Yes | Signature y parity (0 or 1) | | `v` | number/bigint | No | Optional signature v value | Gas Parameter Rules [#gas-parameter-rules] * **Legacy transactions**: Use `gasPrice` only * **EIP-1559 transactions**: Use both `maxFeePerGas` and `maxPriorityFeePerGas` together * You cannot mix `gasPrice` with `maxFeePerGas` or `maxPriorityFeePerGas` Response [#response] Success Response [#success-response] ```json filename="response.json" { "success": true, "data": { "txId": "68fa3450539a3c9d28bbca33" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Response Fields [#response-fields] | Field | Type | Description | | ------ | ------ | ------------------------------------------------------------------------------------ | | `txId` | string | Unique transaction ID that can be used to track the transaction status and execution | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "INVALID_PARAMETERS", "message": "Missing required transaction parameters", "category": "VALIDATION_ERROR", "details": { "field": "chainId", "message": "chainId is required" }, "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Requests [#example-requests] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "label": "My Base Transaction" }' ``` **With Gas Parameters:** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "gasLimit": "21000", "label": "My Transaction with Gas Limit" }' ``` **With EIP-1559 Gas Parameters:** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "maxFeePerGas": "2000000000", "maxPriorityFeePerGas": "1000000000", "label": "EIP-1559 Transaction" }' ``` **Aptos** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 88888888, "to": "0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219", "value": "1", "callData": "0x", "gasLimit": "100", "label": "My Aptos Transaction" }' ```
**Note:** Gas limit is required for Aptos transactions.
**Solana** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 10100000, "to": "BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm", "value": "1000000", "callData": "0x", "label": "My Solana Transaction" }' ``` **Sui** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 897796746, "to": "0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0", "value": "100000000", "callData": "0x", "gasLimit": "3000000", "label": "send-native-sui" }' ```
**Note:** Gas limit is required for Sui transactions. Value is denominated in MIST (1 SUI = 10^9 MIST).
**NEAR** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 7777777, "to": "deeprice6887.near", "value": "1000000000000000000000000", "callData": "0x", "label": "My NEAR Transaction" }' ``` **NEAR** ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "to": "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", "callData": "0x", "value": "1", "chainId": 23448594291968334, "label": "send strk", "retries": 0 }' ```
Advanced Examples [#advanced-examples] Transaction with Max USD Limit [#transaction-with-max-usd-limit] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "maxUSD": 5.0, "label": "Transaction with USD Cap" }' ``` Authenticated Transaction [#authenticated-transaction] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "transactionType": "authenticated", "isAuthenticatedTx": true, "label": "Authenticated Transaction" }' ``` Flash-Blocks Transaction [#flash-blocks-transaction] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "transactionType": "flash-blocks", "label": "Flash-Blocks Transaction" }' ```
**Note:** Flash-blocks transaction type is only supported on Base (8453) and Base Sepolia (84532). Authorization lists cannot be used with flash-blocks transactions.
Transaction with Authorization List (EIP-7702) [#transaction-with-authorization-list-eip-7702] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "authorizationList": [ { "chainId": 8453, "address": "0x1234567890abcdef1234567890abcdef12345678", "nonce": 1, "r": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "s": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "yParity": 1 } ], "label": "Delegated Transaction" }' ``` With Custom Derivation Path [#with-custom-derivation-path] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "derivationPath": "m/44'\''/60'\''/0'\''/0/1", "label": "Transaction from Custom Account" }' ``` Transaction with Multicall Batching [#transaction-with-multicall-batching] ```bash filename="submit-transaction.sh" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "0", "callData": "0xa9059cbb000000000000000000000000...", "shouldBatchInMulticall": true, "label": "Batched Transaction" }' ``` Transaction with Retries [#transaction-with-retries] ```bash filename="terminal" curl -X POST "https://tachyon.rath.fi/api/submit-tx" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "retries": 3, "label": "Transaction with Auto-Retry" }' ``` # Get Relay Status (/tachyon/tachyon-api/relay_status) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Get Relay Status [#get-relay-status] Get the current status of a submitted transaction, including execution details, costs, and on-chain transaction hash once available. Endpoint [#endpoint] ``` GET https://tachyon.rath.fi/api/tx?id={txId} ``` Query Parameters [#query-parameters] | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------------------------------- | | `id` | string | Yes | The transaction ID returned from submitting a relay transaction | Response [#response] Success Response [#success-response] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": "1000000000", "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": "21000", "label": "My Transaction", "status": "EXECUTED", "executionTxHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "timestamp": "2025-10-23T13:57:36.672Z", "latency": 2500, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": true, "extraData": null, "error": null }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Response Fields [#response-fields] | Field | Type | Description | | ---------------------- | -------------- | ---------------------------------------------------------------------------- | | `id` | string | Unique transaction identifier | | `userId` | string | User ID associated with the transaction | | `to` | string | Recipient address | | `callData` | string | Encoded transaction data in hexadecimal format | | `value` | string | Amount transferred in smallest unit (wei for EVM, lamports for Solana, etc.) | | `chainId` | number | Blockchain network ID where the transaction was submitted | | `gasPrice` | string | Gas price used for the transaction | | `maxFeePerGas` | string \| null | Maximum fee per gas unit (EIP-1559 transactions) | | `maxPriorityFeePerGas` | string \| null | Maximum priority fee per gas (EIP-1559 transactions) | | `gasLimit` | string | Gas limit for the transaction | | `label` | string | Human-readable transaction label | | `status` | string | Current transaction status (see status values below) | | `executionTxHash` | string \| null | On-chain transaction hash (null until executed) | | `timestamp` | string | ISO 8601 timestamp of transaction submission | | `latency` | number | Time taken for execution in milliseconds (0 if not executed) | | `costUSD` | number | Transaction cost in USD | | `retries` | number | Number of retry attempts made | | `isAccountCharged` | boolean | Whether the account has been charged for the transaction | | `extraData` | any | Additional transaction metadata | | `error` | string \| null | Error message if transaction failed | Transaction Status Values [#transaction-status-values] | Status | Description | | --------------------- | ------------------------------------------------------ | | `NOT_PICKED_UP` | Transaction submitted but not yet picked up by relayer | | `PICKED_UP` | Transaction picked up by relayer, awaiting execution | | `PENDING` | Transaction is being processed | | `NEEDS_TO_BE_RETRIED` | Transaction execution failed and will be retried | | `EXECUTED` | Transaction successfully executed on-chain | | `FAILED` | Transaction execution failed permanently | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "NOT_FOUND", "message": "Transaction not found", "category": "NOT_FOUND_ERROR", "details": { "field": "id", "message": "No transaction found with the provided ID" }, "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Requests [#example-requests] Basic Status Check [#basic-status-check] ```bash filename="check-status.sh" curl "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY" ``` Check Multiple Transactions [#check-multiple-transactions] You can check multiple transactions by making separate requests: ```bash filename="check-status.sh" #!/bin/bash TX_IDS=("68fa3450539a3c9d28bbca33" "68fa3450539a3c9d28bbca34" "68fa3450539a3c9d28bbca35") for tx_id in "${TX_IDS[@]}"; do echo "Checking status for transaction: $tx_id" curl "https://tachyon.rath.fi/api/tx?id=$tx_id" \ -H "api-key: YOUR_API_KEY" echo "" done ``` With jq for Formatted Output [#with-jq-for-formatted-output] ```bash filename="check-status.sh" curl "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY" | jq '{ id: .data.id, status: .data.status, executionHash: .data.executionTxHash, cost: .data.costUSD, latency: .data.latency }' ``` **Example Output:** ```json filename="status-response.json" { "id": "68fa3450539a3c9d28bbca33", "status": "EXECUTED", "executionHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "cost": 0.8400561743999754, "latency": 2500 } ``` Response Examples by Status [#response-examples-by-status] Not Picked Up [#not-picked-up] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "status": "NOT_PICKED_UP", "executionTxHash": null, "latency": 0, "costUSD": 0.8400561743999754, "error": null, ... } } ``` Picked Up / Pending [#picked-up--pending] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "status": "PICKED_UP", "executionTxHash": null, "latency": 0, "costUSD": 0.8400561743999754, "error": null, ... } } ``` Executed [#executed] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "status": "EXECUTED", "executionTxHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "latency": 2500, "costUSD": 0.8400561743999754, "isAccountCharged": true, "error": null, ... } } ``` Failed [#failed] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "status": "FAILED", "executionTxHash": null, "latency": 1500, "costUSD": 0, "isAccountCharged": false, "error": "Insufficient gas for transaction execution", ... } } ``` Needs Retry [#needs-retry] ```json filename="status-response.json" { "success": true, "data": { "id": "68fa3450539a3c9d28bbca33", "status": "NEEDS_TO_BE_RETRIED", "executionTxHash": null, "latency": 0, "costUSD": 0.8400561743999754, "retries": 2, "error": "Network congestion - retrying", ... } } ``` Understanding Costs and Charging [#understanding-costs-and-charging] * **costUSD**: Shows the estimated or actual transaction cost * **isAccountCharged**: * `false`: Account not yet charged (transaction pending or failed) * `true`: Account has been charged (transaction executed successfully) * **Estimated vs Actual Cost**: Before execution, `costUSD` shows the estimate. After execution, it shows the actual cost. Use Cases [#use-cases] Transaction Monitoring [#transaction-monitoring] Check transaction status periodically to update your UI: ```bash filename="check-status.sh" # Check status every 5 seconds while true; do status=$(curl -s "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY" | jq -r '.data.status') echo "Current status: $status" if [ "$status" = "EXECUTED" ] || [ "$status" = "FAILED" ]; then break fi sleep 5 done ``` Cost Tracking [#cost-tracking] Retrieve cost information for accounting: ```bash filename="check-status.sh" curl "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY" | jq '{ transactionId: .data.id, cost: .data.costUSD, charged: .data.isAccountCharged, timestamp: .data.timestamp }' ``` Error Handling [#error-handling] Check for errors and retry logic: ```bash filename="terminal" response=$(curl -s "https://tachyon.rath.fi/api/tx?id=68fa3450539a3c9d28bbca33" \ -H "api-key: YOUR_API_KEY") status=$(echo $response | jq -r '.data.status') error=$(echo $response | jq -r '.data.error') if [ "$status" = "FAILED" ]; then echo "Transaction failed: $error" # Implement retry or notification logic elif [ "$status" = "NEEDS_TO_BE_RETRIED" ]; then echo "Transaction will be retried automatically" fi ``` # Get Transaction Quote (/tachyon/tachyon-api/tx-quote) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Get Transaction Quote [#get-transaction-quote] Before submitting a transaction, you can request a quote to estimate the cost in USD and the minimum balance required. This helps you understand the transaction cost upfront and ensure your account has sufficient balance. Endpoint [#endpoint] ``` POST https://tachyon.rath.fi/api/quote ``` Request Body [#request-body] | Parameter | Type | Required | Description | | ------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | number | Yes | The blockchain network ID where the transaction will be executed | | `to` | string | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR) | | `value` | string | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Defaults to '0' | | `callData` | string | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers) | | `label` | string | No | Optional human-readable label for tracking | | `gasLimit` | string | No | Optional gas limit for the transaction. Required for Aptos and Sui transactions | | `gasPrice` | string | No | Gas price in wei (for legacy transactions). Cannot be used with maxFeePerGas or maxPriorityFeePerGas | | `maxFeePerGas` | string | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with maxPriorityFeePerGas | | `maxPriorityFeePerGas` | string | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with maxFeePerGas | | `maxUSD` | number | No | Maximum cost in USD that you're willing to pay for this transaction | | `shouldBatchInMulticall` | boolean | No | Whether to batch this transaction in a multicall | | `retries` | number | No | Number of retries if transaction fails. Defaults to 0 | | `isAuthenticatedTx` | boolean | No | Whether to use authenticated relay mode for additional security. Defaults to false | | `derivationPath` | string | No | Optional HD wallet derivation path for transaction signing | | `transactionType` | string | No | Type of relay transaction: `"flash"` (default), `"authenticated"`, `"funding-signed"`, or `"flash-blocks"` (Base/Base Sepolia only) | | `authorizationList` | array | No | Optional list of authorization entries for delegated transactions or batched operations (EIP-7702). Not allowed for flash-blocks transactions | AuthorizationListItem Object [#authorizationlistitem-object] When using `authorizationList`, each item should contain: | Field | Type | Required | Description | | --------- | ------------- | -------- | -------------------------------------------- | | `chainId` | number | Yes | Chain ID for the authorization | | `address` | string | Yes | Ethereum address (must start with "0x") | | `nonce` | number | Yes | Nonce for the authorization | | `r` | string | Yes | Signature r component (must start with "0x") | | `s` | string | Yes | Signature s component (must start with "0x") | | `yParity` | number | Yes | Signature y parity (0 or 1) | | `v` | number/bigint | No | Optional signature v value | Gas Parameter Rules [#gas-parameter-rules] * **Legacy transactions**: Use `gasPrice` only * **EIP-1559 transactions**: Use both `maxFeePerGas` and `maxPriorityFeePerGas` together * You cannot mix `gasPrice` with `maxFeePerGas` or `maxPriorityFeePerGas` Response [#response] Success Response [#success-response] ```json filename="response.json" { "success": true, "data": { "costUSD": 0.0009221670934825817, "minBalanceRequired": "223171904787" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Response Fields [#response-fields] | Field | Type | Description | | -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `costUSD` | number | Estimated transaction cost in USD. This includes gas fees and relay service charges | | `minBalanceRequired` | string | Minimum balance required in the smallest unit to execute the transaction. Unit varies by chain (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, octas for Aptos, MIST for Sui) | Error Response [#error-response] ```json filename="error-response.json" { "success": false, "error": { "code": "INVALID_PARAMETERS", "message": "Missing required transaction parameters for quote", "category": "VALIDATION_ERROR", "details": { "field": "chainId", "message": "chainId is required" }, "traceId": "trace_abc123xyz789" }, "timestamp": "2025-10-24T12:34:56.789Z" } ``` Example Requests [#example-requests] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "label": "My Base Transaction" }' ``` **With Gas Limit:** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "gasLimit": "21000", "label": "My Transaction with Gas Limit" }' ``` **With EIP-1559 Gas Parameters:** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "maxFeePerGas": "2000000000", "maxPriorityFeePerGas": "1000000000", "label": "EIP-1559 Transaction" }' ``` **Aptos** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 88888888, "to": "0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219", "value": "1", "callData": "0x", "gasLimit": "100", "label": "My Aptos Transaction" }' ```
**Note:** Gas limit is required for Aptos transactions.
**Solana** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 10100000, "to": "BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm", "value": "1000000", "callData": "0x", "label": "My Solana Transaction" }' ``` **Sui** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 897796746, "to": "0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0", "value": "100000000", "callData": "0x", "gasLimit": "3000000", "label": "send-native-sui" }' ```
**Note:** Gas limit is required for Sui transactions. Value is denominated in MIST (1 SUI = 10^9 MIST).
**NEAR** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 7777777, "to": "deeprice6887.near", "value": "1000000000000000000000000", "callData": "0x", "label": "My NEAR Transaction" }' ``` **Starknet** ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "to": "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", "callData": "0x", "value": "1", "chainId": 23448594291968334, "label": "send strk", "retries": 0 }' ```
Advanced Examples [#advanced-examples] Quote with Max USD Limit [#quote-with-max-usd-limit] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "maxUSD": 5.0, "label": "Transaction with USD Cap" }' ``` Authenticated Transaction Quote [#authenticated-transaction-quote] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "transactionType": "authenticated", "isAuthenticatedTx": true, "label": "Authenticated Transaction Quote" }' ``` Flash-Blocks Transaction Quote [#flash-blocks-transaction-quote] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "transactionType": "flash-blocks", "label": "Flash-Blocks Quote" }' ```
**Note:** Flash-blocks transaction type is only supported on Base (8453) and Base Sepolia (84532). Authorization lists cannot be used with flash-blocks transactions.
Quote with Authorization List (EIP-7702) [#quote-with-authorization-list-eip-7702] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "authorizationList": [ { "chainId": 8453, "address": "0x1234567890abcdef1234567890abcdef12345678", "nonce": 1, "r": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "s": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "yParity": 1 } ], "label": "Delegated Transaction Quote" }' ``` Quote with Custom Derivation Path [#quote-with-custom-derivation-path] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "1000000000000000", "callData": "0x", "derivationPath": "m/44'\''/60'\''/0'\''/0/1", "label": "Quote from Custom Account" }' ``` Quote with Multicall Batching [#quote-with-multicall-batching] ```bash filename="api-request.sh" curl -X POST "https://tachyon.rath.fi/api/quote" \ -H "Content-Type: application/json" \ -H "api-key: YOUR_API_KEY" \ -d '{ "chainId": 8453, "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "value": "0", "callData": "0xa9059cbb000000000000000000000000...", "shouldBatchInMulticall": true, "label": "Batched Transaction Quote" }' ``` Understanding Units [#understanding-units] The `minBalanceRequired` field uses different units depending on the blockchain: | Network | Unit | Conversion | | ---------- | --------- | ----------------------- | | EVM Chains | Wei | 1 ETH = 10¹⁸ wei | | Solana | Lamports | 1 SOL = 10⁹ lamports | | NEAR | yoctoNEAR | 1 NEAR = 10²⁴ yoctoNEAR | | Aptos | Octas | 1 APT = 10⁸ octas | | Sui | MIST | 1 SUI = 10⁹ MIST | Use Cases [#use-cases] * **Pre-transaction validation**: Check if users have sufficient balance before attempting a transaction * **Cost transparency**: Display estimated costs to users in your application UI * **Budget planning**: Help users understand the financial impact of their transactions with maxUSD limits * **Multi-chain comparison**: Compare costs across different blockchain networks for the same operation * **Gas optimization**: Test different gas parameters to find the optimal transaction cost # EIP-7702 with Account Abstraction (/tachyon/use-cases/eip7702-account-abstraction) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. EIP-7702 with Account Abstraction [#eip-7702-with-account-abstraction] This guide demonstrates how to combine EIP-7702 authorization with ERC-4337 Account Abstraction to execute UserOperations through an EOA delegated to a smart account implementation. Overview [#overview] By leveraging EIP-7702, you can temporarily delegate your EOA to an ERC-4337 compatible smart account, enabling: * **Gas Sponsorship**: Execute transactions without holding native tokens * **Batched Operations**: Multiple contract calls in a single transaction * **Custom Validation**: Advanced signature schemes and access controls * **No Migration Required**: Use smart account features without deploying a new wallet Prerequisites [#prerequisites] * Node.js 18+ * A funded EOA wallet * Tachyon API key * Basic understanding of [EIP-7702](/tachyon/features/eip-7702) and Account Abstraction Step-by-Step Implementation [#step-by-step-implementation] Install Dependencies [#install-dependencies] ```bash npm install viem @rathfi/tachyon ``` Import Required Modules [#import-required-modules] ```typescript filename="imports.ts" import { createWalletClient, createPublicClient, http, encodeFunctionData, encodePacked, concat, pad, numberToHex, } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { base } from "viem/chains"; import { Tachyon } from "@rathfi/tachyon"; import { entryPoint07Abi, entryPoint07Address, getUserOperationHash, } from "viem/account-abstraction"; ``` Configure Entry Point and Clients [#configure-entry-point-and-clients] Set up the ERC-4337 EntryPoint v0.7 configuration and create the necessary clients: ```typescript filename="config.ts" // Entry point configuration (v0.7) const entryPoint = { address: entryPoint07Address as `0x${string}`, version: "0.7" as const, abi: entryPoint07Abi, }; // Public client for reading blockchain state const publicClient = createPublicClient({ transport: http(), chain: base, }); // Wallet client with your EOA const walletClient = createWalletClient({ account: privateKeyToAccount(process.env.PRIVATE_KEY! as `0x${string}`), transport: http(), chain: base, }); // Contract addresses const delegateContractAddress = "0xd6CEDDe84be40893d153Be9d467CD6aD37875a28"; // ERC-4337 Account implementation const beneficiary = "0x4C16955d8A0DcB2e7826d50f4114990c787b21E7"; // Bundler beneficiary const targetContract = "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7"; // Your target contract ``` Create EIP-7702 Authorization (First Transaction Only) [#create-eip-7702-authorization-first-transaction-only] Sign an authorization to delegate your EOA to the smart account implementation: ```typescript filename="authorization.ts" // Track delegation state - set to true after first successful delegation const isAlreadyDelegated = false; async function getAuthorizationList() { if (isAlreadyDelegated) { console.log("Skipping delegation - address already delegated"); return undefined; } // Sign the authorization - viem handles nonce automatically const authorization = await walletClient.signAuthorization({ contractAddress: delegateContractAddress, }); // Format authorization for Tachyon const auth = { chainId: authorization.chainId, address: authorization.address, nonce: Number(authorization.nonce), r: authorization.r, s: authorization.s, v: Number(authorization.v), yParity: Number(authorization.yParity) as 0 | 1, }; console.log("Authorization created for delegation"); return [auth]; } ``` After the first transaction with authorization, your EOA will be delegated to the smart account. Subsequent transactions can skip the authorization step by setting `isAlreadyDelegated` to `true`. Encode the Target Call Data [#encode-the-target-call-data] Prepare the function call you want to execute: ```typescript filename="calldata.ts" // Example: Calling a sayHello function const sayHelloAbi = [ { inputs: [{ internalType: "string", name: "message", type: "string" }], name: "sayHello", outputs: [], stateMutability: "nonpayable", type: "function", }, ] as const; const sayHelloCallData = encodeFunctionData({ abi: sayHelloAbi, functionName: "sayHello", args: ["Hello from Tachyon!"], }); ``` Build the UserOperation Call Data [#build-the-useroperation-call-data] Encode the execution data for the smart account's `execute` function: ```typescript filename="userop-calldata.ts" // Encode execution payload: target address + value + calldata const executionPayload = encodePacked( ["address", "uint256", "bytes"], [ targetContract as `0x${string}`, BigInt(0), // No ETH value sayHelloCallData as `0x${string}`, ] ); // Encode the execute function call for the smart account const executeAbi = [ { inputs: [ { internalType: "ExecMode", name: "execMode", type: "bytes32" }, { internalType: "bytes", name: "executionCalldata", type: "bytes" }, ], name: "execute", outputs: [], stateMutability: "payable", type: "function", }, ] as const; const userOperationCallData = encodeFunctionData({ abi: executeAbi, functionName: "execute", args: [ "0x0000000000000000000000000000000000000000000000000000000000000000", // Default exec mode executionPayload, ], }); ``` Create and Sign the UserOperation [#create-and-sign-the-useroperation] Build the UserOperation structure and sign it: ```typescript filename="userop.ts" // Get nonce from EntryPoint const nonce = await publicClient.readContract({ address: entryPoint.address, abi: entryPoint.abi, functionName: "getNonce", args: [walletClient.account.address, BigInt(0)], blockTag: "pending", }); // Gas limits const callGasLimit = BigInt(500_000); const verificationGasLimit = BigInt(1_200_000); const preVerificationGas = BigInt(100_000); // Create UserOperation const userOperation = { sender: walletClient.account.address, nonce: nonce, initCode: "0x" as `0x${string}`, callData: userOperationCallData, callGasLimit: callGasLimit, verificationGasLimit: verificationGasLimit, preVerificationGas: preVerificationGas, maxFeePerGas: BigInt(0), maxPriorityFeePerGas: BigInt(0), paymasterAndData: "0x" as `0x${string}`, signature: "0x" as `0x${string}`, }; // Get UserOperation hash const userOperationHash = getUserOperationHash({ userOperation, entryPointAddress: entryPoint.address, entryPointVersion: entryPoint.version, chainId: base.id, }); // Sign the UserOperation hash with EOA const signature = await walletClient.signMessage({ message: { raw: userOperationHash }, }); userOperation.signature = signature; console.log("UserOperation Hash:", userOperationHash); console.log("Signature:", signature); ``` Encode the handleOps Call [#encode-the-handleops-call] Prepare the EntryPoint `handleOps` function call: ```typescript filename="handleops.ts" const handleOpsCallData = encodeFunctionData({ abi: entryPoint.abi, functionName: "handleOps", args: [ [ { sender: userOperation.sender, nonce: userOperation.nonce, initCode: userOperation.initCode || "0x", callData: userOperation.callData, accountGasLimits: concat([ pad(numberToHex(userOperation.verificationGasLimit || BigInt(0)), { size: 16, }), pad(numberToHex(userOperation.callGasLimit || BigInt(0)), { size: 16, }), ]), preVerificationGas: userOperation.preVerificationGas, gasFees: concat([ pad(numberToHex(BigInt(0)), { size: 16 }), pad(numberToHex(BigInt(0)), { size: 16 }), ]), paymasterAndData: userOperation.paymasterAndData || "0x", signature: userOperation.signature, }, ], beneficiary as `0x${string}`, ], }); ``` Submit via Tachyon [#submit-via-tachyon] Initialize the Tachyon SDK and submit the transaction: ```typescript filename="submit.ts" // Calculate gas limit with buffer const relayGasLimit = (userOperation.callGasLimit + userOperation.verificationGasLimit + userOperation.preVerificationGas) * BigInt(2); // Initialize Tachyon SDK const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, }); // Get authorization list (only needed for first transaction) const authorizationList = await getAuthorizationList(); // Submit transaction const taskId = await tachyon.relay({ chainId: base.id, to: entryPoint.address, callData: handleOpsCallData, value: "0", gasLimit: relayGasLimit.toString(), ...(authorizationList ? { authorizationList } : { transactionType: "flash-blocks" }), }); console.log("Task ID:", taskId); // Wait for execution const tx = await tachyon.waitForExecutionHash(taskId, 30_000); console.log("Transaction executed:", tx); console.log("Called sayHello via EIP-7702 delegated address through EntryPoint"); ``` Complete Example [#complete-example] Here's the full implementation combining all the steps: ```typescript filename="eip7702-aa-complete.ts" import { createWalletClient, createPublicClient, http, encodeFunctionData, encodePacked, concat, pad, numberToHex, } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { base } from "viem/chains"; import { Tachyon } from "@rathfi/tachyon"; import { entryPoint07Abi, entryPoint07Address, getUserOperationHash, } from "viem/account-abstraction"; // Configuration const entryPoint = { address: entryPoint07Address as `0x${string}`, version: "0.7" as const, abi: entryPoint07Abi, }; const delegateContractAddress = "0xd6CEDDe84be40893d153Be9d467CD6aD37875a28"; const beneficiary = "0x4C16955d8A0DcB2e7826d50f4114990c787b21E7"; const targetContract = "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7"; // Set to true after first successful delegation const isAlreadyDelegated = false; const publicClient = createPublicClient({ transport: http(), chain: base, }); const walletClient = createWalletClient({ account: privateKeyToAccount(process.env.PRIVATE_KEY! as `0x${string}`), transport: http(), chain: base, }); async function executeEIP7702WithAA() { // Step 1: Get authorization (only for first transaction) let authorizationList = undefined; if (!isAlreadyDelegated) { const authorization = await walletClient.signAuthorization({ contractAddress: delegateContractAddress, }); authorizationList = [ { chainId: authorization.chainId, address: authorization.address, nonce: Number(authorization.nonce), r: authorization.r, s: authorization.s, v: Number(authorization.v), yParity: Number(authorization.yParity) as 0 | 1, }, ]; console.log("Authorization created"); } // Step 2: Encode target call const sayHelloCallData = encodeFunctionData({ abi: [ { inputs: [{ internalType: "string", name: "message", type: "string" }], name: "sayHello", outputs: [], stateMutability: "nonpayable", type: "function", }, ], functionName: "sayHello", args: ["Hello from Tachyon!"], }); // Step 3: Build execution payload const executionPayload = encodePacked( ["address", "uint256", "bytes"], [targetContract as `0x${string}`, BigInt(0), sayHelloCallData as `0x${string}`] ); const userOperationCallData = encodeFunctionData({ abi: [ { inputs: [ { internalType: "ExecMode", name: "execMode", type: "bytes32" }, { internalType: "bytes", name: "executionCalldata", type: "bytes" }, ], name: "execute", outputs: [], stateMutability: "payable", type: "function", }, ], functionName: "execute", args: [ "0x0000000000000000000000000000000000000000000000000000000000000000", executionPayload, ], }); // Step 4: Get nonce and create UserOperation const nonce = await publicClient.readContract({ address: entryPoint.address, abi: entryPoint.abi, functionName: "getNonce", args: [walletClient.account.address, BigInt(0)], blockTag: "pending", }); const userOperation = { sender: walletClient.account.address, nonce: nonce, initCode: "0x" as `0x${string}`, callData: userOperationCallData, callGasLimit: BigInt(500_000), verificationGasLimit: BigInt(1_200_000), preVerificationGas: BigInt(100_000), maxFeePerGas: BigInt(0), maxPriorityFeePerGas: BigInt(0), paymasterAndData: "0x" as `0x${string}`, signature: "0x" as `0x${string}`, }; // Step 5: Sign UserOperation const userOperationHash = getUserOperationHash({ userOperation, entryPointAddress: entryPoint.address, entryPointVersion: entryPoint.version, chainId: base.id, }); userOperation.signature = await walletClient.signMessage({ message: { raw: userOperationHash }, }); // Step 6: Encode handleOps const handleOpsCallData = encodeFunctionData({ abi: entryPoint.abi, functionName: "handleOps", args: [ [ { sender: userOperation.sender, nonce: userOperation.nonce, initCode: "0x", callData: userOperation.callData, accountGasLimits: concat([ pad(numberToHex(userOperation.verificationGasLimit), { size: 16 }), pad(numberToHex(userOperation.callGasLimit), { size: 16 }), ]), preVerificationGas: userOperation.preVerificationGas, gasFees: concat([ pad(numberToHex(BigInt(0)), { size: 16 }), pad(numberToHex(BigInt(0)), { size: 16 }), ]), paymasterAndData: "0x", signature: userOperation.signature, }, ], beneficiary as `0x${string}`, ], }); // Step 7: Submit via Tachyon const relayGasLimit = (userOperation.callGasLimit + userOperation.verificationGasLimit + userOperation.preVerificationGas) * BigInt(2); const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, }); const taskId = await tachyon.relay({ chainId: base.id, to: entryPoint.address, callData: handleOpsCallData, value: "0", gasLimit: relayGasLimit.toString(), ...(authorizationList ? { authorizationList } : { transactionType: "flash-blocks" }), }); console.log("Task ID:", taskId); const tx = await tachyon.waitForExecutionHash(taskId, 30_000); console.log("Transaction executed:", tx); return tx; } executeEIP7702WithAA(); ``` Key Considerations [#key-considerations] **Security**: Never expose your private key in client-side code. Use secure key management solutions in production. * **Delegation Persistence**: After the first transaction with `authorizationList`, your EOA remains delegated until you explicitly revoke it * **Gas Estimation**: The example uses fixed gas limits. In production, consider using gas estimation APIs for optimal values * **Nonce Management**: The EntryPoint manages its own nonce system, separate from the EOA's transaction nonce * **Chain Support**: EIP-7702 is supported on specific chains. Check [supported networks](/tachyon/supported-networks) for availability Related Resources [#related-resources] * [EIP-7702 Authorization](/tachyon/features/eip-7702) - Learn more about EIP-7702 delegation * [Relay Transactions](/tachyon/how-to-guides/relay-tx) - Basic transaction relay guide * [Tachyon SDK Reference](/tachyon/tachyon-sdk) - Complete SDK documentation # Token Swap with Permit API (/tachyon/use-cases/swap-using-custodial) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Token Swap with Permit API Reference [#token-swap-with-permit-api-reference] This guide demonstrates how to perform token swaps using custodial wallets by leveraging **EIP-712 signatures** and **ERC-20 permit functionality** through the Tachyon relay API. *** Endpoint [#endpoint] ``` POST https://tachyon.rath.fi/api/submit-tx ``` *** Authentication [#authentication] Include your API key in the request headers: ``` api-key: YOUR_API_KEY ``` *** Overview by Chain [#overview-by-chain] **EVM Chains (Ethereum, Base, Polygon, etc.)** Understanding EIP-712 Signatures [#understanding-eip-712-signatures] EIP-712 is a standard for typed structured data hashing and signing. It provides a more secure and user-friendly way to sign data compared to traditional message signing methods. Key benefits include: * **Human-readable signatures**: Users can see exactly what they're signing in their wallet interface * **Domain separation**: Prevents signature replay attacks across different applications and chains * **Type safety**: Ensures the data structure matches expected formats EIP-712 signatures are particularly useful for meta-transactions and gasless interactions, as they allow users to authorize actions without directly submitting transactions to the blockchain. Reference: [EIP-712 Specification](https://eips.ethereum.org/EIPS/eip-712) ERC-20 Permit Functionality [#erc-20-permit-functionality] The ERC-20 Permit extension (EIP-2612) enables token approvals via signatures instead of on-chain transactions. Traditional token approvals require two transactions: 1. `approve()` - Authorize a spender to use your tokens 2. `transferFrom()` - The spender moves the tokens With permit functionality: * Users sign an off-chain message (EIP-712) authorizing token spending * The signature can be submitted by anyone (including relayers) * Approval and transfer happen in a single transaction * No gas costs for the token owner This is ideal for custodial wallets and gasless experiences, as users can authorize token movements without holding native tokens for gas fees. Reference: [EIP-20 Permit Guide](https://docs.openzeppelin.com/contracts-cairo/2.x/guides/erc20-permit) *** Permit and Swap Contract [#permit-and-swap-contract] ```solidity filename="contract.sol" // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract PermitSwap { address public swapper; constructor(address _swapper) { swapper = _swapper; } function permitAndSwap( address owner, address tokenIn, uint256 amountIn, bytes memory data, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external { IERC20Permit(tokenIn).permit(owner, address(this), amountIn, deadline, v, r, s); IERC20(tokenIn).transferFrom(owner, address(this), amountIn); IERC20(tokenIn).approve(swapper, amountIn); (bool ok,) = swapper.call(data); require(ok, "swap failed"); } } ``` *** Implementation Example [#implementation-example] **Reference:** * [Full Code (using ethers)](https://github.com/RathFinance/tachyon-examples/blob/main/ts-example/src/scripts/swap_using_permit.ts) * [Full Code (using viem)](https://github.com/RathFinance/tachyon-examples/blob/main/ts-example/src/scripts/swap_using_permit_viem.ts) ```typescript filename="import-sdk.ts" import { ethers } from "ethers"; import { ChainId, Tachyon } from "@rathfi/tachyon"; import * as dotenv from "dotenv"; dotenv.config({ path: "ts-example/.env" }); // === CONFIG === const PERMIT_SWAP_ADDRESS = process.env.PERMIT_SWAP_CONTRACT!; const TOKEN_IN_ADDRESS = process.env.TOKEN_ADDRESS!; const SWAPPER_ADDRESS = "0x6352a56caadC4F1E25CD6c75970Fa768A3304e64"; // on base // Example encoded swap payload — replace this with your actual swap call data const SWAP_DATA = "0x"; // === ABI === const permitSwapAbi = [ "function permitAndSwap(address owner, address tokenIn, uint256 amountIn, bytes data, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external", ]; async function main() { // Step 1. Setup provider and signer for signing the permit const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); console.log("Using RPC URL:", process.env.RPC_URL); const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); const owner = await signer.getAddress(); const token = new ethers.Contract( TOKEN_IN_ADDRESS, [ "function name() view returns (string)", "function nonces(address) view returns (uint256)", ], provider ); const name = await token.name(); const nonce = await token.nonces(owner); const chain = await provider.getNetwork(); const amountIn = 10; // usdc const deadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour from now // Step 2. Create EIP-712 domain and message const domain = { name, version: "2", // hardcoded for USDC on base chainId: chain.chainId, verifyingContract: TOKEN_IN_ADDRESS, }; const types = { Permit: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, { name: "value", type: "uint256" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" }, ], }; const message = { owner, spender: PERMIT_SWAP_ADDRESS, value: amountIn, nonce, deadline, }; const signature = await signer.signTypedData(domain, types, message); const sig = ethers.Signature.from(signature); const { v, r, s } = sig; // Step 3. Encode function call data for permitAndSwap() const iface = new ethers.Interface(permitSwapAbi); const callData = iface.encodeFunctionData("permitAndSwap", [ owner, TOKEN_IN_ADDRESS, amountIn, SWAP_DATA, deadline, v, r, s, ]); // Step 4. Initialize Tachyon const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY || "", }); // Step 5. Relay the transaction via Tachyon console.log("Relaying transaction via Tachyon..."); const txId = await tachyon.relay({ chainId: ChainId.BASE, // Adjust chain if not Base to: PERMIT_SWAP_ADDRESS, value: "0", // No native value needed gasLimit: "1000000", callData, }); console.log("Relay Tx ID:", txId); // Step 6. Wait for the transaction to execute const relayStatus = await tachyon.waitForPendingExecutionHash(txId); console.log("Transaction Status:", relayStatus); } main().catch((error) => { console.error(error); process.exitCode = 1; }); ``` *** API Request Example [#api-request-example] Once you have the encoded `callData` from the permit signature, submit it via the relay API: ```bash filename="submit-transaction.sh" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainId": 8453, "to": "0xPermitSwapContractAddress", "value": "0", "gasLimit": "1000000", "callData": "0x...", "label": "Permit and Swap" }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` *** Environment Variables [#environment-variables] The following environment variables are used in the example: | Variable | Description | | ---------------------- | ---------------------------------------------------------------------------------------------------------- | | `RPC_URL` | JSON-RPC endpoint for the target chain | | `PRIVATE_KEY` | Private key used to create the EIP-712 signature (in custodial setups this may be held in a secure signer) | | `PERMIT_SWAP_CONTRACT` | Address of the contract exposing `permitAndSwap` | | `TOKEN_ADDRESS` | Token to be permitted and swapped | | `TACHYON_API_KEY` | Tachyon relay API key | *** Workflow Summary [#workflow-summary] 1. **Create EIP-712 Signature**: User signs a permit message off-chain 2. **Encode Function Call**: Combine the signature with swap parameters 3. **Submit to Relay**: POST the encoded transaction to `/api/submit-tx` 4. **Track Execution**: Monitor the transaction using the returned `txId` **Aptos** Token swap with permit functionality for Aptos will be added soon. **Solana** Token swap with permit functionality for Solana will be added soon. **Sui** Token swap with permit functionality for Sui will be added soon. **NEAR** Token swap with permit functionality for NEAR will be added soon. *** Benefits of Permit-Based Swaps [#benefits-of-permit-based-swaps] 1. **Gasless for Users**: Users don't need native tokens to approve token spending 2. **Single Transaction**: Approval and swap happen atomically 3. **Better UX**: No need for separate approval transactions 4. **Custodial Friendly**: Works seamlessly with custodial wallet architectures 5. **Security**: EIP-712 provides clear, human-readable signing context *** Best Practices [#best-practices] 1. **Set Reasonable Deadlines**: Use appropriate expiration times for permit signatures (e.g., 1 hour) 2. **Validate Token Support**: Ensure tokens implement the ERC-2612 permit extension 3. **Handle Nonces Correctly**: Always fetch the current nonce before creating signatures 4. **Secure Private Keys**: In production, use secure key management solutions 5. **Test Thoroughly**: Test with small amounts on testnets before mainnet deployment *** Rate Limits [#rate-limits] API requests are subject to rate limits based on your subscription tier. Contact support for information about your specific limits. *** Support [#support] For questions or issues with the API, please contact: * Documentation: [https://docs.tachyon.rath.fi](https://docs.tachyon.rath.fi) * Support: [support@rath.fi](mailto:support@rath.fi) * GitHub Examples: [https://github.com/RathFinance/tachyon-examples](https://github.com/RathFinance/tachyon-examples) # Smart Contract Call (/tachyon/how-to-guides/contract-call) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Smart Contract Call [#smart-contract-call] Use the **Tachyon Relay API** to interact with smart contracts across multiple blockchains. The `/api/submit-tx` endpoint supports **EVM**, **Solana**, **Aptos**, **Sui**, and **NEAR**, enabling a unified interface for submitting encoded contract calls through the Tachyon network. Chain Examples [#chain-examples] EVM Chains (Ethereum, Base, Polygon, etc.) [#evm-chains-ethereum-base-polygon-etc] Using Tachyon SDK (TypeScript) [#using-tachyon-sdk-typescript] Code Example [#code-example] ```typescript filename="smart-contract-call.ts" import { Tachyon, ChainId } from '@rathfi/tachyon'; import { ethers } from 'ethers'; // Initialize SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); // Create and encode the function call const abi = ["function sayHello(string message)"]; const iface = new ethers.Interface(abi); const callData = iface.encodeFunctionData("sayHello", ["Hello from Tachyon!"]); // Relay transaction const txId = await tachyon.relay({ chainId: ChainId.BASE, to: "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7", value: "0", callData, label: "Say Hello Example" }); console.log("Transaction ID:", txId); ``` Step-by-Step Instructions [#step-by-step-instructions] 1. **Install the required dependencies:** ```bash filename="terminal" npm install @rathfi/tachyon ethers ``` 2. **Import the necessary modules:** * Import `Tachyon` and `ChainId` from `@rathfi/tachyon` * Import `ethers` for encoding contract call data 3. **Initialize the Tachyon SDK:** * Create a new `Tachyon` instance * Pass your API key in the configuration object: `{ apiKey: 'YOUR_API_KEY' }` 4. **Define your contract ABI:** * Create an array with the function signature(s) you want to call * Example: `["function sayHello(string message)"]` 5. **Encode the function call:** * Create an ethers `Interface` instance with your ABI * Use `encodeFunctionData()` to encode the function name and parameters * Store the result in `callData` 6. **Submit the relay transaction:** * Call `tachyon.relay()` with the transaction parameters * Use `await` since this is an asynchronous operation 7. **Handle the transaction ID:** * The method returns a `txId` string * Use this ID to track the transaction status through the Tachyon API SDK Function Parameters [#sdk-function-parameters] **`tachyon.relay(options)`** | Parameter | Type | Required | Description | Example | | ------------------- | --------------------- | -------- | --------------------------------------------- | ---------------------------------------------- | | `chainId` | `ChainId` or `number` | Yes | Chain identifier (use ChainId enum or number) | `ChainId.BASE` or `8453` | | `to` | `string` | Yes | Target contract address | `"0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7"` | | `value` | `string` | Yes | Amount in wei | `"0"` | | `callData` | `string` | Yes | Encoded function call data | Result from `iface.encodeFunctionData()` | | `label` | `string` | Optional | Custom transaction label | `"Say Hello Example"` | | `gasLimit` | `string` | Optional | Gas limit override | `"100000"` | | `isAuthenticatedTx` | `boolean` | Optional | Authenticated relay mode | `true` or `false` | | `transactionType` | `string` | Optional | Processing type | `"flash"` or `"flash-blocks"` | **Returns:** `Promise` - The transaction ID (`txId`) Using REST API [#using-rest-api] Code Example [#code-example-1] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainId": 8453, "to": "0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7", "value": "0", "callData": "0xc3a9b1c50000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001348656c6c6f2066726f6d2054616368796f6e2100000000000000000000000000", "label": "Hello From Tachyon Call" }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` Step-by-Step Instructions [#step-by-step-instructions-1] 1. **Obtain your API key** from the Tachyon dashboard at [https://accounts.rath.fi](https://accounts.rath.fi) 2. **Prepare your contract call data:** * Identify the target contract address (`to`) * Encode your function call into `callData` (see SDK example for encoding details) * Determine the `chainId` for your target network (e.g., 8453 for Base, 1 for Ethereum) 3. **Set the transaction value:** * Use `"0"` for non-payable functions * Specify the amount in wei as a string for payable functions 4. **Make the API request:** * Send a POST request to `https://tachyon.rath.fi/api/submit-tx` * Include your API key in the api-key header as `YOUR_API_KEY` * Set Content-Type header to `application/json` 5. **Handle the response:** * Extract the `txId` from the response * Use this `txId` to track your transaction status API Parameters [#api-parameters] The `RelayParams` object defines the parameters required when calling the `relay()` method. | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR). Defaults to '0' if not specified. | | `label` | `string` | No | Optional human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Optional gas limit for the transaction. If not specified, it will be estimated automatically. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum cost in USD that you're willing to pay for this transaction. | | `retries` | `number` | No | Number of retry attempts for the transaction. Defaults to 0. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall operation. | | `isAuthenticatedTx` | `boolean` | No | Enable authenticated relay mode for additional security and verification. Defaults to false. | | `derivationPath` | `string` | No | Optional HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash" \| "authenticated" \| "funding-signed" \| "flash-blocks"` | No | Type of relay transaction. Defaults to `"flash"`. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | Optional list of authorization entries for delegated transactions or batched operations. Cannot be used with `"flash-blocks"` transaction type. | Aptos [#aptos] Using Tachyon SDK [#using-tachyon-sdk] Code Example [#code-example-2] ```typescript filename="aptos-contract-call.ts" import { Tachyon } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); const functionPayload = { function: "0x3690a8173c5f738234d3772621db2923cf283029d0b9a7795038fde6f3fcdabd::hello_tachyon_v2::preview_message", typeArguments: [], functionArguments: ["GM Tachyon!"] }; const callData = Buffer.from(JSON.stringify(functionPayload)).toString('base64'); const txId = await tachyon.relay({ chainId: 88888888, to: "0x3690a8173c5f738234d3772621db2923cf283029d0b9a7795038fde6f3fcdabd", value: "0", callData, label: "send-to-aptos", gasLimit: "5000" }); ``` Using REST API [#using-rest-api-1] Code Example [#code-example-3] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainId": 88888888, "to": "0x3690a8173c5f738234d3772621db2923cf283029d0b9a7795038fde6f3fcdabd", "value": "0", "callData": "eyJmdW5jdGlvbiI6IjB4MzY5MGE4MTczYzVmNzM4MjM0ZDM3NzI2MjFkYjI5MjNjZjI4MzAyOWQwYjlhNzc5NTAzOGZkZTZmM2ZjZGFiZDo6aGVsbG9fdGFjaHlvbl92Mjo6cHJldmlld19tZXNzYWdlIiwidHlwZUFyZ3VtZW50cyI6W10sImZ1bmN0aW9uQXJndW1lbnRzIjpbIkdNIFRhY2h5b24hIl19", "label": "send-to-aptos", "gasLimit": "5000" }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` callData Structure (before Base64 encoding) [#calldata-structure-before-base64-encoding] ```json filename="aptos-payload.json" { "function": "0x3690a8173c5f738234d3772621db2923cf283029d0b9a7795038fde6f3fcdabd::hello_tachyon_v2::preview_message", "typeArguments": [], "functionArguments": ["GM Tachyon!"] } ``` Solana [#solana] Using Tachyon SDK [#using-tachyon-sdk-1] Code Example [#code-example-4] ```typescript filename="solana-contract-call.ts" import { Tachyon, ChainId } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); // 1. Create callData const programId = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"; const payer = "3dQFssz4XLF9LKTTGrqCy4PwDSFiw6QrPwHW5QkvLmw3"; // your wallet pubkey const memoMessage = "Hello from rath"; // Encode the message as bytes const instructionData = Buffer.from(memoMessage, "utf8"); // Build the instruction JSON const message = { programId, keys: [], data: instructionData.toString("base64"), }; // Encode the JSON to Base64 const callData = Buffer.from(JSON.stringify(message), "utf8").toString("base64"); // 2. relay contract call const txId = await tachyon.relay({ chainId: 10100000, to: "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", value: "0", callData, label: "contract-call-solana" }); ``` Step-by-Step Instructions [#step-by-step-instructions-2] Solana SDK integration documentation will be added soon. SDK Function Parameters [#sdk-function-parameters-1] Parameters specific to Solana program calls will be documented upon release. Using REST API [#using-rest-api-2] Code Example [#code-example-5] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", "callData": "eyJwcm9ncmFtSWQiOiJNZW1vU3E0Z3FBQkFYS2I5NnFuSDhUeXNOY1d4TXlXQ3FYZ0RMR21mY0hyIiwia2V5cyI6W10sImRhdGEiOiJTR1ZzYkc4Z1puSnZiU0J5WVhSbyJ9", "value": "0", "chainId": 10100000, "label": "call-contract-solana" }' ``` Step-by-Step Instructions [#step-by-step-instructions-3] Example integration for Solana will be added soon.\ Developers will be able to relay compiled BPF contract calls using the same `/api/submit-tx` endpoint. API Parameters [#api-parameters-1] Documentation will be available soon with Solana-specific parameter details. Sui [#sui] Using Tachyon SDK [#using-tachyon-sdk-2] Code Example [#code-example-6] ```typescript filename="sui-contract-call.ts" import { Tachyon } from '@rathfi/tachyon'; import { Transaction as SuiTransaction } from '@mysten/sui/transactions'; const PACKAGE_ID = '0xb4ce9c7b45e665ec8a310b7f5507123fa3de79f53917f20b9408cdcb159dcc70'; const tx = new SuiTransaction(); tx.moveCall({ target: `${PACKAGE_ID}::greeting::new`, arguments: [], }); const txBytes = tx.serialize(); const createGreetingCallData = Buffer.from(txBytes).toString('base64'); const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); const txId = await tachyon.relay({ chainId: 897796746, to: "0xb4ce9c7b45e665ec8a310b7f5507123fa3de79f53917f20b9408cdcb159dcc70", value: "0", callData: createGreetingCallData, label: "call-contract-sui", gasLimit: "1000000" }); ``` Using REST API [#using-rest-api-3] Code Example [#code-example-7] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainId": 897796746, "to": "0xb4ce9c7b45e665ec8a310b7f5507123fa3de79f53917f20b9408cdcb159dcc70", "value": "0", "callData": "eyJ2ZXJzaW9uIjoxLCJleHBpcmF0aW9uIjpudWxsLCJnYXNDb25maWciOnt9LCJpbnB1dHMiOlt7ImtpbmQiOiJJbnB1dCIsInR5cGUiOiJvYmplY3QiLCJpbmRleCI6MCwidmFsdWUiOiIweDk3ZTAxODMyY2M4MGI4NTBhMTU5YmUwZmNjNjgwY2Q4ZmE2ZmVkYjIzMmI0YmViNmYxOGMyOGI4YTk2YzE3OWMifSx7ImtpbmQiOiJJbnB1dCIsImluZGV4IjoxLCJ2YWx1ZSI6eyJQdXJlIjpbMTksNzIsMTAxLDEwOCwxMDgsMTExLDMyLDEwMiwxMTQsMTExLDEwOSwzMiw4NCw5Nyw5OSwxMDQsMTIxLDExMSwxMTAsMzNdfSwidHlwZSI6InB1cmUifV0sInRyYW5zYWN0aW9ucyI6W3sia2luZCI6Ik1vdmVDYWxsIiwidGFyZ2V0IjoiMHhiNGNlOWM3YjQ1ZTY2NWVjOGEzMTBiN2Y1NTA3MTIzZmEzZGU3OWY1MzkxN2YyMGI5NDA4Y2RjYjE1OWRjYzcwOjpncmVldGluZzo6dXBkYXRlX3RleHQiLCJ0eXBlQXJndW1lbnRzIjpbXSwiYXJndW1lbnRzIjpbeyJraW5kIjoiSW5wdXQiLCJ0eXBlIjoib2JqZWN0IiwiaW5kZXgiOjAsInZhbHVlIjoiMHg5N2UwMTgzMmNjODBiODUwYTE1OWJlMGZjYzY4MGNkOGZhNmZlZGIyMzJiNGJlYjZmMThjMjhiOGE5NmMxNzljIn0seyJraW5kIjoiSW5wdXQiLCJpbmRleCI6MSwidmFsdWUiOnsiUHVyZSI6WzE5LDcyLDEwMSwxMDgsMTA4LDExMSwzMiwxMDIsMTE0LDExMSwxMDksMzIsODQsOTcsOTksMTA0LDEyMSwxMTEsMTEwLDMzXX0sInR5cGUiOiJwdXJlIn1dfV19", "label": "call-contract-sui", "gasLimit": "1000000" }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` callData Structure (before Base64 encoding) [#calldata-structure-before-base64-encoding-1] ```json filename="sui-transaction.json" { "version": 1, "expiration": null, "gasConfig": {}, "inputs": [ { "kind": "Input", "type": "object", "index": 0, "value": "0x97e01832cc80b850a159be0fcc680cd8fa6fedb232b4beb6f18c28b8a96c179c" }, { "kind": "Input", "index": 1, "value": {"Pure": [19, 72, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 84, 97, 99, 104, 121, 111, 110, 33]}, "type": "pure" } ], "transactions": [ { "kind": "MoveCall", "target": "0xb4ce9c7b45e665ec8a310b7f5507123fa3de79f53917f20b9408cdcb159dcc70::greeting::update_text", "typeArguments": [], "arguments": [ {"kind": "Input", "type": "object", "index": 0, "value": "0x97e01832cc80b850a159be0fcc680cd8fa6fedb232b4beb6f18c28b8a96c179c"}, {"kind": "Input", "index": 1, "value": {"Pure": [19, 72, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 84, 97, 99, 104, 121, 111, 110, 33]}, "type": "pure"} ] } ] } ``` NEAR [#near] Using Tachyon SDK [#using-tachyon-sdk-3] Code Example [#code-example-8] ```typescript filename="near-contract-call.ts" import { Tachyon } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); const methodCall = { methodName: "set_greeting", args: { greeting: "Hello from tachyon!" } }; const callData = Buffer.from(JSON.stringify(methodCall)).toString('base64'); const txId = await tachyon.relay({ chainId: 7777777, to: "rathgreeting.near", value: "0", callData, label: "contract-call-near" }); ``` Using REST API [#using-rest-api-4] Code Example [#code-example-9] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chainId": 7777777, "to": "rathgreeting.near", "value": "0", "callData": "eyJtZXRob2ROYW1lIjoic2V0X2dyZWV0aW5nIiwiYXJncyI6eyJncmVldGluZyI6IkhlbGxvIGZyb20gdGFjaHlvbiEifX0=", "label": "contract-call-near" }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` callData Structure (before Base64 encoding) [#calldata-structure-before-base64-encoding-2] ```json filename="near-method-call.json" { "methodName": "set_greeting", "args": { "greeting": "Hello from tachyon!" } } ``` Starknet [#starknet] Using Tachyon SDK (TypeScript) [#using-tachyon-sdk-typescript-1] Code Example [#code-example-10] ```typescript filename="smart-contract-call.ts" import { CallData, CairoByteArray } from "starknet"; /** * Script to create calldata for say_hello function in Starknet contract * Contract: 0x038f1247ea37e673b432794cfa8ebf4561abd0acb98ba4d726e2d15998a9013e * Function: say_hello(name: ByteArray) -> ByteArray */ // Create call object for say_hello function function createCallObject(contractAddress, name) { const nameEncoded = new CairoByteArray(name); const calldata = CallData.compile([ ...nameEncoded.toApiRequest(), ]); return [ { contractAddress: contractAddress, entrypoint: 'say_hello', calldata, }, ]; } // Encode to base64 for API function encodeCallDataToBase64(contractAddress, name) { const callObject = createCallObject(contractAddress, name); const jsonString = JSON.stringify(callObject); return Buffer.from(jsonString, 'utf8').toString('base64'); } // ========== EXAMPLE USAGE ========== const CONTRACT_ADDRESS = '0x02D1B27260A8CE330aA2FDCCE3E8B7F7711A02A2C0776511fb5f42390f4216B6'; // Example name to pass to say_hello function const name = 'Hello World'; // Encode const base64CallData = encodeCallDataToBase64(CONTRACT_ADDRESS, name); // Initialize SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY' }); // Relay transaction const txId = await tachyon.relay({ to: "0x02d1b27260a8ce330aa2fdcce3e8b7f7711a02a2c0776511fb5f42390f4216b6", callData: base64CallData, value: "0", chainId: 23448594291968334 }); console.log("Transaction ID:", txId); ``` Step-by-Step Instructions [#step-by-step-instructions-4] 1. **Install the required dependencies:** ```bash filename="terminal" npm install @rathfi/tachyon ethers ``` 2. **Import the necessary modules:** * Import `Tachyon` and `ChainId` from `@rathfi/tachyon` * Import `ethers` for encoding contract call data 3. **Initialize the Tachyon SDK:** * Create a new `Tachyon` instance * Pass your API key in the configuration object: `{ apiKey: 'YOUR_API_KEY' }` 4. **Define your contract ABI:** * Create an array with the function signature(s) you want to call * Example: `["function sayHello(string message)"]` 5. **Encode the function call:** * Create an ethers `Interface` instance with your ABI * Use `encodeFunctionData()` to encode the function name and parameters * Store the result in `callData` 6. **Submit the relay transaction:** * Call `tachyon.relay()` with the transaction parameters * Use `await` since this is an asynchronous operation 7. **Handle the transaction ID:** * The method returns a `txId` string * Use this ID to track the transaction status through the Tachyon API SDK Function Parameters [#sdk-function-parameters-2] **`tachyon.relay(options)`** | Parameter | Type | Required | Description | Example | | ------------------- | --------------------- | -------- | --------------------------------------------- | ---------------------------------------------- | | `chainId` | `ChainId` or `number` | Yes | Chain identifier (use ChainId enum or number) | `ChainId.BASE` or `8453` | | `to` | `string` | Yes | Target contract address | `"0xA7A833e6641D7901F30EaD6f27d4Ee2C9bb670a7"` | | `value` | `string` | Yes | Amount in wei | `"0"` | | `callData` | `string` | Yes | Encoded function call data | Result from `iface.encodeFunctionData()` | | `label` | `string` | Optional | Custom transaction label | `"Say Hello Example"` | | `gasLimit` | `string` | Optional | Gas limit override | `"100000"` | | `isAuthenticatedTx` | `boolean` | Optional | Authenticated relay mode | `true` or `false` | | `transactionType` | `string` | Optional | Processing type | `"flash"` or `"flash-blocks"` | **Returns:** `Promise` - The transaction ID (`txId`) Using REST API [#using-rest-api-5] Code Example [#code-example-11] ```bash filename="terminal" curl -X POST https://tachyon.rath.fi/api/submit-tx \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "0x02d1b27260a8ce330aa2fdcce3e8b7f7711a02a2c0776511fb5f42390f4216b6", "callData": "W3siY29udHJhY3RBZGRyZXNzIjoiMHgwMmQxYjI3MjYwYThjZTMzMGFhMmZkY2NlM2U4YjdmNzcxMWEwMmEyYzA3NzY1MTFmYjVmNDIzOTBmNDIxNmI2IiwiZW50cnlwb2ludCI6InNheV9oZWxsbyIsImNhbGxkYXRhIjpbIjAiLCIweDQxNmM2OTYzNjUiLCI1Il19XQ==", "value": "0", "chainId": 23448594291968334 }' ``` **Response:** ```json filename="response.json" { "txId": "68fa3450539a3c9d28bbca33" } ``` Step-by-Step Instructions [#step-by-step-instructions-5] 1. **Obtain your API key** from the Tachyon dashboard at [https://accounts.rath.fi](https://accounts.rath.fi) 2. **Prepare your contract call data:** * Identify the target contract address (`to`) * Encode your function call into `callData` (see SDK example for encoding details) * Determine the `chainId` for your target network (e.g., 8453 for Base, 1 for Ethereum) 3. **Set the transaction value:** * Use `"0"` for non-payable functions * Specify the amount in wei as a string for payable functions 4. **Make the API request:** * Send a POST request to `https://tachyon.rath.fi/api/submit-tx` * Include your API key in the api-key header as `YOUR_API_KEY` * Set Content-Type header to `application/json` 5. **Handle the response:** * Extract the `txId` from the response * Use this `txId` to track your transaction status API Parameters [#api-parameters-2] The `RelayParams` object defines the parameters required when calling the `relay()` method. | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR). Defaults to '0' if not specified. | | `label` | `string` | No | Optional human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Optional gas limit for the transaction. If not specified, it will be estimated automatically. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum cost in USD that you're willing to pay for this transaction. | | `retries` | `number` | No | Number of retry attempts for the transaction. Defaults to 0. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall operation. | | `isAuthenticatedTx` | `boolean` | No | Enable authenticated relay mode for additional security and verification. Defaults to false. | | `derivationPath` | `string` | No | Optional HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash" \| "authenticated" \| "funding-signed" \| "flash-blocks"` | No | Type of relay transaction. Defaults to `"flash"`. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | Optional list of authorization entries for delegated transactions or batched operations. Cannot be used with `"flash-blocks"` transaction type. | *** Transaction Lifecycle [#transaction-lifecycle] After submitting your transaction through either the REST API or SDK: 1. **Submission:** The `/api/submit-tx` endpoint returns a unique `txId` 2. **Queued:** Transaction enters the relay queue with `NOT_PICKED_UP` status 3. **Processing:** A relay node picks up and broadcasts the transaction to the blockchain 4. **Executed:** Transaction gets confirmed on-chain; execution hash becomes available You can use the `txId` to query the transaction status and retrieve the execution hash once confirmed. *** Summary [#summary] The Tachyon Relay API provides a simple, unified interface for interacting with smart contracts across multiple blockchain networks. Whether you're using the REST API for direct HTTP calls or the TypeScript SDK for type-safe integration, the process remains straightforward: encode your contract call, submit it to the relay, and track it using the returned transaction ID. # Register Notifier (/tachyon/how-to-guides/register-notifier) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Register Notifier [#register-notifier] Once the Tachyon account is set up, follow these steps to register a notifier to get transaction updates. Open Dashboard [#open-dashboard] Go to your Tachyon dashboard and navigate to the "Configure Webhooks" section. Open dashboard webhook settings Select notifier and provide details [#select-notifier-and-provide-details] You can configure these notifiers: * For Discord provide the Discord channel webhook url. * For Slack provide the Slack webhook url. * For PagerDuty provide the integration key. Add webhook URL Select Add Integration in the Notifier [#select-add-integration-in-the-notifier] Add webhook URL Notifier Registered Successfully [#notifier-registered-successfully] Now you will start receiving transaction notification on the notifier platform. Add webhook URL # Register Webhook (/tachyon/how-to-guides/register-webhook) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Register Webhook [#register-webhook] Once the Tachyon account is set up, follow these steps to register a webhook to get transaction updates, balance alerts, and circuit breaker events. Open Dashboard [#open-dashboard] Go to your Tachyon dashboard and navigate to the "Configure Webhooks" section. Open dashboard webhook settings Create New Webhook [#create-new-webhook] Select "Create New Webhook". Add webhook URL Add Webhook URL [#add-webhook-url] Add webhook URL Webhook registered [#webhook-registered] Add webhook URL # Register WebSocket (/tachyon/how-to-guides/register-websocket) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Register Websocket [#register-websocket] Once the Tachyon account is set up, follow these steps to register a webhook to get transaction updates, balance alerts, and circuit breaker events. Open Dashboard [#open-dashboard] Go to your Tachyon dashboard and navigate to the "Configure Webhooks" section. Open dashboard webhook settings Toggle Websocket [#toggle-websocket] Select toggle on the "Websocket" section. Add webhook URL Websocket registered [#websocket-registered] You may access the api key or copy it and store it safely. Add webhook URL Go to [Websocket usage examples](/tachyon/tachyon-sdk/reg-websocket#usage-examples) to see examples of websocket connection and usage using the Tachyon SDK. # Relay Transactions (/tachyon/how-to-guides/relay-tx) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Relay Transactions [#relay-transactions] The Tachyon SDK provides a complete workflow for submitting transactions to the relay network, monitoring their status, and waiting for on-chain execution. This guide covers the three main methods you'll use: submitting transactions, checking their status, and waiting for confirmation. *** Quick Start [#quick-start] **EVM Chains (Ethereum, Base, Polygon, etc.)** Follow these steps to submit and track a transaction on EVM-compatible chains: Import the SDK [#import-the-sdk] ```javascript filename="import.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client] ```javascript filename="initialize.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction] ```javascript filename="submit-tx.js" const txId = await tachyon.relay({ chainId: ChainId.BASE, // 8453 to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', // 1 wei callData: '0x', label: 'My Base Transaction', }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status] ```javascript filename="check-status-evm.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution] ```javascript filename="wait-execution-evm.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Aptos** Follow these steps to submit and track a transaction on Aptos: Import the SDK [#import-the-sdk-1] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client-1] ```javascript filename="initialize-tachyon.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction-1] ```javascript filename="relay-aptos.js" const txId = await tachyon.relay({ chainId: 88888888, // Aptos chain ID to: '0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219', value: '1', callData: '0x', gasLimit: '100', // Required for Aptos label: 'My Aptos Transaction', }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status-1] ```javascript filename="check-status.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution-1] ```javascript filename="wait-execution.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Solana** Follow these steps to submit and track a transaction on Solana: Import the SDK [#import-the-sdk-2] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client-2] ```javascript filename="initialize-tachyon.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction-2] ```javascript filename="relay-solana.js" const txId = await tachyon.relay({ chainId: 10100000, // Solana chain ID to: 'BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm', value: '1', // 1 lamport callData: '0x', label: 'My Solana Transaction', }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status-2] ```javascript filename="check-status.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution-2] ```javascript filename="wait-execution.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Sui** Follow these steps to submit and track a transaction on Sui: Import the SDK [#import-the-sdk-3] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client-3] ```javascript filename="initialize-tachyon.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction-3] ```javascript filename="relay-sui.js" const txId = await tachyon.relay({ chainId: 897796746, // Sui chain ID to: '0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0', value: '1000', callData: '0x', gasLimit: '3000000', // Required for Sui label: 'My Sui Transaction', }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status-3] ```javascript filename="check-status.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution-3] ```javascript filename="wait-execution.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **NEAR** Follow these steps to submit and track a transaction on NEAR: Import the SDK [#import-the-sdk-4] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client-4] ```javascript filename="initialize-tachyon.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction-4] ```javascript filename="relay-near.js" const txId = await tachyon.relay({ chainId: 7777777, // NEAR chain ID to: 'deeprice6887.near', value: '1', // 1 yoctoNEAR callData: '0x', label: 'My NEAR Transaction', }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status-4] ```javascript filename="check-status.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution-4] ```javascript filename="wait-execution.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Starknet** Follow these steps to submit and track a transaction on Starknet: Import the SDK [#import-the-sdk-5] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' ``` Initialize the Tachyon Client [#initialize-the-tachyon-client-5] ```javascript filename="initialize-tachyon.js" const tachyon = new Tachyon({ apiKey: 'API-KEY', }) ``` Submit a Transaction [#submit-a-transaction-5] ```javascript filename="relay-starknet.js" const txId = await tachyon.relay({ "to": "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", "callData": "0x", "value": "1", "chainId": 23448594291968334, "label": "send strk", "retries": 0 }) console.log('Transaction submitted with ID:', txId) ``` Check Transaction Status [#check-transaction-status-5] ```javascript filename="check-status.js" const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) ``` Wait for Execution [#wait-for-execution-5] ```javascript filename="wait-execution.js" const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` *** Methods [#methods] `relay(params)` [#relayparams] Submits a transaction to the Tachyon relay network for execution. The relay service handles gas payments and transaction submission on your behalf, returning a unique transaction ID for tracking. **Parameters:** The `RelayParams` object defines the parameters required when calling the `relay()` method. | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR). Defaults to '0' if not specified. | | `label` | `string` | No | No human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Optional gas limit for the transaction. If not specified, it will be estimated automatically. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be used together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be used together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum cost in USD that you're willing to pay for this transaction. | | `retries` | `number` | No | Number of retry attempts for the transaction. Defaults to 0. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall operation. | | `isAuthenticatedTx` | `boolean` | No | Enable authenticated relay mode for additional security and verification. Defaults to false. | | `derivationPath` | `string` | No | Optional HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash" \| "authenticated" \| "funding-signed" \| "flash-blocks"` | No | Type of relay transaction. Defaults to `"flash"`. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | Optional list of authorization entries for delegated transactions or batched operations. Cannot be used with `"flash-blocks"` transaction type. | **Important Notes:** * `gasPrice` and `maxFeePerGas` cannot be used together * `gasPrice` and `maxPriorityFeePerGas` cannot be used together * If using EIP-1559 gas parameters, both `maxFeePerGas` and `maxPriorityFeePerGas` must be provided together * `authorizationList` is not allowed for `"flash-blocks"` transactions * `"flash-blocks"` transaction type is only supported on Base (8453) and Base Sepolia (84532) *** `getRelayStatus(txId)` [#getrelaystatustxid] Retrieves the current status of a relay transaction, including execution details, costs, and any errors that may have occurred. **Parameters:** | Name | Type | Required | Description | | ------ | -------- | -------- | ------------------------------------------------------ | | `txId` | `string` | Yes | The transaction ID returned from the `relay()` method. | **Returns:** `Promise` — A status object containing detailed information about the transaction. **Status Object Properties:** | Property | Type | Description | | ----------------- | ---------------- | -------------------------------------------------------------------------------- | | `id` | `string` | Unique transaction identifier. | | `status` | `string` | Current status (e.g., `"NOT_PICKED_UP"`, `"PENDING"`, `"EXECUTED"`, `"FAILED"`). | | `executionTxHash` | `string \| null` | On-chain transaction hash once executed, `null` if pending. | | `costUSD` | `number` | Estimated or actual cost of the transaction in USD. | | `timestamp` | `string` | ISO timestamp of when the transaction was submitted. | | `latency` | `number \| null` | Time taken for execution in milliseconds, `null` if not yet executed. | | `retries` | `number` | Number of retry attempts made for this transaction. | *** `waitForExecutionHash(txId, timeoutMs?, pollIntervalMs?)` [#waitforexecutionhashtxid-timeoutms-pollintervalms] Polls the relay service until the transaction has been executed on-chain, returning the final transaction status with the execution hash. This method is useful when you need to wait for confirmation before proceeding with subsequent operations. **Parameters:** | Name | Type | Required | Description | | ---------------- | -------- | -------- | --------------------------------------------------------------------- | | `txId` | `string` | Yes | The transaction ID to monitor. | | `timeoutMs` | `number` | Optional | Maximum time to wait for execution in milliseconds (default: 5000ms). | | `pollIntervalMs` | `number` | Optional | Time between status checks in milliseconds (default: 50ms). | **Returns:** `Promise` — The completed transaction status object with the execution hash. **Throws:** Will reject the promise if the timeout is reached before the transaction executes. *** Transaction Lifecycle [#transaction-lifecycle] 1. **Submission**: Call `relay()` with transaction parameters to submit to the relay network. 2. **Queued**: Transaction enters the relay queue with status `"NOT_PICKED_UP"`. 3. **Processing**: Relay service picks up and submits the transaction on-chain. 4. **Executed**: Transaction is confirmed on-chain and `executionTxHash` becomes available. *** Example Output [#example-output] After submitting a transaction and checking its status, you'll receive a response similar to this: ```json filename="status-response.json" { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": null, "label": "My Transaction", "status": "NOT_PICKED_UP", "executionTxHash": null, "timestamp": "2025-10-23T13:57:36.672Z", "latency": null, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": false, "extraData": null, "transactionType": "flash" } ``` Once the transaction is executed, the `executionTxHash` will be populated: ```plaintext filename="output.txt" Execution hash: 0x094b3e172162c1f7618397413dbcde074f7f908bc63fd8010d4e6ca40d5afa76 ``` You can use this hash to view the transaction on a block explorer or verify its execution on-chain. # Check Account Info (/tachyon/tachyon-sdk/check-account-info) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `checkAccountInfo(address)` [#checkaccountinfoaddress] Gets account information for a wallet address. ```typescript filename="check-account-info.ts" const accountInfo = await tachyon.checkAccountInfo('0x742d35cc...'); ``` **Parameters:** * `address` (string, required): Wallet address to query **Returns:** `Promise` - Account information **Account Info Properties:** * `userId`: User ID * `address`: Wallet address * `availableBalance`: Available balance * `pendingBalance`: Pending balance * `defaultTachyonAccount`: Default account details # Connect WebSocket (/tachyon/tachyon-sdk/connect-websocket) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `connectWebSocket(apiKey, onMessage, onError?, onClose?)` [#connectwebsocketapikey-onmessage-onerror-onclose] Connects to Tachyon via WebSocket. ```typescript filename="connect-websocket.ts" const socket = tachyon.connectWebSocket( apiKey, (msg) => console.log("Got message", msg), (err) => console.error("Socket error", err), () => console.log("Socket closed") ); // later socket.close(); ``` **Parameters:** * `apiKey`: User-specific API key for authentication * `onMessage` Callback for incoming messages (WebsocketMessage) * `onError` (optional): Callback on WebSocket error * `onClose` (optional): Callback when WebSocket closes **WebsocketMessage Types:** * `{ type: "notification"; data: TxNotificationPayload }` * `{ type: "system"; data: SystemMessagePayload }` * `{ type: "raw"; data: any }` **TxNotificationPayload Properties:** * `txId`: Transaction ID * `chainId`: Chain ID * `status`: PENDING | EXECUTED | FAILED | NEEDS\_TO\_BE\_RETRIED * `costUSD`: Execution cost * `totalNativeTokenUsed`: Total native token spent * `gasPrice`: Gas price used * `txHash`: On-chain transaction hash * `submittedAt`: ISO date string * `updatedAt`: ISO date string * `retries`: Number of retries **SystemMessagePayload Properties:** * `message`: System message string # Get Supported Chains (/tachyon/tachyon-sdk/get-supported-chains) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `getSupportedChains()` [#getsupportedchains] Gets all supported blockchain networks. ```typescript filename="get-supported-chains.ts" const chains = await tachyon.getSupportedChains(); ``` **Returns:** `Promise` - Array of supported chains **Chain Object Properties:** * `id`: Chain ID * `name`: Chain name * `iconUrl`: Chain icon URL * `isTestnet`: Whether it's a testnet * `nativeCurrency`: Native currency info * `blockExplorers`: Block explorer URLs # Get Version (/tachyon/tachyon-sdk/get-version) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `getVersion()` [#getversion] Gets the current SDK version. ```typescript filename="get-version.ts" const version = tachyon.getVersion(); ``` **Returns:** `string` - SDK version # Quickstart (/tachyon/tachyon-sdk) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Quickstart [#quickstart] Get started with the Tachyon SDK and submit your first transaction in minutes. Installation [#installation] Install the Package [#install-the-package] Install the Tachyon SDK using your preferred package manager: ```bash filename="install-dependencies.sh" npm install @rathfi/tachyon ``` ```bash filename="install-dependencies.sh" yarn add @rathfi/tachyon ``` ```bash filename="install-dependencies.sh" pnpm add @rathfi/tachyon ``` **Requirements:** * Node.js 16 or higher * TypeScript 4.5 or higher (if using TypeScript) Get Your API Key [#get-your-api-key] To use the Tachyon SDK, you'll need an API key: 1. Apply for the [API KEY](https://forms.gle/L2AqkS2GtN9HJKnY6) 2. Sign up or log in to your [Tachyon account](https://accounts.rath.fi) Basic Setup [#basic-setup] Create a new Tachyon instance with your API key: ```typescript filename="import-sdk.ts" import { Tachyon } from '@rathfi/tachyon'; const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, // Store your API key securely }); ``` Quick Start Guide [#quick-start-guide] Import the SDK [#import-the-sdk] ```typescript filename="import-sdk.ts" import { Tachyon, ChainId } from '@rathfi/tachyon'; ``` Import the `Tachyon` class and `ChainId` enum from the package. The `ChainId` enum provides type-safe chain identifiers for supported networks. Initialize the SDK [#initialize-the-sdk] ```typescript filename="initialize-tachyon.ts" const tachyon = new Tachyon({ apiKey: process.env.TACHYON_API_KEY!, // Store your API key securely }); ``` Create a new Tachyon instance with your API key. Always store your API key in environment variables for security. Submit a Transaction [#submit-a-transaction] ```typescript filename="relay-transaction.ts" const txId = await tachyon.relay({ chainId: ChainId.BASE, to: '0x742d35cc6634C0532925a3b8D1C9b53e6aC3', value: '1', // 1 wei callData: '0x', label: 'My Transaction' // Optional label for tracking }); console.log('Transaction ID:', txId); ``` Call the `relay()` method with your transaction parameters: * `chainId`: The target blockchain network * `to`: The recipient address * `value`: Amount in wei (use '0' for contract calls without value transfer) * `callData`: Encoded transaction data ('0x' for simple transfers) * `label`: Optional custom label for tracking Check Transaction Status [#check-transaction-status] ```typescript filename="get-status.ts" const status = await tachyon.getRelayStatus(txId); console.log('Transaction status:', status); ``` Use the returned `txId` to check the current status of your transaction. Wait for Execution [#wait-for-execution] ```typescript filename="wait-execution.ts" const executedTx = await tachyon.waitForExecutionHash(txId); console.log('Execution hash:', executedTx.executionTxHash); ``` Wait for the transaction to be executed on-chain and get the execution hash. # Is Chain Supported (/tachyon/tachyon-sdk/is-chain-supported) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `isChainSupported(chainId)` [#ischainsupportedchainid] Checks if a specific chain is supported. ```typescript filename="is-chain-supported.ts" const isSupported = await tachyon.isChainSupported(ChainId.BASE); ``` **Parameters:** * `chainId` (number, required): Chain ID to check **Returns:** `Promise` - Whether the chain is supported # Register Webhooks (/tachyon/tachyon-sdk/reg-webhook) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `registerWebhooks()` [#registerwebhooks] Register webhook endpoints to receive real-time notifications about transaction events and status updates for your Tachyon relay operations. Quick Start [#quick-start] ```javascript filename="register-webhooks.js" import { Tachyon } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Register webhooks const webhooks = await tachyon.registerWebhooks([ { url: 'https://your-app.com/webhooks/tachyon', authType: 'bearer', secret: 'your-webhook-secret', enabled: true, }, { url: 'https://your-app.com/webhooks/backup', authType: 'api-key', secret: 'your-api-key', apiKeyVar: 'X-API-Key', apiKeyPlacement: 'header', enabled: true, } ]); console.log('Registered webhooks for user:', webhooks.userId); console.log('Associated address:', webhooks.address); console.log('Active webhooks:', webhooks.webhooks); ``` Methods [#methods] `registerWebhooks(payload)` [#registerwebhookspayload] Registers one or more webhook endpoints to receive notifications about transaction events. You can configure multiple webhooks with different authentication methods for redundancy and flexibility. Parameters [#parameters] The `registerWebhooks()` method accepts an array of `WebhookRegistrationInput` objects with the following properties: | Name | Type | Required | Description | | ----------------- | -------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | `string` | Yes | The HTTPS endpoint URL where webhook notifications will be sent. Must be a valid, publicly accessible URL. | | `authType` | `"none"` \| `"bearer"` \| `"basic"` \| `"api-key"` | Yes | Authentication method for securing webhook requests. Options: `"none"` (no authentication), `"bearer"` (Bearer token), `"basic"` (Basic auth), `"api-key"` (API key). | | `secret` | `string` | No | Secret/token used for authentication. Required when `authType` is `"bearer"`, `"basic"`, or `"api-key"`. | | `apiKeyVar` | `string` | No | The name of the API key variable (e.g., `"X-API-Key"`, `"api_key"`). Required when `authType` is `"api-key"`. | | `apiKeyPlacement` | `"header"` \| `"query"` | No | Where to place the API key: in the request header or as a query parameter. Required when `authType` is `"api-key"`. | | `enabled` | `boolean` | Yes | Whether this webhook is active. Set to `false` to temporarily disable without deleting the configuration. | Authentication Types [#authentication-types] **None (`"none"`)** * No authentication required * Use only for testing or internal endpoints **Bearer Token (`"bearer"`)** * Sends `Authorization: Bearer {secret}` header * Recommended for most use cases **Basic Auth (`"basic"`)** * Sends `Authorization: Basic {base64(secret)}` header * Compatible with basic HTTP authentication **API Key (`"api-key"`)** * Flexible API key placement * Can be sent in header or query parameter * Specify custom variable name Response [#response] **Returns:** `Promise` The `WebhookRegistrationResponse` object contains: | Property | Type | Description | | ---------- | ----------------- | -------------------------------------------------- | | `userId` | `string` | Your unique user identifier in the Tachyon system. | | `address` | `string` | The wallet address associated with your account. | | `webhooks` | `WebhookConfig[]` | Array of registered webhook configurations. | WebhookConfig Object [#webhookconfig-object] | Property | Type | Description | | ---------- | ----------------- | ------------------------------------------------------- | | `url` | `string` | The registered webhook endpoint URL. | | `authType` | `WebhookAuthType` | The authentication method configured. | | `secret` | `string` | The authentication secret (may be masked for security). | | `enabled` | `boolean` | Whether the webhook is currently active. | Example Output [#example-output] ```json filename="webhook-config.json" { "userId": "usr_1234567890abcdef", "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "webhooks": [ { "url": "https://your-app.com/webhooks/tachyon", "authType": "bearer", "secret": "***************", "enabled": true }, { "url": "https://your-app.com/webhooks/backup", "authType": "api-key", "secret": "***************", "enabled": true } ] } ``` Authentication Examples [#authentication-examples] Bearer Token Authentication [#bearer-token-authentication] ```javascript filename="register-webhooks.js" const webhooks = await tachyon.registerWebhooks([ { url: 'https://api.yourapp.com/webhooks', authType: 'bearer', secret: 'your-secret-bearer-token', enabled: true, } ]); ``` API Key in Header [#api-key-in-header] ```javascript filename="register-webhooks.js" const webhooks = await tachyon.registerWebhooks([ { url: 'https://api.yourapp.com/webhooks', authType: 'api-key', secret: 'your-api-key-value', apiKeyVar: 'X-API-Key', apiKeyPlacement: 'header', enabled: true, } ]); ``` API Key in Query Parameter [#api-key-in-query-parameter] ```javascript filename="register-webhooks.js" const webhooks = await tachyon.registerWebhooks([ { url: 'https://api.yourapp.com/webhooks', authType: 'api-key', secret: 'your-api-key-value', apiKeyVar: 'api_key', apiKeyPlacement: 'query', enabled: true, } ]); ``` Basic Authentication [#basic-authentication] ```javascript filename="register-webhooks.js" const webhooks = await tachyon.registerWebhooks([ { url: 'https://api.yourapp.com/webhooks', authType: 'basic', secret: 'username:password', enabled: true, } ]); ``` No Authentication (Testing Only) [#no-authentication-testing-only] ```javascript filename="register-webhooks.js" const webhooks = await tachyon.registerWebhooks([ { url: 'https://your-dev-server.com/test-webhooks', authType: 'none', enabled: true, } ]); ``` Use Cases [#use-cases] * **Real-time notifications**: Receive instant updates when transactions are confirmed or fail. * **Transaction monitoring**: Track the status of relay operations across multiple chains. * **Automated workflows**: Trigger business logic in your application based on transaction events. * **Redundancy**: Configure multiple webhook endpoints for high-availability systems. * **Audit logging**: Maintain a record of all transaction events in your own database. Best Practices [#best-practices] 1. **Use HTTPS**: Always use secure HTTPS endpoints for webhook URLs. 2. **Implement retry logic**: Handle webhook delivery failures gracefully on your server. 3. **Validate signatures**: Verify the authenticity of incoming webhook requests. 4. **Enable selectively**: Set `enabled: false` for webhooks during maintenance without deleting them. 5. **Monitor webhook health**: Track delivery success rates and response times. 6. **Use strong secrets**: Generate cryptographically secure tokens for authentication. # Register WebSocket (/tachyon/tachyon-sdk/reg-websocket) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `registerWebsocket()` [#registerwebsocket] Registers a WebSocket for a user and returns the connection details needed to establish a real-time connection with the Tachyon relay service. ```typescript filename="register-websocket.ts" const wsConfig = await tachyon.registerWebsocket(); ``` **Returns:** `Promise` - Response of registered websocket **WebsocketRegistrationResponse Properties:** * `wsUrl`: WebSocket URL to connect to * `apiKey`: User-specific persistent API key for authentication Usage Examples [#usage-examples] Basic WebSocket Connection [#basic-websocket-connection] ```typescript filename="basic-websocket.ts" import { Tachyon } from '@rathfi/tachyon' // Initialize Tachyon client const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) // Register WebSocket and get connection details const wsConfig = await tachyon.registerWebsocket() console.log('WebSocket URL:', wsConfig.wsUrl) console.log('API Key:', wsConfig.apiKey) // Connect to WebSocket const ws = new WebSocket(wsConfig.wsUrl, { headers: { 'x-ws-token': wsConfig.apiKey, }, }) ws.on('open', () => { console.log('WebSocket connected!') }) ws.on('message', (data) => { const message = JSON.parse(data.toString()) console.log('Received:', message) }) ws.on('close', () => { console.log('WebSocket disconnected') }) ws.on('error', (error) => { console.error('WebSocket error:', error) }) ``` Browser Usage [#browser-usage] ```typescript filename="browser-websocket.ts" import { Tachyon } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) // Register and connect const wsConfig = await tachyon.registerWebsocket() // Create WebSocket connection (browsers don't support custom headers in constructor) // The token must be passed as a query parameter or handled differently const ws = new WebSocket(wsConfig.wsUrl) ws.onopen = () => { console.log('WebSocket connected!') } ws.onmessage = (event) => { const message = JSON.parse(event.data) console.log('Received:', message) if (message.error) { console.error('Error:', message.error) } } ws.onclose = () => { console.log('WebSocket disconnected') } ws.onerror = (error) => { console.error('WebSocket error:', error) } // Send a message ws.send(JSON.stringify({ type: 'ping', data: 'Hello!' })) ``` Sending and Receiving Messages [#sending-and-receiving-messages] ```typescript filename="websocket-messaging.ts" const wsConfig = await tachyon.registerWebsocket() const ws = new WebSocket(wsConfig.wsUrl, { headers: { 'x-ws-token': wsConfig.apiKey, }, }) ws.on('open', () => { // Send a message to the server ws.send(JSON.stringify({ type: 'subscribe', chainId: 8453, })) }) ws.on('message', (data) => { const message = JSON.parse(data.toString()) // Handle initial connection message if (message.message === 'WebSocket connected!') { console.log('Successfully connected to Tachyon relay') } // Handle echo responses if (message.echo) { console.log('Echo from server:', message.echo) } // Handle errors if (message.error) { console.error('Server error:', message.error) } }) ``` Monitoring Transaction Updates [#monitoring-transaction-updates] ```typescript filename="monitor-transactions.ts" const wsConfig = await tachyon.registerWebsocket() const ws = new WebSocket(wsConfig.wsUrl, { headers: { 'x-ws-token': wsConfig.apiKey, }, }) // Submit a transaction const txId = await tachyon.relay({ chainId: 8453, to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', callData: '0x', }) console.log('Transaction submitted:', txId) // Listen for real-time updates ws.on('message', (data) => { const message = JSON.parse(data.toString()) // Handle transaction status updates if (message.type === 'tx-update' && message.txId === txId) { console.log('Transaction status:', message.status) if (message.executionTxHash) { console.log('Execution hash:', message.executionTxHash) } } }) ``` Connection with Automatic Reconnection [#connection-with-automatic-reconnection] ```typescript filename="auto-reconnect-websocket.ts" let ws: WebSocket let wsConfig: any let reconnectAttempts = 0 const MAX_RECONNECT_ATTEMPTS = 5 async function connectWebSocket() { try { // Register WebSocket (reuse config if already registered) if (!wsConfig) { wsConfig = await tachyon.registerWebsocket() } ws = new WebSocket(wsConfig.wsUrl, { headers: { 'x-ws-token': wsConfig.apiKey, }, }) ws.on('open', () => { console.log('WebSocket connected!') reconnectAttempts = 0 }) ws.on('message', (data) => { const message = JSON.parse(data.toString()) console.log('Received:', message) }) ws.on('close', () => { console.log('WebSocket closed') attemptReconnect() }) ws.on('error', (error) => { console.error('WebSocket error:', error) }) } catch (error) { console.error('Failed to connect:', error) attemptReconnect() } } function attemptReconnect() { if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { reconnectAttempts++ const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000) console.log(`Reconnecting in ${delay}ms... (attempt ${reconnectAttempts})`) setTimeout(connectWebSocket, delay) } else { console.error('Max reconnection attempts reached') } } // Initialize connection connectWebSocket() ``` Authentication [#authentication] The WebSocket connection requires authentication using the `x-ws-token` header with the API key returned from `registerWebsocket()`. If authentication fails, the connection will be closed with an "Unauthorized" error message. **Important:** The API key returned from `registerWebsocket()` is user-specific and persistent. Store it securely and reuse it for subsequent connections. # Relay Signed Transactions (/tachyon/tachyon-sdk/relay-tx-signed) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Relay Signed Transactions [#relay-signed-transactions] The Tachyon SDK provides a specialized method for submitting pre-signed transactions with automatic funding. This is useful when you need to execute transactions from a specific address while having Tachyon handle the gas payments and ensure the account has sufficient balance. Overview [#overview] The `relaySignedTx()` method allows you to: * Submit pre-signed transactions for execution * Automatically fund the sender address with the minimum required balance * Track transaction status using the same methods as regular relay transactions * Maintain control over transaction signing while outsourcing gas payment **Use Cases:** * Executing transactions from deterministic addresses * Managing multiple accounts with centralized funding * Implementing account abstraction patterns * Batch operations requiring specific signer addresses Method Reference [#method-reference] `relaySignedTx(params)` [#relaysignedtxparams] Submits a pre-signed transaction to the Tachyon relay network. Tachyon will ensure the sender address is funded with at least `minBalanceRequired` before broadcasting the signed transaction. **Parameters:** The `SignedTransactionParams` object defines the parameters required when calling the `relaySignedTx()` method. | Name | Type | Required | Description | | -------------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `fromAddress` | `string` | Yes | The address that signed the transaction. This address will be funded if needed. Must be a valid address for the specified chain. | | `signedTx` | `string` | Yes | The complete signed transaction data in hexadecimal format. This should be the raw signed transaction ready for broadcast. | | `minBalanceRequired` | `string` | Yes | The minimum balance required in the sender's account to execute the transaction (in smallest unit - wei for EVM chains). Typically calculated as `gasLimit * maxFeePerGas`. | | `label` | `string` | No | Optional human-readable label for easier transaction identification and tracking. | **Returns:** `Promise` — A unique transaction ID that can be used to track the transaction status and execution. **Throws:** * Error if required parameters are missing * Error if the from address is invalid for the specified chain * Error if the funding cost exceeds account limits * Error if the account has insufficient balance * Error if the chain is disabled for the account Complete Examples [#complete-examples] Basic EVM Transaction [#basic-evm-transaction] ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon' import { ethers } from 'ethers' async function relaySignedTransaction() { // Initialize Tachyon const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) // Create wallet const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY') // Prepare transaction const tx = { to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: ethers.parseEther('0.01'), data: '0x', chainId: 8453, // Base nonce: 0, gasLimit: 21000, maxFeePerGas: ethers.parseUnits('2', 'gwei'), maxPriorityFeePerGas: ethers.parseUnits('1', 'gwei'), } // Sign transaction const signedTx = await wallet.signTransaction(tx) // Calculate minimum balance (gas cost) const minBalance = ( BigInt(tx.gasLimit) * BigInt(tx.maxFeePerGas) ).toString() // Submit to Tachyon const txId = await tachyon.relaySignedTx({ chainId: tx.chainId, fromAddress: wallet.address, signedTx: signedTx, minBalanceRequired: minBalance, label: 'Transfer 0.01 ETH', }) console.log('Transaction ID:', txId) // Wait for execution const result = await tachyon.waitForExecutionHash(txId, 60000) console.log('Transaction executed:', result.executionTxHash) return result } relaySignedTransaction() ``` Smart Contract Interaction [#smart-contract-interaction] ```javascript filename="import-sdk.js" import { Tachyon } from '@rathfi/tachyon' import { ethers } from 'ethers' async function callContract() { const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY') // Encode contract call const contractAddress = '0x...' const abi = ['function transfer(address to, uint256 amount)'] const iface = new ethers.Interface(abi) const callData = iface.encodeFunctionData('transfer', [ '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', ethers.parseEther('100'), ]) // Prepare and sign transaction const tx = { to: contractAddress, value: 0, data: callData, chainId: 8453, nonce: 0, gasLimit: 100000, maxFeePerGas: ethers.parseUnits('2', 'gwei'), maxPriorityFeePerGas: ethers.parseUnits('1', 'gwei'), } const signedTx = await wallet.signTransaction(tx) const minBalance = ( BigInt(tx.gasLimit) * BigInt(tx.maxFeePerGas) ).toString() // Submit signed transaction const txId = await tachyon.relaySignedTx({ chainId: tx.chainId, fromAddress: wallet.address, signedTx: signedTx, minBalanceRequired: minBalance, label: 'Token Transfer', }) return txId } ``` With Automatic Nonce Management [#with-automatic-nonce-management] ```javascript filename="import-sdk.js" import { Tachyon } from '@rathfi/tachyon' import { ethers } from 'ethers' async function relayWithAutoNonce(provider) { const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider) // Get current nonce from provider const nonce = await provider.getTransactionCount(wallet.address) // Get current gas prices const feeData = await provider.getFeeData() const tx = { to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: ethers.parseEther('0.001'), data: '0x', chainId: 8453, nonce: nonce, gasLimit: 21000, maxFeePerGas: feeData.maxFeePerGas, maxPriorityFeePerGas: feeData.maxPriorityFeePerGas, } const signedTx = await wallet.signTransaction(tx) const minBalance = ( BigInt(tx.gasLimit) * BigInt(tx.maxFeePerGas) ).toString() const txId = await tachyon.relaySignedTx({ chainId: tx.chainId, fromAddress: wallet.address, signedTx: signedTx, minBalanceRequired: minBalance, }) return txId } ``` Batch Processing Multiple Signed Transactions [#batch-processing-multiple-signed-transactions] ```javascript filename="import-sdk.js" import { Tachyon } from '@rathfi/tachyon' import { ethers } from 'ethers' async function batchRelaySignedTransactions() { const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }) const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY') const recipients = [ '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', '0x8888888888888888888888888888888888888888', ] const txIds = [] for (let i = 0; i < recipients.length; i++) { const tx = { to: recipients[i], value: ethers.parseEther('0.001'), data: '0x', chainId: 8453, nonce: i, // Sequential nonces gasLimit: 21000, maxFeePerGas: ethers.parseUnits('2', 'gwei'), maxPriorityFeePerGas: ethers.parseUnits('1', 'gwei'), } const signedTx = await wallet.signTransaction(tx) const minBalance = ( BigInt(tx.gasLimit) * BigInt(tx.maxFeePerGas) ).toString() const txId = await tachyon.relaySignedTx({ chainId: tx.chainId, fromAddress: wallet.address, signedTx: signedTx, minBalanceRequired: minBalance, label: `Batch transfer ${i + 1}/${recipients.length}`, }) txIds.push(txId) console.log(`Submitted transaction ${i + 1}:`, txId) } // Wait for all transactions to execute const results = await Promise.all( txIds.map(txId => tachyon.waitForExecutionHash(txId)) ) return results } ``` How It Works [#how-it-works] 1. **Transaction Signing**: You sign the transaction with your private key using your preferred wallet/signer 2. **Funding Check**: Tachyon checks if the sender address has sufficient balance 3. **Automatic Funding**: If needed, Tachyon funds the address with the `minBalanceRequired` amount 4. **Transaction Broadcast**: Once funded, Tachyon broadcasts your pre-signed transaction 5. **Execution**: The transaction executes on-chain from your specified address Cost Calculation [#cost-calculation] The cost for a signed transaction relay includes: * **Funding Cost**: The `minBalanceRequired` amount needed to execute your transaction * **Service Fee**: A 8% service fee applied to the funding cost **Example:** ```javascript filename="example.js" // If minBalanceRequired = 0.001 ETH (in wei) // Funding cost = 0.001 ETH // Total cost = 0.001 ETH * 1.08 = 0.00108 ETH ``` The funding cost is deducted from your Tachyon account balance, not from the sender address. Important Notes [#important-notes] * The `fromAddress` must be a valid address for the specified chain * The `signedTx` must be properly signed and ready for broadcast * `minBalanceRequired` should cover the maximum possible gas cost (gasLimit × maxFeePerGas) * Tachyon will fund the address before broadcasting, so ensure your account has sufficient balance * The transaction type is automatically set to `FUNDING_SIGNED` * Once submitted, you can track the transaction using the same status methods as regular relay transactions Error Handling [#error-handling] ```javascript filename="sign-transaction.js" try { const txId = await tachyon.relaySignedTx({ chainId: 8453, fromAddress: wallet.address, signedTx: signedTx, minBalanceRequired: minBalance, }) console.log('Success:', txId) } catch (error) { if (error.message.includes('Invalid from address')) { console.error('Address validation failed') } else if (error.message.includes('Insufficient balance')) { console.error('Not enough balance in Tachyon account') } else if (error.message.includes('Cost exceeded')) { console.error('Transaction cost exceeds limits') } else { console.error('Submission failed:', error.message) } } ``` # Relay Transactions - Sync (/tachyon/tachyon-sdk/relay-tx-sync) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Relay Transactions - Sync [#relay-transactions---sync] The `relaySync()` method submits a transaction to the relay network and waits until it either reaches a terminal state or the configured timeout expires. Unlike `relay()`, it returns the latest known transaction status object directly instead of only returning a transaction ID. Quick Start [#quick-start] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```javascript filename="relay-sync.js" import { Tachyon, ChainId } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { chainId: ChainId.BASE, // 8453 to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', callData: '0x', label: 'My Base Transaction', }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` **Aptos** ```javascript filename="relay-sync-aptos.js" import { Tachyon } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { chainId: 88888888, to: '0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219', value: '1', callData: '0x', gasLimit: '100', label: 'My Aptos Transaction', }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` **Solana** ```javascript filename="relay-sync-solana.js" import { Tachyon } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { chainId: 10100000, to: 'BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm', value: '1', callData: '0x', label: 'My Solana Transaction', }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` **Sui** ```javascript filename="relay-sync-sui.js" import { Tachyon, ChainId } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { chainId: ChainId.SUI, to: '0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0', value: '100000000', callData: '0x', gasLimit: '3000000', label: 'send-native-sui', }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` **NEAR** ```javascript filename="relay-sync-near.js" import { Tachyon, ChainId } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { chainId: ChainId.NEAR, to: 'deeprice6887.near', value: '1', callData: '0x', label: 'My NEAR Transaction', }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` **Starknet** ```javascript filename="relay-sync-starknet.js" import { Tachyon } from '@rathfi/tachyon' const tachyon = new Tachyon({ apiKey: 'API-KEY', }) const result = await tachyon.relaySync( { to: '0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B', callData: '0x', value: '1', chainId: 23448594291968334, label: 'send strk', retries: 0, }, { timeoutMs: 30000, } ) console.log('Transaction status:', result.status) console.log('Execution hash:', result.executionTxHash) ``` Example Output [#example-output] When the transaction finishes within the timeout window, you'll receive a response like this: ```json filename="relay-sync-response.json" { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": "21000", "label": "My Base Transaction", "status": "EXECUTED", "executionTxHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "timestamp": "2025-10-24T12:34:56.789Z", "latency": 2500, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": true, "extraData": null, "transactionType": "flash" } ``` If the timeout expires first, the runtime response may include `timedOut: true` with the latest known status: ```json filename="relay-sync-timeout-response.json" { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": "21000", "label": "My Base Transaction", "status": "PENDING", "executionTxHash": null, "timestamp": "2025-10-24T12:34:56.789Z", "latency": null, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": false, "extraData": null, "transactionType": "flash", "timedOut": true } ``` Methods [#methods] `relaySync(tx, options?)` [#relaysynctx-options] Submits a transaction to the Tachyon relay network and waits for the latest known execution result. The method returns a status object rather than a `txId`, so it is useful when you want synchronous submit-and-wait behavior in a single SDK call. Parameters [#parameters] | Name | Type | Required | Description | | --------- | ------------------------- | -------- | ------------------------------------------------------- | | `tx` | `RelayParams` | Yes | Transaction payload. Uses the same fields as `relay()`. | | `options` | `RelaySyncOptionalFields` | No | Controls timeout and optional response enrichment. | `RelayParams` [#relayparams] The `RelayParams` object defines the transaction fields accepted by `relaySync()`: | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). Must be a valid address for the specified chain. | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No (default: `'0'`) | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Use '0' for contract calls with no value transfer. | | `label` | `string` | No | Human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Gas limit for the transaction. If not specified, it will be estimated automatically. Required for Aptos transactions. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be provided together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be provided together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum USD cost limit for the transaction. Transaction will fail if estimated cost exceeds this value. | | `retries` | `number` | No (default: `0`) | Number of retry attempts for failed transactions. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall for gas optimization. | | `isAuthenticatedTx` | `boolean` | No (default: `false`) | Enable authenticated relay mode for additional security and verification. | | `derivationPath` | `string` | No | HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash"` \| `"authenticated"` \| `"funding-signed"` \| `"flash-blocks"` | Optional (default: `"flash"`) | Type of relay transaction. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | List of authorization entries for delegated transactions or batched operations. Not allowed for `"flash-blocks"` transactions. | `RelaySyncOptionalFields` [#relaysyncoptionalfields] | Name | Type | Required | Description | | ------------------- | --------- | --------------------- | -------------------------------------------------------------------------- | | `timeoutMs` | `number` | No (default: `30000`) | Maximum time to wait before returning. Minimum `1000`, maximum `120000`. | | `includeReceipt` | `boolean` | No (default: `false`) | Include the transaction receipt when available. | | `includeRevertInfo` | `boolean` | No (default: `false`) | Include decoded revert information for failed transactions when available. | Important Behavior [#important-behavior] * `relaySync()` returns the terminal transaction status when it reaches `EXECUTED` or `FAILED` within the timeout window. * If the timeout expires first, the method returns the latest known transaction status. The runtime response may include `timedOut: true`. * A transaction with `status: "FAILED"` is still returned as a successful SDK response. The method throws only for request validation errors or API failures. * After a timeout, continue tracking with `tachyon.getRelayStatus(result.id)` or `tachyon.waitForExecutionHash(result.id)`. Response [#response] **Returns:** `Promise` The returned object includes the same core fields as `getRelayStatus()`, including: | Property | Type | Description | | ----------------- | ------------------- | ----------------------------------------- | | `id` | `string` | Unique transaction ID. | | `status` | `TransactionStatus` | Current transaction status. | | `executionTxHash` | `string \| null` | On-chain transaction hash when available. | | `latency` | `number \| null` | Time taken for execution in milliseconds. | | `costUSD` | `number` | Transaction cost in USD. | | `error` | `string \| null` | Error message if the transaction failed. | Depending on the options passed and the transaction outcome, the runtime response may also include: | Property | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------- | | `timedOut` | `boolean` | Present when the timeout expires before a terminal state is reached. | | `receipt` | `object` | Present when `includeReceipt` is enabled and a receipt is available. | | `revert` | `object` | Present when `includeRevertInfo` is enabled and revert data is available. | # Relay Transactions (/tachyon/tachyon-sdk/relay-tx) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Relay Transactions [#relay-transactions] The Tachyon SDK provides a complete workflow for submitting transactions to the relay network, monitoring their status, and waiting for on-chain execution. This guide covers the three main methods you'll use: submitting transactions, checking their status, and waiting for confirmation. Quick Start [#quick-start] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```javascript filename="relay-transaction.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on Base const txId = await tachyon.relay({ chainId: ChainId.BASE, // 8453 to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', // 1 wei callData: '0x', label: 'My Base Transaction', }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Aptos** ```javascript filename="relay-aptos.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on Aptos const txId = await tachyon.relay({ chainId: 88888888, // Aptos chain ID to: '0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219', value: '1', callData: '0x', gasLimit: '100', // Required for Aptos label: 'My Aptos Transaction', }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Solana** ```javascript filename="relay-solana.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on Solana const txId = await tachyon.relay({ chainId: 10100000, // Solana chain ID to: 'BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm', value: '1', // 1 lamport callData: '0x', label: 'My Solana Transaction', }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Sui** ```javascript filename="relay-sui.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on Sui const txId = await tachyon.relay({ chainId: 897796746, // Sui chain ID to: '0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0', value: '100000000', // 0.1 SUI (in MIST) callData: '0x', gasLimit: '3000000', label: 'send-native-sui', }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **NEAR** ```javascript filename="relay-near.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on NEAR const txId = await tachyon.relay({ chainId: 7777777, // NEAR chain ID to: 'deeprice6887.near', value: '1', // 1 yoctoNEAR callData: '0x', label: 'My NEAR Transaction', }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` **Starknet** ```javascript filename="relay-starknet.js" import { Tachyon, ChainId } from '@rathfi/tachyon' // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'API-KEY', }) // Submit a transaction on Starknet const txId = await tachyon.relay({ to: "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", callData: "0x", value: "1", chainId: 23448594291968334, label: "send strk", retries: 0 }) console.log('Transaction submitted with ID:', txId) // Check transaction status const status = await tachyon.getRelayStatus(txId) console.log('Transaction status:', status.status) // Wait for execution const executedTx = await tachyon.waitForExecutionHash(txId) console.log('Execution hash:', executedTx.executionTxHash) ``` Example Output [#example-output] After submitting a transaction and checking its status, you'll receive a response similar to this: ```json filename="relay-response.json" { "id": "68fa3450539a3c9d28bbca33", "userId": "68c275846a6ba1c9a2198a8c", "to": "0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49", "callData": "0x", "value": "1", "chainId": 8453, "gasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasLimit": null, "label": "My Transaction", "status": "NOT_PICKED_UP", "executionTxHash": null, "timestamp": "2025-10-23T13:57:36.672Z", "latency": null, "costUSD": 0.8400561743999754, "retries": 0, "isAccountCharged": false, "extraData": null, "transactionType": "flash" } ``` Methods [#methods] `relay(params)` [#relayparams] Submits a transaction to the Tachyon relay network for execution. The relay service handles gas payments and transaction submission on your behalf, returning a unique transaction ID for tracking. Parameters [#parameters] The `RelayParams` object defines the parameters required when calling the `relay()` method. | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). Must be a valid address for the specified chain. | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No (default: `'0'`) | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Use '0' for contract calls with no value transfer. | | `label` | `string` | No | Human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Gas limit for the transaction. If not specified, it will be estimated automatically. Required for Aptos transactions. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be provided together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be provided together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum USD cost limit for the transaction. Transaction will fail if estimated cost exceeds this value. | | `retries` | `number` | No (default: `0`) | Number of retry attempts for failed transactions. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall for gas optimization. | | `isAuthenticatedTx` | `boolean` | No (default: `false`) | Enable authenticated relay mode for additional security and verification. | | `derivationPath` | `string` | No | HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash"` \| `"authenticated"` \| `"funding-signed"` \| `"flash-blocks"` | Optional (default: `"flash"`) | Type of relay transaction. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | List of authorization entries for delegated transactions or batched operations. Not allowed for `"flash-blocks"` transactions. | Important Constraints [#important-constraints] * **Gas Parameters**: `gasPrice` cannot be used together with `maxFeePerGas` or `maxPriorityFeePerGas` * **EIP-1559 Fees**: Both `maxFeePerGas` and `maxPriorityFeePerGas` must be provided together if either is specified * **Flash-blocks Support**: `transactionType: "flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532) * **Authorization List**: `authorizationList` cannot be used with `"flash-blocks"` transaction type * **Address Validation**: The `to` address must be valid for the specified `chainId` **Returns:** `Promise` — A unique transaction ID that can be used to track the transaction status and execution. # Get Relay Status (/tachyon/tachyon-sdk/relay_status) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `getRelayStatus(txId)` [#getrelaystatustxid] Gets the current status of a submitted transaction. ```typescript filename="get-relay-status.ts" const status = await tachyon.getRelayStatus('tx_id_here'); ``` **Parameters:** * `txId` (string, required): The transaction ID returned from `relay()` **Returns:** `Promise` - Transaction status object **Status Object Properties:** * `id`: Transaction ID * `status`: Current status (`EXECUTED`, `FAILED`, `NOT_PICKED_UP`, `PENDING`, `NEEDS_TO_BE_RETRIED`) * `to`: Recipient address * `callData`: Transaction data * `value`: Amount in wei * `chainId`: Network ID * `executionTxHash`: On-chain transaction hash (null if not executed) * `timestamp`: Submission timestamp * `latency`: Execution latency in milliseconds * `costUSD`: Execution cost in USD * `error`: Error message (if failed) # Estimate Transaction Fee (Quote) (/tachyon/tachyon-sdk/tx-quote) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Get Transaction Quote [#get-transaction-quote] Before submitting a transaction, you can request a quote to estimate the cost in USD and the minimum balance required. This helps you understand the transaction cost upfront and ensure your account has sufficient balance. Quick Start [#quick-start] **EVM Chains (Ethereum, Base, Polygon, etc.)** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for a Base transaction const quote = await tachyon.getQuote({ chainId: ChainId.BASE, // 8453 to: '0x3dbE34f2C21b3B2980d4dc53f3c7E51e39663F49', value: '1', // 1 wei callData: '0x', label: 'My Base Transaction', }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` **Aptos** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for an Aptos transaction const quote = await tachyon.getQuote({ chainId: 88888888, // Aptos chain ID to: '0x09ebf332aa3e4edad203aff521bd8a47597119de1956885711223ec157eac219', value: '1', callData: '0x', gasLimit: '100', // Required for Aptos label: 'My Aptos Transaction', }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` **Solana** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for a Solana transaction const quote = await tachyon.getQuote({ chainId: 10100000, // Solana chain ID to: 'BSNsLtDDM1wN8rjEJQaZreVqRhibsUtsEq9m1G2deAm', value: '1', // 1 lamport callData: '0x', label: 'My Solana Transaction', }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` **Sui** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for a Sui transaction const quote = await tachyon.getQuote({ chainId: 897796746, // Sui chain ID to: '0xf78da4499004aa2d594143d69a7804f6f989ab8152de59d3726def827c9fe1f0', value: '100000000', // 0.1 SUI in MIST (1 SUI = 10^9 MIST) callData: '0x', gasLimit: '3000000', // Gas limit for Sui label: 'send-native-sui', }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` **NEAR** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for a NEAR transaction const quote = await tachyon.getQuote({ chainId: 7777777, // NEAR chain ID to: 'deeprice6887.near', value: '1', // 1 yoctoNEAR callData: '0x', label: 'My NEAR Transaction', }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` **Starknet** ```javascript filename="import-sdk.js" import { Tachyon, ChainId } from '@rathfi/tachyon'; // Initialize the SDK const tachyon = new Tachyon({ apiKey: 'YOUR_API_KEY', }); // Get a quote for the Starknet transaction const quote = await tachyon.getQuote({ to: "0x021Af6FEc4753c4C7C248Dc68d1B43ed721f0246e9dC8A9e5b7d74Ff3373764B", callData: "0x", value: "1", chainId: 23448594291968334, label: "send strk", retries: 0 }); console.log('Estimated cost (USD):', quote.costUSD); console.log('Minimum balance required:', quote.minBalanceRequired); ``` Methods [#methods] `getQuote(params)` [#getquoteparams] Retrieves an estimated quote for relaying a transaction, including the cost in USD and minimum balance required. This allows you to inform users of costs before they commit to a transaction. Parameters [#parameters] The `getQuote()` method accepts a `RelayParams` object with the following properties: | Name | Type | Required | Description | | ------------------------ | ------------------------------------------------------------------------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `chainId` | `number` | Yes | The blockchain network ID where the transaction will be executed. Must be a supported chain. | | `to` | `string` | Yes | The recipient wallet address or smart contract address. Format varies by chain (hex for EVM, base58 for Solana, named for NEAR). Must be a valid address for the specified chain. | | `callData` | `string` | Yes | Encoded transaction data in hexadecimal format (use '0x' for simple transfers). | | `value` | `string` | No (default: `'0'`) | Amount of native currency to send in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui). Use '0' for contract calls with no value transfer. | | `label` | `string` | No | Human-readable label for easier transaction identification and tracking. | | `gasLimit` | `string` | No | Gas limit for the transaction. If not specified, it will be estimated automatically. Required for Aptos transactions. | | `gasPrice` | `string` | No | Gas price for legacy transactions. Cannot be used with `maxFeePerGas` or `maxPriorityFeePerGas`. | | `maxFeePerGas` | `string` | No | Maximum fee per gas for EIP-1559 transactions. Must be provided together with `maxPriorityFeePerGas`. | | `maxPriorityFeePerGas` | `string` | No | Maximum priority fee per gas for EIP-1559 transactions. Must be provided together with `maxFeePerGas`. | | `maxUSD` | `number` | No | Maximum USD cost limit for the transaction. Quote will reflect if estimated cost exceeds this value. | | `retries` | `number` | No (default: `0`) | Number of retry attempts for failed transactions. | | `shouldBatchInMulticall` | `boolean` | No | Whether to batch this transaction in a multicall for gas optimization. | | `isAuthenticatedTx` | `boolean` | No (default: `false`) | Enable authenticated relay mode for additional security and verification. | | `derivationPath` | `string` | No | HD wallet derivation path for transaction signing (useful for multi-account setups). | | `transactionType` | `"flash"` \| `"authenticated"` \| `"funding-signed"` \| `"flash-blocks"` | No (default: `"flash"`) | Type of relay transaction. `"flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532). | | `authorizationList` | `AuthorizationListItem[]` | No | List of authorization entries for delegated transactions or batched operations. Not allowed for `"flash-blocks"` transactions. | Important Constraints [#important-constraints] * **Gas Parameters**: `gasPrice` cannot be used together with `maxFeePerGas` or `maxPriorityFeePerGas` * **EIP-1559 Fees**: Both `maxFeePerGas` and `maxPriorityFeePerGas` must be provided together if either is specified * **Flash-blocks Support**: `transactionType: "flash-blocks"` is only supported on Base (8453) and Base Sepolia (84532) * **Authorization List**: `authorizationList` cannot be used with `"flash-blocks"` transaction type * **Address Validation**: The `to` address must be valid for the specified `chainId` Response [#response] **Returns:** `Promise` The `QuoteResponse` object contains: | Property | Type | Description | | -------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `costUSD` | `number` | Estimated transaction cost in USD. | | `minBalanceRequired` | `string` | Minimum balance required in the smallest unit (wei for EVM, lamports for Solana, yoctoNEAR for NEAR, MIST for Sui) to execute the transaction. | Example Output [#example-output] ```json filename="quote-response.json" { "costUSD": 0.0009221670934825817, "minBalanceRequired": "223171904787" } ``` **Response Details:** * **costUSD**: The estimated cost to relay the transaction, denominated in US dollars. This includes gas fees and relay service charges. * **minBalanceRequired**: The minimum balance that must be available in your account to successfully execute this transaction. The unit varies by chain: * **EVM chains**: Wei (1 ETH = 10^18 wei) * **Solana**: Lamports (1 SOL = 10^9 lamports) * **NEAR**: yoctoNEAR (1 NEAR = 10^24 yoctoNEAR) * **Aptos**: Octas (1 APT = 10^8 octas) * **Sui**: MIST (1 SUI = 10^9 MIST) Use Cases [#use-cases] * **Pre-transaction validation**: Check if users have sufficient balance before attempting a transaction. * **Cost transparency**: Display estimated costs to users in your application UI. * **Budget planning**: Help users understand the financial impact of their transactions. * **Multi-chain comparison**: Compare costs across different blockchain networks for the same operation. # Types and Enums (/tachyon/tachyon-sdk/types) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. Types and Enums [#types-and-enums] `ChainId` [#chainid] Enum of supported blockchain network IDs: ```typescript filename="types.ts" enum ChainId { ETHEREUM = 1, OPTIMISM = 10, BSC = 56, POLYGON = 137, ARBITRUM_ONE = 42161, BASE = 8453, // ... and more } ``` `TransactionStatus` [#transactionstatus] Enum of possible transaction statuses: ```typescript filename="types.ts" enum TransactionStatus { NOT_PICKED_UP = 'NOT_PICKED_UP', PENDING = 'PENDING', EXECUTED = 'EXECUTED', FAILED = 'FAILED', NEEDS_TO_BE_RETRIED = 'NEEDS_TO_BE_RETRIED' } ``` # Wait For Execution Hash (/tachyon/tachyon-sdk/wait-exec-hash) ## Documentation Index Fetch the complete documentation index at: https://docs.rath.fi/llms.txt Use this file to discover all available pages before exploring further. `waitForExecutionHash(txId, timeoutMs?, pollIntervalMs?)` [#waitforexecutionhashtxid-timeoutms-pollintervalms] Polls for transaction execution and returns when complete. ```typescript filename="wait-execution-hash.ts" const executedTx = await tachyon.waitForExecutionHash( 'tx_id_here', 30000, // 30 second timeout 1000 // poll every 1 second ); ``` **Parameters:** * `txId` (string, required): Transaction ID * `timeoutMs` (number, optional): Maximum wait time in ms (default: 5000) * `pollIntervalMs` (number, optional): Polling interval in ms (default: 50) **Returns:** `Promise` - Completed transaction status **Throws:** Error if timeout reached or transaction fails