Skip to content

Commit

Permalink
refactor: linter warning fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasBustamante committed Jan 27, 2021
1 parent 0092b57 commit 75e3ca4
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ const tryAddToken = <T extends TransactionInOut>(inOut: T, findResult: FindTrans
if (!tokenBundle.tokens.has(policyAsHex)) {
tokenBundle.tokens.set(policyAsHex, []);
}
tokenBundle.tokens.get(policyAsHex)!.push({ name: nameAsHex, quantity });
tokenBundle.tokens.get(policyAsHex)?.push({ name: nameAsHex, quantity });

return {
...inOut,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
PREFIX_LENGTH,
PUBLIC_KEY_BYTES_LENGTH,
SIGNATURE_LENGTH,
StakeType
StakeAddressPrefix
} from '../utils/constants';
import { ErrorFactory } from '../utils/errors';
import { hexFormatter } from '../utils/formatters';
Expand Down Expand Up @@ -301,7 +301,9 @@ const configure = (linearFeeParameters: LinearFeeParameters, minKeyDeposit: numb
},
isStakeAddress(address) {
const addressPrefix = this.getPrefixFromAddress(address);
return [StakeType.STAKE as string, StakeType.STAKE_TEST as string].some(type => addressPrefix.includes(type));
return [StakeAddressPrefix.MAIN as string, StakeAddressPrefix.TEST as string].some(type =>
addressPrefix.includes(type)
);
},
getHashOfSignedTransaction(logger, signedTransaction) {
try {
Expand Down
21 changes: 7 additions & 14 deletions cardano-rosetta-server/src/server/utils/cardano/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import CardanoWasm, { StakeCredential } from 'cardano-serialization-lib';
import { Logger } from 'fastify';
import { NetworkIdentifier } from '../constants';
import { NetworkIdentifier, AddressPrefix, StakeAddressPrefix, NonStakeAddressPrefix } from '../constants';

/**
* Returns the bech-32 address prefix based on the netowrkId acording to
* Prefix according to: https://github.com/cardano-foundation/CIPs/tree/master/CIP5#specification
* Returns the bech-32 address prefix based on the netowrkId
* Prefix according to: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0005/CIP-0005.md
* @param network number
* @param addressPrefix the corresponding prefix enum. Defaults to non stake address prefixes
*/
export const getAddressPrefix = (network: number) =>
network === NetworkIdentifier.CARDANO_MAINNET_NETWORK ? 'addr' : 'addr_test';

/**
* Returns the bech-32 stake address prefix based on the netowrkId acording to
* Prefix according to: https://github.com/cardano-foundation/CIPs/tree/master/CIP5#specification
* @param network number
*/
export const getStakeAddressPrefix = (network: number) =>
network === NetworkIdentifier.CARDANO_MAINNET_NETWORK ? 'stake' : 'stake_test';
export const getAddressPrefix = (network: number, addressPrefix: AddressPrefix = NonStakeAddressPrefix): string =>
network === NetworkIdentifier.CARDANO_MAINNET_NETWORK ? addressPrefix.MAIN : addressPrefix.TEST;

/**
* Creates a new Reward address
Expand All @@ -31,7 +24,7 @@ export const generateRewardAddress = (
): string => {
logger.info('[generateRewardAddress] Deriving cardano reward address from valid public staking key');
const rewardAddress = CardanoWasm.RewardAddress.new(network, paymentCredential);
const bech32address = rewardAddress.to_address().to_bech32(getStakeAddressPrefix(network));
const bech32address = rewardAddress.to_address().to_bech32(getAddressPrefix(network, StakeAddressPrefix));
logger.info(`[generateRewardAddress] reward address is ${bech32address}`);
return bech32address;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,52 +19,45 @@ import { getStakingCredentialFromHex } from './staking-credentials';

const isPositiveNumber = (value: string): boolean => /^\+?\d+/.test(value);

/**
* This function validates and parses token bundles that might be attached to unspents
*
* @param tokenBundle bundle to be parsed
*/
const validateAndParseTokenBundle = (
logger: Logger,
tokenBundle: Components.Schemas.TokenBundleItem[]
): CardanoWasm.MultiAsset =>
tokenBundle.reduce((multiAssets, multiAsset) => {
const policyId = multiAsset.policyId;
tokenBundle.reduce((multiAssets, { policyId, tokens }) => {
if (!isPolicyIdValid(policyId)) {
logger.error(`[validateAndParseTokenBundle] PolicyId ${policyId} is not valid`);
throw ErrorFactory.transactionOutputsParametersMissingError(`PolicyId ${policyId} is not valid`);
}
const policy = ScriptHash.from_bytes(Buffer.from(multiAsset.policyId, 'hex'));
const assetsToAdd = multiAsset.tokens.reduce((assets, asset) => {
const tokenName = asset.currency.symbol;
const policy = ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
const assetsToAdd = tokens.reduce((assets, { currency: { symbol: tokenName }, value: assetValue }) => {
if (!isTokenNameValid(tokenName)) {
logger.error(`[validateAndParseTokenBundle] Token name ${tokenName} is not valid`);
throw ErrorFactory.transactionOutputsParametersMissingError(`Token name ${tokenName} is not valid`);
}
const assetName = AssetName.new(Buffer.from(tokenName, 'hex'));
if (assets.get(assetName) !== undefined) {
logger.error(
`[validateAndParseTokenBundle] Token name ${tokenName} has already been added for policy ${multiAsset.policyId}`
`[validateAndParseTokenBundle] Token name ${tokenName} has already been added for policy ${policyId}`
);
throw ErrorFactory.transactionOutputsParametersMissingError(
`Token name ${tokenName} has already been added for policy ${multiAsset.policyId} and will be overriden`
`Token name ${tokenName} has already been added for policy ${policyId} and will be overriden`
);
}
if (asset.value === undefined || !asset.value[0]) {
if (assetValue === undefined || !assetValue[0]) {
logger.error(
`[validateAndParseTokenBundle] Token with name ${tokenName} for policy ${multiAsset.policyId} has no value or is empty`
`[validateAndParseTokenBundle] Token with name ${tokenName} for policy ${policyId} has no value or is empty`
);
throw ErrorFactory.transactionOutputsParametersMissingError(
`Token with name ${tokenName} for policy ${multiAsset.policyId} has no value or is empty`
`Token with name ${tokenName} for policy ${policyId} has no value or is empty`
);
}
if (!isPositiveNumber(asset.value)) {
logger.error(`[validateAndParseTokenBundle] Asset ${tokenName} has negative or invalid value '${asset.value}'`);
if (!isPositiveNumber(assetValue)) {
logger.error(`[validateAndParseTokenBundle] Asset ${tokenName} has negative or invalid value '${assetValue}'`);
throw ErrorFactory.transactionOutputsParametersMissingError(
`Asset ${tokenName} has negative or invalid value '${asset.value}'`
`Asset ${tokenName} has negative or invalid value '${assetValue}'`
);
}
assets.insert(assetName, BigNum.from_str(asset.value));
assets.insert(assetName, BigNum.from_str(assetValue));
return assets;
}, Assets.new());
multiAssets.insert(policy, assetsToAdd);
Expand All @@ -75,7 +68,6 @@ const validateAndParseTransactionOutput = (
logger: Logger,
output: Components.Schemas.Operation
): CardanoWasm.TransactionOutput => {
// eslint-disable-next-line camelcase
let address;
try {
address = output.account && CardanoWasm.Address.from_bech32(output.account.address);
Expand Down Expand Up @@ -198,12 +190,15 @@ const operationProcessor: (
} = (logger, operation, network, resultAccumulator) => ({
[OperationType.INPUT]: () => {
resultAccumulator.transactionInputs.add(validateAndParseTransactionInput(logger, operation));
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resultAccumulator.addresses.push(operation.account!.address);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resultAccumulator.inputAmounts.push(operation.amount!.value);
return resultAccumulator;
},
[OperationType.OUTPUT]: () => {
resultAccumulator.transactionOutputs.add(validateAndParseTransactionOutput(logger, operation));
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resultAccumulator.outputAmounts.push(operation.amount!.value);
return resultAccumulator;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ const parseCertToOperation = (
};
const delegationCert = cert.as_stake_delegation();
if (delegationCert) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
operation.metadata!.pool_key_hash = Buffer.from(delegationCert.pool_keyhash().to_bytes()).toString('hex');
}
return operation;
Expand All @@ -151,15 +152,17 @@ const parseCertsToOperations = (
}
const credential = getStakingCredentialFromHex(logger, stakingOperation.metadata?.staking_credential);
const address = generateRewardAddress(logger, network, credential);
const cert = transactionBody.certs()!.get(i);
const parsedOperation = parseCertToOperation(
cert,
stakingOperation.operation_identifier.index,
hex,
stakingOperation.type,
address
);
parsedOperations.push(parsedOperation);
const cert = transactionBody.certs()?.get(i);
if (cert) {
const parsedOperation = parseCertToOperation(
cert,
stakingOperation.operation_identifier.index,
hex,
stakingOperation.type,
address
);
parsedOperations.push(parsedOperation);
}
}

return parsedOperations;
Expand Down Expand Up @@ -197,10 +200,13 @@ const parseWithdrawalsToOperations = (
logger.info(`[parseWithdrawalsToOperations] About to parse ${withdrawalsCount} withdrawals`);
for (let i = 0; i < withdrawalsCount; i++) {
const withdrawalOperation = withdrawalOps[i];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const credential = getStakingCredentialFromHex(logger, withdrawalOperation.metadata!.staking_credential);
const address = generateRewardAddress(logger, network, credential);
const parsedOperation = parseWithdrawalToOperation(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
withdrawalOperation.amount!.value,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
withdrawalOperation.metadata!.staking_credential!.hex_bytes,
withdrawalOperation.operation_identifier.index,
address
Expand Down
15 changes: 12 additions & 3 deletions cardano-rosetta-server/src/server/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,18 @@ export const PUBLIC_KEY_BYTES_LENGTH = 64;
export const POLICY_ID_LENGTH = 56;
export const ASSET_NAME_LENGTH = 64;

export enum StakeType {
STAKE = 'stake',
STAKE_TEST = 'stake_test'
export enum NonStakeAddressPrefix {
MAIN = 'addr',
TEST = 'addr_test'
}

export enum StakeAddressPrefix {
MAIN = 'stake',
TEST = 'stake_test'
}
export interface AddressPrefix {
MAIN: string;
TEST: string;
}

export enum OperationType {
Expand Down
2 changes: 1 addition & 1 deletion cardano-rosetta-server/src/server/utils/data-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const mapAmount = (
value: string,
symbol = ADA,
decimals = ADA_DECIMALS,
metadata?: any
metadata?: { policyId?: string }
): Components.Schemas.Amount => ({
value,
currency: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ describe(CONSTRUCTION_DERIVE_ENDPOINT, () => {
});
expect(response.statusCode).toEqual(StatusCodes.OK);
// Address generated locally with following command (using private keys attached to issue #198):
// eslint-disable-next-line max-len
// cat addr.prv | ./cardano-address key public | ./cardano-address address payment --network-tag 1 | ./cardano-address address delegation $(cat stake.prv | ./cardano-address key public)
expect(response.json().address).toEqual(
'addr1q9dhy809valxaer3nlvg2h5nudd62pxp6lu0cs36zczhfr98y6pah6lvppk8xft57nef6yexqh6rr204yemcmm3emhzsgg4fg0'
Expand Down Expand Up @@ -230,6 +231,7 @@ describe(CONSTRUCTION_DERIVE_ENDPOINT, () => {
})
});
expect(response.statusCode).toEqual(StatusCodes.OK);
// eslint-disable-next-line max-len
// https://cardanoscan.io/address/015b721de5677e6ee4719fd8855e93e35ba504c1d7f8fc423a1605748ca72683dbebec086c732574f4f29d132605f431a9f526778dee39ddc5
expect(response.json().address).toEqual('stake1uxnjdq7ma0kqsmrny460fu5azvnqtap3486jvaudacuam3g3yc4nu');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ describe(CONSTRUCTION_PAYLOADS_ENDPOINT, () => {
test('Should return an error when input operation has no coin change property', async () => {
const { operations, ...restPayload } = CONSTRUCTION_PAYLOADS_REQUEST;
const payload = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
operations: operations.map(({ coin_change, ...restOperation }) => ({
...restOperation
})),
Expand All @@ -177,6 +178,7 @@ describe(CONSTRUCTION_PAYLOADS_ENDPOINT, () => {
test('Should return an error when input operation has invalid coin identifier', async () => {
const { operations, ...restPayload } = CONSTRUCTION_PAYLOADS_REQUEST;
const payload = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
operations: operations.map(({ coin_change, ...restOperation }) => ({
coin_change: {
coin_identifier: {
Expand Down Expand Up @@ -510,7 +512,7 @@ describe(CONSTRUCTION_PAYLOADS_ENDPOINT, () => {
network_identifier,
operations: operations.map(({ metadata: opMetadata, ...rest }) => ({
metadata: opMetadata && {
staking_credential: { hex_bytes: opMetadata.staking_credential!.hex_bytes, curve_type: 'secp256k1' }
staking_credential: { hex_bytes: opMetadata.staking_credential?.hex_bytes, curve_type: 'secp256k1' }
},
...rest
})),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ describe(CONSTRUCTION_PREPROCESS_ENDPOINT, () => {
code: 4009,
details: {
message:
// eslint-disable-next-line max-len
'Token name 6e7574636f696e has already been added for policy b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a7 and will be overriden'
},
message: invalidOperationErrorMessage,
Expand Down
1 change: 1 addition & 0 deletions cardano-rosetta-server/test/e2e/environment-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Environment parser test', () => {
throw new Error(code?.toString());
});
expect(environmentParser).toThrowError(Error);
expect(mockExit).toHaveBeenCalledWith(1);
process.env.TOPOLOGY_FILE_PATH = previousPath;
});
test('Should throw an error if a field is expected to be a valid host but its not', () => {
Expand Down
3 changes: 2 additions & 1 deletion cardano-rosetta-server/test/e2e/utils/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const DEFAULT_PAGE_SIZE = 5;
* Setups a database connection that will fail if invoked.
* This is useful to test offline methods
*/
export const setupOfflineDatabase = () => {
export const setupOfflineDatabase = (): Pool => {
const poolMock = new Pool();
poolMock.query = jest.fn();
return poolMock;
Expand Down Expand Up @@ -104,6 +104,7 @@ export const testInvalidNetworkParameters = (
});
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const modifyMAOperation = (policyId?: string, symbol?: string) =>
mod(
1,
Expand Down

0 comments on commit 75e3ca4

Please sign in to comment.