wallet
starchild-ai-agent/official-skills
Multi-chain wallet for EVM and Solana: check balances, send tokens, sign transactions, and manage policies.
What is wallet?
A script-based wallet skill supporting EVM (via DeBank) and Solana (via Birdeye) networks. Use it to query balances, transfer tokens, sign messages and typed data, view transaction history, and propose wallet policies with configurable allow/deny rules.
- Query balances across all EVM chains and Solana in a single call
- Send EVM and Solana transactions with optional gas sponsorship
- Sign EIP-191 messages, EIP-712 typed data, and Solana messages
- View transaction history on EVM and Solana
- Propose and manage wallet policies with granular allow/deny rules
- Access user's own linked wallets (login and secondary) read-only from environment
How to install wallet
npx skills add https://github.com/starchild-ai-agent/official-skills --skill wallet- Python 3 environment with core.skill_tools.wallet module available
- DeBank API key (auto-injected by sc-proxy) for EVM balance queries
- Birdeye API key (auto-injected by sc-proxy) for Solana balance queries
- User's wallet address(es) from USER_LOGIN_WALLET_ADDRESS and USER_SECONDARY_WALLET_ADDRESS environment variables
How to use wallet
- 1.Call wallet_balance(chain='base') to check EVM balances on a specific chain
- 2.Call wallet_get_all_balances() to fetch balances across all supported chains at once
- 3.For transfers: verify balance first, then call wallet_transfer(to='0x...', amount='...', chain_id=8453) with amount in wei
- 4.Sign messages using wallet_sign(message) for EIP-191 or wallet_sign_typed_data(...) for EIP-712
- 5.Check policy status with wallet_get_policy(chain_type='ethereum'), then propose changes via frontend_action(action_type='update_wallet_policy', ...)
- 6.For Solana: use wallet_sol_balance(), wallet_sol_transfer(), and wallet_sol_sign() equivalents
Use cases
- Check your balance on Base, Ethereum, or Solana before making a transfer
- Send 10 USDC on Base to another address with sponsored gas
- Sign an EIP-712 permit for a DeFi protocol interaction
- Set up a wallet policy that denies private key export but allows all other operations
- Review recent transaction history across multiple chains
- Users managing multi-chain crypto assets
- Developers building wallet-integrated agents
- Anyone needing to sign blockchain transactions programmatically
- Users wanting to enforce transaction policies via allow/deny rules
wallet FAQ
The agent wallet is the skill's own wallet for transactions. The user's wallet (login and secondary) is read-only and accessed via USER_LOGIN_WALLET_ADDRESS and USER_SECONDARY_WALLET_ADDRESS environment variables. To check the user's balance, pass their address into wallet_balance(chain, address=...).
EVM amounts are in wei (e.g., 0.01 ETH = 10000000000000000). For ERC-20 transfers, set amount=0 and encode the transfer in the data calldata parameter.
Yes, gas is sponsored by default on EVM chains. The user doesn't need native tokens for gas. Pass sponsor=False to pay gas from wallet balance instead.
Use the frontend_action tool with action_type='update_wallet_policy', chain_type, and rules array. The user confirms and signs in the UI. Policy is off (allow-all) by default; enable it to require UI confirmation for transactions.
All DeBank-supported chains, including Ethereum, Base, Arbitrum, Optimism, Polygon, Linea, BSC, Avalanche, Fantom, Gnosis, zkSync, Scroll, Blast, Mantle, Celo, Aurora, Monad, World, Unichain, Abstract, Sonic, and Berachain.
Full instructions (SKILL.md)
Source of truth, from starchild-ai-agent/official-skills.
name: wallet version: 3.7.0 description: | Multi-chain wallet: EVM and Solana balances, transfers, signing, and policy.
Use when checking balances, sending tokens, signing typed data, or proposing a wallet policy (e.g. send 10 USDC on Base, sign EIP-712, Solana balance). author: starchild tags: [wallet, evm, solana, transfer, sign, policy, debank, birdeye] delivery: script metadata: starchild: emoji: 💰 skillKey: wallet
💰 Wallet Skill
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.
How to call
All read/transfer/sign operations are Python functions in core.skill_tools.wallet.
Run them from bash and read the JSON result:
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_balance(chain='base')))"
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).
Functions (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 User's Own Wallets (login / secondary)
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:
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.get_user_wallets()))"
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:
- Read-only. The agent holds no keys for these wallets. To check the user's
balances, pass the address into
wallet_balance(chain, address=...)/wallet_sol_balance(address=...). - Transactions from the user's wallet never go through script functions —
use the native
frontend_action(action_type="user_wallet_tx", ...)flow, where the user signs in the UI andexpected_fromis enforced server-side.
Key Facts
- Amounts are in wei for EVM (
wallet_transfer/wallet_sign_transaction). 0.01 ETH =10000000000000000. For ERC-20 token sends,amountis0(native) and the transfer is encoded indatacalldata. - Gas is sponsored by default on EVM chains — user doesn't need native tokens for gas. Falls back to user-paid if unavailable. Pass
sponsor=Falseto pay gas from wallet balance. - Policy default: OFF (allow-all). Only when policy is enabled do transactions need UI confirmation.
- Supported EVM chains: All DeBank-supported chains. Common names auto-mapped (e.g.
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. - Balance sources: DeBank (EVM), Birdeye (Solana), wallet-service (fallback). DeBank/Birdeye keys are auto-injected by sc-proxy.
Workflows
Check balances
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_balance(chain='base')))"
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_get_all_balances()))"
Send a transaction (EVM)
Always verify balance before, and the result/history after.
# 1. check
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_balance(chain='base')))"
# 2. transfer (amount in wei)
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_transfer(to='0x...', amount='10000000000000000', chain_id=8453)))"
# 3. verify
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_transactions(chain='base')))"
Sign EIP-712 typed data
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_sign_typed_data(domain={...}, types={...}, primaryType='Permit', message={...})))"
Policy Management
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).
- Check current policy:
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.wallet_get_policy(chain_type='ethereum')))" - (Optional) pre-validate rules:
python3 -c "from core.skill_tools import wallet; import json; print(json.dumps(wallet.validate_and_clean_rules([...], 'ethereum')))" - Propose — call the
frontend_actiontool (not a script):
The user confirms + signs in the UI. Call once per chain (EVM + Solana = two calls).frontend_action(action_type="update_wallet_policy", chain_type="ethereum", rules=[...])
Standard Wildcard Policy (when needed)
rules = [
{"name": "Deny key export", "method": "exportPrivateKey", "conditions": [], "action": "DENY"},
{"name": "Allow all", "method": "*", "conditions": [], "action": "ALLOW"},
]
Policy Modes — CRITICAL DECISION TABLE
⚠️ 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 |
Mode 1: Allow-All (Standard Wildcard)
rules = [
{"name": "Deny key export", "method": "exportPrivateKey", "conditions": [], "action": "DENY"},
{"name": "Allow all", "method": "*", "conditions": [], "action": "ALLOW"},
]
Mode 2: Deny-All (Lockdown)
rules = [
{"name": "Deny key export", "method": "exportPrivateKey", "conditions": [], "action": "DENY"},
{"name": "Deny all actions", "method": "*", "conditions": [], "action": "DENY"},
]
# ⚠️ NO ALLOW rules here — DENY * would override them!
Mode 3: Whitelist (Selective Allow)
rules = [
{"name": "Deny key export", "method": "exportPrivateKey", "conditions": [], "action": "DENY"},
{"name": "Allow transfer to Uniswap", "method": "eth_sendTransaction", "conditions": [
{"field_source": "ethereum_transaction", "field": "to", "operator": "eq", "value": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}
], "action": "ALLOW"},
]
# ⚠️ NO "DENY *" here! enabled=true already denies everything not ALLOWed.
# Adding DENY * would override the ALLOW rules above (DENY > ALLOW).
Privy Policy Rules — Key Constraints
| 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 |
Gotchas
- Policy proposal goes through the
frontend_actiontool — needs an active SSE session (won't work from a background task). wallet_balancerequireschain— usewallet_get_all_balancesfor discovery.- For both EVM + Solana policy, call
frontend_actionTWICE (one per chain_type).
Related skills
More from starchild-ai-agent/official-skills and the wider catalog.

wallet-policy
Generate Privy wallet security policy rules from natural language descriptions.

web-crawler
Web scraping for public posts, transcripts, and JS-heavy pages across YouTube, TikTok, Instagram, LinkedIn, Reddit, and more.

wechat-binding
Connect, scan, and manage WeChat account binding for message delivery.

worldcup
FIFA World Cup 2026 match schedules, live scores, and points-based prediction game.

xai-grok-onboarding
Connect your xAI subscription (X Premium, SuperGrok, etc.) via OAuth 2.0 to unlock Grok models.
steel-browser
Cloud browser for AI agents: JavaScript rendering, form filling, CAPTCHA bypass, and multi-step web automation.