diff --git a/apps/appkit-minter/src/core/components/layout/app-router/app-router.tsx b/apps/appkit-minter/src/core/components/layout/app-router/app-router.tsx index a10a7b60e..ef78bdc27 100644 --- a/apps/appkit-minter/src/core/components/layout/app-router/app-router.tsx +++ b/apps/appkit-minter/src/core/components/layout/app-router/app-router.tsx @@ -11,7 +11,7 @@ import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import { useWatchBalance, useWatchTransactions, useWatchJettons, useBalance } from '@ton/appkit-react'; import { toast } from 'sonner'; -import { JettonsPage, MinterPage, NftsPage, StakingPage, SwapPage } from '@/pages'; +import { JettonsPage, MinterPage, NftsPage, StakingPage, SwapPage, SmartAccountPage, BridgeToTacPage } from '@/pages'; export const AppRouter: React.FC = () => { // Set balance refetch interval to 20 seconds @@ -57,6 +57,8 @@ export const AppRouter: React.FC = () => { } /> } /> } /> + } /> + } /> } /> diff --git a/apps/appkit-minter/src/core/components/layout/layout/layout.tsx b/apps/appkit-minter/src/core/components/layout/layout/layout.tsx index 7bfb7c0f4..3a34aebbb 100644 --- a/apps/appkit-minter/src/core/components/layout/layout/layout.tsx +++ b/apps/appkit-minter/src/core/components/layout/layout/layout.tsx @@ -7,7 +7,17 @@ */ import { TonConnectButton, useAddress } from '@ton/appkit-react'; -import { ArrowLeftRight, BookOpen, Coins, ExternalLink, Github, ImageIcon, Sparkles, Wallet } from 'lucide-react'; +import { + ArrowLeftRight, + BookOpen, + Coins, + ExternalLink, + Github, + ImageIcon, + Sparkles, + Wallet, + WorkflowIcon, +} from 'lucide-react'; import { Link, NavLink } from 'react-router-dom'; import type { ComponentType, FC, ReactNode } from 'react'; @@ -58,6 +68,13 @@ const NAV_GROUPS: readonly { label?: string; links: readonly NavGroupLink[] }[] { to: '/staking', label: 'Staking', icon: Coins }, ], }, + { + label: 'Cross-chain', + links: [ + { to: '/tac-smart-account', label: 'TAC – Smart account', icon: WorkflowIcon }, + { to: '/bridge-to-tac', label: 'TAC – Bridge', icon: ArrowLeftRight }, + ], + }, ]; const EXTERNAL_LINKS: readonly { href: string; label: string; icon: ComponentType<{ className?: string }> }[] = [ diff --git a/apps/appkit-minter/src/core/configs/app-kit.ts b/apps/appkit-minter/src/core/configs/app-kit.ts index 1e51648dd..3cf1338d2 100644 --- a/apps/appkit-minter/src/core/configs/app-kit.ts +++ b/apps/appkit-minter/src/core/configs/app-kit.ts @@ -17,6 +17,7 @@ import { import { createDeDustProvider } from '@ton/appkit/swap/dedust'; import { createOmnistonProvider } from '@ton/appkit/swap/omniston'; import { createTonstakersProvider } from '@ton/appkit/staking/tonstakers'; +import { createTacProvider } from '@ton/appkit/cross-chain/tac'; import { ENV_TON_API_KEY_TESTNET, ENV_TON_API_KEY_MAINNET, ENV_TONCONNECT_MANIFEST_URL } from '@/core/configs/env'; @@ -52,6 +53,7 @@ export const appKit = new AppKit({ createOmnistonProvider(), createDeDustProvider(), createTonstakersProvider(), + createTacProvider(), createTonCenterStreamingProvider({ network: Network.mainnet(), apiKey: ENV_TON_API_KEY_MAINNET }), createTonCenterStreamingProvider({ network: Network.testnet(), apiKey: ENV_TON_API_KEY_TESTNET }), ], diff --git a/apps/appkit-minter/src/features/cross-chain/components/tac/bridge-to-tac-chain.tsx b/apps/appkit-minter/src/features/cross-chain/components/tac/bridge-to-tac-chain.tsx new file mode 100644 index 000000000..ea99bc6e9 --- /dev/null +++ b/apps/appkit-minter/src/features/cross-chain/components/tac/bridge-to-tac-chain.tsx @@ -0,0 +1,242 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import React, { useMemo, useState } from 'react'; +import { + Button, + Input, + useAddress, + useBalance, + useJettons, + formatLargeValue, + parseUnits, + TokenSelectModal, + Skeleton, +} from '@ton/appkit-react'; +import type { AppkitUIToken } from '@ton/appkit-react'; +import { useSendCrossChainTransaction, useCrossChainProvider } from '@ton/appkit-react/cross-chain'; +import { Network, validateNumericString, calcFiatValue, compareAddress } from '@ton/appkit'; +import { toast } from 'sonner'; +import { ChevronDown } from 'lucide-react'; + +import { TacTransactionProgress } from './tac-transaction-progress'; +import { TacAddressInput, isTacAddressValid } from './tac-address-input'; + +const ASSETS: AppkitUIToken[] = [ + { + symbol: 'TON', + name: 'Toncoin', + address: 'ton', + decimals: 9, + logo: 'https://asset.ston.fi/img/EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c/c8d21a3d93f9b574381e0a8d8f16d48b325dd8f54ce172f599c1e9d6c62f03f7', + network: Network.mainnet(), + }, + { + symbol: 'USD₮', + name: 'Tether USD', + address: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', + decimals: 6, + logo: 'https://asset.ston.fi/img/EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs/1a87edfee9a28b05578853952e5effb8cc30af1e0fb90043aa2ce19dce490849', + network: Network.mainnet(), + rate: '1', + }, + { + symbol: 'STON', + name: 'STON', + address: 'EQA2kCVNwVsil2EM2mB0SkXytxCqQjS4mttjDpnXmwG9T6bO', + decimals: 9, + logo: 'https://asset.ston.fi/img/EQA2kCVNwVsil2EM2mB0SkXytxCqQjS4mttjDpnXmwG9T6bO/7c9798ce1e64707fb4cb8f025d4060f66b386ed381b50498e3b88731cedeffe8', + network: Network.mainnet(), + }, +]; + +export const BridgeToTacChain: React.FC = () => { + const [targetWalletAddress, setTargetWalletAddress] = useState(''); + const [amount, setAmount] = useState(''); + const [selectedAsset, setSelectedAsset] = useState(ASSETS[0]); + const [isTokenSelectOpen, setIsTokenSelectOpen] = useState(false); + const [trackingHash, setTrackingHash] = useState(null); + const [isSending, setIsSending] = useState(false); + + const address = useAddress(); + const { data: tonBalance, isLoading: isTonLoading, refetch: refetchBalance } = useBalance(); + const { data: userJettons, isLoading: isJettonsLoading, refetch: refetchJettons } = useJettons(); + + const crossChainProvider = useCrossChainProvider({ id: 'tac' }); + const { send } = useSendCrossChainTransaction({ providerId: 'tac' }); + + const isBalanceLoading = selectedAsset.address === 'ton' ? isTonLoading : isJettonsLoading; + + const currentBalance = useMemo(() => { + if (selectedAsset.address === 'ton') { + return tonBalance || '0'; + } + const jetton = userJettons?.jettons?.find((j) => compareAddress(j.address, selectedAsset.address)); + return jetton?.balance || '0'; + }, [selectedAsset, tonBalance, userJettons]); + + const formattedBalance = useMemo(() => { + return formatLargeValue(currentBalance, 4); + }, [currentBalance]); + + const handleMax = () => { + setAmount(currentBalance); + }; + + const handleAmountChange = (val: string) => { + const normalized = val.replace(',', '.'); + if (normalized === '' || validateNumericString(normalized, selectedAsset.decimals)) { + setAmount(normalized); + } + }; + + const handleSend = async () => { + if (!crossChainProvider) { + toast.error('Cross-chain provider not initialized'); + return; + } + + if (!address) { + toast.error('Wallet not connected'); + return; + } + + if (!targetWalletAddress) { + toast.error('Please enter a target wallet address'); + return; + } + + if (!isTacAddressValid(targetWalletAddress)) { + toast.error('Invalid TAC Wallet address'); + return; + } + + const amountNum = Number(amount); + if (isNaN(amountNum) || amountNum <= 0) { + toast.error('Please enter a valid amount'); + return; + } + + setIsSending(true); + try { + const amountBigInt = parseUnits(amount, selectedAsset.decimals); + + const result = await send({ + senderAddress: address, + message: { + evmTargetAddress: targetWalletAddress, + }, + assets: [ + { + address: selectedAsset.address === 'ton' ? undefined : selectedAsset.address, + rawAmount: amountBigInt, + }, + ], + }); + + if (result.normalizedHash) { + setTrackingHash(result.normalizedHash); + toast.success('Transaction submitted successfully!'); + refetchBalance(); + refetchJettons(); + } + } catch (e) { + toast.error(e instanceof Error ? e.message : 'Failed to send transaction'); + } finally { + setIsSending(false); + } + }; + + return ( +
+
+
+
+
+ + + Amount + + +
+ handleAmountChange((e.target as HTMLInputElement).value)} + placeholder="0.0" + /> + +
+ +
+
+ {selectedAsset.rate && amount && ( + <>≈ ${formatLargeValue(calcFiatValue(amount, selectedAsset.rate), 2)} + )} +
+
+ + Balance:{' '} + {isBalanceLoading ? ( + + ) : ( + <> + {formattedBalance} {selectedAsset.symbol} + + )} + + +
+
+
+
+
+
+ + +
+ + +
+ + setIsTokenSelectOpen(false)} + tokens={ASSETS} + onSelect={setSelectedAsset} + title="Select Token" + /> + + {trackingHash && ( + setTrackingHash(null)} /> + )} +
+ ); +}; diff --git a/apps/appkit-minter/src/features/cross-chain/components/tac/smart-account.tsx b/apps/appkit-minter/src/features/cross-chain/components/tac/smart-account.tsx new file mode 100644 index 000000000..43c497e84 --- /dev/null +++ b/apps/appkit-minter/src/features/cross-chain/components/tac/smart-account.tsx @@ -0,0 +1,156 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import React, { useMemo, useState } from 'react'; +import { Network } from '@ton/appkit'; +import { Button, Input, Select } from '@ton/appkit-react'; +import { useSmartAccountAddress } from '@ton/appkit-react/cross-chain'; +import { Copy, ExternalLink, ChevronDownIcon, LayoutGrid } from 'lucide-react'; +import { Skeleton } from '@ton/appkit-react'; +import { useNetwork } from '@ton/appkit-react'; + +import { TacAddressInput, isTacAddressValid } from './tac-address-input'; + +const APPS = [ + { + name: 'Orbs', + address: '0xaD809718714905344669E2C5150a33b21c35C53E', + logo: 'https://assets.coingecko.com/coins/images/4630/standard/Orbs.jpg?1696505200', + }, + { + name: 'Merkl', + address: '0x74e6b5e701bA5de3245653d72A075c7709EeFDC4', + logo: 'https://raw.githubusercontent.com/AngleProtocol/angle-token-list/refs/heads/main/src/assets/protocols/merkl.svg', + }, + { + name: 'Euler', + address: '0xDD9722bd6874167Ee2b5b4062cf65d0C5Cdb2280', + logo: 'https://raw.githubusercontent.com/AngleProtocol/angle-token-list/refs/heads/main/src/assets/tokens/EUL.svg', + }, +]; + +export const SmartAccount: React.FC = () => { + const [selectedAppId, setSelectedAppId] = useState(APPS[0].address); + const [customAppAddress, setCustomAppAddress] = useState(''); + const network = useNetwork(); + + const appAddress = selectedAppId === 'custom' ? customAppAddress : selectedAppId; + const isAppAddressValid = isTacAddressValid(appAddress); + + const { address: smartAccountAddress, isLoading: isAddressLoading } = useSmartAccountAddress({ + applicationAddress: isAppAddressValid ? appAddress : '', + providerId: 'tac', + }); + + const explorerLink = useMemo(() => { + if (!smartAccountAddress) { + return undefined; + } + if (network?.chainId === Network.testnet().chainId) { + return `https://spb.explorer.tac.build/address/${smartAccountAddress}`; + } + return `https://explorer.tac.build/address/${smartAccountAddress}`; + }, [smartAccountAddress]); + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(text); + } catch { + // Fail silently + } + }; + + return ( +
+
+ + + Select dApp + + + + {selectedAppId === 'custom' ? ( + + ) : ( + a.address === selectedAppId)?.logo} + className="size-5 rounded-full" + alt="" + /> + )} + + {selectedAppId === 'custom' + ? 'Custom' + : APPS.find((a) => a.address === selectedAppId)?.name} + + + + + {APPS.map((app) => ( + + + {app.name} + + ))} + + + Custom + + + + + + {selectedAppId === 'custom' && ( + + )} + + + + Your Smart Account Address + + +
+ {isAddressLoading ? ( + + ) : ( + + {(smartAccountAddress as string) || '—'} + + )} + +
+ + +
+
+
+
+
+
+ ); +}; diff --git a/apps/appkit-minter/src/features/cross-chain/components/tac/tac-address-input.tsx b/apps/appkit-minter/src/features/cross-chain/components/tac/tac-address-input.tsx new file mode 100644 index 000000000..7f5466d6e --- /dev/null +++ b/apps/appkit-minter/src/features/cross-chain/components/tac/tac-address-input.tsx @@ -0,0 +1,65 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import React from 'react'; +import { Button, Input } from '@ton/appkit-react'; +import { toast } from 'sonner'; + +export const isTacAddressValid = (address: string) => !address || /^0x[a-fA-F0-9]{40}$/.test(address); + +interface TacAddressInputProps { + value: string; + onChange: (value: string) => void; + label?: string; + name?: string; + placeholder?: string; + className?: string; +} + +export const TacAddressInput: React.FC = ({ + value, + onChange, + label = 'Target TAC Wallet', + name = 'tac-address-input', + placeholder = '0x...', + className, +}) => { + const isValid = isTacAddressValid(value); + + const handlePaste = async () => { + try { + const text = await navigator.clipboard.readText(); + onChange(text.trim()); + } catch { + toast.error('Failed to read from clipboard'); + } + }; + + return ( + + + {label} + + +
+ onChange((e.target as HTMLInputElement).value)} + placeholder={placeholder} + /> + +
+
+ {!isValid && value !== '' && Invalid EVM address} +
+ ); +}; diff --git a/apps/appkit-minter/src/features/cross-chain/components/tac/tac-transaction-progress.tsx b/apps/appkit-minter/src/features/cross-chain/components/tac/tac-transaction-progress.tsx new file mode 100644 index 000000000..9c812159e --- /dev/null +++ b/apps/appkit-minter/src/features/cross-chain/components/tac/tac-transaction-progress.tsx @@ -0,0 +1,123 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import React from 'react'; +import { Button, useNetwork, Network } from '@ton/appkit-react'; +import { useCrossChainTransactionStatus } from '@ton/appkit-react/cross-chain'; +import { ExternalLink, Info, CheckCircle2, AlertCircle } from 'lucide-react'; + +import { cn } from '@/core/lib/utils'; + +interface TacTransactionProgressProps { + trackingHash: string; + onDismiss: () => void; +} + +export const TacTransactionProgress: React.FC = ({ trackingHash, onDismiss }) => { + const network = useNetwork(); + const { data: trackData, isLoading: isTracking } = useCrossChainTransactionStatus({ + transactionHash: trackingHash, + providerId: 'tac', + }); + + const status = trackData?.status; + const totalMessages = trackData?.totalMessages || 0; + const onchainMessages = trackData?.onchainMessages || 0; + + const getProgress = () => { + if (status === 'completed') return 100; + if (!trackData || totalMessages === 0) return 0; + return (onchainMessages / totalMessages) * 100; + }; + + const getStatusColor = () => { + if (status === 'failed') return 'text-red-500'; + if (status === 'completed') return 'text-green-500'; + return 'text-blue-500'; + }; + + return ( +
+
+

+ + Transaction Status +

+ +
+ +
+
+
+ TON tx hash + {trackingHash} +
+ +
+ +
+
+ Current Status + + {isTracking + ? 'Processing...' + : status === 'pending' && totalMessages > 0 + ? `Processing (${onchainMessages}/${totalMessages})` + : status && status !== 'unknown' + ? status + : 'Pending'} + +
+
+
+
+
+ + {status === 'completed' && ( +
+ + Successfully sent to TAC! +
+ )} + + {status === 'failed' && ( +
+ + Execution failed. Check explorer for details. +
+ )} +
+
+ ); +}; diff --git a/apps/appkit-minter/src/features/cross-chain/index.ts b/apps/appkit-minter/src/features/cross-chain/index.ts new file mode 100644 index 000000000..7432910e6 --- /dev/null +++ b/apps/appkit-minter/src/features/cross-chain/index.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export { SmartAccount } from './components/tac/smart-account'; +export { BridgeToTacChain } from './components/tac/bridge-to-tac-chain'; diff --git a/apps/appkit-minter/src/pages/bridge-to-tac-page.tsx b/apps/appkit-minter/src/pages/bridge-to-tac-page.tsx new file mode 100644 index 000000000..122a7e27b --- /dev/null +++ b/apps/appkit-minter/src/pages/bridge-to-tac-page.tsx @@ -0,0 +1,20 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type React from 'react'; + +import { Layout } from '@/core/components'; +import { BridgeToTacChain } from '@/features/cross-chain'; + +export const BridgeToTacPage: React.FC = () => { + return ( + + + + ); +}; diff --git a/apps/appkit-minter/src/pages/index.ts b/apps/appkit-minter/src/pages/index.ts index 09a13a93d..feaa0298b 100644 --- a/apps/appkit-minter/src/pages/index.ts +++ b/apps/appkit-minter/src/pages/index.ts @@ -11,3 +11,5 @@ export { JettonsPage } from './jettons-page'; export { NftsPage } from './nfts-page'; export { SwapPage } from './swap-page'; export { StakingPage } from './staking-page'; +export { SmartAccountPage } from './smart-account-page'; +export { BridgeToTacPage } from './bridge-to-tac-page'; diff --git a/apps/appkit-minter/src/pages/smart-account-page.tsx b/apps/appkit-minter/src/pages/smart-account-page.tsx new file mode 100644 index 000000000..9ba948b85 --- /dev/null +++ b/apps/appkit-minter/src/pages/smart-account-page.tsx @@ -0,0 +1,20 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type React from 'react'; + +import { Layout } from '@/core/components'; +import { SmartAccount } from '@/features/cross-chain'; + +export const SmartAccountPage: React.FC = () => { + return ( + + + + ); +}; diff --git a/packages/appkit-react/package.json b/packages/appkit-react/package.json index 26f4edb82..fee5d982a 100644 --- a/packages/appkit-react/package.json +++ b/packages/appkit-react/package.json @@ -33,12 +33,19 @@ "types": "./dist/types/index.d.ts", "default": "./dist/esm/index.js" }, - "./styles.css": "./dist/esm/styles/index.css" + "./styles.css": "./dist/esm/styles/index.css", + "./cross-chain": { + "types": "./dist/types/features/cross-chain/index.d.ts", + "default": "./dist/esm/features/cross-chain/index.js" + } }, "typesVersions": { "*": { "styles.css": [ "./dist/esm/styles/index.css" + ], + "cross-chain": [ + "./dist/types/features/cross-chain/index.d.ts" ] } }, diff --git a/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-provider.ts b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-provider.ts new file mode 100644 index 000000000..4a073028d --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-provider.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { useSyncExternalStore, useCallback } from 'react'; +import { getCrossChainProvider, watchCrossChainProviders } from '@ton/appkit'; +import type { GetCrossChainProviderOptions, GetCrossChainProviderReturnType } from '@ton/appkit'; + +import { useAppKit } from '../../settings'; + +export type UseCrossChainProviderReturnType = GetCrossChainProviderReturnType; + +/** + * Hook to get cross-chain provider + */ +export const useCrossChainProvider = ( + options: GetCrossChainProviderOptions, +): UseCrossChainProviderReturnType | undefined => { + const appKit = useAppKit(); + const { id } = options; + + const subscribe = useCallback( + (onChange: () => void) => { + return watchCrossChainProviders(appKit, { onChange }); + }, + [appKit], + ); + + const getSnapshot = useCallback(() => { + try { + return getCrossChainProvider(appKit, { id }); + } catch { + return undefined; + } + }, [appKit, id]); + + return useSyncExternalStore(subscribe, getSnapshot, getSnapshot); +}; diff --git a/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-providers.ts b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-providers.ts new file mode 100644 index 000000000..d6a8702f7 --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-providers.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { useSyncExternalStore, useCallback } from 'react'; +import { getCrossChainProviders, watchCrossChainProviders } from '@ton/appkit'; +import type { GetCrossChainProvidersReturnType } from '@ton/appkit'; + +import { useAppKit } from '../../settings'; + +export type UseCrossChainProvidersReturnType = GetCrossChainProvidersReturnType; + +/** + * Hook to get all registered cross-chain providers. + */ +export const useCrossChainProviders = (): UseCrossChainProvidersReturnType => { + const appKit = useAppKit(); + + const subscribe = useCallback( + (onChange: () => void) => { + return watchCrossChainProviders(appKit, { onChange }); + }, + [appKit], + ); + + const getSnapshot = useCallback(() => { + return getCrossChainProviders(appKit); + }, [appKit]); + + return useSyncExternalStore(subscribe, getSnapshot, getSnapshot); +}; diff --git a/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-transaction-status.ts b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-transaction-status.ts new file mode 100644 index 000000000..666f81b6f --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/hooks/use-cross-chain-transaction-status.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { + GetCrossChainTransactionStatusData, + GetCrossChainTransactionStatusErrorType, + GetCrossChainTransactionStatusParameters, + GetCrossChainTransactionStatusQueryConfig, +} from '@ton/appkit/queries'; +import { getCrossChainTransactionStatusQueryOptions } from '@ton/appkit/queries'; + +import { useQuery } from '../../../libs/query'; +import type { UseQueryReturnType } from '../../../libs/query'; +import { useAppKit } from '../../settings'; + +export type UseCrossChainTransactionStatusParameters = + GetCrossChainTransactionStatusParameters & GetCrossChainTransactionStatusQueryConfig; + +export type UseCrossChainTransactionStatusReturnType = + UseQueryReturnType; + +/** + * Hook for tracking cross-chain transactions. + * + * This hook polls the cross-chain provider to track the progress of a cross-chain transaction. + * + * @example + * ```ts + * const { data: status } = useCrossChainTransactionStatus({ + * transactionHash: '...', + * providerId: 'tac', + * query: { + * refetchInterval: 2000, + * } + * }); + * ``` + */ +export const useCrossChainTransactionStatus = ( + parameters: UseCrossChainTransactionStatusParameters, +): UseCrossChainTransactionStatusReturnType => { + const appKit = useAppKit(); + + return useQuery(getCrossChainTransactionStatusQueryOptions(appKit, parameters)); +}; diff --git a/packages/appkit-react/src/features/cross-chain/hooks/use-send-cross-chain-transaction.ts b/packages/appkit-react/src/features/cross-chain/hooks/use-send-cross-chain-transaction.ts new file mode 100644 index 000000000..f4235255d --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/hooks/use-send-cross-chain-transaction.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { buildCrossChainTransaction, sendTransaction } from '@ton/appkit'; +import { useCallback } from 'react'; + +import { useAppKit } from '../../settings'; + +export interface UseSendCrossChainTransactionParameters { + providerId?: string; +} + +/** + * Hook for sending cross-chain transactions. + */ +export const useSendCrossChainTransaction = (parameters: UseSendCrossChainTransactionParameters = {}) => { + const { providerId } = parameters; + const appKit = useAppKit(); + + const send = useCallback( + async (txParameters: unknown) => { + if (!providerId) { + throw new Error('Provider ID is required'); + } + + const transactionRequest = await buildCrossChainTransaction(appKit, { + providerId, + parameters: txParameters, + }); + + return sendTransaction(appKit, transactionRequest); + }, + [appKit, providerId], + ); + + return { send }; +}; diff --git a/packages/appkit-react/src/features/cross-chain/hooks/use-smart-account-address.ts b/packages/appkit-react/src/features/cross-chain/hooks/use-smart-account-address.ts new file mode 100644 index 000000000..281e5d0d1 --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/hooks/use-smart-account-address.ts @@ -0,0 +1,50 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { getSmartAccountAddress } from '@ton/appkit'; +import type { Compute } from '@ton/appkit'; + +import { useQuery } from '../../../libs/query'; +import type { UseQueryReturnType } from '../../../libs/query'; +import { useAppKit } from '../../settings'; +import { useAddress } from '../../wallets'; + +export interface UseSmartAccountAddressParameters { + applicationAddress?: string; + providerId?: string; +} + +export type UseSmartAccountAddressReturnType = Compute< + Omit, 'data'> & { + address: string | null; + } +>; + +/** + * Hook for getting the smart account address. + */ +export const useSmartAccountAddress = ( + parameters: UseSmartAccountAddressParameters, +): UseSmartAccountAddressReturnType => { + const { applicationAddress, providerId } = parameters; + const appKit = useAppKit(); + const address = useAddress(); + + const { data, ...rest } = useQuery({ + queryKey: ['cross-chain', 'smart-account', address, applicationAddress, providerId], + queryFn: async () => { + if (!providerId || !applicationAddress || !address) { + return null; + } + return getSmartAccountAddress(appKit, { applicationAddress, providerId }); + }, + enabled: !!providerId && !!applicationAddress && !!address, + }); + + return { address: data, ...rest } as UseSmartAccountAddressReturnType; +}; diff --git a/packages/appkit-react/src/features/cross-chain/index.ts b/packages/appkit-react/src/features/cross-chain/index.ts new file mode 100644 index 000000000..91245486b --- /dev/null +++ b/packages/appkit-react/src/features/cross-chain/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export * from './hooks/use-send-cross-chain-transaction'; +export * from './hooks/use-cross-chain-transaction-status'; +export * from './hooks/use-smart-account-address'; +export * from './hooks/use-cross-chain-provider'; +export * from './hooks/use-cross-chain-providers'; diff --git a/packages/appkit-react/src/index.ts b/packages/appkit-react/src/index.ts index 2ae249e19..ce9a62d91 100644 --- a/packages/appkit-react/src/index.ts +++ b/packages/appkit-react/src/index.ts @@ -39,5 +39,6 @@ export * from './features/settings'; export * from './features/swap'; export * from './features/signing'; export * from './features/staking'; +export * from './features/cross-chain'; export * from './types/appkit-ui-token'; diff --git a/packages/appkit/package.json b/packages/appkit/package.json index 93bd90bb2..ad6cafea1 100644 --- a/packages/appkit/package.json +++ b/packages/appkit/package.json @@ -60,6 +60,16 @@ "types": "./dist/cjs/staking/tonstakers/index.d.ts", "default": "./dist/cjs/staking/tonstakers/index.js" } + }, + "./cross-chain/tac": { + "import": { + "types": "./dist/esm/cross-chain/tac/index.d.ts", + "default": "./dist/esm/cross-chain/tac/index.js" + }, + "require": { + "types": "./dist/cjs/cross-chain/tac/index.d.ts", + "default": "./dist/cross-chain/cjs/tac/index.js" + } } }, "typesVersions": { @@ -75,6 +85,9 @@ ], "staking/tonstakers": [ "./dist/esm/staking/tonstakers/index.d.ts" + ], + "cross-chain/tac": [ + "./dist/esm/tac/index.d.ts" ] } }, diff --git a/packages/appkit/src/actions/cross-chain/build-cross-chain-transaction.ts b/packages/appkit/src/actions/cross-chain/build-cross-chain-transaction.ts new file mode 100644 index 000000000..5b90a7019 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/build-cross-chain-transaction.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { TransactionRequest } from '@ton/walletkit'; + +import type { AppKit } from '../../core/app-kit'; + +export interface BuildCrossChainTransactionOptions { + /** + * The transaction parameters. + */ + parameters: T; + + /** + * The required ID of the cross-chain provider to use. + */ + providerId: string; +} + +export type BuildCrossChainTransactionReturnType = Promise; + +/** + * Builds a cross-chain transaction. + * + * @param appKit - The AppKit instance. + * @param options - The transaction options. + * @returns The built transaction request. + */ +export async function buildCrossChainTransaction( + appKit: AppKit, + options: BuildCrossChainTransactionOptions, +): BuildCrossChainTransactionReturnType { + const provider = appKit.crossChainManager.getProvider(options.providerId); + return await provider.buildCrossChainTransaction(options.parameters as never); +} diff --git a/packages/appkit/src/actions/cross-chain/get-cross-chain-manager.ts b/packages/appkit/src/actions/cross-chain/get-cross-chain-manager.ts new file mode 100644 index 000000000..77fbdbb55 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/get-cross-chain-manager.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { CrossChainManager } from '@ton/walletkit'; + +import type { AppKit } from '../../core/app-kit'; + +export type GetCrossChainManagerReturnType = CrossChainManager; + +/** + * Get cross-chain manager instance + */ +export const getCrossChainManager = (appKit: AppKit): GetCrossChainManagerReturnType => { + return appKit.crossChainManager; +}; diff --git a/packages/appkit/src/actions/cross-chain/get-cross-chain-provider.ts b/packages/appkit/src/actions/cross-chain/get-cross-chain-provider.ts new file mode 100644 index 000000000..a16caf310 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/get-cross-chain-provider.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { CrossChainProvider } from '@ton/walletkit'; + +import type { AppKit } from '../../core/app-kit'; + +export interface GetCrossChainProviderOptions { + id: string; +} + +export type GetCrossChainProviderReturnType = CrossChainProvider; + +/** + * Get cross-chain provider by ID + */ +export const getCrossChainProvider = ( + appKit: AppKit, + options: GetCrossChainProviderOptions, +): GetCrossChainProviderReturnType => { + return appKit.crossChainManager.getProvider(options.id); +}; diff --git a/packages/appkit/src/actions/cross-chain/get-cross-chain-providers.ts b/packages/appkit/src/actions/cross-chain/get-cross-chain-providers.ts new file mode 100644 index 000000000..03900b809 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/get-cross-chain-providers.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { CrossChainProvider } from '@ton/walletkit'; + +import type { AppKit } from '../../core/app-kit'; + +export type GetCrossChainProvidersReturnType = CrossChainProvider[]; + +/** + * Get all registered cross-chain providers + */ +export const getCrossChainProviders = (appKit: AppKit): GetCrossChainProvidersReturnType => { + return appKit.crossChainManager.getProviders(); +}; diff --git a/packages/appkit/src/actions/cross-chain/get-cross-chain-transaction-status.ts b/packages/appkit/src/actions/cross-chain/get-cross-chain-transaction-status.ts new file mode 100644 index 000000000..7a555c79f --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/get-cross-chain-transaction-status.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { TransactionStatusResponse } from '@ton/walletkit'; + +import type { AppKit } from '../../core/app-kit'; + +export type GetCrossChainTransactionStatusParameters = { + /** + * The transaction hash to check. + */ + transactionHash: string; + + /** + * The ID of the cross-chain provider to use. + */ + providerId: string; +}; + +export type GetCrossChainTransactionStatusReturnType = TransactionStatusResponse; + +/** + * Gets the status of a cross-chain transaction. + * + * @param appKit - The AppKit instance. + * @param options - The options for getting the status. + * @returns The transaction status response. + */ +export async function getCrossChainTransactionStatus( + appKit: AppKit, + options: GetCrossChainTransactionStatusParameters, +): Promise { + const provider = appKit.crossChainManager.getProvider(options.providerId); + return provider.getTransactionStatus(options.transactionHash); +} diff --git a/packages/appkit/src/actions/cross-chain/get-smart-account-address.ts b/packages/appkit/src/actions/cross-chain/get-smart-account-address.ts new file mode 100644 index 000000000..5984a8c37 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/get-smart-account-address.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { AppKit } from '../../core/app-kit'; +import { getSelectedWallet } from '../wallets/get-selected-wallet'; + +export type GetSmartAccountAddressOptions = { + applicationAddress: string; + providerId: string; +}; +export type GetSmartAccountAddressReturnType = Promise; + +/** + * Gets the smart account address for a TVM wallet and application. + * + * @param appKit - The AppKit instance. + * @param options - The options for getting the smart account address. + * @returns The smart account address. + */ +export async function getSmartAccountAddress( + appKit: AppKit, + options: GetSmartAccountAddressOptions, +): GetSmartAccountAddressReturnType { + const provider = appKit.crossChainManager.getProvider(options.providerId); + const wallet = getSelectedWallet(appKit); + if (!wallet) { + throw new Error('No wallet connected'); + } + + const { applicationAddress } = options; + + return provider.getSmartAccountAddress(wallet.getAddress(), applicationAddress); +} diff --git a/packages/appkit/src/actions/cross-chain/has-cross-chain-provider.ts b/packages/appkit/src/actions/cross-chain/has-cross-chain-provider.ts new file mode 100644 index 000000000..3215ceb29 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/has-cross-chain-provider.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { AppKit } from '../../core/app-kit'; + +export interface HasCrossChainProviderOptions { + id: string; +} + +export type HasCrossChainProviderReturnType = boolean; + +/** + * Check if a cross-chain provider is registered + */ +export const hasCrossChainProvider = ( + appKit: AppKit, + options: HasCrossChainProviderOptions, +): HasCrossChainProviderReturnType => { + return appKit.crossChainManager.hasProvider(options.id); +}; diff --git a/packages/appkit/src/actions/cross-chain/watch-cross-chain-providers.ts b/packages/appkit/src/actions/cross-chain/watch-cross-chain-providers.ts new file mode 100644 index 000000000..ea589f1c4 --- /dev/null +++ b/packages/appkit/src/actions/cross-chain/watch-cross-chain-providers.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { AppKit } from '../../core/app-kit'; + +export interface WatchCrossChainProvidersParameters { + onChange: () => void; +} + +export type WatchCrossChainProvidersReturnType = () => void; + +/** + * Watch for new cross-chain providers registration + */ +export const watchCrossChainProviders = ( + appKit: AppKit, + parameters: WatchCrossChainProvidersParameters, +): WatchCrossChainProvidersReturnType => { + const { onChange } = parameters; + + const unsubscribeRegistered = appKit.emitter.on('provider:registered', (event) => { + if (event.payload.type === 'cross-chain') onChange(); + }); + + return () => { + unsubscribeRegistered(); + }; +}; diff --git a/packages/appkit/src/actions/index.ts b/packages/appkit/src/actions/index.ts index e9c38eb36..a952636fa 100644 --- a/packages/appkit/src/actions/index.ts +++ b/packages/appkit/src/actions/index.ts @@ -230,3 +230,33 @@ export { type WatchConnectedWalletsParameters, type WatchConnectedWalletsReturnType, } from './wallets/watch-connected-wallets'; + +// Cross-chain +export { getCrossChainManager, type GetCrossChainManagerReturnType } from './cross-chain/get-cross-chain-manager'; +export { + getCrossChainProvider, + type GetCrossChainProviderOptions, + type GetCrossChainProviderReturnType, +} from './cross-chain/get-cross-chain-provider'; +export { getCrossChainProviders, type GetCrossChainProvidersReturnType } from './cross-chain/get-cross-chain-providers'; +export { + getCrossChainTransactionStatus, + type GetCrossChainTransactionStatusParameters, + type GetCrossChainTransactionStatusReturnType, +} from './cross-chain/get-cross-chain-transaction-status'; +export { getSmartAccountAddress, type GetSmartAccountAddressReturnType } from './cross-chain/get-smart-account-address'; +export { + buildCrossChainTransaction, + type BuildCrossChainTransactionOptions, + type BuildCrossChainTransactionReturnType, +} from './cross-chain/build-cross-chain-transaction'; +export { + watchCrossChainProviders, + type WatchCrossChainProvidersParameters, + type WatchCrossChainProvidersReturnType, +} from './cross-chain/watch-cross-chain-providers'; +export { + hasCrossChainProvider, + type HasCrossChainProviderOptions, + type HasCrossChainProviderReturnType, +} from './cross-chain/has-cross-chain-provider'; diff --git a/packages/appkit/src/core/app-kit/services/app-kit.ts b/packages/appkit/src/core/app-kit/services/app-kit.ts index fcb685a37..d6a51fe1a 100644 --- a/packages/appkit/src/core/app-kit/services/app-kit.ts +++ b/packages/appkit/src/core/app-kit/services/app-kit.ts @@ -6,8 +6,14 @@ * */ -import { SwapManager, StreamingManager } from '@ton/walletkit'; -import type { ProviderInput, SwapProviderInterface, StakingProviderInterface, StreamingProvider } from '@ton/walletkit'; +import { SwapManager, StreamingManager, CrossChainManager } from '@ton/walletkit'; +import type { + ProviderInput, + SwapProviderInterface, + StakingProviderInterface, + CrossChainProvider, + StreamingProvider, +} from '@ton/walletkit'; import type { AppKitConfig } from '../types/config'; import { CONNECTOR_EVENTS, WALLETS_EVENTS } from '../constants/events'; @@ -33,6 +39,7 @@ export class AppKit { readonly walletsManager: WalletsManager; readonly swapManager: SwapManager; readonly stakingManager: StakingManager; + readonly crossChainManager: CrossChainManager; readonly networkManager: AppKitNetworkManager; readonly streamingManager: StreamingManager; @@ -57,6 +64,7 @@ export class AppKit { this.swapManager = new SwapManager(() => this.createFactoryContext()); this.stakingManager = new StakingManager(() => this.createFactoryContext()); this.streamingManager = new StreamingManager(() => this.createFactoryContext()); + this.crossChainManager = new CrossChainManager(() => this.createFactoryContext()); if (config.connectors) { config.connectors.forEach((input) => { @@ -126,6 +134,9 @@ export class AppKit { case 'streaming': this.streamingManager.registerProvider(provider as StreamingProvider); break; + case 'cross-chain': + this.crossChainManager.registerProvider(provider as CrossChainProvider); + break; default: throw new Error('Unknown provider type'); } diff --git a/packages/appkit/src/cross-chain/tac/index.ts b/packages/appkit/src/cross-chain/tac/index.ts new file mode 100644 index 000000000..f2a14cf76 --- /dev/null +++ b/packages/appkit/src/cross-chain/tac/index.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export * from '@ton/walletkit/cross-chain/tac'; diff --git a/packages/appkit/src/queries/cross-chain/get-cross-chain-transaction-status.ts b/packages/appkit/src/queries/cross-chain/get-cross-chain-transaction-status.ts new file mode 100644 index 000000000..3b0ef1d35 --- /dev/null +++ b/packages/appkit/src/queries/cross-chain/get-cross-chain-transaction-status.ts @@ -0,0 +1,48 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { getCrossChainTransactionStatus } from '../../actions'; +import type { GetCrossChainTransactionStatusParameters, GetCrossChainTransactionStatusReturnType } from '../../actions'; +import type { AppKit } from '../../core/app-kit'; +import type { QueryOptions, QueryParameter } from '../../types/query'; +import type { Compute } from '../../types/utils'; + +export type { GetCrossChainTransactionStatusParameters, GetCrossChainTransactionStatusReturnType }; + +export type GetCrossChainTransactionStatusData = Compute; + +export type GetCrossChainTransactionStatusErrorType = Error; + +export type GetCrossChainTransactionStatusQueryKey = readonly ['cross-chain', 'transaction-status', string, string]; + +export type GetCrossChainTransactionStatusQueryConfig = QueryParameter< + GetCrossChainTransactionStatusData, + GetCrossChainTransactionStatusErrorType, + selectData, + GetCrossChainTransactionStatusQueryKey +>; + +export type GetCrossChainTransactionStatusQueryOptions = QueryOptions< + GetCrossChainTransactionStatusData, + GetCrossChainTransactionStatusErrorType, + selectData, + GetCrossChainTransactionStatusQueryKey +>; + +export const getCrossChainTransactionStatusQueryOptions = ( + appKit: AppKit, + options: GetCrossChainTransactionStatusParameters & GetCrossChainTransactionStatusQueryConfig, +): GetCrossChainTransactionStatusQueryOptions => { + return { + ...options.query, + queryFn: () => { + return getCrossChainTransactionStatus(appKit, options); + }, + queryKey: ['cross-chain', 'transaction-status', options.providerId, options.transactionHash] as const, + }; +}; diff --git a/packages/appkit/src/queries/index.ts b/packages/appkit/src/queries/index.ts index da7e6f0b9..26793b7b0 100644 --- a/packages/appkit/src/queries/index.ts +++ b/packages/appkit/src/queries/index.ts @@ -229,3 +229,14 @@ export { type GetTransactionStatusQueryConfig, type GetTransactionStatusQueryOptions, } from './transaction/get-transaction-status'; + +// Cross-chain +export { + getCrossChainTransactionStatusQueryOptions, + type GetCrossChainTransactionStatusData, + type GetCrossChainTransactionStatusErrorType, + type GetCrossChainTransactionStatusParameters, + type GetCrossChainTransactionStatusReturnType, + type GetCrossChainTransactionStatusQueryConfig, + type GetCrossChainTransactionStatusQueryOptions, +} from './cross-chain/get-cross-chain-transaction-status'; diff --git a/packages/appkit/src/types/provider.ts b/packages/appkit/src/types/provider.ts index d83d060d0..650f0b83d 100644 --- a/packages/appkit/src/types/provider.ts +++ b/packages/appkit/src/types/provider.ts @@ -6,9 +6,14 @@ * */ -import type { SwapProviderInterface, StakingProviderInterface, StreamingProvider } from '@ton/walletkit'; +import type { + SwapProviderInterface, + StakingProviderInterface, + StreamingProvider, + CrossChainProvider, +} from '@ton/walletkit'; /** * Available provider types in AppKit. */ -export type AppKitProvider = SwapProviderInterface | StakingProviderInterface | StreamingProvider; +export type AppKitProvider = SwapProviderInterface | StakingProviderInterface | StreamingProvider | CrossChainProvider; diff --git a/packages/walletkit/package.json b/packages/walletkit/package.json index 2005fee11..e51e6458e 100644 --- a/packages/walletkit/package.json +++ b/packages/walletkit/package.json @@ -60,6 +60,16 @@ "types": "./dist/cjs/defi/staking/tonstakers/index.d.ts", "default": "./dist/cjs/defi/staking/tonstakers/index.js" } + }, + "./cross-chain/tac": { + "import": { + "types": "./dist/esm/cross-chain/tac/index.d.ts", + "default": "./dist/esm/cross-chain/tac/index.js" + }, + "require": { + "types": "./dist/cjs/cross-chain/tac/index.d.ts", + "default": "./dist/cjs/cross-chain/tac/index.js" + } } }, "typesVersions": { @@ -75,6 +85,9 @@ ], "staking/tonstakers": [ "./dist/cjs/defi/staking/tonstakers/index.d.ts" + ], + "cross-chain/tac": [ + "./dist/cjs/cross-chain/tac/index.d.ts" ] } }, @@ -119,11 +132,15 @@ }, "peerDependencies": { "@ton/core": "^0.62.0 || ^0.63.0", - "@ton/crypto": "^3.3.0" + "@ton/crypto": "^3.3.0", + "@tonappchain/sdk": "catalog:" }, "peerDependenciesMeta": { "@ston-fi/omniston-sdk": { "optional": true + }, + "@tonappchain/sdk": { + "optional": true } }, "optionalDependencies": { @@ -134,6 +151,7 @@ "@stryker-mutator/core": "^9.6.1", "@ton/core": "catalog:", "@ton/crypto": "catalog:", + "@tonappchain/sdk": "catalog:", "@types/chrome": "^0.1.40", "@types/jest": "^30.0.0", "@types/webextension-polyfill": "^0.12.4", diff --git a/packages/walletkit/src/api/interfaces/CrossChainManagerAPI.ts b/packages/walletkit/src/api/interfaces/CrossChainManagerAPI.ts new file mode 100644 index 000000000..e95f9b058 --- /dev/null +++ b/packages/walletkit/src/api/interfaces/CrossChainManagerAPI.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { ProviderInput } from '../../types'; +import type { ProviderFactoryContext } from '../../types/factory'; +import type { CrossChainProvider } from '../../cross-chain/CrossChainProvider'; + +/** + * Cross-chain API interface exposed by CrossChainManager + */ +export interface CrossChainManagerAPI { + createFactoryContext(): ProviderFactoryContext; + /** + * Register a new provider. If a provider with the same id is already registered, it is replaced. + * @param provider Provider instance or factory (must produce a provider with providerId) + */ + registerProvider(provider: ProviderInput): void; + + /** + * Remove a previously registered provider. No-op if the provider was not registered. + * @param provider Provider instance to remove (matched by providerId) + */ + removeProvider(provider: CrossChainProvider): void; + + /** + * Get a registered provider + * @param providerId Provider identifier (optional, returns default if not specified) + */ + getProvider(providerId?: string): CrossChainProvider; + + /** + * Get all registered providers. + * The returned array keeps a stable reference until the provider list changes. + */ + getProviders(): CrossChainProvider[]; + + /** + * Check if a provider is registered + * @param providerId Provider identifier + */ + hasProvider(providerId: string): boolean; +} diff --git a/packages/walletkit/src/api/interfaces/index.ts b/packages/walletkit/src/api/interfaces/index.ts index cdaca3627..d03b60954 100644 --- a/packages/walletkit/src/api/interfaces/index.ts +++ b/packages/walletkit/src/api/interfaces/index.ts @@ -15,6 +15,8 @@ export type { DefiManagerAPI } from './DefiManagerAPI'; export type { DefiProvider } from './DefiProvider'; export type { SwapAPI, SwapProviderInterface } from './SwapAPI'; export type { StakingAPI, StakingProviderInterface } from './StakingAPI'; +export type { CrossChainProvider } from '../../cross-chain/CrossChainProvider'; +export type { CrossChainManagerAPI } from './CrossChainManagerAPI'; export type { TONConnectSessionManager } from './TONConnectSessionManager'; diff --git a/packages/walletkit/src/api/models/cross-chain/CrossChainSmartAccountParams.ts b/packages/walletkit/src/api/models/cross-chain/CrossChainSmartAccountParams.ts new file mode 100644 index 000000000..72431d72b --- /dev/null +++ b/packages/walletkit/src/api/models/cross-chain/CrossChainSmartAccountParams.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export type CrossChainSmartAccountParams = { + userAddress: string; + applicationAddress: string; +}; diff --git a/packages/walletkit/src/api/models/cross-chain/CrossChainTransactionParams.ts b/packages/walletkit/src/api/models/cross-chain/CrossChainTransactionParams.ts new file mode 100644 index 000000000..10420202f --- /dev/null +++ b/packages/walletkit/src/api/models/cross-chain/CrossChainTransactionParams.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export type CrossChainTransactionParams = T; diff --git a/packages/walletkit/src/api/models/index.ts b/packages/walletkit/src/api/models/index.ts index 2f9cba702..1737d9cdc 100644 --- a/packages/walletkit/src/api/models/index.ts +++ b/packages/walletkit/src/api/models/index.ts @@ -175,3 +175,6 @@ export type { TransactionsUpdate } from './streaming/TransactionsUpdate'; export type { JettonUpdate } from './streaming/JettonUpdate'; export type { StreamingUpdate } from './streaming/StreamingUpdate'; export type { StreamingEvents } from './streaming/StreamingEvents'; + +// Cross-chain models +export type { CrossChainSmartAccountParams } from './cross-chain/CrossChainSmartAccountParams'; diff --git a/packages/walletkit/src/cross-chain/CrossChainManager.ts b/packages/walletkit/src/cross-chain/CrossChainManager.ts new file mode 100644 index 000000000..90190e8d7 --- /dev/null +++ b/packages/walletkit/src/cross-chain/CrossChainManager.ts @@ -0,0 +1,121 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { SharedKitEvents } from '../types/emitter'; +import type { ProviderFactoryContext, ProviderInput } from '../types/factory'; +import { resolveProvider } from '../types'; +import type { CrossChainManagerAPI, CrossChainProvider } from '../api/interfaces'; +import type { EventEmitter } from '../core/EventEmitter'; +import { CrossChainError } from './errors'; +import { CrossChainErrorCode } from './errors'; +import { globalLogger } from '../core/Logger'; + +const log = globalLogger.createChild('CrossChainManager'); + +/** + * CrossChainManager - manages cross-chain providers and delegates cross-chain operations + * + * Allows registration of multiple cross-chain providers and provides a unified API + * for cross-chain operations. + */ +export class CrossChainManager implements CrossChainManagerAPI { + public createFactoryContext: () => ProviderFactoryContext; + + protected providers: CrossChainProvider[] = []; + protected eventEmitter: EventEmitter; + + constructor(createFactoryContext: () => ProviderFactoryContext) { + this.createFactoryContext = createFactoryContext; + this.eventEmitter = createFactoryContext().eventEmitter; + } + + protected createError(message: string, code: string, details?: unknown) { + log.error(message, { code, details }); + return new CrossChainError(message, code as CrossChainErrorCode, details); + } + + /** + * Register a provider. If another provider with the same id is already registered, + * it is removed first and replaced by the new instance. Emits `provider:registered`. + * @param {ProviderInput} input - Provider instance or factory that produces one + * @throws {CrossChainError} if the resolved provider has no providerId + */ + registerProvider(input: ProviderInput): void { + const provider = resolveProvider(input, this.createFactoryContext()); + const providerId = provider.providerId; + + if (!providerId) { + throw this.createError('Provider must have a providerId', CrossChainErrorCode.InvalidProvider); + } + + const oldProvider = this.providers.find((p) => p.providerId === providerId); + if (oldProvider) { + this.removeProvider(oldProvider); + } + + this.providers = [...this.providers, provider]; + + this.eventEmitter.emit('provider:registered', { providerId, type: provider.type }, 'cross-chain-manager'); + } + + /** + * Remove a previously registered provider. No-op if the provider is not registered. + * The provider is matched by its `providerId`, so any instance with the same id will match. + * @param {CrossChainProvider} provider - Provider instance to remove + */ + removeProvider(provider: CrossChainProvider): void { + const oldProvider = this.providers.find((p) => p.providerId === provider.providerId); + + if (oldProvider) { + this.providers = this.providers.filter((p) => p !== oldProvider); + } + } + + /** + * Get a provider by name, or the default provider + * @param {string} providerId - Optional provider name + * @returns {CrossChainProvider} Provider instance + * @throws {CrossChainError} if provider not found or no default set + */ + getProvider(providerId: string): CrossChainProvider { + if (!providerId) { + throw this.createError( + 'No default provider set. Register a provider first.', + CrossChainErrorCode.NoDefaultProvider, + ); + } + + const provider = this.providers.find((p) => p.providerId === providerId); + if (!provider) { + throw this.createError(`Provider '${providerId}' not found`, CrossChainErrorCode.ProviderNotFound, { + provider: providerId, + registered: this.providers.map((p) => p.providerId), + }); + } + + return provider; + } + + /** + * Get all registered providers. The returned array keeps a stable reference + * until the provider list changes, so it can be safely used with React + * subscription APIs like `useSyncExternalStore`. + */ + getProviders(): CrossChainProvider[] { + return this.providers; + } + + /** + * Check if a provider is registered + * @param {string} providerId - Provider id + * @returns {boolean} true if provider exists + */ + hasProvider(providerId: string): boolean { + return this.providers.some((p) => p.providerId === providerId); + } +} diff --git a/packages/walletkit/src/cross-chain/CrossChainProvider.ts b/packages/walletkit/src/cross-chain/CrossChainProvider.ts new file mode 100644 index 000000000..753c10843 --- /dev/null +++ b/packages/walletkit/src/cross-chain/CrossChainProvider.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { ApiClient } from '../api/interfaces'; +import type { CrossChainTransactionParams } from '../api/models/cross-chain/CrossChainTransactionParams'; +import type { BaseProvider, TransactionRequest, TransactionStatusResponse } from '../api/models'; + +/** + * Abstract interface for cross-chain providers + * + * Provides a common interface for implementing cross-chain functionality + * across different protocols. + * + * @example + * ```typescript + * class MyCrossChainProvider implements CrossChainProvider { + * async buildCrossChainTransaction(parameters: CrossChainTransactionParams): Promise { + * // ... + * } + * + * async getSmartAccountAddress(walletAddress: string, applicationAddress: string): Promise { + * // ... + * } + * } + * ``` + */ +export interface CrossChainProvider extends BaseProvider { + type: 'cross-chain'; + + /** + * Unique identifier for the provider + */ + providerId: string; + + /** + * Build a transaction for executing a cross-chain operation + * @param {CrossChainTransactionParams} parameters - Parameters for the cross-chain transaction + * @returns {Promise} Promise resolving to transaction request + */ + buildCrossChainTransaction: (parameters: CrossChainTransactionParams) => Promise; + + /** + * Get the smart account address for a given wallet and application + * @param {string} walletAddress - The user's wallet address + * @param {string} applicationAddress - The application address + * @returns {Promise} Promise resolving to the smart account address + */ + getSmartAccountAddress: (walletAddress: string, applicationAddress: string) => Promise; + + /** + * Get the status of a cross-chain transaction + * @param {string} transactionHash - The hash of the transaction + * @param {ApiClient} [client] - Optional API client + * @returns {Promise} Promise resolving to the transaction status + */ + getTransactionStatus: (transactionHash: string, client?: ApiClient) => Promise; +} diff --git a/packages/walletkit/src/cross-chain/errors.ts b/packages/walletkit/src/cross-chain/errors.ts new file mode 100644 index 000000000..f72e24c02 --- /dev/null +++ b/packages/walletkit/src/cross-chain/errors.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export enum CrossChainErrorCode { + ProviderNotFound = 'PROVIDER_NOT_FOUND', + NetworkError = 'NETWORK_ERROR', + UnsupportedNetwork = 'UNSUPPORTED_NETWORK', + InvalidParams = 'INVALID_PARAMS', + InvalidProvider = 'INVALID_PROVIDER', + NoDefaultProvider = 'NO_DEFAULT_PROVIDER', +} + +export class CrossChainError extends Error { + public readonly code: string; + public readonly details?: unknown; + + constructor(message: string, code: CrossChainErrorCode, details?: unknown) { + super(message); + this.name = 'CrossChainError'; + this.code = code; + this.details = details; + } +} diff --git a/packages/walletkit/src/cross-chain/index.ts b/packages/walletkit/src/cross-chain/index.ts new file mode 100644 index 000000000..99a2b68f4 --- /dev/null +++ b/packages/walletkit/src/cross-chain/index.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export { CrossChainManager } from './CrossChainManager'; +export { CrossChainError, CrossChainErrorCode } from './errors'; diff --git a/packages/walletkit/src/cross-chain/tac/TacCrossChainProvider.ts b/packages/walletkit/src/cross-chain/tac/TacCrossChainProvider.ts new file mode 100644 index 000000000..ee230f4a0 --- /dev/null +++ b/packages/walletkit/src/cross-chain/tac/TacCrossChainProvider.ts @@ -0,0 +1,178 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { AssetLike, EvmProxyMsg } from '@tonappchain/sdk'; +import { Network as TacSdkNetwork, TacSdk } from '@tonappchain/sdk'; + +import type { ApiClient, CrossChainProvider } from '../../api/interfaces'; +import type { Base64String, TransactionRequest, TransactionStatusResponse } from '../../api/models'; +import { Network } from '../../api/models'; +import { CrossChainError, CrossChainErrorCode } from '../errors'; +import type { TacCrossChainProviderConfig } from './TacCrossChainProviderConfig'; +import type { TacCrossChainTransactionParams } from './TacCrossChainTransactionParams'; +import { getTransactionStatus } from '../../utils'; +import type { NetworkManager } from '../../core/NetworkManager'; +import type { ProviderFactoryContext } from '../../types/factory'; + +/** + * TacCrossChainProvider - implementation of CrossChainProvider for TAC (TON Application Chain) + * + * This provider should only be created via the {@link createTacProvider()} function. + * + * @example + * ```typescript + * const tacProvider = createTacProvider(); + * + * new AppKit({ + * networks: { ... }, + * connectors: [ ... ], + * providers: [ tacProvider ], + * }); + * ``` + */ +export class TacCrossChainProvider implements CrossChainProvider { + readonly type = 'cross-chain'; + readonly providerId = 'tac'; + readonly network: Network; + private readonly networkManager: NetworkManager; + private readonly config: TacCrossChainProviderConfig; + + sdk: TacSdk | undefined; + private sdkPromise: Promise | undefined; + + constructor(networkManager: NetworkManager, config?: TacCrossChainProviderConfig, sdk?: TacSdk) { + this.networkManager = networkManager; + this.config = config || {}; + this.network = config?.network || Network.mainnet(); + this.sdk = sdk; + } + + private async getSdk(): Promise { + if (this.sdk) { + return this.sdk; + } + + if (!this.sdkPromise) { + this.sdkPromise = TacSdk.create({ + ...(this.config.sdkConfig || {}), + network: TacCrossChainProvider.getTacSdkNetworkByTonNetwork(this.config?.network || Network.mainnet()), + }).then((sdk) => { + this.sdk = sdk; + return sdk; + }); + } + + return this.sdkPromise; + } + + static getTacSdkNetworkByTonNetwork(tonNetwork: Network): TacSdkNetwork { + switch (tonNetwork.chainId) { + case Network.mainnet().chainId: + return TacSdkNetwork.MAINNET; + case Network.testnet().chainId: + return TacSdkNetwork.TESTNET; + default: + throw new CrossChainError( + `TacCrossChainProvider does not support chain ${tonNetwork.chainId}`, + CrossChainErrorCode.UnsupportedNetwork, + { network: tonNetwork }, + ); + } + } + + static async create(networkManager: NetworkManager, config: TacCrossChainProviderConfig) { + const sdkInstance = await TacSdk.create({ + ...config.sdkConfig, + network: this.getTacSdkNetworkByTonNetwork(config.network || Network.mainnet()), + }); + + return new TacCrossChainProvider(networkManager, config, sdkInstance); + } + + static createFromContext(ctx: ProviderFactoryContext, config?: TacCrossChainProviderConfig) { + const networkManager = ctx.networkManager; + return new TacCrossChainProvider(networkManager, config); + } + + /** + * Get supported networks for this provider + * @returns {Network[]} Array of networks supported by this provider + */ + getSupportedNetworks(): Network[] { + return [this.network]; + } + + private getApiClient(network?: Network): ApiClient { + const targetNetwork = network ?? this.network; + return this.networkManager.getClient(targetNetwork); + } + + /** + * Get the smart account address for a given wallet and application + * @param {string} walletAddress - The user's wallet address + * @param {string} applicationAddress - The application address + * @returns {Promise} Promise resolving to the smart account address + */ + async getSmartAccountAddress(walletAddress: string, applicationAddress: string): Promise { + const sdk = await this.getSdk(); + return sdk.getSmartAccountAddressForTvmWallet(walletAddress, applicationAddress); + } + + /** + * Get the status of a TON transaction + * @param {string} transactionHash - The hash of the transaction + * @param {ApiClient} [client] - Optional API client + * @returns {Promise} Promise resolving to the transaction status + */ + async getTransactionStatus(transactionHash: string, client?: ApiClient): Promise { + return await getTransactionStatus(client ?? this.getApiClient(this.network), { + normalizedHash: transactionHash, + }); + } + + /** + * Build a transaction for executing a cross-chain operation + * @param {TacCrossChainTransactionParams} parameters - Parameters for the cross-chain transaction + * @returns {Promise} Promise resolving to transaction request + */ + async buildCrossChainTransaction( + parameters: TacCrossChainTransactionParams, + ): Promise { + const sdk = await this.getSdk(); + const network = this.getSupportedNetworks()?.[0]; + if (!network) { + throw new CrossChainError('No supported networks configured', CrossChainErrorCode.InvalidProvider); + } + + const results = await sdk.prepareCrossChainTransactionPayload( + parameters.message, + parameters.senderAddress, + parameters.assets, + parameters.options || undefined, + ); + + const messages = results.map((result) => ({ + address: result.destinationAddress, + amount: result.tonAmount.toString(), + payload: result.body.toBoc().toString('base64') as Base64String, + })); + + return { messages, network } as TransactionRequest; + } +} + +/** + * Creates a TAC cross-chain provider factory + * @param {TacCrossChainProviderConfig} [config] - Optional configuration for the TAC provider + * @returns {(ctx: ProviderFactoryContext) => TacCrossChainProvider} A function that takes a ProviderFactoryContext and returns a TacCrossChainProvider instance + */ +export const createTacProvider = ( + config?: TacCrossChainProviderConfig, +): ((ctx: ProviderFactoryContext) => TacCrossChainProvider) => { + return (ctx) => TacCrossChainProvider.createFromContext(ctx, config); +}; diff --git a/packages/walletkit/src/cross-chain/tac/TacCrossChainProviderConfig.ts b/packages/walletkit/src/cross-chain/tac/TacCrossChainProviderConfig.ts new file mode 100644 index 000000000..eede3e383 --- /dev/null +++ b/packages/walletkit/src/cross-chain/tac/TacCrossChainProviderConfig.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import type { SDKParams } from '@tonappchain/sdk'; + +import type { Network } from '../../api/models'; + +/** + * Configuration for the TAC cross-chain provider + */ +export interface TacCrossChainProviderConfig { + /** + * The network to use (mainnet or testnet) + */ + network?: Network; + /** + * Optional configuration for the TAC SDK + */ + sdkConfig?: SDKParams; +} diff --git a/packages/walletkit/src/cross-chain/tac/TacCrossChainTransactionParams.ts b/packages/walletkit/src/cross-chain/tac/TacCrossChainTransactionParams.ts new file mode 100644 index 000000000..f0f16c4d1 --- /dev/null +++ b/packages/walletkit/src/cross-chain/tac/TacCrossChainTransactionParams.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +/** + * Parameters for a TAC cross-chain transaction + * @template {any} T - The type of a cross-chain message + * @template {any[]} A - The type of the assets array + * @template {any} O - The type of the options + */ +export type TacCrossChainTransactionParams = { + /** + * The address of the sender + */ + senderAddress: string; + /** + * The message to be used for execution on the destination chain + */ + message: T; + /** + * Optional assets to be transferred + */ + assets?: A; + /** + * Optional execution options + */ + options?: O; +}; diff --git a/packages/walletkit/src/cross-chain/tac/index.ts b/packages/walletkit/src/cross-chain/tac/index.ts new file mode 100644 index 000000000..baa022a2b --- /dev/null +++ b/packages/walletkit/src/cross-chain/tac/index.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export * from './TacCrossChainProvider'; +export * from './TacCrossChainProviderConfig'; +export * from './TacCrossChainTransactionParams'; diff --git a/packages/walletkit/src/index.ts b/packages/walletkit/src/index.ts index 605d94e49..10f055a47 100644 --- a/packages/walletkit/src/index.ts +++ b/packages/walletkit/src/index.ts @@ -21,6 +21,7 @@ export { Initializer } from './core/Initializer'; export { JettonsManager } from './core/JettonsManager'; export { DefiError, DefiErrorCode } from './defi/errors'; export { SwapManager, SwapProvider, SwapError, SwapErrorCode } from './defi/swap'; +export { CrossChainManager, CrossChainError, CrossChainErrorCode } from './cross-chain'; export { StakingManager, StakingProvider, StakingError, StakingErrorCode } from './defi/staking'; export { EventEmitter } from './core/EventEmitter'; export type { EventListener, EventPayload, KitEvent } from './core/EventEmitter'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eadb0f3d8..02f332f7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,21 +18,24 @@ catalogs: '@ton/crypto': specifier: ^3.3.0 version: 3.3.0 + '@tonappchain/sdk': + specifier: 0.7.2 + version: 0.7.2 '@tonconnect/bridge-sdk': specifier: ^0.2.8 version: 0.2.8 '@tonconnect/protocol': - specifier: ^2.5.0-alpha.0 + specifier: ^2.5.0-alpha.1 version: 2.5.0-alpha.1 '@tonconnect/sdk': - specifier: ^3.5.0-alpha.0 + specifier: ^3.5.0-alpha.1 version: 3.5.0-alpha.1 '@tonconnect/ui': - specifier: ^2.5.0-alpha.0 - version: 2.5.0-alpha.0 + specifier: ^2.5.0-alpha.1 + version: 2.5.0-alpha.1 '@tonconnect/ui-react': - specifier: ^2.5.0-alpha.0 - version: 2.5.0-alpha.0 + specifier: ^2.5.0-alpha.1 + version: 2.5.0-alpha.1 '@types/react': specifier: 19.2.3 version: 19.2.3 @@ -139,7 +142,7 @@ importers: version: 3.5.0-alpha.1 '@tonconnect/ui-react': specifier: 'catalog:' - version: 2.5.0-alpha.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.5.0-alpha.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) buffer: specifier: 'catalog:' version: 6.0.3 @@ -351,10 +354,10 @@ importers: version: 3.5.0-alpha.1 '@tonconnect/ui': specifier: 'catalog:' - version: 2.5.0-alpha.0 + version: 2.5.0-alpha.1 '@tonconnect/ui-react': specifier: 'catalog:' - version: 2.5.0-alpha.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.5.0-alpha.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@types/react': specifier: 'catalog:' version: 19.2.3 @@ -484,7 +487,7 @@ importers: version: 0.63.1(@ton/crypto@3.3.0) '@tonconnect/ui': specifier: 'catalog:' - version: 2.5.0-alpha.0 + version: 2.5.0-alpha.1 typescript: specifier: 'catalog:' version: 5.9.3 @@ -527,7 +530,7 @@ importers: version: 5.100.14(react@19.2.3) '@tonconnect/ui-react': specifier: 'catalog:' - version: 2.5.0-alpha.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.5.0-alpha.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@types/react': specifier: 'catalog:' version: 19.2.3 @@ -644,6 +647,9 @@ importers: '@ton/crypto': specifier: 'catalog:' version: 3.3.0 + '@tonappchain/sdk': + specifier: 'catalog:' + version: 0.7.2(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0)(@ton/ton@15.4.0(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0))(@tonconnect/ui@2.5.0-alpha.1)(ethers@6.16.0)(ton-crypto@3.2.0) '@types/chrome': specifier: ^0.1.40 version: 0.1.42 @@ -770,6 +776,9 @@ packages: '@adobe/css-tools@4.5.0': resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==} + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@apidevtools/json-schema-ref-parser@14.0.1': resolution: {integrity: sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==} engines: {node: '>= 16'} @@ -786,6 +795,17 @@ packages: peerDependencies: openapi-types: '>=7' + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/types@3.973.9': + resolution: {integrity: sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==} + engines: {node: '>=20.0.0'} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1105,6 +1125,10 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1872,10 +1896,20 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.9.7': resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} engines: {node: ^14.21.3 || >=16} + '@noble/ed25519@1.7.5': + resolution: {integrity: sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -1896,6 +1930,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@orbs-network/ton-access@2.3.3': + resolution: {integrity: sha512-b1miCPts7wBG9JKYgzXIRZQm/LMy5Uk1mNK8NzlcXHL3HRHJkkFbuYJGuj3IkWCiIicW3Ipp4sYnn3Fwo4oB0g==} + '@oxc-parser/binding-android-arm-eabi@0.127.0': resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3160,6 +3197,22 @@ packages: '@sinonjs/fake-timers@15.4.0': resolution: {integrity: sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==} + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/types@4.14.2': + resolution: {integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -3434,10 +3487,30 @@ packages: '@ton/crypto@3.3.0': resolution: {integrity: sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA==} + '@ton/ton@15.4.0': + resolution: {integrity: sha512-f19y2Rez88KZK+lv3CT3ghXi07LcToJtJhlgRSfK+3GzjdIcoW/wbmXG1ffi6fkc8W2LO5z6Q3gZaIEvNGnz6w==} + peerDependencies: + '@ton/core': '>=0.62.0 <1.0.0' + '@ton/crypto': '>=3.2.0' + '@ton/toolchain@https://codeload.github.com/the-ton-tech/toolchain/tar.gz/17345d74225d1afa01a21981e16dd3dfd8b72d2b': - resolution: {gitHosted: true, integrity: sha512-8mZs2Vkvpq8Ze9UqLOUzK/FZ7+QGFQqrFe2XlpO86HXVlz1jW3NFwvyWzKNqvLGHg208eP10zeUXmGBFERKQkw==, tarball: https://codeload.github.com/the-ton-tech/toolchain/tar.gz/17345d74225d1afa01a21981e16dd3dfd8b72d2b} + resolution: {gitHosted: true, tarball: https://codeload.github.com/the-ton-tech/toolchain/tar.gz/17345d74225d1afa01a21981e16dd3dfd8b72d2b} version: 1.7.0 + '@tonappchain/adnl@1.0.4': + resolution: {integrity: sha512-0qd25AJsoxXeJ0R5xhv8rLKQ/lWxfuBIaIsSRV79v0r1LpJw/YwHX8TJWaTOhWlJja2xCPpLC8dJwa+je5w4wg==} + + '@tonappchain/sdk@0.7.2': + resolution: {integrity: sha512-TqhEWOLgxAuK2qvCTpEx8fFEQ2a6SzRXL6Uyjd/X334F5UMkq8ojgK+6AULq7wspDAkol7Q0upnppIfqnD8f0A==} + peerDependencies: + '@ton/ton': '>=15' + '@tonconnect/ui': '>=2' + ethers: '>=6' + ton-crypto: '>=3' + + '@tonappchain/ton-lite-client@3.0.6': + resolution: {integrity: sha512-euXQCF1gYRCZt470Ek8I+mzNYQFquSoEay5P8bZDhZW53zVSnM36yFFexeCCEUGdiN8EJa1oOq9i9x32GZsmQQ==} + '@tonconnect/bridge-sdk@0.2.8': resolution: {integrity: sha512-bii7xs8+jeoBCXQM/VTA83EWGVnDhURrxI9YPGR3RQdSoA+EcxEiX2AGW6god3Ar8mk989eMXRCxcAVLGGHeLw==} @@ -3450,23 +3523,17 @@ packages: '@tonconnect/protocol@2.4.0': resolution: {integrity: sha512-3xg6sMWIrSgW7/f7iPgOb2BI3LaMScjDMqfu20fcEMbOVvNFk3TGAUKK5cJ3pfvUINsyLgPoylcIbPap37jXiA==} - '@tonconnect/protocol@2.5.0-alpha.0': - resolution: {integrity: sha512-9cUWsCkM53bYlqxEvohj0Ks1Zb6huZvJnCFQIPswzwQVlW1tySIuElU4Ei2WC471V8TngkvT4WDOnuEPsyjbvA==} - '@tonconnect/protocol@2.5.0-alpha.1': resolution: {integrity: sha512-9rMmSMvhLpvFovVUIjEK2Vmf8EH7Lob4S/B7nheM0QEooM/fd0FHTFk6ovBtYANu0IQ0QNMTsrGQ5s5KpKCwHQ==} '@tonconnect/sdk@3.4.1': resolution: {integrity: sha512-eVH8erAFout89gXYHXua/es+mmLPiW1r7ng9hgHKYQv85HLq8/zzQEkbJpbTlnIuQ6CJ/QKchjMsIgYz3BYCUQ==} - '@tonconnect/sdk@3.5.0-alpha.0': - resolution: {integrity: sha512-N6nvinZeIapIKO7P1fY0thfHVY8oLV5wcaqiM3XvskYJ9+29KqH/li5v8wliHisecHF209OTghFiLjEVgHTBOA==} - '@tonconnect/sdk@3.5.0-alpha.1': resolution: {integrity: sha512-VE7c1ot4+wteTOV385G1GmEztZzvV9IEPD17jc84QGmHlGqvyTfmpD6ggRmzjO66zL+3v7yer+g9IIURcKrdMw==} - '@tonconnect/ui-react@2.5.0-alpha.0': - resolution: {integrity: sha512-N1c67Yoq7POrYmrOuyMC42/w00GmQJnioNZgBwt6xnhHIVaRqZ88IpdIxX7MImDstPb+K8sKUaQob5T/vl4jaQ==} + '@tonconnect/ui-react@2.5.0-alpha.1': + resolution: {integrity: sha512-iEKKfaOWQBsA5R0UzOPn3u9kPUJps8ezclsIvSumYFqt9eer4PTSYQV2wuTuHw08LnWhvI3aDfVSwopx8VmrnA==} peerDependencies: react: '>=17.0.0' react-dom: '>=17.0.0' @@ -3474,8 +3541,8 @@ packages: '@tonconnect/ui@2.4.4': resolution: {integrity: sha512-XgIHAkdimDk+YeRDPsQp7eOz2lM4aScYL3hiTP1Z9YgWRVROjEqTbw5ZP9pt6rgmYTzL26QpqhI6uNTFdYNFIA==} - '@tonconnect/ui@2.5.0-alpha.0': - resolution: {integrity: sha512-kQi8H2+RzD2VWv0UvdygJUNG2E6TYUNwAJOg47744/cGkvZLAYossye+6cp1ljBL24iN+ZhErrtk4Moqc0wRNA==} + '@tonconnect/ui@2.5.0-alpha.1': + resolution: {integrity: sha512-Oc7rSM8n1xAj86Qke35+FJO+3FnmHH4yaBOMK/QMGPXajKaQ/PcQ9Aa4fUsBQJ1/ICaULCBM+UUmrDE0b2PkyQ==} '@truecarry/vite-plugin-web-extension@4.5.1': resolution: {integrity: sha512-WSramCYE+wVFH/zQdBhaBP5gSd9pldyjOu+jvkaTEFXwzCDbNQJ+34ke4/XDsaohpcQTe+lbVXbUT+Jt4Ni9Jw==} @@ -3544,6 +3611,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/bn.js@5.2.0': + resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -3598,9 +3668,15 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/node@25.9.1': resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + '@types/pegjs@0.10.6': + resolution: {integrity: sha512-eLYXDbZWXh2uxf+w8sXS8d6KSoXTswfps6fvCUuVAGN8eRpfe7h9eSRydxiSJvo9Bf+GzifsDOr9TMQlmJdmkw==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -3941,6 +4017,16 @@ packages: resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==} engines: {node: '>=12.0'} + aes-js@3.1.2: + resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@9.0.0: resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==} engines: {node: '>= 20'} @@ -4099,6 +4185,9 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -4110,6 +4199,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} + babel-jest@30.4.1: resolution: {integrity: sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -4166,6 +4258,9 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + bn.js@5.2.3: + resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} @@ -4262,6 +4357,9 @@ packages: caniuse-lite@1.0.30001793: resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + case-shift@2.5.3: + resolution: {integrity: sha512-6SdS9W5xu82Kj1Z6f14h0zsbWTdXGtD0RftPNnqbAFFqqlzX1SMFi1E1NDIBg5LC2m9EYWWPUV80nTb3iu2e6Q==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -4328,6 +4426,10 @@ packages: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -4357,6 +4459,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@14.0.3: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} @@ -4428,6 +4534,11 @@ packages: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -4471,6 +4582,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dataloader@2.2.3: + resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} + dayjs@1.11.20: resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} @@ -4553,6 +4667,10 @@ packages: defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -4630,6 +4748,10 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@17.4.2: resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} @@ -4890,6 +5012,10 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + ethers@6.16.0: + resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==} + engines: {node: '>=14.0.0'} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -5038,6 +5164,15 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -5046,6 +5181,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -5281,6 +5420,10 @@ packages: http2-client@1.3.5: resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@9.0.0: resolution: {integrity: sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==} engines: {node: '>= 20'} @@ -5581,6 +5724,9 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + isomorphic-fetch@3.0.0: + resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + isomorphic-ws@5.0.0: resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: @@ -5966,6 +6112,9 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru_map@0.4.1: + resolution: {integrity: sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==} + lucide-react@0.562.0: resolution: {integrity: sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==} peerDependencies: @@ -6020,10 +6169,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} @@ -6421,6 +6578,11 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + pegjs@0.10.0: + resolution: {integrity: sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow==} + engines: {node: '>=0.10'} + hasBin: true + perfect-debounce@2.1.0: resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} @@ -6544,6 +6706,10 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -7151,6 +7317,9 @@ packages: resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} hasBin: true + symbol.inspect@1.0.1: + resolution: {integrity: sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==} + synckit@0.11.12: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7256,6 +7425,15 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + ton-crypto-primitives@2.0.0: + resolution: {integrity: sha512-K+qKjpS0h9sPW6oExcpxnzuQ7nEgHEiDKwIqE/jWD25o8iFGe3FWj1gKxFNbKE9wwYKc5IV8FwrU+raF0KO5nQ==} + + ton-crypto@3.2.0: + resolution: {integrity: sha512-fltdBNQ45gARMuGMEOjPZWPJ5eSql8p3CA0Dj7tPv5lhU5ziT8SxXLAzDraR9HJ8YpjBHLVvYyhMLRiEwxgtMQ==} + + ton-tl@1.0.1: + resolution: {integrity: sha512-dAHJSWEW0CRNm/sdWVhola9/OZc/yHmLOXlSNr9I6l0WaVZmGhwkmDuzvMm1ZJ3Dvhf5tYN+iAUSSgmf8Q+P0g==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -7334,6 +7512,9 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -7454,6 +7635,9 @@ packages: underscore@1.13.8: resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} @@ -7720,6 +7904,9 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} @@ -7935,6 +8122,8 @@ snapshots: '@adobe/css-tools@4.5.0': {} + '@adraffy/ens-normalize@1.10.1': {} + '@apidevtools/json-schema-ref-parser@14.0.1': dependencies: '@types/json-schema': 7.0.15 @@ -7954,6 +8143,23 @@ snapshots: call-me-maybe: 1.0.2 openapi-types: 12.1.3 + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.9 + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.9 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/types@3.973.9': + dependencies: + '@smithy/types': 4.14.2 + tslib: 2.8.1 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -8402,6 +8608,9 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 + '@colors/colors@1.5.0': + optional: true + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -9192,10 +9401,18 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + '@noble/curves@1.9.7': dependencies: '@noble/hashes': 1.8.0 + '@noble/ed25519@1.7.5': {} + + '@noble/hashes@1.3.2': {} + '@noble/hashes@1.8.0': {} '@noble/hashes@2.2.0': {} @@ -9212,6 +9429,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@orbs-network/ton-access@2.3.3': + dependencies: + isomorphic-fetch: 3.0.0 + transitivePeerDependencies: + - encoding + '@oxc-parser/binding-android-arm-eabi@0.127.0': optional: true @@ -10297,6 +10520,24 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/types@4.14.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + '@standard-schema/spec@1.1.0': {} '@ston-fi/omniston-sdk@0.7.9': @@ -10635,6 +10876,19 @@ snapshots: jssha: 3.2.0 tweetnacl: 1.0.3 + '@ton/ton@15.4.0(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0)': + dependencies: + '@ton/core': 0.63.1(@ton/crypto@3.3.0) + '@ton/crypto': 3.3.0 + axios: 1.16.1 + dataloader: 2.2.3 + symbol.inspect: 1.0.1 + teslabot: 1.5.0 + zod: 3.25.76 + transitivePeerDependencies: + - debug + - supports-color + '@ton/toolchain@https://codeload.github.com/the-ton-tech/toolchain/tar.gz/17345d74225d1afa01a21981e16dd3dfd8b72d2b(jest@30.4.2(@types/node@25.9.1)(node-notifier@10.0.1))(jiti@2.7.0)(typescript@6.0.3)': dependencies: '@eslint/js': 9.39.4 @@ -10656,6 +10910,57 @@ snapshots: - supports-color - typescript + '@tonappchain/adnl@1.0.4': + dependencies: + '@noble/ed25519': 1.7.5 + '@noble/hashes': 1.8.0 + aes-js: 3.1.2 + buffer: 6.0.3 + events: 3.3.0 + isomorphic-ws: 5.0.0(ws@8.21.0) + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tonappchain/sdk@0.7.2(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0)(@ton/ton@15.4.0(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0))(@tonconnect/ui@2.5.0-alpha.1)(ethers@6.16.0)(ton-crypto@3.2.0)': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@orbs-network/ton-access': 2.3.3 + '@ton/ton': 15.4.0(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0) + '@tonappchain/ton-lite-client': 3.0.6(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0) + '@tonconnect/ui': 2.5.0-alpha.1 + bn.js: 5.2.3 + cli-table3: 0.6.5 + dotenv: 16.6.1 + ethers: 6.16.0 + ton-crypto: 3.2.0 + transitivePeerDependencies: + - '@ton/core' + - '@ton/crypto' + - bufferutil + - debug + - encoding + - supports-color + - utf-8-validate + + '@tonappchain/ton-lite-client@3.0.6(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0)': + dependencies: + '@ton/ton': 15.4.0(@ton/core@0.63.1(@ton/crypto@3.3.0))(@ton/crypto@3.3.0) + '@tonappchain/adnl': 1.0.4 + dataloader: 2.2.3 + lru_map: 0.4.1 + teslabot: 1.5.0 + ton-tl: 1.0.1 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - '@ton/core' + - '@ton/crypto' + - bufferutil + - debug + - supports-color + - utf-8-validate + '@tonconnect/bridge-sdk@0.2.8': dependencies: '@tonconnect/isomorphic-eventsource': 0.0.2 @@ -10681,11 +10986,6 @@ snapshots: tweetnacl: 1.0.3 tweetnacl-util: 0.15.1 - '@tonconnect/protocol@2.5.0-alpha.0': - dependencies: - tweetnacl: 1.0.3 - tweetnacl-util: 0.15.1 - '@tonconnect/protocol@2.5.0-alpha.1': dependencies: tweetnacl: 1.0.3 @@ -10699,14 +10999,6 @@ snapshots: transitivePeerDependencies: - encoding - '@tonconnect/sdk@3.5.0-alpha.0': - dependencies: - '@tonconnect/isomorphic-eventsource': 0.0.2 - '@tonconnect/isomorphic-fetch': 0.0.3 - '@tonconnect/protocol': 2.5.0-alpha.0 - transitivePeerDependencies: - - encoding - '@tonconnect/sdk@3.5.0-alpha.1': dependencies: '@tonconnect/isomorphic-eventsource': 0.0.2 @@ -10715,9 +11007,9 @@ snapshots: transitivePeerDependencies: - encoding - '@tonconnect/ui-react@2.5.0-alpha.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tonconnect/ui-react@2.5.0-alpha.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tonconnect/ui': 2.5.0-alpha.0 + '@tonconnect/ui': 2.5.0-alpha.1 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: @@ -10733,9 +11025,9 @@ snapshots: transitivePeerDependencies: - encoding - '@tonconnect/ui@2.5.0-alpha.0': + '@tonconnect/ui@2.5.0-alpha.1': dependencies: - '@tonconnect/sdk': 3.5.0-alpha.0 + '@tonconnect/sdk': 3.5.0-alpha.1 classnames: 2.5.1 csstype: 3.2.3 deepmerge: 4.3.1 @@ -10833,6 +11125,10 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@types/bn.js@5.2.0': + dependencies: + '@types/node': 25.9.1 + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -10884,10 +11180,16 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + '@types/node@25.9.1': dependencies: undici-types: 7.24.6 + '@types/pegjs@0.10.6': {} + '@types/react-dom@19.2.3(@types/react@19.2.3)': dependencies: '@types/react': 19.2.3 @@ -11236,6 +11538,16 @@ snapshots: adm-zip@0.5.17: {} + aes-js@3.1.2: {} + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@9.0.0: {} ajv-draft-04@1.0.0(ajv@8.20.0): @@ -11399,6 +11711,8 @@ snapshots: async@3.2.6: {} + asynckit@0.4.0: {} + atomic-sleep@1.0.0: {} atomically@2.1.1: @@ -11410,6 +11724,16 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axios@1.16.1: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + babel-jest@30.4.1(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 @@ -11488,6 +11812,8 @@ snapshots: bluebird@3.7.2: {} + bn.js@5.2.3: {} + body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -11612,6 +11938,8 @@ snapshots: caniuse-lite@1.0.30001793: {} + case-shift@2.5.3: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -11671,6 +11999,12 @@ snapshots: cli-boxes@3.0.0: {} + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + cli-width@4.1.0: {} cliui@7.0.4: @@ -11697,6 +12031,10 @@ snapshots: color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@14.0.3: {} commander@2.9.0: @@ -11761,6 +12099,8 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 + crc-32@1.2.2: {} + create-require@1.1.1: {} cross-env@10.1.0: @@ -11810,6 +12150,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dataloader@2.2.3: {} + dayjs@1.11.20: {} debounce@1.2.1: {} @@ -11863,6 +12205,8 @@ snapshots: defu@6.1.7: {} + delayed-stream@1.0.0: {} + depd@2.0.0: {} dequal@2.0.3: {} @@ -11930,6 +12274,8 @@ snapshots: dependencies: type-fest: 4.41.0 + dotenv@16.6.1: {} + dotenv@17.4.2: {} dunder-proto@1.0.1: @@ -12288,6 +12634,19 @@ snapshots: etag@1.8.1: {} + ethers@6.16.0: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + events@3.3.0: {} eventsource-parser@3.0.8: {} @@ -12478,6 +12837,8 @@ snapshots: flatted@3.4.2: {} + follow-redirects@1.16.0: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -12487,6 +12848,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + forwarded@0.2.0: {} framer-motion@12.40.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): @@ -12735,6 +13104,13 @@ snapshots: http2-client@1.3.5: {} + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@9.0.0: dependencies: agent-base: 9.0.0 @@ -12982,10 +13358,21 @@ snapshots: isobject@3.0.1: {} + isomorphic-fetch@3.0.0: + dependencies: + node-fetch: 2.7.0 + whatwg-fetch: 3.6.20 + transitivePeerDependencies: + - encoding + isomorphic-ws@5.0.0(ws@8.17.1): dependencies: ws: 8.17.1 + isomorphic-ws@5.0.0(ws@8.21.0): + dependencies: + ws: 8.21.0 + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@6.0.3: @@ -13524,6 +13911,8 @@ snapshots: dependencies: yallist: 3.1.1 + lru_map@0.4.1: {} + lucide-react@0.562.0(react@19.2.3): dependencies: react: 19.2.3 @@ -13573,8 +13962,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -13996,6 +14391,8 @@ snapshots: pathval@2.0.1: {} + pegjs@0.10.0: {} + perfect-debounce@2.1.0: {} picocolors@1.1.1: {} @@ -14119,6 +14516,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@2.1.0: {} + pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -14919,6 +15318,8 @@ snapshots: transitivePeerDependencies: - encoding + symbol.inspect@1.0.1: {} + synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 @@ -15006,6 +15407,25 @@ snapshots: toidentifier@1.0.1: {} + ton-crypto-primitives@2.0.0: + dependencies: + jssha: 3.2.0 + + ton-crypto@3.2.0: + dependencies: + jssha: 3.2.0 + ton-crypto-primitives: 2.0.0 + tweetnacl: 1.0.3 + + ton-tl@1.0.1: + dependencies: + '@types/bn.js': 5.2.0 + '@types/pegjs': 0.10.6 + bn.js: 5.2.3 + case-shift: 2.5.3 + crc-32: 1.2.2 + pegjs: 0.10.0 + totalist@3.0.1: {} tr46@0.0.3: {} @@ -15085,6 +15505,8 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@2.7.0: {} + tslib@2.8.1: {} tsx@4.22.3: @@ -15207,6 +15629,8 @@ snapshots: underscore@1.13.8: {} + undici-types@6.19.8: {} + undici-types@7.24.6: {} undici@8.0.2: {} @@ -15434,6 +15858,8 @@ snapshots: webpack-virtual-modules@0.6.2: {} + whatwg-fetch@3.6.20: {} + whatwg-mimetype@3.0.0: {} whatwg-url@16.0.1(@noble/hashes@2.2.0): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c514a9cbb..90aa00681 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,10 +16,11 @@ catalog: '@ton/core': ^0.63.1 '@ton/crypto': ^3.3.0 '@tonconnect/bridge-sdk': ^0.2.8 - '@tonconnect/protocol': ^2.5.0-alpha.0 - '@tonconnect/sdk': ^3.5.0-alpha.0 - '@tonconnect/ui': ^2.5.0-alpha.0 - '@tonconnect/ui-react': ^2.5.0-alpha.0 + '@tonconnect/protocol': ^2.5.0-alpha.1 + '@tonconnect/sdk': ^3.5.0-alpha.1 + '@tonconnect/ui': ^2.5.0-alpha.1 + '@tonconnect/ui-react': ^2.5.0-alpha.1 + '@tonappchain/sdk': 0.7.2 '@types/react': 19.2.3 '@types/react-dom': 19.2.3 buffer: ^6.0.3