From 0c44680b35b318b5bb4eb2049c85022fe712087c Mon Sep 17 00:00:00 2001 From: coderofstuff <114628839+coderofstuff@users.noreply.github.com> Date: Sat, 14 Oct 2023 23:30:50 -0600 Subject: [PATCH] Allow generating the xpub for root node --- doc/COMMANDS.md | 17 +++++++++++------ src/handler/get_public_key.c | 7 +------ src/sw.h | 3 +-- .../application_client/kaspa_command_sender.py | 3 +-- tests/test_pubkey_cmd.py | 6 +++--- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index 0aa991c..ef049a2 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -47,15 +47,21 @@ Raw response looks like: `4b617370619000` | --- | --- | --- | --- | --- | --- | | 0xE0 | 0x05 | 0x00 (no display)
0x01 (display) | 0x00 | 0x15 | `path len (1 byte)` \|\|
`purpose (4 bytes)` \|\|
`coin_type (4 bytes)` \|\|
`account (4 bytes)` \|\|
`type (4 bytes)` \|\|
`index (4 bytes)` | -Keys for kaspa use the derivation path `m/44'/111111'/'//`. +Keys for kaspa normally use the derivation path `m/44'/111111'/'//`. This command will accept these as inputs: +- `m/44'/111111'` +- `m/44'/111111'/'` +- `m/44'/111111'/'/` +- `m/44'/111111'/'//` | CData Part | Description | | --- | --- | | `purpose` | Must be `44'` or `80000002c` | | `coin_type` | Must be `111111'` or `8001b207` | -| `account` | Current wallets all use `80000000` for `0'` for default account but any value is accepted | -| `type` | Either `00000000` for Receive Address or `00000001` for Change Address | -| `index` | Any value from `00000000` to `11111111` | +| `account` | Current wallets all use `80000000` (aka. `0'`) for default account but any value from `00000000` to `11111111` is accepted if passed | +| `type` | Current wallets use either `00000000` for Receive Address or `00000001` for Change Address, but any value from `00000000` to `11111111` is accepted if passed | +| `index` | Any value from `00000000` to `11111111` if passed | + +If you want to generate addresses using a root public key, ### Response @@ -171,8 +177,7 @@ Transactions signed with ECDSA are currently not supported. | 0xB008 | `SW_SIGNATURE_FAIL` | Signature of raw transaction failed | | 0xB009 | `SW_WRONG_BIP32_PURPOSE` | `Purpose` must be `44'` | | 0xB00A | `SW_WRONG_BIP32_COIN_TYPE` | `Coin Type` must be `111111'` | -| 0xB00B | `SW_WRONG_BIP32_TYPE` | `Type` passed is not valid. Must be either `0` for `Receive` or `1` for `Change`| -| 0xB00C | `SW_WRONG_BIP32_PATH_LEN` | Path length must be `5` | +| 0xB00B | `SW_WRONG_BIP32_PATH_LEN` | Path length must be `5` | | 0xB010 | `SW_MESSAGE_PARSING_FAIL` | Unable to parse message data | | 0xB011 | `SW_MESSAGE_TOO_LONG` | Message len greater than max | | 0xB012 | `SW_MESSAGE_TOO_SHORT` | Message len is 0 | diff --git a/src/handler/get_public_key.c b/src/handler/get_public_key.c index fd574eb..f559efb 100644 --- a/src/handler/get_public_key.c +++ b/src/handler/get_public_key.c @@ -51,7 +51,7 @@ int handler_get_public_key(buffer_t *cdata, bool display) { return io_send_sw(SW_WRONG_DATA_LENGTH); } - if (G_context.bip32_path_len != 5) { + if (G_context.bip32_path_len < 2 || G_context.bip32_path_len > 5) { return io_send_sw(SW_WRONG_BIP32_PATH_LEN); } @@ -63,11 +63,6 @@ int handler_get_public_key(buffer_t *cdata, bool display) { return io_send_sw(SW_WRONG_BIP32_COIN_TYPE); } - if (G_context.bip32_path[3] != (uint32_t) RECEIVE && - G_context.bip32_path[3] != (uint32_t) CHANGE) { - return io_send_sw(SW_WRONG_BIP32_TYPE); - } - int error = bip32_derive_get_pubkey_256(CX_CURVE_256K1, G_context.bip32_path, G_context.bip32_path_len, diff --git a/src/sw.h b/src/sw.h index a60be47..7adffdf 100644 --- a/src/sw.h +++ b/src/sw.h @@ -86,8 +86,7 @@ #define SW_WRONG_BIP32_PURPOSE 0xB009 #define SW_WRONG_BIP32_COIN_TYPE 0xB00A -#define SW_WRONG_BIP32_TYPE 0xB00B -#define SW_WRONG_BIP32_PATH_LEN 0xB00C +#define SW_WRONG_BIP32_PATH_LEN 0xB00B #define SW_MESSAGE_PARSING_FAIL 0xB010 #define SW_MESSAGE_TOO_LONG 0xB011 #define SW_MESSAGE_TOO_SHORT 0xB012 diff --git a/tests/application_client/kaspa_command_sender.py b/tests/application_client/kaspa_command_sender.py index e5af126..c6abd06 100644 --- a/tests/application_client/kaspa_command_sender.py +++ b/tests/application_client/kaspa_command_sender.py @@ -54,8 +54,7 @@ class Errors(IntEnum): SW_SIGNATURE_FAIL = 0xB008 SW_WRONG_BIP32_PURPOSE = 0xB009 SW_WRONG_BIP32_COIN_TYPE = 0xB00A - SW_WRONG_BIP32_TYPE = 0xB00B - SW_WRONG_BIP32_PATH_LEN = 0xB00C + SW_WRONG_BIP32_PATH_LEN = 0xB00B SW_MESSAGE_PARSING_FAIL = 0xB010 SW_MESSAGE_TOO_LONG = 0xB011 SW_MESSAGE_TOO_SHORT = 0xB012 diff --git a/tests/test_pubkey_cmd.py b/tests/test_pubkey_cmd.py index c9809c4..d1d56bf 100644 --- a/tests/test_pubkey_cmd.py +++ b/tests/test_pubkey_cmd.py @@ -8,7 +8,7 @@ # GET_PUBLIC_KEY works for valid cases in non-confirmation mode def test_get_public_key_no_confirm_valid(backend): - for path in ["m/44'/111111'/0'/0/0", "m/44'/111111'/0/0/0", "m/44'/111111'/911'/0/0", "m/44'/111111'/0/1/255", "m/44'/111111'/2147483647/0/0"]: + for path in ["m/44'/111111'/0'/0/0", "m/44'/111111'/0/0/0", "m/44'/111111'/911'/0/0", "m/44'/111111'/0/1/255", "m/44'/111111'/2147483647/0/0", "m/44'/111111'/0'/0/0", "m/44'/111111'/911'/3/0", "m/44'/111111'"]: client = KaspaCommandSender(backend) response = client.get_public_key(path=path).data _, public_key, _, chain_code = unpack_get_public_key_response(response) @@ -24,8 +24,8 @@ def test_get_public_key_no_confirm_invalid(backend): for test_case in [ ("m/33'/0'/0'/0/0", Errors.SW_WRONG_BIP32_PURPOSE), ("m/44'/0'/0/0/0", Errors.SW_WRONG_BIP32_COIN_TYPE), - ("m/44'/111111'/911'/3/0", Errors.SW_WRONG_BIP32_TYPE), - ("m/44'/111111'/2147483647/0", Errors.SW_WRONG_BIP32_PATH_LEN) + ("m/44'", Errors.SW_WRONG_BIP32_PATH_LEN), + ("m/44'/111111'/2147483647/0/0/0", Errors.SW_WRONG_BIP32_PATH_LEN) ]: client = KaspaCommandSender(backend)