@ar.io/sdk 3.14.0-alpha.8 → 3.14.0-alpha.9
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/CHANGELOG.md +1111 -0
- package/README.md +6 -6
- package/bundles/web.bundle.min.js +108 -108
- package/lib/cjs/common/ant.js +43 -40
- package/lib/cjs/utils/ant.js +16 -1
- package/lib/esm/common/ant.js +45 -42
- package/lib/esm/utils/ant.js +14 -0
- package/lib/types/common/ant.d.ts +3 -2
- package/lib/types/utils/ant.d.ts +1 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
package/lib/cjs/common/ant.js
CHANGED
|
@@ -41,6 +41,7 @@ class AoANTReadable {
|
|
|
41
41
|
strict;
|
|
42
42
|
hyperbeamUrl;
|
|
43
43
|
checkHyperBeamPromise;
|
|
44
|
+
logger = index_js_2.Logger.default;
|
|
44
45
|
constructor(config) {
|
|
45
46
|
this.strict = config.strict || false;
|
|
46
47
|
if ((0, index_js_1.isProcessConfiguration)(config)) {
|
|
@@ -59,38 +60,57 @@ class AoANTReadable {
|
|
|
59
60
|
this.checkHyperBeamPromise = this.checkHyperBeamCompatibility();
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
|
-
* Check if the process is
|
|
63
|
+
* Check if the process is HyperBeam compatible. If so, we'll use the HyperBeam node to fetch the state.
|
|
63
64
|
*
|
|
64
|
-
* @returns {Promise<boolean>} True if the process is
|
|
65
|
+
* @returns {Promise<boolean>} True if the process is HyperBeam compatible, false otherwise.
|
|
65
66
|
*/
|
|
66
67
|
async checkHyperBeamCompatibility() {
|
|
67
68
|
if (this.checkHyperBeamPromise !== undefined) {
|
|
68
69
|
return this.checkHyperBeamPromise;
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
method: '
|
|
71
|
+
this.checkHyperBeamPromise = fetch(`${this.hyperbeamUrl.toString()}${this.processId}~process@1.0/now/cache`, {
|
|
72
|
+
method: 'HEAD',
|
|
73
|
+
}).then((res) => {
|
|
74
|
+
if (res.ok) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
72
78
|
});
|
|
73
|
-
|
|
74
|
-
if (res.ok) {
|
|
75
|
-
isHyperBeamCompatible = true;
|
|
76
|
-
}
|
|
77
|
-
this.checkHyperBeamPromise = Promise.resolve(isHyperBeamCompatible);
|
|
78
|
-
return isHyperBeamCompatible;
|
|
79
|
+
return this.checkHyperBeamPromise;
|
|
79
80
|
}
|
|
80
81
|
async getState({ strict } = { strict: this.strict }) {
|
|
81
82
|
if (await this.checkHyperBeamCompatibility()) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
let retries = 0;
|
|
84
|
+
while (retries < 3) {
|
|
85
|
+
try {
|
|
86
|
+
const res = await fetch(`${this.hyperbeamUrl}${this.processId}~process@1.0/compute/cache/serialize~json@1.0`, {
|
|
87
|
+
method: 'GET',
|
|
88
|
+
redirect: 'follow',
|
|
89
|
+
mode: 'cors',
|
|
90
|
+
headers: {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (res.status !== 200) {
|
|
95
|
+
throw new Error(`Failed to fetch ant state: ${res?.statusText ?? 'Unknown error'}`);
|
|
96
|
+
}
|
|
97
|
+
const unnormalizedState = (await res.json());
|
|
98
|
+
if (!(0, ant_js_2.isHyperBeamANTState)(unnormalizedState)) {
|
|
99
|
+
throw new Error('Invalid HyperBeam ANT state', {
|
|
100
|
+
cause: { state: unnormalizedState },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// normalize and return the state
|
|
104
|
+
return (0, ant_js_2.convertHyperBeamStateToAoANTState)(unnormalizedState);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
this.logger.error(`Failed to fetch process state from HyperBEAM (attempt ${retries + 1} / 3)`, {
|
|
108
|
+
cause: error,
|
|
109
|
+
});
|
|
110
|
+
retries++;
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * retries ** 2));
|
|
112
|
+
}
|
|
92
113
|
}
|
|
93
|
-
return (0, ant_js_2.convertHyperBeamStateToAoANTState)((await res.json()));
|
|
94
114
|
}
|
|
95
115
|
const tags = [{ name: 'Action', value: 'State' }];
|
|
96
116
|
const res = await this.process.read({
|
|
@@ -264,25 +284,8 @@ class AoANTReadable {
|
|
|
264
284
|
* ```
|
|
265
285
|
*/
|
|
266
286
|
async getBalances({ strict } = { strict: this.strict }) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
method: 'GET',
|
|
270
|
-
redirect: 'follow',
|
|
271
|
-
mode: 'cors',
|
|
272
|
-
headers: {
|
|
273
|
-
'Content-Type': 'application/json',
|
|
274
|
-
},
|
|
275
|
-
});
|
|
276
|
-
if (!res.ok) {
|
|
277
|
-
throw new Error('Failed to fetch ant balances');
|
|
278
|
-
}
|
|
279
|
-
const result = (await res.json());
|
|
280
|
-
return result.balances;
|
|
281
|
-
}
|
|
282
|
-
const tags = [{ name: 'Action', value: 'Balances' }];
|
|
283
|
-
const balances = await this.process.read({
|
|
284
|
-
tags,
|
|
285
|
-
});
|
|
287
|
+
const state = await this.getState();
|
|
288
|
+
const balances = state.Balances;
|
|
286
289
|
if (strict)
|
|
287
290
|
(0, schema_js_1.parseSchemaResult)(ant_js_1.AntBalancesSchema, balances);
|
|
288
291
|
return balances;
|
package/lib/cjs/utils/ant.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertHyperBeamStateToAoANTState = exports.sortANTRecords = void 0;
|
|
3
|
+
exports.convertHyperBeamStateToAoANTState = exports.isHyperBeamANTState = exports.sortANTRecords = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Sorts ANT records by priority and then lexicographically.
|
|
6
6
|
*
|
|
@@ -41,6 +41,21 @@ const sortANTRecords = (antRecords) => {
|
|
|
41
41
|
return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }]));
|
|
42
42
|
};
|
|
43
43
|
exports.sortANTRecords = sortANTRecords;
|
|
44
|
+
const isHyperBeamANTState = (state) => {
|
|
45
|
+
return ('name' in state &&
|
|
46
|
+
'ticker' in state &&
|
|
47
|
+
'description' in state &&
|
|
48
|
+
'keywords' in state &&
|
|
49
|
+
'denomination' in state &&
|
|
50
|
+
'owner' in state &&
|
|
51
|
+
'controllers' in state &&
|
|
52
|
+
'records' in state &&
|
|
53
|
+
'balances' in state &&
|
|
54
|
+
'logo' in state &&
|
|
55
|
+
'totalsupply' in state &&
|
|
56
|
+
'initialized' in state);
|
|
57
|
+
};
|
|
58
|
+
exports.isHyperBeamANTState = isHyperBeamANTState;
|
|
44
59
|
/**
|
|
45
60
|
* Convert HyperBeam serialized ANT state to backwards compatible format.
|
|
46
61
|
*
|
package/lib/esm/common/ant.js
CHANGED
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { AntBalancesSchema, AntControllersSchema, AntInfoSchema, AntRecordSchema, AntRecordsSchema, AntStateSchema, } from '../types/ant.js';
|
|
18
18
|
import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/index.js';
|
|
19
|
-
import { convertHyperBeamStateToAoANTState, sortANTRecords, } from '../utils/ant.js';
|
|
19
|
+
import { convertHyperBeamStateToAoANTState, isHyperBeamANTState, sortANTRecords, } from '../utils/ant.js';
|
|
20
20
|
import { createAoSigner } from '../utils/ao.js';
|
|
21
21
|
import { parseSchemaResult } from '../utils/schema.js';
|
|
22
22
|
import { ANTVersions } from './ant-versions.js';
|
|
23
|
-
import { AOProcess, InvalidContractConfigurationError } from './index.js';
|
|
23
|
+
import { AOProcess, InvalidContractConfigurationError, Logger, } from './index.js';
|
|
24
24
|
export class ANT {
|
|
25
25
|
static versions = ANTVersions.init();
|
|
26
26
|
// implementation
|
|
@@ -37,6 +37,7 @@ export class AoANTReadable {
|
|
|
37
37
|
strict;
|
|
38
38
|
hyperbeamUrl;
|
|
39
39
|
checkHyperBeamPromise;
|
|
40
|
+
logger = Logger.default;
|
|
40
41
|
constructor(config) {
|
|
41
42
|
this.strict = config.strict || false;
|
|
42
43
|
if (isProcessConfiguration(config)) {
|
|
@@ -55,38 +56,57 @@ export class AoANTReadable {
|
|
|
55
56
|
this.checkHyperBeamPromise = this.checkHyperBeamCompatibility();
|
|
56
57
|
}
|
|
57
58
|
/**
|
|
58
|
-
* Check if the process is
|
|
59
|
+
* Check if the process is HyperBeam compatible. If so, we'll use the HyperBeam node to fetch the state.
|
|
59
60
|
*
|
|
60
|
-
* @returns {Promise<boolean>} True if the process is
|
|
61
|
+
* @returns {Promise<boolean>} True if the process is HyperBeam compatible, false otherwise.
|
|
61
62
|
*/
|
|
62
63
|
async checkHyperBeamCompatibility() {
|
|
63
64
|
if (this.checkHyperBeamPromise !== undefined) {
|
|
64
65
|
return this.checkHyperBeamPromise;
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
method: '
|
|
67
|
+
this.checkHyperBeamPromise = fetch(`${this.hyperbeamUrl.toString()}${this.processId}~process@1.0/now/cache`, {
|
|
68
|
+
method: 'HEAD',
|
|
69
|
+
}).then((res) => {
|
|
70
|
+
if (res.ok) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
68
74
|
});
|
|
69
|
-
|
|
70
|
-
if (res.ok) {
|
|
71
|
-
isHyperBeamCompatible = true;
|
|
72
|
-
}
|
|
73
|
-
this.checkHyperBeamPromise = Promise.resolve(isHyperBeamCompatible);
|
|
74
|
-
return isHyperBeamCompatible;
|
|
75
|
+
return this.checkHyperBeamPromise;
|
|
75
76
|
}
|
|
76
77
|
async getState({ strict } = { strict: this.strict }) {
|
|
77
78
|
if (await this.checkHyperBeamCompatibility()) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
let retries = 0;
|
|
80
|
+
while (retries < 3) {
|
|
81
|
+
try {
|
|
82
|
+
const res = await fetch(`${this.hyperbeamUrl}${this.processId}~process@1.0/compute/cache/serialize~json@1.0`, {
|
|
83
|
+
method: 'GET',
|
|
84
|
+
redirect: 'follow',
|
|
85
|
+
mode: 'cors',
|
|
86
|
+
headers: {
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
if (res.status !== 200) {
|
|
91
|
+
throw new Error(`Failed to fetch ant state: ${res?.statusText ?? 'Unknown error'}`);
|
|
92
|
+
}
|
|
93
|
+
const unnormalizedState = (await res.json());
|
|
94
|
+
if (!isHyperBeamANTState(unnormalizedState)) {
|
|
95
|
+
throw new Error('Invalid HyperBeam ANT state', {
|
|
96
|
+
cause: { state: unnormalizedState },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// normalize and return the state
|
|
100
|
+
return convertHyperBeamStateToAoANTState(unnormalizedState);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
this.logger.error(`Failed to fetch process state from HyperBEAM (attempt ${retries + 1} / 3)`, {
|
|
104
|
+
cause: error,
|
|
105
|
+
});
|
|
106
|
+
retries++;
|
|
107
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * retries ** 2));
|
|
108
|
+
}
|
|
88
109
|
}
|
|
89
|
-
return convertHyperBeamStateToAoANTState((await res.json()));
|
|
90
110
|
}
|
|
91
111
|
const tags = [{ name: 'Action', value: 'State' }];
|
|
92
112
|
const res = await this.process.read({
|
|
@@ -260,25 +280,8 @@ export class AoANTReadable {
|
|
|
260
280
|
* ```
|
|
261
281
|
*/
|
|
262
282
|
async getBalances({ strict } = { strict: this.strict }) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
method: 'GET',
|
|
266
|
-
redirect: 'follow',
|
|
267
|
-
mode: 'cors',
|
|
268
|
-
headers: {
|
|
269
|
-
'Content-Type': 'application/json',
|
|
270
|
-
},
|
|
271
|
-
});
|
|
272
|
-
if (!res.ok) {
|
|
273
|
-
throw new Error('Failed to fetch ant balances');
|
|
274
|
-
}
|
|
275
|
-
const result = (await res.json());
|
|
276
|
-
return result.balances;
|
|
277
|
-
}
|
|
278
|
-
const tags = [{ name: 'Action', value: 'Balances' }];
|
|
279
|
-
const balances = await this.process.read({
|
|
280
|
-
tags,
|
|
281
|
-
});
|
|
283
|
+
const state = await this.getState();
|
|
284
|
+
const balances = state.Balances;
|
|
282
285
|
if (strict)
|
|
283
286
|
parseSchemaResult(AntBalancesSchema, balances);
|
|
284
287
|
return balances;
|
package/lib/esm/utils/ant.js
CHANGED
|
@@ -37,6 +37,20 @@ export const sortANTRecords = (antRecords) => {
|
|
|
37
37
|
// now that they are sorted, add the index to each record - this is their position in the sorted list and is used to enforce undername limits
|
|
38
38
|
return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }]));
|
|
39
39
|
};
|
|
40
|
+
export const isHyperBeamANTState = (state) => {
|
|
41
|
+
return ('name' in state &&
|
|
42
|
+
'ticker' in state &&
|
|
43
|
+
'description' in state &&
|
|
44
|
+
'keywords' in state &&
|
|
45
|
+
'denomination' in state &&
|
|
46
|
+
'owner' in state &&
|
|
47
|
+
'controllers' in state &&
|
|
48
|
+
'records' in state &&
|
|
49
|
+
'balances' in state &&
|
|
50
|
+
'logo' in state &&
|
|
51
|
+
'totalsupply' in state &&
|
|
52
|
+
'initialized' in state);
|
|
53
|
+
};
|
|
40
54
|
/**
|
|
41
55
|
* Convert HyperBeam serialized ANT state to backwards compatible format.
|
|
42
56
|
*
|
|
@@ -18,11 +18,12 @@ export declare class AoANTReadable implements AoANTRead {
|
|
|
18
18
|
private strict;
|
|
19
19
|
private hyperbeamUrl;
|
|
20
20
|
private checkHyperBeamPromise;
|
|
21
|
+
private logger;
|
|
21
22
|
constructor(config: ANTConfigOptionalStrict);
|
|
22
23
|
/**
|
|
23
|
-
* Check if the process is
|
|
24
|
+
* Check if the process is HyperBeam compatible. If so, we'll use the HyperBeam node to fetch the state.
|
|
24
25
|
*
|
|
25
|
-
* @returns {Promise<boolean>} True if the process is
|
|
26
|
+
* @returns {Promise<boolean>} True if the process is HyperBeam compatible, false otherwise.
|
|
26
27
|
*/
|
|
27
28
|
private checkHyperBeamCompatibility;
|
|
28
29
|
getState({ strict }?: AntReadOptions): Promise<AoANTState>;
|
package/lib/types/utils/ant.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { ANTRecords, AoANTState, HyperBeamANTState, SortedANTRecords } from '../
|
|
|
24
24
|
* @param antRecords - The ANT records to sort.
|
|
25
25
|
*/
|
|
26
26
|
export declare const sortANTRecords: (antRecords: ANTRecords) => SortedANTRecords;
|
|
27
|
+
export declare const isHyperBeamANTState: (state: any) => state is HyperBeamANTState;
|
|
27
28
|
/**
|
|
28
29
|
* Convert HyperBeam serialized ANT state to backwards compatible format.
|
|
29
30
|
*
|
package/lib/types/version.d.ts
CHANGED