@solana-mobile/mobile-wallet-adapter-protocol 2.2.3 → 2.2.5
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 +2 -2
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/SolanaMobileWalletAdapterModule.kt +14 -9
- package/lib/cjs/index.browser.js +26 -9
- package/lib/cjs/index.js +26 -9
- package/lib/cjs/index.native.js +23 -6
- package/lib/esm/index.browser.js +26 -9
- package/lib/esm/index.js +26 -9
- package/lib/types/index.browser.d.ts +1 -1
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +1 -1
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +4 -3
package/android/build.gradle
CHANGED
|
@@ -8,7 +8,7 @@ buildscript {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
dependencies {
|
|
11
|
-
classpath 'com.android.tools.build:gradle:8.
|
|
11
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
12
12
|
// noinspection DifferentKotlinGradleVersion
|
|
13
13
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
14
14
|
}
|
|
@@ -144,7 +144,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
|
|
|
144
144
|
dependencies {
|
|
145
145
|
//noinspection GradleDynamicVersion
|
|
146
146
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
|
147
|
-
implementation "com.solanamobile:mobile-wallet-adapter-clientlib:2.0
|
|
147
|
+
implementation "com.solanamobile:mobile-wallet-adapter-clientlib:2.1.0"
|
|
148
148
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
149
149
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0"
|
|
150
150
|
}
|
|
@@ -49,7 +49,7 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
|
|
|
49
49
|
private val mActivityEventListener: ActivityEventListener =
|
|
50
50
|
object : BaseActivityEventListener() {
|
|
51
51
|
override fun onActivityResult(
|
|
52
|
-
activity: Activity
|
|
52
|
+
activity: Activity,
|
|
53
53
|
requestCode: Int,
|
|
54
54
|
resultCode: Int,
|
|
55
55
|
data: Intent?
|
|
@@ -61,10 +61,10 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
|
|
|
61
61
|
|
|
62
62
|
private val sessionBackgroundTaskConfig
|
|
63
63
|
get() = HeadlessJsTaskConfig(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
"SolanaMobileWalletAdapterSessionBackgroundTask",
|
|
65
|
+
Arguments.createMap(),
|
|
66
|
+
0,
|
|
67
|
+
true
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
init {
|
|
@@ -87,6 +87,10 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
|
|
|
87
87
|
if (taskId != null && headlessJsTaskContext.isTaskRunning(taskId)) {
|
|
88
88
|
headlessJsTaskContext.finishTask(taskId)
|
|
89
89
|
}
|
|
90
|
+
// fix for Expo 52/RN 0.72/0.73 where the older kotlin/gradle toolchain complains
|
|
91
|
+
// about the above if statement being used as an expression. Explicitly returning
|
|
92
|
+
// Unit here tells the compiler that the above if is not an expression
|
|
93
|
+
Unit
|
|
90
94
|
} catch (e: Exception) {
|
|
91
95
|
Log.w(TAG, "Failed to finish headless JS task", e)
|
|
92
96
|
}
|
|
@@ -121,10 +125,11 @@ class SolanaMobileWalletAdapterModule(reactContext: ReactApplicationContext) :
|
|
|
121
125
|
// stop the headless js task, regardless if the association was successful or not
|
|
122
126
|
finishHeadlessTask(sessionTaskId)
|
|
123
127
|
}
|
|
124
|
-
currentActivity?.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
reactApplicationContext.currentActivity?.apply {
|
|
129
|
+
startActivityForResult(intent, REQUEST_LOCAL_ASSOCIATION)
|
|
130
|
+
} ?: throw NullPointerException(
|
|
131
|
+
"Could not find a current activity from which to launch a local association"
|
|
132
|
+
)
|
|
128
133
|
val client = localAssociation.start()
|
|
129
134
|
.get(ASSOCIATION_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
|
130
135
|
sessionState = SessionState(client, localAssociation)
|
package/lib/cjs/index.browser.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var walletStandardUtil = require('@solana/wallet-standard-util');
|
|
6
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
6
7
|
|
|
7
8
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
8
9
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
@@ -74,7 +75,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
74
75
|
function encode(input) {
|
|
75
76
|
return window.btoa(input);
|
|
76
77
|
}
|
|
77
|
-
function fromUint8Array(byteArray, urlsafe) {
|
|
78
|
+
function fromUint8Array$1(byteArray, urlsafe) {
|
|
78
79
|
const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
79
80
|
if (urlsafe) {
|
|
80
81
|
return base64
|
|
@@ -106,8 +107,11 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
106
107
|
function createSIWSMessage(payload) {
|
|
107
108
|
return walletStandardUtil.createSignInMessageText(payload);
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
-
return encode(createSIWSMessage(payload))
|
|
110
|
+
function createSIWSMessageBase64Url(payload) {
|
|
111
|
+
return encode(createSIWSMessage(payload))
|
|
112
|
+
.replace(/\+/g, '-')
|
|
113
|
+
.replace(/\//g, '_')
|
|
114
|
+
.replace(/=+$/, ''); // convert to base64url encoding;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
// optional features
|
|
@@ -115,6 +119,13 @@ const SolanaSignTransactions = 'solana:signTransactions';
|
|
|
115
119
|
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
116
120
|
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
117
121
|
|
|
122
|
+
function fromUint8Array(byteArray) {
|
|
123
|
+
return codecsStrings.getBase58Decoder().decode(byteArray);
|
|
124
|
+
}
|
|
125
|
+
function base64ToBase58(base64EncodedString) {
|
|
126
|
+
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
127
|
+
}
|
|
128
|
+
|
|
118
129
|
/**
|
|
119
130
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
120
131
|
*
|
|
@@ -261,15 +272,21 @@ function signInFallback(signInPayload, authorizationResult, protocolRequestHandl
|
|
|
261
272
|
return __awaiter(this, void 0, void 0, function* () {
|
|
262
273
|
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
263
274
|
const address = authorizationResult.accounts[0].address;
|
|
264
|
-
const siwsMessage =
|
|
275
|
+
const siwsMessage = createSIWSMessageBase64Url(Object.assign(Object.assign({}, signInPayload), { domain, address: base64ToBase58(address) }));
|
|
265
276
|
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
266
277
|
addresses: [address],
|
|
267
278
|
payloads: [siwsMessage]
|
|
268
279
|
});
|
|
280
|
+
const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);
|
|
281
|
+
const signedMessage = fromUint8Array$1(signedPayload.slice(0, signedPayload.length - 64));
|
|
282
|
+
const signature = fromUint8Array$1(signedPayload.slice(signedPayload.length - 64));
|
|
269
283
|
const signInResult = {
|
|
270
284
|
address: address,
|
|
271
|
-
|
|
272
|
-
|
|
285
|
+
// Workaround: some wallets have been observed to only reply with the message signature.
|
|
286
|
+
// This is non-compliant with the spec, but in the interest of maximizing compatibility,
|
|
287
|
+
// detect this case and reuse the original message.
|
|
288
|
+
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
289
|
+
signature
|
|
273
290
|
};
|
|
274
291
|
return signInResult;
|
|
275
292
|
});
|
|
@@ -422,7 +439,7 @@ function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority,
|
|
|
422
439
|
const url = getIntentURL('v1/associate/remote', associationURLBase);
|
|
423
440
|
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
424
441
|
url.searchParams.set('reflector', `${hostAuthority}`);
|
|
425
|
-
url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);
|
|
442
|
+
url.searchParams.set('id', `${fromUint8Array$1(reflectorId, true)}`);
|
|
426
443
|
protocolVersions.forEach((version) => {
|
|
427
444
|
url.searchParams.set('v', version);
|
|
428
445
|
});
|
|
@@ -953,7 +970,7 @@ function startRemoteScenario(config) {
|
|
|
953
970
|
const ecdhKeypair = yield generateECDHKeypair();
|
|
954
971
|
const binaryMsg = yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
955
972
|
if (encoding == 'base64') {
|
|
956
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
973
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
957
974
|
}
|
|
958
975
|
else {
|
|
959
976
|
socket.send(binaryMsg);
|
|
@@ -1011,7 +1028,7 @@ function startRemoteScenario(config) {
|
|
|
1011
1028
|
params: params !== null && params !== void 0 ? params : {},
|
|
1012
1029
|
}, sharedSecret);
|
|
1013
1030
|
if (encoding == 'base64') {
|
|
1014
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
1031
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
1015
1032
|
}
|
|
1016
1033
|
else {
|
|
1017
1034
|
socket.send(binaryMsg);
|
package/lib/cjs/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var walletStandardUtil = require('@solana/wallet-standard-util');
|
|
6
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
6
7
|
|
|
7
8
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
8
9
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
@@ -74,7 +75,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
74
75
|
function encode(input) {
|
|
75
76
|
return window.btoa(input);
|
|
76
77
|
}
|
|
77
|
-
function fromUint8Array(byteArray, urlsafe) {
|
|
78
|
+
function fromUint8Array$1(byteArray, urlsafe) {
|
|
78
79
|
const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
79
80
|
if (urlsafe) {
|
|
80
81
|
return base64
|
|
@@ -106,8 +107,11 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
106
107
|
function createSIWSMessage(payload) {
|
|
107
108
|
return walletStandardUtil.createSignInMessageText(payload);
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
-
return encode(createSIWSMessage(payload))
|
|
110
|
+
function createSIWSMessageBase64Url(payload) {
|
|
111
|
+
return encode(createSIWSMessage(payload))
|
|
112
|
+
.replace(/\+/g, '-')
|
|
113
|
+
.replace(/\//g, '_')
|
|
114
|
+
.replace(/=+$/, ''); // convert to base64url encoding;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
// optional features
|
|
@@ -115,6 +119,13 @@ const SolanaSignTransactions = 'solana:signTransactions';
|
|
|
115
119
|
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
116
120
|
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
117
121
|
|
|
122
|
+
function fromUint8Array(byteArray) {
|
|
123
|
+
return codecsStrings.getBase58Decoder().decode(byteArray);
|
|
124
|
+
}
|
|
125
|
+
function base64ToBase58(base64EncodedString) {
|
|
126
|
+
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
127
|
+
}
|
|
128
|
+
|
|
118
129
|
/**
|
|
119
130
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
120
131
|
*
|
|
@@ -261,15 +272,21 @@ function signInFallback(signInPayload, authorizationResult, protocolRequestHandl
|
|
|
261
272
|
return __awaiter(this, void 0, void 0, function* () {
|
|
262
273
|
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
263
274
|
const address = authorizationResult.accounts[0].address;
|
|
264
|
-
const siwsMessage =
|
|
275
|
+
const siwsMessage = createSIWSMessageBase64Url(Object.assign(Object.assign({}, signInPayload), { domain, address: base64ToBase58(address) }));
|
|
265
276
|
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
266
277
|
addresses: [address],
|
|
267
278
|
payloads: [siwsMessage]
|
|
268
279
|
});
|
|
280
|
+
const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);
|
|
281
|
+
const signedMessage = fromUint8Array$1(signedPayload.slice(0, signedPayload.length - 64));
|
|
282
|
+
const signature = fromUint8Array$1(signedPayload.slice(signedPayload.length - 64));
|
|
269
283
|
const signInResult = {
|
|
270
284
|
address: address,
|
|
271
|
-
|
|
272
|
-
|
|
285
|
+
// Workaround: some wallets have been observed to only reply with the message signature.
|
|
286
|
+
// This is non-compliant with the spec, but in the interest of maximizing compatibility,
|
|
287
|
+
// detect this case and reuse the original message.
|
|
288
|
+
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
289
|
+
signature
|
|
273
290
|
};
|
|
274
291
|
return signInResult;
|
|
275
292
|
});
|
|
@@ -422,7 +439,7 @@ function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority,
|
|
|
422
439
|
const url = getIntentURL('v1/associate/remote', associationURLBase);
|
|
423
440
|
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
424
441
|
url.searchParams.set('reflector', `${hostAuthority}`);
|
|
425
|
-
url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);
|
|
442
|
+
url.searchParams.set('id', `${fromUint8Array$1(reflectorId, true)}`);
|
|
426
443
|
protocolVersions.forEach((version) => {
|
|
427
444
|
url.searchParams.set('v', version);
|
|
428
445
|
});
|
|
@@ -953,7 +970,7 @@ function startRemoteScenario(config) {
|
|
|
953
970
|
const ecdhKeypair = yield generateECDHKeypair();
|
|
954
971
|
const binaryMsg = yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
955
972
|
if (encoding == 'base64') {
|
|
956
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
973
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
957
974
|
}
|
|
958
975
|
else {
|
|
959
976
|
socket.send(binaryMsg);
|
|
@@ -1011,7 +1028,7 @@ function startRemoteScenario(config) {
|
|
|
1011
1028
|
params: params !== null && params !== void 0 ? params : {},
|
|
1012
1029
|
}, sharedSecret);
|
|
1013
1030
|
if (encoding == 'base64') {
|
|
1014
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
1031
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
1015
1032
|
}
|
|
1016
1033
|
else {
|
|
1017
1034
|
socket.send(binaryMsg);
|
package/lib/cjs/index.native.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
|
-
var walletStandardUtil = require('@solana/wallet-standard-util');
|
|
7
6
|
var jsBase64 = require('js-base64');
|
|
7
|
+
var walletStandardUtil = require('@solana/wallet-standard-util');
|
|
8
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
8
9
|
|
|
9
10
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
10
11
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
@@ -78,8 +79,11 @@ var NativeSolanaMobileWalletAdapter = reactNative.TurboModuleRegistry.getEnforci
|
|
|
78
79
|
function createSIWSMessage(payload) {
|
|
79
80
|
return walletStandardUtil.createSignInMessageText(payload);
|
|
80
81
|
}
|
|
81
|
-
function
|
|
82
|
-
return jsBase64.encode(createSIWSMessage(payload))
|
|
82
|
+
function createSIWSMessageBase64Url(payload) {
|
|
83
|
+
return jsBase64.encode(createSIWSMessage(payload))
|
|
84
|
+
.replace(/\+/g, '-')
|
|
85
|
+
.replace(/\//g, '_')
|
|
86
|
+
.replace(/=+$/, ''); // convert to base64url encoding;
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
// optional features
|
|
@@ -87,6 +91,13 @@ const SolanaSignTransactions = 'solana:signTransactions';
|
|
|
87
91
|
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
88
92
|
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
89
93
|
|
|
94
|
+
function fromUint8Array(byteArray) {
|
|
95
|
+
return codecsStrings.getBase58Decoder().decode(byteArray);
|
|
96
|
+
}
|
|
97
|
+
function base64ToBase58(base64EncodedString) {
|
|
98
|
+
return fromUint8Array(jsBase64.toUint8Array(base64EncodedString));
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
/**
|
|
91
102
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
92
103
|
*
|
|
@@ -233,15 +244,21 @@ function signInFallback(signInPayload, authorizationResult, protocolRequestHandl
|
|
|
233
244
|
return __awaiter(this, void 0, void 0, function* () {
|
|
234
245
|
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
235
246
|
const address = authorizationResult.accounts[0].address;
|
|
236
|
-
const siwsMessage =
|
|
247
|
+
const siwsMessage = createSIWSMessageBase64Url(Object.assign(Object.assign({}, signInPayload), { domain, address: base64ToBase58(address) }));
|
|
237
248
|
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
238
249
|
addresses: [address],
|
|
239
250
|
payloads: [siwsMessage]
|
|
240
251
|
});
|
|
252
|
+
const signedPayload = jsBase64.toUint8Array(signMessageResult.signed_payloads[0]);
|
|
253
|
+
const signedMessage = jsBase64.fromUint8Array(signedPayload.slice(0, signedPayload.length - 64));
|
|
254
|
+
const signature = jsBase64.fromUint8Array(signedPayload.slice(signedPayload.length - 64));
|
|
241
255
|
const signInResult = {
|
|
242
256
|
address: address,
|
|
243
|
-
|
|
244
|
-
|
|
257
|
+
// Workaround: some wallets have been observed to only reply with the message signature.
|
|
258
|
+
// This is non-compliant with the spec, but in the interest of maximizing compatibility,
|
|
259
|
+
// detect this case and reuse the original message.
|
|
260
|
+
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
261
|
+
signature
|
|
245
262
|
};
|
|
246
263
|
return signInResult;
|
|
247
264
|
});
|
package/lib/esm/index.browser.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createSignInMessageText } from '@solana/wallet-standard-util';
|
|
2
|
+
import { getBase58Decoder } from '@solana/codecs-strings';
|
|
2
3
|
|
|
3
4
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
4
5
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
@@ -70,7 +71,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
70
71
|
function encode(input) {
|
|
71
72
|
return window.btoa(input);
|
|
72
73
|
}
|
|
73
|
-
function fromUint8Array(byteArray, urlsafe) {
|
|
74
|
+
function fromUint8Array$1(byteArray, urlsafe) {
|
|
74
75
|
const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
75
76
|
if (urlsafe) {
|
|
76
77
|
return base64
|
|
@@ -102,8 +103,11 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
102
103
|
function createSIWSMessage(payload) {
|
|
103
104
|
return createSignInMessageText(payload);
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
-
return encode(createSIWSMessage(payload))
|
|
106
|
+
function createSIWSMessageBase64Url(payload) {
|
|
107
|
+
return encode(createSIWSMessage(payload))
|
|
108
|
+
.replace(/\+/g, '-')
|
|
109
|
+
.replace(/\//g, '_')
|
|
110
|
+
.replace(/=+$/, ''); // convert to base64url encoding;
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
// optional features
|
|
@@ -111,6 +115,13 @@ const SolanaSignTransactions = 'solana:signTransactions';
|
|
|
111
115
|
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
112
116
|
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
113
117
|
|
|
118
|
+
function fromUint8Array(byteArray) {
|
|
119
|
+
return getBase58Decoder().decode(byteArray);
|
|
120
|
+
}
|
|
121
|
+
function base64ToBase58(base64EncodedString) {
|
|
122
|
+
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
/**
|
|
115
126
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
116
127
|
*
|
|
@@ -257,15 +268,21 @@ function signInFallback(signInPayload, authorizationResult, protocolRequestHandl
|
|
|
257
268
|
return __awaiter(this, void 0, void 0, function* () {
|
|
258
269
|
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
259
270
|
const address = authorizationResult.accounts[0].address;
|
|
260
|
-
const siwsMessage =
|
|
271
|
+
const siwsMessage = createSIWSMessageBase64Url(Object.assign(Object.assign({}, signInPayload), { domain, address: base64ToBase58(address) }));
|
|
261
272
|
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
262
273
|
addresses: [address],
|
|
263
274
|
payloads: [siwsMessage]
|
|
264
275
|
});
|
|
276
|
+
const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);
|
|
277
|
+
const signedMessage = fromUint8Array$1(signedPayload.slice(0, signedPayload.length - 64));
|
|
278
|
+
const signature = fromUint8Array$1(signedPayload.slice(signedPayload.length - 64));
|
|
265
279
|
const signInResult = {
|
|
266
280
|
address: address,
|
|
267
|
-
|
|
268
|
-
|
|
281
|
+
// Workaround: some wallets have been observed to only reply with the message signature.
|
|
282
|
+
// This is non-compliant with the spec, but in the interest of maximizing compatibility,
|
|
283
|
+
// detect this case and reuse the original message.
|
|
284
|
+
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
285
|
+
signature
|
|
269
286
|
};
|
|
270
287
|
return signInResult;
|
|
271
288
|
});
|
|
@@ -418,7 +435,7 @@ function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority,
|
|
|
418
435
|
const url = getIntentURL('v1/associate/remote', associationURLBase);
|
|
419
436
|
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
420
437
|
url.searchParams.set('reflector', `${hostAuthority}`);
|
|
421
|
-
url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);
|
|
438
|
+
url.searchParams.set('id', `${fromUint8Array$1(reflectorId, true)}`);
|
|
422
439
|
protocolVersions.forEach((version) => {
|
|
423
440
|
url.searchParams.set('v', version);
|
|
424
441
|
});
|
|
@@ -949,7 +966,7 @@ function startRemoteScenario(config) {
|
|
|
949
966
|
const ecdhKeypair = yield generateECDHKeypair();
|
|
950
967
|
const binaryMsg = yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
951
968
|
if (encoding == 'base64') {
|
|
952
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
969
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
953
970
|
}
|
|
954
971
|
else {
|
|
955
972
|
socket.send(binaryMsg);
|
|
@@ -1007,7 +1024,7 @@ function startRemoteScenario(config) {
|
|
|
1007
1024
|
params: params !== null && params !== void 0 ? params : {},
|
|
1008
1025
|
}, sharedSecret);
|
|
1009
1026
|
if (encoding == 'base64') {
|
|
1010
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
1027
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
1011
1028
|
}
|
|
1012
1029
|
else {
|
|
1013
1030
|
socket.send(binaryMsg);
|
package/lib/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createSignInMessageText } from '@solana/wallet-standard-util';
|
|
2
|
+
import { getBase58Decoder } from '@solana/codecs-strings';
|
|
2
3
|
|
|
3
4
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
4
5
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
@@ -70,7 +71,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
70
71
|
function encode(input) {
|
|
71
72
|
return window.btoa(input);
|
|
72
73
|
}
|
|
73
|
-
function fromUint8Array(byteArray, urlsafe) {
|
|
74
|
+
function fromUint8Array$1(byteArray, urlsafe) {
|
|
74
75
|
const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
75
76
|
if (urlsafe) {
|
|
76
77
|
return base64
|
|
@@ -102,8 +103,11 @@ function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
102
103
|
function createSIWSMessage(payload) {
|
|
103
104
|
return createSignInMessageText(payload);
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
-
return encode(createSIWSMessage(payload))
|
|
106
|
+
function createSIWSMessageBase64Url(payload) {
|
|
107
|
+
return encode(createSIWSMessage(payload))
|
|
108
|
+
.replace(/\+/g, '-')
|
|
109
|
+
.replace(/\//g, '_')
|
|
110
|
+
.replace(/=+$/, ''); // convert to base64url encoding;
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
// optional features
|
|
@@ -111,6 +115,13 @@ const SolanaSignTransactions = 'solana:signTransactions';
|
|
|
111
115
|
const SolanaCloneAuthorization = 'solana:cloneAuthorization';
|
|
112
116
|
const SolanaSignInWithSolana = 'solana:signInWithSolana';
|
|
113
117
|
|
|
118
|
+
function fromUint8Array(byteArray) {
|
|
119
|
+
return getBase58Decoder().decode(byteArray);
|
|
120
|
+
}
|
|
121
|
+
function base64ToBase58(base64EncodedString) {
|
|
122
|
+
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
/**
|
|
115
126
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
116
127
|
*
|
|
@@ -257,15 +268,21 @@ function signInFallback(signInPayload, authorizationResult, protocolRequestHandl
|
|
|
257
268
|
return __awaiter(this, void 0, void 0, function* () {
|
|
258
269
|
const domain = (_a = signInPayload.domain) !== null && _a !== void 0 ? _a : window.location.host;
|
|
259
270
|
const address = authorizationResult.accounts[0].address;
|
|
260
|
-
const siwsMessage =
|
|
271
|
+
const siwsMessage = createSIWSMessageBase64Url(Object.assign(Object.assign({}, signInPayload), { domain, address: base64ToBase58(address) }));
|
|
261
272
|
const signMessageResult = yield protocolRequestHandler('sign_messages', {
|
|
262
273
|
addresses: [address],
|
|
263
274
|
payloads: [siwsMessage]
|
|
264
275
|
});
|
|
276
|
+
const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);
|
|
277
|
+
const signedMessage = fromUint8Array$1(signedPayload.slice(0, signedPayload.length - 64));
|
|
278
|
+
const signature = fromUint8Array$1(signedPayload.slice(signedPayload.length - 64));
|
|
265
279
|
const signInResult = {
|
|
266
280
|
address: address,
|
|
267
|
-
|
|
268
|
-
|
|
281
|
+
// Workaround: some wallets have been observed to only reply with the message signature.
|
|
282
|
+
// This is non-compliant with the spec, but in the interest of maximizing compatibility,
|
|
283
|
+
// detect this case and reuse the original message.
|
|
284
|
+
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
285
|
+
signature
|
|
269
286
|
};
|
|
270
287
|
return signInResult;
|
|
271
288
|
});
|
|
@@ -418,7 +435,7 @@ function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority,
|
|
|
418
435
|
const url = getIntentURL('v1/associate/remote', associationURLBase);
|
|
419
436
|
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
420
437
|
url.searchParams.set('reflector', `${hostAuthority}`);
|
|
421
|
-
url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);
|
|
438
|
+
url.searchParams.set('id', `${fromUint8Array$1(reflectorId, true)}`);
|
|
422
439
|
protocolVersions.forEach((version) => {
|
|
423
440
|
url.searchParams.set('v', version);
|
|
424
441
|
});
|
|
@@ -949,7 +966,7 @@ function startRemoteScenario(config) {
|
|
|
949
966
|
const ecdhKeypair = yield generateECDHKeypair();
|
|
950
967
|
const binaryMsg = yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
951
968
|
if (encoding == 'base64') {
|
|
952
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
969
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
953
970
|
}
|
|
954
971
|
else {
|
|
955
972
|
socket.send(binaryMsg);
|
|
@@ -1007,7 +1024,7 @@ function startRemoteScenario(config) {
|
|
|
1007
1024
|
params: params !== null && params !== void 0 ? params : {},
|
|
1008
1025
|
}, sharedSecret);
|
|
1009
1026
|
if (encoding == 'base64') {
|
|
1010
|
-
socket.send(fromUint8Array(binaryMsg));
|
|
1027
|
+
socket.send(fromUint8Array$1(binaryMsg));
|
|
1011
1028
|
}
|
|
1012
1029
|
else {
|
|
1013
1030
|
socket.send(binaryMsg);
|
|
@@ -247,7 +247,7 @@ type SignInPayloadWithRequiredFields = Partial<SignInPayload> & Required<Pick<Si
|
|
|
247
247
|
type SignInResult = Readonly<{
|
|
248
248
|
address: Base64EncodedAddress;
|
|
249
249
|
signed_message: Base64EncodedSignedMessage;
|
|
250
|
-
signature:
|
|
250
|
+
signature: Base64EncodedSignature;
|
|
251
251
|
signature_type?: string;
|
|
252
252
|
}>;
|
|
253
253
|
type Scenario = Readonly<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/base58Utils.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"names":[],"mappings":""}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -247,7 +247,7 @@ type SignInPayloadWithRequiredFields = Partial<SignInPayload> & Required<Pick<Si
|
|
|
247
247
|
type SignInResult = Readonly<{
|
|
248
248
|
address: Base64EncodedAddress;
|
|
249
249
|
signed_message: Base64EncodedSignedMessage;
|
|
250
|
-
signature:
|
|
250
|
+
signature: Base64EncodedSignature;
|
|
251
251
|
signature_type?: string;
|
|
252
252
|
}>;
|
|
253
253
|
type Scenario = Readonly<{
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/base58Utils.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"names":[],"mappings":""}
|
|
@@ -247,7 +247,7 @@ type SignInPayloadWithRequiredFields = Partial<SignInPayload> & Required<Pick<Si
|
|
|
247
247
|
type SignInResult = Readonly<{
|
|
248
248
|
address: Base64EncodedAddress;
|
|
249
249
|
signed_message: Base64EncodedSignedMessage;
|
|
250
|
-
signature:
|
|
250
|
+
signature: Base64EncodedSignature;
|
|
251
251
|
signature_type?: string;
|
|
252
252
|
}>;
|
|
253
253
|
type Scenario = Readonly<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts","../../src/codegenSpec/NativeSolanaMobileWalletAdapter.ts","../../src/__forks__/react-native/transact.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../../src/index.ts","../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/types.ts","../../src/createSIWSMessage.ts","../../src/base58Utils.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/parseHelloRsp.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts","../../src/codegenSpec/NativeSolanaMobileWalletAdapter.ts","../../src/__forks__/react-native/transact.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana-mobile/mobile-wallet-adapter-protocol",
|
|
3
3
|
"description": "An implementation of the Solana Mobile Mobile Wallet Adapter protocol. Use this to open a session with a mobile wallet app, and to issue API calls to it.",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.5",
|
|
5
5
|
"author": "Steven Luscher <steven.luscher@solanamobile.com>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"require": "./lib/cjs/index.js"
|
|
19
19
|
},
|
|
20
20
|
"browser": {
|
|
21
|
-
"import": "./lib/
|
|
22
|
-
"require": "./lib/
|
|
21
|
+
"import": "./lib/esm/index.browser.js",
|
|
22
|
+
"require": "./lib/cjs/index.browser.js"
|
|
23
23
|
},
|
|
24
24
|
"node": {
|
|
25
25
|
"import": "./lib/esm/index.js",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "agadoo"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"@solana/codecs-strings": "^4.0.0",
|
|
59
60
|
"@solana/wallet-standard": "^1.1.2",
|
|
60
61
|
"@solana/wallet-standard-util": "^1.1.1",
|
|
61
62
|
"@wallet-standard/core": "^1.0.3",
|