@meshsdk/core-csl 1.6.0-alpha.1

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.
Files changed (74) hide show
  1. package/README.md +9 -0
  2. package/dist/cjs/core/builder.d.ts +38 -0
  3. package/dist/cjs/core/builder.js +389 -0
  4. package/dist/cjs/core/index.d.ts +1 -0
  5. package/dist/cjs/core/index.js +17 -0
  6. package/dist/cjs/deser/builder.d.ts +18 -0
  7. package/dist/cjs/deser/builder.js +130 -0
  8. package/dist/cjs/deser/constants.d.ts +12 -0
  9. package/dist/cjs/deser/constants.js +15 -0
  10. package/dist/cjs/deser/converter.d.ts +27 -0
  11. package/dist/cjs/deser/converter.js +352 -0
  12. package/dist/cjs/deser/csl.d.ts +1 -0
  13. package/dist/cjs/deser/csl.js +27 -0
  14. package/dist/cjs/deser/deserializer.d.ts +19 -0
  15. package/dist/cjs/deser/deserializer.js +40 -0
  16. package/dist/cjs/deser/index.d.ts +6 -0
  17. package/dist/cjs/deser/index.js +22 -0
  18. package/dist/cjs/deser/types.d.ts +146 -0
  19. package/dist/cjs/deser/types.js +2 -0
  20. package/dist/cjs/index.d.ts +3 -0
  21. package/dist/cjs/index.js +19 -0
  22. package/dist/cjs/utils/address.d.ts +12 -0
  23. package/dist/cjs/utils/address.js +60 -0
  24. package/dist/cjs/utils/aiken.d.ts +2 -0
  25. package/dist/cjs/utils/aiken.js +20 -0
  26. package/dist/cjs/utils/credentials.d.ts +1 -0
  27. package/dist/cjs/utils/credentials.js +10 -0
  28. package/dist/cjs/utils/datum.d.ts +4 -0
  29. package/dist/cjs/utils/datum.js +18 -0
  30. package/dist/cjs/utils/index.d.ts +7 -0
  31. package/dist/cjs/utils/index.js +23 -0
  32. package/dist/cjs/utils/scripts.d.ts +1 -0
  33. package/dist/cjs/utils/scripts.js +6 -0
  34. package/dist/cjs/utils/staking.d.ts +3 -0
  35. package/dist/cjs/utils/staking.js +25 -0
  36. package/dist/cjs/utils/transaction.d.ts +2 -0
  37. package/dist/cjs/utils/transaction.js +15 -0
  38. package/dist/mjs/core/builder.d.ts +38 -0
  39. package/dist/mjs/core/builder.js +380 -0
  40. package/dist/mjs/core/index.d.ts +1 -0
  41. package/dist/mjs/core/index.js +1 -0
  42. package/dist/mjs/deser/builder.d.ts +18 -0
  43. package/dist/mjs/deser/builder.js +118 -0
  44. package/dist/mjs/deser/constants.d.ts +12 -0
  45. package/dist/mjs/deser/constants.js +12 -0
  46. package/dist/mjs/deser/converter.d.ts +27 -0
  47. package/dist/mjs/deser/converter.js +321 -0
  48. package/dist/mjs/deser/csl.d.ts +1 -0
  49. package/dist/mjs/deser/csl.js +1 -0
  50. package/dist/mjs/deser/deserializer.d.ts +19 -0
  51. package/dist/mjs/deser/deserializer.js +20 -0
  52. package/dist/mjs/deser/index.d.ts +6 -0
  53. package/dist/mjs/deser/index.js +6 -0
  54. package/dist/mjs/deser/types.d.ts +146 -0
  55. package/dist/mjs/deser/types.js +1 -0
  56. package/dist/mjs/index.d.ts +3 -0
  57. package/dist/mjs/index.js +3 -0
  58. package/dist/mjs/utils/address.d.ts +12 -0
  59. package/dist/mjs/utils/address.js +50 -0
  60. package/dist/mjs/utils/aiken.d.ts +2 -0
  61. package/dist/mjs/utils/aiken.js +15 -0
  62. package/dist/mjs/utils/credentials.d.ts +1 -0
  63. package/dist/mjs/utils/credentials.js +6 -0
  64. package/dist/mjs/utils/datum.d.ts +4 -0
  65. package/dist/mjs/utils/datum.js +13 -0
  66. package/dist/mjs/utils/index.d.ts +7 -0
  67. package/dist/mjs/utils/index.js +7 -0
  68. package/dist/mjs/utils/scripts.d.ts +1 -0
  69. package/dist/mjs/utils/scripts.js +2 -0
  70. package/dist/mjs/utils/staking.d.ts +3 -0
  71. package/dist/mjs/utils/staking.js +18 -0
  72. package/dist/mjs/utils/transaction.d.ts +2 -0
  73. package/dist/mjs/utils/transaction.js +10 -0
  74. package/package.json +53 -0
@@ -0,0 +1,380 @@
1
+ import JSONbig from 'json-bigint';
2
+ import { DEFAULT_PROTOCOL_PARAMETERS, selectUtxos } from '@meshsdk/common';
3
+ import { signTransaction } from '../utils';
4
+ import { buildDataCost, buildTxBuilder, toAddress, toPlutusData, toRelay, toValue, csl, LANGUAGE_VERSIONS, } from '../deser';
5
+ export const emptyTxBuilderBody = () => ({
6
+ inputs: [],
7
+ outputs: [],
8
+ extraInputs: [],
9
+ selectionThreshold: 0,
10
+ collaterals: [],
11
+ requiredSignatures: [],
12
+ referenceInputs: [],
13
+ mints: [],
14
+ changeAddress: '',
15
+ metadata: [],
16
+ validityRange: {},
17
+ certificates: [],
18
+ signingKey: [],
19
+ });
20
+ export class CSLSerializer {
21
+ txBuilder;
22
+ protocolParams;
23
+ meshTxBuilderBody = emptyTxBuilderBody();
24
+ constructor(protocolParams) {
25
+ this.protocolParams = protocolParams || DEFAULT_PROTOCOL_PARAMETERS;
26
+ this.txBuilder = buildTxBuilder(protocolParams);
27
+ }
28
+ serializeTxBody(txBody, protocolParams) {
29
+ if (protocolParams) {
30
+ this.protocolParams = protocolParams;
31
+ }
32
+ this.txBuilder = buildTxBuilder(protocolParams);
33
+ const { inputs, outputs, extraInputs, selectionThreshold, collaterals, referenceInputs, mints, changeAddress, certificates, validityRange, requiredSignatures, metadata, } = txBody;
34
+ if (extraInputs.length > 0) {
35
+ this.addUtxosFrom(extraInputs, String(selectionThreshold));
36
+ }
37
+ this.removeDuplicateInputs();
38
+ mints.sort((a, b) => a.policyId.localeCompare(b.policyId));
39
+ inputs.sort((a, b) => {
40
+ if (a.txIn.txHash === b.txIn.txHash) {
41
+ return a.txIn.txIndex - b.txIn.txIndex;
42
+ }
43
+ return a.txIn.txHash.localeCompare(b.txIn.txHash);
44
+ });
45
+ this.addAllInputs(inputs);
46
+ this.addAllOutputs(outputs);
47
+ this.addAllCollaterals(collaterals);
48
+ this.addAllReferenceInputs(referenceInputs);
49
+ this.addAllMints(mints);
50
+ this.addAllCertificates(certificates);
51
+ this.addValidityRange(validityRange);
52
+ this.addAllRequiredSignatures(requiredSignatures);
53
+ this.addAllMetadata(metadata);
54
+ this.addCostModels();
55
+ if (changeAddress) {
56
+ // Hacky fix to set a dummy collateral return so fees are calculated correctly
57
+ const totalCollateral = collaterals
58
+ .map((collateral) => collateral.txIn.amount?.find((asset) => asset.unit === 'lovelace')
59
+ ?.quantity || '0')
60
+ .reduce((acc, curr) => acc + parseInt(curr), 0);
61
+ const collateralEstimate = Math.ceil((this.protocolParams.collateralPercent *
62
+ Number(Number(this.txBuilder
63
+ .min_fee()
64
+ .checked_add(csl.BigNum.from_str('10000'))
65
+ .to_js_value()))) /
66
+ 100);
67
+ let collateralReturnNeeded = false;
68
+ if (totalCollateral - collateralEstimate > 0) {
69
+ const collateralEstimateOutput = csl.TransactionOutput.new(csl.Address.from_bech32(changeAddress), csl.Value.new(csl.BigNum.from_str(String(collateralEstimate))));
70
+ if (totalCollateral - collateralEstimate >
71
+ Number(csl
72
+ .min_ada_for_output(collateralEstimateOutput, csl.DataCost.new_coins_per_byte(csl.BigNum.from_str(this.protocolParams.coinsPerUTxOSize)))
73
+ .to_js_value())) {
74
+ this.txBuilder.set_collateral_return(csl.TransactionOutput.new(csl.Address.from_bech32(changeAddress), csl.Value.new(csl.BigNum.from_str(String(totalCollateral)))));
75
+ this.txBuilder.set_total_collateral(csl.BigNum.from_str(String(totalCollateral)));
76
+ collateralReturnNeeded = true;
77
+ }
78
+ }
79
+ this.addChange(changeAddress);
80
+ if (collateralReturnNeeded)
81
+ this.addCollateralReturn(changeAddress);
82
+ }
83
+ const tx = this.txBuilder.build_tx();
84
+ // const txJson = JSON.parse(tx.to_json());
85
+ const txHex = tx.to_hex();
86
+ return txHex;
87
+ }
88
+ addSigningKeys(txHex, signingKeys) {
89
+ if (signingKeys.length > 0) {
90
+ return signTransaction(txHex, signingKeys);
91
+ }
92
+ return txHex;
93
+ }
94
+ addUtxosFrom = (extraInputs, threshold) => {
95
+ const requiredAssets = this.meshTxBuilderBody.outputs.reduce((map, output) => {
96
+ const outputAmount = output.amount;
97
+ outputAmount.forEach((asset) => {
98
+ const { unit, quantity } = asset;
99
+ const existingQuantity = Number(map.get(unit)) || 0;
100
+ map.set(unit, String(existingQuantity + Number(quantity)));
101
+ });
102
+ return map;
103
+ }, new Map());
104
+ this.meshTxBuilderBody.inputs.reduce((map, input) => {
105
+ const inputAmount = input.txIn.amount;
106
+ inputAmount?.forEach((asset) => {
107
+ const { unit, quantity } = asset;
108
+ const existingQuantity = Number(map.get(unit)) || 0;
109
+ map.set(unit, String(existingQuantity - Number(quantity)));
110
+ });
111
+ return map;
112
+ }, requiredAssets);
113
+ this.meshTxBuilderBody.mints.reduce((map, mint) => {
114
+ const mintAmount = {
115
+ unit: mint.policyId + mint.assetName,
116
+ quantity: String(mint.amount),
117
+ };
118
+ const existingQuantity = Number(map.get(mintAmount.unit)) || 0;
119
+ map.set(mintAmount.unit, String(existingQuantity - Number(mintAmount.quantity)));
120
+ return map;
121
+ }, requiredAssets);
122
+ const selectedInputs = selectUtxos(extraInputs, requiredAssets, threshold);
123
+ selectedInputs.forEach((input) => {
124
+ const pubKeyTxIn = {
125
+ type: 'PubKey',
126
+ txIn: {
127
+ txHash: input.input.txHash,
128
+ txIndex: input.input.outputIndex,
129
+ amount: input.output.amount,
130
+ address: input.output.address,
131
+ },
132
+ };
133
+ this.meshTxBuilderBody.inputs.push(pubKeyTxIn);
134
+ this.addTxIn(pubKeyTxIn);
135
+ });
136
+ };
137
+ makePlutusScriptSource = (scriptSourceInfo) => {
138
+ const scriptHash = csl.ScriptHash.from_hex(scriptSourceInfo.spendingScriptHash);
139
+ const scriptRefInput = csl.TransactionInput.new(csl.TransactionHash.from_hex(scriptSourceInfo.txHash), scriptSourceInfo.txIndex);
140
+ const scriptSource = csl.PlutusScriptSource.new_ref_input_with_lang_ver(scriptHash, scriptRefInput, LANGUAGE_VERSIONS[scriptSourceInfo.version]);
141
+ return scriptSource;
142
+ };
143
+ // Below protected functions for completing tx building
144
+ removeDuplicateInputs = () => {
145
+ const { inputs } = this.meshTxBuilderBody;
146
+ const getTxInId = (txIn) => `${txIn.txHash}#${txIn.txIndex}`;
147
+ const addedInputs = [];
148
+ for (let i = 0; i < inputs.length; i += 1) {
149
+ const currentTxInId = getTxInId(inputs[i].txIn);
150
+ if (addedInputs.includes(currentTxInId)) {
151
+ inputs.splice(i, 1);
152
+ i -= 1;
153
+ }
154
+ else {
155
+ addedInputs.push(currentTxInId);
156
+ }
157
+ }
158
+ };
159
+ addAllInputs = (inputs) => {
160
+ for (let i = 0; i < inputs.length; i += 1) {
161
+ const currentTxIn = inputs[i]; // TODO: add type
162
+ switch (currentTxIn.type) {
163
+ case 'PubKey':
164
+ this.addTxIn(currentTxIn);
165
+ break;
166
+ case 'Script':
167
+ this.addScriptTxIn(currentTxIn);
168
+ break;
169
+ }
170
+ }
171
+ };
172
+ addTxIn = (currentTxIn) => {
173
+ this.txBuilder.add_input(csl.Address.from_bech32(currentTxIn.txIn.address), csl.TransactionInput.new(csl.TransactionHash.from_hex(currentTxIn.txIn.txHash), currentTxIn.txIn.txIndex), toValue(currentTxIn.txIn.amount));
174
+ };
175
+ addScriptTxIn = ({ scriptTxIn, txIn, }) => {
176
+ let cslDatum;
177
+ const { datumSource, scriptSource, redeemer } = scriptTxIn;
178
+ if (datumSource.type === 'Provided') {
179
+ cslDatum = csl.DatumSource.new(this.castDataToPlutusData(datumSource.data));
180
+ }
181
+ else {
182
+ const refTxIn = csl.TransactionInput.new(csl.TransactionHash.from_hex(datumSource.txHash), datumSource.txIndex);
183
+ cslDatum = csl.DatumSource.new_ref_input(refTxIn);
184
+ }
185
+ let cslScript;
186
+ if (scriptSource.type === 'Inline') {
187
+ cslScript = this.makePlutusScriptSource(scriptSource.txInInfo);
188
+ }
189
+ else {
190
+ cslScript = csl.PlutusScriptSource.new(csl.PlutusScript.from_hex_with_version(scriptSource.script.code, LANGUAGE_VERSIONS[scriptSource.script.version]));
191
+ }
192
+ const cslRedeemer = csl.Redeemer.new(csl.RedeemerTag.new_spend(), csl.BigNum.from_str('0'), this.castDataToPlutusData(redeemer.data), csl.ExUnits.new(csl.BigNum.from_str(String(redeemer.exUnits.mem)), csl.BigNum.from_str(String(redeemer.exUnits.steps))));
193
+ this.txBuilder.add_plutus_script_input(csl.PlutusWitness.new_with_ref(cslScript, cslDatum, cslRedeemer), csl.TransactionInput.new(csl.TransactionHash.from_hex(txIn.txHash), txIn.txIndex), toValue(txIn.amount));
194
+ };
195
+ addAllOutputs = (outputs) => {
196
+ for (let i = 0; i < outputs.length; i += 1) {
197
+ const currentOutput = outputs[i];
198
+ this.addOutput(currentOutput);
199
+ }
200
+ };
201
+ addOutput = ({ amount, address, datum, referenceScript }) => {
202
+ const txValue = toValue(amount);
203
+ const multiAsset = txValue.multiasset();
204
+ if (txValue.is_zero() && multiAsset === undefined)
205
+ throw Error('Invalid output amount');
206
+ let outputBuilder = csl.TransactionOutputBuilder.new().with_address(toAddress(address));
207
+ if (datum && datum.type === 'Hash') {
208
+ outputBuilder = outputBuilder.with_data_hash(csl.hash_plutus_data(this.castDataToPlutusData(datum.data)));
209
+ }
210
+ if (datum && datum.type === 'Inline') {
211
+ outputBuilder = outputBuilder.with_plutus_data(this.castDataToPlutusData(datum.data));
212
+ }
213
+ if (referenceScript) {
214
+ outputBuilder = outputBuilder.with_script_ref(csl.ScriptRef.new_plutus_script(csl.PlutusScript.from_hex_with_version(referenceScript.code, LANGUAGE_VERSIONS[referenceScript.version])));
215
+ }
216
+ const amountBuilder = outputBuilder.next();
217
+ if (multiAsset) {
218
+ const output = txValue.coin().is_zero()
219
+ ? amountBuilder
220
+ .with_asset_and_min_required_coin_by_utxo_cost(multiAsset, buildDataCost(this.protocolParams.coinsPerUTxOSize))
221
+ .build()
222
+ : amountBuilder.with_coin_and_asset(txValue.coin(), multiAsset).build();
223
+ this.txBuilder.add_output(output);
224
+ }
225
+ else {
226
+ const output = amountBuilder.with_coin(txValue.coin()).build();
227
+ this.txBuilder.add_output(output);
228
+ }
229
+ };
230
+ addAllCollaterals = (collaterals) => {
231
+ const collateralBuilder = csl.TxInputsBuilder.new();
232
+ for (let i = 0; i < collaterals.length; i += 1) {
233
+ const currentCollateral = collaterals[i];
234
+ this.addCollateral(collateralBuilder, currentCollateral);
235
+ }
236
+ this.txBuilder.set_collateral(collateralBuilder);
237
+ };
238
+ addCollateral = (collateralBuilder, currentCollateral) => {
239
+ collateralBuilder.add_input(csl.Address.from_bech32(currentCollateral.txIn.address), csl.TransactionInput.new(csl.TransactionHash.from_hex(currentCollateral.txIn.txHash), currentCollateral.txIn.txIndex), toValue(currentCollateral.txIn.amount));
240
+ };
241
+ addCollateralReturn = (returnAddress) => {
242
+ const currentFee = this.txBuilder.get_fee_if_set()?.to_js_value();
243
+ if (currentFee) {
244
+ const collateralAmount = Math.ceil((this.protocolParams.collateralPercent * Number(currentFee)) / 100);
245
+ this.txBuilder.set_total_collateral_and_return(csl.BigNum.from_str(String(collateralAmount)), csl.Address.from_bech32(returnAddress));
246
+ }
247
+ };
248
+ addAllReferenceInputs = (refInputs) => {
249
+ refInputs.forEach((refInput) => {
250
+ this.addReferenceInput(refInput);
251
+ });
252
+ };
253
+ addReferenceInput = ({ txHash, txIndex }) => {
254
+ const refInput = csl.TransactionInput.new(csl.TransactionHash.from_hex(txHash), txIndex);
255
+ this.txBuilder.add_reference_input(refInput);
256
+ };
257
+ addAllMints = (mints) => {
258
+ const mintBuilder = csl.MintBuilder.new();
259
+ let plutusMintCount = 0;
260
+ for (let i = 0; i < mints.length; i += 1) {
261
+ const mintItem = mints[i];
262
+ if (!mintItem.scriptSource)
263
+ throw Error('Mint script is expected to be provided');
264
+ if (mintItem.type === 'Plutus') {
265
+ if (!mintItem.redeemer)
266
+ throw Error('Missing mint redeemer information');
267
+ this.addPlutusMint(mintBuilder, mintItem, plutusMintCount); // TODO: Update after csl update
268
+ plutusMintCount += 1; // TODO: Remove after csl update
269
+ }
270
+ else if (mintItem.type === 'Native') {
271
+ this.addNativeMint(mintBuilder, mintItem);
272
+ }
273
+ }
274
+ this.txBuilder.set_mint_builder(mintBuilder);
275
+ };
276
+ addPlutusMint = (mintBuilder, { redeemer, policyId, scriptSource, assetName, amount }, redeemerIndex) => {
277
+ const newRedeemer = csl.Redeemer.new(csl.RedeemerTag.new_mint(), csl.BigNum.from_str(String(redeemerIndex)), this.castDataToPlutusData(redeemer.data), csl.ExUnits.new(csl.BigNum.from_str(String(redeemer.exUnits.mem)), csl.BigNum.from_str(String(redeemer.exUnits.steps))));
278
+ const script = scriptSource.type === 'Reference Script'
279
+ ? csl.PlutusScriptSource.new_ref_input_with_lang_ver(csl.ScriptHash.from_hex(policyId), csl.TransactionInput.new(csl.TransactionHash.from_hex(scriptSource.txHash), scriptSource.txIndex), LANGUAGE_VERSIONS[scriptSource.version])
280
+ : csl.PlutusScriptSource.new(csl.PlutusScript.from_hex_with_version(scriptSource.script.code, LANGUAGE_VERSIONS[scriptSource.script.version]));
281
+ mintBuilder.add_asset(csl.MintWitness.new_plutus_script(script, newRedeemer), csl.AssetName.new(Buffer.from(assetName, 'hex')), csl.Int.from_str(amount));
282
+ };
283
+ addNativeMint = (mintBuilder, { scriptSource, assetName, amount }) => {
284
+ if (scriptSource.type === 'Reference Script')
285
+ throw Error('Native mint cannot have reference script');
286
+ mintBuilder.add_asset(csl.MintWitness.new_native_script(csl.NativeScript.from_hex(scriptSource.script.code)), csl.AssetName.new(Buffer.from(assetName, 'hex')), csl.Int.from_str(amount));
287
+ };
288
+ decimalToFraction(decimal) {
289
+ const powerOf10 = 10 ** decimal.toString().split('.')[1].length;
290
+ const numerator = decimal * powerOf10;
291
+ const denominator = powerOf10;
292
+ return [numerator, denominator];
293
+ }
294
+ toPoolParams = (poolParams) => {
295
+ const marginFraction = this.decimalToFraction(poolParams.margin);
296
+ const relays = csl.Relays.new();
297
+ poolParams.relays.forEach((relay) => {
298
+ relays.add(toRelay(relay));
299
+ });
300
+ const rewardAddress = csl.RewardAddress.from_address(csl.Address.from_bech32(poolParams.rewardAddress));
301
+ if (rewardAddress === undefined) {
302
+ throw new Error('Reward address is invalid');
303
+ }
304
+ const poolOwners = csl.Ed25519KeyHashes.new();
305
+ poolParams.owners.forEach((owner) => {
306
+ poolOwners.add(csl.Ed25519KeyHash.from_hex(owner));
307
+ });
308
+ return csl.PoolParams.new(csl.Ed25519KeyHash.from_hex(poolParams.operator), csl.VRFKeyHash.from_hex(poolParams.VRFKeyHash), csl.BigNum.from_str(poolParams.pledge), csl.BigNum.from_str(poolParams.cost), csl.UnitInterval.new(csl.BigNum.from_str(marginFraction[0].toString()), csl.BigNum.from_str(marginFraction[1].toString())), rewardAddress, poolOwners, relays, poolParams.metadata
309
+ ? csl.PoolMetadata.from_json(JSONbig.stringify(poolParams.metadata))
310
+ : undefined);
311
+ };
312
+ addCertificate = (certificates, cert) => {
313
+ switch (cert.type) {
314
+ case 'RegisterPool':
315
+ certificates.add(csl.Certificate.new_pool_registration(csl.PoolRegistration.new(this.toPoolParams(cert.poolParams))));
316
+ break;
317
+ case 'RegisterStake':
318
+ certificates.add(csl.Certificate.new_stake_registration(csl.StakeRegistration.new(csl.StakeCredential.from_keyhash(csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)))));
319
+ break;
320
+ case 'DelegateStake':
321
+ certificates.add(csl.Certificate.new_stake_delegation(csl.StakeDelegation.new(csl.StakeCredential.from_keyhash(csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)), cert.poolId.startsWith('pool')
322
+ ? csl.Ed25519KeyHash.from_bech32(cert.poolId)
323
+ : csl.Ed25519KeyHash.from_hex(cert.poolId))));
324
+ break;
325
+ case 'DeregisterStake':
326
+ certificates.add(csl.Certificate.new_stake_deregistration(csl.StakeDeregistration.new(csl.StakeCredential.from_keyhash(csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)))));
327
+ break;
328
+ case 'RetirePool':
329
+ certificates.add(csl.Certificate.new_pool_retirement(csl.PoolRetirement.new(cert.poolId.startsWith('pool')
330
+ ? csl.Ed25519KeyHash.from_bech32(cert.poolId)
331
+ : csl.Ed25519KeyHash.from_hex(cert.poolId), cert.epoch)));
332
+ }
333
+ };
334
+ addAllCertificates = (allCertificates) => {
335
+ const certificates = csl.Certificates.new();
336
+ allCertificates.forEach((cert) => {
337
+ this.addCertificate(certificates, cert);
338
+ });
339
+ this.txBuilder.set_certs(certificates);
340
+ };
341
+ addCostModels = () => {
342
+ this.txBuilder.calc_script_data_hash(csl.TxBuilderConstants.plutus_vasil_cost_models());
343
+ };
344
+ addChange = (changeAddress) => {
345
+ this.txBuilder.add_change_if_needed(csl.Address.from_bech32(changeAddress));
346
+ };
347
+ addValidityRange = ({ invalidBefore, invalidHereafter }) => {
348
+ if (invalidBefore) {
349
+ this.txBuilder.set_validity_start_interval_bignum(csl.BigNum.from_str(invalidBefore.toString()));
350
+ }
351
+ if (invalidHereafter) {
352
+ this.txBuilder.set_ttl_bignum(csl.BigNum.from_str(invalidHereafter.toString()));
353
+ }
354
+ };
355
+ addAllRequiredSignatures = (requiredSignatures) => {
356
+ requiredSignatures.forEach((pubKeyHash) => {
357
+ this.txBuilder.add_required_signer(csl.Ed25519KeyHash.from_hex(pubKeyHash));
358
+ });
359
+ };
360
+ addAllMetadata = (allMetadata) => {
361
+ allMetadata.forEach(({ tag, metadata }) => {
362
+ this.txBuilder.add_json_metadatum(csl.BigNum.from_str(tag), JSONbig.stringify(metadata));
363
+ });
364
+ };
365
+ castRawDataToJsonString = (rawData) => {
366
+ if (typeof rawData === 'object') {
367
+ return JSONbig.stringify(rawData);
368
+ }
369
+ return rawData;
370
+ };
371
+ castDataToPlutusData = ({ type, content }) => {
372
+ if (type === 'Mesh') {
373
+ return toPlutusData(content);
374
+ }
375
+ if (type === 'CBOR') {
376
+ return csl.PlutusData.from_hex(content);
377
+ }
378
+ return csl.PlutusData.from_json(content, csl.PlutusDatumSchema.DetailedSchema);
379
+ };
380
+ }
@@ -0,0 +1 @@
1
+ export * from './builder';
@@ -0,0 +1 @@
1
+ export * from './builder';
@@ -0,0 +1,18 @@
1
+ import { Action, Data, PlutusScript, Recipient, UTxO } from '@meshsdk/core';
2
+ import { csl } from './csl';
3
+ import type { BaseAddress, Bip32PrivateKey, DataCost, DatumSource, Ed25519KeyHash, EnterpriseAddress, MintWitness, PlutusScriptSource, RewardAddress, TransactionBuilder, TransactionOutputBuilder, TxInputsBuilder } from './types';
4
+ export declare const buildBaseAddress: (networkId: number, paymentKeyHash: Ed25519KeyHash, stakeKeyHash: Ed25519KeyHash) => BaseAddress;
5
+ export declare const buildBip32PrivateKey: (entropy: string, password?: string) => Bip32PrivateKey;
6
+ export declare const buildDataCost: (coinsPerByte: string) => DataCost;
7
+ export declare const buildDatumSource: (datum: Data | UTxO) => DatumSource;
8
+ export declare const buildEnterpriseAddress: (networkId: number, paymentKeyHash: Ed25519KeyHash) => EnterpriseAddress;
9
+ export declare const buildGeneralTxMetadata: (metadata: Record<string, unknown>) => csl.GeneralTransactionMetadata;
10
+ export declare const buildMintWitness: (script: string | PlutusScript | UTxO, redeemer?: Partial<Action>) => MintWitness;
11
+ export declare const buildRewardAddress: (networkId: number, stakeKeyHash: Ed25519KeyHash) => RewardAddress;
12
+ export declare const buildPlutusScriptSource: (script: PlutusScript | UTxO) => PlutusScriptSource;
13
+ export declare const buildScriptPubkey: (keyHash: Ed25519KeyHash) => csl.NativeScript;
14
+ export declare const buildTimelockExpiry: (slot: string) => csl.NativeScript;
15
+ export declare const buildTimelockStart: (slot: string) => csl.NativeScript;
16
+ export declare const buildTxBuilder: (parameters?: import("@meshsdk/core").Protocol) => TransactionBuilder;
17
+ export declare const buildTxInputsBuilder: (utxos: unknown[]) => TxInputsBuilder;
18
+ export declare const buildTxOutputBuilder: (recipient: Recipient) => TransactionOutputBuilder;
@@ -0,0 +1,118 @@
1
+ import { DEFAULT_PROTOCOL_PARAMETERS, DEFAULT_REDEEMER_BUDGET } from '@meshsdk/common';
2
+ import { LANGUAGE_VERSIONS } from './constants';
3
+ import { csl } from './csl';
4
+ import { fromScriptRef, fromUTF8, toAddress, toBytes, toPlutusData, toRedeemer, toScriptRef, toTxUnspentOutput, toUnitInterval, } from './converter';
5
+ import { deserializeNativeScript, deserializePlutusScript } from './deserializer';
6
+ export const buildBaseAddress = (networkId, paymentKeyHash, stakeKeyHash) => csl.BaseAddress.new(networkId, csl.StakeCredential.from_keyhash(paymentKeyHash), csl.StakeCredential.from_keyhash(stakeKeyHash));
7
+ export const buildBip32PrivateKey = (entropy, password = '') => csl.Bip32PrivateKey.from_bip39_entropy(toBytes(entropy), toBytes(fromUTF8(password)));
8
+ export const buildDataCost = (coinsPerByte) => csl.DataCost.new_coins_per_byte(csl.BigNum.from_str(coinsPerByte));
9
+ export const buildDatumSource = (datum) => {
10
+ if (typeof datum !== 'object' || !('input' in datum)) {
11
+ return csl.DatumSource.new(toPlutusData(datum));
12
+ }
13
+ const utxo = toTxUnspentOutput(datum);
14
+ if (utxo.output().has_plutus_data()) {
15
+ return csl.DatumSource.new_ref_input(utxo.input());
16
+ }
17
+ throw new Error(`No inline datum found in UTxO: ${utxo.input().transaction_id().to_hex()}`);
18
+ };
19
+ export const buildEnterpriseAddress = (networkId, paymentKeyHash) => csl.EnterpriseAddress.new(networkId, csl.StakeCredential.from_keyhash(paymentKeyHash));
20
+ export const buildGeneralTxMetadata = (metadata) => {
21
+ const generalTxMetadata = csl.GeneralTransactionMetadata.new();
22
+ Object.entries(metadata).forEach(([MetadataLabel, Metadata]) => {
23
+ generalTxMetadata.insert(csl.BigNum.from_str(MetadataLabel), csl.encode_json_str_to_metadatum(JSON.stringify(Metadata), csl.MetadataJsonSchema.NoConversions));
24
+ });
25
+ return generalTxMetadata;
26
+ };
27
+ export const buildMintWitness = (script, redeemer) => {
28
+ if (typeof script === 'string') {
29
+ return csl.MintWitness.new_native_script(deserializeNativeScript(script));
30
+ }
31
+ if (redeemer === undefined)
32
+ throw new Error('Minting with plutus requires a redeemer to be defined');
33
+ if (redeemer.tag !== 'MINT')
34
+ throw new Error("Minting redeemer's tag must be defined as 'MINT'");
35
+ return csl.MintWitness.new_plutus_script(buildPlutusScriptSource(script), toRedeemer({
36
+ tag: 'MINT',
37
+ index: 0,
38
+ budget: DEFAULT_REDEEMER_BUDGET,
39
+ data: {
40
+ alternative: 0,
41
+ fields: [],
42
+ },
43
+ ...redeemer,
44
+ }));
45
+ };
46
+ export const buildRewardAddress = (networkId, stakeKeyHash) => csl.RewardAddress.new(networkId, csl.StakeCredential.from_keyhash(stakeKeyHash));
47
+ export const buildPlutusScriptSource = (script) => {
48
+ if ('code' in script) {
49
+ return csl.PlutusScriptSource.new(deserializePlutusScript(script.code, script.version));
50
+ }
51
+ const utxo = toTxUnspentOutput(script);
52
+ if (utxo.output().has_script_ref()) {
53
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
54
+ const scriptRef = utxo.output().script_ref();
55
+ if (scriptRef.is_plutus_script()) {
56
+ const plutusScript = fromScriptRef(scriptRef);
57
+ const scriptHash = deserializePlutusScript(plutusScript.code, plutusScript.version).hash();
58
+ return csl.PlutusScriptSource.new_ref_input_with_lang_ver(scriptHash, utxo.input(), LANGUAGE_VERSIONS[plutusScript.version]);
59
+ }
60
+ }
61
+ throw new Error(`No plutus script reference found in UTxO: ${utxo.input().transaction_id().to_hex()}`);
62
+ };
63
+ export const buildScriptPubkey = (keyHash) => {
64
+ const scriptPubkey = csl.ScriptPubkey.new(keyHash);
65
+ return csl.NativeScript.new_script_pubkey(scriptPubkey);
66
+ };
67
+ export const buildTimelockExpiry = (slot) => {
68
+ const expiry = csl.BigNum.from_str(slot);
69
+ const timelockExpiry = csl.TimelockExpiry.new_timelockexpiry(expiry);
70
+ return csl.NativeScript.new_timelock_expiry(timelockExpiry);
71
+ };
72
+ export const buildTimelockStart = (slot) => {
73
+ const start = csl.BigNum.from_str(slot);
74
+ const timelockStart = csl.TimelockStart.new_timelockstart(start);
75
+ return csl.NativeScript.new_timelock_start(timelockStart);
76
+ };
77
+ export const buildTxBuilder = (parameters = DEFAULT_PROTOCOL_PARAMETERS) => {
78
+ const txBuilderConfig = csl.TransactionBuilderConfigBuilder.new()
79
+ .coins_per_utxo_byte(csl.BigNum.from_str(parameters.coinsPerUTxOSize))
80
+ .ex_unit_prices(csl.ExUnitPrices.new(toUnitInterval(parameters.priceMem.toString()), toUnitInterval(parameters.priceStep.toString())))
81
+ .fee_algo(csl.LinearFee.new(csl.BigNum.from_str(parameters.minFeeA.toString()), csl.BigNum.from_str(parameters.minFeeB.toString())))
82
+ .key_deposit(csl.BigNum.from_str(parameters.keyDeposit))
83
+ .max_tx_size(parameters.maxTxSize)
84
+ .max_value_size(parseInt(parameters.maxValSize, 10))
85
+ .pool_deposit(csl.BigNum.from_str(parameters.poolDeposit))
86
+ .build();
87
+ return csl.TransactionBuilder.new(txBuilderConfig);
88
+ };
89
+ export const buildTxInputsBuilder = (utxos) => {
90
+ const txInputsBuilder = csl.TxInputsBuilder.new();
91
+ utxos
92
+ .map((utxo) => utxo instanceof csl.TransactionUnspentOutput
93
+ ? utxo
94
+ : toTxUnspentOutput(utxo))
95
+ .forEach((utxo) => {
96
+ txInputsBuilder.add_input(utxo.output().address(), utxo.input(), utxo.output().amount());
97
+ });
98
+ return txInputsBuilder;
99
+ };
100
+ export const buildTxOutputBuilder = (recipient) => {
101
+ if (typeof recipient === 'string') {
102
+ return csl.TransactionOutputBuilder.new().with_address(toAddress(recipient));
103
+ }
104
+ let txOutputBuilder = csl.TransactionOutputBuilder.new().with_address(toAddress(recipient.address));
105
+ if (recipient.datum) {
106
+ const { value, inline } = recipient.datum;
107
+ const plutusData = toPlutusData(value);
108
+ txOutputBuilder = txOutputBuilder.with_data_hash(csl.hash_plutus_data(plutusData));
109
+ if (inline) {
110
+ txOutputBuilder = txOutputBuilder.with_plutus_data(plutusData);
111
+ }
112
+ }
113
+ if (recipient.script) {
114
+ const reference = toScriptRef(recipient.script);
115
+ txOutputBuilder = txOutputBuilder.with_script_ref(reference);
116
+ }
117
+ return txOutputBuilder;
118
+ };
@@ -0,0 +1,12 @@
1
+ import { csl } from './csl';
2
+ export declare const LANGUAGE_VERSIONS: {
3
+ V1: csl.Language;
4
+ V2: csl.Language;
5
+ };
6
+ export declare const REDEEMER_TAGS: {
7
+ CERT: csl.RedeemerTag;
8
+ MINT: csl.RedeemerTag;
9
+ REWARD: csl.RedeemerTag;
10
+ SPEND: csl.RedeemerTag;
11
+ };
12
+ export declare const POLICY_ID_LENGTH = 56;
@@ -0,0 +1,12 @@
1
+ import { csl } from './csl';
2
+ export const LANGUAGE_VERSIONS = {
3
+ V1: csl.Language.new_plutus_v1(),
4
+ V2: csl.Language.new_plutus_v2(),
5
+ };
6
+ export const REDEEMER_TAGS = {
7
+ CERT: csl.RedeemerTag.new_cert(),
8
+ MINT: csl.RedeemerTag.new_mint(),
9
+ REWARD: csl.RedeemerTag.new_reward(),
10
+ SPEND: csl.RedeemerTag.new_spend(),
11
+ };
12
+ export const POLICY_ID_LENGTH = 56;
@@ -0,0 +1,27 @@
1
+ import type { Action, Asset, Data, NativeScript, PlutusScript, PoolParams, Relay, UTxO } from '@meshsdk/core';
2
+ import { csl } from './csl';
3
+ import { Value, PlutusData, ScriptRef, TransactionUnspentOutput } from './types';
4
+ export declare const toAddress: (bech32: string) => csl.Address;
5
+ export declare const toBaseAddress: (bech32: string) => csl.BaseAddress | undefined;
6
+ export declare const toEnterpriseAddress: (bech32: string) => csl.EnterpriseAddress | undefined;
7
+ export declare const toRewardAddress: (bech32: string) => csl.RewardAddress | undefined;
8
+ export declare const fromBytes: (bytes: Uint8Array) => string;
9
+ export declare const toBytes: (hex: string) => Uint8Array;
10
+ export declare const fromLovelace: (lovelace: number) => number;
11
+ export declare const toLovelace: (ada: number) => number;
12
+ export declare const fromNativeScript: (script: csl.NativeScript) => NativeScript;
13
+ export declare const toNativeScript: (script: NativeScript) => csl.NativeScript;
14
+ export declare const fromPlutusData: (plutusData: PlutusData) => Data;
15
+ export declare const toPlutusData: (data: Data) => csl.PlutusData;
16
+ export declare const toPoolParams: (params: PoolParams) => never;
17
+ export declare const toRedeemer: (action: Action) => csl.Redeemer;
18
+ export declare const toRelay: (relay: Relay) => csl.Relay;
19
+ export declare const fromScriptRef: (scriptRef: ScriptRef) => NativeScript | PlutusScript;
20
+ export declare const toScriptRef: (script: PlutusScript | NativeScript) => csl.ScriptRef;
21
+ export declare const fromTxUnspentOutput: (txUnspentOutput: TransactionUnspentOutput) => UTxO;
22
+ export declare const toTxUnspentOutput: (utxo: UTxO) => csl.TransactionUnspentOutput;
23
+ export declare const toUnitInterval: (float: string) => csl.UnitInterval;
24
+ export declare const fromUTF8: (utf8: string) => string;
25
+ export declare const toUTF8: (hex: string) => string;
26
+ export declare const fromValue: (value: Value) => Asset[];
27
+ export declare const toValue: (assets: Asset[]) => csl.Value;