@lucid-evolution/provider 0.2.6 → 0.4.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,
@@ -135,7 +134,7 @@ var OgmiosJsonRpcError = class extends KupmiosError {
135
134
  var toKupmiosError = (cause, protocol, operation) => cause instanceof KupmiosError ? cause : new KupmiosError({ cause, protocol, operation });
136
135
 
137
136
  // src/core.ts
138
- var CML = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1);
137
+ var CML = __toESM(require("@lucid-evolution/cml"), 1);
139
138
 
140
139
  // src/blockfrost.ts
141
140
  var import_core_utils = require("@lucid-evolution/core-utils");
@@ -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.6",
146
+ version: "0.4.0",
148
147
  description: "",
149
148
  main: "./dist/index.js",
150
149
  types: "./dist/index.d.ts",
@@ -170,14 +169,10 @@ var package_default = {
170
169
  keywords: [],
171
170
  author: "",
172
171
  license: "MIT",
173
- browser: {
174
- "@anastasia-labs/cardano-multiplatform-lib-nodejs": "@anastasia-labs/cardano-multiplatform-lib-browser"
175
- },
176
172
  dependencies: {
177
- "@anastasia-labs/cardano-multiplatform-lib-browser": "6.2.0-1",
178
- "@anastasia-labs/cardano-multiplatform-lib-nodejs": "6.2.0-1",
179
173
  "@effect/platform": "^0.71.3",
180
174
  "@effect/schema": "^0.68.26",
175
+ "@lucid-evolution/cml": "workspace:*",
181
176
  "@lucid-evolution/core-types": "workspace:*",
182
177
  "@lucid-evolution/core-utils": "workspace:*",
183
178
  "@lucid-evolution/utils": "workspace:*",
@@ -1067,6 +1062,7 @@ var Kupmios = class {
1067
1062
  options;
1068
1063
  requestTimeoutMs;
1069
1064
  awaitTxTimeoutMs;
1065
+ httpLayer;
1070
1066
  constructor(kupoUrl, ogmiosUrl, options = {}) {
1071
1067
  this.kupoUrl = kupoUrl;
1072
1068
  this.ogmiosUrl = ogmiosUrl;
@@ -1079,6 +1075,10 @@ var Kupmios = class {
1079
1075
  "awaitTxTimeoutMs",
1080
1076
  options.awaitTxTimeoutMs ?? DEFAULT_AWAIT_TX_TIMEOUT_MS
1081
1077
  );
1078
+ this.httpLayer = options.fetchImpl === void 0 ? import_platform2.FetchHttpClient.layer : import_effect6.Layer.provide(
1079
+ import_platform2.FetchHttpClient.layer,
1080
+ import_effect6.Layer.succeed(import_platform2.FetchHttpClient.Fetch, options.fetchImpl)
1081
+ );
1082
1082
  }
1083
1083
  async getProtocolParameters() {
1084
1084
  const data = {
@@ -1100,7 +1100,7 @@ var Kupmios = class {
1100
1100
  ),
1101
1101
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1102
1102
  catchProviderError("ogmios", "queryLedgerState/protocolParameters"),
1103
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1103
+ import_effect6.Effect.provide(this.httpLayer)
1104
1104
  ),
1105
1105
  "ogmios",
1106
1106
  "queryLedgerState/protocolParameters"
@@ -1135,7 +1135,7 @@ var Kupmios = class {
1135
1135
  ),
1136
1136
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1137
1137
  catchProviderError("ogmios", "queryLedgerState/treasuryAndReserves"),
1138
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1138
+ import_effect6.Effect.provide(this.httpLayer)
1139
1139
  ),
1140
1140
  "ogmios",
1141
1141
  "queryLedgerState/treasuryAndReserves"
@@ -1158,7 +1158,7 @@ var Kupmios = class {
1158
1158
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1159
1159
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1160
1160
  catchProviderError("kupo", "getUtxos"),
1161
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1161
+ import_effect6.Effect.provide(this.httpLayer)
1162
1162
  ),
1163
1163
  "kupo",
1164
1164
  "getUtxos"
@@ -1177,7 +1177,7 @@ var Kupmios = class {
1177
1177
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1178
1178
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1179
1179
  catchProviderError("kupo", "getUtxosWithUnit"),
1180
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1180
+ import_effect6.Effect.provide(this.httpLayer)
1181
1181
  ),
1182
1182
  "kupo",
1183
1183
  "getUtxosWithUnit"
@@ -1201,7 +1201,7 @@ var Kupmios = class {
1201
1201
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1202
1202
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1203
1203
  catchProviderError("kupo", "getUtxosWithPolicy"),
1204
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1204
+ import_effect6.Effect.provide(this.httpLayer)
1205
1205
  ),
1206
1206
  "kupo",
1207
1207
  "getUtxosWithPolicy"
@@ -1217,7 +1217,7 @@ var Kupmios = class {
1217
1217
  import_effect6.Effect.map(kupmiosUtxosToUtxos),
1218
1218
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1219
1219
  catchProviderError("kupo", "getUtxoByUnit"),
1220
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1220
+ import_effect6.Effect.provide(this.httpLayer)
1221
1221
  ),
1222
1222
  "kupo",
1223
1223
  "getUtxoByUnit"
@@ -1246,7 +1246,7 @@ var Kupmios = class {
1246
1246
  )
1247
1247
  );
1248
1248
  const utxos = await runProviderEffect(
1249
- (0, import_effect6.pipe)(program, import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)),
1249
+ (0, import_effect6.pipe)(program, import_effect6.Effect.provide(this.httpLayer)),
1250
1250
  "kupo",
1251
1251
  "getUtxosByOutRef"
1252
1252
  );
@@ -1272,7 +1272,7 @@ var Kupmios = class {
1272
1272
  schema,
1273
1273
  this.options.ogmiosHeader
1274
1274
  ),
1275
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1275
+ import_effect6.Effect.provide(this.httpLayer),
1276
1276
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1277
1277
  catchProviderError("ogmios", "queryLedgerState/rewardAccountSummaries")
1278
1278
  ),
@@ -1296,7 +1296,7 @@ var Kupmios = class {
1296
1296
  const result = await runProviderEffect(
1297
1297
  (0, import_effect6.pipe)(
1298
1298
  makeGet(pattern, schema, this.options.kupoHeader),
1299
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1299
+ import_effect6.Effect.provide(this.httpLayer),
1300
1300
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1301
1301
  import_effect6.Effect.flatMap(import_effect6.Effect.fromNullable),
1302
1302
  catchProviderError("kupo", "getDatum")
@@ -1316,7 +1316,7 @@ var Kupmios = class {
1316
1316
  makeGet(pattern, schema, this.options.kupoHeader),
1317
1317
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1318
1318
  catchProviderError("kupo", "getTransactionStatus"),
1319
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
1319
+ import_effect6.Effect.provide(this.httpLayer)
1320
1320
  ),
1321
1321
  "kupo",
1322
1322
  "getTransactionStatus",
@@ -1342,7 +1342,7 @@ var Kupmios = class {
1342
1342
  const result = await runProviderEffect(
1343
1343
  (0, import_effect6.pipe)(
1344
1344
  makeGet(pattern, schema, this.options.kupoHeader),
1345
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1345
+ import_effect6.Effect.provide(this.httpLayer),
1346
1346
  import_effect6.Effect.repeat({
1347
1347
  schedule: import_effect6.Schedule.exponential(checkInterval),
1348
1348
  until: (result2) => result2.length > 0
@@ -1380,7 +1380,7 @@ var Kupmios = class {
1380
1380
  schema,
1381
1381
  this.options.ogmiosHeader
1382
1382
  ),
1383
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1383
+ import_effect6.Effect.provide(this.httpLayer),
1384
1384
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1385
1385
  catchProviderError("ogmios", "submitTransaction")
1386
1386
  ),
@@ -1413,7 +1413,7 @@ var Kupmios = class {
1413
1413
  schema,
1414
1414
  this.options.ogmiosHeader
1415
1415
  ),
1416
- import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
1416
+ import_effect6.Effect.provide(this.httpLayer),
1417
1417
  import_effect6.Effect.timeout(this.requestTimeoutMs),
1418
1418
  catchProviderError("ogmios", "evaluateTransaction")
1419
1419
  ),
@@ -1519,10 +1519,206 @@ var kupmiosUtxosToUtxos = (utxos) => utxos.map((utxo) => ({
1519
1519
  }));
1520
1520
 
1521
1521
  // src/emulator.ts
1522
- var import_utils5 = require("@lucid-evolution/utils");
1523
1522
  var import_utils6 = require("@lucid-evolution/utils");
1523
+ var import_utils7 = require("@lucid-evolution/utils");
1524
1524
  var import_core_utils2 = require("@lucid-evolution/core-utils");
1525
1525
  var import_wallet = require("@lucid-evolution/wallet");
1526
+
1527
+ // src/internal/emulator-ledger.ts
1528
+ var import_utils5 = require("@lucid-evolution/utils");
1529
+ var isUnorderedKey = (key) => {
1530
+ if (key === "__proto__") return true;
1531
+ if (key.length > 10) return false;
1532
+ const index = Number(key);
1533
+ return Number.isInteger(index) && index < 2 ** 32 - 1 && String(index) === key;
1534
+ };
1535
+ var EmulatorLedger = class {
1536
+ #record = {};
1537
+ #exposed = false;
1538
+ /** Record keys in record order; `undefined` marks a deleted slot. */
1539
+ #keys = [];
1540
+ /** Record entries, parallel to `#keys`. */
1541
+ #entries = [];
1542
+ #slots = /* @__PURE__ */ new Map();
1543
+ #holes = 0;
1544
+ /** Per slot, the address whose payment hash `#slotHashes` holds. */
1545
+ #slotHashAddresses = [];
1546
+ #slotHashes = [];
1547
+ #paymentHashes = /* @__PURE__ */ new Map();
1548
+ /** The record, for internal reads that do not let it escape. */
1549
+ get record() {
1550
+ return this.#record;
1551
+ }
1552
+ /** Returns the record to a caller, who may then change it at any time. */
1553
+ expose() {
1554
+ this.#dropMirror();
1555
+ return this.#record;
1556
+ }
1557
+ /** Adopts a record supplied by a caller. */
1558
+ replace(record) {
1559
+ this.#record = record;
1560
+ this.#dropMirror();
1561
+ }
1562
+ get(outRef) {
1563
+ return this.#record[outRef];
1564
+ }
1565
+ set(outRef, entry) {
1566
+ this.#record[outRef] = entry;
1567
+ if (this.#exposed) return;
1568
+ if (isUnorderedKey(outRef)) {
1569
+ this.#dropMirror();
1570
+ return;
1571
+ }
1572
+ const slot = this.#slots.get(outRef);
1573
+ if (slot === void 0) {
1574
+ this.#slots.set(outRef, this.#keys.length);
1575
+ this.#keys.push(outRef);
1576
+ this.#entries.push(entry);
1577
+ this.#slotHashAddresses.push(void 0);
1578
+ this.#slotHashes.push(void 0);
1579
+ } else {
1580
+ this.#entries[slot] = entry;
1581
+ }
1582
+ }
1583
+ /**
1584
+ * Moves the mempool into the record, then deletes every entry marked
1585
+ * spent, as the emulator always has.
1586
+ */
1587
+ applyMempool(mempool) {
1588
+ for (const [outRef, { utxo, spent }] of Object.entries(mempool)) {
1589
+ this.set(outRef, { utxo, spent });
1590
+ }
1591
+ const record = this.#record;
1592
+ if (this.#exposed) {
1593
+ for (const [outRef, { spent }] of Object.entries(record)) {
1594
+ if (spent) delete record[outRef];
1595
+ }
1596
+ return;
1597
+ }
1598
+ const keys = this.#keys;
1599
+ const entries = this.#entries;
1600
+ for (let slot = 0; slot < entries.length; slot++) {
1601
+ const entry = entries[slot];
1602
+ if (entry === void 0 || !entry.spent) continue;
1603
+ const outRef = keys[slot];
1604
+ delete record[outRef];
1605
+ this.#slots.delete(outRef);
1606
+ keys[slot] = void 0;
1607
+ entries[slot] = void 0;
1608
+ this.#holes++;
1609
+ }
1610
+ if (this.#holes > 64 && this.#holes * 2 > entries.length) this.#compact();
1611
+ }
1612
+ /**
1613
+ * Unspent UTxOs at an address or payment credential, optionally holding
1614
+ * `unit`, in record order.
1615
+ */
1616
+ utxosAt(addressOrCredential, unit) {
1617
+ const utxos = [];
1618
+ const entries = this.#inOrder();
1619
+ if (typeof addressOrCredential === "string") {
1620
+ for (let i = 0; i < entries.length; i++) {
1621
+ const entry = entries[i];
1622
+ if (entry === void 0 && !this.#exposed) continue;
1623
+ const { utxo, spent } = entry;
1624
+ if (!spent && utxo.address === addressOrCredential && (unit === void 0 || utxo.assets[unit] > 0n)) {
1625
+ utxos.push(utxo);
1626
+ }
1627
+ }
1628
+ return utxos;
1629
+ }
1630
+ const hash = addressOrCredential.hash;
1631
+ const hashAddresses = this.#slotHashAddresses;
1632
+ const hashes = this.#slotHashes;
1633
+ for (let i = 0; i < entries.length; i++) {
1634
+ const entry = entries[i];
1635
+ if (entry === void 0 && !this.#exposed) continue;
1636
+ const { utxo, spent } = entry;
1637
+ if (spent) continue;
1638
+ const address = utxo.address;
1639
+ let paymentHash;
1640
+ if (this.#exposed) {
1641
+ paymentHash = this.#paymentHashOf(address);
1642
+ } else if (hashAddresses[i] === address) {
1643
+ paymentHash = hashes[i];
1644
+ } else {
1645
+ paymentHash = this.#paymentHashOf(address);
1646
+ hashAddresses[i] = address;
1647
+ hashes[i] = paymentHash;
1648
+ }
1649
+ if (paymentHash === hash && (unit === void 0 || utxo.assets[unit] > 0n)) {
1650
+ utxos.push(utxo);
1651
+ }
1652
+ }
1653
+ return utxos;
1654
+ }
1655
+ /** Unspent UTxOs holding `unit`, in record order. */
1656
+ utxosWithUnit(unit) {
1657
+ const utxos = [];
1658
+ const entries = this.#inOrder();
1659
+ for (let i = 0; i < entries.length; i++) {
1660
+ const entry = entries[i];
1661
+ if (entry === void 0 && !this.#exposed) continue;
1662
+ const { utxo, spent } = entry;
1663
+ if (!spent && utxo.assets[unit] > 0n) utxos.push(utxo);
1664
+ }
1665
+ return utxos;
1666
+ }
1667
+ /**
1668
+ * The record's entries in record order. From the mirror, deleted slots
1669
+ * are `undefined`; from an exposed record, every value is as stored, so a
1670
+ * malformed entry fails a query just as a scan of the record would.
1671
+ */
1672
+ #inOrder() {
1673
+ if (!this.#exposed) return this.#entries;
1674
+ const record = this.#record;
1675
+ const keys = Object.keys(record);
1676
+ const entries = new Array(keys.length);
1677
+ for (let i = 0; i < keys.length; i++) entries[i] = record[keys[i]];
1678
+ return entries;
1679
+ }
1680
+ /** Payment credential hash of an address; parse errors propagate. */
1681
+ #paymentHashOf(address) {
1682
+ if (this.#paymentHashes.has(address))
1683
+ return this.#paymentHashes.get(address);
1684
+ const hash = (0, import_utils5.getAddressDetails)(address).paymentCredential?.hash;
1685
+ this.#paymentHashes.set(address, hash);
1686
+ return hash;
1687
+ }
1688
+ #compact() {
1689
+ const keys = [];
1690
+ const entries = [];
1691
+ const hashAddresses = [];
1692
+ const hashes = [];
1693
+ this.#slots.clear();
1694
+ for (let slot = 0; slot < this.#entries.length; slot++) {
1695
+ const entry = this.#entries[slot];
1696
+ if (entry === void 0) continue;
1697
+ const outRef = this.#keys[slot];
1698
+ this.#slots.set(outRef, keys.length);
1699
+ keys.push(outRef);
1700
+ entries.push(entry);
1701
+ hashAddresses.push(this.#slotHashAddresses[slot]);
1702
+ hashes.push(this.#slotHashes[slot]);
1703
+ }
1704
+ this.#keys = keys;
1705
+ this.#entries = entries;
1706
+ this.#slotHashAddresses = hashAddresses;
1707
+ this.#slotHashes = hashes;
1708
+ this.#holes = 0;
1709
+ }
1710
+ #dropMirror() {
1711
+ this.#exposed = true;
1712
+ this.#keys = [];
1713
+ this.#entries = [];
1714
+ this.#slots.clear();
1715
+ this.#slotHashAddresses = [];
1716
+ this.#slotHashes = [];
1717
+ this.#holes = 0;
1718
+ }
1719
+ };
1720
+
1721
+ // src/emulator.ts
1526
1722
  var EMULATOR_PROVIDER_BRAND = Symbol.for(
1527
1723
  "@lucid-evolution/provider/Emulator"
1528
1724
  );
@@ -1545,7 +1741,7 @@ function generateEmulatorAccountFromPrivateKey(assets) {
1545
1741
  };
1546
1742
  }
1547
1743
  function generateEmulatorAccount(assets) {
1548
- const seedPhrase = (0, import_utils5.generateSeedPhrase)();
1744
+ const seedPhrase = (0, import_utils6.generateSeedPhrase)();
1549
1745
  return {
1550
1746
  seedPhrase,
1551
1747
  address: (0, import_wallet.walletFromSeed)(seedPhrase, {
@@ -1560,7 +1756,13 @@ function generateEmulatorAccount(assets) {
1560
1756
  var DEFAULT_PROTOCOL_MAJOR_VERSION = 11;
1561
1757
  var Emulator = class {
1562
1758
  [EMULATOR_PROVIDER_BRAND] = true;
1563
- ledger;
1759
+ #confirmed = new EmulatorLedger();
1760
+ #ledgerProperty = Object.defineProperty(this, "ledger", {
1761
+ configurable: true,
1762
+ enumerable: true,
1763
+ get: () => this.#confirmed.expose(),
1764
+ set: (entries) => this.#confirmed.replace(entries)
1765
+ });
1564
1766
  mempool = {};
1565
1767
  /**
1566
1768
  * Only stake key registrations/delegations and rewards are tracked.
@@ -1573,13 +1775,37 @@ var Emulator = class {
1573
1775
  protocolParameters;
1574
1776
  datumTable = {};
1575
1777
  treasury;
1576
- transactionHistory = {};
1577
- constructor(accounts, protocolParameters = import_utils5.PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1778
+ #history = {};
1779
+ /** Whether a caller holds `transactionHistory`, and may edit it. */
1780
+ #historyExposed = false;
1781
+ #historyProperty = Object.defineProperty(this, "transactionHistory", {
1782
+ configurable: true,
1783
+ enumerable: true,
1784
+ get: () => {
1785
+ this.#historyExposed = true;
1786
+ return this.#history;
1787
+ },
1788
+ set: (history) => {
1789
+ this.#historyExposed = true;
1790
+ this.#history = history;
1791
+ }
1792
+ });
1793
+ /**
1794
+ * Transactions submitted since the last block. While no caller holds
1795
+ * `transactionHistory`, these are its only pending entries.
1796
+ */
1797
+ #pendingTxHashes = [];
1798
+ /**
1799
+ * Script hashes of reference scripts, keyed by type and CBOR. A plain Map
1800
+ * keyed by long script text puts every script of the same length in one
1801
+ * hash bucket; `ScriptCache` keys a fingerprint and is bounded.
1802
+ */
1803
+ #scriptRefHashes = new import_utils7.ScriptCache(4096, 64 * 1024 * 1024);
1804
+ constructor(accounts, protocolParameters = import_utils6.PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1578
1805
  const GENESIS_HASH = "00".repeat(32);
1579
1806
  this.blockHeight = 0;
1580
1807
  this.slot = 0;
1581
1808
  this.time = Date.now();
1582
- this.ledger = {};
1583
1809
  accounts.forEach(({ address, assets, outputData }, index) => {
1584
1810
  if ([outputData?.hash, outputData?.asHash, outputData?.inline].filter(
1585
1811
  (b) => b
@@ -1588,7 +1814,7 @@ var Emulator = class {
1588
1814
  "Not allowed to set hash, asHash and inline at the same time."
1589
1815
  );
1590
1816
  }
1591
- this.ledger[GENESIS_HASH + index] = {
1817
+ this.#confirmed.set(GENESIS_HASH + index, {
1592
1818
  utxo: {
1593
1819
  txHash: GENESIS_HASH,
1594
1820
  outputIndex: index,
@@ -1601,7 +1827,7 @@ var Emulator = class {
1601
1827
  scriptRef: outputData?.scriptRef
1602
1828
  },
1603
1829
  spent: false
1604
- };
1830
+ });
1605
1831
  });
1606
1832
  this.protocolParameters = protocolParameters;
1607
1833
  this.treasury = treasury;
@@ -1609,16 +1835,28 @@ var Emulator = class {
1609
1835
  now() {
1610
1836
  return this.time;
1611
1837
  }
1838
+ /** Confirms every pending transaction in `transactionHistory`. */
1612
1839
  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
- };
1840
+ const history = this.#history;
1841
+ if (this.#historyExposed) {
1842
+ for (const [txHash, { status }] of Object.entries(history)) {
1843
+ if (status === "pending") {
1844
+ history[txHash] = { status: "confirmed", blockHeight, slot };
1845
+ }
1846
+ }
1847
+ } else {
1848
+ for (const txHash of this.#pendingTxHashes) {
1849
+ if (history[txHash].status === "pending") {
1850
+ history[txHash] = { status: "confirmed", blockHeight, slot };
1851
+ }
1620
1852
  }
1621
1853
  }
1854
+ this.#pendingTxHashes = [];
1855
+ }
1856
+ /** Moves the mempool into the ledger and drops spent entries. */
1857
+ applyMempool() {
1858
+ this.#confirmed.applyMempool(this.mempool);
1859
+ this.mempool = {};
1622
1860
  }
1623
1861
  awaitSlot(length = 1) {
1624
1862
  this.slot += length;
@@ -1630,13 +1868,7 @@ var Emulator = class {
1630
1868
  currentHeight + 1,
1631
1869
  (currentHeight + 1) * 20
1632
1870
  );
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 = {};
1871
+ this.applyMempool();
1640
1872
  }
1641
1873
  }
1642
1874
  awaitBlock(height = 1) {
@@ -1648,27 +1880,10 @@ var Emulator = class {
1648
1880
  if (height > 0) {
1649
1881
  this.confirmPendingTransactions(previousHeight + 1, previousSlot + 20);
1650
1882
  }
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 = {};
1883
+ this.applyMempool();
1658
1884
  }
1659
1885
  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);
1886
+ return Promise.resolve(this.#confirmed.utxosAt(addressOrCredential));
1672
1887
  }
1673
1888
  getProtocolParameters() {
1674
1889
  return Promise.resolve(this.protocolParameters);
@@ -1680,31 +1895,18 @@ var Emulator = class {
1680
1895
  return Promise.resolve(this.datumTable[datumHash]);
1681
1896
  }
1682
1897
  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);
1898
+ return Promise.resolve(this.#confirmed.utxosAt(addressOrCredential, unit));
1695
1899
  }
1696
1900
  getUtxosByOutRef(outRefs) {
1697
1901
  return Promise.resolve(
1698
1902
  outRefs.flatMap((outRef) => {
1699
- const entry = this.ledger[outRef.txHash + outRef.outputIndex];
1903
+ const entry = this.#confirmed.get(outRef.txHash + outRef.outputIndex);
1700
1904
  return entry && !entry.spent ? entry.utxo : [];
1701
1905
  })
1702
1906
  );
1703
1907
  }
1704
1908
  getUtxoByUnit(unit) {
1705
- const utxos = Object.values(this.ledger).flatMap(
1706
- ({ utxo, spent }) => !spent && utxo.assets[unit] > 0n ? utxo : []
1707
- );
1909
+ const utxos = this.#confirmed.utxosWithUnit(unit);
1708
1910
  if (utxos.length > 1) {
1709
1911
  throw new Error("Unit needs to be an NFT or only held by one address.");
1710
1912
  }
@@ -1725,7 +1927,7 @@ var Emulator = class {
1725
1927
  });
1726
1928
  }
1727
1929
  awaitTx(txHash) {
1728
- if (this.transactionHistory[txHash]?.status === "pending") {
1930
+ if (this.#history[txHash]?.status === "pending") {
1729
1931
  this.awaitBlock();
1730
1932
  return Promise.resolve(true);
1731
1933
  }
@@ -1737,7 +1939,7 @@ var Emulator = class {
1737
1939
  options.signal.reason instanceof Error ? options.signal.reason : new DOMException("The operation was aborted.", "AbortError")
1738
1940
  );
1739
1941
  }
1740
- const status = this.transactionHistory[txHash];
1942
+ const status = this.#history[txHash];
1741
1943
  if (!status) return Promise.resolve({ status: "not_found", txHash });
1742
1944
  if (status.status === "pending") {
1743
1945
  return Promise.resolve({ status: "pending", txHash });
@@ -1775,10 +1977,14 @@ var Emulator = class {
1775
1977
  this.awaitBlock();
1776
1978
  }
1777
1979
  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();
1980
+ return (0, import_core_utils2.withCMLScope)((own) => Promise.resolve(this.applyTx(tx, own)));
1981
+ }
1982
+ /** Validates `tx` and applies it to the mempool; returns its hash. */
1983
+ applyTx(tx, own) {
1984
+ const desTx = own(CML.Transaction.from_cbor_hex(tx));
1985
+ const body = own(desTx.body());
1986
+ const witnesses = own(desTx.witness_set());
1987
+ const datums = own(witnesses.plutus_datums());
1782
1988
  const txHash = CML.hash_transaction(body).to_hex();
1783
1989
  const lowerBound = body.validity_interval_start() ? parseInt(body.validity_interval_start().toString()) : null;
1784
1990
  const upperBound = body.ttl() ? parseInt(body.ttl().toString()) : null;
@@ -1812,24 +2018,24 @@ var Emulator = class {
1812
2018
  const datumTable = (() => {
1813
2019
  const table = {};
1814
2020
  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();
2021
+ (0, import_core_utils2.withCMLScope)((own2) => {
2022
+ const datum = own2(datums.get(i));
2023
+ const datumHash = own2(CML.hash_plutus_data(datum)).to_hex();
1818
2024
  table[datumHash] = datum.to_cbor_hex();
1819
2025
  });
1820
2026
  }
1821
2027
  return table;
1822
2028
  })();
1823
2029
  const consumedHashes = /* @__PURE__ */ new Set();
1824
- const keyHashes = (0, import_core_utils2.withCMLScope)((own) => {
2030
+ const keyHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1825
2031
  const keyHashes2 = [];
1826
- const vkeyWitnesses = own(witnesses.vkeywitnesses());
2032
+ const vkeyWitnesses = own2(witnesses.vkeywitnesses());
1827
2033
  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()))) {
2034
+ (0, import_core_utils2.withCMLScope)((own3) => {
2035
+ const witness = own3(vkeyWitnesses.get(i));
2036
+ const publicKey = own3(witness.vkey());
2037
+ const keyHash = own3(publicKey.hash()).to_hex();
2038
+ if (!publicKey.verify((0, import_core_utils2.fromHex)(txHash), own3(witness.ed25519_signature()))) {
1833
2039
  throw new Error(`Invalid vkey witness. Key hash: ${keyHash}`);
1834
2040
  }
1835
2041
  keyHashes2.push(keyHash);
@@ -1837,19 +2043,20 @@ var Emulator = class {
1837
2043
  }
1838
2044
  return keyHashes2;
1839
2045
  });
1840
- const edKeyHashes = CML.Ed25519KeyHashList.new();
1841
- keyHashes.forEach(
2046
+ const keyHashes = new Set(keyHashList);
2047
+ const edKeyHashes = own(CML.Ed25519KeyHashList.new());
2048
+ keyHashList.forEach(
1842
2049
  (keyHash) => (0, import_core_utils2.withCMLScope)(
1843
- (own) => edKeyHashes.add(own(CML.Ed25519KeyHash.from_hex(keyHash)))
2050
+ (own2) => edKeyHashes.add(own2(CML.Ed25519KeyHash.from_hex(keyHash)))
1844
2051
  )
1845
2052
  );
1846
- const nativeHashes = (0, import_core_utils2.withCMLScope)((own) => {
2053
+ const nativeHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1847
2054
  const scriptHashes = [];
1848
- const nativeScripts = own(witnesses.native_scripts());
2055
+ const nativeScripts = own2(witnesses.native_scripts());
1849
2056
  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();
2057
+ (0, import_core_utils2.withCMLScope)((own3) => {
2058
+ const witness = own3(nativeScripts.get(i));
2059
+ const scriptHash = own3(witness.hash()).to_hex();
1853
2060
  if (!witness.verify(
1854
2061
  Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
1855
2062
  Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
@@ -1859,9 +2066,9 @@ var Emulator = class {
1859
2066
  `Invalid native script witness. Script hash: ${scriptHash}`
1860
2067
  );
1861
2068
  }
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();
2069
+ const requiredSigners2 = own3(witness.get_required_signers());
2070
+ for (let j = 0; j < requiredSigners2.len(); j++) {
2071
+ const keyHash = own3(requiredSigners2.get(j)).to_hex();
1865
2072
  consumedHashes.add(keyHash);
1866
2073
  }
1867
2074
  scriptHashes.push(scriptHash);
@@ -1869,18 +2076,18 @@ var Emulator = class {
1869
2076
  }
1870
2077
  return scriptHashes;
1871
2078
  });
1872
- edKeyHashes.free();
2079
+ const nativeHashes = new Set(nativeHashList);
1873
2080
  const nativeHashesOptional = {};
1874
- const plutusHashesOptional = [];
2081
+ const plutusHashesOptional = /* @__PURE__ */ new Set();
1875
2082
  const plutusV3Hashes = /* @__PURE__ */ new Set();
1876
- const plutusHashes = (0, import_core_utils2.withCMLScope)((own) => {
2083
+ const plutusHashList = (0, import_core_utils2.withCMLScope)((own2) => {
1877
2084
  const scriptHashes = [];
1878
2085
  const collectHashes = (scripts, isPlutusV3 = false) => {
1879
- own(scripts);
2086
+ own2(scripts);
1880
2087
  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();
2088
+ (0, import_core_utils2.withCMLScope)((own3) => {
2089
+ const script = own3(scripts.get(i));
2090
+ const scriptHash = own3(script.hash()).to_hex();
1884
2091
  scriptHashes.push(scriptHash);
1885
2092
  if (isPlutusV3) plutusV3Hashes.add(scriptHash);
1886
2093
  });
@@ -1891,16 +2098,26 @@ var Emulator = class {
1891
2098
  collectHashes(witnesses.plutus_v3_scripts(), true);
1892
2099
  return scriptHashes;
1893
2100
  });
1894
- const inputs = body.inputs();
2101
+ const plutusHashes = new Set(plutusHashList);
2102
+ const collectScriptRef = (scriptRef) => {
2103
+ const scriptHash = this.scriptRefHash(scriptRef);
2104
+ if (scriptRef.type === "Native") {
2105
+ nativeHashesOptional[scriptHash] = scriptRef.script;
2106
+ return;
2107
+ }
2108
+ plutusHashesOptional.add(scriptHash);
2109
+ if (scriptRef.type === "PlutusV3") plutusV3Hashes.add(scriptHash);
2110
+ };
2111
+ const inputs = own(body.inputs());
1895
2112
  const resolvedInputs = [];
1896
2113
  const inputOutRefs = /* @__PURE__ */ new Set();
1897
2114
  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();
2115
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2116
+ const input = own2(inputs.get(i));
2117
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
1901
2118
  });
1902
2119
  inputOutRefs.add(outRef);
1903
- const entryLedger = this.ledger[outRef];
2120
+ const entryLedger = this.#confirmed.get(outRef);
1904
2121
  const { entry, type } = !entryLedger ? { entry: this.mempool[outRef], type: "Mempool" } : { entry: entryLedger, type: "Ledger" };
1905
2122
  if (!entry || entry.spent) {
1906
2123
  throw new Error(
@@ -1912,52 +2129,18 @@ It does not exist or was already spent.`
1912
2129
  );
1913
2130
  }
1914
2131
  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
- }
2132
+ if (scriptRef) collectScriptRef(scriptRef);
1949
2133
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
1950
2134
  resolvedInputs.push({ entry, type });
1951
2135
  }
1952
- inputs.free();
1953
- const referenceInputs = body.reference_inputs();
2136
+ const referenceInputs = own(body.reference_inputs());
1954
2137
  const nonDisjointRefInputs = [];
1955
2138
  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();
2139
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2140
+ const input = own2(referenceInputs.get(i));
2141
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
1959
2142
  });
1960
- const entry = this.ledger[outRef] || this.mempool[outRef];
2143
+ const entry = this.#confirmed.get(outRef) || this.mempool[outRef];
1961
2144
  if (!entry || entry.spent) {
1962
2145
  throw new Error(
1963
2146
  `Could not read UTxO: ${JSON.stringify({
@@ -1973,44 +2156,11 @@ It does not exist or was already spent.`
1973
2156
  );
1974
2157
  }
1975
2158
  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
- }
2159
+ if (scriptRef) collectScriptRef(scriptRef);
2010
2160
  if (entry.utxo.datumHash) consumedHashes.add(entry.utxo.datumHash);
2011
2161
  }
2012
- referenceInputs?.free();
2013
- const redeemers = (() => {
2162
+ const redeemerKey = (tag, index) => `${tag}:${index}`;
2163
+ const redeemers = (0, import_core_utils2.withCMLScope)((own2) => {
2014
2164
  const tagMap = {
2015
2165
  0: "Spend",
2016
2166
  1: "Mint",
@@ -2019,35 +2169,33 @@ It does not exist or was already spent.`
2019
2169
  4: "Proposing",
2020
2170
  5: "Voting"
2021
2171
  };
2022
- const collected = [];
2023
- const redeemers2 = witnesses.redeemers();
2024
- const arrLegacyRedeemer = redeemers2?.as_arr_legacy_redeemer();
2172
+ const collected = /* @__PURE__ */ new Set();
2173
+ const redeemers2 = own2(witnesses.redeemers());
2174
+ const arrLegacyRedeemer = own2(redeemers2?.as_arr_legacy_redeemer());
2025
2175
  if (arrLegacyRedeemer) {
2026
2176
  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
- });
2177
+ const redeemer = own2(arrLegacyRedeemer.get(i));
2178
+ collected.add(
2179
+ redeemerKey(tagMap[redeemer.tag()], Number(redeemer.index()))
2180
+ );
2032
2181
  }
2033
2182
  }
2034
- const mapRedeemerKeyToRedeemerVal = redeemers2?.as_map_redeemer_key_to_redeemer_val();
2183
+ const mapRedeemerKeyToRedeemerVal = own2(
2184
+ redeemers2?.as_map_redeemer_key_to_redeemer_val()
2185
+ );
2035
2186
  if (mapRedeemerKeyToRedeemerVal) {
2036
- const keys = mapRedeemerKeyToRedeemerVal.keys();
2187
+ const keys = own2(mapRedeemerKeyToRedeemerVal.keys());
2037
2188
  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
- });
2189
+ const key = own2(keys.get(i));
2190
+ collected.add(redeemerKey(tagMap[key.tag()], Number(key.index())));
2043
2191
  }
2044
2192
  }
2045
2193
  return collected;
2046
- })();
2194
+ });
2047
2195
  function checkAndConsumeHash(credential, tag, index) {
2048
2196
  switch (credential.type) {
2049
2197
  case "Key": {
2050
- if (!keyHashes.includes(credential.hash)) {
2198
+ if (!keyHashes.has(credential.hash)) {
2051
2199
  throw new Error(
2052
2200
  `Missing vkey witness. Key hash: ${credential.hash}`
2053
2201
  );
@@ -2056,28 +2204,29 @@ It does not exist or was already spent.`
2056
2204
  break;
2057
2205
  }
2058
2206
  case "Script": {
2059
- if (nativeHashes.includes(credential.hash)) {
2207
+ if (nativeHashes.has(credential.hash)) {
2060
2208
  consumedHashes.add(credential.hash);
2061
2209
  break;
2062
2210
  } 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
- )) {
2211
+ const valid = (0, import_core_utils2.withCMLScope)(
2212
+ (own2) => own2(
2213
+ CML.NativeScript.from_cbor_hex(
2214
+ nativeHashesOptional[credential.hash]
2215
+ )
2216
+ ).verify(
2217
+ Number.isInteger(lowerBound) ? BigInt(lowerBound) : void 0,
2218
+ Number.isInteger(upperBound) ? BigInt(upperBound) : void 0,
2219
+ edKeyHashes
2220
+ )
2221
+ );
2222
+ if (!valid) {
2072
2223
  throw new Error(
2073
2224
  `Invalid native script witness. Script hash: ${credential.hash}`
2074
2225
  );
2075
2226
  }
2076
2227
  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
- )) {
2228
+ } else if (plutusHashes.has(credential.hash) || plutusHashesOptional.has(credential.hash)) {
2229
+ if (redeemers.has(redeemerKey(tag, index))) {
2081
2230
  consumedHashes.add(credential.hash);
2082
2231
  break;
2083
2232
  }
@@ -2088,13 +2237,14 @@ It does not exist or was already spent.`
2088
2237
  }
2089
2238
  }
2090
2239
  }
2091
- const collateralInputs = body.collateral_inputs();
2240
+ const collateralInputs = own(body.collateral_inputs());
2241
+ const collateralBalance = {};
2092
2242
  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();
2243
+ const outRef = (0, import_core_utils2.withCMLScope)((own2) => {
2244
+ const input = own2(collateralInputs.get(i));
2245
+ return own2(input.transaction_id()).to_hex() + input.index().toString();
2096
2246
  });
2097
- const entry = this.ledger[outRef] || this.mempool[outRef];
2247
+ const entry = this.#confirmed.get(outRef) || this.mempool[outRef];
2098
2248
  if (!entry || entry.spent) {
2099
2249
  throw new Error(
2100
2250
  `Could not read UTxO: ${JSON.stringify({
@@ -2104,19 +2254,27 @@ It does not exist or was already spent.`
2104
2254
  It does not exist or was already spent.`
2105
2255
  );
2106
2256
  }
2107
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(entry.utxo.address);
2257
+ const { paymentCredential } = (0, import_utils7.getAddressDetails)(entry.utxo.address);
2108
2258
  if (paymentCredential?.type === "Script") {
2109
2259
  throw new Error("Collateral inputs can only contain vkeys.");
2110
2260
  }
2111
2261
  checkAndConsumeHash(paymentCredential, null, null);
2262
+ for (const [unit, amount] of Object.entries(entry.utxo.assets)) {
2263
+ collateralBalance[unit] = (collateralBalance[unit] ?? 0n) + amount;
2264
+ }
2265
+ }
2266
+ if (redeemers.size > 0) {
2267
+ this.checkCollateral(body, collateralBalance, own);
2112
2268
  }
2113
- collateralInputs?.free();
2114
- for (let i = 0; i < (body.required_signers()?.len() || 0); i++) {
2115
- const signer = body.required_signers().get(i);
2269
+ const requiredSigners = own(body.required_signers());
2270
+ for (let i = 0; i < (requiredSigners?.len() || 0); i++) {
2271
+ const signer = own(requiredSigners.get(i));
2116
2272
  checkAndConsumeHash({ type: "Key", hash: signer.to_hex() }, null, null);
2117
2273
  }
2118
- for (let index = 0; index < (body.mint()?.keys().len() || 0); index++) {
2119
- const policyId = body.mint().keys().get(index).to_hex();
2274
+ const mint = own(body.mint());
2275
+ const policyIds = own(mint?.keys());
2276
+ for (let index = 0; index < (policyIds?.len() || 0); index++) {
2277
+ const policyId = own(policyIds.get(index)).to_hex();
2120
2278
  checkAndConsumeHash({ type: "Script", hash: policyId }, "Mint", index);
2121
2279
  }
2122
2280
  const withdrawalRequests = [];
@@ -2126,7 +2284,7 @@ It does not exist or was already spent.`
2126
2284
  body.withdrawals().get(rawAddress).toString()
2127
2285
  );
2128
2286
  const rewardAddress = rawAddress.to_address().to_bech32(void 0);
2129
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2287
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2130
2288
  checkAndConsumeHash(stakeCredential, "Reward", index);
2131
2289
  if (this.chain[rewardAddress]?.delegation.rewards !== withdrawal) {
2132
2290
  throw new Error(
@@ -2165,7 +2323,7 @@ It does not exist or was already spent.`
2165
2323
  CML.NetworkInfo.testnet().network_id(),
2166
2324
  registration.stake_credential()
2167
2325
  ).to_address().to_bech32(void 0);
2168
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2326
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2169
2327
  checkAndConsumeHash(stakeCredential, "Cert", index);
2170
2328
  if (this.chain[rewardAddress]?.registeredStake) {
2171
2329
  throw new Error(
@@ -2181,7 +2339,7 @@ It does not exist or was already spent.`
2181
2339
  CML.NetworkInfo.testnet().network_id(),
2182
2340
  deregistration.stake_credential()
2183
2341
  ).to_address().to_bech32(void 0);
2184
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2342
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2185
2343
  checkAndConsumeHash(stakeCredential, "Cert", index);
2186
2344
  if (!this.chain[rewardAddress]?.registeredStake) {
2187
2345
  throw new Error(
@@ -2198,7 +2356,7 @@ It does not exist or was already spent.`
2198
2356
  delegation.stake_credential()
2199
2357
  ).to_address().to_bech32(void 0);
2200
2358
  const poolId = delegation.pool().to_bech32("pool");
2201
- const { stakeCredential } = (0, import_utils6.getAddressDetails)(rewardAddress);
2359
+ const { stakeCredential } = (0, import_utils7.getAddressDetails)(rewardAddress);
2202
2360
  checkAndConsumeHash(stakeCredential, "Cert", index);
2203
2361
  if (!this.chain[rewardAddress]?.registeredStake && !certRequests.find(
2204
2362
  (request) => request.type === "Registration" && request.rewardAddress === rewardAddress
@@ -2373,26 +2531,26 @@ It does not exist or was already spent.`
2373
2531
  }
2374
2532
  }
2375
2533
  resolvedInputs.forEach(({ entry: { utxo } }, index) => {
2376
- const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
2534
+ const { paymentCredential } = (0, import_utils7.getAddressDetails)(utxo.address);
2377
2535
  checkAndConsumeHash(paymentCredential, "Spend", index);
2378
2536
  });
2379
- const outputs = (0, import_core_utils2.withCMLScope)((own) => {
2537
+ const outputs = (0, import_core_utils2.withCMLScope)((own2) => {
2380
2538
  const collected = [];
2381
- const bodyOutputs = own(body.outputs());
2539
+ const bodyOutputs = own2(body.outputs());
2382
2540
  for (let i = 0; i < bodyOutputs.len(); i++) {
2383
- const output = own(bodyOutputs.get(i));
2384
- const unspentOutput = own(
2541
+ const output = own2(bodyOutputs.get(i));
2542
+ const unspentOutput = own2(
2385
2543
  CML.TransactionUnspentOutput.new(
2386
- own(
2544
+ own2(
2387
2545
  CML.TransactionInput.new(
2388
- own(CML.TransactionHash.from_hex(txHash)),
2546
+ own2(CML.TransactionHash.from_hex(txHash)),
2389
2547
  BigInt(i)
2390
2548
  )
2391
2549
  ),
2392
2550
  output
2393
2551
  )
2394
2552
  );
2395
- const utxo = (0, import_utils6.coreToUtxo)(unspentOutput);
2553
+ const utxo = (0, import_utils7.coreToUtxo)(unspentOutput);
2396
2554
  if (utxo.datumHash) consumedHashes.add(utxo.datumHash);
2397
2555
  collected.push({
2398
2556
  utxo,
@@ -2401,13 +2559,13 @@ It does not exist or was already spent.`
2401
2559
  }
2402
2560
  return collected;
2403
2561
  });
2404
- const [extraKeyHash] = keyHashes.filter(
2562
+ const [extraKeyHash] = keyHashList.filter(
2405
2563
  (keyHash) => !consumedHashes.has(keyHash)
2406
2564
  );
2407
2565
  if (extraKeyHash) {
2408
2566
  throw new Error(`Extraneous vkey witness. Key hash: ${extraKeyHash}`);
2409
2567
  }
2410
- const [extraNativeHash] = nativeHashes.filter(
2568
+ const [extraNativeHash] = nativeHashList.filter(
2411
2569
  (scriptHash) => !consumedHashes.has(scriptHash)
2412
2570
  );
2413
2571
  if (extraNativeHash) {
@@ -2415,7 +2573,7 @@ It does not exist or was already spent.`
2415
2573
  `Extraneous native script. Script hash: ${extraNativeHash}`
2416
2574
  );
2417
2575
  }
2418
- const [extraPlutusHash] = plutusHashes.filter(
2576
+ const [extraPlutusHash] = plutusHashList.filter(
2419
2577
  (scriptHash) => !consumedHashes.has(scriptHash)
2420
2578
  );
2421
2579
  if (extraPlutusHash) {
@@ -2446,11 +2604,8 @@ It does not exist or was already spent.`
2446
2604
  );
2447
2605
  }
2448
2606
  }
2449
- resolvedInputs.forEach(({ entry, type }) => {
2450
- const outRef = entry.utxo.txHash + entry.utxo.outputIndex;
2607
+ resolvedInputs.forEach(({ entry }) => {
2451
2608
  entry.spent = true;
2452
- if (type === "Ledger") this.ledger[outRef] = entry;
2453
- else if (type === "Mempool") this.mempool[outRef] = entry;
2454
2609
  });
2455
2610
  withdrawalRequests.forEach(({ rewardAddress, withdrawal }) => {
2456
2611
  this.chain[rewardAddress].delegation.rewards -= withdrawal;
@@ -2490,9 +2645,115 @@ It does not exist or was already spent.`
2490
2645
  for (const [datumHash, datum] of Object.entries(datumTable)) {
2491
2646
  this.datumTable[datumHash] = datum;
2492
2647
  }
2493
- this.transactionHistory[txHash] = { status: "pending" };
2494
- (0, import_core_utils2.freeCML)(datums, witnesses, body, desTx);
2495
- return Promise.resolve(txHash);
2648
+ this.#history[txHash] = { status: "pending" };
2649
+ this.#pendingTxHashes.push(txHash);
2650
+ return txHash;
2651
+ }
2652
+ /**
2653
+ * The ledger's collateral rules for a transaction with redeemers: at least
2654
+ * one and at most `maxCollateralInputs` collateral inputs, a balance (inputs
2655
+ * minus the collateral return) of ADA only that covers
2656
+ * `collateralPercentage` of the fee, a `total_collateral` field, when
2657
+ * present, equal to that balance, and a collateral return holding at least
2658
+ * its minimum ADA.
2659
+ */
2660
+ checkCollateral(body, collateralBalance, own) {
2661
+ const inputCount = own(body.collateral_inputs())?.len() ?? 0;
2662
+ if (inputCount === 0) {
2663
+ throw new Error(
2664
+ "NoCollateralInputs: a transaction that runs scripts needs collateral inputs."
2665
+ );
2666
+ }
2667
+ const { maxCollateralInputs, collateralPercentage } = this.protocolParameters;
2668
+ if (inputCount > maxCollateralInputs) {
2669
+ throw new Error(
2670
+ `TooManyCollateralInputs: ${inputCount} collateral inputs, but at most ${maxCollateralInputs} are allowed.`
2671
+ );
2672
+ }
2673
+ const balance = { ...collateralBalance };
2674
+ const collateralReturn = own(body.collateral_return());
2675
+ if (collateralReturn) {
2676
+ const minLovelace = CML.min_ada_required(
2677
+ collateralReturn,
2678
+ this.protocolParameters.coinsPerUtxoByte
2679
+ );
2680
+ const returnedLovelace = own(collateralReturn.amount()).coin();
2681
+ if (returnedLovelace < minLovelace) {
2682
+ throw new Error(
2683
+ `BabbageOutputTooSmallUTxO: collateral return holds ${returnedLovelace} Lovelace, but needs at least ${minLovelace} Lovelace.`
2684
+ );
2685
+ }
2686
+ const returned = (0, import_utils7.valueToAssets)(own(collateralReturn.amount()));
2687
+ for (const [unit, amount] of Object.entries(returned)) {
2688
+ balance[unit] = (balance[unit] ?? 0n) - amount;
2689
+ }
2690
+ }
2691
+ const nonAda = Object.entries(balance).filter(
2692
+ ([unit, amount]) => unit !== "lovelace" && amount !== 0n
2693
+ );
2694
+ if (nonAda.length > 0) {
2695
+ throw new Error(
2696
+ `CollateralContainsNonADA: collateral balance holds ${nonAda.map(([unit, amount]) => `${amount} ${unit}`).join(", ")}.`
2697
+ );
2698
+ }
2699
+ const collateral = balance.lovelace ?? 0n;
2700
+ const fee = body.fee();
2701
+ if (collateral * 100n < fee * BigInt(collateralPercentage)) {
2702
+ const required = (fee * BigInt(collateralPercentage) + 99n) / 100n;
2703
+ throw new Error(
2704
+ `InsufficientCollateral: collateral balance is ${collateral} Lovelace, but the fee of ${fee} requires ${required} Lovelace (${collateralPercentage}%).`
2705
+ );
2706
+ }
2707
+ const totalCollateral = body.total_collateral();
2708
+ if (totalCollateral !== void 0 && totalCollateral !== collateral) {
2709
+ throw new Error(
2710
+ `IncorrectTotalCollateralField: total collateral is ${totalCollateral} Lovelace, but the collateral balance is ${collateral} Lovelace.`
2711
+ );
2712
+ }
2713
+ }
2714
+ /** Hash of a reference script, computed once per distinct script. */
2715
+ scriptRefHash(scriptRef) {
2716
+ let scriptHash = this.#scriptRefHashes.get(
2717
+ scriptRef.type,
2718
+ scriptRef.script
2719
+ );
2720
+ if (scriptHash === void 0) {
2721
+ scriptHash = (0, import_core_utils2.withCMLScope)((own) => {
2722
+ const bytes = (0, import_core_utils2.fromHex)(scriptRef.script);
2723
+ switch (scriptRef.type) {
2724
+ case "Native":
2725
+ return own(
2726
+ own(CML.NativeScript.from_cbor_bytes(bytes)).hash()
2727
+ ).to_hex();
2728
+ case "PlutusV1":
2729
+ return own(
2730
+ own(
2731
+ CML.PlutusScript.from_v1(
2732
+ own(CML.PlutusV1Script.from_cbor_bytes(bytes))
2733
+ )
2734
+ ).hash()
2735
+ ).to_hex();
2736
+ case "PlutusV2":
2737
+ return own(
2738
+ own(
2739
+ CML.PlutusScript.from_v2(
2740
+ own(CML.PlutusV2Script.from_cbor_bytes(bytes))
2741
+ )
2742
+ ).hash()
2743
+ ).to_hex();
2744
+ case "PlutusV3":
2745
+ return own(
2746
+ own(
2747
+ CML.PlutusScript.from_v3(
2748
+ own(CML.PlutusV3Script.from_cbor_bytes(bytes))
2749
+ )
2750
+ ).hash()
2751
+ ).to_hex();
2752
+ }
2753
+ });
2754
+ this.#scriptRefHashes.set(scriptRef.type, scriptRef.script, scriptHash);
2755
+ }
2756
+ return scriptHash;
2496
2757
  }
2497
2758
  async evaluateTx(tx, additionalUTxOs) {
2498
2759
  return (0, import_core_utils2.withCMLScope)((own) => {
@@ -2513,7 +2774,7 @@ It does not exist or was already spent.`
2513
2774
  steps: Number(exUnits.steps())
2514
2775
  },
2515
2776
  redeemer_index: Number(legacyRedeemer.index()),
2516
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(legacyRedeemer.tag())
2777
+ redeemer_tag: (0, import_utils6.fromCMLRedeemerTag)(legacyRedeemer.tag())
2517
2778
  });
2518
2779
  }
2519
2780
  return evalRedeemers;
@@ -2534,7 +2795,7 @@ It does not exist or was already spent.`
2534
2795
  steps: Number(exUnits.steps())
2535
2796
  },
2536
2797
  redeemer_index: Number(key.index()),
2537
- redeemer_tag: (0, import_utils5.fromCMLRedeemerTag)(key.tag())
2798
+ redeemer_tag: (0, import_utils6.fromCMLRedeemerTag)(key.tag())
2538
2799
  });
2539
2800
  }
2540
2801
  }
@@ -2557,7 +2818,7 @@ It does not exist or was already spent.`
2557
2818
  }
2558
2819
  const totalBalances = {};
2559
2820
  const balances = {};
2560
- for (const { utxo } of Object.values(this.ledger)) {
2821
+ for (const { utxo } of Object.values(this.#confirmed.record)) {
2561
2822
  for (const [unit, quantity] of Object.entries(utxo.assets)) {
2562
2823
  if (!balances[utxo.address]) {
2563
2824
  balances[utxo.address] = { [unit]: quantity };
@@ -2610,367 +2871,8 @@ ${"\u2581".repeat(60)}
2610
2871
  }
2611
2872
  };
2612
2873
 
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
2874
  // src/koios.ts
2973
- var import_core_utils4 = require("@lucid-evolution/core-utils");
2875
+ var import_core_utils3 = require("@lucid-evolution/core-utils");
2974
2876
  var import_utils9 = require("@lucid-evolution/utils");
2975
2877
 
2976
2878
  // src/internal/koios.ts
@@ -3224,9 +3126,9 @@ var toUTxO = (koiosUTxO, address) => ({
3224
3126
  address,
3225
3127
  datumHash: koiosUTxO.inline_datum ? void 0 : koiosUTxO.datum_hash || void 0,
3226
3128
  datum: koiosUTxO.inline_datum ? koiosUTxO.inline_datum.bytes : void 0,
3227
- scriptRef: toScriptRef3(koiosUTxO.reference_script)
3129
+ scriptRef: toScriptRef2(koiosUTxO.reference_script)
3228
3130
  });
3229
- var toScriptRef3 = (reference_script) => {
3131
+ var toScriptRef2 = (reference_script) => {
3230
3132
  if (reference_script && reference_script.bytes && reference_script.type) {
3231
3133
  switch (reference_script.type) {
3232
3134
  case "plutusV1":
@@ -3555,7 +3457,7 @@ var Koios = class {
3555
3457
  }
3556
3458
  async submitTx(tx) {
3557
3459
  const url = `${this.baseUrl}/submittx`;
3558
- const body = (0, import_core_utils4.fromHex)(tx);
3460
+ const body = (0, import_core_utils3.fromHex)(tx);
3559
3461
  const schema = TxHashSchema;
3560
3462
  const bearerToken = this.token ? { Authorization: `Bearer ${this.token}` } : void 0;
3561
3463
  const result = await (0, import_effect8.pipe)(
@@ -3608,7 +3510,6 @@ var Koios = class {
3608
3510
  KoiosError,
3609
3511
  Kupmios,
3610
3512
  KupmiosError,
3611
- Maestro,
3612
3513
  OgmiosJsonRpcError,
3613
3514
  generateEmulatorAccount,
3614
3515
  generateEmulatorAccountFromPrivateKey,