Fuse Blockchain Developer Quick Start Guide
Welcome to the Fuse Blockchain Developer Quick Start Guide! This guide is designed to help developers like you get up and running quickly with building on the Fuse Blockchain. Whether you're a seasoned blockchain developer or just getting started, this guide will provide you with the essential information and resources you need to start building on the Fuse network.
Network Details
Fuse Mainnet | Fuse Testnet (Sparknet) | |
---|---|---|
Chain ID | 122 | 123 |
RPC | https://rpc.fuse.io/ | https://rpc.fusespark.io |
Symbol | FUSE | FUSE |
Health | https://health.fuse.io/ | https://health.fusespark.io |
Explorer | https://explorer.fuse.io/ | https://explorer.fusespark.io/ |
WebSocket | wss://explorer-node.fuse.io/ws | wss://explorernode.fusespark.io/ws |
Faucet | Stakely | ChainDrop faucet, Stakely faucet |
Block size | 20,000,000 | 20,000,000 |
Block speed | 5 seconds | 5 seconds |
Gas price | 10 GWei | 10 GWei |
Fuse Network Core Contracts
Name | Contract |
---|---|
Core Consensus | 0x3014ca10b91cb3D0AD85fEf7A3Cb95BCAc9c0f79 |
BlockReward | 0x63D4efeD2e3dA070247bea3073BCaB896dFF6C9B |
Voting | 0x4c889f137232E827c00710752E86840805A70484 |
Oracles
In the table below are the Supra Smart Contracts deployed on Fuse.
Contract Name | Contract Address | Version |
---|---|---|
Supra Router Contract | 0x1daB558F090029580854FbCF8f83ef3Ad8C223b5 | V2 |
Supra Deposit Contract | 0x7a168e3AE8B701648D4f8F89B5fCD278885eBeFA | V2 |
Fuse SubGraphs
Name | Description |
---|---|
fuse-nft | All NFTs on the Fuse Network |
fuse-blocks | Blocks details of the network |
voltage-dex | Voltage DEX subgraph for on-chain trading information |
fuse-ethereum-amb | Subgraph for Fuse - Ethereum AMB bridge |
etherem-fuse-amb | Subgraph for Ethereum - Fuse AMB bridge |
Create and Deploy Smart Contracts
Fuse Blockchain is EVM-compatible. Smart Contracts written in Solidity are deployed on the Fuse Chain. Developers can deploy Smart Contracts in development to the Testnet and Smart Contracts going to Production on the Mainnet. Developers have the option to write their Smart Contracts using a variety of build tools:
After writing a Smart Contract to deploy to the Fuse Blockchain, developers must add the Fuse Network to MetaMask. You can add Fuse Network to MetaMask using the following guide.
We are going to write an example Smart Contract and follow the required steps to deploy it to the Fuse Blockchain using Hardhat.
Open a new terminal and run these commands to create a new folder:
mkdir hardhat-fuse-guide && cd hardhat-fuse-guide
Inside the folder, initialize a project by running:
npm init -y
In the same directory where you installed Hardhat run:
npx hardhat init
Open the Project in a VSCode editor. Open the Contract folder, delete the default Lock.sol file and add a new file Token.sol. Update the contents of HelloWorld.sol with the following code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts@4.0.0/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts@4.0.0/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts@4.0.0/access/Ownable.sol";
contract MyToken is ERC20, ERC20Burnable, Ownable {
constructor(address initialOwner)
ERC20("MyToken", "MTK")
Ownable()
{}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
To compile your contracts run:
npx hardhat compile
It will return the response:
Compiling...
Compiled 1 contract successfully
The next step is to deploy the contracts to the Fuse Blockchain. In Hardhat, deployments are defined through Ignition Modules. These modules are abstractions to describe a deployment; that is, JavaScript functions that specify what you want to deploy.
Open ignition inside the project root's directory, then, enter the directory named modules. Create a deploy.js and paste the following code:
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
const Token = buildModule("Token", (m) => {
const contract = m.contract("Token");
return { contract };
});
module.exports = Token;
To deploy the Smart Contract, open the hardhat.config.js file and update the information on Fuse Network
hardhat.config.js
module.exports = {
// ...
networks: {
fuse: {
url: "https://rpc.fuse.io/",
accounts: [`0xPRIVATE_KEY`], // put dev menomonic or PK here,
},
spark: {
url: "https://rpc.fusespark.io/",
accounts: [`0xPRIVATE_KEY`], // put dev menomonic or PK here,
},
},
// ...
};
Please note: The 0xPRIVATE_KEY
is used to sign the Transaction from your EOA without needing permission. You must ensure the EOA that owns the Private Key is funded with some Fuse Tokens to pay for Gas when deploying the Smart Contract.
Open a new terminal and deploy the smart contract to the Fuse network:
npx hardhat ignition deploy ./ignition/modules/deploy.js --network fuse
The Smart Contract is deployed to the Fuse Mainnet and Testnet. To view the deployed Contract address and the Transaction calls, open the Fuse Mainnet or Testnet Explorer and paste the deployed address.
The Deployed Smart Contract can be verified and interacted with from a User Interface leveraging several tools. The official recommended tool from Fuse is FuseBox.
Connect Smart Contract using FuseBox
FuseBox is an Open-Source Wallet-as-a-Service platform based on Account Abstraction. It is ERC-4337 compliant and allows developers to use a Bundler to collect UserOperations and a Paymaster to sponsor Gas payments for their users, enabling a Gasless experience.
FuseBox is available as a TypeScript SDK and a Flutter SDK. It is a middleware infrastructure that connects directly to the fuse blockchain without needing an RPC node provider. It also makes it easy for Web2 developers to start building blockchain applications without the need to understand ABIs.
To understand FuseBox, we will build a quick guide to building a UI for the deployed Token Smart Contract using the FuseBox Web SDK.
The Smart Contract has several deployed methods for interacting with it. This quickstart guide will focus on transfer
and balanceOf
. The respective SDK methods required are:
Step 1: Set Up Your Next.js App
Create a new Next.js app:
npx create-next-app my-fuse-demo-app
cd my-fuse-demo-app
Answer the required prompts from NextJS in the terminal. We must note that we use TypeScript and Tailwind CSS for this application.
Step 2: Install Dependencies
Install the required dependencies:
npm install @fuseio/fusebox-web-sdk
npm install ethers
Step 3: Run the Development Server
Run npm run dev
to start the development server. Visit http://localhost:3000
to view your application.
Step 4: Import Libraries
Open the index.tsx
file, delete the default code from NextJS. Edit index.tsx
file by adding the code below and save it to see the updated result in your browser. First, import the required libraries and put up a default Hello, World! text:
import { FuseSDK } from "@fuseio/fusebox-web-sdk";
import { ethers } from "ethers";
export default function Home() {
return (
<main className={`flex flex-col items-center p-24 ${inter.className}`}>
Hello, World!
</main>
);
}
Step 5: Create a Smart Contract Wallet.
To use the SDK in your project, you must create an instance of the FuseSDK class. This class is the key to interacting with the Fuse API using the SDK.
The init
method sets up a wallet and authenticates the user's provided credentials. It requires a API_KEY from FuseBox. Create an Account and get the API_KEY
in the Fuse Developer Console here. When you send a request to the server using this method, it verifies the credentials. If the credentials are valid, developers can use the getSender()
to return an address.
To create the Smart Contract Wallet, we will update the code by adding a smartWallet
function, and parsing the returned Smart Contract Address to a state variable.
Inside the Home Component, import the useState method:
import { useState, useEffect } from 'react'
Set the state variable to manage the state of the Smart Contract Account that will be created:
const [smartAccount, setSmartAccount] = useState<string>("")
Add the smartWallet function:
const smartWallet = async() => {
const apiKey = "API_KEY";
const credentials = new ethers.Wallet(`0xPrivateKey`);
const fuseSDK = await FuseSDK.init(apiKey, credentials, {
withPaymaster: true,
});
setSmartAccount(fuseSDK.wallet.getSender());
console.log(
`Smart account address: https://explorer.fuse.io/address/${fuseSDK.wallet.getSender()}`
);
}
To call the function and render the response in the application UI, we have to use the useEffect
hook to prevent too many re-renders:
import { useState, useEffect } from ’react’;
Add the useEffect Hook:
useEffect(()=> {
smartWallet()
}, [])
Reload the app and open the console. The newly created Smart Contract Address will be logged into the Console!
To return the Smart Contract Address to the UI, you can parse the stored state variable:
return (
<main className={`flex flex-col items-center p-24 ${inter.className}`}>
Hello, World!
{smartAccount}
</main>
);
Step 6: Token Transfers
Transfer Transactions which happen on the Blockchain are state-changing. In Account Abstraction these “Transactions” are called “UserOperations” because they are first sent to an alternate Mempool where they are then Bundled and sent on-chain. FuseBox uses the transferToken method to carry out a UserOperation of transferring a Token from one Address to another.
Add another Function transferToken:
const transferToken = async() => {
const tokenAddress = "0x28C3d1cD466Ba22f6cae51b1a4692a831696391A"
const apiKey = "API_KEY";
const credentials = new ethers.Wallet(`0xPrivateKey`);
const fuseSDK = await FuseSDK.init(apiKey, credentials, {
withPaymaster: true,
});
const recipient = "Enter ANY EOA or SCW address";
const amount = ethers.parseUnits(amountValue, 6)
const res = await fuseSDK.transferToken(tokenAddress, recipient, amount);
console.log(`UserOpHash: ${res?.userOpHash}`);
console.log("Waiting for transaction...");
const receipt = await res?.wait();
console.log(
`User operation hash: https://explorer.fuse.io/tx/${receipt?.transactionHash}`
);
}
The transferToken
method takes in three arguments: tokenAddress
, recipient
, amount
.
Note: SCW is a Smart Contract Wallet Address.
The tokenAddress is the address of the Token which we are sending a specific amount to a receiving address recipient. You can find a list of Token Addresses here: https://explorer.fuse.io/tokens
It is important to mention that when sending a Token, you will parse the token in units to the number of the decimal places which the Token is defined. For example, USDC has 6 decimal places. To send 1 USDC, you parse it thus:
ethers.parseUnits(“1”, 6)
Where the string “1” is the amount, and 6 the number of decimal places.
Step 7: Form UI. To carryout Token Transfer, the next step is to build a Form component where we can enter the recipient and amount values we want to transfer to.
Update the UI:
<form className="flex max-w-md flex-col gap-4">
<div className="mt-3">
<label htmlFor="base-input" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" />
<input type="text" id="base-input" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
<label htmlFor="base-input" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" />
<input type="text" id="base-input" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
</div>
<button type="text" className=" focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800">Send</button>
</form>
The Form above has two labels and a button. To use the form, we have to take the input data and pass it as arguments to the transferToken method.
Let’s write the state variables to store the recipient and amount values. In this example, we will keep the tokenAddress static as USDC.
const [toValue, setToValue] = useState<string>(' ');
const [amountValue, setAmountValue] = useState<string>(' ');
Add a handle method to take the input data
const handleTo = (e) => {
setToValue(e.target.value);
};
const handleAmount = (e) => {
setAmountValue(e.target.value)
};
The values are set in the state: recipient == toValue
, amount == amountValue
Update the Form UI to handle the data and submit it:
<form onSubmit={handleSubmit} className="flex max-w-md flex-col gap-4">
<div className="mt-3">
<label htmlFor="base-input" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" />
<input type="text" id="base-input" **value={toValue} onChange={handleTo}** className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
<label htmlFor="base-input" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" />
<input type="text" id="base-input" **value={amountValue} onChange={handleAmount}** className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" />
</div>
<button type="submit" className=" focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800">Send</button>
</form>
Add a handleSubmit method:
const handleSubmit = (e) => {
e.preventDefault();
console.log("Input value:", toValue, amountValue);
transferToken();
};
Update the transferToken function to read the values stored in the state:
const res = await fuseSDK.transferToken(tokenAddress, toValue, amountValue);
You can carry out Token Transfers via the UI. Note that you have to get some USDC Token, or you can put the number ‘0’ in the amount field to see the success of the UserOperation. You can open the console to see the UserOperation logged.
This is a quickstart guide on how to deploy Smart Contracts to Fuse Testnet and Mainnet, and also how to use FuseBox to connect to the deployed Smart Contract