
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@clawswap/sdk
Advanced tools
Gasless cross-chain token swaps for AI agents via x402 micropayments. Solana ↔ Base bidirectional. No API key, no gas management.
Framework-agnostic TypeScript SDK for bidirectional Solana ↔ Base cross-chain token swaps.
To use the ClawSwap SDK, you need:
See the main README for detailed wallet setup instructions.
npm install @clawswap/sdk
# For Solana → Base (x402 payment + Solana signing)
npm install @clawswap/sdk @x402/fetch @x402/core @x402/svm @solana/signers @solana/web3.js bs58
# For Base → Solana (EVM signing only, no x402 needed)
npm install @clawswap/sdk viem
Create .env file:
# For Solana → Base swaps
SOLANA_PRIVATE_KEY=your_base58_key_here
# For Base → Solana swaps
EVM_PRIVATE_KEY=0xyour_hex_private_key_here
| Variable | Required | Description |
|---|---|---|
SOLANA_PRIVATE_KEY | For Solana → Base | Base58-encoded Solana private key |
EVM_PRIVATE_KEY | For Base → Solana | 0x-prefixed hex EVM private key |
Security: Add .env to .gitignore.
Solana → Base: 0.5 USDC + 0.01 SOL on Solana
Base → Solana: USDC + small ETH ($0.001) on Base
import { ClawSwapClient } from '@clawswap/sdk';
import { wrapFetchWithPayment } from '@x402/fetch';
import { x402Client } from '@x402/core/client';
import { registerExactSvmScheme } from '@x402/svm/exact/client';
import { createKeyPairSignerFromBytes } from '@solana/signers';
import { Connection, Transaction, Keypair } from '@solana/web3.js';
import bs58 from 'bs58';
import 'dotenv/config';
// 1. Setup x402 payment (Solana-source swaps require $0.50 USDC fee)
const secretKey = bs58.decode(process.env.SOLANA_PRIVATE_KEY!);
const signer = await createKeyPairSignerFromBytes(secretKey);
const x402 = new x402Client();
registerExactSvmScheme(x402, {
signer,
networks: ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'],
x402Versions: [2, 1],
});
const fetchWithPayment = wrapFetchWithPayment(fetch, x402);
const client = new ClawSwapClient({ fetch: fetchWithPayment });
// 2. Execute swap
const swap = await client.executeSwap({
sourceChain: 'solana',
sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
destinationChain: 'base',
destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
amount: '1000000', // 1 USDC (6 decimals)
userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
});
// 3. Sign and submit (Solana source returns base64 string)
const connection = new Connection('https://api.mainnet-beta.solana.com');
const tx = Transaction.from(Buffer.from(swap.transaction as string, 'base64'));
const keypair = Keypair.fromSecretKey(secretKey);
tx.partialSign(keypair);
const signature = await connection.sendRawTransaction(tx.serialize());
await connection.confirmTransaction(signature);
// 4. Wait for completion
const result = await client.waitForSettlement(swap.requestId);
console.log(`Swap ${result.status}!`);
import { ClawSwapClient, isEvmSource } from '@clawswap/sdk';
import { createWalletClient, createPublicClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
import 'dotenv/config';
// 1. No x402 setup needed for Base-source swaps
const client = new ClawSwapClient();
// 2. Execute swap
const swap = await client.executeSwap({
sourceChain: 'base',
sourceToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
destinationChain: 'solana',
destinationToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: '1000000',
userWallet: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
recipient: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
});
// 3. Sign and submit (Base source returns ordered transactions array)
if (isEvmSource(swap)) {
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY! as `0x${string}`);
const wallet = createWalletClient({ account, chain: base, transport: http() });
const publicClient = createPublicClient({ chain: base, transport: http() });
for (const tx of swap.transactions!) {
const txHash = await wallet.sendTransaction({
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value),
});
await publicClient.waitForTransactionReceipt({ hash: txHash });
console.log(`Transaction: https://basescan.org/tx/${txHash}`);
}
}
// 4. Wait for completion
const result = await client.waitForSettlement(swap.requestId);
console.log(`Swap ${result.status}!`);
waitForSettlement() polls until swap completesx402 is a micropayment protocol that enables pay-per-use API access with cryptocurrency:
x402 is only required for Solana-source swaps. When you wrap your fetch with wrapFetchWithPayment(fetch, x402), it automatically handles payment for the /api/swap/execute endpoint. Base-source swaps use plain fetch with no payment.
Learn more at x402.org
ClawSwapClientnew ClawSwapClient(config?: ClawSwapConfig)
Config Options:
baseUrl? - API base URL (default: https://api.clawswap.dev)fetch? - Custom fetch implementation (default: globalThis.fetch)timeout? - Request timeout in ms (default: 30000)headers? - Custom headers for all requestsgetQuote(request: QuoteRequest): Promise<QuoteResponse>Get a quote for a cross-chain swap. Free endpoint.
const quote = await client.getQuote({
sourceChain: 'solana',
sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
destinationChain: 'base',
destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
amount: '1000000', // 1 USDC (6 decimals)
userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
slippageTolerance: 0.01, // Optional, 1%
});
executeSwap(request: QuoteRequest): Promise<ExecuteSwapResponse>Execute a cross-chain swap. Solana-source swaps require $0.50 USDC via x402. Base-source swaps are free.
Accepts the same parameters as getQuote(). The API fetches a fresh quote internally, so no quote expiry issues.
Returns transaction data that must be signed and submitted:
transaction is a base64 string → deserialize, sign, submit to Solana RPCtransactions is an ordered array of EvmTransaction objects → execute sequentially with viem/ethersimport { isEvmSource, isSolanaSource } from '@clawswap/sdk';
const response = await client.executeSwap({ /* ... */ });
if (isEvmSource(response)) {
// Base source → execute transactions in order (approve, then bridge)
for (const tx of response.transactions) {
// sign with viem and submit to Base
}
} else if (isSolanaSource(response)) {
// Solana source → deserialize base64, sign, submit to Solana
}
console.log(response.requestId); // Use for status tracking
getStatus(requestId: string): Promise<StatusResponse>Check the status of a swap using the request ID. Free endpoint.
// Use requestId from executeSwap response
const status = await client.getStatus(response.requestId);
console.log(status.status); // 'pending' | 'submitted' | 'filling' | 'completed' | 'failed'
waitForSettlement(requestId: string, options?): Promise<StatusResponse>Poll until swap reaches a terminal state (completed/failed).
// Use requestId from executeSwap response
const result = await client.waitForSettlement(response.requestId, {
timeout: 300000, // 5 minutes (default)
interval: 3000, // Poll every 3 seconds (default)
onStatusUpdate: (status) => {
console.log(`Current status: ${status.status}`);
},
});
getSupportedChains(): Promise<Chain[]>Get list of supported blockchains. Free endpoint, cached 1 hour.
const chains = await client.getSupportedChains();
getSupportedTokens(chainId: string): Promise<Token[]>Get tokens supported on a specific chain. Free endpoint, cached 1 hour.
const tokens = await client.getSupportedTokens('solana');
getSupportedPairs(): Promise<TokenPair[]>Get all valid cross-chain swap pairs. Derives pairs from chains and tokens. Results are cached for 1 hour.
const pairs = await client.getSupportedPairs();
// Returns array of { sourceChain, sourceToken, destinationChain, destinationToken }
The SDK throws typed errors for specific failure scenarios:
import {
ClawSwapError,
InsufficientLiquidityError,
PaymentRequiredError
} from '@clawswap/sdk';
try {
await client.executeSwap(request);
} catch (error) {
if (error instanceof InsufficientLiquidityError) {
console.error('Not enough liquidity:', error.suggestion);
} else if (error instanceof PaymentRequiredError) {
console.error('Payment failed:', error.message);
} else if (error instanceof ClawSwapError) {
console.error(`Error ${error.code}:`, error.message);
}
}
Available Error Classes:
MissingFieldError - Required field missing from requestUnsupportedChainError - Chain not supportedUnsupportedRouteError - Token pair/route not supportedQuoteFailedError - Failed to get quoteInsufficientLiquidityError - Not enough liquidity for swapAmountTooLowError / AmountTooHighError - Amount outside limitsGasExceedsThresholdError - Gas cost exceeds safety thresholdRelayUnavailableError - Relay bridge service unavailablePaymentRequiredError - x402 payment required (Solana-source swaps)RateLimitExceededError - Too many requestsNetworkError - Network request failedTimeoutError - Request or polling timed outThe SDK works with standard fetch too (for free endpoints):
const client = new ClawSwapClient(); // Uses global fetch
// Free endpoints work without x402
const chains = await client.getSupportedChains();
const tokens = await client.getSupportedTokens('solana');
const quote = await client.getQuote(request);
// Solana-source executeSwap requires x402-wrapped fetch (PaymentRequiredError otherwise)
// Base-source executeSwap works with plain fetch (no x402 payment needed)
The SDK is written in TypeScript with full type definitions included.
import type { QuoteResponse, SwapStatus } from '@clawswap/sdk';
const quote: QuoteResponse = await client.getQuote(request);
const status: SwapStatus = 'completed';
MIT
FAQs
Gasless cross-chain token swaps for AI agents via x402 micropayments. Solana ↔ Base bidirectional. No API key, no gas management.
The npm package @clawswap/sdk receives a total of 12 weekly downloads. As such, @clawswap/sdk popularity was classified as not popular.
We found that @clawswap/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.