Skip to content

Commit 2efa895

Browse files
authored
Merge pull request #54 from coderofstuff/resupport-derivation-paths
Allow generating the xpub for root node
2 parents f4abd89 + 0c44680 commit 2efa895

5 files changed

Lines changed: 17 additions & 19 deletions

File tree

doc/COMMANDS.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,21 @@ Raw response looks like: `4b617370619000`
4747
| --- | --- | --- | --- | --- | --- |
4848
| 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)` |
4949

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

5256
| CData Part | Description |
5357
| --- | --- |
5458
| `purpose` | Must be `44'` or `80000002c` |
5559
| `coin_type` | Must be `111111'` or `8001b207` |
56-
| `account` | Current wallets all use `80000000` for `0'` for default account but any value is accepted |
57-
| `type` | Either `00000000` for Receive Address or `00000001` for Change Address |
58-
| `index` | Any value from `00000000` to `11111111` |
60+
| `account` | Current wallets all use `80000000` (aka. `0'`) for default account but any value from `00000000` to `11111111` is accepted if passed |
61+
| `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 |
62+
| `index` | Any value from `00000000` to `11111111` if passed |
63+
64+
If you want to generate addresses using a root public key,
5965

6066
### Response
6167

@@ -171,8 +177,7 @@ Transactions signed with ECDSA are currently not supported.
171177
| 0xB008 | `SW_SIGNATURE_FAIL` | Signature of raw transaction failed |
172178
| 0xB009 | `SW_WRONG_BIP32_PURPOSE` | `Purpose` must be `44'` |
173179
| 0xB00A | `SW_WRONG_BIP32_COIN_TYPE` | `Coin Type` must be `111111'` |
174-
| 0xB00B | `SW_WRONG_BIP32_TYPE` | `Type` passed is not valid. Must be either `0` for `Receive` or `1` for `Change`|
175-
| 0xB00C | `SW_WRONG_BIP32_PATH_LEN` | Path length must be `5` |
180+
| 0xB00B | `SW_WRONG_BIP32_PATH_LEN` | Path length must be `5` |
176181
| 0xB010 | `SW_MESSAGE_PARSING_FAIL` | Unable to parse message data |
177182
| 0xB011 | `SW_MESSAGE_TOO_LONG` | Message len greater than max |
178183
| 0xB012 | `SW_MESSAGE_TOO_SHORT` | Message len is 0 |

src/handler/get_public_key.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ int handler_get_public_key(buffer_t *cdata, bool display) {
5151
return io_send_sw(SW_WRONG_DATA_LENGTH);
5252
}
5353

54-
if (G_context.bip32_path_len != 5) {
54+
if (G_context.bip32_path_len < 2 || G_context.bip32_path_len > 5) {
5555
return io_send_sw(SW_WRONG_BIP32_PATH_LEN);
5656
}
5757

@@ -63,11 +63,6 @@ int handler_get_public_key(buffer_t *cdata, bool display) {
6363
return io_send_sw(SW_WRONG_BIP32_COIN_TYPE);
6464
}
6565

66-
if (G_context.bip32_path[3] != (uint32_t) RECEIVE &&
67-
G_context.bip32_path[3] != (uint32_t) CHANGE) {
68-
return io_send_sw(SW_WRONG_BIP32_TYPE);
69-
}
70-
7166
int error = bip32_derive_get_pubkey_256(CX_CURVE_256K1,
7267
G_context.bip32_path,
7368
G_context.bip32_path_len,

src/sw.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@
8686

8787
#define SW_WRONG_BIP32_PURPOSE 0xB009
8888
#define SW_WRONG_BIP32_COIN_TYPE 0xB00A
89-
#define SW_WRONG_BIP32_TYPE 0xB00B
90-
#define SW_WRONG_BIP32_PATH_LEN 0xB00C
89+
#define SW_WRONG_BIP32_PATH_LEN 0xB00B
9190
#define SW_MESSAGE_PARSING_FAIL 0xB010
9291
#define SW_MESSAGE_TOO_LONG 0xB011
9392
#define SW_MESSAGE_TOO_SHORT 0xB012

tests/application_client/kaspa_command_sender.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ class Errors(IntEnum):
5454
SW_SIGNATURE_FAIL = 0xB008
5555
SW_WRONG_BIP32_PURPOSE = 0xB009
5656
SW_WRONG_BIP32_COIN_TYPE = 0xB00A
57-
SW_WRONG_BIP32_TYPE = 0xB00B
58-
SW_WRONG_BIP32_PATH_LEN = 0xB00C
57+
SW_WRONG_BIP32_PATH_LEN = 0xB00B
5958
SW_MESSAGE_PARSING_FAIL = 0xB010
6059
SW_MESSAGE_TOO_LONG = 0xB011
6160
SW_MESSAGE_TOO_SHORT = 0xB012

tests/test_pubkey_cmd.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# GET_PUBLIC_KEY works for valid cases in non-confirmation mode
1010
def test_get_public_key_no_confirm_valid(backend):
11-
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"]:
11+
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'"]:
1212
client = KaspaCommandSender(backend)
1313
response = client.get_public_key(path=path).data
1414
_, public_key, _, chain_code = unpack_get_public_key_response(response)
@@ -24,8 +24,8 @@ def test_get_public_key_no_confirm_invalid(backend):
2424
for test_case in [
2525
("m/33'/0'/0'/0/0", Errors.SW_WRONG_BIP32_PURPOSE),
2626
("m/44'/0'/0/0/0", Errors.SW_WRONG_BIP32_COIN_TYPE),
27-
("m/44'/111111'/911'/3/0", Errors.SW_WRONG_BIP32_TYPE),
28-
("m/44'/111111'/2147483647/0", Errors.SW_WRONG_BIP32_PATH_LEN)
27+
("m/44'", Errors.SW_WRONG_BIP32_PATH_LEN),
28+
("m/44'/111111'/2147483647/0/0/0", Errors.SW_WRONG_BIP32_PATH_LEN)
2929
]:
3030
client = KaspaCommandSender(backend)
3131

0 commit comments

Comments
 (0)