diff --git a/backend/src/common/stellar-network.ts b/backend/src/common/stellar-network.ts new file mode 100644 index 0000000..1222e53 --- /dev/null +++ b/backend/src/common/stellar-network.ts @@ -0,0 +1,35 @@ +/** + * Stellar network normalisation (#1495). + * + * `STELLAR_NETWORK` was interpreted as a passphrase in one place and as a + * network name in another. This maps names to passphrases and back so both + * stay consistent. + */ +export enum StellarNetwork { + PUBLIC = "PUBLIC", + TESTNET = "TESTNET", + FUTURENET = "FUTURENET", +} + +const PASSPHRASES: Record = { + [StellarNetwork.PUBLIC]: "Public Global Stellar Network ; September 2015", + [StellarNetwork.TESTNET]: "Test SDF Network ; September 2015", + [StellarNetwork.FUTURENET]: "Test SDF Future Network ; October 2022", +}; + +/** Resolve a network name to its passphrase. */ +export function passphraseFor(network: StellarNetwork): string { + return PASSPHRASES[network]; +} + +/** Resolve a passphrase or name back to a `StellarNetwork`, or `null`. */ +export function networkFrom(value: string): StellarNetwork | null { + const upper = value.trim().toUpperCase(); + if (upper in PASSPHRASES) { + return upper as StellarNetwork; + } + const match = ( + Object.entries(PASSPHRASES) as [StellarNetwork, string][] + ).find(([, passphrase]) => passphrase === value); + return match ? match[0] : null; +} diff --git a/backend/src/disputes/dispute-actions.constants.ts b/backend/src/disputes/dispute-actions.constants.ts new file mode 100644 index 0000000..03c3b69 --- /dev/null +++ b/backend/src/disputes/dispute-actions.constants.ts @@ -0,0 +1,31 @@ +/** + * Dispute route + resolution constants (#1492). + * + * Defines the reassign and withdraw (DELETE) routes, the admin listing path and + * the resolution states, so the new endpoints agree on a single vocabulary. + */ +export interface DisputeRoute { + method: "POST" | "DELETE" | "GET" | "PATCH"; + path: string; +} + +export const DISPUTE_ROUTES: Readonly> = + Object.freeze({ + reassign: { method: "POST", path: "disputes/:id/reassign" }, + withdraw: { method: "DELETE", path: "disputes/:id" }, + adminList: { method: "GET", path: "admin/disputes" }, + resolve: { method: "PATCH", path: "disputes/:id/resolve" }, + }); + +export type DisputeResolution = "UPHELD" | "REJECTED" | "WITHDRAWN"; + +export const DISPUTE_RESOLUTIONS: readonly DisputeResolution[] = [ + "UPHELD", + "REJECTED", + "WITHDRAWN", +]; + +/** Whether a resolution requires a non-empty note (#1492). */ +export function requiresResolutionNote(resolution: DisputeResolution): boolean { + return resolution !== "WITHDRAWN"; +}