Compare commits
9 Commits
35bb6b9806
...
fix/cross-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd412209a7 | ||
| 09c52b2519 | |||
| 1fb9fade51 | |||
| bc04482fb5 | |||
|
|
045328f3b9 | ||
|
|
576fe3ab15 | ||
|
|
8c071ae508 | ||
|
|
a3c2b8227a | ||
|
|
f9f3e7b85a |
@@ -586,6 +586,19 @@
|
|||||||
<div id="confirm-fee-amount" class="text-xs"></div>
|
<div id="confirm-fee-amount" class="text-xs"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="confirm-warnings" class="mb-2 hidden"></div>
|
<div id="confirm-warnings" class="mb-2 hidden"></div>
|
||||||
|
<div
|
||||||
|
id="confirm-recipient-warning"
|
||||||
|
class="mb-2"
|
||||||
|
style="visibility: hidden"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="border border-red-500 border-dashed p-2 text-xs font-bold text-red-500"
|
||||||
|
>
|
||||||
|
WARNING: The recipient address has ZERO transaction
|
||||||
|
history. This may indicate a fresh or unused address.
|
||||||
|
Double-check the address before sending.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
id="confirm-errors"
|
id="confirm-errors"
|
||||||
class="mb-2 border border-border border-dashed p-2 hidden"
|
class="mb-2 border border-border border-dashed p-2 hidden"
|
||||||
|
|||||||
@@ -97,18 +97,26 @@ async function importMnemonic(ctx) {
|
|||||||
const pw = validatePassword();
|
const pw = validatePassword();
|
||||||
if (!pw) return;
|
if (!pw) return;
|
||||||
const { xpub, firstAddress } = hdWalletFromMnemonic(mnemonic);
|
const { xpub, firstAddress } = hdWalletFromMnemonic(mnemonic);
|
||||||
const duplicate = state.wallets.find(
|
const addrDup = state.wallets.find((w) =>
|
||||||
(w) =>
|
w.addresses.some(
|
||||||
w.type === "hd" &&
|
(a) => a.address.toLowerCase() === firstAddress.toLowerCase(),
|
||||||
w.addresses[0] &&
|
),
|
||||||
w.addresses[0].address.toLowerCase() === firstAddress.toLowerCase(),
|
|
||||||
);
|
);
|
||||||
if (duplicate) {
|
if (addrDup) {
|
||||||
showFlash(
|
showFlash(
|
||||||
"This recovery phrase is already added (" + duplicate.name + ").",
|
"An address from this phrase already exists in " +
|
||||||
|
addrDup.name +
|
||||||
|
".",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const xpubDup = state.wallets.find(
|
||||||
|
(w) => (w.type === "hd" || w.type === "xprv") && w.xpub === xpub,
|
||||||
|
);
|
||||||
|
if (xpubDup) {
|
||||||
|
showFlash("This recovery phrase matches " + xpubDup.name + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const encrypted = await encryptWithPassword(mnemonic, pw);
|
const encrypted = await encryptWithPassword(mnemonic, pw);
|
||||||
const walletNum = state.wallets.length + 1;
|
const walletNum = state.wallets.length + 1;
|
||||||
const wallet = {
|
const wallet = {
|
||||||
@@ -162,16 +170,11 @@ async function importPrivateKey(ctx) {
|
|||||||
}
|
}
|
||||||
const pw = validatePassword();
|
const pw = validatePassword();
|
||||||
if (!pw) return;
|
if (!pw) return;
|
||||||
const duplicate = state.wallets.find(
|
const duplicate = state.wallets.find((w) =>
|
||||||
(w) =>
|
w.addresses.some((a) => a.address.toLowerCase() === addr.toLowerCase()),
|
||||||
w.type === "key" &&
|
|
||||||
w.addresses[0] &&
|
|
||||||
w.addresses[0].address.toLowerCase() === addr.toLowerCase(),
|
|
||||||
);
|
);
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
showFlash(
|
showFlash("This address already exists in " + duplicate.name + ".");
|
||||||
"This private key is already added (" + duplicate.name + ").",
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const encrypted = await encryptWithPassword(key, pw);
|
const encrypted = await encryptWithPassword(key, pw);
|
||||||
@@ -208,14 +211,22 @@ async function importXprvKey(ctx) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { xpub, firstAddress } = result;
|
const { xpub, firstAddress } = result;
|
||||||
const duplicate = state.wallets.find(
|
const addrDup = state.wallets.find((w) =>
|
||||||
(w) =>
|
w.addresses.some(
|
||||||
(w.type === "hd" || w.type === "xprv") &&
|
(a) => a.address.toLowerCase() === firstAddress.toLowerCase(),
|
||||||
w.addresses[0] &&
|
),
|
||||||
w.addresses[0].address.toLowerCase() === firstAddress.toLowerCase(),
|
|
||||||
);
|
);
|
||||||
if (duplicate) {
|
if (addrDup) {
|
||||||
showFlash("This key is already added (" + duplicate.name + ").");
|
showFlash(
|
||||||
|
"An address from this key already exists in " + addrDup.name + ".",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const xpubDup = state.wallets.find(
|
||||||
|
(w) => (w.type === "hd" || w.type === "xprv") && w.xpub === xpub,
|
||||||
|
);
|
||||||
|
if (xpubDup) {
|
||||||
|
showFlash("This key matches " + xpubDup.name + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const pw = validatePassword();
|
const pw = validatePassword();
|
||||||
|
|||||||
@@ -243,7 +243,11 @@ function show(txInfo) {
|
|||||||
state.viewData = { pendingTx: txInfo };
|
state.viewData = { pendingTx: txInfo };
|
||||||
showView("confirm-tx");
|
showView("confirm-tx");
|
||||||
|
|
||||||
|
// Reset recipient warning to hidden (space always reserved, no layout shift)
|
||||||
|
$("confirm-recipient-warning").style.visibility = "hidden";
|
||||||
|
|
||||||
estimateGas(txInfo);
|
estimateGas(txInfo);
|
||||||
|
checkRecipientHistory(txInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function estimateGas(txInfo) {
|
async function estimateGas(txInfo) {
|
||||||
@@ -286,6 +290,26 @@ async function estimateGas(txInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkRecipientHistory(txInfo) {
|
||||||
|
const el = $("confirm-recipient-warning");
|
||||||
|
try {
|
||||||
|
const provider = getProvider(state.rpcUrl);
|
||||||
|
// Skip warning for contract addresses — they may legitimately
|
||||||
|
// have zero outgoing transactions (getTransactionCount returns
|
||||||
|
// the nonce, i.e. sent-tx count only).
|
||||||
|
const code = await provider.getCode(txInfo.to);
|
||||||
|
if (code && code !== "0x") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const txCount = await provider.getTransactionCount(txInfo.to);
|
||||||
|
if (txCount === 0) {
|
||||||
|
el.style.visibility = "visible";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log.errorf("recipient history check failed:", e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function init(ctx) {
|
function init(ctx) {
|
||||||
$("btn-confirm-send").addEventListener("click", async () => {
|
$("btn-confirm-send").addEventListener("click", async () => {
|
||||||
const password = $("confirm-tx-password").value;
|
const password = $("confirm-tx-password").value;
|
||||||
|
|||||||
Reference in New Issue
Block a user