Buy flow: balance pre-flight; Trust Wallet users get a drain-warning heads-up

Stops early when the wallet lacks the POL. Only Trust Wallet users see the
proportion warning (smaller package / add POL / other wallet); everyone else
goes straight to the wallet confirmation. Buy-pane tip + chatbot reworded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-09 07:23:19 -05:00
parent 68d68b1ebf
commit 9608d07544
5 changed files with 33 additions and 4 deletions
+17
View File
@@ -1227,6 +1227,23 @@
await IAPWallet.signIn();
}
const spNow = await jretry('/api/sponsor');
// pre-flight: stop early if the POL is not there. Trust Wallet also hard-blocks any
// transaction that spends most of the balance ("drain your wallet"), so Trust users
// get a heads-up first; other wallets go straight to the confirmation.
try {
const need = BigInt(b.dataset.cost) + BigInt(b.dataset.cost) / 50n; // same 2% pad as buy()
const bal = await IAPWallet.balance(IAPWallet.address() || meNow.address);
if (bal < need) {
IAP.status('That wallet holds ' + IAP.fmtPol(bal.toString()) + ' POL, but this package needs about ' + IAP.fmtPol(need.toString()) + ' POL plus a little for gas. Top it up and try again.', 'bad');
return;
}
const pct = Number(need * 100n / bal);
const isTrust = /trust/i.test(IAPWallet.walletName() || '');
if (isTrust && pct > 55 && !confirm('Heads up for Trust Wallet users: this purchase uses about ' + pct + '% of the POL in your wallet, and Trust Wallet refuses transactions that spend most of the balance (it shows a "drain your wallet" warning with only Stop and go back).' + '\n\n' + 'Options: pick a smaller package first, add some POL, or connect a different wallet (MetaMask, Phantom, SafePal). Extra POL always stays yours.' + '\n\n' + 'Try it anyway?')) {
IAP.status('Purchase paused. Pick a smaller package, add POL, or connect another wallet, then try again.', 'ok');
return;
}
} catch (e) { /* balance read failed: let the wallet decide */ }
IAP.status('Confirm the purchase in your wallet…');
const r = await IAPWallet.buy(Number(b.dataset.id), spNow.sponsorId || 0, b.dataset.cost);
if (r.status !== '0x1' && r.receipt && r.receipt.status !== '0x1') throw new Error('Transaction reverted.');
+8 -1
View File
@@ -221,5 +221,12 @@ window.IAPWallet = (function () {
try { Object.keys(localStorage).forEach(k => { if (/wc@2|walletconnect|w3m|wcm|reown|wagmi|appkit/i.test(k)) localStorage.removeItem(k); }); } catch (e) {}
}
return { connect, signIn, buy, activate, waitTx, disconnect };
// native balance of the connected wallet (pre-flight check before a buy)
async function balance(addr) {
await connect();
const h = await eth().request({ method: 'eth_getBalance', params: [addr || currentAddress(), 'latest'] });
return BigInt(h);
}
function walletName() { try { const w = modal && modal.getWalletInfo && modal.getWalletInfo(); return (w && w.name) || ''; } catch (e) { return ''; } }
return { connect, signIn, buy, activate, waitTx, disconnect, balance, address: currentAddress, walletName };
})();