@meshsdk/transaction 1.5.28

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.mjs ADDED
@@ -0,0 +1,2014 @@
1
+ // src/mesh-tx-builder/tx-builder-core.ts
2
+ import {
3
+ DEFAULT_REDEEMER_BUDGET,
4
+ DEFAULT_PROTOCOL_PARAMETERS as DEFAULT_PROTOCOL_PARAMETERS3,
5
+ emptyTxBuilderBody
6
+ } from "@meshsdk/common";
7
+ import JSONBig from "json-bigint";
8
+
9
+ // src/utxo-selection/keepRelevant.ts
10
+ import { BigNum as BigNum2 } from "@meshsdk/common";
11
+
12
+ // src/utxo-selection/common.ts
13
+ import { BigNum } from "@meshsdk/common";
14
+ import { resolveTxFees } from "@meshsdk/common";
15
+ var enoughValueHasBeenSelected = (selection, assets) => {
16
+ return Array.from(assets, (asset) => ({
17
+ unit: asset[0],
18
+ quantity: BigNum.new(asset[1])
19
+ })).every((asset) => {
20
+ return selection.filter((utxo) => {
21
+ return utxo.output.amount.find((a) => a.unit === asset.unit) !== void 0;
22
+ }).reduce((selectedQuantity, utxo) => {
23
+ const utxoQuantity = utxo.output.amount.reduce(
24
+ (quantity, a) => quantity.checkedAdd(
25
+ BigNum.new(asset.unit === a.unit ? a.quantity : "0")
26
+ ),
27
+ BigNum.new("0")
28
+ );
29
+ return selectedQuantity.checkedAdd(utxoQuantity);
30
+ }, BigNum.new("0")).lessThan(asset.quantity) === false;
31
+ });
32
+ };
33
+ var largestLovelaceQuantity = (utxoA, utxoB) => {
34
+ const aLovelaceQuantity = BigNum.new(
35
+ utxoA.output.amount.find((asset) => asset.unit === "lovelace")?.quantity ?? "0"
36
+ );
37
+ const bLovelaceQuantity = BigNum.new(
38
+ utxoB.output.amount.find((asset) => asset.unit === "lovelace")?.quantity ?? "0"
39
+ );
40
+ return bLovelaceQuantity.compare(aLovelaceQuantity);
41
+ };
42
+ var maxTxFees = (parameters) => {
43
+ const { maxTxSize, minFeeA, minFeeB } = parameters;
44
+ return BigNum.new(resolveTxFees(maxTxSize, minFeeA, minFeeB));
45
+ };
46
+ var multiAssetUTxO = (utxo) => utxo.output.amount.length > 1;
47
+ var selectedLovelaceQuantity = (multiAsset) => {
48
+ return multiAsset.reduce((sum, utxo) => {
49
+ const lovelace = utxo.output.amount.find((asset) => asset.unit === "lovelace")?.quantity ?? "0";
50
+ return sum.checkedAdd(BigNum.new(lovelace));
51
+ }, BigNum.new("0"));
52
+ };
53
+ var remainingLovelace = (quantity, initialUTxOSet) => {
54
+ const sortedUTxOs = initialUTxOSet.sort(largestLovelaceQuantity);
55
+ const requestedOutputSet = /* @__PURE__ */ new Map([["lovelace", quantity]]);
56
+ const selection = selectValue(sortedUTxOs, requestedOutputSet);
57
+ return selection;
58
+ };
59
+ var selectValue = (inputUTxO, outputSet, selection = []) => {
60
+ if (inputUTxO.length === 0 || enoughValueHasBeenSelected(selection, outputSet)) {
61
+ return selection;
62
+ }
63
+ if (valueCanBeSelected(inputUTxO[0], outputSet)) {
64
+ return selectValue(inputUTxO.slice(1), outputSet, [
65
+ ...selection,
66
+ inputUTxO[0]
67
+ ]);
68
+ }
69
+ return selectValue(inputUTxO.slice(1), outputSet, selection);
70
+ };
71
+ var valueCanBeSelected = (utxo, assets) => {
72
+ return Array.from(assets.keys()).some((unit) => {
73
+ return utxo.output.amount.find((asset) => asset.unit === unit) !== void 0;
74
+ });
75
+ };
76
+
77
+ // src/utxo-selection/keepRelevant.ts
78
+ var keepRelevant = (requiredAssets, inputs, threshold = "5000000") => {
79
+ const requestedLovelace = BigNum2.new(
80
+ requiredAssets.get("lovelace") ?? "0"
81
+ ).checkedAdd(BigNum2.new(threshold));
82
+ const multiAsset = inputs.filter(
83
+ (utxo) => utxo.output.amount.filter((asset) => asset.unit !== "lovelace").some((asset) => requiredAssets.has(asset.unit))
84
+ );
85
+ const selectedLovelace = selectedLovelaceQuantity(multiAsset);
86
+ const lovelace = selectedLovelace.lessThan(requestedLovelace) ? remainingLovelace(
87
+ requestedLovelace.clampedSub(selectedLovelace).toString(),
88
+ inputs.filter((input) => {
89
+ return !multiAsset.some(
90
+ (selectedUtxo) => selectedUtxo.input.txHash === input.input.txHash && selectedUtxo.input.outputIndex === input.input.outputIndex
91
+ );
92
+ })
93
+ ) : [];
94
+ return [...lovelace, ...multiAsset];
95
+ };
96
+
97
+ // src/utxo-selection/largestFirst.ts
98
+ import {
99
+ DEFAULT_PROTOCOL_PARAMETERS,
100
+ BigNum as BigNum3,
101
+ resolveTxFees as resolveTxFees2
102
+ } from "@meshsdk/common";
103
+ var largestFirst = (lovelace, initialUTxOSet, includeTxFees = false, { maxTxSize, minFeeA, minFeeB } = DEFAULT_PROTOCOL_PARAMETERS) => {
104
+ const sortedUTxOs = initialUTxOSet.filter((utxo) => multiAssetUTxO(utxo) === false).sort(largestLovelaceQuantity);
105
+ const maxTxFees2 = BigNum3.new(resolveTxFees2(maxTxSize, minFeeA, minFeeB));
106
+ const quantity = includeTxFees ? BigNum3.new(lovelace).checkedAdd(maxTxFees2).toString() : lovelace;
107
+ const requestedOutputSet = /* @__PURE__ */ new Map([["lovelace", quantity]]);
108
+ const selection = selectValue(sortedUTxOs, requestedOutputSet);
109
+ return selection;
110
+ };
111
+
112
+ // src/utxo-selection/largestFirstMultiAsset.ts
113
+ import {
114
+ BigNum as BigNum4,
115
+ DEFAULT_PROTOCOL_PARAMETERS as DEFAULT_PROTOCOL_PARAMETERS2
116
+ } from "@meshsdk/common";
117
+ var largestFirstMultiAsset = (requestedOutputSet, initialUTxOSet, includeTxFees = false, parameters = DEFAULT_PROTOCOL_PARAMETERS2) => {
118
+ const sortedMultiAssetUTxOs = initialUTxOSet.filter(multiAssetUTxO).sort(largestLovelaceQuantity);
119
+ const txFees = maxTxFees(parameters);
120
+ const lovelace = requestedOutputSet.get("lovelace") ?? "0";
121
+ const quantity = includeTxFees ? BigNum4.new(lovelace).checkedAdd(txFees).toString() : lovelace;
122
+ requestedOutputSet.set("lovelace", quantity);
123
+ const selection = selectValue(sortedMultiAssetUTxOs, requestedOutputSet);
124
+ return selection;
125
+ };
126
+
127
+ // src/utxo-selection/experimental.ts
128
+ var experimentalSelectUtxos = (requiredAssets, inputs, threshold) => {
129
+ const totalRequiredAssets = new Map(requiredAssets);
130
+ totalRequiredAssets.set(
131
+ "lovelace",
132
+ String(Number(totalRequiredAssets.get("lovelace") || 0) + Number(threshold))
133
+ );
134
+ const utxoMap = /* @__PURE__ */ new Map();
135
+ for (let i = 0; i < inputs.length; i++) {
136
+ utxoMap.set(i, inputs[i]);
137
+ }
138
+ const selectedInputs = /* @__PURE__ */ new Set();
139
+ const onlyLovelace = /* @__PURE__ */ new Set();
140
+ const singletons = /* @__PURE__ */ new Set();
141
+ const pairs = /* @__PURE__ */ new Set();
142
+ const rest = /* @__PURE__ */ new Set();
143
+ for (let i = 0; i < inputs.length; i++) {
144
+ switch (inputs[i].output.amount.length) {
145
+ case 1: {
146
+ onlyLovelace.add(i);
147
+ break;
148
+ }
149
+ case 2: {
150
+ singletons.add(i);
151
+ break;
152
+ }
153
+ case 3: {
154
+ pairs.add(i);
155
+ break;
156
+ }
157
+ default: {
158
+ rest.add(i);
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ const addUtxoWithAssetAmount = (inputIndex, assetUnit, set) => {
164
+ const utxo = utxoMap.get(inputIndex);
165
+ if (!utxo) return;
166
+ const amount = getAssetAmount(utxo, assetUnit);
167
+ if (Number(amount) > 0) {
168
+ selectedInputs.add(inputIndex);
169
+ set.delete(inputIndex);
170
+ for (const asset of utxo.output.amount) {
171
+ totalRequiredAssets.set(
172
+ asset.unit,
173
+ String(
174
+ Number(totalRequiredAssets.get(asset.unit)) - Number(asset.quantity)
175
+ )
176
+ );
177
+ }
178
+ }
179
+ };
180
+ for (const assetUnit of totalRequiredAssets.keys()) {
181
+ if (assetUnit == "lovelace") continue;
182
+ for (const inputIndex of singletons) {
183
+ const assetRequired = totalRequiredAssets.get(assetUnit);
184
+ if (!assetRequired || Number(assetRequired) <= 0) break;
185
+ addUtxoWithAssetAmount(inputIndex, assetUnit, singletons);
186
+ }
187
+ for (const inputIndex of pairs) {
188
+ const assetRequired = totalRequiredAssets.get(assetUnit);
189
+ if (!assetRequired || Number(assetRequired) <= 0) break;
190
+ addUtxoWithAssetAmount(inputIndex, assetUnit, pairs);
191
+ }
192
+ for (const inputIndex of rest) {
193
+ const assetRequired = totalRequiredAssets.get(assetUnit);
194
+ if (!assetRequired || Number(assetRequired) <= 0) break;
195
+ addUtxoWithAssetAmount(inputIndex, assetUnit, rest);
196
+ }
197
+ }
198
+ for (const inputIndex of onlyLovelace) {
199
+ const assetRequired = totalRequiredAssets.get("lovelace");
200
+ if (!assetRequired || Number(assetRequired) <= 0) break;
201
+ addUtxoWithAssetAmount(inputIndex, "lovelace", onlyLovelace);
202
+ }
203
+ for (const inputIndex of singletons) {
204
+ const assetRequired = totalRequiredAssets.get("lovelace");
205
+ if (!assetRequired || Number(assetRequired) <= 0) break;
206
+ addUtxoWithAssetAmount(inputIndex, "lovelace", singletons);
207
+ }
208
+ for (const inputIndex of pairs) {
209
+ const assetRequired = totalRequiredAssets.get("lovelace");
210
+ if (!assetRequired || Number(assetRequired) <= 0) break;
211
+ addUtxoWithAssetAmount(inputIndex, "lovelace", pairs);
212
+ }
213
+ for (const inputIndex of rest) {
214
+ const assetRequired = totalRequiredAssets.get("lovelace");
215
+ if (!assetRequired || Number(assetRequired) <= 0) break;
216
+ addUtxoWithAssetAmount(inputIndex, "lovelace", rest);
217
+ }
218
+ for (const assetUnit of totalRequiredAssets.keys()) {
219
+ if (Number(totalRequiredAssets.get(assetUnit)) > 0) {
220
+ console.log("Insufficient funds for", assetUnit);
221
+ console.log(
222
+ "Remaining quantity",
223
+ Number(totalRequiredAssets.get(assetUnit))
224
+ );
225
+ return [];
226
+ }
227
+ }
228
+ const selectedUtxos = [];
229
+ for (const inputIndex of selectedInputs) {
230
+ const utxo = utxoMap.get(inputIndex);
231
+ if (utxo) {
232
+ selectedUtxos.push(utxo);
233
+ }
234
+ }
235
+ return selectedUtxos;
236
+ };
237
+ var getAssetAmount = (utxo, assetUnit) => {
238
+ for (const utxoAsset of utxo.output.amount) {
239
+ if (utxoAsset.unit == assetUnit) return utxoAsset.quantity;
240
+ }
241
+ return "0";
242
+ };
243
+
244
+ // src/utxo-selection/index.ts
245
+ var UtxoSelection = class {
246
+ constructor() {
247
+ }
248
+ largestFirst(requiredAssets, inputs, threshold = "5000000") {
249
+ const lovelaceAmount = requiredAssets.get("lovelace") ?? "0";
250
+ const requiredAssetWithThreshold = BigInt(lovelaceAmount) + BigInt(threshold);
251
+ return largestFirst(requiredAssetWithThreshold.toString(), inputs, false);
252
+ }
253
+ keepRelevant(requiredAssets, inputs, threshold = "5000000") {
254
+ return keepRelevant(requiredAssets, inputs, threshold);
255
+ }
256
+ largestFirstMultiAsset(requiredAssets, inputs, threshold) {
257
+ const lovelaceAmount = requiredAssets.get("lovelace") ?? "0";
258
+ requiredAssets.set(
259
+ "lovelace",
260
+ (BigInt(lovelaceAmount) + BigInt(threshold)).toString()
261
+ );
262
+ return largestFirstMultiAsset(requiredAssets, inputs, false);
263
+ }
264
+ experimental(requiredAssets, inputs, threshold) {
265
+ return experimentalSelectUtxos(requiredAssets, inputs, threshold);
266
+ }
267
+ };
268
+
269
+ // src/mesh-tx-builder/tx-builder-core.ts
270
+ var MeshTxBuilderCore = class {
271
+ constructor() {
272
+ this.txEvaluationMultiplier = 1.1;
273
+ this.addingPlutusScriptInput = false;
274
+ this.addingPlutusMint = false;
275
+ this.addingPlutusWithdrawal = false;
276
+ this._protocolParams = DEFAULT_PROTOCOL_PARAMETERS3;
277
+ /**
278
+ * Set the input for transaction
279
+ * @param txHash The transaction hash of the input UTxO
280
+ * @param txIndex The transaction index of the input UTxO
281
+ * @param amount The asset amount of index of the input UTxO
282
+ * @param address The address of the input UTxO
283
+ * @returns The MeshTxBuilder instance
284
+ */
285
+ this.txIn = (txHash, txIndex, amount, address) => {
286
+ if (this.txInQueueItem) {
287
+ this.queueInput();
288
+ }
289
+ if (!this.addingPlutusScriptInput) {
290
+ this.txInQueueItem = {
291
+ type: "PubKey",
292
+ txIn: {
293
+ txHash,
294
+ txIndex,
295
+ amount,
296
+ address
297
+ }
298
+ };
299
+ } else {
300
+ this.txInQueueItem = {
301
+ type: "Script",
302
+ txIn: {
303
+ txHash,
304
+ txIndex,
305
+ amount,
306
+ address
307
+ },
308
+ scriptTxIn: {}
309
+ };
310
+ }
311
+ this.addingPlutusScriptInput = false;
312
+ return this;
313
+ };
314
+ /**
315
+ * Set the script for transaction input
316
+ * @param {string} scriptCbor The CborHex of the script
317
+ * @param version Optional - The Plutus script version
318
+ * @returns The MeshTxBuilder instance
319
+ */
320
+ this.txInScript = (scriptCbor) => {
321
+ if (!this.txInQueueItem) throw Error("Undefined input");
322
+ if (this.txInQueueItem.type === "PubKey") {
323
+ this.txInQueueItem = {
324
+ type: "SimpleScript",
325
+ txIn: this.txInQueueItem.txIn,
326
+ simpleScriptTxIn: {
327
+ scriptSource: {
328
+ type: "Provided",
329
+ script: scriptCbor
330
+ }
331
+ }
332
+ };
333
+ }
334
+ if (this.txInQueueItem.type === "Script") {
335
+ this.txInQueueItem.scriptTxIn.scriptSource = {
336
+ type: "Provided",
337
+ script: {
338
+ code: scriptCbor,
339
+ version: this.plutusSpendingScriptVersion || "V2"
340
+ }
341
+ };
342
+ }
343
+ return this;
344
+ };
345
+ /**
346
+ * Set the input datum for transaction input
347
+ * @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
348
+ * @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
349
+ * @returns The MeshTxBuilder instance
350
+ */
351
+ this.txInDatumValue = (datum, type = "Mesh") => {
352
+ if (!this.txInQueueItem) throw Error("Undefined input");
353
+ if (this.txInQueueItem.type === "PubKey")
354
+ throw Error("Datum value attempted to be called a non script input");
355
+ if (this.txInQueueItem.type === "SimpleScript")
356
+ throw Error(
357
+ "Datum value attempted to be called on a simple script input"
358
+ );
359
+ let content = datum;
360
+ if (type === "JSON") {
361
+ content = this.castRawDataToJsonString(datum);
362
+ }
363
+ if (type === "Mesh") {
364
+ this.txInQueueItem.scriptTxIn.datumSource = {
365
+ type: "Provided",
366
+ data: {
367
+ type,
368
+ content: datum
369
+ }
370
+ };
371
+ return this;
372
+ }
373
+ this.txInQueueItem.scriptTxIn.datumSource = {
374
+ type: "Provided",
375
+ data: {
376
+ type,
377
+ content
378
+ }
379
+ };
380
+ return this;
381
+ };
382
+ /**
383
+ * Tell the transaction builder that the input UTxO has inlined datum
384
+ * @returns The MeshTxBuilder instance
385
+ */
386
+ this.txInInlineDatumPresent = () => {
387
+ if (!this.txInQueueItem) throw Error("Undefined input");
388
+ if (this.txInQueueItem.type === "PubKey")
389
+ throw Error(
390
+ "Inline datum present attempted to be called a non script input"
391
+ );
392
+ if (this.txInQueueItem.type === "SimpleScript")
393
+ throw Error(
394
+ "Inline datum present attempted to be called on a simple script input"
395
+ );
396
+ const { txHash, txIndex } = this.txInQueueItem.txIn;
397
+ if (txHash && txIndex.toString()) {
398
+ this.txInQueueItem.scriptTxIn.datumSource = {
399
+ type: "Inline",
400
+ txHash,
401
+ txIndex
402
+ };
403
+ }
404
+ return this;
405
+ };
406
+ // /**
407
+ // * Native script - Set the reference input where it would also be spent in the transaction
408
+ // * @param txHash The transaction hash of the reference UTxO
409
+ // * @param txIndex The transaction index of the reference UTxO
410
+ // * @param spendingScriptHash The script hash of the spending script
411
+ // * @returns The MeshTxBuilder instance
412
+ // */
413
+ // simpleScriptTxInReference = (
414
+ // txHash: string,
415
+ // txIndex: number,
416
+ // spendingScriptHash?: string
417
+ // ) => {
418
+ // if (!this.txInQueueItem) throw Error('Undefined input');
419
+ // if (this.txInQueueItem.type === 'PubKey')
420
+ // throw Error(
421
+ // 'Spending tx in reference attempted to be called a non script input'
422
+ // );
423
+ // this.txInQueueItem.scriptTxIn.scriptSource = {
424
+ // type: 'Inline',
425
+ // txInInfo: {
426
+ // txHash,
427
+ // txIndex,
428
+ // spendingScriptHash,
429
+ // },
430
+ // };
431
+ // return this;
432
+ // };
433
+ /**
434
+ * Set the redeemer for the reference input to be spent in same transaction
435
+ * @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
436
+ * @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
437
+ * @param exUnits The execution units budget for the redeemer
438
+ * @returns The MeshTxBuilder instance
439
+ */
440
+ this.txInRedeemerValue = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
441
+ if (!this.txInQueueItem) throw Error("Undefined input");
442
+ if (this.txInQueueItem.type === "PubKey")
443
+ throw Error(
444
+ "Spending tx in reference redeemer attempted to be called a non script input"
445
+ );
446
+ if (this.txInQueueItem.type === "SimpleScript")
447
+ throw Error(
448
+ "Spending tx in reference redeemer attempted to be called on a simple script input"
449
+ );
450
+ this.txInQueueItem.scriptTxIn.redeemer = this.castBuilderDataToRedeemer(
451
+ redeemer,
452
+ type,
453
+ exUnits
454
+ );
455
+ return this;
456
+ };
457
+ /**
458
+ * Set the output for transaction
459
+ * @param {string} address The recipient of the output
460
+ * @param {Asset[]} amount The amount of other native assets attached with UTxO
461
+ * @returns The MeshTxBuilder instance
462
+ */
463
+ this.txOut = (address, amount) => {
464
+ if (this.txOutput) {
465
+ this.meshTxBuilderBody.outputs.push(this.txOutput);
466
+ this.txOutput = void 0;
467
+ }
468
+ this.txOutput = {
469
+ address,
470
+ amount
471
+ };
472
+ return this;
473
+ };
474
+ /**
475
+ * Set the output datum hash for transaction
476
+ * @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
477
+ * @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
478
+ * @returns The MeshTxBuilder instance
479
+ */
480
+ this.txOutDatumHashValue = (datum, type = "Mesh") => {
481
+ let content = datum;
482
+ if (this.txOutput) {
483
+ if (type === "Mesh") {
484
+ this.txOutput.datum = {
485
+ type: "Hash",
486
+ data: {
487
+ type,
488
+ content
489
+ }
490
+ };
491
+ return this;
492
+ }
493
+ if (type === "JSON") {
494
+ content = this.castRawDataToJsonString(datum);
495
+ }
496
+ this.txOutput.datum = {
497
+ type: "Hash",
498
+ data: {
499
+ type,
500
+ content
501
+ }
502
+ };
503
+ }
504
+ return this;
505
+ };
506
+ /**
507
+ * Set the output inline datum for transaction
508
+ * @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
509
+ * @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
510
+ * @returns The MeshTxBuilder instance
511
+ */
512
+ this.txOutInlineDatumValue = (datum, type = "Mesh") => {
513
+ let content = datum;
514
+ if (this.txOutput) {
515
+ if (type === "Mesh") {
516
+ this.txOutput.datum = {
517
+ type: "Inline",
518
+ data: {
519
+ type,
520
+ content
521
+ }
522
+ };
523
+ return this;
524
+ }
525
+ if (type === "JSON") {
526
+ content = this.castRawDataToJsonString(datum);
527
+ }
528
+ this.txOutput.datum = {
529
+ type: "Inline",
530
+ data: {
531
+ type,
532
+ content
533
+ }
534
+ };
535
+ }
536
+ return this;
537
+ };
538
+ /**
539
+ * Set the reference script to be attached with the output
540
+ * @param scriptCbor The CBOR hex of the script to be attached to UTxO as reference script
541
+ * @param version Optional - The Plutus script version
542
+ * @returns The MeshTxBuilder instance
543
+ */
544
+ this.txOutReferenceScript = (scriptCbor, version = "V2") => {
545
+ if (this.txOutput) {
546
+ this.txOutput.referenceScript = { code: scriptCbor, version };
547
+ }
548
+ return this;
549
+ };
550
+ /**
551
+ * Set the instruction that it is currently using V1 Plutus spending scripts
552
+ * @returns The MeshTxBuilder instance
553
+ */
554
+ this.spendingPlutusScriptV1 = () => {
555
+ this.addingPlutusScriptInput = true;
556
+ this.plutusSpendingScriptVersion = "V1";
557
+ return this;
558
+ };
559
+ /**
560
+ * Set the instruction that it is currently using V2 Plutus spending scripts
561
+ * @returns The MeshTxBuilder instance
562
+ */
563
+ this.spendingPlutusScriptV2 = () => {
564
+ this.addingPlutusScriptInput = true;
565
+ this.plutusSpendingScriptVersion = "V2";
566
+ return this;
567
+ };
568
+ /**
569
+ * Set the instruction that it is currently using V3 Plutus spending scripts
570
+ * @returns The MeshTxBuilder instance
571
+ */
572
+ this.spendingPlutusScriptV3 = () => {
573
+ this.addingPlutusScriptInput = true;
574
+ this.plutusSpendingScriptVersion = "V3";
575
+ return this;
576
+ };
577
+ /**
578
+ * Set the reference input where it would also be spent in the transaction
579
+ * @param txHash The transaction hash of the reference UTxO
580
+ * @param txIndex The transaction index of the reference UTxO
581
+ * @param spendingScriptHash The script hash of the spending script
582
+ * @returns The MeshTxBuilder instance
583
+ */
584
+ this.spendingTxInReference = (txHash, txIndex, spendingScriptHash) => {
585
+ if (!this.txInQueueItem) throw Error("Undefined input");
586
+ if (this.txInQueueItem.type === "PubKey")
587
+ throw Error(
588
+ "Spending tx in reference attempted to be called a non script input"
589
+ );
590
+ if (this.txInQueueItem.type === "SimpleScript")
591
+ throw Error(
592
+ "Spending tx in reference attempted to be called on a simple script input"
593
+ );
594
+ this.txInQueueItem.scriptTxIn.scriptSource = {
595
+ type: "Inline",
596
+ txHash,
597
+ txIndex,
598
+ scriptHash: spendingScriptHash,
599
+ version: this.plutusSpendingScriptVersion || "V2",
600
+ scriptSize: "0"
601
+ // TODO
602
+ };
603
+ return this;
604
+ };
605
+ /**
606
+ * [Alias of txInInlineDatumPresent] Set the instruction that the reference input has inline datum
607
+ * @returns The MeshTxBuilder instance
608
+ */
609
+ // Unsure how this is different from the --tx-in-inline-datum-present flag
610
+ // It seems to just be different based on if the script is a reference input
611
+ this.spendingReferenceTxInInlineDatumPresent = () => {
612
+ this.txInInlineDatumPresent();
613
+ return this;
614
+ };
615
+ /**
616
+ * [Alias of txInRedeemerValue] Set the redeemer for the reference input to be spent in same transaction
617
+ * @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
618
+ * @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
619
+ * @param exUnits The execution units budget for the redeemer
620
+ * @returns The MeshTxBuilder instance
621
+ */
622
+ this.spendingReferenceTxInRedeemerValue = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
623
+ this.txInRedeemerValue(redeemer, type, exUnits);
624
+ return this;
625
+ };
626
+ /**
627
+ * Specify a read only reference input. This reference input is not witnessing anything it is simply provided in the plutus script context.
628
+ * @param txHash The transaction hash of the reference UTxO
629
+ * @param txIndex The transaction index of the reference UTxO
630
+ * @returns The MeshTxBuilder instance
631
+ */
632
+ this.readOnlyTxInReference = (txHash, txIndex) => {
633
+ this.meshTxBuilderBody.referenceInputs.push({ txHash, txIndex });
634
+ return this;
635
+ };
636
+ /**
637
+ * Set the instruction that it is currently using V1 Plutus minting scripts
638
+ * @returns The MeshTxBuilder instance
639
+ */
640
+ this.mintPlutusScriptV1 = () => {
641
+ this.addingPlutusMint = true;
642
+ this.plutusMintingScriptVersion = "V1";
643
+ return this;
644
+ };
645
+ /**
646
+ * Set the instruction that it is currently using V2 Plutus minting scripts
647
+ * @returns The MeshTxBuilder instance
648
+ */
649
+ this.mintPlutusScriptV2 = () => {
650
+ this.addingPlutusMint = true;
651
+ this.plutusMintingScriptVersion = "V2";
652
+ return this;
653
+ };
654
+ /**
655
+ * Set the instruction that it is currently using V3 Plutus minting scripts
656
+ * @returns The MeshTxBuilder instance
657
+ */
658
+ this.mintPlutusScriptV3 = () => {
659
+ this.addingPlutusMint = true;
660
+ this.plutusMintingScriptVersion = "V3";
661
+ return this;
662
+ };
663
+ /**
664
+ * Set the minting value of transaction
665
+ * @param quantity The quantity of asset to be minted
666
+ * @param policy The policy id of the asset to be minted
667
+ * @param name The hex of token name of the asset to be minted
668
+ * @returns The MeshTxBuilder instance
669
+ */
670
+ this.mint = (quantity, policy, name) => {
671
+ if (this.mintItem) {
672
+ this.queueMint();
673
+ }
674
+ this.mintItem = {
675
+ type: this.addingPlutusMint ? "Plutus" : "Native",
676
+ policyId: policy,
677
+ assetName: name,
678
+ amount: quantity
679
+ };
680
+ this.addingPlutusMint = false;
681
+ return this;
682
+ };
683
+ /**
684
+ * Set the minting script of current mint
685
+ * @param scriptCBOR The CBOR hex of the minting policy script
686
+ * @param version Optional - The Plutus script version
687
+ * @returns The MeshTxBuilder instance
688
+ */
689
+ this.mintingScript = (scriptCBOR) => {
690
+ if (!this.mintItem) throw Error("Undefined mint");
691
+ if (!this.mintItem.type) throw Error("Mint information missing");
692
+ if (this.mintItem.type === "Native") {
693
+ this.mintItem.scriptSource = {
694
+ type: "Provided",
695
+ scriptCode: scriptCBOR
696
+ };
697
+ }
698
+ if (this.mintItem.type === "Plutus") {
699
+ this.mintItem.scriptSource = {
700
+ type: "Provided",
701
+ script: {
702
+ code: scriptCBOR,
703
+ version: this.plutusMintingScriptVersion || "V2"
704
+ }
705
+ };
706
+ }
707
+ return this;
708
+ };
709
+ /**
710
+ * Use reference script for minting
711
+ * @param txHash The transaction hash of the UTxO
712
+ * @param txIndex The transaction index of the UTxO
713
+ * @returns The MeshTxBuilder instance
714
+ */
715
+ this.mintTxInReference = (txHash, txIndex) => {
716
+ if (!this.mintItem) throw Error("Undefined mint");
717
+ if (!this.mintItem.type) throw Error("Mint information missing");
718
+ if (this.mintItem.type == "Native") {
719
+ throw Error(
720
+ "Mint tx in reference can only be used on plutus script tokens"
721
+ );
722
+ }
723
+ if (!this.mintItem.policyId)
724
+ throw Error("PolicyId information missing from mint asset");
725
+ this.mintItem.scriptSource = {
726
+ type: "Inline",
727
+ txHash,
728
+ txIndex,
729
+ version: this.plutusMintingScriptVersion,
730
+ scriptSize: "0",
731
+ // TODO
732
+ scriptHash: ""
733
+ // TODO
734
+ };
735
+ return this;
736
+ };
737
+ /**
738
+ * Set the redeemer for minting
739
+ * @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
740
+ * @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
741
+ * @param exUnits The execution units budget for the redeemer
742
+ * @returns The MeshTxBuilder instance
743
+ */
744
+ this.mintReferenceTxInRedeemerValue = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
745
+ if (!this.mintItem) throw Error("Undefined mint");
746
+ if (this.mintItem.type == "Native") {
747
+ throw Error(
748
+ "Mint tx in reference can only be used on plutus script tokens"
749
+ );
750
+ } else if (this.mintItem.type == "Plutus") {
751
+ if (!this.mintItem.policyId)
752
+ throw Error("PolicyId information missing from mint asset");
753
+ }
754
+ this.mintItem.redeemer = this.castBuilderDataToRedeemer(
755
+ redeemer,
756
+ type,
757
+ exUnits
758
+ );
759
+ return this;
760
+ };
761
+ /**
762
+ * Set the redeemer for the reference input to be spent in same transaction
763
+ * @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
764
+ * @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
765
+ * @param exUnits The execution units budget for the redeemer
766
+ * @returns The MeshTxBuilder instance
767
+ */
768
+ this.mintRedeemerValue = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
769
+ this.mintReferenceTxInRedeemerValue(redeemer, type, exUnits);
770
+ return this;
771
+ };
772
+ /**
773
+ * Set the required signer of the transaction
774
+ * @param pubKeyHash The PubKeyHash of the required signer
775
+ * @returns The MeshTxBuilder instance
776
+ */
777
+ this.requiredSignerHash = (pubKeyHash) => {
778
+ this.meshTxBuilderBody.requiredSignatures.push(pubKeyHash);
779
+ return this;
780
+ };
781
+ /**
782
+ * Set the collateral UTxO for the transaction
783
+ * @param txHash The transaction hash of the collateral UTxO
784
+ * @param txIndex The transaction index of the collateral UTxO
785
+ * @param amount The asset amount of index of the collateral UTxO
786
+ * @param address The address of the collateral UTxO
787
+ * @returns The MeshTxBuilder instance
788
+ */
789
+ this.txInCollateral = (txHash, txIndex, amount, address) => {
790
+ if (this.collateralQueueItem) {
791
+ this.meshTxBuilderBody.collaterals.push(this.collateralQueueItem);
792
+ }
793
+ this.collateralQueueItem = {
794
+ type: "PubKey",
795
+ txIn: {
796
+ txHash,
797
+ txIndex,
798
+ amount,
799
+ address
800
+ }
801
+ };
802
+ return this;
803
+ };
804
+ /**
805
+ * Set the instruction that it is currently using V1 Plutus withdrawal scripts
806
+ * @returns The MeshTxBuilder instance
807
+ */
808
+ this.withdrawalPlutusScriptV1 = () => {
809
+ this.addingPlutusWithdrawal = true;
810
+ this.plutusWithdrawalScriptVersion = "V1";
811
+ return this;
812
+ };
813
+ /**
814
+ * Set the instruction that it is currently using V2 Plutus withdrawal scripts
815
+ * @returns The MeshTxBuilder instance
816
+ */
817
+ this.withdrawalPlutusScriptV2 = () => {
818
+ this.addingPlutusWithdrawal = true;
819
+ this.plutusWithdrawalScriptVersion = "V2";
820
+ return this;
821
+ };
822
+ /**
823
+ * Set the instruction that it is currently using V3 Plutus withdrawal scripts
824
+ * @returns The MeshTxBuilder instance
825
+ */
826
+ this.withdrawalPlutusScriptV3 = () => {
827
+ this.addingPlutusWithdrawal = true;
828
+ this.plutusWithdrawalScriptVersion = "V3";
829
+ return this;
830
+ };
831
+ /**
832
+ * Withdraw stake rewards in the MeshTxBuilder instance
833
+ * @param stakeAddress The address corresponding to the stake key
834
+ * @param coin The amount of lovelaces in the withdrawal
835
+ * @returns The MeshTxBuilder instance
836
+ */
837
+ this.withdrawal = (stakeAddress, coin) => {
838
+ if (this.withdrawalItem) {
839
+ this.queueWithdrawal();
840
+ }
841
+ if (this.addingPlutusWithdrawal) {
842
+ const withdrawal2 = {
843
+ plutusScriptWithdrawal: {
844
+ address: stakeAddress,
845
+ coin
846
+ }
847
+ };
848
+ this.meshTxBuilderBody.withdrawals.push(withdrawal2);
849
+ return this;
850
+ }
851
+ const withdrawal = {
852
+ pubKeyWithdrawal: {
853
+ address: stakeAddress,
854
+ coin
855
+ }
856
+ };
857
+ this.meshTxBuilderBody.withdrawals.push(withdrawal);
858
+ return this;
859
+ };
860
+ /**
861
+ * Add a withdrawal script to the MeshTxBuilder instance
862
+ * @param scriptCbor The script in CBOR format
863
+ * @param version The language version
864
+ * @returns The MeshTxBuilder instance
865
+ */
866
+ this.withdrawalScript = (scriptCbor, version) => {
867
+ if (!this.withdrawalItem)
868
+ throw Error("withdrawalScript: Undefined withdrawal");
869
+ if (!("plutusScriptWithdrawal" in this.withdrawalItem))
870
+ throw Error("withdrawalScript: Adding script to non plutus withdrawal");
871
+ this.withdrawalItem.plutusScriptWithdrawal.scriptSource = {
872
+ type: "Provided",
873
+ script: {
874
+ code: scriptCbor,
875
+ version: this.plutusWithdrawalScriptVersion || "V2"
876
+ }
877
+ };
878
+ return this;
879
+ };
880
+ /**
881
+ * Add a withdrawal reference to the MeshTxBuilder instance
882
+ * @param txHash The transaction hash of reference UTxO
883
+ * @param txIndex The transaction index of reference UTxO
884
+ * @param withdrawalScriptHash The script hash of the withdrawal script
885
+ * @param scriptSize The script size of the withdrawal script
886
+ * @returns The MeshTxBuilder instance
887
+ */
888
+ this.withdrawalTxInReference = (txHash, txIndex, withdrawalScriptHash, scriptSize) => {
889
+ if (!this.withdrawalItem)
890
+ throw Error("withdrawalTxInReference: Undefined withdrawal");
891
+ if (!("plutusScriptWithdrawal" in this.withdrawalItem))
892
+ throw Error(
893
+ "withdrawalTxInReference: Adding script reference to non plutus withdrawal"
894
+ );
895
+ this.withdrawalItem.plutusScriptWithdrawal.scriptSource = {
896
+ type: "Inline",
897
+ txHash,
898
+ txIndex,
899
+ scriptHash: withdrawalScriptHash,
900
+ version: this.plutusWithdrawalScriptVersion || "V2",
901
+ scriptSize: scriptSize || "0"
902
+ };
903
+ };
904
+ /**
905
+ * Set the transaction withdrawal redeemer value in the MeshTxBuilder instance
906
+ * @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
907
+ * @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
908
+ * @param exUnits The execution units budget for the redeemer
909
+ * @returns The MeshTxBuilder instance
910
+ */
911
+ this.withdrawalRedeemerValue = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
912
+ if (!this.withdrawalItem)
913
+ throw Error("withdrawalRedeemerValue: Undefined withdrawal");
914
+ if (!("plutusScriptWithdrawal" in this.withdrawalItem))
915
+ throw Error(
916
+ "withdrawalRedeemerValue: Adding redeemer to non plutus withdrawal"
917
+ );
918
+ this.withdrawalItem.plutusScriptWithdrawal.redeemer = this.castBuilderDataToRedeemer(redeemer, type, exUnits);
919
+ return this;
920
+ };
921
+ /**
922
+ * Creates a pool registration certificate, and adds it to the transaction
923
+ * @param poolParams Parameters for pool registration
924
+ * @returns The MeshTxBuilder instance
925
+ */
926
+ this.registerPoolCertificate = (poolParams) => {
927
+ this.meshTxBuilderBody.certificates.push({
928
+ type: "RegisterPool",
929
+ poolParams
930
+ });
931
+ return this;
932
+ };
933
+ /**
934
+ * Creates a stake registration certificate, and adds it to the transaction
935
+ * @param stakeKeyHash The keyHash of the stake key
936
+ * @returns The MeshTxBuilder instance
937
+ */
938
+ this.registerStakeCertificate = (stakeKeyHash) => {
939
+ this.meshTxBuilderBody.certificates.push({
940
+ type: "RegisterStake",
941
+ stakeKeyHash
942
+ });
943
+ return this;
944
+ };
945
+ /**
946
+ * Creates a stake delegation certificate, and adds it to the transaction
947
+ * This will delegate stake from the corresponding stake address to the pool
948
+ * @param stakeKeyHash The keyHash of the stake key
949
+ * @param poolId poolId can be in either bech32 or hex form
950
+ * @returns The MeshTxBuilder instance
951
+ */
952
+ this.delegateStakeCertificate = (stakeKeyHash, poolId) => {
953
+ this.meshTxBuilderBody.certificates.push({
954
+ type: "DelegateStake",
955
+ stakeKeyHash,
956
+ poolId
957
+ });
958
+ return this;
959
+ };
960
+ /**
961
+ * Creates a stake deregister certificate, and adds it to the transaction
962
+ * @param stakeKeyHash The keyHash of the stake key
963
+ * @returns The MeshTxBuilder instance
964
+ */
965
+ this.deregisterStakeCertificate = (stakeKeyHash) => {
966
+ this.meshTxBuilderBody.certificates.push({
967
+ type: "DeregisterStake",
968
+ stakeKeyHash
969
+ });
970
+ return this;
971
+ };
972
+ /**
973
+ * Creates a pool retire certificate, and adds it to the transaction
974
+ * @param poolId poolId can be in either bech32 or hex form
975
+ * @param epoch The intended epoch to retire the pool
976
+ * @returns The MeshTxBuilder instance
977
+ */
978
+ this.retirePoolCertificate = (poolId, epoch) => {
979
+ this.meshTxBuilderBody.certificates.push({
980
+ type: "RetirePool",
981
+ poolId,
982
+ epoch
983
+ });
984
+ return this;
985
+ };
986
+ /**
987
+ * Configure the address to accept change UTxO
988
+ * @param addr The address to accept change UTxO
989
+ * @returns The MeshTxBuilder instance
990
+ */
991
+ this.changeAddress = (addr) => {
992
+ this.meshTxBuilderBody.changeAddress = addr;
993
+ return this;
994
+ };
995
+ /**
996
+ * Set the transaction valid interval to be valid only after the slot
997
+ * @param slot The transaction is valid only after this slot
998
+ * @returns The MeshTxBuilder instance
999
+ */
1000
+ this.invalidBefore = (slot) => {
1001
+ this.meshTxBuilderBody.validityRange.invalidBefore = slot;
1002
+ return this;
1003
+ };
1004
+ /**
1005
+ * Set the transaction valid interval to be valid only before the slot
1006
+ * @param slot The transaction is valid only before this slot
1007
+ * @returns The MeshTxBuilder instance
1008
+ */
1009
+ this.invalidHereafter = (slot) => {
1010
+ this.meshTxBuilderBody.validityRange.invalidHereafter = slot;
1011
+ return this;
1012
+ };
1013
+ /**
1014
+ * Add metadata to the transaction
1015
+ * @param tag The tag of the metadata
1016
+ * @param metadata The metadata in any format
1017
+ * @returns The MeshTxBuilder instance
1018
+ */
1019
+ this.metadataValue = (tag, metadata) => {
1020
+ const metadataString = JSONBig.stringify(metadata);
1021
+ this.meshTxBuilderBody.metadata.push({ tag, metadata: metadataString });
1022
+ return this;
1023
+ };
1024
+ /**
1025
+ * Sign the transaction with the private key
1026
+ * @param skeyHex The private key in cborHex (with or without 5820 prefix, i.e. the format when generated from cardano-cli)
1027
+ * @returns
1028
+ */
1029
+ this.signingKey = (skeyHex) => {
1030
+ this.meshTxBuilderBody.signingKey.push(skeyHex);
1031
+ return this;
1032
+ };
1033
+ /**
1034
+ * EXPERIMENTAL - Selects utxos to fill output value and puts them into inputs
1035
+ * @param extraInputs The inputs already placed into the object will remain, these extra inputs will be used to fill the remaining value needed
1036
+ * @param threshold Extra value needed to be selected for, usually for paying fees and min UTxO value of change output
1037
+ */
1038
+ this.selectUtxosFrom = (extraInputs, threshold = 5e6) => {
1039
+ this.meshTxBuilderBody.extraInputs = extraInputs;
1040
+ this.meshTxBuilderBody.selectionThreshold = threshold;
1041
+ return this;
1042
+ };
1043
+ /**
1044
+ * Set the protocol parameters to be used for the transaction other than the default one
1045
+ * @param params (Part of) the protocol parameters to be used for the transaction
1046
+ * @returns The MeshTxBuilder instance
1047
+ */
1048
+ this.protocolParams = (params) => {
1049
+ const updatedParams = { ...DEFAULT_PROTOCOL_PARAMETERS3, ...params };
1050
+ this._protocolParams = updatedParams;
1051
+ return this;
1052
+ };
1053
+ this.queueAllLastItem = () => {
1054
+ if (this.txOutput) {
1055
+ this.meshTxBuilderBody.outputs.push(this.txOutput);
1056
+ this.txOutput = void 0;
1057
+ }
1058
+ if (this.txInQueueItem) {
1059
+ this.queueInput();
1060
+ }
1061
+ if (this.collateralQueueItem) {
1062
+ this.meshTxBuilderBody.collaterals.push(this.collateralQueueItem);
1063
+ this.collateralQueueItem = void 0;
1064
+ }
1065
+ if (this.mintItem) {
1066
+ this.queueMint();
1067
+ }
1068
+ if (this.withdrawalItem) {
1069
+ this.queueWithdrawal();
1070
+ }
1071
+ };
1072
+ this.queueInput = () => {
1073
+ if (!this.txInQueueItem) throw Error("queueInput: Undefined input");
1074
+ if (this.txInQueueItem.type === "Script") {
1075
+ if (!this.txInQueueItem.scriptTxIn) {
1076
+ throw Error(
1077
+ "queueInput: Script input does not contain script, datum, or redeemer information"
1078
+ );
1079
+ } else {
1080
+ if (!this.txInQueueItem.scriptTxIn.datumSource)
1081
+ throw Error(
1082
+ "queueInput: Script input does not contain datum information"
1083
+ );
1084
+ if (!this.txInQueueItem.scriptTxIn.redeemer)
1085
+ throw Error(
1086
+ "queueInput: Script input does not contain redeemer information"
1087
+ );
1088
+ if (!this.txInQueueItem.scriptTxIn.scriptSource)
1089
+ throw Error(
1090
+ "queueInput: Script input does not contain script information"
1091
+ );
1092
+ }
1093
+ }
1094
+ this.meshTxBuilderBody.inputs.push(this.txInQueueItem);
1095
+ this.txInQueueItem = void 0;
1096
+ };
1097
+ this.queueMint = () => {
1098
+ if (!this.mintItem) throw Error("queueMint: Undefined mint");
1099
+ if (!this.mintItem.scriptSource)
1100
+ throw Error("queueMint: Missing mint script information");
1101
+ this.meshTxBuilderBody.mints.push(this.mintItem);
1102
+ this.mintItem = void 0;
1103
+ };
1104
+ this.queueWithdrawal = () => {
1105
+ if (!this.withdrawalItem)
1106
+ throw Error("queueWithdrawal: Undefined withdrawal");
1107
+ if ("plutusScriptWithdrawal" in this.withdrawalItem) {
1108
+ if (!this.withdrawalItem.plutusScriptWithdrawal.scriptSource) {
1109
+ throw Error("queueWithdrawal: Missing withdrawal script information");
1110
+ }
1111
+ if (!this.withdrawalItem.plutusScriptWithdrawal.redeemer) {
1112
+ throw Error("queueWithdrawal: Missing withdrawal redeemer information");
1113
+ }
1114
+ }
1115
+ this.meshTxBuilderBody.withdrawals.push(this.withdrawalItem);
1116
+ this.withdrawalItem = void 0;
1117
+ };
1118
+ this.castRawDataToJsonString = (rawData) => {
1119
+ if (typeof rawData === "object") {
1120
+ return JSONBig.stringify(rawData);
1121
+ } else {
1122
+ return rawData;
1123
+ }
1124
+ };
1125
+ this.castBuilderDataToRedeemer = (redeemer, type = "Mesh", exUnits = { ...DEFAULT_REDEEMER_BUDGET }) => {
1126
+ let red;
1127
+ let content = redeemer;
1128
+ if (type === "Mesh") {
1129
+ red = {
1130
+ data: {
1131
+ type,
1132
+ content
1133
+ },
1134
+ exUnits
1135
+ };
1136
+ return red;
1137
+ }
1138
+ if (type === "JSON") {
1139
+ content = this.castRawDataToJsonString(redeemer);
1140
+ }
1141
+ red = {
1142
+ data: {
1143
+ type,
1144
+ content
1145
+ },
1146
+ exUnits
1147
+ };
1148
+ return red;
1149
+ };
1150
+ this.updateRedeemer = (meshTxBuilderBody, txEvaluation) => {
1151
+ txEvaluation.forEach((redeemerEvaluation) => {
1152
+ switch (redeemerEvaluation.tag) {
1153
+ case "SPEND": {
1154
+ const input = meshTxBuilderBody.inputs[redeemerEvaluation.index];
1155
+ if (input.type == "Script" && input.scriptTxIn.redeemer) {
1156
+ input.scriptTxIn.redeemer.exUnits.mem = Math.floor(
1157
+ redeemerEvaluation.budget.mem * this.txEvaluationMultiplier
1158
+ );
1159
+ input.scriptTxIn.redeemer.exUnits.steps = Math.floor(
1160
+ redeemerEvaluation.budget.steps * this.txEvaluationMultiplier
1161
+ );
1162
+ }
1163
+ break;
1164
+ }
1165
+ case "MINT": {
1166
+ const mint = meshTxBuilderBody.mints[redeemerEvaluation.index];
1167
+ if (mint.type == "Plutus" && mint.redeemer) {
1168
+ mint.redeemer.exUnits.mem = Math.floor(
1169
+ redeemerEvaluation.budget.mem * this.txEvaluationMultiplier
1170
+ );
1171
+ mint.redeemer.exUnits.steps = Math.floor(
1172
+ redeemerEvaluation.budget.steps * this.txEvaluationMultiplier
1173
+ );
1174
+ }
1175
+ break;
1176
+ }
1177
+ case "CERT":
1178
+ break;
1179
+ case "REWARD":
1180
+ break;
1181
+ }
1182
+ });
1183
+ };
1184
+ this.addUtxosFromSelection = () => {
1185
+ const requiredAssets = this.meshTxBuilderBody.outputs.reduce(
1186
+ (map, output) => {
1187
+ const outputAmount = output.amount;
1188
+ outputAmount.forEach((asset) => {
1189
+ const { unit, quantity } = asset;
1190
+ const existingQuantity = Number(map.get(unit)) || 0;
1191
+ map.set(unit, String(existingQuantity + Number(quantity)));
1192
+ });
1193
+ return map;
1194
+ },
1195
+ /* @__PURE__ */ new Map()
1196
+ );
1197
+ this.meshTxBuilderBody.inputs.reduce((map, input) => {
1198
+ const inputAmount = input.txIn.amount;
1199
+ inputAmount?.forEach((asset) => {
1200
+ const { unit, quantity } = asset;
1201
+ const existingQuantity = Number(map.get(unit)) || 0;
1202
+ map.set(unit, String(existingQuantity - Number(quantity)));
1203
+ });
1204
+ return map;
1205
+ }, requiredAssets);
1206
+ this.meshTxBuilderBody.mints.reduce((map, mint) => {
1207
+ const mintAmount = {
1208
+ unit: mint.policyId + mint.assetName,
1209
+ quantity: String(mint.amount)
1210
+ };
1211
+ const existingQuantity = Number(map.get(mintAmount.unit)) || 0;
1212
+ map.set(
1213
+ mintAmount.unit,
1214
+ String(existingQuantity - Number(mintAmount.quantity))
1215
+ );
1216
+ return map;
1217
+ }, requiredAssets);
1218
+ const selectedInputs = experimentalSelectUtxos(
1219
+ requiredAssets,
1220
+ this.meshTxBuilderBody.extraInputs,
1221
+ this.meshTxBuilderBody.selectionThreshold.toString()
1222
+ );
1223
+ selectedInputs.forEach((input) => {
1224
+ const pubKeyTxIn = {
1225
+ type: "PubKey",
1226
+ txIn: {
1227
+ txHash: input.input.txHash,
1228
+ txIndex: input.input.outputIndex,
1229
+ amount: input.output.amount,
1230
+ address: input.output.address
1231
+ }
1232
+ };
1233
+ this.meshTxBuilderBody.inputs.push(pubKeyTxIn);
1234
+ });
1235
+ };
1236
+ this.removeDuplicateInputs = () => {
1237
+ const { inputs } = this.meshTxBuilderBody;
1238
+ const getTxInId = (txIn) => `${txIn.txHash}#${txIn.txIndex}`;
1239
+ const currentTxInIds = [];
1240
+ const addedInputs = [];
1241
+ for (let i = 0; i < inputs.length; i += 1) {
1242
+ const currentInput = inputs[i];
1243
+ const currentTxInId = getTxInId(currentInput.txIn);
1244
+ if (currentTxInIds.includes(currentTxInId)) {
1245
+ inputs.splice(i, 1);
1246
+ i -= 1;
1247
+ } else {
1248
+ addedInputs.push(currentInput);
1249
+ }
1250
+ }
1251
+ this.meshTxBuilderBody.inputs = addedInputs;
1252
+ };
1253
+ this.emptyTxBuilderBody = () => {
1254
+ this.meshTxBuilderBody = emptyTxBuilderBody();
1255
+ return emptyTxBuilderBody;
1256
+ };
1257
+ this.reset = () => {
1258
+ this.meshTxBuilderBody = emptyTxBuilderBody();
1259
+ this.txEvaluationMultiplier = 1.1;
1260
+ this.txOutput = void 0;
1261
+ this.addingPlutusScriptInput = false;
1262
+ this.plutusSpendingScriptVersion = void 0;
1263
+ this.addingPlutusMint = false;
1264
+ this.plutusMintingScriptVersion = void 0;
1265
+ this.addingPlutusWithdrawal = false;
1266
+ this.plutusWithdrawalScriptVersion = void 0;
1267
+ this._protocolParams = DEFAULT_PROTOCOL_PARAMETERS3;
1268
+ this.mintItem = void 0;
1269
+ this.txInQueueItem = void 0;
1270
+ this.withdrawalItem = void 0;
1271
+ this.collateralQueueItem = void 0;
1272
+ this.refScriptTxInQueueItem = void 0;
1273
+ };
1274
+ this.meshTxBuilderBody = emptyTxBuilderBody();
1275
+ }
1276
+ };
1277
+
1278
+ // src/mesh-tx-builder/index.ts
1279
+ import { CSLSerializer } from "@meshsdk/core-csl";
1280
+ var MeshTxBuilder = class extends MeshTxBuilderCore {
1281
+ constructor({
1282
+ serializer,
1283
+ fetcher,
1284
+ submitter,
1285
+ evaluator,
1286
+ params,
1287
+ isHydra = false
1288
+ } = {}) {
1289
+ super();
1290
+ this.txHex = "";
1291
+ this.queriedTxHashes = /* @__PURE__ */ new Set();
1292
+ this.queriedUTxOs = {};
1293
+ /**
1294
+ * It builds the transaction and query the blockchain for missing information
1295
+ * @param customizedTx The optional customized transaction body
1296
+ * @returns The signed transaction in hex ready to submit / signed by client
1297
+ */
1298
+ this.complete = async (customizedTx) => {
1299
+ if (customizedTx) {
1300
+ this.meshTxBuilderBody = customizedTx;
1301
+ } else {
1302
+ this.queueAllLastItem();
1303
+ }
1304
+ this.removeDuplicateInputs();
1305
+ const { inputs, collaterals } = this.meshTxBuilderBody;
1306
+ const incompleteTxIns = [...inputs, ...collaterals].filter(
1307
+ (txIn) => !this.isInputComplete(txIn)
1308
+ );
1309
+ await this.queryAllTxInfo(incompleteTxIns);
1310
+ incompleteTxIns.forEach((txIn) => {
1311
+ this.completeTxInformation(txIn);
1312
+ });
1313
+ this.addUtxosFromSelection();
1314
+ let txHex = this.serializer.serializeTxBody(
1315
+ this.meshTxBuilderBody,
1316
+ this._protocolParams
1317
+ );
1318
+ if (this.evaluator) {
1319
+ const txEvaluation = await this.evaluator.evaluateTx(txHex).catch((error) => {
1320
+ throw Error(`Tx evaluation failed: ${error}`);
1321
+ });
1322
+ this.updateRedeemer(this.meshTxBuilderBody, txEvaluation);
1323
+ txHex = this.serializer.serializeTxBody(
1324
+ this.meshTxBuilderBody,
1325
+ this._protocolParams
1326
+ );
1327
+ }
1328
+ console.log(txHex);
1329
+ this.txHex = txHex;
1330
+ return txHex;
1331
+ };
1332
+ /**
1333
+ * It builds the transaction without dependencies
1334
+ * @param customizedTx The optional customized transaction body
1335
+ * @returns The signed transaction in hex ready to submit / signed by client
1336
+ */
1337
+ this.completeSync = (customizedTx) => {
1338
+ if (customizedTx) {
1339
+ this.meshTxBuilderBody = customizedTx;
1340
+ } else {
1341
+ this.queueAllLastItem();
1342
+ }
1343
+ return this.serializer.serializeTxBody(
1344
+ this.meshTxBuilderBody,
1345
+ this._protocolParams
1346
+ );
1347
+ };
1348
+ /**
1349
+ * Complete the signing process
1350
+ * @returns The signed transaction in hex
1351
+ */
1352
+ this.completeSigning = () => {
1353
+ const signedTxHex = this.serializer.addSigningKeys(
1354
+ this.txHex,
1355
+ this.meshTxBuilderBody.signingKey
1356
+ );
1357
+ this.txHex = signedTxHex;
1358
+ return signedTxHex;
1359
+ };
1360
+ /**
1361
+ * Submit transactions to the blockchain using the fetcher instance
1362
+ * @param txHex The signed transaction in hex
1363
+ * @returns
1364
+ */
1365
+ this.submitTx = async (txHex) => {
1366
+ const txHash = await this.submitter?.submitTx(txHex);
1367
+ return txHash;
1368
+ };
1369
+ /**
1370
+ * Get the UTxO information from the blockchain
1371
+ * @param TxHash The TxIn object that contains the txHash and txIndex, while missing amount and address information
1372
+ */
1373
+ this.getUTxOInfo = async (txHash) => {
1374
+ let utxos = [];
1375
+ if (!this.queriedTxHashes.has(txHash)) {
1376
+ this.queriedTxHashes.add(txHash);
1377
+ utxos = await this.fetcher?.fetchUTxOs(txHash) || [];
1378
+ this.queriedUTxOs[txHash] = utxos;
1379
+ }
1380
+ };
1381
+ this.queryAllTxInfo = (incompleteTxIns) => {
1382
+ const queryUTxOPromises = [];
1383
+ if (incompleteTxIns.length > 0 && !this.fetcher)
1384
+ throw Error(
1385
+ "Transaction information is incomplete while no fetcher instance is provided"
1386
+ );
1387
+ for (let i = 0; i < incompleteTxIns.length; i++) {
1388
+ const currentTxIn = incompleteTxIns[i];
1389
+ if (!this.isInputInfoComplete(currentTxIn)) {
1390
+ queryUTxOPromises.push(this.getUTxOInfo(currentTxIn.txIn.txHash));
1391
+ }
1392
+ if (currentTxIn.type === "Script" && currentTxIn.scriptTxIn.scriptSource?.type === "Inline" && !this.isRefScriptInfoComplete(currentTxIn)) {
1393
+ queryUTxOPromises.push(
1394
+ this.getUTxOInfo(currentTxIn.scriptTxIn.scriptSource.txHash)
1395
+ );
1396
+ }
1397
+ }
1398
+ return Promise.all(queryUTxOPromises);
1399
+ };
1400
+ this.completeTxInformation = (input) => {
1401
+ if (!this.isInputInfoComplete(input)) {
1402
+ const utxos = this.queriedUTxOs[input.txIn.txHash];
1403
+ const utxo = utxos?.find(
1404
+ (utxo2) => utxo2.input.outputIndex === input.txIn.txIndex
1405
+ );
1406
+ const amount = utxo?.output.amount;
1407
+ const address = utxo?.output.address;
1408
+ if (!amount || amount.length === 0)
1409
+ throw Error(
1410
+ `Couldn't find value information for ${input.txIn.txHash}#${input.txIn.txIndex}`
1411
+ );
1412
+ input.txIn.amount = amount;
1413
+ if (input.type === "PubKey") {
1414
+ if (!address || address === "")
1415
+ throw Error(
1416
+ `Couldn't find address information for ${input.txIn.txHash}#${input.txIn.txIndex}`
1417
+ );
1418
+ input.txIn.address = address;
1419
+ }
1420
+ }
1421
+ if (input.type === "Script" && input.scriptTxIn.scriptSource?.type == "Inline" && !this.isRefScriptInfoComplete(input)) {
1422
+ const scriptSource = input.scriptTxIn.scriptSource;
1423
+ const refUtxos = this.queriedUTxOs[scriptSource.txHash];
1424
+ const scriptRefUtxo = refUtxos.find(
1425
+ (utxo) => utxo.input.outputIndex === scriptSource.txIndex
1426
+ );
1427
+ if (!scriptRefUtxo)
1428
+ throw Error(
1429
+ `Couldn't find script reference utxo for ${scriptSource.txHash}#${scriptSource.txIndex}`
1430
+ );
1431
+ scriptSource.scriptHash = scriptRefUtxo?.output.scriptHash;
1432
+ }
1433
+ };
1434
+ this.isInputComplete = (txIn) => {
1435
+ if (txIn.type === "PubKey") return this.isInputInfoComplete(txIn);
1436
+ if (txIn.type === "Script") {
1437
+ return this.isInputInfoComplete(txIn) && this.isRefScriptInfoComplete(txIn);
1438
+ }
1439
+ return true;
1440
+ };
1441
+ this.isInputInfoComplete = (txIn) => {
1442
+ const { amount, address } = txIn.txIn;
1443
+ if (txIn.type === "PubKey" && (!amount || !address)) return false;
1444
+ if (txIn.type === "Script") {
1445
+ if (!amount) return false;
1446
+ }
1447
+ return true;
1448
+ };
1449
+ this.isRefScriptInfoComplete = (scriptTxIn) => {
1450
+ const { scriptSource } = scriptTxIn.scriptTxIn;
1451
+ if (scriptSource?.type === "Inline" && !scriptSource?.scriptHash)
1452
+ return false;
1453
+ return true;
1454
+ };
1455
+ if (serializer) {
1456
+ this.serializer = serializer;
1457
+ } else {
1458
+ this.serializer = new CSLSerializer();
1459
+ }
1460
+ if (fetcher) this.fetcher = fetcher;
1461
+ if (submitter) this.submitter = submitter;
1462
+ if (evaluator) this.evaluator = evaluator;
1463
+ if (params) this.protocolParams(params);
1464
+ if (isHydra)
1465
+ this.protocolParams({
1466
+ minFeeA: 0,
1467
+ minFeeB: 0,
1468
+ priceMem: 0,
1469
+ priceStep: 0,
1470
+ collateralPercent: 0,
1471
+ coinsPerUtxoSize: 0
1472
+ });
1473
+ }
1474
+ };
1475
+
1476
+ // src/scripts/forge.script.ts
1477
+ import {
1478
+ buildScriptPubkey,
1479
+ deserializeEd25519KeyHash,
1480
+ toNativeScript,
1481
+ resolvePaymentKeyHash
1482
+ } from "@meshsdk/core-cst";
1483
+ var ForgeScript = class {
1484
+ static withOneSignature(address) {
1485
+ const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address));
1486
+ return buildScriptPubkey(keyHash).toCbor();
1487
+ }
1488
+ // static withAtLeastNSignatures(
1489
+ // addresses: string[], minimumRequired: number,
1490
+ // ): string {
1491
+ // const nativeScripts = csl.NativeScripts.new();
1492
+ // addresses.forEach((address) => {
1493
+ // const keyHash = deserializeEd25519KeyHash(
1494
+ // resolvePaymentKeyHash(address),
1495
+ // );
1496
+ // nativeScripts.add(buildScriptPubkey(keyHash));
1497
+ // });
1498
+ // const scriptNOfK = csl.ScriptNOfK.new(minimumRequired, nativeScripts);
1499
+ // return csl.NativeScript.new_script_any(scriptNOfK).to_hex();
1500
+ // }
1501
+ // static withAnySignature(addresses: string[]): string {
1502
+ // const nativeScripts = csl.NativeScripts.new();
1503
+ // addresses.forEach((address) => {
1504
+ // const keyHash = deserializeEd25519KeyHash(
1505
+ // resolvePaymentKeyHash(address),
1506
+ // );
1507
+ // nativeScripts.add(buildScriptPubkey(keyHash));
1508
+ // });
1509
+ // const scriptAny = csl.ScriptAny.new(nativeScripts);
1510
+ // return csl.NativeScript.new_script_any(scriptAny).to_hex();
1511
+ // }
1512
+ // static withAllSignatures(addresses: string[]): string {
1513
+ // const nativeScripts = csl.NativeScripts.new();
1514
+ // addresses.forEach((address) => {
1515
+ // const keyHash = deserializeEd25519KeyHash(
1516
+ // resolvePaymentKeyHash(address),
1517
+ // );
1518
+ // nativeScripts.add(buildScriptPubkey(keyHash));
1519
+ // });
1520
+ // const scriptAll = csl.ScriptAll.new(nativeScripts);
1521
+ // return csl.NativeScript.new_script_any(scriptAll).to_hex();
1522
+ // }
1523
+ static fromNativeScript(script) {
1524
+ return toNativeScript(script).toCbor();
1525
+ }
1526
+ };
1527
+
1528
+ // src/transaction/index.ts
1529
+ import {
1530
+ CIP68_100,
1531
+ CIP68_222,
1532
+ DEFAULT_REDEEMER_BUDGET as DEFAULT_REDEEMER_BUDGET2,
1533
+ POLICY_ID_LENGTH,
1534
+ SUPPORTED_TOKENS,
1535
+ hexToString,
1536
+ metadataToCip68,
1537
+ stringToHex
1538
+ } from "@meshsdk/common";
1539
+ import {
1540
+ deserializeNativeScript,
1541
+ deserializePlutusScript,
1542
+ fromScriptRef
1543
+ } from "@meshsdk/core-cst";
1544
+ var Transaction = class {
1545
+ constructor(options) {
1546
+ this.isCollateralNeeded = false;
1547
+ this.txBuilder = new MeshTxBuilder(options);
1548
+ this.initiator = options.initiator;
1549
+ }
1550
+ /**
1551
+ * Adds an output to the transaction.
1552
+ *
1553
+ * @param recipient The recipient of the output.
1554
+ * @param assets The assets to send. Provide string for lovelace and Asset[] for tokens and/or lovelace.
1555
+ * @returns The transaction builder.
1556
+ * @see {@link https://meshjs.dev/apis/transaction#sendAssets}
1557
+ */
1558
+ sendAssets(recipient, assets) {
1559
+ if (typeof assets === "string") {
1560
+ assets = [
1561
+ {
1562
+ unit: "lovelace",
1563
+ quantity: assets
1564
+ }
1565
+ ];
1566
+ }
1567
+ if (typeof recipient === "string") {
1568
+ this.txBuilder.txOut(recipient, assets);
1569
+ }
1570
+ if (typeof recipient === "object") {
1571
+ this.txBuilder.txOut(recipient.address, assets);
1572
+ if (recipient.datum) {
1573
+ if (recipient.datum.inline) {
1574
+ this.txBuilder.txOutInlineDatumValue(recipient.datum.value);
1575
+ } else {
1576
+ this.txBuilder.txOutDatumHashValue(recipient.datum.value);
1577
+ }
1578
+ }
1579
+ }
1580
+ return this;
1581
+ }
1582
+ /**
1583
+ * Suggest deprecated - Adds a transaction output to the transaction.
1584
+ * Use sendAssets instead:
1585
+ * ```ts
1586
+ * this.sendAssets(recipient, lovelace);
1587
+ * ```
1588
+ *
1589
+ * Deprecation reason - Unnecessary implementation which might cause confusion.
1590
+ *
1591
+ * @param {Recipient} recipient The recipient of the transaction.
1592
+ * @param {string} lovelace The amount of lovelace to send.
1593
+ * @returns {Transaction} The Transaction object.
1594
+ * @see {@link https://meshjs.dev/apis/transaction#sendAda}
1595
+ */
1596
+ sendLovelace(recipient, lovelace) {
1597
+ return this.sendAssets(recipient, lovelace);
1598
+ }
1599
+ /**
1600
+ * Suggest deprecated - Adds stable coins transaction output to the transaction.
1601
+ * Please use sendAssets with helper function to obtain token unit instead:
1602
+ * ```ts
1603
+ * const assets = [{ unit: SUPPORTED_TOKENS.GIMBAL, quantity: "100" }]
1604
+ * transaction.sendAssets(recipient, assets)
1605
+ * ```
1606
+ *
1607
+ * Deprecation reason - Required maintenance on tokens.
1608
+ *
1609
+ * @param {Recipient} recipient The recipient of the transaction.
1610
+ * @param {Token} ticker The ticker of the token to send.
1611
+ * @param {string} amount The amount of the token to send.
1612
+ * @returns {Transaction} The Transaction object.
1613
+ * @see {@link https://meshjs.dev/apis/transaction#sendToken}
1614
+ */
1615
+ sendToken(recipient, ticker, amount) {
1616
+ const assets = [{ unit: SUPPORTED_TOKENS[ticker], quantity: amount }];
1617
+ return this.sendAssets(recipient, assets);
1618
+ }
1619
+ /**
1620
+ * Adds an output to the transaction.
1621
+ * Suggest deprecated - use sendAssets instead:
1622
+ *
1623
+ * ```ts
1624
+ * const assets = value.output.amount;
1625
+ * this.sendAssets(recipient, assets);
1626
+ * ```
1627
+ * Deprecation reason - Unnecessary implementation which might cause confusion.
1628
+ *
1629
+ * @param {Recipient} recipient The recipient of the output.
1630
+ * @param {UTxO} value The UTxO value of the output.
1631
+ * @returns {Transaction} The Transaction object.
1632
+ */
1633
+ sendValue(recipient, value) {
1634
+ const assets = value.output.amount;
1635
+ return this.sendAssets(recipient, assets);
1636
+ }
1637
+ /**
1638
+ * Sets the inputs for the transaction.
1639
+ *
1640
+ * @param {UTxO[]} inputs The inputs to set.
1641
+ * @returns {Transaction} The transaction.
1642
+ */
1643
+ setTxInputs(inputs) {
1644
+ inputs.forEach((input) => {
1645
+ this.txBuilder.txIn(
1646
+ input.input.txHash,
1647
+ input.input.outputIndex,
1648
+ input.output.amount,
1649
+ input.output.address
1650
+ );
1651
+ });
1652
+ return this;
1653
+ }
1654
+ /**
1655
+ * Sets the reference inputs for the transaction.
1656
+ *
1657
+ * @param {UTxO[]} inputs The reference inputs to set.
1658
+ * @returns {Transaction} The transaction.
1659
+ */
1660
+ setTxRefInputs(inputs) {
1661
+ inputs.forEach((input) => {
1662
+ this.txBuilder.readOnlyTxInReference(
1663
+ input.input.txHash,
1664
+ input.input.outputIndex
1665
+ );
1666
+ });
1667
+ return this;
1668
+ }
1669
+ /**
1670
+ * Sets the native script for the transaction.
1671
+ * @param {NativeScript} script The native script to spend from.
1672
+ * @param {UTxO} utxo The UTxO attached to the script.
1673
+ * @returns {Transaction} The Transaction object.
1674
+ */
1675
+ setNativeScriptInput(script, utxo) {
1676
+ const { scriptCbor } = this.txBuilder.serializer.deserializer.script.deserializeNativeScript(
1677
+ script
1678
+ );
1679
+ this.txBuilder.txIn(
1680
+ utxo.input.txHash,
1681
+ utxo.input.outputIndex,
1682
+ utxo.output.amount,
1683
+ utxo.output.address
1684
+ ).txInScript(scriptCbor);
1685
+ return this;
1686
+ }
1687
+ // TODO: nuke this probably as the input type is too confusing
1688
+ redeemValue(options) {
1689
+ const { value, script, datum, redeemer } = options;
1690
+ const red = redeemer || {
1691
+ data: { alternative: 0, fields: ["mesh"] },
1692
+ budget: DEFAULT_REDEEMER_BUDGET2
1693
+ };
1694
+ if ("code" in script) {
1695
+ this.isCollateralNeeded = true;
1696
+ this.spendingPlutusScript(script).txIn(
1697
+ value.input.txHash,
1698
+ value.input.outputIndex,
1699
+ value.output.amount,
1700
+ value.output.address
1701
+ ).txInScript(script.code).txInRedeemerValue(red.data, "Mesh", red.budget);
1702
+ }
1703
+ if ("output" in script) {
1704
+ if (!script.output.scriptRef) {
1705
+ throw new Error("redeemValue: No script reference found in UTxO");
1706
+ }
1707
+ const scriptRef = fromScriptRef(script.output.scriptRef);
1708
+ if (!scriptRef || !("code" in scriptRef)) {
1709
+ throw new Error("redeemValue: Script reference not found");
1710
+ }
1711
+ this.isCollateralNeeded = true;
1712
+ this.spendingPlutusScript(scriptRef).txIn(
1713
+ value.input.txHash,
1714
+ value.input.outputIndex,
1715
+ value.output.amount,
1716
+ value.output.address
1717
+ ).spendingTxInReference(
1718
+ script.input.txHash,
1719
+ script.input.outputIndex,
1720
+ script.output.scriptHash
1721
+ ).txInRedeemerValue(red.data, "Mesh", red.budget);
1722
+ }
1723
+ if (datum) {
1724
+ this.txBuilder.txInDatumValue(datum);
1725
+ } else {
1726
+ this.txBuilder.txInInlineDatumPresent();
1727
+ }
1728
+ return this;
1729
+ }
1730
+ // TODO: nuke this probably as the input type is too confusing
1731
+ mintAsset(forgeScript, mint, redeemer) {
1732
+ const assetQuantity = mint.assetQuantity;
1733
+ let assetNameHex = stringToHex(mint.assetName);
1734
+ const referenceAssetNameHex = CIP68_100(assetNameHex);
1735
+ if (mint.cip68ScriptAddress) {
1736
+ assetNameHex = CIP68_222(assetNameHex);
1737
+ }
1738
+ let policyId = "";
1739
+ switch (typeof forgeScript) {
1740
+ case "string":
1741
+ policyId = deserializeNativeScript(forgeScript).hash().toString();
1742
+ this.txBuilder.mint(assetQuantity, policyId, assetNameHex).mintingScript(forgeScript);
1743
+ if (mint.cip68ScriptAddress) {
1744
+ this.txBuilder.mint(assetQuantity, policyId, referenceAssetNameHex).mintingScript(forgeScript);
1745
+ }
1746
+ break;
1747
+ case "object":
1748
+ if (!redeemer)
1749
+ throw new Error(
1750
+ "burnAsset: Redeemer data is required for Plutus minting"
1751
+ );
1752
+ if ("code" in forgeScript) {
1753
+ policyId = deserializePlutusScript(
1754
+ forgeScript.code,
1755
+ forgeScript.version
1756
+ ).hash().toString();
1757
+ this.isCollateralNeeded = true;
1758
+ this.mintPlutusScript(forgeScript).mint(assetQuantity, policyId, assetNameHex).mintingScript(forgeScript.code).mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
1759
+ if (mint.cip68ScriptAddress) {
1760
+ this.mintPlutusScript(forgeScript).mint(assetQuantity, policyId, referenceAssetNameHex).mintingScript(forgeScript.code).mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
1761
+ }
1762
+ break;
1763
+ }
1764
+ if ("output" in forgeScript) {
1765
+ if (!forgeScript.output.scriptRef) {
1766
+ throw new Error("mintAsset: No script reference found in UTxO");
1767
+ }
1768
+ const script = fromScriptRef(forgeScript.output.scriptRef);
1769
+ if (!script) {
1770
+ throw new Error("mintAsset: Script reference not found");
1771
+ }
1772
+ if ("code" in script) {
1773
+ policyId = deserializePlutusScript(script.code, script.version).hash().toString();
1774
+ this.isCollateralNeeded = true;
1775
+ this.mintPlutusScript(script).mint(assetQuantity, policyId, assetNameHex).mintTxInReference(
1776
+ forgeScript.input.txHash,
1777
+ forgeScript.input.outputIndex
1778
+ ).mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
1779
+ if (mint.cip68ScriptAddress) {
1780
+ this.mintPlutusScript(script).mint(assetQuantity, policyId, referenceAssetNameHex).mintTxInReference(
1781
+ forgeScript.input.txHash,
1782
+ forgeScript.input.outputIndex
1783
+ ).mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
1784
+ break;
1785
+ }
1786
+ break;
1787
+ } else {
1788
+ throw new Error(
1789
+ "mintAsset: Reference script minting not implemented"
1790
+ );
1791
+ }
1792
+ }
1793
+ break;
1794
+ }
1795
+ if (mint.metadata && mint.label) {
1796
+ this.setMetadata(Number(mint.label), {
1797
+ [policyId]: {
1798
+ [mint.assetName]: mint.metadata
1799
+ },
1800
+ version: 1
1801
+ });
1802
+ }
1803
+ if (mint.recipient) {
1804
+ this.sendAssets(mint.recipient, [
1805
+ { unit: policyId + assetNameHex, quantity: mint.assetQuantity }
1806
+ ]);
1807
+ }
1808
+ if (mint.cip68ScriptAddress) {
1809
+ this.sendAssets(
1810
+ {
1811
+ address: mint.cip68ScriptAddress,
1812
+ datum: { inline: true, value: metadataToCip68(mint.metadata) }
1813
+ },
1814
+ [
1815
+ {
1816
+ unit: policyId + referenceAssetNameHex,
1817
+ quantity: mint.assetQuantity
1818
+ }
1819
+ ]
1820
+ );
1821
+ }
1822
+ return this;
1823
+ }
1824
+ // TODO: nuke this probably as the input type is too confusing
1825
+ // TO be deprecated as it doesnt support reference script minting native assets
1826
+ burnAsset(forgeScript, asset, redeemer) {
1827
+ const assetQuantity = "-" + asset.quantity;
1828
+ const mint = {
1829
+ assetName: hexToString(asset.unit.slice(POLICY_ID_LENGTH)),
1830
+ assetQuantity
1831
+ };
1832
+ try {
1833
+ this.mintAsset(forgeScript, mint, redeemer);
1834
+ } catch (error) {
1835
+ throw new Error("burnAsset: " + error);
1836
+ }
1837
+ return this;
1838
+ }
1839
+ /**
1840
+ * Sets the change address for the transaction.
1841
+ *
1842
+ * @param {string} changeAddress The change address.
1843
+ * @returns {Transaction} The Transaction object.
1844
+ */
1845
+ setChangeAddress(changeAddress) {
1846
+ this.txBuilder.changeAddress(changeAddress);
1847
+ return this;
1848
+ }
1849
+ /**
1850
+ * Sets the collateral for the transaction.
1851
+ *
1852
+ * @param {UTxO[]} collateral - Set the UTxO for collateral.
1853
+ * @returns {Transaction} The Transaction object.
1854
+ */
1855
+ setCollateral(collateral) {
1856
+ collateral.forEach((collateralUtxo) => {
1857
+ this.txBuilder.txInCollateral(
1858
+ collateralUtxo.input.txHash,
1859
+ collateralUtxo.input.outputIndex,
1860
+ collateralUtxo.output.amount,
1861
+ collateralUtxo.output.address
1862
+ );
1863
+ });
1864
+ return this;
1865
+ }
1866
+ /**
1867
+ * Sets the required signers for the transaction.
1868
+ *
1869
+ * @param {string[]} addresses The addresses of the required signers.
1870
+ * @returns {Transaction} The Transaction object.
1871
+ */
1872
+ setRequiredSigners(addresses) {
1873
+ addresses.forEach((address) => {
1874
+ const { pubKeyHash } = this.txBuilder.serializer.deserializer.key.deserializeAddress(address);
1875
+ this.txBuilder.requiredSignerHash(pubKeyHash);
1876
+ });
1877
+ return this;
1878
+ }
1879
+ /**
1880
+ * Set the time to live for the transaction.
1881
+ *
1882
+ * @param {string} slot The slot number to expire the transaction at.
1883
+ * @returns {Transaction} The Transaction object.
1884
+ * @see {@link https://meshjs.dev/apis/transaction#setTimeLimit}
1885
+ */
1886
+ setTimeToExpire(slot) {
1887
+ this.txBuilder.invalidHereafter(Number(slot));
1888
+ return this;
1889
+ }
1890
+ /**
1891
+ * Sets the start slot for the transaction.
1892
+ *
1893
+ * @param {string} slot The start slot for the transaction.
1894
+ * @returns {Transaction} The Transaction object.
1895
+ * @see {@link https://meshjs.dev/apis/transaction#setTimeLimit}
1896
+ */
1897
+ setTimeToStart(slot) {
1898
+ this.txBuilder.invalidBefore(Number(slot));
1899
+ return this;
1900
+ }
1901
+ /**
1902
+ * Add a JSON metadata entry to the transaction.
1903
+ *
1904
+ * @param {number} key The key to use for the metadata entry.
1905
+ * @param {unknown} value The value to use for the metadata entry.
1906
+ * @returns {Transaction} The Transaction object.
1907
+ * @see {@link https://meshjs.dev/apis/transaction#setMetadata}
1908
+ */
1909
+ setMetadata(key, value) {
1910
+ this.txBuilder.metadataValue(key.toString(), value);
1911
+ return this;
1912
+ }
1913
+ withdrawRewards(rewardAddress, lovelace) {
1914
+ this.txBuilder.withdrawal(rewardAddress, lovelace);
1915
+ return this;
1916
+ }
1917
+ delegateStake(rewardAddress, poolId) {
1918
+ this.txBuilder.delegateStakeCertificate(
1919
+ this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(
1920
+ rewardAddress
1921
+ ),
1922
+ this.txBuilder.serializer.resolver.keys.resolveEd25519KeyHash(poolId)
1923
+ );
1924
+ return this;
1925
+ }
1926
+ deregisterStake(rewardAddress) {
1927
+ this.txBuilder.deregisterStakeCertificate(
1928
+ this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
1929
+ );
1930
+ return this;
1931
+ }
1932
+ registerStake(rewardAddress) {
1933
+ this.txBuilder.registerStakeCertificate(
1934
+ this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
1935
+ );
1936
+ return this;
1937
+ }
1938
+ // TODO: test
1939
+ registerPool(params) {
1940
+ this.txBuilder.registerPoolCertificate(params);
1941
+ return this;
1942
+ }
1943
+ // TODO: test
1944
+ retirePool(poolId, epochNo) {
1945
+ this.txBuilder.retirePoolCertificate(poolId, epochNo);
1946
+ return this;
1947
+ }
1948
+ async build() {
1949
+ try {
1950
+ await this.addCollateralIfNeeded();
1951
+ await this.addTxInputsAsNeeded();
1952
+ await this.addChangeAddress();
1953
+ return this.txBuilder.complete();
1954
+ } catch (error) {
1955
+ throw new Error(
1956
+ `[Transaction] An error occurred during build: ${error}.`
1957
+ );
1958
+ }
1959
+ }
1960
+ mintPlutusScript(script) {
1961
+ switch (script.version) {
1962
+ case "V1":
1963
+ this.txBuilder.mintPlutusScriptV1();
1964
+ break;
1965
+ case "V2":
1966
+ this.txBuilder.mintPlutusScriptV2();
1967
+ break;
1968
+ case "V3":
1969
+ this.txBuilder.mintPlutusScriptV3();
1970
+ break;
1971
+ }
1972
+ return this.txBuilder;
1973
+ }
1974
+ spendingPlutusScript(script) {
1975
+ switch (script.version) {
1976
+ case "V1":
1977
+ this.txBuilder.spendingPlutusScriptV1();
1978
+ break;
1979
+ case "V2":
1980
+ this.txBuilder.spendingPlutusScriptV2();
1981
+ break;
1982
+ case "V3":
1983
+ this.txBuilder.spendingPlutusScriptV3();
1984
+ break;
1985
+ }
1986
+ return this.txBuilder;
1987
+ }
1988
+ async addCollateralIfNeeded() {
1989
+ if (this.isCollateralNeeded) {
1990
+ const collaterals = await this.initiator.getCollateral();
1991
+ this.setCollateral(collaterals);
1992
+ }
1993
+ }
1994
+ async addTxInputsAsNeeded() {
1995
+ const utxos = await this.initiator.getUtxos();
1996
+ this.txBuilder.selectUtxosFrom(utxos);
1997
+ }
1998
+ async addChangeAddress() {
1999
+ if (this.txBuilder.meshTxBuilderBody.changeAddress === "") {
2000
+ const changeAddress = await this.initiator.getChangeAddress();
2001
+ this.setChangeAddress(changeAddress);
2002
+ }
2003
+ }
2004
+ };
2005
+ export {
2006
+ ForgeScript,
2007
+ MeshTxBuilder,
2008
+ Transaction,
2009
+ UtxoSelection,
2010
+ experimentalSelectUtxos,
2011
+ keepRelevant,
2012
+ largestFirst,
2013
+ largestFirstMultiAsset
2014
+ };