@stable-io/cctp-sdk-definitions
Version:
Definitions for the CCTP SDK
177 lines • 5.91 kB
JavaScript
// Copyright (c) 2025 Stable Technologies Inc
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
import { Rational, Amount } from "@stable-io/amount";
import { constMap } from "@stable-io/map-utils";
export const unit = (symbol, scale) => ({ symbol, scale });
export const oom = (order) => order < 0
? Rational.from(1n, 10n ** BigInt(-order))
: 10n ** BigInt(order);
export const Duration = {
name: "Duration",
units: [
unit("sec", 1),
unit("min", 60),
unit("hr", 60 * 60),
unit("day", 60 * 60 * 24),
unit("msec", oom(-3)),
unit("µsec", oom(-6)),
unit("nsec", oom(-9)),
],
//TODO more readable stringify
};
export const duration = Amount.ofKind(Duration);
export const Percentage = {
name: "Percentage",
human: "%",
units: [
unit("scalar", 1),
unit("%", oom(-2)),
unit("bp", oom(-4)),
],
};
export const percentage = Amount.ofKind(Percentage);
//for now, we don't make a distinction between usd and usdc
const Usd = {
name: "Usd",
units: [unit("$", 1n), unit("¢", oom(-2))],
human: "$",
atomic: "¢",
stringify: function (val) {
return val.ge(1)
? `$${val.eq(val.floor()) ? val.toString() : val.toFixed(2)}`
: `${val.mul(100).toString()}¢`;
},
};
export const usd = Amount.ofKind(Usd);
export const Usdc = {
name: "Usdc",
units: [unit("USDC", 1), unit("µUSDC", oom(-6))],
human: "USDC",
atomic: "µUSDC",
stringify: function (val) {
return val.ge(oom(-2))
? `${val.eq(val.floor()) ? val.toString() : val.toFixed(2)} USDC`
: `${val.div(oom(-6)).toString()} µUSDC`;
},
};
export const usdc = Amount.ofKind(Usdc);
export const isUsdc = (amount) => amount.kind.name === "Usdc";
//generic type to refer to arbitrary gas tokens where atomic amount is unknown
export const GenericGasToken = {
name: "GasToken",
units: [
unit("GasToken", 1n),
unit("mGasToken", oom(-3)),
unit("µGasToken", oom(-6)),
unit("nGasToken", oom(-9)),
unit("aGasToken", oom(-18)),
],
human: "GasToken",
};
export const genericGasToken = Amount.ofKind(GenericGasToken);
//generic type to refer to Evm gas tokens in particular, which always have 18 decimals
export const EvmGasToken = {
name: "EvmGasToken",
units: [
unit("EvmGasToken", 1n),
unit("nEvmGasToken", oom(-9)),
unit("aEvmGasToken", oom(-18)),
],
human: "EvmGasToken",
atomic: "aEvmGasToken",
};
export const evmGasToken = Amount.ofKind(EvmGasToken);
export const Eth = {
name: "Eth",
units: [unit("ETH", 1n), unit("Gwei", oom(-9)), unit("wei", oom(-18))],
human: "ETH",
atomic: "wei",
};
export const eth = Amount.ofKind(Eth);
export const Avax = {
name: "Avax",
units: [unit("AVAX", 1n), unit("nAVAX", oom(-9)), unit("aAVAX", oom(-18))],
human: "AVAX",
atomic: "aAVAX",
};
export const avax = Amount.ofKind(Avax);
export const Pol = {
name: "Pol",
units: [unit("POL", 1n), unit("Gwei", oom(-9)), unit("wei", oom(-18))],
human: "POL",
atomic: "wei",
};
export const pol = Amount.ofKind(Pol);
export const Sonic = {
name: "Sonic",
units: [unit("S", 1n), unit("Gwei", oom(-9)), unit("wei", oom(-18))],
human: "S",
atomic: "wei",
};
export const sonic = Amount.ofKind(Sonic);
export const Sol = {
name: "Sol",
units: [unit("SOL", 1n), unit("lamports", oom(-9))],
human: "SOL",
atomic: "lamports",
};
export const sol = Amount.ofKind(Sol);
export const Sui = {
name: "Sui",
units: [unit("SUI", 1n), unit("MIST", oom(-9))],
human: "SUI",
atomic: "MIST",
};
export const sui = Amount.ofKind(Sui);
export const Apt = {
name: "Apt",
units: [unit("APT", 1n), unit("Octas", oom(-8))],
human: "APT",
atomic: "Octas",
};
export const apt = Amount.ofKind(Apt);
//TODO introduce type aliasing like for domains to deal with large, ugly kind types
export const nameKindAmountEntries = [
["Duration", [Duration, duration]],
["Usdc", [Usdc, usdc]],
["GenericGasToken", [GenericGasToken, genericGasToken]],
["EvmGasToken", [EvmGasToken, evmGasToken]],
["Eth", [Eth, eth]],
["Avax", [Avax, avax]],
["Pol", [Pol, pol]],
["Sonic", [Sonic, sonic]],
["Sol", [Sol, sol]],
["Sui", [Sui, sui]],
["Apt", [Apt, apt]],
];
const kindAmountOf = constMap(nameKindAmountEntries);
//There's an explicit point to going through the name first instead of directly linking domains to
// their associated kinds and amounts, namely that it avoids duplication of types:
//tsc can automatically deduplicate union types for built-ins like string or number. However, for
// more complex types like kinds, this is not always possible. Therefore, a direct mapping for
// something like GasTokenOf<DomainsOf<"Evm">>, the inferred type would contain multiple duplicates
// of the Eth kind, which makes the already unwieldy type even more bothersome.
//Taking the intermediate step through the name allows collapsing the type to one instance per kind.
export const gasTokenNameEntries = [
["Ethereum", "Eth"],
["Avalanche", "Avax"],
["Optimism", "Eth"],
["Arbitrum", "Eth"],
["Noble", "Usdc"],
["Solana", "Sol"],
["Base", "Eth"],
["Polygon", "Pol"],
["Sui", "Sui"],
["Aptos", "Apt"],
["Unichain", "Eth"],
["Linea", "Eth"],
["Codex", "Eth"],
["Sonic", "Sonic"],
["Worldchain", "Eth"],
];
export const gasTokenNameOf = constMap(gasTokenNameEntries);
export const gasTokenKindOf = (d) => kindAmountOf(gasTokenNameOf(d))[0];
export const gasTokenOf = (d) => kindAmountOf(gasTokenNameOf(d))[1];
//# sourceMappingURL=kinds.js.map