Skip to content

Commit

Permalink
Enhancements on loading states
Browse files Browse the repository at this point in the history
  • Loading branch information
quetool committed Apr 11, 2024
1 parent 971145e commit 310bedc
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 131 deletions.
27 changes: 14 additions & 13 deletions example/wallet/lib/dependencies/chains/evm_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@ class EVMService {
late final Web3Client ethClient;

Map<String, dynamic Function(String, dynamic)> get sessionRequestHandlers => {
'personal_sign': personalSign,
};

Map<String, dynamic Function(String, dynamic)> get methodRequestHandlers => {
'personal_sign': personalSign,
// 'personal_sign': personalSign,
'eth_sign': ethSign,
'eth_signTransaction': ethSignTransaction,
'eth_sendTransaction': ethSendTransaction,
'eth_signTypedData': ethSignTypedData,
'eth_signTypedData_v4': ethSignTypedDataV4,
'wallet_switchEthereumChain': switchChain,
'wallet_addEthereumChain': addChain,
};

Map<String, dynamic Function(String, dynamic)> get methodRequestHandlers => {
'personal_sign': personalSign,
'eth_sendTransaction': ethSendTransaction,
};

EVMService({required this.chainSupported}) {
final supportedId = chainSupported.chainId;
final chainMetadata = ChainData.allChains.firstWhere(
Expand All @@ -55,6 +55,13 @@ class EVMService {
);
}

for (var handler in sessionRequestHandlers.entries) {
_web3Wallet.registerRequestHandler(
chainId: chainSupported.chainId,
method: handler.key,
handler: handler.value,
);
}
for (var handler in methodRequestHandlers.entries) {
_web3Wallet.registerRequestHandler(
chainId: chainSupported.chainId,
Expand All @@ -67,8 +74,8 @@ class EVMService {
}

void _onSessionRequest(SessionRequestEvent? args) async {
debugPrint('[WALLET] _onSessionRequest ${args?.toString()}');
if (args != null && args.chainId == chainSupported.chainId) {
debugPrint('[WALLET] _onSessionRequest ${args.toString()}');
final handler = sessionRequestHandlers[args.method];
if (handler != null) {
await handler(args.topic, args.params);
Expand All @@ -79,7 +86,6 @@ class EVMService {
// personal_sign is handled using onSessionRequest event for demo purposes
Future<void> personalSign(String topic, dynamic parameters) async {
debugPrint('[WALLET] personalSign request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
final message = EthUtils.getUtf8Message(data.toString());
Expand Down Expand Up @@ -123,7 +129,6 @@ class EVMService {

Future<void> ethSign(String topic, dynamic parameters) async {
debugPrint('[WALLET] ethSign request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
final message = EthUtils.getUtf8Message(data.toString());
Expand Down Expand Up @@ -167,7 +172,6 @@ class EVMService {

Future<void> ethSignTypedData(String topic, dynamic parameters) async {
debugPrint('[WALLET] ethSignTypedData request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
var response = JsonRpcResponse(
Expand Down Expand Up @@ -209,7 +213,6 @@ class EVMService {

Future<void> ethSignTypedDataV4(String topic, dynamic parameters) async {
debugPrint('[WALLET] ethSignTypedDataV4 request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
var response = JsonRpcResponse(
Expand Down Expand Up @@ -251,7 +254,6 @@ class EVMService {

Future<void> ethSignTransaction(String topic, dynamic parameters) async {
debugPrint('[WALLET] ethSignTransaction request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
Expand Down Expand Up @@ -305,7 +307,6 @@ class EVMService {

Future<void> ethSendTransaction(String topic, dynamic parameters) async {
debugPrint('[WALLET] ethSendTransaction request: $parameters');
DeepLinkHandler.waiting.value = true;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
Expand Down
23 changes: 11 additions & 12 deletions example/wallet/lib/dependencies/deep_link_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,17 @@ class DeepLinkHandler {
waiting.value = false;
if (scheme.isEmpty) return;
await Future.delayed(Duration(milliseconds: delay));
launchUrlString(scheme, mode: LaunchMode.externalApplication).catchError(
(e) {
debugPrint(
'[WALLET] [DeepLinkHandler] error re-opening dapp ($scheme). $e');
_goBackModal(
title: modalTitle,
message: modalMessage,
success: success,
);
return true;
},
);
try {
await launchUrlString(scheme, mode: LaunchMode.externalApplication);
} catch (e) {
debugPrint(
'[WALLET] [DeepLinkHandler] error re-opening dapp ($scheme). $e');
_goBackModal(
title: modalTitle,
message: modalMessage,
success: success,
);
}
}

static void _onLink(Object? event) {
Expand Down
162 changes: 96 additions & 66 deletions example/wallet/lib/dependencies/web3wallet_service.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:eth_sig_util/eth_sig_util.dart';
Expand All @@ -22,6 +23,20 @@ class Web3WalletService extends IWeb3WalletService {
final _bottomSheetHandler = GetIt.I<IBottomSheetService>();
Web3Wallet? _web3Wallet;

static final supportedMethods = {
'eth_sign',
'eth_signTransaction',
'eth_signTypedData',
'eth_signTypedData_v4',
'wallet_switchEthereumChain',
'wallet_addEthereumChain',
};

static final requiredMethods = {
'personal_sign',
'eth_sendTransaction',
};

@override
void create() async {
// Create the web3wallet
Expand Down Expand Up @@ -77,7 +92,6 @@ class Web3WalletService extends IWeb3WalletService {
debugPrint('[WALLET] [$runtimeType] create');
_web3Wallet!.core.pairing.onPairingInvalid.subscribe(_onPairingInvalid);
_web3Wallet!.core.pairing.onPairingCreate.subscribe(_onPairingCreate);
_web3Wallet!.pairings.onSync.subscribe(_onPairingsSync);
_web3Wallet!.onSessionProposal.subscribe(_onSessionProposal);
_web3Wallet!.onSessionProposalError.subscribe(_onSessionProposalError);
_web3Wallet!.onAuthRequest.subscribe(_onAuthRequest);
Expand All @@ -100,7 +114,7 @@ class Web3WalletService extends IWeb3WalletService {
FutureOr onDispose() {
debugPrint('[$runtimeType] [WALLET] dispose');
_web3Wallet!.core.pairing.onPairingInvalid.unsubscribe(_onPairingInvalid);
_web3Wallet!.pairings.onSync.unsubscribe(_onPairingsSync);
_web3Wallet!.core.pairing.onPairingCreate.unsubscribe(_onPairingCreate);
_web3Wallet!.onSessionProposal.unsubscribe(_onSessionProposal);
_web3Wallet!.onSessionProposalError.unsubscribe(_onSessionProposalError);
_web3Wallet!.onAuthRequest.unsubscribe(_onAuthRequest);
Expand All @@ -115,57 +129,15 @@ class Web3WalletService extends IWeb3WalletService {
@override
Web3Wallet get web3wallet => _web3Wallet!;

void _onPairingsSync(StoreSyncEvent? args) {
debugPrint('[$runtimeType] [WALLET] _onPairingsSync');
}

void _onSessionProposalError(SessionProposalErrorEvent? args) async {
debugPrint('[$runtimeType] [WALLET] _onSessionProposalError $args');
if (args != null) {
String errorMessage = args.error.message;
if (args.error.code == 5100) {
errorMessage =
errorMessage.replaceFirst('Requested:', '\n\nRequested:');
errorMessage =
errorMessage.replaceFirst('Supported:', '\n\nSupported:');
}
GetIt.I<IBottomSheetService>().queueBottomSheet(
widget: Container(
color: Colors.white,
width: double.infinity,
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Icon(
Icons.error_outline_sharp,
color: Colors.red[100],
size: 80.0,
),
Text(
'Error',
style: StyleConstants.subtitleText.copyWith(
color: Colors.black,
fontSize: 18.0,
),
),
Text(errorMessage),
],
),
),
);
}
}

Map<String, Namespace> _generateNamespaces(
Map<String, Namespace>? approvedNamespaces,
ChainType chainType,
) {
//
final constructedNS = Map<String, Namespace>.from(approvedNamespaces ?? {});
constructedNS[chainType.name] = constructedNS[chainType.name]!.copyWith(
methods: [
'personal_sign',
...constructedNS[chainType.name]!.methods,
...supportedMethods,
],
);
return constructedNS;
Expand All @@ -183,6 +155,7 @@ class Web3WalletService extends IWeb3WalletService {
final proposalData = args.params.copyWith(
generatedNamespaces: approvedNS,
);
debugPrint('[WALLET] proposalData $proposalData');
final approved = await _bottomSheetHandler.queueBottomSheet(
widget: WCRequestWidget(
child: WCConnectionRequestWidget(
Expand All @@ -195,17 +168,17 @@ class Web3WalletService extends IWeb3WalletService {
),
);

final scheme = args.params.proposer.metadata.redirect?.native ?? '';

if (approved == true) {
await _web3Wallet!.approveSession(id: args.id, namespaces: approvedNS);
DeepLinkHandler.goTo(scheme);
} else {
final error = Errors.getSdkError(Errors.USER_REJECTED);
await _web3Wallet!.rejectSession(id: args.id, reason: error);
// await _web3Wallet!.core.pairing.disconnect(
// topic: args.params.pairingTopic,
// );
await _web3Wallet!.core.pairing.disconnect(
topic: args.params.pairingTopic,
);

// TODO this should be triggered on _onRelayClientMessage
final scheme = args.params.proposer.metadata.redirect?.native ?? '';
DeepLinkHandler.goTo(
scheme,
modalTitle: 'Error',
Expand All @@ -216,10 +189,77 @@ class Web3WalletService extends IWeb3WalletService {
}
}

void _onRelayClientMessage(MessageEvent? args) {
debugPrint(
'[$runtimeType] [WALLET] _onRelayClientMessage ${args.toString()}',
);
void _onSessionProposalError(SessionProposalErrorEvent? args) async {
debugPrint('[$runtimeType] [WALLET] _onSessionProposalError $args');
DeepLinkHandler.waiting.value = false;
if (args != null) {
String errorMessage = args.error.message;
if (args.error.code == 5100) {
errorMessage =
errorMessage.replaceFirst('Requested:', '\n\nRequested:');
errorMessage =
errorMessage.replaceFirst('Supported:', '\n\nSupported:');
}
GetIt.I<IBottomSheetService>().queueBottomSheet(
widget: Container(
color: Colors.white,
width: double.infinity,
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Icon(
Icons.error_outline_sharp,
color: Colors.red[100],
size: 80.0,
),
Text(
'Error',
style: StyleConstants.subtitleText.copyWith(
color: Colors.black,
fontSize: 18.0,
),
),
Text(errorMessage),
],
),
),
);
}
}

void _onRelayClientMessage(MessageEvent? args) async {
debugPrint('[$runtimeType] [WALLET] _onRelayClientMessage $args');
if (args != null) {
final payloadString = await _web3Wallet!.core.crypto.decode(
args.topic,
args.message,
);
if (payloadString == null) return;

final data = jsonDecode(payloadString);
if (data.containsKey('method')) {
final request = JsonRpcRequest.fromJson(data);
debugPrint('[$runtimeType] [WALLET] _onRelayClientMessage $request');
if (request.method != 'wc_sessionDelete' &&
request.method != 'wc_pairingDelete') {
DeepLinkHandler.waiting.value = true;
}
} else {
final response = JsonRpcResponse.fromJson(data);
debugPrint('[$runtimeType] [WALLET] _onRelayClientMessage $response');
// REDIRECT BACK TO DAPP
final session = _web3Wallet!.sessions.get(args.topic);
final scheme = session?.peer.metadata.redirect?.native ?? '';
DeepLinkHandler.goTo(
scheme,
modalTitle: response.result != null ? null : 'Error',
modalMessage: response.result != null
? null
: response.error?.message ?? 'Error',
success: response.result != null,
);
}
}
}

void _onRelayClientError(ErrorEvent? args) {
Expand Down Expand Up @@ -261,14 +301,6 @@ class Web3WalletService extends IWeb3WalletService {
),
);

// EthPrivateKey credentials =
// EthPrivateKey.fromHex(chainKeys.first.privateKey);
// final String sig = utf8.decode(
// credentials.signPersonalMessageToUint8List(
// Uint8List.fromList(message.codeUnits),
// ),
// );

final String sig = EthSigUtil.signPersonalMessage(
message: Uint8List.fromList(message.codeUnits),
privateKey: chainKeys.first.privateKey,
Expand All @@ -286,9 +318,7 @@ class Web3WalletService extends IWeb3WalletService {
await _web3Wallet!.respondAuthRequest(
id: args.id,
iss: iss,
error: Errors.getSdkError(
Errors.USER_REJECTED_AUTH,
),
error: Errors.getSdkError(Errors.USER_REJECTED_AUTH),
);
}
}
Expand Down
1 change: 1 addition & 0 deletions example/wallet/lib/pages/app_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class AppDetailPageState extends State<AppDetailPage> {
final namespaceWidget = ConnectionWidgetBuilder.buildFromNamespaces(
session.topic,
session.namespaces,
context,
);
// Loop through and add the namespace widgets, but put 20 pixels between each one
for (int i = 0; i < namespaceWidget.length; i++) {
Expand Down
Loading

0 comments on commit 310bedc

Please sign in to comment.