Skip to content

Add ValidateAddress function to check onchain and offchain addresses#136

Open
tiero wants to merge 2 commits into
masterfrom
claude/add-address-validation-IBzhT
Open

Add ValidateAddress function to check onchain and offchain addresses#136
tiero wants to merge 2 commits into
masterfrom
claude/add-address-validation-IBzhT

Conversation

@tiero
Copy link
Copy Markdown
Member

@tiero tiero commented Apr 6, 2026

Adds an exported ValidateAddress(address string) function that infers
the network from the address prefix and returns whether it is a valid
Bitcoin onchain address or Ark offchain address, without requiring a
configured client.

https://claude.ai/code/session_0151wY6W7ib1h3HWof32Xz7q

Summary by CodeRabbit

  • New Features

    • Added address validation supporting Bitcoin onchain formats and Ark offchain formats, improving input validation across the app.
  • Tests

    • Added comprehensive tests covering valid onchain and offchain addresses and various invalid input cases.

Adds an exported ValidateAddress(address string) function that infers
the network from the address prefix and returns whether it is a valid
Bitcoin onchain address or Ark offchain address, without requiring a
configured client.

https://claude.ai/code/session_0151wY6W7ib1h3HWof32Xz7q
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 6, 2026

Walkthrough

Added a new exported function ValidateAddress(address string) that classifies an input as a Bitcoin onchain address (tries multiple Bitcoin networks) or an Ark offchain address (falls back to Ark V0 decoding). Also added unit tests exercising onchain, offchain, and invalid inputs.

Changes

Cohort / File(s) Summary
Address Validation (runtime)
utils.go
Added ValidateAddress(address string) (isOnchain bool, isOffchain bool, err error) which iterates Bitcoin networks (btcutil.DecodeAddress) and falls back to arklib.DecodeAddressV0 on failure.
Tests
utils_test.go
Added TestValidateAddress which generates Bitcoin addresses (P2PKH, P2WPKH, P2TR across mainnet/testnet/regtest) and an Ark V0 address; verifies onchain, offchain, and several invalid inputs.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller as Caller
  participant Val as ValidateAddress
  participant BTC as btcutil.DecodeAddress
  participant ARK as arklib.DecodeAddressV0

  Caller->>Val: ValidateAddress(address)
  Val->>BTC: try decode (mainnet/testnet3/signet/regtest/Mutiny)
  alt BTC decode succeeds
    BTC-->>Val: decoded (onchain)
    Val-->>Caller: (isOnchain=true, isOffchain=false, nil)
  else BTC decode fails for all nets
    Val->>ARK: DecodeAddressV0(address)
    alt ARK decode succeeds
      ARK-->>Val: decoded (offchain)
      Val-->>Caller: (isOnchain=false, isOffchain=true, nil)
    else ARK decode fails
      ARK-->>Val: error
      Val-->>Caller: (false, false, error)
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • altafan
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and accurately summarizes the main change: adding a ValidateAddress function for checking both onchain and offchain addresses.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/add-address-validation-IBzhT

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
utils.go (1)

151-160: Prefer a single source of truth for supported Bitcoin networks.

Lines 151-157 duplicate network mapping that already exists via toBitcoinNetwork. This can drift as networks evolve.

♻️ Proposed refactor
 func ValidateAddress(address string) (isOnchain bool, isOffchain bool, err error) {
-	knownNetworks := []*chaincfg.Params{
-		&chaincfg.MainNetParams,
-		&chaincfg.TestNet3Params,
-		&chaincfg.SigNetParams,
-		&chaincfg.RegressionNetParams,
-		&arklib.MutinyNetSigNetParams,
-	}
-	for _, net := range knownNetworks {
-		if _, e := btcutil.DecodeAddress(address, net); e == nil {
+	knownNetworks := []arklib.Network{
+		arklib.Bitcoin,
+		arklib.BitcoinTestNet,
+		arklib.BitcoinSigNet,
+		arklib.BitcoinRegTest,
+		arklib.BitcoinMutinyNet,
+	}
+	for _, net := range knownNetworks {
+		params := toBitcoinNetwork(net)
+		if _, e := btcutil.DecodeAddress(address, &params); e == nil {
 			return true, false, nil
 		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils.go` around lines 151 - 160, The hardcoded knownNetworks slice
duplicates logic from toBitcoinNetwork and risks drifting; replace the inline
knownNetworks usage in the address validation loop with the canonical network
set returned or referenced by toBitcoinNetwork (e.g., iterate over the
networks/mapping provided by toBitcoinNetwork instead of creating
&chaincfg.MainNetParams, &chaincfg.TestNet3Params, &chaincfg.SigNetParams,
&chaincfg.RegressionNetParams, &arklib.MutinyNetSigNetParams), then call
btcutil.DecodeAddress(address, net) as before and return the same values; remove
the duplicated slice so the code uses the single source of truth in
toBitcoinNetwork.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@utils.go`:
- Around line 151-160: The hardcoded knownNetworks slice duplicates logic from
toBitcoinNetwork and risks drifting; replace the inline knownNetworks usage in
the address validation loop with the canonical network set returned or
referenced by toBitcoinNetwork (e.g., iterate over the networks/mapping provided
by toBitcoinNetwork instead of creating &chaincfg.MainNetParams,
&chaincfg.TestNet3Params, &chaincfg.SigNetParams, &chaincfg.RegressionNetParams,
&arklib.MutinyNetSigNetParams), then call btcutil.DecodeAddress(address, net) as
before and return the same values; remove the duplicated slice so the code uses
the single source of truth in toBitcoinNetwork.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 09445741-80d0-4dd8-a740-7925d1a3b41e

📥 Commits

Reviewing files that changed from the base of the PR and between 7435d18 and ae90cca.

📒 Files selected for processing (1)
  • utils.go

Tests cover valid onchain addresses (P2PKH, P2WPKH, P2TR across mainnet,
testnet, and regtest), valid Ark offchain addresses, and invalid inputs
(empty string, garbage, unknown prefix, truncated addresses).
Addresses are generated programmatically to avoid hardcoded checksum values.

https://claude.ai/code/session_0151wY6W7ib1h3HWof32Xz7q
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@utils_test.go`:
- Line 81: The long call at p2trMainnet, err :=
btcutil.NewAddressTaproot(schnorr.SerializePubKey(pubKey),
&chaincfg.MainNetParams) exceeds golines limits; split it across lines or
extract the serialized pubkey into a temporary variable to shorten the
expression. For example, assign serialized := schnorr.SerializePubKey(pubKey)
and then call btcutil.NewAddressTaproot(serialized, &chaincfg.MainNetParams) or
break the NewAddressTaproot call arguments onto multiple lines so the line
length constraint is satisfied (affects p2trMainnet, err,
btcutil.NewAddressTaproot, schnorr.SerializePubKey, pubKey,
chaincfg.MainNetParams).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d43598c4-998d-43ab-989b-a8e2b568cc96

📥 Commits

Reviewing files that changed from the base of the PR and between ae90cca and 6abb77f.

📒 Files selected for processing (1)
  • utils_test.go

Comment thread utils_test.go
require.NoError(t, err)
p2wpkhMainnet, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.MainNetParams)
require.NoError(t, err)
p2trMainnet, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(pubKey), &chaincfg.MainNetParams)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix golines formatting at Line 81 to unblock CI.

Line 81 exceeds formatting limits and is currently failing lint in CI.

Suggested formatting fix
-	p2trMainnet, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(pubKey), &chaincfg.MainNetParams)
+	p2trMainnet, err := btcutil.NewAddressTaproot(
+		schnorr.SerializePubKey(pubKey),
+		&chaincfg.MainNetParams,
+	)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
p2trMainnet, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(pubKey), &chaincfg.MainNetParams)
p2trMainnet, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(pubKey),
&chaincfg.MainNetParams,
)
🧰 Tools
🪛 GitHub Actions: ci_unit

[error] 81-81: golangci-lint reported formatting error: File is not properly formatted (golines).

🪛 GitHub Check: Sdk unit tests

[failure] 81-81:
File is not properly formatted (golines)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils_test.go` at line 81, The long call at p2trMainnet, err :=
btcutil.NewAddressTaproot(schnorr.SerializePubKey(pubKey),
&chaincfg.MainNetParams) exceeds golines limits; split it across lines or
extract the serialized pubkey into a temporary variable to shorten the
expression. For example, assign serialized := schnorr.SerializePubKey(pubKey)
and then call btcutil.NewAddressTaproot(serialized, &chaincfg.MainNetParams) or
break the NewAddressTaproot call arguments onto multiple lines so the line
length constraint is satisfied (affects p2trMainnet, err,
btcutil.NewAddressTaproot, schnorr.SerializePubKey, pubKey,
chaincfg.MainNetParams).

@altafan
Copy link
Copy Markdown
Contributor

altafan commented Apr 7, 2026

@tiero this function should be added to arkd/pkg/ark-lib

@tiero
Copy link
Copy Markdown
Member Author

tiero commented Apr 7, 2026

My idea was to
Avoid to have devs to install may packages and since this is a "unified" method (checks both onchain and Arkade) feels to me more like an SDK convenience method (Ark lib already has the decode address method)

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.

3 participants