@solana-mobile/mobile-wallet-adapter-protocol 2.0.0 → 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.
- package/.gitignore +2 -0
- package/README.md +69 -62
- package/android/.gitignore +14 -0
- package/android/.gradle/4.4.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/4.4.1/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/4.4.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.1/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.1/gc.properties +0 -0
- package/android/.gradle/7.5/checksums/checksums.lock +0 -0
- package/android/.gradle/7.5/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.5/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.5/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.5/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.5/gc.properties +0 -0
- package/android/.gradle/7.5.1/checksums/checksums.lock +0 -0
- package/android/.gradle/7.5.1/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/7.5.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.5.1/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.5.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.5.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.5.1/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/checksums/checksums.lock +0 -0
- package/android/.gradle/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +146 -146
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -5
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/SolanaMobileWalletAdapterModule.kt +178 -139
- 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 +56 -51
- package/src/__forks__/react-native/base64Utils.ts +1 -0
- package/src/__forks__/react-native/transact.ts +92 -0
- package/src/arrayBufferToBase64String.ts +10 -0
- package/src/associationPort.ts +19 -0
- package/src/base64Utils.ts +3 -0
- package/src/createHelloReq.ts +12 -0
- package/src/createMobileWalletProxy.ts +175 -0
- package/src/createSIWSMessage.ts +14 -0
- package/src/createSequenceNumberVector.ts +11 -0
- package/src/encryptedMessage.ts +60 -0
- package/src/errors.ts +95 -0
- package/src/generateAssociationKeypair.ts +10 -0
- package/src/generateECDHKeypair.ts +10 -0
- package/src/getAssociateAndroidIntentURL.ts +57 -0
- package/src/getJWS.ts +19 -0
- package/src/getStringWithURLUnsafeBase64CharactersReplaced.ts +11 -0
- package/src/index.ts +3 -0
- package/src/jsonRpcMessage.ts +38 -0
- package/src/parseHelloRsp.ts +46 -0
- package/src/parseSessionProps.ts +33 -0
- package/src/startSession.ts +94 -0
- package/src/transact.ts +266 -0
- package/src/types.ts +181 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +8 -0
package/lib/cjs/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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;
|