Skip to main content

WebWallet

A Zcash wallet

This is the main entry point for interacting with this library. For the most part you will only need to create and interact with a Wallet instance.

A wallet is a set of accounts that can be synchronized together with the blockchain. Once synchronized, the wallet can be used to propose, build and send transactions.

Create a new WebWallet with

const wallet = new WebWallet("main", "https://zcash-mainnet.chainsafe.dev", 10);

Adding Accounts

Accounts can be added by either importing a seed phrase or a Unified Full Viewing Key (UFVK). If you do import via a UFVK it is important that you also have access to the Unified Spending Key (USK) for that account otherwise the wallet will not be able to create transactions.

When importing an account you can also specify the block height at which the account was created. This can significantly reduce the time it takes to sync the account as the wallet will only scan for transactions after this height. Failing to provide a birthday height will result in extremely slow sync times as the wallet will need to scan the entire blockchain.

e.g.

const account_id = await wallet.create_account("...", 1, 2657762)

// OR

const account_id = await wallet.import_ufvk("...", 2657762)
``

## Synchronizing

The wallet can be synchronized with the blockchain by calling the `sync` method. This will fetch compact blocks from the connected lightwalletd instance and scan them for transactions.
The sync method uses a built-in strategy to determine which blocks is needs to download and scan in order to gain full knowledge of the balances for all accounts that are managed.

Syncing is a long running process and so is delegated to a WebWorker to prevent from blocking the main thread. It is safe to call other methods on the wallet during syncing although they may take
longer than usual while they wait for a write-lock to be released.

```javascript
await wallet.sync();

Transacting

Sending a transaction is a three step process: proposing, authorizing, and sending.

A transaction proposal is created by calling propose_transfer with the intended recipient and amount. This will create a proposal object that describes which notes will be spent in order to fulfil this request. The proposal should be presented to the user for review before being authorized.

To authorize the transaction the caller must currently provide the seed phrase and account index of the account that will be used to sign the transaction. This method also perform the SNARK proving which is an expensive operation and performed in parallel by a series of WebWorkers. Note: Handing the sensitive key material this way is not recommended for production applications. Upcoming changes to how proposals are authorized will allow separation of proof generation and signing but currently these are coupled.

Finally, A transaction can be sent to the network by calling send_authorized_transactions with the list of transaction IDs that were generated by the authorization step.

The full flow looks like

const proposal = wallet.propose_transfer(1, "...", 100000000);
const authorized_txns = wallet.create_proposed_transactions(proposal, "...", 1);
await wallet.send_authorized_transactions(authorized_txns);

Index

Constructors

constructor

  • new WebWallet(network: string, lightwalletd_url: string, min_confirmations: number, db_bytes?: Uint8Array): WebWallet
  • Create a new instance of a Zcash wallet for a given network. Only one instance should be created per page.

    Arguments

    • network - Must be one of "main" or "test"
    • lightwalletd_url - Url of the lightwalletd instance to connect to (e.g. https://zcash-mainnet.chainsafe.dev)
    • min_confirmations - Number of confirmations required before a transaction is considered final
    • db_bytes - (Optional) UInt8Array of a serialized wallet database. This can be used to restore a wallet from a previous session that was serialized by db_to_bytes

    Examples

    const wallet = new WebWallet("main", "https://zcash-mainnet.chainsafe.dev", 10);

    Parameters

    • network: string
    • lightwalletd_url: string
    • min_confirmations: number
    • optionaldb_bytes: Uint8Array

    Returns WebWallet

Methods

create_account

  • create_account(seed_phrase: string, account_hd_index: number, birthday_height?: number): Promise<number>
  • Add a new account to the wallet using a given seed phrase

    Arguments

    • seed_phrase - 24 word mnemonic seed phrase
    • account_hd_index - ZIP32 hierarchical deterministic index of the account
    • birthday_height - Block height at which the account was created. The sync logic will assume no funds are send or received prior to this height which can VERY significantly reduce sync time

    Examples

    const wallet = new WebWallet("main", "https://zcash-mainnet.chainsafe.dev", 10);
    const account_id = await wallet.create_account("...", 1, 2657762)

    Parameters

    • seed_phrase: string
    • account_hd_index: number
    • optionalbirthday_height: number

    Returns Promise<number>

create_account_ufvk

  • create_account_ufvk(encoded_ufvk: string, birthday_height?: number): Promise<number>
  • Add a new account to the wallet by directly importing a Unified Full Viewing Key (UFVK)

    Arguments

    • key - ZIP316 encoded UFVK
    • birthday_height - Block height at which the account was created. The sync logic will assume no funds are send or received prior to this height which can VERY significantly reduce sync time

    Examples

    const wallet = new WebWallet("main", "https://zcash-mainnet.chainsafe.dev", 10);
    const account_id = await wallet.import_ufvk("...", 2657762)

    Parameters

    • encoded_ufvk: string
    • optionalbirthday_height: number

    Returns Promise<number>

create_proposed_transactions

  • create_proposed_transactions(proposal: Proposal, seed_phrase: string, account_hd_index: number): Promise<any>
  • Generate a valid Zcash transaction from a given proposal

    IMPORTANT: This will spawn a new webworker which will handle the proving task which may take 10s of seconds

    Arguments

    • proposal - A proposal object generated by propose_transfer
    • seed_phrase - 24 word mnemonic seed phrase. This MUST correspond to the accountID used when creating the proposal.
    • account_hd_index - ZIP32 hierarchical deterministic index of the account. This MUST correspond to the accountID used when creating the proposal.

    Returns

    A list of transaction IDs which can be used to track the status of the transaction on the network. The transactions themselves are stored within the wallet

    Examples

    const proposal = await wallet.propose_transfer(1, "u18rakpts0de589sx9dkamcjms3apruqqax9k2s6e7zjxx9vv5kc67pks2trg9d3nrgd5acu8w8arzjjuepakjx38dyxl6ahd948w0mhdt9jxqsntan6px3ysz80s04a87pheg2mqvlzpehrgup7568nfd6ez23xd69ley7802dfvplnfn7c07vlyumcnfjul4pvv630ac336rjhjyak5", 100000000);
    const authorized_txns = await wallet.create_proposed_transactions(proposal, "...", 1);

    Parameters

    • proposal: Proposal
    • seed_phrase: string
    • account_hd_index: number

    Returns Promise<any>

db_to_bytes

  • db_to_bytes(): Promise<Uint8Array>
  • Serialize the internal wallet database to bytes

    This should be used for persisting the wallet between sessions. The resulting byte array can be used to construct a new wallet instance. Note this method is async and will block until a read-lock can be acquired on the wallet database

    Returns

    A postcard encoded byte array of the wallet database


    Returns Promise<Uint8Array>

free

  • free(): void
  • Returns void

get_current_address

  • get_current_address(account_id: number): Promise<string>
  • Get the current unified address for a given account. This is returned as a string in canonical encoding

    Arguments

    • account_id - The ID of the account to get the address for

    Parameters

    • account_id: number

    Returns Promise<string>

get_latest_block

  • get_latest_block(): Promise<bigint>
  • Get the hightest known block height from the connected lightwalletd instance


    Returns Promise<bigint>

get_wallet_summary

propose_transfer

  • propose_transfer(account_id: number, to_address: string, value: bigint): Promise<Proposal>
  • Create a new transaction proposal to send funds to a given address

    Not this does NOT sign, generate a proof, or send the transaction. It will only craft the proposal which designates how notes from this account can be spent to realize the requested transfer.

    Arguments

    • account_id - The ID of the account in this wallet to send funds from
    • to_address - ZIP316 encoded address to send funds to
    • value - Amount to send in Zatoshis (1 ZEC = 100_000_000 Zatoshis)

    Returns

    A proposal object which can be inspected and later used to generate a valid transaction

    Examples

    const proposal = await wallet.propose_transfer(1, "u18rakpts0de589sx9dkamcjms3apruqqax9k2s6e7zjxx9vv5kc67pks2trg9d3nrgd5acu8w8arzjjuepakjx38dyxl6ahd948w0mhdt9jxqsntan6px3ysz80s04a87pheg2mqvlzpehrgup7568nfd6ez23xd69ley7802dfvplnfn7c07vlyumcnfjul4pvv630ac336rjhjyak5", 100000000);

    Parameters

    • account_id: number
    • to_address: string
    • value: bigint

    Returns Promise<Proposal>

send_authorized_transactions

  • send_authorized_transactions(txids: any): Promise<void>
  • Send a list of authorized transactions to the network to be included in the blockchain

    These will be sent via the connected lightwalletd instance

    Arguments

    • txids - A list of transaction IDs (typically generated by create_proposed_transactions)

    Examples

    const proposal = wallet.propose_transfer(1, "u18rakpts0de589sx9dkamcjms3apruqqax9k2s6e7zjxx9vv5kc67pks2trg9d3nrgd5acu8w8arzjjuepakjx38dyxl6ahd948w0mhdt9jxqsntan6px3ysz80s04a87pheg2mqvlzpehrgup7568nfd6ez23xd69ley7802dfvplnfn7c07vlyumcnfjul4pvv630ac336rjhjyak5", 100000000);
    const authorized_txns = wallet.create_proposed_transactions(proposal, "...", 1);
    await wallet.send_authorized_transactions(authorized_txns);

    Parameters

    • txids: any

    Returns Promise<void>

sync

  • sync(): Promise<void>
  • Start a background sync task which will fetch and scan blocks from the connected lighwalletd server

    IMPORTANT: This will spawn a new webworker which will handle the sync task. The sync task will continue to run in the background until the sync process is complete. During this time the main thread will not block but certain wallet methods may temporarily block while the wallet is being written to during the sync.


    Returns Promise<void>