Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions lib/src/coin/cronosCoin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import Big from 'big.js';
import ow from 'ow';

import { owCoin } from './ow.types';
import { InitConfigurations } from '../core/cro';
import { Network } from '../network/network';
import { Coin as CosmosCoin, coin as cosmosCoin, coins as cosmosCoins } from '../cosmos/coins';
import { ICoin } from './coin';

export const cronosCoin = function (config: InitConfigurations) {
return class CronosCoin implements ICoin {
/**
* Total supply in base unit represented as string
* @type {string}
* @static
* @memberof Coin
*/
public static TOTAL_SUPPLY_STRING = '100000000000000000000000000000';

public static TOTAL_SUPPLY = new CronosCoin(CronosCoin.TOTAL_SUPPLY_STRING);

/**
* Coin value stored in basic unit as Big
*/
public readonly baseAmount: Big;

public readonly network: Network;

/**
* Constructor to create a Coin
* @param {string} amount coins amount represented as string
* @throws {Error} amount or unit is invalid
* @returns {Coin}
*/
constructor(amount: string) {
ow(amount, 'amount', ow.string);

let coins: Big;
try {
coins = new Big(amount);
} catch (err) {
throw new TypeError(`Expected amount to be a base10 number represented as string, got \`${amount}\``);
}
this.network = config.network;
this.baseAmount = CronosCoin.parseBaseAmount(coins);
}

getNetwork(): Network {
return this.network;
}

/**
* Parse and validate a amount in base unit represented as Big
* @param {Big} baseAmount amount in base unit
* @returns {Big} the parsed coins in base unit
* @throws {TypeError} coins amount is invalid
*/
static parseBaseAmount(baseAmount: Big): Big {
if (baseAmount.cmp(baseAmount.toFixed(0)) !== 0) {
throw new TypeError(`Expected base amount to be an integer, got \`${baseAmount}\``);
}
if (baseAmount.lt(0)) {
throw new TypeError(`Expected base amount to be positive, got \`${baseAmount}\``);
}

if (baseAmount.gt(CronosCoin.TOTAL_SUPPLY_STRING)) {
throw new TypeError(`Expected base amount to be within total supply, got \`${baseAmount}\``);
}

return baseAmount;
}

/**
* Add two coins together and returns a new Coin
* @param {Coin} anotherCoin coins to add
* @returns {Coin}
* @throws {Error} adding two coins would exceed total supply
* @memberof Coin
*/
public add(anotherCoin: CronosCoin): CronosCoin {
ow(anotherCoin, owCoin());

const newAmount = this.baseAmount.add(anotherCoin.toBig());
if (newAmount.gt(CronosCoin.TOTAL_SUPPLY_STRING)) {
throw new Error('Adding two Coin together exceed total supply');
}
return new CronosCoin(newAmount.toString());
}

/**
* Subtract another Coin and returns a new Coin
* @param {Coin} anotherCoin coins to subtract
* @returns {Coin}
* @throws {Error} subtracting two coins would become negative
* @memberof Coin
*/
public sub(anotherCoin: CronosCoin): CronosCoin {
ow(anotherCoin, owCoin());

const newAmount = this.baseAmount.sub(anotherCoin.toBig());
if (newAmount.lt(0)) {
throw new Error('Subtracting the Coin results in negation Coin');
}
return new CronosCoin(newAmount.toString());
}

/**
* Returns the Big representation of the Coin in base unit
* @returns {Big}
* @memberof Coin
*/
public toBig(): Big {
return this.baseAmount;
}

/**
* Returns the Cosmos-compatible Coin object representation
* @returns {CosmosCoin}
* @memberof Coin
* */
public toCosmosCoin(): CosmosCoin {
return cosmosCoin(this.toString(), config.network.coin.baseDenom);
}

/**
* Returns the Cosmos-compatible Coin object representation
* @returns {CosmosCoin[]}
* @memberof Coin
* */
public toCosmosCoins(): CosmosCoin[] {
return cosmosCoins(this.toString(), config.network.coin.baseDenom);
}

/**
* Returns a string representation of the Coin.
* @returns {string}
* @throws {Error} unit is invalid
* @memberof Coin
*/
public toString(): string {
return this.baseAmount.toString();
}
};
};
2 changes: 1 addition & 1 deletion lib/src/coin/ow.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ow from 'ow';
import { owOptionalStrictObject, owStrictObject } from '../ow.types';
import { isCoin, Units } from './coin';
import { isCoin, Units } from './v2.coin/v2.coin';

export const owCoinUnit = ow.string.validate((val) => ({
validator: Object.values(Units).includes(val as any),
Expand Down
22 changes: 21 additions & 1 deletion lib/src/coin/v2.coin/v2.coin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Coin as CosmosCoin, coin as cosmosCoin, coins as cosmosCoins } from '..
export enum Units {
BASE = 'base',
CRO = 'cro',
CUSTOM = 'custom',
}

// Duck type check due to limitations of non exportable type for proper instance of checks
Expand Down Expand Up @@ -111,6 +112,8 @@ export const coinv2 = function (config: InitConfigurations) {
} else if (!['cro', 'tcro'].includes(denom.toLowerCase())) {
throw new Error('Provided Units and Denom do not belong to the same network.');
}
} else if (unit === Units.CUSTOM) {
this.baseAmount = CoinV2.parseCustomAmount(coins);
}
this.denom = denom || this.network.coin.baseDenom;
this.receivedAmount = coins;
Expand All @@ -122,7 +125,7 @@ export const coinv2 = function (config: InitConfigurations) {
* @param {string} denom chain compatible denom value
*/
public static fromCustomAmountDenom = (amount: string, denom: string): CoinV2 => {
return new CoinV2(amount, Units.BASE, denom);
return new CoinV2(amount, Units.CUSTOM, denom);
};

getNetwork(): Network {
Expand Down Expand Up @@ -173,6 +176,23 @@ export const coinv2 = function (config: InitConfigurations) {
return baseAmount;
}

/**
* Parse and validate a amount in base unit represented as Big
* @param {Big} customAmount amount in base unit
* @returns {Big} the parsed coins in base unit
* @throws {TypeError} coins amount is invalid
*/
static parseCustomAmount(customAmount: Big): Big {
if (customAmount.cmp(customAmount.toFixed(0)) !== 0) {
throw new TypeError(`Expected base amount to be an integer, got \`${customAmount}\``);
}
if (customAmount.lt(0)) {
throw new TypeError(`Expected base amount to be positive, got \`${customAmount}\``);
}

return customAmount;
}

/**
* Create a Coin from the base unit
* @param {string} baseValue coins value in base unit
Expand Down
144 changes: 144 additions & 0 deletions lib/src/core/cronos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import ow from 'ow';

import { croClient } from '../client/client';
import { Network } from '../network/network';
import { cronosCoin } from '../coin/cronosCoin';
import { owCroSDKInitParams } from './ow.types';
import { rawTransaction } from '../transaction/raw';
import { msgSend } from '../transaction/msg/bank/msgsend';
import { userAddress } from '../address/address';
import { msgDeposit } from '../transaction/msg/gov/MsgDeposit';
import { msgVote } from '../transaction/msg/gov/MsgVote';
import { msgSubmitProposal } from '../transaction/msg/gov/MsgSubmitProposal';
import { communityPoolSpendProposal } from '../transaction/msg/gov/proposal/CommunityPoolSpendProposal';
import { paramChangeProposal } from '../transaction/msg/gov/proposal/ParamChangeProposal';
import { cancelSoftwareUpgradeProposal } from '../transaction/msg/gov/proposal/CancelSoftwareUpgradeProposal';
import { softwareUpgradeProposal } from '../transaction/msg/gov/proposal/SoftwareUpgradeProposal';
import { textProposal } from '../transaction/msg/gov/proposal/TextProposal';
import { msgTransferIBC } from '../transaction/msg/ibc/applications/MsgTransfer';
import { msgCreateClientIBC } from '../transaction/msg/ibc/core/MsgCreateClient';
import { msgSendV2 } from '../transaction/msg/v2/bank/v2.msgsend';
import { msgDepositV2 } from '../transaction/msg/v2/gov/v2.MsgDeposit';
import { communityPoolSpendProposalV2 } from '../transaction/msg/v2/gov/proposal/v2.CommunityPoolSpendProposal';
import { msgSubmitProposalV2 } from '../transaction/msg/v2/gov/v2.MsgSubmitProposal';
import { msgUpdateClientIBC } from '../transaction/msg/ibc/core/MsgUpdateClient';
import { msgUpgradeClientIBC } from '../transaction/msg/ibc/core/MsgUpgradeClient';
import { msgSubmitMisbehaviourIBC } from '../transaction/msg/ibc/core/MsgSubmitMisbehaviour';
import { rawTransactionV2 } from '../transaction/v2.raw';
import { msgClientState } from '../transaction/msg/ibc/lightclients/ClientState';
import { msgConsensusState } from '../transaction/msg/ibc/lightclients/ConsensusState';
import { msgHeader } from '../transaction/msg/ibc/lightclients/Header';
import { MsgConnectionOpenConfirmIBC } from '../transaction/msg/ibc/core/connection/MsgConnectionOpenConfirm';
import { MsgConnectionOpenTryIBC } from '../transaction/msg/ibc/core/connection/MsgConnectionOpenTry';
import { InitConfigurations } from './cro';
import { coinv2 } from '../coin/v2.coin/v2.coin';

export const CronosSDK = function (configs: InitConfigurations) {
ow(configs, 'configs', owCroSDKInitParams);

return {
CroClient: croClient(configs),
CronosCoin: cronosCoin(configs),
RawTransaction: rawTransaction(configs),
Address: userAddress(configs),
gov: {
MsgDeposit: msgDeposit(configs),
MsgVote: msgVote(configs),
MsgSubmitProposal: msgSubmitProposal(configs),
proposal: {
CommunityPoolSpendProposal: communityPoolSpendProposal(configs),
ParamChangeProposal: paramChangeProposal(),
CancelSoftwareUpgradeProposal: cancelSoftwareUpgradeProposal(),
SoftwareUpgradeProposal: softwareUpgradeProposal(),
TextProposal: textProposal(),
},
},
bank: {
MsgSend: msgSend(configs),
},
ibc: {
MsgTransfer: msgTransferIBC(configs),
MsgCreateClient: msgCreateClientIBC(configs),
MsgUpdateClient: msgUpdateClientIBC(configs),
MsgUpgradeClient: msgUpgradeClientIBC(configs),
MsgSubmitMisbehaviour: msgSubmitMisbehaviourIBC(configs),
lightclient: {
ClientState: msgClientState(),
ConsensusState: msgConsensusState(),
Header: msgHeader(),
},
connection: {
MsgConnectionOpenConfirm: MsgConnectionOpenConfirmIBC(configs),
MsgConnectionOpenTry: MsgConnectionOpenTryIBC(configs),
},
},
v2: {
bank: {
MsgSendV2: msgSendV2(configs),
},
gov: {
MsgDepositV2: msgDepositV2(configs),
MsgSubmitProposalV2: msgSubmitProposalV2(configs),
proposal: {
CommunityPoolSpendProposalV2: communityPoolSpendProposalV2(configs),
},
},
RawTransactionV2: rawTransactionV2(configs),
CoinV2: coinv2(configs),
},
Options: configs,
};
};

export class CronosNetwork {
public static Mainnet: Network = {
defaultNodeUrl: 'https://rpc.cronos.org',
chainId: 'cronosmainnet_25-1',
addressPrefix: 'crc',
validatorAddressPrefix: 'crccncl',
validatorPubKeyPrefix: 'crccnclconspub',
coin: {
baseDenom: 'basecro',
croDenom: '',
},
bip44Path: {
coinType: 1,
account: 0,
},
rpcUrl: 'https://rpc.cronos.org',
};

public static Testnet: Network = {
defaultNodeUrl: 'https://rpc-t3.cronos.org',
chainId: 'cronostestnet_338-3',
addressPrefix: 'tcro',
validatorAddressPrefix: 'tcrocncl',
validatorPubKeyPrefix: 'tcrocnclconspub',
coin: {
baseDenom: 'basetcro',
croDenom: '',
},
bip44Path: {
coinType: 1,
account: 0,
},
rpcUrl: 'https://rpc-t3.cronos.org',
};

public static TestnetP11: Network = {
defaultNodeUrl: 'https://rpc-p11.cronos.org',
chainId: 'pioneereleventestnet_340-1',
addressPrefix: 'tcrc',
validatorAddressPrefix: 'tcrccncl',
validatorPubKeyPrefix: 'tcrccnclconspub',
coin: {
baseDenom: 'basetcro',
croDenom: '',
},
bip44Path: {
coinType: 1,
account: 0,
},
rpcUrl: 'https://rpc-p11.cronos.org:443',
};
}
5 changes: 4 additions & 1 deletion lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { HDKey } from './hdkey/hdkey';
import { Secp256k1KeyPair } from './keypair/secp256k1';
import utils from './utils';
import { CroNetwork, CroSDK } from './core/cro';
import { Units } from './coin/coin';
import { CronosNetwork, CronosSDK } from './core/cronos';
import { Units } from './coin/v2.coin/v2.coin';
import { TxDecoder } from './utils/txDecoder';

// The maximum number of decimal places of the results of operations involving division
Expand All @@ -15,7 +16,9 @@ const _ = {
HDKey,
Secp256k1KeyPair,
CroSDK,
CronosSDK,
CroNetwork,
CronosNetwork,
Units,
TxDecoder,
};
Expand Down