Skip to content

Commit

Permalink
Allow generating the xpub for root node
Browse files Browse the repository at this point in the history
  • Loading branch information
coderofstuff committed Oct 15, 2023
1 parent f4abd89 commit 0c44680
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 19 deletions.
17 changes: 11 additions & 6 deletions doc/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,21 @@ Raw response looks like: `4b617370619000`
| --- | --- | --- | --- | --- | --- |
| 0xE0 | 0x05 | 0x00 (no display) <br> 0x01 (display) | 0x00 | 0x15 | `path len (1 byte)` \|\|<br>`purpose (4 bytes)` \|\|<br> `coin_type (4 bytes)` \|\|<br> `account (4 bytes)` \|\|<br> `type (4 bytes)` \|\|<br>`index (4 bytes)` |

Keys for kaspa use the derivation path `m/44'/111111'/<account>'/<type>/<index>`.
Keys for kaspa normally use the derivation path `m/44'/111111'/<account>'/<type>/<index>`. This command will accept these as inputs:
- `m/44'/111111'`
- `m/44'/111111'/<account>'`
- `m/44'/111111'/<account>'/<type>`
- `m/44'/111111'/<account>'/<type>/<index>`

| 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

Expand Down Expand Up @@ -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 |
Expand Down
7 changes: 1 addition & 6 deletions src/handler/get_public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions src/sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions tests/application_client/kaspa_command_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions tests/test_pubkey_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

Expand Down

0 comments on commit 0c44680

Please sign in to comment.