diff --git a/index.html b/index.html index 5b0a2de..bfb136f 100644 --- a/index.html +++ b/index.html @@ -78,37 +78,62 @@ document.body.prepend(document.createElement('adblocker-warning')) return } - floGlobals.myFloID = floCrypto.getFloID(floDapps.user.public); - floGlobals.myBtcID = btcOperator.convert.legacy2bech(floGlobals.myFloID) - floGlobals.myEthID = floEthereum.ethAddressFromCompressedPublicKey(floDapps.user.public) - // AVAX C-Chain uses same address format as Ethereum - floGlobals.myAvaxID = floGlobals.myEthID; - // BSC (Binance Smart Chain) uses same address format as Ethereum - floGlobals.myBscID = floGlobals.myEthID; - // MATIC (Polygon) uses same address format as Ethereum - floGlobals.myMaticID = floGlobals.myEthID; - // Arbitrum uses same address format as Ethereum - floGlobals.myArbID = floGlobals.myEthID; - // Optimism uses same address format as Ethereum - floGlobals.myOpID = floGlobals.myEthID; - // HBAR (Hedera) uses same address format as Ethereum - floGlobals.myHbarID = floGlobals.myEthID; - - // Initialize private-key-dependent addresses to null (will be derived after messenger init) - floGlobals.myXrpID = null; - floGlobals.mySuiID = null; - floGlobals.myAdaID = null; - floGlobals.myTonID = null; - floGlobals.myTronID = null; - floGlobals.myDogeID = null; - floGlobals.myLtcID = null; - floGlobals.myBchID = null; - floGlobals.myDotID = null; - floGlobals.myAlgoID = null; - floGlobals.myXlmID = null; - floGlobals.mySolID = null; - // Note: Cardano (ADA) address will be derived from private key later + let activeChain = localStorage.getItem(`${floGlobals.application}#activeChain`); + if (activeChain === 'XRP') { + // XRP-only login: skip FLO/BTC/ETH derivations + floGlobals.myFloID = floDapps.user.id; // This is the XRP address (r...) + floGlobals.myXrpID = floDapps.user.id; + floGlobals.myBtcID = null; + floGlobals.myEthID = null; + floGlobals.myAvaxID = null; + floGlobals.myBscID = null; + floGlobals.myMaticID = null; + floGlobals.myArbID = null; + floGlobals.myOpID = null; + floGlobals.myHbarID = null; + floGlobals.mySuiID = null; + floGlobals.myAdaID = null; + floGlobals.myTonID = null; + floGlobals.myTronID = null; + floGlobals.myDogeID = null; + floGlobals.myLtcID = null; + floGlobals.myBchID = null; + floGlobals.myDotID = null; + floGlobals.myAlgoID = null; + floGlobals.myXlmID = null; + floGlobals.mySolID = null; + } else { + floGlobals.myFloID = floCrypto.getFloID(floDapps.user.public); + floGlobals.myBtcID = btcOperator.convert.legacy2bech(floGlobals.myFloID) + floGlobals.myEthID = floEthereum.ethAddressFromCompressedPublicKey(floDapps.user.public) + // AVAX C-Chain uses same address format as Ethereum + floGlobals.myAvaxID = floGlobals.myEthID; + // BSC (Binance Smart Chain) uses same address format as Ethereum + floGlobals.myBscID = floGlobals.myEthID; + // MATIC (Polygon) uses same address format as Ethereum + floGlobals.myMaticID = floGlobals.myEthID; + // Arbitrum uses same address format as Ethereum + floGlobals.myArbID = floGlobals.myEthID; + // Optimism uses same address format as Ethereum + floGlobals.myOpID = floGlobals.myEthID; + // HBAR (Hedera) uses same address format as Ethereum + floGlobals.myHbarID = floGlobals.myEthID; + // Initialize private-key-dependent addresses to null (will be derived after messenger init) + floGlobals.myXrpID = null; + floGlobals.mySuiID = null; + floGlobals.myAdaID = null; + floGlobals.myTonID = null; + floGlobals.myTronID = null; + floGlobals.myDogeID = null; + floGlobals.myLtcID = null; + floGlobals.myBchID = null; + floGlobals.myDotID = null; + floGlobals.myAlgoID = null; + floGlobals.myXlmID = null; + floGlobals.mySolID = null; + // Note: Cardano (ADA) address will be derived from private key later + } document.querySelectorAll('.user-profile-id').forEach(el => el.textContent = floGlobals.myFloID) //load messages from IDB and render them console.log(`Loading Data! Please Wait...`) @@ -230,7 +255,7 @@ } }) } catch (e) { - notify(error, "error") + notify(e, "error") } } @@ -2119,6 +2144,7 @@ const idList = allIds.filter(item => { if (!item.id) return false; + if (activeChain === 'XRP') return item.label === 'XRP'; if (item.label === 'FLO') return true; // Always include FLO if (item.label === activeChain) return true; // Include active chain // For EVM compatible chains which share the ETH ID: @@ -2775,6 +2801,8 @@ value.startsWith('suiprivkey1') ) { isValid = true; + } else if (value.startsWith('s') && value.length >= 29 && value.length <= 32) { + isValid = true; } else if (value.startsWith('S') && value.length === 56) { isValid = true; } else { @@ -2837,7 +2865,22 @@ console.error("Failed to decode SUI key", e); } } - else if (privateKey.startsWith('s')) activeChain = 'XRP'; + else if (privateKey.startsWith('s') && privateKey.length >= 29 && privateKey.length <= 32) { + activeChain = 'XRP'; + // Convert XRP secret to workable FLO WIF using the private key bytes + try { + let wallet = xrpl.Wallet.fromSeed(privateKey); + let privKeyHex = wallet.privateKey; + // Remove ED prefix if present (Ed25519 keys) + if (privKeyHex.startsWith('ED') || privKeyHex.startsWith('ed')) + privKeyHex = privKeyHex.substring(2); + let key = new Bitcoin.ECKey(privKeyHex); + key.setCompressed(true); + privateKey = key.getBitcoinWalletImportFormat(); + } catch (e) { + console.error("Failed to decode XRP key", e); + } + } else if (privateKey.startsWith('Q')) activeChain = 'DOGE'; else if (privateKey.startsWith('T') && privateKey.length === 51) activeChain = 'LTC'; else if (privateKey.startsWith('K') || privateKey.startsWith('L') || privateKey.startsWith('5')) { @@ -3327,8 +3370,19 @@ } }, profile() { + let activeChain = localStorage.getItem(`${floGlobals.application}#activeChain`); return html`
+ ${activeChain === 'XRP' ? html` +
+

XRP-only login

+

You are logged in with an XRP private key. Only the XRP address is available.

+
+
+ My XRP (Ripple) address + +
+ ` : html`

BTC integrated with FLO @@ -3429,6 +3483,7 @@ Unlock all addresses ` : ''} + `}

diff --git a/scripts/floCloudAPI.js b/scripts/floCloudAPI.js index 8482453..dfcbe7b 100644 --- a/scripts/floCloudAPI.js +++ b/scripts/floCloudAPI.js @@ -393,8 +393,21 @@ return; var bytes; + // XRP Address (Base58, starts with 'r', 25-35 chars) - must be checked before FLO/BTC legacy + if (address.length >= 25 && address.length <= 35 && address.startsWith('r')) { + try { + // XRP address - hash the raw address for unique proxy ID + let addrBytes = []; + for (let i = 0; i < address.length; i++) { + addrBytes.push(address.charCodeAt(i)); + } + bytes = ripemd160(Crypto.SHA256(addrBytes, { asBytes: true })); + } catch (e) { + bytes = undefined; + } + } // FLO/BTC legacy encoding (33-34 chars) - if (address.length == 33 || address.length == 34) { + else if (address.length == 33 || address.length == 34) { let decode = bitjs.Base58.decode(address); bytes = decode.slice(0, decode.length - 4); let checksum = decode.slice(decode.length - 4),