@bitboxswiss/bitbox-api 0.1.0 → 0.2.0
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/CONTRIBUTING.md +4 -2
- package/README.md +69 -9
- package/dist/index.d.ts +337 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +451 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/cardano/methods.d.ts +7 -0
- package/dist/internal/cardano/methods.d.ts.map +1 -0
- package/dist/internal/cardano/methods.js +199 -0
- package/dist/internal/cardano/methods.js.map +1 -0
- package/dist/internal/cardano/query.d.ts +4 -0
- package/dist/internal/cardano/query.d.ts.map +1 -0
- package/dist/internal/cardano/query.js +20 -0
- package/dist/internal/cardano/query.js.map +1 -0
- package/dist/internal/connect-simulator.d.ts +2 -0
- package/dist/internal/connect-simulator.d.ts.map +1 -0
- package/dist/internal/connect-simulator.js +25 -0
- package/dist/internal/connect-simulator.js.map +1 -0
- package/dist/internal/connect.d.ts +2 -0
- package/dist/internal/connect.d.ts.map +1 -0
- package/dist/internal/connect.js +54 -0
- package/dist/internal/connect.js.map +1 -0
- package/dist/internal/constants.d.ts +2 -0
- package/dist/internal/constants.d.ts.map +1 -0
- package/dist/internal/constants.js +16 -0
- package/dist/internal/constants.js.map +1 -0
- package/dist/internal/device.d.ts +5 -0
- package/dist/internal/device.d.ts.map +1 -0
- package/dist/internal/device.js +40 -0
- package/dist/internal/device.js.map +1 -0
- package/dist/internal/errors.d.ts +2 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +220 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/eth/antiklepto.d.ts +5 -0
- package/dist/internal/eth/antiklepto.d.ts.map +1 -0
- package/dist/internal/eth/antiklepto.js +59 -0
- package/dist/internal/eth/antiklepto.js.map +1 -0
- package/dist/internal/eth/eip712.d.ts +25 -0
- package/dist/internal/eth/eip712.d.ts.map +1 -0
- package/dist/internal/eth/eip712.js +303 -0
- package/dist/internal/eth/eip712.js.map +1 -0
- package/dist/internal/eth/methods.d.ts +10 -0
- package/dist/internal/eth/methods.d.ts.map +1 -0
- package/dist/internal/eth/methods.js +245 -0
- package/dist/internal/eth/methods.js.map +1 -0
- package/dist/internal/eth/query.d.ts +4 -0
- package/dist/internal/eth/query.d.ts.map +1 -0
- package/dist/internal/eth/query.js +20 -0
- package/dist/internal/eth/query.js.map +1 -0
- package/dist/internal/eth/streaming.d.ts +4 -0
- package/dist/internal/eth/streaming.d.ts.map +1 -0
- package/dist/internal/eth/streaming.js +22 -0
- package/dist/internal/eth/streaming.js.map +1 -0
- package/dist/internal/eth/version.d.ts +2 -0
- package/dist/internal/eth/version.d.ts.map +1 -0
- package/dist/internal/eth/version.js +3 -0
- package/dist/internal/eth/version.js.map +1 -0
- package/dist/internal/hww.d.ts +2 -0
- package/dist/internal/hww.d.ts.map +1 -0
- package/dist/internal/hww.js +240 -0
- package/dist/internal/hww.js.map +1 -0
- package/dist/internal/keypath.d.ts +4 -0
- package/dist/internal/keypath.d.ts.map +1 -0
- package/dist/internal/keypath.js +47 -0
- package/dist/internal/keypath.js.map +1 -0
- package/dist/internal/message-queue.d.ts +2 -0
- package/dist/internal/message-queue.d.ts.map +1 -0
- package/dist/internal/message-queue.js +29 -0
- package/dist/internal/message-queue.js.map +1 -0
- package/dist/internal/noise-config.d.ts +2 -0
- package/dist/internal/noise-config.d.ts.map +1 -0
- package/dist/internal/noise-config.js +160 -0
- package/dist/internal/noise-config.js.map +1 -0
- package/dist/internal/noise.d.ts +2 -0
- package/dist/internal/noise.d.ts.map +1 -0
- package/dist/internal/noise.js +270 -0
- package/dist/internal/noise.js.map +1 -0
- package/dist/internal/pairing.d.ts +2 -0
- package/dist/internal/pairing.d.ts.map +1 -0
- package/dist/internal/pairing.js +130 -0
- package/dist/internal/pairing.js.map +1 -0
- package/dist/internal/proto-query.d.ts +5 -0
- package/dist/internal/proto-query.d.ts.map +1 -0
- package/dist/internal/proto-query.js +28 -0
- package/dist/internal/proto-query.js.map +1 -0
- package/dist/internal/read-write.d.ts +2 -0
- package/dist/internal/read-write.d.ts.map +1 -0
- package/dist/internal/read-write.js +40 -0
- package/dist/internal/read-write.js.map +1 -0
- package/dist/internal/restore.d.ts +3 -0
- package/dist/internal/restore.d.ts.map +1 -0
- package/dist/internal/restore.js +27 -0
- package/dist/internal/restore.js.map +1 -0
- package/dist/internal/transport-bridge.d.ts +2 -0
- package/dist/internal/transport-bridge.d.ts.map +1 -0
- package/dist/internal/transport-bridge.js +97 -0
- package/dist/internal/transport-bridge.js.map +1 -0
- package/dist/internal/transport-simulator.d.ts +2 -0
- package/dist/internal/transport-simulator.d.ts.map +1 -0
- package/dist/internal/transport-simulator.js +83 -0
- package/dist/internal/transport-simulator.js.map +1 -0
- package/dist/internal/transport-webhid.d.ts +2 -0
- package/dist/internal/transport-webhid.d.ts.map +1 -0
- package/dist/internal/transport-webhid.js +69 -0
- package/dist/internal/transport-webhid.js.map +1 -0
- package/dist/internal/u2f-framing.d.ts +2 -0
- package/dist/internal/u2f-framing.d.ts.map +1 -0
- package/dist/internal/u2f-framing.js +155 -0
- package/dist/internal/u2f-framing.js.map +1 -0
- package/dist/internal/utils.d.ts +2 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +90 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/internal/version.d.ts +8 -0
- package/dist/internal/version.d.ts.map +1 -0
- package/dist/internal/version.js +9 -0
- package/dist/internal/version.js.map +1 -0
- package/dist/proto/gen/antiklepto_pb.d.ts +49 -0
- package/dist/proto/gen/antiklepto_pb.d.ts.map +1 -0
- package/dist/proto/gen/antiklepto_pb.js +22 -0
- package/dist/proto/gen/antiklepto_pb.js.map +1 -0
- package/dist/proto/gen/backup_commands_pb.d.ts +124 -0
- package/dist/proto/gen/backup_commands_pb.d.ts.map +1 -0
- package/dist/proto/gen/backup_commands_pb.js +42 -0
- package/dist/proto/gen/backup_commands_pb.js.map +1 -0
- package/dist/proto/gen/backup_pb.d.ts +150 -0
- package/dist/proto/gen/backup_pb.d.ts.map +1 -0
- package/dist/proto/gen/backup_pb.js +46 -0
- package/dist/proto/gen/backup_pb.js.map +1 -0
- package/dist/proto/gen/bitbox02_system_pb.d.ts +207 -0
- package/dist/proto/gen/bitbox02_system_pb.d.ts.map +1 -0
- package/dist/proto/gen/bitbox02_system_pb.js +80 -0
- package/dist/proto/gen/bitbox02_system_pb.js.map +1 -0
- package/dist/proto/gen/bluetooth_pb.d.ts +135 -0
- package/dist/proto/gen/bluetooth_pb.d.ts.map +1 -0
- package/dist/proto/gen/bluetooth_pb.js +42 -0
- package/dist/proto/gen/bluetooth_pb.js.map +1 -0
- package/dist/proto/gen/btc_pb.d.ts +1166 -0
- package/dist/proto/gen/btc_pb.d.ts.map +1 -0
- package/dist/proto/gen/btc_pb.js +442 -0
- package/dist/proto/gen/btc_pb.js.map +1 -0
- package/dist/proto/gen/cardano_pb.d.ts +504 -0
- package/dist/proto/gen/cardano_pb.d.ts.map +1 -0
- package/dist/proto/gen/cardano_pb.js +142 -0
- package/dist/proto/gen/cardano_pb.js.map +1 -0
- package/dist/proto/gen/common_pb.d.ts +129 -0
- package/dist/proto/gen/common_pb.d.ts.map +1 -0
- package/dist/proto/gen/common_pb.js +42 -0
- package/dist/proto/gen/common_pb.js.map +1 -0
- package/dist/proto/gen/eth_pb.d.ts +662 -0
- package/dist/proto/gen/eth_pb.d.ts.map +1 -0
- package/dist/proto/gen/eth_pb.js +221 -0
- package/dist/proto/gen/eth_pb.js.map +1 -0
- package/dist/proto/gen/hww_pb.d.ts +349 -0
- package/dist/proto/gen/hww_pb.d.ts.map +1 -0
- package/dist/proto/gen/hww_pb.js +38 -0
- package/dist/proto/gen/hww_pb.js.map +1 -0
- package/dist/proto/gen/keystore_pb.d.ts +108 -0
- package/dist/proto/gen/keystore_pb.d.ts.map +1 -0
- package/dist/proto/gen/keystore_pb.js +33 -0
- package/dist/proto/gen/keystore_pb.js.map +1 -0
- package/dist/proto/gen/mnemonic_pb.d.ts +48 -0
- package/dist/proto/gen/mnemonic_pb.d.ts.map +1 -0
- package/dist/proto/gen/mnemonic_pb.js +22 -0
- package/dist/proto/gen/mnemonic_pb.js.map +1 -0
- package/dist/proto/gen/perform_attestation_pb.d.ts +57 -0
- package/dist/proto/gen/perform_attestation_pb.d.ts.map +1 -0
- package/dist/proto/gen/perform_attestation_pb.js +17 -0
- package/dist/proto/gen/perform_attestation_pb.js.map +1 -0
- package/dist/proto/gen/system_pb.d.ts +38 -0
- package/dist/proto/gen/system_pb.d.ts.map +1 -0
- package/dist/proto/gen/system_pb.js +30 -0
- package/dist/proto/gen/system_pb.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { x25519 } from '@noble/curves/ed25519';
|
|
3
|
+
import { chacha20poly1305 } from '@noble/ciphers/chacha';
|
|
4
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
5
|
+
import { hkdf } from '@noble/hashes/hkdf';
|
|
6
|
+
import { concatBytes, utf8ToBytes } from './utils.js';
|
|
7
|
+
const PROTOCOL_NAME = 'Noise_XX_25519_ChaChaPoly_SHA256';
|
|
8
|
+
const PROTOCOL_NAME_BYTES = utf8ToBytes(PROTOCOL_NAME);
|
|
9
|
+
const DHLEN = 32;
|
|
10
|
+
const HASHLEN = 32;
|
|
11
|
+
const TAGLEN = 16;
|
|
12
|
+
const EMPTY = new Uint8Array(0);
|
|
13
|
+
const XX_PATTERNS = [
|
|
14
|
+
['e'],
|
|
15
|
+
['e', 'ee', 's', 'es'],
|
|
16
|
+
['s', 'se'],
|
|
17
|
+
];
|
|
18
|
+
/** @internal */
|
|
19
|
+
export class NoiseProtocolError extends Error {
|
|
20
|
+
code = 'noise';
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function noiseError(message) {
|
|
26
|
+
return new NoiseProtocolError(message);
|
|
27
|
+
}
|
|
28
|
+
function keyPairFromPrivateKey(privateKey) {
|
|
29
|
+
try {
|
|
30
|
+
return { privateKey, publicKey: x25519.getPublicKey(privateKey) };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw noiseError('invalid Noise private key');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function dh(local, remotePub) {
|
|
37
|
+
try {
|
|
38
|
+
return x25519.getSharedSecret(local.privateKey, remotePub);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw noiseError('Noise DH failed');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function nonce96(n) {
|
|
45
|
+
const buf = new Uint8Array(12);
|
|
46
|
+
new DataView(buf.buffer).setBigUint64(4, n, true);
|
|
47
|
+
return buf;
|
|
48
|
+
}
|
|
49
|
+
function noiseHkdf2(ck, ikm) {
|
|
50
|
+
const out = hkdf(sha256, ikm, ck, EMPTY, HASHLEN * 2);
|
|
51
|
+
return [out.slice(0, HASHLEN), out.slice(HASHLEN, HASHLEN * 2)];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Post-handshake AEAD state. Tracks a 64-bit nonce counter per direction;
|
|
55
|
+
* empty `k` means the cipher is uninitialized (early-handshake state, before
|
|
56
|
+
* the first `MixKey`).
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export class CipherState {
|
|
60
|
+
k;
|
|
61
|
+
n = 0n;
|
|
62
|
+
constructor(k) {
|
|
63
|
+
if (k !== undefined) {
|
|
64
|
+
this.k = k;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
hasKey() {
|
|
68
|
+
return this.k !== undefined;
|
|
69
|
+
}
|
|
70
|
+
encryptWithAd(ad, plaintext) {
|
|
71
|
+
if (this.k === undefined) {
|
|
72
|
+
return plaintext;
|
|
73
|
+
}
|
|
74
|
+
let ct;
|
|
75
|
+
try {
|
|
76
|
+
ct = chacha20poly1305(this.k, nonce96(this.n), ad).encrypt(plaintext);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw noiseError('noise encryption failed');
|
|
80
|
+
}
|
|
81
|
+
this.n += 1n;
|
|
82
|
+
return ct;
|
|
83
|
+
}
|
|
84
|
+
decryptWithAd(ad, ciphertext) {
|
|
85
|
+
if (this.k === undefined) {
|
|
86
|
+
return ciphertext;
|
|
87
|
+
}
|
|
88
|
+
let pt;
|
|
89
|
+
try {
|
|
90
|
+
pt = chacha20poly1305(this.k, nonce96(this.n), ad).decrypt(ciphertext);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw noiseError('noise decryption failed');
|
|
94
|
+
}
|
|
95
|
+
this.n += 1n;
|
|
96
|
+
return pt;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
class SymmetricState {
|
|
100
|
+
ck;
|
|
101
|
+
h;
|
|
102
|
+
cipher;
|
|
103
|
+
constructor() {
|
|
104
|
+
this.h = new Uint8Array(HASHLEN);
|
|
105
|
+
this.h.set(PROTOCOL_NAME_BYTES);
|
|
106
|
+
this.ck = new Uint8Array(this.h);
|
|
107
|
+
this.cipher = new CipherState();
|
|
108
|
+
}
|
|
109
|
+
hasCipherKey() {
|
|
110
|
+
return this.cipher.hasKey();
|
|
111
|
+
}
|
|
112
|
+
mixHash(data) {
|
|
113
|
+
this.h = sha256(concatBytes(this.h, data));
|
|
114
|
+
}
|
|
115
|
+
mixKey(ikm) {
|
|
116
|
+
const [newCk, newK] = noiseHkdf2(this.ck, ikm);
|
|
117
|
+
this.ck = newCk;
|
|
118
|
+
this.cipher = new CipherState(newK);
|
|
119
|
+
}
|
|
120
|
+
encryptAndHash(plaintext) {
|
|
121
|
+
const ct = this.cipher.encryptWithAd(this.h, plaintext);
|
|
122
|
+
this.mixHash(ct);
|
|
123
|
+
return ct;
|
|
124
|
+
}
|
|
125
|
+
decryptAndHash(ct) {
|
|
126
|
+
const pt = this.cipher.decryptWithAd(this.h, ct);
|
|
127
|
+
this.mixHash(ct);
|
|
128
|
+
return pt;
|
|
129
|
+
}
|
|
130
|
+
split() {
|
|
131
|
+
const [k1, k2] = noiseHkdf2(this.ck, EMPTY);
|
|
132
|
+
return [new CipherState(k1), new CipherState(k2)];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* `Noise_XX_25519_ChaChaPoly_SHA256` handshake state. The class supports both
|
|
137
|
+
* initiator and responder roles so the same code can drive production
|
|
138
|
+
* handshakes (initiator) and unit-test peer simulation (responder).
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
export class NoiseXX {
|
|
142
|
+
initiator;
|
|
143
|
+
s;
|
|
144
|
+
e;
|
|
145
|
+
re;
|
|
146
|
+
rs;
|
|
147
|
+
symmetric = new SymmetricState();
|
|
148
|
+
patternIndex = 0;
|
|
149
|
+
fixedEphemeralPrivateKey;
|
|
150
|
+
constructor(initiator, staticPrivateKey, options) {
|
|
151
|
+
this.initiator = initiator;
|
|
152
|
+
this.s = keyPairFromPrivateKey(staticPrivateKey);
|
|
153
|
+
this.symmetric.mixHash(PROTOCOL_NAME_BYTES);
|
|
154
|
+
if (options?.fixedEphemeralPrivateKey !== undefined) {
|
|
155
|
+
this.fixedEphemeralPrivateKey = options.fixedEphemeralPrivateKey;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Compose the next outgoing handshake message; payload is empty. */
|
|
159
|
+
writeMessage() {
|
|
160
|
+
const tokens = XX_PATTERNS[this.patternIndex];
|
|
161
|
+
if (tokens === undefined) {
|
|
162
|
+
throw new Error('handshake already complete');
|
|
163
|
+
}
|
|
164
|
+
const isOurTurn = (this.patternIndex % 2 === 0) === this.initiator;
|
|
165
|
+
if (!isOurTurn) {
|
|
166
|
+
throw new Error('not the local peer turn to write');
|
|
167
|
+
}
|
|
168
|
+
let buf = EMPTY;
|
|
169
|
+
for (const tok of tokens) {
|
|
170
|
+
if (tok === 'e') {
|
|
171
|
+
const sk = this.fixedEphemeralPrivateKey ?? x25519.utils.randomPrivateKey();
|
|
172
|
+
this.e = keyPairFromPrivateKey(sk);
|
|
173
|
+
buf = concatBytes(buf, this.e.publicKey);
|
|
174
|
+
this.symmetric.mixHash(this.e.publicKey);
|
|
175
|
+
}
|
|
176
|
+
else if (tok === 's') {
|
|
177
|
+
buf = concatBytes(buf, this.symmetric.encryptAndHash(this.s.publicKey));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
this.symmetric.mixKey(this.tokenDh(tok));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
buf = concatBytes(buf, this.symmetric.encryptAndHash(EMPTY));
|
|
184
|
+
this.patternIndex += 1;
|
|
185
|
+
return buf;
|
|
186
|
+
}
|
|
187
|
+
/** Process an incoming handshake message; payload is expected empty. */
|
|
188
|
+
readMessage(message) {
|
|
189
|
+
const tokens = XX_PATTERNS[this.patternIndex];
|
|
190
|
+
if (tokens === undefined) {
|
|
191
|
+
throw new Error('handshake already complete');
|
|
192
|
+
}
|
|
193
|
+
const isOurTurn = (this.patternIndex % 2 === 0) === this.initiator;
|
|
194
|
+
if (isOurTurn) {
|
|
195
|
+
throw new Error('not the local peer turn to read');
|
|
196
|
+
}
|
|
197
|
+
let cursor = 0;
|
|
198
|
+
for (const tok of tokens) {
|
|
199
|
+
if (tok === 'e') {
|
|
200
|
+
if (message.length - cursor < DHLEN) {
|
|
201
|
+
throw noiseError('handshake message truncated at remote ephemeral key');
|
|
202
|
+
}
|
|
203
|
+
this.re = message.slice(cursor, cursor + DHLEN);
|
|
204
|
+
cursor += DHLEN;
|
|
205
|
+
this.symmetric.mixHash(this.re);
|
|
206
|
+
}
|
|
207
|
+
else if (tok === 's') {
|
|
208
|
+
const len = this.symmetric.hasCipherKey() ? DHLEN + TAGLEN : DHLEN;
|
|
209
|
+
if (message.length - cursor < len) {
|
|
210
|
+
throw noiseError('handshake message truncated at remote static key');
|
|
211
|
+
}
|
|
212
|
+
const slice = message.slice(cursor, cursor + len);
|
|
213
|
+
cursor += len;
|
|
214
|
+
this.rs = this.symmetric.decryptAndHash(slice);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this.symmetric.mixKey(this.tokenDh(tok));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
this.symmetric.decryptAndHash(message.slice(cursor));
|
|
221
|
+
this.patternIndex += 1;
|
|
222
|
+
}
|
|
223
|
+
isComplete() {
|
|
224
|
+
return this.patternIndex >= XX_PATTERNS.length;
|
|
225
|
+
}
|
|
226
|
+
finalize() {
|
|
227
|
+
if (!this.isComplete()) {
|
|
228
|
+
throw new Error('handshake not complete');
|
|
229
|
+
}
|
|
230
|
+
if (this.rs === undefined) {
|
|
231
|
+
throw new Error('remote static key was not received');
|
|
232
|
+
}
|
|
233
|
+
const [c1, c2] = this.symmetric.split();
|
|
234
|
+
return {
|
|
235
|
+
hash: this.symmetric.h,
|
|
236
|
+
remoteStaticPubkey: this.rs,
|
|
237
|
+
send: this.initiator ? c1 : c2,
|
|
238
|
+
recv: this.initiator ? c2 : c1,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
tokenDh(token) {
|
|
242
|
+
if (token === 'ee') {
|
|
243
|
+
return dh(this.e, this.re);
|
|
244
|
+
}
|
|
245
|
+
if (token === 'ss') {
|
|
246
|
+
return dh(this.s, this.rs);
|
|
247
|
+
}
|
|
248
|
+
if (token === 'es') {
|
|
249
|
+
return this.initiator ? dh(this.e, this.rs) : dh(this.s, this.re);
|
|
250
|
+
}
|
|
251
|
+
if (token === 'se') {
|
|
252
|
+
return this.initiator ? dh(this.s, this.re) : dh(this.e, this.rs);
|
|
253
|
+
}
|
|
254
|
+
throw new Error(`unsupported handshake token: ${token}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/** Generate a new x25519 static keypair private key (32 bytes). @internal */
|
|
258
|
+
export function generateStaticPrivateKey() {
|
|
259
|
+
return x25519.utils.randomPrivateKey();
|
|
260
|
+
}
|
|
261
|
+
/** Derive the public key for an x25519 private key. @internal */
|
|
262
|
+
export function publicKeyFromPrivateKey(privateKey) {
|
|
263
|
+
try {
|
|
264
|
+
return x25519.getPublicKey(privateKey);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
throw noiseError('invalid Noise private key');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=noise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/internal/noise.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/internal/pairing.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { NoiseXX, generateStaticPrivateKey, } from './noise.js';
|
|
3
|
+
import { addDeviceStaticPubkey, containsDeviceStaticPubkey, } from './noise-config.js';
|
|
4
|
+
import { CODE_UNEXPECTED_RESPONSE, makeError } from './errors.js';
|
|
5
|
+
const OP_UNLOCK = 0x75; // 'u'
|
|
6
|
+
const OP_I_CAN_HAS_HANDSHAEK = 0x68; // 'h'
|
|
7
|
+
const OP_HER_COMEZ_TEH_HANDSHAEK = 0x48; // 'H'
|
|
8
|
+
const OP_I_CAN_HAS_PAIRIN_VERIFICASHUN = 0x76; // 'v'
|
|
9
|
+
const OP_NOISE_MSG = 0x6e; // 'n'
|
|
10
|
+
const RESPONSE_SUCCESS = 0x00;
|
|
11
|
+
const DEVICE_PAIRING_REQUIRED = 0x01;
|
|
12
|
+
const EMPTY = new Uint8Array(0);
|
|
13
|
+
/** @internal */
|
|
14
|
+
export class NoiseError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
constructor(code, message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.code = code;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const RFC4648_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
22
|
+
function base32Encode(bytes) {
|
|
23
|
+
let bits = 0;
|
|
24
|
+
let value = 0;
|
|
25
|
+
let out = '';
|
|
26
|
+
for (const b of bytes) {
|
|
27
|
+
value = (value << 8) | b;
|
|
28
|
+
bits += 8;
|
|
29
|
+
while (bits >= 5) {
|
|
30
|
+
bits -= 5;
|
|
31
|
+
out += RFC4648_ALPHABET[(value >> bits) & 0x1f];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (bits > 0) {
|
|
35
|
+
out += RFC4648_ALPHABET[(value << (5 - bits)) & 0x1f];
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
/** @internal */
|
|
40
|
+
export function formatPairingCode(handshakeHash) {
|
|
41
|
+
const encoded = base32Encode(handshakeHash);
|
|
42
|
+
return `${encoded.slice(0, 5)} ${encoded.slice(5, 10)}\n${encoded.slice(10, 15)} ${encoded.slice(15, 20)}`;
|
|
43
|
+
}
|
|
44
|
+
async function handshakeQuery(hww, message) {
|
|
45
|
+
const framed = new Uint8Array(message.length + 1);
|
|
46
|
+
framed[0] = OP_HER_COMEZ_TEH_HANDSHAEK;
|
|
47
|
+
framed.set(message, 1);
|
|
48
|
+
const response = await hww.query(framed);
|
|
49
|
+
if (response.length < 1 || response[0] !== RESPONSE_SUCCESS) {
|
|
50
|
+
throw new NoiseError('noise', 'handshake response was not RESPONSE_SUCCESS');
|
|
51
|
+
}
|
|
52
|
+
return response.slice(1);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Drives `OP_UNLOCK`, `OP_I_CAN_HAS_HANDSHAEK`, and the three Noise XX message
|
|
56
|
+
* exchanges. Returns the in-flight pairing state — caller decides whether to
|
|
57
|
+
* surface a pairing code to the user before completing pairing.
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export async function performHandshake(hww, config) {
|
|
61
|
+
await hww.query(new Uint8Array([OP_UNLOCK]));
|
|
62
|
+
let configData = config.read();
|
|
63
|
+
let appStaticPrivkey;
|
|
64
|
+
if (configData.appStaticPrivkey !== undefined) {
|
|
65
|
+
appStaticPrivkey = configData.appStaticPrivkey;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
appStaticPrivkey = generateStaticPrivateKey();
|
|
69
|
+
configData = {
|
|
70
|
+
appStaticPrivkey,
|
|
71
|
+
deviceStaticPubkeys: configData.deviceStaticPubkeys,
|
|
72
|
+
};
|
|
73
|
+
config.store(configData);
|
|
74
|
+
}
|
|
75
|
+
const handshakeStart = await hww.query(new Uint8Array([OP_I_CAN_HAS_HANDSHAEK]));
|
|
76
|
+
if (handshakeStart.length !== 1 || handshakeStart[0] !== RESPONSE_SUCCESS) {
|
|
77
|
+
throw new NoiseError('noise', 'device did not accept handshake start');
|
|
78
|
+
}
|
|
79
|
+
const xx = new NoiseXX(true, appStaticPrivkey);
|
|
80
|
+
const m1 = xx.writeMessage();
|
|
81
|
+
const m2 = await handshakeQuery(hww, m1);
|
|
82
|
+
xx.readMessage(m2);
|
|
83
|
+
const m3 = xx.writeMessage();
|
|
84
|
+
const finishResponse = await handshakeQuery(hww, m3);
|
|
85
|
+
const finalState = xx.finalize();
|
|
86
|
+
const cached = config.read();
|
|
87
|
+
const appWantsVerification = !containsDeviceStaticPubkey(cached, finalState.remoteStaticPubkey);
|
|
88
|
+
const deviceWantsVerification = finishResponse.length === 1 && finishResponse[0] === DEVICE_PAIRING_REQUIRED;
|
|
89
|
+
const pairingCode = appWantsVerification || deviceWantsVerification
|
|
90
|
+
? formatPairingCode(finalState.hash)
|
|
91
|
+
: undefined;
|
|
92
|
+
return { hww, config, finalState, pairingCode };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Completes pairing: if a pairing code was shown the host issues
|
|
96
|
+
* `OP_I_CAN_HAS_PAIRIN_VERIFICASHUN` and persists the device's static pubkey on
|
|
97
|
+
* confirmation. Returns an encrypted-channel adapter for subsequent queries.
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
export async function completePairing(state) {
|
|
101
|
+
if (state.pairingCode !== undefined) {
|
|
102
|
+
const verify = await state.hww.query(new Uint8Array([OP_I_CAN_HAS_PAIRIN_VERIFICASHUN]));
|
|
103
|
+
if (verify.length !== 1 || verify[0] !== RESPONSE_SUCCESS) {
|
|
104
|
+
throw new NoiseError('pairing-rejected', 'pairing code rejected by user');
|
|
105
|
+
}
|
|
106
|
+
const cached = state.config.read();
|
|
107
|
+
const updated = addDeviceStaticPubkey(cached, state.finalState.remoteStaticPubkey);
|
|
108
|
+
if (updated !== cached) {
|
|
109
|
+
state.config.store(updated);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return makeEncryptedChannel(state.hww, state.finalState.send, state.finalState.recv);
|
|
113
|
+
}
|
|
114
|
+
/** @internal */
|
|
115
|
+
export function makeEncryptedChannel(hww, send, recv) {
|
|
116
|
+
return {
|
|
117
|
+
async query(plaintext) {
|
|
118
|
+
const ciphertext = send.encryptWithAd(EMPTY, plaintext);
|
|
119
|
+
const framed = new Uint8Array(ciphertext.length + 1);
|
|
120
|
+
framed[0] = OP_NOISE_MSG;
|
|
121
|
+
framed.set(ciphertext, 1);
|
|
122
|
+
const response = await hww.query(framed);
|
|
123
|
+
if (response.length < 1 || response[0] !== RESPONSE_SUCCESS) {
|
|
124
|
+
throw makeError(CODE_UNEXPECTED_RESPONSE, 'BitBox returned an unexpected response');
|
|
125
|
+
}
|
|
126
|
+
return recv.decryptWithAd(EMPTY, response.slice(1));
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/internal/pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Request, type Response } from '../proto/gen/hww_pb.js';
|
|
2
|
+
import type { EncryptedChannel } from './pairing.js';
|
|
3
|
+
export declare function query(channel: EncryptedChannel, request: Request): Promise<Response>;
|
|
4
|
+
export declare function unexpectedResponse(message?: string): Error;
|
|
5
|
+
//# sourceMappingURL=proto-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proto-query.d.ts","sourceRoot":"","sources":["../../src/internal/proto-query.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAQrD,wBAAsB,KAAK,CACzB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,SAA2C,GAAG,KAAK,CAE5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { fromBinary, toBinary } from '@bufbuild/protobuf';
|
|
3
|
+
import { RequestSchema, ResponseSchema, } from '../proto/gen/hww_pb.js';
|
|
4
|
+
import { CODE_PROTOBUF_DECODE, CODE_UNEXPECTED_RESPONSE, deviceErrorFor, makeError, } from './errors.js';
|
|
5
|
+
export async function query(channel, request) {
|
|
6
|
+
const encoded = toBinary(RequestSchema, request);
|
|
7
|
+
const responseBytes = await channel.query(encoded);
|
|
8
|
+
let decoded;
|
|
9
|
+
try {
|
|
10
|
+
decoded = fromBinary(ResponseSchema, responseBytes);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw makeError(CODE_PROTOBUF_DECODE, 'protobuf message could not be decoded');
|
|
14
|
+
}
|
|
15
|
+
if (decoded.response.case === undefined) {
|
|
16
|
+
throw makeError(CODE_PROTOBUF_DECODE, 'protobuf message could not be decoded');
|
|
17
|
+
}
|
|
18
|
+
if (decoded.response.case === 'error') {
|
|
19
|
+
const { code: numericCode } = decoded.response.value;
|
|
20
|
+
const { code, message } = deviceErrorFor(numericCode);
|
|
21
|
+
throw makeError(code, message);
|
|
22
|
+
}
|
|
23
|
+
return decoded;
|
|
24
|
+
}
|
|
25
|
+
export function unexpectedResponse(message = 'BitBox returned an unexpected response') {
|
|
26
|
+
return makeError(CODE_UNEXPECTED_RESPONSE, message);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=proto-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proto-query.js","sourceRoot":"","sources":["../../src/internal/proto-query.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,cAAc,GAGf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAyB,EACzB,OAAgB;IAEhB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACtC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAO,GAAG,wCAAwC;IACnF,OAAO,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-write.d.ts","sourceRoot":"","sources":["../../src/internal/read-write.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Transport-layer errors. The shape `{ code, message }` is compatible with the
|
|
4
|
+
* public `Error` type in `src/index.ts`, so `ensureError` returns these as-is.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export class TransportError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
constructor(code, message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = 'TransportError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
export async function query(rw, msg) {
|
|
17
|
+
rw.write(msg);
|
|
18
|
+
return rw.read();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Wraps a close callback so it fires exactly once. Clearing the reference
|
|
22
|
+
* after invocation prevents retained callbacks after teardown.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export function makeCloseGuard(cb) {
|
|
26
|
+
let fired = false;
|
|
27
|
+
let stored = cb;
|
|
28
|
+
return () => {
|
|
29
|
+
if (fired) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
fired = true;
|
|
33
|
+
const f = stored;
|
|
34
|
+
stored = undefined;
|
|
35
|
+
if (f !== undefined) {
|
|
36
|
+
f();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=read-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-write.js","sourceRoot":"","sources":["../../src/internal/read-write.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAyBtC;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,IAAI,CAAqB;IAEzB,YAAY,IAAwB,EAAE,OAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,gBAAgB;AAChB,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,EAAa,EAAE,GAAe;IACxD,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACd,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAe;IAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,GAAG,EAAE;QACV,IAAI,KAAK,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,KAAK,GAAG,IAAI,CAAC;QACb,MAAM,CAAC,GAAG,MAAM,CAAC;QACjB,MAAM,GAAG,SAAS,CAAC;QACnB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/internal/restore.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKrD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBlF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { create } from '@bufbuild/protobuf';
|
|
3
|
+
import { RequestSchema } from '../proto/gen/hww_pb.js';
|
|
4
|
+
import { RestoreFromMnemonicRequestSchema } from '../proto/gen/mnemonic_pb.js';
|
|
5
|
+
import { CODE_UNEXPECTED_RESPONSE, makeError } from './errors.js';
|
|
6
|
+
import { query } from './proto-query.js';
|
|
7
|
+
const UINT32_MAX = 0xffffffff;
|
|
8
|
+
export async function restoreFromMnemonic(channel) {
|
|
9
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
10
|
+
const timestamp = nowSec >= 0 && nowSec <= UINT32_MAX ? nowSec : 0;
|
|
11
|
+
// getTimezoneOffset returns minutes WEST of UTC; firmware expects seconds EAST of UTC.
|
|
12
|
+
const timezoneOffset = -new Date().getTimezoneOffset() * 60;
|
|
13
|
+
const request = create(RequestSchema, {
|
|
14
|
+
request: {
|
|
15
|
+
case: 'restoreFromMnemonic',
|
|
16
|
+
value: create(RestoreFromMnemonicRequestSchema, {
|
|
17
|
+
timestamp,
|
|
18
|
+
timezoneOffset,
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const response = await query(channel, request);
|
|
23
|
+
if (response.response.case !== 'success') {
|
|
24
|
+
throw makeError(CODE_UNEXPECTED_RESPONSE, 'unexpected response to restoreFromMnemonic');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=restore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../../src/internal/restore.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,UAAU,GAAG,UAAU,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAyB;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,uFAAuF;IACvF,MAAM,cAAc,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC;IAE5D,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,EAAE;QACpC,OAAO,EAAE;YACP,IAAI,EAAE,qBAAqB;YAC3B,KAAK,EAAE,MAAM,CAAC,gCAAgC,EAAE;gBAC9C,SAAS;gBACT,cAAc;aACf,CAAC;SACH;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,SAAS,CAAC,wBAAwB,EAAE,4CAA4C,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport-bridge.d.ts","sourceRoot":"","sources":["../../src/internal/transport-bridge.ts"],"names":[],"mappings":""}
|