From 4c9fa87f85d2f6d312893361e9c79562f1bb2d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodolfo=20Pietro=20Calabr=C3=B2?= <33911400+rodolfopietro97@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:46:23 +0100 Subject: [PATCH] chore: Improve doc examples (#334) * fix: move builddocs.ts in build-scripts folder * fix: typo --- docs/accounts.md | 90 +++++++----- docs/bloom-filter.md | 12 +- docs/{ => build-scripts}/builddocs.ts | 0 docs/certificates.md | 10 +- docs/contracts.md | 21 ++- docs/cryptography.md | 27 +++- docs/encoding.md | 33 +++-- docs/examples/accounts/bip32.ts | 16 +- docs/examples/accounts/bip39.ts | 17 ++- docs/examples/accounts/keystore.ts | 58 ++++---- docs/examples/accounts/pubkey.ts | 11 +- docs/examples/bloom/bloom.ts | 12 +- docs/examples/certificates/sign_verify.ts | 10 +- docs/examples/contracts/contract-deploy.ts | 7 + .../contracts/contract-function-call.ts | 14 +- docs/examples/cryptography/blake2b256.ts | 7 +- docs/examples/cryptography/keccak256.ts | 2 + docs/examples/cryptography/secp256k1.ts | 18 ++- docs/examples/encoding/abi.ts | 14 +- docs/examples/encoding/contract.ts | 9 +- docs/examples/encoding/rlp.ts | 10 +- docs/examples/polls/event-poll-dapp.ts | 9 +- .../polls/sync-poll-wait-balance-update.ts | 2 + .../polls/sync-poll-wait-new-block.ts | 1 + docs/examples/thorest-client/accounts.ts | 19 ++- docs/examples/thorest-client/blocks.ts | 23 +-- .../thorest-client/delegated-transactions.ts | 36 +++-- docs/examples/thorest-client/logs.ts | 17 +-- docs/examples/thorest-client/nodes.ts | 12 +- docs/examples/thorest-client/transactions.ts | 29 ++-- .../transactions/blockref_expiration.ts | 22 ++- docs/examples/transactions/fee_delegation.ts | 37 +++-- .../examples/transactions/multiple_clauses.ts | 19 ++- docs/examples/transactions/sign_decode.ts | 19 ++- docs/examples/transactions/tx_dependency.ts | 41 +++--- docs/package.json | 2 +- docs/polls.md | 12 +- docs/thorest-client.md | 136 ++++++++--------- docs/transactions.md | 138 ++++++++++-------- 39 files changed, 585 insertions(+), 387 deletions(-) rename docs/{ => build-scripts}/builddocs.ts (100%) diff --git a/docs/accounts.md b/docs/accounts.md index e5fef326f..3d2dd39a2 100644 --- a/docs/accounts.md +++ b/docs/accounts.md @@ -16,18 +16,23 @@ Mnemonics represent a standard human-readable approach to generate private keys. import { mnemonic } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Generate BIP39 mnemonic words, default to 12 words(128bit strength) -const rndMnemonic = mnemonic.generate(); +// 1 - Generate BIP39 mnemonic words, default to 12 words (128bit strength) + +const randomMnemonic = mnemonic.generate(); + +console.log('Mnemonic words', randomMnemonic); +// Mnemonic words: "w1 w2 ... w12" + +// 2 - Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. -// Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. // Defined for VET at https://github.com/satoshilabs/slips/blob/master/slip-0044.md -const privateKey = mnemonic.derivePrivateKey(rndMnemonic); +const privateKey = mnemonic.derivePrivateKey(randomMnemonic); + console.log(privateKey.toString('hex')); // ...SOME PRIVATE KEY... // In recovery process, validation is recommended -const ok = mnemonic.validate(rndMnemonic); -expect(ok).toBeTruthy(); +expect(mnemonic.validate(randomMnemonic)).toBeTruthy(); // true ``` @@ -37,15 +42,19 @@ expect(ok).toBeTruthy(); ```typescript { name=bip32, category=example } import { mnemonic, HDNode } from '@vechainfoundation/vechain-sdk-core'; -// Generate BIP39 mnemonic words, default to 12 words(128bit strength) -const rndMnemonic = mnemonic.generate(); -console.log('Mnemonic words', rndMnemonic); +// 1 - Generate BIP39 mnemonic words, default to 12 words (128bit strength) + +const randomMnemonic = mnemonic.generate(); + +console.log('Mnemonic words', randomMnemonic); // Mnemonic words: "w1 w2 ... w12" -// Create BIP32 HD node from mnemonic words -const hdnode = HDNode.fromMnemonic(rndMnemonic); +// 2 - Create BIP32 HD node from mnemonic words + +const hdnode = HDNode.fromMnemonic(randomMnemonic); + +// 3 - Derive 5 child private keys -// Derive 5 child private keys for (let i = 0; i < 5; i++) { const child = hdnode.derive(i); console.log(`children ${i}`, child.address); @@ -62,22 +71,27 @@ for (let i = 0; i < 5; i++) { ```typescript { name=pubkey, category=example } import { HDNode } from '@vechainfoundation/vechain-sdk-core'; -// Create HD node from xpub +// 1 - Create HD node from xpub (extended private key) and chain code + const xpub = Buffer.from( '04dc40b4324626eb393dbf77b6930e915dcca6297b42508adb743674a8ad5c69a046010f801a62cb945a6cb137a050cefaba0572429fc4afc57df825bfca2f219a', 'hex' ); + const chainCode = Buffer.from( '105da5578eb3228655a8abe70bf4c317e525c7f7bb333634f5b7d1f70e111a33', 'hex' ); -// Create BIP32 HD node from xpub +// 2 - Create BIP32 HD node from xpub + const hdnode = HDNode.fromPublicKey(xpub, chainCode); -// Derive 5 child public keys +// 3 - Derive 5 child public keys + for (let i = 0; i < 5; i++) { const child = hdnode.derive(i); + console.log(`children ${i}`, child.address); // children 0 0x... // children 1 0x... @@ -97,36 +111,34 @@ Through the use of mnemonics and keystore, Vechain SDK ensures secure and user-f import { keystore, secp256k1 } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -async function example(): Promise { - // Create private key +// 1 - Create private key using Secp256k1 - // BIP 39 - // const words = mnemonic.generate() - // const privateKey = mnemonic.derivePrivateKey(words) +const privateKey = secp256k1.generatePrivateKey(); - // Secp256k1 - const privateKey = secp256k1.generatePrivateKey(); +// @NOTE you can use BIP 39 too! +// const words = mnemonic.generate() +// const privateKey = mnemonic.derivePrivateKey(words) - // ... +// ... - // Encrypt/decrypt private key using Ethereum's keystore scheme - const keyStorePassword = 'your password'; - const newKeyStore = await keystore.encrypt(privateKey, keyStorePassword); +// 2 - Encrypt/decrypt private key using Ethereum's keystore scheme - // Throw for wrong password - const recoveredPrivateKey = await keystore.decrypt( - newKeyStore, - keyStorePassword - ); - console.log(recoveredPrivateKey.privateKey.toString()); - // ... +const keyStorePassword = 'your password'; +const newKeyStore = await keystore.encrypt(privateKey, keyStorePassword); - // Roughly check keystore format - const ok = keystore.isValid(newKeyStore); - expect(ok).toBeTruthy(); - // Key store ok true -} -await example(); +// 3 - Throw for wrong password + +const recoveredPrivateKey = await keystore.decrypt( + newKeyStore, + keyStorePassword +); + +console.log(recoveredPrivateKey.privateKey.toString()); +// 0x... + +// Roughly check keystore format +expect(keystore.isValid(newKeyStore)).toBeTruthy(); +// Key store ok true ``` diff --git a/docs/bloom-filter.md b/docs/bloom-filter.md index eee5f0dc5..820f057aa 100644 --- a/docs/bloom-filter.md +++ b/docs/bloom-filter.md @@ -28,19 +28,23 @@ By employing bloom filters in this manner, the VechainThor blockchain significan import { bloom } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Get best value of k (bits per key) +// 1 - Get best value of k (bits per key) + const k = bloom.calculateK(100); console.log(k); -// Create a bloom filter with 14 bits +// 2 - Create a bloom filter with 14 bits + const bloomGenerator = new bloom.Generator(); -// Add number from 0 to 99 to the bloom gernator +// 3 - Add number from 0 to 99 to the bloom gernator + for (let i = 0; i < 100; i++) { bloomGenerator.add(Buffer.from(i + '', 'utf8')); } -// Create the filter +// 4 - Create the filter + const bloomFilter = bloomGenerator.generate(100, k); // Positive case (number from 0 to 99 must be present in the bloom filter) diff --git a/docs/builddocs.ts b/docs/build-scripts/builddocs.ts similarity index 100% rename from docs/builddocs.ts rename to docs/build-scripts/builddocs.ts diff --git a/docs/certificates.md b/docs/certificates.md index 857e3b651..8db881dde 100644 --- a/docs/certificates.md +++ b/docs/certificates.md @@ -42,15 +42,14 @@ import { addressUtils } from '@vechainfoundation/vechain-sdk-core'; -// In this example we create a certificate and -// sign it, and then call verify to verify the signature +// 1 - Generate a private key and address for the signer -// Generate a private key and address for the signer const privateKey = secp256k1.generatePrivateKey(); const publicKey = secp256k1.derivePublicKey(privateKey); const signerAddress = addressUtils.fromPublicKey(publicKey); -// Create a certificate +// 2 - Create a certificate + const cert: Certificate = { purpose: 'identification', payload: { @@ -62,7 +61,8 @@ const cert: Certificate = { signer: signerAddress }; -// Sign certificate +// 3 - Sign certificate + const jsonStr = certificate.encode(cert); const signature = secp256k1.sign(blake2b256(jsonStr), privateKey); diff --git a/docs/contracts.md b/docs/contracts.md index 90e931ab6..6bb7c58c5 100644 --- a/docs/contracts.md +++ b/docs/contracts.md @@ -10,10 +10,17 @@ This example showcases the process of building a smart contract transaction usin import { buildDeployContractTransaction } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Init contract bytecode to deploy + const contractBytecode = '0x608060405234801561000f575f80fd5b506101438061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c806360fe47b1146100385780636d4ce63c14610054575b5f80fd5b610052600480360381019061004d91906100ba565b610072565b005b61005c61007b565b60405161006991906100f4565b60405180910390f35b805f8190555050565b5f8054905090565b5f80fd5b5f819050919050565b61009981610087565b81146100a3575f80fd5b50565b5f813590506100b481610090565b92915050565b5f602082840312156100cf576100ce610083565b5b5f6100dc848285016100a6565b91505092915050565b6100ee81610087565b82525050565b5f6020820190506101075f8301846100e5565b9291505056fea2646970667358221220427ff5682ef89b62b910bb1286c1028d32283512122854159ad59f1c71fb6d8764736f6c63430008160033'; +// 2 - Create a transaction to deploy the contract + const transaction = buildDeployContractTransaction(contractBytecode); +console.log(transaction); + +// The first clause of the transaction should be a deploy contract clause expect(transaction.body.clauses[0].data).toEqual(contractBytecode); ``` @@ -37,9 +44,14 @@ This example provides a practical demonstration of utilizing the Vechain SDK to This example demonstrates the process of building a transaction to call a function on a deployed smart contract using the Vechain SDK. ```typescript { name=contract-function-call, category=example } -import { networkInfo, buildCallContractTransaction } from '@vechainfoundation/vechain-sdk-core'; +import { + networkInfo, + buildCallContractTransaction +} from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Init a simple contract ABI + const contractABI = JSON.stringify([ { constant: false, @@ -71,6 +83,8 @@ const contractABI = JSON.stringify([ } ]); +// 2 - Create a transaction to call setValue(123) + const transaction = buildCallContractTransaction( '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', // just a sample deployed contract address contractABI, @@ -78,10 +92,13 @@ const transaction = buildCallContractTransaction( [123] ); -// check the parameters of the transaction +// 3 - Check the parameters of the transaction + expect(transaction.body.clauses[0].to).toBe( '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed' ); + +// Some checks on the transaction body expect(transaction.body.clauses[0].value).toBe(0); expect(transaction.body.clauses[0].data).toBeDefined(); expect(transaction.body.nonce).toBeDefined(); diff --git a/docs/cryptography.md b/docs/cryptography.md index a1396e353..362b63393 100644 --- a/docs/cryptography.md +++ b/docs/cryptography.md @@ -15,10 +15,15 @@ vechain sdk supports blake2b256 and keccak256 hash functions. Blake2b256 is a specific type of hash function known for its speed and security. It takes any input data and generates a 256-bit (32-byte) hash value. The blake2b256 part refers to the specific design of the algorithm, and the 256 indicates the length of the resulting hash code. Blake2b256 is widely used in cryptographic applications, blockchain technologies, and secure data storage. ```typescript { name=blake2b256, category=example } -import { blake2b256, type HashInput } from '@vechainfoundation/vechain-sdk-core'; +import { + blake2b256, + type HashInput +} from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// Input of hash function (it can be a string or a Buffer) const toHash: HashInput = 'hello world'; + const hash = blake2b256(toHash); expect(hash.toString('hex')).toBe( '256c83b297114d201b30179f3f0ef0cace9783622da5974326b436178aeef610' @@ -34,7 +39,9 @@ Keccak256 is another type of hash function, and it's particularly well-known for import { keccak256, type HashInput } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// Input of hash function (it can be a string or a Buffer) const toHash: HashInput = 'hello world'; + const hash = keccak256(toHash); expect(hash.toString('hex')).toBe( '47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad' @@ -63,29 +70,33 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Generate a private key +// 1 - Generate a private key + const privateKey = secp256k1.generatePrivateKey(); console.log('Private key:', privateKey.toString('hex')); // Private key: ...SOME_PRIVATE_KEY... -// Public key and address from private key +// 2 - Derive public key and address from private key + const publicKey = secp256k1.derivePublicKey(privateKey); const userAddress = addressUtils.fromPublicKey(publicKey); console.log('User address:', userAddress); // User address: 0x...SOME_ADDRESS... -// Sign message +// 3 - Sign message + const messageToSign: HashInput = 'hello world'; const hash = keccak256(messageToSign); console.log(`Hash: ${hash.toString()}`); + const signature = secp256k1.sign(hash, privateKey); console.log('Signature:', signature.toString('hex')); // Signature: ...SOME_SIGNATURE... -// Test recovery -const recoveredPubKey = secp256k1.recover(hash, signature); -const equals = publicKey.equals(recoveredPubKey); -expect(equals).toBeTruthy(); +// 4 - Test recovery of public key + +const recoveredPublicKey = secp256k1.recover(hash, signature); +expect(publicKey.equals(recoveredPublicKey)).toBeTruthy(); // Recovered public key is correct: true ``` diff --git a/docs/encoding.md b/docs/encoding.md index 9c294d514..79f01695f 100644 --- a/docs/encoding.md +++ b/docs/encoding.md @@ -14,7 +14,8 @@ Vechain SDK provides functionality to interact with smart contracts on the Vecha import { abi } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Create a new function +// 1 - Create a simple function to encode into ABI + const simpleAbiFunction = new abi.Function({ constant: false, inputs: [ @@ -43,16 +44,19 @@ const simpleAbiFunction = new abi.Function({ type: 'function' }); -// Encode function -const data = simpleAbiFunction.encodeInput([1, 'foo']); -// Check encoding +// 2 - Encode function + +const encodedFunction = simpleAbiFunction.encodeInput([1, 'foo']); + +// 3 - Check encoding + const expected = '0x27fcbb2f0000000000000000000000000000000000000000000000000000\ 00000000000100000000000000000000000000000000000000000000000000\ 00000000000040000000000000000000000000000000000000000000000000\ 0000000000000003666f6f0000000000000000000000000000000000000000\ 000000000000000000'; -expect(data).toBe(expected); +expect(encodedFunction).toBe(expected); ``` @@ -64,6 +68,8 @@ The contract interface is used to provide a higher level of abstraction to allow import { contract } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Create a new function + const contractABI = JSON.stringify([ { constant: false, @@ -95,14 +101,19 @@ const contractABI = JSON.stringify([ } ]); +// 2 - Encode the function input, ready to be used to send a tx + const encodedData = contract.encodeFunctionInput(contractABI, 'setValue', [ 123 -]); // encode the function input, ready to be used to send a tx +]); + +// 3 - Decode the function input data const decodedData = String( contract.decodeFunctionInput(contractABI, 'setValue', encodedData)[0] ); // decode the function input data +// Check the decoded data expect(decodedData).toEqual('123'); ``` @@ -117,7 +128,8 @@ By supporting ABI and RLP encoding handling, Vechain SDK equips developers with import { RLP } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Define the profile for tx clause structure +// 1 - Define the profile for tx clause structure + const profile = { name: 'clause', kind: [ @@ -127,14 +139,16 @@ const profile = { ] }; -// Create clauses +// 2 - Create clauses + const clause = { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', value: 10, data: '0x' }; -// Instace RLP +// 3 - RLP Instance to encode and decode + const rlp = new RLP.Profiler(profile); // Encoding and Decoding @@ -143,6 +157,7 @@ expect(data.toString('hex')).toBe( 'd7947567d83b7b8d80addcb281a71d54fc7b3364ffed0a80' ); +// Decode the data const obj = rlp.decodeObject(data); expect(JSON.stringify(obj)).toBe(JSON.stringify(clause)); diff --git a/docs/examples/accounts/bip32.ts b/docs/examples/accounts/bip32.ts index ae21ac978..39c315787 100644 --- a/docs/examples/accounts/bip32.ts +++ b/docs/examples/accounts/bip32.ts @@ -1,14 +1,18 @@ import { mnemonic, HDNode } from '@vechainfoundation/vechain-sdk-core'; -// Generate BIP39 mnemonic words, default to 12 words(128bit strength) -const rndMnemonic = mnemonic.generate(); -console.log('Mnemonic words', rndMnemonic); +// 1 - Generate BIP39 mnemonic words, default to 12 words (128bit strength) + +const randomMnemonic = mnemonic.generate(); + +console.log('Mnemonic words', randomMnemonic); // Mnemonic words: "w1 w2 ... w12" -// Create BIP32 HD node from mnemonic words -const hdnode = HDNode.fromMnemonic(rndMnemonic); +// 2 - Create BIP32 HD node from mnemonic words + +const hdnode = HDNode.fromMnemonic(randomMnemonic); + +// 3 - Derive 5 child private keys -// Derive 5 child private keys for (let i = 0; i < 5; i++) { const child = hdnode.derive(i); console.log(`children ${i}`, child.address); diff --git a/docs/examples/accounts/bip39.ts b/docs/examples/accounts/bip39.ts index 7d7e93418..bf3cc1a94 100644 --- a/docs/examples/accounts/bip39.ts +++ b/docs/examples/accounts/bip39.ts @@ -1,16 +1,21 @@ import { mnemonic } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Generate BIP39 mnemonic words, default to 12 words(128bit strength) -const rndMnemonic = mnemonic.generate(); +// 1 - Generate BIP39 mnemonic words, default to 12 words (128bit strength) + +const randomMnemonic = mnemonic.generate(); + +console.log('Mnemonic words', randomMnemonic); +// Mnemonic words: "w1 w2 ... w12" + +// 2 - Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. -// Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. // Defined for VET at https://github.com/satoshilabs/slips/blob/master/slip-0044.md -const privateKey = mnemonic.derivePrivateKey(rndMnemonic); +const privateKey = mnemonic.derivePrivateKey(randomMnemonic); + console.log(privateKey.toString('hex')); // ...SOME PRIVATE KEY... // In recovery process, validation is recommended -const ok = mnemonic.validate(rndMnemonic); -expect(ok).toBeTruthy(); +expect(mnemonic.validate(randomMnemonic)).toBeTruthy(); // true diff --git a/docs/examples/accounts/keystore.ts b/docs/examples/accounts/keystore.ts index 84d6f1a22..92ab58844 100644 --- a/docs/examples/accounts/keystore.ts +++ b/docs/examples/accounts/keystore.ts @@ -1,33 +1,31 @@ import { keystore, secp256k1 } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -async function example(): Promise { - // Create private key - - // BIP 39 - // const words = mnemonic.generate() - // const privateKey = mnemonic.derivePrivateKey(words) - - // Secp256k1 - const privateKey = secp256k1.generatePrivateKey(); - - // ... - - // Encrypt/decrypt private key using Ethereum's keystore scheme - const keyStorePassword = 'your password'; - const newKeyStore = await keystore.encrypt(privateKey, keyStorePassword); - - // Throw for wrong password - const recoveredPrivateKey = await keystore.decrypt( - newKeyStore, - keyStorePassword - ); - console.log(recoveredPrivateKey.privateKey.toString()); - // ... - - // Roughly check keystore format - const ok = keystore.isValid(newKeyStore); - expect(ok).toBeTruthy(); - // Key store ok true -} -await example(); +// 1 - Create private key using Secp256k1 + +const privateKey = secp256k1.generatePrivateKey(); + +// @NOTE you can use BIP 39 too! +// const words = mnemonic.generate() +// const privateKey = mnemonic.derivePrivateKey(words) + +// ... + +// 2 - Encrypt/decrypt private key using Ethereum's keystore scheme + +const keyStorePassword = 'your password'; +const newKeyStore = await keystore.encrypt(privateKey, keyStorePassword); + +// 3 - Throw for wrong password + +const recoveredPrivateKey = await keystore.decrypt( + newKeyStore, + keyStorePassword +); + +console.log(recoveredPrivateKey.privateKey.toString()); +// 0x... + +// Roughly check keystore format +expect(keystore.isValid(newKeyStore)).toBeTruthy(); +// Key store ok true diff --git a/docs/examples/accounts/pubkey.ts b/docs/examples/accounts/pubkey.ts index 13111a042..0d0a7f88d 100644 --- a/docs/examples/accounts/pubkey.ts +++ b/docs/examples/accounts/pubkey.ts @@ -1,21 +1,26 @@ import { HDNode } from '@vechainfoundation/vechain-sdk-core'; -// Create HD node from xpub +// 1 - Create HD node from xpub (extended private key) and chain code + const xpub = Buffer.from( '04dc40b4324626eb393dbf77b6930e915dcca6297b42508adb743674a8ad5c69a046010f801a62cb945a6cb137a050cefaba0572429fc4afc57df825bfca2f219a', 'hex' ); + const chainCode = Buffer.from( '105da5578eb3228655a8abe70bf4c317e525c7f7bb333634f5b7d1f70e111a33', 'hex' ); -// Create BIP32 HD node from xpub +// 2 - Create BIP32 HD node from xpub + const hdnode = HDNode.fromPublicKey(xpub, chainCode); -// Derive 5 child public keys +// 3 - Derive 5 child public keys + for (let i = 0; i < 5; i++) { const child = hdnode.derive(i); + console.log(`children ${i}`, child.address); // children 0 0x... // children 1 0x... diff --git a/docs/examples/bloom/bloom.ts b/docs/examples/bloom/bloom.ts index 040eebeaf..a469d6b59 100644 --- a/docs/examples/bloom/bloom.ts +++ b/docs/examples/bloom/bloom.ts @@ -1,19 +1,23 @@ import { bloom } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Get best value of k (bits per key) +// 1 - Get best value of k (bits per key) + const k = bloom.calculateK(100); console.log(k); -// Create a bloom filter with 14 bits +// 2 - Create a bloom filter with 14 bits + const bloomGenerator = new bloom.Generator(); -// Add number from 0 to 99 to the bloom gernator +// 3 - Add number from 0 to 99 to the bloom gernator + for (let i = 0; i < 100; i++) { bloomGenerator.add(Buffer.from(i + '', 'utf8')); } -// Create the filter +// 4 - Create the filter + const bloomFilter = bloomGenerator.generate(100, k); // Positive case (number from 0 to 99 must be present in the bloom filter) diff --git a/docs/examples/certificates/sign_verify.ts b/docs/examples/certificates/sign_verify.ts index b97d758ce..d53ced2dd 100644 --- a/docs/examples/certificates/sign_verify.ts +++ b/docs/examples/certificates/sign_verify.ts @@ -6,15 +6,14 @@ import { addressUtils } from '@vechainfoundation/vechain-sdk-core'; -// In this example we create a certificate and -// sign it, and then call verify to verify the signature +// 1 - Generate a private key and address for the signer -// Generate a private key and address for the signer const privateKey = secp256k1.generatePrivateKey(); const publicKey = secp256k1.derivePublicKey(privateKey); const signerAddress = addressUtils.fromPublicKey(publicKey); -// Create a certificate +// 2 - Create a certificate + const cert: Certificate = { purpose: 'identification', payload: { @@ -26,7 +25,8 @@ const cert: Certificate = { signer: signerAddress }; -// Sign certificate +// 3 - Sign certificate + const jsonStr = certificate.encode(cert); const signature = secp256k1.sign(blake2b256(jsonStr), privateKey); diff --git a/docs/examples/contracts/contract-deploy.ts b/docs/examples/contracts/contract-deploy.ts index 8422388ff..3b09eb988 100644 --- a/docs/examples/contracts/contract-deploy.ts +++ b/docs/examples/contracts/contract-deploy.ts @@ -1,8 +1,15 @@ import { buildDeployContractTransaction } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Init contract bytecode to deploy + const contractBytecode = '0x608060405234801561000f575f80fd5b506101438061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c806360fe47b1146100385780636d4ce63c14610054575b5f80fd5b610052600480360381019061004d91906100ba565b610072565b005b61005c61007b565b60405161006991906100f4565b60405180910390f35b805f8190555050565b5f8054905090565b5f80fd5b5f819050919050565b61009981610087565b81146100a3575f80fd5b50565b5f813590506100b481610090565b92915050565b5f602082840312156100cf576100ce610083565b5b5f6100dc848285016100a6565b91505092915050565b6100ee81610087565b82525050565b5f6020820190506101075f8301846100e5565b9291505056fea2646970667358221220427ff5682ef89b62b910bb1286c1028d32283512122854159ad59f1c71fb6d8764736f6c63430008160033'; +// 2 - Create a transaction to deploy the contract + const transaction = buildDeployContractTransaction(contractBytecode); +console.log(transaction); + +// The first clause of the transaction should be a deploy contract clause expect(transaction.body.clauses[0].data).toEqual(contractBytecode); diff --git a/docs/examples/contracts/contract-function-call.ts b/docs/examples/contracts/contract-function-call.ts index bebdc6beb..89af41829 100644 --- a/docs/examples/contracts/contract-function-call.ts +++ b/docs/examples/contracts/contract-function-call.ts @@ -1,6 +1,11 @@ -import { networkInfo, buildCallContractTransaction } from '@vechainfoundation/vechain-sdk-core'; +import { + networkInfo, + buildCallContractTransaction +} from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Init a simple contract ABI + const contractABI = JSON.stringify([ { constant: false, @@ -32,6 +37,8 @@ const contractABI = JSON.stringify([ } ]); +// 2 - Create a transaction to call setValue(123) + const transaction = buildCallContractTransaction( '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', // just a sample deployed contract address contractABI, @@ -39,10 +46,13 @@ const transaction = buildCallContractTransaction( [123] ); -// check the parameters of the transaction +// 3 - Check the parameters of the transaction + expect(transaction.body.clauses[0].to).toBe( '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed' ); + +// Some checks on the transaction body expect(transaction.body.clauses[0].value).toBe(0); expect(transaction.body.clauses[0].data).toBeDefined(); expect(transaction.body.nonce).toBeDefined(); diff --git a/docs/examples/cryptography/blake2b256.ts b/docs/examples/cryptography/blake2b256.ts index a5de93f14..442c9cba3 100644 --- a/docs/examples/cryptography/blake2b256.ts +++ b/docs/examples/cryptography/blake2b256.ts @@ -1,7 +1,12 @@ -import { blake2b256, type HashInput } from '@vechainfoundation/vechain-sdk-core'; +import { + blake2b256, + type HashInput +} from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// Input of hash function (it can be a string or a Buffer) const toHash: HashInput = 'hello world'; + const hash = blake2b256(toHash); expect(hash.toString('hex')).toBe( '256c83b297114d201b30179f3f0ef0cace9783622da5974326b436178aeef610' diff --git a/docs/examples/cryptography/keccak256.ts b/docs/examples/cryptography/keccak256.ts index b535e1734..de644a465 100644 --- a/docs/examples/cryptography/keccak256.ts +++ b/docs/examples/cryptography/keccak256.ts @@ -1,7 +1,9 @@ import { keccak256, type HashInput } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// Input of hash function (it can be a string or a Buffer) const toHash: HashInput = 'hello world'; + const hash = keccak256(toHash); expect(hash.toString('hex')).toBe( '47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad' diff --git a/docs/examples/cryptography/secp256k1.ts b/docs/examples/cryptography/secp256k1.ts index 898a08a7d..95b53b93d 100644 --- a/docs/examples/cryptography/secp256k1.ts +++ b/docs/examples/cryptography/secp256k1.ts @@ -6,27 +6,31 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Generate a private key +// 1 - Generate a private key + const privateKey = secp256k1.generatePrivateKey(); console.log('Private key:', privateKey.toString('hex')); // Private key: ...SOME_PRIVATE_KEY... -// Public key and address from private key +// 2 - Derive public key and address from private key + const publicKey = secp256k1.derivePublicKey(privateKey); const userAddress = addressUtils.fromPublicKey(publicKey); console.log('User address:', userAddress); // User address: 0x...SOME_ADDRESS... -// Sign message +// 3 - Sign message + const messageToSign: HashInput = 'hello world'; const hash = keccak256(messageToSign); console.log(`Hash: ${hash.toString()}`); + const signature = secp256k1.sign(hash, privateKey); console.log('Signature:', signature.toString('hex')); // Signature: ...SOME_SIGNATURE... -// Test recovery -const recoveredPubKey = secp256k1.recover(hash, signature); -const equals = publicKey.equals(recoveredPubKey); -expect(equals).toBeTruthy(); +// 4 - Test recovery of public key + +const recoveredPublicKey = secp256k1.recover(hash, signature); +expect(publicKey.equals(recoveredPublicKey)).toBeTruthy(); // Recovered public key is correct: true diff --git a/docs/examples/encoding/abi.ts b/docs/examples/encoding/abi.ts index 69614f57f..c08b40f34 100644 --- a/docs/examples/encoding/abi.ts +++ b/docs/examples/encoding/abi.ts @@ -1,7 +1,8 @@ import { abi } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Create a new function +// 1 - Create a simple function to encode into ABI + const simpleAbiFunction = new abi.Function({ constant: false, inputs: [ @@ -30,13 +31,16 @@ const simpleAbiFunction = new abi.Function({ type: 'function' }); -// Encode function -const data = simpleAbiFunction.encodeInput([1, 'foo']); -// Check encoding +// 2 - Encode function + +const encodedFunction = simpleAbiFunction.encodeInput([1, 'foo']); + +// 3 - Check encoding + const expected = '0x27fcbb2f0000000000000000000000000000000000000000000000000000\ 00000000000100000000000000000000000000000000000000000000000000\ 00000000000040000000000000000000000000000000000000000000000000\ 0000000000000003666f6f0000000000000000000000000000000000000000\ 000000000000000000'; -expect(data).toBe(expected); +expect(encodedFunction).toBe(expected); diff --git a/docs/examples/encoding/contract.ts b/docs/examples/encoding/contract.ts index f8ae9754b..e36cec18d 100644 --- a/docs/examples/encoding/contract.ts +++ b/docs/examples/encoding/contract.ts @@ -1,6 +1,8 @@ import { contract } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; +// 1 - Create a new function + const contractABI = JSON.stringify([ { constant: false, @@ -32,12 +34,17 @@ const contractABI = JSON.stringify([ } ]); +// 2 - Encode the function input, ready to be used to send a tx + const encodedData = contract.encodeFunctionInput(contractABI, 'setValue', [ 123 -]); // encode the function input, ready to be used to send a tx +]); + +// 3 - Decode the function input data const decodedData = String( contract.decodeFunctionInput(contractABI, 'setValue', encodedData)[0] ); // decode the function input data +// Check the decoded data expect(decodedData).toEqual('123'); diff --git a/docs/examples/encoding/rlp.ts b/docs/examples/encoding/rlp.ts index 841413a8c..f79621829 100644 --- a/docs/examples/encoding/rlp.ts +++ b/docs/examples/encoding/rlp.ts @@ -1,7 +1,8 @@ import { RLP } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// Define the profile for tx clause structure +// 1 - Define the profile for tx clause structure + const profile = { name: 'clause', kind: [ @@ -11,14 +12,16 @@ const profile = { ] }; -// Create clauses +// 2 - Create clauses + const clause = { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', value: 10, data: '0x' }; -// Instace RLP +// 3 - RLP Instance to encode and decode + const rlp = new RLP.Profiler(profile); // Encoding and Decoding @@ -27,5 +30,6 @@ expect(data.toString('hex')).toBe( 'd7947567d83b7b8d80addcb281a71d54fc7b3364ffed0a80' ); +// Decode the data const obj = rlp.decodeObject(data); expect(JSON.stringify(obj)).toBe(JSON.stringify(clause)); diff --git a/docs/examples/polls/event-poll-dapp.ts b/docs/examples/polls/event-poll-dapp.ts index 2d92804e6..9d5259e07 100644 --- a/docs/examples/polls/event-poll-dapp.ts +++ b/docs/examples/polls/event-poll-dapp.ts @@ -10,7 +10,7 @@ const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); const thorestClient = new ThorestClient(testNetwork); -// 2- Init accounts +// 2 - Init accounts const accounts = [ '0x2669514f9fe96bc7301177ba774d3da8a06cace4', @@ -24,18 +24,25 @@ for (const account of accounts) { async () => await thorestClient.accounts.getAccount(account), 1000 ) + // Add listeners for start event .onStart((eventPoll) => { console.log(`Start monitoring account ${account}`, eventPoll); }) + + // Add listeners for stop event .onStop((eventPoll) => { console.log(`Stop monitoring account ${account}`, eventPoll); }) + + // Add listeners for data event. It intercepts the account details every 1 second .onData((accountDetails, eventPoll) => { console.log(`Account details of ${account}:`, accountDetails); // Stop after 3 iterations - EXIT CONDITION if (eventPoll.getCurrentIteration === 3) eventPoll.stopListen(); }) + + // Add listeners for error event .onError((error) => { console.log('Error:', error); }); diff --git a/docs/examples/polls/sync-poll-wait-balance-update.ts b/docs/examples/polls/sync-poll-wait-balance-update.ts index a9e7bb4c8..854720ddc 100644 --- a/docs/examples/polls/sync-poll-wait-balance-update.ts +++ b/docs/examples/polls/sync-poll-wait-balance-update.ts @@ -95,6 +95,7 @@ expect(dataUtils.isHexString(sentedTransaction.id)).toBe(true); // 4 -Wait until balance is updated +// New balance of sender (wait until the balance is updated) const newBalanceSender = await Poll.SyncPoll( async () => (await thorestSoloClient.accounts.getAccount(sender.address)).balance @@ -102,6 +103,7 @@ const newBalanceSender = await Poll.SyncPoll( return newBalance !== senderBalanceBefore; }); +// New balance of receiver (wait until the balance is updated) const newBalanceReceiver = await Poll.SyncPoll( async () => (await thorestSoloClient.accounts.getAccount(receiver.address)).balance diff --git a/docs/examples/polls/sync-poll-wait-new-block.ts b/docs/examples/polls/sync-poll-wait-new-block.ts index 74fa2cd34..d984216e6 100644 --- a/docs/examples/polls/sync-poll-wait-new-block.ts +++ b/docs/examples/polls/sync-poll-wait-new-block.ts @@ -19,6 +19,7 @@ console.log('Current block:', currentBlock); // 3 - Wait until a new block is created +// Wait until a new block is created with polling interval of 3 seconds const newBlock = await Poll.SyncPoll( // Get the latest block as polling target function async () => await thorestClient.blocks.getBlock('best'), diff --git a/docs/examples/thorest-client/accounts.ts b/docs/examples/thorest-client/accounts.ts index 9bd9a3cfe..86c35fb32 100644 --- a/docs/examples/thorest-client/accounts.ts +++ b/docs/examples/thorest-client/accounts.ts @@ -4,29 +4,28 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Get account details -// Get account details -const accountDetails = await thorestTestnetClient.accounts.getAccount( +// Account details +const accountDetails = await thorestClient.accounts.getAccount( '0x5034aa590125b64023a0262112b98d72e3c8e40e' ); expect(accountDetails).toBeDefined(); -// Get account code -const accountCode = await thorestTestnetClient.accounts.getBytecode( +// Account code +const accountCode = await thorestClient.accounts.getBytecode( '0x5034aa590125b64023a0262112b98d72e3c8e40e' ); expect(accountCode).toEqual('0x'); // Get account storage -const accountStorage = await thorestTestnetClient.accounts.getStorageAt( +const accountStorage = await thorestClient.accounts.getStorageAt( '0x5034aa590125b64023a0262112b98d72e3c8e40e', '0x0000000000000000000000000000000000000000000000000000000000000001' ); diff --git a/docs/examples/thorest-client/blocks.ts b/docs/examples/thorest-client/blocks.ts index d0230e64e..9d49d471e 100644 --- a/docs/examples/thorest-client/blocks.ts +++ b/docs/examples/thorest-client/blocks.ts @@ -4,17 +4,16 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Get block details -// Get block details -const blockDetails = await thorestTestnetClient.blocks.getBlock(1); +// Details of block +const blockDetails = await thorestClient.blocks.getBlock(1); expect(blockDetails).toEqual({ number: 1, id: '0x000000019015bbd98fc1c9088d793ba9add53896a29cd9aa3a4dcabd1f561c38', @@ -40,10 +39,12 @@ expect(blockDetails).toEqual({ transactions: [] }); -// Get best block details -const bestBlockDetails = await thorestTestnetClient.blocks.getBestBlock(); +// 3 - Get best block details + +const bestBlockDetails = await thorestClient.blocks.getBestBlock(); expect(bestBlockDetails).toBeDefined(); -// Get finalizes block details -const finalBlockDetails = await thorestTestnetClient.blocks.getFinalBlock(); +// 4 - Get finalizes block details + +const finalBlockDetails = await thorestClient.blocks.getFinalBlock(); expect(finalBlockDetails).toBeDefined(); diff --git a/docs/examples/thorest-client/delegated-transactions.ts b/docs/examples/thorest-client/delegated-transactions.ts index 1e19b0859..fdcac0f0b 100644 --- a/docs/examples/thorest-client/delegated-transactions.ts +++ b/docs/examples/thorest-client/delegated-transactions.ts @@ -11,19 +11,18 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the solo network -const _soloUrl = 'http://localhost:8669'; +// 1 - Create client for solo network -// Solo network instance +const _soloUrl = 'http://localhost:8669'; const soloNetwork = new HttpClient(_soloUrl); - -// Thorest client solo instance const thorestSoloClient = new ThorestClient(soloNetwork); -// Get latest block +// 2 - Get latest block + const latestBlock = await thorestSoloClient.blocks.getBestBlock(); -// Create clauses +// 3 - Create transaction clauses + const clauses = [ { to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39', @@ -35,7 +34,8 @@ const clauses = [ // Get gas @NOTE this is an approximation const gas = 5000 + TransactionUtils.intrinsicGas(clauses) * 5; -// Create delegated transaction +// 4 - Create delegated transaction + const delegatedTransaction = new Transaction({ chainTag: 0xf6, blockRef: latestBlock !== null ? latestBlock.id.slice(0, 18) : '0x0', @@ -51,23 +51,25 @@ const delegatedTransaction = new Transaction({ }); // Private keys of sender -const pkSender = +const senderPrivateKey = 'ea5383ac1f9e625220039a4afac6a7f868bf1ad4f48ce3a1dd78bd214ee4ace5'; /** Private key of delegate * @NOTE The delegate account must have enough VET and VTHO to pay for the gas */ -const pkDelegate = +const delegatePrivateKey = '432f38bcf338c374523e83fdb2ebe1030aba63c7f1e81f7d76c5f53f4d42e766'; -// Normal signature and delegation signature +// 5 - Normal signature and delegation signature + const rawDelegatedSigned = TransactionHandler.signWithDelegator( delegatedTransaction, - Buffer.from(pkSender, 'hex'), - Buffer.from(pkDelegate, 'hex') + Buffer.from(senderPrivateKey, 'hex'), + Buffer.from(delegatePrivateKey, 'hex') ).encoded; -// Send transaction +// 6 - Send transaction + const send = await thorestSoloClient.transactions.sendTransaction( `0x${rawDelegatedSigned.toString('hex')}` ); @@ -75,10 +77,14 @@ expect(send).toBeDefined(); expect(send).toHaveProperty('id'); expect(dataUtils.isHexString(send.id)).toBe(true); -// Get transaction details and receipt +// 7 - Get transaction details and receipt + +// Details of transaction const transactionDetails = await thorestSoloClient.transactions.getTransaction( send.id ); + +// Receipt of transaction const transactionReceipt = await thorestSoloClient.transactions.getTransactionReceipt(send.id); diff --git a/docs/examples/thorest-client/logs.ts b/docs/examples/thorest-client/logs.ts index 403756741..da1dfb683 100644 --- a/docs/examples/thorest-client/logs.ts +++ b/docs/examples/thorest-client/logs.ts @@ -4,17 +4,15 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Filter event logs based on the provided criteria. (EXAMPLE 1) -// Filters event logs based on the provided criteria. -const eventLogs = await thorestTestnetClient.logs.filterEventLogs({ +const eventLogs = await thorestClient.logs.filterEventLogs({ // Specify the range of blocks to search for events range: { unit: 'block', @@ -96,8 +94,9 @@ expect(eventLogs).toEqual([ } ]); -// Filters transfer logs based on the provided criteria. -const transferLogs = await thorestTestnetClient.logs.filterTransferLogs({ +// 3 - Filter again event logs based on the provided criteria. (EXAMPLE 2) + +const transferLogs = await thorestClient.logs.filterTransferLogs({ // Specify the range of blocks to search for transfer events range: { unit: 'block', diff --git a/docs/examples/thorest-client/nodes.ts b/docs/examples/thorest-client/nodes.ts index bdd308403..035aefd7c 100644 --- a/docs/examples/thorest-client/nodes.ts +++ b/docs/examples/thorest-client/nodes.ts @@ -4,15 +4,13 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Retrieves connected peers of a node -// Retrieves connected peers of a node. -const peerNodes = await thorestTestnetClient.nodes.getNodes(); +const peerNodes = await thorestClient.nodes.getNodes(); expect(peerNodes).toBeDefined(); diff --git a/docs/examples/thorest-client/transactions.ts b/docs/examples/thorest-client/transactions.ts index 626217cbd..d81e036ff 100644 --- a/docs/examples/thorest-client/transactions.ts +++ b/docs/examples/thorest-client/transactions.ts @@ -11,19 +11,18 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the solo network -const _soloUrl = 'http://localhost:8669'; +// 1 - Create client for solo network -// Solo network instance +const _soloUrl = 'http://localhost:8669'; const soloNetwork = new HttpClient(_soloUrl); - -// Thorest client solo instance const thorestSoloClient = new ThorestClient(soloNetwork); -// Get latest block +// 2 - Get latest block + const latestBlock = await thorestSoloClient.blocks.getBestBlock(); -// Create clauses +// 3 - Create clauses + const clauses = [ { to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39', @@ -32,7 +31,8 @@ const clauses = [ } ]; -// Create transaction +// 4 - Create transaction + const transaction = new Transaction({ chainTag: 0xf6, blockRef: latestBlock !== null ? latestBlock.id.slice(0, 18) : '0x0', @@ -45,16 +45,18 @@ const transaction = new Transaction({ }); // Private keys of sender -const pkSender = +const senderPrivateKey = 'ea5383ac1f9e625220039a4afac6a7f868bf1ad4f48ce3a1dd78bd214ee4ace5'; -// Normal signature and delegation signature +// 5 - Normal signature (NO delegation) + const rawNormalSigned = TransactionHandler.sign( transaction, - Buffer.from(pkSender, 'hex') + Buffer.from(senderPrivateKey, 'hex') ).encoded; -// Send transaction +// 6 - Send transaction + const send = await thorestSoloClient.transactions.sendTransaction( `0x${rawNormalSigned.toString('hex')}` ); @@ -62,7 +64,8 @@ expect(send).toBeDefined(); expect(send).toHaveProperty('id'); expect(dataUtils.isHexString(send.id)).toBe(true); -// Get transaction details and receipt +// 7 - Get transaction details and receipt + const transactionDetails = await thorestSoloClient.transactions.getTransaction( send.id ); diff --git a/docs/examples/transactions/blockref_expiration.ts b/docs/examples/transactions/blockref_expiration.ts index 01f83c270..3f71dd231 100644 --- a/docs/examples/transactions/blockref_expiration.ts +++ b/docs/examples/transactions/blockref_expiration.ts @@ -10,10 +10,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a transaction is created that -// has its expiry set to a specified block height +// 1 - Define clauses -// Define clause const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -22,7 +20,8 @@ const clauses: TransactionClause[] = [ } ]; -// Body of transaction +// 2 - Define transaction body + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x00ffecb8ac3142c4', // first 8 bytes of block id from block #16772280 @@ -34,14 +33,21 @@ const body: TransactionBody = { nonce: 1 }; -// Create private key +// 3 - Create private key + const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction + +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction + +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check + +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.blockRef).toBe(body.blockRef); expect(decodedTx.body.expiration).toBe(body.expiration); diff --git a/docs/examples/transactions/fee_delegation.ts b/docs/examples/transactions/fee_delegation.ts index c58aa2ac5..7ed0bc439 100644 --- a/docs/examples/transactions/fee_delegation.ts +++ b/docs/examples/transactions/fee_delegation.ts @@ -12,10 +12,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a fee delegated transaction is -// created, signed (by both parties), encoded and then decoded +// 1 - Define clause -// Define clause const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -24,7 +22,8 @@ const clauses: TransactionClause[] = [ } ]; -// Body of transaction +// 2 - Define transaction body + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -39,24 +38,32 @@ const body: TransactionBody = { } }; -// Create private keys of sender and delegate -const pkSender = secp256k1.generatePrivateKey(); +// 3 - Create private keys of sender and delegate + +const senderPrivateKey = secp256k1.generatePrivateKey(); const nodeDelegate = HDNode.fromMnemonic(mnemonic.generate()); -const pkDelegate = nodeDelegate.privateKey; -// Get address of delegate -const addrDelegate = nodeDelegate.address; -// Sign transaction as sender and delegate +const delegatorPrivateKey = nodeDelegate.privateKey; + +// 4 - Get address of delegate + +const delegatorAddress = nodeDelegate.address; + +// 5 - Sign transaction as sender and delegate + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.signWithDelegator( unsignedTx, - pkSender, - pkDelegate + senderPrivateKey, + delegatorPrivateKey ); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check + +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.isDelegated).toBeTruthy(); -expect(decodedTx.delegator).toBe(addrDelegate); +expect(decodedTx.delegator).toBe(delegatorAddress); diff --git a/docs/examples/transactions/multiple_clauses.ts b/docs/examples/transactions/multiple_clauses.ts index 3457fa326..55c66815a 100644 --- a/docs/examples/transactions/multiple_clauses.ts +++ b/docs/examples/transactions/multiple_clauses.ts @@ -10,10 +10,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a multiple clause transaction is -// created, signed, encoded and then decoded +// 1 - Define multiple clauses -// Define multiple clauses const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -29,10 +27,12 @@ const clauses: TransactionClause[] = [ } ]; -// Calculate intrinsic gas of both clauses +// 2 - Calculate intrinsic gas of both clauses + const gas = TransactionUtils.intrinsicGas(clauses); -// Body of transaction +// 3 - Body of transaction + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -47,13 +47,16 @@ const body: TransactionBody = { // Create private key const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.clauses.length).toBe(clauses.length); diff --git a/docs/examples/transactions/sign_decode.ts b/docs/examples/transactions/sign_decode.ts index 9d2029064..8695d391b 100644 --- a/docs/examples/transactions/sign_decode.ts +++ b/docs/examples/transactions/sign_decode.ts @@ -10,10 +10,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a simple single clause transaction is -// created, signed, encoded and then decoded +// 1 - Define clauses -// Define clauses const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -22,10 +20,12 @@ const clauses: TransactionClause[] = [ } ]; -// Calculate intrinsic gas of clauses +// 2 - Calculate intrinsic gas of clauses + const gas = TransactionUtils.intrinsicGas(clauses); -// Body of transaction +// 3 - Body of transaction + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -40,14 +40,17 @@ const body: TransactionBody = { // Create private key const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.chainTag).toBe(body.chainTag); expect(decodedTx.body.nonce).toBe(body.nonce); diff --git a/docs/examples/transactions/tx_dependency.ts b/docs/examples/transactions/tx_dependency.ts index 1a04bf390..0d0cd10ca 100644 --- a/docs/examples/transactions/tx_dependency.ts +++ b/docs/examples/transactions/tx_dependency.ts @@ -10,10 +10,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example transaction A is created with no dependencies -// Transaction B is the created as being dependant on transaction A +// 1 - Define transaction clauses -// Define transaction clauses const txAClauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -29,8 +27,9 @@ const txBClauses: TransactionClause[] = [ } ]; -// Define transaction A with no dependencies -// Note: This transaction has nonce = 1 +// 2 - Define transaction A with no dependencies + +// @NOTE: This transaction has nonce = 1 const txABody: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -42,8 +41,9 @@ const txABody: TransactionBody = { nonce: 1 }; -// Define transaction B with nonce = 2 -// Note at the moment dependsOn is null +// 3 - Define transaction B with nonce = 2 + +// @NOTE: at the moment dependsOn is null const txBBody: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -56,25 +56,30 @@ const txBBody: TransactionBody = { }; // Define the senders private key -const pkSender = secp256k1.generatePrivateKey(); +const senderPrivateKey = secp256k1.generatePrivateKey(); // To define transaction B as dependant on transaction A // We need to sign transaction A, and then get its Id // and set that Id into transaction B's dependsOn field -// get tx A id +// 4 - Get Tx A id + const txAUnsigned = new Transaction(txABody); -const txASigned = TransactionHandler.sign(txAUnsigned, pkSender); -const txAId = txASigned.id; -// set it inside tx B -txBBody.dependsOn = txAId; +const txASigned = TransactionHandler.sign(txAUnsigned, senderPrivateKey); + +// 5 - Set it inside tx B + +txBBody.dependsOn = txASigned.id; + +// 6 - Sign Tx B -// sign Tx B const txBUnsigned = new Transaction(txBBody); -const txBSigned = TransactionHandler.sign(txBUnsigned, pkSender); -// encode Tx B +const txBSigned = TransactionHandler.sign(txBUnsigned, senderPrivateKey); + +// 7 - encode Tx B + const rawTxB = txBSigned.encoded; -// To check we can decode Tx B +// Check (we can decode Tx B) const decodedTx = TransactionHandler.decode(rawTxB, true); -expect(decodedTx.body.dependsOn).toBe(txAId); +expect(decodedTx.body.dependsOn).toBe(txASigned.id); diff --git a/docs/package.json b/docs/package.json index 45b280c39..ed2c6adbe 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,7 +7,7 @@ "test:before": "docker compose up -d", "test:after": "docker compose down", "test:examples": "yarn test:before && ts-node-test examples/ && yarn test:after", - "build": "find . -name \"*.md\" -type f -maxdepth 1 ! -name \"README.md\" -delete && tsup builddocs.ts && node dist/builddocs.cjs" + "build": "find . -name \"*.md\" -type f -maxdepth 1 ! -name \"README.md\" -delete && tsup ./build-scripts && node dist/builddocs.cjs" }, "dependencies": { "@vechainfoundation/vechain-sdk-core": "*", diff --git a/docs/polls.md b/docs/polls.md index c52e4f672..6efcf20db 100644 --- a/docs/polls.md +++ b/docs/polls.md @@ -29,6 +29,7 @@ console.log('Current block:', currentBlock); // 3 - Wait until a new block is created +// Wait until a new block is created with polling interval of 3 seconds const newBlock = await Poll.SyncPoll( // Get the latest block as polling target function async () => await thorestClient.blocks.getBlock('best'), @@ -147,6 +148,7 @@ expect(dataUtils.isHexString(sentedTransaction.id)).toBe(true); // 4 -Wait until balance is updated +// New balance of sender (wait until the balance is updated) const newBalanceSender = await Poll.SyncPoll( async () => (await thorestSoloClient.accounts.getAccount(sender.address)).balance @@ -154,6 +156,7 @@ const newBalanceSender = await Poll.SyncPoll( return newBalance !== senderBalanceBefore; }); +// New balance of receiver (wait until the balance is updated) const newBalanceReceiver = await Poll.SyncPoll( async () => (await thorestSoloClient.accounts.getAccount(receiver.address)).balance @@ -192,7 +195,7 @@ const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); const thorestClient = new ThorestClient(testNetwork); -// 2- Init accounts +// 2 - Init accounts const accounts = [ '0x2669514f9fe96bc7301177ba774d3da8a06cace4', @@ -206,18 +209,25 @@ for (const account of accounts) { async () => await thorestClient.accounts.getAccount(account), 1000 ) + // Add listeners for start event .onStart((eventPoll) => { console.log(`Start monitoring account ${account}`, eventPoll); }) + + // Add listeners for stop event .onStop((eventPoll) => { console.log(`Stop monitoring account ${account}`, eventPoll); }) + + // Add listeners for data event. It intercepts the account details every 1 second .onData((accountDetails, eventPoll) => { console.log(`Account details of ${account}:`, accountDetails); // Stop after 3 iterations - EXIT CONDITION if (eventPoll.getCurrentIteration === 3) eventPoll.stopListen(); }) + + // Add listeners for error event .onError((error) => { console.log('Error:', error); }); diff --git a/docs/thorest-client.md b/docs/thorest-client.md index 2099f0021..b9e216efa 100644 --- a/docs/thorest-client.md +++ b/docs/thorest-client.md @@ -17,29 +17,28 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Get account details -// Get account details -const accountDetails = await thorestTestnetClient.accounts.getAccount( +// Account details +const accountDetails = await thorestClient.accounts.getAccount( '0x5034aa590125b64023a0262112b98d72e3c8e40e' ); expect(accountDetails).toBeDefined(); -// Get account code -const accountCode = await thorestTestnetClient.accounts.getBytecode( +// Account code +const accountCode = await thorestClient.accounts.getBytecode( '0x5034aa590125b64023a0262112b98d72e3c8e40e' ); expect(accountCode).toEqual('0x'); // Get account storage -const accountStorage = await thorestTestnetClient.accounts.getStorageAt( +const accountStorage = await thorestClient.accounts.getStorageAt( '0x5034aa590125b64023a0262112b98d72e3c8e40e', '0x0000000000000000000000000000000000000000000000000000000000000001' ); @@ -76,17 +75,16 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Get block details -// Get block details -const blockDetails = await thorestTestnetClient.blocks.getBlock(1); +// Details of block +const blockDetails = await thorestClient.blocks.getBlock(1); expect(blockDetails).toEqual({ number: 1, id: '0x000000019015bbd98fc1c9088d793ba9add53896a29cd9aa3a4dcabd1f561c38', @@ -112,12 +110,14 @@ expect(blockDetails).toEqual({ transactions: [] }); -// Get best block details -const bestBlockDetails = await thorestTestnetClient.blocks.getBestBlock(); +// 3 - Get best block details + +const bestBlockDetails = await thorestClient.blocks.getBestBlock(); expect(bestBlockDetails).toBeDefined(); -// Get finalizes block details -const finalBlockDetails = await thorestTestnetClient.blocks.getFinalBlock(); +// 4 - Get finalizes block details + +const finalBlockDetails = await thorestClient.blocks.getFinalBlock(); expect(finalBlockDetails).toBeDefined(); ``` @@ -149,17 +149,15 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Filter event logs based on the provided criteria. (EXAMPLE 1) -// Filters event logs based on the provided criteria. -const eventLogs = await thorestTestnetClient.logs.filterEventLogs({ +const eventLogs = await thorestClient.logs.filterEventLogs({ // Specify the range of blocks to search for events range: { unit: 'block', @@ -241,8 +239,9 @@ expect(eventLogs).toEqual([ } ]); -// Filters transfer logs based on the provided criteria. -const transferLogs = await thorestTestnetClient.logs.filterTransferLogs({ +// 3 - Filter again event logs based on the provided criteria. (EXAMPLE 2) + +const transferLogs = await thorestClient.logs.filterTransferLogs({ // Specify the range of blocks to search for transfer events range: { unit: 'block', @@ -310,17 +309,15 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the testnet network -const _testnetUrl = 'https://testnet.vechain.org/'; +// 1 - Create client for testnet -// Testnet network instance +const _testnetUrl = 'https://testnet.vechain.org'; const testNetwork = new HttpClient(_testnetUrl); +const thorestClient = new ThorestClient(testNetwork); -// Thorest client testnet instance -const thorestTestnetClient = new ThorestClient(testNetwork); +// 2 - Retrieves connected peers of a node -// Retrieves connected peers of a node. -const peerNodes = await thorestTestnetClient.nodes.getNodes(); +const peerNodes = await thorestClient.nodes.getNodes(); expect(peerNodes).toBeDefined(); ``` @@ -349,19 +346,18 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the solo network -const _soloUrl = 'http://localhost:8669'; +// 1 - Create client for solo network -// Solo network instance +const _soloUrl = 'http://localhost:8669'; const soloNetwork = new HttpClient(_soloUrl); - -// Thorest client solo instance const thorestSoloClient = new ThorestClient(soloNetwork); -// Get latest block +// 2 - Get latest block + const latestBlock = await thorestSoloClient.blocks.getBestBlock(); -// Create clauses +// 3 - Create clauses + const clauses = [ { to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39', @@ -370,7 +366,8 @@ const clauses = [ } ]; -// Create transaction +// 4 - Create transaction + const transaction = new Transaction({ chainTag: 0xf6, blockRef: latestBlock !== null ? latestBlock.id.slice(0, 18) : '0x0', @@ -383,16 +380,18 @@ const transaction = new Transaction({ }); // Private keys of sender -const pkSender = +const senderPrivateKey = 'ea5383ac1f9e625220039a4afac6a7f868bf1ad4f48ce3a1dd78bd214ee4ace5'; -// Normal signature and delegation signature +// 5 - Normal signature (NO delegation) + const rawNormalSigned = TransactionHandler.sign( transaction, - Buffer.from(pkSender, 'hex') + Buffer.from(senderPrivateKey, 'hex') ).encoded; -// Send transaction +// 6 - Send transaction + const send = await thorestSoloClient.transactions.sendTransaction( `0x${rawNormalSigned.toString('hex')}` ); @@ -400,7 +399,8 @@ expect(send).toBeDefined(); expect(send).toHaveProperty('id'); expect(dataUtils.isHexString(send.id)).toBe(true); -// Get transaction details and receipt +// 7 - Get transaction details and receipt + const transactionDetails = await thorestSoloClient.transactions.getTransaction( send.id ); @@ -452,19 +452,18 @@ import { } from '@vechainfoundation/vechain-sdk-network'; import { expect } from 'expect'; -// Url of the solo network -const _soloUrl = 'http://localhost:8669'; +// 1 - Create client for solo network -// Solo network instance +const _soloUrl = 'http://localhost:8669'; const soloNetwork = new HttpClient(_soloUrl); - -// Thorest client solo instance const thorestSoloClient = new ThorestClient(soloNetwork); -// Get latest block +// 2 - Get latest block + const latestBlock = await thorestSoloClient.blocks.getBestBlock(); -// Create clauses +// 3 - Create transaction clauses + const clauses = [ { to: '0x9e7911de289c3c856ce7f421034f66b6cde49c39', @@ -476,7 +475,8 @@ const clauses = [ // Get gas @NOTE this is an approximation const gas = 5000 + TransactionUtils.intrinsicGas(clauses) * 5; -// Create delegated transaction +// 4 - Create delegated transaction + const delegatedTransaction = new Transaction({ chainTag: 0xf6, blockRef: latestBlock !== null ? latestBlock.id.slice(0, 18) : '0x0', @@ -492,23 +492,25 @@ const delegatedTransaction = new Transaction({ }); // Private keys of sender -const pkSender = +const senderPrivateKey = 'ea5383ac1f9e625220039a4afac6a7f868bf1ad4f48ce3a1dd78bd214ee4ace5'; /** Private key of delegate * @NOTE The delegate account must have enough VET and VTHO to pay for the gas */ -const pkDelegate = +const delegatePrivateKey = '432f38bcf338c374523e83fdb2ebe1030aba63c7f1e81f7d76c5f53f4d42e766'; -// Normal signature and delegation signature +// 5 - Normal signature and delegation signature + const rawDelegatedSigned = TransactionHandler.signWithDelegator( delegatedTransaction, - Buffer.from(pkSender, 'hex'), - Buffer.from(pkDelegate, 'hex') + Buffer.from(senderPrivateKey, 'hex'), + Buffer.from(delegatePrivateKey, 'hex') ).encoded; -// Send transaction +// 6 - Send transaction + const send = await thorestSoloClient.transactions.sendTransaction( `0x${rawDelegatedSigned.toString('hex')}` ); @@ -516,10 +518,14 @@ expect(send).toBeDefined(); expect(send).toHaveProperty('id'); expect(dataUtils.isHexString(send.id)).toBe(true); -// Get transaction details and receipt +// 7 - Get transaction details and receipt + +// Details of transaction const transactionDetails = await thorestSoloClient.transactions.getTransaction( send.id ); + +// Receipt of transaction const transactionReceipt = await thorestSoloClient.transactions.getTransactionReceipt(send.id); diff --git a/docs/transactions.md b/docs/transactions.md index e90081eb2..a3e8f10ef 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -28,10 +28,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a simple single clause transaction is -// created, signed, encoded and then decoded +// 1 - Define clauses -// Define clauses const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -40,10 +38,12 @@ const clauses: TransactionClause[] = [ } ]; -// Calculate intrinsic gas of clauses +// 2 - Calculate intrinsic gas of clauses + const gas = TransactionUtils.intrinsicGas(clauses); -// Body of transaction +// 3 - Body of transaction + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -58,14 +58,17 @@ const body: TransactionBody = { // Create private key const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.chainTag).toBe(body.chainTag); expect(decodedTx.body.nonce).toBe(body.nonce); @@ -89,10 +92,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a multiple clause transaction is -// created, signed, encoded and then decoded +// 1 - Define multiple clauses -// Define multiple clauses const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -108,10 +109,12 @@ const clauses: TransactionClause[] = [ } ]; -// Calculate intrinsic gas of both clauses +// 2 - Calculate intrinsic gas of both clauses + const gas = TransactionUtils.intrinsicGas(clauses); -// Body of transaction +// 3 - Body of transaction + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -126,14 +129,17 @@ const body: TransactionBody = { // Create private key const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.clauses.length).toBe(clauses.length); @@ -157,10 +163,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a fee delegated transaction is -// created, signed (by both parties), encoded and then decoded +// 1 - Define clause -// Define clause const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -169,7 +173,8 @@ const clauses: TransactionClause[] = [ } ]; -// Body of transaction +// 2 - Define transaction body + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -184,27 +189,35 @@ const body: TransactionBody = { } }; -// Create private keys of sender and delegate -const pkSender = secp256k1.generatePrivateKey(); +// 3 - Create private keys of sender and delegate + +const senderPrivateKey = secp256k1.generatePrivateKey(); const nodeDelegate = HDNode.fromMnemonic(mnemonic.generate()); -const pkDelegate = nodeDelegate.privateKey; -// Get address of delegate -const addrDelegate = nodeDelegate.address; -// Sign transaction as sender and delegate +const delegatorPrivateKey = nodeDelegate.privateKey; + +// 4 - Get address of delegate + +const delegatorAddress = nodeDelegate.address; + +// 5 - Sign transaction as sender and delegate + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.signWithDelegator( unsignedTx, - pkSender, - pkDelegate + senderPrivateKey, + delegatorPrivateKey ); -// Encode transaction +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check + +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.isDelegated).toBeTruthy(); -expect(decodedTx.delegator).toBe(addrDelegate); +expect(decodedTx.delegator).toBe(delegatorAddress); ``` @@ -224,10 +237,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example a transaction is created that -// has its expiry set to a specified block height +// 1 - Define clauses -// Define clause const clauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -236,7 +247,8 @@ const clauses: TransactionClause[] = [ } ]; -// Body of transaction +// 2 - Define transaction body + const body: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x00ffecb8ac3142c4', // first 8 bytes of block id from block #16772280 @@ -248,14 +260,21 @@ const body: TransactionBody = { nonce: 1 }; -// Create private key +// 3 - Create private key + const privateKey = secp256k1.generatePrivateKey(); -// Sign transaction + +// 4 - Sign transaction + const unsignedTx = new Transaction(body); const signedTransaction = TransactionHandler.sign(unsignedTx, privateKey); -// Encode transaction + +// 5 - Encode transaction + const encodedRaw = signedTransaction.encoded; -// Decode transaction and check + +// 6 - Decode transaction and check + const decodedTx = TransactionHandler.decode(encodedRaw, true); expect(decodedTx.body.blockRef).toBe(body.blockRef); expect(decodedTx.body.expiration).toBe(body.expiration); @@ -278,10 +297,8 @@ import { } from '@vechainfoundation/vechain-sdk-core'; import { expect } from 'expect'; -// In this example transaction A is created with no dependencies -// Transaction B is the created as being dependant on transaction A +// 1 - Define transaction clauses -// Define transaction clauses const txAClauses: TransactionClause[] = [ { to: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', @@ -297,8 +314,9 @@ const txBClauses: TransactionClause[] = [ } ]; -// Define transaction A with no dependencies -// Note: This transaction has nonce = 1 +// 2 - Define transaction A with no dependencies + +// @NOTE: This transaction has nonce = 1 const txABody: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -310,8 +328,9 @@ const txABody: TransactionBody = { nonce: 1 }; -// Define transaction B with nonce = 2 -// Note at the moment dependsOn is null +// 3 - Define transaction B with nonce = 2 + +// @NOTE: at the moment dependsOn is null const txBBody: TransactionBody = { chainTag: networkInfo.mainnet.chainTag, blockRef: '0x0000000000000000', @@ -324,28 +343,33 @@ const txBBody: TransactionBody = { }; // Define the senders private key -const pkSender = secp256k1.generatePrivateKey(); +const senderPrivateKey = secp256k1.generatePrivateKey(); // To define transaction B as dependant on transaction A // We need to sign transaction A, and then get its Id // and set that Id into transaction B's dependsOn field -// get tx A id +// 4 - Get Tx A id + const txAUnsigned = new Transaction(txABody); -const txASigned = TransactionHandler.sign(txAUnsigned, pkSender); -const txAId = txASigned.id; -// set it inside tx B -txBBody.dependsOn = txAId; +const txASigned = TransactionHandler.sign(txAUnsigned, senderPrivateKey); + +// 5 - Set it inside tx B + +txBBody.dependsOn = txASigned.id; + +// 6 - Sign Tx B -// sign Tx B const txBUnsigned = new Transaction(txBBody); -const txBSigned = TransactionHandler.sign(txBUnsigned, pkSender); -// encode Tx B +const txBSigned = TransactionHandler.sign(txBUnsigned, senderPrivateKey); + +// 7 - encode Tx B + const rawTxB = txBSigned.encoded; -// To check we can decode Tx B +// Check (we can decode Tx B) const decodedTx = TransactionHandler.decode(rawTxB, true); -expect(decodedTx.body.dependsOn).toBe(txAId); +expect(decodedTx.body.dependsOn).toBe(txASigned.id); ```