Ethereum Development

Overview

Popular blockchain choices for building Web3 capabilities are based typically on the Ethereum Virtual Machine (EVM), and therefore share the development tech stack.

Some examples of EVM blockchains:

  • Ethereum
  • BNB Chain (BSC)
  • Polygon
  • Avalanche
  • Arbitrum

Convenience libraries

Most commonly, developers interact with EVM-based blockchains using "convenience libraries" such as web3.js and ethers.js.

To streamline your JavaScript development experience, we created the Fireblocks Web3 Provider, to easily connect ethers.js and web3.js to your Fireblocks workspace.

web3.js integration

The Fireblocks Web3 Provider helps seamlessly integrate Fireblocks into your web3.js development stack. Use it to deploy contracts, sign messages, and send transactions.

Installation

npm install @fireblocks/fireblocks-web3-provider web3

Setup

import { FireblocksWeb3Provider, ChainId, ApiBaseUrl } from "@fireblocks/fireblocks-web3-provider";

const eip1193Provider = new FireblocksWeb3Provider({
    apiBaseUrl: ApiBaseUrl.Sandbox, // If using a sandbox workspace
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI,
})

If you are not using a Sandbox environment, but rather a regular one, just comment the apiBaseUrl line.

Usage

import Web3 from "web3";

const web3 = new Web3(eip1193Provider);

Now you can use the web3 object exactly as you normally would!

Example

In this example we are executing the 'approve' method of USDC (ERC20) token on Goerli by using web3.js and Fireblocks web3 provider.

const { FireblocksWeb3Provider, ChainId, ApiBaseUrl } = require("@fireblocks/fireblocks-web3-provider")
const Web3 = require("web3");

// Import the Goerli USDC ABI
const ABI = require("./USDC_GOERLI_ABI.json");

// Goerli USDC Contract Address
const CONTRACT_ADDRESS = "0x07865c6E87B9F70255377e024ace6630C1Eaa37F"

const eip1193Provider = new FireblocksWeb3Provider({
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI,
 // apiBaseUrl: ApiBaseUrl.Sandbox // If using a sandbox workspace
});


(async() => {
  
  	const web3 = new Web3(eip1193Provider);
  	const myAddr = await web3.eth.getAccounts()
  	const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS);
  	const spenderAddr = "<spender_address>"

    // 1 USDC to approve 
    const amount = 1e6

    // Invoke approve method
    console.log(
        await contract.methods.approve(spenderAddr, amount).send({
            from: myAddr[0]
        })
    )

})().catch(error => {
    console.log(error)
});

ethers.js integration

The Fireblocks Web3 Provider helps seamlessly integrate Fireblocks into your ethers.js development stack.

You can use it to deploy contracts, sign messages, and send transactions.

Installation

npm install @fireblocks/fireblocks-web3-provider ethers@5

Setup

import { FireblocksWeb3Provider, ChainId, ApiBaseUrl } from "@fireblocks/fireblocks-web3-provider";

const eip1193Provider = new FireblocksWeb3Provider({
    apiBaseUrl: ApiBaseUrl.Sandbox, // If using a sandbox workspace
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI,
})

If you are not using a Sandbox environment, but rather a regular one, just comment the apiBaseUrl line.

Usage

import * as ethers from "ethers"

const provider = new ethers.providers.Web3Provider(eip1193Provider);

Now you can use the provider object exactly as you normally would!

Example

In this example we are executing the 'approve' method of USDC (ERC20) token on Goerli by using ethers.js and Fireblocks web3 provider.

const { FireblocksWeb3Provider, ChainId, ApiBaseUrl } = require("@fireblocks/fireblocks-web3-provider")
const ethers = require("ethers")

// Import the Goerli USDC ABI
const ABI = require("./USDC_GOERLI_ABI.json");

// Goerli USDC Contract Address
const CONTRACT_ADDRESS = "0x07865c6E87B9F70255377e024ace6630C1Eaa37F"

const eip1193Provider = new FireblocksWeb3Provider({
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI,
 // apiBaseUrl: ApiBaseUrl.Sandbox // If using a sandbox workspace
});


(async() => {

    const provider = new ethers.providers.Web3Provider(eip1193Provider);
    const myContract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider.getSigner());
    const spenderAddr = "<spender_address>"

    // 1 USDC to approve 
    const amount = 1e6

    // Invoke approve method
    const tx = await myContract.approve(
        spenderAddr,
        amount
    )
   
    console.log(JSON.stringify(tx, null, 2))

})().catch(error => {
    console.log(error)
});

Viem integration

The Fireblocks Web3 Provider helps seamlessly integrate Fireblocks into your viem development stack.

You can use it to deploy contracts, sign messages, and send transactions.

Installation

npm install @fireblocks/fireblocks-web3-provider viem

Setup

import { FireblocksWeb3Provider, ChainId, ApiBaseUrl } from "@fireblocks/fireblocks-web3-provider";

const eip1193Provider = new FireblocksWeb3Provider({
    apiBaseUrl: ApiBaseUrl.Sandbox, // If using a sandbox workspace
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI,
})

If you are not using a Sandbox environment, but rather a regular one, just comment the apiBaseUrl line.

Usage

const { createWalletClient, custom } = require("viem")
const { goerli } = require("viem/chains")

const walletClient = createWalletClient({
    chain: goerli,
    transport: custom(eip1193Provider),
});

Now you can use the walletClient object exactly as you normally would!

Example

In this example we are executing the 'approve' method of USDC (ERC20) token on Goerli by using viem and Fireblocks web3 provider.

const { goerli } = require("viem/chains")
const {
  ChainId,
  FireblocksWeb3Provider,
  ApiBaseUrl
} = require("@fireblocks/fireblocks-web3-provider")

const { 
  createWalletClient, 
  custom, 
  createPublicClient, 
  http 
} = require("viem")


// Import the Goerli USDC ABI
const ABI = require("./USDC_GOERLI_ABI.json");

// Goerli USDC Contract Address
const CONTRACT_ADDRESS = '0x07865c6E87B9F70255377e024ace6630C1Eaa37F'

(async () => {

  const spenderAddr = "<spender_addr>";
  
  // 1 USDC to approve
  const amount = 1e6;
  
  const eip1193Provider = new FireblocksWeb3Provider({
   // apiBaseUrl: ApiBaseUrl.Sandbox, // If using a sandbox workspace
    privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
    apiKey: process.env.FIREBLOCKS_API_KEY,
    vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
    chainId: ChainId.GOERLI
  });
  
  // Create wallet client instance
  const walletClient = createWalletClient({
    chain: goerli,
    transport: custom(eip1193Provider),
  });
  
  // Create public client instance
  const publicClient = createPublicClient({
    chain: goerli,
    transport: http()
  })
  
  // Get my account's address
  const [ account ] = await walletClient.getAddresses();
  
  // Simulate the 'approve' call
  const { request } = await publicClient.simulateContract({
    address: CONTRACT_ADDRESS,
    abi: ABI,
    functionName: 'approve',
    args: [spenderAddr, amount],
    account
  })

  // Execute approve call via Fireblocks
  await walletClient.writeContract(request)
})();

web3.py integration

Fireblocks JSON-RPC helps seamlessly integrate Fireblocks into your web3.py development stack.

You can use it to deploy contracts, sign messages, and send transactions.

Installation

npm install -g @fireblocks/fireblocks-json-rpc
pip install web3

Setup

Set the environment variables.

Create example.py:

import json
import os
from datetime import datetime
from web3 import Web3

web3 = Web3(Web3.IPCProvider(os.environ['FIREBLOCKS_JSON_RPC_ADDRESS'], 60000*180))
web3.eth.defaultAccount = web3.eth.accounts[0]
CONTRACT_ADDRESS = Web3.toChecksumAddress("0x8A470A36a1BDE8B18949599a061892f6B2c4fFAb")
GREETER_ABI = json.loads('[{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"greet","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_greeting","type":"string"}],"name":"setGreeting","outputs":[],"stateMutability":"nonpayable","type":"function"}]')
GREETING = "Hello web3! By " + web3.eth.defaultAccount + " at " + str(datetime.now())

if __name__ == '__main__':
    print('last block number: ', web3.eth.blockNumber)
    for account in web3.eth.accounts:
        print('account: ', account)
        print('account balance: ', web3.fromWei(web3.eth.getBalance(account), "ether"), ' ETH\n')

    print('Greeter contract: https://goerli.etherscan.io/address/' + CONTRACT_ADDRESS)
   
  	contract = web3.eth.contract(address=CONTRACT_ADDRESS, abi=GREETER_ABI)

    print('Current greeting:', contract.functions.greet().call())
    
    print('Setting greeting to:', GREETING)
    tx_hash = contract.functions.setGreeting(GREETING).transact({'from':web3.eth.defaultAccount})
    print('Transaction signed and broadcasted: https://goerli.etherscan.io/tx/' + tx_hash.hex())
    print('Waiting for transaction to be mined...')
    web3.eth.wait_for_transaction_receipt(tx_hash)

    print('Current greeting:', contract.functions.greet().call())



Usage

fireblocks-json-rpc -- python example.py

You can now use the web3 object exactly as you normally would!

ethers-rs integration

A community developed project implemented an ethers-fireblocks integration for the popular etheres-rs convenience library. More details and an example of usage is in the Rust Guide.