@solana-mobile/mobile-wallet-adapter-protocol 2.0.1 → 2.0.2

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.
@@ -8,7 +8,7 @@ buildscript {
8
8
  }
9
9
 
10
10
  dependencies {
11
- classpath 'com.android.tools.build:gradle:7.4.2'
11
+ classpath 'com.android.tools.build:gradle:8.2.0'
12
12
  // noinspection DifferentKotlinGradleVersion
13
13
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
14
  }
@@ -132,9 +132,9 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
132
132
  dependencies {
133
133
  //noinspection GradleDynamicVersion
134
134
  implementation "com.facebook.react:react-native:+" // From node_modules
135
- implementation "com.solanamobile:mobile-wallet-adapter-clientlib:1.1.0"
135
+ implementation "com.solanamobile:mobile-wallet-adapter-clientlib:2.0.0"
136
136
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
137
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1"
137
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
138
138
  }
139
139
 
140
140
  if (isNewArchitectureEnabled()) {
@@ -10,6 +10,7 @@ import com.solana.mobilewalletadapter.clientlib.protocol.JsonRpc20Client
10
10
  import com.solana.mobilewalletadapter.clientlib.protocol.MobileWalletAdapterClient
11
11
  import com.solana.mobilewalletadapter.clientlib.scenario.LocalAssociationIntentCreator
12
12
  import com.solana.mobilewalletadapter.clientlib.scenario.LocalAssociationScenario
13
+ import com.solana.mobilewalletadapter.common.protocol.SessionProperties.ProtocolVersion
13
14
  import com.solanamobile.mobilewalletadapter.reactnative.JSONSerializationUtils.convertJsonToMap
14
15
  import com.solanamobile.mobilewalletadapter.reactnative.JSONSerializationUtils.convertMapToJson
15
16
  import kotlinx.coroutines.*
@@ -38,9 +39,9 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
38
39
  // Used to ensure that you can't start more than one session at a time.
39
40
  private val mutex: Mutex = Mutex()
40
41
  private var sessionState: SessionState? = null
42
+ private var associationResultCallback: ((Int) -> Unit)? = null
41
43
  }
42
44
 
43
- private val mActivityEventCallbacks = mutableMapOf<Int, (Int, Intent?) -> (Unit)>()
44
45
  private val mActivityEventListener: ActivityEventListener =
45
46
  object : BaseActivityEventListener() {
46
47
  override fun onActivityResult(
@@ -49,10 +50,8 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
49
50
  resultCode: Int,
50
51
  data: Intent?
51
52
  ) {
52
- mActivityEventCallbacks[requestCode]?.let { callback ->
53
- callback(resultCode, data)
54
- mActivityEventCallbacks.remove(requestCode)
55
- }
53
+ if (requestCode == REQUEST_LOCAL_ASSOCIATION)
54
+ associationResultCallback?.invoke(resultCode)
56
55
  }
57
56
  }
58
57
 
@@ -78,7 +77,7 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
78
77
  localAssociation.port,
79
78
  localAssociation.session
80
79
  )
81
- launchIntent(intent, REQUEST_LOCAL_ASSOCIATION) { resultCode, _ ->
80
+ associationResultCallback = { resultCode ->
82
81
  if (resultCode == Activity.RESULT_CANCELED) {
83
82
  Log.d(name, "Local association cancelled by user, ending session")
84
83
  promise.reject("Session not established: Local association cancelled by user",
@@ -86,10 +85,18 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
86
85
  localAssociation.close()
87
86
  }
88
87
  }
88
+ currentActivity?.startActivityForResult(intent, REQUEST_LOCAL_ASSOCIATION)
89
+ ?: throw NullPointerException("Could not find a current activity from which to launch a local association")
89
90
  val client =
90
91
  localAssociation.start().get(ASSOCIATION_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
91
92
  sessionState = SessionState(client, localAssociation)
92
- promise.resolve(true)
93
+ val sessionPropertiesMap: WritableMap = WritableNativeMap()
94
+ sessionPropertiesMap.putString("protocol_version",
95
+ when (localAssociation.session.sessionProperties.protocolVersion) {
96
+ ProtocolVersion.LEGACY -> "legacy"
97
+ ProtocolVersion.V1 -> "v1"
98
+ })
99
+ promise.resolve(sessionPropertiesMap)
93
100
  } catch (e: ActivityNotFoundException) {
94
101
  Log.e(name, "Found no installed wallet that supports the mobile wallet protocol", e)
95
102
  cleanup()
@@ -129,6 +136,8 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
129
136
  val userInfo = Arguments.createMap()
130
137
  userInfo.putInt("jsonRpcErrorCode", cause.code)
131
138
  promise.reject("JSON_RPC_ERROR", cause, userInfo)
139
+ } else if (cause is TimeoutException) {
140
+ promise.reject("Timed out waiting for response", e)
132
141
  } else {
133
142
  throw e
134
143
  }
@@ -159,16 +168,9 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
159
168
  }
160
169
  } ?: throw NullPointerException("Tried to end a session without an active session")
161
170
 
162
- private fun launchIntent(intent: Intent, requestCode: Int, callback: (Int, Intent?) -> (Unit)) {
163
- mActivityEventCallbacks[requestCode] = callback
164
- currentActivity?.startActivityForResult(intent, REQUEST_LOCAL_ASSOCIATION) ?: run {
165
- mActivityEventCallbacks.remove(requestCode)
166
- throw NullPointerException("Could not find a current activity from which to launch a local association")
167
- }
168
- }
169
-
170
171
  private fun cleanup() {
171
172
  sessionState = null
173
+ associationResultCallback = null
172
174
  if (mutex.isLocked) {
173
175
  mutex.unlock()
174
176
  }
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var walletStandardUtil = require('@solana/wallet-standard-util');
6
+
5
7
  // Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
6
8
  const SolanaMobileWalletAdapterErrorCode = {
7
9
  ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',
@@ -10,6 +12,7 @@ const SolanaMobileWalletAdapterErrorCode = {
10
12
  ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',
11
13
  ERROR_SESSION_TIMEOUT: 'ERROR_SESSION_TIMEOUT',
12
14
  ERROR_WALLET_NOT_FOUND: 'ERROR_WALLET_NOT_FOUND',
15
+ ERROR_INVALID_PROTOCOL_VERSION: 'ERROR_INVALID_PROTOCOL_VERSION',
13
16
  };
14
17
  class SolanaMobileWalletAdapterError extends Error {
15
18
  constructor(...args) {
@@ -77,6 +80,175 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
77
80
  });
78
81
  }
79
82
 
83
+ function encode(input) {
84
+ return window.btoa(input);
85
+ }
86
+
87
+ function createSIWSMessage(payload) {
88
+ return walletStandardUtil.createSignInMessageText(payload);
89
+ }
90
+ function createSIWSMessageBase64(payload) {
91
+ return encode(createSIWSMessage(payload));
92
+ }
93
+
94
+ // optional features
95
+ const SolanaSignTransactions = 'solana:signTransactions';
96
+ const SolanaCloneAuthorization = 'solana:cloneAuthorization';
97
+ const SolanaSignInWithSolana = 'solana:signInWithSolana';
98
+
99
+ /**
100
+ * Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
101
+ *
102
+ * @param protocolVersion the protocol version in use for this session/request
103
+ * @param protocolRequestHandler callback function that handles sending the RPC request to the wallet endpoint.
104
+ * @returns a {@link MobileWallet} proxy
105
+ */
106
+ function createMobileWalletProxy(protocolVersion, protocolRequestHandler) {
107
+ return new Proxy({}, {
108
+ get(target, p) {
109
+ if (target[p] == null) {
110
+ target[p] = function (inputParams) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);
113
+ const result = yield protocolRequestHandler(method, params);
114
+ // if the request tried to sign in but the wallet did not return a sign in result, fallback on message signing
115
+ if (method === 'authorize' && params.sign_in_payload && !result.sign_in_result) {
116
+ result['sign_in_result'] = yield signInFallback(params.sign_in_payload, result, protocolRequestHandler);
117
+ }
118
+ return handleMobileWalletResponse(p, result, protocolVersion);
119
+ });
120
+ };
121
+ }
122
+ return target[p];
123
+ },
124
+ defineProperty() {
125
+ return false;
126
+ },
127
+ deleteProperty() {
128
+ return false;
129
+ },
130
+ });
131
+ }
132
+ /**
133
+ * Handles all {@link MobileWallet} API requests and determines the correct MWA RPC method and params to call.
134
+ * This handles backwards compatibility, based on the provided @protocolVersion.
135
+ *
136
+ * @param methodName the name of {@link MobileWallet} method that was called
137
+ * @param methodParams the parameters that were passed to the method
138
+ * @param protocolVersion the protocol version in use for this session/request
139
+ * @returns the RPC request method and params that should be sent to the wallet endpoint
140
+ */
141
+ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
142
+ let params = methodParams;
143
+ let method = methodName
144
+ .toString()
145
+ .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
146
+ .toLowerCase();
147
+ switch (methodName) {
148
+ case 'authorize': {
149
+ let { chain } = params;
150
+ if (protocolVersion === 'legacy') {
151
+ switch (chain) {
152
+ case 'solana:testnet': {
153
+ chain = 'testnet';
154
+ break;
155
+ }
156
+ case 'solana:devnet': {
157
+ chain = 'devnet';
158
+ break;
159
+ }
160
+ case 'solana:mainnet': {
161
+ chain = 'mainnet-beta';
162
+ break;
163
+ }
164
+ default: {
165
+ chain = params.cluster;
166
+ }
167
+ }
168
+ params.cluster = chain;
169
+ }
170
+ else {
171
+ switch (chain) {
172
+ case 'testnet':
173
+ case 'devnet': {
174
+ chain = `solana:${chain}`;
175
+ break;
176
+ }
177
+ case 'mainnet-beta': {
178
+ chain = 'solana:mainnet';
179
+ break;
180
+ }
181
+ }
182
+ params.chain = chain;
183
+ }
184
+ }
185
+ case 'reauthorize': {
186
+ const { auth_token, identity } = params;
187
+ if (auth_token) {
188
+ switch (protocolVersion) {
189
+ case 'legacy': {
190
+ method = 'reauthorize';
191
+ params = { auth_token: auth_token, identity: identity };
192
+ break;
193
+ }
194
+ default: {
195
+ method = 'authorize';
196
+ break;
197
+ }
198
+ }
199
+ }
200
+ break;
201
+ }
202
+ }
203
+ return { method, params };
204
+ }
205
+ /**
206
+ * Handles all {@link MobileWallet} API responses and modifies the response for backwards compatibility, if needed
207
+ *
208
+ * @param method the {@link MobileWallet} method that was called
209
+ * @param response the original response that was returned by the method call
210
+ * @param protocolVersion the protocol version in use for this session/request
211
+ * @returns the possibly modified response
212
+ */
213
+ function handleMobileWalletResponse(method, response, protocolVersion) {
214
+ switch (method) {
215
+ case 'getCapabilities': {
216
+ const capabilities = response;
217
+ switch (protocolVersion) {
218
+ case 'legacy': {
219
+ const features = [SolanaSignTransactions];
220
+ if (capabilities.supports_clone_authorization === true) {
221
+ features.push(SolanaCloneAuthorization);
222
+ }
223
+ return Object.assign(Object.assign({}, capabilities), { features: features });
224
+ }
225
+ case 'v1': {
226
+ return Object.assign(Object.assign({}, capabilities), { supports_sign_and_send_transactions: true, supports_clone_authorization: capabilities.features.includes(SolanaCloneAuthorization) });
227
+ }
228
+ }
229
+ }
230
+ }
231
+ return response;
232
+ }
233
+ function signInFallback(signInPayload, authorizationResult, protocolRequestHandler) {
234
+ var _a;
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
237
+ const address = authorizationResult.accounts[0].address;
238
+ const siwsMessage = createSIWSMessageBase64(Object.assign(Object.assign({}, signInPayload), { domain, address }));
239
+ const signMessageResult = yield protocolRequestHandler('sign_messages', {
240
+ addresses: [address],
241
+ payloads: [siwsMessage]
242
+ });
243
+ const signInResult = {
244
+ address: address,
245
+ signed_message: siwsMessage,
246
+ signature: signMessageResult.signed_payloads[0].slice(siwsMessage.length)
247
+ };
248
+ return signInResult;
249
+ });
250
+ }
251
+
80
252
  const SEQUENCE_NUMBER_BYTES = 4;
81
253
  function createSequenceNumberVector(sequenceNumber) {
82
254
  if (sequenceNumber >= 4294967296) {
@@ -88,29 +260,11 @@ function createSequenceNumberVector(sequenceNumber) {
88
260
  return new Uint8Array(byteArray);
89
261
  }
90
262
 
91
- function generateAssociationKeypair() {
92
- return __awaiter(this, void 0, void 0, function* () {
93
- return yield crypto.subtle.generateKey({
94
- name: 'ECDSA',
95
- namedCurve: 'P-256',
96
- }, false /* extractable */, ['sign'] /* keyUsages */);
97
- });
98
- }
99
-
100
- function generateECDHKeypair() {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- return yield crypto.subtle.generateKey({
103
- name: 'ECDH',
104
- namedCurve: 'P-256',
105
- }, false /* extractable */, ['deriveKey', 'deriveBits'] /* keyUsages */);
106
- });
107
- }
108
-
109
263
  const INITIALIZATION_VECTOR_BYTES = 12;
110
- function encryptJsonRpcMessage(jsonRpcMessage, sharedSecret) {
264
+ const ENCODED_PUBLIC_KEY_LENGTH_BYTES = 65;
265
+ function encryptMessage(plaintext, sequenceNumber, sharedSecret) {
111
266
  return __awaiter(this, void 0, void 0, function* () {
112
- const plaintext = JSON.stringify(jsonRpcMessage);
113
- const sequenceNumberVector = createSequenceNumberVector(jsonRpcMessage.id);
267
+ const sequenceNumberVector = createSequenceNumberVector(sequenceNumber);
114
268
  const initializationVector = new Uint8Array(INITIALIZATION_VECTOR_BYTES);
115
269
  crypto.getRandomValues(initializationVector);
116
270
  const ciphertext = yield crypto.subtle.encrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, new TextEncoder().encode(plaintext));
@@ -121,18 +275,14 @@ function encryptJsonRpcMessage(jsonRpcMessage, sharedSecret) {
121
275
  return response;
122
276
  });
123
277
  }
124
- function decryptJsonRpcMessage(message, sharedSecret) {
278
+ function decryptMessage(message, sharedSecret) {
125
279
  return __awaiter(this, void 0, void 0, function* () {
126
280
  const sequenceNumberVector = message.slice(0, SEQUENCE_NUMBER_BYTES);
127
281
  const initializationVector = message.slice(SEQUENCE_NUMBER_BYTES, SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);
128
282
  const ciphertext = message.slice(SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);
129
283
  const plaintextBuffer = yield crypto.subtle.decrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, ciphertext);
130
284
  const plaintext = getUtf8Decoder().decode(plaintextBuffer);
131
- const jsonRpcMessage = JSON.parse(plaintext);
132
- if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {
133
- throw new SolanaMobileWalletAdapterProtocolError(jsonRpcMessage.id, jsonRpcMessage.error.code, jsonRpcMessage.error.message);
134
- }
135
- return jsonRpcMessage;
285
+ return plaintext;
136
286
  });
137
287
  }
138
288
  function getAlgorithmParams(sequenceNumber, initializationVector) {
@@ -151,12 +301,48 @@ function getUtf8Decoder() {
151
301
  return _utf8Decoder;
152
302
  }
153
303
 
304
+ function generateAssociationKeypair() {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ return yield crypto.subtle.generateKey({
307
+ name: 'ECDSA',
308
+ namedCurve: 'P-256',
309
+ }, false /* extractable */, ['sign'] /* keyUsages */);
310
+ });
311
+ }
312
+
313
+ function generateECDHKeypair() {
314
+ return __awaiter(this, void 0, void 0, function* () {
315
+ return yield crypto.subtle.generateKey({
316
+ name: 'ECDH',
317
+ namedCurve: 'P-256',
318
+ }, false /* extractable */, ['deriveKey', 'deriveBits'] /* keyUsages */);
319
+ });
320
+ }
321
+
322
+ function encryptJsonRpcMessage(jsonRpcMessage, sharedSecret) {
323
+ return __awaiter(this, void 0, void 0, function* () {
324
+ const plaintext = JSON.stringify(jsonRpcMessage);
325
+ const sequenceNumber = jsonRpcMessage.id;
326
+ return encryptMessage(plaintext, sequenceNumber, sharedSecret);
327
+ });
328
+ }
329
+ function decryptJsonRpcMessage(message, sharedSecret) {
330
+ return __awaiter(this, void 0, void 0, function* () {
331
+ const plaintext = yield decryptMessage(message, sharedSecret);
332
+ const jsonRpcMessage = JSON.parse(plaintext);
333
+ if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {
334
+ throw new SolanaMobileWalletAdapterProtocolError(jsonRpcMessage.id, jsonRpcMessage.error.code, jsonRpcMessage.error.message);
335
+ }
336
+ return jsonRpcMessage;
337
+ });
338
+ }
339
+
154
340
  function parseHelloRsp(payloadBuffer, // The X9.62-encoded wallet endpoint ephemeral ECDH public keypoint.
155
341
  associationPublicKey, ecdhPrivateKey) {
156
342
  return __awaiter(this, void 0, void 0, function* () {
157
343
  const [associationPublicKeyBuffer, walletPublicKey] = yield Promise.all([
158
344
  crypto.subtle.exportKey('raw', associationPublicKey),
159
- crypto.subtle.importKey('raw', payloadBuffer, { name: 'ECDH', namedCurve: 'P-256' }, false /* extractable */, [] /* keyUsages */),
345
+ crypto.subtle.importKey('raw', payloadBuffer.slice(0, ENCODED_PUBLIC_KEY_LENGTH_BYTES), { name: 'ECDH', namedCurve: 'P-256' }, false /* extractable */, [] /* keyUsages */),
160
346
  ]);
161
347
  const sharedSecret = yield crypto.subtle.deriveBits({ name: 'ECDH', public: walletPublicKey }, ecdhPrivateKey, 256);
162
348
  const ecdhSecretKey = yield crypto.subtle.importKey('raw', sharedSecret, 'HKDF', false /* extractable */, ['deriveKey'] /* keyUsages */);
@@ -170,6 +356,31 @@ associationPublicKey, ecdhPrivateKey) {
170
356
  });
171
357
  }
172
358
 
359
+ function parseSessionProps(message, sharedSecret) {
360
+ return __awaiter(this, void 0, void 0, function* () {
361
+ const plaintext = yield decryptMessage(message, sharedSecret);
362
+ const jsonProperties = JSON.parse(plaintext);
363
+ let protocolVersion = 'legacy';
364
+ if (Object.hasOwnProperty.call(jsonProperties, 'v')) {
365
+ switch (jsonProperties.v) {
366
+ case 1:
367
+ case '1':
368
+ case 'v1':
369
+ protocolVersion = 'v1';
370
+ break;
371
+ case 'legacy':
372
+ protocolVersion = 'legacy';
373
+ break;
374
+ default:
375
+ throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION, `Unknown/unsupported protocol version: ${jsonProperties.v}`);
376
+ }
377
+ }
378
+ return ({
379
+ protocol_version: protocolVersion
380
+ });
381
+ });
382
+ }
383
+
173
384
  function getRandomAssociationPort() {
174
385
  return assertAssociationPort(49152 + Math.floor(Math.random() * (65535 - 49152 + 1)));
175
386
  }
@@ -226,7 +437,7 @@ function getIntentURL(methodPathname, intentUrlBase) {
226
437
  [...getPathParts(baseUrl.pathname), ...getPathParts(methodPathname)].join('/');
227
438
  return new URL(pathname, baseUrl);
228
439
  }
229
- function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associationURLBase) {
440
+ function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associationURLBase, protocolVersions = ['v1']) {
230
441
  return __awaiter(this, void 0, void 0, function* () {
231
442
  const associationPort = assertAssociationPort(putativePort);
232
443
  const exportedKey = yield crypto.subtle.exportKey('raw', associationPublicKey);
@@ -234,6 +445,9 @@ function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associ
234
445
  const url = getIntentURL('v1/associate/local', associationURLBase);
235
446
  url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
236
447
  url.searchParams.set('port', `${associationPort}`);
448
+ protocolVersions.forEach((version) => {
449
+ url.searchParams.set('v', version);
450
+ });
237
451
  return url;
238
452
  });
239
453
  }
@@ -438,59 +652,51 @@ function transact(callback, config) {
438
652
  break;
439
653
  case 'hello_req_sent': {
440
654
  const sharedSecret = yield parseHelloRsp(responseBuffer, state.associationPublicKey, state.ecdhPrivateKey);
441
- state = { __type: 'connected', sharedSecret };
442
- const wallet = new Proxy({}, {
443
- get(target, p) {
444
- if (target[p] == null) {
445
- const method = p
446
- .toString()
447
- .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
448
- .toLowerCase();
449
- target[p] = function (params) {
450
- return __awaiter(this, void 0, void 0, function* () {
451
- const id = nextJsonRpcMessageId++;
452
- socket.send(yield encryptJsonRpcMessage({
453
- id,
454
- jsonrpc: '2.0',
455
- method,
456
- params: params !== null && params !== void 0 ? params : {},
457
- }, sharedSecret));
458
- return new Promise((resolve, reject) => {
459
- jsonRpcResponsePromises[id] = {
460
- resolve(result) {
461
- switch (p) {
462
- case 'authorize':
463
- case 'reauthorize': {
464
- const { wallet_uri_base } = result;
465
- if (wallet_uri_base != null) {
466
- try {
467
- assertSecureEndpointSpecificURI(wallet_uri_base);
468
- }
469
- catch (e) {
470
- reject(e);
471
- return;
472
- }
473
- }
474
- break;
475
- }
476
- }
477
- resolve(result);
478
- },
479
- reject,
480
- };
481
- });
482
- });
483
- };
655
+ const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);
656
+ const sessionProperties = sessionPropertiesBuffer.byteLength !== 0
657
+ ? yield (() => __awaiter(this, void 0, void 0, function* () {
658
+ const sequenceNumberVector = sessionPropertiesBuffer.slice(0, SEQUENCE_NUMBER_BYTES);
659
+ const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);
660
+ if (sequenceNumber !== (lastKnownInboundSequenceNumber + 1)) {
661
+ throw new Error('Encrypted message has invalid sequence number');
484
662
  }
485
- return target[p];
486
- },
487
- defineProperty() {
488
- return false;
489
- },
490
- deleteProperty() {
491
- return false;
492
- },
493
- });
663
+ lastKnownInboundSequenceNumber = sequenceNumber;
664
+ return parseSessionProps(sessionPropertiesBuffer, sharedSecret);
665
+ }))() : { protocol_version: 'legacy' };
666
+ state = { __type: 'connected', sharedSecret, sessionProperties };
667
+ const wallet = createMobileWalletProxy(sessionProperties.protocol_version, (method, params) => __awaiter(this, void 0, void 0, function* () {
668
+ const id = nextJsonRpcMessageId++;
669
+ socket.send(yield encryptJsonRpcMessage({
670
+ id,
671
+ jsonrpc: '2.0',
672
+ method,
673
+ params: params !== null && params !== void 0 ? params : {},
674
+ }, sharedSecret));
675
+ return new Promise((resolve, reject) => {
676
+ jsonRpcResponsePromises[id] = {
677
+ resolve(result) {
678
+ switch (method) {
679
+ case 'authorize':
680
+ case 'reauthorize': {
681
+ const { wallet_uri_base } = result;
682
+ if (wallet_uri_base != null) {
683
+ try {
684
+ assertSecureEndpointSpecificURI(wallet_uri_base);
685
+ }
686
+ catch (e) {
687
+ reject(e);
688
+ return;
689
+ }
690
+ }
691
+ break;
692
+ }
693
+ }
694
+ resolve(result);
695
+ },
696
+ reject,
697
+ };
698
+ });
699
+ }));
494
700
  try {
495
701
  resolve(yield callback(wallet));
496
702
  }
@@ -533,8 +739,11 @@ function transact(callback, config) {
533
739
  });
534
740
  }
535
741
 
742
+ exports.SolanaCloneAuthorization = SolanaCloneAuthorization;
536
743
  exports.SolanaMobileWalletAdapterError = SolanaMobileWalletAdapterError;
537
744
  exports.SolanaMobileWalletAdapterErrorCode = SolanaMobileWalletAdapterErrorCode;
538
745
  exports.SolanaMobileWalletAdapterProtocolError = SolanaMobileWalletAdapterProtocolError;
539
746
  exports.SolanaMobileWalletAdapterProtocolErrorCode = SolanaMobileWalletAdapterProtocolErrorCode;
747
+ exports.SolanaSignInWithSolana = SolanaSignInWithSolana;
748
+ exports.SolanaSignTransactions = SolanaSignTransactions;
540
749
  exports.transact = transact;