@odatano/core 0.3.16 → 0.3.18

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 (94) hide show
  1. package/@cds-models/CardanoODataService/index.d.ts +434 -427
  2. package/@cds-models/CardanoODataService/index.d.ts.map +1 -1
  3. package/@cds-models/CardanoODataService/index.js +7 -0
  4. package/@cds-models/CardanoODataService/index.js.map +1 -1
  5. package/@cds-models/CardanoODataService/index.ts +99 -92
  6. package/@cds-models/CardanoSignService/index.d.ts +1549 -0
  7. package/@cds-models/CardanoSignService/index.d.ts.map +1 -0
  8. package/@cds-models/CardanoSignService/index.js +291 -0
  9. package/@cds-models/CardanoSignService/index.js.map +1 -0
  10. package/@cds-models/CardanoSignService/index.ts +519 -0
  11. package/@cds-models/CardanoTransactionService/index.d.ts +338 -815
  12. package/@cds-models/CardanoTransactionService/index.d.ts.map +1 -1
  13. package/@cds-models/CardanoTransactionService/index.js +3 -63
  14. package/@cds-models/CardanoTransactionService/index.js.map +1 -1
  15. package/@cds-models/CardanoTransactionService/index.ts +71 -210
  16. package/@cds-models/index.d.ts +150 -1
  17. package/@cds-models/index.d.ts.map +1 -1
  18. package/@cds-models/index.js +51 -1
  19. package/@cds-models/index.js.map +1 -1
  20. package/@cds-models/index.ts +74 -2
  21. package/@cds-models/odatano/cardano/index.d.ts +553 -696
  22. package/@cds-models/odatano/cardano/index.d.ts.map +1 -1
  23. package/@cds-models/odatano/cardano/index.js +3 -52
  24. package/@cds-models/odatano/cardano/index.js.map +1 -1
  25. package/@cds-models/odatano/cardano/index.ts +93 -165
  26. package/README.md +78 -19
  27. package/db/schema.cds +6 -108
  28. package/db/types.cds +111 -0
  29. package/package.json +22 -6
  30. package/src/index.d.ts.map +1 -1
  31. package/src/index.js +8 -3
  32. package/src/index.js.map +1 -1
  33. package/src/plugin.d.ts.map +1 -1
  34. package/src/plugin.js +7 -2
  35. package/src/plugin.js.map +1 -1
  36. package/srv/blockchain/backends/koios-backend.d.ts.map +1 -1
  37. package/srv/blockchain/backends/koios-backend.js +6 -16
  38. package/srv/blockchain/backends/koios-backend.js.map +1 -1
  39. package/srv/blockchain/cardano-client.d.ts.map +1 -1
  40. package/srv/blockchain/cardano-client.js +13 -10
  41. package/srv/blockchain/cardano-client.js.map +1 -1
  42. package/srv/blockchain/cardano-indexer.d.ts.map +1 -1
  43. package/srv/blockchain/cardano-indexer.js +10 -8
  44. package/srv/blockchain/cardano-indexer.js.map +1 -1
  45. package/srv/blockchain/cardano-tx-builder.d.ts.map +1 -1
  46. package/srv/blockchain/cardano-tx-builder.js +16 -16
  47. package/srv/blockchain/cardano-tx-builder.js.map +1 -1
  48. package/srv/blockchain/signing/hsm-signer.d.ts.map +1 -0
  49. package/srv/blockchain/signing/hsm-signer.js +290 -0
  50. package/srv/blockchain/signing/hsm-signer.js.map +1 -0
  51. package/srv/blockchain/signing/signature-verifier.d.ts.map +1 -1
  52. package/srv/blockchain/signing/signature-verifier.js +7 -25
  53. package/srv/blockchain/signing/signature-verifier.js.map +1 -1
  54. package/srv/blockchain/transaction-building/buildooor-tx.d.ts.map +1 -1
  55. package/srv/blockchain/transaction-building/buildooor-tx.js +171 -437
  56. package/srv/blockchain/transaction-building/buildooor-tx.js.map +1 -1
  57. package/srv/blockchain/transaction-building/cardano-tx.d.ts.map +1 -1
  58. package/srv/blockchain/transaction-building/csl-tx.d.ts.map +1 -1
  59. package/srv/blockchain/transaction-building/csl-tx.js +230 -611
  60. package/srv/blockchain/transaction-building/csl-tx.js.map +1 -1
  61. package/srv/cardano-service.cds +17 -9
  62. package/srv/cardano-service.js +2 -14
  63. package/srv/cardano-service.js.map +1 -1
  64. package/srv/cardano-sign-service.cds +128 -0
  65. package/srv/cardano-sign-service.d.ts.map +1 -0
  66. package/srv/cardano-sign-service.js +401 -0
  67. package/srv/cardano-sign-service.js.map +1 -0
  68. package/srv/cardano-tx-service.cds +116 -196
  69. package/srv/cardano-tx-service.js +5 -308
  70. package/srv/cardano-tx-service.js.map +1 -1
  71. package/srv/server.d.ts.map +1 -1
  72. package/srv/server.js +60 -5
  73. package/srv/server.js.map +1 -1
  74. package/srv/utils/const.d.ts.map +1 -1
  75. package/srv/utils/const.js +5 -1
  76. package/srv/utils/const.js.map +1 -1
  77. package/srv/utils/error-codes.d.ts.map +1 -1
  78. package/srv/utils/error-codes.js +15 -0
  79. package/srv/utils/error-codes.js.map +1 -1
  80. package/srv/utils/errors.d.ts.map +1 -1
  81. package/srv/utils/errors.js +12 -1
  82. package/srv/utils/errors.js.map +1 -1
  83. package/srv/utils/mappers.d.ts.map +1 -1
  84. package/srv/utils/mappers.js +9 -29
  85. package/srv/utils/mappers.js.map +1 -1
  86. package/srv/utils/signing-helper.d.ts.map +1 -1
  87. package/srv/utils/signing-helper.js +43 -25
  88. package/srv/utils/signing-helper.js.map +1 -1
  89. package/srv/utils/tx-build-helper.d.ts.map +1 -1
  90. package/srv/utils/tx-build-helper.js +10 -4
  91. package/srv/utils/tx-build-helper.js.map +1 -1
  92. package/srv/utils/types.d.ts.map +1 -1
  93. package/srv/utils/types.js +2 -0
  94. package/srv/utils/types.js.map +1 -1
@@ -31,207 +31,51 @@ class BuildooorTxBuilder {
31
31
  const params = protocolParams ?? await client.getProtocolParameters();
32
32
  const txbParameters = this._mapLedgerParametersToBuildooorParams(params);
33
33
  this.txBuilder = new buildooor_1.TxBuilder(txbParameters);
34
- logger.debug(`TxBuilder initialized with protocol parameters`);
34
+ logger.debug(`Initialized with protocol parameters`);
35
35
  }
36
36
  /**
37
- * Build unsigned ADA transfer transaction
38
- * @param req transaction build request
39
- * @param ctx transaction build context
40
- * @returns {Promise<TxBuildResult>} transaction build result
37
+ * Build unsigned transfer transaction (ADA-only or with native assets)
41
38
  */
42
- async buildUnsignedAdaTransfer(req, ctx) {
39
+ async buildUnsignedTransfer(req, ctx) {
43
40
  try {
44
- // mapping of ODATANO UTxO Type to ledger-ts UTxO objects (with multi-asset support)
45
- // This allows spending UTxOs that contain native assets - they will be returned in the change output
46
41
  const ledgerUtxos = ctx.utxos.map(utxo => this._mapMultiAssetUtxoToLedgerUtxo(utxo));
47
- // and map to Buildooor TxIn objects for inputs
48
42
  const inputs = ledgerUtxos.map(utxo => ({ utxo }));
49
- // set Addresses
50
43
  const recipientAddress = cardano_ledger_ts_1.Address.fromString(req.recipientAddress);
51
44
  const changeAddress = cardano_ledger_ts_1.Address.fromString(req.changeAddress ?? req.senderAddress);
52
- // set Amount
53
45
  const amount = BigInt(String(req.lovelaceAmount));
54
- // build new outputs for recipient (lovelace + optional native assets)
46
+ // Build output value (lovelace + optional native assets)
55
47
  let outputValue = cardano_ledger_ts_1.Value.lovelaces(amount);
56
48
  if (req.assets && req.assets.length > 0) {
57
- for (const asset of req.assets) {
58
- if (asset.unit === 'lovelace')
59
- continue;
60
- const { policyId, assetName } = (0, tx_build_helper_1.parseAssetUnit)(asset.unit);
61
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(new cardano_ledger_ts_1.Hash28(policyId), Buffer.from(assetName, 'hex'), BigInt(asset.quantity));
62
- outputValue = cardano_ledger_ts_1.Value.add(outputValue, assetValue);
63
- }
64
- }
65
- const txOutParams = {
66
- address: recipientAddress,
67
- value: outputValue,
68
- };
69
- if (req.outputDatum) {
70
- txOutParams.datum = (0, tx_build_helper_1.jsonToPlutusData)(req.outputDatum);
49
+ outputValue = this._buildLedgerValue(amount, req.assets);
71
50
  }
72
- const outputs = [new cardano_ledger_ts_1.TxOut(txOutParams)];
73
- // build the transaction
74
- const tx = await this.txBuilder.build({
75
- inputs,
76
- outputs,
77
- changeAddress,
78
- });
79
- // full unsigned tx cbor (4-tuple, witness empty)
80
- const unsignedTxBytes = tx.toCbor().toBuffer();
81
- const unsignedTxCbor = (0, uint8array_utils_1.toHex)(unsignedTxBytes);
82
- const txBodyHash = tx.hash.toString();
51
+ const outputs = [this._buildTxOut(recipientAddress, outputValue, req.outputDatum)];
52
+ const tx = await this.txBuilder.build({ inputs, outputs, changeAddress });
83
53
  logger.debug(`Built unsigned transaction successfully.`);
84
- return {
85
- unsignedTxCbor: unsignedTxCbor,
86
- txBodyHash: txBodyHash,
87
- senderAddress: req.senderAddress,
88
- network: this.cardanoClient.network,
89
- sizeBytes: unsignedTxBytes.length,
90
- builderEngine: this.name,
91
- feeLovelace: tx.body.fee.toString(),
92
- inputs: ctx.utxos.map(u => ({
93
- txHash: u.txHash,
94
- index: u.outputIndex,
95
- lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
96
- })),
97
- outputs: tx.body.outputs.map((o) => ({
98
- address: o.address?.toString?.() ?? "",
99
- lovelace: o.value?.lovelaces?.toString?.() ?? "0"
100
- })),
101
- warnings: []
102
- };
54
+ return this._buildResult(req, ctx, this._extractTxDetails(tx));
103
55
  }
104
56
  catch (err) {
105
- (0, tx_build_helper_1.mapBuilderError)(err, 'lovelace');
57
+ (0, tx_build_helper_1.mapBuilderError)(err);
106
58
  }
107
59
  }
108
60
  async buildUnsignedTransactionWithMetadata(req, ctx) {
109
61
  try {
110
- // mapping of ODATANO UTxO Type to ledger-ts UTxO objects (with multi-asset support)
111
- // This allows spending UTxOs that contain native assets - they will be returned in the change output
112
62
  const ledgerUtxos = ctx.utxos.map(utxo => this._mapMultiAssetUtxoToLedgerUtxo(utxo));
113
- // Buildooor TxIn objects for inputs
114
63
  const inputs = ledgerUtxos.map(utxo => ({ utxo }));
115
- // Addresses
116
64
  const recipientAddress = cardano_ledger_ts_1.Address.fromString(req.recipientAddress);
117
65
  const changeAddress = cardano_ledger_ts_1.Address.fromString(req.changeAddress ?? req.senderAddress);
118
- // Amount
119
66
  const amount = BigInt(String(req.lovelaceAmount));
120
67
  const metadata = this._mapOdatanoMetadataToLedgerMetadata(req.metadataJson);
121
- // build new outputs for recipient
122
- const outputs = [
123
- new cardano_ledger_ts_1.TxOut({
124
- address: recipientAddress,
125
- value: cardano_ledger_ts_1.Value.lovelaces(amount)
126
- })
127
- ];
128
- // build the transaction
129
- const tx = await this.txBuilder.build({
130
- inputs,
131
- outputs,
132
- changeAddress,
133
- metadata
134
- });
135
- // full unsigned tx cbor (4-tuple, witness empty)
136
- const unsignedTxBytes = tx.toCbor().toBuffer();
137
- const unsignedTxCbor = (0, uint8array_utils_1.toHex)(unsignedTxBytes);
138
- const txBodyHash = tx.hash.toString();
68
+ const outputs = [new cardano_ledger_ts_1.TxOut({ address: recipientAddress, value: cardano_ledger_ts_1.Value.lovelaces(amount) })];
69
+ const tx = await this.txBuilder.build({ inputs, outputs, changeAddress, metadata });
139
70
  logger.debug(`Built unsigned transaction successfully.`);
140
- return {
141
- unsignedTxCbor: unsignedTxCbor,
142
- txBodyHash: txBodyHash,
143
- senderAddress: req.senderAddress,
144
- network: this.cardanoClient.network,
145
- builderEngine: this.name,
146
- sizeBytes: unsignedTxBytes.length,
147
- feeLovelace: tx.body.fee.toString(),
148
- inputs: ctx.utxos.map(u => ({
149
- txHash: u.txHash,
150
- index: u.outputIndex,
151
- lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
152
- })),
153
- outputs: tx.body.outputs.map((o) => ({
154
- address: o.address?.toString?.() ?? "",
155
- lovelace: o.value?.lovelaces?.toString?.() ?? "0"
156
- })),
157
- warnings: []
158
- };
71
+ return this._buildResult(req, ctx, this._extractTxDetails(tx));
159
72
  }
160
73
  catch (err) {
161
- (0, tx_build_helper_1.mapBuilderError)(err, 'lovelace');
162
- }
163
- }
164
- async buildUnsignedMultiAssetTransaction(req, ctx) {
165
- if (!req.assets || req.assets.length === 0) {
166
- throw new Error('[BuildooorTxBuilder] buildUnsignedMultiAssetTransaction requires assets to be specified');
167
- }
168
- try {
169
- // Map all available UTxOs to ledger UTxOs for Buildooor (let builder handle selection)
170
- const ledgerUtxos = ctx.utxos.map(utxo => this._mapMultiAssetUtxoToLedgerUtxo(utxo));
171
- // Buildooor TxIn objects for inputs
172
- const inputs = ledgerUtxos.map(utxo => ({ utxo }));
173
- // Addresses
174
- const recipientAddress = cardano_ledger_ts_1.Address.fromString(req.recipientAddress);
175
- const changeAddress = cardano_ledger_ts_1.Address.fromString(req.changeAddress ?? req.senderAddress);
176
- // Build output value with ADA + assets
177
- let outputValue = cardano_ledger_ts_1.Value.lovelaces(BigInt(req.lovelaceAmount));
178
- for (const asset of req.assets) {
179
- // Parse policyId and assetName from unit (format: policyId.assetName or policyId+assetName)
180
- const { policyId, assetName } = (0, tx_build_helper_1.parseAssetUnit)(asset.unit);
181
- const policyHash = new cardano_ledger_ts_1.Hash28(policyId);
182
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(policyHash, Buffer.from(assetName, 'hex'), BigInt(asset.quantity));
183
- outputValue = cardano_ledger_ts_1.Value.add(outputValue, assetValue);
184
- }
185
- // Build output (with optional inline datum for script addresses)
186
- const txOutParams = {
187
- address: recipientAddress,
188
- value: outputValue,
189
- };
190
- if (req.outputDatum) {
191
- txOutParams.datum = (0, tx_build_helper_1.jsonToPlutusData)(req.outputDatum);
192
- }
193
- const outputs = [new cardano_ledger_ts_1.TxOut(txOutParams)];
194
- // Build the transaction
195
- const tx = await this.txBuilder.build({
196
- inputs,
197
- outputs,
198
- changeAddress,
199
- });
200
- // Full unsigned tx cbor (4-tuple, witness empty)
201
- const unsignedTxBytes = tx.toCbor().toBuffer();
202
- const unsignedTxCbor = (0, uint8array_utils_1.toHex)(unsignedTxBytes);
203
- const txBodyHash = tx.hash.toString();
204
- logger.debug(`Built unsigned multi-asset transaction successfully.`);
205
- return {
206
- unsignedTxCbor: unsignedTxCbor,
207
- txBodyHash: txBodyHash,
208
- senderAddress: req.senderAddress,
209
- network: this.cardanoClient.network,
210
- sizeBytes: unsignedTxBytes.length,
211
- builderEngine: this.name,
212
- feeLovelace: tx.body.fee.toString(),
213
- inputs: ctx.utxos.map(u => ({
214
- txHash: u.txHash,
215
- index: u.outputIndex,
216
- lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
217
- })),
218
- outputs: tx.body.outputs.map((o) => ({
219
- address: o.address?.toString?.() ?? "",
220
- lovelace: o.value?.lovelaces?.toString?.() ?? "0"
221
- })),
222
- warnings: []
223
- };
224
- }
225
- catch (err) {
226
- // Extract asset unit from error message if possible
227
- const assetMatch = err?.message?.match(/not enough\s+([a-f0-9.]+)/i);
228
- const assetUnit = assetMatch?.[1];
229
- (0, tx_build_helper_1.mapBuilderError)(err, assetUnit);
74
+ (0, tx_build_helper_1.mapBuilderError)(err);
230
75
  }
231
76
  }
232
77
  async buildUnsignedMintTransaction(req, ctx) {
233
78
  try {
234
- // Addresses
235
79
  const recipientAddress = cardano_ledger_ts_1.Address.fromString(req.recipientAddress);
236
80
  const changeAddress = cardano_ledger_ts_1.Address.fromString(req.changeAddress ?? req.senderAddress);
237
81
  // Parse the minting policy script once
@@ -242,9 +86,8 @@ class BuildooorTxBuilder {
242
86
  const mints = [];
243
87
  for (const mintAction of req.mintActions) {
244
88
  const { assetName } = (0, tx_build_helper_1.parseAssetUnit)(mintAction.assetUnit);
245
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(script.hash, Buffer.from(assetName, 'hex'), BigInt(mintAction.quantity));
246
89
  mints.push({
247
- value: assetValue,
90
+ value: cardano_ledger_ts_1.Value.singleAsset(script.hash, Buffer.from(assetName, 'hex'), BigInt(mintAction.quantity)),
248
91
  script: {
249
92
  inline: script,
250
93
  redeemer: req.mintRedeemer
@@ -262,126 +105,36 @@ class BuildooorTxBuilder {
262
105
  const quantity = BigInt(mintAction.quantity);
263
106
  if (quantity > 0n) {
264
107
  const { assetName } = (0, tx_build_helper_1.parseAssetUnit)(mintAction.assetUnit);
265
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(script.hash, Buffer.from(assetName, 'hex'), quantity);
266
- mintValue = cardano_ledger_ts_1.Value.add(mintValue, assetValue);
108
+ mintValue = cardano_ledger_ts_1.Value.add(mintValue, cardano_ledger_ts_1.Value.singleAsset(script.hash, Buffer.from(assetName, 'hex'), quantity));
267
109
  }
268
110
  }
269
- // Build output value - recipient gets the minted assets + min ADA
270
- let outputValue = cardano_ledger_ts_1.Value.lovelaces(BigInt(req.lovelaceAmount || 1_000_000));
111
+ // Build output recipient gets the minted assets + min ADA
112
+ let outputValue = cardano_ledger_ts_1.Value.lovelaces(BigInt(req.lovelaceAmount));
271
113
  outputValue = cardano_ledger_ts_1.Value.add(outputValue, mintValue);
272
- // Build output
273
- const txOutParams = {
274
- address: recipientAddress,
275
- value: outputValue,
276
- };
277
- if (req.inlineDatum) {
278
- txOutParams.datum = (0, tx_build_helper_1.jsonToPlutusData)(req.inlineDatum);
279
- }
280
- const outputs = [new cardano_ledger_ts_1.TxOut(txOutParams)];
281
- // Find an ADA-only UTxO for collateral (Plutus scripts require ADA-only collateral)
282
- const adaOnlyUtxo = ctx.utxos.find(u => u.amount.every(a => a.unit.toLowerCase() === 'lovelace'));
283
- if (!adaOnlyUtxo) {
284
- throw new Error('[BuildooorTxBuilder] No ADA-only UTxO available for collateral. Plutus scripts require ADA-only collateral.');
285
- }
286
- // Use only 1 collateral to minimize tx size
287
- const collateralUtxos = [this._mapOdatanoUtxoToLedgerUtxo(adaOnlyUtxo)];
288
- // Exclude collateral UTxO from regular inputs so it is not consumed on successful tx.
289
- // This preserves the dedicated collateral UTxO for future Plutus transactions.
290
- const fundingUtxos = ctx.utxos.filter(u => !(u.txHash === adaOnlyUtxo.txHash && u.outputIndex === adaOnlyUtxo.outputIndex));
114
+ const outputs = [this._buildTxOut(recipientAddress, outputValue, req.inlineDatum)];
115
+ // Collateral + funding separation
116
+ const { collateralUtxos, fundingUtxos } = this._setupCollateral(ctx.utxos);
291
117
  const fundingLedgerUtxos = fundingUtxos.map(utxo => this._mapMultiAssetUtxoToLedgerUtxo(utxo));
292
118
  const inputs = fundingLedgerUtxos.map(utxo => ({ utxo }));
293
- // Determine execution units based on evaluator availability
294
- let finalExUnits = const_1.DEFAULT_EXECUTION_UNITS;
295
- if (ctx.evaluateTransaction) {
296
- // Build first pass with high execution units for evaluation
297
- logger.debug(`Building evaluation pass with high execution units`);
298
- const evalMints = buildMints(const_1.HIGH_EXECUTION_UNITS);
119
+ // Evaluate execution units
120
+ const finalExUnits = await this._evaluateExUnits(async () => {
299
121
  const evalTx = await this.txBuilder.build({
300
- inputs,
301
- outputs,
302
- changeAddress,
303
- mints: evalMints,
304
- collaterals: collateralUtxos,
305
- requiredSigners: req.requiredSigners
122
+ inputs, outputs, changeAddress, mints: buildMints(const_1.HIGH_EXECUTION_UNITS),
123
+ collaterals: collateralUtxos, requiredSigners: req.requiredSigners
306
124
  });
307
- const evalTxCbor = (0, uint8array_utils_1.toHex)(evalTx.toCbor().toBuffer());
308
- try {
309
- // Evaluate to get exact execution units
310
- const evalResults = await ctx.evaluateTransaction(evalTxCbor);
311
- logger.debug(`Evaluation results: ${JSON.stringify(evalResults)}`);
312
- if (evalResults && evalResults.length > 0) {
313
- // Use the evaluated budget (take first result for single script)
314
- const budget = evalResults[0].budget;
315
- // Add safety margin to evaluated units
316
- finalExUnits = {
317
- mem: Math.ceil(budget.memory * const_1.EXECUTION_UNIT_BUFFER),
318
- cpu: Math.ceil(budget.cpu * const_1.EXECUTION_UNIT_BUFFER)
319
- };
320
- logger.info(`Using evaluated execution units: mem=${finalExUnits.mem}, cpu=${finalExUnits.cpu}`);
321
- }
322
- }
323
- catch (evalError) {
324
- logger.warn(`Evaluation failed, using default units: ${evalError.message}`);
325
- // Fall back to defaults on evaluation failure
326
- }
327
- }
328
- else {
329
- logger.debug(`No evaluator available, using default execution units`);
330
- }
331
- // Build with final execution units
125
+ return (0, uint8array_utils_1.toHex)(evalTx.toCbor().toBuffer());
126
+ }, ctx.evaluateTransaction);
127
+ // Build with final execution units + witness buffer
332
128
  const mints = buildMints(finalExUnits);
333
- // First build to calculate base fee
334
- const txFirstPass = await this.txBuilder.build({
335
- inputs,
336
- outputs,
337
- changeAddress,
338
- mints: mints,
339
- collaterals: collateralUtxos,
340
- requiredSigners: req.requiredSigners
341
- });
342
- // Add minimal buffer for witness set CBOR overhead (signing adds ~44 bytes)
343
- const calculatedFee = BigInt(txFirstPass.body.fee.toString());
344
- const witnessBuffer = BigInt(const_1.WITNESS_BUFFER_BYTES);
345
- const adjustedMinFee = calculatedFee + witnessBuffer;
346
- logger.debug(`First pass fee: ${calculatedFee}, rebuilding with witness buffer: ${adjustedMinFee}`);
347
- // Final build with adjusted minimum fee to account for witness overhead
348
- const tx = await this.txBuilder.build({
349
- inputs,
350
- outputs,
351
- changeAddress,
352
- mints: mints,
353
- collaterals: collateralUtxos,
354
- requiredSigners: req.requiredSigners,
355
- fee: adjustedMinFee
129
+ const tx = await this._buildWithWitnessBuffer({
130
+ inputs, outputs, changeAddress, mints,
131
+ collaterals: collateralUtxos, requiredSigners: req.requiredSigners
356
132
  });
357
- // Full unsigned tx cbor (4-tuple, witness empty)
358
- const unsignedTxBytes = tx.toCbor().toBuffer();
359
- const unsignedTxCbor = (0, uint8array_utils_1.toHex)(unsignedTxBytes);
360
- const txBodyHash = tx.hash.toString();
361
133
  logger.debug(`Built unsigned minting transaction successfully with fee: ${tx.body.fee.toString()}`);
362
- return {
363
- unsignedTxCbor: unsignedTxCbor,
364
- txBodyHash: txBodyHash,
365
- senderAddress: req.senderAddress,
366
- network: this.cardanoClient.network,
367
- builderEngine: this.name,
368
- sizeBytes: unsignedTxBytes.length,
369
- feeLovelace: tx.body.fee.toString(),
370
- inputs: ctx.utxos.map(u => ({
371
- txHash: u.txHash,
372
- index: u.outputIndex,
373
- lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
374
- })),
375
- outputs: tx.body.outputs.map((o) => ({
376
- address: o.address?.toString?.() ?? "",
377
- lovelace: o.value?.lovelaces?.toString?.() ?? "0"
378
- })),
379
- scriptHash: script.hash.toString(),
380
- warnings: []
381
- };
134
+ return this._buildResult(req, ctx, this._extractTxDetails(tx), { scriptHash: script.hash.toString() });
382
135
  }
383
136
  catch (err) {
384
- (0, tx_build_helper_1.mapBuilderError)(err, 'lovelace');
137
+ (0, tx_build_helper_1.mapBuilderError)(err);
385
138
  }
386
139
  }
387
140
  async buildUnsignedPlutusSpendTransaction(req, ctx) {
@@ -397,160 +150,173 @@ class BuildooorTxBuilder {
397
150
  ? (0, tx_build_helper_1.jsonToPlutusData)(plutusScriptExecution.datum)
398
151
  : "inline";
399
152
  // Find the specific script UTxO in the provided context UTxOs
400
- // The coordinator is responsible for including the script UTxO in ctx.utxos
401
153
  const scriptUtxoRef = plutusScriptExecution.scriptUtxo;
402
154
  const scriptOdatanoUtxo = ctx.utxos.find(u => u.txHash === scriptUtxoRef.txHash && u.outputIndex === scriptUtxoRef.outputIndex);
403
155
  if (!scriptOdatanoUtxo) {
404
- throw new Error(`[BuildooorTxBuilder] Script UTxO ${scriptUtxoRef.txHash}#${scriptUtxoRef.outputIndex} not found in provided UTxOs`);
156
+ throw new Error(`Script UTxO ${scriptUtxoRef.txHash}#${scriptUtxoRef.outputIndex} not found in provided UTxOs`);
405
157
  }
406
- // Map the script UTxO to ledger format
407
158
  const scriptLedgerUtxo = this._mapMultiAssetUtxoToLedgerUtxo(scriptOdatanoUtxo);
408
159
  // Map sender UTxOs (excluding the script UTxO) as regular inputs
409
160
  const senderUtxos = ctx.utxos.filter(u => !(u.txHash === scriptUtxoRef.txHash && u.outputIndex === scriptUtxoRef.outputIndex));
410
- // Addresses
411
161
  const recipientAddress = cardano_ledger_ts_1.Address.fromString(req.recipientAddress);
412
162
  const changeAddress = cardano_ledger_ts_1.Address.fromString(req.changeAddress ?? req.senderAddress);
413
163
  // Build output — include multi-assets from script UTxO in continuing output
164
+ const scriptNonAdaAssets = scriptOdatanoUtxo.amount.filter(a => a.unit.toLowerCase() !== 'lovelace' && BigInt(a.quantity) > 0n);
414
165
  let outputValue = cardano_ledger_ts_1.Value.lovelaces(BigInt(req.lovelaceAmount || 2_000_000));
415
- for (const amount of scriptOdatanoUtxo.amount) {
416
- if (amount.unit.toLowerCase() !== 'lovelace' && BigInt(amount.quantity) > 0n) {
417
- const { policyId, assetName } = (0, tx_build_helper_1.parseAssetUnit)(amount.unit);
418
- const policyHash = new cardano_ledger_ts_1.Hash28(policyId);
419
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(policyHash, Buffer.from(assetName, 'hex'), BigInt(amount.quantity));
420
- outputValue = cardano_ledger_ts_1.Value.add(outputValue, assetValue);
421
- }
166
+ if (scriptNonAdaAssets.length > 0) {
167
+ outputValue = this._buildLedgerValue(BigInt(req.lovelaceAmount || 2_000_000), scriptOdatanoUtxo.amount);
422
168
  }
423
- const txOutParams = {
424
- address: recipientAddress,
425
- value: outputValue,
426
- };
427
- if (req.inlineDatum) {
428
- txOutParams.datum = (0, tx_build_helper_1.jsonToPlutusData)(req.inlineDatum);
429
- }
430
- const outputs = [new cardano_ledger_ts_1.TxOut(txOutParams)];
431
- // Find an ADA-only UTxO for collateral (from sender UTxOs only)
432
- const adaOnlyUtxo = senderUtxos.find(u => u.amount.every(a => a.unit.toLowerCase() === 'lovelace'));
433
- if (!adaOnlyUtxo) {
434
- throw new Error('[BuildooorTxBuilder] No ADA-only UTxO available for collateral. Plutus scripts require ADA-only collateral.');
435
- }
436
- const collateralUtxos = [this._mapOdatanoUtxoToLedgerUtxo(adaOnlyUtxo)];
437
- // Exclude collateral UTxO from regular inputs so it is not consumed on successful tx.
438
- // This preserves the dedicated collateral UTxO for future Plutus transactions.
439
- const fundingUtxos = senderUtxos.filter(u => !(u.txHash === adaOnlyUtxo.txHash && u.outputIndex === adaOnlyUtxo.outputIndex));
169
+ const outputs = [this._buildTxOut(recipientAddress, outputValue, req.inlineDatum)];
170
+ // Collateral + funding separation (from sender UTxOs only)
171
+ const { collateralUtxos, fundingUtxos } = this._setupCollateral(senderUtxos);
440
172
  const fundingLedgerUtxos = fundingUtxos.map(utxo => this._mapMultiAssetUtxoToLedgerUtxo(utxo));
441
173
  // Helper to build inputs with specified execution units
442
174
  const buildInputs = (exUnits) => {
443
- // Script input with witness
444
175
  const scriptInput = {
445
176
  utxo: scriptLedgerUtxo,
446
- inputScript: {
447
- script,
448
- datum,
449
- redeemer: redeemerData,
450
- executionUnits: exUnits
451
- }
177
+ inputScript: { script, datum, redeemer: redeemerData, executionUnits: exUnits }
452
178
  };
453
- // Regular sender inputs for fees (excluding collateral)
454
179
  const regularInputs = fundingLedgerUtxos.map(utxo => ({ utxo }));
455
180
  return [scriptInput, ...regularInputs];
456
181
  };
457
- // Determine execution units based on evaluator availability
458
- let finalExUnits = const_1.DEFAULT_EXECUTION_UNITS;
459
- if (ctx.evaluateTransaction) {
460
- // Build first pass with high execution units for evaluation
461
- logger.debug(`Building evaluation pass with high execution units`);
462
- const evalInputs = buildInputs(const_1.HIGH_EXECUTION_UNITS);
182
+ // Evaluate execution units
183
+ const finalExUnits = await this._evaluateExUnits(async () => {
463
184
  const evalTx = await this.txBuilder.build({
464
- inputs: evalInputs,
465
- outputs,
466
- changeAddress,
467
- collaterals: collateralUtxos,
468
- requiredSigners: req.requiredSigners
185
+ inputs: buildInputs(const_1.HIGH_EXECUTION_UNITS), outputs, changeAddress,
186
+ collaterals: collateralUtxos, requiredSigners: req.requiredSigners
469
187
  });
470
- const evalTxCbor = (0, uint8array_utils_1.toHex)(evalTx.toCbor().toBuffer());
471
- try {
472
- const evalResults = await ctx.evaluateTransaction(evalTxCbor);
473
- logger.debug(`Evaluation results: ${JSON.stringify(evalResults)}`);
474
- if (evalResults && evalResults.length > 0) {
475
- const budget = evalResults[0].budget;
476
- finalExUnits = {
477
- mem: Math.ceil(budget.memory * const_1.EXECUTION_UNIT_BUFFER),
478
- cpu: Math.ceil(budget.cpu * const_1.EXECUTION_UNIT_BUFFER)
479
- };
480
- logger.info(`Using evaluated execution units: mem=${finalExUnits.mem}, cpu=${finalExUnits.cpu}`);
481
- }
482
- }
483
- catch (evalError) {
484
- logger.warn(`Evaluation failed, using default units: ${evalError.message}`);
485
- }
486
- }
487
- else {
488
- logger.debug(`No evaluator available, using default execution units`);
489
- }
490
- // Build with final execution units
188
+ return (0, uint8array_utils_1.toHex)(evalTx.toCbor().toBuffer());
189
+ }, ctx.evaluateTransaction);
190
+ // Build with final execution units + witness buffer
491
191
  const inputs = buildInputs(finalExUnits);
492
- // First build to calculate base fee
493
- const txFirstPass = await this.txBuilder.build({
494
- inputs,
495
- outputs,
496
- changeAddress,
497
- collaterals: collateralUtxos,
498
- requiredSigners: req.requiredSigners
192
+ const tx = await this._buildWithWitnessBuffer({
193
+ inputs, outputs, changeAddress,
194
+ collaterals: collateralUtxos, requiredSigners: req.requiredSigners
499
195
  });
500
- // Add minimal buffer for witness set CBOR overhead
501
- const calculatedFee = BigInt(txFirstPass.body.fee.toString());
502
- const witnessBuffer = BigInt(const_1.WITNESS_BUFFER_BYTES);
503
- const adjustedMinFee = calculatedFee + witnessBuffer;
504
- logger.debug(`First pass fee: ${calculatedFee}, rebuilding with witness buffer: ${adjustedMinFee}`);
505
- // Final build with adjusted minimum fee
506
- const tx = await this.txBuilder.build({
507
- inputs,
508
- outputs,
509
- changeAddress,
510
- collaterals: collateralUtxos,
511
- requiredSigners: req.requiredSigners,
512
- fee: adjustedMinFee
513
- });
514
- const unsignedTxBytes = tx.toCbor().toBuffer();
515
- const unsignedTxCbor = (0, uint8array_utils_1.toHex)(unsignedTxBytes);
516
- const txBodyHash = tx.hash.toString();
517
196
  logger.debug(`Built unsigned Plutus spending transaction successfully with fee: ${tx.body.fee.toString()}`);
518
- return {
519
- unsignedTxCbor,
520
- txBodyHash,
521
- senderAddress: req.senderAddress,
522
- network: this.cardanoClient.network,
523
- builderEngine: this.name,
524
- sizeBytes: unsignedTxBytes.length,
525
- feeLovelace: tx.body.fee.toString(),
526
- inputs: ctx.utxos.map(u => ({
527
- txHash: u.txHash,
528
- index: u.outputIndex,
529
- lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
530
- })),
531
- outputs: tx.body.outputs.map((o) => ({
532
- address: o.address?.toString?.() ?? "",
533
- lovelace: o.value?.lovelaces?.toString?.() ?? "0"
534
- })),
535
- scriptHash: script.hash.toString(),
536
- warnings: []
537
- };
197
+ return this._buildResult(req, ctx, this._extractTxDetails(tx), { scriptHash: script.hash.toString() });
538
198
  }
539
199
  catch (err) {
540
- (0, tx_build_helper_1.mapBuilderError)(err, 'lovelace');
200
+ (0, tx_build_helper_1.mapBuilderError)(err);
201
+ }
202
+ }
203
+ //---------------------------------------------------------------------------
204
+ // Shared Helper Methods
205
+ //---------------------------------------------------------------------------
206
+ /** Extract CBOR, hash, fee, size, and outputs from a built Buildooor Tx */
207
+ _extractTxDetails(tx) {
208
+ const unsignedTxBytes = tx.toCbor().toBuffer();
209
+ return {
210
+ unsignedTxCbor: (0, uint8array_utils_1.toHex)(unsignedTxBytes),
211
+ txBodyHash: tx.hash.toString(),
212
+ sizeBytes: unsignedTxBytes.length,
213
+ feeLovelace: tx.body.fee.toString(),
214
+ outputDetails: tx.body.outputs.map((o) => ({
215
+ address: o.address?.toString?.() ?? "",
216
+ lovelace: o.value?.lovelaces?.toString?.() ?? "0"
217
+ })),
218
+ };
219
+ }
220
+ /** Build the standard TxBuildResult object */
221
+ _buildResult(req, ctx, txDetails, extra) {
222
+ return {
223
+ unsignedTxCbor: txDetails.unsignedTxCbor,
224
+ txBodyHash: txDetails.txBodyHash,
225
+ senderAddress: req.senderAddress,
226
+ network: this.cardanoClient.network,
227
+ builderEngine: this.name,
228
+ sizeBytes: txDetails.sizeBytes,
229
+ feeLovelace: txDetails.feeLovelace,
230
+ inputs: ctx.utxos.map(u => ({
231
+ txHash: u.txHash,
232
+ index: u.outputIndex,
233
+ lovelace: (0, tx_build_helper_1.getLovelace)(u).toString()
234
+ })),
235
+ outputs: txDetails.outputDetails,
236
+ ...extra,
237
+ warnings: [],
238
+ };
239
+ }
240
+ /**
241
+ * Evaluate execution units via callback. Caller provides an async function
242
+ * that builds the evaluation tx and returns its CBOR hex.
243
+ */
244
+ async _evaluateExUnits(buildEvalTx, evaluator) {
245
+ if (!evaluator) {
246
+ logger.debug('No evaluator available, using default execution units');
247
+ return const_1.DEFAULT_EXECUTION_UNITS;
248
+ }
249
+ logger.debug('Building evaluation pass with high execution units');
250
+ const evalTxCbor = await buildEvalTx();
251
+ try {
252
+ const evalResults = await evaluator(evalTxCbor);
253
+ logger.debug(`Evaluation results: ${JSON.stringify(evalResults)}`);
254
+ if (evalResults && evalResults.length > 0) {
255
+ const budget = evalResults[0].budget;
256
+ const result = {
257
+ mem: Math.ceil(budget.memory * const_1.EXECUTION_UNIT_BUFFER),
258
+ cpu: Math.ceil(budget.cpu * const_1.EXECUTION_UNIT_BUFFER)
259
+ };
260
+ logger.info(`Using evaluated execution units: mem=${result.mem}, cpu=${result.cpu}`);
261
+ return result;
262
+ }
263
+ }
264
+ catch (evalError) {
265
+ logger.warn(`Evaluation failed, using default units: ${evalError.message}`);
266
+ }
267
+ return const_1.DEFAULT_EXECUTION_UNITS;
268
+ }
269
+ /** Two-pass build: first build to calculate fee, then rebuild with witness buffer */
270
+ async _buildWithWitnessBuffer(buildParams) {
271
+ const txFirstPass = await this.txBuilder.build(buildParams);
272
+ const calculatedFee = BigInt(txFirstPass.body.fee.toString());
273
+ const adjustedMinFee = calculatedFee + BigInt(const_1.WITNESS_BUFFER_BYTES);
274
+ logger.debug(`First pass fee: ${calculatedFee}, rebuilding with witness buffer: ${adjustedMinFee}`);
275
+ return this.txBuilder.build({ ...buildParams, fee: adjustedMinFee });
276
+ }
277
+ /**
278
+ * Find an ADA-only UTxO for collateral, map it, and return remaining funding UTxOs.
279
+ * Throws if no ADA-only UTxO is available.
280
+ */
281
+ _setupCollateral(utxos) {
282
+ const adaOnlyUtxo = utxos.find(u => u.amount.every(a => a.unit.toLowerCase() === 'lovelace'));
283
+ if (!adaOnlyUtxo) {
284
+ throw new Error('No ADA-only UTxO available for collateral. Plutus scripts require ADA-only collateral.');
541
285
  }
286
+ const collateralUtxos = [this._mapOdatanoUtxoToLedgerUtxo(adaOnlyUtxo)];
287
+ const fundingUtxos = utxos.filter(u => !(u.txHash === adaOnlyUtxo.txHash && u.outputIndex === adaOnlyUtxo.outputIndex));
288
+ return { collateralUtxos, fundingUtxos };
289
+ }
290
+ /** Build a Ledger Value from lovelace + optional multi-asset array */
291
+ _buildLedgerValue(lovelace, assets) {
292
+ let value = cardano_ledger_ts_1.Value.lovelaces(lovelace);
293
+ if (assets) {
294
+ for (const asset of assets) {
295
+ if (asset.unit.toLowerCase() === 'lovelace')
296
+ continue;
297
+ if (BigInt(asset.quantity) <= 0n)
298
+ continue;
299
+ const { policyId, assetName } = (0, tx_build_helper_1.parseAssetUnit)(asset.unit);
300
+ value = cardano_ledger_ts_1.Value.add(value, cardano_ledger_ts_1.Value.singleAsset(new cardano_ledger_ts_1.Hash28(policyId), Buffer.from(assetName, 'hex'), BigInt(asset.quantity)));
301
+ }
302
+ }
303
+ return value;
304
+ }
305
+ /** Build a TxOut with optional inline datum */
306
+ _buildTxOut(address, value, datum) {
307
+ const params = { address, value };
308
+ if (datum) {
309
+ params.datum = (0, tx_build_helper_1.jsonToPlutusData)(datum);
310
+ }
311
+ return new cardano_ledger_ts_1.TxOut(params);
542
312
  }
543
313
  //---------------------------------------------------------------------------
544
- // Private Helper Methods
314
+ // UTxO Mapping & Configuration Helpers
545
315
  //---------------------------------------------------------------------------
546
316
  /**
547
317
  * Map ODATANO LedgerProtocolParameter to Buildooor's ProtocolParameters shape
548
- * @param protocolParameters ledger protocol parameters
549
- * @returns mapped protocol parameters
550
318
  */
551
319
  _mapLedgerParametersToBuildooorParams(protocolParameters) {
552
- // Map LedgerProtocolParameter to Buildooor's ProtocolParameters shape
553
- // Using defaultProtocolParameters as base and overriding with actual values
554
320
  return {
555
321
  ...cardano_ledger_ts_1.defaultProtocolParameters,
556
322
  txFeePerByte: Number(protocolParameters.minFeeA),
@@ -564,22 +330,14 @@ class BuildooorTxBuilder {
564
330
  }
565
331
  /**
566
332
  * Map ODATANO UTxO to Ledger UTxO (ADA-only)
567
- * @param utxos ODATANO UTxO
568
- * @returns mapped Ledger UTxO
569
333
  */
570
334
  _mapOdatanoUtxoToLedgerUtxo(utxos) {
571
335
  (0, tx_build_helper_1.assertAdaOnly)(utxos);
572
- const outRef = new cardano_ledger_ts_1.TxOutRef({
573
- id: utxos.txHash,
574
- index: utxos.outputIndex
575
- });
576
- const addr = cardano_ledger_ts_1.Address.fromString(utxos.address);
577
- const value = cardano_ledger_ts_1.Value.lovelaces((0, tx_build_helper_1.getLovelace)(utxos));
578
336
  return new cardano_ledger_ts_1.UTxO({
579
- utxoRef: outRef,
337
+ utxoRef: new cardano_ledger_ts_1.TxOutRef({ id: utxos.txHash, index: utxos.outputIndex }),
580
338
  resolved: new cardano_ledger_ts_1.TxOut({
581
- address: addr,
582
- value,
339
+ address: cardano_ledger_ts_1.Address.fromString(utxos.address),
340
+ value: cardano_ledger_ts_1.Value.lovelaces((0, tx_build_helper_1.getLovelace)(utxos)),
583
341
  datum: undefined,
584
342
  refScript: undefined
585
343
  })
@@ -587,32 +345,14 @@ class BuildooorTxBuilder {
587
345
  }
588
346
  /**
589
347
  * Map ODATANO UTxO to Ledger UTxO (with multi-asset support)
590
- * @param utxo ODATANO UTxO
591
- * @returns mapped Ledger UTxO
592
348
  */
593
349
  _mapMultiAssetUtxoToLedgerUtxo(utxo) {
594
- const outRef = new cardano_ledger_ts_1.TxOutRef({
595
- id: utxo.txHash,
596
- index: utxo.outputIndex
597
- });
598
- const addr = cardano_ledger_ts_1.Address.fromString(utxo.address);
599
- // Build Value from all amounts
600
- let value = cardano_ledger_ts_1.Value.lovelaces((0, tx_build_helper_1.getLovelace)(utxo));
601
- for (const amount of utxo.amount) {
602
- if (amount.unit.toLowerCase() !== 'lovelace') {
603
- const { policyId, assetName } = (0, tx_build_helper_1.parseAssetUnit)(amount.unit);
604
- const policyHash = new cardano_ledger_ts_1.Hash28(policyId);
605
- const assetValue = cardano_ledger_ts_1.Value.singleAsset(policyHash, Buffer.from(assetName, 'hex'), BigInt(amount.quantity));
606
- value = cardano_ledger_ts_1.Value.add(value, assetValue);
607
- }
608
- }
609
- const datumValue = utxo.inlineDatum
610
- ? (0, plutus_data_1.dataFromCbor)(utxo.inlineDatum)
611
- : undefined;
350
+ const value = this._buildLedgerValue((0, tx_build_helper_1.getLovelace)(utxo), utxo.amount);
351
+ const datumValue = utxo.inlineDatum ? (0, plutus_data_1.dataFromCbor)(utxo.inlineDatum) : undefined;
612
352
  return new cardano_ledger_ts_1.UTxO({
613
- utxoRef: outRef,
353
+ utxoRef: new cardano_ledger_ts_1.TxOutRef({ id: utxo.txHash, index: utxo.outputIndex }),
614
354
  resolved: new cardano_ledger_ts_1.TxOut({
615
- address: addr,
355
+ address: cardano_ledger_ts_1.Address.fromString(utxo.address),
616
356
  value,
617
357
  datum: datumValue,
618
358
  refScript: undefined
@@ -621,8 +361,6 @@ class BuildooorTxBuilder {
621
361
  }
622
362
  /**
623
363
  * Map ODATANO metadata JSON to Ledger TxMetadata
624
- * @param metadataJson metadata in JSON format
625
- * @returns mapped TxMetadata
626
364
  */
627
365
  _mapOdatanoMetadataToLedgerMetadata(metadataJson) {
628
366
  if (!metadataJson) {
@@ -630,9 +368,7 @@ class BuildooorTxBuilder {
630
368
  }
631
369
  const metadata = {};
632
370
  for (const [label, value] of Object.entries(metadataJson)) {
633
- // convert label to number
634
371
  const numericLabel = parseInt(label, 10);
635
- // convert JSON value to TxMetadatum
636
372
  const txMetadatum = this._jsonToTxMetadatum(value);
637
373
  logger.debug(`Created TxMetadatum for label ${numericLabel}: ${txMetadatum.constructor.name}`);
638
374
  metadata[numericLabel] = txMetadatum;
@@ -644,8 +380,6 @@ class BuildooorTxBuilder {
644
380
  }
645
381
  /**
646
382
  * Recursively convert JSON value to TxMetadatum
647
- * @param value JSON value
648
- * @returns corresponding TxMetadatum
649
383
  */
650
384
  _jsonToTxMetadatum(value) {
651
385
  if (typeof value === 'number' || typeof value === 'bigint') {
@@ -667,7 +401,7 @@ class BuildooorTxBuilder {
667
401
  }
668
402
  return new TxMetadatum_1.TxMetadatumMap(map);
669
403
  }
670
- throw new Error(`[BuildooorTxBuilder] Unsupported metadata value type: ${typeof value}`);
404
+ throw new Error(`Unsupported metadata value type: ${typeof value}`);
671
405
  }
672
406
  }
673
407
  exports.BuildooorTxBuilder = BuildooorTxBuilder;