# ARIO Integrations (/(ant-contracts)/ario-integrations) #### releaseName() Releases a name from the current owner and makes it available for purchase on the ARIO contract. The name must be permanently owned by the releasing wallet. If purchased within the recently returned name period (14 epochs), 50% of the purchase amount will be distributed to the ANT owner at the time of release. If no purchases in the recently returned name period, the name can be reregistered by anyone for the normal fee. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.releaseName({ name: 'permalink', arioProcessId: ARIO_MAINNET_PROCESS_ID, // releases the name owned by the ANT and sends it to recently returned names on the ARIO contract }); ``` #### reassignName() 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._ ```typescript const { id: txId } = await ant.reassignName({ name: 'ardrive', arioProcessId: ARIO_MAINNET_PROCESS_ID, antProcessId: NEW_ANT_PROCESS_ID, // the new ANT process id that will take over ownership of the name }); ``` #### approvePrimaryNameRequest() Approves a primary name request for a given name or address. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.approvePrimaryNameRequest({ name: 'arns', address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', // must match the request initiator address arioProcessId: ARIO_MAINNET_PROCESS_ID, // the ARIO process id to use for the request }); ``` #### removePrimaryNames() Removes primary names from the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript 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 arioProcessId: ARIO_MAINNET_PROCESS_ID, notifyOwners: true, // if true, the owners of the removed names will be send AO messages to notify them of the removal }); ``` # Balances (/(ant-contracts)/balances) #### getBalances() Returns all token balances for the ANT. ```typescript const balances = await ant.getBalances(); ``` **Output:** ```json { "ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4": 1, "aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f": 0 } ``` #### getBalance() Returns the balance of a specific address. ```typescript const balance = await ant.getBalance({ address: 'ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4', }); ``` **Output:** ```json 1 ``` # Controllers (/(ant-contracts)/controllers) #### addController() 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._ ```typescript const { id: txId } = await ant.addController( { controller: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### removeController() 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._ ```typescript const { id: txId } = await ant.removeController( { controller: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` # Initialize (/(ant-contracts)/initialize) #### init() 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. ```typescript // 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' }); ``` # Metadata (/(ant-contracts)/metadata) #### setName() Sets the name of the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.setName( { name: 'My ANT' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### setTicker() Sets the ticker of the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.setTicker( { ticker: 'ANT-NEW-TICKER' }, // optional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### setDescription() Sets the description of the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.setDescription( { description: 'A friendly description of this ANT' }, // optional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### setKeywords() Sets the keywords of the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.setKeywords( { keywords: ['Game', 'FPS', 'AO'] }, // optional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### getLogo() Returns the TX ID of the logo set for the ANT. ```typescript const logoTxId = await ant.getLogo(); ``` #### setLogo() Sets the Logo of the ANT - logo should be an Arweave transaction ID. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.setLogo( { txId: 'U7RXcpaVShG4u9nIcPVmm2FJSM5Gru9gQCIiRaIPV7f' }, // optional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` # Records (/(ant-contracts)/records) #### setBaseNameRecord() Adds or updates the base name record for the ANT. This is the top level name of the ANT (e.g. ardrive.ar.io). Supports undername ownership delegation and metadata. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript // get the ant for the base name const arnsRecord = await ario.getArNSRecord({ name: 'ardrive' }); const ant = await ANT.init({ processId: arnsName.processId }); // Basic usage const { id: txId } = await ant.setBaseNameRecord({ transactionId: '432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM', ttlSeconds: 3600, }); // With ownership delegation and metadata const { id: txId } = await ant.setBaseNameRecord({ transactionId: '432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM', ttlSeconds: 3600, owner: 'user-wallet-address-123...', // delegate ownership to another address displayName: 'ArDrive', // display name logo: 'logo-tx-id-123...', // logo transaction ID description: 'Decentralized storage application', keywords: ['storage', 'decentralized', 'web3'], }); // ardrive.ar.io will now resolve to the provided transaction id and include metadata ``` #### setUndernameRecord() Adds or updates an undername record for the ANT. An undername is appended to the base name of the ANT (e.g. dapp_ardrive.ar.io). Supports undername ownership delegation and metadata. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ > 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. ```typescript const arnsRecord = await ario.getArNSRecord({ name: 'ardrive' }); const ant = await ANT.init({ processId: arnsName.processId }); // Basic usage const { id: txId } = await ant.setUndernameRecord( { undername: 'dapp', transactionId: '432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM', ttlSeconds: 900, }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); // With ownership delegation and metadata const { id: txId } = await ant.setUndernameRecord( { undername: 'alice', transactionId: '432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM', ttlSeconds: 900, owner: 'alice-wallet-address-123...', // delegate ownership to Alice displayName: "Alice's Site", // display name logo: 'avatar-tx-id-123...', // avatar/logo transaction ID description: 'Personal portfolio and blog', keywords: ['portfolio', 'personal', 'blog'], }, { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); // dapp_ardrive.ar.io will now resolve to the provided transaction id // alice_ardrive.ar.io will be owned by Alice and include metadata ``` #### removeUndernameRecord() Removes an undername record from the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.removeUndernameRecord( { undername: 'dapp' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); // dapp_ardrive.ar.io will no longer resolve to the provided transaction id ``` #### setRecord() Deprecated: Use `setBaseNameRecord` or `setUndernameRecord` instead. Adds or updates a record for the ANT process. The `undername` parameter is used to specify the record name. Use `@` for the base name record. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ > 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. ```typescript 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() Deprecated: Use `removeUndernameRecord` instead. Removes a record from the ANT process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const arnsRecord = await ario.getArNSRecord({ name: 'ardrive' }); const ant = await ANT.init({ processId: arnsName.processId }); const { id: txId } = await ant.removeRecord( { undername: 'dapp' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); // dapp_ardrive.ar.io will no longer resolve to the provided transaction id ``` # Spawn (/(ant-contracts)/spawn) #### spawn() Spawns a new ANT (Arweave Name Token) process. This static function creates a new ANT process on the AO network and returns the process ID. _Note: Requires `signer` to be provided to sign the spawn transaction._ ```typescript const processId = await ANT.spawn({ signer: new ArweaveSigner(jwk), state: { name: 'My ANT', ticker: 'MYANT', description: 'My custom ANT token', }, }); // Using a custom module ID const processId = await ANT.spawn({ signer: new ArweaveSigner(jwk), module: 'FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE', // Custom module ID state: { name: 'My Custom Module ANT', ticker: 'CUSTOM', description: 'ANT using a specific module version', }, }); ``` **CLI Usage:** ```bash ar.io spawn-ant --wallet-file wallet.json --name "My ANT" --ticker "MYANT" ar.io spawn-ant --wallet-file wallet.json --module FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE --name "My Custom ANT" --ticker "CUSTOM" ``` **Parameters:** - `signer: AoSigner` - The signer used to authenticate the spawn transaction - `module?: string` - Optional module ID to use; if not provided, gets latest from ANT registry - `ao?: AoClient` - Optional AO client instance (defaults to legacy mode connection) - `scheduler?: string` - Optional scheduler ID - `state?: SpawnANTState` - Optional initial state for the ANT including name, ticker, description, etc. - `antRegistryId?: string` - Optional ANT registry ID - `logger?: Logger` - Optional logger instance - `authority?: string` - Optional authority **Returns:** `Promise\` - The process ID of the newly spawned ANT # State (/(ant-contracts)/state) #### getInfo() Retrieves the information of the ANT process. ```typescript const info = await ant.getInfo(); ``` **Output:** ```json { "name": "ArDrive", "ticker": "ANT-ARDRIVE", "description": "This is the ANT for the ArDrive decentralized web app.", "keywords": ["File-sharing", "Publishing", "dApp"], "owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ" } ``` #### getHandlers() Retrieves the handlers supported on the ANT ```typescript const handlers = await ant.getHandlers(); ``` **Output:** ```json [ "_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. ```typescript const state = await ant.getState(); ``` **Output:** ```json { "TotalSupply": 1, "Balances": { "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY": 1 }, "Controllers": [], "Records": { "v1-0-0_whitepaper": { "transactionId": "lNjWn3LpyhKC95Kqe-x8X2qgju0j98MhucdDKK85vc4", "ttlSeconds": 900 }, "@": { "transactionId": "2rMLb2uHAyEt7jSu6bXtKx8e-jOfIf7E-DOgQnm8EtU", "ttlSeconds": 3600 }, "alice": { "transactionId": "kMk95k_3R8x_7d3wB9tEOiL5v6n8QhR_VnFCh3aeE3f", "ttlSeconds": 900, "owner": "alice-wallet-address-123...", "displayName": "Alice's Portfolio", "logo": "avatar-tx-id-456...", "description": "Personal portfolio and blog", "keywords": ["portfolio", "personal", "blog"] }, "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" } ``` #### getOwner() Returns the owner of the configured ANT process. ```typescript const owner = await ant.getOwner(); ``` **Output:** ```json "ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4" ``` #### getName() Returns the name of the ANT (not the same as ArNS name). ```typescript const name = await ant.getName(); ``` **Output:** ```json "ArDrive" ``` #### getTicker() Returns the ticker symbol of the ANT. ```typescript const ticker = await ant.getTicker(); ``` **Output:** ```json "ANT-ARDRIVE" ``` #### getControllers() Returns the controllers of the configured ANT process. ```typescript const controllers = await ant.getControllers(); ``` **Output:** ```json ["ccp3blG__gKUvG3hsGC2u06aDmqv4CuhuDJGOIg0jw4"] ``` #### getRecords() Returns all records on the configured ANT process, including the required `@` record that resolve connected ArNS names. ```typescript const records = await ant.getRecords(); ``` **Output:** ```json { "@": { "transactionId": "UyC5P5qKPZaltMmmZAWdakhlDXsBF6qmyrbWYFchRTk", "ttlSeconds": 3600 }, "alice": { "transactionId": "kMk95k_3R8x_7d3wB9tEOiL5v6n8QhR_VnFCh3aeE3f", "ttlSeconds": 900, "owner": "alice-wallet-address-123...", "displayName": "Alice's Portfolio", "logo": "avatar-tx-id-456...", "description": "Personal portfolio and blog", "keywords": ["portfolio", "personal", "blog"] }, "zed": { "transactionId": "-k7t8xMoB8hW482609Z9F4bTFMC3MnuW8bTvTyT8pFI", "ttlSeconds": 900 }, "ardrive": { "transactionId": "-cucucachoodwedwedoiwepodiwpodiwpoidpwoiedp", "ttlSeconds": 900 } } ``` #### getRecord() Returns a specific record by its undername. ```typescript const record = await ant.getRecord({ undername: 'dapp' }); ``` **Output:** ```json { "transactionId": "432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "ttlSeconds": 900, "owner": "alice-wallet-address-123...", "displayName": "Alice's Site", "logo": "avatar-tx-id-456...", "description": "Personal portfolio and blog", "keywords": ["portfolio", "personal", "blog"] } ``` # Static Methods (/(ant-contracts)/static-methods) #### ANT.fork() Forks an existing ANT process to create a new one with the same state but potentially a different module. This is used for upgrading ANTs to new versions. ```typescript const newProcessId = await ANT.fork({ signer: new ArweaveSigner(jwk), antProcessId: 'existing-ant-process-id', // Optional: specify a specific module ID, defaults to latest from registry module: 'new-module-id', onSigningProgress: (event, payload) => { console.log(`Fork progress: ${event}`); }, }); console.log(`Forked ANT to new process: ${newProcessId}`); ``` #### ANT.upgrade() Static method to upgrade an ANT by forking it to the latest version and reassigning names. ```typescript // Upgrade and reassign all affiliated names const result = await ANT.upgrade({ signer: new ArweaveSigner(jwk), antProcessId: 'existing-ant-process-id', reassignAffiliatedNames: true, arioProcessId: ARIO_MAINNET_PROCESS_ID }); // Upgrade and reassign specific names const result = await ANT.upgrade({ signer: new ArweaveSigner(jwk), antProcessId: 'existing-ant-process-id', names: ['ardrive', 'example'], reassignAffiliatedNames: false, arioProcessId: ARIO_MAINNET_PROCESS_ID }); console.log(`Upgraded to process: ${result.forkedProcessId}`); console.log(`Successfully reassigned names: ${Object.keys(result.reassignedNames)}`); console.log(`Failed reassignments: ${Object.keys(result.failedReassignedNames)}`); ``` # Transfer (/(ant-contracts)/transfer) #### transfer() 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._ ```typescript const { id: txId } = await ant.transfer( { target: 'aGzM_yjralacHIUo8_nQXMbh9l1cy0aksiL_x9M359f' }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` # Undername Ownership (/(ant-contracts)/undername-ownership) NTs support ownership of undernames: 1. **ANT Owner** - Has full control over the ANT and all records 2. **Controllers** - Can manage records but cannot transfer ANT ownership 3. **Record Owners** - Can only update their specific delegated records When a record owner updates their own record, they **MUST** include their own address in the `owner` field. If the `owner` field is omitted or set to a different address, the record ownership will be transferred or renounced. #### transferRecord() Transfers ownership of a specific record (undername) to another address. This enables delegation of control for individual records within an ANT while maintaining the ANT owner's ultimate authority. The current record owner or ANT owner/controllers can transfer ownership. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript const { id: txId } = await ant.transferRecord({ undername: 'alice', // the subdomain/record to transfer recipient: 'new-owner-address-123...', // address of the new owner }); // alice_ardrive.ar.io is now owned by the new owner address // The new owner can update the record but not other records in the ANT ``` **CLI Usage:** ```bash ar.io transfer-record \ --process-id "ANT_PROCESS_ID" \ --undername "alice" \ --recipient "new-owner-address-123..." \ --wallet-file "path/to/wallet.json" ``` #### Record Owner Workflow Examples **Checking Record Ownership:** ```typescript const record = await ant.getRecord({ undername: 'alice' }); console.log(`Record owner: ${record.owner}`); console.log(`Transaction ID: ${record.transactionId}`); ``` **Record Owner Updating Their Own Record:** ```typescript // Alice (record owner) updating her own record const aliceAnt = ANT.init({ processId: 'ANT_PROCESS_ID', signer: new ArweaveSigner(aliceJwk), // Alice's wallet }); // ✅ CORRECT: Alice includes her own address as owner const { id: txId } = await aliceAnt.setUndernameRecord({ undername: 'alice', transactionId: 'new-content-tx-id-456...', ttlSeconds: 1800, owner: 'alice-wallet-address-123...', // MUST be Alice's own address displayName: 'Alice Updated Portfolio', description: 'Updated personal portfolio and blog', }); // ❌ WRONG: Omitting owner field will renounce ownership const badUpdate = await aliceAnt.setUndernameRecord({ undername: 'alice', transactionId: 'new-content-tx-id-456...', ttlSeconds: 1800, // Missing owner field - this will renounce ownership! }); // ❌ WRONG: Setting different owner will transfer ownership const badTransfer = await aliceAnt.setUndernameRecord({ undername: 'alice', transactionId: 'new-content-tx-id-456...', ttlSeconds: 1800, owner: 'someone-else-address-789...', // This transfers ownership to someone else! }); ``` **What Happens When Record Ownership is Renounced:** If a record owner updates their record without including the `owner` field, the record becomes owned by the ANT owner/controllers again: ```typescript // Before: alice record is owned by alice-wallet-address-123... const recordBefore = await ant.getRecord({ undername: 'alice' }); console.log(recordBefore.owner); // "alice-wallet-address-123..." // Alice updates without owner field await aliceAnt.setUndernameRecord({ undername: 'alice', transactionId: 'new-tx-id...', ttlSeconds: 900, // No owner field = renounces ownership }); // After: record ownership reverts to ANT owner const recordAfter = await ant.getRecord({ undername: 'alice' }); console.log(recordAfter.owner); // undefined (controlled by ANT owner again) ``` # Upgrade (/(ant-contracts)/upgrade) #### upgrade() Upgrades an ANT by forking it to the latest version from the ANT registry and optionally reassigning ArNS names to the new process. This function first checks the version of the existing ANT, creates a new ANT using `.fork()` to the latest version, and then reassigns the ArNS names affiliated with this process to the new process. _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._ ```typescript // Upgrade ANT and reassign all affiliated ArNS names to the new process const result = await ant.upgrade(); // Upgrade ANT and reassign specific ArNS names to the new process const result = await ant.upgrade({ names: ['ardrive', 'example'], }); // with callbacks const result = await ant.upgrade({ names: ['ardrive', 'example'], onSigningProgress: (event, payload) => { console.log(`${event}:`, payload); if (event === 'checking-version') { console.log(`Checking version: ${payload.antProcessId}`); } if (event === 'fetching-affiliated-names') { console.log(`Fetching affiliated names: ${payload.arioProcessId}`); } if (event === 'reassigning-name') { console.log(`Reassigning name: ${payload.name}`); } if (event === 'validating-names') { console.log(`Validating names: ${payload.names}`); } // other callback events... }, }); console.log(`Upgraded to process: ${result.forkedProcessId}`); console.log(`Successfully reassigned names: ${result.reassignedNames}`); console.log(`Failed to reassign names: ${result.failedReassignedNames}`); ``` **Parameters:** - `reassignAffiliatedNames?: boolean` - If true, reassigns all names associated with this process to the new forked process (defaults to true when names is empty) - `names?: string[]` - Optional array of specific names to reassign (cannot be used with `reassignAffiliatedNames: true`). These names must be affiliated with this ANT on the provided ARIO process. - `arioProcessId?: string` - Optional ARIO process ID (defaults to mainnet) - `antRegistryId?: string` - Optional ANT registry process ID used to resolve the latest version (defaults to mainnet registry) - `skipVersionCheck?: boolean` - Skip checking if ANT is already latest version (defaults to false) - `onSigningProgress?: Function` - Optional progress callback for tracking upgrade steps **Returns:** `Promise, failedReassignedNames: Record }>` # Versions (/(ant-contracts)/versions) #### getModuleId() Gets the module ID of the current ANT process by querying its spawn transaction tags. Results are cached after the first successful fetch. ```typescript const moduleId = await ant.getModuleId(); console.log(`ANT was spawned with module: ${moduleId}`); // With custom GraphQL URL and retries const moduleId = await ant.getModuleId({ graphqlUrl: 'https://arweave.net/graphql', retries: 5 }); ``` **Output:** ```json "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE" ``` #### getVersion() Gets the version string of the current ANT by matching its module ID with versions from the ANT registry. ```typescript const version = await ant.getVersion(); console.log(`ANT is running version: ${version}`); // With custom ANT registry const version = await ant.getVersion({ antRegistryId: 'custom-ant-registry-id' }); ``` **Output:** ```json "23" ``` #### isLatestVersion() Checks if the current ANT version is the latest according to the ANT registry. ```typescript const isLatest = await ant.isLatestVersion(); if (!isLatest) { console.log('ANT can be upgraded to the latest version'); } ``` **Output:** ```json true ``` #### getANTVersions Static method that returns the full array of available ANT versions and the latest version from the ANT registry. ```typescript // Get all available ANT versions const antVersions = ANT.versions; const versions = await antVersions.getANTVersions(); ``` Result: ```json { [ { "moduleId": "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE", "version": "23", "releaseNotes": "Initial release of the ANT module.", "releaseDate": 1700000000000 } // ...other versions ], } ``` #### getLatestANTVersion() Static method that returns the latest ANT version from the ANT registry. ```typescript // Get the latest ANT version // Get all available ANT versions const antVersions = ANT.versions; const versions = await antVersions.getANTVersions(); const latestVersion = await antVersions.getLatestANTVersion(); ``` Result: ```json { "moduleId": "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE", "version": "23", "releaseNotes": "Initial release of the ANT module.", "releaseDate": 1700000000000 } ``` # Arweave Name System (ArNS) (/(ario-contract)/arweave-name-system-arns) #### resolveArNSName() Resolves an ArNS name to the underlying data id stored on the names corresponding ANT id. ##### Resolving a base name ```typescript const ario = ARIO.mainnet(); const record = await ario.resolveArNSName({ name: 'ardrive' }); ``` **Output:** ```json { "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "txId": "kvhEUsIY5bXe0Wu2-YUFz20O078uYFzmQIO-7brv8qw", "type": "lease", "recordIndex": 0, "undernameLimit": 100, "owner": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3", "name": "ardrive" } ``` ##### Resolving an undername ```typescript const ario = ARIO.mainnet(); const record = await ario.resolveArNSName({ name: 'logo_ardrive' }); ``` **Output:** ```json { "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "txId": "kvhEUsIY5bXe0Wu2-YUFz20O078uYFzmQIO-7brv8qw", "type": "lease", "recordIndex": 1, "undernameLimit": 100, "owner": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3", "name": "ardrive" } ``` #### buyRecord() Purchases a new ArNS record with the specified name, type, processId, and duration. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ **Arguments:** - `name` - _required_: the name of the ArNS record to purchase - `type` - _required_: the type of ArNS record to purchase - `processId` - _optional_: the process id of an existing ANT process. If not provided, a new ANT process using the provided `signer` will be spawned, and the ArNS record will be assigned to that process. - `years` - _optional_: the duration of the ArNS record in years. If not provided and `type` is `lease`, the record will be leased for 1 year. If not provided and `type` is `permabuy`, the record will be permanently registered. - `referrer` - _optional_: track purchase referrals for analytics (e.g. `my-app.com`) ```typescript const ario = ARIO.mainnet({ signer }); const record = await ario.buyRecord( { name: 'ardrive', type: 'lease', years: 1, processId: 'bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM', // optional: assign to existing ANT process referrer: 'my-app.com', // optional: track purchase referrals for analytics }, { // optional tags tags: [{ name: 'App-Name', value: 'ArNS-App' }], onSigningProgress: (step, event) => { console.log(`Signing progress: ${step}`); if (step === 'spawning-ant') { console.log('Spawning ant:', event); } if (step === 'registering-ant') { console.log('Registering ant:', event); } if (step === 'verifying-state') { console.log('Verifying state:', event); } if (step === 'buying-name') { console.log('Buying name:', event); } }, }, ); ``` #### upgradeRecord() Upgrades an existing leased ArNS record to a permanent ownership. The record must be currently owned by the caller and be of type "lease". _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer }); const record = await ario.upgradeRecord( { name: 'ardrive', referrer: 'my-app.com', // optional: track purchase referrals for analytics }, { // optional tags tags: [{ name: 'App-Name', value: 'ArNS-App' }], }, ); ``` #### getArNSRecord() Retrieves the record info of the specified ArNS name. ```typescript const ario = ARIO.mainnet(); const record = await ario.getArNSRecord({ name: 'ardrive' }); ``` **Output:** ```json { "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "endTimestamp": 1752256702026, "startTimestamp": 1720720819969, "type": "lease", "undernameLimit": 100 } ``` #### getArNSRecords() 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. ```typescript const ario = ARIO.mainnet(); // get the newest 100 names const records = await ario.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:** ```json { "items": [ { "name": "ao", "processId": "eNey-H9RB9uCdoJUvPULb35qhZVXZcEXv8xds4aHhkQ", "purchasePrice": 75541282285, "startTimestamp": 1720720621424, "endTimestamp": 1752256702026, "type": "permabuy", "undernameLimit": 10 }, { "name": "ardrive", "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "endTimestamp": 1720720819969, "startTimestamp": 1720720620813, "purchasePrice": 75541282285, "type": "lease", "undernameLimit": 100 }, { "name": "arweave", "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "endTimestamp": 1720720819969, "startTimestamp": 1720720620800, "purchasePrice": 75541282285, "type": "lease", "undernameLimit": 100 }, { "name": "ar-io", "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "endTimestamp": 1720720819969, "startTimestamp": 1720720619000, "purchasePrice": 75541282285, "type": "lease", "undernameLimit": 100 }, { "name": "fwd", "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM", "endTimestamp": 1720720819969, "startTimestamp": 1720720220811, "purchasePrice": 75541282285, "type": "lease", "undernameLimit": 100 } // ...95 other records ], "hasMore": true, "nextCursor": "fwdresearch", "totalItems": 21740, "sortBy": "startTimestamp", "sortOrder": "desc" } ``` #### getArNSRecordsForAddress() Retrieves all registered ArNS records of the specified address according to the `ANTRegistry` access control list, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last ArNS name from the previous request. ```typescript const ario = ARIO.mainnet(); const records = await ario.getArNSRecordsForAddress({ address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', 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:** ```json { "limit": 1, "totalItems": 31, "hasMore": true, "nextCursor": "ardrive", "items": [ { "startTimestamp": 1740009600000, "name": "ardrive", "endTimestamp": 1777328018367, "type": "permabuy", "purchasePrice": 0, "undernameLimit": 100, "processId": "hpF0HdijWlBLFePjWX6u_-Lg3Z2E_PrP_AoaXDVs0bA" } ], "sortOrder": "desc", "sortBy": "startTimestamp" } ``` #### increaseUndernameLimit() 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._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.increaseUndernameLimit( { name: 'ar-io', qty: 420, referrer: 'my-app.com', // optional: track purchase referrals for analytics }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### extendLease() 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. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.extendLease( { name: 'ar-io', years: 1, referrer: 'my-app.com', // optional: track purchase referrals for analytics }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### getTokenCost() Calculates the price in mARIO to perform the interaction in question, eg a 'Buy-Name' interaction, where args are the specific params for that interaction. ```typescript const price = await ario .getTokenCost({ intent: 'Buy-Name', name: 'ar-io', type: 'permabuy', }) .then((p) => new mARIOToken(p).toARIO()); // convert to ARIO for readability ``` **Output:** ```json 1642.34 ``` #### getCostDetails() Calculates the expanded cost details for the interaction in question, e.g a 'Buy-Name' interaction, where args are the specific params for that interaction. The fromAddress is the address that would be charged for the interaction, and fundFrom is where the funds would be taken from, either `balance`, `stakes`, or `any`. ```typescript const costDetails = await ario.getCostDetails({ intent: 'Buy-Name', fromAddress: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', fundFrom: 'stakes', name: 'ar-io', type: 'permabuy', }); ``` **Output:** ```json { "tokenCost": 2384252273, "fundingPlan": { "address": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3", "balance": 0, "stakes": { "Rc80LG6h27Y3p9TN6J5hwDeG5M51cu671YwZpU9uAVE": { "vaults": [], "delegatedStake": 2384252273 } }, "shortfall": 0 }, "discounts": [] } ``` #### 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. ```typescript const ario = ARIO.mainnet(); const demandFactor = await ario.getDemandFactor(); ``` **Output:** ```json 1.05256 ``` #### getArNSReturnedNames() 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. ```typescript const ario = ARIO.mainnet(); const returnedNames = await ario.getArNSReturnedNames({ limit: 100, sortBy: 'endTimestamp', sortOrder: 'asc', // return the returned names ending soonest first }); ``` **Output:** ```json { "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() Retrieves the returned name data for the specified returned name. ```typescript const ario = ARIO.mainnet(); const returnedName = await ario.getArNSReturnedName({ name: 'permalink' }); ``` **Output:** ```json { "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 } } ``` # Configuration (/(ario-contract)/configuration) The ARIO client class exposes APIs relevant to the ar.io process. It can be configured to use any AO Process ID that adheres to the [ARIO Network Spec]. By default, it will use the current [ARIO Testnet Process]. Refer to [AO Connect] for more information on how to configure an ARIO process to use specific AO infrastructure. ```typescript // provide a custom ao infrastructure and process id const ario = ARIO.mainnet({ process: new AOProcess({ processId: 'ARIO_PROCESS_ID' ao: connect({ MODE: 'legacy', MU_URL: 'https://mu-testnet.xyz', CU_URL: 'https://cu-testnet.xyz', GRAPHQL_URL: 'https://arweave.net/graphql', GATEWAY_URL: 'https://arweave.net', }) }) }); ``` # Epochs (/(ario-contract)/epochs) #### getCurrentEpoch() Returns the current epoch data. ```typescript const ario = ARIO.mainnet(); const epoch = await ario.getCurrentEpoch(); ``` **Output:** ```json { "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, "gatewayPerformanceRatio": 1, "observerRewardRatioWeight": 1, "compositeWeight": 0.4494598765432099, "normalizedCompositeWeight": 0.002057032496835938 } ], "distributions": { "distributedTimestamp": 1711122739, "totalEligibleRewards": 100000000, "rewards": { "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000 } } } ``` #### getEpoch() Returns the epoch data for the specified block height. If no epoch index is provided, the current epoch is used. ```typescript const ario = ARIO.mainnet(); const epoch = await ario.getEpoch({ epochIndex: 0 }); ``` **Output:** ```json { "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, "gatewayPerformanceRatio": 1, "observerRewardRatioWeight": 1, "compositeWeight": 0.4494598765432099, "normalizedCompositeWeight": 0.002057032496835938 } ], "distributions": { "totalEligibleGateways": 1, "totalEligibleRewards": 100000000, "totalEligibleObserverReward": 100000000, "totalEligibleGatewayReward": 100000000, "totalDistributedRewards": 100000000, "distributedTimestamp": 1720720621424, "rewards": { "distributed": { "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000 } } } } ``` #### getEligibleEpochRewards() Returns the eligible epoch rewards for the specified block height. If no epoch index is provided, the current epoch is used. ```typescript const ario = ARIO.mainnet(); const rewards = await ario.getEligibleEpochRewards({ epochIndex: 0 }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": true, "totalItems": 37, "limit": 1, "sortBy": "cursorId", "items": [ { "cursorId": "xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0_xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0", "recipient": "xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0", "gatewayAddress": "xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0", "eligibleReward": 2627618704, "type": "operatorReward" } ], "nextCursor": "xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0_xN_aVln30LmoCffwmk5_kRkcyQZyZWy1o_TNtM_CTm0" } ``` #### getObservations() Returns the epoch-indexed observation list. If no epoch index is provided, the current epoch is used. ```typescript const ario = ARIO.mainnet(); const observations = await ario.getObservations(); ``` **Output:** ```json { "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() Returns the current rewards distribution information. If no epoch index is provided, the current epoch is used. ```typescript const ario = ARIO.mainnet(); const distributions = await ario.getDistributions({ epochIndex: 0 }); ``` **Output:** ```json { "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 } } } ``` #### saveObservations() Saves the observations of the current epoch. Requires `signer` to be provided on `ARIO.init` to sign the transaction. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.saveObservations( { reportTxId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3', failedGateways: ['t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3'], }, { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }], }, ); ``` #### getPrescribedObservers() Retrieves the prescribed observers of the ARIO process. To fetch prescribed observers for a previous epoch set the `epochIndex` to the desired epoch index. ```typescript const ario = ARIO.mainnet(); const observers = await ario.getPrescribedObservers({ epochIndex: 0 }); ``` **Output:** ```json [ { "gatewayAddress": "BpQlyhREz4lNGS-y3rSS1WxADfxPpAuing9Lgfdrj2U", "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE", "stake": 10000000000, // value in mARIO "start": 1296976, "stakeWeight": 1, "tenureWeight": 0.41453703703703704, "gatewayPerformanceRatio": 1, "observerRewardRatioWeight": 1, "compositeWeight": 0.41453703703703704, "normalizedCompositeWeight": 0.0018972019546783507 } ] ``` # Gateways (/(ario-contract)/gateways) #### getGateway() Retrieves a gateway's info by its staking wallet address. ```typescript const ario = ARIO.mainnet(); const gateway = await ario.getGateway({ address: '-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck', }); ``` **Output:** ```json { "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, "gatewayPerformanceRatio": 1, "tenureWeight": 0.19444444444444, "observerRewardRatioWeight": 1, "normalizedCompositeWeight": 0.19247316211083, "stakeWeight": 5.02400000024 } } ``` #### getGateways() 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. ```typescript const ario = ARIO.mainnet(); const gateways = await ario.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:** ```json { "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, "gatewayPerformanceRatio": 1, "tenureWeight": 0.19444444444444, "observerRewardRatioWeight": 1, "normalizedCompositeWeight": 0.19247316211083, "stakeWeight": 5.02400000024 } } ], "hasMore": true, "nextCursor": "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA", "totalItems": 316, "sortBy": "operatorStake", "sortOrder": "desc" } ``` #### getGatewayDelegates() Retrieves all delegates for a specific gateway, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last delegate address from the previous request. ```typescript const ario = ARIO.mainnet(); const delegates = await ario.getGatewayDelegates({ address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', limit: 3, sortBy: 'startTimestamp', sortOrder: 'desc', }); ``` **Output:** ```json { "nextCursor": "ScEtph9-vfY7lgqlUWwUwOmm99ySeZGQhOX0MFAyFEs", "limit": 3, "sortBy": "startTimestamp", "totalItems": 32, "sortOrder": "desc", "hasMore": true, "items": [ { "delegatedStake": 600000000, "address": "qD5VLaMYyIHlT6vH59TgYIs6g3EFlVjlPqljo6kqVxk", "startTimestamp": 1732716956301 }, { "delegatedStake": 508999038, "address": "KG8TlcWk-8pvroCjiLD2J5zkG9rqC6yYaBuZNqHEyY4", "startTimestamp": 1731828123742 }, { "delegatedStake": 510926479, "address": "ScEtph9-vfY7lgqlUWwUwOmm99ySeZGQhOX0MFAyFEs", "startTimestamp": 1731689356040 } ] } ``` #### joinNetwork() 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._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.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 `ARIO.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 `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.leaveNetwork( // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### updateGatewaySettings() Writes new gateway settings to the callers gateway configuration. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ 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() Increases the callers stake on the target gateway. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.increaseDelegateStake( { target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', qty: new ARIOToken(100).toMARIO(), }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### decreaseDelegateStake() Decreases the callers stake on the target gateway. Can instantly decrease stake by setting instant to `true`. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ 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' }], }, ); ``` Pay the early withdrawal fee and withdraw instantly. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.decreaseDelegateStake({ target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', qty: new ARIOToken(100).toMARIO(), instant: true, // Immediately withdraw this stake and pay the instant withdrawal fee }); ``` #### getDelegations() 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 delgation) from the previous request. ```typescript const ario = ARIO.mainnet(); const vaults = await ario.getDelegations({ address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', cursor: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_123456789', limit: 2, sortBy: 'startTimestamp', sortOrder: 'asc', }); ``` **Output:** ```json { "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() 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._ ```typescript const ario = ARIO.mainnet({ 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() 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 `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ 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() Retrieves all allowed delegates for a specific address. The `cursor` used for pagination is the last address from the previous request. ```typescript const ario = ARIO.mainnet(); const allowedDelegates = await ario.getAllowedDelegates({ address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": false, "totalItems": 4, "limit": 100, "items": [ "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM", "N4h8M9A9hasa3tF47qQyNvcKjm4APBKuFs7vqUVm-SI", "JcC4ZLUY76vmWha5y6RwKsFqYTrMZhbockl8iM9p5lQ", "31LPFYoow2G7j-eSSsrIh8OlNaARZ84-80J-8ba68d8" ] } ``` #### getGatewayVaults() Retrieves all vaults across 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. ```typescript const ario = ARIO.mainnet(); const vaults = await ario.getGatewayVaults({ address: '"PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM', }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": false, "totalItems": 1, "limit": 100, "sortBy": "endTimestamp", "items": [ { "cursorId": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM_1728067635857", "startTimestamp": 1728067635857, "balance": 50000000000, "vaultId": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM", "endTimestamp": 1735843635857 } ] } ``` #### getAllGatewayVaults() Retrieves all vaults across all gateways, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last vaultId from the previous request. ```typescript const ario = ARIO.mainnet(); const vaults = await ario.getAllGatewayVaults({ limit: 1, sortBy: 'endTimestamp', sortOrder: 'desc', }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": true, "totalItems": 95, "limit": 1, "sortBy": "endTimestamp", "items": [ { "cursorId": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM_E-QVU3dta36Wia2uQw6tQLjQk7Qw5uN0Z6fUzsoqzUc", "gatewayAddress": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM", "startTimestamp": 1728067635857, "balance": 50000000000, "vaultId": "E-QVU3dta36Wia2uQw6tQLjQk7Qw5uN0Z6fUzsoqzUc", "endTimestamp": 1735843635857 } ], "nextCursor": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM_E-QVU3dta36Wia2uQw6tQLjQk7Qw5uN0Z6fUzsoqzUc" } ``` #### increaseOperatorStake() Increases the callers 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._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.increaseOperatorStake( { qty: new ARIOToken(100).toMARIO(), }, { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }], }, ); ``` #### decreaseOperatorStake() Decreases the callers operator stake. Must be executed with a wallet registered as a gateway operator. Requires `signer` to be provided on `ARIO.init` to sign the transaction. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.decreaseOperatorStake( { qty: new ARIOToken(100).toMARIO(), }, { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }], }, ); ``` #### redelegateStake() 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. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.redelegateStake({ target: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', source: 'HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA', stakeQty: new ARIOToken(1000).toMARIO(), vaultId: 'fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3', }); ``` #### getRedelegationFee() 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. ```typescript const ario = ARIO.mainnet(); const fee = await ario.getRedelegationFee({ address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', }); ``` **Output:** ```json { "redelegationFeeRate": 10, "feeResetTimestamp": 1730996691117 } ``` #### getAllDelegates() Retrieves all delegates across all gateways, paginated and sorted by the specified criteria. The `cursor` used for pagination is a `cursorId` derived from delegate address and the gatewayAddress from the previous request. e.g `address_gatewayAddress`. ```typescript const ario = ARIO.mainnet(); const delegates = await ario.getAllDelegates({ limit: 2, sortBy: 'startTimestamp', sortOrder: 'desc', }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": true, "totalItems": 95, "limit": 2, "sortBy": "startTimestamp", "items": [ { "startTimestamp": 1734709397622, "cursorId": "9jfM0uzGNc9Mkhjo1ixGoqM7ygSem9wx_EokiVgi0Bs_E-QVU3dta36Wia2uQw6tQLjQk7Qw5uN0Z6fUzsoqzUc", "gatewayAddress": "E-QVU3dta36Wia2uQw6tQLjQk7Qw5uN0Z6fUzsoqzUc", "address": "9jfM0uzGNc9Mkhjo1ixGoqM7ygSem9wx_EokiVgi0Bs", "delegatedStake": 2521349108, "vaultedStake": 0 }, { "startTimestamp": 1734593229454, "cursorId": "LtV0aSqgK3YI7c5FmfvZd-wG95TJ9sezj_a4syaLMS8_M0WP8KSzCvKpzC-HPF1WcddLgGaL9J4DGi76iMnhrN4", "gatewayAddress": "M0WP8KSzCvKpzC-HPF1WcddLgGaL9J4DGi76iMnhrN4", "address": "LtV0aSqgK3YI7c5FmfvZd-wG95TJ9sezj_a4syaLMS8", "delegatedStake": 1685148110, "vaultedStake": 10000000 } ], "nextCursor": "PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM_QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ" } ``` # General (/(ario-contract)/general) #### init() 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. ```typescript // 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. ```typescript const ario = ARIO.mainnet(); const info = await ario.getInfo(); ``` **Output:** ```json { "Name": "ARIO", "Ticker": "ARIO", "Owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ", "Denomination": 6, "Handlers": ["_eval", "_default_"], // full list of handlers, useful for debugging "LastCreatedEpochIndex": 31, // epoch index of the last tick "LastDistributedEpochIndex": 31 // epoch index of the last distribution } ``` #### 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. ```typescript const ario = ARIO.mainnet(); const supply = await ario.getTokenSupply(); ``` **Output:** ```json { "total": 1000000000000000000, "circulating": 998094653842520, "locked": 0, "withdrawn": 560563387278, "delegated": 1750000000, "staked": 1343032770199, "protocolBalance": 46317263683761 } ``` #### getBalance() Retrieves the balance of the specified wallet address. ```typescript const ario = ARIO.mainnet(); // 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:** ```json 100000 ``` #### getBalances() 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. ```typescript const ario = ARIO.mainnet(); const balances = await ario.getBalances({ cursor: '-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA', limit: 100, sortBy: 'balance', sortOrder: 'desc', }); ``` **Output:** ```json { "items": [ { "address": "-4xgjroXENKYhTWqrBo57HQwvDL51mMvSxJy6Y2Z_sA", "balance": 1000000 }, { "address": "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck", "balance": 1000000 } // ...98 other balances ], "hasMore": true, "nextCursor": "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck", "totalItems": 1789, "sortBy": "balance", "sortOrder": "desc" } ``` #### transfer() Transfers `mARIO` to the designated `target` recipient address. Requires `signer` to be provided on `ARIO.init` to sign the transaction. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ 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' }] }, ); ``` # Networks (/(ario-contract)/networks) The SDK provides the following process IDs for the mainnet and testnet environments: - `ARIO_MAINNET_PROCESS_ID` - Mainnet ARIO process ID (production) - `ARIO_TESTNET_PROCESS_ID` - Testnet ARIO process ID (testing and development) - `ARIO_DEVNET_PROCESS_ID` - Devnet ARIO process ID (development) As of `v3.8.1` the SDK defaults all API interactions to **mainnet**. To use the **testnet** or **devnet** provide the appropriate `ARIO_TESTNET_PROCESS_ID` or `ARIO_DEVNET_PROCESS_ID` when initializing the client. #### Mainnet As of `v3.8.1` the SDK defaults all API interactions to **mainnet**. To use the **testnet** or **devnet** provide the appropriate `ARIO_TESTNET_PROCESS_ID` or `ARIO_DEVNET_PROCESS_ID` when initializing the client. ```typescript const ario = ARIO.mainnet(); // or ARIO.init() ``` #### Testnet ```typescript const testnet = ARIO.testnet(); // or ARIO.init({ processId: ARIO_TESTNET_PROCESS_ID }) ``` ##### Faucet The SDK provides APIs for claiming tokens via a faucet on the AR.IO Testnet process (`tARIO`) via the [ar-io-testnet-faucet] service. All token requests require a captcha to be solved, and the faucet is rate limited to prevent abuse. To claim testnet tokens from the testnet token faucet, you can use one of the following methods: 1. Visit [faucet.ar.io](https://faucet.ar.io) - the easiest way to quickly get tokens for testing for a single address. 2. Programmatically via the SDK - useful if you need to claim tokens for multiple addresses or dynamically within your application. - `ARIO.testnet().faucet.captchaUrl()` - returns the captcha URL for the testnet faucet. Open this URL in a new browser window and listen for the `ario-jwt-success` event to be emitted. - `ARIO.testnet().faucet.claimWithAuthToken({ authToken, recipient, quantity })` - claims tokens for the specified recipient address using the provided auth token. - `ARIO.testnet().faucet.verifyAuthToken({ authToken })` - verifies if the provided auth token is still valid. Example client-side code for claiming tokens ```typescript const testnet = ARIO.testnet(); const captchaUrl = await ario.faucet.captchaUrl(); // open the captcha URL in the browser, and listen for the auth token event const captchaWindow = window.open( captchaUrl.captchaUrl, '_blank', 'width=600,height=600', ); /** * The captcha URL includes a window.parent.postMessage event that is used to send the auth token to the parent window. * You can store the auth token in localStorage and use it to claim tokens for the duration of the auth token's expiration (default 1 hour). */ window.parent.addEventListener('message', async (event) => { if (event.data.type === 'ario-jwt-success') { localStorage.setItem('ario-jwt', event.data.token); localStorage.setItem('ario-jwt-expires-at', event.data.expiresAt); // close our captcha window captchaWindow?.close(); // claim the tokens using the JWT token const res = await testnet.faucet .claimWithAuthToken({ authToken: event.data.token, recipient: await window.arweaveWallet.getActiveAddress(), quantity: new ARIOToken(100).toMARIO().valueOf(), // 100 ARIO }) .then((res) => { alert( 'Successfully claimed 100 ARIO tokens! Transaction ID: ' + res.id, ); }) .catch((err) => { alert(`Failed to claim tokens: ${err}`); }); } }); /** * Once you have a valid JWT, you can check if it is still valid and use it for subsequent requests without having to open the captcha again. */ if ( localStorage.getItem('ario-jwt-expires-at') && Date.now() # Primary Names (/(ario-contract)/primary-names) #### getPrimaryNames() Retrieves all primary names paginated and sorted by the specified criteria. The `cursor` used for pagination is the last name from the previous request. ```typescript const ario = ARIO.mainnet(); const names = await ario.getPrimaryNames({ cursor: 'ao', // this is the last name from the previous request limit: 1, sortBy: 'startTimestamp', sortOrder: 'desc', }); ``` **Output:** ```json { "sortOrder": "desc", "hasMore": true, "totalItems": 100, "limit": 1, "sortBy": "startTimestamp", "cursor": "arns", "items": [ { "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA", "startTimestamp": 1719356032297, "name": "arns" } ] } ``` #### getPrimaryName() Retrieves the primary name for a given name or address. ```typescript const ario = ARIO.mainnet(); const name = await ario.getPrimaryName({ name: 'arns', }); // or const name = await ario.getPrimaryName({ address: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', }); ``` **Output:** ```json { "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA", "startTimestamp": 1719356032297, "name": "arns" } ``` #### setPrimaryName() Sets an ArNS name already owned by the `signer` as their primary name. Note: `signer` must be the owner of the `processId` that is assigned to the name. If not, the transaction will fail. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const signer = new ArweaveSigner(jwk); const ario = ARIO.mainnet({ signer }); await ario.setPrimaryName({ name: 'my-arns-name' }); // the caller must already have purchased the name my-arns-name and be assigned as the owner of the processId that is assigned to the name ``` #### requestPrimaryName() Requests a primary name for the `signer`'s address. The request must be approved by the new owner of the requested name via the `approvePrimaryNameRequest`[#approveprimarynamerequest-name-address-] API. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.requestPrimaryName({ name: 'arns', }); ``` #### getPrimaryNameRequest() Retrieves the primary name request for a a wallet address. ```typescript const ario = ARIO.mainnet(); const request = await ario.getPrimaryNameRequest({ initiator: 't4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3', }); ``` **Output:** ```json { "initiator": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3", "name": "arns", "startTimestamp": 1728067635857, "endTimestamp": 1735843635857 } ``` # Vaults (/(ario-contract)/vaults) #### getVault() Retrieves the locked-balance user vault of the ARIO process by the specified wallet address and vault ID. ```typescript const ario = ARIO.mainnet(); const vault = await ario.getVault({ address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', vaultId: 'vaultIdOne', }); ``` **Output:** ```json { "balance": 1000000, "startTimestamp": 123, "endTimestamp": 4567 } ``` #### getVaults() Retrieves all locked-balance user vaults of the ARIO process, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last wallet address from the previous request. ```typescript const ario = ARIO.mainnet(); const vaults = await ario.getVaults({ cursor: '0', limit: 100, sortBy: 'balance', sortOrder: 'desc', }); ``` **Output:** ```json { "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" } ``` #### vaultedTransfer() Transfers `mARIO` to the designated `recipient` address and locks the balance for the specified `lockLengthMs` milliseconds. The `revokable` flag determines if the vaulted transfer can be revoked by the sender. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.vaultedTransfer( { recipient: '-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5', quantity: new ARIOToken(1000).toMARIO(), lockLengthMs: 1000 * 60 * 60 * 24 * 365, // 1 year revokable: true, }, // optional additional tags { tags: [{ name: 'App-Name', value: 'My-Awesome-App' }] }, ); ``` #### revokeVault() Revokes a vaulted transfer by the recipient address and vault ID. Only the sender of the vaulted transfer can revoke it. _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._ ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.revokeVault({ recipient: '-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5', vaultId: 'IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs', }); ``` #### createVault() Creates a vault for the specified `quantity` of mARIO from the signer's balance and locks it for the specified `lockLengthMs` milliseconds. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.createVault({ lockLengthMs: 1000 * 60 * 60 * 24 * 365, // 1 year quantity: new ARIOToken(1000).toMARIO(), }); ``` #### extendVault() Extends the lock length of a signer's vault by the specified `extendLengthMs` milliseconds. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.extendVault({ vaultId: 'vaultIdOne', extendLengthMs: 1000 * 60 * 60 * 24 * 365, // 1 year }); ``` #### increaseVault() Increases the balance of a signer's vault by the specified `quantity` of mARIO. ```typescript const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) }); const { id: txId } = await ario.increaseVault({ vaultId: 'vaultIdOne', quantity: new ARIOToken(1000).toMARIO(), }); ``` # AR.IO SDK (/index) **For AI and LLM users**: Access the complete AR.IO SDK documentation in plain text format at llm.txt for easy consumption by AI agents and language models. # AR.IO SDK Please refer to the [source code](https://github.com/ar-io/ar-io-sdk) for SDK details. # Logging (/logging) The library uses a lightweight console logger by default for both Node.js and web environments. The logger outputs structured JSON logs with timestamps. You can configure the log level via `setLogLevel()` API or provide a custom logger that satisfies the `ILogger` interface. #### Default Logger ```typescript // set the log level Logger.default.setLogLevel('debug'); // Create a new logger instance with a specific level const logger = new Logger({ level: 'debug' }); ``` #### Custom Logger Implementation You can provide any custom logger that implements the `ILogger` interface: ```typescript // Custom logger example const customLogger: ILogger = { info: (message, ...args) => console.log(`[INFO] ${message}`, ...args), warn: (message, ...args) => console.warn(`[WARN] ${message}`, ...args), error: (message, ...args) => console.error(`[ERROR] ${message}`, ...args), debug: (message, ...args) => console.debug(`[DEBUG] ${message}`, ...args), setLogLevel: (level) => { /* implement level filtering */ }, }; // Use custom logger with any class const ario = ARIO.mainnet({ logger: customLogger }); // or set it as the default logger in the entire SDK Logger.default = customLogger; ``` #### Winston Logger (Optional) For advanced logging features, you can optionally install Winston and use the provided Winston logger adapter: ```bash yarn add winston ``` ```typescript // Create Winston logger with custom configuration const winstonLogger = new WinstonLogger({ level: 'debug', }); // Use with any class that accepts a logger const ario = ARIO.mainnet({ logger: winstonLogger }); // or set it as the default logger in the entire SDK Logger.default = winstonLogger; ``` #### Other Popular Loggers You can easily integrate other popular logging libraries: ```typescript // Bunyan example const bunyanLogger = bunyan.createLogger({ name: 'ar-io-sdk' }); const adapter: ILogger = { info: (message, ...args) => bunyanLogger.info({ args }, message), warn: (message, ...args) => bunyanLogger.warn({ args }, message), error: (message, ...args) => bunyanLogger.error({ args }, message), debug: (message, ...args) => bunyanLogger.debug({ args }, message), setLogLevel: (level) => bunyanLogger.level(level), }; const ario = ARIO.mainnet({ logger: adapter }); // or set it as the default logger in the entire SDK Logger.default = adapter; ``` # Pagination (/pagination) #### Overview 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](https://www.getknit.dev/blog/api-pagination-best-practices#api-pagination-techniques-). 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`. ```typescript let hasMore = true; let cursor: string | undefined; const gateaways = []; while (hasMore) { const page = await ario.getGateways({ limit: 100, cursor }); gateaways.push(...items); cursor = page.nextCursor; hasMore = page.hasMore; } ``` #### Filtering Paginated APIs also support filtering by providing a `filters` parameter. Filters can be applied to any field in the response. When multiple keys are provided, they are treated as AND conditions (all conditions must match). When multiple values are provided for a single key (as an array), they are treated as OR conditions (any value can match). Example: ```typescript const records = await ario.getArNSRecords({ filters: { type: 'lease', processId: [ 'ZkgLfyHALs5koxzojpcsEFAKA8fbpzP7l-tbM7wmQNM', 'r61rbOjyXx3u644nGl9bkwLWlWmArMEzQgxBo2R-Vu0', ], }, }); ``` In the example above, the query will return ArNS records where: - The type is "lease" AND - The processId is EITHER "ZkgLfyHALs5koxzojpcsEFAKA8fbpzP7l-tbM7wmQNM" OR "r61rbOjyXx3u644nGl9bkwLWlWmArMEzQgxBo2R-Vu0" # Token Conversion (/token-conversion) The ARIO process stores all values as mARIO (milli-ARIO) to avoid floating-point arithmetic issues. The SDK provides an `ARIOToken` and `mARIOToken` classes to handle the conversion between ARIO and mARIO, along with rounding logic for precision. **All process interactions expect values in mARIO. If numbers are provided as inputs, they are assumed to be in raw mARIO values.** #### Converting ARIO to mARIO ```typescript const arioValue = 1; const mARIOValue = new ARIOToken(arioValue).toMARIO(); const mARIOValue = 1_000_000; const arioValue = new mARIOToken(mARIOValue).toARIO(); ```