Fix proxy ID listener derivation and add TON/ALGO blockchain selection popup

- Handle CashAddr format validating natively for BCH in floCrypto.js

- Require explicit TON vs ALGO blockchain selection for 128-char hex private keys during login

- Fix fallback logic in messenger.js to cleanly default to myFloID listener instead of duplicate listener addresses
This commit is contained in:
void-57 2026-02-28 04:35:04 +05:30
parent ec5c8495dd
commit 6dc2c8f922
4 changed files with 57 additions and 7 deletions

View File

@ -275,6 +275,29 @@
<button class="button cancel-button" onclick="resolveBlockchainSelection(null)">Cancel</button>
</div>
</sm-popup>
<sm-popup id="btc_bch_select_popup" dismissable="false">
<h4 id="btc_bch_select_title">Select Blockchain</h4>
<p>Your private key format is used by Bitcoin and Bitcoin Cash. Please select the correct blockchain for this
key:</p>
<div class="grid gap-0-5 margin-top-1">
<button class="button w-100" onclick="resolveBlockchainSelection('BTC')">Bitcoin (BTC)</button>
<button class="button w-100" onclick="resolveBlockchainSelection('BCH')">Bitcoin Cash (BCH)</button>
</div>
<div class="flex align-center gap-0-5 margin-top-1 margin-left-auto">
<button class="button cancel-button" onclick="resolveBlockchainSelection(null)">Cancel</button>
</div>
</sm-popup>
<sm-popup id="ton_algo_select_popup" dismissable="false">
<h4 id="ton_algo_select_title">Select Blockchain</h4>
<p>Your private key format is used by TON and Algorand. Please select the correct blockchain for this key:</p>
<div class="grid gap-0-5 margin-top-1">
<button class="button w-100" onclick="resolveBlockchainSelection('TON')">TON</button>
<button class="button w-100" onclick="resolveBlockchainSelection('ALGO')">Algorand (ALGO)</button>
</div>
<div class="flex align-center gap-0-5 margin-top-1 margin-left-auto">
<button class="button cancel-button" onclick="resolveBlockchainSelection(null)">Cancel</button>
</div>
</sm-popup>
<div id="adblocker_warning"></div>
<div id="secondary_pages" class="page hidden">
<header class="flex align-center gap-1 space-between">
@ -2784,8 +2807,13 @@
key.setCompressed(true);
privateKey = key.getBitcoinWalletImportFormat();
} else if (/^[0-9a-fA-F]{128}$/.test(privateKey)) {
activeChain = 'TON';
// Convert 128-char TON ed25519 key to workable FLO WIF using the first 32-bytes (seed)
activeChain = await new Promise(resolve => {
_blockchainResolve = resolve;
openPopup('ton_algo_select_popup');
});
if (!activeChain) return;
// Convert 128-char ed25519 key to workable FLO WIF using the first 32-bytes (seed)
let key = new Bitcoin.ECKey(privateKey.substring(0, 64));
key.setCompressed(true);
privateKey = key.getBitcoinWalletImportFormat();
@ -2810,7 +2838,13 @@
else if (privateKey.startsWith('s')) activeChain = 'XRP';
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')) activeChain = 'BTC';
else if (privateKey.startsWith('K') || privateKey.startsWith('L') || privateKey.startsWith('5')) {
activeChain = await new Promise(resolve => {
_blockchainResolve = resolve;
openPopup('btc_bch_select_popup');
});
if (!activeChain) return;
}
else if (privateKey.startsWith('S') && privateKey.length === 56) activeChain = 'XLM';
else if (privateKey.startsWith('R')) activeChain = 'FLO';
else activeChain = 'UNKNOWN';

View File

@ -406,8 +406,8 @@
hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3] ?
bytes = undefined : bytes.shift();
}
// BTC/LTC Bech32 encoding (42 or 62 chars, not starting with 0x)
else if (!address.startsWith("0x") && (address.length == 42 || address.length == 62) && !address.startsWith("addr1")) {
// BTC/LTC Bech32 encoding (bc1 or ltc1 prefix)
else if (/^(bc1|ltc1)[a-zA-HJ-NP-Z0-9]{25,62}$/.test(address)) {
if (typeof coinjs !== 'function')
throw "library missing (lib_btc.js)";
let decode = coinjs.bech32_decode(address);

View File

@ -299,7 +299,7 @@
return true;
else
return false;
} else if (raw.type === 'ethereum') {
} else if (raw.type === 'ethereum' || raw.type === 'bch') {
return true
} else //unknown
return false;
@ -439,6 +439,22 @@
type: 'ethereum',
bytes
}
} else if (address.length >= 34 && address.length <= 45 && /^q[a-z0-9]+$/.test(address)) { //BCH Address
try {
let addrBytes = [];
for (let i = 0; i < address.length; i++) {
addrBytes.push(address.charCodeAt(i));
}
let payload = ripemd160(Crypto.SHA256(addrBytes, { asBytes: true }));
return {
version: 1,
hex: Crypto.util.bytesToHex(payload),
type: 'bch',
bytes: payload
}
} catch (e) {
return null;
}
}
}

View File

@ -606,7 +606,7 @@
return new Promise(async (resolve, reject) => {
// All blockchain address IDs to listen on
let activeChain = localStorage.getItem(`${floGlobals.application}#activeChain`);
const blockchainAddressIDs = [user.id]; // Always listen to FLO address (primary)
const blockchainAddressIDs = [floGlobals.myFloID || user.id]; // Always listen to FLO address (primary)
if (!activeChain) {
try {