# ar-io sdk

The ar.io SDK provides functionality for interacting with the ar.io ecosystem of services (e.g. gateways and observers) and protocols (e.g. ArNS). It is available for both NodeJS and Web environments.

# Prerequisites

  • node>=v18.0.0
  • npm or yarn

# Installation

npm install @ar.io/sdk

or

yarn add @ar.io/sdk --ignore-engines

NOTE: The --ignore-engines flag i required when using yarn, as permaweb/aoconnect (opens new window) recommends only the use of npm. Alternatively, you can add a .yarnrc.yml file to your project containing ignore-engines true to ignore the engine check.

# Quick Start

Loading the gateway list in NodeJS.

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

const ario = ARIO.init();
const gateways = await ario.getGateways();

console.log(gateways);
Output
{
  "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ": {
    "end": 0,
    "observerWallet": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
    "operatorStake": 250000000000, // value in mARIO
    "settings": {
      "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"
    },
    "start": 1256694,
    "stats": {
      "failedConsecutiveEpochs": 0,
      "passedEpochCount": 30,
      "submittedEpochCount": 30,
      "totalEpochParticipationCount": 31,
      "totalEpochsPrescribedCount": 31
    },
    "status": "joined",
    "vaults": {},
    "weights": {
      "stakeWeight": 25,
      "tenureWeight": 0.9031327160493827,
      "gatewayRewardRatioWeight": 0.96875,
      "observerRewardRatioWeight": 0.96875,
      "compositeWeight": 21.189222170982834,
      "normalizedCompositeWeight": 0.27485583057217183
    }
  }
}

# Usage

The SDK is provided in both CommonJS and ESM formats and is compatible with bundlers such as Webpack, Rollup, and ESbuild. Utilize the appropriately named exports provided by this SDK's package.json (opens new window) based on your project's configuration. Refer to the examples (opens new window) directory to see how to use the SDK in various environments.

# Web

# Bundlers (Webpack, Rollup, ESbuild, etc.)

import { ARIO } from '@ar.io/sdk/web';

// set up client
const ario = ARIO.init();
// fetch gateways
const gateways = await ario.getGateways();

Note: polyfills are only provided when using the named @ar.io/sdk/web export (which requires moduleResolution: nodenext in tsconfig.json). If you are using the default export within a Typescript project (e.g. moduleResolution: node), you will need to provide your own polyfills - specifically crypto, fs and buffer. Refer to examples/webpack (opens new window) and examples/vite (opens new window) for references in how to properly provide those polyfills. For other project configurations, refer to your bundler's documentation for more information on how to provide the necessary polyfills.

# Browser

<script type="module">
  import { ARIO } from 'https://unpkg.com/@ar.io/sdk';

  // set up client
  const ario = ARIO.init();
  // fetch gateways
  const gateways = await ario.getGateways();
</script>

# Node

# ESM (NodeNext)
import { ARIO } from '@ar.io/sdk/node';

// set up client
const ario = ARIO.init();
// fetch gateways
const gateways = await ario.getGateways();
# CJS
import { ARIO } from '@ar.io/sdk';

// set up client
const ario = ARIO.init();
// fetch gateways
const gateways = await ario.getGateways();

# Typescript

The SDK provides TypeScript types. When you import the SDK in a TypeScript project types are exported from ./lib/types/[node/web]/index.d.ts and should be automatically recognized by package managers, offering benefits such as type-checking and autocompletion.

NOTE: Typescript version 5.3 or higher is recommended.

# ARIO Token & mARIO Token

The ArIO contract stores all values as mARIO (milli-ARIO) to avoid floating-point arithmetic issues. The SDK provides an IOToken and mIOToken classes to handle the conversion between ARIO and mARIO, along with rounding logic for precision.

All contract interactions expect values in mARIO. If numbers are provided as inputs, they are assumed to be in raw mARIO values.

# Converting ARIO to mARIO

import { ARIOToken, mARIOToken } from '@ar.io/sdk';

const arioValue = 1;
const mARIOValue = new ARIOToken(arioValue).toMARIO();
console.log(mARIOValue); // 1000000 (mARIO)

const mARIOValue = 1_000_000;
const arioValue = new mARIOToken(mARIOValue).toARIO();
console.log(arioValue); // 1 (ARIO)

# ARIO Process

# APIs

# init({ signer })

Factory function to that creates a read-only or writeable client. By providing a signer additional write APIs that require signing, like joinNetwork and delegateStake are available. By default, a read-only client is returned and no write APIs are available.

// read-only client
const ario = ARIO.init()

// read-write client for browser environments
const ario = ARIO.init({ signer: new ArConnectSigner(window.arweaveWallet, Arweave.init({}))});

// read-write client for node environments
const ario = ARIO.init({ signer: new ArweaveSigner(JWK) });

# getInfo()

Retrieves the information of the ARIO process.

const ario = ARIO.init();
const info = await ario.getInfo();
Output
{
  "Name": "Testnet ARIO",
  "Ticker": "tARIO",
  "Owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
  "Denomination": 6,
  "Handlers": ["_eval", "_default_"], // full list of handlers, useful for debugging
  "LastTickedEpochIndex": 31 // epoch index of the last tick
}

# 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();
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();
// 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
// value in ARIO
1_000_000

# 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();
const balances = await ario.getBalances({
  cursor: '-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA',
  limit: 1,
  sortBy: 'balance',
  sortOrder: 'desc',
});
Output
{
  "items": [
    {
      "address": "-4xgjroXENKYhTWqrBo57HQwvDL51mMvSxJy6Y2Z_sA",
      "balance": 1000000
    }
  ],
  "hasMore": true,
  "nextCursor": "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck",
  "totalItems": 1789,
  "sortBy": "balance",
  "sortOrder": "desc"
}

# getGateway({ address })

Retrieves a gateway's info by its staking wallet address.

const ario = ARIO.init();
const gateway = await ario.getGateway({
  address: 'INSERT_GATEWAY_ADDRESS',
});
Output
{
  "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
  "operatorStake": 250000000000,
  "settings": {
    "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": 1720720620813,
  "stats": {
    "failedConsecutiveEpochs": 0,
    "passedEpochCount": 30,
    "submittedEpochCount": 30,
    "totalEpochCount": 31,
    "totalEpochsPrescribedCount": 31
  },
  "status": "joined",
  "vaults": {},
  "weights": {
    "compositeWeight": 0.97688888893556,
    "gatewayRewardRatioWeight": 1,
    "tenureWeight": 0.19444444444444,
    "observerRewardRatioWeight": 1,
    "normalizedCompositeWeight": 0.19247316211083,
    "stakeWeight": 5.02400000024
  }
}

# getGateways({ cursor, limit, sortBy, sortOrder })

Retrieves registered gateways of the ARIO process, using pagination and sorting by the specified criteria. The cursor used for pagination is the last gateway address from the previous request.

const ario = ARIO.init();
const gateways = await ario.getGateways({
  limit: 1,
  sortOrder: 'desc',
  sortBy: 'operatorStake',
});

Available sortBy options are any of the keys on the gateway object, e.g. operatorStake, start, status, settings.fqdn, settings.label, settings.note, settings.port, settings.protocol, stats.failedConsecutiveEpochs, stats.passedConsecutiveEpochs, etc.

Output
{
  "items": [
    {
      "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
      "operatorStake": 250000000000,
      "settings": {
        "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": 1720720620813,
      "stats": {
        "failedConsecutiveEpochs": 0,
        "passedEpochCount": 30,
        "submittedEpochCount": 30,
        "totalEpochCount": 31,
        "totalEpochsPrescribedCount": 31
      },
      "status": "joined",
      "vaults": {},
      "weights": {
        "compositeWeight": 0.97688888893556,
        "gatewayRewardRatioWeight": 1,
        "tenureWeight": 0.19444444444444,
        "observerRewardRatioWeight": 1,
        "normalizedCompositeWeight": 0.19247316211083,
        "stakeWeight": 5.02400000024
      }
    }
  ],
  "hasMore": true,
  "nextCursor": "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
  "totalItems": 316,
  "sortBy": "operatorStake",
  "sortOrder": "desc"
}

# getArNSRecord({ name })

Retrieves the record info of the specified ArNS name.

const ario = ARIO.init();
const record = await ario.getArNSRecord({ name: 'ardrive' });
Output
{
  "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
  "endTimestamp": 1711122739,
  "startTimestamp": 1694101828,
  "type": "lease",
  "undernames": 100
}

# getArNSRecords({ cursor, limit, sortBy, sortOrder })

Retrieves all registered ArNS records of the ARIO process, paginated and sorted by the specified criteria. The cursor used for pagination is the last ArNS name from the previous request.

const ario = ARIO.init();
// get the 5 newest names
const records = await ario.getArNSRecords({
  limit: 5,
  sortBy: 'startTimestamp',
  sortOrder: 'desc',
});

Available sortBy options are any of the keys on the record object, e.g. name, processId, endTimestamp, startTimestamp, type, undernames.

Output
{
  "items": [
    {
      "name": "ao",
      "processId": "eNey-H9RB9uCdoJUvPULb35qhZVXZcEXv8xds4aHhkQ",
      "purchasePrice": 75541282285,
      "startTimestamp": 1720720621424,
      "type": "permabuy",
      "undernames": 10
    },
    {
      "name": "ardrive",
      "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
      "endTimestamp": 1720720819969,
      "startTimestamp": 1720720620813,
      "type": "lease",
      "undernames": 100
    },
    {
      "name": "arweave",
      "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
      "endTimestamp": 1720720819969,
      "startTimestamp": 1720720620800,
      "type": "lease",
      "undernames": 100
    },
    {
      "name": "ar-io",
      "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
      "endTimestamp": 1720720819969,
      "startTimestamp": 1720720619000,
      "type": "lease",
      "undernames": 100
    },
    {
      "name": "fwd",
      "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
      "endTimestamp": 1720720819969,
      "startTimestamp": 1720720220811,
      "type": "lease",
      "undernames": 100
    }
  ],
  "hasMore": true,
  "nextCursor": "fwdresearch",
  "totalItems": 21740,
  "sortBy": "startTimestamp",
  "sortOrder": "desc"
}

# getDemandFactor()

Retrieves the current demand factor of the network. The demand factor is a multiplier applied to the cost of ArNS interactions based on the current network demand.

const ario = ARIO.init();
const demandFactor = await ario.getDemandFactor();
Output
1.05256

# getArNSReturnedNames({ cursor, limit, sortyBy, sortOrder })

Retrieves all active returned names of the ARIO process, paginated and sorted by the specified criteria. The cursor used for pagination is the last returned name from the previous request.

const ario = ARIO.init();
const returnedNames = await ario.getArNSReturnedNames({
  limit: 100,
  sortBy: 'endTimestamp',
  sortOrder: 'asc', // return the returned names ending soonest first
});
Output
{
  "items": [
    {
      "name": "permalink",
      "endTimestamp": 1730985241349,
      "startTimestamp": 1729775641349,
      "baseFee": 250000000,
      "demandFactor": 1.05256,
      "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
      "settings": {
        "durationMs": 1209600000,
        "decayRate": 0.000000000016847809193121693,
        "scalingExponent": 190,
        "startPriceMultiplier": 50
      }
    }
  ],
  "hasMore": false,
  "totalItems": 1,
  "sortBy": "endTimestamp",
  "sortOrder": "asc"
}

# getArNSReturnedName({ name })

Retrieves the returned name data for the specified returned name.

const ario = ARIO.init();
const returnedName = await ario.getArNSReturnedName({ name: 'permalink' });
Output
{
  "name": "permalink",
  "endTimestamp": 1730985241349,
  "startTimestamp": 1729775641349,
  "baseFee": 250000000,
  "demandFactor": 1.05256,
  "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
  "settings": {
    "durationMs": 1209600000,
    "decayRate": 0.000000000016847809193121693,
    "scalingExponent": 190,
    "startPriceMultiplier": 50
  }
}

# getObservations({ epochIndex })

Returns the epoch-indexed observation list.

const ario = ARIO.init();
const observations = await ario.getObservations();
Output
{
  "0": {
    "failureSummaries": {
      "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
        "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA",
        "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA"
      ]
    },
    "reports": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": "B6UUjKWjjEWDBvDSMXWNmymfwvgR9EN27z5FTkEVlX4",
      "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA": "7tKsiQ2fxv0D8ZVN_QEv29fZ8hwFIgHoEDrpeEG0DIs",
      "osZP4D9cqeDvbVFBaEfjIxwc1QLIvRxUBRAxDIX9je8": "aatgznEvC_UPcxp1v0uw_RqydhIfKm4wtt1KCpONBB0",
      "qZ90I67XG68BYIAFVNfm9PUdM7v1XtFTn7u-EOZFAtk": "Bd8SmFK9-ktJRmwIungS8ur6JM-JtpxrvMtjt5JkB1M"
    }
  }
}

# getDistributions({ epochIndex })

Returns the current rewards distribution information. If no epoch index is provided, the current epoch is used.

const ario = ARIO.init();
const distributions = await ario.getDistributions({ epochIndex: 0 });
Output
{
  "totalEligibleGateways": 1,
  "totalEligibleRewards": 100000000,
  "totalEligibleObserverReward": 100000000,
  "totalEligibleGatewayReward": 100000000,
  "totalDistributedRewards": 100000000,
  "distributedTimestamp": 1720720621424,
  "rewards": {
    "eligible": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": {
        "operatorReward": 100000000,
        "delegateRewards": {}
      }
    },
    "distributed": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
    }
  }
}

# getEpoch({ epochIndex })

Returns the epoch data for the specified block height. If no epoch index is provided, the current epoch is used.

const ario = ARIO.init();
const epoch = await ario.getEpoch({ epochIndex: 0 });
Output
{
  "epochIndex": 0,
  "startTimestamp": 1720720620813,
  "endTimestamp": 1752256702026,
  "startHeight": 1350700,
  "distributionTimestamp": 1752256702026,
  "observations": {
    "failureSummaries": {
      "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
        "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA"
      ]
    },
    "reports": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": "B6UUjKWjjEWDBvDSMXWNmymfwvgR9EN27z5FTkEVlX4"
    }
  },
  "prescribedNames": ["ardrive", "ar-io", "arweave", "fwd", "ao"],
  "prescribedObservers": [
    {
      "gatewayAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
      "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
      "stake": 10000000000, // value in mARIO
      "startTimestamp": 1720720620813,
      "stakeWeight": 1,
      "tenureWeight": 0.4494598765432099,
      "gatewayRewardRatioWeight": 1,
      "observerRewardRatioWeight": 1,
      "compositeWeight": 0.4494598765432099,
      "normalizedCompositeWeight": 0.002057032496835938
    }
  ],
  "distributions": {
    "totalEligibleGateways": 1,
    "totalEligibleRewards": 100000000,
    "totalEligibleObserverReward": 100000000,
    "totalEligibleGatewayReward": 100000000,
    "totalDistributedRewards": 100000000,
    "distributedTimestamp": 1720720621424,
    "rewards": {
      "eligible": {
        "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": {
          "operatorReward": 100000000,
          "delegateRewards": {}
        }
      },
      "distributed": {
        "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
      }
    }
  }
}

# getCurrentEpoch()

Returns the current epoch data.

const ario = ARIO.init();
const epoch = await ario.getCurrentEpoch();
Output
{
  "epochIndex": 0,
  "startTimestamp": 1720720621424,
  "endTimestamp": 1752256702026,
  "startHeight": 1350700,
  "distributionTimestamp": 1711122739,
  "observations": {
    "failureSummaries": {
      "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
        "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA"
      ]
    },
    "reports": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": "B6UUjKWjjEWDBvDSMXWNmymfwvgR9EN27z5FTkEVlX4"
    }
  },
  "prescribedNames": ["ardrive", "ar-io", "arweave", "fwd", "ao"],
  "prescribedObservers": [
    {
      "gatewayAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
      "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
      "stake": 10000000000,
      "start": 1292450,
      "stakeWeight": 1,
      "tenureWeight": 0.4494598765432099,
      "gatewayRewardRatioWeight": 1,
      "observerRewardRatioWeight": 1,
      "compositeWeight": 0.4494598765432099,
      "normalizedCompositeWeight": 0.002057032496835938
    }
  ],
  "distributions": {
    "distributedTimestamp": 1711122739,
    "totalEligibleRewards": 100000000,
    "rewards": {
      "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
    }
  }
}

# getPrescribedObservers({ epochIndex })

Retrieves the prescribed observers of the ARIO process. To fetch prescribed observers for a previous epoch set the epochIndex to the desired epoch.

const ario = ARIO.init();
const observers = await ario.getPrescribedObservers({ epochIndex: 0 });
Output
[
  {
    "gatewayAddress": "BpQlyhREz4lNGS-y3rSS1WxADfxPpAuing9Lgfdrj2U",
    "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
    "stake": 10000000000, // value in mARIO
    "start": 1296976,
    "stakeWeight": 1,
    "tenureWeight": 0.41453703703703704,
    "gatewayRewardRatioWeight": 1,
    "observerRewardRatioWeight": 1,
    "compositeWeight": 0.41453703703703704,
    "normalizedCompositeWeight": 0.0018972019546783507
  }
]

# getTokenCost({ intent, ...args })

Calculates the price in mARIO to perform the interaction in question, e.g. a Buy-record interaction, where args are the specific params for that interaction.

const price = await ario
  .getTokenCost({
    intent: 'Buy-Record',
    name: 'ar-io',
    type: 'permabuy',
  })
  .then((p) => new mARIOToken(p).toARIO()); // convert to ARIO for readability
Output
1642.34

# joinNetwork( params )

Joins a gateway to the ar.io network via its associated wallet.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.joinNetwork(
  {
    qty: new ARIOToken(10_000).toMARIO(), // minimum operator stake allowed
    autoStake: true, // auto-stake operator rewards to the gateway
    allowDelegatedStaking: true, // allows delegated staking
    minDelegatedStake: new ARIOToken(100).toMARIO(), // minimum delegated stake allowed
    delegateRewardShareRatio: 10, // percentage of rewards to share with delegates (e.g. 10%)
    label: 'john smith', // min 1, max 64 characters
    note: 'The example gateway', // max 256 characters
    properties: 'FH1aVetOoulPGqgYukj0VE0wIhDy90WiQoV3U2PeY44', // Arweave transaction ID containing additional properties of the Gateway
    observerWallet: '0VE0wIhDy90WiQoV3U2PeY44FH1aVetOoulPGqgYukj', // wallet address of the observer, must match OBSERVER_WALLET on the observer
    fqdn: 'example.com', // fully qualified domain name - note: you must own the domain and set the OBSERVER_WALLET on your gateway to match `observerWallet`
    port: 443, // port number
    protocol: 'https', // only 'https' is supported
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# leaveNetwork()

Sets the gateway as leaving on the ar.io network. Requires signer to be provided on IO.init to sign the transaction. The gateway's operator and delegated stakes are vaulted and will be returned after the leave periods. The gateway will be removed from the network after the leave period.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });

const { id: txId } = await ario.leaveNetwork(
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# updateGatewaySettings( gatewaySettings )

Writes new gateway settings to the caller's gateway configuration.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.updateGatewaySettings(
  {
    // any other settings you want to update
    minDelegatedStake: new ARIOToken(100).toMARIO(),
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# increaseDelegateStake({ target, qty })

Increases the caller's stake on the target gateway.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.increaseDelegateStake(
  {
    target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
    qty: new ARIOToken(100).toMARIO(),
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# decreaseDelegateStake({ target, qty })

Decrease the caller's stake on the target gateway.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.decreaseDelegateStake(
  {
    target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
    qty: new ARIOToken(100).toMARIO(),
  },
  {
    tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
  },
);

# getDelegations({ address, cursor, limit, sortyBy })

Retrieves all active and vaulted stakes across all gateways for a specific address, paginated and sorted by the specified criteria. The cursor used for pagination is the last delegationId (concatenated gateway and startTimestamp of the delegation) from the previous request.

const ario = ARIO.init();
const vaults = await ario.getDelegations({
  address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
  cursor: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_123456789',
  limit: 2,
  sortBy: 'startTimestamp',
  sortOrder: 'asc',
});
Output
{
  "sortOrder": "asc",
  "hasMore": true,
  "totalItems": 95,
  "limit": 2,
  "sortBy": "startTimestamp",
  "items": [
    {
      "type": "stake",
      "startTimestamp": 1727815440632,
      "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "delegationId": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_1727815440632",
      "balance": 1383212512
    },
    {
      "type": "vault",
      "startTimestamp": 1730996691117,
      "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "delegationId": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_1730996691117",
      "vaultId": "_sGDS7X1hyLCVpfe40GWioH9BSOb7f0XWbhHBa1q4-g",
      "balance": 50000000,
      "endTimestamp": 1733588691117
    }
  ],
  "nextCursor": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_1730996691117"
}

# instantWithdrawal({ gatewayAddress, vaultId})

Instantly withdraws an existing vault on a gateway. If no gatewayAddress is provided, the signer's address will be used.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
// removes a delegated vault from a gateway
const { id: txId } = await ario.instantWithdrawal(
  {
    // gateway address where delegate vault exists
    gatewayAddress: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
    // delegated vault id to cancel
    vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
  },
  // optional additional tags
  {
    tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
  },
);
// removes an operator vault from a gateway
const { id: txId } = await ario.instantWithdrawal(
  {
    vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
  },
);

# cancelWithdrawal({ gatewayAddress, vaultId })

Cancels an existing vault on a gateway. The vaulted stake will be returned to the caller's stake. if no gatewayAddress is provided, the signer's address will be used.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
// cancels a delegated vault from a gateway
const { id: txId } = await ario.cancelWithdrawal(
  {
    // gateway address where vault exists
    gatewayAddress: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
    // vault id to cancel
    vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
// cancels an operator vault from a gateway
const { id: txId } = await ario.cancelWithdrawal(
  {
    // operator vault id to cancel
    vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
  },
);

# getAllowedDelegates({ address, cursor, limit, sortBy, sortOrder })

Retrieves all allowed delegates for a specific address. The cursor used for pagination is the last address from the previous request.

const ario = ARIO.init();
const allowedDelegates = await ario.getAllowedDelegates({
  address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ',
});
Output
{
  "sortOrder": "desc",
  "hasMore": false,
  "totalItems": 4,
  "limit": 100,
  "items": [
    "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM",
    "N4h8M9A9hasa3tF47qQyNvcKjm4APBKuFs7vqUVm-SI",
    "JcC4ZLUY76vmWha5y6RwKsFqYTrMZhbockl8iM9p5lQ",
    "31LPFYoow2G7j-eSSsrIh8OlNaARZ84-80J-8ba68d8"
  ]
}

# getGatewayVaults({ address, cursor, limit, sortyBy, sortOrder })

Retrieves all vaults accross all gateways for a specific address, paginated and sorted by the specified criteria. The cursor used for pagination is the last vaultId from the previous request.

const ario = ARIO.init();
const vaults = await ario.getGatewayVaults({
  address: '"PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM',
});
Output
{
  "sortOrder": "desc",
  "hasMore": false,
  "totalItems": 1,
  "limit": 100,
  "sortBy": "endTimestamp",
  "items": [
    {
      "cursorId": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM_1728067635857",
      "startTimestamp": 1728067635857,
      "balance": 50000000000,
      "vaultId": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM",
      "endTimestamp": 1735843635857
    }
  ]
}

# increaseOperatorStake({ qty })

Increases the caller's operator stake. Must be executed with a wallet registered as a gateway operator.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.increaseOperatorStake(
  {
    qty: new ARIOToken(100).toMARIO(),
  },
  {
    tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
  },
);

# decreaseOperatorStake({ qty })

Decreases the caller's operator stake. Must be executed with a wallet registered as a gateway operator.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.decreaseOperatorStake(
  {
    qty: new ARIOToken(100).toMARIO(),
  },
  {
    tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
  },
);

# redelegateStake({ target, source, stakeQty, vaultId })

Redelegates the stake of a specific address to a new gateway. Vault ID may be optionally included in order to redelegate from an existing withdrawal vault. The redelegation fee is calculated based on the fee rate and the stake amount. Users are allowed one free redelegation every seven epochs. Each additional redelegation beyond the free redelegation will increase the fee by 10%, capping at a 60% redelegation fee.

e.g: If 1000 mARIO is redelegated and the fee rate is 10%, the fee will be 100 mARIO. Resulting in 900 mARIO being redelegated to the new gateway and 100 mARIO being deducted back to the protocol balance.

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });

const { id: txId } = await io.redelegateStake({
  target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
  source: 'HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA',
  stakeQty: new ARIOToken(1000).toMARIO(),
  vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
});

# getRedelegationFee({ address })

Retrieves the fee rate as percentage required to redelegate the stake of a specific address. Fee rate ranges from 0% to 60% based on the number of redelegations since the last fee reset.

const ario = ARIO.init();

const fee = await ario.getRedelegationFee({
  address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
});
Output
{
  "redelegationFeeRate": 10,
  "feeResetTimestamp": 1730996691117
}

# saveObservations({ reportTxId, failedGateways })

Saves the observations of the current epoch.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.saveObservations(
  {
    reportTxId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
    failedGateways: ['t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3'],
  },
  {
    tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
  },
);

# transfer({ target, qty, denomination })

Transfers mARIO to the designated target recipient address.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.transfer(
  {
    target: '-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5',
    qty: new ARIOToken(1000).toMARIO(),
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# increaseUndernameLimit({ name, qty })

Increases the undername support of a domain up to a maximum of 10k. Domains, by default, support up to 10 undernames.

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

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.increaseUndernameLimit(
  {
    name: 'ar-io',
    qty: 420,
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# extendLease({ name, years })

Extends the lease of a registered ArNS domain, with an extension of 1-5 years depending on grace period status. Permanently registered domains cannot be extended.

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.extendLease(
  {
    name: 'ar-io',
    years: 1,
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# getVault({ address, vaultId })

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

const ario = ARIO.init();
const vault = await io.getVault({
  address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ',
  vaultId: 'vaultIdOne',
});
Output
{
  "balance": 1000000,
  "startTimestamp": 123,
  "endTimestamp": 4567
}

# getVaults({ cursor, limit, sortBy, sortOrder })

Retrieves all locked-balance user vaults of the ARIO process, paginated and sorted by the specifed criteria. The cursor used for pagination is the last wallet address from the previous request.

const ario = ARIO.init();
const vaults = await ario.getVaults({
  cursor: '0',
  limit: 100,
  sortBy: 'balance',
  sortOrder: 'desc',
});
Output
{
  "items": [
    {
      "address": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "vaultId": "vaultIdOne",
      "balance": 1000000,
      "startTimestamp": 123,
      "endTimestamp": 4567
    },
    {
      "address": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
      "vaultId": "vaultIdTwo",
      "balance": 1000000,
      "startTimestamp": 123,
      "endTimestamp": 4567
    }
    // ...98 other addresses with vaults
  ],
  "hasMore": true,
  "nextCursor": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
  "totalItems": 1789,
  "sortBy": "balance",
  "sortOrder": "desc"
}

# buyRecord({ name, type, years, processId })

Purchases a new ArNS record with the specified name, type, and duration.

const ario = ARIO.init({ processId: ARIO_DEVNET_PROCESS_ID, signer });
const record = await ario.buyRecord(
  { name: 'ardrive', type: 'lease', years: 1 },
  {
    // optional tags
    tags: [{ name: 'App-Name', value: 'ArNS-App' }],
  },
);

# getArNSAuctions({ cursor, limit, sortBy, sortOrder })

Retrieves all active auctions of the ARIO process, paginated and sorted by the specified criteria. The cursor used for pagination is the last auction name from the previous request.

const ario = ARIO.init();
const auctions = await ario.getArNSAuctions({
  limit: 100,
  sortBy: 'endTimestamp',
  sortOrder: 'asc', // return the auctions ending soonest first
});
Output
{
  "items": [
    {
      "name": "permalink",
      "endTimestamp": 1730985241349,
      "startTimestamp": 1729775641349,
      "baseFee": 250000000,
      "demandFactor": 1.05256,
      "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
      "settings": {
        "durationMs": 1209600000,
        "decayRate": 0.000000000016847809193121693,
        "scalingExponent": 190,
        "startPriceMultiplier": 50
      }
    }
  ],
  "hasMore": false,
  "totalItems": 1,
  "sortBy": "endTimestamp",
  "sortOrder": "asc"
}

# getArNSAuction({ name })

Retrieves the auction data for the specified auction name.

const ario = ARIO.init();
const auction = await ario.getArNSAuction({ name: 'permalink' });
Output
{
  "name": "permalink",
  "endTimestamp": 1730985241349,
  "startTimestamp": 1729775641349,
  "baseFee": 250000000,
  "demandFactor": 1.05256,
  "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
  "settings": {
    "durationMs": 1209600000,
    "decayRate": 0.000000000016847809193121693,
    "scalingExponent": 190,
    "startPriceMultiplier": 50
  }
}

# getArNSAuctionPrices({ name, type, years, intervalMs })

Retrieves the auction price curve of the specified auction name for the specified type, duration, and interval. The intervalMs is the number of miliseconds between price points on the curve. The default interval is 15 minutes.

const ario = ARIO.init();
const priceCurve = await ario.getArNSAuctionPrices({
  name: 'permalink',
  type: 'lease',
  years: 1,
  intervalMs: 3600000, // 1 hour price intervals (default is 15 minutes)
});
Output
{
  "name": "permalink",
  "type": "lease",
  "currentPrice": 12582015000,
  "years": 1,
  "prices": {
    "1730412841349": 1618516789,
    "1729908841349": 8210426826,
    "1730722441349": 592768907,
    "1730859241349": 379659914,
    "1730866441349": 370850139,
    "1730884441349": 349705277,
    "1730150041349": 3780993370,
    "1730031241349": 5541718397,
    "1730603641349": 872066253,
    "1730715241349": 606815377,
    "1730942041349": 289775172,
    "1730916841349": 314621977,
    "1730484841349": 1281957300,
    "1730585641349": 924535164,
    "1730232841349": 2895237473,
    "1730675641349": 690200977,
    "1730420041349": 1581242331,
    "1729786441349": 12154428186,
    "1730308441349": 2268298483,
    "1730564041349": 991657913,
    "1730081641349": 4712427282,
    "1730909641349": 322102563,
    "1730945641349": 286388732,
    "1730024041349": 5671483398,
    "1729937641349": 7485620175
    // ...
  }
}

# submitAuctionBid({ name, type, years, processId })

Submit a bid for the current auction. If the bid is accepted, the name will be leased for the specified duration and assigned the specified type and processId.

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });

const auction = await ario.getArNSAuction({ name: 'permalink' });

// check the current price is under some threshold
if (auction && auction.currentPrice <= new ARIOToken(20_000).toMARIO().valueOf()) {
  const { id: txId } = await ario.submitAuctionBid(
    {
      name: 'permalink',
      type: 'lease',
      years: 1,
      processId: 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM',
    },
    // optional additional tags
    { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
  );
}

# getPrimaryNames({ cursor, limit, sortyBy, sortOrder })

Retrieves all primary names paginated and sorted by the specified criteria. the cursor used for pagination is the last name from the previous request.

const ario = ARIO.init();
const names = await ario.getPrimaryNames({
  cursor: 'ao', // this is the last name from the previous request
  limit: 1,
  sortBy: 'startTimestamp',
  sortOrder: 'desc',
});
Output
{
  "sortOrder": "desc",
  "hasMore": true,
  "totalItems": 100,
  "limit": 1,
  "sortBy": "startTimestamp",
  "cursor": "arns",
  "items": [
    {
      "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA",
      "startTimestamp": 1719356032297,
      "name": "arns"
    }
  ]
}

# getPrimaryName({ name, address })

Retrieves the primary name for a given name or address.

const ario = ARIO.init();
const name = await ario.getPrimaryName({
  name: 'arns',
});
// or
const name = await ario.getPrimaryName({
  address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
});
Output
{
  "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA",
  "startTimestamp": 1719356032297,
  "name": "arns"
}

# requestPrimaryName({ name, address })

Requests a primary name for the caller's address. The request must be approved b the new owner of the requested name via the approvePrimaryNameRequest API.

const ario = ARIO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await ario.requestPrimaryName({
  name: 'arns',
});

# getPrimaryNameRequest({ initiator })

Retrieves the primary name request for a wallet address.

const ario = ARIO.init();
const request = await ario.getPrimaryNameRequest({
  initiator: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
});
Output
{
  "initiator": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
  "name": "arns",
  "startTimestamp": 1728067635857,
  "endTimestamp": 1735843635857
}

# Configuration

The ARIO client class exposes APIs relevenat to the ar.io process. It can be configured to use any AO Process ID that adheres to the ARIO Network Spec (opens new window). By default, it will use the current ARIO testnet process (opens new window). Refer to AO Connect (opens new window) for more information on how to configure an ARIO process to use specific AO infrastructure.

// provide a custom ao infrastructure and process id
const ario = ARIO.init({
  process: new AoProcess({
    processId: 'ARIO_PROCESS_ID'
    ao: connect({
      MU_URL: 'https://mu-testnet.xyz',
      CU_URL: 'https://cu-testnet.xyz',
      GRAPHQL_URL: 'https://arweave.net/graphql',
      GATEWAY_URL: 'https://arweave.net',
    })
  })
});

# Arweave Name Tokens (ANT's)

The ANT client class exposes APIs relevant to compliant Arweave Name Token processes. It can be configured to use any process ID that adheres to the ANT process spec. You must provide either a custom process data provider or a processId to the ANT class constructor to use.

# APIs

# init({ processId, signer })

Factory function to that creates a read-only or writeable client. By providing a signer additional write APIs that require signing, like setRecord and transfer are available. By default, a read-only client is returned and no write APIs are available.

// in a browser environment with ArConnect
const ant = ANT.init({
  signer: new ArConnectSigner(window.arweaveWallet, Arweave.init({})),
  processId: 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM'
});

// in a node environment
const ant = ANT.init({
  signer: new ArweaveSigner(JWK),
  processId: 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM'
});

# getInfo()

Retrieves the information about the ANT process.

const info = await ant.getInfo();
Output
{
  "name": "Ardrive",
  "ticker": "ANT-ARDRIVE",
  "owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ"
}

# getHandlers()

Retrieves the handlers supported on the ANT.

const handlers = await ant.getHandlers();
Output
[
  "_eval",
  "_default",
  "transfer",
  "balance",
  "balances",
  "totalSupply",
  "info",
  "addController",
  "removeController",
  "controllers",
  "setRecord",
  "removeRecord",
  "record",
  "records",
  "setName",
  "setTicker",
  "initializeState",
  "state"
]

# getState()

Retrieves the state of the ANT process.

const state = await ant.getState();
Output
{
  "TotalSupply": 1,
  "Balances": {
    "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY": 1
  },
  "Controllers": [],
  "Records": {
    "v1-0-0_whitepaper": {
      "transactionId": "lNjWn3LpyhKC95Kqe-x8X2qgju0j98MhucdDKK85vc4",
      "ttlSeconds": 900
    },
    "@": {
      "transactionId": "2rMLb2uHAyEt7jSu6bXtKx8e-jOfIf7E-DOgQnm8EtU",
      "ttlSeconds": 3600
    },
    "whitepaper": {
      "transactionId": "lNjWn3LpyhKC95Kqe-x8X2qgju0j98MhucdDKK85vc4",
      "ttlSeconds": 900
    }
  },
  "Initialized": true,
  "Ticker": "ANT-AR-IO",
  "Logo": "Sie_26dvgyok0PZD_-iQAFOhOd5YxDTkczOLoqTTL_A",
  "Denomination": 0,
  "Name": "AR.IO Foundation",
  "Owner": "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY"
}

# getOwner()

Returns the owner of the configured ANT process.

const owner = await ant.getOwner();
Output
"ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4"

# getControllers()

Returns the controllers of the configured ANT process.

const controllers = await ant.getControllers();
Output
["ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4"]

# getRecords()

Returns all records on the configured ANT process, including the required @ record that resolve connected ArNS names.

const records = await ant.getRecords();
Output
{
  "@": {
    "transactionId": "nOXJjj_vk0Dc1yCgdWD8kti_1iHruGzLQLNNBHVpN0Y",
    "ttlSeconds": 3600
  },
  "cn": {
    "transactionId": "_HquerT6pfGFXrVxRxQTkJ7PV5RciZCqvMjLtUY0C1k",
    "ttlSeconds": 3300
  },
  "dapp": {
    "transactionId": "hxlxVgAG0K4o3fVD9T6Q4VBWpPmMZwMWgRh1kcuh3WU",
    "ttlSeconds": 3600
  },
  "logo": {
    "transactionId": "KKmRbIfrc7wiLcG0zvY1etlO0NBx1926dSCksxCIN3A",
    "ttlSeconds": 3600
  },
  "og": {
    "transactionId": "YzD_Pm5VAfYpMD3zQCgMUcKKuleGhEH7axlrnrDCKBo",
    "ttlSeconds": 3600
  },
  "og_dapp": {
    "transactionId": "5iR4wBu4KUV1pUz1YpYE1ARXSRHUT5G2ptMuoN2JDlI",
    "ttlSeconds": 3600
  },
  "og_logo": {
    "transactionId": "TB2wJyKrPnkAW79DAwlJYwpgdHKpijEJWQfcwX715Co",
    "ttlSeconds": 3600
  }
}

# transfer({ target })

Transfers ownership of the ANT to a new target address. Target MUST be an Arweave address.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.transfer(
  { target: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setController({ controller })

Adds a new controller to the list of approved controllers on the ANT. Controllers can set records and change the ticker and name of the ANT process.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.setController(
  { controller: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# removeController({ controller })

Removes a controller from the list of approved controllers on the ANT.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.removeController(
  { controller: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setRecord({ undername, transactionId, ttlSeconds })

Updates or creates a record in the ANT process.

Records, or undernames are configured with the transactionId - the arweave transaction id the record resolves - and ttlSeconds, the Time To Live in the cache of client applications.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.setRecord(
  {
    undername: '@',
    transactionId: '432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM'
    ttlSeconds: 3600
  },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# removeRecord({ undername })

Removes a record from the ANT process.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.removeRecord(
  { undername: 'remove-domemain' },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setName({ name })

Sets the name of the ANT process.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.setName(
  { name: 'My ANT' },
  // optional additional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setTicker({ ticker })

Sets the ticker of the ANT contract.

NOTE: Requires signer to be provided on ANT.init to sign the transaction.

const { id: txId } = await ant.setTicker(
  { ticker: 'ANT-NEW-TICKER' },
  // optional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setDescription({ description })

Sets the description of the ANT process.

const { id: txId } = await ant.setDescription(
  { description: 'A friendly description of this ANT' },
  // optional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setKeywords({ keywords })

Sets the keywords of the ANT process.

const { id: txId } = await ant.setDescription(
  { keywords: ['Game', 'FPS', 'AO'] },
  // optional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# setLogo({ txId })

Sets the Logo of the ANT - logo should be an Arweave transaction ID.

const { id: txId } = await ant.setLogo(
  { txId: 'U7RXcpaVShG4u9nIcPVmm2FJSM5Gru9gQCIiRaIPV7f' },
  // optional tags
  { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);

# releasename({ name, ioProcessId })

Releases a name from the auction and makes it available for auction on the ARIO contract. The name must be permanently owned by the releasing wallet. 50% of the winning bid will be distributed to the ANT owner at the time of release. If no bids, the name will be released and can be reregistered by anyone.

const { id: txId } = await ant.releaseName({
  name: 'permalink',
  ioProcessId: IO_TESTNET_PROCESS_ID, // releases the name owned by the ANT and sends it to auction on the ARIO contract
});

# reassignName({ name, ioProcessId, antProcessId })

Reassigns a name to a new ANT. This can only be done by the current owner of the ANT.

const { id: txId } = await ant.reassignName({
  name: 'ardrive',
  ioProcessId: IO_TESTNET_PROCESS_ID,
  antProcessId: NEW_ANT_PROCESS_ID, // the new ANT process id that will take over ownership of the name
});

# approvePrimaryNameRequest({ name, address, ioProcessId })

Approves a primary name request for a given name or address.

const { id: txId } = await ant.approvePrimaryNameRequest({
  name: 'arns',
  address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', // must match the request initiator address
  ioProcessId: IO_TESTNET_PROCESS_ID, // the ARIO process id to use for the request
});

# removePrimaryNames({ names, ioProcessId })

Removes primary names from the ANT process.

const { id: txId } = await ant.removePrimaryNames({
  names: ['arns', 'test_arns'], // any primary names associated with a base name controlled by this ANT will be removed
  ioProcessId: IO_TESTNET_PROCESS_ID,
});

# Configuration

ANT clients can be configured to use custom AO processes. Refer to AO Connect (opens new window) for more information on how to configure the AO process to use specific AO infrastructure.

const ant = ANT.init({
  process: new AoProcess({
    processId: 'ANT_PROCESS_ID'
    ao: connect({
      MU_URL: 'https://mu-testnet.xyz',
      CU_URL: 'https://cu-testnet.xyz',
      GRAPHQL_URL: 'https://arweave.net/graphql',
      GATEWAY_URL: 'https://arweave.net',
    })
  })
});

# Logging

The library uses the Winston (opens new window) logger for node based projects, and console logger for web based projects by default. You can configure the log level via setLogLevel() API. Alternatively you can set a custom logger as the default logger so long as it satisfies the ILogger interface.

# Configuration

import { Logger } from '@ar.io/sdk';

// set the log level
Logger.default.setLogLevel('debug');

// provide your own logger
Logger.default = winston.createLogger({ ...loggerConfigs }); // or some other logger that satisifes ILogger interface

# Pagination

Certain APIs that could return a large amount of data are paginated using cursors. The SDK uses the cursor pattern (as opposed to pages) to better protect against changing data while paginating through a list of items. For more information on pagination strategies refer to this article (opens new window).

Paginated results include the following properties:

  • items: the list of items on the current request, defaulted to 100 items.
  • nextCursor: the cursor to use for the next batch of items. This is undefined if there are no more items to fetch.
  • hasMore: a boolean indicating if there are more items to fetch. This is false if there are no more items to fetch.
  • totalItems: the total number of items available. This may change as new items are added to the list, only use this for informational purposes.
  • sortBy: the field used to sort the items, by default this is startTimestamp.
  • sortOrder: the order used to sort the items, by default this is desc.

To request all the items in a list, you can iterate through the list using the nextCursor until hasMore is false.

let hasMore = true;
let cursor: string | undefined;
const gateaways = [];
while (hasMore) {
  const page = await io.getGateways({ limit: 10, cursor });
  gateaways.push(...items);
  cursor = page.nextCursor;
  hasMore = page.hasMore;
}

# Resources

# Bundling

For ANS-104 (opens new window) bundling compatible with ar.io gateways, we recommend using turbo-sdk (opens new window). Turbo SDK provides efficient and reliable methods for creating and uploading data bundles to the Arweave network, which are fully compatible with ar.io gateways. Turbo supports fiat and crypto bundling and uploading with a focus on ease of use and reliability.

# Gateways

# Running a Gateway

To run your own ar.io gateway, you can refer to the following resources:

Running your own gateway allows you to participate in the ar.io network, serve Arweave data, and potentially earn rewards. Make sure to follow the official documentation for the most up-to-date and accurate information on gateway operation.

# AO

This library integrates with AO (opens new window), a decentralized compute platform built on Arweave. We utilize AO Connect (opens new window) to interact with AO processes and messages. This integration allows for seamless communication with the AO network, enabling developers to leverage decentralized computation and storage capabilities in their applications.

For more information on how to use AO and AO Connect within this library, please refer to our documentation and examples.

# Developers

# Requirements

  • node >= v18.0.0
  • npm or yarn
  • docker (recommended for testing)

# Setup & Build

  • nvm use - use the correct node version
  • yarn install - installs dependencies
  • yarn build - builds web/node/bundled outputs

# Testing

  • yarn test:integration - runs integration tests against a local arns-service (opens new window)
  • yarn example:web - opens up the example web page
  • yarn example:cjs - runs example CJS node script
  • yarn example:esm - runs example ESM node script

# Linting & Formatting

  • yarn lint:check - checks for linting errors
  • yarn lint:fix - fixes linting errors
  • yarn format:check - checks for formatting errors
  • yarn format:fix - fixes formatting errors

# Architecture

  • Code to interfaces.
  • Prefer type safety over runtime safety.
  • Prefer composition over inheritance.
  • Prefer integration tests over unit tests.