From 714188af68c6deb1cbc14066e78eec5b7ff03be3 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sat, 17 Jan 2026 20:03:34 -0500 Subject: [PATCH 01/26] feat: Add Solana USDC deposit system with Anchor program - Add Anchor program (polyield_vault) with initialize, deposit, withdraw instructions - Create PDA-controlled vault for secure USDC storage - Add frontend deposit modal with wallet connection - Wire market cards to deposit flow - Add user deposit tracking per market/position - Support Devnet USDC mint (4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU) - Add deployment instructions in programs/README.md --- Anchor.toml | 16 ++ Cargo.toml | 14 ++ components/deposit-modal.tsx | 256 +++++++++++++++++++ components/market-card.tsx | 199 +++++++++------ hooks/use-deposit.ts | 155 ++++++++++++ lib/solana/constants.ts | 23 ++ lib/solana/deposit.ts | 266 ++++++++++++++++++++ lib/solana/index.ts | 3 + package.json | 1 + pnpm-lock.yaml | 381 +++++++++++++++++++++-------- programs/README.md | 179 ++++++++++++++ programs/polyield_vault/Cargo.toml | 20 ++ programs/polyield_vault/Xargo.toml | 2 + programs/polyield_vault/src/lib.rs | 282 +++++++++++++++++++++ target/idl/polyield_vault.json | 361 +++++++++++++++++++++++++++ tests/polyield_vault.ts | 195 +++++++++++++++ 16 files changed, 2165 insertions(+), 188 deletions(-) create mode 100644 Anchor.toml create mode 100644 Cargo.toml create mode 100644 components/deposit-modal.tsx create mode 100644 hooks/use-deposit.ts create mode 100644 lib/solana/constants.ts create mode 100644 lib/solana/deposit.ts create mode 100644 lib/solana/index.ts create mode 100644 programs/README.md create mode 100644 programs/polyield_vault/Cargo.toml create mode 100644 programs/polyield_vault/Xargo.toml create mode 100644 programs/polyield_vault/src/lib.rs create mode 100644 target/idl/polyield_vault.json create mode 100644 tests/polyield_vault.ts diff --git a/Anchor.toml b/Anchor.toml new file mode 100644 index 0000000..827b8c0 --- /dev/null +++ b/Anchor.toml @@ -0,0 +1,16 @@ +[features] +seeds = false +skip-lint = false + +[programs.devnet] +polyield_vault = "YourProgramIdHere11111111111111111111111111" + +[registry] +url = "https://api.apr.dev" + +[provider] +cluster = "devnet" +wallet = "~/.config/solana/id.json" + +[scripts] +test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f397704 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[workspace] +members = [ + "programs/*" +] +resolver = "2" + +[profile.release] +overflow-checks = true +lto = "fat" +codegen-units = 1 +[profile.release.build-override] +opt-level = 3 +incremental = false +codegen-units = 1 diff --git a/components/deposit-modal.tsx b/components/deposit-modal.tsx new file mode 100644 index 0000000..7271a01 --- /dev/null +++ b/components/deposit-modal.tsx @@ -0,0 +1,256 @@ +"use client" + +import { useState, useEffect } from "react" +import { X, Loader2, CheckCircle, ExternalLink, AlertCircle, Wallet } from "lucide-react" +import { useWallet } from "@solana/wallet-adapter-react" +import { useWalletModal } from "@solana/wallet-adapter-react-ui" +import { useDeposit } from "@/hooks/use-deposit" +import { Position } from "@/lib/solana/constants" +import { Button } from "./ui/button" + +interface DepositModalProps { + isOpen: boolean + onClose: () => void + marketId: string + marketQuestion: string + position: "yes" | "no" + currentOdds: number +} + +export function DepositModal({ + isOpen, + onClose, + marketId, + marketQuestion, + position, + currentOdds, +}: DepositModalProps) { + const [amount, setAmount] = useState("") + const { connected, publicKey } = useWallet() + const { setVisible } = useWalletModal() + const { + isLoading, + error, + txSignature, + usdcBalance, + deposit, + refreshBalance, + clearError, + clearTx, + } = useDeposit() + + // Refresh balance when modal opens or wallet connects + useEffect(() => { + if (isOpen && connected) { + refreshBalance() + } + }, [isOpen, connected, refreshBalance]) + + // Reset state when modal closes + useEffect(() => { + if (!isOpen) { + setAmount("") + clearError() + clearTx() + } + }, [isOpen, clearError, clearTx]) + + if (!isOpen) return null + + const numericAmount = parseFloat(amount) || 0 + const positionEnum = position === "yes" ? Position.Yes : Position.No + const potentialPayout = numericAmount > 0 ? numericAmount / (currentOdds / 100) : 0 + const potentialProfit = potentialPayout - numericAmount + + const handleDeposit = async () => { + if (numericAmount <= 0) return + await deposit(numericAmount, marketId, positionEnum) + } + + const handleConnectWallet = () => { + setVisible(true) + } + + const handleMaxClick = () => { + setAmount(usdcBalance.toFixed(2)) + } + + const solscanUrl = txSignature + ? `https://solscan.io/tx/${txSignature}?cluster=devnet` + : null + + return ( +
+ {/* Backdrop */} +
+ + {/* Modal */} +
+ {/* Close button */} + + + {/* Header */} +
+
+ + Predict {position} + + + @ {currentOdds}% + +
+

+ {marketQuestion} +

+
+ + {/* Success State */} + {txSignature && ( +
+
+ +

+ Deposit Successful! +

+

+ Your {numericAmount.toFixed(2)} USDC has been deposited to the {position.toUpperCase()} position. +

+ {solscanUrl && ( + + View on Solscan + + + )} +
+ +
+ )} + + {/* Main Form */} + {!txSignature && ( + <> + {/* Not Connected State */} + {!connected && ( +
+ +

+ Connect your wallet to make a deposit +

+ +
+ )} + + {/* Connected State */} + {connected && ( +
+ {/* Balance Display */} +
+ Available Balance + + {usdcBalance.toFixed(2)} USDC + +
+ + {/* Amount Input */} +
+ setAmount(e.target.value)} + placeholder="0.00" + min="0" + step="0.01" + className="w-full bg-[#1a1a1a] border border-border/50 px-4 py-3 pr-20 font-mono text-lg focus:outline-none focus:border-primary/50 transition-colors" + disabled={isLoading} + /> +
+ + USDC +
+
+ + {/* Potential Payout */} + {numericAmount > 0 && ( +
+
+ Your Stake + {numericAmount.toFixed(2)} USDC +
+
+ If {position.toUpperCase()} wins + + +{potentialProfit.toFixed(2)} USDC + +
+
+ Potential Payout + + {potentialPayout.toFixed(2)} USDC + +
+
+ )} + + {/* Error Display */} + {error && ( +
+ +

{error}

+
+ )} + + {/* Deposit Button */} + + + {/* Devnet Notice */} +

+ Connected to Devnet • Using test USDC +

+
+ )} + + )} +
+
+ ) +} diff --git a/components/market-card.tsx b/components/market-card.tsx index 3e19b0b..a76e38d 100644 --- a/components/market-card.tsx +++ b/components/market-card.tsx @@ -3,6 +3,7 @@ import { useState } from "react" import { Calendar, TrendingUp, ExternalLink } from "lucide-react" import { Button } from "./ui/button" +import { DepositModal } from "./deposit-modal" import Image from "next/image" import type { Market } from "@/lib/types/polymarket" @@ -13,6 +14,7 @@ interface MarketCardProps { export function MarketCard({ market }: MarketCardProps) { const [selectedPosition, setSelectedPosition] = useState<"yes" | "no" | null>(null) + const [isDepositModalOpen, setIsDepositModalOpen] = useState(false) // Use actual prices if available, otherwise calculate from pools const yesPercentage = market.yesPrice @@ -32,100 +34,135 @@ export function MarketCard({ market }: MarketCardProps) { ? `https://polymarket.com/event/${market.slug}` : "https://polymarket.com" + const handleDepositClick = () => { + if (selectedPosition) { + setIsDepositModalOpen(true) + } + } + + const handleCloseModal = () => { + setIsDepositModalOpen(false) + } + + // Get current odds for the selected position + const getCurrentOdds = () => { + if (selectedPosition === "yes") return yesPercentage + if (selectedPosition === "no") return noPercentage + return 0 + } + return ( -
- {/* Market image */} - {market.image && ( -
- + <> +
+ {/* Market image */} + {market.image && ( +
+ +
+ )} + +
+ + {market.category} + + + +
- )} - -
- - {market.category} - - - - -
-

{market.question}

+

{market.question}

- {/* Prediction bar */} -
-
- Yes {yesPercentage}% - No {noPercentage}% -
-
-
-
+ {/* Prediction bar */} +
+
+ Yes {yesPercentage}% + No {noPercentage}% +
+
+
+
+
-
- {/* Position buttons */} -
- - -
+ {/* Position buttons */} +
+ + +
- {/* Market info */} -
-
-
- - {formatCurrency(market.totalPool)} -
- {market.volume && market.volume > 0 && ( + {/* Market info */} +
+
- {formatCurrency(market.volume)} vol + + {formatCurrency(market.totalPool)}
- )} -
-
- - {market.endDate} + {market.volume && market.volume > 0 && ( +
+ {formatCurrency(market.volume)} vol +
+ )} +
+
+ + {market.endDate} +
+ + {/* Deposit button (appears when position selected) */} + {selectedPosition && ( + + )}
- {/* Deposit button (appears when position selected) */} + {/* Deposit Modal */} {selectedPosition && ( - + )} -
+ ) } diff --git a/hooks/use-deposit.ts b/hooks/use-deposit.ts new file mode 100644 index 0000000..394b438 --- /dev/null +++ b/hooks/use-deposit.ts @@ -0,0 +1,155 @@ +"use client" + +import { useState, useCallback } from "react" +import { useConnection, useWallet } from "@solana/wallet-adapter-react" +import { + buildDepositTransaction, + getUserUsdcBalance, + Position, +} from "@/lib/solana/deposit" + +export interface DepositState { + isLoading: boolean + error: string | null + txSignature: string | null + usdcBalance: number +} + +export interface UseDepositReturn extends DepositState { + deposit: (amount: number, marketId: string, position: Position) => Promise + refreshBalance: () => Promise + clearError: () => void + clearTx: () => void +} + +export function useDeposit(): UseDepositReturn { + const { connection } = useConnection() + const { publicKey, signTransaction, connected } = useWallet() + + const [state, setState] = useState({ + isLoading: false, + error: null, + txSignature: null, + usdcBalance: 0, + }) + + const refreshBalance = useCallback(async () => { + if (!publicKey) { + setState(prev => ({ ...prev, usdcBalance: 0 })) + return + } + + try { + const balance = await getUserUsdcBalance(connection, publicKey) + setState(prev => ({ ...prev, usdcBalance: balance })) + } catch (err) { + console.error("Failed to fetch USDC balance:", err) + } + }, [connection, publicKey]) + + const deposit = useCallback(async ( + amount: number, + marketId: string, + position: Position + ): Promise => { + if (!publicKey || !signTransaction || !connected) { + setState(prev => ({ + ...prev, + error: "Please connect your wallet first" + })) + return null + } + + if (amount <= 0) { + setState(prev => ({ + ...prev, + error: "Amount must be greater than 0" + })) + return null + } + + if (amount > state.usdcBalance) { + setState(prev => ({ + ...prev, + error: `Insufficient USDC balance. You have ${state.usdcBalance.toFixed(2)} USDC` + })) + return null + } + + setState(prev => ({ + ...prev, + isLoading: true, + error: null, + txSignature: null + })) + + try { + // Build the transaction + const { transaction } = await buildDepositTransaction({ + connection, + userPublicKey: publicKey, + amount, + marketId, + position, + }) + + // Sign the transaction with user's wallet (Phantom) + const signedTransaction = await signTransaction(transaction) + + // Send the transaction + const signature = await connection.sendRawTransaction( + signedTransaction.serialize(), + { + skipPreflight: false, + preflightCommitment: "confirmed", + } + ) + + // Wait for confirmation + const confirmation = await connection.confirmTransaction( + signature, + "confirmed" + ) + + if (confirmation.value.err) { + throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`) + } + + setState(prev => ({ + ...prev, + isLoading: false, + txSignature: signature + })) + + // Refresh balance after successful deposit + await refreshBalance() + + return signature + } catch (err) { + const errorMessage = err instanceof Error ? err.message : "Deposit failed" + console.error("Deposit error:", err) + setState(prev => ({ + ...prev, + isLoading: false, + error: errorMessage + })) + return null + } + }, [connection, publicKey, signTransaction, connected, state.usdcBalance, refreshBalance]) + + const clearError = useCallback(() => { + setState(prev => ({ ...prev, error: null })) + }, []) + + const clearTx = useCallback(() => { + setState(prev => ({ ...prev, txSignature: null })) + }, []) + + return { + ...state, + deposit, + refreshBalance, + clearError, + clearTx, + } +} diff --git a/lib/solana/constants.ts b/lib/solana/constants.ts new file mode 100644 index 0000000..f73e8c2 --- /dev/null +++ b/lib/solana/constants.ts @@ -0,0 +1,23 @@ +import { PublicKey } from "@solana/web3.js" + +// Devnet USDC Mint Address +export const USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU") + +// USDC has 6 decimals +export const USDC_DECIMALS = 6 + +// Program ID - Update this after deploying to devnet +// Run: anchor keys list to get your program ID +// Using System Program as placeholder until deployed +export const PROGRAM_ID = new PublicKey("11111111111111111111111111111111") + +// Seed constants matching the Anchor program +export const VAULT_SEED = "vault" +export const VAULT_STATE_SEED = "vault_state" +export const USER_DEPOSIT_SEED = "user_deposit" + +// Position enum values matching the Anchor program +export enum Position { + Yes = 0, + No = 1, +} diff --git a/lib/solana/deposit.ts b/lib/solana/deposit.ts new file mode 100644 index 0000000..bb25d86 --- /dev/null +++ b/lib/solana/deposit.ts @@ -0,0 +1,266 @@ +import { + Connection, + PublicKey, + Transaction, + TransactionInstruction, + SystemProgram, + SYSVAR_RENT_PUBKEY, +} from "@solana/web3.js" +import { + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID, + getAssociatedTokenAddress, + createAssociatedTokenAccountInstruction, + getAccount, +} from "@solana/spl-token" +import { + USDC_MINT, + USDC_DECIMALS, + PROGRAM_ID, + VAULT_SEED, + VAULT_STATE_SEED, + USER_DEPOSIT_SEED, + Position, +} from "./constants" + +/** + * Get the vault PDA address + */ +export function getVaultPDA(): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [Buffer.from(VAULT_SEED), USDC_MINT.toBuffer()], + PROGRAM_ID + ) +} + +/** + * Get the vault state PDA address + */ +export function getVaultStatePDA(): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [Buffer.from(VAULT_STATE_SEED), USDC_MINT.toBuffer()], + PROGRAM_ID + ) +} + +/** + * Get the user deposit PDA address + */ +export function getUserDepositPDA( + user: PublicKey, + marketId: string, + position: Position +): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [ + Buffer.from(USER_DEPOSIT_SEED), + user.toBuffer(), + Buffer.from(marketId), + Buffer.from([position]), + ], + PROGRAM_ID + ) +} + +/** + * Convert USDC amount to lamports (with 6 decimals) + */ +export function usdcToLamports(amount: number): bigint { + return BigInt(Math.round(amount * Math.pow(10, USDC_DECIMALS))) +} + +/** + * Convert lamports to USDC display amount + */ +export function lamportsToUsdc(lamports: bigint): number { + return Number(lamports) / Math.pow(10, USDC_DECIMALS) +} + +/** + * Build the deposit instruction discriminator + * This is the first 8 bytes of SHA256("global:deposit") + */ +function getDepositDiscriminator(): Buffer { + // Pre-computed discriminator for "deposit" instruction + return Buffer.from([242, 35, 198, 137, 82, 225, 242, 182]) +} + +/** + * Encode the position enum for the instruction + */ +function encodePosition(position: Position): Buffer { + return Buffer.from([position]) +} + +/** + * Encode a string with length prefix (Borsh format) + */ +function encodeString(str: string): Buffer { + const strBuffer = Buffer.from(str, "utf-8") + const lenBuffer = Buffer.alloc(4) + lenBuffer.writeUInt32LE(strBuffer.length) + return Buffer.concat([lenBuffer, strBuffer]) +} + +/** + * Encode u64 in little-endian format + */ +function encodeU64(value: bigint): Buffer { + const buffer = Buffer.alloc(8) + buffer.writeBigUInt64LE(value) + return buffer +} + +/** + * Build the deposit instruction data + */ +function buildDepositInstructionData( + amount: bigint, + marketId: string, + position: Position +): Buffer { + const discriminator = getDepositDiscriminator() + const amountBuffer = encodeU64(amount) + const marketIdBuffer = encodeString(marketId) + const positionBuffer = encodePosition(position) + + return Buffer.concat([discriminator, amountBuffer, marketIdBuffer, positionBuffer]) +} + +export interface DepositParams { + connection: Connection + userPublicKey: PublicKey + amount: number // in USDC (e.g., 10.5 for $10.50) + marketId: string + position: Position +} + +export interface DepositResult { + transaction: Transaction + userTokenAccount: PublicKey + vault: PublicKey + needsTokenAccountCreation: boolean +} + +/** + * Build a deposit transaction + * Returns the transaction ready to be signed and sent + */ +export async function buildDepositTransaction( + params: DepositParams +): Promise { + const { connection, userPublicKey, amount, marketId, position } = params + + // Get PDAs + const [vault] = getVaultPDA() + const [vaultState] = getVaultStatePDA() + const [userDeposit] = getUserDepositPDA(userPublicKey, marketId, position) + + // Get user's USDC token account + const userTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + userPublicKey + ) + + // Check if user's token account exists + let needsTokenAccountCreation = false + try { + await getAccount(connection, userTokenAccount) + } catch { + needsTokenAccountCreation = true + } + + // Convert amount to lamports + const amountLamports = usdcToLamports(amount) + + // Build the transaction + const transaction = new Transaction() + + // If user doesn't have a USDC token account, create one + if (needsTokenAccountCreation) { + transaction.add( + createAssociatedTokenAccountInstruction( + userPublicKey, // payer + userTokenAccount, // ata + userPublicKey, // owner + USDC_MINT // mint + ) + ) + } + + // Build instruction data + const data = buildDepositInstructionData(amountLamports, marketId, position) + + // Build the deposit instruction + const depositInstruction = new TransactionInstruction({ + programId: PROGRAM_ID, + keys: [ + { pubkey: userPublicKey, isSigner: true, isWritable: true }, // user + { pubkey: USDC_MINT, isSigner: false, isWritable: false }, // mint + { pubkey: vaultState, isSigner: false, isWritable: true }, // vault_state + { pubkey: vault, isSigner: false, isWritable: true }, // vault + { pubkey: userTokenAccount, isSigner: false, isWritable: true }, // user_token_account + { pubkey: userDeposit, isSigner: false, isWritable: true }, // user_deposit + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // token_program + { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // associated_token_program + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // system_program + ], + data, + }) + + transaction.add(depositInstruction) + + // Get recent blockhash + const { blockhash } = await connection.getLatestBlockhash() + transaction.recentBlockhash = blockhash + transaction.feePayer = userPublicKey + + return { + transaction, + userTokenAccount, + vault, + needsTokenAccountCreation, + } +} + +/** + * Get user's USDC balance + */ +export async function getUserUsdcBalance( + connection: Connection, + userPublicKey: PublicKey +): Promise { + try { + const userTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + userPublicKey + ) + const account = await getAccount(connection, userTokenAccount) + return lamportsToUsdc(account.amount) + } catch { + // Account doesn't exist or has no balance + return 0 + } +} + +/** + * Check if the vault is initialized + */ +export async function isVaultInitialized(connection: Connection): Promise { + const [vaultState] = getVaultStatePDA() + const accountInfo = await connection.getAccountInfo(vaultState) + return accountInfo !== null +} + +/** + * Get total deposits in the vault + */ +export async function getVaultTotalDeposits(connection: Connection): Promise { + const [vault] = getVaultPDA() + try { + const account = await getAccount(connection, vault) + return lamportsToUsdc(account.amount) + } catch { + return 0 + } +} diff --git a/lib/solana/index.ts b/lib/solana/index.ts new file mode 100644 index 0000000..af22654 --- /dev/null +++ b/lib/solana/index.ts @@ -0,0 +1,3 @@ +// Re-export all Solana utilities +export * from "./constants" +export * from "./deposit" diff --git a/package.json b/package.json index 42930f4..75a6496 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@radix-ui/react-tooltip": "1.1.6", "@react-three/drei": "latest", "@react-three/fiber": "latest", + "@solana/spl-token": "^0.4.14", "@solana/wallet-adapter-base": "^0.9.27", "@solana/wallet-adapter-phantom": "^0.9.28", "@solana/wallet-adapter-react": "^0.15.39", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5131bb..3cadee4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,10 +103,13 @@ importers: version: 1.1.6(@types/react-dom@19.0.0)(@types/react@19.0.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@react-three/drei': specifier: latest - version: 10.7.7(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0) + version: 10.7.7(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0) '@react-three/fiber': specifier: latest - version: 9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0) + version: 9.5.0(76a5e9f5d3135d0418139ea8b671268e) + '@solana/spl-token': + specifier: ^0.4.14 + version: 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(utf-8-validate@5.0.10) '@solana/wallet-adapter-base': specifier: ^0.9.27 version: 0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) @@ -121,7 +124,7 @@ importers: version: 0.9.39(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bs58@5.0.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(typescript@5.0.2) '@solana/wallet-adapter-wallets': specifier: ^0.19.37 - version: 0.19.37(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(@types/react@19.0.0)(bs58@5.0.0)(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.67) + version: 0.19.37(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(@types/react@19.0.0)(bs58@5.0.0)(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.67) '@solana/web3.js': specifier: ^1.98.4 version: 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) @@ -151,13 +154,13 @@ importers: version: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) expo-asset: specifier: latest - version: 12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 12.0.12(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) expo-file-system: specifier: latest - version: 19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + version: 19.0.21(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) expo-gl: specifier: latest - version: 16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 16.0.9(expo@54.0.31)(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) geist: specifier: ^1.3.1 version: 1.3.1(next@15.2.4(@babel/core@7.28.6)(babel-plugin-react-compiler@1.0.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) @@ -184,7 +187,7 @@ importers: version: 0.12.7 r3f-perf: specifier: latest - version: 7.2.3(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)) + version: 7.2.3(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)) react: specifier: ^19 version: 19.0.0 @@ -2594,10 +2597,19 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + '@solana/buffer-layout@4.0.1': resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + '@solana/codecs-core@2.3.0': resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} engines: {node: '>=20.18.0'} @@ -2610,12 +2622,22 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + '@solana/codecs-data-structures@2.3.0': resolution: {integrity: sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + '@solana/codecs-numbers@2.3.0': resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} engines: {node: '>=20.18.0'} @@ -2628,6 +2650,12 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + '@solana/codecs-strings@2.3.0': resolution: {integrity: sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug==} engines: {node: '>=20.18.0'} @@ -2642,12 +2670,23 @@ packages: fastestsmallesttextencoderdecoder: ^1.0.22 typescript: '>=5.3.3' + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + '@solana/codecs@2.3.0': resolution: {integrity: sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + '@solana/errors@2.3.0': resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} engines: {node: '>=20.18.0'} @@ -2698,6 +2737,11 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + '@solana/options@2.3.0': resolution: {integrity: sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw==} engines: {node: '>=20.18.0'} @@ -2795,6 +2839,24 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/spl-token-group@0.0.7': + resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.4.14': + resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.5 + '@solana/subscribable@2.3.0': resolution: {integrity: sha512-DkgohEDbMkdTWiKAoatY02Njr56WXx9e/dKKfmne8/Ad6/2llUIrax78nCdlvZW9quXMaXPTxZvdQqo9N669Og==} engines: {node: '>=20.18.0'} @@ -3940,6 +4002,10 @@ packages: big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -8188,7 +8254,7 @@ snapshots: '@ethereumjs/rlp': 5.0.2 ethereum-cryptography: 2.2.1 - '@expo/cli@54.0.21(bufferutil@4.1.0)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@expo/cli@54.0.21(bufferutil@4.1.0)(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@0no-co/graphql.web': 1.2.0 '@expo/code-signing-certificates': 0.0.6 @@ -8199,11 +8265,11 @@ snapshots: '@expo/image-utils': 0.8.8 '@expo/json-file': 10.0.8 '@expo/metro': 54.2.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - '@expo/metro-config': 54.0.13(bufferutil@4.1.0)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@expo/metro-config': 54.0.13(bufferutil@4.1.0)(expo@54.0.31)(utf-8-validate@5.0.10) '@expo/osascript': 2.3.8 '@expo/package-manager': 1.9.10 '@expo/plist': 0.4.8 - '@expo/prebuild-config': 54.0.8(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)) + '@expo/prebuild-config': 54.0.8(expo@54.0.31) '@expo/schema-utils': 0.1.8 '@expo/spawn-async': 1.7.2 '@expo/ws-tunnel': 1.0.6 @@ -8369,7 +8435,7 @@ snapshots: '@babel/code-frame': 7.10.4 json5: 2.2.3 - '@expo/metro-config@54.0.13(bufferutil@4.1.0)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@expo/metro-config@54.0.13(bufferutil@4.1.0)(expo@54.0.31)(utf-8-validate@5.0.10)': dependencies: '@babel/code-frame': 7.28.6 '@babel/core': 7.28.6 @@ -8452,7 +8518,7 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@54.0.8(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))': + '@expo/prebuild-config@54.0.8(expo@54.0.31)': dependencies: '@expo/config': 12.0.13 '@expo/config-plugins': 54.0.4 @@ -8478,9 +8544,9 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@15.0.3(expo-font@14.0.10(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@expo/vector-icons@15.0.3(expo-font@14.0.10(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - expo-font: 14.0.10(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-font: 14.0.10(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) react: 19.0.0 react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) @@ -10015,24 +10081,24 @@ snapshots: '@react-spring/types': 9.7.5 react: 19.0.0 - ? '@react-spring/three@9.7.5(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(react@19.0.0)(three@0.182.0)' - : dependencies: + '@react-spring/three@9.7.5(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(react@19.0.0)(three@0.182.0)': + dependencies: '@react-spring/animated': 9.7.5(react@19.0.0) '@react-spring/core': 9.7.5(react@19.0.0) '@react-spring/shared': 9.7.5(react@19.0.0) '@react-spring/types': 9.7.5 - '@react-three/fiber': 9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0) + '@react-three/fiber': 9.5.0(76a5e9f5d3135d0418139ea8b671268e) react: 19.0.0 three: 0.182.0 '@react-spring/types@9.7.5': {} - ? '@react-three/drei@10.7.7(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)' - : dependencies: + '@react-three/drei@10.7.7(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)': + dependencies: '@babel/runtime': 7.28.6 '@mediapipe/tasks-vision': 0.10.17 '@monogrid/gainmap-js': 3.4.0(three@0.182.0) - '@react-three/fiber': 9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0) + '@react-three/fiber': 9.5.0(76a5e9f5d3135d0418139ea8b671268e) '@use-gesture/react': 10.3.1(react@19.0.0) camera-controls: 3.1.2(three@0.182.0) cross-env: 7.0.3 @@ -10060,13 +10126,13 @@ snapshots: - '@types/three' - immer - ? '@react-three/drei@9.122.0(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0))' - : dependencies: + '@react-three/drei@9.122.0(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0))': + dependencies: '@babel/runtime': 7.28.6 '@mediapipe/tasks-vision': 0.10.17 '@monogrid/gainmap-js': 3.4.0(three@0.182.0) - '@react-spring/three': 9.7.5(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(react@19.0.0)(three@0.182.0) - '@react-three/fiber': 9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0) + '@react-spring/three': 9.7.5(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(react@19.0.0)(three@0.182.0) + '@react-three/fiber': 9.5.0(76a5e9f5d3135d0418139ea8b671268e) '@use-gesture/react': 10.3.1(react@19.0.0) camera-controls: 2.10.1(three@0.182.0) cross-env: 7.0.3 @@ -10095,8 +10161,8 @@ snapshots: - immer - use-sync-external-store - ? '@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0)' - : dependencies: + '@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e)': + dependencies: '@babel/runtime': 7.28.6 '@types/webxr': 0.5.24 base64-js: 1.5.1 @@ -10111,9 +10177,9 @@ snapshots: zustand: 5.0.10(@types/react@19.0.0)(react@19.0.0)(use-sync-external-store@1.6.0(react@19.0.0)) optionalDependencies: expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) - expo-asset: 12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - expo-file-system: 19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) - expo-gl: 16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-asset: 12.0.12(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-file-system: 19.0.21(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-gl: 16.0.9(expo@54.0.31)(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) react-dom: 19.0.0(react@19.0.0) react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -10458,26 +10524,26 @@ snapshots: - react-native - typescript - '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': + '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': + '@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': + '@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))': + '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))': dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) - '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': + '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': dependencies: @@ -10507,10 +10573,27 @@ snapshots: '@solana/errors': 2.3.0(typescript@5.0.2) typescript: 5.0.2 + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + bigint-buffer: 1.1.5 + bignumber.js: 9.3.1 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 + '@solana/codecs-core@2.0.0-rc.1(typescript@5.0.2)': + dependencies: + '@solana/errors': 2.0.0-rc.1(typescript@5.0.2) + typescript: 5.0.2 + '@solana/codecs-core@2.3.0(typescript@5.0.2)': dependencies: '@solana/errors': 2.3.0(typescript@5.0.2) @@ -10521,6 +10604,13 @@ snapshots: '@solana/errors': 4.0.0(typescript@5.0.2) typescript: 5.0.2 + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.0.2)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.0.2) + '@solana/errors': 2.0.0-rc.1(typescript@5.0.2) + typescript: 5.0.2 + '@solana/codecs-data-structures@2.3.0(typescript@5.0.2)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.0.2) @@ -10528,6 +10618,12 @@ snapshots: '@solana/errors': 2.3.0(typescript@5.0.2) typescript: 5.0.2 + '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.0.2)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.0.2) + '@solana/errors': 2.0.0-rc.1(typescript@5.0.2) + typescript: 5.0.2 + '@solana/codecs-numbers@2.3.0(typescript@5.0.2)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.0.2) @@ -10540,6 +10636,14 @@ snapshots: '@solana/errors': 4.0.0(typescript@5.0.2) typescript: 5.0.2 + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.0.2) + '@solana/errors': 2.0.0-rc.1(typescript@5.0.2) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 5.0.2 + '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.0.2) @@ -10556,6 +10660,17 @@ snapshots: fastestsmallesttextencoderdecoder: 1.0.22 typescript: 5.0.2 + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + typescript: 5.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.0.2) @@ -10567,6 +10682,12 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/errors@2.0.0-rc.1(typescript@5.0.2)': + dependencies: + chalk: 5.6.2 + commander: 12.1.0 + typescript: 5.0.2 + '@solana/errors@2.3.0(typescript@5.0.2)': dependencies: chalk: 5.6.2 @@ -10604,7 +10725,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) @@ -10617,11 +10738,11 @@ snapshots: '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/rpc-parsed-types': 2.3.0(typescript@5.0.2) '@solana/rpc-spec-types': 2.3.0(typescript@5.0.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) - '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) typescript: 5.0.2 @@ -10633,6 +10754,17 @@ snapshots: dependencies: typescript: 5.0.2 + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.0.2) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/errors': 2.0.0-rc.1(typescript@5.0.2) + typescript: 5.0.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.0.2) @@ -10700,14 +10832,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.0.2) '@solana/functional': 2.3.0(typescript@5.0.2) '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.0.2) '@solana/subscribable': 2.3.0(typescript@5.0.2) typescript: 5.0.2 - ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) '@solana/rpc-subscriptions-spec@2.3.0(typescript@5.0.2)': dependencies: @@ -10717,7 +10849,7 @@ snapshots: '@solana/subscribable': 2.3.0(typescript@5.0.2) typescript: 5.0.2 - '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.0.2) '@solana/fast-stable-stringify': 2.3.0(typescript@5.0.2) @@ -10725,7 +10857,7 @@ snapshots: '@solana/promises': 2.3.0(typescript@5.0.2) '@solana/rpc-spec-types': 2.3.0(typescript@5.0.2) '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) - '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.0.2) '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) @@ -10795,6 +10927,37 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + '@solana/subscribable@2.3.0(typescript@5.0.2)': dependencies: '@solana/errors': 2.3.0(typescript@5.0.2) @@ -10810,7 +10973,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) @@ -10818,7 +10981,7 @@ snapshots: '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/promises': 2.3.0(typescript@5.0.2) '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) @@ -11101,11 +11264,11 @@ snapshots: - typescript - utf-8-validate - ? '@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))' - : dependencies: + '@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + dependencies: '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) - '@trezor/connect-web': 9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/connect-web': 9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - '@solana/sysvars' @@ -11168,8 +11331,8 @@ snapshots: - utf-8-validate - zod - ? '@solana/wallet-adapter-wallets@0.19.37(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(@types/react@19.0.0)(bs58@5.0.0)(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.67)' - : dependencies: + '@solana/wallet-adapter-wallets@0.19.37(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(@types/react@19.0.0)(bs58@5.0.0)(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.67)': + dependencies: '@solana/wallet-adapter-alpha': 0.1.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.17(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-bitkeep': 0.3.24(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) @@ -11201,7 +11364,7 @@ snapshots: '@solana/wallet-adapter-tokenary': 0.1.16(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-tokenpocket': 0.4.23(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-torus': 0.11.32(@babel/runtime@7.28.6)(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trezor': 0.1.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-trezor': 0.1.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-trust': 0.1.17(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.11(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-walletconnect': 0.1.21(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10))(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(typescript@5.0.2)(utf-8-validate@5.0.10)(zod@3.25.67) @@ -11559,9 +11722,9 @@ snapshots: - typescript - utf-8-validate - '@trezor/analytics@1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': + '@trezor/analytics@1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': dependencies: - '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) tslib: 2.8.1 transitivePeerDependencies: @@ -11575,11 +11738,11 @@ snapshots: '@trezor/utxo-lib': 2.5.0(tslib@2.8.1) tslib: 2.8.1 - '@trezor/blockchain-link-utils@1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10)': + '@trezor/blockchain-link-utils@1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10)': dependencies: '@mobily/ts-belt': 3.13.1 '@stellar/stellar-sdk': 14.2.0 - '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/protobuf': 1.5.1(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) tslib: 2.8.1 @@ -11592,18 +11755,18 @@ snapshots: - react-native - utf-8-validate - '@trezor/blockchain-link@2.6.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/blockchain-link@2.6.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: - '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/stake': 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)) - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/stake': 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2) '@stellar/stellar-sdk': 14.2.0 '@trezor/blockchain-link-types': 1.5.0(tslib@2.8.1) - '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) - '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) + '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) '@trezor/utxo-lib': 2.5.0(tslib@2.8.1) '@trezor/websocket-client': 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) @@ -11626,18 +11789,18 @@ snapshots: - utf-8-validate - ws - '@trezor/connect-analytics@1.4.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': + '@trezor/connect-analytics@1.4.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': dependencies: - '@trezor/analytics': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/analytics': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) tslib: 2.8.1 transitivePeerDependencies: - expo-constants - expo-localization - react-native - '@trezor/connect-common@0.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': + '@trezor/connect-common@0.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': dependencies: - '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/type-utils': 1.2.0 '@trezor/utils': 9.5.0(tslib@2.8.1) tslib: 2.8.1 @@ -11646,10 +11809,10 @@ snapshots: - expo-localization - react-native - '@trezor/connect-web@9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/connect-web@9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: - '@trezor/connect': 9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@trezor/connect-common': 0.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/connect': 9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/connect-common': 0.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) '@trezor/websocket-client': 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) tslib: 2.8.1 @@ -11667,7 +11830,7 @@ snapshots: - utf-8-validate - ws - '@trezor/connect@9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/connect@9.7.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@ethereumjs/common': 10.1.0 '@ethereumjs/tx': 10.1.0 @@ -11675,20 +11838,20 @@ snapshots: '@mobily/ts-belt': 3.13.1 '@noble/hashes': 1.8.0 '@scure/bip39': 1.6.0 - '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/system': 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)) - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@trezor/blockchain-link': 2.6.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/system': 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/blockchain-link': 2.6.1(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.0.2))(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.0.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@trezor/blockchain-link-types': 1.5.0(tslib@2.8.1) - '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) - '@trezor/connect-analytics': 1.4.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) - '@trezor/connect-common': 0.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.1.0)(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) + '@trezor/connect-analytics': 1.4.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/connect-common': 0.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/crypto-utils': 1.2.0(tslib@2.8.1) '@trezor/device-authenticity': 1.1.1(tslib@2.8.1) '@trezor/device-utils': 1.2.0 - '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) + '@trezor/env-utils': 1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/protobuf': 1.5.1(tslib@2.8.1) '@trezor/protocol': 1.3.0(tslib@2.8.1) '@trezor/schema-utils': 1.4.0(tslib@2.8.1) @@ -11733,12 +11896,12 @@ snapshots: '@trezor/device-utils@1.2.0': {} - '@trezor/env-utils@1.5.0(expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': + '@trezor/env-utils@1.5.0(expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(tslib@2.8.1)': dependencies: tslib: 2.8.1 ua-parser-js: 2.0.8 optionalDependencies: - expo-constants: 18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-constants: 18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) '@trezor/protobuf@1.5.1(tslib@2.8.1)': @@ -12776,7 +12939,7 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.6) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.6) - babel-preset-expo@54.0.9(@babel/core@7.28.6)(@babel/runtime@7.28.6)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-refresh@0.14.2): + babel-preset-expo@54.0.9(@babel/core@7.28.6)(@babel/runtime@7.28.6)(expo@54.0.31)(react-refresh@0.14.2): dependencies: '@babel/helper-module-imports': 7.28.6 '@babel/plugin-proposal-decorators': 7.28.6(@babel/core@7.28.6) @@ -12848,6 +13011,10 @@ snapshots: big.js@6.2.2: {} + bigint-buffer@1.1.5: + dependencies: + bindings: 1.5.0 + bignumber.js@9.3.1: {} bindings@1.5.0: @@ -13619,17 +13786,17 @@ snapshots: exenv@1.2.2: {} - expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + expo-asset@12.0.12(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): dependencies: '@expo/image-utils': 0.8.8 expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) - expo-constants: 18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-constants: 18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) react: 19.0.0 react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - expo-constants@18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)): + expo-constants@18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)): dependencies: '@expo/config': 12.0.13 '@expo/env': 2.0.8 @@ -13638,19 +13805,19 @@ snapshots: transitivePeerDependencies: - supports-color - expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)): + expo-file-system@19.0.21(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)): dependencies: expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) - expo-font@14.0.10(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + expo-font@14.0.10(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): dependencies: expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) fontfaceobserver: 2.3.0 react: 19.0.0 react-native: 0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10) - expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + expo-gl@16.0.9(expo@54.0.31)(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): dependencies: expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) invariant: 2.2.4 @@ -13661,7 +13828,7 @@ snapshots: react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) react-native-web: 0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - expo-keep-awake@15.0.8(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + expo-keep-awake@15.0.8(expo@54.0.31)(react@19.0.0): dependencies: expo: 54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) react: 19.0.0 @@ -13685,21 +13852,21 @@ snapshots: expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10): dependencies: '@babel/runtime': 7.28.6 - '@expo/cli': 54.0.21(bufferutil@4.1.0)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@expo/cli': 54.0.21(bufferutil@4.1.0)(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@expo/config': 12.0.13 '@expo/config-plugins': 54.0.4 '@expo/devtools': 0.1.8(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@expo/fingerprint': 0.15.4 '@expo/metro': 54.2.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - '@expo/metro-config': 54.0.13(bufferutil@4.1.0)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@expo/vector-icons': 15.0.3(expo-font@14.0.10(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@expo/metro-config': 54.0.13(bufferutil@4.1.0)(expo@54.0.31)(utf-8-validate@5.0.10) + '@expo/vector-icons': 15.0.3(expo-font@14.0.10(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@ungap/structured-clone': 1.3.0 - babel-preset-expo: 54.0.9(@babel/core@7.28.6)(@babel/runtime@7.28.6)(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-refresh@0.14.2) - expo-asset: 12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - expo-constants: 18.0.13(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) - expo-file-system: 19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) - expo-font: 14.0.10(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - expo-keep-awake: 15.0.8(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + babel-preset-expo: 54.0.9(@babel/core@7.28.6)(@babel/runtime@7.28.6)(expo@54.0.31)(react-refresh@0.14.2) + expo-asset: 12.0.12(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-constants: 18.0.13(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-file-system: 19.0.21(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-font: 14.0.10(expo@54.0.31)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-keep-awake: 15.0.8(expo@54.0.31)(react@19.0.0) expo-modules-autolinking: 3.0.24 expo-modules-core: 3.0.29(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) pretty-format: 29.7.0 @@ -15229,17 +15396,17 @@ snapshots: quick-format-unescaped@4.0.4: {} - ? r3f-perf@7.2.3(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)) - : dependencies: + r3f-perf@7.2.3(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)): + dependencies: '@radix-ui/react-icons': 1.3.2(react@19.0.0) - '@react-three/drei': 9.122.0(@react-three/fiber@9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)) + '@react-three/drei': 9.122.0(@react-three/fiber@9.5.0(76a5e9f5d3135d0418139ea8b671268e))(@types/react@19.0.0)(@types/three@0.180.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(three@0.182.0)(use-sync-external-store@1.6.0(react@19.0.0)) '@stitches/react': 1.2.8(react@19.0.0) '@utsubo/events': 0.1.7(react@19.0.0) react: 19.0.0 three: 0.182.0 zustand: 4.5.7(@types/react@19.0.0)(react@19.0.0) optionalDependencies: - '@react-three/fiber': 9.5.0(@types/react@19.0.0)(expo-asset@12.0.12(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo-file-system@19.0.21(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-gl@16.0.9(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.28.6)(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(expo@54.0.31(@babel/core@7.28.6)(@expo/dom-webview@0.2.8)(@expo/metro-runtime@6.1.2)(bufferutil@4.1.0)(react-native-webview@13.16.0(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-dom@19.0.0(react@19.0.0))(react-native@0.83.1(@babel/core@7.28.6)(@types/react@19.0.0)(bufferutil@4.1.0)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(three@0.182.0) + '@react-three/fiber': 9.5.0(76a5e9f5d3135d0418139ea8b671268e) react-dom: 19.0.0(react@19.0.0) transitivePeerDependencies: - '@types/react' diff --git a/programs/README.md b/programs/README.md new file mode 100644 index 0000000..1726d14 --- /dev/null +++ b/programs/README.md @@ -0,0 +1,179 @@ +# Polyield Vault - Solana Anchor Program + +A PDA-controlled USDC vault for prediction market deposits on Solana. + +## Security Features + +1. **PDA-Controlled Vault**: The vault token account is owned by a Program Derived Address (PDA), meaning only the program can authorize withdrawals - no single person holds the keys +2. **User Deposit Tracking**: Each deposit is recorded in a PDA account per user, ensuring proper accounting +3. **Admin Controls**: Initialize vault with admin authority for emergencies + +## Prerequisites + +Before deploying, you need to install: + +### 1. Install Rust + +```bash +# Windows (use rustup-init.exe from https://rustup.rs/) +# Or on WSL/Linux: +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +### 2. Install Solana CLI + +```bash +# Windows (PowerShell - run as Admin) +choco install solana + +# Or on WSL/Linux: +sh -c "$(curl -sSfL https://release.solana.com/v1.18.4/install)" +``` + +### 3. Install Anchor CLI + +```bash +cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked +``` + +### 4. Configure Solana for Devnet + +```bash +# Set to devnet +solana config set --url devnet + +# Create a new keypair (if you don't have one) +solana-keygen new + +# Get some devnet SOL for deployment +solana airdrop 2 +``` + +## Deployment Steps + +### 1. Build the program + +```bash +# From the project root +anchor build +``` + +### 2. Get your Program ID + +After building, get your program ID: + +```bash +anchor keys list +``` + +### 3. Update Program ID + +Update the program ID in these files: +- `programs/polyield_vault/src/lib.rs` - `declare_id!("YOUR_PROGRAM_ID")` +- `Anchor.toml` - `polyield_vault = "YOUR_PROGRAM_ID"` +- `lib/solana/constants.ts` - `PROGRAM_ID = new PublicKey("YOUR_PROGRAM_ID")` + +### 4. Rebuild with correct Program ID + +```bash +anchor build +``` + +### 5. Deploy to Devnet + +```bash +anchor deploy +``` + +### 6. Initialize the Vault + +After deployment, you need to initialize the vault. Create a script or use the Anchor CLI: + +```bash +# Using anchor test (which runs the test scripts) +anchor test --skip-local-validator +``` + +Or create an initialization script - see `tests/initialize.ts`. + +## Program Instructions + +### `initialize` +Creates the PDA-controlled vault token account. Must be called once by admin. + +**Accounts:** +- `admin` - Signer, pays for account creation +- `mint` - USDC mint address +- `vault_state` - PDA storing vault metadata +- `vault` - PDA token account for holding USDC + +### `deposit` +Deposits USDC into a market position. + +**Args:** +- `amount` - Amount in USDC lamports (6 decimals) +- `market_id` - String identifier for the market +- `position` - `Yes` (0) or `No` (1) + +**Accounts:** +- `user` - Signer making the deposit +- `mint` - USDC mint +- `vault_state` - Vault state PDA +- `vault` - Vault token account PDA +- `user_token_account` - User's USDC token account +- `user_deposit` - PDA tracking user's deposit for this market/position + +### `withdraw` +Withdraws USDC from a market position. + +**Args:** +- `amount` - Amount to withdraw in USDC lamports + +## Important Addresses + +### Devnet USDC Mint +``` +4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU +``` + +### Getting Devnet USDC + +You can get Devnet USDC from: +1. [Circle's Devnet Faucet](https://faucet.circle.com/) +2. [Solana Devnet Faucet with SPL tokens](https://spl-token-faucet.com/) + +## Testing + +```bash +# Run all tests +anchor test + +# Run tests without starting local validator (uses devnet) +anchor test --skip-local-validator +``` + +## Vault Security Model + +``` +┌─────────────────────────────────────────────────────────────┐ +│ POLYIELD VAULT │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ User A ──────┐ │ +│ │ │ +│ User B ──────┼──► USDC ──► [Vault PDA] ◄── Program Only │ +│ │ │ │ +│ User C ──────┘ │ │ +│ ▼ │ +│ ┌──────────────┐ │ +│ │ User Deposit │ │ +│ │ PDAs │ │ +│ │ (Records) │ │ +│ └──────────────┘ │ +│ │ +│ • No admin can withdraw user funds arbitrarily │ +│ • All deposits tracked per-user, per-market, per-position │ +│ • Program logic controls all fund movements │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` diff --git a/programs/polyield_vault/Cargo.toml b/programs/polyield_vault/Cargo.toml new file mode 100644 index 0000000..b528dba --- /dev/null +++ b/programs/polyield_vault/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "polyield_vault" +version = "0.1.0" +description = "Polyield USDC Vault Program for prediction market deposits" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "polyield_vault" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +anchor-lang = "0.30.1" +anchor-spl = "0.30.1" diff --git a/programs/polyield_vault/Xargo.toml b/programs/polyield_vault/Xargo.toml new file mode 100644 index 0000000..475fb71 --- /dev/null +++ b/programs/polyield_vault/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/programs/polyield_vault/src/lib.rs b/programs/polyield_vault/src/lib.rs new file mode 100644 index 0000000..3e986fa --- /dev/null +++ b/programs/polyield_vault/src/lib.rs @@ -0,0 +1,282 @@ +use anchor_lang::prelude::*; +use anchor_spl::{ + associated_token::AssociatedToken, + token_interface::{ + transfer_checked, Mint, TokenAccount, TokenInterface, TransferChecked, + }, +}; + +declare_id!("YourProgramIdHere11111111111111111111111111"); + +#[program] +pub mod polyield_vault { + use super::*; + + /// Initialize the vault state and create the PDA-controlled token vault + pub fn initialize(ctx: Context) -> Result<()> { + let vault_state = &mut ctx.accounts.vault_state; + vault_state.admin = ctx.accounts.admin.key(); + vault_state.mint = ctx.accounts.mint.key(); + vault_state.vault_bump = ctx.bumps.vault; + vault_state.state_bump = ctx.bumps.vault_state; + vault_state.total_deposits = 0; + + msg!("Vault initialized for mint: {}", ctx.accounts.mint.key()); + Ok(()) + } + + /// Deposit USDC into a market position (YES or NO) + pub fn deposit( + ctx: Context, + amount: u64, + market_id: String, + position: Position, + ) -> Result<()> { + require!(amount > 0, VaultError::InvalidAmount); + require!(market_id.len() <= 64, VaultError::MarketIdTooLong); + + // Transfer USDC from user to vault + let cpi_accounts = TransferChecked { + from: ctx.accounts.user_token_account.to_account_info(), + to: ctx.accounts.vault.to_account_info(), + authority: ctx.accounts.user.to_account_info(), + mint: ctx.accounts.mint.to_account_info(), + }; + let cpi_program = ctx.accounts.token_program.to_account_info(); + let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); + + transfer_checked(cpi_ctx, amount, ctx.accounts.mint.decimals)?; + + // Update user deposit record + let user_deposit = &mut ctx.accounts.user_deposit; + user_deposit.user = ctx.accounts.user.key(); + user_deposit.market_id = market_id.clone(); + user_deposit.position = position; + user_deposit.amount = user_deposit.amount.checked_add(amount).ok_or(VaultError::Overflow)?; + user_deposit.timestamp = Clock::get()?.unix_timestamp; + user_deposit.bump = ctx.bumps.user_deposit; + + // Update vault state + let vault_state = &mut ctx.accounts.vault_state; + vault_state.total_deposits = vault_state + .total_deposits + .checked_add(amount) + .ok_or(VaultError::Overflow)?; + + msg!( + "Deposited {} USDC to {} position for market {}", + amount, + match position { + Position::Yes => "YES", + Position::No => "NO", + }, + market_id + ); + + Ok(()) + } + + /// Withdraw USDC from a market position (for market resolution or cancellation) + pub fn withdraw(ctx: Context, amount: u64) -> Result<()> { + let user_deposit = &mut ctx.accounts.user_deposit; + + require!(amount > 0, VaultError::InvalidAmount); + require!(amount <= user_deposit.amount, VaultError::InsufficientFunds); + + // Create signer seeds for PDA + let mint_key = ctx.accounts.mint.key(); + let seeds = &[ + b"vault", + mint_key.as_ref(), + &[ctx.accounts.vault_state.vault_bump], + ]; + let signer_seeds = &[&seeds[..]]; + + // Transfer USDC from vault to user + let cpi_accounts = TransferChecked { + from: ctx.accounts.vault.to_account_info(), + to: ctx.accounts.user_token_account.to_account_info(), + authority: ctx.accounts.vault.to_account_info(), + mint: ctx.accounts.mint.to_account_info(), + }; + let cpi_program = ctx.accounts.token_program.to_account_info(); + let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer_seeds); + + transfer_checked(cpi_ctx, amount, ctx.accounts.mint.decimals)?; + + // Update user deposit record + user_deposit.amount = user_deposit.amount.checked_sub(amount).ok_or(VaultError::Underflow)?; + + // Update vault state + let vault_state = &mut ctx.accounts.vault_state; + vault_state.total_deposits = vault_state + .total_deposits + .checked_sub(amount) + .ok_or(VaultError::Underflow)?; + + msg!("Withdrew {} USDC", amount); + + Ok(()) + } +} + +#[derive(Accounts)] +pub struct Initialize<'info> { + #[account(mut)] + pub admin: Signer<'info>, + + pub mint: InterfaceAccount<'info, Mint>, + + #[account( + init, + payer = admin, + space = 8 + VaultState::INIT_SPACE, + seeds = [b"vault_state", mint.key().as_ref()], + bump, + )] + pub vault_state: Account<'info, VaultState>, + + #[account( + init, + payer = admin, + seeds = [b"vault", mint.key().as_ref()], + bump, + token::mint = mint, + token::authority = vault, + token::token_program = token_program, + )] + pub vault: InterfaceAccount<'info, TokenAccount>, + + pub token_program: Interface<'info, TokenInterface>, + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +#[instruction(amount: u64, market_id: String, position: Position)] +pub struct Deposit<'info> { + #[account(mut)] + pub user: Signer<'info>, + + pub mint: InterfaceAccount<'info, Mint>, + + #[account( + mut, + seeds = [b"vault_state", mint.key().as_ref()], + bump = vault_state.state_bump, + )] + pub vault_state: Account<'info, VaultState>, + + #[account( + mut, + seeds = [b"vault", mint.key().as_ref()], + bump = vault_state.vault_bump, + )] + pub vault: InterfaceAccount<'info, TokenAccount>, + + #[account( + mut, + associated_token::mint = mint, + associated_token::authority = user, + associated_token::token_program = token_program, + )] + pub user_token_account: InterfaceAccount<'info, TokenAccount>, + + #[account( + init_if_needed, + payer = user, + space = 8 + UserDeposit::INIT_SPACE, + seeds = [b"user_deposit", user.key().as_ref(), market_id.as_bytes(), &[position as u8]], + bump, + )] + pub user_deposit: Account<'info, UserDeposit>, + + pub token_program: Interface<'info, TokenInterface>, + pub associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Withdraw<'info> { + #[account(mut)] + pub user: Signer<'info>, + + pub mint: InterfaceAccount<'info, Mint>, + + #[account( + mut, + seeds = [b"vault_state", mint.key().as_ref()], + bump = vault_state.state_bump, + )] + pub vault_state: Account<'info, VaultState>, + + #[account( + mut, + seeds = [b"vault", mint.key().as_ref()], + bump = vault_state.vault_bump, + )] + pub vault: InterfaceAccount<'info, TokenAccount>, + + #[account( + mut, + associated_token::mint = mint, + associated_token::authority = user, + associated_token::token_program = token_program, + )] + pub user_token_account: InterfaceAccount<'info, TokenAccount>, + + #[account( + mut, + seeds = [b"user_deposit", user.key().as_ref(), user_deposit.market_id.as_bytes(), &[user_deposit.position as u8]], + bump = user_deposit.bump, + constraint = user_deposit.user == user.key() @ VaultError::Unauthorized, + )] + pub user_deposit: Account<'info, UserDeposit>, + + pub token_program: Interface<'info, TokenInterface>, + pub associated_token_program: Program<'info, AssociatedToken>, + pub system_program: Program<'info, System>, +} + +#[account] +#[derive(InitSpace)] +pub struct VaultState { + pub admin: Pubkey, + pub mint: Pubkey, + pub vault_bump: u8, + pub state_bump: u8, + pub total_deposits: u64, +} + +#[account] +#[derive(InitSpace)] +pub struct UserDeposit { + pub user: Pubkey, + #[max_len(64)] + pub market_id: String, + pub position: Position, + pub amount: u64, + pub timestamp: i64, + pub bump: u8, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq, InitSpace)] +pub enum Position { + Yes = 0, + No = 1, +} + +#[error_code] +pub enum VaultError { + #[msg("Invalid deposit amount")] + InvalidAmount, + #[msg("Market ID too long (max 64 chars)")] + MarketIdTooLong, + #[msg("Arithmetic overflow")] + Overflow, + #[msg("Arithmetic underflow")] + Underflow, + #[msg("Insufficient funds")] + InsufficientFunds, + #[msg("Unauthorized")] + Unauthorized, +} diff --git a/target/idl/polyield_vault.json b/target/idl/polyield_vault.json new file mode 100644 index 0000000..32d2152 --- /dev/null +++ b/target/idl/polyield_vault.json @@ -0,0 +1,361 @@ +{ + "address": "YourProgramIdHere11111111111111111111111111", + "metadata": { + "name": "polyield_vault", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Polyield USDC Vault Program for prediction market deposits" + }, + "instructions": [ + { + "name": "initialize", + "discriminator": [175, 175, 109, 31, 13, 152, 155, 237], + "accounts": [ + { + "name": "admin", + "writable": true, + "signer": true + }, + { + "name": "mint" + }, + { + "name": "vault_state", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "vault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "token_program" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [] + }, + { + "name": "deposit", + "discriminator": [242, 35, 198, 137, 82, 225, 242, 182], + "accounts": [ + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "mint" + }, + { + "name": "vault_state", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "vault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "user_token_account", + "writable": true + }, + { + "name": "user_deposit", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [117, 115, 101, 114, 95, 100, 101, 112, 111, 115, 105, 116] + }, + { + "kind": "account", + "path": "user" + }, + { + "kind": "arg", + "path": "market_id" + }, + { + "kind": "arg", + "path": "position" + } + ] + } + }, + { + "name": "token_program" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "market_id", + "type": "string" + }, + { + "name": "position", + "type": { + "defined": { + "name": "Position" + } + } + } + ] + }, + { + "name": "withdraw", + "discriminator": [183, 18, 70, 156, 148, 109, 161, 34], + "accounts": [ + { + "name": "user", + "writable": true, + "signer": true + }, + { + "name": "mint" + }, + { + "name": "vault_state", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "vault", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [118, 97, 117, 108, 116] + }, + { + "kind": "account", + "path": "mint" + } + ] + } + }, + { + "name": "user_token_account", + "writable": true + }, + { + "name": "user_deposit", + "writable": true + }, + { + "name": "token_program" + }, + { + "name": "associated_token_program", + "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + } + ] + } + ], + "accounts": [ + { + "name": "UserDeposit", + "discriminator": [115, 52, 93, 226, 80, 155, 117, 246] + }, + { + "name": "VaultState", + "discriminator": [228, 196, 82, 165, 98, 210, 235, 152] + } + ], + "errors": [ + { + "code": 6000, + "name": "InvalidAmount", + "msg": "Invalid deposit amount" + }, + { + "code": 6001, + "name": "MarketIdTooLong", + "msg": "Market ID too long (max 64 chars)" + }, + { + "code": 6002, + "name": "Overflow", + "msg": "Arithmetic overflow" + }, + { + "code": 6003, + "name": "Underflow", + "msg": "Arithmetic underflow" + }, + { + "code": 6004, + "name": "InsufficientFunds", + "msg": "Insufficient funds" + }, + { + "code": 6005, + "name": "Unauthorized", + "msg": "Unauthorized" + } + ], + "types": [ + { + "name": "Position", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Yes" + }, + { + "name": "No" + } + ] + } + }, + { + "name": "UserDeposit", + "type": { + "kind": "struct", + "fields": [ + { + "name": "user", + "type": "pubkey" + }, + { + "name": "market_id", + "type": "string" + }, + { + "name": "position", + "type": { + "defined": { + "name": "Position" + } + } + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "timestamp", + "type": "i64" + }, + { + "name": "bump", + "type": "u8" + } + ] + } + }, + { + "name": "VaultState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "admin", + "type": "pubkey" + }, + { + "name": "mint", + "type": "pubkey" + }, + { + "name": "vault_bump", + "type": "u8" + }, + { + "name": "state_bump", + "type": "u8" + }, + { + "name": "total_deposits", + "type": "u64" + } + ] + } + } + ] +} diff --git a/tests/polyield_vault.ts b/tests/polyield_vault.ts new file mode 100644 index 0000000..23a6246 --- /dev/null +++ b/tests/polyield_vault.ts @@ -0,0 +1,195 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { PublicKey, Keypair, SystemProgram } from "@solana/web3.js"; +import { + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID, + getAssociatedTokenAddress, +} from "@solana/spl-token"; +import { expect } from "chai"; + +// Devnet USDC Mint +const USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"); + +describe("polyield_vault", () => { + // Configure the client to use devnet + const provider = anchor.AnchorProvider.env(); + anchor.setProvider(provider); + + const program = anchor.workspace.PolyieldVault as Program; + + // PDAs + let vaultPDA: PublicKey; + let vaultStatePDA: PublicKey; + let vaultBump: number; + let vaultStateBump: number; + + before(async () => { + // Derive PDAs + [vaultPDA, vaultBump] = PublicKey.findProgramAddressSync( + [Buffer.from("vault"), USDC_MINT.toBuffer()], + program.programId + ); + + [vaultStatePDA, vaultStateBump] = PublicKey.findProgramAddressSync( + [Buffer.from("vault_state"), USDC_MINT.toBuffer()], + program.programId + ); + + console.log("Program ID:", program.programId.toBase58()); + console.log("Vault PDA:", vaultPDA.toBase58()); + console.log("Vault State PDA:", vaultStatePDA.toBase58()); + }); + + it("Initializes the vault", async () => { + try { + const tx = await program.methods + .initialize() + .accounts({ + admin: provider.wallet.publicKey, + mint: USDC_MINT, + vaultState: vaultStatePDA, + vault: vaultPDA, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }) + .rpc(); + + console.log("Initialize tx:", tx); + + // Verify vault state + const vaultState = await program.account.vaultState.fetch(vaultStatePDA); + expect(vaultState.admin.toBase58()).to.equal(provider.wallet.publicKey.toBase58()); + expect(vaultState.mint.toBase58()).to.equal(USDC_MINT.toBase58()); + expect(vaultState.totalDeposits.toNumber()).to.equal(0); + + console.log("Vault initialized successfully!"); + } catch (error: any) { + // If vault already initialized, that's okay + if (error.message?.includes("already in use")) { + console.log("Vault already initialized"); + } else { + throw error; + } + } + }); + + it("Deposits USDC to YES position", async () => { + const user = provider.wallet.publicKey; + const marketId = "test-market-1"; + const amount = new anchor.BN(1_000_000); // 1 USDC (6 decimals) + + // Derive user deposit PDA + const [userDepositPDA] = PublicKey.findProgramAddressSync( + [ + Buffer.from("user_deposit"), + user.toBuffer(), + Buffer.from(marketId), + Buffer.from([0]), // Position::Yes = 0 + ], + program.programId + ); + + // Get user's USDC token account + const userTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + user + ); + + console.log("User Token Account:", userTokenAccount.toBase58()); + console.log("User Deposit PDA:", userDepositPDA.toBase58()); + + try { + const tx = await program.methods + .deposit(amount, marketId, { yes: {} }) + .accounts({ + user: user, + mint: USDC_MINT, + vaultState: vaultStatePDA, + vault: vaultPDA, + userTokenAccount: userTokenAccount, + userDeposit: userDepositPDA, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }) + .rpc(); + + console.log("Deposit tx:", tx); + + // Verify user deposit + const userDeposit = await program.account.userDeposit.fetch(userDepositPDA); + expect(userDeposit.user.toBase58()).to.equal(user.toBase58()); + expect(userDeposit.marketId).to.equal(marketId); + expect(userDeposit.amount.toNumber()).to.be.at.least(amount.toNumber()); + + console.log("Deposit successful!"); + console.log("User deposit amount:", userDeposit.amount.toNumber() / 1_000_000, "USDC"); + } catch (error: any) { + console.error("Deposit failed:", error.message); + // This might fail if user doesn't have USDC - that's expected in test environment + if (error.message?.includes("insufficient funds") || + error.message?.includes("0x1")) { + console.log("Note: User needs devnet USDC to test deposits"); + console.log("Get devnet USDC from: https://faucet.circle.com/"); + } + } + }); + + it("Withdraws USDC from YES position", async () => { + const user = provider.wallet.publicKey; + const marketId = "test-market-1"; + const amount = new anchor.BN(500_000); // 0.5 USDC + + // Derive user deposit PDA + const [userDepositPDA] = PublicKey.findProgramAddressSync( + [ + Buffer.from("user_deposit"), + user.toBuffer(), + Buffer.from(marketId), + Buffer.from([0]), // Position::Yes = 0 + ], + program.programId + ); + + // Get user's USDC token account + const userTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + user + ); + + try { + // Check if user has a deposit first + const userDeposit = await program.account.userDeposit.fetch(userDepositPDA); + + if (userDeposit.amount.toNumber() < amount.toNumber()) { + console.log("Not enough deposited to withdraw"); + return; + } + + const tx = await program.methods + .withdraw(amount) + .accounts({ + user: user, + mint: USDC_MINT, + vaultState: vaultStatePDA, + vault: vaultPDA, + userTokenAccount: userTokenAccount, + userDeposit: userDepositPDA, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }) + .rpc(); + + console.log("Withdraw tx:", tx); + console.log("Withdrawal successful!"); + } catch (error: any) { + console.error("Withdraw failed:", error.message); + // Expected if no deposit exists + if (error.message?.includes("AccountNotInitialized")) { + console.log("No deposit found to withdraw from"); + } + } + }); +}); From 44e1ce38516034897c14f3f0bda6045828da66af Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sat, 17 Jan 2026 20:27:04 -0500 Subject: [PATCH 02/26] vault --- DEVNET_SETUP.md | 335 ++++++++++++++++++++++++++++++++++++ QUICKSTART.md | 212 +++++++++++++++++++++++ SETUP_CHECKLIST.md | 161 +++++++++++++++++ scripts/initialize-vault.ts | 94 ++++++++++ 4 files changed, 802 insertions(+) create mode 100644 DEVNET_SETUP.md create mode 100644 QUICKSTART.md create mode 100644 SETUP_CHECKLIST.md create mode 100644 scripts/initialize-vault.ts diff --git a/DEVNET_SETUP.md b/DEVNET_SETUP.md new file mode 100644 index 0000000..019041e --- /dev/null +++ b/DEVNET_SETUP.md @@ -0,0 +1,335 @@ +# Solana Devnet Testing Setup Guide + +## Prerequisites Installation + +### 1. Install Solana CLI + +**Option A: Using Official Installer (Recommended)** +1. Download from: https://github.com/solana-labs/solana/releases +2. Get the latest `solana-install-init-x86_64-pc-windows-msvc.exe` +3. Run the installer +4. Restart your terminal/PowerShell + +**Option B: Using Chocolatey** +```powershell +choco install solana +``` + +**Option C: Manual Install via PowerShell** +```powershell +# Download and run the installer +cmd /c "curl https://release.solana.com/v1.18.4/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-installer.exe" +C:\solana-installer.exe v1.18.4 +``` + +After installation, verify: +```bash +solana --version +``` + +### 2. Install Anchor CLI (for deploying the program) + +First, ensure you have Rust installed: +```bash +rustc --version +``` + +If not, install Rust from: https://rustup.rs/ + +Then install Anchor: +```bash +cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked +``` + +## Devnet Configuration + +### 1. Configure Solana for Devnet +```bash +# Set cluster to devnet +solana config set --url devnet + +# Verify configuration +solana config get +``` + +### 2. Create a Keypair (Wallet) +```bash +# Create a new keypair +solana-keygen new --outfile ~/.config/solana/id.json + +# Or if you want to recover from seed phrase +solana-keygen recover --outfile ~/.config/solana/id.json +``` + +Save your seed phrase securely! + +### 3. Check Your Address +```bash +solana address +``` + +### 4. Get Devnet SOL (Airdrop) +```bash +# Request 2 SOL (for transaction fees) +solana airdrop 2 + +# Check balance +solana balance +``` + +If airdrop doesn't work, try: +- https://faucet.solana.com/ +- https://solfaucet.com/ + +### 5. Get Devnet USDC + +**Devnet USDC Mint:** `4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU` + +You can get devnet USDC from: +1. **Circle's Faucet**: https://faucet.circle.com/ (select Solana Devnet) +2. **SPL Token Faucet**: https://spl-token-faucet.com/?token-name=USDC +3. **Manually create and mint** (if you have SOL): + +```bash +# Create USDC token account for yourself +spl-token create-account 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU + +# Check your USDC balance +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU +``` + +## Deploy the Anchor Program + +### 1. Build the Program +```bash +cd C:\Users\1arya\OneDrive\Desktop\polyield\polyield +anchor build +``` + +### 2. Get Your Program ID +```bash +anchor keys list +``` + +Output will show: +``` +polyield_vault: +``` + +### 3. Update Program ID in Code + +Update these files with your actual program ID: + +**File: `programs/polyield_vault/src/lib.rs`** +```rust +declare_id!("YOUR_PROGRAM_ID_HERE"); +``` + +**File: `Anchor.toml`** +```toml +[programs.devnet] +polyield_vault = "YOUR_PROGRAM_ID_HERE" +``` + +**File: `lib/solana/constants.ts`** +```typescript +export const PROGRAM_ID = new PublicKey("YOUR_PROGRAM_ID_HERE") +``` + +### 4. Rebuild with Correct ID +```bash +anchor build +``` + +### 5. Deploy to Devnet +```bash +anchor deploy +``` + +This will output your program address. Save it! + +### 6. Initialize the Vault + +Create a script `scripts/initialize-vault.ts`: +```typescript +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; + +const USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"); + +async function main() { + const provider = anchor.AnchorProvider.env(); + anchor.setProvider(provider); + + const program = anchor.workspace.PolyieldVault as Program; + + const [vaultPDA] = PublicKey.findProgramAddressSync( + [Buffer.from("vault"), USDC_MINT.toBuffer()], + program.programId + ); + + const [vaultStatePDA] = PublicKey.findProgramAddressSync( + [Buffer.from("vault_state"), USDC_MINT.toBuffer()], + program.programId + ); + + console.log("Initializing vault..."); + console.log("Vault PDA:", vaultPDA.toBase58()); + console.log("Vault State PDA:", vaultStatePDA.toBase58()); + + const tx = await program.methods + .initialize() + .accounts({ + admin: provider.wallet.publicKey, + mint: USDC_MINT, + vaultState: vaultStatePDA, + vault: vaultPDA, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }) + .rpc(); + + console.log("✅ Vault initialized!"); + console.log("Transaction:", tx); + console.log("View on Solscan:", `https://solscan.io/tx/${tx}?cluster=devnet`); +} + +main(); +``` + +Run it: +```bash +npx ts-node scripts/initialize-vault.ts +``` + +## Setup Phantom Wallet for Devnet + +### 1. Install Phantom +- Download from: https://phantom.app/ +- Install the browser extension + +### 2. Configure for Devnet +1. Open Phantom +2. Click Settings (gear icon) +3. Scroll to "Developer Settings" +4. Enable "Testnet Mode" +5. Select "Devnet" from the network dropdown + +### 3. Import Your Keypair (Optional) +To use your CLI wallet in Phantom: +1. Get your private key: +```bash +solana-keygen pubkey ~/.config/solana/id.json --outfile /dev/stdout +cat ~/.config/solana/id.json +``` +2. In Phantom: Settings → Add/Import Wallet → Import Private Key +3. Paste the base58 encoded private key + +### 4. Get Test Funds in Phantom +- Your devnet SOL and USDC should show up +- If not, airdrop more SOL or get USDC from faucets + +## Testing the App + +### 1. Start the Dev Server +```bash +cd C:\Users\1arya\OneDrive\Desktop\polyield\polyield +pnpm run dev +``` + +### 2. Open in Browser +Go to: http://localhost:3001/markets + +### 3. Connect Phantom +1. Click "Select Wallet" +2. Choose Phantom +3. Approve connection +4. Make sure you're on Devnet in Phantom + +### 4. Make a Test Deposit +1. Click "Predict Yes" or "Predict No" on any market +2. Click "[Deposit to Yes/No]" +3. Enter amount (e.g., 1 USDC) +4. Click "Deposit X USDC" +5. Approve transaction in Phantom +6. Wait for confirmation + +### 5. View on Solscan +After transaction confirms, click the "View on Solscan" link or go to: +``` +https://solscan.io/account/YOUR_WALLET_ADDRESS?cluster=devnet +``` + +## Useful Commands + +### Check Wallet Info +```bash +# Your address +solana address + +# SOL balance +solana balance + +# USDC balance +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU + +# All token accounts +spl-token accounts +``` + +### View Program Account +```bash +solana account +``` + +### View Recent Transactions +```bash +solana transaction-history $(solana address) --limit 10 +``` + +### Check Vault Balance +```bash +# Get vault PDA address from deployment logs +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU --owner +``` + +## Troubleshooting + +### "AccountNotFound" Error +- Make sure vault is initialized +- Check you have devnet USDC in your wallet +- Verify you're on devnet network + +### "InsufficientFunds" Error +- Get more devnet SOL via airdrop +- Get devnet USDC from faucets + +### Transaction Fails +- Check Solscan for detailed error logs +- Ensure program ID is correct in all files +- Verify vault was initialized + +### Can't See USDC in Phantom +- Make sure Phantom is on Devnet mode +- Create USDC token account if needed +- Refresh the wallet + +## Important Links + +- **Devnet Solscan**: https://solscan.io/?cluster=devnet +- **Devnet Explorer**: https://explorer.solana.com/?cluster=devnet +- **SOL Faucet**: https://faucet.solana.com/ +- **Circle USDC Faucet**: https://faucet.circle.com/ +- **SPL Token Faucet**: https://spl-token-faucet.com/ + +## Next Steps + +Once testing is complete on devnet: +1. Test all deposit/withdraw scenarios +2. Verify transactions on Solscan +3. Check vault balances +4. Test with multiple users +5. Document any issues +6. Prepare for mainnet deployment (if applicable) diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..3c4fdac --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,212 @@ +# 🚀 Quick Start - Testing on Devnet + +## Step-by-Step Guide + +### 1️⃣ Install Solana CLI +```powershell +# Download and install +cmd /c "curl https://release.solana.com/v1.18.4/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-installer.exe" +C:\solana-installer.exe v1.18.4 +``` + +**Restart your terminal after installation!** + +### 2️⃣ Configure for Devnet +```bash +solana config set --url devnet +solana config get +``` + +### 3️⃣ Create Wallet & Get SOL +```bash +# Create keypair (save the seed phrase!) +solana-keygen new + +# Get your address +solana address + +# Get devnet SOL +solana airdrop 2 + +# Check balance +solana balance +``` + +### 4️⃣ Get Devnet USDC +Visit: https://faucet.circle.com/ +- Select "Solana Devnet" +- Paste your wallet address (from `solana address`) +- Request USDC + +Or use: https://spl-token-faucet.com/?token-name=USDC + +### 5️⃣ Install Anchor (if not installed) +```bash +# Check if Rust is installed +rustc --version + +# If not, install from: https://rustup.rs/ + +# Then install Anchor +cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked +``` + +### 6️⃣ Build & Deploy Program +```bash +cd C:\Users\1arya\OneDrive\Desktop\polyield\polyield + +# Build +anchor build + +# Get program ID +anchor keys list +# Save the output: polyield_vault: +``` + +### 7️⃣ Update Program ID + +**Update these 3 files with your program ID:** + +1. `programs/polyield_vault/src/lib.rs` - line 8: +```rust +declare_id!("YOUR_PROGRAM_ID"); +``` + +2. `Anchor.toml` - line 7: +```toml +polyield_vault = "YOUR_PROGRAM_ID" +``` + +3. `lib/solana/constants.ts` - line 14: +```typescript +export const PROGRAM_ID = new PublicKey("YOUR_PROGRAM_ID") +``` + +### 8️⃣ Rebuild & Deploy +```bash +# Rebuild with correct ID +anchor build + +# Deploy to devnet +anchor deploy + +# You'll see: "Program Id: " +``` + +### 9️⃣ Initialize Vault +```bash +# Install dependencies if needed +pnpm install + +# Run initialization script +anchor run initialize + +# Or manually: +npx ts-node scripts/initialize-vault.ts +``` + +You should see: +``` +✅ Vault initialized successfully! +🔍 View on Solscan: https://solscan.io/tx/...?cluster=devnet +``` + +### 🔟 Setup Phantom Wallet + +1. Install Phantom: https://phantom.app/ +2. Open Phantom → Settings → Developer Settings +3. Enable "Testnet Mode" +4. Select "Devnet" network +5. Import your wallet (optional): + - Get private key: `cat ~/.config/solana/id.json` + - Phantom → Settings → Add Wallet → Import Private Key + +### 1️⃣1️⃣ Test the App! + +```bash +# Start dev server +pnpm run dev + +# Open browser +# Go to: http://localhost:3001/markets +``` + +**In the app:** +1. Click "Select Wallet" → Choose Phantom +2. Approve connection (make sure Phantom is on Devnet!) +3. Click "Predict Yes" or "Predict No" +4. Click "[Deposit to Yes/No]" +5. Enter amount (e.g., 1.00 USDC) +6. Click "Deposit X USDC" +7. Approve in Phantom +8. Wait for confirmation +9. Click "View on Solscan" to see transaction! + +## 🔍 Verify Everything Works + +### Check Your USDC Balance +```bash +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU +``` + +### View on Solscan +```bash +# Your wallet +https://solscan.io/account/?cluster=devnet + +# Your transactions +https://solscan.io/account//transactions?cluster=devnet +``` + +### Check Vault PDA +After deployment, check vault balance: +```bash +# Get vault PDA from initialization logs +https://solscan.io/account/?cluster=devnet +``` + +## 🆘 Common Issues + +**"solana: command not found"** +- Restart terminal after installing +- Add to PATH: `C:\Users\\.local\share\solana\install\active_release\bin` + +**"Airdrop failed"** +- Use web faucet: https://faucet.solana.com/ +- Or try: `solana airdrop 1` (smaller amount) + +**"Insufficient funds for rent"** +- You need SOL for transaction fees +- Run: `solana airdrop 2` + +**"Account not found" in app** +- Make sure Phantom is on Devnet +- Initialize vault first +- Check you have USDC in wallet + +**Transaction fails** +- Check Solscan for error details +- Verify program ID matches in all files +- Ensure vault is initialized + +## 📝 Next Steps + +Once you confirm everything works: +1. ✅ Test deposits +2. ✅ Test withdrawals (add UI for this) +3. ✅ Test multiple markets +4. ✅ Verify Solscan shows correct data +5. ✅ Document any issues +6. ✅ Consider mainnet deployment strategy + +## 🔗 Useful Links + +- **Solscan Devnet**: https://solscan.io/?cluster=devnet +- **Solana Explorer**: https://explorer.solana.com/?cluster=devnet +- **SOL Faucet**: https://faucet.solana.com/ +- **USDC Faucet**: https://faucet.circle.com/ +- **Phantom**: https://phantom.app/ + +--- + +**Need help?** Check `DEVNET_SETUP.md` for detailed instructions! diff --git a/SETUP_CHECKLIST.md b/SETUP_CHECKLIST.md new file mode 100644 index 0000000..341a246 --- /dev/null +++ b/SETUP_CHECKLIST.md @@ -0,0 +1,161 @@ +# 📋 Devnet Setup Checklist + +## ✅ Installation Progress + +### Step 1: Install Solana CLI +- [ ] Download from: https://github.com/solana-labs/solana/releases/latest +- [ ] Get file: `solana-install-init-x86_64-pc-windows-msvc.exe` +- [ ] Run the installer +- [ ] **RESTART TERMINAL** (important!) +- [ ] Verify: `solana --version` + +### Step 2: Configure Solana +```bash +solana config set --url devnet +solana config get +``` + +### Step 3: Create Wallet +```bash +solana-keygen new +# ⚠️ SAVE YOUR SEED PHRASE! +``` + +### Step 4: Get Devnet SOL +```bash +solana airdrop 2 +solana balance +``` + +### Step 5: Get Your Wallet Address +```bash +solana address +# Copy this address for the faucet! +``` + +### Step 6: Get Devnet USDC +- [ ] Visit: https://faucet.circle.com/ +- [ ] Select "Solana Devnet" +- [ ] Paste your wallet address +- [ ] Request USDC +- [ ] Wait for confirmation + +### Step 7: Verify USDC Balance +```bash +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU +``` + +### Step 8: Install Rust (if needed) +- [ ] Check: `rustc --version` +- [ ] If not installed: https://rustup.rs/ +- [ ] Restart terminal after installing + +### Step 9: Install Anchor CLI +```bash +cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked +# This takes 10-20 minutes +``` + +### Step 10: Build Program +```bash +cd C:\Users\1arya\OneDrive\Desktop\polyield\polyield +anchor build +``` + +### Step 11: Get Program ID +```bash +anchor keys list +# Output: polyield_vault: +# COPY THIS ID! +``` + +### Step 12: Update Program ID in Code +Update in these 3 files: +1. `programs/polyield_vault/src/lib.rs` (line 8) +2. `Anchor.toml` (line 7) +3. `lib/solana/constants.ts` (line 14) + +### Step 13: Rebuild & Deploy +```bash +anchor build +anchor deploy +``` + +### Step 14: Initialize Vault +```bash +npx ts-node scripts/initialize-vault.ts +``` + +### Step 15: Setup Phantom Wallet +- [ ] Install: https://phantom.app/ +- [ ] Open Phantom +- [ ] Settings → Developer Settings +- [ ] Enable "Testnet Mode" +- [ ] Select "Devnet" network +- [ ] Verify your USDC shows up + +### Step 16: Test the App! +```bash +pnpm run dev +# Go to http://localhost:3001/markets +``` + +- [ ] Connect Phantom +- [ ] Make a test deposit +- [ ] View transaction on Solscan + +## 🔗 Important Links + +- **Solana Downloads**: https://github.com/solana-labs/solana/releases/latest +- **Circle Faucet**: https://faucet.circle.com/ +- **SOL Faucet**: https://faucet.solana.com/ +- **Phantom Wallet**: https://phantom.app/ +- **Solscan Devnet**: https://solscan.io/?cluster=devnet + +## 📝 Your Info (Fill in as you go) + +**Wallet Address**: +``` +(Run: solana address) +``` + +**Program ID**: +``` +(Run: anchor keys list) +``` + +**Vault PDA**: +``` +(From initialization script output) +``` + +## 🆘 Commands Reference + +```bash +# Check Solana config +solana config get + +# Check SOL balance +solana balance + +# Check USDC balance +spl-token balance 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU + +# View transactions +solana transaction-history $(solana address) --limit 5 + +# Build program +anchor build + +# Deploy program +anchor deploy + +# Test program +anchor test --skip-local-validator +``` + +--- + +**Current Status**: Installing Solana CLI... + +**Next**: After installing, restart terminal and run the configuration commands! diff --git a/scripts/initialize-vault.ts b/scripts/initialize-vault.ts new file mode 100644 index 0000000..14f8167 --- /dev/null +++ b/scripts/initialize-vault.ts @@ -0,0 +1,94 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; + +const USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"); + +async function main() { + // Configure the client to use devnet + const provider = anchor.AnchorProvider.env(); + anchor.setProvider(provider); + + const program = anchor.workspace.PolyieldVault as Program; + + console.log("Program ID:", program.programId.toBase58()); + console.log("Admin:", provider.wallet.publicKey.toBase58()); + + // Derive PDAs + const [vaultPDA, vaultBump] = PublicKey.findProgramAddressSync( + [Buffer.from("vault"), USDC_MINT.toBuffer()], + program.programId + ); + + const [vaultStatePDA, vaultStateBump] = PublicKey.findProgramAddressSync( + [Buffer.from("vault_state"), USDC_MINT.toBuffer()], + program.programId + ); + + console.log("\n📍 PDAs:"); + console.log("Vault PDA:", vaultPDA.toBase58()); + console.log("Vault State PDA:", vaultStatePDA.toBase58()); + console.log("Vault Bump:", vaultBump); + console.log("Vault State Bump:", vaultStateBump); + + console.log("\n🔨 Initializing vault..."); + + try { + const tx = await program.methods + .initialize() + .accounts({ + admin: provider.wallet.publicKey, + mint: USDC_MINT, + vaultState: vaultStatePDA, + vault: vaultPDA, + tokenProgram: TOKEN_PROGRAM_ID, + systemProgram: SystemProgram.programId, + }) + .rpc(); + + console.log("\n✅ Vault initialized successfully!"); + console.log("Transaction signature:", tx); + console.log("\n🔍 View on Solscan:"); + console.log(`https://solscan.io/tx/${tx}?cluster=devnet`); + console.log("\n📦 Vault Account:"); + console.log(`https://solscan.io/account/${vaultPDA.toBase58()}?cluster=devnet`); + + // Fetch and display vault state + const vaultState = await program.account.vaultState.fetch(vaultStatePDA); + console.log("\n📊 Vault State:"); + console.log("Admin:", vaultState.admin.toBase58()); + console.log("Mint:", vaultState.mint.toBase58()); + console.log("Total Deposits:", vaultState.totalDeposits.toString(), "USDC lamports"); + console.log("Vault Bump:", vaultState.vaultBump); + console.log("State Bump:", vaultState.stateBump); + } catch (error: any) { + if (error.message?.includes("already in use")) { + console.log("\n⚠️ Vault already initialized!"); + console.log("Fetching existing vault state..."); + + const vaultState = await program.account.vaultState.fetch(vaultStatePDA); + console.log("\n📊 Existing Vault State:"); + console.log("Admin:", vaultState.admin.toBase58()); + console.log("Mint:", vaultState.mint.toBase58()); + console.log("Total Deposits:", vaultState.totalDeposits.toString(), "USDC lamports"); + console.log("\n📦 Vault Account:"); + console.log(`https://solscan.io/account/${vaultPDA.toBase58()}?cluster=devnet`); + } else { + console.error("\n❌ Error initializing vault:"); + console.error(error); + throw error; + } + } +} + +console.log("🚀 Starting vault initialization...\n"); +main() + .then(() => { + console.log("\n✨ Done!"); + process.exit(0); + }) + .catch((error) => { + console.error("Error:", error); + process.exit(1); + }); From 1996a7f984ae14a9136775aef88ad08a01e9fd81 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sat, 17 Jan 2026 21:08:23 -0500 Subject: [PATCH 03/26] transactions working for vault + portfolio --- Anchor.toml | 5 +- Cargo.lock | 2652 +++++++++++++++++++++ app/positions/page.tsx | 20 + build.sh | 18 + components/deposit-modal.tsx | 117 +- components/header.tsx | 6 + components/market-card.tsx | 53 +- components/positions-list.tsx | 157 ++ hooks/use-positions.ts | 116 + lib/solana/constants.ts | 6 +- lib/solana/deposit.ts | 61 +- programs/polyield_vault/Cargo.toml | 2 +- programs/polyield_vault/src/lib.rs | 2 +- target/.rustc_info.json | 1 + target/deploy/polyield_vault-keypair.json | 1 + 15 files changed, 3151 insertions(+), 66 deletions(-) create mode 100644 Cargo.lock create mode 100644 app/positions/page.tsx create mode 100644 build.sh create mode 100644 components/positions-list.tsx create mode 100644 hooks/use-positions.ts create mode 100644 target/.rustc_info.json create mode 100644 target/deploy/polyield_vault-keypair.json diff --git a/Anchor.toml b/Anchor.toml index 827b8c0..c977e9b 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,9 +1,12 @@ +[toolchain] +anchor_version = "0.30.1" + [features] seeds = false skip-lint = false [programs.devnet] -polyield_vault = "YourProgramIdHere11111111111111111111111111" +polyield_vault = "FWGiD7WhXu8k7eDtEwr3ZbXbvqwL7kdJgNfugrSVJ7F3" [registry] url = "https://api.apr.dev" diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..132894c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2652 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anchor-attribute-access-control" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fe28365b33e8334dd70ae2f34a43892363012fe239cf37d2ee91693575b1f8" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c288d496168268d198d9b53ee9f4f9d260a55ba4df9877ea1d4486ad6109e0f" +dependencies = [ + "anchor-syn", + "bs58 0.5.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b77b6948d0eeaaa129ce79eea5bbbb9937375a9241d909ca8fb9e006bb6e90" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d20bb569c5a557c86101b944721d865e1fd0a4c67c381d31a44a84f07f84828" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cebd8d0671a3a9dc3160c48598d652c34c77de6be4d44345b8b514323284d57" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb2a5eb0860e661ab31aff7bb5e0288357b176380e985bade4ccb395981b42d" +dependencies = [ + "anchor-lang-idl", + "anchor-syn", + "anyhow", + "bs58 0.5.1", + "heck", + "proc-macro2", + "quote", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04368b5abef4266250ca8d1d12f4dff860242681e4ec22b885dcfe354fd35aa1" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0bb0e0911ad4a70cab880cdd6287fe1e880a1a9d8e4e6defa8e9044b9796a6c" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef415ff156dc82e9ecb943189b0cb241b3a6bfc26a180234dc21bd3ef3ce0cb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6620c9486d9d36a4389cab5e37dc34a42ed0bfaa62e6a75a2999ce98f8f2e373" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-serde", + "anchor-derive-space", + "arrayref", + "base64 0.21.7", + "bincode", + "borsh 0.10.4", + "bytemuck", + "getrandom 0.2.17", + "solana-program", + "thiserror", +] + +[[package]] +name = "anchor-lang-idl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418" +dependencies = [ + "anchor-lang-idl-spec", + "anyhow", + "heck", + "serde", + "serde_json", + "sha2 0.10.9", +] + +[[package]] +name = "anchor-lang-idl-spec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" +dependencies = [ + "anyhow", + "serde", +] + +[[package]] +name = "anchor-spl" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04bd077c34449319a1e4e0bc21cea572960c9ae0d0fefda0dd7c52fcc3c647a3" +dependencies = [ + "anchor-lang", + "spl-associated-token-account", + "spl-pod", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", +] + +[[package]] +name = "anchor-syn" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f99daacb53b55cfd37ce14d6c9905929721137fd4c67bbab44a19802aecb622f" +dependencies = [ + "anyhow", + "bs58 0.5.1", + "heck", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.9", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +dependencies = [ + "borsh-derive 1.6.0", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +dependencies = [ + "once_cell", + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "num-traits", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.114", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek", + "hmac 0.12.1", + "sha2 0.10.9", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "find-msvc-tools" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.12", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint", + "thiserror", +] + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "polyield_vault" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anchor-spl", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "solana-frozen-abi" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" +dependencies = [ + "block-buffer 0.10.4", + "bs58 0.4.0", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.9", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.114", +] + +[[package]] +name = "solana-logger" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121d36ffb3c6b958763312cbc697fbccba46ee837d3a0aa4fc0e90fcb3b884f3" +dependencies = [ + "env_logger", + "lazy_static", + "log", +] + +[[package]] +name = "solana-program" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.4", + "borsh 0.9.3", + "borsh 1.6.0", + "bs58 0.4.0", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.17", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.9", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-sdk" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580ad66c2f7a4c3cb3244fe21440546bd500f5ecb955ad9826e92a78dded8009" +dependencies = [ + "assert_matches", + "base64 0.21.7", + "bincode", + "bitflags", + "borsh 1.6.0", + "bs58 0.4.0", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek", + "ed25519-dalek-bip32", + "generic-array", + "hmac 0.12.1", + "itertools", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memmap2", + "num-derive", + "num-traits", + "num_enum", + "pbkdf2 0.11.0", + "qstring", + "qualifier_attr", + "rand 0.7.3", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "serde_with", + "sha2 0.10.9", + "sha3 0.10.8", + "siphasher", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" +dependencies = [ + "bs58 0.4.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.114", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "156bb61a96c605fa124e052d630dba2f6fb57e08c7d15b757e1e958b3ed7b3fe" +dependencies = [ + "hashbrown 0.15.2", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cbdf4249b6dfcbba7d84e2b53313698043f60f8e22ce48286e6fbe8a17c8d16" +dependencies = [ + "aes-gcm-siv", + "base64 0.21.7", + "bincode", + "bytemuck", + "byteorder", + "curve25519-dalek", + "getrandom 0.1.16", + "itertools", + "lazy_static", + "merlin", + "num-derive", + "num-traits", + "rand 0.7.3", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143109d789171379e6143ef23191786dfaac54289ad6e7917cfb26b36c432b10" +dependencies = [ + "assert_matches", + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-program", + "spl-token", + "spl-token-2022", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210101376962bb22bb13be6daea34656ea1cbc248fce2164b146e39203b55e03" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.114", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.114", + "thiserror", +] + +[[package]] +name = "spl-memo" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49f49f95f2d02111ded31696ab38a081fab623d4c76bd4cb074286db4560836" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c52d84c55efeef8edcc226743dc089d7e3888b8e3474569aa3eff152b37b9996" +dependencies = [ + "borsh 1.6.0", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45a49acb925db68aa501b926096b2164adbdcade7a0c24152af9f0742d0a602" +dependencies = [ + "num-derive", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.114", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fab8edfd37be5fa17c9e42c1bff86abbbaf0494b031b37957f2728ad2ff842ba" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-token" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9eb465e4bf5ce1d498f05204c8089378c1ba34ef2777ea95852fc53a1fd4fb2" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c39e416aeb1ea0b22f3b2bbecaf7e38a92a1aa8f4a0c5785c94179694e846a0" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "solana-security-txt", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "014817d6324b1e20c4bbc883e8ee30a5faa13e59d91d1b2b95df98b920150c17" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3da00495b602ebcf5d8ba8b3ecff1ee454ce4c125c9077747be49c2d62335ba" +dependencies = [ + "borsh 1.6.0", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9b5c08a89838e5a2931f79b17f611857f281a14a2100968a3ccef352cb7414b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c872f93d0600e743116501eba2d53460e73a12c9a496875a42a7d70e034fe06d" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "zerocopy" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zmij" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f63c051f4fe3c1509da62131a678643c5b6fbdc9273b2b79d4378ebda003d2" diff --git a/app/positions/page.tsx b/app/positions/page.tsx new file mode 100644 index 0000000..1c2c001 --- /dev/null +++ b/app/positions/page.tsx @@ -0,0 +1,20 @@ +import { PositionsList } from "@/components/positions-list" +import { Pill } from "@/components/pill" + +export default function PositionsPage() { + return ( +
+
+ Portfolio +

+ Your Positions +

+

+ Track your active predictions and watch your no-loss yield grow in real-time. +

+
+ + +
+ ) +} diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..fb5bed2 --- /dev/null +++ b/build.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Source cargo environment first +source "$HOME/.cargo/env" 2>/dev/null + +# Set PATH with Solana tools and cargo +export PATH="$HOME/.cargo/bin:/home/arya/.local/share/solana/install/active_release/bin:/usr/local/bin:/usr/bin:/bin" + +# Force use of system cargo +export CARGO="$HOME/.cargo/bin/cargo" +export RUSTC="$HOME/.cargo/bin/rustc" + +cd /mnt/c/Users/1arya/OneDrive/Desktop/polyield/polyield + +echo "Using Rust: $(rustc --version)" +echo "Using Cargo: $(cargo --version)" +echo "Building..." + +anchor build diff --git a/components/deposit-modal.tsx b/components/deposit-modal.tsx index 7271a01..e08dccf 100644 --- a/components/deposit-modal.tsx +++ b/components/deposit-modal.tsx @@ -1,10 +1,11 @@ "use client" import { useState, useEffect } from "react" -import { X, Loader2, CheckCircle, ExternalLink, AlertCircle, Wallet } from "lucide-react" +import { X, Loader2, CheckCircle, ExternalLink, AlertCircle, Wallet, Shield, TrendingUp, RefreshCw } from "lucide-react" import { useWallet } from "@solana/wallet-adapter-react" import { useWalletModal } from "@solana/wallet-adapter-react-ui" import { useDeposit } from "@/hooks/use-deposit" +import { usePositions } from "@/hooks/use-positions" import { Position } from "@/lib/solana/constants" import { Button } from "./ui/button" @@ -13,6 +14,7 @@ interface DepositModalProps { onClose: () => void marketId: string marketQuestion: string + marketExpiry: string position: "yes" | "no" currentOdds: number } @@ -22,6 +24,7 @@ export function DepositModal({ onClose, marketId, marketQuestion, + marketExpiry, position, currentOdds, }: DepositModalProps) { @@ -38,6 +41,7 @@ export function DepositModal({ clearError, clearTx, } = useDeposit() + const { addPosition } = usePositions() // Refresh balance when modal opens or wallet connects useEffect(() => { @@ -64,7 +68,16 @@ export function DepositModal({ const handleDeposit = async () => { if (numericAmount <= 0) return - await deposit(numericAmount, marketId, positionEnum) + const signature = await deposit(numericAmount, marketId, positionEnum) + + if (signature) { + // Parse expiry string to timestamp, fallback to 30 days from now + const expiryTimestamp = marketExpiry + ? new Date(marketExpiry).getTime() + : Date.now() + (30 * 24 * 60 * 60 * 1000) + + addPosition(marketId, marketQuestion, positionEnum, numericAmount, expiryTimestamp) + } } const handleConnectWallet = () => { @@ -82,11 +95,11 @@ export function DepositModal({ return (
{/* Backdrop */} -
- + {/* Modal */}
{/* Close button */} @@ -99,17 +112,20 @@ export function DepositModal({ {/* Header */}
-
- + + }`}> Predict {position} @ {currentOdds}% + + + No-Loss +

{marketQuestion} @@ -120,13 +136,20 @@ export function DepositModal({ {txSignature && (
- +
+ + +

- Deposit Successful! + Position Secured!

-

- Your {numericAmount.toFixed(2)} USDC has been deposited to the {position.toUpperCase()} position. +

+ {numericAmount.toFixed(2)} USDC deposited on {position.toUpperCase()}

+
+ + Your principal is protected +
{solscanUrl && (
- {/* Potential Payout */} + {/* No-Loss Guarantee Banner */} +
+ +

+ Principal Protected — You cannot lose your stake +

+
+ + {/* Potential Outcomes */} {numericAmount > 0 && ( -
-
- Your Stake +
+ {/* Your Stake */} +
+ + + Your Stake (Protected) + {numericAmount.toFixed(2)} USDC
-
- If {position.toUpperCase()} wins - - +{potentialProfit.toFixed(2)} USDC + + {/* Divider */} +
+ + {/* If You Win */} +
+ + + If {position.toUpperCase()} wins +
+ + +{potentialProfit.toFixed(2)} USDC + +

yield profit

+
-
- Potential Payout - - {potentialPayout.toFixed(2)} USDC + + {/* If You Lose */} +
+ + + If {position.toUpperCase()} loses +
+ + {numericAmount.toFixed(2)} USDC + +

full refund

+
+
+ + {/* Summary */} +
+
+ Max Payout + + {potentialPayout.toFixed(2)} USDC + +
+

+ Stake + Yield if your prediction is correct +

)} diff --git a/components/header.tsx b/components/header.tsx index cd1e805..ef3edaf 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -19,6 +19,12 @@ export const Header = () => { > Markets + + Positions + {["How It Works", "Leaderboard", "FAQ"].map((item) => ( { @@ -30,8 +30,8 @@ export function MarketCard({ market }: MarketCardProps) { return `$${value}` } - const polymarketUrl = market.slug - ? `https://polymarket.com/event/${market.slug}` + const polymarketUrl = market.slug + ? `https://polymarket.com/event/${market.slug}` : "https://polymarket.com" const handleDepositClick = () => { @@ -67,12 +67,16 @@ export function MarketCard({ market }: MarketCardProps) { />
)} - +
{market.category} - + + No-Loss + + @@ -142,13 +144,19 @@ export function MarketCard({ market }: MarketCardProps) { {/* Deposit button (appears when position selected) */} {selectedPosition && ( - +
+ +

+ + Win yield or get refunded — you can't lose +

+
)}
@@ -159,6 +167,7 @@ export function MarketCard({ market }: MarketCardProps) { onClose={handleCloseModal} marketId={market.id} marketQuestion={market.question} + marketExpiry={market.endDate} position={selectedPosition} currentOdds={getCurrentOdds()} /> diff --git a/components/positions-list.tsx b/components/positions-list.tsx new file mode 100644 index 0000000..b62f005 --- /dev/null +++ b/components/positions-list.tsx @@ -0,0 +1,157 @@ +"use client" + +import { usePositions } from "@/hooks/use-positions" +import { useWallet } from "@solana/wallet-adapter-react" +import { Shield, TrendingUp, Wallet, AlertCircle, Clock, CheckCircle2 } from "lucide-react" +import { Button } from "./ui/button" +import { Position } from "@/lib/solana/constants" + +export function PositionsList() { + const { connected } = useWallet() + const { positions, totalValue, totalYield, apy } = usePositions() + + if (!connected) { + return ( +
+ +

Connect Your Wallet

+

+ Connect your wallet to view your active positions and accrued yield. +

+
+ ) + } + + if (positions.length === 0) { + return ( +
+ +

No Active Positions

+

+ You haven't made any predictions yet. Explore markets to start earning yield on your predictions. +

+ +
+ ) + } + + return ( +
+ {/* Portfolio Summary */} +
+
+
+ + Total Protected Value +
+
+ ${totalValue.toFixed(2)} +
+
+ +
+
+
+ + Accrued Yield +
+
+ +${totalYield.toFixed(6)} +
+
+ Est. APY: {(apy * 100).toFixed(0)}% +
+
+ +
+
+ + Active Positions +
+
+ {positions.length} +
+
+
+ + {/* Positions List */} +
+

Your Positions

+
+ {positions.map((pos) => { + const isYes = pos.position === Position.Yes + + // Check expiry + const now = Date.now() + const isExpired = now > pos.expiryTimestamp + + // Calculate yield based on time elapsed (capped at expiry) + const endTime = isExpired ? pos.expiryTimestamp : now + const durationMs = Math.max(0, endTime - pos.timestamp) + const durationYears = durationMs / (1000 * 60 * 60 * 24 * 365) + const yieldAmount = pos.amount * apy * durationYears + + return ( +
+
+
+ + Predict {isYes ? "Yes" : "No"} + + + Placed {new Date(pos.timestamp).toLocaleDateString()} + + {isExpired && ( + + Expired + + )} +
+

{pos.marketQuestion}

+
+ +
+
+
Principal
+
${pos.amount.toFixed(2)}
+
+ +
+
+ {isExpired ? "Final Yield" : "Current Yield"} +
+
+ +${yieldAmount.toFixed(6)} +
+
+ +
+ {isExpired ? ( + + ) : ( +
+ + Yielding +
+ )} +
+
+
+ ) + })} +
+
+
+ ) +} diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts new file mode 100644 index 0000000..150ace3 --- /dev/null +++ b/hooks/use-positions.ts @@ -0,0 +1,116 @@ +"use client" + +import { useState, useEffect } from "react" +import { useWallet } from "@solana/wallet-adapter-react" +import { Position } from "@/lib/solana/constants" + +export interface UserPosition { + id: string + marketId: string + marketQuestion: string + position: Position + amount: number + timestamp: number + expiryTimestamp: number + status: "active" | "claimed" | "refunded" +} + +// Mock APY for yield calculation (e.g., 12%) +const MOCK_APY = 0.12 + +export function usePositions() { + const { publicKey } = useWallet() + const [positions, setPositions] = useState([]) + const [totalYield, setTotalYield] = useState(0) + const [totalValue, setTotalValue] = useState(0) + + // Load positions from local storage + useEffect(() => { + if (!publicKey) { + setPositions([]) + return + } + + const loadPositions = () => { + try { + const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) + if (stored) { + const parsed = JSON.parse(stored) + setPositions(parsed) + calculateTotals(parsed) + } + } catch (e) { + console.error("Failed to load positions", e) + } + } + + loadPositions() + + // Listen for storage events to update real-time + window.addEventListener("storage", loadPositions) + return () => window.removeEventListener("storage", loadPositions) + }, [publicKey]) + + const calculateTotals = (currentPositions: UserPosition[]) => { + const now = Date.now() + let yieldSum = 0 + let valueSum = 0 + + currentPositions.forEach(pos => { + // Calculate yield: Principal * APY * (TimeDelta in Years) + const timeDiff = now - pos.timestamp + const yearsElapsed = timeDiff / (1000 * 60 * 60 * 24 * 365) + + // In this model, assume yield is generated continuously + // For winners, they get a share of total yield. + // For this demo, we'll simulate a projected yield based on the mock APY. + const estimatedYield = pos.amount * MOCK_APY * yearsElapsed + + if (pos.status === "active") { + yieldSum += estimatedYield + valueSum += pos.amount + } + }) + + setTotalYield(yieldSum) + setTotalValue(valueSum) + } + + const addPosition = ( + marketId: string, + marketQuestion: string, + position: Position, + amount: number, + expiryTimestamp: number + ) => { + if (!publicKey) return + + const newPosition: UserPosition = { + id: Math.random().toString(36).substring(7), + marketId, + marketQuestion, + position, + amount, + timestamp: Date.now(), + expiryTimestamp, + status: "active" + } + + const updated = [...positions, newPosition] + setPositions(updated) + calculateTotals(updated) + + localStorage.setItem( + `polyield_positions_${publicKey.toBase58()}`, + JSON.stringify(updated) + ) + } + + return { + positions, + totalYield, + totalValue, + addPosition, + apy: MOCK_APY + } +} diff --git a/lib/solana/constants.ts b/lib/solana/constants.ts index f73e8c2..01b00b6 100644 --- a/lib/solana/constants.ts +++ b/lib/solana/constants.ts @@ -6,10 +6,8 @@ export const USDC_MINT = new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJD // USDC has 6 decimals export const USDC_DECIMALS = 6 -// Program ID - Update this after deploying to devnet -// Run: anchor keys list to get your program ID -// Using System Program as placeholder until deployed -export const PROGRAM_ID = new PublicKey("11111111111111111111111111111111") +// Program ID - Deployed to devnet +export const PROGRAM_ID = new PublicKey("FWGiD7WhXu8k7eDtEwr3ZbXbvqwL7kdJgNfugrSVJ7F3") // Seed constants matching the Anchor program export const VAULT_SEED = "vault" diff --git a/lib/solana/deposit.ts b/lib/solana/deposit.ts index bb25d86..77cadf6 100644 --- a/lib/solana/deposit.ts +++ b/lib/solana/deposit.ts @@ -11,6 +11,7 @@ import { ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, + createTransferInstruction, getAccount, } from "@solana/spl-token" import { @@ -188,27 +189,63 @@ export async function buildDepositTransaction( ) } - // Build instruction data - const data = buildDepositInstructionData(amountLamports, marketId, position) + // --- TEMPORARY: Direct Transfer for Frontend Testing --- + // Since the Anchor program isn't deployed yet, we'll simulate the deposit + // by transferring USDC directly to the Vault's Token Account. + + // Get Vault's ATA + const vaultTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + vault, + true // allowOwnerOffCurve = true because vault is a PDA + ) + + // Check if Vault ATA exists, if not create it + try { + await getAccount(connection, vaultTokenAccount) + } catch { + transaction.add( + createAssociatedTokenAccountInstruction( + userPublicKey, // payer + vaultTokenAccount, // ata + vault, // owner + USDC_MINT // mint + ) + ) + } - // Build the deposit instruction + // Add Transfer Instruction + transaction.add( + createTransferInstruction( + userTokenAccount, // source + vaultTokenAccount, // destination + userPublicKey, // owner + amountLamports + ) + ) + + /* + // Anchor Program Instruction (Commented out until deployment) + const data = buildDepositInstructionData(amountLamports, marketId, position) + const depositInstruction = new TransactionInstruction({ programId: PROGRAM_ID, keys: [ - { pubkey: userPublicKey, isSigner: true, isWritable: true }, // user - { pubkey: USDC_MINT, isSigner: false, isWritable: false }, // mint - { pubkey: vaultState, isSigner: false, isWritable: true }, // vault_state - { pubkey: vault, isSigner: false, isWritable: true }, // vault - { pubkey: userTokenAccount, isSigner: false, isWritable: true }, // user_token_account - { pubkey: userDeposit, isSigner: false, isWritable: true }, // user_deposit - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // token_program - { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // associated_token_program - { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, // system_program + { pubkey: userPublicKey, isSigner: true, isWritable: true }, + { pubkey: USDC_MINT, isSigner: false, isWritable: false }, + { pubkey: vaultState, isSigner: false, isWritable: true }, + { pubkey: vault, isSigner: false, isWritable: true }, + { pubkey: userTokenAccount, isSigner: false, isWritable: true }, + { pubkey: userDeposit, isSigner: false, isWritable: true }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ], data, }) transaction.add(depositInstruction) + */ // Get recent blockhash const { blockhash } = await connection.getLatestBlockhash() diff --git a/programs/polyield_vault/Cargo.toml b/programs/polyield_vault/Cargo.toml index b528dba..78f29ce 100644 --- a/programs/polyield_vault/Cargo.toml +++ b/programs/polyield_vault/Cargo.toml @@ -17,4 +17,4 @@ default = [] [dependencies] anchor-lang = "0.30.1" -anchor-spl = "0.30.1" +anchor-spl = "0.30.1" \ No newline at end of file diff --git a/programs/polyield_vault/src/lib.rs b/programs/polyield_vault/src/lib.rs index 3e986fa..3b45fe9 100644 --- a/programs/polyield_vault/src/lib.rs +++ b/programs/polyield_vault/src/lib.rs @@ -6,7 +6,7 @@ use anchor_spl::{ }, }; -declare_id!("YourProgramIdHere11111111111111111111111111"); +declare_id!("FWGiD7WhXu8k7eDtEwr3ZbXbvqwL7kdJgNfugrSVJ7F3"); #[program] pub mod polyield_vault { diff --git a/target/.rustc_info.json b/target/.rustc_info.json new file mode 100644 index 0000000..02d2ef6 --- /dev/null +++ b/target/.rustc_info.json @@ -0,0 +1 @@ +{"rustc_fingerprint":16472775163035338029,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.84.1-dev\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: x86_64-unknown-linux-gnu\nrelease: 1.84.1-dev\nLLVM version: 19.1.7\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/arya/.cache/solana/v1.51/platform-tools/rust\noff\npacked\nunpacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nub_checks\nunix\n","stderr":""},"11765043263735001137":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\n___.so\nlib___.a\n/home/arya/.cache/solana/v1.51/platform-tools/rust\noff\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"abort\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"sbf\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"solana\"\ntarget_has_atomic\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"solana\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"solana\"\nub_checks\n","stderr":"warning: dropping unsupported crate type `dylib` for target `sbpf-solana-solana`\n\nwarning: dropping unsupported crate type `proc-macro` for target `sbpf-solana-solana`\n\nwarning: 2 warnings emitted\n\n"}},"successes":{}} \ No newline at end of file diff --git a/target/deploy/polyield_vault-keypair.json b/target/deploy/polyield_vault-keypair.json new file mode 100644 index 0000000..e4101be --- /dev/null +++ b/target/deploy/polyield_vault-keypair.json @@ -0,0 +1 @@ +[222,239,227,68,221,105,81,1,8,82,216,70,186,167,249,183,147,72,203,41,149,226,225,117,32,14,56,6,142,9,79,16,215,131,57,110,219,229,41,100,239,72,101,97,214,54,74,78,106,62,105,2,202,206,25,75,148,95,55,116,68,1,16,206] \ No newline at end of file From bd8a8d71a0243117641198dbc59b8b1440ddd678 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sat, 17 Jan 2026 21:26:37 -0500 Subject: [PATCH 04/26] onchain storage --- hooks/use-deposit.ts | 6 ++- hooks/use-positions.ts | 91 +++++++++++++++++++++++++++++++++--------- lib/solana/deposit.ts | 26 +++++++++++- 3 files changed, 102 insertions(+), 21 deletions(-) diff --git a/hooks/use-deposit.ts b/hooks/use-deposit.ts index 394b438..c082baf 100644 --- a/hooks/use-deposit.ts +++ b/hooks/use-deposit.ts @@ -16,7 +16,7 @@ export interface DepositState { } export interface UseDepositReturn extends DepositState { - deposit: (amount: number, marketId: string, position: Position) => Promise + deposit: (amount: number, marketId: string, marketQuestion: string, expiry: number, position: Position) => Promise refreshBalance: () => Promise clearError: () => void clearTx: () => void @@ -50,6 +50,8 @@ export function useDeposit(): UseDepositReturn { const deposit = useCallback(async ( amount: number, marketId: string, + marketQuestion: string, + expiry: number, position: Position ): Promise => { if (!publicKey || !signTransaction || !connected) { @@ -90,6 +92,8 @@ export function useDeposit(): UseDepositReturn { userPublicKey: publicKey, amount, marketId, + marketQuestion, + expiry, position, }) diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts index 150ace3..f4172e0 100644 --- a/hooks/use-positions.ts +++ b/hooks/use-positions.ts @@ -1,8 +1,11 @@ "use client" import { useState, useEffect } from "react" -import { useWallet } from "@solana/wallet-adapter-react" +import { useConnection, useWallet } from "@solana/wallet-adapter-react" import { Position } from "@/lib/solana/constants" +import { PublicKey } from "@solana/web3.js" + +const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcQb") export interface UserPosition { id: string @@ -19,37 +22,92 @@ export interface UserPosition { const MOCK_APY = 0.12 export function usePositions() { + const { connection } = useConnection() const { publicKey } = useWallet() const [positions, setPositions] = useState([]) const [totalYield, setTotalYield] = useState(0) const [totalValue, setTotalValue] = useState(0) - // Load positions from local storage + // Fetch positions from chain history useEffect(() => { if (!publicKey) { setPositions([]) return } - const loadPositions = () => { + const fetchPositions = async () => { try { - const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) - if (stored) { - const parsed = JSON.parse(stored) - setPositions(parsed) - calculateTotals(parsed) + // Fetch last 20 signatures + const signatures = await connection.getSignaturesForAddress(publicKey, { limit: 20 }) + if (signatures.length === 0) return + + // Fetch parsed transactions + const txs = await connection.getParsedTransactions( + signatures.map(s => s.signature), + { maxSupportedTransactionVersion: 0 } + ) + + const loadedPositions: UserPosition[] = [] + + txs.forEach(tx => { + if (!tx || !tx.meta || tx.meta.err) return + + // Look for Memo instruction + const instructions = tx.transaction.message.instructions + for (const ix of instructions) { + if (ix.programId.equals(MEMO_PROGRAM_ID)) { + // Handle parsed vs raw instruction + let memoString = "" + if ("parsed" in ix) { + memoString = ix.parsed as string + } else if ("data" in ix) { + // If data is base58 encoded + // Not typical for getParsedTransactions but handling safety + // Ideally parsed transactions handle SplMemo + // We'll rely on it being parsed or check raw data decoding if needed + // For simplicity assuming parsed for now as standard RPC does it + continue + } + + try { + // Try to parse our JSON format + if (memoString.includes("polyield_position")) { + const data = JSON.parse(memoString) + if (data.type === "polyield_position") { + loadedPositions.push({ + id: tx.transaction.signatures[0], // Use tx sig as ID + marketId: data.marketId, + marketQuestion: data.marketQuestion, + position: data.position, + amount: data.amount, + timestamp: data.timestamp, + expiryTimestamp: data.expiry, + status: "active" + }) + } + } + } catch (e) { + // Not our memo or invalid JSON, ignore + } + } + } + }) + + if (loadedPositions.length > 0) { + setPositions(loadedPositions) + calculateTotals(loadedPositions) } } catch (e) { - console.error("Failed to load positions", e) + console.error("Failed to fetch positions", e) } } - loadPositions() + fetchPositions() - // Listen for storage events to update real-time - window.addEventListener("storage", loadPositions) - return () => window.removeEventListener("storage", loadPositions) - }, [publicKey]) + // Poll every 15 seconds + const interval = setInterval(fetchPositions, 15000) + return () => clearInterval(interval) + }, [publicKey, connection]) const calculateTotals = (currentPositions: UserPosition[]) => { const now = Date.now() @@ -99,11 +157,6 @@ export function usePositions() { const updated = [...positions, newPosition] setPositions(updated) calculateTotals(updated) - - localStorage.setItem( - `polyield_positions_${publicKey.toBase58()}`, - JSON.stringify(updated) - ) } return { diff --git a/lib/solana/deposit.ts b/lib/solana/deposit.ts index 77cadf6..4b71dc7 100644 --- a/lib/solana/deposit.ts +++ b/lib/solana/deposit.ts @@ -24,6 +24,9 @@ import { Position, } from "./constants" +// Memo Program ID +export const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcQb") + /** * Get the vault PDA address */ @@ -133,6 +136,8 @@ export interface DepositParams { userPublicKey: PublicKey amount: number // in USDC (e.g., 10.5 for $10.50) marketId: string + marketQuestion: string + expiry: number position: Position } @@ -150,7 +155,7 @@ export interface DepositResult { export async function buildDepositTransaction( params: DepositParams ): Promise { - const { connection, userPublicKey, amount, marketId, position } = params + const { connection, userPublicKey, amount, marketId, marketQuestion, expiry, position } = params // Get PDAs const [vault] = getVaultPDA() @@ -224,6 +229,25 @@ export async function buildDepositTransaction( ) ) + // Add Memo Instruction to persist position data on-chain + const memoData = JSON.stringify({ + type: "polyield_position", + marketId, + marketQuestion, + position, + amount, + expiry, + timestamp: Date.now() + }) + + transaction.add( + new TransactionInstruction({ + keys: [], + programId: MEMO_PROGRAM_ID, + data: Buffer.from(memoData, "utf-8"), + }) + ) + /* // Anchor Program Instruction (Commented out until deployment) const data = buildDepositInstructionData(amountLamports, marketId, position) From f987a6d9eac46aeb7416be83e1b3e451d744f8dc Mon Sep 17 00:00:00 2001 From: Umar Date: Sat, 17 Jan 2026 21:29:57 -0500 Subject: [PATCH 05/26] Added script --- setup-devnet-wallet.ps1 | 119 ++++++++++++++++++++++++++++++++++++ setup-devnet-wallet.sh | 129 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 setup-devnet-wallet.ps1 create mode 100644 setup-devnet-wallet.sh diff --git a/setup-devnet-wallet.ps1 b/setup-devnet-wallet.ps1 new file mode 100644 index 0000000..bde0701 --- /dev/null +++ b/setup-devnet-wallet.ps1 @@ -0,0 +1,119 @@ +# Solana Devnet Wallet Setup Script +# This script creates a new Solana wallet on devnet and funds it with USDC + +Write-Host "=== Solana Devnet Wallet Setup ===" -ForegroundColor Cyan +Write-Host "" + +# Check if Solana CLI is installed +Write-Host "Checking for Solana CLI..." -ForegroundColor Yellow +try { + $solanaVersion = solana --version 2>&1 + Write-Host "✓ Solana CLI found: $solanaVersion" -ForegroundColor Green +} catch { + Write-Host "✗ Solana CLI not found!" -ForegroundColor Red + Write-Host "Please install Solana CLI from: https://docs.solana.com/cli/install-solana-cli-tools" -ForegroundColor Yellow + exit 1 +} + +# Set cluster to devnet +Write-Host "" +Write-Host "Setting cluster to devnet..." -ForegroundColor Yellow +solana config set --url devnet +Write-Host "✓ Cluster set to devnet" -ForegroundColor Green + +# Generate new keypair +Write-Host "" +Write-Host "Generating new keypair..." -ForegroundColor Yellow +$keypairPath = "$env:USERPROFILE\.config\solana\devnet-wallet.json" + +# Create directory if it doesn't exist +$configDir = Split-Path -Parent $keypairPath +if (!(Test-Path $configDir)) { + New-Item -ItemType Directory -Path $configDir -Force | Out-Null +} + +# Generate keypair (force overwrite if exists) +solana-keygen new --outfile $keypairPath --force --no-bip39-passphrase + +Write-Host "✓ Keypair generated at: $keypairPath" -ForegroundColor Green + +# Set as default keypair +solana config set --keypair $keypairPath + +# Get wallet address +$walletAddress = solana address + +# Extract private key for Phantom import +Write-Host "" +Write-Host "Extracting private key for Phantom wallet..." -ForegroundColor Yellow +$privateKeyBytes = Get-Content $keypairPath | ConvertFrom-Json +$privateKeyArray = $privateKeyBytes -join ',' + +Write-Host "" +Write-Host "=== Your Wallet Details ===" -ForegroundColor Cyan +Write-Host "Address: $walletAddress" -ForegroundColor White +Write-Host "Keypair Path: $keypairPath" -ForegroundColor White +Write-Host "" +Write-Host "=== Private Key (for Phantom import) ===" -ForegroundColor Yellow +Write-Host "⚠ KEEP THIS SECRET! Never share with anyone!" -ForegroundColor Red +Write-Host "" +Write-Host "Private Key (byte array format):" -ForegroundColor White +Write-Host "[$privateKeyArray]" -ForegroundColor Cyan +Write-Host "" + +# Airdrop SOL for transaction fees +Write-Host "" +Write-Host "Requesting SOL airdrop for transaction fees..." -ForegroundColor Yellow +try { + solana airdrop 2 + Start-Sleep -Seconds 3 + $solBalance = solana balance + Write-Host "✓ SOL Balance: $solBalance" -ForegroundColor Green +} catch { + Write-Host "⚠ Airdrop failed (rate limit or network issue)" -ForegroundColor Yellow + Write-Host "You can try again later or use the web faucet: https://faucet.solana.com" -ForegroundColor Yellow +} + +# Instructions for Phantom Wallet Import +Write-Host "" +Write-Host "=== Import to Phantom Wallet ===" -ForegroundColor Cyan +Write-Host "" +Write-Host "1. Open Phantom wallet extension" -ForegroundColor White +Write-Host "2. Click the menu (☰) → 'Add / Connect Wallet'" -ForegroundColor White +Write-Host "3. Select 'Import Private Key'" -ForegroundColor White +Write-Host "4. Paste the private key array shown above" -ForegroundColor White +Write-Host "5. Make sure Phantom is set to 'Devnet' (Settings → Developer Settings → Testnet Mode)" -ForegroundColor White +Write-Host "" + +# Instructions for Circle USDC Faucet +Write-Host "=== Get USDC from Circle Faucet ===" -ForegroundColor Cyan +Write-Host "" +Write-Host "1. Open Circle Faucet: https://faucet.circle.com/" -ForegroundColor White +Write-Host "2. Select 'Solana Devnet' from the network dropdown" -ForegroundColor White +Write-Host "3. Select 'USDC' as the token" -ForegroundColor White +Write-Host "4. Paste your wallet address: $walletAddress" -ForegroundColor Yellow +Write-Host "5. Click 'Get Tokens'" -ForegroundColor White +Write-Host "" + +# Copy address to clipboard +Write-Host "Copying wallet address to clipboard..." -ForegroundColor Yellow +Set-Clipboard -Value $walletAddress +Write-Host "✓ Address copied to clipboard!" -ForegroundColor Green + +# Open Circle faucet in browser +Write-Host "" +$openBrowser = Read-Host "Open Circle Faucet in browser? (y/n)" +if ($openBrowser -eq 'y' -or $openBrowser -eq 'Y') { + Start-Process "https://faucet.circle.com/" + Write-Host "✓ Browser opened" -ForegroundColor Green +} + +Write-Host "" +Write-Host "=== Setup Complete! ===" -ForegroundColor Green +Write-Host "" +Write-Host "Your wallet is ready. After getting USDC from the faucet, you can check your balance with:" -ForegroundColor White +Write-Host " solana balance" -ForegroundColor Cyan +Write-Host "" +Write-Host "To use this wallet in your app, set the keypair path:" -ForegroundColor White +Write-Host " solana config set --keypair $keypairPath" -ForegroundColor Cyan +Write-Host "" diff --git a/setup-devnet-wallet.sh b/setup-devnet-wallet.sh new file mode 100644 index 0000000..9efd03c --- /dev/null +++ b/setup-devnet-wallet.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# Solana Devnet Wallet Setup Script +# This script creates a new Solana wallet on devnet and funds it with USDC + +echo "=== Solana Devnet Wallet Setup ===" +echo "" + +# Check if Solana CLI is installed +echo "Checking for Solana CLI..." +if ! command -v solana &> /dev/null; then + echo "✗ Solana CLI not found!" + echo "Please install Solana CLI from: https://docs.solana.com/cli/install-solana-cli-tools" + exit 1 +fi + +SOLANA_VERSION=$(solana --version) +echo "✓ Solana CLI found: $SOLANA_VERSION" + +# Set cluster to devnet +echo "" +echo "Setting cluster to devnet..." +solana config set --url devnet +echo "✓ Cluster set to devnet" + +# Generate new keypair +echo "" +echo "Generating new keypair..." +KEYPAIR_PATH="$HOME/.config/solana/devnet-wallet.json" + +# Create directory if it doesn't exist +mkdir -p "$(dirname "$KEYPAIR_PATH")" + +# Generate keypair (force overwrite if exists) +solana-keygen new --outfile "$KEYPAIR_PATH" --force --no-bip39-passphrase + +echo "✓ Keypair generated at: $KEYPAIR_PATH" + +# Set as default keypair +solana config set --keypair "$KEYPAIR_PATH" + +# Get wallet address +WALLET_ADDRESS=$(solana address) + +# Extract private key for Phantom import +echo "" +echo "Extracting private key for Phantom wallet..." +PRIVATE_KEY=$(cat "$KEYPAIR_PATH" | tr -d '[]' | tr -d ' ' | tr -d '\n') + +echo "" +echo "=== Your Wallet Details ===" +echo "Address: $WALLET_ADDRESS" +echo "Keypair Path: $KEYPAIR_PATH" +echo "" +echo "=== Private Key (for Phantom import) ===" +echo "⚠ KEEP THIS SECRET! Never share with anyone!" +echo "" +echo "Private Key (byte array format):" +echo "[$PRIVATE_KEY]" +echo "" + +# Airdrop SOL for transaction fees +echo "" +echo "Requesting SOL airdrop for transaction fees..." +if solana airdrop 2; then + sleep 3 + SOL_BALANCE=$(solana balance) + echo "✓ SOL Balance: $SOL_BALANCE" +else + echo "⚠ Airdrop failed (rate limit or network issue)" + echo "You can try again later or use the web faucet: https://faucet.solana.com" +fi + +# Instructions for Phantom Wallet Import +echo "" +echo "=== Import to Phantom Wallet ===" +echo "" +echo "1. Open Phantom wallet extension" +echo "2. Click the menu (☰) → 'Add / Connect Wallet'" +echo "3. Select 'Import Private Key'" +echo "4. Paste the private key array shown above" +echo "5. Make sure Phantom is set to 'Devnet' (Settings → Developer Settings → Testnet Mode)" +echo "" + +# Instructions for Circle USDC Faucet +echo "=== Get USDC from Circle Faucet ===" +echo "" +echo "1. Open Circle Faucet: https://faucet.circle.com/" +echo "2. Select 'Solana Devnet' from the network dropdown" +echo "3. Select 'USDC' as the token" +echo "4. Paste your wallet address: $WALLET_ADDRESS" +echo "5. Click 'Get Tokens'" +echo "" + +# Copy address to clipboard (if available) +if command -v pbcopy &> /dev/null; then + echo "$WALLET_ADDRESS" | pbcopy + echo "✓ Address copied to clipboard (macOS)!" +elif command -v xclip &> /dev/null; then + echo "$WALLET_ADDRESS" | xclip -selection clipboard + echo "✓ Address copied to clipboard (Linux)!" +elif command -v clip.exe &> /dev/null; then + echo "$WALLET_ADDRESS" | clip.exe + echo "✓ Address copied to clipboard (WSL)!" +fi + +# Open Circle faucet in browser +echo "" +read -p "Open Circle Faucet in browser? (y/n) " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + if command -v xdg-open &> /dev/null; then + xdg-open "https://faucet.circle.com/" + elif command -v open &> /dev/null; then + open "https://faucet.circle.com/" + elif command -v start &> /dev/null; then + start "https://faucet.circle.com/" + fi + echo "✓ Browser opened" +fi + +echo "" +echo "=== Setup Complete! ===" +echo "" +echo "Your wallet is ready. After getting USDC from the faucet, you can check your balance with:" +echo " solana balance" +echo "" +echo "To use this wallet in your app, set the keypair path:" +echo " solana config set --keypair $KEYPAIR_PATH" +echo "" From 2aa3a03bacef459210f4fe96c3e3cefe7f51f4a3 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sat, 17 Jan 2026 21:51:42 -0500 Subject: [PATCH 06/26] made changes --- hooks/use-deposit.ts | 6 +-- hooks/use-positions.ts | 91 +++++++++--------------------------------- lib/solana/deposit.ts | 26 +----------- 3 files changed, 21 insertions(+), 102 deletions(-) diff --git a/hooks/use-deposit.ts b/hooks/use-deposit.ts index c082baf..394b438 100644 --- a/hooks/use-deposit.ts +++ b/hooks/use-deposit.ts @@ -16,7 +16,7 @@ export interface DepositState { } export interface UseDepositReturn extends DepositState { - deposit: (amount: number, marketId: string, marketQuestion: string, expiry: number, position: Position) => Promise + deposit: (amount: number, marketId: string, position: Position) => Promise refreshBalance: () => Promise clearError: () => void clearTx: () => void @@ -50,8 +50,6 @@ export function useDeposit(): UseDepositReturn { const deposit = useCallback(async ( amount: number, marketId: string, - marketQuestion: string, - expiry: number, position: Position ): Promise => { if (!publicKey || !signTransaction || !connected) { @@ -92,8 +90,6 @@ export function useDeposit(): UseDepositReturn { userPublicKey: publicKey, amount, marketId, - marketQuestion, - expiry, position, }) diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts index f4172e0..150ace3 100644 --- a/hooks/use-positions.ts +++ b/hooks/use-positions.ts @@ -1,11 +1,8 @@ "use client" import { useState, useEffect } from "react" -import { useConnection, useWallet } from "@solana/wallet-adapter-react" +import { useWallet } from "@solana/wallet-adapter-react" import { Position } from "@/lib/solana/constants" -import { PublicKey } from "@solana/web3.js" - -const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcQb") export interface UserPosition { id: string @@ -22,92 +19,37 @@ export interface UserPosition { const MOCK_APY = 0.12 export function usePositions() { - const { connection } = useConnection() const { publicKey } = useWallet() const [positions, setPositions] = useState([]) const [totalYield, setTotalYield] = useState(0) const [totalValue, setTotalValue] = useState(0) - // Fetch positions from chain history + // Load positions from local storage useEffect(() => { if (!publicKey) { setPositions([]) return } - const fetchPositions = async () => { + const loadPositions = () => { try { - // Fetch last 20 signatures - const signatures = await connection.getSignaturesForAddress(publicKey, { limit: 20 }) - if (signatures.length === 0) return - - // Fetch parsed transactions - const txs = await connection.getParsedTransactions( - signatures.map(s => s.signature), - { maxSupportedTransactionVersion: 0 } - ) - - const loadedPositions: UserPosition[] = [] - - txs.forEach(tx => { - if (!tx || !tx.meta || tx.meta.err) return - - // Look for Memo instruction - const instructions = tx.transaction.message.instructions - for (const ix of instructions) { - if (ix.programId.equals(MEMO_PROGRAM_ID)) { - // Handle parsed vs raw instruction - let memoString = "" - if ("parsed" in ix) { - memoString = ix.parsed as string - } else if ("data" in ix) { - // If data is base58 encoded - // Not typical for getParsedTransactions but handling safety - // Ideally parsed transactions handle SplMemo - // We'll rely on it being parsed or check raw data decoding if needed - // For simplicity assuming parsed for now as standard RPC does it - continue - } - - try { - // Try to parse our JSON format - if (memoString.includes("polyield_position")) { - const data = JSON.parse(memoString) - if (data.type === "polyield_position") { - loadedPositions.push({ - id: tx.transaction.signatures[0], // Use tx sig as ID - marketId: data.marketId, - marketQuestion: data.marketQuestion, - position: data.position, - amount: data.amount, - timestamp: data.timestamp, - expiryTimestamp: data.expiry, - status: "active" - }) - } - } - } catch (e) { - // Not our memo or invalid JSON, ignore - } - } - } - }) - - if (loadedPositions.length > 0) { - setPositions(loadedPositions) - calculateTotals(loadedPositions) + const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) + if (stored) { + const parsed = JSON.parse(stored) + setPositions(parsed) + calculateTotals(parsed) } } catch (e) { - console.error("Failed to fetch positions", e) + console.error("Failed to load positions", e) } } - fetchPositions() + loadPositions() - // Poll every 15 seconds - const interval = setInterval(fetchPositions, 15000) - return () => clearInterval(interval) - }, [publicKey, connection]) + // Listen for storage events to update real-time + window.addEventListener("storage", loadPositions) + return () => window.removeEventListener("storage", loadPositions) + }, [publicKey]) const calculateTotals = (currentPositions: UserPosition[]) => { const now = Date.now() @@ -157,6 +99,11 @@ export function usePositions() { const updated = [...positions, newPosition] setPositions(updated) calculateTotals(updated) + + localStorage.setItem( + `polyield_positions_${publicKey.toBase58()}`, + JSON.stringify(updated) + ) } return { diff --git a/lib/solana/deposit.ts b/lib/solana/deposit.ts index 4b71dc7..77cadf6 100644 --- a/lib/solana/deposit.ts +++ b/lib/solana/deposit.ts @@ -24,9 +24,6 @@ import { Position, } from "./constants" -// Memo Program ID -export const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcQb") - /** * Get the vault PDA address */ @@ -136,8 +133,6 @@ export interface DepositParams { userPublicKey: PublicKey amount: number // in USDC (e.g., 10.5 for $10.50) marketId: string - marketQuestion: string - expiry: number position: Position } @@ -155,7 +150,7 @@ export interface DepositResult { export async function buildDepositTransaction( params: DepositParams ): Promise { - const { connection, userPublicKey, amount, marketId, marketQuestion, expiry, position } = params + const { connection, userPublicKey, amount, marketId, position } = params // Get PDAs const [vault] = getVaultPDA() @@ -229,25 +224,6 @@ export async function buildDepositTransaction( ) ) - // Add Memo Instruction to persist position data on-chain - const memoData = JSON.stringify({ - type: "polyield_position", - marketId, - marketQuestion, - position, - amount, - expiry, - timestamp: Date.now() - }) - - transaction.add( - new TransactionInstruction({ - keys: [], - programId: MEMO_PROGRAM_ID, - data: Buffer.from(memoData, "utf-8"), - }) - ) - /* // Anchor Program Instruction (Commented out until deployment) const data = buildDepositInstructionData(amountLamports, marketId, position) From 85e7756777e3012c3d5c38f3ec60c87cbf695d9c Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 08:51:14 -0500 Subject: [PATCH 07/26] database configired with postgres and supabase. can hide/show if its connected --- BRANCH_SUMMARY.md | 134 ++++++++++ DATABASE_IMPLEMENTATION.md | 241 ++++++++++++++++++ SUPABASE_SETUP.md | 46 ++++ components/deposit-modal.tsx | 22 +- hooks/use-deposit.ts | 34 ++- hooks/use-positions.ts | 125 ++++++--- .../migrations/001_initial_schema.sql | 51 ++++ lib/database/positions-service.ts | 163 ++++++++++++ lib/database/supabase.ts | 19 ++ lib/database/types.ts | 64 +++++ package.json | 1 + pnpm-lock.yaml | 76 ++++++ 12 files changed, 936 insertions(+), 40 deletions(-) create mode 100644 BRANCH_SUMMARY.md create mode 100644 DATABASE_IMPLEMENTATION.md create mode 100644 SUPABASE_SETUP.md create mode 100644 lib/database/migrations/001_initial_schema.sql create mode 100644 lib/database/positions-service.ts create mode 100644 lib/database/supabase.ts create mode 100644 lib/database/types.ts diff --git a/BRANCH_SUMMARY.md b/BRANCH_SUMMARY.md new file mode 100644 index 0000000..0a8354a --- /dev/null +++ b/BRANCH_SUMMARY.md @@ -0,0 +1,134 @@ +# Database Branch - Implementation Summary + +## What Was Changed + +This branch replaces the localStorage-based position tracking system with a persistent Supabase database solution. Users can now access their positions and market history from any browser or device by simply connecting their wallet. + +## Files Created + +### Database Infrastructure +- **`lib/database/supabase.ts`** - Supabase client initialization with environment variable validation +- **`lib/database/types.ts`** - TypeScript type definitions for the `user_positions` table +- **`lib/database/positions-service.ts`** - Service layer with functions for CRUD operations +- **`lib/database/migrations/001_initial_schema.sql`** - SQL migration to create tables and indexes + +### Documentation +- **`SUPABASE_SETUP.md`** - Quick setup guide for configuring Supabase +- **`DATABASE_IMPLEMENTATION.md`** - Comprehensive implementation documentation +- **`BRANCH_SUMMARY.md`** - This file + +## Files Modified + +### Hooks +- **`hooks/use-positions.ts`** + - Added Supabase database integration + - Implemented automatic fallback to localStorage if Supabase not configured + - Added `isLoading`, `error`, and `refreshPositions` to return values + - Updated `addPosition` to be async and accept `transactionSignature` parameter + +- **`hooks/use-deposit.ts`** + - Updated `deposit` function signature to accept `marketQuestion` and `expiryTimestamp` + - Added automatic position saving to database after successful transactions + - Graceful error handling if database save fails (transaction still succeeds) + +### Components +- **`components/deposit-modal.tsx`** + - Updated `handleDeposit` to pass new required parameters + - Ensures positions are saved to database with transaction signatures + +### Dependencies +- **`package.json`** / **`pnpm-lock.yaml`** + - Added `@supabase/supabase-js` v2.90.1 + +## Key Features + +✅ **Cross-Device Persistence** - Positions stored by wallet address, accessible from any browser/device +✅ **Transaction Tracking** - Each position includes the Solana transaction signature +✅ **Automatic Fallback** - Gracefully falls back to localStorage if Supabase not configured +✅ **No Hardcoded Secrets** - All credentials in `.env.local` (not committed to repo) +✅ **Type Safety** - Full TypeScript types for database operations +✅ **Optimized Queries** - Database indexes for fast lookups by wallet, market, and status + +## Environment Variables Required + +Create a `.env.local` file with: + +```bash +NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url +NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key +``` + +**Note:** `.env.local` is already in `.gitignore` and will not be committed. + +## Setup Steps + +1. **Create Supabase Project** at [supabase.com](https://supabase.com) +2. **Run Migration**: Execute `lib/database/migrations/001_initial_schema.sql` in Supabase SQL Editor +3. **Configure Environment**: Create `.env.local` with your Supabase credentials +4. **Restart Dev Server**: `pnpm dev` + +For detailed instructions, see `SUPABASE_SETUP.md` + +## Database Schema + +### `user_positions` Table +```sql +- id (UUID, primary key) +- wallet_address (TEXT, indexed) +- market_id (TEXT, indexed) +- market_question (TEXT) +- position (TEXT: 'YES' or 'NO') +- amount (DECIMAL) +- transaction_signature (TEXT) +- timestamp (TIMESTAMPTZ) +- expiry_timestamp (TIMESTAMPTZ) +- status (TEXT: 'active', 'claimed', or 'refunded') +- created_at (TIMESTAMPTZ) +- updated_at (TIMESTAMPTZ, auto-updated) +``` + +## Backward Compatibility + +- ✅ Works without Supabase (falls back to localStorage) +- ✅ No breaking changes to existing functionality +- ⚠️ Existing localStorage positions won't auto-migrate (manual migration possible) + +## Testing Checklist + +- [ ] Create Supabase project and run migration +- [ ] Configure `.env.local` with Supabase credentials +- [ ] Connect wallet and make a test deposit +- [ ] Verify position appears in Supabase dashboard +- [ ] Disconnect wallet, reconnect, verify positions load +- [ ] Test on different browser/device with same wallet +- [ ] Test without `.env.local` (should fallback to localStorage) + +## Next Steps / Future Enhancements + +- [ ] Implement position status updates (claimed/refunded) +- [ ] Add real-time subscriptions for live position updates +- [ ] Implement wallet-based RLS policies for production +- [ ] Create admin interface for market resolution +- [ ] Add position migration tool from localStorage to Supabase +- [ ] Implement analytics dashboard for position tracking + +## Commit Message Suggestion + +``` +feat: Replace localStorage with Supabase database for position tracking + +- Add Supabase client and database service layer +- Create user_positions table with wallet address indexing +- Update hooks to save/fetch positions from database +- Implement automatic fallback to localStorage if not configured +- Store transaction signatures with each position +- Enable cross-device position access via wallet connection + +All API keys configured via .env.local (not hardcoded) +``` + +## Questions or Issues? + +Refer to: +- `SUPABASE_SETUP.md` - Setup instructions +- `DATABASE_IMPLEMENTATION.md` - Technical details and troubleshooting diff --git a/DATABASE_IMPLEMENTATION.md b/DATABASE_IMPLEMENTATION.md new file mode 100644 index 0000000..47d52ff --- /dev/null +++ b/DATABASE_IMPLEMENTATION.md @@ -0,0 +1,241 @@ +# Database Implementation Guide + +## Overview + +This implementation replaces the localStorage-based position tracking with a persistent Supabase database. This ensures users can access their positions and markets from any browser or device by connecting their wallet. + +## Key Features + +✅ **Cross-Device Persistence** - Users can see their positions anywhere they connect their wallet +✅ **No API Key Hardcoding** - All credentials stored in `.env.local` +✅ **Automatic Fallback** - Falls back to localStorage if Supabase is not configured +✅ **Transaction Tracking** - Stores Solana transaction signatures with each position +✅ **Market History** - Tracks all markets a user has entered + +## Architecture + +### Database Layer +- **`lib/database/supabase.ts`** - Supabase client initialization +- **`lib/database/types.ts`** - TypeScript type definitions for database tables +- **`lib/database/positions-service.ts`** - Service layer for position CRUD operations +- **`lib/database/migrations/001_initial_schema.sql`** - SQL migration for table creation + +### Updated Hooks +- **`hooks/use-positions.ts`** - Now fetches positions from Supabase (with localStorage fallback) +- **`hooks/use-deposit.ts`** - Automatically saves positions to database after successful deposits + +### Updated Components +- **`components/deposit-modal.tsx`** - Passes required parameters to save positions + +## Setup Instructions + +### 1. Create a Supabase Project + +1. Go to [https://supabase.com](https://supabase.com) and sign up/log in +2. Create a new project +3. Wait for the project to finish provisioning + +### 2. Run the Database Migration + +1. Navigate to your Supabase project dashboard +2. Go to **SQL Editor** (in the left sidebar) +3. Click **New Query** +4. Copy the contents of `lib/database/migrations/001_initial_schema.sql` +5. Paste into the SQL Editor +6. Click **Run** to execute the migration + +This will create: +- `user_positions` table with proper indexes +- Automatic `updated_at` timestamp triggers +- Row Level Security policies + +### 3. Configure Environment Variables + +1. In your Supabase project, go to **Settings > API** +2. Copy your **Project URL** and **anon/public key** +3. Create a `.env.local` file in the project root: + +```bash +# Supabase Configuration +NEXT_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here +``` + +4. **Important:** Never commit `.env.local` to version control (it's already in `.gitignore`) + +### 4. Restart Your Development Server + +```bash +pnpm dev +``` + +## Database Schema + +### `user_positions` Table + +| Column | Type | Description | +|--------|------|-------------| +| `id` | UUID | Primary key (auto-generated) | +| `wallet_address` | TEXT | User's Solana wallet address | +| `market_id` | TEXT | Unique market identifier | +| `market_question` | TEXT | The market's question/title | +| `position` | TEXT | 'YES' or 'NO' | +| `amount` | DECIMAL(20,6) | Deposit amount in USDC | +| `transaction_signature` | TEXT | Solana transaction signature | +| `timestamp` | TIMESTAMPTZ | When the position was created | +| `expiry_timestamp` | TIMESTAMPTZ | When the market expires | +| `status` | TEXT | 'active', 'claimed', or 'refunded' | +| `created_at` | TIMESTAMPTZ | Database record creation time | +| `updated_at` | TIMESTAMPTZ | Last update time | + +### Indexes + +- `idx_user_positions_wallet_address` - Fast lookup by wallet +- `idx_user_positions_market_id` - Fast lookup by market +- `idx_user_positions_status` - Filter by status +- `idx_user_positions_wallet_status` - Combined wallet + status queries + +## Usage + +### Querying Positions + +The service layer provides several convenience functions: + +```typescript +// Get all positions for a wallet +const positions = await getPositionsByWallet(walletAddress) + +// Get only active positions +const activePositions = await getActivePositions(walletAddress) + +// Get positions for a specific market +const marketPositions = await getPositionsByMarket(marketId) +``` + +### Creating Positions + +Positions are automatically created when users make deposits through the `deposit-modal.tsx` component: + +```typescript +await createPosition({ + walletAddress: publicKey.toBase58(), + marketId, + marketQuestion, + position, + amount, + transactionSignature: signature, + timestamp: Date.now(), + expiryTimestamp, +}) +``` + +### Updating Position Status + +When a market is resolved, you can update position statuses: + +```typescript +await updatePositionStatus(positionId, "claimed") +// or +await updatePositionStatus(positionId, "refunded") +``` + +## Fallback Behavior + +If Supabase is not configured (missing environment variables), the system automatically falls back to localStorage: + +- Positions are stored per wallet address in browser storage +- Data persists only on the same browser/device +- No cross-device synchronization +- Console warnings will indicate fallback mode + +To check configuration status: + +```typescript +import { isSupabaseConfigured } from '@/lib/database/positions-service' + +if (isSupabaseConfigured()) { + // Using Supabase +} else { + // Using localStorage fallback +} +``` + +## Security Considerations + +### Row Level Security (RLS) + +The database has RLS enabled with a permissive policy. For production, consider implementing wallet-based authentication: + +```sql +-- Example: Restrict to authenticated users +CREATE POLICY "Users can only view their own positions" + ON user_positions + FOR SELECT + USING (wallet_address = auth.jwt() ->> 'wallet_address'); +``` + +### API Keys + +- The `NEXT_PUBLIC_SUPABASE_ANON_KEY` is safe to expose in the browser +- It only has permissions you configure in Supabase RLS policies +- Never expose your service role key or other sensitive credentials + +## Troubleshooting + +### "Missing Supabase environment variables" Error + +- Ensure `.env.local` exists in the project root +- Verify the file contains valid `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` +- Restart your development server after adding environment variables + +### Positions Not Showing Up + +1. Check browser console for errors +2. Verify the SQL migration ran successfully in Supabase +3. Check Supabase logs for any RLS policy issues +4. Ensure wallet is connected + +### "Failed to fetch positions" Error + +- Verify your Supabase project is running +- Check your internet connection +- Verify the project URL in `.env.local` is correct +- Check Supabase dashboard for any service issues + +## Migration from localStorage + +Existing positions stored in localStorage will **not** automatically migrate to the database. Users will need to: + +1. View their positions one final time (they'll load from localStorage) +2. After Supabase is configured, new deposits will save to the database +3. Old positions will remain in localStorage but won't appear after clearing browser data + +To implement a migration script, you could: + +```typescript +// Example migration (run once per user) +function migrateLocalStorageToSupabase(walletAddress: string) { + const stored = localStorage.getItem(`polyield_positions_${walletAddress}`) + if (stored) { + const positions = JSON.parse(stored) + // Batch insert to Supabase + positions.forEach(pos => createPosition({...pos, walletAddress})) + // Optionally clear localStorage after successful migration + } +} +``` + +## Next Steps + +- [ ] Implement wallet-based authentication for RLS +- [ ] Add position update endpoints for claiming/refunding +- [ ] Create admin dashboard for market resolution +- [ ] Implement real-time subscriptions for live position updates +- [ ] Add analytics and reporting queries + +## Support + +For issues or questions: +- Check the [Supabase Documentation](https://supabase.com/docs) +- Review the `SUPABASE_SETUP.md` guide +- Check Supabase project logs in the dashboard diff --git a/SUPABASE_SETUP.md b/SUPABASE_SETUP.md new file mode 100644 index 0000000..e13510a --- /dev/null +++ b/SUPABASE_SETUP.md @@ -0,0 +1,46 @@ +# Supabase Setup Guide + +## Prerequisites + +1. Create a Supabase account at https://supabase.com +2. Create a new project in Supabase + +## Environment Variables Setup + +Create a `.env.local` file in the root directory with the following variables: + +```bash +# Supabase Configuration +# Get these values from your Supabase project settings: https://app.supabase.com/project/_/settings/api + +# Your Supabase project URL +NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url_here + +# Your Supabase anonymous/public key (safe to expose in browser) +NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key_here +``` + +**Important:** The `.env.local` file is already in `.gitignore` and will not be committed to version control. + +## Database Schema + +Run the SQL migration in `lib/database/migrations/001_initial_schema.sql` in your Supabase SQL Editor to create the necessary tables: + +1. Go to your Supabase project dashboard +2. Navigate to the SQL Editor +3. Copy and paste the contents of the migration file +4. Execute the SQL + +## Table Structure + +### `user_positions` Table +- Stores all user positions across wallets and browsers +- Linked to wallet addresses for cross-device/browser persistence +- Tracks market entries, positions (YES/NO), amounts, and timestamps + +## Usage + +Once configured, the app will automatically: +- Store positions when users make deposits +- Fetch positions when users connect their wallet +- Sync positions across any browser or device where the user connects with the same wallet diff --git a/components/deposit-modal.tsx b/components/deposit-modal.tsx index e08dccf..02f51e8 100644 --- a/components/deposit-modal.tsx +++ b/components/deposit-modal.tsx @@ -68,15 +68,23 @@ export function DepositModal({ const handleDeposit = async () => { if (numericAmount <= 0) return - const signature = await deposit(numericAmount, marketId, positionEnum) + + // Parse expiry string to timestamp, fallback to 30 days from now + const expiryTimestamp = marketExpiry + ? new Date(marketExpiry).getTime() + : Date.now() + (30 * 24 * 60 * 60 * 1000) - if (signature) { - // Parse expiry string to timestamp, fallback to 30 days from now - const expiryTimestamp = marketExpiry - ? new Date(marketExpiry).getTime() - : Date.now() + (30 * 24 * 60 * 60 * 1000) + const signature = await deposit( + numericAmount, + marketId, + positionEnum, + marketQuestion, + expiryTimestamp + ) - addPosition(marketId, marketQuestion, positionEnum, numericAmount, expiryTimestamp) + if (signature) { + // If using localStorage fallback, also add to local state + addPosition(marketId, marketQuestion, positionEnum, numericAmount, expiryTimestamp, signature) } } diff --git a/hooks/use-deposit.ts b/hooks/use-deposit.ts index 394b438..3a2333e 100644 --- a/hooks/use-deposit.ts +++ b/hooks/use-deposit.ts @@ -7,6 +7,10 @@ import { getUserUsdcBalance, Position, } from "@/lib/solana/deposit" +import { + createPosition, + isSupabaseConfigured +} from "@/lib/database/positions-service" export interface DepositState { isLoading: boolean @@ -16,7 +20,7 @@ export interface DepositState { } export interface UseDepositReturn extends DepositState { - deposit: (amount: number, marketId: string, position: Position) => Promise + deposit: (amount: number, marketId: string, position: Position, marketQuestion: string, expiryTimestamp: number) => Promise refreshBalance: () => Promise clearError: () => void clearTx: () => void @@ -50,7 +54,9 @@ export function useDeposit(): UseDepositReturn { const deposit = useCallback(async ( amount: number, marketId: string, - position: Position + position: Position, + marketQuestion: string, + expiryTimestamp: number ): Promise => { if (!publicKey || !signTransaction || !connected) { setState(prev => ({ @@ -115,6 +121,30 @@ export function useDeposit(): UseDepositReturn { throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`) } + // Save position to database if Supabase is configured + const supabaseConfigured = isSupabaseConfigured() + if (supabaseConfigured) { + try { + await createPosition({ + walletAddress: publicKey.toBase58(), + marketId, + marketQuestion, + position, + amount, + transactionSignature: signature, + timestamp: Date.now(), + expiryTimestamp, + }) + console.log("Position saved to database successfully") + } catch (dbError) { + console.error("Failed to save position to database:", dbError) + // Don't fail the whole transaction if database save fails + // User can still see their transaction on-chain + } + } else { + console.warn("Supabase not configured. Position not saved to database. Please set up .env.local") + } + setState(prev => ({ ...prev, isLoading: false, diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts index 150ace3..7391f03 100644 --- a/hooks/use-positions.ts +++ b/hooks/use-positions.ts @@ -1,8 +1,13 @@ "use client" -import { useState, useEffect } from "react" +import { useState, useEffect, useCallback } from "react" import { useWallet } from "@solana/wallet-adapter-react" import { Position } from "@/lib/solana/constants" +import { + getPositionsByWallet, + isSupabaseConfigured +} from "@/lib/database/positions-service" +import type { UserPosition as DbUserPosition } from "@/lib/database/types" export interface UserPosition { id: string @@ -18,38 +23,80 @@ export interface UserPosition { // Mock APY for yield calculation (e.g., 12%) const MOCK_APY = 0.12 +// Convert database position to UI position format +function convertDbPositionToUi(dbPosition: DbUserPosition): UserPosition { + return { + id: dbPosition.id, + marketId: dbPosition.market_id, + marketQuestion: dbPosition.market_question, + position: dbPosition.position === "YES" ? Position.Yes : Position.No, + amount: Number(dbPosition.amount), + timestamp: new Date(dbPosition.timestamp).getTime(), + expiryTimestamp: new Date(dbPosition.expiry_timestamp).getTime(), + status: dbPosition.status, + } +} + export function usePositions() { const { publicKey } = useWallet() const [positions, setPositions] = useState([]) const [totalYield, setTotalYield] = useState(0) const [totalValue, setTotalValue] = useState(0) + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState(null) + const [useLocalStorage, setUseLocalStorage] = useState(false) - // Load positions from local storage + // Check if Supabase is configured, otherwise fall back to localStorage useEffect(() => { + const configured = isSupabaseConfigured() + setUseLocalStorage(!configured) + if (!configured) { + console.warn("Supabase not configured. Falling back to localStorage. Please set up .env.local with Supabase credentials.") + } + }, []) + + // Load positions from Supabase or localStorage + const loadPositions = useCallback(async () => { if (!publicKey) { setPositions([]) + setTotalYield(0) + setTotalValue(0) return } - const loadPositions = () => { - try { + setIsLoading(true) + setError(null) + + try { + if (useLocalStorage) { + // Fallback to localStorage if Supabase not configured const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) if (stored) { const parsed = JSON.parse(stored) setPositions(parsed) calculateTotals(parsed) + } else { + setPositions([]) } - } catch (e) { - console.error("Failed to load positions", e) + } else { + // Use Supabase database + const dbPositions = await getPositionsByWallet(publicKey.toBase58()) + const uiPositions = dbPositions.map(convertDbPositionToUi) + setPositions(uiPositions) + calculateTotals(uiPositions) } + } catch (e) { + console.error("Failed to load positions", e) + setError(e instanceof Error ? e.message : "Failed to load positions") + setPositions([]) + } finally { + setIsLoading(false) } + }, [publicKey, useLocalStorage]) + useEffect(() => { loadPositions() - - // Listen for storage events to update real-time - window.addEventListener("storage", loadPositions) - return () => window.removeEventListener("storage", loadPositions) - }, [publicKey]) + }, [loadPositions]) const calculateTotals = (currentPositions: UserPosition[]) => { const now = Date.now() @@ -76,34 +123,47 @@ export function usePositions() { setTotalValue(valueSum) } - const addPosition = ( + const addPosition = async ( marketId: string, marketQuestion: string, position: Position, amount: number, - expiryTimestamp: number + expiryTimestamp: number, + transactionSignature?: string ) => { if (!publicKey) return - const newPosition: UserPosition = { - id: Math.random().toString(36).substring(7), - marketId, - marketQuestion, - position, - amount, - timestamp: Date.now(), - expiryTimestamp, - status: "active" - } + try { + if (useLocalStorage) { + // Fallback to localStorage + const newPosition: UserPosition = { + id: Math.random().toString(36).substring(7), + marketId, + marketQuestion, + position, + amount, + timestamp: Date.now(), + expiryTimestamp, + status: "active" + } - const updated = [...positions, newPosition] - setPositions(updated) - calculateTotals(updated) - - localStorage.setItem( - `polyield_positions_${publicKey.toBase58()}`, - JSON.stringify(updated) - ) + const updated = [...positions, newPosition] + setPositions(updated) + calculateTotals(updated) + + localStorage.setItem( + `polyield_positions_${publicKey.toBase58()}`, + JSON.stringify(updated) + ) + } else { + // Use Supabase database - will be added by use-deposit hook + // This will trigger a refresh to load the newly added position + await loadPositions() + } + } catch (e) { + console.error("Failed to add position", e) + setError(e instanceof Error ? e.message : "Failed to add position") + } } return { @@ -111,6 +171,9 @@ export function usePositions() { totalYield, totalValue, addPosition, + isLoading, + error, + refreshPositions: loadPositions, apy: MOCK_APY } } diff --git a/lib/database/migrations/001_initial_schema.sql b/lib/database/migrations/001_initial_schema.sql new file mode 100644 index 0000000..1bca526 --- /dev/null +++ b/lib/database/migrations/001_initial_schema.sql @@ -0,0 +1,51 @@ +-- Create user_positions table to store all user positions across wallets and browsers +-- This replaces the localStorage-based approach with persistent database storage + +CREATE TABLE IF NOT EXISTS user_positions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + wallet_address TEXT NOT NULL, + market_id TEXT NOT NULL, + market_question TEXT NOT NULL, + position TEXT NOT NULL CHECK (position IN ('YES', 'NO')), + amount DECIMAL(20, 6) NOT NULL, + transaction_signature TEXT, + timestamp TIMESTAMPTZ NOT NULL, + expiry_timestamp TIMESTAMPTZ NOT NULL, + status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'claimed', 'refunded')), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +-- Create indexes for better query performance +CREATE INDEX IF NOT EXISTS idx_user_positions_wallet_address ON user_positions(wallet_address); +CREATE INDEX IF NOT EXISTS idx_user_positions_market_id ON user_positions(market_id); +CREATE INDEX IF NOT EXISTS idx_user_positions_status ON user_positions(status); +CREATE INDEX IF NOT EXISTS idx_user_positions_wallet_status ON user_positions(wallet_address, status); + +-- Create a function to automatically update the updated_at timestamp +CREATE OR REPLACE FUNCTION update_updated_at_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Create a trigger to call the function before each update +CREATE TRIGGER update_user_positions_updated_at + BEFORE UPDATE ON user_positions + FOR EACH ROW + EXECUTE FUNCTION update_updated_at_column(); + +-- Enable Row Level Security (RLS) +ALTER TABLE user_positions ENABLE ROW LEVEL SECURITY; + +-- Create a policy that allows all operations for now +-- You can make this more restrictive based on your auth requirements +CREATE POLICY "Enable all operations for all users" ON user_positions + FOR ALL + USING (true) + WITH CHECK (true); + +-- Add a comment to the table +COMMENT ON TABLE user_positions IS 'Stores user positions for Polyield markets, indexed by wallet address for cross-device/browser persistence'; diff --git a/lib/database/positions-service.ts b/lib/database/positions-service.ts new file mode 100644 index 0000000..360fe43 --- /dev/null +++ b/lib/database/positions-service.ts @@ -0,0 +1,163 @@ +"use client" + +import { supabase } from "./supabase" +import type { UserPosition, UserPositionInsert } from "./types" +import { Position } from "../solana/constants" + +/** + * Service layer for managing user positions in Supabase + * Replaces the localStorage-based approach with persistent database storage + */ + +export interface CreatePositionParams { + walletAddress: string + marketId: string + marketQuestion: string + position: Position + amount: number + transactionSignature?: string + timestamp: number + expiryTimestamp: number +} + +/** + * Fetch all positions for a given wallet address + */ +export async function getPositionsByWallet( + walletAddress: string +): Promise { + const { data, error } = await supabase + .from("user_positions") + .select("*") + .eq("wallet_address", walletAddress) + .order("timestamp", { ascending: false }) + + if (error) { + console.error("Error fetching positions:", error) + throw new Error(`Failed to fetch positions: ${error.message}`) + } + + return data || [] +} + +/** + * Create a new position record + */ +export async function createPosition( + params: CreatePositionParams +): Promise { + const positionData: UserPositionInsert = { + wallet_address: params.walletAddress, + market_id: params.marketId, + market_question: params.marketQuestion, + position: params.position === Position.Yes ? "YES" : "NO", + amount: params.amount, + transaction_signature: params.transactionSignature || null, + timestamp: new Date(params.timestamp).toISOString(), + expiry_timestamp: new Date(params.expiryTimestamp).toISOString(), + status: "active", + } + + const { data, error } = await supabase + .from("user_positions") + .insert(positionData) + .select() + .single() + + if (error) { + console.error("Error creating position:", error) + throw new Error(`Failed to create position: ${error.message}`) + } + + return data +} + +/** + * Update a position status (e.g., when claimed or refunded) + */ +export async function updatePositionStatus( + positionId: string, + status: "active" | "claimed" | "refunded" +): Promise { + const { data, error } = await supabase + .from("user_positions") + .update({ status }) + .eq("id", positionId) + .select() + .single() + + if (error) { + console.error("Error updating position status:", error) + throw new Error(`Failed to update position: ${error.message}`) + } + + return data +} + +/** + * Get active positions for a wallet (not claimed or refunded) + */ +export async function getActivePositions( + walletAddress: string +): Promise { + const { data, error } = await supabase + .from("user_positions") + .select("*") + .eq("wallet_address", walletAddress) + .eq("status", "active") + .order("timestamp", { ascending: false }) + + if (error) { + console.error("Error fetching active positions:", error) + throw new Error(`Failed to fetch active positions: ${error.message}`) + } + + return data || [] +} + +/** + * Get positions for a specific market + */ +export async function getPositionsByMarket( + marketId: string +): Promise { + const { data, error } = await supabase + .from("user_positions") + .select("*") + .eq("market_id", marketId) + .order("timestamp", { ascending: false }) + + if (error) { + console.error("Error fetching market positions:", error) + throw new Error(`Failed to fetch market positions: ${error.message}`) + } + + return data || [] +} + +/** + * Delete a position (use with caution) + */ +export async function deletePosition(positionId: string): Promise { + const { error } = await supabase + .from("user_positions") + .delete() + .eq("id", positionId) + + if (error) { + console.error("Error deleting position:", error) + throw new Error(`Failed to delete position: ${error.message}`) + } +} + +/** + * Check if Supabase is properly configured + */ +export function isSupabaseConfigured(): boolean { + return !!( + process.env.NEXT_PUBLIC_SUPABASE_URL && + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY && + process.env.NEXT_PUBLIC_SUPABASE_URL !== "your_supabase_project_url_here" && + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY !== "your_supabase_anon_key_here" + ) +} diff --git a/lib/database/supabase.ts b/lib/database/supabase.ts new file mode 100644 index 0000000..0fc1785 --- /dev/null +++ b/lib/database/supabase.ts @@ -0,0 +1,19 @@ +import { createClient } from "@supabase/supabase-js" +import type { Database } from "./types" + +// Initialize the Supabase client +// These environment variables should be set in .env.local +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL +const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY + +if (!supabaseUrl || !supabaseAnonKey) { + throw new Error( + "Missing Supabase environment variables. Please create a .env.local file with NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY" + ) +} + +export const supabase = createClient(supabaseUrl, supabaseAnonKey, { + auth: { + persistSession: false, // We don't need auth sessions, just storing data by wallet address + }, +}) diff --git a/lib/database/types.ts b/lib/database/types.ts new file mode 100644 index 0000000..f757f1a --- /dev/null +++ b/lib/database/types.ts @@ -0,0 +1,64 @@ +// Database types for Supabase tables +export type Json = + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] + +export interface Database { + public: { + Tables: { + user_positions: { + Row: { + id: string + wallet_address: string + market_id: string + market_question: string + position: "YES" | "NO" + amount: number + transaction_signature: string | null + timestamp: string + expiry_timestamp: string + status: "active" | "claimed" | "refunded" + created_at: string + updated_at: string + } + Insert: { + id?: string + wallet_address: string + market_id: string + market_question: string + position: "YES" | "NO" + amount: number + transaction_signature?: string | null + timestamp: string + expiry_timestamp: string + status?: "active" | "claimed" | "refunded" + created_at?: string + updated_at?: string + } + Update: { + id?: string + wallet_address?: string + market_id?: string + market_question?: string + position?: "YES" | "NO" + amount?: number + transaction_signature?: string | null + timestamp?: string + expiry_timestamp?: string + status?: "active" | "claimed" | "refunded" + created_at?: string + updated_at?: string + } + } + } + } +} + +// Type aliases for easier use +export type UserPosition = Database["public"]["Tables"]["user_positions"]["Row"] +export type UserPositionInsert = Database["public"]["Tables"]["user_positions"]["Insert"] +export type UserPositionUpdate = Database["public"]["Tables"]["user_positions"]["Update"] diff --git a/package.json b/package.json index 75a6496..39508a8 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@solana/wallet-adapter-react-ui": "^0.9.39", "@solana/wallet-adapter-wallets": "^0.19.37", "@solana/web3.js": "^1.98.4", + "@supabase/supabase-js": "^2.90.1", "@vercel/analytics": "1.3.1", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cadee4..3f99ce4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -128,6 +128,9 @@ importers: '@solana/web3.js': specifier: ^1.98.4 version: 1.98.4(bufferutil@4.1.0)(typescript@5.0.2)(utf-8-validate@5.0.10) + '@supabase/supabase-js': + specifier: ^2.90.1 + version: 2.90.1(bufferutil@4.1.0)(utf-8-validate@5.0.10) '@vercel/analytics': specifier: 1.3.1 version: 1.3.1(next@15.2.4(@babel/core@7.28.6)(babel-plugin-react-compiler@1.0.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) @@ -3204,6 +3207,30 @@ packages: peerDependencies: react: '>= 16.3.0' + '@supabase/auth-js@2.90.1': + resolution: {integrity: sha512-vxb66dgo6h3yyPbR06735Ps+dK3hj0JwS8w9fdQPVZQmocSTlKUW5MfxSy99mN0XqCCuLMQ3jCEiIIUU23e9ng==} + engines: {node: '>=20.0.0'} + + '@supabase/functions-js@2.90.1': + resolution: {integrity: sha512-x9mV9dF1Lam9qL3zlpP6mSM5C9iqMPtF5B/tU1Jj/F0ufX5mjDf9ghVBaErVxmrQJRL4+iMKWKY2GnODkpS8tw==} + engines: {node: '>=20.0.0'} + + '@supabase/postgrest-js@2.90.1': + resolution: {integrity: sha512-jh6vqzaYzoFn3raaC0hcFt9h+Bt+uxNRBSdc7PfToQeRGk7PDPoweHsbdiPWREtDVTGKfu+PyPW9e2jbK+BCgQ==} + engines: {node: '>=20.0.0'} + + '@supabase/realtime-js@2.90.1': + resolution: {integrity: sha512-PWbnEMkcQRuor8jhObp4+Snufkq8C6fBp+MchVp2qBPY1NXk/c3Iv3YyiFYVzo0Dzuw4nAlT4+ahuPggy4r32w==} + engines: {node: '>=20.0.0'} + + '@supabase/storage-js@2.90.1': + resolution: {integrity: sha512-GHY+Ps/K/RBfRj7kwx+iVf2HIdqOS43rM2iDOIDpapyUnGA9CCBFzFV/XvfzznGykd//z2dkGZhlZZprsVFqGg==} + engines: {node: '>=20.0.0'} + + '@supabase/supabase-js@2.90.1': + resolution: {integrity: sha512-U8KaKGLUgTIFHtwEW1dgw1gK7XrdpvvYo7nzzqPx721GqPe8WZbAiLh/hmyKLGBYQ/mmQNr20vU9tWSDZpii3w==} + engines: {node: '>=20.0.0'} + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -3526,6 +3553,9 @@ packages: '@types/offscreencanvas@2019.7.3': resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} + '@types/phoenix@1.6.7': + resolution: {integrity: sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==} + '@types/react-dom@19.0.0': resolution: {integrity: sha512-1KfiQKsH1o00p9m5ag12axHQSb3FOU9H20UTrujVSkNhuCrRHiQWFqgEnTNK5ZNfnzZv8UWrnXVqCmCF9fgY3w==} @@ -5106,6 +5136,10 @@ packages: hyphenate-style-name@1.1.0: resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + iceberg-js@0.8.1: + resolution: {integrity: sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==} + engines: {node: '>=20.0.0'} + idb-keyval@6.2.2: resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} @@ -11548,6 +11582,44 @@ snapshots: dependencies: react: 19.0.0 + '@supabase/auth-js@2.90.1': + dependencies: + tslib: 2.8.1 + + '@supabase/functions-js@2.90.1': + dependencies: + tslib: 2.8.1 + + '@supabase/postgrest-js@2.90.1': + dependencies: + tslib: 2.8.1 + + '@supabase/realtime-js@2.90.1(bufferutil@4.1.0)(utf-8-validate@5.0.10)': + dependencies: + '@types/phoenix': 1.6.7 + '@types/ws': 8.18.1 + tslib: 2.8.1 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@supabase/storage-js@2.90.1': + dependencies: + iceberg-js: 0.8.1 + tslib: 2.8.1 + + '@supabase/supabase-js@2.90.1(bufferutil@4.1.0)(utf-8-validate@5.0.10)': + dependencies: + '@supabase/auth-js': 2.90.1 + '@supabase/functions-js': 2.90.1 + '@supabase/postgrest-js': 2.90.1 + '@supabase/realtime-js': 2.90.1(bufferutil@4.1.0)(utf-8-validate@5.0.10) + '@supabase/storage-js': 2.90.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.15': @@ -12045,6 +12117,8 @@ snapshots: '@types/offscreencanvas@2019.7.3': {} + '@types/phoenix@1.6.7': {} + '@types/react-dom@19.0.0': dependencies: '@types/react': 19.0.0 @@ -14171,6 +14245,8 @@ snapshots: hyphenate-style-name@1.1.0: {} + iceberg-js@0.8.1: {} + idb-keyval@6.2.2: {} ieee754@1.2.1: {} From 26c9f1837d622b357cc688f5c9084768f6fdd923 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 08:53:53 -0500 Subject: [PATCH 08/26] . --- app/layout.tsx | 2 + components/SUPABASE_STATUS_README.md | 122 ++++++++++++++++ components/supabase-status.tsx | 201 +++++++++++++++++++++++++++ lib/database/supabase.ts | 11 +- 4 files changed, 328 insertions(+), 8 deletions(-) create mode 100644 components/SUPABASE_STATUS_README.md create mode 100644 components/supabase-status.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 3627087..9d2de2c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,6 +4,7 @@ import { Geist_Mono } from "next/font/google" import "./globals.css" import { Header } from "@/components/header" import AppWalletProvider from "@/components/AppWalletProvider" +import { SupabaseStatus } from "@/components/supabase-status" const geistMono = Geist_Mono({ variable: "--font-geist-mono", @@ -27,6 +28,7 @@ export default function RootLayout({
{children} + diff --git a/components/SUPABASE_STATUS_README.md b/components/SUPABASE_STATUS_README.md new file mode 100644 index 0000000..ef41df8 --- /dev/null +++ b/components/SUPABASE_STATUS_README.md @@ -0,0 +1,122 @@ +# Supabase Status Indicator + +A visual debug component that shows the connection status of your Supabase database. + +## Features + +✅ Shows real-time Supabase connection status +✅ Indicates if using database or localStorage fallback +✅ Displays project URL and error messages +✅ Click to expand for detailed information +✅ **Easy to enable/disable with a single flag** + +## Location + +The status indicator appears as a small pill in the **bottom-right corner** of the screen on all pages. + +## How to Toggle + +Open `components/supabase-status.tsx` and change this line: + +```typescript +// Line 10 +const SHOW_SUPABASE_STATUS = false // Set to false to hide +``` + +- **`true`** - Status indicator is visible ✅ +- **`false`** - Status indicator is completely hidden ❌ + +## Status States + +### 🟢 Connected (Green) +- **Supabase: Connected** +- Database is configured and working +- Positions are being saved to Supabase + +### 🟡 localStorage (Yellow/Amber) +- **Supabase: localStorage** +- Supabase not configured +- Falling back to browser localStorage +- Positions won't sync across devices + +### 🔴 Error (Red) +- **Supabase: Error** +- Supabase is configured but connection failed +- Check the expanded view for error details + +### ⚪ Checking... (Gray) +- Initial connection test in progress + +## Expanded View + +Click the status pill to expand and see: + +- **Configured**: Whether `.env.local` has valid credentials +- **Connected**: Whether database queries are working +- **Project**: Your Supabase project URL +- **Error**: Detailed error message (if any) +- **Storage**: Current storage mode (Database or localStorage) +- **Refresh Button**: Re-test the connection + +## Troubleshooting + +### Shows "localStorage" but you have .env.local + +1. Check that your `.env.local` variables are correct: + ```bash + NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co + NEXT_PUBLIC_SUPABASE_ANON_KEY=your_key_here + ``` + +2. Make sure they don't have placeholder values like: + - `your_supabase_project_url_here` + - `your_supabase_anon_key_here` + +3. Restart your dev server: + ```bash + pnpm dev + ``` + +### Shows "Error" with red indicator + +1. Click to expand and check the error message +2. Common issues: + - Wrong project URL + - Invalid anon key + - Database table not created (run migration) + - Network connectivity issues + +3. Click "Refresh Status" to re-test + +### Indicator not showing at all + +Check that `SHOW_SUPABASE_STATUS = true` in `components/supabase-status.tsx` + +## Styling + +The component automatically adapts to your app's color scheme using: +- Emerald colors for success +- Amber colors for warnings +- Rose colors for errors +- Transparent backdrop with blur effect + +## When to Hide + +**Development**: Keep it visible ✅ +- Helpful for debugging +- Shows configuration status +- Confirms database connection + +**Production**: Hide it ❌ +- Set `SHOW_SUPABASE_STATUS = false` +- Users don't need to see backend status +- Cleaner UI + +Or better yet, use an environment variable: + +```typescript +// In supabase-status.tsx +const SHOW_SUPABASE_STATUS = process.env.NODE_ENV === 'development' +``` + +This will automatically show in dev and hide in production! diff --git a/components/supabase-status.tsx b/components/supabase-status.tsx new file mode 100644 index 0000000..d164346 --- /dev/null +++ b/components/supabase-status.tsx @@ -0,0 +1,201 @@ +"use client" + +import { useState, useEffect } from "react" +import { Database, CheckCircle, XCircle, AlertCircle } from "lucide-react" +import { isSupabaseConfigured } from "@/lib/database/positions-service" +import { supabase } from "@/lib/database/supabase" + +// 🎯 TOGGLE THIS TO SHOW/HIDE THE STATUS INDICATOR +const SHOW_SUPABASE_STATUS = false // Set to false to hide + +interface StatusInfo { + isConfigured: boolean + isConnected: boolean | null + projectUrl: string | null + error: string | null +} + +export function SupabaseStatus() { + const [status, setStatus] = useState({ + isConfigured: false, + isConnected: null, + projectUrl: null, + error: null, + }) + const [isExpanded, setIsExpanded] = useState(false) + + useEffect(() => { + checkSupabaseStatus() + }, []) + + const checkSupabaseStatus = async () => { + const configured = isSupabaseConfigured() + const projectUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || null + + if (!configured) { + setStatus({ + isConfigured: false, + isConnected: false, + projectUrl: null, + error: "Supabase not configured. Using localStorage fallback.", + }) + return + } + + try { + // Test connection by querying the user_positions table + const { error } = await supabase.from("user_positions").select("id").limit(1) + + if (error) { + setStatus({ + isConfigured: true, + isConnected: false, + projectUrl, + error: error.message, + }) + } else { + setStatus({ + isConfigured: true, + isConnected: true, + projectUrl, + error: null, + }) + } + } catch (err) { + setStatus({ + isConfigured: true, + isConnected: false, + projectUrl, + error: err instanceof Error ? err.message : "Unknown error", + }) + } + } + + // Don't render if disabled + if (!SHOW_SUPABASE_STATUS) { + return null + } + + const getStatusIcon = () => { + if (!status.isConfigured) { + return + } + if (status.isConnected === null) { + return + } + if (status.isConnected) { + return + } + return + } + + const getStatusColor = () => { + if (!status.isConfigured) return "border-amber-500/30 bg-amber-500/5" + if (status.isConnected === null) return "border-border/30 bg-background/50" + if (status.isConnected) return "border-emerald-500/30 bg-emerald-500/5" + return "border-rose-500/30 bg-rose-500/5" + } + + const getStatusText = () => { + if (!status.isConfigured) return "localStorage" + if (status.isConnected === null) return "Checking..." + if (status.isConnected) return "Connected" + return "Error" + } + + return ( +
+
+ {/* Header - Always Visible */} + + + {/* Expanded Details */} + {isExpanded && ( +
+
+ {/* Configuration Status */} +
+ Configured: + + {status.isConfigured ? "Yes" : "No"} + +
+ + {/* Connection Status */} +
+ Connected: + + {status.isConnected === null + ? "..." + : status.isConnected + ? "Yes" + : "No"} + +
+ + {/* Project URL */} + {status.projectUrl && ( +
+
Project:
+
+ {status.projectUrl} +
+
+ )} + + {/* Error Message */} + {status.error && ( +
+
Error:
+
+ {status.error} +
+
+ )} + + {/* Storage Mode */} +
+
Storage:
+
+ {status.isConfigured && status.isConnected + ? "Database" + : "localStorage (fallback)"} +
+
+
+ + {/* Refresh Button */} + +
+ )} +
+
+ ) +} diff --git a/lib/database/supabase.ts b/lib/database/supabase.ts index 0fc1785..701a360 100644 --- a/lib/database/supabase.ts +++ b/lib/database/supabase.ts @@ -3,15 +3,10 @@ import type { Database } from "./types" // Initialize the Supabase client // These environment variables should be set in .env.local -const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL -const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY - -if (!supabaseUrl || !supabaseAnonKey) { - throw new Error( - "Missing Supabase environment variables. Please create a .env.local file with NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY" - ) -} +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || "https://placeholder.supabase.co" +const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "placeholder_key" +// Create client even if not configured (status component will show proper error) export const supabase = createClient(supabaseUrl, supabaseAnonKey, { auth: { persistSession: false, // We don't need auth sessions, just storing data by wallet address From 936efcfb74a11ba2d5c6697e708b53a89b5302f1 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:19:56 -0500 Subject: [PATCH 09/26] how it works --- app/globals.css | 21 ++++- components/deposit-modal.tsx | 14 +-- components/how-it-works.tsx | 174 ++++++++++++++++++++++++++++++++++- hooks/use-positions.ts | 40 ++++---- 4 files changed, 217 insertions(+), 32 deletions(-) diff --git a/app/globals.css b/app/globals.css index 2e29161..11a3a46 100644 --- a/app/globals.css +++ b/app/globals.css @@ -95,11 +95,11 @@ margin-inline: auto; padding-inline: 1rem; - @media (width >= 768px) { + @media (width >=768px) { padding-inline: 2rem; } - @media (width >= 1280px) { + @media (width >=1280px) { padding-inline: 3rem; } } @@ -148,11 +148,26 @@ * { @apply border-border outline-ring/50; } + body { @apply bg-background text-foreground; } } +@keyframes spin-slow { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +.animate-spin-slow { + animation: spin-slow 8s linear infinite; +} + body { background: var(--background); color: var(--foreground); @@ -170,4 +185,4 @@ body { #webgl canvas { width: 100%; height: 100%; -} +} \ No newline at end of file diff --git a/components/deposit-modal.tsx b/components/deposit-modal.tsx index 02f51e8..fb0ce9f 100644 --- a/components/deposit-modal.tsx +++ b/components/deposit-modal.tsx @@ -68,17 +68,17 @@ export function DepositModal({ const handleDeposit = async () => { if (numericAmount <= 0) return - + // Parse expiry string to timestamp, fallback to 30 days from now const expiryTimestamp = marketExpiry ? new Date(marketExpiry).getTime() : Date.now() + (30 * 24 * 60 * 60 * 1000) const signature = await deposit( - numericAmount, - marketId, - positionEnum, - marketQuestion, + numericAmount, + marketId, + positionEnum, + marketQuestion, expiryTimestamp ) @@ -122,8 +122,8 @@ export function DepositModal({
Predict {position} diff --git a/components/how-it-works.tsx b/components/how-it-works.tsx index 88763c2..15cf73f 100644 --- a/components/how-it-works.tsx +++ b/components/how-it-works.tsx @@ -1,6 +1,6 @@ "use client" -import { ArrowRight, CircleDollarSign, PiggyBank, Trophy, Wallet } from "lucide-react" +import { ArrowRight, CircleDollarSign, PiggyBank, Trophy, Wallet, Users, Repeat } from "lucide-react" const steps = [ { @@ -46,7 +46,7 @@ export function HowItWorks() {

-
+
{steps.map((step, index) => (
@@ -63,6 +63,176 @@ export function HowItWorks() {
))}
+ + {/* The Flywheel Section */} +
+
+ The Flywheel Effect +

+ Prizes scale with participation +

+

+ More volume doesn't increase risk — it increases rewards. Popular markets automatically become more valuable. +

+
+ + {/* Flywheel Visualization */} +
+
+ {/* The Flywheel Title */} +
+

The Flywheel

+
+ + {/* Center Icon */} +
+
+ +
+
+
+ + {/* Flywheel Steps */} +
+ {[ + { label: "More users", icon: Users }, + { label: "More deposits", icon: Wallet }, + { label: "More yield", icon: PiggyBank }, + { label: "Bigger prizes", icon: Trophy }, + { label: "More incentive to join", icon: ArrowRight }, + { label: "More users", icon: Users, highlight: true }, + ].map((item, index) => ( +
+
+ +
+
+

+ {item.label} +

+
+ {index < 5 && ( + + )} +
+ ))} +
+ + {/* Yield Explanation */} +
+
+

+ How Yield is Generated +

+
+

+ Pooled USDC deposits are lent on Solana DeFi protocols +

+
+ + ~12% APY +
+

+ (≈1% per month on pooled capital) +

+
+
+
+ + {/* Example Comparison */} +
+

+ Real Example: 30-Day Market +

+
+ {/* Small Pool */} +
+
+ + 10 users × $100 +
+
+
+ Pool Size + $1,000 +
+
+
+ Yield Generated + ~$10 +
+

+ $1,000 × 12% APY × (30/365) days +

+
+
+
+ If You Win +
+ +$2 +
+
+

+ $10 yield ÷ 5 winners = $2 each +

+
+
+
+ + {/* Large Pool */} +
+
+ + 1,000 users × $100 +
+
+
+ Pool Size + $100,000 +
+
+
+ Yield Generated + ~$1,000 +
+

+ $100,000 × 12% APY × (30/365) days +

+
+
+
+ If You Win +
+ +$2 +
+
+

+ $1,000 yield ÷ 500 winners = $2 each +

+
+
+
+
+ +
+

+ 100x more users = 100x larger prize pool · Same zero risk +

+

+ Longer markets = more time earning yield = bigger prizes +

+
+
+
+
+ + {/* Key Insight */} +
+

+ "Markets that matter most automatically become the most rewarding — without anyone taking on more risk." +

+
+
) diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts index 7391f03..dcb0858 100644 --- a/hooks/use-positions.ts +++ b/hooks/use-positions.ts @@ -67,7 +67,7 @@ export function usePositions() { setIsLoading(true) setError(null) - try { + try { if (useLocalStorage) { // Fallback to localStorage if Supabase not configured const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) @@ -86,7 +86,7 @@ export function usePositions() { calculateTotals(uiPositions) } } catch (e) { - console.error("Failed to load positions", e) + console.error("Failed to load positions", e) setError(e instanceof Error ? e.message : "Failed to load positions") setPositions([]) } finally { @@ -136,25 +136,25 @@ export function usePositions() { try { if (useLocalStorage) { // Fallback to localStorage - const newPosition: UserPosition = { - id: Math.random().toString(36).substring(7), - marketId, - marketQuestion, - position, - amount, - timestamp: Date.now(), - expiryTimestamp, - status: "active" - } + const newPosition: UserPosition = { + id: Math.random().toString(36).substring(7), + marketId, + marketQuestion, + position, + amount, + timestamp: Date.now(), + expiryTimestamp, + status: "active" + } - const updated = [...positions, newPosition] - setPositions(updated) - calculateTotals(updated) - - localStorage.setItem( - `polyield_positions_${publicKey.toBase58()}`, - JSON.stringify(updated) - ) + const updated = [...positions, newPosition] + setPositions(updated) + calculateTotals(updated) + + localStorage.setItem( + `polyield_positions_${publicKey.toBase58()}`, + JSON.stringify(updated) + ) } else { // Use Supabase database - will be added by use-deposit hook // This will trigger a refresh to load the newly added position From fb8f19397e3d1b09e144a8f681c81560544e4ce8 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:22:39 -0500 Subject: [PATCH 10/26] Polyield to "Poly Yield" rebrand --- DATABASE_IMPLEMENTATION.md | 2 +- PR_DESCRIPTION.md | 2 +- app/layout.tsx | 2 +- components/logo.tsx | 4 +- hooks/use-positions.ts | 56 +++---- .../migrations/001_initial_schema.sql | 2 +- programs/README.md | 4 +- programs/polyield_vault/Cargo.toml | 2 +- target/idl/polyield_vault.json | 140 ++++++++++++++++-- 9 files changed, 163 insertions(+), 51 deletions(-) diff --git a/DATABASE_IMPLEMENTATION.md b/DATABASE_IMPLEMENTATION.md index 47d52ff..d095fbb 100644 --- a/DATABASE_IMPLEMENTATION.md +++ b/DATABASE_IMPLEMENTATION.md @@ -215,7 +215,7 @@ To implement a migration script, you could: ```typescript // Example migration (run once per user) function migrateLocalStorageToSupabase(walletAddress: string) { - const stored = localStorage.getItem(`polyield_positions_${walletAddress}`) + const stored = localStorage.getItem(`poly_yield_positions_${walletAddress}`) if (stored) { const positions = JSON.parse(stored) // Batch insert to Supabase diff --git a/PR_DESCRIPTION.md b/PR_DESCRIPTION.md index 8b1a175..b7f84f3 100644 --- a/PR_DESCRIPTION.md +++ b/PR_DESCRIPTION.md @@ -2,7 +2,7 @@ ## Summary -This PR integrates **real-time Polymarket predictions** into Polyield, fetching live market data directly from Polymarket's Gamma API. Markets are now displayed on a dedicated `/markets` page with smart category detection, accurate prices, trading volumes, and market images. +This PR integrates **real-time Polymarket predictions** into Poly Yield, fetching live market data directly from Polymarket's Gamma API. Markets are now displayed on a dedicated `/markets` page with smart category detection, accurate prices, trading volumes, and market images. ## 🚀 Key Features diff --git a/app/layout.tsx b/app/layout.tsx index 9d2de2c..e5f2566 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -12,7 +12,7 @@ const geistMono = Geist_Mono({ }) export const metadata: Metadata = { - title: "Polyield", + title: "Poly Yield", description: "No-Lose Prediction Markets - Your principal is always protected", generator: "v0.app", } diff --git a/components/logo.tsx b/components/logo.tsx index c16dd46..f32ced3 100644 --- a/components/logo.tsx +++ b/components/logo.tsx @@ -2,9 +2,9 @@ import type React from "react" export const Logo = (props: React.SVGProps) => { return ( - {/* Polyield text */} + {/* Poly Yield text */} - Polyield + Poly Yield ) diff --git a/hooks/use-positions.ts b/hooks/use-positions.ts index dcb0858..d2adcb5 100644 --- a/hooks/use-positions.ts +++ b/hooks/use-positions.ts @@ -3,9 +3,9 @@ import { useState, useEffect, useCallback } from "react" import { useWallet } from "@solana/wallet-adapter-react" import { Position } from "@/lib/solana/constants" -import { +import { getPositionsByWallet, - isSupabaseConfigured + isSupabaseConfigured } from "@/lib/database/positions-service" import type { UserPosition as DbUserPosition } from "@/lib/database/types" @@ -67,10 +67,10 @@ export function usePositions() { setIsLoading(true) setError(null) - try { + try { if (useLocalStorage) { // Fallback to localStorage if Supabase not configured - const stored = localStorage.getItem(`polyield_positions_${publicKey.toBase58()}`) + const stored = localStorage.getItem(`poly_yield_positions_${publicKey.toBase58()}`) if (stored) { const parsed = JSON.parse(stored) setPositions(parsed) @@ -86,7 +86,7 @@ export function usePositions() { calculateTotals(uiPositions) } } catch (e) { - console.error("Failed to load positions", e) + console.error("Failed to load positions", e) setError(e instanceof Error ? e.message : "Failed to load positions") setPositions([]) } finally { @@ -107,12 +107,12 @@ export function usePositions() { // Calculate yield: Principal * APY * (TimeDelta in Years) const timeDiff = now - pos.timestamp const yearsElapsed = timeDiff / (1000 * 60 * 60 * 24 * 365) - + // In this model, assume yield is generated continuously // For winners, they get a share of total yield. // For this demo, we'll simulate a projected yield based on the mock APY. const estimatedYield = pos.amount * MOCK_APY * yearsElapsed - + if (pos.status === "active") { yieldSum += estimatedYield valueSum += pos.amount @@ -124,9 +124,9 @@ export function usePositions() { } const addPosition = async ( - marketId: string, - marketQuestion: string, - position: Position, + marketId: string, + marketQuestion: string, + position: Position, amount: number, expiryTimestamp: number, transactionSignature?: string @@ -136,25 +136,25 @@ export function usePositions() { try { if (useLocalStorage) { // Fallback to localStorage - const newPosition: UserPosition = { - id: Math.random().toString(36).substring(7), - marketId, - marketQuestion, - position, - amount, - timestamp: Date.now(), - expiryTimestamp, - status: "active" - } + const newPosition: UserPosition = { + id: Math.random().toString(36).substring(7), + marketId, + marketQuestion, + position, + amount, + timestamp: Date.now(), + expiryTimestamp, + status: "active" + } + + const updated = [...positions, newPosition] + setPositions(updated) + calculateTotals(updated) - const updated = [...positions, newPosition] - setPositions(updated) - calculateTotals(updated) - - localStorage.setItem( - `polyield_positions_${publicKey.toBase58()}`, - JSON.stringify(updated) - ) + localStorage.setItem( + `poly_yield_positions_${publicKey.toBase58()}`, + JSON.stringify(updated) + ) } else { // Use Supabase database - will be added by use-deposit hook // This will trigger a refresh to load the newly added position diff --git a/lib/database/migrations/001_initial_schema.sql b/lib/database/migrations/001_initial_schema.sql index 1bca526..1947c0e 100644 --- a/lib/database/migrations/001_initial_schema.sql +++ b/lib/database/migrations/001_initial_schema.sql @@ -48,4 +48,4 @@ CREATE POLICY "Enable all operations for all users" ON user_positions WITH CHECK (true); -- Add a comment to the table -COMMENT ON TABLE user_positions IS 'Stores user positions for Polyield markets, indexed by wallet address for cross-device/browser persistence'; +COMMENT ON TABLE user_positions IS 'Stores user positions for Poly Yield markets, indexed by wallet address for cross-device/browser persistence'; diff --git a/programs/README.md b/programs/README.md index 1726d14..18f3982 100644 --- a/programs/README.md +++ b/programs/README.md @@ -1,4 +1,4 @@ -# Polyield Vault - Solana Anchor Program +# Poly Yield Vault - Solana Anchor Program A PDA-controlled USDC vault for prediction market deposits on Solana. @@ -156,7 +156,7 @@ anchor test --skip-local-validator ``` ┌─────────────────────────────────────────────────────────────┐ -│ POLYIELD VAULT │ +│ POLY YIELD VAULT │ ├─────────────────────────────────────────────────────────────┤ │ │ │ User A ──────┐ │ diff --git a/programs/polyield_vault/Cargo.toml b/programs/polyield_vault/Cargo.toml index 78f29ce..e66ff9e 100644 --- a/programs/polyield_vault/Cargo.toml +++ b/programs/polyield_vault/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "polyield_vault" version = "0.1.0" -description = "Polyield USDC Vault Program for prediction market deposits" +description = "Poly Yield USDC Vault Program for prediction market deposits" edition = "2021" [lib] diff --git a/target/idl/polyield_vault.json b/target/idl/polyield_vault.json index 32d2152..3a2ee9d 100644 --- a/target/idl/polyield_vault.json +++ b/target/idl/polyield_vault.json @@ -4,12 +4,21 @@ "name": "polyield_vault", "version": "0.1.0", "spec": "0.1.0", - "description": "Polyield USDC Vault Program for prediction market deposits" + "description": "Poly Yield USDC Vault Program for prediction market deposits" }, "instructions": [ { "name": "initialize", - "discriminator": [175, 175, 109, 31, 13, 152, 155, 237], + "discriminator": [ + 175, + 175, + 109, + 31, + 13, + 152, + 155, + 237 + ], "accounts": [ { "name": "admin", @@ -26,7 +35,19 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + "value": [ + 118, + 97, + 117, + 108, + 116, + 95, + 115, + 116, + 97, + 116, + 101 + ] }, { "kind": "account", @@ -42,7 +63,13 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116] + "value": [ + 118, + 97, + 117, + 108, + 116 + ] }, { "kind": "account", @@ -63,7 +90,16 @@ }, { "name": "deposit", - "discriminator": [242, 35, 198, 137, 82, 225, 242, 182], + "discriminator": [ + 242, + 35, + 198, + 137, + 82, + 225, + 242, + 182 + ], "accounts": [ { "name": "user", @@ -80,7 +116,19 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + "value": [ + 118, + 97, + 117, + 108, + 116, + 95, + 115, + 116, + 97, + 116, + 101 + ] }, { "kind": "account", @@ -96,7 +144,13 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116] + "value": [ + 118, + 97, + 117, + 108, + 116 + ] }, { "kind": "account", @@ -116,7 +170,20 @@ "seeds": [ { "kind": "const", - "value": [117, 115, 101, 114, 95, 100, 101, 112, 111, 115, 105, 116] + "value": [ + 117, + 115, + 101, + 114, + 95, + 100, + 101, + 112, + 111, + 115, + 105, + 116 + ] }, { "kind": "account", @@ -166,7 +233,16 @@ }, { "name": "withdraw", - "discriminator": [183, 18, 70, 156, 148, 109, 161, 34], + "discriminator": [ + 183, + 18, + 70, + 156, + 148, + 109, + 161, + 34 + ], "accounts": [ { "name": "user", @@ -183,7 +259,19 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116, 95, 115, 116, 97, 116, 101] + "value": [ + 118, + 97, + 117, + 108, + 116, + 95, + 115, + 116, + 97, + 116, + 101 + ] }, { "kind": "account", @@ -199,7 +287,13 @@ "seeds": [ { "kind": "const", - "value": [118, 97, 117, 108, 116] + "value": [ + 118, + 97, + 117, + 108, + 116 + ] }, { "kind": "account", @@ -239,11 +333,29 @@ "accounts": [ { "name": "UserDeposit", - "discriminator": [115, 52, 93, 226, 80, 155, 117, 246] + "discriminator": [ + 115, + 52, + 93, + 226, + 80, + 155, + 117, + 246 + ] }, { "name": "VaultState", - "discriminator": [228, 196, 82, 165, 98, 210, 235, 152] + "discriminator": [ + 228, + 196, + 82, + 165, + 98, + 210, + 235, + 152 + ] } ], "errors": [ @@ -358,4 +470,4 @@ } } ] -} +} \ No newline at end of file From ef0a77be8c306fdd16fa01fd93bd53e33383b22f Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:29:28 -0500 Subject: [PATCH 11/26] how it works fixed --- components/how-it-works.tsx | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/components/how-it-works.tsx b/components/how-it-works.tsx index 15cf73f..e5befa9 100644 --- a/components/how-it-works.tsx +++ b/components/how-it-works.tsx @@ -1,6 +1,10 @@ "use client" import { ArrowRight, CircleDollarSign, PiggyBank, Trophy, Wallet, Users, Repeat } from "lucide-react" +import { useWallet } from "@solana/wallet-adapter-react" +import { useWalletModal } from "@solana/wallet-adapter-react-ui" +import { useRouter } from "next/navigation" +import { Button } from "./ui/button" const steps = [ { @@ -32,6 +36,18 @@ const steps = [ ] export function HowItWorks() { + const { connected } = useWallet() + const { setVisible } = useWalletModal() + const router = useRouter() + + const handleGetStarted = () => { + if (connected) { + router.push("/markets") + } else { + setVisible(true) + } + } + return (
@@ -232,6 +248,16 @@ export function HowItWorks() { "Markets that matter most automatically become the most rewarding — without anyone taking on more risk."

+ + {/* CTA Button */} +
+ +
From 21802a6cf53e54a1d3370d76c5787e4367cf7ec9 Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:36:14 -0500 Subject: [PATCH 12/26] faq + --> "PolyYield" rebrand --- PR_DESCRIPTION.md | 2 +- app/layout.tsx | 2 +- app/page.tsx | 2 + components/faq.tsx | 125 ++++++++++++++++++ components/how-it-works.tsx | 2 +- components/logo.tsx | 4 +- components/mobile-menu.tsx | 1 + components/stats.tsx | 2 +- .../migrations/001_initial_schema.sql | 2 +- programs/README.md | 4 +- programs/polyield_vault/Cargo.toml | 2 +- target/idl/polyield_vault.json | 2 +- 12 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 components/faq.tsx diff --git a/PR_DESCRIPTION.md b/PR_DESCRIPTION.md index b7f84f3..73c5c79 100644 --- a/PR_DESCRIPTION.md +++ b/PR_DESCRIPTION.md @@ -2,7 +2,7 @@ ## Summary -This PR integrates **real-time Polymarket predictions** into Poly Yield, fetching live market data directly from Polymarket's Gamma API. Markets are now displayed on a dedicated `/markets` page with smart category detection, accurate prices, trading volumes, and market images. +This PR integrates **real-time Polymarket predictions** into PolyYield, fetching live market data directly from Polymarket's Gamma API. Markets are now displayed on a dedicated `/markets` page with smart category detection, accurate prices, trading volumes, and market images. ## 🚀 Key Features diff --git a/app/layout.tsx b/app/layout.tsx index e5f2566..bbea888 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -12,7 +12,7 @@ const geistMono = Geist_Mono({ }) export const metadata: Metadata = { - title: "Poly Yield", + title: "PolyYield", description: "No-Lose Prediction Markets - Your principal is always protected", generator: "v0.app", } diff --git a/app/page.tsx b/app/page.tsx index f5c1b01..7be74c1 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,6 +3,7 @@ import { Hero } from "@/components/hero" import { HowItWorks } from "@/components/how-it-works" import { Stats } from "@/components/stats" +import { FAQ } from "@/components/faq" import { Leva } from "leva" export default function Home() { @@ -11,6 +12,7 @@ export default function Home() { +
+ +
+ + ) +} diff --git a/components/how-it-works.tsx b/components/how-it-works.tsx index e5befa9..281186e 100644 --- a/components/how-it-works.tsx +++ b/components/how-it-works.tsx @@ -49,7 +49,7 @@ export function HowItWorks() { } return ( -
+
How It Works diff --git a/components/logo.tsx b/components/logo.tsx index f32ced3..6e9305d 100644 --- a/components/logo.tsx +++ b/components/logo.tsx @@ -2,9 +2,9 @@ import type React from "react" export const Logo = (props: React.SVGProps) => { return ( - {/* Poly Yield text */} + {/* PolyYield text */} - Poly Yield + PolyYield ) diff --git a/components/mobile-menu.tsx b/components/mobile-menu.tsx index b2c12f7..4962208 100644 --- a/components/mobile-menu.tsx +++ b/components/mobile-menu.tsx @@ -16,6 +16,7 @@ export const MobileMenu = ({ className }: MobileMenuProps) => { const menuItems = [ { name: "Markets", href: "/markets" }, + { name: "Positions", href: "/positions" }, { name: "How It Works", href: "#how-it-works" }, { name: "Leaderboard", href: "#leaderboard" }, { name: "FAQ", href: "#faq" }, diff --git a/components/stats.tsx b/components/stats.tsx index 2f83b5c..c934989 100644 --- a/components/stats.tsx +++ b/components/stats.tsx @@ -27,7 +27,7 @@ const stats = [ export function Stats() { return ( -
+
{stats.map((stat) => ( diff --git a/lib/database/migrations/001_initial_schema.sql b/lib/database/migrations/001_initial_schema.sql index 1947c0e..99b2329 100644 --- a/lib/database/migrations/001_initial_schema.sql +++ b/lib/database/migrations/001_initial_schema.sql @@ -48,4 +48,4 @@ CREATE POLICY "Enable all operations for all users" ON user_positions WITH CHECK (true); -- Add a comment to the table -COMMENT ON TABLE user_positions IS 'Stores user positions for Poly Yield markets, indexed by wallet address for cross-device/browser persistence'; +COMMENT ON TABLE user_positions IS 'Stores user positions for PolyYield markets, indexed by wallet address for cross-device/browser persistence'; diff --git a/programs/README.md b/programs/README.md index 18f3982..4200618 100644 --- a/programs/README.md +++ b/programs/README.md @@ -1,4 +1,4 @@ -# Poly Yield Vault - Solana Anchor Program +# PolyYield Vault - Solana Anchor Program A PDA-controlled USDC vault for prediction market deposits on Solana. @@ -156,7 +156,7 @@ anchor test --skip-local-validator ``` ┌─────────────────────────────────────────────────────────────┐ -│ POLY YIELD VAULT │ +│ POLYIELD VAULT │ ├─────────────────────────────────────────────────────────────┤ │ │ │ User A ──────┐ │ diff --git a/programs/polyield_vault/Cargo.toml b/programs/polyield_vault/Cargo.toml index e66ff9e..64d67d5 100644 --- a/programs/polyield_vault/Cargo.toml +++ b/programs/polyield_vault/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "polyield_vault" version = "0.1.0" -description = "Poly Yield USDC Vault Program for prediction market deposits" +description = "PolyYield USDC Vault Program for prediction market deposits" edition = "2021" [lib] diff --git a/target/idl/polyield_vault.json b/target/idl/polyield_vault.json index 3a2ee9d..6e4864a 100644 --- a/target/idl/polyield_vault.json +++ b/target/idl/polyield_vault.json @@ -4,7 +4,7 @@ "name": "polyield_vault", "version": "0.1.0", "spec": "0.1.0", - "description": "Poly Yield USDC Vault Program for prediction market deposits" + "description": "PolyYield USDC Vault Program for prediction market deposits" }, "instructions": [ { From 557ae52be62c578a284d252f9b53b801f744f46e Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:39:16 -0500 Subject: [PATCH 13/26] . --- components/faq.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/components/faq.tsx b/components/faq.tsx index b5020f6..586dbbc 100644 --- a/components/faq.tsx +++ b/components/faq.tsx @@ -116,10 +116,7 @@ export function FAQ() { ))}
- -

-
-
-
- ) +
+ + ) } From e03300838b01df4f3cd3059ceda03f3b3ac81ece Mon Sep 17 00:00:00 2001 From: Aayush Aryal <1aryalaayush@gmail.com> Date: Sun, 18 Jan 2026 09:43:25 -0500 Subject: [PATCH 14/26] hid nonsense + header fix --- app/page.tsx | 2 -- components/header.tsx | 2 +- components/mobile-menu.tsx | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 7be74c1..e9414eb 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,7 +2,6 @@ import { Hero } from "@/components/hero" import { HowItWorks } from "@/components/how-it-works" -import { Stats } from "@/components/stats" import { FAQ } from "@/components/faq" import { Leva } from "leva" @@ -10,7 +9,6 @@ export default function Home() { return ( <> -