Skip to content

Python SDK

The sigvault-sdk package is the official Python client for the Sigvault API. It wraps the REST and WebSocket endpoints in a typed, async-first interface so you can manage devices, build wallets, prepare transactions and drive remote signing sessions without writing raw HTTP calls.

Terminal window
pip install sigvault-sdk

The SDK requires Python 3.10 or newer. It depends on httpx, websockets, and pydantic v2.

All requests are authenticated with an API key issued from the Sigvault dashboard under Settings > API Keys. Pass it to the client constructor along with the base URL of your Sigvault instance:

from sigvault_sdk import SigVaultClient
client = SigVaultClient(
base_url="https://api.sigvault.io",
api_key="sk_live_...",
)

The client is async and is best used as a context manager so the underlying HTTP connection pool is closed cleanly:

import asyncio
from sigvault_sdk import SigVaultClient
async def main():
async with SigVaultClient("https://api.sigvault.io", "sk_live_...") as client:
wallets = await client.list_wallets()
for w in wallets:
print(w.id, w.name)
asyncio.run(main())

Devices represent the signing keys attached to your account — both hardware wallets registered through the desktop app and system-managed keys hosted by Sigvault.

devices = await client.list_devices()
device = await client.create_device(
name="Treasury Cold Key",
device_type="HARDWARE",
description="Ledger Nano X in vault",
)
await client.update_device_credentials(
device_id=device.id,
xpub="tpubD6N...",
derivation_path="m/48'/1'/0'/2'",
parent_fingerprint="6fb270de",
)

For hardware devices that need an interactive enrollment flow, open a remote session:

session = await client.create_device_session(device.id)
async with await client.connect_session(session.id) as conn:
await conn.initialize()
result = await conn.submit({"action": "register"})

List wallets and inspect their balance, addresses, UTXOs and transaction history:

wallets = await client.list_wallets()
wallet = await client.get_wallet(wallets[0].id)
addresses = await client.get_wallet_addresses(wallet.id, is_change=False)
utxos = await client.get_wallet_utxos(wallet.id)
history = await client.get_wallet_transactions(wallet.id)

To pick up new on-chain activity immediately, trigger a sync:

await client.sync_wallet(wallet.id)

Transactions follow a four-step lifecycle: prepare, request signatures, collect them, then broadcast.

draft = await client.prepare_transaction(
wallet_id=wallet.id,
destination_address="bc1q...",
amount_sats=50_000,
spending_condition_id="primary",
fee_per_byte_sats=8,
)

draft is a PrepareTransactionResponseDTO containing the draft transaction id, the unsigned PSBT, and the computed fee.

For each device that needs to sign, request a signature. System-managed keys are signed automatically; hardware keys are routed to the desktop app.

await client.request_signature(
wallet_id=wallet.id,
draft_transaction_id=draft.draft_transaction_id,
device_id="device_1",
)

Poll for signature state when you need to know when the draft is fully signed:

requests = await client.get_signature_requests(
wallet_id=wallet.id,
draft_transaction_id=draft.draft_transaction_id,
)
details = await client.get_draft_transaction_details(
wallet_id=wallet.id,
draft_transaction_id=draft.draft_transaction_id,
)

Once enough signatures have been collected to satisfy the spending condition, broadcast:

result = await client.broadcast_transaction(
wallet_id=wallet.id,
draft_transaction_id=draft.draft_transaction_id,
)
print(result["txid"])

Some flows — registering a hardware wallet, signing with an air-gapped device, completing an interactive ceremony — run over a WebSocket session. The SDK exposes this through connect_session, which handles token exchange and the WebSocket handshake:

session = await client.create_device_session(device_id)
async with await client.connect_session(session.id) as conn:
await conn.initialize()
response = await conn.submit({"action": "sign", "psbt": psbt_b64})
while response.get("status") == "pending":
response = await conn.wait_for_message()

To enumerate live sessions across all devices on your account:

sessions = await client.list_remote_sessions()

All HTTP failures raise SigVaultAPIError, which exposes both the status code and the API-provided detail message:

from sigvault_sdk.client import SigVaultAPIError
try:
await client.get_wallet("does-not-exist")
except SigVaultAPIError as e:
if e.status_code == 404:
print("wallet not found")
else:
raise

The SDK ships with runnable examples under packages/sdk-python/examples/:

  • device_registration.py — full hardware device enrollment flow over a remote session
  • transaction_signing.py — prepare, sign, and broadcast a transaction end to end

The SDK source lives in the Sigvault monorepo at packages/sdk-python/. File issues and feature requests on the main Sigvault repository.