Blockstream Enterprise
RecipesWallets

Wallet setup prerequisites

Before creating a wallet, ensure you have:

  1. An authenticated user (API or regular user)
  2. The @blockstream/ecs-js-sdk package configured
  3. Appropriate permissions to create signers and wallets

Signer Creation

All wallet types require a signer. The signer holds the cryptographic keys used for transaction signing.

Signer Locations

LocationDescription
hostedKeys managed by the Custody Engine server
externalKeys managed externally (hardware wallets, etc.) - WIP

Note: External signers are currently a work in progress. Use hosted for production deployments.

Creating a Signer

import { v4 as uuidv4 } from 'uuid'

const signerResult = await broadcastRequest({
  action: 'add',
  resource: '/signers',
  details: {
    sid: uuidv4(),
    name: 'my_signer',
    location: 'hosted',
  },
})

const signerId = signerResult.details.sid

Signer Creation Parameters

FieldTypeRequiredDescription
sidUUIDYesUnique identifier for the signer
nameStringYesHuman-readable name
locationStringYesWhere keys are stored (hosted or external)

XPUB Derivation

After creating a signer, derive an extended public key (XPUB) for address generation.

What is an XPUB?

An Extended Public Key (XPUB) is a cryptographic construct that allows generating an unlimited number of public keys (and thus addresses) from a single master key, without exposing the private key.

Why XPUBs matter:

  • Privacy: Generate a new address for each transaction without key management overhead
  • Security: Share the XPUB with watch-only systems that can't spend funds
  • Audit: Accountants/auditors can verify all addresses belong to the same wallet
  • HD Wallets: Follows BIP-32/BIP-44/BIP-87 hierarchical deterministic standards

Derivation

m / purpose' / coin_type' / account' / change / address_index
     87          0 (BTC)        0        0/1      0+
                 1 (testnet)
                1776 (Liquid)
const xpubResult = await broadcastRequest({
  action: 'add',
  resource: `/signers/${signerId}/xpubs`,
  details: {
    id: uuidv4(),
    change: 'receive', // 'receive' or 'change'
  },
})

const keyoriginXpub = xpubResult.details.keyorigin_xpub

XPUB Derivation Parameters

FieldTypeRequiredDescription
idUUIDYesUnique identifier for the XPUB
changeStringYesAddress type (receive or change)

Wallet creation

Address Generation

Each wallet type has its own creation flow, but after creating a wallet, generate addresses to receive funds:

const addressResult = await broadcastRequest({
  action: 'add',
  resource: `/wallets/${walletId}/addresses`,
  details: {
    type: 'receive', // 'receive' or 'change'
    index: 1, // Address index (increment for new addresses)
  },
})

const address = addressResult.details.address

Address Parameters

FieldTypeRequiredDescription
typeStringYesAddress type (receive or change)
indexNumberYesDerivation index (use sequential numbers)

On this page