toss-expo-sdk 0.1.1 → 1.0.1

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.
Files changed (93) hide show
  1. package/README.md +490 -81
  2. package/lib/module/ble.js +59 -4
  3. package/lib/module/ble.js.map +1 -1
  4. package/lib/module/client/BLETransactionHandler.js +277 -0
  5. package/lib/module/client/BLETransactionHandler.js.map +1 -0
  6. package/lib/module/client/NonceAccountManager.js +364 -0
  7. package/lib/module/client/NonceAccountManager.js.map +1 -0
  8. package/lib/module/client/TossClient.js +27 -44
  9. package/lib/module/client/TossClient.js.map +1 -1
  10. package/lib/module/contexts/WalletContext.js +4 -4
  11. package/lib/module/contexts/WalletContext.js.map +1 -1
  12. package/lib/module/discovery.js +35 -8
  13. package/lib/module/discovery.js.map +1 -1
  14. package/lib/module/examples/offlinePaymentFlow.js +27 -2
  15. package/lib/module/examples/offlinePaymentFlow.js.map +1 -1
  16. package/lib/module/hooks/useOfflineBLETransactions.js +314 -0
  17. package/lib/module/hooks/useOfflineBLETransactions.js.map +1 -0
  18. package/lib/module/index.js +13 -8
  19. package/lib/module/index.js.map +1 -1
  20. package/lib/module/intent.js +198 -0
  21. package/lib/module/intent.js.map +1 -1
  22. package/lib/module/nfc.js +1 -1
  23. package/lib/module/noise.js +176 -1
  24. package/lib/module/noise.js.map +1 -1
  25. package/lib/module/reconciliation.js +155 -0
  26. package/lib/module/reconciliation.js.map +1 -1
  27. package/lib/module/services/authService.js +164 -1
  28. package/lib/module/services/authService.js.map +1 -1
  29. package/lib/module/storage/secureStorage.js +102 -0
  30. package/lib/module/storage/secureStorage.js.map +1 -1
  31. package/lib/module/storage.js +4 -4
  32. package/lib/module/sync.js +25 -1
  33. package/lib/module/sync.js.map +1 -1
  34. package/lib/module/types/nonceAccount.js +2 -0
  35. package/lib/module/types/nonceAccount.js.map +1 -0
  36. package/lib/module/types/tossUser.js +16 -1
  37. package/lib/module/types/tossUser.js.map +1 -1
  38. package/lib/typescript/src/__tests__/solana-program-simple.test.d.ts +8 -0
  39. package/lib/typescript/src/__tests__/solana-program-simple.test.d.ts.map +1 -0
  40. package/lib/typescript/src/ble.d.ts +31 -2
  41. package/lib/typescript/src/ble.d.ts.map +1 -1
  42. package/lib/typescript/src/client/BLETransactionHandler.d.ts +98 -0
  43. package/lib/typescript/src/client/BLETransactionHandler.d.ts.map +1 -0
  44. package/lib/typescript/src/client/NonceAccountManager.d.ts +82 -0
  45. package/lib/typescript/src/client/NonceAccountManager.d.ts.map +1 -0
  46. package/lib/typescript/src/client/TossClient.d.ts +10 -12
  47. package/lib/typescript/src/client/TossClient.d.ts.map +1 -1
  48. package/lib/typescript/src/discovery.d.ts +8 -2
  49. package/lib/typescript/src/discovery.d.ts.map +1 -1
  50. package/lib/typescript/src/examples/offlinePaymentFlow.d.ts +9 -1
  51. package/lib/typescript/src/examples/offlinePaymentFlow.d.ts.map +1 -1
  52. package/lib/typescript/src/hooks/useOfflineBLETransactions.d.ts +91 -0
  53. package/lib/typescript/src/hooks/useOfflineBLETransactions.d.ts.map +1 -0
  54. package/lib/typescript/src/index.d.ts +11 -4
  55. package/lib/typescript/src/index.d.ts.map +1 -1
  56. package/lib/typescript/src/intent.d.ts +26 -0
  57. package/lib/typescript/src/intent.d.ts.map +1 -1
  58. package/lib/typescript/src/noise.d.ts +62 -0
  59. package/lib/typescript/src/noise.d.ts.map +1 -1
  60. package/lib/typescript/src/reconciliation.d.ts +6 -0
  61. package/lib/typescript/src/reconciliation.d.ts.map +1 -1
  62. package/lib/typescript/src/services/authService.d.ts +26 -1
  63. package/lib/typescript/src/services/authService.d.ts.map +1 -1
  64. package/lib/typescript/src/storage/secureStorage.d.ts +16 -0
  65. package/lib/typescript/src/storage/secureStorage.d.ts.map +1 -1
  66. package/lib/typescript/src/sync.d.ts +6 -1
  67. package/lib/typescript/src/sync.d.ts.map +1 -1
  68. package/lib/typescript/src/types/nonceAccount.d.ts +59 -0
  69. package/lib/typescript/src/types/nonceAccount.d.ts.map +1 -0
  70. package/lib/typescript/src/types/tossUser.d.ts +16 -0
  71. package/lib/typescript/src/types/tossUser.d.ts.map +1 -1
  72. package/package.json +12 -1
  73. package/src/__tests__/reconciliation.test.tsx +7 -1
  74. package/src/__tests__/solana-program-simple.test.ts +256 -0
  75. package/src/ble.ts +105 -4
  76. package/src/client/BLETransactionHandler.ts +364 -0
  77. package/src/client/NonceAccountManager.ts +444 -0
  78. package/src/client/TossClient.ts +36 -49
  79. package/src/contexts/WalletContext.tsx +4 -4
  80. package/src/discovery.ts +46 -8
  81. package/src/examples/offlinePaymentFlow.ts +48 -2
  82. package/src/hooks/useOfflineBLETransactions.ts +438 -0
  83. package/src/index.tsx +49 -7
  84. package/src/intent.ts +254 -0
  85. package/src/nfc.ts +4 -4
  86. package/src/noise.ts +239 -1
  87. package/src/reconciliation.ts +184 -0
  88. package/src/services/authService.ts +188 -1
  89. package/src/storage/secureStorage.ts +142 -4
  90. package/src/storage.ts +4 -4
  91. package/src/sync.ts +40 -0
  92. package/src/types/nonceAccount.ts +75 -0
  93. package/src/types/tossUser.ts +35 -2
package/lib/module/ble.js CHANGED
@@ -3,10 +3,14 @@
3
3
  // src/ble.ts
4
4
  import { BleManager } from 'react-native-ble-plx';
5
5
  import { PermissionsAndroid, Platform } from 'react-native';
6
+ import { BLETransactionHandler } from "./client/BLETransactionHandler.js";
6
7
  const SERVICE_UUID = '0000ff00-0000-1000-8000-00805f9b34fb';
7
8
  const USER_CHARACTERISTIC = '0000ff01-0000-1000-8000-00805f9b34fb';
8
9
  const INTENT_CHARACTERISTIC = '0000ff02-0000-1000-8000-00805f9b34fb';
10
+ const OFFLINE_TX_CHARACTERISTIC = '0000ff03-0000-1000-8000-00805f9b34fb'; // New for offline transactions
11
+
9
12
  const manager = new BleManager();
13
+ const bleTransactionHandler = new BLETransactionHandler(Platform.OS === 'ios' ? 'ios' : 'android');
10
14
  export async function requestBLEPermissions() {
11
15
  if (Platform.OS === 'android') {
12
16
  await PermissionsAndroid.requestMultiple([PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]);
@@ -21,7 +25,7 @@ async function connect(device) {
21
25
  }
22
26
 
23
27
  // Scan for BLE devices advertising TOSS service
24
- export function startTossScan(onUserFound, onIntentFound) {
28
+ export function startTossScan(onUserFound, onIntentFound, onOfflineTransactionFound) {
25
29
  manager.startDeviceScan([SERVICE_UUID], null, async (error, device) => {
26
30
  if (error) {
27
31
  console.warn('BLE scan error', error.message);
@@ -45,6 +49,20 @@ export function startTossScan(onUserFound, onIntentFound) {
45
49
  const intent = JSON.parse(intentData.value);
46
50
  onIntentFound(intent, device);
47
51
  }
52
+
53
+ // Check for offline transaction data (fragmented)
54
+ if (onOfflineTransactionFound) {
55
+ try {
56
+ const txData = await services.readCharacteristicForService(device.id, SERVICE_UUID, OFFLINE_TX_CHARACTERISTIC);
57
+ if (txData?.value) {
58
+ const tx = JSON.parse(txData.value);
59
+ onOfflineTransactionFound(tx, device);
60
+ }
61
+ } catch {
62
+ // Offline TX characteristic may not be available
63
+ console.debug('Offline transaction characteristic not found');
64
+ }
65
+ }
48
66
  } catch (err) {
49
67
  console.warn('Error reading device data:', err);
50
68
  }
@@ -96,8 +114,45 @@ export async function sendIntentToDevice(deviceId, intent) {
96
114
  await device.cancelConnection();
97
115
  }
98
116
 
99
- // Stop scan
100
- export function stopScan() {
101
- manager.stopDeviceScan();
117
+ /**
118
+ * Send fragmented offline transaction over BLE with Noise Protocol encryption
119
+ * Automatically handles MTU limitations and retries
120
+ */
121
+ export async function sendOfflineTransactionFragmented(device, transaction, noiseEncryptFn, isIntent = false) {
122
+ try {
123
+ const result = await bleTransactionHandler.sendFragmentedTransactionBLE(device, transaction, async (deviceId, charUUID, data) => {
124
+ const dev = await manager.connectToDevice(deviceId);
125
+ await dev.discoverAllServicesAndCharacteristics();
126
+ const characteristic = charUUID === OFFLINE_TX_CHARACTERISTIC ? OFFLINE_TX_CHARACTERISTIC : INTENT_CHARACTERISTIC;
127
+ await dev.writeCharacteristicWithResponseForService(deviceId, SERVICE_UUID, characteristic, data.toString('base64'));
128
+ await dev.cancelConnection();
129
+ }, noiseEncryptFn, isIntent);
130
+ return result;
131
+ } catch (error) {
132
+ const errorMessage = error instanceof Error ? error.message : String(error);
133
+ console.error('Failed to send offline transaction:', errorMessage);
134
+ throw new Error(`BLE transmission failed: ${errorMessage}`);
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Receive and reassemble fragmented message from BLE
140
+ */
141
+ export async function receiveOfflineTransactionFragment(fragment, noiseDecryptFn) {
142
+ return bleTransactionHandler.receiveFragmentedMessage(fragment, noiseDecryptFn);
143
+ }
144
+
145
+ /**
146
+ * Get current BLE MTU configuration
147
+ */
148
+ export function getBLEMTUConfig() {
149
+ return bleTransactionHandler.getMTUConfig();
150
+ }
151
+
152
+ /**
153
+ * Set custom BLE MTU configuration
154
+ */
155
+ export function setBLEMTUConfig(config) {
156
+ bleTransactionHandler.setMTUConfig(config);
102
157
  }
103
158
  //# sourceMappingURL=ble.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["BleManager","PermissionsAndroid","Platform","SERVICE_UUID","USER_CHARACTERISTIC","INTENT_CHARACTERISTIC","manager","requestBLEPermissions","OS","requestMultiple","PERMISSIONS","BLUETOOTH_SCAN","BLUETOOTH_CONNECT","ACCESS_FINE_LOCATION","connect","device","connectedDevice","connectToDevice","id","discoverAllServicesAndCharacteristics","startTossScan","onUserFound","onIntentFound","startDeviceScan","error","console","warn","message","services","userData","readCharacteristicForService","value","user","JSON","parse","intentData","intent","err","State","advertiseUser","subscription","onStateChange","state","PoweredOn","log","userId","remove","errorMessage","Error","String","stopAdvertising","stopDeviceScan","sendIntentToDevice","deviceId","jsonIntent","stringify","writeCharacteristicWithResponseForService","Buffer","from","toString","cancelConnection","stopScan"],"sourceRoot":"../../src","sources":["ble.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["BleManager","PermissionsAndroid","Platform","BLETransactionHandler","SERVICE_UUID","USER_CHARACTERISTIC","INTENT_CHARACTERISTIC","OFFLINE_TX_CHARACTERISTIC","manager","bleTransactionHandler","OS","requestBLEPermissions","requestMultiple","PERMISSIONS","BLUETOOTH_SCAN","BLUETOOTH_CONNECT","ACCESS_FINE_LOCATION","connect","device","connectedDevice","connectToDevice","id","discoverAllServicesAndCharacteristics","startTossScan","onUserFound","onIntentFound","onOfflineTransactionFound","startDeviceScan","error","console","warn","message","services","userData","readCharacteristicForService","value","user","JSON","parse","intentData","intent","txData","tx","debug","err","State","advertiseUser","subscription","onStateChange","state","PoweredOn","log","userId","remove","errorMessage","Error","String","stopAdvertising","stopDeviceScan","sendIntentToDevice","deviceId","jsonIntent","stringify","writeCharacteristicWithResponseForService","Buffer","from","toString","cancelConnection","sendOfflineTransactionFragmented","transaction","noiseEncryptFn","isIntent","result","sendFragmentedTransactionBLE","charUUID","data","dev","characteristic","receiveOfflineTransactionFragment","fragment","noiseDecryptFn","receiveFragmentedMessage","getBLEMTUConfig","getMTUConfig","setBLEMTUConfig","config","setMTUConfig"],"sourceRoot":"../../src","sources":["ble.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * BLE MTU Configuration for different device types
5
+ */
6
+
7
+ /**
8
+ * Default MTU configurations
9
+ */
10
+ const DEFAULT_MTU_CONFIGS = {
11
+ android: {
12
+ maxPayloadSize: 512,
13
+ // Typical Android BLE MTU
14
+ chunkSize: 480,
15
+ // Conservative chunk size
16
+ maxRetries: 3,
17
+ timeout: 5000
18
+ },
19
+ ios: {
20
+ maxPayloadSize: 512,
21
+ // iOS BLE MTU
22
+ chunkSize: 480,
23
+ maxRetries: 3,
24
+ timeout: 5000
25
+ }
26
+ };
27
+
28
+ /**
29
+ * Represents a fragmented message with header information
30
+ */
31
+
32
+ /**
33
+ * Represents a Noise-encrypted BLE message
34
+ */
35
+
36
+ /**
37
+ * BLETransactionHandler
38
+ * Manages secure, fragmented BLE transmission of offline transactions
39
+ * with Noise Protocol encryption
40
+ */
41
+ export class BLETransactionHandler {
42
+ fragmentCache = new Map();
43
+ messageIdMap = new Map();
44
+ constructor(platform = 'android') {
45
+ this.mtuConfig = DEFAULT_MTU_CONFIGS[platform] || DEFAULT_MTU_CONFIGS.android;
46
+ }
47
+
48
+ /**
49
+ * Fragment a large transaction/intent into BLE-safe chunks
50
+ * Respects MTU limitations and adds framing information
51
+ */
52
+ fragmentTransaction(transaction, isIntent = false) {
53
+ const payload = Buffer.from(JSON.stringify(transaction), 'utf-8');
54
+ const messageId = `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
55
+ const totalFragments = Math.ceil(payload.length / this.mtuConfig.chunkSize);
56
+ const fragments = [];
57
+ for (let i = 0; i < totalFragments; i++) {
58
+ const start = i * this.mtuConfig.chunkSize;
59
+ const end = Math.min(start + this.mtuConfig.chunkSize, payload.length);
60
+ const chunk = payload.slice(start, end);
61
+ const fragment = {
62
+ messageId,
63
+ sequenceNumber: i,
64
+ totalFragments,
65
+ checksumValue: this.calculateCRC32(chunk),
66
+ payload: chunk
67
+ };
68
+ fragments.push(fragment);
69
+ }
70
+
71
+ // Store fragments for reassembly on receiver end
72
+ this.fragmentCache.set(messageId, fragments);
73
+ this.messageIdMap.set(messageId, isIntent ? transaction : transaction);
74
+ return fragments;
75
+ }
76
+
77
+ /**
78
+ * Prepare encrypted BLE message for transmission
79
+ * Uses Noise Protocol for end-to-end encryption
80
+ */
81
+ async prepareEncryptedMessage(fragment, noiseEncryptFn) {
82
+ // Serialize fragment
83
+ const fragmentData = this.serializeFragment(fragment);
84
+
85
+ // Encrypt using Noise Protocol
86
+ const encrypted = await noiseEncryptFn(fragmentData);
87
+ return encrypted;
88
+ }
89
+
90
+ /**
91
+ * Send fragmented transaction over BLE with encryption
92
+ * Handles retries and verification
93
+ */
94
+ async sendFragmentedTransactionBLE(device, transaction, sendFn, noiseEncryptFn, isIntent = false) {
95
+ const fragments = this.fragmentTransaction(transaction, isIntent);
96
+ const messageId = fragments[0]?.messageId;
97
+ const failedFragments = [];
98
+ if (!messageId) {
99
+ throw new Error('Failed to generate message ID for transaction');
100
+ }
101
+ const CHARACTERISTIC_UUID = '0000ff02-0000-1000-8000-00805f9b34fb'; // Intent characteristic
102
+
103
+ for (const fragment of fragments) {
104
+ let retries = 0;
105
+ let sent = false;
106
+ while (retries < this.mtuConfig.maxRetries && !sent) {
107
+ try {
108
+ let messageData;
109
+ if (noiseEncryptFn) {
110
+ // Encrypt fragment using Noise Protocol
111
+ const encrypted = await this.prepareEncryptedMessage(fragment, noiseEncryptFn);
112
+ messageData = Buffer.from(JSON.stringify(encrypted), 'utf-8');
113
+ } else {
114
+ // Send unencrypted (not recommended)
115
+ messageData = Buffer.from(JSON.stringify(fragment), 'utf-8');
116
+ }
117
+
118
+ // Send via BLE
119
+ await sendFn(device.id, CHARACTERISTIC_UUID, messageData);
120
+ sent = true;
121
+ } catch (error) {
122
+ retries++;
123
+ console.warn(`Failed to send fragment ${fragment.sequenceNumber}, retry ${retries}:`, error);
124
+ if (retries >= this.mtuConfig.maxRetries) {
125
+ failedFragments.push(fragment.sequenceNumber);
126
+ } else {
127
+ // Exponential backoff
128
+ await this.delay(Math.pow(2, retries) * 100);
129
+ }
130
+ }
131
+ }
132
+ }
133
+ return {
134
+ success: failedFragments.length === 0,
135
+ sentFragments: fragments.length - failedFragments.length,
136
+ failedFragments,
137
+ messageId
138
+ };
139
+ }
140
+
141
+ /**
142
+ * Receive and reassemble fragmented messages
143
+ */
144
+ async receiveFragmentedMessage(fragment, _noiseDecryptFn) {
145
+ const messageId = fragment.messageId;
146
+
147
+ // Initialize or retrieve fragment cache
148
+ if (!this.fragmentCache.has(messageId)) {
149
+ this.fragmentCache.set(messageId, []);
150
+ }
151
+ const cachedFragments = this.fragmentCache.get(messageId);
152
+ cachedFragments[fragment.sequenceNumber] = fragment;
153
+ const progress = {
154
+ received: cachedFragments.filter(f => f !== undefined).length,
155
+ total: fragment.totalFragments
156
+ };
157
+
158
+ // Check if all fragments received
159
+ if (progress.received < fragment.totalFragments) {
160
+ return {
161
+ complete: false,
162
+ progress
163
+ };
164
+ }
165
+
166
+ // Reassemble message
167
+ const reassembled = this.reassembleMessage(cachedFragments);
168
+ if (!reassembled) {
169
+ return {
170
+ complete: false,
171
+ progress
172
+ };
173
+ }
174
+ try {
175
+ // Parse transaction
176
+ const transactionData = JSON.parse(reassembled);
177
+ const transaction = transactionData;
178
+
179
+ // Cleanup cache
180
+ this.fragmentCache.delete(messageId);
181
+ this.messageIdMap.delete(messageId);
182
+ return {
183
+ complete: true,
184
+ transaction,
185
+ progress
186
+ };
187
+ } catch (error) {
188
+ console.error('Failed to parse reassembled message:', error);
189
+ return {
190
+ complete: false,
191
+ progress
192
+ };
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Reassemble fragments into original message
198
+ */
199
+ reassembleMessage(fragments) {
200
+ try {
201
+ // Sort by sequence number
202
+ const sorted = fragments.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
203
+
204
+ // Verify all fragments present and checksums
205
+ for (const fragment of sorted) {
206
+ const calculatedChecksum = this.calculateCRC32(fragment.payload);
207
+ if (calculatedChecksum !== fragment.checksumValue) {
208
+ console.warn(`Checksum mismatch for fragment ${fragment.sequenceNumber}`);
209
+ return null;
210
+ }
211
+ }
212
+
213
+ // Concatenate payloads
214
+ const combined = Buffer.concat(sorted.map(f => Buffer.from(f.payload)));
215
+ return combined.toString('utf-8');
216
+ } catch (error) {
217
+ console.error('Failed to reassemble message:', error);
218
+ return null;
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Serialize BLE fragment for transmission
224
+ */
225
+ serializeFragment(fragment) {
226
+ const data = {
227
+ messageId: fragment.messageId,
228
+ sequenceNumber: fragment.sequenceNumber,
229
+ totalFragments: fragment.totalFragments,
230
+ checksumValue: fragment.checksumValue,
231
+ payload: Array.from(fragment.payload)
232
+ };
233
+ return new Uint8Array(Buffer.from(JSON.stringify(data), 'utf-8'));
234
+ }
235
+
236
+ /**
237
+ * Calculate CRC32 checksum for fragment verification
238
+ */
239
+ calculateCRC32(data) {
240
+ let crc = 0xffffffff;
241
+ for (let i = 0; i < data.length; i++) {
242
+ const byte = data[i];
243
+ if (byte !== undefined) {
244
+ crc = crc ^ byte;
245
+ for (let j = 0; j < 8; j++) {
246
+ crc = crc >>> 1 ^ (crc & 1 ? 0xedb88320 : 0);
247
+ }
248
+ }
249
+ }
250
+ return (crc ^ 0xffffffff) >>> 0;
251
+ }
252
+
253
+ /**
254
+ * Delay utility for retries
255
+ */
256
+ delay(ms) {
257
+ return new Promise(resolve => setTimeout(resolve, ms));
258
+ }
259
+
260
+ /**
261
+ * Get MTU configuration
262
+ */
263
+ getMTUConfig() {
264
+ return this.mtuConfig;
265
+ }
266
+
267
+ /**
268
+ * Set custom MTU configuration
269
+ */
270
+ setMTUConfig(config) {
271
+ this.mtuConfig = {
272
+ ...this.mtuConfig,
273
+ ...config
274
+ };
275
+ }
276
+ }
277
+ //# sourceMappingURL=BLETransactionHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_MTU_CONFIGS","android","maxPayloadSize","chunkSize","maxRetries","timeout","ios","BLETransactionHandler","fragmentCache","Map","messageIdMap","constructor","platform","mtuConfig","fragmentTransaction","transaction","isIntent","payload","Buffer","from","JSON","stringify","messageId","Date","now","Math","random","toString","substr","totalFragments","ceil","length","fragments","i","start","end","min","chunk","slice","fragment","sequenceNumber","checksumValue","calculateCRC32","push","set","prepareEncryptedMessage","noiseEncryptFn","fragmentData","serializeFragment","encrypted","sendFragmentedTransactionBLE","device","sendFn","failedFragments","Error","CHARACTERISTIC_UUID","retries","sent","messageData","id","error","console","warn","delay","pow","success","sentFragments","receiveFragmentedMessage","_noiseDecryptFn","has","cachedFragments","get","progress","received","filter","f","undefined","total","complete","reassembled","reassembleMessage","transactionData","parse","delete","sorted","sort","a","b","calculatedChecksum","combined","concat","map","data","Array","Uint8Array","crc","byte","j","ms","Promise","resolve","setTimeout","getMTUConfig","setMTUConfig","config"],"sourceRoot":"../../../src","sources":["client/BLETransactionHandler.ts"],"mappings":"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","ignoreList":[]}