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/*.
From npm (consumer apps):
npm install @dashevo/wasm-sdk
# or
yarn add @dashevo/wasm-sdkFrom this monorepo (contributors):
# fast for development
yarn build
# or optimized
yarn run build:releaseThe package is ESM-only ("type": "module"). In CommonJS, use dynamic import().
Always call await init() once before using the API. It is idempotent and safe to call multiple times.
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();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');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.wasmConfigure your bundler accordingly. For webpack 5:
// webpack config
module.exports = {
experiments: { asyncWebAssembly: true },
module: { rules: [{ test: /\.wasm$/, type: 'asset/resource' }] },
};The publishable build provides two ways to consume the SDK:
- Single file (default):
import '@dashevo/wasm-sdk'
dist/sdk.jsinlines 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.wasmasset.
- Raw artifacts (opt-in):
import '@dashevo/wasm-sdk/raw'
dist/raw/wasm_sdk.js(unmodified wasm-bindgen output) plusdist/raw/wasm_sdk_bg.wasm.- Your bundler must serve the
.wasmwith 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.
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:releaseUnit tests (Node + browser/Karma):
yarn workspace @dashevo/wasm-sdk test:unitFunctional tests (networked; some cases may be skipped if offline):
yarn workspace @dashevo/wasm-sdk test:functionalExamples (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.
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.
- ESM-only package ("type": "module"). Use dynamic import in CJS.
- Node.js: 16+ recommended (18+ preferred).
- Browsers: modern engines with WebAssembly + Web Workers.
-
"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.
- Ensure you import the default entry (
-
Karma/webpack serving errors:
- Not applicable with the default single-file build. If you opt into
@dashevo/wasm-sdk/raw, configure a.wasmasset rule and correct MIME type.
- Not applicable with the default single-file build. If you opt into
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.
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();