Skip to content

Commit

Permalink
Merge pull request #268 from ElrondNetwork/erdjs-interaction
Browse files Browse the repository at this point in the history
Erdjs interaction examples
  • Loading branch information
claudiu725 authored Aug 9, 2021
2 parents c0f290e + 6a4aeb4 commit db080f7
Show file tree
Hide file tree
Showing 10 changed files with 411 additions and 0 deletions.
22 changes: 22 additions & 0 deletions contracts/examples/adder/interaction/Adder.erdjs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Adder

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, wallets: { alice } } = await erdjs.setupInteractive("local-testnet");

let adder = await erdSys.loadWrapper("contracts/examples/adder");

// Deploy the adder contract with an initial value of 42
await adder.sender(alice).gas(20_000_000).call.deploy(42);

// Check that the sum is 42
await adder.query.getSum().then((sum) => sum.toString());

await adder.gas(3_000_000).call.add(30);

// Check that the sum is 72
await adder.query.getSum().then((sum) => sum.toString());

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Crowdfunding ESDT - Using EGLD

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, Egld, wallets: { alice, bob, carol }} = await erdjs.setupInteractive("local-testnet");

let crowdfunding = await erdSys.loadWrapper("contracts/examples/crowdfunding-esdt");

// Set the deadline to 1 minute from now (adjust this if you want more time before claiming the rewards)
let someTimeFromNow = await erdSys.currentNonce() + erdjs.minutesToNonce(1);

// Deploy the crowdfunding contract with a target of 2 EGLD
await crowdfunding.sender(alice).gas(50_000_000).call.deploy(Egld(2), someTimeFromNow, Egld);

// Bob and carol contribute 1.5 EGLD each
await crowdfunding.sender(bob).gas(10_000_000).value(Egld(1.5)).call.fund();
await crowdfunding.sender(carol).value(Egld(1.5)).call.fund();

// Get the current funds. Note the usage of Egld.raw (since the balance comes as an integer from the smart contract)
let currentFunds = Egld.raw(await crowdfunding.query.currentFunds());

// Should print 3 EGLD (since bob and carol added 1.5 EGLD each)
erdjs.print(currentFunds);

// Confirming the target is 2 EGLD
erdjs.print(Egld.raw(await crowdfunding.query.get_target()));

// Check that alice is the owner
alice.address.equals(await crowdfunding.query.get_owner());

// Store alice's current balance (we'll use this to check the balance difference later on)
let aliceBalanceBefore = await erdSys.getBalance(alice, Egld);
erdjs.print(aliceBalanceBefore);

// Wait a minute first, otherwise you'll get the "cannot claim before deadline" error
// If the claim doesn't return an error - there are two possibilities:
// - the funding failed, and 1.5 EGLD are sent back to both bob and carol
// - it was succesful and alice receives 3 EGLD
// Because the target sum specified on deployment was 2 EGLD, and we have 3 EGLD, the funding should be succesful
await crowdfunding.sender(alice).call.claim();

// Let's check if alice received the funds
let aliceBalanceAfter = await erdSys.getBalance(alice, Egld);
erdjs.print(aliceBalanceAfter);

// If the previous claim was successful, this prints 2.99 EGLD (because of the gas costs)
erdjs.print(aliceBalanceAfter.minus(aliceBalanceBefore));
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Crowdfunding ESDT - Using ESDT (Fungible token)

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, wallets: { alice, bob, carol } } = await erdjs.setupInteractive("local-testnet");

let crowdfunding = await erdSys.loadWrapper("contracts/examples/crowdfunding-esdt");

// Issue a new fungible token
let MyToken = await erdSys.sender(alice).issueFungible("MyFungibleToken", "MYTOKEN", 1_000_00, 2);

// Note: wait a few seconds, otherwise the first send fails
// Send some tokens to bob and carol (so that they can call fund later on)
await erdSys.sender(alice).value(MyToken(200.0)).send(bob);
await erdSys.sender(alice).value(MyToken(200.0)).send(carol);

// Set the deadline to 1 minute from now (adjust this if you want more time before claiming the rewards)
let someTimeFromNow = await erdSys.currentNonce() + erdjs.minutesToNonce(1);

// Deploy the crowdfunding contract
await crowdfunding.sender(alice).gas(50_000_000).call.deploy(MyToken(2), someTimeFromNow, MyToken);

// Bob and carol contribute 1.5 MYTOKEN each
await crowdfunding.sender(bob).gas(10_000_000).value(MyToken(1.5)).call.fund();
await crowdfunding.sender(carol).value(MyToken(1.5)).call.fund();

// Get the current funds. Note the usage of MyToken.raw (since the balance comes as an integer from the smart contract)
let currentFunds = MyToken.raw(await crowdfunding.query.currentFunds());

// Should print 3 MYTOKEN (since bob and carol added 1.5 MYTOKEN each)
erdjs.print(currentFunds);

// Confirming the target is 2 MYTOKEN
erdjs.print(MyToken.raw(await crowdfunding.query.get_target()));

// Check that alice is the owner
alice.address.equals(await crowdfunding.query.get_owner());

// Store alice's current balance (we'll use this to check the balance difference later on)
let aliceBalanceBefore = await erdSys.getBalance(alice, MyToken);
erdjs.print(aliceBalanceBefore);

// Wait a minute first, otherwise you'll get the "cannot claim before deadline" error
// If the claim doesn't return an error - there are two possibilities:
// - the funding failed, and 1.5 MYTOKEN are sent back to both bob and carol
// - it was succesful and alice receives 3 MYTOKEN
// Because the target sum specified on deployment was 2 MYTOKEN, and we have 3 MYTOKEN, the funding should be succesful
await crowdfunding.sender(alice).call.claim();

// Let's check if alice received the funds
let aliceBalanceAfter = await erdSys.getBalance(alice, MyToken);
erdjs.print(aliceBalanceAfter);

// If the previous claim was successful, this prints 3 MYTOKEN
erdjs.print(aliceBalanceAfter.minus(aliceBalanceBefore));
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Multisig

This contract uses a few uncommon concepts (eg. _quorum_), which These are explained in detail in the [README.md](../README.md).

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, Egld, wallets: { alice, bob, carol, dan, eve }} = await erdjs.setupInteractive("local-testnet");

let multisig = await erdSys.loadWrapper("contracts/examples/multisig");

// Deploy a multisig contract with a quorum of 3, but 4 possible signers: alice, bob, carol, dan
await multisig.sender(alice).gas(150_000_000).call.deploy(3, alice, bob, carol, dan);

// Deposit 10 EGLD from alice to the multisig contract, which we'll use them in the next examples
await multisig.gas(20_000_000).sender(alice).value(Egld(10)).call.deposit();

// Create a proposal to send 3 EGLD from the multisig to eve
// Note that any proposal is automatically signed by alice
var sendId = await multisig.sender(alice).call.proposeSendEgld(eve, Egld(3));

// Sign the previous proposal 2 more times
await multisig.sender(bob).call.sign(sendId);
await multisig.sender(carol).call.sign(sendId);

// This will return 3, which means that the quorum has been reached
await multisig.query.getActionValidSignerCount(sendId);

// Perform the send
await multisig.call.performAction(sendId);

// Let's use the adder contract as the nested contract which is to be managed by the multisig
let adder = await erdSys.loadWrapper("contracts/examples/adder");

// Validate and pack the arguments into a FormattedCall object
// Note: this doesn't deploy the contract (this will be done through the proposal below)
let formattedDeploy = adder.format.deploy(42);

// A proposal to deploy the adder smart contract. The formattedCall is automatically expanded.
var deployId = await multisig.sender(alice).gas(200_000_000).call.proposeSCDeploy(Egld(0), await adder.getCode(), false, false, false, formattedDeploy);

// Sign the deployment 2 more times
await multisig.sender(bob).gas(20_000_000).call.sign(deployId);
await multisig.sender(carol).call.sign(deployId);

// Perform the deploy. The address of the deployed adder will be returned.
var deployAddress = await multisig.call.performAction(deployId);

// Check the deploy address. bech32() will output it as erd1...
deployAddress.bech32();

// We can also access the adder smart contract by setting its deployed address to the smart contract wrapper instance.
// Let's check that the sum is 42 (the sum provided through the constructor).
await adder.address(deployAddress).sender(alice).query.getSum();

// Create a proposal on calling the "add" method
let formattedAdd = adder.format.add(1000);
var addId = await multisig.sender(alice).call.proposeSCCall(adder, Egld(0), formattedAdd);

// Sign the add proposal
await multisig.sender(bob).call.sign(addId);
await multisig.sender(carol).call.sign(addId);

// Before performing the "add" action, the sum should still be 42
await adder.sender(alice).query.getSum();

// Add 1000
await multisig.gas(40_000_000).call.performAction(addId);

// After adding, the sum should be 1042
await adder.sender(alice).query.getSum();
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Ping-pong

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, Egld, wallets: { alice, bob, carol, dan } } = await erdjs.setupInteractive("local-testnet");

let pingPong = await erdSys.loadWrapper("contracts/examples/ping-pong-egld");

await pingPong.sender(alice).gas(150_000_000).call.deploy(Egld(0.5), 2 * 60, null, Egld(1.5));

await pingPong.gas(20_000_000).sender(alice).value(Egld(0.5)).ping("note 1");

await pingPong.sender(bob).value(Egld(0.5)).ping(null);
await pingPong.sender(carol).value(Egld(0.5)).ping(null);

// this fails because of the balance limit of 1.5 egld
await pingPong.sender(dan).value(Egld(0.5).ping(null);

await pingPong.pongAll();

```
33 changes: 33 additions & 0 deletions tutorial/src/interaction/esdt-FT-fungible-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Fungible Tokens (FT)

Fungible Tokens have variable amounts, but always have nonce 0. They may be denominated.

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, wallets: { alice, bob, carol } } = await erdjs.setupInteractive("local-testnet");

// Issue a new fungible token
let MyToken = await erdSys.sender(alice).issueFungible("MyFungibleToken", "MYTOKEN", 1_000_00, 2);

// Check the token's identifier
console.log(MyToken.getTokenIdentifier());

// Note: if you have the token identifier, you can recall the token via:
// let MyToken = await erdSys.recallToken("MYTOKEN-a4fc62");

// Check alice's token balance
// Note: if the balance comes up as 0, wait some time and try again
await erdSys.getBalance(alice, MyToken).then(erdjs.print);

// Send some tokens to bob
await erdSys.sender(alice).value(MyToken(200.0)).send(bob);

// Check alice's balance (should be 800.00 MYTOKEN)
await erdSys.getBalance(alice, MyToken).then(erdjs.print);

// Check bob's balance (should be 200.00 MYTOKEN)
await erdSys.getBalance(bob, MyToken).then(erdjs.print);

```
29 changes: 29 additions & 0 deletions tutorial/src/interaction/esdt-NFT-non-fungible-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Non-Fungible Tokens (NFTs)

Non-Fungible Tokens have amounts of either 0 or 1, and variable nonce. They are not denominated (the amount has 0 decimals).

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, Egld, wallets: { alice, bob, carol } } = await erdjs.setupInteractive("local-testnet");

// Issue a new non-fungible token
let MyToken = await erdSys.sender(alice).issueNonFungible("MyFungibleToken", "MYTOKEN");

// Check the token's identifier
console.log(MyToken.getTokenIdentifier());

await erdSys.esdtSystemContract.sender(alice).call.setSpecialRole(MyToken, alice, "ESDTRoleNFTCreate");

// Create 2 tokens
let MyFirstNFT = await erdSys.sender(alice).esdtNftCreate(MyToken, 1, "MyFirstNFT", 0, "", "", "https://example.com");
let MySecondNFT = await erdSys.sender(alice).esdtNftCreate(MyToken, 1, "MySecondNFT", 0, "", "", "https://example.com");

// Send some tokens to bob and carol
await erdSys.sender(alice).value(MyFirstNFT.one()).send(bob);
await erdSys.sender(alice).value(MySecondNFT.one()).send(carol);

await erdSys.getBalanceList(alice, MyToken).then(erdjs.printList);
await erdSys.getBalanceList(bob, MyToken).then(erdjs.printList);
```
32 changes: 32 additions & 0 deletions tutorial/src/interaction/esdt-SFT-semi-fungible-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Semi-Fungible Tokens (SFTs).

Semi-Fungible Tokens have variable amounts, and variable nonce. They are not denominated (the amount has 0 decimals).

First [set up a node terminal](../../../../tutorial/src/interaction/interaction-basic.md).

```javascript
let erdjs = await require('@elrondnetwork/erdjs');
let { erdSys, Egld, wallets: { alice, bob, carol } } = await erdjs.setupInteractive("local-testnet");

// Issue a new semi-fungible token
let MyToken = await erdSys.sender(alice).issueSemiFungible("MySemiFungibleToken", "MYTOKEN");

// Check the token's identifier
console.log(MyToken.getTokenIdentifier());

await erdSys.esdtSystemContract.sender(alice).call.setSpecialRole(MyToken, alice, "ESDTRoleNFTCreate", "ESDTRoleNFTAddQuantity");

// Create a new nonce
let MyFirstSemi = await erdSys.sender(alice).esdtNftCreate(MyToken, 1_000, "MyFirstSemi", 0, "", "", "https://example.com");

// Check alice's token balance
// Note: if the balance comes up as 0, wait some time and try again
await erdSys.getBalance(alice, MyFirstSemi).then(erdjs.print);

// Send some tokens to bob and carol
await erdSys.sender(alice).value(MyFirstSemi(200)).send(bob);

await erdSys.getBalance(alice, MyFirstSemi).then(erdjs.print);
await erdSys.getBalance(bob, MyFirstSemi).then(erdjs.print);

```
36 changes: 36 additions & 0 deletions tutorial/src/interaction/interaction-basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Preparations

# Setting up the local testnet

The following examples rely on having a [local testnet](https://docs.elrond.com/developers/setup-local-testnet/) up and running.

# Installing @elrondnetwork/erdjs globally

```bash
cd ./code/elrond-sdk-erdjs
npm run compile && npm test && npm install -g
```

# How to start a node terminal

By exporting `NODE_PATH`, the node terminal should have access to `erdjs`.
Open a terminal and enter the following:

```bash
cd ./code/elrond-wasm-rs
export NODE_PATH=$HOME/.nvm/versions/node/$(node --version)/lib/node_modules
node --experimental-repl-await
```

# Basic ESDT usage

- [Fungible Tokens (FTs)](esdt-FT-fungible-tokens.md)
- [Semi-Fungible Tokens (SFTs)](esdt-SFT-semi-fungible-tokens.md)
- [Non-Fungible Tokens (NFTs)](esdt-NFT-non-fungible-tokens.md)

# Smart contract examples

- Adder [interaction](../../../contracts/examples/adder/interaction/Adder.erdjs.md)
- Crowdfunding ESDT [EGLD interaction](../../../contracts/examples/crowdfunding-esdt/interaction/Crowdfunding-egld.erdjs.md), [ESDT interaction](../../../contracts/examples/crowdfunding-esdt/interaction/Crowdfunding-esdt.erdjs.md)
- Multisig [EGLD adder interaction](../../../contracts/examples/multisig/interaction/Multisig-adder-egld.erdjs.md)
- Ping-pong [EGLD interaction](../../../contracts/examples/ping-pong-egld/interaction/Ping-pong-egld.erdjs.md)
Loading

0 comments on commit db080f7

Please sign in to comment.