This guide will show you how to use BLS Wallet in your L2 dApp (Layer 2 decentralized application) so you can utilize multi-action transactions.
Quill is a prototype browser extension wallet which integrates bls-wallet-clients to communicate with the BLS Wallet smart contracts & transaction aggregator. It supports most of the functionality in EIP-1193.
Currently, we have the contracts deployed to the networks/chains listed here. If your desired network isn't there, you can use the Remote Development contract deployment instructions or request a network deploy by opening an issue or starting a discussion.
Below are the instructions for 2 ways you can add Quill to your browser.
Go to the releases page and scroll down to the latest release. In the Assets
section, download the extension for either Chrome, Firefox, or Opera. To install, simply drag and drop the file into your browser on the extensions page or follow instructions for installing extensions from a file for your browser.
Follow the instructions in either Local Development or Remote Development to setup this repo and install Quill.
After installing the extension, Quill will auto-open and guide you through the setup process.
Next, connect your dApp to Quill just like you would any other extension wallet.
ethers.js
import { providers } from "ethers";
const provider = new providers.Web3Provider(window.ethereum);
await window.ethereum.request({ method: "eth_accounts" });
Or similarly with web3modal or rainbow-connect
Finally, you can populate & send your multi-action transaction. In the following example, we will do an approve & swap with a DEX (decentralized exchange) in one transaction.
Since any browser extension wallet could be used, make sure that it is Quill before allowing a multi-action transaction.
const areMultiActionTransactionSupported = !!window.ethereum.isQuill;
// Branch here depending on the result
if (areMultiActionTransactionSupported) {
...
}
First, we will populate the transactions (actions) we want to send.
// Get the signer and connect to the contracts.
//
// If you want the contracts to always have write access
// for a specific account, pass the signer in as the
// provider instead and skip calling connect on them.
const signer = provider.getSigner();
const erc20Contract = new ethers.Contract(erc20Address, erc20Abi, provider);
const dexContract = new ethers.Contract(dexAddress, dex20Abi, provider);
// Populate the token approval transaction.
const approveTransaction = await erc20Contract
.connect(signer)
.populateTransaction.approve(dexAddress, amount);
// Populate the token swap transaction.
const swapTransaction = await dexContract
.connect(signer)
.populateTransaction.swap(erc20Address, amount, otherERC20Address);
Then, send the populated transactions.
Quill's eth_sendTransaction accepts a modified params
property into which more than one transaction object can be passed in. Make sure window.ethereum can accept multiple transactions before passing more than one in.
const transactionHash = await window.ethereum.request({
method: "eth_sendTransaction",
params: [approveTransaction, swapTransaction],
});
const transactionReceipt = await provider.getTransactionReceipt(
transactionHash
);
// Do anything else you need to with the transaction receipt.
You also can still send normal one-off transactions as you normally would, and still get the gas saving benefits of having your transaction aggregated with other transactions.
const transferTransaction = await erc20Contract
.connect(signer)
.approve(otherAddress, amount);
await transferTransaction.wait();
See the System Overview for more details on what's happening behind the scenes.
- https://github.com/kautukkundan/BLSWallet-ERC20-demo
- https://github.com/voltrevo/bls-wallet-billboard
- https://github.com/JohnGuilding/single-pool-dex
- Gasless transaction example.