@onekeyfe/hwk-trezor-core 1.1.27-alpha.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @onekeyfe/hwk-trezor-core
2
+
3
+ Minimal Trezor message call layer for Hardware Wallet Kit.
4
+
5
+ This package owns protobuf message encoding, transport framing, chunked writes, and response decoding. It does not depend on Trezor Connect or Connect Mobile.
@@ -0,0 +1,239 @@
1
+ interface TrezorByteTransport {
2
+ write(chunk: Buffer, signal?: AbortSignal): Promise<void>;
3
+ read(signal?: AbortSignal): Promise<Buffer>;
4
+ }
5
+ interface TrezorTransportProtocol {
6
+ name: 'bridge' | 'v1' | 'v2';
7
+ encode(data: Buffer, options: {
8
+ messageType: number;
9
+ header?: Buffer;
10
+ }): Buffer;
11
+ decode(bytes: Buffer): {
12
+ header: Buffer;
13
+ length: number;
14
+ messageType: number;
15
+ payload: Buffer;
16
+ };
17
+ getHeaders(data: Buffer): [header: Buffer, chunkHeader: Buffer];
18
+ }
19
+ type TrezorThpState = {
20
+ readonly sendNonce?: number;
21
+ sync(direction: 'send' | 'recv', messageName: string): void;
22
+ };
23
+ type TrezorMessageName = string;
24
+ type TrezorMessageResponse<T extends string = string> = {
25
+ type: T;
26
+ message: Record<string, unknown>;
27
+ };
28
+ type TrezorCoreOptions = {
29
+ transport: TrezorByteTransport;
30
+ protocol?: TrezorTransportProtocol;
31
+ chunkSize?: number;
32
+ logger?: TrezorDebugLogger;
33
+ };
34
+ type TrezorCallOptions = {
35
+ signal?: AbortSignal;
36
+ thpState?: TrezorThpState;
37
+ };
38
+ type TrezorThpRawTransport = {
39
+ write?(connectId: string, data: Uint8Array): Promise<void>;
40
+ read?(connectId: string, timeoutMs?: number): Promise<Uint8Array | undefined>;
41
+ };
42
+ type TrezorThpCallParams = {
43
+ messageName: string;
44
+ data?: Record<string, unknown>;
45
+ skipAck?: boolean;
46
+ };
47
+ type TrezorDebugLogLevel = 'debug' | 'info' | 'warn' | 'error';
48
+ type TrezorDebugLogEntry = {
49
+ level: TrezorDebugLogLevel;
50
+ scope: string;
51
+ event: string;
52
+ data?: Record<string, unknown>;
53
+ };
54
+ type TrezorDebugLogger = (entry: TrezorDebugLogEntry) => void;
55
+ declare class TrezorFailureError extends Error {
56
+ readonly code?: unknown;
57
+ readonly response: TrezorMessageResponse<'Failure'>;
58
+ constructor(response: TrezorMessageResponse<'Failure'>);
59
+ }
60
+ declare class TrezorCore {
61
+ private readonly transport;
62
+ private readonly protocol;
63
+ private readonly chunkSize;
64
+ private readonly logger?;
65
+ constructor({ transport, protocol, chunkSize, logger }: TrezorCoreOptions);
66
+ call(name: TrezorMessageName, data?: Record<string, unknown>, options?: TrezorCallOptions): Promise<TrezorMessageResponse>;
67
+ private thpLoopLogger;
68
+ }
69
+ declare class TrezorThpProtocol {
70
+ private readonly thpState;
71
+ constructor();
72
+ encode({ messageName, data }: TrezorThpCallParams): Uint8Array;
73
+ call(transport: TrezorThpRawTransport, connectId: string, params: TrezorThpCallParams): Promise<TrezorMessageResponse>;
74
+ private applyReceivedState;
75
+ }
76
+ type TrezorCoreLike = {
77
+ call(name: string, data?: Record<string, unknown>, options?: TrezorCallOptions): Promise<TrezorMessageResponse>;
78
+ };
79
+ type TrezorCoreFactory = (transport: TrezorByteTransport, protocol: TrezorTransportProtocol, chunkSize: number, logger?: TrezorDebugLogger) => TrezorCoreLike;
80
+ type TrezorSessionProtocol = 'v1' | 'thp';
81
+ type TrezorDeviceSessionOptions = {
82
+ transport: TrezorByteTransport;
83
+ connectionType?: string;
84
+ chunkSize?: number;
85
+ coreFactory?: TrezorCoreFactory;
86
+ initializedState?: {
87
+ protocol: TrezorSessionProtocol;
88
+ features: Record<string, unknown>;
89
+ thpState?: TrezorThpState;
90
+ };
91
+ thp?: TrezorThpSessionOptions;
92
+ };
93
+ type TrezorThpPairingMethod = number | 'CodeEntry' | 'QrCode' | 'NFC' | 'SkipPairing';
94
+ type TrezorThpCredentials = Record<string, unknown> & {
95
+ host_static_key?: string;
96
+ autoconnect?: boolean;
97
+ };
98
+ type TrezorThpHandshakeInitResponse = Record<string, unknown>;
99
+ type TrezorPinMatrixRequestPayload = Record<string, unknown> & {
100
+ type?: string;
101
+ };
102
+ type TrezorThpHandshakeCredentials = {
103
+ pairingMethods: number[];
104
+ handshakeHash: Buffer;
105
+ handshakeCommitment?: Buffer;
106
+ codeEntryChallenge?: Buffer;
107
+ trezorEncryptedStaticPubkey: Buffer;
108
+ hostEncryptedStaticPubkey: Buffer;
109
+ staticKey: Buffer;
110
+ hostStaticPublicKey?: Buffer;
111
+ hostKey: Buffer;
112
+ trezorKey: Buffer;
113
+ trezorCpacePublicKey?: Buffer;
114
+ };
115
+ type TrezorThpHandshakeInitHandler = (args: {
116
+ handshakeInitResponse: TrezorThpHandshakeInitResponse;
117
+ thpState: TrezorThpState;
118
+ knownCredentials: TrezorThpCredentials[];
119
+ hostEphemeralKeys: {
120
+ privateKey: Buffer;
121
+ publicKey: Buffer;
122
+ };
123
+ tryToUnlock: 0 | 1;
124
+ protobufEncoder: (name: string, data: Record<string, unknown>) => {
125
+ message: Buffer;
126
+ };
127
+ }) => {
128
+ trezorMaskedStaticPubkey: Buffer;
129
+ trezorEncryptedStaticPubkey: Buffer;
130
+ hostEncryptedStaticPubkey: Buffer;
131
+ hostKey: Buffer;
132
+ trezorKey: Buffer;
133
+ handshakeHash: Buffer;
134
+ credentials?: TrezorThpCredentials;
135
+ allCredentials: TrezorThpCredentials[];
136
+ encryptedPayload: Buffer;
137
+ staticKey: Buffer;
138
+ hostStaticKeys: {
139
+ privateKey: Buffer;
140
+ publicKey: Buffer;
141
+ };
142
+ };
143
+ type TrezorThpPairingResponse = {
144
+ selectedMethod: TrezorThpPairingMethod;
145
+ } | {
146
+ tag: string;
147
+ };
148
+ type TrezorThpSessionOptions = {
149
+ hostName?: string;
150
+ appName?: string;
151
+ pairingMethods?: TrezorThpPairingMethod[];
152
+ knownCredentials?: TrezorThpCredentials[];
153
+ randomBytes?: (size: number) => Buffer;
154
+ handleHandshakeInit?: TrezorThpHandshakeInitHandler;
155
+ onPairingRequest?: (payload: {
156
+ availableMethods: number[];
157
+ selectedMethod: number;
158
+ nfcData?: string;
159
+ }) => Promise<TrezorThpPairingResponse>;
160
+ onButtonRequest?: (payload: Record<string, unknown>) => Promise<void> | void;
161
+ onPinMatrixRequest?: (payload: TrezorPinMatrixRequestPayload) => Promise<string> | string;
162
+ /**
163
+ * Provide the passphrase for a session. Called at two points depending on
164
+ * protocol — proactively before `ThpCreateNewSession` (THP), reactively on
165
+ * a `PassphraseRequest` (v1). Return `{ on_device: true }` to enter the
166
+ * passphrase on the device instead of sending a value. Empty string = the
167
+ * standard (no-passphrase) wallet.
168
+ */
169
+ onPassphraseRequest?: (payload?: Record<string, unknown>) => Promise<{
170
+ passphrase?: string;
171
+ on_device?: boolean;
172
+ }> | {
173
+ passphrase?: string;
174
+ on_device?: boolean;
175
+ };
176
+ /**
177
+ * Invoked after the THP handshake mints fresh pairing credentials (i.e.
178
+ * the first successful pairing run after a wipe / new device). The host
179
+ * should persist the full `credentials` list keyed by `deviceId` and feed
180
+ * it back via `knownCredentials` on the next connect to skip pairing UX.
181
+ */
182
+ onPairingCredentialsChanged?: (payload: {
183
+ credentials: TrezorThpCredentials[];
184
+ }) => Promise<void> | void;
185
+ logger?: TrezorDebugLogger;
186
+ };
187
+ declare class TrezorDeviceSession {
188
+ private readonly transport;
189
+ private readonly connectionType?;
190
+ private readonly chunkSize;
191
+ private readonly coreFactory;
192
+ private readonly thpOptions?;
193
+ private core?;
194
+ private protocol;
195
+ private thpState?;
196
+ private thpAppSessionActive;
197
+ private currentFeatures?;
198
+ constructor(options: TrezorDeviceSessionOptions);
199
+ get features(): Record<string, unknown> | undefined;
200
+ /**
201
+ * Whether this device speaks THP (v2). THP supports multiple host-managed
202
+ * application sessions per channel (passphrase sessions); v1 does not — its
203
+ * passphrase flow is reactive (device-driven `PassphraseRequest`). The
204
+ * adapter branches on this to decide whether to drive app-session caching.
205
+ */
206
+ get isThp(): boolean;
207
+ getThpState(): TrezorThpState | undefined;
208
+ initialize(): Promise<Record<string, unknown>>;
209
+ call(name: string, data?: Record<string, unknown>): Promise<{
210
+ type: string;
211
+ message: Record<string, unknown>;
212
+ }>;
213
+ private initializeThp;
214
+ /**
215
+ * Create a NEW THP application session with a freshly-prompted passphrase
216
+ * (or empty if the device has no passphrase protection). Returns the new
217
+ * session id (hex). The session knows nothing about wallet identity (XFP) —
218
+ * the adapter derives that (via master fingerprint) and owns the
219
+ * XFP↔sessionId map. Multiple sessions can coexist on one channel.
220
+ */
221
+ createThpAppSession(deriveCardano?: boolean): Promise<string>;
222
+ /**
223
+ * Switch the active THP session to an existing id (host-side: just sets the
224
+ * session-id byte in the next message header). The device must still hold
225
+ * the session — validity is verified by the caller's next real call (an
226
+ * evicted session surfaces as a Failure/ThpError, the adapter then recreates).
227
+ */
228
+ selectThpAppSession(sessionId: string): void;
229
+ /** Active THP session id (hex), or undefined if none created/selected. */
230
+ getThpAppSessionId(): string | undefined;
231
+ private ensureThpApplicationSession;
232
+ private handleButtonRequest;
233
+ private handlePinMatrixRequest;
234
+ private handlePassphraseRequest;
235
+ private cancelCurrentCall;
236
+ private log;
237
+ }
238
+
239
+ export { type TrezorByteTransport, type TrezorCallOptions, TrezorCore, type TrezorCoreFactory, type TrezorCoreLike, type TrezorCoreOptions, type TrezorDebugLogEntry, type TrezorDebugLogLevel, type TrezorDebugLogger, TrezorDeviceSession, TrezorFailureError, type TrezorMessageName, type TrezorMessageResponse, type TrezorPinMatrixRequestPayload, type TrezorThpCallParams, type TrezorThpCredentials, type TrezorThpHandshakeCredentials, type TrezorThpHandshakeInitHandler, type TrezorThpHandshakeInitResponse, type TrezorThpPairingMethod, TrezorThpProtocol, type TrezorThpRawTransport, type TrezorThpSessionOptions, type TrezorThpState, type TrezorTransportProtocol };
@@ -0,0 +1,239 @@
1
+ interface TrezorByteTransport {
2
+ write(chunk: Buffer, signal?: AbortSignal): Promise<void>;
3
+ read(signal?: AbortSignal): Promise<Buffer>;
4
+ }
5
+ interface TrezorTransportProtocol {
6
+ name: 'bridge' | 'v1' | 'v2';
7
+ encode(data: Buffer, options: {
8
+ messageType: number;
9
+ header?: Buffer;
10
+ }): Buffer;
11
+ decode(bytes: Buffer): {
12
+ header: Buffer;
13
+ length: number;
14
+ messageType: number;
15
+ payload: Buffer;
16
+ };
17
+ getHeaders(data: Buffer): [header: Buffer, chunkHeader: Buffer];
18
+ }
19
+ type TrezorThpState = {
20
+ readonly sendNonce?: number;
21
+ sync(direction: 'send' | 'recv', messageName: string): void;
22
+ };
23
+ type TrezorMessageName = string;
24
+ type TrezorMessageResponse<T extends string = string> = {
25
+ type: T;
26
+ message: Record<string, unknown>;
27
+ };
28
+ type TrezorCoreOptions = {
29
+ transport: TrezorByteTransport;
30
+ protocol?: TrezorTransportProtocol;
31
+ chunkSize?: number;
32
+ logger?: TrezorDebugLogger;
33
+ };
34
+ type TrezorCallOptions = {
35
+ signal?: AbortSignal;
36
+ thpState?: TrezorThpState;
37
+ };
38
+ type TrezorThpRawTransport = {
39
+ write?(connectId: string, data: Uint8Array): Promise<void>;
40
+ read?(connectId: string, timeoutMs?: number): Promise<Uint8Array | undefined>;
41
+ };
42
+ type TrezorThpCallParams = {
43
+ messageName: string;
44
+ data?: Record<string, unknown>;
45
+ skipAck?: boolean;
46
+ };
47
+ type TrezorDebugLogLevel = 'debug' | 'info' | 'warn' | 'error';
48
+ type TrezorDebugLogEntry = {
49
+ level: TrezorDebugLogLevel;
50
+ scope: string;
51
+ event: string;
52
+ data?: Record<string, unknown>;
53
+ };
54
+ type TrezorDebugLogger = (entry: TrezorDebugLogEntry) => void;
55
+ declare class TrezorFailureError extends Error {
56
+ readonly code?: unknown;
57
+ readonly response: TrezorMessageResponse<'Failure'>;
58
+ constructor(response: TrezorMessageResponse<'Failure'>);
59
+ }
60
+ declare class TrezorCore {
61
+ private readonly transport;
62
+ private readonly protocol;
63
+ private readonly chunkSize;
64
+ private readonly logger?;
65
+ constructor({ transport, protocol, chunkSize, logger }: TrezorCoreOptions);
66
+ call(name: TrezorMessageName, data?: Record<string, unknown>, options?: TrezorCallOptions): Promise<TrezorMessageResponse>;
67
+ private thpLoopLogger;
68
+ }
69
+ declare class TrezorThpProtocol {
70
+ private readonly thpState;
71
+ constructor();
72
+ encode({ messageName, data }: TrezorThpCallParams): Uint8Array;
73
+ call(transport: TrezorThpRawTransport, connectId: string, params: TrezorThpCallParams): Promise<TrezorMessageResponse>;
74
+ private applyReceivedState;
75
+ }
76
+ type TrezorCoreLike = {
77
+ call(name: string, data?: Record<string, unknown>, options?: TrezorCallOptions): Promise<TrezorMessageResponse>;
78
+ };
79
+ type TrezorCoreFactory = (transport: TrezorByteTransport, protocol: TrezorTransportProtocol, chunkSize: number, logger?: TrezorDebugLogger) => TrezorCoreLike;
80
+ type TrezorSessionProtocol = 'v1' | 'thp';
81
+ type TrezorDeviceSessionOptions = {
82
+ transport: TrezorByteTransport;
83
+ connectionType?: string;
84
+ chunkSize?: number;
85
+ coreFactory?: TrezorCoreFactory;
86
+ initializedState?: {
87
+ protocol: TrezorSessionProtocol;
88
+ features: Record<string, unknown>;
89
+ thpState?: TrezorThpState;
90
+ };
91
+ thp?: TrezorThpSessionOptions;
92
+ };
93
+ type TrezorThpPairingMethod = number | 'CodeEntry' | 'QrCode' | 'NFC' | 'SkipPairing';
94
+ type TrezorThpCredentials = Record<string, unknown> & {
95
+ host_static_key?: string;
96
+ autoconnect?: boolean;
97
+ };
98
+ type TrezorThpHandshakeInitResponse = Record<string, unknown>;
99
+ type TrezorPinMatrixRequestPayload = Record<string, unknown> & {
100
+ type?: string;
101
+ };
102
+ type TrezorThpHandshakeCredentials = {
103
+ pairingMethods: number[];
104
+ handshakeHash: Buffer;
105
+ handshakeCommitment?: Buffer;
106
+ codeEntryChallenge?: Buffer;
107
+ trezorEncryptedStaticPubkey: Buffer;
108
+ hostEncryptedStaticPubkey: Buffer;
109
+ staticKey: Buffer;
110
+ hostStaticPublicKey?: Buffer;
111
+ hostKey: Buffer;
112
+ trezorKey: Buffer;
113
+ trezorCpacePublicKey?: Buffer;
114
+ };
115
+ type TrezorThpHandshakeInitHandler = (args: {
116
+ handshakeInitResponse: TrezorThpHandshakeInitResponse;
117
+ thpState: TrezorThpState;
118
+ knownCredentials: TrezorThpCredentials[];
119
+ hostEphemeralKeys: {
120
+ privateKey: Buffer;
121
+ publicKey: Buffer;
122
+ };
123
+ tryToUnlock: 0 | 1;
124
+ protobufEncoder: (name: string, data: Record<string, unknown>) => {
125
+ message: Buffer;
126
+ };
127
+ }) => {
128
+ trezorMaskedStaticPubkey: Buffer;
129
+ trezorEncryptedStaticPubkey: Buffer;
130
+ hostEncryptedStaticPubkey: Buffer;
131
+ hostKey: Buffer;
132
+ trezorKey: Buffer;
133
+ handshakeHash: Buffer;
134
+ credentials?: TrezorThpCredentials;
135
+ allCredentials: TrezorThpCredentials[];
136
+ encryptedPayload: Buffer;
137
+ staticKey: Buffer;
138
+ hostStaticKeys: {
139
+ privateKey: Buffer;
140
+ publicKey: Buffer;
141
+ };
142
+ };
143
+ type TrezorThpPairingResponse = {
144
+ selectedMethod: TrezorThpPairingMethod;
145
+ } | {
146
+ tag: string;
147
+ };
148
+ type TrezorThpSessionOptions = {
149
+ hostName?: string;
150
+ appName?: string;
151
+ pairingMethods?: TrezorThpPairingMethod[];
152
+ knownCredentials?: TrezorThpCredentials[];
153
+ randomBytes?: (size: number) => Buffer;
154
+ handleHandshakeInit?: TrezorThpHandshakeInitHandler;
155
+ onPairingRequest?: (payload: {
156
+ availableMethods: number[];
157
+ selectedMethod: number;
158
+ nfcData?: string;
159
+ }) => Promise<TrezorThpPairingResponse>;
160
+ onButtonRequest?: (payload: Record<string, unknown>) => Promise<void> | void;
161
+ onPinMatrixRequest?: (payload: TrezorPinMatrixRequestPayload) => Promise<string> | string;
162
+ /**
163
+ * Provide the passphrase for a session. Called at two points depending on
164
+ * protocol — proactively before `ThpCreateNewSession` (THP), reactively on
165
+ * a `PassphraseRequest` (v1). Return `{ on_device: true }` to enter the
166
+ * passphrase on the device instead of sending a value. Empty string = the
167
+ * standard (no-passphrase) wallet.
168
+ */
169
+ onPassphraseRequest?: (payload?: Record<string, unknown>) => Promise<{
170
+ passphrase?: string;
171
+ on_device?: boolean;
172
+ }> | {
173
+ passphrase?: string;
174
+ on_device?: boolean;
175
+ };
176
+ /**
177
+ * Invoked after the THP handshake mints fresh pairing credentials (i.e.
178
+ * the first successful pairing run after a wipe / new device). The host
179
+ * should persist the full `credentials` list keyed by `deviceId` and feed
180
+ * it back via `knownCredentials` on the next connect to skip pairing UX.
181
+ */
182
+ onPairingCredentialsChanged?: (payload: {
183
+ credentials: TrezorThpCredentials[];
184
+ }) => Promise<void> | void;
185
+ logger?: TrezorDebugLogger;
186
+ };
187
+ declare class TrezorDeviceSession {
188
+ private readonly transport;
189
+ private readonly connectionType?;
190
+ private readonly chunkSize;
191
+ private readonly coreFactory;
192
+ private readonly thpOptions?;
193
+ private core?;
194
+ private protocol;
195
+ private thpState?;
196
+ private thpAppSessionActive;
197
+ private currentFeatures?;
198
+ constructor(options: TrezorDeviceSessionOptions);
199
+ get features(): Record<string, unknown> | undefined;
200
+ /**
201
+ * Whether this device speaks THP (v2). THP supports multiple host-managed
202
+ * application sessions per channel (passphrase sessions); v1 does not — its
203
+ * passphrase flow is reactive (device-driven `PassphraseRequest`). The
204
+ * adapter branches on this to decide whether to drive app-session caching.
205
+ */
206
+ get isThp(): boolean;
207
+ getThpState(): TrezorThpState | undefined;
208
+ initialize(): Promise<Record<string, unknown>>;
209
+ call(name: string, data?: Record<string, unknown>): Promise<{
210
+ type: string;
211
+ message: Record<string, unknown>;
212
+ }>;
213
+ private initializeThp;
214
+ /**
215
+ * Create a NEW THP application session with a freshly-prompted passphrase
216
+ * (or empty if the device has no passphrase protection). Returns the new
217
+ * session id (hex). The session knows nothing about wallet identity (XFP) —
218
+ * the adapter derives that (via master fingerprint) and owns the
219
+ * XFP↔sessionId map. Multiple sessions can coexist on one channel.
220
+ */
221
+ createThpAppSession(deriveCardano?: boolean): Promise<string>;
222
+ /**
223
+ * Switch the active THP session to an existing id (host-side: just sets the
224
+ * session-id byte in the next message header). The device must still hold
225
+ * the session — validity is verified by the caller's next real call (an
226
+ * evicted session surfaces as a Failure/ThpError, the adapter then recreates).
227
+ */
228
+ selectThpAppSession(sessionId: string): void;
229
+ /** Active THP session id (hex), or undefined if none created/selected. */
230
+ getThpAppSessionId(): string | undefined;
231
+ private ensureThpApplicationSession;
232
+ private handleButtonRequest;
233
+ private handlePinMatrixRequest;
234
+ private handlePassphraseRequest;
235
+ private cancelCurrentCall;
236
+ private log;
237
+ }
238
+
239
+ export { type TrezorByteTransport, type TrezorCallOptions, TrezorCore, type TrezorCoreFactory, type TrezorCoreLike, type TrezorCoreOptions, type TrezorDebugLogEntry, type TrezorDebugLogLevel, type TrezorDebugLogger, TrezorDeviceSession, TrezorFailureError, type TrezorMessageName, type TrezorMessageResponse, type TrezorPinMatrixRequestPayload, type TrezorThpCallParams, type TrezorThpCredentials, type TrezorThpHandshakeCredentials, type TrezorThpHandshakeInitHandler, type TrezorThpHandshakeInitResponse, type TrezorThpPairingMethod, TrezorThpProtocol, type TrezorThpRawTransport, type TrezorThpSessionOptions, type TrezorThpState, type TrezorTransportProtocol };