From 18ecd6e1d4e2831694840292525a3330631cf88d Mon Sep 17 00:00:00 2001 From: Mahmoud Aboelenein Date: Fri, 5 Apr 2024 12:09:34 +0200 Subject: [PATCH] code review changes --- src/adapters/satsConnectAdapter.ts | 193 ++++++++++++++++++----------- src/runes/index.ts | 64 +++++----- 2 files changed, 155 insertions(+), 102 deletions(-) diff --git a/src/adapters/satsConnectAdapter.ts b/src/adapters/satsConnectAdapter.ts index 309072d..a1b3585 100644 --- a/src/adapters/satsConnectAdapter.ts +++ b/src/adapters/satsConnectAdapter.ts @@ -1,4 +1,4 @@ -import { RunesApi } from '../runes'; +import { getRunesApiClient, RunesApi } from '../runes'; import { Params, Requests } from '../request'; import { RpcErrorCode, RpcResult } from '../types'; @@ -8,45 +8,46 @@ abstract class SatsConnectAdapter { private async mintRunes(params: Params<'runes_mint'>): Promise> { try { const orderResponse = await new RunesApi(params.network).createMintOrder(params); - if (orderResponse.data) { - const paymentResponse = await this.requestInternal('sendTransfer', { - recipients: [ - { - address: orderResponse.data.fundAddress, - amount: orderResponse.data.fundAmount, - }, - ], - }); - if (paymentResponse?.status === 'success') { - await new RunesApi(params.network).executeMint( - orderResponse.data.orderId, - paymentResponse.result.txid - ); - return { - status: 'success', - result: { - orderId: orderResponse.data.orderId, - fundTransactionId: paymentResponse.result.txid, - }, - }; - } else { - return { - status: 'error', - error: { - code: RpcErrorCode.USER_REJECTION, - message: 'User rejected the payment request', - }, - }; - } - } else { + if (!orderResponse.data) { return { status: 'error', error: { - code: RpcErrorCode.INTERNAL_ERROR, - message: orderResponse.error, + code: + orderResponse.error.code === 400 + ? RpcErrorCode.INVALID_REQUEST + : RpcErrorCode.INTERNAL_ERROR, + message: orderResponse.error.message, }, }; } + const paymentResponse = await this.requestInternal('sendTransfer', { + recipients: [ + { + address: orderResponse.data.fundAddress, + amount: orderResponse.data.fundAmount, + }, + ], + }); + if (paymentResponse?.status !== 'success') { + return { + status: 'error', + error: { + code: RpcErrorCode.USER_REJECTION, + message: 'User rejected the payment request', + }, + }; + } + await new RunesApi(params.network).executeMint( + orderResponse.data.orderId, + paymentResponse.result.txid + ); + return { + status: 'success', + result: { + orderId: orderResponse.data.orderId, + fundTransactionId: paymentResponse.result.txid, + }, + }; } catch (error) { return { status: 'error', @@ -61,45 +62,46 @@ abstract class SatsConnectAdapter { private async etchRunes(params: Params<'runes_etch'>): Promise> { try { const orderResponse = await new RunesApi(params.network).createEtchOrder(params); - if (orderResponse.data) { - const paymentResponse = await this.requestInternal('sendTransfer', { - recipients: [ - { - address: orderResponse.data.fundAddress, - amount: orderResponse.data.fundAmount, - }, - ], - }); - if (paymentResponse?.status === 'success') { - await new RunesApi(params.network).executeEtch( - orderResponse.data.orderId, - paymentResponse.result.txid - ); - return { - status: 'success', - result: { - orderId: orderResponse.data.orderId, - fundTransactionId: paymentResponse.result.txid, - }, - }; - } else { - return { - status: 'error', - error: { - code: RpcErrorCode.USER_REJECTION, - message: 'User rejected the payment request', - }, - }; - } - } else { + if (!orderResponse.data) { return { status: 'error', error: { - code: RpcErrorCode.INTERNAL_ERROR, - message: orderResponse.error, + code: + orderResponse.error.code === 400 + ? RpcErrorCode.INVALID_REQUEST + : RpcErrorCode.INTERNAL_ERROR, + message: orderResponse.error.message, }, }; } + const paymentResponse = await this.requestInternal('sendTransfer', { + recipients: [ + { + address: orderResponse.data.fundAddress, + amount: orderResponse.data.fundAmount, + }, + ], + }); + if (paymentResponse?.status !== 'success') { + return { + status: 'error', + error: { + code: RpcErrorCode.USER_REJECTION, + message: 'User rejected the payment request', + }, + }; + } + await new RunesApi(params.network).executeEtch( + orderResponse.data.orderId, + paymentResponse.result.txid + ); + return { + status: 'success', + result: { + orderId: orderResponse.data.orderId, + fundTransactionId: paymentResponse.result.txid, + }, + }; } catch (error) { return { status: 'error', @@ -111,6 +113,50 @@ abstract class SatsConnectAdapter { } } + private async estimateMint( + params: Params<'runes_estimateMint'> + ): Promise> { + const response = await getRunesApiClient( + (params as Params<'runes_estimateMint'>).network + ).estimateMintCost(params as Params<'runes_estimateMint'>); + if (response.data) { + return { + status: 'success', + result: response.data, + }; + } + return { + status: 'error', + error: { + code: + response.error.code === 400 ? RpcErrorCode.INVALID_REQUEST : RpcErrorCode.INTERNAL_ERROR, + message: response.error.message, + }, + }; + } + + private async estimateEtch( + params: Params<'runes_estimateEtch'> + ): Promise> { + const response = await getRunesApiClient( + (params as Params<'runes_estimateEtch'>).network + ).estimateEtchCost(params as Params<'runes_estimateEtch'>); + if (response.data) { + return { + status: 'success', + result: response.data, + }; + } + return { + status: 'error', + error: { + code: + response.error.code === 400 ? RpcErrorCode.INVALID_REQUEST : RpcErrorCode.INTERNAL_ERROR, + message: response.error.message, + }, + }; + } + async request( method: Method, params: Params @@ -121,13 +167,14 @@ abstract class SatsConnectAdapter { case 'runes_etch': return this.etchRunes(params as Params<'runes_etch'>) as Promise>; case 'runes_estimateMint': - return new RunesApi((params as Params<'runes_estimateMint'>).network).estimateMintCost( - params as Params<'runes_estimateMint'> - ) as Promise>; + return this.estimateMint(params as Params<'runes_estimateMint'>) as Promise< + RpcResult + >; case 'runes_estimateEtch': - return new RunesApi((params as Params<'runes_estimateEtch'>).network).estimateEtchCost( - params as Params<'runes_estimateEtch'> - ) as Promise>; + return this.estimateEtch(params as Params<'runes_estimateEtch'>) as Promise< + RpcResult + >; + default: return this.requestInternal(method, params); } diff --git a/src/runes/index.ts b/src/runes/index.ts index 688ded1..5a1eb04 100644 --- a/src/runes/index.ts +++ b/src/runes/index.ts @@ -8,7 +8,7 @@ import { } from './types'; import { BitcoinNetworkType, RpcErrorCode, RpcResult } from '../types'; -import axios, { AxiosInstance } from 'axios'; +import axios, { Axios, AxiosError, AxiosInstance } from 'axios'; export const RUNES_API_BASE_URL = (network: BitcoinNetworkType = BitcoinNetworkType.Mainnet) => `https://ordinals${network === BitcoinNetworkType.Testnet ? '-testnet' : ''}.xverse.app/v1/runes`; @@ -22,52 +22,38 @@ export class RunesApi { }); } - estimateMintCost = async ( - mintParams: EstimateMintOrderRequest - ): Promise> => { + estimateMintCost = async (mintParams: EstimateMintOrderRequest) => { try { const response = await this.client.post('/mint/estimate', { ...mintParams, }); return { - status: 'success', - result: { - costBreakdown: response.data.costBreakdown, - totalCost: response.data.totalCost, - totalSize: response.data.totalSize, - }, + data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - status: 'error', error: { - code: RpcErrorCode.INTERNAL_ERROR, - message: error.message, + code: err.response?.status, + message: error.data.message, }, }; } }; - estimateEtchCost = async ( - etchParams: EstimateEtchOrderRequest - ): Promise> => { + estimateEtchCost = async (etchParams: EstimateEtchOrderRequest) => { try { const response = await this.client.post('/etch/estimate', { ...etchParams, }); return { - status: 'success', - result: { - costBreakdown: response.data.costBreakdown, - totalCost: response.data.totalCost, - totalSize: response.data.totalSize, - }, + data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - status: 'error', error: { - code: RpcErrorCode.INTERNAL_ERROR, + code: err.response?.status, message: error.data.message, }, }; @@ -83,8 +69,12 @@ export class RunesApi { data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - error: error.data.message, + error: { + code: err.response?.status, + message: error.data.message, + }, }; } }; @@ -98,8 +88,12 @@ export class RunesApi { data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - error: error.data.message, + error: { + code: err.response?.status, + message: error.data.message, + }, }; } }; @@ -113,8 +107,12 @@ export class RunesApi { data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - error: error.data.message, + error: { + code: err.response?.status, + message: error.data.message, + }, }; } }; @@ -128,11 +126,19 @@ export class RunesApi { data: response.data, }; } catch (error) { + const err = error as AxiosError; return { - error: error.data.message, + error: { + code: err.response?.status, + message: error.data.message, + }, }; } }; } -export default RunesApi; +const testnetClient = new RunesApi(BitcoinNetworkType.Testnet); +const mainnetClient = new RunesApi(BitcoinNetworkType.Mainnet); + +export const getRunesApiClient = (network: BitcoinNetworkType = BitcoinNetworkType.Mainnet) => + network === BitcoinNetworkType.Mainnet ? mainnetClient : testnetClient;