@dynamic-labs/solana 4.49.0 → 4.50.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.
- package/CHANGELOG.md +15 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +12 -12
- package/src/index.cjs +2 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/injected/walletStandard/createSolanaSignerFromWalletStandard/createSolanaSignerFromWalletStandard.cjs +17 -7
- package/src/injected/walletStandard/createSolanaSignerFromWalletStandard/createSolanaSignerFromWalletStandard.js +17 -7
- package/src/phantomRedirect/PhantomRedirect/PhantomRedirect.cjs +200 -63
- package/src/phantomRedirect/PhantomRedirect/PhantomRedirect.d.ts +18 -2
- package/src/phantomRedirect/PhantomRedirect/PhantomRedirect.js +202 -65
- package/src/phantomRedirect/storage/storage.cjs +77 -4
- package/src/phantomRedirect/storage/storage.d.ts +10 -0
- package/src/phantomRedirect/storage/storage.js +77 -4
- package/src/phantomRedirect/types.d.ts +1 -1
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.cjs +12 -11
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.js +13 -12
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
-
import {
|
|
3
|
+
import { Transaction, VersionedTransaction, PublicKey } from '@solana/web3.js';
|
|
4
4
|
import bs58 from 'bs58';
|
|
5
5
|
import nacl from 'tweetnacl';
|
|
6
6
|
import { SolanaWalletConnector } from '@dynamic-labs/solana-core';
|
|
7
|
-
import { StorageService, PHANTOM_REDIRECT_CONNECTION_TYPE_KEY
|
|
7
|
+
import { PlatformService, StorageService, PHANTOM_REDIRECT_CONNECTION_TYPE_KEY } from '@dynamic-labs/utils';
|
|
8
8
|
import { buildUrl } from '../buildUrl/buildUrl.js';
|
|
9
9
|
import { clearRedirectUrlForPhantom } from '../clearRedirectUrlForPhantom/clearRedirectUrlForPhantom.js';
|
|
10
10
|
import { decryptPayload } from '../decryptPayload/decryptPayload.js';
|
|
11
11
|
import { encryptPayload } from '../encryptPayload/encryptPayload.js';
|
|
12
12
|
import { storage, clearStorage } from '../storage/storage.js';
|
|
13
|
+
import { logger } from '../../utils/logger.js';
|
|
13
14
|
|
|
14
15
|
class PhantomRedirect extends SolanaWalletConnector {
|
|
15
16
|
constructor(props) {
|
|
@@ -20,6 +21,59 @@ class PhantomRedirect extends SolanaWalletConnector {
|
|
|
20
21
|
getMethod() {
|
|
21
22
|
throw new Error('Method not implemented.');
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Sets up a Promise/listener pattern for native mobile redirects.
|
|
26
|
+
* Returns undefined if not on native mobile.
|
|
27
|
+
*/
|
|
28
|
+
setupNativeMobileListener({ eventName, methodName, getResult, shouldIgnoreEvent, }) {
|
|
29
|
+
if (!PlatformService.isNativeMobile) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const requestId = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
33
|
+
storage.requestId.set(requestId);
|
|
34
|
+
logger.logVerboseTroubleshootingMessage(`[PhantomRedirect] ${methodName} - setting up listener`, { requestId });
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const listener = (event) => {
|
|
37
|
+
// Check requestId mismatch or custom validation
|
|
38
|
+
if (event.requestId !== requestId ||
|
|
39
|
+
(shouldIgnoreEvent === null || shouldIgnoreEvent === void 0 ? void 0 : shouldIgnoreEvent(event, requestId))) {
|
|
40
|
+
logger.logVerboseTroubleshootingMessage(`[PhantomRedirect] ${methodName} - ignoring event (requestId mismatch)`, {
|
|
41
|
+
expectedRequestId: requestId,
|
|
42
|
+
receivedRequestId: event.requestId,
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
logger.logVerboseTroubleshootingMessage(`[PhantomRedirect] ${methodName} - listener received matching event`, { errorCode: event.errorCode, requestId });
|
|
47
|
+
// Clean up this listener
|
|
48
|
+
this.off(eventName, listener);
|
|
49
|
+
if (event.errorCode) {
|
|
50
|
+
reject(new Error(event.errorMessage || event.errorCode));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
resolve(getResult(event));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
this.on(eventName, listener);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Encrypts payload, builds Phantom redirect URL, stores method, and opens URL.
|
|
61
|
+
*/
|
|
62
|
+
openPhantomUrl({ payload, sharedSecret, encryptionPublicKey, phantomEndpoint, methodToStore, }) {
|
|
63
|
+
const [nonce, encryptedPayload] = encryptPayload(payload, sharedSecret);
|
|
64
|
+
const params = new URLSearchParams({
|
|
65
|
+
dapp_encryption_public_key: bs58.encode(encryptionPublicKey),
|
|
66
|
+
nonce: bs58.encode(nonce),
|
|
67
|
+
payload: bs58.encode(encryptedPayload),
|
|
68
|
+
redirect_link: clearRedirectUrlForPhantom(PlatformService.getUrl()),
|
|
69
|
+
});
|
|
70
|
+
const url = buildUrl(phantomEndpoint, params);
|
|
71
|
+
storage.method.set(methodToStore);
|
|
72
|
+
logger.debug(`[PhantomRedirect] ${methodToStore} - opening Phantom`, {
|
|
73
|
+
isNativeMobile: PlatformService.isNativeMobile,
|
|
74
|
+
});
|
|
75
|
+
PlatformService.openURL(url);
|
|
76
|
+
}
|
|
23
77
|
getAddress() {
|
|
24
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
79
|
const address = storage.address.get();
|
|
@@ -83,36 +137,58 @@ class PhantomRedirect extends SolanaWalletConnector {
|
|
|
83
137
|
}
|
|
84
138
|
signMessage(messageToSign) {
|
|
85
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
logger.debug('[PhantomRedirect] signMessage called', {
|
|
141
|
+
messageLength: messageToSign.length,
|
|
142
|
+
messagePreview: messageToSign.substring(0, 200),
|
|
143
|
+
});
|
|
86
144
|
const { session, sharedSecret, encryptionPublicKey } = this.getInputsOrThrow('signMessage', [], ['session', 'sharedSecret', 'encryptionPublicKey']);
|
|
87
145
|
storage.message.set(messageToSign);
|
|
88
146
|
const payload = {
|
|
89
147
|
message: bs58.encode(Buffer.from(messageToSign)),
|
|
90
148
|
session,
|
|
91
149
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
150
|
+
this.openPhantomUrl({
|
|
151
|
+
encryptionPublicKey,
|
|
152
|
+
methodToStore: 'signMessage',
|
|
153
|
+
payload,
|
|
154
|
+
phantomEndpoint: 'signMessage',
|
|
155
|
+
sharedSecret,
|
|
98
156
|
});
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
//
|
|
109
|
-
//
|
|
157
|
+
const nativePromise = this.setupNativeMobileListener({
|
|
158
|
+
eventName: 'signMessage',
|
|
159
|
+
getResult: (event) => event.signature,
|
|
160
|
+
methodName: 'signMessage',
|
|
161
|
+
shouldIgnoreEvent: (event) => event.message !== messageToSign,
|
|
162
|
+
});
|
|
163
|
+
if (nativePromise) {
|
|
164
|
+
return nativePromise;
|
|
165
|
+
}
|
|
166
|
+
// On mobile web browsers, Phantom opens in a new tab and redirects back
|
|
167
|
+
// to a fresh page load, losing this Promise/listener context.
|
|
168
|
+
// The signature is handled via PhantomRedirectContext which reads URL
|
|
169
|
+
// params on page load and emits the 'signMessage' event, but there's
|
|
170
|
+
// no way to return it to the original caller. Throwing here prevents
|
|
171
|
+
// the SDK from clearing local storage when no signature is returned.
|
|
172
|
+
logger.debug('[PhantomRedirect] signMessage - mobile web, throwing ignore error');
|
|
110
173
|
throw new Error('ignore');
|
|
111
174
|
});
|
|
112
175
|
}
|
|
113
176
|
extractSignature() {
|
|
177
|
+
var _a;
|
|
178
|
+
logger.debug('[PhantomRedirect] extractSignature called');
|
|
114
179
|
const { data, nonce, sharedSecret, message } = this.getInputsOrThrow('extractSignature', ['data', 'nonce'], ['sharedSecret', 'message']);
|
|
180
|
+
logger.debug('[PhantomRedirect] extractSignature - retrieved from storage', {
|
|
181
|
+
dataPresent: Boolean(data),
|
|
182
|
+
message,
|
|
183
|
+
messageLength: message === null || message === void 0 ? void 0 : message.length,
|
|
184
|
+
noncePresent: Boolean(nonce),
|
|
185
|
+
sharedSecretPresent: Boolean(sharedSecret),
|
|
186
|
+
});
|
|
115
187
|
const signMessageData = decryptPayload(data, nonce, sharedSecret);
|
|
188
|
+
logger.debug('[PhantomRedirect] extractSignature - decrypted payload', {
|
|
189
|
+
signature: signMessageData.signature,
|
|
190
|
+
signatureLength: (_a = signMessageData.signature) === null || _a === void 0 ? void 0 : _a.length,
|
|
191
|
+
});
|
|
116
192
|
return {
|
|
117
193
|
message,
|
|
118
194
|
signature: signMessageData.signature,
|
|
@@ -127,14 +203,55 @@ class PhantomRedirect extends SolanaWalletConnector {
|
|
|
127
203
|
extractTransaction() {
|
|
128
204
|
const { data, nonce, sharedSecret } = this.getInputsOrThrow('extractTransaction', ['data', 'nonce'], ['sharedSecret']);
|
|
129
205
|
const signTransactionData = decryptPayload(data, nonce, sharedSecret);
|
|
130
|
-
const
|
|
131
|
-
|
|
206
|
+
const transactionBytes = bs58.decode(signTransactionData.transaction);
|
|
207
|
+
// Try to deserialize as VersionedTransaction first, fall back to legacy Transaction
|
|
208
|
+
// VersionedTransaction has a version prefix byte, legacy transactions don't
|
|
209
|
+
try {
|
|
210
|
+
return VersionedTransaction.deserialize(transactionBytes);
|
|
211
|
+
}
|
|
212
|
+
catch (_a) {
|
|
213
|
+
// If VersionedTransaction fails, try legacy Transaction
|
|
214
|
+
return Transaction.from(transactionBytes);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Extracts the signed transaction and sends it to the network.
|
|
219
|
+
* Used for signAndSendTransaction since Phantom redirect doesn't support it natively.
|
|
220
|
+
* @returns The transaction signature
|
|
221
|
+
*/
|
|
222
|
+
extractAndSendTransaction() {
|
|
223
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
224
|
+
logger.debug('[PhantomRedirect] extractAndSendTransaction called');
|
|
225
|
+
const signedTransaction = this.extractTransaction();
|
|
226
|
+
// Get stored send options if any
|
|
227
|
+
const sendOptionsJson = storage.sendOptions.get();
|
|
228
|
+
storage.sendOptions.remove();
|
|
229
|
+
const sendOptions = sendOptionsJson
|
|
230
|
+
? JSON.parse(sendOptionsJson)
|
|
231
|
+
: undefined;
|
|
232
|
+
logger.debug('[PhantomRedirect] Sending transaction to network', {
|
|
233
|
+
hasSendOptions: Boolean(sendOptions),
|
|
234
|
+
isVersioned: signedTransaction instanceof VersionedTransaction,
|
|
235
|
+
});
|
|
236
|
+
// Send the signed transaction to the network
|
|
237
|
+
const serialized = signedTransaction.serialize();
|
|
238
|
+
const signature = yield this.getWalletClient().sendRawTransaction(serialized, sendOptions);
|
|
239
|
+
logger.debug('[PhantomRedirect] Transaction sent successfully', {
|
|
240
|
+
signature,
|
|
241
|
+
});
|
|
242
|
+
return signature;
|
|
243
|
+
});
|
|
132
244
|
}
|
|
133
245
|
consumeMethod() {
|
|
134
246
|
const method = storage.method.get();
|
|
135
247
|
storage.method.remove();
|
|
136
248
|
return method;
|
|
137
249
|
}
|
|
250
|
+
consumeRequestId() {
|
|
251
|
+
const requestId = storage.requestId.get();
|
|
252
|
+
storage.requestId.remove();
|
|
253
|
+
return requestId;
|
|
254
|
+
}
|
|
138
255
|
getSigner() {
|
|
139
256
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
257
|
const address = storage.address.get();
|
|
@@ -197,55 +314,67 @@ class PhantomRedirect extends SolanaWalletConnector {
|
|
|
197
314
|
session,
|
|
198
315
|
transactions: serializedTransactions,
|
|
199
316
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
317
|
+
this.openPhantomUrl({
|
|
318
|
+
encryptionPublicKey,
|
|
319
|
+
methodToStore: 'signAllTransactions',
|
|
320
|
+
payload,
|
|
321
|
+
phantomEndpoint: 'signAllTransactions',
|
|
322
|
+
sharedSecret,
|
|
323
|
+
});
|
|
324
|
+
const nativePromise = this.setupNativeMobileListener({
|
|
325
|
+
eventName: 'signAllTransactions',
|
|
326
|
+
getResult: (event) => (event.transactions || []),
|
|
327
|
+
methodName: 'signAllTransactions',
|
|
206
328
|
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
329
|
+
if (nativePromise) {
|
|
330
|
+
return nativePromise;
|
|
331
|
+
}
|
|
332
|
+
// On mobile web browsers, return empty array
|
|
333
|
+
// The signed transactions are handled via PhantomRedirectContext
|
|
210
334
|
return [];
|
|
211
335
|
}),
|
|
212
336
|
signAndSendTransaction: (transaction, options) => __awaiter(this, void 0, void 0, function* () {
|
|
337
|
+
// Phantom redirect doesn't support signAndSendTransaction natively,
|
|
338
|
+
// so we use signTransaction and then send it manually after redirect
|
|
339
|
+
const serializedTransaction = bs58.encode(transaction.serialize({ requireAllSignatures: false }));
|
|
213
340
|
const { session, sharedSecret, encryptionPublicKey } = this.getInputsOrThrow('signAndSendTransaction', [], ['session', 'sharedSecret', 'encryptionPublicKey']);
|
|
214
341
|
const payload = {
|
|
215
|
-
options,
|
|
216
342
|
session,
|
|
217
|
-
transaction:
|
|
343
|
+
transaction: serializedTransaction,
|
|
218
344
|
};
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
345
|
+
// Store send options to use when sending the transaction
|
|
346
|
+
if (options) {
|
|
347
|
+
storage.sendOptions.set(JSON.stringify(options));
|
|
348
|
+
}
|
|
349
|
+
// Use signTransaction endpoint since Phantom redirect doesn't support signAndSendTransaction
|
|
350
|
+
// but store method as signAndSendTransaction so we know to send after signing
|
|
351
|
+
this.openPhantomUrl({
|
|
352
|
+
encryptionPublicKey,
|
|
353
|
+
methodToStore: 'signAndSendTransaction',
|
|
354
|
+
payload,
|
|
355
|
+
phantomEndpoint: 'signTransaction',
|
|
356
|
+
sharedSecret,
|
|
225
357
|
});
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
358
|
+
const nativePromise = this.setupNativeMobileListener({
|
|
359
|
+
eventName: 'signAndSendTransaction',
|
|
360
|
+
getResult: (event) => ({ signature: event.signature || '' }),
|
|
361
|
+
methodName: 'signAndSendTransaction',
|
|
362
|
+
});
|
|
363
|
+
if (nativePromise) {
|
|
364
|
+
return nativePromise;
|
|
365
|
+
}
|
|
366
|
+
// On mobile web browsers, return empty signature
|
|
367
|
+
// The actual signature is handled via PhantomRedirectContext
|
|
230
368
|
return { signature: '' };
|
|
231
369
|
}),
|
|
232
370
|
signMessage: (message) => __awaiter(this, void 0, void 0, function* () {
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
371
|
+
// Delegate to connector's signMessage which properly stores method and sets up listeners
|
|
372
|
+
const messageString = new TextDecoder().decode(message);
|
|
373
|
+
const signature = yield this.signMessage(messageString);
|
|
374
|
+
// Convert signature string to Uint8Array for ISolana interface
|
|
375
|
+
return {
|
|
376
|
+
signature: signature ? bs58.decode(signature) : new Uint8Array(0),
|
|
237
377
|
};
|
|
238
|
-
const [nonce, encryptedPayload] = encryptPayload(payload, sharedSecret);
|
|
239
|
-
const params = new URLSearchParams({
|
|
240
|
-
dapp_encryption_public_key: bs58.encode(encryptionPublicKey),
|
|
241
|
-
nonce: bs58.encode(nonce),
|
|
242
|
-
payload: bs58.encode(encryptedPayload),
|
|
243
|
-
redirect_link: clearRedirectUrlForPhantom(PlatformService.getUrl()),
|
|
244
|
-
});
|
|
245
|
-
const url = buildUrl('signMessage', params);
|
|
246
|
-
PlatformService.openURL(url);
|
|
247
|
-
// actual signature will be retrived upon redirect back to dapp
|
|
248
|
-
return { signature: Buffer.from('') };
|
|
249
378
|
}),
|
|
250
379
|
signTransaction: (transaction) => __awaiter(this, void 0, void 0, function* () {
|
|
251
380
|
const serializedTransaction = bs58.encode(transaction.serialize({
|
|
@@ -256,15 +385,23 @@ class PhantomRedirect extends SolanaWalletConnector {
|
|
|
256
385
|
session,
|
|
257
386
|
transaction: serializedTransaction,
|
|
258
387
|
};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
388
|
+
this.openPhantomUrl({
|
|
389
|
+
encryptionPublicKey,
|
|
390
|
+
methodToStore: 'signTransaction',
|
|
391
|
+
payload,
|
|
392
|
+
phantomEndpoint: 'signTransaction',
|
|
393
|
+
sharedSecret,
|
|
394
|
+
});
|
|
395
|
+
const nativePromise = this.setupNativeMobileListener({
|
|
396
|
+
eventName: 'signTransaction',
|
|
397
|
+
getResult: (event) => event.transaction,
|
|
398
|
+
methodName: 'signTransaction',
|
|
265
399
|
});
|
|
266
|
-
|
|
267
|
-
|
|
400
|
+
if (nativePromise) {
|
|
401
|
+
return nativePromise;
|
|
402
|
+
}
|
|
403
|
+
// On mobile web browsers, return the original transaction
|
|
404
|
+
// The signed transaction is handled via PhantomRedirectContext
|
|
268
405
|
return transaction;
|
|
269
406
|
}),
|
|
270
407
|
};
|
|
@@ -3,13 +3,26 @@
|
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
|
+
var logger = require('../../utils/logger.cjs');
|
|
7
|
+
|
|
6
8
|
const storage = {
|
|
7
9
|
address: {
|
|
8
|
-
get: () => {
|
|
10
|
+
get: () => {
|
|
11
|
+
var _a;
|
|
12
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_wallet_address')) !== null && _a !== void 0 ? _a : undefined;
|
|
13
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.get', {
|
|
14
|
+
value,
|
|
15
|
+
});
|
|
16
|
+
return value;
|
|
17
|
+
},
|
|
9
18
|
remove: () => {
|
|
19
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.remove');
|
|
10
20
|
localStorage.removeItem('dynamic_phantom_wallet_address');
|
|
11
21
|
},
|
|
12
22
|
set: (address) => {
|
|
23
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.set', {
|
|
24
|
+
address: address.toString(),
|
|
25
|
+
});
|
|
13
26
|
localStorage.setItem('dynamic_phantom_wallet_address', address.toString());
|
|
14
27
|
},
|
|
15
28
|
},
|
|
@@ -44,49 +57,109 @@ const storage = {
|
|
|
44
57
|
},
|
|
45
58
|
},
|
|
46
59
|
message: {
|
|
47
|
-
get: () => {
|
|
60
|
+
get: () => {
|
|
61
|
+
var _a;
|
|
62
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_message_to_sign')) !== null && _a !== void 0 ? _a : undefined;
|
|
63
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.get', {
|
|
64
|
+
hasMessage: Boolean(value),
|
|
65
|
+
messageLength: value === null || value === void 0 ? void 0 : value.length,
|
|
66
|
+
messagePreview: value === null || value === void 0 ? void 0 : value.substring(0, 100),
|
|
67
|
+
});
|
|
68
|
+
return value;
|
|
69
|
+
},
|
|
48
70
|
remove: () => {
|
|
71
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.remove');
|
|
49
72
|
localStorage.removeItem('dynamic_phantom_message_to_sign');
|
|
50
73
|
},
|
|
51
74
|
set: (message) => {
|
|
75
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.set', {
|
|
76
|
+
messageLength: message.length,
|
|
77
|
+
messagePreview: message.substring(0, 100),
|
|
78
|
+
});
|
|
52
79
|
localStorage.setItem('dynamic_phantom_message_to_sign', message);
|
|
53
80
|
},
|
|
54
81
|
},
|
|
55
82
|
method: {
|
|
56
|
-
get: () => {
|
|
83
|
+
get: () => {
|
|
84
|
+
var _a;
|
|
85
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_method')) !== null && _a !== void 0 ? _a : undefined;
|
|
86
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.get', {
|
|
87
|
+
value,
|
|
88
|
+
});
|
|
89
|
+
return value;
|
|
90
|
+
},
|
|
57
91
|
remove: () => {
|
|
92
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.remove');
|
|
58
93
|
localStorage.removeItem('dynamic_phantom_method');
|
|
59
94
|
},
|
|
60
95
|
set: (method) => {
|
|
96
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.set', {
|
|
97
|
+
method,
|
|
98
|
+
});
|
|
61
99
|
localStorage.setItem('dynamic_phantom_method', method);
|
|
62
100
|
},
|
|
63
101
|
},
|
|
102
|
+
requestId: {
|
|
103
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_request_id')) !== null && _a !== void 0 ? _a : undefined; },
|
|
104
|
+
remove: () => {
|
|
105
|
+
localStorage.removeItem('dynamic_phantom_request_id');
|
|
106
|
+
},
|
|
107
|
+
set: (requestId) => {
|
|
108
|
+
localStorage.setItem('dynamic_phantom_request_id', requestId);
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
sendOptions: {
|
|
112
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_send_options')) !== null && _a !== void 0 ? _a : undefined; },
|
|
113
|
+
remove: () => {
|
|
114
|
+
localStorage.removeItem('dynamic_phantom_send_options');
|
|
115
|
+
},
|
|
116
|
+
set: (options) => {
|
|
117
|
+
localStorage.setItem('dynamic_phantom_send_options', options);
|
|
118
|
+
},
|
|
119
|
+
},
|
|
64
120
|
session: {
|
|
65
|
-
get: () => {
|
|
121
|
+
get: () => {
|
|
122
|
+
var _a;
|
|
123
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_session')) !== null && _a !== void 0 ? _a : undefined;
|
|
124
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.get', {
|
|
125
|
+
hasSession: Boolean(value),
|
|
126
|
+
});
|
|
127
|
+
return value;
|
|
128
|
+
},
|
|
66
129
|
remove: () => {
|
|
130
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.remove');
|
|
67
131
|
localStorage.removeItem('dynamic_phantom_session');
|
|
68
132
|
},
|
|
69
133
|
set: (session) => {
|
|
134
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.set', {
|
|
135
|
+
session,
|
|
136
|
+
});
|
|
70
137
|
localStorage.setItem('dynamic_phantom_session', session);
|
|
71
138
|
},
|
|
72
139
|
},
|
|
73
140
|
sharedSecret: {
|
|
74
141
|
get: () => {
|
|
75
142
|
const rawSharedSecret = localStorage.getItem('dynamic_phantom_shared_secret');
|
|
143
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.get', { hasSharedSecret: Boolean(rawSharedSecret) });
|
|
76
144
|
if (!rawSharedSecret) {
|
|
77
145
|
return undefined;
|
|
78
146
|
}
|
|
79
147
|
return new Uint8Array(JSON.parse(rawSharedSecret));
|
|
80
148
|
},
|
|
81
149
|
remove: () => {
|
|
150
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.remove');
|
|
82
151
|
localStorage.removeItem('dynamic_phantom_shared_secret');
|
|
83
152
|
},
|
|
84
153
|
set: (sharedSecret) => {
|
|
154
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.set', {
|
|
155
|
+
sharedSecretLength: sharedSecret.length,
|
|
156
|
+
});
|
|
85
157
|
localStorage.setItem('dynamic_phantom_shared_secret', JSON.stringify([...sharedSecret]));
|
|
86
158
|
},
|
|
87
159
|
},
|
|
88
160
|
};
|
|
89
161
|
const clearStorage = () => {
|
|
162
|
+
logger.logger.logVerboseTroubleshootingMessage('[PhantomStorage] clearStorage called');
|
|
90
163
|
for (const key in storage) {
|
|
91
164
|
storage[key].remove();
|
|
92
165
|
}
|
|
@@ -26,6 +26,16 @@ export declare const storage: {
|
|
|
26
26
|
remove: () => void;
|
|
27
27
|
set: (method: Method) => void;
|
|
28
28
|
};
|
|
29
|
+
requestId: {
|
|
30
|
+
get: () => string | undefined;
|
|
31
|
+
remove: () => void;
|
|
32
|
+
set: (requestId: string) => void;
|
|
33
|
+
};
|
|
34
|
+
sendOptions: {
|
|
35
|
+
get: () => string | undefined;
|
|
36
|
+
remove: () => void;
|
|
37
|
+
set: (options: string) => void;
|
|
38
|
+
};
|
|
29
39
|
session: {
|
|
30
40
|
get: () => string | undefined;
|
|
31
41
|
remove: () => void;
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
'use client'
|
|
2
|
+
import { logger } from '../../utils/logger.js';
|
|
3
|
+
|
|
2
4
|
const storage = {
|
|
3
5
|
address: {
|
|
4
|
-
get: () => {
|
|
6
|
+
get: () => {
|
|
7
|
+
var _a;
|
|
8
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_wallet_address')) !== null && _a !== void 0 ? _a : undefined;
|
|
9
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.get', {
|
|
10
|
+
value,
|
|
11
|
+
});
|
|
12
|
+
return value;
|
|
13
|
+
},
|
|
5
14
|
remove: () => {
|
|
15
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.remove');
|
|
6
16
|
localStorage.removeItem('dynamic_phantom_wallet_address');
|
|
7
17
|
},
|
|
8
18
|
set: (address) => {
|
|
19
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] address.set', {
|
|
20
|
+
address: address.toString(),
|
|
21
|
+
});
|
|
9
22
|
localStorage.setItem('dynamic_phantom_wallet_address', address.toString());
|
|
10
23
|
},
|
|
11
24
|
},
|
|
@@ -40,49 +53,109 @@ const storage = {
|
|
|
40
53
|
},
|
|
41
54
|
},
|
|
42
55
|
message: {
|
|
43
|
-
get: () => {
|
|
56
|
+
get: () => {
|
|
57
|
+
var _a;
|
|
58
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_message_to_sign')) !== null && _a !== void 0 ? _a : undefined;
|
|
59
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.get', {
|
|
60
|
+
hasMessage: Boolean(value),
|
|
61
|
+
messageLength: value === null || value === void 0 ? void 0 : value.length,
|
|
62
|
+
messagePreview: value === null || value === void 0 ? void 0 : value.substring(0, 100),
|
|
63
|
+
});
|
|
64
|
+
return value;
|
|
65
|
+
},
|
|
44
66
|
remove: () => {
|
|
67
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.remove');
|
|
45
68
|
localStorage.removeItem('dynamic_phantom_message_to_sign');
|
|
46
69
|
},
|
|
47
70
|
set: (message) => {
|
|
71
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] message.set', {
|
|
72
|
+
messageLength: message.length,
|
|
73
|
+
messagePreview: message.substring(0, 100),
|
|
74
|
+
});
|
|
48
75
|
localStorage.setItem('dynamic_phantom_message_to_sign', message);
|
|
49
76
|
},
|
|
50
77
|
},
|
|
51
78
|
method: {
|
|
52
|
-
get: () => {
|
|
79
|
+
get: () => {
|
|
80
|
+
var _a;
|
|
81
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_method')) !== null && _a !== void 0 ? _a : undefined;
|
|
82
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.get', {
|
|
83
|
+
value,
|
|
84
|
+
});
|
|
85
|
+
return value;
|
|
86
|
+
},
|
|
53
87
|
remove: () => {
|
|
88
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.remove');
|
|
54
89
|
localStorage.removeItem('dynamic_phantom_method');
|
|
55
90
|
},
|
|
56
91
|
set: (method) => {
|
|
92
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] method.set', {
|
|
93
|
+
method,
|
|
94
|
+
});
|
|
57
95
|
localStorage.setItem('dynamic_phantom_method', method);
|
|
58
96
|
},
|
|
59
97
|
},
|
|
98
|
+
requestId: {
|
|
99
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_request_id')) !== null && _a !== void 0 ? _a : undefined; },
|
|
100
|
+
remove: () => {
|
|
101
|
+
localStorage.removeItem('dynamic_phantom_request_id');
|
|
102
|
+
},
|
|
103
|
+
set: (requestId) => {
|
|
104
|
+
localStorage.setItem('dynamic_phantom_request_id', requestId);
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
sendOptions: {
|
|
108
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_send_options')) !== null && _a !== void 0 ? _a : undefined; },
|
|
109
|
+
remove: () => {
|
|
110
|
+
localStorage.removeItem('dynamic_phantom_send_options');
|
|
111
|
+
},
|
|
112
|
+
set: (options) => {
|
|
113
|
+
localStorage.setItem('dynamic_phantom_send_options', options);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
60
116
|
session: {
|
|
61
|
-
get: () => {
|
|
117
|
+
get: () => {
|
|
118
|
+
var _a;
|
|
119
|
+
const value = (_a = localStorage.getItem('dynamic_phantom_session')) !== null && _a !== void 0 ? _a : undefined;
|
|
120
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.get', {
|
|
121
|
+
hasSession: Boolean(value),
|
|
122
|
+
});
|
|
123
|
+
return value;
|
|
124
|
+
},
|
|
62
125
|
remove: () => {
|
|
126
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.remove');
|
|
63
127
|
localStorage.removeItem('dynamic_phantom_session');
|
|
64
128
|
},
|
|
65
129
|
set: (session) => {
|
|
130
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] session.set', {
|
|
131
|
+
session,
|
|
132
|
+
});
|
|
66
133
|
localStorage.setItem('dynamic_phantom_session', session);
|
|
67
134
|
},
|
|
68
135
|
},
|
|
69
136
|
sharedSecret: {
|
|
70
137
|
get: () => {
|
|
71
138
|
const rawSharedSecret = localStorage.getItem('dynamic_phantom_shared_secret');
|
|
139
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.get', { hasSharedSecret: Boolean(rawSharedSecret) });
|
|
72
140
|
if (!rawSharedSecret) {
|
|
73
141
|
return undefined;
|
|
74
142
|
}
|
|
75
143
|
return new Uint8Array(JSON.parse(rawSharedSecret));
|
|
76
144
|
},
|
|
77
145
|
remove: () => {
|
|
146
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.remove');
|
|
78
147
|
localStorage.removeItem('dynamic_phantom_shared_secret');
|
|
79
148
|
},
|
|
80
149
|
set: (sharedSecret) => {
|
|
150
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] sharedSecret.set', {
|
|
151
|
+
sharedSecretLength: sharedSecret.length,
|
|
152
|
+
});
|
|
81
153
|
localStorage.setItem('dynamic_phantom_shared_secret', JSON.stringify([...sharedSecret]));
|
|
82
154
|
},
|
|
83
155
|
},
|
|
84
156
|
};
|
|
85
157
|
const clearStorage = () => {
|
|
158
|
+
logger.logVerboseTroubleshootingMessage('[PhantomStorage] clearStorage called');
|
|
86
159
|
for (const key in storage) {
|
|
87
160
|
storage[key].remove();
|
|
88
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type Method = 'signMessage' | 'signAndSendTransaction';
|
|
1
|
+
export type Method = 'signMessage' | 'signTransaction' | 'signAllTransactions' | 'signAndSendTransaction';
|