Docs
v1

Guide

WASM module

tenrai-wasm brings the Tenrai rules for transactions, addresses, amounts and wallet keys to browsers and other WebAssembly hosts.

On this page

tenrai-wasm is the protocol code of the node, compiled to WebAssembly. It encodes and checks transactions, derives keys and addresses, and signs. It makes no network requests, stores no wallet and chooses no coins; your application does that and submits the finished transaction.

Use the SDK when you can: its wallet wraps this module and adds coin selection, fees and resending. Use the module directly when you need full control over a transaction, or a host the SDK does not cover.

Get it

The SDK package contains the module (wasm/tenrai_wasm.js, wasm/tenrai_wasm_bg.wasm) and a release.json with their SHA-256 hashes. To build it yourself from the node repository, install the wasm32-unknown-unknown target and wasm-pack, then run:

Shell
pwsh scripts/package-wasm.ps1 -Revision <git revision>

The package lands in crates/wasm/pkg/.

Rules of the interface

  • Every protocol integer is a decimal string. Amounts are never JavaScript numbers.
  • Every transaction call takes the manifest from GET /v1/transactions/manifest as JSON, and refuses a body bound to another chain, protocol version or rule set.
  • network is mainnet, testnet, testnet100 or development.

Build a payment

  1. Describe the body and encode it with encodeTransactionBody(requestJson, manifestJson):

    JSON
    {
      "valid_from_height": "40",
      "valid_until_height": "1840",
      "inputs": [{ "transaction_id": "<96 hex>", "output_index": "0" }],
      "outputs": [{ "address": "trai1…", "amount": "100000000" }],
      "payload_hex": ""
    }

    The fee is implicit: inputs minus outputs. quoteTransaction returns the exact mass and the minimum fee for the body.

  2. Get the message for each input with spendMessage(body, index, previousOutputJson, manifest), where the previous output is { "address": "…", "amount": "…" }.

  3. Sign with WalletRoot.sign(account, branch, index, message, "spend") and wrap each signature with encodeWitness(publicKey, signature).

  4. Assemble the body and the witnesses, inputs first, with assembleTransaction.

  5. Verify with verifyTransaction(wire, previousOutputsJson, ownerAddress, manifest) before the transaction leaves your code.

  6. Submit the hex to POST /v1/transactions.

Smaller inputs

Once an address has spent, its public key is in the chain's key registry and later inputs can refer to it instead of carrying it. Ask POST /v1/keys/registered, then quote with quoteTransactionWithInputProfiles and encode those inputs with encodeWitnessWithProfile("referenced", null, signature). Only use a key the registry reports from a finalized cut.

Bindings

GroupFunctions
ManifestvalidateManifest
BodiesencodeTransactionBody, inspectTransactionBody, transactionId, quoteTransaction, quoteTransactionWithInputProfiles, quoteTransactionWithWitnesses
AuthorizationspendMessage, operationMessage, possessionMessage, encodeWitness, encodeWitnessWithProfile, encodeMultisigInlineWitness, assembleTransaction, inspectTransaction, verifyTransaction, verifyTransactionWithReferencedKeys
MultisigcreateMultisigDescriptor, validateMultisigDescriptor, multisigAddress, createMultisigPackage, decodeMultisigPackage, reviewMultisigPackage, multisigPackageSigningMessages, addMultisigPackageSignatures, combineMultisigPackages, completeMultisigPackage
TextaddressFromPublicKey, parseAddress, burnAddress, parsePaymentUri, parseAmount, formatAmount
Recipient payloadsencodeRecipientPayloads, decodeRecipientPayloads
MessengermessengerLimits, isMessengerPayload, WalletRoot (messengerId, messengerRequest, messengerAccept, messengerMessage, messengerChats)
KeysmnemonicFromEntropy, mnemonicEntropy, WalletRoot (fingerprint, derivePublicKey, sign, signPossession, proveAddress)
Address ownershipaddressVerificationWords, addressProofRequest, verifyAddressProof
Wallet filesealWalletFile, openWalletFile
Service answersserviceIdentityForPublicKey, verifyServiceResponse

Keys

The mnemonic functions turn 32 bytes of entropy into the 24-word phrase and back. WalletRoot derives hardened ML-DSA-65 keys from that entropy, an optional passphrase, an account, a receive or change branch and an index. Signing draws fresh randomness inside the module. Free the WalletRoot when you are done; the module keeps no other key material.

Multisig

The module supports transparent 2-of-3 and 3-of-5 addresses. createMultisigDescriptor(threshold, membersJson) sorts the public keys and returns the descriptor, and multisigAddress(descriptorJson, network) returns its address.

For an offline signing flow, first encode the normal payment body, then call createMultisigPackage(descriptor, body, inputAmountsJson, manifest). Before any key signs, call reviewMultisigPackage(package, manifest) and show its recipients, amounts, fee, inputs, validity window, descriptor, template digest and witness_profile. Give that exact digest to multisigPackageSigningMessages; it returns the member's per-input messages. Add the resulting signatures with addMultisigPackageSignatures.

combineMultisigPackages accepts only partial packages for the same immutable template, descriptor and manifest. Once the review says it is complete, completeMultisigPackage verifies the collected threshold signatures and returns the ordinary wire transaction. createMultisigPackage makes inline packages. A referenced TRMSIGP2 package can be decoded, reviewed, signed, combined and completed without a network lookup; completion checks it locally against its descriptor keys, not that those keys are finalized in the chain registry. This package path is preferred over assembling inline threshold witnesses by hand because it binds every signature to the reviewed transaction template.

Staking operations

A body may carry one staking operation, for example a bond:

JSON
{ "type": "bond", "data": { "validator_id": "<96 hex>", "owner_address": "trai1…", "reward_address": "trai1…", "amount": "100000000000" } }

The owner signs operationMessage(body, manifest) with the purpose operation. Its witness follows the input witnesses.

Type to search guides, concepts and reference pages.