mempool/unfurler/src/routes.ts
2022-09-29 15:29:59 +00:00

150 lines
3.2 KiB
TypeScript

interface Match {
render: boolean;
title: string;
fallbackImg: string;
staticImg?: string;
networkMode: string;
}
const routes = {
block: {
render: true,
params: 1,
getTitle(path) {
return `Block: ${path[0]}`;
}
},
address: {
render: true,
params: 1,
getTitle(path) {
return `Address: ${path[0]}`;
}
},
tx: {
render: true,
params: 1,
getTitle(path) {
return `Transaction: ${path[0]}`;
}
},
lightning: {
title: "Lightning",
fallbackImg: '/resources/previews/lightning.png',
routes: {
node: {
render: true,
params: 1,
getTitle(path) {
return `Lightning Node: ${path[0]}`;
}
},
channel: {
render: true,
params: 1,
getTitle(path) {
return `Lightning Channel: ${path[0]}`;
}
},
nodes: {
routes: {
isp: {
render: true,
params: 1,
getTitle(path) {
return `Lightning ISP: ${path[0]}`;
}
}
}
},
group: {
render: true,
params: 1,
getTitle(path) {
return `Lightning Node Group: ${path[0]}`;
}
}
}
},
mining: {
title: "Mining",
fallbackImg: '/resources/previews/mining.png',
routes: {
pool: {
render: true,
params: 1,
getTitle(path) {
return `Mining Pool: ${path[0]}`;
}
}
}
}
};
const networks = {
bitcoin: {
fallbackImg: '/resources/previews/dashboard.png',
routes: {
...routes // all routes supported
}
},
liquid: {
fallbackImg: '/resources/liquid/liquid-network-preview.png',
routes: { // only block, address & tx routes supported
block: routes.block,
address: routes.address,
tx: routes.tx
}
},
bisq: {
fallbackImg: '/resources/bisq/bisq-markets-preview.png',
routes: {} // no routes supported
}
};
export function matchRoute(network: string, path: string): Match {
const match: Match = {
render: false,
title: '',
fallbackImg: '',
networkMode: 'mainnet'
}
const parts = path.slice(1).split('/').filter(p => p.length);
if (parts[0] === 'preview') {
parts.shift();
}
if (['testnet', 'signet'].includes(parts[0])) {
match.networkMode = parts.shift() || 'mainnet';
}
let route = networks[network] || networks.bitcoin;
match.fallbackImg = route.fallbackImg;
// traverse the route tree until we run out of route or tree, or hit a renderable match
while (!route.render && route.routes && parts.length && route.routes[parts[0]]) {
route = route.routes[parts[0]];
parts.shift();
if (route.fallbackImg) {
match.fallbackImg = route.fallbackImg;
}
}
// enough route parts left for title & rendering
if (route.render && parts.length >= route.params) {
match.render = true;
}
// only use set a static image for exact matches
if (!parts.length && route.staticImg) {
match.staticImg = route.staticImg;
}
// apply the title function if present
if (route.getTitle && typeof route.getTitle === 'function') {
match.title = route.getTitle(parts);
} else {
match.title = route.title;
}
return match;
}