@meshsdk/transaction 1.6.0-alpha.11
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/README.md +5 -0
- package/package.json +35 -0
- package/src/index.ts +4 -0
- package/src/mesh-tx-builder/index.ts +259 -0
- package/src/mesh-tx-builder/tx-builder-core.ts +1180 -0
- package/src/scripts/forge.script.ts +63 -0
- package/src/scripts/index.ts +1 -0
- package/src/transaction/index.ts +609 -0
- package/src/transaction/transaction-v2.ts +81 -0
- package/src/utxo-selection/common.ts +113 -0
- package/src/utxo-selection/experimental.ts +137 -0
- package/src/utxo-selection/index.ts +69 -0
- package/src/utxo-selection/keepRelevant.ts +35 -0
- package/src/utxo-selection/largestFirst.ts +31 -0
- package/src/utxo-selection/largestFirstMultiAsset.ts +37 -0
- package/tsconfig.json +5 -0
- package/types/index.ts +0 -0
|
@@ -0,0 +1,1180 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Asset,
|
|
3
|
+
Data,
|
|
4
|
+
LanguageVersion,
|
|
5
|
+
PoolParams,
|
|
6
|
+
UTxO,
|
|
7
|
+
DEFAULT_REDEEMER_BUDGET,
|
|
8
|
+
MintItem,
|
|
9
|
+
TxIn,
|
|
10
|
+
PubKeyTxIn,
|
|
11
|
+
MeshTxBuilderBody,
|
|
12
|
+
RefTxIn,
|
|
13
|
+
Output,
|
|
14
|
+
BuilderData,
|
|
15
|
+
TxInParameter,
|
|
16
|
+
Quantity,
|
|
17
|
+
Unit,
|
|
18
|
+
RequiredWith,
|
|
19
|
+
Action,
|
|
20
|
+
Protocol,
|
|
21
|
+
DEFAULT_PROTOCOL_PARAMETERS,
|
|
22
|
+
Withdrawal,
|
|
23
|
+
Redeemer,
|
|
24
|
+
emptyTxBuilderBody,
|
|
25
|
+
} from "@meshsdk/common";
|
|
26
|
+
import JSONBig from "json-bigint";
|
|
27
|
+
import { experimentalSelectUtxos } from "../utxo-selection";
|
|
28
|
+
|
|
29
|
+
export class MeshTxBuilderCore {
|
|
30
|
+
txEvaluationMultiplier = 1.1;
|
|
31
|
+
private txOutput?: Output;
|
|
32
|
+
private addingPlutusScriptInput = false;
|
|
33
|
+
private plutusSpendingScriptVersion: LanguageVersion | undefined;
|
|
34
|
+
private addingPlutusMint = false;
|
|
35
|
+
private plutusMintingScriptVersion: LanguageVersion | undefined;
|
|
36
|
+
private addingPlutusWithdrawal = false;
|
|
37
|
+
private plutusWithdrawalScriptVersion: LanguageVersion | undefined;
|
|
38
|
+
|
|
39
|
+
protected _protocolParams: Protocol = DEFAULT_PROTOCOL_PARAMETERS;
|
|
40
|
+
|
|
41
|
+
protected mintItem?: MintItem;
|
|
42
|
+
|
|
43
|
+
protected txInQueueItem?: TxIn;
|
|
44
|
+
|
|
45
|
+
protected withdrawalItem?: Withdrawal;
|
|
46
|
+
|
|
47
|
+
protected collateralQueueItem?: PubKeyTxIn;
|
|
48
|
+
|
|
49
|
+
protected refScriptTxInQueueItem?: RefTxIn;
|
|
50
|
+
|
|
51
|
+
meshTxBuilderBody: MeshTxBuilderBody;
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
this.meshTxBuilderBody = emptyTxBuilderBody();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Set the input for transaction
|
|
59
|
+
* @param txHash The transaction hash of the input UTxO
|
|
60
|
+
* @param txIndex The transaction index of the input UTxO
|
|
61
|
+
* @param amount The asset amount of index of the input UTxO
|
|
62
|
+
* @param address The address of the input UTxO
|
|
63
|
+
* @returns The MeshTxBuilder instance
|
|
64
|
+
*/
|
|
65
|
+
txIn = (
|
|
66
|
+
txHash: string,
|
|
67
|
+
txIndex: number,
|
|
68
|
+
amount?: Asset[],
|
|
69
|
+
address?: string
|
|
70
|
+
) => {
|
|
71
|
+
if (this.txInQueueItem) {
|
|
72
|
+
this.queueInput();
|
|
73
|
+
}
|
|
74
|
+
if (!this.addingPlutusScriptInput) {
|
|
75
|
+
this.txInQueueItem = {
|
|
76
|
+
type: "PubKey",
|
|
77
|
+
txIn: {
|
|
78
|
+
txHash: txHash,
|
|
79
|
+
txIndex: txIndex,
|
|
80
|
+
amount: amount,
|
|
81
|
+
address: address,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
} else {
|
|
85
|
+
this.txInQueueItem = {
|
|
86
|
+
type: "Script",
|
|
87
|
+
txIn: {
|
|
88
|
+
txHash: txHash,
|
|
89
|
+
txIndex: txIndex,
|
|
90
|
+
amount: amount,
|
|
91
|
+
address: address,
|
|
92
|
+
},
|
|
93
|
+
scriptTxIn: {},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
this.addingPlutusScriptInput = false;
|
|
97
|
+
return this;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set the script for transaction input
|
|
102
|
+
* @param {string} scriptCbor The CborHex of the script
|
|
103
|
+
* @param version Optional - The Plutus script version
|
|
104
|
+
* @returns The MeshTxBuilder instance
|
|
105
|
+
*/
|
|
106
|
+
txInScript = (scriptCbor: string) => {
|
|
107
|
+
if (!this.txInQueueItem) throw Error("Undefined input");
|
|
108
|
+
if (this.txInQueueItem.type === "PubKey") {
|
|
109
|
+
this.txInQueueItem = {
|
|
110
|
+
type: "SimpleScript",
|
|
111
|
+
txIn: this.txInQueueItem.txIn,
|
|
112
|
+
simpleScriptTxIn: {
|
|
113
|
+
scriptSource: {
|
|
114
|
+
type: "Provided",
|
|
115
|
+
script: scriptCbor,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (this.txInQueueItem.type === "Script") {
|
|
121
|
+
this.txInQueueItem.scriptTxIn.scriptSource = {
|
|
122
|
+
type: "Provided",
|
|
123
|
+
script: {
|
|
124
|
+
code: scriptCbor,
|
|
125
|
+
version: this.plutusSpendingScriptVersion || "V2",
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return this;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Set the input datum for transaction input
|
|
134
|
+
* @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
135
|
+
* @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
136
|
+
* @returns The MeshTxBuilder instance
|
|
137
|
+
*/
|
|
138
|
+
txInDatumValue = (
|
|
139
|
+
datum: BuilderData["content"],
|
|
140
|
+
type: BuilderData["type"] = "Mesh"
|
|
141
|
+
) => {
|
|
142
|
+
if (!this.txInQueueItem) throw Error("Undefined input");
|
|
143
|
+
if (this.txInQueueItem.type === "PubKey")
|
|
144
|
+
throw Error("Datum value attempted to be called a non script input");
|
|
145
|
+
if (this.txInQueueItem.type === "SimpleScript")
|
|
146
|
+
throw Error(
|
|
147
|
+
"Datum value attempted to be called on a simple script input"
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
let content = datum;
|
|
151
|
+
if (type === "JSON") {
|
|
152
|
+
content = this.castRawDataToJsonString(datum as object | string);
|
|
153
|
+
}
|
|
154
|
+
if (type === "Mesh") {
|
|
155
|
+
this.txInQueueItem.scriptTxIn.datumSource = {
|
|
156
|
+
type: "Provided",
|
|
157
|
+
data: {
|
|
158
|
+
type,
|
|
159
|
+
content: datum as Data,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
this.txInQueueItem.scriptTxIn.datumSource = {
|
|
165
|
+
type: "Provided",
|
|
166
|
+
data: {
|
|
167
|
+
type,
|
|
168
|
+
content: content as string,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
return this;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Tell the transaction builder that the input UTxO has inlined datum
|
|
176
|
+
* @returns The MeshTxBuilder instance
|
|
177
|
+
*/
|
|
178
|
+
txInInlineDatumPresent = () => {
|
|
179
|
+
if (!this.txInQueueItem) throw Error("Undefined input");
|
|
180
|
+
if (this.txInQueueItem.type === "PubKey")
|
|
181
|
+
throw Error(
|
|
182
|
+
"Inline datum present attempted to be called a non script input"
|
|
183
|
+
);
|
|
184
|
+
if (this.txInQueueItem.type === "SimpleScript")
|
|
185
|
+
throw Error(
|
|
186
|
+
"Inline datum present attempted to be called on a simple script input"
|
|
187
|
+
);
|
|
188
|
+
const { txHash, txIndex } = this.txInQueueItem.txIn;
|
|
189
|
+
if (txHash && txIndex.toString()) {
|
|
190
|
+
this.txInQueueItem.scriptTxIn.datumSource = {
|
|
191
|
+
type: "Inline",
|
|
192
|
+
txHash,
|
|
193
|
+
txIndex,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return this;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// /**
|
|
200
|
+
// * Native script - Set the reference input where it would also be spent in the transaction
|
|
201
|
+
// * @param txHash The transaction hash of the reference UTxO
|
|
202
|
+
// * @param txIndex The transaction index of the reference UTxO
|
|
203
|
+
// * @param spendingScriptHash The script hash of the spending script
|
|
204
|
+
// * @returns The MeshTxBuilder instance
|
|
205
|
+
// */
|
|
206
|
+
// simpleScriptTxInReference = (
|
|
207
|
+
// txHash: string,
|
|
208
|
+
// txIndex: number,
|
|
209
|
+
// spendingScriptHash?: string
|
|
210
|
+
// ) => {
|
|
211
|
+
// if (!this.txInQueueItem) throw Error('Undefined input');
|
|
212
|
+
// if (this.txInQueueItem.type === 'PubKey')
|
|
213
|
+
// throw Error(
|
|
214
|
+
// 'Spending tx in reference attempted to be called a non script input'
|
|
215
|
+
// );
|
|
216
|
+
// this.txInQueueItem.scriptTxIn.scriptSource = {
|
|
217
|
+
// type: 'Inline',
|
|
218
|
+
// txInInfo: {
|
|
219
|
+
// txHash,
|
|
220
|
+
// txIndex,
|
|
221
|
+
// spendingScriptHash,
|
|
222
|
+
// },
|
|
223
|
+
// };
|
|
224
|
+
// return this;
|
|
225
|
+
// };
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Set the redeemer for the reference input to be spent in same transaction
|
|
229
|
+
* @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
230
|
+
* @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
231
|
+
* @param exUnits The execution units budget for the redeemer
|
|
232
|
+
* @returns The MeshTxBuilder instance
|
|
233
|
+
*/
|
|
234
|
+
txInRedeemerValue = (
|
|
235
|
+
redeemer: BuilderData["content"],
|
|
236
|
+
type: BuilderData["type"] = "Mesh",
|
|
237
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
238
|
+
) => {
|
|
239
|
+
if (!this.txInQueueItem) throw Error("Undefined input");
|
|
240
|
+
if (this.txInQueueItem.type === "PubKey")
|
|
241
|
+
throw Error(
|
|
242
|
+
"Spending tx in reference redeemer attempted to be called a non script input"
|
|
243
|
+
);
|
|
244
|
+
if (this.txInQueueItem.type === "SimpleScript")
|
|
245
|
+
throw Error(
|
|
246
|
+
"Spending tx in reference redeemer attempted to be called on a simple script input"
|
|
247
|
+
);
|
|
248
|
+
this.txInQueueItem.scriptTxIn.redeemer = this.castBuilderDataToRedeemer(
|
|
249
|
+
redeemer,
|
|
250
|
+
type,
|
|
251
|
+
exUnits
|
|
252
|
+
);
|
|
253
|
+
return this;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Set the output for transaction
|
|
258
|
+
* @param {string} address The recipient of the output
|
|
259
|
+
* @param {Asset[]} amount The amount of other native assets attached with UTxO
|
|
260
|
+
* @returns The MeshTxBuilder instance
|
|
261
|
+
*/
|
|
262
|
+
txOut = (address: string, amount: Asset[]) => {
|
|
263
|
+
if (this.txOutput) {
|
|
264
|
+
this.meshTxBuilderBody.outputs.push(this.txOutput);
|
|
265
|
+
this.txOutput = undefined;
|
|
266
|
+
}
|
|
267
|
+
this.txOutput = {
|
|
268
|
+
address,
|
|
269
|
+
amount,
|
|
270
|
+
};
|
|
271
|
+
return this;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Set the output datum hash for transaction
|
|
276
|
+
* @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
277
|
+
* @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
278
|
+
* @returns The MeshTxBuilder instance
|
|
279
|
+
*/
|
|
280
|
+
txOutDatumHashValue = (
|
|
281
|
+
datum: BuilderData["content"],
|
|
282
|
+
type: BuilderData["type"] = "Mesh"
|
|
283
|
+
) => {
|
|
284
|
+
let content = datum;
|
|
285
|
+
if (this.txOutput) {
|
|
286
|
+
if (type === "Mesh") {
|
|
287
|
+
this.txOutput.datum = {
|
|
288
|
+
type: "Hash",
|
|
289
|
+
data: {
|
|
290
|
+
type,
|
|
291
|
+
content: content as Data,
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
if (type === "JSON") {
|
|
297
|
+
content = this.castRawDataToJsonString(datum as object | string);
|
|
298
|
+
}
|
|
299
|
+
this.txOutput.datum = {
|
|
300
|
+
type: "Hash",
|
|
301
|
+
data: {
|
|
302
|
+
type,
|
|
303
|
+
content: content as string,
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return this;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Set the output inline datum for transaction
|
|
312
|
+
* @param datum The datum in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
313
|
+
* @param type The datum type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
314
|
+
* @returns The MeshTxBuilder instance
|
|
315
|
+
*/
|
|
316
|
+
txOutInlineDatumValue = (
|
|
317
|
+
datum: BuilderData["content"],
|
|
318
|
+
type: BuilderData["type"] = "Mesh"
|
|
319
|
+
) => {
|
|
320
|
+
let content = datum;
|
|
321
|
+
if (this.txOutput) {
|
|
322
|
+
if (type === "Mesh") {
|
|
323
|
+
this.txOutput.datum = {
|
|
324
|
+
type: "Inline",
|
|
325
|
+
data: {
|
|
326
|
+
type,
|
|
327
|
+
content: content as Data,
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
if (type === "JSON") {
|
|
333
|
+
content = this.castRawDataToJsonString(datum as object | string);
|
|
334
|
+
}
|
|
335
|
+
this.txOutput.datum = {
|
|
336
|
+
type: "Inline",
|
|
337
|
+
data: {
|
|
338
|
+
type,
|
|
339
|
+
content: content as string,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
return this;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Set the reference script to be attached with the output
|
|
348
|
+
* @param scriptCbor The CBOR hex of the script to be attached to UTxO as reference script
|
|
349
|
+
* @param version Optional - The Plutus script version
|
|
350
|
+
* @returns The MeshTxBuilder instance
|
|
351
|
+
*/
|
|
352
|
+
txOutReferenceScript = (
|
|
353
|
+
scriptCbor: string,
|
|
354
|
+
version: LanguageVersion = "V2"
|
|
355
|
+
) => {
|
|
356
|
+
if (this.txOutput) {
|
|
357
|
+
this.txOutput.referenceScript = { code: scriptCbor, version };
|
|
358
|
+
}
|
|
359
|
+
return this;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Set the instruction that it is currently using V1 Plutus spending scripts
|
|
364
|
+
* @returns The MeshTxBuilder instance
|
|
365
|
+
*/
|
|
366
|
+
spendingPlutusScriptV1 = () => {
|
|
367
|
+
// This flag should signal a start to a script input
|
|
368
|
+
// The next step after will be to add a tx-in
|
|
369
|
+
// After which, we will REQUIRE, script, datum and redeemer info
|
|
370
|
+
// for unlocking this particular input
|
|
371
|
+
this.addingPlutusScriptInput = true;
|
|
372
|
+
this.plutusSpendingScriptVersion = "V1";
|
|
373
|
+
return this;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Set the instruction that it is currently using V2 Plutus spending scripts
|
|
377
|
+
* @returns The MeshTxBuilder instance
|
|
378
|
+
*/
|
|
379
|
+
spendingPlutusScriptV2 = () => {
|
|
380
|
+
// This flag should signal a start to a script input
|
|
381
|
+
// The next step after will be to add a tx-in
|
|
382
|
+
// After which, we will REQUIRE, script, datum and redeemer info
|
|
383
|
+
// for unlocking this particular input
|
|
384
|
+
this.addingPlutusScriptInput = true;
|
|
385
|
+
this.plutusSpendingScriptVersion = "V2";
|
|
386
|
+
return this;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Set the instruction that it is currently using V3 Plutus spending scripts
|
|
390
|
+
* @returns The MeshTxBuilder instance
|
|
391
|
+
*/
|
|
392
|
+
spendingPlutusScriptV3 = () => {
|
|
393
|
+
// This flag should signal a start to a script input
|
|
394
|
+
// The next step after will be to add a tx-in
|
|
395
|
+
// After which, we will REQUIRE, script, datum and redeemer info
|
|
396
|
+
// for unlocking this particular input
|
|
397
|
+
this.addingPlutusScriptInput = true;
|
|
398
|
+
this.plutusSpendingScriptVersion = "V3";
|
|
399
|
+
return this;
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Set the reference input where it would also be spent in the transaction
|
|
404
|
+
* @param txHash The transaction hash of the reference UTxO
|
|
405
|
+
* @param txIndex The transaction index of the reference UTxO
|
|
406
|
+
* @param spendingScriptHash The script hash of the spending script
|
|
407
|
+
* @returns The MeshTxBuilder instance
|
|
408
|
+
*/
|
|
409
|
+
spendingTxInReference = (
|
|
410
|
+
txHash: string,
|
|
411
|
+
txIndex: number,
|
|
412
|
+
spendingScriptHash?: string
|
|
413
|
+
) => {
|
|
414
|
+
if (!this.txInQueueItem) throw Error("Undefined input");
|
|
415
|
+
if (this.txInQueueItem.type === "PubKey")
|
|
416
|
+
throw Error(
|
|
417
|
+
"Spending tx in reference attempted to be called a non script input"
|
|
418
|
+
);
|
|
419
|
+
if (this.txInQueueItem.type === "SimpleScript")
|
|
420
|
+
throw Error(
|
|
421
|
+
"Spending tx in reference attempted to be called on a simple script input"
|
|
422
|
+
);
|
|
423
|
+
this.txInQueueItem.scriptTxIn.scriptSource = {
|
|
424
|
+
type: "Inline",
|
|
425
|
+
txHash,
|
|
426
|
+
txIndex,
|
|
427
|
+
scriptHash: spendingScriptHash,
|
|
428
|
+
version: this.plutusSpendingScriptVersion || "V2",
|
|
429
|
+
scriptSize: "0", // TODO
|
|
430
|
+
};
|
|
431
|
+
return this;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* [Alias of txInInlineDatumPresent] Set the instruction that the reference input has inline datum
|
|
436
|
+
* @returns The MeshTxBuilder instance
|
|
437
|
+
*/
|
|
438
|
+
// Unsure how this is different from the --tx-in-inline-datum-present flag
|
|
439
|
+
// It seems to just be different based on if the script is a reference input
|
|
440
|
+
spendingReferenceTxInInlineDatumPresent = () => {
|
|
441
|
+
this.txInInlineDatumPresent();
|
|
442
|
+
return this;
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* [Alias of txInRedeemerValue] Set the redeemer for the reference input to be spent in same transaction
|
|
447
|
+
* @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
448
|
+
* @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
449
|
+
* @param exUnits The execution units budget for the redeemer
|
|
450
|
+
* @returns The MeshTxBuilder instance
|
|
451
|
+
*/
|
|
452
|
+
spendingReferenceTxInRedeemerValue = (
|
|
453
|
+
redeemer: BuilderData["content"],
|
|
454
|
+
type: BuilderData["type"] = "Mesh",
|
|
455
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
456
|
+
) => {
|
|
457
|
+
this.txInRedeemerValue(redeemer, type, exUnits);
|
|
458
|
+
return this;
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Specify a read only reference input. This reference input is not witnessing anything it is simply provided in the plutus script context.
|
|
463
|
+
* @param txHash The transaction hash of the reference UTxO
|
|
464
|
+
* @param txIndex The transaction index of the reference UTxO
|
|
465
|
+
* @returns The MeshTxBuilder instance
|
|
466
|
+
*/
|
|
467
|
+
readOnlyTxInReference = (txHash: string, txIndex: number) => {
|
|
468
|
+
this.meshTxBuilderBody.referenceInputs.push({ txHash, txIndex });
|
|
469
|
+
return this;
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Set the instruction that it is currently using V1 Plutus minting scripts
|
|
474
|
+
* @returns The MeshTxBuilder instance
|
|
475
|
+
*/
|
|
476
|
+
mintPlutusScriptV1 = () => {
|
|
477
|
+
this.addingPlutusMint = true;
|
|
478
|
+
this.plutusMintingScriptVersion = "V1";
|
|
479
|
+
return this;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Set the instruction that it is currently using V2 Plutus minting scripts
|
|
483
|
+
* @returns The MeshTxBuilder instance
|
|
484
|
+
*/
|
|
485
|
+
mintPlutusScriptV2 = () => {
|
|
486
|
+
this.addingPlutusMint = true;
|
|
487
|
+
this.plutusMintingScriptVersion = "V2";
|
|
488
|
+
return this;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* Set the instruction that it is currently using V3 Plutus minting scripts
|
|
492
|
+
* @returns The MeshTxBuilder instance
|
|
493
|
+
*/
|
|
494
|
+
mintPlutusScriptV3 = () => {
|
|
495
|
+
this.addingPlutusMint = true;
|
|
496
|
+
this.plutusMintingScriptVersion = "V3";
|
|
497
|
+
return this;
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Set the minting value of transaction
|
|
502
|
+
* @param quantity The quantity of asset to be minted
|
|
503
|
+
* @param policy The policy id of the asset to be minted
|
|
504
|
+
* @param name The hex of token name of the asset to be minted
|
|
505
|
+
* @returns The MeshTxBuilder instance
|
|
506
|
+
*/
|
|
507
|
+
mint = (quantity: string, policy: string, name: string) => {
|
|
508
|
+
if (this.mintItem) {
|
|
509
|
+
this.queueMint();
|
|
510
|
+
}
|
|
511
|
+
this.mintItem = {
|
|
512
|
+
type: this.addingPlutusMint ? "Plutus" : "Native",
|
|
513
|
+
policyId: policy,
|
|
514
|
+
assetName: name,
|
|
515
|
+
amount: quantity,
|
|
516
|
+
};
|
|
517
|
+
this.addingPlutusMint = false;
|
|
518
|
+
return this;
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Set the minting script of current mint
|
|
523
|
+
* @param scriptCBOR The CBOR hex of the minting policy script
|
|
524
|
+
* @param version Optional - The Plutus script version
|
|
525
|
+
* @returns The MeshTxBuilder instance
|
|
526
|
+
*/
|
|
527
|
+
mintingScript = (scriptCBOR: string) => {
|
|
528
|
+
if (!this.mintItem) throw Error("Undefined mint");
|
|
529
|
+
if (!this.mintItem.type) throw Error("Mint information missing");
|
|
530
|
+
if (this.mintItem.type === "Native") {
|
|
531
|
+
this.mintItem.scriptSource = {
|
|
532
|
+
type: "Provided",
|
|
533
|
+
scriptCode: scriptCBOR,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
if (this.mintItem.type === "Plutus") {
|
|
537
|
+
this.mintItem.scriptSource = {
|
|
538
|
+
type: "Provided",
|
|
539
|
+
script: {
|
|
540
|
+
code: scriptCBOR,
|
|
541
|
+
version: this.plutusMintingScriptVersion || "V2",
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return this;
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Use reference script for minting
|
|
551
|
+
* @param txHash The transaction hash of the UTxO
|
|
552
|
+
* @param txIndex The transaction index of the UTxO
|
|
553
|
+
* @returns The MeshTxBuilder instance
|
|
554
|
+
*/
|
|
555
|
+
mintTxInReference = (txHash: string, txIndex: number) => {
|
|
556
|
+
if (!this.mintItem) throw Error("Undefined mint");
|
|
557
|
+
if (!this.mintItem.type) throw Error("Mint information missing");
|
|
558
|
+
if (this.mintItem.type == "Native") {
|
|
559
|
+
throw Error(
|
|
560
|
+
"Mint tx in reference can only be used on plutus script tokens"
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
if (!this.mintItem.policyId)
|
|
564
|
+
throw Error("PolicyId information missing from mint asset");
|
|
565
|
+
this.mintItem.scriptSource = {
|
|
566
|
+
type: "Inline",
|
|
567
|
+
txHash,
|
|
568
|
+
txIndex,
|
|
569
|
+
version: this.plutusMintingScriptVersion,
|
|
570
|
+
scriptSize: "0", // TODO
|
|
571
|
+
scriptHash: "", // TODO
|
|
572
|
+
};
|
|
573
|
+
return this;
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Set the redeemer for minting
|
|
578
|
+
* @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
579
|
+
* @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
580
|
+
* @param exUnits The execution units budget for the redeemer
|
|
581
|
+
* @returns The MeshTxBuilder instance
|
|
582
|
+
*/
|
|
583
|
+
mintReferenceTxInRedeemerValue = (
|
|
584
|
+
redeemer: BuilderData["content"],
|
|
585
|
+
type: BuilderData["type"] = "Mesh",
|
|
586
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
587
|
+
) => {
|
|
588
|
+
if (!this.mintItem) throw Error("Undefined mint");
|
|
589
|
+
if (this.mintItem.type == "Native") {
|
|
590
|
+
throw Error(
|
|
591
|
+
"Mint tx in reference can only be used on plutus script tokens"
|
|
592
|
+
);
|
|
593
|
+
} else if (this.mintItem.type == "Plutus") {
|
|
594
|
+
if (!this.mintItem.policyId)
|
|
595
|
+
throw Error("PolicyId information missing from mint asset");
|
|
596
|
+
}
|
|
597
|
+
this.mintItem.redeemer = this.castBuilderDataToRedeemer(
|
|
598
|
+
redeemer,
|
|
599
|
+
type,
|
|
600
|
+
exUnits
|
|
601
|
+
);
|
|
602
|
+
return this;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Set the redeemer for the reference input to be spent in same transaction
|
|
607
|
+
* @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
608
|
+
* @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
609
|
+
* @param exUnits The execution units budget for the redeemer
|
|
610
|
+
* @returns The MeshTxBuilder instance
|
|
611
|
+
*/
|
|
612
|
+
mintRedeemerValue = (
|
|
613
|
+
redeemer: BuilderData["content"],
|
|
614
|
+
type: BuilderData["type"] = "Mesh",
|
|
615
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
616
|
+
) => {
|
|
617
|
+
this.mintReferenceTxInRedeemerValue(redeemer, type, exUnits);
|
|
618
|
+
return this;
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Set the required signer of the transaction
|
|
623
|
+
* @param pubKeyHash The PubKeyHash of the required signer
|
|
624
|
+
* @returns The MeshTxBuilder instance
|
|
625
|
+
*/
|
|
626
|
+
requiredSignerHash = (pubKeyHash: string) => {
|
|
627
|
+
this.meshTxBuilderBody.requiredSignatures.push(pubKeyHash);
|
|
628
|
+
return this;
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Set the collateral UTxO for the transaction
|
|
633
|
+
* @param txHash The transaction hash of the collateral UTxO
|
|
634
|
+
* @param txIndex The transaction index of the collateral UTxO
|
|
635
|
+
* @param amount The asset amount of index of the collateral UTxO
|
|
636
|
+
* @param address The address of the collateral UTxO
|
|
637
|
+
* @returns The MeshTxBuilder instance
|
|
638
|
+
*/
|
|
639
|
+
txInCollateral = (
|
|
640
|
+
txHash: string,
|
|
641
|
+
txIndex: number,
|
|
642
|
+
amount?: Asset[],
|
|
643
|
+
address?: string
|
|
644
|
+
) => {
|
|
645
|
+
if (this.collateralQueueItem) {
|
|
646
|
+
this.meshTxBuilderBody.collaterals.push(this.collateralQueueItem);
|
|
647
|
+
}
|
|
648
|
+
this.collateralQueueItem = {
|
|
649
|
+
type: "PubKey",
|
|
650
|
+
txIn: {
|
|
651
|
+
txHash: txHash,
|
|
652
|
+
txIndex: txIndex,
|
|
653
|
+
amount,
|
|
654
|
+
address,
|
|
655
|
+
},
|
|
656
|
+
};
|
|
657
|
+
return this;
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Set the instruction that it is currently using V1 Plutus withdrawal scripts
|
|
662
|
+
* @returns The MeshTxBuilder instance
|
|
663
|
+
*/
|
|
664
|
+
withdrawalPlutusScriptV1 = () => {
|
|
665
|
+
this.addingPlutusWithdrawal = true;
|
|
666
|
+
this.plutusWithdrawalScriptVersion = "V1";
|
|
667
|
+
return this;
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Set the instruction that it is currently using V2 Plutus withdrawal scripts
|
|
672
|
+
* @returns The MeshTxBuilder instance
|
|
673
|
+
*/
|
|
674
|
+
withdrawalPlutusScriptV2 = () => {
|
|
675
|
+
this.addingPlutusWithdrawal = true;
|
|
676
|
+
this.plutusWithdrawalScriptVersion = "V2";
|
|
677
|
+
return this;
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Set the instruction that it is currently using V3 Plutus withdrawal scripts
|
|
682
|
+
* @returns The MeshTxBuilder instance
|
|
683
|
+
*/
|
|
684
|
+
withdrawalPlutusScriptV3 = () => {
|
|
685
|
+
this.addingPlutusWithdrawal = true;
|
|
686
|
+
this.plutusWithdrawalScriptVersion = "V3";
|
|
687
|
+
return this;
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Withdraw stake rewards in the MeshTxBuilder instance
|
|
692
|
+
* @param stakeAddress The address corresponding to the stake key
|
|
693
|
+
* @param coin The amount of lovelaces in the withdrawal
|
|
694
|
+
* @returns The MeshTxBuilder instance
|
|
695
|
+
*/
|
|
696
|
+
withdrawal = (stakeAddress: string, coin: string) => {
|
|
697
|
+
if (this.withdrawalItem) {
|
|
698
|
+
this.queueWithdrawal();
|
|
699
|
+
}
|
|
700
|
+
if (this.addingPlutusWithdrawal) {
|
|
701
|
+
const withdrawal: Withdrawal = {
|
|
702
|
+
plutusScriptWithdrawal: {
|
|
703
|
+
address: stakeAddress,
|
|
704
|
+
coin: coin,
|
|
705
|
+
},
|
|
706
|
+
};
|
|
707
|
+
this.meshTxBuilderBody.withdrawals.push(withdrawal);
|
|
708
|
+
return this;
|
|
709
|
+
}
|
|
710
|
+
const withdrawal: Withdrawal = {
|
|
711
|
+
pubKeyWithdrawal: {
|
|
712
|
+
address: stakeAddress,
|
|
713
|
+
coin: coin,
|
|
714
|
+
},
|
|
715
|
+
};
|
|
716
|
+
this.meshTxBuilderBody.withdrawals.push(withdrawal);
|
|
717
|
+
return this;
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Add a withdrawal script to the MeshTxBuilder instance
|
|
722
|
+
* @param scriptCbor The script in CBOR format
|
|
723
|
+
* @param version The language version
|
|
724
|
+
* @returns The MeshTxBuilder instance
|
|
725
|
+
*/
|
|
726
|
+
withdrawalScript = (scriptCbor: string, version: LanguageVersion) => {
|
|
727
|
+
if (!this.withdrawalItem)
|
|
728
|
+
throw Error("withdrawalScript: Undefined withdrawal");
|
|
729
|
+
if (!("plutusScriptWithdrawal" in this.withdrawalItem))
|
|
730
|
+
throw Error("withdrawalScript: Adding script to non plutus withdrawal");
|
|
731
|
+
this.withdrawalItem.plutusScriptWithdrawal.scriptSource = {
|
|
732
|
+
type: "Provided",
|
|
733
|
+
script: {
|
|
734
|
+
code: scriptCbor,
|
|
735
|
+
version: this.plutusWithdrawalScriptVersion || "V2",
|
|
736
|
+
},
|
|
737
|
+
};
|
|
738
|
+
return this;
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Add a withdrawal reference to the MeshTxBuilder instance
|
|
743
|
+
* @param txHash The transaction hash of reference UTxO
|
|
744
|
+
* @param txIndex The transaction index of reference UTxO
|
|
745
|
+
* @param withdrawalScriptHash The script hash of the withdrawal script
|
|
746
|
+
* @param scriptSize The script size of the withdrawal script
|
|
747
|
+
* @returns The MeshTxBuilder instance
|
|
748
|
+
*/
|
|
749
|
+
withdrawalTxInReference = (
|
|
750
|
+
txHash: string,
|
|
751
|
+
txIndex: number,
|
|
752
|
+
withdrawalScriptHash?: string,
|
|
753
|
+
scriptSize?: string
|
|
754
|
+
) => {
|
|
755
|
+
if (!this.withdrawalItem)
|
|
756
|
+
throw Error("withdrawalTxInReference: Undefined withdrawal");
|
|
757
|
+
if (!("plutusScriptWithdrawal" in this.withdrawalItem))
|
|
758
|
+
throw Error(
|
|
759
|
+
"withdrawalTxInReference: Adding script reference to non plutus withdrawal"
|
|
760
|
+
);
|
|
761
|
+
this.withdrawalItem.plutusScriptWithdrawal.scriptSource = {
|
|
762
|
+
type: "Inline",
|
|
763
|
+
txHash,
|
|
764
|
+
txIndex,
|
|
765
|
+
scriptHash: withdrawalScriptHash,
|
|
766
|
+
version: this.plutusWithdrawalScriptVersion || "V2",
|
|
767
|
+
scriptSize: scriptSize || "0",
|
|
768
|
+
};
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Set the transaction withdrawal redeemer value in the MeshTxBuilder instance
|
|
773
|
+
* @param redeemer The redeemer in Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
774
|
+
* @param type The redeemer data type, either Mesh Data type, JSON in raw constructor like format, or CBOR hex string
|
|
775
|
+
* @param exUnits The execution units budget for the redeemer
|
|
776
|
+
* @returns The MeshTxBuilder instance
|
|
777
|
+
*/
|
|
778
|
+
withdrawalRedeemerValue = (
|
|
779
|
+
redeemer: BuilderData["content"],
|
|
780
|
+
type: BuilderData["type"] = "Mesh",
|
|
781
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
782
|
+
) => {
|
|
783
|
+
if (!this.withdrawalItem)
|
|
784
|
+
throw Error("withdrawalRedeemerValue: Undefined withdrawal");
|
|
785
|
+
if (!("plutusScriptWithdrawal" in this.withdrawalItem))
|
|
786
|
+
throw Error(
|
|
787
|
+
"withdrawalRedeemerValue: Adding redeemer to non plutus withdrawal"
|
|
788
|
+
);
|
|
789
|
+
this.withdrawalItem.plutusScriptWithdrawal.redeemer =
|
|
790
|
+
this.castBuilderDataToRedeemer(redeemer, type, exUnits);
|
|
791
|
+
|
|
792
|
+
return this;
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Creates a pool registration certificate, and adds it to the transaction
|
|
797
|
+
* @param poolParams Parameters for pool registration
|
|
798
|
+
* @returns The MeshTxBuilder instance
|
|
799
|
+
*/
|
|
800
|
+
registerPoolCertificate = (poolParams: PoolParams) => {
|
|
801
|
+
this.meshTxBuilderBody.certificates.push({
|
|
802
|
+
type: "RegisterPool",
|
|
803
|
+
poolParams,
|
|
804
|
+
});
|
|
805
|
+
return this;
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Creates a stake registration certificate, and adds it to the transaction
|
|
810
|
+
* @param stakeKeyHash The keyHash of the stake key
|
|
811
|
+
* @returns The MeshTxBuilder instance
|
|
812
|
+
*/
|
|
813
|
+
registerStakeCertificate = (stakeKeyHash: string) => {
|
|
814
|
+
this.meshTxBuilderBody.certificates.push({
|
|
815
|
+
type: "RegisterStake",
|
|
816
|
+
stakeKeyHash,
|
|
817
|
+
});
|
|
818
|
+
return this;
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Creates a stake delegation certificate, and adds it to the transaction
|
|
823
|
+
* This will delegate stake from the corresponding stake address to the pool
|
|
824
|
+
* @param stakeKeyHash The keyHash of the stake key
|
|
825
|
+
* @param poolId poolId can be in either bech32 or hex form
|
|
826
|
+
* @returns The MeshTxBuilder instance
|
|
827
|
+
*/
|
|
828
|
+
delegateStakeCertificate = (stakeKeyHash: string, poolId: string) => {
|
|
829
|
+
this.meshTxBuilderBody.certificates.push({
|
|
830
|
+
type: "DelegateStake",
|
|
831
|
+
stakeKeyHash,
|
|
832
|
+
poolId,
|
|
833
|
+
});
|
|
834
|
+
return this;
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Creates a stake deregister certificate, and adds it to the transaction
|
|
839
|
+
* @param stakeKeyHash The keyHash of the stake key
|
|
840
|
+
* @returns The MeshTxBuilder instance
|
|
841
|
+
*/
|
|
842
|
+
deregisterStakeCertificate = (stakeKeyHash: string) => {
|
|
843
|
+
this.meshTxBuilderBody.certificates.push({
|
|
844
|
+
type: "DeregisterStake",
|
|
845
|
+
stakeKeyHash,
|
|
846
|
+
});
|
|
847
|
+
return this;
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Creates a pool retire certificate, and adds it to the transaction
|
|
852
|
+
* @param poolId poolId can be in either bech32 or hex form
|
|
853
|
+
* @param epoch The intended epoch to retire the pool
|
|
854
|
+
* @returns The MeshTxBuilder instance
|
|
855
|
+
*/
|
|
856
|
+
retirePoolCertificate = (poolId: string, epoch: number) => {
|
|
857
|
+
this.meshTxBuilderBody.certificates.push({
|
|
858
|
+
type: "RetirePool",
|
|
859
|
+
poolId,
|
|
860
|
+
epoch,
|
|
861
|
+
});
|
|
862
|
+
return this;
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Configure the address to accept change UTxO
|
|
867
|
+
* @param addr The address to accept change UTxO
|
|
868
|
+
* @returns The MeshTxBuilder instance
|
|
869
|
+
*/
|
|
870
|
+
changeAddress = (addr: string) => {
|
|
871
|
+
this.meshTxBuilderBody.changeAddress = addr;
|
|
872
|
+
return this;
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Set the transaction valid interval to be valid only after the slot
|
|
877
|
+
* @param slot The transaction is valid only after this slot
|
|
878
|
+
* @returns The MeshTxBuilder instance
|
|
879
|
+
*/
|
|
880
|
+
invalidBefore = (slot: number) => {
|
|
881
|
+
this.meshTxBuilderBody.validityRange.invalidBefore = slot;
|
|
882
|
+
return this;
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Set the transaction valid interval to be valid only before the slot
|
|
887
|
+
* @param slot The transaction is valid only before this slot
|
|
888
|
+
* @returns The MeshTxBuilder instance
|
|
889
|
+
*/
|
|
890
|
+
invalidHereafter = (slot: number) => {
|
|
891
|
+
this.meshTxBuilderBody.validityRange.invalidHereafter = slot;
|
|
892
|
+
return this;
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Add metadata to the transaction
|
|
897
|
+
* @param tag The tag of the metadata
|
|
898
|
+
* @param metadata The metadata in any format
|
|
899
|
+
* @returns The MeshTxBuilder instance
|
|
900
|
+
*/
|
|
901
|
+
metadataValue = (tag: string, metadata: any) => {
|
|
902
|
+
const metadataString = JSONBig.stringify(metadata);
|
|
903
|
+
this.meshTxBuilderBody.metadata.push({ tag, metadata: metadataString });
|
|
904
|
+
return this;
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Sign the transaction with the private key
|
|
909
|
+
* @param skeyHex The private key in cborHex (with or without 5820 prefix, i.e. the format when generated from cardano-cli)
|
|
910
|
+
* @returns
|
|
911
|
+
*/
|
|
912
|
+
signingKey = (skeyHex: string) => {
|
|
913
|
+
this.meshTxBuilderBody.signingKey.push(skeyHex);
|
|
914
|
+
return this;
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* EXPERIMENTAL - Selects utxos to fill output value and puts them into inputs
|
|
919
|
+
* @param extraInputs The inputs already placed into the object will remain, these extra inputs will be used to fill the remaining value needed
|
|
920
|
+
* @param threshold Extra value needed to be selected for, usually for paying fees and min UTxO value of change output
|
|
921
|
+
*/
|
|
922
|
+
selectUtxosFrom = (extraInputs: UTxO[], threshold = 5000000) => {
|
|
923
|
+
this.meshTxBuilderBody.extraInputs = extraInputs;
|
|
924
|
+
this.meshTxBuilderBody.selectionThreshold = threshold;
|
|
925
|
+
return this;
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Set the protocol parameters to be used for the transaction other than the default one
|
|
930
|
+
* @param params (Part of) the protocol parameters to be used for the transaction
|
|
931
|
+
* @returns The MeshTxBuilder instance
|
|
932
|
+
*/
|
|
933
|
+
protocolParams = (params: Partial<Protocol>) => {
|
|
934
|
+
const updatedParams = { ...DEFAULT_PROTOCOL_PARAMETERS, ...params };
|
|
935
|
+
this._protocolParams = updatedParams;
|
|
936
|
+
return this;
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
protected queueAllLastItem = () => {
|
|
940
|
+
if (this.txOutput) {
|
|
941
|
+
this.meshTxBuilderBody.outputs.push(this.txOutput);
|
|
942
|
+
this.txOutput = undefined;
|
|
943
|
+
}
|
|
944
|
+
if (this.txInQueueItem) {
|
|
945
|
+
this.queueInput();
|
|
946
|
+
}
|
|
947
|
+
if (this.collateralQueueItem) {
|
|
948
|
+
this.meshTxBuilderBody.collaterals.push(this.collateralQueueItem);
|
|
949
|
+
this.collateralQueueItem = undefined;
|
|
950
|
+
}
|
|
951
|
+
if (this.mintItem) {
|
|
952
|
+
this.queueMint();
|
|
953
|
+
}
|
|
954
|
+
if (this.withdrawalItem) {
|
|
955
|
+
this.queueWithdrawal();
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
private queueInput = () => {
|
|
960
|
+
if (!this.txInQueueItem) throw Error("queueInput: Undefined input");
|
|
961
|
+
if (this.txInQueueItem.type === "Script") {
|
|
962
|
+
if (!this.txInQueueItem.scriptTxIn) {
|
|
963
|
+
throw Error(
|
|
964
|
+
"queueInput: Script input does not contain script, datum, or redeemer information"
|
|
965
|
+
);
|
|
966
|
+
} else {
|
|
967
|
+
if (!this.txInQueueItem.scriptTxIn.datumSource)
|
|
968
|
+
throw Error(
|
|
969
|
+
"queueInput: Script input does not contain datum information"
|
|
970
|
+
);
|
|
971
|
+
if (!this.txInQueueItem.scriptTxIn.redeemer)
|
|
972
|
+
throw Error(
|
|
973
|
+
"queueInput: Script input does not contain redeemer information"
|
|
974
|
+
);
|
|
975
|
+
if (!this.txInQueueItem.scriptTxIn.scriptSource)
|
|
976
|
+
throw Error(
|
|
977
|
+
"queueInput: Script input does not contain script information"
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
this.meshTxBuilderBody.inputs.push(this.txInQueueItem);
|
|
982
|
+
this.txInQueueItem = undefined;
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
private queueMint = () => {
|
|
986
|
+
if (!this.mintItem) throw Error("queueMint: Undefined mint");
|
|
987
|
+
if (!this.mintItem.scriptSource)
|
|
988
|
+
throw Error("queueMint: Missing mint script information");
|
|
989
|
+
this.meshTxBuilderBody.mints.push(this.mintItem);
|
|
990
|
+
this.mintItem = undefined;
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
private queueWithdrawal = () => {
|
|
994
|
+
if (!this.withdrawalItem)
|
|
995
|
+
throw Error("queueWithdrawal: Undefined withdrawal");
|
|
996
|
+
if ("plutusScriptWithdrawal" in this.withdrawalItem) {
|
|
997
|
+
if (!this.withdrawalItem.plutusScriptWithdrawal.scriptSource) {
|
|
998
|
+
throw Error("queueWithdrawal: Missing withdrawal script information");
|
|
999
|
+
}
|
|
1000
|
+
if (!this.withdrawalItem.plutusScriptWithdrawal.redeemer) {
|
|
1001
|
+
throw Error("queueWithdrawal: Missing withdrawal redeemer information");
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
this.meshTxBuilderBody.withdrawals.push(this.withdrawalItem);
|
|
1005
|
+
this.withdrawalItem = undefined;
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
protected castRawDataToJsonString = (rawData: object | string) => {
|
|
1009
|
+
if (typeof rawData === "object") {
|
|
1010
|
+
return JSONBig.stringify(rawData);
|
|
1011
|
+
} else {
|
|
1012
|
+
return rawData as string;
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
protected castBuilderDataToRedeemer = (
|
|
1017
|
+
redeemer: BuilderData["content"],
|
|
1018
|
+
type: BuilderData["type"] = "Mesh",
|
|
1019
|
+
exUnits = { ...DEFAULT_REDEEMER_BUDGET }
|
|
1020
|
+
): Redeemer => {
|
|
1021
|
+
let red: Redeemer;
|
|
1022
|
+
let content = redeemer;
|
|
1023
|
+
if (type === "Mesh") {
|
|
1024
|
+
red = {
|
|
1025
|
+
data: {
|
|
1026
|
+
type,
|
|
1027
|
+
content: content as Data,
|
|
1028
|
+
},
|
|
1029
|
+
exUnits,
|
|
1030
|
+
};
|
|
1031
|
+
return red;
|
|
1032
|
+
}
|
|
1033
|
+
if (type === "JSON") {
|
|
1034
|
+
content = this.castRawDataToJsonString(redeemer as object | string);
|
|
1035
|
+
}
|
|
1036
|
+
red = {
|
|
1037
|
+
data: {
|
|
1038
|
+
type,
|
|
1039
|
+
content: content as string,
|
|
1040
|
+
},
|
|
1041
|
+
exUnits,
|
|
1042
|
+
};
|
|
1043
|
+
return red;
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
protected updateRedeemer = (
|
|
1047
|
+
meshTxBuilderBody: MeshTxBuilderBody,
|
|
1048
|
+
txEvaluation: Omit<Action, "data">[]
|
|
1049
|
+
) => {
|
|
1050
|
+
txEvaluation.forEach((redeemerEvaluation) => {
|
|
1051
|
+
switch (redeemerEvaluation.tag) {
|
|
1052
|
+
case "SPEND": {
|
|
1053
|
+
const input = meshTxBuilderBody.inputs[redeemerEvaluation.index]!;
|
|
1054
|
+
if (input.type == "Script" && input.scriptTxIn.redeemer) {
|
|
1055
|
+
input.scriptTxIn.redeemer.exUnits.mem = Math.floor(
|
|
1056
|
+
redeemerEvaluation.budget.mem * this.txEvaluationMultiplier
|
|
1057
|
+
);
|
|
1058
|
+
input.scriptTxIn.redeemer.exUnits.steps = Math.floor(
|
|
1059
|
+
redeemerEvaluation.budget.steps * this.txEvaluationMultiplier
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1062
|
+
break;
|
|
1063
|
+
}
|
|
1064
|
+
case "MINT": {
|
|
1065
|
+
const mint = meshTxBuilderBody.mints[redeemerEvaluation.index]!;
|
|
1066
|
+
if (mint.type == "Plutus" && mint.redeemer) {
|
|
1067
|
+
mint.redeemer.exUnits.mem = Math.floor(
|
|
1068
|
+
redeemerEvaluation.budget.mem * this.txEvaluationMultiplier
|
|
1069
|
+
);
|
|
1070
|
+
mint.redeemer.exUnits.steps = Math.floor(
|
|
1071
|
+
redeemerEvaluation.budget.steps * this.txEvaluationMultiplier
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
case "CERT":
|
|
1077
|
+
// TODO
|
|
1078
|
+
break;
|
|
1079
|
+
case "REWARD":
|
|
1080
|
+
// TODO
|
|
1081
|
+
break;
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
addUtxosFromSelection = () => {
|
|
1087
|
+
const requiredAssets = this.meshTxBuilderBody.outputs.reduce(
|
|
1088
|
+
(map, output) => {
|
|
1089
|
+
const outputAmount = output.amount;
|
|
1090
|
+
outputAmount.forEach((asset) => {
|
|
1091
|
+
const { unit, quantity } = asset;
|
|
1092
|
+
const existingQuantity = Number(map.get(unit)) || 0;
|
|
1093
|
+
map.set(unit, String(existingQuantity + Number(quantity)));
|
|
1094
|
+
});
|
|
1095
|
+
return map;
|
|
1096
|
+
},
|
|
1097
|
+
new Map<Unit, Quantity>()
|
|
1098
|
+
);
|
|
1099
|
+
this.meshTxBuilderBody.inputs.reduce((map, input) => {
|
|
1100
|
+
const inputAmount = input.txIn.amount;
|
|
1101
|
+
inputAmount?.forEach((asset) => {
|
|
1102
|
+
const { unit, quantity } = asset;
|
|
1103
|
+
const existingQuantity = Number(map.get(unit)) || 0;
|
|
1104
|
+
map.set(unit, String(existingQuantity - Number(quantity)));
|
|
1105
|
+
});
|
|
1106
|
+
return map;
|
|
1107
|
+
}, requiredAssets);
|
|
1108
|
+
this.meshTxBuilderBody.mints.reduce((map, mint) => {
|
|
1109
|
+
const mintAmount: Asset = {
|
|
1110
|
+
unit: mint.policyId + mint.assetName,
|
|
1111
|
+
quantity: String(mint.amount),
|
|
1112
|
+
};
|
|
1113
|
+
const existingQuantity = Number(map.get(mintAmount.unit)) || 0;
|
|
1114
|
+
map.set(
|
|
1115
|
+
mintAmount.unit,
|
|
1116
|
+
String(existingQuantity - Number(mintAmount.quantity))
|
|
1117
|
+
);
|
|
1118
|
+
return map;
|
|
1119
|
+
}, requiredAssets);
|
|
1120
|
+
const selectedInputs = experimentalSelectUtxos(
|
|
1121
|
+
requiredAssets,
|
|
1122
|
+
this.meshTxBuilderBody.extraInputs,
|
|
1123
|
+
this.meshTxBuilderBody.selectionThreshold.toString()
|
|
1124
|
+
);
|
|
1125
|
+
selectedInputs.forEach((input) => {
|
|
1126
|
+
const pubKeyTxIn: PubKeyTxIn = {
|
|
1127
|
+
type: "PubKey",
|
|
1128
|
+
txIn: {
|
|
1129
|
+
txHash: input.input.txHash,
|
|
1130
|
+
txIndex: input.input.outputIndex,
|
|
1131
|
+
amount: input.output.amount,
|
|
1132
|
+
address: input.output.address,
|
|
1133
|
+
},
|
|
1134
|
+
};
|
|
1135
|
+
this.meshTxBuilderBody.inputs.push(pubKeyTxIn);
|
|
1136
|
+
});
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
removeDuplicateInputs = () => {
|
|
1140
|
+
const { inputs } = this.meshTxBuilderBody;
|
|
1141
|
+
const getTxInId = (txIn: TxInParameter): string =>
|
|
1142
|
+
`${txIn.txHash}#${txIn.txIndex}`;
|
|
1143
|
+
const currentTxInIds: string[] = [];
|
|
1144
|
+
const addedInputs: TxIn[] = [];
|
|
1145
|
+
for (let i = 0; i < inputs.length; i += 1) {
|
|
1146
|
+
const currentInput = inputs[i]!;
|
|
1147
|
+
const currentTxInId = getTxInId(currentInput.txIn);
|
|
1148
|
+
if (currentTxInIds.includes(currentTxInId)) {
|
|
1149
|
+
inputs.splice(i, 1);
|
|
1150
|
+
i -= 1;
|
|
1151
|
+
} else {
|
|
1152
|
+
addedInputs.push(currentInput);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
this.meshTxBuilderBody.inputs = addedInputs;
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
emptyTxBuilderBody = () => {
|
|
1159
|
+
this.meshTxBuilderBody = emptyTxBuilderBody();
|
|
1160
|
+
return emptyTxBuilderBody;
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
reset = () => {
|
|
1164
|
+
this.meshTxBuilderBody = emptyTxBuilderBody();
|
|
1165
|
+
this.txEvaluationMultiplier = 1.1;
|
|
1166
|
+
this.txOutput = undefined;
|
|
1167
|
+
this.addingPlutusScriptInput = false;
|
|
1168
|
+
this.plutusSpendingScriptVersion = undefined;
|
|
1169
|
+
this.addingPlutusMint = false;
|
|
1170
|
+
this.plutusMintingScriptVersion = undefined;
|
|
1171
|
+
this.addingPlutusWithdrawal = false;
|
|
1172
|
+
this.plutusWithdrawalScriptVersion = undefined;
|
|
1173
|
+
this._protocolParams = DEFAULT_PROTOCOL_PARAMETERS;
|
|
1174
|
+
this.mintItem = undefined;
|
|
1175
|
+
this.txInQueueItem = undefined;
|
|
1176
|
+
this.withdrawalItem = undefined;
|
|
1177
|
+
this.collateralQueueItem = undefined;
|
|
1178
|
+
this.refScriptTxInQueueItem = undefined;
|
|
1179
|
+
};
|
|
1180
|
+
}
|