Skip to content

feat(statics): add bip44CoinType per coin family - #9882

Open
danielpeng1 wants to merge 1 commit into
masterfrom
WCN-2955/statics-bip44-coin-type
Open

danielpeng1 wants to merge 1 commit into
masterfrom
WCN-2955/statics-bip44-coin-type

Conversation

@danielpeng1

Copy link
Copy Markdown
Contributor

Adds an optional bip44CoinType to statics coins, resolved per coin family, and moves the root slot list into statics.

  • Add bip44CoinType to BaseCoin, validated as an integer in [0, 0x7fffffff]
  • Add BIP44_COIN_TYPES, a table keyed by coin family, so testnets and tokens inherit their parent chain's value (OFC and fiat have none)
  • Move the root slot list and its ordinals (1–4) into statics; sdk-core imports it instead of keeping its own copy
  • Field stays optional for now; making it required is a follow-up

Tests

  • Field validation (valid, out-of-range, non-integer, boundaries) and family-value default
  • Table values are valid and unique, every coin carries its family's value, testnets and tokens mirror their parent, and every key-holding coin has a value
  • Slot ordinals cover the slot list and run 1–4 in order

Ticket: WCN-2955

@danielpeng1 danielpeng1 self-assigned this Oct 2, 2026
@linear-code

linear-code Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

WCN-2955

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Unit tests are failing on Node 26.x (Current release line, non-blocking). This is not an LTS version yet, so it does not block merge, but it signals an incompatibility to fix before Node 26.x becomes LTS.

View run

@danielpeng1
danielpeng1 marked this pull request as ready for review October 2, 2026 16:40
@danielpeng1
danielpeng1 requested review from a team as code owners October 2, 2026 16:40

@mohd-kashif mohd-kashif left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking suggestions from a code review — all optional, none block merge.

* change one. A new coin family takes the next free value above the highest (0x70000000 and up).
* OFC and fiat have no family entry and are not BIP44-derivable.
*/
export const BIP44_COIN_TYPES: Partial<Record<CoinFamilyName, number>> = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit (non-blocking): Since ofc and fiat are the only families intentionally omitted, consider typing this as Record<Exclude<CoinFamilyName, 'ofc' | 'fiat'>, number> instead of Partial<Record<...>>. That would make a missing derivable family a compile error rather than something only the runtime invariant test catches — and it would surface today that dydx and eth2 have no entry (fine while no derivable coins use them, but the compiler would force a conscious decision when one is added).

* coins carry no `bip44CoinType` and cannot mint a safe child key.
* @experimental
*/
export function isBip44Derivable(coin: Readonly<BaseCoin>): boolean {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit (non-blocking): isBip44Derivable is exported but has no consumer in this PR (only tests call it). Fine as experimental groundwork, but if no caller lands soon it's dead surface area in a package that's widely re-exported — consider landing it together with its first consumer or deferring it.

* (`m/44/<bip44CoinType>/<slot>/<account>`).
* @experimental
*/
export type SafeRootSlot = 'secp256k1Multisig' | 'ed25519Multisig' | 'ecdsaMpc' | 'eddsaMpc';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit (non-blocking): This adds a third name for the same 4-value union — public-types has RootKeyType, sdk-lib-safes has SafeRootKeyType (see #9881), and now SafeRootSlot here. The SAFE_ROOT_SLOTS: RootKeyType[] = STATICS_SAFE_ROOT_SLOTS assignment in sdk-core's rootCoin.ts does act as a compile-time drift check, which helps — but a short comment here noting RootKeyType (in @bitgo/public-types) as the canonical source of these slot names would help future readers keep them in sync.

}

// the bip44 coin type is the <coinType>' segment of safe child derivation paths
if (options.bip44CoinType !== undefined) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit (non-blocking): Validation asymmetry — explicitly-passed bip44CoinType values are range-checked here, but family-derived values (the ?? getBip44CoinType(...) fallback in the constructor) are only guarded by the BIP44_COIN_TYPES table test. Consistent today since the table is tested, just worth being aware the two paths carry different guarantees.

otherSupportedKeyCurves?: KeyCurve[];
/**
* BIP44 coin type used by the safe child derivation scheme
* `m/44'/<bip44CoinType>'/<slot>'/<account>'` (see SAFE_ROOT_SLOT_ORDINALS for `<slot>`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit (non-blocking): This reference to SAFE_ROOT_SLOT_ORDINALS is cross-package (it lives in safe.ts in this package), so a plain-text mention won't resolve as a JSDoc link from consumer packages. Minor — either keep as prose or note the defining module explicitly.

This branch has not been deployed

No deployments
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