Hanzo

Wallets

Package wallets is blockchain key custody: create wallets, rotate their keys, and sign with them.

Package wallets is blockchain key custody: create wallets, rotate their keys, and sign with them.

Base URLhttps://api.hanzo.ai
Operations8
AuthAuthorization: Bearer $HANZO_API_KEY

wallets

Rolls one wallet's signing material through its own custody backend and answers the wallet with whatever address that produced.

POST /v1/wallets/{id}/keys

Rolls one wallet's signing material through its own custody backend and answers the wallet with whatever address that produced. For KMS custody a fresh secp256k1 key is generated and sealed, which CHANGES the address — funds and approvals at the old address do not move. For a Safe the address is counterfactual and the owner shares are ring-managed, so rotation is a no-op and the address is unchanged. A backend that is not configured fails closed with 503 rather than leaving the wallet half-rotated.

ParameterInTypeRequiredDescription
idpathstringyes

Composes a Safe transaction on the MPC ring and answers its EIP-712 hash together with the owner approval the ring's threshold signature produced.

POST /v1/wallets/{id}/safe-tx

Composes a Safe transaction on the MPC ring and answers its EIP-712 hash together with the owner approval the ring's threshold signature produced. Only a wallet whose custody is "safe" can do this — any other custody is a 400, because the backend itself is asked whether it can propose rather than the kind being switched on. The ring computes the Safe-tx hash bound to the Safe contract and the chain id, so the hash a caller gets back is the one the Safe will verify. This PROPOSES: it does not execute the transaction.

ParameterInTypeRequiredDescription
idpathstringyes

Request bodyapplication/json (required)

FieldTypeRequiredDescription
chainIdintegerChainID is the EVM chain the Safe transaction is bound to.
datastringData is the call data, hex-encoded.
nonceintegerNonce is the Safe's transaction nonce.
tostringTo is the transaction's target address.
valuestringValue is the native-token amount to send, as a decimal string in wei.

Produces a secp256k1 signature from one of the caller org's wallets over a 32-byte digest, through whichever custody backend that wallet uses.

POST /v1/wallets/{id}/sign

Produces a secp256k1 signature from one of the caller org's wallets over a 32-byte digest, through whichever custody backend that wallet uses. Give it either a digest (32 bytes as hex, signed verbatim) or a message (hashed with Keccak256 first) — exactly one is required. The private key never leaves its backend: KMS custody opens the sealed key in-process, MPC custody produces a threshold signature on the ring. The answer carries the digest that was signed alongside the signature, so a caller can verify what it got.

ParameterInTypeRequiredDescription
idpathstringyes

Request bodyapplication/json (required)

FieldTypeRequiredDescription
digeststringDigest is a pre-computed 32-byte digest as hex, with or without the 0x prefix.
messagestringMessage is arbitrary text to hash with Keccak256 and sign.

Returns one of the caller org's wallets: its scope, custody kind, tier, chain and on-chain address.

GET /v1/wallets/{id}

Returns one of the caller org's wallets: its scope, custody kind, tier, chain and on-chain address. The custody handle to the signing material is never part of the answer. A wallet id another org owns reads as not found, so the response cannot confirm that it exists.

ParameterInTypeRequiredDescription
idpathstringyes

Returns the caller org's wallet accounts, newest first.

GET /v1/wallets/accounts

Returns the caller org's wallet accounts, newest first. Accounts are physically org-scoped, so another tenant's are not reachable from here.

Opens a named wallet account for the caller's org.

POST /v1/wallets/accounts

Opens a named wallet account for the caller's org. An account is a GROUPING of wallets, not a key or a balance: wallets are created under one and can be listed by it. The org is stamped by the server from the validated principal, so a request can never open an account in another tenant.

Request bodyapplication/json (required)

FieldTypeRequiredDescription
namestringName is the account's label.

Returns the caller org's wallets, newest first, optionally NARROWED within the org by project, agent or account.

GET /v1/wallets

Returns the caller org's wallets, newest first, optionally NARROWED within the org by project, agent or account. The org is always the bound isolation boundary — the filters only ever narrow inside it, so a caller can never widen past its own org.

ParameterInTypeRequiredDescription
projectquerystringProject narrows to wallets scoped to one project.
agentquerystringAgent narrows to wallets scoped to one agent.
accountquerystringAccount narrows to wallets under one account id.

Provisions a new signing identity under one of the caller org's accounts and answers the stored wallet including its on-chain address.

POST /v1/wallets

Provisions a new signing identity under one of the caller org's accounts and answers the stored wallet including its on-chain address. The custody backend generates the key material — a KMS-sealed secp256k1 key, an MPC threshold key on the ring, or a Safe smart wallet owned by one — and the HANDLE to it is kept server-side and never returned. A custody kind the deployment has not wired fails CLOSED with 503: a signature is never fabricated. The wallet is scoped to the org, the caller's ambient project, and optionally an agent and the named account; those narrowings are what its key ref is derived from, so each must be a url-safe segment.

Request bodyapplication/json (required)

FieldTypeRequiredDescription
accountIdstringAccountID is the account this wallet belongs to.
agentstringAgent optionally narrows the wallet to one agent within the org.
chainstringChain is the EVM chain this wallet is for, as "eip155:<n>" or a bare decimal chain id.
custodystringCustody selects the signing backend: "kms" (in-process, always available), "mpc" or "treasury" (the deployed MPC ring),
namestringName is the wallet's display label.
tierstringTier is the MPC wallet tier: hot, warm, cold, gas, bridge, contract_admin, validator, quarantine or disaster_recovery.

All Hanzo APIs · Interactive reference

How is this guide?

On this page