import { isoly } from "isoly" import { isly } from "isly" import { Charge } from "./Transaction/Amount/Charge" export namespace fx { export interface Quote { id: string created: isoly.DateTime expires: isoly.DateTime account: { id: string; fx: { markup: number } } fixed: Quote.Fixed from: { amount: number; currency: isoly.Currency } to: { amount: number; currency: isoly.Currency } rate: { base: number; markup: number; effective: number } } export namespace Quote { export type Fixed = (typeof Fixed.values)[number] export namespace Fixed { export const values = ["from", "to"] as const export const type = isly.string(values) } export type Creatable = Creatable.From | Creatable.To export namespace Creatable { export interface From { from: { amount: number; currency: isoly.Currency } to: isoly.Currency } export namespace From { export const type = isly.object({ from: isly.object({ currency: isly.string(isoly.Currency.values), amount: isly.number() }), to: isly.string(isoly.Currency.values), }) } export interface To { from: isoly.Currency to: { amount: number; currency: isoly.Currency } } export namespace To { export const type = isly.object({ from: isly.string(isoly.Currency.values), to: isly.object({ currency: isly.string(isoly.Currency.values), amount: isly.number() }), }) } export const type = isly.union(From.type, To.type) } export function toCharge(quote: Quote): Charge | undefined { const withoutMarkup = isoly.Currency.round( isoly.Currency.divide(quote.to.currency, quote.to.amount, quote.rate.base), quote.from.currency ) const charge = isoly.Currency.subtract(quote.from.currency, quote.from.amount, withoutMarkup) return charge !== 0 ? { fx: { amount: charge, preset: "default", rate: quote.rate.markup } } : undefined } } export const type = isly.object({ id: isly.string(), created: isly.string(), expires: isly.string(), account: isly.object({ id: isly.string(), fx: isly.object({ markup: isly.number() }), }), fixed: Quote.Fixed.type, from: isly.object({ amount: isly.number(), currency: isly.string(isoly.Currency.values) }), to: isly.object({ amount: isly.number(), currency: isly.string(isoly.Currency.values) }), rate: isly.object({ base: isly.number(), markup: isly.number(), effective: isly.number() }), }) }