mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
678 words
3 minutes
An EVM wallet login interface for EOAs
2026-06-08
2026-06-09

The following only represents the author’s current understanding

=====================

Recently, I built a mainly front-end interface for EOA wallet login. It can be considered the start of getting into blockChain development, and it also happened to let me get a feel for how the EVM is actually operated.

dreaifeHebi
/
web3WalletLogin
Waiting for api.github.com...
00K
0K
0K
Waiting...

image.png

A wallet login#

Although it is called one login, the interactions that actually require wallet confirmation happen twice—once for confirming the request initiated by the page to obtain the wallet address, and once for the server side to send a message to the wallet for verification, including things like the authentication message / calling domain / nonce, etc., following a protocol structure. The structure currently used imitates EIP-4361, though personally I feel this is more of a UI / traceability design; in practice, the nonce alone should be enough to ensure request disambiguation.

Why do we need to obtain the wallet address first before initiating verification? Probably because both the browser and the wallet themselves are untrusted. So if the data directly given during the intermediate interaction is considered untrusted, then only the address confirmed through the wallet is trusted, and only then can the process proceed to the next step of wallet verification.

I control this wallet!#

What is your wallet address?#

This is actually an interaction between the browser and the wallet, used to confirm which wallet address should be selected and authorized to be provided to the website.

In this project, wagmi’s connect is actually used to request wallet interaction.

// wagmi config
export const wagmiConfig = createConfig({
...,
connectors: [injected({ shimDisconnect: true })],
...
});
// get wagmi injected connector
const injectedConnector = useMemo(
() => connectors.find((connector) => connector.id === "injected") ?? connectors[0],
[connectors]
);
// connect wallet
connect({ connector: injectedConnector });
// auto get wallet connect info
const { address, chainId, isConnected } = useAccount();

Here, wagmi’s useAccount is also used to automatically obtain the updated information after wallet confirmation.

So, is this wallet you mentioned yours?#

I need you to authenticate this information#

Now that the address requiring authentication is known, we can prepare a standard SIWE (Sign-In with Ethereum) login signing message. A message in roughly this format:

localhost:3000 wants you to sign in with your Ethereum account:
0xYourWalletAddress
Sign in to web3walletLogin with this wallet.
URI: http://localhost:3000
Version: 1
Chain ID: 1
Nonce: <server-issued nonce>
Issued At: <generated timestamp>

Then this message is standardized according to EIP-191, to distinguish it from other signatures and ordinary transactions:

"\x19Ethereum Signed Message:\n" + len(message) + message

The implementation here comes from wagmi’s signMessageAsync, which performs the actual authentication request to the wallet.

const { signMessageAsync, isPending: isSigning } = useSignMessage();
// make a siwe message
const siweMessage = new SiweMessage({
domain: window.location.host,
address,
statement: "Sign in to web3walletLogin with this wallet.",
uri: siteOrigin,
version: "1",
chainId,
nonce
});
const preparedMessage = siweMessage.prepareMessage();
// send sign request to wallet
const signature = await signMessageAsync({ message: preparedMessage });

This is authentication that only my private key can produce#

When this message reaches the wallet requesting authentication, the wallet needs to ensure that its signature can prove its control over the address previously provided. At this point, the wallet needs to use its private key to encrypt the hash of the information just sent, while also ensuring that this signature can be verified by the website, which only knows the wallet address and the requested message. What is needed here is naturally a series of mathematical transformations to guarantee the validity of this verification method. Of course, here I am just using wagmi’s algorithm to verify the returned signature first (

// use the message (the client send) and sign(the wallet back)
const verifyResponse = await fetch("/api/auth/verify", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ message: preparedMessage, signature })
});
// sign message verify
const siwe = new SiweMessage(body.message);
const result = await siwe.verify({
signature: body.signature,
domain: expectedDomain,
nonce: siwe.nonce
});
// the fail result
if (!result.success) {
return NextResponse.json({ error: "invalid signature" }, { status: 401 });
}

As for the actual verification calculation?

That brings us to the secp256k1 curve used by EOA wallet signatures. For an EOA wallet, it is roughly like this:

  • EOA private key: a roughly 256-bit random number d
  • Public key: elliptic curve point Q = d * G
  • Address: the last 20 bytes of keccak256(publicKey)
  • Signature: ECDSA over secp256k1

However, I actually don’t really understand the actual computation in this part either (, but I roughly know that the reason the private key d cannot be reversed from the public key Q obtained via the signature and message hash is that it would be equivalent to solving the elliptic curve discrete logarithm problem Q=dGQ = d * G, with a workload on the order of about 21282^{128} (secp256k1 is a 256-bit-level curve).

In this way, using the returned signature (r+s+vr + s + v) and the message hash that we sent, we can ultimately recover a public key and calculate an address from it. When this address matches the address provided earlier, it proves that this wallet has control over that address.

Conclusion#

As a start to actually developing with blockChain, that’s about it. To be honest, when looking at the actual implementation of private-key signing and signature recovery, it felt a bit like when I first learned ACM (

But as a gateway project, it feels just right—it has sparked my interest in learning blockChain.

Share

If this article helped you, please share it with others!

An EVM wallet login interface for EOAs
https://dreaife.tokyo/en/posts/evm-wallet-login/
Author
dreaife
Published at
2026-06-08
License
CC BY-NC-SA 4.0

Some information may be outdated

Related Posts Smart
1
About an EOA Wallet Signature Verification and Related Content
WEB3 A developer-focused guide to EOA wallet signature verification, covering secp256k1, ECDSA r/s/v signatures, public key recovery, keccak-256 address derivation, and how SIWE proves wallet ownership without exposing the private key.
2
Trading Journal
WEB3 Recent trading experience shows a relatively high win rate, especially with a short position on February 3 that produced significant profit. Although some gains were lost due to judgment errors, overall returns remain positive. The market is currently range-bound and may face a second test in the short term, so caution is needed. The trading strategy is mainly based on candlesticks and volume, with position allocation of 80% low-leverage trend trading, 10% high-leverage high-frequency trading, and the remaining funds used for on-chain operations. To avoid emotional trading, staying in cash is recommended when judgment is unclear, and high-risk operations should be considered after cash flow becomes stable.
3
Understanding Blockchain
WEB3 Blockchain is a structure composed of blocks linked in chronological order, with core characteristics such as decentralization, immutability, transparency, and security. Its workflow includes transaction creation, validation, packaging, and adding blocks to the chain. Application scenarios include cryptocurrencies, supply chain management, and financial services. Challenges include scalability, energy consumption, and user education. The underlying logic is based on distributed ledgers and consensus mechanisms to ensure data security and consistency.
4
The First Round of Screening in the New Era
life This article explores how, against the backdrop of rapid AI development, the cost of using advanced models will become a key factor in a new round of social screening. The author expresses concern that rising model usage fees may lead to a digital divide, pointing out that when usage costs increase from today’s subsidized prices to higher levels, ordinary users may struggle to afford them, resulting in class-based differentiation in technology access. The article also reviews AI’s diverse applications in fields such as security, video, and music, emphasizing that AI is expanding from a coding tool into broader industries. From a personal perspective, the author describes how to navigate the tide of the times with limited capital and calls for attention to the impact of technology costs on public access. Keywords: AI model costs, digital divide, technological screening, AI applications, anxiety of the times.
5
Blog Migration - Mizuki Configuration Records
infra A record of the migration from NotionNext to Mizuki, mainly due to NotionNext's limitations. Mizuki was chosen for its lightweight nature and good balance of features, supporting diaries and project showcases. The configuration process is simple, with content controlled via md and ts files, and it also connects to the Bangumi API. The plan is to synchronize Notion content via CI, implement multilingual support, and address the issue of image links expiring.

Table of Contents