This is a fork of flutter_web3_provider. Be sure to check out the original package.
flutter_web3 is Dart class and method wrapper for
- Ethereum object
- Ether.js package
- This can be used to sign transaction and interact with smart contract, also query Blockchain data utils and a lot of helper function for developing dapps.
- Wallet Connect Provider package
- This enable QR code modal interaction and enable wallet that utilize Wallet Connect to use provider.
By utilizing dart2js functionality and dart extension, we manage to get Typing and Asynchonous into dart!
API Reference can be view here
NOTE: This is for Flutter web only!
-
1.0.18:
ethereumEnabled
getter was changed toisEthereumSupported
to reflect its property more clearly. -
1.0.15: Ethers
Utils
class was changed toEthUtils
, Functionality remain the same.
You can access the Ethereum object by accessing the ethereum
getter.
// use `isEthereumSupported` to avoid js undefined error on some browser.
if (isEthereumSupported) {
final accs = await ethereum!.getAccounts(); // get all accounts in node disposal.
accs // [foo,bar]
}
Prompt user to connect to provider, aka eth_requestAccounts,
final accs = await ethereum!.requestAccount(); // prompt the connection, make sure to handle the error when user cancle.
accs // [foo,bar]
Subscribe to accountsChanged event,
ethereum!.onAccountChanged((accs) {
print(accs); // [foo,bar]
});
Handle other dynamic event,
ethereum!.on('message', (message) {
final json = convertToDart(message); // Convert js to Dart object.
json['foo'] // Foo
json['bar']['baz'] // Barbaz
});
Or call other json rpc request method that have generic return type T,
final result = await ethereum!.request<BigNumber>('eth_gasPrice');
result.toBigInt; // 100,000,000,000
To initialize, add ethers.js script to web/index.html
.
<script src="https://cdn.ethers.io/lib/ethers-5.0.umd.min.js" type="application/javascript"></script>
Then create an ethers provider:
// For a read-only provider:
final provider = JsonRpcProvider("https://rpc.foo.io");
// For a read-write provider (ie: metamask, trust wallet, binance chain, etc.)
final provider = Web3Provider(ethereum!);
Or use the default Web3Provider getter
final web3provider = provider;
Then we can query various Blockchain data,
final balance = await provider!.getBalance('0xBar');
balance // 100,000,000 (in Wei)
final block = await provider!.getBlock(3949294);
block.miner // 0xbar
block.transaction // [0xfoo,0xbar,0xbarbaz]
block.nounce // 1293014
Or directly calling Ethers js with specific result type,
final result = await provider!.call<BigNumber>('getGasPrice');
result.toBigInt;// 100,000,000,000,000
Use signer to get specific data about address in possession,
final balance = await provider!.getBalance();
balance; // 100,000,000,000,000
Or use signer to send transaction,
final tx = await provider!.getSigner().send(TxParams(to: '0xbar',value: '100,000,000'));
tx.hash // 0xbaz
Initializing Contract object, Supported Abi types refer to Ether.js docs
final abi = [
// Some details about the token
"function name() view returns (string)",
"function symbol() view returns (string)",
// Get the account balance
"function balanceOf(address) view returns (uint)",
// Send some of your tokens to someone else
"function transfer(address to, uint amount)",
// An event triggered whenever anyone transfers to someone else
"event Transfer(address indexed from, address indexed to, uint amount)"
];
final contract = Contract('0xfoo', abi, provider!);
Calling view-only property,
final name = await contract.call<String>('name');
name // FooBarBaz
final symbol = await contract.call<String>('symbol');
symbol // FBB
Multicalling view-only constant method,
final balances = await contract.multicall<String>('balanceOf', [
['0xbar'],
['0xfoo'],
['0xbaz']
]);
balances // [1000000, 1000000, 1000000000]
Sending write method (need Signer to passed into the contract),
final contract = Contract('0xfoo', abi, provider!.getSigner());
final tx = await contract.send('transfer', ['0xbarbaz','100000000']);
tx.hash // 0xfoo
And wait until transaction is successfully mined
var receipt = await provider!.waitForTransaction(tx.hash);
// or
var receipt = await tx.wait();
receipt.isSuccessful // true if successful
receipt.logs.firstWhere((e) => e.topics.first == '0xbar').data // 0xfoobar
Subscribe to any emitted event,
contract.on('Transfer', (from,to,amount,data) {
convertToDart(data) // {'foo':'bar','baz':'foobar',...}
from // 0xbar
to // 0xbaz
amount // 100,000,000,000
});
Convert abi to different format,
final interface = Interface([
'function balanceOf(address) view returns (uint)',
]);
interface.format(FormatTypes.json); // [{"type":"function","name":"balanceOf","constant":true,"stateMutability":"view","payable":false,"inputs":[{"type":"address"}],"outputs":[{"type":"uint256"}]}]
Query past event logs,
// Filter logs from 0xfoo to { 0xbar or 0xbaz }.
final filter = contract.getFilter('Transfer', ['0xfoo', ['0xbar', '0xbaz']]);
// Apply filter and query all logs from block 111111 to lastest.
final logs = await contract.queryFilter(filter, 111111);
// The last is the most recent one.
logs.last.transactionHash // 0xfoobar
Alternatively for ERC20 Contract, we can use ContractERC20 class.
final token = ContractERC20('0xfoo', provider!.getSigner());
await token.name; // Foo
await token.symbol; // Bar
await token.decimals; // Baz
final tx = await token.transfer('0xbar', BigInt.parse('10000000000000'));
tx.hash // 0xbarbaz
token.onApproval((owner, spender, value, data) {
owner // 0xfoo
spender //0xbar
value //0xbaz
});
To initialize, add Wallet Connect Provider script to web/index.html
. We can use CDN from jsdelivr.
<script src="https://cdn.jsdelivr.net/npm/@walletconnect/web3-provider@1.5.0-rc.2/dist/umd/index.min.js" type="application/javascript"></script>
Create Wallet Connect Provider object,
Since rpc argument in WalletConnectProviderOptions
is js map object with dynamic keys and values, we need to wrap it in js converter.
final jsMap = convertRpc({
56: 'https://bsc-dataseed.binance.org/',
});
final option = WalletConnectProviderOptions(
rpc: jsMap,
network: 'binance', // select one sepcific network to connect
chainId: 56, // select one sepcific network to connect
);
final wc = WalletConnectProvider(option);
Then enable the session by toggling QR code modal,
await wc.connect();
After that, we can use the object normally as Ethereum object,
await wc.getChainId(); // 1
Or integrate into Ethers library and use Web3Provider to interact further,
final w3 = Web3Provider(wc);
await w3.getGasPrice(); // 100,000,000