diff --git a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing.dart b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing.dart index 8917b0e8..e27ed4a1 100644 --- a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing.dart +++ b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing.dart @@ -9,6 +9,10 @@ class SignMessageRequest required String rpcPass, required this.coin, required this.message, + this.derivationPath, + this.accountId, + this.chain, + this.addressId, }) : super(method: 'sign_message', rpcPass: rpcPass, mmrpc: RpcVersion.v2_0); /// The coin to sign a message with @@ -17,11 +21,42 @@ class SignMessageRequest /// The message you want to sign final String message; + /// Optional HD address selector: full derivation path + /// Example: m/84'/2'/0'/0/1 + final String? derivationPath; + + /// Optional HD address selector components + /// When provided together with [chain], [addressId] they form the BIP44 path + /// m/44'/COIN_ID'/accountId'/chain/addressId + final int? accountId; + + /// Optional HD address selector chain. Must be "Internal" or "External" if provided. + final String? chain; + + /// Optional HD address selector: address index within the chain + final int? addressId; + @override Map toJson() { - return super.toJson().deepMerge({ - 'params': {'coin': coin, 'message': message}, - }); + final params = { + 'coin': coin, + 'message': message, + }; + + // HD address selection (preferred nested under 'address') + final address = {}; + if (derivationPath != null && derivationPath!.isNotEmpty) { + address['derivation_path'] = derivationPath; + } else if (accountId != null && chain != null && addressId != null) { + address['account_id'] = accountId; + address['chain'] = chain; + address['address_id'] = addressId; + } + if (address.isNotEmpty) { + params['address'] = address; + } + + return super.toJson().deepMerge({'params': params}); } @override diff --git a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing_rpc_namespace.dart b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing_rpc_namespace.dart index db54993c..73111ff9 100644 --- a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing_rpc_namespace.dart +++ b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods/utility/message_signing_rpc_namespace.dart @@ -9,9 +9,21 @@ class MessageSigningMethodsNamespace extends BaseRpcMethodNamespace { Future signMessage({ required String coin, required String message, + String? derivationPath, + int? accountId, + String? chain, + int? addressId, }) { return execute( - SignMessageRequest(rpcPass: rpcPass ?? '', coin: coin, message: message), + SignMessageRequest( + rpcPass: rpcPass ?? '', + coin: coin, + message: message, + derivationPath: derivationPath, + accountId: accountId, + chain: chain, + addressId: addressId, + ), ); } diff --git a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods_library.dart b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods_library.dart index 0d8e5573..6e2b0e94 100644 --- a/packages/komodo_defi_rpc_methods/lib/src/rpc_methods_library.dart +++ b/packages/komodo_defi_rpc_methods/lib/src/rpc_methods_library.dart @@ -172,9 +172,21 @@ class UtilityMethods extends BaseRpcMethodNamespace { Future signMessage({ required String coin, required String message, + String? derivationPath, + int? accountId, + String? chain, + int? addressId, String? rpcPass, }) => execute( - SignMessageRequest(coin: coin, message: message, rpcPass: rpcPass ?? ''), + SignMessageRequest( + coin: coin, + message: message, + rpcPass: rpcPass ?? '', + derivationPath: derivationPath, + accountId: accountId, + chain: chain, + addressId: addressId, + ), ); /// Verifies a message signature diff --git a/packages/komodo_defi_sdk/example/lib/widgets/asset/asset_header_widget.dart b/packages/komodo_defi_sdk/example/lib/widgets/asset/asset_header_widget.dart index c54fd4ec..d9850b30 100644 --- a/packages/komodo_defi_sdk/example/lib/widgets/asset/asset_header_widget.dart +++ b/packages/komodo_defi_sdk/example/lib/widgets/asset/asset_header_widget.dart @@ -185,6 +185,7 @@ class _AssetHeaderWidgetState extends State { coin: widget.asset.id.id, message: message, address: widget.pubkeys!.keys.first.address, + derivationPath: widget.pubkeys!.keys.first.derivationPath, ); setState(() => _signedMessage = signature); } catch (e) { diff --git a/packages/komodo_defi_sdk/lib/src/message_signing/message_signing_manager.dart b/packages/komodo_defi_sdk/lib/src/message_signing/message_signing_manager.dart index c4a9f658..691953b4 100644 --- a/packages/komodo_defi_sdk/lib/src/message_signing/message_signing_manager.dart +++ b/packages/komodo_defi_sdk/lib/src/message_signing/message_signing_manager.dart @@ -17,9 +17,9 @@ class MessageSigningManager { /// This method creates a cryptographic signature that can be used to prove /// ownership of an address. /// - /// The `address` parameter is not used in the signing process and will be - /// ignored. This is in preparation for the near future when KDF will add HD - /// wallet support. + /// For HD wallets, you can optionally pass a specific derivation to sign + /// from using either a full `derivationPath` (preferred) or the + /// `accountId`/`chain`/`addressId` components. /// /// Parameters: /// - [coin]: The ticker of the coin to use for signing (e.g., "BTC"). @@ -39,10 +39,18 @@ class MessageSigningManager { required String coin, required String message, required String address, + String? derivationPath, + int? accountId, + String? chain, + int? addressId, }) async { final response = await _client.rpc.utility.signMessage( coin: coin, message: message, + derivationPath: derivationPath, + accountId: accountId, + chain: chain, + addressId: addressId, ); return response.signature; }