mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-10 21:49:15 +00:00
Adapt GasPrice.fromString in @cosmjs/stargate and increase testing
This commit is contained in:
parent
b0b535ec95
commit
8f3260e1ac
@ -17,6 +17,8 @@ and this project adheres to
|
|||||||
work with Hermes ([#801]; thanks [@AlexBHarley]).
|
work with Hermes ([#801]; thanks [@AlexBHarley]).
|
||||||
- @cosmjs/launchpad: Adapt `GasPrice.fromString` denom pattern to Cosmos SDK
|
- @cosmjs/launchpad: Adapt `GasPrice.fromString` denom pattern to Cosmos SDK
|
||||||
0.39 rules: reduce denom length to 16 and allow digits in denom.
|
0.39 rules: reduce denom length to 16 and allow digits in denom.
|
||||||
|
- @cosmjs/stargate: Adapt `GasPrice.fromString` denom pattern to Cosmos SDK 0.42
|
||||||
|
rules: allow lengths up to 128, allow upper case letters and digits.
|
||||||
|
|
||||||
[#800]: https://github.com/cosmos/cosmjs/issues/800
|
[#800]: https://github.com/cosmos/cosmjs/issues/800
|
||||||
[#801]: https://github.com/cosmos/cosmjs/issues/801
|
[#801]: https://github.com/cosmos/cosmjs/issues/801
|
||||||
|
@ -14,12 +14,27 @@ describe("GasPrice", () => {
|
|||||||
|
|
||||||
describe("fromString", () => {
|
describe("fromString", () => {
|
||||||
it("works", () => {
|
it("works", () => {
|
||||||
const inputs = ["3.14", "3", "0.14"];
|
const inputs: Record<string, { amount: string; denom: string }> = {
|
||||||
inputs.forEach((input) => {
|
// Test amounts
|
||||||
const gasPrice = GasPrice.fromString(`${input}utest`);
|
"3.14utest": { amount: "3.14", denom: "utest" },
|
||||||
expect(gasPrice.amount.toString()).toEqual(input);
|
"3utest": { amount: "3", denom: "utest" },
|
||||||
expect(gasPrice.denom).toEqual("utest");
|
"0.14utest": { amount: "0.14", denom: "utest" },
|
||||||
});
|
// Test denoms
|
||||||
|
"0.14sht": { amount: "0.14", denom: "sht" },
|
||||||
|
"0.14testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest": {
|
||||||
|
amount: "0.14",
|
||||||
|
denom:
|
||||||
|
"testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
|
||||||
|
},
|
||||||
|
"0.14ucoin2": { amount: "0.14", denom: "ucoin2" },
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
"0.14FOOBAR": { amount: "0.14", denom: "FOOBAR" },
|
||||||
|
};
|
||||||
|
for (const [input, expected] of Object.entries(inputs)) {
|
||||||
|
const gasPrice = GasPrice.fromString(input);
|
||||||
|
expect(gasPrice.amount.toString()).withContext(`Input: ${input}`).toEqual(expected.amount);
|
||||||
|
expect(gasPrice.denom).withContext(`Input: ${input}`).toEqual(expected.denom);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("errors for invalid gas price", () => {
|
it("errors for invalid gas price", () => {
|
||||||
@ -30,17 +45,13 @@ describe("GasPrice", () => {
|
|||||||
expect(() => GasPrice.fromString("234")).toThrowError(/Invalid gas price string/i);
|
expect(() => GasPrice.fromString("234")).toThrowError(/Invalid gas price string/i);
|
||||||
expect(() => GasPrice.fromString("-234tkn")).toThrowError(/Invalid gas price string/i);
|
expect(() => GasPrice.fromString("-234tkn")).toThrowError(/Invalid gas price string/i);
|
||||||
// Checks details of <denom>
|
// Checks details of <denom>
|
||||||
expect(() => GasPrice.fromString("234t")).toThrowError(
|
expect(() => GasPrice.fromString("234t")).toThrowError(/denom must be between 3 and 128 characters/i);
|
||||||
/denomination must be between 3 and 127 characters/i,
|
expect(() => GasPrice.fromString("234tt")).toThrowError(/denom must be between 3 and 128 characters/i);
|
||||||
);
|
|
||||||
expect(() => GasPrice.fromString("234tt")).toThrowError(
|
|
||||||
/denomination must be between 3 and 127 characters/i,
|
|
||||||
);
|
|
||||||
expect(() =>
|
expect(() =>
|
||||||
GasPrice.fromString(
|
GasPrice.fromString(
|
||||||
"234tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
|
"234ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
|
||||||
),
|
),
|
||||||
).toThrowError(/denomination must be between 3 and 127 characters/i);
|
).toThrowError(/denom must be between 3 and 128 characters/i);
|
||||||
// Checks details of <amount>
|
// Checks details of <amount>
|
||||||
expect(() => GasPrice.fromString("3.utkn")).toThrowError(/Fractional part missing/i);
|
expect(() => GasPrice.fromString("3.utkn")).toThrowError(/Fractional part missing/i);
|
||||||
expect(() => GasPrice.fromString("..utkn")).toThrowError(/More than one separator found/i);
|
expect(() => GasPrice.fromString("..utkn")).toThrowError(/More than one separator found/i);
|
||||||
|
@ -7,6 +7,18 @@ import { coins } from "@cosmjs/proto-signing";
|
|||||||
*/
|
*/
|
||||||
export type FeeTable = Record<string, StdFee>;
|
export type FeeTable = Record<string, StdFee>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denom checker for the Cosmos SDK 0.42 denom pattern
|
||||||
|
* (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601).
|
||||||
|
*
|
||||||
|
* This is like a regexp but with helpful error messages.
|
||||||
|
*/
|
||||||
|
function checkDenom(denom: string): void {
|
||||||
|
if (denom.length < 3 || denom.length > 128) {
|
||||||
|
throw new Error("Denom must be between 3 and 128 characters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A gas price, i.e. the price of a single gas. This is typically a fraction of
|
* A gas price, i.e. the price of a single gas. This is typically a fraction of
|
||||||
* the smallest fee token unit, such as 0.012utoken.
|
* the smallest fee token unit, such as 0.012utoken.
|
||||||
@ -24,16 +36,20 @@ export class GasPrice {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a gas price formatted as `<amount><denom>`, e.g. `GasPrice.fromString("0.012utoken")`.
|
* Parses a gas price formatted as `<amount><denom>`, e.g. `GasPrice.fromString("0.012utoken")`.
|
||||||
|
*
|
||||||
|
* The denom must match the Cosmos SDK 0.42 pattern (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601).
|
||||||
|
* See `GasPrice` in @cosmjs/stargate for a more generic matcher.
|
||||||
|
*
|
||||||
|
* Separators are not yet supported.
|
||||||
*/
|
*/
|
||||||
public static fromString(gasPrice: string): GasPrice {
|
public static fromString(gasPrice: string): GasPrice {
|
||||||
const matchResult = gasPrice.match(/^([0-9.]+?)([a-z]+)$/);
|
// Use Decimal.fromUserInput and checkDenom for detailed checks and helpful error messages
|
||||||
|
const matchResult = gasPrice.match(/^([0-9.]+)([a-z][a-z0-9]*)$/i);
|
||||||
if (!matchResult) {
|
if (!matchResult) {
|
||||||
throw new Error("Invalid gas price string");
|
throw new Error("Invalid gas price string");
|
||||||
}
|
}
|
||||||
const [_, amount, denom] = matchResult;
|
const [_, amount, denom] = matchResult;
|
||||||
if (denom.length < 3 || denom.length > 127) {
|
checkDenom(denom);
|
||||||
throw new Error("Gas price denomination must be between 3 and 127 characters");
|
|
||||||
}
|
|
||||||
const fractionalDigits = 18;
|
const fractionalDigits = 18;
|
||||||
const decimalAmount = Decimal.fromUserInput(amount, fractionalDigits);
|
const decimalAmount = Decimal.fromUserInput(amount, fractionalDigits);
|
||||||
return new GasPrice(decimalAmount, denom);
|
return new GasPrice(decimalAmount, denom);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user