JavaScript API libraries

Sam Richards
Last edit: @samajammin, September 24, 2020
See contributors
Edit page

In order for a web app to interact with the Ethereum blockchain (i.e. read blockchain data and/or send transactions to the network), it must connect to an Ethereum node.

For this purpose, every Ethereum client implements the JSON-RPC specification, so there are a uniform set of endpoints that applications can rely on.

If you want to use JavaScript to connect with an Ethereum node, it's possible to use vanilla JavaScript but several convenience libraries exist within the ecosystem that make this much easier. With these libraries, developers can write intuitive, one-line methods to initialize JSON RPC requests (under the hood) that interact with Ethereum.

Prerequisites

As well as understanding JavaScript, it might be helpful to understand the Ethereum stack and Ethereum clients.

Why use a library?

These libraries abstract away much of the complexity of interacting directly with an Ethereum node. They also provide utility functions (e.g. converting ETH to Gwei) so as a developer you can spend less time dealing with the intricacies of Ethereum clients and more time focused on the unique functionality of your application.

Library features

Connect to Ethereum nodes

Using providers, these libraries allow you to connect to Ethereum and read its data, whether that's over JSON-RPC, INFURA, Etherscan, Alchemy or MetaMask.

Ethers example

1// A Web3Provider wraps a standard Web3 provider, which is
2// what Metamask injects as window.ethereum into each page
3const provider = new ethers.providers.Web3Provider(window.ethereum)
4
5// The Metamask plugin also allows signing transactions to
6// send ether and pay to change state within the blockchain.
7// For this, we need the account signer...
8const signer = provider.getSigner()
9
📋 Copy

Web3js example

1var web3 = new Web3("http://localhost:8545")
2// or
3var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
4
5// change provider
6web3.setProvider("ws://localhost:8546")
7// or
8web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546"))
9
10// Using the IPC provider in node.js
11var net = require("net")
12var web3 = new Web3("/Users/myuser/Library/Ethereum/geth.ipc", net) // mac os path
13// or
14var web3 = new Web3(
15 new Web3.providers.IpcProvider("/Users/myuser/Library/Ethereum/geth.ipc", net)
16) // mac os path
17// on windows the path is: "\\\\.\\pipe\\geth.ipc"
18// on linux the path is: "/users/myuser/.ethereum/geth.ipc"
19
📋 Copy

Once set up you'll be able to query the blockchain for:

  • block numbers
  • gas estimates
  • smart contract events
  • network id
  • and more...

Wallet functionality

These libraries give you functionality to create wallets, manage keys and sign transactions.

Here's an examples from Ethers

1// Create a wallet instance from a mnemonic...
2mnemonic =
3 "announce room limb pattern dry unit scale effort smooth jazz weasel alcohol"
4walletMnemonic = Wallet.fromMnemonic(mnemonic)
5
6// ...or from a private key
7walletPrivateKey = new Wallet(walletMnemonic.privateKey)
8
9walletMnemonic.address === walletPrivateKey.address
10// true
11
12// The address as a Promise per the Signer API
13walletMnemonic.getAddress()
14// { Promise: '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1' }
15
16// A Wallet address is also available synchronously
17walletMnemonic.address
18// '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1'
19
20// The internal cryptographic components
21walletMnemonic.privateKey
22// '0x1da6847600b0ee25e9ad9a52abbd786dd2502fa4005dd5af9310b7cc7a3b25db'
23walletMnemonic.publicKey
24// '0x04b9e72dfd423bcf95b3801ac93f4392be5ff22143f9980eb78b3a860c4843bfd04829ae61cdba4b3b1978ac5fc64f5cc2f4350e35a108a9c9a92a81200a60cd64'
25
26// The wallet mnemonic
27walletMnemonic.mnemonic
28// {
29// locale: 'en',
30// path: 'm/44\'/60\'/0\'/0/0',
31// phrase: 'announce room limb pattern dry unit scale effort smooth jazz weasel alcohol'
32// }
33
34// Note: A wallet created with a private key does not
35// have a mnemonic (the derivation prevents it)
36walletPrivateKey.mnemonic
37// null
38
39// Signing a message
40walletMnemonic.signMessage("Hello World")
41// { Promise: '0x14280e5885a19f60e536de50097e96e3738c7acae4e9e62d67272d794b8127d31c03d9cd59781d4ee31fb4e1b893bd9b020ec67dfa65cfb51e2bdadbb1de26d91c' }
42
43tx = {
44 to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
45 value: utils.parseEther("1.0"),
46}
47
48// Signing a transaction
49walletMnemonic.signTransaction(tx)
50// { Promise: '0xf865808080948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a7640000801ca0918e294306d177ab7bd664f5e141436563854ebe0a3e523b9690b4922bbb52b8a01181612cec9c431c4257a79b8c9f0c980a2c49bb5a0e6ac52949163eeb565dfc' }
51
52// The connect method returns a new instance of the
53// Wallet connected to a provider
54wallet = walletMnemonic.connect(provider)
55
56// Querying the network
57wallet.getBalance()
58// { Promise: { BigNumber: "42" } }
59wallet.getTransactionCount()
60// { Promise: 0 }
61
62// Sending ether
63wallet.sendTransaction(tx)
64
📋 Copy

Read the full docs

Once set up you'll be able to:

  • create accounts
  • send transactions
  • sign transactions
  • and more...

Interact with smart contract functions

Javascript client libraries allow your application to call smart contract functions by reading the Application Binary Interface (ABI) of a compiled contract.

The ABI essentially explains the contract's functions in a JSON format and allows you to use it like a normal JavaScipt object.

So the following Solidity contract:

1contract Test {
2 uint a;
3 address d = 0x12345678901234567890123456789012;
4
5 function Test(uint testInt) { a = testInt;}
6
7 event Event(uint indexed b, bytes32 c);
8
9 event Event2(uint indexed b, bytes32 c);
10
11 function foo(uint b, bytes32 c) returns(address) {
12 Event(b, c);
13 return d;
14 }
15}
16
📋 Copy

Would result in the following JSON:

1[{
2 "type":"constructor",
3 "payable":false,
4 "stateMutability":"nonpayable"
5 "inputs":[{"name":"testInt","type":"uint256"}],
6 },{
7 "type":"function",
8 "name":"foo",
9 "constant":false,
10 "payable":false,
11 "stateMutability":"nonpayable",
12 "inputs":[{"name":"b","type":"uint256"}, {"name":"c","type":"bytes32"}],
13 "outputs":[{"name":"","type":"address"}]
14 },{
15 "type":"event",
16 "name":"Event",
17 "inputs":[{"indexed":true,"name":"b","type":"uint256"}, {"indexed":false,"name":"c","type":"bytes32"}],
18 "anonymous":false
19 },{
20 "type":"event",
21 "name":"Event2",
22 "inputs":[{"indexed":true,"name":"b","type":"uint256"},{"indexed":false,"name":"c","type":"bytes32"}],
23 "anonymous":false
24}]
25
📋 Copy

This means you can:

  • Send a transaction to the smart contract and execute its method
  • Call to estimate the gas a method execution will take when executed in the EVM
  • Deploy a contract
  • And more...

Utility functions

Utility functions give you handy shortcuts that make building with Ethereum a little easier.

ETH values are in Wei by default. 1 ETH = 1,000,000,000,000,000,000 WEI – this means you're dealing with a lot of numbers! web3.utils.toWei converts Ether to Wei for you.

And in ethers it looks like this:

1// Get the balance of an account (by address or ENS name)
2balance = await provider.getBalance("ethers.eth")
3// { BigNumber: "2337132817842795605" }
4
5// Often you will need to format the output for the user
6// which prefer to see values in ether (instead of wei)
7ethers.utils.formatEther(balance)
8// '2.337132817842795605'
9
📋 Copy

Available libraries

Web3.js - Ethereum JavaScript API.

Ethers.js - Complete Ethereum wallet implementation and utilities in JavaScript and TypeScript.

The Graph - A protocol for indexing Ethereum and IPFS data and querying it using GraphQL.

light.js - A high-level reactive JS library optimized for light clients.

Web3-wrapper - Typescript alternative to Web3.js.

Further reading

Know of a community resource that helped you? Edit this page and add it!