-
Notifications
You must be signed in to change notification settings - Fork 300
refactor: migrated generateWallet to typed routes #7052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
danielzhao122
merged 8 commits into
master
from
WP-5415-express-migrate-api-v2-coin-wallet-generate-to-typed-routes
Oct 31, 2025
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
9156c78
refactor: migrated generateWallet to typed routes
danielzhao122 70d48ad
refactor: moved codecs and changed generate.ts->generateWallet.ts
danielzhao122 abd87a9
refactor: includeKeychain is type BooleanFromString
danielzhao122 678e891
refactor: included missing package
danielzhao122 d03a236
refactor: added supterests and modified request codec
danielzhao122 0e14f60
Merge remote-tracking branch 'origin/master' into WP-5415-express-mig…
danielzhao122 35276bb
refactor: fix bug in generateWalletOptionsi
danielzhao122 95909b1
refactor: generateWalletOptions change
danielzhao122 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
modules/express/src/typedRoutes/api/v2/generateWallet.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import * as t from 'io-ts'; | ||
| import { BooleanFromString } from 'io-ts-types'; | ||
| import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; | ||
| import { BitgoExpressError } from '../../schemas/error'; | ||
| import { UserKeychainCodec, BackupKeychainCodec, BitgoKeychainCodec } from '../../schemas/keychain'; | ||
| import { multisigType, walletType } from '../../schemas/wallet'; | ||
|
|
||
| /** | ||
| * Request body for wallet generation. | ||
| */ | ||
| export const GenerateWalletBody = { | ||
| /** Wallet label */ | ||
| label: t.string, | ||
| /** Enterprise id. Required for Ethereum wallets since they can only be created as part of an enterprise. Optional for other coins. */ | ||
| enterprise: optional(t.string), | ||
| /** If absent, BitGo uses the default wallet type for the asset */ | ||
| multisigType: optional(multisigType), | ||
| /** The type of wallet, defined by key management and signing protocols. 'hot' and 'cold' are both self-managed wallets. If absent, defaults to 'hot' */ | ||
| type: optional(walletType), | ||
| /** Passphrase to be used to encrypt the user key on the wallet */ | ||
| passphrase: optional(t.string), | ||
| /** User provided public key */ | ||
| userKey: optional(t.string), | ||
| /** Backup extended public key */ | ||
| backupXpub: optional(t.string), | ||
| /** Optional key recovery service to provide and store the backup key */ | ||
| backupXpubProvider: optional(t.literal('dai')), | ||
| /** Flag for disabling wallet transaction notifications */ | ||
| disableTransactionNotifications: optional(t.boolean), | ||
| /** The passphrase used for decrypting the encrypted wallet passphrase during wallet recovery */ | ||
| passcodeEncryptionCode: optional(t.string), | ||
| /** Seed that derives an extended user key or common keychain for a cold wallet */ | ||
| coldDerivationSeed: optional(t.string), | ||
| /** Gas price to use when deploying an Ethereum wallet */ | ||
| gasPrice: optional(t.number), | ||
| /** Flag for preventing KRS from sending email after creating backup key */ | ||
| disableKRSEmail: optional(t.boolean), | ||
| /** (ETH only) Specify the wallet creation contract version used when creating a wallet contract */ | ||
| walletVersion: optional(t.number), | ||
| /** True, if the wallet type is a distributed-custodial. If passed, you must also pass the 'enterprise' parameter */ | ||
| isDistributedCustody: optional(t.boolean), | ||
| /** BitGo key ID for self-managed cold MPC wallets */ | ||
| bitgoKeyId: optional(t.string), | ||
| /** Common keychain for self-managed cold MPC wallets */ | ||
| commonKeychain: optional(t.string), | ||
| } as const; | ||
|
|
||
| export const GenerateWalletResponse200 = t.union([ | ||
| t.UnknownRecord, | ||
| t.type({ | ||
| wallet: t.UnknownRecord, | ||
| encryptedWalletPassphrase: optional(t.string), | ||
| userKeychain: optional(UserKeychainCodec), | ||
| backupKeychain: optional(BackupKeychainCodec), | ||
| bitgoKeychain: optional(BitgoKeychainCodec), | ||
| warning: optional(t.string), | ||
| }), | ||
| ]); | ||
|
|
||
| /** | ||
| * Response body for wallet generation. | ||
| */ | ||
| export const GenerateWalletResponse = { | ||
| /** The newly created wallet */ | ||
| 200: GenerateWalletResponse200, | ||
| /** Bad request */ | ||
| 400: BitgoExpressError, | ||
| } as const; | ||
|
|
||
| /** | ||
| * Path parameters for wallet generation. | ||
| */ | ||
| export const GenerateWalletV2Params = { | ||
| /** Coin ticker / chain identifier */ | ||
| coin: t.string, | ||
| }; | ||
|
|
||
| /** | ||
| * Query parameters for wallet generation. | ||
| * @property includeKeychains - Include user, backup and bitgo keychains along with generated wallet | ||
| */ | ||
| export const GenerateWalletV2Query = { | ||
| /** Include user, backup and bitgo keychains along with generated wallet */ | ||
| includeKeychains: optional(BooleanFromString), | ||
| }; | ||
|
|
||
| /** | ||
| * Generate Wallet | ||
| * | ||
| * This API call creates a new wallet. Under the hood, the SDK (or BitGo Express) does the following: | ||
| * | ||
| * 1. Creates the user keychain locally on the machine, and encrypts it with the provided passphrase (skipped if userKey is provided). | ||
| * 2. Creates the backup keychain locally on the machine. | ||
| * 3. Uploads the encrypted user keychain and public backup keychain. | ||
| * 4. Creates the BitGo key (and the backup key if backupXpubProvider is set) on the service. | ||
| * 5. Creates the wallet on BitGo with the 3 public keys above. | ||
| * | ||
| * ⓘ Ethereum wallets can only be created under an enterprise. Pass in the id of the enterprise to associate the wallet with. Your enterprise id can be seen by clicking on the "Manage Organization" link on the enterprise dropdown. Each enterprise has a fee address which will be used to pay for transaction fees on all Ethereum wallets in that enterprise. The fee address is displayed in the dashboard of the website, please fund it before creating a wallet. | ||
| * | ||
| * ⓘ You cannot generate a wallet by passing in a subtoken as the coin. Subtokens share wallets with their parent coin and it is not possible to create a wallet specific to one token. | ||
| * | ||
| * ⓘ This endpoint should be called through BitGo Express if used without the SDK, such as when using cURL. | ||
| * | ||
| * @operationId express.wallet.generate | ||
| */ | ||
| export const PostGenerateWallet = httpRoute({ | ||
| path: '/api/v2/:coin/wallet/generate', | ||
| method: 'POST', | ||
| request: httpRequest({ | ||
| params: GenerateWalletV2Params, | ||
| query: GenerateWalletV2Query, | ||
| body: GenerateWalletBody, | ||
| }), | ||
| response: GenerateWalletResponse, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import * as t from 'io-ts'; | ||
danielzhao122 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Base keychain fields | ||
| const BaseKeychainCodec = t.type({ | ||
| id: t.string, | ||
| pub: t.string, | ||
| source: t.string, | ||
| }); | ||
|
|
||
| // User keychain: can have encryptedPrv and prv | ||
| export const UserKeychainCodec = t.intersection([ | ||
| BaseKeychainCodec, | ||
| t.partial({ | ||
| ethAddress: t.string, | ||
| coinSpecific: t.UnknownRecord, | ||
| encryptedPrv: t.string, | ||
| prv: t.string, | ||
| }), | ||
| ]); | ||
|
|
||
| // Backup keychain: can have prv | ||
| export const BackupKeychainCodec = t.intersection([ | ||
| BaseKeychainCodec, | ||
| t.partial({ | ||
| ethAddress: t.string, | ||
| coinSpecific: t.UnknownRecord, | ||
| prv: t.string, | ||
| }), | ||
| ]); | ||
|
|
||
| // BitGo keychain: must have isBitGo | ||
| export const BitgoKeychainCodec = t.intersection([ | ||
| BaseKeychainCodec, | ||
| t.type({ | ||
| isBitGo: t.boolean, | ||
| }), | ||
| t.partial({ | ||
| ethAddress: t.string, | ||
| coinSpecific: t.UnknownRecord, | ||
| }), | ||
| ]); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.