@solana-mobile/mobile-wallet-adapter-protocol 2.1.3 → 2.1.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 +158 -146
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -5
- package/android/gradle.properties +5 -5
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/JSONSerializationUtils.kt +11 -9
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/SolanaMobileWalletAdapterModule.kt +201 -178
- package/android/src/main/java/com/solanamobile/mobilewalletadapter/reactnative/SolanaMobileWalletAdapterPackage.kt +26 -7
- package/android/src/newarch/SolanaMobileWalletAdapter.kt +7 -0
- package/android/src/oldarch/SolanaMobileWalletAdapter.kt +16 -0
- package/lib/cjs/index.browser.js +266 -5
- package/lib/cjs/index.js +266 -5
- package/lib/cjs/index.native.js +5 -2
- package/lib/esm/index.browser.js +266 -6
- package/lib/esm/index.js +266 -6
- package/lib/types/index.browser.d.ts +17 -1
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.ts +17 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +17 -1
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +70 -58
- package/.gitignore +0 -2
- package/android/.gitignore +0 -14
- package/src/__forks__/react-native/base64Utils.ts +0 -1
- package/src/__forks__/react-native/transact.ts +0 -92
- package/src/arrayBufferToBase64String.ts +0 -10
- package/src/associationPort.ts +0 -19
- package/src/base64Utils.ts +0 -3
- package/src/createHelloReq.ts +0 -12
- package/src/createMobileWalletProxy.ts +0 -175
- package/src/createSIWSMessage.ts +0 -14
- package/src/createSequenceNumberVector.ts +0 -11
- package/src/encryptedMessage.ts +0 -60
- package/src/errors.ts +0 -95
- package/src/generateAssociationKeypair.ts +0 -10
- package/src/generateECDHKeypair.ts +0 -10
- package/src/getAssociateAndroidIntentURL.ts +0 -57
- package/src/getJWS.ts +0 -19
- package/src/getStringWithURLUnsafeBase64CharactersReplaced.ts +0 -11
- package/src/index.ts +0 -3
- package/src/jsonRpcMessage.ts +0 -38
- package/src/parseHelloRsp.ts +0 -46
- package/src/parseSessionProps.ts +0 -33
- package/src/startSession.ts +0 -94
- package/src/transact.ts +0 -266
- package/src/types.ts +0 -181
- package/tsconfig.cjs.json +0 -7
- package/tsconfig.json +0 -8
package/lib/cjs/index.js
CHANGED
|
@@ -7,6 +7,7 @@ var walletStandardUtil = require('@solana/wallet-standard-util');
|
|
|
7
7
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
8
8
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
9
9
|
ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',
|
|
10
|
+
ERROR_REFLECTOR_ID_OUT_OF_RANGE: 'ERROR_REFLECTOR_ID_OUT_OF_RANGE',
|
|
10
11
|
ERROR_FORBIDDEN_WALLET_BASE_URL: 'ERROR_FORBIDDEN_WALLET_BASE_URL',
|
|
11
12
|
ERROR_SECURE_CONTEXT_REQUIRED: 'ERROR_SECURE_CONTEXT_REQUIRED',
|
|
12
13
|
ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',
|
|
@@ -410,6 +411,24 @@ function getStringWithURLUnsafeCharactersReplaced(unsafeBase64EncodedString) {
|
|
|
410
411
|
}[m]));
|
|
411
412
|
}
|
|
412
413
|
|
|
414
|
+
function getRandomReflectorId() {
|
|
415
|
+
return assertReflectorId(getRandomInt(0, 9007199254740991)); // 0 < id < 2^53 - 1
|
|
416
|
+
}
|
|
417
|
+
function getRandomInt(min, max) {
|
|
418
|
+
const randomBuffer = new Uint32Array(1);
|
|
419
|
+
window.crypto.getRandomValues(randomBuffer);
|
|
420
|
+
let randomNumber = randomBuffer[0] / (0xffffffff + 1);
|
|
421
|
+
min = Math.ceil(min);
|
|
422
|
+
max = Math.floor(max);
|
|
423
|
+
return Math.floor(randomNumber * (max - min + 1)) + min;
|
|
424
|
+
}
|
|
425
|
+
function assertReflectorId(id) {
|
|
426
|
+
if (id < 0 || id > 9007199254740991) { // 0 < id < 2^53 - 1
|
|
427
|
+
throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_REFLECTOR_ID_OUT_OF_RANGE, `Association port number must be between 49152 and 65535. ${id} given.`, { id });
|
|
428
|
+
}
|
|
429
|
+
return id;
|
|
430
|
+
}
|
|
431
|
+
|
|
413
432
|
const INTENT_NAME = 'solana-wallet';
|
|
414
433
|
function getPathParts(pathString) {
|
|
415
434
|
return (pathString
|
|
@@ -451,6 +470,21 @@ function getAssociateAndroidIntentURL(associationPublicKey, putativePort, associ
|
|
|
451
470
|
return url;
|
|
452
471
|
});
|
|
453
472
|
}
|
|
473
|
+
function getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority, putativeId, associationURLBase, protocolVersions = ['v1']) {
|
|
474
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
475
|
+
const reflectorId = assertReflectorId(putativeId);
|
|
476
|
+
const exportedKey = yield crypto.subtle.exportKey('raw', associationPublicKey);
|
|
477
|
+
const encodedKey = arrayBufferToBase64String(exportedKey);
|
|
478
|
+
const url = getIntentURL('v1/associate/remote', associationURLBase);
|
|
479
|
+
url.searchParams.set('association', getStringWithURLUnsafeCharactersReplaced(encodedKey));
|
|
480
|
+
url.searchParams.set('reflector', `${hostAuthority}`);
|
|
481
|
+
url.searchParams.set('id', `${reflectorId}`);
|
|
482
|
+
protocolVersions.forEach((version) => {
|
|
483
|
+
url.searchParams.set('v', version);
|
|
484
|
+
});
|
|
485
|
+
return url;
|
|
486
|
+
});
|
|
487
|
+
}
|
|
454
488
|
|
|
455
489
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
456
490
|
const Browser = {
|
|
@@ -493,10 +527,8 @@ function launchUrlThroughHiddenFrame(url) {
|
|
|
493
527
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
494
528
|
_frame.contentWindow.location.href = url.toString();
|
|
495
529
|
}
|
|
496
|
-
function
|
|
530
|
+
function launchAssociation(associationUrl) {
|
|
497
531
|
return __awaiter(this, void 0, void 0, function* () {
|
|
498
|
-
const randomAssociationPort = getRandomAssociationPort();
|
|
499
|
-
const associationUrl = yield getAssociateAndroidIntentURL(associationPublicKey, randomAssociationPort, associationURLBase);
|
|
500
532
|
if (associationUrl.protocol === 'https:') {
|
|
501
533
|
// The association URL is an Android 'App Link' or iOS 'Universal Link'.
|
|
502
534
|
// These are regular web URLs that are designed to launch an app if it
|
|
@@ -527,9 +559,23 @@ function startSession(associationPublicKey, associationURLBase) {
|
|
|
527
559
|
throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND, 'Found no installed wallet that supports the mobile wallet protocol.');
|
|
528
560
|
}
|
|
529
561
|
}
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
function startSession(associationPublicKey, associationURLBase) {
|
|
565
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
566
|
+
const randomAssociationPort = getRandomAssociationPort();
|
|
567
|
+
const associationUrl = yield getAssociateAndroidIntentURL(associationPublicKey, randomAssociationPort, associationURLBase);
|
|
568
|
+
yield launchAssociation(associationUrl);
|
|
530
569
|
return randomAssociationPort;
|
|
531
570
|
});
|
|
532
571
|
}
|
|
572
|
+
function getRemoteSessionUrl(associationPublicKey, hostAuthority, associationURLBase) {
|
|
573
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
574
|
+
const randomReflectorId = getRandomReflectorId();
|
|
575
|
+
const associationUrl = yield getRemoteAssociateAndroidIntentURL(associationPublicKey, hostAuthority, randomReflectorId, associationURLBase);
|
|
576
|
+
return { associationUrl, reflectorId: randomReflectorId };
|
|
577
|
+
});
|
|
578
|
+
}
|
|
533
579
|
|
|
534
580
|
const WEBSOCKET_CONNECTION_CONFIG = {
|
|
535
581
|
/**
|
|
@@ -591,8 +637,14 @@ function transact(callback, config) {
|
|
|
591
637
|
`Got \`${state.__type}\`.`);
|
|
592
638
|
return;
|
|
593
639
|
}
|
|
594
|
-
const { associationKeypair } = state;
|
|
595
640
|
socket.removeEventListener('open', handleOpen);
|
|
641
|
+
// previous versions of this library and walletlib incorrectly implemented the MWA session
|
|
642
|
+
// establishment protocol for local connections. The dapp is supposed to wait for the
|
|
643
|
+
// APP_PING message before sending the HELLO_REQ. Instead, the dapp was sending the HELLO_REQ
|
|
644
|
+
// immediately upon connection to the websocket server regardless of wether or not an
|
|
645
|
+
// APP_PING was sent by the wallet/websocket server. We must continue to support this behavior
|
|
646
|
+
// in case the user is using a wallet that has not updated their walletlib implementation.
|
|
647
|
+
const { associationKeypair } = state;
|
|
596
648
|
const ecdhKeypair = yield generateECDHKeypair();
|
|
597
649
|
socket.send(yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
598
650
|
state = {
|
|
@@ -613,7 +665,7 @@ function transact(callback, config) {
|
|
|
613
665
|
const handleError = (_evt) => __awaiter(this, void 0, void 0, function* () {
|
|
614
666
|
disposeSocket();
|
|
615
667
|
if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {
|
|
616
|
-
reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT, `Failed to connect to the wallet websocket
|
|
668
|
+
reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT, `Failed to connect to the wallet websocket at ${websocketURL}.`));
|
|
617
669
|
}
|
|
618
670
|
else {
|
|
619
671
|
yield new Promise((resolve) => {
|
|
@@ -626,6 +678,18 @@ function transact(callback, config) {
|
|
|
626
678
|
const handleMessage = (evt) => __awaiter(this, void 0, void 0, function* () {
|
|
627
679
|
const responseBuffer = yield evt.data.arrayBuffer();
|
|
628
680
|
switch (state.__type) {
|
|
681
|
+
case 'connecting':
|
|
682
|
+
if (responseBuffer.byteLength !== 0) {
|
|
683
|
+
throw new Error('Encountered unexpected message while connecting');
|
|
684
|
+
}
|
|
685
|
+
const ecdhKeypair = yield generateECDHKeypair();
|
|
686
|
+
socket.send(yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
687
|
+
state = {
|
|
688
|
+
__type: 'hello_req_sent',
|
|
689
|
+
associationPublicKey: associationKeypair.publicKey,
|
|
690
|
+
ecdhPrivateKey: ecdhKeypair.privateKey,
|
|
691
|
+
};
|
|
692
|
+
break;
|
|
629
693
|
case 'connected':
|
|
630
694
|
try {
|
|
631
695
|
const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);
|
|
@@ -651,6 +715,17 @@ function transact(callback, config) {
|
|
|
651
715
|
}
|
|
652
716
|
break;
|
|
653
717
|
case 'hello_req_sent': {
|
|
718
|
+
// if we receive an APP_PING message (empty message), resend the HELLO_REQ (see above)
|
|
719
|
+
if (responseBuffer.byteLength === 0) {
|
|
720
|
+
const ecdhKeypair = yield generateECDHKeypair();
|
|
721
|
+
socket.send(yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
722
|
+
state = {
|
|
723
|
+
__type: 'hello_req_sent',
|
|
724
|
+
associationPublicKey: associationKeypair.publicKey,
|
|
725
|
+
ecdhPrivateKey: ecdhKeypair.privateKey,
|
|
726
|
+
};
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
654
729
|
const sharedSecret = yield parseHelloRsp(responseBuffer, state.associationPublicKey, state.ecdhPrivateKey);
|
|
655
730
|
const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);
|
|
656
731
|
const sessionProperties = sessionPropertiesBuffer.byteLength !== 0
|
|
@@ -738,6 +813,191 @@ function transact(callback, config) {
|
|
|
738
813
|
});
|
|
739
814
|
});
|
|
740
815
|
}
|
|
816
|
+
function transactRemote(callback, config) {
|
|
817
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
818
|
+
assertSecureContext();
|
|
819
|
+
const associationKeypair = yield generateAssociationKeypair();
|
|
820
|
+
const { associationUrl, reflectorId } = yield getRemoteSessionUrl(associationKeypair.publicKey, config.remoteHostAuthority, config === null || config === void 0 ? void 0 : config.baseUri);
|
|
821
|
+
const websocketURL = `wss://${config === null || config === void 0 ? void 0 : config.remoteHostAuthority}/reflect?id=${reflectorId}`;
|
|
822
|
+
let connectionStartTime;
|
|
823
|
+
const getNextRetryDelayMs = (() => {
|
|
824
|
+
const schedule = [...WEBSOCKET_CONNECTION_CONFIG.retryDelayScheduleMs];
|
|
825
|
+
return () => (schedule.length > 1 ? schedule.shift() : schedule[0]);
|
|
826
|
+
})();
|
|
827
|
+
let nextJsonRpcMessageId = 1;
|
|
828
|
+
let lastKnownInboundSequenceNumber = 0;
|
|
829
|
+
let state = { __type: 'disconnected' };
|
|
830
|
+
return { associationUrl, result: new Promise((resolve, reject) => {
|
|
831
|
+
let socket;
|
|
832
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
833
|
+
const jsonRpcResponsePromises = {};
|
|
834
|
+
const handleOpen = () => __awaiter(this, void 0, void 0, function* () {
|
|
835
|
+
if (state.__type !== 'connecting') {
|
|
836
|
+
console.warn('Expected adapter state to be `connecting` at the moment the websocket opens. ' +
|
|
837
|
+
`Got \`${state.__type}\`.`);
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
socket.removeEventListener('open', handleOpen);
|
|
841
|
+
});
|
|
842
|
+
const handleClose = (evt) => {
|
|
843
|
+
if (evt.wasClean) {
|
|
844
|
+
state = { __type: 'disconnected' };
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED, `The wallet session dropped unexpectedly (${evt.code}: ${evt.reason}).`, { closeEvent: evt }));
|
|
848
|
+
}
|
|
849
|
+
disposeSocket();
|
|
850
|
+
};
|
|
851
|
+
const handleError = (_evt) => __awaiter(this, void 0, void 0, function* () {
|
|
852
|
+
disposeSocket();
|
|
853
|
+
if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {
|
|
854
|
+
reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT, `Failed to connect to the wallet websocket at ${websocketURL}.`));
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
yield new Promise((resolve) => {
|
|
858
|
+
const retryDelayMs = getNextRetryDelayMs();
|
|
859
|
+
retryWaitTimeoutId = window.setTimeout(resolve, retryDelayMs);
|
|
860
|
+
});
|
|
861
|
+
attemptSocketConnection();
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
const handleMessage = (evt) => __awaiter(this, void 0, void 0, function* () {
|
|
865
|
+
const responseBuffer = yield evt.data.arrayBuffer();
|
|
866
|
+
switch (state.__type) {
|
|
867
|
+
case 'connecting':
|
|
868
|
+
if (responseBuffer.byteLength !== 0) {
|
|
869
|
+
throw new Error('Encountered unexpected message while connecting');
|
|
870
|
+
}
|
|
871
|
+
const ecdhKeypair = yield generateECDHKeypair();
|
|
872
|
+
socket.send(yield createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
873
|
+
state = {
|
|
874
|
+
__type: 'hello_req_sent',
|
|
875
|
+
associationPublicKey: associationKeypair.publicKey,
|
|
876
|
+
ecdhPrivateKey: ecdhKeypair.privateKey,
|
|
877
|
+
};
|
|
878
|
+
break;
|
|
879
|
+
case 'connected':
|
|
880
|
+
try {
|
|
881
|
+
const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);
|
|
882
|
+
const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);
|
|
883
|
+
if (sequenceNumber !== (lastKnownInboundSequenceNumber + 1)) {
|
|
884
|
+
throw new Error('Encrypted message has invalid sequence number');
|
|
885
|
+
}
|
|
886
|
+
lastKnownInboundSequenceNumber = sequenceNumber;
|
|
887
|
+
const jsonRpcMessage = yield decryptJsonRpcMessage(responseBuffer, state.sharedSecret);
|
|
888
|
+
const responsePromise = jsonRpcResponsePromises[jsonRpcMessage.id];
|
|
889
|
+
delete jsonRpcResponsePromises[jsonRpcMessage.id];
|
|
890
|
+
responsePromise.resolve(jsonRpcMessage.result);
|
|
891
|
+
}
|
|
892
|
+
catch (e) {
|
|
893
|
+
if (e instanceof SolanaMobileWalletAdapterProtocolError) {
|
|
894
|
+
const responsePromise = jsonRpcResponsePromises[e.jsonRpcMessageId];
|
|
895
|
+
delete jsonRpcResponsePromises[e.jsonRpcMessageId];
|
|
896
|
+
responsePromise.reject(e);
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
throw e;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
break;
|
|
903
|
+
case 'hello_req_sent': {
|
|
904
|
+
const sharedSecret = yield parseHelloRsp(responseBuffer, state.associationPublicKey, state.ecdhPrivateKey);
|
|
905
|
+
const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);
|
|
906
|
+
const sessionProperties = sessionPropertiesBuffer.byteLength !== 0
|
|
907
|
+
? yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
908
|
+
const sequenceNumberVector = sessionPropertiesBuffer.slice(0, SEQUENCE_NUMBER_BYTES);
|
|
909
|
+
const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);
|
|
910
|
+
if (sequenceNumber !== (lastKnownInboundSequenceNumber + 1)) {
|
|
911
|
+
throw new Error('Encrypted message has invalid sequence number');
|
|
912
|
+
}
|
|
913
|
+
lastKnownInboundSequenceNumber = sequenceNumber;
|
|
914
|
+
return parseSessionProps(sessionPropertiesBuffer, sharedSecret);
|
|
915
|
+
}))() : { protocol_version: 'legacy' };
|
|
916
|
+
state = { __type: 'connected', sharedSecret, sessionProperties };
|
|
917
|
+
const wallet = createMobileWalletProxy(sessionProperties.protocol_version, (method, params) => __awaiter(this, void 0, void 0, function* () {
|
|
918
|
+
const id = nextJsonRpcMessageId++;
|
|
919
|
+
socket.send(yield encryptJsonRpcMessage({
|
|
920
|
+
id,
|
|
921
|
+
jsonrpc: '2.0',
|
|
922
|
+
method,
|
|
923
|
+
params: params !== null && params !== void 0 ? params : {},
|
|
924
|
+
}, sharedSecret));
|
|
925
|
+
return new Promise((resolve, reject) => {
|
|
926
|
+
jsonRpcResponsePromises[id] = {
|
|
927
|
+
resolve(result) {
|
|
928
|
+
switch (method) {
|
|
929
|
+
case 'authorize':
|
|
930
|
+
case 'reauthorize': {
|
|
931
|
+
const { wallet_uri_base } = result;
|
|
932
|
+
if (wallet_uri_base != null) {
|
|
933
|
+
try {
|
|
934
|
+
assertSecureEndpointSpecificURI(wallet_uri_base);
|
|
935
|
+
}
|
|
936
|
+
catch (e) {
|
|
937
|
+
reject(e);
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
resolve(result);
|
|
945
|
+
},
|
|
946
|
+
reject,
|
|
947
|
+
};
|
|
948
|
+
});
|
|
949
|
+
}));
|
|
950
|
+
try {
|
|
951
|
+
resolve(yield callback(new Proxy(wallet, {
|
|
952
|
+
get(target, p) {
|
|
953
|
+
if (p == 'terminateSession') {
|
|
954
|
+
return function () {
|
|
955
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
956
|
+
disposeSocket();
|
|
957
|
+
socket.close();
|
|
958
|
+
return;
|
|
959
|
+
});
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
else
|
|
963
|
+
return target[p];
|
|
964
|
+
},
|
|
965
|
+
})));
|
|
966
|
+
}
|
|
967
|
+
catch (e) {
|
|
968
|
+
reject(e);
|
|
969
|
+
}
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
let disposeSocket;
|
|
975
|
+
let retryWaitTimeoutId;
|
|
976
|
+
const attemptSocketConnection = () => {
|
|
977
|
+
if (disposeSocket) {
|
|
978
|
+
disposeSocket();
|
|
979
|
+
}
|
|
980
|
+
state = { __type: 'connecting', associationKeypair };
|
|
981
|
+
if (connectionStartTime === undefined) {
|
|
982
|
+
connectionStartTime = Date.now();
|
|
983
|
+
}
|
|
984
|
+
socket = new WebSocket(websocketURL, [WEBSOCKET_PROTOCOL]);
|
|
985
|
+
socket.addEventListener('open', handleOpen);
|
|
986
|
+
socket.addEventListener('close', handleClose);
|
|
987
|
+
socket.addEventListener('error', handleError);
|
|
988
|
+
socket.addEventListener('message', handleMessage);
|
|
989
|
+
disposeSocket = () => {
|
|
990
|
+
window.clearTimeout(retryWaitTimeoutId);
|
|
991
|
+
socket.removeEventListener('open', handleOpen);
|
|
992
|
+
socket.removeEventListener('close', handleClose);
|
|
993
|
+
socket.removeEventListener('error', handleError);
|
|
994
|
+
socket.removeEventListener('message', handleMessage);
|
|
995
|
+
};
|
|
996
|
+
};
|
|
997
|
+
attemptSocketConnection();
|
|
998
|
+
}) };
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
741
1001
|
|
|
742
1002
|
exports.SolanaCloneAuthorization = SolanaCloneAuthorization;
|
|
743
1003
|
exports.SolanaMobileWalletAdapterError = SolanaMobileWalletAdapterError;
|
|
@@ -747,3 +1007,4 @@ exports.SolanaMobileWalletAdapterProtocolErrorCode = SolanaMobileWalletAdapterPr
|
|
|
747
1007
|
exports.SolanaSignInWithSolana = SolanaSignInWithSolana;
|
|
748
1008
|
exports.SolanaSignTransactions = SolanaSignTransactions;
|
|
749
1009
|
exports.transact = transact;
|
|
1010
|
+
exports.transactRemote = transactRemote;
|
package/lib/cjs/index.native.js
CHANGED
|
@@ -9,6 +9,7 @@ var jsBase64 = require('js-base64');
|
|
|
9
9
|
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
|
|
10
10
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
11
11
|
ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',
|
|
12
|
+
ERROR_REFLECTOR_ID_OUT_OF_RANGE: 'ERROR_REFLECTOR_ID_OUT_OF_RANGE',
|
|
12
13
|
ERROR_FORBIDDEN_WALLET_BASE_URL: 'ERROR_FORBIDDEN_WALLET_BASE_URL',
|
|
13
14
|
ERROR_SECURE_CONTEXT_REQUIRED: 'ERROR_SECURE_CONTEXT_REQUIRED',
|
|
14
15
|
ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',
|
|
@@ -71,6 +72,8 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
var NativeSolanaMobileWalletAdapter = reactNative.TurboModuleRegistry.getEnforcing('SolanaMobileWalletAdapter');
|
|
76
|
+
|
|
74
77
|
function createSIWSMessage(payload) {
|
|
75
78
|
return walletStandardUtil.createSignInMessageText(payload);
|
|
76
79
|
}
|
|
@@ -242,8 +245,8 @@ const LINKING_ERROR = `The package 'solana-mobile-wallet-adapter-protocol' doesn
|
|
|
242
245
|
' - You have added `@solana-mobile/mobile-wallet-adapter-protocol` as an explicit dependency, and\n' +
|
|
243
246
|
' - You have added `@solana-mobile/mobile-wallet-adapter-protocol` to the `nohoist` section of your package.json\n' +
|
|
244
247
|
'- You are not using Expo managed workflow\n';
|
|
245
|
-
const SolanaMobileWalletAdapter = reactNative.Platform.OS === 'android' &&
|
|
246
|
-
?
|
|
248
|
+
const SolanaMobileWalletAdapter = reactNative.Platform.OS === 'android' && NativeSolanaMobileWalletAdapter
|
|
249
|
+
? NativeSolanaMobileWalletAdapter
|
|
247
250
|
: new Proxy({}, {
|
|
248
251
|
get() {
|
|
249
252
|
throw new Error(reactNative.Platform.OS !== 'android'
|