diff --git a/.changeset/unlucky-socks-occur.md b/.changeset/unlucky-socks-occur.md new file mode 100644 index 0000000..c16cae2 --- /dev/null +++ b/.changeset/unlucky-socks-occur.md @@ -0,0 +1,5 @@ +--- +'@rosen-chains/cardano': major +--- + +consider decimals drop diff --git a/packages/chains/cardano/lib/CardanoChain.ts b/packages/chains/cardano/lib/CardanoChain.ts index 4d22279..3a70ad0 100644 --- a/packages/chains/cardano/lib/CardanoChain.ts +++ b/packages/chains/cardano/lib/CardanoChain.ts @@ -80,9 +80,16 @@ class CardanoChain extends AbstractUtxoChain { ) continue; + const assetBalance = CardanoUtils.getBoxAssets(output); + const wrappedBalance = ChainUtils.wrapAssetBalance( + assetBalance, + this.tokenMap, + this.NATIVE_TOKEN_ID, + this.CHAIN + ); const payment: SinglePayment = { address: output.address().to_bech32(), - assets: CardanoUtils.getBoxAssets(output), + assets: wrappedBalance, }; order.push(payment); } @@ -109,19 +116,29 @@ class CardanoChain extends AbstractUtxoChain { `Generating Cardano transaction for Order: ${JsonBigInt.stringify(order)}` ); // calculate required assets + const fee = this.configs.fee; const requiredAssets = order .map((order) => order.assets) .reduce(ChainUtils.sumAssetBalance, { - nativeToken: this.getMinimumNativeToken() + this.configs.fee, + nativeToken: + this.getMinimumNativeToken() + + this.tokenMap.wrapAmount(this.NATIVE_TOKEN_ID, fee, this.CHAIN) + .amount, tokens: [], }); this.logger.debug( `Required assets: ${JsonBigInt.stringify(requiredAssets)}` ); + const unwrappedRequiredAssets = ChainUtils.unwrapAssetBalance( + requiredAssets, + this.tokenMap, + this.NATIVE_TOKEN_ID, + this.CHAIN + ); if (!(await this.hasLockAddressEnoughAssets(requiredAssets))) { - const neededADA = requiredAssets.nativeToken.toString(); - const neededTokens = JSONBigInt.stringify(requiredAssets.tokens); + const neededADA = unwrappedRequiredAssets.nativeToken.toString(); + const neededTokens = JSONBigInt.stringify(unwrappedRequiredAssets.tokens); throw new NotEnoughAssetsError( `Locked assets cannot cover required assets. ADA: ${neededADA}, Tokens: ${neededTokens}` ); @@ -144,13 +161,13 @@ class CardanoChain extends AbstractUtxoChain { const coveredBoxes = await this.getCoveringBoxes( this.configs.addresses.lock, - requiredAssets, + unwrappedRequiredAssets, forbiddenBoxIds, trackMap ); if (!coveredBoxes.covered) { - const neededAdas = requiredAssets.nativeToken.toString(); - const neededTokens = JSONBigInt.stringify(requiredAssets.tokens); + const neededAdas = unwrappedRequiredAssets.nativeToken.toString(); + const neededTokens = JSONBigInt.stringify(unwrappedRequiredAssets.tokens); throw new NotEnoughValidBoxesError( `Available boxes didn't cover required assets. ADA: ${neededAdas}, Tokens: ${neededTokens}` ); @@ -171,20 +188,30 @@ class CardanoChain extends AbstractUtxoChain { throw Error('Cardano does not support extra data in payment order'); } // accumulate value + const orderLovelace = this.tokenMap.unwrapAmount( + this.NATIVE_TOKEN_ID, + order.assets.nativeToken, + this.CHAIN + ).amount; orderValue = orderValue.checked_add( - CardanoUtils.bigIntToBigNum(order.assets.nativeToken) + CardanoUtils.bigIntToBigNum(orderLovelace) ); // reduce order value from remaining assets remainingAssets = ChainUtils.subtractAssetBalance( remainingAssets, - order.assets + ChainUtils.unwrapAssetBalance( + order.assets, + this.tokenMap, + this.NATIVE_TOKEN_ID, + this.CHAIN + ) ); // create order output const address = CardanoWasm.Address.from_bech32(order.address); const value = CardanoWasm.Value.new( - CardanoUtils.bigIntToBigNum(order.assets.nativeToken) + CardanoUtils.bigIntToBigNum(orderLovelace) ); // inserting assets const orderMultiAsset = CardanoWasm.MultiAsset.new(); @@ -198,7 +225,9 @@ class CardanoChain extends AbstractUtxoChain { orderMultiAsset.set_asset( policyId, assetName, - CardanoUtils.bigIntToBigNum(asset.value) + CardanoUtils.bigIntToBigNum( + this.tokenMap.unwrapAmount(asset.id, asset.value, this.CHAIN).amount + ) ); }); value.set_multiasset(orderMultiAsset); @@ -223,7 +252,7 @@ class CardanoChain extends AbstractUtxoChain { ); // create change output - remainingAssets.nativeToken -= this.configs.fee; + remainingAssets.nativeToken -= fee; const changeBox = CardanoUtils.createTransactionOutput( remainingAssets, this.configs.addresses.lock @@ -232,7 +261,7 @@ class CardanoChain extends AbstractUtxoChain { // set ttl and fee txBuilder.set_ttl((await this.network.currentSlot()) + this.configs.txTtl); - txBuilder.set_fee(CardanoUtils.bigIntToBigNum(this.configs.fee)); + txBuilder.set_fee(CardanoUtils.bigIntToBigNum(fee)); // create the transaction const txBody = txBuilder.build(); @@ -262,6 +291,7 @@ class CardanoChain extends AbstractUtxoChain { /** * extracts box id and assets of a box + * Note: it returns the actual value * @param box the box * @returns an object containing the box id and assets */ @@ -366,8 +396,18 @@ class CardanoChain extends AbstractUtxoChain { } return { - inputAssets, - outputAssets, + inputAssets: ChainUtils.wrapAssetBalance( + inputAssets, + this.tokenMap, + this.NATIVE_TOKEN_ID, + this.CHAIN + ), + outputAssets: ChainUtils.wrapAssetBalance( + outputAssets, + this.tokenMap, + this.NATIVE_TOKEN_ID, + this.CHAIN + ), }; }; @@ -544,7 +584,11 @@ class CardanoChain extends AbstractUtxoChain { * @returns the minimum amount */ getMinimumNativeToken = () => { - return this.configs.minBoxValue; + return this.tokenMap.wrapAmount( + this.NATIVE_TOKEN_ID, + this.configs.minBoxValue, + this.CHAIN + ).amount; }; /** diff --git a/packages/chains/cardano/tests/CardanoChain.spec.ts b/packages/chains/cardano/tests/CardanoChain.spec.ts index 9bc3860..39f3c8c 100644 --- a/packages/chains/cardano/tests/CardanoChain.spec.ts +++ b/packages/chains/cardano/tests/CardanoChain.spec.ts @@ -245,6 +245,81 @@ describe('CardanoChain', () => { ); }).rejects.toThrow(NotEnoughValidBoxesError); }); + + /** + * @target CardanoChain.generateTransaction should generate payment + * transaction with wrapped order successfully + * @dependencies + * @scenario + * - mock transaction order, currentSlot + * - mock getCoveringBoxes, hasLockAddressEnoughAssets + * - call the function + * - check returned value + * @expected + * - PaymentTransaction txType, eventId, network and inputUtxos should be as + * expected + * - extracted order of generated transaction should be the same as input + * order + * - transaction fee and ttl should be the same as config fee + * - tokens with same policyId and should put correctly + */ + it('should generate payment transaction with wrapped order successfully', async () => { + // mock transaction order, currentSlot + const order = TestData.transaction4WrappedOrder; + const payment = CardanoTransaction.fromJson( + TestData.transaction4PaymentTransaction + ); + const getSlotSpy = spyOn(network, 'currentSlot'); + getSlotSpy.mockResolvedValue(200); + + // mock getCoveringBoxes, hasLockAddressEnoughAssets + const cardanoChain = + TestUtils.generateChainObjectWithMultiDecimalTokenMap(network); + const getCovBoxesSpy = spyOn(cardanoChain as any, 'getCoveringBoxes'); + getCovBoxesSpy.mockResolvedValue({ + covered: true, + boxes: bankBoxes.slice(2), + }); + const hasLockAddressEnoughAssetsSpy = spyOn( + cardanoChain, + 'hasLockAddressEnoughAssets' + ); + hasLockAddressEnoughAssetsSpy.mockResolvedValue(true); + + // call the function + const result = await cardanoChain.generateTransaction( + '2bedc6e54ede7748e5efc7df689a0a89b281ac1d92d09054650d5f27a25d5b85', + TransactionType.payment, + order, + [], + [] + ); + const cardanoTx = result as CardanoTransaction; + + // check returned value + expect(cardanoTx.txType).toEqual(payment.txType); + expect(cardanoTx.eventId).toEqual(payment.eventId); + expect(cardanoTx.network).toEqual(payment.network); + expect(cardanoTx.inputUtxos).toEqual( + bankBoxes.slice(2).map((utxo) => JsonBI.stringify(utxo)) + ); + + // extracted order of generated transaction should be the same as input order + const extractedOrder = cardanoChain.extractTransactionOrder(cardanoTx); + expect(extractedOrder).toEqual(order); + + // transaction fee and ttl should be the same as input configs + const tx = Transaction.from_bytes(cardanoTx.txBytes); + expect(tx.body().fee().to_str()).toEqual( + TestUtils.configs.fee.toString() + ); + expect(tx.body().ttl()).toEqual(264); + + // tokens with same policyId and should put correctly + expect( + tx.body().outputs().get(1).amount().multiasset()!.to_json() + ).toEqual(TestData.transaction4ChangeBoxMultiAssets.trim()); + }); }); describe('extractTransactionOrder', () => { @@ -275,6 +350,33 @@ describe('CardanoChain', () => { // check returned value expect(result).toEqual(expectedOrder); }); + + /** + * @target CardanoChain.extractTransactionOrder should wrap transaction + * order successfully + * @dependencies + * @scenario + * - mock PaymentTransaction + * - call the function + * - check returned value + * @expected + * - it should return mocked transaction order + */ + it('should wrap transaction order successfully', () => { + // mock PaymentTransaction + const paymentTx = CardanoTransaction.fromJson( + TestData.transaction1PaymentTransaction + ); + const expectedOrder = TestData.transaction1WrappedOrder; + + // call the function + const cardanoChain = + TestUtils.generateChainObjectWithMultiDecimalTokenMap(network); + const result = cardanoChain.extractTransactionOrder(paymentTx); + + // check returned value + expect(result).toEqual(expectedOrder); + }); }); describe('getBoxInfo', () => { @@ -426,6 +528,35 @@ describe('CardanoChain', () => { const result = await cardanoChain.getTransactionAssets(paymentTx); expect(result.inputAssets).toEqual(TestData.transaction6InputAssets); }); + + /** + * @target CardanoChain.getTransactionAssets should wrap transaction assets + * successfully + * @dependencies + * @scenario + * - mock PaymentTransaction + * - call the function + * - check returned value + * @expected + * - it should return mocked transaction assets (both input and output assets) + */ + it('should wrap transaction assets successfully', async () => { + // mock PaymentTransaction + const paymentTx = CardanoTransaction.fromJson( + TestData.transaction1PaymentTransaction + ); + + // call the function + const cardanoChain = + TestUtils.generateChainObjectWithMultiDecimalTokenMap(network); + + // check returned value + const result = await cardanoChain.getTransactionAssets(paymentTx); + expect(result.inputAssets).toEqual( + TestData.transaction1WrappedInputAssets + ); + expect(result.outputAssets).toEqual(TestData.transaction1WrappedAssets); + }); }); describe('getMempoolBoxMapping', () => { @@ -562,7 +693,7 @@ describe('CardanoChain', () => { const testInstance = new TestCardanoChain( network, TestUtils.configs, - TestUtils.rosenTokens, + TestData.testTokenMap, null as any ); @@ -1028,7 +1159,7 @@ describe('CardanoChain', () => { const cardanoChain = new CardanoChain( network, newConfigs, - TestUtils.rosenTokens, + TestData.testTokenMap, TestUtils.mockedSignFn ); diff --git a/packages/chains/cardano/tests/testData.ts b/packages/chains/cardano/tests/testData.ts index a1c7b46..9d30b52 100644 --- a/packages/chains/cardano/tests/testData.ts +++ b/packages/chains/cardano/tests/testData.ts @@ -4,101 +4,212 @@ import { PaymentOrder, } from '@rosen-chains/abstract-chain'; import { CardanoTx } from '../lib'; +import { RosenTokens } from '@rosen-bridge/tokens'; -export const testTokenMap = ` -{ - "idKeys" : { - "ergo" : "tokenId", - "cardano" : "tokenId" +export const testTokenMap: RosenTokens = { + idKeys: { + ergo: 'tokenId', + cardano: 'tokenId', }, - "tokens" : [ + tokens: [ { - "ergo" : { - "tokenId" : "erg", - "tokenName" : "erg", - "decimals" : 9, - "metaData" : { - "type" : "ERG", - "residency" : "native" - } + ergo: { + tokenId: 'erg', + name: 'ERG', + decimals: 9, + metaData: { + type: 'ERG', + residency: 'native', + }, + }, + cardano: { + tokenId: + 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + name: 'RstERGvTest', + policyId: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286', + assetName: '5273744552477654657374', + decimals: 9, + metaData: { + type: 'native', + residency: 'wrapped', + }, }, - "cardano" : { - "tokenId" : "ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374", - "policyId" : "ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286", - "assetName" : "5273744552477654657374", - "decimals" : 0, - "metaData" : { - "type" : "native", - "residency" : "wrapped" - } - } }, { - "ergo" : { - "tokenId" : "4ed6449240d166b0e44c529b5bf06d210796473d3811b9aa0e15329599164c24", - "tokenName" : "RST-ADA.V-test", - "decimals" : 6, - "metaData" : { - "type" : "EIP-004", - "residency" : "wrapped" - } + ergo: { + tokenId: + '4ed6449240d166b0e44c529b5bf06d210796473d3811b9aa0e15329599164c24', + name: 'RST-ADA.V-test', + decimals: 6, + metaData: { + type: 'EIP-004', + residency: 'wrapped', + }, + }, + cardano: { + tokenId: 'ada', + name: 'ADA', + policyId: '', + assetName: '414441', + decimals: 6, + metaData: { + type: 'ADA', + residency: 'native', + }, }, - "cardano" : { - "tokenId" : "ada", - "policyId" : "", - "assetName" : "414441", - "decimals" : 6, - "metaData" : { - "type" : "ADA", - "residency" : "native" - } - } }, { - "ergo" : { - "tokenId" : "c59e86ef9d0280de582d6266add18fca339a77dfb321268e83033fe47101dc4d", - "tokenName" : "RST-Cardano-Token.V-test", - "decimals" : 4, - "metaData" : { - "type" : "EIP-004", - "residency" : "wrapped" - } + ergo: { + tokenId: + 'c59e86ef9d0280de582d6266add18fca339a77dfb321268e83033fe47101dc4d', + name: 'RST-Cardano-Token.V-test', + decimals: 4, + metaData: { + type: 'EIP-004', + residency: 'wrapped', + }, + }, + cardano: { + tokenId: + 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be.43617264616e6f546f6b656e7654657374', + name: 'CardanoTokenvTest', + policyId: 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be', + assetName: '43617264616e6f546f6b656e7654657374', + decimals: 4, + metaData: { + type: 'native', + residency: 'native', + }, }, - "cardano" : { - "tokenId" : "cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be.43617264616e6f546f6b656e7654657374", - "policyId" : "cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be", - "assetName" : "43617264616e6f546f6b656e7654657374", - "decimals" : 0, - "metaData" : { - "type" : "native", - "residency" : "native" - } - } }, { - "ergo" : { - "tokenId" : "a1143e81c5ab485a807e6f0f76af1dd70cc5359b29e0b1229d0edfe490d33b67", - "tokenName" : "Ergo-Token.V-test", - "decimals" : 4, - "metaData" : { - "type" : "EIP-004", - "residency" : "native" - } + ergo: { + tokenId: + 'a1143e81c5ab485a807e6f0f76af1dd70cc5359b29e0b1229d0edfe490d33b67', + name: 'Ergo-Token.V-test', + decimals: 4, + metaData: { + type: 'EIP-004', + residency: 'native', + }, }, - "cardano" : { - "tokenId" : "48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b.5273744572676f546f6b656e7654657374", - "policyId" : "48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b", - "assetName" : "5273744572676f546f6b656e7654657374", - "decimals" : 0, - "metaData" : { - "type" : "native", - "residency" : "wrapped" - } - } - } - ] -} -`; + cardano: { + tokenId: + '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b.5273744572676f546f6b656e7654657374', + name: 'RstErgoTokenvTest', + policyId: '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b', + assetName: '5273744572676f546f6b656e7654657374', + decimals: 4, + metaData: { + type: 'native', + residency: 'wrapped', + }, + }, + }, + ], +}; +export const multiDecimalTokenMap: RosenTokens = { + idKeys: { + ergo: 'tokenId', + cardano: 'tokenId', + }, + tokens: [ + { + ergo: { + tokenId: 'erg', + name: 'erg', + decimals: 9, + metaData: { + type: 'ERG', + residency: 'native', + }, + }, + cardano: { + tokenId: + 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + name: 'RstERGvTest', + policyId: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286', + assetName: '5273744552477654657374', + decimals: 10, + metaData: { + type: 'native', + residency: 'wrapped', + }, + }, + }, + { + ergo: { + tokenId: + '4ed6449240d166b0e44c529b5bf06d210796473d3811b9aa0e15329599164c24', + name: 'RST-ADA.V-test', + decimals: 4, + metaData: { + type: 'EIP-004', + residency: 'wrapped', + }, + }, + cardano: { + tokenId: 'ada', + name: 'ADA', + policyId: '', + assetName: '414441', + decimals: 6, + metaData: { + type: 'ADA', + residency: 'native', + }, + }, + }, + { + ergo: { + tokenId: + 'c59e86ef9d0280de582d6266add18fca339a77dfb321268e83033fe47101dc4d', + name: 'RST-Cardano-Token.V-test', + decimals: 4, + metaData: { + type: 'EIP-004', + residency: 'wrapped', + }, + }, + cardano: { + tokenId: + 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be.43617264616e6f546f6b656e7654657374', + name: 'CardanoTokenvTest', + policyId: 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be', + assetName: '43617264616e6f546f6b656e7654657374', + decimals: 5, + metaData: { + type: 'native', + residency: 'native', + }, + }, + }, + { + ergo: { + tokenId: + 'a1143e81c5ab485a807e6f0f76af1dd70cc5359b29e0b1229d0edfe490d33b67', + name: 'Ergo-Token.V-test', + decimals: 4, + metaData: { + type: 'EIP-004', + residency: 'native', + }, + }, + cardano: { + tokenId: + '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b.5273744572676f546f6b656e7654657374', + name: 'RstErgoTokenvTest', + policyId: '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b', + assetName: '5273744572676f546f6b656e7654657374', + decimals: 1, + metaData: { + type: 'native', + residency: 'wrapped', + }, + }, + }, + ], +}; export const transaction1 = ` { @@ -233,6 +344,21 @@ export const transaction1Order: PaymentOrder = [ }, }, ]; +export const transaction1WrappedOrder: PaymentOrder = [ + { + address: + 'addr1qxwxpafgqasnddk8et6en0vn74awg4j0n2nfek6e62aywvgcwedk5s2s92dx7msutk33zsl92uh8uhahh305nz7pekjsz5l37w', + assets: { + nativeToken: 20000n, + tokens: [ + { + id: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + value: 10n, + }, + ], + }, + }, +]; export const transaction1PaymentTransaction = ` { @@ -270,6 +396,23 @@ export const transaction1Assets: AssetBalance = { }, ], }; +export const transaction1WrappedAssets: AssetBalance = { + nativeToken: 1400100n, + tokens: [ + { + id: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + value: 100n, + }, + { + id: '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b.5273744572676f546f6b656e7654657374', + value: 5000n, + }, + { + id: 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be.43617264616e6f546f6b656e7654657374', + value: 10n, + }, + ], +}; export const transaction1InputAssets: AssetBalance = { nativeToken: 140010000n, @@ -288,6 +431,23 @@ export const transaction1InputAssets: AssetBalance = { }, ], }; +export const transaction1WrappedInputAssets: AssetBalance = { + nativeToken: 1400100n, + tokens: [ + { + id: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + value: 100n, + }, + { + id: '48d4a14b8407af8407702df3afda4cc8a945ce55235e9808c62c5f9b.5273744572676f546f6b656e7654657374', + value: 5000n, + }, + { + id: 'cfd784ccfe5fe8ce7d09f4ddb65624378cc8022bf3ec240cf41ea6be.43617264616e6f546f6b656e7654657374', + value: 10n, + }, + ], +}; export const transaction2PaymentTransaction = ` { @@ -324,6 +484,21 @@ export const transaction4Order: PaymentOrder = [ }, }, ]; +export const transaction4WrappedOrder: PaymentOrder = [ + { + address: + 'addr1qxwxpafgqasnddk8et6en0vn74awg4j0n2nfek6e62aywvgcwedk5s2s92dx7msutk33zsl92uh8uhahh305nz7pekjsz5l37w', + assets: { + nativeToken: 100000n, + tokens: [ + { + id: 'ef6aa6200e21634e58ce6796b4b61d1d7d059d2ebe93c2996eeaf286.5273744552477654657374', + value: 100n, + }, + ], + }, + }, +]; export const transaction4PaymentTransaction = ` { diff --git a/packages/chains/cardano/tests/testUtils.ts b/packages/chains/cardano/tests/testUtils.ts index 9108559..67ae7d8 100644 --- a/packages/chains/cardano/tests/testUtils.ts +++ b/packages/chains/cardano/tests/testUtils.ts @@ -3,7 +3,7 @@ import { CardanoConfigs, CardanoUtxo } from '../lib/types'; import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs'; import CardanoUtils from '../lib/CardanoUtils'; import { RosenTokens } from '@rosen-bridge/tokens'; -import { testTokenMap } from './testData'; +import { multiDecimalTokenMap, testTokenMap } from './testData'; import TestCardanoNetwork from './network/TestCardanoNetwork'; import { CardanoChain } from '../lib'; @@ -151,11 +151,16 @@ export const configs: CardanoConfigs = { aggregatedPublicKey: 'bcb07faa6c0f19e2f2587aa9ef6f43a68fc0135321216a71dc87c8527af4ca6a', }; -export const rosenTokens: RosenTokens = JSON.parse(testTokenMap); export const mockedSignFn = () => Promise.resolve(''); export const generateChainObject = ( network: TestCardanoNetwork, signFn: (txHash: Uint8Array) => Promise = mockedSignFn ) => { - return new CardanoChain(network, configs, rosenTokens, signFn); + return new CardanoChain(network, configs, testTokenMap, signFn); +}; +export const generateChainObjectWithMultiDecimalTokenMap = ( + network: TestCardanoNetwork, + signFn: (txHash: Uint8Array) => Promise = mockedSignFn +) => { + return new CardanoChain(network, configs, multiDecimalTokenMap, signFn); };