Skip to content

Commit

Permalink
Merge pull request #269 from WalletConnect/bugfix/proper_usage_on_ses…
Browse files Browse the repository at this point in the history
…sion_request

Fix Sign Engines's session request logic
  • Loading branch information
quetool committed Feb 23, 2024
2 parents 8660262 + ed45b49 commit 40a593a
Show file tree
Hide file tree
Showing 23 changed files with 230 additions and 198 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.2.1

- [Wallet] Fixed and issue where Sign Engine was not properly deciding between using a registered request handler or emitting an onSessionRequest event.

## 2.2.0

- Added Smart Contract interactions to SignEngine
Expand Down
12 changes: 6 additions & 6 deletions example/dapp/lib/utils/crypto/eip155.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ class EIP155 {
topic: topic,
chainId: chainData.chainId,
address: address,
data: testSignData,
message: testSignData,
);
case EIP155Methods.ethSign:
return ethSign(
web3App: web3App,
topic: topic,
chainId: chainData.chainId,
address: address,
data: testSignData,
message: testSignData,
);
case EIP155Methods.ethSignTypedData:
return ethSignTypedData(
Expand Down Expand Up @@ -159,14 +159,14 @@ class EIP155 {
required String topic,
required String chainId,
required String address,
required String data,
required String message,
}) async {
return await web3App.request(
topic: topic,
chainId: chainId,
request: SessionRequestParams(
method: methods[EIP155Methods.personalSign]!,
params: [data, address],
params: [message, address],
),
);
}
Expand All @@ -176,14 +176,14 @@ class EIP155 {
required String topic,
required String chainId,
required String address,
required String data,
required String message,
}) async {
return await web3App.request(
topic: topic,
chainId: chainId,
request: SessionRequestParams(
method: methods[EIP155Methods.ethSign]!,
params: [address, data],
params: [address, message],
),
);
}
Expand Down
32 changes: 19 additions & 13 deletions example/dapp/lib/widgets/session_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class SessionWidgetState extends State<SessionWidget> {
final List<Widget> buttons = [];
// Add Methods
for (final String method in getChainMethods(chainMetadata.type)) {
final namespaces = widget.session.namespaces[chainMetadata.type.name];
final supported = namespaces?.methods.contains(method) ?? false;
buttons.add(
Container(
width: double.infinity,
Expand All @@ -175,20 +177,24 @@ class SessionWidgetState extends State<SessionWidget> {
vertical: StyleConstants.linear8,
),
child: ElevatedButton(
onPressed: () async {
final future = EIP155.callMethod(
web3App: widget.web3App,
topic: widget.session.topic,
method: method.toEip155Method()!,
chainData: chainMetadata,
address: address.toLowerCase(),
);
MethodDialog.show(context, method, future);
_launchWallet();
},
onPressed: supported
? () async {
final future = EIP155.callMethod(
web3App: widget.web3App,
topic: widget.session.topic,
method: method.toEip155Method()!,
chainData: chainMetadata,
address: address.toLowerCase(),
);
MethodDialog.show(context, method, future);
_launchWallet();
}
: null,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
chainMetadata.color,
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(states) => states.contains(MaterialState.disabled)
? Colors.grey
: chainMetadata.color,
),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
Expand Down
79 changes: 43 additions & 36 deletions example/wallet/lib/dependencies/chains/evm_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,59 @@ 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 EventsConstants.requiredEvents) {
_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?.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 +124,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 +169,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 +210,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 @@ -242,16 +249,16 @@ class EVMService {
);
}

Future<dynamic> ethSignTransaction(String topic, dynamic parameters) async {
Future<void> 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 @@ -295,16 +302,16 @@ class EVMService {
);
}

Future<dynamic> ethSendTransaction(String topic, dynamic parameters) async {
Future<void> 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
35 changes: 29 additions & 6 deletions example/wallet/lib/dependencies/web3wallet_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:walletconnect_flutter_v2_wallet/dependencies/deep_link_handler.d
import 'package:walletconnect_flutter_v2_wallet/dependencies/i_web3wallet_service.dart';
import 'package:walletconnect_flutter_v2_wallet/dependencies/key_service/chain_key.dart';
import 'package:walletconnect_flutter_v2_wallet/dependencies/key_service/i_key_service.dart';
import 'package:walletconnect_flutter_v2_wallet/models/chain_metadata.dart';
import 'package:walletconnect_flutter_v2_wallet/utils/constants.dart';
import 'package:walletconnect_flutter_v2_wallet/utils/dart_defines.dart';
import 'package:walletconnect_flutter_v2_wallet/widgets/wc_connection_request/wc_auth_request_model.dart';
Expand Down Expand Up @@ -165,14 +166,38 @@ class Web3WalletService extends IWeb3WalletService {
}
}

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,
],
);
return constructedNS;
}

void _onSessionProposal(SessionProposalEvent? args) async {
if (args != null) {
// generatedNamespaces is constructed based on registered methods handlers
// so if you want to handle requests using onSessionRequest event then you would need to manually add that method in the approved namespaces
final approvedNS = _generateNamespaces(
args.params.generatedNamespaces!,
ChainType.eip155,
);
final proposalData = args.params.copyWith(
generatedNamespaces: approvedNS,
);
final approved = await _bottomSheetHandler.queueBottomSheet(
widget: WCRequestWidget(
child: WCConnectionRequestWidget(
wallet: _web3Wallet!,
sessionProposal: WCSessionRequestModel(
request: args.params,
request: proposalData,
verifyContext: args.verifyContext,
),
),
Expand All @@ -182,7 +207,7 @@ class Web3WalletService extends IWeb3WalletService {
if (approved == true) {
_web3Wallet!.approveSession(
id: args.id,
namespaces: args.params.generatedNamespaces!,
namespaces: approvedNS,
);
final scheme = args.params.proposer.metadata.redirect?.native ?? '';
DeepLinkHandler.goTo(scheme, delay: 300);
Expand Down Expand Up @@ -217,11 +242,9 @@ class Web3WalletService extends IWeb3WalletService {

Future<void> _onAuthRequest(AuthRequest? args) async {
if (args != null) {
List<ChainKey> chainKeys = GetIt.I<IKeyService>().getKeysForChain(
'eip155:1',
);
final chainKeys = GetIt.I<IKeyService>().getKeysForChain('eip155:1');
// Create the message to be signed
final String iss = 'did:pkh:eip155:1:${chainKeys.first.address}';
final iss = 'did:pkh:eip155:1:${chainKeys.first.address}';

final bool? auth = await _bottomSheetHandler.queueBottomSheet(
widget: WCRequestWidget(
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
Loading

0 comments on commit 40a593a

Please sign in to comment.