# LoomLay Documentation - Full Content This file contains the complete text content of all documentation pages. Use this for comprehensive context when answering questions. --- # Glossary > Key terms and definitions URL: https://docs.loomlay.com/glossary # Glossary A reference guide to common terms used throughout the LoomLay platform and documentation. --- ## Blockchain Terms ### SOL The native token of the Solana blockchain. Used to pay transaction fees and as the primary trading pair for tokens on LoomLay. ### SPL Token **Solana Program Library Token** - The standard token format on Solana, similar to ERC-20 on Ethereum. All tokens launched on LoomLay are SPL tokens. ### Transaction An on-chain operation that modifies blockchain state. Examples include transfers, swaps, and token launches. Solana transactions require a small fee paid in SOL. ### Wallet Software or hardware that stores your private keys and allows you to sign transactions. Popular Solana wallets include Phantom, Solflare, and Backpack. ### Private Key A secret cryptographic key that proves ownership of a wallet address. Never share your private key or seed phrase with anyone. ### Seed Phrase A 12 or 24-word recovery phrase that can restore access to a wallet. Also called a mnemonic or recovery phrase. ### Block A bundle of transactions processed together on the blockchain. Solana produces blocks approximately every 400 milliseconds. ### Confirmation When a transaction is included in a block and verified by the network. Solana transactions typically confirm in 1-2 seconds. --- ## DeFi Terms ### AMM **Automated Market Maker** - A system that uses mathematical formulas to set prices and enable trading without traditional order books. Trades execute against a liquidity pool. ### DAMM **Dynamic Automated Market Maker** - Meteora's implementation of an AMM with dynamic fees and concentrated liquidity. All LoomLay tokens trade on DAMM v2 pools. ### Liquidity Pool A collection of tokens locked in a smart contract that enables trading. Pools contain two tokens (like SOL and your token) that traders can swap between. ### Liquidity Provider (LP) Someone who deposits tokens into a liquidity pool. LPs earn a share of trading fees proportional to their contribution. ### Slippage The difference between the expected price of a trade and the actual executed price. Higher slippage can occur with large trades or low liquidity. ### Price Impact How much a trade affects the token's price. Large trades relative to pool liquidity cause higher price impact. ### Swap Exchanging one token for another through a liquidity pool. For example, swapping SOL for USDC. ### DEX **Decentralized Exchange** - A trading platform that operates without a central authority, using smart contracts to execute trades. Meteora is a Solana DEX. ### TVL **Total Value Locked** - The total value of assets deposited in a protocol or pool, usually measured in USD. --- ## LoomLay Terms ### Instant Launch A quick token deployment method that creates a token and liquidity pool in just 2 transactions. No approval needed, and tokens are immediately tradable. ### Curated Launch A vetted token launch that goes through an application process. Includes a 24-hour funding period and token vesting for participants. ### Alpha Vault Meteora's mechanism for whitelist-based token sales with built-in vesting. Used for the initial sale phase of curated launches. ### Fee Split The division of trading fees between the token creator and the LoomLay platform. For instant launches, this is **60% to the creator** and **40% to the platform**. ### Funding Period The 24-hour window during a curated launch when participants can deposit funds. Deposits outside this window are not accepted. ### Vesting A schedule that controls when tokens become available. Tokens vest gradually over time rather than all at once. ### Cliff The initial period of a vesting schedule during which no tokens are released. After the cliff ends, tokens begin unlocking. ### Linear Vesting A vesting method where tokens unlock at a constant rate over time. For example, 10% per month for 10 months. ### Discovery Feed The LoomLay interface for browsing and finding tokens. Shows trending tokens, new launches, and top gainers. --- ## Trading Terms ### Market Cap **Market Capitalization** - The total value of a token's circulating supply, calculated as price multiplied by circulating supply. ### Volume The total value of trades over a period, typically measured in 24 hours (24h volume). ### Order Book A list of buy and sell orders at different prices. Note: AMMs like Meteora don't use order books - they use liquidity pools instead. ### Limit Order An order to buy or sell at a specific price. Not natively supported by AMMs but can be implemented through specialized protocols. ### Market Order An order to buy or sell immediately at the current market price. All swaps on LoomLay are effectively market orders. --- ## Technical Terms ### RPC **Remote Procedure Call** - The interface used to communicate with blockchain nodes. RPC endpoints allow applications to read data and submit transactions. ### API **Application Programming Interface** - A set of rules for how software components interact. The LoomLay API enables programmatic access to platform features. ### SDK **Software Development Kit** - A collection of tools and code libraries for building applications. The OpenClawWallet SDK enables developers to integrate LoomLay features. ### Smart Contract Self-executing code deployed on a blockchain. On Solana, these are called "programs." LoomLay uses established Meteora programs rather than custom contracts. ### Mainnet The primary, production blockchain network where real assets have value. As opposed to testnet or devnet used for development. ### Gas A term from Ethereum for transaction fees. On Solana, the equivalent is simply called the "transaction fee" and is paid in SOL. --- # LoomLay Documentation > Everything you need to build on LoomLay URL: https://docs.loomlay.com/ # LoomLay Documentation Welcome to the LoomLay documentation. LoomLay is a Solana-based launchpad platform with an AI-friendly Agent API. **Build crypto-native applications without managing private keys.** LoomLay provides a complete infrastructure layer for creating wallets, executing trades, and launching tokens - all through a simple REST API. ## What Can You Build? | Use Case | Description | |----------|-------------| | **Trading Bots** | Automated trading strategies with swap and bridge support across Solana and EVM chains | | **Portfolio Trackers** | Real-time portfolio monitoring with unified balance views across multiple chains | | **Token Launchers** | Deploy tokens with instant liquidity pools on Meteora in just 2 transactions | | **AI Agents with Crypto Wallets** | Give your AI agents autonomous crypto capabilities with secure wallet management | ## Quick Start Install the SDK and create your first wallet: ```bash npm install @loomlay/openclaw-wallet-sdk ``` ```typescript import { OpenClawWallet } from '@loomlay/openclaw-wallet-sdk'; // Register and get API key const result = await OpenClawWallet.register(); // Initialize client const wallet = new OpenClawWallet({ apiKey: result.apiKey }); // Create multi-chain wallet const created = await wallet.wallet.create(); console.log(created.solana.address); // Solana address console.log(created.evm.address); // EVM address ``` ## What's Here | Section | Description | |---------|-------------| | [SDK Reference](/sdk) | TypeScript SDK for wallets, trading, and token launches | | [Platform Guide](/platform) | Understanding launches, fees, and discovery | | [API Reference](/api-reference) | Interactive REST API documentation | ## For AI Agents This documentation is designed to be AI-friendly: - **[llms.txt](/llms.txt)** - Structured overview for LLM assistants - **[llms-full.txt](/llms-full.txt)** - Complete documentation content - **[OpenAPI Spec](/openapi.json)** - Machine-readable API specification ## Get Started - New to LoomLay? Start with the [SDK Getting Started](/sdk/getting-started) guide - Want to launch a token? Read about [Instant Launches](/platform/instant-launches) - Building an AI agent? Jump to the [API Reference](/api-reference) --- # Curated Launches > Vetted token launches with funding periods and vesting URL: https://docs.loomlay.com/platform/curated-launches # Curated Launches Curated launches go through a vetting process and offer structured funding with vesting. ## Launch Phases 1. **Application** - Submit project details for review 2. **Approval** - LoomLay team reviews and approves 3. **Configuration** - Set pricing, allocation, and vesting terms 4. **Funding** - 24-hour period for participants to deposit 5. **Execution** - Pool deployment and token distribution 6. **Vesting** - Tokens released according to schedule ## Timeline Expectations | Phase | Typical Duration | Notes | |-------|------------------|-------| | **Application Review** | 2-5 business days | Depends on completeness of submission | | **Configuration** | 1-2 days | After approval, set your launch parameters | | **Funding Period** | 24 hours | Fixed window for participants to deposit | | **Execution** | Immediate | Automatically triggers after funding closes | | **Vesting** | Varies | Typically 1-12 months based on your configuration | The 24-hour funding window is fixed and cannot be extended. Plan your marketing and community outreach accordingly. ## Pool Structure Curated launches use Meteora's Alpha Vault for the initial sale: | Component | Purpose | |-----------|---------| | **Alpha Vault** | Whitelist-based token sale with vesting | | **DAMM Pool** | Secondary market liquidity after launch | ## Vesting Tokens purchased in curated launches vest over time: - **Cliff** - Initial lock period before any tokens release - **Linear** - Gradual release after cliff ends - **Full unlock** - All tokens available ### Example Vesting Schedule A typical 6-month vesting schedule with a 1-month cliff: | Time | Tokens Released | Cumulative | |------|-----------------|------------| | Day 0 | 0% | 0% | | Month 1 (cliff) | 20% | 20% | | Month 2 | 16% | 36% | | Month 3 | 16% | 52% | | Month 4 | 16% | 68% | | Month 5 | 16% | 84% | | Month 6 | 16% | 100% | Vesting schedules are locked at launch time and cannot be modified afterward. Choose your schedule carefully based on your tokenomics plan. ## Allocation Participants receive allocation based on: - Deposit amount - Pro-rata distribution if oversubscribed ### Oversubscription Example If a launch has a $100,000 cap and receives $200,000 in deposits: - Each participant receives 50% of their requested allocation - Excess funds are automatically refunded after execution ## What Happens If Funding Target Is Not Met If the minimum funding threshold is not reached during the 24-hour window: | Outcome | Description | |---------|-------------| | **Launch cancelled** | The curated launch does not proceed | | **Full refunds** | All deposited funds are returned to participants | | **No tokens minted** | The token is not created on-chain | | **Reapplication allowed** | You can submit a new application with adjusted parameters | Setting a realistic minimum funding target is crucial. Consider your community size and engagement levels when configuring this threshold. ## Requirements Projects must meet criteria: - Clear roadmap and documentation - Team verification (optional doxxing) - Technical audit (for smart contracts) - Marketing plan ## Application Tips To improve your chances of approval: ### Documentation - Provide a comprehensive whitepaper or project documentation - Include clear tokenomics with supply breakdown - Explain your token's utility and use cases ### Team - Highlight relevant experience of team members - LinkedIn profiles or verifiable credentials help - Consider KYC verification for faster approval ### Community - Show existing community engagement (Discord, Twitter) - Demonstrate organic growth, not just follower counts - Include any partnerships or integrations ### Technical - If your project involves smart contracts, have them audited - Open-source code repositories are viewed favorably - Provide testnet deployments if applicable Applications with incomplete information or unrealistic projections are typically rejected. Be thorough and realistic in your submission. ## Post-Launch Considerations After a successful curated launch: - **Liquidity management** - Monitor and potentially add liquidity as trading volume grows - **Community updates** - Keep participants informed about vesting unlocks - **Fee claiming** - Claim accumulated trading fees regularly - **Market making** - Consider active market making to maintain healthy order books --- # Discovery > Finding and exploring token launches URL: https://docs.loomlay.com/platform/discovery # Discovery LoomLay provides tools to discover and research token launches. ## Discovery Feed The main discovery page shows: - **Trending** - High-volume tokens - **New** - Recently launched - **Upcoming** - Curated launches in funding phase - **Your Portfolio** - Tokens you hold ## Filtering Filter launches by: | Filter | Options | |--------|---------| | **Type** | Instant, Curated | | **Status** | Live, Upcoming, Completed | | **Volume** | Min/max 24h volume | | **Liquidity** | Min pool liquidity | ## Token Pages Each token has a dedicated page showing: - **Chart** - Price and volume history - **Pool Info** - Liquidity, fees earned - **Holders** - Top token holders - **Transactions** - Recent trades - **Social** - Twitter, Telegram links ## Understanding Token Metrics When evaluating tokens, pay attention to these key metrics: ### Volume | Metric | What It Indicates | |--------|-------------------| | **24h Volume** | Recent trading activity level | | **Volume/Liquidity Ratio** | High ratio may indicate active speculation | | **Volume Trend** | Increasing volume suggests growing interest | Healthy tokens typically have consistent volume rather than isolated spikes. Look for sustained trading activity over multiple days. ### Liquidity | Depth | Implication | |-------|-------------| | **< $10,000** | High slippage likely on trades over $100 | | **$10,000 - $100,000** | Moderate liquidity, suitable for smaller trades | | **> $100,000** | Deep liquidity, can handle larger orders | ### Holders | Pattern | Interpretation | |---------|----------------| | **Top holder > 50%** | High concentration risk | | **Top 10 holders > 80%** | Limited distribution | | **Balanced distribution** | Healthier token economics | High concentration in few wallets increases the risk of large price movements if major holders sell. Check holder distribution before investing. ## Safety Indicators in Token Search When searching for tokens via the API, the response includes safety indicators: | Indicator | Description | |-----------|-------------| | **Verified** | Token metadata has been validated | | **Liquidity locked** | Pool liquidity cannot be withdrawn | | **Mint authority** | Whether new tokens can be minted | | **Freeze authority** | Whether transfers can be frozen | ### Interpreting Authority Flags ```typescript const results = await wallet.tokens.search({ query: 'example', chain: 'solana', }); // Check safety indicators results.forEach(token => { if (token.mintAuthority === null) { // Supply is fixed - no new tokens can be created } if (token.freezeAuthority === null) { // Transfers cannot be frozen } }); ``` Tokens with active mint authority can have their supply increased at any time by the authority holder. This is a significant risk factor. ## API Access Query discovery data via the Agent API: ```typescript // Get trending tokens const trending = await wallet.dex.trending({ chain: 'solana', limit: 10, }); // Search tokens const results = await wallet.tokens.search({ query: 'meme', chain: 'solana', }); ``` ## Real-time Updates Subscribe to live updates via WebSocket: ```typescript const dexWs = wallet.createDexWebSocket(); await dexWs.connect(); dexWs.subscribe( { chain: 'solana', minLiquidity: 10000 }, (pairs) => console.log('Updated pairs:', pairs) ); ``` ### How Real-time Updates Work The WebSocket connection provides: | Update Type | Frequency | Data Included | |-------------|-----------|---------------| | **Price updates** | Every trade | Current price, 24h change | | **Volume updates** | Aggregated | Rolling 24h volume | | **New pairs** | As they launch | Full pair metadata | | **Liquidity changes** | On deposit/withdraw | Updated liquidity depth | WebSocket subscriptions filter server-side based on your criteria (minimum liquidity, chain, etc.). This reduces bandwidth and processing on your end. ### Connection Management ```typescript // Handle disconnections gracefully dexWs.on('disconnect', () => { console.log('Disconnected, attempting reconnect...'); }); dexWs.on('reconnect', () => { // Resubscribe after reconnection dexWs.subscribe( { chain: 'solana', minLiquidity: 10000 }, handlePairs ); }); // Clean up when done dexWs.disconnect(); ``` ## Best Practices for Discovery 1. **Combine filters** - Use multiple criteria to narrow down quality tokens 2. **Check history** - Look at trading patterns over days, not just hours 3. **Verify socials** - Check that linked social accounts are active and legitimate 4. **Monitor changes** - Use WebSocket subscriptions to track tokens you're interested in 5. **Research the team** - For curated launches, review the project's application materials --- # FAQ > Frequently asked questions about the LoomLay platform URL: https://docs.loomlay.com/platform/faq # Frequently Asked Questions ## Launches ### What's the difference between Instant and Curated launches? **Instant launches** let you deploy a token immediately with just 2 transactions. No approval is needed, and your token is tradable as soon as the transactions confirm. Best for quick launches, memecoins, and community tokens. **Curated launches** go through an application and approval process. They include a 24-hour funding period and vesting schedules. Best for serious projects looking for structured funding and credibility. | Feature | Instant | Curated | |---------|---------|---------| | Approval needed | No | Yes | | Time to launch | Minutes | Days to weeks | | Funding period | None | 24 hours | | Vesting | No | Yes | | Best for | Quick launches | Larger projects | ### How long does the funding period last for Curated launches? The funding period is exactly **24 hours**. During this window, participants can deposit funds to participate in the launch. After the period ends, no additional deposits are accepted. ### What happens if a Curated launch doesn't reach its funding target? If a curated launch doesn't reach its minimum funding target: - All deposited funds are returned to participants - The launch is cancelled - Participants can claim their refunds through the platform ### Can I launch more than one token? **Instant launches**: Yes, you can launch multiple tokens from the same wallet. **API/SDK launches**: Limited to one token per API key account. ### What information do I need to launch a token? For an instant launch, you need: - Token name and symbol - Description - Token image (square, minimum 400x400px) - Total supply amount - Initial liquidity amount (in SOL) --- ## Fees ### How does the 60/40 fee split work? For instant launches, trading fees from the Meteora pool are split: | Recipient | Share | |-----------|-------| | Token Creator | 60% | | LoomLay Platform | 40% | Fees accumulate from every swap on your token's pool and can be claimed at any time. ### How do I claim my fees as a token creator? You can claim fees through: 1. **Platform Dashboard**: Navigate to your dashboard, view pending fees, and click "Claim" 2. **SDK/API**: Use the fees endpoint to check pending amounts and claim Fees are paid out in SOL to the wallet that created the token. ### Are there upfront fees for launching? **Instant launches**: Yes, there's a platform fee paid during the launch transaction. The exact amount depends on your configuration. **Curated launches**: Fees are negotiated during the application process and may include listing fees and success fees based on funds raised. ### When do fees start accumulating? Fees begin accumulating as soon as trading starts on your token's pool. For instant launches, this is immediately after the launch transactions confirm. --- ## Trading ### Where does liquidity come from? All LoomLay tokens trade on **Meteora DAMM v2** pools on Solana. Liquidity is provided by: - Initial liquidity from the token creator (instant launches) - Funds raised during the funding period (curated launches) - Additional liquidity providers who add to the pool ### Is my token immediately tradable after an Instant launch? Yes. As soon as both launch transactions confirm on Solana (typically within seconds), your token is live and tradable on Meteora DEX. ### What is slippage and how do I set it? Slippage is the difference between the expected price and the actual execution price. Higher trading volume or lower liquidity can cause more slippage. - **Recommended**: 0.5-1% for most trades - **High volatility**: 2-5% may be needed - **Low liquidity tokens**: May require higher slippage ### Can I trade LoomLay tokens on other platforms? Yes. Since all tokens use standard SPL token accounts and Meteora pools, you can trade them on: - Meteora DEX directly - Jupiter aggregator - Any Solana DEX that routes through Meteora --- ## Wallets and Security ### Which wallets are supported? LoomLay supports all major Solana wallets: - Phantom - Solflare - Backpack - Ledger (via Phantom or Solflare) ### Is my wallet safe when connecting to LoomLay? LoomLay uses standard Solana wallet adapter connections. We never have access to your private keys or seed phrase. Each transaction requires your explicit approval in your wallet. ### What happens if I lose access to my wallet? LoomLay cannot recover wallet access. If you lose access to your wallet: - Holdings remain on-chain and are recoverable with your seed phrase - Fee claims are tied to the creator wallet address - Contact your wallet provider's support for recovery options --- ## Vesting (Curated Launches) ### How does vesting work? Tokens purchased in curated launches are released gradually: 1. **Cliff**: Initial period where no tokens are released 2. **Linear vesting**: Tokens unlock progressively after the cliff 3. **Full unlock**: All remaining tokens become available ### Can I trade vested tokens before they unlock? No. Tokens remain locked until they vest according to the schedule. Once unlocked, they're transferred to your wallet and can be traded freely. ### Where do I see my vesting schedule? Check your dashboard under **Holdings** to see: - Total tokens allocated - Tokens already unlocked - Next unlock date and amount - Full vesting schedule --- ## Technical ### What blockchain does LoomLay use? LoomLay is built on **Solana**. All tokens are SPL tokens, and all liquidity pools use Meteora DAMM v2. ### What is Meteora DAMM v2? Meteora's Dynamic Automated Market Maker (DAMM) v2 is a liquidity pool implementation that offers: - Concentrated liquidity for better price execution - Dynamic fees that adjust to market conditions - Single-sided deposits for token launches ### How fast are transactions? Solana transactions typically confirm in **1-2 seconds**. You'll see your trades and launches execute almost instantly. ### What are the transaction fees? Solana network fees are minimal (typically less than $0.01 per transaction). LoomLay platform fees are separate and vary by launch type. --- # Fees > Understanding LoomLay's fee structure URL: https://docs.loomlay.com/platform/fees # Fees ## Fee Structure ### Instant Launches | Fee Type | Amount | Split | |----------|--------|-------| | Platform Fee | Variable | 40% platform, 60% creator | | Trading Fee | 1% | From pool swaps | ### Curated Launches | Fee Type | Amount | Description | |----------|--------|-------------| | Listing Fee | Negotiated | One-time fee for launch | | Success Fee | % of raise | Percentage of funds raised | ## Fee Claiming Creators can claim fees through the platform or API: ```typescript // Check pending fees const pending = await wallet.fees.getPending(); // Claim all pending fees const claim = await wallet.fees.claim(); ``` --- # Getting Started > Start using the LoomLay platform URL: https://docs.loomlay.com/platform/getting-started # Getting Started This guide helps you get started with the LoomLay web platform. If you're a developer looking to integrate with the SDK, see the [SDK Getting Started](/sdk/getting-started) guide instead. ## Connect Your Wallet To use LoomLay, you need a Solana wallet. ### Supported Wallets | Wallet | Platform | Notes | |--------|----------|-------| | **Phantom** | Browser, Mobile | Most popular Solana wallet | | **Solflare** | Browser, Mobile | Feature-rich with staking | | **Backpack** | Browser | Multi-chain support | | **Ledger** | Hardware | Connect via Phantom or Solflare | ### How to Connect 1. Click **Connect Wallet** in the top navigation 2. Select your wallet from the list 3. Approve the connection in your wallet 4. Your wallet address will appear in the navigation Make sure you have some SOL in your wallet for transaction fees before participating in launches. ## Explore Tokens LoomLay's discovery feed helps you find tokens launched on the platform. ### Using the Discovery Feed - **Trending** - Tokens with the highest recent trading volume - **New** - Recently launched tokens - **Gainers** - Tokens with the largest price increases ### Understanding Token Metrics | Metric | Description | |--------|-------------| | **Market Cap** | Total value of circulating supply | | **24h Volume** | Trading volume in the last 24 hours | | **Liquidity** | Amount of assets in the trading pool | | **Price Change** | Percentage change over selected period | ### Finding New Launches - Check the **Upcoming** section for curated launches accepting deposits - Browse **Recently Launched** for the newest instant launches - Use filters to narrow by date, volume, or price change ## Participate in Launches ### Instant Launches Instant launches are immediately tradable: 1. Find a token on the discovery page 2. Click **Trade** to open the swap interface 3. Enter the amount of SOL to swap 4. Review the transaction details and confirm 5. Approve the transaction in your wallet ### Curated Launches Curated launches have a structured funding period: 1. Find an upcoming curated launch 2. Review the project details, vesting schedule, and terms 3. Click **Deposit** during the 24-hour funding window 4. Enter your deposit amount 5. Confirm the transaction in your wallet 6. Receive tokens according to the vesting schedule after launch Curated launches have a fixed 24-hour funding period. Deposits made outside this window are not accepted. ## Launch Your Own Token ### Instant Launch Deploy a token in seconds: 1. Click **Launch** in the navigation 2. Select **Instant Launch** 3. Fill in token details: - Name and symbol - Description and image - Initial liquidity amount (in SOL) - Total supply 4. Review the fees and confirm 5. Approve two transactions in your wallet 6. Your token is live and tradable immediately ### Curated Launch Application For larger projects seeking vetting and structured funding: 1. Click **Launch** in the navigation 2. Select **Apply for Curated Launch** 3. Complete the application: - Project overview and roadmap - Team information - Tokenomics and allocation - Funding goals 4. Submit for review 5. The LoomLay team will contact you with next steps ## Dashboard After launching a token or participating in launches, use your dashboard to: - **View Holdings** - See tokens you've purchased - **Track Launches** - Monitor your launched tokens - **Claim Fees** - Collect your share of trading fees (for creators) - **Vesting Schedule** - Track upcoming token unlocks ## Next Steps - [Instant Launches](/platform/instant-launches) - Deep dive into instant launches - [Curated Launches](/platform/curated-launches) - Learn about vetted launches - [Fees](/platform/fees) - Understand the fee structure - [Discovery](/platform/discovery) - Explore the token discovery feed - [FAQ](/platform/faq) - Common questions answered --- # Platform Overview > Launch tokens and participate in token sales on Solana URL: https://docs.loomlay.com/platform # Platform Overview LoomLay is a Solana-based launchpad that offers two ways to launch tokens, both powered by Meteora's battle-tested liquidity infrastructure. ## Why LoomLay? - **No smart contract development** - Launch tokens using established Meteora pools without writing or auditing custom programs - **Instant liquidity** - Tokens are immediately tradable on Meteora DEX after launch - **Built-in fee sharing** - Earn from trading volume on your token's pool - **AI-agent ready** - Full API access for automated launches and trading ## Launch Types | Type | Speed | Pool | Best For | |------|-------|------|----------| | **Instant** | 2 transactions | Single-sided DAMM | Quick launches, memecoins | | **Curated** | 24h funding period | Alpha Vault + DAMM | Serious projects, larger raises | ## How It Works **Instant Launch** - Deploy a token and liquidity pool in seconds. No approval needed. Pay fees upfront and your token is immediately tradable on Meteora. **Curated Launch** - Go through a vetting process with structured funding and vesting. Apply, get approved, configure your sale, and launch with whitelist-based allocation. ## Meteora DAMM v2 All LoomLay tokens trade on Meteora's Dynamic Automated Market Maker (DAMM) v2 pools: | Feature | Benefit | |---------|---------| | **Concentrated liquidity** | Better price execution with less capital | | **Dynamic fees** | Fees adjust based on market volatility | | **Single-sided deposits** | Launch with just SOL - no need to pre-mint tokens | | **Built-in analytics** | Track volume, fees, and liquidity in real-time | Meteora DAMM pools are the same infrastructure used by major Solana projects. Your token benefits from Meteora's established ecosystem and trading interfaces. ## Key Features | Feature | Description | |---------|-------------| | **Meteora Integration** | All pools deployed on Meteora DAMM v2 | | **Fee Sharing** | 60/40 creator/platform split on instant launches | | **Automated Market Making** | Liquidity managed by battle-tested Meteora contracts | | **Multi-chain Wallets** | Trade across Solana and EVM chains via the Agent API | ## Quick Links - [Getting Started](/platform/getting-started) - Connect your wallet and start using the platform - [Instant Launches](/platform/instant-launches) - Deploy in seconds - [Curated Launches](/platform/curated-launches) - Vetted launches with vesting - [Fees](/platform/fees) - Fee structure - [Discovery](/platform/discovery) - Find and explore launches - [FAQ](/platform/faq) - Frequently asked questions --- # Instant Launches > Deploy a token and liquidity pool in seconds URL: https://docs.loomlay.com/platform/instant-launches # Instant Launches Instant launches let you deploy a token and liquidity pool in just 2 transactions. ## How It Works 1. **Configure** - Set token name, symbol, supply, and initial liquidity 2. **Pay Fees** - Platform fee collected upfront 3. **Deploy** - Two transactions create token and pool 4. **Trade** - Immediately tradable on Meteora ## The Two Transactions When you execute an instant launch, two on-chain transactions are submitted: ### Transaction 1: Token Creation - Creates the SPL token with your specified supply - Sets token metadata (name, symbol, image URI) - Mints the total supply to a holding account - Establishes the token's mint authority ### Transaction 2: Pool Deployment - Creates a Meteora DAMM v2 pool - Deposits your SOL as initial liquidity - Adds tokens to the pool at the configured ratio - Enables trading immediately upon confirmation Both transactions must succeed for the launch to complete. If the first transaction succeeds but the second fails, no pool is created and no funds are locked. ## SOL Requirements Before launching, ensure your wallet has sufficient SOL: | Cost | Amount | Purpose | |------|--------|---------| | **Initial Liquidity** | Your chosen amount | Deposited into the pool | | **Transaction Fees** | ~0.01 SOL | Solana network fees | | **Account Rent** | ~0.03 SOL | Token and pool account creation | | **Platform Fee** | Varies | See [Fees](/platform/fees) | We recommend having at least your liquidity amount plus 0.05 SOL to cover all fees and account creation costs. ## What You Get After Launch After a successful launch, you receive: | Output | Description | |--------|-------------| | **Token Address** | The SPL token mint address for your new token | | **Pool Address** | The Meteora DAMM pool where your token trades | | **Trading URL** | Direct link to trade on Meteora | Your token is immediately: - Tradable on Meteora DEX - Visible on Solana explorers (Solscan, SolanaFM) - Discoverable via the LoomLay discovery feed - Generating trading fees for you to claim ## Fee Structure Instant launches use a 60/40 fee split: | Recipient | Share | Description | |-----------|-------|-------------| | Creator | 60% | Token creator revenue | | Platform | 40% | LoomLay platform fee | Fees are collected from trading volume on the pool. ## Code Example ```typescript // Using the Agent API to create an instant launch const launch = await wallet.tokenize.launch({ name: 'My Token', symbol: 'MTK', description: 'A sample token', initialLiquidity: '10', // SOL supply: '1000000000', }); console.log('Token address:', launch.tokenAddress); console.log('Pool address:', launch.poolAddress); ``` ## Requirements - Wallet with sufficient SOL for fees and liquidity - Unique token name and symbol - Valid token metadata (image, description) ## Fee Claiming Creators can claim accumulated fees at any time: ```typescript const fees = await wallet.fees.getPending(); console.log('Pending fees:', fees.pendingAmount); const claim = await wallet.fees.claim(); console.log('Claimed:', claim.claimedAmount); ``` ## Common Issues ### "Insufficient balance" Your wallet does not have enough SOL. Ensure you have your liquidity amount plus at least 0.05 SOL for fees. ### "Transaction simulation failed" This usually indicates a network congestion issue. Wait a few seconds and retry the launch. ### "Token name already exists" Choose a different token name. While symbols can be reused, having a unique name helps with discoverability. ### "Metadata upload failed" Check that your image URL is accessible and returns a valid image. IPFS and Arweave links are recommended for permanence. Instant launches cannot be reversed. Once deployed, the token and pool exist permanently on Solana. Double-check all parameters before confirming. --- # AI Agent Best Practices > Guidelines for building safe and effective AI agents with the OpenClaw Wallet SDK URL: https://docs.loomlay.com/sdk/ai-agent-guide # AI Agent Best Practices This guide covers best practices for developers building AI agents that interact with wallets, execute trades, and manage digital assets using the OpenClaw Wallet SDK. ## Introduction AI agents operating with real financial assets require careful design. Unlike traditional software, agents make autonomous decisions that can result in irreversible transactions. This guide establishes patterns for building agents that are: - **Safe** - Verify before executing, handle errors gracefully - **Transparent** - Explain actions in plain language - **Deliberate** - Require confirmation for significant operations - **Secure** - Protect credentials and never expose sensitive data ## Core Workflow Every agent operation should follow this six-phase workflow: ``` 1. AUTHENTICATE → 2. UNDERSTAND → 3. VALIDATE → 4. EXECUTE → 5. VERIFY → 6. DOCUMENT │ │ │ │ │ │ │ │ │ │ │ └─ Summarize result │ │ │ │ └─ Confirm success │ │ │ └─ Execute with user approval │ │ └─ Get quotes, check balances │ └─ Clarify what user wants └─ Ensure API key is configured ``` ### Phase 1: Authenticate Before any operation, verify you have a valid API key and wallet access: ```typescript import { OpenClawWallet } from '@loomlay/openclaw-wallet-sdk'; // Self-custody mode (recommended) — keys stay on your device const client = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY, walletMode: 'local', getPassphrase: async () => process.env.LOOMLAY_WALLET_PASSPHRASE!, }); ``` If no API key exists, register for one (rate limited to 1 per IP): ```typescript const { apiKey } = await OpenClawWallet.register(); // Store this securely - it's your identity ``` In self-custody mode, the agent needs a passphrase to sign transactions. Set `LOOMLAY_WALLET_PASSPHRASE` as an environment variable so it doesn't appear in conversation logs. ### Phase 2: Understand Clarify user intent before taking action: **For trading requests:** - Which tokens? (resolve names to addresses if needed) - How much? (decimal, USD, percentage, or max?) - Which chain? (Solana by default, or EVM chains) **For research requests:** - What metric matters? (volume, price change, liquidity) - What timeframe? (5m, 1h, 6h, 24h) - What filters? (minimum liquidity, safety score) ### Phase 3: Validate Always validate before executing: ```typescript // Get a quote first const quote = await client.trading.getSwapQuote({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100' }); // Show the user what they'll receive // "You'll swap ~1.2 SOL for ~$99.50 USDC (0.5% price impact)" ``` ### Phase 4: Execute Only execute after user confirmation: ```typescript const result = await client.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100' }); ``` ### Phase 5: Verify Confirm the result: ```typescript const wallet = await client.wallet.get(); // Check new balance reflects the expected change ``` ### Phase 6: Document Summarize what happened: - What was executed - Transaction hash (if applicable) - New balances - Any follow-up actions needed ## Security Guidelines ### Self-Custody Security In self-custody mode, the agent handles real cryptographic operations locally: **Critical Security Rules:** - **Seed phrase shown once** - `wallet.create()` returns the seed phrase exactly once - **Never log secrets** - Do not include seed phrases, passphrases, or private keys in output - **Passphrase via env var** - Use `LOOMLAY_WALLET_PASSPHRASE` to avoid conversation logs - **Keys never transmitted** - Only public addresses and signed transactions leave the device ```typescript // Self-custody wallet creation const { seedPhrase, wallet } = await client.wallet.create(); // Tell user: "Your seed phrase is shown once. Store it securely offline." // Tell user: "Your keys are encrypted on this device at ~/.loomlay/wallet.json" // NEVER do this: // - console.log(seedPhrase) // - store in database // - send to analytics // - include in error reports ``` ### Seed Phrase Handling The seed phrase is the master key to all funds. Handle with extreme care: When users create a wallet, guide them: ``` Your seed phrase (SAVE THIS NOW): word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12 This phrase is your master key to all funds. - Write it down on paper - Store in a secure location - Never share with anyone - If lost, funds are unrecoverable ``` ### Transaction Safety 1. **Always quote first** - Never execute without showing expected outcome 2. **Verify addresses** - Transfers are irreversible 3. **Check slippage** - High price impact indicates a bad trade 4. **Confirm large amounts** - Extra verification for significant value ```typescript // Get quote with price impact const quote = await client.trading.getSwapQuote({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', }); // Warn on high price impact if (quote.priceImpact > 2) { // "Warning: 3.5% price impact. Consider a smaller trade." } // Only execute after user confirms const result = await client.trading.swap({...}); ``` ### API Key Security **API Key Best Practices:** - Store in environment variables, never hardcode - One key per agent/application - Revoke immediately if compromised ```typescript // Good: Load from environment const client = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, }); // Bad: Hardcoded key const client = new OpenClawWallet({ apiKey: 'agent_abc123...', // Never do this! }); ``` ## Quality Gate Checklist Before executing any transaction, verify these conditions: ### Safety Checks - [ ] User explicitly requested this action - [ ] Quote shown and confirmed for trades - [ ] Address validated for transfers - [ ] Sufficient balance confirmed - [ ] Slippage/price impact acceptable ### Information Provided - [ ] Expected outcome explained - [ ] Fees/costs disclosed - [ ] Risks mentioned if applicable - [ ] Transaction hash provided after execution ### Never Do - [ ] Execute without user confirmation - [ ] Log or display seed phrases - [ ] Assume token addresses (search first) - [ ] Ignore error responses - [ ] Skip quote step for trades ## Standardized Response Format All SDK operations return a consistent response format for predictable error handling: ```typescript interface ToolResponse { success: boolean; data?: T; error?: { message: string; code?: string; retryAfter?: number; }; } ``` ### Success Response ```typescript { success: true, data: { txHash: "abc123...", outputAmount: "99.50", // ... operation-specific data } } ``` ### Error Response ```typescript { success: false, error: { message: "Rate limited. Retry after 30 seconds.", code: "RATE_LIMITED", retryAfter: 30 } } ``` ### Using the Response Format ```typescript import { executeTool } from '@loomlay/openclaw-wallet-sdk'; const response = await executeTool(() => client.trading.swap(params)); if (response.success) { // Handle success console.log('Swap completed:', response.data); } else { // Handle error console.log('Swap failed:', response.error?.message); } ``` ## Error Handling Patterns ### Error Types ```typescript import { RateLimitError, ApiError, NetworkError, TimeoutError, ValidationError, } from '@loomlay/openclaw-wallet-sdk'; ``` ### Recovery Strategies | Error Type | Retry? | Strategy | |------------|--------|----------| | `RateLimitError` | Yes | Wait for `retryAfter` seconds, then retry | | `NetworkError` | Yes | Exponential backoff (1s, 2s, 4s), max 3 attempts | | `TimeoutError` | Maybe | Check operation status first, retry if not confirmed | | `ApiError` (4xx) | No | Fix input parameters before retrying | | `ApiError` (5xx) | Yes | Retry with exponential backoff | | `ValidationError` | No | Fix validation issues before retrying | ### Rate Limit Handling ```typescript async function withRateLimitRetry(fn: () => Promise): Promise { try { return await fn(); } catch (error) { if (error instanceof RateLimitError && error.retryAfter) { console.log(`Rate limited. Waiting ${error.retryAfter}s...`); await sleep(error.retryAfter * 1000); return await fn(); } throw error; } } ``` ### Exponential Backoff ```typescript async function withExponentialBackoff( fn: () => Promise, maxAttempts = 3, baseDelayMs = 1000 ): Promise { let lastError: Error; for (let attempt = 0; attempt < maxAttempts; attempt++) { try { return await fn(); } catch (error) { lastError = error as Error; if (error instanceof ApiError && error.status < 500) { throw error; // Don't retry client errors } if (attempt < maxAttempts - 1) { const delay = baseDelayMs * Math.pow(2, attempt); await sleep(delay); } } } throw lastError!; } ``` ### Transaction Safety Pattern For operations that might be partially complete: ```typescript async function safeSwap(params: SwapParams) { // 1. Get quote first const quote = await client.trading.getSwapQuote(params); // 2. Confirm with user if (!userConfirms(quote)) return null; try { // 3. Execute return await client.trading.swap(params); } catch (error) { if (error instanceof TimeoutError) { // Transaction might have succeeded - check balance const wallet = await client.wallet.get(); return { status: 'unknown', wallet }; } throw error; } } ``` ### User-Friendly Error Messages Transform technical errors into understandable messages: ```typescript function getUserMessage(error: unknown): string { if (error instanceof RateLimitError) { return `Too many requests. Please wait ${error.retryAfter} seconds.`; } if (error instanceof ApiError) { switch (error.code) { case 'UNAUTHORIZED': return 'Authentication failed. Please check your API key.'; case 'INSUFFICIENT_FUNDS': return 'Not enough balance to complete this transaction.'; case 'SLIPPAGE_EXCEEDED': return 'Price moved too much. Try again with higher slippage.'; default: return error.message; } } if (error instanceof NetworkError) { return 'Network connection failed. Please check your internet.'; } return 'An unexpected error occurred.'; } ``` ## Skill Documentation Structure The SDK includes a skill system for AI agents, organized as follows: ### Main Skill File `SKILL.md` - The primary instruction file containing: - Agent philosophy and approach - Core workflow phases - Security guidelines - Quick reference tables - Quality gate checklist ### Reference Guides Detailed documentation for specific capabilities: | Reference | Description | |-----------|-------------| | `wallet-operations.md` | Wallet creation, security, key export | | `trading-guide.md` | Swaps, transfers, bridges with amount formats | | `market-analysis.md` | DEX data, trending tokens, filtering | | `token-launch.md` | Tokenize workflow, tiers, fee structure | | `error-handling.md` | Error types, recovery patterns, retries | | `amount-formats.md` | Flexible amounts (decimal, USD, %, max) | | `chain-reference.md` | Supported chains and behaviors | ### Workflow Playbooks Step-by-step guides for common scenarios: | Workflow | Description | |----------|-------------| | `first-time-setup.md` | Registration, wallet creation, first trade | | `token-launch-playbook.md` | Complete token launch guide | ## Amount Formats The SDK supports flexible amount specifications: | Format | Example | Use Case | |--------|---------|----------| | Decimal | `"1.5"` | Exact amount | | USD | `"$100"` | Dollar value (auto-converts) | | Percentage | `"50%"` | Half of balance | | Max | `"max"` | Entire balance | ```typescript // All valid: await client.trading.swap({ amount: '1.5', ... }); // 1.5 tokens await client.trading.swap({ amount: '$100', ... }); // $100 worth await client.trading.swap({ amount: '50%', ... }); // Half balance await client.trading.swap({ amount: 'max', ... }); // Full balance ``` ## Best Practices Summary 1. **Verify before executing** - Always get quotes and show expected outcomes 2. **Explain in plain language** - Users should understand what's happening 3. **Surface relevant data** - Provide market context for informed decisions 4. **Handle errors gracefully** - Clear recovery paths for all failures 5. **Protect sensitive data** - Never expose seed phrases or API keys 6. **Confirm significant actions** - Extra verification for large transactions 7. **Document outcomes** - Summarize results with transaction details ## Related Documentation - [Getting Started](/sdk/getting-started) - Set up the SDK - [Security Best Practices](/sdk/security) - Detailed security guidelines - [Error Handling](/sdk/error-handling) - Complete error reference - [Trading](/sdk/trading) - Swaps, transfers, and bridges - [Tokenize](/sdk/tokenize) - Launch your own token --- # Amount Formats > Flexible amount input formats for swaps, transfers, and bridges URL: https://docs.loomlay.com/sdk/amount-formats # Amount Formats The SDK supports multiple amount formats for intuitive trading. Instead of always specifying exact token amounts, you can use USD values, percentages, or max/all keywords. ## Overview | Format | Example | Description | |--------|---------|-------------| | Decimal | `"1.5"` | Exact token amount | | USD | `"$100"` or `"100usd"` | Dollar value at current price | | Percentage | `"50%"` | Percentage of wallet balance | | Max | `"max"` or `"all"` | Entire available balance | ## Decimal Amounts The most precise format - specify exactly how many tokens to use. ```typescript // Swap exactly 1.5 SOL await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1.5', }); // Transfer exactly 0.01 ETH await wallet.trading.transfer({ to: '0x...', token: 'ETH', amount: '0.01', chain: 'ethereum', }); ``` ### Precision Notes - Respects token decimals (SOL: 9, USDC: 6, ETH: 18) - Excess precision is truncated, not rounded - Always use strings to avoid floating-point issues ```typescript // Good - use strings amount: '0.123456789' // Avoid - numbers may lose precision amount: 0.123456789 ``` ## USD Amounts Specify value in US dollars - automatically converted at the current market price. ```typescript // Swap $100 worth of SOL await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100', }); // Alternative suffix format await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100usd', }); ``` ### How USD Conversion Works 1. Fetch current token price from market data 2. Calculate token amount: `tokenAmount = usdAmount / price` 3. Execute with the calculated token amount ``` User request: "$100 of SOL" SOL price: $150 Calculation: $100 / $150 = 0.667 SOL Executed: Swap 0.667 SOL ``` ### USD Format Variants All of these are equivalent: - `"$100"` - Dollar sign prefix - `"$100.00"` - With cents - `"100usd"` - Lowercase suffix - `"100USD"` - Uppercase suffix **Price Volatility:** USD amounts convert at the moment of execution. For volatile tokens, the actual token amount may differ from what you expect. Use `quoteOnly: true` to preview the conversion before executing. ## Percentage Amounts Swap or transfer a percentage of your current balance. ```typescript // Swap half of SOL balance await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '50%', }); // Transfer 25% of USDC holdings await wallet.trading.transfer({ to: 'recipient_address', token: 'USDC', amount: '25%', chain: 'solana', }); ``` ### How Percentage Works 1. Fetch current balance of the input token 2. Calculate amount: `amount = balance * (percentage / 100)` 3. Execute with the calculated amount ``` User request: "50% of SOL" SOL balance: 10 SOL Calculation: 10 x 0.5 = 5 SOL Executed: Swap 5 SOL ``` ### Percentage Considerations - Based on balance at execution time - For native tokens (SOL/ETH), a gas buffer is reserved - `"100%"` is equivalent to `"max"` ## Max/All Amounts Swap or transfer your entire balance of a token. ```typescript // Swap all SOL await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: 'max', }); // Alternative keyword await wallet.trading.swap({ inputToken: 'BONK', outputToken: 'SOL', amount: 'all', }); ``` ### Gas Buffer for Native Tokens When using "max" with native tokens (SOL, ETH), a small buffer is reserved for transaction fees: | Chain | Native Token | Gas Buffer | |-------|--------------|------------| | Solana | SOL | ~0.001 SOL | | Ethereum | ETH | ~0.01 ETH | | Base | ETH | ~0.001 ETH | | Arbitrum | ETH | ~0.001 ETH | For non-native tokens (USDC, BONK, etc.), "max" uses the full balance with no buffer. ### Max Format Variants All of these are equivalent: - `"max"` - Lowercase - `"MAX"` - Uppercase - `"all"` - Alternative keyword - `"ALL"` - Uppercase alternative ## Endpoint Support | Endpoint | Decimal | USD | Percentage | Max | |----------|---------|-----|------------|-----| | `trading.swap()` | Yes | Yes | Yes | Yes | | `trading.transfer()` | Yes | Yes | Yes | Yes | | `trading.bridge()` | Yes | Yes | Yes | Yes | | Quote operations | Yes | Yes | Yes | Yes | All trading operations support all amount formats. ## Edge Cases and Considerations ### Dust Amounts Very small amounts may fail due to minimum transaction requirements: ```typescript // May fail - amount too small await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '0.000001', // Dust amount }); ``` Different DEXes have different minimum trade sizes. Jupiter on Solana typically requires at least ~$0.01 worth of tokens. ### Rounding Behavior - Amounts are truncated to the token's decimal precision, not rounded - For example, `"1.123456789123"` SOL becomes `"1.123456789"` (9 decimals) - USD conversions may result in slight differences from the requested dollar amount ### Insufficient Balance If the calculated amount exceeds your balance: ```typescript // Balance: 5 SOL, requesting $1000 worth await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$1000', // More than balance }); // Throws InsufficientFundsError ``` ## Format Selection Guide | Scenario | Recommended Format | Example | |----------|-------------------|---------| | Precise trade amount | Decimal | `"1.5"` | | "I want to spend $100" | USD | `"$100"` | | "Sell half my position" | Percentage | `"50%"` | | "Exit entire position" | Max | `"max"` | | DCA fixed dollar amount | USD | `"$50"` | | Portfolio rebalancing | Percentage | `"25%"` | ## Best Practices ### Always Preview with Quotes Get a quote first to see the actual amounts before executing: ```typescript // Preview the swap const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100', quoteOnly: true, }); console.log(`Will swap ${quote.inputAmount} SOL for ~${quote.outputAmount} USDC`); // Then execute const result = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100', }); ``` ### Confirm Large Operations For max or high percentage amounts, always confirm with the user: ```typescript const info = await wallet.wallet.get(); const solBalance = info.balances.solana.native; // Show user what "max" means console.log(`This will swap your entire balance of ${solBalance} SOL`); // Then execute after confirmation await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: 'max', }); ``` ### Use Strings for Precision Always pass amounts as strings to avoid JavaScript floating-point issues: ```typescript // Correct amount: '0.1' // Avoid - may have precision issues amount: 0.1 amount: String(0.1) ``` ## Error Cases | Input | Error | |-------|-------| | `"0"` | Zero amount not allowed | | `"-1"` | Negative amounts not allowed | | `"101%"` | Percentage over 100% not allowed | | `"abc"` | Invalid format | | `""` | Empty amount not allowed | | `"$"` | Missing value after dollar sign | ## Type Definition ```typescript type FlexibleAmount = string; // Valid patterns: // /^\d+\.?\d*$/ - Decimal (1.5, 100) // /^\$\d+\.?\d*$/ - USD prefix ($100, $100.50) // /^\d+\.?\d*usd$/i - USD suffix (100usd, 100USD) // /^\d+\.?\d*%$/ - Percentage (50%, 100%) // /^(max|all)$/i - Max (max, MAX, all, ALL) ``` --- # Supported Chains > Blockchain networks supported by the SDK URL: https://docs.loomlay.com/sdk/chains # Supported Chains The SDK supports multiple blockchain networks through a unified interface. ## Chain Overview | Chain | Type | Native Token | Chain ID | Swap | Transfer | Bridge | |-------|------|--------------|----------|------|----------|--------| | Solana | Non-EVM | SOL | - | Yes | Yes | No | | Ethereum | EVM | ETH | 1 | Yes | Yes | Yes | | Base | EVM | ETH | 8453 | Yes | Yes | Yes | | Arbitrum | EVM | ETH | 42161 | Yes | Yes | Yes | ## Chain Details ### Solana Full trading support via Jupiter aggregator. ```typescript // Swap on Solana (default chain) await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1', }); // Transfer SOL await wallet.trading.transfer({ to: 'recipient_solana_address', token: 'SOL', amount: '1', chain: 'solana', }); // Launch tokens (Solana only) await wallet.tokenize.launch({ name: 'My Token', symbol: 'MTK', description: 'A new token', image: 'https://...', initialLiquidity: '10', }); ``` **Features:** - Token swaps via Jupiter Ultra - Native SOL and SPL token transfers - Token launches with instant liquidity - Sub-second transaction finality ### Ethereum EVM support via Relay aggregator. ```typescript // Swap on Ethereum await wallet.trading.swap({ inputToken: 'ETH', outputToken: 'USDC', amount: '0.1', chain: 'ethereum', }); // Transfer ETH await wallet.trading.transfer({ to: '0x...', token: 'ETH', amount: '0.1', chain: 'ethereum', }); ``` **Features:** - Token swaps via Relay - Native ETH and ERC-20 transfers - Bridge source and destination ### Base L2 with low fees via Relay. ```typescript // Swap on Base await wallet.trading.swap({ inputToken: 'ETH', outputToken: 'USDC', amount: '0.1', chain: 'base', }); // Bridge from Ethereum to Base await wallet.trading.bridge({ fromChain: 'ethereum', toChain: 'base', token: 'USDC', amount: '100', }); ``` **Features:** - Low transaction fees - Fast confirmation times - Bridge from/to other EVM chains ### Arbitrum L2 with Ethereum security via Relay. ```typescript // Swap on Arbitrum await wallet.trading.swap({ inputToken: 'ETH', outputToken: 'USDC', amount: '0.1', chain: 'arbitrum', }); ``` **Features:** - Low transaction fees - Ethereum-level security - Bridge from/to other EVM chains ## Bridges Bridges are only available between EVM chains. Solana bridges are not yet supported. ### Supported Bridge Routes | From | To | Supported | |------|-----|-----------| | Ethereum | Base | Yes | | Ethereum | Arbitrum | Yes | | Base | Ethereum | Yes | | Base | Arbitrum | Yes | | Arbitrum | Ethereum | Yes | | Arbitrum | Base | Yes | | Solana | Any EVM | No | | Any EVM | Solana | No | ### Bridge Example ```typescript // Bridge USDC from Ethereum to Base const result = await wallet.trading.bridge({ fromChain: 'ethereum', toChain: 'base', token: 'USDC', amount: '100', }); console.log('Source tx:', result.sourceTxHash); console.log('Estimated time:', result.estimatedTime); ``` ## Wallet Addresses One seed phrase generates addresses for all chains: ```typescript const created = await wallet.wallet.create(); // Single seed phrase console.log('Seed phrase:', created.seedPhrase); // Generates both addresses console.log('Solana:', created.solanaAddress); // Base58 console.log('EVM:', created.evmAddress); // 0x... (same for all EVM chains) ``` The EVM address is shared across Ethereum, Base, and Arbitrum. ## Balances Check balances across all chains: ```typescript const info = await wallet.wallet.get(); // Solana console.log('SOL:', info.balances.solana.native); // EVM chains console.log('ETH (Ethereum):', info.balances.ethereum.native); console.log('ETH (Base):', info.balances.base.native); console.log('ETH (Arbitrum):', info.balances.arbitrum.native); ``` ## Token Resolution The SDK resolves token symbols to addresses automatically: ```typescript // These all work await wallet.trading.swap({ inputToken: 'SOL', ... }); await wallet.trading.swap({ inputToken: 'ETH', chain: 'ethereum', ... }); await wallet.trading.swap({ inputToken: 'USDC', chain: 'base', ... }); // Or use contract addresses directly await wallet.trading.swap({ inputToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC on Solana ... }); ``` ## Coming Soon - Solana to EVM bridges - Additional EVM chains (Polygon, Optimism) - Cross-chain swap in single transaction --- # Market Data > Access DexScreener data with the SDK URL: https://docs.loomlay.com/sdk/dex # Market Data The `dex` resource provides access to DexScreener market data. ## Trending Pairs ```typescript const trending = await wallet.dex.trending({ chain: 'solana', limit: 10, }); for (const pair of trending.pairs) { console.log(`${pair.baseToken.symbol}/${pair.quoteToken.symbol}`); console.log(` Price: $${pair.priceUsd}`); console.log(` 24h Volume: $${pair.volume24h}`); console.log(` 24h Change: ${pair.priceChange24h}%`); } ``` ## Market Movers ```typescript // Top gainers const gainers = await wallet.dex.gainers({ chain: 'solana', limit: 10 }); // Top losers const losers = await wallet.dex.losers({ chain: 'solana', limit: 10 }); // Highest volume const volume = await wallet.dex.volume({ chain: 'solana', limit: 10 }); // New pairs const newPairs = await wallet.dex.new({ chain: 'solana', limit: 10 }); ``` ## Custom Queries Search with specific filters: ```typescript const results = await wallet.dex.query({ query: 'meme', chain: 'solana', filters: { minLiquidity: 10000, minVolume: 50000, priceChange24h: { min: 0 }, // Only gainers }, }); ``` ## Token Search Search for specific tokens: ```typescript const tokens = await wallet.tokens.search({ query: 'bonk', chain: 'solana', }); for (const token of tokens.tokens) { console.log(`${token.name} (${token.symbol})`); console.log(` Address: ${token.address}`); console.log(` Safety score: ${token.safety.score}`); console.log(` Verified: ${token.safety.verified}`); } ``` ## Pump.fun Tokens Get Pump.fun specific data: ```typescript const pumpfun = await wallet.dex.pumpfun({ limit: 20 }); for (const token of pumpfun.tokens) { console.log(`${token.name}: ${token.marketCap}`); } ``` ## Pair Details Get detailed info for a specific pair: ```typescript const pair = await wallet.dex.getPair({ chain: 'solana', pairAddress: 'pair_address_here', }); console.log('Base token:', pair.baseToken.symbol); console.log('Quote token:', pair.quoteToken.symbol); console.log('Liquidity:', pair.liquidity); console.log('Created:', pair.createdAt); ``` ## Type Definitions ```typescript interface DexPair { pairAddress: string; baseToken: TokenInfo; quoteToken: TokenInfo; priceUsd: string; priceNative: string; volume24h: string; liquidity: string; priceChange24h: number; priceChange1h: number; txCount24h: number; } interface TokenInfo { address: string; name: string; symbol: string; } interface TokenSafety { score: number; flags: string[]; verified: boolean; } ``` --- # Error Handling > Handle errors gracefully with the SDK URL: https://docs.loomlay.com/sdk/error-handling # Error Handling The SDK provides typed errors for robust error handling. ## Error Types ```typescript import { OpenClawWalletError, ConfigurationError, AuthenticationError, RateLimitError, ValidationError, NetworkError, InsufficientFundsError, } from '@loomlay/openclaw-wallet-sdk'; ``` ## Basic Error Handling ```typescript try { await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', }); } catch (error) { if (error instanceof InsufficientFundsError) { console.log('Not enough SOL:', error.message); console.log('Required:', error.required); console.log('Available:', error.available); } else if (error instanceof RateLimitError) { console.log('Rate limited. Retry after:', error.retryAfter, 'seconds'); } else if (error instanceof ValidationError) { console.log('Invalid input:', error.field, error.message); } else { throw error; } } ``` ## Error Properties All errors extend `OpenClawWalletError`: ```typescript interface OpenClawWalletError extends Error { code: string; // Machine-readable error code statusCode?: number; // HTTP status if applicable details?: unknown; // Additional error details } ``` ### Specific Error Types ```typescript // Configuration issues class ConfigurationError extends OpenClawWalletError { code: 'CONFIGURATION_ERROR'; } // Auth failures class AuthenticationError extends OpenClawWalletError { code: 'UNAUTHORIZED' | 'INVALID_API_KEY'; } // Rate limiting class RateLimitError extends OpenClawWalletError { code: 'RATE_LIMITED'; retryAfter: number; // Seconds until retry allowed } // Input validation class ValidationError extends OpenClawWalletError { code: 'VALIDATION_ERROR'; field: string; } // Network issues class NetworkError extends OpenClawWalletError { code: 'NETWORK_ERROR' | 'TIMEOUT'; } // Insufficient balance class InsufficientFundsError extends OpenClawWalletError { code: 'INSUFFICIENT_FUNDS'; required: string; available: string; token: string; } // Transaction failed class TransactionError extends OpenClawWalletError { code: 'TRANSACTION_FAILED' | 'TRANSACTION_TIMEOUT'; txHash?: string; } // Token launch errors class TokenizeError extends OpenClawWalletError { code: 'ALREADY_LAUNCHED' | 'SYMBOL_TAKEN' | 'INVALID_IMAGE'; } ``` ## Error Code Reference | Error Code | HTTP Status | Error Class | Description | |------------|-------------|-------------|-------------| | `CONFIGURATION_ERROR` | - | `ConfigurationError` | SDK misconfigured (missing API key, invalid options) | | `UNAUTHORIZED` | 401 | `AuthenticationError` | Missing or invalid API key | | `INVALID_API_KEY` | 401 | `AuthenticationError` | API key format is invalid | | `RATE_LIMITED` | 429 | `RateLimitError` | Too many requests, retry after `retryAfter` seconds | | `VALIDATION_ERROR` | 400 | `ValidationError` | Invalid input parameters | | `NETWORK_ERROR` | - | `NetworkError` | Connection failed or request timed out | | `TIMEOUT` | - | `NetworkError` | Request exceeded timeout limit | | `INSUFFICIENT_FUNDS` | 400 | `InsufficientFundsError` | Not enough balance for operation | | `TRANSACTION_FAILED` | 500 | `TransactionError` | On-chain transaction failed | | `TRANSACTION_TIMEOUT` | 500 | `TransactionError` | Transaction confirmation timed out | | `ALREADY_LAUNCHED` | 400 | `TokenizeError` | Account already launched a token | | `SYMBOL_TAKEN` | 400 | `TokenizeError` | Token symbol already exists | | `INVALID_IMAGE` | 400 | `TokenizeError` | Image URL invalid or inaccessible | | `WALLET_NOT_FOUND` | 404 | `OpenClawWalletError` | No wallet exists for this account | | `TOKEN_NOT_FOUND` | 404 | `OpenClawWalletError` | Token address or symbol not found | | `SLIPPAGE_EXCEEDED` | 400 | `OpenClawWalletError` | Price moved beyond slippage tolerance | ## Retry Logic The SDK has built-in retry for transient failures: ```typescript const wallet = new OpenClawWallet({ apiKey: 'agent_xxx', maxRetries: 3, // Retry up to 3 times retryDelay: 1000, // Start with 1s delay }); ``` ### Custom Retry ```typescript async function swapWithRetry(params: SwapParams, maxAttempts = 3) { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await wallet.trading.swap(params); } catch (error) { if (error instanceof RateLimitError) { if (attempt < maxAttempts) { await sleep(error.retryAfter * 1000); continue; } } throw error; } } } ``` ## Retry Strategy by Error Type | Error Type | Retry? | Strategy | |------------|--------|----------| | `RateLimitError` | Yes | Wait for `retryAfter` seconds, then retry | | `NetworkError` | Yes | Exponential backoff (1s, 2s, 4s), max 3 attempts | | `TransactionError` (TIMEOUT) | Maybe | Check transaction status first, retry if not confirmed | | `TransactionError` (FAILED) | No | Transaction was rejected, fix params and retry | | `InsufficientFundsError` | No | Add funds before retrying | | `ValidationError` | No | Fix input parameters before retrying | | `AuthenticationError` | No | Check API key, do not retry | | `ConfigurationError` | No | Fix SDK configuration, do not retry | | `TokenizeError` | No | Address the specific issue (symbol, image, etc.) | | `SLIPPAGE_EXCEEDED` | Yes | Increase slippage or retry with fresh quote | **Pro Tip:** For `SLIPPAGE_EXCEEDED` errors, fetch a fresh quote with `quoteOnly: true` before retrying. Market conditions may have changed significantly. ## WebSocket Errors ```typescript const dexWs = wallet.createDexWebSocket(); dexWs.on('error', (error) => { if (error instanceof AuthenticationError) { console.log('Invalid API key'); } else if (error instanceof NetworkError) { console.log('Connection lost'); } }); ``` ## Logging Enable debug logging: ```typescript import { setLogLevel } from '@loomlay/openclaw-wallet-sdk'; setLogLevel('debug'); // 'debug' | 'info' | 'warn' | 'error' | 'none' ``` --- # FAQ > Frequently asked questions about the SDK URL: https://docs.loomlay.com/sdk/faq # Frequently Asked Questions Common questions and answers about the OpenClawWallet SDK. ## Registration ### Why can I only launch one token per API key? Each API key is tied to one agent account to prevent spam and ensure quality token launches. This limit: - Prevents bot-driven token spam - Ensures creators are invested in their token's success - Maintains platform quality If you need to launch multiple tokens, you'll need separate agent accounts. ### How do I get a new API key if I lost mine? Registration is IP-limited. Your options: 1. **Check your code** - Search for `agent_` in your codebase or environment files 2. **Check registration response** - If you try to register again, you'll see your key prefix 3. **Contact support** - Email [support@loomlay.io](mailto:support@loomlay.io) with verification of ownership ```typescript // Registration attempt shows your existing key prefix const result = await OpenClawWallet.register(); if (!result.success) { console.log('Already registered. Key prefix:', result.keyPrefix); // Use this to help identify your key } ``` ### Can I have multiple API keys? Yes, you can create additional keys for your existing account: ```typescript // Create new key const newKey = await wallet.auth.createKey(); // List all keys const keys = await wallet.auth.listKeys(); // Revoke if needed await wallet.auth.revokeKey({ keyId: 'key_id' }); ``` ## Trading ### Why is my swap failing? Common causes: **Insufficient balance** ```typescript import { InsufficientFundsError } from '@loomlay/openclaw-wallet-sdk'; try { await wallet.trading.swap({ ... }); } catch (error) { if (error instanceof InsufficientFundsError) { console.log('Required:', error.required); console.log('Available:', error.available); } } ``` **Slippage too low** ```typescript // Try higher slippage for volatile tokens await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'MEMECOIN', amount: '1', slippage: 3, // 3% instead of default 0.5% }); ``` **Token not found** ```typescript // Ensure token exists and use correct symbol or address await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC address amount: '1', }); ``` **Liquidity issues** ```typescript // Check price impact first const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'LOW_LIQ_TOKEN', amount: '100', quoteOnly: true, }); if (quote.priceImpact > 5) { console.warn('High price impact - consider smaller amount'); } ``` ### Why is my bridge taking so long? Bridge times vary by network congestion: | Route | Typical Time | |-------|-------------| | Ethereum to Base | 1-5 minutes | | Ethereum to Arbitrum | 1-5 minutes | | Base to Ethereum | 5-15 minutes | | Arbitrum to Ethereum | 5-15 minutes | The SDK returns estimated time: ```typescript const result = await wallet.trading.bridge({ ... }); console.log('Estimated time:', result.estimatedTime); ``` ### What chains are supported for bridges? EVM chains only. Solana bridges are not yet supported. | From | To | Supported | |------|-----|-----------| | Ethereum | Base, Arbitrum | Yes | | Base | Ethereum, Arbitrum | Yes | | Arbitrum | Ethereum, Base | Yes | | Solana | Any | No | | Any | Solana | No | ## Wallet ### How do I check my wallet balance? Two options depending on what you need: ```typescript // Option 1: Basic wallet info const info = await wallet.wallet.get(); console.log('SOL:', info.balances.solana.native); console.log('ETH:', info.balances.ethereum.native); // Option 2: Full portfolio with USD values const portfolio = await wallet.portfolio.get(); console.log('Total value:', portfolio.totalValueUsd); for (const holding of portfolio.holdings) { console.log(`${holding.symbol}: ${holding.balance} ($${holding.valueUsd})`); } ``` ### Can I import an existing wallet? Yes, in self-custody mode you can import an existing BIP39 seed phrase: ```typescript // SDK const imported = await wallet.wallet.importSeed( 'your twelve word seed phrase here ...', 'my-secure-passphrase' ); ``` ```typescript // Plugin const imported = await wallet_import({ seedPhrase: 'your twelve word seed phrase here ...', passphrase: 'my-secure-passphrase' }); ``` The seed phrase is encrypted locally and public addresses are registered with the API for balance lookups. ### Where are my private keys stored? Private keys are derived from your seed phrase using: - **Solana**: SLIP-0010 derivation (m/44'/501'/0'/0') - **EVM**: BIP32 derivation (m/44'/60'/0'/0/0) Storage depends on your wallet mode: | Mode | Where Keys Live | Encryption | |------|----------------|------------| | **Self-custody** (`local`) | `~/.loomlay/wallet.json` on your device | PBKDF2-SHA512 + AES-256-GCM | | **Custodial** | Server-side (PostgreSQL) | AES-256-GCM with server key | In self-custody mode, private keys never leave your device. Only public addresses and signed transactions are sent to the API. ### How do I unlock my wallet for signing? In self-custody mode, you need to provide your passphrase before signing transactions. Three options: 1. **Environment variable** (recommended): `export LOOMLAY_WALLET_PASSPHRASE=your-passphrase` 2. **Plugin tool**: Call `wallet_unlock({ passphrase: 'your-passphrase' })` 3. **SDK callback**: Pass `getPassphrase` when creating the client ## Token Launch ### Why did my token launch fail? Common issues: **Insufficient SOL** ```typescript // Need SOL for: liquidity + transaction fees // Example: 10 SOL liquidity + ~0.1 SOL fees const info = await wallet.wallet.get(); console.log('SOL balance:', info.balances.solana.native); ``` **Invalid image** ```typescript // Image requirements: // - Valid URL (https://) // - PNG, JPG, or GIF format // - Minimum 200x200 pixels // - Accessible publicly ``` **Symbol already used** ```typescript // Each symbol must be unique on LoomLay // Try a different symbol if yours is taken ``` ### How do I claim fees from my token? ```typescript // Check pending fees const fees = await wallet.fees.getPending(); console.log('Pending:', fees.pendingAmount, 'SOL'); // Claim fees (rate limited to 1 per hour) if (parseFloat(fees.pendingAmount) > 0) { const claim = await wallet.fees.claim(); console.log('Claimed:', claim.claimedAmount, 'SOL'); } ``` Fee claims are rate limited to 1 per hour. The platform pays gas, so this prevents abuse. ## WebSockets ### Why am I getting disconnected? Common causes: **Inactivity timeout** ```typescript // Send heartbeats to stay connected const dexWs = wallet.createDexWebSocket(); // SDK handles heartbeats automatically, but you can listen: dexWs.on('heartbeat', () => { console.log('Connection alive'); }); ``` **Too many subscriptions** ```typescript // Maximum 10 subscriptions per connection // Create multiple connections if needed ``` **Network issues** ```typescript dexWs.on('disconnect', (reason) => { console.log('Disconnected:', reason); // SDK auto-reconnects with exponential backoff }); ``` ### How do I subscribe to multiple pairs? ```typescript const dexWs = wallet.createDexWebSocket(); // Subscribe to multiple pairs (max 10) const pairs = ['SOL/USDC', 'ETH/USDC', 'BONK/SOL']; for (const pair of pairs) { dexWs.subscribePair(pair); } dexWs.on('update', (data) => { console.log(`${data.pair}: $${data.price}`); }); ``` ## General ### Is the SDK browser-compatible? No. The SDK is designed for server-side use only: - API keys should never be exposed to browsers - Seed phrases must stay server-side - Use a backend API to proxy requests if needed ### What's the difference between quote and execute? ```typescript // Quote: Get price without executing (no funds needed) const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', quoteOnly: true, // Just get the price }); // Execute: Actually perform the swap (needs funds) const result = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', // quoteOnly defaults to false }); ``` ### How do I handle errors? ```typescript import { OpenClawWalletError, AuthenticationError, RateLimitError, InsufficientFundsError, ValidationError, } from '@loomlay/openclaw-wallet-sdk'; try { await wallet.trading.swap({ ... }); } catch (error) { if (error instanceof AuthenticationError) { // Invalid or revoked API key } else if (error instanceof RateLimitError) { // Wait and retry await sleep(error.retryAfter * 1000); } else if (error instanceof InsufficientFundsError) { // Not enough balance } else if (error instanceof ValidationError) { // Invalid parameters } else if (error instanceof OpenClawWalletError) { // Other SDK error console.log('Error code:', error.code); } else { throw error; } } ``` See [Error Handling](/sdk/error-handling) for more details. --- # Getting Started > Set up the OpenClawWallet SDK or OpenClaw Plugin in your project URL: https://docs.loomlay.com/sdk/getting-started # Getting Started This guide walks you through setting up the OpenClawWallet SDK or OpenClaw Plugin. ## Prerequisites Before you begin, ensure you have: - **Node.js 18+** or **Bun 1.0+** - A package manager: npm, yarn, pnpm, or bun - A server-side environment (the SDK is not designed for browser use) ## Installation ```bash npm install @loomlay/openclaw-wallet-sdk ``` ```bash yarn add @loomlay/openclaw-wallet-sdk ``` ```bash pnpm add @loomlay/openclaw-wallet-sdk ``` ```bash bun add @loomlay/openclaw-wallet-sdk ``` ## Quick Start (Auto-Registration) The easiest way to get started is with automatic registration: ```typescript import { OpenClawWallet } from '@loomlay/openclaw-wallet-sdk'; // Auto-register if no key found, saves to ~/.loomlay/credentials.json const { client, registration } = await OpenClawWallet.create({ autoRegister: true }); if (registration) { console.log('New account created!'); console.log('API Key:', registration.apiKey); console.log('Saved to:', registration.savedTo); } // Use the client const wallet = await client.wallet.create(); ``` The `create()` method checks for API keys in this order: 1. `apiKey` option (if provided) 2. `LOOMLAY_API_KEY` environment variable 3. Stored credentials (`~/.loomlay/credentials.json`) 4. Auto-register (if `autoRegister: true`) ## Manual Registration If you prefer to register manually: ```typescript import { OpenClawWallet } from '@loomlay/openclaw-wallet-sdk'; // This is rate-limited to 1 per IP const result = await OpenClawWallet.register(); console.log('API Key:', result.apiKey); // Save this key securely! ``` Save your API key immediately - it's only shown once during registration. ### Registration Failed (409)? If your IP already has an account: 1. **Check stored credentials** - `cat ~/.loomlay/credentials.json` 2. **Set environment variable** - `export LOOMLAY_API_KEY=agent_your_key` 3. **Contact support** - [support@loomlay.io](mailto:support@loomlay.io) for key recovery ## Initialize the Client ### Option 1: With auto-registration (recommended) ```typescript const { client } = await OpenClawWallet.create({ autoRegister: true }); ``` ### Option 2: With self-custody mode ```typescript const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, walletMode: 'local', getPassphrase: async () => process.env.LOOMLAY_WALLET_PASSPHRASE!, }); ``` In self-custody mode, private keys are generated and stored locally on your device. The API only receives public addresses. See [Wallet Management](/sdk/wallet) for details. ### Option 3: With environment variable (custodial) ```typescript const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, }); ``` ### Option 4: With explicit key ```typescript const wallet = new OpenClawWallet({ apiKey: 'agent_your_key_here', }); ``` ## Create Your First Wallet ```typescript // Create a new wallet const created = await wallet.wallet.create(); console.log('Seed phrase:', created.seedPhrase); console.log('Solana:', created.solanaAddress); console.log('EVM:', created.evmAddress); // Save the seed phrase securely! ``` ## Check Balances ```typescript const info = await wallet.wallet.get(); console.log('Solana balance:', info.balances.solana.native, 'SOL'); console.log('Ethereum balance:', info.balances.ethereum.native, 'ETH'); ``` ## Make Your First Swap ```typescript import { InsufficientFundsError, RateLimitError } from '@loomlay/openclaw-wallet-sdk'; try { // Swap 1 SOL for USDC const swap = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1', }); console.log('Swapped for:', swap.outputAmount, 'USDC'); console.log('Transaction:', swap.txHash); } catch (error) { if (error instanceof InsufficientFundsError) { console.error('Not enough funds:', error.message); console.error('Required:', error.required, '| Available:', error.available); } else if (error instanceof RateLimitError) { console.error('Rate limited. Retry in', error.retryAfter, 'seconds'); } else { throw error; } } ``` ## Environment Variables We recommend storing your API key in environment variables: ```bash # .env LOOMLAY_API_KEY=agent_your_key_here ``` ```typescript // Load from environment const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, }); ``` ## TypeScript Support The SDK is written in TypeScript and provides full type definitions: ```typescript import type { SwapParams, SwapResult, WalletInfo } from '@loomlay/openclaw-wallet-sdk'; const params: SwapParams = { inputToken: 'SOL', outputToken: 'USDC', amount: '1.5', slippage: 0.5, }; const result: SwapResult = await wallet.trading.swap(params); ``` ## Next Steps - [Wallet Management](/sdk/wallet) - Create and manage wallets - [Trading](/sdk/trading) - Swaps, transfers, and bridges - [Market Data](/sdk/dex) - Access DexScreener data - [Real-time Updates](/sdk/websockets) - WebSocket subscriptions If you're using an AI coding assistant like Claude Code, you can use the OpenClaw Plugin instead of integrating the SDK directly. The plugin provides 29 tools for wallet management, trading, and market data that the AI can use on your behalf. The plugin defaults to **self-custody mode** — private keys stay on your device. ## Installation ```bash npm install @loomlay/openclaw-wallet-plugin ``` ## Configuration No configuration required! The plugin auto-registers an API key and creates a local wallet on first use. Optionally set environment variables: ```bash # Override auto-registration export LOOMLAY_API_KEY=agent_your_key_here # Set wallet passphrase (recommended — avoids passphrase in conversation logs) export LOOMLAY_WALLET_PASSPHRASE=your-secure-passphrase ``` ## What's Included The plugin provides **29 tools** across these categories: | Category | Tools | Description | |----------|-------|-------------| | **Wallet** | 5 | Create wallets, check balances, export keys, unlock, import | | **Trading** | 5 | Swaps, transfers, bridges with quotes | | **Tokens** | 4 | Search, price, details, charts | | **Portfolio** | 2 | Holdings and transaction history | | **DEX** | 7 | Trending, gainers, losers, new pairs | | **Tokenize** | 2 | Launch tokens and check status | | **Fees** | 2 | Check and claim trading fees | | **RPC** | 2 | Direct chain RPC access | ## Skill System The plugin includes a skill system that teaches Claude: - Wallet security best practices - Quote-before-trade workflow - Error handling patterns - Chain-specific behaviors ## Example Usage Once configured, Claude can execute commands like: - "Create a new wallet" - "Swap 1 SOL for USDC" - "Show me trending tokens on Solana" - "What's the price of BONK?" Always review swap quotes before confirming trades. The plugin will show you expected output amounts and price impact. ## Next Steps - [OpenClaw Plugin](/sdk/openclaw-plugin) - Full plugin documentation - [Wallet Management](/sdk/wallet) - Wallet operations reference - [Trading](/sdk/trading) - Trading operations reference --- # SDK Overview > TypeScript SDK for the LoomLay Agent API URL: https://docs.loomlay.com/sdk # SDK Overview The official TypeScript SDK for the LoomLay Agent API. Build AI agents that can trade, manage wallets, and launch tokens across multiple blockchains. ## Choose Your Integration **Package:** `@loomlay/openclaw-wallet-sdk` For TypeScript/JavaScript applications that need programmatic access to the LoomLay Agent API. ```bash npm install @loomlay/openclaw-wallet-sdk ``` ```typescript import { OpenClawWallet } from '@loomlay/openclaw-wallet-sdk'; const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, }); // Swap tokens await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1', }); ``` [Get Started with the SDK](/sdk/getting-started) **Package:** `@loomlay/openclaw-wallet-plugin` For AI agents and coding assistants. Provides a skill-based interface with 29 tools for wallet management, trading, and market data. Defaults to **self-custody** — private keys stay on your device. ```bash npm install -g @loomlay/openclaw-wallet-plugin ``` Then use the `/wallet` skill in your AI coding assistant: ``` /wallet swap 1 SOL to USDC /wallet check balance /wallet transfer 0.5 ETH to 0x... ``` [OpenClaw Plugin Guide](/sdk/openclaw-plugin) **Building an AI Agent?** Check out the [AI Agent Development Guide](/sdk/ai-agent-guide) for best practices on amount formatting, error handling, and transaction confirmations. ## How It Works **Register** - Get an API key with a single call. One key per IP address. **Create Wallet** - Generate a multi-chain wallet with Solana and EVM addresses from a single seed phrase. **Trade** - Swap tokens, transfer funds, and bridge across chains with simple method calls. ## Supported Chains | Chain | Type | Native Token | Chain ID | Swap | Transfer | Bridge | |-------|------|--------------|----------|------|----------|--------| | Solana | Non-EVM | SOL | - | Yes | Yes | No | | Ethereum | EVM | ETH | 1 | Yes | Yes | Yes | | Base | EVM | ETH | 8453 | Yes | Yes | Yes | | Arbitrum | EVM | ETH | 42161 | Yes | Yes | Yes | | Optimism | EVM | ETH | 10 | Yes | Yes | Yes | | Polygon | EVM | MATIC | 137 | Yes | Yes | Yes | | BSC | EVM | BNB | 56 | Yes | Yes | Yes | All EVM chains share the same wallet address. See [Supported Chains](/sdk/chains) for detailed chain information. ## Key Features | Feature | Description | |---------|-------------| | **Self-custody** | Private keys encrypted locally, never sent to server | | **Type-safe** | Full TypeScript support with generated types | | **Multi-chain** | Solana + EVM from single interface | | **WebSockets** | Real-time market data subscriptions | | **Auto-retry** | Configurable retry logic for transient failures | | **AI-ready** | OpenClaw Plugin with 29 tools | API requests are rate-limited to prevent abuse. See [Rate Limits](/api-reference/rate-limits) for details on limits per endpoint. Each API key is tied to one agent account, which can only launch **one token**. Choose your token launch carefully as this cannot be undone. ## Resources | Resource | Purpose | |----------|---------| | `wallet.auth` | API key management | | `wallet.wallet` | Wallet creation and info | | `wallet.trading` | Swaps, transfers, bridges | | `wallet.dex` | Market data | | `wallet.tokenize` | Token launches | ## Quick Links ### Getting Started - [Getting Started](/sdk/getting-started) - Set up the SDK - [Wallet Management](/sdk/wallet) - Create and manage wallets - [Trading](/sdk/trading) - Swaps, transfers, bridges - [WebSockets](/sdk/websockets) - Real-time subscriptions ### AI Agent Development - [OpenClaw Plugin](/sdk/openclaw-plugin) - Skill-based interface for AI agents - [Tools Reference](/sdk/tools-reference) - All 27 available tools - [AI Agent Guide](/sdk/ai-agent-guide) - Best practices for AI agents - [Amount Formats](/sdk/amount-formats) - Human-readable vs raw amounts ### Reference - [Supported Chains](/sdk/chains) - Chain details and capabilities - [Error Handling](/sdk/error-handling) - Error types and recovery - [Security](/sdk/security) - API key and wallet security --- # OpenClaw Plugin > Native tools for AI agents with multi-chain wallet and trading capabilities URL: https://docs.loomlay.com/sdk/openclaw-plugin # OpenClaw Plugin The OpenClaw Plugin provides 29 native tools for multi-chain wallet management, trading, and market data directly within AI coding assistants like Claude Code. The plugin defaults to **self-custody mode** — private keys are generated and encrypted locally on your device, never sent to any server. ## Architecture Overview The OpenClaw ecosystem has a dual-layer architecture: | Layer | Package | Purpose | |-------|---------|---------| | **SDK** | `@loomlay/openclaw-wallet-sdk` | Programmatic TypeScript interface for building applications | | **Plugin** | `@loomlay/openclaw-wallet-plugin` | Native tools for AI agents | The SDK is designed for developers building applications. The Plugin wraps the SDK and exposes its functionality as discrete tools that AI agents can invoke directly. The Plugin depends on the SDK internally. When you install the plugin, the SDK is included as a peer dependency. ## Installation ```bash npm install @loomlay/openclaw-wallet-plugin ``` ```bash yarn add @loomlay/openclaw-wallet-plugin ``` ```bash pnpm add @loomlay/openclaw-wallet-plugin ``` ```bash bun add @loomlay/openclaw-wallet-plugin ``` ## Configuration ### Zero Configuration (Recommended) The plugin works out of the box with **no configuration required**. On first use, it automatically: 1. Registers for a new API key (saved to `~/.loomlay/credentials.json`) 2. Generates wallet keys **locally** on your device 3. Encrypts keys with your passphrase (saved to `~/.loomlay/wallet.json`) 4. Registers only public addresses with the API ```typescript import { wallet_create, wallet_unlock } from '@loomlay/openclaw-wallet-plugin'; // First use: auto-registers API key, creates local wallet const wallet = await wallet_create(); // → Keys generated on YOUR device, encrypted with passphrase // → Public addresses registered with API for balance lookups // Unlock wallet for signing operations await wallet_unlock({ passphrase: 'your-passphrase' }); // All trades sign locally — private key never sent to server ``` ### API Key Resolution Order The plugin checks for API keys in this order: 1. `LOOMLAY_API_KEY` environment variable (highest priority) 2. Stored credentials (`~/.loomlay/credentials.json`) 3. Auto-register new account (if no key found) ### Passphrase Resolution Order For signing operations (swaps, transfers), the passphrase is resolved: 1. `LOOMLAY_WALLET_PASSPHRASE` environment variable (highest priority, recommended) 2. In-memory cache (set via `wallet_unlock`) 3. Error thrown with instructions ### Environment Variables (Optional) ```bash # Override auto-registration export LOOMLAY_API_KEY=agent_your_key_here # Set wallet passphrase (avoids passphrase appearing in conversation logs) export LOOMLAY_WALLET_PASSPHRASE=your-secure-passphrase # Optional: Custom API base URL export LOOMLAY_BASE_URL=https://api.loomlay.com ``` ### Programmatic Configuration (Optional) ```typescript import { initPlugin, initPluginAsync } from '@loomlay/openclaw-wallet-plugin'; // Sync: Requires existing key from env or stored credentials initPlugin({ apiKey: 'agent_your_key_here', baseUrl: 'https://api.loomlay.com' // Optional }); // Async: Supports auto-registration const { client, registration } = await initPluginAsync(); ``` ### Disable Auto-Registration If you want to require explicit API key configuration: ```typescript import { initPluginAsync } from '@loomlay/openclaw-wallet-plugin'; // Throws error if no key found instead of auto-registering const { client } = await initPluginAsync({ autoRegister: false }); ``` Store your API key in environment variables or let the plugin manage it automatically. API keys start with `agent_` prefix. ## Available Tools (29) The plugin provides 29 tools organized into 8 categories: ### Wallet (5 tools) | Tool | Description | |------|-------------| | `wallet_create` | Create a new multi-chain wallet (keys stored locally in self-custody mode). Returns Solana and EVM addresses plus a 12-word seed phrase shown only once. | | `wallet_get` | Get wallet addresses and current balances across all chains. | | `wallet_export_keys` | Export private keys. In self-custody mode, decrypts locally using passphrase. In custodial mode, requires seed phrase. | | `wallet_unlock` | Cache passphrase in memory for signing operations. Required before swaps/transfers in self-custody mode. | | `wallet_import` | Import an existing seed phrase into a local self-custody wallet. Encrypts locally and registers addresses with API. | ### Trading (5 tools) | Tool | Description | |------|-------------| | `swap` | Execute a token swap. Supports flexible amounts: `"1.5"`, `"$100"`, `"50%"`, or `"max"`. | | `swap_quote` | Get a swap quote without executing. Shows expected output, minimum received, and price impact. | | `transfer` | Transfer tokens to another address on any supported chain. | | `bridge` | Bridge tokens between different chains (e.g., Solana to Base). | | `bridge_quote` | Get a bridge quote showing fees and estimated completion time. | ### Tokens (4 tools) | Tool | Description | |------|-------------| | `token_search` | Search for tokens by name, symbol, or address. Returns matches with safety scores. | | `token_price` | Get current USD price for any token. | | `token_details` | Get detailed token information including market data and safety analysis. | | `token_chart` | Get OHLCV chart data for technical analysis. | ### Portfolio (2 tools) | Tool | Description | |------|-------------| | `portfolio_get` | Get combined portfolio across all chains with total USD value. | | `portfolio_history` | Get transaction history with optional chain filtering. | ### DEX (7 tools) | Tool | Description | |------|-------------| | `dex_trending` | Get trending trading pairs sorted by trending score. | | `dex_volume` | Get top trading pairs by 24h volume. | | `dex_gainers` | Get top price gainers (24h). | | `dex_losers` | Get top price losers (24h). | | `dex_new` | Get newly created pairs (< 24 hours old). | | `dex_pumpfun` | Get Pumpfun trending pairs (Solana only, bonding curve tokens). | | `dex_query` | Advanced DEX query with custom filters, ranking, and timeframes. | ### Tokenize (2 tools) | Tool | Description | |------|-------------| | `tokenize_launch` | Launch a new token on Solana with automatic pool creation. One token per account. | | `tokenize_info` | Get information about your launched token including mint and pool addresses. | ### Fees (2 tools) | Tool | Description | |------|-------------| | `fees_status` | Get fee status including generated, claimed, and unclaimed amounts. | | `fees_claim` | Claim accumulated trading fees from your launched token (platform pays gas). | ### RPC (2 tools) | Tool | Description | |------|-------------| | `rpc_call` | Make a direct RPC call to any supported chain. | | `rpc_chains` | Get list of supported chains for RPC access. | ## Skill System The plugin includes a skill file (`SKILL.md`) that teaches AI agents how to use the tools safely and effectively. ### What the Skill Teaches The skill provides guidance on: 1. **Core Workflow** - A structured approach: Authenticate, Understand, Validate, Execute, Verify, Document 2. **Security Best Practices** - Seed phrase handling, transaction safety, API key management 3. **Quote-Before-Trade Pattern** - Always get quotes and show expected outcomes before executing 4. **Error Handling** - Recovery patterns for rate limits, insufficient funds, and network errors 5. **Chain-Specific Behaviors** - Differences between Solana and EVM chains ### Key Safety Principles The skill enforces these safety principles for AI agents: ``` Security comes first. Wallets contain real value. Every action involving funds should be deliberate, verified, and explained to the user before execution. ``` **Quality Gate Checklist:** - User explicitly requested this action - Quote shown and confirmed for trades - Address validated for transfers - Sufficient balance confirmed - Slippage/price impact acceptable - Transaction hash provided after execution ### Accessing the Skill ```typescript // Import from the package import skillContent from '@loomlay/openclaw-wallet-plugin/skill'; // Or read the file directly // node_modules/@loomlay/openclaw-wallet-plugin/skill/SKILL.md ``` ## Usage Example ### Self-Custody Workflow ```typescript import { wallet_create, wallet_unlock, wallet_get, swap, swap_quote, dex_trending } from '@loomlay/openclaw-wallet-plugin'; // 1. Create wallet (keys generated and encrypted locally) const wallet = await wallet_create(); if (wallet.success) { console.log('Solana Address:', wallet.data.wallet.solanaAddress); console.log('EVM Address:', wallet.data.wallet.evmAddress); // IMPORTANT: Save the seed phrase securely - shown only once console.log('Seed Phrase:', wallet.data.seedPhrase); } // 2. Unlock wallet for signing (or set LOOMLAY_WALLET_PASSPHRASE env var) await wallet_unlock({ passphrase: 'my-secure-passphrase' }); // Check balance const balance = await wallet_get(); if (balance.success) { console.log('SOL Balance:', balance.data.balances.solana.sol); } // Get a quote before trading const quote = await swap_quote({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100' }); if (quote.success) { console.log('Expected Output:', quote.data.outputAmount, 'USDC'); console.log('Price Impact:', quote.data.priceImpact, '%'); } // Execute the swap after confirming the quote const result = await swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '$100' }); // Get trending tokens const trending = await dex_trending({ chain: 'solana', minLiquidity: 10000, limit: 20 }); ``` ### Using the Tools Registry ```typescript import { tools } from '@loomlay/openclaw-wallet-plugin'; // Call tools by name const wallet = await tools.wallet_get(); const trending = await tools.dex_trending({ chain: 'solana' }); ``` ## Response Format All tools return a standardized response: ```typescript interface ToolResponse { success: boolean; data?: T; // Present when success is true error?: { message: string; code?: string; retryAfter?: number; // For rate limit errors }; } ``` ### Success Response ```typescript { success: true, data: { // Tool-specific data } } ``` ### Error Response ```typescript { success: false, error: { message: "Rate limited", code: "RATE_LIMITED", retryAfter: 30 } } ``` ## Amount Formats Trading tools accept flexible amount formats: | Format | Example | Description | |--------|---------|-------------| | Decimal | `"1.5"` | Exact token amount | | USD | `"$100"` | Dollar value (auto-converts) | | Percentage | `"50%"` | Percentage of balance | | Max | `"max"` | Entire balance | ## Supported Chains | Chain | Swaps | Bridges | RPC | |-------|:-----:|:-------:|:---:| | Solana | Yes | Yes | Yes | | Ethereum | Yes | Yes | Yes | | Base | Yes | Yes | Yes | | Arbitrum | Yes | Yes | Yes | | Optimism | Yes | Yes | Yes | | Polygon | Yes | Yes | Yes | | BSC | Yes | Yes | Yes | ## Plugin Manifest The `openclaw.plugin.json` file describes all tools in a machine-readable format: ```json { "name": "@loomlay/openclaw-wallet-plugin", "tools": [ { "name": "swap", "description": "Execute a token swap...", "parameters": { ... }, "returns": { ... } } ] } ``` This manifest enables plugin systems and AI agents to discover and understand available tools programmatically. ## Security Notes **Seed Phrase Security:** The seed phrase is returned only once when creating a wallet. It cannot be retrieved later. Store it securely offline. Never log it, include it in error messages, or store it in databases. ### Self-Custody Security In self-custody mode (default), your keys are protected by: - **Local encryption**: PBKDF2-SHA512 (600k iterations) + AES-256-GCM - **File permissions**: `~/.loomlay/wallet.json` with `0600` (owner read/write only) - **No key transmission**: Private keys never sent to any server - **Transaction validation**: Fee payer verified before signing - **Key zeroing**: Private key buffers zeroed after signing Set `LOOMLAY_WALLET_PASSPHRASE` as an environment variable to keep your passphrase out of conversation logs. ### General 1. **API Key** - Store in environment variables, never hardcode 2. **Seed Phrase** - Returned once from `wallet_create`, store offline securely 3. **Quotes First** - Always get quotes before executing trades 4. **Verify Addresses** - Double-check recipient addresses for transfers 5. **Check Price Impact** - High price impact (>1%) indicates significant market movement ## Related Pages - [SDK Overview](/sdk) - Full TypeScript SDK documentation - [Getting Started](/sdk/getting-started) - SDK setup and first steps - [Trading](/sdk/trading) - Detailed swap, transfer, and bridge documentation - [Market Data](/sdk/dex) - DEX data and market analysis tools - [Error Handling](/sdk/error-handling) - Error types and recovery patterns - [Rate Limits](/sdk/rate-limits) - API rate limit information --- # Rate Limits > API rate limits and best practices URL: https://docs.loomlay.com/sdk/rate-limits # Rate Limits The API enforces rate limits to ensure fair usage and platform stability. ## Rate Limit Overview | Endpoint | Limit | Window | |----------|-------|--------| | Registration | 5 requests | 24 hours | | Wallet operations | 30 requests | 1 minute | | Trading (swap/transfer/bridge) | 30 requests | 1 minute | | Portfolio | 60 requests | 1 minute | | Token search | 100 requests | 1 minute | | DEX data | 60 requests | 1 minute | | RPC proxy | 100 requests | 1 minute | | Token launch | 1 request | 24 hours | | Fee claims | 1 request | 1 hour | ## Rate Limit Headers All API responses include rate limit headers: ``` X-RateLimit-Limit: 30 X-RateLimit-Remaining: 25 X-RateLimit-Reset: 1699574400 ``` ## Handling 429 Responses When you exceed rate limits, the API returns HTTP 429: ```typescript import { RateLimitError } from '@loomlay/openclaw-wallet-sdk'; try { await wallet.trading.swap({ ... }); } catch (error) { if (error instanceof RateLimitError) { console.log('Rate limited. Retry after:', error.retryAfter, 'seconds'); } } ``` ## Exponential Backoff Implement exponential backoff for robust retry logic: ```typescript async function withRetry( fn: () => Promise, maxAttempts = 5 ): Promise { let lastError: Error | undefined; for (let attempt = 0; attempt < maxAttempts; attempt++) { try { return await fn(); } catch (error) { if (error instanceof RateLimitError) { // Use server-provided retry time, or calculate backoff const delay = error.retryAfter ? error.retryAfter * 1000 : Math.min(1000 * Math.pow(2, attempt), 30000); console.log(`Rate limited. Retrying in ${delay}ms...`); await sleep(delay); lastError = error; } else { throw error; } } } throw lastError; } function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } // Usage const result = await withRetry(() => wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1', }) ); ``` ## Built-in Retry The SDK includes built-in retry for transient failures: ```typescript const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, maxRetries: 3, // Retry up to 3 times retryDelay: 1000, // Start with 1s delay }); ``` Built-in retry uses exponential backoff automatically. Each retry waits 2x longer than the previous. ## WebSocket Limits WebSocket connections have separate limits: | Limit | Value | |-------|-------| | Subscriptions per client | 10 | | Max upstream connections | 20 | | Heartbeat interval | 30 seconds | ```typescript const dexWs = wallet.createDexWebSocket(); // Maximum 10 subscriptions per connection dexWs.subscribePair('SOL/USDC'); dexWs.subscribePair('ETH/USDC'); // ... up to 10 pairs ``` ## Best Practices ### Batch When Possible Instead of multiple individual calls: ```typescript // Less efficient: 3 API calls const sol = await wallet.wallet.get(); const portfolio = await wallet.portfolio.get(); const status = await wallet.tokenize.status(); ``` Use a single portfolio call when you need holdings: ```typescript // More efficient: 1 API call const portfolio = await wallet.portfolio.get(); // Contains balances across all chains ``` ### Cache Responses Cache data that doesn't change frequently: ```typescript let cachedPortfolio: PortfolioResult | null = null; let cacheTime = 0; const CACHE_TTL = 60000; // 1 minute async function getPortfolio() { const now = Date.now(); if (cachedPortfolio && now - cacheTime < CACHE_TTL) { return cachedPortfolio; } cachedPortfolio = await wallet.portfolio.get(); cacheTime = now; return cachedPortfolio; } ``` ### Use WebSockets for Real-time Data For frequently updating data, use WebSockets instead of polling: ```typescript // Instead of polling setInterval(async () => { const data = await wallet.dex.getPair('SOL/USDC'); // Uses rate limit }, 1000); // Use WebSocket const dexWs = wallet.createDexWebSocket(); dexWs.subscribePair('SOL/USDC'); dexWs.on('update', (data) => { console.log('Real-time update:', data); }); ``` ### Spread Out Requests If you need to make many requests, spread them out: ```typescript const tokens = ['SOL', 'ETH', 'USDC', 'BONK', 'WIF']; const results = []; for (const token of tokens) { const data = await wallet.dex.getToken(token); results.push(data); // Small delay between requests await sleep(100); } ``` ## Registration Limits Registration is strictly limited to prevent abuse. Each IP address can only register a limited number of accounts. If you need additional API keys: 1. Use the key management endpoints to create additional keys for your existing account 2. Contact support for legitimate multi-account use cases ```typescript // Create additional keys for existing account const newKey = await wallet.auth.createKey(); console.log('New key:', newKey.apiKey); // List all keys const keys = await wallet.auth.listKeys(); // Revoke a key await wallet.auth.revokeKey({ keyId: 'key_to_revoke' }); ``` --- # Security Best Practices > Keep your API keys and wallets secure URL: https://docs.loomlay.com/sdk/security # Security Best Practices This guide covers essential security practices for using the SDK safely. The SDK supports two wallet modes with different security models. ## Self-Custody Security In self-custody mode (`walletMode: 'local'`), your private keys never leave your device: ### Encryption - **KDF**: PBKDF2-SHA512 with 600,000 iterations (exceeds OWASP 2024 recommendations) + random 32-byte salt - **Cipher**: AES-256-GCM with random 12-byte IV and 16-byte auth tag - **Storage**: `~/.loomlay/wallet.json` with `0600` permissions (owner read/write only) - **Key zeroing**: Private key buffers are zeroed immediately after signing ### What Stays Local - Encrypted seed phrase (in `~/.loomlay/wallet.json`) - Passphrase (in-memory only, never written to disk) - Transaction signing (decrypt → sign → zero → discard) ### What Goes to the API - Public wallet addresses (for balance lookups) - Signed transactions (for submission to the blockchain) - Never: private keys, seed phrases, or passphrases ### Passphrase Management The passphrase protects your encrypted wallet. Best practices: ```bash # Recommended: Set as environment variable (avoids conversation logs) export LOOMLAY_WALLET_PASSPHRASE=your-secure-passphrase ``` ```typescript // Or provide programmatically const wallet = new OpenClawWallet({ apiKey: 'agent_xxx', walletMode: 'local', getPassphrase: async () => process.env.LOOMLAY_WALLET_PASSPHRASE!, }); ``` If using the OpenClaw Plugin, set `LOOMLAY_WALLET_PASSPHRASE` as an environment variable to avoid your passphrase appearing in conversation logs. ### Transaction Validation Before signing any transaction locally, the SDK validates that the transaction's `feePayer` matches your local wallet address. This prevents signing malicious transactions that could drain your funds. ## API Key Security ### Never Commit Keys ```bash # .gitignore .env .env.local *.env ``` Never commit API keys to version control. Even if you remove them later, they remain in git history. ### Use Environment Variables ```typescript // Good: Load from environment const wallet = new OpenClawWallet({ apiKey: process.env.LOOMLAY_API_KEY!, }); // Bad: Hardcoded key const wallet = new OpenClawWallet({ apiKey: 'agent_abc123...', // Never do this! }); ``` ### One Key Per Application Each API key should be used by only one application: - Development environment: separate key - Staging environment: separate key - Production environment: separate key ### Key Rotation If you suspect a key is compromised: 1. Generate a new key via the API 2. Update your application with the new key 3. Revoke the old key ```typescript // Generate new key const newKey = await wallet.auth.createKey(); // After updating your app, revoke the old key await wallet.auth.revokeKey({ keyId: 'old_key_id' }); ``` ## Seed Phrase Security Your seed phrase is the master key to your wallet. Anyone with access to it can steal all your funds. ### Storage Guidelines - **Never transmit** seed phrases over the internet - **Never store** in plain text files - **Never share** with anyone, including support - Store offline in a secure location (encrypted USB, hardware wallet, paper backup) ### SDK Usage The SDK only requires the seed phrase for key export: ```typescript // Seed phrase NOT needed for: await wallet.wallet.get(); // Check balances await wallet.trading.swap({...}); // Execute swaps await wallet.trading.transfer({...}); // Send tokens // Seed phrase ONLY needed for: await wallet.wallet.exportKeys({ seedPhrase: 'your twelve word seed phrase', }); ``` ### For Large Amounts Consider using self-custody mode (`walletMode: 'local'`) for maximum security. In custodial mode, the SDK-managed wallet stores keys server-side and is best suited for active trading amounts. For holdings above your risk tolerance, consider hardware wallet integration. ## Transaction Safety ### Verify Recipient Addresses Always double-check addresses before transfers: ```typescript const recipient = '7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU'; // Verify address format if (!recipient.match(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/)) { throw new Error('Invalid Solana address format'); } await wallet.trading.transfer({ to: recipient, token: 'USDC', amount: '1000', chain: 'solana', }); ``` ### Quote Before Large Swaps Always get a quote before executing large swaps: ```typescript // First, get a quote const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', quoteOnly: true, }); console.log('Expected output:', quote.outputAmount); console.log('Price impact:', quote.priceImpact, '%'); // Review the quote, then execute if (quote.priceImpact < 1) { const result = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '100', }); } ``` ### Set Appropriate Slippage ```typescript // Default slippage is 0.5% await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '10', slippage: 0.5, // 0.5% - good for liquid pairs }); // For volatile or low-liquidity tokens, you may need higher slippage await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'MEMECOIN', amount: '1', slippage: 3, // 3% - for volatile tokens }); ``` ### Monitor Price Impact High price impact indicates you're moving the market: ```typescript const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1000', quoteOnly: true, }); if (quote.priceImpact > 2) { console.warn('High price impact! Consider smaller trade size.'); } ``` ## Environment Setup ### Example .env File ```bash # .env # API key for LoomLay SDK LOOMLAY_API_KEY=agent_your_key_here # Optional: Seed phrase backup (only if you need key export) # WARNING: Storing seed phrases in .env is risky # Only do this if your server is highly secured # LOOMLAY_SEED_PHRASE="word1 word2 word3 ..." ``` ### Environment Validation ```typescript function validateEnv() { const apiKey = process.env.LOOMLAY_API_KEY; if (!apiKey) { throw new Error('LOOMLAY_API_KEY is required'); } if (!apiKey.startsWith('agent_')) { throw new Error('Invalid API key format'); } return { apiKey }; } const { apiKey } = validateEnv(); const wallet = new OpenClawWallet({ apiKey }); ``` ## Production Checklist Before deploying to production: - [ ] API keys loaded from environment variables - [ ] `.env` files in `.gitignore` - [ ] Seed phrases stored securely offline - [ ] Error handling for all API calls - [ ] Rate limit handling implemented - [ ] Transaction amounts validated before execution - [ ] Slippage limits appropriate for token liquidity - [ ] Self-custody mode enabled for sensitive deployments (`walletMode: 'local'`) - [ ] `LOOMLAY_WALLET_PASSPHRASE` set via environment variable (not in code) - [ ] `~/.loomlay/wallet.json` permissions verified (`0600`) --- # Token Launch > Launch tokens on Solana with the SDK URL: https://docs.loomlay.com/sdk/tokenize # Token Launch The `tokenize` resource lets you launch a token on Solana with instant liquidity. **One Token Per Account:** Each agent account can only launch **one token ever**. This limit cannot be reset or bypassed. Once you launch a token, that account is permanently tied to it. Plan your token launch carefully before executing. ## Launch a Token ```typescript const launch = await wallet.tokenize.launch({ name: 'My Token', symbol: 'MTK', description: 'A revolutionary new token', image: 'https://example.com/token-image.png', initialLiquidity: '10', // SOL supply: '1000000000', // 1 billion }); console.log('Token address:', launch.tokenAddress); console.log('Pool address:', launch.poolAddress); console.log('Transactions:', launch.txHashes); ``` ## Check Launch Status ```typescript const status = await wallet.tokenize.status(); if (status.launched) { console.log('Token:', status.tokenAddress); console.log('Pool:', status.poolAddress); console.log('Launched at:', status.launchedAt); } else { console.log('No token launched yet'); } ``` ## Fee Management ### Check Pending Fees ```typescript const fees = await wallet.fees.getPending(); console.log('Pending fees:', fees.pendingAmount, 'SOL'); console.log('Total claimed:', fees.totalClaimed, 'SOL'); console.log('Last claim:', fees.lastClaimAt); ``` ### Claim Fees ```typescript const claim = await wallet.fees.claim(); console.log('Claimed:', claim.claimedAmount, 'SOL'); console.log('Transaction:', claim.txHash); ``` ## Token Metadata Metadata is stored on-chain via Metaplex: ```typescript const launch = await wallet.tokenize.launch({ name: 'My Token', symbol: 'MTK', description: 'Description goes here', image: 'https://...', // Required: PNG, JPG, or GIF // Optional social links twitter: 'https://twitter.com/mytoken', telegram: 'https://t.me/mytoken', website: 'https://mytoken.com', initialLiquidity: '10', }); ``` ## Requirements - **SOL balance**: Enough for liquidity + transaction fees (~0.05 SOL for fees) - **Image**: Valid URL to PNG, JPG, or GIF (min 200x200px) - **Unique symbol**: Not already used on LoomLay ### Image Requirements | Requirement | Details | |-------------|---------| | **Format** | PNG, JPG, or GIF | | **Minimum size** | 200x200 pixels | | **Maximum size** | 5MB | | **URL** | Must be publicly accessible (no authentication) | | **Hosting** | Use a reliable CDN (IPFS, Cloudflare, AWS S3) | The image URL must be accessible at launch time. If the URL returns a 404 or requires authentication, the launch will fail. Consider using IPFS via Pinata or a CDN for reliable hosting. ## Common Issues | Issue | Cause | Solution | |-------|-------|----------| | `INSUFFICIENT_FUNDS` | Not enough SOL for liquidity + fees | Ensure balance covers `initialLiquidity` + ~0.05 SOL for transaction fees | | `INVALID_IMAGE` | Image URL not accessible or wrong format | Verify URL is publicly accessible and returns a valid image | | `SYMBOL_TAKEN` | Symbol already used on LoomLay | Choose a different, unique symbol | | `ALREADY_LAUNCHED` | Account already launched a token | Each account can only launch one token | | `INVALID_SYMBOL` | Symbol too long or contains invalid characters | Use 2-10 uppercase alphanumeric characters | | `NETWORK_ERROR` | RPC or network connectivity issue | Retry after a few seconds | ## Type Definitions ```typescript interface TokenizeLaunchParams { name: string; symbol: string; description: string; image: string; initialLiquidity: string; supply?: string; twitter?: string; telegram?: string; website?: string; } interface TokenizeLaunchResult { success: boolean; tokenAddress: string; poolAddress: string; txHashes: string[]; } interface FeesResult { pendingAmount: string; totalClaimed: string; lastClaimAt: string | null; } ``` --- # Tools Reference > Complete reference for all 29 tools available in the OpenClaw Plugin URL: https://docs.loomlay.com/sdk/tools-reference # Tools Reference The OpenClaw Plugin provides 29 tools for multi-chain wallet management, trading, and market data. These tools are available when using the plugin with AI coding assistants like Claude Code. ## Table of Contents | Category | Tools | Description | |----------|-------|-------------| | [Wallet](#wallet) | 5 | Create wallets, get balances, export keys, unlock, import | | [Trading](#trading) | 5 | Swaps, transfers, and bridges | | [Tokens](#tokens) | 4 | Search, price, details, and charts | | [Portfolio](#portfolio) | 2 | Holdings and transaction history | | [DEX](#dex) | 7 | Market data and rankings | | [Tokenize](#tokenize) | 2 | Launch tokens on Solana | | [Fees](#fees) | 2 | Fee status and claims | | [RPC](#rpc) | 2 | Direct RPC access | --- ## Wallet Tools for creating and managing multi-chain wallets. ### wallet_create Create a new multi-chain wallet. In self-custody mode (default), keys are generated and encrypted locally on your device. Returns wallet addresses for Solana and EVM chains, plus a 12-word seed phrase shown only once. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `wallet.solanaAddress` | string | Solana wallet address | | `wallet.evmAddress` | string | EVM wallet address (shared across all EVM chains) | | `seedPhrase` | string | 12-word BIP39 seed phrase (shown only once) | | `message` | string | Confirmation message | **Example:** ``` User: Create a new wallet for me Claude: I'll create a new multi-chain wallet for you. [Uses wallet_create tool] Result: - Solana: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU - EVM: 0x742d35Cc6634C0532925a3b844Bc9e7595f8fE0d - Seed phrase: abandon ability able about above absent... ``` The seed phrase is only shown once. Store it securely and never share it. --- ### wallet_get Get wallet addresses and current balances across all chains. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `wallet.solanaAddress` | string | Solana wallet address | | `wallet.evmAddress` | string | EVM wallet address | | `balances.solana` | object | Solana native and token balances | | `balances.evm` | object | EVM native and token balances | **Example:** ``` User: What's my wallet balance? Claude: I'll check your wallet balances. [Uses wallet_get tool] Result: - Solana: 5.23 SOL + 100 USDC - EVM: 0.15 ETH + 50 USDC (Base) ``` --- ### wallet_export_keys Export private keys for external wallet import. In self-custody mode, decrypts locally using passphrase. In custodial mode, requires seed phrase for verification. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `seedPhrase` | string | Custodial only | 12-word BIP39 seed phrase for verification (not needed in self-custody mode) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `solanaPrivateKey` | string | Solana private key (base58) | | `evmPrivateKey` | string | EVM private key (hex) | **Example:** ``` User: Export my private keys, seed phrase is "abandon ability able..." Claude: I'll export your private keys for external wallet import. [Uses wallet_export_keys tool with seedPhrase] Result: - Solana key: 4wBqp... - EVM key: 0x3a2f... ``` Only export keys when absolutely necessary. Exposing private keys risks losing all funds. --- ### wallet_unlock Cache your wallet passphrase in memory for the current session. Required before signing transactions in self-custody mode. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `passphrase` | string | Yes | Passphrase used to encrypt/decrypt the local wallet | **Returns:** | Field | Type | Description | |-------|------|-------------| | `unlocked` | boolean | Whether the wallet was unlocked successfully | | `message` | string | Confirmation message | **Example:** ``` User: Unlock my wallet with passphrase "my-secure-pass" Claude: I'll unlock your wallet for this session. [Uses wallet_unlock tool with passphrase] Result: Wallet unlocked. You can now sign transactions. ``` Set `LOOMLAY_WALLET_PASSPHRASE` as an environment variable to avoid the passphrase appearing in conversation logs. --- ### wallet_import Import an existing BIP39 seed phrase into a local self-custody wallet. The seed phrase is encrypted locally and public addresses are registered with the API. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `seedPhrase` | string | Yes | 12-word BIP39 seed phrase to import | | `passphrase` | string | Yes | Passphrase to encrypt the wallet locally | **Returns:** | Field | Type | Description | |-------|------|-------------| | `wallet.solanaAddress` | string | Derived Solana address | | `wallet.evmAddress` | string | Derived EVM address | | `seedPhrase` | string | The imported seed phrase (for confirmation) | | `message` | string | Confirmation message | **Example:** ``` User: Import my existing wallet with seed phrase "abandon ability able..." Claude: I'll import your seed phrase into a local wallet. [Uses wallet_import tool with seedPhrase and passphrase] Result: - Imported wallet locally - Solana: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU - EVM: 0x742d35Cc6634C0532925a3b844Bc9e7595f8fE0d ``` The seed phrase is encrypted and stored locally at `~/.loomlay/wallet.json`. Only public addresses are sent to the API. --- ## Trading Tools for executing swaps, transfers, and cross-chain bridges. ### swap Execute a token swap. Supports flexible amounts: decimal (1.5), USD ($100), percentage (50%), or max. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `inputToken` | string | Yes | Token to sell (symbol or address) | | `outputToken` | string | Yes | Token to buy (symbol or address) | | `amount` | string | Yes | Amount to swap (e.g., '1.5', '$100', '50%', 'max') | | `chain` | string | No | Chain: solana, ethereum, base, arbitrum, optimism, polygon, bsc | | `slippage` | number | No | Max slippage percentage (default 1) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `success` | boolean | Whether the swap succeeded | | `txHash` | string | Transaction hash | | `inputAmount` | string | Amount of input token spent | | `outputAmount` | string | Amount of output token received | **Example:** ``` User: Swap 1 SOL for USDC Claude: I'll swap 1 SOL for USDC on Solana. [Uses swap tool with inputToken="SOL", outputToken="USDC", amount="1"] Result: - Swapped 1 SOL for 98.52 USDC - Transaction: 5xKq... ``` --- ### swap_quote Get a swap quote without executing. Use to show expected output before trading. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `inputToken` | string | Yes | Token to sell | | `outputToken` | string | Yes | Token to buy | | `amount` | string | Yes | Amount to swap | | `chain` | string | No | Target chain | **Returns:** | Field | Type | Description | |-------|------|-------------| | `inputAmount` | string | Input amount | | `outputAmount` | string | Expected output amount | | `minOutputAmount` | string | Minimum output with slippage | | `priceImpact` | number | Price impact percentage | | `route` | string | Routing description | **Example:** ``` User: How much USDC would I get for 10 SOL? Claude: I'll get a quote for swapping 10 SOL to USDC. [Uses swap_quote tool] Result: - Expected output: 985.20 USDC - Minimum output: 975.35 USDC (1% slippage) - Price impact: 0.05% ``` --- ### transfer Transfer tokens to another address. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `token` | string | Yes | Token to transfer (symbol or address) | | `amount` | string | Yes | Amount to transfer | | `to` | string | Yes | Recipient address | | `chain` | string | No | Target chain | **Returns:** | Field | Type | Description | |-------|------|-------------| | `success` | boolean | Whether the transfer succeeded | | `txHash` | string | Transaction hash | | `amount` | string | Amount transferred | | `token` | string | Token transferred | | `to` | string | Recipient address | **Example:** ``` User: Send 50 USDC to 7xKXtg... Claude: I'll transfer 50 USDC to the specified address. [Uses transfer tool] Result: - Sent 50 USDC to 7xKXtg... - Transaction: 3nPq... ``` --- ### bridge Bridge tokens between different chains (e.g., Solana to Base). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `inputToken` | string | Yes | Token to bridge | | `amount` | string | Yes | Amount to bridge | | `sourceChain` | string | Yes | Source chain | | `destinationChain` | string | Yes | Destination chain | | `outputToken` | string | No | Output token (if different) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `success` | boolean | Whether the bridge initiated successfully | | `sourceTxHash` | string | Source chain transaction hash | | `destinationTxHash` | string | Destination chain transaction hash | | `status` | string | Bridge status | **Example:** ``` User: Bridge 100 USDC from Ethereum to Base Claude: I'll bridge 100 USDC from Ethereum to Base. [Uses bridge tool] Result: - Bridge initiated - Source tx: 0x4a2f... - Estimated completion: ~2 minutes ``` --- ### bridge_quote Get a bridge quote showing fees and estimated time. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `inputToken` | string | Yes | Token to bridge | | `amount` | string | Yes | Amount to bridge | | `sourceChain` | string | Yes | Source chain | | `destinationChain` | string | Yes | Destination chain | | `outputToken` | string | No | Output token | **Returns:** | Field | Type | Description | |-------|------|-------------| | `inputAmount` | string | Input amount | | `outputAmount` | string | Expected output after fees | | `fee` | string | Bridge fee | | `estimatedTime` | number | Estimated time in seconds | **Example:** ``` User: How much would it cost to bridge 1000 USDC to Arbitrum? Claude: I'll get a quote for bridging 1000 USDC to Arbitrum. [Uses bridge_quote tool] Result: - Input: 1000 USDC - Output: 998.50 USDC - Fee: 1.50 USDC - Time: ~90 seconds ``` --- ## Tokens Tools for searching and analyzing tokens. ### token_search Search for tokens by name, symbol, or address. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `query` | string | Yes | Search query (min 2 characters) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `tokens` | array | Array of matching tokens with address, name, symbol, chain, and safety info | **Example:** ``` User: Find the BONK token Claude: I'll search for BONK. [Uses token_search tool with query="BONK"] Result: - BONK (DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263) - Chain: Solana - Safety score: 85 ``` --- ### token_price Get current USD price for a token. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `token` | string | Yes | Token symbol or address | | `chain` | string | No | Chain filter | **Returns:** | Field | Type | Description | |-------|------|-------------| | `token` | string | Token identifier | | `price` | number | Current USD price | | `chain` | string | Token chain | **Example:** ``` User: What's the price of SOL? Claude: I'll check the current price of SOL. [Uses token_price tool] Result: SOL is currently $98.52 ``` --- ### token_details Get detailed information about a token including market data and safety analysis. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `address` | string | Yes | Token address | **Returns:** | Field | Type | Description | |-------|------|-------------| | `token` | object | Token info (name, symbol, decimals) | | `market` | object | Market data (price, volume, market cap) | | `safety` | object | Safety analysis (score, flags, verified) | **Example:** ``` User: Give me details on token DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 Claude: I'll get detailed information on this token. [Uses token_details tool] Result: - Name: Bonk - Price: $0.0000234 - Market Cap: $1.5B - 24h Volume: $45M - Safety Score: 85/100 - Verified: Yes ``` --- ### token_chart Get OHLCV chart data for a token. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `address` | string | Yes | Token address | **Returns:** | Field | Type | Description | |-------|------|-------------| | `data` | array | OHLCV candle data (timestamp, open, high, low, close, volume) | **Example:** ``` User: Show me the price chart for BONK Claude: I'll fetch the chart data for BONK. [Uses token_chart tool] Result: Returns OHLCV data for charting ``` --- ## Portfolio Tools for viewing holdings and transaction history. ### portfolio_get Get combined portfolio across all chains with total USD value. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `positions` | array | Array of holdings with token, balance, value, and chain | | `totalUsdValue` | number | Total portfolio value in USD | **Example:** ``` User: What's in my portfolio? Claude: I'll get your complete portfolio. [Uses portfolio_get tool] Result: - SOL: 5.23 ($515) - USDC: 150 ($150) - BONK: 1,000,000 ($23) - Total: $688 ``` --- ### portfolio_history Get transaction history. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `limit` | number | No | Max results (default 50) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `transactions` | array | Array of transactions with type, amount, token, hash, timestamp | **Example:** ``` User: Show my recent transactions Claude: I'll fetch your transaction history. [Uses portfolio_history tool] Result: - Swap: 1 SOL -> 98.52 USDC (2 hours ago) - Transfer: 50 USDC to 7xKX... (5 hours ago) - Receive: 5 SOL from 3nPq... (1 day ago) ``` --- ## DEX Tools for accessing DexScreener market data. ### dex_trending Get trending trading pairs by trending score. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `minLiquidity` | number | No | Minimum liquidity in USD | | `minSafetyScore` | number | No | Minimum safety score (0-100) | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of trending pairs with token info, price, volume, liquidity | | `pagination` | object | Pagination info | **Example:** ``` User: What's trending on Solana? Claude: I'll check the trending pairs on Solana. [Uses dex_trending tool with chain="solana"] Result: 1. WIF/SOL - $2.45 (+150%) 2. BONK/SOL - $0.000023 (+45%) 3. JUP/SOL - $0.89 (+12%) ``` --- ### dex_volume Get top trading pairs by 24h volume. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `minLiquidity` | number | No | Minimum liquidity in USD | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of pairs sorted by 24h volume | | `pagination` | object | Pagination info | **Example:** ``` User: What tokens have the highest volume today? Claude: I'll check the highest volume pairs. [Uses dex_volume tool] Result: 1. SOL/USDC - $1.2B volume 2. WIF/SOL - $450M volume 3. JUP/USDC - $120M volume ``` --- ### dex_gainers Get top price gainers (24h). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `minLiquidity` | number | No | Minimum liquidity in USD | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of pairs sorted by 24h price gain | **Example:** ``` User: What are the top gainers today? Claude: I'll check the top gainers. [Uses dex_gainers tool] Result: 1. MEME/SOL - +450% 2. NEW/SOL - +280% 3. PUMP/SOL - +150% ``` --- ### dex_losers Get top price losers (24h). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `minLiquidity` | number | No | Minimum liquidity in USD | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of pairs sorted by 24h price loss | **Example:** ``` User: What tokens dropped the most today? Claude: I'll check the top losers. [Uses dex_losers tool] Result: 1. RUG/SOL - -85% 2. DUMP/SOL - -72% 3. OLD/SOL - -45% ``` --- ### dex_new Get newly created pairs (less than 24 hours old). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `minLiquidity` | number | No | Minimum liquidity in USD | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of new pairs | | `maxAgeHours` | number | Maximum age filter applied | **Example:** ``` User: What new tokens launched today? Claude: I'll check for newly launched tokens. [Uses dex_new tool] Result: 1. NEW1/SOL - Launched 2h ago, $50K liquidity 2. NEW2/SOL - Launched 5h ago, $120K liquidity 3. NEW3/SOL - Launched 8h ago, $30K liquidity ``` --- ### dex_pumpfun Get Pumpfun trending pairs (Solana only, bonding curve tokens). **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `maxAge` | number | No | Maximum age in hours | | `maxProgress` | number | No | Maximum bonding curve progress percentage | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of Pumpfun pairs with bonding curve info | **Example:** ``` User: What's trending on Pumpfun? Claude: I'll check Pumpfun trending tokens. [Uses dex_pumpfun tool] Result: 1. PUMP1 - 75% bonding curve, $45K market cap 2. PUMP2 - 50% bonding curve, $22K market cap 3. PUMP3 - 30% bonding curve, $12K market cap ``` --- ### dex_query Advanced DEX query with custom filters and ranking. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | No | Filter by chain | | `timeframe` | string | No | Timeframe: m5, h1, h6, h24 | | `rankBy` | string | No | Ranking: volume, txns, priceChangeH24, liquidity, fdv | | `order` | string | No | Order: asc or desc | | `filters` | object | No | Range filters for liquidity, volume, etc. | | `minSafetyScore` | number | No | Minimum safety score | | `limit` | number | No | Maximum results | **Returns:** | Field | Type | Description | |-------|------|-------------| | `pairs` | array | Array of pairs matching query | | `pagination` | object | Pagination info | **Example:** ``` User: Find Solana tokens with >$100K liquidity, sorted by transactions Claude: I'll search for high-liquidity Solana tokens. [Uses dex_query tool with chain="solana", filters={minLiquidity: 100000}, rankBy="txns"] Result: 1. SOL/USDC - 15K txns, $50M liquidity 2. WIF/SOL - 8K txns, $5M liquidity 3. BONK/SOL - 6K txns, $2M liquidity ``` --- ## Tokenize Tools for launching tokens on Solana. ### tokenize_launch Launch a new token on Solana with automatic pool creation. One token per account. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `name` | string | Yes | Token name (1-32 characters) | | `symbol` | string | Yes | Token symbol (2-10 uppercase letters) | | `tier` | string | No | Market cap tier: 10k, 100k, 1m, 10m (default 100k) | | `imageUrl` | string | No | Token logo URL (PNG/JPEG, square) | **Returns:** | Field | Type | Description | |-------|------|-------------| | `success` | boolean | Whether the launch succeeded | | `launchId` | string | Unique launch identifier | | `tokenMint` | string | Token mint address | | `poolAddress` | string | Liquidity pool address | | `dexscreenerUrl` | string | DexScreener URL for the token | **Example:** ``` User: Launch a token called "My Token" with symbol MTK Claude: I'll launch your token on Solana. [Uses tokenize_launch tool] Result: - Token launched successfully! - Mint: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU - Pool: 3nPqD... - DexScreener: https://dexscreener.com/solana/7xKXtg... ``` Each account can only launch **one token ever**. This limit cannot be reset. --- ### tokenize_info Get information about your launched token. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `hasToken` | boolean | Whether the account has launched a token | | `launchId` | string | Launch identifier | | `tokenMint` | string | Token mint address | | `poolAddress` | string | Pool address | | `dexscreenerUrl` | string | DexScreener URL | **Example:** ``` User: What token did I launch? Claude: I'll check your launched token. [Uses tokenize_info tool] Result: - Token: My Token (MTK) - Mint: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU - Pool: 3nPqD... ``` --- ## Fees Tools for managing trading fees from launched tokens. ### fees_status Get fee status for your launched token including generated, claimed, and unclaimed amounts. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `totalFeesGeneratedSol` | number | Total fees generated in SOL | | `beneficiaryFeesEarnedSol` | number | Your share of fees earned | | `beneficiaryFeesClaimedSol` | number | Fees already claimed | | `beneficiaryFeesUnclaimedSol` | number | Fees available to claim | | `canClaim` | boolean | Whether fees can be claimed now | | `feeForfeitsAt` | string | Deadline for claiming before forfeiture | **Example:** ``` User: How much in fees have I earned? Claude: I'll check your fee status. [Uses fees_status tool] Result: - Total generated: 5.23 SOL - Your share: 3.14 SOL (60%) - Claimed: 1.00 SOL - Unclaimed: 2.14 SOL - Can claim: Yes ``` --- ### fees_claim Claim accumulated trading fees from your launched token (platform pays gas). **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `success` | boolean | Whether the claim succeeded | | `amountSol` | number | Amount claimed in SOL | | `txSignature` | string | Transaction signature | **Example:** ``` User: Claim my fees Claude: I'll claim your accumulated fees. [Uses fees_claim tool] Result: - Claimed 2.14 SOL - Transaction: 5xKq... ``` The platform pays gas fees for claiming, so you receive the full amount. --- ## RPC Tools for direct RPC access to supported chains. ### rpc_call Make a direct RPC call to any supported chain. **Parameters:** | Name | Type | Required | Description | |------|------|----------|-------------| | `chain` | string | Yes | Target chain | | `method` | string | Yes | RPC method name | | `params` | array | No | Method parameters | **Returns:** | Field | Type | Description | |-------|------|-------------| | `result` | any | RPC response result | | `error` | object | Error object if call failed | **Example:** ``` User: Get the latest Solana block height Claude: I'll make an RPC call to get the block height. [Uses rpc_call tool with chain="solana", method="getBlockHeight"] Result: Block height: 245,892,341 ``` --- ### rpc_chains Get list of supported chains for RPC access. **Parameters:** None **Returns:** | Field | Type | Description | |-------|------|-------------| | `chains` | array | Array of supported chain names | **Example:** ``` User: What chains support RPC calls? Claude: I'll check the supported chains. [Uses rpc_chains tool] Result: Supported chains: solana, ethereum, base, arbitrum, optimism, polygon, bsc ``` --- # Trading > Swaps, transfers, and bridges with the SDK URL: https://docs.loomlay.com/sdk/trading # Trading The `trading` resource handles swaps, transfers, and cross-chain bridges. ## Supported DEXes | Chain | DEX Provider | Features | |-------|--------------|----------| | Solana | Jupiter | Best price routing across all Solana DEXes | | Ethereum | Relay | Cross-chain swaps and bridges | | Base | Relay | Cross-chain swaps and bridges | | Arbitrum | Relay | Cross-chain swaps and bridges | ## Self-Custody Signing Flow In self-custody mode (`walletMode: 'local'`), swaps and transfers follow a build → sign → submit flow where signing happens locally: ``` ┌─────────┐ ┌─────────┐ ┌─────────────┐ ┌─────────┐ │ Your │────>│ API │────>│ Your │────>│ API │ │ App │ │ Server │ │ Device │ │ Server │ │ │ │ │ │ (signing) │ │ │ │ swap() │ │ /build │ │ sign tx │ │ /execute│ └─────────┘ └─────────┘ └─────────────┘ └─────────┘ ``` 1. **Build**: API builds an unsigned transaction (no private keys needed) 2. **Sign**: SDK decrypts your local wallet and signs the transaction on your device 3. **Submit**: Signed transaction sent to API for blockchain submission This is handled automatically — the same `swap()` and `transfer()` API works in both modes. EVM chain operations (bridges) currently use custodial mode regardless of your `walletMode` setting. Local EVM signing is planned for a future release. ## Swaps Swap tokens on the same chain: ```typescript const result = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1.5', slippage: 0.5, // Optional, default 0.5% }); console.log('Input:', result.inputAmount, 'SOL'); console.log('Output:', result.outputAmount, 'USDC'); console.log('Transaction:', result.txHash); ``` ### Slippage Recommendations | Token Type | Recommended Slippage | Notes | |------------|---------------------|-------| | Stablecoins (USDC, USDT) | 0.1% - 0.5% | Low volatility, tight spreads | | Major tokens (SOL, ETH) | 0.5% - 1% | Moderate volatility | | Volatile/low liquidity | 1% - 3% | Higher slippage needed to ensure execution | | Meme tokens | 3% - 5%+ | High volatility, consider using `quoteOnly` first | **Price Impact Warning:** Always check `priceImpact` in the quote response before executing large trades. A price impact above 1% indicates significant market movement. Above 5% suggests you should consider splitting the trade into smaller amounts. ### Quote Only Get a quote without executing: ```typescript const quote = await wallet.trading.swap({ inputToken: 'SOL', outputToken: 'USDC', amount: '1.5', quoteOnly: true, }); console.log('Expected output:', quote.outputAmount, 'USDC'); console.log('Price impact:', quote.priceImpact, '%'); ``` ### EVM Swaps ```typescript const result = await wallet.trading.swap({ inputToken: 'ETH', outputToken: 'USDC', amount: '0.1', chain: 'ethereum', // Specify chain for EVM }); ``` **Gas Estimation:** On EVM chains, gas fees are estimated automatically based on current network conditions. The SDK uses a priority fee multiplier to ensure timely execution. During high congestion, transactions may take longer or require higher gas. Consider using `quoteOnly` to preview the expected gas cost before executing. ## Transfers Send tokens to another address: ```typescript const result = await wallet.trading.transfer({ to: 'recipient_address', token: 'USDC', amount: '100', chain: 'solana', }); console.log('Sent:', result.amount, result.token); console.log('Transaction:', result.txHash); ``` ### Send Native Tokens ```typescript // Send SOL await wallet.trading.transfer({ to: 'recipient', token: 'SOL', amount: '1', chain: 'solana', }); // Send ETH await wallet.trading.transfer({ to: '0x...', token: 'ETH', amount: '0.1', chain: 'ethereum', }); ``` ## Bridges Bridge tokens between EVM chains: ```typescript const result = await wallet.trading.bridge({ fromChain: 'ethereum', toChain: 'base', token: 'USDC', amount: '100', }); console.log('Bridge initiated'); console.log('Source tx:', result.sourceTxHash); console.log('Estimated time:', result.estimatedTime); ``` Bridges are only available between EVM chains. Solana bridges are not yet supported. ## Token Resolution The SDK resolves token names to addresses: ```typescript // All these work await wallet.trading.swap({ inputToken: 'SOL', ... }); await wallet.trading.swap({ inputToken: 'USDC', ... }); await wallet.trading.swap({ inputToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC address ... }); ``` ## Type Definitions ```typescript interface SwapParams { inputToken: string; outputToken: string; amount: string; chain?: string; slippage?: number; quoteOnly?: boolean; } interface SwapResult { inputAmount: string; outputAmount: string; txHash?: string; chain: string; priceImpact?: number; } interface TransferParams { to: string; token: string; amount: string; chain: string; } interface BridgeParams { fromChain: string; toChain: string; token: string; amount: string; } ``` --- # Wallet Management > Creating and managing wallets with the SDK URL: https://docs.loomlay.com/sdk/wallet # Wallet Management The SDK provides a `wallet` resource for managing multi-chain wallets. It supports two modes: | Mode | Keys Stored | Signing | Best For | |------|-------------|---------|----------| | `local` (self-custody) | Client-side (`~/.loomlay/wallet.json`) | Client | Maximum security, self-custody | | `custodial` | Server-side (encrypted in PostgreSQL) | Server | Simple integration | ## Wallet Modes ### Self-Custody Mode (Recommended) In self-custody mode, private keys are generated and encrypted locally on your device. They are never sent to any server. The API only receives public addresses for balance lookups. ```typescript const wallet = new OpenClawWallet({ apiKey: 'agent_xxx', walletMode: 'local', getPassphrase: async () => process.env.LOOMLAY_WALLET_PASSPHRASE!, }); ``` ### Custodial Mode In custodial mode, the API manages keys server-side. This is simpler but requires trusting the server with your keys. ```typescript const wallet = new OpenClawWallet({ apiKey: 'agent_xxx', // walletMode defaults to 'custodial' in SDK }); ``` The OpenClaw Plugin defaults to **self-custody** (`walletMode: 'local'`). The SDK defaults to `'custodial'` for backwards compatibility. ## Create a Wallet ```typescript // Keys generated and encrypted locally const created = await wallet.wallet.create(); console.log('Seed phrase:', created.seedPhrase); // Save securely! console.log('Solana:', created.wallet.solanaAddress); console.log('EVM:', created.wallet.evmAddress); // Public addresses auto-registered with API ``` ```typescript const created = await wallet.wallet.create(); console.log('Seed phrase:', created.seedPhrase); console.log('Solana:', created.solanaAddress); console.log('EVM:', created.evmAddress); ``` The seed phrase is the only way to recover your wallet. Store it securely and never share it. **Security Best Practices:** - Never log or print seed phrases in production code - Store seed phrases in encrypted secret managers (e.g., AWS Secrets Manager, HashiCorp Vault) - Never commit seed phrases to version control - Use environment variables only for development; use proper secrets management in production ## Supported Chains The SDK derives addresses for multiple chains from a single BIP39 seed phrase: | Chain | Derivation Path | Curve | Address Format | |-------|-----------------|-------|----------------| | Solana | `m/44'/501'/0'/0'` | ed25519 | Base58 | | Ethereum | `m/44'/60'/0'/0/0` | secp256k1 | 0x-prefixed hex | | Base | Same as Ethereum | secp256k1 | 0x-prefixed hex | | Arbitrum | Same as Ethereum | secp256k1 | 0x-prefixed hex | All EVM chains share the same address derived from the secp256k1 curve. Solana uses a separate ed25519-based address. ## Get Wallet Info ```typescript const info = await wallet.wallet.get(); console.log('Addresses:', { solana: info.solanaAddress, evm: info.evmAddress, }); // Solana balances console.log('SOL:', info.balances.solana.native); for (const token of info.balances.solana.tokens) { console.log(`${token.symbol}: ${token.balance}`); } // EVM balances (aggregated across chains) console.log('ETH:', info.balances.ethereum.native); ``` **Balance Caching:** Balances are fetched in real-time from chain RPC nodes and portfolio APIs. For high-frequency applications, consider caching balances locally and refreshing periodically (e.g., every 30 seconds) to reduce API calls. ## Import an Existing Wallet Import an existing seed phrase into a local self-custody wallet (self-custody mode only): ```typescript const imported = await wallet.wallet.importSeed( 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', 'my-secure-passphrase' ); console.log('Imported:', imported.wallet.solanaAddress); // Addresses auto-registered with API ``` ## Register External Addresses Register externally-managed wallet addresses with the API for balance lookups: ```typescript await wallet.wallet.register({ solanaAddress: 'your-solana-address', evmAddress: '0xyour-evm-address', // Optional }); ``` ## Export Private Keys Only export keys when absolutely necessary. Exposing private keys risks losing all funds. ```typescript // Decrypts locally using passphrase — no API call needed const keys = await wallet.wallet.exportKeys('any-seed-phrase'); console.log('Solana private key:', keys.solana.privateKey); console.log('EVM private key:', keys.evm.privateKey); ``` ```typescript const keys = await wallet.wallet.exportKeys('your twelve word seed phrase here'); console.log('Solana private key:', keys.solana.privateKey); console.log('EVM private key:', keys.evm.privateKey); ``` ## Portfolio View Get a comprehensive view of holdings across all chains: ```typescript const portfolio = await wallet.portfolio.get(); for (const holding of portfolio.holdings) { console.log(`${holding.symbol} on ${holding.chain}`); console.log(` Balance: ${holding.balance}`); console.log(` Value: $${holding.valueUsd}`); } console.log('Total portfolio value:', portfolio.totalValueUsd); ``` ## Transaction History ```typescript const history = await wallet.portfolio.history({ limit: 20, chain: 'solana', // Optional filter }); for (const tx of history.transactions) { console.log(`${tx.type}: ${tx.amount} ${tx.token}`); console.log(` Hash: ${tx.txHash}`); console.log(` Time: ${tx.timestamp}`); } ``` ## Type Definitions ```typescript interface WalletCreateResult { seedPhrase: string; solanaAddress: string; evmAddress: string; } interface WalletInfo { solanaAddress: string; evmAddress: string; balances: { solana: ChainBalance; ethereum: ChainBalance; // ... other chains }; } interface ChainBalance { native: string; tokens: TokenBalance[]; } interface TokenBalance { address: string; symbol: string; name: string; balance: string; decimals: number; } ``` --- # WebSockets > Real-time data subscriptions with the SDK URL: https://docs.loomlay.com/sdk/websockets # WebSockets The SDK provides typed WebSocket clients for real-time data. ## Connection Lifecycle WebSocket connections follow this lifecycle: 1. **Connect** - Establish connection to the server 2. **Authenticate** - API key is validated on first message 3. **Subscribe** - Register for specific data channels 4. **Receive** - Data is pushed to your callbacks 5. **Unsubscribe** - Remove specific subscriptions 6. **Disconnect** - Close the connection ``` ┌─────────┐ ┌──────────────┐ ┌───────────┐ ┌─────────┐ │ connect │───>│ authenticate │───>│ subscribe │───>│ receive │ └─────────┘ └──────────────┘ └───────────┘ └────┬────┘ │ ┌────────────┐ ┌─────────────┐ │ │ disconnect │<───│ unsubscribe │<──┘ └────────────┘ └─────────────┘ ``` ## DEX WebSocket Subscribe to real-time market data: ```typescript const dexWs = wallet.createDexWebSocket(); // Connect await dexWs.connect(); // Subscribe to trending pairs const subId = await dexWs.subscribe( { chain: 'solana', minLiquidity: 10000 }, (pairs) => { console.log('Trending pairs updated:', pairs.length); for (const pair of pairs) { console.log(`${pair.baseToken.symbol}: $${pair.priceUsd}`); } } ); // Later: unsubscribe and disconnect dexWs.unsubscribe(subId); dexWs.disconnect(); ``` ### Heartbeat / Ping The server sends periodic ping frames to keep the connection alive. The SDK handles pong responses automatically. If no ping is received for 60 seconds, the connection is considered stale and will be closed. **Max Subscriptions:** Each WebSocket connection supports up to **50 active subscriptions**. If you need more, open additional connections. Subscriptions are counted per connection, not per API key. ### Subscription Filters ```typescript await dexWs.subscribe( { chain: 'solana', minLiquidity: 10000, // Minimum USD liquidity minVolume: 5000, // Minimum 24h volume channel: 'trending', // trending, gainers, losers, new }, (pairs) => console.log(pairs) ); ``` ### Multiple Subscriptions ```typescript // Subscribe to multiple channels const trendingId = await dexWs.subscribe( { channel: 'trending', chain: 'solana' }, handleTrending ); const gainersId = await dexWs.subscribe( { channel: 'gainers', chain: 'solana' }, handleGainers ); // Unsubscribe individually dexWs.unsubscribe(trendingId); dexWs.unsubscribe(gainersId); // Or unsubscribe all dexWs.unsubscribeAll(); ``` ## Chain WebSocket Subscribe to on-chain events: ```typescript const chainWs = wallet.createChainWebSocket('solana'); await chainWs.connect(); // Subscribe to account changes const subId = await chainWs.subscribe( 'accountSubscribe', ['wallet_address', { encoding: 'jsonParsed' }], (data) => { console.log('Account updated:', data); } ); // Unsubscribe await chainWs.unsubscribe(subId); chainWs.disconnect(); ``` ### Solana Subscriptions ```typescript // Account changes await chainWs.subscribe('accountSubscribe', [address], callback); // Program logs await chainWs.subscribe('logsSubscribe', [{ mentions: [programId] }], callback); // Slot updates await chainWs.subscribe('slotSubscribe', [], callback); ``` ## Reconnection Both WebSocket clients support automatic reconnection: ```typescript const dexWs = wallet.createDexWebSocket({ reconnect: true, maxReconnectAttempts: 5, reconnectDelay: 1000, // Base delay in ms (uses exponential backoff) }); ``` ### Reconnection Best Practices **Important:** Subscriptions are NOT automatically restored after reconnection. You must re-subscribe to channels after the `connected` event fires. ```typescript const dexWs = wallet.createDexWebSocket({ reconnect: true, maxReconnectAttempts: 5, reconnectDelay: 1000, }); // Track active subscriptions for re-subscription const activeSubscriptions: DexSubscriptionParams[] = []; dexWs.on('connected', async () => { console.log('Connected - restoring subscriptions'); // Re-subscribe to all channels after reconnection for (const params of activeSubscriptions) { await dexWs.subscribe(params, handleData); } }); dexWs.on('disconnected', () => { console.log('Disconnected - will attempt reconnection'); }); dexWs.on('reconnecting', (attempt) => { console.log(`Reconnection attempt ${attempt} of 5`); }); // Store subscription params when subscribing const params = { channel: 'trending', chain: 'solana' }; activeSubscriptions.push(params); await dexWs.subscribe(params, handleData); ``` ### Exponential Backoff Reconnection uses exponential backoff with jitter: | Attempt | Base Delay | With Jitter (approx) | |---------|------------|---------------------| | 1 | 1s | 1-1.5s | | 2 | 2s | 2-3s | | 3 | 4s | 4-6s | | 4 | 8s | 8-12s | | 5 | 16s | 16-24s | After `maxReconnectAttempts` is reached, the client stops reconnecting and emits an `error` event. ### Connection Events ```typescript dexWs.on('connected', () => console.log('Connected')); dexWs.on('disconnected', () => console.log('Disconnected')); dexWs.on('reconnecting', (attempt) => console.log(`Reconnecting... attempt ${attempt}`)); dexWs.on('error', (error) => console.error('Error:', error)); ``` ## Type Definitions ```typescript interface DexWebSocketOptions { reconnect?: boolean; maxReconnectAttempts?: number; reconnectDelay?: number; } interface DexSubscriptionParams { chain?: string; channel?: 'trending' | 'gainers' | 'losers' | 'new'; minLiquidity?: number; minVolume?: number; } interface ChainWebSocketOptions { reconnect?: boolean; maxReconnectAttempts?: number; reconnectDelay?: number; } ```