MCPcopy Index your code
hub / github.com/ar-io/ar-io-sdk

github.com/ar-io/ar-io-sdk @v4.0.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v4.0.3 ↗ · + Follow
977 symbols 3,117 edges 117 files 221 documented · 23%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

@ar.io/sdk

codecov

The Solana-native SDK for the AR.IO network. Provides typed client classes (ARIO, ANT, ANTRegistry), PDA helpers, deserializers, and escrow primitives for the AR.IO protocol on Solana. Codama-generated instruction builders and account decoders are supplied by @ar.io/solana-contracts.

Table of Contents

Installation

Requires node>=v18.0.0.

npm install @ar.io/sdk

or

yarn add @ar.io/sdk

Quick Start

import { ARIO } from '@ar.io/sdk';
import { createSolanaRpc } from '@solana/kit';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const ario = ARIO.init({ rpc });
const gateways = await ario.getGateways();

Write operations need a @solana/kit signer plus an rpcSubscriptions client (used by kit's sendAndConfirmTransaction):

import { ARIO } from '@ar.io/sdk';
import {
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  createKeyPairSignerFromBytes,
} from '@solana/kit';
import { readFileSync } from 'node:fs';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions(
  'wss://api.mainnet-beta.solana.com',
);
const signer = await createKeyPairSignerFromBytes(
  new Uint8Array(JSON.parse(readFileSync('keypair.json', 'utf8'))),
);

const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
await ario.buyRecord({
  name: 'foo',
  type: 'lease',
  years: 1,
  processId: '<ANT mint pubkey>',
});

Output

{
  "items": [
    {
      "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
      "operatorStake": 250000000000,
      "totalDelegatedStake": 0,
      "settings": {
        "allowDelegatedStaking": true,
        "allowedDelegates": [],
        "autoStake": false,
        "delegateRewardShareRatio": 10,
        "minDelegatedStake": 100000000,
        "fqdn": "ar-io.dev",
        "label": "ar.io Test",
        "note": "Test Gateway operated by PDS for the ar.io ecosystem.",
        "port": 443,
        "properties": "raJgvbFU-YAnku-WsupIdbTsqqGLQiYpGzoqk9SCVgY",
        "protocol": "https"
      },
      "startTimestamp": 1720720621424,
      "endTimestamp": 0,
      "stats": {
        "passedConsecutiveEpochs": 30,
        "failedConsecutiveEpochs": 0,
        "totalEpochCount": 31,
        "passedEpochCount": 30,
        "failedEpochCount": 1,
        "observedEpochCount": 30,
        "prescribedEpochCount": 31
      },
      "status": "joined",
      "weights": {
        "stakeWeight": 5.02400000024,
        "tenureWeight": 0.19444444444444,
        "gatewayPerformanceRatio": 1,
        "observerPerformanceRatio": 1,
        "gatewayRewardRatioWeight": 1,
        "observerRewardRatioWeight": 1,
        "compositeWeight": 0.97688888893556,
        "normalizedCompositeWeight": 0.19247316211083
      }
    }
  ],
  "hasMore": true,
  "nextCursor": "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
  "totalItems": 316,
  "limit": 100,
  "sortBy": "startTimestamp",
  "sortOrder": "desc"
}

Usage

The SDK is published as an ES module ("type": "module") and is compatible with modern bundlers such as Webpack, Rollup, ESbuild, and Vite. CommonJS consumers should migrate to ESM (Node 18+ supports ESM natively). Refer to the [examples] directory to see how to use the SDK in various environments.

Subpath exports

  • @ar.io/sdk — main entry. ARIO, ANT, ANTRegistry, Solana client classes, PDA helpers, deserializers, escrow primitives.
  • @ar.io/sdk/solana — alias of the main entry (kept for one release while consumers migrate from the previous subpath layout).

Web

[!WARNING] Polyfills are not provided by default for bundled web projects (Vite, ESBuild, Webpack, Rollup, etc.). Depending on your bundler config, you will need polyfills for crypto, process and buffer. Refer to [examples/webpack] and [examples/vite] for examples.

import { ARIO } from '@ar.io/sdk';
import { createSolanaRpc } from '@solana/kit';

const ario = ARIO.init({
  rpc: createSolanaRpc('https://api.mainnet-beta.solana.com'),
});
const gateways = await ario.getGateways();

Browser bundle

<script type="module">
  // replace <version> with a release version
  import { ARIO } from 'https://github.com/ar-io/ar-io-sdk/releases/download/v<version>/web.bundle.min.js';
  import { createSolanaRpc } from 'https://esm.sh/@solana/kit@6';

  const ario = ARIO.init({
    rpc: createSolanaRpc('https://api.mainnet-beta.solana.com'),
  });
  const gateways = await ario.getGateways();
</script>

TypeScript

The SDK ships TypeScript types alongside the JS output. Types are exported from ./lib/types/solana/index.d.ts and resolve automatically for ESM consumers.

[!NOTE] TypeScript 5.3+ is recommended (the SDK uses nodenext module resolution with .js extensions in relative imports).

ARIO Contract

General

init({ rpc, rpcSubscriptions?, signer? })

Factory function that creates a read-only or writeable ARIO client. Providing signer plus rpcSubscriptions enables write methods (joinNetwork, delegateStake, buyRecord, etc.). Without a signer, the client is read-only.

import { ARIO } from '@ar.io/sdk';
import {
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  createKeyPairSignerFromBytes,
} from '@solana/kit';

const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');

// read-only client
const ario = ARIO.init({ rpc });

// read-write client (needs rpcSubscriptions for sendAndConfirm)
const rpcSubscriptions = createSolanaRpcSubscriptions(
  'wss://api.mainnet-beta.solana.com',
);
const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */);
const arioWrite = ARIO.init({ rpc, rpcSubscriptions, signer });

getInfo()

Retrieves the information of the ARIO process.

const ario = ARIO.init({ rpc });
const info = await ario.getInfo();

Output

{
  "Name": "AR.IO",
  "Ticker": "ARIO",
  "Logo": "",
  "Denomination": 6,
  "Handlers": [],
  "LastCreatedEpochIndex": 0,
  "LastDistributedEpochIndex": 0,
  "totalSupply": 1000000000000000,
  "protocolBalance": 0,
  "epochSettings": {
    "durationMs": 86400000,
    "prescribedNameCount": 25,
    "maxObservers": 50
  }
}

Note: Handlers, LastCreatedEpochIndex, and LastDistributedEpochIndex are placeholders on Solana (returned for backwards-compatible field shape with consumer code). totalSupply / protocolBalance are live reads from the ArioConfig PDA; epochSettings is live from the EpochSettings PDA. See src/solana/io-readable.ts for the exact projection.

getTokenSupply()

Retrieves the total supply of tokens, returned in mARIO. The total supply includes the following:

  • total - the total supply of all tokens
  • circulating - the total supply minus locked, withdrawn, delegated, and staked
  • locked - tokens that are locked in the protocol (a.k.a. vaulted)
  • withdrawn - tokens that have been withdrawn from the protocol by operators and delegators
  • delegated - tokens that have been delegated to gateways
  • staked - tokens that are staked in the protocol by gateway operators
  • protocolBalance - tokens that are held in the protocol's treasury. This is included in the circulating supply.
const ario = ARIO.init({ rpc });
const supply = await ario.getTokenSupply();

Output

{
  "total": 1000000000000000000,
  "circulating": 998094653842520,
  "locked": 0,
  "withdrawn": 560563387278,
  "delegated": 1750000000,
  "staked": 1343032770199,
  "protocolBalance": 46317263683761
}

getBalance({ address })

Retrieves the balance of the specified wallet address.

const ario = ARIO.init({ rpc });
// the balance will be returned in mARIO as a value
const balance = await ario
  .getBalance({
    address: "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
  })
  .then((balance: number) => new mARIOToken(balance).toARIO()); // convert it to ARIO for readability

Output

100000

getBalances({ cursor, limit, sortBy, sortOrder })

Retrieves the balances of the ARIO process in mARIO, paginated and sorted by the specified criteria. The cursor used for pagination is the last wallet address from the previous request.

const ario = ARIO.init({ rpc });
const balances = await ario.getBalances({
  cursor: "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
  limit: 100,
  sortBy: "balance",
  sortOrder: "desc",
});

Output

{
  "items": [
    {
      "address": "-4xgjroXENKYhTWqrBo57HQwvDL51mMvSxJy6Y2Z_sA",
      "balance": 1000000
    },
    {
      "address": "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck",
      "balance": 1000000
    }
    // ...98 other balances
  ],
  "hasMore": true,
  "nextCursor": "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck",
  "totalItems": 1789,
  "sortBy": "balance",
  "sortOrder": "desc"
}

transfer({ target, qty })

Transfers mARIO to the designated target recipient address. Requires signer to be provided on ARIO.init to sign the transaction.

Note: Requires signer to be provided on ARIO.init to sign the transaction.

const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
const { id: txId } = await ario.transfer({
  target: 'RecipientSolanaPubkeyBase58',
  qty: new ARIOToken(1000).toMARIO(),
});

Networks

The SDK talks to whatever cluster your @solana/kit RPC client points at — mainnet-beta by default. For devnet or a local validator, override the RPC URL and (on any non-mainnet cluster) the per-program addresses:

import { ARIO } from '@ar.io/sdk';
import { createSolanaRpc, address } from '@solana/kit';

const ario = ARIO.init({
  rpc: createSolanaRpc('https://api.devnet.solana.com'),
  coreProgramId: address('<ARIO_CORE_PROGRAM_ID>'),
  garProgramId: address('<ARIO_GAR_PROGRAM_ID>'),
  arnsProgramId: address('<ARIO_ARNS_PROGRAM_ID>'),
  antProgramId: address('<ARIO_ANT_PROGRAM_ID>'),
});

On localnet (Surfpool) source program IDs from migration/localnet/out/localnet.env in the solana-ar-io monorepo.

Vaults

getVault({ address, vaultId })

Retrieves the locked-balance user vault of the ARIO process by the specified wallet address and vault ID.

```typescript const ario = ARIO.init({ rpc }); const

Extension points exported contracts — how you extend this code

HTTPClient (Interface)
(no doc) [2 implementers]
src/types/common.ts
ILogger (Interface)
(no doc) [2 implementers]
src/common/logger.ts
JsonRpcResponse (Interface)
(no doc)
test/helpers/time.ts
NftMetadataJson (Interface)
(no doc)
src/solana/metadata.ts
CommanderOption (Interface)
(no doc)
src/cli/utils.ts
ANTRegistryRead (Interface)
(no doc) [2 implementers]
src/types/ant-registry.ts
SurfpoolEpochInfo (Interface)
(no doc)
test/helpers/time.ts
AntMetadataParams (Interface)
(no doc)
src/solana/metadata.ts

Core symbols most depended-on inside this repo

makeCommand
called by 110
src/cli/utils.ts
toString
called by 72
src/types/token.ts
requiredStringFromOptions
called by 55
src/cli/utils.ts
sendTransaction
called by 54
src/solana/io-writeable.ts
assertConfirmationPrompt
called by 42
src/cli/utils.ts
readARIOFromOptions
called by 41
src/cli/utils.ts
send
called by 40
src/solana/escrow.ts
crankEpochStep
called by 35
src/solana/io-writeable.ts

Shape

Method 475
Function 403
Class 64
Interface 35

Languages

TypeScript100%

Modules by API surface

src/solana/io-writeable.ts111 symbols
src/solana/io-readable.ts86 symbols
src/solana/deserialize.ts75 symbols
src/solana/escrow.ts53 symbols
src/types/io.ts52 symbols
src/cli/utils.ts49 symbols
src/solana/pda.ts36 symbols
src/solana/ant-readable.ts31 symbols
src/types/token.ts30 symbols
src/solana/crank-epoch-step.test.ts26 symbols
src/common/error.ts25 symbols
src/cli/commands/readCommands.ts25 symbols

For agents

$ claude mcp add ar-io-sdk \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page