agentleFS
gear-foundationgear-foundation/vara-skills/skills/vara-wallet/SKILL.md

vara-wallet

Skill17 starsChanged 7 months agoMITView on GitHub

Use when an agent needs to interact with Vara Network or Vara.eth on-chain — deploy programs, call Sails methods, manage wallets, transfer tokens, monitor events. Do not use for building Sails programs.

  • Installs packages

We split this skill into the rules it gives an agent

12 rules. About 0 are common, 4 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill for on-chain interaction with Vara Network and Vara.eth: deploying programs, calling Sails methods, managing wallets, …

    line 15
  2. Distinctive:

    Do NOT use this skill for:

    line 17
  3. Very specific:

    Use --chain vara-eth when the user asks for Vara.eth, Hoodi, Mirrors, WVARA, Ethereum V3 keystores, or vara-eth:* commands.

    line 58
  4. Distinctive:

    Prefer root Sails parity where possible:

    line 75
  5. Very specific:

    When deploying to a local dev node, use --network local or set the endpoint explicitly.

    line 210
  6. Very specific:

    All commands output JSON to stdout.

    line 364
  7. Distinctive:

    Never pass secrets (seeds, mnemonics, passphrases) as CLI arguments in committed scripts.

    line 489
  8. Very specific:

    Never use --show-secret in automated flows.

    line 490
  9. Very specific:

    Always use --account <name> for signing, not --seed.

    line 491
  10. Very specific:

    When targeting a local dev node, use --network local or VARA_WS=ws://localhost:9944.

    line 495
  11. Very specific:

    Use config set network testnet to persist network choice across sessions.

    line 496
  12. Very specific:

    If sails-local-smoke is green and you need to interact with a deployed program on a live network, switch to this skill.

    line 499

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Vara Wallet

CLI tool for AI agents to interact with Vara Network on-chain.

Repository: https://github.com/gear-foundation/vara-wallet Install: npm install -g vara-wallet

Role

Use this skill for on-chain interaction with Vara Network and Vara.eth: deploying programs, calling Sails methods, managing wallets, transferring tokens, querying state, and monitoring events.

Do NOT use this skill for:

  • Writing Sails Rust programs — use vara-skills/skills/sails-feature-workflow/
  • Running gtest — use vara-skills/skills/sails-gtest/
  • Setting up Rust/Gear toolchain — use vara-skills/skills/sails-dev-env/

Setup

# Check if installed
if command -v vara-wallet &>/dev/null; then
  VW="vara-wallet"
else
  npm install -g vara-wallet
  VW="vara-wallet"
fi

Minimum version: 0.20.5. The recipes below assume the structured PROGRAM_ERROR / TRANSPORT_ERROR surfaces, the enveloped sails:idl extractor, transparent auto-retry on transient transport reasons (timeout, ws_close_abnormal), the Vara.eth --chain vara-eth rail, direct --wait submitted handoff, and persistent vara-eth:session action loops.

Zero-Setup Wallet

On first use, create a wallet. Encryption and passphrase are automatic — no human setup required.

# Creates wallet, auto-generates passphrase, encrypts, suppresses secrets
$VW wallet create --name agent

# Verify
$VW wallet list
# → [{ "chain": "vara", "name": "agent", "address": "kG...", "encrypted": true, "isDefault": true }]

The passphrase is stored at ~/.vara-wallet/.passphrase (0600). The agent never sees or handles it.

wallet list without --chain is a full local inventory: native Vara rows use chain: "vara" and Vara.eth rows use chain: "vara-eth". Use --chain vara wallet list or --chain vara-eth wallet list when a workflow needs only one rail.

Vara.eth Quick Route

Use --chain vara-eth when the user asks for Vara.eth, Hoodi, Mirrors, WVARA, Ethereum V3 keystores, or vara-eth:* commands. Native Vara remains the default. Vara.eth network names are mainnet, hoodi, and local; do not use native Vara's testnet alias on this rail.

$VW vara-eth:wallet create agent-eth --passphrase "$PASSPHRASE"
$VW --chain vara-eth --network hoodi vara-eth:wvara balance 0xYOUR_ETH_ADDRESS
$VW --chain vara-eth --network hoodi --account agent-eth \
  vara-eth:message send 0xMIRROR --payload 0xfeed --via eth --wait submitted

Vara.eth messages and state-changing Sails calls default to --wait reply; WVARA writes and message replies default to --wait receipt. Select --wait submitted only for transaction-hash handoff. Direct messages then avoid the validator and return messageId: null; read the detailed reference first.

Prefer root Sails parity where possible:

$VW --chain vara-eth --network hoodi --account agent-eth \
  program upload ./program.opt.wasm --idl ./program.idl --args '[]'
$VW --chain vara-eth --network hoodi discover 0xMIRROR --idl ./program.idl
$VW --chain vara-eth --network hoodi call 0xMIRROR Service/Query --args '[]' --idl ./program.idl

For detailed Vara.eth wallet workflows, read references/vara-eth-wallet.md in this skill. For multiple Vara.eth Sails actions in one agent process, use vara-eth:session (persistent signer, connection, and IDL cache; injected submissions); see the detailed reference before choosing it over a direct L1 write.

Command Quick Reference

Read (no account needed)

CommandPurpose
$VW node infoChain name, genesis, latest block
$VW balance [address]Account balance in VARA
$VW program info <id>Program status and codeId
$VW program list [--count N] [--all]List on-chain programs (default: 100)
$VW code info <codeId>Code blob metadata
$VW code list [--count N]List uploaded code blobs
$VW call <pid> Service/Query --args '[]' [--idl <path>]Sails read-only query (free; IDL auto-resolved from on-chain WASM for any program with an embedded sails:idl section)
$VW discover <pid> [--idl <path>]Introspect Sails services, methods, events (IDL auto-resolved from on-chain WASM)
$VW idl import <path.idl> (--code-id <hex> | --program <hex|ss58>)Seed local IDL cache for contracts without an embedded IDL
$VW idl listList cached IDL entries (codeId, version, source, importedAt, idlSizeBytes)
$VW idl remove <code-id>Remove one cache entry (idempotent)
$VW idl clear [--yes]Wipe IDL cache (terraform-style: bare invocation previews; --yes commits)
$VW metadata listList cached runtime-metadata entries (genesisHash-specVersion, saves ~750ms per warm connect)
$VW metadata clear [--yes]Wipe runtime-metadata cache (terraform-style: bare previews; --yes commits)
$VW state read <pid>Read raw program state
$VW mailbox read [address]Read mailbox messages
$VW inbox list [--since <duration>] [--limit <n>]Query captured mailbox messages from event store
$VW inbox read <messageId>Read a specific captured message
$VW events list [--type <t>] [--since <d>] [--program <id>]Query captured events from event store
$VW events prune [--older-than <duration>]Delete old events
$VW query <pallet> <method> [args...]Generic storage query
$VW vft balance <token> [account] --idl <path>Fungible token balance
$VW vft info <token> --idl <path>Token name, symbol, decimals, total supply
$VW vft allowance <token> <owner> <spender> --idl <path>Token allowance
$VW dex pairs --factory <addr>List DEX trading pairs
$VW dex pool <t0> <t1> --factory <addr>Pool reserves and prices
$VW dex quote <tIn> <tOut> <amount> --factory <addr>Swap quote with price impact

Write (account required — add --account <name>)

CommandPurpose
$VW transfer <to> <amount>Transfer VARA tokens
$VW program upload <wasm> [--idl <path>] [--init <name>] [--args <json>] [--payload <hex>] [--value <v>]Upload + init program (use --idl for auto-encoding)
$VW program deploy <codeId> [--idl <path>] [--init <name>] [--args <json>] [--payload <hex>] [--value <v>]Deploy from existing code (use --idl for auto-encoding)
$VW code upload <wasm>Upload code blob only
$VW message send <dest> [--payload <hex>] [--value <v>] [--voucher <id>]Send message to any actor (program, user, wallet)
$VW message reply <mid> [--payload <hex>] [--voucher <id>]Reply to a message
$VW mailbox claim <messageId>Claim value from mailbox message
$VW call <pid> Service/Function --args '[...]' --value <v> --units human|raw [--idl <path>]Sails state-changing call (response includes decoded events: [...])
$VW call <pid> Service/Function --estimate [--idl <path>]Estimate gas cost without sending
$VW call <pid> Service/Function --dry-run [--idl <path>]Encode SCALE payload + return destination — no signing, no submit, no wallet
$VW call <pid> Service/Function --dry-run --estimate [--idl <path>]Encode AND estimate gas (compose; account required for the estimate half)
$VW call <pid> Service/Function --args-file <path> [--idl <path>]Read --args JSON from file (use - for stdin) — avoids shell-escape on nested JSON
$VW vft transfer <token> <to> <amount> --idl <path>Transfer fungible tokens
$VW vft transfer-from <token> <from> <to> <amount> --idl <path>Transfer from approved allowance
$VW vft approve <token> <spender> <amount> --idl <path>Approve token spender
$VW vft mint <token> <to> <amount> --idl <path>Admin token minting
$VW vft burn <token> <from> <amount> --idl <path>Admin token burning
$VW dex swap <tIn> <tOut> <amount> --factory <addr> [--slippage <bps>]Swap tokens (auto-approves)
$VW dex add-liquidity <t0> <t1> <a0> <a1> --factory <addr>Add pool liquidity
$VW dex remove-liquidity <t0> <t1> <lp> --factory <addr>Remove pool liquidity
$VW voucher issue <spender> <value>Issue gas voucher (see ../../references/voucher-and-signless-flows.md)
$VW voucher revoke <spender> <voucherId>Revoke voucher
$VW faucet [address]Request testnet TVARA tokens (auto-connects to testnet)
$VW sign <data> [--hex]Sign arbitrary data with wallet key (raw sr25519)
$VW tx <pallet> <method> [args...]Submit generic extrinsic

Verify (no account needed)

CommandPurpose
$VW verify <data> <signature> <address> [--hex]Verify signature against data and address

Monitor

CommandPurpose
$VW wait <messageId> [--timeout <s>]Wait for message reply
$VW watch <pid> [--event Service/Event|pallet:Name] [--idl <path>] [--no-decode]Stream program events (NDJSON; IDL adds decoded.kind === 'sails' block)
$VW subscribe blocks [--finalized]Stream new/finalized blocks (NDJSON + SQLite)
$VW subscribe messages <pid> [--event Service/Event|pallet:Name] [--idl <path>] [--no-decode]Stream program messages/events (IDL-aware decoding)
$VW subscribe mailbox <address>Capture mailbox messages (survives between runs)
$VW subscribe balance <address>Stream balance changes
$VW subscribe transfers [--from <a>] [--to <a>]Stream transfer events
$VW subscribe program <pid>Stream program state changes

Wallet Management

CommandPurpose
$VW wallet create [--name <n>]Create encrypted wallet
$VW wallet import [--seed <s>] [--mnemonic <m>] [--json <path>]Import existing key
$VW wallet listList native + Vara.eth wallet inventory; add --chain to filter
$VW wallet export <name> [--decrypt]Export keyring JSON
$VW wallet default [name]Get/set default wallet
$VW init [--name <n>]Initialize config + default wallet
$VW config listShow all config values
$VW config set network testnetPersist network endpoint
$VW config set <key> <value>Set any config key
$VW config get <key>Get a config value

Common Workflows

Deploy and interact with a Sails program

# 1. Upload program (auto-encodes Sails constructor from IDL)
UPLOAD=$($VW --account agent program upload ./target/wasm32-unknown-unknown/release/my_program.opt.wasm \
  --idl ./target/idl/my_program.idl --args '["MyToken", "MTK", 18]')
PROGRAM_ID=$(echo $UPLOAD | jq -r .programId)

# 2. Discover interface
$VW discover $PROGRAM_ID --idl ./target/idl/my_program.idl

# 3. Estimate gas before calling
$VW --account agent call $PROGRAM_ID MyService/DoSomething --args '["hello"]' --idl ./my_program.idl --estimate

# 4. Call a function (state-changing)
$VW --account agent call $PROGRAM_ID MyService/DoSomething --args '["hello"]' --idl ./my_program.idl

# 5. Query state (read-only, free)
$VW call $PROGRAM_ID MyService/GetState --args '[]' --idl ./my_program.idl

Local node deployment

When deploying to a local dev node, use --network local or set the endpoint explicitly.

# Use --network shorthand (recommended)
$VW --network local wallet import --seed '//Alice' --name alice

# Or persist in config
$VW config set network local

# Or set for the session
export VARA_WS=ws://localhost:9944

# Deploy with IDL-based constructor encoding
UPLOAD=$($VW --account alice program upload ./target/wasm32-unknown-unknown/release/my_program.opt.wasm \
  --idl ./my_program.idl --args '["arg1"]')
PROGRAM_ID=$(echo $UPLOAD | jq -r .programId)

# Verify
$VW call $PROGRAM_ID MyService/GetState --args '[]' --idl ./my_program.idl

Send message and wait for reply

RESULT=$($VW --account agent message send $PROGRAM_ID --payload 0x00)
MSG_ID=$(echo $RESULT | jq -r .messageId)

REPLY=$($VW wait $MSG_ID --timeout 60)
echo $REPLY | jq .payload

Monitor program events

# Raw NDJSON
$VW watch $PROGRAM_ID | while read -r line; do
  echo "$line" | jq .
done

# IDL-aware: each UserMessageSent gets a `decoded: { kind: 'sails', service, event, data }` block
$VW watch $PROGRAM_ID --idl ./my-program.idl | jq '.decoded // .'

# Filter by Sails event (qualified or bare when unambiguous)
$VW watch $PROGRAM_ID --idl ./my-program.idl --event MyService/Transferred
$VW subscribe messages $PROGRAM_ID --idl ./my-program.idl --event Transferred --count 1 --timeout 30

# Force pallet vocab even with IDL loaded — replaces the dropped --pallet-event flag
$VW watch $PROGRAM_ID --idl ./my-program.idl --event pallet:UserMessageSent

Bare event names that resolve to multiple services hard-fail with AMBIGUOUS_EVENT listing the alternatives — qualify as Service/Event or use pallet:Name to force pallet vocabulary. --no-decode disables the opportunistic IDL auto-load entirely. The decoded.kind discriminator future-proofs the surface for additional decoder types.

Preview a call without signing

--dry-run encodes the SCALE payload and exits with willSubmit: false. Works on machines with no wallet configured — useful for previewing payloads in CI, code review, or read-only environments.

# call dry-run — no account needed
$VW call $PROGRAM_ID MyService/DoSomething --args '["hello"]' --idl ./my-program.idl --dry-run

# program upload dry-run — reports resolved constructor + encoded init payload
$VW program upload ./my-program.opt.wasm --idl ./my-program.idl --args '["MyToken", "MTK", 18]' --dry-run

Pass nested JSON via stdin (avoids shell-escape footguns)

--args-file <path> (or - for stdin) eliminates double-escape failures when the JSON contains hex actor IDs, 64-byte vec u8 signatures, or other punctuation-heavy payloads.

echo '[["0xabcd...", 1000]]' | $VW --account agent call $PROGRAM_ID MyService/BatchTransfer --args-file - --idl ./my-program.idl

--args and --args-file are mutually exclusive (INVALID_ARGS_SOURCE). Stdin without a pipe attached fails fast with STDIN_IS_TTY instead of hanging on EOF.

Subscribe to events (with persistence)

# Catch mailbox messages (they vanish after ~1 block)
$VW subscribe mailbox $MY_ADDRESS

# Wait for exactly 1 transfer, then exit (agent-friendly)
$VW subscribe transfers --count 1 --timeout 30

# Query captured events between runs
$VW inbox list --since 1h
$VW events list --type mailbox --limit 10

Token operations

# Token info
$VW vft info $TOKEN_PROGRAM --idl ./vft.idl

# Check balance
$VW vft balance $TOKEN_PROGRAM --idl ./vft.idl

# Transfer
$VW --account agent vft transfer $TOKEN_PROGRAM $RECIPIENT 1000 --idl ./vft.idl

# Approve
$VW --account agent vft approve $TOKEN_PROGRAM $SPENDER 1000 --idl ./vft.idl

DEX operations (Rivr)

# Check available pairs
$VW dex pairs --factory $FACTORY

# Get swap quote with price impact
$VW dex quote $TOKEN_IN $TOKEN_OUT 100 --factory $FACTORY

# Swap tokens (auto-approves input token)
$VW --account agent dex swap $TOKEN_IN $TOKEN_OUT 100 --factory $FACTORY --slippage 100

Fund an account with a voucher

$VW --account sponsor voucher issue $SPENDER_ADDRESS 100 --duration 14400

Sign and verify data

# Sign arbitrary data
SIG=$($VW --account agent sign "hello world" | jq -r .signature)

# Verify signature
$VW verify "hello world" $SIG $ADDRESS

IDL Resolution

Sails commands (call, discover, vft, dex) need an IDL. Resolution order:

  1. --idl <path> — local file, always works, takes precedence
  2. Local cache — ~/.vara-wallet/idl-cache/<codeId>.cache.json, populated automatically by previous fetches or by idl import
  3. Embedded sails:idl section — auto-extracted from the program's on-chain WASM and cached. Since 0.18.0 the extractor reads the enveloped section format (1-byte version, 1-byte flags with deflate bit, payload) emitted by current sails-rs, with a raw UTF-8 fallback for older beta.1-era programs.
  4. Bundled IDLs — standard VFT and Rivr DEX IDLs ship in the binary for vft / dex commands.

Embedded IDL is the default. Any contract built with current sails-rs ships its IDL inside the WASM, so call / discover / vft / dex work without --idl; the first invocation populates the cache and subsequent calls hit it for free. idl import is only for contracts that don't have an embedded sails:idl section — seed the cache once:

# Resolves codeId via RPC
$VW idl import ./my-program.idl --program <programId>

# Fully offline if you already know the codeId
$VW idl import ./my-program.idl --code-id 0x<hex>

Output Parsing

All commands output JSON to stdout. Errors go to stderr as { error, code }.

# Extract a field
$VW balance | jq -r .balance

# Check transaction success
RESULT=$($VW --account agent transfer $TO 1)
echo $RESULT | jq '.events[] | select(.section == "balances")'

# Verbose debug (stderr, won't break JSON parsing)
$VW --verbose balance 2>/dev/null | jq .

Structured Errors

Program-execution failures surface as flat JSON on stderr — reason and programMessage are top-level keys, not nested under meta:

{"code":"PROGRAM_ERROR","reason":"panic","programMessage":"<BareVariant>","error":"<full text>"}

reason ∈ panic | unreachable | inactive | not_found. programMessage is the bare Sails error variant — the called \Result::unwrap()` on an `Err` value:wrapper that#[export(unwrap_result)]` adds is stripped, so agents can switch on it directly:

ERR=$(vara-wallet --account agent call $PID Service/Method --args '[...]' --idl ./my.idl 2>&1 1>/dev/null)
case "$(echo "$ERR" | jq -r '.programMessage // ""')" in
  InsufficientBalance) refill ;;
  Unauthorized)        switch_account ;;
  *)                   echo "unhandled: $ERR" ;;
esac

Transport Errors

Migration: scripts that grepped "code":"CONNECTION_TIMEOUT" (WS connect) or "code":"TIMEOUT" / "code":"CONNECTION_FAILED" (program/dex/vft/message paths) must switch to "code":"TRANSPORT_ERROR" + the matching reason. Faucet HTTP CONNECTION_FAILED is unchanged — different consumer surface. --light failures route through the same taxonomy.

Transport-layer failures (DNS, WS handshake, RPC disconnect, TLS, timeout) surface as structured TRANSPORT_ERROR with a reason subcode instead of the legacy opaque {"error":"{}","code":"UNKNOWN_ERROR"}. The error carries endpoint, host (DNS path), and meta.cause (raw underlying message):

{"code":"TRANSPORT_ERROR","reason":"dns_failure","error":"Cannot resolve host nonexistent-host","endpoint":"wss://nonexistent-host","host":"nonexistent-host","meta":{"cause":"<raw>"}}

reason taxonomy: dns_failure | connection_refused | timeout | ws_close_abnormal | protocol_mismatch | unreachable | tls_failure | unknown. Switch on it to decide retry vs. fail:

case "$(echo "$ERR" | jq -r '.reason // ""')" in
  timeout|connection_refused|unreachable|ws_close_abnormal) retry_with_backoff ;;
  dns_failure|tls_failure|protocol_mismatch)                fail_fast ;;
esac

--verbose writes a [verbose] cause: code=<x>, message=<y> line to stderr immediately before the structured JSON (EPIPE-safe), making cause-chain triage cheap without changing the machine-readable surface.

Network Switching

# Shorthand (recommended)
$VW --network testnet balance

# Per-command with full URL
$VW --ws wss://testnet.vara.network balance

# Persist across sessions
$VW config set network testnet

# Session-wide env var
export VARA_WS=wss://testnet.vara.network

Endpoint resolution order: --ws > --network > VARA_WS env > config.wsEndpoint > default.

NetworkEndpoint--network shorthand
Mainnetwss://rpc.vara.network (default)--network mainnet
Testnetwss://testnet.vara.network--network testnet
Localws://localhost:9944--network local

Connection timeout is 10s. Bad endpoints fail fast with TRANSPORT_ERROR instead of hanging — see Transport Errors.

For full network endpoint and account format details, see ../../references/vara-network-endpoints.md.

Units

1 VARA = 10^12 minimal units (12 decimals). Amounts default to VARA.

$VW transfer $TO 1.5                        # 1.5 VARA
$VW transfer $TO 1500000000000 --units raw   # same in raw units

All --units flags use a unified human|raw vocabulary:

  • Native commands (balance, transfer, message, call, voucher, program): human (default) = VARA decimals (12). raw = minimal units passthrough.
  • VFT and DEX commands: raw (default) = minimal units passthrough. human = use the token's declared decimals (queried at runtime).
  • The literals vara and token are rejected with INVALID_UNITS — pulled from old tutorials, they no longer work.

Existential deposit is ~10 VARA on mainnet.

Error Recovery

CodeMeaningAction
NO_ACCOUNTNo signing accountAdd --account <name>
PASSPHRASE_REQUIREDEncrypted wallet, no passphraseCheck ~/.vara-wallet/.passphrase exists
DECRYPT_FAILEDWrong passphraseVerify passphrase file content
TRANSPORT_ERRORTransport-layer failureSwitch on .reason to decide retry vs. fail. See Transport Errors
WRONG_NETWORKCommand not available on this networkUse --network testnet for faucet
TX_TIMEOUTTransaction didn't land in 60sRetry — network congestion
TX_FAILEDOn-chain failureInspect .events in output
IDL_NOT_FOUNDNo embedded sails:idl and no cache/bundled matchRun idl import (the error pre-fills the command) or pass --idl <path>. See IDL Resolution
METHOD_NOT_FOUNDMethod not in IDLCheck discover output; cross-service hint is suggested in the error
AMBIGUOUS_EVENTBare Sails event name maps to multiple servicesQualify as --event Service/Event or use pallet:Name
INVALID_ARGS_FORMAT--args shape mismatchSails methods take POSITIONAL args. Pass as a JSON array: '[arg1, arg2]'. Single-struct-arg methods also accept the bare object form: '{"field": ...}'. Multi-arg methods reject named-arg objects
INVALID_ADDRESSTyped actor_id field got the wrong shapeRead the field name from the error (Invalid ActorId for "<field>": ...) and fix that field — use hex (0x + 64 chars), SS58, or 32-byte array. Don't rewrite the whole payload
INVALID_ARGS_SOURCE--args and --args-file used togetherPick one
STDIN_IS_TTY--args-file - used with no pipe attachedPipe JSON in or pass a real path
CONFLICTING_OPTIONSMutually exclusive options (e.g. --network + --ws)Pick one. Note: --dry-run + --estimate compose on call
INVALID_UNITS--units value isn't human or rawUse the unified vocabulary; the literals vara / token are rejected
PROGRAM_ERRORSails program execution failedInspect top-level reason and programMessage. State problem — do NOT bump --gas-limit. See Structured Errors for the JSON shape, reason enum, and case-switch pattern
PERMISSION_DENIEDOS-level permission error (e.g. idl clear --yes on a read-only dir)Check filesystem permissions on ~/.vara-wallet/
INVALID_NETWORKUnknown --network valueUse mainnet, testnet, or local
INVALID_CONFIG_KEYUnknown config keyUse config list to see valid keys

Guardrails

  • Never pass secrets (seeds, mnemonics, passphrases) as CLI arguments in committed scripts. Use wallet files.
  • Never use --show-secret in automated flows. Secrets should stay in encrypted wallet files.
  • Always use --account <name> for signing, not --seed.
  • Gas is auto-calculated — omit --gas-limit unless you have a specific reason. calculateGas failures (program panic during dry-run) surface as classified PROGRAM_ERROR, not opaque gas errors — see Error Recovery.
  • Messages are async. After message send, use wait to get the reply.
  • call auto-detects queries vs functions — no need to specify.
  • When targeting a local dev node, use --network local or VARA_WS=ws://localhost:9944. The default endpoint is mainnet.
  • Use config set network testnet to persist network choice across sessions.
  • program list returns 100 programs by default. Use --all for unlimited.
  • faucet only works on testnet. It refuses mainnet endpoints automatically.
  • If sails-local-smoke is green and you need to interact with a deployed program on a live network, switch to this skill.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.