@lucid-evolution/provider 0.2.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -36,7 +36,6 @@ __export(index_exports, {
36
36
  KoiosError: () => KoiosError,
37
37
  Kupmios: () => Kupmios,
38
38
  KupmiosError: () => KupmiosError,
39
- Maestro: () => Maestro,
40
39
  OgmiosJsonRpcError: () => OgmiosJsonRpcError,
41
40
  generateEmulatorAccount: () => generateEmulatorAccount,
42
41
  generateEmulatorAccountFromPrivateKey: () => generateEmulatorAccountFromPrivateKey,
@@ -144,7 +143,7 @@ var import_utils2 = require("@lucid-evolution/utils");
144
143
  // package.json
145
144
  var package_default = {
146
145
  name: "@lucid-evolution/provider",
147
- version: "0.2.5",
146
+ version: "0.3.0",
148
147
  description: "",
149
148
  main: "./dist/index.js",
150
149
  types: "./dist/index.d.ts",
@@ -1067,6 +1066,7 @@ var Kupmios = class {
1067
1066
  options;
1068
1067
  requestTimeoutMs;
1069
1068
  awaitTxTimeoutMs;
1069
+ httpLayer;
1070
1070
  constructor(kupoUrl, ogmiosUrl, options = {}) {
1071
1071
  this.kupoUrl = kupoUrl;
1072
1072
  this.ogmiosUrl = ogmiosUrl;
@@ -1079,6 +1079,10 @@ var Kupmios = class {
1079
1079
  "awaitTxTimeoutMs",
1080
1080
  options.awaitTxTimeoutMs ?? DEFAULT_AWAIT_TX_TIMEOUT_MS
1081
1081
  );
1082
+ this.httpLayer = options.fetchImpl === void 0 ? import_platform2.FetchHttpClient.layer : import_effect6.Layer.provide(
1083
+ import_platform2.FetchHttpClient.layer,
1084
+ import_effect6.Layer.succeed(import_platform2.FetchHttpClient.Fetch, options.fetchImpl)
1085
+ );
1082
1086
  }
1083
1087
  async getProtocolParameters() {
1084
1088
  const data = {
@@ -1100,7 +1104,7 @@ var Kupmios = class {
1100
1104
  ),
1101
1105
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1102
1106
  catchProviderError("ogmios", "queryLedgerState/protocolParameters"),
1103
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1107
+ import_effect6.Effect.provide(this.httpLayer)
1104
1108
  ),
1105
1109
  "ogmios",
1106
1110
  "queryLedgerState/protocolParameters"
@@ -1135,7 +1139,7 @@ var Kupmios = class {
1135
1139
  ),
1136
1140
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1137
1141
  catchProviderError("ogmios", "queryLedgerState/treasuryAndReserves"),
1138
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1142
+ import_effect6.Effect.provide(this.httpLayer)
1139
1143
  ),
1140
1144
  "ogmios",
1141
1145
  "queryLedgerState/treasuryAndReserves"
@@ -1158,7 +1162,7 @@ var Kupmios = class {
1158
1162
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1159
1163
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1160
1164
  catchProviderError("kupo", "getUtxos"),
1161
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1165
+ import_effect6.Effect.provide(this.httpLayer)
1162
1166
  ),
1163
1167
  "kupo",
1164
1168
  "getUtxos"
@@ -1177,7 +1181,7 @@ var Kupmios = class {
1177
1181
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1178
1182
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1179
1183
  catchProviderError("kupo", "getUtxosWithUnit"),
1180
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1184
+ import_effect6.Effect.provide(this.httpLayer)
1181
1185
  ),
1182
1186
  "kupo",
1183
1187
  "getUtxosWithUnit"
@@ -1201,7 +1205,7 @@ var Kupmios = class {
1201
1205
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1202
1206
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1203
1207
  catchProviderError("kupo", "getUtxosWithPolicy"),
1204
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1208
+ import_effect6.Effect.provide(this.httpLayer)
1205
1209
  ),
1206
1210
  "kupo",
1207
1211
  "getUtxosWithPolicy"
@@ -1217,7 +1221,7 @@ var Kupmios = class {
1217
1221
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1218
1222
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1219
1223
  catchProviderError("kupo", "getUtxoByUnit"),
1220
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1224
+ import_effect6.Effect.provide(this.httpLayer)
1221
1225
  ),
1222
1226
  "kupo",
1223
1227
  "getUtxoByUnit"
@@ -1246,7 +1250,7 @@ var Kupmios = class {
1246
1250
  )
1247
1251
  );
1248
1252
  const utxos = await runProviderEffect(
1249
- (0, import_effect6.pipe)(program, import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)),
1253
+ (0, import_effect6.pipe)(program, import_effect6.Effect.provide(this.httpLayer)),
1250
1254
  "kupo",
1251
1255
  "getUtxosByOutRef"
1252
1256
  );
@@ -1272,7 +1276,7 @@ var Kupmios = class {
1272
1276
  schema,
1273
1277
  this.options.ogmiosHeader
1274
1278
  ),
1275
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1279
+ import_effect6.Effect.provide(this.httpLayer),
1276
1280
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1277
1281
  catchProviderError("ogmios", "queryLedgerState/rewardAccountSummaries")
1278
1282
  ),
@@ -1296,7 +1300,7 @@ var Kupmios = class {
1296
1300
  const result = await runProviderEffect(
1297
1301
  (0, import_effect6.pipe)(
1298
1302
  makeGet(pattern, schema, this.options.kupoHeader),
1299
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1303
+ import_effect6.Effect.provide(this.httpLayer),
1300
1304
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1301
1305
  import_effect6.Effect.flatMap(import_effect6.Effect.fromNullable),
1302
1306
  catchProviderError("kupo", "getDatum")
@@ -1316,7 +1320,7 @@ var Kupmios = class {
1316
1320
  makeGet(pattern, schema, this.options.kupoHeader),
1317
1321
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1318
1322
  catchProviderError("kupo", "getTransactionStatus"),
1319
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1323
+ import_effect6.Effect.provide(this.httpLayer)
1320
1324
  ),
1321
1325
  "kupo",
1322
1326
  "getTransactionStatus",
@@ -1342,7 +1346,7 @@ var Kupmios = class {
1342
1346
  const result = await runProviderEffect(
1343
1347
  (0, import_effect6.pipe)(
1344
1348
  makeGet(pattern, schema, this.options.kupoHeader),
1345
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1349
+ import_effect6.Effect.provide(this.httpLayer),
1346
1350
  import_effect6.Effect.repeat({
1347
1351
  schedule: import_effect6.Schedule.exponential(checkInterval),
1348
1352
  until: (result2) => result2.length > 0
@@ -1380,7 +1384,7 @@ var Kupmios = class {
1380
1384
  schema,
1381
1385
  this.options.ogmiosHeader
1382
1386
  ),
1383
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1387
+ import_effect6.Effect.provide(this.httpLayer),
1384
1388
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1385
1389
  catchProviderError("ogmios", "submitTransaction")
1386
1390
  ),
@@ -1413,7 +1417,7 @@ var Kupmios = class {
1413
1417
  schema,
1414
1418
  this.options.ogmiosHeader
1415
1419
  ),
1416
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1420
+ import_effect6.Effect.provide(this.httpLayer),
1417
1421
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1418
1422
  catchProviderError("ogmios", "evaluateTransaction")
1419
1423
  ),
@@ -1519,10 +1523,206 @@ var kupmiosUtxosToUtxos = (utxos) => utxos.map((utxo) => ({
1519
1523
  }));
1520
1524
 
1521
1525
  // src/emulator.ts
1522
- var import_utils5 = require("@lucid-evolution/utils");
1523
1526
  var import_utils6 = require("@lucid-evolution/utils");
1527
+ var import_utils7 = require("@lucid-evolution/utils");
1524
1528
  var import_core_utils2 = require("@lucid-evolution/core-utils");
1525
1529
  var import_wallet = require("@lucid-evolution/wallet");
1530
+
1531
+ // src/internal/emulator-ledger.ts
1532
+ var import_utils5 = require("@lucid-evolution/utils");
1533
+ var isUnorderedKey = (key) => {
1534
+ if (key === "__proto__") return true;
1535
+ if (key.length > 10) return false;
1536
+ const index = Number(key);
1537
+ return Number.isInteger(index) && index < 2 ** 32 - 1 && String(index) === key;
1538
+ };
1539
+ var EmulatorLedger = class {
1540
+ #record = {};
1541
+ #exposed = false;
1542
+ /** Record keys in record order; `undefined` marks a deleted slot. */
1543
+ #keys = [];
1544
+ /** Record entries, parallel to `#keys`. */
1545
+ #entries = [];
1546
+ #slots = /* @__PURE__ */ new Map();
1547
+ #holes = 0;
1548
+ /** Per slot, the address whose payment hash `#slotHashes` holds. */
1549
+ #slotHashAddresses = [];
1550
+ #slotHashes = [];
1551
+ #paymentHashes = /* @__PURE__ */ new Map();
1552
+ /** The record, for internal reads that do not let it escape. */
1553
+ get record() {
1554
+ return this.#record;
1555
+ }
1556
+ /** Returns the record to a caller, who may then change it at any time. */
1557
+ expose() {
1558
+ this.#dropMirror();
1559
+ return this.#record;
1560
+ }
1561
+ /** Adopts a record supplied by a caller. */
1562
+ replace(record) {
1563
+ this.#record = record;
1564
+ this.#dropMirror();
1565
+ }
1566
+ get(outRef) {
1567
+ return this.#record[outRef];
1568
+ }
1569
+ set(outRef, entry) {
1570
+ this.#record[outRef] = entry;
1571
+ if (this.#exposed) return;
1572
+ if (isUnorderedKey(outRef)) {
1573
+ this.#dropMirror();
1574
+ return;
1575
+ }
1576
+ const slot = this.#slots.get(outRef);
1577
+ if (slot === void 0) {
1578
+ this.#slots.set(outRef, this.#keys.length);
1579
+ this.#keys.push(outRef);
1580
+ this.#entries.push(entry);
1581
+ this.#slotHashAddresses.push(void 0);
1582
+ this.#slotHashes.push(void 0);
1583
+ } else {
1584
+ this.#entries[slot] = entry;
1585
+ }
1586
+ }
1587
+ /**
1588
+ * Moves the mempool into the record, then deletes every entry marked
1589
+ * spent, as the emulator always has.
1590
+ */
1591
+ applyMempool(mempool) {
1592
+ for (const [outRef, { utxo, spent }] of Object.entries(mempool)) {
1593
+ this.set(outRef, { utxo, spent });
1594
+ }
1595
+ const record = this.#record;
1596
+ if (this.#exposed) {
1597
+ for (const [outRef, { spent }] of Object.entries(record)) {
1598
+ if (spent) delete record[outRef];
1599
+ }
1600
+ return;
1601
+ }
1602
+ const keys = this.#keys;
1603
+ const entries = this.#entries;
1604
+ for (let slot = 0; slot < entries.length; slot++) {
1605
+ const entry = entries[slot];
1606
+ if (entry === void 0 || !entry.spent) continue;
1607
+ const outRef = keys[slot];
1608
+ delete record[outRef];
1609
+ this.#slots.delete(outRef);
1610
+ keys[slot] = void 0;
1611
+ entries[slot] = void 0;
1612
+ this.#holes++;
1613
+ }
1614
+ if (this.#holes > 64 && this.#holes * 2 > entries.length) this.#compact();
1615
+ }
1616
+ /**
1617
+ * Unspent UTxOs at an address or payment credential, optionally holding
1618
+ * `unit`, in record order.
1619
+ */
1620
+ utxosAt(addressOrCredential, unit) {
1621
+ const utxos = [];
1622
+ const entries = this.#inOrder();
1623
+ if (typeof addressOrCredential === "string") {
1624
+ for (let i = 0; i < entries.length; i++) {
1625
+ const entry = entries[i];
1626
+ if (entry === void 0 && !this.#exposed) continue;
1627
+ const { utxo, spent } = entry;
1628
+ if (!spent && utxo.address === addressOrCredential && (unit === void 0 || utxo.assets[unit] > 0n)) {
1629
+ utxos.push(utxo);
1630
+ }
1631
+ }
1632
+ return utxos;
1633
+ }
1634
+ const hash = addressOrCredential.hash;
1635
+ const hashAddresses = this.#slotHashAddresses;
1636
+ const hashes = this.#slotHashes;
1637
+ for (let i = 0; i < entries.length; i++) {
1638
+ const entry = entries[i];
1639
+ if (entry === void 0 && !this.#exposed) continue;
1640
+ const { utxo, spent } = entry;
1641
+ if (spent) continue;
1642
+ const address = utxo.address;
1643
+ let paymentHash;
1644
+ if (this.#exposed) {
1645
+ paymentHash = this.#paymentHashOf(address);
1646
+ } else if (hashAddresses[i] === address) {
1647
+ paymentHash = hashes[i];
1648
+ } else {
1649
+ paymentHash = this.#paymentHashOf(address);
1650
+ hashAddresses[i] = address;
1651
+ hashes[i] = paymentHash;
1652
+ }
1653
+ if (paymentHash === hash && (unit === void 0 || utxo.assets[unit] > 0n)) {
1654
+ utxos.push(utxo);
1655
+ }
1656
+ }
1657
+ return utxos;
1658
+ }
1659
+ /** Unspent UTxOs holding `unit`, in record order. */
1660
+ utxosWithUnit(unit) {
1661
+ const utxos = [];
1662
+ const entries = this.#inOrder();
1663
+ for (let i = 0; i < entries.length; i++) {
1664
+ const entry = entries[i];
1665
+ if (entry === void 0 && !this.#exposed) continue;
1666
+ const { utxo, spent } = entry;
1667
+ if (!spent && utxo.assets[unit] > 0n) utxos.push(utxo);
1668
+ }
1669
+ return utxos;
1670
+ }
1671
+ /**
1672
+ * The record's entries in record order. From the mirror, deleted slots
1673
+ * are `undefined`; from an exposed record, every value is as stored, so a
1674
+ * malformed entry fails a query just as a scan of the record would.
1675
+ */
1676
+ #inOrder() {
1677
+ if (!this.#exposed) return this.#entries;
1678
+ const record = this.#record;
1679
+ const keys = Object.keys(record);
1680
+ const entries = new Array(keys.length);
1681
+ for (let i = 0; i < keys.length; i++) entries[i] = record[keys[i]];
1682
+ return entries;
1683
+ }
1684
+ /** Payment credential hash of an address; parse errors propagate. */
1685
+ #paymentHashOf(address) {
1686
+ if (this.#paymentHashes.has(address))
1687
+ return this.#paymentHashes.get(address);
1688
+ const hash = (0, import_utils5.getAddressDetails)(address).paymentCredential?.hash;
1689
+ this.#paymentHashes.set(address, hash);
1690
+ return hash;
1691
+ }
1692
+ #compact() {
1693
+ const keys = [];
1694
+ const entries = [];
1695
+ const hashAddresses = [];
1696
+ const hashes = [];
1697
+ this.#slots.clear();
1698
+ for (let slot = 0; slot < this.#entries.length; slot++) {
1699
+ const entry = this.#entries[slot];
1700
+ if (entry === void 0) continue;
1701
+ const outRef = this.#keys[slot];
1702
+ this.#slots.set(outRef, keys.length);
1703
+ keys.push(outRef);
1704
+ entries.push(entry);
1705
+ hashAddresses.push(this.#slotHashAddresses[slot]);
1706
+ hashes.push(this.#slotHashes[slot]);
1707
+ }
1708
+ this.#keys = keys;
1709
+ this.#entries = entries;
1710
+ this.#slotHashAddresses = hashAddresses;
1711
+ this.#slotHashes = hashes;
1712
+ this.#holes = 0;
1713
+ }
1714
+ #dropMirror() {
1715
+ this.#exposed = true;
1716
+ this.#keys = [];
1717
+ this.#entries = [];
1718
+ this.#slots.clear();
1719
+ this.#slotHashAddresses = [];
1720
+ this.#slotHashes = [];
1721
+ this.#holes = 0;
1722
+ }
1723
+ };
1724
+
1725
+ // src/emulator.ts
1526
1726
  var EMULATOR_PROVIDER_BRAND = Symbol.for(
1527
1727
  "@lucid-evolution/provider/Emulator"
1528
1728
  );
@@ -1545,7 +1745,7 @@ function generateEmulatorAccountFromPrivateKey(assets) {
1545
1745
  };
1546
1746
  }
1547
1747
  function generateEmulatorAccount(assets) {
1548
- const seedPhrase = (0, import_utils5.generateSeedPhrase)();
1748
+ const seedPhrase = (0, import_utils6.generateSeedPhrase)();
1549
1749
  return {
1550
1750
  seedPhrase,
1551
1751
  address: (0, import_wallet.walletFromSeed)(seedPhrase, {
@@ -1560,7 +1760,13 @@ function generateEmulatorAccount(assets) {
1560
1760
  var DEFAULT_PROTOCOL_MAJOR_VERSION = 11;
1561
1761
  var Emulator = class {
1562
1762
  [EMULATOR_PROVIDER_BRAND] = true;
1563
- ledger;
1763
+ #confirmed = new EmulatorLedger();
1764
+ #ledgerProperty = Object.defineProperty(this, "ledger", {
1765
+ configurable: true,
1766
+ enumerable: true,
1767
+ get: () => this.#confirmed.expose(),
1768
+ set: (entries) => this.#confirmed.replace(entries)
1769
+ });
1564
1770
  mempool = {};
1565
1771
  /**
1566
1772
  * Only stake key registrations/delegations and rewards are tracked.
@@ -1573,13 +1779,37 @@ var Emulator = class {
1573
1779
  protocolParameters;
1574
1780
  datumTable = {};
1575
1781
  treasury;
1576
- transactionHistory = {};
1577
- constructor(accounts, protocolParameters = import_utils5.PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1782
+ #history = {};
1783
+ /** Whether a caller holds `transactionHistory`, and may edit it. */
1784
+ #historyExposed = false;
1785
+ #historyProperty = Object.defineProperty(this, "transactionHistory", {
1786
+ configurable: true,
1787
+ enumerable: true,
1788
+ get: () => {
1789
+ this.#historyExposed = true;
1790
+ return this.#history;
1791
+ },
1792
+ set: (history) => {
1793
+ this.#historyExposed = true;
1794
+ this.#history = history;
1795
+ }
1796
+ });
1797
+ /**
1798
+ * Transactions submitted since the last block. While no caller holds
1799
+ * `transactionHistory`, these are its only pending entries.
1800
+ */
1801
+ #pendingTxHashes = [];
1802
+ /**
1803
+ * Script hashes of reference scripts, keyed by type and CBOR. A plain Map
1804
+ * keyed by long script text puts every script of the same length in one
1805
+ * hash bucket; `ScriptCache` keys a fingerprint and is bounded.
1806
+ */
1807
+ #scriptRefHashes = new import_utils7.ScriptCache(4096, 64 * 1024 * 1024);
1808
+ constructor(accounts, protocolParameters = import_utils6.PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1578
1809
  const GENESIS_HASH = "00".repeat(32);
1579
1810
  this.blockHeight = 0;
1580
1811
  this.slot = 0;
1581
1812
  this.time = Date.now();
1582
- this.ledger = {};
1583
1813
  accounts.forEach(({ address, assets, outputData }, index) => {
1584
1814
  if ([outputData?.hash, outputData?.asHash, outputData?.inline].filter(
1585
1815
  (b) => b
@@ -1588,7 +1818,7 @@ var Emulator = class {
1588
1818
  "Not allowed to set hash, asHash and inline at the same time."
1589
1819
  );
1590
1820
  }
1591
- this.ledger[GENESIS_HASH + index] = {
1821
+ this.#confirmed.set(GENESIS_HASH + index, {
1592
1822
  utxo: {
1593
1823
  txHash: GENESIS_HASH,
1594
1824
  outputIndex: index,
@@ -1601,7 +1831,7 @@ var Emulator = class {
1601
1831
  scriptRef: outputData?.scriptRef
1602
1832
  },
1603
1833
  spent: false
1604
- };
1834
+ });
1605
1835
  });
1606
1836
  this.protocolParameters = protocolParameters;
1607
1837
  this.treasury = treasury;
@@ -1609,16 +1839,28 @@ var Emulator = class {
1609
1839
  now() {
1610
1840
  return this.time;
1611
1841
  }
1842
+ /** Confirms every pending transaction in `transactionHistory`. */
1612
1843
  confirmPendingTransactions(blockHeight, slot) {
1613
- for (const [txHash, status] of Object.entries(this.transactionHistory)) {
1614
- if (status.status === "pending") {
1615
- this.transactionHistory[txHash] = {
1616
- status: "confirmed",
1617
- blockHeight,
1618
- slot
1619
- };
1844
+ const history = this.#history;
1845
+ if (this.#historyExposed) {
1846
+ for (const [txHash, { status }] of Object.entries(history)) {
1847
+ if (status === "pending") {
1848
+ history[txHash] = { status: "confirmed", blockHeight, slot };
1849
+ }
1850
+ }
1851
+ } else {
1852
+ for (const txHash of this.#pendingTxHashes) {
1853
+ if (history[txHash].status === "pending") {
1854
+ history[txHash] = { status: "confirmed", blockHeight, slot };
1855
+ }
1620
1856
  }
1621
1857
  }
1858
+ this.#pendingTxHashes = [];
1859
+ }
1860
+ /** Moves the mempool into the ledger and drops spent entries. */
1861
+ applyMempool() {
1862
+ this.#confirmed.applyMempool(this.mempool);
1863
+ this.mempool = {};
1622
1864
  }
1623
1865
  awaitSlot(length = 1) {
1624
1866
  this.slot += length;
@@ -1630,13 +1872,7 @@ var Emulator = class {
1630
1872
  currentHeight + 1,
1631
1873
  (currentHeight + 1) * 20
1632
1874
  );
1633
- for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1634
- this.ledger[outRef] = { utxo, spent };
1635
- }
1636
- for (const [outRef, { spent }] of Object.entries(this.ledger)) {
1637
- if (spent) delete this.ledger[outRef];
1638
- }
1639
- this.mempool = {};
1875
+ this.applyMempool();
1640
1876
  }
1641
1877
  }
1642
1878
  awaitBlock(height = 1) {
@@ -1648,27 +1884,10 @@ var Emulator = class {
1648
1884
  if (height > 0) {
1649
1885
  this.confirmPendingTransactions(previousHeight + 1, previousSlot + 20);
1650
1886
  }
1651
- for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1652
- this.ledger[outRef] = { utxo, spent };
1653
- }
1654
- for (const [outRef, { spent }] of Object.entries(this.ledger)) {
1655
- if (spent) delete this.ledger[outRef];
1656
- }
1657
- this.mempool = {};
1887
+ this.applyMempool();
1658
1888
  }
1659
1889
  getUtxos(addressOrCredential) {
1660
- const utxos = Object.values(this.ledger).flatMap(
1661
- ({ utxo, spent }) => {
1662
- if (spent) return [];
1663
- if (typeof addressOrCredential === "string") {
1664
- return addressOrCredential === utxo.address ? utxo : [];
1665
- } else {
1666
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
1667
- return paymentCredential?.hash === addressOrCredential.hash ? utxo : [];
1668
- }
1669
- }
1670
- );
1671
- return Promise.resolve(utxos);
1890
+ return Promise.resolve(this.#confirmed.utxosAt(addressOrCredential));
1672
1891
  }
1673
1892
  getProtocolParameters() {
1674
1893
  return Promise.resolve(this.protocolParameters);
@@ -1680,31 +1899,18 @@ var Emulator = class {
1680
1899
  return Promise.resolve(this.datumTable[datumHash]);
1681
1900
  }
1682
1901
  getUtxosWithUnit(addressOrCredential, unit) {
1683
- const utxos = Object.values(this.ledger).flatMap(
1684
- ({ utxo, spent }) => {
1685
- if (spent) return [];
1686
- if (typeof addressOrCredential === "string") {
1687
- return addressOrCredential === utxo.address && utxo.assets[unit] > 0n ? utxo : [];
1688
- } else {
1689
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
1690
- return paymentCredential?.hash === addressOrCredential.hash && utxo.assets[unit] > 0n ? utxo : [];
1691
- }
1692
- }
1693
- );
1694
- return Promise.resolve(utxos);
1902
+ return Promise.resolve(this.#confirmed.utxosAt(addressOrCredential, unit));
1695
1903
  }
1696
1904
  getUtxosByOutRef(outRefs) {
1697
1905
  return Promise.resolve(
1698
1906
  outRefs.flatMap((outRef) => {
1699
- const entry = this.ledger[outRef.txHash + outRef.outputIndex];
1907
+ const entry = this.#confirmed.get(outRef.txHash + outRef.outputIndex);
1700
1908
  return entry && !entry.spent ? entry.utxo : [];
1701
1909
  })
1702
1910
  );
1703
1911
  }
1704
1912
  getUtxoByUnit(unit) {
1705
- const utxos = Object.values(this.ledger).flatMap(
1706
- ({ utxo, spent }) => !spent && utxo.assets[unit] > 0n ? utxo : []
1707
- );
1913
+ const utxos = this.#confirmed.utxosWithUnit(unit);
1708
1914
  if (utxos.length > 1) {
1709
1915
  throw new Error("Unit needs to be an NFT or only held by one address.");
1710
1916
  }
@@ -1725,7 +1931,7 @@ var Emulator = class {
1725
1931
  });
1726
1932
  }
1727
1933
  awaitTx(txHash) {
1728
- if (this.transactionHistory[txHash]?.status === "pending") {
1934
+ if (this.#history[txHash]?.status === "pending") {
1729
1935
  this.awaitBlock();
1730
1936
  return Promise.resolve(true);
1731
1937
  }
@@ -1737,7 +1943,7 @@ var Emulator = class {
1737
1943
  options.signal.reason instanceof Error ? options.signal.reason : new DOMException("The operation was aborted.", "AbortError")
1738
1944
  );
1739
1945
  }
1740
- const status = this.transactionHistory[txHash];
1946
+ const status = this.#history[txHash];
1741
1947
  if (!status) return Promise.resolve({ status: "not_found", txHash });
1742
1948
  if (status.status === "pending") {
1743
1949
  return Promise.resolve({ status: "pending", txHash });
@@ -1775,10 +1981,14 @@ var Emulator = class {
1775
1981
  this.awaitBlock();
1776
1982
  }
1777
1983
  submitTx(tx) {
1778
- const desTx = CML.Transaction.from_cbor_hex(tx);
1779
- const body = desTx.body();
1780
- const witnesses = desTx.witness_set();
1781
- const datums = witnesses.plutus_datums();
1984
+ return (0, import_core_utils2.withCMLScope)((own) => Promise.resolve(this.applyTx(tx, own)));
1985
+ }
1986
+ /** Validates `tx` and applies it to the mempool; returns its hash. */
1987
+ applyTx(tx, own) {
1988
+ const desTx = own(CML.Transaction.from_cbor_hex(tx));
1989
+ const body = own(desTx.body());
1990
+ const witnesses = own(desTx.witness_set());
1991
+ const datums = own(witnesses.plutus_datums());
1782
1992
  const txHash = CML.hash_transaction(body).to_hex();
1783
1993
  const lowerBound = body.validity_interval_start() ? parseInt(body.validity_interval_start().toString()) : null;
1784
1994
  const upperBound = body.ttl() ? parseInt(body.ttl().toString()) : null;
@@ -1812,24 +2022,24 @@ var Emulator = class {
1812
2022
  const datumTable = (() => {
1813
2023
  const table = {};
1814
2024
  for (let i = 0; i < (datums?.len() || 0); i++) {
1815
- (0, import_core_utils2.withCMLScope)((own) => {
1816
- const datum = own(datums.get(i));
1817
- const datumHash = own(CML.hash_plutus_data(datum)).to_hex();
2025
+ (0, import_core_utils2.withCMLScope)((own2) => {
2026
+ const datum = own2(datums.get(i));
2027
+ const datumHash = own2(CML.hash_plutus_data(datum)).to_hex();
1818
2028
  table[datumHash] = datum.to_cbor_hex();
1819
2029
  });
1820
2030
  }
1821
2031
  return table;
1822
2032
  })();
1823
2033
  const consumedHashes = /* @__PURE__ */ new Set();
1824
- const keyHashes = (0, import_core_utils2.withCMLScope)((own) => {
2034
+ const keyHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1825
2035
  const keyHashes2 = [];
1826
- const vkeyWitnesses = own(witnesses.vkeywitnesses());
2036
+ const vkeyWitnesses = own2(witnesses.vkeywitnesses());
1827
2037
  for (let i = 0; i < (vkeyWitnesses?.len() || 0); i++) {
1828
- (0, import_core_utils2.withCMLScope)((own2) => {
1829
- const witness = own2(vkeyWitnesses.get(i));
1830
- const publicKey = own2(witness.vkey());
1831
- const keyHash = own2(publicKey.hash()).to_hex();
1832
- if (!publicKey.verify((0, import_core_utils2.fromHex)(txHash), own2(witness.ed25519_signature()))) {
2038
+ (0, import_core_utils2.withCMLScope)((own3) => {
2039
+ const witness = own3(vkeyWitnesses.get(i));
2040
+ const publicKey = own3(witness.vkey());
2041
+ const keyHash = own3(publicKey.hash()).to_hex();
2042
+ if (!publicKey.verify((0, import_core_utils2.fromHex)(txHash), own3(witness.ed25519_signature()))) {
1833
2043
  throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1834
2044
  }
1835
2045
  keyHashes2.push(keyHash);
@@ -1837,19 +2047,20 @@ var Emulator = class {
1837
2047
  }
1838
2048
  return keyHashes2;
1839
2049
  });
1840
- const edKeyHashes = CML.Ed25519KeyHashList.new();
1841
- keyHashes.forEach(
2050
+ const keyHashes = new Set(keyHashList);
2051
+ const edKeyHashes = own(CML.Ed25519KeyHashList.new());
2052
+ keyHashList.forEach(
1842
2053
  (keyHash) => (0, import_core_utils2.withCMLScope)(
1843
- (own) => edKeyHashes.add(own(CML.Ed25519KeyHash.from_hex(keyHash)))
2054
+ (own2) => edKeyHashes.add(own2(CML.Ed25519KeyHash.from_hex(keyHash)))
1844
2055
  )
1845
2056
  );
1846
- const nativeHashes = (0, import_core_utils2.withCMLScope)((own) => {
2057
+ const nativeHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1847
2058
  const scriptHashes = [];
1848
- const nativeScripts = own(witnesses.native_scripts());
2059
+ const nativeScripts = own2(witnesses.native_scripts());
1849
2060
  for (let i = 0; i < (nativeScripts?.len() || 0); i++) {
1850
- (0, import_core_utils2.withCMLScope)((own2) => {
1851
- const witness = own2(nativeScripts.get(i));
1852
- const scriptHash = own2(witness.hash()).to_hex();
2061
+ (0, import_core_utils2.withCMLScope)((own3) => {
2062
+ const witness = own3(nativeScripts.get(i));
2063
+ const scriptHash = own3(witness.hash()).to_hex();
1853
2064
  if (!witness.verify(
1854
2065
  Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
1855
2066
  Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
@@ -1859,9 +2070,9 @@ var Emulator = class {
1859
2070
  `Invalid native script witness. Script hash: ${scriptHash}`
1860
2071
  );
1861
2072
  }
1862
- const requiredSigners = own2(witness.get_required_signers());
1863
- for (let j = 0; j < requiredSigners.len(); j++) {
1864
- const keyHash = own2(requiredSigners.get(j)).to_hex();
2073
+ const requiredSigners2 = own3(witness.get_required_signers());
2074
+ for (let j = 0; j < requiredSigners2.len(); j++) {
2075
+ const keyHash = own3(requiredSigners2.get(j)).to_hex();
1865
2076
  consumedHashes.add(keyHash);
1866
2077
  }
1867
2078
  scriptHashes.push(scriptHash);
@@ -1869,18 +2080,18 @@ var Emulator = class {
1869
2080
  }
1870
2081
  return scriptHashes;
1871
2082
  });
1872
- edKeyHashes.free();
2083
+ const nativeHashes = new Set(nativeHashList);
1873
2084
  const nativeHashesOptional = {};
1874
- const plutusHashesOptional = [];
2085
+ const plutusHashesOptional = /* @__PURE__ */ new Set();
1875
2086
  const plutusV3Hashes = /* @__PURE__ */ new Set();
1876
- const plutusHashes = (0, import_core_utils2.withCMLScope)((own) => {
2087
+ const plutusHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1877
2088
  const scriptHashes = [];
1878
2089
  const collectHashes = (scripts, isPlutusV3 = false) => {
1879
- own(scripts);
2090
+ own2(scripts);
1880
2091
  for (let i = 0; i < (scripts?.len() || 0); i++) {
1881
- (0, import_core_utils2.withCMLScope)((own2) => {
1882
- const script = own2(scripts.get(i));
1883
- const scriptHash = own2(script.hash()).to_hex();
2092
+ (0, import_core_utils2.withCMLScope)((own3) => {
2093
+ const script = own3(scripts.get(i));
2094
+ const scriptHash = own3(script.hash()).to_hex();
1884
2095
  scriptHashes.push(scriptHash);
1885
2096
  if (isPlutusV3) plutusV3Hashes.add(scriptHash);
1886
2097
  });
@@ -1891,16 +2102,26 @@ var Emulator = class {
1891
2102
  collectHashes(witnesses.plutus_v3_scripts(), true);
1892
2103
  return scriptHashes;
1893
2104
  });
1894
- const inputs = body.inputs();
2105
+ const plutusHashes = new Set(plutusHashList);
2106
+ const collectScriptRef = (scriptRef) => {
2107
+ const scriptHash = this.scriptRefHash(scriptRef);
2108
+ if (scriptRef.type === "Native") {
2109
+ nativeHashesOptional[scriptHash] = scriptRef.script;
2110
+ return;
2111
+ }
2112
+ plutusHashesOptional.add(scriptHash);
2113
+ if (scriptRef.type === "PlutusV3") plutusV3Hashes.add(scriptHash);
2114
+ };
2115
+ const inputs = own(body.inputs());
1895
2116
  const resolvedInputs = [];
1896
2117
  const inputOutRefs = /* @__PURE__ */ new Set();
1897
2118
  for (let i = 0; i < inputs.len(); i++) {
1898
- const outRef = (0, import_core_utils2.withCMLScope)((own) => {
1899
- const input = own(inputs.get(i));
1900
- return own(input.transaction_id()).to_hex() + input.index().toString();
2119
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2120
+ const input = own2(inputs.get(i));
2121
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
1901
2122
  });
1902
2123
  inputOutRefs.add(outRef);
1903
- const entryLedger = this.ledger[outRef];
2124
+ const entryLedger = this.#confirmed.get(outRef);
1904
2125
  const { entry, type } = !entryLedger ? { entry: this.mempool[outRef], type: "Mempool" } : { entry: entryLedger, type: "Ledger" };
1905
2126
  if (!entry || entry.spent) {
1906
2127
  throw new Error(
@@ -1912,52 +2133,18 @@ It does not exist or was already spent.`
1912
2133
  );
1913
2134
  }
1914
2135
  const scriptRef = entry.utxo.scriptRef;
1915
- if (scriptRef) {
1916
- switch (scriptRef.type) {
1917
- case "Native": {
1918
- const script = CML.NativeScript.from_cbor_bytes(
1919
- (0, import_core_utils2.fromHex)(scriptRef.script)
1920
- );
1921
- nativeHashesOptional[script.hash().to_hex()] = script;
1922
- break;
1923
- }
1924
- case "PlutusV1": {
1925
- const script = CML.PlutusScript.from_v1(
1926
- CML.PlutusV1Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1927
- );
1928
- plutusHashesOptional.push(script.hash().to_hex());
1929
- break;
1930
- }
1931
- case "PlutusV2": {
1932
- const script = CML.PlutusScript.from_v2(
1933
- CML.PlutusV2Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1934
- );
1935
- plutusHashesOptional.push(script.hash().to_hex());
1936
- break;
1937
- }
1938
- case "PlutusV3": {
1939
- const script = CML.PlutusScript.from_v3(
1940
- CML.PlutusV3Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1941
- );
1942
- const scriptHash = script.hash().to_hex();
1943
- plutusHashesOptional.push(scriptHash);
1944
- plutusV3Hashes.add(scriptHash);
1945
- break;
1946
- }
1947
- }
1948
- }
2136
+ if (scriptRef) collectScriptRef(scriptRef);
1949
2137
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1950
2138
  resolvedInputs.push({ entry, type });
1951
2139
  }
1952
- inputs.free();
1953
- const referenceInputs = body.reference_inputs();
2140
+ const referenceInputs = own(body.reference_inputs());
1954
2141
  const nonDisjointRefInputs = [];
1955
2142
  for (let i = 0; i < (referenceInputs?.len() || 0); i++) {
1956
- const outRef = (0, import_core_utils2.withCMLScope)((own) => {
1957
- const input = own(referenceInputs.get(i));
1958
- return own(input.transaction_id()).to_hex() + input.index().toString();
2143
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2144
+ const input = own2(referenceInputs.get(i));
2145
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
1959
2146
  });
1960
- const entry = this.ledger[outRef] || this.mempool[outRef];
2147
+ const entry = this.#confirmed.get(outRef) || this.mempool[outRef];
1961
2148
  if (!entry || entry.spent) {
1962
2149
  throw new Error(
1963
2150
  `Could not read UTxO: ${JSON.stringify({
@@ -1973,44 +2160,11 @@ It does not exist or was already spent.`
1973
2160
  );
1974
2161
  }
1975
2162
  const scriptRef = entry.utxo.scriptRef;
1976
- if (scriptRef) {
1977
- switch (scriptRef.type) {
1978
- case "Native": {
1979
- const script = CML.NativeScript.from_cbor_bytes(
1980
- (0, import_core_utils2.fromHex)(scriptRef.script)
1981
- );
1982
- nativeHashesOptional[script.hash().to_hex()] = script;
1983
- break;
1984
- }
1985
- case "PlutusV1": {
1986
- const script = CML.PlutusScript.from_v1(
1987
- CML.PlutusV1Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1988
- );
1989
- plutusHashesOptional.push(script.hash().to_hex());
1990
- break;
1991
- }
1992
- case "PlutusV2": {
1993
- const script = CML.PlutusScript.from_v2(
1994
- CML.PlutusV2Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
1995
- );
1996
- plutusHashesOptional.push(script.hash().to_hex());
1997
- break;
1998
- }
1999
- case "PlutusV3": {
2000
- const script = CML.PlutusScript.from_v3(
2001
- CML.PlutusV3Script.from_cbor_bytes((0, import_core_utils2.fromHex)(scriptRef.script))
2002
- );
2003
- const scriptHash = script.hash().to_hex();
2004
- plutusHashesOptional.push(scriptHash);
2005
- plutusV3Hashes.add(scriptHash);
2006
- break;
2007
- }
2008
- }
2009
- }
2163
+ if (scriptRef) collectScriptRef(scriptRef);
2010
2164
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
2011
2165
  }
2012
- referenceInputs?.free();
2013
- const redeemers = (() => {
2166
+ const redeemerKey = (tag, index) => `${tag}:${index}`;
2167
+ const redeemers = (0, import_core_utils2.withCMLScope)((own2) => {
2014
2168
  const tagMap = {
2015
2169
  0: "Spend",
2016
2170
  1: "Mint",
@@ -2019,35 +2173,33 @@ It does not exist or was already spent.`
2019
2173
  4: "Proposing",
2020
2174
  5: "Voting"
2021
2175
  };
2022
- const collected = [];
2023
- const redeemers2 = witnesses.redeemers();
2024
- const arrLegacyRedeemer = redeemers2?.as_arr_legacy_redeemer();
2176
+ const collected = /* @__PURE__ */ new Set();
2177
+ const redeemers2 = own2(witnesses.redeemers());
2178
+ const arrLegacyRedeemer = own2(redeemers2?.as_arr_legacy_redeemer());
2025
2179
  if (arrLegacyRedeemer) {
2026
2180
  for (let i = 0; i < (arrLegacyRedeemer.len() || 0); i++) {
2027
- const redeemer = arrLegacyRedeemer.get(i);
2028
- collected.push({
2029
- tag: tagMap[redeemer.tag()],
2030
- index: Number(redeemer.index())
2031
- });
2181
+ const redeemer = own2(arrLegacyRedeemer.get(i));
2182
+ collected.add(
2183
+ redeemerKey(tagMap[redeemer.tag()], Number(redeemer.index()))
2184
+ );
2032
2185
  }
2033
2186
  }
2034
- const mapRedeemerKeyToRedeemerVal = redeemers2?.as_map_redeemer_key_to_redeemer_val();
2187
+ const mapRedeemerKeyToRedeemerVal = own2(
2188
+ redeemers2?.as_map_redeemer_key_to_redeemer_val()
2189
+ );
2035
2190
  if (mapRedeemerKeyToRedeemerVal) {
2036
- const keys = mapRedeemerKeyToRedeemerVal.keys();
2191
+ const keys = own2(mapRedeemerKeyToRedeemerVal.keys());
2037
2192
  for (let i = 0; i < (keys.len() || 0); i++) {
2038
- const key = keys.get(i);
2039
- collected.push({
2040
- tag: tagMap[key.tag()],
2041
- index: Number(key.index())
2042
- });
2193
+ const key = own2(keys.get(i));
2194
+ collected.add(redeemerKey(tagMap[key.tag()], Number(key.index())));
2043
2195
  }
2044
2196
  }
2045
2197
  return collected;
2046
- })();
2198
+ });
2047
2199
  function checkAndConsumeHash(credential, tag, index) {
2048
2200
  switch (credential.type) {
2049
2201
  case "Key": {
2050
- if (!keyHashes.includes(credential.hash)) {
2202
+ if (!keyHashes.has(credential.hash)) {
2051
2203
  throw new Error(
2052
2204
  `Missing vkey witness. Key hash: ${credential.hash}`
2053
2205
  );
@@ -2056,28 +2208,29 @@ It does not exist or was already spent.`
2056
2208
  break;
2057
2209
  }
2058
2210
  case "Script": {
2059
- if (nativeHashes.includes(credential.hash)) {
2211
+ if (nativeHashes.has(credential.hash)) {
2060
2212
  consumedHashes.add(credential.hash);
2061
2213
  break;
2062
2214
  } else if (nativeHashesOptional[credential.hash]) {
2063
- if (!nativeHashesOptional[credential.hash].verify(
2064
- Number.isInteger(lowerBound) ? CML.BigInteger.from_str(
2065
- lowerBound.toString()
2066
- ).to_js_value() : void 0,
2067
- Number.isInteger(upperBound) ? CML.BigInteger.from_str(
2068
- upperBound.toString()
2069
- ).to_js_value() : void 0,
2070
- edKeyHashes
2071
- )) {
2215
+ const valid = (0, import_core_utils2.withCMLScope)(
2216
+ (own2) => own2(
2217
+ CML.NativeScript.from_cbor_hex(
2218
+ nativeHashesOptional[credential.hash]
2219
+ )
2220
+ ).verify(
2221
+ Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
2222
+ Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
2223
+ edKeyHashes
2224
+ )
2225
+ );
2226
+ if (!valid) {
2072
2227
  throw new Error(
2073
2228
  `Invalid native script witness. Script hash: ${credential.hash}`
2074
2229
  );
2075
2230
  }
2076
2231
  break;
2077
- } else if (plutusHashes.includes(credential.hash) || plutusHashesOptional.includes(credential.hash)) {
2078
- if (redeemers.find(
2079
- (redeemer) => redeemer.tag === tag && redeemer.index === index
2080
- )) {
2232
+ } else if (plutusHashes.has(credential.hash) || plutusHashesOptional.has(credential.hash)) {
2233
+ if (redeemers.has(redeemerKey(tag, index))) {
2081
2234
  consumedHashes.add(credential.hash);
2082
2235
  break;
2083
2236
  }
@@ -2088,13 +2241,14 @@ It does not exist or was already spent.`
2088
2241
  }
2089
2242
  }
2090
2243
  }
2091
- const collateralInputs = body.collateral_inputs();
2244
+ const collateralInputs = own(body.collateral_inputs());
2245
+ const collateralBalance = {};
2092
2246
  for (let i = 0; i < (collateralInputs?.len() || 0); i++) {
2093
- const outRef = (0, import_core_utils2.withCMLScope)((own) => {
2094
- const input = own(collateralInputs.get(i));
2095
- return own(input.transaction_id()).to_hex() + input.index().toString();
2247
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2248
+ const input = own2(collateralInputs.get(i));
2249
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
2096
2250
  });
2097
- const entry = this.ledger[outRef] || this.mempool[outRef];
2251
+ const entry = this.#confirmed.get(outRef) || this.mempool[outRef];
2098
2252
  if (!entry || entry.spent) {
2099
2253
  throw new Error(
2100
2254
  `Could not read UTxO: ${JSON.stringify({
@@ -2104,19 +2258,27 @@ It does not exist or was already spent.`
2104
2258
  It does not exist or was already spent.`
2105
2259
  );
2106
2260
  }
2107
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(entry.utxo.address);
2261
+ const { paymentCredential } = (0, import_utils7.getAddressDetails)(entry.utxo.address);
2108
2262
  if (paymentCredential?.type === "Script") {
2109
2263
  throw new Error("Collateral inputs can only contain vkeys.");
2110
2264
  }
2111
2265
  checkAndConsumeHash(paymentCredential, null, null);
2266
+ for (const [unit, amount] of Object.entries(entry.utxo.assets)) {
2267
+ collateralBalance[unit] = (collateralBalance[unit] ?? 0n) + amount;
2268
+ }
2112
2269
  }
2113
- collateralInputs?.free();
2114
- for (let i = 0; i < (body.required_signers()?.len() || 0); i++) {
2115
- const signer = body.required_signers().get(i);
2270
+ if (redeemers.size > 0) {
2271
+ this.checkCollateral(body, collateralBalance, own);
2272
+ }
2273
+ const requiredSigners = own(body.required_signers());
2274
+ for (let i = 0; i < (requiredSigners?.len() || 0); i++) {
2275
+ const signer = own(requiredSigners.get(i));
2116
2276
  checkAndConsumeHash({ type: "Key", hash: signer.to_hex() }, null, null);
2117
2277
  }
2118
- for (let index = 0; index < (body.mint()?.keys().len() || 0); index++) {
2119
- const policyId = body.mint().keys().get(index).to_hex();
2278
+ const mint = own(body.mint());
2279
+ const policyIds = own(mint?.keys());
2280
+ for (let index = 0; index < (policyIds?.len() || 0); index++) {
2281
+ const policyId = own(policyIds.get(index)).to_hex();
2120
2282
  checkAndConsumeHash({ type: "Script", hash: policyId }, "Mint", index);
2121
2283
  }
2122
2284
  const withdrawalRequests = [];
@@ -2126,7 +2288,7 @@ It does not exist or was already spent.`
2126
2288
  body.withdrawals().get(rawAddress).toString()
2127
2289
  );
2128
2290
  const rewardAddress = rawAddress.to_address().to_bech32(void 0);
2129
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2291
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2130
2292
  checkAndConsumeHash(stakeCredential, "Reward", index);
2131
2293
  if (this.chain[rewardAddress]?.delegation.rewards !== withdrawal) {
2132
2294
  throw new Error(
@@ -2165,7 +2327,7 @@ It does not exist or was already spent.`
2165
2327
  CML.NetworkInfo.testnet().network_id(),
2166
2328
  registration.stake_credential()
2167
2329
  ).to_address().to_bech32(void 0);
2168
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2330
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2169
2331
  checkAndConsumeHash(stakeCredential, "Cert", index);
2170
2332
  if (this.chain[rewardAddress]?.registeredStake) {
2171
2333
  throw new Error(
@@ -2181,7 +2343,7 @@ It does not exist or was already spent.`
2181
2343
  CML.NetworkInfo.testnet().network_id(),
2182
2344
  deregistration.stake_credential()
2183
2345
  ).to_address().to_bech32(void 0);
2184
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2346
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2185
2347
  checkAndConsumeHash(stakeCredential, "Cert", index);
2186
2348
  if (!this.chain[rewardAddress]?.registeredStake) {
2187
2349
  throw new Error(
@@ -2198,7 +2360,7 @@ It does not exist or was already spent.`
2198
2360
  delegation.stake_credential()
2199
2361
  ).to_address().to_bech32(void 0);
2200
2362
  const poolId = delegation.pool().to_bech32("pool");
2201
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2363
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2202
2364
  checkAndConsumeHash(stakeCredential, "Cert", index);
2203
2365
  if (!this.chain[rewardAddress]?.registeredStake && !certRequests.find(
2204
2366
  (request) => request.type === "Registration" && request.rewardAddress === rewardAddress
@@ -2373,26 +2535,26 @@ It does not exist or was already spent.`
2373
2535
  }
2374
2536
  }
2375
2537
  resolvedInputs.forEach(({ entry: { utxo } }, index) => {
2376
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
2538
+ const { paymentCredential } = (0, import_utils7.getAddressDetails)(utxo.address);
2377
2539
  checkAndConsumeHash(paymentCredential, "Spend", index);
2378
2540
  });
2379
- const outputs = (0, import_core_utils2.withCMLScope)((own) => {
2541
+ const outputs = (0, import_core_utils2.withCMLScope)((own2) => {
2380
2542
  const collected = [];
2381
- const bodyOutputs = own(body.outputs());
2543
+ const bodyOutputs = own2(body.outputs());
2382
2544
  for (let i = 0; i < bodyOutputs.len(); i++) {
2383
- const output = own(bodyOutputs.get(i));
2384
- const unspentOutput = own(
2545
+ const output = own2(bodyOutputs.get(i));
2546
+ const unspentOutput = own2(
2385
2547
  CML.TransactionUnspentOutput.new(
2386
- own(
2548
+ own2(
2387
2549
  CML.TransactionInput.new(
2388
- own(CML.TransactionHash.from_hex(txHash)),
2550
+ own2(CML.TransactionHash.from_hex(txHash)),
2389
2551
  BigInt(i)
2390
2552
  )
2391
2553
  ),
2392
2554
  output
2393
2555
  )
2394
2556
  );
2395
- const utxo = (0, import_utils6.coreToUtxo)(unspentOutput);
2557
+ const utxo = (0, import_utils7.coreToUtxo)(unspentOutput);
2396
2558
  if (utxo.datumHash) consumedHashes.add(utxo.datumHash);
2397
2559
  collected.push({
2398
2560
  utxo,
@@ -2401,13 +2563,13 @@ It does not exist or was already spent.`
2401
2563
  }
2402
2564
  return collected;
2403
2565
  });
2404
- const [extraKeyHash] = keyHashes.filter(
2566
+ const [extraKeyHash] = keyHashList.filter(
2405
2567
  (keyHash) => !consumedHashes.has(keyHash)
2406
2568
  );
2407
2569
  if (extraKeyHash) {
2408
2570
  throw new Error(`Extraneous vkey witness. Key hash: ${extraKeyHash}`);
2409
2571
  }
2410
- const [extraNativeHash] = nativeHashes.filter(
2572
+ const [extraNativeHash] = nativeHashList.filter(
2411
2573
  (scriptHash) => !consumedHashes.has(scriptHash)
2412
2574
  );
2413
2575
  if (extraNativeHash) {
@@ -2415,7 +2577,7 @@ It does not exist or was already spent.`
2415
2577
  `Extraneous native script. Script hash: ${extraNativeHash}`
2416
2578
  );
2417
2579
  }
2418
- const [extraPlutusHash] = plutusHashes.filter(
2580
+ const [extraPlutusHash] = plutusHashList.filter(
2419
2581
  (scriptHash) => !consumedHashes.has(scriptHash)
2420
2582
  );
2421
2583
  if (extraPlutusHash) {
@@ -2446,11 +2608,8 @@ It does not exist or was already spent.`
2446
2608
  );
2447
2609
  }
2448
2610
  }
2449
- resolvedInputs.forEach(({ entry, type }) => {
2450
- const outRef = entry.utxo.txHash + entry.utxo.outputIndex;
2611
+ resolvedInputs.forEach(({ entry }) => {
2451
2612
  entry.spent = true;
2452
- if (type === "Ledger") this.ledger[outRef] = entry;
2453
- else if (type === "Mempool") this.mempool[outRef] = entry;
2454
2613
  });
2455
2614
  withdrawalRequests.forEach(({ rewardAddress, withdrawal }) => {
2456
2615
  this.chain[rewardAddress].delegation.rewards -= withdrawal;
@@ -2490,9 +2649,115 @@ It does not exist or was already spent.`
2490
2649
  for (const [datumHash, datum] of Object.entries(datumTable)) {
2491
2650
  this.datumTable[datumHash] = datum;
2492
2651
  }
2493
- this.transactionHistory[txHash] = { status: "pending" };
2494
- (0, import_core_utils2.freeCML)(datums, witnesses, body, desTx);
2495
- return Promise.resolve(txHash);
2652
+ this.#history[txHash] = { status: "pending" };
2653
+ this.#pendingTxHashes.push(txHash);
2654
+ return txHash;
2655
+ }
2656
+ /**
2657
+ * The ledger's collateral rules for a transaction with redeemers: at least
2658
+ * one and at most `maxCollateralInputs` collateral inputs, a balance (inputs
2659
+ * minus the collateral return) of ADA only that covers
2660
+ * `collateralPercentage` of the fee, a `total_collateral` field, when
2661
+ * present, equal to that balance, and a collateral return holding at least
2662
+ * its minimum ADA.
2663
+ */
2664
+ checkCollateral(body, collateralBalance, own) {
2665
+ const inputCount = own(body.collateral_inputs())?.len() ?? 0;
2666
+ if (inputCount === 0) {
2667
+ throw new Error(
2668
+ "NoCollateralInputs: a transaction that runs scripts needs collateral inputs."
2669
+ );
2670
+ }
2671
+ const { maxCollateralInputs, collateralPercentage } = this.protocolParameters;
2672
+ if (inputCount > maxCollateralInputs) {
2673
+ throw new Error(
2674
+ `TooManyCollateralInputs: ${inputCount} collateral inputs, but at most ${maxCollateralInputs} are allowed.`
2675
+ );
2676
+ }
2677
+ const balance = { ...collateralBalance };
2678
+ const collateralReturn = own(body.collateral_return());
2679
+ if (collateralReturn) {
2680
+ const minLovelace = CML.min_ada_required(
2681
+ collateralReturn,
2682
+ this.protocolParameters.coinsPerUtxoByte
2683
+ );
2684
+ const returnedLovelace = own(collateralReturn.amount()).coin();
2685
+ if (returnedLovelace < minLovelace) {
2686
+ throw new Error(
2687
+ `BabbageOutputTooSmallUTxO: collateral return holds ${returnedLovelace} Lovelace, but needs at least ${minLovelace} Lovelace.`
2688
+ );
2689
+ }
2690
+ const returned = (0, import_utils7.valueToAssets)(own(collateralReturn.amount()));
2691
+ for (const [unit, amount] of Object.entries(returned)) {
2692
+ balance[unit] = (balance[unit] ?? 0n) - amount;
2693
+ }
2694
+ }
2695
+ const nonAda = Object.entries(balance).filter(
2696
+ ([unit, amount]) => unit !== "lovelace" && amount !== 0n
2697
+ );
2698
+ if (nonAda.length > 0) {
2699
+ throw new Error(
2700
+ `CollateralContainsNonADA: collateral balance holds ${nonAda.map(([unit, amount]) => `${amount} ${unit}`).join(", ")}.`
2701
+ );
2702
+ }
2703
+ const collateral = balance.lovelace ?? 0n;
2704
+ const fee = body.fee();
2705
+ if (collateral * 100n < fee * BigInt(collateralPercentage)) {
2706
+ const required = (fee * BigInt(collateralPercentage) + 99n) / 100n;
2707
+ throw new Error(
2708
+ `InsufficientCollateral: collateral balance is ${collateral} Lovelace, but the fee of ${fee} requires ${required} Lovelace (${collateralPercentage}%).`
2709
+ );
2710
+ }
2711
+ const totalCollateral = body.total_collateral();
2712
+ if (totalCollateral !== void 0 && totalCollateral !== collateral) {
2713
+ throw new Error(
2714
+ `IncorrectTotalCollateralField: total collateral is ${totalCollateral} Lovelace, but the collateral balance is ${collateral} Lovelace.`
2715
+ );
2716
+ }
2717
+ }
2718
+ /** Hash of a reference script, computed once per distinct script. */
2719
+ scriptRefHash(scriptRef) {
2720
+ let scriptHash = this.#scriptRefHashes.get(
2721
+ scriptRef.type,
2722
+ scriptRef.script
2723
+ );
2724
+ if (scriptHash === void 0) {
2725
+ scriptHash = (0, import_core_utils2.withCMLScope)((own) => {
2726
+ const bytes = (0, import_core_utils2.fromHex)(scriptRef.script);
2727
+ switch (scriptRef.type) {
2728
+ case "Native":
2729
+ return own(
2730
+ own(CML.NativeScript.from_cbor_bytes(bytes)).hash()
2731
+ ).to_hex();
2732
+ case "PlutusV1":
2733
+ return own(
2734
+ own(
2735
+ CML.PlutusScript.from_v1(
2736
+ own(CML.PlutusV1Script.from_cbor_bytes(bytes))
2737
+ )
2738
+ ).hash()
2739
+ ).to_hex();
2740
+ case "PlutusV2":
2741
+ return own(
2742
+ own(
2743
+ CML.PlutusScript.from_v2(
2744
+ own(CML.PlutusV2Script.from_cbor_bytes(bytes))
2745
+ )
2746
+ ).hash()
2747
+ ).to_hex();
2748
+ case "PlutusV3":
2749
+ return own(
2750
+ own(
2751
+ CML.PlutusScript.from_v3(
2752
+ own(CML.PlutusV3Script.from_cbor_bytes(bytes))
2753
+ )
2754
+ ).hash()
2755
+ ).to_hex();
2756
+ }
2757
+ });
2758
+ this.#scriptRefHashes.set(scriptRef.type, scriptRef.script, scriptHash);
2759
+ }
2760
+ return scriptHash;
2496
2761
  }
2497
2762
  async evaluateTx(tx, additionalUTxOs) {
2498
2763
  return (0, import_core_utils2.withCMLScope)((own) => {
@@ -2513,7 +2778,7 @@ It does not exist or was already spent.`
2513
2778
  steps: Number(exUnits.steps())
2514
2779
  },
2515
2780
  redeemer_index: Number(legacyRedeemer.index()),
2516
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(legacyRedeemer.tag())
2781
+ redeemer_tag: (0, import_utils6.fromCMLRedeemerTag)(legacyRedeemer.tag())
2517
2782
  });
2518
2783
  }
2519
2784
  return evalRedeemers;
@@ -2534,7 +2799,7 @@ It does not exist or was already spent.`
2534
2799
  steps: Number(exUnits.steps())
2535
2800
  },
2536
2801
  redeemer_index: Number(key.index()),
2537
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(key.tag())
2802
+ redeemer_tag: (0, import_utils6.fromCMLRedeemerTag)(key.tag())
2538
2803
  });
2539
2804
  }
2540
2805
  }
@@ -2557,7 +2822,7 @@ It does not exist or was already spent.`
2557
2822
  }
2558
2823
  const totalBalances = {};
2559
2824
  const balances = {};
2560
- for (const { utxo } of Object.values(this.ledger)) {
2825
+ for (const { utxo } of Object.values(this.#confirmed.record)) {
2561
2826
  for (const [unit, quantity] of Object.entries(utxo.assets)) {
2562
2827
  if (!balances[utxo.address]) {
2563
2828
  balances[utxo.address] = { [unit]: quantity };
@@ -2610,367 +2875,8 @@ ${"\u2581".repeat(60)}
2610
2875
  }
2611
2876
  };
2612
2877
 
2613
- // src/maestro.ts
2614
- var import_utils7 = require("@lucid-evolution/utils");
2615
- var import_core_utils3 = require("@lucid-evolution/core-utils");
2616
- var Maestro = class {
2617
- url;
2618
- apiKey;
2619
- turboSubmit;
2620
- constructor({ network, apiKey, turboSubmit = false }) {
2621
- this.url = `https://${network}.gomaestro-api.org/v1`;
2622
- this.apiKey = apiKey;
2623
- this.turboSubmit = turboSubmit;
2624
- }
2625
- async getProtocolParameters() {
2626
- const timestampedResult = await fetch(`${this.url}/protocol-parameters`, {
2627
- headers: this.commonHeaders()
2628
- }).then((res) => res.json());
2629
- const result = timestampedResult.data;
2630
- const decimalFromRationalString = (str) => {
2631
- const forwardSlashIndex = str.indexOf("/");
2632
- return parseInt(str.slice(0, forwardSlashIndex)) / parseInt(str.slice(forwardSlashIndex + 1));
2633
- };
2634
- return {
2635
- protocolMajorVersion: result.version?.major,
2636
- protocolMinorVersion: result.version?.minor,
2637
- minFeeA: parseInt(result.min_fee_coefficient),
2638
- minFeeB: parseInt(result.min_fee_constant.ada.lovelace),
2639
- maxTxSize: parseInt(result.max_transaction_size.bytes),
2640
- maxValSize: parseInt(result.max_value_size.bytes),
2641
- keyDeposit: BigInt(result.stake_credential_deposit.ada.lovelace),
2642
- poolDeposit: BigInt(result.stake_pool_deposit.ada.lovelace),
2643
- drepDeposit: BigInt(result.delegate_representative_deposit.ada.lovelace),
2644
- govActionDeposit: BigInt(result.governance_action_deposit.ada.lovelace),
2645
- priceMem: decimalFromRationalString(
2646
- result.script_execution_prices.memory
2647
- ),
2648
- priceStep: decimalFromRationalString(result.script_execution_prices.cpu),
2649
- maxTxExMem: BigInt(result.max_execution_units_per_transaction.memory),
2650
- maxTxExSteps: BigInt(result.max_execution_units_per_transaction.cpu),
2651
- coinsPerUtxoByte: BigInt(result.min_utxo_deposit_coefficient),
2652
- collateralPercentage: parseInt(result.collateral_percentage),
2653
- maxCollateralInputs: parseInt(result.max_collateral_inputs),
2654
- minFeeRefScriptCostPerByte: parseInt(
2655
- result.min_fee_reference_scripts.base
2656
- ),
2657
- costModels: {
2658
- PlutusV1: result.plutus_cost_models.plutus_v1,
2659
- PlutusV2: result.plutus_cost_models.plutus_v2,
2660
- PlutusV3: result.plutus_cost_models.plutus_v3
2661
- }
2662
- };
2663
- }
2664
- async getTreasury() {
2665
- throw new Error(
2666
- "Maestro does not expose a current treasury query. Pass currentTreasuryValue explicitly to donateToTreasury."
2667
- );
2668
- }
2669
- async getUtxosInternal(addressOrCredential, unit) {
2670
- const queryPredicate = (() => {
2671
- if (typeof addressOrCredential === "string") {
2672
- return "/addresses/" + addressOrCredential;
2673
- }
2674
- let credentialBech32Query = "/addresses/cred/";
2675
- credentialBech32Query += addressOrCredential.type === "Key" ? CML.Ed25519KeyHash.from_hex(addressOrCredential.hash).to_bech32(
2676
- "addr_vkh"
2677
- ) : CML.ScriptHash.from_hex(addressOrCredential.hash).to_bech32(
2678
- "addr_shared_vkh"
2679
- );
2680
- return credentialBech32Query;
2681
- })();
2682
- const qparams = new URLSearchParams({
2683
- count: "100",
2684
- ...unit && { asset: unit }
2685
- });
2686
- const result = await this.getAllPagesData(
2687
- async (qry) => await fetch(qry, {
2688
- headers: this.requireAmountsAsStrings(this.commonHeaders())
2689
- }),
2690
- `${this.url}${queryPredicate}/utxos`,
2691
- qparams,
2692
- "Location: getUtxosInternal. Error: Could not fetch UTxOs from Maestro"
2693
- );
2694
- return result.map(this.maestroUtxoToUtxo);
2695
- }
2696
- getUtxos(addressOrCredential) {
2697
- return this.getUtxosInternal(addressOrCredential);
2698
- }
2699
- getUtxosWithUnit(addressOrCredential, unit) {
2700
- return this.getUtxosInternal(addressOrCredential, unit);
2701
- }
2702
- async getUtxoByUnit(unit) {
2703
- const timestampedAddressesResponse = await fetch(
2704
- `${this.url}/assets/${unit}/addresses?count=2`,
2705
- { headers: this.commonHeaders() }
2706
- );
2707
- const timestampedAddresses = await timestampedAddressesResponse.json();
2708
- if (!timestampedAddressesResponse.ok) {
2709
- if (timestampedAddresses.message) {
2710
- throw new Error(timestampedAddresses.message);
2711
- }
2712
- throw new Error(
2713
- "Location: getUtxoByUnit. Error: Couldn't perform query. Received status code: " + timestampedAddressesResponse.status
2714
- );
2715
- }
2716
- const addressesWithAmount = timestampedAddresses.data;
2717
- if (addressesWithAmount.length === 0) {
2718
- throw new Error("Location: getUtxoByUnit. Error: Unit not found.");
2719
- }
2720
- if (addressesWithAmount.length > 1) {
2721
- throw new Error(
2722
- "Location: getUtxoByUnit. Error: Unit needs to be an NFT or only held by one address."
2723
- );
2724
- }
2725
- const address = addressesWithAmount[0].address;
2726
- const utxos = await this.getUtxosWithUnit(address, unit);
2727
- if (utxos.length > 1) {
2728
- throw new Error(
2729
- "Location: getUtxoByUnit. Error: Unit needs to be an NFT or only held by one address."
2730
- );
2731
- }
2732
- return utxos[0];
2733
- }
2734
- async getUtxosByOutRef(outRefs) {
2735
- const qry = `${this.url}/transactions/outputs`;
2736
- const body = JSON.stringify(
2737
- outRefs.map(({ txHash, outputIndex }) => `${txHash}#${outputIndex}`)
2738
- );
2739
- const utxos = await this.getAllPagesData(
2740
- async (qry2) => await fetch(qry2, {
2741
- method: "POST",
2742
- headers: {
2743
- "Content-Type": "application/json",
2744
- ...this.requireAmountsAsStrings(this.commonHeaders())
2745
- },
2746
- body
2747
- }),
2748
- qry,
2749
- new URLSearchParams({}),
2750
- "Location: getUtxosByOutRef. Error: Could not fetch UTxOs by references from Maestro"
2751
- );
2752
- return utxos.map(this.maestroUtxoToUtxo);
2753
- }
2754
- async getRewardAccount(rewardAddress) {
2755
- const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
2756
- headers: this.requireAmountsAsStrings(this.commonHeaders())
2757
- });
2758
- if (response.status === 404) {
2759
- return { registered: false, poolId: null, rewards: 0n };
2760
- }
2761
- if (!response.ok) {
2762
- throw new Error(
2763
- `Could not fetch reward account from Maestro. Received status code: ${response.status}`
2764
- );
2765
- }
2766
- const timestampedResult = await response.json();
2767
- const result = timestampedResult.data;
2768
- return {
2769
- registered: result.registered,
2770
- poolId: result.delegated_pool || null,
2771
- rewards: BigInt(result.rewards_available)
2772
- };
2773
- }
2774
- async getDelegation(rewardAddress) {
2775
- const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
2776
- return { poolId, rewards };
2777
- }
2778
- async getDatum(datumHash) {
2779
- const timestampedResultResponse = await fetch(
2780
- `${this.url}/datums/${datumHash}`,
2781
- {
2782
- headers: this.commonHeaders()
2783
- }
2784
- );
2785
- if (!timestampedResultResponse.ok) {
2786
- if (timestampedResultResponse.status === 404) {
2787
- throw new Error(`No datum found for datum hash: ${datumHash}`);
2788
- } else {
2789
- throw new Error(
2790
- "Location: getDatum. Error: Couldn't successfully perform query. Received status code: " + timestampedResultResponse.status
2791
- );
2792
- }
2793
- }
2794
- const timestampedResult = await timestampedResultResponse.json();
2795
- return timestampedResult.data.bytes;
2796
- }
2797
- awaitTx(txHash, checkInterval = 3e3) {
2798
- return new Promise((res) => {
2799
- const confirmation = setInterval(async () => {
2800
- const isConfirmedResponse = await fetch(
2801
- `${this.url}/transactions/${txHash}/cbor`,
2802
- {
2803
- headers: this.commonHeaders()
2804
- }
2805
- );
2806
- if (isConfirmedResponse.ok) {
2807
- await isConfirmedResponse.json();
2808
- clearInterval(confirmation);
2809
- await new Promise((res2) => setTimeout(() => res2(1), 1e3));
2810
- return res(true);
2811
- }
2812
- }, checkInterval);
2813
- });
2814
- }
2815
- async getTransactionStatus(txHash, options = {}) {
2816
- const response = await fetch(`${this.url}/txmanager/${txHash}/state`, {
2817
- headers: this.commonHeaders(),
2818
- signal: options.signal
2819
- });
2820
- if (response.status === 404) return { status: "not_found", txHash };
2821
- if (!response.ok) {
2822
- throw new Error(
2823
- `Could not fetch transaction status from Maestro. Received status code: ${response.status}`
2824
- );
2825
- }
2826
- const result = await response.json();
2827
- switch (result.status) {
2828
- case "pending":
2829
- return { status: "pending", txHash };
2830
- case "confirmed":
2831
- return {
2832
- status: "confirmed",
2833
- txHash,
2834
- confirmation: {
2835
- txHash,
2836
- confirmations: result.confirmations
2837
- }
2838
- };
2839
- case "failed":
2840
- return {
2841
- status: "failed",
2842
- txHash,
2843
- reason: result.reason ?? result.error
2844
- };
2845
- default:
2846
- throw new Error(
2847
- `Maestro returned an unknown transaction status: ${String(result.status)}`
2848
- );
2849
- }
2850
- }
2851
- async submitTx(tx) {
2852
- let queryUrl = `${this.url}/txmanager`;
2853
- queryUrl += this.turboSubmit ? "/turbosubmit" : "";
2854
- const response = await fetch(queryUrl, {
2855
- method: "POST",
2856
- headers: {
2857
- "Content-Type": "application/cbor",
2858
- Accept: "text/plain",
2859
- ...this.commonHeaders()
2860
- },
2861
- body: (0, import_core_utils3.fromHex)(tx)
2862
- });
2863
- const result = await response.text();
2864
- if (!response.ok) {
2865
- if (response.status === 400) throw new Error(result);
2866
- else {
2867
- throw new Error(
2868
- "Could not submit transaction. Received status code: " + response.status
2869
- );
2870
- }
2871
- }
2872
- return result;
2873
- }
2874
- commonHeaders() {
2875
- return { "api-key": this.apiKey, lucid: lucid2 };
2876
- }
2877
- requireAmountsAsStrings(obj) {
2878
- return { ...obj, "amounts-as-strings": "true" };
2879
- }
2880
- maestroUtxoToUtxo(result) {
2881
- return {
2882
- txHash: result.tx_hash,
2883
- outputIndex: result.index,
2884
- assets: (() => {
2885
- const a = {};
2886
- result.assets.forEach((am) => {
2887
- a[am.unit] = BigInt(am.amount);
2888
- });
2889
- return a;
2890
- })(),
2891
- address: result.address,
2892
- datumHash: result.datum ? result.datum.type == "inline" ? void 0 : result.datum.hash : void 0,
2893
- datum: result.datum?.bytes,
2894
- scriptRef: toScriptRef2(result.reference_script)
2895
- };
2896
- }
2897
- async getAllPagesData(getResponse, qry, paramsGiven, errorMsg) {
2898
- let nextCursor = null;
2899
- let result = [];
2900
- while (true) {
2901
- if (nextCursor !== null) {
2902
- paramsGiven.set("cursor", nextCursor);
2903
- }
2904
- const response = await getResponse(`${qry}?` + paramsGiven);
2905
- const pageResult = await response.json();
2906
- if (!response.ok) {
2907
- throw new Error(
2908
- `${errorMsg}. Received status code: ${response.status}`
2909
- );
2910
- }
2911
- nextCursor = pageResult.next_cursor;
2912
- result = result.concat(pageResult.data);
2913
- if (nextCursor == null) break;
2914
- }
2915
- return result;
2916
- }
2917
- async evaluateTx(tx, additionalUTxOs) {
2918
- const additionalMaestroUTxOs = (additionalUTxOs || []).map((utxo) => ({
2919
- tx_hash: utxo.txHash,
2920
- index: utxo.outputIndex,
2921
- txout_cbor: (0, import_utils7.utxoToCore)(utxo).output().to_cbor_hex()
2922
- }));
2923
- const payload = {
2924
- cbor: tx,
2925
- additional_utxos: additionalMaestroUTxOs
2926
- };
2927
- const res = await fetch(`${this.url}/transactions/evaluate`, {
2928
- method: "POST",
2929
- headers: {
2930
- "Content-Type": "application/json",
2931
- Accept: "application/json",
2932
- "api-key": this.apiKey
2933
- },
2934
- body: JSON.stringify(payload)
2935
- });
2936
- if (!res.ok) {
2937
- const body = await res.text();
2938
- console.error("Response error:", JSON.stringify(res));
2939
- throw new Error(`Evaluate transaction failed: ${body}`);
2940
- }
2941
- const result = await res.json();
2942
- return result;
2943
- }
2944
- };
2945
- var toScriptRef2 = (reference_script) => {
2946
- if (reference_script && reference_script.bytes) {
2947
- switch (reference_script.type) {
2948
- case "native":
2949
- return (0, import_utils7.scriptFromNative)(reference_script.json);
2950
- case "plutusv1":
2951
- return {
2952
- type: "PlutusV1",
2953
- script: (0, import_utils7.applyDoubleCborEncoding)(reference_script.bytes)
2954
- };
2955
- case "plutusv2":
2956
- return {
2957
- type: "PlutusV2",
2958
- script: (0, import_utils7.applyDoubleCborEncoding)(reference_script.bytes)
2959
- };
2960
- case "plutusv3":
2961
- return {
2962
- type: "PlutusV3",
2963
- script: (0, import_utils7.applyDoubleCborEncoding)(reference_script.bytes)
2964
- };
2965
- default:
2966
- return void 0;
2967
- }
2968
- }
2969
- };
2970
- var lucid2 = package_default.version;
2971
-
2972
2878
  // src/koios.ts
2973
- var import_core_utils4 = require("@lucid-evolution/core-utils");
2879
+ var import_core_utils3 = require("@lucid-evolution/core-utils");
2974
2880
  var import_utils9 = require("@lucid-evolution/utils");
2975
2881
 
2976
2882
  // src/internal/koios.ts
@@ -3224,9 +3130,9 @@ var toUTxO = (koiosUTxO, address) => ({
3224
3130
  address,
3225
3131
  datumHash: koiosUTxO.inline_datum ? void 0 : koiosUTxO.datum_hash || void 0,
3226
3132
  datum: koiosUTxO.inline_datum ? koiosUTxO.inline_datum.bytes : void 0,
3227
- scriptRef: toScriptRef3(koiosUTxO.reference_script)
3133
+ scriptRef: toScriptRef2(koiosUTxO.reference_script)
3228
3134
  });
3229
- var toScriptRef3 = (reference_script) => {
3135
+ var toScriptRef2 = (reference_script) => {
3230
3136
  if (reference_script && reference_script.bytes && reference_script.type) {
3231
3137
  switch (reference_script.type) {
3232
3138
  case "plutusV1":
@@ -3555,7 +3461,7 @@ var Koios = class {
3555
3461
  }
3556
3462
  async submitTx(tx) {
3557
3463
  const url = `${this.baseUrl}/submittx`;
3558
- const body = (0, import_core_utils4.fromHex)(tx);
3464
+ const body = (0, import_core_utils3.fromHex)(tx);
3559
3465
  const schema = TxHashSchema;
3560
3466
  const bearerToken = this.token ? { Authorization: `Bearer ${this.token}` } : void 0;
3561
3467
  const result = await (0, import_effect8.pipe)(
@@ -3608,7 +3514,6 @@ var Koios = class {
3608
3514
  KoiosError,
3609
3515
  Kupmios,
3610
3516
  KupmiosError,
3611
- Maestro,
3612
3517
  OgmiosJsonRpcError,
3613
3518
  generateEmulatorAccount,
3614
3519
  generateEmulatorAccountFromPrivateKey,