@ar.io/sdk 1.2.0-alpha.9 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,15 +14,15 @@
14
14
  * You should have received a copy of the GNU Affero General Public License
15
15
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
+ import { EventEmitter } from 'eventemitter3';
17
18
  import { pLimit } from 'plimit-lit';
18
19
  import { ANT } from '../../common/ant.js';
19
20
  import { IO } from '../../common/io.js';
20
21
  import { ioDevnetProcessId } from '../../constants.js';
21
- // throttle the requests to avoid rate limiting
22
- const throttle = pLimit(50);
23
22
  export const getANTProcessesOwnedByWallet = async ({ address, contract = IO.init({
24
23
  processId: ioDevnetProcessId,
25
24
  }), }) => {
25
+ const throttle = pLimit(50);
26
26
  // get the record names of the registry - TODO: this may need to be paginated
27
27
  const uniqueContractProcessIds = await contract
28
28
  .getArNSRecords()
@@ -30,14 +30,93 @@ export const getANTProcessesOwnedByWallet = async ({ address, contract = IO.init
30
30
  .filter((record) => record.processId !== undefined)
31
31
  .map((record) => record.processId));
32
32
  // check the contract owner and controllers
33
- const ownedOrControlledByWallet = await Promise.all(uniqueContractProcessIds.filter(async (processId) => throttle(async () => {
33
+ const ownedOrControlledByWallet = await Promise.all(uniqueContractProcessIds.map(async (processId) => throttle(async () => {
34
34
  const ant = ANT.init({
35
35
  processId,
36
36
  });
37
- const owner = await ant.getOwner();
38
- const controllers = await ant.getControllers();
39
- return owner === address || controllers.includes(address);
37
+ const { Owner, Controllers } = await ant.getState();
38
+ if (Owner === address || Controllers.includes(address)) {
39
+ return processId;
40
+ }
41
+ return;
40
42
  })));
43
+ if (ownedOrControlledByWallet.length === 0) {
44
+ return [];
45
+ }
41
46
  // TODO: insert gql query to find ANT processes owned by wallet given wallet not currently in the registry
42
47
  return [...new Set(ownedOrControlledByWallet)];
43
48
  };
49
+ function timeout(ms, promise) {
50
+ return new Promise((resolve, reject) => {
51
+ const timer = setTimeout(() => {
52
+ reject(new Error('Timeout'));
53
+ }, ms);
54
+ promise
55
+ .then((value) => {
56
+ clearTimeout(timer);
57
+ resolve(value);
58
+ })
59
+ .catch((err) => {
60
+ clearTimeout(timer);
61
+ reject(err);
62
+ });
63
+ });
64
+ }
65
+ export class ArNSEventEmitter extends EventEmitter {
66
+ contract;
67
+ timeoutMs; // timeout for each request to 3 seconds
68
+ throttle;
69
+ constructor({ contract = IO.init({
70
+ processId: ioDevnetProcessId,
71
+ }), timeoutMs = 60_000, concurrency = 30, }) {
72
+ super();
73
+ this.contract = contract;
74
+ this.timeoutMs = timeoutMs;
75
+ this.throttle = pLimit(concurrency);
76
+ }
77
+ async fetchProcessesOwnedByWallet({ address }) {
78
+ const uniqueContractProcessIds = {};
79
+ await timeout(this.timeoutMs, this.contract.getArNSRecords().catch((e) => {
80
+ this.emit('error', `Error getting ArNS records: ${e}`);
81
+ return {};
82
+ })).then((records) => {
83
+ if (!records)
84
+ return;
85
+ Object.entries(records).forEach(([name, record]) => {
86
+ if (record.processId === undefined) {
87
+ return;
88
+ }
89
+ if (uniqueContractProcessIds[record.processId] === undefined) {
90
+ uniqueContractProcessIds[record.processId] = {
91
+ state: undefined,
92
+ names: {},
93
+ };
94
+ }
95
+ uniqueContractProcessIds[record.processId].names[name] = record;
96
+ });
97
+ });
98
+ const idCount = Object.keys(uniqueContractProcessIds).length;
99
+ // check the contract owner and controllers
100
+ this.emit('progress', 0, idCount);
101
+ await Promise.all(Object.keys(uniqueContractProcessIds).map(async (processId, i) => this.throttle(async () => {
102
+ if (uniqueContractProcessIds[processId].state !== undefined) {
103
+ this.emit('progress', i + 1, idCount);
104
+ return;
105
+ }
106
+ const ant = ANT.init({
107
+ processId,
108
+ });
109
+ const state = (await timeout(this.timeoutMs, ant.getState()).catch((e) => {
110
+ this.emit('error', `Error getting state for process ${processId}: ${e}`);
111
+ return undefined;
112
+ }));
113
+ if (state?.Owner === address ||
114
+ state?.Controllers.includes(address)) {
115
+ uniqueContractProcessIds[processId].state = state;
116
+ this.emit('process', processId, uniqueContractProcessIds[processId]);
117
+ }
118
+ this.emit('progress', i + 1, idCount);
119
+ })));
120
+ this.emit('end', uniqueContractProcessIds);
121
+ }
122
+ }
@@ -19,3 +19,4 @@ export * from './http-client.js';
19
19
  export * from './smartweave.js';
20
20
  export * from './graphql/index.js';
21
21
  export * from './ao.js';
22
+ export * from './json.js';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ export function safeDecode(data) {
18
+ try {
19
+ return JSON.parse(data);
20
+ }
21
+ catch (e) {
22
+ return data;
23
+ }
24
+ }
@@ -15,4 +15,4 @@
15
15
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
17
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
18
- export const version = '1.2.0-alpha.9';
18
+ export const version = '1.2.0';
@@ -15,12 +15,13 @@
15
15
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
17
  import { ANTRecord } from '../contract-state.js';
18
- import { AoANTRead, AoANTWrite, ProcessConfiguration } from '../io.js';
18
+ import { AoANTRead, AoANTState, AoANTWrite, ProcessConfiguration } from '../io.js';
19
19
  import { AoMessageResult, WalletAddress, WithSigner } from '../types.js';
20
20
  import { AOProcess } from './contracts/ao-process.js';
21
21
  export declare class AoANTReadable implements AoANTRead {
22
22
  protected process: AOProcess;
23
23
  constructor(config: Required<ProcessConfiguration>);
24
+ getState(): Promise<AoANTState>;
24
25
  getInfo(): Promise<{
25
26
  Name: string;
26
27
  Ticker: string;
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import Arweave from 'arweave';
18
18
  import { ArNSReservedNameData, EpochDistributionData, EpochObservations, WeightedObserver } from '../contract-state.js';
19
- import { AoArNSNameData, AoEpochData, AoGateway, AoIORead, AoIOWrite, EpochInput } from '../io.js';
19
+ import { AoArNSNameData, AoEpochData, AoEpochSettings, AoGateway, AoIORead, AoIOWrite, EpochInput } from '../io.js';
20
20
  import { mIOToken } from '../token.js';
21
21
  import { AoMessageResult, ContractSigner, JoinNetworkParams, ProcessConfiguration, TransactionId, UpdateGatewaySettingsParams, WalletAddress, WithSigner, WriteOptions } from '../types.js';
22
22
  import { AOProcess } from './contracts/ao-process.js';
@@ -43,6 +43,13 @@ export declare class IOReadable implements AoIORead {
43
43
  protected process: AOProcess;
44
44
  private arweave;
45
45
  constructor(config?: ProcessConfiguration, arweave?: Arweave);
46
+ getInfo(): Promise<{
47
+ Name: string;
48
+ Ticker: string;
49
+ Logo: string;
50
+ Denomination: number;
51
+ }>;
52
+ getEpochSettings(params?: EpochInput): Promise<AoEpochSettings>;
46
53
  getEpoch(epoch?: EpochInput): Promise<AoEpochData>;
47
54
  getArNSRecord({ name, }: {
48
55
  name: string;
@@ -66,18 +73,18 @@ export declare class IOReadable implements AoIORead {
66
73
  getObservations(epoch?: EpochInput): Promise<EpochObservations>;
67
74
  getDistributions(epoch?: EpochInput): Promise<EpochDistributionData>;
68
75
  getTokenCost(params: {
69
- intent: 'BuyRecord';
76
+ intent: 'Buy-Record';
70
77
  purchaseType: 'permabuy' | 'lease';
71
78
  years: number;
72
79
  name: string;
73
80
  }): Promise<number>;
74
81
  getTokenCost(params: {
75
- intent: 'ExtendLease';
82
+ intent: 'Extend-Lease';
76
83
  years: number;
77
84
  name: string;
78
85
  }): Promise<number>;
79
86
  getTokenCost(params: {
80
- intent: 'IncreaseUndernameLimit';
87
+ intent: 'Increase-Undername-Limit';
81
88
  quantity: number;
82
89
  name: string;
83
90
  }): Promise<number>;
@@ -20,8 +20,10 @@ export declare const FQDN_REGEX: RegExp;
20
20
  export declare const SORT_KEY_REGEX: RegExp;
21
21
  export declare const ARNS_TESTNET_REGISTRY_TX: string;
22
22
  export declare const ARNS_DEVNET_REGISTRY_TX = "_NctcA2sRy1-J4OmIQZbYFPM17piNcbdBPH2ncX2RL8";
23
+ export declare const IO_DEVNET_PROCESS_ID = "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc";
23
24
  export declare const ioDevnetProcessId = "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc";
25
+ export declare const IO_TESTNET_PROCESS_ID = "agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA";
24
26
  export declare const MIO_PER_IO = 1000000;
25
- export declare const AOS_MODULE_ID = "9afQ1PLf2mrshqCTZEzzJTR2gWaC9zNPnYgYEqg1Pt4";
26
- export declare const ANT_LUA_ID = "obPBMsBWmG5q2qODj3y-zdKiuhZaJC_nuBaQRvORKkU";
27
+ export declare const AOS_MODULE_ID = "cbn0KKrBZH7hdNkNokuXLtGryrWM--PjSTBqIzw9Kkk";
28
+ export declare const ANT_LUA_ID = "3OlGzE5mrsN2GsxCYM0Tae1KzWepGOr5a94deOWmApM";
27
29
  export declare const DEFAULT_SCHEDULER_ID = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA";
package/lib/types/io.d.ts CHANGED
@@ -31,8 +31,6 @@ export type ProcessConfiguration = {
31
31
  processId?: string;
32
32
  };
33
33
  export type EpochInput = {
34
- blockHeight: BlockHeight;
35
- } | {
36
34
  epochIndex: AoEpochIndex;
37
35
  } | {
38
36
  timestamp: Timestamp;
@@ -58,6 +56,13 @@ export interface AOContract {
58
56
  }>;
59
57
  }
60
58
  export interface AoIORead {
59
+ getInfo(): Promise<{
60
+ Ticker: string;
61
+ Name: string;
62
+ Logo: string;
63
+ Denomination: number;
64
+ }>;
65
+ getEpochSettings(params?: EpochInput): Promise<AoEpochSettings>;
61
66
  getGateway({ address, }: {
62
67
  address: WalletAddress;
63
68
  }): Promise<AoGateway | undefined>;
@@ -81,7 +86,7 @@ export interface AoIORead {
81
86
  getObservations(epoch?: EpochInput): Promise<EpochObservations>;
82
87
  getDistributions(epoch?: EpochInput): Promise<EpochDistributionData>;
83
88
  getTokenCost({ intent, purchaseType, years, name, quantity, }: {
84
- intent: 'BuyRecord' | 'ExtendLease' | 'IncreaseUndernameLimit';
89
+ intent: 'Buy-Record' | 'Extend-Lease' | 'Increase-Undername-Limit';
85
90
  purchaseType?: 'permabuy' | 'lease';
86
91
  years?: number;
87
92
  name?: string;
@@ -134,6 +139,7 @@ export interface AoIOWrite extends AoIORead {
134
139
  }, options?: WriteOptions): Promise<AoMessageResult>;
135
140
  }
136
141
  export interface AoANTRead {
142
+ getState(): Promise<AoANTState>;
137
143
  getInfo(): Promise<{
138
144
  Name: string;
139
145
  Ticker: string;
@@ -208,6 +214,14 @@ export type AoArNSLeaseData = AoArNSBaseNameData & {
208
214
  type: 'lease';
209
215
  endTimestamp: number;
210
216
  };
217
+ export type AoEpochSettings = {
218
+ epochZeroStartTimestamp: Timestamp;
219
+ durationMs: number;
220
+ prescribedNameCount: number;
221
+ rewardPercentage: number;
222
+ maxObservers: number;
223
+ distributionDelayMs: number;
224
+ };
211
225
  export type AoEpochData = {
212
226
  epochIndex: AoEpochIndex;
213
227
  startHeight: BlockHeight;
@@ -244,3 +258,15 @@ export type AoGateway = {
244
258
  operatorStake: number;
245
259
  status: 'joined' | 'leaving';
246
260
  };
261
+ export type AoANTState = {
262
+ Name: string;
263
+ Ticker: string;
264
+ Denomination: number;
265
+ Owner: WalletAddress;
266
+ Controllers: WalletAddress[];
267
+ Records: Record<string, ANTRecord>;
268
+ Balances: Record<WalletAddress, number>;
269
+ Logo: string;
270
+ TotalSupply: number;
271
+ Initialized: boolean;
272
+ };
@@ -1,5 +1,35 @@
1
+ /**
2
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ import { EventEmitter } from 'eventemitter3';
1
18
  import { AoIORead, ProcessId, WalletAddress } from '../../types.js';
2
19
  export declare const getANTProcessesOwnedByWallet: ({ address, contract, }: {
3
20
  address: WalletAddress;
4
21
  contract?: AoIORead;
5
22
  }) => Promise<ProcessId[]>;
23
+ export declare class ArNSEventEmitter extends EventEmitter {
24
+ protected contract: AoIORead;
25
+ private timeoutMs;
26
+ private throttle;
27
+ constructor({ contract, timeoutMs, concurrency, }: {
28
+ contract?: AoIORead;
29
+ timeoutMs?: number;
30
+ concurrency?: number;
31
+ });
32
+ fetchProcessesOwnedByWallet({ address }: {
33
+ address: WalletAddress;
34
+ }): Promise<void>;
35
+ }
@@ -19,3 +19,4 @@ export * from './http-client.js';
19
19
  export * from './smartweave.js';
20
20
  export * from './graphql/index.js';
21
21
  export * from './ao.js';
22
+ export * from './json.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+ export declare function safeDecode<R = unknown>(data: any): R;
@@ -14,4 +14,4 @@
14
14
  * You should have received a copy of the GNU Affero General Public License
15
15
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
- export declare const version = "1.2.0-alpha.8";
17
+ export declare const version = "1.2.0-alpha.21";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "1.2.0-alpha.9",
3
+ "version": "1.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"
@@ -68,7 +68,12 @@
68
68
  "format": "prettier --check .",
69
69
  "format:fix": "prettier --write .",
70
70
  "test": "yarn test:unit && yarn test:integration",
71
+ "test:cjs": "cd ./tests/e2e/cjs && yarn && yarn test",
72
+ "test:esm": "cd ./tests/e2e/esm && yarn && yarn test",
73
+ "test:web": "cd ./tests/e2e/web && yarn && yarn test",
71
74
  "test:unit": "jest --config=jest.config.mjs",
75
+ "test:link": "yarn build && yarn link",
76
+ "test:e2e": "yarn test:link && yarn test:cjs && yarn test:esm && yarn test:web",
72
77
  "test:integration": "jest --config=jest.integration.config.mjs --runInBand",
73
78
  "test:docker": "docker-compose up --exit-code-from test-runner --build",
74
79
  "prepare": "husky install",
@@ -123,6 +128,7 @@
123
128
  "axios": "1.7.2",
124
129
  "axios-retry": "^4.3.0",
125
130
  "bunyan": "^1.8.15",
131
+ "eventemitter3": "^5.0.1",
126
132
  "plimit-lit": "^3.0.1",
127
133
  "warp-contracts": "1.4.45"
128
134
  },