Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<String, dynamic> toJson() {
return super.toJson().deepMerge({
'params': {'coin': coin, 'message': message},
});
final params = <String, dynamic>{
'coin': coin,
'message': message,
};

// HD address selection (preferred nested under 'address')
final address = <String, dynamic>{};
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ class MessageSigningMethodsNamespace extends BaseRpcMethodNamespace {
Future<SignMessageResponse> 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,
),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,21 @@ class UtilityMethods extends BaseRpcMethodNamespace {
Future<SignMessageResponse> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class _AssetHeaderWidgetState extends State<AssetHeaderWidget> {
coin: widget.asset.id.id,
message: message,
address: widget.pubkeys!.keys.first.address,
derivationPath: widget.pubkeys!.keys.first.derivationPath,
);
setState(() => _signedMessage = signature);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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").
Expand All @@ -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;
}
Expand Down
Loading