diff --git a/app/(tabs)/receive.tsx b/app/(tabs)/receive.tsx index c0190555..a35abdd9 100644 --- a/app/(tabs)/receive.tsx +++ b/app/(tabs)/receive.tsx @@ -63,7 +63,7 @@ function ReceiveScreenContent({ walletContext }: { walletContext: ReturnType { - if (currentWallet?.xpub) { + if (currentWallet?.xpub && walletService.clearAddressCache) { console.log('🔄 Receive screen focused - clearing address cache for fresh data'); walletService.clearAddressCache(currentWallet.xpub); } @@ -86,7 +86,9 @@ function ReceiveScreenContent({ walletContext }: { walletContext: ReturnType { - private appearanceSubscription: EmitterSubscription | undefined; + private appearanceSubscription: NativeEventSubscription | undefined; constructor(props: { children: ReactNode }) { super(props); diff --git a/app/address-details.tsx b/app/address-details.tsx index d2d13c9e..64115914 100644 --- a/app/address-details.tsx +++ b/app/address-details.tsx @@ -170,7 +170,8 @@ export default function AddressDetailsScreen() { // Use real exchange rate from wallet store based on selected currency const btcAmount = satoshis / 100000000; // Get rate for selected currency from price query, fallback to USD if specific currency not available - const rate = priceQuery?.data?.[selectedCurrency]?.last || priceQuery?.data?.USD?.last || 0; + const priceData = priceQuery?.data as any; + const rate = priceData?.[selectedCurrency]?.last || priceData?.USD?.last || 0; return rate > 0 ? (btcAmount * rate).toFixed(2) : '0.00'; }; diff --git a/app/coin-control.tsx b/app/coin-control.tsx index 003b365e..f839291e 100644 --- a/app/coin-control.tsx +++ b/app/coin-control.tsx @@ -92,7 +92,7 @@ export default function CoinControlScreen() { console.log('🔍 Coin control: Starting filtering with', utxos.length, 'UTXOs'); console.log('🔍 Coin control: Filter settings:', { filterBy, hideSmallUtxos }); - let filtered = utxos.filter(utxo => { + let filtered = utxos.filter((utxo: UTXO) => { console.log('🔍 Coin control: Filtering UTXO:', { txid: utxo.txid?.substring(0, 10) + '...', value: utxo.value, @@ -131,7 +131,7 @@ export default function CoinControlScreen() { console.log('🔍 Coin control: After filtering:', filtered.length, 'UTXOs remain'); - const sorted = filtered.sort((a, b) => { + const sorted = filtered.sort((a: UTXO, b: UTXO) => { let comparison = 0; switch (sortBy) { @@ -155,7 +155,7 @@ export default function CoinControlScreen() { }); console.log('🔍 Coin control: Final sorted UTXOs:', sorted.length); - console.log('🔍 Coin control: Final UTXO details:', sorted.map(u => ({ + console.log('🔍 Coin control: Final UTXO details:', sorted.map((u: UTXO) => ({ txid: u.txid?.substring(0, 10) + '...', vout: u.vout, value: u.value, @@ -167,7 +167,7 @@ export default function CoinControlScreen() { }, [utxos, sortBy, sortAscending, filterBy, hideSmallUtxos]); const toggleUtxoSelection = (utxoId: string) => { - const utxo = utxos.find(item => `${item.txid}:${item.vout}` === utxoId); + const utxo = utxos.find((item: UTXO) => `${item.txid}:${item.vout}` === utxoId); if (utxo?.frozen && !selectedUtxos.has(utxoId)) { return; } @@ -181,7 +181,7 @@ export default function CoinControlScreen() { }; const toggleUtxoFreeze = (utxoId: string) => { - const target = utxos.find(utxo => `${utxo.txid}:${utxo.vout}` === utxoId); + const target = utxos.find((utxo: UTXO) => `${utxo.txid}:${utxo.vout}` === utxoId); const wasFrozen = target?.frozen ?? false; coinControl.toggleFreeze(utxoId); // Note: No need to update local state - the coinControl store manages frozen status @@ -198,8 +198,8 @@ export default function CoinControlScreen() { const selectAllUtxos = () => { const allIds = filteredAndSortedUtxos - .filter(utxo => !utxo.frozen) - .map(utxo => `${utxo.txid}:${utxo.vout}`); + .filter((utxo: UTXO) => !utxo.frozen) + .map((utxo: UTXO) => `${utxo.txid}:${utxo.vout}`); setSelectedUtxos(new Set(allIds)); }; @@ -266,12 +266,12 @@ export default function CoinControlScreen() { const totalSelectedValue = useMemo(() => { return filteredAndSortedUtxos - .filter(utxo => selectedUtxos.has(`${utxo.txid}:${utxo.vout}`)) - .reduce((sum, utxo) => sum + utxo.value, 0); + .filter((utxo: UTXO) => selectedUtxos.has(`${utxo.txid}:${utxo.vout}`)) + .reduce((sum: number, utxo: UTXO) => sum + utxo.value, 0); }, [filteredAndSortedUtxos, selectedUtxos]); const totalValue = useMemo(() => { - return filteredAndSortedUtxos.reduce((sum, utxo) => sum + utxo.value, 0); + return filteredAndSortedUtxos.reduce((sum: number, utxo: UTXO) => sum + utxo.value, 0); }, [filteredAndSortedUtxos]); const UtxoItem = ({ utxo }: { utxo: UTXO }) => { @@ -602,7 +602,7 @@ export default function CoinControlScreen() { {/* UTXO Items */} - {filteredAndSortedUtxos.map((utxo) => ( + {filteredAndSortedUtxos.map((utxo: UTXO) => ( ))} diff --git a/app/transaction-details.tsx b/app/transaction-details.tsx index 6f7535b2..6da6f658 100644 --- a/app/transaction-details.tsx +++ b/app/transaction-details.tsx @@ -43,7 +43,7 @@ export default function TransactionDetailsScreen() { useEffect(() => { if (txid && transactions) { - const tx = transactions.find(t => t.txid === txid); + const tx = transactions.find((t: Transaction) => t.txid === txid); if (tx) { setTransaction(tx); lastTxRef.current = tx; @@ -581,6 +581,9 @@ const styles = StyleSheet.create({ borderRadius: platformStyles.borderRadius.medium, marginBottom: platformStyles.spacing.sm, }, + disabledActionButton: { + opacity: 0.5, + }, actionButtonText: { ...platformStyles.typography.bodyLarge, marginLeft: platformStyles.spacing.md, diff --git a/app/transaction-explorer.tsx b/app/transaction-explorer.tsx index 690bdc62..68576db1 100644 --- a/app/transaction-explorer.tsx +++ b/app/transaction-explorer.tsx @@ -83,16 +83,20 @@ interface NormalizedVinSource { // Some transaction detail responses include extra fields such as `net_amount` and `vsize`. // Model those explicitly instead of using `as any` to preserve type safety. -interface ExtendedTransactionDetails extends Transaction { +interface ExtendedTransactionDetails extends Omit { net_amount?: number; - vsize?: number; time?: number; - confirmations?: number; - size?: number; weight?: number; version?: number; locktime?: number; - rbf?: boolean; + vin?: any[]; + vout?: any[]; + status?: { + confirmed?: boolean; + block_height?: number; + block_hash?: string; + block_time?: number; + } | 'pending' | 'confirmed' | 'failed'; } export default function TransactionExplorerScreen() { @@ -123,7 +127,7 @@ export default function TransactionExplorerScreen() { setError(null); } - const localTx = transactions?.find(t => t.txid === txid) || lastDetailsRef.current[txid] || null; + const localTx = transactions?.find((t: Transaction) => t.txid === txid) || lastDetailsRef.current[txid] || null; if (localTx) { lastDetailsRef.current[txid] = localTx; } @@ -144,7 +148,7 @@ export default function TransactionExplorerScreen() { } as Transaction; lastDetailsRef.current[txid] = summaryTransaction; - const explorerSummary = buildExplorerData(summaryTransaction, bitcoinPrice, currentWallet); + const explorerSummary = buildExplorerData(summaryTransaction, bitcoinPrice || null, currentWallet); if (isMounted) { setTransaction(summaryTransaction); @@ -155,7 +159,7 @@ export default function TransactionExplorerScreen() { const cached = lastDetailsRef.current[txid]; if (cached) { setTransaction(cached); - setExplorerData(buildExplorerData(cached, bitcoinPrice, currentWallet)); + setExplorerData(buildExplorerData(cached, bitcoinPrice || null, currentWallet)); } else { setExplorerData(null); setError(error.message || 'Failed to fetch transaction details'); @@ -687,13 +691,14 @@ const styles = StyleSheet.create({ }); const buildExplorerData = ( - txDetails: Transaction, - bitcoinPrice: { usd?: number } | null, + txDetails: Transaction | ExtendedTransactionDetails, + bitcoinPrice: { usd?: number } | null | undefined, currentWallet: Wallet | null, ): TransactionExplorerData => { - const statusInfo = txDetails.status || {}; - const vinList = Array.isArray(txDetails.inputs) ? txDetails.inputs : txDetails.vin || []; - const voutList = Array.isArray(txDetails.outputs) ? txDetails.outputs : txDetails.vout || []; + const extendedTx = txDetails as ExtendedTransactionDetails; + const statusInfo = (typeof extendedTx.status === 'object' ? extendedTx.status : {}) as { confirmed?: boolean; block_height?: number; block_hash?: string; block_time?: number }; + const vinList = Array.isArray(txDetails.inputs) ? txDetails.inputs : extendedTx.vin || []; + const voutList = Array.isArray(txDetails.outputs) ? txDetails.outputs : extendedTx.vout || []; // Normalize vin objects to ensure consistent structure. // Some sources provide prevout directly, others provide value/address at the top level. @@ -708,8 +713,8 @@ const buildExplorerData = ( scriptpubkey_address: vout.address ?? vout.scriptpubkey_address, })); - const inputValueSats = normalizeVin.reduce((sum, vin) => sum + (vin.prevout?.value ?? 0), 0); - const outputValueSats = normalizeVout.reduce((sum, vout) => sum + (vout.value ?? 0), 0); + const inputValueSats = normalizeVin.reduce((sum: number, vin: any) => sum + (vin.prevout?.value ?? 0), 0); + const outputValueSats = normalizeVout.reduce((sum: number, vout: any) => sum + (vout.value ?? 0), 0); const feeSats = txDetails.fee ?? 0; const feeBtc = feeSats / SATOSHIS_PER_BTC; @@ -720,13 +725,13 @@ const buildExplorerData = ( } if (addressSet.size > 0) { - const received = normalizeVout.reduce((sum, output) => + const received = normalizeVout.reduce((sum: number, output: any) => output.scriptpubkey_address && addressSet.has(output.scriptpubkey_address) ? sum + (output.value ?? 0) : sum, 0); - const sent = normalizeVin.reduce((sum, input) => + const sent = normalizeVin.reduce((sum: number, input: any) => input.prevout?.scriptpubkey_address && addressSet.has(input.prevout.scriptpubkey_address) ? sum + (input.prevout?.value ?? 0) : sum, @@ -765,11 +770,11 @@ const buildExplorerData = ( version: extendedTxDetails.version ?? 0, locktime: extendedTxDetails.locktime ?? 0, rbf: extendedTxDetails.rbf ?? false, - inputs: normalizeVin.map(vin => ({ + inputs: normalizeVin.map((vin: any) => ({ address: vin.prevout?.scriptpubkey_address ?? 'Unknown', value: (vin.prevout?.value ?? 0) / SATOSHIS_PER_BTC, })), - outputs: normalizeVout.map(vout => ({ + outputs: normalizeVout.map((vout: any) => ({ address: vout.scriptpubkey_address ?? 'Unknown', value: (vout.value ?? 0) / SATOSHIS_PER_BTC, })), diff --git a/app/transaction-history.tsx b/app/transaction-history.tsx index 46ca03ea..146af9e7 100644 --- a/app/transaction-history.tsx +++ b/app/transaction-history.tsx @@ -1,5 +1,6 @@ import TransactionItem from '@/components/TransactionItem'; import { useWallet } from '@/hooks/wallet-store'; +import { Transaction } from '@/types/wallet'; import { Stack, router } from 'expo-router'; import { ArrowLeft, Clock } from 'lucide-react-native'; import React from 'react'; @@ -134,7 +135,7 @@ export default function TransactionHistoryScreen() { {/* Transaction List */} {transactions.length > 0 && ( - {transactions.map((transaction, index) => ( + {transactions.map((transaction: Transaction, index: number) => ( - {addressesQuery.isLoading && (!addressesQuery.data || addressesQuery.data.length === 0) ? ( + {addressesQuery.isLoading && addressData.length === 0 ? ( diff --git a/components/BitSleuthButton.tsx b/components/BitSleuthButton.tsx index 7383d628..e172a5d0 100644 --- a/components/BitSleuthButton.tsx +++ b/components/BitSleuthButton.tsx @@ -1,4 +1,4 @@ -import { createButtonStyle } from '@/constants/themes'; +import { createButtonStyle, lightTheme } from '@/constants/themes'; import { HapticService } from '@/services/haptic-service'; import { LinearGradient } from 'expo-linear-gradient'; import React from 'react'; @@ -127,8 +127,26 @@ export default function BitSleuthButton({ }; // Button style + // Map variant to theme variant + const themeVariant = (() => { + switch (variant) { + case 'accent': + case 'success': + case 'warning': + case 'error': + case 'ghost': + return 'primary'; + case 'secondary': + return 'secondary'; + case 'fun': + return 'fun'; + default: + return variant as 'primary' | 'secondary' | 'outline' | 'gradient' | 'fun'; + } + })(); + const buttonStyle = [ - createButtonStyle({ colors: {}, shadows: {} }, variant), + createButtonStyle(lightTheme, themeVariant), currentSize, style, animatedStyle, diff --git a/components/BitSleuthCard.tsx b/components/BitSleuthCard.tsx index 8935a004..0d15fc7f 100644 --- a/components/BitSleuthCard.tsx +++ b/components/BitSleuthCard.tsx @@ -1,4 +1,4 @@ -import { createCardShadow, createCardStyle } from '@/constants/themes'; +import { createCardStyle, lightTheme } from '@/constants/themes'; import { HapticService } from '@/services/haptic-service'; import { LinearGradient } from 'expo-linear-gradient'; import React from 'react'; @@ -43,7 +43,7 @@ export default function BitSleuthCard({ const shadowOpacity = useSharedValue(0.15); // Color mapping for fun variants - const funColors = { + const funColors: Record = { purple: ['#9B59B6', '#8E44AD'], yellow: ['#F1C40F', '#F39C12'], pink: ['#E91E63', '#C2185B'], @@ -84,9 +84,11 @@ export default function BitSleuthCard({ }; // Card style + // Map variant to theme variant + const themeVariant = variant === 'gradient' ? 'elevated' : variant as 'default' | 'elevated' | 'fun'; + const cardStyle = [ - createCardStyle({ colors: {}, shadows: {} }, variant), - createCardShadow({ shadows: {} }, shadowElevation), + createCardStyle(lightTheme, themeVariant), style, animatedStyle, ]; diff --git a/components/ConfettiCelebration.tsx b/components/ConfettiCelebration.tsx index 02edf371..1135b460 100644 --- a/components/ConfettiCelebration.tsx +++ b/components/ConfettiCelebration.tsx @@ -1,8 +1,10 @@ import { HapticService } from '@/services/haptic-service'; import React, { useEffect, useRef } from 'react'; -import { StyleSheet, View } from 'react-native'; +import { Dimensions, StyleSheet, View } from 'react-native'; import ConfettiCannon from 'react-native-confetti-cannon'; +const { height: screenHeight } = Dimensions.get('window'); + interface ConfettiCelebrationProps { isVisible: boolean; onComplete?: () => void; @@ -73,16 +75,16 @@ export default function ConfettiCelebration({ }; // Position configuration - const getPositionStyle = () => { + const getPositionStyle = (): { top?: number; bottom?: number } => { switch (position) { case 'top': return { top: 100 }; case 'center': - return { top: '50%' }; + return { top: screenHeight / 2 }; case 'bottom': return { bottom: 100 }; default: - return { top: '50%' }; + return { top: screenHeight / 2 }; } }; diff --git a/components/EmojiReaction.tsx b/components/EmojiReaction.tsx index 522f5509..706bb9d6 100644 --- a/components/EmojiReaction.tsx +++ b/components/EmojiReaction.tsx @@ -1,3 +1,4 @@ +import { platformStyles } from '@/constants/themes'; import React, { useCallback, useEffect, useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Animated, { diff --git a/components/PremiumButton.tsx b/components/PremiumButton.tsx index 9155083f..7b8ba571 100644 --- a/components/PremiumButton.tsx +++ b/components/PremiumButton.tsx @@ -1,3 +1,4 @@ +import { platformStyles } from '@/constants/themes'; import { HapticService } from '@/services/haptic-service'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useCallback } from 'react'; @@ -75,7 +76,7 @@ export default function PremiumButton({ } }, [disabled, loading, onPress, scale, opacity]); - const getGradientColors = () => { + const getGradientColors = (): readonly [string, string] => { switch (variant) { case 'primary': return ['#26F5FE', '#00BCD4']; @@ -94,7 +95,7 @@ export default function PremiumButton({ <> {loading && } {!loading && icon && <>{icon}} - + {loading ? 'Loading...' : title} diff --git a/components/PriceChart.tsx b/components/PriceChart.tsx index 20290fe8..5efd3004 100644 --- a/components/PriceChart.tsx +++ b/components/PriceChart.tsx @@ -1,5 +1,6 @@ import { platformStyles } from '@/constants/themes'; import { useWallet } from '@/hooks/wallet-store'; +import { Transaction } from '@/types/wallet'; import { WifiOff } from 'lucide-react-native'; import React, { useRef, useState } from 'react'; import { Animated, Dimensions, PanResponder, StyleSheet, Text, View } from 'react-native'; @@ -69,7 +70,7 @@ function BalanceChartContent({ selectedPeriod }: BalanceChartProps) { case '1M': return 30; case '1Y': return 365; case 'All': return Math.max(365, transactions.length > 0 ? - Math.ceil((Date.now() - Math.min(...transactions.map(tx => tx.timestamp))) / (24 * 60 * 60 * 1000)) : 365); + Math.ceil((Date.now() - Math.min(...transactions.map((tx: Transaction) => tx.timestamp))) / (24 * 60 * 60 * 1000)) : 365); default: return 30; } }; diff --git a/components/SuccessAnimation.tsx b/components/SuccessAnimation.tsx index b9fce509..d4bf3045 100644 --- a/components/SuccessAnimation.tsx +++ b/components/SuccessAnimation.tsx @@ -1,5 +1,6 @@ import { HapticService } from '@/services/haptic-service'; import { Check } from 'lucide-react-native'; +import { platformStyles } from '@/constants/themes'; import React, { useEffect } from 'react'; import { StyleSheet, View } from 'react-native'; import Animated, { diff --git a/hooks/use-performance-monitor.ts b/hooks/use-performance-monitor.ts index 80e18bb9..1b935af9 100644 --- a/hooks/use-performance-monitor.ts +++ b/hooks/use-performance-monitor.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; interface PerformanceMetrics { renderCount: number; diff --git a/hooks/wallet-store.ts b/hooks/wallet-store.ts index 1d33493d..801358bb 100644 --- a/hooks/wallet-store.ts +++ b/hooks/wallet-store.ts @@ -35,11 +35,13 @@ try { generateAddressesForView: importedService.generateAddressesForView, isAddressInWallet: importedService.isAddressInWallet, discoverUsedAddresses: importedService.discoverUsedAddresses, - getWalletData: importedService.getWalletData + getWalletData: importedService.getWalletData, + clearAddressCache: importedService.clearAddressCache, + getFirstUnusedReceivingAddress: importedService.getFirstUnusedReceivingAddress }; // Verify all required functions are available - const requiredFunctions = ['generateMnemonic', 'validateMnemonic', 'createWallet', 'importWallet', 'generateAddressFromXpub', 'generateNewAddress', 'getPrivateKey', 'findNextUnusedAddressIndexWithCycling', 'generateAddressBatchForView', 'generateAddressesForView', 'isAddressInWallet', 'discoverUsedAddresses', 'getWalletData']; + const requiredFunctions = ['generateMnemonic', 'validateMnemonic', 'createWallet', 'importWallet', 'generateAddressFromXpub', 'generateNewAddress', 'getPrivateKey', 'findNextUnusedAddressIndexWithCycling', 'generateAddressBatchForView', 'generateAddressesForView', 'isAddressInWallet', 'discoverUsedAddresses', 'getWalletData', 'clearAddressCache', 'getFirstUnusedReceivingAddress']; const missingFunctions = requiredFunctions.filter(func => typeof walletService[func] !== 'function'); if (missingFunctions.length > 0) { @@ -63,7 +65,9 @@ try { generateAddressesForView: async () => { throw new Error('Wallet service not available'); }, isAddressInWallet: async () => { throw new Error('Wallet service not available'); }, discoverUsedAddresses: async () => { throw new Error('Wallet service not available'); }, - getWalletData: async () => { throw new Error('Wallet service not available'); } + getWalletData: async () => { throw new Error('Wallet service not available'); }, + clearAddressCache: () => {}, + getFirstUnusedReceivingAddress: async () => null }; } @@ -2226,6 +2230,7 @@ export const [WalletProvider, useWallet] = createContextHook(() => { balance, balanceUSD: balance * (priceQuery.data?.usd || 0), bitcoinPrice: priceQuery.data, + priceQuery, isLoadingBalance: balanceQuery.isLoading && lastBalanceRef.current === null, isRefreshingBalance: balanceQuery.isFetching && lastBalanceRef.current !== null, isLoadingPrice: priceQuery.isLoading, @@ -2234,7 +2239,7 @@ export const [WalletProvider, useWallet] = createContextHook(() => { balanceError: balanceQuery.error, priceError: priceQuery.error, }; - }, [balanceQuery.data, balanceQuery.isLoading, balanceQuery.isFetching, balanceQuery.error, priceQuery.data, priceQuery.isLoading, priceQuery.error]); + }, [balanceQuery.data, balanceQuery.isLoading, balanceQuery.isFetching, balanceQuery.error, priceQuery.data, priceQuery.isLoading, priceQuery.error, priceQuery]); const stableTransactions = transactionsQuery.data ?? lastTransactionsRef.current; useEffect(() => { diff --git a/services/cpfp-service.ts b/services/cpfp-service.ts index f7e51eaa..2c0ff797 100644 --- a/services/cpfp-service.ts +++ b/services/cpfp-service.ts @@ -696,8 +696,12 @@ export async function deriveAddressIndexFromAddress(mnemonic: string, targetAddr try { // Check cache first if (addressIndexCache.has(targetAddress)) { - const cachedIndex = addressIndexCache.get(targetAddress)!; - console.log(`✅ Found cached BIP32 index ${cachedIndex} for address: ${targetAddress}`); + const cachedValue = addressIndexCache.get(targetAddress)!; + console.log(`✅ Found cached BIP32 index ${cachedValue} for address: ${targetAddress}`); + // If cached value is a string, parse the index from it + const cachedIndex = typeof cachedValue === 'string' + ? parseInt(cachedValue.split(':')[1], 10) + : cachedValue; return cachedIndex; } diff --git a/services/ecc-override.ts b/services/ecc-override.ts index 20ea131b..1743573b 100644 --- a/services/ecc-override.ts +++ b/services/ecc-override.ts @@ -442,7 +442,7 @@ export const createNobleECC = () => { const parity = resultBytes[0] === 0x03 ? 1 : 0; const xOnlyResult = resultBytes.slice(1); - console.log(`🔧 xOnlyPointAddTweak: even y-coordinate result parity=${parity}, xOnlyPubkey=${Array.from(xOnlyResult).map(b => b.toString(16).padStart(2, '0')).join('')}`); + console.log(`🔧 xOnlyPointAddTweak: even y-coordinate result parity=${parity}, xOnlyPubkey=${Array.from(xOnlyResult).map((b: unknown) => (b as number).toString(16).padStart(2, '0')).join('')}`); return { parity, @@ -468,7 +468,7 @@ export const createNobleECC = () => { const parity = resultBytes[0] === 0x03 ? 1 : 0; const xOnlyResult = resultBytes.slice(1); - console.log(`🔧 xOnlyPointAddTweak: odd y-coordinate result parity=${parity}, xOnlyPubkey=${Array.from(xOnlyResult).map(b => b.toString(16).padStart(2, '0')).join('')}`); + console.log(`🔧 xOnlyPointAddTweak: odd y-coordinate result parity=${parity}, xOnlyPubkey=${Array.from(xOnlyResult).map((b: unknown) => (b as number).toString(16).padStart(2, '0')).join('')}`); return { parity, diff --git a/services/rbf-service.ts b/services/rbf-service.ts index a8f0f837..077d4e8c 100644 --- a/services/rbf-service.ts +++ b/services/rbf-service.ts @@ -372,8 +372,9 @@ export async function createReplacementTransaction( // We just need to verify that our ECC library works correctly console.log('🔧 Testing ECC library functionality (bitcoinjs-lib 7.x compatible)...'); try { - // Reuse the testPrivateKey defined earlier - // (already set to a valid value) + // Define test private key for verification + const testPrivateKey = new Uint8Array(32); + testPrivateKey[31] = 1; // Set to 1 to ensure it's a valid private key // Test if our ECC library can create a public key const publicKey = ecc.pointFromScalar(testPrivateKey, true); @@ -903,6 +904,8 @@ async function createCancellationTransaction( // We just need to verify that our ECC library works correctly console.log('🔧 Testing ECC library functionality (bitcoinjs-lib 7.x compatible)...'); try { + // Define test private key for verification + const testPrivateKey = new Uint8Array(32); testPrivateKey[31] = 1; // Set to 1 to ensure it's a valid private key // Test if our ECC library can create a public key @@ -1239,8 +1242,12 @@ export async function deriveAddressIndexFromAddress(mnemonic: string, targetAddr try { // Check cache first if (addressIndexCache.has(targetAddress)) { - const cachedIndex = addressIndexCache.get(targetAddress)!; - console.log(`✅ Found cached BIP32 index ${cachedIndex} for address: ${targetAddress}`); + const cachedValue = addressIndexCache.get(targetAddress)!; + console.log(`✅ Found cached BIP32 index ${cachedValue} for address: ${targetAddress}`); + // If cached value is a string, parse the index from it + const cachedIndex = typeof cachedValue === 'string' + ? parseInt(cachedValue.split(':')[1], 10) + : cachedValue; return cachedIndex; }