generate static method
String
generate({
- required String chainId,
- required List<
String> accounts, - required bool isConnected,
- required EIP6963ProviderInfo providerInfo,
Implementation
static String generate({
required String chainId,
required List<String> accounts,
required bool isConnected,
required EIP6963ProviderInfo providerInfo,
}) {
return '''
(function() {
class EthereumProvider extends EventTarget {
constructor() {
super();
this._isConnected = ${isConnected};
this._chainId = '${chainId}';
this._accounts = ${jsonEncode(accounts)};
this._initialized = false;
// Standard properties
this.isWallet = true;
this._networkVersion = parseInt(this._chainId, 16).toString();
// Initialize
this._initialize();
}
async _initialize() {
try {
this._initialized = true;
if (this._isConnected) {
this._emit('connect', { chainId: this._chainId });
if (this._accounts.length > 0) {
this._emit('accountsChanged', this._accounts);
}
}
} catch (error) {
console.error('Failed to initialize provider:', error);
}
}
async request(args) {
if (!args || typeof args !== 'object' || !args.method) {
throw new Error('Invalid request args');
}
const { method, params = [] } = args;
if (params && !Array.isArray(params)) {
throw new Error('Invalid params');
}
try {
const result = await window.flutter_inappwebview.callHandler(
'ethereumRequest',
{
method,
params,
chainId: this._chainId
}
);
if (method === 'eth_requestAccounts') {
this._handleAccountsChanged(result);
}
return result;
} catch (error) {
throw this._processError(error);
}
}
on(eventName, listener) {
this.addEventListener(eventName, (event) => {
listener(event.detail);
});
}
once(eventName, listener) {
const handler = (event) => {
this.removeEventListener(eventName, handler);
listener(event.detail);
};
this.addEventListener(eventName, handler);
}
removeListener(eventName, listener) {
this.removeEventListener(eventName, listener);
}
_emit(eventName, data) {
const event = new CustomEvent(eventName, { detail: data });
this.dispatchEvent(event);
}
_handleAccountsChanged(accounts) {
if (Array.isArray(accounts)) {
const changed = !this._arrayEquals(this._accounts, accounts);
if (changed) {
this._accounts = accounts;
this._emit('accountsChanged', accounts);
}
}
}
async _handleChainChanged(chainId) {
if (this._chainId !== chainId) {
this._chainId = chainId;
this._networkVersion = parseInt(chainId, 16).toString();
this._emit('chainChanged', chainId);
}
}
_arrayEquals(a, b) {
return Array.isArray(a) && Array.isArray(b) &&
a.length === b.length &&
a.every((val, index) => val === b[index]);
}
_processError(error) {
if (typeof error === 'string') {
return new Error(error);
}
return error;
}
get isConnected() {
return this._isConnected;
}
disconnect() {
this._isConnected = false;
this._accounts = [];
this._emit('disconnect', {});
this._emit('accountsChanged', []);
}
enable() {
console.warn('ethereum.enable() is deprecated, use ethereum.request({method: "eth_requestAccounts"}) instead.');
return this.request({ method: 'eth_requestAccounts' });
}
get selectedAddress() {
return this._isConnected ? (this._accounts[0] || null) : null;
}
get chainId() {
return this._chainId;
}
get networkVersion() {
return this._networkVersion;
}
// ✅ BỔ SUNG CÁC METHODS THIẾU
async send(method, params) {
return this.request({ method, params });
}
async sendAsync(payload, callback) {
try {
const result = await this.request(payload);
callback(null, { id: payload.id, result });
} catch (error) {
callback(error, { id: payload.id, error: { message: error.message, code: -32000 } });
}
}
// ✅ SUPPORT CHO WEB3.JS LEGACY
get currentProvider() {
return this;
}
// ✅ SUPPORT CHO EIP-1193 EVENTS (alias cho addEventListener)
addListener(eventName, listener) {
this.addEventListener(eventName, (event) => {
listener(event.detail);
});
}
// ✅ SUPPORT CHO METAMASK COMPATIBILITY
get isMetaMask() {
return true;
}
// ✅ SUPPORT CHO PERSONAL METHODS
async personalSign(message, address) {
return this.request({ method: 'personal_sign', params: [message, address] });
}
async signTypedData(typedData, address) {
return this.request({ method: 'eth_signTypedData_v4', params: [address, typedData] });
}
// ✅ SUPPORT CHO WALLET METHODS
async requestPermissions() {
return this.request({ method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }] });
}
async getPermissions() {
return this.request({ method: 'wallet_getPermissions' });
}
// ✅ SUPPORT CHO NETWORK METHODS
async switchChain(chainId) {
return this.request({ method: 'wallet_switchEthereumChain', params: [{ chainId }] });
}
async addChain(chainParams) {
return this.request({ method: 'wallet_addEthereumChain', params: [chainParams] });
}
// ✅ SUPPORT CHO ACCOUNT METHODS
async getAccounts() {
return this.request({ method: 'eth_accounts' });
}
async getBalance(address, blockNumber = 'latest') {
return this.request({ method: 'eth_getBalance', params: [address, blockNumber] });
}
// ✅ SUPPORT CHO TRANSACTION METHODS
async sendTransaction(transaction) {
return this.request({ method: 'eth_sendTransaction', params: [transaction] });
}
async signTransaction(transaction) {
return this.request({ method: 'eth_signTransaction', params: [transaction] });
}
// ✅ SUPPORT CHO BLOCK METHODS
async getBlockNumber() {
return this.request({ method: 'eth_blockNumber' });
}
async getBlock(blockHashOrNumber, returnTransactionObjects = false) {
return this.request({ method: 'eth_getBlockByHash', params: [blockHashOrNumber, returnTransactionObjects] });
}
// ✅ SUPPORT CHO CONTRACT METHODS
async call(transaction, blockNumber = 'latest') {
return this.request({ method: 'eth_call', params: [transaction, blockNumber] });
}
async estimateGas(transaction) {
return this.request({ method: 'eth_estimateGas', params: [transaction] });
}
// ✅ SUPPORT CHO UTILITY METHODS
async getGasPrice() {
return this.request({ method: 'eth_gasPrice' });
}
async getTransactionCount(address, blockNumber = 'latest') {
return this.request({ method: 'eth_getTransactionCount', params: [address, blockNumber] });
}
// ✅ SUPPORT CHO FILTER METHODS
async newFilter(filterOptions) {
return this.request({ method: 'eth_newFilter', params: [filterOptions] });
}
async getFilterChanges(filterId) {
return this.request({ method: 'eth_getFilterChanges', params: [filterId] });
}
async uninstallFilter(filterId) {
return this.request({ method: 'eth_uninstallFilter', params: [filterId] });
}
// ✅ SUPPORT CHO SUBSCRIPTION METHODS
async subscribe(subscriptionType, params) {
return this.request({ method: 'eth_subscribe', params: [subscriptionType, ...params] });
}
async unsubscribe(subscriptionId) {
return this.request({ method: 'eth_unsubscribe', params: [subscriptionId] });
}
}
if (typeof window.ethereum === 'undefined') {
const provider = new EthereumProvider();
window.ethereum = provider;
if (typeof window.web3 === 'undefined') {
window.web3 = {
currentProvider: provider
};
}
const walletInfo = {
uuid: "${providerInfo.uuid}",
name: "${providerInfo.name}",
icon: "${providerInfo.icon}",
rdns: "${providerInfo.rdns}",
};
const announcement = {
info: walletInfo,
provider: provider
};
window.addEventListener('eip6963:requestProvider', (event) => {
window.dispatchEvent(new CustomEvent('eip6963:announceProvider', {
detail: announcement
}));
});
console.log('EIP-6963 wallet provider injected');
}
})();
''';
}