Skip to content

Instantly share code, notes, and snippets.

@TABASCOatw
Created October 25, 2023 07:10
Show Gist options
  • Save TABASCOatw/375a8707115832ea71c9d06bcff81fa1 to your computer and use it in GitHub Desktop.
Save TABASCOatw/375a8707115832ea71c9d06bcff81fa1 to your computer and use it in GitHub Desktop.
Avalanche Mainnet Biconomy smart account implementation with Smart WaaS (modular SA update)
import React, { useState, useEffect } from 'react';
import { ParticleNetwork } from '@particle-network/auth';
import { ParticleProvider } from '@particle-network/provider';
import { Avalanche } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount, SendTransactionMode } from '@particle-network/aa';
import { ethers } from 'ethers';
const config = {
projectId: process.env.REACT_APP_PROJECT_ID,
clientKey: process.env.REACT_APP_CLIENT_KEY,
appId: process.env.REACT_APP_APP_ID,
};
const particle = new ParticleNetwork({
...config,
chainName: Avalanche.name,
chainId: Avalanche.id,
wallet: { displayWalletEntry: true }
});
const smartAccount = new SmartAccount(new ParticleProvider(particle.auth), {
...config,
aaOptions: {
biconomy: [{ chainId: Avalanche.id, version: '1.0.0' }],
paymasterApiKeys: [{ chainId: Avalanche.id, apiKey: process.env.BICONOMY_API_KEY }]
}
});
const customProvider = new ethers.providers.Web3Provider(new AAWrapProvider(smartAccount, SendTransactionMode.Gasless), "any");
particle.setERC4337({
name: 'BICONOMY',
version: '1.0.0'
});
const App = () => {
const [userInfo, setUserInfo] = useState(null);
const [avaxBalance, setAvaxBalance] = useState(null);
useEffect(() => {
if (userInfo) {
fetchAvaxBalance();
}
}, [userInfo]);
const fetchAvaxBalance = async () => {
const address = await smartAccount.getAddress();
const balance = await customProvider.getBalance(address);
setAvaxBalance(ethers.utils.formatEther(balance));
};
const handleLogin = async (preferredAuthType) => {
const user = !particle.auth.isLogin() ? await particle.auth.login({preferredAuthType}) : particle.auth.getUserInfo();
setUserInfo(user);
}
const executeUserOp = async () => {
const signer = customProvider.getSigner();
const tx = {
to: "0x000000000000000000000000000000000000dEaD",
value: ethers.utils.parseEther("0.001"),
};
const txResponse = await signer.sendTransaction(tx);
const txReceipt = await txResponse.wait();
console.log('Transaction hash:', txReceipt.transactionHash);
};
return (
<div className="App">
{!userInfo ? (
<div>
<button onClick={() => handleLogin('google')}>Sign in with Google</button>
<button onClick={() => handleLogin('twitter')}>Sign in with Twitter</button>
</div>
) : (
<div>
<h2>{userInfo.name}</h2>
<div>
<small>{avaxBalance} AVAX</small>
<button onClick={executeUserOp}>Execute User Operation</button>
</div>
</div>
)}
</div>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment