From a6c0502b7668aae0700ddeff7bfccef35161764d Mon Sep 17 00:00:00 2001 From: chenshooker Date: Thu, 15 Jun 2023 10:57:46 +0300 Subject: [PATCH 01/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 9 ++++- src/types.ts | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 261a0183..d298853a 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -80,7 +80,7 @@ import { ValidateCreateTravelRuleTransaction, ValidateFullTravelRuleResult, TravelRuleVasp, - TravelRuleVaspFilter, + TravelRuleVaspFilter, StakingPosition, } from "./types"; import { AxiosProxyConfig, AxiosResponse } from "axios"; import { PIIEncryption } from "./pii-client"; @@ -1458,7 +1458,12 @@ export class FireblocksSDK { public async removeLinkedTokenPermissions(assetId: string, permission: TokenLinkPermissionEntry): Promise { return await this.apiClient.issueDeleteRequest(`/v1/tokenization/tokens/${assetId}/permissions?permission=${permission.permission}&vaultAccountId=${permission.vaultAccountId}`); } - + public async executeStakePositionAction(actionId: string, chainDescriptor: string , body: any) { + return await this.apiClient.issuePostRequest(`/v1/chains/{chainDescriptor}/{actionId}`, body); + } + public async getStakingPositions(chainDescriptor: string): Promise> { + return await this.apiClient.issueGetRequest(`/v1/positions/${chainDescriptor}`); + } /** * Validate VASP details for travel rule compliance * @param travelRuleMessageVaspInfo diff --git a/src/types.ts b/src/types.ts index 331f56e0..b476b87a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1369,3 +1369,88 @@ export interface IssueTokenRequest { issuerAddress?: string; decimals: number; } +export enum TDelegationState { + "error" = "error", + + "activating" = "activating", + "activated" = "activated", + + "deactivating" = "deactivating", + "deactivated" = "deactivated", + + "withdrawing" = "withdrawing", + "withdrawn" = "withdrawn", +} + +interface ISolanaBlockchainData { + /** + * The stake account address matching the stakeAccountId + */ + stakeAccountAddress: string; +} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface IEthereumBlockchainData {} + +export type TBlockchainSpecific = ISolanaBlockchainData | IEthereumBlockchainData; + +export interface StakingPosition { + + /** + * Delegation request id + */ + delegationRequestId: string; + + /** + * The source vault account to stake from + */ + vaultAccountId: string; + + /** + * The destination validator address name + */ + validatorName: string; + /** + * The destination validator provider name + */ + providerName: string; + + /** + * The blockchain descriptor to use + */ + chainDescriptor: string; + + /** + * Amount of tokens to stake + */ + amount: string; + + /** + * Amount of staking rewards + */ + rewardsAmount: string; + + /** + * When was the request made (ISO Date) + */ + dateCreated: string; + + /** + * The current state. + */ + state: TDelegationState; + + /** + * If a request was started but wasn't verified on the blockchain yet. + */ + ongoingRequest?: boolean; + + /** + * Additional fields per blockchain - can be empty or missing if not initialized or no additional info exists + * The type depends on the chainDescriptor value + */ + blockchainSpecific?: TBlockchainSpecific; + + validatorAddress: string; + + availableActions: string[]; +} \ No newline at end of file From fb308b4ed18850277615e0fb497ffd71dc3f9b03 Mon Sep 17 00:00:00 2001 From: chenshooker Date: Thu, 15 Jun 2023 11:20:15 +0300 Subject: [PATCH 02/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index d298853a..c2da59e3 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -1461,7 +1461,7 @@ export class FireblocksSDK { public async executeStakePositionAction(actionId: string, chainDescriptor: string , body: any) { return await this.apiClient.issuePostRequest(`/v1/chains/{chainDescriptor}/{actionId}`, body); } - public async getStakingPositions(chainDescriptor: string): Promise> { + public async getStakingPositions(chainDescriptor: string): Promise { return await this.apiClient.issueGetRequest(`/v1/positions/${chainDescriptor}`); } /** From 49dc2ee60d7429b097883dca8baedb5e5a719423 Mon Sep 17 00:00:00 2001 From: chenshooker Date: Thu, 15 Jun 2023 11:24:18 +0300 Subject: [PATCH 03/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 5 ++++- src/types.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index c2da59e3..95143a51 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -80,7 +80,7 @@ import { ValidateCreateTravelRuleTransaction, ValidateFullTravelRuleResult, TravelRuleVasp, - TravelRuleVaspFilter, StakingPosition, + TravelRuleVaspFilter, StakingPosition, StakingValidator, } from "./types"; import { AxiosProxyConfig, AxiosResponse } from "axios"; import { PIIEncryption } from "./pii-client"; @@ -1464,6 +1464,9 @@ export class FireblocksSDK { public async getStakingPositions(chainDescriptor: string): Promise { return await this.apiClient.issueGetRequest(`/v1/positions/${chainDescriptor}`); } + public async getStakingValidatorsByChain(chainDescriptor: string): Promise { + return await this.apiClient.issueGetRequest(`/v1/validators/${chainDescriptor}`); + } /** * Validate VASP details for travel rule compliance * @param travelRuleMessageVaspInfo diff --git a/src/types.ts b/src/types.ts index b476b87a..55cad754 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1453,4 +1453,16 @@ export interface StakingPosition { validatorAddress: string; availableActions: string[]; +} +export interface StakingValidator { + chainDescriptor: string; + providerId: number; + validatorId: number; + validatorAddress: string; + feePercent: number; + validatorName: string; + providerName: string; + iconUrl: string; + termsOfServiceUrl: string; + isTermsOfServiceApproved: boolean; } \ No newline at end of file From 540ef812b914fac0c2f2b5779620b767330f00fa Mon Sep 17 00:00:00 2001 From: chenshooker Date: Thu, 15 Jun 2023 14:09:51 +0300 Subject: [PATCH 04/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 95143a51..e8c22371 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -1459,13 +1459,13 @@ export class FireblocksSDK { return await this.apiClient.issueDeleteRequest(`/v1/tokenization/tokens/${assetId}/permissions?permission=${permission.permission}&vaultAccountId=${permission.vaultAccountId}`); } public async executeStakePositionAction(actionId: string, chainDescriptor: string , body: any) { - return await this.apiClient.issuePostRequest(`/v1/chains/{chainDescriptor}/{actionId}`, body); + return await this.apiClient.issuePostRequest(`/v1/staking/chains/{chainDescriptor}/{actionId}`, body); } public async getStakingPositions(chainDescriptor: string): Promise { - return await this.apiClient.issueGetRequest(`/v1/positions/${chainDescriptor}`); + return await this.apiClient.issueGetRequest(`/v1/staking/positions/${chainDescriptor}`); } public async getStakingValidatorsByChain(chainDescriptor: string): Promise { - return await this.apiClient.issueGetRequest(`/v1/validators/${chainDescriptor}`); + return await this.apiClient.issueGetRequest(`/v1/staking/validators/${chainDescriptor}`); } /** * Validate VASP details for travel rule compliance From c282a8ade38bd98aa0520abd0d5f240478c05ae1 Mon Sep 17 00:00:00 2001 From: chenshooker Date: Sun, 18 Jun 2023 12:46:00 +0300 Subject: [PATCH 05/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index e8c22371..2f9b879e 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -1459,7 +1459,7 @@ export class FireblocksSDK { return await this.apiClient.issueDeleteRequest(`/v1/tokenization/tokens/${assetId}/permissions?permission=${permission.permission}&vaultAccountId=${permission.vaultAccountId}`); } public async executeStakePositionAction(actionId: string, chainDescriptor: string , body: any) { - return await this.apiClient.issuePostRequest(`/v1/staking/chains/{chainDescriptor}/{actionId}`, body); + return await this.apiClient.issuePostRequest(`/v1/staking/chains/${chainDescriptor}/${actionId}`, body); } public async getStakingPositions(chainDescriptor: string): Promise { return await this.apiClient.issueGetRequest(`/v1/staking/positions/${chainDescriptor}`); From 2b9080a51072470fb942b04979778cbcbed93e6c Mon Sep 17 00:00:00 2001 From: chenshooker Date: Sun, 15 Oct 2023 12:37:50 +0300 Subject: [PATCH 06/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 40 ++++++++++-- src/types.ts | 145 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 163 insertions(+), 22 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 1edacc1f..92939b30 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -106,7 +106,7 @@ import { PendingTokenLinkDto, TAP, StakingPosition, - StakingValidator, + StakingValidator, StakingAction, StakingChain, CheckTermsOfServiceRequestDto, CheckTermsOfServiceResponseDto, } from "./types"; import { AxiosProxyConfig, AxiosResponse } from "axios"; import { PIIEncryption } from "./pii-client"; @@ -1665,15 +1665,45 @@ export class FireblocksSDK { public async getPendingLinkedTokens(): Promise { return await this.apiClient.issueGetRequest(`/v1/tokenization/tokens/pending`); } - public async executeStakePositionAction(actionId: string, chainDescriptor: string , body: any) { + /** + * Get all staking chains + */ + public async getStakingChains() { + return await this.apiClient.issueGetRequest(`/v1/staking/chains`); + } + /** + * Execute staking action on a chain + */ + public async executeStakePositionAction(actionId: StakingAction, chainDescriptor: StakingChain , body: any) { return await this.apiClient.issuePostRequest(`/v1/staking/chains/${chainDescriptor}/${actionId}`, body); } - public async getStakingPositions(chainDescriptor: string): Promise { - return await this.apiClient.issueGetRequest(`/v1/staking/positions/${chainDescriptor}`); + /** + * Get all staking positions, optionally filtered by chain + */ + public async getStakingPositions(chainDescriptor?: StakingChain): Promise { + const url = `/v1/staking/positions${chainDescriptor ? `?chainDescriptor=${chainDescriptor}` : ""}`; + return await this.apiClient.issueGetRequest(url); + } + /** + * Get a staking position by id + */ + public async getStakingPosition(positionId?: string): Promise { + const url = `/v1/staking/positions/${positionId}`; + return await this.apiClient.issueGetRequest(url); } - public async getStakingValidatorsByChain(chainDescriptor: string): Promise { + /** + * Get all staking validators, filtered by chain + */ + public async getStakingValidatorsByChain(chainDescriptor: StakingChain): Promise { return await this.apiClient.issueGetRequest(`/v1/staking/validators/${chainDescriptor}`); } + /** + * Approve staking provider terms of service + */ + public async approveStakingProviderTermsOfService(checkTermsOfServiceRequestDto: CheckTermsOfServiceRequestDto): Promise { + return await this.apiClient.issuePostRequest(`/v1/staking/providers/approveTermsOfService`, checkTermsOfServiceRequestDto); + } + /** * Validate VASP details for travel rule compliance * @param travelRuleMessageVaspInfo diff --git a/src/types.ts b/src/types.ts index fc8ef17f..219fd097 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2003,11 +2003,12 @@ export namespace TAP { metadata?: Metadata; } } -export enum TDelegationState { + +export enum PositionState { "error" = "error", "activating" = "activating", - "activated" = "activated", + "active" = "active", "deactivating" = "deactivating", "deactivated" = "deactivated", @@ -2027,76 +2028,186 @@ interface IEthereumBlockchainData {} export type TBlockchainSpecific = ISolanaBlockchainData | IEthereumBlockchainData; -export interface StakingPosition { +class RelatedTransactionDto { + /** + * The transaction ID + */ + txId: string; + + /** + * Is the transaction successful or not + */ + isSuccessful: boolean; +} +export class StakingPosition { /** - * Delegation request id + * The unique identifier of the staking position */ - delegationRequestId: string; + id: string; /** - * The source vault account to stake from + * The source vault account to stake from. */ vaultAccountId: string; /** - * The destination validator address name + * The destination validator address name. */ validatorName: string; /** - * The destination validator provider name + * The destination validator provider name. */ providerName: string; /** - * The blockchain descriptor to use + * The blockchain descriptor to use. */ chainDescriptor: string; /** - * Amount of tokens to stake + * Amount of tokens to stake. */ amount: string; /** - * Amount of staking rewards + * The amount staked in the position, measured in the blockchain descriptor unit. */ rewardsAmount: string; /** - * When was the request made (ISO Date) + * When was the request made (ISO Date). */ dateCreated: string; /** * The current state. */ - state: TDelegationState; + state: PositionState; + + /** + * An array of transaction objects related to this position. + * Each object includes a 'txId' representing the transaction ID + * and a 'isSuccessful' boolean indicating if the transaction was successful. + */ + relatedTransactions: RelatedTransactionDto[]; /** - * If a request was started but wasn't verified on the blockchain yet. + * Indicates whether there is an ongoing action for this position (true if ongoing, false if not). */ ongoingRequest?: boolean; /** - * Additional fields per blockchain - can be empty or missing if not initialized or no additional info exists - * The type depends on the chainDescriptor value + * The transaction ID of the ongoing request + */ + onGoingRequestTxId?: string; + + /** + * Additional fields per blockchain - can be empty or missing if not initialized or no additional info exists. + * The type depends on the chainDescriptor value. + * For Solana (SOL), stake account address. + * For Ethereum (ETH), an empty object is returned as no specific data is available. */ blockchainSpecific?: TBlockchainSpecific; + /** + * The destination address of the staking transaction. + */ validatorAddress: string; + /** + * An array of available actions that can be performed. for example, actions like "unstake" or "withdraw". + */ availableActions: string[]; } + export interface StakingValidator { + /** + * Blockchain descriptor for the validator + */ chainDescriptor: string; + + /** + * The ID of the provider + */ providerId: number; + + /** + * The ID of the validator + */ validatorId: number; + + /** + * The destination address of the staking transaction + */ validatorAddress: string; + + /** + * Percentage fee charged by the validator + */ feePercent: number; + + /** + * Name of the validator + */ validatorName: string; + + /** + * Name of the provider + */ providerName: string; + + /** + * URL to the validator's icon + */ iconUrl: string; + + /** + * URL to the terms of service + */ termsOfServiceUrl: string; + + /** + * Indicates whether the terms of service are approved" + */ isTermsOfServiceApproved: boolean; -} \ No newline at end of file +} + +/** + * Staking actions + */ +export enum StakingAction { + stake = "stake", + unstake = "unstake", + withdraw = "withdraw", +} + +/** + * Staking chain descriptors + */ +export enum StakingChain { + SOLANA = "SOL", + SOLANA_TESTNET = "SOL_TEST", + ETHEREUM = "ETH", + GOERLI = "ETH_TEST3", +} + +/** + * Check terms of service request body + */ +export class CheckTermsOfServiceRequestDto { + /** + * Validator provider ID + */ + validatorProviderId: number; +} + +/** + * Check terms of service response + */ +export class CheckTermsOfServiceResponseDto { + /** + * True if the terms and services were previously approved + */ + isPreviouslyApproved: boolean; +} From ff7c798db060dc6422235189b28f827625ea9b44 Mon Sep 17 00:00:00 2001 From: chenshooker Date: Sun, 22 Oct 2023 11:11:14 +0300 Subject: [PATCH 07/12] add staking sdk endpoints --- src/fireblocks-sdk.ts | 24 +++++++++++++++++++++--- src/types.ts | 10 ---------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 92939b30..3ccbe2be 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -106,7 +106,10 @@ import { PendingTokenLinkDto, TAP, StakingPosition, - StakingValidator, StakingAction, StakingChain, CheckTermsOfServiceRequestDto, CheckTermsOfServiceResponseDto, + StakingValidator, + StakingAction, + StakingChain, + CheckTermsOfServiceResponseDto, } from "./types"; import { AxiosProxyConfig, AxiosResponse } from "axios"; import { PIIEncryption } from "./pii-client"; @@ -1671,6 +1674,21 @@ export class FireblocksSDK { public async getStakingChains() { return await this.apiClient.issueGetRequest(`/v1/staking/chains`); } + + /** + * Get chain info + */ + public async getChainInfo(chainDescriptor: StakingChain) { + return await this.apiClient.issueGetRequest(`/v1/staking/${chainDescriptor}/chainInfo`); + } + + /** + * Get staking positions summary + */ + public async getPositionsSummary() { + return await this.apiClient.issueGetRequest(`/v1/staking/positions/summary`); + } + /** * Execute staking action on a chain */ @@ -1700,8 +1718,8 @@ export class FireblocksSDK { /** * Approve staking provider terms of service */ - public async approveStakingProviderTermsOfService(checkTermsOfServiceRequestDto: CheckTermsOfServiceRequestDto): Promise { - return await this.apiClient.issuePostRequest(`/v1/staking/providers/approveTermsOfService`, checkTermsOfServiceRequestDto); + public async approveStakingProviderTermsOfService(validatorProviderId: string): Promise { + return await this.apiClient.issuePostRequest(`/v1/staking/providers/approveTermsOfService`, {validatorProviderId}); } /** diff --git a/src/types.ts b/src/types.ts index 219fd097..84451496 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2192,16 +2192,6 @@ export enum StakingChain { GOERLI = "ETH_TEST3", } -/** - * Check terms of service request body - */ -export class CheckTermsOfServiceRequestDto { - /** - * Validator provider ID - */ - validatorProviderId: number; -} - /** * Check terms of service response */ From 165e16d8e671b5f8191076c8adb94f164119a576 Mon Sep 17 00:00:00 2001 From: chenshooker Date: Wed, 25 Oct 2023 14:30:17 +0300 Subject: [PATCH 08/12] fix getChainInfo --- src/fireblocks-sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 41551518..5d9d077c 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -1698,7 +1698,7 @@ export class FireblocksSDK { * Get chain info */ public async getChainInfo(chainDescriptor: StakingChain) { - return await this.apiClient.issueGetRequest(`/v1/staking/${chainDescriptor}/chainInfo`); + return await this.apiClient.issueGetRequest(`/v1/staking/chains/${chainDescriptor}/chainInfo`); } /** From 3a529f823cb8c2a708cbb811fb60841db6c9c91a Mon Sep 17 00:00:00 2001 From: chenshooker Date: Wed, 25 Oct 2023 19:41:26 +0300 Subject: [PATCH 09/12] separate sdk --- src/fireblocks-sdk.ts | 73 ++------- src/staking/index.ts | 3 + src/staking/staking-api-client.ts | 87 +++++++++++ src/staking/staking-sdk.ts | 49 ++++++ src/staking/types.ts | 243 ++++++++++++++++++++++++++++++ src/types.ts | 198 ------------------------ 6 files changed, 397 insertions(+), 256 deletions(-) create mode 100644 src/staking/index.ts create mode 100644 src/staking/staking-api-client.ts create mode 100644 src/staking/staking-sdk.ts create mode 100644 src/staking/types.ts diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 5d9d077c..067e2495 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -108,16 +108,13 @@ import { TAP, ExchangeAccountsPageFilter, PagedExchangeResponse, - StakingPosition, - StakingValidator, - StakingAction, - StakingChain, - CheckTermsOfServiceResponseDto, } from "./types"; import { AxiosProxyConfig, AxiosResponse } from "axios"; import { PIIEncryption } from "./pii-client"; import { NcwApiClient } from "./ncw-api-client"; import { NcwSdk } from "./ncw-sdk"; +import { StakingApiClient } from "./staking/staking-api-client"; +import { StakingSDK } from "./staking/staking-sdk"; export * from "./types"; @@ -157,6 +154,7 @@ export class FireblocksSDK { private readonly apiBaseUrl: string; private readonly apiClient: ApiClient; private readonly apiNcw: NcwApiClient; + private readonly stakingApiClient: StakingApiClient; private piiClient: PIIEncryption; @@ -182,6 +180,8 @@ export class FireblocksSDK { } this.apiNcw = new NcwApiClient(this.apiClient); + + this.stakingApiClient = new StakingApiClient(this.apiClient); } /** @@ -194,6 +194,16 @@ export class FireblocksSDK { return this.apiNcw; } + /** + * Staking API Namespace + * + * @readonly + * @type {StakingSDK} + */ + public get staking(): StakingSDK { + return this.stakingApiClient; + } + /** * Get the instance of ApiClient used by the FireblocksSDK */ @@ -1687,59 +1697,6 @@ export class FireblocksSDK { public async getPendingLinkedTokens(): Promise { return await this.apiClient.issueGetRequest(`/v1/tokenization/tokens/pending`); } - /** - * Get all staking chains - */ - public async getStakingChains() { - return await this.apiClient.issueGetRequest(`/v1/staking/chains`); - } - - /** - * Get chain info - */ - public async getChainInfo(chainDescriptor: StakingChain) { - return await this.apiClient.issueGetRequest(`/v1/staking/chains/${chainDescriptor}/chainInfo`); - } - - /** - * Get staking positions summary - */ - public async getPositionsSummary() { - return await this.apiClient.issueGetRequest(`/v1/staking/positions/summary`); - } - - /** - * Execute staking action on a chain - */ - public async executeStakePositionAction(actionId: StakingAction, chainDescriptor: StakingChain , body: any) { - return await this.apiClient.issuePostRequest(`/v1/staking/chains/${chainDescriptor}/${actionId}`, body); - } - /** - * Get all staking positions, optionally filtered by chain - */ - public async getStakingPositions(chainDescriptor?: StakingChain): Promise { - const url = `/v1/staking/positions${chainDescriptor ? `?chainDescriptor=${chainDescriptor}` : ""}`; - return await this.apiClient.issueGetRequest(url); - } - /** - * Get a staking position by id - */ - public async getStakingPosition(positionId?: string): Promise { - const url = `/v1/staking/positions/${positionId}`; - return await this.apiClient.issueGetRequest(url); - } - /** - * Get all staking validators, filtered by chain - */ - public async getStakingValidatorsByChain(chainDescriptor: StakingChain): Promise { - return await this.apiClient.issueGetRequest(`/v1/staking/validators/${chainDescriptor}`); - } - /** - * Approve staking provider terms of service - */ - public async approveStakingProviderTermsOfService(validatorProviderId: string): Promise { - return await this.apiClient.issuePostRequest(`/v1/staking/providers/approveTermsOfService`, {validatorProviderId}); - } /** * Validate VASP details for travel rule compliance diff --git a/src/staking/index.ts b/src/staking/index.ts new file mode 100644 index 00000000..9743a35a --- /dev/null +++ b/src/staking/index.ts @@ -0,0 +1,3 @@ +export * from "./staking-api-client"; +export * from "./staking-sdk"; +export * from "./types"; \ No newline at end of file diff --git a/src/staking/staking-api-client.ts b/src/staking/staking-api-client.ts new file mode 100644 index 00000000..1729f4ce --- /dev/null +++ b/src/staking/staking-api-client.ts @@ -0,0 +1,87 @@ +import { + ChainInfo, + CheckTermsOfServiceResponseDto, + DelegationSummaryDto, + DelegationSummaryDtoByVault, + ExecuteActionResponse, + StakingAction, + StakingChain, + StakingPosition, + StakingValidator, +} from "./types"; +import { StakingSDK } from "./staking-sdk"; +import { ApiClient } from "../api-client"; + +const STAKING_BASE_PATH = "/v1/staking"; + +export class StakingApiClient implements StakingSDK { + constructor(private readonly apiClient: ApiClient) {} + + /** + * Get all staking chains + */ + public async getChains(): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/chains`); + } + + /** + * Get chain info + */ + public async getChainInfo(chainDescriptor: StakingChain): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/chains/${chainDescriptor}/chainInfo`); + } + + /** + * Get staking positions summary + */ + public async getPositionsSummary(): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/positions/summary`); + } + + /** + * Execute staking action on a chain + */ + public async executeAction( + actionId: StakingAction, + chainDescriptor: StakingChain, + body: any, + ): Promise { + return await this.apiClient.issuePostRequest( + `${STAKING_BASE_PATH}/chains/${chainDescriptor}/${actionId}`, + body, + ); + } + + /** + * Get all staking positions, optionally filtered by chain + */ + public async getPositions(chainDescriptor?: StakingChain): Promise { + const url = `${STAKING_BASE_PATH}/positions${chainDescriptor ? `?chainDescriptor=${chainDescriptor}` : ""}`; + return await this.apiClient.issueGetRequest(url); + } + + /** + * Get a staking position by id + */ + public async getPosition(positionId?: string): Promise { + const url = `${STAKING_BASE_PATH}/positions/${positionId}`; + return await this.apiClient.issueGetRequest(url); + } + + /** + * Get all staking validators, filtered by chain + */ + public async getValidatorsByChain(chainDescriptor: StakingChain): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/validators/${chainDescriptor}`); + } + + /** + * Approve staking provider terms of service + */ + public async approveProviderTermsOfService(validatorProviderId: string): Promise { + return await this.apiClient.issuePostRequest(`${STAKING_BASE_PATH}/providers/approveTermsOfService`, { + validatorProviderId, + }); + } +} + diff --git a/src/staking/staking-sdk.ts b/src/staking/staking-sdk.ts new file mode 100644 index 00000000..ac8bc377 --- /dev/null +++ b/src/staking/staking-sdk.ts @@ -0,0 +1,49 @@ +import { + ChainInfo, CheckTermsOfServiceResponseDto, + DelegationSummaryDto, + DelegationSummaryDtoByVault, + ExecuteActionResponse, + StakingAction, + StakingChain, StakingPosition, StakingValidator +} from "./types"; + +export interface StakingSDK { + /** + * Get all staking chains + */ + getChains(): Promise; + + /** + * Get chain info + */ + getChainInfo(chainDescriptor: StakingChain): Promise; + + /** + * Get staking positions summary + */ + getPositionsSummary(): Promise; + + /** + * Execute staking action on a chain + */ + executeAction(actionId: StakingAction, chainDescriptor: StakingChain, body: any): Promise; + + /** + * Get all staking positions, optionally filtered by chain + */ + getPositions(chainDescriptor?: StakingChain): Promise; + /** + * Get a staking position by id + */ + getPosition(positionId?: string): Promise; + + /** + * Get all staking validators, filtered by chain + */ + getValidatorsByChain(chainDescriptor: StakingChain): Promise; + + /** + * Approve staking provider terms of service + */ + approveProviderTermsOfService(validatorProviderId: string): Promise; +} diff --git a/src/staking/types.ts b/src/staking/types.ts new file mode 100644 index 00000000..1ed5200f --- /dev/null +++ b/src/staking/types.ts @@ -0,0 +1,243 @@ +export enum PositionState { + "error" = "error", + + "activating" = "activating", + "active" = "active", + + "deactivating" = "deactivating", + "deactivated" = "deactivated", + + "withdrawing" = "withdrawing", + "withdrawn" = "withdrawn", +} + +interface ISolanaBlockchainData { + /** + * The stake account address matching the stakeAccountId + */ + stakeAccountAddress: string; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface IEthereumBlockchainData {} + +export type TBlockchainSpecific = ISolanaBlockchainData | IEthereumBlockchainData; + +interface RelatedTransactionDto { + /** + * The transaction ID + */ + txId: string; + + /** + * Is the transaction successful or not + */ + isSuccessful: boolean; +} + +export interface StakingPosition { + /** + * The unique identifier of the staking position + */ + id: string; + + /** + * The source vault account to stake from. + */ + vaultAccountId: string; + + /** + * The destination validator address name. + */ + validatorName: string; + /** + * The destination validator provider name. + */ + providerName: string; + + /** + * The blockchain descriptor to use. + */ + chainDescriptor: string; + + /** + * Amount of tokens to stake. + */ + amount: string; + + /** + * The amount staked in the position, measured in the blockchain descriptor unit. + */ + rewardsAmount: string; + + /** + * When was the request made (ISO Date). + */ + dateCreated: string; + + /** + * The current state. + */ + state: PositionState; + + /** + * An array of transaction objects related to this position. + * Each object includes a 'txId' representing the transaction ID + * and a 'isSuccessful' boolean indicating if the transaction was successful. + */ + relatedTransactions: RelatedTransactionDto[]; + + /** + * Indicates whether there is an ongoing action for this position (true if ongoing, false if not). + */ + ongoingRequest?: boolean; + + /** + * The transaction ID of the ongoing request + */ + onGoingRequestTxId?: string; + + /** + * Additional fields per blockchain - can be empty or missing if not initialized or no additional info exists. + * The type depends on the chainDescriptor value. + * For Solana (SOL), stake account address. + * For Ethereum (ETH), an empty object is returned as no specific data is available. + */ + blockchainSpecific?: TBlockchainSpecific; + + /** + * The destination address of the staking transaction. + */ + validatorAddress: string; + + /** + * An array of available actions that can be performed. for example, actions like "unstake" or "withdraw". + */ + availableActions: string[]; +} + +export interface StakingValidator { + /** + * Blockchain descriptor for the validator + */ + chainDescriptor: string; + + /** + * The ID of the provider + */ + providerId: number; + + /** + * The ID of the validator + */ + validatorId: number; + + /** + * The destination address of the staking transaction + */ + validatorAddress: string; + + /** + * Percentage fee charged by the validator + */ + feePercent: number; + + /** + * Name of the validator + */ + validatorName: string; + + /** + * Name of the provider + */ + providerName: string; + + /** + * URL to the validator's icon + */ + iconUrl: string; + + /** + * URL to the terms of service + */ + termsOfServiceUrl: string; + + /** + * Indicates whether the terms of service are approved" + */ + isTermsOfServiceApproved: boolean; +} + +/** + * Staking actions + */ +export enum StakingAction { + stake = "stake", + unstake = "unstake", + withdraw = "withdraw", +} + +/** + * Staking chain descriptors + */ +export enum StakingChain { + SOLANA = "SOL", + SOLANA_TESTNET = "SOL_TEST", + ETHEREUM = "ETH", + GOERLI = "ETH_TEST3", +} + +/** + * Check terms of service response + */ +export interface CheckTermsOfServiceResponseDto { + /** + * True if the terms and services were previously approved + */ + isPreviouslyApproved: boolean; +} + +export interface ChainInfo { + chainId: string; + currentEpoch: number; + nextEpoch: number; + epochElapsed: number; + epochDuration: number; + additionalInfo: { [key: string]: any }; +} + +export interface AmountAndChainDescriptor { + chainDescriptor: string; + amount: string; +} + +export interface DelegationSummaryDto { + /** + * An array of objects containing chain descriptors and associated amounts, representing active positions. + */ + active: AmountAndChainDescriptor[]; + + /** + * An array of objects containing chain descriptors and associated amounts, representing inActive positions. + */ + inActive: AmountAndChainDescriptor[]; + + /** + * An array of objects containing chain descriptors and associated amounts, representing rewards positions. + */ + rewardsAmount: AmountAndChainDescriptor[]; + + /** + * An array of objects with chain descriptors and total staked amounts, + * representing the combined staked totals of active and inactive positions. + */ + totalStaked: AmountAndChainDescriptor[]; +} + +export class DelegationSummaryDtoByVault { + [vaultAccountId: string]: DelegationSummaryDto; +} + +export type ExecuteActionResponse = {} | { + delegationRequestId: string; +}; diff --git a/src/types.ts b/src/types.ts index adc48b95..c7463156 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2030,201 +2030,3 @@ export namespace TAP { metadata?: Metadata; } } - -export enum PositionState { - "error" = "error", - - "activating" = "activating", - "active" = "active", - - "deactivating" = "deactivating", - "deactivated" = "deactivated", - - "withdrawing" = "withdrawing", - "withdrawn" = "withdrawn", -} - -interface ISolanaBlockchainData { - /** - * The stake account address matching the stakeAccountId - */ - stakeAccountAddress: string; -} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -interface IEthereumBlockchainData {} - -export type TBlockchainSpecific = ISolanaBlockchainData | IEthereumBlockchainData; - -class RelatedTransactionDto { - /** - * The transaction ID - */ - txId: string; - - /** - * Is the transaction successful or not - */ - isSuccessful: boolean; -} - -export class StakingPosition { - /** - * The unique identifier of the staking position - */ - id: string; - - /** - * The source vault account to stake from. - */ - vaultAccountId: string; - - /** - * The destination validator address name. - */ - validatorName: string; - /** - * The destination validator provider name. - */ - providerName: string; - - /** - * The blockchain descriptor to use. - */ - chainDescriptor: string; - - /** - * Amount of tokens to stake. - */ - amount: string; - - /** - * The amount staked in the position, measured in the blockchain descriptor unit. - */ - rewardsAmount: string; - - /** - * When was the request made (ISO Date). - */ - dateCreated: string; - - /** - * The current state. - */ - state: PositionState; - - /** - * An array of transaction objects related to this position. - * Each object includes a 'txId' representing the transaction ID - * and a 'isSuccessful' boolean indicating if the transaction was successful. - */ - relatedTransactions: RelatedTransactionDto[]; - - /** - * Indicates whether there is an ongoing action for this position (true if ongoing, false if not). - */ - ongoingRequest?: boolean; - - /** - * The transaction ID of the ongoing request - */ - onGoingRequestTxId?: string; - - /** - * Additional fields per blockchain - can be empty or missing if not initialized or no additional info exists. - * The type depends on the chainDescriptor value. - * For Solana (SOL), stake account address. - * For Ethereum (ETH), an empty object is returned as no specific data is available. - */ - blockchainSpecific?: TBlockchainSpecific; - - /** - * The destination address of the staking transaction. - */ - validatorAddress: string; - - /** - * An array of available actions that can be performed. for example, actions like "unstake" or "withdraw". - */ - availableActions: string[]; -} - -export interface StakingValidator { - /** - * Blockchain descriptor for the validator - */ - chainDescriptor: string; - - /** - * The ID of the provider - */ - providerId: number; - - /** - * The ID of the validator - */ - validatorId: number; - - /** - * The destination address of the staking transaction - */ - validatorAddress: string; - - /** - * Percentage fee charged by the validator - */ - feePercent: number; - - /** - * Name of the validator - */ - validatorName: string; - - /** - * Name of the provider - */ - providerName: string; - - /** - * URL to the validator's icon - */ - iconUrl: string; - - /** - * URL to the terms of service - */ - termsOfServiceUrl: string; - - /** - * Indicates whether the terms of service are approved" - */ - isTermsOfServiceApproved: boolean; -} - -/** - * Staking actions - */ -export enum StakingAction { - stake = "stake", - unstake = "unstake", - withdraw = "withdraw", -} - -/** - * Staking chain descriptors - */ -export enum StakingChain { - SOLANA = "SOL", - SOLANA_TESTNET = "SOL_TEST", - ETHEREUM = "ETH", - GOERLI = "ETH_TEST3", -} - -/** - * Check terms of service response - */ -export class CheckTermsOfServiceResponseDto { - /** - * True if the terms and services were previously approved - */ - isPreviouslyApproved: boolean; -} From a9acf6482b4fe0f5c3e39f0d0bf6a1e75a5bc6d7 Mon Sep 17 00:00:00 2001 From: Yahav Amar Date: Tue, 31 Oct 2023 16:41:50 +0200 Subject: [PATCH 10/12] staking-sdk: integrate staking APIs for use with FireblocksSDK as required --- src/fireblocks-sdk.ts | 68 +++++++++++++++++++++++++------ src/staking/staking-api-client.ts | 41 ++----------------- src/staking/types.ts | 4 +- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 067e2495..45df239d 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -114,7 +114,13 @@ import { PIIEncryption } from "./pii-client"; import { NcwApiClient } from "./ncw-api-client"; import { NcwSdk } from "./ncw-sdk"; import { StakingApiClient } from "./staking/staking-api-client"; -import { StakingSDK } from "./staking/staking-sdk"; +import { + ChainInfo, CheckTermsOfServiceResponseDto, + DelegationSummaryDto, + DelegationSummaryDtoByVault, + ExecuteActionResponse, StakingAction, + StakingChain, StakingPosition, StakingValidator +} from "./staking"; export * from "./types"; @@ -193,24 +199,60 @@ export class FireblocksSDK { public get NCW(): NcwSdk { return this.apiNcw; } - - /** - * Staking API Namespace - * - * @readonly - * @type {StakingSDK} - */ - public get staking(): StakingSDK { - return this.stakingApiClient; - } - /** * Get the instance of ApiClient used by the FireblocksSDK */ public getApiClient(): ApiClient { return this.apiClient; } - + /** + * Get all staking chains + */ + public async getStakingChains(): Promise { + return await this.stakingApiClient.getChains(); + } + /** + * Get chain info + */ + public async getStakingChainInfo(chainDescriptor: StakingChain): Promise { + return await this.stakingApiClient.getChainInfo(chainDescriptor); + } + /** + * Get staking positions summary + */ + public async getStakingPositionsSummary(byVault?: boolean): Promise { + return await this.stakingApiClient.getPositionsSummary(byVault); + } + /** + * Execute staking action on a chain + */ + public async executeStakingAction(actionId: StakingAction, chainDescriptor: StakingChain, body: any): Promise { + return await this.stakingApiClient.executeAction(actionId, chainDescriptor, body); + } + /** + * Get all staking positions, optionally filtered by chain + */ + public async getStakingPositions(chainDescriptor?: StakingChain): Promise { + return await this.stakingApiClient.getPositions(chainDescriptor); + } + /** + * Get a staking position by id + */ + public async getStakingPosition(positionId?: string): Promise { + return await this.stakingApiClient.getPosition(positionId); + } + /** + * Get all staking validators, filtered by chain + */ + public async getStakingValidatorsByChain(chainDescriptor: StakingChain): Promise { + return await this.stakingApiClient.getValidatorsByChain(chainDescriptor); + } + /** + * Approve staking provider terms of service + */ + public async approveStakingProviderTermsOfService(validatorProviderId: string): Promise { + return await this.stakingApiClient.approveProviderTermsOfService(validatorProviderId); + } /** * Gets all assets that are currently supported by Fireblocks */ diff --git a/src/staking/staking-api-client.ts b/src/staking/staking-api-client.ts index 1729f4ce..f5df74d6 100644 --- a/src/staking/staking-api-client.ts +++ b/src/staking/staking-api-client.ts @@ -16,31 +16,15 @@ const STAKING_BASE_PATH = "/v1/staking"; export class StakingApiClient implements StakingSDK { constructor(private readonly apiClient: ApiClient) {} - - /** - * Get all staking chains - */ public async getChains(): Promise { return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/chains`); } - - /** - * Get chain info - */ public async getChainInfo(chainDescriptor: StakingChain): Promise { return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/chains/${chainDescriptor}/chainInfo`); } - - /** - * Get staking positions summary - */ - public async getPositionsSummary(): Promise { - return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/positions/summary`); + public async getPositionsSummary(byVault?: boolean): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/positions/summary${byVault ? "?byVault=true" : "?byVault=false"}`); } - - /** - * Execute staking action on a chain - */ public async executeAction( actionId: StakingAction, chainDescriptor: StakingChain, @@ -51,33 +35,16 @@ export class StakingApiClient implements StakingSDK { body, ); } - - /** - * Get all staking positions, optionally filtered by chain - */ public async getPositions(chainDescriptor?: StakingChain): Promise { const url = `${STAKING_BASE_PATH}/positions${chainDescriptor ? `?chainDescriptor=${chainDescriptor}` : ""}`; return await this.apiClient.issueGetRequest(url); } - - /** - * Get a staking position by id - */ - public async getPosition(positionId?: string): Promise { - const url = `${STAKING_BASE_PATH}/positions/${positionId}`; - return await this.apiClient.issueGetRequest(url); + public async getPosition(positionId: string): Promise { + return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/positions/${positionId}`); } - - /** - * Get all staking validators, filtered by chain - */ public async getValidatorsByChain(chainDescriptor: StakingChain): Promise { return await this.apiClient.issueGetRequest(`${STAKING_BASE_PATH}/validators/${chainDescriptor}`); } - - /** - * Approve staking provider terms of service - */ public async approveProviderTermsOfService(validatorProviderId: string): Promise { return await this.apiClient.issuePostRequest(`${STAKING_BASE_PATH}/providers/approveTermsOfService`, { validatorProviderId, diff --git a/src/staking/types.ts b/src/staking/types.ts index 1ed5200f..adc01f99 100644 --- a/src/staking/types.ts +++ b/src/staking/types.ts @@ -21,7 +21,7 @@ interface ISolanaBlockchainData { // eslint-disable-next-line @typescript-eslint/no-empty-interface interface IEthereumBlockchainData {} -export type TBlockchainSpecific = ISolanaBlockchainData | IEthereumBlockchainData; +export type TBlockchainPositionInfo = ISolanaBlockchainData | IEthereumBlockchainData; interface RelatedTransactionDto { /** @@ -103,7 +103,7 @@ export interface StakingPosition { * For Solana (SOL), stake account address. * For Ethereum (ETH), an empty object is returned as no specific data is available. */ - blockchainSpecific?: TBlockchainSpecific; + blockchainPositionInfo?: TBlockchainPositionInfo; /** * The destination address of the staking transaction. From 6a1fac1032e917d96a012825fce165313e8fe55f Mon Sep 17 00:00:00 2001 From: Yahav Amar Date: Wed, 1 Nov 2023 11:35:32 +0200 Subject: [PATCH 11/12] staking-sdk: mr comments implemented, add execute action request dto for staking/unstake/withdraw --- src/fireblocks-sdk.ts | 2 +- src/staking/staking-api-client.ts | 6 +-- src/staking/types.ts | 76 +++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 45df239d..fb092fd3 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -238,7 +238,7 @@ export class FireblocksSDK { /** * Get a staking position by id */ - public async getStakingPosition(positionId?: string): Promise { + public async getStakingPosition(positionId: string): Promise { return await this.stakingApiClient.getPosition(positionId); } /** diff --git a/src/staking/staking-api-client.ts b/src/staking/staking-api-client.ts index f5df74d6..8d2c3add 100644 --- a/src/staking/staking-api-client.ts +++ b/src/staking/staking-api-client.ts @@ -3,11 +3,11 @@ import { CheckTermsOfServiceResponseDto, DelegationSummaryDto, DelegationSummaryDtoByVault, - ExecuteActionResponse, + ExecuteActionResponse, StakeRequestDto, StakingAction, StakingChain, StakingPosition, - StakingValidator, + StakingValidator, UnstakeRequestDto, WithdrawRequestDto, } from "./types"; import { StakingSDK } from "./staking-sdk"; import { ApiClient } from "../api-client"; @@ -28,7 +28,7 @@ export class StakingApiClient implements StakingSDK { public async executeAction( actionId: StakingAction, chainDescriptor: StakingChain, - body: any, + body: StakeRequestDto | UnstakeRequestDto | WithdrawRequestDto, ): Promise { return await this.apiClient.issuePostRequest( `${STAKING_BASE_PATH}/chains/${chainDescriptor}/${actionId}`, diff --git a/src/staking/types.ts b/src/staking/types.ts index adc01f99..76b076f5 100644 --- a/src/staking/types.ts +++ b/src/staking/types.ts @@ -241,3 +241,79 @@ export class DelegationSummaryDtoByVault { export type ExecuteActionResponse = {} | { delegationRequestId: string; }; + +export interface StakeRequestDto { + /** + * The source vault account to stake from + */ + vaultAccountId: string; + + /** + * The destination validator address id. The blockchain is used implicitly (it's associated with the address) + */ + validatorAddressId: string; + + /** + * Amount of tokens to stake + */ + stakeAmount: string; + + /** + * The note to associate with the stake transactions + */ + txNote?: string; + + /** + * Represents the fee for a transaction, which can be specified as a percentage value. Only one of fee/feeLevel is required + */ + fee?: string; + + /** + * Represents the fee level for a transaction, which can be set as slow, medium, or fast. Only one of fee/feeLevel is required + */ + feeLevel?: string; +} + +export interface UnstakeRequestDto { + /** + * id of position to unstake + */ + id: string; + + /** + * Represents the fee for a transaction, which can be specified as a percentage value. Only one of fee/feeLevel is required + */ + fee?: string; + + /** + * Represents the fee level for a transaction, which can be set as slow, medium, or fast. Only one of fee/feeLevel is required + */ + feeLevel?: string; + + /** + * The note to associate with the transactions + */ + txNote?: string; +} + +export interface WithdrawRequestDto { + /** + * id of position to withdraw + */ + id: string; + + /** + * Represents the fee for a transaction, which can be specified as a percentage value. Only one of fee/feeLevel is required + */ + fee?: string; + + /** + * Represents the fee level for a transaction, which can be set as slow, medium, or fast. Only one of fee/feeLevel is required + */ + feeLevel?: string; + + /** + * The note to associate with the transactions + */ + txNote?: string; +} \ No newline at end of file From 59dfa20e45a0d666856e62d628d674315ef7fcd1 Mon Sep 17 00:00:00 2001 From: Yahav Amar Date: Wed, 1 Nov 2023 11:44:09 +0200 Subject: [PATCH 12/12] staking-sdk: executeStakingAction type fix --- src/fireblocks-sdk.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index fb092fd3..710cd0db 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -118,8 +118,8 @@ import { ChainInfo, CheckTermsOfServiceResponseDto, DelegationSummaryDto, DelegationSummaryDtoByVault, - ExecuteActionResponse, StakingAction, - StakingChain, StakingPosition, StakingValidator + ExecuteActionResponse, StakeRequestDto, StakingAction, + StakingChain, StakingPosition, StakingValidator, UnstakeRequestDto, WithdrawRequestDto } from "./staking"; export * from "./types"; @@ -226,7 +226,7 @@ export class FireblocksSDK { /** * Execute staking action on a chain */ - public async executeStakingAction(actionId: StakingAction, chainDescriptor: StakingChain, body: any): Promise { + public async executeStakingAction(actionId: StakingAction, chainDescriptor: StakingChain, body: StakeRequestDto | UnstakeRequestDto | WithdrawRequestDto): Promise { return await this.stakingApiClient.executeAction(actionId, chainDescriptor, body); } /**