From bd893c9b54a65453e528f02ee44bcf6711d792ec Mon Sep 17 00:00:00 2001 From: Alia Aamir Date: Thu, 5 Feb 2026 14:14:15 -0500 Subject: [PATCH] feat: update scripts for go account creation CAAS-739 TICKET: CAAS-739 --- examples/README.md | 7 + examples/docs/go-account-creation.md | 253 ++++++++++++++++++ examples/ts/create-go-account-advanced.ts | 310 ++++++++++++++++++++++ examples/ts/create-go-account.ts | 118 ++++++-- 4 files changed, 666 insertions(+), 22 deletions(-) create mode 100644 examples/docs/go-account-creation.md create mode 100644 examples/ts/create-go-account-advanced.ts diff --git a/examples/README.md b/examples/README.md index 0f525fb623..f8c7d1b475 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,6 +4,13 @@ In this directory, you can find examples on how to use the BitGoJS SDK with TypeScript. These examples use modern TypeScript/ES6 syntax with `async`/`await`. This is the recommended way to use the BitGoJS SDK for new projects. +### Go Accounts (Trading Wallets) + +Go Accounts are trading wallets that don't require BitGo Express. See the [detailed guide](./docs/go-account-creation.md) for more information. + +- [Create Go Account (SDK Approach - Recommended)](./ts/create-go-account.ts) - Simple, high-level wallet creation +- [Create Go Account (Advanced SDK Approach)](./ts/create-go-account-advanced.ts) - Manual keychain control for advanced users + ### Wallet - [Backup Key Creation](./ts/backup-key-creation.ts) diff --git a/examples/docs/go-account-creation.md b/examples/docs/go-account-creation.md new file mode 100644 index 0000000000..b3c71e4766 --- /dev/null +++ b/examples/docs/go-account-creation.md @@ -0,0 +1,253 @@ +# Creating Go Accounts without BitGo Express + +This guide demonstrates how to create Go Accounts (trading wallets) using only the BitGo SDK, without requiring BitGo Express. + +## Overview + +**BitGo Express is optional middleware** - you can interact directly with the BitGo platform using the SDK. This approach gives you: +- Direct API communication with BitGo +- No need to run a separate Express server +- Full control over the wallet creation process +- Production-ready code with proper error handling + +## Two Approaches + +### 1. SDK Approach (Recommended) +**File:** `examples/ts/create-go-account.ts` + +Uses the high-level `generateWallet()` method which handles keychain creation, encryption, and wallet setup automatically. + +**Best for:** +- Most production use cases +- Quick integration +- Users who don't need manual key management + +**Example:** +```typescript +const bitgo = new BitGoAPI({ + accessToken: process.env.TESTNET_ACCESS_TOKEN, + env: 'test', +}); + +const coin = 'ofc'; +bitgo.register(coin, coins.Ofc.createInstance); + +const response = await bitgo.coin(coin).wallets().generateWallet({ + label: 'My Go Account', + passphrase: 'wallet_passphrase', + passcodeEncryptionCode: 'encryption_code', + enterprise: 'your_enterprise_id', + type: 'trading', // Required for Go Accounts +}); + +const { wallet, userKeychain, encryptedWalletPassphrase } = response; +``` + +### 2. Advanced SDK Approach +**File:** `examples/ts/create-go-account-advanced.ts` + +Provides manual control over keychain creation and wallet setup using SDK methods. + +**Best for:** +- Advanced users needing custom key management +- Integration with custom key storage systems +- Understanding the internals of Go Account creation +- Testing and debugging + +**Example:** +```typescript +// Step 1: Create keychain locally +const keychain = bitgo.coin('ofc').keychains().create(); + +// Step 2: Encrypt private key +const encryptedPrv = bitgo.encrypt({ + password: passphrase, + input: keychain.prv +}); + +// Step 3: Add keychain to BitGo +const addedKeychain = await bitgo.coin('ofc').keychains().add({ + pub: keychain.pub, + encryptedPrv: encryptedPrv, + originalPasscodeEncryptionCode: passcodeEncryptionCode, + keyType: 'independent', + source: 'user', + enterprise: enterpriseId, +}); + +// Step 4: Create wallet +const walletResponse = await bitgo.coin('ofc').wallets().add({ + label: 'My Go Account', + m: 1, + n: 1, + keys: [addedKeychain.id], + type: 'trading', + enterprise: enterpriseId, +}); +``` + +## Complete Workflow + +Both examples demonstrate the complete Go Account creation flow: + +### 1. Create Wallet +```typescript +// SDK generates keychain and wallet in one call +const response = await bitgo.coin('ofc').wallets().generateWallet({...}); +``` + +### 2. Wait for Initialization +Go Accounts require system initialization, which may take a few seconds: + +```typescript +async function waitForWalletInitialization(wallet, maxRetries = 30, delayMs = 2000) { + for (let attempt = 1; attempt <= maxRetries; attempt++) { + const walletData = await bitgo.coin('ofc').wallets().get({ id: wallet.id() }); + const coinSpecific = walletData._wallet.coinSpecific; + + if (!coinSpecific.pendingSystemInitialization) { + return; // Wallet ready + } + + await sleep(delayMs); + } +} +``` + +### 3. Create Addresses +**IMPORTANT:** For Go Account (OFC) wallets, the `onToken` parameter is **always required** when creating addresses. There is no "default" address - every address must be associated with a specific token. + +```typescript +// Create a token-specific address (onToken is mandatory) +const tokenAddress = await wallet.createAddress({ + label: 'USDC Address', + onToken: 'ofctsol:usdc' // Required for OFC wallets +}); + +// Create addresses for different tokens +const usdtAddress = await wallet.createAddress({ + label: 'USDT Address', + onToken: 'ofcttrx:usdt' +}); +``` + +## Key Differences from Express Approach + +| Aspect | Express | Direct SDK | +|--------|---------|------------| +| **Server Required** | Yes (Express server) | No | +| **API Calls** | HTTP to Express → Express to BitGo | Direct SDK → BitGo | +| **Setup** | More complex (server + SDK) | Simple (SDK only) | +| **Security** | Keys never leave Express server | Keys managed in your application | +| **Performance** | Extra network hop | Direct communication | +| **Use Case** | Shared signing server | Embedded integration | + +## Security Best Practices + +1. **Backup Critical Information:** + - Encrypted private key (`userKeychain.encryptedPrv`) + - Keychain ID (`userKeychain.id`) + - Encrypted wallet passphrase (`encryptedWalletPassphrase`) + - Passphrase encryption code (stored separately) + +2. **Secure Storage:** + - Store encrypted keys in secure database + - Never log unencrypted private keys + - Use environment variables for sensitive config + +3. **Access Control:** + - Limit access token permissions + - Use enterprise-scoped tokens + - Implement proper authentication + +## Running the Examples + +1. Install dependencies: + ```bash + cd /path/to/BitGoJS + yarn install + ``` + +2. Set up environment: + ```bash + cp examples/.env.example examples/.env + # Edit .env with your access token and enterprise ID + ``` + +3. Update script configuration: + - Set your `enterprise` ID + - Choose wallet `label` and `passphrase` + - Optional: Set `token` for specific crypto assets + +4. Run the script: + ```bash + cd examples/ts + npx tsx create-go-account.ts + # or for advanced approach: + npx tsx create-go-account-advanced.ts + ``` + +## Supported Tokens + +Common tokens for Go Accounts (use with `onToken` parameter): + +### Testnet Tokens +Stablecoins: +- `ofctsol:usdc` - USD Coin on Solana testnet +- `ofctsol:usdt` - USD Tether on Solana testnet +- `ofcttrx:usdt` - USDT on Tron testnet + +Native/Wrapped Tokens: +- `ofcbtc` - Bitcoin +- `ofceth` - Ethereum +- `ofctsol:wsol` - Wrapped SOL on Solana testnet +- `ofctsol:ray` - Raydium on Solana testnet +- `ofctsol:srm` - Serum on Solana testnet + +### Mainnet Tokens (use when `env: 'production'`) +Stablecoins: +- `ofcsol:usdc` - USD Coin on Solana +- `ofcsol:usdt` - USD Tether on Solana +- `ofcpolygon:usdc` - USD Coin on Polygon +- `ofcarbeth:usdc` - USD Coin on Arbitrum +- `ofcbsc:usdc` - USD Coin on BSC + +Native/Wrapped Tokens: +- `ofcbtc` - Bitcoin +- `ofceth` - Ethereum +- `ofcsol:wsol` - Wrapped SOL on Solana +- `ofcpolygon:matic` - MATIC on Polygon + +**Note:** Token names use the format `ofc[network]:[token]` (e.g., `ofcsol:usdc`) for chain-specific tokens, or just `ofc[coin]` (e.g., `ofcbtc`) for native coins. + +## Troubleshooting + +### Wallet initialization timeout +**Issue:** Wallet stuck in `pendingSystemInitialization` + +**Solution:** Increase the retry count and delay in `waitForWalletInitialization()`. + +### Token address creation fails +**Issue:** Error "onToken is a mandatory parameter for OFC wallets" + +**Solution:** Always include the `onToken` parameter when creating addresses for Go Account wallets. There is no default address - every address must specify a token. + +**Issue:** Error "Coin unsupported: [token]" + +**Solution:** +- Verify the token name format is correct (e.g., `ofctsol:usdc` for testnet, `ofcsol:usdc` for mainnet) +- Check that the token is enabled for your enterprise +- Ensure you're using testnet tokens (`ofct...`) with `env: 'test'` and mainnet tokens (`ofc...`) with `env: 'production'` + +## Additional Resources + +- [BitGo API Documentation](https://developers.bitgo.com/) +- [Go Accounts Overview](https://developers.bitgo.com/docs/crypto-as-a-service-go-accounts) +- [SDK Reference](https://github.com/BitGo/BitGoJS) + +## Support + +For questions or issues: +1. Check the [BitGo Developer Documentation](https://developers.bitgo.com/) +2. Open an issue on [GitHub](https://github.com/BitGo/BitGoJS/issues) +3. Contact BitGo support diff --git a/examples/ts/create-go-account-advanced.ts b/examples/ts/create-go-account-advanced.ts new file mode 100644 index 0000000000..fb3f1165bb --- /dev/null +++ b/examples/ts/create-go-account-advanced.ts @@ -0,0 +1,310 @@ +/** + * Advanced Go Account Creation Example (Low-Level SDK Approach) + * + * This script demonstrates how to create a Go Account with manual control over + * keychain creation and wallet setup. This approach gives you fine-grained control + * over the wallet creation process and is useful for: + * - Advanced users who need custom key management + * - Understanding the internals of Go Account creation + * - Integrating with custom key management systems + * + * For most use cases, prefer the simpler approach in create-go-account.ts + * + * This example does NOT use BitGo Express - all operations use the SDK directly + * against the BitGo platform APIs. + * + * IMPORTANT: You must backup the encrypted private key and encrypted wallet passphrase! + * + * Copyright 2025, BitGo, Inc. All Rights Reserved. + */ + +import { BitGoAPI } from '@bitgo/sdk-api'; +import { Wallet } from '@bitgo/sdk-core'; +import { coins } from 'bitgo'; +require('dotenv').config({ path: '../../.env' }); + +// Initialize BitGo SDK +const bitgo = new BitGoAPI({ + accessToken: process.env.TESTNET_ACCESS_TOKEN, + env: 'test', // Change this to env: 'production' when you are ready for production +}); + +// Go Accounts use the 'ofc' (Off-Chain) coin +const coin = 'ofc'; +bitgo.register(coin, coins.Ofc.createInstance); + +// Configuration - Update these values +const label = 'Go Account Wallet'; +const passphrase = 'go_account_wallet_passphrase'; +const passcodeEncryptionCode = 'encryption_code_for_passphrase'; +const enterprise = 'your_enterprise_id'; + +// Token to create address for (required for OFC wallets) +// Examples: 'ofctsol:usdc', 'ofctsol:usdt', 'ofcttrx:usdt', 'ofcbtc', 'ofceth' +const token = 'ofctsol'; + +/** + * Helper function to sleep for a specified duration + */ +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +/** + * Step 1: Create a keychain locally + * This generates a public/private key pair on the client side + */ +async function createKeychain() { + console.log('Creating keychain locally...'); + const ofcCoin = bitgo.coin(coin); + const keychain = ofcCoin.keychains().create(); + + console.log(`✓ Keychain created`); + console.log(` Public Key: ${keychain.pub}`); + console.log(` Private Key (unencrypted): ${keychain.prv?.substring(0, 20)}...`); + console.log('\nKeychain Response:'); + console.log(JSON.stringify({ + pub: keychain.pub, + prv: keychain.prv ? `${keychain.prv.substring(0, 20)}... (truncated for security)` : undefined, + }, null, 2)); + + return keychain; +} + +/** + * Step 2: Encrypt the private key with the wallet passphrase + * This protects the private key before sending it to BitGo + */ +function encryptPrivateKey(privateKey: string, password: string): string { + console.log('Encrypting private key...'); + const encrypted = bitgo.encrypt({ + password, + input: privateKey + }); + console.log(`✓ Private key encrypted`); + console.log('\nEncrypted Private Key (preview):'); + console.log(encrypted.substring(0, 100) + '...'); + return encrypted; +} + +/** + * Step 3: Add the keychain to BitGo + * This registers the key with BitGo and associates it with your enterprise + */ +async function addKeychain( + publicKey: string, + encryptedPrivateKey: string, + enterpriseId: string, + passcodeEncryptionCode: string +) { + console.log('Adding keychain to BitGo...'); + const ofcCoin = bitgo.coin(coin); + + const keychainParams = { + pub: publicKey, + encryptedPrv: encryptedPrivateKey, + originalPasscodeEncryptionCode: passcodeEncryptionCode, + keyType: 'independent' as const, + source: 'user' as const, + enterprise: enterpriseId, + }; + + const addedKeychain = await ofcCoin.keychains().add(keychainParams); + console.log(`✓ Keychain added to BitGo`); + console.log(` Keychain ID: ${addedKeychain.id}`); + console.log('\nAdd Keychain Response:'); + console.log(JSON.stringify(addedKeychain, null, 2)); + + return addedKeychain; +} + +/** + * Step 4: Create the Go Account wallet + * This creates a 1-of-1 trading wallet using the keychain + */ +async function createGoAccountWallet( + keychainId: string, + walletLabel: string, + enterpriseId: string +) { + console.log('Creating Go Account wallet...'); + const ofcCoin = bitgo.coin(coin); + + const walletParams = { + label: walletLabel, + m: 1, // 1-of-1 signature required + n: 1, // 1 total key + keys: [keychainId], + type: 'trading' as const, // Required for Go Accounts + enterprise: enterpriseId, + tags: [] as string[], + }; + + const walletResponse = await ofcCoin.wallets().add(walletParams); + const wallet = walletResponse.wallet; + + console.log(`✓ Go Account wallet created`); + console.log(` Wallet ID: ${wallet.id()}`); + console.log(` Wallet Label: ${walletLabel}`); + console.log('\nWallet Response:'); + console.log(JSON.stringify(walletResponse, null, 2)); + + return wallet; +} + +/** + * Step 5: Wait for wallet initialization to complete + * Go Accounts require system initialization which can take a few seconds + */ +async function waitForWalletInitialization( + walletId: string, + maxRetries = 30, + delayMs = 2000 +): Promise { + console.log('Waiting for wallet initialization...'); + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const walletData = await bitgo.coin(coin).wallets().get({ id: walletId }); + const coinSpecific = walletData._wallet.coinSpecific as { pendingSystemInitialization?: boolean }; + const pendingInitialization = coinSpecific?.pendingSystemInitialization; + + console.log(` Attempt ${attempt}/${maxRetries}: Pending = ${pendingInitialization}`); + + if (!pendingInitialization) { + console.log('✓ Wallet initialization complete!'); + return; + } + + await sleep(delayMs); + } catch (error) { + console.error(` Error checking wallet status: ${error}`); + throw error; + } + } + + throw new Error('Wallet initialization timeout'); +} + +/** + * Step 6: Create a receive address for the wallet + * Note: onToken is REQUIRED for OFC (Go Account) wallets + */ +async function createReceiveAddress( + wallet: Wallet, + addressLabel: string, + onToken: string +) { + console.log(`Creating address for token ${onToken}...`); + + const addressParams = { + label: addressLabel, + onToken: onToken + }; + + const address = await wallet.createAddress(addressParams); + console.log(`✓ Address created: ${address.address}`); + console.log('\nAddress Response:'); + console.log(JSON.stringify(address, null, 2)); + + return address; +} + +/** + * Main function - orchestrates the complete Go Account creation flow + */ +async function main() { + try { + console.log('=== Advanced Go Account Creation ===\n'); + console.log('This example shows manual control over keychain and wallet creation.\n'); + + // Step 1: Create keychain locally + console.log('Step 1: Generate Keychain'); + console.log('-'.repeat(50)); + const keychain = await createKeychain(); + if (!keychain.prv) { + throw new Error('Failed to generate private key'); + } + console.log(); + + // Step 2: Encrypt the private key + console.log('Step 2: Encrypt Private Key'); + console.log('-'.repeat(50)); + const encryptedPrivateKey = encryptPrivateKey(keychain.prv, passphrase); + console.log(); + + // Step 3: Add keychain to BitGo + console.log('Step 3: Register Keychain with BitGo'); + console.log('-'.repeat(50)); + const addedKeychain = await addKeychain( + keychain.pub as string, + encryptedPrivateKey, + enterprise, + passcodeEncryptionCode + ); + console.log(); + + // Step 4: Create the wallet + console.log('Step 4: Create Go Account Wallet'); + console.log('-'.repeat(50)); + const wallet = await createGoAccountWallet( + addedKeychain.id!, + label, + enterprise + ); + console.log(); + + // Step 5: Wait for initialization + console.log('Step 5: Wait for System Initialization'); + console.log('-'.repeat(50)); + await waitForWalletInitialization(wallet.id()); + console.log(); + + // Step 6: Create token-specific address (required for OFC wallets) + console.log(`Step 6: Create Token Address (${token})`); + console.log('-'.repeat(50)); + try { + await createReceiveAddress(wallet, `${token} Address`, token); + } catch (error) { + console.log(` Error: Token address creation failed. Token may not be enabled.`); + console.error(` Error: ${error}`); + throw error; + } + console.log(); + + // Display backup information + console.log('='.repeat(60)); + console.log('BACKUP THE FOLLOWING INFORMATION'); + console.log('='.repeat(60)); + console.log('\nWallet Information:'); + console.log(` Wallet ID: ${wallet.id()}`); + console.log(` Label: ${label}`); + console.log('\nKeychain Information:'); + console.log(` Keychain ID: ${addedKeychain.id}`); + console.log(` Public Key: ${addedKeychain.pub}`); + console.log(` Encrypted Private Key: ${addedKeychain.encryptedPrv}`); + console.log('\nPassphrase Information:'); + console.log(` Encrypted Wallet Passphrase: ${bitgo.encrypt({ + password: passcodeEncryptionCode, + input: passphrase + })}`); + console.log('\n' + '='.repeat(60)); + + console.log('\n✓ Go Account setup complete!'); + + console.log('Next Steps:'); + console.log('1. Securely backup all keychain and passphrase information'); + console.log('2. Retrieve wallet: bitgo.coin("ofc").wallets().get({ id: "' + wallet.id() + '" })'); + console.log('3. Create additional addresses: wallet.createAddress({ label: "...", onToken: "..." })'); + console.log('4. Fund the wallet and start trading!'); + + } catch (error) { + console.error('\n❌ Error creating Go Account:', error); + process.exit(1); + } +} + +main().catch((e) => { + console.error('\n❌ Error creating Go Account:', e); + process.exit(1); +}); diff --git a/examples/ts/create-go-account.ts b/examples/ts/create-go-account.ts index 072c0e11d5..29dfdc761e 100644 --- a/examples/ts/create-go-account.ts +++ b/examples/ts/create-go-account.ts @@ -1,6 +1,13 @@ /** - * Create a Go Account wallet at BitGo. - * This makes use of the convenience function generateWallet with type: 'trading' + * Create a Go Account wallet at BitGo (SDK Approach) + * + * This example demonstrates creating a Go Account using the BitGo SDK's high-level + * generateWallet() method. This is the recommended approach for most use cases. + * + * This does NOT use BitGo Express - it communicates directly with BitGo platform APIs. + * Express is optional middleware; this example shows you can work directly with the SDK. + * + * For advanced users who need manual keychain control, see create-go-account-advanced.ts * * IMPORTANT: You must backup the encrypted private key and encrypted wallet passphrase! * @@ -11,6 +18,7 @@ import { BitGoAPI } from '@bitgo/sdk-api'; import { coins } from 'bitgo'; require('dotenv').config({ path: '../../.env' }); +// Initialize BitGo SDK const bitgo = new BitGoAPI({ accessToken: process.env.TESTNET_ACCESS_TOKEN, env: 'test', // Change this to env: 'production' when you are ready for production @@ -20,19 +28,49 @@ const bitgo = new BitGoAPI({ const coin = 'ofc'; bitgo.register(coin, coins.Ofc.createInstance); -// TODO: set a label for your new Go Account here -const label = 'Example Go Account Wallet'; - -// TODO: set your passphrase for your new wallet here (encrypts the private key) +// Configuration - Update these values +const label = 'Go Account Wallet'; const passphrase = 'go_account_wallet_passphrase'; - -// TODO: set your passcode encryption code here (encrypts the passphrase itself) const passcodeEncryptionCode = 'encryption_code_for_passphrase'; - -// TODO: set your enterprise ID for your new wallet here const enterprise = 'your_enterprise_id'; +// Token to create address for (required for OFC wallets) +// Examples: 'ofctsol:usdc', 'ofctsol:usdt', 'ofcttrx:usdt', 'ofcbtc', 'ofceth' +const token = 'ofctsol'; + +/** + * Helper function to wait for wallet initialization + * Go Accounts require system initialization which can take a few seconds + */ +async function waitForWalletInitialization( + walletId: string, + maxRetries = 30, + delayMs = 2000 +): Promise { + console.log('Waiting for wallet initialization...'); + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + const walletData = await bitgo.coin(coin).wallets().get({ id: walletId }); + const coinSpecific = walletData._wallet.coinSpecific as { pendingSystemInitialization?: boolean }; + const pendingInitialization = coinSpecific?.pendingSystemInitialization; + + if (!pendingInitialization) { + console.log('✓ Wallet initialization complete!'); + return; + } + + console.log(` Waiting... (${attempt}/${maxRetries})`); + await new Promise(resolve => setTimeout(resolve, delayMs)); + } + + throw new Error('Wallet initialization timeout'); +} + async function main() { + console.log('=== Creating Go Account (SDK Approach) ===\n'); + + // Step 1: Generate the Go Account wallet (handles keychain creation internally) + console.log('Generating Go Account wallet...'); const response = await bitgo.coin(coin).wallets().generateWallet({ label, passphrase, @@ -48,20 +86,56 @@ async function main() { const { wallet, userKeychain, encryptedWalletPassphrase } = response; + console.log(`\n✓ Wallet created successfully!`); console.log(`Wallet ID: ${wallet.id()}`); + console.log('\nWallet Response:'); + console.log(JSON.stringify(response, null, 2)); + + // Step 2: Wait for wallet initialization + await waitForWalletInitialization(wallet.id()); + + // Step 3: Create token-specific address (required for OFC wallets) + console.log(`\nCreating address for token ${token}...`); + try { + const tokenAddress = await wallet.createAddress({ + label: `${token} Address`, + onToken: token + }); + console.log(`✓ Address created: ${tokenAddress.address}`); + console.log('\nAddress Response:'); + console.log(JSON.stringify(tokenAddress, null, 2)); + } catch (error) { + console.log(` Error: Token address creation failed. Token may not be enabled.`); + console.error(` Error: ${error}`); + throw error; + } - console.log('BACKUP THE FOLLOWING INFORMATION: '); - console.log('User Keychain:'); - console.log(`Keychain ID: ${userKeychain.id}`); - console.log(`Public Key: ${userKeychain.pub}`); - console.log(`Encrypted Private Key: ${userKeychain.encryptedPrv}`); - - console.log(`Encrypted Wallet Passphrase: ${encryptedWalletPassphrase}`); - - // Create receive address for Go Account - const receiveAddress = await wallet.createAddress(); - console.log('Go Account Receive Address:', receiveAddress.address); + // Display backup information + console.log('\n' + '='.repeat(60)); + console.log('BACKUP THE FOLLOWING INFORMATION'); + console.log('='.repeat(60)); + console.log('\nWallet Information:'); + console.log(` Wallet ID: ${wallet.id()}`); + console.log(` Label: ${label}`); + console.log('\nKeychain Information:'); + console.log(` Keychain ID: ${userKeychain.id}`); + console.log(` Public Key: ${userKeychain.pub}`); + console.log(` Encrypted Private Key: ${userKeychain.encryptedPrv}`); + console.log('\nPassphrase Information:'); + console.log(` Encrypted Wallet Passphrase: ${encryptedWalletPassphrase}`); + console.log('\n' + '='.repeat(60)); + + console.log('\n✓ Go Account setup complete!'); + + console.log('\nNext Steps:'); + console.log('1. Securely backup all keychain and passphrase information'); + console.log('2. Retrieve wallet: bitgo.coin("ofc").wallets().get({ id: "' + wallet.id() + '" })'); + console.log('3. Create additional addresses: wallet.createAddress({ label: "...", onToken: "..." })'); + console.log('4. Fund the wallet and start trading!'); } -main().catch((e) => console.error('Error creating Go Account:', e)); +main().catch((e) => { + console.error('\n❌ Error creating Go Account:', e); + process.exit(1); +});