Skip to content

feat(transaction): add useWalletRisk hook#2640

Open
lau90eth wants to merge 1 commit into
coinbase:mainfrom
lau90eth:feat/wallet-risk-v2
Open

feat(transaction): add useWalletRisk hook#2640
lau90eth wants to merge 1 commit into
coinbase:mainfrom
lau90eth:feat/wallet-risk-v2

Conversation

@lau90eth

@lau90eth lau90eth commented May 2, 2026

Copy link
Copy Markdown

Summary

Every day users send funds to wrong addresses, new wallets, or scam
accounts. One typo = lost forever. OnchainKit has zero wallet
verification before sending.

This PR adds useWalletRisk, a hook that analyzes the destination
wallet before the user clicks "Send" — flagging new wallets,
contracts, and suspicious patterns.

const { risk, flags, isContract, txCount } = useWalletRisk({
  address: recipientAddress,
});

// "🔴 New wallet — never received funds"
// "⚠️ Smart contract — verify before sending"
// "✅ Active wallet — 142 transactions"

What changed

  • useWalletRisk hook — analyzes a destination wallet address
    and returns risk level, flags, contract status, and transaction
    history summary
  • getWalletRisk utility — Basescan API integration that reads
    transaction history, detects new/unused wallets, and checks if
    address is a smart contract
  • WalletRisk type — standardized shape including risk level,
    flags array, isContract, txCount, and date ranges
  • Public exports — added to src/transaction/index.ts

Usage

import { useWalletRisk } from '@coinbase/onchainkit/transaction';

const {
  risk,          // 'low' | 'medium' | 'high'
  flags,         // string[] — human-readable risk signals
  isContract,    // true if address has deployed bytecode
  txCount,       // number of historical transactions
  firstTxDate,   // date of first transaction
  lastTxDate,    // date of most recent transaction
  isLoading,
  error,
} = useWalletRisk({ address: recipientAddress });

// Gate send button
<TransactionButton disabled={risk === 'high'} />

// Show warnings
{flags.map(flag => <p key={flag}>⚠️ {flag}</p>)}

API

type UseWalletRiskParams = {
  address?: Address;
};

type WalletRisk = {
  risk: 'low' | 'medium' | 'high';
  flags: string[];
  isContract: boolean;
  txCount: number;
  firstTxDate?: string;
  lastTxDate?: string;
  totalReceived?: string;
  totalSent?: string;
};

Risk scoring

Condition Risk Flag
Zero transactions high new_wallet
Never received funds high never_received
Smart contract medium smart_contract
< 5 transactions medium low_activity
Active wallet low

Conservative by design: new wallet = high risk by default.
Better to warn unnecessarily than miss a real risk.


Notes to reviewers

  • Uses Basescan txlist API — same pattern as useContractVerification.
    If apiKey is present in OnchainKitProvider, passed for higher
    rate limits. Works without key for low-volume usage.
  • isContract check via Basescan getabi endpoint — distinguishes
    EOA from smart contract without additional RPC call.
  • Complements useContractVerification — one analyzes destination
    contracts, the other destination wallets. Together they cover the
    full security surface before sending.
  • Returns { risk: 'low', flags: [] } when no address provided —
    zero impact on existing flows.

Testing

  • useWalletRisk.test.ts — 5 tests
  • getWalletRisk.test.ts — utility unit tests
  • All 389 test files pass (2698 tests)

Test cases covered:

  • Empty state → risk: 'low', flags: [], no fetch
  • New wallet (zero txs) → risk: 'high', flags: ['new_wallet']
  • Active wallet → risk: 'low', txCount populated
  • Smart contract → risk: 'medium', isContract: true
  • API error → graceful fallback, error state exposed

Risk

Low. Read-only hook. Basescan calls are GET requests with
zero side effects.

Returns default safe state { risk: 'low', flags: [] } when
no address is provided.

Does not modify any existing transaction, wallet, or API logic.

Adds wallet risk analysis to prevent sending funds to suspicious addresses.

- useWalletRisk hook: analyzes wallet history, detects risk signals
- getWalletRisk utility: Basescan API integration for tx history analysis
- Detects: new wallet, never received, low activity, smart contract
- Risk scoring: high for new/unused wallets, medium for contracts
- 5 tests covering: empty state, new wallet, active wallet, contract, API error

Refs: coinbase#2572
@vercel

vercel Bot commented May 2, 2026

Copy link
Copy Markdown

@lau90eth is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@cb-heimdall

Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants