mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
255 lines
6.9 KiB
TypeScript
255 lines
6.9 KiB
TypeScript
'use client';
|
|
|
|
import { PubKey } from '@session/ui/components/PubKey';
|
|
import { ArrowDownIcon } from '@session/ui/icons/ArrowDownIcon';
|
|
import { cn } from '@session/ui/lib/utils';
|
|
import { Avatar, AvatarFallback, AvatarImage } from '@session/ui/ui/avatar';
|
|
import { Button, type ButtonProps } from '@session/ui/ui/button';
|
|
import { Input } from '@session/ui/ui/input';
|
|
import {
|
|
Sheet,
|
|
SheetContent,
|
|
SheetDescription,
|
|
SheetHeader,
|
|
SheetOverlay,
|
|
SheetTitle,
|
|
} from '@session/ui/ui/sheet';
|
|
import { Switch } from '@session/ui/ui/switch';
|
|
import { Tooltip } from '@session/ui/ui/tooltip';
|
|
import {
|
|
QueryProvider,
|
|
WalletProvider,
|
|
type WalletProviderProps,
|
|
createWeb3WalletConfig,
|
|
} from '@web3sheet/core';
|
|
import type { DynamicTokenRowProps } from '@web3sheet/core/hooks/useWallet';
|
|
import type { Web3WalletComponentLibrary } from '@web3sheet/ui/lib/library';
|
|
import { type ReactNode, forwardRef, useState } from 'react';
|
|
import { http } from 'viem';
|
|
import { arbitrum, arbitrumSepolia, mainnet, sepolia } from 'viem/chains';
|
|
|
|
const TabFullWidthButton = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
({ className, children, ...props }, ref) => (
|
|
<Button {...props} className={cn('w-full', className)} variant="outline" ref={ref}>
|
|
{children}
|
|
</Button>
|
|
)
|
|
);
|
|
|
|
const ButtonWithIconSrc = forwardRef<HTMLButtonElement, ButtonProps & { src: string }>(
|
|
({ src, children, className, ...props }, ref) => (
|
|
<TabFullWidthButton {...props} ref={ref} className={cn('relative', className)}>
|
|
<div className="absolute h-6 w-6" style={{ left: '6px' }}>
|
|
<Avatar className="h-6 w-6">
|
|
<AvatarImage src={src} />
|
|
<AvatarFallback className="bg-black" />
|
|
</Avatar>
|
|
</div>
|
|
{children}
|
|
</TabFullWidthButton>
|
|
)
|
|
);
|
|
|
|
const ButtonWithIconReactNode = forwardRef<HTMLButtonElement, ButtonProps & { icon: ReactNode }>(
|
|
({ icon, children, className, ...props }, ref) => (
|
|
<TabFullWidthButton {...props} ref={ref} className={cn('relative', className)}>
|
|
<div className="absolute h-6 w-6" style={{ left: '6px' }}>
|
|
{icon}
|
|
</div>
|
|
{children}
|
|
</TabFullWidthButton>
|
|
)
|
|
);
|
|
|
|
const BackButton = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => (
|
|
<Button {...props} ref={ref} variant="ghost" size="icon">
|
|
<ArrowDownIcon className="mt-0.5 h-3 w-3 rotate-90 fill-session-text" />
|
|
</Button>
|
|
));
|
|
|
|
const componentLibrary: Web3WalletComponentLibrary = {
|
|
// @ts-expect-error -- TODO: deal with data test ids
|
|
TabFullWidthButton,
|
|
// @ts-expect-error -- TODO: deal with data test ids
|
|
ButtonWithIconReactNode,
|
|
// @ts-expect-error -- TODO: deal with data test ids
|
|
ButtonWithIconSrc,
|
|
// @ts-expect-error -- TODO: deal with data test ids
|
|
BackButton,
|
|
Switch,
|
|
Sheet,
|
|
SheetContent,
|
|
SheetDescription,
|
|
SheetHeader,
|
|
SheetTitle,
|
|
SheetOverlay,
|
|
Input,
|
|
PubKey,
|
|
Tooltip,
|
|
};
|
|
|
|
function TokenActionButton({ href, children }: { href: string; children: ReactNode }) {
|
|
return (
|
|
<a href={href} target="_blank" rel="noreferrer">
|
|
<Button
|
|
size="xs"
|
|
className="h-4 px-1.5"
|
|
variant="outline"
|
|
rounded="md"
|
|
data-testid="button:token-action"
|
|
>
|
|
{children}
|
|
</Button>
|
|
</a>
|
|
);
|
|
}
|
|
|
|
const tokenOptions = {
|
|
name: 'Session Token',
|
|
iconSrc: 'https://stake.getsession.org/images/token_logo.svg',
|
|
tokenAddress: '0x10Ea9E5303670331Bdddfa66A4cEA47dae4fcF3b',
|
|
showAddTokenButton: true,
|
|
} as const;
|
|
|
|
const tokenDetailsArbitrum: DynamicTokenRowProps = {
|
|
...tokenOptions,
|
|
network: {
|
|
id: arbitrum.id,
|
|
name: 'Arbitrum One',
|
|
iconSrc: '/images/arbitrum.svg',
|
|
},
|
|
children: <TokenActionButton href="/stake">Stake</TokenActionButton>,
|
|
};
|
|
|
|
const tokenDetailsEthereum: DynamicTokenRowProps = {
|
|
...tokenOptions,
|
|
network: {
|
|
id: mainnet.id,
|
|
name: 'Ethereum',
|
|
iconSrc: '/images/eth.svg',
|
|
className: 'bg-session-white',
|
|
},
|
|
children: <TokenActionButton href="/bridge/arbitrum">Bridge</TokenActionButton>,
|
|
};
|
|
|
|
const tokenDetailsArbitrumSepolia: DynamicTokenRowProps = {
|
|
...tokenOptions,
|
|
tokenAddress: '0x7D7fD4E91834A96cD9Fb2369E7f4EB72383bbdEd',
|
|
symbolPrefix: 't',
|
|
network: {
|
|
id: arbitrumSepolia.id,
|
|
name: 'Arbitrum Sepolia',
|
|
iconSrc: '/images/arbitrum.svg',
|
|
},
|
|
children: <TokenActionButton href="/stake">Stake</TokenActionButton>,
|
|
};
|
|
|
|
const tokenDetailsEthereumSepolia: DynamicTokenRowProps = {
|
|
...tokenOptions,
|
|
tokenAddress: '0x0DBD22764C6C77827B4D03482998CA2dd61b5294',
|
|
symbolPrefix: 't',
|
|
network: {
|
|
id: sepolia.id,
|
|
name: 'Ethereum Sepolia',
|
|
iconSrc: '/images/eth.svg',
|
|
className: 'bg-session-white',
|
|
},
|
|
children: <TokenActionButton href="/bridge/arbitrum">Bridge</TokenActionButton>,
|
|
};
|
|
|
|
const tokenDetailsWOXENEthereum: DynamicTokenRowProps = {
|
|
tokenAddress: '0xd1e2d5085b39B80C9948AeB1b9aA83AF6756bcc5',
|
|
name: 'Wrapped OXEN',
|
|
iconSrc: 'https://stake.getsession.org/images/woxen.svg',
|
|
network: {
|
|
id: mainnet.id,
|
|
name: 'Ethereum',
|
|
iconSrc: '/images/eth.svg',
|
|
className: 'bg-session-white',
|
|
},
|
|
hideIfZero: true,
|
|
children: <TokenActionButton href="https://claim.oxen.io">Migrate</TokenActionButton>,
|
|
};
|
|
|
|
export type ConfigParams = {
|
|
projectId: string;
|
|
testnet?: boolean;
|
|
arbRpcUrl?: string;
|
|
arbRpcBatchCalls?: boolean;
|
|
ethRpcUrl?: string;
|
|
ethRpcBatchCalls?: boolean;
|
|
};
|
|
|
|
const batchConfig = { batch: { batchSize: 100, wait: 500 } } as const;
|
|
|
|
const createConfig = ({
|
|
ethRpcUrl,
|
|
arbRpcUrl,
|
|
ethRpcBatchCalls,
|
|
arbRpcBatchCalls,
|
|
testnet,
|
|
projectId,
|
|
}: ConfigParams) => {
|
|
const arb = testnet ? arbitrumSepolia : arbitrum;
|
|
const eth = testnet ? sepolia : mainnet;
|
|
|
|
const transports = {
|
|
[arb.id]: http(
|
|
arbRpcUrl ?? arb.rpcUrls.default.http[0],
|
|
arbRpcBatchCalls ? batchConfig : undefined
|
|
),
|
|
[eth.id]: http(
|
|
ethRpcUrl ?? eth.rpcUrls.default.http[0],
|
|
ethRpcBatchCalls ? batchConfig : undefined
|
|
),
|
|
};
|
|
|
|
const config = createWeb3WalletConfig({
|
|
wagmiConfig: {
|
|
chains: [arb, eth],
|
|
transports,
|
|
},
|
|
walletConnectConfig: {
|
|
projectId,
|
|
},
|
|
metaMaskConfig: {
|
|
dappMetadata: {
|
|
name: 'Session Wallet',
|
|
url: 'https://stake.getsession.org',
|
|
},
|
|
},
|
|
});
|
|
|
|
config.componentLibrary = componentLibrary;
|
|
|
|
config.tokens = testnet
|
|
? [tokenDetailsArbitrumSepolia, tokenDetailsEthereumSepolia]
|
|
: [tokenDetailsArbitrum, tokenDetailsEthereum, tokenDetailsWOXENEthereum];
|
|
|
|
return config;
|
|
};
|
|
|
|
export type Web3WalletProviderProps = Omit<WalletProviderProps, 'config'> & {
|
|
walletSheetConfig: ConfigParams;
|
|
children: ReactNode;
|
|
};
|
|
|
|
export function Web3WalletProvider({
|
|
children,
|
|
wagmiCookie,
|
|
settingsPreferenceStorage,
|
|
walletSheetConfig,
|
|
}: Web3WalletProviderProps) {
|
|
const [config] = useState(createConfig(walletSheetConfig));
|
|
|
|
return (
|
|
<WalletProvider
|
|
settingsPreferenceStorage={settingsPreferenceStorage}
|
|
config={config}
|
|
wagmiCookie={wagmiCookie}
|
|
>
|
|
<QueryProvider>{children}</QueryProvider>
|
|
</WalletProvider>
|
|
);
|
|
}
|