Fuji Workflow

Introduction

Fuji is the Avalanche network's test network. You can use it to test your dapp or smart contract after you've developed it locally. (You can use Avash to test things locally.) Fuji is typically on the same version as the Avalanche Mainnet, but sometimes it is running an unreleased version of AvalancheGo. In general, you can expect Fuji's behavior to be about the same as Avalanche Mainnet. Tools such as a explorers and wallets should work with the Fuji Testnet.
In this tutorial, we’ll go through an example Fuji workflow to show how it can be used. We'll do the following:
    1.
    Generate a 24 word english mnemonic via AvalancheJS
    2.
    Derive external BIP44 X-Chain addresses via AvalancheJS
    3.
    Get AVAX from the Fuji faucet
    4.
    Send AVAX via AvalancheJS
    5.
    Examine the resulting transaction on the Avalanche Explorer
    6.
    Use the mnemonic to sign into the web wallet

Generate a Mnemonic

To begin, we'll create a mnemonic phrase with AvalancheJS. Mnemonics enable us to encode strong security into a human-readable phrase. AvalancheJS supports 10 languages including English, Japanese, Spanish, Italian, French, Korean, Czech, Portugese, Chinese Simplified and Chinese Traditional.
First, generate a 24 word english BIP39-compliant mnemonic via AvalancheJS.
1
import { Mnemonic } from "avalanche"
2
const mnemonic: Mnemonic = Mnemonic.getInstance()
3
const strength: number = 256
4
const wordlist = mnemonic.getWordlists("english") as string[]
5
const m: string = mnemonic.generateMnemonic(strength, randomBytes, wordlist)
6
console.log(m)
7
// "pool hat domain flame stomach canal fury master farm gown tide supreme winner motion this first divide spray forum wall reopen bounce spider palm"
Copied!

Derive Addresses

After generating a mnemonic we can use AvalancheJS to derive BIP32-compliant hierarchical deterministic (HD) keypairs.
1
import HDNode from "avalanche/utils/hdnode"
2
const seed: Buffer = mnemonic.mnemonicToSeedSync(m)
3
const hdnode: HDNode = new HDNode(seed)
4
5
for (let i: number = 0; i <= 2; i++) {
6
// Deriving the _i_th external BIP44 X-Chain address
7
const child: HDNode = hdnode.derive(`m/44'/9000'/0'/0/${i}`)
8
keychain.importKey(child.privateKeyCB58)
9
}
10
11
const xAddressStrings: string[] = xchain.keyChain().getAddressStrings()
12
console.log(xAddressStrings)
13
// [
14
// 'X-fuji1cfvdpdqyzpp8pq0g6trmjsrn9pt8nutsfm7a40',
15
// 'X-fuji1y75dj6qygj7frw2xtcfn724qfty4aadnmeth6y',
16
// 'X-fuji1p6n0vyjqgmp06f7pr405q2flqu9v93j383ncam'
17
// ]
Copied!
Note that we're using keychain which hasn't been defined yet. Creating an empty keychain can be seen in this example AvalancheJS script. There are links to dozens of AvalancheJS examples in the resources listed below.
As long as you have the menmonic phrase, you can re-generate your private keys and the addresses they control.

Get a Drip from the Fuji Faucet

We can get a "drip" of AVAX from the Fuji faucet. Paste the address into the Fuji faucet website. These AVAX are for the Fuji Testnet and have no monetary value.
Requesting AVAX
The faucet will send some AVAX to the address and return a transaction ID (txID). This txID can be used with the Fuji Testnet Explorer to learn more about the transaction.
Receiving AVAX

Check the Transaction Details

The txID, 2GjAMJrBUYs8RuK2bXrNCuu34fNpJVor2ubNzvcUDPo5t9nMct, can be seen on the Fuji Testnet Explorer. Avalanche also has a Mainnet Explorer.

Get the Balance

We can also use the Fuji Explorer to get the balance for the 1st BIP44-derived address—X-fuji1cfvdpdqyzpp8pq0g6trmjsrn9pt8nutsfm7a40.
Alternatively, we can use AvalancheJS to get the balance.
1
const address: string = "X-fuji1cfvdpdqyzpp8pq0g6trmjsrn9pt8nutsfm7a40"
2
const balance: any = await xchain.getBalance(address, "AVAX")
3
console.log(balance)
4
// {
5
// balance: '2000000000',
6
// utxoIDs: [
7
// {
8
// txID: '2GjAMJrBUYs8RuK2bXrNCuu34fNpJVor2ubNzvcUDPo5t9nMct',
9
// outputIndex: 0
10
// }
11
// ]
12
// }
Copied!

Sending AVAX

The faucet sent 2 AVAX to the first address we generated. Let's send AVAX from the 1st address to the 2nd address.
1
// get the AVAX asset ID
2
const avaxAssetID: string = Defaults.network[networkID].X['avaxAssetID']
3
4
// get the AVAX balance for the 1st address
5
const getBalanceResponse: any = await xchain.getBalance(xAddressStrings[0], avaxAssetID)
6
const balance: BN = new BN(getBalanceResponse.balance)
7
8
// subtract the fee
9
const fee: BN = xchain.getDefaultTxFee()
10
const amount: BN = balance.sub(fee)
11
12
// get the UTXOs for the 1st address
13
const avmUTXOResponse: any = await xchain.getUTXOs(xAddressStrings[0])
14
const utxoSet: UTXOSet = avmUTXOResponse.utxos
15
16
// build an UnsignedTx sending AVAX from the first external BIP44 address to the second external BIP44 address
17
const unsignedTx: UnsignedTx = await xchain.buildBaseTx(
18
utxoSet,
19
amount,
20
avaxAssetID,
21
[xAddressStrings[1]],
22
[xAddressStrings[0]],
23
[xAddressStrings[1]]
24
)
25
26
// sign it
27
const tx: Tx = unsignedTx.sign(xKeychain)
28
29
// issue it and get a txid
30
const txid: string = await xchain.issueTx(tx)
31
console.log(`Success! TXID: ${txid}`)
32
// Success! TXID: ankMr1tD65A9SSto5w4ic1d31t6w42jeu8pfv6v4gRPpMg17g
Copied!

Verify Success

We can verify that the transaction, ankMr1tD65A9SSto5w4ic1d31t6w42jeu8pfv6v4gRPpMg17g, was successful using AvalancheJS.
1
const txid: string = "ankMr1tD65A9SSto5w4ic1d31t6w42jeu8pfv6v4gRPpMg17g"
2
const status: string = await xchain.getTxStatus(txid)
3
console.log(status)
4
// Accepted
Copied!
Alternatively we can use the Fuji Tesntet Explorer. The transaction can be seen on the Fuji Explorer.

Get the Balance

We can also use the Fuji Explorer to get the balance for the 2nd address—X-fuji1y75dj6qygj7frw2xtcfn724qfty4aadnmeth6y.
Alternatively, we can use AvalancheJS to get the balance.
1
const address: string = "X-fuji1y75dj6qygj7frw2xtcfn724qfty4aadnmeth6y"
2
const balance: any = await xchain.getBalance(address, "AVAX")
3
console.log(balance)
4
// {
5
// balance: '1999000000',
6
// utxoIDs: [
7
// {
8
// txID: 'ankMr1tD65A9SSto5w4ic1d31t6w42jeu8pfv6v4gRPpMg17g',
9
// outputIndex: 0
10
// }
11
// ]
12
// }
Copied!

Sign into the Web Wallet

Lastly, we can use the mnemonic to access the Avalanche Web Wallet. We'll see that it has the AVAX balance and that it auto-magically derives the 3rd address from the mnemonic.
Use the mnemonic to access the Web Wallet.
Acess the wallet
The balance is correct and the "active" address is the 3rd derived address.
Also note that the wallet GUI shows that it derived the same 3 addresses as our script above.

Summary

The Fuji Testnet plays a critical role in testing and QAing dapps, smart contracts and financial products before deploying to the Mainnet. Tooling like AvalancheJS, the public API, faucet, and explorer helps to ensure that your testing and QA environment is close to Mainnet so that you can be confident when you launch on Mainnet.

Resources

For additional and valuable resources please see below.

Faucet

The Fuji Faucet sends AVAX to X-Chain or C-Chain addresses to help you test. (This testnet Avax has no value.)

Wallet

The Avalanche Web Wallet is a simple, secure, non-custodial wallet for storing Avalanche assets. It supports Mainnet, Fuji and custom networks.

Explorer

The Avalanche Explorer allows you to explore the network on Mainnet and Fuji.

Public API

See here.

AvalancheJS Examples

There are over 60 example AvalancheJS scripts which demonstrate how to assets and NFTs, send transactions, add validators and more.
Last modified 3mo ago