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

193
node_modules/@solana/wallet-adapter-base/src/adapter.ts generated vendored Normal file
View File

@@ -0,0 +1,193 @@
import type { Connection, PublicKey, SendOptions, Signer, Transaction, TransactionSignature } from '@solana/web3.js';
import EventEmitter from 'eventemitter3';
import { type WalletError, WalletNotConnectedError } from './errors.js';
import type { SupportedTransactionVersions, TransactionOrVersionedTransaction } from './transaction.js';
export { EventEmitter };
export interface WalletAdapterEvents {
connect(publicKey: PublicKey): void;
disconnect(): void;
error(error: WalletError): void;
readyStateChange(readyState: WalletReadyState): void;
}
export interface SendTransactionOptions extends SendOptions {
signers?: Signer[];
}
// WalletName is a nominal type that wallet adapters should use, e.g. `'MyCryptoWallet' as WalletName<'MyCryptoWallet'>`
// https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d
export type WalletName<T extends string = string> = T & { __brand__: 'WalletName' };
export interface WalletAdapterProps<Name extends string = string> {
name: WalletName<Name>;
url: string;
icon: string;
readyState: WalletReadyState;
publicKey: PublicKey | null;
connecting: boolean;
connected: boolean;
supportedTransactionVersions?: SupportedTransactionVersions;
autoConnect(): Promise<void>;
connect(): Promise<void>;
disconnect(): Promise<void>;
sendTransaction(
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options?: SendTransactionOptions
): Promise<TransactionSignature>;
}
export type WalletAdapter<Name extends string = string> = WalletAdapterProps<Name> & EventEmitter<WalletAdapterEvents>;
/**
* A wallet's readiness describes a series of states that the wallet can be in,
* depending on what kind of wallet it is. An installable wallet (eg. a browser
* extension like Phantom) might be `Installed` if we've found the Phantom API
* in the global scope, or `NotDetected` otherwise. A loadable, zero-install
* runtime (eg. Torus Wallet) might simply signal that it's `Loadable`. Use this
* metadata to personalize the wallet list for each user (eg. to show their
* installed wallets first).
*/
export enum WalletReadyState {
/**
* User-installable wallets can typically be detected by scanning for an API
* that they've injected into the global context. If such an API is present,
* we consider the wallet to have been installed.
*/
Installed = 'Installed',
NotDetected = 'NotDetected',
/**
* Loadable wallets are always available to you. Since you can load them at
* any time, it's meaningless to say that they have been detected.
*/
Loadable = 'Loadable',
/**
* If a wallet is not supported on a given platform (eg. server-rendering, or
* mobile) then it will stay in the `Unsupported` state.
*/
Unsupported = 'Unsupported',
}
export abstract class BaseWalletAdapter<Name extends string = string>
extends EventEmitter<WalletAdapterEvents>
implements WalletAdapter<Name>
{
abstract name: WalletName<Name>;
abstract url: string;
abstract icon: string;
abstract readyState: WalletReadyState;
abstract publicKey: PublicKey | null;
abstract connecting: boolean;
abstract supportedTransactionVersions?: SupportedTransactionVersions;
get connected() {
return !!this.publicKey;
}
async autoConnect() {
await this.connect();
}
abstract connect(): Promise<void>;
abstract disconnect(): Promise<void>;
abstract sendTransaction(
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options?: SendTransactionOptions
): Promise<TransactionSignature>;
protected async prepareTransaction(
transaction: Transaction,
connection: Connection,
options: SendOptions = {}
): Promise<Transaction> {
const publicKey = this.publicKey;
if (!publicKey) throw new WalletNotConnectedError();
transaction.feePayer = transaction.feePayer || publicKey;
transaction.recentBlockhash =
transaction.recentBlockhash ||
(
await connection.getLatestBlockhash({
commitment: options.preflightCommitment,
minContextSlot: options.minContextSlot,
})
).blockhash;
return transaction;
}
}
export function scopePollingDetectionStrategy(detect: () => boolean): void {
// Early return when server-side rendering
if (typeof window === 'undefined' || typeof document === 'undefined') return;
const disposers: (() => void)[] = [];
function detectAndDispose() {
const detected = detect();
if (detected) {
for (const dispose of disposers) {
dispose();
}
}
}
// Strategy #1: Try detecting every second.
const interval =
// TODO: #334 Replace with idle callback strategy.
setInterval(detectAndDispose, 1000);
disposers.push(() => clearInterval(interval));
// Strategy #2: Detect as soon as the DOM becomes 'ready'/'interactive'.
if (
// Implies that `DOMContentLoaded` has not yet fired.
document.readyState === 'loading'
) {
document.addEventListener('DOMContentLoaded', detectAndDispose, { once: true });
disposers.push(() => document.removeEventListener('DOMContentLoaded', detectAndDispose));
}
// Strategy #3: Detect after the `window` has fully loaded.
if (
// If the `complete` state has been reached, we're too late.
document.readyState !== 'complete'
) {
window.addEventListener('load', detectAndDispose, { once: true });
disposers.push(() => window.removeEventListener('load', detectAndDispose));
}
// Strategy #4: Detect synchronously, now.
detectAndDispose();
}
/**
* Users on iOS can be redirected into a wallet's in-app browser automatically,
* if that wallet has a universal link configured to do so
* But should not be redirected from within a webview, eg. if they're already
* inside a wallet's browser
* This function can be used to identify users who are on iOS and can be redirected
*
* @returns true if the user can be redirected
*/
export function isIosAndRedirectable() {
// SSR: return false
if (!navigator) return false;
const userAgent = navigator.userAgent.toLowerCase();
// if on iOS the user agent will contain either iPhone or iPad
// caveat: if requesting desktop site then this won't work
const isIos = userAgent.includes('iphone') || userAgent.includes('ipad');
// if in a webview then it will not include Safari
// note that other iOS browsers also include Safari
// so we will redirect only if Safari is also included
const isSafari = userAgent.includes('safari');
return isIos && isSafari;
}

77
node_modules/@solana/wallet-adapter-base/src/errors.ts generated vendored Normal file
View File

@@ -0,0 +1,77 @@
export class WalletError extends Error {
error: any;
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
constructor(message?: string, error?: any) {
super(message);
this.error = error;
}
}
export class WalletNotReadyError extends WalletError {
name = 'WalletNotReadyError';
}
export class WalletLoadError extends WalletError {
name = 'WalletLoadError';
}
export class WalletConfigError extends WalletError {
name = 'WalletConfigError';
}
export class WalletConnectionError extends WalletError {
name = 'WalletConnectionError';
}
export class WalletDisconnectedError extends WalletError {
name = 'WalletDisconnectedError';
}
export class WalletDisconnectionError extends WalletError {
name = 'WalletDisconnectionError';
}
export class WalletAccountError extends WalletError {
name = 'WalletAccountError';
}
export class WalletPublicKeyError extends WalletError {
name = 'WalletPublicKeyError';
}
export class WalletKeypairError extends WalletError {
name = 'WalletKeypairError';
}
export class WalletNotConnectedError extends WalletError {
name = 'WalletNotConnectedError';
}
export class WalletSendTransactionError extends WalletError {
name = 'WalletSendTransactionError';
}
export class WalletSignTransactionError extends WalletError {
name = 'WalletSignTransactionError';
}
export class WalletSignMessageError extends WalletError {
name = 'WalletSignMessageError';
}
export class WalletSignInError extends WalletError {
name = 'WalletSignInError';
}
export class WalletTimeoutError extends WalletError {
name = 'WalletTimeoutError';
}
export class WalletWindowBlockedError extends WalletError {
name = 'WalletWindowBlockedError';
}
export class WalletWindowClosedError extends WalletError {
name = 'WalletWindowClosedError';
}

View File

@@ -0,0 +1,6 @@
export * from './adapter.js';
export * from './errors.js';
export * from './signer.js';
export * from './standard.js';
export * from './transaction.js';
export * from './types.js';

144
node_modules/@solana/wallet-adapter-base/src/signer.ts generated vendored Normal file
View File

@@ -0,0 +1,144 @@
import type { SolanaSignInInput, SolanaSignInOutput } from '@solana/wallet-standard-features';
import type { Connection, TransactionSignature } from '@solana/web3.js';
import {
BaseWalletAdapter,
type SendTransactionOptions,
type WalletAdapter,
type WalletAdapterProps,
} from './adapter.js';
import { WalletSendTransactionError, WalletSignTransactionError } from './errors.js';
import { isVersionedTransaction, type TransactionOrVersionedTransaction } from './transaction.js';
export interface SignerWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
signTransaction<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transaction: T
): Promise<T>;
signAllTransactions<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transactions: T[]
): Promise<T[]>;
}
export type SignerWalletAdapter<Name extends string = string> = WalletAdapter<Name> & SignerWalletAdapterProps<Name>;
export abstract class BaseSignerWalletAdapter<Name extends string = string>
extends BaseWalletAdapter<Name>
implements SignerWalletAdapter<Name>
{
async sendTransaction(
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options: SendTransactionOptions = {}
): Promise<TransactionSignature> {
let emit = true;
try {
if (isVersionedTransaction(transaction)) {
if (!this.supportedTransactionVersions)
throw new WalletSendTransactionError(
`Sending versioned transactions isn't supported by this wallet`
);
if (!this.supportedTransactionVersions.has(transaction.version))
throw new WalletSendTransactionError(
`Sending transaction version ${transaction.version} isn't supported by this wallet`
);
try {
transaction = await this.signTransaction(transaction);
const rawTransaction = transaction.serialize();
return await connection.sendRawTransaction(rawTransaction, options);
} catch (error: any) {
// If the error was thrown by `signTransaction`, rethrow it and don't emit a duplicate event
if (error instanceof WalletSignTransactionError) {
emit = false;
throw error;
}
throw new WalletSendTransactionError(error?.message, error);
}
} else {
try {
const { signers, ...sendOptions } = options;
transaction = await this.prepareTransaction(transaction, connection, sendOptions);
signers?.length && transaction.partialSign(...signers);
transaction = await this.signTransaction(transaction);
const rawTransaction = transaction.serialize();
return await connection.sendRawTransaction(rawTransaction, sendOptions);
} catch (error: any) {
// If the error was thrown by `signTransaction`, rethrow it and don't emit a duplicate event
if (error instanceof WalletSignTransactionError) {
emit = false;
throw error;
}
throw new WalletSendTransactionError(error?.message, error);
}
}
} catch (error: any) {
if (emit) {
this.emit('error', error);
}
throw error;
}
}
abstract signTransaction<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transaction: T
): Promise<T>;
async signAllTransactions<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transactions: T[]
): Promise<T[]> {
for (const transaction of transactions) {
if (isVersionedTransaction(transaction)) {
if (!this.supportedTransactionVersions)
throw new WalletSignTransactionError(
`Signing versioned transactions isn't supported by this wallet`
);
if (!this.supportedTransactionVersions.has(transaction.version))
throw new WalletSignTransactionError(
`Signing transaction version ${transaction.version} isn't supported by this wallet`
);
}
}
const signedTransactions: T[] = [];
for (const transaction of transactions) {
signedTransactions.push(await this.signTransaction(transaction));
}
return signedTransactions;
}
}
export interface MessageSignerWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
signMessage(message: Uint8Array): Promise<Uint8Array>;
}
export type MessageSignerWalletAdapter<Name extends string = string> = WalletAdapter<Name> &
MessageSignerWalletAdapterProps<Name>;
export abstract class BaseMessageSignerWalletAdapter<Name extends string = string>
extends BaseSignerWalletAdapter<Name>
implements MessageSignerWalletAdapter<Name>
{
abstract signMessage(message: Uint8Array): Promise<Uint8Array>;
}
export interface SignInMessageSignerWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
signIn(input?: SolanaSignInInput): Promise<SolanaSignInOutput>;
}
export type SignInMessageSignerWalletAdapter<Name extends string = string> = WalletAdapter<Name> &
SignInMessageSignerWalletAdapterProps<Name>;
export abstract class BaseSignInMessageSignerWalletAdapter<Name extends string = string>
extends BaseMessageSignerWalletAdapter<Name>
implements SignInMessageSignerWalletAdapter<Name>
{
abstract signIn(input?: SolanaSignInInput): Promise<SolanaSignInOutput>;
}

View File

@@ -0,0 +1,42 @@
import {
SolanaSignAndSendTransaction,
type SolanaSignAndSendTransactionFeature,
type SolanaSignInFeature,
type SolanaSignMessageFeature,
SolanaSignTransaction,
type SolanaSignTransactionFeature,
} from '@solana/wallet-standard-features';
import type { Wallet as StandardWallet, WalletWithFeatures as StandardWalletWithFeatures } from '@wallet-standard/base';
import {
StandardConnect,
type StandardConnectFeature,
type StandardDisconnectFeature,
StandardEvents,
type StandardEventsFeature,
} from '@wallet-standard/features';
import type { WalletAdapter, WalletAdapterProps } from './adapter.js';
export type WalletAdapterCompatibleStandardWallet = StandardWalletWithFeatures<
StandardConnectFeature &
StandardEventsFeature &
(SolanaSignAndSendTransactionFeature | SolanaSignTransactionFeature) &
(StandardDisconnectFeature | SolanaSignMessageFeature | SolanaSignInFeature | object)
>;
export interface StandardWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
wallet: WalletAdapterCompatibleStandardWallet;
standard: true;
}
export type StandardWalletAdapter<Name extends string = string> = WalletAdapter<Name> &
StandardWalletAdapterProps<Name>;
export function isWalletAdapterCompatibleStandardWallet(
wallet: StandardWallet
): wallet is WalletAdapterCompatibleStandardWallet {
return (
StandardConnect in wallet.features &&
StandardEvents in wallet.features &&
(SolanaSignAndSendTransaction in wallet.features || SolanaSignTransaction in wallet.features)
);
}

View File

@@ -0,0 +1,13 @@
import type { Transaction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
export type SupportedTransactionVersions = ReadonlySet<TransactionVersion> | null | undefined;
export type TransactionOrVersionedTransaction<S extends SupportedTransactionVersions> = S extends null | undefined
? Transaction
: Transaction | VersionedTransaction;
export function isVersionedTransaction(
transaction: Transaction | VersionedTransaction
): transaction is VersionedTransaction {
return 'version' in transaction;
}

16
node_modules/@solana/wallet-adapter-base/src/types.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
import type { WalletAdapter } from './adapter.js';
import type { MessageSignerWalletAdapter, SignerWalletAdapter, SignInMessageSignerWalletAdapter } from './signer.js';
import type { StandardWalletAdapter } from './standard.js';
export type Adapter =
| WalletAdapter
| SignerWalletAdapter
| MessageSignerWalletAdapter
| SignInMessageSignerWalletAdapter
| StandardWalletAdapter;
export enum WalletAdapterNetwork {
Mainnet = 'mainnet-beta',
Testnet = 'testnet',
Devnet = 'devnet',
}