Skip to content

Commit

Permalink
refactor!: rename AssetInfo 'quantity' to 'supply'
Browse files Browse the repository at this point in the history
  • Loading branch information
mirceahasegan committed Apr 18, 2023
1 parent 195766a commit 6e28df4
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { AssetProvider } from '@cardano-sdk/core';
import { CreateHttpProviderConfig, HttpProviderConfigPaths, createHttpProvider } from '../HttpProvider';
import { Asset, AssetProvider } from '@cardano-sdk/core';
import {
CreateHttpProviderConfig,
HttpProviderConfig,
HttpProviderConfigPaths,
createHttpProvider
} from '../HttpProvider';

/**
* The AssetProvider endpoint paths.
Expand All @@ -10,6 +15,23 @@ const paths: HttpProviderConfigPaths<AssetProvider> = {
healthCheck: '/health'
};

const isAssetInfo = (assetInfo: unknown): assetInfo is Asset.AssetInfo => !!(assetInfo as Asset.AssetInfo)?.assetId;

const transformQuantityToSupply = (assetInfo: Asset.AssetInfo | unknown): Asset.AssetInfo | unknown => {
if (isAssetInfo(assetInfo) && assetInfo.supply === undefined) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { quantity, ...assetInfoReduced } = assetInfo as any;
return { ...assetInfoReduced, supply: quantity } as Asset.AssetInfo;
}
return assetInfo;
};

const responseTransformers: HttpProviderConfig<AssetProvider>['responseTransformers'] = {
getAsset: (data: unknown): unknown => transformQuantityToSupply(data),
getAssets: (data: unknown): unknown =>
Array.isArray(data) ? data.map((assetInfo) => transformQuantityToSupply(assetInfo)) : data
};

/**
* Connect to a Cardano Services HttpServer instance with the service available
*
Expand All @@ -18,5 +40,6 @@ const paths: HttpProviderConfigPaths<AssetProvider> = {
export const assetInfoHttpProvider = (config: CreateHttpProviderConfig<AssetProvider>): AssetProvider =>
createHttpProvider<AssetProvider>({
...config,
paths
paths,
responseTransformers
});
17 changes: 14 additions & 3 deletions packages/cardano-services-client/src/HttpProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import { Logger } from 'ts-log';
import { ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { fromSerializableObject, toSerializableObject } from '@cardano-sdk/util';
import axios, { AxiosAdapter, AxiosRequestConfig } from 'axios';
import axios, { AxiosAdapter, AxiosRequestConfig, AxiosResponseTransformer } from 'axios';

const isEmptyResponse = (response: any) => response === '';

export type HttpProviderConfigPaths<T> = { [methodName in keyof T]: string };
type ResponseTransformers<T> = { [K in keyof T]?: AxiosResponseTransformer };

export interface HttpProviderConfig<T> {
/**
Expand Down Expand Up @@ -41,6 +42,11 @@ export interface HttpProviderConfig<T> {
* Logger strategy.
*/
logger: Logger;

/**
* Transform responses
*/
responseTransformers?: ResponseTransformers<T>;
}

/**
Expand All @@ -65,14 +71,17 @@ export const createHttpProvider = <T extends object>({
mapError,
paths,
adapter,
logger
logger,
responseTransformers
}: HttpProviderConfig<T>): T =>
new Proxy<T>({} as T, {
// eslint-disable-next-line sonarjs/cognitive-complexity
get(_, prop) {
if (prop === 'then') return;
const method = prop as keyof T;
const path = paths[method];
const transformResponse =
responseTransformers && responseTransformers[method] ? responseTransformers[method]! : (v: unknown) => v;
if (!path)
throw new ProviderError(ProviderFailure.NotImplemented, `HttpProvider missing path for '${prop.toString()}'`);
return async (...args: any[]) => {
Expand All @@ -97,7 +106,9 @@ export const createHttpProvider = <T extends object>({
});
axiosInstance.interceptors.response.use((value) => ({
...value,
data: fromSerializableObject(value.data, { getErrorPrototype: () => ProviderError.prototype })
data: transformResponse(
fromSerializableObject(value.data, { getErrorPrototype: () => ProviderError.prototype })
)
}));
const response = (await axiosInstance.request(req)).data;
return !isEmptyResponse(response) ? response : undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Cardano } from '@cardano-sdk/core';
import { assetInfoHttpProvider } from '../../src';
import { logger } from '@cardano-sdk/util-dev';
import { toSerializableObject } from '@cardano-sdk/util';
import MockAdapter from 'axios-mock-adapter';
import axios from 'axios';

Expand Down Expand Up @@ -41,5 +42,25 @@ describe('assetInfoHttpProvider', () => {
})
).resolves.toEqual({});
});

test('getAsset maps legacy assetInfo `quantity` as `supply`', async () => {
axiosMock.onPost().replyOnce(200, toSerializableObject({ assetId: 'dummy', quantity: 2n }));
const provider = assetInfoHttpProvider(config);
await expect(
provider.getAsset({
assetId: Cardano.AssetId('f43a62fdc3965df486de8a0d32fe800963589c41b38946602a0dc53541474958')
})
).resolves.toEqual({ assetId: 'dummy', supply: 2n });
});

test('getAssets maps legacy assetInfo `quantity` as `supply`', async () => {
axiosMock.onPost().replyOnce(200, toSerializableObject([{ assetId: 'dummy', quantity: 2n }]));
const provider = assetInfoHttpProvider(config);
await expect(
provider.getAssets({
assetIds: [Cardano.AssetId('f43a62fdc3965df486de8a0d32fe800963589c41b38946602a0dc53541474958')]
})
).resolves.toEqual([{ assetId: 'dummy', supply: 2n }]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ export class DbSyncAssetProvider extends DbSyncProvider() implements AssetProvid

const fingerprint = multiAsset.fingerprint as unknown as Cardano.AssetFingerprint;
const quantities = await this.#builder.queryMultiAssetQuantities(multiAsset.id);
const quantity = BigInt(quantities.sum);
const supply = BigInt(quantities.sum);
const mintOrBurnCount = Number(quantities.count);

return { assetId, fingerprint, mintOrBurnCount, name, policyId, quantity };
return { assetId, fingerprint, mintOrBurnCount, name, policyId, supply };
}
}
16 changes: 16 additions & 0 deletions packages/cardano-services/src/Asset/openApi.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,22 @@
},
"policyId": {
"type": "string"
},
"supply": {
"$ref": "#/components/schemas/BigInt"
}
}
},
"BigInt": {
"required": ["value", "__type"],
"type": "object",
"properties": {
"value": {
"type": "string"
},
"__type": {
"type": "string",
"enum": ["bigint"]
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('DbSyncAssetProvider', () => {
mintOrBurnCount: 1,
name: '6d616361726f6e2d63616b65',
policyId: '50fdcdbfa3154db86a87e4b5697ae30d272e0bbcfa8122efd3e301cb',
quantity: 1n
supply: 1n
});
});
it('returns an AssetInfo with extra data', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Asset/types/AssetInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface AssetInfo {
policyId: PolicyId;
name: AssetName;
fingerprint: AssetFingerprint;
quantity: bigint;
supply: bigint;
mintOrBurnCount: number;
/**
* Sorted by slot
Expand Down
8 changes: 4 additions & 4 deletions packages/e2e/test/wallet/SingleAddressWallet/nft.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ describe('SingleAddressWallet.assets/nft', () => {
version: '1.0'
},
policyId,
// in case of repeated tests on the same network, total asset quantity is not updated due to
// in case of repeated tests on the same network, total asset supply is not updated due to
// the limitation that asset info is not refreshed on wallet balance changes
quantity: expect.anything(),
supply: expect.anything(),
tokenMetadata: null
});
expect(nfts.find((nft) => nft.assetId === assetIds[TOKEN_METADATA_1_INDEX])).toBeDefined();
Expand Down Expand Up @@ -251,7 +251,7 @@ describe('SingleAddressWallet.assets/nft', () => {
version: '1.0'
},
policyId,
quantity: expect.anything(),
supply: expect.anything(),
tokenMetadata: null
});
});
Expand Down Expand Up @@ -385,7 +385,7 @@ describe('SingleAddressWallet.assets/nft', () => {
version: '1.0'
},
policyId,
quantity: expect.anything(),
supply: expect.anything(),
tokenMetadata: null
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/wallet/test/mocks/mockAssetProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const asset = {
name: Cardano.AssetName('54534c41'),
nftMetadata: null,
policyId: Cardano.PolicyId('7eae28af2208be856f7a119668ae52a49b73725e326dc16579dcc373'),
quantity: 1000n,
supply: 1000n,
tokenMetadata: null
} as Asset.AssetInfo;

Expand Down

0 comments on commit 6e28df4

Please sign in to comment.