Selendra

Documentation

TypeScript SDK API Reference

Complete API documentation for Selendra TypeScript SDK v1.0.0.

Implementation Status:

  • Substrate APIs: 100% production-ready
  • React Hooks: 100% production-ready
  • Unified Accounts: 95%
  • EVM APIs: 50% [BETA]
  • Rust SDK: 58% - separate documentation

npm version
Tests

SelendraSDK

Main SDK class with builder pattern configuration.

const sdk = new SelendraSDK()
  .withEndpoint("https://rpc.selendra.org")
  .withNetwork(Network.Selendra)
  .withChainType(ChainType.Substrate);

await sdk.connect();

Core Methods

MethodReturnsDescription
connect()Promise<void>Connect to network
disconnect()Promise<void>Disconnect and cleanup
isConnected()booleanCheck connection status
getApi()ApiPromiseGet Polkadot.js API instance
createAccount(mnemonic?)AccountCreate/restore account
getBalance(address)Promise<Balance>Query balance
getChainInfo()Promise<ChainInfo>Get chain info
getAccounts()Promise<Account[]>Get all available accounts

Substrate APIs

StakingClient

Staking operations for nominators and validators.

const staking = new StakingClient(api);

Query Methods

MethodReturnsDescription
getValidators()Promise<ValidatorInfo[]>Get all active validators
getNominators()Promise<NominatorInfo[]>Get all nominators
getNominatorsByTarget(address)Promise<string[]>Get nominators for validator
getCurrentEra()Promise<EraInfo>Get current era info
getStakingInfo(address)Promise<StakingInfo>Get detailed staking info
calculateRewards(address)Promise<RewardInfo>Calculate staking rewards
isValidator(address)Promise<boolean>Check if address is validator
isNominator(address)Promise<boolean>Check if address is nominator
// Query examples
const validators = await staking.getValidators();
const era = await staking.getCurrentEra();
const info = await staking.getStakingInfo(address);

Transaction Methods

MethodParametersDescription
bond(signer, amount, controller)signer, amount: string, controller: stringBond tokens
bondExtra(signer, amount)signer, amount: stringBond additional tokens
unbond(signer, amount)signer, amount: stringUnbond tokens
withdrawUnbonded(signer)signerWithdraw unbonded tokens
nominate(signer, targets)signer, targets: string[]Nominate validators
chill(signer)signerStop nominating/validating
validate(signer, prefs)signer, prefs: ValidatorPrefsStart validating
// Transaction examples
await staking.bond(signer, "1000000000000", controller);
await staking.nominate(signer, [validator1, validator2]);
await staking.unbond(signer, "500000000000");
await staking.withdrawUnbonded(signer);

AlephClient

Aleph Zero finality consensus operations.

const aleph = new AlephClient(api);

Methods

MethodReturnsDescription
getCurrentSession()Promise<number>Get current session number
getSessionValidators()Promise<string[]>Get session validators
getAuthorities()Promise<string[]>Get current authorities
isCurrentAuthority(address)Promise<boolean>Check if address is authority
getFinalizedBlockNumber()Promise<number>Get latest finalized block
getFinalityStatus()Promise<FinalityStatus>Get finality status info
const session = await aleph.getCurrentSession();
const validators = await aleph.getSessionValidators();
const finalized = await aleph.getFinalizedBlockNumber();

ElectionsClient

Council elections operations.

const elections = new ElectionsClient(api);

Query Methods

MethodReturnsDescription
getMembers()Promise<Member[]>Get elected council members
getRunnersUp()Promise<RunnerUp[]>Get runners-up candidates
getCandidates()Promise<string[]>Get all current candidates

Transaction Methods

MethodParametersDescription
vote(signer, candidates, amount)signer, candidates: string[], amount: stringVote for candidates (max 16)
removeVoter(signer)signerRemove vote and unbond
submitCandidacy(signer)signerSubmit candidacy
renounceCandidacy(signer)signerRenounce candidacy
const members = await elections.getMembers();
await elections.vote(signer, [candidate1, candidate2], amount);
await elections.submitCandidacy(signer);

DemocracyClient

Governance proposals and referendums.

const democracy = new DemocracyClient(api);

Query Methods

MethodReturnsDescription
getReferendums()Promise<Referendum[]>Get all active referendums
getProposals()Promise<Proposal[]>Get all proposals

Transaction Methods

MethodParametersDescription
propose(signer, hash, value)signer, proposalHash: string, value: stringSubmit proposal
vote(signer, refIndex, vote)signer, refIndex: number, vote: VoteVote on referendum
delegate(signer, target, conviction)signer, target: string, conviction: ConvictionDelegate voting power
const referendums = await democracy.getReferendums();
await democracy.propose(signer, proposalHash, value);
await democracy.vote(signer, refIndex, { aye: true });

Unified Accounts

Convert and manage addresses between Substrate and EVM formats.

const accounts = new UnifiedAccountManager(api);

Methods

MethodParametersReturnsDescription
substrateToEvm(address)address: stringstringConvert Substrate to EVM address
evmToSubstrate(address)address: stringstringConvert EVM to Substrate address
validateAddress(address)address: stringValidationResultValidate address format
getEvmAddressFromMapping(address)address: stringPromise<string | null>Get on-chain mapped EVM address
claimDefaultEvmAddress(signer)signerPromise<TransactionResult>Claim default EVM address
getUnifiedBalance(address)address: stringPromise<Balance>Get balance for either format
// Address conversion
const evmAddr = accounts.substrateToEvm("5GrwvaEF...");
const subAddr = accounts.evmToSubstrate("0x742d35Cc...");

// Validation
const validation = accounts.validateAddress(address);

// On-chain mapping
const mapped = await accounts.getEvmAddressFromMapping(substrateAddr);
await accounts.claimDefaultEvmAddress(signer);

// Balance query
const balance = await accounts.getUnifiedBalance(address);

React Hooks

React integration for real-time data and state management.

Available Hooks

HookParametersReturnsDescription
useSelendra()-{ isConnected, connect, disconnect }Connection management
useBalance(address)address: string{ balance, loading, error }Real-time balance updates
useAccount()-{ account, setAccount }Account management
useTransaction()-{ submit, status, error }Transaction submission
useContract(address)address: string{ contract, call, send }Contract interaction
useEvents()-{ events, subscribe }Event subscription
useBlockSubscription()-{ block, number, hash }Block updates
import {
  useSelendra,
  useBalance,
  useAccount,
  useTransaction,
} from "@selendrajs/sdk";

function Component() {
  const { isConnected, connect } = useSelendra();
  const { balance } = useBalance(address);
  const { account } = useAccount();
  const { submit } = useTransaction();

  return <div>Balance: {balance?.free.toString()}</div>;
}

Core Types

Network & Chain

enum Network {
  Selendra = "selendra",
  Custom = "custom",
}

enum ChainType {
  Substrate = "substrate",
  EVM = "evm",
}

type NetworkType = "mainnet" | "testnet" | "custom";

Account & Balance

interface Account {
  address: string;
  name?: string;
  type: "substrate" | "evm";
  publicKey: string;
}

interface Balance {
  free: bigint;
  reserved: bigint;
  frozen: bigint;
  total: bigint;
  tokenSymbol: string;
  decimals: number;
}

Validator & Staking

interface ValidatorInfo {
  address: string;
  commission: number;
  blocked: boolean;
  totalStake: string;
  ownStake: string;
  nominators: string[];
}

interface StakingInfo {
  address: string;
  staked: string;
  unlocking: UnlockingChunk[];
  available: string;
  isValidator: boolean;
  isNominator: boolean;
  nominations: string[];
}

interface UnlockingChunk {
  value: string;
  era: number;
}

Elections & Governance

interface Member {
  address: string;
  stake: string;
  backers: number;
}

interface Referendum {
  index: number;
  proposalHash: string;
  end: number;
  threshold: "SuperMajorityApprove" | "SuperMajorityAgainst" | "SimpleMajority";
  delay: number;
  tally: { ayes: string; nays: string; turnout: string };
}

Chain & Finality

interface ChainInfo {
  chainName: string;
  chainId: number;
  version: string;
  specVersion: number;
  implVersion: number;
  tokenDecimals: number;
  tokenSymbol: string;
}

interface FinalityStatus {
  finalizedBlock: number;
  currentBlock: number;
  lag: number;
}

Transaction & Events

interface Transaction {
  hash: string;
  from: string;
  to: string;
  amount?: bigint;
  data?: string;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
  maxPriorityFeePerGas?: bigint;
  nonce?: number;
  blockNumber?: number;
  blockHash?: string;
  status: "pending" | "included" | "finalized" | "failed";
  events: TransactionEvent[];
  timestamp?: number;
}

type EventType =
  | "transfer"
  | "contract.deployed"
  | "contract.interaction"
  | "block"
  | "error"
  | "connected"
  | "disconnected";

interface EventData {
  type: EventType;
  data: any;
  timestamp: number;
}

Register as a validator.

async validate(
  signer: any,
  preferences: ValidatorPreferences
): Promise<TransactionResult>

Parameters

interface ValidatorPreferences {
  commission: number; // 0-100
  blocked: boolean;
}

Example

await staking.validate(signer, {
  commission: 10, // 10%
  blocked: false,
});

Account Management

createAccount()

Creates a new account with a randomly generated mnemonic.

async createAccount(options?: CreateAccountOptions): Promise<CreatedAccount>

Parameters

  • options (optional) - Account creation options
interface CreateAccountOptions {
  type?: "substrate" | "evm" | "both";
  name?: string;
  password?: string;
  derivationPath?: string;
}

Returns

interface CreatedAccount {
  mnemonic: string;
  address: string;
  publicKey: string;
  type: "substrate" | "evm" | "both";
}

Example

const account = await sdk.createAccount({
  type: "both",
  name: "My Wallet",
});

console.log("Mnemonic:", account.mnemonic);
console.log("Address:", account.address);

importAccountFromMnemonic()

Imports an account from a mnemonic phrase.

async importAccountFromMnemonic(
  mnemonic: string,
  options?: ImportAccountOptions
): Promise<Account>

Example

const account = await sdk.importAccountFromMnemonic("word1 word2 word3 ...", {
  type: "substrate",
  derivationPath: "//m/44'/354'/0'/0'/0'",
});

importAccountFromPrivateKey()

Imports an account from a private key.

async importAccountFromPrivateKey(
  privateKey: string,
  options?: ImportAccountOptions
): Promise<Account>

getBalance()

Gets the balance of an account.

async getBalance(address: string): Promise<Balance>

Returns

interface Balance {
  free: bigint;
  reserved: bigint;
  frozen: bigint;
  total: bigint;
  tokenSymbol: string;
  decimals: number;
}

Example

const balance = await sdk.getBalance(
  "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
);
console.log(`Free balance: ${balance.free} ${balance.tokenSymbol}`);

Transactions

transfer()

Transfers tokens to another address.

async transfer(options: TransferOptions): Promise<Transaction>

Parameters

interface TransferOptions {
  to: string;
  amount: bigint | string | number;
  from?: string;
  memo?: string;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
  maxPriorityFeePerGas?: bigint;
}

Returns

interface Transaction {
  hash: string;
  from: string;
  to: string;
  amount: bigint;
  blockNumber?: number;
  status: "pending" | "included" | "finalized" | "failed";
  events: TransactionEvent[];
}

Example

const tx = await sdk.transfer({
  to: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
  amount: BigInt("1000000000000"), // 1 SEL (assuming 12 decimals)
  memo: "Payment for services",
});

console.log("Transaction hash:", tx.hash);
console.log("Status:", tx.status);

sendTransaction()

Sends a custom transaction.

async sendTransaction(options: SendTransactionOptions): Promise<Transaction>

Parameters

interface SendTransactionOptions {
  from?: string;
  to?: string;
  data?: string;
  value?: bigint;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
  maxPriorityFeePerGas?: bigint;
  nonce?: number;
}

estimateGas()

Estimates gas required for a transaction.

async estimateGas(options: SendTransactionOptions): Promise<bigint>

getTransaction()

Gets transaction details by hash.

async getTransaction(hash: string): Promise<Transaction | null>

getTransactionReceipt()

Gets transaction receipt.

async getTransactionReceipt(hash: string): Promise<TransactionReceipt | null>

Returns

interface TransactionReceipt {
  transactionHash: string;
  transactionIndex: number;
  blockHash: string;
  blockNumber: number;
  from: string;
  to: string;
  gasUsed: bigint;
  logs: Log[];
  status: "success" | "failure";
}

Smart Contracts

Contract

Class for interacting with smart contracts.

new Contract(address: string, abi: any[], sdk: SelendraSDK)

Example

const contract = new Contract("0x1234...abcd", abi, sdk);

contract.call()

Reads data from a contract view function.

async call(functionName: string, ...args: any[]): Promise<any>

Example

const balance = await contract.call("balanceOf", "0xAddress...");
console.log("Token balance:", balance);

contract.send()

Writes data to a contract function.

async send(
  functionName: string,
  options?: SendOptions,
  ...args: any[]
): Promise<Transaction>

Parameters

interface SendOptions {
  from?: string;
  value?: bigint;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
}

Example

const tx = await contract.send(
  "transfer",
  { from: "0xMyAddress...", value: BigInt("1000000000000") },
  "0xRecipientAddress...",
  BigInt("1000000000000")
);

deployContract()

Deploys a new smart contract.

async deployContract(options: DeployOptions): Promise<DeployedContract>

Parameters

interface DeployOptions {
  bytecode: string;
  abi: any[];
  constructorArgs?: any[];
  from?: string;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
}

Returns

interface DeployedContract {
  address: string;
  transactionHash: string;
  blockNumber?: number;
}

Example

const deployed = await sdk.deployContract({
  bytecode: "0x6080604052348015...",
  abi: erc20ABI,
  constructorArgs: ["My Token", "MTK", 18],
  from: "0xMyAddress...",
});

console.log("Contract deployed at:", deployed.address);

EVM Compatibility

getEvmAccount()

Gets EVM account information.

async getEvmAccount(address: string): Promise<EvmAccount>

Returns

interface EvmAccount {
  address: string;
  nonce: number;
  balance: bigint;
  codeHash: string;
  storageRoot: string;
}

getEvmTransactionCount()

Gets the number of transactions sent from an address.

async getEvmTransactionCount(address: string): Promise<number>

getEvmBlock()

Gets block information.

async getEvmBlock(blockHashOrNumber: string | number): Promise<EvmBlock>

sendEvmTransaction()

Sends an EVM transaction.

async sendEvmTransaction(
  tx: EvmTransactionRequest
): Promise<EvmTransaction>

Parameters

interface EvmTransactionRequest {
  from: string;
  to?: string;
  data?: string;
  value?: bigint;
  gas?: bigint;
  maxPriorityFeePerGas?: bigint;
  maxFeePerGas?: bigint;
  nonce?: number;
}

Substrate Integration

query()

Queries Substrate storage.

async query(pallet: string, storage: string, ...args: any[]): Promise<any>

Example

const systemAccount = await sdk.query(
  "System",
  "Account",
  "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
);

console.log("Account info:", systemAccount.toHuman());

tx()

Creates a Substrate transaction.

tx(pallet: string, method: string, ...args: any[]): SubmittableExtrinsic

Example

const transferTx = sdk.tx(
  "Balances",
  "transfer",
  "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
  BigInt("1000000000000")
);

const hash = await transferTx.signAndSend("my-mnemonic");
console.log("Transaction hash:", hash.toHex());

getRuntimeVersion()

Gets the current runtime version.

async getRuntimeVersion(): Promise<RuntimeVersion>

subscribeToHeads()

Subscribes to new block headers.

async subscribeToHeads(
  callback: (header: Header) => void
): Promise<() => void>

Example

const unsubscribe = await sdk.subscribeToHeads((header) => {
  console.log("New block:", header.number.toNumber());
});

// Later: unsubscribe();

Utilities

formatBalance()

Formats a balance value to human-readable format.

formatBalance(balance: bigint | string | number, decimals?: number): string

Example

const formatted = sdk.formatBalance(BigInt("1000000000000"), 12);
console.log(formatted); // "1,000.000000000000"

parseBalance()

Parses a human-readable balance to bigint.

parseBalance(balance: string, decimals?: number): bigint

addressToEvm()

Converts Substrate address to EVM address.

addressToEvm(substrateAddress: string): string

evmToAddress()

Converts EVM address to Substrate address.

evmToAddress(evmAddress: string): string

validateAddress()

Validates an address format.

validateAddress(address: string): 'substrate' | 'evm' | 'invalid'

getFeeEstimate()

Gets current fee estimates.

async getFeeEstimate(): Promise<FeeEstimate>

Returns

interface FeeEstimate {
  slow: {
    maxFeePerGas: bigint;
    maxPriorityFeePerGas: bigint;
    estimatedTime: number; // seconds
  };
  average: FeeTier;
  fast: FeeTier;
}

interface FeeTier {
  maxFeePerGas: bigint;
  maxPriorityFeePerGas: bigint;
  estimatedTime: number;
}

React Components

SelendraProvider

React context provider for the SDK.

<SelendraProvider sdk={sdk}>
  <App />
</SelendraProvider>

useSelendra()

Hook to access the SDK instance.

const sdk = useSelendra();

useAccount()

Hook to manage account state.

interface UseAccountReturn {
  account: Account | null;
  isConnected: boolean;
  connect: () => Promise<void>;
  disconnect: () => Promise<void>;
  balance: Balance | null;
}

const { account, isConnected, connect, disconnect, balance } = useAccount();

useBalance()

Hook to get account balance.

const { balance, loading, error } = useBalance(address);

useTransaction()

Hook to send transactions.

interface UseTransactionReturn {
  send: (options: SendTransactionOptions) => Promise<Transaction>;
  transaction: Transaction | null;
  loading: boolean;
  error: Error | null;
}

const { send, transaction, loading, error } = useTransaction();

Example

const { send, loading, error } = useTransaction();

const handleTransfer = async () => {
  try {
    const tx = await send({
      to: recipient,
      amount: BigInt("1000000000000"),
    });
    console.log("Transaction sent:", tx.hash);
  } catch (err) {
    console.error("Transfer failed:", err);
  }
};

Types

Account

interface Account {
  address: string;
  name?: string;
  type: "substrate" | "evm";
  publicKey: string;
}

Balance

interface Balance {
  free: bigint;
  reserved: bigint;
  frozen: bigint;
  total: bigint;
  tokenSymbol: string;
  decimals: number;
}

Transaction

interface Transaction {
  hash: string;
  from: string;
  to: string;
  amount?: bigint;
  data?: string;
  gasLimit?: bigint;
  maxFeePerGas?: bigint;
  maxPriorityFeePerGas?: bigint;
  nonce?: number;
  blockNumber?: number;
  blockHash?: string;
  status: "pending" | "included" | "finalized" | "failed";
  events: TransactionEvent[];
  timestamp?: number;
}

ChainInfo

interface ChainInfo {
  chainName: string;
  chainId: number;
  version: string;
  specVersion: number;
  implVersion: number;
  tokenDecimals: number;
  tokenSymbol: string;
}

Network

type Network = "mainnet" | "testnet" | "custom";

EventType

type EventType =
  | "transfer"
  | "contract.deployed"
  | "contract.interaction"
  | "block"
  | "error"
  | "connected"
  | "disconnected";

EventData

interface EventData {
  type: EventType;
  data: any;
  timestamp: number;
}

Error Handling

SelendraError

Base error class for SDK errors.

class SelendraError extends Error {
  code: string;
  details?: any;

  constructor(message: string, code: string, details?: any);
}

Common Error Codes

  • CONNECTION_ERROR - Network connection failed
  • INVALID_ADDRESS - Address format is invalid
  • INSUFFICIENT_BALANCE - Not enough balance for operation
  • TRANSACTION_FAILED - Transaction execution failed
  • CONTRACT_ERROR - Smart contract interaction failed
  • TIMEOUT - Operation timed out

Example

try {
  await sdk.transfer({ to, amount });
} catch (error) {
  if (error instanceof SelendraError) {
    switch (error.code) {
      case "INSUFFICIENT_BALANCE":
        console.error("Not enough balance!");
        break;
      case "INVALID_ADDRESS":
        console.error("Invalid recipient address!");
        break;
      default:
        console.error("Transfer failed:", error.message);
    }
  }
}

This API reference covers all major functionality of the Selendra TypeScript SDK. For more specific examples and use cases, check out our examples directory and tutorials.

Contribute

Found an issue or want to contribute?

Help us improve this documentation by editing this page on GitHub.

Edit this page on GitHub