diff --git a/README.md b/README.md index d4b389db..fb1834ed 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,9 @@ This is the home of [ar.io] SDK. This SDK provides functionality for interacting - [`getGateways({ cursor, limit, sortBy, sortOrder })`](#getgateways-cursor-limit-sortby-sortorder-) - [`getArNSRecord({ name })`](#getarnsrecord-name-) - [`getArNSRecords({ cursor, limit, sortBy, sortOrder })`](#getarnsrecords-cursor-limit-sortby-sortorder-) + - [`getAuctions({ cursor, limit, sortBy, sortOrder })`](#getauctions-cursor-limit-sortby-sortorder-) + - [`getAuction({ name })`](#getauction-name-) + - [`getAuctionPrices({ name, type, years, intervalMs })`](#getauctionprices-name-type-years-intervalms-) - [`getDemandFactor()`](#getdemandfactor) - [`getObservations({ epochIndex })`](#getobservations-epochindex-) - [`getDistributions({ epochIndex })`](#getdistributions-epochindex-) @@ -69,6 +72,7 @@ This is the home of [ar.io] SDK. This SDK provides functionality for interacting - [`removeRecord({ undername })`](#removerecord-undername-) - [`setName({ name })`](#setname-name-) - [`setTicker({ ticker })`](#setticker-ticker-) + - [`releaseName({ name, ioProcessId })`](#releasename-name-ioprocessid-) - [Configuration](#configuration-1) - [Logging](#logging) - [Configuration](#configuration-2) @@ -598,6 +602,136 @@ Available `sortBy` options are any of the keys on the record object, e.g. `name` +#### `getAuctions({ cursor, limit, sortBy, sortOrder })` + +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. + +```typescript +const io = IO.init(); +const auctions = await io.getAuctions({ + limit: 100, + sortBy: 'endTimestamp', + sortOrder: 'asc', // return the auctions 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" +} +``` + +
+ +#### `getAuction({ name })` + +Retrieves the auction data for the specified auction name. + +```typescript +const io = IO.init(); +const auction = await io.getAuction({ 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 + } +} +``` + +
+ +#### `getAuctionPrices({ name, type, years, intervalMs })` + +Retrieves the auction price curve of the specified auction name for the specified type, duration, and interval. The `intervalMs` is the number of milliseconds between price points on the curve. The default interval is 15 minutes. + +```typescript +const io = IO.init(); +const priceCurve = await io.getAuctionPrices({ + name: 'permalink', + type: 'lease', + years: 1, + intervalMs: 3600000, // 1 hour price intervals (default is 15 minutes) +}); +``` + +
+ Output + +```json +{ + "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 + // ... + } +} +``` + +
+ #### `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. @@ -1413,6 +1547,19 @@ const { id: txId } = await ant.setTicker( ); ``` +#### `releaseName({ name, ioProcessId })` + +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._ + +```typescript +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 +}); +``` + ### Configuration 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. diff --git a/examples/esm/index.mjs b/examples/esm/index.mjs index 7d6eead8..347b3c6f 100644 --- a/examples/esm/index.mjs +++ b/examples/esm/index.mjs @@ -20,7 +20,7 @@ import { const distributions = await arIO.getDistributions({ epochIndex: 0 }); const buyRecordCost = await arIO.getTokenCost({ intent: 'Buy-Record', - purchaseType: 'lease', + type: 'lease', name: 'ar-io-dapp-record', years: 1, }); diff --git a/examples/vite/package.json b/examples/vite/package.json index b1422ca0..0d8cb871 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -7,6 +7,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^9.0.1", + "recharts": "^2.13.0", "remark-gfm": "^4.0.0" }, "devDependencies": { diff --git a/examples/vite/src/App.css b/examples/vite/src/App.css index d99bf119..ed6a79d2 100644 --- a/examples/vite/src/App.css +++ b/examples/vite/src/App.css @@ -1,6 +1,6 @@ .App { text-align: center; - background-color: #282c34; + background-color: #f0f0f0; } .markdown { diff --git a/examples/vite/src/App.tsx b/examples/vite/src/App.tsx index 0139d109..f78c834b 100644 --- a/examples/vite/src/App.tsx +++ b/examples/vite/src/App.tsx @@ -1,33 +1,98 @@ -import { ANT, ANTState } from '@ar.io/sdk/web'; +import { + AoAuction, + AoAuctionPriceData, + IO, + IO_DEVNET_PROCESS_ID, + PaginationResult, +} from '@ar.io/sdk/web'; import { useEffect, useState } from 'react'; -import Markdown from 'react-markdown'; -import remarkGfm from 'remark-gfm'; +import { + Label, + Line, + LineChart, + ReferenceLine, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; import './App.css'; -const contractTxId = 'ilwT4ObFQ7cGPbW-8z-h7mvvWGt_yhWNlqxNjSUgiYY'; -const antContract = ANT.init({ contractTxId, strict: true }); +const io = IO.init({ processId: IO_DEVNET_PROCESS_ID }); + +type AuctionWithPrices = AoAuction & { + prices: { timestamp: string; price: number }[]; + currentPrice: number; +}; function App() { - const [contract, setContract] = useState('Loading...'); + const [auctions, setAuctions] = useState([]); useEffect(() => { - antContract - .getState() - .then((state: ANTState) => { - setContract(`\`\`\`json\n${JSON.stringify(state, null, 2)}`); - }) - .catch((error: unknown) => { - console.error(error); - setContract('Error loading contract state'); + io.getAuctions().then((page: PaginationResult) => { + page.items.forEach((auction: AoAuction) => { + io.getAuctionPrices({ + name: auction.name, + type: 'lease', + intervalMs: 1000 * 60 * 60 * 24, // 1 day + }).then((price: AoAuctionPriceData) => { + const arrayOfPrices = Object.entries(price.prices) + .sort(([timestampA], [timestampB]) => +timestampA - +timestampB) + .map(([timestamp, price]) => ({ + timestamp: new Date(+timestamp).toLocaleString('en-US', { + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + hour12: false, + }), + price: price / 10 ** 6, + })); + const auctionWithPrices = { + ...auction, + prices: arrayOfPrices, + currentPrice: price.currentPrice / 10 ** 6, + }; + setAuctions((prev) => [...prev, auctionWithPrices]); + }); }); + }); }, []); return ( -
- - {contract} - +
+ {auctions.length > 0 && ( + + + + + + + + + + + + + )}
); } diff --git a/examples/vite/src/index.css b/examples/vite/src/index.css index e8c77d29..20d9a81b 100644 --- a/examples/vite/src/index.css +++ b/examples/vite/src/index.css @@ -5,7 +5,7 @@ body { sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - background-color: #282c34; + background-color: #f0f0f0; } code { diff --git a/examples/vite/yarn.lock b/examples/vite/yarn.lock index 8b1eaf2a..9f213319 100644 --- a/examples/vite/yarn.lock +++ b/examples/vite/yarn.lock @@ -199,6 +199,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.9.tgz#65884fd6dc255a775402cc1d9811082918f4bf00" + integrity sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" @@ -952,6 +959,57 @@ dependencies: "@babel/types" "^7.20.7" +"@types/d3-array@^3.0.3": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-ease@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-interpolate@^3.0.1": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.0.tgz#2b907adce762a78e98828f0b438eaca339ae410a" + integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ== + +"@types/d3-scale@^4.0.2": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb" + integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== + dependencies: + "@types/d3-time" "*" + +"@types/d3-shape@^3.1.0": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72" + integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time@*", "@types/d3-time@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be" + integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== + +"@types/d3-timer@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + "@types/debug@^4.0.0": version "4.1.12" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" @@ -1738,6 +1796,11 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clsx@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1933,6 +1996,77 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: + version "3.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +"d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-ease@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +"d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +d3-shape@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +"d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +d3-timer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + debug@^4.0.0, debug@^4.1.0, debug@^4.3.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -1940,6 +2074,11 @@ debug@^4.0.0, debug@^4.1.0, debug@^4.3.1: dependencies: ms "2.1.2" +decimal.js-light@^2.4.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" @@ -2038,6 +2177,14 @@ dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== +dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + dom-serializer@^1.0.1: version "1.4.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" @@ -2234,6 +2381,11 @@ estree-walker@^2.0.1, estree-walker@^2.0.2: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== +eventemitter3@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + events@3.3.0, events@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -2273,6 +2425,11 @@ fast-copy@^3.0.0: resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.2.tgz#59c68f59ccbcac82050ba992e0d5c389097c9d35" integrity sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ== +fast-equals@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d" + integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== + fast-glob@^3.2.11: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -2614,6 +2771,11 @@ internal-slot@^1.0.4: hasown "^2.0.0" side-channel "^1.0.4" +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + is-alphabetical@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" @@ -3021,7 +3183,7 @@ lodash.union@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== -lodash@^4.17.15: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3031,7 +3193,7 @@ longest-streak@^3.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -loose-envify@^1.1.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -3754,6 +3916,11 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" @@ -3950,6 +4117,15 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +prop-types@^15.6.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + property-information@^6.0.0: version "6.5.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec" @@ -4017,12 +4193,17 @@ react-dom@^18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0: +react-is@^18.0.0, react-is@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== @@ -4048,6 +4229,25 @@ react-refresh@^0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== +react-smooth@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.1.tgz#6200d8699bfe051ae40ba187988323b1449eab1a" + integrity sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w== + dependencies: + fast-equals "^5.0.1" + prop-types "^15.8.1" + react-transition-group "^4.4.5" + +react-transition-group@^4.4.5: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" @@ -4084,6 +4284,27 @@ readdir-glob@^1.1.2: dependencies: minimatch "^5.1.0" +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + +recharts@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.13.0.tgz#a293322ea357491393cc7ad6fcbb1e5f8e99bc93" + integrity sha512-sbfxjWQ+oLWSZEWmvbq/DFVdeRLqqA6d0CDjKx2PkxVVdoXo16jvENCE+u/x7HxOO+/fwx//nYRwb8p8X6s/lQ== + dependencies: + clsx "^2.0.0" + eventemitter3 "^4.0.1" + lodash "^4.17.21" + react-is "^18.3.1" + react-smooth "^4.0.0" + recharts-scale "^0.4.4" + tiny-invariant "^1.3.1" + victory-vendor "^36.6.8" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -4471,6 +4692,11 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-invariant@^1.3.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + tmp-promise@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -4667,6 +4893,26 @@ vfile@^6.0.0: unist-util-stringify-position "^4.0.0" vfile-message "^4.0.0" +victory-vendor@^36.6.8: + version "36.9.2" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.9.2.tgz#668b02a448fa4ea0f788dbf4228b7e64669ff801" + integrity sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ== + dependencies: + "@types/d3-array" "^3.0.3" + "@types/d3-ease" "^3.0.0" + "@types/d3-interpolate" "^3.0.1" + "@types/d3-scale" "^4.0.2" + "@types/d3-shape" "^3.1.0" + "@types/d3-time" "^3.0.0" + "@types/d3-timer" "^3.0.0" + d3-array "^3.1.6" + d3-ease "^3.0.1" + d3-interpolate "^3.0.1" + d3-scale "^4.0.2" + d3-shape "^3.1.0" + d3-time "^3.0.0" + d3-timer "^3.0.1" + vite-plugin-html@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/vite-plugin-html/-/vite-plugin-html-3.2.2.tgz#661834fa09015d3fda48ba694dbaa809396f5f7a" diff --git a/package.json b/package.json index 6ab3e813..6bc6302b 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "test:link": "yarn build && yarn link", "test:e2e": "yarn test:cjs && yarn test:esm && yarn test:web", "prepare": "husky install", + "docs:update": "markdown-toc-gen insert README.md", "example:esm": "cd examples/esm && yarn && node index.mjs", "example:cjs": "yarn test:link && cd examples/cjs && yarn && node index.cjs", "example:web": "yarn test:link && build:web && http-server --port 8080 --host -o examples/web" diff --git a/src/common/ant.ts b/src/common/ant.ts index ad865272..673a5643 100644 --- a/src/common/ant.ts +++ b/src/common/ant.ts @@ -457,7 +457,7 @@ export class AoANTWriteable extends AoANTReadable implements AoANTWrite { * @returns {Promise} The result of the interaction. * @example * ```ts - * ant.setName({ name: "ships at sea" }); + * ant.setName({ name: "test" }); // results in the resolution of `test_.ar.io` * ``` */ async setName( @@ -473,4 +473,28 @@ export class AoANTWriteable extends AoANTReadable implements AoANTWrite { signer: this.signer, }); } + + /** + * @param name @type {string} The name you want to release. The name will be put up for auction on the IO contract. 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. + * @param ioProcessId @type {string} The processId of the IO contract. This is where the ANT will send the message to release the name. + * @returns {Promise} The result of the interaction. + * @example + * ```ts + * ant.releaseName({ name: "ardrive", ioProcessId: IO_TESTNET_PROCESS_ID }); + * ``` + */ + async releaseName( + { name, ioProcessId }: { name: string; ioProcessId: string }, + options?: WriteOptions, + ): Promise { + return this.process.send({ + tags: [ + ...(options?.tags ?? []), + { name: 'Action', value: 'Release-Name' }, + { name: 'Name', value: name }, + { name: 'IO-Process-Id', value: ioProcessId }, + ], + signer: this.signer, + }); + } } diff --git a/src/common/io.ts b/src/common/io.ts index 398f552e..f24a4842 100644 --- a/src/common/io.ts +++ b/src/common/io.ts @@ -19,6 +19,7 @@ import { IO_TESTNET_PROCESS_ID } from '../constants.js'; import { AoArNSNameDataWithName, AoArNSReservedNameData, + AoAuction, AoBalanceWithAddress, AoEpochDistributionData, AoEpochObservationData, @@ -40,6 +41,7 @@ import { } from '../types/index.js'; import { AoArNSNameData, + AoAuctionPriceData, AoEpochData, AoEpochSettings, AoGateway, @@ -503,7 +505,7 @@ export class IOReadable implements AoIORead { async getTokenCost(params: { intent: 'Buy-Record'; - purchaseType: 'permabuy' | 'lease'; + type: 'permabuy' | 'lease'; years: number; name: string; }): Promise; @@ -519,13 +521,13 @@ export class IOReadable implements AoIORead { }): Promise; async getTokenCost({ intent, - purchaseType, + type, years, name, quantity, }: { intent: 'Buy-Record' | 'Extend-Lease' | 'Increase-Undername-Limit'; - purchaseType?: 'permabuy' | 'lease'; + type?: 'permabuy' | 'lease'; years?: number; name?: string; quantity?: number; @@ -550,7 +552,7 @@ export class IOReadable implements AoIORead { }, { name: 'Purchase-Type', - value: purchaseType, + value: type, }, { name: 'Timestamp', @@ -590,6 +592,93 @@ export class IOReadable implements AoIORead { tags: [{ name: 'Action', value: 'Demand-Factor' }], }); } + + // Auctions + async getAuctions( + params?: PaginationParams, + ): Promise> { + const allTags = [ + { name: 'Action', value: 'Auctions' }, + { name: 'Cursor', value: params?.cursor?.toString() }, + { name: 'Limit', value: params?.limit?.toString() }, + { name: 'Sort-By', value: params?.sortBy }, + { name: 'Sort-Order', value: params?.sortOrder }, + ]; + + const prunedTags: { name: string; value: string }[] = allTags.filter( + (tag: { + name: string; + value: string | undefined; + }): tag is { name: string; value: string } => tag.value !== undefined, + ); + + return this.process.read>({ + tags: prunedTags, + }); + } + + async getAuction({ name }: { name: string }): Promise { + const allTags = [ + { name: 'Action', value: 'Auction-Info' }, + { name: 'Name', value: name }, + ]; + + return this.process.read({ + tags: allTags, + }); + } + + /** + * Get auction prices for a given auction at the provided intervals + * + * @param {Object} params - The parameters for fetching auction prices + * @param {string} params.name - The name of the auction + * @param {('permabuy'|'lease')} [params.type='lease'] - The type of purchase + * @param {number} [params.years=1] - The number of years for lease (only applicable if type is 'lease') + * @param {number} [params.timestamp=Date.now()] - The timestamp to fetch prices for + * @param {number} [params.intervalMs=900000] - The interval in milliseconds between price points (default is 15 minutes) + * @returns {Promise} The auction price data + */ + async getAuctionPrices({ + name, + type, + years, + timestamp, + intervalMs, + }: { + name: string; + type?: 'permabuy' | 'lease'; + years?: number; + timestamp?: number; + intervalMs?: number; + }): Promise { + const prunedPriceTags: { name: string; value: string }[] = [ + { name: 'Action', value: 'Auction-Prices' }, + { name: 'Name', value: name }, + { + name: 'Timestamp', + value: timestamp?.toString() ?? Date.now().toString(), + }, + { name: 'Purchase-Type', value: type ?? 'lease' }, + { + name: 'Years', + value: + type == undefined || type === 'lease' + ? years?.toString() ?? '1' + : undefined, + }, + { + name: 'Price-Interval-Ms', + value: intervalMs?.toString() ?? '900000', + }, + ].filter( + (tag): tag is { name: string; value: string } => tag.value !== undefined, + ); + + return this.process.read({ + tags: prunedPriceTags, + }); + } } export class IOWriteable extends IOReadable implements AoIOWrite { @@ -1005,4 +1094,30 @@ export class IOWriteable extends IOReadable implements AoIOWrite { ], }); } + + async submitAuctionBid( + params: { name: string; processId: string; quantity?: number }, + options?: WriteOptions, + ): Promise { + const { tags = [] } = options || {}; + const allTags = [ + ...tags, + { name: 'Action', value: 'Submit-Auction-Bid' }, + { name: 'Name', value: params.name }, + { name: 'Process-Id', value: params.processId }, + { name: 'Quantity', value: params.quantity?.toString() ?? undefined }, + ]; + + const prunedTags: { name: string; value: string }[] = allTags.filter( + (tag: { + name: string; + value: string | undefined; + }): tag is { name: string; value: string } => tag.value !== undefined, + ); + + return this.process.send({ + signer: this.signer, + tags: prunedTags, + }); + } } diff --git a/src/types/ant.ts b/src/types/ant.ts index 27f82534..86a001c4 100644 --- a/src/types/ant.ts +++ b/src/types/ant.ts @@ -116,6 +116,7 @@ export const AntHandlerNames = [ 'setTicker', 'initializeState', 'state', + 'releaseName', ]; export const AntHandlersSchema = z .array(z.string({ description: 'Handler Name' })) @@ -226,4 +227,8 @@ export interface AoANTWrite extends AoANTRead { { name }: { name: string }, options?: WriteOptions, ): Promise; + releaseName( + { name, ioProcessId }: { name: string; ioProcessId: string }, + options?: WriteOptions, + ): Promise; } diff --git a/src/types/io.ts b/src/types/io.ts index 71f5e8be..136f604b 100644 --- a/src/types/io.ts +++ b/src/types/io.ts @@ -257,6 +257,31 @@ export type AoBalanceWithAddress = { balance: number; }; +// Auctions +export type AoAuctionSettings = { + durationMs: number; + decayRate: number; + scalingExponent: number; + startPriceMultiplier: number; +}; + +export type AoAuction = { + name: string; + startTimestamp: Timestamp; + endTimestamp: Timestamp; + initiator: string; + baseFee: number; + demandFactor: number; + settings: AoAuctionSettings; +}; + +export type AoAuctionPriceData = { + type: 'lease' | 'permabuy'; + years?: number; + prices: Record; + currentPrice: number; +}; + // Input types // TODO: confirm what is required or if all can be optional and defaults will be provided @@ -318,19 +343,34 @@ export interface AoIORead { getDistributions(epoch?: EpochInput): Promise; getTokenCost({ intent, - purchaseType, + type, years, name, quantity, }: { intent: 'Buy-Record' | 'Extend-Lease' | 'Increase-Undername-Limit'; - purchaseType?: 'permabuy' | 'lease'; + type?: 'permabuy' | 'lease'; years?: number; name?: string; quantity?: number; }): Promise; getRegistrationFees(): Promise; getDemandFactor(): Promise; + getAuctions(params?: PaginationParams): Promise>; + getAuction({ name }: { name: string }): Promise; + getAuctionPrices({ + name, + type, + years, + timestamp, + intervalMs, + }: { + name: string; + type: 'lease' | 'permabuy'; + years?: number; + timestamp?: number; + intervalMs?: number; + }): Promise; } export interface AoIOWrite extends AoIORead { @@ -450,6 +490,14 @@ export interface AoIOWrite extends AoIORead { }, options?: WriteOptions, ): Promise; + submitAuctionBid( + params: { + name: string; + processId: string; + quantity?: number; + }, + options?: WriteOptions, + ): Promise; } // Typeguard functions diff --git a/tests/e2e/cjs/index.test.js b/tests/e2e/cjs/index.test.js index 923cca7e..cc272fa3 100644 --- a/tests/e2e/cjs/index.test.js +++ b/tests/e2e/cjs/index.test.js @@ -41,344 +41,346 @@ const io = IO.init({ }), }); -describe('IO', async () => { - let compose; - before(async () => { - compose = await new DockerComposeEnvironment( - projectRootPath, - '../docker-compose.test.yml', - ) - .withBuild() - .withWaitStrategy('ao-cu-1', Wait.forHttp('/', 6363)) - .up(['ao-cu']); - }); +describe('e2e cjs tests', async () => { + describe('IO', async () => { + let compose; + before(async () => { + compose = await new DockerComposeEnvironment( + projectRootPath, + '../docker-compose.test.yml', + ) + .withBuild() + .withWaitStrategy('ao-cu-1', Wait.forHttp('/', 6363)) + .up(['ao-cu']); + }); - after(async () => { - await compose.down(); - }); - it('should be able to get the process information', async () => { - const epoch = await io.getInfo(); - assert.ok(epoch); - }); + after(async () => { + await compose.down(); + }); + it('should be able to get the process information', async () => { + const epoch = await io.getInfo(); + assert.ok(epoch); + }); - it('should be able to get the total token supply', async () => { - const tokenSupply = await io.getTokenSupply(); - assert.ok(tokenSupply); - }); + it('should be able to get the total token supply', async () => { + const tokenSupply = await io.getTokenSupply(); + assert.ok(tokenSupply); + }); - it('should be able to get first set of arns records', async () => { - const records = await io.getArNSRecords(); - assert.ok(records); - assert(records.limit === 100); - assert(records.sortOrder === 'desc'); - assert(records.sortBy === 'startTimestamp'); - assert(typeof records.totalItems === 'number'); - assert(typeof records.sortBy === 'string'); - assert(typeof records.sortOrder === 'string'); - assert(typeof records.limit === 'number'); - assert(typeof records.hasMore === 'boolean'); - if (records.nextCursor) { - assert(typeof records.nextCursor === 'string'); - } - assert(Array.isArray(records.items)); - records.items.forEach((record) => { - assert(typeof record.processId === 'string'); - assert(typeof record.name === 'string'); - assert(typeof record.startTimestamp === 'number'); - assert(['lease', 'permabuy'].includes(record.type)); - assert(typeof record.undernameLimit === 'number'); + it('should be able to get first set of arns records', async () => { + const records = await io.getArNSRecords(); + assert.ok(records); + assert(records.limit === 100); + assert(records.sortOrder === 'desc'); + assert(records.sortBy === 'startTimestamp'); + assert(typeof records.totalItems === 'number'); + assert(typeof records.sortBy === 'string'); + assert(typeof records.sortOrder === 'string'); + assert(typeof records.limit === 'number'); + assert(typeof records.hasMore === 'boolean'); + if (records.nextCursor) { + assert(typeof records.nextCursor === 'string'); + } + assert(Array.isArray(records.items)); + records.items.forEach((record) => { + assert(typeof record.processId === 'string'); + assert(typeof record.name === 'string'); + assert(typeof record.startTimestamp === 'number'); + assert(['lease', 'permabuy'].includes(record.type)); + assert(typeof record.undernameLimit === 'number'); + }); }); - }); - it('should be able to return a specific page of arns records', async () => { - const records = await io.getArNSRecords({ - cursor: 'ardrive', - limit: 5, - sortOrder: 'desc', - sortBy: 'name', + it('should be able to return a specific page of arns records', async () => { + const records = await io.getArNSRecords({ + cursor: 'ardrive', + limit: 5, + sortOrder: 'desc', + sortBy: 'name', + }); + assert.ok(records); + assert(records.limit === 5); + assert(records.sortOrder === 'desc'); + assert(records.sortBy === 'name'); + assert(typeof records.totalItems === 'number'); + assert(typeof records.sortBy === 'string'); + assert(typeof records.sortOrder === 'string'); + assert(typeof records.limit === 'number'); + assert(typeof records.hasMore === 'boolean'); + if (records.nextCursor) { + assert(typeof records.nextCursor === 'string'); + } + assert(Array.isArray(records.items)); + records.items.forEach((record) => { + assert(typeof record.processId === 'string'); + assert(typeof record.name === 'string'); + assert(typeof record.startTimestamp === 'number'); + assert(['lease', 'permabuy'].includes(record.type)); + assert(typeof record.undernameLimit === 'number'); + }); }); - assert.ok(records); - assert(records.limit === 5); - assert(records.sortOrder === 'desc'); - assert(records.sortBy === 'name'); - assert(typeof records.totalItems === 'number'); - assert(typeof records.sortBy === 'string'); - assert(typeof records.sortOrder === 'string'); - assert(typeof records.limit === 'number'); - assert(typeof records.hasMore === 'boolean'); - if (records.nextCursor) { - assert(typeof records.nextCursor === 'string'); - } - assert(Array.isArray(records.items)); - records.items.forEach((record) => { - assert(typeof record.processId === 'string'); - assert(typeof record.name === 'string'); - assert(typeof record.startTimestamp === 'number'); - assert(['lease', 'permabuy'].includes(record.type)); - assert(typeof record.undernameLimit === 'number'); + it('should be able to get a single arns record', async () => { + const arns = await io.getArNSRecord({ name: 'ardrive' }); + assert.ok(arns); }); - }); - it('should be able to get a single arns record', async () => { - const arns = await io.getArNSRecord({ name: 'ardrive' }); - assert.ok(arns); - }); - - it('should be able to get the current epoch using getCurrentEpoch', async () => { - const epoch = await io.getCurrentEpoch(); - assert.ok(epoch); - }); - - it('should be able to get the current epoch using getEpoch', async () => { - const epoch = await io.getEpoch({ epochIndex: 0 }); - assert.ok(epoch); - }); - it('should be able to get epoch-settings', async () => { - const epochSettings = await io.getEpochSettings(); - assert.ok(epochSettings); - }); + it('should be able to get the current epoch using getCurrentEpoch', async () => { + const epoch = await io.getCurrentEpoch(); + assert.ok(epoch); + }); - it('should be able to get reserved names', async () => { - const reservedNames = await io.getArNSReservedNames(); - assert.ok(reservedNames); - }); + it('should be able to get the current epoch using getEpoch', async () => { + const epoch = await io.getEpoch({ epochIndex: 0 }); + assert.ok(epoch); + }); - it('should be able to get a single reserved name', async () => { - const reservedNames = await io.getArNSReservedNames({ name: 'www ' }); - assert.ok(reservedNames); - }); + it('should be able to get epoch-settings', async () => { + const epochSettings = await io.getEpochSettings(); + assert.ok(epochSettings); + }); - it('should be able to get first page of gateways', async () => { - const gateways = await io.getGateways(); - assert.ok(gateways); - assert(gateways.limit === 100); - assert(gateways.sortOrder === 'desc'); - assert(gateways.sortBy === 'startTimestamp'); - assert(typeof gateways.totalItems === 'number'); - assert(typeof gateways.sortBy === 'string'); - assert(typeof gateways.sortOrder === 'string'); - assert(typeof gateways.limit === 'number'); - assert(typeof gateways.hasMore === 'boolean'); - if (gateways.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(gateways.items)); - gateways.items.forEach((gateway) => { - assert(typeof gateway.gatewayAddress === 'string'); - assert(typeof gateway.observerAddress === 'string'); - assert(typeof gateway.startTimestamp === 'number'); - assert(typeof gateway.operatorStake === 'number'); - assert(typeof gateway.totalDelegatedStake === 'number'); - assert(typeof gateway.settings === 'object'); - assert(typeof gateway.weights === 'object'); - assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); - assert(typeof gateway.weights.compositeWeight === 'number'); - assert(typeof gateway.weights.stakeWeight === 'number'); - assert(typeof gateway.weights.tenureWeight === 'number'); - assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); - assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + it('should be able to get reserved names', async () => { + const reservedNames = await io.getArNSReservedNames(); + assert.ok(reservedNames); }); - }); - it('should be able to get a specific page of gateways', async () => { - const gateways = await io.getGateways({ - cursor: 1000000, - limit: 1, - sortBy: 'operatorStake', - sortOrder: 'desc', + it('should be able to get a single reserved name', async () => { + const reservedNames = await io.getArNSReservedNames({ name: 'www ' }); + assert.ok(reservedNames); }); - assert.ok(gateways); - assert(gateways.limit === 1); - assert(gateways.sortOrder === 'desc'); - assert(gateways.sortBy === 'operatorStake'); - assert(typeof gateways.totalItems === 'number'); - assert(typeof gateways.sortBy === 'string'); - assert(typeof gateways.sortOrder === 'string'); - assert(typeof gateways.limit === 'number'); - assert(typeof gateways.hasMore === 'boolean'); - if (gateways.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(gateways.items)); - gateways.items.forEach((gateway) => { - assert(typeof gateway.gatewayAddress === 'string'); - assert(typeof gateway.observerAddress === 'string'); - assert(typeof gateway.startTimestamp === 'number'); - assert(typeof gateway.operatorStake === 'number'); - assert(typeof gateway.totalDelegatedStake === 'number'); - assert(typeof gateway.settings === 'object'); - assert(typeof gateway.weights === 'object'); - assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); - assert(typeof gateway.weights.compositeWeight === 'number'); - assert(typeof gateway.weights.stakeWeight === 'number'); - assert(typeof gateway.weights.tenureWeight === 'number'); - assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); - assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + + it('should be able to get first page of gateways', async () => { + const gateways = await io.getGateways(); + assert.ok(gateways); + assert(gateways.limit === 100); + assert(gateways.sortOrder === 'desc'); + assert(gateways.sortBy === 'startTimestamp'); + assert(typeof gateways.totalItems === 'number'); + assert(typeof gateways.sortBy === 'string'); + assert(typeof gateways.sortOrder === 'string'); + assert(typeof gateways.limit === 'number'); + assert(typeof gateways.hasMore === 'boolean'); + if (gateways.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(gateways.items)); + gateways.items.forEach((gateway) => { + assert(typeof gateway.gatewayAddress === 'string'); + assert(typeof gateway.observerAddress === 'string'); + assert(typeof gateway.startTimestamp === 'number'); + assert(typeof gateway.operatorStake === 'number'); + assert(typeof gateway.totalDelegatedStake === 'number'); + assert(typeof gateway.settings === 'object'); + assert(typeof gateway.weights === 'object'); + assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); + assert(typeof gateway.weights.compositeWeight === 'number'); + assert(typeof gateway.weights.stakeWeight === 'number'); + assert(typeof gateway.weights.tenureWeight === 'number'); + assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); + assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + }); }); - }); - it('should be able to get a single gateway', async () => { - const gateways = await io.getGateway({ - address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + it('should be able to get a specific page of gateways', async () => { + const gateways = await io.getGateways({ + cursor: 1000000, + limit: 1, + sortBy: 'operatorStake', + sortOrder: 'desc', + }); + assert.ok(gateways); + assert(gateways.limit === 1); + assert(gateways.sortOrder === 'desc'); + assert(gateways.sortBy === 'operatorStake'); + assert(typeof gateways.totalItems === 'number'); + assert(typeof gateways.sortBy === 'string'); + assert(typeof gateways.sortOrder === 'string'); + assert(typeof gateways.limit === 'number'); + assert(typeof gateways.hasMore === 'boolean'); + if (gateways.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(gateways.items)); + gateways.items.forEach((gateway) => { + assert(typeof gateway.gatewayAddress === 'string'); + assert(typeof gateway.observerAddress === 'string'); + assert(typeof gateway.startTimestamp === 'number'); + assert(typeof gateway.operatorStake === 'number'); + assert(typeof gateway.totalDelegatedStake === 'number'); + assert(typeof gateway.settings === 'object'); + assert(typeof gateway.weights === 'object'); + assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); + assert(typeof gateway.weights.compositeWeight === 'number'); + assert(typeof gateway.weights.stakeWeight === 'number'); + assert(typeof gateway.weights.tenureWeight === 'number'); + assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); + assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + }); }); - assert.ok(gateways); - }); - it('should be able to get balances, defaulting to first page', async () => { - const balances = await io.getBalances(); - assert.ok(balances); - assert(balances.limit === 100); - assert(balances.sortOrder === 'desc'); - assert(balances.sortBy === 'balance'); - assert(typeof balances.totalItems === 'number'); - assert(typeof balances.sortBy === 'string'); - assert(typeof balances.sortOrder === 'string'); - assert(typeof balances.limit === 'number'); - assert(typeof balances.hasMore === 'boolean'); - if (balances.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(balances.items)); - balances.items.forEach((wallet) => { - assert(typeof wallet.address === 'string'); - assert(typeof wallet.balance === 'number'); + it('should be able to get a single gateway', async () => { + const gateways = await io.getGateway({ + address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + }); + assert.ok(gateways); }); - }); - it('should be able to get balances of a specific to first page', async () => { - const balances = await io.getBalances({ - cursor: 1000000, - limit: 1, - sortBy: 'address', - sortOrder: 'asc', + it('should be able to get balances, defaulting to first page', async () => { + const balances = await io.getBalances(); + assert.ok(balances); + assert(balances.limit === 100); + assert(balances.sortOrder === 'desc'); + assert(balances.sortBy === 'balance'); + assert(typeof balances.totalItems === 'number'); + assert(typeof balances.sortBy === 'string'); + assert(typeof balances.sortOrder === 'string'); + assert(typeof balances.limit === 'number'); + assert(typeof balances.hasMore === 'boolean'); + if (balances.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(balances.items)); + balances.items.forEach((wallet) => { + assert(typeof wallet.address === 'string'); + assert(typeof wallet.balance === 'number'); + }); }); - assert.ok(balances); - assert(balances.limit === 1); - assert(balances.sortOrder === 'asc'); - assert(balances.sortBy === 'address'); - assert(typeof balances.totalItems === 'number'); - assert(typeof balances.sortBy === 'string'); - assert(typeof balances.sortOrder === 'string'); - assert(typeof balances.limit === 'number'); - assert(typeof balances.hasMore === 'boolean'); - if (balances.nextCursor) { - assert(typeof balances.nextCursor === 'string'); - } - assert(Array.isArray(balances.items)); - balances.items.forEach((wallet) => { - assert(typeof wallet.address === 'string'); - assert(typeof wallet.balance === 'number'); + + it('should be able to get balances of a specific to first page', async () => { + const balances = await io.getBalances({ + cursor: 1000000, + limit: 1, + sortBy: 'address', + sortOrder: 'asc', + }); + assert.ok(balances); + assert(balances.limit === 1); + assert(balances.sortOrder === 'asc'); + assert(balances.sortBy === 'address'); + assert(typeof balances.totalItems === 'number'); + assert(typeof balances.sortBy === 'string'); + assert(typeof balances.sortOrder === 'string'); + assert(typeof balances.limit === 'number'); + assert(typeof balances.hasMore === 'boolean'); + if (balances.nextCursor) { + assert(typeof balances.nextCursor === 'string'); + } + assert(Array.isArray(balances.items)); + balances.items.forEach((wallet) => { + assert(typeof wallet.address === 'string'); + assert(typeof wallet.balance === 'number'); + }); }); - }); - it('should be able to get a single balance', async () => { - const balances = await io.getBalance({ - address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + it('should be able to get a single balance', async () => { + const balances = await io.getBalance({ + address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + }); + assert.ok(balances); }); - assert.ok(balances); - }); - it('should be able to get prescribed names', async () => { - const prescribedNames = await io.getPrescribedNames(); - assert.ok(prescribedNames); - }); + it('should be able to get prescribed names', async () => { + const prescribedNames = await io.getPrescribedNames(); + assert.ok(prescribedNames); + }); - it('should return the prescribed observers for a given epoch', async () => { - const observers = await io.getPrescribedObservers(); - assert.ok(observers); - for (const observer of observers) { - assert(typeof observer.gatewayAddress === 'string'); - assert(typeof observer.observerAddress === 'string'); - assert(typeof observer.stake === 'number'); - assert(typeof observer.startTimestamp === 'number'); - assert(typeof observer.stakeWeight === 'number'); - assert(typeof observer.tenureWeight === 'number'); - assert(typeof observer.gatewayRewardRatioWeight === 'number'); - assert(typeof observer.observerRewardRatioWeight === 'number'); - assert(typeof observer.compositeWeight === 'number'); - } - }); + it('should return the prescribed observers for a given epoch', async () => { + const observers = await io.getPrescribedObservers(); + assert.ok(observers); + for (const observer of observers) { + assert(typeof observer.gatewayAddress === 'string'); + assert(typeof observer.observerAddress === 'string'); + assert(typeof observer.stake === 'number'); + assert(typeof observer.startTimestamp === 'number'); + assert(typeof observer.stakeWeight === 'number'); + assert(typeof observer.tenureWeight === 'number'); + assert(typeof observer.gatewayRewardRatioWeight === 'number'); + assert(typeof observer.observerRewardRatioWeight === 'number'); + assert(typeof observer.compositeWeight === 'number'); + } + }); - it('should be able to get token cost for leasing a name', async () => { - const tokenCost = await io.getTokenCost({ - intent: 'Buy-Record', - name: 'new-name', - years: 1, + it('should be able to get token cost for leasing a name', async () => { + const tokenCost = await io.getTokenCost({ + intent: 'Buy-Record', + name: 'new-name', + years: 1, + }); + assert.ok(tokenCost); }); - assert.ok(tokenCost); - }); - it('should be able to get token cost for buying a name name', async () => { - const tokenCost = await io.getTokenCost({ - intent: 'Buy-Record', - name: 'new-name', - type: 'permabuy', + it('should be able to get token cost for buying a name name', async () => { + const tokenCost = await io.getTokenCost({ + intent: 'Buy-Record', + name: 'new-name', + type: 'permabuy', + }); + assert.ok(tokenCost); }); - assert.ok(tokenCost); - }); - it('should be able to get registration fees', async () => { - const registrationFees = await io.getRegistrationFees(); - assert(registrationFees); - assert.equal(Object.keys(registrationFees).length, 51); - for (const nameLength of Object.keys(registrationFees)) { - // assert lease is length of 5 - assert(registrationFees[nameLength]['lease']['1'] > 0); - assert(registrationFees[nameLength]['lease']['2'] > 0); - assert(registrationFees[nameLength]['lease']['3'] > 0); - assert(registrationFees[nameLength]['lease']['4'] > 0); - assert(registrationFees[nameLength]['lease']['5'] > 0); - assert(registrationFees[nameLength]['permabuy'] > 0); - } - }); - it('should be able to create IOWriteable with valid signers', async () => { - for (const signer of signers) { - const io = IO.init({ signer }); + it('should be able to get registration fees', async () => { + const registrationFees = await io.getRegistrationFees(); + assert(registrationFees); + assert.equal(Object.keys(registrationFees).length, 51); + for (const nameLength of Object.keys(registrationFees)) { + // assert lease is length of 5 + assert(registrationFees[nameLength]['lease']['1'] > 0); + assert(registrationFees[nameLength]['lease']['2'] > 0); + assert(registrationFees[nameLength]['lease']['3'] > 0); + assert(registrationFees[nameLength]['lease']['4'] > 0); + assert(registrationFees[nameLength]['lease']['5'] > 0); + assert(registrationFees[nameLength]['permabuy'] > 0); + } + }); + it('should be able to create IOWriteable with valid signers', async () => { + for (const signer of signers) { + const io = IO.init({ signer }); - assert(io instanceof IOWriteable); - } + assert(io instanceof IOWriteable); + } + }); }); -}); -describe('ANTRegistry', async () => { - const registry = ANTRegistry.init(); - const address = '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk'; + describe('ANTRegistry', async () => { + const registry = ANTRegistry.init(); + const address = '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk'; - it('should retrieve ids from registry', async () => { - const affiliatedAnts = await registry.accessControlList({ address }); - assert(Array.isArray(affiliatedAnts.Owned)); - assert(Array.isArray(affiliatedAnts.Controlled)); - }); + it('should retrieve ids from registry', async () => { + const affiliatedAnts = await registry.accessControlList({ address }); + assert(Array.isArray(affiliatedAnts.Owned)); + assert(Array.isArray(affiliatedAnts.Controlled)); + }); - it('should be able to create AoANTRegistryWriteable with valid signers', async () => { - for (const signer of signers) { - const registry = ANTRegistry.init({ - signer, - }); - assert(registry instanceof AoANTRegistryWriteable); - } + it('should be able to create AoANTRegistryWriteable with valid signers', async () => { + for (const signer of signers) { + const registry = ANTRegistry.init({ + signer, + }); + assert(registry instanceof AoANTRegistryWriteable); + } + }); }); -}); -describe('ANT', async () => { - const processId = 'YcxE5IbqZYK72H64ELoysxiJ-0wb36deYPv55wgl8xo'; - it('should be able to create ANTWriteable with valid signers', async () => { - for (const signer of signers) { - const ant = ANT.init({ - processId, - signer, - strict: true, - ao: aoClient, - }); - const strictAnt = ANT.init({ - processId, - signer, - strict: true, - ao: aoClient, - }); + describe('ANT', async () => { + const processId = 'YcxE5IbqZYK72H64ELoysxiJ-0wb36deYPv55wgl8xo'; + it('should be able to create ANTWriteable with valid signers', async () => { + for (const signer of signers) { + const ant = ANT.init({ + processId, + signer, + strict: true, + ao: aoClient, + }); + const strictAnt = ANT.init({ + processId, + signer, + strict: true, + ao: aoClient, + }); - assert(ant instanceof AoANTWriteable); - assert(strictAnt instanceof AoANTWriteable); - } + assert(ant instanceof AoANTWriteable); + assert(strictAnt instanceof AoANTWriteable); + } + }); }); }); diff --git a/tests/e2e/esm/index.test.js b/tests/e2e/esm/index.test.js index cdfa6d9c..7fc114cb 100644 --- a/tests/e2e/esm/index.test.js +++ b/tests/e2e/esm/index.test.js @@ -1,6 +1,7 @@ import { ANT, ANTRegistry, + ANT_REGISTRY_ID, AOProcess, AoANTRegistryWriteable, AoANTWriteable, @@ -32,16 +33,18 @@ const signers = [ * (simply running npm run test:integration will ensure npm link is ran) */ +const aoClient = connect({ + CU_URL: 'http://localhost:6363', +}); + const io = IO.init({ process: new AOProcess({ processId: ioDevnetProcessId, - ao: connect({ - CU_URL: 'http://localhost:6363', - }), + ao: aoClient, }), }); -describe('IO', async () => { +describe('e2e esm tests', async () => { let compose; before(async () => { compose = await new DockerComposeEnvironment( @@ -57,418 +60,414 @@ describe('IO', async () => { await compose.down(); }); - it('should be able to get the process information', async () => { - const info = await io.getInfo(); - assert.ok(info); - assert(typeof info.Name === 'string'); - assert(typeof info.Ticker === 'string'); - assert(typeof info.Logo === 'string'); - assert(typeof info.Denomination === 'number'); - assert(Array.isArray(info.Handlers)); - assert(typeof info.LastTickedEpochIndex === 'number'); - }); + describe('IO', async () => { + it('should be able to get the process information', async () => { + const info = await io.getInfo(); + assert.ok(info); + assert(typeof info.Name === 'string'); + assert(typeof info.Ticker === 'string'); + assert(typeof info.Logo === 'string'); + assert(typeof info.Denomination === 'number'); + assert(Array.isArray(info.Handlers)); + assert(typeof info.LastTickedEpochIndex === 'number'); + }); - it('should be able to get the total token supply', async () => { - const tokenSupply = await io.getTokenSupply(); - assert.ok(tokenSupply); - assert(typeof tokenSupply.total === 'number'); - assert(typeof tokenSupply.circulating === 'number'); - assert(typeof tokenSupply.locked === 'number'); - assert(typeof tokenSupply.withdrawn === 'number'); - assert(typeof tokenSupply.delegated === 'number'); - assert(typeof tokenSupply.staked === 'number'); - assert(typeof tokenSupply.protocolBalance === 'number'); - }); + it('should be able to return a specific page of arns records', async () => { + const records = await io.getArNSRecords({ + cursor: 'ardrive', + limit: 5, + sortOrder: 'desc', + sortBy: 'name', + }); + assert.ok(records); + assert(records.limit === 5); + assert(records.sortOrder === 'desc'); + assert(records.sortBy === 'name'); + assert(typeof records.totalItems === 'number'); + assert(typeof records.sortBy === 'string'); + assert(typeof records.sortOrder === 'string'); + assert(typeof records.limit === 'number'); + assert(typeof records.hasMore === 'boolean'); + if (records.nextCursor) { + assert(typeof records.nextCursor === 'string'); + } + assert(Array.isArray(records.items)); + records.items.forEach((record) => { + assert(typeof record.processId === 'string'); + assert(typeof record.name === 'string'); + assert(typeof record.startTimestamp === 'number'); + assert(['lease', 'permabuy'].includes(record.type)); + assert(typeof record.undernameLimit === 'number'); + }); + }); + it('should be able to get a single arns record', async () => { + const arns = await io.getArNSRecord({ name: 'ardrive' }); + assert.ok(arns); + }); - it('should be able to get first set of arns records', async () => { - const records = await io.getArNSRecords(); - assert.ok(records); - assert(records.limit === 100); - assert(records.sortOrder === 'desc'); - assert(records.sortBy === 'startTimestamp'); - assert(typeof records.totalItems === 'number'); - assert(typeof records.sortBy === 'string'); - assert(typeof records.sortOrder === 'string'); - assert(typeof records.limit === 'number'); - assert(typeof records.hasMore === 'boolean'); - if (records.nextCursor) { - assert(typeof records.nextCursor === 'string'); - } - assert(Array.isArray(records.items)); - records.items.forEach((record) => { - assert(typeof record.processId === 'string'); - assert(typeof record.name === 'string'); - assert(typeof record.startTimestamp === 'number'); - assert(['lease', 'permabuy'].includes(record.type)); - assert(typeof record.undernameLimit === 'number'); + it('should be able to get the current epoch', async () => { + const epoch = await io.getCurrentEpoch(); + assert.ok(epoch); }); - }); - it('should be able to return a specific page of arns records', async () => { - const records = await io.getArNSRecords({ - cursor: 'ardrive', - limit: 5, - sortOrder: 'desc', - sortBy: 'name', - }); - assert.ok(records); - assert(records.limit === 5); - assert(records.sortOrder === 'desc'); - assert(records.sortBy === 'name'); - assert(typeof records.totalItems === 'number'); - assert(typeof records.sortBy === 'string'); - assert(typeof records.sortOrder === 'string'); - assert(typeof records.limit === 'number'); - assert(typeof records.hasMore === 'boolean'); - if (records.nextCursor) { - assert(typeof records.nextCursor === 'string'); - } - assert(Array.isArray(records.items)); - records.items.forEach((record) => { - assert(typeof record.processId === 'string'); - assert(typeof record.name === 'string'); - assert(typeof record.startTimestamp === 'number'); - assert(['lease', 'permabuy'].includes(record.type)); - assert(typeof record.undernameLimit === 'number'); + it('should be able to get epoch-settings', async () => { + const epochSettings = await io.getEpochSettings(); + assert.ok(epochSettings); }); - }); - it('should be able to get a single arns record', async () => { - const arns = await io.getArNSRecord({ name: 'ardrive' }); - assert.ok(arns); - }); - it('should be able to get the current epoch', async () => { - const epoch = await io.getCurrentEpoch(); - assert.ok(epoch); - }); + it('should be able to get reserved names', async () => { + const reservedNames = await io.getArNSReservedNames(); + assert.ok(reservedNames); + }); - it('should be able to get epoch-settings', async () => { - const epochSettings = await io.getEpochSettings(); - assert.ok(epochSettings); - }); + it('should be able to get a single reserved name', async () => { + const reservedNames = await io.getArNSReservedNames({ name: 'www ' }); + assert.ok(reservedNames); + }); - it('should be able to get reserved names', async () => { - const reservedNames = await io.getArNSReservedNames(); - assert.ok(reservedNames); - }); + it('should be able to get first page of gateways', async () => { + const gateways = await io.getGateways(); + assert.ok(gateways); + assert(gateways.limit === 100); + assert(gateways.sortOrder === 'desc'); + assert(gateways.sortBy === 'startTimestamp'); + assert(typeof gateways.totalItems === 'number'); + assert(typeof gateways.sortBy === 'string'); + assert(typeof gateways.sortOrder === 'string'); + assert(typeof gateways.limit === 'number'); + assert(typeof gateways.hasMore === 'boolean'); + if (gateways.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(gateways.items)); + gateways.items.forEach((gateway) => { + assert(typeof gateway.gatewayAddress === 'string'); + assert(typeof gateway.observerAddress === 'string'); + assert(typeof gateway.startTimestamp === 'number'); + assert(typeof gateway.operatorStake === 'number'); + assert(typeof gateway.totalDelegatedStake === 'number'); + assert(typeof gateway.settings === 'object'); + assert(typeof gateway.weights === 'object'); + assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); + assert(typeof gateway.weights.compositeWeight === 'number'); + assert(typeof gateway.weights.stakeWeight === 'number'); + assert(typeof gateway.weights.tenureWeight === 'number'); + assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); + assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + }); + }); - it('should be able to get a single reserved name', async () => { - const reservedNames = await io.getArNSReservedNames({ name: 'www ' }); - assert.ok(reservedNames); - }); + it('should be able to get a specific page of gateways', async () => { + const gateways = await io.getGateways({ + cursor: 1000000, + limit: 1, + sortBy: 'operatorStake', + sortOrder: 'desc', + }); + assert.ok(gateways); + assert(gateways.limit === 1); + assert(gateways.sortOrder === 'desc'); + assert(gateways.sortBy === 'operatorStake'); + assert(typeof gateways.totalItems === 'number'); + assert(typeof gateways.sortBy === 'string'); + assert(typeof gateways.sortOrder === 'string'); + assert(typeof gateways.limit === 'number'); + assert(typeof gateways.hasMore === 'boolean'); + if (gateways.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(gateways.items)); + gateways.items.forEach((gateway) => { + assert(typeof gateway.gatewayAddress === 'string'); + assert(typeof gateway.observerAddress === 'string'); + assert(typeof gateway.startTimestamp === 'number'); + assert(typeof gateway.operatorStake === 'number'); + assert(typeof gateway.totalDelegatedStake === 'number'); + assert(typeof gateway.settings === 'object'); + assert(typeof gateway.weights === 'object'); + assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); + assert(typeof gateway.weights.compositeWeight === 'number'); + assert(typeof gateway.weights.stakeWeight === 'number'); + assert(typeof gateway.weights.tenureWeight === 'number'); + assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); + assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + }); + }); - it('should be able to get first page of gateways', async () => { - const gateways = await io.getGateways(); - assert.ok(gateways); - assert(gateways.limit === 100); - assert(gateways.sortOrder === 'desc'); - assert(gateways.sortBy === 'startTimestamp'); - assert(typeof gateways.totalItems === 'number'); - assert(typeof gateways.sortBy === 'string'); - assert(typeof gateways.sortOrder === 'string'); - assert(typeof gateways.limit === 'number'); - assert(typeof gateways.hasMore === 'boolean'); - if (gateways.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(gateways.items)); - gateways.items.forEach((gateway) => { - assert(typeof gateway.gatewayAddress === 'string'); - assert(typeof gateway.observerAddress === 'string'); - assert(typeof gateway.startTimestamp === 'number'); - assert(typeof gateway.operatorStake === 'number'); - assert(typeof gateway.totalDelegatedStake === 'number'); - assert(typeof gateway.settings === 'object'); - assert(typeof gateway.weights === 'object'); - assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); - assert(typeof gateway.weights.compositeWeight === 'number'); - assert(typeof gateway.weights.stakeWeight === 'number'); - assert(typeof gateway.weights.tenureWeight === 'number'); - assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); - assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + it('should be able to get a single gateway', async () => { + const gateways = await io.getGateway({ + address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + }); + assert.ok(gateways); }); - }); - it('should be able to get a specific page of gateways', async () => { - const gateways = await io.getGateways({ - cursor: 1000000, - limit: 1, - sortBy: 'operatorStake', - sortOrder: 'desc', - }); - assert.ok(gateways); - assert(gateways.limit === 1); - assert(gateways.sortOrder === 'desc'); - assert(gateways.sortBy === 'operatorStake'); - assert(typeof gateways.totalItems === 'number'); - assert(typeof gateways.sortBy === 'string'); - assert(typeof gateways.sortOrder === 'string'); - assert(typeof gateways.limit === 'number'); - assert(typeof gateways.hasMore === 'boolean'); - if (gateways.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(gateways.items)); - gateways.items.forEach((gateway) => { - assert(typeof gateway.gatewayAddress === 'string'); - assert(typeof gateway.observerAddress === 'string'); - assert(typeof gateway.startTimestamp === 'number'); - assert(typeof gateway.operatorStake === 'number'); - assert(typeof gateway.totalDelegatedStake === 'number'); - assert(typeof gateway.settings === 'object'); - assert(typeof gateway.weights === 'object'); - assert(typeof gateway.weights.normalizedCompositeWeight === 'number'); - assert(typeof gateway.weights.compositeWeight === 'number'); - assert(typeof gateway.weights.stakeWeight === 'number'); - assert(typeof gateway.weights.tenureWeight === 'number'); - assert(typeof gateway.weights.observerRewardRatioWeight === 'number'); - assert(typeof gateway.weights.gatewayRewardRatioWeight === 'number'); + it('should be able to get balances, defaulting to first page', async () => { + const balances = await io.getBalances(); + assert.ok(balances); + assert(balances.limit === 100); + assert(balances.sortOrder === 'desc'); + assert(balances.sortBy === 'balance'); + assert(typeof balances.totalItems === 'number'); + assert(typeof balances.sortBy === 'string'); + assert(typeof balances.sortOrder === 'string'); + assert(typeof balances.limit === 'number'); + assert(typeof balances.hasMore === 'boolean'); + if (balances.nextCursor) { + assert(typeof gateways.nextCursor === 'string'); + } + assert(Array.isArray(balances.items)); + balances.items.forEach((wallet) => { + assert(typeof wallet.address === 'string'); + assert(typeof wallet.balance === 'number'); + }); }); - }); - it('should be able to get a single gateway', async () => { - const gateways = await io.getGateway({ - address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + it('should be able to get balances of a specific to first page', async () => { + const balances = await io.getBalances({ + cursor: 1000000, + limit: 1, + sortBy: 'address', + sortOrder: 'asc', + }); + assert.ok(balances); + assert(balances.limit === 1); + assert(balances.sortOrder === 'asc'); + assert(balances.sortBy === 'address'); + assert(typeof balances.totalItems === 'number'); + assert(typeof balances.sortBy === 'string'); + assert(typeof balances.sortOrder === 'string'); + assert(typeof balances.limit === 'number'); + assert(typeof balances.hasMore === 'boolean'); + if (balances.nextCursor) { + assert(typeof balances.nextCursor === 'string'); + } + assert(Array.isArray(balances.items)); + balances.items.forEach((wallet) => { + assert(typeof wallet.address === 'string'); + assert(typeof wallet.balance === 'number'); + }); }); - assert.ok(gateways); - }); - it('should be able to get balances, defaulting to first page', async () => { - const balances = await io.getBalances(); - assert.ok(balances); - assert(balances.limit === 100); - assert(balances.sortOrder === 'desc'); - assert(balances.sortBy === 'balance'); - assert(typeof balances.totalItems === 'number'); - assert(typeof balances.sortBy === 'string'); - assert(typeof balances.sortOrder === 'string'); - assert(typeof balances.limit === 'number'); - assert(typeof balances.hasMore === 'boolean'); - if (balances.nextCursor) { - assert(typeof gateways.nextCursor === 'string'); - } - assert(Array.isArray(balances.items)); - balances.items.forEach((wallet) => { - assert(typeof wallet.address === 'string'); - assert(typeof wallet.balance === 'number'); + it('should be able to get a single balance', async () => { + const balances = await io.getBalance({ + address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + }); + assert.ok(balances); }); - }); - it('should be able to get balances of a specific to first page', async () => { - const balances = await io.getBalances({ - cursor: 1000000, - limit: 1, - sortBy: 'address', - sortOrder: 'asc', - }); - assert.ok(balances); - assert(balances.limit === 1); - assert(balances.sortOrder === 'asc'); - assert(balances.sortBy === 'address'); - assert(typeof balances.totalItems === 'number'); - assert(typeof balances.sortBy === 'string'); - assert(typeof balances.sortOrder === 'string'); - assert(typeof balances.limit === 'number'); - assert(typeof balances.hasMore === 'boolean'); - if (balances.nextCursor) { - assert(typeof balances.nextCursor === 'string'); - } - assert(Array.isArray(balances.items)); - balances.items.forEach((wallet) => { - assert(typeof wallet.address === 'string'); - assert(typeof wallet.balance === 'number'); + it('should be able to get prescribed names', async () => { + const prescribedNames = await io.getPrescribedNames(); + assert.ok(prescribedNames); }); - }); - it('should be able to get a single balance', async () => { - const balances = await io.getBalance({ - address: 'QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ', + it('should return the prescribed observers for a given epoch', async () => { + const observers = await io.getPrescribedObservers(); + assert.ok(observers); + for (const observer of observers) { + assert(typeof observer.gatewayAddress === 'string'); + assert(typeof observer.observerAddress === 'string'); + assert(typeof observer.stake === 'number'); + assert(typeof observer.startTimestamp === 'number'); + assert(typeof observer.stakeWeight === 'number'); + assert(typeof observer.tenureWeight === 'number'); + assert(typeof observer.gatewayRewardRatioWeight === 'number'); + assert(typeof observer.observerRewardRatioWeight === 'number'); + assert(typeof observer.compositeWeight === 'number'); + } }); - assert.ok(balances); - }); - it('should be able to get prescribed names', async () => { - const prescribedNames = await io.getPrescribedNames(); - assert.ok(prescribedNames); - }); + it('should be able to get token cost for leasing a name', async () => { + const tokenCost = await io.getTokenCost({ + intent: 'Buy-Record', + name: 'new-name', + years: 1, + }); + assert.ok(tokenCost); + }); - it('should return the prescribed observers for a given epoch', async () => { - const observers = await io.getPrescribedObservers(); - assert.ok(observers); - for (const observer of observers) { - assert(typeof observer.gatewayAddress === 'string'); - assert(typeof observer.observerAddress === 'string'); - assert(typeof observer.stake === 'number'); - assert(typeof observer.startTimestamp === 'number'); - assert(typeof observer.stakeWeight === 'number'); - assert(typeof observer.tenureWeight === 'number'); - assert(typeof observer.gatewayRewardRatioWeight === 'number'); - assert(typeof observer.observerRewardRatioWeight === 'number'); - assert(typeof observer.compositeWeight === 'number'); - } - }); + it('should be able to get token cost for buying a name name', async () => { + const tokenCost = await io.getTokenCost({ + intent: 'Buy-Record', + name: 'new-name', + type: 'permabuy', + }); + assert.ok(tokenCost); + }); - it('should be able to get token cost for leasing a name', async () => { - const tokenCost = await io.getTokenCost({ - intent: 'Buy-Record', - name: 'new-name', - years: 1, + it('should be able to get registration fees', async () => { + const registrationFees = await io.getRegistrationFees(); + assert(registrationFees); + assert.equal(Object.keys(registrationFees).length, 51); + for (const nameLength of Object.keys(registrationFees)) { + // assert lease is length of 5 + assert(registrationFees[nameLength]['lease']['1'] > 0); + assert(registrationFees[nameLength]['lease']['2'] > 0); + assert(registrationFees[nameLength]['lease']['3'] > 0); + assert(registrationFees[nameLength]['lease']['4'] > 0); + assert(registrationFees[nameLength]['lease']['5'] > 0); + assert(registrationFees[nameLength]['permabuy'] > 0); + } }); - assert.ok(tokenCost); - }); - it('should be able to get token cost for buying a name name', async () => { - const tokenCost = await io.getTokenCost({ - intent: 'Buy-Record', - name: 'new-name', - type: 'permabuy', + it('should be able to get current epoch distributions', async () => { + const distributions = await io.getDistributions(); + assert.ok(distributions); }); - assert.ok(tokenCost); - }); - it('should be able to get registration fees', async () => { - const registrationFees = await io.getRegistrationFees(); - assert(registrationFees); - assert.equal(Object.keys(registrationFees).length, 51); - for (const nameLength of Object.keys(registrationFees)) { - // assert lease is length of 5 - assert(registrationFees[nameLength]['lease']['1'] > 0); - assert(registrationFees[nameLength]['lease']['2'] > 0); - assert(registrationFees[nameLength]['lease']['3'] > 0); - assert(registrationFees[nameLength]['lease']['4'] > 0); - assert(registrationFees[nameLength]['lease']['5'] > 0); - assert(registrationFees[nameLength]['permabuy'] > 0); - } - }); + it('should be able to get epoch distributions at a specific epoch', async () => { + const distributions = await io.getDistributions({ epochIndex: 0 }); + assert.ok(distributions); + }); - it('should be able to get current epoch distributions', async () => { - const distributions = await io.getDistributions(); - assert.ok(distributions); - }); + it('should be able to get current epoch observations', async () => { + const observations = await io.getObservations(); + assert.ok(observations); + }); - it('should be able to get epoch distributions at a specific epoch', async () => { - const distributions = await io.getDistributions({ epochIndex: 0 }); - assert.ok(distributions); - }); + it('should be able to get epoch observations at a specific epoch', async () => { + const observations = await io.getObservations({ epochIndex: 0 }); + assert.ok(observations); + }); - it('should be able to get current epoch observations', async () => { - const observations = await io.getObservations(); - assert.ok(observations); - }); + it('should be able to get current demand factor', async () => { + const demandFactor = await io.getDemandFactor(); + assert.ok(demandFactor); + }); - it('should be able to get epoch observations at a specific epoch', async () => { - const observations = await io.getObservations({ epochIndex: 0 }); - assert.ok(observations); - }); + it('should be able to get current auctions', async () => { + const { items: auctions } = await io.getAuctions(); + assert.ok(auctions); + }); - it('should be able to get current demand factor', async () => { - const demandFactor = await io.getDemandFactor(); - assert.ok(demandFactor); - }); + it('should be able to get a specific auction', async () => { + const { items: auctions } = await io.getAuctions(); + if (auctions.length === 0) { + return; + } + const auction = await io.getAuction({ name: auctions[0].name }); + assert.ok(auction); + }); - it('should be able to create IOWriteable with valid signers', async () => { - for (const signer of signers) { - const io = IO.init({ signer }); + it('should be able to create IOWriteable with valid signers', async () => { + for (const signer of signers) { + const io = IO.init({ signer }); - assert(io instanceof IOWriteable); - } + assert(io instanceof IOWriteable); + } + }); }); -}); -describe('ANTRegistry', async () => { - const registry = ANTRegistry.init(); - const address = '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk'; - - it('should retrieve ids from registry', async () => { - const affiliatedAnts = await registry.accessControlList({ address }); - assert(Array.isArray(affiliatedAnts.Owned)); - assert(Array.isArray(affiliatedAnts.Controlled)); - }); + describe('ANTRegistry', async () => { + const registry = ANTRegistry.init({ + process: new AOProcess({ + processId: ANT_REGISTRY_ID, + ao: aoClient, + }), + }); + const address = '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk'; - it('should be able to create AoANTRegistryWriteable with valid signers', async () => { - for (const signer of signers) { - const registry = ANTRegistry.init({ - signer, - }); - assert(registry instanceof AoANTRegistryWriteable); - } - }); -}); + it('should retrieve ids from registry', async () => { + const affiliatedAnts = await registry.accessControlList({ address }); + assert(Array.isArray(affiliatedAnts.Owned)); + assert(Array.isArray(affiliatedAnts.Controlled)); + }); -describe('ANT', async () => { - const processId = 'YcxE5IbqZYK72H64ELoysxiJ-0wb36deYPv55wgl8xo'; - const ant = ANT.init({ - processId, - strict: true, + it('should be able to create AoANTRegistryWriteable with valid signers', async () => { + for (const signer of signers) { + const registry = ANTRegistry.init({ + signer, + process: new AOProcess({ + processId: ANT_REGISTRY_ID, + ao: aoClient, + }), + }); + assert(registry instanceof AoANTRegistryWriteable); + } + }); }); - it('should be able to create ANTWriteable with valid signers', async () => { - for (const signer of signers) { - const nonStrictAnt = ANT.init({ + describe('ANT', async () => { + const processId = 'YcxE5IbqZYK72H64ELoysxiJ-0wb36deYPv55wgl8xo'; + const ant = ANT.init({ + process: new AOProcess({ processId, - signer, - strict: false, - }); - const strictAnt = ANT.init({ - processId, - signer, - strict: true, - }); + ao: aoClient, + }), + }); - assert(nonStrictAnt instanceof AoANTWriteable); - assert(strictAnt instanceof AoANTWriteable); - } - }); + it('should be able to create ANTWriteable with valid signers', async () => { + for (const signer of signers) { + const nonStrictAnt = ANT.init({ + process: new AOProcess({ + processId, + ao: aoClient, + }), + signer, + }); + const strictAnt = ANT.init({ + process: new AOProcess({ + processId, + ao: aoClient, + }), + signer, + strict: true, + }); + + assert(nonStrictAnt instanceof AoANTWriteable); + assert(strictAnt instanceof AoANTWriteable); + } + }); - it('should be able to get ANT info', async () => { - const info = await ant.getInfo(); - assert.ok(info); - }); + it('should be able to get ANT info', async () => { + const info = await ant.getInfo(); + assert.ok(info); + }); - it('should be able to get the ANT records', async () => { - const records = await ant.getRecords(); - assert.ok(records); - }); + it('should be able to get the ANT records', async () => { + const records = await ant.getRecords(); + assert.ok(records); + }); - it('should be able to get a @ record from the ANT', async () => { - const record = await ant.getRecord({ undername: '@' }); - assert.ok(record); - }); + it('should be able to get a @ record from the ANT', async () => { + const record = await ant.getRecord({ undername: '@' }); + assert.ok(record); + }); - it('should be able to get the ANT owner', async () => { - const owner = await ant.getOwner(); - assert.ok(owner); - }); + it('should be able to get the ANT owner', async () => { + const owner = await ant.getOwner(); + assert.ok(owner); + }); - it('should be able to get the ANT name', async () => { - const name = await ant.getName(); - assert.ok(name); - }); + it('should be able to get the ANT name', async () => { + const name = await ant.getName(); + assert.ok(name); + }); - it('should be able to get the ANT ticker', async () => { - const ticker = await ant.getTicker(); - assert.ok(ticker); - }); + it('should be able to get the ANT ticker', async () => { + const ticker = await ant.getTicker(); + assert.ok(ticker); + }); - it('should be able to get the ANT controllers', async () => { - const controllers = await ant.getControllers(); - assert.ok(controllers); - }); + it('should be able to get the ANT controllers', async () => { + const controllers = await ant.getControllers(); + assert.ok(controllers); + }); - it('should be able to get the ANT state', async () => { - const state = await ant.getState(); - assert.ok(state); - }); + it('should be able to get the ANT state', async () => { + const state = await ant.getState(); + assert.ok(state); + }); - it('should be able to get the ANT balance for an address', async () => { - const balance = await ant.getBalance({ - address: '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk', + it('should be able to get the ANT balance for an address', async () => { + const balance = await ant.getBalance({ + address: '7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk', + }); + assert.notEqual(balance, undefined); }); - assert.notEqual(balance, undefined); - }); - it('should be able to get the ANT balances', async () => { - const balances = await ant.getBalances(); - assert.ok(balances); + it('should be able to get the ANT balances', async () => { + const balances = await ant.getBalances(); + assert.ok(balances); + }); }); });