Skip to main content

Coinweb Wallet SDK

Introduction

The Coinweb Wallet SDK consists of the following libraries:

  • @coinweb/wallet-lib:

    • Language: Rust compiled to WebAssembly + TypeScript
    • Description: Bindings to the Rust code in the wallet-lib crate.
  • @coinweb/cweb-wallet-library:

    • Language: TypeScript
    • Description: A TypeScript wrapper for the Rust-based @coinweb/wallet-lib.
  • @coinweb/cweb-wallet-library-rn:

    • Language: TypeScript
    • Description: A TypeScript wrapper for the Rust-based @coinweb/wallet-lib, for use in WASM-challenged environments. In this version, the WASM code is transpiled to plain JavaScript.
  • @coinweb/cweb-vm-lib:

    • Language: Rust compiled to WebAssembly + TypeScript
    • Description: Bindings to the Rust code in the cweb-virtual-machine crate. exposing cweb-vm related code to javascript/typescript executables

    This crate contains the [main computations in Coinweb](/learn/Protocol/Coinweb Computation System#processing-blocks)

  • @coinweb/cweb-tool:

    • Language: TypeScript
    • Description: CLI for working with Coinweb smart contracts.
  • cweb_xxxxx:

    • Language: JavaScript
    • Description: Contract modules containing reusable smart contract logic.

The @coinweb/cweb-wallet-library is a node.js package that acts as a TypeScript wrapper for the Rust-based @coinweb/wallet-lib node.js package.

The @coinweb/cweb-wallet-library and @coinweb/wallet-lib packages are available in two versions:

  1. The primary version is based on WASM.
  2. The secondary version is written purely in JavaScript. It offers the same functionality as the WASM version and is designed for environments where WASM may not be available or is challenging to use, such as React Native.

How to Install the cweb-wallet-library Locally

  1. Create a .npmrc file in the same directory as your package.json file. The contents of the .npmrc file should be:
@coinweb:registry=https://gitlab.com/api/v4/projects/29112346/packages/npm/
//gitlab.com/api/v4/projects/29112346/packages/npm/:_authToken=<AUTH_TOKEN>
  1. To install the latest version of the cweb-wallet-library, use one of the following commands:
npm install @coinweb/cweb-wallet-library

Basic Usage

Creating a Transaction

  1. First, create an instance of TransactionMonitor. This step is only required once:
import { create_tx_monitor, Transaction } from '@coinweb/cweb-wallet-library';

let pending_txs: Transaction[] = ...
// Load pending transactions from local cache (persistent) or from server

let utxos: Map<SigningTxInputId, PaymentUtxoInfo[]> = ...
// Load utxos reserved for this transactions from local cache (persistent) or from server

let tx_monitor = create_tx_monitor(pending_txs, utxos);
  1. Next, create an instance of Wallet:
import { create_wallet, WalletConfig } from '@coinweb/cweb-wallet-library';

//Specify wallet config
let config: WalletConfig = {...};

let wallet = await create_wallet(config);
  1. Subscribe to notifications to receive updates about transaction events:
import { subscribe_to_notifications } from '@coinweb/cweb-wallet-library';

const subscription = subscribe_to_notifications(wallet); // Get `Observable` of events stream

subscription.subscribe((_x) => {}); // Currently there is no need to do anything in handler, but this call is required anyway

Note: To avoid missing any events, use the subscription in conjunction with a polling API (e.g., once every 30 seconds). 4. Execute the Compose L2 transaction from the UI command:

import { compose_send, embed, SendUiCommand } from '@coinweb/cweb-wallet-library';

const command: SendUiCommand = {...};

const l2TransactionData = await compose_send(wallet, command);
  1. Execute the token command:
import { compose_token_command, embed, TokenUiCommand } from '@coinweb/cweb-wallet-library';

const command: TokenUiCommand = {...};

// Compose L2 transaction from token command:
const l2TransactionData = await compose_token_command(wallet, command);

// Prepare L1 transaction base on l2TransactionData and execute it:
const uuid = await embed(wallet, l2TransactionData);

// Retrieve its current status:
const status = await embed_status(wallet, [uuid]);

Each UI command will have a corresponding compose_XXXX function.

The l2TransactionData includes fields that define the cost of fees:

  • wallet_fees — This covers the cost of L1 broadcasting and the broadcaster's profit.
  • network_fees — This covers the fees associated with the Coinweb protocol.

Monitoring Transactions

  1. Once a transaction is created, it must be added to the monitor:
const new_txs = await add_txs(tx_monitor, l2TransactionData.l2_transaction);
  1. After this step, new pending transactions and reserved utxos should be persisted to prevent loss in the event of an app crash or similar incidents.
  2. You can query all current pending transactions using the get_pending_txs function:
const pending_txs = await get_pending_txs(tx_monitor);
  1. You can query all current reserved utxos using the get_all_utxos function:
const reserved_utxos = await get_all_utxos(tx_monitor);
  1. Prepare the L1 transaction and broadcast it:
const embedding_id = await embed(wallet, l2TransactionData.l2_transaction);
  1. Once a transaction is added, tx_monitor will monitor the state of the new transaction and update its status accordingly.
  • Use the get_final_txs function to retrieve transactions that are considered final.
  • Use the get_failed_txs function to retrieve failed transactions.
  • The get_last_updated_txs function returns transactions that were updated since the last call to this function.
  • Use the get_txs function to retrieve a transaction record by its ID.

Resource Management

Both Wallet and TransactionMonitor have a free function. This function should be invoked when an instance is no longer needed, in order to free up memory and other resources held by the instance. If the free function is not called, memory usage will increase over time.

Transaction Signing

The code snippet below demonstrates how to integrate a third-party library for secp256k1 curve ECDSA signing and how to test it:

import {
create_wallet,
from_hex_string,
sign, // This function provides a reference implementation
test_signing
} from '@coinweb/cweb-wallet-library';

const wallet = create_wallet({
...
pub_key: '0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166',
sign_callback: (msg) => {
let secret_key = from_hex_string(
'01010101010101010001020304050607ffff0000ffff00006363636363636363'
);
return sign(secret_key, msg);
},
});

// Call this function to test the `sign_callback` works as expected.
// After each sign, the signature is verified. The `test_signing` performs
// test signing, if no exception is thrown then signing works.

test_signing(wallet);

Error handling

  • All functions in the wallet library throw exceptions of the WalletError type. These exceptions have a tag field that can be used to distinguish between different kinds of errors.
  • Transactions with a TransactionStatus.Error status should be retried if necessary. The Transaction.error field provides details about the error.
  • The WalletError type now includes L1EmbeddingTimeout and L2SuccessTimeout errors to help distinguish between different transaction errors. The Transaction.ui_command field can be used to compose a transaction for a retry.
  • The tx_monitor stores a list of all reserved utxos, which can be retrieved using the get_all_utxos() or get_utxos_for(input_id) functions.

Troubleshooting

The enable_logging function can be used to enable internal logging in the wallet library. This function should be called before any other function in the wallet library.