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
3 changes: 3 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/blockLatest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"height": 800000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - i'd like for this to represent more complete block data. even if all that's required is height a full btc block might be nice here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will look into that

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "backup-key-id",
"pub": "xpub661MyMwAqRbcEnWZUJZRDiFY4SwUJdfPDLposNTiqZSvETPaQSkBsKJkCPmtptoc6iBZsG84qncYi1K1NUWjELHNfNjhTLGU2KvTDP9Evui",
"source": "backup",
"type": "independent"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"id": "bitgo-key-id",
"pub": "xpub661MyMwAqRbcF5aJh6F6ToXGzgTs7pfPxgFx1QLGzUx6FfehAodsCW1Zv4DRb5P95BVg8birSFoMQVWpKhL5wLogDNxiusG4CCtouPeDzfK",
"source": "bitgo",
"type": "independent",
"isBitGo": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "user-key-id",
"pub": "xpub661MyMwAqRbcEvJQx6spkkHLRgtjxmVdyDSvbDt2m9NFpbkHdcu5WJsHHHqFxNATbNHnhMWJiwckoMqF75EpcNhU9xeVM4oDS7urM3os4BH",
"source": "user",
"type": "independent"
}
19 changes: 19 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/getWallet.hteth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "test-wallet-id",
"coin": "hteth",
"type": "advanced",
"multisigType": "onchain",
"keys": ["user-key-id", "backup-key-id", "bitgo-key-id"],
"isCold": true,
"m": 2,
"n": 3,
"enterprise": "test-enterprise",
"label": "test-wallet",
"balance": 0,
"balanceString": "0",
"confirmedBalanceString": "0",
"spendableBalanceString": "0",
"deleted": false,
"approvalsRequired": 1,
"coinSpecific": {}
}
19 changes: 19 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/getWallet.tbtc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "test-wallet-id",
"coin": "tbtc",
"type": "advanced",
"multisigType": "onchain",
"keys": ["user-key-id", "backup-key-id", "bitgo-key-id"],
"isCold": true,
"m": 2,
"n": 3,
"enterprise": "test-enterprise",
"label": "test-wallet",
"balance": 0,
"balanceString": "0",
"confirmedBalanceString": "0",
"spendableBalanceString": "0",
"deleted": false,
"approvalsRequired": 1,
"coinSpecific": {}
}
11 changes: 11 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/prebuildTx.hteth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"coin": "hteth",
"recipients": [
{
"address": "0xe01866e64418db20a2831e41eb11eca2a77245a3",
"amount": "100000000000000"
}
],
"nextContractSequenceId": 1,
"expireTime": 1893456000
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"txHex": "70736274ff01005e0200000001d89f04fb23bfe665e2d5a64c24452581a3cca2671a1fa6b4e404bccb6fc9f46f0100000000ffffffff0110270000000000002200206a2459d26e8c6ca0595ad9b9e952ec8bdbd08b49cba186d64d3fb3c248c40bea000000000001012ba086010000000000220020b41d3a1e7ae51e81e1f5ac6518d6a4c449f1e1744461b9a298452913c7c14a9e01056952210295bc96ecdb5ceae2716051cd835ec0e635ff3ab464a992c0b2d7dbdf969d682021038c69636106774394c8369affe354e33b63a0deb196278320be2eaa273a5dcf542102020e1b0585251821432d92d3d716774aee750cb0758b52d4e51a480a952d410153ae220602020e1b0585251821432d92d3d716774aee750cb0758b52d4e51a480a952d410114d3b12b170000000000000000140000000000000022060295bc96ecdb5ceae2716051cd835ec0e635ff3ab464a992c0b2d7dbdf969d6820146bf51aa8000000000000000014000000000000002206038c69636106774394c8369affe354e33b63a0deb196278320be2eaa273a5dcf5414460c6594000000000000000014000000000000000000",
"txInfo": { "nP2SHInputs": 0, "nSegwitInputs": 1, "nOutputs": 1 }
}
14 changes: 14 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/sendTx.hteth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"transfer": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for the transfers, something that looks a bit more like our full transfer object might be nice

"id": "test-transfer-id",
"coin": "hteth",
"txid": "0xtest-eth-tx-id",
"state": "signed",
"value": -100000000000000,
"valueString": "-100000000000000",
"entries": []
},
"txid": "0xtest-eth-tx-id",
"tx": "0x",
"status": "signed"
}
14 changes: 14 additions & 0 deletions src/__tests__/integration/fixtures/bitgo/sendTx.tbtc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"transfer": {
"id": "test-transfer-id",
"coin": "tbtc",
"txid": "test-tx-id",
"state": "signed",
"value": -10202,
"valueString": "-10202",
"entries": []
},
"txid": "test-tx-id",
"tx": "01000000000101030a0000",
"status": "signed"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"signature": "0xa1b2c3d4e5f60718293a4b5c6d7e8f9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789011b"
}
3 changes: 3 additions & 0 deletions src/__tests__/integration/fixtures/keyProvider/sign.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"signature": "70736274ff01005e0200000001d89f04fb23bfe665e2d5a64c24452581a3cca2671a1fa6b4e404bccb6fc9f46f0100000000ffffffff0110270000000000002200206a2459d26e8c6ca0595ad9b9e952ec8bdbd08b49cba186d64d3fb3c248c40bea000000000001012ba086010000000000220020b41d3a1e7ae51e81e1f5ac6518d6a4c449f1e1744461b9a298452913c7c14a9e01056952210295bc96ecdb5ceae2716051cd835ec0e635ff3ab464a992c0b2d7dbdf969d682021038c69636106774394c8369affe354e33b63a0deb196278320be2eaa273a5dcf542102020e1b0585251821432d92d3d716774aee750cb0758b52d4e51a480a952d410153ae220602020e1b0585251821432d92d3d716774aee750cb0758b52d4e51a480a952d410114d3b12b170000000000000000140000000000000022060295bc96ecdb5ceae2716051cd835ec0e635ff3ab464a992c0b2d7dbdf969d6820146bf51aa8000000000000000014000000000000002206038c69636106774394c8369affe354e33b63a0deb196278320be2eaa273a5dcf5414460c6594000000000000000014000000000000000000"
}
59 changes: 56 additions & 3 deletions src/__tests__/integration/helpers/mockBitgoServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,28 @@ export interface MockBitgoServer {

const FIXTURES_DIR = path.resolve(__dirname, '../fixtures/bitgo');

function loadFixture(name: string): unknown {
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[] = [];

Expand All @@ -43,17 +61,52 @@ export async function startMockBitgoServer(): Promise<MockBitgoServer> {
const source = req.body?.source;
const fixtureName =
source === 'user' ? 'addKey.user' : source === 'backup' ? 'addKey.backup' : 'addKey.bitgo';
const fixture = loadFixture(fixtureName) as Record<string, unknown>;
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') as Record<string, unknown>;
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);

Expand Down
23 changes: 23 additions & 0 deletions src/__tests__/integration/helpers/mockKeyProviderServer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import * as http from 'http';
import * as path from 'path';
import express from 'express';
import { BitGoAPI } from '@bitgo-beta/sdk-api';
import { Hteth } from '@bitgo-beta/sdk-coin-eth';
import { Tbtc } from '@bitgo-beta/sdk-coin-btc';
import { listen, close } from './servers';

function loadKeyProviderFixture(name: string): Record<string, unknown> {
return require(`${path.resolve(__dirname, '../fixtures/keyProvider')}/${name}.json`);
}

export interface MockKeyProviderCall {
method: string;
path: string;
Expand Down Expand Up @@ -67,6 +72,24 @@ export async function startMockKeyProviderServer(): Promise<MockKeyProviderServe
res.json({ pub, coin, source, type });
});

/** Local signing mode — AWM retrieves the stored key to sign locally */
app.get('/key/:pub', (req, res) => {
const entry = keyStore.get(req.params.pub);
if (!entry) {
res.status(404).json({ message: `Key not found: ${req.params.pub}` });
return;
}
res.json({ pub: req.params.pub, ...entry });
});

/** External signing mode — key provider signs the payload, returns signed PSBT or ETH sig.
* ETH signablePayload starts with 0x (operation hash), BTC is a PSBT hex. */
app.post('/sign', (req, res) => {
const { signablePayload } = req.body;
const isEth = typeof signablePayload === 'string' && signablePayload.startsWith('0x');
res.json(loadKeyProviderFixture(isEth ? 'sign.eth' : 'sign'));
});

const server = http.createServer(app);
const port = await listen(server);

Expand Down
Loading
Loading