From 244c863582f45c833e009275570907686fc9d885 Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Mon, 13 Nov 2023 14:31:41 -0700 Subject: [PATCH] feat(price): add price endpoint for retrieving costs of interactions on contract --- package.json | 1 + src/router.ts | 8 ++++++++ src/routes/contract.ts | 15 ++++++++++++++- tests/integration/arlocal/index.js | 4 ++++ tests/integration/routes.test.ts | 16 +++++++++++++++- tests/integration/setup.test.ts | 6 ------ 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 5e4f322..93de6e8 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "start:prod": "yarn build && node dist/app.js", "build": "yarn clean && yarn && npx tsc --project ./tsconfig.json", "clean": "rimraf [ node_modules dist cache ]", + "test:docker": "docker compose up --exit-code-from test-runner --build", "test:integration": "mocha --spec=tests/integration/**.test.ts", "test:integration:local": "docker compose up arlocal -d ; yarn test:integration $* ; docker compose down -v", "docker:run": "docker compose up arns-service --build", diff --git a/src/router.ts b/src/router.ts index 610e423..ba1b2ab 100644 --- a/src/router.ts +++ b/src/router.ts @@ -86,6 +86,14 @@ router.get( return contractReadInteractionHandler(ctx, next); }, ); +router.get( + `/v1/contract/:contractTxId${ARNS_CONTRACT_ID_REGEX}/price`, + (ctx: KoaContext, next: Next) => { + // set params for auction read interaction and then use our generic handler + ctx.params.functionName = 'priceForInteraction'; + return contractReadInteractionHandler(ctx, next); + }, +); // generic handler that handles read APIs for any contract function router.get( `/v1/contract/:contractTxId${ARNS_CONTRACT_ID_REGEX}/read/:functionName`, diff --git a/src/routes/contract.ts b/src/routes/contract.ts index 8c1041c..cc6c6d9 100644 --- a/src/routes/contract.ts +++ b/src/routes/contract.ts @@ -284,12 +284,25 @@ export async function contractReadInteractionHandler( functionName, }); + const parsedInput = Object.entries(input).reduce( + (parsedParams: { [x: string]: any }, [key, value]) => { + // parse known integer values + if (typeof value === 'string' && !isNaN(+value)) { + parsedParams[key] = +value; + return parsedParams; + } + parsedParams[key] = value; + return parsedParams; + }, + {}, + ); + const { result, evaluationOptions } = await getContractReadInteraction({ contractTxId, warp, logger, functionName, - input, + input: parsedInput, }); ctx.body = { diff --git a/tests/integration/arlocal/index.js b/tests/integration/arlocal/index.js index c57debf..69b2a9d 100644 --- a/tests/integration/arlocal/index.js +++ b/tests/integration/arlocal/index.js @@ -70,6 +70,10 @@ export function handle(state, action) { return { state }; } + if (input.function === 'priceForInteraction') { + return { result: { price: input.qty } }; + } + throw new ContractError( `No function supplied or function not recognized: "${input.function}"`, ); diff --git a/tests/integration/routes.test.ts b/tests/integration/routes.test.ts index 9509468..4d5331e 100644 --- a/tests/integration/routes.test.ts +++ b/tests/integration/routes.test.ts @@ -30,7 +30,7 @@ const axios = axiosPackage.create({ baseURL: serviceURL, validateStatus: () => true, // don't throw errors }); -describe('PDNS Service Integration tests', () => { +describe('Integration tests', () => { let ids: string[] = []; let id: string; let walletAddress: string; @@ -140,6 +140,20 @@ describe('PDNS Service Integration tests', () => { expect(status).to.equal(404); }); }); + describe('/:contractTxId/price', () => { + it('should properly handle price interaction inputs', async () => { + const { status, data } = await axios.get( + `/v1/contract/${id}/price?qty=100`, + ); + expect(status).to.equal(200); + expect(data).to.not.be.undefined; + const { contractTxId, result, evaluationOptions } = data; + expect(contractTxId).to.equal(id); + expect(evaluationOptions).not.to.be.undefined; + expect(result).to.include.keys(['price']); + expect(result.price).to.equal(100); + }); + }); describe('/:contractTxId/interactions', () => { it('should return the contract interactions', async () => { diff --git a/tests/integration/setup.test.ts b/tests/integration/setup.test.ts index 8b156ce..0da6fdb 100644 --- a/tests/integration/setup.test.ts +++ b/tests/integration/setup.test.ts @@ -109,12 +109,6 @@ export async function mochaGlobalSetup() { }, }), src: contractSrcJs, - evaluationManifest: { - evaluationOptions: { - // used for testing query params - throwOnInternalWriteError: true, - }, - }, }, true, // disable bundling );