SDK

xeris-sdk 5.0.0npmMITNode 18+TypeScript

xeris-sdk builds, signs and submits Xeris transactions from Node or the browser.

Quick start

npm install xeris-sdk # https://github.com/ZZachWWins/xeris-sdk
import { XerisClient, XerisKeypair } from 'xeris-sdk'; const client = XerisClient.testnet(); // from keypair_gen, wallet keygen or saveToFile const wallet = XerisKeypair.fromJsonFile('./keypair.json'); const { signature } = await client.transferXrs(wallet, '<recipient>', 1); const tx = await client.waitForConfirmation(signature); console.log(tx.status); // "confirmed"

No faucet. Fund the address first; each transaction costs 0.001 XRS.

Classes

ClassSigns withRuns in
XerisClientyour keypairNode, servers, scripts
XerisDAppthe user's wallet (window.xeris)the browser
XerisAgentthe agent's key, inside an owner's RegisterAgent limitsan agent process
const testnet = XerisClient.testnet(); // 138.197.116.81, ports 56001 and 50008 // throws without a host or XERIS_MAINNET_HOST const mainnet = XerisClient.mainnet('http://<host>'); const custom = new XerisClient('http://<host>', { rpcPort: 56001, explorerPort: 50008 });

Keys

const kp = XerisKeypair.generate(); kp.saveToFile('keypair.json'); // JSON array of 64 bytes, mode 0600 console.log(kp.publicKey); // base58 kp.sign(message); // Ed25519, 64 bytes // the file xrs-node --validator and the wallet CLI read const same = XerisKeypair.fromJsonFile('keypair.json');

Send and confirm

// status "ok" = admitted to the mempool; any {"error"} body throws RpcError const { status, signature } = await client.transferXrs(wallet, to, 1.5); // default 600,000 ms const tx = await client.waitForConfirmation(signature, { timeoutMs: 30_000 }); tx.status; // "confirmed" | "partial" | "failed" | "included" tx.confirmations; // current_slot - block_slot
waitForConfirmation polls GET /v2/tx until the transaction is indexed. Status vocabulary.

Read

await client.getBalance(address); // lamports; 1 XRS = 1,000,000,000 await client.getAccountInfo(address); // data: balance, stake, is_validator, … await client.getStats(); // data: block_height, current_slot, … await client.getBlocks(1, 5); // data: [block], pagination // [{ signature, slot, err, … }] await client.getSignaturesForAddress(address, 20); // RPC port: reward, fees, stake await client.getNetworkEconomics();

Method index

Methods ending in Xrs take XRS as a number or decimal string; every other amount is base units.

Write

MethodInstructionReference
transferXrs(kp, to, xrs), transferLamports(kp, to, lamports)NativeTransfer11
stakeXrs(kp, xrs), unstakeXrs(kp, xrs)Stake, Unstake9, 10
wrapXrs(kp, xrs), unwrapXrs(kp, xrs)WrapXrs, UnwrapXrs13, 14
createToken, mintTokens, transferToken, burnTokensTokenCreate, TokenMint, TokenTransfer, TokenBurn3, 0, 1, 2
createRwaToken, rwaUpdateStatus, rwaTransferTokenCreateRWA, RWAUpdateStatus, RWATransfer6, 7, 8
deployContract, callContractContractDeploy, ContractCall5, 4
swap, swapByToken, addLiquidity, removeLiquidity, buyOnLaunchpad, sellOnLaunchpadContractCall4
submitAttestation(kp, slot, hash32)ValidatorAttestation12
registerAgent, updateAgentRegisterAgent, UpdateAgent15, 16
createIdentity, updateIdentityCreateIdentity, UpdateIdentity18, 19
attestReputation, sendAgentMessageAttestReputation, AgentMessage20, 21
conditionalOrder, cancelConditionalOrderConditionalOrder, CancelConditionalOrder23, 24
registerOracle, oracleSubmitRegisterOracle, OracleSubmit25, 26
hardwareAttestHardwareAttest27
registerCapability, updateCapabilityRegisterCapability, UpdateCapability28, 29
postTask, claimTask, resolveTaskPostTask, ClaimTask, ResolveTask31, 32, 33
registerModel, updateModelRegisterModel, UpdateModel34, 35
openDispute, resolveDispute, slashReportOpenDispute, ResolveDispute, SlashReport36, 37, 38
createProposal, castVote, executeProposalCreateProposal, CastVote, ExecuteProposal39, 40, 41
openChannel, closeChannel, forceCloseChannelOpenChannel, CloseChannel, ForceCloseChannel42, 43, 44
agentHeartbeatAgentHeartbeat45
zkProofSubmit, zkProofVerify, zkVkRegisterZkProofSubmit, ZkProofVerify, ZkVkRegister46, 47, 61
pqKeyRegister, pqKeyRotate, pqAttestPqKeyRegister, PqKeyRotate, PqAttest50, 51, 53
createDeal, acceptDeal, confirmDeal, cancelDeal, disputeDeal, settleDeal, reclaimDealCreateDeal … ReclaimDeal54, 55, 56, 57, 58, 59, 60
sendInstruction(kp, bytes)anyenvelope

Read, RPC port

getHealth()GET /health
getRecentBlocks()GET /blocks
getStakeInfo(addr)GET /stake/{address}
getUnstaking(addr)GET /account/{address}/unstaking
getNetworkEconomics()GET /network/economics
getTokenList()GET /tokens
getTokenBalance(addr, id)GET /token/balance/{address}/{token_id}
getTokenAccounts(addr)GET /token/accounts/{address}
getContracts()GET /contracts
getContract(id)GET /contract/{id}
getContractQuote(id, inputToken, amount)GET /contract/{id}/quote
getVestingStatus(id, wallet)GET /contract/{id}/vesting/{wallet}
getLaunchpads()GET /launchpads
getLaunchpadQuote(id, lamports)GET /launchpad/{id}/quote
getAgentRegistry(owner)GET /agent/registry/{owner}
validateAgent(agent, owner)GET /agent/validate/{agent}/{owner}
agentPlan(body), planTransfer, planSwap, planBuyLaunchpad, planStake, planWrap, planUnwrapPOST /agent/plan
getCapabilities()GET /capabilities
searchCapabilities(params)GET /capabilities/search
getTasks()GET /tasks
getTask(id)GET /tasks/{id}
getZkProofs(identity)GET /zk/proofs/{identity}
getZkProofStatus(id)GET /zk/verify/{proof_id}
getZkStats()GET /zk/stats
getPqKey(addr)GET /pq/keys/{address}
getPqStatus()GET /pq/status
getGovernanceProposals()GET /governance/proposals
getGovernanceLock(addr)GET /governance/lock/{address}
getPriceHistory(pool, limit)GET /price-history
getAllPoolPriceHistory()GET /pools/price-history

Read, explorer port

JSON-RPC
getBalance(addr)getBalance
getAccountInfoRpc(addr)getAccountInfo
getSlot()getSlot
getBlockHeight()getBlockHeight
getLatestBlockhash(), getLatestBlockhashInfo()getLatestBlockhash
getBlockRpc(slot)getBlock
getTransactionRpc(sig)getTransaction
getSignaturesForAddress(addr, limit)getSignaturesForAddress
getHealthRpc()getHealth
getVersion()getVersion
REST v2
getStats()GET /v2/stats
getBlocks(page, size)GET /v2/blocks
getBlockBySlot(slot)GET /v2/block/slot/{slot}
getBlockByHash(hash)GET /v2/block/hash/{hash}
getTransactions(page, size)GET /v2/transactions
getTransaction(sig), waitForConfirmation(sig)GET /v2/tx/{signature}
getAccountInfo(addr)GET /v2/account/{address}
getAccountTransactions(addr, { page, pageSize, before })GET /v2/account/{address}/transactions
getValidators()GET /v2/validators
search(q)GET /v2/search
getTokens({ after, limit })GET /v2/tokens
getTokenHolders(id)GET /v2/token/{id}/holders
getRwaTokens()GET /v2/rwa
getRwa(id)GET /v2/rwa/{id}
getContractsV2()GET /v2/contracts
getContractV2(id)GET /v2/contract/{id}
getPools()GET /v2/pools

Tokens

import { toBaseUnits } from 'xeris-sdk'; // signer = mint authority; maxSupply in base units await client.createToken(wallet, 'mytoken', 'My Token', 'MTK', 9, toBaseUnits('1000000', 9)); // 1,000 MTK await client.mintTokens(wallet, 'mytoken', to, toBaseUnits('1000', 9)); await client.transferToken(wallet, 'mytoken', to, toBaseUnits('50', 9)); // { native_xrs, token_accounts: [{ token_id, balance, … }] } await client.getTokenAccounts(to);

DEX and launchpad

// the DEX and the launchpad spend wrapped XRS await client.wrapXrs(wallet, 10); // POST /agent/plan: amount_in in lamports, slippage 1 % const swap = await client.planSwap(poolId, 'xrs_native', 1_000_000_000, 1); // args: 16 raw bytes, amount_in ‖ min_output, u64 LE (encodeSwapCall) await client.swap(wallet, poolId, swap.params.method, 1_000_000_000, swap.quote.min_amount_out); const buy = await client.planBuyLaunchpad(launchpadId, 1_000_000_000, 1); // args: JSON { xrs_amount, min_tokens_out } await client.buyOnLaunchpad(wallet, launchpadId, 1_000_000_000, buy.quote.min_tokens_out); // any plan: await client.sendInstruction(wallet, fromPlan(plan))

Browser

import { XerisDApp } from 'xeris-sdk'; // { host } for another node; mainnet needs one const dapp = new XerisDApp(); await dapp.connect(); // window.xeris signs; the SDK holds no key await dapp.getBalance(); // the connected address const { signature } = await dapp.transferXrs(to, 5); await dapp.waitForConfirmation(signature);

Agents

await client.registerAgent( owner, 'ari-trader', agentKp.publicKey, 5_000_000_000, // max_per_tx, lamports 10_000_000_000, // max_daily, lamports, per 21,600 slots [], // allowed_contracts, empty = any // allowed_operations, exact strings from AGENT_OPERATIONS ['NativeTransfer', 'WrapXrs', 'UnwrapXrs'], 0, // expires_at_slot, 0 = never );
import { XerisAgent } from 'xeris-sdk'; const agent = XerisAgent.testnet(agentKp, owner.publicKey); await agent.getPermissions(); // { authorized, revoked, expired, agent } // once, before the first heartbeat await agent.createIdentity('Ari Trader', '{}'); // model hash, active tasks, capacity, status await agent.heartbeat('', 1, 9, 'online'); const [task] = await agent.findTasks({ category: 'trading' }); await agent.claimTask(task.task_id); // AgentExecute: runs as the owner, inside the limits await agent.transferXrs(to, 2); // swaps, launchpad buys and Stake cannot be delegated await agent.completeTask(task.task_id, proof);

AgentExecute rules. Design: whitepaper.

Post-quantum keys

import { buildPqRotationMessage, CHAIN_ID_TESTNET } from 'xeris-sdk'; // ML-DSA-65 public key, 1,952 bytes; POST /pq-register await client.pqKeyRegister(wallet, pqPublicKey, 'dilithium3', 3); // { has_pq_key, algorithm, security_level, rotation_count, … } const key = await client.getPqKey(wallet.publicKey); await client.getPqStatus(); const msg = buildPqRotationMessage( CHAIN_ID_TESTNET, pqPublicKey, newPqPublicKey, key.rotation_count); // proof: the current key signs msg, ML-DSA-65, 3,309 bytes await client.pqKeyRotate(wallet, newPqPublicKey, 'dilithium3', proof);

Raw instructions

import { Instructions, encodeU32, encodeU64, encodeString } from 'xeris-sdk'; // 36 bytes; builders take base units, positional, strict arity const ix = Instructions.nativeTransfer(wallet.publicKey, to, 1_000_000_000); // blockhash, sign, POST /submit; up to 16 instructions per transaction await client.sendInstruction(wallet, ix); // the same bytes by hand: u32 variant, then the fields in declaration order Buffer.concat([encodeU32(11), encodeString(wallet.publicKey), encodeString(to), encodeU64(1_000_000_000)]);

Test vectors

npm test npm run test:vectors

Expected bytes: Instruction set.

Removed in 5.0

MethodReasonNow
airdropthe faucet is disabled on the nodeFeatureDisabledError
subDelegatevariant 22 is refused at ingressFeatureDisabledError
zkPrivateTransfer, sendZkPrivateTransfervariant 48 is skipped by the dispatcherFeatureDisabledError
zkIdentityProofvariant 49, sameFeatureDisabledError
pqSignedTransfer, sendPqTransfervariant 52, sameFeatureDisabledError
claimStakingRewardPOST /stake/claim answers 501; rewards pay every 900 blocksFeatureDisabledError
governanceLock, governanceDelegateno lock or delegation instruction existsFeatureDisabledError
XerisAgent.swapTokens, buyOnLaunchpad, sellOnLaunchpad, stakeXrs, unstakeXrscannot be delegatedFeatureDisabledError
buildPqTransferMessage, createZkPrivateTransferProofs, domainHashno on-chain pathremoved