diff --git a/CHANGELOG.md b/CHANGELOG.md index b5fac95e..9bfb6fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Coinbase Node.js SDK Changelog +## [0.0.15] + +### Added + +- USD value conversion details to the StakingReward object + ## [0.0.14] - 2024-08-05 ### Added diff --git a/src/client/api.ts b/src/client/api.ts index 2bfdc0ff..a59e6c7c 100644 --- a/src/client/api.ts +++ b/src/client/api.ts @@ -85,6 +85,31 @@ export interface AddressBalanceList { */ 'total_count': number; } +/** + * + * @export + * @interface AddressHistoricalBalanceList + */ +export interface AddressHistoricalBalanceList { + /** + * + * @type {Array} + * @memberof AddressHistoricalBalanceList + */ + 'data': Array; + /** + * True if this list has another page of items after this one that can be fetched. + * @type {boolean} + * @memberof AddressHistoricalBalanceList + */ + 'has_more': boolean; + /** + * The page token to be used to fetch the next page. + * @type {string} + * @memberof AddressHistoricalBalanceList + */ + 'next_page': string; +} /** * * @export @@ -757,6 +782,37 @@ export interface GetStakingContextRequest { */ 'options': { [key: string]: string; }; } +/** + * The balance of an asset onchain at a particular block + * @export + * @interface HistoricalBalance + */ +export interface HistoricalBalance { + /** + * The amount in the atomic units of the asset + * @type {string} + * @memberof HistoricalBalance + */ + 'amount': string; + /** + * The hash of the block at which the balance was recorded + * @type {string} + * @memberof HistoricalBalance + */ + 'block_hash': string; + /** + * The block height at which the balance was recorded + * @type {string} + * @memberof HistoricalBalance + */ + 'block_height': string; + /** + * + * @type {Asset} + * @memberof HistoricalBalance + */ + 'asset': Asset; +} /** * An error response from the Coinbase Developer Platform API * @export @@ -1236,6 +1292,12 @@ export interface StakingReward { * @memberof StakingReward */ 'format': StakingRewardFormat; + /** + * + * @type {StakingRewardUSDValue} + * @memberof StakingReward + */ + 'usd_value': StakingRewardUSDValue; } export const StakingRewardStateEnum = { @@ -1259,6 +1321,31 @@ export const StakingRewardFormat = { export type StakingRewardFormat = typeof StakingRewardFormat[keyof typeof StakingRewardFormat]; +/** + * The USD value of the reward + * @export + * @interface StakingRewardUSDValue + */ +export interface StakingRewardUSDValue { + /** + * The value of the reward in USD + * @type {string} + * @memberof StakingRewardUSDValue + */ + 'amount': string; + /** + * The conversion price from native currency to USD + * @type {string} + * @memberof StakingRewardUSDValue + */ + 'conversion_price': string; + /** + * The time of the conversion in UTC. + * @type {string} + * @memberof StakingRewardUSDValue + */ + 'conversion_time': string; +} /** * A trade of an asset to another asset * @export @@ -1490,7 +1577,41 @@ export interface Transfer { * @memberof Transfer */ 'transaction': Transaction; + /** + * The unsigned payload of the transfer. This is the payload that needs to be signed by the sender. + * @type {string} + * @memberof Transfer + */ + 'unsigned_payload'?: string; + /** + * The signed payload of the transfer. This is the payload that has been signed by the sender. + * @type {string} + * @memberof Transfer + */ + 'signed_payload'?: string; + /** + * The hash of the transfer transaction + * @type {string} + * @memberof Transfer + */ + 'transaction_hash'?: string; + /** + * The status of the transfer + * @type {string} + * @memberof Transfer + */ + 'status'?: TransferStatusEnum; } + +export const TransferStatusEnum = { + Pending: 'pending', + Broadcast: 'broadcast', + Complete: 'complete', + Failed: 'failed' +} as const; + +export type TransferStatusEnum = typeof TransferStatusEnum[keyof typeof TransferStatusEnum]; + /** * * @export @@ -2798,6 +2919,58 @@ export const ExternalAddressesApiAxiosParamCreator = function (configuration?: C + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * List the historical balance of an asset in a specific address. + * @summary Get address balance history for asset + * @param {string} networkId The ID of the blockchain network + * @param {string} addressId The ID of the address to fetch the historical balance for. + * @param {string} assetId The symbol of the asset to fetch the historical balance for. + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listAddressHistoricalBalance: async (networkId: string, addressId: string, assetId: string, limit?: number, page?: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'networkId' is not null or undefined + assertParamExists('listAddressHistoricalBalance', 'networkId', networkId) + // verify required parameter 'addressId' is not null or undefined + assertParamExists('listAddressHistoricalBalance', 'addressId', addressId) + // verify required parameter 'assetId' is not null or undefined + assertParamExists('listAddressHistoricalBalance', 'assetId', assetId) + const localVarPath = `/v1/networks/{network_id}/addresses/{address_id}/balance_history/{asset_id}` + .replace(`{${"network_id"}}`, encodeURIComponent(String(networkId))) + .replace(`{${"address_id"}}`, encodeURIComponent(String(addressId))) + .replace(`{${"asset_id"}}`, encodeURIComponent(String(assetId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (limit !== undefined) { + localVarQueryParameter['limit'] = limit; + } + + if (page !== undefined) { + localVarQueryParameter['page'] = page; + } + + + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; @@ -2913,6 +3086,23 @@ export const ExternalAddressesApiFp = function(configuration?: Configuration) { const localVarOperationServerBasePath = operationServerMap['ExternalAddressesApi.getExternalAddressBalance']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, + /** + * List the historical balance of an asset in a specific address. + * @summary Get address balance history for asset + * @param {string} networkId The ID of the blockchain network + * @param {string} addressId The ID of the address to fetch the historical balance for. + * @param {string} assetId The symbol of the asset to fetch the historical balance for. + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listAddressHistoricalBalance(networkId: string, addressId: string, assetId: string, limit?: number, page?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listAddressHistoricalBalance(networkId, addressId, assetId, limit, page, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ExternalAddressesApi.listAddressHistoricalBalance']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, /** * List all of the balances of an external address * @summary Get the balances of an external address @@ -2964,6 +3154,20 @@ export const ExternalAddressesApiFactory = function (configuration?: Configurati getExternalAddressBalance(networkId: string, addressId: string, assetId: string, options?: any): AxiosPromise { return localVarFp.getExternalAddressBalance(networkId, addressId, assetId, options).then((request) => request(axios, basePath)); }, + /** + * List the historical balance of an asset in a specific address. + * @summary Get address balance history for asset + * @param {string} networkId The ID of the blockchain network + * @param {string} addressId The ID of the address to fetch the historical balance for. + * @param {string} assetId The symbol of the asset to fetch the historical balance for. + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listAddressHistoricalBalance(networkId: string, addressId: string, assetId: string, limit?: number, page?: string, options?: any): AxiosPromise { + return localVarFp.listAddressHistoricalBalance(networkId, addressId, assetId, limit, page, options).then((request) => request(axios, basePath)); + }, /** * List all of the balances of an external address * @summary Get the balances of an external address @@ -3008,6 +3212,20 @@ export interface ExternalAddressesApiInterface { */ getExternalAddressBalance(networkId: string, addressId: string, assetId: string, options?: RawAxiosRequestConfig): AxiosPromise; + /** + * List the historical balance of an asset in a specific address. + * @summary Get address balance history for asset + * @param {string} networkId The ID of the blockchain network + * @param {string} addressId The ID of the address to fetch the historical balance for. + * @param {string} assetId The symbol of the asset to fetch the historical balance for. + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExternalAddressesApiInterface + */ + listAddressHistoricalBalance(networkId: string, addressId: string, assetId: string, limit?: number, page?: string, options?: RawAxiosRequestConfig): AxiosPromise; + /** * List all of the balances of an external address * @summary Get the balances of an external address @@ -3054,6 +3272,22 @@ export class ExternalAddressesApi extends BaseAPI implements ExternalAddressesAp return ExternalAddressesApiFp(this.configuration).getExternalAddressBalance(networkId, addressId, assetId, options).then((request) => request(this.axios, this.basePath)); } + /** + * List the historical balance of an asset in a specific address. + * @summary Get address balance history for asset + * @param {string} networkId The ID of the blockchain network + * @param {string} addressId The ID of the address to fetch the historical balance for. + * @param {string} assetId The symbol of the asset to fetch the historical balance for. + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ExternalAddressesApi + */ + public listAddressHistoricalBalance(networkId: string, addressId: string, assetId: string, limit?: number, page?: string, options?: RawAxiosRequestConfig) { + return ExternalAddressesApiFp(this.configuration).listAddressHistoricalBalance(networkId, addressId, assetId, limit, page, options).then((request) => request(this.axios, this.basePath)); + } + /** * List all of the balances of an external address * @summary Get the balances of an external address diff --git a/src/coinbase/staking_reward.ts b/src/coinbase/staking_reward.ts index dbc575bd..4437f081 100644 --- a/src/coinbase/staking_reward.ts +++ b/src/coinbase/staking_reward.ts @@ -109,12 +109,39 @@ export class StakingReward { return this.model.address_id; } + /** + * Returns the USD value of the StakingReward. + * + * @returns The USD value. + */ + public usdValue(): Amount { + return new Decimal(this.model.usd_value.amount).div(new Decimal("100")); + } + + /** + * Returns the conversion price of the StakingReward in USD. + * + * @returns The conversion price. + */ + public conversionPrice(): Amount { + return new Decimal(this.model.usd_value.conversion_price); + } + + /** + * Returns the time of calculating the conversion price. + * + * @returns The conversion time. + */ + public conversionTime(): Date { + return new Date(this.model.usd_value.conversion_time); + } + /** * Print the Staking Reward as a string. * * @returns The string representation of the Staking Reward. */ public toString(): string { - return `StakingReward { date: '${this.date().toISOString()}' address: '${this.addressId()}' amount: '${this.amount().toString()}' }`; + return `StakingReward { date: '${this.date().toISOString()}' address: '${this.addressId()}' amount: '${this.amount().toString()}' usd_value: '${this.usdValue().toString()}' conversion_price: '${this.conversionPrice().toString()}' conversion_time: '${this.conversionTime().toISOString()}' }`; } } diff --git a/src/tests/external_address_test.ts b/src/tests/external_address_test.ts index d3d37d12..a3a7ff30 100644 --- a/src/tests/external_address_test.ts +++ b/src/tests/external_address_test.ts @@ -99,6 +99,11 @@ describe("ExternalAddress", () => { amount: "361", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "361", + conversion_price: "3000", + conversion_time: "2024-05-01T00:00:00Z", + }, }, { address_id: address.getId(), @@ -106,6 +111,11 @@ describe("ExternalAddress", () => { amount: "203", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "203", + conversion_price: "3000", + conversion_time: "2024-05-02T00:00:00Z", + }, }, { address_id: address.getId(), @@ -113,6 +123,11 @@ describe("ExternalAddress", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, ], has_more: false, diff --git a/src/tests/staking_reward_test.ts b/src/tests/staking_reward_test.ts index 53387fc2..871527a9 100644 --- a/src/tests/staking_reward_test.ts +++ b/src/tests/staking_reward_test.ts @@ -36,6 +36,11 @@ describe("StakingReward", () => { amount: "361", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "361", + conversion_price: "3000", + conversion_time: "2024-05-01T00:00:00Z", + }, }, { address_id: address.getId(), @@ -43,6 +48,11 @@ describe("StakingReward", () => { amount: "203", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "203", + conversion_price: "3000", + conversion_time: "2024-05-02T00:00:00Z", + }, }, { address_id: address.getId(), @@ -50,6 +60,11 @@ describe("StakingReward", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, ], has_more: false, @@ -132,13 +147,20 @@ describe("StakingReward", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, asset, StakingRewardFormat.Usd, ); const amount = reward.amount(); + const usdValue = reward.usdValue(); expect(amount).toEqual(new Decimal("2.26")); + expect(usdValue).toEqual(new Decimal("2.26")); }); it("should return the correct amount for native format", () => { @@ -149,6 +171,11 @@ describe("StakingReward", () => { amount: "726030823305604", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Native, + usd_value: { + amount: "179", + conversion_price: "2461.63", + conversion_time: "2024-05-02T00:00:00Z", + }, }, asset, StakingRewardFormat.Native, @@ -168,13 +195,20 @@ describe("StakingReward", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, asset, StakingRewardFormat.Usd, ); const date = reward.date(); + const conversionTime = reward.conversionTime(); expect(date).toEqual(new Date("2024-05-03")); + expect(conversionTime).toEqual(new Date("2024-05-03T00:00:00Z")); }); }); @@ -187,6 +221,11 @@ describe("StakingReward", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, asset, StakingRewardFormat.Usd, @@ -194,7 +233,7 @@ describe("StakingReward", () => { const rewardStr = reward.toString(); expect(rewardStr).toEqual( - "StakingReward { date: '2024-05-03T00:00:00.000Z' address: 'some-address-id' amount: '2.26' }", + "StakingReward { date: '2024-05-03T00:00:00.000Z' address: 'some-address-id' amount: '2.26' usd_value: '2.26' conversion_price: '3000' conversion_time: '2024-05-03T00:00:00.000Z' }", ); }); }); @@ -208,6 +247,11 @@ describe("StakingReward", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, asset, StakingRewardFormat.Usd, diff --git a/src/tests/wallet_address_test.ts b/src/tests/wallet_address_test.ts index c190df2e..2e2fd6b7 100644 --- a/src/tests/wallet_address_test.ts +++ b/src/tests/wallet_address_test.ts @@ -309,6 +309,11 @@ describe("WalletAddress", () => { amount: "361", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "361", + conversion_price: "3000", + conversion_time: "2024-05-01T00:00:00Z", + }, }, { address_id: newAddress.address_id, @@ -316,6 +321,11 @@ describe("WalletAddress", () => { amount: "203", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "203", + conversion_price: "3000", + conversion_time: "2024-05-02T00:00:00Z", + }, }, { address_id: newAddress.address_id, @@ -323,6 +333,11 @@ describe("WalletAddress", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, ], has_more: false, diff --git a/src/tests/wallet_test.ts b/src/tests/wallet_test.ts index 666389a7..3e0a3ad6 100644 --- a/src/tests/wallet_test.ts +++ b/src/tests/wallet_test.ts @@ -154,6 +154,11 @@ describe("Wallet Class", () => { amount: "361", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "361", + conversion_price: "3000", + conversion_time: "2024-05-01T00:00:00Z", + }, }, { address_id: addressID, @@ -161,6 +166,11 @@ describe("Wallet Class", () => { amount: "203", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "203", + conversion_price: "3000", + conversion_time: "2024-05-02T00:00:00Z", + }, }, { address_id: addressID, @@ -168,6 +178,11 @@ describe("Wallet Class", () => { amount: "226", state: StakingRewardStateEnum.Pending, format: StakingRewardFormat.Usd, + usd_value: { + amount: "226", + conversion_price: "3000", + conversion_time: "2024-05-03T00:00:00Z", + }, }, ], has_more: false,