Skip to content

Commit

Permalink
fix _onSessionRequest logic in sign_engine so wallet can use either m…
Browse files Browse the repository at this point in the history
…ethods handlers or onSessionRequest event
  • Loading branch information
quetool committed Feb 20, 2024
1 parent 8660262 commit ef2bea5
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 100 deletions.
74 changes: 41 additions & 33 deletions example/wallet/lib/dependencies/chains/evm_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,60 @@ class EVMService {
final ChainMetadata chainSupported;
late final Web3Client ethClient;

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

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

EVMService({required this.chainSupported}) {
final supportedId = chainSupported.chainId;
final chainMetadata = ChainData.allChains.firstWhere(
(c) => c.chainId == supportedId,
);
debugPrint('supportedId $supportedId - ${chainMetadata.rpc.first}');
ethClient = Web3Client(chainMetadata.rpc.first, http.Client());

const supportedEvents = EventsConstants.requiredEvents;
for (final String event in supportedEvents) {
debugPrint('Supported event ${chainSupported.chainId} $event');
for (final event in supportedEvents) {
_web3Wallet.registerEventEmitter(
chainId: chainSupported.chainId,
event: event,
);
}

// Supported methods
Map<String, dynamic Function(String, dynamic)> methodsHandlers = {
'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,
// add whatever method/handler you want to support
};

for (var handler in methodsHandlers.entries) {
for (var handler in methodRequestHandlers.entries) {
_web3Wallet.registerRequestHandler(
chainId: chainSupported.chainId,
method: handler.key,
handler: handler.value,
);
}

_web3Wallet.onSessionRequest.subscribe(_onSessionRequest);
}

void _onSessionRequest(SessionRequestEvent? args) async {
if (args != null && args.chainId == chainSupported.chainId) {
debugPrint('[$runtimeType] onSessionRequest $args');
final handler = sessionRequestHandlers[args.method];
if (handler != null) {
await handler(args.topic, args.params);
}
}
}

// personal_sign is handled using onSessionRequest event for demo purposes
Future<void> personalSign(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] personalSign request: $parameters');
// message, address

final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
final message = EthUtils.getUtf8Message(data.toString());
var response = JsonRpcResponse(
Expand Down Expand Up @@ -115,9 +125,7 @@ class EVMService {

Future<void> ethSign(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] ethSign request: $parameters');
// address, message

final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
final message = EthUtils.getUtf8Message(data.toString());
var response = JsonRpcResponse(
Expand Down Expand Up @@ -162,13 +170,13 @@ class EVMService {

Future<void> ethSignTypedData(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] ethSignTypedData request: $parameters');

final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
var response = JsonRpcResponse(
id: pRequest.id,
jsonrpc: '2.0',
);

if (await requestApproval(data)) {
try {
final keys = GetIt.I<IKeyService>().getKeysForChain(
Expand Down Expand Up @@ -203,13 +211,13 @@ class EVMService {

Future<void> ethSignTypedDataV4(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] ethSignTypedDataV4 request: $parameters');

final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getDataFromParamsList(parameters);
var response = JsonRpcResponse(
id: pRequest.id,
jsonrpc: '2.0',
);

if (await requestApproval(data)) {
try {
final keys = GetIt.I<IKeyService>().getKeysForChain(
Expand Down Expand Up @@ -244,14 +252,14 @@ class EVMService {

Future<dynamic> ethSignTransaction(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] ethSignTransaction request: $parameters');
final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
var response = JsonRpcResponse(
id: pRequest.id,
jsonrpc: '2.0',
);

final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
final result = await approveTransaction(data);
if (result is Transaction) {
try {
Expand Down Expand Up @@ -297,14 +305,14 @@ class EVMService {

Future<dynamic> ethSendTransaction(String topic, dynamic parameters) async {
debugPrint('[$runtimeType] ethSendTransaction request: $parameters');
final pRequest = _web3Wallet.pendingRequests.getAll().first;
final pRequest = _web3Wallet.pendingRequests.getAll().last;
final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
var response = JsonRpcResponse(
id: pRequest.id,
jsonrpc: '2.0',
);

final data = EthUtils.getTransactionFromParams(parameters);
if (data == null) return;
final result = await approveTransaction(data);
if (result is Transaction) {
try {
Expand Down
3 changes: 3 additions & 0 deletions example/wallet/lib/dependencies/web3wallet_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ class Web3WalletService extends IWeb3WalletService {

void _onSessionProposal(SessionProposalEvent? args) async {
if (args != null) {
final accounts = args.params.generatedNamespaces?['eip155']?.accounts;
final allChains = NamespaceUtils.getChainsFromAccounts(accounts ?? []);
debugPrint('[$runtimeType] _onSessionProposal chains: $allChains');
final approved = await _bottomSheetHandler.queueBottomSheet(
widget: WCRequestWidget(
child: WCConnectionRequestWidget(
Expand Down
31 changes: 17 additions & 14 deletions example/wallet/lib/utils/namespace_model_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,28 @@ class ConnectionWidgetBuilder {
) {
final List<WCConnectionWidget> views = [];
for (final key in generatedNamespaces.keys) {
Namespace ns = generatedNamespaces[key]!;
final namespaces = generatedNamespaces[key]!;
final chains = NamespaceUtils.getChainsFromAccounts(namespaces.accounts);
final List<WCConnectionModel> models = [];
// If the chains property is present, add the chain data to the models
models.add(
WCConnectionModel(
title: StringConstants.chains,
elements: ns.accounts.map((acc) {
return NamespaceUtils.getChainFromAccount(acc);
}).toList(),
elements: chains,
),
);
models.add(
WCConnectionModel(
title: StringConstants.methods,
elements: namespaces.methods,
),
);
models.add(
WCConnectionModel(
title: StringConstants.events,
elements: namespaces.events,
),
);
models.add(WCConnectionModel(
title: StringConstants.methods,
elements: ns.methods,
));
models.add(WCConnectionModel(
title: StringConstants.events,
elements: ns.events,
));

views.add(
WCConnectionWidget(
Expand All @@ -48,12 +51,12 @@ class ConnectionWidgetBuilder {
) {
final List<WCConnectionWidget> views = [];
for (final key in namespaces.keys) {
final Namespace ns = namespaces[key]!;
final ns = namespaces[key]!;
final List<WCConnectionModel> models = [];
// If the chains property is present, add the chain data to the models
models.add(
WCConnectionModel(
title: StringConstants.chains,
title: StringConstants.accounts,
elements: ns.accounts,
),
);
Expand Down
1 change: 1 addition & 0 deletions example/wallet/lib/utils/string_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class StringConstants {

// Session Proposal
static const String chains = 'Chains';
static const String accounts = 'Accounts';
static const String methods = 'Methods';
static const String events = 'Events';

Expand Down
2 changes: 1 addition & 1 deletion lib/apis/core/relay_client/relay_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class RelayClient implements IRelayClient {
Future<void> _createJsonRPCProvider() async {
_connecting = true;
_active = true;
var auth = await core.crypto.signJWT(core.relayUrl);
final auth = await core.crypto.signJWT(core.relayUrl);
core.logger.t('Signed JWT: $auth');
try {
final url = WalletConnectUtils.formatRelayRpcUrl(
Expand Down
88 changes: 36 additions & 52 deletions lib/apis/sign_api/sign_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1273,64 +1273,48 @@ class SignEngine implements ISignEngine {
sessionRequest,
);

final String methodKey = _getRegisterKey(
final methodKey = _getRegisterKey(
request.chainId,
request.request.method,
);
// print('method key: $methodKey');
if (_methodHandlers.containsKey(methodKey)) {
final handler = _methodHandlers[methodKey];
if (handler != null) {
try {
final result = await handler(
topic,
request.request.params,
);
await core.pairing.sendResult(
payload.id,
topic,
MethodConstants.WC_SESSION_REQUEST,
result,
);
} on WalletConnectError catch (e) {
await core.pairing.sendError(
payload.id,
topic,
payload.method,
JsonRpcError.fromJson(
e.toJson(),
),
);
} on WalletConnectErrorSilent catch (_) {
// Do nothing on silent error
} catch (err) {
await core.pairing.sendError(
payload.id,
topic,
payload.method,
JsonRpcError.invalidParams(
err.toString(),
),
);
}

await _deletePendingRequest(payload.id);
// else, we send an onSessionRequest event
onSessionRequest.broadcast(
SessionRequestEvent.fromSessionRequest(
sessionRequest,
),
);

final methodHandler = _methodHandlers[methodKey];
if (methodHandler != null) {
// If a method handler has been set using registerRequestHandler we use it to process the request
try {
final result = await methodHandler(topic, request.request.params);
await core.pairing.sendResult(
payload.id,
topic,
MethodConstants.WC_SESSION_REQUEST,
result,
);
} on WalletConnectError catch (e) {
await core.pairing.sendError(
payload.id,
topic,
payload.method,
JsonRpcError.fromJson(e.toJson()),
);
} on WalletConnectErrorSilent catch (_) {
// Do nothing on silent error
} catch (err) {
await core.pairing.sendError(
payload.id,
topic,
payload.method,
JsonRpcError.invalidParams(err.toString()),
);
}

onSessionRequest.broadcast(
SessionRequestEvent.fromSessionRequest(
sessionRequest,
),
);
} else {
await core.pairing.sendError(
payload.id,
topic,
payload.method,
JsonRpcError.methodNotFound(
'No handler found for chainId:method -> $methodKey',
),
);
await _deletePendingRequest(payload.id);
}
} on WalletConnectError catch (err) {
await core.pairing.sendError(
Expand Down

0 comments on commit ef2bea5

Please sign in to comment.