@ar.io/sdk 1.2.2 → 2.0.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 +148 -60
- package/bundles/web.bundle.min.js +132 -331
- package/lib/cjs/common/ant.js +147 -206
- package/lib/cjs/common/contracts/ao-process.js +1 -1
- package/lib/cjs/common/http.js +1 -2
- package/lib/cjs/common/index.js +0 -5
- package/lib/cjs/common/io.js +39 -31
- package/lib/cjs/common/logger.js +31 -19
- package/lib/cjs/types.js +0 -1
- package/lib/cjs/utils/arweave.js +1 -15
- package/lib/cjs/utils/http-client.js +1 -1
- package/lib/cjs/utils/index.js +1 -2
- package/lib/cjs/utils/{graphql/processes.js → processes.js} +35 -10
- package/lib/cjs/version.js +1 -1
- package/lib/esm/common/ant.js +144 -203
- package/lib/esm/common/contracts/ao-process.js +2 -2
- package/lib/esm/common/http.js +2 -3
- package/lib/esm/common/index.js +0 -5
- package/lib/esm/common/io.js +39 -28
- package/lib/esm/common/logger.js +29 -14
- package/lib/esm/types.js +0 -1
- package/lib/esm/utils/arweave.js +0 -12
- package/lib/esm/utils/http-client.js +2 -2
- package/lib/esm/utils/index.js +1 -2
- package/lib/esm/utils/{graphql/processes.js → processes.js} +33 -9
- package/lib/esm/version.js +1 -1
- package/lib/types/common/ant.d.ts +53 -175
- package/lib/types/common/contracts/ao-process.d.ts +2 -2
- package/lib/types/common/http.d.ts +3 -2
- package/lib/types/common/index.d.ts +0 -4
- package/lib/types/common/io.d.ts +5 -4
- package/lib/types/common/logger.d.ts +10 -3
- package/lib/types/common.d.ts +1 -145
- package/lib/types/io.d.ts +28 -3
- package/lib/types/types.d.ts +0 -1
- package/lib/types/utils/arweave.d.ts +0 -5
- package/lib/types/utils/http-client.d.ts +2 -2
- package/lib/types/utils/index.d.ts +1 -2
- package/lib/types/utils/{graphql/processes.d.ts → processes.d.ts} +4 -1
- package/lib/types/version.d.ts +1 -1
- package/package.json +8 -13
- package/lib/cjs/arns-service.js +0 -2
- package/lib/cjs/common/ant-ao.js +0 -297
- package/lib/cjs/common/ar-io.js +0 -741
- package/lib/cjs/common/contracts/remote-contract.js +0 -55
- package/lib/cjs/common/contracts/warp-contract.js +0 -176
- package/lib/cjs/common/warp.js +0 -25
- package/lib/cjs/utils/graphql/index.js +0 -34
- package/lib/cjs/utils/graphql/smartweave.js +0 -309
- package/lib/cjs/utils/smartweave.js +0 -58
- package/lib/esm/arns-service.js +0 -1
- package/lib/esm/common/ant-ao.js +0 -292
- package/lib/esm/common/ar-io.js +0 -735
- package/lib/esm/common/contracts/remote-contract.js +0 -51
- package/lib/esm/common/contracts/warp-contract.js +0 -172
- package/lib/esm/common/warp.js +0 -22
- package/lib/esm/utils/graphql/index.js +0 -18
- package/lib/esm/utils/graphql/smartweave.js +0 -303
- package/lib/esm/utils/smartweave.js +0 -50
- package/lib/types/arns-service.d.ts +0 -23
- package/lib/types/common/ant-ao.d.ts +0 -194
- package/lib/types/common/ar-io.d.ts +0 -551
- package/lib/types/common/contracts/remote-contract.d.ts +0 -38
- package/lib/types/common/contracts/warp-contract.d.ts +0 -43
- package/lib/types/common/warp.d.ts +0 -1
- package/lib/types/utils/graphql/index.d.ts +0 -18
- package/lib/types/utils/graphql/smartweave.d.ts +0 -47
- package/lib/types/utils/smartweave.d.ts +0 -41
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { AxiosHTTPService } from '../http.js';
|
|
2
|
-
import { DefaultLogger } from '../logger.js';
|
|
3
|
-
// TODO: this assumes the API structure matches the current arns-service API - we will want to consider another interface that exposes relevant APIs with client implementations (arns-service, DRE nodes, etc.)
|
|
4
|
-
export class RemoteContract {
|
|
5
|
-
logger;
|
|
6
|
-
http;
|
|
7
|
-
contractTxId;
|
|
8
|
-
cacheUrl;
|
|
9
|
-
constructor({ cacheUrl = 'https://api.arns.app', contractTxId, logger = new DefaultLogger(), }) {
|
|
10
|
-
this.cacheUrl = cacheUrl;
|
|
11
|
-
this.contractTxId = contractTxId;
|
|
12
|
-
this.logger = logger;
|
|
13
|
-
this.http = new AxiosHTTPService({
|
|
14
|
-
url: `${cacheUrl}/v1/contract/${contractTxId}`,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
configuration() {
|
|
18
|
-
return {
|
|
19
|
-
contractTxId: this.contractTxId,
|
|
20
|
-
cacheUrl: this.cacheUrl,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
async getState({ evaluationOptions } = {}) {
|
|
24
|
-
this.logger.debug(`Fetching contract state`, {
|
|
25
|
-
contractTxId: this.contractTxId,
|
|
26
|
-
evaluationOptions,
|
|
27
|
-
});
|
|
28
|
-
const { state } = await this.http.get({
|
|
29
|
-
endpoint: ``,
|
|
30
|
-
params: {
|
|
31
|
-
...evaluationOptions?.evalTo,
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
return state;
|
|
35
|
-
}
|
|
36
|
-
async readInteraction({ functionName, inputs, evaluationOptions, }) {
|
|
37
|
-
this.logger.debug(`Evaluating read interaction on contract`, {
|
|
38
|
-
functionName,
|
|
39
|
-
inputs,
|
|
40
|
-
evaluationOptions,
|
|
41
|
-
});
|
|
42
|
-
const { result } = await this.http.get({
|
|
43
|
-
endpoint: `/read/${functionName}`,
|
|
44
|
-
params: {
|
|
45
|
-
...evaluationOptions?.evalTo,
|
|
46
|
-
...inputs,
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,172 +0,0 @@
|
|
|
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 { LoggerFactory, Signature, Tag, } from 'warp-contracts';
|
|
18
|
-
import { sha256B64Url, toB64Url } from '../../utils/base64.js';
|
|
19
|
-
import { getContractManifest } from '../../utils/smartweave.js';
|
|
20
|
-
import { FailedRequestError, WriteInteractionError } from '../error.js';
|
|
21
|
-
import { DefaultLogger } from '../logger.js';
|
|
22
|
-
import { defaultWarp } from '../warp.js';
|
|
23
|
-
LoggerFactory.INST.logLevel('error');
|
|
24
|
-
export class WarpContract {
|
|
25
|
-
contract;
|
|
26
|
-
contractTxId;
|
|
27
|
-
cacheUrl;
|
|
28
|
-
logger;
|
|
29
|
-
warp;
|
|
30
|
-
constructor({ contractTxId, cacheUrl = 'https://api.arns.app', warp = defaultWarp, logger = new DefaultLogger({
|
|
31
|
-
level: 'info',
|
|
32
|
-
}), }) {
|
|
33
|
-
this.contractTxId = contractTxId;
|
|
34
|
-
this.contract = warp.contract(contractTxId);
|
|
35
|
-
this.cacheUrl = cacheUrl;
|
|
36
|
-
this.warp = warp;
|
|
37
|
-
this.logger = logger;
|
|
38
|
-
}
|
|
39
|
-
configuration() {
|
|
40
|
-
return {
|
|
41
|
-
contractTxId: this.contractTxId,
|
|
42
|
-
cacheUrl: this.cacheUrl,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
// TODO: could abstract into our own interface that constructs different signers
|
|
46
|
-
async createWarpSigner(signer) {
|
|
47
|
-
// ensure appropriate permissions are granted with injected signers.
|
|
48
|
-
if (signer.publicKey === undefined && 'setPublicKey' in signer) {
|
|
49
|
-
await signer.setPublicKey();
|
|
50
|
-
}
|
|
51
|
-
const warpSigner = new Signature(this.warp, {
|
|
52
|
-
signer: async (tx) => {
|
|
53
|
-
tx.setOwner(toB64Url(signer.publicKey));
|
|
54
|
-
const dataToSign = await tx.getSignatureData();
|
|
55
|
-
const signatureUint8Array = await signer.sign(dataToSign);
|
|
56
|
-
const signatureBuffer = Buffer.from(signatureUint8Array);
|
|
57
|
-
const id = sha256B64Url(signatureBuffer);
|
|
58
|
-
tx.setSignature({
|
|
59
|
-
id: id,
|
|
60
|
-
owner: toB64Url(signer.publicKey),
|
|
61
|
-
signature: toB64Url(signatureBuffer),
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
type: 'arweave',
|
|
65
|
-
});
|
|
66
|
-
return warpSigner;
|
|
67
|
-
}
|
|
68
|
-
async getState({ evaluationOptions = {} }) {
|
|
69
|
-
await this.ensureContractInit();
|
|
70
|
-
const evalTo = evaluationOptions?.evalTo;
|
|
71
|
-
let sortKeyOrBlockHeight;
|
|
72
|
-
if (evalTo && 'sortKey' in evalTo) {
|
|
73
|
-
sortKeyOrBlockHeight = evalTo.sortKey;
|
|
74
|
-
}
|
|
75
|
-
else if (evalTo && 'blockHeight' in evalTo) {
|
|
76
|
-
sortKeyOrBlockHeight = evalTo.blockHeight;
|
|
77
|
-
}
|
|
78
|
-
const evaluationResult = await this.contract.readState(sortKeyOrBlockHeight);
|
|
79
|
-
if (!evaluationResult.cachedValue.state) {
|
|
80
|
-
throw new FailedRequestError(502, 'Failed to evaluate contract state');
|
|
81
|
-
}
|
|
82
|
-
return evaluationResult.cachedValue.state;
|
|
83
|
-
}
|
|
84
|
-
async ensureContractInit({ signer } = {}) {
|
|
85
|
-
this.logger.debug(`Checking contract initialized`, {
|
|
86
|
-
contractTxId: this.contractTxId,
|
|
87
|
-
});
|
|
88
|
-
// Get contact manifest and sync state
|
|
89
|
-
this.logger.debug(`Fetching contract manifest`, {
|
|
90
|
-
contractTxId: this.contractTxId,
|
|
91
|
-
});
|
|
92
|
-
const { evaluationOptions = {} } = await getContractManifest({
|
|
93
|
-
arweave: this.warp.arweave,
|
|
94
|
-
contractTxId: this.contractTxId,
|
|
95
|
-
});
|
|
96
|
-
this.contract.setEvaluationOptions(evaluationOptions);
|
|
97
|
-
if (signer)
|
|
98
|
-
this.contract.connect(await this.createWarpSigner(signer));
|
|
99
|
-
if (this.cacheUrl !== undefined) {
|
|
100
|
-
this.logger.debug(`Syncing contract state`, {
|
|
101
|
-
contractTxId: this.contractTxId,
|
|
102
|
-
remoteCacheUrl: this.cacheUrl,
|
|
103
|
-
});
|
|
104
|
-
await this.contract.syncState(`${this.cacheUrl}/v1/contract/${this.contractTxId}`, {
|
|
105
|
-
validity: true,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async readInteraction({ functionName, inputs,
|
|
110
|
-
// TODO: view state only supports sort key so we won't be able to use block height
|
|
111
|
-
}) {
|
|
112
|
-
await this.ensureContractInit();
|
|
113
|
-
this.logger.debug(`Read interaction: ${functionName}`, {
|
|
114
|
-
contractTxId: this.contractTxId,
|
|
115
|
-
inputs,
|
|
116
|
-
});
|
|
117
|
-
const evaluationResult = await this.contract.viewState({
|
|
118
|
-
function: functionName,
|
|
119
|
-
...inputs,
|
|
120
|
-
});
|
|
121
|
-
if (evaluationResult.result === undefined) {
|
|
122
|
-
throw new FailedRequestError(502, 'Failed to evaluate contract read interaction: ' +
|
|
123
|
-
JSON.stringify({ error: evaluationResult.errorMessage, functionName, inputs }, null, 2));
|
|
124
|
-
}
|
|
125
|
-
this.logger.debug('Successfully evaluated contract read interaction', {
|
|
126
|
-
contractTxId: this.contractTxId,
|
|
127
|
-
result: evaluationResult.result,
|
|
128
|
-
});
|
|
129
|
-
return evaluationResult.result;
|
|
130
|
-
}
|
|
131
|
-
async writeInteraction({ functionName, inputs, signer,
|
|
132
|
-
// TODO: support dryWrite
|
|
133
|
-
}, options) {
|
|
134
|
-
try {
|
|
135
|
-
this.logger.debug(`Write interaction: ${functionName}`, {
|
|
136
|
-
contractTxId: this.contractTxId,
|
|
137
|
-
});
|
|
138
|
-
// Sync state before writing
|
|
139
|
-
await this.ensureContractInit({ signer });
|
|
140
|
-
// run dry write before actual write
|
|
141
|
-
const result = await this.contract.dryWrite({
|
|
142
|
-
function: functionName,
|
|
143
|
-
...inputs,
|
|
144
|
-
});
|
|
145
|
-
if (result.type !== 'ok') {
|
|
146
|
-
throw new Error(`Failed to dry write contract interaction ${functionName}: ${result.errorMessage}`);
|
|
147
|
-
}
|
|
148
|
-
const writeResult = await this.contract.writeInteraction({
|
|
149
|
-
function: functionName,
|
|
150
|
-
...inputs,
|
|
151
|
-
}, {
|
|
152
|
-
disableBundling: true,
|
|
153
|
-
tags: options?.tags?.map((tag) => new Tag(tag.name, tag.value)),
|
|
154
|
-
});
|
|
155
|
-
if (!writeResult?.interactionTx) {
|
|
156
|
-
throw new Error(`Failed to write contract interaction: ${functionName}`);
|
|
157
|
-
}
|
|
158
|
-
this.logger.debug('Successfully wrote contract interaction', {
|
|
159
|
-
contractTxId: this.contractTxId,
|
|
160
|
-
interactionTxId: writeResult.originalTxId,
|
|
161
|
-
});
|
|
162
|
-
// hack - we only support L1 for interactions so they should always be transactions
|
|
163
|
-
return writeResult.interactionTx;
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
this.logger.error(`Failed to write contract interaction: ${error.message}`, {
|
|
167
|
-
contractTxId: this.contractTxId,
|
|
168
|
-
});
|
|
169
|
-
throw new WriteInteractionError(error);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
package/lib/esm/common/warp.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
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 { WarpFactory, defaultCacheOptions } from 'warp-contracts';
|
|
18
|
-
import { defaultArweave } from './arweave.js';
|
|
19
|
-
export const defaultWarp = WarpFactory.forMainnet({
|
|
20
|
-
...defaultCacheOptions,
|
|
21
|
-
inMemory: true,
|
|
22
|
-
}, true, defaultArweave);
|
|
@@ -1,18 +0,0 @@
|
|
|
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 * from './smartweave.js';
|
|
18
|
-
export * from './processes.js';
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import { AbortError } from '../../common/error.js';
|
|
2
|
-
export const MAX_REQUEST_SIZE = 100;
|
|
3
|
-
/**
|
|
4
|
-
* @param arweave - arweave instance to perform gql request
|
|
5
|
-
* @param address - address of the wallet to get transactions for
|
|
6
|
-
* @param signal - signal to abort the request
|
|
7
|
-
* @returns @type {Promise<DataProtocolTransaction[]>} - returns the list of data protocol txs, for e.g smartweave contracts
|
|
8
|
-
*/
|
|
9
|
-
export async function getSmartweaveContractsFromGQL({ address, arweave, signal = AbortSignal.timeout(10_000),
|
|
10
|
-
// TODO: add retry provider - eg pass in fetcher for the query
|
|
11
|
-
}) {
|
|
12
|
-
let hasNextPage = false;
|
|
13
|
-
let cursor;
|
|
14
|
-
const protocolTxs = new Set();
|
|
15
|
-
do {
|
|
16
|
-
const queryObject = {
|
|
17
|
-
query: `
|
|
18
|
-
{
|
|
19
|
-
transactions (
|
|
20
|
-
owners:["${address}"]
|
|
21
|
-
tags: [
|
|
22
|
-
{
|
|
23
|
-
name: "App-Name",
|
|
24
|
-
values: ["SmartWeaveContract"],
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
sort: HEIGHT_DESC,
|
|
28
|
-
first: ${MAX_REQUEST_SIZE},
|
|
29
|
-
bundledIn: null,
|
|
30
|
-
${cursor !== undefined ? `after: "${cursor}"` : ''}
|
|
31
|
-
) {
|
|
32
|
-
pageInfo {
|
|
33
|
-
hasNextPage
|
|
34
|
-
}
|
|
35
|
-
edges {
|
|
36
|
-
cursor
|
|
37
|
-
node {
|
|
38
|
-
id
|
|
39
|
-
block {
|
|
40
|
-
height
|
|
41
|
-
}
|
|
42
|
-
tags {
|
|
43
|
-
name
|
|
44
|
-
value
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}`,
|
|
50
|
-
};
|
|
51
|
-
if (signal?.aborted) {
|
|
52
|
-
throw new AbortError('GraphQL request was aborted.');
|
|
53
|
-
}
|
|
54
|
-
const { status, ...response } = await arweave.api.post('/graphql', queryObject, {
|
|
55
|
-
signal,
|
|
56
|
-
});
|
|
57
|
-
if (status == 429) {
|
|
58
|
-
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (status !== 200) {
|
|
62
|
-
console.dir(response, { depth: null });
|
|
63
|
-
throw Error(`Failed to fetch contracts for wallet. Status code: ${status}`);
|
|
64
|
-
}
|
|
65
|
-
if (!response.data.data?.transactions?.edges?.length) {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
response.data.data.transactions.edges
|
|
69
|
-
.map((e) => ({
|
|
70
|
-
id: e.node.id,
|
|
71
|
-
tags: e.node.tags,
|
|
72
|
-
data: e.node.data,
|
|
73
|
-
}))
|
|
74
|
-
.forEach((c) => {
|
|
75
|
-
protocolTxs.add(c.def);
|
|
76
|
-
});
|
|
77
|
-
cursor =
|
|
78
|
-
response.data.data.transactions.edges[MAX_REQUEST_SIZE - 1]?.cursor;
|
|
79
|
-
hasNextPage =
|
|
80
|
-
response.data.data.transactions.pageInfo?.hasNextPage ?? false;
|
|
81
|
-
} while (hasNextPage);
|
|
82
|
-
return [...protocolTxs];
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* @param arweave - arweave instance to perform gql request
|
|
86
|
-
* @param address - address of the wallet to get transactions for
|
|
87
|
-
* @param contractTxId - contract tx id to filter the transactions
|
|
88
|
-
* @param signal - signal to abort the request
|
|
89
|
-
* @returns @type {Promise<DataProtocolTransaction[]>} - returns the list of data protocol txs, for e.g smartweave contracts
|
|
90
|
-
*/
|
|
91
|
-
export async function getSmartweaveTransactionsFromGQL({ address, contractTxId, arweave, signal = AbortSignal.timeout(10_000),
|
|
92
|
-
// TODO: add retry provider - eg pass in fetcher for the query
|
|
93
|
-
}) {
|
|
94
|
-
let hasNextPage = false;
|
|
95
|
-
let cursor;
|
|
96
|
-
const protocolTxs = new Set();
|
|
97
|
-
do {
|
|
98
|
-
const queryObject = {
|
|
99
|
-
query: `
|
|
100
|
-
{
|
|
101
|
-
transactions (
|
|
102
|
-
owners:["${address}"]
|
|
103
|
-
tags: [
|
|
104
|
-
{
|
|
105
|
-
name: "App-Name",
|
|
106
|
-
values: ["SmartWeaveAction"],
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: "Contract",
|
|
110
|
-
values: ["${contractTxId}"],
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
sort: HEIGHT_DESC,
|
|
114
|
-
first: ${MAX_REQUEST_SIZE},
|
|
115
|
-
bundledIn: null,
|
|
116
|
-
${cursor !== undefined ? `after: "${cursor}"` : ''}
|
|
117
|
-
) {
|
|
118
|
-
pageInfo {
|
|
119
|
-
hasNextPage
|
|
120
|
-
}
|
|
121
|
-
edges {
|
|
122
|
-
cursor
|
|
123
|
-
node {
|
|
124
|
-
id
|
|
125
|
-
block {
|
|
126
|
-
height
|
|
127
|
-
}
|
|
128
|
-
tags {
|
|
129
|
-
name
|
|
130
|
-
value
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}`,
|
|
136
|
-
};
|
|
137
|
-
if (signal?.aborted) {
|
|
138
|
-
throw new AbortError('GraphQL request was aborted.');
|
|
139
|
-
}
|
|
140
|
-
const { status, ...response } = await arweave.api.post('/graphql', queryObject, {
|
|
141
|
-
signal,
|
|
142
|
-
});
|
|
143
|
-
if (status == 429) {
|
|
144
|
-
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (status !== 200) {
|
|
148
|
-
throw Error(`Failed to fetch contracts for wallet. Status code: ${status}`);
|
|
149
|
-
}
|
|
150
|
-
if (!response.data.data?.transactions?.edges?.length) {
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
response.data.data.transactions.edges
|
|
154
|
-
.map((e) => ({
|
|
155
|
-
id: e.node.id,
|
|
156
|
-
tags: e.node.tags,
|
|
157
|
-
data: e.node.data,
|
|
158
|
-
}))
|
|
159
|
-
.forEach((c) => {
|
|
160
|
-
protocolTxs.add(c.def);
|
|
161
|
-
});
|
|
162
|
-
cursor =
|
|
163
|
-
response.data.data.transactions.edges[MAX_REQUEST_SIZE - 1]?.cursor;
|
|
164
|
-
hasNextPage =
|
|
165
|
-
response.data.data.transactions.pageInfo?.hasNextPage ?? false;
|
|
166
|
-
} while (hasNextPage);
|
|
167
|
-
return [...protocolTxs];
|
|
168
|
-
}
|
|
169
|
-
export async function getContractsTransferredToOrControlledByWallet(arweave, params, signal) {
|
|
170
|
-
const { address } = params;
|
|
171
|
-
let hasNextPage = false;
|
|
172
|
-
let cursor;
|
|
173
|
-
const protocolTxs = new Set();
|
|
174
|
-
do {
|
|
175
|
-
const queryObject = {
|
|
176
|
-
query: `
|
|
177
|
-
{
|
|
178
|
-
transactions (
|
|
179
|
-
tags:[
|
|
180
|
-
{
|
|
181
|
-
name: "App-Name",
|
|
182
|
-
values: ["SmartWeaveAction"]
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: "Input",
|
|
186
|
-
values: ${JSON.stringify([
|
|
187
|
-
// duplicated because the order of the input matters when querying gql
|
|
188
|
-
{
|
|
189
|
-
function: 'setController',
|
|
190
|
-
target: address,
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
target: address,
|
|
194
|
-
function: 'setController',
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
function: 'transfer',
|
|
198
|
-
target: address,
|
|
199
|
-
qty: 1,
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
function: 'transfer',
|
|
203
|
-
qty: 1,
|
|
204
|
-
target: address,
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
target: address,
|
|
208
|
-
function: 'transfer',
|
|
209
|
-
qty: 1,
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
target: address,
|
|
213
|
-
qty: 1,
|
|
214
|
-
function: 'transfer',
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
qty: 1,
|
|
218
|
-
target: address,
|
|
219
|
-
function: 'transfer',
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
qty: 1,
|
|
223
|
-
function: 'transfer',
|
|
224
|
-
target: address,
|
|
225
|
-
},
|
|
226
|
-
// removing qty just for coverage
|
|
227
|
-
{
|
|
228
|
-
function: 'transfer',
|
|
229
|
-
target: address,
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
target: address,
|
|
233
|
-
function: 'transfer',
|
|
234
|
-
},
|
|
235
|
-
])
|
|
236
|
-
.replace(/"/g, '\\"')
|
|
237
|
-
.replace(/\{/g, '"{')
|
|
238
|
-
.replace(/\}/g, '}"')}
|
|
239
|
-
}
|
|
240
|
-
],
|
|
241
|
-
sort: HEIGHT_DESC,
|
|
242
|
-
first: ${MAX_REQUEST_SIZE},
|
|
243
|
-
bundledIn: null,
|
|
244
|
-
${cursor !== undefined ? `after: "${cursor}"` : ''}
|
|
245
|
-
) {
|
|
246
|
-
pageInfo {
|
|
247
|
-
hasNextPage
|
|
248
|
-
}
|
|
249
|
-
edges {
|
|
250
|
-
cursor
|
|
251
|
-
node {
|
|
252
|
-
id
|
|
253
|
-
tags {
|
|
254
|
-
name
|
|
255
|
-
value
|
|
256
|
-
}
|
|
257
|
-
block {
|
|
258
|
-
height
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}`,
|
|
264
|
-
};
|
|
265
|
-
if (signal?.aborted) {
|
|
266
|
-
throw new AbortError('GraphQL request was aborted.');
|
|
267
|
-
}
|
|
268
|
-
const { status, ...response } = await arweave.api.post('/graphql', queryObject, {
|
|
269
|
-
signal,
|
|
270
|
-
});
|
|
271
|
-
if (status == 429) {
|
|
272
|
-
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
if (status !== 200) {
|
|
276
|
-
throw Error(`Failed to fetch contracts for wallet. Status code: ${status}`);
|
|
277
|
-
}
|
|
278
|
-
if (!response.data.data?.transactions?.edges?.length) {
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
response.data.data.transactions.edges
|
|
282
|
-
.map((e) => {
|
|
283
|
-
const contractTag = e.node.tags.find((t) => t.name === 'Contract');
|
|
284
|
-
// we want to preserve the cursor here, so add even if a duplicate and the set will handle removing the contract if its a duplicate
|
|
285
|
-
return {
|
|
286
|
-
id: contractTag?.value,
|
|
287
|
-
tags: [],
|
|
288
|
-
data: 0,
|
|
289
|
-
};
|
|
290
|
-
})
|
|
291
|
-
.forEach((c) => {
|
|
292
|
-
if (c.tx?.id) {
|
|
293
|
-
protocolTxs.add(c.tx);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
cursor =
|
|
297
|
-
response.data.data.transactions.edges[MAX_REQUEST_SIZE - 1]?.cursor ??
|
|
298
|
-
undefined;
|
|
299
|
-
hasNextPage =
|
|
300
|
-
response.data.data.transactions.pageInfo?.hasNextPage ?? false;
|
|
301
|
-
} while (hasNextPage);
|
|
302
|
-
return [...protocolTxs];
|
|
303
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { SORT_KEY_REGEX } from '../constants.js';
|
|
2
|
-
import { tagsToObject, validateArweaveId } from './arweave.js';
|
|
3
|
-
export function isSortKey(sortKey) {
|
|
4
|
-
return SmartWeaveSortKey.validate(sortKey);
|
|
5
|
-
}
|
|
6
|
-
export class SmartWeaveSortKey {
|
|
7
|
-
_sortKey;
|
|
8
|
-
constructor(sortKey) {
|
|
9
|
-
if (!SmartWeaveSortKey.validate(sortKey)) {
|
|
10
|
-
throw new Error(`Invalid sort key: ${sortKey}`);
|
|
11
|
-
}
|
|
12
|
-
this._sortKey = sortKey;
|
|
13
|
-
}
|
|
14
|
-
static validate(sortKey) {
|
|
15
|
-
return SORT_KEY_REGEX.test(sortKey);
|
|
16
|
-
}
|
|
17
|
-
toString() {
|
|
18
|
-
return this._sortKey;
|
|
19
|
-
}
|
|
20
|
-
parts() {
|
|
21
|
-
return this._sortKey.split(',');
|
|
22
|
-
}
|
|
23
|
-
blockHeight() {
|
|
24
|
-
return parseInt(this.parts()[0]);
|
|
25
|
-
}
|
|
26
|
-
timestamp() {
|
|
27
|
-
return parseInt(this.parts()[1]);
|
|
28
|
-
}
|
|
29
|
-
hash() {
|
|
30
|
-
return this.parts()[2];
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export async function getContractManifest({ arweave, contractTxId, }) {
|
|
34
|
-
const { tags: encodedTags } = await arweave.transactions
|
|
35
|
-
.get(contractTxId)
|
|
36
|
-
.catch(() => ({ tags: [] }));
|
|
37
|
-
const decodedTags = tagsToObject(encodedTags);
|
|
38
|
-
const contractManifestString = decodedTags['Contract-Manifest'] ?? '{}';
|
|
39
|
-
// TODO throw if manifest is missing
|
|
40
|
-
const contractManifest = JSON.parse(contractManifestString);
|
|
41
|
-
return contractManifest;
|
|
42
|
-
}
|
|
43
|
-
export function isContractConfiguration(config) {
|
|
44
|
-
return 'contract' in config;
|
|
45
|
-
}
|
|
46
|
-
export function isContractTxIdConfiguration(config) {
|
|
47
|
-
return ('contractTxId' in config &&
|
|
48
|
-
typeof config.contractTxId === 'string' &&
|
|
49
|
-
validateArweaveId(config.contractTxId) === true);
|
|
50
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
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 { EvalStateResult, EvaluationOptions } from 'warp-contracts';
|
|
18
|
-
export type EvaluatedContractState<ContractState> = EvalStateResult<ContractState> & {
|
|
19
|
-
sortKey: string;
|
|
20
|
-
evaluationOptions: EvaluationOptions;
|
|
21
|
-
contractTxId: string;
|
|
22
|
-
};
|
|
23
|
-
export type ArNSStateResponse<StateKey extends string, StateObject> = Pick<EvaluatedContractState<unknown>, 'contractTxId' | 'sortKey' | 'evaluationOptions'> & Record<StateKey, StateObject>;
|