diff --git a/packages/api/src/config/index.ts b/packages/api/src/config/index.ts index 1d3986635..73030faa9 100644 --- a/packages/api/src/config/index.ts +++ b/packages/api/src/config/index.ts @@ -63,7 +63,7 @@ export default { */ impactMarketContractBlockNumber: validatedEnv.IMPACT_MARKET_CONTRACT_BLOCK, - /** contract addresses */ + /** contract addresses used to calculate the circulating supply */ contractAddresses: { pact: validatedEnv.PACT_CONTRACT_ADDRESS, airgrab: validatedEnv.AIRGRAB_CONTRACT_ADDRESS, diff --git a/packages/api/src/controllers/v1/circulatingSupply.ts b/packages/api/src/controllers/v1/circulatingSupply.ts new file mode 100644 index 000000000..0c7230279 --- /dev/null +++ b/packages/api/src/controllers/v1/circulatingSupply.ts @@ -0,0 +1,37 @@ +import { Contract } from '@ethersproject/contracts'; +import { JsonRpcProvider } from '@ethersproject/providers'; +import { config, contracts } from '@impactmarket/core'; +import { BigNumber } from 'bignumber.js'; +import { Request, Response } from 'express'; + +// this is required for external services to access the circulating supply +export const circulatingSupply = async (_req: Request, res: Response) => { + const decimals = new BigNumber(10).pow(18); + const pact = new Contract( + config.contractAddresses.pact, + contracts.ERC20ABI, + new JsonRpcProvider(config.jsonRpcUrl) + ); + const airgrabPACTBalance = await pact.balanceOf( + config.contractAddresses.airgrab + ); + const daoPACTBalance = await pact.balanceOf(config.contractAddresses.dao); + const donationMinerPACTBalance = await pact.balanceOf( + config.contractAddresses.donationMiner + ); + const impactLabsPACTBalance = await pact.balanceOf( + config.contractAddresses.impactLabs + ); + const idoPACTBalance = await pact.balanceOf(config.contractAddresses.ido); + const totalSupply = new BigNumber(10000000000).multipliedBy(decimals); + const circulatingSupply = new BigNumber(totalSupply) + .minus(airgrabPACTBalance.toString()) + .minus(daoPACTBalance.toString()) + .minus(donationMinerPACTBalance.toString()) + .minus(impactLabsPACTBalance.toString()) + .minus(idoPACTBalance.toString()); + const response = circulatingSupply.dividedBy(decimals).toNumber(); + + // answer + res.send(response.toString()); +}; diff --git a/packages/api/src/controllers/v1/generic.ts b/packages/api/src/controllers/v1/generic.ts index 6ecb31b54..1ce5f68ed 100644 --- a/packages/api/src/controllers/v1/generic.ts +++ b/packages/api/src/controllers/v1/generic.ts @@ -1,36 +1,7 @@ -import { config, database, contracts } from '@impactmarket/core'; -import { BigNumber } from 'bignumber.js'; -import { Contract, ethers } from 'ethers'; +import { database } from '@impactmarket/core'; +import { ethers } from 'ethers'; import { Request, Response } from 'express'; -const circulatingSupply = async (req: Request, res: Response) => { - const pact = new Contract( - config.contractAddresses.pact, - contracts.ERC20ABI, - new ethers.providers.JsonRpcProvider(config.jsonRpcUrl) - ); - const airgrabPACTBalance = await pact.balanceOf( - config.contractAddresses.airgrab - ); - const daoPACTBalance = await pact.balanceOf(config.contractAddresses.dao); - const donationMinerPACTBalance = await pact.balanceOf( - config.contractAddresses.donationMiner - ); - const impactLabsPACTBalance = await pact.balanceOf( - config.contractAddresses.impactLabs - ); - const idoPACTBalance = await pact.balanceOf(config.contractAddresses.ido); - const totalSupply = new BigNumber(10000000000).multipliedBy(10 ** 18); - const circulatingSupply = new BigNumber(totalSupply) - .minus(airgrabPACTBalance.toString()) - .minus(daoPACTBalance.toString()) - .minus(donationMinerPACTBalance.toString()) - .minus(impactLabsPACTBalance.toString()) - .minus(idoPACTBalance.toString()); - const response = circulatingSupply.dividedBy(10 ** 18).toNumber(); - res.send(response.toString()); -}; - const getAirgrab = async (req: Request, res: Response) => { const { address } = req.params; try { @@ -59,6 +30,5 @@ const getAirgrab = async (req: Request, res: Response) => { }; export default { - circulatingSupply, getAirgrab, }; diff --git a/packages/api/src/routes/v1/circulatingSupply.ts b/packages/api/src/routes/v1/circulatingSupply.ts new file mode 100644 index 000000000..31fd924e9 --- /dev/null +++ b/packages/api/src/routes/v1/circulatingSupply.ts @@ -0,0 +1,49 @@ +import { database } from '@impactmarket/core'; +import { Router, Request, Response } from 'express'; + +import { circulatingSupply } from '../../controllers/v1/circulatingSupply'; + +export default (app: Router): void => { + /** + * @swagger + * + * /circulating-supply: + * get: + * tags: + * - "generic" + * summary: Gets PACT circulating supply. + * responses: + * "200": + * description: OK + */ + app.get( + '/circulating-supply', + database.cacheWithRedis('50 minutes', database.cacheOnlySuccess), + circulatingSupply + ); + + /** + * @swagger + * + * /total-supply: + * get: + * tags: + * - "generic" + * summary: Gets total PACT supply. + * responses: + * "200": + * description: OK + * content: + * application/json: + * schema: + * type: object + * properties: + * success: + * type: boolean + * data: + * type: number + */ + app.get('/total-supply', (_req: Request, res: Response) => + res.send('10000000000') + ); +}; diff --git a/packages/api/src/routes/v1/generic.ts b/packages/api/src/routes/v1/generic.ts index e848f96b9..0f319d1a3 100644 --- a/packages/api/src/routes/v1/generic.ts +++ b/packages/api/src/routes/v1/generic.ts @@ -1,4 +1,4 @@ -import { config, database, services } from '@impactmarket/core'; +import { config, services } from '@impactmarket/core'; import { Router, Request, Response } from 'express'; import genericController from '../../controllers/v1/generic'; @@ -101,24 +101,6 @@ export default (app: Router): void => { standardResponse(res, 200, true, new Date().getTime()) ); - /** - * @swagger - * - * /circulating-supply: - * get: - * tags: - * - "generic" - * summary: Gets PACT circulating supply. - * responses: - * "200": - * description: OK - */ - app.get( - '/circulating-supply', - database.cacheWithRedis('10 minutes', database.cacheOnlySuccess), - genericController.circulatingSupply - ); - /** * @swagger * diff --git a/packages/api/src/routes/v1/index.ts b/packages/api/src/routes/v1/index.ts index bcfe74a8f..13bd66485 100644 --- a/packages/api/src/routes/v1/index.ts +++ b/packages/api/src/routes/v1/index.ts @@ -1,31 +1,10 @@ import { Router } from 'express'; -import claimLocation from './claimLocation'; -import community from './community'; -import exchange from './exchangeRates'; -import generic from './generic'; -import global from './global'; -import media from './media'; -import mobile from './mobile'; -import story from './story'; -import user from './user'; +import circulatingSupply from './circulatingSupply'; export default (): Router => { const app = Router(); - community(app); - user(app); - claimLocation(app); - exchange(app); - global(app); - mobile(app); - story(app); - media(app); - generic(app); - - /** - * @deprecated use /time - */ - app.get('/clock', (req, res) => res.json(new Date().getTime())); + circulatingSupply(app); return app; }; diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts index 75db1e7dd..6203c9432 100644 --- a/packages/api/src/server.ts +++ b/packages/api/src/server.ts @@ -12,6 +12,7 @@ import swaggerUi from 'swagger-ui-express'; import config from './config'; import { rateLimiter } from './middlewares'; // import v1routes from './routes/v1'; +import v1routes from './routes/v1'; import v2routes from './routes/v2'; export default (app: express.Application): void => { @@ -162,7 +163,9 @@ export default (app: express.Application): void => { } // Load API routes - // app.use(config.api.prefix, v1routes()); + // currenclty only PACT supply endpoints (used by external services) + app.use(config.api.prefix, v1routes()); + // default app.use(config.api.v2prefix, v2routes()); // The error handler must be before any other error middleware and after all controllers