Skip to content

Commit

Permalink
add NCW feature (#192)
Browse files Browse the repository at this point in the history
* feat: NCW SDK
  • Loading branch information
amper-fb authored Aug 20, 2023
1 parent 8c4a3bc commit 8a73b3a
Show file tree
Hide file tree
Showing 6 changed files with 368 additions and 5 deletions.
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ export class ApiClient {
if (idempotencyKey) {
headers["Idempotency-Key"] = idempotencyKey;
}

const ncwWalletId = requestOptions?.ncw?.walletId;
if (ncwWalletId) {
headers["X-End-User-Wallet-Id"] = ncwWalletId;
}

const response = await this.axiosInstance.post<T>(path, body, {headers});
return response.data;
}
Expand Down
26 changes: 25 additions & 1 deletion src/fireblocks-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
SettlementRequest,
SettlementResponse,
GetNFTsFilter,
PeerType,
PublicKeyInformation,
DropTransactionResponse,
TokenLink,
Expand Down Expand Up @@ -95,6 +96,8 @@ import {
} from "./types";
import { AxiosProxyConfig, AxiosResponse } from "axios";
import { PIIEncryption } from "./pii-client";
import { NcwApiClient } from "./ncw-api-client";
import { NcwSdk } from "./ncw-sdk";

export * from "./types";

Expand Down Expand Up @@ -133,6 +136,8 @@ export class FireblocksSDK {
private readonly authProvider: IAuthProvider;
private readonly apiBaseUrl: string;
private readonly apiClient: ApiClient;
private readonly apiNcw: NcwApiClient;

private piiClient: PIIEncryption;

/**
Expand All @@ -155,6 +160,18 @@ export class FireblocksSDK {
if (sdkOptions?.travelRuleOptions) {
this.piiClient = new PIIEncryption(sdkOptions.travelRuleOptions);
}

this.apiNcw = new NcwApiClient(this.apiClient);
}

/**
* NCW API Namespace
*
* @readonly
* @type {NcwSdk}
*/
public get NCW(): NcwSdk {
return this.apiNcw;
}

/**
Expand Down Expand Up @@ -798,11 +815,18 @@ export class FireblocksSDK {
* Creates a new transaction with the specified options
*/
public async createTransaction(transactionArguments: TransactionArguments, requestOptions?: RequestOptions, travelRuleEncryptionOptions?: TravelRuleEncryptionOptions): Promise<CreateTransactionResponse> {
const opts = { ...requestOptions };

if (transactionArguments?.travelRuleMessage) {
transactionArguments = await this.piiClient.hybridEncode(transactionArguments, travelRuleEncryptionOptions);
}

return await this.apiClient.issuePostRequest("/v1/transactions", transactionArguments, requestOptions);
if (transactionArguments.source?.type === PeerType.END_USER_WALLET && !opts.ncw?.walletId) {
const { walletId } = transactionArguments.source;
opts.ncw = { ...opts.ncw, walletId };
}

return await this.apiClient.issuePostRequest("/v1/transactions", transactionArguments, opts);
}

/**
Expand Down
121 changes: 121 additions & 0 deletions src/ncw-api-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { ApiClient } from "./api-client";
import {
AssetResponse, DepositAddressResponse, Web3PagedResponse, NCW
} from "./types";
import { NcwSdk } from "./ncw-sdk";

export class NcwApiClient implements NcwSdk {
constructor(private readonly apiClient: ApiClient) {
}

public async createWallet(): Promise<{ walletId: string; enabled: boolean; }> {
return await this.apiClient.issuePostRequest(
`/v1/wallets`,
{});
}

public async getWallet(walletId: string): Promise<{ walletId: string; enabled: boolean; }> {
return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}`);
}

public async enableWallet(walletId: string, enabled: boolean): Promise<void> {
return await this.apiClient.issuePutRequest(
`/v1/wallets/${walletId}/enable`,
{ enabled });
}

public async invokeWalletRpc(walletId: string, deviceId: string, payload: string): Promise<{ result: string; } | { error: { message: string; code?: number; }; }> {
return await this.apiClient.issuePostRequest(
`/v1/wallets/${walletId}/devices/${deviceId}/invoke`,
{ payload });
}

public async createWalletAccount(walletId: string): Promise<{
walletId: string;
accountId: number;
}> {
return await this.apiClient.issuePostRequest(
`/v1/wallets/${walletId}/accounts`,
{});
}

public async getWallets({ pageCursor, pageSize, sort, order }: NCW.GetWalletsPayload = {}): Promise<Web3PagedResponse<NCW.WalletInfo>> {
const params = new URLSearchParams({
...(pageCursor && { pageCursor }),
...(pageSize && { pageSize: pageSize.toString() }),
...(sort && { sort }),
...(order && { order }),
});

return await this.apiClient.issueGetRequest(`/v1/wallets?${params.toString()}`);
}

public async getWalletAccounts(walletId: string, { pageCursor, pageSize, sort, order }: NCW.GetWalletsPayload = {}): Promise<Web3PagedResponse<{
walletId: string;
accountId: number;
}>> {
const params = new URLSearchParams({
...(pageCursor && { pageCursor }),
...(pageSize && { pageSize: pageSize.toString() }),
...(sort && { sort }),
...(order && { order }),
});

return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts?${params.toString()}`);
}

public async getWalletAccount(walletId: string, accountId: number): Promise<{
walletId: string;
accountId: number;
}> {
return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts/${accountId}`);
}

public async getWalletAssets(walletId: string, accountId: number, { pageCursor, pageSize, sort, order }: NCW.GetWalletAssetsPayload = {}): Promise<Web3PagedResponse<NCW.WalletAssetResponse>> {
const params = new URLSearchParams({
...(pageCursor && { pageCursor }),
...(pageSize && { pageSize: pageSize.toString() }),
...(sort && { sort }),
...(order && { order }),
});

return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets?${params.toString()}`);
}

public async getWalletAsset(walletId: string, accountId: number, assetId: string): Promise<NCW.WalletAssetResponse> {
return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets/${assetId}`);
}

public async activateWalletAsset(walletId: string, accountId: number, assetId: string): Promise<NCW.WalletAssetAddress> {
return await this.apiClient.issuePostRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets/${assetId}`, {});
}

public async getWalletAssetAddresses(walletId: string, accountId: number, assetId: string, { pageCursor, pageSize, sort, order }: NCW.GetWalletAddressesPayload = {}): Promise<Web3PagedResponse<NCW.WalletAssetAddress>> {
const params = new URLSearchParams({
...(pageCursor && { pageCursor }),
...(pageSize && { pageSize: pageSize.toString() }),
...(sort && { sort }),
...(order && { order }),
});

return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets/${assetId}/addresses?${params.toString()}`);
}

public async getWalletAssetBalance(walletId: string, accountId: number, assetId: string): Promise<AssetResponse> {
return await this.apiClient.issueGetRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets/${assetId}/balance`);
}

public async refreshWalletAssetBalance(walletId: string, accountId: number, assetId: string): Promise<AssetResponse> {
return await this.apiClient.issuePutRequest(
`/v1/wallets/${walletId}/accounts/${accountId}/assets/${assetId}/balance`,
{});
}
}
136 changes: 136 additions & 0 deletions src/ncw-sdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import {
AssetResponse, Web3PagedResponse, NCW,
} from "./types";

export interface NcwSdk {
/**
* Create a new NCW wallet
*/
createWallet(): Promise<{ walletId: string; enabled: boolean; }>;

/**
* Get a NCW wallet
*
* @param {string} walletId
*/
getWallet(walletId: string): Promise<{ walletId: string; enabled: boolean; }>;

/**
* Enable a NCW wallet
*
* @param {string} walletId
* @param {boolean} enabled
*/
enableWallet(walletId: string, enabled: boolean): Promise<void>;

/**
* Invoke NCW wallet RPC call
*
* @param {string} walletId
* @param {string} deviceId
* @param {string} payload
* @return {*} {(Promise<{ result: string } | { error: { message: string, code?: number } }>)}
*/
invokeWalletRpc(walletId: string, deviceId: string, payload: string): Promise<{ result: string; } | { error: { message: string; code?: number; }; }>;

/**
* Create a new NCW wallet account
*
* @param {string} walletId
*/
createWalletAccount(walletId: string): Promise<{
walletId: string;
accountId: number;
}>;

/**
* Get NCW wallets
*
* @param {GetWalletsPayload} { pageCursor, pageSize, sort, order }
* @return {*} {Promise<Web3PagedResponse<WalletInfo>>}
*/
getWallets({ pageCursor, pageSize, sort, order }: NCW.GetWalletsPayload): Promise<Web3PagedResponse<NCW.WalletInfo>>;

/**
* Get NCW accounts
*
* @param {string} walletId
* @param {GetWalletsPayload} [{ pageCursor, pageSize, sort, order }]
*/
getWalletAccounts(walletId: string, { pageCursor, pageSize, sort, order }?: NCW.GetWalletsPayload): Promise<Web3PagedResponse<{
walletId: string;
accountId: number;
}>>;

/**
* Get a NCW account
*
* @param {string} walletId
* @param {number} accountId
*/
getWalletAccount(walletId: string, accountId: number): Promise<{
walletId: string;
accountId: number;
}>;

/**
* Get NCW assets
*
* @param {string} walletId
* @param {number} accountId
* @param {GetWalletAssetsPayload} [{ pageCursor, pageSize, sort, order }]
* @return {*} {Promise<Web3PagedResponse<NcwWalletAssetResponse>>}
*/
getWalletAssets(walletId: string, accountId: number, { pageCursor, pageSize, sort, order }?: NCW.GetWalletAssetsPayload): Promise<Web3PagedResponse<NCW.WalletAssetResponse>>;

/**
* Get a NCW asset
*
* @param {string} walletId
* @param {number} accountId
* @param {string} assetId
* @return {*} {Promise<NcwWalletAssetResponse>}
*/
getWalletAsset(walletId: string, accountId: number, assetId: string): Promise<NCW.WalletAssetResponse>;

/**
* Activate a NCW asset
*
* @param {string} walletId
* @param {number} accountId
* @param {string} assetId
* @return {*} {Promise<DepositAddressResponse>}
*/
activateWalletAsset(walletId: string, accountId: number, assetId: string): Promise<NCW.WalletAssetAddress>;

/**
* Get a NCW asset addresses
*
* @param {string} walletId
* @param {number} accountId
* @param {string} assetId
* @param {GetWalletAddressesPayload} { pageCursor, pageSize, sort, order }
* @return {*} {Promise<Web3PagedResponse<DepositAddressResponse>>}
*/
getWalletAssetAddresses(walletId: string, accountId: number, assetId: string, { pageCursor, pageSize, sort, order }?: NCW.GetWalletAddressesPayload): Promise<Web3PagedResponse<NCW.WalletAssetAddress>>;

/**
* Get a NCW asset balance
*
* @param {string} walletId
* @param {number} accountId
* @param {string} assetId
* @return {*} {Promise<AssetResponse>}
*/
getWalletAssetBalance(walletId: string, accountId: number, assetId: string): Promise<AssetResponse>;

/**
* refresh a NCW asset balance
*
* @param {string} walletId
* @param {number} accountId
* @param {string} assetId
* @return {*} {Promise<AssetResponse>}
*/
refreshWalletAssetBalance(walletId: string, accountId: number, assetId: string): Promise<AssetResponse>;
}
Loading

0 comments on commit 8a73b3a

Please sign in to comment.