koios-agent-wallet
🎯Skillfrom thamacroman/cardano-agent-skills
Generates and manages Cardano key-based wallets, enabling wallet creation, stake address registration, pool staking, and transactions via KoiosProvider.
Part of
thamacroman/cardano-agent-skills(15 items)
Installation
node scripts/agent-wallet.jsnode scripts/generate-key-based-wallet.jsSkill Details
"Quick setup of key-based Cardano agent wallets with MeshJS (MeshWallet) and KoiosProvider: generate wallet (no mnemonic), register stake address, and stake to a pool. Use when users ask to generate a wallet, register it, stake it, send transactions, or query wallet state via Koios."
Overview
# koios-agent-wallet
Operating rules (must follow)
- Default to mainnet unless the user explicitly requests preprod/preview/guild.
- Confirm target network (mainnet, preprod, preview, guild) before giving endpoints if unclear.
- Use KoiosProvider for read + submit; do not suggest it for key generation.
- Never request seed phrases or private keys; keep examples with placeholder addresses only.
- Agent runtime must not use mnemonic phrases for signing/staking; use
clikeys orrootkey mode only. - Use the correct Koios base URL per network and confirm with the user if unsure.
- Staking requires a stake signing key; if only a payment key is available, staking cannot be signed.
Quickstart workflow
- Confirm key-based setup and environment
- Ask: CLI-generated signing keys or root private key?
- If user only has a mnemonic, instruct them to derive/export keys offline first; do not use mnemonic directly in agent runtime.
- Ask: Node.js or browser? TypeScript or JavaScript?
- Provide key-based wallet creation path
- When the user wants a new wallet: run scripts/generate-key-based-wallet.js from the skill directory. It creates payment + stake keypairs and prints base address, stake address, and PAYMENT_SKEY_CBOR_HEX / STAKE_SKEY_CBOR_HEX. Optionally set WALLET_DIR=./wallet to write addresses.json, payment.skey, stake.skey, and (if @noble/ed25519 is installed) payment.vkey, stake.vkey. Use those CBOR hex values with agent-wallet.js for send/stake.
- Use MeshWallet for key-based wallets (CLI keys or root key).
- For staking, require both payment.skey and stake.skey (or a root key).
- If CLI keys are needed and the user does not have them, use scripts/generate-key-based-wallet.js (MeshJS + Koios only; no cardano-cli).
- If mnemonic is provided to the agent, fail fast with a clear error and request CLI/root key input.
- Provide Koios base URL for the network
- Mainnet: https://api.koios.rest
- Preprod: https://preprod.koios.rest
- Preview: https://preview.koios.rest
- Guild: https://guild.koios.rest
- Use the OpenAPI docs at the base URL to confirm endpoint paths.
- Verify funding with Koios
- Use KoiosProvider.fetchAddressUTxOs or provider.get(...) with an OpenAPI endpoint.
- If the wallet is unfunded on a testnet, direct the user to a faucet before retrying.
- Core actions (must support)
- Send ADA transactions with MeshTxBuilder.
- Register and delegate stake with MeshTxBuilder + deserializePoolId.
- Confirm staking status with provider.fetchAccountInfo.
- Sign + submit prebuilt txs from dApp mint builders (e.g., Nexus).
MeshJS key-based wallet (MeshWallet)
Koios provider (recommended for agent read-only queries)
```typescript
import { KoiosProvider } from "@meshsdk/core";
const provider = new KoiosProvider("api", "
```
Network values: api (mainnet), preview, preprod, guild.
Load from Cardano CLI keys (recommended for agents)
```typescript
import { MeshWallet } from "@meshsdk/core";
const wallet = new MeshWallet({
networkId: 1, // 1 = mainnet
fetcher: provider,
submitter: provider,
key: {
type: "cli",
payment: "
stake: "
},
});
await wallet.init();
const address = await wallet.getChangeAddress();
console.log(address);
```
Load from a root private key (alternative)
```typescript
import { MeshWallet } from "@meshsdk/core";
const wallet = new MeshWallet({
networkId: 1, // 1 = mainnet
fetcher: provider,
submitter: provider,
key: {
type: "root",
bech32: "xprv1...", // root private key (keep secure)
},
});
await wallet.init();
const address = await wallet.getChangeAddress();
console.log(address);
```
Read-only wallet (address only)
```typescript
import { MeshWallet } from "@meshsdk/core";
const wallet = new MeshWallet({
networkId: 1, // 1 = mainnet
fetcher: provider,
key: {
type: "address",
address: "addr1...",
},
});
await wallet.init();
const address = await wallet.getChangeAddress();
console.log(address);
```
Minimal Koios check (UTxOs)
TypeScript (KoiosProvider)
```typescript
import { KoiosProvider } from "@meshsdk/core";
const provider = new KoiosProvider("api", "
const address = "addr1...";
const utxos = await provider.fetchAddressUTxOs(address);
console.log(utxos);
```
Funding + confirmation checklist
- Funding
- Check UTxOs: provider.fetchAddressUTxOs(address)
- Ensure enough ADA for fees and (if first-time staking) the stake deposit.
- Staking readiness
- Get reward address: const rewardAddress = (await wallet.getRewardAddresses())[0]
- Check registration/delegation: provider.fetchAccountInfo(rewardAddress)
- Confirmation after submit
- Use provider.fetchTxInfo(txHash) or poll until confirmed.
Agent wallet dossier (output format)
```
=== Agent Wallet Dossier ===
Network: mainnet (api)
Payment Address: addr1...
Stake Address: stake1...
Koios Provider: api
Funding UTxOs:
Stake Status: registered | unregistered
Delegated Pool: pool1... | none
Last Tx:
```
Send ADA (MeshTxBuilder)
```typescript
import { KoiosProvider, MeshTxBuilder } from "@meshsdk/core";
const provider = new KoiosProvider("api", "
const txBuilder = new MeshTxBuilder({ fetcher: provider });
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const unsignedTx = await txBuilder
.txOut("addr1...", [{ unit: "lovelace", quantity: "1000000" }])
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log(txHash);
```
Mint NFTs via dApp builder (Nexus / similar)
Minting on hosted dApps typically means their backend builds an unsigned transaction and your wallet only signs. Koios submits it. You cannot recreate these mint transactions without the policy script + server rules, so the agent should sign and submit the dApp-built tx.
Step 1: Capture the unsigned tx (CBOR hex)
- Use the dApp’s mint API that the website calls after wallet connect.
- Capture the request/response in browser devtools; look for response fields like
txCbor,cborHex,unsignedTx, ortx. - If the API returns base64, convert to hex before using the script.
Step 2: Sign + submit (agent)
```bash
KOIOS_NETWORK=api MODE=sign-submit \
PAYMENT_SKEY_CBOR_HEX=
TX_CBOR_HEX=
node scripts/agent-wallet.js
```
- Optional:
TX_FILE=/path/to/tx.cborhex,PRINT_SIGNED=1,CONFIRM=1. - The payment key must match the address used in the mint request.
MODE=sign-submitpreserves existing script witnesses/redeemers in the tx.
Stake to a pool (register + delegate)
```typescript
import { KoiosProvider, MeshTxBuilder, deserializePoolId } from "@meshsdk/core";
const provider = new KoiosProvider("api", "
const txBuilder = new MeshTxBuilder({ fetcher: provider, verbose: true });
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const rewardAddresses = await wallet.getRewardAddresses();
const rewardAddress = rewardAddresses[0]!;
const poolIdHash = deserializePoolId("pool1...");
const unsignedTx = await txBuilder
.registerStakeCertificate(rewardAddress)
.delegateStakeCertificate(rewardAddress, poolIdHash)
.selectUtxosFrom(utxos)
.changeAddress(changeAddress)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log(txHash);
```
Agent workflow: generate → fund → register + stake
Use this sequence when the user wants a new wallet, then to register its stake address and delegate to a pool. All steps use key-based setup (no mnemonic in agent runtime). Yes: the agent can register, then stake — both happen in one transaction (Step 3).
Step 1: Generate wallet (agent runs the script)
- Run
scripts/generate-key-based-wallet.jsfrom the skill directory. Uses MeshJS + Koios only (no cardano-cli, no mnemonic). - Env (optional):
NETWORK=mainnet(default) orpreprod/preview;KOIOS_API_KEYfor Koios;WALLET_DIR=./walletto writeaddresses.json,payment.skey,stake.skey, and (if@noble/ed25519is installed)payment.vkey,stake.vkey. Keys are also printed to stdout. - Output: base address, stake address, and export lines for
PAYMENT_SKEY_CBOR_HEX/STAKE_SKEY_CBOR_HEX. For.vkeyfiles, install@noble/ed25519alongside@meshsdk/core. - Requires
@meshsdk/coreand network access (Koios) for address derivation.
```bash
cd skills/koios-agent-wallet
NETWORK=mainnet node scripts/generate-key-based-wallet.js
# Optional: WALLET_DIR=./wallet to persist keys to disk
```
- From the script output, capture the base address (user funds this), and the two CBOR hex values for Step 3.
Step 2: Fund the wallet
- User must send ADA to the base address (payment address) printed in the dossier.
- For first-time staking: wallet needs enough for ~2 ADA stake deposit plus fees (e.g. 3+ ADA total). Check with
provider.fetchAddressUTxOs(baseAddress)before Step 3.
Step 3: Register stake address and delegate (one transaction)
- Register and stake in a single tx: run
scripts/agent-wallet.jswithMODE=stake,REGISTER_STAKE=1, andPOOL_ID=pool1.... This registers the stake address and delegates to the pool; no separate "register only" step is needed. - Env:
PAYMENT_SKEY_CBOR_HEX,STAKE_SKEY_CBOR_HEX(from Step 1),KOIOS_NETWORK=api(mainnet) orpreprod/preview,POOL_ID,REGISTER_STAKE=1.
```bash
KOIOS_NETWORK=api MODE=stake REGISTER_STAKE=1 POOL_ID=pool1... \
PAYMENT_SKEY_CBOR_HEX=
node scripts/agent-wallet.js
```
- Optional:
CONFIRM=1to poll for tx confirmation.
Staking gotchas (agent must respect)
- Stake address not registered: Always use
REGISTER_STAKE=1for the first delegation (or the stake cert will fail). Omit or set to 0 when changing delegation only. - Insufficient funds for deposit: Stake registration locks ~2 ADA. Ensure wallet has 2 ADA + fees before running Step 3.
- Staking requires stake key: Wallet must be loaded with
STAKE_SKEY_CBOR_HEX(or root key); payment-only cannot sign stake certs. - Stake cert signing:
MeshWallet.signTx()only adds the payment key witness; stake registration/delegation certs require the stake key witness too. If you seeMissingVKeyWitnessesUTXOWorKeyHash {...}, the missing witness is usually the stake key. The skill’sagent-wallet.jsuses CSLFixedTransactionto get the tx hash (CSL 15.x+), createmake_vkey_witnessfor both payment and stake keys, and rebuildTransaction.new(body, witnessSet, auxiliaryData)so auxiliary data is preserved (avoidsMissingTxMetadata). For staking with CLI keys, install:@meshsdk/core,@emurgo/cardano-serialization-lib-nodejs, and (if using hex pool ID)bech32. - Pool ID (recommended): The skill uses MeshJS’s
deserializePoolId(pool1...)with a bech32 pool ID — that is correct. Prefer the bech32 pool ID from a trusted source (e.g. Cardanoscan or the pool’s official page) instead of manually converting hex to bech32; manual conversion with a genericbech32library can produce the wrong ID (wrong checksum / wrong pool). When an API gives you a hex pool ID, look up the pool on Cardanoscan and use thepool1...ID shown there. The script can accept hex and attempt conversion, but the canonical source is the explorer’s bech32. - Pool ID format:
deserializePoolId()expects bech32 (pool1...). PassPOOL_IDas bech32 when possible; hex (56 chars) is supported and converted via thebech32package, but using the bech32 ID from Cardanoscan is more reliable. - MeshJS staking reference:
Summary
| Step | Action | Script / API |
| ---- | ----------------------------- | ------------------------------------------------------- |
| 1 | Generate wallet (no mnemonic) | generate-key-based-wallet.js |
| 2 | Fund base address | User sends ADA; verify with fetchAddressUTxOs |
| 3 | Register + delegate | agent-wallet.js MODE=stake, REGISTER_STAKE=1, POOL_ID |
Response checklist (agent wallet setup)
- Network and Koios base URL
- Wallet address used for funding
- Koios query used (endpoint + payload)
- Transaction intent (send or stake), tx hash, and confirmation method
Notes
- Koios provides OpenAPI docs at each network base URL; use them to confirm endpoints and payloads.
- KoiosProvider expects a
networkstring and optionalapiKey; it can submit transactions. - MeshTxBuilder staking flows are documented in MeshJS staking transactions.
Scripts
scripts/agent-wallet.js— end-to-end template (wallet init, send ADA, stake, confirm). Staking with CLI keys: uses CSLFixedTransactionto get the tx hash (CSL 15.x+), create vkey witnesses for both payment and stake keys, and rebuild the transaction with auxiliary data preserved (MeshWallet.signTx only signs with payment key; stake certs need both). Pool ID: use the bech32 pool ID (pool1...) from Cardanoscan or the pool’s page when possible; the script accepts hex and converts viabech32, but manual hex→bech32 conversion can be wrong — prefer the explorer’spool1...ID. Deps:@meshsdk/core,@emurgo/cardano-serialization-lib-nodejs; for hexPOOL_ID, alsobech32.scripts/generate-key-based-wallet.js— generate new key-based wallet (no mnemonic, no cardano-cli); uses MeshJS + Koios only; creates payment + stake keys and outputs CBOR hex for use with agent-wallet (staking-ready).
Generate new wallet (key-based, stakable)
```bash
# Optional: NETWORK=mainnet (default) | preprod | preview; KOIOS_API_KEY=...; WALLET_DIR=./my-wallet (writes addresses.json only)
node scripts/generate-key-based-wallet.js
```
Outputs: base + stake addresses and PAYMENT_SKEY_CBOR_HEX / STAKE_SKEY_CBOR_HEX export lines. If WALLET_DIR is set, writes addresses.json, payment.skey, stake.skey, and (if @noble/ed25519 is installed) payment.vkey, stake.vkey. No cardano-cli required. Requires @meshsdk/core and Koios (network). For staking with agent-wallet.js (CLI keys), also install @emurgo/cardano-serialization-lib-nodejs; if you pass a hex POOL_ID, install bech32.
Script usage examples
```bash
# Status (read-only)
KOIOS_NETWORK=api MODE=status ADDRESS_ONLY=addr1... \\
node scripts/agent-wallet.js
# Send ADA (CLI keys)
KOIOS_NETWORK=api MODE=send PAYMENT_SKEY_CBOR_HEX=<...> \\
RECIPIENT_ADDR=addr1... SEND_LOVELACE=1000000 \\
node scripts/agent-wallet.js
# Register + delegate (prefer POOL_ID as pool1... from Cardanoscan)
KOIOS_NETWORK=api MODE=stake PAYMENT_SKEY_CBOR_HEX=<...> \\
STAKE_SKEY_CBOR_HEX=<...> POOL_ID=pool1... REGISTER_STAKE=1 \\
node scripts/agent-wallet.js
```
References
shared/PRINCIPLES.md- Koios API base:
https://api.koios.rest/ - Koios API guide:
https://koios.rest/guide/ - MeshJS Koios provider:
https://meshjs.dev/providers/koios - MeshJS MeshWallet:
https://meshjs.dev/apis/wallets/meshwallet - MeshJS MeshTxBuilder basics:
https://meshjs.dev/apis/txbuilder/basics - MeshJS staking transactions:
https://meshjs.dev/apis/txbuilder/staking
More from this repository10
Provides step-by-step guidance for setting up and managing Hydra Head nodes with best practices and configuration templates.
Enables seamless Cardano dApp development using MeshJS, providing wallet connections, transaction building, and script interactions in TypeScript/JavaScript.
Troubleshoots Hydra Head node connectivity and synchronization issues by systematically diagnosing network, configuration, and peer-related problems.
Skill
Skill
Skill
Executes Cardano CLI transactions with manual confirmation, ensuring safe and reproducible transaction builds and submissions.
Enables rapid Aiken smart contract development on Cardano, generating validators, blueprints, and .plutus artifacts with safe, version-controlled workflows.
Generates comprehensive Cardano CLI transaction templates for ADA transfers, multi-output transactions, native token transfers, and metadata-enriched transactions across different networks.
Executes Plutus script transactions on Cardano, requiring explicit human verification and collateral management.