68 lines
2.6 KiB
TypeScript
68 lines
2.6 KiB
TypeScript
import { TokenConfiguration } from "@cosmwasm/bcp";
|
|
import { Account, Amount, TokenTicker } from "@iov/bcp";
|
|
import { Decimal, Uint53 } from "@iov/encoding";
|
|
|
|
/** Send `factor` times credit amount on refilling */
|
|
const defaultRefillFactor = 20;
|
|
|
|
/** refill when balance gets below `factor` times credit amount */
|
|
const defaultRefillThresholdFactor = 8;
|
|
|
|
export class TokenManager {
|
|
private readonly config: TokenConfiguration;
|
|
|
|
public constructor(config: TokenConfiguration) {
|
|
this.config = config;
|
|
}
|
|
|
|
/** The amount of tokens that will be sent to the user */
|
|
public creditAmount(token: TokenTicker, factor: Uint53 = new Uint53(1)): Amount {
|
|
const amountFromEnv = process.env[`FAUCET_CREDIT_AMOUNT_${token}`];
|
|
const amount = amountFromEnv ? Uint53.fromString(amountFromEnv).toNumber() : 10;
|
|
const value = new Uint53(amount * factor.toNumber());
|
|
|
|
const fractionalDigits = this.getFractionalDigits(token);
|
|
return {
|
|
quantity: value.toString() + "0".repeat(fractionalDigits),
|
|
fractionalDigits: fractionalDigits,
|
|
tokenTicker: token,
|
|
};
|
|
}
|
|
|
|
public refillAmount(token: TokenTicker): Amount {
|
|
const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_FACTOR || "0", 10) || undefined;
|
|
const factor = new Uint53(factorFromEnv || defaultRefillFactor);
|
|
return this.creditAmount(token, factor);
|
|
}
|
|
|
|
public refillThreshold(token: TokenTicker): Amount {
|
|
const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_THRESHOLD || "0", 10) || undefined;
|
|
const factor = new Uint53(factorFromEnv || defaultRefillThresholdFactor);
|
|
return this.creditAmount(token, factor);
|
|
}
|
|
|
|
/** true iff the distributor account needs a refill */
|
|
public needsRefill(account: Account, token: TokenTicker): boolean {
|
|
const balanceAmount = account.balance.find(b => b.tokenTicker === token);
|
|
|
|
const balance = balanceAmount
|
|
? Decimal.fromAtomics(balanceAmount.quantity, balanceAmount.fractionalDigits)
|
|
: Decimal.fromAtomics("0", 0);
|
|
|
|
const thresholdAmount = this.refillThreshold(token);
|
|
const threshold = Decimal.fromAtomics(thresholdAmount.quantity, thresholdAmount.fractionalDigits);
|
|
|
|
// TODO: perform < operation on Decimal type directly
|
|
// https://github.com/iov-one/iov-core/issues/1375
|
|
return balance.toFloatApproximation() < threshold.toFloatApproximation();
|
|
}
|
|
|
|
private getFractionalDigits(ticker: TokenTicker): number {
|
|
const match = [...this.config.bankTokens, ...(this.config.erc20Tokens || [])].find(
|
|
token => token.ticker === ticker,
|
|
);
|
|
if (!match) throw new Error(`No token found for ticker symbol: ${ticker}`);
|
|
return match.fractionalDigits;
|
|
}
|
|
}
|