@solana-mobile/mobile-wallet-adapter-protocol 2.2.7 → 2.2.9
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/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +3 -1
- package/android/gradlew +1 -1
- package/android/gradlew.bat +10 -21
- package/lib/cjs/chunks/base58Utils.js +63 -0
- package/lib/cjs/chunks/base58Utils.js.map +1 -0
- package/lib/cjs/chunks/encoding.js +145 -0
- package/lib/cjs/chunks/encoding.js.map +1 -0
- package/lib/cjs/encoding.browser.js +12 -0
- package/lib/cjs/encoding.js +12 -0
- package/lib/cjs/encoding.native.js +49 -0
- package/lib/cjs/encoding.native.js.map +1 -0
- package/lib/cjs/index.browser.js +36 -63
- package/lib/cjs/index.browser.js.map +1 -1
- package/lib/cjs/index.js +36 -63
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/index.native.js +14 -20
- package/lib/cjs/index.native.js.map +1 -1
- package/lib/esm/chunks/encoding.js +62 -0
- package/lib/esm/chunks/encoding.js.map +1 -0
- package/lib/esm/encoding.browser.js +2 -0
- package/lib/esm/encoding.js +2 -0
- package/lib/esm/index.browser.js +30 -57
- package/lib/esm/index.browser.js.map +1 -1
- package/lib/esm/index.js +30 -57
- package/lib/esm/index.js.map +1 -1
- package/lib/types/encoding.d.ts +16 -0
- package/lib/types/encoding.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +44 -21
- package/src/codegenSpec/NativeSolanaMobileWalletAdapter.ts +2 -0
package/lib/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { c as utf8FromUint8Array, d as base64ToBase58, f as encode, l as utf8ToUint8Array, m as toUint8Array, p as fromUint8Array, u as arrayBufferToBase64String } from "./chunks/encoding.js";
|
|
1
2
|
import { createSignInMessageText } from "@solana/wallet-standard-util";
|
|
2
|
-
import { getBase58Decoder } from "@solana/codecs-strings";
|
|
3
3
|
//#region src/errors.ts
|
|
4
4
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
5
5
|
ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: "ERROR_ASSOCIATION_PORT_OUT_OF_RANGE",
|
|
@@ -47,19 +47,6 @@ var SolanaMobileWalletAdapterProtocolError = class extends Error {
|
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
//#endregion
|
|
50
|
-
//#region src/base64Utils.ts
|
|
51
|
-
function encode(input) {
|
|
52
|
-
return window.btoa(input);
|
|
53
|
-
}
|
|
54
|
-
function fromUint8Array$1(byteArray, urlsafe) {
|
|
55
|
-
const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
56
|
-
if (urlsafe) return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
57
|
-
else return base64;
|
|
58
|
-
}
|
|
59
|
-
function toUint8Array(base64EncodedByteArray) {
|
|
60
|
-
return new Uint8Array(window.atob(base64EncodedByteArray).split("").map((c) => c.charCodeAt(0)));
|
|
61
|
-
}
|
|
62
|
-
//#endregion
|
|
63
50
|
//#region src/createHelloReq.ts
|
|
64
51
|
async function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
65
52
|
const publicKeyBuffer = await crypto.subtle.exportKey("raw", ecdhPublicKey);
|
|
@@ -86,14 +73,6 @@ const SolanaSignTransactions = "solana:signTransactions";
|
|
|
86
73
|
const SolanaCloneAuthorization = "solana:cloneAuthorization";
|
|
87
74
|
const SolanaSignInWithSolana = "solana:signInWithSolana";
|
|
88
75
|
//#endregion
|
|
89
|
-
//#region src/base58Utils.ts
|
|
90
|
-
function fromUint8Array(byteArray) {
|
|
91
|
-
return getBase58Decoder().decode(byteArray);
|
|
92
|
-
}
|
|
93
|
-
function base64ToBase58(base64EncodedString) {
|
|
94
|
-
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
95
|
-
}
|
|
96
|
-
//#endregion
|
|
97
76
|
//#region src/createMobileWalletProxy.ts
|
|
98
77
|
/**
|
|
99
78
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
@@ -109,7 +88,7 @@ function createMobileWalletProxy(protocolVersion, protocolRequestHandler) {
|
|
|
109
88
|
if (target[p] == null) target[p] = async function(inputParams) {
|
|
110
89
|
const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);
|
|
111
90
|
const result = await protocolRequestHandler(method, params);
|
|
112
|
-
if (method === "authorize" && params.sign_in_payload && !result.sign_in_result) result
|
|
91
|
+
if (method === "authorize" && params.sign_in_payload && !result.sign_in_result) result.sign_in_result = await signInFallback(params.sign_in_payload, result, protocolRequestHandler);
|
|
113
92
|
return handleMobileWalletResponse(p, result, protocolVersion);
|
|
114
93
|
};
|
|
115
94
|
return target[p];
|
|
@@ -136,7 +115,8 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
136
115
|
let method = methodName.toString().replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`).toLowerCase();
|
|
137
116
|
switch (methodName) {
|
|
138
117
|
case "authorize": {
|
|
139
|
-
|
|
118
|
+
const authorizeParams = params;
|
|
119
|
+
let { chain } = authorizeParams;
|
|
140
120
|
if (protocolVersion === "legacy") {
|
|
141
121
|
switch (chain) {
|
|
142
122
|
case "solana:testnet":
|
|
@@ -148,9 +128,10 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
148
128
|
case "solana:mainnet":
|
|
149
129
|
chain = "mainnet-beta";
|
|
150
130
|
break;
|
|
151
|
-
default: chain =
|
|
131
|
+
default: chain = authorizeParams.cluster;
|
|
152
132
|
}
|
|
153
|
-
|
|
133
|
+
authorizeParams.cluster = chain;
|
|
134
|
+
params = authorizeParams;
|
|
154
135
|
} else {
|
|
155
136
|
switch (chain) {
|
|
156
137
|
case "testnet":
|
|
@@ -161,7 +142,8 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
161
142
|
chain = "solana:mainnet";
|
|
162
143
|
break;
|
|
163
144
|
}
|
|
164
|
-
|
|
145
|
+
authorizeParams.chain = chain;
|
|
146
|
+
params = authorizeParams;
|
|
165
147
|
}
|
|
166
148
|
}
|
|
167
149
|
case "reauthorize": {
|
|
@@ -229,8 +211,8 @@ async function signInFallback(signInPayload, authorizationResult, protocolReques
|
|
|
229
211
|
addresses: [address],
|
|
230
212
|
payloads: [siwsMessage]
|
|
231
213
|
})).signed_payloads[0]);
|
|
232
|
-
const signedMessage = fromUint8Array
|
|
233
|
-
const signature = fromUint8Array
|
|
214
|
+
const signedMessage = fromUint8Array(signedPayload.slice(0, signedPayload.length - 64));
|
|
215
|
+
const signature = fromUint8Array(signedPayload.slice(signedPayload.length - 64));
|
|
234
216
|
return {
|
|
235
217
|
address,
|
|
236
218
|
signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,
|
|
@@ -250,7 +232,7 @@ async function encryptMessage(plaintext, sequenceNumber, sharedSecret) {
|
|
|
250
232
|
const sequenceNumberVector = createSequenceNumberVector(sequenceNumber);
|
|
251
233
|
const initializationVector = new Uint8Array(INITIALIZATION_VECTOR_BYTES);
|
|
252
234
|
crypto.getRandomValues(initializationVector);
|
|
253
|
-
const ciphertext = await crypto.subtle.encrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret,
|
|
235
|
+
const ciphertext = await crypto.subtle.encrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, utf8ToUint8Array(plaintext));
|
|
254
236
|
const response = new Uint8Array(sequenceNumberVector.byteLength + initializationVector.byteLength + ciphertext.byteLength);
|
|
255
237
|
response.set(new Uint8Array(sequenceNumberVector), 0);
|
|
256
238
|
response.set(new Uint8Array(initializationVector), sequenceNumberVector.byteLength);
|
|
@@ -262,7 +244,7 @@ async function decryptMessage(message, sharedSecret) {
|
|
|
262
244
|
const initializationVector = message.slice(4, 4 + INITIALIZATION_VECTOR_BYTES);
|
|
263
245
|
const ciphertext = message.slice(4 + INITIALIZATION_VECTOR_BYTES);
|
|
264
246
|
const plaintextBuffer = await crypto.subtle.decrypt(getAlgorithmParams(sequenceNumberVector, initializationVector), sharedSecret, ciphertext);
|
|
265
|
-
return
|
|
247
|
+
return utf8FromUint8Array(new Uint8Array(plaintextBuffer));
|
|
266
248
|
}
|
|
267
249
|
function getAlgorithmParams(sequenceNumber, initializationVector) {
|
|
268
250
|
return {
|
|
@@ -272,11 +254,6 @@ function getAlgorithmParams(sequenceNumber, initializationVector) {
|
|
|
272
254
|
tagLength: 128
|
|
273
255
|
};
|
|
274
256
|
}
|
|
275
|
-
let _utf8Decoder;
|
|
276
|
-
function getUtf8Decoder() {
|
|
277
|
-
if (_utf8Decoder === void 0) _utf8Decoder = new TextDecoder("utf-8");
|
|
278
|
-
return _utf8Decoder;
|
|
279
|
-
}
|
|
280
257
|
//#endregion
|
|
281
258
|
//#region src/generateAssociationKeypair.ts
|
|
282
259
|
async function generateAssociationKeypair() {
|
|
@@ -294,15 +271,6 @@ async function generateECDHKeypair() {
|
|
|
294
271
|
}, false, ["deriveKey", "deriveBits"]);
|
|
295
272
|
}
|
|
296
273
|
//#endregion
|
|
297
|
-
//#region src/arrayBufferToBase64String.ts
|
|
298
|
-
function arrayBufferToBase64String(buffer) {
|
|
299
|
-
let binary = "";
|
|
300
|
-
const bytes = new Uint8Array(buffer);
|
|
301
|
-
const len = bytes.byteLength;
|
|
302
|
-
for (let ii = 0; ii < len; ii++) binary += String.fromCharCode(bytes[ii]);
|
|
303
|
-
return window.btoa(binary);
|
|
304
|
-
}
|
|
305
|
-
//#endregion
|
|
306
274
|
//#region src/associationPort.ts
|
|
307
275
|
function getRandomAssociationPort() {
|
|
308
276
|
return assertAssociationPort(49152 + Math.floor(Math.random() * 16384));
|
|
@@ -313,7 +281,7 @@ function assertAssociationPort(port) {
|
|
|
313
281
|
}
|
|
314
282
|
//#endregion
|
|
315
283
|
//#region src/getStringWithURLUnsafeBase64CharactersReplaced.ts
|
|
316
|
-
function
|
|
284
|
+
function getStringWithURLUnsafeBase64CharactersReplaced(unsafeBase64EncodedString) {
|
|
317
285
|
return unsafeBase64EncodedString.replace(/[/+=]/g, (m) => ({
|
|
318
286
|
"/": "_",
|
|
319
287
|
"+": "-",
|
|
@@ -342,7 +310,7 @@ async function getAssociateAndroidIntentURL(associationPublicKey, putativePort,
|
|
|
342
310
|
const associationPort = assertAssociationPort(putativePort);
|
|
343
311
|
const encodedKey = arrayBufferToBase64String(await crypto.subtle.exportKey("raw", associationPublicKey));
|
|
344
312
|
const url = getIntentURL("v1/associate/local", associationURLBase);
|
|
345
|
-
url.searchParams.set("association",
|
|
313
|
+
url.searchParams.set("association", getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));
|
|
346
314
|
url.searchParams.set("port", `${associationPort}`);
|
|
347
315
|
protocolVersions.forEach((version) => {
|
|
348
316
|
url.searchParams.set("v", version);
|
|
@@ -352,9 +320,9 @@ async function getAssociateAndroidIntentURL(associationPublicKey, putativePort,
|
|
|
352
320
|
async function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority, reflectorId, associationURLBase, protocolVersions = ["v1"]) {
|
|
353
321
|
const encodedKey = arrayBufferToBase64String(await crypto.subtle.exportKey("raw", associationPublicKey));
|
|
354
322
|
const url = getIntentURL("v1/associate/remote", associationURLBase);
|
|
355
|
-
url.searchParams.set("association",
|
|
323
|
+
url.searchParams.set("association", getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));
|
|
356
324
|
url.searchParams.set("reflector", `${hostAuthority}`);
|
|
357
|
-
url.searchParams.set("id", `${fromUint8Array
|
|
325
|
+
url.searchParams.set("id", `${fromUint8Array(reflectorId, true)}`);
|
|
358
326
|
protocolVersions.forEach((version) => {
|
|
359
327
|
url.searchParams.set("v", version);
|
|
360
328
|
});
|
|
@@ -468,7 +436,7 @@ async function launchAssociation(associationUrl) {
|
|
|
468
436
|
}
|
|
469
437
|
default: assertUnreachable(browser);
|
|
470
438
|
}
|
|
471
|
-
} catch
|
|
439
|
+
} catch {
|
|
472
440
|
throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND, "Found no installed wallet that supports the mobile wallet protocol.");
|
|
473
441
|
}
|
|
474
442
|
}
|
|
@@ -510,7 +478,10 @@ function getSequenceNumberFromByteArray(byteArray) {
|
|
|
510
478
|
return new DataView(byteArray).getUint32(0, false);
|
|
511
479
|
}
|
|
512
480
|
function decodeVarLong(byteArray) {
|
|
513
|
-
|
|
481
|
+
const bytes = new Uint8Array(byteArray);
|
|
482
|
+
const l = byteArray.byteLength;
|
|
483
|
+
const limit = 10;
|
|
484
|
+
let value = 0, offset = 0, b;
|
|
514
485
|
do {
|
|
515
486
|
if (offset >= l || offset > limit) throw new RangeError("Failed to decode varint");
|
|
516
487
|
b = bytes[offset++];
|
|
@@ -522,7 +493,7 @@ function decodeVarLong(byteArray) {
|
|
|
522
493
|
};
|
|
523
494
|
}
|
|
524
495
|
function getReflectorIdFromByteArray(byteArray) {
|
|
525
|
-
|
|
496
|
+
const { value: length, offset } = decodeVarLong(byteArray);
|
|
526
497
|
return new Uint8Array(byteArray.slice(offset, offset + length));
|
|
527
498
|
}
|
|
528
499
|
async function transact(callback, config) {
|
|
@@ -589,7 +560,7 @@ async function startScenario(config) {
|
|
|
589
560
|
const handleMessage = async (evt) => {
|
|
590
561
|
const responseBuffer = await evt.data.arrayBuffer();
|
|
591
562
|
switch (state.__type) {
|
|
592
|
-
case "connecting":
|
|
563
|
+
case "connecting": {
|
|
593
564
|
if (responseBuffer.byteLength !== 0) throw new Error("Encountered unexpected message while connecting");
|
|
594
565
|
const ecdhKeypair = await generateECDHKeypair();
|
|
595
566
|
socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
@@ -599,6 +570,7 @@ async function startScenario(config) {
|
|
|
599
570
|
ecdhPrivateKey: ecdhKeypair.privateKey
|
|
600
571
|
};
|
|
601
572
|
break;
|
|
573
|
+
}
|
|
602
574
|
case "connected":
|
|
603
575
|
try {
|
|
604
576
|
const sequenceNumber = getSequenceNumberFromByteArray(responseBuffer.slice(0, 4));
|
|
@@ -726,7 +698,7 @@ async function startRemoteScenario(config) {
|
|
|
726
698
|
let state = { __type: "disconnected" };
|
|
727
699
|
let socket;
|
|
728
700
|
let disposeSocket;
|
|
729
|
-
|
|
701
|
+
const decodeBytes = async (evt) => {
|
|
730
702
|
if (encoding == "base64") return toUint8Array(await evt.data).buffer;
|
|
731
703
|
else return await evt.data.arrayBuffer();
|
|
732
704
|
};
|
|
@@ -806,11 +778,11 @@ async function startRemoteScenario(config) {
|
|
|
806
778
|
const handleMessage = async (evt) => {
|
|
807
779
|
const responseBuffer = await decodeBytes(evt);
|
|
808
780
|
switch (state.__type) {
|
|
809
|
-
case "reflector_id_received":
|
|
781
|
+
case "reflector_id_received": {
|
|
810
782
|
if (responseBuffer.byteLength !== 0) throw new Error("Encountered unexpected message while awaiting reflection");
|
|
811
783
|
const ecdhKeypair = await generateECDHKeypair();
|
|
812
784
|
const binaryMsg = await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
813
|
-
if (encoding == "base64") socket.send(fromUint8Array
|
|
785
|
+
if (encoding == "base64") socket.send(fromUint8Array(binaryMsg));
|
|
814
786
|
else socket.send(binaryMsg);
|
|
815
787
|
state = {
|
|
816
788
|
__type: "hello_req_sent",
|
|
@@ -818,6 +790,7 @@ async function startRemoteScenario(config) {
|
|
|
818
790
|
ecdhPrivateKey: ecdhKeypair.privateKey
|
|
819
791
|
};
|
|
820
792
|
break;
|
|
793
|
+
}
|
|
821
794
|
case "connected":
|
|
822
795
|
try {
|
|
823
796
|
const sequenceNumber = getSequenceNumberFromByteArray(responseBuffer.slice(0, 4));
|
|
@@ -857,7 +830,7 @@ async function startRemoteScenario(config) {
|
|
|
857
830
|
method,
|
|
858
831
|
params: params ?? {}
|
|
859
832
|
}, sharedSecret);
|
|
860
|
-
if (encoding == "base64") socket.send(fromUint8Array
|
|
833
|
+
if (encoding == "base64") socket.send(fromUint8Array(binaryMsg));
|
|
861
834
|
else socket.send(binaryMsg);
|
|
862
835
|
return new Promise((resolve, reject) => {
|
|
863
836
|
jsonRpcResponsePromises[id] = {
|