@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/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
- const response = await (options.fetcher ?? fetch)(options.url, {
15
- method: "POST",
16
- headers: common.ensureDefaults(options.headers, DEFAULT_HEADERS),
17
- credentials: options.credentials,
18
- body: (options.parser ?? JSON).stringify({
19
- operationName: getOpName(query),
20
- query,
21
- variables: variables ? common.clearUndefined(variables) : void 0
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
- const rawData = await response.text();
25
- const parsedData = (options.parser ?? JSON).parse(rawData);
26
- if (options.throwOnNonNetworkErrors && common.some(parsedData.errors) && common.isEmpty(parsedData.data)) {
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 parsedData;
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
- `query boxes($spent: Boolean! $boxIds: [String!] $ergoTrees: [String!] $ergoTreeTemplateHash: String $tokenId: String $skip: Int $take: Int)`,
42
- `boxIds: $boxIds ergoTrees: $ergoTrees ergoTreeTemplateHash: $ergoTreeTemplateHash tokenId: $tokenId skip: $skip take: $take`,
43
- `boxId transactionId index value creationHeight ergoTree assets { tokenId amount } additionalRegisters beingSpent`
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 CONF_BOXES_QUERY = `${B[0]} { boxes(spent: $spent ${B[1]}) { ${B[2]} } }`;
46
- var UNCONF_BOXES_QUERY = `${B[0]} { mempool { boxes(${B[1]}) { ${B[2]} } } }`;
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
- #getConfBoxes;
57
- #getUnconfBoxes;
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.#getConfBoxes = this.createOperation(CONF_BOXES_QUERY);
68
- this.#getUnconfBoxes = this.createOperation(UNCONF_BOXES_QUERY);
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
- if (inclConf && inclUnconf) {
76
- return this.#getAllBoxes(args);
77
- } else if (inclUnconf) {
78
- return this.#getUnconfBoxes(args);
79
- } else {
80
- return this.#getConfBoxes(args);
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 fetchFromChain = from !== "mempool";
92
- let fetchFromMempool = from !== "blockchain";
93
- const isMempoolAware = fetchFromMempool;
150
+ let inclChain = from !== "mempool";
151
+ let inclPool = from !== "blockchain";
152
+ const isMempoolAware = inclPool;
94
153
  do {
95
- const response = await this.#fetchBoxes(args, fetchFromChain, fetchFromMempool);
96
- const { data } = response;
154
+ const { data } = await this.#fetchBoxes(args, inclChain, inclPool);
97
155
  let boxes = [];
98
- if (fetchFromChain && hasConfirmed(data)) {
156
+ if (inclChain && hasConfirmed(data)) {
99
157
  if (common.some(data.boxes)) {
100
- const confirmedBoxes = (isMempoolAware ? data.boxes.filter(notBeingSpent) : data.boxes).map(asConfirmed(true));
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
- fetchFromChain = data.boxes.length === PAGE_SIZE;
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(asConfirmed(false));
165
+ const mempoolBoxes = data.mempool.boxes.filter(notBeingSpent).map((b) => mapUnconfirmedBox(b, this.#biMapper));
108
166
  boxes = boxes.concat(mempoolBoxes);
109
167
  }
110
- fetchFromMempool = data.mempool.boxes.length === PAGE_SIZE;
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
- boxes.forEach((box) => returnedBoxIds.add(box.boxId));
176
+ for (const box of boxes) returnedBoxIds.add(box.boxId);
119
177
  yield boxes;
120
178
  }
121
179
  }
122
- if (fetchFromChain || fetchFromMempool)
123
- args.skip += PAGE_SIZE;
124
- } while (fetchFromChain || fetchFromMempool);
180
+ if (inclChain || inclPool) args.skip += PAGE_SIZE;
181
+ } while (inclChain || inclPool);
125
182
  }
126
183
  async getBoxes(query) {
127
- let boxes = [];
128
- for await (const chunk of this.streamBoxes(query)) {
129
- boxes = boxes.concat(chunk);
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 common.orderBy(boxes, (box) => box.creationHeight);
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.#checkTx({ signedTransaction });
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.#sendTx({ signedTransaction });
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.fromBase58(address).ergoTree : address.ergoTree
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 asConfirmed(confirmed) {
202
- return (box) => ({
203
- ...box,
204
- value: BigInt(box.value),
205
- assets: box.assets.map((asset) => ({
206
- tokenId: asset.tokenId,
207
- amount: BigInt(asset.amount)
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
- confirmed
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=out.js.map
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":";AAMA;AAAA,EAGE,kBAAAA;AAAA,EAEA,WAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,QAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;;;ACpB5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,IAAM,gBAAgB;AACf,IAAM,kBAA2B;AAAA,EACtC,gBAAgB;AAAA,EAChB,QAAQ;AACV;AA4DO,SAAS,mBACd,OACA,SACyC;AACzC,SAAO,OAAO,cAA+C;AAC3D,UAAM,WAAW,OAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS,eAAe,QAAQ,SAAS,eAAe;AAAA,MACxD,aAAa,QAAQ;AAAA,MACrB,OAAO,QAAQ,UAAU,MAAM,UAAU;AAAA,QACvC,eAAe,UAAU,KAAK;AAAA,QAC9B;AAAA,QACA,WAAW,YAAY,eAAe,SAAS,IAAI;AAAA,MACrD,CAAkB;AAAA,IACpB,CAAC;AAED,UAAM,UAAU,MAAM,SAAS,KAAK;AACpC,UAAM,cAAc,QAAQ,UAAU,MAAM,MAAM,OAAO;AAEzD,QAAI,QAAQ,2BAA2B,KAAK,WAAW,MAAM,KAAK,QAAQ,WAAW,IAAI,GAAG;AAC1F,YAAM,IAAI,wBAAwB,WAAW,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,WAAW,OAAO,CAAC;AAAA,IAC9F;AAEA,WAAO;AAAA,EACT;AACF;AAMO,SAAS,UAAU,OAAmC;AAC3D,SAAO,cAAc,KAAK,KAAK,GAAG,GAAG,CAAC;AACxC;AAEO,SAAS,eAAe,KAA4C;AACzE,SAAO,OAAO,QAAQ,YAAa,IAA8B,QAAQ;AAC3E;;;AC7GA,IAAM,IAAI;AAAA,EACR;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,mBAAmB,GAAG,EAAE,CAAC,CAAC,0BAA0B,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AACzE,IAAM,qBAAqB,GAAG,EAAE,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AACvE,IAAM,kBAAkB,GAAG,EAAE,CAAC,CAAC,0BAA0B,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7G,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;;;AF2DhC,IAAM,YAAY;AAEX,IAAM,sBAAN,MAAmE;AAAA,EACxE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAIA,YAAY,UAAoD;AAC9D,SAAK,WAAW;AAAA,MACd,GAAI,eAAe,QAAQ,IAAI,WAAW,EAAE,KAAK,SAAS;AAAA,MAC1D,yBAAyB;AAAA,IAC3B;AAEA,SAAK,gBAAgB,KAAK,gBAA0C,gBAAgB;AACpF,SAAK,kBAAkB,KAAK,gBAA4C,kBAAkB;AAC1F,SAAK,eAAe,KAAK,gBAAyC,eAAe;AACjF,SAAK,cAAc,KAAK,gBAA0C,aAAa;AAC/E,SAAK,WAAW,KAAK,gBAA+C,iBAAiB;AACrF,SAAK,UAAU,KAAK,gBAA8C,gBAAgB;AAAA,EACpF;AAAA,EAEA,YAAY,MAAiB,UAAmB,YAAqB;AACnE,QAAI,YAAY,YAAY;AAC1B,aAAO,KAAK,aAAa,IAAI;AAAA,IAC/B,WAAW,YAAY;AACrB,aAAO,KAAK,gBAAgB,IAAI;AAAA,IAClC,OAAO;AACL,aAAO,KAAK,cAAc,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,OAAO,YAAY,OAA4D;AAC7E,QAAID,SAAQ,MAAM,KAAK,GAAG;AACxB,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAEA,UAAM,gBAAgB,CAAC,QAAa,CAAC,IAAI;AACzC,UAAM,iBAAiB,oBAAI,IAAY;AACvC,UAAM,EAAE,OAAO,KAAK,IAAI;AACxB,UAAM,OAAO,qBAAqB,KAAK;AAEvC,QAAI,iBAAiB,SAAS;AAC9B,QAAI,mBAAmB,SAAS;AAChC,UAAM,iBAAiB;AAEvB,OAAG;AACD,YAAM,WAAW,MAAM,KAAK,YAAY,MAAM,gBAAgB,gBAAgB;AAE9E,YAAM,EAAE,KAAK,IAAI;AACjB,UAAI,QAA4B,CAAC;AAEjC,UAAI,kBAAkB,aAAa,IAAI,GAAG;AACxC,YAAIC,MAAK,KAAK,KAAK,GAAG;AACpB,gBAAM,kBACJ,iBAAiB,KAAK,MAAM,OAAO,aAAa,IAAI,KAAK,OACzD,IAAI,YAAY,IAAI,CAAC;AAEvB,kBAAQ,MAAM,OAAO,cAAc;AAAA,QACrC;AAEA,yBAAiB,KAAK,MAAM,WAAW;AAAA,MACzC;AAEA,UAAI,kBAAkB,WAAW,IAAI,GAAG;AACtC,YAAIA,MAAK,KAAK,QAAQ,KAAK,GAAG;AAC5B,gBAAM,eAAe,KAAK,QAAQ,MAAM,OAAO,aAAa,EAAE,IAAI,YAAY,KAAK,CAAC;AACpF,kBAAQ,MAAM,OAAO,YAAY;AAAA,QACnC;AAEA,2BAAmB,KAAK,QAAQ,MAAM,WAAW;AAAA,MACnD;AAEA,UAAIA,MAAK,KAAK,GAAG;AAGf,YAAI,MAAM,KAAK,CAAC,QAAQ,eAAe,IAAI,IAAI,KAAK,CAAC,GAAG;AACtD,kBAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,KAAK,CAAC;AAAA,QAC1D;AAEA,YAAIA,MAAK,KAAK,GAAG;AACf,kBAAQ,OAAO,OAAO,CAAC,QAAQ,IAAI,KAAK;AACxC,gBAAM,QAAQ,CAAC,QAAQ,eAAe,IAAI,IAAI,KAAK,CAAC;AAEpD,gBAAM;AAAA,QACR;AAAA,MACF;AAEA,UAAI,kBAAkB;AAAkB,aAAK,QAAQ;AAAA,IACvD,SAAS,kBAAkB;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAS,OAAqD;AAClE,QAAI,QAA4B,CAAC;AACjC,qBAAiB,SAAS,KAAK,YAAY,KAAK,GAAG;AACjD,cAAQ,MAAM,OAAO,KAAK;AAAA,IAC5B;AAEA,WAAO,QAAQ,OAAO,CAAC,QAAQ,IAAI,cAAc;AAAA,EACnD;AAAA,EAEA,MAAM,WAAW,OAA4C;AAC3D,UAAM,WAAW,MAAM,KAAK,YAAY,KAAK;AAE7C,WACE,SAAS,MAAM,aAAa,IAAI,CAAC,YAAY;AAAA,MAC3C,GAAG;AAAA,MACH,IAAI,OAAO;AAAA,MACX,WAAW,OAAO,OAAO,SAAS;AAAA,MAClC,OAAO,OAAO,OAAO,KAAK;AAAA,MAC1B,OAAO,OAAO,MAAM,KAAK,EAAE;AAAA,IAC7B,EAAE,KAAK,CAAC;AAAA,EAEZ;AAAA,EAEA,gBACE,OACA,SACgD;AAChD,UAAM,MAAMF,gBAAe,SAAS,KAAK,QAAQ;AACjD,QAAI,0BAA0B;AAE9B,WAAO,mBAAmB,OAAO,GAAG;AAAA,EACtC;AAAA,EAEA,MAAM,iBACJ,mBACsC;AACtC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,SAAS,EAAE,kBAAkB,CAAC;AAE1D,aAAO,EAAE,SAAS,MAAM,eAAe,SAAS,KAAK,iBAAiB;AAAA,IACxE,SAAS,GAAG;AACV,aAAO,EAAE,SAAS,OAAO,SAAU,EAAY,QAAQ;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,kBACJ,mBACsC;AACtC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,QAAQ,EAAE,kBAAkB,CAAC;AAEzD,aAAO,EAAE,SAAS,MAAM,eAAe,SAAS,KAAK,kBAAkB;AAAA,IACzE,SAAS,GAAG;AACV,aAAO,EAAE,SAAS,OAAO,SAAU,EAAY,QAAQ;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,oBAAyD;AACvD,UAAM,IAAI,kBAAkB,wDAAwD;AAAA,EACtF;AACF;AAEA,SAAS,qBAAqB,OAAwB;AACpD,QAAM,OAAO;AAAA,IACX,OAAO;AAAA,IACP,QAAQ,MAAM,MAAM,QAAQ,MAAM,KAAK;AAAA,IACvC,WAAW,MAAM,MAAM,WAAW,MAAM,QAAQ;AAAA,IAChD,sBAAsB,MAAM;AAAA,IAC5B,SAAS,MAAM;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,QAAM,YAAY,MAAM,MAAM,WAAW,MAAM,OAAO;AACtD,MAAIE,MAAK,SAAS,GAAG;AACnB,UAAM,QAAQ,UAAU;AAAA,MAAI,CAAC,YAC3B,OAAO,YAAY,WAAW,YAAY,WAAW,OAAO,EAAE,WAAW,QAAQ;AAAA,IACnF;AAEA,SAAK,YAAY,KAAKA,MAAK,KAAK,SAAS,IAAI,KAAK,UAAU,OAAO,KAAK,IAAI,KAAK;AAAA,EACnF;AAEA,SAAO;AACT;AAEA,SAAS,MAAS,OAAa,IAAQ;AACrC,MAAID,SAAQ,KAAK,KAAK,YAAY,EAAE;AAAG;AAEvC,QAAM,MAAM,IAAI,IAAO,SAAS,CAAC,CAAC;AAClC,MAAI,CAAC,YAAY,EAAE;AAAG,QAAI,IAAI,EAAE;AAChC,SAAO,MAAM,KAAK,IAAI,OAAO,CAAC;AAChC;AAEA,SAAS,WAAW,MAA+E;AACjG,SAAO,CAAC,CAAE,MAA0B,SAAS;AAC/C;AAEA,SAAS,aAAa,MAA6E;AACjG,SAAO,CAAC,CAAE,MAAwB;AACpC;AAEA,SAAS,YAAY,WAAoB;AACvC,SAAO,CAAC,SAAgC;AAAA,IACtC,GAAG;AAAA,IACH,OAAO,OAAO,IAAI,KAAK;AAAA,IACvB,QAAQ,IAAI,OAAO,IAAI,CAAC,WAAW;AAAA,MACjC,SAAS,MAAM;AAAA,MACf,QAAQ,OAAO,MAAM,MAAM;AAAA,IAC7B,EAAE;AAAA,IACF;AAAA,EACF;AACF","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"]}