From 35996e78e951a16fcab51e99629d2ed23a273e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 14:32:03 +0200 Subject: [PATCH 01/10] Compiler option: ES2020. --- tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 716261e6..089ef306 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { "module": "CommonJS", - "target": "es2015", + "target": "ES2020", "outDir": "out", "lib": [ - "ES2015", + "ES2020", "DOM" ], "sourceMap": true, From 0dbe620c99333b90b9bb974f11c1af3680ad5da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 14:32:30 +0200 Subject: [PATCH 02/10] For "Token" and "NextTokenTransfer", use "bigint" instead of "BigNumber.Value". --- src/tokens.spec.ts | 6 +-- src/tokens.ts | 11 +++--- .../smartContractTransactionsFactory.spec.ts | 38 +++++++++---------- .../tokenTransfersDataBuilder.ts | 2 +- .../transferTransactionsFactory.spec.ts | 20 +++++----- src/utils.codec.spec.ts | 10 ++++- src/utils.codec.ts | 14 +++++-- 7 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/tokens.spec.ts b/src/tokens.spec.ts index 9fd54cd4..e7949b56 100644 --- a/src/tokens.spec.ts +++ b/src/tokens.spec.ts @@ -1,12 +1,12 @@ -import { Token, TokenComputer } from "./tokens"; import { assert } from "chai"; +import { Token, TokenComputer } from "./tokens"; describe("test token computer", async () => { const tokenComputer = new TokenComputer(); it("should test if token is fungible", async () => { - const fungibleToken = new Token("TEST-123456", 0); - const nonFungibleToken = new Token("NFT-987654", 7); + const fungibleToken = new Token("TEST-123456", 0n); + const nonFungibleToken = new Token("NFT-987654", 7n); assert.equal(tokenComputer.isFungible(fungibleToken), true); assert.equal(tokenComputer.isFungible(nonFungibleToken), false); diff --git a/src/tokens.ts b/src/tokens.ts index e6d18c28..66d200e0 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -1,11 +1,10 @@ -import BigNumber from "bignumber.js"; import { ErrInvalidTokenIdentifier } from "./errors"; export class Token { identifier: string; - nonce: BigNumber.Value; + nonce: bigint; - constructor(identifier: string, nonce: BigNumber.Value) { + constructor(identifier: string, nonce: bigint) { this.identifier = identifier; this.nonce = nonce; } @@ -13,9 +12,9 @@ export class Token { export class NextTokenTransfer { token: Token; - amount: BigNumber.Value; + amount: bigint; - constructor(token: Token, amount: BigNumber.Value) { + constructor(token: Token, amount: bigint) { this.token = token; this.amount = amount; } @@ -25,7 +24,7 @@ export class TokenComputer { constructor() {} isFungible(token: Token): boolean { - return token.nonce === 0; + return token.nonce == 0n; } extractNonceFromExtendedIdentifier(identifier: string): number { diff --git a/src/transactionsFactories/smartContractTransactionsFactory.spec.ts b/src/transactionsFactories/smartContractTransactionsFactory.spec.ts index d4ab3c62..fe447a9c 100644 --- a/src/transactionsFactories/smartContractTransactionsFactory.spec.ts +++ b/src/transactionsFactories/smartContractTransactionsFactory.spec.ts @@ -1,15 +1,15 @@ +import BigNumber from "bignumber.js"; import { assert, expect } from "chai"; -import { SmartContractTransactionsFactory } from "./smartContractTransactionsFactory"; import { Address } from "../address"; -import { Code } from "../smartcontracts/code"; -import { AbiRegistry } from "../smartcontracts/typesystem/abiRegistry"; -import { U32Value } from "../smartcontracts"; import { CONTRACT_DEPLOY_ADDRESS } from "../constants"; -import { loadContractCode, loadAbiRegistry } from "../testutils/utils"; import { Err } from "../errors"; +import { U32Value } from "../smartcontracts"; +import { Code } from "../smartcontracts/code"; +import { AbiRegistry } from "../smartcontracts/typesystem/abiRegistry"; +import { loadAbiRegistry, loadContractCode } from "../testutils/utils"; +import { NextTokenTransfer, Token, TokenComputer } from "../tokens"; +import { SmartContractTransactionsFactory } from "./smartContractTransactionsFactory"; import { TransactionsFactoryConfig } from "./transactionsFactoryConfig"; -import BigNumber from "bignumber.js"; -import { Token, NextTokenTransfer, TokenComputer } from "../tokens"; describe("test smart contract transactions factory", function () { const config = new TransactionsFactoryConfig("D"); @@ -149,8 +149,8 @@ describe("test smart contract transactions factory", function () { const func = "add"; const gasLimit = 6000000; const args = [new U32Value(7)]; - const token = new Token("FOO-6ce17b", 0); - const transfer = new NextTokenTransfer(token, 10); + const token = new Token("FOO-6ce17b", 0n); + const transfer = new NextTokenTransfer(token, 10n); const transaction = smartContractFactory.createTransactionForExecute({ sender: sender, @@ -185,10 +185,10 @@ describe("test smart contract transactions factory", function () { const gasLimit = 6000000; const args = [new U32Value(7)]; - const fooToken = new Token("FOO-6ce17b", 0); - const fooTransfer = new NextTokenTransfer(fooToken, 10); - const barToken = new Token("BAR-5bc08f", 0); - const barTransfer = new NextTokenTransfer(barToken, 3140); + const fooToken = new Token("FOO-6ce17b", 0n); + const fooTransfer = new NextTokenTransfer(fooToken, 10n); + const barToken = new Token("BAR-5bc08f", 0n); + const barTransfer = new NextTokenTransfer(barToken, 3140n); const transaction = smartContractFactory.createTransactionForExecute({ sender: sender, @@ -230,8 +230,8 @@ describe("test smart contract transactions factory", function () { const gasLimit = 6000000; const args = [new U32Value(7)]; - const token = new Token("NFT-123456", 1); - const transfer = new NextTokenTransfer(token, 1); + const token = new Token("NFT-123456", 1n); + const transfer = new NextTokenTransfer(token, 1n); const transaction = smartContractFactory.createTransactionForExecute({ sender: sender, @@ -274,10 +274,10 @@ describe("test smart contract transactions factory", function () { const gasLimit = 6000000; const args = [new U32Value(7)]; - const firstToken = new Token("NFT-123456", 1); - const firstTransfer = new NextTokenTransfer(firstToken, 1); - const secondToken = new Token("NFT-123456", 42); - const secondTransfer = new NextTokenTransfer(secondToken, 1); + const firstToken = new Token("NFT-123456", 1n); + const firstTransfer = new NextTokenTransfer(firstToken, 1n); + const secondToken = new Token("NFT-123456", 42n); + const secondTransfer = new NextTokenTransfer(secondToken, 1n); const transaction = smartContractFactory.createTransactionForExecute({ sender: sender, diff --git a/src/transactionsFactories/tokenTransfersDataBuilder.ts b/src/transactionsFactories/tokenTransfersDataBuilder.ts index 7804e7bd..593f9275 100644 --- a/src/transactionsFactories/tokenTransfersDataBuilder.ts +++ b/src/transactionsFactories/tokenTransfersDataBuilder.ts @@ -1,6 +1,6 @@ import { IAddress } from "../interface"; import { NextTokenTransfer, TokenComputer } from "../tokens"; -import { numberToPaddedHex, utf8ToHex, addressToHex } from "../utils.codec"; +import { addressToHex, numberToPaddedHex, utf8ToHex } from "../utils.codec"; export class TokenTransfersDataBuilder { private tokenComputer: TokenComputer; diff --git a/src/transactionsFactories/transferTransactionsFactory.spec.ts b/src/transactionsFactories/transferTransactionsFactory.spec.ts index 2f609159..39903b91 100644 --- a/src/transactionsFactories/transferTransactionsFactory.spec.ts +++ b/src/transactionsFactories/transferTransactionsFactory.spec.ts @@ -1,9 +1,9 @@ import { assert } from "chai"; import { Address } from "../address"; -import { Token, NextTokenTransfer, TokenComputer } from "../tokens"; +import { ErrBadUsage } from "../errors"; +import { NextTokenTransfer, Token, TokenComputer } from "../tokens"; import { TransactionsFactoryConfig } from "./transactionsFactoryConfig"; import { NextTransferTransactionsFactory } from "./transferTransactionsFactory"; -import { ErrBadUsage } from "../errors"; describe("test transfer transcations factory", function () { const config = new TransactionsFactoryConfig("D"); @@ -58,8 +58,8 @@ describe("test transfer transcations factory", function () { }); it("should create 'TransactionNext' for esdt transfer", async () => { - const fooToken = new Token("FOO-123456", 0); - const transfer = new NextTokenTransfer(fooToken, 1000000); + const fooToken = new Token("FOO-123456", 0n); + const transfer = new NextTokenTransfer(fooToken, 1000000n); const transaction = nextTransferFactory.createTransactionForESDTTokenTransfer({ sender: alice, @@ -75,8 +75,8 @@ describe("test transfer transcations factory", function () { }); it("should create 'TransactionNext' for nft transfer", async () => { - const nft = new Token("NFT-123456", 10); - const transfer = new NextTokenTransfer(nft, 1); + const nft = new Token("NFT-123456", 10n); + const transfer = new NextTokenTransfer(nft, 1n); const transaction = nextTransferFactory.createTransactionForESDTTokenTransfer({ sender: alice, @@ -95,11 +95,11 @@ describe("test transfer transcations factory", function () { }); it("should create 'TransactionNext' for multiple nft transfers", async () => { - const firstNft = new Token("NFT-123456", 10); - const firstTransfer = new NextTokenTransfer(firstNft, 1); + const firstNft = new Token("NFT-123456", 10n); + const firstTransfer = new NextTokenTransfer(firstNft, 1n); - const secondNft = new Token("TEST-987654", 1); - const secondTransfer = new NextTokenTransfer(secondNft, 1); + const secondNft = new Token("TEST-987654", 1n); + const secondTransfer = new NextTokenTransfer(secondNft, 1n); const transaction = nextTransferFactory.createTransactionForESDTTokenTransfer({ sender: alice, diff --git a/src/utils.codec.spec.ts b/src/utils.codec.spec.ts index ba38f632..817496cc 100644 --- a/src/utils.codec.spec.ts +++ b/src/utils.codec.spec.ts @@ -1,11 +1,19 @@ import { assert } from "chai"; -import { isPaddedHex, numberToPaddedHex, zeroPadStringIfOddLength, byteArrayToHex, utf8ToHex } from "./utils.codec"; +import { byteArrayToHex, isPaddedHex, numberToPaddedHex, utf8ToHex, zeroPadStringIfOddLength } from "./utils.codec"; describe("test codec utils", () => { it("should convert numberToPaddedHex", () => { assert.equal(numberToPaddedHex(1), "01"); assert.equal(numberToPaddedHex(10), "0a"); assert.equal(numberToPaddedHex(256), "0100"); + + assert.equal(numberToPaddedHex(1n), "01"); + assert.equal(numberToPaddedHex(10n), "0a"); + assert.equal(numberToPaddedHex(256n), "0100"); + + assert.equal(numberToPaddedHex("1"), "01"); + assert.equal(numberToPaddedHex("10"), "0a"); + assert.equal(numberToPaddedHex("256"), "0100"); }); it("should check if isPaddedHex", () => { diff --git a/src/utils.codec.ts b/src/utils.codec.ts index 6d326412..0e03b658 100644 --- a/src/utils.codec.ts +++ b/src/utils.codec.ts @@ -1,10 +1,18 @@ import BigNumber from "bignumber.js"; -import * as contractsCodecUtils from "./smartcontracts/codec/utils"; import { Address } from "./address"; import { IAddress } from "./interface"; +import * as contractsCodecUtils from "./smartcontracts/codec/utils"; + +export function numberToPaddedHex(value: bigint | number | BigNumber.Value) { + let hexableNumber: { toString(radix?: number): string }; + + if (typeof value === "bigint" || typeof value === "number") { + hexableNumber = value; + } else { + hexableNumber = new BigNumber(value); + } -export function numberToPaddedHex(value: BigNumber.Value) { - let hex = new BigNumber(value).toString(16); + const hex = hexableNumber.toString(16); return zeroPadStringIfOddLength(hex); } From bfdb4533c06be465d313d0eece3a59b86d89f85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 14:34:31 +0200 Subject: [PATCH 03/10] ES2015 -> ES2020. --- tsconfig.tests.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.tests.json b/tsconfig.tests.json index 29ec228e..52a987db 100644 --- a/tsconfig.tests.json +++ b/tsconfig.tests.json @@ -1,10 +1,10 @@ { "compilerOptions": { "module": "CommonJS", - "target": "ES2015", + "target": "ES2020", "outDir": "out-tests", "lib": [ - "ES2015", + "ES2020", "DOM" ], "sourceMap": true, From 20a6f19e13449897e22260ca9cac7795e63061c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 15:04:41 +0200 Subject: [PATCH 04/10] Fix after review. --- src/tokens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tokens.ts b/src/tokens.ts index 66d200e0..361800ac 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -24,7 +24,7 @@ export class TokenComputer { constructor() {} isFungible(token: Token): boolean { - return token.nonce == 0n; + return token.nonce === 0n; } extractNonceFromExtendedIdentifier(identifier: string): number { From 847be22ae4c5d1ebb091dcd4018b7f41b07b7193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 17:37:56 +0200 Subject: [PATCH 05/10] Add extra methods on Address, wrt. specs. --- src/address.ts | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/address.ts b/src/address.ts index 54601745..123a5417 100644 --- a/src/address.ts +++ b/src/address.ts @@ -138,9 +138,16 @@ export class Address { } /** - * Returns the hex representation of the address (pubkey) + * Use {@link toHex} instead. */ hex(): string { + return this.toHex(); + } + + /** + * Returns the hex representation of the address (pubkey) + */ + toHex(): string { if (this.isEmpty()) { return ""; } @@ -149,9 +156,16 @@ export class Address { } /** - * Returns the bech32 representation of the address + * Use {@link toBech32} instead. */ bech32(): string { + return this.toBech32(); + } + + /** + * Returns the bech32 representation of the address + */ + toBech32(): string { if (this.isEmpty()) { return ""; } @@ -162,9 +176,16 @@ export class Address { } /** - * Returns the pubkey as raw bytes (buffer) + * Use {@link getPublicKey} instead. */ pubkey(): Buffer { + return this.getPublicKey(); + } + + /** + * Returns the pubkey as raw bytes (buffer) + */ + getPublicKey(): Buffer { if (this.isEmpty()) { return Buffer.from([]); } @@ -214,7 +235,17 @@ export class Address { return new Address("0".repeat(64)); } + /** + * Use {@link isSmartContract} instead. + */ isContractAddress(): boolean { return this.hex().startsWith(SMART_CONTRACT_HEX_PUBKEY_PREFIX); } + + /** + * Returns whether the address is a smart contract address. + */ + isSmartContract(): boolean { + return this.isContractAddress(); + } } From 0dd4a3a23307fcc70ca9731a223dfc962e1061c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 19:28:33 +0200 Subject: [PATCH 06/10] Adjust some deprecations. --- src/smartcontracts/transactionPayloadBuilders.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/smartcontracts/transactionPayloadBuilders.ts b/src/smartcontracts/transactionPayloadBuilders.ts index c70fbdcc..4234381f 100644 --- a/src/smartcontracts/transactionPayloadBuilders.ts +++ b/src/smartcontracts/transactionPayloadBuilders.ts @@ -6,11 +6,10 @@ import { TypedValue } from "./typesystem"; export const WasmVirtualMachine = "0500"; -/** - * A builder for {@link TransactionPayload} objects, to be used for Smart Contract deployment transactions. - */ /** * @deprecated Use {@link SmartContractTransactionsFactory} instead. + * + * A builder for {@link TransactionPayload} objects, to be used for Smart Contract deployment transactions. */ export class ContractDeployPayloadBuilder { private code: ICode | null = null; @@ -65,6 +64,8 @@ export class ContractDeployPayloadBuilder { } /** + * @deprecated Use {@link SmartContractTransactionsFactory} instead. + * * A builder for {@link TransactionPayload} objects, to be used for Smart Contract upgrade transactions. */ export class ContractUpgradePayloadBuilder { @@ -120,6 +121,8 @@ export class ContractUpgradePayloadBuilder { } /** + * @deprecated Use {@link SmartContractTransactionsFactory} instead. + * * A builder for {@link TransactionPayload} objects, to be used for Smart Contract execution transactions. */ export class ContractCallPayloadBuilder { From fc954bd5083dac2c7b1e160a207bd5c4f932e086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 19:33:38 +0200 Subject: [PATCH 07/10] Breaking change: Address constructor cannot be called with no parameters anymore. Replacement: Address.empty(). --- src/account.ts | 2 +- src/address.spec.ts | 2 +- src/address.ts | 8 ++++---- src/signableMessage.ts | 2 +- src/smartcontracts/interaction.ts | 4 ++-- src/smartcontracts/query.ts | 2 +- src/smartcontracts/resultsParser.spec.ts | 4 ++-- src/smartcontracts/smartContract.ts | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/account.ts b/src/account.ts index 68ccf609..d371afdc 100644 --- a/src/account.ts +++ b/src/account.ts @@ -8,7 +8,7 @@ export class Account { /** * The address of the account. */ - readonly address: IAddress = new Address(); + readonly address: IAddress = Address.empty(); /** * The nonce of the account (the account sequence number). diff --git a/src/address.spec.ts b/src/address.spec.ts index 248b858a..63abaa51 100644 --- a/src/address.spec.ts +++ b/src/address.spec.ts @@ -17,7 +17,7 @@ describe("test address", () => { }); it("should create empty address", async () => { - let nobody = new Address(); + const nobody = Address.empty(); assert.isEmpty(nobody.hex()); assert.isEmpty(nobody.bech32()); diff --git a/src/address.ts b/src/address.ts index 123a5417..b8a4b7c3 100644 --- a/src/address.ts +++ b/src/address.ts @@ -23,7 +23,7 @@ export class Address { /** * Creates an address object, given a raw string (whether a hex pubkey or a Bech32 address), a sequence of bytes, or another Address object. */ - public constructor(value?: Address | Buffer | string) { + public constructor(value: Address | Buffer | string) { if (!value) { return; } @@ -48,7 +48,7 @@ export class Address { } private static fromValidHex(value: string): Address { - let result = new Address(); + let result = Address.empty(); result.valueHex = value; return result; } @@ -91,10 +91,10 @@ export class Address { } /** - * Creates an empty address object + * Creates an empty address object. Generally speaking, this should not be used in client code (internal use only). */ static empty(): Address { - return new Address(); + return new Address(""); } /** diff --git a/src/signableMessage.ts b/src/signableMessage.ts index 4fe82b7e..3277e106 100644 --- a/src/signableMessage.ts +++ b/src/signableMessage.ts @@ -36,7 +36,7 @@ export class SignableMessage { this.signature = Buffer.from([]); this.version = 1; this.signer = "ErdJS"; - this.address = new Address(); + this.address = Address.empty(); Object.assign(this, init); } diff --git a/src/smartcontracts/interaction.ts b/src/smartcontracts/interaction.ts index 1b5b71f3..9cf2b7b7 100644 --- a/src/smartcontracts/interaction.ts +++ b/src/smartcontracts/interaction.ts @@ -35,9 +35,9 @@ export class Interaction { private gasLimit: IGasLimit = 0; private gasPrice: IGasPrice | undefined = undefined; private chainID: IChainID = ""; - private querent: IAddress = new Address(); + private querent: IAddress = Address.empty(); private explicitReceiver?: IAddress; - private sender: IAddress = new Address(); + private sender: IAddress = Address.empty(); private isWithSingleESDTTransfer: boolean = false; private isWithSingleESDTNFTTransfer: boolean = false; diff --git a/src/smartcontracts/query.ts b/src/smartcontracts/query.ts index a298ebf0..3db54519 100644 --- a/src/smartcontracts/query.ts +++ b/src/smartcontracts/query.ts @@ -18,7 +18,7 @@ export class Query { args?: TypedValue[], value?: ITransactionValue }) { - this.caller = obj.caller || new Address(); + this.caller = obj.caller || Address.empty(); this.address = obj.address; this.func = obj.func; this.args = obj.args || []; diff --git a/src/smartcontracts/resultsParser.spec.ts b/src/smartcontracts/resultsParser.spec.ts index e257cc07..2c033a65 100644 --- a/src/smartcontracts/resultsParser.spec.ts +++ b/src/smartcontracts/resultsParser.spec.ts @@ -202,7 +202,7 @@ describe("test smart contract results parser", () => { it("should parse contract outcome, on signal error", async () => { let transaction = new TransactionOnNetwork({ logs: new TransactionLogs({ - address: new Address(), + address: Address.empty(), events: [ new TransactionEvent({ identifier: "signalError", @@ -222,7 +222,7 @@ describe("test smart contract results parser", () => { it("should parse contract outcome, on too much gas warning", async () => { let transaction = new TransactionOnNetwork({ logs: new TransactionLogs({ - address: new Address(), + address: Address.empty(), events: [ new TransactionEvent({ identifier: "writeLog", diff --git a/src/smartcontracts/smartContract.ts b/src/smartcontracts/smartContract.ts index 788c9d54..7e02329c 100644 --- a/src/smartcontracts/smartContract.ts +++ b/src/smartcontracts/smartContract.ts @@ -31,7 +31,7 @@ interface IAbi { * An abstraction for deploying and interacting with Smart Contracts. */ export class SmartContract implements ISmartContract { - private address: IAddress = new Address(); + private address: IAddress = Address.empty(); private abi?: IAbi; /** @@ -53,7 +53,7 @@ export class SmartContract implements ISmartContract { * Create a SmartContract object by providing its address on the Network. */ constructor(options: { address?: IAddress, abi?: IAbi } = {}) { - this.address = options.address || new Address(); + this.address = options.address || Address.empty(); this.abi = options.abi; if (this.abi) { From 29bf7dbbb0f6c2646f5d4f78f7a466cd3d9f8c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 19:45:57 +0200 Subject: [PATCH 08/10] Breaking change (fixing change): when address is required, but detected to be empty (or zero), an error is thrown (instead of just displaying a WARN). --- src/compatibility.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/compatibility.ts b/src/compatibility.ts index 3aec4764..b214c4f2 100644 --- a/src/compatibility.ts +++ b/src/compatibility.ts @@ -1,26 +1,21 @@ import { Address } from "./address"; +import { Err } from "./errors"; import { IAddress } from "./interface"; /** * For internal use only. */ export class Compatibility { - static areWarningsEnabled: boolean = true; - /** * For internal use only. */ static guardAddressIsSetAndNonZero(address: IAddress | undefined, context: string, resolution: string) { - if (!this.areWarningsEnabled) { - return; - } - if (!address || address.bech32() == "") { - console.warn( + throw new Err( `${context}: address should be set; ${resolution}. In the future, this will throw an exception instead of emitting a WARN.`, ); } else if (address.bech32() == Address.Zero().bech32()) { - console.warn( + throw new Err( `${context}: address should not be the 'zero' address (also known as the 'contracts deployment address'); ${resolution}. In the future, this will throw an exception instead of emitting a WARN.`, ); } From db67192857cb447c3b03ab732c46b38075e4d6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 15 Feb 2024 19:48:32 +0200 Subject: [PATCH 09/10] Fix comments. --- src/address.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/address.ts b/src/address.ts index b8a4b7c3..9745ac9c 100644 --- a/src/address.ts +++ b/src/address.ts @@ -91,7 +91,8 @@ export class Address { } /** - * Creates an empty address object. Generally speaking, this should not be used in client code (internal use only). + * Creates an empty address object. + * Generally speaking, this should not be used by client code (internal use only). */ static empty(): Address { return new Address(""); @@ -229,7 +230,8 @@ export class Address { } /** - * Creates the Zero address (the one that should be used when deploying smart contracts) + * Creates the Zero address (the one that should be used when deploying smart contracts). + * Generally speaking, this should not be used by client code (internal use only). */ static Zero(): Address { return new Address("0".repeat(64)); From 42498c3b384b8abf1f21a8326b3eb3462b48f38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Fri, 16 Feb 2024 09:48:40 +0200 Subject: [PATCH 10/10] Minor refactoring. Additional tests. --- src/address.spec.ts | 12 ++++++++++++ src/address.ts | 22 +++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/address.spec.ts b/src/address.spec.ts index 63abaa51..48313ab0 100644 --- a/src/address.spec.ts +++ b/src/address.spec.ts @@ -55,4 +55,16 @@ describe("test address", () => { assert.isFalse(Address.isValid("xerd1l453hd0gt5gzdp7czpuall8ggt2dcv5zwmfdf3sd3lguxseux2fsmsgldz")); assert.isFalse(Address.isValid("erd1l453hd0gt5gzdp7czpuall8ggt2dcv5zwmfdf3sd3lguxseux2")); }); + + it("should check whether isSmartContract", () => { + assert.isFalse( + Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th").isSmartContract(), + ); + assert.isTrue( + Address.fromBech32("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l").isSmartContract(), + ); + assert.isTrue( + Address.fromBech32("erd1qqqqqqqqqqqqqpgqxwakt2g7u9atsnr03gqcgmhcv38pt7mkd94q6shuwt").isSmartContract(), + ); + }); }); diff --git a/src/address.ts b/src/address.ts index 9745ac9c..a5b3fda5 100644 --- a/src/address.ts +++ b/src/address.ts @@ -110,12 +110,12 @@ export class Address { throw new errors.ErrAddressCannotCreate(value, err); } - let prefix = decoded.prefix; + const prefix = decoded.prefix; if (prefix != HRP) { throw new errors.ErrAddressBadHrp(HRP, prefix); } - let pubkey = Buffer.from(bech32.fromWords(decoded.words)); + const pubkey = Buffer.from(bech32.fromWords(decoded.words)); if (pubkey.length != PUBKEY_LENGTH) { throw new errors.ErrAddressCannotCreate(value); } @@ -194,6 +194,14 @@ export class Address { return Buffer.from(this.valueHex, "hex"); } + /** + * Returns the human-readable-part of the bech32 addresses. + * The HRP is currently hardcoded to "erd". + */ + getHrp(): string { + return HRP; + } + /** * Returns whether the address is empty. */ @@ -216,7 +224,7 @@ export class Address { * Returns the bech32 representation of the address */ toString(): string { - return this.bech32(); + return this.toBech32(); } /** @@ -224,8 +232,8 @@ export class Address { */ toJSON(): object { return { - bech32: this.bech32(), - pubkey: this.hex(), + bech32: this.toBech32(), + pubkey: this.toHex(), }; } @@ -241,13 +249,13 @@ export class Address { * Use {@link isSmartContract} instead. */ isContractAddress(): boolean { - return this.hex().startsWith(SMART_CONTRACT_HEX_PUBKEY_PREFIX); + return this.isSmartContract(); } /** * Returns whether the address is a smart contract address. */ isSmartContract(): boolean { - return this.isContractAddress(); + return this.toHex().startsWith(SMART_CONTRACT_HEX_PUBKEY_PREFIX); } }