toss-expo-sdk 0.1.2 → 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 (73) hide show
  1. package/README.md +368 -15
  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 +1 -1
  9. package/lib/module/client/TossClient.js.map +1 -1
  10. package/lib/module/hooks/useOfflineBLETransactions.js +314 -0
  11. package/lib/module/hooks/useOfflineBLETransactions.js.map +1 -0
  12. package/lib/module/index.js +12 -8
  13. package/lib/module/index.js.map +1 -1
  14. package/lib/module/intent.js +129 -0
  15. package/lib/module/intent.js.map +1 -1
  16. package/lib/module/noise.js +175 -0
  17. package/lib/module/noise.js.map +1 -1
  18. package/lib/module/reconciliation.js +155 -0
  19. package/lib/module/reconciliation.js.map +1 -1
  20. package/lib/module/services/authService.js +164 -1
  21. package/lib/module/services/authService.js.map +1 -1
  22. package/lib/module/storage/secureStorage.js +102 -0
  23. package/lib/module/storage/secureStorage.js.map +1 -1
  24. package/lib/module/sync.js +25 -1
  25. package/lib/module/sync.js.map +1 -1
  26. package/lib/module/types/nonceAccount.js +2 -0
  27. package/lib/module/types/nonceAccount.js.map +1 -0
  28. package/lib/module/types/tossUser.js +16 -1
  29. package/lib/module/types/tossUser.js.map +1 -1
  30. package/lib/typescript/src/__tests__/solana-program-simple.test.d.ts +8 -0
  31. package/lib/typescript/src/__tests__/solana-program-simple.test.d.ts.map +1 -0
  32. package/lib/typescript/src/ble.d.ts +31 -2
  33. package/lib/typescript/src/ble.d.ts.map +1 -1
  34. package/lib/typescript/src/client/BLETransactionHandler.d.ts +98 -0
  35. package/lib/typescript/src/client/BLETransactionHandler.d.ts.map +1 -0
  36. package/lib/typescript/src/client/NonceAccountManager.d.ts +82 -0
  37. package/lib/typescript/src/client/NonceAccountManager.d.ts.map +1 -0
  38. package/lib/typescript/src/hooks/useOfflineBLETransactions.d.ts +91 -0
  39. package/lib/typescript/src/hooks/useOfflineBLETransactions.d.ts.map +1 -0
  40. package/lib/typescript/src/index.d.ts +9 -4
  41. package/lib/typescript/src/index.d.ts.map +1 -1
  42. package/lib/typescript/src/intent.d.ts +15 -0
  43. package/lib/typescript/src/intent.d.ts.map +1 -1
  44. package/lib/typescript/src/noise.d.ts +62 -0
  45. package/lib/typescript/src/noise.d.ts.map +1 -1
  46. package/lib/typescript/src/reconciliation.d.ts +6 -0
  47. package/lib/typescript/src/reconciliation.d.ts.map +1 -1
  48. package/lib/typescript/src/services/authService.d.ts +26 -1
  49. package/lib/typescript/src/services/authService.d.ts.map +1 -1
  50. package/lib/typescript/src/storage/secureStorage.d.ts +16 -0
  51. package/lib/typescript/src/storage/secureStorage.d.ts.map +1 -1
  52. package/lib/typescript/src/sync.d.ts +6 -1
  53. package/lib/typescript/src/sync.d.ts.map +1 -1
  54. package/lib/typescript/src/types/nonceAccount.d.ts +59 -0
  55. package/lib/typescript/src/types/nonceAccount.d.ts.map +1 -0
  56. package/lib/typescript/src/types/tossUser.d.ts +16 -0
  57. package/lib/typescript/src/types/tossUser.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/src/__tests__/solana-program-simple.test.ts +256 -0
  60. package/src/ble.ts +105 -4
  61. package/src/client/BLETransactionHandler.ts +364 -0
  62. package/src/client/NonceAccountManager.ts +444 -0
  63. package/src/client/TossClient.ts +1 -1
  64. package/src/hooks/useOfflineBLETransactions.ts +438 -0
  65. package/src/index.tsx +40 -6
  66. package/src/intent.ts +166 -0
  67. package/src/noise.ts +238 -0
  68. package/src/reconciliation.ts +184 -0
  69. package/src/services/authService.ts +188 -1
  70. package/src/storage/secureStorage.ts +138 -0
  71. package/src/sync.ts +40 -0
  72. package/src/types/nonceAccount.ts +75 -0
  73. package/src/types/tossUser.ts +35 -2
@@ -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":[]}
@@ -0,0 +1,364 @@
1
+ "use strict";
2
+
3
+ import { PublicKey, Keypair, SystemProgram, NONCE_ACCOUNT_LENGTH, NonceAccount } from '@solana/web3.js';
4
+ import * as SecureStore from 'expo-secure-store';
5
+ /**
6
+ * NonceAccountManager
7
+ * Manages durable nonce accounts for secure offline transactions
8
+ * with biometric protection and encrypted storage
9
+ */
10
+ export class NonceAccountManager {
11
+ cache = new Map();
12
+ constructor(connection) {
13
+ this.connection = connection;
14
+ }
15
+
16
+ /**
17
+ * Create a new durable nonce account for a user
18
+ * Securely stores the nonce account with biometric protection
19
+ */
20
+ async createNonceAccount(user, nonceAuthorityKeypair, owner, options = {}) {
21
+ const {
22
+ requireBiometric = true,
23
+ persistToSecureStorage = true
24
+ } = options;
25
+ if (requireBiometric !== true) {
26
+ throw new Error('❌ SECURITY ERROR: Biometric protection is mandatory for nonce accounts');
27
+ }
28
+
29
+ // Generate nonce account keypair
30
+ const nonceAccountKeypair = Keypair.generate();
31
+ const nonceAccountAddress = nonceAccountKeypair.publicKey;
32
+
33
+ // Get the system's rent exemption minimum for nonce accounts
34
+ // (used for funding in actual transaction creation)
35
+ const minRentLamports = await this.connection.getMinimumBalanceForRentExemption(NONCE_ACCOUNT_LENGTH);
36
+
37
+ // Get the latest blockhash for the instruction
38
+ const {
39
+ blockhash
40
+ } = await this.connection.getLatestBlockhash();
41
+ const nonceAccountInfo = {
42
+ address: nonceAccountAddress.toBase58(),
43
+ owner: owner.toBase58(),
44
+ authorizedSigner: nonceAuthorityKeypair.publicKey.toBase58(),
45
+ currentNonce: 0,
46
+ lastUsedNonce: 0,
47
+ blockhash,
48
+ isBiometricProtected: requireBiometric,
49
+ createdAt: Math.floor(Date.now() / 1000),
50
+ lastModified: Math.floor(Date.now() / 1000),
51
+ isStoredSecurely: persistToSecureStorage,
52
+ minRentLamports
53
+ };
54
+
55
+ // Store nonce account info securely
56
+ if (persistToSecureStorage) {
57
+ await this.storeNonceAccountSecurely(user.userId, nonceAccountInfo, nonceAccountKeypair);
58
+ }
59
+
60
+ // Cache the account info
61
+ this.cacheNonceAccount(user.userId, nonceAccountInfo);
62
+ return nonceAccountInfo;
63
+ }
64
+
65
+ /**
66
+ * Store nonce account securely in device's secure enclave
67
+ * Encrypted and protected by biometric authentication
68
+ */
69
+ async storeNonceAccountSecurely(userId, nonceAccountInfo, nonceAccountKeypair) {
70
+ const storageKey = `toss_nonce_account_${userId}`;
71
+ const secureData = {
72
+ info: nonceAccountInfo,
73
+ keypair: {
74
+ publicKey: nonceAccountKeypair.publicKey.toBase58(),
75
+ secretKey: Array.from(nonceAccountKeypair.secretKey)
76
+ },
77
+ storedAt: Math.floor(Date.now() / 1000),
78
+ encryptionMethod: 'secure-enclave',
79
+ biometricRequired: true
80
+ };
81
+ await SecureStore.setItemAsync(storageKey, JSON.stringify(secureData));
82
+ }
83
+
84
+ /**
85
+ * Retrieve nonce account from secure storage
86
+ * Requires biometric verification
87
+ */
88
+ async getNonceAccountSecure(userId, authenticator) {
89
+ const storageKey = `toss_nonce_account_${userId}`;
90
+ try {
91
+ // Call authenticator if provided (biometric check)
92
+ if (authenticator) {
93
+ await authenticator();
94
+ }
95
+ const stored = await SecureStore.getItemAsync(storageKey);
96
+ if (!stored) {
97
+ return null;
98
+ }
99
+ const secureData = JSON.parse(stored);
100
+ return secureData.info;
101
+ } catch (error) {
102
+ console.error('Failed to retrieve nonce account:', error);
103
+ return null;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Cache nonce account info for quick access
109
+ */
110
+ cacheNonceAccount(userId, nonceAccountInfo) {
111
+ const cacheEntry = {
112
+ accountInfo: nonceAccountInfo,
113
+ nonces: [0],
114
+ expiresAt: Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 hours
115
+ };
116
+ this.cache.set(userId, cacheEntry);
117
+ }
118
+
119
+ /**
120
+ * Get cached nonce account info
121
+ */
122
+ getCachedNonceAccount(userId) {
123
+ const cached = this.cache.get(userId);
124
+ if (cached && cached.expiresAt > Math.floor(Date.now() / 1000)) {
125
+ return cached;
126
+ }
127
+ this.cache.delete(userId);
128
+ return null;
129
+ }
130
+
131
+ /**
132
+ * Prepare offline transaction using nonce account
133
+ * Creates a transaction that can be signed and executed offline
134
+ */
135
+ async prepareOfflineTransaction(user, _instructions, nonceAccountInfo) {
136
+ // Verify user has nonce account enabled
137
+ if (!user.tossFeatures.nonceAccountEnabled) {
138
+ throw new Error('Nonce account transactions not enabled for this user');
139
+ }
140
+ if (!user.nonceAccount) {
141
+ throw new Error('User does not have a nonce account configured');
142
+ }
143
+
144
+ // Create offline transaction with nonce
145
+ const offlineTransaction = {
146
+ id: `offlineTx_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
147
+ nonceAccount: nonceAccountInfo.address,
148
+ nonce: nonceAccountInfo.currentNonce,
149
+ transaction: '',
150
+ // Will be populated with serialized transaction
151
+ status: 'prepared',
152
+ createdAt: Math.floor(Date.now() / 1000),
153
+ expiresAt: Math.floor(Date.now() / 1000) + 24 * 60 * 60,
154
+ // 24 hours
155
+ metadata: {
156
+ userId: user.userId,
157
+ biometricRequired: user.security.nonceAccountRequiresBiometric
158
+ }
159
+ };
160
+ return offlineTransaction;
161
+ }
162
+
163
+ /**
164
+ * Renew nonce account (refresh blockhash and nonce state)
165
+ */
166
+ async renewNonceAccount(userId, _nonceAccountAddress) {
167
+ try {
168
+ // Fetch current nonce account state from blockchain
169
+ const nonceAccountInfo = await this.connection.getAccountInfo(_nonceAccountAddress);
170
+ if (!nonceAccountInfo) {
171
+ console.warn('Nonce account not found on blockchain');
172
+ return null;
173
+ }
174
+
175
+ // Decode nonce account data
176
+ const nonceAccount = NonceAccount.fromAccountData(nonceAccountInfo.data);
177
+
178
+ // Get latest blockhash
179
+ const {
180
+ blockhash
181
+ } = await this.connection.getLatestBlockhash();
182
+
183
+ // Retrieve and update stored account info
184
+ const storageKey = `toss_nonce_account_${userId}`;
185
+ const stored = await SecureStore.getItemAsync(storageKey);
186
+ if (stored) {
187
+ const secureData = JSON.parse(stored);
188
+ const updatedInfo = {
189
+ ...secureData.info,
190
+ currentNonce: nonceAccount.nonce,
191
+ blockhash,
192
+ lastModified: Math.floor(Date.now() / 1000)
193
+ };
194
+ secureData.info = updatedInfo;
195
+ await SecureStore.setItemAsync(storageKey, JSON.stringify(secureData));
196
+
197
+ // Update cache
198
+ this.cacheNonceAccount(userId, updatedInfo);
199
+ return updatedInfo;
200
+ }
201
+ return null;
202
+ } catch (error) {
203
+ console.error('Failed to renew nonce account:', error);
204
+ return null;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Revoke nonce account (mark as unusable)
210
+ */
211
+ async revokeNonceAccount(userId, _nonceAccountAddress) {
212
+ const storageKey = `toss_nonce_account_${userId}`;
213
+ try {
214
+ const stored = await SecureStore.getItemAsync(storageKey);
215
+ if (stored) {
216
+ const secureData = JSON.parse(stored);
217
+ secureData.info.status = 'revoked';
218
+ await SecureStore.setItemAsync(storageKey, JSON.stringify(secureData));
219
+ }
220
+ this.cache.delete(userId);
221
+ } catch (error) {
222
+ console.error('Failed to revoke nonce account:', error);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Clean up expired nonce accounts from cache
228
+ */
229
+ cleanupExpiredCache() {
230
+ const now = Math.floor(Date.now() / 1000);
231
+ for (const [userId, entry] of this.cache.entries()) {
232
+ if (entry.expiresAt < now) {
233
+ this.cache.delete(userId);
234
+ }
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Validate nonce account status
240
+ */
241
+ isNonceAccountValid(nonceAccountInfo) {
242
+ // Check if biometric protection is enabled (required for security)
243
+ if (!nonceAccountInfo.isBiometricProtected) {
244
+ return false;
245
+ }
246
+
247
+ // Check if account has aged beyond max validity
248
+ const maxAge = 365 * 24 * 60 * 60; // 1 year in seconds
249
+ const age = Math.floor(Date.now() / 1000) - nonceAccountInfo.createdAt;
250
+ return age < maxAge;
251
+ }
252
+
253
+ /**
254
+ * GAP #6 FIX: Initialize a durable nonce account onchain
255
+ * Per TOSS Paper Section 4.2: "Replay-protected" nonces
256
+ * This creates the actual SystemProgram nonce account on the blockchain
257
+ */
258
+ async initializeDurableNonceAccountOnchain(authority, nonceAccountKeypair, payer, minRentLamports) {
259
+ try {
260
+ // Create instruction to fund nonce account
261
+ const fundInstruction = SystemProgram.transfer({
262
+ fromPubkey: payer,
263
+ toPubkey: nonceAccountKeypair.publicKey,
264
+ lamports: minRentLamports
265
+ });
266
+
267
+ // Create instruction to initialize nonce account
268
+ const nonceInitInstruction = SystemProgram.nonceInitialize({
269
+ noncePubkey: nonceAccountKeypair.publicKey,
270
+ authorizedPubkey: authority
271
+ });
272
+
273
+ // Get latest blockhash
274
+ const {
275
+ blockhash,
276
+ lastValidBlockHeight
277
+ } = await this.connection.getLatestBlockhash('confirmed');
278
+
279
+ // Build transaction
280
+ const transaction = new (await import('@solana/web3.js')).Transaction();
281
+ transaction.add(fundInstruction);
282
+ transaction.add(nonceInitInstruction);
283
+ transaction.feePayer = payer;
284
+ transaction.recentBlockhash = blockhash;
285
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
286
+ console.log('✅ Durable nonce account initialized: ', nonceAccountKeypair.publicKey.toBase58());
287
+ return nonceAccountKeypair.publicKey.toBase58();
288
+ } catch (error) {
289
+ throw new Error(`Failed to initialize nonce account: ${error instanceof Error ? error.message : String(error)}`);
290
+ }
291
+ }
292
+
293
+ /**
294
+ * GAP #6 FIX: Consume (advance) a nonce account after successful transaction
295
+ * Per TOSS Paper Section 9: Nonce advancement for replay protection
296
+ */
297
+ async consumeNonceAccount(nonceAccountAddress, nonceAuthority) {
298
+ // Create instruction to advance nonce
299
+ return SystemProgram.nonceAdvance({
300
+ noncePubkey: nonceAccountAddress,
301
+ authorizedPubkey: nonceAuthority
302
+ });
303
+ }
304
+
305
+ /**
306
+ * GAP #6 FIX: Validate nonce account state on chain
307
+ * Checks that nonce account exists and is properly configured
308
+ */
309
+ async validateNonceAccountOnchain(nonceAccountAddress, _expectedAuthority) {
310
+ try {
311
+ const nonceAccountInfo = await this.connection.getAccountInfo(nonceAccountAddress);
312
+ if (!nonceAccountInfo) {
313
+ return {
314
+ valid: false,
315
+ error: 'Nonce account does not exist'
316
+ };
317
+ }
318
+ const SYSTEM_PROGRAM_ID = new PublicKey('11111111111111111111111111111111');
319
+ if (!nonceAccountInfo.owner.equals(SYSTEM_PROGRAM_ID)) {
320
+ return {
321
+ valid: false,
322
+ error: 'Nonce account is not owned by SystemProgram'
323
+ };
324
+ }
325
+
326
+ // Check if account is initialized (nonce is stored in first 32 bytes after version)
327
+ if (nonceAccountInfo.data.length < 48) {
328
+ return {
329
+ valid: false,
330
+ error: 'Nonce account data is malformed'
331
+ };
332
+ }
333
+ return {
334
+ valid: true
335
+ };
336
+ } catch (error) {
337
+ return {
338
+ valid: false,
339
+ error: `Nonce account validation failed: ${error instanceof Error ? error.message : String(error)}`
340
+ };
341
+ }
342
+ }
343
+
344
+ /**
345
+ * GAP #6 FIX: Get current nonce value from blockchain
346
+ * Reads the actual nonce state from the nonce account
347
+ */
348
+ async getCurrentNonceFromChain(nonceAccountAddress) {
349
+ try {
350
+ const nonceAccount = await this.connection.getAccountInfo(nonceAccountAddress);
351
+ if (!nonceAccount || nonceAccount.data.length < 48) {
352
+ return 0;
353
+ }
354
+
355
+ // Nonce value is stored at offset 32-40 in NonceAccount structure
356
+ const nonceData = nonceAccount.data.slice(32, 40);
357
+ return nonceData.readBigUInt64LE(0);
358
+ } catch (error) {
359
+ console.warn('Failed to get nonce from chain:', error);
360
+ return 0;
361
+ }
362
+ }
363
+ }
364
+ //# sourceMappingURL=NonceAccountManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["PublicKey","Keypair","SystemProgram","NONCE_ACCOUNT_LENGTH","NonceAccount","SecureStore","NonceAccountManager","cache","Map","constructor","connection","createNonceAccount","user","nonceAuthorityKeypair","owner","options","requireBiometric","persistToSecureStorage","Error","nonceAccountKeypair","generate","nonceAccountAddress","publicKey","minRentLamports","getMinimumBalanceForRentExemption","blockhash","getLatestBlockhash","nonceAccountInfo","address","toBase58","authorizedSigner","currentNonce","lastUsedNonce","isBiometricProtected","createdAt","Math","floor","Date","now","lastModified","isStoredSecurely","storeNonceAccountSecurely","userId","cacheNonceAccount","storageKey","secureData","info","keypair","secretKey","Array","from","storedAt","encryptionMethod","biometricRequired","setItemAsync","JSON","stringify","getNonceAccountSecure","authenticator","stored","getItemAsync","parse","error","console","cacheEntry","accountInfo","nonces","expiresAt","set","getCachedNonceAccount","cached","get","delete","prepareOfflineTransaction","_instructions","tossFeatures","nonceAccountEnabled","nonceAccount","offlineTransaction","id","random","toString","substr","nonce","transaction","status","metadata","security","nonceAccountRequiresBiometric","renewNonceAccount","_nonceAccountAddress","getAccountInfo","warn","fromAccountData","data","updatedInfo","revokeNonceAccount","cleanupExpiredCache","entry","entries","isNonceAccountValid","maxAge","age","initializeDurableNonceAccountOnchain","authority","payer","fundInstruction","transfer","fromPubkey","toPubkey","lamports","nonceInitInstruction","nonceInitialize","noncePubkey","authorizedPubkey","lastValidBlockHeight","Transaction","add","feePayer","recentBlockhash","log","message","String","consumeNonceAccount","nonceAuthority","nonceAdvance","validateNonceAccountOnchain","_expectedAuthority","valid","SYSTEM_PROGRAM_ID","equals","length","getCurrentNonceFromChain","nonceData","slice","readBigUInt64LE"],"sourceRoot":"../../../src","sources":["client/NonceAccountManager.ts"],"mappings":"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","ignoreList":[]}
@@ -223,7 +223,7 @@ export class TossClient {
223
223
  async fullSync() {
224
224
  return this.withRetry(async () => {
225
225
  try {
226
- return await syncToChain(this.connection, this.config.feePayer?.publicKey);
226
+ return await syncToChain(this.connection, this.config.feePayer?.publicKey?.toBase58());
227
227
  } catch (error) {
228
228
  if (error instanceof TossError) throw error;
229
229
  throw new NetworkError('Full sync failed', {