Skip to content

Latest commit

 

History

History

README.md

WASM SDK

Dash Platform WebAssembly SDK for JavaScript and TypeScript. The core is implemented in Rust and compiled to WebAssembly; a thin ESM wrapper exposes a convenient JS API that works in both Node.js and modern browsers.

The SDK provides:

  • Cryptographic utilities: mnemonic generation/validation, key derivation, key pair generation, address validation, message signing.
  • Platform state transitions and queries: identities, documents, data contracts, tokens, groups, epochs/system, voting, proofs (when supported).
  • A builder pattern (WasmSdkBuilder) to configure and construct a client for network-backed queries.

This package ships a single-file ESM build (dist/sdk.js) with the Wasm inlined and compiled off the main thread in browsers. Advanced users can also opt into separate raw artifacts under dist/raw/*.


Install

From npm (consumer apps):

npm install @dashevo/wasm-sdk
# or
yarn add @dashevo/wasm-sdk

From this monorepo (contributors):

# fast for development
yarn build
# or optimized
yarn run build:release

The package is ESM-only ("type": "module"). In CommonJS, use dynamic import().


Usage

Always call await init() once before using the API. It is idempotent and safe to call multiple times.

Node.js (ESM)

import init, * as sdk from '@dashevo/wasm-sdk';

// Initialize Wasm (Node uses an inlined binary; no assets to load)
await init();

// Crypto helpers
const { address } = sdk.generate_key_pair('testnet');
console.log('Address:', address);

// Optional: enable logs (silent by default)
await sdk.WasmSdk.setLogLevel('warn'); // or 'info' | 'debug' | full filter

// Platform queries via a client
let builder = sdk.WasmSdkBuilder.testnetTrusted();
builder = builder.withSettings(5000, 10000, 3, true);
const client = await builder.withLogs('warn').build();

const DPNS = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
const docs = await client.getDocuments({
  dataContractId: DPNS,
  documentTypeName: 'domain',
  limit: 5,
});
console.log('Docs:', docs.length);

client.free();

Browser (bundler, ESM)

import init, * as sdk from '@dashevo/wasm-sdk';

// Initialize Wasm (browser compiles in a Web Worker; no separate .wasm files)
await init();

const ok = sdk.validate_address('yXXX...', 'testnet');

Advanced: raw artifacts (separate .wasm)

If you prefer to manage the .wasm file via your bundler, import the raw entry explicitly:

import init, * as sdk from '@dashevo/wasm-sdk/raw';
await init(); // wasm-bindgen will resolve and fetch wasm_sdk_bg.wasm

Configure your bundler accordingly. For webpack 5:

// webpack config
module.exports = {
  experiments: { asyncWebAssembly: true },
  module: { rules: [{ test: /\.wasm$/, type: 'asset/resource' }] },
};

How bundling works

The publishable build provides two ways to consume the SDK:

  1. Single file (default): import '@dashevo/wasm-sdk'
  • dist/sdk.js inlines the Wasm (base64) to avoid asset pipelines and MIME issues.
  • Browser: compiles the inlined bytes in a Web Worker to avoid main-thread stalls and 8MB sync limits; then instantiates on the main thread.
  • Node: uses the inlined bytes with initSync internally; you still call await init() for a consistent API.
  • The wrapper imports a sanitized variant of the wasm-bindgen glue so bundlers do not "see" any new URL('…wasm') and therefore will not emit a .wasm asset.
  1. Raw artifacts (opt-in): import '@dashevo/wasm-sdk/raw'
  • dist/raw/wasm_sdk.js (unmodified wasm-bindgen output) plus dist/raw/wasm_sdk_bg.wasm.
  • Your bundler must serve the .wasm with the correct content type and URL rewriting.

Why this design?

  • Eliminate flaky Wasm asset handling in test/dev and simplify consumer setup.
  • Keep an escape hatch for asset-pipeline users.

Build (contributors)

Prerequisites: Rust toolchain, wasm-pack, and (optionally) Binaryen for optimized builds.

Commands (run at repo root or inside packages/wasm-sdk):

# Development build (fast)
yarn workspace @dashevo/wasm-sdk build

# Release build (optimized)
yarn workspace @dashevo/wasm-sdk build:release

Test (contributors)

Unit tests (Node + browser/Karma):

yarn workspace @dashevo/wasm-sdk test:unit

Functional tests (networked; some cases may be skipped if offline):

yarn workspace @dashevo/wasm-sdk test:functional

API highlights

Examples (after await init()):

// Addresses & keys
const { address, private_key_wif } = sdk.generate_key_pair('mainnet');
sdk.validate_address(address, 'mainnet');
const addr = sdk.pubkey_to_address('02...pubkeyHex', 'testnet');

// Mnemonics & derivation
const m = sdk.generate_mnemonic(12);
const r = sdk.derive_key_from_seed_with_path(m, undefined, "m/44'/5'/0'/0/0", 'mainnet');

// Network client
let b = sdk.WasmSdkBuilder.testnetTrusted();
const client = await b.withSettings(5000, 10000, 3, true).withLogs('info').build();
const status = await client.getStatus();
client.free();

The full surface includes identity, document, contract, token, group, epoch/system, and proof helpers.

Logging

By default, the SDK is silent. You can enable tracing logs globally or via the builder:

// Globally
await sdk.WasmSdk.setLogLevel('info');

// Or on the builder (applies immediately)
await sdk.WasmSdkBuilder.new_testnet().withLogs('wasm_sdk=debug,rs_dapi_client=warn').build();

Accepted values are simple levels ('off'|'error'|'warn'|'info'|'debug'|'trace') or a full EnvFilter string.


Environment & compatibility

  • ESM-only package ("type": "module"). Use dynamic import in CJS.
  • Node.js: 16+ recommended (18+ preferred).
  • Browsers: modern engines with WebAssembly + Web Workers.

Troubleshooting

  • "expected magic word 00 61 73 6d …" in browsers:

    • Ensure you import the default entry (@dashevo/wasm-sdk), not the raw one, unless you have configured Wasm assets.
    • Always await init() before calling functions.
  • Karma/webpack serving errors:

    • Not applicable with the default single-file build. If you opt into @dashevo/wasm-sdk/raw, configure a .wasm asset rule and correct MIME type.

Contributing & License

This package is part of the Dash Platform monorepo. Follow the repository’s contribution guidelines and do not commit secrets. See the root repository for license details.


State transitions

In addition to read-only queries, the SDK exposes helpers to construct and submit state transitions (requires a networked client and valid inputs):

import init, * as sdk from '@dashevo/wasm-sdk';
await init();

const builder = sdk.WasmSdkBuilder.testnetTrusted();
const client = await builder.build();

// Identity create (example — requires a valid proof and keys)
const proofJson = JSON.stringify({ /* platform-provided proof object */ });
const assetLockWif = 'Kx...';
const pubKeysJson = JSON.stringify([
  { keyType: 'ECDSA_SECP256K1', purpose: 'AUTHENTICATION', securityLevel: 'MASTER', privateKeyHex: '...' },
]);
await sdk.identityCreate(proofJson, assetLockWif, pubKeysJson)
  .then(() => {/* submitted */})
  .catch((e) => {/* handle error */});

// Token transfer (negative example if parameters are invalid)
await sdk.tokenTransfer('contractId', 0, '1000', 'senderIdentityId', 'recipientIdentityId', assetLockWif, null)
  .catch(() => {});

client.free();