const USDT_DECIMALS = 6n;
const USDT_SCALE = 10n ** USDT_DECIMALS;
export function parseUsdt(input: string): bigint {
const s = input.trim();
if (s.length === 0) throw new Error("Empty amount");
if (s.startsWith("-")) throw new Error("Negative amount");
const parts = s.split(".");
if (parts.length > 2) throw new Error("Invalid amount");
const wholeStr = parts[0] ?? "";
const fracStr = parts[1] ?? "";
if (!/^\d+$/.test(wholeStr)) throw new Error("Invalid amount");
if (fracStr.length > 0 && !/^\d+$/.test(fracStr))
throw new Error("Invalid amount");
if (fracStr.length > 6) throw new Error("Too many decimals");
const whole = BigInt(wholeStr || "0");
const frac = BigInt((fracStr + "0".repeat(6)).slice(0, 6) || "0");
return whole * USDT_SCALE + frac;
}
export function formatUsdt(amount: bigint): string {
const neg = amount < 0n;
const v = neg ? -amount : amount;
const whole = v / USDT_SCALE;
const frac = v % USDT_SCALE;
const fracStr = frac.toString().padStart(6, "0").replace(/0+$/, "");
const out =
fracStr.length === 0 ? whole.toString() : `${whole.toString()}.${fracStr}`;
return neg ? `-${out}` : out;
}
export function usdtUnits(amount: string | number | bigint): bigint {
if (typeof amount === "bigint") return amount;
if (typeof amount === "number") {
if (!Number.isFinite(amount)) throw new Error("Invalid amount");
// Only accept integers here to avoid float money.
if (!Number.isInteger(amount)) throw new Error("Non-integer number amount");
return BigInt(amount);
}
// Human-readable decimal string like "10.5"
return parseUsdt(amount);
}