diff --git a/.changeset/chilled-students-laugh.md b/.changeset/chilled-students-laugh.md new file mode 100644 index 0000000..bde4399 --- /dev/null +++ b/.changeset/chilled-students-laugh.md @@ -0,0 +1,5 @@ +--- +"@coinbase-platform/onchain": patch +--- + +fix: make rpc client correctly infer response type diff --git a/packages/onchain/src/address/list-address-transactions.ts b/packages/onchain/src/address/list-address-transactions.ts index 3dbec47..183e263 100644 --- a/packages/onchain/src/address/list-address-transactions.ts +++ b/packages/onchain/src/address/list-address-transactions.ts @@ -1,28 +1,15 @@ import type { RpcClient, RpcRequestConfig } from "../rpc"; -type AddressTransaction = { - name: string; - hash: string; - blockHash: string; - blockHeight: string; - // TODO: can be narrowed to a union - status: string; -}; - -export type ListAddressTransactionsResponse = { - id: number; - jsonrpc: string; - result: { - addressTransactions: AddressTransaction[]; - nextPageToken?: string; - }; -}; - export type ListAddressTransactionsParameters = Extract< RpcRequestConfig, { method: "cdp_listAddressTransactions" } >["parameters"]; +export type ListAddressTransactionsResponse = Extract< + RpcRequestConfig, + { method: "cdp_listAddressTransactions" } +>["response"]["result"]; + /** * @returns The list of transactions of specified address. * @@ -46,8 +33,9 @@ export async function listAddressTransactions( rpc: RpcClient, parameters: ListAddressTransactionsParameters, ): Promise { - return await rpc.request({ + const response = await rpc.request({ method: "cdp_listAddressTransactions", parameters, }); + return response.result; } diff --git a/packages/onchain/src/balance/list-balance-details.ts b/packages/onchain/src/balance/list-balance-details.ts index b821508..ec958dc 100644 --- a/packages/onchain/src/balance/list-balance-details.ts +++ b/packages/onchain/src/balance/list-balance-details.ts @@ -1,37 +1,15 @@ import type { RpcClient, RpcRequestConfig } from "../rpc"; -type BalanceDetails = { - asset: { - id: string; - // TODO: Add all token types - type: - | "native" - | "erc20" - | "erc721" - | "erc1155" - | "creditAlphanum4" - | "fa2" - | (string & {}); - groupId: string; - subGroupId: string; - }; - value: number; -}; - -export type ListBalanceDetailsResponse = { - id: number; - jsonrpc: string; - result: { - balances: BalanceDetails[]; - nextPageToken?: string; - }; -}; - export type ListBalanceDetailsParameters = Extract< RpcRequestConfig, { method: "cdp_listBalanceDetails" } >["parameters"]; +export type ListBalanceDetailsResponse = Extract< + RpcRequestConfig, + { method: "cdp_listBalanceDetails" } +>["response"]["result"]; + /** * @returns The list of balance details of assets specified in parameters. * @@ -56,8 +34,9 @@ export async function listBalanceDetails( rpc: RpcClient, parameters: ListBalanceDetailsParameters, ): Promise { - return await rpc.request({ + const response = await rpc.request({ method: "cdp_listBalanceDetails", parameters, }); + return response.result; } diff --git a/packages/onchain/src/balance/list-balance-histories.ts b/packages/onchain/src/balance/list-balance-histories.ts index 806c2a4..483707c 100644 --- a/packages/onchain/src/balance/list-balance-histories.ts +++ b/packages/onchain/src/balance/list-balance-histories.ts @@ -1,25 +1,15 @@ import type { RpcClient, RpcRequestConfig } from "../rpc"; -type BalanceHistory = { - blockHeight: number; - blockHash: string; - value: number; -}; - -export type ListBalanceHistoriesResponse = { - id: number; - jsonrpc: string; - result: { - balanceHistories: BalanceHistory[] | null; - nextPageToken?: string; - }; -}; - export type ListBalanceHistoriesParameters = Extract< RpcRequestConfig, { method: "cdp_listBalanceHistories" } >["parameters"]; +export type ListBalanceHistoriesResponse = Extract< + RpcRequestConfig, + { method: "cdp_listBalanceHistories" } +>["response"]["result"]; + /** * @returns The list of balance histories of assets specified in parameters. * @@ -44,8 +34,9 @@ export async function listBalanceHistories( rpc: RpcClient, parameters: ListBalanceHistoriesParameters, ): Promise { - return await rpc.request({ + const response = await rpc.request({ method: "cdp_listBalanceHistories", parameters, }); + return response.result; } diff --git a/packages/onchain/src/balance/list-balances.ts b/packages/onchain/src/balance/list-balances.ts index eaed43a..af91d8b 100644 --- a/packages/onchain/src/balance/list-balances.ts +++ b/packages/onchain/src/balance/list-balances.ts @@ -1,37 +1,15 @@ import type { RpcClient, RpcRequestConfig } from "../rpc"; -type Balance = { - asset: { - id: string; - // TODO: Add all token types - type: - | "native" - | "erc20" - | "erc721" - | "erc1155" - | "creditAlphanum4" - | "fa2" - | (string & {}); - groupId: string; - subGroupId: string; - }; - value: number; -}; - -export type ListBalancesResponse = { - id: number; - jsonrpc: string; - result: { - balances: Balance[]; - nextPageToken?: string; - }; -}; - export type ListBalancesParameters = Extract< RpcRequestConfig, { method: "cdp_listBalances" } >["parameters"]; +export type ListBalancesResponse = Extract< + RpcRequestConfig, + { method: "cdp_listBalances" } +>["response"]["result"]; + /** * @returns The list of token balances specified in parameters. * @@ -55,8 +33,9 @@ export async function listBalances( rpc: RpcClient, parameters: ListBalancesParameters, ): Promise { - return await rpc.request({ + const response = await rpc.request({ method: "cdp_listBalances", parameters, }); + return response.result; } diff --git a/packages/onchain/src/index.ts b/packages/onchain/src/index.ts index 77637b3..b773013 100644 --- a/packages/onchain/src/index.ts +++ b/packages/onchain/src/index.ts @@ -1,3 +1,8 @@ +export { listAddressTransactions } from "./address/list-address-transactions"; +export type { + ListAddressTransactionsResponse, + ListAddressTransactionsParameters, +} from "./address/list-address-transactions"; export { listBalances } from "./balance/list-balances"; export type { ListBalancesParameters, @@ -13,11 +18,6 @@ export type { ListBalanceHistoriesResponse, ListBalanceHistoriesParameters, } from "./balance/list-balance-histories"; -export { listAddressTransactions } from "./address/list-address-transactions"; -export type { - ListAddressTransactionsResponse, - ListAddressTransactionsParameters, -} from "./address/list-address-transactions"; export { createClient } from "./client"; export type { Client, ClientConfig } from "./client"; export { createRpcClient } from "./rpc"; diff --git a/packages/onchain/src/rpc.ts b/packages/onchain/src/rpc.ts index f47aa2f..c3d08a3 100644 --- a/packages/onchain/src/rpc.ts +++ b/packages/onchain/src/rpc.ts @@ -3,7 +3,21 @@ import * as http from "./http"; export type RpcClient = { __url: string; - request: (config: RpcRequestConfig) => Promise; + request: < + TConfig extends RpcRequestConfig, + TMethod extends RpcRequestConfig["method"], + >( + config: TConfig extends { + method: TMethod; + parameters: infer TParameters; + } + ? { method: TMethod; parameters: TParameters } + : never, + ) => Promise< + TConfig extends { method: TMethod; response: infer TResponse } + ? TResponse + : never + >; }; export type RpcClientConfig = { @@ -44,6 +58,10 @@ export type RpcRequestConfig = /** Number of balances to receive in a page. The default value is 25. The maximum value is 100, and values supplied over this will be coerced to the maximum. */ pageSize?: number; }>; + response: BaseRpcResponse<{ + addressTransactions: RpcAddressTransaction[]; + nextPageToken?: string; + }>; } | { method: "cdp_listBalanceDetails"; @@ -55,6 +73,10 @@ export type RpcRequestConfig = /** Number of balances to receive in a page. The default value is 25. The maximum value is 100, and values supplied over this will be coerced to the maximum. */ pageSize?: number; }>; + response: BaseRpcResponse<{ + balances: RpcBalanceDetails[]; + nextPageToken?: string; + }>; } | { method: "cdp_listBalanceHistories"; @@ -66,6 +88,10 @@ export type RpcRequestConfig = /** Number of balances to receive in a page. The default value is 25. The maximum value is 100, and values supplied over this will be coerced to the maximum. */ pageSize?: number; }>; + response: BaseRpcResponse<{ + balanceHistories: RpcBalanceHistory[] | null; + nextPageToken?: string; + }>; } | { method: "cdp_listBalances"; @@ -76,4 +102,65 @@ export type RpcRequestConfig = /** Number of balances to receive in a page. The default value is 25. The maximum value is 100, and values supplied over this will be coerced to the maximum. */ pageSize?: number; }>; + response: BaseRpcResponse<{ + balances: RpcBalance[]; + nextPageToken?: string; + }>; }; + +type BaseRpcResponse = { + id: number; + jsonrpc: string; + result: TResult; +}; + +export type RpcAddressTransaction = { + name: string; + hash: string; + blockHash: string; + blockHeight: string; + // TODO: can be narrowed to a union + status: string; +}; + +export type RpcBalance = { + asset: { + id: string; + // TODO: Add all token types + type: + | "native" + | "erc20" + | "erc721" + | "erc1155" + | "creditAlphanum4" + | "fa2" + | (string & {}); + groupId: string; + subGroupId: string; + }; + value: number; +}; + +export type RpcBalanceDetails = { + asset: { + id: string; + // TODO: Add all token types + type: + | "native" + | "erc20" + | "erc721" + | "erc1155" + | "creditAlphanum4" + | "fa2" + | (string & {}); + groupId: string; + subGroupId: string; + }; + value: number; +}; + +export type RpcBalanceHistory = { + blockHeight: number; + blockHash: string; + value: number; +};