Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
typhoon-starknet-account【部署与运维】Create a Starknet account to your agent through Typhoon anonymous deployer and interact with Starknet contracts (read/write + preflight).
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Path note (per OpenClaw docs): Skills may be installed in different directories (
<workspace>/skills,~/.openclaw/skills, or bundled). To keep this skill portable, commands below are written relative to the skill folder.Run from the skill directory:
cd <skill>/thennode scripts/<script>.js ...After Clawhub install, a typical location is:
~/.openclaw/workspace/skills/typhoon-starknet-account/
This skill provides agent-facing scripts for:
npm install starknet@^9.2.1 typhoon-sdk@^1.1.13
When the user asks to create a Starknet account (in any form like "create an account", "create a Starknet account for my agent", "I need a wallet", etc.), ALWAYS follow this flow:
node scripts/check-account.js
If hasAccount: false:
Tell the user:
To create your Starknet account, you need to fund it through Typhoon:
Then wait for the user to paste the note content.
Note: Account creation can take a few minutes. Typhoon proof generation + Starknet deployment/finality are not instant; tell the user to wait and avoid retrying unless it fails.
Once the user pastes the note JSON, run:
node scripts/create-account.js '<paste the note JSON here>'
The note format is:
{
"secret": "0x...",
"nullifier": "0x...",
"txHash": "0x...",
"pool": "0x...",
"day": "0x..."
}
After successful creation, show the user:
When user asks "what's my address", "show my wallet", "my account address", etc.:
node scripts/show-address.js
If multiple accounts exist, it returns all. Pass index to get specific one:
node scripts/show-address.js 0
| Script | Purpose |
|---|---|
check-account.js | Check if account(s) exist |
show-address.js | Show account address(es) |
load-account.js | Load an existing local account artifact |
create-account.js | Create + deploy a new account via Typhoon |
get-abi.js | Fetch ABI summary + list functions (+ optional candidate ranking) |
call-contract.js | Call a view function |
invoke-contract.js | Call an external function |
check-allowance.js | Check ERC20 allowance (supports human amount) |
multicall.js | Execute multiple calls in one tx |
estimate-fee.js | Preflight fee estimate for a call/multicall |
simulate.js | Preflight simulate for a call/multicall |
token-info.js | Token metadata (decodes felt short strings) |
decode-felt.js | Decode felt short strings |
sign-typed-data.js | Sign typedData (for SIWS / Starkbook-style auth) |
sign-invoke-tx.js | Sign an INVOKE transaction (one or more calls) without broadcasting |
If the user mentions protocols/tokens/apps (e.g. "Ekubo", "STRK", "ETH"), the agent must first search for:
Research constraint: all agent research must be done through MCP (Model Context Protocol) — no interactive browser/UI. Use machine-readable sources (APIs, docs URLs, GitHub raw files) via agent fetch tools.
This skill does not do web search by itself; it provides the onchain tooling once addresses are known.
node scripts/load-account.js
node scripts/get-abi.js '{"contractAddress":"0x..."}'
If you want the script to return ranked candidates (to help the agent decide), pass a query:
node scripts/get-abi.js '{"contractAddress":"0x...","query":"swap exact tokens for tokens"}'
node scripts/call-contract.js '{"contractAddress":"0x...","method":"<view_fn>","args":[...]}'
Optional: decode felt short strings:
node scripts/call-contract.js '{"contractAddress":"0x...","method":"symbol","args":[],"decodeShortStrings":true}'
Raw base units:
node scripts/check-allowance.js '{"tokenAddress":"0x...","ownerAddress":"0x...","spenderAddress":"0x...","requiredAmount":"20000000000000000000"}'
Human amount (script fetches decimals):
node scripts/check-allowance.js '{"tokenAddress":"0x...","ownerAddress":"0x...","spenderAddress":"0x...","requiredAmountHuman":"20"}'
Fee estimate:
node scripts/estimate-fee.js '{"privateKeyPath":"...","accountAddress":"0x...","calls":[{"contractAddress":"0x...","method":"...","args":[...]}]}'
Simulation:
node scripts/simulate.js '{"privateKeyPath":"...","accountAddress":"0x...","calls":[{"contractAddress":"0x...","method":"...","args":[...]}]}'
Single write:
node scripts/invoke-contract.js '{"privateKeyPath":"...","accountAddress":"0x...","contractAddress":"0x...","method":"...","args":[...]}'
When you need a Starknet account to sign a SIWS challenge (typedData) without ever exposing the private key, use:
node scripts/sign-typed-data.js '{
"accountAddress":"0x...",
"typedData": { "domain": { }, "types": { }, "primaryType": "Message", "message": { } }
}'
Or if you saved the typedData to a file:
node scripts/sign-typed-data.js '{
"accountAddress":"0x...",
"typedDataPath":"/tmp/typedData.json"
}'
Output is a signature array (hex strings) that can be submitted to verification endpoints (e.g. Starkbook /api/auth/verify).
To sign a transaction without sending it, use:
node scripts/sign-invoke-tx.js '{
"accountAddress":"0x...",
"calls":[
{"contractAddress":"0xTOKEN","entrypoint":"transfer","calldata":["0xTO","<uint256_low>","<uint256_high>"]}
]
}'
Or with ABI args (the script will fetch ABI and compile calldata for you):
node scripts/sign-invoke-tx.js '{
"accountAddress":"0x...",
"calls":[
{"contractAddress":"0xTOKEN","method":"transfer","args":["0xTO","123"]}
]
}'
This returns an invokeTransaction payload suitable for RPC starknet_addInvokeTransaction (signature included) plus a fee estimate.
⚠️ Not broadcast: this script only signs. To actually send, you must submit the payload to an RPC endpoint (and you should confirm before broadcasting).
If you want a single command that does challenge → sign locally → verify → (optional) post without Starkbook ever touching a private key:
node scripts/starkbook-client.js '{
"base":"http://localhost:3000",
"accountAddress":"0x...",
"action":"post",
"body":"hello from agent",
"linkUrl":"https://example.com"
}'
Approve + action in one tx:
node scripts/multicall.js '{"privateKeyPath":"...","accountAddress":"0x...","calls":[{"contractAddress":"0x...","method":"approve","args":["0xspender","123"]},{"contractAddress":"0x...","method":"...","args":[...]}]}'