From 65d138d94574b3131a540f7f1f77030d9896c505 Mon Sep 17 00:00:00 2001 From: goweiss <159821646+goweiss@users.noreply.github.com> Date: Wed, 27 Nov 2024 17:52:43 +0200 Subject: [PATCH] GetPublicKey For NCW (#294) * WLT-658 - GetPublicKey For NCW added two new functions for NCW GetPublicKey * WLT-658 - GetPublicKey For NCW code review fixes * WLT-658 - GetPublicKey For NCW * WLT-658 - GetPublicKey For NCW --- src/api-client.ts | 13 ++++++---- src/common/public_key_info.ts | 45 +++++++++++++++++++++++++++++++++++ src/fireblocks-sdk.ts | 19 +++------------ src/ncw-api-client.ts | 14 +++++++++++ src/ncw-sdk.ts | 21 +++++++++++++++- src/types.ts | 11 +++++++-- 6 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 src/common/public_key_info.ts diff --git a/src/api-client.ts b/src/api-client.ts index 69aaf00a..38d05ceb 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -57,14 +57,19 @@ export class ApiClient { }; } - public async issueGetRequest(rawPath: string, queryStringParams?: object): Promise { + public async issueGetRequest(rawPath: string, queryStringParams?: object, requestOptions?: RequestOptions): Promise { const pathWithParams = queryStringParams ? `${rawPath}?${queryString.stringify(queryStringParams)}` : rawPath; const path = normalizePath(pathWithParams); const token = this.authProvider.signJwt(path); - const res = await this.axiosInstance.get(path, { - headers: {"Authorization": `Bearer ${token}`} - }); + const headers: any = {"Authorization": `Bearer ${token}`}; + + const ncwWalletId = requestOptions?.ncw?.walletId; + if (ncwWalletId) { + headers["X-End-User-Wallet-Id"] = ncwWalletId; + } + + const res = await this.axiosInstance.get(path, { headers }); return res.data; } diff --git a/src/common/public_key_info.ts b/src/common/public_key_info.ts new file mode 100644 index 00000000..34bc0d41 --- /dev/null +++ b/src/common/public_key_info.ts @@ -0,0 +1,45 @@ +import { ApiClient } from "../api-client"; +import { PeerType, PublicKeyInfoArgs, PublicKeyInfoByAccountAssetArgs, PublicKeyInfoForVaultAccountArgs, PublicKeyInformation, PublicKeyResponse, RequestOptions } from "../types"; +import queryString from "query-string"; + +export async function getPublicKeyInfoImpl(peerType: PeerType, args: PublicKeyInfoArgs, apiClient: ApiClient, walletId?: string): Promise { + let url: string; + let requestOptions: RequestOptions; + if (peerType === PeerType.VAULT_ACCOUNT) { + url = `/v1/vault/public_key_info`; + } else if (peerType === PeerType.END_USER_WALLET) { + requestOptions = { ncw: { walletId } }; + url = `/v1/ncw/${walletId}/public_key_info`; + } else { + throw new Error(`Unsupported peer type: ${peerType}`); + } + + const query = queryString.stringify({ + algorithm: args.algorithm, + derivationPath: JSON.stringify(args.derivationPath), + compressed: args.compressed, + }); + url += `?${query}`; + + return await apiClient.issueGetRequest(url, undefined, requestOptions); +} + +export async function getPublicKeyInfoByAccountAssetImpl(peerType: PeerType, args: PublicKeyInfoForVaultAccountArgs | PublicKeyInfoByAccountAssetArgs, apiClient: ApiClient, walletId?: string): Promise { + let url: string; + let requestOptions: RequestOptions; + if (peerType === PeerType.VAULT_ACCOUNT) { + url = `/v1/vault/accounts/${(args as PublicKeyInfoForVaultAccountArgs).vaultAccountId}/${args.assetId}/${args.change}/${args.addressIndex}/public_key_info`; + } else if (peerType === PeerType.END_USER_WALLET) { + requestOptions = { ncw: { walletId } }; + url = `/v1/ncw/${walletId}/accounts/${(args as PublicKeyInfoByAccountAssetArgs).accountId}/${args.assetId}/${args.change}/${args.addressIndex}/public_key_info`; + } else { + throw new Error(`Unsupported peer type: ${peerType}`); + } + + const query = queryString.stringify({ + compressed: args.compressed, + }); + url += `?${query}`; + + return await apiClient.issueGetRequest(url, undefined, requestOptions); +} \ No newline at end of file diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 7bca2d4d..22109fbe 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -172,6 +172,7 @@ import { WithdrawRequestDto, WithdrawResponse } from "./staking"; +import { getPublicKeyInfoByAccountAssetImpl, getPublicKeyInfoImpl } from "./common/public_key_info"; export * from "./types"; @@ -1161,17 +1162,7 @@ export class FireblocksSDK { * @param args */ public async getPublicKeyInfo(args: PublicKeyInfoArgs): Promise { - let url = `/v1/vault/public_key_info`; - if (args.algorithm) { - url += `?algorithm=${args.algorithm}`; - } - if (args.derivationPath) { - url += `&derivationPath=${JSON.stringify(args.derivationPath)}`; - } - if (args.compressed) { - url += `&compressed=${args.compressed}`; - } - return await this.apiClient.issueGetRequest(url); + return await getPublicKeyInfoImpl(PeerType.VAULT_ACCOUNT, args, this.apiClient); } /** @@ -1205,11 +1196,7 @@ export class FireblocksSDK { * @param args */ public async getPublicKeyInfoForVaultAccount(args: PublicKeyInfoForVaultAccountArgs): Promise { - let url = `/v1/vault/accounts/${args.vaultAccountId}/${args.assetId}/${args.change}/${args.addressIndex}/public_key_info`; - if (args.compressed) { - url += `?compressed=${args.compressed}`; - } - return await this.apiClient.issueGetRequest(url); + return await getPublicKeyInfoByAccountAssetImpl(PeerType.VAULT_ACCOUNT, args, this.apiClient); } /** diff --git a/src/ncw-api-client.ts b/src/ncw-api-client.ts index dd3a3fff..c8772790 100644 --- a/src/ncw-api-client.ts +++ b/src/ncw-api-client.ts @@ -5,8 +5,14 @@ import { NCW, UnspentInputsResponse, SigningAlgorithm, + PublicKeyInfoArgs, + PublicKeyInformation, + PublicKeyResponse, + PublicKeyInfoByAccountAssetArgs, + PeerType, } from "./types"; import { NcwSdk } from "./ncw-sdk"; +import { getPublicKeyInfoByAccountAssetImpl, getPublicKeyInfoImpl } from "./common/public_key_info"; export class NcwApiClient implements NcwSdk { private readonly NCW_BASE_PATH = "/v1/ncw/wallets"; @@ -169,4 +175,12 @@ export class NcwApiClient implements NcwSdk { public async getUnspentInputs(walletId: string, accountId: number, assetId: string): Promise { return await this.apiClient.issueGetRequest(`/v1/ncw/${walletId}/accounts/${accountId}/${assetId}/unspent_inputs`); } + + public async getPublicKeyInfo(walletId: string, args: PublicKeyInfoArgs): Promise { + return await getPublicKeyInfoImpl(PeerType.END_USER_WALLET, args, this.apiClient, walletId); + } + + public async getPublicKeyInfoByAccountAsset(walletId: string, args: PublicKeyInfoByAccountAssetArgs): Promise { + return await getPublicKeyInfoByAccountAssetImpl(PeerType.END_USER_WALLET, args, this.apiClient, walletId); + } } diff --git a/src/ncw-sdk.ts b/src/ncw-sdk.ts index dfee9b25..f439bd0f 100644 --- a/src/ncw-sdk.ts +++ b/src/ncw-sdk.ts @@ -1,6 +1,10 @@ import { AssetResponse, Web3PagedResponse, NCW, UnspentInputsResponse, SigningAlgorithm, + PublicKeyInfoArgs, + PublicKeyInformation, + PublicKeyResponse, + PublicKeyInfoByAccountAssetArgs, } from "./types"; export interface NcwSdk { @@ -198,9 +202,24 @@ export interface NcwSdk { * refresh a NCW asset balance * * @param {string} walletId - * @param {string} walletId + * @param {SigningAlgorithm[]} algorithms * @return {*} {Promise} */ setWalletRequiredAlgorithms(walletId: string, algorithms: SigningAlgorithm[]): Promise; + /** + * Get the public key information + * @param {string} walletId + * @param {PublicKeyInfoArgs} args + * @return {*} {Promise} + */ + getPublicKeyInfo(walletId: string, args: PublicKeyInfoArgs): Promise; + + /** + * Get the public key information for an NCW account + * @param {string} walletId + * @param {PublicKeyInfoByAccountAssetArgs} args + * @return {*} {Promise} + */ + getPublicKeyInfoByAccountAsset(walletId: string, args: PublicKeyInfoByAccountAssetArgs): Promise; } diff --git a/src/types.ts b/src/types.ts index 5f743a68..8336e92f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1223,14 +1223,21 @@ export interface PublicKeyInfoArgs { compressed?: boolean; } -export interface PublicKeyInfoForVaultAccountArgs { +export interface BasePublicKeyInfoByAccountAssetArgs { assetId: string; - vaultAccountId: number; change: number; addressIndex: number; compressed?: boolean; } +export interface PublicKeyInfoByAccountAssetArgs extends BasePublicKeyInfoByAccountAssetArgs { + accountId: number; +} + +export interface PublicKeyInfoForVaultAccountArgs extends BasePublicKeyInfoByAccountAssetArgs { + vaultAccountId: number; +} + export interface GasStationInfo { balance: { [asset: string]: string }; configuration: {