@bit-buccaneers/wallet-abstraction 0.0.11 → 0.0.13
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/dist/dev.js +54 -145
- package/dist/dev.jsx +53 -149
- package/dist/index.js +60 -144
- package/dist/index.jsx +59 -148
- package/dist/lib/connectors/phantom.d.ts +2 -0
- package/dist/lib/connectors/shared/download-only-connector.d.ts +8 -0
- package/dist/lib/connectors/shared/index.d.ts +1 -0
- package/dist/lib/connectors/solflare.d.ts +1 -0
- package/dist/lib/core/helpers.d.ts +2 -1
- package/dist/lib/core/types.d.ts +4 -1
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -50,6 +50,7 @@ var qrcodeResult = (uri, wait) => ({
|
|
|
50
50
|
wait
|
|
51
51
|
});
|
|
52
52
|
var pendingResult = () => ({ status: "pending" });
|
|
53
|
+
var downloadOnlyResult = () => ({ status: "downloadOnly" });
|
|
53
54
|
|
|
54
55
|
// src/lib/core/storage.ts
|
|
55
56
|
var storage = {
|
|
@@ -307,20 +308,6 @@ var getDappKeyPair = (storageKey) => {
|
|
|
307
308
|
});
|
|
308
309
|
return keyPair;
|
|
309
310
|
};
|
|
310
|
-
var buildConnectUrl = (config2, params) => {
|
|
311
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
312
|
-
const url = new URL(config2.connectUrl);
|
|
313
|
-
url.searchParams.set("app_url", params.appUrl);
|
|
314
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
315
|
-
url.searchParams.set("redirect_link", params.redirectUrl);
|
|
316
|
-
if (params.cluster) {
|
|
317
|
-
url.searchParams.set("cluster", params.cluster);
|
|
318
|
-
}
|
|
319
|
-
if (params.chain) {
|
|
320
|
-
url.searchParams.set("chain", params.chain);
|
|
321
|
-
}
|
|
322
|
-
return url.toString();
|
|
323
|
-
};
|
|
324
311
|
var parseConnectResponse = (urlParams, config2) => {
|
|
325
312
|
const walletPublicKey = urlParams.get(config2.encryptionKeyParam);
|
|
326
313
|
const nonce = urlParams.get("nonce");
|
|
@@ -375,29 +362,6 @@ var restoreMobileSession = (sessionKey) => {
|
|
|
375
362
|
var getStoredSession = (sessionKey) => {
|
|
376
363
|
return storage.get(sessionKey);
|
|
377
364
|
};
|
|
378
|
-
var buildSignMessageUrl = (signUrl, config2, sessionKey, message, redirectUrl) => {
|
|
379
|
-
const session = getStoredSession(sessionKey);
|
|
380
|
-
if (!session) return null;
|
|
381
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
382
|
-
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
383
|
-
const payload = {
|
|
384
|
-
message: bs582.encode(new TextEncoder().encode(message)),
|
|
385
|
-
session: session.session,
|
|
386
|
-
display: "utf8"
|
|
387
|
-
};
|
|
388
|
-
const nonce = nacl.randomBytes(24);
|
|
389
|
-
const encrypted = nacl.box.after(
|
|
390
|
-
new TextEncoder().encode(JSON.stringify(payload)),
|
|
391
|
-
nonce,
|
|
392
|
-
sharedSecret
|
|
393
|
-
);
|
|
394
|
-
const url = new URL(signUrl);
|
|
395
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
396
|
-
url.searchParams.set("nonce", bs582.encode(nonce));
|
|
397
|
-
url.searchParams.set("redirect_link", redirectUrl);
|
|
398
|
-
url.searchParams.set("payload", bs582.encode(encrypted));
|
|
399
|
-
return url.toString();
|
|
400
|
-
};
|
|
401
365
|
var parseSignMessageResponse = (config2, sessionKey) => {
|
|
402
366
|
const params = new URLSearchParams(window.location.search);
|
|
403
367
|
const nonce = params.get("nonce");
|
|
@@ -740,9 +704,48 @@ var createWcSolanaConnector = (config2) => {
|
|
|
740
704
|
};
|
|
741
705
|
};
|
|
742
706
|
|
|
707
|
+
// src/lib/connectors/shared/download-only-connector.ts
|
|
708
|
+
var createDownloadOnlySolanaConnector = (config2) => {
|
|
709
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
710
|
+
return {
|
|
711
|
+
...walletConfig2,
|
|
712
|
+
type: "solana",
|
|
713
|
+
installed: false,
|
|
714
|
+
wallet: {
|
|
715
|
+
_provider: null,
|
|
716
|
+
connect: async () => {
|
|
717
|
+
return downloadOnlyResult();
|
|
718
|
+
},
|
|
719
|
+
disconnect: async () => {
|
|
720
|
+
},
|
|
721
|
+
signMessage: async () => {
|
|
722
|
+
throw new Error("Wallet is not installed");
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
};
|
|
727
|
+
var createDownloadOnlyEvmConnector = (config2) => {
|
|
728
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
729
|
+
return {
|
|
730
|
+
...walletConfig2,
|
|
731
|
+
type: "evm",
|
|
732
|
+
installed: false,
|
|
733
|
+
wallet: {
|
|
734
|
+
_connector: null,
|
|
735
|
+
connect: async () => {
|
|
736
|
+
return downloadOnlyResult();
|
|
737
|
+
},
|
|
738
|
+
disconnect: async () => {
|
|
739
|
+
},
|
|
740
|
+
signMessage: async () => {
|
|
741
|
+
throw new Error("Wallet is not installed");
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
};
|
|
746
|
+
|
|
743
747
|
// src/lib/connectors/phantom.ts
|
|
744
748
|
var PHANTOM_CONNECT_URL = "https://phantom.app/ul/v1/connect";
|
|
745
|
-
var PHANTOM_SIGN_MESSAGE_URL = "https://phantom.app/ul/v1/signMessage";
|
|
746
749
|
var PHANTOM_BROWSE_URL = "https://phantom.app/ul/browse";
|
|
747
750
|
var createPhantomSolanaDappBrowserConnector = () => createDappBrowserSolanaConnector({
|
|
748
751
|
walletId: "phantom",
|
|
@@ -760,71 +763,9 @@ var STORAGE_KEYS2 = {
|
|
|
760
763
|
SESSION: "phantom_mobile_session",
|
|
761
764
|
SIGN_PENDING: "phantom_mobile_sign_pending"
|
|
762
765
|
};
|
|
763
|
-
|
|
764
|
-
var
|
|
765
|
-
var
|
|
766
|
-
...phantomWalletConfig,
|
|
767
|
-
type: "evm",
|
|
768
|
-
wallet: {
|
|
769
|
-
_connector: null,
|
|
770
|
-
connect: async () => {
|
|
771
|
-
const currentUrl = encodeURIComponent(window.location.href);
|
|
772
|
-
window.location.href = `${PHANTOM_BROWSE_URL}/${currentUrl}?ref=${encodeURIComponent(
|
|
773
|
-
window.location.origin
|
|
774
|
-
)}`;
|
|
775
|
-
return pendingResult();
|
|
776
|
-
},
|
|
777
|
-
disconnect: async () => {
|
|
778
|
-
},
|
|
779
|
-
signMessage: async () => {
|
|
780
|
-
throw new Error("signMessage not supported via mobile deeplink");
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
|
-
var createPhantomSolanaConnector = () => ({
|
|
785
|
-
...phantomWalletConfig,
|
|
786
|
-
type: "solana",
|
|
787
|
-
wallet: {
|
|
788
|
-
_provider: null,
|
|
789
|
-
connect: async () => {
|
|
790
|
-
if (isInPhantom() && window.solana) {
|
|
791
|
-
return connectSolanaInjected();
|
|
792
|
-
}
|
|
793
|
-
storage.setString(STORAGE_KEYS2.PENDING, "1");
|
|
794
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${PHANTOM_CONFIG.callbackParam}=1`;
|
|
795
|
-
window.location.href = buildConnectUrl(PHANTOM_CONFIG, {
|
|
796
|
-
appUrl: window.location.origin,
|
|
797
|
-
redirectUrl,
|
|
798
|
-
cluster: "mainnet-beta",
|
|
799
|
-
chain: "solana"
|
|
800
|
-
});
|
|
801
|
-
return pendingResult();
|
|
802
|
-
},
|
|
803
|
-
disconnect: async () => {
|
|
804
|
-
storage.remove(STORAGE_KEYS2.SESSION);
|
|
805
|
-
},
|
|
806
|
-
signMessage: async (message) => {
|
|
807
|
-
if (isInPhantom()) {
|
|
808
|
-
return signSolanaInjected(message);
|
|
809
|
-
}
|
|
810
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?phantom_sign_callback=1`;
|
|
811
|
-
const signUrl = buildSignMessageUrl(
|
|
812
|
-
PHANTOM_SIGN_MESSAGE_URL,
|
|
813
|
-
PHANTOM_CONFIG,
|
|
814
|
-
STORAGE_KEYS2.SESSION,
|
|
815
|
-
message,
|
|
816
|
-
redirectUrl
|
|
817
|
-
);
|
|
818
|
-
if (!signUrl) {
|
|
819
|
-
throw new Error("No Phantom session for signing");
|
|
820
|
-
}
|
|
821
|
-
storage.setString(STORAGE_KEYS2.SIGN_PENDING, "1");
|
|
822
|
-
window.location.href = signUrl;
|
|
823
|
-
return new Promise(() => {
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
});
|
|
766
|
+
WALLETS.find((i) => i.id === "phantom");
|
|
767
|
+
var createPhantomEvmConnector = () => createDownloadOnlyEvmConnector({ walletId: "phantom" });
|
|
768
|
+
var createPhantomSolanaConnector = () => createDownloadOnlySolanaConnector({ walletId: "phantom" });
|
|
828
769
|
var isPhantomMobilePending = () => storage.getString(STORAGE_KEYS2.PENDING) === "1";
|
|
829
770
|
var handlePhantomMobileCallback = () => handleMobileCallback(PHANTOM_CONFIG, STORAGE_KEYS2.PENDING, STORAGE_KEYS2.SESSION);
|
|
830
771
|
var restorePhantomMobileSession = () => restoreMobileSession(STORAGE_KEYS2.SESSION);
|
|
@@ -856,7 +797,6 @@ var createMetaMaskSolanaDappBrowserConnector = () => createDappBrowserSolanaConn
|
|
|
856
797
|
|
|
857
798
|
// src/lib/connectors/solflare.ts
|
|
858
799
|
var SOLFLARE_CONNECT_URL = "https://solflare.com/ul/v1/connect";
|
|
859
|
-
var SOLFLARE_SIGN_MESSAGE_URL = "https://solflare.com/ul/v1/signMessage";
|
|
860
800
|
var buildSolflareBrowseUrl = () => `https://solflare.com/ul/v1/browse/${encodeURIComponent(
|
|
861
801
|
window.location.href
|
|
862
802
|
)}?ref=${encodeURIComponent(window.location.origin)}`;
|
|
@@ -876,44 +816,8 @@ var STORAGE_KEYS3 = {
|
|
|
876
816
|
SESSION: "solflare_mobile_session",
|
|
877
817
|
SIGN_PENDING: "solflare_mobile_sign_pending"
|
|
878
818
|
};
|
|
879
|
-
|
|
880
|
-
var createSolflareSolanaMobileConnector = () => ({
|
|
881
|
-
...solflareWalletConfig,
|
|
882
|
-
type: "solana",
|
|
883
|
-
wallet: {
|
|
884
|
-
_provider: null,
|
|
885
|
-
connect: async () => {
|
|
886
|
-
storage.setString(STORAGE_KEYS3.PENDING, "1");
|
|
887
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${SOLFLARE_CONFIG.callbackParam}=1`;
|
|
888
|
-
window.location.href = buildConnectUrl(SOLFLARE_CONFIG, {
|
|
889
|
-
appUrl: window.location.origin,
|
|
890
|
-
redirectUrl,
|
|
891
|
-
cluster: "mainnet-beta"
|
|
892
|
-
});
|
|
893
|
-
return pendingResult();
|
|
894
|
-
},
|
|
895
|
-
disconnect: async () => {
|
|
896
|
-
storage.remove(STORAGE_KEYS3.SESSION);
|
|
897
|
-
},
|
|
898
|
-
signMessage: async (message) => {
|
|
899
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?solflare_sign_callback=1`;
|
|
900
|
-
const signUrl = buildSignMessageUrl(
|
|
901
|
-
SOLFLARE_SIGN_MESSAGE_URL,
|
|
902
|
-
SOLFLARE_CONFIG,
|
|
903
|
-
STORAGE_KEYS3.SESSION,
|
|
904
|
-
message,
|
|
905
|
-
redirectUrl
|
|
906
|
-
);
|
|
907
|
-
if (!signUrl) {
|
|
908
|
-
throw new Error("No Solflare session for signing");
|
|
909
|
-
}
|
|
910
|
-
storage.setString(STORAGE_KEYS3.SIGN_PENDING, "1");
|
|
911
|
-
window.location.href = signUrl;
|
|
912
|
-
return new Promise(() => {
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
});
|
|
819
|
+
WALLETS.find((i) => i.id === "solflare");
|
|
820
|
+
var createSolflareSolanaMobileConnector = () => createDownloadOnlySolanaConnector({ walletId: "solflare" });
|
|
917
821
|
var isSolflareMobilePending = () => storage.getString(STORAGE_KEYS3.PENDING) === "1";
|
|
918
822
|
var handleSolflareMobileCallback = () => handleMobileCallback(SOLFLARE_CONFIG, STORAGE_KEYS3.PENDING, STORAGE_KEYS3.SESSION);
|
|
919
823
|
var restoreSolflareMobileSession = () => restoreMobileSession(STORAGE_KEYS3.SESSION);
|
|
@@ -1327,11 +1231,16 @@ var SOLANA_FALLBACK_CONNECTORS = isMobile() ? [
|
|
|
1327
1231
|
var getSolanaWallets = () => {
|
|
1328
1232
|
const { get } = getWallets();
|
|
1329
1233
|
const wallets = get();
|
|
1234
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
1330
1235
|
const connectors = wallets.filter(isWalletAdapterCompatibleStandardWallet).filter((w) => {
|
|
1331
|
-
|
|
1236
|
+
if (w.constructor.name === "SolflareMetaMaskWallet") return false;
|
|
1237
|
+
if (w.name === "MetaMask" && w.icon?.includes("9945ff")) return false;
|
|
1238
|
+
if (seenNames.has(w.name)) return false;
|
|
1239
|
+
seenNames.add(w.name);
|
|
1240
|
+
return true;
|
|
1332
1241
|
}).map(createSolanaConnector);
|
|
1333
|
-
console.log({ wallets });
|
|
1334
|
-
console.log({ connectors });
|
|
1242
|
+
console.log("wallets", { wallets });
|
|
1243
|
+
console.log("connectors", { connectors });
|
|
1335
1244
|
addFallbackConnectors(connectors, SOLANA_FALLBACK_CONNECTORS);
|
|
1336
1245
|
return connectors;
|
|
1337
1246
|
};
|
package/dist/dev.jsx
CHANGED
|
@@ -25,12 +25,7 @@ var getEvmConfig = () => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
// src/lib/evm/connectors.ts
|
|
28
|
-
import {
|
|
29
|
-
connect,
|
|
30
|
-
disconnect,
|
|
31
|
-
getConnectors,
|
|
32
|
-
signMessage as wagmiSignMessage
|
|
33
|
-
} from "@wagmi/core";
|
|
28
|
+
import { connect, disconnect, getConnectors, signMessage as wagmiSignMessage } from "@wagmi/core";
|
|
34
29
|
|
|
35
30
|
// src/lib/core/constants.ts
|
|
36
31
|
var STORAGE_KEYS = {
|
|
@@ -50,6 +45,7 @@ var qrcodeResult = (uri, wait) => ({
|
|
|
50
45
|
wait
|
|
51
46
|
});
|
|
52
47
|
var pendingResult = () => ({ status: "pending" });
|
|
48
|
+
var downloadOnlyResult = () => ({ status: "downloadOnly" });
|
|
53
49
|
|
|
54
50
|
// src/lib/core/storage.ts
|
|
55
51
|
var storage = {
|
|
@@ -314,20 +310,6 @@ var getDappKeyPair = (storageKey) => {
|
|
|
314
310
|
});
|
|
315
311
|
return keyPair;
|
|
316
312
|
};
|
|
317
|
-
var buildConnectUrl = (config2, params) => {
|
|
318
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
319
|
-
const url = new URL(config2.connectUrl);
|
|
320
|
-
url.searchParams.set("app_url", params.appUrl);
|
|
321
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
322
|
-
url.searchParams.set("redirect_link", params.redirectUrl);
|
|
323
|
-
if (params.cluster) {
|
|
324
|
-
url.searchParams.set("cluster", params.cluster);
|
|
325
|
-
}
|
|
326
|
-
if (params.chain) {
|
|
327
|
-
url.searchParams.set("chain", params.chain);
|
|
328
|
-
}
|
|
329
|
-
return url.toString();
|
|
330
|
-
};
|
|
331
313
|
var parseConnectResponse = (urlParams, config2) => {
|
|
332
314
|
const walletPublicKey = urlParams.get(config2.encryptionKeyParam);
|
|
333
315
|
const nonce = urlParams.get("nonce");
|
|
@@ -382,29 +364,6 @@ var restoreMobileSession = (sessionKey) => {
|
|
|
382
364
|
var getStoredSession = (sessionKey) => {
|
|
383
365
|
return storage.get(sessionKey);
|
|
384
366
|
};
|
|
385
|
-
var buildSignMessageUrl = (signUrl, config2, sessionKey, message, redirectUrl) => {
|
|
386
|
-
const session = getStoredSession(sessionKey);
|
|
387
|
-
if (!session) return null;
|
|
388
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
389
|
-
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
390
|
-
const payload = {
|
|
391
|
-
message: bs582.encode(new TextEncoder().encode(message)),
|
|
392
|
-
session: session.session,
|
|
393
|
-
display: "utf8"
|
|
394
|
-
};
|
|
395
|
-
const nonce = nacl.randomBytes(24);
|
|
396
|
-
const encrypted = nacl.box.after(
|
|
397
|
-
new TextEncoder().encode(JSON.stringify(payload)),
|
|
398
|
-
nonce,
|
|
399
|
-
sharedSecret
|
|
400
|
-
);
|
|
401
|
-
const url = new URL(signUrl);
|
|
402
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
403
|
-
url.searchParams.set("nonce", bs582.encode(nonce));
|
|
404
|
-
url.searchParams.set("redirect_link", redirectUrl);
|
|
405
|
-
url.searchParams.set("payload", bs582.encode(encrypted));
|
|
406
|
-
return url.toString();
|
|
407
|
-
};
|
|
408
367
|
var parseSignMessageResponse = (config2, sessionKey) => {
|
|
409
368
|
const params = new URLSearchParams(window.location.search);
|
|
410
369
|
const nonce = params.get("nonce");
|
|
@@ -753,9 +712,48 @@ var createWcSolanaConnector = (config2) => {
|
|
|
753
712
|
};
|
|
754
713
|
};
|
|
755
714
|
|
|
715
|
+
// src/lib/connectors/shared/download-only-connector.ts
|
|
716
|
+
var createDownloadOnlySolanaConnector = (config2) => {
|
|
717
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
718
|
+
return {
|
|
719
|
+
...walletConfig2,
|
|
720
|
+
type: "solana",
|
|
721
|
+
installed: false,
|
|
722
|
+
wallet: {
|
|
723
|
+
_provider: null,
|
|
724
|
+
connect: async () => {
|
|
725
|
+
return downloadOnlyResult();
|
|
726
|
+
},
|
|
727
|
+
disconnect: async () => {
|
|
728
|
+
},
|
|
729
|
+
signMessage: async () => {
|
|
730
|
+
throw new Error("Wallet is not installed");
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
};
|
|
735
|
+
var createDownloadOnlyEvmConnector = (config2) => {
|
|
736
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
737
|
+
return {
|
|
738
|
+
...walletConfig2,
|
|
739
|
+
type: "evm",
|
|
740
|
+
installed: false,
|
|
741
|
+
wallet: {
|
|
742
|
+
_connector: null,
|
|
743
|
+
connect: async () => {
|
|
744
|
+
return downloadOnlyResult();
|
|
745
|
+
},
|
|
746
|
+
disconnect: async () => {
|
|
747
|
+
},
|
|
748
|
+
signMessage: async () => {
|
|
749
|
+
throw new Error("Wallet is not installed");
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
};
|
|
754
|
+
|
|
756
755
|
// src/lib/connectors/phantom.ts
|
|
757
756
|
var PHANTOM_CONNECT_URL = "https://phantom.app/ul/v1/connect";
|
|
758
|
-
var PHANTOM_SIGN_MESSAGE_URL = "https://phantom.app/ul/v1/signMessage";
|
|
759
757
|
var PHANTOM_BROWSE_URL = "https://phantom.app/ul/browse";
|
|
760
758
|
var createPhantomSolanaDappBrowserConnector = () => createDappBrowserSolanaConnector({
|
|
761
759
|
walletId: "phantom",
|
|
@@ -773,71 +771,9 @@ var STORAGE_KEYS2 = {
|
|
|
773
771
|
SESSION: "phantom_mobile_session",
|
|
774
772
|
SIGN_PENDING: "phantom_mobile_sign_pending"
|
|
775
773
|
};
|
|
776
|
-
var isInPhantom = () => isInWalletBrowser("isPhantom");
|
|
777
774
|
var phantomWalletConfig = WALLETS.find((i) => i.id === "phantom");
|
|
778
|
-
var createPhantomEvmConnector = () => ({
|
|
779
|
-
|
|
780
|
-
type: "evm",
|
|
781
|
-
wallet: {
|
|
782
|
-
_connector: null,
|
|
783
|
-
connect: async () => {
|
|
784
|
-
const currentUrl = encodeURIComponent(window.location.href);
|
|
785
|
-
window.location.href = `${PHANTOM_BROWSE_URL}/${currentUrl}?ref=${encodeURIComponent(
|
|
786
|
-
window.location.origin
|
|
787
|
-
)}`;
|
|
788
|
-
return pendingResult();
|
|
789
|
-
},
|
|
790
|
-
disconnect: async () => {
|
|
791
|
-
},
|
|
792
|
-
signMessage: async () => {
|
|
793
|
-
throw new Error("signMessage not supported via mobile deeplink");
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
});
|
|
797
|
-
var createPhantomSolanaConnector = () => ({
|
|
798
|
-
...phantomWalletConfig,
|
|
799
|
-
type: "solana",
|
|
800
|
-
wallet: {
|
|
801
|
-
_provider: null,
|
|
802
|
-
connect: async () => {
|
|
803
|
-
if (isInPhantom() && window.solana) {
|
|
804
|
-
return connectSolanaInjected();
|
|
805
|
-
}
|
|
806
|
-
storage.setString(STORAGE_KEYS2.PENDING, "1");
|
|
807
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${PHANTOM_CONFIG.callbackParam}=1`;
|
|
808
|
-
window.location.href = buildConnectUrl(PHANTOM_CONFIG, {
|
|
809
|
-
appUrl: window.location.origin,
|
|
810
|
-
redirectUrl,
|
|
811
|
-
cluster: "mainnet-beta",
|
|
812
|
-
chain: "solana"
|
|
813
|
-
});
|
|
814
|
-
return pendingResult();
|
|
815
|
-
},
|
|
816
|
-
disconnect: async () => {
|
|
817
|
-
storage.remove(STORAGE_KEYS2.SESSION);
|
|
818
|
-
},
|
|
819
|
-
signMessage: async (message) => {
|
|
820
|
-
if (isInPhantom()) {
|
|
821
|
-
return signSolanaInjected(message);
|
|
822
|
-
}
|
|
823
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?phantom_sign_callback=1`;
|
|
824
|
-
const signUrl = buildSignMessageUrl(
|
|
825
|
-
PHANTOM_SIGN_MESSAGE_URL,
|
|
826
|
-
PHANTOM_CONFIG,
|
|
827
|
-
STORAGE_KEYS2.SESSION,
|
|
828
|
-
message,
|
|
829
|
-
redirectUrl
|
|
830
|
-
);
|
|
831
|
-
if (!signUrl) {
|
|
832
|
-
throw new Error("No Phantom session for signing");
|
|
833
|
-
}
|
|
834
|
-
storage.setString(STORAGE_KEYS2.SIGN_PENDING, "1");
|
|
835
|
-
window.location.href = signUrl;
|
|
836
|
-
return new Promise(() => {
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
});
|
|
775
|
+
var createPhantomEvmConnector = () => createDownloadOnlyEvmConnector({ walletId: "phantom" });
|
|
776
|
+
var createPhantomSolanaConnector = () => createDownloadOnlySolanaConnector({ walletId: "phantom" });
|
|
841
777
|
var isPhantomMobilePending = () => storage.getString(STORAGE_KEYS2.PENDING) === "1";
|
|
842
778
|
var handlePhantomMobileCallback = () => handleMobileCallback(PHANTOM_CONFIG, STORAGE_KEYS2.PENDING, STORAGE_KEYS2.SESSION);
|
|
843
779
|
var restorePhantomMobileSession = () => restoreMobileSession(STORAGE_KEYS2.SESSION);
|
|
@@ -869,7 +805,6 @@ var createMetaMaskSolanaDappBrowserConnector = () => createDappBrowserSolanaConn
|
|
|
869
805
|
|
|
870
806
|
// src/lib/connectors/solflare.ts
|
|
871
807
|
var SOLFLARE_CONNECT_URL = "https://solflare.com/ul/v1/connect";
|
|
872
|
-
var SOLFLARE_SIGN_MESSAGE_URL = "https://solflare.com/ul/v1/signMessage";
|
|
873
808
|
var buildSolflareBrowseUrl = () => `https://solflare.com/ul/v1/browse/${encodeURIComponent(
|
|
874
809
|
window.location.href
|
|
875
810
|
)}?ref=${encodeURIComponent(window.location.origin)}`;
|
|
@@ -890,43 +825,7 @@ var STORAGE_KEYS3 = {
|
|
|
890
825
|
SIGN_PENDING: "solflare_mobile_sign_pending"
|
|
891
826
|
};
|
|
892
827
|
var solflareWalletConfig = WALLETS.find((i) => i.id === "solflare");
|
|
893
|
-
var createSolflareSolanaMobileConnector = () => ({
|
|
894
|
-
...solflareWalletConfig,
|
|
895
|
-
type: "solana",
|
|
896
|
-
wallet: {
|
|
897
|
-
_provider: null,
|
|
898
|
-
connect: async () => {
|
|
899
|
-
storage.setString(STORAGE_KEYS3.PENDING, "1");
|
|
900
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${SOLFLARE_CONFIG.callbackParam}=1`;
|
|
901
|
-
window.location.href = buildConnectUrl(SOLFLARE_CONFIG, {
|
|
902
|
-
appUrl: window.location.origin,
|
|
903
|
-
redirectUrl,
|
|
904
|
-
cluster: "mainnet-beta"
|
|
905
|
-
});
|
|
906
|
-
return pendingResult();
|
|
907
|
-
},
|
|
908
|
-
disconnect: async () => {
|
|
909
|
-
storage.remove(STORAGE_KEYS3.SESSION);
|
|
910
|
-
},
|
|
911
|
-
signMessage: async (message) => {
|
|
912
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?solflare_sign_callback=1`;
|
|
913
|
-
const signUrl = buildSignMessageUrl(
|
|
914
|
-
SOLFLARE_SIGN_MESSAGE_URL,
|
|
915
|
-
SOLFLARE_CONFIG,
|
|
916
|
-
STORAGE_KEYS3.SESSION,
|
|
917
|
-
message,
|
|
918
|
-
redirectUrl
|
|
919
|
-
);
|
|
920
|
-
if (!signUrl) {
|
|
921
|
-
throw new Error("No Solflare session for signing");
|
|
922
|
-
}
|
|
923
|
-
storage.setString(STORAGE_KEYS3.SIGN_PENDING, "1");
|
|
924
|
-
window.location.href = signUrl;
|
|
925
|
-
return new Promise(() => {
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
});
|
|
828
|
+
var createSolflareSolanaMobileConnector = () => createDownloadOnlySolanaConnector({ walletId: "solflare" });
|
|
930
829
|
var isSolflareMobilePending = () => storage.getString(STORAGE_KEYS3.PENDING) === "1";
|
|
931
830
|
var handleSolflareMobileCallback = () => handleMobileCallback(SOLFLARE_CONFIG, STORAGE_KEYS3.PENDING, STORAGE_KEYS3.SESSION);
|
|
932
831
|
var restoreSolflareMobileSession = () => restoreMobileSession(STORAGE_KEYS3.SESSION);
|
|
@@ -1364,11 +1263,16 @@ var SOLANA_FALLBACK_CONNECTORS = isMobile() ? [
|
|
|
1364
1263
|
var getSolanaWallets = () => {
|
|
1365
1264
|
const { get } = getWallets();
|
|
1366
1265
|
const wallets = get();
|
|
1266
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
1367
1267
|
const connectors = wallets.filter(isWalletAdapterCompatibleStandardWallet).filter((w) => {
|
|
1368
|
-
|
|
1268
|
+
if (w.constructor.name === "SolflareMetaMaskWallet") return false;
|
|
1269
|
+
if (w.name === "MetaMask" && w.icon?.includes("9945ff")) return false;
|
|
1270
|
+
if (seenNames.has(w.name)) return false;
|
|
1271
|
+
seenNames.add(w.name);
|
|
1272
|
+
return true;
|
|
1369
1273
|
}).map(createSolanaConnector);
|
|
1370
|
-
console.log({ wallets });
|
|
1371
|
-
console.log({ connectors });
|
|
1274
|
+
console.log("wallets", { wallets });
|
|
1275
|
+
console.log("connectors", { connectors });
|
|
1372
1276
|
addFallbackConnectors(connectors, SOLANA_FALLBACK_CONNECTORS);
|
|
1373
1277
|
return connectors;
|
|
1374
1278
|
};
|
package/dist/index.js
CHANGED
|
@@ -50,6 +50,7 @@ var qrcodeResult = (uri, wait) => ({
|
|
|
50
50
|
wait
|
|
51
51
|
});
|
|
52
52
|
var pendingResult = () => ({ status: "pending" });
|
|
53
|
+
var downloadOnlyResult = () => ({ status: "downloadOnly" });
|
|
53
54
|
|
|
54
55
|
// src/lib/core/storage.ts
|
|
55
56
|
var storage = {
|
|
@@ -307,20 +308,6 @@ var getDappKeyPair = (storageKey) => {
|
|
|
307
308
|
});
|
|
308
309
|
return keyPair;
|
|
309
310
|
};
|
|
310
|
-
var buildConnectUrl = (config2, params) => {
|
|
311
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
312
|
-
const url = new URL(config2.connectUrl);
|
|
313
|
-
url.searchParams.set("app_url", params.appUrl);
|
|
314
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
315
|
-
url.searchParams.set("redirect_link", params.redirectUrl);
|
|
316
|
-
if (params.cluster) {
|
|
317
|
-
url.searchParams.set("cluster", params.cluster);
|
|
318
|
-
}
|
|
319
|
-
if (params.chain) {
|
|
320
|
-
url.searchParams.set("chain", params.chain);
|
|
321
|
-
}
|
|
322
|
-
return url.toString();
|
|
323
|
-
};
|
|
324
311
|
var parseConnectResponse = (urlParams, config2) => {
|
|
325
312
|
const walletPublicKey = urlParams.get(config2.encryptionKeyParam);
|
|
326
313
|
const nonce = urlParams.get("nonce");
|
|
@@ -375,29 +362,6 @@ var restoreMobileSession = (sessionKey) => {
|
|
|
375
362
|
var getStoredSession = (sessionKey) => {
|
|
376
363
|
return storage.get(sessionKey);
|
|
377
364
|
};
|
|
378
|
-
var buildSignMessageUrl = (signUrl, config2, sessionKey, message, redirectUrl) => {
|
|
379
|
-
const session = getStoredSession(sessionKey);
|
|
380
|
-
if (!session) return null;
|
|
381
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
382
|
-
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
383
|
-
const payload = {
|
|
384
|
-
message: bs582.encode(new TextEncoder().encode(message)),
|
|
385
|
-
session: session.session,
|
|
386
|
-
display: "utf8"
|
|
387
|
-
};
|
|
388
|
-
const nonce = nacl.randomBytes(24);
|
|
389
|
-
const encrypted = nacl.box.after(
|
|
390
|
-
new TextEncoder().encode(JSON.stringify(payload)),
|
|
391
|
-
nonce,
|
|
392
|
-
sharedSecret
|
|
393
|
-
);
|
|
394
|
-
const url = new URL(signUrl);
|
|
395
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
396
|
-
url.searchParams.set("nonce", bs582.encode(nonce));
|
|
397
|
-
url.searchParams.set("redirect_link", redirectUrl);
|
|
398
|
-
url.searchParams.set("payload", bs582.encode(encrypted));
|
|
399
|
-
return url.toString();
|
|
400
|
-
};
|
|
401
365
|
var parseSignMessageResponse = (config2, sessionKey) => {
|
|
402
366
|
const params = new URLSearchParams(window.location.search);
|
|
403
367
|
const nonce = params.get("nonce");
|
|
@@ -514,6 +478,7 @@ var connectWalletConnect = async (options) => {
|
|
|
514
478
|
try {
|
|
515
479
|
await signClient.core.pairing.disconnect({ topic: pairing.topic });
|
|
516
480
|
} catch {
|
|
481
|
+
console.log("Failed to disconnect pairing", pairing);
|
|
517
482
|
}
|
|
518
483
|
}
|
|
519
484
|
}
|
|
@@ -552,10 +517,12 @@ var requestWalletConnect = async (method, params, chainId) => {
|
|
|
552
517
|
try {
|
|
553
518
|
await signClient.ping({ topic: currentSession.topic });
|
|
554
519
|
} catch (e) {
|
|
520
|
+
console.error("WalletConnect session ping failed:", e);
|
|
555
521
|
currentSession = null;
|
|
556
522
|
notifySessionChange(null);
|
|
557
523
|
throw new Error("WalletConnect session expired. Please reconnect.");
|
|
558
524
|
}
|
|
525
|
+
console.log("WC request:", { method, params, chainId, topic: currentSession.topic });
|
|
559
526
|
try {
|
|
560
527
|
const result = await signClient.request({
|
|
561
528
|
topic: currentSession.topic,
|
|
@@ -565,8 +532,10 @@ var requestWalletConnect = async (method, params, chainId) => {
|
|
|
565
532
|
params
|
|
566
533
|
}
|
|
567
534
|
});
|
|
535
|
+
console.log("WC response:", result);
|
|
568
536
|
return result;
|
|
569
537
|
} catch (e) {
|
|
538
|
+
console.error("WC request failed:", e);
|
|
570
539
|
throw e;
|
|
571
540
|
}
|
|
572
541
|
};
|
|
@@ -735,9 +704,48 @@ var createWcSolanaConnector = (config2) => {
|
|
|
735
704
|
};
|
|
736
705
|
};
|
|
737
706
|
|
|
707
|
+
// src/lib/connectors/shared/download-only-connector.ts
|
|
708
|
+
var createDownloadOnlySolanaConnector = (config2) => {
|
|
709
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
710
|
+
return {
|
|
711
|
+
...walletConfig2,
|
|
712
|
+
type: "solana",
|
|
713
|
+
installed: false,
|
|
714
|
+
wallet: {
|
|
715
|
+
_provider: null,
|
|
716
|
+
connect: async () => {
|
|
717
|
+
return downloadOnlyResult();
|
|
718
|
+
},
|
|
719
|
+
disconnect: async () => {
|
|
720
|
+
},
|
|
721
|
+
signMessage: async () => {
|
|
722
|
+
throw new Error("Wallet is not installed");
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
};
|
|
727
|
+
var createDownloadOnlyEvmConnector = (config2) => {
|
|
728
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
729
|
+
return {
|
|
730
|
+
...walletConfig2,
|
|
731
|
+
type: "evm",
|
|
732
|
+
installed: false,
|
|
733
|
+
wallet: {
|
|
734
|
+
_connector: null,
|
|
735
|
+
connect: async () => {
|
|
736
|
+
return downloadOnlyResult();
|
|
737
|
+
},
|
|
738
|
+
disconnect: async () => {
|
|
739
|
+
},
|
|
740
|
+
signMessage: async () => {
|
|
741
|
+
throw new Error("Wallet is not installed");
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
};
|
|
746
|
+
|
|
738
747
|
// src/lib/connectors/phantom.ts
|
|
739
748
|
var PHANTOM_CONNECT_URL = "https://phantom.app/ul/v1/connect";
|
|
740
|
-
var PHANTOM_SIGN_MESSAGE_URL = "https://phantom.app/ul/v1/signMessage";
|
|
741
749
|
var PHANTOM_BROWSE_URL = "https://phantom.app/ul/browse";
|
|
742
750
|
var createPhantomSolanaDappBrowserConnector = () => createDappBrowserSolanaConnector({
|
|
743
751
|
walletId: "phantom",
|
|
@@ -755,71 +763,9 @@ var STORAGE_KEYS2 = {
|
|
|
755
763
|
SESSION: "phantom_mobile_session",
|
|
756
764
|
SIGN_PENDING: "phantom_mobile_sign_pending"
|
|
757
765
|
};
|
|
758
|
-
|
|
759
|
-
var
|
|
760
|
-
var
|
|
761
|
-
...phantomWalletConfig,
|
|
762
|
-
type: "evm",
|
|
763
|
-
wallet: {
|
|
764
|
-
_connector: null,
|
|
765
|
-
connect: async () => {
|
|
766
|
-
const currentUrl = encodeURIComponent(window.location.href);
|
|
767
|
-
window.location.href = `${PHANTOM_BROWSE_URL}/${currentUrl}?ref=${encodeURIComponent(
|
|
768
|
-
window.location.origin
|
|
769
|
-
)}`;
|
|
770
|
-
return pendingResult();
|
|
771
|
-
},
|
|
772
|
-
disconnect: async () => {
|
|
773
|
-
},
|
|
774
|
-
signMessage: async () => {
|
|
775
|
-
throw new Error("signMessage not supported via mobile deeplink");
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
});
|
|
779
|
-
var createPhantomSolanaConnector = () => ({
|
|
780
|
-
...phantomWalletConfig,
|
|
781
|
-
type: "solana",
|
|
782
|
-
wallet: {
|
|
783
|
-
_provider: null,
|
|
784
|
-
connect: async () => {
|
|
785
|
-
if (isInPhantom() && window.solana) {
|
|
786
|
-
return connectSolanaInjected();
|
|
787
|
-
}
|
|
788
|
-
storage.setString(STORAGE_KEYS2.PENDING, "1");
|
|
789
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${PHANTOM_CONFIG.callbackParam}=1`;
|
|
790
|
-
window.location.href = buildConnectUrl(PHANTOM_CONFIG, {
|
|
791
|
-
appUrl: window.location.origin,
|
|
792
|
-
redirectUrl,
|
|
793
|
-
cluster: "mainnet-beta",
|
|
794
|
-
chain: "solana"
|
|
795
|
-
});
|
|
796
|
-
return pendingResult();
|
|
797
|
-
},
|
|
798
|
-
disconnect: async () => {
|
|
799
|
-
storage.remove(STORAGE_KEYS2.SESSION);
|
|
800
|
-
},
|
|
801
|
-
signMessage: async (message) => {
|
|
802
|
-
if (isInPhantom()) {
|
|
803
|
-
return signSolanaInjected(message);
|
|
804
|
-
}
|
|
805
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?phantom_sign_callback=1`;
|
|
806
|
-
const signUrl = buildSignMessageUrl(
|
|
807
|
-
PHANTOM_SIGN_MESSAGE_URL,
|
|
808
|
-
PHANTOM_CONFIG,
|
|
809
|
-
STORAGE_KEYS2.SESSION,
|
|
810
|
-
message,
|
|
811
|
-
redirectUrl
|
|
812
|
-
);
|
|
813
|
-
if (!signUrl) {
|
|
814
|
-
throw new Error("No Phantom session for signing");
|
|
815
|
-
}
|
|
816
|
-
storage.setString(STORAGE_KEYS2.SIGN_PENDING, "1");
|
|
817
|
-
window.location.href = signUrl;
|
|
818
|
-
return new Promise(() => {
|
|
819
|
-
});
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
});
|
|
766
|
+
WALLETS.find((i) => i.id === "phantom");
|
|
767
|
+
var createPhantomEvmConnector = () => createDownloadOnlyEvmConnector({ walletId: "phantom" });
|
|
768
|
+
var createPhantomSolanaConnector = () => createDownloadOnlySolanaConnector({ walletId: "phantom" });
|
|
823
769
|
var isPhantomMobilePending = () => storage.getString(STORAGE_KEYS2.PENDING) === "1";
|
|
824
770
|
var handlePhantomMobileCallback = () => handleMobileCallback(PHANTOM_CONFIG, STORAGE_KEYS2.PENDING, STORAGE_KEYS2.SESSION);
|
|
825
771
|
var restorePhantomMobileSession = () => restoreMobileSession(STORAGE_KEYS2.SESSION);
|
|
@@ -851,7 +797,6 @@ var createMetaMaskSolanaDappBrowserConnector = () => createDappBrowserSolanaConn
|
|
|
851
797
|
|
|
852
798
|
// src/lib/connectors/solflare.ts
|
|
853
799
|
var SOLFLARE_CONNECT_URL = "https://solflare.com/ul/v1/connect";
|
|
854
|
-
var SOLFLARE_SIGN_MESSAGE_URL = "https://solflare.com/ul/v1/signMessage";
|
|
855
800
|
var buildSolflareBrowseUrl = () => `https://solflare.com/ul/v1/browse/${encodeURIComponent(
|
|
856
801
|
window.location.href
|
|
857
802
|
)}?ref=${encodeURIComponent(window.location.origin)}`;
|
|
@@ -871,44 +816,8 @@ var STORAGE_KEYS3 = {
|
|
|
871
816
|
SESSION: "solflare_mobile_session",
|
|
872
817
|
SIGN_PENDING: "solflare_mobile_sign_pending"
|
|
873
818
|
};
|
|
874
|
-
|
|
875
|
-
var createSolflareSolanaMobileConnector = () => ({
|
|
876
|
-
...solflareWalletConfig,
|
|
877
|
-
type: "solana",
|
|
878
|
-
wallet: {
|
|
879
|
-
_provider: null,
|
|
880
|
-
connect: async () => {
|
|
881
|
-
storage.setString(STORAGE_KEYS3.PENDING, "1");
|
|
882
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${SOLFLARE_CONFIG.callbackParam}=1`;
|
|
883
|
-
window.location.href = buildConnectUrl(SOLFLARE_CONFIG, {
|
|
884
|
-
appUrl: window.location.origin,
|
|
885
|
-
redirectUrl,
|
|
886
|
-
cluster: "mainnet-beta"
|
|
887
|
-
});
|
|
888
|
-
return pendingResult();
|
|
889
|
-
},
|
|
890
|
-
disconnect: async () => {
|
|
891
|
-
storage.remove(STORAGE_KEYS3.SESSION);
|
|
892
|
-
},
|
|
893
|
-
signMessage: async (message) => {
|
|
894
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?solflare_sign_callback=1`;
|
|
895
|
-
const signUrl = buildSignMessageUrl(
|
|
896
|
-
SOLFLARE_SIGN_MESSAGE_URL,
|
|
897
|
-
SOLFLARE_CONFIG,
|
|
898
|
-
STORAGE_KEYS3.SESSION,
|
|
899
|
-
message,
|
|
900
|
-
redirectUrl
|
|
901
|
-
);
|
|
902
|
-
if (!signUrl) {
|
|
903
|
-
throw new Error("No Solflare session for signing");
|
|
904
|
-
}
|
|
905
|
-
storage.setString(STORAGE_KEYS3.SIGN_PENDING, "1");
|
|
906
|
-
window.location.href = signUrl;
|
|
907
|
-
return new Promise(() => {
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
});
|
|
819
|
+
WALLETS.find((i) => i.id === "solflare");
|
|
820
|
+
var createSolflareSolanaMobileConnector = () => createDownloadOnlySolanaConnector({ walletId: "solflare" });
|
|
912
821
|
var isSolflareMobilePending = () => storage.getString(STORAGE_KEYS3.PENDING) === "1";
|
|
913
822
|
var handleSolflareMobileCallback = () => handleMobileCallback(SOLFLARE_CONFIG, STORAGE_KEYS3.PENDING, STORAGE_KEYS3.SESSION);
|
|
914
823
|
var restoreSolflareMobileSession = () => restoreMobileSession(STORAGE_KEYS3.SESSION);
|
|
@@ -1322,9 +1231,16 @@ var SOLANA_FALLBACK_CONNECTORS = isMobile() ? [
|
|
|
1322
1231
|
var getSolanaWallets = () => {
|
|
1323
1232
|
const { get } = getWallets();
|
|
1324
1233
|
const wallets = get();
|
|
1234
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
1325
1235
|
const connectors = wallets.filter(isWalletAdapterCompatibleStandardWallet).filter((w) => {
|
|
1326
|
-
|
|
1236
|
+
if (w.constructor.name === "SolflareMetaMaskWallet") return false;
|
|
1237
|
+
if (w.name === "MetaMask" && w.icon?.includes("9945ff")) return false;
|
|
1238
|
+
if (seenNames.has(w.name)) return false;
|
|
1239
|
+
seenNames.add(w.name);
|
|
1240
|
+
return true;
|
|
1327
1241
|
}).map(createSolanaConnector);
|
|
1242
|
+
console.log("wallets", { wallets });
|
|
1243
|
+
console.log("connectors", { connectors });
|
|
1328
1244
|
addFallbackConnectors(connectors, SOLANA_FALLBACK_CONNECTORS);
|
|
1329
1245
|
return connectors;
|
|
1330
1246
|
};
|
|
@@ -1594,7 +1510,7 @@ var useWalletConnect = (options) => {
|
|
|
1594
1510
|
options.onEvmConnection(getEvmAccountFromSession(session.namespaces));
|
|
1595
1511
|
}
|
|
1596
1512
|
if (session.namespaces.solana?.accounts?.[0] && options.onSolanaConnection) {
|
|
1597
|
-
getSolanaAccountFromSession(session.namespaces).then(options.onSolanaConnection).catch((err) =>
|
|
1513
|
+
getSolanaAccountFromSession(session.namespaces).then(options.onSolanaConnection).catch((err) => console.error("Solana session parse error:", err));
|
|
1598
1514
|
}
|
|
1599
1515
|
};
|
|
1600
1516
|
const existingSession = getCurrentSession();
|
package/dist/index.jsx
CHANGED
|
@@ -25,12 +25,7 @@ var getEvmConfig = () => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
// src/lib/evm/connectors.ts
|
|
28
|
-
import {
|
|
29
|
-
connect,
|
|
30
|
-
disconnect,
|
|
31
|
-
getConnectors,
|
|
32
|
-
signMessage as wagmiSignMessage
|
|
33
|
-
} from "@wagmi/core";
|
|
28
|
+
import { connect, disconnect, getConnectors, signMessage as wagmiSignMessage } from "@wagmi/core";
|
|
34
29
|
|
|
35
30
|
// src/lib/core/constants.ts
|
|
36
31
|
var STORAGE_KEYS = {
|
|
@@ -50,6 +45,7 @@ var qrcodeResult = (uri, wait) => ({
|
|
|
50
45
|
wait
|
|
51
46
|
});
|
|
52
47
|
var pendingResult = () => ({ status: "pending" });
|
|
48
|
+
var downloadOnlyResult = () => ({ status: "downloadOnly" });
|
|
53
49
|
|
|
54
50
|
// src/lib/core/storage.ts
|
|
55
51
|
var storage = {
|
|
@@ -314,20 +310,6 @@ var getDappKeyPair = (storageKey) => {
|
|
|
314
310
|
});
|
|
315
311
|
return keyPair;
|
|
316
312
|
};
|
|
317
|
-
var buildConnectUrl = (config2, params) => {
|
|
318
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
319
|
-
const url = new URL(config2.connectUrl);
|
|
320
|
-
url.searchParams.set("app_url", params.appUrl);
|
|
321
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
322
|
-
url.searchParams.set("redirect_link", params.redirectUrl);
|
|
323
|
-
if (params.cluster) {
|
|
324
|
-
url.searchParams.set("cluster", params.cluster);
|
|
325
|
-
}
|
|
326
|
-
if (params.chain) {
|
|
327
|
-
url.searchParams.set("chain", params.chain);
|
|
328
|
-
}
|
|
329
|
-
return url.toString();
|
|
330
|
-
};
|
|
331
313
|
var parseConnectResponse = (urlParams, config2) => {
|
|
332
314
|
const walletPublicKey = urlParams.get(config2.encryptionKeyParam);
|
|
333
315
|
const nonce = urlParams.get("nonce");
|
|
@@ -382,29 +364,6 @@ var restoreMobileSession = (sessionKey) => {
|
|
|
382
364
|
var getStoredSession = (sessionKey) => {
|
|
383
365
|
return storage.get(sessionKey);
|
|
384
366
|
};
|
|
385
|
-
var buildSignMessageUrl = (signUrl, config2, sessionKey, message, redirectUrl) => {
|
|
386
|
-
const session = getStoredSession(sessionKey);
|
|
387
|
-
if (!session) return null;
|
|
388
|
-
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
389
|
-
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
390
|
-
const payload = {
|
|
391
|
-
message: bs582.encode(new TextEncoder().encode(message)),
|
|
392
|
-
session: session.session,
|
|
393
|
-
display: "utf8"
|
|
394
|
-
};
|
|
395
|
-
const nonce = nacl.randomBytes(24);
|
|
396
|
-
const encrypted = nacl.box.after(
|
|
397
|
-
new TextEncoder().encode(JSON.stringify(payload)),
|
|
398
|
-
nonce,
|
|
399
|
-
sharedSecret
|
|
400
|
-
);
|
|
401
|
-
const url = new URL(signUrl);
|
|
402
|
-
url.searchParams.set("dapp_encryption_public_key", bs582.encode(keyPair.publicKey));
|
|
403
|
-
url.searchParams.set("nonce", bs582.encode(nonce));
|
|
404
|
-
url.searchParams.set("redirect_link", redirectUrl);
|
|
405
|
-
url.searchParams.set("payload", bs582.encode(encrypted));
|
|
406
|
-
return url.toString();
|
|
407
|
-
};
|
|
408
367
|
var parseSignMessageResponse = (config2, sessionKey) => {
|
|
409
368
|
const params = new URLSearchParams(window.location.search);
|
|
410
369
|
const nonce = params.get("nonce");
|
|
@@ -524,6 +483,7 @@ var connectWalletConnect = async (options) => {
|
|
|
524
483
|
try {
|
|
525
484
|
await signClient.core.pairing.disconnect({ topic: pairing.topic });
|
|
526
485
|
} catch {
|
|
486
|
+
console.log("Failed to disconnect pairing", pairing);
|
|
527
487
|
}
|
|
528
488
|
}
|
|
529
489
|
}
|
|
@@ -562,10 +522,12 @@ var requestWalletConnect = async (method, params, chainId) => {
|
|
|
562
522
|
try {
|
|
563
523
|
await signClient.ping({ topic: currentSession.topic });
|
|
564
524
|
} catch (e) {
|
|
525
|
+
console.error("WalletConnect session ping failed:", e);
|
|
565
526
|
currentSession = null;
|
|
566
527
|
notifySessionChange(null);
|
|
567
528
|
throw new Error("WalletConnect session expired. Please reconnect.");
|
|
568
529
|
}
|
|
530
|
+
console.log("WC request:", { method, params, chainId, topic: currentSession.topic });
|
|
569
531
|
try {
|
|
570
532
|
const result = await signClient.request({
|
|
571
533
|
topic: currentSession.topic,
|
|
@@ -575,8 +537,10 @@ var requestWalletConnect = async (method, params, chainId) => {
|
|
|
575
537
|
params
|
|
576
538
|
}
|
|
577
539
|
});
|
|
540
|
+
console.log("WC response:", result);
|
|
578
541
|
return result;
|
|
579
542
|
} catch (e) {
|
|
543
|
+
console.error("WC request failed:", e);
|
|
580
544
|
throw e;
|
|
581
545
|
}
|
|
582
546
|
};
|
|
@@ -748,9 +712,48 @@ var createWcSolanaConnector = (config2) => {
|
|
|
748
712
|
};
|
|
749
713
|
};
|
|
750
714
|
|
|
715
|
+
// src/lib/connectors/shared/download-only-connector.ts
|
|
716
|
+
var createDownloadOnlySolanaConnector = (config2) => {
|
|
717
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
718
|
+
return {
|
|
719
|
+
...walletConfig2,
|
|
720
|
+
type: "solana",
|
|
721
|
+
installed: false,
|
|
722
|
+
wallet: {
|
|
723
|
+
_provider: null,
|
|
724
|
+
connect: async () => {
|
|
725
|
+
return downloadOnlyResult();
|
|
726
|
+
},
|
|
727
|
+
disconnect: async () => {
|
|
728
|
+
},
|
|
729
|
+
signMessage: async () => {
|
|
730
|
+
throw new Error("Wallet is not installed");
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
};
|
|
735
|
+
var createDownloadOnlyEvmConnector = (config2) => {
|
|
736
|
+
const walletConfig2 = WALLETS.find((w) => w.id === config2.walletId);
|
|
737
|
+
return {
|
|
738
|
+
...walletConfig2,
|
|
739
|
+
type: "evm",
|
|
740
|
+
installed: false,
|
|
741
|
+
wallet: {
|
|
742
|
+
_connector: null,
|
|
743
|
+
connect: async () => {
|
|
744
|
+
return downloadOnlyResult();
|
|
745
|
+
},
|
|
746
|
+
disconnect: async () => {
|
|
747
|
+
},
|
|
748
|
+
signMessage: async () => {
|
|
749
|
+
throw new Error("Wallet is not installed");
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
};
|
|
754
|
+
|
|
751
755
|
// src/lib/connectors/phantom.ts
|
|
752
756
|
var PHANTOM_CONNECT_URL = "https://phantom.app/ul/v1/connect";
|
|
753
|
-
var PHANTOM_SIGN_MESSAGE_URL = "https://phantom.app/ul/v1/signMessage";
|
|
754
757
|
var PHANTOM_BROWSE_URL = "https://phantom.app/ul/browse";
|
|
755
758
|
var createPhantomSolanaDappBrowserConnector = () => createDappBrowserSolanaConnector({
|
|
756
759
|
walletId: "phantom",
|
|
@@ -768,71 +771,9 @@ var STORAGE_KEYS2 = {
|
|
|
768
771
|
SESSION: "phantom_mobile_session",
|
|
769
772
|
SIGN_PENDING: "phantom_mobile_sign_pending"
|
|
770
773
|
};
|
|
771
|
-
var isInPhantom = () => isInWalletBrowser("isPhantom");
|
|
772
774
|
var phantomWalletConfig = WALLETS.find((i) => i.id === "phantom");
|
|
773
|
-
var createPhantomEvmConnector = () => ({
|
|
774
|
-
|
|
775
|
-
type: "evm",
|
|
776
|
-
wallet: {
|
|
777
|
-
_connector: null,
|
|
778
|
-
connect: async () => {
|
|
779
|
-
const currentUrl = encodeURIComponent(window.location.href);
|
|
780
|
-
window.location.href = `${PHANTOM_BROWSE_URL}/${currentUrl}?ref=${encodeURIComponent(
|
|
781
|
-
window.location.origin
|
|
782
|
-
)}`;
|
|
783
|
-
return pendingResult();
|
|
784
|
-
},
|
|
785
|
-
disconnect: async () => {
|
|
786
|
-
},
|
|
787
|
-
signMessage: async () => {
|
|
788
|
-
throw new Error("signMessage not supported via mobile deeplink");
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
var createPhantomSolanaConnector = () => ({
|
|
793
|
-
...phantomWalletConfig,
|
|
794
|
-
type: "solana",
|
|
795
|
-
wallet: {
|
|
796
|
-
_provider: null,
|
|
797
|
-
connect: async () => {
|
|
798
|
-
if (isInPhantom() && window.solana) {
|
|
799
|
-
return connectSolanaInjected();
|
|
800
|
-
}
|
|
801
|
-
storage.setString(STORAGE_KEYS2.PENDING, "1");
|
|
802
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${PHANTOM_CONFIG.callbackParam}=1`;
|
|
803
|
-
window.location.href = buildConnectUrl(PHANTOM_CONFIG, {
|
|
804
|
-
appUrl: window.location.origin,
|
|
805
|
-
redirectUrl,
|
|
806
|
-
cluster: "mainnet-beta",
|
|
807
|
-
chain: "solana"
|
|
808
|
-
});
|
|
809
|
-
return pendingResult();
|
|
810
|
-
},
|
|
811
|
-
disconnect: async () => {
|
|
812
|
-
storage.remove(STORAGE_KEYS2.SESSION);
|
|
813
|
-
},
|
|
814
|
-
signMessage: async (message) => {
|
|
815
|
-
if (isInPhantom()) {
|
|
816
|
-
return signSolanaInjected(message);
|
|
817
|
-
}
|
|
818
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?phantom_sign_callback=1`;
|
|
819
|
-
const signUrl = buildSignMessageUrl(
|
|
820
|
-
PHANTOM_SIGN_MESSAGE_URL,
|
|
821
|
-
PHANTOM_CONFIG,
|
|
822
|
-
STORAGE_KEYS2.SESSION,
|
|
823
|
-
message,
|
|
824
|
-
redirectUrl
|
|
825
|
-
);
|
|
826
|
-
if (!signUrl) {
|
|
827
|
-
throw new Error("No Phantom session for signing");
|
|
828
|
-
}
|
|
829
|
-
storage.setString(STORAGE_KEYS2.SIGN_PENDING, "1");
|
|
830
|
-
window.location.href = signUrl;
|
|
831
|
-
return new Promise(() => {
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
});
|
|
775
|
+
var createPhantomEvmConnector = () => createDownloadOnlyEvmConnector({ walletId: "phantom" });
|
|
776
|
+
var createPhantomSolanaConnector = () => createDownloadOnlySolanaConnector({ walletId: "phantom" });
|
|
836
777
|
var isPhantomMobilePending = () => storage.getString(STORAGE_KEYS2.PENDING) === "1";
|
|
837
778
|
var handlePhantomMobileCallback = () => handleMobileCallback(PHANTOM_CONFIG, STORAGE_KEYS2.PENDING, STORAGE_KEYS2.SESSION);
|
|
838
779
|
var restorePhantomMobileSession = () => restoreMobileSession(STORAGE_KEYS2.SESSION);
|
|
@@ -864,7 +805,6 @@ var createMetaMaskSolanaDappBrowserConnector = () => createDappBrowserSolanaConn
|
|
|
864
805
|
|
|
865
806
|
// src/lib/connectors/solflare.ts
|
|
866
807
|
var SOLFLARE_CONNECT_URL = "https://solflare.com/ul/v1/connect";
|
|
867
|
-
var SOLFLARE_SIGN_MESSAGE_URL = "https://solflare.com/ul/v1/signMessage";
|
|
868
808
|
var buildSolflareBrowseUrl = () => `https://solflare.com/ul/v1/browse/${encodeURIComponent(
|
|
869
809
|
window.location.href
|
|
870
810
|
)}?ref=${encodeURIComponent(window.location.origin)}`;
|
|
@@ -885,43 +825,7 @@ var STORAGE_KEYS3 = {
|
|
|
885
825
|
SIGN_PENDING: "solflare_mobile_sign_pending"
|
|
886
826
|
};
|
|
887
827
|
var solflareWalletConfig = WALLETS.find((i) => i.id === "solflare");
|
|
888
|
-
var createSolflareSolanaMobileConnector = () => ({
|
|
889
|
-
...solflareWalletConfig,
|
|
890
|
-
type: "solana",
|
|
891
|
-
wallet: {
|
|
892
|
-
_provider: null,
|
|
893
|
-
connect: async () => {
|
|
894
|
-
storage.setString(STORAGE_KEYS3.PENDING, "1");
|
|
895
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?${SOLFLARE_CONFIG.callbackParam}=1`;
|
|
896
|
-
window.location.href = buildConnectUrl(SOLFLARE_CONFIG, {
|
|
897
|
-
appUrl: window.location.origin,
|
|
898
|
-
redirectUrl,
|
|
899
|
-
cluster: "mainnet-beta"
|
|
900
|
-
});
|
|
901
|
-
return pendingResult();
|
|
902
|
-
},
|
|
903
|
-
disconnect: async () => {
|
|
904
|
-
storage.remove(STORAGE_KEYS3.SESSION);
|
|
905
|
-
},
|
|
906
|
-
signMessage: async (message) => {
|
|
907
|
-
const redirectUrl = `${window.location.origin}${window.location.pathname}?solflare_sign_callback=1`;
|
|
908
|
-
const signUrl = buildSignMessageUrl(
|
|
909
|
-
SOLFLARE_SIGN_MESSAGE_URL,
|
|
910
|
-
SOLFLARE_CONFIG,
|
|
911
|
-
STORAGE_KEYS3.SESSION,
|
|
912
|
-
message,
|
|
913
|
-
redirectUrl
|
|
914
|
-
);
|
|
915
|
-
if (!signUrl) {
|
|
916
|
-
throw new Error("No Solflare session for signing");
|
|
917
|
-
}
|
|
918
|
-
storage.setString(STORAGE_KEYS3.SIGN_PENDING, "1");
|
|
919
|
-
window.location.href = signUrl;
|
|
920
|
-
return new Promise(() => {
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
});
|
|
828
|
+
var createSolflareSolanaMobileConnector = () => createDownloadOnlySolanaConnector({ walletId: "solflare" });
|
|
925
829
|
var isSolflareMobilePending = () => storage.getString(STORAGE_KEYS3.PENDING) === "1";
|
|
926
830
|
var handleSolflareMobileCallback = () => handleMobileCallback(SOLFLARE_CONFIG, STORAGE_KEYS3.PENDING, STORAGE_KEYS3.SESSION);
|
|
927
831
|
var restoreSolflareMobileSession = () => restoreMobileSession(STORAGE_KEYS3.SESSION);
|
|
@@ -1359,9 +1263,16 @@ var SOLANA_FALLBACK_CONNECTORS = isMobile() ? [
|
|
|
1359
1263
|
var getSolanaWallets = () => {
|
|
1360
1264
|
const { get } = getWallets();
|
|
1361
1265
|
const wallets = get();
|
|
1266
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
1362
1267
|
const connectors = wallets.filter(isWalletAdapterCompatibleStandardWallet).filter((w) => {
|
|
1363
|
-
|
|
1268
|
+
if (w.constructor.name === "SolflareMetaMaskWallet") return false;
|
|
1269
|
+
if (w.name === "MetaMask" && w.icon?.includes("9945ff")) return false;
|
|
1270
|
+
if (seenNames.has(w.name)) return false;
|
|
1271
|
+
seenNames.add(w.name);
|
|
1272
|
+
return true;
|
|
1364
1273
|
}).map(createSolanaConnector);
|
|
1274
|
+
console.log("wallets", { wallets });
|
|
1275
|
+
console.log("connectors", { connectors });
|
|
1365
1276
|
addFallbackConnectors(connectors, SOLANA_FALLBACK_CONNECTORS);
|
|
1366
1277
|
return connectors;
|
|
1367
1278
|
};
|
|
@@ -1647,7 +1558,7 @@ var useWalletConnect = (options) => {
|
|
|
1647
1558
|
options.onEvmConnection(getEvmAccountFromSession(session.namespaces));
|
|
1648
1559
|
}
|
|
1649
1560
|
if (session.namespaces.solana?.accounts?.[0] && options.onSolanaConnection) {
|
|
1650
|
-
getSolanaAccountFromSession(session.namespaces).then(options.onSolanaConnection).catch((err) =>
|
|
1561
|
+
getSolanaAccountFromSession(session.namespaces).then(options.onSolanaConnection).catch((err) => console.error("Solana session parse error:", err));
|
|
1651
1562
|
}
|
|
1652
1563
|
};
|
|
1653
1564
|
const existingSession = getCurrentSession();
|
|
@@ -3,7 +3,9 @@ import type { EvmWalletConnector } from '../evm';
|
|
|
3
3
|
import type { SolanaWalletConnector } from '../solana';
|
|
4
4
|
export declare const createPhantomSolanaDappBrowserConnector: () => SolanaWalletConnector;
|
|
5
5
|
export declare const createPhantomEvmConnector: () => EvmWalletConnector;
|
|
6
|
+
export declare const createPhantomEvmConnectorDeeplink: () => EvmWalletConnector;
|
|
6
7
|
export declare const createPhantomSolanaConnector: () => SolanaWalletConnector;
|
|
8
|
+
export declare const createPhantomSolanaConnectorDeeplink: () => SolanaWalletConnector;
|
|
7
9
|
export declare const isPhantomMobilePending: () => boolean;
|
|
8
10
|
export declare const handlePhantomMobileCallback: () => ConnectedResult | null;
|
|
9
11
|
export declare const restorePhantomMobileSession: () => ConnectedResult | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EvmWalletConnector } from '../../evm';
|
|
2
|
+
import type { SolanaWalletConnector } from '../../solana';
|
|
3
|
+
import { type WalletId } from '../../wallets';
|
|
4
|
+
export interface DownloadOnlyWalletConfig {
|
|
5
|
+
walletId: WalletId;
|
|
6
|
+
}
|
|
7
|
+
export declare const createDownloadOnlySolanaConnector: (config: DownloadOnlyWalletConfig) => SolanaWalletConnector;
|
|
8
|
+
export declare const createDownloadOnlyEvmConnector: (config: DownloadOnlyWalletConfig) => EvmWalletConnector;
|
|
@@ -3,6 +3,7 @@ import type { SolanaWalletConnector } from '../solana';
|
|
|
3
3
|
import { type StoredSession } from './shared';
|
|
4
4
|
export declare const createSolflareSolanaDappBrowserConnector: () => SolanaWalletConnector;
|
|
5
5
|
export declare const createSolflareSolanaMobileConnector: () => SolanaWalletConnector;
|
|
6
|
+
export declare const createSolflareSolanaMobileConnectorDeeplink: () => SolanaWalletConnector;
|
|
6
7
|
export declare const isSolflareMobilePending: () => boolean;
|
|
7
8
|
export declare const handleSolflareMobileCallback: () => ConnectedResult | null;
|
|
8
9
|
export declare const getSolflareMobileSession: () => StoredSession | null;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { ConnectedResult, PendingResult, QRCodeResult } from './types';
|
|
1
|
+
import type { ConnectedResult, DownloadOnlyResult, PendingResult, QRCodeResult } from './types';
|
|
2
2
|
export declare const connectedResult: (address: string, options?: {
|
|
3
3
|
chainId?: number;
|
|
4
4
|
publicKey?: Uint8Array;
|
|
5
5
|
}) => ConnectedResult;
|
|
6
6
|
export declare const qrcodeResult: (uri: string, wait: () => Promise<ConnectedResult>) => QRCodeResult;
|
|
7
7
|
export declare const pendingResult: () => PendingResult;
|
|
8
|
+
export declare const downloadOnlyResult: () => DownloadOnlyResult;
|
package/dist/lib/core/types.d.ts
CHANGED
|
@@ -16,7 +16,10 @@ export interface QRCodeResult {
|
|
|
16
16
|
export interface PendingResult {
|
|
17
17
|
status: 'pending';
|
|
18
18
|
}
|
|
19
|
-
export
|
|
19
|
+
export interface DownloadOnlyResult {
|
|
20
|
+
status: 'downloadOnly';
|
|
21
|
+
}
|
|
22
|
+
export type ConnectResult = ConnectedResult | QRCodeResult | PendingResult | DownloadOnlyResult;
|
|
20
23
|
export interface Wallet {
|
|
21
24
|
connect: () => Promise<ConnectResult>;
|
|
22
25
|
disconnect: () => Promise<void>;
|