Universal cross-chain swap & bridge skill for OpenClaw using the NEAR Intents 1Click SDK. Supports 14+ blockchains including NEAR, Base, Ethereum, Solana, and Bitcoin.
What it does: Universal cross-chain swap & bridge tool powered by the 1Click API and the @defuse-protocol/one-click-sdk-typescript SDK.
Supported chains: NEAR, Base, Ethereum, Arbitrum, Solana, BSC, Gnosis, Starknet, Bitcoin, Dogecoin, Zcash, Litecoin.
How it works:
Key facts:
All swaps go through the 1Click API (https://1click.chaindefuser.com):
User Wallet βββΊ [Deposit to 1Click address] βββΊ Market Makers βββΊ Recipient on Destination Chain
There is no need to interact with intents.near directly β the 1Click API abstracts everything.
executeIntent() APIThe single entry point exported by index.ts:
import { executeIntent } from './index';
const result = await executeIntent({
assetIn: 'NEAR', // Origin token (see Asset Naming below)
assetOut: 'base:USDC', // Destination token
amount: '1.0', // Human-readable amount
recipient: '0x...', // Destination address (optional if same-chain NEAR)
mode: 'auto', // 'auto' (default) or 'manual'
swapType: 'EXACT_INPUT', // 'EXACT_INPUT' (default) or 'EXACT_OUTPUT'
});
| Parameter | Type | Required | Description |
|---|---|---|---|
assetIn | string | β | Origin asset symbol (e.g., 'NEAR', 'base:USDC', 'arb:ARB') |
assetOut | string | β | Destination asset symbol |
amount | string | β | Human-readable amount (e.g., '1.0', '0.5') |
recipient | string | β | Destination address. Required for cross-chain. Defaults to NEAR account |
refundAddress | string | β οΈ | REQUIRED for non-NEAR origins. Address on origin chain for refunds if swap fails. CRITICAL for fund safety! |
mode | string | β | 'auto' sends deposit automatically from NEAR account. 'manual' returns quote + deposit address for user to send manually |
swapType | string | β | 'EXACT_INPUT' (amount = input), 'EXACT_OUTPUT' (amount = desired output) |
When assetIn is on a non-NEAR chain (e.g., 'base:USDC', 'arb:ARB', 'btc:BTC'):
refundAddress is REQUIRED β the function will throw an error if missingExample:
// β WRONG - Missing refundAddress for non-NEAR origin
await executeIntent({
assetIn: 'base:USDC', // Base origin
assetOut: 'NEAR',
amount: '0.5',
recipient: 'user.near',
mode: 'manual'
});
// β Error: Cross-chain swap from base:USDC requires refundAddress parameter
// β
CORRECT - User's Base wallet address provided
await executeIntent({
assetIn: 'base:USDC',
assetOut: 'NEAR',
amount: '0.5',
recipient: 'user.near',
refundAddress: '0x123...', // User's Base address
mode: 'manual'
});
Why this matters:
refundAddress on the origin chainrefundAddress is wrong or belongs to someone else, funds are permanently lost"Swap Successful! 1.0 NEAR β 0.97 USDC\nTransaction: https://nearblocks.io/txns/...\nExplorer: https://explorer.near-intents.org/transactions/..."Use chain:SYMBOL format. Omit chain prefix for NEAR-native tokens.
| Chain | Prefix | Examples |
|---|---|---|
| NEAR | (none) | NEAR, USDC, USDT, wNEAR |
| Base | base: | base:USDC |
| Ethereum | eth: | eth:ETH, eth:USDC |
| Arbitrum | arb: | arb:USDC, arb:ARB |
| Solana | sol: | sol:SOL, sol:USDC |
| BSC | bsc: | bsc:USDC |
| Bitcoin | btc: | btc:BTC (native only) |
| Dogecoin | doge: | doge:DOGE (native only) |
| Zcash | zec: | zec:ZEC (native only) |
| Litecoin | ltc: | ltc:LTC (native only) |
near, NEAR, Near all workAutomatically sends the deposit from the configured NEAR account.
Use when: Origin asset is on NEAR and agent has NEAR credentials in .env.
await executeIntent({
assetIn: 'NEAR',
assetOut: 'base:USDC',
amount: '1.0',
recipient: '0xYourBaseAddress',
});
Returns a quote with deposit address β the user (or agent) sends tokens separately.
Use when: Origin is on a non-NEAR chain, or you want to show the user a quote first.
const quote = await executeIntent({
assetIn: 'arb:USDC',
assetOut: 'sol:USDC',
amount: '5.0',
recipient: 'YourSolanaAddress',
mode: 'manual',
});
// Returns deposit address + instructions
Specify the desired output amount; the 1Click API tells you how much to send.
const quote = await executeIntent({
assetIn: 'USDT',
assetOut: 'base:USDC',
amount: '10.0', // Want exactly 10 USDC out
recipient: '0x...',
mode: 'manual',
swapType: 'EXACT_OUTPUT',
});
await executeIntent({
assetIn: 'NEAR',
assetOut: 'base:USDC',
amount: '1.0',
recipient: '0xYourBaseAddress',
});
const quote = await executeIntent({
assetIn: 'arb:USDC',
assetOut: 'sol:USDC',
amount: '5.0',
recipient: 'YourSolanaAddress',
refundAddress: '0xYourArbitrumAddress', // REQUIRED for refunds
mode: 'manual',
});
// User sends 5 USDC to the deposit address on Arbitrum
await executeIntent({
assetIn: 'NEAR',
assetOut: 'USDC',
amount: '2.0',
});
const quote = await executeIntent({
assetIn: 'NEAR',
assetOut: 'arb:USDC',
amount: '10.0',
recipient: '0xYourArbAddress',
mode: 'manual',
swapType: 'EXACT_OUTPUT',
});
const quote = await executeIntent({
assetIn: 'btc:BTC',
assetOut: 'NEAR',
amount: '0.01',
recipient: 'yourname.near',
refundAddress: 'bc1q...', // REQUIRED - Your Bitcoin address
mode: 'manual',
});
// User sends 0.01 BTC to the deposit address on Bitcoin
.env file (only needed for auto mode with NEAR origin):NEAR_ACCOUNT_ID=your-account.near
NEAR_PRIVATE_KEY=ed25519:your_private_key_here
NEAR_RPC_URL=https://rpc.mainnet.fastnear.com
NEAR_NETWORK_ID=mainnet
ONE_CLICK_JWT=optional_jwt_token
ONE_CLICK_JWT: Register at partners.near-intents.org to avoid the 0.2% fee..env entirely if only using manual mode for non-NEAR-origin swaps.β οΈ Never commit .env to version control!
executeIntent()
β
ββ 1. resolveToken(assetIn) β { symbol, decimals, assetId }
ββ 2. resolveToken(assetOut) β { symbol, decimals, assetId }
ββ 3. toSmallestUnit(amount, decimals)
β
ββ 4. OneClickService.getQuote({
β originAsset, destinationAsset, amount,
β refundTo, recipient, deadline, ...
β })
β β Returns { depositAddress, amountIn, amountOut }
β
ββ [manual mode] β return quote instructions
β
ββ 5. account.transfer() β send deposit to depositAddress
ββ 6. OneClickService.submitDepositTx() β (optional, speeds up)
ββ 7. OneClickService.getExecutionStatus() β poll until SUCCESS
| Status | Meaning |
|---|---|
PENDING_DEPOSIT | Waiting for deposit |
PROCESSING | Deposit detected, market makers executing |
SUCCESS | Tokens delivered to recipient |
INCOMPLETE_DEPOSIT | Deposit below required amount |
REFUNDED | Swap failed, tokens returned to refund address |
FAILED | Swap failed due to error |
The code includes a static TOKEN_MAP for common tokens:
| Key | Asset ID (NEP-141) | Decimals |
|---|---|---|
NEAR | nep141:wrap.near | 24 |
USDC | nep141:17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1 | 6 |
USDT | nep141:usdt.tether-token.near | 6 |
base:USDC | nep141:base-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.omft.near | 6 |
arb:USDC | nep141:arb-0xaf88d065e77c8cc2239327c5edb3a432268e5831.omft.near | 6 |
arb:ARB | nep141:arb-0x912ce59144191c1204e64559fe8253a0e49e6548.omft.near | 18 |
eth:ETH | nep141:eth.omft.near | 18 |
eth:USDC | nep141:eth-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.omft.near | 6 |
sol:SOL | nep141:sol.omft.near | 9 |
sol:USDC | nep141:sol-5ce3bf3a31af18be40ba30f721101b4341690186.omft.near | 6 |
To add more tokens: use OneClickService.getTokens() or check TOKENS.md.
| Token | Decimals | "1.0" β smallest unit |
|---|---|---|
| NEAR | 24 | 1000000000000000000000000 |
| USDC | 6 | 1000000 |
| USDT | 6 | 1000000 |
| ETH | 18 | 1000000000000000000 |
| SOL | 9 | 1000000000 |
| BTC | 8 | 100000000 |
Decimal conversion is handled automatically by index.ts using decimal.js.
https://nearblocks.io/txns/<txHash>https://explorer.near-intents.org/transactions/<depositAddress>| Error | Solution |
|---|---|
Token not found: X | Check symbol and chain prefix. See TOKEN_MAP or TOKENS.md |
No deposit address in quote response | Solver couldn't match the pair/amount. Try a different amount or pair |
NEAR_ACCOUNT_ID and NEAR_PRIVATE_KEY must be set | Configure .env or use mode: 'manual' |
Swap failed with status: REFUNDED | Tokens returned to refund address. Retry with different amount |
Status polling timed out | Check explorer URL manually. Swap may still complete |
| 401 Authentication error | JWT is invalid or expired. Register at partners.near-intents.org |
{
"@defuse-protocol/one-click-sdk-typescript": "0.1.1",
"@near-js/accounts": "^2.2.4",
"@near-js/crypto": "^2.2.4",
"@near-js/providers": "^2.2.4",
"@near-js/signers": "^2.2.4",
"@near-js/tokens": "^2.2.4",
"decimal.js": "^10.4.3",
"dotenv": "^16.3.1"
}
| File | Purpose |
|---|---|
index.ts | Main entry β exports executeIntent() |
lib-1click/ | Step-by-step 1Click SDK examples (get tokens, get quote, send deposit, etc.) |
SKILL.md | This file β primary AI agent reference |
AI-AGENT-GUIDE.md | Detailed agent workflow guide |
TOKENS.md | Full token reference with decimals and asset IDs |
manifest.json | Skill manifest for OpenClaw |
README.md | Project documentation |
USAGE_GUIDE.md | Usage patterns and troubleshooting |
v2.0.0 β Powered by 1Click SDK and NEAR Intents
MIT