@ar.io/sdk 3.2.0 → 3.3.0-alpha.10
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 +46 -0
- package/bundles/web.bundle.min.js +87 -65
- package/lib/cjs/cli/cli.js +26 -2
- package/lib/cjs/cli/commands/readCommands.js +6 -1
- package/lib/cjs/common/ant-registry.js +14 -21
- package/lib/cjs/common/ant.js +5 -8
- package/lib/cjs/common/contracts/ao-process.js +28 -21
- package/lib/cjs/common/io.js +59 -37
- package/lib/cjs/constants.js +2 -2
- package/lib/cjs/utils/ao.js +36 -22
- package/lib/cjs/utils/arweave.js +51 -16
- package/lib/cjs/version.js +1 -1
- package/lib/esm/cli/cli.js +29 -5
- package/lib/esm/cli/commands/readCommands.js +4 -0
- package/lib/esm/common/ant-registry.js +14 -21
- package/lib/esm/common/ant.js +5 -8
- package/lib/esm/common/contracts/ao-process.js +28 -21
- package/lib/esm/common/io.js +60 -38
- package/lib/esm/constants.js +2 -2
- package/lib/esm/utils/ao.js +35 -22
- package/lib/esm/utils/arweave.js +49 -16
- package/lib/esm/version.js +1 -1
- package/lib/types/cli/commands/readCommands.d.ts +3 -0
- package/lib/types/common/ant-registry.d.ts +5 -4
- package/lib/types/common/ant.d.ts +9 -10
- package/lib/types/common/contracts/ao-process.d.ts +1 -1
- package/lib/types/common/io.d.ts +31 -27
- package/lib/types/constants.d.ts +2 -2
- package/lib/types/types/common.d.ts +4 -0
- package/lib/types/types/io.d.ts +25 -15
- package/lib/types/utils/ao.d.ts +13 -3
- package/lib/types/utils/arweave.d.ts +31 -1
- package/lib/types/version.d.ts +1 -1
- package/package.json +2 -2
package/lib/esm/cli/cli.js
CHANGED
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
*/
|
|
17
17
|
// eslint-disable-next-line header/header -- This is a CLI file
|
|
18
18
|
import { program } from 'commander';
|
|
19
|
-
import { spawnANT } from '../node/index.js';
|
|
19
|
+
import { AOProcess, spawnANT } from '../node/index.js';
|
|
20
20
|
import { mARIOToken } from '../types/token.js';
|
|
21
21
|
import { version } from '../version.js';
|
|
22
22
|
import { buyRecordCLICommand, extendLeaseCLICommand, increaseUndernameLimitCLICommand, requestPrimaryNameCLICommand, upgradeRecordCLICommand, } from './commands/arnsPurchaseCommands.js';
|
|
23
23
|
import { cancelWithdrawal, decreaseDelegateStake, decreaseOperatorStake, delegateStake, increaseOperatorStake, instantWithdrawal, joinNetwork, leaveNetwork, redelegateStake, saveObservations, updateGatewaySettings, } from './commands/gatewayWriteCommands.js';
|
|
24
|
-
import { getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listArNSRecords, listArNSReservedNames, listArNSReturnedNames, listGateways, } from './commands/readCommands.js';
|
|
24
|
+
import { getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listAllDelegatesCLICommand, listArNSRecords, listArNSReservedNames, listArNSReturnedNames, listGateways, } from './commands/readCommands.js';
|
|
25
25
|
import { transfer } from './commands/transfer.js';
|
|
26
26
|
import { addressAndVaultIdOptions, antStateOptions, arnsPurchaseOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, joinNetworkOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, writeActionOptions, } from './options.js';
|
|
27
|
-
import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeActionTagsFromOptions, } from './utils.js';
|
|
27
|
+
import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredProcessIdFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeActionTagsFromOptions, } from './utils.js';
|
|
28
28
|
applyOptions(program
|
|
29
29
|
.name('ar.io')
|
|
30
30
|
.version(version)
|
|
@@ -62,6 +62,12 @@ makeCommand({
|
|
|
62
62
|
options: paginationOptions,
|
|
63
63
|
action: listGateways,
|
|
64
64
|
});
|
|
65
|
+
makeCommand({
|
|
66
|
+
name: 'list-all-delegates',
|
|
67
|
+
description: 'List all paginated delegates from all gateways',
|
|
68
|
+
options: paginationOptions,
|
|
69
|
+
action: listAllDelegatesCLICommand,
|
|
70
|
+
});
|
|
65
71
|
makeCommand({
|
|
66
72
|
name: 'get-gateway-delegates',
|
|
67
73
|
description: 'Get the delegates of a gateway',
|
|
@@ -143,13 +149,17 @@ makeCommand({
|
|
|
143
149
|
name: 'get-observations',
|
|
144
150
|
description: 'Get observations for an epoch',
|
|
145
151
|
options: epochOptions,
|
|
146
|
-
action: (o) => readARIOFromOptions(o)
|
|
152
|
+
action: (o) => readARIOFromOptions(o)
|
|
153
|
+
.getObservations(epochInputFromOptions(o))
|
|
154
|
+
.then((result) => result ?? { message: 'No observations found for epoch' }),
|
|
147
155
|
});
|
|
148
156
|
makeCommand({
|
|
149
157
|
name: 'get-distributions',
|
|
150
158
|
description: 'Get distributions for an epoch',
|
|
151
159
|
options: epochOptions,
|
|
152
|
-
action: (o) => readARIOFromOptions(o)
|
|
160
|
+
action: (o) => readARIOFromOptions(o)
|
|
161
|
+
.getDistributions(epochInputFromOptions(o))
|
|
162
|
+
.then((result) => result ?? { message: 'No distributions found for epoch' }),
|
|
153
163
|
});
|
|
154
164
|
makeCommand({
|
|
155
165
|
name: 'get-token-cost',
|
|
@@ -652,6 +662,20 @@ makeCommand({
|
|
|
652
662
|
}, writeActionTagsFromOptions(options));
|
|
653
663
|
},
|
|
654
664
|
});
|
|
665
|
+
makeCommand({
|
|
666
|
+
name: 'write-action',
|
|
667
|
+
description: 'Send a write action to an AO Process',
|
|
668
|
+
options: [...writeActionOptions, optionMap.processId],
|
|
669
|
+
action: async (options) => {
|
|
670
|
+
const process = new AOProcess({
|
|
671
|
+
processId: requiredProcessIdFromOptions(options),
|
|
672
|
+
});
|
|
673
|
+
return process.send({
|
|
674
|
+
tags: writeActionTagsFromOptions(options).tags ?? [],
|
|
675
|
+
signer: requiredAoSignerFromOptions(options),
|
|
676
|
+
});
|
|
677
|
+
},
|
|
678
|
+
});
|
|
655
679
|
if (process.argv[1].includes('bin/ar.io') || // Running from global .bin
|
|
656
680
|
process.argv[1].includes('cli/cli') // Running from source
|
|
657
681
|
) {
|
|
@@ -11,6 +11,10 @@ export async function listGateways(o) {
|
|
|
11
11
|
const gateways = await readARIOFromOptions(o).getGateways(paginationParamsFromOptions(o));
|
|
12
12
|
return gateways.items.length ? gateways : { message: 'No gateways found' };
|
|
13
13
|
}
|
|
14
|
+
export async function listAllDelegatesCLICommand(o) {
|
|
15
|
+
const delegates = await readARIOFromOptions(o).getAllDelegates(paginationParamsFromOptions(o));
|
|
16
|
+
return delegates.items.length ? delegates : { message: 'No delegates found' };
|
|
17
|
+
}
|
|
14
18
|
export async function getGatewayDelegates(o) {
|
|
15
19
|
const address = requiredAddressFromOptions(o);
|
|
16
20
|
const result = await readARIOFromOptions(o).getGatewayDelegates({
|
|
@@ -19,12 +19,8 @@ import { createAoSigner } from '../utils/ao.js';
|
|
|
19
19
|
import { AOProcess, InvalidContractConfigurationError } from './index.js';
|
|
20
20
|
export class ANTRegistry {
|
|
21
21
|
static init(config) {
|
|
22
|
-
if (config && config
|
|
23
|
-
|
|
24
|
-
return new AoANTRegistryWriteable({
|
|
25
|
-
...rest,
|
|
26
|
-
signer,
|
|
27
|
-
});
|
|
22
|
+
if (config !== undefined && 'signer' in config) {
|
|
23
|
+
return new AoANTRegistryWriteable(config);
|
|
28
24
|
}
|
|
29
25
|
return new AoANTRegistryReadable(config);
|
|
30
26
|
}
|
|
@@ -32,25 +28,22 @@ export class ANTRegistry {
|
|
|
32
28
|
export class AoANTRegistryReadable {
|
|
33
29
|
process;
|
|
34
30
|
constructor(config) {
|
|
35
|
-
if (config
|
|
36
|
-
(isProcessIdConfiguration(config) || isProcessConfiguration(config))) {
|
|
37
|
-
if (isProcessConfiguration(config)) {
|
|
38
|
-
this.process = config.process;
|
|
39
|
-
}
|
|
40
|
-
else if (isProcessIdConfiguration(config)) {
|
|
41
|
-
this.process = new AOProcess({
|
|
42
|
-
processId: config.processId,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
throw new InvalidContractConfigurationError();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
31
|
+
if (config === undefined || Object.keys(config).length === 0) {
|
|
50
32
|
this.process = new AOProcess({
|
|
51
33
|
processId: ANT_REGISTRY_ID,
|
|
52
34
|
});
|
|
53
35
|
}
|
|
36
|
+
else if (isProcessConfiguration(config)) {
|
|
37
|
+
this.process = config.process;
|
|
38
|
+
}
|
|
39
|
+
else if (isProcessIdConfiguration(config)) {
|
|
40
|
+
this.process = new AOProcess({
|
|
41
|
+
processId: config.processId,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new InvalidContractConfigurationError();
|
|
46
|
+
}
|
|
54
47
|
}
|
|
55
48
|
// Should we rename this to "getANTsByAddress"? seems more clear, though not same as handler name
|
|
56
49
|
async accessControlList({ address, }) {
|
package/lib/esm/common/ant.js
CHANGED
|
@@ -20,15 +20,12 @@ import { createAoSigner } from '../utils/ao.js';
|
|
|
20
20
|
import { parseSchemaResult } from '../utils/schema.js';
|
|
21
21
|
import { AOProcess, InvalidContractConfigurationError } from './index.js';
|
|
22
22
|
export class ANT {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
return new AoANTReadable({ strict, ...config });
|
|
28
|
-
}
|
|
29
|
-
return new AoANTWriteable({ signer, strict, ...config });
|
|
23
|
+
// implementation
|
|
24
|
+
static init(config) {
|
|
25
|
+
if (config !== undefined && 'signer' in config) {
|
|
26
|
+
return new AoANTWriteable(config);
|
|
30
27
|
}
|
|
31
|
-
|
|
28
|
+
return new AoANTReadable(config);
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
31
|
export class AoANTReadable {
|
|
@@ -21,8 +21,8 @@ import { WriteInteractionError } from '../error.js';
|
|
|
21
21
|
import { Logger } from '../logger.js';
|
|
22
22
|
export class AOProcess {
|
|
23
23
|
logger;
|
|
24
|
-
processId;
|
|
25
24
|
ao;
|
|
25
|
+
processId;
|
|
26
26
|
constructor({ processId, ao = connect(), logger = Logger.default, }) {
|
|
27
27
|
this.processId = processId;
|
|
28
28
|
this.logger = logger;
|
|
@@ -39,8 +39,9 @@ export class AOProcess {
|
|
|
39
39
|
let lastError;
|
|
40
40
|
while (attempts < retries) {
|
|
41
41
|
try {
|
|
42
|
-
this.logger.debug(`Evaluating read interaction on
|
|
42
|
+
this.logger.debug(`Evaluating read interaction on process`, {
|
|
43
43
|
tags,
|
|
44
|
+
processId: this.processId,
|
|
44
45
|
});
|
|
45
46
|
// map tags to inputs
|
|
46
47
|
const dryRunInput = {
|
|
@@ -53,13 +54,18 @@ export class AOProcess {
|
|
|
53
54
|
const result = await this.ao.dryrun(dryRunInput);
|
|
54
55
|
this.logger.debug(`Read interaction result`, {
|
|
55
56
|
result,
|
|
57
|
+
processId: this.processId,
|
|
56
58
|
});
|
|
57
59
|
const error = errorMessageFromOutput(result);
|
|
58
60
|
if (error !== undefined) {
|
|
59
61
|
throw new Error(error);
|
|
60
62
|
}
|
|
61
63
|
if (result.Messages === undefined || result.Messages.length === 0) {
|
|
62
|
-
this.logger.debug(`Process ${this.processId} does not support provided action.`,
|
|
64
|
+
this.logger.debug(`Process ${this.processId} does not support provided action.`, {
|
|
65
|
+
result,
|
|
66
|
+
tags,
|
|
67
|
+
processId: this.processId,
|
|
68
|
+
});
|
|
63
69
|
throw new Error(`Process ${this.processId} does not support provided action.`);
|
|
64
70
|
}
|
|
65
71
|
const messageData = result.Messages?.[0]?.Data;
|
|
@@ -67,16 +73,18 @@ export class AOProcess {
|
|
|
67
73
|
if (this.isMessageDataEmpty(messageData)) {
|
|
68
74
|
return undefined;
|
|
69
75
|
}
|
|
70
|
-
const response = safeDecode(
|
|
76
|
+
const response = safeDecode(messageData);
|
|
71
77
|
return response;
|
|
72
78
|
}
|
|
73
|
-
catch (
|
|
79
|
+
catch (error) {
|
|
74
80
|
attempts++;
|
|
75
81
|
this.logger.debug(`Read attempt ${attempts} failed`, {
|
|
76
|
-
error:
|
|
82
|
+
error: error?.message,
|
|
83
|
+
stack: error?.stack,
|
|
77
84
|
tags,
|
|
85
|
+
processId: this.processId,
|
|
78
86
|
});
|
|
79
|
-
lastError =
|
|
87
|
+
lastError = error;
|
|
80
88
|
// exponential backoff
|
|
81
89
|
await new Promise((resolve) => setTimeout(resolve, 2 ** attempts * 1000));
|
|
82
90
|
}
|
|
@@ -144,16 +152,17 @@ export class AOProcess {
|
|
|
144
152
|
}
|
|
145
153
|
catch (error) {
|
|
146
154
|
this.logger.error('Error sending message to process', {
|
|
147
|
-
error: error
|
|
155
|
+
error: error?.message,
|
|
156
|
+
stack: error?.stack,
|
|
148
157
|
processId: this.processId,
|
|
149
158
|
tags,
|
|
150
159
|
});
|
|
151
|
-
// throw on write interaction errors. No point retrying
|
|
160
|
+
// throw on write interaction errors. No point retrying write interactions, waste of gas.
|
|
152
161
|
if (error.message.includes('500')) {
|
|
153
162
|
this.logger.debug('Retrying send interaction', {
|
|
154
163
|
attempts,
|
|
155
164
|
retries,
|
|
156
|
-
error: error
|
|
165
|
+
error: error?.message,
|
|
157
166
|
processId: this.processId,
|
|
158
167
|
});
|
|
159
168
|
// exponential backoff
|
|
@@ -170,18 +179,16 @@ export class AOProcess {
|
|
|
170
179
|
}
|
|
171
180
|
function errorMessageFromOutput(output) {
|
|
172
181
|
const errorData = output.Error;
|
|
173
|
-
if
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return errorData;
|
|
177
|
-
}
|
|
178
|
-
const error = output.Messages?.[0]?.Tags?.find((tag) => tag.name === 'Error')?.value;
|
|
182
|
+
// Attempt to extract error details from Messages.Tags if Error is undefined
|
|
183
|
+
const error = errorData ??
|
|
184
|
+
output.Messages?.[0]?.Tags?.find((tag) => tag.name === 'Error')?.value;
|
|
179
185
|
if (error !== undefined) {
|
|
180
|
-
//
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
186
|
+
// Consolidated regex to match and extract line number and AO error message or Error Tags
|
|
187
|
+
const match = error.match(/\[string "aos"]:(\d+):\s*(.+)/);
|
|
188
|
+
if (match) {
|
|
189
|
+
const [, lineNumber, errorMessage] = match;
|
|
190
|
+
return `${errorMessage.trim()} (line ${lineNumber.trim()})`.trim();
|
|
191
|
+
}
|
|
185
192
|
}
|
|
186
193
|
return undefined;
|
|
187
194
|
}
|
package/lib/esm/common/io.js
CHANGED
|
@@ -1,32 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
1
|
import { ARIO_TESTNET_PROCESS_ID } from '../constants.js';
|
|
17
2
|
import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/io.js';
|
|
18
3
|
import { createAoSigner } from '../utils/ao.js';
|
|
19
|
-
import { paginationParamsToTags, pruneTags } from '../utils/arweave.js';
|
|
4
|
+
import { getEpochDataFromGql, paginationParamsToTags, pruneTags, } from '../utils/arweave.js';
|
|
5
|
+
import { defaultArweave } from './arweave.js';
|
|
20
6
|
import { AOProcess } from './contracts/ao-process.js';
|
|
21
7
|
import { InvalidContractConfigurationError } from './error.js';
|
|
22
8
|
export class ARIO {
|
|
9
|
+
// Implementation
|
|
23
10
|
static init(config) {
|
|
24
|
-
if (config && config
|
|
25
|
-
|
|
26
|
-
return new ARIOWriteable({
|
|
27
|
-
...rest,
|
|
28
|
-
signer,
|
|
29
|
-
});
|
|
11
|
+
if (config !== undefined && 'signer' in config) {
|
|
12
|
+
return new ARIOWriteable(config);
|
|
30
13
|
}
|
|
31
14
|
return new ARIOReadable(config);
|
|
32
15
|
}
|
|
@@ -34,8 +17,10 @@ export class ARIO {
|
|
|
34
17
|
export class ARIOReadable {
|
|
35
18
|
process;
|
|
36
19
|
epochSettings;
|
|
20
|
+
arweave;
|
|
37
21
|
constructor(config) {
|
|
38
|
-
|
|
22
|
+
this.arweave = config?.arweave ?? defaultArweave;
|
|
23
|
+
if (config === undefined || Object.keys(config).length === 0) {
|
|
39
24
|
this.process = new AOProcess({
|
|
40
25
|
processId: ARIO_TESTNET_PROCESS_ID,
|
|
41
26
|
});
|
|
@@ -68,6 +53,13 @@ export class ARIOReadable {
|
|
|
68
53
|
const epochLengthMs = epochSettings.durationMs;
|
|
69
54
|
return Math.floor((timestamp - epochZeroStartTimestamp) / epochLengthMs);
|
|
70
55
|
}
|
|
56
|
+
async computeCurrentEpochIndex() {
|
|
57
|
+
const epochSettings = await this.getEpochSettings();
|
|
58
|
+
const epochZeroStartTimestamp = epochSettings.epochZeroStartTimestamp;
|
|
59
|
+
const epochLengthMs = epochSettings.durationMs;
|
|
60
|
+
const currentTimestamp = Date.now();
|
|
61
|
+
return Math.floor((currentTimestamp - epochZeroStartTimestamp) / epochLengthMs);
|
|
62
|
+
}
|
|
71
63
|
async computeEpochIndex(params) {
|
|
72
64
|
const epochIndex = params?.epochIndex;
|
|
73
65
|
if (epochIndex !== undefined) {
|
|
@@ -85,6 +77,17 @@ export class ARIOReadable {
|
|
|
85
77
|
}));
|
|
86
78
|
}
|
|
87
79
|
async getEpoch(epoch) {
|
|
80
|
+
const epochIndex = await this.computeEpochIndex(epoch);
|
|
81
|
+
const currentIndex = await this.computeCurrentEpochIndex();
|
|
82
|
+
if (epochIndex !== undefined && +epochIndex < currentIndex) {
|
|
83
|
+
const epochData = await getEpochDataFromGql({
|
|
84
|
+
arweave: this.arweave,
|
|
85
|
+
epochIndex: +epochIndex,
|
|
86
|
+
processId: this.process.processId,
|
|
87
|
+
});
|
|
88
|
+
return epochData;
|
|
89
|
+
}
|
|
90
|
+
// go to the process epoch and fetch the epoch data
|
|
88
91
|
const allTags = [
|
|
89
92
|
{ name: 'Action', value: 'Epoch' },
|
|
90
93
|
{ name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
|
|
@@ -215,7 +218,19 @@ export class ARIOReadable {
|
|
|
215
218
|
tags: pruneTags(allTags),
|
|
216
219
|
});
|
|
217
220
|
}
|
|
221
|
+
// we need to find the epoch index for the epoch that is currently being distributed and fetch it from gql
|
|
218
222
|
async getObservations(epoch) {
|
|
223
|
+
const epochIndex = await this.computeEpochIndex(epoch);
|
|
224
|
+
const currentIndex = await this.computeCurrentEpochIndex();
|
|
225
|
+
if (epochIndex !== undefined && +epochIndex < currentIndex) {
|
|
226
|
+
const epochData = await getEpochDataFromGql({
|
|
227
|
+
arweave: this.arweave,
|
|
228
|
+
epochIndex: +epochIndex,
|
|
229
|
+
processId: this.process.processId,
|
|
230
|
+
});
|
|
231
|
+
return epochData?.observations;
|
|
232
|
+
}
|
|
233
|
+
// go to the process epoch and fetch the observations
|
|
219
234
|
const allTags = [
|
|
220
235
|
{ name: 'Action', value: 'Epoch-Observations' },
|
|
221
236
|
{ name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
|
|
@@ -225,6 +240,17 @@ export class ARIOReadable {
|
|
|
225
240
|
});
|
|
226
241
|
}
|
|
227
242
|
async getDistributions(epoch) {
|
|
243
|
+
const epochIndex = await this.computeEpochIndex(epoch);
|
|
244
|
+
const currentIndex = await this.computeCurrentEpochIndex();
|
|
245
|
+
if (epochIndex !== undefined && +epochIndex < currentIndex) {
|
|
246
|
+
const epochData = await getEpochDataFromGql({
|
|
247
|
+
arweave: this.arweave,
|
|
248
|
+
epochIndex: +epochIndex,
|
|
249
|
+
processId: this.process.processId,
|
|
250
|
+
});
|
|
251
|
+
return epochData?.distributions;
|
|
252
|
+
}
|
|
253
|
+
// go to the process epoch and fetch the distributions
|
|
228
254
|
const allTags = [
|
|
229
255
|
{ name: 'Action', value: 'Epoch-Distributions' },
|
|
230
256
|
{ name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
|
|
@@ -411,33 +437,29 @@ export class ARIOReadable {
|
|
|
411
437
|
tags: [{ name: 'Action', value: 'Gateway-Registry-Settings' }],
|
|
412
438
|
});
|
|
413
439
|
}
|
|
440
|
+
async getAllDelegates(params) {
|
|
441
|
+
return this.process.read({
|
|
442
|
+
tags: [
|
|
443
|
+
{ name: 'Action', value: 'All-Paginated-Delegates' },
|
|
444
|
+
...paginationParamsToTags(params),
|
|
445
|
+
],
|
|
446
|
+
});
|
|
447
|
+
}
|
|
414
448
|
}
|
|
415
449
|
export class ARIOWriteable extends ARIOReadable {
|
|
416
450
|
signer;
|
|
417
451
|
constructor({ signer, ...config }) {
|
|
418
|
-
if (
|
|
452
|
+
if (config === undefined) {
|
|
419
453
|
super({
|
|
420
454
|
process: new AOProcess({
|
|
421
455
|
processId: ARIO_TESTNET_PROCESS_ID,
|
|
422
456
|
}),
|
|
423
457
|
});
|
|
424
|
-
this.signer = createAoSigner(signer);
|
|
425
|
-
}
|
|
426
|
-
else if (isProcessConfiguration(config)) {
|
|
427
|
-
super({ process: config.process });
|
|
428
|
-
this.signer = createAoSigner(signer);
|
|
429
|
-
}
|
|
430
|
-
else if (isProcessIdConfiguration(config)) {
|
|
431
|
-
super({
|
|
432
|
-
process: new AOProcess({
|
|
433
|
-
processId: config.processId,
|
|
434
|
-
}),
|
|
435
|
-
});
|
|
436
|
-
this.signer = createAoSigner(signer);
|
|
437
458
|
}
|
|
438
459
|
else {
|
|
439
|
-
|
|
460
|
+
super(config);
|
|
440
461
|
}
|
|
462
|
+
this.signer = createAoSigner(signer);
|
|
441
463
|
}
|
|
442
464
|
async transfer({ target, qty, }, options) {
|
|
443
465
|
const { tags = [] } = options || {};
|
package/lib/esm/constants.js
CHANGED
|
@@ -26,6 +26,6 @@ export const arioDevnetProcessId = ARIO_DEVNET_PROCESS_ID;
|
|
|
26
26
|
export const ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA';
|
|
27
27
|
export const ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
|
|
28
28
|
export const MARIO_PER_ARIO = 1_000_000;
|
|
29
|
-
export const AOS_MODULE_ID = '
|
|
30
|
-
export const ANT_LUA_ID = '
|
|
29
|
+
export const AOS_MODULE_ID = 'BRyNPIJWZaQ4IudfNnsfvMrZBO2YDPjgKqg_wCYT2U8';
|
|
30
|
+
export const ANT_LUA_ID = 'k9tQkbnFYZOGp6ist1yFuaqk_wOkzM5KUSNDtWzCLtg';
|
|
31
31
|
export const DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';
|
package/lib/esm/utils/ao.js
CHANGED
|
@@ -13,18 +13,14 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { createData } from '@dha-team/arbundles';
|
|
16
|
+
import { ArconnectSigner, DataItem, createData } from '@dha-team/arbundles';
|
|
17
17
|
import { connect, createDataItemSigner } from '@permaweb/aoconnect';
|
|
18
18
|
import { z } from 'zod';
|
|
19
19
|
import { defaultArweave } from '../common/arweave.js';
|
|
20
20
|
import { ANTRegistry, AOProcess, Logger } from '../common/index.js';
|
|
21
21
|
import { ANT_LUA_ID, ANT_REGISTRY_ID, AOS_MODULE_ID, DEFAULT_SCHEDULER_ID, } from '../constants.js';
|
|
22
|
-
export async function spawnANT({ signer, module = AOS_MODULE_ID,
|
|
23
|
-
//TODO:
|
|
24
|
-
const luaString = (await arweave.transactions.getData(luaCodeTxId, {
|
|
25
|
-
decode: true,
|
|
26
|
-
string: true,
|
|
27
|
-
}));
|
|
22
|
+
export async function spawnANT({ signer, module = AOS_MODULE_ID, ao = connect(), scheduler = DEFAULT_SCHEDULER_ID, state, stateContractTxId, antRegistryId = ANT_REGISTRY_ID, logger = Logger.default, }) {
|
|
23
|
+
// TODO: use On-Boot data handler for bootstrapping state instead of initialize-state
|
|
28
24
|
const processId = await ao.spawn({
|
|
29
25
|
module,
|
|
30
26
|
scheduler,
|
|
@@ -34,10 +30,6 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
|
|
|
34
30
|
name: 'ANT-Registry-Id',
|
|
35
31
|
value: antRegistryId,
|
|
36
32
|
},
|
|
37
|
-
{
|
|
38
|
-
name: 'Source-Code-TX-ID', // utility for understanding what the original source id of the lua code was
|
|
39
|
-
value: luaCodeTxId,
|
|
40
|
-
},
|
|
41
33
|
],
|
|
42
34
|
});
|
|
43
35
|
const aosClient = new AOProcess({
|
|
@@ -45,21 +37,10 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
|
|
|
45
37
|
ao,
|
|
46
38
|
logger,
|
|
47
39
|
});
|
|
48
|
-
const { id: evalId } = await aosClient.send({
|
|
49
|
-
tags: [
|
|
50
|
-
{ name: 'Action', value: 'Eval' },
|
|
51
|
-
{ name: 'App-Name', value: 'ArNS-ANT' },
|
|
52
|
-
{ name: 'Source-Code-TX-ID', value: luaCodeTxId },
|
|
53
|
-
],
|
|
54
|
-
data: luaString,
|
|
55
|
-
signer,
|
|
56
|
-
});
|
|
57
40
|
logger.debug(`Spawned ANT`, {
|
|
58
41
|
processId,
|
|
59
42
|
module,
|
|
60
43
|
scheduler,
|
|
61
|
-
luaCodeTxId,
|
|
62
|
-
evalId,
|
|
63
44
|
});
|
|
64
45
|
if (state) {
|
|
65
46
|
const { id: initializeMsgId } = await aosClient.send({
|
|
@@ -79,6 +60,7 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
|
|
|
79
60
|
initializeMsgId,
|
|
80
61
|
});
|
|
81
62
|
}
|
|
63
|
+
// This could be done by the ANT in On-Boot to self-register with its tagged ANT registry
|
|
82
64
|
const registryClient = ANTRegistry.init({
|
|
83
65
|
process: new AOProcess({
|
|
84
66
|
processId: antRegistryId,
|
|
@@ -165,6 +147,20 @@ export function createAoSigner(signer) {
|
|
|
165
147
|
typeof signer.setPublicKey === 'function') {
|
|
166
148
|
await signer.setPublicKey();
|
|
167
149
|
}
|
|
150
|
+
if (signer instanceof ArconnectSigner) {
|
|
151
|
+
// Sign using Arconnect signDataItem API
|
|
152
|
+
const signedDataItem = await signer['signer'].signDataItem({
|
|
153
|
+
data,
|
|
154
|
+
tags,
|
|
155
|
+
target,
|
|
156
|
+
anchor,
|
|
157
|
+
});
|
|
158
|
+
const dataItem = new DataItem(Buffer.from(signedDataItem));
|
|
159
|
+
return {
|
|
160
|
+
id: await dataItem.id,
|
|
161
|
+
raw: await dataItem.getRaw(),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
168
164
|
const dataItem = createData(data, signer, { tags, target, anchor });
|
|
169
165
|
const signedData = dataItem.sign(signer).then(async () => ({
|
|
170
166
|
id: await dataItem.id,
|
|
@@ -192,3 +188,20 @@ export function initANTStateForAddress({ owner, targetId, ttlSeconds = 3600, key
|
|
|
192
188
|
},
|
|
193
189
|
};
|
|
194
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Uses zod schema to parse the epoch data
|
|
193
|
+
*/
|
|
194
|
+
export function parseAoEpochData(value) {
|
|
195
|
+
const epochDataSchema = z.object({
|
|
196
|
+
startTimestamp: z.number(),
|
|
197
|
+
startHeight: z.number(),
|
|
198
|
+
distributions: z.any(),
|
|
199
|
+
endTimestamp: z.number(),
|
|
200
|
+
prescribedObservers: z.any(),
|
|
201
|
+
prescribedNames: z.array(z.string()),
|
|
202
|
+
observations: z.any(),
|
|
203
|
+
distributionTimestamp: z.number(),
|
|
204
|
+
epochIndex: z.number(),
|
|
205
|
+
});
|
|
206
|
+
return epochDataSchema.parse(value);
|
|
207
|
+
}
|
package/lib/esm/utils/arweave.js
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { ARWEAVE_TX_REGEX } from '../constants.js';
|
|
1
|
+
import { ARIO_TESTNET_PROCESS_ID, ARWEAVE_TX_REGEX } from '../constants.js';
|
|
2
|
+
import { parseAoEpochData } from './ao.js';
|
|
17
3
|
export const validateArweaveId = (id) => {
|
|
18
4
|
return ARWEAVE_TX_REGEX.test(id);
|
|
19
5
|
};
|
|
@@ -37,3 +23,50 @@ export const paginationParamsToTags = (params) => {
|
|
|
37
23
|
];
|
|
38
24
|
return pruneTags(tags);
|
|
39
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Get the epoch with distribution data for the current epoch
|
|
28
|
+
* @param arweave - The Arweave instance
|
|
29
|
+
* @returns The epoch with distribution data
|
|
30
|
+
*/
|
|
31
|
+
export const getEpochDataFromGql = async ({ arweave, epochIndex, processId = ARIO_TESTNET_PROCESS_ID, }) => {
|
|
32
|
+
// fetch from gql
|
|
33
|
+
const query = epochDistributionNoticeGqlQuery({ epochIndex, processId });
|
|
34
|
+
const response = await arweave.api.post('graphql', query);
|
|
35
|
+
// parse the nodes to get the id
|
|
36
|
+
if (response.data.data.transactions?.edges?.length === 0) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const id = response.data.data.transactions.edges[0].node.id;
|
|
40
|
+
// fetch the transaction from arweave
|
|
41
|
+
const transaction = await arweave.api.get(id);
|
|
42
|
+
const data = transaction.data;
|
|
43
|
+
// assert it is the correct type
|
|
44
|
+
return parseAoEpochData(data);
|
|
45
|
+
};
|
|
46
|
+
export const epochDistributionNoticeGqlQuery = ({ epochIndex, processId = ARIO_TESTNET_PROCESS_ID, }) => {
|
|
47
|
+
// write the query
|
|
48
|
+
const gqlQuery = JSON.stringify({
|
|
49
|
+
query: `
|
|
50
|
+
query {
|
|
51
|
+
transactions(
|
|
52
|
+
tags: [
|
|
53
|
+
{ name: "From-Process", values: ["${processId}"] }
|
|
54
|
+
{ name: "Action", values: ["Epoch-Distribution-Notice"] }
|
|
55
|
+
{ name: "Epoch-Index", values: ["${epochIndex}"] }
|
|
56
|
+
{ name: "Data-Protocol", values: ["ao"] }
|
|
57
|
+
],
|
|
58
|
+
owners: ["fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY"],
|
|
59
|
+
first: 1,
|
|
60
|
+
sort: HEIGHT_DESC
|
|
61
|
+
) {
|
|
62
|
+
edges {
|
|
63
|
+
node {
|
|
64
|
+
id
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`,
|
|
70
|
+
});
|
|
71
|
+
return gqlQuery;
|
|
72
|
+
};
|
package/lib/esm/version.js
CHANGED
|
@@ -21,6 +21,9 @@ export declare function getGateway(o: AddressCLIOptions): Promise<import("../../
|
|
|
21
21
|
export declare function listGateways(o: PaginationCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoGatewayWithAddress> | {
|
|
22
22
|
message: string;
|
|
23
23
|
}>;
|
|
24
|
+
export declare function listAllDelegatesCLICommand(o: PaginationCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoAllDelegates> | {
|
|
25
|
+
message: string;
|
|
26
|
+
}>;
|
|
24
27
|
export declare function getGatewayDelegates(o: AddressCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoGatewayDelegateWithAddress> | {
|
|
25
28
|
message: string;
|
|
26
29
|
}>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AoANTRegistryRead, AoANTRegistryWrite } from '../types/ant-registry.js';
|
|
2
2
|
import { AoMessageResult, ProcessConfiguration, WithSigner } from '../types/index.js';
|
|
3
3
|
import { AOProcess } from './index.js';
|
|
4
|
+
type ANTRegistryNoSigner = ProcessConfiguration;
|
|
5
|
+
type ANTRegistryWithSigner = WithSigner<ProcessConfiguration>;
|
|
4
6
|
export declare class ANTRegistry {
|
|
5
7
|
static init(): AoANTRegistryRead;
|
|
6
|
-
static init(config:
|
|
7
|
-
|
|
8
|
-
}): AoANTRegistryRead;
|
|
9
|
-
static init({ signer, ...config }: WithSigner<Required<ProcessConfiguration>>): AoANTRegistryWrite;
|
|
8
|
+
static init(config: ANTRegistryNoSigner): AoANTRegistryRead;
|
|
9
|
+
static init(config: ANTRegistryWithSigner): AoANTRegistryWrite;
|
|
10
10
|
}
|
|
11
11
|
export declare class AoANTRegistryReadable implements AoANTRegistryRead {
|
|
12
12
|
protected process: AOProcess;
|
|
@@ -25,3 +25,4 @@ export declare class AoANTRegistryWriteable extends AoANTRegistryReadable implem
|
|
|
25
25
|
processId: string;
|
|
26
26
|
}): Promise<AoMessageResult>;
|
|
27
27
|
}
|
|
28
|
+
export {};
|