Positions: force the wallet's account picker (wallet_requestPermissions) when adding a position or when the Buy-from wallet doesn't match; sign/send with the wallet's active account
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+30
-3
@@ -93,6 +93,33 @@ window.IAPWallet = (function () {
|
||||
}
|
||||
|
||||
function eth() { if (!provider) throw new Error('Connect your wallet first.'); return provider; }
|
||||
const isInjected = () => !!(provider && window.ethereum && (provider === window.ethereum || provider.isMetaMask));
|
||||
// the account the wallet will actually sign with: for an injected wallet (MetaMask
|
||||
// extension) that is its active account, which can differ from AppKit's cached one
|
||||
async function activeAddress(fallback) {
|
||||
if (isInjected()) { try { const a = await provider.request({ method: 'eth_accounts' }); if (a && a[0]) return a[0]; } catch (e) {} }
|
||||
return fallback || currentAddress();
|
||||
}
|
||||
// Force the wallet's own account picker. Injected wallets stay connected to the
|
||||
// site, so a plain disconnect/reconnect never shows one: asking for permissions
|
||||
// again makes MetaMask open its account-selection prompt, and whatever the user
|
||||
// ticks becomes the active account. WalletConnect wallets fall back to a fresh
|
||||
// session (the picker + the wallet app's own account choice).
|
||||
async function pickAccount() {
|
||||
const c = await IAP.getConfig();
|
||||
await initAppKit(c);
|
||||
const inj = window.ethereum;
|
||||
if (inj && inj.request) {
|
||||
try {
|
||||
await inj.request({ method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }] });
|
||||
const accs = await inj.request({ method: 'eth_accounts' });
|
||||
if (accs && accs[0]) { provider = inj; await ensureChain(c).catch(() => {}); return accs[0]; }
|
||||
} catch (e) {
|
||||
if (e && (e.code === 4001 || /reject|denied/i.test(String(e.message || '')))) throw new Error('You closed the account picker. Pick the account you want and try again.');
|
||||
}
|
||||
}
|
||||
return freshConnect(c);
|
||||
}
|
||||
|
||||
// A WalletConnect session can die underneath AppKit's cached "connected"
|
||||
// state: the wallet app rejects or kills it (Trust does this after its own
|
||||
@@ -149,7 +176,7 @@ window.IAPWallet = (function () {
|
||||
|
||||
// SIWE: challenge -> personal_sign -> verify (server sets the session cookie)
|
||||
async function signIn(opts) {
|
||||
const addr = await connect();
|
||||
const addr = (opts && opts.pick) ? await pickAccount() : await activeAddress(await connect());
|
||||
const ch = await (await fetch('/api/auth/challenge', { method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: addr }) })).json();
|
||||
if (ch.error) throw new Error(ch.error);
|
||||
@@ -177,7 +204,7 @@ window.IAPWallet = (function () {
|
||||
if (!isNaN(chainNum(cur)) && chainNum(cur) !== wantNum)
|
||||
throw new Error('Your wallet is on the wrong network. Switch it to ' + (c.chainName || 'the correct network') + ', then try again.');
|
||||
}
|
||||
const tx = { from: addr, to: c.contract, data };
|
||||
const tx = { from: await activeAddress(addr), to: c.contract, data };
|
||||
if (valueWei) tx.value = '0x' + BigInt(valueWei).toString(16);
|
||||
// Amoy's Bor nodes enforce a ~25 gwei minimum priority fee that MetaMask's
|
||||
// own estimate misses ("gas tip below minimum"). Pull the network's correct
|
||||
@@ -237,5 +264,5 @@ window.IAPWallet = (function () {
|
||||
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 };
|
||||
return { connect, signIn, buy, activate, waitTx, disconnect, balance, address: currentAddress, activeAddress, pickAccount, walletName };
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user