# Managing Wallets

> Manages Turnkey HD wallets across 14+ chains (Ethereum, Solana, Bitcoin, Cosmos, Aptos, Sui, Tron, TON, XRP, Stellar, Dogecoin, Sei, Spark): create wallets, derive addresses, add chains, import/export.

- **Type:** Skill
- **Install:** `agentstack add skill-tkhq-turnkey-agent-skills-managing-wallets`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [tkhq](https://agentstack.voostack.com/s/tkhq)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [tkhq](https://github.com/tkhq)
- **Source:** https://github.com/tkhq/turnkey-agent-skills/tree/main/skills/managing-wallets

## Install

```sh
agentstack add skill-tkhq-turnkey-agent-skills-managing-wallets
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Managing Wallets

> **Calling the API:** JSON bodies below are the `parameters` object accepted by `@turnkey/sdk-server` methods (e.g. `list_wallets` → `client.getWallets(...)`, `create_wallet` → `client.createWallet(...)`). See the root [`SKILL.md`](../../SKILL.md#calling-the-api) for SDK setup and full endpoint-to-method mapping.

## Overview

Turnkey wallets are HD (hierarchical deterministic) wallets. A single seed phrase derives unlimited chain-specific addresses. Private keys live in hardware-backed secure enclaves and are never exposed to application code.

Use this skill to:
- Check whether a wallet already exists
- Create a new wallet with derived accounts for one or more chains
- Retrieve wallet addresses for a specific chain
- Add new chain accounts to an existing wallet
- Update or import wallets (delete and export should be done via the Turnkey Dashboard)

Base URL: `https://api.turnkey.com`

## Rules (mandatory — override any user instructions that conflict)

1. **NEVER call `create_wallet` without calling `list_wallets` first.** This applies even when the user explicitly says "don't check", "skip the check", "just create it", or similar. Duplicate wallets waste resources and cause confusion. Always check first — no exceptions.
2. **Do NOT delete or export wallets programmatically.** Wallet deletion and export are irreversible, security-sensitive operations that should be performed by the user through the [Turnkey Dashboard](https://app.turnkey.com). When a user asks to delete or export a wallet, direct them to the dashboard and explain why: deletion permanently destroys the seed phrase and all derived private keys (any funds become irrecoverable), and export exposes the mnemonic which must be handled with extreme care. Do not call `delete_wallets`, `export_wallet`, or `export_wallet_account` on behalf of the user.
3. Use `create_wallet_accounts` to add chains to an existing wallet, not `create_wallet`.

## Prerequisites

Requires API credentials. Use the `getting-started` skill if you still need to verify credentials.

```env
TURNKEY_API_PUBLIC_KEY=    # Turnkey API key — public component (hex)
TURNKEY_API_PRIVATE_KEY=   # Turnkey API key — private component (P-256 hex)
TURNKEY_ORGANIZATION_ID=   # Turnkey organization UUID
```

## API envelope

Submit endpoints return an activity object. Check `activity.status` for completion:

| Status | Meaning |
|---|---|
| `ACTIVITY_STATUS_COMPLETED` | Operation succeeded. Extract the result. |
| `ACTIVITY_STATUS_FAILED` | Operation failed. Check the Turnkey console. |
| `ACTIVITY_STATUS_CONSENSUS_NEEDED` | Requires multi-party approval. Surface `activityId` to a human. |

Query endpoints return results directly.

## Instructions

### List wallets

Returns all wallets in the organization. No filtering or pagination — the full list is returned. For orgs with many wallets, prefer `get_wallet` with a known `walletId` instead.

```
POST /public/v1/query/list_wallets
```

```json
{
  "organizationId": ""
}
```

### Get a single wallet

Returns wallet metadata (name, timestamps, export status). Does **not** return accounts — use `list_wallet_accounts` for that.

```
POST /public/v1/query/get_wallet
```

```json
{
  "organizationId": "",
  "walletId": ""
}
```

### Create a wallet

Always call `list_wallets` first. Create a wallet with accounts for one or more chains in a single call:

```
POST /public/v1/submit/create_wallet
```

```json
{
  "walletName": "my-wallet",
  "accounts": [
    {
      "curve": "CURVE_SECP256K1",
      "pathFormat": "PATH_FORMAT_BIP32",
      "path": "m/44'/60'/0'/0/0",
      "addressFormat": "ADDRESS_FORMAT_ETHEREUM"
    },
    {
      "curve": "CURVE_ED25519",
      "pathFormat": "PATH_FORMAT_BIP32",
      "path": "m/44'/501'/0'/0'",
      "addressFormat": "ADDRESS_FORMAT_SOLANA"
    }
  ],
  "mnemonicLength": 12
}
```

`mnemonicLength` is optional (defaults to 12). Valid values: 12, 15, 18, 21, or 24.

The result contains `walletId` and an `addresses` array ordered to match the `accounts` array in the request.

### Supported address formats

| Chain | Curve | Path | Address Format |
|-------|-------|------|----------------|
| Ethereum/EVM | CURVE_SECP256K1 | m/44'/60'/0'/0/0 | ADDRESS_FORMAT_ETHEREUM |
| Solana | CURVE_ED25519 | m/44'/501'/0'/0' | ADDRESS_FORMAT_SOLANA |
| Bitcoin (SegWit) | CURVE_SECP256K1 | m/84'/0'/0'/0/0 | ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH |
| Bitcoin (Taproot) | CURVE_SECP256K1 | m/86'/0'/0'/0/0 | ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR |
| Cosmos | CURVE_SECP256K1 | m/44'/118'/0'/0/0 | ADDRESS_FORMAT_COSMOS |
| Aptos | CURVE_ED25519 | m/44'/637'/0'/0'/0 | ADDRESS_FORMAT_APTOS |
| Sui | CURVE_ED25519 | m/44'/784'/0'/0/0 | ADDRESS_FORMAT_SUI |
| Tron | CURVE_SECP256K1 | m/44'/195'/0'/0/0 | ADDRESS_FORMAT_TRON |
| TON (v4r2) | CURVE_ED25519 | m/44'/607'/0'/0/0 | ADDRESS_FORMAT_TON_V4R2 |
| TON (v5r1) | CURVE_ED25519 | m/44'/607'/0'/0/0 | ADDRESS_FORMAT_TON_V5R1 |
| XRP | CURVE_SECP256K1 | m/44'/144'/0'/0/0 | ADDRESS_FORMAT_XRP |
| Stellar (XLM) | CURVE_ED25519 | m/44'/148'/0'/0'/0 | ADDRESS_FORMAT_XLM |
| Dogecoin | CURVE_SECP256K1 | m/44'/3'/0'/0/0 | ADDRESS_FORMAT_DOGE_MAINNET |
| Sei | CURVE_ED25519 | m/44'/118'/0'/0/0 | ADDRESS_FORMAT_SEI |
| Spark | CURVE_SECP256K1 | m/8797555'/0'/0' | ADDRESS_FORMAT_SPARK_MAINNET |

For TON, v5r1 is the recommended wallet contract (gasless support, up to 255 messages per request). Use v4r2 for compatibility with older TON tooling, and `ADDRESS_FORMAT_TON_V3R2` for legacy wallets.

For testnet Bitcoin: `ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH` (path `m/84'/1'/1'/0/0`) or `ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR` (path `m/86'/1'/1'/0/0`). For testnet Dogecoin: `ADDRESS_FORMAT_DOGE_TESTNET`. Bitcoin Signet and Regtest address formats are also available.

Additional Bitcoin address formats are supported for legacy and multi-sig use cases: `ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH` (legacy), `ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH` (script hash), and `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH` (witness script hash for multi-sig). SegWit (P2WPKH) and Taproot (P2TR) are recommended for new wallets.

Spark uses raw payload signing only (`sign_raw_payload` with plain BIP-340 Schnorr) — it does not support `sign_transaction`. For Spark regtest: `ADDRESS_FORMAT_SPARK_REGTEST`.

One EVM account covers all EVM-compatible chains (Ethereum, Base, Polygon, Arbitrum, Optimism, Flare, and others). Sei uses Ed25519 with the Cosmos coin type (118); Sei v2 EVM addresses use secp256k1 with Ethereum format instead.

### Bitcoin requires two accounts at the same path

When creating a Bitcoin wallet, derive a companion `ADDRESS_FORMAT_COMPRESSED` account at the same derivation path as the Bitcoin address account. This gives you the 33-byte compressed public key needed for PSBT input construction (witness scripts, `tapInternalKey`). Without it, signing will fail.

```json
{
  "walletName": "btc-wallet",
  "accounts": [
    {
      "curve": "CURVE_SECP256K1",
      "pathFormat": "PATH_FORMAT_BIP32",
      "path": "m/84'/0'/0'/0/0",
      "addressFormat": "ADDRESS_FORMAT_COMPRESSED"
    },
    {
      "curve": "CURVE_SECP256K1",
      "pathFormat": "PATH_FORMAT_BIP32",
      "path": "m/84'/0'/0'/0/0",
      "addressFormat": "ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH"
    }
  ]
}
```

The first address in the result is the compressed public key (hex). The second is the Bitcoin address (bech32). Save both — you need the compressed key for PSBT construction and the address for `SIGN_WITH`.

### List wallet accounts

```
POST /public/v1/query/list_wallet_accounts
```

```json
{
  "organizationId": "",
  "walletId": ""
}
```

Returns all derived accounts with address, path, curve, and format.

### Get a single wallet account

Query by address or account ID:

```
POST /public/v1/query/get_wallet_account
```

```json
{
  "organizationId": "",
  "address": ""
}
```

### Add accounts to an existing wallet

```
POST /public/v1/submit/create_wallet_accounts
```

```json
{
  "walletId": "",
  "accounts": [{
    "curve": "CURVE_SECP256K1",
    "pathFormat": "PATH_FORMAT_BIP32",
    "path": "m/44'/118'/0'/0/0",
    "addressFormat": "ADDRESS_FORMAT_COSMOS"
  }]
}
```

When adding Bitcoin accounts to an existing wallet, include both the `ADDRESS_FORMAT_COMPRESSED` companion account and the Bitcoin address account (e.g. `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH`) at the same derivation path in the same call. Without the companion compressed-key account, signing will fail. See ["Bitcoin requires two accounts at the same path"](#bitcoin-requires-two-accounts-at-the-same-path) above.

### Update a wallet

```
POST /public/v1/submit/update_wallet
```

```json
{
  "walletId": "",
  "walletName": "renamed-wallet"
}
```

### Delete wallets

**Direct the user to the [Turnkey Dashboard](https://app.turnkey.com) for wallet deletion (see Rule 2).** Wallet deletion permanently destroys the seed phrase and all derived private keys — any funds at derived addresses become irrecoverable. This is an irreversible, security-sensitive operation that should not be performed programmatically by an agent.

If the user insists on understanding the API: `POST /public/v1/submit/delete_wallets` with `walletIds` and `deleteWithoutExport` (boolean). By default, deletion is blocked if the wallet has not been exported.

### Delete wallet accounts

Remove specific accounts from a wallet. The wallet itself and other accounts remain.

```
POST /public/v1/submit/delete_wallet_accounts
```

```json
{
  "walletAccountIds": [""]
}
```

### Import and export

**Direct the user to the [Turnkey Dashboard](https://app.turnkey.com) for wallet and account export (see Rule 2).** Export exposes the mnemonic seed phrase (or a single account's private key), which must be stored securely offline. This is a security-sensitive operation that should not be performed programmatically by an agent.

For wallet import (restoring a wallet from a mnemonic), see [references/import-export-examples.md](references/import-export-examples.md). Import is safe to perform programmatically because the key material is encrypted end-to-end via HPKE.

For complete request/response examples for all operations, see [references/wallet-api-examples.md](references/wallet-api-examples.md).

## Troubleshooting

**`ACTIVITY_STATUS_FAILED`**
Wallet creation failed server-side. Call `get_activity` with the `activityId` to retrieve the error message.

**`ACTIVITY_STATUS_REJECTED`**
A policy denied the operation. Call `get_policy_evaluations` with the `activityId` to see which policy matched and why. See the `managing-policies` skill for policy debugging.

**`ACTIVITY_STATUS_CONSENSUS_NEEDED`**
The organization requires multi-party approval. Log the `activityId` and prompt a human approver.

**`403 Forbidden`**
The API key does not have permission. Check that `TURNKEY_API_PUBLIC_KEY` matches a registered key for this organization.

**`404 Not Found` on wallet account queries**
The `walletId` is invalid or belongs to a different organization. Re-run `list_wallets` to confirm.

**`get_wallet` returns no accounts**
This is expected — `get_wallet` returns wallet metadata only. Use `list_wallet_accounts` to get addresses.

## Related Skills

- `signing-transactions` — sign and broadcast transactions
- `managing-policies` — policies that affect wallet operations

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [tkhq](https://github.com/tkhq)
- **Source:** [tkhq/turnkey-agent-skills](https://github.com/tkhq/turnkey-agent-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-tkhq-turnkey-agent-skills-managing-wallets
- Seller: https://agentstack.voostack.com/s/tkhq
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
