Building a Non-Custodial Crypto Wallet: The Architecture Decisions That Matter

Building a non-custodial crypto wallet: the architecture decisions that matter

Wallet development is the project type where the gap between a demo and a shippable product is widest. A team can wire up an interface that generates an address, displays a balance, and sends a transaction in a couple of weeks. Turning that into something you would ask a stranger to put money into takes considerably longer, and almost all of the additional work sits in areas a demo never touches: how key material is generated and stored, what your infrastructure can learn about your users, how the app behaves when a node lies to it, and how you keep an open API from becoming an open door.

We have built and maintain non-custodial wallets in production, including KimlWallet and DokWallet, and the decisions below are the ones that consistently determine whether a wallet project goes smoothly or spends its last two months in remediation.

Non-Custodial Is an Architecture, Not a Marketing Term

The distinction that matters is control of key material. In a genuinely non-custodial design, the private key or seed is generated on the user’s device, never transmitted, and never recoverable by the operator. If your backend can reconstruct a user’s key under any circumstances — including a well-intentioned “account recovery” feature — you are custodial, whatever the landing page says.

This is not only a security question. Whether a wallet provider is deemed to hold client crypto-assets is central to how it is classified under frameworks such as the EU’s Markets in Crypto-Assets Regulation, and that classification follows the architecture rather than the description. Teams should settle the technical design and then take the regulatory question to qualified counsel in the relevant jurisdiction, not the other way around. We build to a specified custody model; determining which model a given business needs is a legal question, not an engineering one.

Key Generation and Storage on Device

The standards here are settled and there is little reason to deviate from them. Entropy is generated on device from a cryptographically secure source, converted to a mnemonic under BIP-39, and used to derive a hierarchical key tree under BIP-32 and BIP-44 so that a single seed serves every supported chain.

Where implementations diverge — and where reviews find problems — is storage. On iOS, key material belongs in the Keychain with the strictest practical accessibility class, ideally with Secure Enclave-backed protection and biometric gating. On Android, the equivalent is the hardware-backed Keystore with setUserAuthenticationRequired enabled where the device supports it. What key material must never touch is the JavaScript bridge in a cross-platform framework, application logs, crash-reporting payloads, clipboard history, or automatic cloud backup. Each of those is a documented leak path, and crash reporters in particular are easy to overlook because the leak only appears when something else has already gone wrong.

Seed backup is the point where security and usability collide hardest. A twelve-word phrase the user must write down is the most robust option and the one most users handle badly. Encrypted cloud backup improves recovery rates and introduces a new attack surface plus a passphrase-strength problem. Social recovery and multi-party schemes spread the risk differently rather than removing it. There is no correct answer, only a decision to be made deliberately, documented, and communicated honestly to users.

Multi-Chain Support Costs More Than It Looks

Adding a chain is rarely a matter of a new derivation path. Each family brings its own address format, fee model, transaction structure, finality behaviour, and failure modes. UTXO chains require coin selection and change management that account-based chains do not. Chains with account-model differences from the EVM — Solana being the common example — need distinct transaction construction, rent and account-creation handling, and their own signing flow. Every additional chain also multiplies the testing matrix and the ongoing maintenance load, because each has its own upgrade cadence that can break your integration without notice.

The practical scoping advice is to launch with the smallest set of chains your users actually need, and to treat each subsequent chain as a discrete piece of work with its own estimate rather than as a configuration change.

Your Node Strategy Is a Privacy Decision

Most wallets read chain state through third-party RPC providers, which is sensible from a reliability standpoint and quietly consequential for privacy. If every balance refresh sends a user’s addresses to a commercial endpoint alongside their IP address, that provider can build a linkage between network identity and on-chain activity even though your own servers store nothing. A wallet can be entirely non-custodial and still leak a detailed picture of its users this way.

Mitigations exist at varying cost: proxying requests so the provider sees your infrastructure rather than user IPs, batching and padding queries, rotating across multiple providers, or running your own nodes for high-traffic chains. Each trades operating cost or latency against exposure. The decision should be made explicitly and stated in the privacy policy, because users increasingly ask and the honest answer is not always the flattering one.

Hardening the API Layer

A non-custodial wallet still needs a backend for price feeds, token metadata, swap quotes, and push notifications. Because those endpoints hold no custody, they are frequently built with less rigour than they warrant — and an unauthenticated public API is both a cost-abuse problem and an information-disclosure problem, since query patterns alone can reveal user activity.

The pattern we implement combines several controls. Requests are signed with an HMAC over the payload, a timestamp, and a client-held secret, so that arbitrary callers cannot craft valid requests. A single-use nonce with a short validity window prevents replay of captured requests. Platform attestation — App Attest on iOS and the Play Integrity API on Android — establishes that a request originates from a genuine, unmodified build of your app rather than a script. A challenge mechanism such as Turnstile or reCAPTCHA covers web clients. Rate limits are applied per client and per endpoint rather than globally.

The design goal throughout is that the backend stores nothing which would be damaging to lose. If an endpoint does not need to persist user data to function, it should not, and that constraint should be enforced in review rather than left to good intentions.

Third-Party Integrations Are Someone Else’s Compliance Surface

Fiat on-ramps, swap aggregators, and card funding flows all bring external providers into your product, and each arrives with its own KYC scope, jurisdictional restrictions, and terms. Two failure modes recur. The first is technical: providers change response schemas, deprecate endpoints, and impose limits with little warning, so integrations need defensive parsing and graceful degradation rather than assuming a stable contract. The second is descriptive — marketing copy that overstates what an integrated service does. If a swap provider requires identity verification above a threshold, or supports fewer chains than your wallet does, the interface and the website must both say so. Claims about KYC scope and supported assets are exactly the statements that draw regulatory attention, and they are usually wrong through carelessness rather than intent.

What Open Source Changes

Publishing wallet source code is a meaningful trust signal and it raises the bar on everything else. Secrets cannot live in the repository, history included. Dependencies become publicly auditable, so pinning and a maintained SBOM matter more. Build reproducibility becomes a question users can actually ask, meaning the binary in the app store should be verifiably derived from the published source. None of this is prohibitive, but it needs to be planned from the first commit rather than retrofitted before a release.

Scoping a Wallet Project Realistically

A single-chain wallet with send, receive, and balance display is a genuinely small project. A multi-chain wallet with swap integration, fiat on-ramp, hardware-wallet support, push notifications, and a hardened API is a substantial one, and the security work is not a phase at the end — it is distributed across every stage of the build. Teams that budget for an independent security review before launch, rather than after a third party raises findings, consistently ship sooner and with less rework.

Previous postNext post

Keep your code secure with Dapplication.

Contact us