Skip to content

feat: add getPublicKey across all chains#194

Open
teyrebaz33 wants to merge 1 commit intoopen-wallet-standard:mainfrom
teyrebaz33:feat/get-public-key
Open

feat: add getPublicKey across all chains#194
teyrebaz33 wants to merge 1 commit intoopen-wallet-standard:mainfrom
teyrebaz33:feat/get-public-key

Conversation

@teyrebaz33
Copy link
Copy Markdown

Summary

Adds getPublicKey(walletName, chainId) to the Node SDK, Python SDK, and CLI. Eliminates the mnemonic round-trip workaround for public key access.

Closes #157

Problem

TON wallet contract initialization (WalletContractV5R1) requires the raw Ed25519 public key. The only workaround was calling exportWallet() to get the mnemonic, re-deriving the keypair externally, then zeroing secret material — partially undermining key isolation even with careful zeroing.

Solution

// Node SDK
const pubkey = getPublicKey('my-wallet', 'ton', undefined, vaultDir);
// → 'a1b2c3...' (32-byte hex, Ed25519)

const evmPubkey = getPublicKey('my-wallet', 'evm', undefined, vaultDir);
// → '02a1b2...' (33-byte compressed SEC1)
# CLI
ows wallet public-key --wallet my-wallet --chain ton
ows wallet public-key --wallet my-wallet --chain evm --json
# Python SDK
pubkey = get_public_key('my-wallet', 'ton', None, vault_dir)

Return format

Curve Chains Format
Ed25519 TON, Solana, Sui 32-byte hex (64 chars)
secp256k1 EVM, Bitcoin, Cosmos, Tron, XRPL, Filecoin, Spark 33-byte compressed SEC1 (66 chars, 02/03 prefix)

Changes

  • ows-signer: derive_public_key() added to ChainSigner trait, implemented for all 10 chains
  • ows-lib: get_public_key(wallet, chain, index, vault_path) with 8 unit tests
  • bindings/node: getPublicKey() exported via NAPI
  • bindings/python: get_public_key() exported via PyO3
  • ows-cli: ows wallet public-key --wallet --chain [--index] [--json]

Tests

test get_public_key_evm_returns_33_bytes ... ok
test get_public_key_ton_returns_32_bytes ... ok
test get_public_key_solana_returns_32_bytes ... ok
test get_public_key_bitcoin_returns_33_bytes ... ok
test get_public_key_is_deterministic ... ok
test get_public_key_different_index_yields_different_key ... ok
test get_public_key_fails_for_nonexistent_wallet ... ok
test get_public_key_all_chains ... ok

8 passed — 144 existing ows-lib tests also pass

Security

Public keys are not secret — exposing them does not weaken the security model. Private key material never leaves the OWS signing core.

Adds derive_public_key() to ChainSigner trait and wires it through
ows-lib, Node binding, Python binding, and CLI.

Closes open-wallet-standard#157

Problem
-------
TON wallet contract initialization (WalletContractV5R1) requires the
raw Ed25519 public key. The only workaround was exportWallet() to get
the mnemonic, re-derive externally, then zero the secret material —
partially undermining key isolation.

Solution
--------
Add get_public_key(wallet, chain, index) that returns the raw public
key hex without exposing any secret material.

Return format:
- Ed25519 chains (TON, Solana, Sui): 32-byte hex (64 chars)
- secp256k1 chains (EVM, Bitcoin, Cosmos, Tron, XRPL, Filecoin, Spark):
  33-byte compressed SEC1 hex (66 chars, starts with 02 or 03)

Changes
-------
- ows-signer: derive_public_key() added to ChainSigner trait
- ows-signer: implemented for all 10 chains
- ows-lib: get_public_key() with 8 unit tests (144 existing pass)
- bindings/node: getPublicKey() exported via NAPI
- bindings/python: get_public_key() exported via PyO3
- ows-cli: ows wallet public-key --wallet --chain [--index] [--json]
@teyrebaz33 teyrebaz33 requested a review from njdawn as a code owner April 5, 2026 00:33
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

@teyrebaz33 is attempting to deploy a commit to the MoonPay Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: getPublicKey(walletName, chainId) - needed for TON wallet contract initialization

1 participant