address

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package address validates SOVR account addresses (FR-014) and derives test-only addresses from BIP39 mnemonics (FR-015). Behavior is pinned by test-vectors/addresses.json and test-vectors/derivation.json; the TypeScript library mirrors every error code and check order exactly.

UNSAFE_TEST_ONLY — DeriveAddress handles raw mnemonics and private keys in process memory with no protection whatsoever. It exists solely for deterministic test-vector generation and integration testing (FR-015). Production key generation, storage, and signing belong entirely to the exchange's own custody infrastructure; never pass a production mnemonic to anything in this file.

Index

Constants

View Source
const (
	Bech32PrefixAccount  = "sovr"
	Bech32PrefixValOper  = "sovrvaloper"
	Bech32PrefixValCons  = "sovrvalcons"
	AccountAddressLength = 20
)
View Source
const (
	CodeEmpty          = "ADDRESS_EMPTY"
	CodeInvalidBech32  = "ADDRESS_INVALID_BECH32"
	CodeWrongPrefix    = "ADDRESS_WRONG_PREFIX"
	CodeWrongLength    = "ADDRESS_WRONG_LENGTH"
	CodeNotAccountType = "ADDRESS_NOT_ACCOUNT_TYPE"
	CodeProhibited     = "ADDRESS_PROHIBITED"
	CodeWhitespace     = "ADDRESS_WHITESPACE"
)

FR-014 error codes. Stable API: exchanges branch on these strings.

View Source
const DefaultHDPath = "m/44'/118'/0'/0/0"

DefaultHDPath is the documented Cosmos-compatible derivation path (SLIP-44 coin type 118), index 0.

Variables

This section is empty.

Functions

func ModuleAccountAddress

func ModuleAccountAddress(name string) (string, error)

ModuleAccountAddress returns the sovr1… address of a top-level module account (sha256(name) truncated to 20 bytes, per Cosmos SDK convention).

Types

type Address

type Address struct {
	Path                string
	PrivateKey          []byte // 32-byte secp256k1 secret — UNSAFE_TEST_ONLY
	PublicKeyCompressed []byte // 33 bytes
	AddressBytes        []byte // 20 bytes: ripemd160(sha256(pubkey))
	Bech32              string // sovr1…
}

Address is a derived test address with its full (test-only) key material.

func DeriveAddress

func DeriveAddress(mnemonic, path string) (Address, error)

DeriveAddress derives the secp256k1 key and sovr1… address for a BIP39 mnemonic at a BIP32 path of the form m/44'/118'/account'/change/index. UNSAFE_TEST_ONLY: see the file header.

type PSet

type PSet map[string]struct{}

PSet is a prohibited-address set for ValidateAccountAddressStrict. Entries must be canonical lowercase sovr1… strings; membership is exact-match against the normalized address.

func DefaultProhibitedModuleAccounts

func DefaultProhibitedModuleAccounts() PSet

DefaultProhibitedModuleAccounts is the kit's client-side withdrawal blocklist: every account a customer withdrawal must never reach, rejected client-side rather than left to fail — or strand funds — on-chain. Exchanges extend it via ValidateAccountAddressStrict.

It is the chain's blocked-module-account set PLUS gov, and is deliberately NOT identical to the chain's bank blocklist:

  • The 34 names below plus legacyRenamedModuleAccountAddress reproduce the chain's 35 blocked accounts. The one renamed-module account is pinned by address, never by its retired internal name (see legacyRenamedModuleAccountAddress).
  • gov is a CLIENT-ONLY addition. The chain omits gov from its bank blocklist only so MsgDeposit can move proposal deposits into the gov module account; a plain withdrawal MsgSend to that same address creates no governance deposit record, so the funds land in an account no keeper will ever release — permanently stranded. A withdrawal to gov is therefore always an operator error, and the kit rejects it up front.
  • mint has no counterpart: SOVR has no x/mint module, so no mint account exists to block.

The kit hardcodes the names (and the one legacy address) to keep itself free of any chain import. The 35 chain-mirrored entries are kept in sync by a drift test in the sbn repo (app/exchange_kit_module_accounts_test.go) that fails if the chain adds or removes a blocked module account; that test guards only the chain-mirrored names, and gov is pinned as the intentional client-only extra by address_test.go here. There are 36 entries in total: 35 names below plus the legacy address.

func NewPSet

func NewPSet(addrs ...string) PSet

func (PSet) Contains

func (p PSet) Contains(addr string) bool

type ValidationResult

type ValidationResult struct {
	Valid             bool
	NormalizedAddress string // set iff Valid; always lowercase canonical bech32
	ErrorCode         string
	ErrorMessage      string
}

ValidationResult is the outcome of address validation (contracts/go-client-api.md §address).

func ValidateAccountAddress

func ValidateAccountAddress(addr string) ValidationResult

ValidateAccountAddress validates addr as a SOVR account address (FR-014). Whitespace is never trimmed; uppercase-only bech32 is valid and normalized to lowercase; mixed case is invalid. Check order is contract-pinned: empty → whitespace → hex form → mixed case → bech32 decode → prefix → payload length.

func ValidateAccountAddressStrict

func ValidateAccountAddressStrict(addr string, prohibited PSet) ValidationResult

ValidateAccountAddressStrict runs ValidateAccountAddress and additionally rejects normalized addresses present in prohibited (module accounts, exchange blocklists) with ADDRESS_PROHIBITED.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL