Skip to content

Commit

Permalink
Merge branch 'main' into abi-parser-arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Jun 16, 2023
2 parents 9a0429d + 78a5671 commit e078a84
Show file tree
Hide file tree
Showing 14 changed files with 418 additions and 24 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@multiversx/sdk-core",
"version": "12.2.2",
"version": "12.4.1",
"description": "MultiversX SDK for JavaScript and TypeScript",
"main": "out/index.js",
"types": "out/index.d.js",
Expand Down
2 changes: 2 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface IPlainTransactionObject {
value: string;
receiver: string;
sender: string;
receiverUsername?: string;
senderUsername?: string;
guardian?: string;
gasPrice: number;
gasLimit: number;
Expand Down
19 changes: 19 additions & 0 deletions src/proto/serializer.spec.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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");
});
});
4 changes: 2 additions & 2 deletions src/proto/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
43 changes: 40 additions & 3 deletions src/relayedTransactionV1Builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/relayedTransactionV1Builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 17 additions & 3 deletions src/tokenOperations/tokenOperationsFactory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ describe("test factory", () => {
factory = new TokenOperationsFactory(new TokenOperationsFactoryConfig("T"));
});

it("should create <registerAndSetAllRoles>", () => {
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 <issueFungible>", () => {
const transaction = factory.issueFungible({
issuer: frank.address,
Expand All @@ -22,15 +38,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");
Expand Down
140 changes: 138 additions & 2 deletions src/tokenOperations/tokenOperationsFactory.test.net.spec.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -33,6 +33,142 @@ describe("test factory on testnet", function () {
transferTransactionsFactory = new TransferTransactionsFactory(new GasEstimator());
});

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);

// 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.parseUnsetBurnRoleGlobally(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.parseSetBurnRoleGlobally(tx3OnNetwork);
});

it("should issue fungible, mint, burn", async function () {
this.timeout(120000);
await frank.sync(provider);
Expand Down
Loading

0 comments on commit e078a84

Please sign in to comment.