If you are already using a different version of the Node (for example, Node v12), use the Node Version Manager(NVM) to install and use the version supported by caver-js.
Installation
To try it out, install caver-js with npm using the following command:
$ npm install caver-js
Note: package.json file should exist on the same install path. If it does not exist, package.json should be generated via npm init.
To install a specific version of caver-js, try the following command:
$ npm install caver-js@X.X.X
Starting with caver-js
Once you have finished installing caver-js, you can now connect caver-js with a Klaytn Node.
You can import the caver-js module and connect it to a Klaytn Node in the Baobab testnet as shown in the example below:
Note: Functions associated with caver.klay.accounts have no effect on the actual Klaytn network.
Add Accounts to caver-js
You can use your account easily by using the in-memory wallet provided by caver-js. The following examples illustrate how to add an account to a wallet using an account object and a keystore file generated by Klaytn Wallet.
The account added to the caver-js wallet can be used for sendTransaction.
Sending a Transaction
This section will show you how to send a KLAY using caver-js on the Baobab network.
Getting KLAY via Baobab Faucet
If you need KLAY for testing, you can get Baobab testnet KLAY from the Klaytn Wallet. Log in to the Klaytn Wallet using the private key or the keystore file and receive Baobab testnet KLAY via the faucet for testing.
Sending a Value Transfer Transaction
You can use a caver-js wallet to generate a signature of a transaction. If you have an account in the caver-js wallet, the signature generation will be done with the private key inside the caver-js wallet when you execute caver.klay.sendTransaction. Note that caver.klay.sendTransaction performs both signature generation and submission of the transaction at once.
// If you have not added an account to caver-js's wallet, add it to your wallet by running 'caver.klay.accounts.wallet.add'.
// If the same account is already in the wallet, 'Error: Account exists with {hex in address}' is returned. In this case, you can use the address string in the `from` field to reference the account in the wallet.
> const account = caver.klay.accounts.wallet.add('0x{private key}')
> caver.klay.sendTransaction({
type: 'VALUE_TRANSFER',
from: account.address',
to: '0xeF5cd886C7f8d85fbe8023291761341aCBb4DA01',
gas: '300000',
value: 1,
}).then(console.log)
{
blockHash: '0x5e9f427c9550a6f7575bcf60aba9257634884519a6273a23e8eefee2a696cce4',
blockNumber: 3841096,
contractAddress: null,
from: '0x3bd32d55e64d6cbe54bec4f5200e678ee8d1a990',
...
status: true,
to: '0xef5cd886c7f8d85fbe8023291761341acbb4da01',
transactionHash: '0xb09f6d26734074a259f6cbe4d509d2bf40f6f0a4559081354527ae211dd9d00f',
transactionIndex: 1,
type: 'TxTypeValueTransfer',
typeInt: 8,
value: '0x1'
}
If you want to generate a signature directly from the private key without a caver-js wallet, the following steps are required:
caver.klay.accounts.signTransaction - The process of signing a transaction with a private key and getting a RLP-encoded transaction.
caver.klay.sendSignedTransaction - sends the RLP-encoded transaction to the node connected to caver-js.
First, to sign the transaction, specify the sender, recipient, and the private key appropriately like shown below:
Note: The sender should have enough amount of KLAY.
You can get a RLP-encoded transaction (rawTransaction) using caver.klay.accounts.signTransaction as above and use this to transfer the transaction to the Klaytn network as below.
As shown in the example above, you can send a request and use the event emitter to get the hash of the submitted transaction by calling .on('transactionHash', console.log).
As described in the example above, you can get the result of sending a transaction through the promise and event emitter. And also, if you know the transaction hash, you can query the transaction receipt using the caver.klay.getTransactionReceipt RPC call. The example below shows how to get a receipt using the caver.klay.getTransactionReceipt RPC call.
The result of the transaction can be found through the status of the receipt. For a detailed description of the return values, see getTransactionReceipt. If a transaction is failed, you can check the detailed error in txError of the receipt. For more information about txError, see txError: Detailed Information of Transaction Failures.
Executing Other Transaction Types
Klaytn provides various transaction types for extensibility and performance. For more information, see Transactions. This section describes various examples that can be used with caver-js.
Fee Delegation
Klaytn provides Fee Delegation feature. Here's an example code.
When you are a sender, use the code below to make an RLP-encoded transaction object:
With the signed RLP-encoded transaction object (rawTransaction), the fee payer can send the transaction after attaching the one's signature. The fee payer sets the rawTransaction to senderRawTransaction and signs with the address of the fee payer, as in the example below.
// If you have not added a fee payer account to caver-js's wallet, add it to your wallet by running 'caver.klay.accounts.wallet.add'.
// If an account is already added to the wallet, 'Error: Account is existed with {hex in address}' is returned. In this case, please use the account's address instead of `feePayer.address`.
> const feePayer = caver.klay.accounts.wallet.add('0x{private key}')
> caver.klay.sendTransaction({
senderRawTransaction: rawTransaction,
feePayer: feePayer.address,
}).then(console.log)
{
blockHash: '0xf0c4ef717a674ffaea8bf68597c936ce8a3773dab1e1f6f42508963f124bc301',
blockNumber: 3840725,
...
transactionHash: '0x8d1fea7710bc351540257a4ae7f2274d66ddd7f62bcdb6f1f77893cecb659405',
transactionIndex: 2,
type: 'TxTypeFeeDelegatedValueTransfer',
typeInt: 9,
value: '0xde0b6b3a7640000'
}
NOTE: The fee payer's account must be in the caver-js wallet.
Account Update
If you want to change the key of the account, send a transaction as shown below. Please check Account Update for the transaction field according to the key type.
// If you have not added an account to caver-js's wallet, add it to your wallet by running 'caver.klay.accounts.wallet.add'.
// If the same account is already in the wallet, 'Error: Account exists with {hex in address}' is returned. In this case, you can use the address string in the `from` field to reference the account in the wallet.
> const account = caver.klay.accounts.wallet.add('0x{private key}')
> caver.klay.sendTransaction({
type: 'ACCOUNT_UPDATE',
from: account.address,
publicKey: '0x9016de15ebb219b1e8bc732070df93a28903e5799d0cd24a807a5afabf4601f7e5ab312b5a682dd8c0e72e71e67552174d5082cde25db3626a5b025f97f8a005',
gas: '300000',
}).then(console.log);
Smart Contract
The caver.klay.Contract package makes it easy to interact with smart contracts on Klaytn. It automatically converts all methods of a smart contract into javascript calls when its low-level ABI (Application Binary Interface) is given. This allows you to interact with smart contracts as if they were JavaScript objects.
First, we start by compiling a smart contract to get its bytecode and ABI.
If the contract instance is created, you can deploy it by passing the bytecode to the data field as shown below:
// If you have not added an account to caver-js's wallet, add it to your wallet by running 'caver.klay.accounts.wallet.add'.
// If the same account is already in the wallet, 'Error: Account exists with {hex in address}' is returned. In this case, you can use the address string in the `from` field to reference the account in the wallet.
> const account = caver.klay.accounts.wallet.add('0x{private key}')
> contractInstance.deploy({
data: '60806040526000805534801561001457600080fd5b50610123806100246000396000f3fe6080604052600436106053576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14605857806342cbb15c146080578063d14e62b81460a8575b600080fd5b348015606357600080fd5b50606a60df565b6040518082815260200191505060405180910390f35b348015608b57600080fd5b50609260e5565b6040518082815260200191505060405180910390f35b34801560b357600080fd5b5060dd6004803603602081101560c857600080fd5b810190808035906020019092919050505060ed565b005b60005481565b600043905090565b806000819055505056fea165627a7a72305820e381897039d8e48bf74b4a096bb1c4ed02f331bd1a7a4add6217b72fa888f2f10029',
}).send({
from: account.address,
gas: '0x4bfd200',
value: '0x0',
}).then(console.log)
{
blockHash: '0x71426773ed65f307bdfac5070ac54f11f406086bbe8dfa170215ed4190f176ed',
blockNumber: 226,
codeFormat: '0x0',
contractAddress: '0xC9f0b868e5103b6823171a2Df85E7B696660E466',
from: '0x71959675eeb7c7ec1e0c74f206a9c488d7f178d4',
gas: '0x4bfd200',
gasPrice: '0x5d21dba00',
gasUsed: 149017,
humanReadable: false,
input: '0x60806040526000805534801561001457600080fd5b50610123806100246000396000f3fe6080604052600436106053576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14605857806342cbb15c146080578063d14e62b81460a8575b600080fd5b348015606357600080fd5b50606a60df565b6040518082815260200191505060405180910390f35b348015608b57600080fd5b50609260e5565b6040518082815260200191505060405180910390f35b34801560b357600080fd5b5060dd6004803603602081101560c857600080fd5b810190808035906020019092919050505060ed565b005b60005481565b600043905090565b806000819055505056fea165627a7a72305820e381897039d8e48bf74b4a096bb1c4ed02f331bd1a7a4add6217b72fa888f2f10029',
...
type: 'TxTypeSmartContractDeploy',
typeInt: 40,
value: '0x0',
events: {}
}
The deployed contract address can be found in contractAddress of the transaction receipt. Before sending a smart contract execution transaction, set the address to the address of the contract instance as follows:
One way to invoke a specific method of a smart contract is to use it with caver.klay.Contract or use SMART_CONTRACT_EXECUTION.
To transact with a smart contract:
// If you have not added an account to caver-js's wallet, add it to your wallet by running 'caver.klay.accounts.wallet.add'.
// If the same account is already in the wallet, 'Error: Account exists with {hex in address}' is returned. In this case, you can use the address string in the `from` field to reference the account in the wallet.
> const account = caver.klay.accounts.wallet.add('0x{private key}')
> contractInstance.methods.setCount(1).send({from:account.address, gas:'0x4bfd200'}).then(console.log)
{
blockHash: '0x159f8515102951bca9c403b2b1b37850ca01a08dffb9a763837f55a6d518bbb6',
blockNumber: 644,
contractAddress: null,
from: '0x71959675eeb7c7ec1e0c74f206a9c488d7f178d4',
gas: '0x4bfd200',
gasPrice: '0x5d21dba00',
gasUsed: 44875,
input: '0xd14e62b80000000000000000000000000000000000000000000000000000000000000001',
...
type: 'TxTypeSmartContractExecution',
typeInt: 48,
value: '0x0',
events: {}
}
The caver.klay.accounts package uses AccountKeyPublic, which stores and manages a private key string by default.
The following example creates an account with AccountKeyPublic as accountKey.
// test.js fileasyncfunctiontestFunction() {// Create random account with accountKeyPublic by defaultconstaccount=caver.klay.accounts.create()printAccount(account)// Create account with specific private key stringconstprivateKey=caver.klay.accounts.create().privateKeyconstaccountFromKey=caver.klay.accounts.privateKeyToAccount(privateKey)printAccount(accountFromKey)}functionprintAccount(account) {console.log(`address: ${account.address}`)console.log(`privateKey: ${account.privateKey}`)console.log(`accountKeyType: ${account.accountKeyType}`)console.log(`accountKey`)console.log(account.accountKey)console.log(`account.keys: ${account.keys}`)console.log(`account.transactionKey: ${account.transactionKey}`)console.log(`account.updateKey: ${account.updateKey}`)console.log(`account.feePayerKey: ${account.feePayerKey}\n`)}
The printAccount above shows how to use the properties of the Account instance. The properties inside Account are as follows.
Property Name
Description
address
The address of the account.
privateKey
Default key string of accountKey that the account has. This property is left for backward compatibility. privateKey only represents the default key of accountKey, so using privateKey to sign or send a transaction is not recommended. It is recommended to use transactionKey, updateKey, or feePayerKey in context.
accountKeyType
Type of accountKey the account has. This can be AccountKeyPublic, AccountKeyMultiSig, or AccountKeyRoleBased
accountKey
The key of the account. This is AccountKeyPublic, AccountKeyMultiSig or AccountKeyRoleBased.
keys
All keys inside accountKey that the account has.
transactionKey
Key used for the RoleTransaction. AccountKeyPublic or AccountKeyMultiSig are not bound to any roles, so transactionKey holds the same value as keys.
updateKey
Key used for the RoleAccountUpdate. AccountKeyPublic or AccountKeyMultiSig are not bound to any roles, so updateKey holds the same value as keys.
feePayerKey
Key used for RoleFeePayer. AccountKeyPublic or AccountKeyMultiSig are not bound to any roles, so feePayerKey holds the same value as keys.
NOTEtransactionKey, updateKey, and feePayerKey return a private key string or an array of private key strings that should be used for the role. So rather than using privateKey property, it is recommended that you use transactionKey, updateKey and feePayerKey as appropriate, without worrying about the accountKey type.
An explanation of the various AccountKey classes is provided in the AccountKey part.
AccountKey
AccountKey is a data structure that stores the keys of an account. An account can have one private key string or multiple private key strings to be used for signing. Account can also manage the private keys by roles.
To support this structure, caver-js introduces new classes called AccountKeyPublic, AccountKeyMultiSig, and AccountKeyRoleBased.
To create an AccountKey, use caver.klay.accounts.createAccountKey. This function determines which AccountKey to generate based on the type of the parameter. It creates AccountKeyPublic if a private key string comes as a parameter, or AccountKeyMultiSig if an array of private key strings comes. And if there is an object with a different key for each role, it creates AccountKeyRoleBased.
NOTE The classes for AccountKey defined in caver-js are data structures for storing private keys for use in caver-js. It can be different from the key in your account on Klaytn network.
AccountKeyPublic
AccountKeyPublic is a class for storing and managing a single private key string.
The following describes how to update an account with AccountKeyPublic. Write the following code into testFunction() and run it.
AccountKeyPublic stores and manages a private key string, so if you run the example above, you will see that keys, transactionKey, updateKey and feePayerKey all represent the same private key string.
See below for an example of creating an Account with AccountKeyPublic as its accountKey.
constprivateKey=caver.klay.accounts.create().privateKeyconstaccountKey=caver.klay.accounts.createAccountKey(privateKey)constaddress=caver.klay.accounts.create().address// Create an Account instance with a private key stringconstaccountFromStringKey=caver.klay.accounts.createWithAccountKey(address, privateKey)// Create an Account instance with an AccountKeyPublic instanceconstaccountFromAccountKey=caver.klay.accounts.createWithAccountKey(address, accountKey)
AccountKeyMultiSig
AccountKeyMultiSig is a class for storing and managing multiple private key strings.
The following describes how to update an account with AccountKeyMultiSig. Write the following code into testFunction() and run it.
AccountKeyMultiSig stores and manages multiple private key strings, so if you run the example above, you will see that keys, transactionKey, updateKey and feePayerKey all represent the same multiple private key strings.
If you do not specify a private key (or an array of private key strings) to use when signing a transaction, caver-js will find an account from the in-memory wallet that matches the from or fee payer and sign with it. In this case, if your account has multiple private keys, caver-js will sign the transaction with all of those keys.
See below for an example of creating an Account with AccountKeyMultiSig as its accountKey.
constprivateKeyArray= [caver.klay.accounts.create().privateKey,caver.klay.accounts.create().privateKey]constaccountKey=caver.klay.accounts.createAccountKey(privateKeyArray)constaddress=caver.klay.accounts.create().address// Create Account instance with an array of private key stringsconstaccountFromStringKey=caver.klay.accounts.createWithAccountKey(address, privateKeyArray)// Create Account instance with AccountKeyMultiSig instanceconstaccountFromAccountKey=caver.klay.accounts.createWithAccountKey(address, accountKey)
AccountKeyRoleBased
AccountKeyRoleBased is a class for storing and managing keys for each role. Each role can have one private key string or multiple private key strings.
The following describes how to update an account with AccountKeyRoleBased. Write the following code into testFunction() and run it.
AccountKeyRoleBased stores and manages keys by role, so if you run the example above, you will see three roles (transactionKey, updateKey, feePayerKey) defined in keys property. Therefore, unlike other AccountKey (AccountKeyPublic or AccountKeyMultiSig), transactionKey, updateKey and feePayerKey each represents a different key.
See below for an example of creating an Account with AccountKeyRoleBased as its accountKey.
constkeyobject= { transactionKey: [caver.klay.accounts.create().privateKey, caver.klay.accounts.create().privateKey, caver.klay.accounts.create().privateKey],
updateKey:caver.klay.accounts.create().privateKey, feePayerKey: [caver.klay.accounts.create().privateKey, caver.klay.accounts.create().privateKey, caver.klay.accounts.create().privateKey]
}constaccountKey=caver.klay.accounts.createAccountKey(keyobject)constaddress=caver.klay.accounts.create().address// Create Account instance with an object that defines key by roleconstaccountFromStringKey=caver.klay.accounts.createWithAccountKey(address, keyobject)// Create Account instance with AccountKeyRoleBased instanceconstaccountFromAccountKey=caver.klay.accounts.createWithAccountKey(address, accountKey)
Through the above examples you will see how to use Account and various AccountKey types in caver-js.
Note that these examples do not affect the Klaytn network. If you want to use your account with a specific account key type, such as AccountKeyPublic, AccountKeyMultiSig, or AccountKeyRoleBased, you must send an account update transaction to the Klaytn network.
The following AccountForUpdate explains how to update an account by sending a transaction to the Klaytn network.
AccountForUpdate
AccountForUpdate is a class designed to make it easier to use transactions for account updates.
The AccountForUpdate contains only the public key to be used for account update and the address of the account to update.
The examples below start with updating your account with accountKey. There must be enough KLAY in the account to be used for testing. Test KLAY for the Baobab network is available through Baobab Faucet.
Create an AccountForUpdate
Let's start by creating an AccountForUpdate.
You can create it by calling createAccountForUpdate() with the target account address and the new key you want to use.
NOTE If you want to update with multiple private key strings, you must define thresholds and weights in the options object.
Account update with AccountForUpdate
You can easily create an account update transaction using AccountForUpdate created above.
There are three types of transactions used to update an account: ACCOUNT_UPDATE, FEE_DELEGATED_ACCOUNT_UPDATE and FEE_DELEGATED_ACCOUNT_UPDATE_WITH_RATIO.
In the example below, account is an account that has enough KLAY balance, and accountForUpdate is an AccountForUpdate instance that contains the new key and the target account address. accountForUpdate is created usingcaver.klay.accounts.createAccountForUpdate`.
The example below demonstrates how to create a transaction using AccountForUpdate and send it to the Klaytn network.
constupdateTx= { type:'ACCOUNT_UPDATE', from:account.address, key: accountForUpdate, gas:300000,}// Sign transaction with updateKey of accountconstsigned=awaitcaver.klay.accounts.signTransaction(updateTx,account.updateKey)// Send account update transactionconstreceipt=awaitcaver.klay.sendSignedTransaction(signed)console.log(receipt)// Get accountKey from Klaytn networkconstupdatedKey=awaitcaver.klay.getAccountKey(account.address)console.log(updatedKey)
If you want to use FEE_DELEGATED_ACCOUNT_UPDATE transaction, see the example below.
constupdateTx= { type:'FEE_DELEGATED_ACCOUNT_UPDATE', from:account.address, key: accountForUpdate, gas:300000,}// Sender signs transaction with updateKey of accountconstsenderSigned=awaitcaver.klay.accounts.signTransaction(updateTx,account.updateKey)// Fee payer signs transaction with feePayerKey of fee payerconst feePayerSigned = await caver.klay.accounts.feePayerSignTransaction(senderSigned.rawTransaction, feePayer.address, feePayer.feePayerKey)
// Send fee delegated account update transactionconstreceipt=awaitcaver.klay.sendSignedTransaction(feePayerSigned)console.log(receipt)// Get accountKey from Klaytn networkconstupdatedKey=awaitcaver.klay.getAccountKey(account.address)console.log(updatedKey)
NOTEcaver.klay.accounts.feePayerSignTransaction is supported since caver-js v1.2.0.
If you want to use FEE_DELEGATED_ACCOUNT_UPDATE_WITH_RATIO transaction, define updateTx in the above example as:
If your account has been updated successfully, the old key can no longer be used. Update the accountKey of the account stored in caver-js as follows.
When updating the accountKey property of an account directly, the assigning value must be an instance of AccountKeyPublic, AccountKeyMultiSig, or AccountKeyRoleBased.
The rawTransaction has an RLP encoded transaction that contains both signatures and feePayerSignatures. feePayerSignature is included only when the transaction is a fee delegated transaction.
The following example shows how to sign a transaction sequentially with multiple private keys. Assume the account's transactionKey has two private key strings.
consttx= { type:'VALUE_TRANSFER', from:account.address, to:caver.klay.accounts.create().address, value:1, gas:900000,}// Sign with transactionKey[0]constuser1Signed=awaitcaver.klay.accounts.signTransaction(tx,account.transactionKey[0])// Append sender's signatures with transactionKey[1]constuser2Signed=awaitcaver.klay.accounts.signTransaction(user1Signed.rawTransaction,account.transactionKey[1])constreceipt=awaitcaver.klay.sendSignedTransaction(user2Signed)console.log(receipt)
See the example below for signing with a fee payer's key whose type is an AccountKeyRoleBased. The fee payer is assumed to have three private key strings in feePayerKey.
consttx= { type:'FEE_DELEGATED_VALUE_TRANSFER', from:account.address, to:caver.klay.accounts.create().address, value:1, gas:900000,}// Sign with transactionKey[0] and transactionKey[1]const userSigned = await caver.klay.accounts.signTransaction(tx, [account.transactionKey[0], account.transactionKey[1]])
// Fee payer signs transaction with feePayerKey[0]const feePayer1Signed = await caver.klay.accounts.feePayerSignTransaction(userSigned.rawTransaction, feePayer.address, feePayer.feePayerKey[0])
// Append feePayerSignatures with feePayerKey[1] and feePayerKey[2]const feePayer2Signed = await caver.klay.accounts.feePayerSignTransaction(feePayer1Signed.rawTransaction, feePayer.address, [feePayer.feePayerKey[1], feePayer.feePayerKey[2]])
constreceipt=awaitcaver.klay.sendSignedTransaction(feePayer2Signed)console.log(receipt)
NOTEcaver.klay.accounts.feePayerSignTransaction is supported since caver-js v1.2.0.
If the account you use exists in the caver-js in-memory wallet, you do not need to pass the key(s) to signTransaction or feePayerSignTransaction. See the example below.
consttx= { type:'FEE_DELEGATED_VALUE_TRANSFER_WITH_RATIO', from:account.address, to:caver.klay.accounts.create().address, value:1, gas:900000, feeRatio:10,}// Sign with transactionKey[0] and transactionKey[1]constuserSigned=awaitcaver.klay.accounts.signTransaction(tx)// Fee payer signs transaction with feePayerKey[0], feePayerKey[1] and feePayerKey[2]constfeePayerSigned=awaitcaver.klay.accounts.feePayerSignTransaction(userSigned.rawTransaction,feePayer.address)constreceipt=awaitcaver.klay.sendSignedTransaction(feePayerSigned)console.log(receipt)
Combine signatures from RawTransaction
If you receive the result object of the caver.klay.accounts.signTransaction or caver.klay.accounts.feePayerSignTransaction from several people, you can create a single RLP encoded transaction that contains all the signature information.
The example below shows how to combine and send the RLP encoded transactions.
NOTEcaver.klay.accounts.combineSignatures is supported since caver-js v1.2.0.
Send transaction object with Signatures and FeePayerSignatures
If you only receive signatures or feePayerSignatures from multiple signers, you can send a transaction as follows:
consttx= { type:'FEE_DELEGATED_VALUE_TRANSFER_WITH_RATIO', from:account.address, to:caver.klay.accounts.create().address, value:1, gas:900000, feeRatio:10,}// Sign with transactionKey[0] and transactionKey[1]const { signatures } =awaitcaver.klay.accounts.signTransaction(tx)// Fee payer signs transaction with feePayerKey[0], feePayerKey[1] and feePayerKey[2]const { feePayerSignatures } =awaitcaver.klay.accounts.feePayerSignTransaction(tx,feePayer.address)// Fill in the missing information in the tx object.tx.signatures = signaturestx.feePayer =feePayer.addresstx.feePayerSignatures = feePayerSignaturesconstreceipt=awaitcaver.klay.sendSignedTransaction(tx)console.log(receipt)
You can also call caver.klay.accounts.getRawTransactionWithSignatures to get an RLP encoded transaction containing the signatures and feePayerSignatures of the transaction object.
consttx= { type:'FEE_DELEGATED_VALUE_TRANSFER_WITH_RATIO', from:account.address, to:caver.klay.accounts.create().address, value:1, gas:900000, feeRatio:10,}// Sign with transactionKey[0] and transactionKey[1]const { signatures } =awaitcaver.klay.accounts.signTransaction(tx)// Fee payer signs transaction with feePayerKey[0], feePayerKey[1] and feePayerKey[2]const { feePayerSignatures } =awaitcaver.klay.accounts.feePayerSignTransaction(tx,feePayer.address)// Fill in the missing information in the tx object.tx.signatures = signaturestx.feePayer =feePayer.addresstx.feePayerSignatures = feePayerSignaturesconst { rawTransaction } =awaitcaver.klay.accounts.getRawTransactionWithSignatures(tx)console.log(rawTransaction)
NOTEcaver.klay.accounts.getRawTransactionWithSignatures is supported since caver-js v1.2.0.
Sample Projects
The BApp (Blockchain Application) Development sample projects using caver-js are the following: