@ar.io/sdk 1.2.0-alpha.8 → 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.
- package/README.md +362 -634
- package/bundles/web.bundle.min.js +83 -83
- package/lib/cjs/common/ant-ao.js +11 -4
- package/lib/cjs/common/contracts/ao-process.js +16 -5
- package/lib/cjs/common/io.js +121 -97
- package/lib/cjs/constants.js +7 -4
- package/lib/cjs/utils/ao.js +1 -1
- package/lib/cjs/utils/graphql/processes.js +87 -7
- package/lib/cjs/utils/index.js +1 -0
- package/lib/cjs/utils/json.js +28 -0
- package/lib/cjs/version.js +1 -1
- package/lib/esm/common/ant-ao.js +11 -4
- package/lib/esm/common/contracts/ao-process.js +16 -5
- package/lib/esm/common/io.js +121 -97
- package/lib/esm/constants.js +6 -3
- package/lib/esm/utils/ao.js +1 -1
- package/lib/esm/utils/graphql/processes.js +85 -6
- package/lib/esm/utils/index.js +1 -0
- package/lib/esm/utils/json.js +24 -0
- package/lib/esm/version.js +1 -1
- package/lib/types/common/ant-ao.d.ts +2 -1
- package/lib/types/common/io.d.ts +24 -1
- package/lib/types/constants.d.ts +4 -2
- package/lib/types/io.d.ts +35 -2
- package/lib/types/utils/ao.d.ts +5 -5
- package/lib/types/utils/graphql/processes.d.ts +30 -0
- package/lib/types/utils/index.d.ts +1 -0
- package/lib/types/utils/json.d.ts +17 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +7 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getANTProcessesOwnedByWallet = void 0;
|
|
3
|
+
exports.ArNSEventEmitter = exports.getANTProcessesOwnedByWallet = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
|
|
6
6
|
*
|
|
@@ -17,15 +17,15 @@ exports.getANTProcessesOwnedByWallet = void 0;
|
|
|
17
17
|
* You should have received a copy of the GNU Affero General Public License
|
|
18
18
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
|
+
const eventemitter3_1 = require("eventemitter3");
|
|
20
21
|
const plimit_lit_1 = require("plimit-lit");
|
|
21
22
|
const ant_js_1 = require("../../common/ant.js");
|
|
22
23
|
const io_js_1 = require("../../common/io.js");
|
|
23
24
|
const constants_js_1 = require("../../constants.js");
|
|
24
|
-
// throttle the requests to avoid rate limiting
|
|
25
|
-
const throttle = (0, plimit_lit_1.pLimit)(50);
|
|
26
25
|
const getANTProcessesOwnedByWallet = async ({ address, contract = io_js_1.IO.init({
|
|
27
26
|
processId: constants_js_1.ioDevnetProcessId,
|
|
28
27
|
}), }) => {
|
|
28
|
+
const throttle = (0, plimit_lit_1.pLimit)(50);
|
|
29
29
|
// get the record names of the registry - TODO: this may need to be paginated
|
|
30
30
|
const uniqueContractProcessIds = await contract
|
|
31
31
|
.getArNSRecords()
|
|
@@ -33,15 +33,95 @@ const getANTProcessesOwnedByWallet = async ({ address, contract = io_js_1.IO.ini
|
|
|
33
33
|
.filter((record) => record.processId !== undefined)
|
|
34
34
|
.map((record) => record.processId));
|
|
35
35
|
// check the contract owner and controllers
|
|
36
|
-
const ownedOrControlledByWallet = await Promise.all(uniqueContractProcessIds.
|
|
36
|
+
const ownedOrControlledByWallet = await Promise.all(uniqueContractProcessIds.map(async (processId) => throttle(async () => {
|
|
37
37
|
const ant = ant_js_1.ANT.init({
|
|
38
38
|
processId,
|
|
39
39
|
});
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
const { Owner, Controllers } = await ant.getState();
|
|
41
|
+
if (Owner === address || Controllers.includes(address)) {
|
|
42
|
+
return processId;
|
|
43
|
+
}
|
|
44
|
+
return;
|
|
43
45
|
})));
|
|
46
|
+
if (ownedOrControlledByWallet.length === 0) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
44
49
|
// TODO: insert gql query to find ANT processes owned by wallet given wallet not currently in the registry
|
|
45
50
|
return [...new Set(ownedOrControlledByWallet)];
|
|
46
51
|
};
|
|
47
52
|
exports.getANTProcessesOwnedByWallet = getANTProcessesOwnedByWallet;
|
|
53
|
+
function timeout(ms, promise) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const timer = setTimeout(() => {
|
|
56
|
+
reject(new Error('Timeout'));
|
|
57
|
+
}, ms);
|
|
58
|
+
promise
|
|
59
|
+
.then((value) => {
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
resolve(value);
|
|
62
|
+
})
|
|
63
|
+
.catch((err) => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
reject(err);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
class ArNSEventEmitter extends eventemitter3_1.EventEmitter {
|
|
70
|
+
contract;
|
|
71
|
+
timeoutMs; // timeout for each request to 3 seconds
|
|
72
|
+
throttle;
|
|
73
|
+
constructor({ contract = io_js_1.IO.init({
|
|
74
|
+
processId: constants_js_1.ioDevnetProcessId,
|
|
75
|
+
}), timeoutMs = 60_000, concurrency = 30, }) {
|
|
76
|
+
super();
|
|
77
|
+
this.contract = contract;
|
|
78
|
+
this.timeoutMs = timeoutMs;
|
|
79
|
+
this.throttle = (0, plimit_lit_1.pLimit)(concurrency);
|
|
80
|
+
}
|
|
81
|
+
async fetchProcessesOwnedByWallet({ address }) {
|
|
82
|
+
const uniqueContractProcessIds = {};
|
|
83
|
+
await timeout(this.timeoutMs, this.contract.getArNSRecords().catch((e) => {
|
|
84
|
+
this.emit('error', `Error getting ArNS records: ${e}`);
|
|
85
|
+
return {};
|
|
86
|
+
})).then((records) => {
|
|
87
|
+
if (!records)
|
|
88
|
+
return;
|
|
89
|
+
Object.entries(records).forEach(([name, record]) => {
|
|
90
|
+
if (record.processId === undefined) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (uniqueContractProcessIds[record.processId] === undefined) {
|
|
94
|
+
uniqueContractProcessIds[record.processId] = {
|
|
95
|
+
state: undefined,
|
|
96
|
+
names: {},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
uniqueContractProcessIds[record.processId].names[name] = record;
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
const idCount = Object.keys(uniqueContractProcessIds).length;
|
|
103
|
+
// check the contract owner and controllers
|
|
104
|
+
this.emit('progress', 0, idCount);
|
|
105
|
+
await Promise.all(Object.keys(uniqueContractProcessIds).map(async (processId, i) => this.throttle(async () => {
|
|
106
|
+
if (uniqueContractProcessIds[processId].state !== undefined) {
|
|
107
|
+
this.emit('progress', i + 1, idCount);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const ant = ant_js_1.ANT.init({
|
|
111
|
+
processId,
|
|
112
|
+
});
|
|
113
|
+
const state = (await timeout(this.timeoutMs, ant.getState()).catch((e) => {
|
|
114
|
+
this.emit('error', `Error getting state for process ${processId}: ${e}`);
|
|
115
|
+
return undefined;
|
|
116
|
+
}));
|
|
117
|
+
if (state?.Owner === address ||
|
|
118
|
+
state?.Controllers.includes(address)) {
|
|
119
|
+
uniqueContractProcessIds[processId].state = state;
|
|
120
|
+
this.emit('process', processId, uniqueContractProcessIds[processId]);
|
|
121
|
+
}
|
|
122
|
+
this.emit('progress', i + 1, idCount);
|
|
123
|
+
})));
|
|
124
|
+
this.emit('end', uniqueContractProcessIds);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.ArNSEventEmitter = ArNSEventEmitter;
|
package/lib/cjs/utils/index.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.safeDecode = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* This program is free software: you can redistribute it and/or modify
|
|
8
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
9
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
* (at your option) any later version.
|
|
11
|
+
*
|
|
12
|
+
* This program is distributed in the hope that it will be useful,
|
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
* GNU Affero General Public License for more details.
|
|
16
|
+
*
|
|
17
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
18
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
*/
|
|
20
|
+
function safeDecode(data) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(data);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.safeDecode = safeDecode;
|
package/lib/cjs/version.js
CHANGED
package/lib/esm/common/ant-ao.js
CHANGED
|
@@ -16,6 +16,13 @@ export class AoANTReadable {
|
|
|
16
16
|
throw new InvalidContractConfigurationError();
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
async getState() {
|
|
20
|
+
const tags = [{ name: 'Action', value: 'State' }];
|
|
21
|
+
const res = await this.process.read({
|
|
22
|
+
tags,
|
|
23
|
+
});
|
|
24
|
+
return res;
|
|
25
|
+
}
|
|
19
26
|
async getInfo() {
|
|
20
27
|
const tags = [{ name: 'Action', value: 'Info' }];
|
|
21
28
|
const info = await this.process.read({
|
|
@@ -35,7 +42,7 @@ export class AoANTReadable {
|
|
|
35
42
|
async getRecord({ undername }) {
|
|
36
43
|
const tags = [
|
|
37
44
|
{ name: 'Sub-Domain', value: undername },
|
|
38
|
-
{ name: 'Action', value: '
|
|
45
|
+
{ name: 'Action', value: 'Record' },
|
|
39
46
|
];
|
|
40
47
|
const record = await this.process.read({
|
|
41
48
|
tags,
|
|
@@ -51,7 +58,7 @@ export class AoANTReadable {
|
|
|
51
58
|
* ````
|
|
52
59
|
*/
|
|
53
60
|
async getRecords() {
|
|
54
|
-
const tags = [{ name: 'Action', value: '
|
|
61
|
+
const tags = [{ name: 'Action', value: 'Records' }];
|
|
55
62
|
const records = await this.process.read({
|
|
56
63
|
tags,
|
|
57
64
|
});
|
|
@@ -78,7 +85,7 @@ export class AoANTReadable {
|
|
|
78
85
|
* ```
|
|
79
86
|
*/
|
|
80
87
|
async getControllers() {
|
|
81
|
-
const tags = [{ name: 'Action', value: '
|
|
88
|
+
const tags = [{ name: 'Action', value: 'Controllers' }];
|
|
82
89
|
const controllers = await this.process.read({
|
|
83
90
|
tags,
|
|
84
91
|
});
|
|
@@ -178,7 +185,7 @@ export class AoANTWriteable extends AoANTReadable {
|
|
|
178
185
|
*/
|
|
179
186
|
async addController({ controller, }) {
|
|
180
187
|
const tags = [
|
|
181
|
-
{ name: 'Action', value: '
|
|
188
|
+
{ name: 'Action', value: 'Add-Controller' },
|
|
182
189
|
{ name: 'Controller', value: controller },
|
|
183
190
|
];
|
|
184
191
|
return this.process.send({
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { connect } from '@permaweb/aoconnect';
|
|
18
18
|
import { createData } from 'arbundles';
|
|
19
|
+
import { safeDecode } from '../../utils/json.js';
|
|
19
20
|
import { version } from '../../version.js';
|
|
20
21
|
import { WriteInteractionError } from '../error.js';
|
|
21
22
|
import { DefaultLogger } from '../logger.js';
|
|
@@ -57,18 +58,22 @@ export class AOProcess {
|
|
|
57
58
|
process: this.processId,
|
|
58
59
|
tags,
|
|
59
60
|
});
|
|
61
|
+
if (result.Messages.length === 0) {
|
|
62
|
+
throw new Error(`Process ${this.processId} does not support provided action.`);
|
|
63
|
+
}
|
|
60
64
|
const tagsOutput = result.Messages[0].Tags;
|
|
61
65
|
const error = tagsOutput.find((tag) => tag.name === 'Error');
|
|
62
66
|
if (error) {
|
|
63
67
|
throw new Error(`${error.Value}: ${result.Messages[0].Data}`);
|
|
64
68
|
}
|
|
65
|
-
if (result.Messages.length === 0) {
|
|
66
|
-
throw new Error('Process does not support provided action.');
|
|
67
|
-
}
|
|
68
69
|
this.logger.debug(`Read interaction result`, {
|
|
69
70
|
result: result.Messages[0].Data,
|
|
70
71
|
});
|
|
71
|
-
|
|
72
|
+
// return empty object if no data is returned
|
|
73
|
+
if (result.Messages[0].Data === undefined) {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
const response = safeDecode(result.Messages[0].Data);
|
|
72
77
|
return response;
|
|
73
78
|
}
|
|
74
79
|
catch (e) {
|
|
@@ -128,7 +133,13 @@ export class AOProcess {
|
|
|
128
133
|
const result = output.Messages[0].Data;
|
|
129
134
|
throw new WriteInteractionError(`${error.Value}: ${result}`);
|
|
130
135
|
}
|
|
131
|
-
|
|
136
|
+
if (output.Messages.length === 0) {
|
|
137
|
+
throw new Error(`Process ${this.processId} does not support provided action.`);
|
|
138
|
+
}
|
|
139
|
+
if (output.Messages[0].Data === undefined) {
|
|
140
|
+
return { id: messageId };
|
|
141
|
+
}
|
|
142
|
+
const resultData = safeDecode(output.Messages[0].Data);
|
|
132
143
|
this.logger.debug('Message result data', {
|
|
133
144
|
resultData,
|
|
134
145
|
messageId,
|