Skip to content

Commit

Permalink
feat: add bitgo network methods to trading class
Browse files Browse the repository at this point in the history
PX-262

TICKET: PX-262
  • Loading branch information
mmcshinsky-bitgo committed Dec 7, 2023
1 parent 8ff1d25 commit c249300
Show file tree
Hide file tree
Showing 12 changed files with 18,972 additions and 16,483 deletions.
31 changes: 31 additions & 0 deletions examples/ts/trade/get-trading-wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Get a trading wallet
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
*/

import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

const OFC_WALLET_ID = process.env.OFC_WALLET_ID;

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
const wallet = await bitgo.coin('ofc').wallets().get({ id: OFC_WALLET_ID });

console.log('Wallet:', wallet);

const tradingAccount = wallet.toTradingAccount();

console.log('Trading Wallet:', tradingAccount);
}

main().catch((e) => console.error(e));
28 changes: 28 additions & 0 deletions examples/ts/trade/list-trading-wallets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Get a list of trading wallets
* Returned list is a list of each ofc coin with the same wallet id
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
*/

import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
const wallets = await bitgo.coin('ofc').wallets().list();

console.log('Trading Wallets:', JSON.stringify(wallets, null, 2));
}

main().catch((e) => console.error(e));

// const tradingAccount = wallet.toTradingAccount();
47 changes: 47 additions & 0 deletions examples/ts/trade/network/create-allocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Create a network allocation
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
*/

import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

const OFC_WALLET_ID = process.env.OFC_WALLET_ID;
const OFC_WALLET_PASSPHRASE = process.env.OFC_WALLET_PASSPHRASE as string;

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
const wallet = await bitgo.coin('ofc').wallets().get({ id: OFC_WALLET_ID });
const tradingAccount = wallet.toTradingAccount();
const tradingNetwork = tradingAccount.toNetwork();

const body = {
connectionId: 'connection-id',
clientExternalId: 'one-time-uuid-v4', // e.g. uuidV4(),
amount: {
currency: 'tbtc',
quantity: '1000000', // in satoshis (base amount)
},
notes: 'Private note that you can view and edit',
nonce: '', // e.g. crypto.randomBytes(32).toString('hex'),
};

const submission = await tradingNetwork.prepareAllocation({ walletPassphrase: OFC_WALLET_PASSPHRASE, ...body });

// Allocation
tradingNetwork.createAllocation(submission);

// Deallocation
tradingNetwork.createDeallocation(submission);
}

main().catch((e) => console.error(e));
31 changes: 31 additions & 0 deletions examples/ts/trade/network/get-balances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Get a list of currenct network balances
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
*/

import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

const OFC_WALLET_ID = process.env.OFC_WALLET_ID;

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
const tradingAccount = (await bitgo.coin('ofc').wallets().get({ id: OFC_WALLET_ID })).toTradingAccount();

const tradingNetwork = tradingAccount.toNetwork();

const tradingNetworkBalances = await tradingNetwork.getBalances();

console.log('Balances', tradingNetworkBalances);
}

main().catch((e) => console.error(e));
42 changes: 42 additions & 0 deletions examples/ts/trade/network/get-supported-currencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Get a list of supported currencies
* Supported currencies are returned that are valid for the given
* network(s) you would like to perform an allocation or deallocation
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
*/

import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

const OFC_WALLET_ID = process.env.OFC_WALLET_ID;

const bitgo = new BitGoAPI({
accessToken: process.env.TESTNET_ACCESS_TOKEN,
env: 'test',
});

const coin = 'ofc';
bitgo.register(coin, coins.Ofc.createInstance);

async function main() {
const tradingAccount = (await bitgo.coin('ofc').wallets().get({ id: OFC_WALLET_ID })).toTradingAccount();

const tradingNetwork = tradingAccount.toNetwork();

const tradingNetworkBalances = await tradingNetwork.getBalances();

const partnerIds = Object.values(tradingNetworkBalances.networkBalances).reduce<string[]>(
(a, c) => [...a, c.partnerId],
[]
);

const supportedCurrencies = await tradingNetwork.getSupportedCurrencies({
partnerIds,
});

console.log('Supported Currencies:', supportedCurrencies);
}

main().catch((e) => console.error(e));
3 changes: 2 additions & 1 deletion modules/sdk-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
"secp256k1": "5.0.0",
"strip-hex-prefix": "^1.0.0",
"superagent": "^3.8.3",
"tweetnacl": "^1.0.3"
"tweetnacl": "^1.0.3",
"uuid": "^8.3.2"
},
"devDependencies": {
"@openpgp/web-stream-tools": "0.0.14",
Expand Down
3 changes: 3 additions & 0 deletions modules/sdk-core/src/bitgo/trading/iTradingAccount.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ITradingNetwork } from './network';

export interface SignPayloadParameters {
payload: string | Record<string, unknown>;
walletPassphrase: string;
Expand All @@ -6,4 +8,5 @@ export interface SignPayloadParameters {
export interface ITradingAccount {
readonly id: string;
signPayload(params: SignPayloadParameters): Promise<string>;
toNetwork(): ITradingNetwork;
}
2 changes: 2 additions & 0 deletions modules/sdk-core/src/bitgo/trading/network/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './network';
export * from './types';
177 changes: 177 additions & 0 deletions modules/sdk-core/src/bitgo/trading/network/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { v4 as uuidV4 } from 'uuid';
import crypto from 'crypto';
import { BitGoBase } from '../../bitgoBase';
import { IWallet } from '../../wallet';
import {
CreateNetworkAllocationParams,
CreateNetworkAllocationResponse,
CreateNetworkConnectionParams,
CreateNetworkConnectionResponse,
CreateNetworkDeallocationParams,
CreateNetworkDeallocationResponse,
GetNetworkAllocationByIdParams,
GetNetworkAllocationByIdResponse,
GetNetworkAllocationsParams,
GetNetworkAllocationsResponse,
GetNetworkBalancesParams,
GetNetworkBalancesResponse,
GetNetworkConnectionByIdParams,
GetNetworkConnectionByIdResponse,
GetNetworkConnectionsParams,
GetNetworkConnectionsResponse,
GetNetworkSettlementByIdParams,
GetNetworkSettlementByIdResponse,
GetNetworkSettlementTransfersParams,
GetNetworkSettlementTransfersResponse,
GetNetworkSettlementsParams,
GetNetworkSettlementsResponse,
GetNetworkSupportedCurrenciesParams,
GetNetworkSupportedCurrenciesResponse,
ITradingNetwork,
UpdateNetworkConnectionParams,
UpdateNetworkConnectionResponse,
} from './types';

export class TradingNetwork implements ITradingNetwork {
private readonly bitgo: BitGoBase;
private readonly enterpriseId: string;

public wallet: IWallet;

constructor(enterpriseId: string, wallet: IWallet, bitgo: BitGoBase) {
this.enterpriseId = enterpriseId;
this.wallet = wallet;
this.bitgo = bitgo;
}

getBalances(params?: GetNetworkBalancesParams): Promise<GetNetworkBalancesResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/balances`);
return this.bitgo.get(url).send(params).result();
}

getSupportedCurrencies(params: GetNetworkSupportedCurrenciesParams): Promise<GetNetworkSupportedCurrenciesResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/supportedCurrencies`);
return this.bitgo.get(url).send(params).result();
}

getConnections(params?: GetNetworkConnectionsParams): Promise<GetNetworkConnectionsResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections`);
return this.bitgo.get(url).send(params).result();
}

getConnectionById({
connectionId,
...params
}: GetNetworkConnectionByIdParams): Promise<GetNetworkConnectionByIdResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections/${connectionId}`
);
return this.bitgo.get(url).send(params).result();
}

createConnection(params: CreateNetworkConnectionParams): Promise<CreateNetworkConnectionResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections`);
return this.bitgo.post(url).send(params).result();
}

updateConnection(params: UpdateNetworkConnectionParams): Promise<UpdateNetworkConnectionResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections`);
return this.bitgo.put(url).send(params).result();
}

getAllocations(params: GetNetworkAllocationsParams): Promise<GetNetworkAllocationsResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/allocations`);
return this.bitgo.get(url).send(params).result();
}

getAllocationById({
allocationId,
...params
}: GetNetworkAllocationByIdParams): Promise<GetNetworkAllocationByIdResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/allocations/${allocationId}`
);
return this.bitgo.get(url).send(params).result();
}

/**
* Prepare an allocation for submission
* @param {string} walletPassphrase ofc wallet passphrase
* @param {string} connectionId connection to whom to make the allocation or deallocation
* @param {string=} clientExternalId one time generated uuid v4
* @param {string} currency currency for which the allocation should be made. e.g. btc / tbtc
* @param {string} quantity base amount. e.g. 10000000 (1 BTC)
* @param {string} notes Private note that you can view and edit
* @param {string=} nonce one time generated string .e.g. crypto.randomBytes(32).toString('hex')
* @returns
*/
async prepareAllocation({
walletPassphrase,
...body
}: Omit<CreateNetworkAllocationParams, 'payload' | 'signature'> & {
walletPassphrase: string;
clientExternalId?: string;
nonce?: string;
}): Promise<CreateNetworkAllocationParams> {
if (!body.clientExternalId) {
body.clientExternalId = uuidV4();
}
if (!body.nonce) {
body.nonce = crypto.randomBytes(32).toString('hex');
}

const payload = JSON.stringify(body);

const prv = await this.wallet.getPrv({ walletPassphrase });
const signedBuffer: Buffer = await this.wallet.baseCoin.signMessage({ prv }, payload);
const signature = signedBuffer.toString('hex');

return {
...body,
payload,
signature,
};
}

createAllocation({
connectionId,
...params
}: CreateNetworkAllocationParams): Promise<CreateNetworkAllocationResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections/${connectionId}/allocations`
);
return this.bitgo.post(url).send(params).result();
}

createDeallocation({
connectionId,
...params
}: CreateNetworkDeallocationParams): Promise<CreateNetworkDeallocationResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/connections/${connectionId}/deallocations`
);
return this.bitgo.post(url).send(params).result();
}

getSettlements(params?: GetNetworkSettlementsParams): Promise<GetNetworkSettlementsResponse> {
const url = this.bitgo.microservicesUrl(`/api/network/v1/enterprises/${this.enterpriseId}/clients/settlements`);
return this.bitgo.get(url).send(params).result();
}

getSettlementById({
settlementId,
...params
}: GetNetworkSettlementByIdParams): Promise<GetNetworkSettlementByIdResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/settlements/${settlementId}`
);
return this.bitgo.get(url).send(params).result();
}

getSettlementTransfers(params: GetNetworkSettlementTransfersParams): Promise<GetNetworkSettlementTransfersResponse> {
const url = this.bitgo.microservicesUrl(
`/api/network/v1/enterprises/${this.enterpriseId}/clients/settlementTransfers`
);
return this.bitgo.get(url).send(params).result();
}
}
Loading

0 comments on commit c249300

Please sign in to comment.