@lucid-evolution/provider 0.0.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/dist/index.js ADDED
@@ -0,0 +1,798 @@
1
+ // src/blockfrost.ts
2
+ import * as CML from "@dcspark/cardano-multiplatform-lib-nodejs";
3
+ import { fromHex } from "@lucid-evolution/core-utils";
4
+ import { applyDoubleCborEncoding } from "@lucid-evolution/utils";
5
+
6
+ // package.json
7
+ var package_default = {
8
+ name: "@anastasia-labs/provider",
9
+ version: "0.0.1",
10
+ description: "",
11
+ main: "./dist/index.js",
12
+ types: "./dist/index.d.ts",
13
+ type: "module",
14
+ files: [
15
+ "dist"
16
+ ],
17
+ publishConfig: {
18
+ access: "public"
19
+ },
20
+ scripts: {
21
+ build: "tsup-node src/index.ts --format esm,cjs --dts --clean",
22
+ clean: "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
23
+ },
24
+ keywords: [],
25
+ author: "",
26
+ license: "MIT",
27
+ devDependencies: {
28
+ "@anastasia-labs/core-types": "workspace:*",
29
+ "@anastasia-labs/core-utils": "workspace:*",
30
+ "@anastasia-labs/utils": "workspace:*",
31
+ "@dcspark/cardano-multiplatform-lib-nodejs": "^5.1.0",
32
+ "@types/node": "^20.11.24",
33
+ tsup: "^8.0.2",
34
+ typescript: "^5.3.3"
35
+ }
36
+ };
37
+
38
+ // src/blockfrost.ts
39
+ var Blockfrost = class {
40
+ url;
41
+ projectId;
42
+ constructor(url, projectId) {
43
+ this.url = url;
44
+ this.projectId = projectId || "";
45
+ }
46
+ async getProtocolParameters() {
47
+ const result = await fetch(`${this.url}/epochs/latest/parameters`, {
48
+ headers: { project_id: this.projectId, lucid }
49
+ }).then((res) => res.json());
50
+ return {
51
+ minFeeA: parseInt(result.min_fee_a),
52
+ minFeeB: parseInt(result.min_fee_b),
53
+ maxTxSize: parseInt(result.max_tx_size),
54
+ maxValSize: parseInt(result.max_val_size),
55
+ keyDeposit: BigInt(result.key_deposit),
56
+ poolDeposit: BigInt(result.pool_deposit),
57
+ priceMem: parseFloat(result.price_mem),
58
+ priceStep: parseFloat(result.price_step),
59
+ maxTxExMem: BigInt(result.max_tx_ex_mem),
60
+ maxTxExSteps: BigInt(result.max_tx_ex_steps),
61
+ coinsPerUtxoByte: BigInt(result.coins_per_utxo_size),
62
+ collateralPercentage: parseInt(result.collateral_percent),
63
+ maxCollateralInputs: parseInt(result.max_collateral_inputs),
64
+ costModels: result.cost_models
65
+ };
66
+ }
67
+ async getUtxos(addressOrCredential) {
68
+ const queryPredicate = (() => {
69
+ if (typeof addressOrCredential === "string")
70
+ return addressOrCredential;
71
+ const credentialBech32 = addressOrCredential.type === "Key" ? CML.Ed25519KeyHash.from_hex(addressOrCredential.hash).to_bech32(
72
+ "addr_vkh"
73
+ ) : CML.ScriptHash.from_hex(addressOrCredential.hash).to_bech32(
74
+ "addr_vkh"
75
+ );
76
+ return credentialBech32;
77
+ })();
78
+ let result = [];
79
+ let page = 1;
80
+ while (true) {
81
+ const pageResult = await fetch(
82
+ `${this.url}/addresses/${queryPredicate}/utxos?page=${page}`,
83
+ { headers: { project_id: this.projectId, lucid } }
84
+ ).then((res) => res.json());
85
+ if (pageResult.error) {
86
+ if (pageResult.status_code === 404) {
87
+ return [];
88
+ } else {
89
+ throw new Error("Could not fetch UTxOs from Blockfrost. Try again.");
90
+ }
91
+ }
92
+ result = result.concat(pageResult);
93
+ if (pageResult.length <= 0)
94
+ break;
95
+ page++;
96
+ }
97
+ return this.blockfrostUtxosToUtxos(result);
98
+ }
99
+ async getUtxosWithUnit(addressOrCredential, unit) {
100
+ const queryPredicate = (() => {
101
+ if (typeof addressOrCredential === "string")
102
+ return addressOrCredential;
103
+ const credentialBech32 = addressOrCredential.type === "Key" ? CML.Ed25519KeyHash.from_hex(addressOrCredential.hash).to_bech32(
104
+ "addr_vkh"
105
+ ) : CML.ScriptHash.from_hex(addressOrCredential.hash).to_bech32(
106
+ "addr_vkh"
107
+ );
108
+ return credentialBech32;
109
+ })();
110
+ let result = [];
111
+ let page = 1;
112
+ while (true) {
113
+ const pageResult = await fetch(
114
+ `${this.url}/addresses/${queryPredicate}/utxos/${unit}?page=${page}`,
115
+ { headers: { project_id: this.projectId, lucid } }
116
+ ).then((res) => res.json());
117
+ if (pageResult.error) {
118
+ if (pageResult.status_code === 404) {
119
+ return [];
120
+ } else {
121
+ throw new Error("Could not fetch UTxOs from Blockfrost. Try again.");
122
+ }
123
+ }
124
+ result = result.concat(pageResult);
125
+ if (pageResult.length <= 0)
126
+ break;
127
+ page++;
128
+ }
129
+ return this.blockfrostUtxosToUtxos(result);
130
+ }
131
+ async getUtxoByUnit(unit) {
132
+ const addresses = await fetch(
133
+ `${this.url}/assets/${unit}/addresses?count=2`,
134
+ { headers: { project_id: this.projectId, lucid } }
135
+ ).then((res) => res.json());
136
+ if (!addresses || addresses.error) {
137
+ throw new Error("Unit not found.");
138
+ }
139
+ if (addresses.length > 1) {
140
+ throw new Error("Unit needs to be an NFT or only held by one address.");
141
+ }
142
+ const address = addresses[0].address;
143
+ const utxos = await this.getUtxosWithUnit(address, unit);
144
+ if (utxos.length > 1) {
145
+ throw new Error("Unit needs to be an NFT or only held by one address.");
146
+ }
147
+ return utxos[0];
148
+ }
149
+ async getUtxosByOutRef(outRefs) {
150
+ const queryHashes = [...new Set(outRefs.map((outRef) => outRef.txHash))];
151
+ const utxos = await Promise.all(
152
+ queryHashes.map(async (txHash) => {
153
+ const result = await fetch(`${this.url}/txs/${txHash}/utxos`, {
154
+ headers: { project_id: this.projectId, lucid }
155
+ }).then((res) => res.json());
156
+ if (!result || result.error) {
157
+ return [];
158
+ }
159
+ const utxosResult = result.outputs.map(
160
+ (r) => ({
161
+ ...r,
162
+ tx_hash: txHash
163
+ })
164
+ );
165
+ return this.blockfrostUtxosToUtxos(utxosResult);
166
+ })
167
+ );
168
+ return utxos.reduce((acc, utxos2) => acc.concat(utxos2), []).filter(
169
+ (utxo) => outRefs.some(
170
+ (outRef) => utxo.txHash === outRef.txHash && utxo.outputIndex === outRef.outputIndex
171
+ )
172
+ );
173
+ }
174
+ async getDelegation(rewardAddress) {
175
+ const result = await fetch(`${this.url}/accounts/${rewardAddress}`, {
176
+ headers: { project_id: this.projectId, lucid }
177
+ }).then((res) => res.json());
178
+ if (!result || result.error) {
179
+ return { poolId: null, rewards: 0n };
180
+ }
181
+ return {
182
+ poolId: result.pool_id || null,
183
+ rewards: BigInt(result.withdrawable_amount)
184
+ };
185
+ }
186
+ async getDatum(datumHash) {
187
+ const datum = await fetch(`${this.url}/scripts/datum/${datumHash}/cbor`, {
188
+ headers: { project_id: this.projectId, lucid }
189
+ }).then((res) => res.json()).then((res) => res.cbor);
190
+ if (!datum || datum.error) {
191
+ throw new Error(`No datum found for datum hash: ${datumHash}`);
192
+ }
193
+ return datum;
194
+ }
195
+ awaitTx(txHash, checkInterval = 3e3) {
196
+ return new Promise((res) => {
197
+ const confirmation = setInterval(async () => {
198
+ const isConfirmed = await fetch(`${this.url}/txs/${txHash}`, {
199
+ headers: { project_id: this.projectId, lucid }
200
+ }).then((res2) => res2.json());
201
+ if (isConfirmed && !isConfirmed.error) {
202
+ clearInterval(confirmation);
203
+ await new Promise((res2) => setTimeout(() => res2(1), 1e3));
204
+ return res(true);
205
+ }
206
+ }, checkInterval);
207
+ });
208
+ }
209
+ async submitTx(tx) {
210
+ const result = await fetch(`${this.url}/tx/submit`, {
211
+ method: "POST",
212
+ headers: {
213
+ "Content-Type": "application/cbor",
214
+ project_id: this.projectId,
215
+ lucid
216
+ },
217
+ body: fromHex(tx)
218
+ }).then((res) => res.json());
219
+ if (!result || result.error) {
220
+ if (result?.status_code === 400)
221
+ throw new Error(result.message);
222
+ else
223
+ throw new Error("Could not submit transaction.");
224
+ }
225
+ return result;
226
+ }
227
+ async blockfrostUtxosToUtxos(result) {
228
+ return await Promise.all(
229
+ result.map(async (r) => ({
230
+ txHash: r.tx_hash,
231
+ outputIndex: r.output_index,
232
+ assets: Object.fromEntries(
233
+ r.amount.map(({ unit, quantity }) => [unit, BigInt(quantity)])
234
+ ),
235
+ address: r.address,
236
+ datumHash: !r.inline_datum && r.data_hash || void 0,
237
+ datum: r.inline_datum || void 0,
238
+ scriptRef: r.reference_script_hash ? await (async () => {
239
+ const { type } = await fetch(
240
+ `${this.url}/scripts/${r.reference_script_hash}`,
241
+ {
242
+ headers: { project_id: this.projectId, lucid }
243
+ }
244
+ ).then((res) => res.json());
245
+ if (type === "Native" || type === "native") {
246
+ throw new Error("Native script ref not implemented!");
247
+ }
248
+ const { cbor: script } = await fetch(
249
+ `${this.url}/scripts/${r.reference_script_hash}/cbor`,
250
+ { headers: { project_id: this.projectId, lucid } }
251
+ ).then((res) => res.json());
252
+ return {
253
+ type: type === "plutusV1" ? "PlutusV1" : "PlutusV2",
254
+ script: applyDoubleCborEncoding(script)
255
+ };
256
+ })() : void 0
257
+ }))
258
+ );
259
+ }
260
+ };
261
+ function datumJsonToCbor(json) {
262
+ const convert = (json2) => {
263
+ if (!isNaN(json2.int)) {
264
+ return CML.PlutusData.new_integer(
265
+ CML.BigInteger.from_str(json2.int.toString())
266
+ );
267
+ } else if (json2.bytes || !isNaN(Number(json2.bytes))) {
268
+ return CML.PlutusData.new_bytes(fromHex(json2.bytes));
269
+ } else if (json2.map) {
270
+ const m = CML.PlutusMap.new();
271
+ json2.map.forEach(({ k, v }) => {
272
+ m.set(convert(k), convert(v));
273
+ });
274
+ return CML.PlutusData.new_map(m);
275
+ } else if (json2.list) {
276
+ const l = CML.PlutusDataList.new();
277
+ json2.list.forEach((v) => {
278
+ l.add(convert(v));
279
+ });
280
+ return CML.PlutusData.new_list(l);
281
+ } else if (!isNaN(json2.constructor)) {
282
+ const l = CML.PlutusDataList.new();
283
+ json2.fields.forEach((v) => {
284
+ l.add(convert(v));
285
+ });
286
+ return CML.PlutusData.new_constr_plutus_data(
287
+ CML.ConstrPlutusData.new(
288
+ CML.BigInteger.from_str(json2.constructor.toString()).as_u64(),
289
+ l
290
+ )
291
+ );
292
+ }
293
+ throw new Error("Unsupported type");
294
+ };
295
+ return convert(json).to_cbor_hex();
296
+ }
297
+ var lucid = package_default.version;
298
+
299
+ // src/kupmios.ts
300
+ import { fromUnit } from "@lucid-evolution/utils";
301
+ import * as CML2 from "@dcspark/cardano-multiplatform-lib-nodejs";
302
+ var Kupmios = class {
303
+ kupoUrl;
304
+ ogmiosUrl;
305
+ /**
306
+ * @param kupoUrl: http(s)://localhost:1442
307
+ * @param ogmiosUrl: ws(s)://localhost:1337
308
+ */
309
+ constructor(kupoUrl, ogmiosUrl) {
310
+ this.kupoUrl = kupoUrl;
311
+ this.ogmiosUrl = ogmiosUrl;
312
+ }
313
+ async getProtocolParameters() {
314
+ const client = await this.ogmiosWsp("Query", {
315
+ query: "currentProtocolParameters"
316
+ });
317
+ return new Promise((res, rej) => {
318
+ client.addEventListener(
319
+ "message",
320
+ (msg) => {
321
+ try {
322
+ const { result } = JSON.parse(msg.data);
323
+ const costModels = {};
324
+ Object.keys(result.costModels).forEach((v) => {
325
+ const version = v.split(":")[1].toUpperCase();
326
+ const plutusVersion = "Plutus" + version;
327
+ costModels[plutusVersion] = result.costModels[v];
328
+ });
329
+ const [memNum, memDenom] = result.prices.memory.split("/");
330
+ const [stepsNum, stepsDenom] = result.prices.steps.split("/");
331
+ res({
332
+ minFeeA: parseInt(result.minFeeCoefficient),
333
+ minFeeB: parseInt(result.minFeeConstant),
334
+ maxTxSize: parseInt(result.maxTxSize),
335
+ maxValSize: parseInt(result.maxValueSize),
336
+ keyDeposit: BigInt(result.stakeKeyDeposit),
337
+ poolDeposit: BigInt(result.poolDeposit),
338
+ priceMem: parseInt(memNum) / parseInt(memDenom),
339
+ priceStep: parseInt(stepsNum) / parseInt(stepsDenom),
340
+ maxTxExMem: BigInt(result.maxExecutionUnitsPerTransaction.memory),
341
+ maxTxExSteps: BigInt(
342
+ result.maxExecutionUnitsPerTransaction.steps
343
+ ),
344
+ coinsPerUtxoByte: BigInt(result.coinsPerUtxoByte),
345
+ collateralPercentage: parseInt(result.collateralPercentage),
346
+ maxCollateralInputs: parseInt(result.maxCollateralInputs),
347
+ costModels
348
+ });
349
+ client.close();
350
+ } catch (e) {
351
+ rej(e);
352
+ }
353
+ },
354
+ { once: true }
355
+ );
356
+ });
357
+ }
358
+ async getUtxos(addressOrCredential) {
359
+ const isAddress = typeof addressOrCredential === "string";
360
+ const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
361
+ const result = await fetch(
362
+ `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent`
363
+ ).then((res) => res.json());
364
+ return this.kupmiosUtxosToUtxos(result);
365
+ }
366
+ async getUtxosWithUnit(addressOrCredential, unit) {
367
+ const isAddress = typeof addressOrCredential === "string";
368
+ const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
369
+ const { policyId, assetName } = fromUnit(unit);
370
+ const result = await fetch(
371
+ `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${policyId}${assetName ? `&asset_name=${assetName}` : ""}`
372
+ ).then((res) => res.json());
373
+ return this.kupmiosUtxosToUtxos(result);
374
+ }
375
+ async getUtxoByUnit(unit) {
376
+ const { policyId, assetName } = fromUnit(unit);
377
+ const result = await fetch(
378
+ `${this.kupoUrl}/matches/${policyId}.${assetName ? `${assetName}` : "*"}?unspent`
379
+ ).then((res) => res.json());
380
+ const utxos = await this.kupmiosUtxosToUtxos(result);
381
+ if (utxos.length > 1) {
382
+ throw new Error("Unit needs to be an NFT or only held by one address.");
383
+ }
384
+ return utxos[0];
385
+ }
386
+ async getUtxosByOutRef(outRefs) {
387
+ const queryHashes = [...new Set(outRefs.map((outRef) => outRef.txHash))];
388
+ const utxos = await Promise.all(
389
+ queryHashes.map(async (txHash) => {
390
+ const result = await fetch(
391
+ `${this.kupoUrl}/matches/*@${txHash}?unspent`
392
+ ).then((res) => res.json());
393
+ return this.kupmiosUtxosToUtxos(result);
394
+ })
395
+ );
396
+ return utxos.reduce((acc, utxos2) => acc.concat(utxos2), []).filter(
397
+ (utxo) => outRefs.some(
398
+ (outRef) => utxo.txHash === outRef.txHash && utxo.outputIndex === outRef.outputIndex
399
+ )
400
+ );
401
+ }
402
+ async getDelegation(rewardAddress) {
403
+ const client = await this.ogmiosWsp("Query", {
404
+ query: { delegationsAndRewards: [rewardAddress] }
405
+ });
406
+ return new Promise((res, rej) => {
407
+ client.addEventListener(
408
+ "message",
409
+ (msg) => {
410
+ try {
411
+ const { result } = JSON.parse(msg.data);
412
+ const delegation = result ? Object.values(result)[0] : {};
413
+ res({
414
+ poolId: delegation?.delegate || null,
415
+ rewards: BigInt(delegation?.rewards || 0)
416
+ });
417
+ client.close();
418
+ } catch (e) {
419
+ rej(e);
420
+ }
421
+ },
422
+ { once: true }
423
+ );
424
+ });
425
+ }
426
+ async getDatum(datumHash) {
427
+ const result = await fetch(`${this.kupoUrl}/datums/${datumHash}`).then(
428
+ (res) => res.json()
429
+ );
430
+ if (!result || !result.datum) {
431
+ throw new Error(`No datum found for datum hash: ${datumHash}`);
432
+ }
433
+ return result.datum;
434
+ }
435
+ awaitTx(txHash, checkInterval = 3e3) {
436
+ return new Promise((res) => {
437
+ const confirmation = setInterval(async () => {
438
+ const isConfirmed = await fetch(
439
+ `${this.kupoUrl}/matches/*@${txHash}?unspent`
440
+ ).then((res2) => res2.json());
441
+ if (isConfirmed && isConfirmed.length > 0) {
442
+ clearInterval(confirmation);
443
+ await new Promise((res2) => setTimeout(() => res2(1), 1e3));
444
+ return res(true);
445
+ }
446
+ }, checkInterval);
447
+ });
448
+ }
449
+ async submitTx(tx) {
450
+ const client = await this.ogmiosWsp("SubmitTx", {
451
+ submit: tx
452
+ });
453
+ return new Promise((res, rej) => {
454
+ client.addEventListener(
455
+ "message",
456
+ (msg) => {
457
+ try {
458
+ const { result } = JSON.parse(msg.data);
459
+ if (result.SubmitSuccess)
460
+ res(result.SubmitSuccess.txId);
461
+ else
462
+ rej(result.SubmitFail);
463
+ client.close();
464
+ } catch (e) {
465
+ rej(e);
466
+ }
467
+ },
468
+ { once: true }
469
+ );
470
+ });
471
+ }
472
+ kupmiosUtxosToUtxos(utxos) {
473
+ return Promise.all(
474
+ utxos.map(async (utxo) => {
475
+ return {
476
+ txHash: utxo.transaction_id,
477
+ outputIndex: parseInt(utxo.output_index),
478
+ address: utxo.address,
479
+ assets: (() => {
480
+ const a = { lovelace: BigInt(utxo.value.coins) };
481
+ Object.keys(utxo.value.assets).forEach((unit) => {
482
+ a[unit.replace(".", "")] = BigInt(utxo.value.assets[unit]);
483
+ });
484
+ return a;
485
+ })(),
486
+ datumHash: utxo?.datum_type === "hash" ? utxo.datum_hash : null,
487
+ datum: utxo?.datum_type === "inline" ? await this.getDatum(utxo.datum_hash) : null,
488
+ scriptRef: utxo.script_hash && await (async () => {
489
+ const { script, language } = await fetch(
490
+ `${this.kupoUrl}/scripts/${utxo.script_hash}`
491
+ ).then((res) => res.json());
492
+ if (language === "native") {
493
+ return { type: "Native", script };
494
+ } else if (language === "plutus:v1") {
495
+ return {
496
+ type: "PlutusV1",
497
+ script: CML2.PlutusV1Script.from_cbor_hex(script).to_cbor_hex()
498
+ };
499
+ } else if (language === "plutus:v2") {
500
+ return {
501
+ type: "PlutusV2",
502
+ script: CML2.PlutusV2Script.from_cbor_hex(script).to_cbor_hex()
503
+ };
504
+ }
505
+ })()
506
+ };
507
+ })
508
+ );
509
+ }
510
+ async ogmiosWsp(methodname, args) {
511
+ const client = new WebSocket(this.ogmiosUrl);
512
+ await new Promise((res) => {
513
+ client.addEventListener("open", () => res(1), { once: true });
514
+ });
515
+ client.send(
516
+ JSON.stringify({
517
+ type: "jsonwsp/request",
518
+ version: "1.0",
519
+ servicename: "ogmios",
520
+ methodname,
521
+ args
522
+ })
523
+ );
524
+ return client;
525
+ }
526
+ };
527
+
528
+ // src/maestro.ts
529
+ import * as CML3 from "@dcspark/cardano-multiplatform-lib-nodejs";
530
+ import { applyDoubleCborEncoding as applyDoubleCborEncoding2 } from "@lucid-evolution/utils";
531
+ import { fromHex as fromHex2 } from "@lucid-evolution/core-utils";
532
+ var Maestro = class {
533
+ url;
534
+ apiKey;
535
+ turboSubmit;
536
+ constructor({ network, apiKey, turboSubmit = false }) {
537
+ this.url = `https://${network}.gomaestro-api.org/v1`;
538
+ this.apiKey = apiKey;
539
+ this.turboSubmit = turboSubmit;
540
+ }
541
+ async getProtocolParameters() {
542
+ const timestampedResult = await fetch(`${this.url}/protocol-params`, {
543
+ headers: this.commonHeaders()
544
+ }).then((res) => res.json());
545
+ const result = timestampedResult.data;
546
+ const decimalFromRationalString = (str) => {
547
+ const forwardSlashIndex = str.indexOf("/");
548
+ return parseInt(str.slice(0, forwardSlashIndex)) / parseInt(str.slice(forwardSlashIndex + 1));
549
+ };
550
+ const renameKeysAndSort = (obj, newKeys) => {
551
+ const entries = Object.keys(obj).sort().map((key) => {
552
+ const newKey = newKeys[key] || key;
553
+ return {
554
+ [newKey]: Object.fromEntries(
555
+ Object.entries(obj[key]).sort(
556
+ ([k, _v], [k2, _v2]) => k.localeCompare(k2)
557
+ )
558
+ )
559
+ };
560
+ });
561
+ return Object.assign({}, ...entries);
562
+ };
563
+ return {
564
+ minFeeA: parseInt(result.min_fee_coefficient),
565
+ minFeeB: parseInt(result.min_fee_constant),
566
+ maxTxSize: parseInt(result.max_tx_size),
567
+ maxValSize: parseInt(result.max_value_size),
568
+ keyDeposit: BigInt(result.stake_key_deposit),
569
+ poolDeposit: BigInt(result.pool_deposit),
570
+ priceMem: decimalFromRationalString(result.prices.memory),
571
+ priceStep: decimalFromRationalString(result.prices.steps),
572
+ maxTxExMem: BigInt(result.max_execution_units_per_transaction.memory),
573
+ maxTxExSteps: BigInt(result.max_execution_units_per_transaction.steps),
574
+ coinsPerUtxoByte: BigInt(result.coins_per_utxo_byte),
575
+ collateralPercentage: parseInt(result.collateral_percentage),
576
+ maxCollateralInputs: parseInt(result.max_collateral_inputs),
577
+ costModels: renameKeysAndSort(result.cost_models, {
578
+ "plutus:v1": "PlutusV1",
579
+ "plutus:v2": "PlutusV2"
580
+ })
581
+ };
582
+ }
583
+ async getUtxosInternal(addressOrCredential, unit) {
584
+ const queryPredicate = (() => {
585
+ if (typeof addressOrCredential === "string") {
586
+ return "/addresses/" + addressOrCredential;
587
+ }
588
+ let credentialBech32Query = "/addresses/cred/";
589
+ credentialBech32Query += addressOrCredential.type === "Key" ? CML3.Ed25519KeyHash.from_hex(addressOrCredential.hash).to_bech32(
590
+ "addr_vkh"
591
+ ) : CML3.ScriptHash.from_hex(addressOrCredential.hash).to_bech32(
592
+ "addr_shared_vkh"
593
+ );
594
+ return credentialBech32Query;
595
+ })();
596
+ const qparams = new URLSearchParams({
597
+ count: "100",
598
+ ...unit && { asset: unit }
599
+ });
600
+ const result = await this.getAllPagesData(
601
+ async (qry) => await fetch(qry, {
602
+ headers: this.requireAmountsAsStrings(this.commonHeaders())
603
+ }),
604
+ `${this.url}${queryPredicate}/utxos`,
605
+ qparams,
606
+ "Location: getUtxosInternal. Error: Could not fetch UTxOs from Maestro"
607
+ );
608
+ return result.map(this.maestroUtxoToUtxo);
609
+ }
610
+ getUtxos(addressOrCredential) {
611
+ return this.getUtxosInternal(addressOrCredential);
612
+ }
613
+ getUtxosWithUnit(addressOrCredential, unit) {
614
+ return this.getUtxosInternal(addressOrCredential, unit);
615
+ }
616
+ async getUtxoByUnit(unit) {
617
+ const timestampedAddressesResponse = await fetch(
618
+ `${this.url}/assets/${unit}/addresses?count=2`,
619
+ { headers: this.commonHeaders() }
620
+ );
621
+ const timestampedAddresses = await timestampedAddressesResponse.json();
622
+ if (!timestampedAddressesResponse.ok) {
623
+ if (timestampedAddresses.message) {
624
+ throw new Error(timestampedAddresses.message);
625
+ }
626
+ throw new Error(
627
+ "Location: getUtxoByUnit. Error: Couldn't perform query. Received status code: " + timestampedAddressesResponse.status
628
+ );
629
+ }
630
+ const addressesWithAmount = timestampedAddresses.data;
631
+ if (addressesWithAmount.length === 0) {
632
+ throw new Error("Location: getUtxoByUnit. Error: Unit not found.");
633
+ }
634
+ if (addressesWithAmount.length > 1) {
635
+ throw new Error(
636
+ "Location: getUtxoByUnit. Error: Unit needs to be an NFT or only held by one address."
637
+ );
638
+ }
639
+ const address = addressesWithAmount[0].address;
640
+ const utxos = await this.getUtxosWithUnit(address, unit);
641
+ if (utxos.length > 1) {
642
+ throw new Error(
643
+ "Location: getUtxoByUnit. Error: Unit needs to be an NFT or only held by one address."
644
+ );
645
+ }
646
+ return utxos[0];
647
+ }
648
+ async getUtxosByOutRef(outRefs) {
649
+ const qry = `${this.url}/transactions/outputs`;
650
+ const body = JSON.stringify(
651
+ outRefs.map(({ txHash, outputIndex }) => `${txHash}#${outputIndex}`)
652
+ );
653
+ const utxos = await this.getAllPagesData(
654
+ async (qry2) => await fetch(qry2, {
655
+ method: "POST",
656
+ headers: {
657
+ "Content-Type": "application/json",
658
+ ...this.requireAmountsAsStrings(this.commonHeaders())
659
+ },
660
+ body
661
+ }),
662
+ qry,
663
+ new URLSearchParams({}),
664
+ "Location: getUtxosByOutRef. Error: Could not fetch UTxOs by references from Maestro"
665
+ );
666
+ return utxos.map(this.maestroUtxoToUtxo);
667
+ }
668
+ async getDelegation(rewardAddress) {
669
+ const timestampedResultResponse = await fetch(
670
+ `${this.url}/accounts/${rewardAddress}`,
671
+ { headers: this.commonHeaders() }
672
+ );
673
+ if (!timestampedResultResponse.ok) {
674
+ return { poolId: null, rewards: 0n };
675
+ }
676
+ const timestampedResult = await timestampedResultResponse.json();
677
+ const result = timestampedResult.data;
678
+ return {
679
+ poolId: result.delegated_pool || null,
680
+ rewards: BigInt(result.rewards_available)
681
+ };
682
+ }
683
+ async getDatum(datumHash) {
684
+ const timestampedResultResponse = await fetch(
685
+ `${this.url}/datums/${datumHash}`,
686
+ {
687
+ headers: this.commonHeaders()
688
+ }
689
+ );
690
+ if (!timestampedResultResponse.ok) {
691
+ if (timestampedResultResponse.status === 404) {
692
+ throw new Error(`No datum found for datum hash: ${datumHash}`);
693
+ } else {
694
+ throw new Error(
695
+ "Location: getDatum. Error: Couldn't successfully perform query. Received status code: " + timestampedResultResponse.status
696
+ );
697
+ }
698
+ }
699
+ const timestampedResult = await timestampedResultResponse.json();
700
+ return timestampedResult.data.bytes;
701
+ }
702
+ awaitTx(txHash, checkInterval = 3e3) {
703
+ return new Promise((res) => {
704
+ const confirmation = setInterval(async () => {
705
+ const isConfirmedResponse = await fetch(
706
+ `${this.url}/transactions/${txHash}/cbor`,
707
+ {
708
+ headers: this.commonHeaders()
709
+ }
710
+ );
711
+ if (isConfirmedResponse.ok) {
712
+ await isConfirmedResponse.json();
713
+ clearInterval(confirmation);
714
+ await new Promise((res2) => setTimeout(() => res2(1), 1e3));
715
+ return res(true);
716
+ }
717
+ }, checkInterval);
718
+ });
719
+ }
720
+ async submitTx(tx) {
721
+ let queryUrl = `${this.url}/txmanager`;
722
+ queryUrl += this.turboSubmit ? "/turbosubmit" : "";
723
+ const response = await fetch(queryUrl, {
724
+ method: "POST",
725
+ headers: {
726
+ "Content-Type": "application/cbor",
727
+ Accept: "text/plain",
728
+ ...this.commonHeaders()
729
+ },
730
+ body: fromHex2(tx)
731
+ });
732
+ const result = await response.text();
733
+ if (!response.ok) {
734
+ if (response.status === 400)
735
+ throw new Error(result);
736
+ else {
737
+ throw new Error(
738
+ "Could not submit transaction. Received status code: " + response.status
739
+ );
740
+ }
741
+ }
742
+ return result;
743
+ }
744
+ commonHeaders() {
745
+ return { "api-key": this.apiKey, lucid: lucid2 };
746
+ }
747
+ requireAmountsAsStrings(obj) {
748
+ return { ...obj, "amounts-as-strings": "true" };
749
+ }
750
+ maestroUtxoToUtxo(result) {
751
+ return {
752
+ txHash: result.tx_hash,
753
+ outputIndex: result.index,
754
+ assets: (() => {
755
+ const a = {};
756
+ result.assets.forEach((am) => {
757
+ a[am.unit] = BigInt(am.amount);
758
+ });
759
+ return a;
760
+ })(),
761
+ address: result.address,
762
+ datumHash: result.datum ? result.datum.type == "inline" ? void 0 : result.datum.hash : void 0,
763
+ datum: result.datum?.bytes,
764
+ scriptRef: result.reference_script ? result.reference_script.type == "native" ? void 0 : {
765
+ type: result.reference_script.type == "plutusv1" ? "PlutusV1" : "PlutusV2",
766
+ script: applyDoubleCborEncoding2(result.reference_script.bytes)
767
+ } : void 0
768
+ };
769
+ }
770
+ async getAllPagesData(getResponse, qry, paramsGiven, errorMsg) {
771
+ let nextCursor = null;
772
+ let result = [];
773
+ while (true) {
774
+ if (nextCursor !== null) {
775
+ paramsGiven.set("cursor", nextCursor);
776
+ }
777
+ const response = await getResponse(`${qry}?` + paramsGiven);
778
+ const pageResult = await response.json();
779
+ if (!response.ok) {
780
+ throw new Error(
781
+ `${errorMsg}. Received status code: ${response.status}`
782
+ );
783
+ }
784
+ nextCursor = pageResult.next_cursor;
785
+ result = result.concat(pageResult.data);
786
+ if (nextCursor == null)
787
+ break;
788
+ }
789
+ return result;
790
+ }
791
+ };
792
+ var lucid2 = package_default.version;
793
+ export {
794
+ Blockfrost,
795
+ Kupmios,
796
+ Maestro,
797
+ datumJsonToCbor
798
+ };