Quick Start

Start using the FunWallet SDK with a Token Transfer example

1

Install Packages

View our install guide for more.

npm install @fun-wallet/sdk ethers
2

Select Environment

The FunWallet SDK currently supports 3 environments:

  • Mainnets

  • Testnets

  • Forks

In this quick start guide we will be showing how to use a FunWallet + Token Transfer Module on the Fuji testnet.

3

Fund Your EOA

Each deployed FunWallet instance has the capability to initiate transactions. In order to initiate transactions, each FunWallet instance needs to meet 1 of 2 requirements to cover its gas needs:

  • Have enough gas token (e.g ETH, MATIC, AVAX, etc) within the FunWallet to cover the desired transaction's gas

  • Have a gas sponsor (e.g USDC Paymaster) with sufficient gas token staked

In this quick start guide, we will be choosing option 1. To fund our FunWallet with the required gas token, we must transfer these tokens from an existing & funded EOA on the same chain as our FunWallet. To obtain gas tokens for the Fuji testnet, visit this link.

A correct construction, initialization & deployment of a FunWallet, as detailed in this quick start guide, will automatically pre-fund your FunWallet with the required gas amount from the connected EOA.

4

Import Required Libraries

import { ethers } from "ethers"
import { FunWallet, FunWalletConfig, Modules } from "@fun-wallet/sdk"
const { TokenTransfer } = Modules
5

Create an ethers.Wallet EOA Instance

This EOA will be used to fund the FunWallet, make sure it is on the same chain as the desired FunWallet instance. There are 2 ways of creating an ether.Wallet EOA instance:

  • With a known private key PRIV_KEY (only for testing):

const rpc = "https://avalanche-fuji.infura.io/v3/4a1a0a67f6874be6bb6947a62792dab7"
const provider = new ethers.providers.JsonRpcProvider(rpc)
// Note that the key here will be exposed and should never be used in production
const eoa = new ethers.Wallet(PRIV_KEY, provider)
  • With an external EOA wallet provide (e.g. MetaMask)

const rpc = "https://avalanche-fuji.infura.io/v3/4a1a0a67f6874be6bb6947a62792dab7"
const provider = new ethers.providers.JsonRpcProvider(rpc)
// To create an EOA instance with an external EOA wallet (e.g MetaMask)
const provider = new ethers.providers.Web3Provider(window.ethereum)
await provider.send('eth_requestAccounts', []) // <- this promps user to connect external wallet
eoa = provider.getSigner()
6

Create & Initialize a FunWallet

A FunWallet is constructed with parameters from a FunWalletConfig object. We are required to call the init on a FunWallet after its construction to ensure that internal variables requiring external async data server calls are updated.

const chainID = "43113" // Fuji testnet
const prefundAmt = 0.3 // amount of native gas token to prefund our FunWallet with
const API_KEY = "" // Get your API key from app.fun.xyz/api-key
const config = new FunWalletConfig(eoa, chainID, prefundAmt)
const wallet = new FunWallet(config, API_KEY)
// init will perform the pre-funding of the FunWallet
await wallet.init()
7

Create & Add TokenTransfer Module to a FunWallet

A FunWallet can make on-chain actions depending on the Modules that have been added to it. For this quick start guide, we add the TokenTransfer Module to our FunWallet to enable the transferring of ERC-20 tokens to external addresses. To get the Transaction which performs the actual token transfer, see step 9.

const tokenTransferModule = new TokenTransfer()
await wallet.addModule(tokenTransferModule)
8

Deploy a FunWallet to a Blockchain

Next, we deploy the FunWallet we created to the Blockchain specified by the chainID parameter in our FunWalletConfig.

const deployWalletReceipt = await wallet.deploy()
9

Generate Token Transfer Transaction & Deploy to a Blockchain

Lastly, we generate a Transaction that transfers 0.01 AVAX (because we have selected the Fuji testnet with chainID 43113) out of the FunWallet.

const to = "0xB4C3826aFea3Bc437C49695983eAaCFF2Bf8E305" // Receiver of tokens
const amount = ethers.utils.parseEther(".01") // Amount of native gas tokens to transfer
const tokenAddr = "0x9983f755bbd60d1886cbfe103c98c272aa0f03d6" // Address of ERC-20 token to tranfer
const tokenTransferTx = await tokenTransferModule.createTransferTx(to, amount, { address: tokenAddr })
const tokenTransferReceipt = await wallet.deployTx(tokenTransferTx)
console.log(tokenTransferReceipt)

Full Example

,
quick-start.js
// 1. Install necessary packages
// npm install @fun-wallet/sdk ethers
// 2. Add Imports
import { ethers } from "ethers"
import { FunWallet, FunWalletConfig, Modules } from "@fun-wallet/sdk"
const { TokenTransfer } = Modules
// 3. Create EOA Instance
// An internal Fun RPC for customer testing
const rpc = "https://avalanche-fuji.infura.io/v3/4a1a0a67f6874be6bb6947a62792dab7"
const provider = new ethers.providers.JsonRpcProvider(rpc)
// Note that the key here will be exposed and should never be used in production
const eoa = new ethers.Wallet(PRIV_KEY, provider)
// To create an EOA instance with an external wallet (e.g MetaMask) do this instead
// const provider = new ethers.providers.Web3Provider(window.ethereum)
// await provider.send('eth_requestAccounts', []) // <- this promps user to connect metamask
// eoa = provider.getSigner()
// 4. Create a FunWallet
const chainID = "43113" // Fuji testnet
const prefundAmt = 0.3 // amount of native gas token to prefund our FunWallet with
const API_KEY = "" // Get your API key from app.fun.xyz/api-key
const config = new FunWalletConfig(eoa, chainID, prefundAmt)
const wallet = new FunWallet(config, API_KEY)
// init will perform the pre-funding of the FunWallet
await wallet.init()
// 5. Create TokenTransfer Module and add it to our FunWallet
const tokenTransferModule = new TokenTransfer()
await wallet.addModule(tokenTransferModule)
// 6. Deploy FunWallet
const deployWalletReceipt = await wallet.deploy()
// 7. Create Token Transfer Transaction & Deploy Onchain
const to = "0xB4C3826aFea3Bc437C49695983eAaCFF2Bf8E305" // Receiver of tokens
const amount = ethers.utils.parseEther(".01") // Amount of native gas tokens to transfer
const tokenAddr = "0x9983f755bbd60d1886cbfe103c98c272aa0f03d6" // Address of ERC-20 token to tranfer
const tokenTransferTx = await tokenTransferModule.createTransferTx(to, amount, { address: tokenAddr })
const tokenTransferReceipt = await wallet.deployTx(tokenTransferTx)
console.log(tokenTransferReceipt)
,
quick-start-output.json
{
userOpHash: '0xd7ea68043200a00db7bdf072842cb3669456525ab24db6032f910fe7aafd56cb',
txid: '0xb98e9c5cd9451a5b7335723f223738eaa0c16b3a60f47e9d3592ff5faef54fb4',
gasUsed: 173974,
gasUSD: 0.09142246713
}

To verify that this transaction executed successfully, view the transaction id on your testnet. The example transaction can be found here.


Mentioned Classes