diff --git a/src/multisig/multisigController.spec.ts b/src/multisig/multisigController.spec.ts index be9f37da..5d0b1ee1 100644 --- a/src/multisig/multisigController.spec.ts +++ b/src/multisig/multisigController.spec.ts @@ -1,6 +1,9 @@ import { assert } from "chai"; +import { Account } from "../accounts"; import { Address, CodeMetadata, SmartContractQueryResponse } from "../core"; -import { loadAbiRegistry, MockNetworkProvider } from "../testutils"; +import { GasLimitEstimator } from "../gasEstimator"; +import { ProxyNetworkProvider } from "../networkProviders"; +import { getTestWalletsPath, loadAbiRegistry, loadContractCode, MockNetworkProvider } from "../testutils"; import { MultisigController } from "./multisigController"; import * as resources from "./resources"; @@ -20,6 +23,48 @@ describe("test multisig controller query methods", () => { }); }); + it("should create transaction for deploy multisig contract", async function () { + const alice = await Account.newFromPem(`${getTestWalletsPath()}/alice.pem`); + + const boardMemberOne = Address.newFromBech32("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx"); + const boardMemberTwo = Address.newFromBech32("erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8"); + + const board = [boardMemberOne, boardMemberTwo]; + + const bytecode = await loadContractCode("src/testdata/multisig-full.wasm"); + const abi = await loadAbiRegistry("src/testdata/multisig-full.abi.json"); + + const networkProvider = new ProxyNetworkProvider("https://devnet-gateway.multiversx.com"); + const gasLimitEstimator = new GasLimitEstimator({ networkProvider: networkProvider }); + + const controller = new MultisigController({ + chainID: "D", + networkProvider: networkProvider, + abi: abi, + gasLimitEstimator: gasLimitEstimator, + }); + + alice.nonce = (await networkProvider.getAccount(alice.address)).nonce; + + const transaction = await controller.createTransactionForDeploy(alice, alice.getNonceThenIncrement(), { + bytecode: bytecode, + quorum: 2, + board, + }); + const bytecodeHex = Buffer.from(bytecode).toString("hex"); + assert.equal(transaction.sender.toBech32(), alice.address.toBech32()); + assert.equal(transaction.receiver.toBech32(), "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"); + assert.equal(transaction.value, 0n); + assert.equal(transaction.chainID, "D"); + assert.isTrue(transaction.gasLimit > 0n); + assert.deepEqual( + Buffer.from(transaction.data), + Buffer.from( + `${bytecodeHex}@0500@0504@02@8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8@b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba`, + ), + ); + }); + it("getQuorum returns the quorum value", async function () { networkProvider.mockQueryContractOnFunction( "getQuorum", diff --git a/src/multisig/multisigController.ts b/src/multisig/multisigController.ts index 98a860b6..b919293d 100644 --- a/src/multisig/multisigController.ts +++ b/src/multisig/multisigController.ts @@ -51,6 +51,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.DeployMultisigContractInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForDeploy(sender.address, options); transaction.guardian = options.guardian ?? Address.empty(); @@ -318,6 +319,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeAddBoardMemberInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeAddBoardMember( sender.address, options, @@ -336,6 +338,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeAddProposerInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeAddProposer(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -351,6 +354,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeRemoveUserInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeRemoveUser(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -366,6 +370,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeChangeQuorumInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeChangeQuorum(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -390,6 +395,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ActionInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForSignAction(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -405,6 +411,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ActionInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForPerformAction(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -429,6 +436,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ActionInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForUnsign(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -444,6 +452,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ActionInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForDiscardAction(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -459,6 +468,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.DepositExecuteInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForDeposit(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -474,6 +484,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeTransferExecuteInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeTransferExecute( sender.address, options, @@ -492,6 +503,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeTransferExecuteEsdtInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeTransferExecuteEsdt( sender.address, options, @@ -510,6 +522,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeAsyncCallInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeAsyncCall(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -525,6 +538,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeContractDeployFromSourceInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeContractDeployFromSource( sender.address, options, @@ -543,6 +557,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ProposeContractUpgradeFromSourceInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForProposeContractUpgradeFromSource( sender.address, options, @@ -561,6 +576,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.GroupInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForSignBatch(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -576,6 +592,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.ActionInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForSignAndPerform(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -591,6 +608,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.UnsignForOutdatedBoardMembersInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForUnsignForOutdatedBoardMembers( sender.address, options, @@ -609,6 +627,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.GroupInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForPerformBatch(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); @@ -624,6 +643,7 @@ export class MultisigController extends BaseController { nonce: bigint, options: resources.DiscardBatchInput & BaseControllerInput, ): Promise { + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; const transaction = await this.multisigFactory.createTransactionForDiscardBatch(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); diff --git a/src/smartContracts/smartContractController.spec.ts b/src/smartContracts/smartContractController.spec.ts index 2dc58fe1..4e2c480e 100644 --- a/src/smartContracts/smartContractController.spec.ts +++ b/src/smartContracts/smartContractController.spec.ts @@ -4,7 +4,8 @@ import { Abi, BigUIntValue, BooleanValue, BytesValue, Tuple, U16Value, U64Value import { Account } from "../accounts"; import { Address, SmartContractQueryResponse } from "../core"; import { GasLimitEstimator } from "../gasEstimator"; -import { MockNetworkProvider, getTestWalletsPath, loadAbiRegistry } from "../testutils"; +import { ProxyNetworkProvider } from "../networkProviders"; +import { MockNetworkProvider, getTestWalletsPath, loadAbiRegistry, loadContractCode } from "../testutils"; import { bigIntToBuffer } from "../tokenOperations/codec"; import { SmartContractController } from "./smartContractController"; @@ -276,5 +277,26 @@ describe("test smart contract queries controller", () => { assert.equal(transaction.gasLimit, 123456789n); }); + + it("should estimate gas using gasLimitEstimator", async function () { + const alice = await Account.newFromPem(`${getTestWalletsPath()}/alice.pem`); + const networkProvider = new ProxyNetworkProvider("https://devnet-gateway.multiversx.com"); + + const gasLimitEstimator = new GasLimitEstimator({ networkProvider: networkProvider }); + const controller = new SmartContractController({ + chainID: "D", + networkProvider: networkProvider, + gasLimitEstimator: gasLimitEstimator, + }); + + const bytecode = await loadContractCode("src/testdata/adder.wasm"); + + const transaction = await controller.createTransactionForDeploy(alice, 0n, { + bytecode: bytecode, + arguments: [new BigUIntValue(0)], + }); + + assert.isTrue(transaction.gasLimit > 0n); + }); }); }); diff --git a/src/smartContracts/smartContractController.ts b/src/smartContracts/smartContractController.ts index ea608539..f9274334 100644 --- a/src/smartContracts/smartContractController.ts +++ b/src/smartContracts/smartContractController.ts @@ -48,8 +48,9 @@ export class SmartContractController extends BaseController { nonce: bigint, options: resources.ContractDeployInput & BaseControllerInput, ): Promise { - const transaction = await this.factory.createTransactionForDeploy(sender.address, options); + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; + const transaction = await this.factory.createTransactionForDeploy(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); return transaction; @@ -69,8 +70,9 @@ export class SmartContractController extends BaseController { nonce: bigint, options: resources.ContractUpgradeInput & BaseControllerInput, ): Promise { - const transaction = await this.factory.createTransactionForUpgrade(sender.address, options); + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; + const transaction = await this.factory.createTransactionForUpgrade(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); return transaction; @@ -81,8 +83,9 @@ export class SmartContractController extends BaseController { nonce: bigint, options: resources.ContractExecuteInput & BaseControllerInput, ): Promise { - const transaction = await this.factory.createTransactionForExecute(sender.address, options); + options.gasLimit = options.gasLimit ? options.gasLimit : 0n; + const transaction = await this.factory.createTransactionForExecute(sender.address, options); await this.setupAndSignTransaction(transaction, options, nonce, sender); return transaction; diff --git a/src/smartContracts/smartContractTransactionsFactory.spec.ts b/src/smartContracts/smartContractTransactionsFactory.spec.ts index 2623fd15..7e56c63d 100644 --- a/src/smartContracts/smartContractTransactionsFactory.spec.ts +++ b/src/smartContracts/smartContractTransactionsFactory.spec.ts @@ -40,7 +40,7 @@ describe("test smart contract transactions factory", function () { assert.fail("Expected error was not thrown"); } catch (err) { assert.instanceOf(err, Err); - assert.match(err.message, /Can't convert args to TypedValues/); + assert.match((err as Error).message, /Can't convert args to TypedValues/); } }); @@ -570,7 +570,7 @@ describe("test smart contract transactions factory", function () { assert.fail("Expected error was not thrown"); } catch (err) { assert.instanceOf(err, Err); - assert.match(err.message, /Can't convert args to TypedValues/); + assert.match((err as Error).message, /Can't convert args to TypedValues/); } }); diff --git a/src/transfers/transferTransactionsFactory.spec.ts b/src/transfers/transferTransactionsFactory.spec.ts index a4be2ea1..5b6eb79e 100644 --- a/src/transfers/transferTransactionsFactory.spec.ts +++ b/src/transfers/transferTransactionsFactory.spec.ts @@ -25,7 +25,7 @@ describe("test transfer transactions factory", function () { assert.fail("Expected error was not thrown"); } catch (err) { assert.instanceOf(err, ErrBadUsage); - assert.match(err.message, /No token transfer has been provided/); + assert.match((err as Error).message, /No token transfer has been provided/); } }); @@ -181,7 +181,7 @@ describe("test transfer transactions factory", function () { assert.fail("Expected error was not thrown"); } catch (err) { - assert.match(err.message, /Can't set data field when sending esdt tokens/); + assert.match((err as Error).message, /Can't set data field when sending esdt tokens/); } });