-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmockBitgoServer.ts
More file actions
114 lines (94 loc) · 3.62 KB
/
mockBitgoServer.ts
File metadata and controls
114 lines (94 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import * as http from 'http';
import * as path from 'path';
import express from 'express';
import { listen, close } from './servers';
export interface MockBitgoCall {
method: string;
path: string;
body: unknown;
}
export interface MockBitgoServer {
port: number;
calls: MockBitgoCall[];
close(): Promise<void>;
}
const FIXTURES_DIR = path.resolve(__dirname, '../fixtures/bitgo');
function loadFixture(name: string): Record<string, unknown> {
return require(`${FIXTURES_DIR}/${name}.json`);
}
type SendManyFixtureMethod = 'getWallet' | 'prebuildTx' | 'sendTx';
type SupportedCoin = 'hteth' | 'tbtc';
type CoinToFixtures<C extends SupportedCoin> = {
[K in SendManyFixtureMethod]: `${K}.${C}`;
};
/** Registry — add a new coin here to support it across all sendMany integ test routes */
const COIN_FIXTURES: { [C in SupportedCoin]: CoinToFixtures<C> } = {
hteth: { getWallet: 'getWallet.hteth', prebuildTx: 'prebuildTx.hteth', sendTx: 'sendTx.hteth' },
tbtc: { getWallet: 'getWallet.tbtc', prebuildTx: 'prebuildTx.tbtc', sendTx: 'sendTx.tbtc' },
};
function coinFixtures(coin: string): CoinToFixtures<SupportedCoin> {
const fixtures = COIN_FIXTURES[coin as SupportedCoin];
if (!fixtures) throw new Error(`No fixtures registered for coin: ${coin}`);
return fixtures;
}
export async function startMockBitgoServer(): Promise<MockBitgoServer> {
const calls: MockBitgoCall[] = [];
const app = express();
app.use(express.json());
app.use((req, _res, next) => {
calls.push({ method: req.method, path: req.path, body: req.body });
next();
});
/** SDK calls this on every BitGo instance initialisation */
app.get('/api/v1/client/constants', (_req, res) => {
res.json({ ttl: 3600, constants: {} });
});
/** Add keychain — source distinguishes user / backup / bitgo */
app.post('/api/v2/:coin/key', (req, res) => {
const { coin } = req.params;
const source = req.body?.source;
const fixtureName =
source === 'user' ? 'addKey.user' : source === 'backup' ? 'addKey.backup' : 'addKey.bitgo';
const fixture = loadFixture(fixtureName);
return res.json({ ...fixture, coin });
});
/** Create wallet */
app.post('/api/v2/:coin/wallet/add', (req, res) => {
const { coin } = req.params;
const fixture = loadFixture('createWallet');
res.json({ ...fixture, coin });
});
/** Get wallet — coin-specific fixture */
app.get('/api/v2/:coin/wallet/:walletId', (req, res) => {
const { coin } = req.params;
const fixture = loadFixture(coinFixtures(coin).getWallet);
res.json({ ...fixture, coin });
});
/** Get keychain — matched by keyId */
app.get('/api/v2/:coin/key/:keyId', (req, res) => {
const { keyId, coin } = req.params;
const fixtureName =
keyId === 'user-key-id'
? 'getKeychain.user'
: keyId === 'backup-key-id'
? 'getKeychain.backup'
: 'getKeychain.bitgo';
const fixture = loadFixture(fixtureName);
res.json({ ...fixture, coin });
});
/** Block height for fee estimation */
app.get('/api/v2/:coin/public/block/latest', (_req, res) => {
res.json(loadFixture('blockLatest'));
});
/** Transaction prebuild — coin-specific fixture */
app.post('/api/v2/:coin/wallet/:walletId/tx/build', (req, res) => {
res.json(loadFixture(coinFixtures(req.params.coin).prebuildTx));
});
/** Transaction submit — coin-specific fixture */
app.post('/api/v2/:coin/wallet/:walletId/tx/send', (req, res) => {
res.json(loadFixture(coinFixtures(req.params.coin).sendTx));
});
const server = http.createServer(app);
const port = await listen(server);
return { port, calls, close: () => close(server) };
}