Skip to content

Commit

Permalink
refactor: externalize currency tools in a new packages (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
vrolland committed Jan 12, 2021
1 parent d08119d commit b9669c4
Show file tree
Hide file tree
Showing 29 changed files with 1,825 additions and 316 deletions.
25 changes: 25 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,26 @@ jobs:
root: *working_directory
paths:
- packages/utils/coverage/
test-currency:
docker:
- *node_image
working_directory: *working_directory
steps:
- attach_workspace:
at: *working_directory
- run:
name: 'Build currency'
command: 'yarn workspace @requestnetwork/currency run build'
- run:
name: 'Lint currency'
command: 'yarn workspace @requestnetwork/currency run lint'
- run:
name: 'Test currency'
command: 'yarn workspace @requestnetwork/currency run test'
- persist_to_workspace:
root: *working_directory
paths:
- packages/currency/coverage/
test-epk-signature:
docker:
- *node_image
Expand Down Expand Up @@ -608,6 +628,9 @@ workflows:
- test-utils:
requires:
- build
- test-currency:
requires:
- build
- test-epk-signature:
requires:
- build
Expand Down Expand Up @@ -651,6 +674,7 @@ workflows:
- test-epk-decryption
- test-request-node
- test-utils
- test-currency
- test-multi-format
- test-payment-detection
- test-payment-processor
Expand All @@ -673,6 +697,7 @@ workflows:
- test-transaction-manager
- test-types
- test-utils
- test-currency
- test-web3-signature
- test-payment-detection
- test-payment-processor
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"scripts": {
"build": "lerna run build",
"clean": "lerna run clean",
"build:tsc": "tsc -b packages/advanced-logic packages/data-access packages/data-format packages/epk-decryption packages/epk-signature packages/ethereum-storage packages/integration-test packages/multi-format packages/payment-detection packages/prototype-estimator packages/request-client.js packages/request-logic packages/request-node packages/smart-contracts packages/toolbox packages/transaction-manager packages/types packages/usage-examples packages/utils packages/web3-signature",
"build:tsc": "tsc -b packages/advanced-logic packages/data-access packages/data-format packages/epk-decryption packages/epk-signature packages/ethereum-storage packages/integration-test packages/multi-format packages/payment-detection packages/prototype-estimator packages/request-client.js packages/request-logic packages/request-node packages/smart-contracts packages/toolbox packages/transaction-manager packages/types packages/usage-examples packages/utils packages/web3-signature packages/currency",
"lint": "lerna run lint",
"lint-staged": "lerna run lint-staged",
"lerna": "lerna",
Expand All @@ -36,4 +36,4 @@
"remap-istanbul": "0.13.0",
"typescript": "4.1.3"
}
}
}
3 changes: 3 additions & 0 deletions packages/currency/.lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"src/**/*.ts": ["tslint --project . --fix", "prettier --single-quote --write", "git add"]
}
19 changes: 19 additions & 0 deletions packages/currency/.nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extension": [
".ts"
],
"include": [
"src/*.ts",
"src/**/*.ts"
],
"require": [
"ts-node/register"
],
"reporter": [
"text-summary",
"json",
"html"
],
"sourceMap":true,
"all": true
}
5 changes: 5 additions & 0 deletions packages/currency/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"mochaExplorer.files": "**/test/**/*.ts",
"mochaExplorer.require": "ts-node/register",
"mochaExplorer.cwd": "../.."
}
32 changes: 32 additions & 0 deletions packages/currency/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# @requestnetwork/currency

`@requestnetwork/currency` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork).
It is a collection of tools for the currencies shared between the @requestnetwork packages.

## Installation

```bash
npm install @requestnetwork/currency
```

## Usage

```javascript
import Currency from '@requestnetwork/currency';

const decimals = Currency.getDecimalsForCurrency({
type: RequestLogicTypes.CURRENCY.ETH,
value: 'ETH',
};

console.log(decimals); // 18
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
[Read the contributing guide](/CONTRIBUTING.md)
## License
[MIT](/LICENSE)
5 changes: 5 additions & 0 deletions packages/currency/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverage: true,
};
64 changes: 64 additions & 0 deletions packages/currency/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "@requestnetwork/currency",
"version": "0.1.0",
"publishConfig": {
"access": "public"
},
"description": "Currency tools for Request Network packages.",
"keywords": [
"requestnetwork",
"currency",
"utils"
],
"repository": {
"type": "git",
"url": "git+https://github.com/RequestNetwork/requestNetwork.git"
},
"homepage": "https://github.com/RequestNetwork/requestNetwork/tree/master/packages/currency#readme",
"bugs": {
"url": "https://github.com/RequestNetwork/requestNetwork/issues"
},
"license": "MIT",
"engines": {
"node": ">=8.0.0"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"directories": {
"lib": "src",
"test": "test"
},
"files": [
"dist"
],
"scripts": {
"build": "tsc -b",
"clean": "shx rm -rf dist tsconfig.tsbuildinfo",
"lint": "tslint --project . && eslint \"src/**/*.ts\"",
"lint-staged": "lint-staged",
"prepare": "yarn run build",
"test": "jest",
"test:watch": "yarn test --watch"
},
"dependencies": {
"@metamask/contract-metadata": "1.20.0",
"@requestnetwork/types": "0.29.2",
"ethers": "4.0.48"
},
"devDependencies": {
"@types/jest": "26.0.13",
"@typescript-eslint/parser": "4.1.1",
"eslint": "7.9.0",
"eslint-plugin-spellcheck": "0.0.17",
"eslint-plugin-typescript": "0.14.0",
"jest": "26.4.2",
"lint-staged": "10.3.0",
"prettier": "2.1.1",
"shx": "0.3.2",
"source-map-support": "0.5.19",
"ts-jest": "26.3.0",
"ts-node": "9.0.0",
"tslint": "6.1.3",
"typescript": "4.0.2"
}
}
102 changes: 102 additions & 0 deletions packages/currency/src/erc20/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { RequestLogicTypes } from '@requestnetwork/types';
import { utils } from 'ethers';
import { supportedNetworks, supportedNetworksDetails, ERC20SymbolDetails } from './networks';

/**
* Returns a Currency object for an ERC20, if found
* @param symbol The ERC20 token symbol
* @param network The ERC20 contract network
*/
export function getErc20Currency(
symbol: string,
network: string = 'mainnet',
): RequestLogicTypes.ICurrency | undefined {
// Check if it's on one of the other supported networks
if (supportedNetworks.hasOwnProperty(network) && supportedNetworks[network].has(symbol)) {
return supportedNetworks[network].get(symbol);
}

return;
}

/**
* Get the amount of decimals for an ERC20 currency
*
* @param currency The ERC20 Currency object
* @returns The number of decimals for the ERC20 currency
*/
export function getErc20Decimals(currency: RequestLogicTypes.ICurrency): number {
const network = currency.network || 'mainnet';
let erc20Token;

// Get the decimals from one of the supported ERC20 networks
if (supportedNetworksDetails.hasOwnProperty(network)) {
erc20Token = Object.values(supportedNetworksDetails[network]).find(
({ address }) => address === currency.value,
);
}

if (erc20Token) {
return erc20Token.decimals;
}

// If no supported ERC20 is found, throw error
throw new Error(`Unsupported ERC20 address: ${currency.value}`);
}

/**
* Returns true if the address is a valid checksum address
*
* @param address The address to validate
* @returns If the address is valid or not
*/
export function validERC20Address(address: string): boolean {
return utils.getAddress(address) === address;
}

/**
* Get an ERC20 symbol from the Currency object
*
* @param token the ERC20 ICurrency
* @returns the ERC20 currency symbol string
*/
export function getErc20Symbol(currency: RequestLogicTypes.ICurrency): string | null {
const network = currency.network || 'mainnet';

if (currency.type !== RequestLogicTypes.CURRENCY.ERC20) {
throw new Error('Can only get symbol for ERC20 currencies');
}

// Find ERC20 symbol in one of the other supported ERC20 networks
if (supportedNetworks.hasOwnProperty(network)) {
const entry = [...supportedNetworks[network].entries()].find(
([, obj]) => currency.value === obj.value,
);
return entry ? entry[0] : null;
}

return null;
}

interface ERC20TokenDetails extends ERC20SymbolDetails {
symbol: string;
}
/**
* Returns a list of supported ERC20 currencies
*
* @returns List of supported ERC20 currencies
*/
export function getSupportedERC20Tokens(): ERC20TokenDetails[] {
return Object.entries(supportedNetworksDetails).reduce(
(acc: ERC20TokenDetails[], [networkName, network]) => {
return [
...acc,
...Object.entries(network).map(([symbol, token]) => ({
...token,
symbol: `${symbol}${networkName !== 'mainnet' ? `-${networkName}` : ''}`,
})),
];
},
[],
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RequestLogicTypes } from '@requestnetwork/types';
import { supportedRinkebyERC20, supportedRinkebyERC20Details } from './rinkeby';
import { supportedMainnetERC20, supportedMainnetERC20Details } from './mainnet';
import { supportedCeloERC20, supportedCeloERC20Details } from './celo';

/**
Expand Down Expand Up @@ -31,9 +32,11 @@ interface ISupportedNetworksDetails {
export const supportedNetworks: ISupportedNetworksMap = {
celo: supportedCeloERC20,
rinkeby: supportedRinkebyERC20,
mainnet: supportedMainnetERC20,
};

export const supportedNetworksDetails: ISupportedNetworksDetails = {
celo: supportedCeloERC20Details,
rinkeby: supportedRinkebyERC20Details,
mainnet: supportedMainnetERC20Details,
};

0 comments on commit b9669c4

Please sign in to comment.