@fleet-sdk/blockchain-providers 0.5.0 → 0.6.1
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 +23 -0
- package/dist/index.d.mts +156 -37
- package/dist/index.d.ts +156 -37
- package/dist/index.js +349 -105
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +345 -107
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/ergo-graphql/ergoGraphQLProvider.ts +312 -143
- package/src/ergo-graphql/queries.ts +14 -5
- package/src/index.ts +3 -0
- package/src/types/blockchainProvider.ts +101 -18
- package/src/utils/_tests.ts +6 -10
- package/src/utils/graphql.ts +53 -65
- package/src/utils/networking.ts +83 -0
package/dist/index.mjs
CHANGED
@@ -1,80 +1,188 @@
|
|
1
|
-
import { isEmpty,
|
1
|
+
import { some, ensureDefaults, clearUndefined, isEmpty, BlockchainProviderError, uniqBy, orderBy, NotSupportedError, uniq, chunk, isUndefined, assertInstanceOf, assertTypeOf, assert } from '@fleet-sdk/common';
|
2
2
|
import { ErgoAddress } from '@fleet-sdk/core';
|
3
3
|
|
4
4
|
// src/ergo-graphql/ergoGraphQLProvider.ts
|
5
|
+
new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
6
|
+
var HEXES = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
7
|
+
var HexChar = {
|
8
|
+
ZERO: 48,
|
9
|
+
// 0
|
10
|
+
NINE: 57,
|
11
|
+
// 9
|
12
|
+
A_UP: 65,
|
13
|
+
// A
|
14
|
+
F_UP: 70,
|
15
|
+
// F
|
16
|
+
A_LO: 97,
|
17
|
+
// a
|
18
|
+
F_LO: 102
|
19
|
+
// f
|
20
|
+
};
|
21
|
+
function bytesToHex(bytes2) {
|
22
|
+
assertInstanceOf(bytes2, Uint8Array);
|
23
|
+
let hex3 = "";
|
24
|
+
for (let i = 0, len = bytes2.length; i < len; i++) {
|
25
|
+
hex3 += HEXES[bytes2[i]];
|
26
|
+
}
|
27
|
+
return hex3;
|
28
|
+
}
|
29
|
+
function hexToBytes(hex3) {
|
30
|
+
assertTypeOf(hex3, "string");
|
31
|
+
assert(hex3.length % 2 === 0, "Invalid hex padding.");
|
32
|
+
const len = hex3.length / 2;
|
33
|
+
const bytes2 = new Uint8Array(len);
|
34
|
+
for (let i = 0, j = 0; i < len; i++) {
|
35
|
+
const n1 = charCodeToBase16(hex3.charCodeAt(j++));
|
36
|
+
const n2 = charCodeToBase16(hex3.charCodeAt(j++));
|
37
|
+
bytes2[i] = n1 * 16 + n2;
|
38
|
+
}
|
39
|
+
return bytes2;
|
40
|
+
}
|
41
|
+
function charCodeToBase16(char) {
|
42
|
+
if (char >= HexChar.ZERO && char <= HexChar.NINE) return char - HexChar.ZERO;
|
43
|
+
if (char >= HexChar.A_UP && char <= HexChar.F_UP) return char - (HexChar.A_UP - 10);
|
44
|
+
if (char >= HexChar.A_LO && char <= HexChar.F_LO) return char - (HexChar.A_LO - 10);
|
45
|
+
throw new Error("Invalid byte sequence.");
|
46
|
+
}
|
47
|
+
var hex2 = {
|
48
|
+
encode: bytesToHex,
|
49
|
+
decode: hexToBytes
|
50
|
+
};
|
51
|
+
async function request(path, opt) {
|
52
|
+
const url = buildURL(path, opt?.query, opt?.base);
|
53
|
+
let response;
|
54
|
+
if (opt?.retry) {
|
55
|
+
const routes = some(opt.retry.fallbacks) ? [url, ...opt.retry.fallbacks] : [url];
|
56
|
+
const attempts = opt.retry.attempts;
|
57
|
+
response = await exponentialRetry(
|
58
|
+
(r) => fetch(resolveUrl(routes, attempts - r), opt.httpOptions),
|
59
|
+
opt.retry
|
60
|
+
);
|
61
|
+
} else {
|
62
|
+
response = await fetch(url, opt?.httpOptions);
|
63
|
+
}
|
64
|
+
return (opt?.parser || JSON).parse(await response.text());
|
65
|
+
}
|
66
|
+
function resolveUrl(routes, attempt) {
|
67
|
+
const route = routes[attempt % routes.length];
|
68
|
+
return typeof route === "string" ? route : buildURL(route.path, route.query, route.base).toString();
|
69
|
+
}
|
70
|
+
function buildURL(path, query, base) {
|
71
|
+
if (!base && !query) return path;
|
72
|
+
const url = new URL(path, base);
|
73
|
+
if (some(query)) {
|
74
|
+
for (const key in query) url.searchParams.append(key, String(query[key]));
|
75
|
+
}
|
76
|
+
return url.toString();
|
77
|
+
}
|
78
|
+
async function exponentialRetry(operation, { attempts, delay }) {
|
79
|
+
try {
|
80
|
+
return await operation(attempts);
|
81
|
+
} catch (e) {
|
82
|
+
if (attempts > 0) {
|
83
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
84
|
+
return exponentialRetry(operation, { attempts: attempts - 1, delay: delay * 2 });
|
85
|
+
}
|
86
|
+
throw e;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
// src/utils/graphql.ts
|
5
91
|
var OP_NAME_REGEX = /(query|mutation)\s?([\w\-_]+)?/;
|
6
92
|
var DEFAULT_HEADERS = {
|
7
93
|
"content-type": "application/json; charset=utf-8",
|
8
94
|
accept: "application/graphql-response+json, application/json"
|
9
95
|
};
|
10
96
|
function createGqlOperation(query, options) {
|
11
|
-
return async (variables) => {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
97
|
+
return async (variables, url) => {
|
98
|
+
url = url ?? options?.url;
|
99
|
+
if (!url) throw new Error("URL is required");
|
100
|
+
const response = await request(url, {
|
101
|
+
...options,
|
102
|
+
httpOptions: {
|
103
|
+
...options?.httpOptions,
|
104
|
+
method: "POST",
|
105
|
+
headers: ensureDefaults(options?.httpOptions?.headers, DEFAULT_HEADERS),
|
106
|
+
body: (options?.parser ?? JSON).stringify({
|
107
|
+
operationName: getOpName(query),
|
108
|
+
query,
|
109
|
+
variables: variables ? clearUndefined(variables) : void 0
|
110
|
+
})
|
111
|
+
}
|
21
112
|
});
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
);
|
26
|
-
if (options.throwOnNonNetworkErrors && some(parsedData.errors) && isEmpty(parsedData.data)) {
|
27
|
-
throw new BlockchainProviderError(parsedData.errors[0].message, {
|
28
|
-
cause: parsedData.errors
|
29
|
-
});
|
113
|
+
if (options?.throwOnNonNetworkErrors && some(response.errors) && isEmpty(response.data)) {
|
114
|
+
const msg = response.errors[0].message;
|
115
|
+
throw new BlockchainProviderError(msg, { cause: response.errors });
|
30
116
|
}
|
31
|
-
return
|
117
|
+
return response;
|
32
118
|
};
|
33
119
|
}
|
120
|
+
function gql(query) {
|
121
|
+
return query[0];
|
122
|
+
}
|
34
123
|
function getOpName(query) {
|
35
124
|
return OP_NAME_REGEX.exec(query)?.at(2);
|
36
125
|
}
|
37
|
-
function isRequestParam(obj) {
|
38
|
-
return typeof obj === "object" && obj.url !== void 0;
|
39
|
-
}
|
40
126
|
|
41
127
|
// src/ergo-graphql/queries.ts
|
42
128
|
var B = [
|
43
|
-
"
|
129
|
+
"$boxIds: [String!] $ergoTrees: [String!] $ergoTreeTemplateHash: String $tokenId: String $skip: Int $take: Int",
|
44
130
|
"boxIds: $boxIds ergoTrees: $ergoTrees ergoTreeTemplateHash: $ergoTreeTemplateHash tokenId: $tokenId skip: $skip take: $take",
|
45
|
-
"boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters
|
131
|
+
"boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters"
|
46
132
|
];
|
47
|
-
var CONF_BOXES_QUERY =
|
48
|
-
var UNCONF_BOXES_QUERY =
|
49
|
-
var ALL_BOXES_QUERY =
|
133
|
+
var CONF_BOXES_QUERY = `query boxes($spent: Boolean! ${B[0]}) { boxes(spent: $spent ${B[1]}) { ${B[2]} beingSpent } }`;
|
134
|
+
var UNCONF_BOXES_QUERY = `query boxes(${B[0]}) { mempool { boxes(${B[1]}) { ${B[2]} beingSpent } } }`;
|
135
|
+
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 } } }`;
|
50
136
|
var HEADERS_QUERY = "query blockHeaders($take: Int) { blockHeaders(take: $take) {headerId timestamp version adProofsRoot stateRoot transactionsRoot nBits extensionHash powSolutions height difficulty parentId votes } }";
|
51
137
|
var CHECK_TX_MUTATION = "mutation checkTransaction($signedTransaction: SignedTransaction!) { checkTransaction(signedTransaction: $signedTransaction) }";
|
52
138
|
var SEND_TX_MUTATION = "mutation submitTransaction($signedTransaction: SignedTransaction!) { submitTransaction(signedTransaction: $signedTransaction) }";
|
139
|
+
var T = [
|
140
|
+
"$addresses: [String!], $transactionIds: [String!], $skip: Int, $take: Int",
|
141
|
+
"addresses: $addresses, transactionIds: $transactionIds, skip: $skip, take: $take",
|
142
|
+
`transactionId timestamp inputs { proofBytes extension index box { ${B[2]} } } dataInputs { boxId }`
|
143
|
+
];
|
144
|
+
var CONF_TX_QUERY = `query confirmedTransactions(${T[0]} $relevantOnly: Boolean) { transactions(${T[1]}) { ${T[2]} outputs(relevantOnly: $relevantOnly) { ${B[2]} } inclusionHeight headerId index } }`;
|
145
|
+
var UNCONF_TX_QUERY = `query unconfirmedTransactions(${T[0]}) { mempool { transactions(${T[1]}) { ${T[2]} outputs { ${B[2]} } } } }`;
|
53
146
|
|
54
147
|
// src/ergo-graphql/ergoGraphQLProvider.ts
|
55
148
|
var PAGE_SIZE = 50;
|
149
|
+
var MAX_ARGS = 20;
|
56
150
|
var ErgoGraphQLProvider = class {
|
57
151
|
#options;
|
58
|
-
#
|
59
|
-
#
|
152
|
+
#biMapper;
|
153
|
+
#getConfirmedBoxes;
|
154
|
+
#getUnconfirmedBoxes;
|
60
155
|
#getAllBoxes;
|
156
|
+
#getConfirmedTransactions;
|
157
|
+
#getUnconfirmedTransactions;
|
158
|
+
#checkTransaction;
|
159
|
+
#sendTransaction;
|
61
160
|
#getHeaders;
|
62
|
-
#checkTx;
|
63
|
-
#sendTx;
|
64
161
|
constructor(optOrUrl) {
|
162
|
+
this.#biMapper = (value) => BigInt(value);
|
65
163
|
this.#options = {
|
66
164
|
...isRequestParam(optOrUrl) ? optOrUrl : { url: optOrUrl },
|
67
165
|
throwOnNonNetworkErrors: true
|
68
166
|
};
|
69
|
-
this.#
|
70
|
-
this.#
|
167
|
+
this.#getConfirmedBoxes = this.createOperation(CONF_BOXES_QUERY);
|
168
|
+
this.#getUnconfirmedBoxes = this.createOperation(UNCONF_BOXES_QUERY);
|
71
169
|
this.#getAllBoxes = this.createOperation(ALL_BOXES_QUERY);
|
170
|
+
this.#getConfirmedTransactions = this.createOperation(CONF_TX_QUERY);
|
171
|
+
this.#getUnconfirmedTransactions = this.createOperation(UNCONF_TX_QUERY);
|
172
|
+
this.#checkTransaction = this.createOperation(CHECK_TX_MUTATION);
|
173
|
+
this.#sendTransaction = this.createOperation(SEND_TX_MUTATION);
|
72
174
|
this.#getHeaders = this.createOperation(HEADERS_QUERY);
|
73
|
-
this.#checkTx = this.createOperation(CHECK_TX_MUTATION);
|
74
|
-
this.#sendTx = this.createOperation(SEND_TX_MUTATION);
|
75
175
|
}
|
76
176
|
#fetchBoxes(args, inclConf, inclUnconf) {
|
77
|
-
return inclConf && inclUnconf ? this.#getAllBoxes(args) : inclUnconf ? this.#
|
177
|
+
return inclConf && inclUnconf ? this.#getAllBoxes(args) : inclUnconf ? this.#getUnconfirmedBoxes(args) : this.#getConfirmedBoxes(args);
|
178
|
+
}
|
179
|
+
setUrl(url) {
|
180
|
+
this.#options.url = url;
|
181
|
+
return this;
|
182
|
+
}
|
183
|
+
setBigIntMapper(mapper) {
|
184
|
+
this.#biMapper = mapper;
|
185
|
+
return this;
|
78
186
|
}
|
79
187
|
async *streamBoxes(query) {
|
80
188
|
if (isEmpty(query.where)) {
|
@@ -83,56 +191,101 @@ var ErgoGraphQLProvider = class {
|
|
83
191
|
const notBeingSpent = (box) => !box.beingSpent;
|
84
192
|
const returnedBoxIds = /* @__PURE__ */ new Set();
|
85
193
|
const { where, from } = query;
|
86
|
-
const
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
}
|
101
|
-
if (isMempoolAware && hasMempool(data)) {
|
102
|
-
if (some(data.mempool.boxes)) {
|
103
|
-
const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map(asConfirmed(false));
|
104
|
-
boxes = boxes.concat(mempoolBoxes);
|
194
|
+
const queries = buildGqlBoxQueries(where);
|
195
|
+
const isMempoolAware = from !== "blockchain";
|
196
|
+
for (const query2 of queries) {
|
197
|
+
let inclChain = from !== "mempool";
|
198
|
+
let inclPool = from !== "blockchain";
|
199
|
+
while (inclChain || inclPool) {
|
200
|
+
const { data } = await this.#fetchBoxes(query2, inclChain, inclPool);
|
201
|
+
let boxes = [];
|
202
|
+
if (inclChain && hasConfirmed(data)) {
|
203
|
+
if (some(data.boxes)) {
|
204
|
+
const confirmedBoxes = (isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes).map((b) => mapConfirmedBox(b, this.#biMapper));
|
205
|
+
boxes = boxes.concat(confirmedBoxes);
|
206
|
+
}
|
207
|
+
inclChain = data.boxes.length === PAGE_SIZE;
|
105
208
|
}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
209
|
+
if (isMempoolAware && hasMempool(data)) {
|
210
|
+
if (some(data.mempool.boxes)) {
|
211
|
+
const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map((b) => mapUnconfirmedBox(b, this.#biMapper));
|
212
|
+
boxes = boxes.concat(mempoolBoxes);
|
213
|
+
}
|
214
|
+
inclPool = data.mempool.boxes.length === PAGE_SIZE;
|
111
215
|
}
|
112
216
|
if (some(boxes)) {
|
113
|
-
|
114
|
-
|
115
|
-
|
217
|
+
if (boxes.some((box) => returnedBoxIds.has(box.boxId))) {
|
218
|
+
boxes = boxes.filter((b) => !returnedBoxIds.has(b.boxId));
|
219
|
+
}
|
220
|
+
if (some(boxes)) {
|
221
|
+
boxes = uniqBy(boxes, (box) => box.boxId);
|
222
|
+
for (const box of boxes) returnedBoxIds.add(box.boxId);
|
223
|
+
yield boxes;
|
224
|
+
}
|
116
225
|
}
|
226
|
+
if (inclChain || inclPool) query2.skip += PAGE_SIZE;
|
117
227
|
}
|
118
|
-
|
119
|
-
} while (inclChain || inclPool);
|
228
|
+
}
|
120
229
|
}
|
121
230
|
async getBoxes(query) {
|
122
|
-
|
123
|
-
for await (const
|
124
|
-
|
231
|
+
const boxes = [];
|
232
|
+
for await (const chunk2 of this.streamBoxes(query)) boxes.push(chunk2);
|
233
|
+
return orderBy(boxes.flat(), (box) => box.creationHeight);
|
234
|
+
}
|
235
|
+
async *streamUnconfirmedTransactions(query) {
|
236
|
+
const queries = buildGqlUnconfirmedTxQueries(query.where);
|
237
|
+
for (const query2 of queries) {
|
238
|
+
let keepFetching = true;
|
239
|
+
while (keepFetching) {
|
240
|
+
const response = await this.#getUnconfirmedTransactions(query2);
|
241
|
+
if (some(response.data?.mempool?.transactions)) {
|
242
|
+
yield response.data.mempool.transactions.map(
|
243
|
+
(t) => mapUnconfirmedTransaction(t, this.#biMapper)
|
244
|
+
);
|
245
|
+
}
|
246
|
+
keepFetching = response.data?.mempool?.transactions?.length === PAGE_SIZE;
|
247
|
+
if (keepFetching) query2.skip += PAGE_SIZE;
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}
|
251
|
+
async getUnconfirmedTransactions(query) {
|
252
|
+
const transactions = [];
|
253
|
+
for await (const chunk2 of this.streamUnconfirmedTransactions(query)) {
|
254
|
+
transactions.push(chunk2);
|
255
|
+
}
|
256
|
+
return transactions.flat();
|
257
|
+
}
|
258
|
+
async *streamConfirmedTransactions(query) {
|
259
|
+
const queries = buildGqlConfirmedTxQueries(query.where);
|
260
|
+
for (const query2 of queries) {
|
261
|
+
let keepFetching = true;
|
262
|
+
while (keepFetching) {
|
263
|
+
const response = await this.#getConfirmedTransactions(query2);
|
264
|
+
if (some(response.data?.transactions)) {
|
265
|
+
yield response.data.transactions.map(
|
266
|
+
(t) => mapConfirmedTransaction(t, this.#biMapper)
|
267
|
+
);
|
268
|
+
}
|
269
|
+
keepFetching = response.data?.transactions?.length === PAGE_SIZE;
|
270
|
+
if (keepFetching) query2.skip += PAGE_SIZE;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
274
|
+
async getConfirmedTransactions(query) {
|
275
|
+
const transactions = [];
|
276
|
+
for await (const chunk2 of this.streamConfirmedTransactions(query)) {
|
277
|
+
transactions.push(chunk2);
|
125
278
|
}
|
126
|
-
return
|
279
|
+
return transactions.flat();
|
127
280
|
}
|
128
281
|
async getHeaders(query) {
|
129
282
|
const response = await this.#getHeaders(query);
|
130
|
-
return response.data?.blockHeaders.map((
|
131
|
-
...
|
132
|
-
id:
|
133
|
-
timestamp: Number(
|
134
|
-
nBits: Number(
|
135
|
-
votes:
|
283
|
+
return response.data?.blockHeaders.map((h) => ({
|
284
|
+
...h,
|
285
|
+
id: h.headerId,
|
286
|
+
timestamp: Number(h.timestamp),
|
287
|
+
nBits: Number(h.nBits),
|
288
|
+
votes: hex2.encode(Uint8Array.from(h.votes))
|
136
289
|
})) ?? [];
|
137
290
|
}
|
138
291
|
createOperation(query, options) {
|
@@ -142,7 +295,7 @@ var ErgoGraphQLProvider = class {
|
|
142
295
|
}
|
143
296
|
async checkTransaction(signedTransaction) {
|
144
297
|
try {
|
145
|
-
const response = await this.#
|
298
|
+
const response = await this.#checkTransaction({ signedTransaction });
|
146
299
|
return { success: true, transactionId: response.data.checkTransaction };
|
147
300
|
} catch (e) {
|
148
301
|
return { success: false, message: e.message };
|
@@ -150,38 +303,60 @@ var ErgoGraphQLProvider = class {
|
|
150
303
|
}
|
151
304
|
async submitTransaction(signedTransaction) {
|
152
305
|
try {
|
153
|
-
const response = await this.#
|
306
|
+
const response = await this.#sendTransaction({ signedTransaction });
|
154
307
|
return { success: true, transactionId: response.data.submitTransaction };
|
155
308
|
} catch (e) {
|
156
309
|
return { success: false, message: e.message };
|
157
310
|
}
|
158
311
|
}
|
159
312
|
reduceTransaction() {
|
160
|
-
throw new NotSupportedError(
|
161
|
-
"Transaction reducing is not supported by ergo-graphql."
|
162
|
-
);
|
313
|
+
throw new NotSupportedError("Transaction reducing is not supported by ergo-graphql.");
|
163
314
|
}
|
164
315
|
};
|
165
|
-
function
|
166
|
-
const
|
316
|
+
function buildGqlBoxQueries(where) {
|
317
|
+
const ergoTrees = uniq(
|
318
|
+
[
|
319
|
+
merge(where.ergoTrees, where.ergoTree) ?? [],
|
320
|
+
merge(where.addresses, where.address)?.map(
|
321
|
+
(a) => typeof a === "string" ? ErgoAddress.decode(a).ergoTree : a.ergoTree
|
322
|
+
) ?? []
|
323
|
+
].flat()
|
324
|
+
);
|
325
|
+
return chunk(ergoTrees, MAX_ARGS).map((chunk2) => ({
|
167
326
|
spent: false,
|
168
|
-
boxIds:
|
169
|
-
ergoTrees:
|
327
|
+
boxIds: where.boxId ? [where.boxId] : void 0,
|
328
|
+
ergoTrees: chunk2,
|
170
329
|
ergoTreeTemplateHash: where.templateHash,
|
171
330
|
tokenId: where.tokenId,
|
172
331
|
skip: 0,
|
173
332
|
take: PAGE_SIZE
|
174
|
-
};
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
333
|
+
}));
|
334
|
+
}
|
335
|
+
function buildGqlUnconfirmedTxQueries(where) {
|
336
|
+
const addresses = uniq(
|
337
|
+
[
|
338
|
+
merge(where.addresses, where.address)?.map(
|
339
|
+
(address) => typeof address === "string" ? address : address.encode()
|
340
|
+
) ?? [],
|
341
|
+
merge(where.ergoTrees, where.ergoTree)?.map(
|
342
|
+
(tree) => ErgoAddress.fromErgoTree(tree).encode()
|
343
|
+
) ?? []
|
344
|
+
].flat()
|
345
|
+
);
|
346
|
+
return chunk(addresses, MAX_ARGS).map((chunk2) => ({
|
347
|
+
addresses: chunk2.length ? chunk2 : void 0,
|
348
|
+
transactionIds: where.transactionId ? [where.transactionId] : void 0,
|
349
|
+
skip: 0,
|
350
|
+
take: PAGE_SIZE
|
351
|
+
}));
|
352
|
+
}
|
353
|
+
function buildGqlConfirmedTxQueries(where) {
|
354
|
+
return buildGqlUnconfirmedTxQueries(where).map((query) => ({
|
355
|
+
...query,
|
356
|
+
headerId: where.headerId,
|
357
|
+
minHeight: where.minHeight,
|
358
|
+
onlyRelevantOutputs: where.onlyRelevantOutputs
|
359
|
+
}));
|
185
360
|
}
|
186
361
|
function merge(array, el) {
|
187
362
|
if (isEmpty(array) && isUndefined(el)) return;
|
@@ -195,18 +370,81 @@ function hasMempool(data) {
|
|
195
370
|
function hasConfirmed(data) {
|
196
371
|
return !!data?.boxes;
|
197
372
|
}
|
198
|
-
function
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
373
|
+
function mapConfirmedBox(box, mapper) {
|
374
|
+
const mapped = mapBox(box, mapper);
|
375
|
+
mapped.confirmed = true;
|
376
|
+
return mapped;
|
377
|
+
}
|
378
|
+
function mapUnconfirmedBox(box, mapper) {
|
379
|
+
const mapped = mapBox(box, mapper);
|
380
|
+
mapped.confirmed = false;
|
381
|
+
return mapped;
|
382
|
+
}
|
383
|
+
function mapBox(box, mapper) {
|
384
|
+
return {
|
385
|
+
boxId: box.boxId,
|
386
|
+
transactionId: box.transactionId,
|
387
|
+
value: mapper(box.value),
|
388
|
+
ergoTree: box.ergoTree,
|
389
|
+
assets: box.assets.map((t) => ({ tokenId: t.tokenId, amount: mapper(t.amount) })),
|
390
|
+
creationHeight: box.creationHeight,
|
391
|
+
additionalRegisters: box.additionalRegisters,
|
392
|
+
index: box.index
|
393
|
+
};
|
394
|
+
}
|
395
|
+
function mapUnconfirmedTransaction(tx, mapper) {
|
396
|
+
return {
|
397
|
+
transactionId: tx.transactionId,
|
398
|
+
timestamp: Number(tx.timestamp),
|
399
|
+
inputs: tx.inputs.map((i) => ({
|
400
|
+
spendingProof: {
|
401
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
402
|
+
extension: i.extension,
|
403
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
404
|
+
proofBytes: i.proofBytes
|
405
|
+
},
|
406
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
407
|
+
...mapBox(i.box, mapper)
|
205
408
|
})),
|
206
|
-
|
207
|
-
|
409
|
+
dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),
|
410
|
+
outputs: tx.outputs.map((b) => mapBox(b, mapper)),
|
411
|
+
confirmed: false
|
412
|
+
};
|
208
413
|
}
|
414
|
+
function mapConfirmedTransaction(tx, mapper) {
|
415
|
+
return {
|
416
|
+
transactionId: tx.transactionId,
|
417
|
+
timestamp: Number(tx.timestamp),
|
418
|
+
inputs: tx.inputs.map((i) => ({
|
419
|
+
spendingProof: {
|
420
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
421
|
+
extension: i.extension,
|
422
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
423
|
+
proofBytes: i.proofBytes
|
424
|
+
},
|
425
|
+
// biome-ignore lint/style/noNonNullAssertion: bad type declarations at '@ergo-graphql/type'
|
426
|
+
...mapBox(i.box, mapper)
|
427
|
+
})),
|
428
|
+
dataInputs: tx.dataInputs.map((di) => ({ boxId: di.boxId })),
|
429
|
+
outputs: tx.outputs.map((b) => mapBox(b, mapper)),
|
430
|
+
height: tx.inclusionHeight,
|
431
|
+
headerId: tx.headerId,
|
432
|
+
index: tx.index,
|
433
|
+
confirmed: true
|
434
|
+
};
|
435
|
+
}
|
436
|
+
function isRequestParam(obj) {
|
437
|
+
return typeof obj === "object" && obj.url !== void 0;
|
438
|
+
}
|
439
|
+
/*! Bundled license information:
|
440
|
+
|
441
|
+
@noble/hashes/esm/utils.js:
|
442
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
443
|
+
|
444
|
+
@scure/base/lib/esm/index.js:
|
445
|
+
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
446
|
+
*/
|
209
447
|
|
210
|
-
export { ErgoGraphQLProvider };
|
211
|
-
//# sourceMappingURL=
|
448
|
+
export { ErgoGraphQLProvider, createGqlOperation, exponentialRetry, getOpName, gql, isRequestParam, request };
|
449
|
+
//# sourceMappingURL=index.mjs.map
|
212
450
|
//# sourceMappingURL=index.mjs.map
|