Skip to content

Commit

Permalink
Merge pull request #354 from bob-collective/feat/status
Browse files Browse the repository at this point in the history
feat: add order status
  • Loading branch information
gregdhill authored Sep 18, 2024
2 parents 1bcd81c + 2cd5f89 commit eba2ee1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 13 deletions.
2 changes: 1 addition & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gobob/bob-sdk",
"version": "2.3.2",
"version": "2.3.3",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
Expand Down
37 changes: 27 additions & 10 deletions sdk/src/gateway/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
GatewayStrategy,
EvmAddress,
GatewayTokensInfo,
OrderStatus,
OrderStatusType,
} from "./types";
import { SYMBOL_LOOKUP, ADDRESS_LOOKUP } from "./tokens";
import { createBitcoinPsbt } from "../wallet";
Expand Down Expand Up @@ -137,7 +139,7 @@ export class GatewayApiClient {
...quote,
fee: quote.fee + (params.gasRefill || 0),
baseToken: ADDRESS_LOOKUP[quote.baseTokenAddress],
outputToken: ADDRESS_LOOKUP[outputTokenAddress],
outputToken: quote.strategyAddress ? ADDRESS_LOOKUP[outputTokenAddress] : undefined,
};
}

Expand Down Expand Up @@ -255,7 +257,7 @@ export class GatewayApiClient {
* @param userAddress The user's EVM address.
* @returns {Promise<GatewayOrder[]>} The array of account orders.
*/
async getOrders(userAddress: EvmAddress): Promise<(GatewayOrder & Optional<GatewayTokensInfo, "outputToken">)[]> {
async getOrders(userAddress: EvmAddress): Promise<(GatewayOrder & GatewayTokensInfo)[]> {
const response = await this.fetchGet(`${this.baseUrl}/orders/${userAddress}`);
const orders: GatewayOrderResponse[] = await response.json();
return orders.map((order) => {
Expand All @@ -273,6 +275,13 @@ export class GatewayApiClient {
const getTokenAddress = (): string | undefined => {
return getFinal(order.baseTokenAddress, order.outputTokenAddress);
}
const getConfirmations = async (esploraClient: EsploraClient, latestHeight?: number) => {
const txStatus = await esploraClient.getTransactionStatus(order.txid);
if (!latestHeight) {
latestHeight = await esploraClient.getLatestHeight();
}
return txStatus.confirmed ? latestHeight - txStatus.block_height! + 1 : 0;
}
return {
gasRefill: order.satsToConvertToEth,
...order,
Expand All @@ -286,14 +295,22 @@ export class GatewayApiClient {
const baseAmount = order.satoshis - order.fee;
return getFinal(baseAmount, order.outputTokenAmount);
},
async getConfirmations(esploraClient: EsploraClient, latestHeight?: number): Promise<number> {
const txStatus = await esploraClient.getTransactionStatus(order.txid);
if (!latestHeight) {
latestHeight = await esploraClient.getLatestHeight();
}

return txStatus.confirmed ? latestHeight - txStatus.block_height! + 1 : 0;
}
getConfirmations,
async getStatus(esploraClient: EsploraClient, latestHeight?: number): Promise<OrderStatus> {
const confirmations = await getConfirmations(esploraClient, latestHeight);
const hasEnoughConfirmations = confirmations >= order.txProofDifficultyFactor;
const data = {
confirmations,
confirmed: hasEnoughConfirmations
};
return order.status
? order.strategyAddress
? order.outputTokenAddress
? { status: OrderStatusType.Success, data }
: { status: OrderStatusType.Failed, data }
: { status: OrderStatusType.Success, data }
: { status: OrderStatusType.Pending, data };
},
};
});
}
Expand Down
9 changes: 8 additions & 1 deletion sdk/src/gateway/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
export { GatewayApiClient as GatewaySDK } from "./client";
export { GatewayQuoteParams, GatewayQuote, GatewayOrder, GatewayStrategyContract } from "./types";
export {
GatewayQuoteParams,
GatewayQuote,
GatewayOrder,
GatewayStrategyContract,
OrderStatusType,
OrderStatus,
} from "./types";
24 changes: 23 additions & 1 deletion sdk/src/gateway/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,22 @@ export type GatewayCreateOrderRequest = {
satoshis: number;
};

export type OrderStatusData = {
confirmations: number;
confirmed: boolean;
};

export enum OrderStatusType {
Success = "Success",
Failed = "Failed",
Pending = "Pending",
}

export type OrderStatus =
| { status: OrderStatusType.Success; data: OrderStatusData }
| { status: OrderStatusType.Failed; data: OrderStatusData }
| { status: OrderStatusType.Pending; data: OrderStatusData };

export interface GatewayOrderResponse {
/** @description The gateway address */
gatewayAddress: EvmAddress;
Expand Down Expand Up @@ -218,6 +234,8 @@ export interface GatewayOrderResponse {
outputTokenAddress?: EvmAddress;
/** @description The output amount (from strategies) */
outputTokenAmount?: string;
/** @description The tx hash on the EVM chain */
txHash?: string;
/** @description Get the actual token address received */
getTokenAddress(): string | undefined;
/** @description Get the actual token received */
Expand All @@ -226,6 +244,8 @@ export interface GatewayOrderResponse {
getAmount(): string | number | undefined;
/** @description Get the number of confirmations */
getConfirmations(esploraClient: EsploraClient, latestHeight?: number): Promise<number>;
/** @description Get the actual order status */
getStatus(esploraClient: EsploraClient, latestHeight?: number): Promise<OrderStatus>;
};

/** Order given by the Gateway API once the bitcoin tx is submitted */
Expand All @@ -238,8 +258,10 @@ export type GatewayOrder = Omit<
>;

export type GatewayTokensInfo = {
/** @description The base token (e.g. wBTC or tBTC) */
baseToken: Token,
outputToken: Token,
/** @description The output token (e.g. uniBTC or SolvBTC.BBN) */
outputToken?: Token,
};

/** @dev Internal */
Expand Down

0 comments on commit eba2ee1

Please sign in to comment.