Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how

## Unreleased
- [Breaking change: adjustements to transaction awaitening and completion, transaction watcher](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/173)
- [Breaking change: simplify network config / improve design - not a singleton anymore](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/176)

**Breaking changes**
- Removed utility functions: `transaction.awaitExecuted()`, `transaction.awaitPending()`. `TransactionWatcher` should be used directly, instead.
- Changed interface of `TransactionWatcher`. The constructor does not expect a transaction hash anymore, but the functions `await*` do.
- Introduced new functions on `TransactionWatcher`: `awaitCompleted()`, `awaitAllEvents()`, `awaitAnyEvent()` etc.
- Removed `Transaction.status` (the one on `TransactionOnNetwork` should be read instead).
- `Transaction.getAsOnNetwork()` does not wait for notarization / completion anymore. One should explicitly use the transaction watcher, when needed.
- Removed `NetworkConfig.getDefault()` and `NetworkConfig.sync()`. Instead, one should use `let networkConfig = await provider.getNetworkConfig()`.
- Constructor of `Transaction` now requires `chainID`, as well.
- Added `Interaction.withChainID()` - must be used before calling `buildTransaction()`.

## [10.0.0-beta.3]
- [Extract dapp / signing providers to separate repositories](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/170)
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ For advanced smart contract interaction, using ABIs, please see the following te
- [abiRegistry.spec.ts](https://github.com/ElrondNetwork/elrond-sdk-erdjs/tree/main/src/smartcontracts/typesystem/abiRegistry.spec.ts)
- [argSerializer.spec.ts](https://github.com/ElrondNetwork/elrond-sdk-erdjs/tree/main/src/smartcontracts/argSerializer.spec.ts)

### Synchronizing network parameters
### Fetching network parameters

```
let provider = new ProxyProvider("https://localhost:7950");
await NetworkConfig.getDefault().sync(provider);

console.log(NetworkConfig.getDefault().MinGasPrice);
console.log(NetworkConfig.getDefault().ChainID);
let network = await provider.getNetworkConfig();
console.log(network.MinGasPrice);
console.log(network.ChainID);
```

### Synchronizing an account object
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const JSONbig = require("json-bigint");

export const TRANSACTION_MIN_GAS_PRICE = 1000000000;
export const TRANSACTION_OPTIONS_DEFAULT = 0;
export const TRANSACTION_OPTIONS_TX_HASH_SIGN = 1;
export const TRANSACTION_VERSION_DEFAULT = 1;
Expand Down
1 change: 0 additions & 1 deletion src/interactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export async function setupInteractive(providerChoice: string): Promise<Interact
}

export async function setupInteractiveWithProvider(provider: IProvider): Promise<InteractivePackage> {
await NetworkConfig.getDefault().sync(provider);
let wallets = await loadAndSyncTestWallets(provider);
let erdSys = await SystemWrapper.load(provider);
return { erdSys, Egld, wallets };
Expand Down
23 changes: 0 additions & 23 deletions src/networkConfig.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import BigNumber from "bignumber.js";
import { IProvider } from "./interface";
import { GasPrice, GasLimit, TransactionVersion, ChainID, GasPriceModifier } from "./networkParams";

/**
* An object holding Network configuration parameters.
*/
export class NetworkConfig {
private static default: NetworkConfig;

/**
* The chain ID. E.g. "1" for the Mainnet.
*/
Expand Down Expand Up @@ -69,26 +66,6 @@ export class NetworkConfig {
this.MinTransactionVersion = new TransactionVersion(1);
}

/**
* Gets the default configuration object (think of the Singleton pattern).
*/
static getDefault(): NetworkConfig {
if (!NetworkConfig.default) {
NetworkConfig.default = new NetworkConfig();
}

return NetworkConfig.default;
}

/**
* Synchronizes a configuration object by querying the Network, through a {@link IProvider}.
* @param provider The provider to use
*/
async sync(provider: IProvider): Promise<void> {
let fresh: NetworkConfig = await provider.getNetworkConfig();
Object.assign(this, fresh);
}

/**
* Constructs a configuration object from a HTTP response (as returned by the provider).
*/
Expand Down
40 changes: 6 additions & 34 deletions src/networkParams.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { TransactionPayload } from "./transactionPayload";
import { NetworkConfig } from "./networkConfig";
import * as errors from "./errors";
import { Egld } from "./balanceBuilder";
import {
TRANSACTION_MIN_GAS_PRICE,
TRANSACTION_OPTIONS_DEFAULT,
TRANSACTION_OPTIONS_TX_HASH_SIGN,
TRANSACTION_VERSION_DEFAULT, TRANSACTION_VERSION_TX_HASH_SIGN
Expand Down Expand Up @@ -30,17 +28,8 @@ export class GasPrice {
this.value = value;
}

toDenominated(): string {
let asBalance = Egld.raw(this.value.toString(10));
return asBalance.toDenominated();
}

/**
* Creates a GasPrice object using the minimum value.
*/
static min(): GasPrice {
let value = NetworkConfig.getDefault().MinGasPrice.value;
return new GasPrice(value);
return new GasPrice(TRANSACTION_MIN_GAS_PRICE);
}

valueOf(): number {
Expand Down Expand Up @@ -70,27 +59,6 @@ export class GasLimit {
this.value = value;
}

/**
* Creates a GasLimit object for a value-transfer {@link Transaction}.
*/
static forTransfer(data: TransactionPayload): GasLimit {
let value = NetworkConfig.getDefault().MinGasLimit.value;

if (data) {
value += NetworkConfig.getDefault().GasPerDataByte * data.length();
}

return new GasLimit(value);
}

/**
* Creates a GasLimit object using the minimum value.
*/
static min(): GasLimit {
let value = NetworkConfig.getDefault().MinGasLimit.value;
return new GasLimit(value);
}

add(other: GasLimit): GasLimit {
return new GasLimit(this.value + other.value);
}
Expand Down Expand Up @@ -118,6 +86,10 @@ export class ChainID {
this.value = value;
}

static unspecified(): ChainID {
return new ChainID("?");
}

valueOf(): string {
return this.value;
}
Expand Down
3 changes: 2 additions & 1 deletion src/proto/serializer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TransactionPayload } from "../transactionPayload";
describe("serialize transactions", () => {
let wallets: Record<string, TestWallet>;
let serializer = new ProtoSerializer();

before(async function () {
wallets = await loadTestWallets();
});
Expand All @@ -21,7 +22,7 @@ describe("serialize transactions", () => {
value: Balance.Zero(),
receiver: wallets.bob.address,
gasPrice: GasPrice.min(),
gasLimit: GasLimit.min(),
gasLimit: new GasLimit(50000),
chainID: new ChainID("local-testnet")
});

Expand Down
46 changes: 27 additions & 19 deletions src/smartcontracts/interaction.local.net.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Interaction } from "./interaction";
import { GasLimit } from "../networkParams";
import { ReturnCode } from "./returnCode";
import BigNumber from "bignumber.js";
import { NetworkConfig } from "../networkConfig";
import { BytesValue } from "./typesystem/bytes";
import { chooseProxyProvider } from "../interactive";

Expand All @@ -28,24 +27,25 @@ describe("test smart contract interactor", function () {
let contract = new SmartContract({ abi: abi });
let controller = new DefaultSmartContractController(abi, provider);

// Currently, this has to be called before creating any Interaction objects,
// because the Transaction objects created under the hood point to the "default" NetworkConfig.
await NetworkConfig.getDefault().sync(provider);
let network = await provider.getNetworkConfig();
await alice.sync(provider);

// Deploy the contract
let deployTransaction = contract.deploy({
code: await loadContractCode("src/testdata/answer.wasm"),
gasLimit: new GasLimit(3000000),
initArguments: []
initArguments: [],
chainID: network.ChainID
});

deployTransaction.setNonce(alice.account.getNonceThenIncrement());
await alice.signer.sign(deployTransaction);
let { bundle: { returnCode } } = await controller.deploy(deployTransaction);
assert.isTrue(returnCode.isSuccess());

let interaction = <Interaction>contract.methods.getUltimateAnswer().withGasLimit(new GasLimit(3000000));
let interaction = <Interaction>contract.methods.getUltimateAnswer()
.withGasLimit(new GasLimit(3000000))
.withChainID(network.ChainID);

// Query
let queryResponseBundle = await controller.query(interaction);
Expand Down Expand Up @@ -75,16 +75,15 @@ describe("test smart contract interactor", function () {
let contract = new SmartContract({ abi: abi });
let controller = new DefaultSmartContractController(abi, provider);

// Currently, this has to be called before creating any Interaction objects,
// because the Transaction objects created under the hood point to the "default" NetworkConfig.
await NetworkConfig.getDefault().sync(provider);
let network = await provider.getNetworkConfig();
await alice.sync(provider);

// Deploy the contract
let deployTransaction = contract.deploy({
code: await loadContractCode("src/testdata/counter.wasm"),
gasLimit: new GasLimit(3000000),
initArguments: []
initArguments: [],
chainID: network.ChainID
});

deployTransaction.setNonce(alice.account.getNonceThenIncrement());
Expand All @@ -93,8 +92,12 @@ describe("test smart contract interactor", function () {
assert.isTrue(returnCode.isSuccess());

let getInteraction = <Interaction>contract.methods.get();
let incrementInteraction = (<Interaction>contract.methods.increment()).withGasLimit(new GasLimit(3000000));
let decrementInteraction = (<Interaction>contract.methods.decrement()).withGasLimit(new GasLimit(3000000));
let incrementInteraction = (<Interaction>contract.methods.increment())
.withGasLimit(new GasLimit(3000000))
.withChainID(network.ChainID);
let decrementInteraction = (<Interaction>contract.methods.decrement())
.withGasLimit(new GasLimit(3000000))
.withChainID(network.ChainID);

// Query "get()"
let { firstValue: counterValue } = await controller.query(getInteraction);
Expand Down Expand Up @@ -125,16 +128,15 @@ describe("test smart contract interactor", function () {
let contract = new SmartContract({ abi: abi });
let controller = new DefaultSmartContractController(abi, provider);

// Currently, this has to be called before creating any Interaction objects,
// because the Transaction objects created under the hood point to the "default" NetworkConfig.
await NetworkConfig.getDefault().sync(provider);
let network = await provider.getNetworkConfig();
await alice.sync(provider);

// Deploy the contract
let deployTransaction = contract.deploy({
code: await loadContractCode("src/testdata/lottery-esdt.wasm"),
gasLimit: new GasLimit(100000000),
initArguments: []
initArguments: [],
chainID: network.ChainID
});

deployTransaction.setNonce(alice.account.getNonceThenIncrement());
Expand All @@ -152,15 +154,21 @@ describe("test smart contract interactor", function () {
OptionValue.newMissing(),
OptionValue.newMissing(),
OptionalValue.newMissing()
]).withGasLimit(new GasLimit(30000000));
])
.withGasLimit(new GasLimit(30000000))
.withChainID(network.ChainID);

let lotteryStatusInteraction = <Interaction>contract.methods.status([
BytesValue.fromUTF8("lucky")
]).withGasLimit(new GasLimit(5000000));
])
.withGasLimit(new GasLimit(5000000))
.withChainID(network.ChainID);

let getLotteryInfoInteraction = <Interaction>contract.methods.getLotteryInfo([
BytesValue.fromUTF8("lucky")
]).withGasLimit(new GasLimit(5000000));
])
.withGasLimit(new GasLimit(5000000))
.withChainID(network.ChainID);

// start()
let startTransaction = startInteraction.useThenIncrementNonceOf(alice.account).buildTransaction();
Expand Down
7 changes: 4 additions & 3 deletions src/smartcontracts/interaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { SmartContractAbi } from "./abi";
import { Address } from "../address";
import { assert } from "chai";
import { Interaction } from "./interaction";
import { GasLimit } from "../networkParams";
import { ChainID, GasLimit } from "../networkParams";
import { ContractFunction } from "./function";
import { QueryResponse } from "./queryResponse";
import { Nonce } from "../nonce";
Expand Down Expand Up @@ -40,7 +40,7 @@ describe("test smart contract interactor", function() {
let transaction = interaction
.withNonce(new Nonce(7))
.withValue(Balance.egld(1))
.withGasLimitComponents({ estimatedExecutionComponent: 20000000 })
.withGasLimitComponents({ minGasLimit: 50000, gasPerDataByte: 1500, estimatedExecutionComponent: 20000000 })
.buildTransaction();

let expectedGasLimit = new GasLimit(50000)
Expand Down Expand Up @@ -116,7 +116,8 @@ describe("test smart contract interactor", function() {

let interaction = <Interaction>contract.methods
.getUltimateAnswer()
.withGasLimit(new GasLimit(543210));
.withGasLimit(new GasLimit(543210))
.withChainID(new ChainID("T"));

assert.equal(contract.getAddress(), dummyAddress);
assert.deepEqual(interaction.getFunction(), new ContractFunction("getUltimateAnswer"));
Expand Down
25 changes: 19 additions & 6 deletions src/smartcontracts/interaction.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Balance } from "../balance";
import { GasLimit } from "../networkParams";
import { ChainID, GasLimit, GasPrice } from "../networkParams";
import { Transaction } from "../transaction";
import { Query } from "./query";
import { ContractFunction } from "./function";
import { Address } from "../address";
import { AddressValue, BigUIntValue, BytesValue, TypedValue, U64Value, U8Value } from "./typesystem";
import { Nonce } from "../nonce";
import { NetworkConfig } from "../networkConfig";
import { ESDTNFT_TRANSFER_FUNCTION_NAME, ESDT_TRANSFER_FUNCTION_NAME, MULTI_ESDTNFT_TRANSFER_FUNCTION_NAME } from "../constants";
import { Account } from "../account";
import { CallArguments } from "./interface";
Expand All @@ -33,7 +32,9 @@ export class Interaction {

private nonce: Nonce = new Nonce(0);
private value: Balance = Balance.Zero();
private gasLimit: GasLimit = GasLimit.min();
private gasLimit: GasLimit = new GasLimit(0);
private gasPrice: GasPrice | undefined = undefined;
private chainID: ChainID = ChainID.unspecified();
private querent: Address = new Address();

private isWithSingleESDTTransfer: boolean = false;
Expand Down Expand Up @@ -104,10 +105,12 @@ export class Interaction {
func: func,
// GasLimit will be set using "withGasLimit()".
gasLimit: this.gasLimit,
gasPrice: this.gasPrice,
args: args,
// Value will be set using "withValue()".
value: this.value,
receiver: receiver,
chainID: this.chainID
});

transaction.setNonce(this.nonce);
Expand Down Expand Up @@ -155,9 +158,9 @@ export class Interaction {
return this;
}

withGasLimitComponents(args: { minGasLimit?: number, gasPerDataByte?: number, estimatedExecutionComponent: number }): Interaction {
let minGasLimit = args.minGasLimit || NetworkConfig.getDefault().MinGasLimit.valueOf();
let gasPerDataByte = args.gasPerDataByte || NetworkConfig.getDefault().GasPerDataByte;
withGasLimitComponents(args: { minGasLimit: number, gasPerDataByte: number, estimatedExecutionComponent: number }): Interaction {
let minGasLimit = args.minGasLimit;
let gasPerDataByte = args.gasPerDataByte;

let transaction = this.buildTransaction();
let dataLength = transaction.getData().length();
Expand All @@ -168,6 +171,11 @@ export class Interaction {
return this.withGasLimit(gasLimit);
}

withGasPrice(gasPrice: GasPrice): Interaction {
this.gasPrice = gasPrice;
return this;
}

withNonce(nonce: Nonce): Interaction {
this.nonce = nonce;
return this;
Expand All @@ -177,6 +185,11 @@ export class Interaction {
return this.withNonce(account.getNonceThenIncrement());
}

withChainID(chainID: ChainID): Interaction {
this.chainID = chainID;
return this;
}

/**
* Sets the "caller" field on contract queries.
*/
Expand Down
Loading