Options
All
  • Public
  • Public/Protected
  • All
Menu

Package wallet-sdk

@stacks/wallet-sdk

@stacks/wallet-sdk is a library for building wallets for the Stacks blockchain.

Features

  • Generate a wallet from scratch
  • Encrypt a wallet with a password
  • Restore a wallet and associated accounts
  • Generate new accounts in a wallet
  • Sign transactions for the Stacks blockchain
  • Register usernames on BNS, the naming service built into the Stacks Blockchain

Key Concepts

Secret Key

A Secret Key is a 12 or 24 word mnemonic phrase, which can be used to deterministically generate a wallet and any number of addresses. When the same Secret Key is used, the exact same addresses will be generated. The Secret Key acts as an easily rememberable and highly secure mechanism for backing up a wallet.

Secret Keys conform to the BIP 39 standard.

Wallet

A "wallet" is a set of private keys for an individual user. A wallet will contain any number of accounts.

Account

Accounts act as a way for users to separate assets and data within their own account. You could think of accounts like different Google accounts while logged into Gmail. You can easily switch between different accounts, but they all have different data and information.

  • Each account is associated with an individual Stacks address.
  • Each account has its own balance and state on the blockchain.
  • Accounts can have usernames.
  • When a user logs in through a wallet, they choose an individual account from their wallet.
  • Application data is completely segregated from different accounts.
  • External parties have no way of knowing that two accounts belong to the same wallet

Derivation paths

Private keys are generated according to the BIP32 and BIP44 standards.

The "coin type" for the Stacks blockchain is 5757.

The private key for each account's STX address is derived from m/44'/5757'/0'/0/n, where n is the index of the account.

Usage

Installation

With NPM:

npm install @stacks/wallet-sdk --save

With Yarn:

yarn add @stacks/wallet-sdk

Generate a Secret Key

By default, a random 24-word Secret Key is generated, using 256 bits of entropy. You can generate a random 12-word key by passing 128 as the entropy argument.

import { generateSecretKey } from '@stacks/wallet-sdk';

const secretKey = generateSecretKey();
// aunt birth lounge misery utility blind holiday walnut fuel make gift parent gap picnic exact various express sphere family nerve oil drill engage youth

const secretKey128 = generateSecretKey(128);
// winter crash infant long upset beauty cram tank short remove decade ladder

Generate a wallet

Create a random Secret Key and a Wallet object. When a wallet is generated, the first account is automatically generated as well.

import { generateWallet, generateSecretKey } from '@stacks/wallet-sdk';

const password = 'password';
const secretKey = generateSecretKey();

const wallet = await generateWallet({
secretKey,
password,
});

A Wallet is a normal JavaScript object with the following properties:

interface Wallet {
/** Used when generating app private keys, which encrypt app-specific data */
salt: string;
/** The private key associated with the root of a BIP39 keychain */
rootKey: string;
/** A private key used to encrypt configuration data */
configPrivateKey: string;
/** The encrypted secret key */
encryptedSecretKey: string;
/** A list of accounts generated by this wallet */
accounts: Account[];
}

Generating new accounts

Accounts allow users to use separate Stacks addresses from within the same wallet. Each account has it's own Stacks address and balance. When a user logs into an app, they choose a specific account.

When using generateNewAccount, the new account is created with next index, based on the existing accounts in a wallet. For example, if a wallet has 5 accounts, calling generateNewAccount will make the sixth account.

import { generateNewAccount } from '@stacks/wallet-sdk';

const account = generateNewAccount(wallet);

An Account is a JavaScript object with these properties:

interface Account {
/** The private key used for STX payments */
stxPrivateKey: string;
/** The private key used in Stacks 1.0 to register BNS names */
dataPrivateKey: string;
/** The salt is the same as the wallet-level salt. Used for app-specific keys */
salt: string;
/** A single username registered via BNS for this account */
username?: string;
/** A profile object that is publicly associated with this account's username */
profile?: Profile;
/** The root of the keychain used to generate app-specific keys */
appsKey: string;
/** The index of this account in the user's wallet. Zero-indexed */
index: number;
}

Restoring accounts for an existing Wallet

When a user restores their wallet in a new app, you can automatically restore any previously-used accounts from the same wallet. It will also restore any usernames owned by this user.

The private keys used to encrypt this data is derived from the path m/44/5757'/0'/1. This data is stored in Gaia, the decentralized storage system in the Stacks network. Users can host their own Gaia hub, and this library's API can use that Gaia hub, if provided.

import { restoreWalletAccounts } from '@stacks/wallet-sdk';

const restoredWallet = await restoreWalletAccounts({
// `baseWallet` is returned from `generateWallet`
wallet: baseWallet,
gaiaHubUrl: 'https://hub.blockstack.org',
network: new StacksMainnet(),
});

Making an authentication response

With an account, you can generate an authentication response, which conforms to the Stacks authentication protocol. The resulting authResponse is a string, representing a signed JSON web token. Learn more about the authentication protocol.

// The transit public key is provided in an "authentication request"
const transitPublicKey = 'xxxx';

const authResponse = await makeAuthResponse({
gaiaHubUrl: 'https://hub.blockstack.org',
appDomain: 'https://example-app.com',
transitPublicKey,
scopes: ['publish_data'],
// `account` is one of the user's accounts
account,
});

Usage with @stacks/transactions

This library is meant to be used in conjunction with the @stacks/transactions library for signing transactions.

Getting an account's STX address

import { getStxAddress } from '@stacks/wallet-sdk';
import { TransactionVersion } from '@stacks/transactions';

// get an account from the user's wallet
const account = wallet.accounts[0];

const testnetAddress = getStxAddress({ account, transactionVersion: TransactionVersion.Testnet });
const mainnetAddress = getStxAddress({ account, transactionVersion: TransactionVersion.Mainnet });

Signing Stacks Transactions

You can generate signed transactions by following the documentation from @stacks/transactions. Use the stxPrivateKey of an account as the senderKey option when creating a transaction.

import { makeSTXTokenTransfer, StacksMainnet } from '@stacks/transactions';

const network = new StacksMainnet();

// get an account from the user's wallet
const account = wallet.accounts[0];

const txOptions = {
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 12345n,
senderKey: account.stxPrivateKey,
network,
};

const transaction = await makeSTXTokenTransfer(txOptions);

Index

Type Aliases

AllowedKeyEntropyBits: 128 | 256

Variables

HARDENED_OFFSET: 2147483648 = 0x80000000

Functions

  • createWalletGaiaConfig(__namedParameters: { gaiaHubUrl: string; wallet: Wallet }): Promise<GaiaHubConfig>
  • Parameters

    • __namedParameters: { gaiaHubUrl: string; wallet: Wallet }
      • gaiaHubUrl: string
      • wallet: Wallet

    Returns Promise<GaiaHubConfig>

  • decrypt(dataBuffer: string | Buffer, password: string): Promise<string>
  • Decrypt an encrypted mnemonic phrase with a password. Legacy triplesec encrypted payloads are also supported.

    Parameters

    • dataBuffer: string | Buffer
    • password: string

      Password for data

    Returns Promise<string>

    the raw mnemonic phrase

  • Parameters

    Returns Account

  • Derive the configPrivateKey for a wallet.

    This key is derived from the path m/5757'/0'/1, using 1 for change option, following the bip44 recommendation for keys relating to non-public data.

    This key is used to encrypt configuration data related to a wallet, so the user's configuration can be synced across wallets.

    Parameters

    • rootNode: BIP32Interface | HDKey

      A keychain that was created using the wallet's seed phrase

    Returns Buffer

  • deriveDataPrivateKey(__namedParameters: { index: number; rootNode: BIP32Interface | HDKey }): string
  • Parameters

    Returns string

  • deriveLegacyConfigPrivateKey(rootNode: BIP32Interface | HDKey): string
  • Before the Stacks Wallet, the authenticator used with Connect used a different format and path for the config file.

    The path for this key is m/45'

    Parameters

    • rootNode: BIP32Interface | HDKey

      A keychain that was created using the wallet's seed phrase

    Returns string

  • Generate a salt, which is used for generating an app-specific private key

    Parameters

    Returns Promise<string>

  • deriveStxPrivateKey(__namedParameters: { index: number; rootNode: BIP32Interface | HDKey }): string
  • Parameters

    Returns string

  • encrypt(phrase: string, password: string): Promise<Buffer>
  • Encrypt a raw mnemonic phrase to be password protected

    Parameters

    • phrase: string

      Raw mnemonic phrase

    • password: string

      Password to encrypt mnemonic with

    Returns Promise<Buffer>

    The encrypted phrase

  • encryptWalletConfig(__namedParameters: { wallet: Wallet; walletConfig: WalletConfig }): Promise<string>
  • Parameters

    Returns Promise<string>

  • fetchUsernameForAccountByDerivationType(__namedParameters: { derivationType: Wallet | Data; index: number; network?: StacksNetwork; rootNode: BIP32Interface | HDKey }): Promise<{ username: undefined | string }>
  • generateNewAccount(wallet: Wallet): { accounts: Account[]; configPrivateKey: string; encryptedSecretKey: string; rootKey: string; salt: string }
  • Parameters

    Returns { accounts: Account[]; configPrivateKey: string; encryptedSecretKey: string; rootKey: string; salt: string }

    • accounts: Account[]
    • configPrivateKey: string

      A private key used to encrypt configuration data

    • encryptedSecretKey: string

      The encrypted secret key

    • rootKey: string

      The private key associated with the root of a BIP39 keychain

    • salt: string

      Used when generating app private keys, which encrypt app-specific data

  • Parameters

    Returns string

  • generateWallet(__namedParameters: { password: string; secretKey: string }): Promise<Wallet>
  • Generate a new Wallet.

    Parameters

    • __namedParameters: { password: string; secretKey: string }
      • password: string
      • secretKey: string

    Returns Promise<Wallet>

  • getAccountDisplayName(account: Account): string
  • Get the display name of an account.

    If the account has a username, it will return the first part of the username, so myname.id => myname, and myname.blockstack.id => myname.

    If the account has no username, it returns Account ${acount.index}

    Parameters

    Returns string

  • getAppPrivateKey(__namedParameters: { account: Account; appDomain: string }): string
  • Parameters

    • __namedParameters: { account: Account; appDomain: string }

    Returns string

  • getGaiaAddress(account: Account): string
  • Parameters

    Returns string

  • getRootNode(wallet: Wallet): HDKey
  • Parameters

    Returns HDKey

  • makeAuthResponse(__namedParameters: { account: Account; appDomain: string; appPrivateKeyFromWalletSalt?: null | string; fetchFn?: FetchFn; gaiaHubUrl: string; scopes?: string[]; transitPublicKey: string }): Promise<string>
  • Parameters

    • __namedParameters: { account: Account; appDomain: string; appPrivateKeyFromWalletSalt?: null | string; fetchFn?: FetchFn; gaiaHubUrl: string; scopes?: string[]; transitPublicKey: string }
      • account: Account
      • appDomain: string
      • Optional appPrivateKeyFromWalletSalt?: null | string
      • Optional fetchFn?: FetchFn
      • gaiaHubUrl: string
      • Optional scopes?: string[]
      • transitPublicKey: string

    Returns Promise<string>

  • Parameters

    Returns WalletConfig

  • Restore wallet accounts by checking for encrypted WalletConfig files, stored in Gaia.

    This helps provide a better UX for users, so we can keep track of accounts they've created, and usernames they've used.

    Parameters

    Returns Promise<Wallet>

  • selectStxDerivation(selectionOptions: { index: number; network?: StacksNetwork; rootNode: BIP32Interface | HDKey; username?: string }): Promise<{ stxDerivationType: DerivationType; username: undefined | string }>
  • Tries to find a derivation path for the stxPrivateKey for the account defined by rootNode and index that respects the username of that account and that respects the given derivationType.

    The stxPrivateKey is used to sign the profile of the account, therefore, a username must be owned by the stxPrivateKey.

    If a username is provided, a lookup for the owner address on the provided network is done.

    If no username is provided, a lookup for names owned by the stx derivation path and by the data derivation path is done.

    If derivationType other than Unknown is given this derivation type is enforced.

    Parameters

    Returns Promise<{ stxDerivationType: DerivationType; username: undefined | string }>

    username and derivation type

Generated using TypeDoc