diff --git a/src/client/api.ts b/src/client/api.ts index e2c8da50..86fc1fb9 100644 --- a/src/client/api.ts +++ b/src/client/api.ts @@ -1323,6 +1323,39 @@ export const StakingRewardFormat = { export type StakingRewardFormat = typeof StakingRewardFormat[keyof typeof StakingRewardFormat]; + +/** + * The asset amount in detail + * @export + * @interface AssetAmount + */ +export interface AssetAmount { + /** + * Amount The amount of the asset in the most common denomination such as ETH, BTC, etc. + * @type {string} + * @memberof AssetAmount + */ + amount: string; + /** + * Exp The number of decimals needed to convert from the raw numeric value to the most. + * @type {number} + * @memberof AssetAmount + */ + exp: number; + /** + * RawNumeric The raw, unadulterated numeric value, such as Wei (in Ethereum) and Lamports (in Solana). + * @type {string} + * @memberof AssetAmount + */ + raw_numeric: string; + /** + * Ticker The ticker of this asset (USD, ETH, SOL). + * @type {string} + * @memberof AssetAmount + */ + ticker: string; +} + /** * The staking balances for an address. * @export @@ -1343,22 +1376,22 @@ export interface StakingBalance { 'date': string; /** * The bonded stake. - * @type {string} + * @type {AssetAmount} * @memberof StakingBalance */ - 'bonded_stake': string; + 'bonded_stake': AssetAmount; /** * The unbonded stake. - * @type {string} + * @type {AssetAmount} * @memberof StakingBalance */ - 'unbonded_stake': string; + 'unbonded_stake': AssetAmount; /** * The total delegation received. - * @type {string} + * @type {AssetAmount} * @memberof StakingBalance */ - 'total_delegation': string; + 'total_delegation_received': AssetAmount; /** * The participate type of the given address. * @type {string} diff --git a/src/coinbase/asset_amount.ts b/src/coinbase/asset_amount.ts new file mode 100644 index 00000000..4a852e0d --- /dev/null +++ b/src/coinbase/asset_amount.ts @@ -0,0 +1,51 @@ +import { AssetAmount as AssetAmountModel } from "../client"; + +/** A representation of a balance. */ +export class AssetAmount { + public readonly amount: string; + public readonly ticker: string; + public readonly raw_numeric: string; + public readonly exp: number; + + public constructor(amount: string, raw_numeric: string, exp: number, ticker: string) { + this.amount = amount; + this.ticker = ticker; + this.raw_numeric = raw_numeric; + this.exp = exp; + } + + /** + * Converts a AssetAmountModel into a AssetAmount object. + * + * @param {AssetAmountModel} model - The assetAmount model object. + * @returns {AssetAmount} The Balance object. + */ + public static fromModel(model: AssetAmountModel): AssetAmount { + return new AssetAmount( + model.amount, + model.raw_numeric, + model.exp, + model.ticker, + ); + } + + public getAmount(): string { + return this.amount; + } + + public getTicker(): string { + return this.ticker; + } + + public getRawNumeric(): string { + return this.raw_numeric; + } + + public getExp(): number { + return this.exp; + } + + public toString(): string { + return `{ amount: '${this.amount}', raw_numeric: '${this.raw_numeric}', exp: ${this.exp}, ticker: '${this.ticker}' }`; + } +} diff --git a/src/coinbase/staking_balance.ts b/src/coinbase/staking_balance.ts index 5409d3f8..045e03c1 100644 --- a/src/coinbase/staking_balance.ts +++ b/src/coinbase/staking_balance.ts @@ -1,8 +1,6 @@ -import { StakingBalance as StakingBalanceModel } from "../client"; -import Decimal from "decimal.js"; +import { AssetAmount as AssetAmountModel, StakingBalance as StakingBalanceModel } from "../client"; import { Coinbase } from "./coinbase"; import { Asset } from "./asset"; -import { Amount } from "./types"; /** * A representation of a staking reward earned on a network for a given asset. @@ -78,8 +76,8 @@ export class StakingBalance { * * @returns The amount. */ - public bondedStake(): Amount { - return this.asset.fromAtomicAmount(new Decimal(this.model.bonded_stake)).toNumber(); + public bondedStake(): AssetAmountModel { + return this.model.bonded_stake } /** @@ -87,8 +85,8 @@ export class StakingBalance { * * @returns The amount. */ - public unbondedStake(): Amount { - return this.asset.fromAtomicAmount(new Decimal(this.model.unbonded_stake)).toNumber(); + public unbondedStake(): AssetAmountModel { + return this.model.unbonded_stake } /** @@ -96,8 +94,8 @@ export class StakingBalance { * * @returns The amount. */ - public totalDelegation(): Amount { - return this.asset.fromAtomicAmount(new Decimal(this.model.total_delegation)).toNumber(); + public totalDelegation(): AssetAmountModel { + return this.model.total_delegation_received } /** diff --git a/src/tests/staking_balance_test.ts b/src/tests/staking_balance_test.ts index d2a186e8..68eb1064 100644 --- a/src/tests/staking_balance_test.ts +++ b/src/tests/staking_balance_test.ts @@ -13,7 +13,7 @@ import { import { StakingBalance } from "../coinbase/staking_balance"; import { ExternalAddress } from "../coinbase/address/external_address"; import { Asset } from "../coinbase/asset"; -import Decimal from "decimal.js"; +import { AssetAmount } from "../coinbase/asset_amount"; describe("StakingBalance", () => { const startTime = "2024-05-01T00:00:00Z"; @@ -26,22 +26,27 @@ describe("StakingBalance", () => { contract_address: "0x", decimals: 18, }); + + const bondedStake = new AssetAmount("3", "3000000000000000000", 18, "ETH"); + const unbondedStake = new AssetAmount("2", "2000000000000000000", 18, "ETH"); + const totalDelegation = new AssetAmount("1", "1000000000000000000", 18, "ETH"); + const STAKING_BALANCE_RESPONSE: FetchStakingBalances200Response = { data: [ { address_id: address.getId(), date: "2024-05-01", - bonded_stake: "32000000000000000000", - unbonded_stake: "1000000000000000000", - total_delegation: "2000000000000000000", + bonded_stake: bondedStake, + unbonded_stake: unbondedStake, + total_delegation_received: totalDelegation, participate_type: "validator", }, { address_id: address.getId(), date: "2024-05-02", - bonded_stake: "33000000000000000000", - unbonded_stake: "2000000000000000000", - total_delegation: "3000000000000000000", + bonded_stake: bondedStake, + unbonded_stake: unbondedStake, + total_delegation_received: totalDelegation, participate_type: "validator", }, ], @@ -120,22 +125,31 @@ describe("StakingBalance", () => { { address_id: address.getId(), date: "2024-05-03", - bonded_stake: "32000000000000000000", - unbonded_stake: "2000000000000000000", - total_delegation: "1000000000000000000", + bonded_stake: new AssetAmount("32", "32000000000000000000", 18, "ETH"), + unbonded_stake: new AssetAmount("2", "2000000000000000000", 18, "ETH"), + total_delegation_received: new AssetAmount("1", "1000000000000000000", 18, "ETH"), participate_type: "validator", }, asset, ); - const bondedStake = balance.bondedStake(); - expect(bondedStake).toEqual(32); + const bondedStake = AssetAmount.fromModel(balance.bondedStake()); + expect(bondedStake.getAmount()).toEqual("32"); + expect(bondedStake.getRawNumeric()).toEqual("32000000000000000000"); + expect(bondedStake.getExp()).toEqual(18); + expect(bondedStake.getTicker()).toEqual("ETH"); - const unbondedStake = balance.unbondedStake(); - expect(unbondedStake).toEqual(2); + const unbondedStake = AssetAmount.fromModel(balance.unbondedStake()); + expect(unbondedStake.getAmount()).toEqual("2"); + expect(unbondedStake.getRawNumeric()).toEqual("2000000000000000000"); + expect(unbondedStake.getExp()).toEqual(18); + expect(unbondedStake.getTicker()).toEqual("ETH"); - const totalDelegation = balance.totalDelegation(); - expect(totalDelegation).toEqual(1); + const totalDelegation = AssetAmount.fromModel(balance.totalDelegation()); + expect(totalDelegation.getAmount()).toEqual("1"); + expect(totalDelegation.getRawNumeric()).toEqual("1000000000000000000"); + expect(totalDelegation.getExp()).toEqual(18); + expect(totalDelegation.getTicker()).toEqual("ETH"); const participateType = balance.participateType(); expect(participateType).toEqual("validator"); @@ -148,9 +162,9 @@ describe("StakingBalance", () => { { address_id: address.getId(), date: "2024-05-03", - bonded_stake: "226", - unbonded_stake: "1", - total_delegation: "0", + bonded_stake: bondedStake, + unbonded_stake: unbondedStake, + total_delegation_received: totalDelegation, participate_type: "validator", }, asset, @@ -167,9 +181,9 @@ describe("StakingBalance", () => { { address_id: address.getId(), date: "2024-05-03", - bonded_stake: "32000000000000000000", - unbonded_stake: "2000000000000000000", - total_delegation: "1000000000000000000", + bonded_stake: bondedStake, + unbonded_stake: unbondedStake, + total_delegation_received: totalDelegation, participate_type: "validator", }, asset, @@ -177,7 +191,7 @@ describe("StakingBalance", () => { const balanceStr = balance.toString(); expect(balanceStr).toEqual( - `StakingBalance { date: '2024-05-03T00:00:00.000Z' address: '${address.getId()}' bondedStake: '32' unbondedStake: '2' totalDelegation: '1' participateType: 'validator' }`, + `StakingBalance { date: '2024-05-03T00:00:00.000Z' address: '${address.getId()}' bondedStake: '{ amount: '${bondedStake.getAmount()}', raw_numeric: '${bondedStake.getRawNumeric()}', exp: ${bondedStake.getExp()}, ticker: '${bondedStake.getTicker()}' }' unbondedStake: '{ amount: '${unbondedStake.getAmount()}', raw_numeric: '${unbondedStake.getRawNumeric()}', exp: ${unbondedStake.getExp()}, ticker: '${unbondedStake.getTicker()}' }' totalDelegation: '{ amount: '${totalDelegation.getAmount()}', raw_numeric: '${totalDelegation.getRawNumeric()}', exp: ${totalDelegation.getExp()}, ticker: '${totalDelegation.getTicker()}' }' participateType: 'validator' }`, ); }); }); @@ -188,9 +202,9 @@ describe("StakingBalance", () => { { address_id: address.getId(), date: "2024-05-03", - bonded_stake: "226", - unbonded_stake: "1", - total_delegation: "0", + bonded_stake: bondedStake, + unbonded_stake: unbondedStake, + total_delegation_received: totalDelegation, participate_type: "validator", }, asset,