76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
/**
|
|
* rExchange applet definitions — Rate Card + Trade Status.
|
|
*/
|
|
|
|
import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types";
|
|
|
|
const rateCard: AppletDefinition = {
|
|
id: "rate-card",
|
|
label: "Rate Card",
|
|
icon: "💱",
|
|
accentColor: "#047857",
|
|
ports: [
|
|
{ name: "pair-in", type: "string", direction: "input" },
|
|
{ name: "rate-out", type: "number", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const pair = (snapshot.pair as string) || "—/—";
|
|
const rate = (snapshot.rate as number) || 0;
|
|
const change24h = (snapshot.change24h as number) || 0;
|
|
const changeColor = change24h >= 0 ? "#22c55e" : "#ef4444";
|
|
const arrow = change24h >= 0 ? "▲" : "▼";
|
|
|
|
return `
|
|
<div style="text-align:center">
|
|
<div style="font-size:11px;color:#94a3b8;margin-bottom:4px">${pair}</div>
|
|
<div style="font-size:22px;font-weight:700;color:#e2e8f0">${rate.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 6 })}</div>
|
|
<div style="font-size:11px;font-weight:500;color:${changeColor};margin-top:4px">${arrow} ${Math.abs(change24h).toFixed(2)}%</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "pair-in" && typeof value === "string") {
|
|
ctx.emitOutput("rate-out", 0);
|
|
}
|
|
},
|
|
};
|
|
|
|
const tradeStatus: AppletDefinition = {
|
|
id: "trade-status",
|
|
label: "Trade Status",
|
|
icon: "🔄",
|
|
accentColor: "#047857",
|
|
ports: [
|
|
{ name: "trade-in", type: "json", direction: "input" },
|
|
{ name: "status-out", type: "string", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const type = (snapshot.type as string) || "trade";
|
|
const amount = (snapshot.amount as number) || 0;
|
|
const asset = (snapshot.asset as string) || "—";
|
|
const status = (snapshot.status as string) || "pending";
|
|
const statusColor = status === "filled" ? "#22c55e" : status === "cancelled" ? "#ef4444" : "#f59e0b";
|
|
|
|
return `
|
|
<div>
|
|
<div style="display:flex;justify-content:space-between;margin-bottom:6px">
|
|
<span style="font-size:11px;color:#94a3b8;text-transform:uppercase">${type}</span>
|
|
<span style="font-size:10px;font-weight:500;color:${statusColor};text-transform:uppercase">${status}</span>
|
|
</div>
|
|
<div style="font-size:18px;font-weight:700;color:#e2e8f0;margin-bottom:2px">${amount.toLocaleString()}</div>
|
|
<div style="font-size:11px;color:#94a3b8">${asset}</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "trade-in" && value && typeof value === "object") {
|
|
const trade = value as Record<string, unknown>;
|
|
ctx.emitOutput("status-out", (trade.status as string) || "pending");
|
|
}
|
|
},
|
|
};
|
|
|
|
export const exchangeApplets: AppletDefinition[] = [rateCard, tradeStatus];
|