@lucid-evolution/provider 0.1.40 → 0.1.42

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.cjs CHANGED
@@ -52,7 +52,7 @@ var import_utils = require("@lucid-evolution/utils");
52
52
  // package.json
53
53
  var package_default = {
54
54
  name: "@lucid-evolution/provider",
55
- version: "0.1.40",
55
+ version: "0.1.42",
56
56
  description: "",
57
57
  main: "./dist/index.js",
58
58
  types: "./dist/index.d.ts",
@@ -284,37 +284,99 @@ var Blockfrost = class {
284
284
  return result;
285
285
  }
286
286
  async blockfrostUtxosToUtxos(result) {
287
- return await Promise.all(
288
- result.map(async (r) => ({
289
- txHash: r.tx_hash,
290
- outputIndex: r.output_index,
291
- assets: Object.fromEntries(
292
- r.amount.map(({ unit, quantity }) => [unit, BigInt(quantity)])
293
- ),
294
- address: r.address,
295
- datumHash: !r.inline_datum && r.data_hash || void 0,
296
- datum: r.inline_datum || void 0,
297
- scriptRef: r.reference_script_hash ? await (async () => {
298
- const { type } = await fetch(
299
- `${this.url}/scripts/${r.reference_script_hash}`,
300
- {
301
- headers: { project_id: this.projectId, lucid }
302
- }
303
- ).then((res) => res.json());
304
- if (type === "Native" || type === "native") {
305
- throw new Error("Native script ref not implemented!");
306
- }
307
- const { cbor: script } = await fetch(
308
- `${this.url}/scripts/${r.reference_script_hash}/cbor`,
309
- { headers: { project_id: this.projectId, lucid } }
310
- ).then((res) => res.json());
287
+ const utxos = [];
288
+ const batchSize = 10;
289
+ let count = 0;
290
+ for (let i = 0; i < result.length; i += batchSize) {
291
+ const batch = result.slice(i, i + batchSize);
292
+ count += batchSize;
293
+ await handleRateLimit(count);
294
+ const batchResults = await Promise.all(
295
+ batch.map(async (r) => {
311
296
  return {
312
- type: type === "plutusV1" ? "PlutusV1" : "PlutusV2",
313
- script: (0, import_utils.applyDoubleCborEncoding)(script)
297
+ txHash: r.tx_hash,
298
+ outputIndex: r.output_index,
299
+ assets: Object.fromEntries(
300
+ r.amount.map(({ unit, quantity }) => [unit, BigInt(quantity)])
301
+ ),
302
+ address: r.address,
303
+ datumHash: !r.inline_datum && r.data_hash || void 0,
304
+ datum: r.inline_datum || void 0,
305
+ scriptRef: r.reference_script_hash ? await (async () => {
306
+ const { type } = await fetch(
307
+ `${this.url}/scripts/${r.reference_script_hash}`,
308
+ {
309
+ headers: { project_id: this.projectId, lucid }
310
+ }
311
+ ).then((res) => res.json());
312
+ if (type.toLowerCase() === "native") {
313
+ throw new Error("Native script ref not implemented!");
314
+ }
315
+ const { cbor: script } = await fetch(
316
+ `${this.url}/scripts/${r.reference_script_hash}/cbor`,
317
+ { headers: { project_id: this.projectId, lucid } }
318
+ ).then((res) => res.json());
319
+ return {
320
+ type: type === "plutusV1" ? "PlutusV1" : "PlutusV2",
321
+ script: (0, import_utils.applyDoubleCborEncoding)(script)
322
+ };
323
+ })() : void 0
314
324
  };
315
- })() : void 0
316
- }))
325
+ })
326
+ );
327
+ utxos.push(...batchResults);
328
+ }
329
+ return utxos;
330
+ }
331
+ async evaluateTx(tx, additionalUTxOs) {
332
+ const additionalUTxOSet = (additionalUTxOs || []).map((utxo) => [
333
+ { txId: utxo.txHash, index: utxo.outputIndex },
334
+ {
335
+ address: utxo.address,
336
+ value: { coins: utxo.assets.lovelace, assets: utxo.assets.restAssets },
337
+ datum_hash: utxo.datumHash,
338
+ datum: utxo.datum,
339
+ script: utxo.scriptRef
340
+ }
341
+ ]);
342
+ const payload = {
343
+ cbor: tx,
344
+ additionalUTxOSet
345
+ };
346
+ const res = await fetch(`${this.url}/utils/txs/evaluate/utxos`, {
347
+ method: "POST",
348
+ headers: {
349
+ "Content-Type": "application/json",
350
+ project_id: this.projectId,
351
+ lucid
352
+ },
353
+ body: JSON.stringify(
354
+ payload,
355
+ (_, value) => typeof value === "bigint" ? value.toString() : value
356
+ )
357
+ }).then((res2) => res2.json());
358
+ if (!res || res.error) {
359
+ const message = res?.status_code === 400 ? res.message : `Could not evaluate the transaction: ${JSON.stringify(res)}`;
360
+ throw new Error(message);
361
+ }
362
+ const blockfrostRedeemer = res;
363
+ if (!("EvaluationResult" in blockfrostRedeemer.result)) {
364
+ throw new Error(
365
+ `EvaluateTransaction fails: ${JSON.stringify(blockfrostRedeemer.result)}`
366
+ );
367
+ }
368
+ const evalRedeemers = [];
369
+ Object.entries(blockfrostRedeemer.result.EvaluationResult).forEach(
370
+ ([redeemerPointer, data]) => {
371
+ const [pTag, pIndex] = redeemerPointer.split(":");
372
+ evalRedeemers.push({
373
+ redeemer_tag: pTag,
374
+ redeemer_index: Number(pIndex),
375
+ ex_units: { mem: Number(data.memory), steps: Number(data.steps) }
376
+ });
377
+ }
317
378
  );
379
+ return evalRedeemers;
318
380
  }
319
381
  };
320
382
  function datumJsonToCbor(json) {
@@ -353,6 +415,13 @@ function datumJsonToCbor(json) {
353
415
  };
354
416
  return convert(json).to_cbor_hex();
355
417
  }
418
+ var handleRateLimit = async (count) => {
419
+ if (count % 100 === 0) {
420
+ await (0, import_core_utils.sleep)(2e3);
421
+ } else if (count % 10 === 0) {
422
+ await (0, import_core_utils.sleep)(200);
423
+ }
424
+ };
356
425
  var lucid = package_default.version;
357
426
 
358
427
  // src/kupmios/kupmios.ts
@@ -627,6 +696,66 @@ var Kupmios = class {
627
696
  const { result } = await import_effect.Effect.runPromise(program);
628
697
  return result.transaction.id;
629
698
  }
699
+ async evaluateTx(tx, additionalUTxOs) {
700
+ const utxos = (additionalUTxOs || []).map((utxo) => {
701
+ const script = utxo.scriptRef ? {
702
+ language: utxo.scriptRef.type,
703
+ cbor: utxo.scriptRef.script
704
+ } : void 0;
705
+ return [
706
+ {
707
+ transaction: { id: utxo.txHash, output: { index: utxo.outputIndex } }
708
+ },
709
+ {
710
+ address: utxo.address,
711
+ value: {
712
+ coins: utxo.assets.lovelace,
713
+ assets: utxo.assets.restAssets
714
+ },
715
+ datumHash: utxo.datumHash,
716
+ datum: utxo.datum,
717
+ script
718
+ }
719
+ ];
720
+ });
721
+ const data = {
722
+ jsonrpc: "2.0",
723
+ method: "evaluateTransaction",
724
+ params: { transaction: { cbor: tx }, additionalUTxO: utxos },
725
+ id: null
726
+ };
727
+ const schema = JSONRPCSchema(
728
+ S2.Array(
729
+ S2.Struct({
730
+ validator: S2.Struct({
731
+ purpose: S2.String,
732
+ index: S2.Int
733
+ }),
734
+ budget: S2.Struct({
735
+ memory: S2.Int,
736
+ cpu: S2.Int
737
+ })
738
+ })
739
+ )
740
+ );
741
+ const program = fetchOgmiosParse(this.ogmiosUrl, data, schema).pipe(
742
+ import_effect.Effect.flatMap(
743
+ (response) => "error" in response ? kupmiosError(response.error) : import_effect.Effect.succeed(response.result)
744
+ ),
745
+ import_effect.Effect.timeout(1e4),
746
+ import_effect.Effect.catchAll(kupmiosError)
747
+ );
748
+ const result = await import_effect.Effect.runPromise(program);
749
+ const evalRedeemers = result.map((item) => ({
750
+ ex_units: {
751
+ mem: item.budget.memory,
752
+ steps: item.budget.cpu
753
+ },
754
+ redeemer_index: item.validator.index,
755
+ redeemer_tag: item.validator.purpose
756
+ }));
757
+ return evalRedeemers;
758
+ }
630
759
  };
631
760
  var getDatumEffect = (kupoUrl, datum_type, datum_hash) => import_effect.Effect.gen(function* () {
632
761
  if (datum_type === "inline" && datum_hash) {
@@ -753,6 +882,7 @@ var import_utils3 = require("@lucid-evolution/utils");
753
882
  var import_utils4 = require("@lucid-evolution/utils");
754
883
  var import_core_utils2 = require("@lucid-evolution/core-utils");
755
884
  var import_wallet = require("@lucid-evolution/wallet");
885
+ var import_cardano_multiplatform_lib_nodejs = require("@anastasia-labs/cardano-multiplatform-lib-nodejs");
756
886
  function generateEmulatorAccount(assets) {
757
887
  const seedPhrase = (0, import_utils3.generateSeedPhrase)();
758
888
  return {
@@ -1340,6 +1470,49 @@ It does not exist or was already spent.`
1340
1470
  }
1341
1471
  return Promise.resolve(txHash);
1342
1472
  }
1473
+ async evaluateTx(tx, additionalUTxOs) {
1474
+ const desTx = CML.Transaction.from_cbor_hex(tx);
1475
+ const redeemers = desTx.witness_set().redeemers();
1476
+ if (!redeemers) {
1477
+ return [];
1478
+ }
1479
+ let evalRedeemers = [];
1480
+ const arrLegacyRedeemer = redeemers.as_arr_legacy_redeemer();
1481
+ if (arrLegacyRedeemer) {
1482
+ for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
1483
+ const legacyRedeemer = arrLegacyRedeemer.get(i);
1484
+ evalRedeemers.push({
1485
+ ex_units: {
1486
+ mem: Number(legacyRedeemer.ex_units().mem()),
1487
+ steps: Number(legacyRedeemer.ex_units().steps())
1488
+ },
1489
+ redeemer_index: Number(legacyRedeemer.index()),
1490
+ redeemer_tag: redeemerTagToString(legacyRedeemer.tag())
1491
+ });
1492
+ }
1493
+ return evalRedeemers;
1494
+ }
1495
+ const mapRedeemerKeyToRedeemerVal = redeemers.as_map_redeemer_key_to_redeemer_val();
1496
+ if (mapRedeemerKeyToRedeemerVal) {
1497
+ const keys = mapRedeemerKeyToRedeemerVal.keys();
1498
+ for (let i = 0; i < keys.len(); i++) {
1499
+ const key = keys.get(i);
1500
+ const redeemerVal = mapRedeemerKeyToRedeemerVal.get(key);
1501
+ if (redeemerVal) {
1502
+ evalRedeemers.push({
1503
+ ex_units: {
1504
+ mem: Number(redeemerVal.ex_units().mem()),
1505
+ steps: Number(redeemerVal.ex_units().steps())
1506
+ },
1507
+ redeemer_index: Number(key.index),
1508
+ redeemer_tag: redeemerTagToString(key.tag())
1509
+ });
1510
+ }
1511
+ }
1512
+ return evalRedeemers;
1513
+ }
1514
+ return evalRedeemers;
1515
+ }
1343
1516
  log() {
1344
1517
  function getRandomColor(unit) {
1345
1518
  const seed = unit === "lovelace" ? "1" : unit;
@@ -1406,6 +1579,24 @@ ${"\u2581".repeat(60)}
1406
1579
  }
1407
1580
  }
1408
1581
  };
1582
+ function redeemerTagToString(tag) {
1583
+ switch (tag) {
1584
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Spend:
1585
+ return "spend";
1586
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Mint:
1587
+ return "mint";
1588
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Cert:
1589
+ return "cert";
1590
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Reward:
1591
+ return "reward";
1592
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Voting:
1593
+ return "voting";
1594
+ case import_cardano_multiplatform_lib_nodejs.RedeemerTag.Proposing:
1595
+ return "proposing";
1596
+ default:
1597
+ return "unknown";
1598
+ }
1599
+ }
1409
1600
 
1410
1601
  // src/maestro.ts
1411
1602
  var import_utils5 = require("@lucid-evolution/utils");
@@ -1667,6 +1858,33 @@ var Maestro = class {
1667
1858
  }
1668
1859
  return result;
1669
1860
  }
1861
+ async evaluateTx(tx, additionalUTxOs) {
1862
+ const additionalMaestroUTxOs = (additionalUTxOs || []).map((utxo) => ({
1863
+ index: utxo.outputIndex,
1864
+ tx_hash: utxo.txHash,
1865
+ tx_cbor: (0, import_utils5.utxoToCore)(utxo).to_cbor_hex
1866
+ }));
1867
+ const payload = {
1868
+ cbor: tx,
1869
+ additionalMaestroUTxOs
1870
+ };
1871
+ const res = await fetch(`${this.url}/transactions/evaluate`, {
1872
+ method: "POST",
1873
+ headers: {
1874
+ "Content-Type": "application/json",
1875
+ Accept: "application/json",
1876
+ "api-key": this.apiKey
1877
+ },
1878
+ body: JSON.stringify(payload)
1879
+ });
1880
+ if (!res.ok) {
1881
+ const body = await res.text();
1882
+ console.error("Response error:", JSON.stringify(res));
1883
+ throw new Error(`Evaluate transaction failed: ${body}`);
1884
+ }
1885
+ const result = await res.json();
1886
+ return result;
1887
+ }
1670
1888
  };
1671
1889
  var lucid2 = package_default.version;
1672
1890
 
@@ -2132,6 +2350,62 @@ var Koios = class {
2132
2350
  }
2133
2351
  return result;
2134
2352
  }
2353
+ async evaluateTx(tx, additionalUTxOs) {
2354
+ const utxos = (additionalUTxOs || []).map((utxo) => {
2355
+ const script = utxo.scriptRef ? {
2356
+ language: utxo.scriptRef.type,
2357
+ cbor: utxo.scriptRef.script
2358
+ } : void 0;
2359
+ return [
2360
+ {
2361
+ transaction: { id: utxo.txHash, output: { index: utxo.outputIndex } }
2362
+ },
2363
+ {
2364
+ address: utxo.address,
2365
+ value: {
2366
+ coins: utxo.assets.lovelace,
2367
+ assets: utxo.assets.restAssets
2368
+ },
2369
+ datumHash: utxo.datumHash,
2370
+ datum: utxo.datum,
2371
+ script
2372
+ }
2373
+ ];
2374
+ });
2375
+ const data = {
2376
+ jsonrpc: "2.0",
2377
+ method: "evaluateTransaction",
2378
+ params: { transaction: { cbor: tx }, additionalUTxO: utxos },
2379
+ id: null
2380
+ };
2381
+ const response = await fetch(`${this.baseUrl}/ogmios`, {
2382
+ headers: {
2383
+ Accept: "application/json",
2384
+ "Content-Type": "application/json"
2385
+ },
2386
+ method: "POST",
2387
+ body: JSON.stringify(
2388
+ data,
2389
+ (_, value) => typeof value === "bigint" ? value.toString() : value
2390
+ )
2391
+ });
2392
+ if (!response.ok) {
2393
+ const errorBody = await response.text();
2394
+ throw new Error(
2395
+ `Request failed with status ${response.status}: ${errorBody}`
2396
+ );
2397
+ }
2398
+ const result = await response.json();
2399
+ const evalRedeemers = result.result.map((item) => ({
2400
+ ex_units: {
2401
+ mem: item.budget.memory,
2402
+ steps: item.budget.cpu
2403
+ },
2404
+ redeemer_index: item.validator.index,
2405
+ redeemer_tag: item.validator.purpose
2406
+ }));
2407
+ return evalRedeemers;
2408
+ }
2135
2409
  };
2136
2410
  var toUTxO = (koiosUTxO, address) => ({
2137
2411
  txHash: koiosUTxO.tx_hash,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Provider, ProtocolParameters, Address, Credential, UTxO, Unit, OutRef, RewardAddress, Delegation, DatumHash, Datum, TxHash, Transaction, Assets, OutputData, UnixTime, Lovelace } from '@lucid-evolution/core-types';
1
+ import { Provider, ProtocolParameters, Address, Credential, UTxO, Unit, OutRef, RewardAddress, Delegation, DatumHash, Datum, TxHash, Transaction, EvalRedeemer, Assets, OutputData, UnixTime, Lovelace } from '@lucid-evolution/core-types';
2
2
  import * as effect_Cause from 'effect/Cause';
3
3
  import * as effect_Types from 'effect/Types';
4
4
  import { Effect } from 'effect';
@@ -17,6 +17,7 @@ declare class Blockfrost implements Provider {
17
17
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
18
18
  submitTx(tx: Transaction): Promise<TxHash>;
19
19
  private blockfrostUtxosToUtxos;
20
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
20
21
  }
21
22
  /**
22
23
  * This function is temporarily needed only, until Blockfrost returns the datum natively in Cbor.
@@ -60,6 +61,7 @@ declare class Kupmios implements Provider {
60
61
  getDatum(datumHash: DatumHash): Promise<Datum>;
61
62
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
62
63
  submitTx(cbor: Transaction): Promise<TxHash>;
64
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
63
65
  }
64
66
 
65
67
  /** Concatentation of txHash + outputIndex */
@@ -111,6 +113,7 @@ declare class Emulator implements Provider {
111
113
  */
112
114
  distributeRewards(rewards: Lovelace): void;
113
115
  submitTx(tx: Transaction): Promise<TxHash>;
116
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
114
117
  log(): void;
115
118
  }
116
119
 
@@ -139,6 +142,7 @@ declare class Maestro implements Provider {
139
142
  private requireAmountsAsStrings;
140
143
  private maestroUtxoToUtxo;
141
144
  private getAllPagesData;
145
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
142
146
  }
143
147
 
144
148
  /**
@@ -156,6 +160,7 @@ declare class Koios implements Provider {
156
160
  getDatum(datumHash: DatumHash): Promise<Datum>;
157
161
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
158
162
  submitTx(tx: Transaction): Promise<TxHash>;
163
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
159
164
  }
160
165
 
161
166
  declare const FetchError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Provider, ProtocolParameters, Address, Credential, UTxO, Unit, OutRef, RewardAddress, Delegation, DatumHash, Datum, TxHash, Transaction, Assets, OutputData, UnixTime, Lovelace } from '@lucid-evolution/core-types';
1
+ import { Provider, ProtocolParameters, Address, Credential, UTxO, Unit, OutRef, RewardAddress, Delegation, DatumHash, Datum, TxHash, Transaction, EvalRedeemer, Assets, OutputData, UnixTime, Lovelace } from '@lucid-evolution/core-types';
2
2
  import * as effect_Cause from 'effect/Cause';
3
3
  import * as effect_Types from 'effect/Types';
4
4
  import { Effect } from 'effect';
@@ -17,6 +17,7 @@ declare class Blockfrost implements Provider {
17
17
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
18
18
  submitTx(tx: Transaction): Promise<TxHash>;
19
19
  private blockfrostUtxosToUtxos;
20
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
20
21
  }
21
22
  /**
22
23
  * This function is temporarily needed only, until Blockfrost returns the datum natively in Cbor.
@@ -60,6 +61,7 @@ declare class Kupmios implements Provider {
60
61
  getDatum(datumHash: DatumHash): Promise<Datum>;
61
62
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
62
63
  submitTx(cbor: Transaction): Promise<TxHash>;
64
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
63
65
  }
64
66
 
65
67
  /** Concatentation of txHash + outputIndex */
@@ -111,6 +113,7 @@ declare class Emulator implements Provider {
111
113
  */
112
114
  distributeRewards(rewards: Lovelace): void;
113
115
  submitTx(tx: Transaction): Promise<TxHash>;
116
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
114
117
  log(): void;
115
118
  }
116
119
 
@@ -139,6 +142,7 @@ declare class Maestro implements Provider {
139
142
  private requireAmountsAsStrings;
140
143
  private maestroUtxoToUtxo;
141
144
  private getAllPagesData;
145
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
142
146
  }
143
147
 
144
148
  /**
@@ -156,6 +160,7 @@ declare class Koios implements Provider {
156
160
  getDatum(datumHash: DatumHash): Promise<Datum>;
157
161
  awaitTx(txHash: TxHash, checkInterval?: number): Promise<boolean>;
158
162
  submitTx(tx: Transaction): Promise<TxHash>;
163
+ evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
159
164
  }
160
165
 
161
166
  declare const FetchError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
package/dist/index.js CHANGED
@@ -8,13 +8,13 @@ var __export = (target, all) => {
8
8
  import * as CML from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
9
9
 
10
10
  // src/blockfrost.ts
11
- import { fromHex } from "@lucid-evolution/core-utils";
11
+ import { fromHex, sleep } from "@lucid-evolution/core-utils";
12
12
  import { applyDoubleCborEncoding } from "@lucid-evolution/utils";
13
13
 
14
14
  // package.json
15
15
  var package_default = {
16
16
  name: "@lucid-evolution/provider",
17
- version: "0.1.40",
17
+ version: "0.1.42",
18
18
  description: "",
19
19
  main: "./dist/index.js",
20
20
  types: "./dist/index.d.ts",
@@ -246,37 +246,99 @@ var Blockfrost = class {
246
246
  return result;
247
247
  }
248
248
  async blockfrostUtxosToUtxos(result) {
249
- return await Promise.all(
250
- result.map(async (r) => ({
251
- txHash: r.tx_hash,
252
- outputIndex: r.output_index,
253
- assets: Object.fromEntries(
254
- r.amount.map(({ unit, quantity }) => [unit, BigInt(quantity)])
255
- ),
256
- address: r.address,
257
- datumHash: !r.inline_datum && r.data_hash || void 0,
258
- datum: r.inline_datum || void 0,
259
- scriptRef: r.reference_script_hash ? await (async () => {
260
- const { type } = await fetch(
261
- `${this.url}/scripts/${r.reference_script_hash}`,
262
- {
263
- headers: { project_id: this.projectId, lucid }
264
- }
265
- ).then((res) => res.json());
266
- if (type === "Native" || type === "native") {
267
- throw new Error("Native script ref not implemented!");
268
- }
269
- const { cbor: script } = await fetch(
270
- `${this.url}/scripts/${r.reference_script_hash}/cbor`,
271
- { headers: { project_id: this.projectId, lucid } }
272
- ).then((res) => res.json());
249
+ const utxos = [];
250
+ const batchSize = 10;
251
+ let count = 0;
252
+ for (let i = 0; i < result.length; i += batchSize) {
253
+ const batch = result.slice(i, i + batchSize);
254
+ count += batchSize;
255
+ await handleRateLimit(count);
256
+ const batchResults = await Promise.all(
257
+ batch.map(async (r) => {
273
258
  return {
274
- type: type === "plutusV1" ? "PlutusV1" : "PlutusV2",
275
- script: applyDoubleCborEncoding(script)
259
+ txHash: r.tx_hash,
260
+ outputIndex: r.output_index,
261
+ assets: Object.fromEntries(
262
+ r.amount.map(({ unit, quantity }) => [unit, BigInt(quantity)])
263
+ ),
264
+ address: r.address,
265
+ datumHash: !r.inline_datum && r.data_hash || void 0,
266
+ datum: r.inline_datum || void 0,
267
+ scriptRef: r.reference_script_hash ? await (async () => {
268
+ const { type } = await fetch(
269
+ `${this.url}/scripts/${r.reference_script_hash}`,
270
+ {
271
+ headers: { project_id: this.projectId, lucid }
272
+ }
273
+ ).then((res) => res.json());
274
+ if (type.toLowerCase() === "native") {
275
+ throw new Error("Native script ref not implemented!");
276
+ }
277
+ const { cbor: script } = await fetch(
278
+ `${this.url}/scripts/${r.reference_script_hash}/cbor`,
279
+ { headers: { project_id: this.projectId, lucid } }
280
+ ).then((res) => res.json());
281
+ return {
282
+ type: type === "plutusV1" ? "PlutusV1" : "PlutusV2",
283
+ script: applyDoubleCborEncoding(script)
284
+ };
285
+ })() : void 0
276
286
  };
277
- })() : void 0
278
- }))
287
+ })
288
+ );
289
+ utxos.push(...batchResults);
290
+ }
291
+ return utxos;
292
+ }
293
+ async evaluateTx(tx, additionalUTxOs) {
294
+ const additionalUTxOSet = (additionalUTxOs || []).map((utxo) => [
295
+ { txId: utxo.txHash, index: utxo.outputIndex },
296
+ {
297
+ address: utxo.address,
298
+ value: { coins: utxo.assets.lovelace, assets: utxo.assets.restAssets },
299
+ datum_hash: utxo.datumHash,
300
+ datum: utxo.datum,
301
+ script: utxo.scriptRef
302
+ }
303
+ ]);
304
+ const payload = {
305
+ cbor: tx,
306
+ additionalUTxOSet
307
+ };
308
+ const res = await fetch(`${this.url}/utils/txs/evaluate/utxos`, {
309
+ method: "POST",
310
+ headers: {
311
+ "Content-Type": "application/json",
312
+ project_id: this.projectId,
313
+ lucid
314
+ },
315
+ body: JSON.stringify(
316
+ payload,
317
+ (_, value) => typeof value === "bigint" ? value.toString() : value
318
+ )
319
+ }).then((res2) => res2.json());
320
+ if (!res || res.error) {
321
+ const message = res?.status_code === 400 ? res.message : `Could not evaluate the transaction: ${JSON.stringify(res)}`;
322
+ throw new Error(message);
323
+ }
324
+ const blockfrostRedeemer = res;
325
+ if (!("EvaluationResult" in blockfrostRedeemer.result)) {
326
+ throw new Error(
327
+ `EvaluateTransaction fails: ${JSON.stringify(blockfrostRedeemer.result)}`
328
+ );
329
+ }
330
+ const evalRedeemers = [];
331
+ Object.entries(blockfrostRedeemer.result.EvaluationResult).forEach(
332
+ ([redeemerPointer, data]) => {
333
+ const [pTag, pIndex] = redeemerPointer.split(":");
334
+ evalRedeemers.push({
335
+ redeemer_tag: pTag,
336
+ redeemer_index: Number(pIndex),
337
+ ex_units: { mem: Number(data.memory), steps: Number(data.steps) }
338
+ });
339
+ }
279
340
  );
341
+ return evalRedeemers;
280
342
  }
281
343
  };
282
344
  function datumJsonToCbor(json) {
@@ -315,6 +377,13 @@ function datumJsonToCbor(json) {
315
377
  };
316
378
  return convert(json).to_cbor_hex();
317
379
  }
380
+ var handleRateLimit = async (count) => {
381
+ if (count % 100 === 0) {
382
+ await sleep(2e3);
383
+ } else if (count % 10 === 0) {
384
+ await sleep(200);
385
+ }
386
+ };
318
387
  var lucid = package_default.version;
319
388
 
320
389
  // src/kupmios/kupmios.ts
@@ -593,6 +662,66 @@ var Kupmios = class {
593
662
  const { result } = await Effect.runPromise(program);
594
663
  return result.transaction.id;
595
664
  }
665
+ async evaluateTx(tx, additionalUTxOs) {
666
+ const utxos = (additionalUTxOs || []).map((utxo) => {
667
+ const script = utxo.scriptRef ? {
668
+ language: utxo.scriptRef.type,
669
+ cbor: utxo.scriptRef.script
670
+ } : void 0;
671
+ return [
672
+ {
673
+ transaction: { id: utxo.txHash, output: { index: utxo.outputIndex } }
674
+ },
675
+ {
676
+ address: utxo.address,
677
+ value: {
678
+ coins: utxo.assets.lovelace,
679
+ assets: utxo.assets.restAssets
680
+ },
681
+ datumHash: utxo.datumHash,
682
+ datum: utxo.datum,
683
+ script
684
+ }
685
+ ];
686
+ });
687
+ const data = {
688
+ jsonrpc: "2.0",
689
+ method: "evaluateTransaction",
690
+ params: { transaction: { cbor: tx }, additionalUTxO: utxos },
691
+ id: null
692
+ };
693
+ const schema = JSONRPCSchema(
694
+ S2.Array(
695
+ S2.Struct({
696
+ validator: S2.Struct({
697
+ purpose: S2.String,
698
+ index: S2.Int
699
+ }),
700
+ budget: S2.Struct({
701
+ memory: S2.Int,
702
+ cpu: S2.Int
703
+ })
704
+ })
705
+ )
706
+ );
707
+ const program = fetchOgmiosParse(this.ogmiosUrl, data, schema).pipe(
708
+ Effect.flatMap(
709
+ (response) => "error" in response ? kupmiosError(response.error) : Effect.succeed(response.result)
710
+ ),
711
+ Effect.timeout(1e4),
712
+ Effect.catchAll(kupmiosError)
713
+ );
714
+ const result = await Effect.runPromise(program);
715
+ const evalRedeemers = result.map((item) => ({
716
+ ex_units: {
717
+ mem: item.budget.memory,
718
+ steps: item.budget.cpu
719
+ },
720
+ redeemer_index: item.validator.index,
721
+ redeemer_tag: item.validator.purpose
722
+ }));
723
+ return evalRedeemers;
724
+ }
596
725
  };
597
726
  var getDatumEffect = (kupoUrl, datum_type, datum_hash) => Effect.gen(function* () {
598
727
  if (datum_type === "inline" && datum_hash) {
@@ -722,6 +851,7 @@ import {
722
851
  import { coreToUtxo, getAddressDetails } from "@lucid-evolution/utils";
723
852
  import { fromHex as fromHex2 } from "@lucid-evolution/core-utils";
724
853
  import { walletFromSeed } from "@lucid-evolution/wallet";
854
+ import { RedeemerTag } from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
725
855
  function generateEmulatorAccount(assets) {
726
856
  const seedPhrase = generateSeedPhrase();
727
857
  return {
@@ -1309,6 +1439,49 @@ It does not exist or was already spent.`
1309
1439
  }
1310
1440
  return Promise.resolve(txHash);
1311
1441
  }
1442
+ async evaluateTx(tx, additionalUTxOs) {
1443
+ const desTx = CML.Transaction.from_cbor_hex(tx);
1444
+ const redeemers = desTx.witness_set().redeemers();
1445
+ if (!redeemers) {
1446
+ return [];
1447
+ }
1448
+ let evalRedeemers = [];
1449
+ const arrLegacyRedeemer = redeemers.as_arr_legacy_redeemer();
1450
+ if (arrLegacyRedeemer) {
1451
+ for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
1452
+ const legacyRedeemer = arrLegacyRedeemer.get(i);
1453
+ evalRedeemers.push({
1454
+ ex_units: {
1455
+ mem: Number(legacyRedeemer.ex_units().mem()),
1456
+ steps: Number(legacyRedeemer.ex_units().steps())
1457
+ },
1458
+ redeemer_index: Number(legacyRedeemer.index()),
1459
+ redeemer_tag: redeemerTagToString(legacyRedeemer.tag())
1460
+ });
1461
+ }
1462
+ return evalRedeemers;
1463
+ }
1464
+ const mapRedeemerKeyToRedeemerVal = redeemers.as_map_redeemer_key_to_redeemer_val();
1465
+ if (mapRedeemerKeyToRedeemerVal) {
1466
+ const keys = mapRedeemerKeyToRedeemerVal.keys();
1467
+ for (let i = 0; i < keys.len(); i++) {
1468
+ const key = keys.get(i);
1469
+ const redeemerVal = mapRedeemerKeyToRedeemerVal.get(key);
1470
+ if (redeemerVal) {
1471
+ evalRedeemers.push({
1472
+ ex_units: {
1473
+ mem: Number(redeemerVal.ex_units().mem()),
1474
+ steps: Number(redeemerVal.ex_units().steps())
1475
+ },
1476
+ redeemer_index: Number(key.index),
1477
+ redeemer_tag: redeemerTagToString(key.tag())
1478
+ });
1479
+ }
1480
+ }
1481
+ return evalRedeemers;
1482
+ }
1483
+ return evalRedeemers;
1484
+ }
1312
1485
  log() {
1313
1486
  function getRandomColor(unit) {
1314
1487
  const seed = unit === "lovelace" ? "1" : unit;
@@ -1375,9 +1548,27 @@ ${"\u2581".repeat(60)}
1375
1548
  }
1376
1549
  }
1377
1550
  };
1551
+ function redeemerTagToString(tag) {
1552
+ switch (tag) {
1553
+ case RedeemerTag.Spend:
1554
+ return "spend";
1555
+ case RedeemerTag.Mint:
1556
+ return "mint";
1557
+ case RedeemerTag.Cert:
1558
+ return "cert";
1559
+ case RedeemerTag.Reward:
1560
+ return "reward";
1561
+ case RedeemerTag.Voting:
1562
+ return "voting";
1563
+ case RedeemerTag.Proposing:
1564
+ return "proposing";
1565
+ default:
1566
+ return "unknown";
1567
+ }
1568
+ }
1378
1569
 
1379
1570
  // src/maestro.ts
1380
- import { applyDoubleCborEncoding as applyDoubleCborEncoding2 } from "@lucid-evolution/utils";
1571
+ import { applyDoubleCborEncoding as applyDoubleCborEncoding2, utxoToCore } from "@lucid-evolution/utils";
1381
1572
  import { fromHex as fromHex3 } from "@lucid-evolution/core-utils";
1382
1573
  var Maestro = class {
1383
1574
  url;
@@ -1636,6 +1827,33 @@ var Maestro = class {
1636
1827
  }
1637
1828
  return result;
1638
1829
  }
1830
+ async evaluateTx(tx, additionalUTxOs) {
1831
+ const additionalMaestroUTxOs = (additionalUTxOs || []).map((utxo) => ({
1832
+ index: utxo.outputIndex,
1833
+ tx_hash: utxo.txHash,
1834
+ tx_cbor: utxoToCore(utxo).to_cbor_hex
1835
+ }));
1836
+ const payload = {
1837
+ cbor: tx,
1838
+ additionalMaestroUTxOs
1839
+ };
1840
+ const res = await fetch(`${this.url}/transactions/evaluate`, {
1841
+ method: "POST",
1842
+ headers: {
1843
+ "Content-Type": "application/json",
1844
+ Accept: "application/json",
1845
+ "api-key": this.apiKey
1846
+ },
1847
+ body: JSON.stringify(payload)
1848
+ });
1849
+ if (!res.ok) {
1850
+ const body = await res.text();
1851
+ console.error("Response error:", JSON.stringify(res));
1852
+ throw new Error(`Evaluate transaction failed: ${body}`);
1853
+ }
1854
+ const result = await res.json();
1855
+ return result;
1856
+ }
1639
1857
  };
1640
1858
  var lucid2 = package_default.version;
1641
1859
 
@@ -2101,6 +2319,62 @@ var Koios = class {
2101
2319
  }
2102
2320
  return result;
2103
2321
  }
2322
+ async evaluateTx(tx, additionalUTxOs) {
2323
+ const utxos = (additionalUTxOs || []).map((utxo) => {
2324
+ const script = utxo.scriptRef ? {
2325
+ language: utxo.scriptRef.type,
2326
+ cbor: utxo.scriptRef.script
2327
+ } : void 0;
2328
+ return [
2329
+ {
2330
+ transaction: { id: utxo.txHash, output: { index: utxo.outputIndex } }
2331
+ },
2332
+ {
2333
+ address: utxo.address,
2334
+ value: {
2335
+ coins: utxo.assets.lovelace,
2336
+ assets: utxo.assets.restAssets
2337
+ },
2338
+ datumHash: utxo.datumHash,
2339
+ datum: utxo.datum,
2340
+ script
2341
+ }
2342
+ ];
2343
+ });
2344
+ const data = {
2345
+ jsonrpc: "2.0",
2346
+ method: "evaluateTransaction",
2347
+ params: { transaction: { cbor: tx }, additionalUTxO: utxos },
2348
+ id: null
2349
+ };
2350
+ const response = await fetch(`${this.baseUrl}/ogmios`, {
2351
+ headers: {
2352
+ Accept: "application/json",
2353
+ "Content-Type": "application/json"
2354
+ },
2355
+ method: "POST",
2356
+ body: JSON.stringify(
2357
+ data,
2358
+ (_, value) => typeof value === "bigint" ? value.toString() : value
2359
+ )
2360
+ });
2361
+ if (!response.ok) {
2362
+ const errorBody = await response.text();
2363
+ throw new Error(
2364
+ `Request failed with status ${response.status}: ${errorBody}`
2365
+ );
2366
+ }
2367
+ const result = await response.json();
2368
+ const evalRedeemers = result.result.map((item) => ({
2369
+ ex_units: {
2370
+ mem: item.budget.memory,
2371
+ steps: item.budget.cpu
2372
+ },
2373
+ redeemer_index: item.validator.index,
2374
+ redeemer_tag: item.validator.purpose
2375
+ }));
2376
+ return evalRedeemers;
2377
+ }
2104
2378
  };
2105
2379
  var toUTxO = (koiosUTxO, address) => ({
2106
2380
  txHash: koiosUTxO.tx_hash,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucid-evolution/provider",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -30,10 +30,10 @@
30
30
  "@effect/platform": "^0.59.2",
31
31
  "@effect/schema": "^0.68.26",
32
32
  "effect": "^3.5.6",
33
- "@lucid-evolution/core-types": "0.1.12",
34
- "@lucid-evolution/core-utils": "0.1.11",
35
- "@lucid-evolution/utils": "0.1.31",
36
- "@lucid-evolution/wallet": "0.1.35"
33
+ "@lucid-evolution/core-types": "0.1.13",
34
+ "@lucid-evolution/core-utils": "0.1.13",
35
+ "@lucid-evolution/utils": "0.1.33",
36
+ "@lucid-evolution/wallet": "0.1.37"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^20.12.8",