npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kalp_studio/tresori-sdk-js

v1.2.1

Published

The TreSori SDK provides a unified, high-level API for blockchain wallet operations. It supports three distinct wallet types to accommodate various security models and use cases:

Downloads

406

Readme

TreSori SDK

Overview

The TreSori SDK provides a unified, high-level API for blockchain wallet operations. It supports three distinct wallet types to accommodate various security models and use cases:

  • Self-Custodial: Full user control with local key management
  • Custodial: Service-managed wallets linked to user accounts
  • MPC: Enhanced security through distributed key shards with verification flows

Table of Contents

Features

Self-Custodial Wallets

| Feature | Description | | -------------------------- | ---------------------------------------------------------------- | | Mnemonic Generation | Generate BIP39-compliant mnemonic phrases (12/15/18/21/24 words) | | Wallet Creation | Create wallets from mnemonic with blockchain registration | | Mnemonic Import | Restore wallets from existing mnemonic phrases | | Private Key Import | Import wallets directly from private keys | | Token Transfers | Transfer native tokens (ETH, MATIC, etc.) | | Smart Contract Interaction | Sign and send contract transactions |

Custodial Wallets

| Feature | Description | | --------------------------- | ------------------------------------------------ | | Managed Wallet Creation | Create server-managed wallets linked to user IDs | | Token Transfers | Transfer native and ERC-20 tokens | | Smart Contract Transactions | Execute contract write operations |

MPC Wallets

| Feature | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------------- | | Email / phone verification | OTP flows; after verify you receive session data for MPC signing | | Native & ERC-20 transfers | Sign and broadcast via chain RPC using clientShare, sessionId, rpcUrl | | Gasless ERC-20 (optional) | When the project has gasless enabled, transferMpcTokens with a token address uses permit + relay (EIP-2612) | | Smart contract writes | Encode locally, MPC sign-simple, broadcast raw tx on your rpcUrl |

Multi-Chain Support

  • Dynamic chain configuration loaded at runtime
  • Support for multiple EVM-compatible networks
  • Chain-specific parameters (chain ID, explorer URL, currency)

Installation

Published package name (see package.json):

npm install @kalp_studio/tresori-sdk-js

Or with yarn:

yarn add @kalp_studio/tresori-sdk-js

The package is ESM-only ("type": "module"). Use in Node.js (14+) or in bundlers (Vite, webpack, Metro, etc.).

The SDK lists @noble/hashes, @noble/ciphers, and related @noble/* packages for MPC DKG (ECDH, SHA-256, AES-256-GCM in pure JS, so React Native does not need crypto.subtle for that path).

The example and example-rn apps in this repo depend on the local package as tresori-sdk-js (file:..); their imports use that name. Published apps should import @kalp_studio/tresori-sdk-js as shown above.

React Native

The SDK works in React Native (iOS and Android). The library does not use DOM-only APIs in its published code.

MPC email flow (new vs returning user)

For sendEmailVerificationRequest and verifyEmail, the SDK calls POST /auth/is-mpc-exist with blockchain, network (mapped from your selected chain), and walletIdentifier (email is trimmed and lowercased before server calls). It sets the internal new-user flag to !isMPCExists, then sends/verifies the OTP with the correct backend shape. You do not pass isNewUser on these methods. If the wallet already exists, verify follows the returning-user path (no DKG). If DKG runs for a new user and fails (e.g. missing crypto.getRandomValues on React Native), the SDK returns the raw verify body and logs a console.warn with the error.

Cryptography (MPC DKG on React Native)

MPC DKG: ECDH and SHA-256 use @noble/curves / @noble/hashes. AES-256-GCM uses @noble/ciphers inside the SDK (pure JavaScript) — you do not need react-native-webcrypto or crypto.subtle. UTF-8 for MPC payloads uses ethers’s toUtf8Bytes / toUtf8String so you do not need global TextDecoder / TextEncoder (Hermes often omits TextDecoder, which previously broke dkg-init after email verify).

Secure random: AES-GCM IVs use crypto.getRandomValues. On React Native you must load react-native-get-random-values once at app entry (Android and iOS). That is the standard, maintained polyfill used across the ecosystem (including with ethers).

Dependencies in your React Native app

npm install react-native-get-random-values

Polyfills at app entry (before any other imports)

In your very first entry file (e.g. index.js), run:

import 'react-native-get-random-values';

This repo’s example-rn does this in polyfills.ts, imported first from index.js.

(Optional) Register ethers secure random

If you use react-native-quick-crypto for performance, you can register it with ethers so mnemonic/key generation uses native bytes (unrelated to MPC AES, which stays in @noble/ciphers):

import crypto from 'react-native-quick-crypto';
import { randomBytes } from 'ethers';
randomBytes.register((length) => new Uint8Array(crypto.randomBytes(length)));

Use the SDK as on web

import { TreSoriImpl, ChainListInstance } from '@kalp_studio/tresori-sdk-js';

await TreSoriImpl.instance.initialize(API_KEY);
// Chains are loaded by initialize()
const chain = ChainListInstance.all[0];
// Self-custodial, custodial, MPC APIs are unchanged.

React Native summary

  • Load react-native-get-random-values at entry on Android and iOS so crypto.getRandomValues exists.
  • No react-native-webcrypto is required for TreSori MPC DKG.
  • Phone MPC still requires an explicit isNewUser flag (no is-mpc-exist wiring in the SDK for phone yet).

Quick Start

import { TreSori, ChainListInstance } from '@kalp_studio/tresori-sdk-js';

async function main() {
  // 1. Initialize the SDK with your API key
  await TreSori().initialize('YOUR_API_KEY');

  // 2. Generate a mnemonic phrase
  const mnemonic = TreSori().generateMnemonic();
  console.log('Mnemonic:', mnemonic);

  // 3. Get a chain (after initialize, chains are loaded)
  const selectedChain = ChainListInstance.all[0];

  // 4. Create a wallet
  const wallet = await TreSori().createWallet({
    chain: selectedChain,
    mnemonic,
    userId: 'user_123',
  });

  console.log('Address:', wallet.address);
  console.log('Private Key:', wallet.privateKey);
}

main().catch(console.error);

API Reference

Initialization

initialize(apiKey: string): Promise<void>

Initializes the SDK with your API key. Must be called before any other operations. Loads supported chains from the backend.

await TreSori().initialize('YOUR_API_KEY');

| Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------- | | apiKey | string | ✅ | Your TreSori API key |

Throws: Error if the API key is empty.

get mpcGaslessEnabled(): boolean

Read-only flag: true when the backend enabled-chains response includes gasless for the project (cached when initialize runs, and refreshed via Config when available). Use it to show or hide gasless ERC-20 UI. Actual gasless transfers still require an EIP-2612–compatible token and the arguments described under transferMpcTokens below.

await TreSori().initialize('YOUR_API_KEY');
if (TreSori().mpcGaslessEnabled) {
  // Offer gasless ERC-20 path (see transferMpcTokens)
}

Self-Custodial Wallet

generateMnemonic(opts?: { wordCount?: number }): string

Generates a BIP39-compliant mnemonic phrase.

// Generate 12-word mnemonic (default)
const mnemonic12 = TreSori().generateMnemonic();

// Generate 24-word mnemonic
const mnemonic24 = TreSori().generateMnemonic({ wordCount: 24 });

| Parameter | Type | Default | Description | | -------------- | ------ | ------- | --------------------------------------- | | opts.wordCount | number | 12 | Number of words (12, 15, 18, 21, or 24) |

Returns: string — Space-separated mnemonic phrase

createWallet(args: { chain, mnemonic, userId }): Promise<object>

Creates a new wallet and registers it with the backend.

const result = await TreSori().createWallet({
  chain: selectedChain,
  mnemonic: 'word1 word2 word3 ... word12',
  userId: 'unique_user_id',
});

console.log('Address:', result.address);
console.log('Private Key:', result.privateKey);
console.log('Mnemonic:', result.mnemonic);

| Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | chain | Chain | ✅ | Target blockchain network | | mnemonic | string | ✅ | BIP39 mnemonic phrase | | userId | string | ✅ | Unique user identifier |

Returns: Promise<object>

{
  mnemonic: string,
  privateKey: string,
  address: string,
  userId: string,
}

importWalletFromMnemonic(mnemonic: string): object

Imports an existing wallet from a mnemonic phrase.

const result = TreSori().importWalletFromMnemonic(
  'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
);
console.log('Address:', result.address);
console.log('Private Key:', result.privateKey);

| Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------- | | mnemonic | string | ✅ | Valid BIP39 mnemonic phrase |

Returns: object

{
  privateKey: string,
  address: string,
}

importWalletFromPrivateKey(privateKey: string): object

Imports a wallet from a private key.

const result = TreSori().importWalletFromPrivateKey(
  '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318',
);
console.log('Address:', result.address);

| Parameter | Type | Required | Description | | ---------- | ------ | -------- | --------------------------------------------------- | | privateKey | string | ✅ | Hex-encoded private key (with or without 0x prefix) |

Returns: object

{
  privateKey: string,
  address: string,
}

transferTokens(args): Promise<string>

Transfers native tokens (ETH, MATIC, etc.) to a recipient address.

const txHash = await TreSori().transferTokens({
  chain: selectedChain,
  privateKey: '0x...',
  toAddress: '0xRecipientAddress',
  amount: '1', // in ether (e.g. 1 ETH); uses ethers parseEther
  rpcUrl: 'https://rpc.example.com',
});
console.log('Transaction Hash:', txHash);

| Parameter | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------ | | chain | Chain | ✅ | Target blockchain network | | privateKey | string | ✅ | Sender's private key | | toAddress | string | ✅ | Recipient's wallet address | | amount | string | ✅ | Amount in ether (e.g. "1" for 1 ETH) | | rpcUrl | string | ✅ | RPC endpoint URL |

Returns: Promise<string> — Transaction hash

signContractTransaction(args): Promise<string>

Signs and sends a smart contract transaction.

const txHash = await TreSori().signContractTransaction({
  chain: selectedChain,
  privateKey: '0x...',
  contractAddress: '0xContractAddress',
  contractAbi: [...],
  functionName: 'transfer',
  parameters: ['0xRecipient', 1000],
  transaction: { value: 0n, maxGas: 100000n, ... },
  rpcUrl: 'https://rpc.example.com',
});

| Parameter | Type | Required | Description | | --------------- | ------------------------ | -------- | --------------------------------------------------------------------------------- | | chain | Chain | ✅ | Target blockchain network | | privateKey | string | ✅ | Sender's private key | | contractAddress | string | ✅ | Deployed contract address | | contractAbi | ContractInterface | any | ✅ | Contract ABI (ethers-compatible) | | functionName | string | ✅ | Contract function to call | | parameters | any[] | No | Function parameters | | transaction | object | ✅ | Ethers TransactionRequest fields; use {} to let the wallet fill gas and nonce | | rpcUrl | string | ✅ | RPC endpoint URL |

Returns: Promise<string> — Transaction hash


Custodial Wallet

createCustodialWallet(args: { chain, userId }): Promise<object>

Creates a service-managed custodial wallet.

const result = await TreSori().createCustodialWallet({
  chain: selectedChain,
  userId: 'unique_user_id',
});
console.log('Custodial Address:', result.address);

| Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | chain | Chain | ✅ | Target blockchain network | | userId | string | ✅ | Unique user identifier |

Returns: Promise<object> — Wallet details including address

transferCustodialTokens(args): Promise<object>

Transfers tokens from a custodial wallet.

const result = await TreSori().transferCustodialTokens({
  fromAddress: '0xCustodialWalletAddress',
  toAddress: '0xRecipientAddress',
  amount: '1000000000000000000', // 1 token in wei
  chain: selectedChain,
  tokenAddress: '0xTokenContractAddress', // Optional: for ERC-20 tokens
});

| Parameter | Type | Required | Description | | ------------ | ------ | -------- | ----------------------------------------------- | | fromAddress | string | ✅ | Custodial wallet address | | toAddress | string | ✅ | Recipient address | | amount | string | ✅ | Amount in wei (as string) | | chain | Chain | ✅ | Target blockchain network | | tokenAddress | string | No | ERC-20 token contract address (omit for native) |

Returns: Promise<object> — Transaction response

writeCustodialSmartContractTransaction(args): Promise<object>

Executes a smart contract write operation from a custodial wallet.

const result = await TreSori().writeCustodialSmartContractTransaction({
  contractAddress: '0xContractAddress',
  functionName: 'transfer',
  parameters: ['0xRecipient', 1000],
  contractAbi: [...],
  fromAddress: '0xCustodialWalletAddress',
  chain: selectedChain,
});

| Parameter | Type | Required | Description | | --------------- | ------ | -------- | ------------------------- | | contractAddress | string | ✅ | Deployed contract address | | functionName | string | ✅ | Contract function to call | | parameters | any[] | ✅ | Function parameters | | contractAbi | any[] | ✅ | Contract ABI as array | | fromAddress | string | ✅ | Custodial wallet address | | chain | Chain | ✅ | Target blockchain network |

Returns: Promise<object> — Transaction response


MPC Wallet

isMpcExist(args): Promise<object>

Checks whether an MPC wallet already exists for a chain + identifier (typically the same email you use for OTP).

const { isMPCExists, mpcExistRequest } = await TreSori().isMpcExist({
  chain: selectedChain,
  walletIdentifier: '[email protected]',
});

| Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ---------------------------------------------------------- | | chain | Chain | ✅ | Target chain (blockchain / network mapped for the API) | | walletIdentifier | string | ✅ | e.g. email address |

Returns: isMPCExists (boolean) and mpcExistRequest — the { blockchain, network, walletIdentifier } body sent to /auth/is-mpc-exist (useful for logging).

Email Verification

sendEmailVerificationRequest(args): Promise<object>

Calls isMpcExist with walletIdentifier = trimmed email, then sends the OTP with the correct new-user vs returning-user payload. chain selects blockchain / network for that check and for DKG when applicable.

const result = await TreSori().sendEmailVerificationRequest({
  chain: selectedChain,
  email: '[email protected]',
  userId: 'unique_user_id',
});

| Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | chain | Chain | ✅ | Target blockchain network | | email | string | ✅ | User's email address | | userId | string | ✅ | Unique user identifier |

Returns: Promise<object> — Backend OTP response. On a normal JSON object response, the SDK also merges isMPCExists and mpcExistRequest for client logging.

verifyEmail(args): Promise<object>

Calls isMpcExist again (same rules as send), then verifies the OTP with the matching new-user vs returning-user behavior.

const result = await TreSori().verifyEmail({
  chain: selectedChain,
  email: '[email protected]',
  userId: 'unique_user_id',
  otp: '123456',
});

| Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | chain | Chain | ✅ | Target blockchain network | | email | string | ✅ | User's email address | | userId | string | ✅ | Unique user identifier | | otp | string | ✅ | OTP code from email |

Returns: Promise<object> — Returning users (MPC already exists for that email/chain): response often includes walletAddress, sessionId, and clientShare without DKG. New users: the SDK runs initDKG (dkg-init then dkg-contribute) and returns those fields on success; on failure it returns the raw email-verify payload (see the React Native section). Merged fields isMPCExists and mpcExistRequest are included when the payload is a plain object.

Phone Verification

sendPhoneVerificationCode(args): Promise<object>

Sends an OTP verification code via SMS.

const result = await TreSori().sendPhoneVerificationCode({
  chain: selectedChain,
  countryCode: '+1',
  phone: '5551234567',
  userId: 'unique_user_id',
  isNewUser: true,
});

| Parameter | Type | Required | Description | | ----------- | ------- | -------- | --------------------------------------- | | chain | Chain | ✅ | Target blockchain network | | countryCode | string | ✅ | Country code (e.g. '+1', '+44') | | phone | string | ✅ | Phone number without country code | | userId | string | ✅ | Unique user identifier | | isNewUser | boolean | ✅ | Whether this is a new user registration |

Returns: Promise<object> — Response indicating OTP was sent

verifyPhone(args): Promise<object>

Verifies the phone number using the OTP received.

const result = await TreSori().verifyPhone({
  chain: selectedChain,
  countryCode: '+1',
  phone: '5551234567',
  userId: 'unique_user_id',
  otp: '123456',
  isNewUser: true,
});

| Parameter | Type | Required | Description | | ----------- | ------- | -------- | --------------------------------------- | | chain | Chain | ✅ | Target blockchain network | | countryCode | string | ✅ | Country code | | phone | string | ✅ | Phone number | | userId | string | ✅ | Unique user identifier | | otp | string | ✅ | OTP code from SMS | | isNewUser | boolean | ✅ | Whether this is a new user registration |

Returns: Promise<object> — Verification result with wallet details

MPC token transfers

transferMpcTokens(args): Promise<Record<string, any>>

Single entry point for native, ERC-20 (user pays gas), and gasless ERC-20 MPC transfers. You must complete email (or phone) verification first and persist clientShare, sessionId, and the MPC wallet fromAddress. All paths need a working rpcUrl to the same chain as chain.

Modes

  1. Native (chain currency) — Omit tokenAddress or pass an empty string. Amount is parsed with decimals (default 18), e.g. "1" for one ETH-style unit. The wallet pays gas.
  2. ERC-20 (user pays gas) — Set tokenAddress to the token contract. Set decimals if not 18. Amount is a human-readable token string in those decimals (e.g. "1.5").
  3. Gasless ERC-20 — When mpcGaslessEnabled is true and tokenAddress is non-empty, the implementation routes to the gasless pipeline (permit + relayer). Use platformFee for the fee in token units (same decimals); defaults apply per backend/facilitator rules. Token must support EIP-2612 permits.

When gasless is used via this method, TreSoriImpl supplies built-in sponsor and relayer addresses for the relay flow. To use your own relayer/sponsor, call gaslessTransferTokens instead.

// Native (default 18 decimals → "1" = 1 ETH-style unit)
const native = await TreSori().transferMpcTokens({
  fromAddress: mpcAddress,
  toAddress: '0xRecipient',
  amount: '1',
  chain: selectedChain,
  clientShare,
  sessionId,
  userIdentity: 'email',
  rpcUrl: 'https://sepolia.drpc.org',
});

// ERC-20 (payer pays gas)
const erc20 = await TreSori().transferMpcTokens({
  fromAddress: mpcAddress,
  toAddress: '0xRecipient',
  amount: '10',
  chain: selectedChain,
  clientShare,
  sessionId,
  userIdentity: 'email',
  rpcUrl: 'https://sepolia.drpc.org',
  tokenAddress: '0xToken',
  decimals: 18,
});

// Gasless ERC-20 (only when mpcGaslessEnabled && tokenAddress set)
const gasless = await TreSori().transferMpcTokens({
  fromAddress: mpcAddress,
  toAddress: '0xRecipient',
  amount: '10',
  chain: selectedChain,
  clientShare,
  sessionId,
  userIdentity: 'email',
  rpcUrl: 'https://sepolia.drpc.org',
  tokenAddress: '0xEip2612Token',
  decimals: 18,
  platformFee: '1',
});

| Parameter | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------------------------------------------------------- | | fromAddress | string | ✅ | MPC wallet address | | toAddress | string | ✅ | Recipient address | | amount | string | ✅ | Human amount; decimals applies (default 18) for both native and ERC-20 | | chain | Chain | ✅ | Target chain | | clientShare | string | ✅ | Client share from verify / DKG | | sessionId | string | ✅ | MPC session id | | userIdentity | string | ✅ | Identity channel, e.g. 'email' | | rpcUrl | string | ✅ | Chain JSON-RPC URL | | tokenAddress | string | No | Omit or empty for native; required for ERC-20 and gasless | | decimals | number | No | Token decimals (default 18) when tokenAddress is set | | platformFee | string | No | Gasless: fee in token units (default '1' when gasless path is used) |

Returns: Promise<Record<string, any>> — Backend/RPC payload; often includes txHash / transactionHash (shape may vary by path).

gaslessTransferTokens(args): Promise<Record<string, any>>

Lower-level gasless transfer with explicit relayerAddress and sponsorAddress. The userShards argument is the same secret material as clientShare in other MPC APIs (naming follows the abstract API).

await TreSori().gaslessTransferTokens({
  fromAddress: mpcAddress,
  toAddress: '0xRecipient',
  amount: '10',
  chain: selectedChain,
  userShards: clientShare,
  userIdentity: 'email',
  rpcUrl: 'https://...',
  sessionId,
  tokenAddress: '0xToken',
  relayerAddress: '0x...',
  sponsorAddress: '0x...',
  decimals: 18,
  platformFee: '1',
});

| Parameter | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------------- | | fromAddress | string | ✅ | MPC wallet address | | toAddress | string | ✅ | Recipient | | amount | string | ✅ | Human amount (token decimals) | | chain | Chain | ✅ | Target chain | | userShards | string | ✅ | Client share (same as clientShare elsewhere) | | userIdentity | string | ✅ | e.g. 'email' | | rpcUrl | string | ✅ | Chain RPC | | sessionId | string | ✅ | MPC session | | tokenAddress | string | ✅ | EIP-2612 token | | relayerAddress | string | ✅ | Relayer contract / service address | | sponsorAddress | string | ✅ | Sponsor address | | decimals | number | No | Default 18 | | platformFee | string | No | Fee in token units |

writeMpcSmartContractTransaction(args): Promise<object>

Encodes the call locally, signs with MPC (/v2/wallet/mpc/sign-simple), and broadcasts via your chain RPC (no relayer write-transaction).

const result = await TreSori().writeMpcSmartContractTransaction({
  contractAddress: '0xContractAddress',
  functionName: 'transfer',
  params: ['0xRecipient', '1000000000000000000'],
  abi: ['function transfer(address to, uint256 amount) returns (bool)'],
  fromAddress: '0xMpcWalletAddress',
  chain: selectedChain,
  clientShare: '...', // from verify / DKG
  sessionId: '...',
  rpcUrl: 'https://...',
  value: '0', // optional: wei sent with call (payable)
});

| Parameter | Type | Required | Description | | --------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------- | | contractAddress | string | ✅ | Contract address | | functionName | string | ✅ | Function to call | | params | any[] | ✅ | Function arguments (ethers-compatible) | | abi | string[] | ✅ | Human-readable ethers fragments only (e.g. 'function foo(uint256) external') — not { type, name, … } JSON | | fromAddress | string | ✅ | MPC wallet address | | chain | Chain | ✅ | Target blockchain network | | clientShare | string | ✅ | Client share from verify / DKG | | sessionId | string | ✅ | MPC session id | | rpcUrl | string | ✅ | Chain JSON-RPC URL | | value | string | No | Wei sent with tx (payable functions) |

Returns: Promise<object> — e.g. { txHash } from eth_sendRawTransaction


Wallet Balance

getWalletBalance(args: { address, chain }): Promise<object>

Retrieves the balance of a wallet.

const result = await TreSori().getWalletBalance({
  address: '0xWalletAddress',
  chain: selectedChain,
});
console.log('Balance:', result.balance);

| Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | address | string | ✅ | Wallet address to query | | chain | Chain | ✅ | Target blockchain network |

Returns: Promise<object> — Balance information


Chain Management

After initialize() is called, supported chains are loaded from the backend. Use ChainListInstance or the chain proxy to obtain a Chain for API calls.

import { TreSori, ChainListInstance, chain } from '@kalp_studio/tresori-sdk-js';

await TreSori().initialize('YOUR_API_KEY');

// All available chains
const allChains = ChainListInstance.all;

for (const c of ChainListInstance.all) {
  console.log(`${c.blockchain} - ${c.network}`);
  console.log('  Chain ID:', c.chainId);
  console.log('  Currency:', c.currency);
  console.log('  Explorer:', c.explorerUrl);
}

// Get chain by blockchain and network (e.g. Ethereum Mainnet)
const ethereumMainnet = chain.ethereum.mainnet;

// Get chain by chainId
const chainById = ChainListInstance.ofChainId('1');

Chain shape

Chains are plain objects with the following fields:

| Property | Type | Description | | ----------- | ------ | -------------------------- | | id | number | Internal ID | | blockchain | string | e.g. "Ethereum", "Polygon" | | network | string | e.g. "Mainnet", "Amoy" | | chainId | string | e.g. "1", "80002" | | explorerUrl | string | Block explorer URL | | currency | string | e.g. "ETH", "MATIC" | | logo | string | Logo URL | | createdAt | string | Creation timestamp |


Error Handling

The SDK throws errors for invalid or failed operations. Wrap calls in try/catch (or handle promise rejections).

try {
  await TreSori().initialize('YOUR_API_KEY');

  const wallet = await TreSori().createWallet({
    chain: selectedChain,
    mnemonic,
    userId,
  });
} catch (err) {
  console.error('Error:', err.message);
}

Common errors

| Error | Cause | | --------------------------------------------------------------------- | --------------------------------------------------------------------- | | Wallet not initialized. Call initialize() first. | SDK methods called before initialize() | | API key is required. Call initialize() first. | Empty API key passed to initialize() | | ChainList not loaded. Call "await ChainList.instance.load()" first. | Chains accessed before initialize() (load runs inside initialize) | | Network/HTTP errors | API connectivity or backend failures |


Response Formats

Successful wallet creation

{
  mnemonic: 'word1 word2 ... word12',
  privateKey: '4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318',
  address: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE56',
  userId: 'user_123',
}

Wallet import (mnemonic / private key)

{
  privateKey: '4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318',
  address: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE56',
}

Example apps

Web (/example)

React + Vite demo: initialization, self-custodial and custodial flows, MPC email/phone verification, native and ERC-20 MPC transfers (including gasless when enabled), MPC contract writes with fragment ABI, and chain selection.

cd example
npm install
npm run dev

React Native (/example-rn)

Expo-based (SDK 55, React Native with New Architecture) Android/iOS demo with the same TreSori APIs. The checked-in app targets Android in app.json. Entry index.js loads ./polyfills first so react-native-get-random-values runs before other imports (Android and iOS). MPC DKG uses @noble/ciphers in the SDK, not react-native-webcrypto. Use npm run android:dev / expo run:android or expo run:ios when you need a full native project; after major Expo upgrades run npm run prebuild:android (or npx expo prebuild --platform android) so android/ stays in sync. See React Native above and example-rn/MPC_FLOW_RN.md. On the MPC tab, new vs returning email flow is determined by /auth/is-mpc-exist; the demo logs MPC: New user or MPC: User exists after Send OTP / Verify.

# from repo root
npm run build
cd example-rn
npm install
npm run android:dev
# iOS: npm run ios

Build the SDK from the repo root first when using a local file:.. dependency:

npm run build
cd example && npm install && npm run dev

Exports

The package exports:

  • TreSori — Function that returns the singleton SDK instance: TreSori().initialize(), TreSori().createWallet(), etc.
  • TreSoriImpl — Concrete class with TreSoriImpl.instance (same singleton; useful in RN when you prefer a static entry point).
  • ChainListInstance — Chain list: load(), all, get, ofChainId, isLoaded, and related helpers.
  • chain — Proxy: chain.<blockchain>.<network> (e.g. chain.ethereum.mainnet).
  • parseMpcAbiFragments / parseMpcAbiFragmentsFromText — Normalize MPC contract abi to string[] fragments (human-readable ethers fragments only; rejects JSON ABI objects). The text helper accepts one fragment per line, strict JSON string[], or bracketed lists (including common single-quote paste formats).
  • Abstract TreSori type and re-exports from ./core where applicable for advanced integration.

License

See LICENSE for details.

Support

For issues, feature requests, or questions, please contact the TreSori team.