From f1e515b18e64da9a1f3159a255680d491ca7969e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 9 Jun 2023 14:14:31 +0300 Subject: [PATCH 01/16] Sketch support for usernames. --- src/interface.ts | 2 ++ src/proto/serializer.spec.ts | 19 ++++++++++++++++ src/proto/serializer.ts | 4 ++-- src/transaction.spec.ts | 22 ++++++++++++++++++- src/transaction.ts | 42 +++++++++++++++++++++++++++++++++--- 5 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/interface.ts b/src/interface.ts index 290e53d6..4a0c1036 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -13,6 +13,8 @@ export interface IPlainTransactionObject { value: string; receiver: string; sender: string; + receiverUsername?: string; + senderUsername?: string; guardian?: string; gasPrice: number; gasLimit: number; diff --git a/src/proto/serializer.spec.ts b/src/proto/serializer.spec.ts index 0269f5dc..f6da42c5 100644 --- a/src/proto/serializer.spec.ts +++ b/src/proto/serializer.spec.ts @@ -1,4 +1,5 @@ import { assert } from "chai"; +import { Address } from "../address"; import { TransactionVersion } from "../networkParams"; import { Signature } from "../signature"; import { loadTestWallets, TestWallet } from "../testutils"; @@ -99,4 +100,22 @@ describe("serialize transactions", () => { let buffer = serializer.serializeTransaction(transaction); assert.equal(buffer.toString("hex"), "120200001a208049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f82a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1388094ebdc034080f1044a0568656c6c6f520d6c6f63616c2d746573746e657458016240dfa3e9f2fdec60dcb353bac3b3435b4a2ff251e7e98eaf8620f46c731fc70c8ba5615fd4e208b05e75fe0f7dc44b7a99567e29f94fcd91efac7e67b182cd2a04"); }); + + it("with usernames", async () => { + const transaction = new Transaction({ + nonce: 204, + value: "1000000000000000000", + sender: Address.fromBech32("erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8"), + receiver: Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"), + senderUsername: "carol", + receiverUsername: "alice", + gasLimit: 50000, + chainID: "T" + }); + + transaction.applySignature(new Signature("5966dd6b98fc5ecbcd203fa38fac7059ba5c17683099071883b0ad6697386769321d851388a99cb8b81aab625aa2d7e13621432dbd8ab334c5891cd7c7755200")) + + const buffer = serializer.serializeTransaction(transaction); + assert.equal(buffer.toString("hex"), "08cc011209000de0b6b3a76400001a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e12205616c6963652a20b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba32056361726f6c388094ebdc0340d08603520154580162405966dd6b98fc5ecbcd203fa38fac7059ba5c17683099071883b0ad6697386769321d851388a99cb8b81aab625aa2d7e13621432dbd8ab334c5891cd7c7755200"); + }); }); diff --git a/src/proto/serializer.ts b/src/proto/serializer.ts index 448d622e..9868041f 100644 --- a/src/proto/serializer.ts +++ b/src/proto/serializer.ts @@ -25,9 +25,9 @@ export class ProtoSerializer { Nonce: transaction.getNonce().valueOf() ? transaction.getNonce().valueOf() : undefined, Value: this.serializeTransactionValue(transaction.getValue()), RcvAddr: receiverPubkey, - RcvUserName: null, + RcvUserName: transaction.getReceiverUsername() ? Buffer.from(transaction.getReceiverUsername()).toString("base64") : undefined, SndAddr: senderPubkey, - SndUserName: null, + SndUserName: transaction.getSenderUsername() ? Buffer.from(transaction.getSenderUsername()).toString("base64") : undefined, GasPrice: transaction.getGasPrice().valueOf(), GasLimit: transaction.getGasLimit().valueOf(), Data: transaction.getData().length() == 0 ? null : transaction.getData().valueOf(), diff --git a/src/transaction.spec.ts b/src/transaction.spec.ts index 74695c92..52dd1f75 100644 --- a/src/transaction.spec.ts +++ b/src/transaction.spec.ts @@ -1,7 +1,8 @@ import BigNumber from "bignumber.js"; import { assert } from "chai"; +import { Address } from "./address"; import { TransactionOptions, TransactionVersion } from "./networkParams"; -import { loadTestWallets, TestWallet } from "./testutils"; +import { TestWallet, loadTestWallets } from "./testutils"; import { TokenTransfer } from "./tokenTransfer"; import { Transaction } from "./transaction"; import { TransactionPayload } from "./transactionPayload"; @@ -157,6 +158,23 @@ describe("test transaction construction", async () => { assert.isFalse(result.toString().includes("options")); }); + it("with usernames", async () => { + const transaction = new Transaction({ + nonce: 204, + value: "1000000000000000000", + sender: Address.fromBech32("erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8"), + receiver: Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"), + senderUsername: "carol", + receiverUsername: "alice", + gasLimit: 50000, + chainID: "T" + }); + + await wallets.carol.signer.sign(transaction); + assert.equal(transaction.getSignature().toString("hex"), "5966dd6b98fc5ecbcd203fa38fac7059ba5c17683099071883b0ad6697386769321d851388a99cb8b81aab625aa2d7e13621432dbd8ab334c5891cd7c7755200"); + assert.equal(transaction.getHash().toString(), "5728fadbc6c1024c4a0d5552eca44e80c182dc9077e58e31d599cf9496c96d1e"); + }); + it("computes correct fee", () => { let transaction = new Transaction({ nonce: 92, @@ -209,6 +227,8 @@ describe("test transaction construction", async () => { value: "123456789000000000000000000000", sender: sender, receiver: wallets.bob.address, + senderUsername: "alice", + receiverUsername: "bob", gasPrice: minGasPrice, gasLimit: 80000, data: new TransactionPayload("hello"), diff --git a/src/transaction.ts b/src/transaction.ts index d6651967..4d4f2e25 100644 --- a/src/transaction.ts +++ b/src/transaction.ts @@ -39,6 +39,16 @@ export class Transaction { */ private readonly receiver: IAddress; + /** + * The username of the sender. + */ + private senderUsername: string; + + /** + * The username of the receiver. + */ + private receiverUsername: string; + /** * The gas price to be used. */ @@ -97,8 +107,10 @@ export class Transaction { public constructor({ nonce, value, - receiver, sender, + receiver, + senderUsername, + receiverUsername, gasPrice, gasLimit, data, @@ -109,8 +121,10 @@ export class Transaction { }: { nonce?: INonce; value?: ITransactionValue; - receiver: IAddress; sender: IAddress; + receiver: IAddress; + senderUsername?: string; + receiverUsername?: string; gasPrice?: IGasPrice; gasLimit: IGasLimit; data?: ITransactionPayload; @@ -123,6 +137,8 @@ export class Transaction { this.value = value ? new BigNumber(value.toString()).toFixed(0) : 0; this.sender = sender; this.receiver = receiver; + this.senderUsername = senderUsername || ""; + this.receiverUsername = receiverUsername || ""; this.gasPrice = gasPrice || TRANSACTION_MIN_GAS_PRICE; this.gasLimit = gasLimit; this.data = data || new TransactionPayload(); @@ -167,6 +183,22 @@ export class Transaction { return this.receiver; } + getSenderUsername(): string { + return this.senderUsername; + } + + setSenderUsername(senderUsername: string) { + this.senderUsername = senderUsername; + } + + getReceiverUsername(): string { + return this.receiverUsername; + } + + setReceiverUsername(receiverUsername: string) { + this.receiverUsername = receiverUsername; + } + getGuardian(): IAddress { return this.guardian; } @@ -274,11 +306,13 @@ export class Transaction { * This function is called internally within the signing procedure. */ toPlainObject(): IPlainTransactionObject { - const plainObject = { + const plainObject: any = { nonce: this.nonce.valueOf(), value: this.value.toString(), receiver: this.receiver.bech32(), sender: this.sender.bech32(), + senderUsername: this.senderUsername ? Buffer.from(this.senderUsername).toString("base64") : undefined, + receiverUsername: this.receiverUsername ? Buffer.from(this.receiverUsername).toString("base64") : undefined, gasPrice: this.gasPrice.valueOf(), gasLimit: this.gasLimit.valueOf(), data: this.data.length() == 0 ? undefined : this.data.encoded(), @@ -305,7 +339,9 @@ export class Transaction { nonce: Number(plainObjectTransaction.nonce), value: new BigNumber(plainObjectTransaction.value).toFixed(0), receiver: Address.fromString(plainObjectTransaction.receiver), + receiverUsername: plainObjectTransaction.receiverUsername == undefined ? undefined : Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString(), sender: Address.fromString(plainObjectTransaction.sender), + senderUsername: plainObjectTransaction.senderUsername == undefined ? undefined : Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString(), guardian: plainObjectTransaction.guardian == undefined ? undefined : Address.fromString(plainObjectTransaction.guardian || ""), gasPrice: Number(plainObjectTransaction.gasPrice), gasLimit: Number(plainObjectTransaction.gasLimit), From 3e7b6253b9c24fb857827412788281caf1419cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 9 Jun 2023 14:51:08 +0300 Subject: [PATCH 02/16] Support usernames for relayed transactions, as well (V1). --- src/relayedTransactionV1Builder.spec.ts | 43 +++++++++++++++++++++++-- src/relayedTransactionV1Builder.ts | 2 ++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/relayedTransactionV1Builder.spec.ts b/src/relayedTransactionV1Builder.spec.ts index fde0d73b..3d6cb476 100644 --- a/src/relayedTransactionV1Builder.spec.ts +++ b/src/relayedTransactionV1Builder.spec.ts @@ -4,15 +4,16 @@ import * as errors from "./errors"; import { TransactionOptions, TransactionVersion } from "./networkParams"; import { RelayedTransactionV1Builder } from "./relayedTransactionV1Builder"; import { Signature } from "./signature"; -import { loadTestWallets, TestWallet } from "./testutils"; +import { TestWallet, loadTestWallets } from "./testutils"; +import { TokenTransfer } from "./tokenTransfer"; import { Transaction } from "./transaction"; import { TransactionPayload } from "./transactionPayload"; describe("test relayed v1 transaction builder", function () { - let alice: TestWallet, bob: TestWallet, grace: TestWallet, frank: TestWallet; + let alice: TestWallet, bob: TestWallet, carol: TestWallet, grace: TestWallet, frank: TestWallet; before(async function () { - ({ alice, bob, grace, frank } = await loadTestWallets()); + ({ alice, bob, carol, grace, frank } = await loadTestWallets()); }); it("should throw exception if args were not set", async function () { @@ -77,6 +78,42 @@ describe("test relayed v1 transaction builder", function () { assert.equal(relayedTxV1.getSignature().toString("hex"), "c7d2c3b971f44eca676c10624d3c4319f8898af159f003e1e59f446cb75e5a294c9f0758d800e04d3daff11e67d20c4c1f85fd54aad6deb947ef391e6dd09d07"); }); + it("should compute relayed v1 transaction (with usernames)", async function () { + const networkConfig = { + MinGasLimit: 50_000, + GasPerDataByte: 1_500, + GasPriceModifier: 0.01, + ChainID: "T" + }; + + const innerTx = new Transaction({ + nonce: 208, + value: TokenTransfer.egldFromAmount(1), + sender: carol.address, + receiver: alice.address, + senderUsername: "carol", + receiverUsername: "alice", + gasLimit: 50000, + chainID: networkConfig.ChainID + }); + + await carol.signer.sign(innerTx); + + const builder = new RelayedTransactionV1Builder(); + const relayedTxV1 = builder + .setInnerTransaction(innerTx) + .setRelayerNonce(715) + .setNetworkConfig(networkConfig) + .setRelayerAddress(frank.address) + .build(); + + await frank.signer.sign(relayedTxV1); + + assert.equal(relayedTxV1.getNonce().valueOf(), 715); + assert.equal(relayedTxV1.getData().toString(), "relayedTx@7b226e6f6e6365223a3230382c2273656e646572223a227371455656633553486b6c45344a717864556e59573068397a536249533141586f3534786f32634969626f3d222c227265636569766572223a2241546c484c76396f686e63616d433877673970645168386b77704742356a6949496f3349484b594e6165453d222c2276616c7565223a313030303030303030303030303030303030302c226761735072696365223a313030303030303030302c226761734c696d6974223a35303030302c2264617461223a22222c227369676e6174757265223a22744d616d736b6f315a574b526663594e4b5673793463797879643335764b754844576a3548706172344167734c2b4a4e585642545a574c754467384867514254476d724a6b49443133637050614c55322f38626644513d3d222c22636861696e4944223a2256413d3d222c2276657273696f6e223a312c22736e64557365724e616d65223a22593246796232773d222c22726376557365724e616d65223a22595778705932553d227d"); + assert.equal(relayedTxV1.getSignature().toString("hex"), "0fbab023085551b7c497e5c52f64df802cb518ebaac93f8897e5cca25a8aff447565fa96570f7b547f7c0d0fceb2c7d12bcb5f37fa92c79725d9b2c69039f00d"); + }); + it("should compute guarded inner Tx - relayed v1 transaction", async function () { const networkConfig = { MinGasLimit: 50_000, diff --git a/src/relayedTransactionV1Builder.ts b/src/relayedTransactionV1Builder.ts index ad4ec2bc..2e690e22 100644 --- a/src/relayedTransactionV1Builder.ts +++ b/src/relayedTransactionV1Builder.ts @@ -141,6 +141,8 @@ export class RelayedTransactionV1Builder { "options": this.innerTransaction.getOptions().valueOf() == 0 ? undefined : this.innerTransaction.getOptions().valueOf(), "guardian": this.innerTransaction.getGuardian().bech32() ? new Address(this.innerTransaction.getGuardian().bech32()).pubkey().toString("base64") : undefined, "guardianSignature": this.innerTransaction.getGuardianSignature().toString("hex") ? this.innerTransaction.getGuardianSignature().toString("base64") : undefined, + "sndUserName": this.innerTransaction.getSenderUsername() ? Buffer.from(this.innerTransaction.getSenderUsername()).toString("base64") : undefined, + "rcvUserName": this.innerTransaction.getReceiverUsername() ? Buffer.from(this.innerTransaction.getReceiverUsername()).toString("base64") : undefined, }; return JSON.stringify(txObject); From b921a118652c88e6ab44c7b059200ac0eca62db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 9 Jun 2023 17:21:26 +0300 Subject: [PATCH 03/16] Add toggle global burn. --- .../tokenOperationsFactory.test.net.spec.ts | 53 ++++++++++++++++++- src/tokenOperations/tokenOperationsFactory.ts | 41 ++++++++++++++ .../tokenOperationsFactoryConfig.ts | 2 + .../tokenOperationsOutcomeParser.ts | 8 +++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts index 0c18aa95..aa8ed867 100644 --- a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts +++ b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts @@ -1,8 +1,8 @@ import { assert } from "chai"; import { GasEstimator } from "../gasEstimator"; import { INetworkConfig, ITransactionOnNetwork } from "../interfaceOfNetwork"; -import { loadTestWallets, TestWallet } from "../testutils"; -import { createTestnetProvider, INetworkProvider } from "../testutils/networkProviders"; +import { TestWallet, loadTestWallets } from "../testutils"; +import { INetworkProvider, createTestnetProvider } from "../testutils/networkProviders"; import { TokenTransfer } from "../tokenTransfer"; import { Transaction } from "../transaction"; import { TransactionWatcher } from "../transactionWatcher"; @@ -33,6 +33,55 @@ describe("test factory on testnet", function () { transferTransactionsFactory = new TransferTransactionsFactory(new GasEstimator()); }); + it.only("should issue fungible, then toggle global burn", async function () { + this.timeout(180000); + await frank.sync(provider); + await grace.sync(provider); + + // Issue + const tx1 = factory.issueFungible({ + issuer: frank.address, + tokenName: "FRANK", + tokenTicker: "FRANK", + initialSupply: 100, + numDecimals: 0, + canFreeze: true, + canWipe: true, + canPause: true, + canMint: true, + canBurn: true, + canChangeOwner: true, + canUpgrade: true, + canAddSpecialRoles: true, + transactionNonce: frank.account.nonce + }); + + const tx1OnNetwork = await processTransaction(frank, tx1, "tx1"); + const tx1Outcome = parser.parseIssueFungible(tx1OnNetwork); + const tokenIdentifier = tx1Outcome.tokenIdentifier; + assert.isTrue(tokenIdentifier.includes("FRANK")); + + // Unset global burn + const tx2 = factory.unsetBurnRoleGlobally({ + manager: frank.address, + tokenIdentifier: tx1Outcome.tokenIdentifier, + transactionNonce: frank.account.nonce + }); + + const tx2OnNetwork = await processTransaction(frank, tx2, "tx2"); + const _tx2Outcome = parser.parseToggleBurnRoleGlobally(tx2OnNetwork); + + // Set global burn + const tx3 = factory.setBurnRoleGlobally({ + manager: frank.address, + tokenIdentifier: tx1Outcome.tokenIdentifier, + transactionNonce: frank.account.nonce + }); + + const tx3OnNetwork = await processTransaction(frank, tx3, "tx3"); + const _tx3Outcome = parser.parseToggleBurnRoleGlobally(tx3OnNetwork); + }); + it("should issue fungible, mint, burn", async function () { this.timeout(120000); await frank.sync(provider); diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index 1d746c1a..57cdab39 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -25,6 +25,8 @@ interface IConfig { gasLimitStorePerByte: IGasLimit; issueCost: BigNumber.Value; esdtContractAddress: IAddress; + + gasLimitToggleBurnRoleGlobally: IGasLimit; } interface IBaseArgs { @@ -70,6 +72,11 @@ interface IRegisterMetaESDT extends IIssueSemiFungibleArgs { numDecimals: number; } +interface IToggleBurnRoleGloballyArgs extends IBaseArgs { + manager: IAddress; + tokenIdentifier: string; +} + interface IFungibleSetSpecialRoleArgs extends IBaseArgs { manager: IAddress; user: IAddress; @@ -279,6 +286,40 @@ export class TokenOperationsFactory { }); } + setBurnRoleGlobally(args: IToggleBurnRoleGloballyArgs): Transaction { + const parts = [ + "setBurnRoleGlobally", + utf8ToHex(args.tokenIdentifier) + ]; + + return this.createTransaction({ + sender: args.manager, + receiver: this.config.esdtContractAddress, + nonce: args.transactionNonce, + gasPrice: args.gasPrice, + gasLimitHint: args.gasLimit, + executionGasLimit: this.config.gasLimitToggleBurnRoleGlobally, + dataParts: parts + }); + } + + unsetBurnRoleGlobally(args: IToggleBurnRoleGloballyArgs): Transaction { + const parts = [ + "unsetBurnRoleGlobally", + utf8ToHex(args.tokenIdentifier) + ]; + + return this.createTransaction({ + sender: args.manager, + receiver: this.config.esdtContractAddress, + nonce: args.transactionNonce, + gasPrice: args.gasPrice, + gasLimitHint: args.gasLimit, + executionGasLimit: this.config.gasLimitToggleBurnRoleGlobally, + dataParts: parts + }); + } + setSpecialRoleOnFungible(args: IFungibleSetSpecialRoleArgs): Transaction { const parts = [ "setSpecialRole", diff --git a/src/tokenOperations/tokenOperationsFactoryConfig.ts b/src/tokenOperations/tokenOperationsFactoryConfig.ts index e7be85e5..452c3b8f 100644 --- a/src/tokenOperations/tokenOperationsFactoryConfig.ts +++ b/src/tokenOperations/tokenOperationsFactoryConfig.ts @@ -22,6 +22,8 @@ export class TokenOperationsFactoryConfig { issueCost: BigNumber.Value = "50000000000000000"; esdtContractAddress: IAddress = Address.fromBech32("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"); + gasLimitToggleBurnRoleGlobally: IGasLimit = 60000000; + constructor(chainID: IChainID) { this.chainID = chainID; } diff --git a/src/tokenOperations/tokenOperationsOutcomeParser.ts b/src/tokenOperations/tokenOperationsOutcomeParser.ts index c988bb24..3d5be5bc 100644 --- a/src/tokenOperations/tokenOperationsOutcomeParser.ts +++ b/src/tokenOperations/tokenOperationsOutcomeParser.ts @@ -37,6 +37,9 @@ export interface IESDTIssueOutcome { tokenIdentifier: string; } +export interface IToggleBurnRoleGloballyOutcome { +} + export interface ISetSpecialRoleOutcome { userAddress: string; tokenIdentifier: string; @@ -131,6 +134,11 @@ export class TokenOperationsOutcomeParser { return { tokenIdentifier: tokenIdentifier }; } + parseToggleBurnRoleGlobally(transaction: ITransactionOnNetwork): IToggleBurnRoleGloballyOutcome { + this.ensureNoError(transaction); + return {}; + } + parseSetSpecialRole(transaction: ITransactionOnNetwork): ISetSpecialRoleOutcome { this.ensureNoError(transaction); From ad8a54c79f23c13089794322bfc2ff868769d2a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Sun, 11 Jun 2023 21:08:01 +0300 Subject: [PATCH 04/16] Two separate functions on parser. --- .../tokenOperationsFactory.test.net.spec.ts | 4 ++-- src/tokenOperations/tokenOperationsOutcomeParser.ts | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts index aa8ed867..a051a8ef 100644 --- a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts +++ b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts @@ -69,7 +69,7 @@ describe("test factory on testnet", function () { }); const tx2OnNetwork = await processTransaction(frank, tx2, "tx2"); - const _tx2Outcome = parser.parseToggleBurnRoleGlobally(tx2OnNetwork); + const _tx2Outcome = parser.parseUnsetBurnRoleGlobally(tx2OnNetwork); // Set global burn const tx3 = factory.setBurnRoleGlobally({ @@ -79,7 +79,7 @@ describe("test factory on testnet", function () { }); const tx3OnNetwork = await processTransaction(frank, tx3, "tx3"); - const _tx3Outcome = parser.parseToggleBurnRoleGlobally(tx3OnNetwork); + const _tx3Outcome = parser.parseSetBurnRoleGlobally(tx3OnNetwork); }); it("should issue fungible, mint, burn", async function () { diff --git a/src/tokenOperations/tokenOperationsOutcomeParser.ts b/src/tokenOperations/tokenOperationsOutcomeParser.ts index 3d5be5bc..523d0702 100644 --- a/src/tokenOperations/tokenOperationsOutcomeParser.ts +++ b/src/tokenOperations/tokenOperationsOutcomeParser.ts @@ -134,7 +134,12 @@ export class TokenOperationsOutcomeParser { return { tokenIdentifier: tokenIdentifier }; } - parseToggleBurnRoleGlobally(transaction: ITransactionOnNetwork): IToggleBurnRoleGloballyOutcome { + parseSetBurnRoleGlobally(transaction: ITransactionOnNetwork): IToggleBurnRoleGloballyOutcome { + this.ensureNoError(transaction); + return {}; + } + + parseUnsetBurnRoleGlobally(transaction: ITransactionOnNetwork): IToggleBurnRoleGloballyOutcome { this.ensureNoError(transaction); return {}; } From 121984510a1eab9858516c173c5ef52c10e40bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 11:48:17 +0300 Subject: [PATCH 05/16] Add "registerAndSetAllRoles". --- .../tokenOperationsFactory.test.net.spec.ts | 91 ++++++++++++++++++- src/tokenOperations/tokenOperationsFactory.ts | 31 +++++++ .../tokenOperationsOutcomeParser.ts | 17 ++++ 3 files changed, 137 insertions(+), 2 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts index a051a8ef..f434fd7f 100644 --- a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts +++ b/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts @@ -33,10 +33,97 @@ describe("test factory on testnet", function () { transferTransactionsFactory = new TransferTransactionsFactory(new GasEstimator()); }); - it.only("should issue fungible, then toggle global burn", async function () { + it("should register and set all roles (FNG)", async function () { + this.timeout(120000); + await frank.sync(provider); + + const tx1 = factory.registerAndSetAllRoles({ + issuer: frank.address, + tokenName: "TEST", + tokenTicker: "TEST", + tokenType: "FNG", + numDecimals: 2, + transactionNonce: frank.account.nonce + }); + + const tx1OnNetwork = await processTransaction(frank, tx1, "tx1"); + const tx1Outcome = parser.parseRegisterAndSetAllRoles(tx1OnNetwork); + + assert.isTrue(tx1Outcome.tokenIdentifier.includes("TEST")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleLocalMint")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleLocalBurn")); + }); + + it("should register and set all roles (NFT)", async function () { + this.timeout(120000); + await frank.sync(provider); + + const tx1 = factory.registerAndSetAllRoles({ + issuer: frank.address, + tokenName: "TEST", + tokenTicker: "TEST", + tokenType: "NFT", + numDecimals: 0, + transactionNonce: frank.account.nonce + }); + + const tx1OnNetwork = await processTransaction(frank, tx1, "tx1"); + const tx1Outcome = parser.parseRegisterAndSetAllRoles(tx1OnNetwork); + + assert.isTrue(tx1Outcome.tokenIdentifier.includes("TEST")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTCreate")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTBurn")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTUpdateAttributes")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTAddURI")); + }); + + it("should register and set all roles (SFT)", async function () { + this.timeout(120000); + await frank.sync(provider); + + const tx1 = factory.registerAndSetAllRoles({ + issuer: frank.address, + tokenName: "TEST", + tokenTicker: "TEST", + tokenType: "SFT", + numDecimals: 0, + transactionNonce: frank.account.nonce + }); + + const tx1OnNetwork = await processTransaction(frank, tx1, "tx1"); + const tx1Outcome = parser.parseRegisterAndSetAllRoles(tx1OnNetwork); + + assert.isTrue(tx1Outcome.tokenIdentifier.includes("TEST")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTCreate")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTBurn")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTAddQuantity")); + }); + + it("should register and set all roles (META)", async function () { + this.timeout(120000); + await frank.sync(provider); + + const tx1 = factory.registerAndSetAllRoles({ + issuer: frank.address, + tokenName: "TEST", + tokenTicker: "TEST", + tokenType: "META", + numDecimals: 2, + transactionNonce: frank.account.nonce + }); + + const tx1OnNetwork = await processTransaction(frank, tx1, "tx1"); + const tx1Outcome = parser.parseRegisterAndSetAllRoles(tx1OnNetwork); + + assert.isTrue(tx1Outcome.tokenIdentifier.includes("TEST")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTCreate")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTBurn")); + assert.isTrue(tx1Outcome.roles.includes("ESDTRoleNFTAddQuantity")); + }); + + it("should issue fungible, then toggle global burn", async function () { this.timeout(180000); await frank.sync(provider); - await grace.sync(provider); // Issue const tx1 = factory.issueFungible({ diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index 57cdab39..95efb7a5 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -72,6 +72,16 @@ interface IRegisterMetaESDT extends IIssueSemiFungibleArgs { numDecimals: number; } +interface IRegisterAndSetAllRoles extends IBaseArgs { + issuer: IAddress; + tokenName: string; + tokenTicker: string; + tokenType: RegisterAndSetAllRolesTokenType; + numDecimals: number; +} + +type RegisterAndSetAllRolesTokenType = "NFT" | "SFT" | "META" | "FNG"; + interface IToggleBurnRoleGloballyArgs extends IBaseArgs { manager: IAddress; tokenIdentifier: string; @@ -286,6 +296,27 @@ export class TokenOperationsFactory { }); } + registerAndSetAllRoles(args: IRegisterAndSetAllRoles): Transaction { + const parts = [ + "registerAndSetAllRoles", + utf8ToHex(args.tokenName), + utf8ToHex(args.tokenTicker), + utf8ToHex(args.tokenType), + bigIntToHex(args.numDecimals) + ]; + + return this.createTransaction({ + sender: args.issuer, + receiver: this.config.esdtContractAddress, + nonce: args.transactionNonce, + value: this.config.issueCost, + gasPrice: args.gasPrice, + gasLimitHint: args.gasLimit, + executionGasLimit: this.config.gasLimitIssue, + dataParts: parts + }); + } + setBurnRoleGlobally(args: IToggleBurnRoleGloballyArgs): Transaction { const parts = [ "setBurnRoleGlobally", diff --git a/src/tokenOperations/tokenOperationsOutcomeParser.ts b/src/tokenOperations/tokenOperationsOutcomeParser.ts index 523d0702..260ffb3d 100644 --- a/src/tokenOperations/tokenOperationsOutcomeParser.ts +++ b/src/tokenOperations/tokenOperationsOutcomeParser.ts @@ -37,6 +37,11 @@ export interface IESDTIssueOutcome { tokenIdentifier: string; } +export interface IRegisterAndSetAllRolesOutcome { + tokenIdentifier: string; + roles: string[]; +} + export interface IToggleBurnRoleGloballyOutcome { } @@ -134,6 +139,18 @@ export class TokenOperationsOutcomeParser { return { tokenIdentifier: tokenIdentifier }; } + parseRegisterAndSetAllRoles(transaction: ITransactionOnNetwork): IRegisterAndSetAllRolesOutcome { + this.ensureNoError(transaction); + + const eventRegister = this.findSingleEventByIdentifier(transaction, "registerAndSetAllRoles"); + const tokenIdentifier = this.extractTokenIdentifier(eventRegister); + + const eventSetRole = this.findSingleEventByIdentifier(transaction, "ESDTSetRole"); + const roles = eventSetRole.topics.slice(3).map(topic => topic.valueOf().toString()); + + return { tokenIdentifier, roles }; + } + parseSetBurnRoleGlobally(transaction: ITransactionOnNetwork): IToggleBurnRoleGloballyOutcome { this.ensureNoError(transaction); return {}; From 2b4b9084c7ab0cd6e4ba278d19787b831dc2e8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 12:00:28 +0300 Subject: [PATCH 06/16] Remove (actually, only deprecate for now): "canBurn" and "canMint". --- src/tokenOperations/tokenOperationsFactory.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index 95efb7a5..abc7a383 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -45,11 +45,19 @@ interface IIssueFungibleArgs extends IBaseArgs { canFreeze: boolean; canWipe: boolean; canPause: boolean; - canMint: boolean; - canBurn: boolean; canChangeOwner: boolean; canUpgrade: boolean; canAddSpecialRoles: boolean; + + /** + * @deprecated (not used anymore) + */ + canMint?: boolean; + + /** + * @deprecated (not used anymore) + */ + canBurn?: boolean; } interface IIssueSemiFungibleArgs extends IBaseArgs { @@ -198,8 +206,6 @@ export class TokenOperationsFactory { ...(args.canFreeze ? [utf8ToHex("canFreeze"), this.trueAsHex] : []), ...(args.canWipe ? [utf8ToHex("canWipe"), this.trueAsHex] : []), ...(args.canPause ? [utf8ToHex("canPause"), this.trueAsHex] : []), - ...(args.canMint ? [utf8ToHex("canMint"), this.trueAsHex] : []), - ...(args.canBurn ? [utf8ToHex("canBurn"), this.trueAsHex] : []), ...(args.canChangeOwner ? [utf8ToHex("canChangeOwner"), this.trueAsHex] : []), ...(args.canUpgrade ? [utf8ToHex("canUpgrade"), this.trueAsHex] : []), ...(args.canAddSpecialRoles ? [utf8ToHex("canAddSpecialRoles"), this.trueAsHex] : []), From 4e5b464b6455b08d44de841f96c04a69b3b218a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 12:02:10 +0300 Subject: [PATCH 07/16] Fix test. --- src/tokenOperations/tokenOperationsFactory.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.spec.ts b/src/tokenOperations/tokenOperationsFactory.spec.ts index 6010019a..bd8e85c8 100644 --- a/src/tokenOperations/tokenOperationsFactory.spec.ts +++ b/src/tokenOperations/tokenOperationsFactory.spec.ts @@ -22,15 +22,13 @@ describe("test factory", () => { canFreeze: true, canWipe: true, canPause: true, - canMint: true, - canBurn: true, canChangeOwner: true, canUpgrade: true, canAddSpecialRoles: true, transactionNonce: 42 }); - assert.equal(transaction.getData().toString(), "issue@4652414e4b@4652414e4b@64@@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4d696e74@74727565@63616e4275726e@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565") + assert.equal(transaction.getData().toString(), "issue@4652414e4b@4652414e4b@64@@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565") assert.equal(transaction.getNonce(), 42); assert.equal(transaction.getSender().toString(), frank.address.toString()); assert.equal(transaction.getReceiver().toString(), "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"); From aa8308d2dbbe0d6cc1eb1d3c945c7370325775e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 12:32:38 +0300 Subject: [PATCH 08/16] Warn about unsetting burn role globally. --- src/tokenOperations/tokenOperationsFactory.ts | 27 ++++++++++++++++++- .../tokenOperationsFactoryConfig.ts | 3 ++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index abc7a383..d16d46f8 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -12,6 +12,7 @@ interface IConfig { minGasLimit: IGasLimit; gasLimitPerByte: IGasLimit; gasLimitIssue: IGasLimit; + gasLimitToggleBurnRoleGlobally: IGasLimit; gasLimitESDTLocalMint: IGasLimit; gasLimitESDTLocalBurn: IGasLimit; gasLimitSetSpecialRole: IGasLimit; @@ -26,7 +27,7 @@ interface IConfig { issueCost: BigNumber.Value; esdtContractAddress: IAddress; - gasLimitToggleBurnRoleGlobally: IGasLimit; + shouldWarnAboutUnsettingBurnRoleGlobally: boolean; } interface IBaseArgs { @@ -197,6 +198,8 @@ export class TokenOperationsFactory { } issueFungible(args: IIssueFungibleArgs): Transaction { + this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + const parts = [ "issue", utf8ToHex(args.tokenName), @@ -223,7 +226,23 @@ export class TokenOperationsFactory { }); } + private warnAboutUnsettingBurnRoleGloballyIfAppropriate() { + if (!this.config.shouldWarnAboutUnsettingBurnRoleGlobally) { + return; + } + + console.warn(` +========== +IMPORTANT! +========== +You are about to issue (register) a new token. +By default, this will set the role "ESDTRoleBurnForAll" (globally). +Once the token is registered, you can unset this role by calling "unsetBurnRoleGlobally" (in a separate transaction).`); + } + issueSemiFungible(args: IIssueSemiFungibleArgs): Transaction { + this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + const parts = [ "issueSemiFungible", utf8ToHex(args.tokenName), @@ -250,6 +269,8 @@ export class TokenOperationsFactory { } issueNonFungible(args: IIssueNonFungibleArgs): Transaction { + this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + const parts = [ "issueNonFungible", utf8ToHex(args.tokenName), @@ -276,6 +297,8 @@ export class TokenOperationsFactory { } registerMetaESDT(args: IRegisterMetaESDT): Transaction { + this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + const parts = [ "registerMetaESDT", utf8ToHex(args.tokenName), @@ -303,6 +326,8 @@ export class TokenOperationsFactory { } registerAndSetAllRoles(args: IRegisterAndSetAllRoles): Transaction { + this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + const parts = [ "registerAndSetAllRoles", utf8ToHex(args.tokenName), diff --git a/src/tokenOperations/tokenOperationsFactoryConfig.ts b/src/tokenOperations/tokenOperationsFactoryConfig.ts index 452c3b8f..7c8cf3c2 100644 --- a/src/tokenOperations/tokenOperationsFactoryConfig.ts +++ b/src/tokenOperations/tokenOperationsFactoryConfig.ts @@ -8,6 +8,7 @@ export class TokenOperationsFactoryConfig { minGasLimit = 50000; gasLimitPerByte = 1500; gasLimitIssue: IGasLimit = 60000000; + gasLimitToggleBurnRoleGlobally: IGasLimit = 60000000; gasLimitESDTLocalMint: IGasLimit = 300000; gasLimitESDTLocalBurn: IGasLimit = 300000; gasLimitSetSpecialRole: IGasLimit = 60000000; @@ -22,7 +23,7 @@ export class TokenOperationsFactoryConfig { issueCost: BigNumber.Value = "50000000000000000"; esdtContractAddress: IAddress = Address.fromBech32("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"); - gasLimitToggleBurnRoleGlobally: IGasLimit = 60000000; + shouldWarnAboutUnsettingBurnRoleGlobally: boolean = true; constructor(chainID: IChainID) { this.chainID = chainID; From 767913d85c869335f08892bdd0f869c19c179b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 12:37:23 +0300 Subject: [PATCH 09/16] Add more tests, bump version. --- package-lock.json | 4 ++-- package.json | 2 +- .../tokenOperationsFactory.spec.ts | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30e00170..97e9fd4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@multiversx/sdk-core", - "version": "12.2.1", + "version": "12.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@multiversx/sdk-core", - "version": "12.2.1", + "version": "12.3.0", "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", diff --git a/package.json b/package.json index 8a6cbaf9..f3f5a6cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-core", - "version": "12.2.1", + "version": "12.3.0", "description": "MultiversX SDK for JavaScript and TypeScript", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/tokenOperations/tokenOperationsFactory.spec.ts b/src/tokenOperations/tokenOperationsFactory.spec.ts index bd8e85c8..f7257b6d 100644 --- a/src/tokenOperations/tokenOperationsFactory.spec.ts +++ b/src/tokenOperations/tokenOperationsFactory.spec.ts @@ -12,6 +12,22 @@ describe("test factory", () => { factory = new TokenOperationsFactory(new TokenOperationsFactoryConfig("T")); }); + it("should create ", () => { + const transaction = factory.registerAndSetAllRoles({ + issuer: frank.address, + tokenName: "TEST", + tokenTicker: "TEST", + tokenType: "FNG", + numDecimals: 2, + transactionNonce: 42 + }); + + assert.equal(transaction.getData().toString(), "registerAndSetAllRoles@54455354@54455354@464e47@02") + assert.equal(transaction.getNonce(), 42); + assert.equal(transaction.getSender().toString(), frank.address.toString()); + assert.equal(transaction.getReceiver().toString(), "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"); + }); + it("should create ", () => { const transaction = factory.issueFungible({ issuer: frank.address, From 068cb198d901aec2ca3501a5e08a91f1aed26f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 12:46:32 +0300 Subject: [PATCH 10/16] Fix notification. --- src/tokenOperations/tokenOperationsFactory.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index d16d46f8..0a652951 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -235,8 +235,7 @@ export class TokenOperationsFactory { ========== IMPORTANT! ========== -You are about to issue (register) a new token. -By default, this will set the role "ESDTRoleBurnForAll" (globally). +You are about to issue (register) a new token. This will set the role "ESDTRoleBurnForAll" (globally). Once the token is registered, you can unset this role by calling "unsetBurnRoleGlobally" (in a separate transaction).`); } From e5d353395e737c27c82865e6fdb7107d57cfe306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Mon, 12 Jun 2023 16:01:06 +0300 Subject: [PATCH 11/16] Fix after review. --- src/tokenOperations/tokenOperationsFactory.ts | 21 +++++++------------ .../tokenOperationsFactoryConfig.ts | 2 -- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/tokenOperations/tokenOperationsFactory.ts b/src/tokenOperations/tokenOperationsFactory.ts index 0a652951..b41e8559 100644 --- a/src/tokenOperations/tokenOperationsFactory.ts +++ b/src/tokenOperations/tokenOperationsFactory.ts @@ -1,6 +1,7 @@ import BigNumber from "bignumber.js"; import { ARGUMENTS_SEPARATOR, TRANSACTION_OPTIONS_DEFAULT, TRANSACTION_VERSION_DEFAULT } from "../constants"; import { IAddress, IChainID, IGasLimit, IGasPrice, INonce, ITransactionValue } from "../interface"; +import { Logger } from "../logger"; import { TransactionOptions, TransactionVersion } from "../networkParams"; import { Transaction } from "../transaction"; import { TransactionPayload } from "../transactionPayload"; @@ -26,8 +27,6 @@ interface IConfig { gasLimitStorePerByte: IGasLimit; issueCost: BigNumber.Value; esdtContractAddress: IAddress; - - shouldWarnAboutUnsettingBurnRoleGlobally: boolean; } interface IBaseArgs { @@ -198,7 +197,7 @@ export class TokenOperationsFactory { } issueFungible(args: IIssueFungibleArgs): Transaction { - this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + this.notifyAboutUnsettingBurnRoleGlobally(); const parts = [ "issue", @@ -226,12 +225,8 @@ export class TokenOperationsFactory { }); } - private warnAboutUnsettingBurnRoleGloballyIfAppropriate() { - if (!this.config.shouldWarnAboutUnsettingBurnRoleGlobally) { - return; - } - - console.warn(` + private notifyAboutUnsettingBurnRoleGlobally() { + Logger.info(` ========== IMPORTANT! ========== @@ -240,7 +235,7 @@ Once the token is registered, you can unset this role by calling "unsetBurnRoleG } issueSemiFungible(args: IIssueSemiFungibleArgs): Transaction { - this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + this.notifyAboutUnsettingBurnRoleGlobally(); const parts = [ "issueSemiFungible", @@ -268,7 +263,7 @@ Once the token is registered, you can unset this role by calling "unsetBurnRoleG } issueNonFungible(args: IIssueNonFungibleArgs): Transaction { - this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + this.notifyAboutUnsettingBurnRoleGlobally(); const parts = [ "issueNonFungible", @@ -296,7 +291,7 @@ Once the token is registered, you can unset this role by calling "unsetBurnRoleG } registerMetaESDT(args: IRegisterMetaESDT): Transaction { - this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + this.notifyAboutUnsettingBurnRoleGlobally(); const parts = [ "registerMetaESDT", @@ -325,7 +320,7 @@ Once the token is registered, you can unset this role by calling "unsetBurnRoleG } registerAndSetAllRoles(args: IRegisterAndSetAllRoles): Transaction { - this.warnAboutUnsettingBurnRoleGloballyIfAppropriate(); + this.notifyAboutUnsettingBurnRoleGlobally(); const parts = [ "registerAndSetAllRoles", diff --git a/src/tokenOperations/tokenOperationsFactoryConfig.ts b/src/tokenOperations/tokenOperationsFactoryConfig.ts index 7c8cf3c2..ef9731bf 100644 --- a/src/tokenOperations/tokenOperationsFactoryConfig.ts +++ b/src/tokenOperations/tokenOperationsFactoryConfig.ts @@ -23,8 +23,6 @@ export class TokenOperationsFactoryConfig { issueCost: BigNumber.Value = "50000000000000000"; esdtContractAddress: IAddress = Address.fromBech32("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"); - shouldWarnAboutUnsettingBurnRoleGlobally: boolean = true; - constructor(chainID: IChainID) { this.chainID = chainID; } From e7bfe90a30026db067e37933aa9bcf94fb2a9f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Jun 2023 13:07:59 +0300 Subject: [PATCH 12/16] Fix after review. --- src/transaction.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/transaction.ts b/src/transaction.ts index 4d4f2e25..ff74936a 100644 --- a/src/transaction.ts +++ b/src/transaction.ts @@ -306,7 +306,7 @@ export class Transaction { * This function is called internally within the signing procedure. */ toPlainObject(): IPlainTransactionObject { - const plainObject: any = { + const plainObject = { nonce: this.nonce.valueOf(), value: this.value.toString(), receiver: this.receiver.bech32(), @@ -317,8 +317,8 @@ export class Transaction { gasLimit: this.gasLimit.valueOf(), data: this.data.length() == 0 ? undefined : this.data.encoded(), chainID: this.chainID.valueOf(), - version: this.version.valueOf(), - options: this.options.valueOf() == 0 ? undefined : this.options.valueOf(), + version: this.getVersion().valueOf(), + options: this.getOptions().valueOf() == 0 ? undefined : this.getOptions().valueOf(), guardian: this.guardian?.bech32() ? (this.guardian.bech32() == "" ? undefined : this.guardian.bech32()) : undefined, signature: this.signature.toString("hex") ? this.signature.toString("hex") : undefined, guardianSignature: this.guardianSignature.toString("hex") ? this.guardianSignature.toString("hex") : undefined, @@ -339,16 +339,16 @@ export class Transaction { nonce: Number(plainObjectTransaction.nonce), value: new BigNumber(plainObjectTransaction.value).toFixed(0), receiver: Address.fromString(plainObjectTransaction.receiver), - receiverUsername: plainObjectTransaction.receiverUsername == undefined ? undefined : Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString(), + receiverUsername: !plainObjectTransaction.receiverUsername ? undefined : Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString(), sender: Address.fromString(plainObjectTransaction.sender), - senderUsername: plainObjectTransaction.senderUsername == undefined ? undefined : Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString(), - guardian: plainObjectTransaction.guardian == undefined ? undefined : Address.fromString(plainObjectTransaction.guardian || ""), + senderUsername: !plainObjectTransaction.senderUsername ? undefined : Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString(), + guardian: !plainObjectTransaction.guardian ? undefined : Address.fromString(plainObjectTransaction.guardian || ""), gasPrice: Number(plainObjectTransaction.gasPrice), gasLimit: Number(plainObjectTransaction.gasLimit), data: new TransactionPayload(Buffer.from(plainObjectTransaction.data || "", "base64")), chainID: String(plainObjectTransaction.chainID), version: new TransactionVersion(plainObjectTransaction.version), - options: plainObjectTransaction.options == undefined ? undefined : new TransactionOptions(plainObjectTransaction.options) + options: plainObjectTransaction.options === undefined ? undefined : new TransactionOptions(plainObjectTransaction.options) }); if (plainObjectTransaction.signature) { From 1bb51bafdfda90363e974767a5abfce1237cbb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Jun 2023 13:09:51 +0300 Subject: [PATCH 13/16] Bump version. --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97e9fd4d..41820177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@multiversx/sdk-core", - "version": "12.3.0", + "version": "12.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@multiversx/sdk-core", - "version": "12.3.0", + "version": "12.4.0", "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", diff --git a/package.json b/package.json index f3f5a6cd..d51b4a50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-core", - "version": "12.3.0", + "version": "12.4.0", "description": "MultiversX SDK for JavaScript and TypeScript", "main": "out/index.js", "types": "out/index.d.js", From e5eca707e1dbb52ccb126f1d003fae49e76acb92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Jun 2023 13:13:34 +0300 Subject: [PATCH 14/16] Fixed after review. --- src/transaction.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transaction.ts b/src/transaction.ts index ff74936a..046faa48 100644 --- a/src/transaction.ts +++ b/src/transaction.ts @@ -339,16 +339,16 @@ export class Transaction { nonce: Number(plainObjectTransaction.nonce), value: new BigNumber(plainObjectTransaction.value).toFixed(0), receiver: Address.fromString(plainObjectTransaction.receiver), - receiverUsername: !plainObjectTransaction.receiverUsername ? undefined : Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString(), + receiverUsername: plainObjectTransaction.receiverUsername ? Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString() : undefined, sender: Address.fromString(plainObjectTransaction.sender), - senderUsername: !plainObjectTransaction.senderUsername ? undefined : Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString(), - guardian: !plainObjectTransaction.guardian ? undefined : Address.fromString(plainObjectTransaction.guardian || ""), + senderUsername: plainObjectTransaction.senderUsername ? Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString() : undefined, + guardian: plainObjectTransaction.guardian ? Address.fromString(plainObjectTransaction.guardian || "") : undefined, gasPrice: Number(plainObjectTransaction.gasPrice), gasLimit: Number(plainObjectTransaction.gasLimit), data: new TransactionPayload(Buffer.from(plainObjectTransaction.data || "", "base64")), chainID: String(plainObjectTransaction.chainID), version: new TransactionVersion(plainObjectTransaction.version), - options: plainObjectTransaction.options === undefined ? undefined : new TransactionOptions(plainObjectTransaction.options) + options: plainObjectTransaction.options !== undefined ? new TransactionOptions(plainObjectTransaction.options) : undefined }); if (plainObjectTransaction.signature) { From 7786d718f1a2802e7d524699f485cb46771cec17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 13 Jun 2023 13:24:33 +0300 Subject: [PATCH 15/16] Fix checks. --- src/transaction.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transaction.ts b/src/transaction.ts index 046faa48..a957adf4 100644 --- a/src/transaction.ts +++ b/src/transaction.ts @@ -339,16 +339,16 @@ export class Transaction { nonce: Number(plainObjectTransaction.nonce), value: new BigNumber(plainObjectTransaction.value).toFixed(0), receiver: Address.fromString(plainObjectTransaction.receiver), - receiverUsername: plainObjectTransaction.receiverUsername ? Buffer.from(plainObjectTransaction.receiverUsername || "", "base64").toString() : undefined, + receiverUsername: plainObjectTransaction.receiverUsername ? Buffer.from(plainObjectTransaction.receiverUsername, "base64").toString() : undefined, sender: Address.fromString(plainObjectTransaction.sender), - senderUsername: plainObjectTransaction.senderUsername ? Buffer.from(plainObjectTransaction.senderUsername || "", "base64").toString() : undefined, - guardian: plainObjectTransaction.guardian ? Address.fromString(plainObjectTransaction.guardian || "") : undefined, + senderUsername: plainObjectTransaction.senderUsername ? Buffer.from(plainObjectTransaction.senderUsername, "base64").toString() : undefined, + guardian: plainObjectTransaction.guardian ? Address.fromString(plainObjectTransaction.guardian) : undefined, gasPrice: Number(plainObjectTransaction.gasPrice), gasLimit: Number(plainObjectTransaction.gasLimit), data: new TransactionPayload(Buffer.from(plainObjectTransaction.data || "", "base64")), chainID: String(plainObjectTransaction.chainID), version: new TransactionVersion(plainObjectTransaction.version), - options: plainObjectTransaction.options !== undefined ? new TransactionOptions(plainObjectTransaction.options) : undefined + options: plainObjectTransaction.options != null ? new TransactionOptions(plainObjectTransaction.options) : undefined }); if (plainObjectTransaction.signature) { From 78a5671f535cfc9297bc1bc557bf4d2ab2ef5cf4 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Fri, 16 Jun 2023 15:06:20 +0300 Subject: [PATCH 16/16] bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41820177..a967a0b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@multiversx/sdk-core", - "version": "12.4.0", + "version": "12.4.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@multiversx/sdk-core", - "version": "12.4.0", + "version": "12.4.1", "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", diff --git a/package.json b/package.json index d51b4a50..f7167abe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-core", - "version": "12.4.0", + "version": "12.4.1", "description": "MultiversX SDK for JavaScript and TypeScript", "main": "out/index.js", "types": "out/index.d.js",