Skip to content

Repository files navigation

HarmonyWeb3Wallet

A self-custody web3 wallet with a built-in dApp browser for HarmonyOS NEXT, written entirely in ArkTS. No ohpm dependencies — all cryptography (BIP-39, BIP-32, Keccak-256, secp256k1, RLP, EIP-155/EIP-1559 transaction encoding, EIP-712) is implemented in pure ArkTS in this repo, so the whole wallet stack is auditable in one place.

Features

  • Wallet creation & import — 256-bit BIP-39 mnemonic generation (via cryptoFramework secure RNG) or import of an existing 12/15/18/21/24-word phrase, with optional passphrase. Backup screen shows the mnemonic once.
  • Secure key storage — the mnemonic is stored in the system credential area via Asset Store Kit (@kit.AssetStoreKit), gated on DEVICE_UNLOCKED accessibility, REQUIRE_PASSWORD_SET, SYNC_TYPE: NEVER. The derived private key exists only in process memory while unlocked.
  • EVM chains — Ethereum, Sepolia, Polygon, BNB Chain, Arbitrum One, OP Mainnet and Harmony Shard 0. Native-balance display, send (legacy + EIP-1559, gas estimation, nonce management) and receive (QR code + copy-to-clipboard).
  • dApp browser — a Web component with URL bar that injects an EIP-1193 provider (window.ethereum, plus an EIP-6963 announcement). eth_requestAccounts, personal_sign, eth_sign, eth_signTypedData*, eth_sendTransaction and wallet_switchEthereumChain all surface a native approval dialog (connect / sign / send / switch) before touching the key. Read-only methods pass through to the chain's JSON-RPC.

Project layout

entry/src/main/ets/
  wallet/
    crypto/        # pure-ArkTS crypto: Bytes, Sha256/512, Hmac, Pbkdf2,
                   # Keccak, Secp256k1, Base58, Bip39, Bip32, Rlp, EthTx,
                   # Eip712, Units, wordlists/English (2048 BIP-39 words)
    Chains.ets     # chain registry (chainId, RPC, explorer, EIP-1559 flag)
    SecureStorage.ets  # Asset Store Kit wrapper
    RpcClient.ets  # JSON-RPC over @kit.NetworkKit http
    WalletManager.ets  # unlock/sign/send, nonce + gas management
  provider/
    InjectedScript.ets # JS shim injected into every page (EIP-1193/EIP-6963)
    ProviderBridge.ets # method routing + RPC error codes (4001/4200/4902)
    ApprovalQueue.ets  # pending-approval queue feeding the UI overlay
  pages/           # Onboarding, MnemonicBackup, Index (tabs: Wallet+Browser),
                   # SendPage, ReceivePage, BrowserPage (Web + approval overlay)
  entryability/EntryAbility.ets
test/
  crypto.test.mjs  # Node test harness — runs the real .ets sources
  sync.sh          # copies .ets sources into test/build/*.ts for Node

Building

Option A — DevEco Studio (recommended, required for device installs)

  1. Install DevEco Studio 5.0+ with HarmonyOS NEXT SDK (API 12+).
  2. Open this directory. DevEco will sync oh-package.json5 automatically.
  3. Configure a signing profile: File → Project Structure → Signing Configs (or add a signingConfigs block in build-profile.json5). The checked-in build-profile.json5 intentionally ships with "signingConfigs": [] — unsigned builds cannot be installed on a device.
  4. Run 'entry' on an emulator or device.

Option B — HarmonyOS Command Line Tools (works on Linux too)

Download the official Command Line Tools (commandline-tools-*) for your platform — e.g. commandline-tools-linux-x64 — from Huawei's repo:

https://repo.huaweicloud.com/harmonyos/ohpm/<version>/commandline-tools-linux-x64-<version>.zip

This project was built and verified on Linux x64 with commandline-tools-linux-x64-5.1.0.840 (hvigor 5.18.5, ohpm 5.1.3, bundled Node 18.20.1, HarmonyOS SDK 5.1.0 / API 18):

cd <unpacked>/command-line-tools/bin
./ohpm install --all            # run inside the project root
./hvigorw assembleHap --mode module -p product=default -p buildMode=debug --no-daemon
./codelinter entry/src/main/ets # optional lint

hvigorw locates DEVECO_NODE_HOME/DEVECO_SDK_HOME itself when run from the bin/ directory of the tool distribution.

What was verified

All verification ran on Linux — no HarmonyOS device or emulator was available, so nothing below claims device-level correctness.

Check Result
test/crypto.test.mjs under Node 24 117/117 assertions pass
hvigorw assembleHap (ArkTS compile + package) BUILD SUCCESSFUL — entry-default-unsigned.hap produced
codelinter on entry/src/main/ets 0 errors, 11 warnings

The Node harness (test/sync.sh + crypto.test.mjs) compiles and executes the actual .ets crypto sources:

  • BIP-39 — all 24 official vectors (entropy → mnemonic, mnemonic → seed)
  • BIP-32 — official test vector 1 master key + m/0' xprv derivation
  • SHA-256 / SHA-512 / HMAC / Keccak-256 — published vectors
  • secp256k1 — keypair from known keys (privkey 1, anvil test account 0)
  • Transaction signing — the EIP-155 spec example transaction byte-for-byte, an EIP-1559 sign/serialize roundtrip, personal_sign + ecrecover
  • EIP-712 — the canonical "Mail" example from the EIP digest-matched
  • Base58 — roundtrip

codelinter warnings are all the same informational perf rule (@performance/hp-arkui-use-local-var-to-replace-state-var) on @State fields that genuinely drive UI reactivity (busy/error flags) — left as-is.

What could NOT be tested

  • On-device / emulator execution — no device, emulator, or hdc target was available on the build host. App lifecycle, navigation, and rendering are unverified.
  • Asset Store Kit behavior — addSync/querySync/removeSync against a real credential area, lock-screen-gated accessibility, and behavior across reboots. The calls compile and follow the SDK docs, but were never run.
  • The dApp browser end-to-end — javaScriptProxy + injected window.ethereum against a real dApp, __harmonyResolve/__harmonyNotify callbacks, and the approval overlay in a running Web component.
  • Live chain interaction — RPC calls, gas estimation, and transaction broadcast were never executed against a real node; RpcClient paths are exercised only by the compiler.
  • Signing — the produced .hap is unsigned; install requires a signing profile (debug or release) configured in DevEco Studio / build-profile.json5.
  • Compatibility — built against HarmonyOS SDK 5.1.0 targeting compatibleSdkVersion 5.0.0 (API 12). HMS generateBarcode (ScanKit) is used for the receive QR; it may be unavailable on pure OpenHarmony devices (the app degrades gracefully to text-only address display).

Security notes

  • The private key is re-derived in memory on unlock; only the mnemonic is persisted, via Asset Store Kit, never in preferences or files.
  • Possible hardening (not implemented): per-access biometric/lock-screen authentication via AUTH_TYPE: ANY + userAuth, or wrapping the mnemonic with a HUKS AES key before storing.
  • The injected provider only signs what the user approves; connected origins are remembered for the session (in-memory only) and reset on app restart.
  • eth_sign (raw hash signing) is supported but shows an explicit warning — it can be used to drain wallets and many providers disable it entirely.
  • wallet_addEthereumChain and wallet_watchAsset are rejected (error 4200); wallet_switchEthereumChain works for the built-in chain list.

Running the crypto tests

./test/sync.sh            # copy .ets → test/build/*.ts
node --experimental-strip-types test/crypto.test.mjs   # Node 22.6+
# or simply `node test/crypto.test.mjs` on Node 24+

License

MIT — see source headers. This is a reference implementation; audit before using it with real funds.

About

Web3 wallet + EIP-1193 dApp browser for HarmonyOS NEXT in pure ArkTS

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages