@kagamidigital/salt-sdk-mirror
    Preparing search index...

    @kagamidigital/salt-sdk-mirror

    TypeScript NPM Version Documentation

    Salt SDK

    TypeScript client for Salt, an open MPC self-custodial infrastructure for organisations. With Salt, anyone can spin up a system of self-sovereignty for self-custodial wealth management, including delegations to 3rd parties such as asset managers, robo-advisors or agents.

    ⚠️ Pre-release software. Before upgrading:

    • Accounts created with this version are incompatible with previous versions.
    • Testnet accounts will be wiped in an upcoming release - do not treat them as long-term.
    • Mainnet is not yet supported — this version creates testnet accounts only.

    📃 API Reference

    npm install salt-sdk viem
    

    viem is a peer dependency.

    import { Salt } from 'salt-sdk';
    import {
    createPublicClient,
    createWalletClient,
    http,
    parseEther,
    type Hex,
    } from 'viem';
    import { privateKeyToAccount } from 'viem/accounts';
    import { arbitrumSepolia, sepolia } from 'viem/chains';

    // Create an instance — TESTNET uses Arbitrum Sepolia for orchestration
    const salt = new Salt({ environment: 'TESTNET' });

    // Set up a viem wallet client (orchestration chain must match the environment)
    const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
    const walletClient = createWalletClient({
    account,
    chain: arbitrumSepolia,
    transport: http(),
    });

    // Authenticate with SIWE
    await salt.authenticate(walletClient);

    // Fetch your organisations and accounts
    const orgs = await salt.getOrganisations();
    const accounts = await salt.getAccounts(orgs[0].id);

    // Submit a native ETH transfer to Sepolia
    const publicClient = createPublicClient({
    chain: sepolia,
    transport: http(process.env.SEPOLIA_RPC_URL),
    });

    const ceremony = await salt.submitTx({
    accountId: accounts[0].id,
    to: '0x000000000000000000000000000000000000dEaD',
    value: parseEther('0.01'),
    chainId: 11155111,
    userAddress: account.address,
    walletClient,
    publicClient,
    });

    // Track progress: proposing → signing → broadcasting → confirming → success | failure
    ceremony.on('stateChanged', ({ stage }) => console.log('tx is now', stage));

    // Wait for MPC signing + broadcast to complete
    const { transaction } = await ceremony.wait();
    console.log('tx hash:', transaction.txHash);

    See More: Salt constructor · authenticate · getOrganisations · getAccounts · submitTx

    Every Salt transaction involves two networks:

    • Orchestration network — where MPC signing coordination happens. Set by the environment:
    • Destination network — where the transaction actually executes. Set by chainId + publicClient in submitTx. Can be any supported EVM chain.
    const ceremony = await salt.submitTx({
    /* ... */
    });

    ceremony.on('stateChanged', ({ stage }) => {
    console.log('transaction is now', stage);
    // proposing → signing → broadcasting → confirming → success | failure
    });

    const { transaction } = await ceremony.wait();

    See More: submitTx · TransactionHostCeremony

    Policies control which transactions robo guardians will co-sign. Create them per account and chain. If a transaction violates a policy, the robos refuse to sign and it fails before broadcast.

    // Restrict ERC-20 approve() calls: only allow a specific spender, cap the amount
    await salt.createAccountPolicy({
    accountId: accounts[0].id,
    organisationId: orgs[0].id,
    type: 'contract_param_restriction',
    chain: '11155111', // Sepolia
    params: {
    restrictions: [
    {
    contractAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238', // USDC on Sepolia
    functionSignature: 'approve(address,uint256)',
    paramIndex: 0, // spender argument
    operator: 'eq',
    value: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
    },
    {
    contractAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
    functionSignature: 'approve(address,uint256)',
    paramIndex: 1, // amount argument
    operator: 'lte',
    value: '1000000', // 1 USDC (6 decimals)
    },
    ],
    },
    });

    See More: createAccountPolicy · ContractParamRestriction · PolicyParams

    Pass encoded calldata via data. The transaction below is valid against the contract_param_restriction policy above — the spender matches and the amount is within the cap.

    import { encodeFunctionData, parseAbi } from 'viem';

    const data = encodeFunctionData({
    abi: parseAbi(['function approve(address spender, uint256 amount)']),
    functionName: 'approve',
    args: [
    '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // allowed spender
    500_000n, // 0.5 USDC — within the 1 USDC cap
    ],
    });

    const ceremony = await salt.submitTx({
    accountId: accounts[0].id,
    to: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238', // USDC on Sepolia
    value: 0n,
    chainId: 11155111,
    data,
    userAddress: account.address,
    walletClient,
    publicClient,
    });

    await ceremony.wait();

    See More: submitTx · SendTransactionParams

    Organisations group collaborators and own accounts. Accounts are MPC wallets: humans create them via a key-generation ceremony and become signers. Fetch what the authenticated user belongs to with getOrganisations and getAccounts, create new ones with createOrganisation and createAccount, and manage collaborators with inviteCollaborator.

    See examples: createOrganisation · inviteCollaborator · updateCollaborator · createAccount · getOrganisations · getAccounts

    Robos belong to an organisation, and are automated co-signers for accounts. Manage robo hosts with createRoboHost and getRoboHost.

    See examples: Salt constructor · createRoboHost · getRoboHost · RoboHost

    Full API reference and more examples at kagamidigital.github.io/salt-sdk-mirror.