Skip to content

Commit

Permalink
feat: transfer tokens clause builder (#445)
Browse files Browse the repository at this point in the history
* chore: workaround for unserializable bigint in tests by jest

* feat: transferToken & transferVET

* refactor: new error messaging format

* feat: vip180 ABI

* test: transferVET & transferToken cases

* refactor: transfer tokens clause builder usage in examples

* refactor: transfer tokens clause builder usage in transactions example

* refactor: code duplication & minor

* fix: update ABI

* chore: code duplication exclusion for ABIs
  • Loading branch information
pierobassa authored Jan 9, 2024
1 parent d22eff7 commit 51d4919
Show file tree
Hide file tree
Showing 21 changed files with 739 additions and 311 deletions.
11 changes: 5 additions & 6 deletions docs/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,11 @@ Once the contract is compiled, we can deploy it using the vechain SDK. The follo

import { expect } from 'expect';
import {
erc20ContractABI,
erc20ContractBytecode,
privateKeyDeployer,
thorSoloClient
} from './fixture.js';
import { addressUtils } from '@vechainfoundation/vechain-sdk-core';
import { addressUtils, VIP180_ABI } from '@vechainfoundation/vechain-sdk-core';

// Deploying the ERC20 contract using the Thor client and the deployer's private key
const transaction = await thorSoloClient.contracts.deployContract(
Expand All @@ -167,7 +166,7 @@ expect(receipt.reverted).toEqual(false);
// Executing a contract call to get the balance of the account that deployed the contract
const balance = await thorSoloClient.contracts.executeContractCall(
receipt.outputs[0].contractAddress,
erc20ContractABI,
VIP180_ABI,
'balanceOf',
[addressUtils.fromPrivateKey(Buffer.from(privateKeyDeployer, 'hex'))]
);
Expand All @@ -183,13 +182,13 @@ expect(parseInt(balance, 16)).toEqual(1e24);
Once the contract is deployed, we can transfer tokens to another address using the vechain SDK. The following code shows how to transfer 10000 token smallest unit to another address:

```typescript { name=contract-transfer-erc20-token, category=example }
import { VIP180_ABI } from '@vechainfoundation/vechain-sdk-core';
import {
erc20ContractABI,
privateKeyDeployer,
setupERC20Contract,
thorSoloClient
} from './fixture.js';
import { TransactionReceipt } from '@vechainfoundation/vechain-sdk-network';
import { type TransactionReceipt } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';

// Setting up the ERC20 contract and getting its address
Expand All @@ -200,7 +199,7 @@ const transferResult =
await thorSoloClient.contracts.executeContractTransaction(
privateKeyDeployer, // Using deployer's private key to authorize the transaction
contractAddress, // Contract address to which the transaction is sent
erc20ContractABI, // ABI of the ERC20 contract
VIP180_ABI, // ABI of the ERC20 contract
'transfer', // Name of the function to be executed in the contract
['0x9e7911de289c3c856ce7f421034f66b6cde49c39', 10000] // Arguments for the 'transfer' function: recipient address and amount
);
Expand Down
5 changes: 2 additions & 3 deletions docs/examples/contracts/contract-create-ERC20-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import { expect } from 'expect';
import {
erc20ContractABI,
erc20ContractBytecode,
privateKeyDeployer,
thorSoloClient
} from './fixture.js';
import { addressUtils } from '@vechainfoundation/vechain-sdk-core';
import { addressUtils, VIP180_ABI } from '@vechainfoundation/vechain-sdk-core';

// Deploying the ERC20 contract using the Thor client and the deployer's private key
const transaction = await thorSoloClient.contracts.deployContract(
Expand All @@ -26,7 +25,7 @@ expect(receipt.reverted).toEqual(false);
// Executing a contract call to get the balance of the account that deployed the contract
const balance = await thorSoloClient.contracts.executeContractCall(
receipt.outputs[0].contractAddress,
erc20ContractABI,
VIP180_ABI,
'balanceOf',
[addressUtils.fromPrivateKey(Buffer.from(privateKeyDeployer, 'hex'))]
);
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/contracts/contract-transfer-ERC20-token.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { VIP180_ABI } from '@vechainfoundation/vechain-sdk-core';
import {
erc20ContractABI,
privateKeyDeployer,
setupERC20Contract,
thorSoloClient
} from './fixture.js';
import { TransactionReceipt } from '@vechainfoundation/vechain-sdk-network';
import { type TransactionReceipt } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';

// Setting up the ERC20 contract and getting its address
Expand All @@ -15,7 +15,7 @@ const transferResult =
await thorSoloClient.contracts.executeContractTransaction(
privateKeyDeployer, // Using deployer's private key to authorize the transaction
contractAddress, // Contract address to which the transaction is sent
erc20ContractABI, // ABI of the ERC20 contract
VIP180_ABI, // ABI of the ERC20 contract
'transfer', // Name of the function to be executed in the contract
['0x9e7911de289c3c856ce7f421034f66b6cde49c39', 10000] // Arguments for the 'transfer' function: recipient address and amount
);
Expand Down
173 changes: 0 additions & 173 deletions docs/examples/contracts/fixture.ts

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/examples/thor-client/delegated-transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
TransactionUtils,
TransactionHandler,
dataUtils,
unitsUtils
unitsUtils,
contract
} from '@vechainfoundation/vechain-sdk-core';
import { HttpClient, ThorClient } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';
Expand All @@ -21,11 +22,10 @@ const latestBlock = await thorSoloClient.blocks.getBestBlock();
// 3 - Create transaction clauses

const clauses = [
{
to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39',
value: unitsUtils.parseVET('10000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x9e7911de289c3c856ce7f421034f66b6cde49c39',
unitsUtils.parseVET('10000')
)
];

// Get gas @NOTE this is an approximation
Expand Down
12 changes: 6 additions & 6 deletions docs/examples/thor-client/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
TransactionUtils,
TransactionHandler,
dataUtils,
unitsUtils
unitsUtils,
contract
} from '@vechainfoundation/vechain-sdk-core';
import { HttpClient, ThorClient } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';
Expand All @@ -21,11 +22,10 @@ const latestBlock = await thorSoloClient.blocks.getBestBlock();
// 3 - Create clauses

const clauses = [
{
to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39',
value: unitsUtils.parseVET('10000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x9e7911de289c3c856ce7f421034f66b6cde49c39',
unitsUtils.parseVET('10000')
)
];

// 4 - Create transaction
Expand Down
12 changes: 6 additions & 6 deletions docs/examples/transactions/blockref_expiration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import {
networkInfo,
type TransactionClause,
type TransactionBody,
unitsUtils
unitsUtils,
contract
} from '@vechainfoundation/vechain-sdk-core';
import { expect } from 'expect';

// 1 - Define clauses

const clauses: TransactionClause[] = [
{
to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
value: unitsUtils.parseVET('1000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseVET('1000')
)
];

// 2 - Define transaction body
Expand Down
11 changes: 5 additions & 6 deletions docs/examples/transactions/fee_delegation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { networkInfo } from '@vechainfoundation/vechain-sdk-core';
import { contract, networkInfo } from '@vechainfoundation/vechain-sdk-core';
import {
Transaction,
secp256k1,
Expand All @@ -15,11 +15,10 @@ import { expect } from 'expect';
// 1 - Define clause

const clauses: TransactionClause[] = [
{
to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
value: unitsUtils.parseVET('10000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseVET('10000')
)
];

// 2 - Define transaction body
Expand Down
27 changes: 14 additions & 13 deletions docs/examples/transactions/multiple_clauses.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { networkInfo } from '@vechainfoundation/vechain-sdk-core';
import {
VTHO_ADDRESS,
contract,
networkInfo
} from '@vechainfoundation/vechain-sdk-core';
import {
Transaction,
secp256k1,
Expand All @@ -13,18 +17,15 @@ import { expect } from 'expect';
// 1 - Define multiple clauses

const clauses: TransactionClause[] = [
{
to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
value: unitsUtils.parseVET('10000').toString(), // VET transfer clause
data: '0x'
},
{
to: '0x0000000000000000000000000000456E65726779',
value: 0, // Contract call to transfer VTHO
data: '0xa9059cbb0000000000000000000000007567d83b7b8d80addcb\
281a71d54fc7b3364ffed0000000000000000000000000000000000000000\
0000000000000000000003e8'
}
contract.clauseBuilder.transferVET(
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseVET('10000')
),
contract.clauseBuilder.transferToken(
VTHO_ADDRESS,
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseUnits('10000', 18) // 10000 VTHO
)
];

// 2 - Calculate intrinsic gas of both clauses
Expand Down
11 changes: 5 additions & 6 deletions docs/examples/transactions/sign_decode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { networkInfo } from '@vechainfoundation/vechain-sdk-core';
import { contract, networkInfo } from '@vechainfoundation/vechain-sdk-core';
import {
Transaction,
secp256k1,
Expand All @@ -13,11 +13,10 @@ import { expect } from 'expect';
// 1 - Define clauses

const clauses: TransactionClause[] = [
{
to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
value: unitsUtils.parseVET('10000').toString(),
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseVET('10000')
)
];

// 2 - Calculate intrinsic gas of clauses
Expand Down
11 changes: 5 additions & 6 deletions docs/examples/transactions/simulation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from 'expect';
import { HttpClient, ThorClient } from '@vechainfoundation/vechain-sdk-network';
import { unitsUtils } from '@vechainfoundation/vechain-sdk-core';
import { contract, unitsUtils } from '@vechainfoundation/vechain-sdk-core';

// In this example we simulate a transaction of sending 1 VET to another account
// And we demonstrate (1) how we can check the expected gas cost and (2) whether the transaction is successful
Expand All @@ -13,11 +13,10 @@ const thorSoloClient = new ThorClient(soloNetwork);
// 2(a) - create the transaction for a VET transfer
const transaction1 = {
clauses: [
{
to: '0xb717b660cd51109334bd10b2c168986055f58c1a',
value: unitsUtils.parseVET('1').toString(), // converts from 1 VET to wei
data: '0x'
}
contract.clauseBuilder.transferVET(
'0xb717b660cd51109334bd10b2c168986055f58c1a',
unitsUtils.parseVET('1')
)
],
// Please note - this field one of the optional fields that may be passed (see SimulateTransactionOptions),
// and is only required if you want to simulate a transaction
Expand Down
20 changes: 9 additions & 11 deletions docs/examples/transactions/tx_dependency.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { networkInfo } from '@vechainfoundation/vechain-sdk-core';
import { contract, networkInfo } from '@vechainfoundation/vechain-sdk-core';
import {
Transaction,
secp256k1,
Expand All @@ -13,18 +13,16 @@ import { expect } from 'expect';
// 1 - Define transaction clauses

const txAClauses: TransactionClause[] = [
{
to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
value: unitsUtils.parseVET('1000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x7567d83b7b8d80addcb281a71d54fc7b3364ffed',
unitsUtils.parseVET('1000')
)
];
const txBClauses: TransactionClause[] = [
{
to: '0x7ccadeea14dd6727845b58f8aa7aad0f41a002a2',
value: 2000, // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x7ccadeea14dd6727845b58f8aa7aad0f41a002a2',
unitsUtils.parseVET('1')
)
];

// 2 - Define transaction A with no dependencies
Expand Down
24 changes: 12 additions & 12 deletions docs/thor-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,8 @@ import {
TransactionUtils,
TransactionHandler,
dataUtils,
unitsUtils
unitsUtils,
contract
} from '@vechainfoundation/vechain-sdk-core';
import { HttpClient, ThorClient } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';
Expand All @@ -344,11 +345,10 @@ const latestBlock = await thorSoloClient.blocks.getBestBlock();
// 3 - Create clauses

const clauses = [
{
to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39',
value: unitsUtils.parseVET('10000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x9e7911de289c3c856ce7f421034f66b6cde49c39',
unitsUtils.parseVET('10000')
)
];

// 4 - Create transaction
Expand Down Expand Up @@ -429,7 +429,8 @@ import {
TransactionUtils,
TransactionHandler,
dataUtils,
unitsUtils
unitsUtils,
contract
} from '@vechainfoundation/vechain-sdk-core';
import { HttpClient, ThorClient } from '@vechainfoundation/vechain-sdk-network';
import { expect } from 'expect';
Expand All @@ -447,11 +448,10 @@ const latestBlock = await thorSoloClient.blocks.getBestBlock();
// 3 - Create transaction clauses

const clauses = [
{
to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39',
value: unitsUtils.parseVET('10000').toString(), // VET transfer transaction
data: '0x'
}
contract.clauseBuilder.transferVET(
'0x9e7911de289c3c856ce7f421034f66b6cde49c39',
unitsUtils.parseVET('10000')
)
];

// Get gas @NOTE this is an approximation
Expand Down
Loading

1 comment on commit 51d4919

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage

Summary

Lines Statements Branches Functions
Coverage: 100%
100% (1481/1481) 100% (329/329) 100% (306/306)
Title Tests Skipped Failures Errors Time
core 390 0 💤 0 ❌ 0 🔥 1m 20s ⏱️
network 159 0 💤 0 ❌ 0 🔥 2m 7s ⏱️
errors 40 0 💤 0 ❌ 0 🔥 9.274s ⏱️

Please sign in to comment.