@solana-mobile/mobile-wallet-adapter-protocol 2.0.1 → 2.1.0-alpha1
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/android/build.gradle +3 -3
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/SolanaMobileWalletAdapterModule.kt +17 -15
- package/lib/cjs/index.browser.js +290 -81
- package/lib/cjs/index.js +290 -81
- package/lib/cjs/index.native.js +180 -28
- package/lib/esm/index.browser.js +288 -82
- package/lib/esm/index.js +288 -82
- package/lib/types/index.browser.d.ts +68 -5
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.ts +68 -5
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +68 -5
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +10 -2
- package/src/__forks__/react-native/base64Utils.ts +1 -0
- package/src/__forks__/react-native/transact.ts +92 -106
- package/src/base64Utils.ts +3 -0
- package/src/createMobileWalletProxy.ts +175 -0
- package/src/createSIWSMessage.ts +14 -0
- package/src/encryptedMessage.ts +60 -0
- package/src/errors.ts +95 -93
- package/src/getAssociateAndroidIntentURL.ts +57 -52
- package/src/jsonRpcMessage.ts +38 -81
- package/src/parseHelloRsp.ts +46 -44
- package/src/parseSessionProps.ts +33 -0
- package/src/transact.ts +266 -268
- package/src/types.ts +74 -4
package/lib/esm/index.browser.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createSignInMessageText } from '@solana/wallet-standard-util';
|
|
2
|
+
|
|
1
3
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
2
4
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
3
5
|
ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',
|
|
@@ -6,6 +8,7 @@ const SolanaMobileWalletAdapterErrorCode = {
|
|
|
6
8
|
ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',
|
|
7
9
|
ERROR_SESSION_TIMEOUT: 'ERROR_SESSION_TIMEOUT',
|
|
8
10
|
ERROR_WALLET_NOT_FOUND: 'ERROR_WALLET_NOT_FOUND',
|
|
11
|
+
ERROR_INVALID_PROTOCOL_VERSION: 'ERROR_INVALID_PROTOCOL_VERSION',
|
|
9
12
|
};
|
|
10
13
|
class SolanaMobileWalletAdapterError extends Error {
|
|
11
14
|
constructor(...args) {
|
|
@@ -73,6 +76,175 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
73
76
|
});
|
|
74
77
|
}
|
|
75
78
|
|
|
79
|
+
function encode(input) {
|
|
80
|
+
return window.btoa(input);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function createSIWSMessage(payload) {
|
|
84
|
+
return createSignInMessageText(payload);
|
|
85
|
+
}
|
|
86
|
+
function createSIWSMessageBase64(payload) {
|
|
87
|
+
return encode(createSIWSMessage(payload));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// optional features
|
|
91
|
+
const SolanaSignTransactions = 'solana:signTransactions';
|
|
92
|
+
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
93
|
+
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
97
|
+
*
|
|
98
|
+
* @param protocolVersion the protocol version in use for this session/request
|
|
99
|
+
* @param protocolRequestHandler callback function that handles sending the RPC request to the wallet endpoint.
|
|
100
|
+
* @returns a {@link MobileWallet} proxy
|
|
101
|
+
*/
|
|
102
|
+
function createMobileWalletProxy(protocolVersion, protocolRequestHandler) {
|
|
103
|
+
return new Proxy({}, {
|
|
104
|
+
get(target, p) {
|
|
105
|
+
if (target[p] == null) {
|
|
106
|
+
target[p] = function (inputParams) {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);
|
|
109
|
+
const result = yield protocolRequestHandler(method, params);
|
|
110
|
+
// if the request tried to sign in but the wallet did not return a sign in result, fallback on message signing
|
|
111
|
+
if (method === 'authorize' && params.sign_in_payload && !result.sign_in_result) {
|
|
112
|
+
result['sign_in_result'] = yield signInFallback(params.sign_in_payload, result, protocolRequestHandler);
|
|
113
|
+
}
|
|
114
|
+
return handleMobileWalletResponse(p, result, protocolVersion);
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return target[p];
|
|
119
|
+
},
|
|
120
|
+
defineProperty() {
|
|
121
|
+
return false;
|
|
122
|
+
},
|
|
123
|
+
deleteProperty() {
|
|
124
|
+
return false;
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handles all {@link MobileWallet} API requests and determines the correct MWA RPC method and params to call.
|
|
130
|
+
* This handles backwards compatibility, based on the provided @protocolVersion.
|
|
131
|
+
*
|
|
132
|
+
* @param methodName the name of {@link MobileWallet} method that was called
|
|
133
|
+
* @param methodParams the parameters that were passed to the method
|
|
134
|
+
* @param protocolVersion the protocol version in use for this session/request
|
|
135
|
+
* @returns the RPC request method and params that should be sent to the wallet endpoint
|
|
136
|
+
*/
|
|
137
|
+
function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
138
|
+
let params = methodParams;
|
|
139
|
+
let method = methodName
|
|
140
|
+
.toString()
|
|
141
|
+
.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
|
|
142
|
+
.toLowerCase();
|
|
143
|
+
switch (methodName) {
|
|
144
|
+
case 'authorize': {
|
|
145
|
+
let { chain } = params;
|
|
146
|
+
if (protocolVersion === 'legacy') {
|
|
147
|
+
switch (chain) {
|
|
148
|
+
case 'solana:testnet': {
|
|
149
|
+
chain = 'testnet';
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case 'solana:devnet': {
|
|
153
|
+
chain = 'devnet';
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case 'solana:mainnet': {
|
|
157
|
+
chain = 'mainnet-beta';
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
default: {
|
|
161
|
+
chain = params.cluster;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
params.cluster = chain;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
switch (chain) {
|
|
168
|
+
case 'testnet':
|
|
169
|
+
case 'devnet': {
|
|
170
|
+
chain = `solana:${chain}`;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case 'mainnet-beta': {
|
|
174
|
+
chain = 'solana:mainnet';
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
params.chain = chain;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
case 'reauthorize': {
|
|
182
|
+
const { auth_token, identity } = params;
|
|
183
|
+
if (auth_token) {
|
|
184
|
+
switch (protocolVersion) {
|
|
185
|
+
case 'legacy': {
|
|
186
|
+
method = 'reauthorize';
|
|
187
|
+
params = { auth_token: auth_token, identity: identity };
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
default: {
|
|
191
|
+
method = 'authorize';
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return { method, params };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Handles all {@link MobileWallet} API responses and modifies the response for backwards compatibility, if needed
|
|
203
|
+
*
|
|
204
|
+
* @param method the {@link MobileWallet} method that was called
|
|
205
|
+
* @param response the original response that was returned by the method call
|
|
206
|
+
* @param protocolVersion the protocol version in use for this session/request
|
|
207
|
+
* @returns the possibly modified response
|
|
208
|
+
*/
|
|
209
|
+
function handleMobileWalletResponse(method, response, protocolVersion) {
|
|
210
|
+
switch (method) {
|
|
211
|
+
case 'getCapabilities': {
|
|
212
|
+
const capabilities = response;
|
|
213
|
+
switch (protocolVersion) {
|
|
214
|
+
case 'legacy': {
|
|
215
|
+
const features = [SolanaSignTransactions];
|
|
216
|
+
if (capabilities.supports_clone_authorization === true) {
|
|
217
|
+
features.push(SolanaCloneAuthorization);
|
|
218
|
+
}
|
|
219
|
+
return Object.assign(Object.assign({}, capabilities), { features: features });
|
|
220
|
+
}
|
|
221
|
+
case 'v1': {
|
|
222
|
+
return Object.assign(Object.assign({}, capabilities), { supports_sign_and_send_transactions: true, supports_clone_authorization: capabilities.features.includes(SolanaCloneAuthorization) });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return response;
|
|
228
|
+
}
|
|
229
|
+
function signInFallback(signInPayload, authorizationResult, protocolRequestHandler) {
|
|
230
|
+
var _a;
|
|
231
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
233
|
+
const address = authorizationResult.accounts[0].address;
|
|
234
|
+
const siwsMessage = createSIWSMessageBase64(Object.assign(Object.assign({}, signInPayload), { domain, address }));
|
|
235
|
+
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
236
|
+
addresses: [address],
|
|
237
|
+
payloads: [siwsMessage]
|
|
238
|
+
});
|
|
239
|
+
const signInResult = {
|
|
240
|
+
address: address,
|
|
241
|
+
signed_message: siwsMessage,
|
|
242
|
+
signature: signMessageResult.signed_payloads[0].slice(siwsMessage.length)
|
|
243
|
+
};
|
|
244
|
+
return signInResult;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
76
248
|
const SEQUENCE_NUMBER_BYTES = 4;
|
|
77
249
|
function createSequenceNumberVector(sequenceNumber) {
|
|
78
250
|
if (sequenceNumber >= 4294967296) {
|
|
@@ -84,29 +256,11 @@ function createSequenceNumberVector(sequenceNumber) {
|
|
|
84
256
|
return new Uint8Array(byteArray);
|
|
85
257
|
}
|
|
86
258
|
|
|
87
|
-
function generateAssociationKeypair() {
|
|
88
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
return yield crypto.subtle.generateKey({
|
|
90
|
-
name: 'ECDSA',
|
|
91
|
-
namedCurve: 'P-256',
|
|
92
|
-
}, false /* extractable */, ['sign'] /* keyUsages */);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function generateECDHKeypair() {
|
|
97
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
return yield crypto.subtle.generateKey({
|
|
99
|
-
name: 'ECDH',
|
|
100
|
-
namedCurve: 'P-256',
|
|
101
|
-
}, false /* extractable */, ['deriveKey', 'deriveBits'] /* keyUsages */);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
259
|
const INITIALIZATION_VECTOR_BYTES = 12;
|
|
106
|
-
|
|
260
|
+
const ENCODED_PUBLIC_KEY_LENGTH_BYTES = 65;
|
|
261
|
+
function encryptMessage(plaintext, sequenceNumber, sharedSecret) {
|
|
107
262
|
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
-
const
|
|
109
|
-
const sequenceNumberVector = createSequenceNumberVector(jsonRpcMessage.id);
|
|
263
|
+
const sequenceNumberVector = createSequenceNumberVector(sequenceNumber);
|
|
110
264
|
const initializationVector = new Uint8Array(INITIALIZATION_VECTOR_BYTES);
|
|
111
265
|
crypto.getRandomValues(initializationVector);
|
|
112
266
|
const ciphertext = yield crypto.subtle.encrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, new TextEncoder().encode(plaintext));
|
|
@@ -117,18 +271,14 @@ function encryptJsonRpcMessage(jsonRpcMessage, sharedSecret) {
|
|
|
117
271
|
return response;
|
|
118
272
|
});
|
|
119
273
|
}
|
|
120
|
-
function
|
|
274
|
+
function decryptMessage(message, sharedSecret) {
|
|
121
275
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
276
|
const sequenceNumberVector = message.slice(0, SEQUENCE_NUMBER_BYTES);
|
|
123
277
|
const initializationVector = message.slice(SEQUENCE_NUMBER_BYTES, SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);
|
|
124
278
|
const ciphertext = message.slice(SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);
|
|
125
279
|
const plaintextBuffer = yield crypto.subtle.decrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, ciphertext);
|
|
126
280
|
const plaintext = getUtf8Decoder().decode(plaintextBuffer);
|
|
127
|
-
|
|
128
|
-
if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {
|
|
129
|
-
throw new SolanaMobileWalletAdapterProtocolError(jsonRpcMessage.id, jsonRpcMessage.error.code, jsonRpcMessage.error.message);
|
|
130
|
-
}
|
|
131
|
-
return jsonRpcMessage;
|
|
281
|
+
return plaintext;
|
|
132
282
|
});
|
|
133
283
|
}
|
|
134
284
|
function getAlgorithmParams(sequenceNumber, initializationVector) {
|
|
@@ -147,12 +297,48 @@ function getUtf8Decoder() {
|
|
|
147
297
|
return _utf8Decoder;
|
|
148
298
|
}
|
|
149
299
|
|
|
300
|
+
function generateAssociationKeypair() {
|
|
301
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
return yield crypto.subtle.generateKey({
|
|
303
|
+
name: 'ECDSA',
|
|
304
|
+
namedCurve: 'P-256',
|
|
305
|
+
}, false /* extractable */, ['sign'] /* keyUsages */);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function generateECDHKeypair() {
|
|
310
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
return yield crypto.subtle.generateKey({
|
|
312
|
+
name: 'ECDH',
|
|
313
|
+
namedCurve: 'P-256',
|
|
314
|
+
}, false /* extractable */, ['deriveKey', 'deriveBits'] /* keyUsages */);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function encryptJsonRpcMessage(jsonRpcMessage, sharedSecret) {
|
|
319
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
320
|
+
const plaintext = JSON.stringify(jsonRpcMessage);
|
|
321
|
+
const sequenceNumber = jsonRpcMessage.id;
|
|
322
|
+
return encryptMessage(plaintext, sequenceNumber, sharedSecret);
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
function decryptJsonRpcMessage(message, sharedSecret) {
|
|
326
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
327
|
+
const plaintext = yield decryptMessage(message, sharedSecret);
|
|
328
|
+
const jsonRpcMessage = JSON.parse(plaintext);
|
|
329
|
+
if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {
|
|
330
|
+
throw new SolanaMobileWalletAdapterProtocolError(jsonRpcMessage.id, jsonRpcMessage.error.code, jsonRpcMessage.error.message);
|
|
331
|
+
}
|
|
332
|
+
return jsonRpcMessage;
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
150
336
|
function parseHelloRsp(payloadBuffer, // The X9.62-encoded wallet endpoint ephemeral ECDH public keypoint.
|
|
151
337
|
associationPublicKey, ecdhPrivateKey) {
|
|
152
338
|
return __awaiter(this, void 0, void 0, function* () {
|
|
153
339
|
const [associationPublicKeyBuffer, walletPublicKey] = yield Promise.all([
|
|
154
340
|
crypto.subtle.exportKey('raw', associationPublicKey),
|
|
155
|
-
crypto.subtle.importKey('raw', payloadBuffer, { name: 'ECDH', namedCurve: 'P-256' }, false /* extractable */, [] /* keyUsages */),
|
|
341
|
+
crypto.subtle.importKey('raw', payloadBuffer.slice(0, ENCODED_PUBLIC_KEY_LENGTH_BYTES), { name: 'ECDH', namedCurve: 'P-256' }, false /* extractable */, [] /* keyUsages */),
|
|
156
342
|
]);
|
|
157
343
|
const sharedSecret = yield crypto.subtle.deriveBits({ name: 'ECDH', public: walletPublicKey }, ecdhPrivateKey, 256);
|
|
158
344
|
const ecdhSecretKey = yield crypto.subtle.importKey('raw', sharedSecret, 'HKDF', false /* extractable */, ['deriveKey'] /* keyUsages */);
|
|
@@ -166,6 +352,31 @@ associationPublicKey, ecdhPrivateKey) {
|
|
|
166
352
|
});
|
|
167
353
|
}
|
|
168
354
|
|
|
355
|
+
function parseSessionProps(message, sharedSecret) {
|
|
356
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
357
|
+
const plaintext = yield decryptMessage(message, sharedSecret);
|
|
358
|
+
const jsonProperties = JSON.parse(plaintext);
|
|
359
|
+
let protocolVersion = 'legacy';
|
|
360
|
+
if (Object.hasOwnProperty.call(jsonProperties, 'v')) {
|
|
361
|
+
switch (jsonProperties.v) {
|
|
362
|
+
case 1:
|
|
363
|
+
case '1':
|
|
364
|
+
case 'v1':
|
|
365
|
+
protocolVersion = 'v1';
|
|
366
|
+
break;
|
|
367
|
+
case 'legacy':
|
|
368
|
+
protocolVersion = 'legacy';
|
|
369
|
+
break;
|
|
370
|
+
default:
|
|
371
|
+
throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION, `Unknown/unsupported protocol version: ${jsonProperties.v}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return ({
|
|
375
|
+
protocol_version: protocolVersion
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
169
380
|
function getRandomAssociationPort() {
|
|
170
381
|
return assertAssociationPort(49152 + Math.floor(Math.random() * (65535 - 49152 + 1)));
|
|
171
382
|
}
|
|
@@ -222,7 +433,7 @@ function getIntentURL(methodPathname, intentUrlBase) {
|
|
|
222
433
|
[...getPathParts(baseUrl.pathname), ...getPathParts(methodPathname)].join('/');
|
|
223
434
|
return new URL(pathname, baseUrl);
|
|
224
435
|
}
|
|
225
|
-
function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associationURLBase) {
|
|
436
|
+
function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associationURLBase, protocolVersions = ['v1']) {
|
|
226
437
|
return __awaiter(this, void 0, void 0, function* () {
|
|
227
438
|
const associationPort = assertAssociationPort(putativePort);
|
|
228
439
|
const exportedKey = yield crypto.subtle.exportKey('raw', associationPublicKey);
|
|
@@ -230,6 +441,9 @@ function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associ
|
|
|
230
441
|
const url = getIntentURL('v1/associate/local', associationURLBase);
|
|
231
442
|
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
232
443
|
url.searchParams.set('port', `${associationPort}`);
|
|
444
|
+
protocolVersions.forEach((version) => {
|
|
445
|
+
url.searchParams.set('v', version);
|
|
446
|
+
});
|
|
233
447
|
return url;
|
|
234
448
|
});
|
|
235
449
|
}
|
|
@@ -434,59 +648,51 @@ function transact(callback, config) {
|
|
|
434
648
|
break;
|
|
435
649
|
case 'hello_req_sent': {
|
|
436
650
|
const sharedSecret = yield parseHelloRsp(responseBuffer, state.associationPublicKey, state.ecdhPrivateKey);
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
.toLowerCase();
|
|
445
|
-
target[p] = function (params) {
|
|
446
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
447
|
-
const id = nextJsonRpcMessageId++;
|
|
448
|
-
socket.send(yield encryptJsonRpcMessage({
|
|
449
|
-
id,
|
|
450
|
-
jsonrpc: '2.0',
|
|
451
|
-
method,
|
|
452
|
-
params: params !== null && params !== void 0 ? params : {},
|
|
453
|
-
}, sharedSecret));
|
|
454
|
-
return new Promise((resolve, reject) => {
|
|
455
|
-
jsonRpcResponsePromises[id] = {
|
|
456
|
-
resolve(result) {
|
|
457
|
-
switch (p) {
|
|
458
|
-
case 'authorize':
|
|
459
|
-
case 'reauthorize': {
|
|
460
|
-
const { wallet_uri_base } = result;
|
|
461
|
-
if (wallet_uri_base != null) {
|
|
462
|
-
try {
|
|
463
|
-
assertSecureEndpointSpecificURI(wallet_uri_base);
|
|
464
|
-
}
|
|
465
|
-
catch (e) {
|
|
466
|
-
reject(e);
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
break;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
resolve(result);
|
|
474
|
-
},
|
|
475
|
-
reject,
|
|
476
|
-
};
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
};
|
|
651
|
+
const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);
|
|
652
|
+
const sessionProperties = sessionPropertiesBuffer.byteLength !== 0
|
|
653
|
+
? yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
654
|
+
const sequenceNumberVector = sessionPropertiesBuffer.slice(0, SEQUENCE_NUMBER_BYTES);
|
|
655
|
+
const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);
|
|
656
|
+
if (sequenceNumber !== (lastKnownInboundSequenceNumber + 1)) {
|
|
657
|
+
throw new Error('Encrypted message has invalid sequence number');
|
|
480
658
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
659
|
+
lastKnownInboundSequenceNumber = sequenceNumber;
|
|
660
|
+
return parseSessionProps(sessionPropertiesBuffer, sharedSecret);
|
|
661
|
+
}))() : { protocol_version: 'legacy' };
|
|
662
|
+
state = { __type: 'connected', sharedSecret, sessionProperties };
|
|
663
|
+
const wallet = createMobileWalletProxy(sessionProperties.protocol_version, (method, params) => __awaiter(this, void 0, void 0, function* () {
|
|
664
|
+
const id = nextJsonRpcMessageId++;
|
|
665
|
+
socket.send(yield encryptJsonRpcMessage({
|
|
666
|
+
id,
|
|
667
|
+
jsonrpc: '2.0',
|
|
668
|
+
method,
|
|
669
|
+
params: params !== null && params !== void 0 ? params : {},
|
|
670
|
+
}, sharedSecret));
|
|
671
|
+
return new Promise((resolve, reject) => {
|
|
672
|
+
jsonRpcResponsePromises[id] = {
|
|
673
|
+
resolve(result) {
|
|
674
|
+
switch (method) {
|
|
675
|
+
case 'authorize':
|
|
676
|
+
case 'reauthorize': {
|
|
677
|
+
const { wallet_uri_base } = result;
|
|
678
|
+
if (wallet_uri_base != null) {
|
|
679
|
+
try {
|
|
680
|
+
assertSecureEndpointSpecificURI(wallet_uri_base);
|
|
681
|
+
}
|
|
682
|
+
catch (e) {
|
|
683
|
+
reject(e);
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
resolve(result);
|
|
691
|
+
},
|
|
692
|
+
reject,
|
|
693
|
+
};
|
|
694
|
+
});
|
|
695
|
+
}));
|
|
490
696
|
try {
|
|
491
697
|
resolve(yield callback(wallet));
|
|
492
698
|
}
|
|
@@ -529,4 +735,4 @@ function transact(callback, config) {
|
|
|
529
735
|
});
|
|
530
736
|
}
|
|
531
737
|
|
|
532
|
-
export { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode, SolanaMobileWalletAdapterProtocolError, SolanaMobileWalletAdapterProtocolErrorCode, transact };
|
|
738
|
+
export { SolanaCloneAuthorization, SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode, SolanaMobileWalletAdapterProtocolError, SolanaMobileWalletAdapterProtocolErrorCode, SolanaSignInWithSolana, SolanaSignTransactions, transact };
|