@lucid-evolution/provider 0.2.2 → 0.2.4

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
@@ -144,7 +144,7 @@ var import_utils2 = require("@lucid-evolution/utils");
144
144
  // package.json
145
145
  var package_default = {
146
146
  name: "@lucid-evolution/provider",
147
- version: "0.2.2",
147
+ version: "0.2.4",
148
148
  description: "",
149
149
  main: "./dist/index.js",
150
150
  types: "./dist/index.d.ts",
@@ -247,6 +247,7 @@ var fromLegacyRedeemerTag = (redeemerTag) => {
247
247
  };
248
248
 
249
249
  // src/blockfrost.ts
250
+ var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
250
251
  var toBlockfrostQueryPredicate = (addressOrCredential) => {
251
252
  if (typeof addressOrCredential === "string") return addressOrCredential;
252
253
  if (addressOrCredential.type === "Key") {
@@ -259,12 +260,24 @@ var toBlockfrostQueryPredicate = (addressOrCredential) => {
259
260
  var Blockfrost = class {
260
261
  url;
261
262
  projectId;
262
- constructor(url, projectId) {
263
+ requestTimeoutMs;
264
+ constructor(url, projectId, options = {}) {
263
265
  this.url = url;
264
266
  this.projectId = projectId || "";
267
+ const timeout = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
268
+ if (!Number.isFinite(timeout) || timeout <= 0) {
269
+ throw new TypeError("requestTimeoutMs must be a positive finite number.");
270
+ }
271
+ this.requestTimeoutMs = timeout;
272
+ }
273
+ /** `fetch` bounded by the provider's request timeout, combined with any caller-supplied signal. */
274
+ fetch(input, init = {}) {
275
+ const timeout = AbortSignal.timeout(this.requestTimeoutMs);
276
+ const signal = init.signal == null ? timeout : typeof AbortSignal.any === "function" ? AbortSignal.any([init.signal, timeout]) : init.signal;
277
+ return fetch(input, { ...init, signal });
265
278
  }
266
279
  async getProtocolParameters() {
267
- const result = await fetch(`${this.url}/epochs/latest/parameters`, {
280
+ const result = await this.fetch(`${this.url}/epochs/latest/parameters`, {
268
281
  headers: { project_id: this.projectId, lucid }
269
282
  }).then((res) => res.json());
270
283
  return {
@@ -292,7 +305,7 @@ var Blockfrost = class {
292
305
  };
293
306
  }
294
307
  async getTreasury() {
295
- const result = await fetch(`${this.url}/network`, {
308
+ const result = await this.fetch(`${this.url}/network`, {
296
309
  headers: { project_id: this.projectId, lucid }
297
310
  }).then((res) => res.json());
298
311
  if (!result || result.error || result.supply?.treasury === void 0) {
@@ -305,7 +318,7 @@ var Blockfrost = class {
305
318
  let result = [];
306
319
  let page = 1;
307
320
  while (true) {
308
- const pageResult = await fetch(
321
+ const pageResult = await this.fetch(
309
322
  `${this.url}/addresses/${queryPredicate}/utxos?page=${page}`,
310
323
  { headers: { project_id: this.projectId, lucid } }
311
324
  ).then((res) => res.json());
@@ -327,7 +340,7 @@ var Blockfrost = class {
327
340
  let result = [];
328
341
  let page = 1;
329
342
  while (true) {
330
- const pageResult = await fetch(
343
+ const pageResult = await this.fetch(
331
344
  `${this.url}/addresses/${queryPredicate}/utxos/${unit}?page=${page}`,
332
345
  { headers: { project_id: this.projectId, lucid } }
333
346
  ).then((res) => res.json());
@@ -345,7 +358,7 @@ var Blockfrost = class {
345
358
  return this.blockfrostUtxosToUtxos(result);
346
359
  }
347
360
  async getUtxoByUnit(unit) {
348
- const addresses = await fetch(
361
+ const addresses = await this.fetch(
349
362
  `${this.url}/assets/${unit}/addresses?count=2`,
350
363
  { headers: { project_id: this.projectId, lucid } }
351
364
  ).then((res) => res.json());
@@ -366,7 +379,7 @@ var Blockfrost = class {
366
379
  const queryHashes = [...new Set(outRefs.map((outRef) => outRef.txHash))];
367
380
  const utxos = await Promise.all(
368
381
  queryHashes.map(async (txHash) => {
369
- const result = await fetch(`${this.url}/txs/${txHash}/utxos`, {
382
+ const result = await this.fetch(`${this.url}/txs/${txHash}/utxos`, {
370
383
  headers: { project_id: this.projectId, lucid }
371
384
  }).then((res) => res.json());
372
385
  if (!result || result.error) {
@@ -388,7 +401,7 @@ var Blockfrost = class {
388
401
  );
389
402
  }
390
403
  async getRewardAccount(rewardAddress) {
391
- const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
404
+ const response = await this.fetch(`${this.url}/accounts/${rewardAddress}`, {
392
405
  headers: { project_id: this.projectId, lucid }
393
406
  });
394
407
  if (response.status === 404) {
@@ -411,9 +424,12 @@ var Blockfrost = class {
411
424
  return { poolId, rewards };
412
425
  }
413
426
  async getDatum(datumHash) {
414
- const datum = await fetch(`${this.url}/scripts/datum/${datumHash}/cbor`, {
415
- headers: { project_id: this.projectId, lucid }
416
- }).then((res) => res.json()).then((res) => res.cbor);
427
+ const datum = await this.fetch(
428
+ `${this.url}/scripts/datum/${datumHash}/cbor`,
429
+ {
430
+ headers: { project_id: this.projectId, lucid }
431
+ }
432
+ ).then((res) => res.json()).then((res) => res.cbor);
417
433
  if (!datum || datum.error) {
418
434
  throw new Error(`No datum found for datum hash: ${datumHash}`);
419
435
  }
@@ -422,7 +438,7 @@ var Blockfrost = class {
422
438
  awaitTx(txHash, checkInterval = 3e3) {
423
439
  return new Promise((res) => {
424
440
  const confirmation = setInterval(async () => {
425
- const isConfirmed = await fetch(`${this.url}/txs/${txHash}/cbor`, {
441
+ const isConfirmed = await this.fetch(`${this.url}/txs/${txHash}/cbor`, {
426
442
  headers: { project_id: this.projectId, lucid }
427
443
  }).then((res2) => res2.json());
428
444
  if (isConfirmed && !isConfirmed.error) {
@@ -434,7 +450,7 @@ var Blockfrost = class {
434
450
  });
435
451
  }
436
452
  async getTransactionStatus(txHash, options = {}) {
437
- const response = await fetch(`${this.url}/txs/${txHash}`, {
453
+ const response = await this.fetch(`${this.url}/txs/${txHash}`, {
438
454
  headers: { project_id: this.projectId, lucid },
439
455
  signal: options.signal
440
456
  });
@@ -457,7 +473,7 @@ var Blockfrost = class {
457
473
  };
458
474
  }
459
475
  async submitTx(tx) {
460
- const result = await fetch(`${this.url}/tx/submit`, {
476
+ const result = await this.fetch(`${this.url}/tx/submit`, {
461
477
  method: "POST",
462
478
  headers: {
463
479
  "Content-Type": "application/cbor",
@@ -492,19 +508,19 @@ var Blockfrost = class {
492
508
  datumHash: !r.inline_datum && r.data_hash || void 0,
493
509
  datum: r.inline_datum || void 0,
494
510
  scriptRef: r.reference_script_hash ? await (async () => {
495
- const { type } = await fetch(
511
+ const { type } = await this.fetch(
496
512
  `${this.url}/scripts/${r.reference_script_hash}`,
497
513
  {
498
514
  headers: { project_id: this.projectId, lucid }
499
515
  }
500
516
  ).then((res) => res.json());
501
- const { cbor: script } = await fetch(
517
+ const { cbor: script } = await this.fetch(
502
518
  `${this.url}/scripts/${r.reference_script_hash}/cbor`,
503
519
  { headers: { project_id: this.projectId, lucid } }
504
520
  ).then((res) => res.json());
505
521
  switch (type) {
506
522
  case "timelock":
507
- const { json: native } = await fetch(
523
+ const { json: native } = await this.fetch(
508
524
  `${this.url}/scripts/${r.reference_script_hash}/json`,
509
525
  { headers: { project_id: this.projectId, lucid } }
510
526
  ).then((res) => res.json());
@@ -539,7 +555,7 @@ var Blockfrost = class {
539
555
  cbor: tx,
540
556
  ...utxos?.length ? { additionalUtxoSet: toAditionalUTXOs(utxos) } : {}
541
557
  };
542
- const res = await fetch(`${this.url}/utils/txs/evaluate/utxos`, {
558
+ const res = await this.fetch(`${this.url}/utils/txs/evaluate/utxos`, {
543
559
  method: "POST",
544
560
  headers: {
545
561
  "Content-Type": "application/json",
@@ -1019,7 +1035,7 @@ var makePostAsUint8Array = (url, data, schema, headers) => (0, import_effect4.pi
1019
1035
 
1020
1036
  // src/kupmios.ts
1021
1037
  var import_platform2 = require("@effect/platform");
1022
- var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
1038
+ var DEFAULT_REQUEST_TIMEOUT_MS2 = 3e4;
1023
1039
  var DEFAULT_AWAIT_TX_TIMEOUT_MS = 16e4;
1024
1040
  var validateTimeout = (name, timeout) => {
1025
1041
  if (!Number.isFinite(timeout) || timeout <= 0) {
@@ -1057,7 +1073,7 @@ var Kupmios = class {
1057
1073
  this.options = options;
1058
1074
  this.requestTimeoutMs = validateTimeout(
1059
1075
  "requestTimeoutMs",
1060
- options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS
1076
+ options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS2
1061
1077
  );
1062
1078
  this.awaitTxTimeoutMs = validateTimeout(
1063
1079
  "awaitTxTimeoutMs",
@@ -1539,6 +1555,7 @@ function generateEmulatorAccount(assets) {
1539
1555
  privateKey: ""
1540
1556
  };
1541
1557
  }
1558
+ var DEFAULT_PROTOCOL_MAJOR_VERSION = 11;
1542
1559
  var Emulator = class {
1543
1560
  [EMULATOR_PROVIDER_BRAND] = true;
1544
1561
  ledger;
@@ -1793,78 +1810,94 @@ var Emulator = class {
1793
1810
  const datumTable = (() => {
1794
1811
  const table = {};
1795
1812
  for (let i = 0; i < (datums?.len() || 0); i++) {
1796
- const datum = datums.get(i);
1797
- const datumHash = CML.hash_plutus_data(datum).to_hex();
1798
- table[datumHash] = datum.to_cbor_hex();
1813
+ (0, import_core_utils2.withCMLScope)((own) => {
1814
+ const datum = own(datums.get(i));
1815
+ const datumHash = own(CML.hash_plutus_data(datum)).to_hex();
1816
+ table[datumHash] = datum.to_cbor_hex();
1817
+ });
1799
1818
  }
1800
1819
  return table;
1801
1820
  })();
1802
1821
  const consumedHashes = /* @__PURE__ */ new Set();
1803
- const keyHashes = (() => {
1822
+ const keyHashes = (0, import_core_utils2.withCMLScope)((own) => {
1804
1823
  const keyHashes2 = [];
1805
- for (let i = 0; i < (witnesses.vkeywitnesses()?.len() || 0); i++) {
1806
- const witness = witnesses.vkeywitnesses().get(i);
1807
- const publicKey = witness.vkey();
1808
- const keyHash = publicKey.hash().to_hex();
1809
- if (!publicKey.verify((0, import_core_utils2.fromHex)(txHash), witness.ed25519_signature())) {
1810
- throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1811
- }
1812
- keyHashes2.push(keyHash);
1824
+ const vkeyWitnesses = own(witnesses.vkeywitnesses());
1825
+ for (let i = 0; i < (vkeyWitnesses?.len() || 0); i++) {
1826
+ (0, import_core_utils2.withCMLScope)((own2) => {
1827
+ const witness = own2(vkeyWitnesses.get(i));
1828
+ const publicKey = own2(witness.vkey());
1829
+ const keyHash = own2(publicKey.hash()).to_hex();
1830
+ if (!publicKey.verify((0, import_core_utils2.fromHex)(txHash), own2(witness.ed25519_signature()))) {
1831
+ throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1832
+ }
1833
+ keyHashes2.push(keyHash);
1834
+ });
1813
1835
  }
1814
1836
  return keyHashes2;
1815
- })();
1837
+ });
1816
1838
  const edKeyHashes = CML.Ed25519KeyHashList.new();
1817
1839
  keyHashes.forEach(
1818
- (keyHash) => edKeyHashes.add(CML.Ed25519KeyHash.from_hex(keyHash))
1840
+ (keyHash) => (0, import_core_utils2.withCMLScope)(
1841
+ (own) => edKeyHashes.add(own(CML.Ed25519KeyHash.from_hex(keyHash)))
1842
+ )
1819
1843
  );
1820
- const nativeHashes = (() => {
1844
+ const nativeHashes = (0, import_core_utils2.withCMLScope)((own) => {
1821
1845
  const scriptHashes = [];
1822
- for (let i = 0; i < (witnesses.native_scripts()?.len() || 0); i++) {
1823
- const witness = witnesses.native_scripts().get(i);
1824
- const scriptHash = witness.hash().to_hex();
1825
- if (!witness.verify(
1826
- Number.isInteger(lowerBound) ? CML.BigInteger.from_str(lowerBound.toString()).to_js_value() : void 0,
1827
- Number.isInteger(upperBound) ? CML.BigInteger.from_str(upperBound.toString()).to_js_value() : void 0,
1828
- edKeyHashes
1829
- )) {
1830
- throw new Error(
1831
- `Invalid native script witness. Script hash: ${scriptHash}`
1832
- );
1833
- }
1834
- for (let i2 = 0; i2 < witness.get_required_signers().len(); i2++) {
1835
- const keyHash = witness.get_required_signers().get(i2).to_hex();
1836
- consumedHashes.add(keyHash);
1837
- }
1838
- scriptHashes.push(scriptHash);
1846
+ const nativeScripts = own(witnesses.native_scripts());
1847
+ for (let i = 0; i < (nativeScripts?.len() || 0); i++) {
1848
+ (0, import_core_utils2.withCMLScope)((own2) => {
1849
+ const witness = own2(nativeScripts.get(i));
1850
+ const scriptHash = own2(witness.hash()).to_hex();
1851
+ if (!witness.verify(
1852
+ Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
1853
+ Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
1854
+ edKeyHashes
1855
+ )) {
1856
+ throw new Error(
1857
+ `Invalid native script witness. Script hash: ${scriptHash}`
1858
+ );
1859
+ }
1860
+ const requiredSigners = own2(witness.get_required_signers());
1861
+ for (let j = 0; j < requiredSigners.len(); j++) {
1862
+ const keyHash = own2(requiredSigners.get(j)).to_hex();
1863
+ consumedHashes.add(keyHash);
1864
+ }
1865
+ scriptHashes.push(scriptHash);
1866
+ });
1839
1867
  }
1840
1868
  return scriptHashes;
1841
- })();
1869
+ });
1870
+ edKeyHashes.free();
1842
1871
  const nativeHashesOptional = {};
1843
1872
  const plutusHashesOptional = [];
1844
- const plutusHashes = (() => {
1873
+ const plutusV3Hashes = /* @__PURE__ */ new Set();
1874
+ const plutusHashes = (0, import_core_utils2.withCMLScope)((own) => {
1845
1875
  const scriptHashes = [];
1846
- for (let i = 0; i < (witnesses.plutus_v1_scripts()?.len() || 0); i++) {
1847
- const script = witnesses.plutus_v1_scripts().get(i);
1848
- const scriptHash = script.hash().to_hex();
1849
- scriptHashes.push(scriptHash);
1850
- }
1851
- for (let i = 0; i < (witnesses.plutus_v2_scripts()?.len() || 0); i++) {
1852
- const script = witnesses.plutus_v2_scripts().get(i);
1853
- const scriptHash = script.hash().to_hex();
1854
- scriptHashes.push(scriptHash);
1855
- }
1856
- for (let i = 0; i < (witnesses.plutus_v3_scripts()?.len() || 0); i++) {
1857
- const script = witnesses.plutus_v3_scripts().get(i);
1858
- const scriptHash = script.hash().to_hex();
1859
- scriptHashes.push(scriptHash);
1860
- }
1876
+ const collectHashes = (scripts, isPlutusV3 = false) => {
1877
+ own(scripts);
1878
+ for (let i = 0; i < (scripts?.len() || 0); i++) {
1879
+ (0, import_core_utils2.withCMLScope)((own2) => {
1880
+ const script = own2(scripts.get(i));
1881
+ const scriptHash = own2(script.hash()).to_hex();
1882
+ scriptHashes.push(scriptHash);
1883
+ if (isPlutusV3) plutusV3Hashes.add(scriptHash);
1884
+ });
1885
+ }
1886
+ };
1887
+ collectHashes(witnesses.plutus_v1_scripts());
1888
+ collectHashes(witnesses.plutus_v2_scripts());
1889
+ collectHashes(witnesses.plutus_v3_scripts(), true);
1861
1890
  return scriptHashes;
1862
- })();
1891
+ });
1863
1892
  const inputs = body.inputs();
1864
1893
  const resolvedInputs = [];
1894
+ const inputOutRefs = /* @__PURE__ */ new Set();
1865
1895
  for (let i = 0; i < inputs.len(); i++) {
1866
- const input = inputs.get(i);
1867
- const outRef = input.transaction_id().to_hex() + input.index().toString();
1896
+ const outRef = (0, import_core_utils2.withCMLScope)((own) => {
1897
+ const input = own(inputs.get(i));
1898
+ return own(input.transaction_id()).to_hex() + input.index().toString();
1899
+ });
1900
+ inputOutRefs.add(outRef);
1868
1901
  const entryLedger = this.ledger[outRef];
1869
1902
  const { entry, type } = !entryLedger ? { entry: this.mempool[outRef], type: "Mempool" } : { entry: entryLedger, type: "Ledger" };
1870
1903
  if (!entry || entry.spent) {
@@ -1904,7 +1937,9 @@ It does not exist or was already spent.`
1904
1937
  const script = CML.PlutusScript.from_v3(
1905
1938
  CML.PlutusV3Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1906
1939
  );
1907
- plutusHashesOptional.push(script.hash().to_hex());
1940
+ const scriptHash = script.hash().to_hex();
1941
+ plutusHashesOptional.push(scriptHash);
1942
+ plutusV3Hashes.add(scriptHash);
1908
1943
  break;
1909
1944
  }
1910
1945
  }
@@ -1912,9 +1947,14 @@ It does not exist or was already spent.`
1912
1947
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1913
1948
  resolvedInputs.push({ entry, type });
1914
1949
  }
1915
- for (let i = 0; i < (body.reference_inputs()?.len() || 0); i++) {
1916
- const input = body.reference_inputs().get(i);
1917
- const outRef = input.transaction_id().to_hex() + input.index().toString();
1950
+ inputs.free();
1951
+ const referenceInputs = body.reference_inputs();
1952
+ const nonDisjointRefInputs = [];
1953
+ for (let i = 0; i < (referenceInputs?.len() || 0); i++) {
1954
+ const outRef = (0, import_core_utils2.withCMLScope)((own) => {
1955
+ const input = own(referenceInputs.get(i));
1956
+ return own(input.transaction_id()).to_hex() + input.index().toString();
1957
+ });
1918
1958
  const entry = this.ledger[outRef] || this.mempool[outRef];
1919
1959
  if (!entry || entry.spent) {
1920
1960
  throw new Error(
@@ -1925,6 +1965,11 @@ It does not exist or was already spent.`
1925
1965
  It does not exist or was already spent.`
1926
1966
  );
1927
1967
  }
1968
+ if (inputOutRefs.has(outRef)) {
1969
+ nonDisjointRefInputs.push(
1970
+ `${entry.utxo.txHash}#${entry.utxo.outputIndex}`
1971
+ );
1972
+ }
1928
1973
  const scriptRef = entry.utxo.scriptRef;
1929
1974
  if (scriptRef) {
1930
1975
  switch (scriptRef.type) {
@@ -1953,13 +1998,16 @@ It does not exist or was already spent.`
1953
1998
  const script = CML.PlutusScript.from_v3(
1954
1999
  CML.PlutusV3Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1955
2000
  );
1956
- plutusHashesOptional.push(script.hash().to_hex());
2001
+ const scriptHash = script.hash().to_hex();
2002
+ plutusHashesOptional.push(scriptHash);
2003
+ plutusV3Hashes.add(scriptHash);
1957
2004
  break;
1958
2005
  }
1959
2006
  }
1960
2007
  }
1961
2008
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1962
2009
  }
2010
+ referenceInputs?.free();
1963
2011
  const redeemers = (() => {
1964
2012
  const tagMap = {
1965
2013
  0: "Spend",
@@ -2038,9 +2086,12 @@ It does not exist or was already spent.`
2038
2086
  }
2039
2087
  }
2040
2088
  }
2041
- for (let i = 0; i < (body.collateral_inputs()?.len() || 0); i++) {
2042
- const input = body.collateral_inputs().get(i);
2043
- const outRef = input.transaction_id().to_hex() + input.index().toString();
2089
+ const collateralInputs = body.collateral_inputs();
2090
+ for (let i = 0; i < (collateralInputs?.len() || 0); i++) {
2091
+ const outRef = (0, import_core_utils2.withCMLScope)((own) => {
2092
+ const input = own(collateralInputs.get(i));
2093
+ return own(input.transaction_id()).to_hex() + input.index().toString();
2094
+ });
2044
2095
  const entry = this.ledger[outRef] || this.mempool[outRef];
2045
2096
  if (!entry || entry.spent) {
2046
2097
  throw new Error(
@@ -2057,6 +2108,7 @@ It does not exist or was already spent.`
2057
2108
  }
2058
2109
  checkAndConsumeHash(paymentCredential, null, null);
2059
2110
  }
2111
+ collateralInputs?.free();
2060
2112
  for (let i = 0; i < (body.required_signers()?.len() || 0); i++) {
2061
2113
  const signer = body.required_signers().get(i);
2062
2114
  checkAndConsumeHash({ type: "Key", hash: signer.to_hex() }, null, null);
@@ -2322,16 +2374,21 @@ It does not exist or was already spent.`
2322
2374
  const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
2323
2375
  checkAndConsumeHash(paymentCredential, "Spend", index);
2324
2376
  });
2325
- const outputs = (() => {
2377
+ const outputs = (0, import_core_utils2.withCMLScope)((own) => {
2326
2378
  const collected = [];
2327
- for (let i = 0; i < body.outputs().len(); i++) {
2328
- const output = body.outputs().get(i);
2329
- const unspentOutput = CML.TransactionUnspentOutput.new(
2330
- CML.TransactionInput.new(
2331
- CML.TransactionHash.from_hex(txHash),
2332
- CML.BigInteger.from_str(i.toString()).to_js_value()
2333
- ),
2334
- output
2379
+ const bodyOutputs = own(body.outputs());
2380
+ for (let i = 0; i < bodyOutputs.len(); i++) {
2381
+ const output = own(bodyOutputs.get(i));
2382
+ const unspentOutput = own(
2383
+ CML.TransactionUnspentOutput.new(
2384
+ own(
2385
+ CML.TransactionInput.new(
2386
+ own(CML.TransactionHash.from_hex(txHash)),
2387
+ BigInt(i)
2388
+ )
2389
+ ),
2390
+ output
2391
+ )
2335
2392
  );
2336
2393
  const utxo = (0, import_utils6.coreToUtxo)(unspentOutput);
2337
2394
  if (utxo.datumHash) consumedHashes.add(utxo.datumHash);
@@ -2341,7 +2398,7 @@ It does not exist or was already spent.`
2341
2398
  });
2342
2399
  }
2343
2400
  return collected;
2344
- })();
2401
+ });
2345
2402
  const [extraKeyHash] = keyHashes.filter(
2346
2403
  (keyHash) => !consumedHashes.has(keyHash)
2347
2404
  );
@@ -2370,6 +2427,23 @@ It does not exist or was already spent.`
2370
2427
  if (extraDatumHash) {
2371
2428
  throw new Error(`Extraneous plutus data. Datum hash: ${extraDatumHash}`);
2372
2429
  }
2430
+ if (nonDisjointRefInputs.length > 0) {
2431
+ const protocolMajorVersion = this.protocolParameters.protocolMajorVersion ?? DEFAULT_PROTOCOL_MAJOR_VERSION;
2432
+ const overlap = nonDisjointRefInputs.join(", ");
2433
+ if (protocolMajorVersion === 9 || protocolMajorVersion === 10) {
2434
+ throw new Error(
2435
+ `BabbageNonDisjointRefInputs: reference inputs must be disjoint from inputs at protocol version ${protocolMajorVersion}. Overlapping: ${overlap}`
2436
+ );
2437
+ }
2438
+ const runsPlutusV3 = [...consumedHashes].some(
2439
+ (hash) => plutusV3Hashes.has(hash)
2440
+ );
2441
+ if (protocolMajorVersion >= 11 && runsPlutusV3) {
2442
+ throw new Error(
2443
+ `ReferenceInputsNotDisjointFromInputs: a PlutusV3 script context cannot be built while reference inputs overlap inputs. Overlapping: ${overlap}`
2444
+ );
2445
+ }
2446
+ }
2373
2447
  resolvedInputs.forEach(({ entry, type }) => {
2374
2448
  const outRef = entry.utxo.txHash + entry.utxo.outputIndex;
2375
2449
  entry.spent = true;
@@ -2415,50 +2489,57 @@ It does not exist or was already spent.`
2415
2489
  this.datumTable[datumHash] = datum;
2416
2490
  }
2417
2491
  this.transactionHistory[txHash] = { status: "pending" };
2492
+ (0, import_core_utils2.freeCML)(datums, witnesses, body, desTx);
2418
2493
  return Promise.resolve(txHash);
2419
2494
  }
2420
2495
  async evaluateTx(tx, additionalUTxOs) {
2421
- const desTx = CML.Transaction.from_cbor_hex(tx);
2422
- const redeemers = desTx.witness_set().redeemers();
2423
- if (!redeemers) {
2424
- return [];
2425
- }
2426
- let evalRedeemers = [];
2427
- const arrLegacyRedeemer = redeemers.as_arr_legacy_redeemer();
2428
- if (arrLegacyRedeemer) {
2429
- for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
2430
- const legacyRedeemer = arrLegacyRedeemer.get(i);
2431
- evalRedeemers.push({
2432
- ex_units: {
2433
- mem: Number(legacyRedeemer.ex_units().mem()),
2434
- steps: Number(legacyRedeemer.ex_units().steps())
2435
- },
2436
- redeemer_index: Number(legacyRedeemer.index()),
2437
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(legacyRedeemer.tag())
2438
- });
2496
+ return (0, import_core_utils2.withCMLScope)((own) => {
2497
+ const desTx = own(CML.Transaction.from_cbor_hex(tx));
2498
+ const redeemers = own(own(desTx.witness_set()).redeemers());
2499
+ if (!redeemers) {
2500
+ return [];
2439
2501
  }
2440
- return evalRedeemers;
2441
- }
2442
- const mapRedeemerKeyToRedeemerVal = redeemers.as_map_redeemer_key_to_redeemer_val();
2443
- if (mapRedeemerKeyToRedeemerVal) {
2444
- const keys = mapRedeemerKeyToRedeemerVal.keys();
2445
- for (let i = 0; i < keys.len(); i++) {
2446
- const key = keys.get(i);
2447
- const redeemerVal = mapRedeemerKeyToRedeemerVal.get(key);
2448
- if (redeemerVal) {
2502
+ const evalRedeemers = [];
2503
+ const arrLegacyRedeemer = own(redeemers.as_arr_legacy_redeemer());
2504
+ if (arrLegacyRedeemer) {
2505
+ for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
2506
+ const legacyRedeemer = own(arrLegacyRedeemer.get(i));
2507
+ const exUnits = own(legacyRedeemer.ex_units());
2449
2508
  evalRedeemers.push({
2450
2509
  ex_units: {
2451
- mem: Number(redeemerVal.ex_units().mem()),
2452
- steps: Number(redeemerVal.ex_units().steps())
2510
+ mem: Number(exUnits.mem()),
2511
+ steps: Number(exUnits.steps())
2453
2512
  },
2454
- redeemer_index: Number(key.index),
2455
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(key.tag())
2513
+ redeemer_index: Number(legacyRedeemer.index()),
2514
+ redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(legacyRedeemer.tag())
2456
2515
  });
2457
2516
  }
2517
+ return evalRedeemers;
2518
+ }
2519
+ const mapRedeemerKeyToRedeemerVal = own(
2520
+ redeemers.as_map_redeemer_key_to_redeemer_val()
2521
+ );
2522
+ if (mapRedeemerKeyToRedeemerVal) {
2523
+ const keys = own(mapRedeemerKeyToRedeemerVal.keys());
2524
+ for (let i = 0; i < keys.len(); i++) {
2525
+ const key = own(keys.get(i));
2526
+ const redeemerVal = own(mapRedeemerKeyToRedeemerVal.get(key));
2527
+ if (redeemerVal) {
2528
+ const exUnits = own(redeemerVal.ex_units());
2529
+ evalRedeemers.push({
2530
+ ex_units: {
2531
+ mem: Number(exUnits.mem()),
2532
+ steps: Number(exUnits.steps())
2533
+ },
2534
+ redeemer_index: Number(key.index()),
2535
+ redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(key.tag())
2536
+ });
2537
+ }
2538
+ }
2539
+ return evalRedeemers;
2458
2540
  }
2459
2541
  return evalRedeemers;
2460
- }
2461
- return evalRedeemers;
2542
+ });
2462
2543
  }
2463
2544
  log() {
2464
2545
  function getRandomColor(unit) {
package/dist/index.d.cts CHANGED
@@ -48,10 +48,17 @@ declare class OgmiosJsonRpcError extends KupmiosError {
48
48
  constructor(options: OgmiosJsonRpcErrorOptions);
49
49
  }
50
50
 
51
+ interface BlockfrostOptions {
52
+ /** Abort any single request after this many milliseconds. Defaults to 30 000. */
53
+ readonly requestTimeoutMs?: number;
54
+ }
51
55
  declare class Blockfrost implements Provider {
52
56
  url: string;
53
57
  projectId: string;
54
- constructor(url: string, projectId?: string);
58
+ private readonly requestTimeoutMs;
59
+ constructor(url: string, projectId?: string, options?: BlockfrostOptions);
60
+ /** `fetch` bounded by the provider's request timeout, combined with any caller-supplied signal. */
61
+ private fetch;
55
62
  getProtocolParameters(): Promise<ProtocolParameters>;
56
63
  getTreasury(): Promise<bigint>;
57
64
  getUtxos(addressOrCredential: Address | Credential): Promise<UTxO[]>;
@@ -287,4 +294,4 @@ declare class Koios implements Provider {
287
294
  evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
288
295
  }
289
296
 
290
- export { Blockfrost, Emulator, type EmulatorAccount, Koios, KoiosError, Kupmios, KupmiosError, type KupmiosErrorOptions, type KupmiosOptions, Maestro, type MaestroConfig, type MaestroSupportedNetworks, OgmiosJsonRpcError, type OgmiosJsonRpcErrorOptions, type ProviderErrorKind, type ProviderTransportProtocol, generateEmulatorAccount, generateEmulatorAccountFromPrivateKey, isEmulatorProvider };
297
+ export { Blockfrost, type BlockfrostOptions, Emulator, type EmulatorAccount, Koios, KoiosError, Kupmios, KupmiosError, type KupmiosErrorOptions, type KupmiosOptions, Maestro, type MaestroConfig, type MaestroSupportedNetworks, OgmiosJsonRpcError, type OgmiosJsonRpcErrorOptions, type ProviderErrorKind, type ProviderTransportProtocol, generateEmulatorAccount, generateEmulatorAccountFromPrivateKey, isEmulatorProvider };
package/dist/index.d.ts CHANGED
@@ -48,10 +48,17 @@ declare class OgmiosJsonRpcError extends KupmiosError {
48
48
  constructor(options: OgmiosJsonRpcErrorOptions);
49
49
  }
50
50
 
51
+ interface BlockfrostOptions {
52
+ /** Abort any single request after this many milliseconds. Defaults to 30 000. */
53
+ readonly requestTimeoutMs?: number;
54
+ }
51
55
  declare class Blockfrost implements Provider {
52
56
  url: string;
53
57
  projectId: string;
54
- constructor(url: string, projectId?: string);
58
+ private readonly requestTimeoutMs;
59
+ constructor(url: string, projectId?: string, options?: BlockfrostOptions);
60
+ /** `fetch` bounded by the provider's request timeout, combined with any caller-supplied signal. */
61
+ private fetch;
55
62
  getProtocolParameters(): Promise<ProtocolParameters>;
56
63
  getTreasury(): Promise<bigint>;
57
64
  getUtxos(addressOrCredential: Address | Credential): Promise<UTxO[]>;
@@ -287,4 +294,4 @@ declare class Koios implements Provider {
287
294
  evaluateTx(tx: Transaction, additionalUTxOs?: UTxO[]): Promise<EvalRedeemer[]>;
288
295
  }
289
296
 
290
- export { Blockfrost, Emulator, type EmulatorAccount, Koios, KoiosError, Kupmios, KupmiosError, type KupmiosErrorOptions, type KupmiosOptions, Maestro, type MaestroConfig, type MaestroSupportedNetworks, OgmiosJsonRpcError, type OgmiosJsonRpcErrorOptions, type ProviderErrorKind, type ProviderTransportProtocol, generateEmulatorAccount, generateEmulatorAccountFromPrivateKey, isEmulatorProvider };
297
+ export { Blockfrost, type BlockfrostOptions, Emulator, type EmulatorAccount, Koios, KoiosError, Kupmios, KupmiosError, type KupmiosErrorOptions, type KupmiosOptions, Maestro, type MaestroConfig, type MaestroSupportedNetworks, OgmiosJsonRpcError, type OgmiosJsonRpcErrorOptions, type ProviderErrorKind, type ProviderTransportProtocol, generateEmulatorAccount, generateEmulatorAccountFromPrivateKey, isEmulatorProvider };
package/dist/index.js CHANGED
@@ -101,7 +101,7 @@ import {
101
101
  // package.json
102
102
  var package_default = {
103
103
  name: "@lucid-evolution/provider",
104
- version: "0.2.2",
104
+ version: "0.2.4",
105
105
  description: "",
106
106
  main: "./dist/index.js",
107
107
  types: "./dist/index.d.ts",
@@ -204,6 +204,7 @@ var fromLegacyRedeemerTag = (redeemerTag) => {
204
204
  };
205
205
 
206
206
  // src/blockfrost.ts
207
+ var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
207
208
  var toBlockfrostQueryPredicate = (addressOrCredential) => {
208
209
  if (typeof addressOrCredential === "string") return addressOrCredential;
209
210
  if (addressOrCredential.type === "Key") {
@@ -216,12 +217,24 @@ var toBlockfrostQueryPredicate = (addressOrCredential) => {
216
217
  var Blockfrost = class {
217
218
  url;
218
219
  projectId;
219
- constructor(url, projectId) {
220
+ requestTimeoutMs;
221
+ constructor(url, projectId, options = {}) {
220
222
  this.url = url;
221
223
  this.projectId = projectId || "";
224
+ const timeout = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
225
+ if (!Number.isFinite(timeout) || timeout <= 0) {
226
+ throw new TypeError("requestTimeoutMs must be a positive finite number.");
227
+ }
228
+ this.requestTimeoutMs = timeout;
229
+ }
230
+ /** `fetch` bounded by the provider's request timeout, combined with any caller-supplied signal. */
231
+ fetch(input, init = {}) {
232
+ const timeout = AbortSignal.timeout(this.requestTimeoutMs);
233
+ const signal = init.signal == null ? timeout : typeof AbortSignal.any === "function" ? AbortSignal.any([init.signal, timeout]) : init.signal;
234
+ return fetch(input, { ...init, signal });
222
235
  }
223
236
  async getProtocolParameters() {
224
- const result = await fetch(`${this.url}/epochs/latest/parameters`, {
237
+ const result = await this.fetch(`${this.url}/epochs/latest/parameters`, {
225
238
  headers: { project_id: this.projectId, lucid }
226
239
  }).then((res) => res.json());
227
240
  return {
@@ -249,7 +262,7 @@ var Blockfrost = class {
249
262
  };
250
263
  }
251
264
  async getTreasury() {
252
- const result = await fetch(`${this.url}/network`, {
265
+ const result = await this.fetch(`${this.url}/network`, {
253
266
  headers: { project_id: this.projectId, lucid }
254
267
  }).then((res) => res.json());
255
268
  if (!result || result.error || result.supply?.treasury === void 0) {
@@ -262,7 +275,7 @@ var Blockfrost = class {
262
275
  let result = [];
263
276
  let page = 1;
264
277
  while (true) {
265
- const pageResult = await fetch(
278
+ const pageResult = await this.fetch(
266
279
  `${this.url}/addresses/${queryPredicate}/utxos?page=${page}`,
267
280
  { headers: { project_id: this.projectId, lucid } }
268
281
  ).then((res) => res.json());
@@ -284,7 +297,7 @@ var Blockfrost = class {
284
297
  let result = [];
285
298
  let page = 1;
286
299
  while (true) {
287
- const pageResult = await fetch(
300
+ const pageResult = await this.fetch(
288
301
  `${this.url}/addresses/${queryPredicate}/utxos/${unit}?page=${page}`,
289
302
  { headers: { project_id: this.projectId, lucid } }
290
303
  ).then((res) => res.json());
@@ -302,7 +315,7 @@ var Blockfrost = class {
302
315
  return this.blockfrostUtxosToUtxos(result);
303
316
  }
304
317
  async getUtxoByUnit(unit) {
305
- const addresses = await fetch(
318
+ const addresses = await this.fetch(
306
319
  `${this.url}/assets/${unit}/addresses?count=2`,
307
320
  { headers: { project_id: this.projectId, lucid } }
308
321
  ).then((res) => res.json());
@@ -323,7 +336,7 @@ var Blockfrost = class {
323
336
  const queryHashes = [...new Set(outRefs.map((outRef) => outRef.txHash))];
324
337
  const utxos = await Promise.all(
325
338
  queryHashes.map(async (txHash) => {
326
- const result = await fetch(`${this.url}/txs/${txHash}/utxos`, {
339
+ const result = await this.fetch(`${this.url}/txs/${txHash}/utxos`, {
327
340
  headers: { project_id: this.projectId, lucid }
328
341
  }).then((res) => res.json());
329
342
  if (!result || result.error) {
@@ -345,7 +358,7 @@ var Blockfrost = class {
345
358
  );
346
359
  }
347
360
  async getRewardAccount(rewardAddress) {
348
- const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
361
+ const response = await this.fetch(`${this.url}/accounts/${rewardAddress}`, {
349
362
  headers: { project_id: this.projectId, lucid }
350
363
  });
351
364
  if (response.status === 404) {
@@ -368,9 +381,12 @@ var Blockfrost = class {
368
381
  return { poolId, rewards };
369
382
  }
370
383
  async getDatum(datumHash) {
371
- const datum = await fetch(`${this.url}/scripts/datum/${datumHash}/cbor`, {
372
- headers: { project_id: this.projectId, lucid }
373
- }).then((res) => res.json()).then((res) => res.cbor);
384
+ const datum = await this.fetch(
385
+ `${this.url}/scripts/datum/${datumHash}/cbor`,
386
+ {
387
+ headers: { project_id: this.projectId, lucid }
388
+ }
389
+ ).then((res) => res.json()).then((res) => res.cbor);
374
390
  if (!datum || datum.error) {
375
391
  throw new Error(`No datum found for datum hash: ${datumHash}`);
376
392
  }
@@ -379,7 +395,7 @@ var Blockfrost = class {
379
395
  awaitTx(txHash, checkInterval = 3e3) {
380
396
  return new Promise((res) => {
381
397
  const confirmation = setInterval(async () => {
382
- const isConfirmed = await fetch(`${this.url}/txs/${txHash}/cbor`, {
398
+ const isConfirmed = await this.fetch(`${this.url}/txs/${txHash}/cbor`, {
383
399
  headers: { project_id: this.projectId, lucid }
384
400
  }).then((res2) => res2.json());
385
401
  if (isConfirmed && !isConfirmed.error) {
@@ -391,7 +407,7 @@ var Blockfrost = class {
391
407
  });
392
408
  }
393
409
  async getTransactionStatus(txHash, options = {}) {
394
- const response = await fetch(`${this.url}/txs/${txHash}`, {
410
+ const response = await this.fetch(`${this.url}/txs/${txHash}`, {
395
411
  headers: { project_id: this.projectId, lucid },
396
412
  signal: options.signal
397
413
  });
@@ -414,7 +430,7 @@ var Blockfrost = class {
414
430
  };
415
431
  }
416
432
  async submitTx(tx) {
417
- const result = await fetch(`${this.url}/tx/submit`, {
433
+ const result = await this.fetch(`${this.url}/tx/submit`, {
418
434
  method: "POST",
419
435
  headers: {
420
436
  "Content-Type": "application/cbor",
@@ -449,19 +465,19 @@ var Blockfrost = class {
449
465
  datumHash: !r.inline_datum && r.data_hash || void 0,
450
466
  datum: r.inline_datum || void 0,
451
467
  scriptRef: r.reference_script_hash ? await (async () => {
452
- const { type } = await fetch(
468
+ const { type } = await this.fetch(
453
469
  `${this.url}/scripts/${r.reference_script_hash}`,
454
470
  {
455
471
  headers: { project_id: this.projectId, lucid }
456
472
  }
457
473
  ).then((res) => res.json());
458
- const { cbor: script } = await fetch(
474
+ const { cbor: script } = await this.fetch(
459
475
  `${this.url}/scripts/${r.reference_script_hash}/cbor`,
460
476
  { headers: { project_id: this.projectId, lucid } }
461
477
  ).then((res) => res.json());
462
478
  switch (type) {
463
479
  case "timelock":
464
- const { json: native } = await fetch(
480
+ const { json: native } = await this.fetch(
465
481
  `${this.url}/scripts/${r.reference_script_hash}/json`,
466
482
  { headers: { project_id: this.projectId, lucid } }
467
483
  ).then((res) => res.json());
@@ -496,7 +512,7 @@ var Blockfrost = class {
496
512
  cbor: tx,
497
513
  ...utxos?.length ? { additionalUtxoSet: toAditionalUTXOs(utxos) } : {}
498
514
  };
499
- const res = await fetch(`${this.url}/utils/txs/evaluate/utxos`, {
515
+ const res = await this.fetch(`${this.url}/utils/txs/evaluate/utxos`, {
500
516
  method: "POST",
501
517
  headers: {
502
518
  "Content-Type": "application/json",
@@ -981,7 +997,7 @@ var makePostAsUint8Array = (url, data, schema, headers) => pipe2(
981
997
 
982
998
  // src/kupmios.ts
983
999
  import { FetchHttpClient } from "@effect/platform";
984
- var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
1000
+ var DEFAULT_REQUEST_TIMEOUT_MS2 = 3e4;
985
1001
  var DEFAULT_AWAIT_TX_TIMEOUT_MS = 16e4;
986
1002
  var validateTimeout = (name, timeout) => {
987
1003
  if (!Number.isFinite(timeout) || timeout <= 0) {
@@ -1019,7 +1035,7 @@ var Kupmios = class {
1019
1035
  this.options = options;
1020
1036
  this.requestTimeoutMs = validateTimeout(
1021
1037
  "requestTimeoutMs",
1022
- options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS
1038
+ options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS2
1023
1039
  );
1024
1040
  this.awaitTxTimeoutMs = validateTimeout(
1025
1041
  "awaitTxTimeoutMs",
@@ -1469,7 +1485,7 @@ import {
1469
1485
  PROTOCOL_PARAMETERS_DEFAULT
1470
1486
  } from "@lucid-evolution/utils";
1471
1487
  import { coreToUtxo, getAddressDetails } from "@lucid-evolution/utils";
1472
- import { fromHex as fromHex2 } from "@lucid-evolution/core-utils";
1488
+ import { freeCML, fromHex as fromHex2, withCMLScope } from "@lucid-evolution/core-utils";
1473
1489
  import { walletFromSeed } from "@lucid-evolution/wallet";
1474
1490
  var EMULATOR_PROVIDER_BRAND = Symbol.for(
1475
1491
  "@lucid-evolution/provider/Emulator"
@@ -1505,6 +1521,7 @@ function generateEmulatorAccount(assets) {
1505
1521
  privateKey: ""
1506
1522
  };
1507
1523
  }
1524
+ var DEFAULT_PROTOCOL_MAJOR_VERSION = 11;
1508
1525
  var Emulator = class {
1509
1526
  [EMULATOR_PROVIDER_BRAND] = true;
1510
1527
  ledger;
@@ -1759,78 +1776,94 @@ var Emulator = class {
1759
1776
  const datumTable = (() => {
1760
1777
  const table = {};
1761
1778
  for (let i = 0; i < (datums?.len() || 0); i++) {
1762
- const datum = datums.get(i);
1763
- const datumHash = CML.hash_plutus_data(datum).to_hex();
1764
- table[datumHash] = datum.to_cbor_hex();
1779
+ withCMLScope((own) => {
1780
+ const datum = own(datums.get(i));
1781
+ const datumHash = own(CML.hash_plutus_data(datum)).to_hex();
1782
+ table[datumHash] = datum.to_cbor_hex();
1783
+ });
1765
1784
  }
1766
1785
  return table;
1767
1786
  })();
1768
1787
  const consumedHashes = /* @__PURE__ */ new Set();
1769
- const keyHashes = (() => {
1788
+ const keyHashes = withCMLScope((own) => {
1770
1789
  const keyHashes2 = [];
1771
- for (let i = 0; i < (witnesses.vkeywitnesses()?.len() || 0); i++) {
1772
- const witness = witnesses.vkeywitnesses().get(i);
1773
- const publicKey = witness.vkey();
1774
- const keyHash = publicKey.hash().to_hex();
1775
- if (!publicKey.verify(fromHex2(txHash), witness.ed25519_signature())) {
1776
- throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1777
- }
1778
- keyHashes2.push(keyHash);
1790
+ const vkeyWitnesses = own(witnesses.vkeywitnesses());
1791
+ for (let i = 0; i < (vkeyWitnesses?.len() || 0); i++) {
1792
+ withCMLScope((own2) => {
1793
+ const witness = own2(vkeyWitnesses.get(i));
1794
+ const publicKey = own2(witness.vkey());
1795
+ const keyHash = own2(publicKey.hash()).to_hex();
1796
+ if (!publicKey.verify(fromHex2(txHash), own2(witness.ed25519_signature()))) {
1797
+ throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1798
+ }
1799
+ keyHashes2.push(keyHash);
1800
+ });
1779
1801
  }
1780
1802
  return keyHashes2;
1781
- })();
1803
+ });
1782
1804
  const edKeyHashes = CML.Ed25519KeyHashList.new();
1783
1805
  keyHashes.forEach(
1784
- (keyHash) => edKeyHashes.add(CML.Ed25519KeyHash.from_hex(keyHash))
1806
+ (keyHash) => withCMLScope(
1807
+ (own) => edKeyHashes.add(own(CML.Ed25519KeyHash.from_hex(keyHash)))
1808
+ )
1785
1809
  );
1786
- const nativeHashes = (() => {
1810
+ const nativeHashes = withCMLScope((own) => {
1787
1811
  const scriptHashes = [];
1788
- for (let i = 0; i < (witnesses.native_scripts()?.len() || 0); i++) {
1789
- const witness = witnesses.native_scripts().get(i);
1790
- const scriptHash = witness.hash().to_hex();
1791
- if (!witness.verify(
1792
- Number.isInteger(lowerBound) ? CML.BigInteger.from_str(lowerBound.toString()).to_js_value() : void 0,
1793
- Number.isInteger(upperBound) ? CML.BigInteger.from_str(upperBound.toString()).to_js_value() : void 0,
1794
- edKeyHashes
1795
- )) {
1796
- throw new Error(
1797
- `Invalid native script witness. Script hash: ${scriptHash}`
1798
- );
1799
- }
1800
- for (let i2 = 0; i2 < witness.get_required_signers().len(); i2++) {
1801
- const keyHash = witness.get_required_signers().get(i2).to_hex();
1802
- consumedHashes.add(keyHash);
1803
- }
1804
- scriptHashes.push(scriptHash);
1812
+ const nativeScripts = own(witnesses.native_scripts());
1813
+ for (let i = 0; i < (nativeScripts?.len() || 0); i++) {
1814
+ withCMLScope((own2) => {
1815
+ const witness = own2(nativeScripts.get(i));
1816
+ const scriptHash = own2(witness.hash()).to_hex();
1817
+ if (!witness.verify(
1818
+ Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
1819
+ Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
1820
+ edKeyHashes
1821
+ )) {
1822
+ throw new Error(
1823
+ `Invalid native script witness. Script hash: ${scriptHash}`
1824
+ );
1825
+ }
1826
+ const requiredSigners = own2(witness.get_required_signers());
1827
+ for (let j = 0; j < requiredSigners.len(); j++) {
1828
+ const keyHash = own2(requiredSigners.get(j)).to_hex();
1829
+ consumedHashes.add(keyHash);
1830
+ }
1831
+ scriptHashes.push(scriptHash);
1832
+ });
1805
1833
  }
1806
1834
  return scriptHashes;
1807
- })();
1835
+ });
1836
+ edKeyHashes.free();
1808
1837
  const nativeHashesOptional = {};
1809
1838
  const plutusHashesOptional = [];
1810
- const plutusHashes = (() => {
1839
+ const plutusV3Hashes = /* @__PURE__ */ new Set();
1840
+ const plutusHashes = withCMLScope((own) => {
1811
1841
  const scriptHashes = [];
1812
- for (let i = 0; i < (witnesses.plutus_v1_scripts()?.len() || 0); i++) {
1813
- const script = witnesses.plutus_v1_scripts().get(i);
1814
- const scriptHash = script.hash().to_hex();
1815
- scriptHashes.push(scriptHash);
1816
- }
1817
- for (let i = 0; i < (witnesses.plutus_v2_scripts()?.len() || 0); i++) {
1818
- const script = witnesses.plutus_v2_scripts().get(i);
1819
- const scriptHash = script.hash().to_hex();
1820
- scriptHashes.push(scriptHash);
1821
- }
1822
- for (let i = 0; i < (witnesses.plutus_v3_scripts()?.len() || 0); i++) {
1823
- const script = witnesses.plutus_v3_scripts().get(i);
1824
- const scriptHash = script.hash().to_hex();
1825
- scriptHashes.push(scriptHash);
1826
- }
1842
+ const collectHashes = (scripts, isPlutusV3 = false) => {
1843
+ own(scripts);
1844
+ for (let i = 0; i < (scripts?.len() || 0); i++) {
1845
+ withCMLScope((own2) => {
1846
+ const script = own2(scripts.get(i));
1847
+ const scriptHash = own2(script.hash()).to_hex();
1848
+ scriptHashes.push(scriptHash);
1849
+ if (isPlutusV3) plutusV3Hashes.add(scriptHash);
1850
+ });
1851
+ }
1852
+ };
1853
+ collectHashes(witnesses.plutus_v1_scripts());
1854
+ collectHashes(witnesses.plutus_v2_scripts());
1855
+ collectHashes(witnesses.plutus_v3_scripts(), true);
1827
1856
  return scriptHashes;
1828
- })();
1857
+ });
1829
1858
  const inputs = body.inputs();
1830
1859
  const resolvedInputs = [];
1860
+ const inputOutRefs = /* @__PURE__ */ new Set();
1831
1861
  for (let i = 0; i < inputs.len(); i++) {
1832
- const input = inputs.get(i);
1833
- const outRef = input.transaction_id().to_hex() + input.index().toString();
1862
+ const outRef = withCMLScope((own) => {
1863
+ const input = own(inputs.get(i));
1864
+ return own(input.transaction_id()).to_hex() + input.index().toString();
1865
+ });
1866
+ inputOutRefs.add(outRef);
1834
1867
  const entryLedger = this.ledger[outRef];
1835
1868
  const { entry, type } = !entryLedger ? { entry: this.mempool[outRef], type: "Mempool" } : { entry: entryLedger, type: "Ledger" };
1836
1869
  if (!entry || entry.spent) {
@@ -1870,7 +1903,9 @@ It does not exist or was already spent.`
1870
1903
  const script = CML.PlutusScript.from_v3(
1871
1904
  CML.PlutusV3Script.from_cbor_bytes(fromHex2(scriptRef.script))
1872
1905
  );
1873
- plutusHashesOptional.push(script.hash().to_hex());
1906
+ const scriptHash = script.hash().to_hex();
1907
+ plutusHashesOptional.push(scriptHash);
1908
+ plutusV3Hashes.add(scriptHash);
1874
1909
  break;
1875
1910
  }
1876
1911
  }
@@ -1878,9 +1913,14 @@ It does not exist or was already spent.`
1878
1913
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1879
1914
  resolvedInputs.push({ entry, type });
1880
1915
  }
1881
- for (let i = 0; i < (body.reference_inputs()?.len() || 0); i++) {
1882
- const input = body.reference_inputs().get(i);
1883
- const outRef = input.transaction_id().to_hex() + input.index().toString();
1916
+ inputs.free();
1917
+ const referenceInputs = body.reference_inputs();
1918
+ const nonDisjointRefInputs = [];
1919
+ for (let i = 0; i < (referenceInputs?.len() || 0); i++) {
1920
+ const outRef = withCMLScope((own) => {
1921
+ const input = own(referenceInputs.get(i));
1922
+ return own(input.transaction_id()).to_hex() + input.index().toString();
1923
+ });
1884
1924
  const entry = this.ledger[outRef] || this.mempool[outRef];
1885
1925
  if (!entry || entry.spent) {
1886
1926
  throw new Error(
@@ -1891,6 +1931,11 @@ It does not exist or was already spent.`
1891
1931
  It does not exist or was already spent.`
1892
1932
  );
1893
1933
  }
1934
+ if (inputOutRefs.has(outRef)) {
1935
+ nonDisjointRefInputs.push(
1936
+ `${entry.utxo.txHash}#${entry.utxo.outputIndex}`
1937
+ );
1938
+ }
1894
1939
  const scriptRef = entry.utxo.scriptRef;
1895
1940
  if (scriptRef) {
1896
1941
  switch (scriptRef.type) {
@@ -1919,13 +1964,16 @@ It does not exist or was already spent.`
1919
1964
  const script = CML.PlutusScript.from_v3(
1920
1965
  CML.PlutusV3Script.from_cbor_bytes(fromHex2(scriptRef.script))
1921
1966
  );
1922
- plutusHashesOptional.push(script.hash().to_hex());
1967
+ const scriptHash = script.hash().to_hex();
1968
+ plutusHashesOptional.push(scriptHash);
1969
+ plutusV3Hashes.add(scriptHash);
1923
1970
  break;
1924
1971
  }
1925
1972
  }
1926
1973
  }
1927
1974
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1928
1975
  }
1976
+ referenceInputs?.free();
1929
1977
  const redeemers = (() => {
1930
1978
  const tagMap = {
1931
1979
  0: "Spend",
@@ -2004,9 +2052,12 @@ It does not exist or was already spent.`
2004
2052
  }
2005
2053
  }
2006
2054
  }
2007
- for (let i = 0; i < (body.collateral_inputs()?.len() || 0); i++) {
2008
- const input = body.collateral_inputs().get(i);
2009
- const outRef = input.transaction_id().to_hex() + input.index().toString();
2055
+ const collateralInputs = body.collateral_inputs();
2056
+ for (let i = 0; i < (collateralInputs?.len() || 0); i++) {
2057
+ const outRef = withCMLScope((own) => {
2058
+ const input = own(collateralInputs.get(i));
2059
+ return own(input.transaction_id()).to_hex() + input.index().toString();
2060
+ });
2010
2061
  const entry = this.ledger[outRef] || this.mempool[outRef];
2011
2062
  if (!entry || entry.spent) {
2012
2063
  throw new Error(
@@ -2023,6 +2074,7 @@ It does not exist or was already spent.`
2023
2074
  }
2024
2075
  checkAndConsumeHash(paymentCredential, null, null);
2025
2076
  }
2077
+ collateralInputs?.free();
2026
2078
  for (let i = 0; i < (body.required_signers()?.len() || 0); i++) {
2027
2079
  const signer = body.required_signers().get(i);
2028
2080
  checkAndConsumeHash({ type: "Key", hash: signer.to_hex() }, null, null);
@@ -2288,16 +2340,21 @@ It does not exist or was already spent.`
2288
2340
  const { paymentCredential } = getAddressDetails(utxo.address);
2289
2341
  checkAndConsumeHash(paymentCredential, "Spend", index);
2290
2342
  });
2291
- const outputs = (() => {
2343
+ const outputs = withCMLScope((own) => {
2292
2344
  const collected = [];
2293
- for (let i = 0; i < body.outputs().len(); i++) {
2294
- const output = body.outputs().get(i);
2295
- const unspentOutput = CML.TransactionUnspentOutput.new(
2296
- CML.TransactionInput.new(
2297
- CML.TransactionHash.from_hex(txHash),
2298
- CML.BigInteger.from_str(i.toString()).to_js_value()
2299
- ),
2300
- output
2345
+ const bodyOutputs = own(body.outputs());
2346
+ for (let i = 0; i < bodyOutputs.len(); i++) {
2347
+ const output = own(bodyOutputs.get(i));
2348
+ const unspentOutput = own(
2349
+ CML.TransactionUnspentOutput.new(
2350
+ own(
2351
+ CML.TransactionInput.new(
2352
+ own(CML.TransactionHash.from_hex(txHash)),
2353
+ BigInt(i)
2354
+ )
2355
+ ),
2356
+ output
2357
+ )
2301
2358
  );
2302
2359
  const utxo = coreToUtxo(unspentOutput);
2303
2360
  if (utxo.datumHash) consumedHashes.add(utxo.datumHash);
@@ -2307,7 +2364,7 @@ It does not exist or was already spent.`
2307
2364
  });
2308
2365
  }
2309
2366
  return collected;
2310
- })();
2367
+ });
2311
2368
  const [extraKeyHash] = keyHashes.filter(
2312
2369
  (keyHash) => !consumedHashes.has(keyHash)
2313
2370
  );
@@ -2336,6 +2393,23 @@ It does not exist or was already spent.`
2336
2393
  if (extraDatumHash) {
2337
2394
  throw new Error(`Extraneous plutus data. Datum hash: ${extraDatumHash}`);
2338
2395
  }
2396
+ if (nonDisjointRefInputs.length > 0) {
2397
+ const protocolMajorVersion = this.protocolParameters.protocolMajorVersion ?? DEFAULT_PROTOCOL_MAJOR_VERSION;
2398
+ const overlap = nonDisjointRefInputs.join(", ");
2399
+ if (protocolMajorVersion === 9 || protocolMajorVersion === 10) {
2400
+ throw new Error(
2401
+ `BabbageNonDisjointRefInputs: reference inputs must be disjoint from inputs at protocol version ${protocolMajorVersion}. Overlapping: ${overlap}`
2402
+ );
2403
+ }
2404
+ const runsPlutusV3 = [...consumedHashes].some(
2405
+ (hash) => plutusV3Hashes.has(hash)
2406
+ );
2407
+ if (protocolMajorVersion >= 11 && runsPlutusV3) {
2408
+ throw new Error(
2409
+ `ReferenceInputsNotDisjointFromInputs: a PlutusV3 script context cannot be built while reference inputs overlap inputs. Overlapping: ${overlap}`
2410
+ );
2411
+ }
2412
+ }
2339
2413
  resolvedInputs.forEach(({ entry, type }) => {
2340
2414
  const outRef = entry.utxo.txHash + entry.utxo.outputIndex;
2341
2415
  entry.spent = true;
@@ -2381,50 +2455,57 @@ It does not exist or was already spent.`
2381
2455
  this.datumTable[datumHash] = datum;
2382
2456
  }
2383
2457
  this.transactionHistory[txHash] = { status: "pending" };
2458
+ freeCML(datums, witnesses, body, desTx);
2384
2459
  return Promise.resolve(txHash);
2385
2460
  }
2386
2461
  async evaluateTx(tx, additionalUTxOs) {
2387
- const desTx = CML.Transaction.from_cbor_hex(tx);
2388
- const redeemers = desTx.witness_set().redeemers();
2389
- if (!redeemers) {
2390
- return [];
2391
- }
2392
- let evalRedeemers = [];
2393
- const arrLegacyRedeemer = redeemers.as_arr_legacy_redeemer();
2394
- if (arrLegacyRedeemer) {
2395
- for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
2396
- const legacyRedeemer = arrLegacyRedeemer.get(i);
2397
- evalRedeemers.push({
2398
- ex_units: {
2399
- mem: Number(legacyRedeemer.ex_units().mem()),
2400
- steps: Number(legacyRedeemer.ex_units().steps())
2401
- },
2402
- redeemer_index: Number(legacyRedeemer.index()),
2403
- redeemer_tag: fromCMLRedeemerTag(legacyRedeemer.tag())
2404
- });
2462
+ return withCMLScope((own) => {
2463
+ const desTx = own(CML.Transaction.from_cbor_hex(tx));
2464
+ const redeemers = own(own(desTx.witness_set()).redeemers());
2465
+ if (!redeemers) {
2466
+ return [];
2405
2467
  }
2406
- return evalRedeemers;
2407
- }
2408
- const mapRedeemerKeyToRedeemerVal = redeemers.as_map_redeemer_key_to_redeemer_val();
2409
- if (mapRedeemerKeyToRedeemerVal) {
2410
- const keys = mapRedeemerKeyToRedeemerVal.keys();
2411
- for (let i = 0; i < keys.len(); i++) {
2412
- const key = keys.get(i);
2413
- const redeemerVal = mapRedeemerKeyToRedeemerVal.get(key);
2414
- if (redeemerVal) {
2468
+ const evalRedeemers = [];
2469
+ const arrLegacyRedeemer = own(redeemers.as_arr_legacy_redeemer());
2470
+ if (arrLegacyRedeemer) {
2471
+ for (let i = 0; i < arrLegacyRedeemer.len(); i++) {
2472
+ const legacyRedeemer = own(arrLegacyRedeemer.get(i));
2473
+ const exUnits = own(legacyRedeemer.ex_units());
2415
2474
  evalRedeemers.push({
2416
2475
  ex_units: {
2417
- mem: Number(redeemerVal.ex_units().mem()),
2418
- steps: Number(redeemerVal.ex_units().steps())
2476
+ mem: Number(exUnits.mem()),
2477
+ steps: Number(exUnits.steps())
2419
2478
  },
2420
- redeemer_index: Number(key.index),
2421
- redeemer_tag: fromCMLRedeemerTag(key.tag())
2479
+ redeemer_index: Number(legacyRedeemer.index()),
2480
+ redeemer_tag: fromCMLRedeemerTag(legacyRedeemer.tag())
2422
2481
  });
2423
2482
  }
2483
+ return evalRedeemers;
2484
+ }
2485
+ const mapRedeemerKeyToRedeemerVal = own(
2486
+ redeemers.as_map_redeemer_key_to_redeemer_val()
2487
+ );
2488
+ if (mapRedeemerKeyToRedeemerVal) {
2489
+ const keys = own(mapRedeemerKeyToRedeemerVal.keys());
2490
+ for (let i = 0; i < keys.len(); i++) {
2491
+ const key = own(keys.get(i));
2492
+ const redeemerVal = own(mapRedeemerKeyToRedeemerVal.get(key));
2493
+ if (redeemerVal) {
2494
+ const exUnits = own(redeemerVal.ex_units());
2495
+ evalRedeemers.push({
2496
+ ex_units: {
2497
+ mem: Number(exUnits.mem()),
2498
+ steps: Number(exUnits.steps())
2499
+ },
2500
+ redeemer_index: Number(key.index()),
2501
+ redeemer_tag: fromCMLRedeemerTag(key.tag())
2502
+ });
2503
+ }
2504
+ }
2505
+ return evalRedeemers;
2424
2506
  }
2425
2507
  return evalRedeemers;
2426
- }
2427
- return evalRedeemers;
2508
+ });
2428
2509
  }
2429
2510
  log() {
2430
2511
  function getRandomColor(unit) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucid-evolution/provider",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -31,9 +31,9 @@
31
31
  "@effect/schema": "^0.68.26",
32
32
  "effect": "^3.11.7",
33
33
  "@lucid-evolution/core-types": "0.3.0",
34
- "@lucid-evolution/core-utils": "0.1.16",
35
- "@lucid-evolution/utils": "0.1.73",
36
- "@lucid-evolution/wallet": "0.2.1"
34
+ "@lucid-evolution/utils": "0.1.74",
35
+ "@lucid-evolution/core-utils": "0.1.17",
36
+ "@lucid-evolution/wallet": "0.2.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^20.12.8",