@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,63 @@
|
|
|
1
|
+
import type { NativeScript } from "@meshsdk/common";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
buildScriptPubkey,
|
|
5
|
+
deserializeEd25519KeyHash,
|
|
6
|
+
toNativeScript,
|
|
7
|
+
resolvePaymentKeyHash,
|
|
8
|
+
} from "@meshsdk/core-cst";
|
|
9
|
+
|
|
10
|
+
export class ForgeScript {
|
|
11
|
+
static withOneSignature(address: string): string {
|
|
12
|
+
const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address));
|
|
13
|
+
return buildScriptPubkey(keyHash).toCbor();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// static withAtLeastNSignatures(
|
|
17
|
+
// addresses: string[], minimumRequired: number,
|
|
18
|
+
// ): string {
|
|
19
|
+
// const nativeScripts = csl.NativeScripts.new();
|
|
20
|
+
|
|
21
|
+
// addresses.forEach((address) => {
|
|
22
|
+
// const keyHash = deserializeEd25519KeyHash(
|
|
23
|
+
// resolvePaymentKeyHash(address),
|
|
24
|
+
// );
|
|
25
|
+
// nativeScripts.add(buildScriptPubkey(keyHash));
|
|
26
|
+
// });
|
|
27
|
+
|
|
28
|
+
// const scriptNOfK = csl.ScriptNOfK.new(minimumRequired, nativeScripts);
|
|
29
|
+
// return csl.NativeScript.new_script_any(scriptNOfK).to_hex();
|
|
30
|
+
// }
|
|
31
|
+
|
|
32
|
+
// static withAnySignature(addresses: string[]): string {
|
|
33
|
+
// const nativeScripts = csl.NativeScripts.new();
|
|
34
|
+
|
|
35
|
+
// addresses.forEach((address) => {
|
|
36
|
+
// const keyHash = deserializeEd25519KeyHash(
|
|
37
|
+
// resolvePaymentKeyHash(address),
|
|
38
|
+
// );
|
|
39
|
+
// nativeScripts.add(buildScriptPubkey(keyHash));
|
|
40
|
+
// });
|
|
41
|
+
|
|
42
|
+
// const scriptAny = csl.ScriptAny.new(nativeScripts);
|
|
43
|
+
// return csl.NativeScript.new_script_any(scriptAny).to_hex();
|
|
44
|
+
// }
|
|
45
|
+
|
|
46
|
+
// static withAllSignatures(addresses: string[]): string {
|
|
47
|
+
// const nativeScripts = csl.NativeScripts.new();
|
|
48
|
+
|
|
49
|
+
// addresses.forEach((address) => {
|
|
50
|
+
// const keyHash = deserializeEd25519KeyHash(
|
|
51
|
+
// resolvePaymentKeyHash(address),
|
|
52
|
+
// );
|
|
53
|
+
// nativeScripts.add(buildScriptPubkey(keyHash));
|
|
54
|
+
// });
|
|
55
|
+
|
|
56
|
+
// const scriptAll = csl.ScriptAll.new(nativeScripts);
|
|
57
|
+
// return csl.NativeScript.new_script_any(scriptAll).to_hex();
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
static fromNativeScript(script: NativeScript): string {
|
|
61
|
+
return toNativeScript(script).toCbor();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./forge.script";
|
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Action,
|
|
3
|
+
Asset,
|
|
4
|
+
Budget,
|
|
5
|
+
CIP68_100,
|
|
6
|
+
CIP68_222,
|
|
7
|
+
DEFAULT_REDEEMER_BUDGET,
|
|
8
|
+
Data,
|
|
9
|
+
IInitiator,
|
|
10
|
+
Mint,
|
|
11
|
+
NativeScript,
|
|
12
|
+
POLICY_ID_LENGTH,
|
|
13
|
+
PlutusScript,
|
|
14
|
+
PoolParams,
|
|
15
|
+
Recipient,
|
|
16
|
+
SUPPORTED_TOKENS,
|
|
17
|
+
Token,
|
|
18
|
+
UTxO,
|
|
19
|
+
hexToString,
|
|
20
|
+
metadataToCip68,
|
|
21
|
+
stringToHex,
|
|
22
|
+
} from "@meshsdk/common";
|
|
23
|
+
import { MeshTxBuilder, MeshTxBuilderOptions } from "../mesh-tx-builder";
|
|
24
|
+
import {
|
|
25
|
+
deserializeNativeScript,
|
|
26
|
+
deserializePlutusScript,
|
|
27
|
+
fromScriptRef,
|
|
28
|
+
} from "@meshsdk/core-cst";
|
|
29
|
+
|
|
30
|
+
export interface TransactionOptions extends MeshTxBuilderOptions {
|
|
31
|
+
initiator: IInitiator;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class Transaction {
|
|
35
|
+
txBuilder: MeshTxBuilder;
|
|
36
|
+
initiator: IInitiator;
|
|
37
|
+
isCollateralNeeded: boolean = false;
|
|
38
|
+
|
|
39
|
+
constructor(options: TransactionOptions) {
|
|
40
|
+
this.txBuilder = new MeshTxBuilder(options);
|
|
41
|
+
this.initiator = options.initiator;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Adds an output to the transaction.
|
|
46
|
+
*
|
|
47
|
+
* @param recipient The recipient of the output.
|
|
48
|
+
* @param assets The assets to send. Provide string for lovelace and Asset[] for tokens and/or lovelace.
|
|
49
|
+
* @returns The transaction builder.
|
|
50
|
+
* @see {@link https://meshjs.dev/apis/transaction#sendAssets}
|
|
51
|
+
*/
|
|
52
|
+
sendAssets(recipient: Recipient, assets: Asset[] | string): Transaction {
|
|
53
|
+
if (typeof assets === "string") {
|
|
54
|
+
assets = [
|
|
55
|
+
{
|
|
56
|
+
unit: "lovelace",
|
|
57
|
+
quantity: assets,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
if (typeof recipient === "string") {
|
|
62
|
+
this.txBuilder.txOut(recipient, assets);
|
|
63
|
+
}
|
|
64
|
+
if (typeof recipient === "object") {
|
|
65
|
+
this.txBuilder.txOut(recipient.address, assets);
|
|
66
|
+
if (recipient.datum) {
|
|
67
|
+
if (recipient.datum.inline) {
|
|
68
|
+
this.txBuilder.txOutInlineDatumValue(recipient.datum.value);
|
|
69
|
+
} else {
|
|
70
|
+
this.txBuilder.txOutDatumHashValue(recipient.datum.value);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Suggest deprecated - Adds a transaction output to the transaction.
|
|
80
|
+
* Use sendAssets instead:
|
|
81
|
+
* ```ts
|
|
82
|
+
* this.sendAssets(recipient, lovelace);
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Deprecation reason - Unnecessary implementation which might cause confusion.
|
|
86
|
+
*
|
|
87
|
+
* @param {Recipient} recipient The recipient of the transaction.
|
|
88
|
+
* @param {string} lovelace The amount of lovelace to send.
|
|
89
|
+
* @returns {Transaction} The Transaction object.
|
|
90
|
+
* @see {@link https://meshjs.dev/apis/transaction#sendAda}
|
|
91
|
+
*/
|
|
92
|
+
sendLovelace(recipient: Recipient, lovelace: string): Transaction {
|
|
93
|
+
return this.sendAssets(recipient, lovelace);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Suggest deprecated - Adds stable coins transaction output to the transaction.
|
|
98
|
+
* Please use sendAssets with helper function to obtain token unit instead:
|
|
99
|
+
* ```ts
|
|
100
|
+
* const assets = [{ unit: SUPPORTED_TOKENS.GIMBAL, quantity: "100" }]
|
|
101
|
+
* transaction.sendAssets(recipient, assets)
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* Deprecation reason - Required maintenance on tokens.
|
|
105
|
+
*
|
|
106
|
+
* @param {Recipient} recipient The recipient of the transaction.
|
|
107
|
+
* @param {Token} ticker The ticker of the token to send.
|
|
108
|
+
* @param {string} amount The amount of the token to send.
|
|
109
|
+
* @returns {Transaction} The Transaction object.
|
|
110
|
+
* @see {@link https://meshjs.dev/apis/transaction#sendToken}
|
|
111
|
+
*/
|
|
112
|
+
sendToken(recipient: Recipient, ticker: Token, amount: string): Transaction {
|
|
113
|
+
const assets = [{ unit: SUPPORTED_TOKENS[ticker], quantity: amount }];
|
|
114
|
+
return this.sendAssets(recipient, assets);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Adds an output to the transaction.
|
|
119
|
+
* Suggest deprecated - use sendAssets instead:
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* const assets = value.output.amount;
|
|
123
|
+
* this.sendAssets(recipient, assets);
|
|
124
|
+
* ```
|
|
125
|
+
* Deprecation reason - Unnecessary implementation which might cause confusion.
|
|
126
|
+
*
|
|
127
|
+
* @param {Recipient} recipient The recipient of the output.
|
|
128
|
+
* @param {UTxO} value The UTxO value of the output.
|
|
129
|
+
* @returns {Transaction} The Transaction object.
|
|
130
|
+
*/
|
|
131
|
+
sendValue(recipient: Recipient, value: UTxO): Transaction {
|
|
132
|
+
const assets = value.output.amount;
|
|
133
|
+
return this.sendAssets(recipient, assets);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Sets the inputs for the transaction.
|
|
138
|
+
*
|
|
139
|
+
* @param {UTxO[]} inputs The inputs to set.
|
|
140
|
+
* @returns {Transaction} The transaction.
|
|
141
|
+
*/
|
|
142
|
+
setTxInputs(inputs: UTxO[]): Transaction {
|
|
143
|
+
inputs.forEach((input) => {
|
|
144
|
+
this.txBuilder.txIn(
|
|
145
|
+
input.input.txHash,
|
|
146
|
+
input.input.outputIndex,
|
|
147
|
+
input.output.amount,
|
|
148
|
+
input.output.address
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Sets the reference inputs for the transaction.
|
|
157
|
+
*
|
|
158
|
+
* @param {UTxO[]} inputs The reference inputs to set.
|
|
159
|
+
* @returns {Transaction} The transaction.
|
|
160
|
+
*/
|
|
161
|
+
setTxRefInputs(inputs: UTxO[]): Transaction {
|
|
162
|
+
inputs.forEach((input) => {
|
|
163
|
+
this.txBuilder.readOnlyTxInReference(
|
|
164
|
+
input.input.txHash,
|
|
165
|
+
input.input.outputIndex
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Sets the native script for the transaction.
|
|
174
|
+
* @param {NativeScript} script The native script to spend from.
|
|
175
|
+
* @param {UTxO} utxo The UTxO attached to the script.
|
|
176
|
+
* @returns {Transaction} The Transaction object.
|
|
177
|
+
*/
|
|
178
|
+
setNativeScriptInput(script: NativeScript, utxo: UTxO): Transaction {
|
|
179
|
+
const { scriptCbor } =
|
|
180
|
+
this.txBuilder.serializer.deserializer.script.deserializeNativeScript(
|
|
181
|
+
script
|
|
182
|
+
);
|
|
183
|
+
this.txBuilder
|
|
184
|
+
.txIn(
|
|
185
|
+
utxo.input.txHash,
|
|
186
|
+
utxo.input.outputIndex,
|
|
187
|
+
utxo.output.amount,
|
|
188
|
+
utxo.output.address
|
|
189
|
+
)
|
|
190
|
+
.txInScript(scriptCbor!);
|
|
191
|
+
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// TODO: nuke this probably as the input type is too confusing
|
|
196
|
+
redeemValue(options: {
|
|
197
|
+
value: UTxO;
|
|
198
|
+
script: PlutusScript | UTxO;
|
|
199
|
+
redeemer?: Pick<Action, "data"> & { budget?: Budget };
|
|
200
|
+
datum?: Data | UTxO;
|
|
201
|
+
}): Transaction {
|
|
202
|
+
const { value, script, datum, redeemer } = options;
|
|
203
|
+
const red = redeemer || {
|
|
204
|
+
data: { alternative: 0, fields: ["mesh"] },
|
|
205
|
+
budget: DEFAULT_REDEEMER_BUDGET,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if ("code" in script) {
|
|
209
|
+
// Provided script for redemption
|
|
210
|
+
this.isCollateralNeeded = true;
|
|
211
|
+
this.spendingPlutusScript(script)
|
|
212
|
+
.txIn(
|
|
213
|
+
value.input.txHash,
|
|
214
|
+
value.input.outputIndex,
|
|
215
|
+
value.output.amount,
|
|
216
|
+
value.output.address
|
|
217
|
+
)
|
|
218
|
+
.txInScript(script.code)
|
|
219
|
+
.txInRedeemerValue(red.data, "Mesh", red.budget);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if ("output" in script) {
|
|
223
|
+
// Reference script for redemption
|
|
224
|
+
if (!script.output.scriptRef) {
|
|
225
|
+
throw new Error("redeemValue: No script reference found in UTxO");
|
|
226
|
+
}
|
|
227
|
+
const scriptRef = fromScriptRef(script.output.scriptRef);
|
|
228
|
+
if (!scriptRef || !("code" in scriptRef)) {
|
|
229
|
+
throw new Error("redeemValue: Script reference not found");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.isCollateralNeeded = true;
|
|
233
|
+
this.spendingPlutusScript(scriptRef)
|
|
234
|
+
.txIn(
|
|
235
|
+
value.input.txHash,
|
|
236
|
+
value.input.outputIndex,
|
|
237
|
+
value.output.amount,
|
|
238
|
+
value.output.address
|
|
239
|
+
)
|
|
240
|
+
.spendingTxInReference(
|
|
241
|
+
script.input.txHash,
|
|
242
|
+
script.input.outputIndex,
|
|
243
|
+
script.output.scriptHash
|
|
244
|
+
)
|
|
245
|
+
.txInRedeemerValue(red.data, "Mesh", red.budget);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (datum) {
|
|
249
|
+
// Provided datum for redemption
|
|
250
|
+
this.txBuilder.txInDatumValue(datum);
|
|
251
|
+
} else {
|
|
252
|
+
// Reference datum for redemption
|
|
253
|
+
this.txBuilder.txInInlineDatumPresent();
|
|
254
|
+
}
|
|
255
|
+
// if (typeof datum === "object" && "output" in datum) {
|
|
256
|
+
// // Reference datum for redemption
|
|
257
|
+
// } else {
|
|
258
|
+
// // Provided datum for redemption
|
|
259
|
+
// if (datum) {
|
|
260
|
+
// }
|
|
261
|
+
// }
|
|
262
|
+
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// TODO: nuke this probably as the input type is too confusing
|
|
267
|
+
mintAsset(
|
|
268
|
+
forgeScript: string | PlutusScript | UTxO,
|
|
269
|
+
mint: Mint,
|
|
270
|
+
redeemer?: Pick<Action, "data"> & { budget?: Budget }
|
|
271
|
+
): Transaction {
|
|
272
|
+
const assetQuantity = mint.assetQuantity;
|
|
273
|
+
let assetNameHex = stringToHex(mint.assetName);
|
|
274
|
+
const referenceAssetNameHex = CIP68_100(assetNameHex);
|
|
275
|
+
if (mint.cip68ScriptAddress) {
|
|
276
|
+
assetNameHex = CIP68_222(assetNameHex);
|
|
277
|
+
}
|
|
278
|
+
let policyId = "";
|
|
279
|
+
switch (typeof forgeScript) {
|
|
280
|
+
case "string":
|
|
281
|
+
policyId = deserializeNativeScript(forgeScript).hash().toString();
|
|
282
|
+
this.txBuilder
|
|
283
|
+
.mint(assetQuantity, policyId, assetNameHex)
|
|
284
|
+
.mintingScript(forgeScript);
|
|
285
|
+
if (mint.cip68ScriptAddress) {
|
|
286
|
+
this.txBuilder
|
|
287
|
+
.mint(assetQuantity, policyId, referenceAssetNameHex)
|
|
288
|
+
.mintingScript(forgeScript);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
break;
|
|
292
|
+
|
|
293
|
+
case "object":
|
|
294
|
+
if (!redeemer)
|
|
295
|
+
throw new Error(
|
|
296
|
+
"burnAsset: Redeemer data is required for Plutus minting"
|
|
297
|
+
);
|
|
298
|
+
if ("code" in forgeScript) {
|
|
299
|
+
// Burn plutus script assets with provided script
|
|
300
|
+
policyId = deserializePlutusScript(
|
|
301
|
+
forgeScript.code,
|
|
302
|
+
forgeScript.version
|
|
303
|
+
)
|
|
304
|
+
.hash()
|
|
305
|
+
.toString();
|
|
306
|
+
|
|
307
|
+
this.isCollateralNeeded = true;
|
|
308
|
+
this.mintPlutusScript(forgeScript)
|
|
309
|
+
.mint(assetQuantity, policyId, assetNameHex)
|
|
310
|
+
.mintingScript(forgeScript.code)
|
|
311
|
+
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
|
|
312
|
+
if (mint.cip68ScriptAddress) {
|
|
313
|
+
this.mintPlutusScript(forgeScript)
|
|
314
|
+
.mint(assetQuantity, policyId, referenceAssetNameHex)
|
|
315
|
+
.mintingScript(forgeScript.code)
|
|
316
|
+
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
if ("output" in forgeScript) {
|
|
321
|
+
// Burn plutus script assets with reference script
|
|
322
|
+
if (!forgeScript.output.scriptRef) {
|
|
323
|
+
throw new Error("mintAsset: No script reference found in UTxO");
|
|
324
|
+
}
|
|
325
|
+
const script = fromScriptRef(forgeScript.output.scriptRef);
|
|
326
|
+
if (!script) {
|
|
327
|
+
throw new Error("mintAsset: Script reference not found");
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if ("code" in script) {
|
|
331
|
+
policyId = deserializePlutusScript(script.code, script.version)
|
|
332
|
+
.hash()
|
|
333
|
+
.toString();
|
|
334
|
+
|
|
335
|
+
this.isCollateralNeeded = true;
|
|
336
|
+
this.mintPlutusScript(script)
|
|
337
|
+
.mint(assetQuantity, policyId, assetNameHex)
|
|
338
|
+
.mintTxInReference(
|
|
339
|
+
forgeScript.input.txHash,
|
|
340
|
+
forgeScript.input.outputIndex
|
|
341
|
+
)
|
|
342
|
+
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
|
|
343
|
+
if (mint.cip68ScriptAddress) {
|
|
344
|
+
this.mintPlutusScript(script)
|
|
345
|
+
.mint(assetQuantity, policyId, referenceAssetNameHex)
|
|
346
|
+
.mintTxInReference(
|
|
347
|
+
forgeScript.input.txHash,
|
|
348
|
+
forgeScript.input.outputIndex
|
|
349
|
+
)
|
|
350
|
+
.mintRedeemerValue(redeemer.data, "Mesh", redeemer.budget);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
break;
|
|
355
|
+
} else {
|
|
356
|
+
// TODO: to implement reference script minting for native script tokens
|
|
357
|
+
throw new Error(
|
|
358
|
+
"mintAsset: Reference script minting not implemented"
|
|
359
|
+
);
|
|
360
|
+
// this.txBuilder
|
|
361
|
+
// .mint(assetQuantity, policyId, assetName)
|
|
362
|
+
// .mintTxInReference(
|
|
363
|
+
// forgeScript.input.txHash,
|
|
364
|
+
// forgeScript.input.outputIndex
|
|
365
|
+
// );
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (mint.metadata && mint.label) {
|
|
372
|
+
this.setMetadata(Number(mint.label), {
|
|
373
|
+
[policyId]: {
|
|
374
|
+
[mint.assetName]: mint.metadata,
|
|
375
|
+
},
|
|
376
|
+
version: 1,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
if (mint.recipient) {
|
|
380
|
+
this.sendAssets(mint.recipient, [
|
|
381
|
+
{ unit: policyId + assetNameHex, quantity: mint.assetQuantity },
|
|
382
|
+
]);
|
|
383
|
+
}
|
|
384
|
+
if (mint.cip68ScriptAddress) {
|
|
385
|
+
this.sendAssets(
|
|
386
|
+
{
|
|
387
|
+
address: mint.cip68ScriptAddress,
|
|
388
|
+
datum: { inline: true, value: metadataToCip68(mint.metadata) },
|
|
389
|
+
},
|
|
390
|
+
[
|
|
391
|
+
{
|
|
392
|
+
unit: policyId + referenceAssetNameHex,
|
|
393
|
+
quantity: mint.assetQuantity,
|
|
394
|
+
},
|
|
395
|
+
]
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return this;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// TODO: nuke this probably as the input type is too confusing
|
|
403
|
+
// TO be deprecated as it doesnt support reference script minting native assets
|
|
404
|
+
burnAsset(
|
|
405
|
+
forgeScript: string | PlutusScript | UTxO,
|
|
406
|
+
asset: Asset,
|
|
407
|
+
redeemer?: Pick<Action, "data"> & { budget?: Budget }
|
|
408
|
+
): Transaction {
|
|
409
|
+
const assetQuantity = "-" + asset.quantity;
|
|
410
|
+
const mint: Mint = {
|
|
411
|
+
assetName: hexToString(asset.unit.slice(POLICY_ID_LENGTH)),
|
|
412
|
+
assetQuantity: assetQuantity,
|
|
413
|
+
};
|
|
414
|
+
try {
|
|
415
|
+
this.mintAsset(forgeScript, mint, redeemer);
|
|
416
|
+
} catch (error) {
|
|
417
|
+
throw new Error("burnAsset: " + error);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return this;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Sets the change address for the transaction.
|
|
425
|
+
*
|
|
426
|
+
* @param {string} changeAddress The change address.
|
|
427
|
+
* @returns {Transaction} The Transaction object.
|
|
428
|
+
*/
|
|
429
|
+
setChangeAddress(changeAddress: string): Transaction {
|
|
430
|
+
this.txBuilder.changeAddress(changeAddress);
|
|
431
|
+
return this;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Sets the collateral for the transaction.
|
|
436
|
+
*
|
|
437
|
+
* @param {UTxO[]} collateral - Set the UTxO for collateral.
|
|
438
|
+
* @returns {Transaction} The Transaction object.
|
|
439
|
+
*/
|
|
440
|
+
setCollateral(collateral: UTxO[]): Transaction {
|
|
441
|
+
collateral.forEach((collateralUtxo) => {
|
|
442
|
+
this.txBuilder.txInCollateral(
|
|
443
|
+
collateralUtxo.input.txHash,
|
|
444
|
+
collateralUtxo.input.outputIndex,
|
|
445
|
+
collateralUtxo.output.amount,
|
|
446
|
+
collateralUtxo.output.address
|
|
447
|
+
);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
return this;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Sets the required signers for the transaction.
|
|
455
|
+
*
|
|
456
|
+
* @param {string[]} addresses The addresses of the required signers.
|
|
457
|
+
* @returns {Transaction} The Transaction object.
|
|
458
|
+
*/
|
|
459
|
+
setRequiredSigners(addresses: string[]): Transaction {
|
|
460
|
+
addresses.forEach((address) => {
|
|
461
|
+
const { pubKeyHash } =
|
|
462
|
+
this.txBuilder.serializer.deserializer.key.deserializeAddress(address);
|
|
463
|
+
this.txBuilder.requiredSignerHash(pubKeyHash);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
return this;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Set the time to live for the transaction.
|
|
471
|
+
*
|
|
472
|
+
* @param {string} slot The slot number to expire the transaction at.
|
|
473
|
+
* @returns {Transaction} The Transaction object.
|
|
474
|
+
* @see {@link https://meshjs.dev/apis/transaction#setTimeLimit}
|
|
475
|
+
*/
|
|
476
|
+
setTimeToExpire(slot: string): Transaction {
|
|
477
|
+
this.txBuilder.invalidHereafter(Number(slot));
|
|
478
|
+
return this;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Sets the start slot for the transaction.
|
|
483
|
+
*
|
|
484
|
+
* @param {string} slot The start slot for the transaction.
|
|
485
|
+
* @returns {Transaction} The Transaction object.
|
|
486
|
+
* @see {@link https://meshjs.dev/apis/transaction#setTimeLimit}
|
|
487
|
+
*/
|
|
488
|
+
setTimeToStart(slot: string): Transaction {
|
|
489
|
+
this.txBuilder.invalidBefore(Number(slot));
|
|
490
|
+
return this;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Add a JSON metadata entry to the transaction.
|
|
495
|
+
*
|
|
496
|
+
* @param {number} key The key to use for the metadata entry.
|
|
497
|
+
* @param {unknown} value The value to use for the metadata entry.
|
|
498
|
+
* @returns {Transaction} The Transaction object.
|
|
499
|
+
* @see {@link https://meshjs.dev/apis/transaction#setMetadata}
|
|
500
|
+
*/
|
|
501
|
+
setMetadata(key: number, value: unknown): Transaction {
|
|
502
|
+
this.txBuilder.metadataValue(key.toString(), value as object);
|
|
503
|
+
return this;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
withdrawRewards(rewardAddress: string, lovelace: string): Transaction {
|
|
507
|
+
this.txBuilder.withdrawal(rewardAddress, lovelace);
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
delegateStake(rewardAddress: string, poolId: string): Transaction {
|
|
512
|
+
this.txBuilder.delegateStakeCertificate(
|
|
513
|
+
this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(
|
|
514
|
+
rewardAddress
|
|
515
|
+
),
|
|
516
|
+
this.txBuilder.serializer.resolver.keys.resolveEd25519KeyHash(poolId)
|
|
517
|
+
);
|
|
518
|
+
return this;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
deregisterStake(rewardAddress: string): Transaction {
|
|
522
|
+
this.txBuilder.deregisterStakeCertificate(
|
|
523
|
+
this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
|
|
524
|
+
);
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
registerStake(rewardAddress: string): Transaction {
|
|
529
|
+
this.txBuilder.registerStakeCertificate(
|
|
530
|
+
this.txBuilder.serializer.resolver.keys.resolveStakeKeyHash(rewardAddress)
|
|
531
|
+
);
|
|
532
|
+
return this;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// TODO: test
|
|
536
|
+
registerPool(params: PoolParams): Transaction {
|
|
537
|
+
this.txBuilder.registerPoolCertificate(params);
|
|
538
|
+
return this;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// TODO: test
|
|
542
|
+
retirePool(poolId: string, epochNo: number): Transaction {
|
|
543
|
+
this.txBuilder.retirePoolCertificate(poolId, epochNo);
|
|
544
|
+
return this;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async build(): Promise<string> {
|
|
548
|
+
try {
|
|
549
|
+
await this.addCollateralIfNeeded();
|
|
550
|
+
await this.addTxInputsAsNeeded();
|
|
551
|
+
await this.addChangeAddress();
|
|
552
|
+
|
|
553
|
+
return this.txBuilder.complete();
|
|
554
|
+
} catch (error) {
|
|
555
|
+
throw new Error(
|
|
556
|
+
`[Transaction] An error occurred during build: ${error}.`
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
protected mintPlutusScript(script: PlutusScript) {
|
|
562
|
+
switch (script.version) {
|
|
563
|
+
case "V1":
|
|
564
|
+
this.txBuilder.mintPlutusScriptV1();
|
|
565
|
+
break;
|
|
566
|
+
case "V2":
|
|
567
|
+
this.txBuilder.mintPlutusScriptV2();
|
|
568
|
+
break;
|
|
569
|
+
case "V3":
|
|
570
|
+
this.txBuilder.mintPlutusScriptV3();
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
573
|
+
return this.txBuilder;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
protected spendingPlutusScript(script: PlutusScript) {
|
|
577
|
+
switch (script.version) {
|
|
578
|
+
case "V1":
|
|
579
|
+
this.txBuilder.spendingPlutusScriptV1();
|
|
580
|
+
break;
|
|
581
|
+
case "V2":
|
|
582
|
+
this.txBuilder.spendingPlutusScriptV2();
|
|
583
|
+
break;
|
|
584
|
+
case "V3":
|
|
585
|
+
this.txBuilder.spendingPlutusScriptV3();
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
return this.txBuilder;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
private async addCollateralIfNeeded() {
|
|
592
|
+
if (this.isCollateralNeeded) {
|
|
593
|
+
const collaterals = await this.initiator.getCollateral();
|
|
594
|
+
this.setCollateral(collaterals);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
private async addTxInputsAsNeeded() {
|
|
599
|
+
const utxos = await this.initiator.getUtxos();
|
|
600
|
+
this.txBuilder.selectUtxosFrom(utxos);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
private async addChangeAddress() {
|
|
604
|
+
if (this.txBuilder.meshTxBuilderBody.changeAddress === "") {
|
|
605
|
+
const changeAddress = await this.initiator.getChangeAddress();
|
|
606
|
+
this.setChangeAddress(changeAddress);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|