Web3 JavaScript API
#
What is Renec-Web3.js?The Renec-Web3.js library aims to provide complete coverage of Renec. The library was built on top of the Renec JSON RPC API.
You can find the full documentation for the @solana/web3.js
library here.
#
Common TerminologyTerm | Definition |
---|---|
Program | Stateless executable code written to interpret instructions. Programs are capable of performing actions based on the instructions provided. |
Instruction | The smallest unit of a program that a client can include in a transaction. Within its processing code, an instruction may contain one or more cross-program invocations. |
Transaction | One or more instructions signed by the client using one or more Keypairs and executed atomically with only two possible outcomes: success or failure. |
For the full list of terms, see Renec terminology
#
Getting Started#
Installation#
yarn#
npm#
Bundle#
Usage#
Javascript#
ES6#
Browser Bundle#
Quickstart#
Connecting to a WalletTo allow users to use your dApp or application on Renec, they will need to get access to their Keypair. A Keypair is a private key with a matching public key, used to sign transactions.
There are two ways to obtain a Keypair:
- Generate a new Keypair
- Obtain a Keypair using the secret key
You can obtain a new Keypair with the following:
This will generate a brand new Keypair for a user to fund and use within your application.
You can allow entry of the secretKey using a textbox, and obtain the Keypair with Keypair.fromSecretKey(secretKey)
.
Many wallets today allow users to bring their Keypair using a variety of extensions or web wallets. The general recommendation is to use wallets, not Keypairs, to sign transactions. The wallet creates a layer of separation between the dApp and the Keypair, ensuring that the dApp never has access to the secret key. You can find ways to connect to external wallets with the wallet-adapter library.
#
Creating and Sending TransactionsTo interact with programs on Renec, you create, sign, and send transactions to the network. Transactions are collections of instructions with signatures. The order that instructions exist in a transaction determines the order they are executed.
A transaction in Renec-Web3.js is created using the Transaction
object and adding desired messages, addresses, or instructions.
Take the example of a transfer transaction:
The above code achieves creating a transaction ready to be signed and broadcasted to the network. The SystemProgram.transfer
instruction was added to the transaction, containing the amount of lamports to send, and the to
and from
public keys.
All that is left is to sign the transaction with keypair and send it over the network. You can accomplish sending a transaction by using sendAndConfirmTransaction
if you wish to alert the user or do something after a transaction is finished, or use sendTransaction
if you don't need to wait for the transaction to be confirmed.
The above code takes in a TransactionInstruction
using SystemProgram
, creates a Transaction
, and sends it over the network. You use Connection
in order to define with Renec network you are connecting to, namely mainnet-beta
, testnet
, or devnet
.
#
Interacting with Custom ProgramsThe previous section visits sending basic transactions. In Renec everything you do interacts with different programs, including the previous section's transfer transaction. At the time of writing programs on Renec are either written in Rust or C.
Let's look at the SystemProgram
. The method signature for allocating space in your account on Renec in Rust looks like this:
In Renec when you want to interact with a program you must first know all the accounts you will be interacting with.
You must always provide every account that the program will be interacting within the instruction. Not only that, but you must provide whether or not the account is isSigner
or isWritable
.
In the allocate
method above, a single account pubkey
is required, as well as an amount of space
for allocation. We know that the allocate
method writes to the account by allocating space within it, making the pubkey
required to be isWritable
. isSigner
is required when you are designating the account that is running the instruction. In this case, the signer is the account calling to allocate space within itself.
Let's look at how to call this instruction using solana-web3.js:
First, we set up the account Keypair and connection so that we have an account to make allocate on the testnet. We also create a payer Keypair and airdrop some renec so we can pay for the allocate transaction.
We create the transaction allocateTransaction
, keys, and params objects. feePayer
is an optional field when creating a transaction that specifies who is paying for the transaction, defaulting to the pubkey of the first signer in the transaction. keys
represents all accounts that the program's allocate
function will interact with. Since the allocate
function also required space, we created params
to be used later when invoking the allocate
function.
The above is created using using u32 and ns64 from @solana/buffer-layout
to facilitate the payload creation. The allocate
function takes in the parameter space
. To interact with the function we must provide the data as a Buffer format. The buffer-layout
library helps with allocating the buffer and encoding it correctly for Rust programs on Renec to interpret.
Let's break down this struct.
index
is set to 8 because the function allocate
is in the 8th position in the instruction enum for SystemProgram
.
Next up is u32('instruction')
.
The layout
in the allocate struct must always have u32('instruction')
first when you are using it to call an instruction.
ns64('space')
is the argument for the allocate
function. You can see in the original allocate
function in Rust that space was of the type u64
. u64
is an unsigned 64bit integer. Javascript by default only provides up to 53bit integers. ns64
comes from @solana/buffer-layout
to help with type conversions between Rust and Javascript. You can find more type conversions between Rust and Javascript at solana-labs/buffer-layout.
Using the previously created bufferLayout, we can allocate a data buffer. We then assign our params { space: 100 }
so that it maps correctly to the layout, and encode it to the data buffer. Now the data is ready to be sent to the program.
Finally, we add the transaction instruction with all the account keys, payer, data, and programId and broadcast the transaction to the network.
The full code can be found below.