Blockstream Enterprise Custody SDK
SDK Reference

JS SDK reference

The AMP2 SDK uses three packages. The page explains core classes, request patterns, endpoint domains, pagination, and related guide pages.

The AMP2 SDK is distributed across three packages:

PackagePurpose
@blockstream/crypticBlockstream class, generateUserKeyPairs
@blockstream/amp-registryAMP Zod request/response schemas
@blockstream/ecs-registryECS resource schemas (auth, wallets, etc.)

Note: More bindings coming The JS/TypeScript SDK is the primary integration path today. Additional language bindings (Python, Go, and others) are planned. Contact Blockstream for early access or to request a specific language.

Core classes

Blockstream

The broadcaster class that handles COSE encryption, signing, and HTTP communication.

import { Blockstream } from '@blockstream/cryptic';

new Blockstream(
  rsaPrivateKeyPem: string,        // Client RSA private key (PEM)
  ecdsaPrivateKey: Uint8Array,     // Client ECDSA private key (32-byte seed; Node: Buffer.from(hex, 'hex'))
  deviceUuid: string,              // Device UUID from invite
  serverRsaPubkeyPem: string,     // Server RSA public key (PEM)
  serverEcdsaPubkey: Uint8Array,   // Server ECDSA public key (decode invite hex with Buffer.from(hex, 'hex'))
): Blockstream

broadcastRequest

This is a user implemented helper function. It wraps the COSE encrypt-send-decrypt lifecycle using the Blockstream class. See the Making Requests guide for a full implementation.

async function broadcastRequest<T>(
  request: { action: string; resource: string; details?: object },
  broadcaster: Blockstream,
): Promise<T>

generateUserKeyPairs

Generates RSA-2048 and ECDSA P-256 key pairs for device registration.

import { generateUserKeyPairs } from '@blockstream/cryptic/utils';

const keys = await generateUserKeyPairs();
// keys.rsa.privateKeyPem    - Promise<string> (PKCS#8 PEM) — await to get the string
// keys.rsa.publicKeyPem     - Promise<string> (SPKI PEM)
// keys.ecdsa.privateKeyHex  - string (64 hex chars, P-256 private key)
// keys.ecdsa.publicKeyHex   - string (66 hex chars, compressed P-256)

Use RSA PEMs with await keys.rsa.privateKeyPem (and the same for publicKeyPem) before passing them to Blockstream or registration payloads. For the ECDSA private key material, pass Buffer.from(keys.ecdsa.privateKeyHex, 'hex') (or equivalent Uint8Array) into the Blockstream constructor.

Signing PSETs in JavaScript (lwk_wasm)

Rust docs cover PSET signing with LWK’s SwSigner. In JavaScript, the lwk_wasm package exposes the same signing step:

import { Signer, Mnemonic, Network, Pset, Bip } from 'lwk_wasm';

const signer = new Signer(new Mnemonic(mnemonic), Network.testnet());
const xpub = signer.keyoriginXpub(Bip.bip87());
const signed = signer.sign(new Pset(unsignedPsetBase64));

Typical flow: request an unsigned PSET from AMP2 via COSE, sign locally with lwk_wasm, then submit for cosign and broadcast through the SDK as documented elsewhere.

Wallet domain

ActionResourceRequest schemaResponse detailsGuide
GET/amp/xpub-{ keyorigin_xpub: string }Wallet Registration
ADD/amp/walletsAmpWalletRequestSchema{ wid: string, descriptor: string }Wallet Registration
GET/amp/wallets-{ total_count: number, wallets: WalletWithData[] }Monitoring
GET/amp/wallets/{wid}-{ wid, descriptor, name, locked }Monitoring
GET/amp/wallets/{wid}/balance-Balance map ({ [asset_id]: satoshi })Monitoring
GET/amp/wallets/{wid}/balance/lbtc-LBTC balance mapMonitoring
GET/amp/wallets/{wid}/address-{ address: string, index: number }Wallet Registration
EDIT/amp/wallets/{wid}/set-notes{ name: string }{}Monitoring
ADD/amp/wallets/{wid}/send/lbtc{ recipients: [{ address, satoshi }] }{ pset: string }PSET Lifecycle
EDIT/amp/wallets/{wid}/lock-{}Lock and Unlock
EDIT/amp/wallets/{wid}/unlock-{}Lock and Unlock

Asset domain

ActionResourceRequest schemaResponse detailsGuide
ADD/amp/assets/issueAmpIssueRequestSchema{ pset: string }Asset Issuance
ADD/amp/assets/{aid}/sendAmpSendAssetRequestSchema{ pset: string }Sending Assets
ADD/amp/assets/{aid}/reissueAmpReissueAssetRequestSchema{ pset: string }Reissue and Burn
ADD/amp/assets/{aid}/burnAmpBurnAssetRequestSchema{ pset: string }Reissue and Burn
ADD/amp/wallets/signAmpSignPsetRequestSchema{ pset: string }Asset Issuance
ADD/amp/wallets/broadcastAmpBroadcastRequestSchema{ txid: string }Asset Issuance
EDIT/amp/assets/{aid}/set-notes{ note: object }{}Monitoring

Restriction and control domain

ActionResourceRequest schemaGuide
EDIT/amp/assets/{aid}/wallets/{wid}/restrictionsEditAssetWalletRestrictionRequestSchemaManaging Restrictions
GET/amp/assets/{aid}/wallets/{wid}/restrictions-Managing Restrictions
DELETE/amp/assets/{aid}/wallets/{wid}/restrictions-Managing Restrictions
GET/amp/assets/{aid}/restrictions-Managing Restrictions
GET/amp/assets/v2/{aid}/restrictions-Managing Restrictions
EDIT/amp/assets/{aid}/restrictionsEditAssetWalletRestrictionsListRequestSchemaManaging Restrictions
DELETE/amp/assets/{aid}/restrictions/group/{gid}-Managing Restrictions
EDIT/amp/assets/{aid}/lockAmpLockAssetRequestSchemaLock and Unlock
EDIT/amp/assets/{aid}/unlockAmpUnlockAssetRequestSchemaLock and Unlock
EDIT/amp/assets/{aid}/utxos/{outpoint}/lock-Lock and Unlock
EDIT/amp/assets/{aid}/utxos/{outpoint}/unlock-Lock and Unlock

Monitoring domain

ActionResourceResponse detailsGuide
GET/amp/assets{ total_count: number, assets: Asset[] }Monitoring
GET/amp/assets/{aid}{ asset_id, issuer, name, contract, notes, locked, ... }Monitoring
GET/amp/assets/{aid}/balance{ [wid]: satoshi }Monitoring
GET/amp/assets/{aid}/txos{ total_count: number, txos: Txo[] }Monitoring
GET/amp/assets/{aid}/utxos{ total_count: number, utxos: Utxo[] }Monitoring
GET/amp/assets/{aid}/txs{ total_count: number, txs: Transaction[] }Monitoring
GET/amp/assets/{aid}/txs/unconfirmed{ total_count: number, txs: Transaction[] }Monitoring

Pagination

All list endpoints support pagination via query parameters and return a total_count field in the response.

ParameterTypeDefaultDescription
offsetinteger0Number of items to skip
limitinteger20Maximum items to return

Paginated responses include total_count indicating the full result set size (independent of offset/limit).

Endpoints that support pagination:

  • GET /amp/assets{ total_count, assets }
  • GET /amp/wallets{ total_count, wallets }
  • GET /amp/assets/{aid}/txos{ total_count, txos }
  • GET /amp/assets/{aid}/utxos{ total_count, utxos }
  • GET /amp/assets/{aid}/txs{ total_count, txs }
  • GET /amp/assets/{aid}/txs/unconfirmed{ total_count, txs }
  • GET /amp/assets/{aid}/restrictions (v1 and v2) — { total_count, restrictions }

Request pattern

Every SDK request follows the same structure:

{
  action: 'get' | 'add' | 'edit' | 'delete',
  resource: '/path/to/resource',
  details: { /* request-specific parameters */ },
}

The action field maps to HTTP semantics: get = read, add = create, edit = update, delete = remove.

All schemas are available from @blockstream/amp-registry for AMP endpoints and from @blockstream/ecs-registry for ECS endpoints (auth, spend requests, etc.).

On this page