From 4a66621dde7069e9959223cbc705d89c2774bf1a Mon Sep 17 00:00:00 2001 From: Pranav Jain Date: Mon, 21 Jul 2025 16:12:56 -0400 Subject: [PATCH 1/3] chore(aw): rename "enclave" to "secure express" The word enclave isnt valid to use here since we cannot make provider-agnostic KMS API calls from an actual enclave. Moving to "secure" bitgo express. Ticket: WP-5298 --- .commitlintrc.json | 2 +- .gitignore | 3 +- CLAUDE.md | 43 +++++--- Dockerfile | 2 +- README.md | 79 +++++++------- ...ed-bitgo-express => secured-bitgo-express} | 0 masterBitgoExpress.json | 10 +- nodemon.json | 2 +- package.json | 6 +- src/__tests__/api/master/accelerate.test.ts | 8 +- src/__tests__/api/master/consolidate.test.ts | 6 +- .../api/master/consolidateUnspents.test.ts | 6 +- src/__tests__/api/master/ecdsa.test.ts | 26 ++--- src/__tests__/api/master/eddsa.test.ts | 26 ++--- .../api/master/generateWallet.test.ts | 61 +++++------ .../api/master/musigRecovery.test.ts | 8 +- .../recoveryConsolidationsWallet.test.ts | 16 +-- .../api/master/recoveryWallet.test.ts | 34 +++--- src/__tests__/api/master/sendMany.test.ts | 31 +++--- .../api/master/signAndSendTxRequest.test.ts | 6 +- .../api/{enclaved => secured}/ecdsaUtils.ts | 0 .../postIndependentKey.test.ts | 10 +- .../postMpcV2Key.test.ts | 10 +- .../recoveryMultisigTransaction.test.ts | 14 +-- .../recoveryMusigEth.test.ts | 16 +-- .../signMpcRecoveryTransaction.test.ts | 10 +- .../signMpcTransaction.test.ts | 10 +- .../signMultisigTransaction.test.ts | 10 +- src/__tests__/config.test.ts | 36 +++---- .../mocks/ethRecoveryMusigMockData.ts | 2 +- src/__tests__/routes.test.ts | 10 +- ...pressClient.ts => securedExpressClient.ts} | 50 ++++----- src/api/master/handlerUtils.ts | 10 +- src/api/master/handlers/ecdsaMPCv2.ts | 49 ++++----- src/api/master/handlers/eddsa.ts | 28 ++--- src/api/master/handlers/generateWallet.ts | 20 ++-- src/api/master/handlers/handleAccelerate.ts | 4 +- src/api/master/handlers/handleConsolidate.ts | 6 +- .../handlers/handleConsolidateUnspents.ts | 4 +- src/api/master/handlers/handleSendMany.ts | 20 ++-- .../handlers/handleSignAndSendTxRequest.ts | 4 +- .../handlers/recoveryConsolidationsWallet.ts | 6 +- src/api/master/handlers/recoveryWallet.ts | 28 ++--- .../master/handlers/transactionRequests.ts | 10 +- src/api/master/middleware/middleware.ts | 16 +-- src/api/master/routers/index.ts | 4 +- ...pressHealth.ts => securedExpressHealth.ts} | 65 ++++++------ .../handlers/ecdsaMPCv2Finalize.ts | 6 +- .../handlers/ecdsaMPCv2Initialize.ts | 6 +- .../handlers/ecdsaMPCv2Round.ts | 6 +- .../handlers/postIndependentKey.ts | 4 +- .../handlers/recoveryMultisigTransaction.ts | 4 +- .../handlers/signEddsaRecoveryTransaction.ts | 4 +- .../handlers/signMpcTransaction.ts | 12 ++- .../handlers/signMultisigTransaction.ts | 4 +- src/api/{enclaved => secured}/mpcFinalize.ts | 8 +- .../{enclaved => secured}/mpcInitialize.ts | 8 +- src/api/{enclaved => secured}/utils.ts | 8 +- src/app.ts | 10 +- src/enclavedBitgoExpress/routers/index.ts | 8 -- src/errors.ts | 12 +-- src/initConfig.ts | 100 +++++++++--------- src/kms/kmsClient.ts | 6 +- src/routes/enclaved.ts | 27 ----- src/routes/master.ts | 8 +- src/routes/secured.ts | 27 +++++ src/routes/utils.ts | 2 +- .../routers/healthCheck.ts | 2 +- src/securedBitgoExpress/routers/index.ts | 8 ++ .../routers/securedExpressApiSpec.ts} | 89 ++++++++-------- src/{enclavedApp.ts => securedExpressApp.ts} | 24 ++--- src/shared/appUtils.ts | 12 +-- src/shared/responseHandler.ts | 6 +- src/shared/types/index.ts | 20 ++-- src/types/request.ts | 4 +- 75 files changed, 642 insertions(+), 620 deletions(-) rename bin/{enclaved-bitgo-express => secured-bitgo-express} (100%) rename src/__tests__/api/{enclaved => secured}/ecdsaUtils.ts (100%) rename src/__tests__/api/{enclaved => secured}/postIndependentKey.test.ts (89%) rename src/__tests__/api/{enclaved => secured}/postMpcV2Key.test.ts (98%) rename src/__tests__/api/{enclaved => secured}/recoveryMultisigTransaction.test.ts (92%) rename src/__tests__/api/{enclaved => secured}/recoveryMusigEth.test.ts (90%) rename src/__tests__/api/{enclaved => secured}/signMpcRecoveryTransaction.test.ts (96%) rename src/__tests__/api/{enclaved => secured}/signMpcTransaction.test.ts (98%) rename src/__tests__/api/{enclaved => secured}/signMultisigTransaction.test.ts (93%) rename src/api/master/clients/{enclavedExpressClient.ts => securedExpressClient.ts} (93%) rename src/api/master/routers/{enclavedExpressHealth.ts => securedExpressHealth.ts} (51%) rename src/api/{enclaved => secured}/handlers/ecdsaMPCv2Finalize.ts (93%) rename src/api/{enclaved => secured}/handlers/ecdsaMPCv2Initialize.ts (88%) rename src/api/{enclaved => secured}/handlers/ecdsaMPCv2Round.ts (97%) rename src/api/{enclaved => secured}/handlers/postIndependentKey.ts (83%) rename src/api/{enclaved => secured}/handlers/recoveryMultisigTransaction.ts (97%) rename src/api/{enclaved => secured}/handlers/signEddsaRecoveryTransaction.ts (97%) rename src/api/{enclaved => secured}/handlers/signMpcTransaction.ts (96%) rename src/api/{enclaved => secured}/handlers/signMultisigTransaction.ts (87%) rename src/api/{enclaved => secured}/mpcFinalize.ts (95%) rename src/api/{enclaved => secured}/mpcInitialize.ts (94%) rename src/api/{enclaved => secured}/utils.ts (95%) delete mode 100644 src/enclavedBitgoExpress/routers/index.ts delete mode 100644 src/routes/enclaved.ts create mode 100644 src/routes/secured.ts rename src/{enclavedBitgoExpress => securedBitgoExpress}/routers/healthCheck.ts (97%) create mode 100644 src/securedBitgoExpress/routers/index.ts rename src/{enclavedBitgoExpress/routers/enclavedApiSpec.ts => securedBitgoExpress/routers/securedExpressApiSpec.ts} (82%) rename src/{enclavedApp.ts => securedExpressApp.ts} (82%) diff --git a/.commitlintrc.json b/.commitlintrc.json index e440d2d..ebcd589 100644 --- a/.commitlintrc.json +++ b/.commitlintrc.json @@ -5,7 +5,7 @@ "header-max-length": [2, "always", 72], "references-empty": [1, "never"], "subject-case": [0], - "scope-enum": [2, "always", ["mbe", "ebe", "docker"]], + "scope-enum": [2, "always", ["mbe", "sbe", "docker"]], "scope-empty": [0, "never"] }, "parserPreset": { diff --git a/.gitignore b/.gitignore index 28299ed..96f110f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ logs/ tsconfig.tsbuildinfo out/ .vscode/ -*.iml \ No newline at end of file +*.iml +.nyc_output/ \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 08fb130..30e76ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,25 +5,29 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Commands ### Development + - `yarn start` - Start the application in development mode using nodemon for auto-reloading - `yarn build` - Build the TypeScript code (creates /dist folder) - `yarn lint` - Run ESLint to check for code issues - `yarn lint:fix` - Run ESLint and automatically fix issues when possible ### Testing + - `yarn test` - Run all tests - `yarn test:watch` - Run tests in watch mode - `yarn test:coverage` - Run tests with coverage report - `yarn generate-test-ssl` - Generate self-signed SSL certificates for testing ### Container + - `yarn container:build` - Build the container image using Podman (optionally use --build-arg PORT=3080) ## Architecture Overview -Enclaved BitGo Express is a secure cryptocurrency signing server with two operational modes: +Secured BitGo Express is a secure cryptocurrency signing server with two operational modes: + +### 1. Secured Express Mode (`APP_MODE=secured`) -### 1. Enclaved Express Mode (`APP_MODE=enclaved`) - Lightweight server focused solely on secure signing operations - Runs on port 3080 by default - Integrates with KMS for key management @@ -31,20 +35,22 @@ Enclaved BitGo Express is a secure cryptocurrency signing server with two operat - Exposes minimal endpoints focused on key generation and signing ### 2. Master Express Mode (`APP_MODE=master-express`) + - Full BitGo API functionality with integrated signing capabilities - Runs on port 3081 by default -- Acts as an API gateway and communicates with Enclaved Express for signing operations +- Acts as an API gateway and communicates with Secured Express for signing operations - Provides a broader set of BitGo wallet operations and transaction handling ### Security Architecture + - Both modes support mutual TLS (mTLS) authentication - Certificates can be loaded from files or environment variables - Client certificate validation for secure communications - Option to validate client certificate fingerprints ### Code Structure -- `src/app.ts` - Main entry point that determines mode and starts the appropriate app -- `src/enclavedApp.ts` - Enclaved Express mode implementation + +- `src/securedApp.ts` - Secured Express mode implementation - `src/masterExpressApp.ts` - Master Express mode implementation - `src/initConfig.ts` - Configuration loading and validation - `src/routes/` - Express routes for both modes @@ -53,27 +59,32 @@ Enclaved BitGo Express is a secure cryptocurrency signing server with two operat - `src/shared/` - Shared utilities and types ### Configuration + Configuration is managed through environment variables with defaults defined in `src/initConfig.ts`. The application requires specific environment variables depending on the mode: #### Common Variables -- `APP_MODE` - Set to "enclaved" or "master-express" + +- `APP_MODE` - Set to "secured" or "master-express" - `TLS_MODE` - Set to "mtls" or "disabled" - `BIND` - Address to bind to (default: localhost) - `TIMEOUT` - Request timeout in milliseconds (default: 305000) -#### Enclaved Mode Specific -- `ENCLAVED_EXPRESS_PORT` - Port to listen on (default: 3080) +#### Secured Mode Specific + +- `SECURED_EXPRESS_PORT` - Port to listen on (default: 3080) - `KMS_URL` - Required KMS service URL #### Master Express Mode Specific + - `MASTER_EXPRESS_PORT` - Port to listen on (default: 3081) - `BITGO_ENV` - BitGo environment (default: test) -- `ENCLAVED_EXPRESS_URL` - Required URL for the Enclaved Express server -- `ENCLAVED_EXPRESS_CERT` - Required path to Enclaved Express certificate +- `SECURED_EXPRESS_URL` - Required URL for the Secured Express server +- `SECURED_EXPRESS_CERT` - Required path to Secured Express certificate ## API Endpoints -### Enclaved Express (Port 3080) +### Secured Express (Port 3080) + - `POST /ping` - Health check - `GET /version` - Version information - `POST /:coin/key/independent` - Generate independent keychain @@ -81,19 +92,23 @@ Configuration is managed through environment variables with defaults defined in ### Master Express (Port 3081) #### Health and Status Endpoints + - `POST /ping` - Health check - `GET /version` - Version information -- `POST /ping/enclavedExpress` - Test connection to Enclaved Express -- `GET /version/enclavedExpress` - Get Enclaved Express version information +- `POST /ping/securedExpress` - Test connection to Secured Express +- `GET /version/securedExpress` - Get Secured Express version information #### Wallet Management + - `POST /api/:coin/wallet/generate` - Generate wallet (supports onchain and TSS multisig types) #### Transaction Operations + - `POST /api/:coin/wallet/:walletId/sendMany` - Send transaction with multiple recipients - `POST /api/:coin/wallet/:walletId/accelerate` - Accelerate pending transactions (CPFP/RBF) - `POST /api/:coin/wallet/:walletId/consolidate` - Consolidate wallet addresses - `POST /api/:coin/wallet/:walletId/consolidateunspents` - Consolidate unspent transaction outputs #### Recovery -- `POST /api/:coin/wallet/recovery` - Recover wallet funds \ No newline at end of file + +- `POST /api/:coin/wallet/recovery` - Recover wallet funds diff --git a/Dockerfile b/Dockerfile index 7b52c9a..43bc38b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -91,4 +91,4 @@ USER bitgo EXPOSE ${PORT} # Start the application using the binary -CMD ["./bin/enclaved-bitgo-express"] \ No newline at end of file +CMD ["./bin/secured-bitgo-express"] \ No newline at end of file diff --git a/README.md b/README.md index dca8a9c..ff5ff0a 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ -# Enclaved BitGo Express +# Secured BitGo Express -A secure, mTLS-enabled cryptocurrency signing server with two operational modes: Enclaved Express (dedicated signer) and Master Express (API gateway with integrated signing capabilities). +A secure, mTLS-enabled cryptocurrency signing server with two operational modes: Secured Express (dedicated signer) and Master Express (API gateway with integrated signing capabilities). ## Overview This application provides secure cryptocurrency operations with mutual TLS (mTLS) authentication: -- **Enclaved Mode**: Lightweight signing server for secure key operations +- **Secured Mode**: Lightweight signing server for secure key operations - **Master Express Mode**: Full BitGo Express functionality with integrated signing - **mTLS Security**: Client certificate validation for secure communications - **Flexible Configuration**: Environment-based setup with file or variable-based certificates ## Architecture -- **Enclaved Express** (Port 3080): Focused signing operations with KMS integration -- **Master Express** (Port 3081): Full BitGo API functionality with secure communication to Enclaved Express +- **Secured Express** (Port 3080): Focused signing operations with KMS integration +- **Master Express** (Port 3081): Full BitGo API functionality with secure communication to Secured Express ## Configuration @@ -22,7 +22,7 @@ Configuration is managed through environment variables: ### Required Settings -- `APP_MODE` - Application mode (required: "enclaved" or "master-express") +- `APP_MODE` - Application mode (required: "secured" or "master-express") ### Network Settings @@ -31,9 +31,9 @@ Configuration is managed through environment variables: - `KEEP_ALIVE_TIMEOUT` - Keep-alive timeout (optional) - `HEADERS_TIMEOUT` - Headers timeout (optional) -#### Enclaved Mode Specific +#### Secured Mode Specific -- `ENCLAVED_EXPRESS_PORT` - Port to listen on (default: 3080) +- `SECURED_EXPRESS_PORT` - Port to listen on (default: 3080) - `KMS_URL` - KMS service URL (required) #### Master Express Mode Specific @@ -44,8 +44,8 @@ Configuration is managed through environment variables: - `BITGO_AUTH_VERSION` - Authentication version (default: 2) - `BITGO_CUSTOM_ROOT_URI` - Custom BitGo API root URI (optional) - `BITGO_CUSTOM_BITCOIN_NETWORK` - Custom Bitcoin network (optional) -- `ENCLAVED_EXPRESS_URL` - Enclaved Express server URL (required) -- `ENCLAVED_EXPRESS_CERT` - Path to Enclaved Express server certificate (required) +- `SECURED_EXPRESS_URL` - Secured Express server URL (required) +- `SECURED_EXPRESS_CERT` - Path to Secured Express server certificate (required) ### TLS/mTLS Configuration @@ -76,7 +76,7 @@ Both modes use the same TLS configuration variables: ### Logging and Debug - `LOGFILE` - Path to log file (optional) -- `DEBUG_NAMESPACE` - Debug namespaces to enable (e.g., 'enclaved:\*') +- `DEBUG_NAMESPACE` - Debug namespaces to enable (e.g., 'secured:\*') ## Quick Start @@ -92,10 +92,10 @@ openssl genrsa -out server.key 2048 openssl req -new -x509 -key server.key -out server.crt -days 365 -subj "/CN=localhost" ``` -### 2. Start Enclaved Express +### 2. Start Secured Express ```bash -APP_MODE=enclaved \ +APP_MODE=secured \ KMS_URL=https://your-kms-service \ TLS_KEY_PATH=./server.key \ TLS_CERT_PATH=./server.crt \ @@ -113,8 +113,8 @@ APP_MODE=master-express \ BITGO_ENV=test \ TLS_KEY_PATH=./server.key \ TLS_CERT_PATH=./server.crt \ -ENCLAVED_EXPRESS_URL=https://localhost:3080 \ -ENCLAVED_EXPRESS_CERT=./server.crt \ +SECURED_EXPRESS_URL=https://localhost:3080 \ +SECURED_EXPRESS_CERT=./server.crt \ MTLS_REQUEST_CERT=false \ ALLOW_SELF_SIGNED=true \ yarn start @@ -122,10 +122,10 @@ yarn start ### 4. Test the Connection -Test that Master Express can communicate with Enclaved Express: +Test that Master Express can communicate with Secured Express: ```bash -curl -k -X POST https://localhost:3081/ping/enclavedExpress +curl -k -X POST https://localhost:3081/ping/securedExpress ``` ## Production Configuration @@ -141,13 +141,13 @@ curl -k -X POST https://localhost:3081/ping/enclavedExpress ### Production Setup Example -#### Enclaved Express (Production) +#### Secured Express (Production) ```bash -APP_MODE=enclaved \ +APP_MODE=secured \ KMS_URL=https://production-kms.example.com \ -TLS_KEY_PATH=/secure/path/enclaved.key \ -TLS_CERT_PATH=/secure/path/enclaved.crt \ +TLS_KEY_PATH=/secure/path/secured.key \ +TLS_CERT_PATH=/secure/path/secured.crt \ MTLS_REQUEST_CERT=true \ ALLOW_SELF_SIGNED=false \ MTLS_ALLOWED_CLIENT_FINGERPRINTS=ABC123...,DEF456... \ @@ -161,8 +161,8 @@ APP_MODE=master-express \ BITGO_ENV=prod \ TLS_KEY_PATH=/secure/path/master.key \ TLS_CERT_PATH=/secure/path/master.crt \ -ENCLAVED_EXPRESS_URL=https://enclaved.internal.example.com:3080 \ -ENCLAVED_EXPRESS_CERT=/secure/path/enclaved.crt \ +SECURED_EXPRESS_URL=https://secured.internal.example.com:3080 \ +SECURED_EXPRESS_CERT=/secure/path/secured.crt \ MTLS_REQUEST_CERT=true \ ALLOW_SELF_SIGNED=false \ yarn start @@ -176,22 +176,22 @@ First, build the container image: # For Master Express (default port 3081) yarn container:build -# For Enclaved Express (port 3080) +# For Secured Express (port 3080) yarn container:build --build-arg PORT=3080 ``` -For local development, you'll need to run both the Enclaved Express and Master Express containers: +For local development, you'll need to run both the Secured Express and Master Express containers: ```bash -# Start Enclaved Express container +# Start Secured Express container podman run -d \ -p 3080:3080 \ -v $(pwd)/certs:/app/certs:Z \ - -e APP_MODE=enclaved \ + -e APP_MODE=secured \ -e BIND=0.0.0.0 \ -e TLS_MODE=mtls \ - -e TLS_KEY_PATH=/app/certs/enclaved-express-key.pem \ - -e TLS_CERT_PATH=/app/certs/enclaved-express-cert.pem \ + -e TLS_KEY_PATH=/app/certs/secured-express-key.pem \ + -e TLS_CERT_PATH=/app/certs/secured-express-cert.pem \ -e KMS_URL=host.containers.internal:3000 \ -e NODE_ENV=development \ -e ALLOW_SELF_SIGNED=true \ @@ -212,8 +212,8 @@ podman run -d \ -e TLS_MODE=mtls \ -e TLS_KEY_PATH=/app/certs/test-ssl-key.pem \ -e TLS_CERT_PATH=/app/certs/test-ssl-cert.pem \ - -e ENCLAVED_EXPRESS_URL=https://host.containers.internal:3080 \ - -e ENCLAVED_EXPRESS_CERT=/app/certs/enclaved-express-cert.pem \ + -e SECURED_EXPRESS_URL=https://host.containers.internal:3080 \ + -e SECURED_EXPRESS_CERT=/app/certs/secured-express-cert.pem \ -e ALLOW_SELF_SIGNED=true \ bitgo-onprem-express @@ -221,24 +221,25 @@ podman run -d \ podman logs -f # Test the endpoints (note: using https and mTLS) -# For Enclaved Express -curl -k --cert certs/test-ssl-cert.pem --key certs/enclaved-express-key.pem -X POST https://localhost:3080/ping +# For Secured Express +curl -k --cert certs/test-ssl-cert.pem --key certs/secured-express-key.pem -X POST https://localhost:3080/ping # For Master Express curl -k --cert certs/test-ssl-cert.pem --key certs/test-ssl-key.pem -X POST https://localhost:3081/ping # Test the connection -curl -k -X POST https://localhost:3081/ping/enclavedExpress +curl -k -X POST https://localhost:3081/ping/securedExpress ``` Notes: + - `host.containers.internal` is a special DNS name that resolves to the host machine from inside containers - The `:Z` option in volume mounts is specific to SELinux-enabled systems and ensures proper volume labeling - The logs directory will be created with appropriate permissions if it doesn't exist ## API Endpoints -### Enclaved Express (Port 3080) +### Secured Express (Port 3080) - `POST /ping` - Health check - `GET /version` - Version information @@ -248,8 +249,8 @@ Notes: - `POST /ping` - Health check - `GET /version` - Version information -- `POST /ping/enclavedExpress` - Test connection to Enclaved Express -- `POST /api/:coin/wallet/generate` - Generate wallet (with Enclaved Express integration) +- `POST /ping/securedExpress` - Test connection to Secured Express +- `POST /api/:coin/wallet/generate` - Generate wallet (with Secured Express integration) ## Troubleshooting @@ -282,7 +283,7 @@ openssl x509 -in certificate.crt -text -noout ```bash # Check that required variables are set -env | grep -E "(APP_MODE|KMS_URL|ENCLAVED_EXPRESS|TLS_)" +env | grep -E "(APP_MODE|KMS_URL|SECURED_EXPRESS|TLS_)" ``` ### Debug Mode @@ -290,7 +291,7 @@ env | grep -E "(APP_MODE|KMS_URL|ENCLAVED_EXPRESS|TLS_)" Enable debug logging for detailed troubleshooting: ```bash -DEBUG_NAMESPACE=enclaved:*,master:* yarn start +DEBUG_NAMESPACE=secured:*,master:* yarn start ``` ## License diff --git a/bin/enclaved-bitgo-express b/bin/secured-bitgo-express similarity index 100% rename from bin/enclaved-bitgo-express rename to bin/secured-bitgo-express diff --git a/masterBitgoExpress.json b/masterBitgoExpress.json index 045f791..d7d3d4b 100644 --- a/masterBitgoExpress.json +++ b/masterBitgoExpress.json @@ -3,7 +3,7 @@ "info": { "title": "@bitgo/master-bitgo-express", "version": "1.0.0", - "description": "BitGo Enclaved Express - Secure enclave for BitGo signing operations with mTLS" + "description": "BitGo secured Express - Secure enclave for BitGo signing operations with mTLS" }, "paths": { "/api/{coin}/wallet/{walletId}/accelerate": { @@ -1023,7 +1023,7 @@ } } }, - "/ping/enclavedExpress": { + "/ping/securedExpress": { "post": { "parameters": [], "responses": { @@ -1037,13 +1037,13 @@ "status": { "type": "string" }, - "enclavedResponse": { + "securedResponse": { "$ref": "#/components/schemas/PingResponseType" } }, "required": [ "status", - "enclavedResponse" + "securedResponse" ] } } @@ -1091,7 +1091,7 @@ } } }, - "/version/enclavedExpress": { + "/version/securedExpress": { "get": { "parameters": [], "responses": { diff --git a/nodemon.json b/nodemon.json index f5c5310..e55c98e 100644 --- a/nodemon.json +++ b/nodemon.json @@ -2,5 +2,5 @@ "watch": ["src/**/*.ts"], "ignore": ["src/**/*.test.ts", "src/**/__tests__/*"], "ext": "ts", - "exec": "yarn build && node ./bin/enclaved-bitgo-express" + "exec": "yarn build && node ./bin/secured-bitgo-express" } diff --git a/package.json b/package.json index dc733c2..6ec57cb 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "@bitgo/enclaved-bitgo-express", + "name": "@bitgo/secured-bitgo-express", "version": "1.0.0", - "description": "BitGo Enclaved Express - Secure enclave for BitGo signing operations with mTLS", + "description": "Secured BitGo Express - for sensitive key management operations like key generation and signing", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "bin": { - "enclaved-bitgo-express": "./bin/enclaved-bitgo-express" + "secured-bitgo-express": "./bin/secured-bitgo-express" }, "scripts": { "start": "nodemon", diff --git a/src/__tests__/api/master/accelerate.test.ts b/src/__tests__/api/master/accelerate.test.ts index a2ddebc..836b521 100644 --- a/src/__tests__/api/master/accelerate.test.ts +++ b/src/__tests__/api/master/accelerate.test.ts @@ -12,7 +12,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => { const walletId = 'test-wallet-id'; const accessToken = 'test-access-token'; const bitgoApiUrl = Environments.test.uri; - const enclavedExpressUrl = 'https://test-enclaved-express.com'; + const securedExpressUrl = 'https://test-secured-express.com'; before(() => { nock.disableNetConnect(); @@ -27,8 +27,8 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'test-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'test-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -43,7 +43,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => { sinon.restore(); }); - it('should accelerate transaction by calling the enclaved express service', async () => { + it('should accelerate transaction by calling the secured express service', async () => { // Mock wallet get request const walletGetNock = nock(bitgoApiUrl) .get(`/api/v2/${coin}/wallet/${walletId}`) diff --git a/src/__tests__/api/master/consolidate.test.ts b/src/__tests__/api/master/consolidate.test.ts index 2e983b7..21ffaa1 100644 --- a/src/__tests__/api/master/consolidate.test.ts +++ b/src/__tests__/api/master/consolidate.test.ts @@ -15,7 +15,7 @@ describe('POST /api/:coin/wallet/:walletId/consolidateunspents', () => { const walletId = 'test-wallet-id'; const accessToken = 'test-access-token'; const bitgoApiUrl = Environments.test.uri; - const enclavedExpressUrl = 'https://test-enclaved-express.com'; + const securedExpressUrl = 'https://test-secured-express.com'; before(() => { nock.disableNetConnect(); @@ -30,8 +30,8 @@ describe('POST /api/:coin/wallet/:walletId/consolidateunspents', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'test-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'test-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, diff --git a/src/__tests__/api/master/consolidateUnspents.test.ts b/src/__tests__/api/master/consolidateUnspents.test.ts index 310437a..77ae0c6 100644 --- a/src/__tests__/api/master/consolidateUnspents.test.ts +++ b/src/__tests__/api/master/consolidateUnspents.test.ts @@ -12,7 +12,7 @@ describe('POST /api/:coin/wallet/:walletId/consolidateunspents', () => { const walletId = 'test-wallet-id'; const accessToken = 'test-access-token'; const bitgoApiUrl = Environments.test.uri; - const enclavedExpressUrl = 'https://test-enclaved-express.com'; + const securedExpressUrl = 'https://test-secured-express.com'; before(() => { nock.disableNetConnect(); @@ -27,8 +27,8 @@ describe('POST /api/:coin/wallet/:walletId/consolidateunspents', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'test-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'test-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, diff --git a/src/__tests__/api/master/ecdsa.test.ts b/src/__tests__/api/master/ecdsa.test.ts index f2eda71..efca47a 100644 --- a/src/__tests__/api/master/ecdsa.test.ts +++ b/src/__tests__/api/master/ecdsa.test.ts @@ -14,7 +14,7 @@ import { SignatureShareType, TransactionState, } from '@bitgo/sdk-core'; -import { EnclavedExpressClient } from '../../../../src/api/master/clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../../../../src/api/master/clients/securedExpressClient'; import { signAndSendEcdsaMPCv2FromTxRequest } from '../../../api/master/handlers/ecdsaMPCv2'; import { BitGo } from 'bitgo'; import { readKey } from 'openpgp'; @@ -22,10 +22,10 @@ import { readKey } from 'openpgp'; describe('Ecdsa Signing Handler', () => { let bitgo: BitGoBase; let wallet: Wallet; - let enclavedExpressClient: EnclavedExpressClient; + let securedExpressClient: SecuredExpressClient; let reqId: IRequestTracer; const bitgoApiUrl = Environments.local.uri; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const coin = 'hteth'; // Use hteth for ECDSA testing const walletId = 'test-wallet-id'; @@ -43,10 +43,10 @@ describe('Ecdsa Signing Handler', () => { }, multisigTypeVersion: () => 2, } as unknown as Wallet; - enclavedExpressClient = new EnclavedExpressClient( + securedExpressClient = new SecuredExpressClient( { - enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: 'disabled', allowSelfSigned: true, } as any, @@ -203,7 +203,7 @@ describe('Ecdsa Signing Handler', () => { }); // Mock MPCv2 Round 1 signing - const signMpcV2Round1NockEbe = nock(enclavedExpressUrl) + const signMpcV2Round1NockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/mpcv2round1`) .reply(200, { signatureShareRound1: round1SignatureShare, @@ -214,7 +214,7 @@ describe('Ecdsa Signing Handler', () => { }); // Mock MPCv2 Round 2 signing - const signMpcV2Round2NockEbe = nock(enclavedExpressUrl) + const signMpcV2Round2NockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/mpcv2round2`) .reply(200, { signatureShareRound2: round2SignatureShare, @@ -222,7 +222,7 @@ describe('Ecdsa Signing Handler', () => { }); // Mock MPCv2 Round 3 signing - const signMpcV2Round3NockEbe = nock(enclavedExpressUrl) + const signMpcV2Round3NockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/mpcv2round3`) .reply(200, { signatureShareRound3: round3SignatureShare, @@ -232,7 +232,7 @@ describe('Ecdsa Signing Handler', () => { bitgo, wallet, txRequest, - enclavedExpressClient, + securedExpressClient, 'user', userPubKey, reqId, @@ -247,8 +247,8 @@ describe('Ecdsa Signing Handler', () => { sendSignatureShareV2Round2Nock.done(); sendSignatureShareV2Round3Nock.done(); sendTxRequestNock.done(); - signMpcV2Round1NockEbe.done(); - signMpcV2Round2NockEbe.done(); - signMpcV2Round3NockEbe.done(); + signMpcV2Round1NockSbe.done(); + signMpcV2Round2NockSbe.done(); + signMpcV2Round3NockSbe.done(); }); }); diff --git a/src/__tests__/api/master/eddsa.test.ts b/src/__tests__/api/master/eddsa.test.ts index 35ae812..306d57e 100644 --- a/src/__tests__/api/master/eddsa.test.ts +++ b/src/__tests__/api/master/eddsa.test.ts @@ -11,7 +11,7 @@ import { EddsaUtils, openpgpUtils, } from '@bitgo/sdk-core'; -import { EnclavedExpressClient } from '../../../../src/api/master/clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../../../../src/api/master/clients/securedExpressClient'; import { handleEddsaSigning } from '../../../../src/api/master/handlers/eddsa'; import { BitGo } from 'bitgo'; import { readKey } from 'openpgp'; @@ -20,10 +20,10 @@ import { readKey } from 'openpgp'; describe('Eddsa Signing Handler', () => { let bitgo: BitGoBase; let wallet: Wallet; - let enclavedExpressClient: EnclavedExpressClient; + let securedExpressClient: SecuredExpressClient; let reqId: IRequestTracer; const bitgoApiUrl = Environments.local.uri; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const coin = 'tbtc'; const walletId = 'test-wallet-id'; @@ -37,10 +37,10 @@ describe('Eddsa Signing Handler', () => { wallet = { id: () => 'test-wallet-id', } as Wallet; - enclavedExpressClient = new EnclavedExpressClient( + securedExpressClient = new SecuredExpressClient( { - enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: 'disabled', allowSelfSigned: true, } as any, @@ -190,7 +190,7 @@ describe('Eddsa Signing Handler', () => { }); // Mock MPC commitment signing - const signMpcCommitmentNockEbe = nock(enclavedExpressUrl) + const signMpcCommitmentNockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/commitment`) .reply(200, { userToBitgoCommitment: { share: 'user-commitment-share' }, @@ -200,7 +200,7 @@ describe('Eddsa Signing Handler', () => { }); // Mock MPC R-share signing - const signMpcRShareNockEbe = nock(enclavedExpressUrl) + const signMpcRShareNockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/r`) .reply(200, { rShare: { @@ -214,7 +214,7 @@ describe('Eddsa Signing Handler', () => { }); // Mock MPC G-share signing - const signMpcGShareNockEbe = nock(enclavedExpressUrl) + const signMpcGShareNockSbe = nock(securedExpressUrl) .post(`/api/${coin}/mpc/sign/g`) .reply(200, { gShare: { @@ -232,7 +232,7 @@ describe('Eddsa Signing Handler', () => { bitgo, wallet, txRequest, - enclavedExpressClient, + securedExpressClient, userPubKey, reqId, ); @@ -247,8 +247,8 @@ describe('Eddsa Signing Handler', () => { getBitgoRShareNock.done(); sendGShareNock.done(); finalGetTxRequestNock.done(); - signMpcCommitmentNockEbe.done(); - signMpcRShareNockEbe.done(); - signMpcGShareNockEbe.done(); + signMpcCommitmentNockSbe.done(); + signMpcRShareNockSbe.done(); + signMpcGShareNockSbe.done(); }); }); diff --git a/src/__tests__/api/master/generateWallet.test.ts b/src/__tests__/api/master/generateWallet.test.ts index 5137627..565e909 100644 --- a/src/__tests__/api/master/generateWallet.test.ts +++ b/src/__tests__/api/master/generateWallet.test.ts @@ -9,7 +9,7 @@ import assert from 'assert'; describe('POST /api/:coin/wallet/generate', () => { let agent: request.SuperAgentTest; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const bitgoApiUrl = Environments.test.uri; const coin = 'tbtc'; const eddsaCoin = 'tsol'; @@ -20,6 +20,7 @@ describe('POST /api/:coin/wallet/generate', () => { nock.disableNetConnect(); nock.enableNetConnect('127.0.0.1'); + // If MasterExpressConfig does not allow securedExpressUrl/securedExpressCert, use type assertion or extend the type for test purposes const config: MasterExpressConfig = { appMode: AppMode.MASTER_EXPRESS, port: 0, // Let OS assign a free port @@ -29,8 +30,8 @@ describe('POST /api/:coin/wallet/generate', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl: securedExpressUrl, // keep property name as in original config + securedExpressCert: 'dummy-cert', // keep property name as in original config tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -44,8 +45,8 @@ describe('POST /api/:coin/wallet/generate', () => { nock.cleanAll(); }); - it('should generate a wallet by calling the enclaved express service', async () => { - const userKeychainNock = nock(enclavedExpressUrl) + it('should generate a wallet by calling the secured express service', async () => { + const userKeychainNock = nock(securedExpressUrl) .post(`/api/${coin}/key/independent`, { source: 'user', }) @@ -55,7 +56,7 @@ describe('POST /api/:coin/wallet/generate', () => { type: 'independent', }); - const backupKeychainNock = nock(enclavedExpressUrl) + const backupKeychainNock = nock(securedExpressUrl) .post(`/api/${coin}/key/independent`, { source: 'backup', }) @@ -139,7 +140,7 @@ describe('POST /api/:coin/wallet/generate', () => { bitgoAddWalletNock.done(); }); - it('should generate a TSS MPC v1 wallet by calling the enclaved express service', async () => { + it('should generate a TSS MPC v1 wallet by calling the secured express service', async () => { const constantsNock = nock(bitgoApiUrl) .get('/api/v1/client/constants') // Not sure why the nock is not matching any headers, but this works @@ -153,7 +154,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const userInitNock = nock(enclavedExpressUrl) + const userInitNock = nock(securedExpressUrl) .post(`/api/${eddsaCoin}/mpc/key/initialize`, { source: 'user', bitgoGpgPub: 'test-bitgo-public-key', @@ -172,7 +173,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const backupInitNock = nock(enclavedExpressUrl) + const backupInitNock = nock(securedExpressUrl) .post(`/api/${eddsaCoin}/mpc/key/initialize`, { source: 'backup', bitgoGpgPub: 'test-bitgo-public-key', @@ -259,7 +260,7 @@ describe('POST /api/:coin/wallet/generate', () => { walletHSMGPGPublicKeySigs: 'hsm-sig', }); - const userFinalizeNock = nock(enclavedExpressUrl) + const userFinalizeNock = nock(securedExpressUrl) .post(`/api/${eddsaCoin}/mpc/key/finalize`, { source: 'user', encryptedDataKey: 'key', @@ -330,7 +331,7 @@ describe('POST /api/:coin/wallet/generate', () => { type: 'tss', commonKeychain: 'commonKeychain', }); - const backupFinalizeNock = nock(enclavedExpressUrl) + const backupFinalizeNock = nock(securedExpressUrl) .post(`/api/${eddsaCoin}/mpc/key/finalize`, { source: 'backup', encryptedDataKey: 'key', @@ -489,7 +490,7 @@ describe('POST /api/:coin/wallet/generate', () => { response.status.should.equal(200); }); - it('should generate a TSS MPC v2 wallet by calling the enclaved express service', async () => { + it('should generate a TSS MPC v2 wallet by calling the secured express service', async () => { const constantsNock = nock(bitgoApiUrl) .get('/api/v1/client/constants') .matchHeader('accept-encoding', 'gzip, deflate') @@ -502,7 +503,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); // init round - const userInitNock = nock(enclavedExpressUrl) + const userInitNock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/initialize`, { source: 'user', }) @@ -512,7 +513,7 @@ describe('POST /api/:coin/wallet/generate', () => { gpgPub: 'test-user-public-key', }); - const backupInitNock = nock(enclavedExpressUrl) + const backupInitNock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/initialize`, { source: 'backup', }) @@ -522,7 +523,7 @@ describe('POST /api/:coin/wallet/generate', () => { gpgPub: 'test-backup-public-key', }); - const userRound1Nock = nock(enclavedExpressUrl) + const userRound1Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'user', encryptedDataKey: 'key', @@ -544,7 +545,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const backupRound1Nock = nock(enclavedExpressUrl) + const backupRound1Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'backup', encryptedDataKey: 'key', @@ -609,7 +610,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const userRound2Nock = nock(enclavedExpressUrl) + const userRound2Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'user', encryptedDataKey: 'key', @@ -658,7 +659,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const backupRound2Nock = nock(enclavedExpressUrl) + const backupRound2Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'backup', encryptedDataKey: 'key', @@ -707,7 +708,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const userRound3Nock = nock(enclavedExpressUrl) + const userRound3Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'user', encryptedDataKey: 'key', @@ -753,14 +754,14 @@ describe('POST /api/:coin/wallet/generate', () => { to: 1, payload: { encryptedMessage: 'test-p2p-message-user-to-backup-3', - signature: 'test-signature-user-to-backup-3', + signature: 'test-signature-backup-to-user-3', }, commitment: 'test-commitment-user-3', }, }, }); - const backupRound3Nock = nock(enclavedExpressUrl) + const backupRound3Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'backup', encryptedDataKey: 'key', @@ -853,7 +854,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const userRound4Nock = nock(enclavedExpressUrl) + const userRound4Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'user', encryptedDataKey: 'key', @@ -874,7 +875,7 @@ describe('POST /api/:coin/wallet/generate', () => { to: 0, payload: { encryptedMessage: 'test-p2p-message-backup-to-user-3', - signature: 'test-signature-backup-to-user-3', + signature: 'test-signature-user-to-backup-3', }, commitment: 'test-commitment-backup-3', }, @@ -893,7 +894,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const backupRound4Nock = nock(enclavedExpressUrl) + const backupRound4Nock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/round`, { source: 'backup', encryptedDataKey: 'key', @@ -974,7 +975,7 @@ describe('POST /api/:coin/wallet/generate', () => { }, }); - const userFinalizeNock = nock(enclavedExpressUrl) + const userFinalizeNock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/finalize`, { source: 'user', encryptedDataKey: 'key', @@ -1002,7 +1003,7 @@ describe('POST /api/:coin/wallet/generate', () => { commonKeychain: 'commonKeychain', }); - const backupFinalizeNock = nock(enclavedExpressUrl) + const backupFinalizeNock = nock(securedExpressUrl) .post(`/api/${ecdsaCoin}/mpcv2/finalize`, { source: 'backup', encryptedDataKey: 'key', @@ -1115,8 +1116,8 @@ describe('POST /api/:coin/wallet/generate', () => { bitgoAddWalletNock.done(); }); - it('should fail when enclaved express client is not configured', async () => { - // Create a config without enclaved express settings + it('should fail when secured express client is not configured', async () => { + // Create a config without secured express settings const invalidConfig: Partial = { appMode: AppMode.MASTER_EXPRESS, port: 0, @@ -1133,9 +1134,9 @@ describe('POST /api/:coin/wallet/generate', () => { try { expressApp(invalidConfig as MasterExpressConfig); - assert(false, 'Expected error to be thrown when enclaved express client is not configured'); + assert(false, 'Expected error to be thrown when secured express client is not configured'); } catch (e) { - (e as Error).message.should.equal('enclavedExpressUrl and enclavedExpressCert are required'); + (e as Error).message.should.equal('securedExpressUrl and securedExpressCert are required'); } }); diff --git a/src/__tests__/api/master/musigRecovery.test.ts b/src/__tests__/api/master/musigRecovery.test.ts index 86123ee..d2ec494 100644 --- a/src/__tests__/api/master/musigRecovery.test.ts +++ b/src/__tests__/api/master/musigRecovery.test.ts @@ -10,7 +10,7 @@ import { data as ethRecoveryData } from '../../mocks/ethRecoveryMusigMockData'; describe('POST /api/:coin/wallet/recovery', () => { let agent: request.SuperAgentTest; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const coin = 'hteth'; const accessToken = 'test-token'; @@ -27,8 +27,8 @@ describe('POST /api/:coin/wallet/recovery', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -51,7 +51,7 @@ describe('POST /api/:coin/wallet/recovery', () => { // the call to eve.recoverWallet(...) // that contains the calls to sdk.signTransaction - const eveRecoverWalletNock = nock(enclavedExpressUrl) + const eveRecoverWalletNock = nock(securedExpressUrl) .post(`/api/${coin}/multisig/recovery`, { userPub: ethRecoveryData.userKey, backupPub: ethRecoveryData.backupKey, diff --git a/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts b/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts index 0d37a71..0f476a4 100644 --- a/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts +++ b/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts @@ -7,11 +7,11 @@ import { AppMode, MasterExpressConfig, TlsMode } from '../../../shared/types'; import { Trx } from '@bitgo/sdk-coin-trx'; import { Sol } from '@bitgo/sdk-coin-sol'; import { Sui } from '@bitgo/sdk-coin-sui'; -import { EnclavedExpressClient } from '../../../api/master/clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../../../api/master/clients/securedExpressClient'; describe('POST /api/:coin/wallet/recoveryconsolidations', () => { let agent: request.SuperAgentTest; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const accessToken = 'test-token'; before(() => { @@ -26,8 +26,8 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -55,7 +55,7 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { }); const recoveryMultisigStub = sinon - .stub(EnclavedExpressClient.prototype, 'recoveryMultisig') + .stub(SecuredExpressClient.prototype, 'recoveryMultisig') .resolves({ txHex: 'signed-tx' }); const response = await agent @@ -97,7 +97,7 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { }); const recoveryMultisigStub = sinon - .stub(EnclavedExpressClient.prototype, 'recoveryMultisig') + .stub(SecuredExpressClient.prototype, 'recoveryMultisig') .resolves({ txHex: 'signed-tx' }); const response = await agent @@ -152,7 +152,7 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { }); const recoveryMPCStub = sinon - .stub(EnclavedExpressClient.prototype, 'recoveryMPC') + .stub(SecuredExpressClient.prototype, 'recoveryMPC') .resolves({ txHex: 'signed-mpc-tx' }); const response = await agent @@ -196,7 +196,7 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { }); const recoveryMPCStub = sinon - .stub(EnclavedExpressClient.prototype, 'recoveryMPC') + .stub(SecuredExpressClient.prototype, 'recoveryMPC') .resolves({ txHex: 'signed-mpc-tx' }); const response = await agent diff --git a/src/__tests__/api/master/recoveryWallet.test.ts b/src/__tests__/api/master/recoveryWallet.test.ts index 6d60416..898d71b 100644 --- a/src/__tests__/api/master/recoveryWallet.test.ts +++ b/src/__tests__/api/master/recoveryWallet.test.ts @@ -8,14 +8,14 @@ import * as middleware from '../../../shared/middleware'; import * as masterMiddleware from '../../../api/master/middleware/middleware'; import { BitGoRequest } from '../../../types/request'; import { BitGo } from 'bitgo'; -import { EnclavedExpressClient } from '../../../api/master/clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../../../api/master/clients/securedExpressClient'; import { CoinFamily } from '@bitgo/statics'; describe('Recovery Tests', () => { let agent: request.SuperAgentTest; let mockBitgo: BitGo; let coinStub: sinon.SinonStub; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const accessToken = 'test-token'; const config: MasterExpressConfig = { appMode: AppMode.MASTER_EXPRESS, @@ -26,8 +26,8 @@ describe('Recovery Tests', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -127,21 +127,23 @@ describe('Recovery Tests', () => { // Setup coin middleware sinon.stub(masterMiddleware, 'validateMasterExpressConfig').callsFake((req, res, next) => { (req as BitGoRequest).params = { coin }; - (req as BitGoRequest).enclavedExpressClient = - new EnclavedExpressClient(config, coin); + (req as BitGoRequest).securedExpressClient = new SecuredExpressClient( + config, + coin, + ); next(); return undefined; }); }); - it('should recover a UTXO wallet by calling the enclaved express service', async () => { + it('should recover a UTXO wallet by calling the secured express service', async () => { const userPub = 'xpub_user'; const backupPub = 'xpub_backup'; const bitgoPub = 'xpub_bitgo'; const recoveryDestination = 'tb1qprdy6jwxrrr2qrwgd2tzl8z99hqp29jn6f3sguxulqm448myj6jsy2nwsu'; - // Mock the enclaved express recovery call - const recoveryNock = nock(enclavedExpressUrl) + // Mock the secured express recovery call + const recoveryNock = nock(securedExpressUrl) .post(`/api/${coin}/multisig/recovery`, { userPub, backupPub, @@ -197,7 +199,7 @@ describe('Recovery Tests', () => { }) .should.be.true(); - // Verify enclaved express call + // Verify secured express call recoveryNock.done(); }); @@ -315,8 +317,10 @@ describe('Recovery Tests', () => { // Setup coin middleware for ETH coin sinon.stub(masterMiddleware, 'validateMasterExpressConfig').callsFake((req, res, next) => { (req as BitGoRequest).params = { coin: ethCoinId }; - (req as BitGoRequest).enclavedExpressClient = - new EnclavedExpressClient(config, ethCoinId); + (req as BitGoRequest).securedExpressClient = new SecuredExpressClient( + config, + ethCoinId, + ); next(); return undefined; }); @@ -413,8 +417,10 @@ describe('Recovery Tests', () => { // Setup coin middleware for Solana coin sinon.stub(masterMiddleware, 'validateMasterExpressConfig').callsFake((req, res, next) => { (req as BitGoRequest).params = { coin: solCoinId }; - (req as BitGoRequest).enclavedExpressClient = - new EnclavedExpressClient(config, solCoinId); + (req as BitGoRequest).securedExpressClient = new SecuredExpressClient( + config, + solCoinId, + ); next(); return undefined; }); diff --git a/src/__tests__/api/master/sendMany.test.ts b/src/__tests__/api/master/sendMany.test.ts index d66a559..81b6c02 100644 --- a/src/__tests__/api/master/sendMany.test.ts +++ b/src/__tests__/api/master/sendMany.test.ts @@ -11,7 +11,7 @@ import assert from 'assert'; describe('POST /api/:coin/wallet/:walletId/sendmany', () => { let agent: request.SuperAgentTest; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const bitgoApiUrl = Environments.test.uri; const accessToken = 'test-token'; const walletId = 'test-wallet-id'; @@ -21,6 +21,7 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { nock.disableNetConnect(); nock.enableNetConnect('127.0.0.1'); + // If MasterExpressConfig does not allow securedExpressUrl/securedExpressCert, use type assertion or extend the type for test purposes const config: MasterExpressConfig = { appMode: AppMode.MASTER_EXPRESS, port: 0, // Let OS assign a free port @@ -30,8 +31,8 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl: securedExpressUrl, // keep property name as in original config + securedExpressCert: 'dummy-cert', // keep property name as in original config tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, @@ -48,7 +49,7 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { describe('SendMany Multisig:', () => { const coin = 'tbtc'; - it('should send many transactions by calling the enclaved express service', async () => { + it('should send many transactions by calling the secured express service', async () => { // Mock wallet get request const walletGetNock = nock(bitgoApiUrl) .get(`/api/v2/${coin}/wallet/${walletId}`) @@ -82,8 +83,8 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { const verifyStub = sinon.stub(Coin.Btc.prototype, 'verifyTransaction').resolves(true); - // Mock enclaved express sign request - const signNock = nock(enclavedExpressUrl) + // Mock secured express sign request + const signNock = nock(securedExpressUrl) .post(`/api/${coin}/multisig/sign`) .reply(200, { halfSigned: { @@ -171,8 +172,8 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { const verifyStub = sinon.stub(Coin.Btc.prototype, 'verifyTransaction').resolves(true); - // Mock enclaved express sign request - const signNock = nock(enclavedExpressUrl) + // Mock secured express sign request + const signNock = nock(securedExpressUrl) .post(`/api/${coin}/multisig/sign`) .reply(200, { halfSigned: { @@ -573,8 +574,8 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { keychainGetNock.done(); }); - it('should fail when enclaved express client is not configured', async () => { - // Create a config without enclaved express settings + it('should fail when secured express client is not configured', async () => { + // Create a config without secured express settings const invalidConfig: Partial = { appMode: AppMode.MASTER_EXPRESS, port: 0, @@ -591,10 +592,10 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { try { expressApp(invalidConfig as MasterExpressConfig); - assert(false, 'Expected error to be thrown when enclaved express client is not configured'); + assert(false, 'Expected error to be thrown when secured express client is not configured'); } catch (error) { (error as Error).message.should.equal( - 'enclavedExpressUrl and enclavedExpressCert are required', + 'securedExpressUrl and securedExpressCert are required', ); } }); @@ -746,8 +747,8 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { const verifyStub = sinon.stub(Coin.Btc.prototype, 'verifyTransaction').resolves(true); - // Mock enclaved express sign request to return an error - const signNock = nock(enclavedExpressUrl) + // Mock secured express sign request to return an error + const signNock = nock(securedExpressUrl) .post(`/api/${coin}/multisig/sign`) .replyWithError( new ApiResponseError('Custom API error', 500, { @@ -770,7 +771,7 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { pubkey: 'xpub_user', }); - // The response should be a 500 error with the enclaved error details + // The response should be a 500 error with the secured error details response.status.should.equal(500); response.body.should.have.property('error'); response.body.should.have.property('details'); diff --git a/src/__tests__/api/master/signAndSendTxRequest.test.ts b/src/__tests__/api/master/signAndSendTxRequest.test.ts index 0351850..a94eab0 100644 --- a/src/__tests__/api/master/signAndSendTxRequest.test.ts +++ b/src/__tests__/api/master/signAndSendTxRequest.test.ts @@ -24,7 +24,7 @@ describe('POST /api/:coin/wallet/:walletId/txrequest/:txRequestId/signAndSend', let bitgo: BitGoBase; let baseCoin: IBaseCoin; let wallet: Wallet; - const enclavedExpressUrl = 'http://enclaved.invalid'; + const securedExpressUrl = 'http://secured.invalid'; const bitgoApiUrl = Environments.test.uri; const accessToken = 'test-token'; const walletId = 'test-wallet-id'; @@ -48,8 +48,8 @@ describe('POST /api/:coin/wallet/:walletId/txrequest/:txRequestId/signAndSend', env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: enclavedExpressUrl, - enclavedExpressCert: 'dummy-cert', + securedExpressUrl: securedExpressUrl, + securedExpressCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, allowSelfSigned: true, diff --git a/src/__tests__/api/enclaved/ecdsaUtils.ts b/src/__tests__/api/secured/ecdsaUtils.ts similarity index 100% rename from src/__tests__/api/enclaved/ecdsaUtils.ts rename to src/__tests__/api/secured/ecdsaUtils.ts diff --git a/src/__tests__/api/enclaved/postIndependentKey.test.ts b/src/__tests__/api/secured/postIndependentKey.test.ts similarity index 89% rename from src/__tests__/api/enclaved/postIndependentKey.test.ts rename to src/__tests__/api/secured/postIndependentKey.test.ts index e18be0e..66c0195 100644 --- a/src/__tests__/api/enclaved/postIndependentKey.test.ts +++ b/src/__tests__/api/secured/postIndependentKey.test.ts @@ -2,15 +2,15 @@ import 'should'; import * as request from 'supertest'; import nock from 'nock'; -import { app as enclavedApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import { app as securedApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; import express from 'express'; import * as sinon from 'sinon'; import * as configModule from '../../../initConfig'; describe('postIndependentKey', () => { - let cfg: EnclavedConfig; + let cfg: SecuredExpressConfig; let app: express.Application; let agent: request.SuperAgentTest; @@ -29,7 +29,7 @@ describe('postIndependentKey', () => { // app config cfg = { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: 0, // Let OS assign a free port bind: 'localhost', timeout: 60000, @@ -43,7 +43,7 @@ describe('postIndependentKey', () => { configStub = sinon.stub(configModule, 'initConfig').returns(cfg); // app setup - app = enclavedApp(cfg); + app = securedApp(cfg); agent = request.agent(app); }); diff --git a/src/__tests__/api/enclaved/postMpcV2Key.test.ts b/src/__tests__/api/secured/postMpcV2Key.test.ts similarity index 98% rename from src/__tests__/api/enclaved/postMpcV2Key.test.ts rename to src/__tests__/api/secured/postMpcV2Key.test.ts index 8a8af68..b44e4de 100644 --- a/src/__tests__/api/enclaved/postMpcV2Key.test.ts +++ b/src/__tests__/api/secured/postMpcV2Key.test.ts @@ -1,5 +1,5 @@ -import { AppMode, EnclavedConfig, TlsMode } from '../../../initConfig'; -import { app as enclavedApp } from '../../../enclavedApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../initConfig'; +import { app as securedApp } from '../../../securedExpressApp'; import express from 'express'; import nock from 'nock'; @@ -12,7 +12,7 @@ import { DklsComms, DklsDkg, DklsTypes } from '@bitgo-beta/sdk-lib-mpc'; import { MPCv2PartiesEnum } from '@bitgo/sdk-core/dist/src/bitgo/utils/tss/ecdsa'; describe('postMpcV2Key', () => { - let cfg: EnclavedConfig; + let cfg: SecuredExpressConfig; let app: express.Application; let agent: request.SuperAgentTest; @@ -31,7 +31,7 @@ describe('postMpcV2Key', () => { // app config cfg = { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: 0, // Let OS assign a free port bind: 'localhost', timeout: 60000, @@ -45,7 +45,7 @@ describe('postMpcV2Key', () => { configStub = sinon.stub(configModule, 'initConfig').returns(cfg); // app setup - app = enclavedApp(cfg); + app = securedApp(cfg); agent = request.agent(app); }); diff --git a/src/__tests__/api/enclaved/recoveryMultisigTransaction.test.ts b/src/__tests__/api/secured/recoveryMultisigTransaction.test.ts similarity index 92% rename from src/__tests__/api/enclaved/recoveryMultisigTransaction.test.ts rename to src/__tests__/api/secured/recoveryMultisigTransaction.test.ts index 5c63b1e..efb9824 100644 --- a/src/__tests__/api/enclaved/recoveryMultisigTransaction.test.ts +++ b/src/__tests__/api/secured/recoveryMultisigTransaction.test.ts @@ -1,21 +1,21 @@ import 'should'; import * as request from 'supertest'; import nock from 'nock'; -import { app as expressApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import { app as expressApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; import sinon from 'sinon'; import * as middleware from '../../../shared/middleware'; import { BitGoRequest } from '../../../types/request'; import { BitGo } from 'bitgo'; -import * as kmsUtils from '../../../api/enclaved/utils'; +import * as kmsUtils from '../../../api/secured/utils'; describe('UTXO recovery', () => { let agent: request.SuperAgentTest; let mockBitgo: BitGo; let mockRetrieveKmsPrvKey: sinon.SinonStub; const coin = 'tbtc'; - const config: EnclavedConfig = { - appMode: AppMode.ENCLAVED, + const config: SecuredExpressConfig = { + appMode: AppMode.SECURED, port: 0, bind: 'localhost', timeout: 60000, @@ -46,8 +46,8 @@ describe('UTXO recovery', () => { // Setup middleware stubs before creating app sinon.stub(middleware, 'prepareBitGo').callsFake(() => (req, res, next) => { - (req as BitGoRequest).bitgo = mockBitgo; - (req as BitGoRequest).config = config; + (req as BitGoRequest).bitgo = mockBitgo; + (req as BitGoRequest).config = config; next(); }); diff --git a/src/__tests__/api/enclaved/recoveryMusigEth.test.ts b/src/__tests__/api/secured/recoveryMusigEth.test.ts similarity index 90% rename from src/__tests__/api/enclaved/recoveryMusigEth.test.ts rename to src/__tests__/api/secured/recoveryMusigEth.test.ts index d21bea3..25f0dd4 100644 --- a/src/__tests__/api/enclaved/recoveryMusigEth.test.ts +++ b/src/__tests__/api/secured/recoveryMusigEth.test.ts @@ -3,17 +3,17 @@ import 'should'; import express from 'express'; import nock from 'nock'; import * as request from 'supertest'; -import { app as enclavedApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import { app as securedApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; import * as sinon from 'sinon'; import * as configModule from '../../../initConfig'; -import { ebeData } from '../../mocks/ethRecoveryMusigMockData'; +import { sbeData } from '../../mocks/ethRecoveryMusigMockData'; import unsignedSweepRecJSON from '../../mocks/unsigned-sweep-prebuild-hteth-musig-recovery.json'; describe('recoveryMultisigTransaction', () => { - let cfg: EnclavedConfig; + let cfg: SecuredExpressConfig; let app: express.Application; let agent: request.SuperAgentTest; @@ -32,7 +32,7 @@ describe('recoveryMultisigTransaction', () => { // app config cfg = { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: 0, // Let OS assign a free port bind: 'localhost', timeout: 60000, @@ -46,7 +46,7 @@ describe('recoveryMultisigTransaction', () => { configStub = sinon.stub(configModule, 'initConfig').returns(cfg); // app setup - app = enclavedApp(cfg); + app = securedApp(cfg); agent = request.agent(app); }); @@ -59,7 +59,7 @@ describe('recoveryMultisigTransaction', () => { }); it('should generate a successful txHex from unsigned sweep prebuild data', async () => { - const { userPub, backupPub, walletContractAddress, userPrv, backupPrv, txHexResult } = ebeData; + const { userPub, backupPub, walletContractAddress, userPrv, backupPrv, txHexResult } = sbeData; const unsignedSweepPrebuildTx = unsignedSweepRecJSON as unknown as any; const mockKmsUserResponse = { @@ -109,7 +109,7 @@ describe('recoveryMultisigTransaction', () => { }); it('should fail when prv keys non related to pub keys', async () => { - const { userPub, backupPub, walletContractAddress } = ebeData; + const { userPub, backupPub, walletContractAddress } = sbeData; const unsignedSweepPrebuildTx = unsignedSweepRecJSON as unknown as any; // Use invalid private keys diff --git a/src/__tests__/api/enclaved/signMpcRecoveryTransaction.test.ts b/src/__tests__/api/secured/signMpcRecoveryTransaction.test.ts similarity index 96% rename from src/__tests__/api/enclaved/signMpcRecoveryTransaction.test.ts rename to src/__tests__/api/secured/signMpcRecoveryTransaction.test.ts index e7a79ae..ba85230 100644 --- a/src/__tests__/api/enclaved/signMpcRecoveryTransaction.test.ts +++ b/src/__tests__/api/secured/signMpcRecoveryTransaction.test.ts @@ -3,14 +3,14 @@ import nock from 'nock'; import sinon from 'sinon'; import supertest from 'supertest'; import { Utils } from '@bitgo/sdk-coin-sol'; -import * as kmsUtils from '../../../api/enclaved/utils'; -import { app as expressApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import * as kmsUtils from '../../../api/secured/utils'; +import { app as expressApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; describe('EdDSA Recovery Signing', () => { let agent: supertest.SuperTest; - const config: EnclavedConfig = { - appMode: AppMode.ENCLAVED, + const config: SecuredExpressConfig = { + appMode: AppMode.SECURED, port: 0, bind: 'localhost', timeout: 60000, diff --git a/src/__tests__/api/enclaved/signMpcTransaction.test.ts b/src/__tests__/api/secured/signMpcTransaction.test.ts similarity index 98% rename from src/__tests__/api/enclaved/signMpcTransaction.test.ts rename to src/__tests__/api/secured/signMpcTransaction.test.ts index 1d57b2d..0941639 100644 --- a/src/__tests__/api/enclaved/signMpcTransaction.test.ts +++ b/src/__tests__/api/secured/signMpcTransaction.test.ts @@ -2,8 +2,8 @@ import 'should'; import * as request from 'supertest'; import nock from 'nock'; -import { app as enclavedApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import { app as securedApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; import express from 'express'; import * as sinon from 'sinon'; import * as configModule from '../../../initConfig'; @@ -17,7 +17,7 @@ import createKeccakHash from 'keccak'; import { bitgoGpgKey } from '../../mocks/gpgKeys'; describe('signMpcTransaction', () => { - let cfg: EnclavedConfig; + let cfg: SecuredExpressConfig; let app: express.Application; let agent: request.SuperAgentTest; @@ -36,7 +36,7 @@ describe('signMpcTransaction', () => { // app config cfg = { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: 0, // Let OS assign a free port bind: 'localhost', timeout: 60000, @@ -50,7 +50,7 @@ describe('signMpcTransaction', () => { configStub = sinon.stub(configModule, 'initConfig').returns(cfg); // app setup - app = enclavedApp(cfg); + app = securedApp(cfg); agent = request.agent(app); }); diff --git a/src/__tests__/api/enclaved/signMultisigTransaction.test.ts b/src/__tests__/api/secured/signMultisigTransaction.test.ts similarity index 93% rename from src/__tests__/api/enclaved/signMultisigTransaction.test.ts rename to src/__tests__/api/secured/signMultisigTransaction.test.ts index 241775c..2790ccf 100644 --- a/src/__tests__/api/enclaved/signMultisigTransaction.test.ts +++ b/src/__tests__/api/secured/signMultisigTransaction.test.ts @@ -2,15 +2,15 @@ import 'should'; import * as request from 'supertest'; import nock from 'nock'; -import { app as enclavedApp } from '../../../enclavedApp'; -import { AppMode, EnclavedConfig, TlsMode } from '../../../shared/types'; +import { app as securedApp } from '../../../securedExpressApp'; +import { AppMode, SecuredExpressConfig, TlsMode } from '../../../shared/types'; import express from 'express'; import * as sinon from 'sinon'; import * as configModule from '../../../initConfig'; describe('signMultisigTransaction', () => { - let cfg: EnclavedConfig; + let cfg: SecuredExpressConfig; let app: express.Application; let agent: request.SuperAgentTest; @@ -29,7 +29,7 @@ describe('signMultisigTransaction', () => { // app config cfg = { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: 0, // Let OS assign a free port bind: 'localhost', timeout: 60000, @@ -43,7 +43,7 @@ describe('signMultisigTransaction', () => { configStub = sinon.stub(configModule, 'initConfig').returns(cfg); // app setup - app = enclavedApp(cfg); + app = securedApp(cfg); agent = request.agent(app); }); diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts index a090fdf..68a94a7 100644 --- a/src/__tests__/config.test.ts +++ b/src/__tests__/config.test.ts @@ -1,5 +1,5 @@ import 'should'; -import { initConfig, isEnclavedConfig, TlsMode } from '../initConfig'; +import { initConfig, isSecuredExpressConfig, TlsMode } from '../initConfig'; describe('Configuration', () => { const originalEnv = process.env; @@ -18,20 +18,20 @@ describe('Configuration', () => { it('should throw error when APP_MODE is not set', () => { (() => initConfig()).should.throw( - 'APP_MODE environment variable is required. Set APP_MODE to either "enclaved" or "master-express"', + 'APP_MODE environment variable is required. Set APP_MODE to either "secured" or "master-express"', ); }); it('should throw error when APP_MODE is invalid', () => { process.env.APP_MODE = 'invalid'; (() => initConfig()).should.throw( - 'Invalid APP_MODE: invalid. Must be either "enclaved" or "master-express"', + 'Invalid APP_MODE: invalid. Must be either "secured" or "master-express"', ); }); - describe('Enclaved Mode', () => { + describe('secured Mode', () => { beforeEach(() => { - process.env.APP_MODE = 'enclaved'; + process.env.APP_MODE = 'secured'; process.env.KMS_URL = 'http://localhost:3000'; // Set default TLS certificates process.env.TLS_KEY = mockTlsKey; @@ -40,8 +40,8 @@ describe('Configuration', () => { it('should use default configuration when no environment variables are set', () => { const cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.port.should.equal(3080); cfg.bind.should.equal('localhost'); cfg.tlsMode.should.equal(TlsMode.MTLS); @@ -53,10 +53,10 @@ describe('Configuration', () => { }); it('should read port from environment variable', () => { - process.env.ENCLAVED_EXPRESS_PORT = '4000'; + process.env.SECURED_EXPRESS_PORT = '4000'; const cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.port.should.equal(4000); cfg.kmsUrl.should.equal('http://localhost:3000'); cfg.tlsKey!.should.equal(mockTlsKey); @@ -68,8 +68,8 @@ describe('Configuration', () => { // Test with TLS disabled process.env.TLS_MODE = 'disabled'; let cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.tlsMode.should.equal(TlsMode.DISABLED); cfg.kmsUrl.should.equal('http://localhost:3000'); } @@ -77,8 +77,8 @@ describe('Configuration', () => { // Test with mTLS explicitly enabled process.env.TLS_MODE = 'mtls'; cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.tlsMode.should.equal(TlsMode.MTLS); cfg.kmsUrl.should.equal('http://localhost:3000'); cfg.tlsKey!.should.equal(mockTlsKey); @@ -94,8 +94,8 @@ describe('Configuration', () => { // Test with no TLS mode (should default to MTLS) delete process.env.TLS_MODE; cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.tlsMode.should.equal(TlsMode.MTLS); cfg.kmsUrl.should.equal('http://localhost:3000'); cfg.tlsKey!.should.equal(mockTlsKey); @@ -109,8 +109,8 @@ describe('Configuration', () => { process.env.MTLS_ALLOWED_CLIENT_FINGERPRINTS = 'ABC123,DEF456'; const cfg = initConfig(); - isEnclavedConfig(cfg).should.be.true(); - if (isEnclavedConfig(cfg)) { + isSecuredExpressConfig(cfg).should.be.true(); + if (isSecuredExpressConfig(cfg)) { cfg.mtlsRequestCert!.should.be.true(); cfg.mtlsAllowedClientFingerprints!.should.deepEqual(['ABC123', 'DEF456']); cfg.kmsUrl.should.equal('http://localhost:3000'); diff --git a/src/__tests__/mocks/ethRecoveryMusigMockData.ts b/src/__tests__/mocks/ethRecoveryMusigMockData.ts index c710785..f20a2bd 100644 --- a/src/__tests__/mocks/ethRecoveryMusigMockData.ts +++ b/src/__tests__/mocks/ethRecoveryMusigMockData.ts @@ -37,7 +37,7 @@ export const data = { recoveryDestinationAddress: '0x927324f364a6fd1bf4648310a445b58063f5bb64', }; -export const ebeData = { +export const sbeData = { userPub: 'xpub661MyMwAqRbcGvbtjkhDJ5uiFWb6eK9nFQmLLgW1jDwJzJ2vQPyp2uKLmUBgGZKiA9HDUFYfuDoyP1dF3tj3Ucod25tmiEG2k26UX97S3Wz', backupPub: diff --git a/src/__tests__/routes.test.ts b/src/__tests__/routes.test.ts index 2df84f4..98524b3 100644 --- a/src/__tests__/routes.test.ts +++ b/src/__tests__/routes.test.ts @@ -3,7 +3,7 @@ import 'should'; import request from 'supertest'; import express from 'express'; import { AppMode, TlsMode } from '../shared/types'; -import { setupRoutes } from '../routes/enclaved'; +import { setupRoutes } from '../routes/secured'; describe('Routes', () => { let app: express.Application; @@ -11,7 +11,7 @@ describe('Routes', () => { beforeEach(() => { app = express(); setupRoutes(app, { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, tlsMode: TlsMode.DISABLED, mtlsRequestCert: false, kmsUrl: 'http://localhost:3000/kms', @@ -25,7 +25,7 @@ describe('Routes', () => { it('should return 200 and status message for /ping', async () => { const response = await request(app).post('/ping'); response.status.should.equal(200); - response.body.should.have.property('status', 'enclaved express server is ok!'); + response.body.should.have.property('status', 'secured express server is ok!'); response.body.should.have.property('timestamp'); }); @@ -33,7 +33,7 @@ describe('Routes', () => { const response = await request(app).get('/version'); response.status.should.equal(200); response.body.should.have.property('version'); - response.body.should.have.property('name', '@bitgo/enclaved-bitgo-express'); + response.body.should.have.property('name', '@bitgo/secured-bitgo-express'); }); }); @@ -43,7 +43,7 @@ describe('Routes', () => { response.status.should.equal(404); response.body.should.have.property( 'error', - 'Route not found or not supported in enclaved mode', + 'Route not found or not supported in secured mode', ); }); }); diff --git a/src/api/master/clients/enclavedExpressClient.ts b/src/api/master/clients/securedExpressClient.ts similarity index 93% rename from src/api/master/clients/enclavedExpressClient.ts rename to src/api/master/clients/securedExpressClient.ts index 54b6c21..0c20ab5 100644 --- a/src/api/master/clients/enclavedExpressClient.ts +++ b/src/api/master/clients/securedExpressClient.ts @@ -23,7 +23,7 @@ import { ApiClient, buildApiClient, superagentRequestFactory } from '@api-ts/sup import { OfflineVaultTxInfo, RecoveryInfo, UnsignedSweepTxMPCv2 } from '@bitgo/sdk-coin-eth'; import { MasterExpressConfig, TlsMode } from '../../../shared/types'; -import { EnclavedApiSpec } from '../../../enclavedBitgoExpress/routers'; +import { SecuredExpressApiSpec } from '../../../securedBitgoExpress/routers'; import { PingResponseType, VersionResponseType } from '../../../types/health'; import { extractTransactionRequestInfo } from '../../../shared/transactionUtils'; import { @@ -33,11 +33,11 @@ import { MpcV2FinalizeResponseType, MpcV2InitializeResponseType, MpcV2RoundResponseType, -} from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { FormattedOfflineVaultTxInfo } from '@bitgo/abstract-utxo'; import { RecoveryTxRequest } from 'bitgo'; -const debugLogger = debug('bitgo:express:enclavedExpressClient'); +const debugLogger = debug('bitgo:express:securedExpressClient'); export type InitMpcKeyGenerationParams = { source: 'user' | 'backup'; @@ -173,7 +173,7 @@ export interface SignMpcV2Round3Response { signatureShareRound3: SignatureShareRecord; } -export class EnclavedExpressClient { +export class SecuredExpressClient { async recoveryMPC(params: { unsignedSweepPrebuildTx: MPCTx | MPCSweepTxs | MPCTxs | RecoveryTxRequest; userPub: string; @@ -220,25 +220,25 @@ export class EnclavedExpressClient { } } private readonly baseUrl: string; - private readonly enclavedExpressCert: string; + private readonly securedExpressCert: string; private readonly tlsKey?: string; private readonly tlsCert?: string; private readonly allowSelfSigned: boolean; private readonly coin?: string; private readonly tlsMode: TlsMode; - private readonly apiClient: ApiClient; + private readonly apiClient: ApiClient; constructor(cfg: MasterExpressConfig, coin?: string) { - if (!cfg.enclavedExpressUrl || !cfg.enclavedExpressCert) { - throw new Error('enclavedExpressUrl and enclavedExpressCert are required'); + if (!cfg.securedExpressUrl || !cfg.securedExpressCert) { + throw new Error('securedExpressUrl and securedExpressCert are required'); } if (cfg.tlsMode === TlsMode.MTLS && (!cfg.tlsKey || !cfg.tlsCert)) { throw new Error('tlsKey and tlsCert are required for mTLS communication'); } - this.baseUrl = cfg.enclavedExpressUrl; - this.enclavedExpressCert = cfg.enclavedExpressCert; + this.baseUrl = cfg.securedExpressUrl; + this.securedExpressCert = cfg.securedExpressCert; this.tlsKey = cfg.tlsKey; this.tlsCert = cfg.tlsCert; this.allowSelfSigned = cfg.allowSelfSigned ?? false; @@ -249,9 +249,9 @@ export class EnclavedExpressClient { const requestFactory = superagentRequestFactory(superagent, this.baseUrl); // Build the type-safe API client - this.apiClient = buildApiClient(requestFactory, EnclavedApiSpec); + this.apiClient = buildApiClient(requestFactory, SecuredExpressApiSpec); - debugLogger('EnclavedExpressClient initialized with URL: %s', this.baseUrl); + debugLogger('securedExpressClient initialized with URL: %s', this.baseUrl); } private createHttpsAgent(): https.Agent { @@ -260,8 +260,8 @@ export class EnclavedExpressClient { } return new https.Agent({ rejectUnauthorized: !this.allowSelfSigned, - ca: this.enclavedExpressCert, - // Use Master Express's own certificate as client cert when connecting to Enclaved Express + ca: this.securedExpressCert, + // Use Master Express's own certificate as client cert when connecting to secured Express key: this.tlsKey, cert: this.tlsCert, }); @@ -329,12 +329,12 @@ export class EnclavedExpressClient { } /** - * Ping the enclaved express service to check if it's available + * Ping the secured express service to check if it's available * @returns {Promise} */ async ping(): Promise { try { - debugLogger('Pinging enclaved express service at: %s', this.baseUrl); + debugLogger('Pinging secured express service at: %s', this.baseUrl); let request = this.apiClient['v1.health.ping'].post({}); if (this.tlsMode === TlsMode.MTLS) { @@ -343,21 +343,21 @@ export class EnclavedExpressClient { const response = await request.decodeExpecting(200); - debugLogger('Enclaved express service ping successful'); + debugLogger('secured express service ping successful'); return response.body; } catch (error) { const err = error as Error; - debugLogger('Enclaved express service ping failed: %s', err.message); + debugLogger('secured express service ping failed: %s', err.message); throw err; } } /** - * Get the version information from the enclaved express service + * Get the version information from the secured express service */ async getVersion(): Promise { try { - debugLogger('Getting version information from enclaved express service'); + debugLogger('Getting version information from secured express service'); let request = this.apiClient['v1.health.version'].get({}); if (this.tlsMode === TlsMode.MTLS) { @@ -752,17 +752,17 @@ export class EnclavedExpressClient { } /** - * Create an enclaved express client if the configuration is present + * Create an secured express client if the configuration is present */ -export function createEnclavedExpressClient( +export function createSecuredExpressClient( cfg: MasterExpressConfig, coin?: string, -): EnclavedExpressClient | undefined { +): SecuredExpressClient | undefined { try { - return new EnclavedExpressClient(cfg, coin); + return new SecuredExpressClient(cfg, coin); } catch (error) { const err = error as Error; - debugLogger('Failed to create enclaved express client: %s', err.message); + debugLogger('Failed to create SecuredExpressClient:', err.message); return undefined; } } diff --git a/src/api/master/handlerUtils.ts b/src/api/master/handlerUtils.ts index ed480dd..df91418 100644 --- a/src/api/master/handlerUtils.ts +++ b/src/api/master/handlerUtils.ts @@ -1,5 +1,5 @@ import { BitGo, CustomSigningFunction, RequestTracer } from 'bitgo'; -import { EnclavedExpressClient } from './clients/enclavedExpressClient'; +import { SecuredExpressClient } from './clients/securedExpressClient'; /** * Fetch wallet and signing keychain, with validation for source and pubkey. @@ -51,20 +51,20 @@ export async function getWalletAndSigningKeychain({ return { baseCoin, wallet, signingKeychain }; } /** - * Create a custom signing function that delegates to enclavedExpressClient.signMultisig. + * Create a custom signing function that delegates to securedExpressClient.signMultisig. */ export function makeCustomSigningFunction({ - enclavedExpressClient, + securedExpressClient, source, pub, }: { - enclavedExpressClient: EnclavedExpressClient; + securedExpressClient: SecuredExpressClient; source: 'user' | 'backup'; pub: string; }): CustomSigningFunction { return async function customSigningFunction(signParams: any) { - return enclavedExpressClient.signMultisig({ + return securedExpressClient.signMultisig({ txPrebuild: signParams.txPrebuild, source, pub, diff --git a/src/api/master/handlers/ecdsaMPCv2.ts b/src/api/master/handlers/ecdsaMPCv2.ts index 0ced479..1f8c398 100644 --- a/src/api/master/handlers/ecdsaMPCv2.ts +++ b/src/api/master/handlers/ecdsaMPCv2.ts @@ -8,17 +8,14 @@ import { Wallet, TxRequest, } from '@bitgo/sdk-core'; -import { - EnclavedExpressClient, - SignMpcV2Round1Response, - SignMpcV2Round2Response, -} from '../clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../clients/securedExpressClient'; +import { SignMpcV2Round1Response, SignMpcV2Round2Response } from '../clients/securedExpressClient'; /** - * Creates custom ECDSA MPCv2 signing functions for use with enclaved express client + * Creates custom ECDSA MPCv2 signing functions for use with secured express client */ export function createEcdsaMPCv2CustomSigners( - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, source: 'user' | 'backup', commonKeychain: string, ) { @@ -28,7 +25,7 @@ export function createEcdsaMPCv2CustomSigners( // Create custom signing methods that maintain state const customMPCv2Round1Generator = async (params: { txRequest: TxRequest }) => { - const response = await enclavedExpressClient.signMPCv2Round1(source, commonKeychain, params); + const response = await securedExpressClient.signMPCv2Round1(source, commonKeychain, params); round1Response = response; return response; }; @@ -42,7 +39,7 @@ export function createEcdsaMPCv2CustomSigners( if (!round1Response) { throw new Error('Round 1 must be completed before Round 2'); } - const response = await enclavedExpressClient.signMPCv2Round2(source, commonKeychain, { + const response = await securedExpressClient.signMPCv2Round2(source, commonKeychain, { ...params, encryptedDataKey: round1Response.encryptedDataKey, encryptedRound1Session: round1Response.encryptedRound1Session, @@ -62,7 +59,7 @@ export function createEcdsaMPCv2CustomSigners( if (!round2Response) { throw new Error('Round 2 must be completed before Round 3'); } - return await enclavedExpressClient.signMPCv2Round3(source, commonKeychain, { + return await securedExpressClient.signMPCv2Round3(source, commonKeychain, { ...params, encryptedDataKey: round1Response.encryptedDataKey, encryptedRound2Session: round2Response.encryptedRound2Session, @@ -82,7 +79,7 @@ export async function signAndSendEcdsaMPCv2FromTxRequest( bitgo: BitGoBase, wallet: Wallet, txRequest: TxRequest, - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, source: 'user' | 'backup', commonKeychain: string, reqId: IRequestTracer, @@ -91,7 +88,7 @@ export async function signAndSendEcdsaMPCv2FromTxRequest( // Use the shared custom signing functions const { customMPCv2Round1Generator, customMPCv2Round2Generator, customMPCv2Round3Generator } = - createEcdsaMPCv2CustomSigners(enclavedExpressClient, source, commonKeychain); + createEcdsaMPCv2CustomSigners(securedExpressClient, source, commonKeychain); // This also sends the TxRequest for broadcast return await ecdsaMPCv2Utils.signEcdsaMPCv2TssUsingExternalSigner( @@ -106,7 +103,7 @@ export async function signAndSendEcdsaMPCv2FromTxRequest( interface OrchestrateEcdsaKeyGenParams { bitgo: BitGoBase; baseCoin: BaseCoin; - enclavedExpressClient: EnclavedExpressClient; + securedExpressClient: SecuredExpressClient; enterprise: string; walletParams: SupplementGenerateWalletOptions; } @@ -114,7 +111,7 @@ interface OrchestrateEcdsaKeyGenParams { export async function orchestrateEcdsaKeyGen({ bitgo, baseCoin, - enclavedExpressClient, + securedExpressClient, enterprise, walletParams, }: OrchestrateEcdsaKeyGenParams) { @@ -125,7 +122,7 @@ export async function orchestrateEcdsaKeyGen({ const ecdsaUtils = new EcdsaMPCv2Utils(bitgo, baseCoin); // INITIALIZE ROUND: GENERATE ALL GPG KEYS AND RETRIEVE GPG PUBS FROM ALL PARTIES - const userInitResponse = await enclavedExpressClient.initEcdsaMpcV2KeyGenMpcV2({ + const userInitResponse = await securedExpressClient.initEcdsaMpcV2KeyGenMpcV2({ source: 'user', }); if ( @@ -135,7 +132,7 @@ export async function orchestrateEcdsaKeyGen({ ) { throw new Error('Missing required fields in user init response'); } - const backupInitResponse = await enclavedExpressClient.initEcdsaMpcV2KeyGenMpcV2({ + const backupInitResponse = await securedExpressClient.initEcdsaMpcV2KeyGenMpcV2({ source: 'backup', }); if ( @@ -147,7 +144,7 @@ export async function orchestrateEcdsaKeyGen({ } // ROUND 1 - const userRound1Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const userRound1Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'user', encryptedData: userInitResponse.encryptedData, encryptedDataKey: userInitResponse.encryptedDataKey, @@ -155,7 +152,7 @@ export async function orchestrateEcdsaKeyGen({ bitgoGpgPub: constants.mpc.bitgoMPCv2PublicKey, counterPartyGpgPub: backupInitResponse.gpgPub, }); - const backupRound1Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const backupRound1Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'backup', encryptedData: backupInitResponse.encryptedData, encryptedDataKey: backupInitResponse.encryptedDataKey, @@ -190,7 +187,7 @@ export async function orchestrateEcdsaKeyGen({ const { sessionId, bitgoMsg1, bitgoToUserMsg2, bitgoToBackupMsg2 } = round1And2BitGoResponse; // ROUND 2 - const userRound2Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const userRound2Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'user', encryptedData: userRound1Response.encryptedData, encryptedDataKey: userRound1Response.encryptedDataKey, @@ -200,7 +197,7 @@ export async function orchestrateEcdsaKeyGen({ counterParty: backupRound1Response.broadcastMessage, }, }); - const backupRound2Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const backupRound2Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'backup', encryptedData: backupRound1Response.encryptedData, encryptedDataKey: backupRound1Response.encryptedDataKey, @@ -222,7 +219,7 @@ export async function orchestrateEcdsaKeyGen({ } // ROUND 3 - const userRound3Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const userRound3Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'user', encryptedData: userRound2Response.encryptedData, encryptedDataKey: userRound2Response.encryptedDataKey, @@ -232,7 +229,7 @@ export async function orchestrateEcdsaKeyGen({ counterParty: backupRound2Response.p2pMessages?.counterParty, }, }); - const backupRound3Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const backupRound3Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'backup', encryptedData: backupRound2Response.encryptedData, encryptedDataKey: backupRound2Response.encryptedDataKey, @@ -271,7 +268,7 @@ export async function orchestrateEcdsaKeyGen({ } // ROUND 4 - const userRound4Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const userRound4Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'user', encryptedData: userRound3Response.encryptedData, encryptedDataKey: userRound3Response.encryptedDataKey, @@ -281,7 +278,7 @@ export async function orchestrateEcdsaKeyGen({ counterParty: backupRound3Response.p2pMessages?.counterParty, }, }); - const backupRound4Promise = enclavedExpressClient.roundEcdsaMPCv2KeyGen({ + const backupRound4Promise = securedExpressClient.roundEcdsaMPCv2KeyGen({ source: 'backup', encryptedData: backupRound3Response.encryptedData, encryptedDataKey: backupRound3Response.encryptedDataKey, @@ -318,7 +315,7 @@ export async function orchestrateEcdsaKeyGen({ bitgoMsg4, commonKeychain: bitgoCommonKeychain, } = round4BitGoResponse; - const userFinalizePromise = enclavedExpressClient.finalizeEcdsaMPCv2KeyGen({ + const userFinalizePromise = securedExpressClient.finalizeEcdsaMPCv2KeyGen({ source: 'user', encryptedData: userRound4Response.encryptedData, encryptedDataKey: userRound4Response.encryptedDataKey, @@ -328,7 +325,7 @@ export async function orchestrateEcdsaKeyGen({ }, bitgoCommonKeychain, }); - const backupFinalizePromise = enclavedExpressClient.finalizeEcdsaMPCv2KeyGen({ + const backupFinalizePromise = securedExpressClient.finalizeEcdsaMPCv2KeyGen({ source: 'backup', encryptedData: backupRound4Response.encryptedData, encryptedDataKey: backupRound4Response.encryptedDataKey, diff --git a/src/api/master/handlers/eddsa.ts b/src/api/master/handlers/eddsa.ts index 24f0eb6..52bb49d 100644 --- a/src/api/master/handlers/eddsa.ts +++ b/src/api/master/handlers/eddsa.ts @@ -14,13 +14,13 @@ import { CustomRShareGeneratingFunction, CustomGShareGeneratingFunction, } from '@bitgo/sdk-core'; -import { EnclavedExpressClient, SignMpcCommitmentResponse } from '../clients/enclavedExpressClient'; +import { SecuredExpressClient, SignMpcCommitmentResponse } from '../clients/securedExpressClient'; /** - * Creates custom EdDSA signing functions for use with enclaved express client + * Creates custom EdDSA signing functions for use with secured express client */ export function createEddsaCustomSigningFunctions( - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, source: 'user' | 'backup', commonKeychain: string, ): { @@ -39,7 +39,7 @@ export function createEddsaCustomSigningFunctions( if (!params.bitgoGpgPubKey) { throw new Error('bitgoGpgPubKey is required for commitment share generation'); } - const response = await enclavedExpressClient.signMpcCommitment({ + const response = await securedExpressClient.signMpcCommitment({ txRequest: params.txRequest, bitgoPublicGpgKey: params.bitgoGpgPubKey, source, @@ -56,7 +56,7 @@ export function createEddsaCustomSigningFunctions( if (!commitmentResponse) { throw new Error('Commitment must be completed before R-share generation'); } - const response = await enclavedExpressClient.signMpcRShare({ + const response = await securedExpressClient.signMpcRShare({ txRequest: params.txRequest, encryptedUserToBitgoRShare: params.encryptedUserToBitgoRShare, encryptedDataKey: commitmentResponse.encryptedDataKey, @@ -75,7 +75,7 @@ export function createEddsaCustomSigningFunctions( if (!commitmentResponse) { throw new Error('Commitment must be completed before G-share generation'); } - const response = await enclavedExpressClient.signMpcGShare({ + const response = await securedExpressClient.signMpcGShare({ txRequest: params.txRequest, bitgoToUserRShare: params.bitgoToUserRShare, userToBitgoRShare: params.userToBitgoRShare, @@ -97,13 +97,13 @@ export async function handleEddsaSigning( bitgo: BitGoBase, wallet: Wallet, txRequest: TxRequest, - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, commonKeychain: string, reqId?: IRequestTracer, ) { const eddsaUtils = new EddsaUtils(bitgo, wallet.baseCoin, wallet); const { customCommitmentGenerator, customRShareGenerator, customGShareGenerator } = - createEddsaCustomSigningFunctions(enclavedExpressClient, 'user', commonKeychain); + createEddsaCustomSigningFunctions(securedExpressClient, 'user', commonKeychain); return await eddsaUtils.signEddsaTssUsingExternalSigner( txRequest, customCommitmentGenerator, @@ -116,7 +116,7 @@ export async function handleEddsaSigning( interface OrchestrateEddsaKeyGenParams { bitgo: BitGoBase; baseCoin: BaseCoin; - enclavedExpressClient: EnclavedExpressClient; + securedExpressClient: SecuredExpressClient; enterprise: string; walletParams: any; } @@ -124,7 +124,7 @@ interface OrchestrateEddsaKeyGenParams { export async function orchestrateEddsaKeyGen({ bitgo, baseCoin, - enclavedExpressClient, + securedExpressClient, enterprise, walletParams, }: OrchestrateEddsaKeyGenParams) { @@ -133,11 +133,11 @@ export async function orchestrateEddsaKeyGen({ throw new Error('Unable to create MPC keys - bitgoPublicKey is missing in constants'); } // Initialize key generation for user and backup - const userInitResponse = await enclavedExpressClient.initMpcKeyGeneration({ + const userInitResponse = await securedExpressClient.initMpcKeyGeneration({ source: 'user', bitgoGpgKey: constants.mpc.bitgoPublicKey, }); - const backupInitResponse = await enclavedExpressClient.initMpcKeyGeneration({ + const backupInitResponse = await securedExpressClient.initMpcKeyGeneration({ source: 'backup', bitgoGpgKey: constants.mpc.bitgoPublicKey, userGpgKey: userInitResponse.bitgoPayload.gpgKey, @@ -167,7 +167,7 @@ export async function orchestrateEddsaKeyGen({ backupGPGPublicKey: backupGPGKey, }); // Finalize user and backup keychains - const userKeychainPromise = await enclavedExpressClient.finalizeMpcKeyGeneration({ + const userKeychainPromise = await securedExpressClient.finalizeMpcKeyGeneration({ source: 'user', coin: baseCoin.getFamily(), encryptedDataKey: userInitResponse.encryptedDataKey, @@ -194,7 +194,7 @@ export async function orchestrateEddsaKeyGen({ source: 'user', type: 'tss', }); - const backupKeychainPromise = await enclavedExpressClient.finalizeMpcKeyGeneration({ + const backupKeychainPromise = await securedExpressClient.finalizeMpcKeyGeneration({ source: 'backup', coin: baseCoin.getFamily(), encryptedDataKey: backupInitResponse.encryptedDataKey, diff --git a/src/api/master/handlers/generateWallet.ts b/src/api/master/handlers/generateWallet.ts index 1f9ec31..6092d3f 100644 --- a/src/api/master/handlers/generateWallet.ts +++ b/src/api/master/handlers/generateWallet.ts @@ -30,7 +30,7 @@ export async function handleGenerateWalletOnPrem( } /** - * This route is used to generate a multisig wallet when enclaved express is enabled + * This route is used to generate a multisig wallet when secured express is enabled */ async function handleGenerateOnPremOnChainWallet( req: MasterApiSpecRouteRequest<'v1.wallet.generate', 'post'>, @@ -38,8 +38,8 @@ async function handleGenerateOnPremOnChainWallet( const bitgo = req.bitgo; const baseCoin = bitgo.coin(req.params.coin); - // The enclavedExpressClient is now available from the request - const enclavedExpressClient = req.enclavedExpressClient; + // The securedExpressClient is now available from the request + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); @@ -64,7 +64,7 @@ async function handleGenerateOnPremOnChainWallet( } const userKeychainPromise = async (): Promise => { - const userKeychain = await enclavedExpressClient.createIndependentKeychain({ + const userKeychain = await securedExpressClient.createIndependentKeychain({ source: 'user', coin: req.params.coin, type: 'independent', @@ -81,7 +81,7 @@ async function handleGenerateOnPremOnChainWallet( }; const backupKeychainPromise = async (): Promise => { - const backupKeychain = await enclavedExpressClient.createIndependentKeychain({ + const backupKeychain = await securedExpressClient.createIndependentKeychain({ source: 'backup', coin: req.params.coin, type: 'independent', @@ -140,7 +140,7 @@ async function handleGenerateOnPremMpcWallet( ) { const bitgo = req.bitgo; const baseCoin = bitgo.coin(req.decoded.coin); - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; if (!baseCoin.supportsTss()) { throw new NotImplementedError( @@ -148,8 +148,8 @@ async function handleGenerateOnPremMpcWallet( ); } - if (!enclavedExpressClient) { - throw new Error('Enclaved express client is required for MPC wallet generation'); + if (!securedExpressClient) { + throw new Error('secured express client is required for MPC wallet generation'); } const reqId = new RequestTracer(); @@ -179,7 +179,7 @@ async function handleGenerateOnPremMpcWallet( orchestrateResult = await orchestrateEcdsaKeyGen({ bitgo, baseCoin, - enclavedExpressClient, + securedExpressClient, enterprise, walletParams, }); @@ -188,7 +188,7 @@ async function handleGenerateOnPremMpcWallet( orchestrateResult = await orchestrateEddsaKeyGen({ bitgo, baseCoin, - enclavedExpressClient, + securedExpressClient, walletParams, enterprise, }); diff --git a/src/api/master/handlers/handleAccelerate.ts b/src/api/master/handlers/handleAccelerate.ts index ec8d6f6..5973cd4 100644 --- a/src/api/master/handlers/handleAccelerate.ts +++ b/src/api/master/handlers/handleAccelerate.ts @@ -6,7 +6,7 @@ import { getWalletAndSigningKeychain, makeCustomSigningFunction } from '../handl export async function handleAccelerate( req: MasterApiSpecRouteRequest<'v1.wallet.accelerate', 'post'>, ) { - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); const bitgo = req.bitgo; const params = req.decoded; @@ -25,7 +25,7 @@ export async function handleAccelerate( try { // Create custom signing function that delegates to EBE const customSigningFunction = makeCustomSigningFunction({ - enclavedExpressClient, + securedExpressClient, source: params.source, pub: signingKeychain.pub!, }); diff --git a/src/api/master/handlers/handleConsolidate.ts b/src/api/master/handlers/handleConsolidate.ts index bd4f931..d09bebd 100644 --- a/src/api/master/handlers/handleConsolidate.ts +++ b/src/api/master/handlers/handleConsolidate.ts @@ -12,7 +12,7 @@ import { signAndSendTxRequests } from './transactionRequests'; export async function handleConsolidate( req: MasterApiSpecRouteRequest<'v1.wallet.consolidate', 'post'>, ) { - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); const bitgo = req.bitgo; const params = req.decoded; @@ -75,7 +75,7 @@ export async function handleConsolidate( })(), reqId, ), - enclavedExpressClient, + securedExpressClient, signingKeychain, reqId, ) @@ -83,7 +83,7 @@ export async function handleConsolidate( ...consolidationParams, prebuildTx: unsignedBuild, customSigningFunction: makeCustomSigningFunction({ - enclavedExpressClient, + securedExpressClient, source: params.source, pub: signingKeychain.pub!, }), diff --git a/src/api/master/handlers/handleConsolidateUnspents.ts b/src/api/master/handlers/handleConsolidateUnspents.ts index e201162..a8cad5c 100644 --- a/src/api/master/handlers/handleConsolidateUnspents.ts +++ b/src/api/master/handlers/handleConsolidateUnspents.ts @@ -6,7 +6,7 @@ import { getWalletAndSigningKeychain, makeCustomSigningFunction } from '../handl export async function handleConsolidateUnspents( req: MasterApiSpecRouteRequest<'v1.wallet.consolidateunspents', 'post'>, ) { - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); const bitgo = req.bitgo; const params = req.decoded; @@ -25,7 +25,7 @@ export async function handleConsolidateUnspents( try { // Create custom signing function that delegates to EBE const customSigningFunction = makeCustomSigningFunction({ - enclavedExpressClient, + securedExpressClient, source: params.source, pub: signingKeychain.pub!, }); diff --git a/src/api/master/handlers/handleSendMany.ts b/src/api/master/handlers/handleSendMany.ts index 56fd042..07780ee 100644 --- a/src/api/master/handlers/handleSendMany.ts +++ b/src/api/master/handlers/handleSendMany.ts @@ -11,7 +11,7 @@ import { import logger from '../../../logger'; import { MasterApiSpecRouteRequest } from '../routers/masterApiSpec'; import { createEcdsaMPCv2CustomSigners } from './ecdsaMPCv2'; -import { EnclavedExpressClient } from '../clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../clients/securedExpressClient'; import { createEddsaCustomSigningFunctions } from './eddsa'; import { BadRequestError, NotFoundError } from '../../../shared/errors'; @@ -33,7 +33,7 @@ interface Recipient { */ function createMPCSendParamsWithCustomSigningFns( req: MasterApiSpecRouteRequest<'v1.wallet.sendMany', 'post'>, - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, signingKeychain: Keychain, ): SendManyOptions { const coin = req.bitgo.coin(req.params.coin); @@ -47,7 +47,7 @@ function createMPCSendParamsWithCustomSigningFns( if (mpcAlgorithm === 'ecdsa') { const { customMPCv2Round1Generator, customMPCv2Round2Generator, customMPCv2Round3Generator } = - createEcdsaMPCv2CustomSigners(enclavedExpressClient, source, commonKeychain); + createEcdsaMPCv2CustomSigners(securedExpressClient, source, commonKeychain); return { ...(req.decoded as SendManyOptions), @@ -57,7 +57,7 @@ function createMPCSendParamsWithCustomSigningFns( }; } else if (mpcAlgorithm === 'eddsa') { const { customCommitmentGenerator, customRShareGenerator, customGShareGenerator } = - createEddsaCustomSigningFunctions(enclavedExpressClient, source, commonKeychain); + createEddsaCustomSigningFunctions(securedExpressClient, source, commonKeychain); return { ...(req.decoded as SendManyOptions), @@ -71,7 +71,7 @@ function createMPCSendParamsWithCustomSigningFns( } export async function handleSendMany(req: MasterApiSpecRouteRequest<'v1.wallet.sendMany', 'post'>) { - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); const bitgo = req.bitgo; const baseCoin = bitgo.coin(req.params.coin); @@ -120,7 +120,7 @@ export async function handleSendMany(req: MasterApiSpecRouteRequest<'v1.wallet.s } const mpcSendParams = createMPCSendParamsWithCustomSigningFns( req, - enclavedExpressClient, + securedExpressClient, signingKeychain, ); return wallet.sendMany(mpcSendParams); @@ -170,7 +170,7 @@ export async function handleSendMany(req: MasterApiSpecRouteRequest<'v1.wallet.s req.decoded.source, txPrebuilt, prebuildParams, - enclavedExpressClient, + securedExpressClient, signingKeychain, reqId, ); @@ -186,7 +186,7 @@ export async function signAndSendMultisig( source: 'user' | 'backup', txPrebuilt: PrebuildTransactionResult, params: SendManyOptions, - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, signingKeychain: Keychain, reqId: RequestTracer, ) { @@ -196,8 +196,8 @@ export async function signAndSendMultisig( logger.info(`Signing with ${source} keychain, pub: ${signingKeychain.pub}`); logger.debug(`Signing keychain: ${JSON.stringify(signingKeychain, null, 2)}`); - // Then sign it using the enclaved express client - const signedTx = await enclavedExpressClient.signMultisig({ + // Then sign it using the secured express client + const signedTx = await securedExpressClient.signMultisig({ txPrebuild: txPrebuilt, source: source, pub: signingKeychain.pub, diff --git a/src/api/master/handlers/handleSignAndSendTxRequest.ts b/src/api/master/handlers/handleSignAndSendTxRequest.ts index cbfa674..6cab5e5 100644 --- a/src/api/master/handlers/handleSignAndSendTxRequest.ts +++ b/src/api/master/handlers/handleSignAndSendTxRequest.ts @@ -6,7 +6,7 @@ import { MasterApiSpecRouteRequest } from '../routers/masterApiSpec'; export async function handleSignAndSendTxRequest( req: MasterApiSpecRouteRequest<'v1.wallet.txrequest.signAndSend', 'post'>, ) { - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const reqId = new RequestTracer(); const bitgo = req.bitgo; const baseCoin = bitgo.coin(req.params.coin); @@ -55,7 +55,7 @@ export async function handleSignAndSendTxRequest( bitgo, wallet, txRequest, - enclavedExpressClient, + securedExpressClient, signingKeychain, reqId, ); diff --git a/src/api/master/handlers/recoveryConsolidationsWallet.ts b/src/api/master/handlers/recoveryConsolidationsWallet.ts index a81f521..fedb296 100644 --- a/src/api/master/handlers/recoveryConsolidationsWallet.ts +++ b/src/api/master/handlers/recoveryConsolidationsWallet.ts @@ -69,7 +69,7 @@ export async function handleRecoveryConsolidationsOnPrem( ) { const bitgo = req.bitgo; const coin = req.decoded.coin; - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const isMPC = req.decoded.multisigType === 'tss'; @@ -117,7 +117,7 @@ export async function handleRecoveryConsolidationsOnPrem( try { for (const tx of txs) { const signedTx = isMPC - ? await enclavedExpressClient.recoveryMPC({ + ? await securedExpressClient.recoveryMPC({ userPub, backupPub, apiKey, @@ -125,7 +125,7 @@ export async function handleRecoveryConsolidationsOnPrem( coinSpecificParams: {}, walletContractAddress: '', }) - : await enclavedExpressClient.recoveryMultisig({ + : await securedExpressClient.recoveryMultisig({ userPub, backupPub, unsignedSweepPrebuildTx: tx as RecoveryTransaction, diff --git a/src/api/master/handlers/recoveryWallet.ts b/src/api/master/handlers/recoveryWallet.ts index 91745a3..7e9b11b 100644 --- a/src/api/master/handlers/recoveryWallet.ts +++ b/src/api/master/handlers/recoveryWallet.ts @@ -17,7 +17,7 @@ import { getReplayProtectionOptions, } from '../../../shared/recoveryUtils'; -import { EnclavedExpressClient } from '../clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../clients/securedExpressClient'; import { CoinSpecificParams, EvmRecoveryOptions, @@ -40,7 +40,7 @@ interface RecoveryParams { apiKey: string; } -interface EnclavedRecoveryParams { +interface securedRecoveryParams { userPub: string; backupPub: string; apiKey: string; @@ -72,8 +72,8 @@ function validateRecoveryParams(sdkCoin: BaseCoin, params?: CoinSpecificParams) async function handleEthLikeRecovery( sdkCoin: BaseCoin, commonRecoveryParams: RecoveryParams, - enclavedExpressClient: any, - params: EnclavedRecoveryParams, + securedExpressClient: any, + params: securedRecoveryParams, env: EnvironmentName, ) { try { @@ -89,7 +89,7 @@ async function handleEthLikeRecovery( replayProtectionOptions: getReplayProtectionOptions(env), }); - const fullSignedRecoveryTx = await enclavedExpressClient.recoveryMultisig({ + const fullSignedRecoveryTx = await securedExpressClient.recoveryMultisig({ ...params, unsignedSweepPrebuildTx, }); @@ -104,8 +104,8 @@ async function handleEddsaRecovery( bitgo: BitGoAPI, sdkCoin: BaseCoin, commonRecoveryParams: RecoveryParams, - enclavedExpressClient: EnclavedExpressClient, - params: EnclavedRecoveryParams, + securedExpressClient: SecuredExpressClient, + params: securedRecoveryParams, ) { const { recoveryDestination, userKey } = commonRecoveryParams; try { @@ -135,7 +135,7 @@ async function handleEddsaRecovery( } logger.info('Unsigned sweep tx: ', JSON.stringify(unsignedSweepPrebuildTx, null, 2)); - return await enclavedExpressClient.recoveryMPC({ + return await securedExpressClient.recoveryMPC({ userPub: params.userPub, backupPub: params.backupPub, apiKey: params.apiKey, @@ -162,7 +162,7 @@ export type UtxoCoinSpecificRecoveryParams = Pick< async function handleUtxoLikeRecovery( sdkCoin: BaseCoin, - enclavedClient: EnclavedExpressClient, + securedClient: SecuredExpressClient, recoveryParams: UtxoCoinSpecificRecoveryParams, ): Promise<{ txHex: string }> { const abstractUtxoCoin = sdkCoin as unknown as AbstractUtxoCoin; @@ -173,7 +173,7 @@ async function handleUtxoLikeRecovery( throw new MethodNotImplementedError(`Unknown transaction ${JSON.stringify(recoverTx)} created`); } - return (await enclavedClient.recoveryMultisig({ + return (await securedClient.recoveryMultisig({ userPub: recoveryParams.userKey, backupPub: recoveryParams.backupKey, bitgoPub: recoveryParams.bitgoKey, @@ -187,7 +187,7 @@ export async function handleRecoveryWalletOnPrem( ) { const bitgo = req.bitgo; const coin = req.decoded.coin; - const enclavedExpressClient = req.enclavedExpressClient; + const securedExpressClient = req.securedExpressClient; const { recoveryDestinationAddress, coinSpecificParams } = req.decoded; const sdkCoin = bitgo.coin(coin); @@ -213,7 +213,7 @@ export async function handleRecoveryWalletOnPrem( recoveryDestination: recoveryDestinationAddress, apiKey: req.decoded.apiKey || '', }, - enclavedExpressClient, + securedExpressClient, { userPub: commonKeychain, backupPub: commonKeychain, @@ -265,7 +265,7 @@ export async function handleRecoveryWalletOnPrem( return handleEthLikeRecovery( sdkCoin, commonRecoveryParams, - enclavedExpressClient, + securedExpressClient, { userPub, backupPub, @@ -282,7 +282,7 @@ export async function handleRecoveryWalletOnPrem( } if (isUtxoCoin(sdkCoin)) { - return handleUtxoLikeRecovery(sdkCoin, req.enclavedExpressClient, { + return handleUtxoLikeRecovery(sdkCoin, req.securedExpressClient, { userKey: userPub, backupKey: backupPub, bitgoKey: bitgoPub, diff --git a/src/api/master/handlers/transactionRequests.ts b/src/api/master/handlers/transactionRequests.ts index 242d8dc..ce56e68 100644 --- a/src/api/master/handlers/transactionRequests.ts +++ b/src/api/master/handlers/transactionRequests.ts @@ -6,7 +6,7 @@ import { TxRequest, Wallet, } from '@bitgo/sdk-core'; -import { EnclavedExpressClient } from '../clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../clients/securedExpressClient'; import { handleEddsaSigning } from './eddsa'; import { signAndSendEcdsaMPCv2FromTxRequest } from './ecdsaMPCv2'; @@ -16,7 +16,7 @@ import { signAndSendEcdsaMPCv2FromTxRequest } from './ecdsaMPCv2'; * @param bitgo - BitGo instance * @param wallet - Wallet instance * @param txRequestId - Transaction request ID - * @param enclavedExpressClient - Enclaved express client + * @param securedExpressClient - secured express client * @param signingKeychain - Signing keychain * @param reqId - Request tracer */ @@ -24,7 +24,7 @@ export async function signAndSendTxRequests( bitgo: BitGoBase, wallet: Wallet, txRequest: TxRequest, - enclavedExpressClient: EnclavedExpressClient, + securedExpressClient: SecuredExpressClient, signingKeychain: Keychain, reqId: RequestTracer, ): Promise { @@ -40,7 +40,7 @@ export async function signAndSendTxRequests( bitgo, wallet, txRequest, - enclavedExpressClient, + securedExpressClient, signingKeychain.commonKeychain, reqId, ); @@ -49,7 +49,7 @@ export async function signAndSendTxRequests( bitgo, wallet, txRequest, - enclavedExpressClient, + securedExpressClient, signingKeychain.source as 'user' | 'backup', signingKeychain.commonKeychain, reqId, diff --git a/src/api/master/middleware/middleware.ts b/src/api/master/middleware/middleware.ts index d42b96b..15b27fe 100644 --- a/src/api/master/middleware/middleware.ts +++ b/src/api/master/middleware/middleware.ts @@ -1,10 +1,10 @@ import { Request, Response, NextFunction } from 'express'; import { isMasterExpressConfig } from '../../../shared/types'; -import { createEnclavedExpressClient } from '../clients/enclavedExpressClient'; +import { createSecuredExpressClient } from '../clients/securedExpressClient'; import { BitGoRequest } from '../../../types/request'; /** - * Middleware to validate master express configuration and enclaved express client + * Middleware to validate master express configuration and secured express client */ export function validateMasterExpressConfig(req: Request, res: Response, next: NextFunction) { const bitgoReq = req as BitGoRequest; @@ -17,16 +17,16 @@ export function validateMasterExpressConfig(req: Request, res: Response, next: N }); } - // Validate enclaved express client - const enclavedExpressClient = createEnclavedExpressClient(bitgoReq.config, bitgoReq.params?.coin); - if (!enclavedExpressClient) { + // Validate secured express client + const securedExpressClient = createSecuredExpressClient(bitgoReq.config, bitgoReq.params?.coin); + if (!securedExpressClient) { return res.status(500).json({ - error: 'Please configure enclaved express configs.', - details: 'Enclaved express features will be disabled', + error: 'Please configure secured express configs.', + details: 'Secured express features will be disabled', }); } // Attach the client to the request for use in route handlers - bitgoReq.enclavedExpressClient = enclavedExpressClient; + bitgoReq.securedExpressClient = securedExpressClient; next(); } diff --git a/src/api/master/routers/index.ts b/src/api/master/routers/index.ts index 4ea8182..bb55183 100644 --- a/src/api/master/routers/index.ts +++ b/src/api/master/routers/index.ts @@ -1,13 +1,13 @@ import { apiSpec } from '@api-ts/io-ts-http'; import { HealthCheckApiSpec } from './healthCheck'; import { MasterApiSpec } from './masterApiSpec'; -import { EnclavedExpressApiSpec } from './enclavedExpressHealth'; +import { securedExpressApiSpec } from './securedExpressHealth'; // Combine all API specifications const combinedSpec = apiSpec({ ...HealthCheckApiSpec, ...MasterApiSpec, - ...EnclavedExpressApiSpec, + ...securedExpressApiSpec, }); export const FullApiSpec = combinedSpec; diff --git a/src/api/master/routers/enclavedExpressHealth.ts b/src/api/master/routers/securedExpressHealth.ts similarity index 51% rename from src/api/master/routers/enclavedExpressHealth.ts rename to src/api/master/routers/securedExpressHealth.ts index 31ab8ea..aff3246 100644 --- a/src/api/master/routers/enclavedExpressHealth.ts +++ b/src/api/master/routers/securedExpressHealth.ts @@ -5,14 +5,14 @@ import { Response } from '@api-ts/response'; import { MasterExpressConfig } from '../../../shared/types'; import logger from '../../../logger'; import { responseHandler } from '../../../shared/middleware'; -import { EnclavedExpressClient } from '../clients/enclavedExpressClient'; +import { SecuredExpressClient } from '../clients/securedExpressClient'; import { PingResponseType, VersionResponseType } from '../../../types/health'; -// Response type for /ping/enclavedExpress endpoint -const PingEnclavedResponse: HttpResponse = { +// Response type for /ping/securedExpress endpoint +export const PingSecuredResponse: HttpResponse = { 200: t.type({ status: t.string, - enclavedResponse: PingResponseType, + securedResponse: PingResponseType, }), 500: t.type({ error: t.string, @@ -20,7 +20,7 @@ const PingEnclavedResponse: HttpResponse = { }), }; -const VersionEnclavedResponse: HttpResponse = { +export const VersionSecuredResponse: HttpResponse = { 200: VersionResponseType, 500: t.type({ error: t.string, @@ -29,78 +29,75 @@ const VersionEnclavedResponse: HttpResponse = { }; // API Specification -export const EnclavedExpressApiSpec = apiSpec({ - 'v1.enclaved.ping': { +export const securedExpressApiSpec = apiSpec({ + 'v1.secured.ping': { post: httpRoute({ method: 'POST', - path: '/ping/enclavedExpress', + path: '/ping/securedExpress', request: httpRequest({}), - response: PingEnclavedResponse, - description: 'Ping the enclaved express server', + response: PingSecuredResponse, + description: 'Ping the secured express server', }), }, - 'v1.enclaved.version': { + 'v1.secured.version': { get: httpRoute({ method: 'GET', - path: '/version/enclavedExpress', + path: '/version/securedExpress', request: httpRequest({}), - response: VersionEnclavedResponse, - description: 'Get the version of the enclaved express server', + response: VersionSecuredResponse, + description: 'Get the version of the secured express server', }), }, }); // Create router with handlers -export function createEnclavedExpressRouter( +export function createSecuredExpressRouter( cfg: MasterExpressConfig, -): WrappedRouter { - const router = createRouter(EnclavedExpressApiSpec); +): WrappedRouter { + const router = createRouter(securedExpressApiSpec); - // Create an instance of EnclavedExpressClient - const enclavedClient = new EnclavedExpressClient(cfg); + // Create an instance of securedExpressClient + const securedExpressClient = new SecuredExpressClient(cfg); // Ping endpoint handler - router.post('v1.enclaved.ping', [ + router.post('v1.secured.ping', [ responseHandler(async () => { - logger.debug('Pinging enclaved express'); + logger.debug('Pinging secured express'); try { // Use the client's ping method instead of direct HTTP request - const pingResponse = await enclavedClient.ping(); + const pingResponse = await securedExpressClient.ping(); return Response.ok({ - status: 'Successfully pinged enclaved express', - enclavedResponse: { - status: pingResponse.status, - timestamp: pingResponse.timestamp, - }, + status: 'Successfully pinged secured express', + securedResponse: pingResponse, }); } catch (error) { - logger.error('Failed to ping enclaved express:', { error }); + logger.error('Failed to ping secured express:', { error }); return Response.internalError({ - error: 'Failed to ping enclaved express', + error: 'Failed to ping secured express', details: error instanceof Error ? error.message : String(error), }); } }), ]); - router.get('v1.enclaved.version', [ + router.get('v1.secured.version', [ responseHandler(async () => { - logger.debug('Getting version from enclaved express'); + logger.debug('Getting version from secured express'); try { // Use the client's getVersion method instead of direct HTTP request - const versionResponse = await enclavedClient.getVersion(); + const versionResponse = await securedExpressClient.getVersion(); return Response.ok({ version: versionResponse.version, name: versionResponse.name, }); } catch (error) { - logger.error('Failed to get version from enclaved express:', { error }); + logger.error('Failed to get version from secured express:', { error }); return Response.internalError({ - error: 'Failed to get version from enclaved express', + error: 'Failed to get version from secured express', details: error instanceof Error ? error.message : String(error), }); } diff --git a/src/api/enclaved/handlers/ecdsaMPCv2Finalize.ts b/src/api/secured/handlers/ecdsaMPCv2Finalize.ts similarity index 93% rename from src/api/enclaved/handlers/ecdsaMPCv2Finalize.ts rename to src/api/secured/handlers/ecdsaMPCv2Finalize.ts index 27b3922..9eb4e7e 100644 --- a/src/api/enclaved/handlers/ecdsaMPCv2Finalize.ts +++ b/src/api/secured/handlers/ecdsaMPCv2Finalize.ts @@ -1,14 +1,14 @@ import { DklsComms, DklsDkg, DklsTypes } from '@bitgo-beta/sdk-lib-mpc'; import { - EnclavedApiSpecRouteRequest, + SecuredExpressApiSpecRouteRequest, MpcV2FinalizeResponseType, MpcV2RoundState, -} from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { KmsClient } from '../../../kms/kmsClient'; import assert from 'assert'; export async function ecdsaMPCv2Finalize( - req: EnclavedApiSpecRouteRequest<'v1.mpcv2.finalize', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.mpcv2.finalize', 'post'>, ): Promise { const { source, encryptedData, encryptedDataKey, broadcastMessages, bitgoCommonKeychain } = req.decoded; diff --git a/src/api/enclaved/handlers/ecdsaMPCv2Initialize.ts b/src/api/secured/handlers/ecdsaMPCv2Initialize.ts similarity index 88% rename from src/api/enclaved/handlers/ecdsaMPCv2Initialize.ts rename to src/api/secured/handlers/ecdsaMPCv2Initialize.ts index 6a053fc..14ff4ba 100644 --- a/src/api/enclaved/handlers/ecdsaMPCv2Initialize.ts +++ b/src/api/secured/handlers/ecdsaMPCv2Initialize.ts @@ -1,15 +1,15 @@ import { - EnclavedApiSpecRouteRequest, + SecuredExpressApiSpecRouteRequest, MpcV2InitializeResponseType, MpcV2RoundState, -} from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { KmsClient } from '../../../kms/kmsClient'; import * as bitgoSdk from '@bitgo/sdk-core'; import logger from '../../../logger'; import { MPCv2PartiesEnum } from '@bitgo/sdk-core/dist/src/bitgo/utils/tss/ecdsa'; export async function ecdsaMPCv2Initialize( - req: EnclavedApiSpecRouteRequest<'v1.mpcv2.initialize', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.mpcv2.initialize', 'post'>, ): Promise { const { source } = req.decoded; diff --git a/src/api/enclaved/handlers/ecdsaMPCv2Round.ts b/src/api/secured/handlers/ecdsaMPCv2Round.ts similarity index 97% rename from src/api/enclaved/handlers/ecdsaMPCv2Round.ts rename to src/api/secured/handlers/ecdsaMPCv2Round.ts index 54c2621..4221a6a 100644 --- a/src/api/enclaved/handlers/ecdsaMPCv2Round.ts +++ b/src/api/secured/handlers/ecdsaMPCv2Round.ts @@ -1,14 +1,14 @@ import { DklsComms, DklsDkg, DklsTypes } from '@bitgo-beta/sdk-lib-mpc'; import { - EnclavedApiSpecRouteRequest, + SecuredExpressApiSpecRouteRequest, MpcV2RoundResponseType, MpcV2RoundState, -} from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { MPCv2PartiesEnum } from '@bitgo/sdk-core/dist/src/bitgo/utils/tss/ecdsa'; import { KmsClient } from '../../../kms/kmsClient'; export async function ecdsaMPCv2Round( - req: EnclavedApiSpecRouteRequest<'v1.mpcv2.round', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.mpcv2.round', 'post'>, ): Promise { const { source, encryptedData, encryptedDataKey, round, broadcastMessages, p2pMessages } = req.decoded; diff --git a/src/api/enclaved/handlers/postIndependentKey.ts b/src/api/secured/handlers/postIndependentKey.ts similarity index 83% rename from src/api/enclaved/handlers/postIndependentKey.ts rename to src/api/secured/handlers/postIndependentKey.ts index 8ba4871..96e5445 100644 --- a/src/api/enclaved/handlers/postIndependentKey.ts +++ b/src/api/secured/handlers/postIndependentKey.ts @@ -1,9 +1,9 @@ import { BitGo } from 'bitgo'; import { KmsClient } from '../../../kms/kmsClient'; -import { EnclavedApiSpecRouteRequest } from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +import { SecuredExpressApiSpecRouteRequest } from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; export async function postIndependentKey( - req: EnclavedApiSpecRouteRequest<'v1.key.independent', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.key.independent', 'post'>, ) { const { source, seed }: { source: string; seed?: string } = req.decoded; if (!source) { diff --git a/src/api/enclaved/handlers/recoveryMultisigTransaction.ts b/src/api/secured/handlers/recoveryMultisigTransaction.ts similarity index 97% rename from src/api/enclaved/handlers/recoveryMultisigTransaction.ts rename to src/api/secured/handlers/recoveryMultisigTransaction.ts index 9c7e3da..5ed20b1 100644 --- a/src/api/enclaved/handlers/recoveryMultisigTransaction.ts +++ b/src/api/secured/handlers/recoveryMultisigTransaction.ts @@ -1,7 +1,7 @@ import { SignFinalOptions } from '@bitgo/abstract-eth'; import { AbstractUtxoCoin } from '@bitgo/abstract-utxo'; import { HalfSignedUtxoTransaction, MethodNotImplementedError, TransactionRecipient } from 'bitgo'; -import { EnclavedApiSpecRouteRequest } from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +import { SecuredExpressApiSpecRouteRequest } from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { EnvironmentName } from '../../../initConfig'; import logger from '../../../logger'; import { @@ -18,7 +18,7 @@ import { SignedEthLikeRecoveryTx } from '../../../types/transaction'; import { retrieveKmsPrvKey } from '../utils'; export async function recoveryMultisigTransaction( - req: EnclavedApiSpecRouteRequest<'v1.multisig.recovery', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.multisig.recovery', 'post'>, ): Promise { const { userPub, backupPub, bitgoPub, unsignedSweepPrebuildTx, walletContractAddress, coin } = req.decoded; diff --git a/src/api/enclaved/handlers/signEddsaRecoveryTransaction.ts b/src/api/secured/handlers/signEddsaRecoveryTransaction.ts similarity index 97% rename from src/api/enclaved/handlers/signEddsaRecoveryTransaction.ts rename to src/api/secured/handlers/signEddsaRecoveryTransaction.ts index 183fa44..d14cd69 100644 --- a/src/api/enclaved/handlers/signEddsaRecoveryTransaction.ts +++ b/src/api/secured/handlers/signEddsaRecoveryTransaction.ts @@ -11,7 +11,7 @@ import { Ed25519Bip32HdTree } from '@bitgo/sdk-lib-mpc'; import { CoinFamily, coins } from '@bitgo/statics'; import { type KeyPair as SolKeyPair } from '@bitgo/sdk-coin-sol'; import { retrieveKmsPrvKey } from '../utils'; -import { EnclavedConfig } from '../../../shared/types'; +import { SecuredExpressConfig } from '../../../shared/types'; import logger from '../../../logger'; async function setupTransactionBuilder( @@ -75,7 +75,7 @@ export type SignEddsaRecoveryTransactionParams = { signableHex: string; derivationPath: string; }; - cfg: EnclavedConfig; + cfg: SecuredExpressConfig; coin: BaseCoin; }; diff --git a/src/api/enclaved/handlers/signMpcTransaction.ts b/src/api/secured/handlers/signMpcTransaction.ts similarity index 96% rename from src/api/enclaved/handlers/signMpcTransaction.ts rename to src/api/secured/handlers/signMpcTransaction.ts index 345d44e..846caff 100644 --- a/src/api/enclaved/handlers/signMpcTransaction.ts +++ b/src/api/secured/handlers/signMpcTransaction.ts @@ -1,4 +1,4 @@ -import { EnclavedApiSpecRouteRequest } from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +import { SecuredExpressApiSpecRouteRequest } from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; import { decryptDataKey, generateDataKey, retrieveKmsPrvKey } from '../utils'; import logger from '../../../logger'; import { @@ -11,7 +11,7 @@ import { SignatureShareRecord, GShare, } from '@bitgo/sdk-core'; -import { EnclavedConfig } from '../../../shared/types'; +import { SecuredExpressConfig } from '../../../shared/types'; import { BitGoBase, BaseCoin } from 'bitgo'; // Define share types for different MPC algorithms @@ -84,7 +84,9 @@ interface EcdsaSigningParams { encryptedRound2Session?: string; } -export async function signMpcTransaction(req: EnclavedApiSpecRouteRequest<'v1.mpc.sign', 'post'>) { +export async function signMpcTransaction( + req: SecuredExpressApiSpecRouteRequest<'v1.mpc.sign', 'post'>, +) { const { source, pub, coin, encryptedDataKey, shareType } = req.decoded; const bitgo = req.bitgo; @@ -144,7 +146,7 @@ export async function signMpcTransaction(req: EnclavedApiSpecRouteRequest<'v1.mp async function handleEddsaSigning( bitgo: BitGoBase, - cfg: EnclavedConfig, + cfg: SecuredExpressConfig, params: EddsaSigningParams, ): Promise<{ userToBitgoCommitment?: CommitmentShareRecord; @@ -233,7 +235,7 @@ async function handleEddsaSigning( async function handleEcdsaMpcV2Signing( bitgo: BitGoBase, - cfg: EnclavedConfig, + cfg: SecuredExpressConfig, params: EcdsaSigningParams, ): Promise { const { coin, shareType } = params; diff --git a/src/api/enclaved/handlers/signMultisigTransaction.ts b/src/api/secured/handlers/signMultisigTransaction.ts similarity index 87% rename from src/api/enclaved/handlers/signMultisigTransaction.ts rename to src/api/secured/handlers/signMultisigTransaction.ts index 1d6ea3d..d795775 100644 --- a/src/api/enclaved/handlers/signMultisigTransaction.ts +++ b/src/api/secured/handlers/signMultisigTransaction.ts @@ -1,10 +1,10 @@ import { KmsClient } from '../../../kms/kmsClient'; import { TransactionPrebuild } from 'bitgo'; import logger from '../../../logger'; -import { EnclavedApiSpecRouteRequest } from '../../../enclavedBitgoExpress/routers/enclavedApiSpec'; +import { SecuredExpressApiSpecRouteRequest } from '../../../securedBitgoExpress/routers/securedExpressApiSpec'; export async function signMultisigTransaction( - req: EnclavedApiSpecRouteRequest<'v1.multisig.sign', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.multisig.sign', 'post'>, ): Promise { const { source, diff --git a/src/api/enclaved/mpcFinalize.ts b/src/api/secured/mpcFinalize.ts similarity index 95% rename from src/api/enclaved/mpcFinalize.ts rename to src/api/secured/mpcFinalize.ts index 627052c..f01989b 100644 --- a/src/api/enclaved/mpcFinalize.ts +++ b/src/api/secured/mpcFinalize.ts @@ -2,16 +2,16 @@ import debug from 'debug'; import * as bitgoSdk from '@bitgo/sdk-core'; import { - EnclavedApiSpecRouteRequest, + SecuredExpressApiSpecRouteRequest, MpcFinalizeRequestType, -} from '../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../securedBitgoExpress/routers/securedExpressApiSpec'; import { KmsClient } from '../../kms/kmsClient'; import { gpgDecrypt, gpgEncrypt } from './utils'; -const debugLogger = debug('bitgo:enclavedBitGoExpress:mpcFinalize'); +const debugLogger = debug('bitgo:securedBitGoExpress:mpcFinalize'); export async function eddsaFinalize( - req: EnclavedApiSpecRouteRequest<'v1.mpc.key.finalize', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.mpc.key.finalize', 'post'>, ) { // request parsing const { diff --git a/src/api/enclaved/mpcInitialize.ts b/src/api/secured/mpcInitialize.ts similarity index 94% rename from src/api/enclaved/mpcInitialize.ts rename to src/api/secured/mpcInitialize.ts index bd70684..10246dc 100644 --- a/src/api/enclaved/mpcInitialize.ts +++ b/src/api/secured/mpcInitialize.ts @@ -3,16 +3,16 @@ import * as bitgoSdk from '@bitgo/sdk-core'; import { assert } from 'console'; import { KmsClient } from '../../kms/kmsClient'; import { - EnclavedApiSpecRouteRequest, + SecuredExpressApiSpecRouteRequest, KeyShareType, MpcInitializeRequestType, -} from '../../enclavedBitgoExpress/routers/enclavedApiSpec'; +} from '../../securedBitgoExpress/routers/securedExpressApiSpec'; import { gpgEncrypt } from './utils'; -const debugLogger = debug('bitgo:enclavedExpress:mpcInitialize'); +const debugLogger = debug('bitgo:securedExpress:mpcInitialize'); export async function eddsaInitialize( - req: EnclavedApiSpecRouteRequest<'v1.mpc.key.initialize', 'post'>, + req: SecuredExpressApiSpecRouteRequest<'v1.mpc.key.initialize', 'post'>, ) { // request parsing. counterPartyGpgPub can be undefined const { source, bitgoGpgPub, counterPartyGpgPub }: MpcInitializeRequestType = req.decoded; diff --git a/src/api/enclaved/utils.ts b/src/api/secured/utils.ts similarity index 95% rename from src/api/enclaved/utils.ts rename to src/api/secured/utils.ts index 0c7be40..e58c82f 100644 --- a/src/api/enclaved/utils.ts +++ b/src/api/secured/utils.ts @@ -2,7 +2,7 @@ import { createMessage, decrypt, encrypt, readKey, readMessage, readPrivateKey } import { KmsClient } from '../../kms/kmsClient'; import { GenerateDataKeyResponse } from '../../kms/types/dataKey'; -import { EnclavedConfig } from '../../shared/types'; +import { SecuredExpressConfig } from '../../shared/types'; export async function retrieveKmsPrvKey({ pub, @@ -12,7 +12,7 @@ export async function retrieveKmsPrvKey({ }: { pub: string; source: string; - cfg: EnclavedConfig; + cfg: SecuredExpressConfig; options?: { useLocalEncipherment?: boolean; }; @@ -85,7 +85,7 @@ export async function generateDataKey({ cfg, }: { keyType: 'AES-256' | 'RSA-2048' | 'ECDSA-P256'; - cfg: EnclavedConfig; + cfg: SecuredExpressConfig; }): Promise { try { const kms = new KmsClient(cfg); @@ -103,7 +103,7 @@ export async function decryptDataKey({ cfg, }: { encryptedDataKey: string; - cfg: EnclavedConfig; + cfg: SecuredExpressConfig; }): Promise { try { const kms = new KmsClient(cfg); diff --git a/src/app.ts b/src/app.ts index 5011e65..f2641f8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,6 +1,6 @@ import { determineAppMode } from './initConfig'; import { AppMode } from './shared/types'; -import * as enclavedApp from './enclavedApp'; +import * as securedApp from './securedExpressApp'; import * as masterExpressApp from './masterExpressApp'; import logger from './logger'; @@ -10,9 +10,9 @@ import logger from './logger'; export async function init(): Promise { const appMode = determineAppMode(); - if (appMode === AppMode.ENCLAVED) { - logger.info('Starting in Enclaved mode...'); - await enclavedApp.init(); + if (appMode === AppMode.SECURED) { + logger.info('Starting in secured mode...'); + await securedApp.init(); } else if (appMode === AppMode.MASTER_EXPRESS) { logger.info('Starting in Master Express mode...'); await masterExpressApp.init(); @@ -22,4 +22,4 @@ export async function init(): Promise { } // Export the individual app modules for direct access if needed -export { enclavedApp, masterExpressApp }; +export { securedApp, masterExpressApp }; diff --git a/src/enclavedBitgoExpress/routers/index.ts b/src/enclavedBitgoExpress/routers/index.ts deleted file mode 100644 index 8221c9c..0000000 --- a/src/enclavedBitgoExpress/routers/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { EnclavedAPiSpec as ApiSpec } from './enclavedApiSpec'; -import { HealthCheckApiSpec } from './healthCheck'; - -export const EnclavedApiSpec = { - ...HealthCheckApiSpec, - ...ApiSpec, -}; -export type EnclavedApiSpec = typeof EnclavedApiSpec; diff --git a/src/errors.ts b/src/errors.ts index 6ce5540..58555f6 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,7 +1,7 @@ /** - * Common base error class for the Enclaved Express application + * Common base error class for the secured Express application */ -export class EnclavedError extends Error { +export class securedError extends Error { public status: number; constructor(message: string, status = 500) { @@ -15,7 +15,7 @@ export class EnclavedError extends Error { /** * Error for API responses */ -export class ApiResponseError extends EnclavedError { +export class ApiResponseError extends securedError { public result: any; constructor(message: string, status = 500, result?: any) { @@ -27,7 +27,7 @@ export class ApiResponseError extends EnclavedError { /** * Error for configuration issues */ -export class ConfigurationError extends EnclavedError { +export class ConfigurationError extends securedError { constructor(message: string) { super(message, 500); } @@ -36,7 +36,7 @@ export class ConfigurationError extends EnclavedError { /** * Error for service connection issues */ -export class ServiceConnectionError extends EnclavedError { +export class ServiceConnectionError extends securedError { constructor(message: string) { super(message, 502); } @@ -45,7 +45,7 @@ export class ServiceConnectionError extends EnclavedError { /** * Error for unsupported operations */ -export class UnsupportedOperationError extends EnclavedError { +export class UnsupportedOperationError extends securedError { constructor(message: string) { super(message, 400); } diff --git a/src/initConfig.ts b/src/initConfig.ts index cc4f5c3..2a88ffe 100644 --- a/src/initConfig.ts +++ b/src/initConfig.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import { Config, - EnclavedConfig, + SecuredExpressConfig, MasterExpressConfig, TlsMode, AppMode, @@ -10,7 +10,7 @@ import { import logger from './logger'; import { validateTlsCertificates, validateMasterExpressConfig } from './shared/appUtils'; -export { Config, EnclavedConfig, MasterExpressConfig, TlsMode, AppMode, EnvironmentName }; +export { Config, SecuredExpressConfig, MasterExpressConfig, TlsMode, AppMode, EnvironmentName }; function isNilOrNaN(val: unknown): val is null | undefined | number { return val == null || (typeof val === 'number' && isNaN(val)); @@ -26,26 +26,26 @@ function determineAppMode(): AppMode { const mode = readEnvVar('APP_MODE') || readEnvVar('BITGO_APP_MODE'); if (!mode) { throw new Error( - 'APP_MODE environment variable is required. Set APP_MODE to either "enclaved" or "master-express"', + 'APP_MODE environment variable is required. Set APP_MODE to either "secured" or "master-express"', ); } + if (mode === 'secured') { + return AppMode.SECURED; + } if (mode === 'master-express') { return AppMode.MASTER_EXPRESS; } - if (mode === 'enclaved') { - return AppMode.ENCLAVED; - } - throw new Error(`Invalid APP_MODE: ${mode}. Must be either "enclaved" or "master-express"`); + throw new Error(`Invalid APP_MODE: ${mode}. Must be either "secured" or "master-express"`); } export { determineAppMode }; // ============================================================================ -// ENCLAVED MODE CONFIGURATION +// SECURED MODE CONFIGURATION // ============================================================================ -const defaultEnclavedConfig: EnclavedConfig = { - appMode: AppMode.ENCLAVED, +const defaultSecuredExpressConfig: SecuredExpressConfig = { + appMode: AppMode.SECURED, port: 3080, bind: 'localhost', timeout: 305 * 1000, @@ -75,7 +75,7 @@ function determineTlsMode(): TlsMode { throw new Error(`Invalid TLS_MODE: ${tlsMode}. Must be either "disabled" or "mtls"`); } -function enclavedEnvConfig(): Partial { +function securedEnvConfig(): Partial { const kmsUrl = readEnvVar('KMS_URL'); if (!kmsUrl) { @@ -84,8 +84,8 @@ function enclavedEnvConfig(): Partial { } return { - appMode: AppMode.ENCLAVED, - port: Number(readEnvVar('ENCLAVED_EXPRESS_PORT')), + appMode: AppMode.SECURED, + port: Number(readEnvVar('SECURED_EXPRESS_PORT')), bind: readEnvVar('BIND'), ipc: readEnvVar('IPC'), debugNamespace: (readEnvVar('DEBUG_NAMESPACE') || '').split(',').filter(Boolean), @@ -107,17 +107,19 @@ function enclavedEnvConfig(): Partial { }; } -function mergeEnclavedConfigs(...configs: Partial[]): EnclavedConfig { - function get(k: T): EnclavedConfig[T] { +function mergeSecuredExpressConfigs( + ...configs: Partial[] +): SecuredExpressConfig { + function get(k: T): SecuredExpressConfig[T] { return configs.reduce( - (entry: EnclavedConfig[T], config) => - !isNilOrNaN(config[k]) ? (config[k] as EnclavedConfig[T]) : entry, - defaultEnclavedConfig[k], + (entry: SecuredExpressConfig[T], config) => + !isNilOrNaN(config[k]) ? (config[k] as SecuredExpressConfig[T]) : entry, + defaultSecuredExpressConfig[k], ); } return { - appMode: AppMode.ENCLAVED, + appMode: AppMode.SECURED, port: get('port'), bind: get('bind'), ipc: get('ipc'), @@ -138,9 +140,9 @@ function mergeEnclavedConfigs(...configs: Partial[]): EnclavedCo }; } -function configureEnclavedMode(): EnclavedConfig { - const env = enclavedEnvConfig(); - let config = mergeEnclavedConfigs(env); +function configureSecuredMode(): SecuredExpressConfig { + const env = securedEnvConfig(); + let config = mergeSecuredExpressConfigs(env); // Only load certificates if TLS is enabled if (config.tlsMode !== TlsMode.DISABLED) { @@ -189,8 +191,8 @@ const defaultMasterExpressConfig: MasterExpressConfig = { env: 'test', disableEnvCheck: true, authVersion: 2, - enclavedExpressUrl: '', // Will be overridden by environment variable - enclavedExpressCert: '', // Will be overridden by environment variable + securedExpressUrl: '', // Will be overridden by environment variable + securedExpressCert: '', // Will be overridden by environment variable tlsMode: TlsMode.MTLS, mtlsRequestCert: true, allowSelfSigned: false, @@ -206,16 +208,16 @@ function determineProtocol(url: string, tlsMode: TlsMode, isBitGo = false): stri } function masterExpressEnvConfig(): Partial { - const enclavedExpressUrl = readEnvVar('ENCLAVED_EXPRESS_URL'); - const enclavedExpressCert = readEnvVar('ENCLAVED_EXPRESS_CERT'); + const securedExpressUrl = readEnvVar('SECURED_EXPRESS_URL'); + const securedExpressCert = readEnvVar('SECURED_EXPRESS_CERT'); const tlsMode = determineTlsMode(); - if (!enclavedExpressUrl) { - throw new Error('ENCLAVED_EXPRESS_URL environment variable is required and cannot be empty'); + if (!securedExpressUrl) { + throw new Error('SECURED_EXPRESS_URL environment variable is required and cannot be empty'); } - if (tlsMode === TlsMode.MTLS && !enclavedExpressCert) { - throw new Error('ENCLAVED_EXPRESS_CERT environment variable is required for MTLS mode.'); + if (tlsMode === TlsMode.MTLS && !securedExpressCert) { + throw new Error('SECURED_EXPRESS_CERT environment variable is required for MTLS mode.'); } // Debug mTLS environment variables @@ -239,8 +241,8 @@ function masterExpressEnvConfig(): Partial { customRootUri: readEnvVar('BITGO_CUSTOM_ROOT_URI'), disableEnvCheck: readEnvVar('BITGO_DISABLE_ENV_CHECK') === 'true', authVersion: Number(readEnvVar('BITGO_AUTH_VERSION')), - enclavedExpressUrl, - enclavedExpressCert, + securedExpressUrl, + securedExpressCert, customBitcoinNetwork: readEnvVar('BITGO_CUSTOM_BITCOIN_NETWORK'), // mTLS settings keyPath: readEnvVar('TLS_KEY_PATH'), @@ -279,8 +281,8 @@ function mergeMasterExpressConfigs( customRootUri: get('customRootUri'), disableEnvCheck: get('disableEnvCheck'), authVersion: get('authVersion'), - enclavedExpressUrl: get('enclavedExpressUrl'), - enclavedExpressCert: get('enclavedExpressCert'), + securedExpressUrl: get('securedExpressUrl'), + securedExpressCert: get('securedExpressCert'), customBitcoinNetwork: get('customBitcoinNetwork'), keyPath: get('keyPath'), crtPath: get('crtPath'), @@ -302,12 +304,8 @@ export function configureMasterExpressMode(): MasterExpressConfig { if (config.customRootUri) { updates.customRootUri = determineProtocol(config.customRootUri, config.tlsMode, true); } - if (config.enclavedExpressUrl) { - updates.enclavedExpressUrl = determineProtocol( - config.enclavedExpressUrl, - config.tlsMode, - false, - ); + if (config.securedExpressUrl) { + updates.securedExpressUrl = determineProtocol(config.securedExpressUrl, config.tlsMode, false); } config = { ...config, ...updates }; @@ -342,26 +340,26 @@ export function configureMasterExpressMode(): MasterExpressConfig { validateTlsCertificates(config); } - // Handle cert loading for Enclaved Express (always required for Master Express) - if (config.enclavedExpressCert) { + // Handle cert loading for Secured Express (always required for Master Express) + if (config.securedExpressCert) { try { - if (fs.existsSync(config.enclavedExpressCert)) { + if (fs.existsSync(config.securedExpressCert)) { config = { ...config, - enclavedExpressCert: fs.readFileSync(config.enclavedExpressCert, 'utf-8'), + securedExpressCert: fs.readFileSync(config.securedExpressCert, 'utf-8'), }; logger.info( - `Successfully loaded Enclaved Express certificate from file: ${config.enclavedExpressCert.substring( + `Successfully loaded Secured Express certificate from file: ${config.securedExpressCert.substring( 0, 50, )}...`, ); } else { - throw new Error(`Certificate file not found: ${config.enclavedExpressCert}`); + throw new Error(`Certificate file not found: ${config.securedExpressCert}`); } } catch (e) { const err = e instanceof Error ? e : new Error(String(e)); - throw new Error(`Failed to read enclaved express cert: ${err.message}`); + throw new Error(`Failed to read secured express cert: ${err.message}`); } } @@ -378,8 +376,8 @@ export function configureMasterExpressMode(): MasterExpressConfig { export function initConfig(): Config { const appMode = determineAppMode(); - if (appMode === AppMode.ENCLAVED) { - return configureEnclavedMode(); + if (appMode === AppMode.SECURED) { + return configureSecuredMode(); } else if (appMode === AppMode.MASTER_EXPRESS) { return configureMasterExpressMode(); } else { @@ -388,8 +386,8 @@ export function initConfig(): Config { } // Type guards for working with the union type -export function isEnclavedConfig(config: Config): config is EnclavedConfig { - return config.appMode === AppMode.ENCLAVED; +export function isSecuredExpressConfig(config: Config): config is SecuredExpressConfig { + return config.appMode === AppMode.SECURED; } export function isMasterExpressConfig(config: Config): config is MasterExpressConfig { diff --git a/src/kms/kmsClient.ts b/src/kms/kmsClient.ts index 01f0a86..83f8cf3 100644 --- a/src/kms/kmsClient.ts +++ b/src/kms/kmsClient.ts @@ -1,6 +1,6 @@ import debug from 'debug'; import * as superagent from 'superagent'; -import { EnclavedConfig, isMasterExpressConfig } from '../shared/types'; +import { SecuredExpressConfig, isMasterExpressConfig } from '../shared/types'; import { PostKeyKmsSchema, PostKeyParams, PostKeyResponse } from './types/postKey'; import { GetKeyKmsSchema, GetKeyParams, GetKeyResponse } from './types/getKey'; import { @@ -19,9 +19,9 @@ const debugLogger = debug('bitgo:express:kmsClient'); export class KmsClient { private readonly url: string; - constructor(cfg: EnclavedConfig) { + constructor(cfg: SecuredExpressConfig) { if (isMasterExpressConfig(cfg)) { - throw new Error('Configuration is not in enclaved express mode'); + throw new Error('Configuration is not in secured express mode'); } if (!cfg.kmsUrl) { diff --git a/src/routes/enclaved.ts b/src/routes/enclaved.ts deleted file mode 100644 index b9e5857..0000000 --- a/src/routes/enclaved.ts +++ /dev/null @@ -1,27 +0,0 @@ -import express from 'express'; -import debug from 'debug'; -import { EnclavedConfig } from '../shared/types'; -import { createKeyGenRouter } from '../enclavedBitgoExpress/routers/enclavedApiSpec'; -import { createHealthCheckRouter } from '../enclavedBitgoExpress/routers/healthCheck'; - -const debugLogger = debug('enclaved:routes'); -/** - * Setup all routes for the Enclaved Express application - * @param app Express application - * @param config - */ -export function setupRoutes(app: express.Application, config: EnclavedConfig): void { - // Register health check routes - app.use(createHealthCheckRouter()); - - // Register keygen routes - app.use(createKeyGenRouter(config)); - - app.use('*', (_req, res) => { - res.status(404).json({ - error: 'Route not found or not supported in enclaved mode', - }); - }); - - debugLogger('All routes configured'); -} diff --git a/src/routes/master.ts b/src/routes/master.ts index 20b42c7..fe14622 100644 --- a/src/routes/master.ts +++ b/src/routes/master.ts @@ -1,7 +1,7 @@ import express from 'express'; import { MasterExpressConfig } from '../shared/types'; import { createHealthCheckRouter } from '../api/master/routers/healthCheck'; -import { createEnclavedExpressRouter } from '../api/master/routers/enclavedExpressHealth'; +import { createSecuredExpressRouter } from '../api/master/routers/securedExpressHealth'; import logger from '../logger'; import { createMasterApiRouter } from '../api/master/routers/masterApiSpec'; @@ -12,9 +12,9 @@ export function setupRoutes(app: express.Application, cfg: MasterExpressConfig): // Setup health check routes using the new router app.use(createHealthCheckRouter('master express')); - // Add enclaved express routes for pinging the enclaved express server - // TODO: Add version endpoint to enclaved express - app.use(createEnclavedExpressRouter(cfg)); + // Add secured express routes for pinging the secured express server + // TODO: Add version endpoint to secured express + app.use(createSecuredExpressRouter(cfg)); app.use(createMasterApiRouter(cfg)); diff --git a/src/routes/secured.ts b/src/routes/secured.ts new file mode 100644 index 0000000..0bcc923 --- /dev/null +++ b/src/routes/secured.ts @@ -0,0 +1,27 @@ +import express from 'express'; +import debug from 'debug'; +import { SecuredExpressConfig } from '../shared/types'; +import { createKeyGenRouter } from '../securedBitgoExpress/routers/securedExpressApiSpec'; +import { createHealthCheckRouter } from '../securedBitgoExpress/routers/healthCheck'; + +const debugLogger = debug('secured:routes'); +/** + * Setup all routes for the Secured Express application + * @param app Express application + * @param config + */ +export function setupRoutes(app: express.Application, config: SecuredExpressConfig): void { + // Register health check routes + app.use(createHealthCheckRouter()); + + // Register keygen routes + app.use(createKeyGenRouter(config)); + + app.use('*', (_req, res) => { + res.status(404).json({ + error: 'Route not found or not supported in secured mode', + }); + }); + + debugLogger('All routes configured'); +} diff --git a/src/routes/utils.ts b/src/routes/utils.ts index 547b646..407d380 100644 --- a/src/routes/utils.ts +++ b/src/routes/utils.ts @@ -1,7 +1,7 @@ import express from 'express'; import debug from 'debug'; -const debugLogger = debug('enclaved:routes'); +const debugLogger = debug('secured:routes'); // promiseWrapper implementation export function promiseWrapper(promiseRequestHandler: any) { diff --git a/src/enclavedBitgoExpress/routers/healthCheck.ts b/src/securedBitgoExpress/routers/healthCheck.ts similarity index 97% rename from src/enclavedBitgoExpress/routers/healthCheck.ts rename to src/securedBitgoExpress/routers/healthCheck.ts index a6b981d..044835d 100644 --- a/src/enclavedBitgoExpress/routers/healthCheck.ts +++ b/src/securedBitgoExpress/routers/healthCheck.ts @@ -43,7 +43,7 @@ export function createHealthCheckRouter(): WrappedRouter Response.ok({ - status: 'enclaved express server is ok!', + status: 'secured express server is ok!', timestamp: new Date().toISOString(), }), ), diff --git a/src/securedBitgoExpress/routers/index.ts b/src/securedBitgoExpress/routers/index.ts new file mode 100644 index 0000000..e8c974f --- /dev/null +++ b/src/securedBitgoExpress/routers/index.ts @@ -0,0 +1,8 @@ +import { SecuredExpressApiSpec as ApiSpec } from './securedExpressApiSpec'; +import { HealthCheckApiSpec } from './healthCheck'; + +export const SecuredExpressApiSpec = { + ...HealthCheckApiSpec, + ...ApiSpec, +}; +export type SecuredExpressApiSpec = typeof SecuredExpressApiSpec; diff --git a/src/enclavedBitgoExpress/routers/enclavedApiSpec.ts b/src/securedBitgoExpress/routers/securedExpressApiSpec.ts similarity index 82% rename from src/enclavedBitgoExpress/routers/enclavedApiSpec.ts rename to src/securedBitgoExpress/routers/securedExpressApiSpec.ts index f9a3ee1..87707d1 100644 --- a/src/enclavedBitgoExpress/routers/enclavedApiSpec.ts +++ b/src/securedBitgoExpress/routers/securedExpressApiSpec.ts @@ -15,20 +15,20 @@ import { } from '@api-ts/typed-express-router'; import express from 'express'; import * as t from 'io-ts'; -import { postIndependentKey } from '../../api/enclaved/handlers/postIndependentKey'; -import { recoveryMultisigTransaction } from '../../api/enclaved/handlers/recoveryMultisigTransaction'; -import { signMultisigTransaction } from '../../api/enclaved/handlers/signMultisigTransaction'; -import { signMpcTransaction } from '../../api/enclaved/handlers/signMpcTransaction'; +import { postIndependentKey } from '../../api/secured/handlers/postIndependentKey'; +import { recoveryMultisigTransaction } from '../../api/secured/handlers/recoveryMultisigTransaction'; +import { signMultisigTransaction } from '../../api/secured/handlers/signMultisigTransaction'; +import { signMpcTransaction } from '../../api/secured/handlers/signMpcTransaction'; import { prepareBitGo, responseHandler } from '../../shared/middleware'; -import { EnclavedConfig } from '../../shared/types'; +import { SecuredExpressConfig } from '../../shared/types'; import { BitGoRequest } from '../../types/request'; -import { eddsaInitialize } from '../../api/enclaved/mpcInitialize'; -import { eddsaFinalize } from '../../api/enclaved/mpcFinalize'; +import { eddsaInitialize } from '../../api/secured/mpcInitialize'; +import { eddsaFinalize } from '../../api/secured/mpcFinalize'; import { DklsDkg, DklsTypes } from '@bitgo-beta/sdk-lib-mpc'; -import { ecdsaMPCv2Initialize } from '../../api/enclaved/handlers/ecdsaMPCv2Initialize'; -import { ecdsaMPCv2Round } from '../../api/enclaved/handlers/ecdsaMPCv2Round'; -import { ecdsaMPCv2Finalize } from '../../api/enclaved/handlers/ecdsaMPCv2Finalize'; -import { signEddsaRecoveryTransaction } from '../../api/enclaved/handlers/signEddsaRecoveryTransaction'; +import { ecdsaMPCv2Initialize } from '../../api/secured/handlers/ecdsaMPCv2Initialize'; +import { ecdsaMPCv2Round } from '../../api/secured/handlers/ecdsaMPCv2Round'; +import { ecdsaMPCv2Finalize } from '../../api/secured/handlers/ecdsaMPCv2Finalize'; +import { signEddsaRecoveryTransaction } from '../../api/secured/handlers/signEddsaRecoveryTransaction'; import { isEddsaCoin } from '../../shared/coinUtils'; import { MethodNotImplementedError } from '@bitgo/sdk-core'; @@ -297,7 +297,7 @@ const MpcV2FinalizeResponseType = t.type(MpcV2FinalizeResponse); export type MpcV2FinalizeResponseType = t.TypeOf; // API Specification -export const EnclavedAPiSpec = apiSpec({ +export const SecuredExpressApiSpec = apiSpec({ 'v1.multisig.sign': { post: httpRoute({ method: 'POST', @@ -469,29 +469,32 @@ export const EnclavedAPiSpec = apiSpec({ }, }); -export type EnclavedApiSpecRouteHandler< - ApiName extends keyof typeof EnclavedAPiSpec, - Method extends keyof (typeof EnclavedAPiSpec)[ApiName] & HttpMethod, -> = TypedRequestHandler; +export type SecuredExpressApiSpecRouteHandler< + ApiName extends keyof typeof SecuredExpressApiSpec, + Method extends keyof (typeof SecuredExpressApiSpec)[ApiName] & HttpMethod, +> = TypedRequestHandler; -export type EnclavedApiSpecRouteRequest< - ApiName extends keyof typeof EnclavedAPiSpec, - Method extends keyof (typeof EnclavedAPiSpec)[ApiName] & HttpMethod, -> = BitGoRequest & Parameters>[0]; +export type SecuredExpressApiSpecRouteRequest< + ApiName extends keyof typeof SecuredExpressApiSpec, + Method extends keyof (typeof SecuredExpressApiSpec)[ApiName] & HttpMethod, +> = BitGoRequest & + Parameters>[0]; -export type GenericEnclavedApiSpecRouteRequest = EnclavedApiSpecRouteRequest; +export type GenericSecuredExpressApiSpecRouteRequest = SecuredExpressApiSpecRouteRequest; // Create router with handlers -export function createKeyGenRouter(config: EnclavedConfig): WrappedRouter { - const router = createRouter(EnclavedAPiSpec); +export function createKeyGenRouter( + config: SecuredExpressConfig, +): WrappedRouter { + const router = createRouter(SecuredExpressApiSpec); // Add middleware router.use(express.json()); router.use(prepareBitGo(config)); // Independent key generation endpoint handler router.post('v1.key.independent', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.key.independent', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.key.independent', 'post'>; const result = await postIndependentKey(typedReq); return Response.ok(result); }), @@ -499,32 +502,32 @@ export function createKeyGenRouter(config: EnclavedConfig): WrappedRouter(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.multisig.sign', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.multisig.sign', 'post'>; const result = await signMultisigTransaction(typedReq); return Response.ok(result); }), ]); router.post('v1.multisig.recovery', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.multisig.recovery', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.multisig.recovery', 'post'>; const result = await recoveryMultisigTransaction(typedReq); return Response.ok(result); }), ]); router.post('v1.mpc.sign', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.mpc.sign', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.mpc.sign', 'post'>; const result = await signMpcTransaction(typedReq); return Response.ok(result); }), ]); router.post('v1.mpc.recovery', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.mpc.recovery', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.mpc.recovery', 'post'>; const coin = typedReq.bitgo.coin(typedReq.decoded.coin); if (isEddsaCoin(coin)) { const result = await signEddsaRecoveryTransaction({ @@ -545,9 +548,9 @@ export function createKeyGenRouter(config: EnclavedConfig): WrappedRouter(async (_req) => { + responseHandler(async (_req) => { try { - const typedReq = _req as EnclavedApiSpecRouteRequest<'v1.mpc.key.initialize', 'post'>; + const typedReq = _req as SecuredExpressApiSpecRouteRequest<'v1.mpc.key.initialize', 'post'>; const response = await eddsaInitialize(typedReq); return Response.ok(response); } catch (error) { @@ -561,9 +564,9 @@ export function createKeyGenRouter(config: EnclavedConfig): WrappedRouter(async (_req) => { + responseHandler(async (_req) => { try { - const typedReq = _req as EnclavedApiSpecRouteRequest<'v1.mpc.key.finalize', 'post'>; + const typedReq = _req as SecuredExpressApiSpecRouteRequest<'v1.mpc.key.finalize', 'post'>; const response = await eddsaFinalize(typedReq); return Response.ok(response); } catch (error) { @@ -577,24 +580,24 @@ export function createKeyGenRouter(config: EnclavedConfig): WrappedRouter(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.mpcv2.initialize', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.mpcv2.initialize', 'post'>; const result = await ecdsaMPCv2Initialize(typedReq); return Response.ok(result); }), ]); router.post('v1.mpcv2.round', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.mpcv2.round', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.mpcv2.round', 'post'>; const result = await ecdsaMPCv2Round(typedReq); return Response.ok(result); }), ]); router.post('v1.mpcv2.finalize', [ - responseHandler(async (req) => { - const typedReq = req as EnclavedApiSpecRouteRequest<'v1.mpcv2.finalize', 'post'>; + responseHandler(async (req) => { + const typedReq = req as SecuredExpressApiSpecRouteRequest<'v1.mpcv2.finalize', 'post'>; const result = await ecdsaMPCv2Finalize(typedReq); return Response.ok(result); }), diff --git a/src/enclavedApp.ts b/src/securedExpressApp.ts similarity index 82% rename from src/enclavedApp.ts rename to src/securedExpressApp.ts index 17e8306..7dc882a 100644 --- a/src/enclavedApp.ts +++ b/src/securedExpressApp.ts @@ -4,9 +4,9 @@ import http from 'http'; import morgan from 'morgan'; import { SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1 } from 'constants'; -import { EnclavedConfig, TlsMode, isEnclavedConfig } from './shared/types'; +import { SecuredExpressConfig, TlsMode, isSecuredExpressConfig } from './shared/types'; import { initConfig } from './initConfig'; -import { setupRoutes } from './routes/enclaved'; +import { setupRoutes } from './routes/secured'; import { setupLogging, setupCommonMiddleware, @@ -21,9 +21,9 @@ import logger from './logger'; /** * Create a startup function which will be run upon server initialization */ -export function startup(config: EnclavedConfig, baseUri: string): () => void { +export function startup(config: SecuredExpressConfig, baseUri: string): () => void { return function () { - logger.info('BitGo Enclaved Express running'); + logger.info('BitGo Secured Express running'); logger.info(`Base URI: ${baseUri}`); logger.info(`TLS Mode: ${config.tlsMode}`); logger.info(`mTLS Enabled: ${config.tlsMode === TlsMode.MTLS}`); @@ -38,7 +38,7 @@ export function startup(config: EnclavedConfig, baseUri: string): () => void { }; } -function isTLS(config: EnclavedConfig): boolean { +function isTLS(config: SecuredExpressConfig): boolean { const { keyPath, crtPath, tlsKey, tlsCert, tlsMode } = config; if (tlsMode === TlsMode.DISABLED) return false; return Boolean((keyPath && crtPath) || (tlsKey && tlsCert)); @@ -46,7 +46,7 @@ function isTLS(config: EnclavedConfig): boolean { async function createHttpsServer( app: express.Application, - config: EnclavedConfig, + config: SecuredExpressConfig, ): Promise { const { tlsKey, tlsCert, tlsMode, mtlsRequestCert } = config; @@ -70,7 +70,7 @@ async function createHttpsServer( } export async function createServer( - config: EnclavedConfig, + config: SecuredExpressConfig, app: express.Application, ): Promise { const server = isTLS(config) ? await createHttpsServer(app, config) : createHttpServer(app); @@ -78,7 +78,7 @@ export async function createServer( return server; } -export function createBaseUri(config: EnclavedConfig): string { +export function createBaseUri(config: SecuredExpressConfig): string { const { bind, port } = config; const tls = config.tlsMode === TlsMode.MTLS; const isStandardPort = (port === 80 && !tls) || (port === 443 && tls); @@ -88,7 +88,7 @@ export function createBaseUri(config: EnclavedConfig): string { /** * Create and configure the express application */ -export function app(cfg: EnclavedConfig): express.Application { +export function app(cfg: SecuredExpressConfig): express.Application { logger.debug('app is initializing'); const app = express(); @@ -120,10 +120,10 @@ export function app(cfg: EnclavedConfig): express.Application { export async function init(): Promise { const cfg = initConfig(); - // Type-safe validation that we're in enclaved mode - if (!isEnclavedConfig(cfg)) { + // Type-safe validation that we're in secured mode + if (!isSecuredExpressConfig(cfg)) { throw new Error( - `This application only supports enclaved mode. Current mode: ${cfg.appMode}. Set APP_MODE=enclaved to use this application.`, + `This application only supports secured mode. Current mode: ${cfg.appMode}. Set APP_MODE=secured to use this application.`, ); } diff --git a/src/shared/appUtils.ts b/src/shared/appUtils.ts index 1af51e6..05e0785 100644 --- a/src/shared/appUtils.ts +++ b/src/shared/appUtils.ts @@ -192,13 +192,13 @@ export function validateTlsCertificates(config: { * Validate Master Express configuration */ export function validateMasterExpressConfig(config: { - enclavedExpressUrl: string; - enclavedExpressCert: string; + securedExpressUrl: string; + securedExpressCert: string; }): void { - if (!config.enclavedExpressUrl) { - throw new Error('ENCLAVED_EXPRESS_URL is required for Master Express mode'); + if (!config.securedExpressUrl) { + throw new Error('SECURED_EXPRESS_URL is required for Master Express mode'); } - if (!config.enclavedExpressCert) { - throw new Error('ENCLAVED_EXPRESS_CERT is required for Master Express mode'); + if (!config.securedExpressCert) { + throw new Error('SECURED_EXPRESS_CERT is required for Master Express mode'); } } diff --git a/src/shared/responseHandler.ts b/src/shared/responseHandler.ts index ec14998..b663bfa 100644 --- a/src/shared/responseHandler.ts +++ b/src/shared/responseHandler.ts @@ -1,7 +1,7 @@ import { Request, Response as ExpressResponse, NextFunction } from 'express'; import { Config } from '../shared/types'; import { BitGoRequest } from '../types/request'; -import { ApiResponseError, EnclavedError } from '../errors'; +import { ApiResponseError, securedError } from '../errors'; import { BitgoExpressError, ValidationError, @@ -81,8 +81,8 @@ export function responseHandler(fn: ServiceFunction extends express.Request { bitgo: BitGo; config: T; - enclavedExpressClient: EnclavedExpressClient; + securedExpressClient: SecuredExpressClient; } export function isBitGoRequest(req: express.Request): req is BitGoRequest { From 4e2d6181f5f09ad3be8b3552c9c6c1fe028b7dfa Mon Sep 17 00:00:00 2001 From: Pranav Jain Date: Mon, 21 Jul 2025 16:14:28 -0400 Subject: [PATCH 2/3] chore(mbe): add "aw" to commit lint scope Ticket: WP-5298 --- .commitlintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.commitlintrc.json b/.commitlintrc.json index ebcd589..206b762 100644 --- a/.commitlintrc.json +++ b/.commitlintrc.json @@ -5,7 +5,7 @@ "header-max-length": [2, "always", 72], "references-empty": [1, "never"], "subject-case": [0], - "scope-enum": [2, "always", ["mbe", "sbe", "docker"]], + "scope-enum": [2, "always", ["aw", "mbe", "sbe", "docker"]], "scope-empty": [0, "never"] }, "parserPreset": { From 277d8d92d68fcc56d5250c408b015ce130e29f9e Mon Sep 17 00:00:00 2001 From: Pranav Jain Date: Mon, 21 Jul 2025 17:02:25 -0400 Subject: [PATCH 3/3] chore(aw): fix the tests Ticket: WP-5298 --- src/__tests__/api/master/generateWallet.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/__tests__/api/master/generateWallet.test.ts b/src/__tests__/api/master/generateWallet.test.ts index 565e909..fb79497 100644 --- a/src/__tests__/api/master/generateWallet.test.ts +++ b/src/__tests__/api/master/generateWallet.test.ts @@ -754,7 +754,7 @@ describe('POST /api/:coin/wallet/generate', () => { to: 1, payload: { encryptedMessage: 'test-p2p-message-user-to-backup-3', - signature: 'test-signature-backup-to-user-3', + signature: 'test-signature-user-to-backup-3', }, commitment: 'test-commitment-user-3', }, @@ -875,7 +875,7 @@ describe('POST /api/:coin/wallet/generate', () => { to: 0, payload: { encryptedMessage: 'test-p2p-message-backup-to-user-3', - signature: 'test-signature-user-to-backup-3', + signature: 'test-signature-backup-to-user-3', }, commitment: 'test-commitment-backup-3', },