From cc631bb363800b988962f475790eecd010298730 Mon Sep 17 00:00:00 2001 From: Alex Stone Date: Mon, 28 Oct 2024 12:05:35 -0700 Subject: [PATCH] fix: Normalize asset IDs This handles normalizing asset IDs when checking responses from the backend. This will allow us to use either `POL` or the normalized `pol` when interacting with Assets / Asset IDs. Previously if you passed a non-normalized asset ID, e.g. `POL`, then when we check the asset ID v.s. the returned model it would not equal `pol`. --- src/coinbase/asset.ts | 9 ++++++--- src/coinbase/coinbase.ts | 4 +++- src/tests/asset_test.ts | 17 ++++++++++++++++- src/tests/wallet_address_test.ts | 2 +- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/coinbase/asset.ts b/src/coinbase/asset.ts index 18b41abb..c9fba368 100644 --- a/src/coinbase/asset.ts +++ b/src/coinbase/asset.ts @@ -44,6 +44,7 @@ export class Asset { throw new Error("Invalid asset model"); } + let decimals = model.decimals!; // TODO: Push this logic down to the backend. if ( @@ -51,7 +52,7 @@ export class Asset { model.asset_id && Coinbase.toAssetId(model.asset_id) !== Coinbase.toAssetId(assetId) ) { - switch (assetId) { + switch (Coinbase.toAssetId(assetId)) { case "gwei": decimals = GWEI_DECIMALS; break; @@ -92,9 +93,11 @@ export class Asset { * @returns The primary denomination for the Asset ID. */ public static primaryDenomination(assetId: string): string { - return [Coinbase.assets.Gwei, Coinbase.assets.Wei].includes(assetId) + const normalizedAssetId = Coinbase.toAssetId(assetId); + + return [Coinbase.assets.Gwei, Coinbase.assets.Wei].includes(normalizedAssetId) ? Coinbase.assets.Eth - : assetId; + : normalizedAssetId; } /** diff --git a/src/coinbase/coinbase.ts b/src/coinbase/coinbase.ts index f060c3a9..90f56caa 100644 --- a/src/coinbase/coinbase.ts +++ b/src/coinbase/coinbase.ts @@ -57,6 +57,7 @@ export class Coinbase { Weth: "weth", Sol: "sol", Lamport: "lamport", + Pol: "pol", }; static apiClients: ApiClients = {}; @@ -253,11 +254,12 @@ export class Coinbase { /** * Converts a string to a symbol, replacing hyphens with underscores. + * This also converts the string to lowercase. * * @param asset - The string to convert * @returns the converted symbol */ static toAssetId(asset: string): string { - return asset.replace(/-/g, "_"); + return asset.replace(/-/g, "_").toLowerCase(); } } diff --git a/src/tests/asset_test.ts b/src/tests/asset_test.ts index 9eac3622..77899603 100644 --- a/src/tests/asset_test.ts +++ b/src/tests/asset_test.ts @@ -17,6 +17,20 @@ describe("Asset", () => { expect(asset.getAssetId()).toEqual(Coinbase.assets.Eth); }); + describe("when the specified Asset ID is not normalized", () => { + it("should normalize the Asset ID", () => { + const model = { + asset_id: "pol", + network_id: Coinbase.networks.PolygonMainnet, + decimals: 18, + }; + const asset = Asset.fromModel(model, "POL"); + expect(asset).toBeInstanceOf(Asset); + expect(asset.getAssetId()).toEqual(Coinbase.assets.Pol); + + }); + }); + describe("when the model is invalid", () => { it("should throw an error", () => { expect(() => Asset.fromModel(null!)).toThrow("Invalid asset model"); @@ -34,6 +48,7 @@ describe("Asset", () => { expect(Asset.fromModel(model, Coinbase.assets.Gwei).decimals).toEqual(GWEI_DECIMALS); }); }); + describe("when the asset_id is wei", () => { it("should set the decimals to 0", () => { const model = { @@ -62,7 +77,7 @@ describe("Asset", () => { }); describe(".primaryDenomination", () => { - ["wei", "gwei"].forEach(assetId => { + ["wei", "gwei", "WEI", "GWEI"].forEach(assetId => { describe(`when the assetId is ${assetId}`, () => { it("should return 'eth'", () => { expect(Asset.primaryDenomination(assetId)).toEqual("eth"); diff --git a/src/tests/wallet_address_test.ts b/src/tests/wallet_address_test.ts index c633d031..0ce226f9 100644 --- a/src/tests/wallet_address_test.ts +++ b/src/tests/wallet_address_test.ts @@ -190,7 +190,7 @@ describe("WalletAddress", () => { it("should return an error for an unsupported asset", async () => { const getAddressBalance = mockReturnRejectedValue(new APIError("")); - const assetId = "unsupported-asset"; + const assetId = "unsupportedasset"; Coinbase.apiClients.externalAddress!.getExternalAddressBalance = getAddressBalance; await expect(address.getBalance(assetId)).rejects.toThrow(APIError); expect(getAddressBalance).toHaveBeenCalledWith(