Let faucet error when ticker field is found
This commit is contained in:
parent
1eb02553dd
commit
97f0949ee2
@ -23,9 +23,9 @@
|
||||
- @cosmjs/faucet: Environmental variable `FAUCET_FEE` renamed to
|
||||
`FAUCET_GAS_PRICE` and now only accepts one token. Environmental variable
|
||||
`FAUCET_GAS` renamed to `FAUCET_GAS_LIMIT`.
|
||||
- @cosmjs/faucet: `/credit` API now accepts either `denom` (base token) or as
|
||||
before `ticker` (unit token). Environmental variables specifying credit
|
||||
amounts now need to use uppercase denom.
|
||||
- @cosmjs/faucet: `/credit` API now expects `denom` (base token) instead of
|
||||
`ticker` (unit token). Environmental variables specifying credit amounts now
|
||||
need to use uppercase denom.
|
||||
- @cosmjs/launchpad: Rename `FeeTable` type to `CosmosFeeTable` and export a new
|
||||
more generic type `FeeTable`.
|
||||
- @cosmjs/launchpad: Add new class `GasPrice`, new helper type `GasLimits` and
|
||||
|
||||
@ -124,7 +124,7 @@ situation is different.
|
||||
```
|
||||
curl --header "Content-Type: application/json" \
|
||||
--request POST \
|
||||
--data '{"ticker":"ISA","address":"cosmos1yre6ac7qfgyfgvh58ph0rgw627rhw766y430qq"}' \
|
||||
--data '{"denom":"ucosm","address":"cosmos1yre6ac7qfgyfgvh58ph0rgw627rhw766y430qq"}' \
|
||||
http://localhost:8000/credit
|
||||
```
|
||||
|
||||
|
||||
@ -6,9 +6,16 @@ describe("RequestParser", () => {
|
||||
expect(RequestParser.parseCreditBody(body)).toEqual({ address: "abc", denom: "utkn" });
|
||||
});
|
||||
|
||||
it("can process valid credit request with ticker", () => {
|
||||
const body = { address: "abc", ticker: "TKN" };
|
||||
expect(RequestParser.parseCreditBody(body)).toEqual({ address: "abc", ticker: "TKN" });
|
||||
it("throws helpful error message when ticker is found", () => {
|
||||
const oldBody = { address: "abc", ticker: "TKN" };
|
||||
expect(() => RequestParser.parseCreditBody(oldBody)).toThrowError(
|
||||
/The 'ticker' field was removed in CosmJS 0.23. Please use 'denom' instead./i,
|
||||
);
|
||||
|
||||
const confusedBody = { address: "abc", ticker: "TKN", denom: "utkn" };
|
||||
expect(() => RequestParser.parseCreditBody(confusedBody)).toThrowError(
|
||||
/The 'ticker' field was removed in CosmJS 0.23. Please use 'denom' instead./i,
|
||||
);
|
||||
});
|
||||
|
||||
it("throws for invalid credit requests", () => {
|
||||
@ -26,44 +33,32 @@ describe("RequestParser", () => {
|
||||
|
||||
// address unset
|
||||
{
|
||||
const body = { ticker: "TKN" };
|
||||
const body = { denom: "utkn" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'address' must be a string/i);
|
||||
}
|
||||
|
||||
// address wrong type
|
||||
{
|
||||
const body = { address: true, ticker: "TKN" };
|
||||
const body = { address: true, denom: "utkn" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'address' must be a string/i);
|
||||
}
|
||||
|
||||
// address empty
|
||||
{
|
||||
const body = { address: "", ticker: "TKN" };
|
||||
const body = { address: "", denom: "utkn" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'address' must not be empty/i);
|
||||
}
|
||||
|
||||
// denom and ticker unset
|
||||
// denom unset
|
||||
{
|
||||
const body = { address: "abc" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(
|
||||
/Exactly one of properties 'denom' or 'ticker' must be a string/i,
|
||||
);
|
||||
}
|
||||
|
||||
// denom and ticker both set
|
||||
{
|
||||
const body = { address: "abc", denom: "ustake", ticker: "COSM" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(
|
||||
/Exactly one of properties 'denom' or 'ticker' must be a string/i,
|
||||
);
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'denom' must be a string/i);
|
||||
}
|
||||
|
||||
// denom wrong type
|
||||
{
|
||||
const body = { address: "abc", denom: true };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(
|
||||
/Exactly one of properties 'denom' or 'ticker' must be a string/i,
|
||||
);
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'denom' must be a string/i);
|
||||
}
|
||||
|
||||
// denom empty
|
||||
@ -71,19 +66,5 @@ describe("RequestParser", () => {
|
||||
const body = { address: "abc", denom: "" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'denom' must not be empty/i);
|
||||
}
|
||||
|
||||
// ticker wrong type
|
||||
{
|
||||
const body = { address: "abc", ticker: true };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(
|
||||
/Exactly one of properties 'denom' or 'ticker' must be a string/i,
|
||||
);
|
||||
}
|
||||
|
||||
// ticker empty
|
||||
{
|
||||
const body = { address: "abc", ticker: "" };
|
||||
expect(() => RequestParser.parseCreditBody(body)).toThrowError(/Property 'ticker' must not be empty/i);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,7 +2,7 @@ import { isNonNullObject } from "@cosmjs/utils";
|
||||
|
||||
import { HttpError } from "./httperror";
|
||||
|
||||
export interface CreditRequestBodyDataWithDenom {
|
||||
export interface CreditRequestBodyData {
|
||||
/** The base denomination */
|
||||
readonly denom: string;
|
||||
/** The recipient address */
|
||||
@ -16,14 +16,6 @@ export interface CreditRequestBodyDataWithTicker {
|
||||
readonly address: string;
|
||||
}
|
||||
|
||||
export type CreditRequestBodyData = CreditRequestBodyDataWithDenom | CreditRequestBodyDataWithTicker;
|
||||
|
||||
export function isCreditRequestBodyDataWithDenom(
|
||||
data: CreditRequestBodyData,
|
||||
): data is CreditRequestBodyDataWithDenom {
|
||||
return typeof (data as CreditRequestBodyDataWithDenom).denom === "string";
|
||||
}
|
||||
|
||||
export class RequestParser {
|
||||
public static parseCreditBody(body: unknown): CreditRequestBodyData {
|
||||
if (!isNonNullObject(body) || Array.isArray(body)) {
|
||||
@ -32,6 +24,10 @@ export class RequestParser {
|
||||
|
||||
const { address, denom, ticker } = body as any;
|
||||
|
||||
if (typeof ticker !== "undefined") {
|
||||
throw new HttpError(400, "The 'ticker' field was removed in CosmJS 0.23. Please use 'denom' instead.");
|
||||
}
|
||||
|
||||
if (typeof address !== "string") {
|
||||
throw new HttpError(400, "Property 'address' must be a string.");
|
||||
}
|
||||
@ -40,29 +36,17 @@ export class RequestParser {
|
||||
throw new HttpError(400, "Property 'address' must not be empty.");
|
||||
}
|
||||
|
||||
if (
|
||||
(typeof denom !== "string" && typeof ticker !== "string") ||
|
||||
(typeof denom === "string" && typeof ticker === "string")
|
||||
) {
|
||||
throw new HttpError(400, "Exactly one of properties 'denom' or 'ticker' must be a string");
|
||||
if (typeof denom !== "string") {
|
||||
throw new HttpError(400, "Property 'denom' must be a string.");
|
||||
}
|
||||
|
||||
if (typeof ticker === "string" && ticker.length === 0) {
|
||||
throw new HttpError(400, "Property 'ticker' must not be empty.");
|
||||
}
|
||||
|
||||
if (typeof denom === "string" && denom.length === 0) {
|
||||
if (denom.length === 0) {
|
||||
throw new HttpError(400, "Property 'denom' must not be empty.");
|
||||
}
|
||||
|
||||
return denom
|
||||
? {
|
||||
address: address,
|
||||
denom: denom,
|
||||
}
|
||||
: {
|
||||
address: address,
|
||||
ticker: ticker,
|
||||
};
|
||||
return {
|
||||
address: address,
|
||||
denom: denom,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { isValidAddress } from "../addresses";
|
||||
import * as constants from "../constants";
|
||||
import { Faucet } from "../faucet";
|
||||
import { HttpError } from "./httperror";
|
||||
import { isCreditRequestBodyDataWithDenom, RequestParser } from "./requestparser";
|
||||
import { RequestParser } from "./requestparser";
|
||||
|
||||
/** This will be passed 1:1 to the user */
|
||||
export interface ChainConstants {
|
||||
@ -59,23 +59,14 @@ export class Webserver {
|
||||
const requestBody = context.request.body;
|
||||
const creditBody = RequestParser.parseCreditBody(requestBody);
|
||||
|
||||
const { address } = creditBody;
|
||||
let denom: string | undefined;
|
||||
let ticker: string | undefined;
|
||||
if (isCreditRequestBodyDataWithDenom(creditBody)) {
|
||||
({ denom } = creditBody);
|
||||
} else {
|
||||
({ ticker } = creditBody);
|
||||
}
|
||||
const { address, denom } = creditBody;
|
||||
|
||||
if (!isValidAddress(address, constants.addressPrefix)) {
|
||||
throw new HttpError(400, "Address is not in the expected format for this chain.");
|
||||
}
|
||||
|
||||
const availableTokens = await faucet.availableTokens();
|
||||
const matchingToken = availableTokens.find(
|
||||
(token) => token.denom === denom || token.tickerSymbol === ticker,
|
||||
);
|
||||
const matchingToken = availableTokens.find((token) => token.denom === denom);
|
||||
if (matchingToken === undefined) {
|
||||
const tokens = JSON.stringify(availableTokens);
|
||||
throw new HttpError(422, `Token is not available. Available tokens are: ${tokens}`);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user