@meshsdk/common 1.9.0-beta.54 → 1.9.0-beta.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -896,6 +896,16 @@ var validityRangeToObj = (validityRange) => {
896
896
  invalidHereafter: validityRange.invalidHereafter ?? null
897
897
  };
898
898
  };
899
+ var validityRangeFromObj = (obj) => {
900
+ const validityRange = {};
901
+ if (obj.invalidBefore !== null && obj.invalidBefore !== void 0) {
902
+ validityRange.invalidBefore = Number(obj.invalidBefore);
903
+ }
904
+ if (obj.invalidHereafter !== null && obj.invalidHereafter !== void 0) {
905
+ validityRange.invalidHereafter = Number(obj.invalidHereafter);
906
+ }
907
+ return validityRange;
908
+ };
899
909
 
900
910
  // src/data/mesh/constructors.ts
901
911
  var mConStr = (alternative, fields) => ({
@@ -1190,6 +1200,7 @@ var jsonProofToPlutusData = (proof) => {
1190
1200
  var bytesToHex = (bytes) => Buffer.from(bytes).toString("hex");
1191
1201
  var hexToBytes = (hex) => Buffer.from(hex, "hex");
1192
1202
  var stringToHex = (str) => Buffer.from(str, "utf8").toString("hex");
1203
+ var isHexString = (hex) => /^[0-9A-F]*$/i.test(hex);
1193
1204
  var hexToString = (hex) => Buffer.from(hex, "hex").toString("utf8");
1194
1205
  var toBytes = (hex) => {
1195
1206
  if (hex.length % 2 === 0 && /^[0-9A-F]*$/i.test(hex))
@@ -1484,6 +1495,23 @@ var MeshValue = class _MeshValue {
1484
1495
  get = (unit) => {
1485
1496
  return this.value[unit] ? BigInt(this.value[unit]) : BigInt(0);
1486
1497
  };
1498
+ /**
1499
+ * Get all assets that belong to a specific policy ID
1500
+ * @param policyId The policy ID to filter by
1501
+ * @returns Array of assets that match the policy ID
1502
+ */
1503
+ getPolicyAssets = (policyId2) => {
1504
+ const assets = [];
1505
+ Object.entries(this.value).forEach(([unit, quantity]) => {
1506
+ if (unit.startsWith(policyId2)) {
1507
+ assets.push({
1508
+ unit,
1509
+ quantity: quantity.toString()
1510
+ });
1511
+ }
1512
+ });
1513
+ return assets;
1514
+ };
1487
1515
  /**
1488
1516
  * Get all asset units
1489
1517
  * @returns The asset units
@@ -1904,6 +1932,473 @@ var UtxoSelection = class {
1904
1932
  }
1905
1933
  };
1906
1934
 
1935
+ // src/tx-tester/index.ts
1936
+ var TxTester = class {
1937
+ txBody;
1938
+ inputsEvaluating;
1939
+ outputsEvaluating;
1940
+ traces;
1941
+ /**
1942
+ * Create a new TxTester instance
1943
+ * @param txBody The transaction builder body
1944
+ */
1945
+ constructor(txBody) {
1946
+ this.txBody = { ...txBody };
1947
+ this.inputsEvaluating = [];
1948
+ this.outputsEvaluating = [];
1949
+ this.traces = [];
1950
+ }
1951
+ /**
1952
+ * Add a trace to the TxTester
1953
+ * @param funcName The function name where the error occurred
1954
+ * @param message The error message
1955
+ */
1956
+ addTrace(funcName, message) {
1957
+ const msg = `[Error - ${funcName}]: ${message}`;
1958
+ this.traces.push(msg);
1959
+ }
1960
+ /**
1961
+ * Check if the transaction evaluation was successful
1962
+ * @returns true if there are no errors, false otherwise
1963
+ */
1964
+ success() {
1965
+ return this.traces.length === 0;
1966
+ }
1967
+ /**
1968
+ * Get the error messages if any
1969
+ * @returns A string representation of the errors or "No errors" if there are none
1970
+ */
1971
+ errors() {
1972
+ if (this.traces.length > 0) {
1973
+ return `${this.traces}`;
1974
+ } else {
1975
+ return "No errors";
1976
+ }
1977
+ }
1978
+ /**
1979
+ * Checks if the transaction is valid after a specified timestamp.
1980
+ * @param requiredTimestamp The timestamp after which the transaction should be valid
1981
+ * @returns The TxTester instance for chaining
1982
+ */
1983
+ validAfter = (requiredTimestamp) => {
1984
+ const invalidBefore = this.txBody.validityRange?.invalidHereafter ? this.txBody.validityRange.invalidHereafter : 9999999999999;
1985
+ const isValidAfter = this.txBody.validityRange?.invalidBefore ? this.txBody.validityRange.invalidBefore < requiredTimestamp : true;
1986
+ if (!isValidAfter) {
1987
+ this.addTrace(
1988
+ "validAfter",
1989
+ `tx invalid before ${invalidBefore}, with requiredTimestamp ${requiredTimestamp}`
1990
+ );
1991
+ }
1992
+ return this;
1993
+ };
1994
+ /**
1995
+ * Checks if the transaction is valid before a specified timestamp.
1996
+ * @param requiredTimestamp The timestamp before which the transaction should be valid
1997
+ * @returns The TxTester instance for chaining
1998
+ */
1999
+ validBefore = (requiredTimestamp) => {
2000
+ const invalidHereafter = this.txBody.validityRange?.invalidBefore ? this.txBody.validityRange.invalidBefore : 0;
2001
+ const isValidBefore = this.txBody.validityRange?.invalidHereafter ? this.txBody.validityRange.invalidHereafter > requiredTimestamp : true;
2002
+ if (!isValidBefore) {
2003
+ this.addTrace(
2004
+ "validBefore",
2005
+ `tx invalid after ${invalidHereafter}, with requiredTimestamp ${requiredTimestamp}`
2006
+ );
2007
+ }
2008
+ return this;
2009
+ };
2010
+ // Extra Signatories Methods
2011
+ /**
2012
+ * Checks if a specific key is signed in the transaction.
2013
+ * @param keyHash The key hash to check
2014
+ * @returns The TxTester instance for chaining
2015
+ */
2016
+ keySigned = (keyHash) => {
2017
+ const isKeySigned = keySignedLogic(this.txBody.requiredSignatures, keyHash);
2018
+ if (!isKeySigned) {
2019
+ this.addTrace("keySigned", `tx does not have key ${keyHash} signed`);
2020
+ }
2021
+ return this;
2022
+ };
2023
+ /**
2024
+ * Checks if any one of the specified keys is signed in the transaction.
2025
+ * @param keyHashes The array of key hashes to check
2026
+ * @returns The TxTester instance for chaining
2027
+ */
2028
+ oneOfKeysSigned = (keyHashes) => {
2029
+ const isOneOfKeysSigned = keyHashes.some(
2030
+ (keyHash) => keySignedLogic(this.txBody.requiredSignatures, keyHash)
2031
+ );
2032
+ if (!isOneOfKeysSigned) {
2033
+ this.addTrace(
2034
+ "oneOfKeysSigned",
2035
+ `tx does not have any of the keys signed: ${keyHashes.join(", ")}`
2036
+ );
2037
+ }
2038
+ return this;
2039
+ };
2040
+ /**
2041
+ * Checks if all specified keys are signed in the transaction.
2042
+ * @param keyHashes The array of key hashes to check
2043
+ * @returns The TxTester instance for chaining
2044
+ */
2045
+ allKeysSigned = (keyHashes) => {
2046
+ const missingKeys = [];
2047
+ const isAllKeysSigned = keyHashes.every((keyHash) => {
2048
+ const isKeySigned = keySignedLogic(
2049
+ this.txBody.requiredSignatures,
2050
+ keyHash
2051
+ );
2052
+ if (!isKeySigned) {
2053
+ missingKeys.push(keyHash);
2054
+ }
2055
+ return isKeySigned;
2056
+ });
2057
+ if (!isAllKeysSigned) {
2058
+ this.addTrace(
2059
+ "allKeysSigned",
2060
+ `tx does not have all keys signed: ${missingKeys.join(", ")}`
2061
+ );
2062
+ }
2063
+ return this;
2064
+ };
2065
+ /**
2066
+ * Checks if a specific token is minted in the transaction.
2067
+ * @param policyId The policy ID of the token
2068
+ * @param assetName The asset name of the token
2069
+ * @param quantity The quantity of the token
2070
+ * @returns The TxTester instance for chaining
2071
+ */
2072
+ tokenMinted = (policyId2, assetName2, quantity) => {
2073
+ const isTokenMinted = tokenMintedLogic(
2074
+ this.txBody.mints,
2075
+ policyId2,
2076
+ assetName2,
2077
+ quantity
2078
+ );
2079
+ if (!isTokenMinted) {
2080
+ this.addTrace(
2081
+ "tokenMinted",
2082
+ `Token with policy_id: ${policyId2}, asset_name: ${assetName2}, quantity: ${quantity} not found in mints.`
2083
+ );
2084
+ }
2085
+ return this;
2086
+ };
2087
+ /**
2088
+ * Checks if a specific token is minted in the transaction and that it is the only mint.
2089
+ * @param policyId The policy ID of the token
2090
+ * @param assetName The asset name of the token
2091
+ * @param quantity The quantity of the token
2092
+ * @returns The TxTester instance for chaining
2093
+ */
2094
+ onlyTokenMinted = (policyId2, assetName2, quantity) => {
2095
+ const isTokenMinted = tokenMintedLogic(
2096
+ this.txBody.mints,
2097
+ policyId2,
2098
+ assetName2,
2099
+ quantity
2100
+ );
2101
+ const isOnlyOneMint = this.txBody.mints?.length === 1;
2102
+ if (!isTokenMinted) {
2103
+ this.addTrace(
2104
+ "onlyTokenMinted",
2105
+ `Token with policy_id: ${policyId2}, asset_name: ${assetName2}, quantity: ${quantity} not found in mints`
2106
+ );
2107
+ }
2108
+ if (!isOnlyOneMint) {
2109
+ this.addTrace(
2110
+ "onlyTokenMinted",
2111
+ `Expected only one mint, but found ${this.txBody.mints?.length || 0} mints.`
2112
+ );
2113
+ }
2114
+ return this;
2115
+ };
2116
+ /**
2117
+ * Checks if a specific token is minted in the transaction, ensuring that it is the only mint for the given policy ID.
2118
+ * @param policyId The policy ID of the token
2119
+ * @param assetName The asset name of the token
2120
+ * @param quantity The quantity of the token
2121
+ * @returns The TxTester instance for chaining
2122
+ */
2123
+ policyOnlyMintedToken = (policyId2, assetName2, quantity) => {
2124
+ const filteredMints = this.txBody.mints?.filter((token) => {
2125
+ return token.policyId === policyId2;
2126
+ }) || [];
2127
+ const isTokenMinted = tokenMintedLogic(
2128
+ this.txBody.mints,
2129
+ policyId2,
2130
+ assetName2,
2131
+ quantity
2132
+ );
2133
+ const isOnlyOneMint = filteredMints.length === 1;
2134
+ if (!isOnlyOneMint) {
2135
+ this.addTrace(
2136
+ "policyOnlyMintedToken",
2137
+ `Expected only one mint for policy_id: ${policyId2}, but found ${filteredMints.length} mints.`
2138
+ );
2139
+ }
2140
+ if (!isTokenMinted) {
2141
+ this.addTrace(
2142
+ "policyOnlyMintedToken",
2143
+ `Token with policy_id: ${policyId2}, asset_name: ${assetName2}, quantity: ${quantity} not found in mints.`
2144
+ );
2145
+ }
2146
+ return this;
2147
+ };
2148
+ /**
2149
+ * Checks if a specific policy ID is burned in the transaction, ensuring that it is the only minting (i.e. burning item).
2150
+ * @param policyId The policy ID to check
2151
+ * @returns true if the policy is the only burn, false otherwise
2152
+ */
2153
+ checkPolicyOnlyBurn = (policyId2) => {
2154
+ const filteredMints = this.txBody.mints?.filter((token) => {
2155
+ return token.policyId === policyId2 && token.mintValue.findIndex((m) => BigInt(m.amount) > 0) >= 0;
2156
+ }) || [];
2157
+ return filteredMints.length === 0;
2158
+ };
2159
+ /**
2160
+ * Not apply filter to inputs
2161
+ * @returns The TxTester instance for chaining
2162
+ */
2163
+ allInputs = () => {
2164
+ this.inputsEvaluating = this.txBody.inputs?.slice() || [];
2165
+ return this;
2166
+ };
2167
+ /**
2168
+ * Filter inputs by address
2169
+ * @param address The address to filter by
2170
+ * @returns The TxTester instance for chaining
2171
+ */
2172
+ inputsAt = (address) => {
2173
+ this.inputsEvaluating = this.txBody.inputs?.filter(
2174
+ (input) => txInToUtxo(input.txIn).output.address === address
2175
+ ) || [];
2176
+ return this;
2177
+ };
2178
+ /**
2179
+ * Filter inputs by unit
2180
+ * @param unit The unit to filter by
2181
+ * @returns The TxTester instance for chaining
2182
+ */
2183
+ inputsWith = (unit) => {
2184
+ this.inputsEvaluating = this.txBody.inputs?.filter((input) => {
2185
+ const inputValue = MeshValue.fromAssets(
2186
+ txInToUtxo(input.txIn).output.amount
2187
+ );
2188
+ const quantity = inputValue.get(unit);
2189
+ return quantity > 0;
2190
+ }) || [];
2191
+ return this;
2192
+ };
2193
+ /**
2194
+ * Filter inputs by policy ID
2195
+ * @param policyId The policy ID to filter by
2196
+ * @returns The TxTester instance for chaining
2197
+ */
2198
+ inputsWithPolicy = (policyId2) => {
2199
+ this.inputsEvaluating = this.txBody.inputs?.filter((input) => {
2200
+ const inputValue = MeshValue.fromAssets(
2201
+ txInToUtxo(input.txIn).output.amount
2202
+ );
2203
+ const assets = inputValue.getPolicyAssets(policyId2);
2204
+ return assets.length > 0;
2205
+ }) || [];
2206
+ return this;
2207
+ };
2208
+ /**
2209
+ * Filter inputs by address and policy ID
2210
+ * @param address The address to filter by
2211
+ * @param policyId The policy ID to filter by
2212
+ * @returns The TxTester instance for chaining
2213
+ */
2214
+ inputsAtWithPolicy = (address, policyId2) => {
2215
+ this.inputsEvaluating = this.txBody.inputs?.filter((input) => {
2216
+ const utxo = txInToUtxo(input.txIn);
2217
+ const inputValue = MeshValue.fromAssets(utxo.output.amount);
2218
+ const assets = inputValue.getPolicyAssets(policyId2);
2219
+ return utxo.output.address === address && assets.length > 0;
2220
+ }) || [];
2221
+ return this;
2222
+ };
2223
+ /**
2224
+ * Filter inputs by address and unit
2225
+ * @param address The address to filter by
2226
+ * @param unit The unit to filter by
2227
+ * @returns The TxTester instance for chaining
2228
+ */
2229
+ inputsAtWith = (address, unit) => {
2230
+ this.inputsEvaluating = this.txBody.inputs?.filter((input) => {
2231
+ const utxo = txInToUtxo(input.txIn);
2232
+ const inputValue = MeshValue.fromAssets(utxo.output.amount);
2233
+ const quantity = inputValue.get(unit);
2234
+ return utxo.output.address === address && quantity > 0;
2235
+ }) || [];
2236
+ return this;
2237
+ };
2238
+ /**
2239
+ * Check if inputs contain the expected value.
2240
+ * *Reminder - It must be called after filtering methods for inputs*
2241
+ * @param expectedValue The expected value
2242
+ * @returns The TxTester instance for chaining
2243
+ */
2244
+ inputsValue = (expectedValue) => {
2245
+ let value2 = new MeshValue();
2246
+ this.inputsEvaluating.forEach((input) => {
2247
+ const utxo = txInToUtxo(input.txIn);
2248
+ value2.addAssets(utxo.output.amount);
2249
+ });
2250
+ const isValueCorrect = value2.eq(expectedValue);
2251
+ if (!isValueCorrect) {
2252
+ this.addTrace(
2253
+ "inputsValue",
2254
+ `inputs ${JSON.stringify(this.inputsEvaluating)} have value ${JSON.stringify(value2)}, expect ${JSON.stringify(expectedValue)}`
2255
+ );
2256
+ }
2257
+ return this;
2258
+ };
2259
+ // /**
2260
+ // * Check if inputs contain a specific inline datum.
2261
+ // * *Reminder - It must be called after filtering methods for inputs*
2262
+ // * @param datumCbor The datum CBOR to check
2263
+ // * @returns The TxTester instance for chaining
2264
+ // */
2265
+ // inputsInlineDatumExist = (datumCbor: string): this => {
2266
+ // const inputsWithInlineDatum = this.inputsEvaluating.filter((input) => {
2267
+ // const utxo = txInToUtxo(input.txIn);
2268
+ // return utxo.output.plutusData === datumCbor;
2269
+ // });
2270
+ // if (inputsWithInlineDatum.length === 0) {
2271
+ // this.addTrace(
2272
+ // "inputsInlineDatumExist",
2273
+ // `No inputs with inline datum matching: ${datumCbor}`,
2274
+ // );
2275
+ // }
2276
+ // return this;
2277
+ // };
2278
+ /**
2279
+ * Not apply filter to outputs
2280
+ * @returns The TxTester instance for chaining
2281
+ */
2282
+ allOutputs = () => {
2283
+ this.outputsEvaluating = this.txBody.outputs?.slice() || [];
2284
+ return this;
2285
+ };
2286
+ /**
2287
+ * Filter outputs by address
2288
+ * @param address The address to filter by
2289
+ * @returns The TxTester instance for chaining
2290
+ */
2291
+ outputsAt = (address) => {
2292
+ this.outputsEvaluating = this.txBody.outputs?.filter((output) => output.address === address) || [];
2293
+ return this;
2294
+ };
2295
+ /**
2296
+ * Filter outputs by unit
2297
+ * @param unit The unit to filter by
2298
+ * @returns The TxTester instance for chaining
2299
+ */
2300
+ outputsWith = (unit) => {
2301
+ this.outputsEvaluating = this.txBody.outputs?.filter((output) => {
2302
+ const outputValue = MeshValue.fromAssets(output.amount);
2303
+ const quantity = outputValue.get(unit);
2304
+ return quantity > 0;
2305
+ }) || [];
2306
+ return this;
2307
+ };
2308
+ /**
2309
+ * Filter outputs by policy ID
2310
+ * @param policyId The policy ID to filter by
2311
+ * @returns The TxTester instance for chaining
2312
+ */
2313
+ outputsWithPolicy = (policyId2) => {
2314
+ this.outputsEvaluating = this.txBody.outputs?.filter((output) => {
2315
+ const outputValue = MeshValue.fromAssets(output.amount);
2316
+ const assets = outputValue.getPolicyAssets(policyId2);
2317
+ return assets.length > 0;
2318
+ }) || [];
2319
+ return this;
2320
+ };
2321
+ /**
2322
+ * Filter outputs by address and policy ID
2323
+ * @param address The address to filter by
2324
+ * @param policyId The policy ID to filter by
2325
+ * @returns The TxTester instance for chaining
2326
+ */
2327
+ outputsAtWithPolicy = (address, policyId2) => {
2328
+ this.outputsEvaluating = this.txBody.outputs?.filter((output) => {
2329
+ const outputValue = MeshValue.fromAssets(output.amount);
2330
+ const assets = outputValue.getPolicyAssets(policyId2);
2331
+ return output.address === address && assets.length > 0;
2332
+ }) || [];
2333
+ return this;
2334
+ };
2335
+ /**
2336
+ * Filter outputs by address and unit
2337
+ * @param address The address to filter by
2338
+ * @param unit The unit to filter by
2339
+ * @returns The TxTester instance for chaining
2340
+ */
2341
+ outputsAtWith = (address, unit) => {
2342
+ this.outputsEvaluating = this.txBody.outputs?.filter((output) => {
2343
+ const outputValue = MeshValue.fromAssets(output.amount);
2344
+ const quantity = outputValue.get(unit);
2345
+ return output.address === address && quantity > 0;
2346
+ }) || [];
2347
+ return this;
2348
+ };
2349
+ /**
2350
+ * Check if outputs contain the expected value.
2351
+ * *Reminder - It must be called after filtering methods for outputs*
2352
+ * @param expectedValue The expected value
2353
+ * @returns The TxTester instance for chaining
2354
+ */
2355
+ outputsValue = (expectedValue) => {
2356
+ let value2 = new MeshValue();
2357
+ this.outputsEvaluating.forEach((output) => {
2358
+ value2.addAssets(output.amount);
2359
+ });
2360
+ const isValueCorrect = value2.eq(expectedValue);
2361
+ if (!isValueCorrect) {
2362
+ this.addTrace(
2363
+ "outputsValue",
2364
+ `tx outputs ${JSON.stringify(this.outputsEvaluating)} have value ${JSON.stringify(value2)}, expected ${JSON.stringify(expectedValue)}`
2365
+ );
2366
+ }
2367
+ return this;
2368
+ };
2369
+ /**
2370
+ * Check if outputs contain a specific inline datum.
2371
+ * *Reminder - It must be called after filtering methods for outputs*
2372
+ * @param datumCbor The datum CBOR to check
2373
+ * @returns The TxTester instance for chaining
2374
+ */
2375
+ outputsInlineDatumExist = (datumCbor) => {
2376
+ const outputsWithInlineDatum = this.outputsEvaluating.filter((output) => {
2377
+ if (output.datum && output.datum.type === "Inline") {
2378
+ return output.datum.data.content === datumCbor;
2379
+ }
2380
+ return false;
2381
+ });
2382
+ if (outputsWithInlineDatum.length === 0) {
2383
+ this.addTrace(
2384
+ "outputs_inline_datum_exist",
2385
+ `No outputs with inline datum matching: ${datumCbor}`
2386
+ );
2387
+ }
2388
+ return this;
2389
+ };
2390
+ };
2391
+ function keySignedLogic(requiredSignatures, keyHash) {
2392
+ return requiredSignatures?.some((signatory) => signatory === keyHash) || false;
2393
+ }
2394
+ function tokenMintedLogic(mints, policyId2, assetName2, quantity) {
2395
+ return mints?.some((token) => {
2396
+ return token.policyId === policyId2 && token.mintValue.findIndex(
2397
+ (m) => m.assetName === assetName2 && BigInt(m.amount) === BigInt(quantity)
2398
+ ) >= 0;
2399
+ }) || false;
2400
+ }
2401
+
1907
2402
  // src/index.ts
1908
2403
  import { generateMnemonic, mnemonicToEntropy } from "bip39";
1909
2404
  export {
@@ -1929,6 +2424,7 @@ export {
1929
2424
  SUPPORTED_OGMIOS_LINKS,
1930
2425
  SUPPORTED_TOKENS,
1931
2426
  SUPPORTED_WALLETS,
2427
+ TxTester,
1932
2428
  UtxoSelection,
1933
2429
  assetClass,
1934
2430
  assetName,
@@ -1958,9 +2454,11 @@ export {
1958
2454
  hexToBytes,
1959
2455
  hexToString,
1960
2456
  integer,
2457
+ isHexString,
1961
2458
  isNetwork,
1962
2459
  jsonProofToPlutusData,
1963
2460
  keepRelevant,
2461
+ keySignedLogic,
1964
2462
  largestFirst,
1965
2463
  largestFirstMultiAsset,
1966
2464
  list,
@@ -2016,11 +2514,13 @@ export {
2016
2514
  stringToHex,
2017
2515
  toBytes,
2018
2516
  toUTF8,
2517
+ tokenMintedLogic,
2019
2518
  tokenName,
2020
2519
  tuple,
2021
2520
  txInToUtxo,
2022
2521
  txOutRef,
2023
2522
  unixTimeToEnclosingSlot,
2523
+ validityRangeFromObj,
2024
2524
  validityRangeToObj,
2025
2525
  value,
2026
2526
  verificationKey
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshsdk/common",
3
- "version": "1.9.0-beta.54",
3
+ "version": "1.9.0-beta.56",
4
4
  "description": "Contains constants, types and interfaces used across the SDK and different serialization libraries",
5
5
  "main": "./dist/index.cjs",
6
6
  "browser": "./dist/index.js",