Skip to main content
ALL CHAINS

Wallet SDK Ecosystem

The Elastos wallet stack is implemented across six repositories in four languages (TypeScript/JavaScript, C++, C, and Java). These libraries are not drop-in replacements for general-purpose Bitcoin wallets: the Elastos main chain uses NIST P-256 (secp256r1) for signing, not Bitcoin’s secp256k1. Integration code that assumes Bitcoin or Ethereum key semantics on the main chain will fail in subtle, expensive ways.

Why this matters

If you port patterns from bitcoinjs-lib, MetaMask-style secp256k1 flows, or raw Ethereum ECDSA on the main chain, signatures and addresses will not validate. Use the official SDKs, or replicate their exact curve, path, and encoding rules.

Overview

DimensionDetail
Repositories6
LanguagesTypeScript/JS, C++, C, Java
Main chain curveNIST P-256 (secp256r1)
Sidechain (ESC/EID)secp256k1 (standard Ethereum ECDSA)
HD standardsBIP32 / BIP39 / BIP44 (with Elastos-specific path and curve usage)

The JS/TS SDK (Elastos.ELA.Wallet.JS.SDK) is the primary choice for web and Node.js: full HD wallet, transaction building, and P-256 signing. The C++ SPV library is the heavy reference used by mobile (e.g. Essentials) with JNI/Cordova bridges. Lower-level Keypair libraries (C and JavaScript) target embedded or minimal runtimes. Elastos.ELA.Utilities.Java suits server-side signing and exchange backends. Elastos.Connectivity.Client.JS.SDK does not implement wallet crypto; it standardizes dApp ↔ wallet connectivity (connectors, session flow).

SDK matrix

SDKLanguageKey classes / surfacePrimary use
Elastos.ELA.Wallet.JS.SDKTypeScriptMasterWallet, SubWallet (e.g. main chain, ID chain)Web/Node wallets, transaction construction and signing
Elastos.ELA.SPV.CppC++IMasterWallet, ISubWalletNative mobile, multi-chain HD, SPV light client
Elastos.SDK.Keypair.CCKey generation, sign/verify, ECIESLow-level crypto, firmware, constrained environments
Elastos.SDK.Keypair.JavascriptJavaScriptKey generation, address derivationBrowser-only key ops without full wallet stack
Elastos.ELA.Utilities.JavaJavaTransaction building, Jetty-hosted RPCJava services, custodial/exchange integration
Elastos.Connectivity.Client.JS.SDKTypeScriptIConnector, connectivity layerdApp bridge to installed wallets (no chain signing in-library)
Choosing an SDK
  • Full product wallet (web/desktop scripting): JS SDK.
  • iOS/Android native with sync: C++ SPV.
  • Minimal footprint or FFI from another language: Keypair C or Keypair JS.
  • JVM microservice: Utilities Java.
  • dApp only: Connectivity Client JS SDK plus a wallet that implements the connector.

Cryptographic foundations

Curves and chains

  • HD derivation: BIP32 / BIP39 / BIP44; master seed from mnemonic, hierarchical children.
  • Elastos main chain (ELA): ECDSA on NIST P-256 (secp256r1).

Derivation paths (conceptual)

PurposeTypical path patternNotes
Main chainm/44'/0'/0'/...BIP44 coin type 0; P-256 math for main-chain keys
DID / identity-orientedm/44'/0'/0'/0/<index>Used in identity flows per wallet design

Address format specification

Elastos standard addresses are Base58Check-encoded payloads built from the public key and version metadata.

Version bytes (prefix semantics)

Version byteRoleTypical leading character
0x21Standard single-sig addressStarts with E
0x12Multi-signature addressStarts with 8
0x4BCross-chain deposit addressStarts with X
0x1FDeposit address (BPoS node registration)Starts with D
0x3FBPoS (DPoSV2) staking addressStarts with SN
0x67DID (identity) addressStarts with i

Encoding pipeline (high level)

  1. Public keyredeem script (script construction as defined by the chain).
  2. SHA-256 of script, then RIPEMD-160 → 20-byte hash.
  3. Prepend version byte.
  4. Checksum: double SHA-256, take first 4 bytes, append.
  5. Base58 encode the result.
Base58Check, not “Bitcoin address”

The pipeline resembles Bitcoin’s P2PKH shape, but version bytes, script templates, and signing curve are Elastos-specific. Do not feed outputs into Bitcoin tooling and expect validity on Elastos.

Transaction model

  • Model: UTXO-based (like Bitcoin): inputs consume prior outputs; outputs create new UTXOs.
  • Types: 40+ distinct transaction / payload types identified by a type byte in the transaction header (exact enumeration lives in protocol and SDK sources).
  • Representative payload kinds:
    • TransferAsset (0x02): ordinary value transfer.
    • RegisterProducer (0x09): BPoS validator registration.
    • TransferCrossChainAsset (0x08): cross-chain movement.
    • CRCProposal (0x25): CR council proposal payloads.
  • Structure: Inputs reference previous txid + output index; outputs carry amount, lock, and payload. Change returns unspent value to a sender-controlled output.
Fee and change

When building txs, explicitly allocate fee and a change output back to your wallet’s address; otherwise the difference is lost to fees or invalidates the tx.

JS SDK (primary) deep dive

The published npm package is @elastosfoundation/wallet-js-sdk. The API centers on MasterWalletManager, MasterWallet, and chain-specific SubWallet / MainchainSubWallet instances that share HD state and enforce curve/path rules inside walletcore (e.g. HDKey, DeterministicKey, Secp256, EcdsaSigner).

Typical flow

  1. Create or restore a master from BIP39 mnemonic + password (encryption for local storage).
  2. createSubWallet('ELA') (or the symbol your build uses for main chain) for main-chain UTXO operations.
  3. Build an unsigned raw transaction from inputs, outputs, fee, optional memo.
  4. Sign with the sub-wallet key using the user password (P-256 ECDSA).
  5. Broadcast the signed raw transaction via your node’s JSON-RPC (for example sendrawtransaction) using hex from convertToRawTransaction; there is no publishTransaction on the sub-wallet typings.

Example (illustrative TypeScript)

The following matches typings/ in @elastosfoundation/wallet-js-sdk: you must supply WalletStorage, network id, and ConfigInfo as required by MasterWalletManager.create. Names of ConfigInfo / storage helpers are taken from the SDK exports.

import {
MasterWalletManager,
type MainchainSubWallet,
type UTXOInput,
} from '@elastosfoundation/wallet-js-sdk';

// storage: WalletStorage; netType: string; config: ConfigInfo — from the SDK
async function sendElaExample(
storage: Parameters<typeof MasterWalletManager.create>[0],
netType: string,
config: Parameters<typeof MasterWalletManager.create>[2]
) {
const mnemonic = 'your twelve or twenty four word mnemonic here ...';
const payPassword = 'strong-user-password';

const manager = await MasterWalletManager.create(storage, netType, config);
const master = await manager.createMasterWallet(
'wallet-id',
mnemonic,
'',
payPassword,
false
);
const subWallet = (await master.createSubWallet('ELA')) as MainchainSubWallet;

const inputs = [] as UTXOInput[]; // populate from listunspent / your indexer
const outputs = [
{ Address: 'E...recipient...', Amount: '100000000' },
{ Address: 'E...change...', Amount: '...' },
];
const fee = '10000';
const memo = '';

const encoded = subWallet.createTransaction(inputs, outputs, fee, memo);
const signed = await subWallet.signTransaction(encoded, payPassword);
const rawHex = subWallet.convertToRawTransaction(signed);
// Broadcast rawHex with your ELA node JSON-RPC sendrawtransaction
return rawHex;
}
Password handling

Never log mnemonics or passwords. In production, derive signing keys in secure enclaves where available, and encrypt keystores at rest using the SDK’s AES paths as intended.

API recap (conceptual)

MethodRole
MasterWalletManager.create(storage, netType, config)Create a manager bound to persistence and network
manager.createMasterWallet(id, mnemonic, passphrase, payPassword, singleAddress)Restore or create a MasterWallet
master.createSubWallet('ELA')Main chain sub-wallet (MainchainSubWallet, UTXO, P-256)
subWallet.createTransaction(inputs, outputs, fee, memo)Assemble unsigned EncodedTx
subWallet.signTransaction(encoded, payPassword)Sign with P-256 derived key
subWallet.convertToRawTransaction(signed)Raw hex for sendrawtransaction

C++ SPV library (Elastos.ELA.SPV.Cpp)

  • Full HD wallet with SPV (Simplified Payment Verification) light-client behavior.
  • Multi-chain: ELA, ID, BTC, ETH, Ripple (scope as implemented in the repo you vendor).
  • Mobile integration: Used by Elastos Essentials via JNI / Cordova bridges, not a hypothetical binding.
  • Networking / sync: Bloom filters for relevant transaction discovery; local persistence typ. SQLite for wallet state.
  • Interfaces: IMasterWallet, ISubWallet mirror the logical split seen in JS (MasterWallet / sub-wallets).
When to prefer C++ SPV

Choose this path when you need on-device sync, minimal trust in third-party full nodes for balance proofs, or tight integration with native iOS/Android codebases already shipping Essentials-style plugins.

Elastos.SDK.Keypair.C and Elastos.SDK.Keypair.Javascript

  • C library: Minimal surface: key generation, ECDSA sign/verify, ECIES for encrypted payloads, and helpers aligned with raw transaction and address experiments. Ideal for embedded targets or custom language bindings.
  • JavaScript library: Browser-friendly key generation and address derivation without pulling the entire wallet/SPV stack, useful for air-gapped or client-only flows when combined with your own transport and UTXO selection.

Elastos.ELA.Utilities.Java

  • Focus on server-side and automation: transaction construction, utilities, and a Jetty-based RPC server pattern for signing or orchestration behind your API gateway.
  • Typical in exchange or custodial backends where JVM ops teams standardize on Java.

Elastos.Connectivity.Client.JS.SDK

  • Exposes IConnector and connectivity primitives so dApps can discover and talk to external wallets (Essentials, etc.).
  • Does not replace wallet cryptography: it is the session and message layer between web apps and wallet apps.
// IConnector is defined in @elastosfoundation/elastos-connectivity-sdk-js (see package typings).
// It does not expose a generic sign(bytes): use getWeb3Provider() for EVM, or DID/credential APIs for identity.
import { Interfaces } from '@elastosfoundation/elastos-connectivity-sdk-js';

function getEvmProvider(connector: Interfaces.Connectors.IConnector) {
return connector.getWeb3Provider();
}
Separation of concerns

Treat Connectivity as transport + UX for “which wallet signs,” and keep ELA.Wallet.JS.SDK (or SPV/Keypair) for actual chain signing when you author a wallet yourself.

Two curves, one mnemonic

A single BIP39 mnemonic can feed both P-256 and secp256k1 derivations on different paths. Never “reuse” a Bitcoin mainnet path and expect ELA main-chain compatibility; the curve and address rules differ.

Security considerations

TopicGuidance
Key storageUse password-based encryption (AES) for keystores; never persist raw private keys as plaintext.
MnemonicsStore offline; restrict clipboard access on mobile/web; consider hardware-backed storage.
Integration errorsThe #1 source of mistakes is confusing P-256 (main chain) with secp256k1 (ESC/EID); validate against test vectors and official SDKs.
OperationalRotate API keys for broadcast endpoints; rate-limit and authenticate Jetty/RPC surfaces in Java utilities.
Raw private keys

Never store, log, or transmit unencrypted private keys. If you must export, use encrypted containers and short-lived, audited flows.

Summary

The Elastos wallet ecosystem gives you six complementary codebases: a primary TypeScript SDK for application developers, a C++ SPV reference for mobile and sync-heavy wallets, lean Keypair libraries in C and JS, Java utilities for server workflows, and a Connectivity SDK for dApp ↔ wallet UX. Success depends on respecting P-256 on the main chain, correct version bytes and Base58Check, UTXO transaction typing, and strict separation between main-chain and EVM-sidechain cryptography.


Further reading: Protocol details evolve; always cross-check transaction type bytes, address version bytes, and npm package names against the latest tagged releases in each GitHub repository before production deployment.