Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions modules/express/src/typedRoutes/api/v1/deriveLocalKeyChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,57 @@ import { BitgoExpressError } from '../../schemas/error';
* Request parameters for deriving a local keychain
*/
export const DeriveLocalKeyChainRequestBody = {
/** The derivation path to use (e.g. 'm/0/1') */
/** BIP32 derivation path (e.g., 'm/0/1' or '0/1'). Defines the hierarchical path from the parent key to derive the child key. */
path: t.string,
/** The extended private key to derive from (either xprv or xpub must be provided) */
/** BIP32 extended private key in base58 format (e.g., 'xprv9s21...'). Provide this to derive both child xprv and xpub. Must provide either xprv or xpub, but not both. */
xprv: optional(t.string),
/** The extended public key to derive from (either xprv or xpub must be provided) */
/** BIP32 extended public key in base58 format (e.g., 'xpub661MyMw...'). Provide this to derive only child xpub (cannot derive xprv from xpub). Must provide either xprv or xpub, but not both. */
xpub: optional(t.string),
};

/**
* Response for deriving a local keychain
*/
export const DeriveLocalKeyChainResponse = t.type({
/** The derivation path that was used */
/** The BIP32 derivation path that was used (echoes the input path for verification) */
path: t.string,
/** The derived extended public key */
/** The derived BIP32 extended public key in base58 format. Always returned regardless of whether xprv or xpub was provided as input. */
xpub: t.string,
/** The derived extended private key (only included if xprv was provided in the request) */
/** The derived BIP32 extended private key in base58 format. Only included if an xprv was provided in the request (not derivable from xpub alone). */
xprv: optional(t.string),
/** The Ethereum address derived from the xpub (if available) */
/** The Ethereum address (0x-prefixed hex format) derived from the xpub. Included when Ethereum address derivation is available for the key type. */
ethAddress: optional(t.string),
});

/**
* Derive a local keychain
* Derive a local keychain using BIP32 hierarchical deterministic derivation
*
* Locally derives a keychain from a top level BIP32 string (xprv or xpub), given a path.
* This is useful for deriving child keys from a parent key without having to store the child keys.
* Performs client-side BIP32 key derivation from a parent extended key (xprv or xpub) to a child key
* at the specified derivation path. This operation is performed entirely locally on the BitGo Express
* server without transmitting keys to BitGo's servers.
*
* The derivation process:
* 1. Takes either an xprv (extended private key) or xpub (extended public key) as input
* 2. Derives a child key at the specified path using BIP32 derivation
* 3. Returns the derived xpub (and xprv if an xprv was provided)
* 4. Also attempts to derive an Ethereum address from the xpub if possible
* **Use Cases:**
* - Derive child keys for specific addresses without storing all keys
* - Generate deterministic key hierarchies from a master key
* - Create segregated key paths for different purposes or accounts
*
* Note: You must provide either xprv or xpub, but not both. If xprv is provided,
* both the derived xprv and xpub are returned. If xpub is provided, only the
* derived xpub is returned.
* **Derivation Process:**
* 1. Accepts either an xprv (extended private key) or xpub (extended public key) as input
* 2. Parses the BIP32 extended key and validates its format
* 3. Applies BIP32 derivation algorithm at the specified path (e.g., 'm/0/1')
* 4. Returns the derived xpub (and xprv if input was xprv)
* 5. Optionally derives an Ethereum address from the xpub if applicable
*
* **Important Constraints:**
* - You must provide exactly one of xprv OR xpub (not both, not neither)
* - If xprv is provided: Returns both derived xprv and xpub
* - If xpub is provided: Returns only derived xpub (cannot derive xprv from xpub)
* - Ethereum address is only included if derivation is supported for the key type
*
* **Security Considerations:**
* - This operation is performed locally and keys are never sent to BitGo's servers
* - Extended private keys (xprv) should be handled with extreme care
* - Consider encrypting xprv values before storage or transmission
*
* @operationId express.v1.keychain.derive
* @tag express
Expand All @@ -54,9 +68,9 @@ export const PostDeriveLocalKeyChain = httpRoute({
body: DeriveLocalKeyChainRequestBody,
}),
response: {
/** Successfully derived keychain */
/** Successfully derived child keychain. Returns the derived xpub (always) and xprv (if input was xprv), along with optional Ethereum address. */
200: DeriveLocalKeyChainResponse,
/** Invalid request or derivation fails */
/** Invalid request parameters (e.g., missing path, invalid xprv/xpub format, both xprv and xpub provided, neither xprv nor xpub provided, or invalid derivation path). */
400: BitgoExpressError,
},
});