FRE-600: Fix code review blockers

- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 00:08:01 -04:00
parent 65b552bb08
commit 7c684a42cc
48450 changed files with 5679671 additions and 383 deletions

View File

@@ -0,0 +1,8 @@
import { Connection } from '@solana/web3.js';
import React, { useMemo } from 'react';
import { ConnectionContext } from './useConnection.js';
export const ConnectionProvider = ({ children, endpoint, config = { commitment: 'confirmed' }, }) => {
const connection = useMemo(() => new Connection(endpoint, config), [endpoint, config]);
return React.createElement(ConnectionContext.Provider, { value: { connection } }, children);
};
//# sourceMappingURL=ConnectionProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ConnectionProvider.js","sourceRoot":"","sources":["../../src/ConnectionProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,EAA2B,OAAO,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAQvD,MAAM,CAAC,MAAM,kBAAkB,GAAgC,CAAC,EAC5D,QAAQ,EACR,QAAQ,EACR,MAAM,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,GACvC,EAAE,EAAE;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAEvF,OAAO,oBAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAG,QAAQ,CAA8B,CAAC;AACtG,CAAC,CAAC"}

View File

@@ -0,0 +1,130 @@
import { createDefaultAddressSelector, createDefaultAuthorizationResultCache, createDefaultWalletNotFoundHandler, SolanaMobileWalletAdapter, SolanaMobileWalletAdapterWalletName, } from '@solana-mobile/wallet-adapter-mobile';
import { useStandardWalletAdapters } from '@solana/wallet-standard-wallet-adapter-react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import getEnvironment, { Environment } from './getEnvironment.js';
import getInferredClusterFromEndpoint from './getInferredClusterFromEndpoint.js';
import { useConnection } from './useConnection.js';
import { useLocalStorage } from './useLocalStorage.js';
import { WalletProviderBase } from './WalletProviderBase.js';
let _userAgent;
function getUserAgent() {
if (_userAgent === undefined) {
_userAgent = globalThis.navigator?.userAgent ?? null;
}
return _userAgent;
}
function getIsMobile(adapters) {
const userAgentString = getUserAgent();
return getEnvironment({ adapters, userAgentString }) === Environment.MOBILE_WEB;
}
function getUriForAppIdentity() {
const location = globalThis.location;
if (!location)
return;
return `${location.protocol}//${location.host}`;
}
export function WalletProvider({ children, wallets: adapters, autoConnect, localStorageKey = 'walletName', onError, }) {
const { connection } = useConnection();
const adaptersWithStandardAdapters = useStandardWalletAdapters(adapters);
const mobileWalletAdapter = useMemo(() => {
if (!getIsMobile(adaptersWithStandardAdapters)) {
return null;
}
const existingMobileWalletAdapter = adaptersWithStandardAdapters.find((adapter) => adapter.name === SolanaMobileWalletAdapterWalletName);
if (existingMobileWalletAdapter) {
return existingMobileWalletAdapter;
}
return new SolanaMobileWalletAdapter({
addressSelector: createDefaultAddressSelector(),
appIdentity: {
uri: getUriForAppIdentity(),
},
authorizationResultCache: createDefaultAuthorizationResultCache(),
cluster: getInferredClusterFromEndpoint(connection?.rpcEndpoint),
onWalletNotFound: createDefaultWalletNotFoundHandler(),
});
}, [adaptersWithStandardAdapters, connection?.rpcEndpoint]);
const adaptersWithMobileWalletAdapter = useMemo(() => {
if (mobileWalletAdapter == null || adaptersWithStandardAdapters.indexOf(mobileWalletAdapter) !== -1) {
return adaptersWithStandardAdapters;
}
return [mobileWalletAdapter, ...adaptersWithStandardAdapters];
}, [adaptersWithStandardAdapters, mobileWalletAdapter]);
const [walletName, setWalletName] = useLocalStorage(localStorageKey, null);
const adapter = useMemo(() => adaptersWithMobileWalletAdapter.find((a) => a.name === walletName) ?? null, [adaptersWithMobileWalletAdapter, walletName]);
const changeWallet = useCallback((nextWalletName) => {
if (walletName === nextWalletName)
return;
if (adapter &&
// Selecting a wallet other than the mobile wallet adapter is not
// sufficient reason to call `disconnect` on the mobile wallet adapter.
// Calling `disconnect` on the mobile wallet adapter causes the entire
// authorization store to be wiped.
adapter.name !== SolanaMobileWalletAdapterWalletName) {
adapter.disconnect();
}
setWalletName(nextWalletName);
}, [adapter, setWalletName, walletName]);
useEffect(() => {
if (!adapter)
return;
function handleDisconnect() {
if (isUnloadingRef.current)
return;
setWalletName(null);
}
adapter.on('disconnect', handleDisconnect);
return () => {
adapter.off('disconnect', handleDisconnect);
};
}, [adapter, adaptersWithStandardAdapters, setWalletName, walletName]);
const hasUserSelectedAWallet = useRef(false);
const handleAutoConnectRequest = useMemo(() => {
if (!autoConnect || !adapter)
return;
return async () => {
// If autoConnect is true or returns true, use the default autoConnect behavior.
if (autoConnect === true || (await autoConnect(adapter))) {
if (hasUserSelectedAWallet.current) {
await adapter.connect();
}
else {
await adapter.autoConnect();
}
}
};
}, [autoConnect, adapter]);
const isUnloadingRef = useRef(false);
useEffect(() => {
if (walletName === SolanaMobileWalletAdapterWalletName && getIsMobile(adaptersWithStandardAdapters)) {
isUnloadingRef.current = false;
return;
}
function handleBeforeUnload() {
isUnloadingRef.current = true;
}
/**
* Some wallets fire disconnection events when the window unloads. Since there's no way to
* distinguish between a disconnection event received because a user initiated it, and one
* that was received because they've closed the window, we have to track window unload
* events themselves. Downstream components use this information to decide whether to act
* upon or drop wallet events and errors.
*/
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, [adaptersWithStandardAdapters, walletName]);
const handleConnectError = useCallback(() => {
if (adapter) {
// If any error happens while connecting, unset the adapter.
changeWallet(null);
}
}, [adapter, changeWallet]);
const selectWallet = useCallback((walletName) => {
hasUserSelectedAWallet.current = true;
changeWallet(walletName);
}, [changeWallet]);
return (React.createElement(WalletProviderBase, { wallets: adaptersWithMobileWalletAdapter, adapter: adapter, isUnloadingRef: isUnloadingRef, onAutoConnectRequest: handleAutoConnectRequest, onConnectError: handleConnectError, onError: onError, onSelectWallet: selectWallet }, children));
}
//# sourceMappingURL=WalletProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WalletProvider.js","sourceRoot":"","sources":["../../src/WalletProvider.tsx"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,239 @@
import { WalletNotConnectedError, WalletNotReadyError, WalletReadyState, } from '@solana/wallet-adapter-base';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { WalletNotSelectedError } from './errors.js';
import { WalletContext } from './useWallet.js';
export function WalletProviderBase({ children, wallets: adapters, adapter, isUnloadingRef, onAutoConnectRequest, onConnectError, onError, onSelectWallet, }) {
const isConnectingRef = useRef(false);
const [connecting, setConnecting] = useState(false);
const isDisconnectingRef = useRef(false);
const [disconnecting, setDisconnecting] = useState(false);
const [publicKey, setPublicKey] = useState(() => adapter?.publicKey ?? null);
const [connected, setConnected] = useState(() => adapter?.connected ?? false);
/**
* Store the error handlers as refs so that a change in the
* custom error handler does not recompute other dependencies.
*/
const onErrorRef = useRef(onError);
useEffect(() => {
onErrorRef.current = onError;
return () => {
onErrorRef.current = undefined;
};
}, [onError]);
const handleErrorRef = useRef((error, adapter) => {
if (!isUnloadingRef.current) {
if (onErrorRef.current) {
onErrorRef.current(error, adapter);
}
else {
console.error(error, adapter);
if (error instanceof WalletNotReadyError && typeof window !== 'undefined' && adapter) {
window.open(adapter.url, '_blank');
}
}
}
return error;
});
// Wrap adapters to conform to the `Wallet` interface
const [wallets, setWallets] = useState(() => adapters
.map((adapter) => ({
adapter,
readyState: adapter.readyState,
}))
.filter(({ readyState }) => readyState !== WalletReadyState.Unsupported));
// When the adapters change, start to listen for changes to their `readyState`
useEffect(() => {
// When the adapters change, wrap them to conform to the `Wallet` interface
setWallets((wallets) => adapters
.map((adapter, index) => {
const wallet = wallets[index];
// If the wallet hasn't changed, return the same instance
return wallet && wallet.adapter === adapter && wallet.readyState === adapter.readyState
? wallet
: {
adapter: adapter,
readyState: adapter.readyState,
};
})
.filter(({ readyState }) => readyState !== WalletReadyState.Unsupported));
function handleReadyStateChange(readyState) {
setWallets((prevWallets) => {
const index = prevWallets.findIndex(({ adapter }) => adapter === this);
if (index === -1)
return prevWallets;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { adapter } = prevWallets[index];
return [
...prevWallets.slice(0, index),
{ adapter, readyState },
...prevWallets.slice(index + 1),
].filter(({ readyState }) => readyState !== WalletReadyState.Unsupported);
});
}
adapters.forEach((adapter) => adapter.on('readyStateChange', handleReadyStateChange, adapter));
return () => {
adapters.forEach((adapter) => adapter.off('readyStateChange', handleReadyStateChange, adapter));
};
}, [adapter, adapters]);
const wallet = useMemo(() => wallets.find((wallet) => wallet.adapter === adapter) ?? null, [adapter, wallets]);
// Setup and teardown event listeners when the adapter changes
useEffect(() => {
if (!adapter)
return;
const handleConnect = (publicKey) => {
setPublicKey(publicKey);
isConnectingRef.current = false;
setConnecting(false);
setConnected(true);
isDisconnectingRef.current = false;
setDisconnecting(false);
};
const handleDisconnect = () => {
if (isUnloadingRef.current)
return;
setPublicKey(null);
isConnectingRef.current = false;
setConnecting(false);
setConnected(false);
isDisconnectingRef.current = false;
setDisconnecting(false);
};
const handleError = (error) => {
handleErrorRef.current(error, adapter);
};
adapter.on('connect', handleConnect);
adapter.on('disconnect', handleDisconnect);
adapter.on('error', handleError);
return () => {
adapter.off('connect', handleConnect);
adapter.off('disconnect', handleDisconnect);
adapter.off('error', handleError);
handleDisconnect();
};
}, [adapter, isUnloadingRef]);
// When the adapter changes, clear the `autoConnect` tracking flag
const didAttemptAutoConnectRef = useRef(false);
useEffect(() => {
return () => {
didAttemptAutoConnectRef.current = false;
};
}, [adapter]);
// If auto-connect is enabled, request to connect when the adapter changes and is ready
useEffect(() => {
if (didAttemptAutoConnectRef.current ||
isConnectingRef.current ||
connected ||
!onAutoConnectRequest ||
!(wallet?.readyState === WalletReadyState.Installed || wallet?.readyState === WalletReadyState.Loadable))
return;
isConnectingRef.current = true;
setConnecting(true);
didAttemptAutoConnectRef.current = true;
(async function () {
try {
await onAutoConnectRequest();
}
catch {
onConnectError();
// Drop the error. It will be caught by `handleError` anyway.
}
finally {
setConnecting(false);
isConnectingRef.current = false;
}
})();
}, [connected, onAutoConnectRequest, onConnectError, wallet]);
// Send a transaction using the provided connection
const sendTransaction = useCallback(async (transaction, connection, options) => {
if (!adapter)
throw handleErrorRef.current(new WalletNotSelectedError());
if (!connected)
throw handleErrorRef.current(new WalletNotConnectedError(), adapter);
return await adapter.sendTransaction(transaction, connection, options);
}, [adapter, connected]);
// Sign a transaction if the wallet supports it
const signTransaction = useMemo(() => adapter && 'signTransaction' in adapter
? async (transaction) => {
if (!connected)
throw handleErrorRef.current(new WalletNotConnectedError(), adapter);
return await adapter.signTransaction(transaction);
}
: undefined, [adapter, connected]);
// Sign multiple transactions if the wallet supports it
const signAllTransactions = useMemo(() => adapter && 'signAllTransactions' in adapter
? async (transactions) => {
if (!connected)
throw handleErrorRef.current(new WalletNotConnectedError(), adapter);
return await adapter.signAllTransactions(transactions);
}
: undefined, [adapter, connected]);
// Sign an arbitrary message if the wallet supports it
const signMessage = useMemo(() => adapter && 'signMessage' in adapter
? async (message) => {
if (!connected)
throw handleErrorRef.current(new WalletNotConnectedError(), adapter);
return await adapter.signMessage(message);
}
: undefined, [adapter, connected]);
// Sign in if the wallet supports it
const signIn = useMemo(() => adapter && 'signIn' in adapter
? async (input) => {
return await adapter.signIn(input);
}
: undefined, [adapter]);
const handleConnect = useCallback(async () => {
if (isConnectingRef.current || isDisconnectingRef.current || wallet?.adapter.connected)
return;
if (!wallet)
throw handleErrorRef.current(new WalletNotSelectedError());
const { adapter, readyState } = wallet;
if (!(readyState === WalletReadyState.Installed || readyState === WalletReadyState.Loadable))
throw handleErrorRef.current(new WalletNotReadyError(), adapter);
isConnectingRef.current = true;
setConnecting(true);
try {
await adapter.connect();
}
catch (e) {
onConnectError();
throw e;
}
finally {
setConnecting(false);
isConnectingRef.current = false;
}
}, [onConnectError, wallet]);
const handleDisconnect = useCallback(async () => {
if (isDisconnectingRef.current)
return;
if (!adapter)
return;
isDisconnectingRef.current = true;
setDisconnecting(true);
try {
await adapter.disconnect();
}
finally {
setDisconnecting(false);
isDisconnectingRef.current = false;
}
}, [adapter]);
return (React.createElement(WalletContext.Provider, { value: {
autoConnect: !!onAutoConnectRequest,
wallets,
wallet,
publicKey,
connected,
connecting,
disconnecting,
select: onSelectWallet,
connect: handleConnect,
disconnect: handleDisconnect,
sendTransaction,
signTransaction,
signAllTransactions,
signMessage,
signIn,
} }, children));
}
//# sourceMappingURL=WalletProviderBase.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
export default function defineProperty(obj, prop, val) {
Object.defineProperty(obj, prop, val);
}
//# sourceMappingURL=defineProperty.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defineProperty.js","sourceRoot":"","sources":["../../src/defineProperty.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,OAAO,UAAU,cAAc,CAClC,GAAQ,EACR,IAAS,EACT,GAAU;IAEV,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC"}

View File

@@ -0,0 +1,8 @@
import { WalletError } from '@solana/wallet-adapter-base';
export class WalletNotSelectedError extends WalletError {
constructor() {
super(...arguments);
this.name = 'WalletNotSelectedError';
}
}
//# sourceMappingURL=errors.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,OAAO,sBAAuB,SAAQ,WAAW;IAAvD;;QACI,SAAI,GAAG,wBAAwB,CAAC;IACpC,CAAC;CAAA"}

View File

@@ -0,0 +1,35 @@
import { SolanaMobileWalletAdapterWalletName } from '@solana-mobile/wallet-adapter-mobile';
import { WalletReadyState } from '@solana/wallet-adapter-base';
export var Environment;
(function (Environment) {
Environment[Environment["DESKTOP_WEB"] = 0] = "DESKTOP_WEB";
Environment[Environment["MOBILE_WEB"] = 1] = "MOBILE_WEB";
})(Environment || (Environment = {}));
function isWebView(userAgentString) {
return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
}
export default function getEnvironment({ adapters, userAgentString }) {
if (adapters.some((adapter) => adapter.name !== SolanaMobileWalletAdapterWalletName &&
adapter.readyState === WalletReadyState.Installed)) {
/**
* There are only two ways a browser extension adapter should be able to reach `Installed` status:
*
* 1. Its browser extension is installed.
* 2. The app is running on a mobile wallet's in-app browser.
*
* In either case, we consider the environment to be desktop-like.
*/
return Environment.DESKTOP_WEB;
}
if (userAgentString &&
// Step 1: Check whether we're on a platform that supports MWA at all.
/android/i.test(userAgentString) &&
// Step 2: Determine that we are *not* running in a WebView.
!isWebView(userAgentString)) {
return Environment.MOBILE_WEB;
}
else {
return Environment.DESKTOP_WEB;
}
}
//# sourceMappingURL=getEnvironment.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getEnvironment.js","sourceRoot":"","sources":["../../src/getEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAgB,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACnB,2DAAW,CAAA;IACX,yDAAU,CAAA;AACd,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAOD,SAAS,SAAS,CAAC,eAAuB;IACtC,OAAO,yGAAyG,CAAC,IAAI,CACjH,eAAe,CAClB,CAAC;AACN,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAU;IACxE,IACI,QAAQ,CAAC,IAAI,CACT,CAAC,OAAO,EAAE,EAAE,CACR,OAAO,CAAC,IAAI,KAAK,mCAAmC;QACpD,OAAO,CAAC,UAAU,KAAK,gBAAgB,CAAC,SAAS,CACxD,EACH,CAAC;QACC;;;;;;;WAOG;QACH,OAAO,WAAW,CAAC,WAAW,CAAC;IACnC,CAAC;IACD,IACI,eAAe;QACf,sEAAsE;QACtE,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC;QAChC,4DAA4D;QAC5D,CAAC,SAAS,CAAC,eAAe,CAAC,EAC7B,CAAC;QACC,OAAO,WAAW,CAAC,UAAU,CAAC;IAClC,CAAC;SAAM,CAAC;QACJ,OAAO,WAAW,CAAC,WAAW,CAAC;IACnC,CAAC;AACL,CAAC"}

View File

@@ -0,0 +1,15 @@
export default function getInferredClusterFromEndpoint(endpoint) {
if (!endpoint) {
return 'mainnet-beta';
}
if (/devnet/i.test(endpoint)) {
return 'devnet';
}
else if (/testnet/i.test(endpoint)) {
return 'testnet';
}
else {
return 'mainnet-beta';
}
}
//# sourceMappingURL=getInferredClusterFromEndpoint.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getInferredClusterFromEndpoint.js","sourceRoot":"","sources":["../../src/getInferredClusterFromEndpoint.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,8BAA8B,CAAC,QAAiB;IACpE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,cAAc,CAAC;IAC1B,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IACpB,CAAC;SAAM,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACrB,CAAC;SAAM,CAAC;QACJ,OAAO,cAAc,CAAC;IAC1B,CAAC;AACL,CAAC"}

View File

@@ -0,0 +1,8 @@
export * from './ConnectionProvider.js';
export * from './errors.js';
export * from './useAnchorWallet.js';
export * from './useConnection.js';
export * from './useLocalStorage.js';
export * from './useWallet.js';
export * from './WalletProvider.js';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC"}

View File

@@ -0,0 +1 @@
{"root":["../../src/ConnectionProvider.tsx","../../src/WalletProvider.tsx","../../src/WalletProviderBase.tsx","../../src/defineProperty.ts","../../src/errors.ts","../../src/getEnvironment.ts","../../src/getInferredClusterFromEndpoint.ts","../../src/index.ts","../../src/useAnchorWallet.ts","../../src/useConnection.ts","../../src/useLocalStorage.native.ts","../../src/useLocalStorage.ts","../../src/useWallet.ts"],"version":"5.8.3"}

View File

@@ -0,0 +1,9 @@
import { useMemo } from 'react';
import { useWallet } from './useWallet.js';
export function useAnchorWallet() {
const { publicKey, signTransaction, signAllTransactions } = useWallet();
return useMemo(() => publicKey && signTransaction && signAllTransactions
? { publicKey, signTransaction, signAllTransactions }
: undefined, [publicKey, signTransaction, signAllTransactions]);
}
//# sourceMappingURL=useAnchorWallet.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useAnchorWallet.js","sourceRoot":"","sources":["../../src/useAnchorWallet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQ3C,MAAM,UAAU,eAAe;IAC3B,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,GAAG,SAAS,EAAE,CAAC;IACxE,OAAO,OAAO,CACV,GAAG,EAAE,CACD,SAAS,IAAI,eAAe,IAAI,mBAAmB;QAC/C,CAAC,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE;QACrD,CAAC,CAAC,SAAS,EACnB,CAAC,SAAS,EAAE,eAAe,EAAE,mBAAmB,CAAC,CACpD,CAAC;AACN,CAAC"}

View File

@@ -0,0 +1,6 @@
import { createContext, useContext } from 'react';
export const ConnectionContext = createContext({});
export function useConnection() {
return useContext(ConnectionContext);
}
//# sourceMappingURL=useConnection.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useConnection.js","sourceRoot":"","sources":["../../src/useConnection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAMlD,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAyB,EAA4B,CAAC,CAAC;AAErG,MAAM,UAAU,aAAa;IACzB,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACzC,CAAC"}

View File

@@ -0,0 +1,39 @@
import { useEffect, useRef, useState } from 'react';
export function useLocalStorage(key, defaultState) {
const state = useState(() => {
try {
const value = localStorage.getItem(key);
if (value)
return JSON.parse(value);
}
catch (error) {
if (typeof window !== 'undefined') {
console.error(error);
}
}
return defaultState;
});
const value = state[0];
const isFirstRenderRef = useRef(true);
useEffect(() => {
if (isFirstRenderRef.current) {
isFirstRenderRef.current = false;
return;
}
try {
if (value === null) {
localStorage.removeItem(key);
}
else {
localStorage.setItem(key, JSON.stringify(value));
}
}
catch (error) {
if (typeof window !== 'undefined') {
console.error(error);
}
}
}, [value, key]);
return state;
}
//# sourceMappingURL=useLocalStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useLocalStorage.js","sourceRoot":"","sources":["../../src/useLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAExF,MAAM,UAAU,eAAe,CAAI,GAAW,EAAE,YAAe;IAC3D,MAAM,KAAK,GAAG,QAAQ,CAAI,GAAG,EAAE;QAC3B,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;QAED,OAAO,YAAY,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvB,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC3B,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;YACjC,OAAO;QACX,CAAC;QACD,IAAI,CAAC;YACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACjB,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACJ,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACrD,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjB,OAAO,KAAK,CAAC;AACjB,CAAC"}

View File

@@ -0,0 +1,9 @@
import { useState } from 'react';
export const useLocalStorage = function useLocalStorage(_key, defaultState) {
/**
* Until such time as we have a strategy for implementing wallet
* memorization on React Native, simply punt and return a no-op.
*/
return useState(defaultState);
};
//# sourceMappingURL=useLocalStorage.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useLocalStorage.native.js","sourceRoot":"","sources":["../../src/useLocalStorage.native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,MAAM,CAAC,MAAM,eAAe,GAA+B,SAAS,eAAe,CAC/E,IAAY,EACZ,YAAe;IAEf;;;OAGG;IACH,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC,CAAC"}

View File

@@ -0,0 +1,61 @@
import { createContext, useContext } from 'react';
const EMPTY_ARRAY = [];
const DEFAULT_CONTEXT = {
autoConnect: false,
connecting: false,
connected: false,
disconnecting: false,
select() {
logMissingProviderError('call', 'select');
},
connect() {
return Promise.reject(logMissingProviderError('call', 'connect'));
},
disconnect() {
return Promise.reject(logMissingProviderError('call', 'disconnect'));
},
sendTransaction() {
return Promise.reject(logMissingProviderError('call', 'sendTransaction'));
},
signTransaction() {
return Promise.reject(logMissingProviderError('call', 'signTransaction'));
},
signAllTransactions() {
return Promise.reject(logMissingProviderError('call', 'signAllTransactions'));
},
signMessage() {
return Promise.reject(logMissingProviderError('call', 'signMessage'));
},
signIn() {
return Promise.reject(logMissingProviderError('call', 'signIn'));
},
};
Object.defineProperty(DEFAULT_CONTEXT, 'wallets', {
get() {
logMissingProviderError('read', 'wallets');
return EMPTY_ARRAY;
},
});
Object.defineProperty(DEFAULT_CONTEXT, 'wallet', {
get() {
logMissingProviderError('read', 'wallet');
return null;
},
});
Object.defineProperty(DEFAULT_CONTEXT, 'publicKey', {
get() {
logMissingProviderError('read', 'publicKey');
return null;
},
});
function logMissingProviderError(action, property) {
const error = new Error(`You have tried to ${action} "${property}" on a WalletContext without providing one. ` +
'Make sure to render a WalletProvider as an ancestor of the component that uses WalletContext.');
console.error(error);
return error;
}
export const WalletContext = createContext(DEFAULT_CONTEXT);
export function useWallet() {
return useContext(WalletContext);
}
//# sourceMappingURL=useWallet.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useWallet.js","sourceRoot":"","sources":["../../src/useWallet.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA2BlD,MAAM,WAAW,GAAyB,EAAE,CAAC;AAE7C,MAAM,eAAe,GAAgC;IACjD,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,aAAa,EAAE,KAAK;IACpB,MAAM;QACF,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,UAAU;QACN,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,eAAe;QACX,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,eAAe;QACX,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,mBAAmB;QACf,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAClF,CAAC;IACD,WAAW;QACP,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM;QACF,OAAO,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrE,CAAC;CACJ,CAAC;AACF,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,SAAS,EAAE;IAC9C,GAAG;QACC,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3C,OAAO,WAAW,CAAC;IACvB,CAAC;CACJ,CAAC,CAAC;AACH,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,QAAQ,EAAE;IAC7C,GAAG;QACC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ,CAAC,CAAC;AACH,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,WAAW,EAAE;IAChD,GAAG;QACC,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ,CAAC,CAAC;AAEH,SAAS,uBAAuB,CAAC,MAAc,EAAE,QAAgB;IAC7D,MAAM,KAAK,GAAG,IAAI,KAAK,CACnB,qBAAqB,MAAM,KAAK,QAAQ,8CAA8C;QAClF,+FAA+F,CACtG,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB,eAAqC,CAAC,CAAC;AAEtG,MAAM,UAAU,SAAS;IACrB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACrC,CAAC"}