This is the home of ar.io SDK. This SDK provides functionality for interacting with the ar.io ecosystem of services (e.g. gateways and observers) and protocols (e.g. ArNS and AO). It is available for both NodeJS and Web environments.
- Table of Contents
- Prerequisites
- Installation
- Quick Start
- Usage
- IOToken & mIOToken
- IO Process
- APIs
init({ signer })
getInfo()
getTokenSupply()
getBalance({ address })
getBalances({ cursor, limit, sortBy, sortOrder })
getVault({ address, vaultId })
getVaults({ cursor, limit, sortBy, sortOrder })
getGateway({ address })
getGateways({ cursor, limit, sortBy, sortOrder })
buyRecord({ name, type, years, processId })
getArNSRecord({ name })
getArNSRecords({ cursor, limit, sortBy, sortOrder })
getArNSAuctions({ cursor, limit, sortBy, sortOrder })
getArNSAuction({ name })
getArNSAuctionPrices({ name, type, years, intervalMs })
getDemandFactor()
getObservations({ epochIndex })
getDistributions({ epochIndex })
getEpoch({ epochIndex })
getCurrentEpoch()
getPrescribedObservers({ epochIndex })
getTokenCost({ intent, ...args })
joinNetwork(params)
leaveNetwork()
updateGatewaySettings(gatewaySettings)
increaseDelegateStake({ target, qty })
decreaseDelegateStake({ target, qty, instant })
instantWithdrawal({ gatewayAddress, vaultId })
increaseOperatorStake({ qty })
decreaseOperatorStake({ qty })
saveObservations({ reportTxId, failedGateways })
transfer({ target, qty })
increaseUndernameLimit({ name, qty })
extendLease({ name, years })
cancelWithdrawal({ gatewayAddress, vaultId })
submitAuctionBid({ name, type, years, processId })
- Configuration
- APIs
- Arweave Name Tokens (ANT's)
- ANT APIs
init({ processId, signer })
getInfo()
getState()
getOwner()
getControllers()
getRecords()
transfer({ target })
setController({ controller })
removeController({ controller })
setRecord({ undername, transactionId, ttlSeconds })
removeRecord({ undername })
setName({ name })
setTicker({ ticker })
setDescription({ description })
setKeywords({ keywords })
releaseName({ name, ioProcessId })
reassignName({ name, ioProcessId, antProcessId })
- Configuration
- ANT APIs
- Logging
- Pagination
- Resources
- Developers
node>=v18.0.0
npm
oryarn
npm install @ar.io/sdk
or
yarn add @ar.io/sdk --ignore-engines
Note
The --ignore-engines
flag is required when using yarn, as permaweb/aoconnect recommends only the use of npm. Alternatively, you can add a .yarnrc.yml
file to your project containing ignore-engines true
to ignore the engines check.
import { IO } from '@ar.io/sdk';
const io = IO.init();
const gateways = await io.getGateways();
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": 1720720621424,
"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": "startTimestamp",
"sortOrder": "desc"
}
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 based on your project's configuration. Refer to the examples directory to see how to use the SDK in various environments.
import { IO } from '@ar.io/sdk/web';
// set up client
const io = IO.init();
// fetch gateways
const gateways = await io.getGateways();
Warning
Polyfills are not provided by default for bundled web projects (Vite, ESBuild, Webpack, Rollup, etc.) . Depending on your apps bundler configuration and plugins, you will need to provide polyfills for various imports including crypto
, process
and buffer
. Refer to examples/webpack and examples/vite for examples. For other project configurations, refer to your bundler's documentation for more information on how to provide the necessary polyfills.
<script type="module">
import { IO } from 'https://unpkg.com/@ar.io/sdk';
// set up client
const io = IO.init();
// fetch gateways
const gateways = await io.getGateways();
</script>
import { IO } from '@ar.io/sdk/node';
// set up client
const io = IO.init();
// fetch gateways
const gateways = await io.getGateways();
import { IO } from '@ar.io/sdk';
// set up client
const io = IO.init();
// fetch gateways
const gateways = await io.getGateways();
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.
The IO process stores all values as mIO (milli-IO) to avoid floating-point arithmetic issues. The SDK provides an IOToken
and mIOToken
classes to handle the conversion between IO and mIO, along with rounding logic for precision.
All process interactions expect values in mIO. If numbers are provided as inputs, they are assumed to be in raw mIO values.
import { IOToken, mIOToken } from '@ar.io/sdk';
const ioValue = 1;
const mIOValue = new IOToken(ioValue).toMIO();
const mIOValue = 1_000_000;
const ioValue = new mIOToken(mIOValue).toIO();
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 io = IO.init()
// read-write client for browser environments
const io = IO.init({ signer: new ArConnectSigner(window.arweaveWallet, Arweave.init({}))});
// read-write client for node environments
const io = IO.init({ signer: new ArweaveSigner(JWK) });
Retrieves the information of the IO process.
const io = IO.init();
const info = await io.getInfo();
Output
{
"Name": "Testnet IO",
"Ticker": "tIO",
"Owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
"Denomination": 6,
"Handlers": ["_eval", "_default_"], // full list of handlers, useful for debugging
"LastTickedEpochIndex": 31 // epoch index of the last tick
}
Retrieves the total supply of tokens, returned in mIO. The total supply includes the following:
total
- the total supply of all tokenscirculating
- the total supply minus locked, withdrawn, delegated, and stakedlocked
- tokens that are locked in the protocol (a.k.a. vaulted)withdrawn
- tokens that have been withdrawn from the protocol by operators and delegatorsdelegated
- tokens that have been delegated to gatewaysstaked
- tokens that are staked in the protocol by gateway operatorsprotocolBalance
- tokens that are held in the protocol's treasury. This is included in the circulating supply.
const io = IO.init();
const supply = await io.getTokenSupply();
Output
{
"total": 1000000000000000000,
"circulating": 998094653842520,
"locked": 0,
"withdrawn": 560563387278,
"delegated": 1750000000,
"staked": 1343032770199,
"protocolBalance": 46317263683761
}
Retrieves the balance of the specified wallet address.
const io = IO.init();
// the balance will be returned in mIO as a value
const balance = await io
.getBalance({
address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ',
})
.then((balance: number) => new mIOToken(balance).toIO()); // convert it to IO for readability
Output
100000
Retrieves the balances of the IO process in mIO
, paginated and sorted by the specified criteria. The cursor
used for pagination is the last wallet address from the previous request.
const io = IO.init();
const balances = await io.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"
}
Retrieves the locked-balance user vault of the IO process by the specified wallet address and vault ID.
const io = IO.init();
const vault = await io.getVault({
address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ',
vaultId: 'vaultIdOne',
});
Output
{
"balance": 1000000,
"startTimestamp": 123,
"endTimestamp": 4567
}
Retrieves all locked-balance user vaults of the IO process, paginated and sorted by the specified criteria. The cursor
used for pagination is the last wallet address from the previous request.
const io = IO.init();
const vaults = await io.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"
}
Retrieves a gateway's info by its staking wallet address.
const io = IO.init();
const gateway = await io.getGateway({
address: '-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck',
});
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
}
}
Retrieves registered gateways of the IO process, using pagination and sorting by the specified criteria. The cursor
used for pagination is the last gateway address from the previous request.
const io = IO.init();
const gateways = await io.getGateways({
limit: 100,
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"
}
Purchases a new ArNS record with the specified name, type, and duration.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ processId: IO_DEVNET_PROCESS_ID, signer });
const record = await io.buyRecord(
{ name: 'ardrive', type: 'lease', years: 1 },
{
// optional tags
tags: [{ name: 'App-Name', value: 'ArNS-App' }],
},
);
Retrieves the record info of the specified ArNS name.
const io = IO.init();
const record = await io.getArNSRecord({ name: 'ardrive' });
Output
{
"processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
"endTimestamp": 1752256702026,
"startTimestamp": 1720720819969,
"type": "lease",
"undernames": 100
}
Retrieves all registered ArNS records of the IO process, paginated and sorted by the specified criteria. The cursor
used for pagination is the last ArNS name from the previous request.
const io = IO.init();
// get the newest 100 names
const records = await io.getArNSRecords({
limit: 100,
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
}
// ...95 other records
],
"hasMore": true,
"nextCursor": "fwdresearch",
"totalItems": 21740,
"sortBy": "startTimestamp",
"sortOrder": "desc"
}
Retrieves all active auctions of the IO process, paginated and sorted by the specified criteria. The cursor
used for pagination is the last auction name from the previous request.
const io = IO.init();
const auctions = await io.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"
}
Retrieves the auction data for the specified auction name.
const io = IO.init();
const auction = await io.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
}
}
Retrieves the auction price curve of the specified auction name for the specified type, duration, and interval. The intervalMs
is the number of milliseconds between price points on the curve. The default interval is 15 minutes.
const io = IO.init();
const priceCurve = await io.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
// ...
}
}
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 io = IO.init();
const demandFactor = await io.getDemandFactor();
Output
1.05256
Returns the epoch-indexed observation list. If no epoch index is provided, the current epoch is used.
const io = IO.init();
const observations = await io.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"
}
}
}
Returns the current rewards distribution information. If no epoch index is provided, the current epoch is used.
const io = IO.init();
const distributions = await io.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
}
}
}
Returns the epoch data for the specified block height. If no epoch index is provided, the current epoch is used.
const io = IO.init();
const epoch = await io.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 mIO
"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
}
}
}
}
Returns the current epoch data.
const io = IO.init();
const epoch = await io.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
}
}
}
Retrieves the prescribed observers of the IO process. To fetch prescribed observers for a previous epoch set the epochIndex
to the desired epoch index.
const io = IO.init();
const observers = await io.getPrescribedObservers({ epochIndex: 0 });
Output
[
{
"gatewayAddress": "BpQlyhREz4lNGS-y3rSS1WxADfxPpAuing9Lgfdrj2U",
"observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
"stake": 10000000000, // value in mIO
"start": 1296976,
"stakeWeight": 1,
"tenureWeight": 0.41453703703703704,
"gatewayRewardRatioWeight": 1,
"observerRewardRatioWeight": 1,
"compositeWeight": 0.41453703703703704,
"normalizedCompositeWeight": 0.0018972019546783507
}
]
Calculates the price in mIO to perform the interaction in question, eg a 'Buy-record' interaction, where args are the specific params for that interaction.
const price = await io
.getTokenCost({
intent: 'Buy-Record',
name: 'ar-io',
type: 'permabuy',
})
.then((p) => new mIOToken(p).toIO()); // convert to IO for readability
Output
1642.34
Joins a gateway to the ar.io network via its associated wallet.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.joinNetwork(
{
qty: new IOToken(10_000).toMIO(), // minimum operator stake allowed
autoStake: true, // auto-stake operator rewards to the gateway
allowDelegatedStaking: true, // allows delegated staking
minDelegatedStake: new IOToken(100).toMIO(), // 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' }] },
);
Sets the gateway as leaving
on the ar.io network. Requires signer
to be provided on IO.init
to sign the transaction. The gateways operator and delegate stakes are vaulted and will be returned after leave periods. The gateway will be removed from the network after the leave period.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.leaveNetwork(
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Writes new gateway settings to the callers gateway configuration.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.updateGatewaySettings(
{
// any other settings you want to update
minDelegatedStake: new IOToken(100).toMIO(),
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Increases the callers stake on the target gateway.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.increaseDelegateStake(
{
target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
qty: new IOToken(100).toMIO(),
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Decreases the callers stake on the target gateway. Can instantly decrease stake by setting instant to true
.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.decreaseDelegateStake(
{
target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
qty: new IOToken(100).toMIO(),
},
{
tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
},
);
Pay the early withdrawal fee and withdraw instantly.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.decreaseDelegateStake({
target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3',
qty: new IOToken(100).toMIO(),
instant: true, // Immediately withdraw this stake and pay the instant withdrawal fee
});
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 IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
// removes a delegated vault from a gateway
const { id: txId } = await io.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 io.instantWithdrawal(
{
vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
},
);
Increases the callers operator stake. Must be executed with a wallet registered as a gateway operator.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.increaseOperatorStake(
{
qty: new IOToken(100).toMIO(),
},
{
tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
},
);
Decreases the callers operator stake. Must be executed with a wallet registered as a gateway operator. Requires signer
to be provided on IO.init
to sign the transaction.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.decreaseOperatorStake(
{
qty: new IOToken(100).toMIO(),
},
{
tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
},
);
Saves the observations of the current epoch. Requires signer
to be provided on IO.init
to sign the transaction.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.saveObservations(
{
reportTxId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
failedGateways: ['t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3'],
},
{
tags: [{ name: 'App-Name', value: 'My-Awesome-App' }],
},
);
Transfers mIO
to the designated target
recipient address. Requires signer
to be provided on IO.init
to sign the transaction.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.transfer(
{
target: '-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5',
qty: new IOToken(1000).toMIO(),
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
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 IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.increaseUndernameLimit(
{
name: 'ar-io',
qty: 420,
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
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 io = IO.init({ signer: new ArweaveSigner(jwk) });
const { id: txId } = await io.extendLease(
{
name: 'ar-io',
years: 1,
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Cancels an existing vault on a gateway. The vaulted stake will be returned to the callers stake. If no gatewayAddress
is provided, the signer's address will be used.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
// cancels a delegated vault from a gateway
const { id: txId } = await io.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 io.cancelWithdrawal(
{
// operator vault id to cancel
vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3',
},
);
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.
Note: Requires signer
to be provided on IO.init
to sign the transaction.
const io = IO.init({ signer: new ArweaveSigner(jwk) });
const auction = await io.getArNSAuction({ name: 'permalink' });
// check the current price is under some threshold
if (auction && auction.currentPrice <= new IOToken(20_000).toMIO().valueOf()) {
const { id: txId } = await io.submitAuctionBid(
{
name: 'permalink',
type: 'lease',
years: 1,
processId: 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM',
},
// optional additional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
}
The IO client class exposes APIs relevant to the ar.io process. It can be configured to use any AO Process ID that adheres to the IO Network Spec. By default, it will use the current IO Testnet Process. Refer to AO Connect for more information on how to configure an IO process to use specific AO infrastructure.
// provide a custom ao infrastructure and process id
const io = IO.init({
process: new AoProcess({
processId: 'IO_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',
})
})
});
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.
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'
});
Retrieves the information of the ANT process.
const info = await ant.getInfo();
Output
{
"name": "ArDrive",
"ticker": "ANT-ARDRIVE",
"description": "This is the ANT for the ArDrive decentralized web app.",
"keywords": ["File-sharing", "Publishing", "dApp"],
"owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ"
}
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",
"Description": "A friendly description for this ANT.",
"Keywords": ["keyword1", "keyword2", "keyword3"],
"Logo": "Sie_26dvgyok0PZD_-iQAFOhOd5YxDTkczOLoqTTL_A",
"Denomination": 0,
"Name": "AR.IO Foundation",
"Owner": "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY"
}
Returns the owner of the configured ANT process.
const owner = await ant.getOwner();
Output
"ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4"
Returns the controllers of the configured ANT process.
const controllers = await ant.getControllers();
Output
["ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4"]
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
}
}
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' }] },
);
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' }] },
);
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' }] },
);
Updates or creates a record in the ANT process.
Note: Requires signer
to be provided on ANT.init
to sign the transaction.
Records, or
undernames
are configured with thetransactionId
- the arweave transaction id the record resolves - andttlSeconds
, the Time To Live in the cache of client applications.
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' }] },
);
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' }] },
);
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' }] },
);
Sets the ticker of the ANT process.
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' }] },
);
Sets the description of the ANT process.
Note: Requires signer
to be provided on ANT.init
to sign the transaction.
const { id: txId } = await ant.setDescription(
{ description: 'A friendly description of this ANT' },
// optional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Sets the keywords of the ANT process.
Note: Requires signer
to be provided on ANT.init
to sign the transaction.
const { id: txId } = await ant.setDescription(
{ keywords: ['Game', 'FPS', 'AO'] },
// optional tags
{ tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] },
);
Releases a name from the auction and makes it available for auction on the IO 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.
Note: Requires signer
to be provided on ANT.init
to sign the transaction.
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 IO contract
});
Reassigns a name to a new ANT. This can only be done by the current owner of the ANT.
Note: Requires signer
to be provided on ANT.init
to sign the transaction.
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
});
ANT clients can be configured to use custom AO process. Refer to AO Connect 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',
})
})
});
The library uses the Winston 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 satisfes the ILogger
interface.
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
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.
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 isundefined
if there are no more items to fetch.hasMore
: a boolean indicating if there are more items to fetch. This isfalse
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 isstartTimestamp
.sortOrder
: the order used to sort the items, by default this isdesc
.
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: 100, cursor });
gateaways.push(...items);
cursor = page.nextCursor;
hasMore = page.hasMore;
}
For ANS-104 bundling compatible with ar.io gateways, we recommend using turbo-sdk. 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.
To run your own ar.io gateway, you can refer to the following resources:
- ar-io-node repository: This repository contains the source code and instructions for setting up and running an ar.io gateway node.
- ar.io Gateway Documentation: This comprehensive guide provides detailed information on gateway setup, configuration, and management.
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.
This library integrates with AO, a decentralized compute platform built on Arweave. We utilize AO Connect 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.
node
>= 18.0.0npm
oryarn
docker
(recommended for testing)
nvm use
- use the correct node versionyarn install
- installs dependenciesyarn build
- builds web/node/bundled outputs
yarn test
- runs e2e tests and unit testsyarn test:e2e
- runs e2e testsyarn test:unit
- runs unit testsyarn example:web
- opens up the example web pageyarn example:cjs
- runs example CJS node scriptyarn example:esm
- runs example ESM node scriptyarn example:vite
- runs example Vite web page
yarn lint:check
- checks for linting errorsyarn lint:fix
- fixes linting errorsyarn format:check
- checks for formatting errorsyarn format:fix
- fixes formatting errors
- Code to interfaces.
- Prefer type safety over runtime safety.
- Prefer composition over inheritance.
- Prefer integration tests over unit tests.
For more information on how to contribute, please see CONTRIBUTING.md.