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
14 changes: 12 additions & 2 deletions src/core/transport/apdu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ function assertBytes(value: Uint8Array, length: number, label: string): void {
/**
* Build GET_PUBLIC_KEY APDU.
* Returns the BabyJubjub spending public key (x, y).
*
* P1 is `0x01` (display + confirm): the RAILGUN app shows the account index and
* pubkey hex and returns the 64-byte key only on Approve (Reject → `0x6985`).
* Production firmware rejects `P1 = 0x00` (`SW_WRONG_P1P2`), so this always
* requires an on-device tap.
* @param account - Account index (default 0).
* @param profile - APDU profile (default RAILGUN_PROFILE).
*/
Expand All @@ -224,7 +229,7 @@ export function buildGetPublicKey(
return {
cla: profile.cla,
ins: profile.commands.getPublicKey.ins,
p1: 0,
p1: 0x01,
p2: 0,
data: encodeAccountIndex(account),
};
Expand Down Expand Up @@ -262,9 +267,14 @@ export function buildSignHash(
}

/**
* Build GET_VIEWING_KEY APDU.
* Build GET_VIEWING_KEY APDU (VIEWING_PRIVKEY, INS 0x13).
* Returns the viewing private key — 32 bytes.
* Device displays a confirmation prompt.
*
* P1 stays `0x00` here: unlike the *public* key commands (spending pubkey 0x01,
* viewing pubkey 0x10), the viewing-privkey export uses `P1 = 0x00` — the app
* already gates it behind an on-device confirmation. `P1 = 0x01` would return
* `SW_WRONG_P1P2`.
* @param account - Account index (default 0).
* @param profile - APDU profile (default RAILGUN_PROFILE).
*/
Expand Down
4 changes: 4 additions & 0 deletions test/unit/public-api-smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ describe('public API smoke tests', () => {
const cmd = buildGetPublicKey();
expect(cmd.cla).toBe(RAILGUN_CLA);
expect(cmd.ins).toBe(RailgunAppINS.GET_PUBLIC_KEY);
// P1 = 0x01 (display + confirm); production firmware rejects P1 = 0x00.
expect(cmd.p1).toBe(0x01);
// Default account 0 → 4 bytes big-endian
expect(cmd.data).toEqual(new Uint8Array([0, 0, 0, 0]));
});
Expand All @@ -77,6 +79,8 @@ describe('public API smoke tests', () => {
const cmd = buildGetViewingKey();
expect(cmd.cla).toBe(RAILGUN_CLA);
expect(cmd.ins).toBe(RailgunAppINS.GET_VIEWING_KEY);
// Viewing-privkey export stays P1 = 0x00 (unlike the public-key commands).
expect(cmd.p1).toBe(0x00);
expect(cmd.data).toEqual(new Uint8Array([0, 0, 0, 0]));
});

Expand Down
Loading