diff --git a/src/modules/auto-router/services/auto-router.transactions.service.ts b/src/modules/auto-router/services/auto-router.transactions.service.ts index 372160abb..7a3b47da6 100644 --- a/src/modules/auto-router/services/auto-router.transactions.service.ts +++ b/src/modules/auto-router/services/auto-router.transactions.service.ts @@ -3,6 +3,7 @@ import { AddressValue, BigUIntValue, BytesValue, + Token, TokenTransfer, TypedValue, } from '@multiversx/sdk-core'; @@ -19,6 +20,7 @@ import { ComposableTasksTransactionService } from 'src/modules/composable-tasks/ import { EsdtTokenPayment } from '@multiversx/sdk-exchange'; import { EgldOrEsdtTokenPayment } from 'src/models/esdtTokenPayment.model'; import { decimalToHex } from 'src/utils/token.converters'; +import { TransactionOptions } from 'src/modules/common/transaction.options'; @Injectable() export class AutoRouterTransactionService { @@ -33,7 +35,6 @@ export class AutoRouterTransactionService { args: MultiSwapTokensArgs, ): Promise { const transactions = []; - const contract = await this.mxProxy.getRouterSmartContract(); const amountIn = new BigNumber(args.intermediaryAmounts[0]).plus( new BigNumber(args.intermediaryAmounts[0]).multipliedBy( @@ -44,6 +45,7 @@ export class AutoRouterTransactionService { if (args.tokenInID === mxConfig.EGLDIdentifier) { return [ await this.wrapEgldAndMultiSwapTransaction( + sender, amountIn.integerValue().toFixed(), args, ), @@ -53,6 +55,7 @@ export class AutoRouterTransactionService { if (args.tokenOutID === mxConfig.EGLDIdentifier) { return [ await this.multiSwapAndUnwrapEgldTransaction( + sender, amountIn.integerValue().toFixed(), args, ), @@ -62,25 +65,31 @@ export class AutoRouterTransactionService { const gasLimit = args.addressRoute.length * gasConfig.router.multiPairSwapMultiplier; - const transactionArgs = - args.swapType == SWAP_TYPE.fixedInput - ? this.multiPairFixedInputSwaps(args) - : this.multiPairFixedOutputSwaps(args); + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'multiPairSwap', + arguments: + args.swapType == SWAP_TYPE.fixedInput + ? this.multiPairFixedInputSwaps(args) + : this.multiPairFixedOutputSwaps(args), + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: args.tokenRoute[0], + }), + amount: BigInt(amountIn.integerValue().toFixed()), + }), + ], + }); + + const transaction = + await this.mxProxy.getRouterSmartContractTransaction( + transactionOptions, + ); + transactions.push(transaction); - transactions.push( - contract.methodsExplicit - .multiPairSwap(transactionArgs) - .withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - args.tokenRoute[0], - amountIn.integerValue(), - ), - ) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(), - ); if (args.tokenOutID === mxConfig.EGLDIdentifier) { transactions.push( await this.transactionsWrapService.unwrapEgld( @@ -209,6 +218,7 @@ export class AutoRouterTransactionService { } async wrapEgldAndMultiSwapTransaction( + sender: string, value: string, args: MultiSwapTokensArgs, ): Promise { @@ -219,6 +229,7 @@ export class AutoRouterTransactionService { const swaps = this.convertMultiPairSwapsToBytesValues(typedArgs); return this.composeTasksTransactionService.getComposeTasksTransaction( + sender, new EsdtTokenPayment({ tokenIdentifier: 'EGLD', tokenNonce: 0, @@ -245,6 +256,7 @@ export class AutoRouterTransactionService { } async multiSwapAndUnwrapEgldTransaction( + sender: string, value: string, args: MultiSwapTokensArgs, ): Promise { @@ -255,6 +267,7 @@ export class AutoRouterTransactionService { const swaps = this.convertMultiPairSwapsToBytesValues(typedArgs); return this.composeTasksTransactionService.getComposeTasksTransaction( + sender, new EsdtTokenPayment({ tokenIdentifier: args.tokenRoute[0], tokenNonce: 0, diff --git a/src/modules/auto-router/specs/auto-router.service.spec.ts b/src/modules/auto-router/specs/auto-router.service.spec.ts index 553a81d30..f9d288db5 100644 --- a/src/modules/auto-router/specs/auto-router.service.spec.ts +++ b/src/modules/auto-router/specs/auto-router.service.spec.ts @@ -35,6 +35,9 @@ import { PairFilteringService } from 'src/modules/pair/services/pair.filtering.s describe('AutoRouterService', () => { let service: AutoRouterService; + const senderAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000001', + ).toBech32(); const ContextGetterServiceProvider = { provide: ContextGetterService, @@ -117,9 +120,9 @@ describe('AutoRouterService', () => { tokenRoute: ['USDC-123456', 'WEGLD-123456'], pairs: [ new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32(), + ).toBech32(), firstToken: Tokens('WEGLD-123456'), secondToken: Tokens('USDC-123456'), info: new PairInfoModel({ @@ -161,9 +164,9 @@ describe('AutoRouterService', () => { tokenRoute: ['USDC-123456', 'WEGLD-123456'], pairs: [ new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32(), + ).toBech32(), firstToken: Tokens('WEGLD-123456'), secondToken: Tokens('USDC-123456'), info: new PairInfoModel({ @@ -210,9 +213,9 @@ describe('AutoRouterService', () => { tokenRoute: ['USDC-123456', 'WEGLD-123456', 'MEX-123456'], pairs: [ new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32(), + ).toBech32(), firstToken: Tokens('WEGLD-123456'), secondToken: Tokens('USDC-123456'), info: new PairInfoModel({ @@ -223,9 +226,9 @@ describe('AutoRouterService', () => { totalFeePercent: 0.003, }), new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + ).toBech32(), firstToken: Tokens('WEGLD-123456'), secondToken: Tokens('MEX-123456'), info: new PairInfoModel({ @@ -245,7 +248,7 @@ describe('AutoRouterService', () => { it('should get a wrap tx + a fixed input simple swap tx', async () => { const transactions = await service.getTransactions( - Address.Zero().bech32(), + senderAddress, new AutoRouteModel({ swapType: 0, tokenInID: 'EGLD', @@ -263,9 +266,9 @@ describe('AutoRouterService', () => { tokenRoute: ['USDC-123456', 'WEGLD-123456'], pairs: [ new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32(), + ).toBech32(), }), ], tolerance: 0.01, @@ -275,8 +278,8 @@ describe('AutoRouterService', () => { { nonce: 0, value: '1000000000000000000', - receiver: Address.Zero().bech32(), - sender: '', + receiver: Address.Zero().toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -294,7 +297,7 @@ describe('AutoRouterService', () => { it('should get a fixed output multi swap tx + unwrap tx', async () => { const transactions = await service.getTransactions( - Address.Zero().bech32(), + senderAddress, new AutoRouteModel({ swapType: 1, tokenInID: 'USDC-123456', @@ -313,14 +316,14 @@ describe('AutoRouterService', () => { tokenRoute: ['USDC-123456', 'WEGLD-123456', 'MEX-123456'], pairs: [ new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32(), + ).toBech32(), }), new PairModel({ - address: Address.fromHex( + address: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + ).toBech32(), }), ], tolerance: 0.01, @@ -330,8 +333,8 @@ describe('AutoRouterService', () => { { nonce: 0, value: '0', - receiver: Address.Zero().bech32(), - sender: '', + receiver: Address.Zero().toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, diff --git a/src/modules/composable-tasks/services/composable.tasks.transaction.ts b/src/modules/composable-tasks/services/composable.tasks.transaction.ts index e2bf75bb9..0f7b37cf8 100644 --- a/src/modules/composable-tasks/services/composable.tasks.transaction.ts +++ b/src/modules/composable-tasks/services/composable.tasks.transaction.ts @@ -16,16 +16,19 @@ import { List, ListType, Struct, + Token, TokenIdentifierValue, TokenTransfer, TypedValue, U64Value, -} from '@multiversx/sdk-core/out'; + VariadicValue, +} from '@multiversx/sdk-core'; import BigNumber from 'bignumber.js'; import { gasConfig, mxConfig } from 'src/config'; import { EgldOrEsdtTokenPayment } from 'src/models/esdtTokenPayment.model'; import { decimalToHex } from 'src/utils/token.converters'; import { WrapAbiService } from 'src/modules/wrapping/services/wrap.abi.service'; +import { TransactionOptions } from 'src/modules/common/transaction.options'; export type ComposableTask = { type: ComposableTaskType; @@ -40,6 +43,7 @@ export class ComposableTasksTransactionService { ) {} async getComposeTasksTransaction( + sender: string, payment: EsdtTokenPayment, tokenOut: EgldOrEsdtTokenPayment, tasks: ComposableTask[], @@ -66,10 +70,12 @@ export class ComposableTasksTransactionService { } } - const contract = await this.mxProxy.getComposableTasksSmartContract(); - - let interaction = contract.methodsExplicit - .composeTasks([ + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'composeTasks', + arguments: [ new Struct(EgldOrEsdtTokenPayment.getStructure(), [ new Field( new TokenIdentifierValue(tokenOut.tokenIdentifier), @@ -81,31 +87,30 @@ export class ComposableTasksTransactionService { 'amount', ), ]), - ...this.getRawTasks(tasks), - ]) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID); - - switch (payment.tokenIdentifier) { - case 'EGLD': - interaction = interaction.withValue( - new BigUIntValue(new BigNumber(payment.amount)), - ); - break; - default: - interaction = interaction.withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - payment.tokenIdentifier, - new BigNumber(payment.amount), - ), - ); - break; + VariadicValue.fromItems(...this.getRawTasks(tasks)), + ], + }); + + if (payment.tokenIdentifier === mxConfig.EGLDIdentifier) { + transactionOptions.nativeTransferAmount = payment.amount; + } else { + transactionOptions.tokenTransfers = [ + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + }), + amount: BigInt(payment.amount), + }), + ]; } - return interaction.buildTransaction().toPlainObject(); + return await this.mxProxy.getComposableTasksContractTransaction( + transactionOptions, + ); } async wrapEgldAndSwapTransaction( + sender: string, value: string, tokenOutID: string, tokenOutAmountMin: string, @@ -131,6 +136,7 @@ export class ComposableTasksTransactionService { }; return this.getComposeTasksTransaction( + sender, new EsdtTokenPayment({ tokenIdentifier: 'EGLD', tokenNonce: 0, @@ -145,6 +151,7 @@ export class ComposableTasksTransactionService { } async swapAndUnwrapEgldTransaction( + sender: string, payment: EsdtTokenPayment, minimumValue: string, swapEndpoint: string, @@ -170,6 +177,7 @@ export class ComposableTasksTransactionService { }; return this.getComposeTasksTransaction( + sender, payment, new EgldOrEsdtTokenPayment({ tokenIdentifier: 'EGLD', diff --git a/src/modules/composable-tasks/specs/composable.tasks.transaction.spec.ts b/src/modules/composable-tasks/specs/composable.tasks.transaction.spec.ts index 4253b1813..52d679f1b 100644 --- a/src/modules/composable-tasks/specs/composable.tasks.transaction.spec.ts +++ b/src/modules/composable-tasks/specs/composable.tasks.transaction.spec.ts @@ -10,11 +10,12 @@ import { EsdtTokenPayment } from '@multiversx/sdk-exchange'; import { EgldOrEsdtTokenPayment } from 'src/models/esdtTokenPayment.model'; import { ComposableTaskType } from '../models/composable.tasks.model'; import { Address } from '@multiversx/sdk-core/out'; -import { gasConfig } from 'src/config'; -import { encodeTransactionData } from 'src/helpers/helpers'; describe('Composable Tasks Transaction', () => { let module: TestingModule; + const senderAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000001', + ).toBech32(); beforeAll(async () => { module = await Test.createTestingModule({ @@ -57,6 +58,7 @@ describe('Composable Tasks Transaction', () => { }); const transaction = await service.getComposeTasksTransaction( + senderAddress, payment, tokenOut, [ @@ -78,7 +80,7 @@ describe('Composable Tasks Transaction', () => { options: undefined, receiver: Address.Zero().bech32(), receiverUsername: undefined, - sender: '', + sender: senderAddress, senderUsername: undefined, signature: undefined, value: '1000000000000000000', @@ -92,6 +94,7 @@ describe('Composable Tasks Transaction', () => { ); const transaction = await service.wrapEgldAndSwapTransaction( + senderAddress, '1000000000000000000', 'USDC-123456', '20000000', @@ -101,7 +104,6 @@ describe('Composable Tasks Transaction', () => { expect(transaction).toEqual({ chainID: 'T', data: 'Y29tcG9zZVRhc2tzQDAwMDAwMDBiNTU1MzQ0NDMyZDMxMzIzMzM0MzUzNjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDAxMzEyZDAwQEBAMDJAMDAwMDAwMTQ3Mzc3NjE3MDU0NmY2YjY1NmU3MzQ2Njk3ODY1NjQ0OTZlNzA3NTc0MDAwMDAwMGI1NTUzNDQ0MzJkMzEzMjMzMzQzNTM2MDAwMDAwMDQwMTMxMmQwMA==', - gasLimit: 40200000, gasPrice: 1000000000, guardian: undefined, @@ -110,7 +112,7 @@ describe('Composable Tasks Transaction', () => { options: undefined, receiver: Address.Zero().bech32(), receiverUsername: undefined, - sender: '', + sender: senderAddress, senderUsername: undefined, signature: undefined, value: '1000000000000000000', @@ -124,6 +126,7 @@ describe('Composable Tasks Transaction', () => { ); const transaction = await service.swapAndUnwrapEgldTransaction( + senderAddress, new EsdtTokenPayment({ tokenIdentifier: 'USDC-123456', tokenNonce: 0, @@ -144,7 +147,7 @@ describe('Composable Tasks Transaction', () => { options: undefined, receiver: Address.Zero().bech32(), receiverUsername: undefined, - sender: '', + sender: senderAddress, senderUsername: undefined, signature: undefined, value: '0', diff --git a/src/modules/pair/pair.resolver.ts b/src/modules/pair/pair.resolver.ts index 5699d3556..7bb77539c 100644 --- a/src/modules/pair/pair.resolver.ts +++ b/src/modules/pair/pair.resolver.ts @@ -574,7 +574,7 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.whitelist(args); + return this.transactionService.whitelist(user.address, args); } @UseGuards(JwtOrNativeAdminGuard) @@ -584,7 +584,7 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.removeWhitelist(args); + return this.transactionService.removeWhitelist(user.address, args); } @UseGuards(JwtOrNativeAdminGuard) @@ -598,6 +598,7 @@ export class PairResolver { ): Promise { await this.pairService.requireOwner(user.address); return this.transactionService.addTrustedSwapPair( + user.address, pairAddress, swapPairAddress, firstTokenID, @@ -615,6 +616,7 @@ export class PairResolver { ): Promise { await this.pairService.requireOwner(user.address); return this.transactionService.removeTrustedSwapPair( + user.address, pairAddress, firstTokenID, secondTokenID, @@ -628,7 +630,7 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.pause(pairAddress); + return this.transactionService.pause(user.address, pairAddress); } @UseGuards(JwtOrNativeAdminGuard) @@ -638,7 +640,7 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.resume(pairAddress); + return this.transactionService.resume(user.address, pairAddress); } @UseGuards(JwtOrNativeAdminGuard) @@ -648,7 +650,10 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.setStateActiveNoSwaps(pairAddress); + return this.transactionService.setStateActiveNoSwaps( + user.address, + pairAddress, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -661,6 +666,7 @@ export class PairResolver { ): Promise { await this.pairService.requireOwner(user.address); return this.transactionService.setFeePercents( + user.address, pairAddress, totalFeePercent, specialFeePercent, @@ -676,6 +682,7 @@ export class PairResolver { ): Promise { await this.pairService.requireOwner(user.address); return this.transactionService.setLockingDeadlineEpoch( + user.address, pairAddress, newDeadline, ); @@ -690,6 +697,7 @@ export class PairResolver { ): Promise { await this.pairService.requireOwner(user.address); return this.transactionService.setLockingScAddress( + user.address, pairAddress, newAddress, ); @@ -703,7 +711,11 @@ export class PairResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.pairService.requireOwner(user.address); - return this.transactionService.setUnlockEpoch(pairAddress, newEpoch); + return this.transactionService.setUnlockEpoch( + user.address, + pairAddress, + newEpoch, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -713,7 +725,11 @@ export class PairResolver { }) async setupFeesCollector( @Args('pairAddress') pairAddress: string, + @AuthUser() user: UserAuthResult, ): Promise { - return this.transactionService.setupFeesCollector(pairAddress); + return this.transactionService.setupFeesCollector( + user.address, + pairAddress, + ); } } diff --git a/src/modules/pair/services/pair.transactions.service.ts b/src/modules/pair/services/pair.transactions.service.ts index c1ed1e879..3cb918f49 100644 --- a/src/modules/pair/services/pair.transactions.service.ts +++ b/src/modules/pair/services/pair.transactions.service.ts @@ -1,12 +1,13 @@ import { Injectable } from '@nestjs/common'; import { + Address, AddressValue, BigUIntValue, - TypedValue, + BytesValue, + Token, + TokenTransfer, U64Value, -} from '@multiversx/sdk-core/out/smartcontracts/typesystem'; -import { BytesValue } from '@multiversx/sdk-core/out/smartcontracts/typesystem/bytes'; -import { Address, TokenTransfer } from '@multiversx/sdk-core'; +} from '@multiversx/sdk-core'; import { mxConfig, gasConfig, scAddress, constantsConfig } from 'src/config'; import { TransactionModel } from 'src/models/transaction.model'; import { @@ -27,6 +28,7 @@ import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; import { ComposableTasksTransactionService } from 'src/modules/composable-tasks/services/composable.tasks.transaction'; import { EsdtTokenPayment } from '@multiversx/sdk-exchange'; import { PairComputeService } from './pair.compute.service'; +import { TransactionOptions } from 'src/modules/common/transaction.options'; @Injectable() export class PairTransactionService { @@ -146,27 +148,29 @@ export class PairTransactionService { throw new Error('Permanent locked amount must be less than 1 USD'); } - const contract = await this.mxProxy.getPairSmartContract( + return await this.mxProxy.getPairSmartContractTransaction( args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.addLiquidity, + function: 'addInitialLiquidity', + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: firstTokenInput.tokenID, + }), + amount: BigInt(firstTokenInput.amount), + }), + new TokenTransfer({ + token: new Token({ + identifier: secondTokenInput.tokenID, + }), + amount: BigInt(secondTokenInput.amount), + }), + ], + }), ); - - return contract.methodsExplicit - .addInitialLiquidity() - .withMultiESDTNFTTransfer([ - TokenTransfer.fungibleFromBigInteger( - firstTokenInput.tokenID, - new BigNumber(firstTokenInput.amount), - ), - TokenTransfer.fungibleFromBigInteger( - secondTokenInput.tokenID, - new BigNumber(secondTokenInput.amount), - ), - ]) - .withSender(Address.fromString(sender)) - .withGasLimit(gasConfig.pairs.addLiquidity) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); } @ErrorLoggerAsync({ @@ -191,32 +195,33 @@ export class PairTransactionService { .multipliedBy(1 - args.tolerance) .integerValue(); - const contract = await this.mxProxy.getPairSmartContract( + return await this.mxProxy.getPairSmartContractTransaction( args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.addLiquidity, + function: 'addLiquidity', + arguments: [ + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: firstTokenInput.tokenID, + }), + amount: BigInt(firstTokenInput.amount), + }), + new TokenTransfer({ + token: new Token({ + identifier: secondTokenInput.tokenID, + }), + amount: BigInt(secondTokenInput.amount), + }), + ], + }), ); - - const endpointArgs: TypedValue[] = [ - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ]; - - return contract.methodsExplicit - .addLiquidity(endpointArgs) - .withMultiESDTNFTTransfer([ - TokenTransfer.fungibleFromBigInteger( - firstTokenInput.tokenID, - new BigNumber(firstTokenInput.amount), - ), - TokenTransfer.fungibleFromBigInteger( - secondTokenInput.tokenID, - new BigNumber(secondTokenInput.amount), - ), - ]) - .withSender(Address.fromString(sender)) - .withGasLimit(gasConfig.pairs.addLiquidity) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); } async removeLiquidity( @@ -224,22 +229,16 @@ export class PairTransactionService { args: RemoveLiquidityArgs, ): Promise { const transactions = []; - const [ - wrappedTokenID, - firstTokenID, - secondTokenID, - liquidityPosition, - contract, - ] = await Promise.all([ - this.wrapAbi.wrappedEgldTokenID(), - this.pairAbi.firstTokenID(args.pairAddress), - this.pairAbi.secondTokenID(args.pairAddress), - this.pairService.getLiquidityPosition( - args.pairAddress, - args.liquidity, - ), - this.mxProxy.getPairSmartContract(args.pairAddress), - ]); + const [wrappedTokenID, firstTokenID, secondTokenID, liquidityPosition] = + await Promise.all([ + this.wrapAbi.wrappedEgldTokenID(), + this.pairAbi.firstTokenID(args.pairAddress), + this.pairAbi.secondTokenID(args.pairAddress), + this.pairService.getLiquidityPosition( + args.pairAddress, + args.liquidity, + ), + ]); const amount0Min = new BigNumber(liquidityPosition.firstTokenAmount) .multipliedBy(1 - args.tolerance) @@ -248,24 +247,28 @@ export class PairTransactionService { .multipliedBy(1 - args.tolerance) .integerValue(); - const endpointArgs = [ - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ]; - transactions.push( - contract.methodsExplicit - .removeLiquidity(endpointArgs) - .withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - args.liquidityTokenID, - new BigNumber(args.liquidity), - ), - ) - .withGasLimit(gasConfig.pairs.removeLiquidity) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(), + const transaction = await this.mxProxy.getPairSmartContractTransaction( + args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.removeLiquidity, + function: 'removeLiquidity', + arguments: [ + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: args.liquidityTokenID, + }), + amount: BigInt(args.liquidity), + }), + ], + }), ); + transactions.push(transaction); switch (wrappedTokenID) { case firstTokenID: @@ -315,6 +318,7 @@ export class PairTransactionService { if (args.tokenInID === mxConfig.EGLDIdentifier) { return this.composableTasksTransaction.wrapEgldAndSwapTransaction( + sender, args.amountIn, args.tokenOutID, amountOutMin.toFixed(), @@ -324,6 +328,7 @@ export class PairTransactionService { if (args.tokenOutID === mxConfig.EGLDIdentifier) { return this.composableTasksTransaction.swapAndUnwrapEgldTransaction( + sender, new EsdtTokenPayment({ tokenIdentifier: args.tokenInID, tokenNonce: 0, @@ -334,31 +339,36 @@ export class PairTransactionService { ); } - const [contract, trustedSwapPairs] = await Promise.all([ - this.mxProxy.getPairSmartContract(args.pairAddress), - this.pairAbi.trustedSwapPairs(args.pairAddress), - ]); + const trustedSwapPairs = await this.pairAbi.trustedSwapPairs( + args.pairAddress, + ); const gasLimit = trustedSwapPairs.length === 0 ? gasConfig.pairs.swapTokensFixedInput.default : gasConfig.pairs.swapTokensFixedInput.withFeeSwap; - return contract.methodsExplicit - .swapTokensFixedInput([ - BytesValue.fromUTF8(args.tokenOutID), - new BigUIntValue(amountOutMin), - ]) - .withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - args.tokenInID, - new BigNumber(amountIn), - ), - ) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'swapTokensFixedInput', + arguments: [ + BytesValue.fromUTF8(args.tokenOutID), + new BigUIntValue(amountOutMin), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: args.tokenInID, + }), + amount: BigInt(amountIn.integerValue().toFixed()), + }), + ], + }), + ); } @ErrorLoggerAsync({ @@ -384,6 +394,7 @@ export class PairTransactionService { if (args.tokenInID === mxConfig.EGLDIdentifier) { return this.composableTasksTransaction.wrapEgldAndSwapTransaction( + sender, args.amountIn, args.tokenOutID, args.amountOut, @@ -393,6 +404,7 @@ export class PairTransactionService { if (args.tokenOutID === mxConfig.EGLDIdentifier) { return this.composableTasksTransaction.swapAndUnwrapEgldTransaction( + sender, new EsdtTokenPayment({ tokenIdentifier: args.tokenInID, tokenNonce: 0, @@ -403,31 +415,36 @@ export class PairTransactionService { ); } - const [contract, trustedSwapPairs] = await Promise.all([ - this.mxProxy.getPairSmartContract(args.pairAddress), - this.pairAbi.trustedSwapPairs(args.pairAddress), - ]); + const trustedSwapPairs = await this.pairAbi.trustedSwapPairs( + args.pairAddress, + ); const gasLimit = trustedSwapPairs.length === 0 ? gasConfig.pairs.swapTokensFixedOutput.default : gasConfig.pairs.swapTokensFixedOutput.withFeeSwap; - return contract.methodsExplicit - .swapTokensFixedOutput([ - BytesValue.fromUTF8(args.tokenOutID), - new BigUIntValue(amountOut), - ]) - .withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - args.tokenInID, - new BigNumber(amountIn), - ), - ) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'swapTokensFixedOutput', + arguments: [ + BytesValue.fromUTF8(args.tokenOutID), + new BigUIntValue(amountOut), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: args.tokenInID, + }), + amount: BigInt(amountIn.integerValue().toFixed()), + }), + ], + }), + ); } async validateTokens( @@ -525,182 +542,229 @@ export class PairTransactionService { } } - async whitelist(args: WhitelistArgs): Promise { - const contract = await this.mxProxy.getPairSmartContract( + async whitelist( + sender: string, + args: WhitelistArgs, + ): Promise { + return await this.mxProxy.getPairSmartContractTransaction( args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.whitelist, + function: 'whitelist', + arguments: [ + new AddressValue(Address.newFromBech32(args.address)), + ], + }), ); - const transactionArgs: TypedValue[] = [ - new AddressValue(Address.fromString(args.address)), - ]; - return contract.methodsExplicit - .whitelist(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.whitelist) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); } - async removeWhitelist(args: WhitelistArgs): Promise { - const contract = await this.mxProxy.getPairSmartContract( + async removeWhitelist( + sender: string, + args: WhitelistArgs, + ): Promise { + return await this.mxProxy.getPairSmartContractTransaction( args.pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.removeWhitelist, + function: 'removeWhitelist', + arguments: [ + new AddressValue(Address.newFromBech32(args.address)), + ], + }), ); - const transactionArgs: TypedValue[] = [ - new AddressValue(Address.fromString(args.address)), - ]; - return contract.methodsExplicit - .removeWhitelist(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.removeWhitelist) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); } async addTrustedSwapPair( + sender: string, pairAddress: string, swapPairAddress: string, firstTokenID: string, secondTokenID: string, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - BytesValue.fromHex(new Address(swapPairAddress).hex()), - BytesValue.fromUTF8(firstTokenID), - BytesValue.fromUTF8(secondTokenID), - ]; - return contract.methodsExplicit - .addTrustedSwapPair(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.addTrustedSwapPair) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.addTrustedSwapPair, + function: 'addTrustedSwapPair', + arguments: [ + BytesValue.fromHex( + Address.newFromBech32(swapPairAddress).toHex(), + ), + BytesValue.fromUTF8(firstTokenID), + BytesValue.fromUTF8(secondTokenID), + ], + }), + ); } async removeTrustedSwapPair( + sender: string, pairAddress: string, firstTokenID: string, secondTokenID: string, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - BytesValue.fromUTF8(firstTokenID), - BytesValue.fromUTF8(secondTokenID), - ]; - return contract.methodsExplicit - .removeTrustedSwapPair(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.removeTrustedSwapPair) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.removeTrustedSwapPair, + function: 'removeTrustedSwapPair', + arguments: [ + BytesValue.fromUTF8(firstTokenID), + BytesValue.fromUTF8(secondTokenID), + ], + }), + ); } - async pause(pairAddress: string): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - return contract.methodsExplicit - .pause() - .withGasLimit(gasConfig.pairs.admin.pause) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async pause( + sender: string, + pairAddress: string, + ): Promise { + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.pause, + function: 'pause', + }), + ); } - async resume(pairAddress: string): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - return contract.methodsExplicit - .resume() - .withGasLimit(gasConfig.pairs.admin.resume) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async resume( + sender: string, + pairAddress: string, + ): Promise { + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.resume, + function: 'resume', + }), + ); } async setStateActiveNoSwaps( + sender: string, pairAddress: string, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - return contract.methodsExplicit - .setStateActiveNoSwaps() - .withGasLimit(gasConfig.pairs.admin.setStateActiveNoSwaps) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setStateActiveNoSwaps, + function: 'setStateActiveNoSwaps', + }), + ); } async setFeePercents( + sender: string, pairAddress: string, totalFeePercent: number, specialFeePercent: number, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - new BigUIntValue(new BigNumber(totalFeePercent)), - new BigUIntValue(new BigNumber(specialFeePercent)), - ]; - return contract.methodsExplicit - .setFeePercents(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.setFeePercents) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setFeePercents, + function: 'setFeePercents', + arguments: [ + new BigUIntValue(new BigNumber(totalFeePercent)), + new BigUIntValue(new BigNumber(specialFeePercent)), + ], + }), + ); } async setLockingDeadlineEpoch( + sender: string, pairAddress: string, newDeadline: number, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - new BigUIntValue(new BigNumber(newDeadline)), - ]; - return contract.methodsExplicit - .setLockingDeadlineEpoch(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.setLockingDeadlineEpoch) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setLockingDeadlineEpoch, + function: 'setLockingDeadlineEpoch', + arguments: [new BigUIntValue(new BigNumber(newDeadline))], + }), + ); } async setUnlockEpoch( + sender: string, pairAddress: string, newEpoch: number, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - new BigUIntValue(new BigNumber(newEpoch)), - ]; - return contract.methodsExplicit - .setUnlockEpoch(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.setUnlockEpoch) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setUnlockEpoch, + function: 'setUnlockEpoch', + arguments: [new BigUIntValue(new BigNumber(newEpoch))], + }), + ); } async setLockingScAddress( + sender: string, pairAddress: string, newAddress: string, ): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - const transactionArgs: TypedValue[] = [ - BytesValue.fromHex(new Address(newAddress).hex()), - ]; - return contract.methodsExplicit - .setLockingScAddress(transactionArgs) - .withGasLimit(gasConfig.pairs.admin.setLockingScAddress) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setLockingScAddress, + function: 'setLockingScAddress', + arguments: [ + BytesValue.fromHex( + Address.newFromBech32(newAddress).toHex(), + ), + ], + }), + ); } - async setupFeesCollector(pairAddress: string): Promise { - const contract = await this.mxProxy.getPairSmartContract(pairAddress); - return contract.methodsExplicit - .setupFeesCollector([ - new AddressValue(Address.fromString(scAddress.feesCollector)), - new U64Value(new BigNumber(constantsConfig.FEES_COLLECTOR_CUT)), - ]) - .withGasLimit(gasConfig.pairs.admin.setupFeesCollector) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async setupFeesCollector( + sender: string, + pairAddress: string, + ): Promise { + return await this.mxProxy.getPairSmartContractTransaction( + pairAddress, + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.pairs.admin.setupFeesCollector, + function: 'setupFeesCollector', + arguments: [ + new AddressValue( + Address.newFromBech32(scAddress.feesCollector), + ), + new U64Value( + new BigNumber(constantsConfig.FEES_COLLECTOR_CUT), + ), + ], + }), + ); } } diff --git a/src/modules/pair/specs/pair.transactions.service.spec.ts b/src/modules/pair/specs/pair.transactions.service.spec.ts index 9ecea3102..f63a59309 100644 --- a/src/modules/pair/specs/pair.transactions.service.spec.ts +++ b/src/modules/pair/specs/pair.transactions.service.spec.ts @@ -397,7 +397,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -440,19 +440,16 @@ describe('TransactionPairService', () => { PairTransactionService, ); - const transactions = await service.swapTokensFixedInput( - 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu', - { - pairAddress: Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), - tokenInID: 'EGLD', - tokenOutID: 'MEX-123456', - amountIn: '5', - amountOut: '5', - tolerance: 0.01, - }, - ); + const transactions = await service.swapTokensFixedInput(senderAddress, { + pairAddress: Address.fromHex( + '0000000000000000000000000000000000000000000000000000000000000012', + ).bech32(), + tokenInID: 'EGLD', + tokenOutID: 'MEX-123456', + amountIn: '5', + amountOut: '5', + tolerance: 0.01, + }); expect(transactions).toEqual({ chainID: 'T', @@ -465,7 +462,7 @@ describe('TransactionPairService', () => { options: undefined, receiver: Address.Zero().bech32(), receiverUsername: undefined, - sender: '', + sender: senderAddress, senderUsername: undefined, signature: undefined, value: '5', @@ -478,24 +475,21 @@ describe('TransactionPairService', () => { PairTransactionService, ); - const transaction = await service.swapTokensFixedOutput( - 'erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu', - { - pairAddress: Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), - tokenInID: 'MEX-123456', - tokenOutID: 'EGLD', - amountIn: '5', - amountOut: '5', - }, - ); + const transaction = await service.swapTokensFixedOutput(senderAddress, { + pairAddress: Address.fromHex( + '0000000000000000000000000000000000000000000000000000000000000012', + ).bech32(), + tokenInID: 'MEX-123456', + tokenOutID: 'EGLD', + amountIn: '5', + amountOut: '5', + }); expect(transaction).toEqual({ nonce: 0, value: '0', receiver: Address.Zero().bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -568,7 +562,7 @@ describe('TransactionPairService', () => { PairTransactionService, ); - const transaction = await service.whitelist({ + const transaction = await service.whitelist(senderAddress, { pairAddress: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -581,7 +575,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -603,7 +597,7 @@ describe('TransactionPairService', () => { PairTransactionService, ); - const transaction = await service.removeWhitelist({ + const transaction = await service.removeWhitelist(senderAddress, { pairAddress: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -616,7 +610,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -639,6 +633,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.addTrustedSwapPair( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -653,7 +648,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -676,6 +671,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.removeTrustedSwapPair( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -689,7 +685,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -712,6 +708,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.pause( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -723,7 +720,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -744,6 +741,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.resume( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -755,7 +753,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -776,6 +774,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setStateActiveNoSwaps( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -787,7 +786,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -808,6 +807,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setFeePercents( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -821,7 +821,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -842,6 +842,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setLockingDeadlineEpoch( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -854,7 +855,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -875,6 +876,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setUnlockEpoch( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -887,7 +889,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -908,6 +910,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setLockingScAddress( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -920,7 +923,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -943,6 +946,7 @@ describe('TransactionPairService', () => { ); const transaction = await service.setupFeesCollector( + senderAddress, Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), @@ -954,7 +958,7 @@ describe('TransactionPairService', () => { receiver: Address.fromHex( '0000000000000000000000000000000000000000000000000000000000000012', ).bech32(), - sender: '', + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, diff --git a/src/modules/position-creator/services/position.creator.transaction.ts b/src/modules/position-creator/services/position.creator.transaction.ts index dcfe160ab..278249430 100644 --- a/src/modules/position-creator/services/position.creator.transaction.ts +++ b/src/modules/position-creator/services/position.creator.transaction.ts @@ -2,11 +2,12 @@ import { Address, AddressValue, BigUIntValue, - Interaction, + Token, TokenTransfer, TypedValue, U64Value, -} from '@multiversx/sdk-core/out'; + VariadicValue, +} from '@multiversx/sdk-core'; import { EsdtTokenPayment } from '@multiversx/sdk-exchange'; import { Injectable } from '@nestjs/common'; import BigNumber from 'bignumber.js'; @@ -29,6 +30,7 @@ import { ProxyFarmAbiService } from 'src/modules/proxy/services/proxy-farm/proxy import { EnergyAbiService } from 'src/modules/energy/services/energy.abi.service'; import { WrapAbiService } from 'src/modules/wrapping/services/wrap.abi.service'; import { FarmVersion } from 'src/modules/farm/models/farm.model'; +import { TransactionOptions } from 'src/modules/common/transaction.options'; @Injectable() export class PositionCreatorTransactionService { @@ -75,55 +77,92 @@ export class PositionCreatorTransactionService { swapRoutes[swapRoutes.length - 1], ); - const contract = lockEpochs - ? await this.mxProxy.getLockedTokenPositionCreatorContract() - : await this.mxProxy.getPostitionCreatorContract(); - - let interaction: Interaction; - - if (lockEpochs) { - interaction = contract.methodsExplicit.createPairPosFromSingleToken( - [ - new U64Value(new BigNumber(lockEpochs)), - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ...swapRouteArgs, - ], - ); - } else { - interaction = contract.methodsExplicit.createLpPosFromSingleToken([ - new AddressValue(Address.fromBech32(pairAddress)), - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ...swapRouteArgs, - ]); - } - const gasLimit = gasConfig.positionCreator.singleToken.liquidityPosition + gasConfig.pairs.addLiquidity + gasConfig.pairs.swapTokensFixedInput.withFeeSwap * swapRoutes[0].pairs.length; - interaction = interaction - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID); + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + }); if (payment.tokenIdentifier === mxConfig.EGLDIdentifier) { - interaction = interaction.withValue(new BigNumber(payment.amount)); + transactionOptions.nativeTransferAmount = payment.amount; } else { - interaction = interaction.withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - payment.tokenIdentifier, - new BigNumber(payment.amount), + transactionOptions.tokenTransfers = [ + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + }), + amount: BigInt(payment.amount), + }), + ]; + } + + if (lockEpochs) { + return [ + await this.getLockedSingleTokenPairPositionTransaction( + lockEpochs, + amount0Min, + amount1Min, + swapRouteArgs, + transactionOptions, ), - ); + ]; } - const transaction = interaction.buildTransaction().toPlainObject(); + return [ + await this.getSingleTokenPairPositionTransaction( + pairAddress, + amount0Min, + amount1Min, + swapRouteArgs, + transactionOptions, + ), + ]; + } - return [transaction]; + private async getLockedSingleTokenPairPositionTransaction( + lockEpochs: number, + amount0Min: BigNumber, + amount1Min: BigNumber, + swapRouteArgs: TypedValue[], + transactionOptions: TransactionOptions, + ): Promise { + transactionOptions.function = 'createPairPosFromSingleToken'; + transactionOptions.arguments = [ + new U64Value(new BigNumber(lockEpochs)), + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + VariadicValue.fromItems(...swapRouteArgs), + ]; + + return await this.mxProxy.getLockedTokenPositionCreatorContractTransaction( + transactionOptions, + ); + } + + private async getSingleTokenPairPositionTransaction( + pairAddress: string, + amount0Min: BigNumber, + amount1Min: BigNumber, + swapRouteArgs: TypedValue[], + transactionOptions: TransactionOptions, + ): Promise { + transactionOptions.function = 'createLpPosFromSingleToken'; + transactionOptions.arguments = [ + new AddressValue(Address.newFromBech32(pairAddress)), + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + VariadicValue.fromItems(...swapRouteArgs), + ]; + + return await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); } async createFarmPositionSingleToken( @@ -173,27 +212,6 @@ export class PositionCreatorTransactionService { swapRoutes[swapRoutes.length - 1], ); - const contract = lockEpochs - ? await this.mxProxy.getLockedTokenPositionCreatorContract() - : await this.mxProxy.getPostitionCreatorContract(); - - let endpointArgs: TypedValue[]; - if (lockEpochs) { - endpointArgs = [ - new U64Value(new BigNumber(lockEpochs)), - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ...swapRouteArgs, - ]; - } else { - endpointArgs = [ - new AddressValue(Address.fromBech32(farmAddress)), - new BigUIntValue(amount0Min), - new BigUIntValue(amount1Min), - ...swapRouteArgs, - ]; - } - const gasLimit = gasConfig.positionCreator.singleToken.farmPosition + gasConfig.pairs.addLiquidity + @@ -201,39 +219,98 @@ export class PositionCreatorTransactionService { gasConfig.pairs.swapTokensFixedInput.withFeeSwap * swapRoutes[0].pairs.length; - let interaction = contract.methodsExplicit - .createFarmPosFromSingleToken(endpointArgs) - .withSender(Address.fromBech32(sender)) - .withChainID(mxConfig.chainID) - .withGasLimit(gasLimit); + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'createFarmPosFromSingleToken', + }); if ( payments[0].tokenIdentifier === mxConfig.EGLDIdentifier && payments.length === 1 ) { - interaction = interaction.withValue( - new BigNumber(payments[0].amount), - ); + transactionOptions.nativeTransferAmount = payments[0].amount; } else { payments[0].tokenIdentifier = payments[0].tokenIdentifier === mxConfig.EGLDIdentifier ? wrappedEgldTokenID : payments[0].tokenIdentifier; - interaction = interaction.withMultiESDTNFTTransfer( - payments.map((payment) => - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), + transactionOptions.tokenTransfers = payments.map( + (payment) => + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), + ); + } + + if (lockEpochs) { + transactions.push( + await this.getLockedSingleTokenFarmPositionTransaction( + lockEpochs, + amount0Min, + amount1Min, + swapRouteArgs, + transactionOptions, ), ); + return transactions; } - transactions.push(interaction.buildTransaction().toPlainObject()); + transactions.push( + await this.getSingleTokenFarmPositionTransaction( + farmAddress, + amount0Min, + amount1Min, + swapRouteArgs, + transactionOptions, + ), + ); return transactions; } + private async getSingleTokenFarmPositionTransaction( + farmAddress: string, + amount0Min: BigNumber, + amount1Min: BigNumber, + swapRouteArgs: TypedValue[], + transactionOptions: TransactionOptions, + ): Promise { + transactionOptions.arguments = [ + new AddressValue(Address.newFromBech32(farmAddress)), + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + VariadicValue.fromItems(...swapRouteArgs), + ]; + + return await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); + } + + private async getLockedSingleTokenFarmPositionTransaction( + lockEpochs: number, + amount0Min: BigNumber, + amount1Min: BigNumber, + swapRouteArgs: TypedValue[], + transactionOptions: TransactionOptions, + ): Promise { + transactionOptions.arguments = [ + new U64Value(new BigNumber(lockEpochs)), + new BigUIntValue(amount0Min), + new BigUIntValue(amount1Min), + VariadicValue.fromItems(...swapRouteArgs), + ]; + + return await this.mxProxy.getLockedTokenPositionCreatorContractTransaction( + transactionOptions, + ); + } + async createDualFarmPositionSingleToken( sender: string, stakingProxyAddress: string, @@ -290,8 +367,6 @@ export class PositionCreatorTransactionService { swapRoutes[swapRoutes.length - 1], ); - const contract = await this.mxProxy.getPostitionCreatorContract(); - let gasLimit = gasConfig.positionCreator.singleToken.dualFarmPosition + gasConfig.pairs.addLiquidity + @@ -305,41 +380,47 @@ export class PositionCreatorTransactionService { gasConfig.pairs.swapTokensFixedInput.withFeeSwap * swapRoutes[0].pairs.length; - let interaction = contract.methodsExplicit - .createMetastakingPosFromSingleToken([ - new AddressValue(Address.fromBech32(stakingProxyAddress)), + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'createMetastakingPosFromSingleToken', + arguments: [ + new AddressValue(Address.newFromBech32(stakingProxyAddress)), new BigUIntValue(amount0Min), new BigUIntValue(amount1Min), - ...swapRouteArgs, - ]) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID); + VariadicValue.fromItems(...swapRouteArgs), + ], + }); if ( payments[0].tokenIdentifier === mxConfig.EGLDIdentifier && payments.length === 1 ) { - interaction = interaction.withValue( - new BigNumber(payments[0].amount), - ); + transactionOptions.nativeTransferAmount = payments[0].amount; } else { payments[0].tokenIdentifier = payments[0].tokenIdentifier === mxConfig.EGLDIdentifier ? wrappedEgldTokenID : payments[0].tokenIdentifier; - interaction = interaction.withMultiESDTNFTTransfer( - payments.map((payment) => - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), - ), + transactionOptions.tokenTransfers = payments.map( + (payment) => + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), ); } - transactions.push(interaction.buildTransaction().toPlainObject()); + const transaction = + await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); + + transactions.push(transaction); return transactions; } @@ -387,10 +468,13 @@ export class PositionCreatorTransactionService { gasConfig.pairs.swapTokensFixedInput.withFeeSwap * swapRoute.pairs.length; - const contract = await this.mxProxy.getPostitionCreatorContract(); - let interaction = contract.methodsExplicit - .createFarmStakingPosFromSingleToken([ - new AddressValue(Address.fromBech32(stakingAddress)), + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'createFarmStakingPosFromSingleToken', + arguments: [ + new AddressValue(Address.newFromBech32(stakingAddress)), new BigUIntValue( new BigNumber( swapRoute.intermediaryAmounts[ @@ -398,36 +482,38 @@ export class PositionCreatorTransactionService { ], ), ), - ...multiSwapArgs, - ]) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID); + VariadicValue.fromItems(...multiSwapArgs), + ], + }); if ( payments[0].tokenIdentifier === mxConfig.EGLDIdentifier && payments.length === 1 ) { - interaction = interaction.withValue( - new BigNumber(payments[0].amount), - ); + transactionOptions.nativeTransferAmount = payments[0].amount; } else { payments[0].tokenIdentifier = payments[0].tokenIdentifier === mxConfig.EGLDIdentifier ? wrappedEgldTokenID : payments[0].tokenIdentifier; - interaction = interaction.withMultiESDTNFTTransfer( - payments.map((payment) => - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), - ), + transactionOptions.tokenTransfers = payments.map( + (payment) => + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), ); } - transactions.push(interaction.buildTransaction().toPlainObject()); + const transaction = + await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); + + transactions.push(transaction); return transactions; } @@ -536,37 +622,46 @@ export class PositionCreatorTransactionService { ? gasConfig.positionCreator.dualTokens.farmPositionProxy : gasConfig.positionCreator.dualTokens.farmPosition; - const contract = isLockedToken - ? await this.mxProxy.getLockedTokenPositionCreatorContract() - : await this.mxProxy.getPostitionCreatorContract(); - - const transaction = contract.methodsExplicit - .createFarmPosFromTwoTokens(endpointArgs) - .withMultiESDTNFTTransfer([ - TokenTransfer.fungibleFromBigInteger( - firstPayment.tokenIdentifier, - new BigNumber(firstPayment.amount), - ), - TokenTransfer.metaEsdtFromBigInteger( - secondPayment.tokenIdentifier, - secondPayment.tokenNonce, - new BigNumber(secondPayment.amount), + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'createFarmPosFromTwoTokens', + arguments: endpointArgs, + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: firstPayment.tokenIdentifier, + }), + amount: BigInt(firstPayment.amount), + }), + new TokenTransfer({ + token: new Token({ + identifier: secondPayment.tokenIdentifier, + nonce: BigInt(secondPayment.tokenNonce), + }), + amount: BigInt(secondPayment.amount), + }), + ...payments.slice(2).map( + (payment) => + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), ), - ...payments - .slice(2) - .map((payment) => - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), - ), - ]) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + ], + }); + + const transaction = isLockedToken + ? await this.mxProxy.getLockedTokenPositionCreatorContractTransaction( + transactionOptions, + ) + : await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); transactions.push(transaction); @@ -630,41 +725,48 @@ export class PositionCreatorTransactionService { .multipliedBy(1 - tolerance) .integerValue(); - const contract = await this.mxProxy.getPostitionCreatorContract(); - - const interaction = contract.methodsExplicit - .createMetastakingPosFromTwoTokens([ - new AddressValue(Address.fromBech32(stakingProxyAddress)), + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.positionCreator.dualTokens.dualFarmPosition, + function: 'createMetastakingPosFromTwoTokens', + arguments: [ + new AddressValue(Address.newFromBech32(stakingProxyAddress)), new BigUIntValue(amount0Min), new BigUIntValue(amount1Min), - ]) - .withMultiESDTNFTTransfer([ - TokenTransfer.fungibleFromBigInteger( - firstPayment.tokenIdentifier, - new BigNumber(firstPayment.amount), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: firstPayment.tokenIdentifier, + }), + amount: BigInt(firstPayment.amount), + }), + new TokenTransfer({ + token: new Token({ + identifier: secondPayment.tokenIdentifier, + }), + amount: BigInt(secondPayment.amount), + }), + ...payments.slice(2).map( + (payment) => + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), ), - TokenTransfer.fungibleFromBigInteger( - secondPayment.tokenIdentifier, + ], + }); - new BigNumber(secondPayment.amount), - ), - ...payments - .slice(2) - .map((payment) => - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), - ), - ]) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasConfig.positionCreator.dualTokens.dualFarmPosition) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); - - transactions.push(interaction); + const transaction = + await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); + + transactions.push(transaction); return transactions; } @@ -694,26 +796,30 @@ export class PositionCreatorTransactionService { .multipliedBy(1 - tolerance) .integerValue(); - const contract = await this.mxProxy.getPostitionCreatorContract(); - - return contract.methodsExplicit - .exitFarmPos([ - new AddressValue(Address.fromBech32(farmAddress)), + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.positionCreator.dualTokens.exitFarm, + function: 'exitFarmPos', + arguments: [ + new AddressValue(Address.newFromBech32(farmAddress)), new BigUIntValue(amount0Min), new BigUIntValue(amount1Min), - ]) - .withSingleESDTNFTTransfer( - TokenTransfer.metaEsdtFromBigInteger( - payment.tokenIdentifier, - payment.tokenNonce, - new BigNumber(payment.amount), - ), - ) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasConfig.positionCreator.dualTokens.exitFarm) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + nonce: BigInt(payment.tokenNonce), + }), + amount: BigInt(payment.amount), + }), + ], + }); + + return await this.mxProxy.getPositionCreatorContractTransaction( + transactionOptions, + ); } async createEnergyPosition( @@ -743,31 +849,37 @@ export class PositionCreatorTransactionService { gasConfig.pairs.swapTokensFixedInput.withFeeSwap * swapRoute.pairs.length; - const contract = - await this.mxProxy.getLockedTokenPositionCreatorContract(); - - let interaction = contract.methodsExplicit - .createEnergyPosition([ + const transactionOptions = new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasLimit, + function: 'createEnergyPosition', + arguments: [ new U64Value(new BigNumber(lockEpochs)), new BigUIntValue(amountOutMin), - ...swapRouteArgs, - ]) - .withSender(Address.fromBech32(sender)) - .withGasLimit(gasLimit) - .withChainID(mxConfig.chainID); + VariadicValue.fromItems(...swapRouteArgs), + ], + }); if (payment.tokenIdentifier === mxConfig.EGLDIdentifier) { - interaction = interaction.withValue(new BigNumber(payment.amount)); + transactionOptions.nativeTransferAmount = payment.amount; } else { - interaction = interaction.withSingleESDTTransfer( - TokenTransfer.fungibleFromBigInteger( - payment.tokenIdentifier, - new BigNumber(payment.amount), - ), - ); + transactionOptions.tokenTransfers = [ + new TokenTransfer({ + token: new Token({ + identifier: payment.tokenIdentifier, + }), + amount: BigInt(payment.amount), + }), + ]; } - return [interaction.buildTransaction().toPlainObject()]; + const transaction = + await this.mxProxy.getLockedTokenPositionCreatorContractTransaction( + transactionOptions, + ); + + return [transaction]; } private async getMinimumAmountsForLiquidity( diff --git a/src/modules/router/router.resolver.ts b/src/modules/router/router.resolver.ts index cbae2c9da..a568864fb 100644 --- a/src/modules/router/router.resolver.ts +++ b/src/modules/router/router.resolver.ts @@ -236,6 +236,7 @@ export class RouterResolver { ): Promise { await this.routerService.requireOwner(user.address); return this.routerTransaction.upgradePair( + user.address, firstTokenID, secondTokenID, fees, @@ -248,8 +249,10 @@ export class RouterResolver { @Args('address') address: string, @Args('lpTokenName') lpTokenName: string, @Args('lpTokenTicker') lpTokenTicker: string, + @AuthUser() user: UserAuthResult, ): Promise { return this.routerTransaction.issueLpToken( + user.address, address, lpTokenName, lpTokenTicker, @@ -260,8 +263,9 @@ export class RouterResolver { @Query(() => TransactionModel) async setLocalRoles( @Args('address') address: string, + @AuthUser() user: UserAuthResult, ): Promise { - return this.routerTransaction.setLocalRoles(address); + return this.routerTransaction.setLocalRoles(user.address, address); } @UseGuards(JwtOrNativeAdminGuard) @@ -272,7 +276,7 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.setState(address, enable); + return this.routerTransaction.setState(user.address, address, enable); } @UseGuards(JwtOrNativeAdminGuard) @@ -286,6 +290,7 @@ export class RouterResolver { ): Promise { await this.routerService.requireOwner(user.address); return this.routerTransaction.setFee( + user.address, pairAddress, feeToAddress, feeTokenID, @@ -300,7 +305,10 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.setPairCreationEnabled(enabled); + return this.routerTransaction.setPairCreationEnabled( + user.address, + enabled, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -309,7 +317,9 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.clearPairTemporaryOwnerStorage(); + return this.routerTransaction.clearPairTemporaryOwnerStorage( + user.address, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -319,7 +329,10 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.setTemporaryOwnerPeriod(periodBlocks); + return this.routerTransaction.setTemporaryOwnerPeriod( + user.address, + periodBlocks, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -329,7 +342,10 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.setPairTemplateAddress(address); + return this.routerTransaction.setPairTemplateAddress( + user.address, + address, + ); } @UseGuards(JwtOrNativeAdminGuard) @@ -340,7 +356,7 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.setLocalRolesOwner(args); + return this.routerTransaction.setLocalRolesOwner(user.address, args); } @UseGuards(JwtOrNativeAdminGuard) @@ -351,7 +367,11 @@ export class RouterResolver { @AuthUser() user: UserAuthResult, ): Promise { await this.routerService.requireOwner(user.address); - return this.routerTransaction.removePair(firstTokenID, secondTokenID); + return this.routerTransaction.removePair( + user.address, + firstTokenID, + secondTokenID, + ); } @UseGuards(JwtOrNativeAuthGuard) diff --git a/src/modules/router/services/router.transactions.service.ts b/src/modules/router/services/router.transactions.service.ts index 893527fc1..ca7ded463 100644 --- a/src/modules/router/services/router.transactions.service.ts +++ b/src/modules/router/services/router.transactions.service.ts @@ -5,9 +5,11 @@ import { BigUIntValue, BooleanValue, BytesValue, + Token, TokenIdentifierValue, TokenTransfer, TypedValue, + VariadicValue, } from '@multiversx/sdk-core'; import { Injectable } from '@nestjs/common'; import BigNumber from 'bignumber.js'; @@ -23,6 +25,7 @@ import { SetLocalRoleOwnerArgs } from '../models/router.args'; import { PairAbiService } from 'src/modules/pair/services/pair.abi.service'; import { RouterAbiService } from './router.abi.service'; import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common'; +import { TransactionOptions } from 'src/modules/common/transaction.options'; @Injectable() export class RouterTransactionService { @@ -40,88 +43,104 @@ export class RouterTransactionService { firstTokenID: string, secondTokenID: string, ): Promise { - const checkPairExists = await this.checkPairExists( + const pairAddress = await this.getPairAddressByTokens( firstTokenID, secondTokenID, ); - if (checkPairExists) { + if (pairAddress) { throw new Error('Pair already exists'); } - const contract = await this.mxProxy.getRouterSmartContract(); - - return contract.methodsExplicit - .createPair([ - BytesValue.fromUTF8(firstTokenID), - BytesValue.fromUTF8(secondTokenID), - new AddressValue(Address.fromString(sender)), - ]) - .withGasLimit(gasConfig.router.createPair) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.createPair, + function: 'createPair', + arguments: [ + BytesValue.fromUTF8(firstTokenID), + BytesValue.fromUTF8(secondTokenID), + new AddressValue(Address.newFromBech32(sender)), + ], + }), + ); } async upgradePair( + sender: string, firstTokenID: string, secondTokenID: string, fees: number[], ): Promise { - const checkPairExists = await this.checkPairExists( + const pairAddress = await this.getPairAddressByTokens( firstTokenID, secondTokenID, ); - if (!checkPairExists) { + if (!pairAddress) { throw new Error('Pair does not exist'); } - const contract = await this.mxProxy.getRouterSmartContract(); + const initialLiquidityAdder = await this.pairAbi.initialLiquidityAdder( + pairAddress, + ); + + if (sender !== initialLiquidityAdder) { + throw new Error('Invalid sender address'); + } + const endpointArgs: TypedValue[] = [ BytesValue.fromUTF8(firstTokenID), BytesValue.fromUTF8(secondTokenID), + new AddressValue(Address.newFromBech32(initialLiquidityAdder)), ]; for (const fee of fees) { endpointArgs.push(new BigUIntValue(new BigNumber(fee))); } - return contract.methodsExplicit - .upgradePair(endpointArgs) - .withGasLimit(gasConfig.router.admin.upgradePair) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.upgradePair, + function: 'upgradePair', + arguments: endpointArgs, + }), + ); } async removePair( + sender: string, firstTokenID: string, secondTokenID: string, ): Promise { - const checkPairExists = await this.checkPairExists( + const pairAddress = await this.getPairAddressByTokens( firstTokenID, secondTokenID, ); - if (!checkPairExists) { + if (!pairAddress) { throw new Error('Pair does not exist'); } - const contract = await this.mxProxy.getRouterSmartContract(); - const endpointArgs: TypedValue[] = [ - BytesValue.fromUTF8(firstTokenID), - BytesValue.fromUTF8(secondTokenID), - ]; - return contract.methodsExplicit - .removePair(endpointArgs) - .withGasLimit(gasConfig.router.admin.removePair) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.removePair, + function: 'removePair', + arguments: [ + BytesValue.fromUTF8(firstTokenID), + BytesValue.fromUTF8(secondTokenID), + ], + }), + ); } async issueLpToken( + sender: string, pairAddress: string, lpTokenName: string, lpTokenTicker: string, @@ -131,99 +150,113 @@ export class RouterTransactionService { throw new Error('LP Token already issued'); } - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .issueLpToken([ - new AddressValue(Address.fromString(pairAddress)), - BytesValue.fromUTF8(lpTokenName), - BytesValue.fromUTF8(lpTokenTicker), - ]) - .withValue(constantsConfig.ISSUE_LP_TOKEN_COST) - .withGasLimit(gasConfig.router.issueToken) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.issueToken, + function: 'issueLpToken', + arguments: [ + new AddressValue(Address.newFromBech32(pairAddress)), + BytesValue.fromUTF8(lpTokenName), + BytesValue.fromUTF8(lpTokenTicker), + ], + nativeTransferAmount: BigInt( + constantsConfig.ISSUE_LP_TOKEN_COST, + ).toString(), + }), + ); } - async setLocalRoles(pairAddress: string): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .setLocalRoles([BytesValue.fromHex(new Address(pairAddress).hex())]) - .withGasLimit(gasConfig.router.setLocalRoles) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async setLocalRoles( + sender: string, + pairAddress: string, + ): Promise { + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.setLocalRoles, + function: 'setLocalRoles', + arguments: [BytesValue.fromHex(new Address(pairAddress).hex())], + }), + ); } async setLocalRolesOwner( + sender: string, args: SetLocalRoleOwnerArgs, ): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - const endpointArgs: TypedValue[] = [ - BytesValue.fromUTF8(args.tokenID), - new AddressValue(Address.fromString(args.address)), - ]; - for (const role of args.roles) { - endpointArgs.push(...[new BigUIntValue(new BigNumber(role))]); - } - return contract.methodsExplicit - .setLocalRolesOwner(endpointArgs) - .withGasLimit(gasConfig.router.admin.setLocalRolesOwner) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setLocalRolesOwner, + function: 'setLocalRolesOwner', + arguments: [ + BytesValue.fromUTF8(args.tokenID), + new AddressValue(Address.newFromBech32(args.address)), + VariadicValue.fromItems( + ...args.roles.map( + (role) => new BigUIntValue(new BigNumber(role)), + ), + ), + ], + }), + ); } async setState( + sender: string, address: string, enable: boolean, ): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - const args = [new AddressValue(Address.fromString(address))]; - - const interaction = enable - ? contract.methodsExplicit.resume(args) - : contract.methodsExplicit.pause(args); - - return interaction - .withGasLimit(gasConfig.router.admin.setState) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setState, + function: enable ? 'resume' : 'pause', + arguments: [new AddressValue(Address.newFromBech32(address))], + }), + ); } - async setPairCreationEnabled(enable: boolean): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .setPairCreationEnabled([new BooleanValue(enable)]) - .withGasLimit(gasConfig.router.admin.setPairCreationEnabled) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async setPairCreationEnabled( + sender: string, + enable: boolean, + ): Promise { + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setPairCreationEnabled, + function: 'setPairCreationEnabled', + arguments: [new BooleanValue(enable)], + }), + ); } async setFee( + sender: string, pairAddress: string, feeToAddress: string, feeTokenID: string, enable: boolean, ): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - const args: TypedValue[] = [ - new AddressValue(Address.fromString(pairAddress)), - new AddressValue(Address.fromString(feeToAddress)), - new TokenIdentifierValue(feeTokenID), - ]; - - const interaction = enable - ? contract.methodsExplicit.setFeeOn(args) - : contract.methodsExplicit.setFeeOff(args); - - return interaction - .withGasLimit(gasConfig.router.admin.setFee) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setFee, + function: enable ? 'setFeeOn' : 'setFeeOff', + arguments: [ + new AddressValue(Address.newFromBech32(pairAddress)), + new AddressValue(Address.newFromBech32(feeToAddress)), + new TokenIdentifierValue(feeTokenID), + ], + }), + ); } @ErrorLoggerAsync({ @@ -244,59 +277,69 @@ export class RouterTransactionService { throw new Error('Invalid sender address'); } - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .setSwapEnabledByUser([ - new AddressValue(Address.fromString(pairAddress)), - ]) - .withSingleESDTNFTTransfer( - TokenTransfer.metaEsdtFromBigInteger( - inputTokens.tokenID, - inputTokens.nonce, - new BigNumber(inputTokens.amount), - ), - ) - .withSender(Address.fromString(sender)) - .withGasLimit(gasConfig.router.swapEnableByUser) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.swapEnableByUser, + function: 'setSwapEnabledByUser', + arguments: [ + new AddressValue(Address.newFromBech32(pairAddress)), + ], + tokenTransfers: [ + new TokenTransfer({ + token: new Token({ + identifier: inputTokens.tokenID, + nonce: BigInt(inputTokens.nonce), + }), + amount: BigInt(inputTokens.amount), + }), + ], + }), + ); } - async clearPairTemporaryOwnerStorage(): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .clearPairTemporaryOwnerStorage() - .withGasLimit(gasConfig.router.admin.clearPairTemporaryOwnerStorage) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async clearPairTemporaryOwnerStorage( + sender: string, + ): Promise { + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.clearPairTemporaryOwnerStorage, + function: 'clearPairTemporaryOwnerStorage', + }), + ); } async setTemporaryOwnerPeriod( + sender: string, periodBlocks: string, ): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .setTemporaryOwnerPeriod([ - new BigUIntValue(new BigNumber(periodBlocks)), - ]) - .withGasLimit(gasConfig.router.admin.setTemporaryOwnerPeriod) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setTemporaryOwnerPeriod, + function: 'setTemporaryOwnerPeriod', + arguments: [new BigUIntValue(new BigNumber(periodBlocks))], + }), + ); } - async setPairTemplateAddress(address: string): Promise { - const contract = await this.mxProxy.getRouterSmartContract(); - return contract.methodsExplicit - .setPairTemplateAddress([ - new AddressValue(Address.fromString(address)), - ]) - .withGasLimit(gasConfig.router.admin.setPairTemplateAddress) - .withChainID(mxConfig.chainID) - .buildTransaction() - .toPlainObject(); + async setPairTemplateAddress( + sender: string, + address: string, + ): Promise { + return await this.mxProxy.getRouterSmartContractTransaction( + new TransactionOptions({ + sender: sender, + chainID: mxConfig.chainID, + gasLimit: gasConfig.router.admin.setPairTemplateAddress, + function: 'setPairTemplateAddress', + arguments: [new AddressValue(Address.newFromBech32(address))], + }), + ); } async multiPairSwap( @@ -357,10 +400,10 @@ export class RouterTransactionService { return transactions; } - private async checkPairExists( + private async getPairAddressByTokens( firstTokenID: string, secondTokenID: string, - ): Promise { + ): Promise { const pairsMetadata = await this.routerAbi.pairsMetadata(); for (const pair of pairsMetadata) { if ( @@ -369,10 +412,10 @@ export class RouterTransactionService { (pair.firstTokenID === secondTokenID && pair.secondTokenID === firstTokenID) ) { - return true; + return pair.address; } } - return false; + return undefined; } async wrapIfNeeded( diff --git a/src/modules/router/specs/router.transactions.service.spec.ts b/src/modules/router/specs/router.transactions.service.spec.ts index 72c6e141c..b2cac88d8 100644 --- a/src/modules/router/specs/router.transactions.service.spec.ts +++ b/src/modules/router/specs/router.transactions.service.spec.ts @@ -27,6 +27,9 @@ import { PairFilteringService } from 'src/modules/pair/services/pair.filtering.s describe('RouterService', () => { let module: TestingModule; + const senderAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000001', + ).toBech32(); const ContextGetterServiceProvider = { provide: ContextGetterService, @@ -76,23 +79,57 @@ describe('RouterService', () => { ); const transaction = await service.createPair( - Address.Zero().bech32(), + senderAddress, 'TOK3-3333', 'TOK4-123456', ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, gasLimit: gasConfig.router.createPair, data: encodeTransactionData( - 'createPair@TOK3-3333@TOK4-123456@erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu', + `createPair@TOK3-3333@TOK4-123456@${senderAddress}`, + ), + chainID: mxConfig.chainID, + version: 2, + options: undefined, + signature: undefined, + guardian: undefined, + guardianSignature: undefined, + }); + }); + + it('should get upgrade pair transaction', async () => { + const service = module.get( + RouterTransactionService, + ); + + const transaction = await service.upgradePair( + senderAddress, + 'WEGLD-123456', + 'USDC-123456', + [300, 100], + ); + expect(transaction).toEqual({ + nonce: 0, + value: '0', + receiver: Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000011', + ).toBech32(), + sender: senderAddress, + receiverUsername: undefined, + senderUsername: undefined, + gasPrice: 1000000000, + gasLimit: gasConfig.router.admin.upgradePair, + data: encodeTransactionData( + `upgradePair@WEGLD-123456@USDC-123456@${senderAddress}@300@100`, ), chainID: mxConfig.chainID, version: 2, @@ -109,6 +146,7 @@ describe('RouterService', () => { ); const transaction = await service.issueLpToken( + senderAddress, 'erd1sea63y47u569ns3x5mqjf4vnygn9whkk7p6ry4rfpqyd6rd5addqyd9lf2', 'LiquidityPoolToken3', 'LPT-3333', @@ -116,10 +154,10 @@ describe('RouterService', () => { expect(transaction).toEqual({ nonce: 0, value: '50000000000000000', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -143,9 +181,10 @@ describe('RouterService', () => { try { await service.issueLpToken( - Address.fromHex( + senderAddress, + Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + ).toBech32(), 'LiquidityPoolTokenT1T4', 'EGLDMEXLP-abcdef', ); @@ -159,27 +198,26 @@ describe('RouterService', () => { RouterTransactionService, ); + const pairAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000012', + ).toBech32(); + const transaction = await service.setLocalRoles( - Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + senderAddress, + pairAddress, ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, gasLimit: gasConfig.router.setLocalRoles, - data: encodeTransactionData( - `setLocalRoles@${Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32()}`, - ), + data: encodeTransactionData(`setLocalRoles@${pairAddress}`), chainID: mxConfig.chainID, version: 2, options: undefined, @@ -195,16 +233,17 @@ describe('RouterService', () => { ); const transaction = await service.setState( + senderAddress, 'erd1qqqqqqqqqqqqqpgqe8m9w7cv2ekdc28q5ahku9x3hcregqpn0n4sum0e3u', false, ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -227,26 +266,27 @@ describe('RouterService', () => { ); const transaction = await service.setState( - Address.fromHex( + senderAddress, + Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + ).toBech32(), true, ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, gasLimit: gasConfig.router.admin.setState, data: encodeTransactionData( - `resume@${Address.fromHex( + `resume@${Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32()}`, + ).toBech32()}`, ), chainID: mxConfig.chainID, version: 2, @@ -261,30 +301,29 @@ describe('RouterService', () => { const service = module.get( RouterTransactionService, ); - + const pairAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000012', + ).toBech32(); const transaction = await service.setFee( - Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), - Address.Zero().bech32(), + senderAddress, + pairAddress, + Address.Zero().toBech32(), 'WEGLD-123456', false, ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, gasLimit: gasConfig.router.admin.setFee, data: encodeTransactionData( - `setFeeOff@${Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32()}@erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu@WEGLD-123456`, + `setFeeOff@${pairAddress}@erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu@WEGLD-123456`, ), chainID: mxConfig.chainID, version: 2, @@ -299,11 +338,12 @@ describe('RouterService', () => { const service = module.get( RouterTransactionService, ); - + const pairAddress = Address.newFromHex( + '0000000000000000000000000000000000000000000000000000000000000012', + ).toBech32(); const transaction = await service.setFee( - Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32(), + senderAddress, + pairAddress, Address.Zero().bech32(), 'WEGLD-123456', true, @@ -311,18 +351,16 @@ describe('RouterService', () => { expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, gasLimit: gasConfig.router.admin.setFee, data: encodeTransactionData( - `setFeeOn@${Address.fromHex( - '0000000000000000000000000000000000000000000000000000000000000012', - ).bech32()}@erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu@WEGLD-123456`, + `setFeeOn@${pairAddress}@erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu@WEGLD-123456`, ), chainID: mxConfig.chainID, version: 2, @@ -338,7 +376,7 @@ describe('RouterService', () => { RouterTransactionService, ); - const transaction = await service.setLocalRolesOwner({ + const transaction = await service.setLocalRolesOwner(senderAddress, { tokenID: 'WEGLD-123456', address: Address.Zero().bech32(), roles: [EsdtLocalRole.Mint], @@ -346,10 +384,10 @@ describe('RouterService', () => { expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -372,16 +410,17 @@ describe('RouterService', () => { ); const transaction = await service.removePair( + senderAddress, 'WEGLD-123456', 'USDC-123456', ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -401,14 +440,17 @@ describe('RouterService', () => { RouterTransactionService, ); - const transaction = await service.setPairCreationEnabled(true); + const transaction = await service.setPairCreationEnabled( + senderAddress, + true, + ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -428,14 +470,17 @@ describe('RouterService', () => { RouterTransactionService, ); - const transaction = await service.setPairCreationEnabled(false); + const transaction = await service.setPairCreationEnabled( + senderAddress, + false, + ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -455,14 +500,16 @@ describe('RouterService', () => { RouterTransactionService, ); - const transaction = await service.clearPairTemporaryOwnerStorage(); + const transaction = await service.clearPairTemporaryOwnerStorage( + senderAddress, + ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -483,15 +530,16 @@ describe('RouterService', () => { ); const transaction = await service.setTemporaryOwnerPeriod( + senderAddress, '1000000000000000000000000000000000', ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -514,15 +562,16 @@ describe('RouterService', () => { ); const transaction = await service.setPairTemplateAddress( + senderAddress, Address.Zero().bech32(), ); expect(transaction).toEqual({ nonce: 0, value: '0', - receiver: Address.fromHex( + receiver: Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32(), - sender: '', + ).toBech32(), + sender: senderAddress, receiverUsername: undefined, senderUsername: undefined, gasPrice: 1000000000, @@ -543,9 +592,6 @@ describe('RouterService', () => { const service = module.get( RouterTransactionService, ); - const senderAddress = Address.newFromHex( - '0000000000000000000000000000000000000000000000000000000000000001', - ).toBech32(); const transaction = await service.setSwapEnabledByUser( senderAddress, @@ -566,11 +612,11 @@ describe('RouterService', () => { gasPrice: 1000000000, gasLimit: gasConfig.router.swapEnableByUser, data: encodeTransactionData( - `ESDTNFTTransfer@LKESDT-123456@01@10000000000@${Address.fromHex( + `ESDTNFTTransfer@LKESDT-123456@01@10000000000@${Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000011', - ).bech32()}@setSwapEnabledByUser@${Address.fromHex( + ).toBech32()}@setSwapEnabledByUser@${Address.newFromHex( '0000000000000000000000000000000000000000000000000000000000000013', - ).bech32()}`, + ).toBech32()}`, ), chainID: mxConfig.chainID, version: 2, diff --git a/src/services/multiversx-communication/mx.proxy.service.ts b/src/services/multiversx-communication/mx.proxy.service.ts index d7c0622c5..2ea153bf4 100644 --- a/src/services/multiversx-communication/mx.proxy.service.ts +++ b/src/services/multiversx-communication/mx.proxy.service.ts @@ -75,10 +75,33 @@ export class MXProxyService { ); } + async getRouterSmartContractTransaction( + options: TransactionOptions, + ): Promise { + return this.getSmartContractTransaction( + scAddress.routerAddress, + abiConfig.router, + 'Router', + options, + ); + } + async getPairSmartContract(pairAddress: string): Promise { return this.getSmartContract(pairAddress, abiConfig.pair, 'Pair'); } + async getPairSmartContractTransaction( + pairAddress: string, + options: TransactionOptions, + ): Promise { + return this.getSmartContractTransaction( + pairAddress, + abiConfig.pair, + 'Pair', + options, + ); + } + async getWrapSmartContract(shardID = 1): Promise { return this.getSmartContract( scAddress.wrappingAddress.get(`shardID-${shardID}`), @@ -254,6 +277,17 @@ export class MXProxyService { ); } + async getPositionCreatorContractTransaction( + options: TransactionOptions, + ): Promise { + return this.getSmartContractTransaction( + scAddress.positionCreator, + abiConfig.positionCreator, + 'AutoPosCreator', + options, + ); + } + async getLockedTokenPositionCreatorContract(): Promise { return this.getSmartContract( scAddress.lockedTokenPositionCreator, @@ -262,6 +296,17 @@ export class MXProxyService { ); } + async getLockedTokenPositionCreatorContractTransaction( + options: TransactionOptions, + ): Promise { + return this.getSmartContractTransaction( + scAddress.lockedTokenPositionCreator, + abiConfig.lockedTokenPositionCreator, + 'LockedTokenPosCreatorContract', + options, + ); + } + async getComposableTasksSmartContract(): Promise { return this.getSmartContract( scAddress.composableTasks, @@ -270,6 +315,17 @@ export class MXProxyService { ); } + async getComposableTasksContractTransaction( + options: TransactionOptions, + ): Promise { + return this.getSmartContractTransaction( + scAddress.composableTasks, + abiConfig.composableTasks, + 'ComposableTasksContract', + options, + ); + } + async getSmartContract( contractAddress: string, contractAbiPath: string,