Skip to content

Commit

Permalink
feat: Added loadTokens and transferToken in the mirai_web3 service
Browse files Browse the repository at this point in the history
  • Loading branch information
i-asimkhan committed Feb 16, 2024
1 parent 3d71248 commit 4c1ba59
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ class MiraiWeb3SignMessageParser
@override
FutureOr<dynamic> onCall(
BuildContext context, MiraiWeb3SignMessage model) async {
return await Web3ModalService.signMessage(model.message);
return await Web3ModalService.requestSignMessage(model.message);
}
}
3 changes: 3 additions & 0 deletions packages/mirai_web3/lib/mirai_web3.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ library mirai_web3;

export 'package:mirai_web3/action_parsers/action_parsers.dart';
export 'package:mirai_web3/parsers/parsers.dart';

// `web3modal_flutter` exports
export 'package:web3modal_flutter/models/w3m_chain_info.dart';
15 changes: 15 additions & 0 deletions packages/mirai_web3/lib/models/contract_details.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class ContractDetails {
ContractDetails({
required this.name,
required this.address,
required this.chainId,
required this.rpcUrl,
required this.abi,
});

final String name;
final String address;
final String chainId;
final String rpcUrl;
final List<Map<String, dynamic>> abi;
}
13 changes: 13 additions & 0 deletions packages/mirai_web3/lib/models/token.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Token {
Token({
required this.name,
required this.address,
required this.supply,
required this.balance,
});

final String name;
final String address;
final String supply;
final String balance;
}
174 changes: 148 additions & 26 deletions packages/mirai_web3/lib/services/web_modal_service.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:mirai_web3/models/chain_meta_data.dart';
import 'package:mirai_web3/models/contract_details.dart';
import 'package:mirai_web3/models/token.dart';
import 'package:web3modal_flutter/web3modal_flutter.dart';

class Web3ModalService {
const Web3ModalService._();

static late W3MService _service;
static W3MService get service => _service;
static late ChainMetadata _chainMetadata;
static late List<ContractDetails> _contracts;
static String? _signature;

static W3MService get service => _service;
static bool get isConnected => _service.isConnected;
static String get connectedWalletAddress =>
isConnected ? _service.session?.address ?? '' : '';
static String? _signature;
static String get signature => _signature ?? '';
static String get chainId =>
_service.selectedChain?.chainId ?? W3MChainPresets.chains['1']!.chainId;

static late ChainMetadata chainMetadata;

static Future<bool> initialize({ChainMetadata? metadata}) async {
chainMetadata = metadata ??
static Future<bool> initialize({
ChainMetadata? metadata,
List<W3MChainInfo> customChains = const [],
List<ContractDetails> contractsList = const [],
}) async {
_chainMetadata = metadata ??
const ChainMetadata(
projectId: "68ccdce69aec001e3cd0b33aec530b81",
name: 'Mirai Gallery',
Expand All @@ -26,26 +37,32 @@ class Web3ModalService {
icons: ['https://walletconnect.com/walletconnect-logo.png'],
);

for (W3MChainInfo chain in customChains) {
W3MChainPresets.chains.putIfAbsent(chain.chainId, () => chain);
}

_contracts = contractsList;

bool isInitialize = false;
try {
_service = W3MService(
projectId: chainMetadata.projectId,
projectId: _chainMetadata.projectId,
metadata: PairingMetadata(
name: chainMetadata.name,
description: chainMetadata.description,
url: chainMetadata.url,
icons: chainMetadata.icons,
name: _chainMetadata.name,
description: _chainMetadata.description,
url: _chainMetadata.url,
icons: _chainMetadata.icons,
redirect: Redirect(
native: 'w3m://',
universal: chainMetadata.url,
universal: _chainMetadata.url,
),
),
);
await _service.init();

isInitialize = true;
} catch (err) {
debugPrint("Catch wallet initialize error $err");
} catch (e) {
debugPrint("Catch wallet initialize error $e");
}
return isInitialize;
}
Expand All @@ -60,22 +77,127 @@ class Web3ModalService {
}
}

static Future<String?> signMessage(String message) async {
static Future<String?> requestSignMessage(String message) async {
if (!isConnected) return null;

await _service.launchConnectedWallet();
try {
await _service.launchConnectedWallet();

final signature = await _service.web3App!.request(
topic: _service.session!.topic!,
chainId: _service.selectedChain?.namespace ?? "eip155:1",
request: SessionRequestParams(
method: 'personal_sign',
params: [message, connectedWalletAddress],
),
);
final signature = await _service.web3App!.request(
topic: _service.session!.topic!,
chainId: _service.selectedChain?.namespace ?? "eip155:1",
request: SessionRequestParams(
method: 'personal_sign',
params: [message, connectedWalletAddress],
),
);

_signature = signature;
return signature;
} catch (e) {
debugPrint(e.toString());
return null;
}
}

static Future<List<Token>> loadTokens() async {
List<Token> tokens = [];

try {
for (ContractDetails contract in _contracts) {
// Create DeployedContract object using contract's ABI and address
final deployedContract = DeployedContract(
ContractAbi.fromJson(
jsonEncode(contract.abi),
contract.name,
),
EthereumAddress.fromHex(contract.address),
);

if (contract.chainId == chainId) {
final results = await Future.wait([
// results[0]
_service.requestReadContract(
deployedContract: deployedContract,
functionName: 'name',
rpcUrl: contract.rpcUrl,
),
// results[1]
_service.requestReadContract(
deployedContract: deployedContract,
functionName: 'totalSupply',
rpcUrl: contract.rpcUrl,
),
// results[2]
_service.requestReadContract(
deployedContract: deployedContract,
functionName: 'balanceOf',
rpcUrl: contract.rpcUrl,
parameters: [
EthereumAddress.fromHex(connectedWalletAddress),
],
),
]);

final formatter = NumberFormat("#,##0.00", "en_US");
final name = results[0].toString();
final total = results[1] / BigInt.from(1000000000000000000);
final balance = results[2] / BigInt.from(1000000000000000000);

tokens.add(Token(
name: name,
address: contract.address,
supply: formatter.format(total),
balance: formatter.format(balance),
));
}
}
} catch (e) {
debugPrint(e.toString());
}

return tokens;
}

static Future<String?> transferToken({
required String tokenAddress,
required String toAddress,
required int amount,
}) async {
try {
final contract =
_contracts.firstWhere((contract) => contract.address == tokenAddress);

// Create DeployedContract object using contract's ABI and address
final deployedContract = DeployedContract(
ContractAbi.fromJson(
jsonEncode(contract.abi),
contract.name,
),
EthereumAddress.fromHex(
contract.address,
),
);

final transactionHash = await _service.requestWriteContract(
topic: _service.session!.topic!,
chainId: _service.selectedChain!.namespace,
rpcUrl: contract.rpcUrl,
deployedContract: deployedContract,
functionName: 'transfer',
transaction: Transaction(
from: EthereumAddress.fromHex(_service.session!.address!),
to: EthereumAddress.fromHex(toAddress),
value: EtherAmount.fromInt(EtherUnit.wei, amount),
),
);

return transactionHash;
} catch (e) {
debugPrint(e.toString());
}

_signature = signature;
return signature;
return null;
}

static Future<void> disconnect() async {
Expand Down
1 change: 1 addition & 0 deletions packages/mirai_web3/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies:
freezed_annotation: ^2.2.0
json_annotation: ^4.8.1
mirai_framework: ^0.0.1
intl: ^0.19.0
# web3modal_flutter: ^3.1.0
web3modal_flutter:
git:
Expand Down

0 comments on commit 4c1ba59

Please sign in to comment.