npx skills add ...
npx skills add starchild-ai-agent/official-skills --skill wallet
Multi-chain wallet: EVM and Solana balances, transfers, signing, and policy.
npx skills add starchild-ai-agent/official-skills --skill wallet
Multi-chain wallet for EVM (DeBank-supported chains) + Solana. Balances, transfers, signing, and policy management. Script skill โ call the functions below via bash; no wallet tools are registered.
All read/transfer/sign operations are Python functions in core.skill_tools.wallet.
Run them from bash and read the JSON result:
The one operation that is NOT a script function is proposing a wallet policy
โ it needs to render a confirmation card in the UI, so it goes through the native
frontend_action tool (see Policy Management below).
from core.skill_tools import wallet)| Function | Description |
|---|---|
wallet_info() | Get all AGENT wallet addresses |
get_user_wallets() | The USER'S OWN wallets (login + secondary) โ read-only, from env |
wallet_balance(chain, address="", asset="") | EVM balance on a chain (DeBank). chain required |
wallet_sol_balance(address="", asset="") | Solana balance (Birdeye) |
wallet_get_all_balances(evm_address="", sol_address="") | All chains at once |
wallet_transfer(to, amount, chain_id=1, data="", **kw) | Broadcast EVM tx (gas sponsored by default) |
wallet_sign_transaction(to, amount, chain_id=1, data="", **kw) | Sign EVM tx (no broadcast) |
wallet_sign(message) | EIP-191 message signing |
wallet_sign_typed_data(domain, types, primaryType, message) | EIP-712 typed data signing |
wallet_transactions(chain="ethereum", asset="", limit=20) | EVM tx history |
wallet_sol_transfer(transaction, caip2=...) | Broadcast Solana tx (base64) |
wallet_sol_sign_transaction(transaction) | Sign Solana tx (no broadcast) |
wallet_sol_sign(message) | Solana message signing |
wallet_sol_transactions(chain="solana", asset="sol", limit=20) | Solana tx history |
wallet_get_policy(chain_type="ethereum") | Check policy status |
validate_and_clean_rules(rules, chain_type) | Pre-validate policy rules before proposing |
The agent wallet is NOT the user's wallet. The platform injects the user's own wallet identities as env vars (synced from the control plane at container start and on user wallet actions):
USER_LOGIN_WALLET_ADDRESS / USER_LOGIN_WALLET_TYPE โ the wallet the user
logs in with (or bound as primary).USER_SECONDARY_WALLET_ADDRESS / USER_SECONDARY_WALLET_TYPE โ the user's
other linked wallet (e.g. Solana when login is EVM).When asked "what's my wallet" / "my login wallet" / "check MY balance", read these โ do NOT answer with the agent wallet or say you don't know:
Empty/missing values mean the user has never bound a wallet in that slot (e.g. social login) โ say so and point them to wallet binding in the web app.
Rules:
wallet_balance(chain, address=...) /
wallet_sol_balance(address=...).frontend_action(action_type="user_wallet_tx", ...) flow,
where the user signs in the UI and expected_from is enforced server-side.wallet_transfer / wallet_sign_transaction). 0.01 ETH = 10000000000000000. For ERC-20 token sends, amount is 0 (native) and the transfer is encoded in data calldata.sponsor=False to pay gas from wallet balance.avalanche โ avax, bsc โ bsc, zksync โ era). Fallback aliases include ethereum/base/arbitrum/optimism/polygon/linea/bsc/avalanche/fantom/gnosis/zksync/scroll/blast/mantle/celo/aurora plus monad/world/unichain/abstract/sonic/berachain.Always verify balance before, and the result/history after.
Checking policy is a script function; proposing a policy uses the native
frontend_action tool (it renders a signature card in the UI โ a script cannot).
frontend_action tool (not a script):
โ ๏ธ DENY > ALLOW in Privy. DENY * overrides ALL ALLOW rules. NEVER mix them.
| Mode | Rules | Effect |
|---|---|---|
| Allow-all (default) | DENY exportPrivateKey + ALLOW * | Everything allowed except key export |
| Deny-all (lockdown) | DENY exportPrivateKey + DENY * | Nothing works. No ALLOW rules! |
| Whitelist (selective) | DENY exportPrivateKey + specific ALLOW rules only | Only whitelisted ops work, rest implicitly denied |
| Rule | Details |
|---|---|
| Default behavior | enabled=true โ deny-all unless explicitly ALLOWed |
| DENY > ALLOW | DENY always wins when both match |
| Empty conditions | Only exportPrivateKey and * (wildcard) allow conditions: [] |
| TX methods need conditions | eth_sendTransaction, eth_signTransaction, eth_signTypedData_v4, eth_signUserOperation, signAndSendTransaction, etc. ALL require โฅ1 condition |
| Valid field_sources | EVM: ethereum_transaction (to/value/chain_id), ethereum_calldata (function_name), ethereum_typed_data_domain (chainId/verifyingContract), ethereum_typed_data_message, system |
| Valid operators | eq, gt, gte, lt, lte, in (array, max 100 values) |
| Dual chain | Call frontend_action(action_type="update_wallet_policy", ...) TWICE for EVM + Solana |
frontend_action tool โ needs an active SSE session (won't work from a background task).wallet_balance requires chain โ use wallet_get_all_balances for discovery.frontend_action TWICE (one per chain_type).