Install
openclaw skills install impossible-financeClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
BSC (Binance Smart Chain) trading on Impossible Finance DEX - wallet registration, swaps, discover tokens and pairs, funding.
openclaw skills install impossible-financeThis skill lets the AI agent create a BSC wallet (private key + address saved in one file), discover which tokens and swaps are available on Impossible Finance DEX, swap tokens, and receive top-ups from the user. The agent is not limited to specific tokens — it can resolve token addresses and check which pairs have liquidity.
Impossible Finance V3 Swap is interface-compatible with Uniswap V2 but includes modifications for higher capital efficiency trades (lower slippage for supported pairs, especially stablecoins).
export BSC_RPC_URL="https://bsc-dataseed1.binance.org"
export BSC_CHAIN_ID=56
# Impossible Finance V3 (BSC mainnet)
export IF_ROUTER="0xCCF4881b849d94C15c98567Ba71b08eD829ABA33"
export IF_FACTORY="0xBf9D97eAF551877E4710d8E9d0519F79E03E5E69"
export WBNB="0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
Block explorer: https://bscscan.com
Impossible Finance Swap UI: https://app.impossible.finance/swap
Prerequisite: Node.js 18+ with ethers (v6):
npm install ethers
# or: pnpm add ethers
The agent needs one file that stores both the private key and public address so it can sign transactions. Create it once and reuse it.
Run this script to generate a new wallet and write it to a file:
node -e "
const fs = require('fs');
const path = require('path');
const { ethers } = require('ethers');
const wallet = ethers.Wallet.createRandom();
const dir = process.env.HOME + '/.config/impossible_agent';
fs.mkdirSync(dir, { recursive: true });
const file = dir + '/wallet.json';
fs.writeFileSync(file, JSON.stringify({
privateKey: wallet.privateKey,
address: wallet.address,
publicKey: wallet.publicKey
}, null, 2));
console.log('Wallet saved to ' + file);
console.log('Address: ' + wallet.address);
"
Default file location: ~/.config/impossible_agent/wallet.json.
File format (wallet.json):
{
"privateKey": "0x...",
"address": "0x...",
"publicKey": "0x..."
}
To use a different path, set the output file in the script:
export IF_WALLET_FILE="$HOME/.config/impossible_agent/wallet.json"
# Then in the script, write to process.env.IF_WALLET_FILE
address and publicKey from wallet.json.<address>After creating your BSC wallet, register the public key on Chromia to link your Impossible Finance wallet to your ClawChain agent account. This enables tracking EVM events on your Chromia chain.
wallet.json file must exist with publicKey (required) and optionally address# Set your ClawChain configuration
export CLAWCHAIN_BRID="9D728CC635A9D33DAABAC8217AA8131997A8CBF946447ED0B98760245CE5207E"
export CLAWCHAIN_NODE="https://chromia.01node.com:7740"
# Read wallet info
WALLET_FILE="$HOME/.config/impossible_agent/wallet.json"
PUBLIC_KEY=$(cat $WALLET_FILE | grep -o '"publicKey": "[^"]*' | cut -d'"' -f4)
ADDRESS=$(cat $WALLET_FILE | grep -o '"address": "[^"]*' | cut -d'"' -f4)
# Register public key on Chromia
chr tx register_evm_public_key \
"impossible_finance" \
"$PUBLIC_KEY" \
"BSC" \
56 \
"$ADDRESS" \
--ft-auth \
--secret ~/.config/clawchain/credentials.json \
-brid $CLAWCHAIN_BRID \
--api-url $CLAWCHAIN_NODE \
--await
Arguments: wallet_type public_key chain network_id address
Network IDs:
569715137Note: If you don't have an address, use "" (empty string) for the last parameter.
If you're integrating this into a web application with an authenticated FT4 session:
const fs = require('fs');
const walletData = JSON.parse(fs.readFileSync('~/.config/impossible_agent/wallet.json', 'utf8'));
// Assuming you have a Chromia session object (from @chromia/ft4)
const result = await session.call({
name: 'register_evm_public_key',
args: [
'impossible_finance', // wallet_type
walletData.publicKey, // public_key (required)
'BSC', // chain
56, // network_id (56 for BSC mainnet, 97 for testnet)
walletData.address || "" // address (optional)
]
});
console.log('Public key registered:', result);
To check which public keys are registered for your agent:
# Get all registered public keys for an agent
chr query get_evm_public_keys 'agent_name=your_agent_name' \
-brid $CLAWCHAIN_BRID --api-url $CLAWCHAIN_NODE
# Get specific public key by wallet type
chr query get_evm_public_key_by_type \
'agent_name=your_agent_name' \
'wallet_type=impossible_finance' \
-brid $CLAWCHAIN_BRID --api-url $CLAWCHAIN_NODE
0x and be at least 66 characters (0x + 64 hex chars).The agent does not have an "account" on a server — it has a BSC address (from wallet.json). Fund the agent by sending BNB and tokens to that address:
<address> from wallet.json.<address>. The agent can swap via Impossible Finance if a pair exists (e.g. USDT/BNB, BUSD/BNB, IF/BNB).provider.getBalance(address)balanceOf(address) on the token contract.The agent must support any BEP-20 token and determine which swaps are possible.
symbol() → e.g. "USDT", "WBNB", "IF"decimals() → use for amount math and display (e.g. 18 or 6)name() → full name (optional)IF_FACTORY).factory.getPair(tokenA, tokenB). If the result is the zero address (0x000...), no pair exists. Otherwise it is the pair contract address.getReserves(). If both reserves are > 0, the pair has liquidity and that swap is available.getAmountsOut(amountIn, path) (read-only). If the call reverts or returns zero for the output amount, the swap is not feasible (no liquidity or invalid path).[tokenA, WBNB, tokenB]. Call getAmountsOut(amountIn, path); if it succeeds and returns a positive amount, the swap is available.The agent uses the private key from wallet.json to sign a swap transaction and sends it to BSC.
| Contract | Address |
|---|---|
| Router | 0xCCF4881b849d94C15c98567Ba71b08eD829ABA33 |
| Factory | 0xBf9D97eAF551877E4710d8E9d0519F79E03E5E69 |
| WBNB | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c |
| Method | Use case |
|---|---|
swapExactETHForTokens | Swap exact BNB for tokens (min amount out) |
swapExactTokensForETH | Swap exact tokens for BNB |
swapExactTokensForTokens | Swap exact token A for token B |
swapTokensForExactTokens | Swap tokens for exact amount of token B |
wallet.json (privateKey + address).new ethers.JsonRpcProvider(BSC_RPC_URL) (mainnet: chain id 56).getAmountsOut(amountIn, path). If it reverts or returns zero, try a multi-hop path (e.g. [tokenA, WBNB, tokenB]) or inform the user the pair has no liquidity.[WBNB, tokenAddress]; token → BNB: [tokenAddress, WBNB]; token → token: [tokenA, WBNB, tokenB] (or direct if pair exists).swapExactETHForTokens, swapExactTokensForETH, or swapExactTokensForTokens.Math.floor(Date.now() / 1000) + 300 (e.g. 5 minutes).getAmountsOut(amountIn, path) then apply slippage (e.g. 1% = amountOut * 0.99).{ value: amountInWei }; for token → BNB or token → token, approve router for the token first, then call the swap.1e18 wei.~/.config/impossible_agent/wallet.json (or IF_WALLET_FILE).address when telling the user where to top up.privateKey only inside the signing process (ethers Wallet).wallet.json.ethers.Wallet(privateKey, provider).swapExactETHForTokens) with path, deadline, amountOutMin.tx = await router.swapExactETHForTokens(...); await tx.wait().https://bscscan.com/tx/<hash>.getAmountsOut(amountIn, path) (read-only) to get expected amountOut, then compute amountOutMin with slippage.| Symbol | Address | Notes |
|---|---|---|
| WBNB | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c | Native wrapped; use in paths |
| USDT | 0x55d398326f99059fF775485246999027B3197955 | Stablecoin |
| BUSD | 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56 | Stablecoin |
| IF | 0xb0e1fc65c1a741b4662b813eb787d369b8614af1 | Impossible Finance governance token |
| IDIA | 0x0b15Ddf19D47E6a86A56148fb4aFFFc6929BcB89 | Impossible Decentralized Incubator Access token |
Do not limit to these. The agent should accept any BEP-20 address and discover availability via getPair / getReserves and getAmountsOut (see §3). If a pair has no liquidity, try a multi-hop path via WBNB or use the Impossible Finance UI.
chmod 600 ~/.config/impossible_agent/wallet.json.| Error | Meaning / action |
|---|---|
| insufficient funds | Not enough BNB for gas or not enough token/BNB for the swap. User should top up. |
| execution reverted: INSUFFICIENT_OUTPUT_AMOUNT | Slippage too low; increase or retry. |
| execution reverted: EXPIRED | Deadline passed; rebuild tx with new deadline. |
| nonce too low | Reuse of nonce; wait and retry or refresh nonce from chain. |
| execution reverted: PAIR_NOT_EXIST | No pair exists for this token combination. Try a multi-hop path via WBNB. |