@fleet-sdk/blockchain-providers 0.4.1 → 0.6.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/CHANGELOG.md +19 -0
- package/dist/index.d.mts +124 -33
- package/dist/index.d.ts +124 -33
- package/dist/index.js +254 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +254 -75
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/ergo-graphql/ergoGraphQLProvider.ts +296 -93
- package/src/ergo-graphql/queries.ts +21 -9
- package/src/index.ts +1 -1
- package/src/types/blockchainProvider.ts +111 -18
- package/src/utils/_tests.ts +7 -7
- package/src/utils/graphql.test-d.ts +15 -7
- package/src/utils/graphql.ts +54 -40
- package/src/utils/networking.ts +84 -0
- package/src/ergo-graphql/index.ts +0 -1
- package/src/types/index.ts +0 -1
package/dist/index.js
CHANGED
@@ -4,29 +4,73 @@ var common = require('@fleet-sdk/common');
|
|
4
4
|
var core = require('@fleet-sdk/core');
|
5
5
|
|
6
6
|
// src/ergo-graphql/ergoGraphQLProvider.ts
|
7
|
+
async function request(path, opt) {
|
8
|
+
const url = buildURL(path, opt?.query, opt?.base);
|
9
|
+
let response;
|
10
|
+
if (opt?.retry) {
|
11
|
+
const routes = common.some(opt.retry.fallbacks) ? [url, ...opt.retry.fallbacks] : [url];
|
12
|
+
const attempts = opt.retry.attempts;
|
13
|
+
response = await exponentialRetry(
|
14
|
+
(r) => fetch(resolveUrl(routes, attempts - r), opt.httpOptions),
|
15
|
+
opt.retry
|
16
|
+
);
|
17
|
+
} else {
|
18
|
+
response = await fetch(url, opt?.httpOptions);
|
19
|
+
}
|
20
|
+
return (opt?.parser || JSON).parse(await response.text());
|
21
|
+
}
|
22
|
+
function resolveUrl(routes, attempt) {
|
23
|
+
const route = routes[attempt % routes.length];
|
24
|
+
return typeof route === "string" ? route : buildURL(route.path, route.query, route.base).toString();
|
25
|
+
}
|
26
|
+
function buildURL(path, query, base) {
|
27
|
+
if (!base && !query) return path;
|
28
|
+
const url = new URL(path, base);
|
29
|
+
if (common.some(query)) {
|
30
|
+
for (const key in query) url.searchParams.append(key, String(query[key]));
|
31
|
+
}
|
32
|
+
return url.toString();
|
33
|
+
}
|
34
|
+
async function exponentialRetry(operation, { attempts, delay }) {
|
35
|
+
try {
|
36
|
+
return await operation(attempts);
|
37
|
+
} catch (e) {
|
38
|
+
if (attempts > 0) {
|
39
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
40
|
+
return exponentialRetry(operation, { attempts: attempts - 1, delay: delay * 2 });
|
41
|
+
}
|
42
|
+
throw e;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
// src/utils/graphql.ts
|
7
47
|
var OP_NAME_REGEX = /(query|mutation)\s?([\w\-_]+)?/;
|
8
48
|
var DEFAULT_HEADERS = {
|
9
49
|
"content-type": "application/json; charset=utf-8",
|
10
50
|
accept: "application/graphql-response+json, application/json"
|
11
51
|
};
|
12
52
|
function createGqlOperation(query, options) {
|
13
|
-
return async (variables) => {
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
53
|
+
return async (variables, url) => {
|
54
|
+
url = url ?? options?.url;
|
55
|
+
if (!url) throw new Error("URL is required");
|
56
|
+
const response = await request(url, {
|
57
|
+
...options,
|
58
|
+
httpOptions: {
|
59
|
+
...options?.httpOptions,
|
60
|
+
method: "POST",
|
61
|
+
headers: common.ensureDefaults(options?.httpOptions?.headers, DEFAULT_HEADERS),
|
62
|
+
body: (options?.parser ?? JSON).stringify({
|
63
|
+
operationName: getOpName(query),
|
64
|
+
query,
|
65
|
+
variables: variables ? common.clearUndefined(variables) : void 0
|
66
|
+
})
|
67
|
+
}
|
23
68
|
});
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
throw new common.BlockchainProviderError(parsedData.errors[0].message, { cause: parsedData.errors });
|
69
|
+
if (options?.throwOnNonNetworkErrors && common.some(response.errors) && common.isEmpty(response.data)) {
|
70
|
+
const msg = response.errors[0].message;
|
71
|
+
throw new common.BlockchainProviderError(msg, { cause: response.errors });
|
28
72
|
}
|
29
|
-
return
|
73
|
+
return response;
|
30
74
|
};
|
31
75
|
}
|
32
76
|
function getOpName(query) {
|
@@ -38,47 +82,62 @@ function isRequestParam(obj) {
|
|
38
82
|
|
39
83
|
// src/ergo-graphql/queries.ts
|
40
84
|
var B = [
|
41
|
-
|
42
|
-
|
43
|
-
|
85
|
+
"$boxIds: [String!] $ergoTrees: [String!] $ergoTreeTemplateHash: String $tokenId: String $skip: Int $take: Int",
|
86
|
+
"boxIds: $boxIds ergoTrees: $ergoTrees ergoTreeTemplateHash: $ergoTreeTemplateHash tokenId: $tokenId skip: $skip take: $take",
|
87
|
+
"boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters"
|
88
|
+
];
|
89
|
+
var CONF_BOXES_QUERY = `query boxes($spent: Boolean! ${B[0]}) { boxes(spent: $spent ${B[1]}) { ${B[2]} beingSpent } }`;
|
90
|
+
var UNCONF_BOXES_QUERY = `query boxes(${B[0]}) { mempool { boxes(${B[1]}) { ${B[2]} beingSpent } } }`;
|
91
|
+
var ALL_BOXES_QUERY = `query boxes($spent: Boolean! ${B[0]}) { boxes(spent: $spent ${B[1]}) { ${B[2]} beingSpent } mempool { boxes(${B[1]}) { ${B[2]} beingSpent } } }`;
|
92
|
+
var HEADERS_QUERY = "query blockHeaders($take: Int) { blockHeaders(take: $take) {headerId timestamp version adProofsRoot stateRoot transactionsRoot nBits extensionHash powSolutions height difficulty parentId votes } }";
|
93
|
+
var CHECK_TX_MUTATION = "mutation checkTransaction($signedTransaction: SignedTransaction!) { checkTransaction(signedTransaction: $signedTransaction) }";
|
94
|
+
var SEND_TX_MUTATION = "mutation submitTransaction($signedTransaction: SignedTransaction!) { submitTransaction(signedTransaction: $signedTransaction) }";
|
95
|
+
var T = [
|
96
|
+
"$addresses: [String!], $transactionIds: [String!], $skip: Int, $take: Int",
|
97
|
+
"addresses: $addresses, transactionIds: $transactionIds, skip: $skip, take: $take",
|
98
|
+
`transactionId timestamp inputs { proofBytes extension index box { ${B[2]} } } dataInputs { boxId }`
|
44
99
|
];
|
45
|
-
var
|
46
|
-
var
|
47
|
-
var ALL_BOXES_QUERY = `${B[0]} { boxes(spent: $spent ${B[1]}) { ${B[2]} } mempool { boxes(${B[1]}) { ${B[2]} } } }`;
|
48
|
-
var HEADERS_QUERY = `query blockHeaders($take: Int) { blockHeaders(take: $take) {headerId timestamp version adProofsRoot stateRoot transactionsRoot nBits extensionHash powSolutions height difficulty parentId votes } }`;
|
49
|
-
var CHECK_TX_MUTATION = `mutation checkTransaction($signedTransaction: SignedTransaction!) { checkTransaction(signedTransaction: $signedTransaction) }`;
|
50
|
-
var SEND_TX_MUTATION = `mutation submitTransaction($signedTransaction: SignedTransaction!) { submitTransaction(signedTransaction: $signedTransaction) }`;
|
100
|
+
var CONF_TX_QUERY = `query confirmedTransactions(${T[0]} $relevantOnly: Boolean) { transactions(${T[1]}) { ${T[2]} outputs(relevantOnly: $relevantOnly) { ${B[2]} } inclusionHeight headerId index } }`;
|
101
|
+
var UNCONF_TX_QUERY = `query unconfirmedTransactions(${T[0]}) { mempool { transactions(${T[1]}) { ${T[2]} outputs { ${B[2]} } } } }`;
|
51
102
|
|
52
103
|
// src/ergo-graphql/ergoGraphQLProvider.ts
|
53
104
|
var PAGE_SIZE = 50;
|
54
105
|
var ErgoGraphQLProvider = class {
|
55
106
|
#options;
|
56
|
-
#
|
57
|
-
#
|
107
|
+
#biMapper;
|
108
|
+
#getConfirmedBoxes;
|
109
|
+
#getUnconfirmedBoxes;
|
58
110
|
#getAllBoxes;
|
111
|
+
#getConfirmedTransactions;
|
112
|
+
#getUnconfirmedTransactions;
|
113
|
+
#checkTransaction;
|
114
|
+
#sendTransaction;
|
59
115
|
#getHeaders;
|
60
|
-
#checkTx;
|
61
|
-
#sendTx;
|
62
116
|
constructor(optOrUrl) {
|
63
117
|
this.#options = {
|
64
118
|
...isRequestParam(optOrUrl) ? optOrUrl : { url: optOrUrl },
|
65
119
|
throwOnNonNetworkErrors: true
|
66
120
|
};
|
67
|
-
this.#
|
68
|
-
this.#
|
121
|
+
this.#biMapper = (value) => BigInt(value);
|
122
|
+
this.#getConfirmedBoxes = this.createOperation(CONF_BOXES_QUERY);
|
123
|
+
this.#getUnconfirmedBoxes = this.createOperation(UNCONF_BOXES_QUERY);
|
69
124
|
this.#getAllBoxes = this.createOperation(ALL_BOXES_QUERY);
|
125
|
+
this.#getConfirmedTransactions = this.createOperation(CONF_TX_QUERY);
|
126
|
+
this.#getUnconfirmedTransactions = this.createOperation(UNCONF_TX_QUERY);
|
127
|
+
this.#checkTransaction = this.createOperation(CHECK_TX_MUTATION);
|
128
|
+
this.#sendTransaction = this.createOperation(SEND_TX_MUTATION);
|
70
129
|
this.#getHeaders = this.createOperation(HEADERS_QUERY);
|
71
|
-
this.#checkTx = this.createOperation(CHECK_TX_MUTATION);
|
72
|
-
this.#sendTx = this.createOperation(SEND_TX_MUTATION);
|
73
130
|
}
|
74
131
|
#fetchBoxes(args, inclConf, inclUnconf) {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
132
|
+
return inclConf && inclUnconf ? this.#getAllBoxes(args, this.#options.url) : inclUnconf ? this.#getUnconfirmedBoxes(args, this.#options.url) : this.#getConfirmedBoxes(args, this.#options.url);
|
133
|
+
}
|
134
|
+
setUrl(url) {
|
135
|
+
this.#options.url = url;
|
136
|
+
return this;
|
137
|
+
}
|
138
|
+
setBigIntMapper(mapper) {
|
139
|
+
this.#biMapper = mapper;
|
140
|
+
return this;
|
82
141
|
}
|
83
142
|
async *streamBoxes(query) {
|
84
143
|
if (common.isEmpty(query.where)) {
|
@@ -88,26 +147,25 @@ var ErgoGraphQLProvider = class {
|
|
88
147
|
const returnedBoxIds = /* @__PURE__ */ new Set();
|
89
148
|
const { where, from } = query;
|
90
149
|
const args = buildGqlBoxQueryArgs(where);
|
91
|
-
let
|
92
|
-
let
|
93
|
-
const isMempoolAware =
|
150
|
+
let inclChain = from !== "mempool";
|
151
|
+
let inclPool = from !== "blockchain";
|
152
|
+
const isMempoolAware = inclPool;
|
94
153
|
do {
|
95
|
-
const
|
96
|
-
const { data } = response;
|
154
|
+
const { data } = await this.#fetchBoxes(args, inclChain, inclPool);
|
97
155
|
let boxes = [];
|
98
|
-
if (
|
156
|
+
if (inclChain && hasConfirmed(data)) {
|
99
157
|
if (common.some(data.boxes)) {
|
100
|
-
const confirmedBoxes = (isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes).map(
|
158
|
+
const confirmedBoxes = (isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes).map((b) => mapConfirmedBox(b, this.#biMapper));
|
101
159
|
boxes = boxes.concat(confirmedBoxes);
|
102
160
|
}
|
103
|
-
|
161
|
+
inclChain = data.boxes.length === PAGE_SIZE;
|
104
162
|
}
|
105
163
|
if (isMempoolAware && hasMempool(data)) {
|
106
164
|
if (common.some(data.mempool.boxes)) {
|
107
|
-
const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map(
|
165
|
+
const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map((b) => mapUnconfirmedBox(b, this.#biMapper));
|
108
166
|
boxes = boxes.concat(mempoolBoxes);
|
109
167
|
}
|
110
|
-
|
168
|
+
inclPool = data.mempool.boxes.length === PAGE_SIZE;
|
111
169
|
}
|
112
170
|
if (common.some(boxes)) {
|
113
171
|
if (boxes.some((box) => returnedBoxIds.has(box.boxId))) {
|
@@ -115,23 +173,62 @@ var ErgoGraphQLProvider = class {
|
|
115
173
|
}
|
116
174
|
if (common.some(boxes)) {
|
117
175
|
boxes = common.uniqBy(boxes, (box) => box.boxId);
|
118
|
-
|
176
|
+
for (const box of boxes) returnedBoxIds.add(box.boxId);
|
119
177
|
yield boxes;
|
120
178
|
}
|
121
179
|
}
|
122
|
-
if (
|
123
|
-
|
124
|
-
} while (fetchFromChain || fetchFromMempool);
|
180
|
+
if (inclChain || inclPool) args.skip += PAGE_SIZE;
|
181
|
+
} while (inclChain || inclPool);
|
125
182
|
}
|
126
183
|
async getBoxes(query) {
|
127
|
-
|
128
|
-
for await (const chunk of this.streamBoxes(query))
|
129
|
-
|
184
|
+
const boxes = [];
|
185
|
+
for await (const chunk of this.streamBoxes(query)) boxes.push(chunk);
|
186
|
+
return common.orderBy(boxes.flat(), (box) => box.creationHeight);
|
187
|
+
}
|
188
|
+
async *streamUnconfirmedTransactions(query) {
|
189
|
+
const args = buildGqlUnconfirmedTxQueryArgs(query.where);
|
190
|
+
let keepFetching = true;
|
191
|
+
while (keepFetching) {
|
192
|
+
const response = await this.#getUnconfirmedTransactions(args);
|
193
|
+
if (common.some(response.data?.mempool?.transactions)) {
|
194
|
+
yield response.data.mempool.transactions.map(
|
195
|
+
(t) => mapUnconfirmedTransaction(t, this.#biMapper)
|
196
|
+
);
|
197
|
+
}
|
198
|
+
keepFetching = response.data?.mempool?.transactions?.length === PAGE_SIZE;
|
199
|
+
if (keepFetching) args.skip += PAGE_SIZE;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
async getUnconfirmedTransactions(query) {
|
203
|
+
const transactions = [];
|
204
|
+
for await (const chunk of this.streamUnconfirmedTransactions(query)) {
|
205
|
+
transactions.push(chunk);
|
130
206
|
}
|
131
|
-
return
|
207
|
+
return transactions.flat();
|
208
|
+
}
|
209
|
+
async *streamConfirmedTransactions(query) {
|
210
|
+
const args = buildGqlConfirmedTxQueryArgs(query.where);
|
211
|
+
let keepFetching = true;
|
212
|
+
while (keepFetching) {
|
213
|
+
const response = await this.#getConfirmedTransactions(args);
|
214
|
+
if (common.some(response.data?.transactions)) {
|
215
|
+
yield response.data.transactions.map(
|
216
|
+
(t) => mapConfirmedTransaction(t, this.#biMapper)
|
217
|
+
);
|
218
|
+
}
|
219
|
+
keepFetching = response.data?.transactions?.length === PAGE_SIZE;
|
220
|
+
if (keepFetching) args.skip += PAGE_SIZE;
|
221
|
+
}
|
222
|
+
}
|
223
|
+
async getConfirmedTransactions(query) {
|
224
|
+
const transactions = [];
|
225
|
+
for await (const chunk of this.streamConfirmedTransactions(query)) {
|
226
|
+
transactions.push(chunk);
|
227
|
+
}
|
228
|
+
return transactions.flat();
|
132
229
|
}
|
133
230
|
async getHeaders(query) {
|
134
|
-
const response = await this.#getHeaders(query);
|
231
|
+
const response = await this.#getHeaders(query, this.#options.url);
|
135
232
|
return response.data?.blockHeaders.map((header) => ({
|
136
233
|
...header,
|
137
234
|
id: header.headerId,
|
@@ -147,7 +244,10 @@ var ErgoGraphQLProvider = class {
|
|
147
244
|
}
|
148
245
|
async checkTransaction(signedTransaction) {
|
149
246
|
try {
|
150
|
-
const response = await this.#
|
247
|
+
const response = await this.#checkTransaction(
|
248
|
+
{ signedTransaction },
|
249
|
+
this.#options.url
|
250
|
+
);
|
151
251
|
return { success: true, transactionId: response.data.checkTransaction };
|
152
252
|
} catch (e) {
|
153
253
|
return { success: false, message: e.message };
|
@@ -155,7 +255,10 @@ var ErgoGraphQLProvider = class {
|
|
155
255
|
}
|
156
256
|
async submitTransaction(signedTransaction) {
|
157
257
|
try {
|
158
|
-
const response = await this.#
|
258
|
+
const response = await this.#sendTransaction(
|
259
|
+
{ signedTransaction },
|
260
|
+
this.#options.url
|
261
|
+
);
|
159
262
|
return { success: true, transactionId: response.data.submitTransaction };
|
160
263
|
} catch (e) {
|
161
264
|
return { success: false, message: e.message };
|
@@ -178,18 +281,42 @@ function buildGqlBoxQueryArgs(where) {
|
|
178
281
|
const addresses = merge(where.addresses, where.address);
|
179
282
|
if (common.some(addresses)) {
|
180
283
|
const trees = addresses.map(
|
181
|
-
(address) => typeof address === "string" ? core.ErgoAddress.
|
284
|
+
(address) => typeof address === "string" ? core.ErgoAddress.decode(address).ergoTree : address.ergoTree
|
182
285
|
);
|
183
286
|
args.ergoTrees = common.uniq(common.some(args.ergoTrees) ? args.ergoTrees.concat(trees) : trees);
|
184
287
|
}
|
185
288
|
return args;
|
186
289
|
}
|
290
|
+
function buildGqlUnconfirmedTxQueryArgs(where) {
|
291
|
+
const addresses = common.uniq(
|
292
|
+
[
|
293
|
+
merge(where.addresses, where.address)?.map(
|
294
|
+
(address) => typeof address === "string" ? address : address.encode()
|
295
|
+
) ?? [],
|
296
|
+
merge(where.ergoTrees, where.ergoTree)?.map(
|
297
|
+
(tree) => core.ErgoAddress.fromErgoTree(tree).encode()
|
298
|
+
) ?? []
|
299
|
+
].flat()
|
300
|
+
);
|
301
|
+
return {
|
302
|
+
addresses: addresses.length ? addresses : void 0,
|
303
|
+
transactionIds: merge(where.transactionIds, where.transactionId),
|
304
|
+
skip: 0,
|
305
|
+
take: PAGE_SIZE
|
306
|
+
};
|
307
|
+
}
|
308
|
+
function buildGqlConfirmedTxQueryArgs(where) {
|
309
|
+
return {
|
310
|
+
...buildGqlUnconfirmedTxQueryArgs(where),
|
311
|
+
headerId: where.headerId,
|
312
|
+
minHeight: where.minHeight,
|
313
|
+
onlyRelevantOutputs: where.onlyRelevantOutputs
|
314
|
+
};
|
315
|
+
}
|
187
316
|
function merge(array, el) {
|
188
|
-
if (common.isEmpty(array) && common.isUndefined(el))
|
189
|
-
return;
|
317
|
+
if (common.isEmpty(array) && common.isUndefined(el)) return;
|
190
318
|
const set = new Set(array ?? []);
|
191
|
-
if (!common.isUndefined(el))
|
192
|
-
set.add(el);
|
319
|
+
if (!common.isUndefined(el)) set.add(el);
|
193
320
|
return Array.from(set.values());
|
194
321
|
}
|
195
322
|
function hasMempool(data) {
|
@@ -198,18 +325,70 @@ function hasMempool(data) {
|
|
198
325
|
function hasConfirmed(data) {
|
199
326
|
return !!data?.boxes;
|
200
327
|
}
|
201
|
-
function
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
328
|
+
function mapConfirmedBox(box, mapper) {
|
329
|
+
const mapped = mapBox(box, mapper);
|
330
|
+
mapped.confirmed = true;
|
331
|
+
return mapped;
|
332
|
+
}
|
333
|
+
function mapUnconfirmedBox(box, mapper) {
|
334
|
+
const mapped = mapBox(box, mapper);
|
335
|
+
mapped.confirmed = false;
|
336
|
+
return mapped;
|
337
|
+
}
|
338
|
+
function mapBox(box, mapper) {
|
339
|
+
return {
|
340
|
+
boxId: box.boxId,
|
341
|
+
transactionId: box.transactionId,
|
342
|
+
value: mapper(box.value),
|
343
|
+
ergoTree: box.ergoTree,
|
344
|
+
assets: box.assets.map((t) => ({ tokenId: t.tokenId, amount: mapper(t.amount) })),
|
345
|
+
creationHeight: box.creationHeight,
|
346
|
+
additionalRegisters: box.additionalRegisters,
|
347
|
+
index: box.index
|
348
|
+
};
|
349
|
+
}
|
350
|
+
function mapUnconfirmedTransaction(tx, mapper) {
|
351
|
+
return {
|
352
|
+
transactionId: tx.transactionId,
|
353
|
+
timestamp: Number(tx.timestamp),
|
354
|
+
inputs: tx.inputs.map((i) => ({
|
355
|
+
spendingProof: {
|
356
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
357
|
+
extension: i.extension,
|
358
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
359
|
+
proofBytes: i.proofBytes
|
360
|
+
},
|
361
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
362
|
+
...mapBox(i.box, mapper)
|
208
363
|
})),
|
209
|
-
|
210
|
-
|
364
|
+
dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),
|
365
|
+
outputs: tx.outputs.map((b) => mapBox(b, mapper)),
|
366
|
+
confirmed: false
|
367
|
+
};
|
368
|
+
}
|
369
|
+
function mapConfirmedTransaction(tx, mapper) {
|
370
|
+
return {
|
371
|
+
transactionId: tx.transactionId,
|
372
|
+
timestamp: Number(tx.timestamp),
|
373
|
+
inputs: tx.inputs.map((i) => ({
|
374
|
+
spendingProof: {
|
375
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
376
|
+
extension: i.extension,
|
377
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
378
|
+
proofBytes: i.proofBytes
|
379
|
+
},
|
380
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
381
|
+
...mapBox(i.box, mapper)
|
382
|
+
})),
|
383
|
+
dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),
|
384
|
+
outputs: tx.outputs.map((b) => mapBox(b, mapper)),
|
385
|
+
height: tx.inclusionHeight,
|
386
|
+
headerId: tx.headerId,
|
387
|
+
index: tx.index,
|
388
|
+
confirmed: true
|
389
|
+
};
|
211
390
|
}
|
212
391
|
|
213
392
|
exports.ErgoGraphQLProvider = ErgoGraphQLProvider;
|
214
|
-
//# sourceMappingURL=
|
393
|
+
//# sourceMappingURL=index.js.map
|
215
394
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/ergo-graphql/ergoGraphQLProvider.ts","../src/utils/graphql.ts","../src/ergo-graphql/queries.ts"],"names":["ensureDefaults","isEmpty","some"],"mappings":"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","sourcesContent":["import {\n Box,\n QueryBoxesArgs as BoxesArgs,\n Header,\n QueryBlockHeadersArgs as HeadersArgs\n} from \"@ergo-graphql/types\";\nimport {\n Base58String,\n BlockHeader,\n ensureDefaults,\n HexString,\n isEmpty,\n isUndefined,\n NotSupportedError,\n orderBy,\n SignedTransaction,\n some,\n uniq,\n uniqBy\n} from \"@fleet-sdk/common\";\nimport { ErgoAddress } from \"@fleet-sdk/core\";\nimport {\n BoxQuery,\n BoxWhere,\n ChainProviderBox,\n HeaderQuery,\n IBlockchainProvider,\n TransactionEvaluationResult,\n TransactionReductionResult\n} from \"../types\";\nimport {\n createGqlOperation,\n GraphQLOperation,\n GraphQLRequestOptions,\n GraphQLSuccessResponse,\n GraphQLThrowableOptions,\n GraphQLVariables,\n isRequestParam\n} from \"../utils\";\nimport {\n ALL_BOXES_QUERY,\n CHECK_TX_MUTATION,\n CONF_BOXES_QUERY,\n HEADERS_QUERY,\n SEND_TX_MUTATION,\n UNCONF_BOXES_QUERY\n} from \"./queries\";\n\nexport type GraphQLBoxWhere = BoxWhere & {\n /** Base16-encoded BoxIds */\n boxIds?: HexString[];\n\n /** Base16-encoded ErgoTrees */\n ergoTrees?: HexString[];\n\n /** Base58-encoded addresses or `ErgoAddress` objects */\n addresses?: (Base58String | ErgoAddress)[];\n};\n\nexport type GraphQLBoxQuery = BoxQuery<GraphQLBoxWhere>;\nexport type ErgoGraphQLRequestOptions = Omit<GraphQLRequestOptions, \"throwOnNonNetworkError\">;\n\ntype ConfBoxesResp = { boxes: Box[] };\ntype UnconfBoxesResp = { mempool: { boxes: Box[] } };\ntype AllBoxesResp = ConfBoxesResp & UnconfBoxesResp;\ntype HeadersResp = { blockHeaders: Header[] };\ntype CheckTxResp = { checkTransaction: string };\ntype SendTxResp = { submitTransaction: string };\ntype SignedTxArgsResp = { signedTransaction: SignedTransaction };\n\nconst PAGE_SIZE = 50;\n\nexport class ErgoGraphQLProvider implements IBlockchainProvider<BoxWhere> {\n #options: GraphQLThrowableOptions;\n\n #getConfBoxes;\n #getUnconfBoxes;\n #getAllBoxes;\n #getHeaders;\n #checkTx;\n #sendTx;\n\n constructor(url: string | URL);\n constructor(url: ErgoGraphQLRequestOptions);\n constructor(optOrUrl: ErgoGraphQLRequestOptions | string | URL) {\n this.#options = {\n ...(isRequestParam(optOrUrl) ? optOrUrl : { url: optOrUrl }),\n throwOnNonNetworkErrors: true\n };\n\n this.#getConfBoxes = this.createOperation<ConfBoxesResp, BoxesArgs>(CONF_BOXES_QUERY);\n this.#getUnconfBoxes = this.createOperation<UnconfBoxesResp, BoxesArgs>(UNCONF_BOXES_QUERY);\n this.#getAllBoxes = this.createOperation<AllBoxesResp, BoxesArgs>(ALL_BOXES_QUERY);\n this.#getHeaders = this.createOperation<HeadersResp, HeadersArgs>(HEADERS_QUERY);\n this.#checkTx = this.createOperation<CheckTxResp, SignedTxArgsResp>(CHECK_TX_MUTATION);\n this.#sendTx = this.createOperation<SendTxResp, SignedTxArgsResp>(SEND_TX_MUTATION);\n }\n\n #fetchBoxes(args: BoxesArgs, inclConf: boolean, inclUnconf: boolean) {\n if (inclConf && inclUnconf) {\n return this.#getAllBoxes(args);\n } else if (inclUnconf) {\n return this.#getUnconfBoxes(args);\n } else {\n return this.#getConfBoxes(args);\n }\n }\n\n async *streamBoxes(query: GraphQLBoxQuery): AsyncGenerator<ChainProviderBox[]> {\n if (isEmpty(query.where)) {\n throw new Error(\"Cannot fetch unspent boxes without a where clause.\");\n }\n\n const notBeingSpent = (box: Box) => !box.beingSpent;\n const returnedBoxIds = new Set<string>();\n const { where, from } = query;\n const args = buildGqlBoxQueryArgs(where);\n\n let fetchFromChain = from !== \"mempool\";\n let fetchFromMempool = from !== \"blockchain\";\n const isMempoolAware = fetchFromMempool;\n\n do {\n const response = await this.#fetchBoxes(args, fetchFromChain, fetchFromMempool);\n\n const { data } = response;\n let boxes: ChainProviderBox[] = [];\n\n if (fetchFromChain && hasConfirmed(data)) {\n if (some(data.boxes)) {\n const confirmedBoxes = (\n isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes\n ).map(asConfirmed(true));\n\n boxes = boxes.concat(confirmedBoxes);\n }\n\n fetchFromChain = data.boxes.length === PAGE_SIZE;\n }\n\n if (isMempoolAware && hasMempool(data)) {\n if (some(data.mempool.boxes)) {\n const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map(asConfirmed(false));\n boxes = boxes.concat(mempoolBoxes);\n }\n\n fetchFromMempool = data.mempool.boxes.length === PAGE_SIZE;\n }\n\n if (some(boxes)) {\n // boxes can be moved from the mempool to the blockchain while streaming,\n // so we need to filter out boxes that have already been returned.\n if (boxes.some((box) => returnedBoxIds.has(box.boxId))) {\n boxes = boxes.filter((b) => !returnedBoxIds.has(b.boxId));\n }\n\n if (some(boxes)) {\n boxes = uniqBy(boxes, (box) => box.boxId);\n boxes.forEach((box) => returnedBoxIds.add(box.boxId));\n\n yield boxes;\n }\n }\n\n if (fetchFromChain || fetchFromMempool) args.skip += PAGE_SIZE;\n } while (fetchFromChain || fetchFromMempool);\n }\n\n async getBoxes(query: GraphQLBoxQuery): Promise<ChainProviderBox[]> {\n let boxes: ChainProviderBox[] = [];\n for await (const chunk of this.streamBoxes(query)) {\n boxes = boxes.concat(chunk);\n }\n\n return orderBy(boxes, (box) => box.creationHeight);\n }\n\n async getHeaders(query: HeaderQuery): Promise<BlockHeader[]> {\n const response = await this.#getHeaders(query);\n\n return (\n response.data?.blockHeaders.map((header) => ({\n ...header,\n id: header.headerId,\n timestamp: Number(header.timestamp),\n nBits: Number(header.nBits),\n votes: header.votes.join(\"\")\n })) ?? []\n );\n }\n\n createOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options?: Partial<ErgoGraphQLRequestOptions>\n ): GraphQLOperation<GraphQLSuccessResponse<R>, V> {\n const opt = ensureDefaults(options, this.#options);\n opt.throwOnNonNetworkErrors = true;\n\n return createGqlOperation(query, opt);\n }\n\n async checkTransaction(\n signedTransaction: SignedTransaction\n ): Promise<TransactionEvaluationResult> {\n try {\n const response = await this.#checkTx({ signedTransaction });\n\n return { success: true, transactionId: response.data.checkTransaction };\n } catch (e) {\n return { success: false, message: (e as Error).message };\n }\n }\n\n async submitTransaction(\n signedTransaction: SignedTransaction\n ): Promise<TransactionEvaluationResult> {\n try {\n const response = await this.#sendTx({ signedTransaction });\n\n return { success: true, transactionId: response.data.submitTransaction };\n } catch (e) {\n return { success: false, message: (e as Error).message };\n }\n }\n\n reduceTransaction(): Promise<TransactionReductionResult> {\n throw new NotSupportedError(\"Transaction reducing is not supported by ergo-graphql.\");\n }\n}\n\nfunction buildGqlBoxQueryArgs(where: GraphQLBoxWhere) {\n const args = {\n spent: false,\n boxIds: merge(where.boxIds, where.boxId),\n ergoTrees: merge(where.ergoTrees, where.ergoTree),\n ergoTreeTemplateHash: where.templateHash,\n tokenId: where.tokenId,\n skip: 0,\n take: PAGE_SIZE\n } satisfies BoxesArgs;\n\n const addresses = merge(where.addresses, where.address);\n if (some(addresses)) {\n const trees = addresses.map((address) =>\n typeof address === \"string\" ? ErgoAddress.fromBase58(address).ergoTree : address.ergoTree\n );\n\n args.ergoTrees = uniq(some(args.ergoTrees) ? args.ergoTrees.concat(trees) : trees);\n }\n\n return args;\n}\n\nfunction merge<T>(array?: T[], el?: T) {\n if (isEmpty(array) && isUndefined(el)) return;\n\n const set = new Set<T>(array ?? []);\n if (!isUndefined(el)) set.add(el);\n return Array.from(set.values());\n}\n\nfunction hasMempool(data: AllBoxesResp | ConfBoxesResp | UnconfBoxesResp): data is UnconfBoxesResp {\n return !!(data as UnconfBoxesResp)?.mempool?.boxes;\n}\n\nfunction hasConfirmed(data: AllBoxesResp | ConfBoxesResp | UnconfBoxesResp): data is ConfBoxesResp {\n return !!(data as ConfBoxesResp)?.boxes;\n}\n\nfunction asConfirmed(confirmed: boolean) {\n return (box: Box): ChainProviderBox => ({\n ...box,\n value: BigInt(box.value),\n assets: box.assets.map((asset) => ({\n tokenId: asset.tokenId,\n amount: BigInt(asset.amount)\n })),\n confirmed\n });\n}\n","import {\n BlockchainProviderError,\n clearUndefined,\n ensureDefaults,\n isEmpty,\n some\n} from \"@fleet-sdk/common\";\n\nconst OP_NAME_REGEX = /(query|mutation)\\s?([\\w\\-_]+)?/;\nexport const DEFAULT_HEADERS: Headers = {\n \"content-type\": \"application/json; charset=utf-8\",\n accept: \"application/graphql-response+json, application/json\"\n};\n\ntype Credentials = RequestCredentials;\ntype Headers = HeadersInit;\ntype Fetcher = typeof fetch;\n\nexport type GraphQLVariables = Record<string, unknown> | null;\n\nexport interface GraphQLError {\n message: string;\n}\n\nexport interface GraphQLSuccessResponse<T = unknown> {\n data: T;\n errors: null;\n}\n\nexport interface GraphQLErrorResponse {\n data: null;\n errors: GraphQLError[];\n}\n\nexport type GraphQLResponse<T = unknown> = GraphQLSuccessResponse<T> | GraphQLErrorResponse;\n\nexport type GraphQLOperation<R extends GraphQLResponse, V extends GraphQLVariables> = (\n variables?: V\n) => Promise<R>;\n\nexport interface ResponseParser {\n parse<T>(text: string): T;\n stringify<T>(value: T): string;\n}\n\nexport interface RequestParams {\n operationName?: string | null;\n query: string;\n variables?: Record<string, unknown> | null;\n}\n\nexport interface GraphQLRequestOptions {\n url: URL | string;\n headers?: Headers;\n parser?: ResponseParser;\n fetcher?: Fetcher;\n credentials?: Credentials;\n throwOnNonNetworkErrors?: boolean;\n}\n\nexport interface GraphQLThrowableOptions extends GraphQLRequestOptions {\n throwOnNonNetworkErrors: true;\n}\n\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLThrowableOptions\n): GraphQLOperation<GraphQLSuccessResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLRequestOptions\n): GraphQLOperation<GraphQLResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLRequestOptions\n): GraphQLOperation<GraphQLResponse<R>, V> {\n return async (variables?: V): Promise<GraphQLResponse<R>> => {\n const response = await (options.fetcher ?? fetch)(options.url, {\n method: \"POST\",\n headers: ensureDefaults(options.headers, DEFAULT_HEADERS),\n credentials: options.credentials,\n body: (options.parser ?? JSON).stringify({\n operationName: getOpName(query),\n query,\n variables: variables ? clearUndefined(variables) : undefined\n } as RequestParams)\n });\n\n const rawData = await response.text();\n const parsedData = (options.parser ?? JSON).parse(rawData) as GraphQLResponse<R>;\n\n if (options.throwOnNonNetworkErrors && some(parsedData.errors) && isEmpty(parsedData.data)) {\n throw new BlockchainProviderError(parsedData.errors[0].message, { cause: parsedData.errors });\n }\n\n return parsedData;\n };\n}\n\nexport function gql(query: TemplateStringsArray): string {\n return query[0];\n}\n\nexport function getOpName(query: string): string | undefined {\n return OP_NAME_REGEX.exec(query)?.at(2);\n}\n\nexport function isRequestParam(obj: unknown): obj is GraphQLRequestOptions {\n return typeof obj === \"object\" && (obj as GraphQLRequestOptions).url !== undefined;\n}\n","const B = [\n `query boxes($spent: Boolean! $boxIds: [String!] $ergoTrees: [String!] $ergoTreeTemplateHash: String $tokenId: String $skip: Int $take: Int)`,\n `boxIds: $boxIds ergoTrees: $ergoTrees ergoTreeTemplateHash: $ergoTreeTemplateHash tokenId: $tokenId skip: $skip take: $take`,\n `boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters beingSpent`\n];\n\nexport const CONF_BOXES_QUERY = `${B[0]} { boxes(spent: $spent ${B[1]}) { ${B[2]} } }`;\nexport const UNCONF_BOXES_QUERY = `${B[0]} { mempool { boxes(${B[1]}) { ${B[2]} } } }`;\nexport const ALL_BOXES_QUERY = `${B[0]} { boxes(spent: $spent ${B[1]}) { ${B[2]} } mempool { boxes(${B[1]}) { ${B[2]} } } }`;\nexport const HEADERS_QUERY = `query blockHeaders($take: Int) { blockHeaders(take: $take) {headerId timestamp version adProofsRoot stateRoot transactionsRoot nBits extensionHash powSolutions height difficulty parentId votes } }`;\nexport const CHECK_TX_MUTATION = `mutation checkTransaction($signedTransaction: SignedTransaction!) { checkTransaction(signedTransaction: $signedTransaction) }`;\nexport const SEND_TX_MUTATION = `mutation submitTransaction($signedTransaction: SignedTransaction!) { submitTransaction(signedTransaction: $signedTransaction) }`;\n"]}
|
1
|
+
{"version":3,"sources":["../src/utils/networking.ts","../src/utils/graphql.ts","../src/ergo-graphql/queries.ts","../src/ergo-graphql/ergoGraphQLProvider.ts"],"names":["some","ensureDefaults","clearUndefined","isEmpty","BlockchainProviderError","uniqBy","orderBy","NotSupportedError","ErgoAddress","uniq","isUndefined"],"mappings":"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","file":"index.js","sourcesContent":["import { some } from \"@fleet-sdk/common\";\nimport { isEmpty } from \"packages/common/src\";\n\nexport interface ParserLike {\n parse<T>(text: string): T;\n stringify<T>(value: T): string;\n}\n\nexport type Route = { base: string; path: string; query?: Record<string, unknown> };\nexport type URLLike = string | Route;\nexport type FallbackRetryOptions = { fallbacks?: URLLike[] } & RetryOptions;\n\nexport type FetchOptions = {\n parser?: ParserLike;\n base?: string;\n query?: Record<string, unknown>;\n retry?: FallbackRetryOptions;\n httpOptions?: RequestInit;\n};\n\nexport async function request<T>(path: string, opt?: Partial<FetchOptions>): Promise<T> {\n const url = buildURL(path, opt?.query, opt?.base);\n\n let response: Response;\n if (opt?.retry) {\n const routes = some(opt.retry.fallbacks) ? [url, ...opt.retry.fallbacks] : [url];\n const attempts = opt.retry.attempts;\n response = await exponentialRetry(\n (r) => fetch(resolveUrl(routes, attempts - r), opt.httpOptions),\n opt.retry\n );\n } else {\n response = await fetch(url, opt?.httpOptions);\n }\n\n return (opt?.parser || JSON).parse(await response.text());\n}\n\nfunction resolveUrl(routes: URLLike[], attempt: number) {\n const route = routes[attempt % routes.length];\n return typeof route === \"string\"\n ? route\n : buildURL(route.path, route.query, route.base).toString();\n}\n\nfunction buildURL(path: string, query?: Record<string, unknown>, base?: string) {\n if (!base && !query) return path;\n\n const url = new URL(path, base);\n if (some(query)) {\n for (const key in query) url.searchParams.append(key, String(query[key]));\n }\n\n return url.toString();\n}\n\nexport type RetryOptions = {\n attempts: number;\n delay: number;\n};\n\n/**\n * Retries an asynchronous operation a specified number of times with a delay\n * growing exponentially between each attempt.\n * @param operation - The asynchronous operation to retry.\n * @param options - The retry options.\n * @returns A promise that resolves to the result of the operation, or undefined\n * if all attempts fail.\n */\nexport async function exponentialRetry<T>(\n operation: (remainingAttempts: number) => Promise<T>,\n { attempts, delay }: RetryOptions\n): Promise<T> {\n try {\n return await operation(attempts);\n } catch (e) {\n if (attempts > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n return exponentialRetry(operation, { attempts: attempts - 1, delay: delay * 2 });\n }\n\n throw e;\n }\n}\n","import {\n BlockchainProviderError,\n clearUndefined,\n ensureDefaults,\n isEmpty,\n some\n} from \"@fleet-sdk/common\";\nimport type { FallbackRetryOptions, ParserLike } from \"./networking\";\nimport { request } from \"./networking\";\n\nconst OP_NAME_REGEX = /(query|mutation)\\s?([\\w\\-_]+)?/;\nexport const DEFAULT_HEADERS = {\n \"content-type\": \"application/json; charset=utf-8\",\n accept: \"application/graphql-response+json, application/json\"\n};\n\nexport type GraphQLVariables = Record<string, unknown> | null;\n\nexport interface GraphQLError {\n message: string;\n}\n\nexport interface GraphQLSuccessResponse<T = unknown> {\n data: T;\n errors: null;\n}\n\nexport interface GraphQLErrorResponse {\n data: null;\n errors: GraphQLError[];\n}\n\nexport type GraphQLResponse<T = unknown> =\n | GraphQLSuccessResponse<T>\n | GraphQLErrorResponse;\n\nexport type GraphQLOperation<R extends GraphQLResponse, V extends GraphQLVariables> = (\n variables?: V,\n url?: string\n) => Promise<R>;\n\nexport type GraphQLRequiredUrlOperation<\n R extends GraphQLResponse,\n V extends GraphQLVariables\n> = (variables: V | undefined, url: string) => Promise<R>;\n\ninterface RequestParams {\n operationName?: string | null;\n query: string;\n variables?: Record<string, unknown> | null;\n}\n\nexport interface GraphQLRequestOptions {\n url?: string;\n parser?: ParserLike;\n retry?: FallbackRetryOptions;\n throwOnNonNetworkErrors?: boolean;\n httpOptions?: Omit<RequestInit, \"body\" | \"method\">;\n}\n\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLRequestOptions & { throwOnNonNetworkErrors: true }\n): GraphQLOperation<GraphQLSuccessResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options?: GraphQLRequestOptions & { url: undefined }\n): GraphQLRequiredUrlOperation<GraphQLResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLRequestOptions & { url: undefined; throwOnNonNetworkErrors: true }\n): GraphQLRequiredUrlOperation<GraphQLSuccessResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options: GraphQLRequestOptions\n): GraphQLOperation<GraphQLResponse<R>, V>;\nexport function createGqlOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options?: GraphQLRequestOptions\n):\n | GraphQLOperation<GraphQLResponse<R>, V>\n | GraphQLRequiredUrlOperation<GraphQLResponse<R>, V> {\n return async (variables?: V, url?: string): Promise<GraphQLResponse<R>> => {\n url = url ?? options?.url;\n if (!url) throw new Error(\"URL is required\");\n\n const response = await request<GraphQLResponse<R>>(url, {\n ...options,\n httpOptions: {\n ...options?.httpOptions,\n method: \"POST\",\n headers: ensureDefaults(options?.httpOptions?.headers, DEFAULT_HEADERS),\n body: (options?.parser ?? JSON).stringify({\n operationName: getOpName(query),\n query,\n variables: variables ? clearUndefined(variables) : undefined\n } as RequestParams)\n }\n });\n\n if (\n options?.throwOnNonNetworkErrors &&\n some(response.errors) &&\n isEmpty(response.data)\n ) {\n const msg = response.errors[0].message;\n throw new BlockchainProviderError(msg, { cause: response.errors });\n }\n\n return response;\n };\n}\n\nexport function gql(query: TemplateStringsArray): string {\n return query[0];\n}\n\nexport function getOpName(query: string): string | undefined {\n return OP_NAME_REGEX.exec(query)?.at(2);\n}\n\nexport function isRequestParam(obj: unknown): obj is GraphQLRequestOptions {\n return typeof obj === \"object\" && (obj as GraphQLRequestOptions).url !== undefined;\n}\n","const B = [\n \"$boxIds: [String!] $ergoTrees: [String!] $ergoTreeTemplateHash: String $tokenId: String $skip: Int $take: Int\",\n \"boxIds: $boxIds ergoTrees: $ergoTrees ergoTreeTemplateHash: $ergoTreeTemplateHash tokenId: $tokenId skip: $skip take: $take\",\n \"boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters\"\n];\n\nexport const CONF_BOXES_QUERY = `query boxes($spent: Boolean! ${B[0]}) { boxes(spent: $spent ${B[1]}) { ${B[2]} beingSpent } }`;\nexport const UNCONF_BOXES_QUERY = `query boxes(${B[0]}) { mempool { boxes(${B[1]}) { ${B[2]} beingSpent } } }`;\nexport const ALL_BOXES_QUERY = `query boxes($spent: Boolean! ${B[0]}) { boxes(spent: $spent ${B[1]}) { ${B[2]} beingSpent } mempool { boxes(${B[1]}) { ${B[2]} beingSpent } } }`;\n\nexport const HEADERS_QUERY =\n \"query blockHeaders($take: Int) { blockHeaders(take: $take) {headerId timestamp version adProofsRoot stateRoot transactionsRoot nBits extensionHash powSolutions height difficulty parentId votes } }\";\nexport const CHECK_TX_MUTATION =\n \"mutation checkTransaction($signedTransaction: SignedTransaction!) { checkTransaction(signedTransaction: $signedTransaction) }\";\nexport const SEND_TX_MUTATION =\n \"mutation submitTransaction($signedTransaction: SignedTransaction!) { submitTransaction(signedTransaction: $signedTransaction) }\";\n\nconst T = [\n \"$addresses: [String!], $transactionIds: [String!], $skip: Int, $take: Int\",\n \"addresses: $addresses, transactionIds: $transactionIds, skip: $skip, take: $take\",\n `transactionId timestamp inputs { proofBytes extension index box { ${B[2]} } } dataInputs { boxId }`\n];\nexport const CONF_TX_QUERY = `query confirmedTransactions(${T[0]} $relevantOnly: Boolean) { transactions(${T[1]}) { ${T[2]} outputs(relevantOnly: $relevantOnly) { ${B[2]} } inclusionHeight headerId index } }`;\nexport const UNCONF_TX_QUERY = `query unconfirmedTransactions(${T[0]}) { mempool { transactions(${T[1]}) { ${T[2]} outputs { ${B[2]} } } } }`;\n","import type {\n Box as GQLBox,\n QueryBoxesArgs,\n Header,\n QueryBlockHeadersArgs,\n Transaction,\n QueryTransactionsArgs,\n MempoolTransactionsArgs,\n UnconfirmedTransaction,\n UnconfirmedBox as GQLUnconfirmedBox\n} from \"@ergo-graphql/types\";\nimport {\n type Base58String,\n type BlockHeader,\n ensureDefaults,\n type HexString,\n isEmpty,\n isUndefined,\n NotSupportedError,\n orderBy,\n type SignedTransaction,\n some,\n uniq,\n uniqBy\n} from \"@fleet-sdk/common\";\nimport { ErgoAddress } from \"@fleet-sdk/core\";\nimport type {\n BoxQuery,\n BoxWhere,\n ChainProviderBox,\n ChainProviderConfirmedTransaction,\n ChainProviderUnconfirmedTransaction,\n HeaderQuery,\n IBlockchainProvider,\n TransactionEvaluationResult,\n TransactionQuery,\n TransactionReductionResult,\n ConfirmedTransactionWhere,\n UnconfirmedTransactionWhere\n} from \"../types/blockchainProvider\";\nimport {\n createGqlOperation,\n type GraphQLOperation,\n type GraphQLRequestOptions,\n type GraphQLSuccessResponse,\n type GraphQLVariables,\n isRequestParam\n} from \"../utils\";\nimport {\n ALL_BOXES_QUERY,\n CHECK_TX_MUTATION,\n CONF_BOXES_QUERY,\n CONF_TX_QUERY,\n HEADERS_QUERY,\n SEND_TX_MUTATION,\n UNCONF_BOXES_QUERY,\n UNCONF_TX_QUERY\n} from \"./queries\";\n\ntype GraphQLThrowableOptions = GraphQLRequestOptions & { throwOnNonNetworkErrors: true };\ntype OP<R, V extends GraphQLVariables> = GraphQLOperation<GraphQLSuccessResponse<R>, V>;\ntype BiMapper<T> = (value: string) => T;\n\nexport type GraphQLBoxWhere = BoxWhere & {\n /** Base16-encoded BoxIds */\n boxIds?: HexString[];\n\n /** Base16-encoded ErgoTrees */\n ergoTrees?: HexString[];\n\n /** Base58-encoded addresses or `ErgoAddress` objects */\n addresses?: (Base58String | ErgoAddress)[];\n};\n\nexport type GraphQLConfirmedTransactionWhere = ConfirmedTransactionWhere & {\n transactionIds?: HexString[];\n addresses?: (Base58String | ErgoAddress)[];\n ergoTrees?: HexString[];\n};\n\nexport type GraphQLUnconfirmedTransactionWhere = UnconfirmedTransactionWhere & {\n transactionIds?: HexString[];\n addresses?: (Base58String | ErgoAddress)[];\n ergoTrees?: HexString[];\n};\n\nexport type GraphQLBoxQuery = BoxQuery<GraphQLBoxWhere>;\nexport type ErgoGraphQLRequestOptions = Omit<\n GraphQLRequestOptions,\n \"throwOnNonNetworkError\"\n>;\n\ntype ConfirmedBoxesResponse = { boxes: GQLBox[] };\ntype UnconfirmedBoxesResponse = { mempool: { boxes: GQLBox[] } };\ntype CombinedBoxesResponse = ConfirmedBoxesResponse & UnconfirmedBoxesResponse;\ntype UnconfirmedTxResponse = { mempool: { transactions: UnconfirmedTransaction[] } };\ntype ConfirmedTxResponse = { transactions: Transaction[] };\ntype BlockHeadersResponse = { blockHeaders: Header[] };\ntype CheckTransactionResponse = { checkTransaction: string };\ntype TransactionSubmissionResponse = { submitTransaction: string };\ntype SignedTxArgsResp = { signedTransaction: SignedTransaction };\n\nconst PAGE_SIZE = 50;\n\nexport class ErgoGraphQLProvider<I = bigint> implements IBlockchainProvider<I> {\n #options: GraphQLThrowableOptions;\n #biMapper: BiMapper<I>;\n\n #getConfirmedBoxes: OP<ConfirmedBoxesResponse, QueryBoxesArgs>;\n #getUnconfirmedBoxes: OP<UnconfirmedBoxesResponse, QueryBoxesArgs>;\n #getAllBoxes: OP<CombinedBoxesResponse, QueryBoxesArgs>;\n #getConfirmedTransactions: OP<ConfirmedTxResponse, QueryTransactionsArgs>;\n #getUnconfirmedTransactions: OP<UnconfirmedTxResponse, MempoolTransactionsArgs>;\n #checkTransaction: OP<CheckTransactionResponse, SignedTxArgsResp>;\n #sendTransaction: OP<TransactionSubmissionResponse, SignedTxArgsResp>;\n #getHeaders!: OP<BlockHeadersResponse, QueryBlockHeadersArgs>;\n\n constructor(url: string);\n constructor(url: ErgoGraphQLRequestOptions);\n constructor(optOrUrl: ErgoGraphQLRequestOptions | string) {\n this.#options = {\n ...(isRequestParam(optOrUrl) ? optOrUrl : { url: optOrUrl }),\n throwOnNonNetworkErrors: true\n };\n\n this.#biMapper = (value) => BigInt(value) as I;\n\n this.#getConfirmedBoxes = this.createOperation(CONF_BOXES_QUERY);\n this.#getUnconfirmedBoxes = this.createOperation(UNCONF_BOXES_QUERY);\n this.#getAllBoxes = this.createOperation(ALL_BOXES_QUERY);\n this.#getConfirmedTransactions = this.createOperation(CONF_TX_QUERY);\n this.#getUnconfirmedTransactions = this.createOperation(UNCONF_TX_QUERY);\n this.#checkTransaction = this.createOperation(CHECK_TX_MUTATION);\n this.#sendTransaction = this.createOperation(SEND_TX_MUTATION);\n this.#getHeaders = this.createOperation(HEADERS_QUERY);\n }\n\n #fetchBoxes(args: QueryBoxesArgs, inclConf: boolean, inclUnconf: boolean) {\n return inclConf && inclUnconf\n ? this.#getAllBoxes(args, this.#options.url)\n : inclUnconf\n ? this.#getUnconfirmedBoxes(args, this.#options.url)\n : this.#getConfirmedBoxes(args, this.#options.url);\n }\n\n setUrl(url: string): ErgoGraphQLProvider<I> {\n this.#options.url = url;\n return this;\n }\n\n setBigIntMapper<M>(mapper: BiMapper<M>): ErgoGraphQLProvider<M> {\n this.#biMapper = mapper as unknown as BiMapper<I>;\n return this as unknown as ErgoGraphQLProvider<M>;\n }\n\n async *streamBoxes(query: GraphQLBoxQuery): AsyncGenerator<ChainProviderBox<I>[]> {\n if (isEmpty(query.where)) {\n throw new Error(\"Cannot fetch unspent boxes without a where clause.\");\n }\n\n const notBeingSpent = (box: GQLBox) => !box.beingSpent;\n const returnedBoxIds = new Set<string>();\n const { where, from } = query;\n const args = buildGqlBoxQueryArgs(where);\n\n let inclChain = from !== \"mempool\";\n let inclPool = from !== \"blockchain\";\n const isMempoolAware = inclPool;\n\n do {\n const { data } = await this.#fetchBoxes(args, inclChain, inclPool);\n let boxes: ChainProviderBox<I>[] = [];\n\n if (inclChain && hasConfirmed(data)) {\n if (some(data.boxes)) {\n const confirmedBoxes = (\n isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes\n ).map((b) => mapConfirmedBox(b, this.#biMapper));\n\n boxes = boxes.concat(confirmedBoxes);\n }\n\n inclChain = data.boxes.length === PAGE_SIZE;\n }\n\n if (isMempoolAware && hasMempool(data)) {\n if (some(data.mempool.boxes)) {\n const mempoolBoxes = data.mempool.boxes\n .filter(notBeingSpent)\n .map((b) => mapUnconfirmedBox(b, this.#biMapper));\n boxes = boxes.concat(mempoolBoxes);\n }\n\n inclPool = data.mempool.boxes.length === PAGE_SIZE;\n }\n\n if (some(boxes)) {\n // boxes can be moved from the mempool to the blockchain while streaming,\n // so we need to filter out boxes that have already been returned.\n if (boxes.some((box) => returnedBoxIds.has(box.boxId))) {\n boxes = boxes.filter((b) => !returnedBoxIds.has(b.boxId));\n }\n\n if (some(boxes)) {\n boxes = uniqBy(boxes, (box) => box.boxId);\n for (const box of boxes) returnedBoxIds.add(box.boxId);\n yield boxes;\n }\n }\n\n if (inclChain || inclPool) args.skip += PAGE_SIZE;\n } while (inclChain || inclPool);\n }\n\n async getBoxes(query: GraphQLBoxQuery): Promise<ChainProviderBox<I>[]> {\n const boxes: ChainProviderBox<I>[][] = [];\n for await (const chunk of this.streamBoxes(query)) boxes.push(chunk);\n return orderBy(boxes.flat(), (box) => box.creationHeight);\n }\n\n async *streamUnconfirmedTransactions(\n query: TransactionQuery<GraphQLUnconfirmedTransactionWhere>\n ): AsyncIterable<ChainProviderUnconfirmedTransaction<I>[]> {\n const args = buildGqlUnconfirmedTxQueryArgs(query.where);\n\n let keepFetching = true;\n while (keepFetching) {\n const response = await this.#getUnconfirmedTransactions(args);\n if (some(response.data?.mempool?.transactions)) {\n yield response.data.mempool.transactions.map((t) =>\n mapUnconfirmedTransaction(t, this.#biMapper)\n );\n }\n\n keepFetching = response.data?.mempool?.transactions?.length === PAGE_SIZE;\n if (keepFetching) args.skip += PAGE_SIZE;\n }\n }\n\n async getUnconfirmedTransactions(\n query: TransactionQuery<GraphQLUnconfirmedTransactionWhere>\n ): Promise<ChainProviderUnconfirmedTransaction<I>[]> {\n const transactions: ChainProviderUnconfirmedTransaction<I>[][] = [];\n for await (const chunk of this.streamUnconfirmedTransactions(query)) {\n transactions.push(chunk);\n }\n\n return transactions.flat();\n }\n\n async *streamConfirmedTransactions(\n query: TransactionQuery<GraphQLConfirmedTransactionWhere>\n ): AsyncIterable<ChainProviderConfirmedTransaction<I>[]> {\n const args = buildGqlConfirmedTxQueryArgs(query.where);\n\n let keepFetching = true;\n while (keepFetching) {\n const response = await this.#getConfirmedTransactions(args);\n if (some(response.data?.transactions)) {\n yield response.data.transactions.map((t) =>\n mapConfirmedTransaction(t, this.#biMapper)\n );\n }\n\n keepFetching = response.data?.transactions?.length === PAGE_SIZE;\n if (keepFetching) args.skip += PAGE_SIZE;\n }\n }\n\n async getConfirmedTransactions(\n query: TransactionQuery<GraphQLConfirmedTransactionWhere>\n ): Promise<ChainProviderConfirmedTransaction<I>[]> {\n const transactions: ChainProviderConfirmedTransaction<I>[][] = [];\n for await (const chunk of this.streamConfirmedTransactions(query)) {\n transactions.push(chunk);\n }\n\n return transactions.flat();\n }\n\n async getHeaders(query: HeaderQuery): Promise<BlockHeader[]> {\n const response = await this.#getHeaders(query, this.#options.url);\n\n return (\n response.data?.blockHeaders.map((header) => ({\n ...header,\n id: header.headerId,\n timestamp: Number(header.timestamp),\n nBits: Number(header.nBits),\n votes: header.votes.join(\"\")\n })) ?? []\n );\n }\n\n createOperation<R, V extends GraphQLVariables = GraphQLVariables>(\n query: string,\n options?: Partial<ErgoGraphQLRequestOptions>\n ): GraphQLOperation<GraphQLSuccessResponse<R>, V> {\n const opt = ensureDefaults(options, this.#options);\n opt.throwOnNonNetworkErrors = true;\n\n return createGqlOperation(query, opt);\n }\n\n async checkTransaction(\n signedTransaction: SignedTransaction\n ): Promise<TransactionEvaluationResult> {\n try {\n const response = await this.#checkTransaction(\n { signedTransaction },\n this.#options.url\n );\n return { success: true, transactionId: response.data.checkTransaction };\n } catch (e) {\n return { success: false, message: (e as Error).message };\n }\n }\n\n async submitTransaction(\n signedTransaction: SignedTransaction\n ): Promise<TransactionEvaluationResult> {\n try {\n const response = await this.#sendTransaction(\n { signedTransaction },\n this.#options.url\n );\n return { success: true, transactionId: response.data.submitTransaction };\n } catch (e) {\n return { success: false, message: (e as Error).message };\n }\n }\n\n reduceTransaction(): Promise<TransactionReductionResult> {\n throw new NotSupportedError(\"Transaction reducing is not supported by ergo-graphql.\");\n }\n}\n\nfunction buildGqlBoxQueryArgs(where: GraphQLBoxWhere) {\n const args = {\n spent: false,\n boxIds: merge(where.boxIds, where.boxId),\n ergoTrees: merge(where.ergoTrees, where.ergoTree),\n ergoTreeTemplateHash: where.templateHash,\n tokenId: where.tokenId,\n skip: 0,\n take: PAGE_SIZE\n } satisfies QueryBoxesArgs;\n\n const addresses = merge(where.addresses, where.address);\n if (some(addresses)) {\n const trees = addresses.map((address) =>\n typeof address === \"string\"\n ? ErgoAddress.decode(address).ergoTree\n : address.ergoTree\n );\n\n args.ergoTrees = uniq(some(args.ergoTrees) ? args.ergoTrees.concat(trees) : trees);\n }\n\n return args;\n}\n\nfunction buildGqlUnconfirmedTxQueryArgs(where: GraphQLConfirmedTransactionWhere) {\n const addresses = uniq(\n [\n merge(where.addresses, where.address)?.map((address): string =>\n typeof address === \"string\" ? address : address.encode()\n ) ?? [],\n merge(where.ergoTrees, where.ergoTree)?.map((tree) =>\n ErgoAddress.fromErgoTree(tree).encode()\n ) ?? []\n ].flat()\n );\n\n return {\n addresses: addresses.length ? addresses : undefined,\n transactionIds: merge(where.transactionIds, where.transactionId),\n skip: 0,\n take: PAGE_SIZE\n };\n}\n\nfunction buildGqlConfirmedTxQueryArgs(where: GraphQLConfirmedTransactionWhere) {\n return {\n ...buildGqlUnconfirmedTxQueryArgs(where),\n headerId: where.headerId,\n minHeight: where.minHeight,\n onlyRelevantOutputs: where.onlyRelevantOutputs\n };\n}\n\nfunction merge<T>(array?: T[], el?: T) {\n if (isEmpty(array) && isUndefined(el)) return;\n\n const set = new Set<T>(array ?? []);\n if (!isUndefined(el)) set.add(el);\n return Array.from(set.values());\n}\n\nfunction hasMempool(data: unknown): data is UnconfirmedBoxesResponse {\n return !!(data as UnconfirmedBoxesResponse)?.mempool?.boxes;\n}\n\nfunction hasConfirmed(data: unknown): data is ConfirmedBoxesResponse {\n return !!(data as ConfirmedBoxesResponse)?.boxes;\n}\n\nfunction mapConfirmedBox<T>(box: GQLBox, mapper: BiMapper<T>): ChainProviderBox<T> {\n const mapped = mapBox(box, mapper) as ChainProviderBox<T>;\n mapped.confirmed = true;\n return mapped;\n}\n\nfunction mapUnconfirmedBox<T>(box: GQLBox, mapper: BiMapper<T>): ChainProviderBox<T> {\n const mapped = mapBox(box, mapper) as ChainProviderBox<T>;\n mapped.confirmed = false;\n return mapped;\n}\n\nfunction mapBox<T>(\n box: GQLBox | GQLUnconfirmedBox,\n mapper: BiMapper<T>\n): Omit<ChainProviderBox<T>, \"confirmed\"> {\n return {\n boxId: box.boxId,\n transactionId: box.transactionId,\n value: mapper(box.value),\n ergoTree: box.ergoTree,\n assets: box.assets.map((t) => ({ tokenId: t.tokenId, amount: mapper(t.amount) })),\n creationHeight: box.creationHeight,\n additionalRegisters: box.additionalRegisters,\n index: box.index\n };\n}\n\nfunction mapUnconfirmedTransaction<T>(\n tx: UnconfirmedTransaction,\n mapper: BiMapper<T>\n): ChainProviderUnconfirmedTransaction<T> {\n return {\n transactionId: tx.transactionId,\n timestamp: Number(tx.timestamp),\n inputs: tx.inputs.map((i) => ({\n spendingProof: {\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n extension: i.extension!,\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n proofBytes: i.proofBytes!\n },\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n ...mapBox(i.box!, mapper)\n })),\n dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),\n outputs: tx.outputs.map((b) => mapBox(b, mapper)),\n confirmed: false\n };\n}\n\nfunction mapConfirmedTransaction<T>(\n tx: Transaction,\n mapper: BiMapper<T>\n): ChainProviderConfirmedTransaction<T> {\n return {\n transactionId: tx.transactionId,\n timestamp: Number(tx.timestamp),\n inputs: tx.inputs.map((i) => ({\n spendingProof: {\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n extension: i.extension!,\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n proofBytes: i.proofBytes!\n },\n // biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'\n ...mapBox(i.box!, mapper)\n })),\n dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),\n outputs: tx.outputs.map((b) => mapBox(b, mapper)),\n height: tx.inclusionHeight,\n headerId: tx.headerId,\n index: tx.index,\n confirmed: true\n };\n}\n"]}
|