Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,17 @@ API responses follow a standard error format with `error` and `details` fields.

#### Wallet Management

- `POST /api/:coin/wallet/generate` - Generate wallet (supports onchain and TSS multisig types)
- `POST /api/v1/:coin/advancedwallet/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
- `POST /api/v1/:coin/advancedwallet/:walletId/sendMany` - Send transaction with multiple recipients
- `POST /api/v1/:coin/advancedwallet/:walletId/accelerate` - Accelerate pending transactions (CPFP/RBF)
- `POST /api/v1/:coin/advancedwallet/:walletId/consolidate` - Consolidate wallet addresses
- `POST /api/v1/:coin/advancedwallet/:walletId/consolidateunspents` - Consolidate unspent transaction outputs
- `POST /api/v1/:coin/advancedwallet/:walletId/txrequest/:txRequestId/signAndSend` - Sign a TxRequest and broadcast it (MPC wallets only)

#### Recovery

- `POST /api/:coin/wallet/recovery` - Recover wallet funds
- `POST /api/v1/:coin/advancedwallet/recovery` - Recover wallet funds
- `POST /api/v1/:coin/advancedwallet/recoveryconsolidations` - Consolidate and recover funds from multiple addresses
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,14 @@ docker-compose down
- `POST /ping` - Health check.
- `GET /version` - Version information.
- `POST /ping/advancedWalletManager` - Test connection to Advanced Wallet Manager.
- `POST /api/:coin/wallet/generate` - Generate wallet (with Advanced Wallet Manager integration).
- `POST /api/v1/:coin/advancedwallet/generate` - Generate wallet (with Advanced Wallet Manager integration).
- `POST /api/v1/:coin/advancedwallet/:walletId/sendMany` - Send transaction with multiple recipients.
- `POST /api/v1/:coin/advancedwallet/:walletId/accelerate` - Accelerate pending transactions (CPFP/RBF).
- `POST /api/v1/:coin/advancedwallet/:walletId/consolidate` - Consolidate wallet addresses.
- `POST /api/v1/:coin/advancedwallet/:walletId/consolidateunspents` - Consolidate unspent transaction outputs.
- `POST /api/v1/:coin/advancedwallet/:walletId/txrequest/:txRequestId/signAndSend` - Sign a TxRequest and broadcast it (MPC wallets only).
- `POST /api/v1/:coin/advancedwallet/recovery` - Recover wallet funds.
- `POST /api/v1/:coin/advancedwallet/recoveryconsolidations` - Consolidate and recover funds from multiple addresses.

### API Documentation

Expand Down
16 changes: 8 additions & 8 deletions masterBitgoExpress.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "Advanced Wallets - On-Premises Key Management with BitGo Express"
},
"paths": {
"/api/{coin}/wallet/{walletId}/accelerate": {
"/api/v1/{coin}/advancedwallet/{walletId}/accelerate": {
"post": {
"summary": "Accelerate unconfirmed transactions on UTXO-based blockchains.",
"description": "Supports Child-Pays-For-Parent (CPFP) and Replace-By-Fee (RBF) acceleration methods.",
Expand Down Expand Up @@ -188,7 +188,7 @@
}
}
},
"/api/{coin}/wallet/{walletId}/consolidate": {
"/api/v1/{coin}/advancedwallet/{walletId}/consolidate": {
"post": {
"summary": "Build, sign, and send a consolidation transaction for an account-based asset all in 1 call.",
"description": "For account-based assets, consolidating the balances in the receive addresses to the base address maximizes the spendable balance of a wallet.",
Expand Down Expand Up @@ -327,7 +327,7 @@
}
}
},
"/api/{coin}/wallet/{walletId}/consolidateunspents": {
"/api/v1/{coin}/advancedwallet/{walletId}/consolidateunspents": {
"post": {
"summary": "Build and send a transaction to consolidate unspents in a wallet.",
"description": "Consolidating unspents is only for UTXO-based assets.",
Expand Down Expand Up @@ -528,7 +528,7 @@
}
}
},
"/api/{coin}/wallet/{walletId}/sendMany": {
"/api/v1/{coin}/advancedwallet/{walletId}/sendMany": {
"post": {
"parameters": [
{
Expand Down Expand Up @@ -821,7 +821,7 @@
}
}
},
"/api/{coin}/wallet/{walletId}/txrequest/{txRequestId}/signAndSend": {
"/api/v1/{coin}/advancedwallet/{walletId}/txrequest/{txRequestId}/signAndSend": {
"post": {
"summary": "Sign a TxRequest and Broadcast it (MPC wallets only)",
"description": "This is usually needed after resolving a pending approval for a MPC wallet",
Expand Down Expand Up @@ -950,7 +950,7 @@
}
}
},
"/api/{coin}/wallet/generate": {
"/api/v1/{coin}/advancedwallet/generate": {
"post": {
"summary": "Generates a new advanced wallet.",
"description": "The wallet creation process involves several steps that happen automatically:\n1. User Keychain Creation: Creates the user keychain in the advanced wallet manager and encrypts it with the respective KMS.\n2. Backup Keychain Creation: Creates the backup keychain in the advanced wallet manager and encrypts it with the respective KMS.\n3. Keychain Upload: Uploads the user/backup public keys to BitGo.\n4. BitGo Key Creation: Creates the BitGo key on the BitGo service.\n5. Wallet Creation: Creates the wallet on BitGo with the 3 keys.",
Expand Down Expand Up @@ -1115,7 +1115,7 @@
}
}
},
"/api/{coin}/wallet/recovery": {
"/api/v1/{coin}/advancedwallet/recovery": {
"post": {
"summary": "Recover funds from an existing wallet using user and backup keys.",
"description": "This endpoint allows for both standard multisig and TSS wallet recovery.",
Expand Down Expand Up @@ -1470,7 +1470,7 @@
}
}
},
"/api/{coin}/wallet/recoveryconsolidations": {
"/api/v1/{coin}/advancedwallet/recoveryconsolidations": {
"post": {
"summary": "Consolidate funds from multiple addresses in a wallet and sign with user & backup keys in a recovery situation.",
"description": "Used for both standard multisig wallets and TSS wallets to consolidate funds from various addresses.",
Expand Down
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"store2": "^2.14.4",
"tar": "^6.2.1",
"tough-cookie": "^4.1.3",
"validator": "^13.15.15",
"validator": "^13.15.22",
"node-forge": "^1.3.2",
"xml2js": "^0.5.0",
"glob": "^11.1.0"
},
Expand Down
42 changes: 22 additions & 20 deletions src/__tests__/api/master/accelerate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { app as expressApp } from '../../../masterBitGoExpressApp';
import { AppMode, MasterExpressConfig, TlsMode } from '../../../shared/types';
import { Environments, Wallet } from '@bitgo-beta/sdk-core';

describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
describe('POST /api/v1/:coin/advancedwallet/:walletId/accelerate', () => {
let agent: request.SuperAgentTest;
const coin = 'tbtc';
const walletId = 'test-wallet-id';
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
};

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send(requestPayload);

Expand Down Expand Up @@ -138,7 +138,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
};

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send(requestPayload);

Expand Down Expand Up @@ -180,7 +180,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
};

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send(requestPayload);

Expand All @@ -200,7 +200,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
.reply(404, { error: 'Wallet not found', name: 'WalletNotFoundError' });

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -225,7 +225,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
.reply(404, { error: 'Keychain not found', name: 'KeychainNotFoundError' });

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -250,7 +250,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
.reply(200, mockUserKeychain);

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: 'xpub661MyMwAqRbcWRONG_PUBKEY_THAT_DOES_NOT_MATCH',
Expand All @@ -266,7 +266,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when required pubkey parameter is missing', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
source: 'user',
Expand All @@ -279,7 +279,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when required source parameter is missing', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -292,7 +292,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when source parameter has invalid value', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -305,11 +305,13 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
});

it('should fail when authorization header is missing', async () => {
const response = await agent.post(`/api/${coin}/wallet/${walletId}/accelerate`).send({
pubkey: mockUserKeychain.pub,
source: 'user',
cpfpTxIds: ['test-tx-id'],
});
const response = await agent
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.send({
pubkey: mockUserKeychain.pub,
source: 'user',
cpfpTxIds: ['test-tx-id'],
});

response.status.should.equal(500);
response.body.should.have.property('error', 'Internal Server Error');
Expand All @@ -332,7 +334,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {
.rejects(new Error('Insufficient funds for acceleration'));

const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -353,7 +355,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when cpfpTxIds parameter is not an array', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -367,7 +369,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when rbfTxIds parameter is not an array', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand All @@ -381,7 +383,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when pubkey parameter is not a string', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: 12345,
Expand All @@ -395,7 +397,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => {

it('should fail when both cpfpTxIds and rbfTxIds are missing', async () => {
const response = await agent
.post(`/api/${coin}/wallet/${walletId}/accelerate`)
.post(`/api/v1/${coin}/advancedwallet/${walletId}/accelerate`)
.set('Authorization', `Bearer ${accessToken}`)
.send({
pubkey: mockUserKeychain.pub,
Expand Down
Loading