Skip to content

Commit

Permalink
Merge branch 'main' into env/testnet
Browse files Browse the repository at this point in the history
  • Loading branch information
alanrsoares committed Nov 28, 2023
2 parents 72896e6 + 997fac8 commit 3956770
Show file tree
Hide file tree
Showing 8 changed files with 501 additions and 4 deletions.
1 change: 1 addition & 0 deletions apps/maestro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.48.2",
"react-jazzicon": "^1.0.4",
"react-markdown": "^9.0.1",
"react-spinners": "^0.13.8",
"redoc": "^2.1.3",
"superjson": "^2.2.1",
Expand Down
2 changes: 2 additions & 0 deletions apps/maestro/src/server/routers/_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { axelarscanRouter } from "./axelarscan";
import { erc20Router } from "./erc20";
import { gmpRouter } from "./gmp";
import { interchainTokenRouter } from "./interchainToken";
import { messagesRouter } from "./messages";
import { openaiRouter } from "./openai";

export const appRouter = router({
Expand All @@ -18,6 +19,7 @@ export const appRouter = router({
interchainToken: interchainTokenRouter,
auth: authRouter,
openai: openaiRouter,
messages: messagesRouter,
});

export type AppRouter = typeof appRouter;
8 changes: 8 additions & 0 deletions apps/maestro/src/server/routers/messages/getMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { publicProcedure } from "~/server/trpc";
import { messageSchema } from "~/services/db/kv";

export const getGlobalMessage = publicProcedure
.output(messageSchema.nullable())
.query(async ({ ctx }) => {
return await ctx.persistence.kv.getGlobalMessage();
});
8 changes: 8 additions & 0 deletions apps/maestro/src/server/routers/messages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { router } from "~/server/trpc";
import { getGlobalMessage } from "./getMessages";

export const messagesRouter = router({
getGlobalMessage,
});

export type MessagesRouter = typeof messagesRouter;
38 changes: 37 additions & 1 deletion apps/maestro/src/services/db/kv/MaestroKVClient.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,44 @@
import type { VercelKV } from "@vercel/kv";
import { z } from "zod";

export const COLLECTIONS = {
accounts: "accounts",
} as const;

export type AccountStatus = "enabled" | "limited" | "disabled";
/**
* Account status
* - enabled: account is enabled (default)
* - limited:{comma-separated-features}: account cannot use certain features
* - disabled: account is disabled (e.g. banned)
* - privileged: account is privileged (e.g. admin)
*/
export type AccountStatus =
| "enabled"
| `limited:${string}`
| "disabled"
| "privileged";

export const COLLECTION_KEYS = {
accountNonce: (accountAddress: `0x${string}`) =>
`${COLLECTIONS.accounts}:${accountAddress}:nonce` as const,
accountStatus: (accountAddress: `0x${string}`) =>
`${COLLECTIONS.accounts}:${accountAddress}:status` as const,
globalMessage: "messages:global" as const,
accountMessage: (accountAddress: `0x${string}`) =>
`messages:${accountAddress}` as const,
};

export const messageSchema = z.object({
kind: z.enum(["modal", "banner"]),
content: z.string(),
startTimestamp: z.string().optional(),
endTimestamp: z.string().optional(),
});

export type Message = z.infer<typeof messageSchema>;

export type MessageKind = Message["kind"];

export class BaseMaestroKVClient {
constructor(protected kv: VercelKV) {}
}
Expand Down Expand Up @@ -40,6 +66,16 @@ export default class MaestroKVClient extends BaseMaestroKVClient {
return status;
}

async getGlobalMessage() {
return await this.kv.hgetall<Message>(COLLECTION_KEYS.globalMessage);
}

async getAccountMessage(accountAddresss: `0x${string}`) {
return await this.kv.hgetall<Message>(
COLLECTION_KEYS.accountMessage(accountAddresss)
);
}

async setCached<T>(key: string, value: T, ttl = 3600) {
await this.kv.set(`cached:${key}`, value, { ex: ttl });
}
Expand Down
6 changes: 6 additions & 0 deletions apps/maestro/src/ui/layouts/MainLayout/MainLayout.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const DEFAULT_BANNERS_STATE = {
isTestnetBannerDismissed: false,
isHeroBannerDismissed: false,
isBetaBannerDismissed: false,
isGlobalBannerDismissed: false,
};

function useLayoutState() {
Expand Down Expand Up @@ -92,6 +93,11 @@ function useLayoutState() {
stateDraft.isBetaBannerDismissed = true;
});
},
dismissGlobalBanner: () => {
setPersistedState((stateDraft) => {
stateDraft.isGlobalBannerDismissed = true;
});
},
},
] as const;
}
Expand Down
25 changes: 25 additions & 0 deletions apps/maestro/src/ui/layouts/MainLayout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import {
LinkButton,
Modal,
ThemeProvider,
Tooltip,
useTheme,
XCircleIcon,
} from "@axelarjs/ui";
import { useEffect, type FC, type PropsWithChildren } from "react";
import Markdown from "react-markdown";
import Link from "next/link";

import sdkPkg from "@axelar-network/axelarjs-sdk/package.json";
Expand All @@ -22,6 +25,7 @@ import {
NEXT_PUBLIC_NETWORK_ENV,
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
} from "~/config/env";
import { trpc } from "~/lib/trpc";
import Appbar from "./Appbar";
import {
LayoutStateProvider,
Expand All @@ -34,6 +38,8 @@ const MainLayout: FC<PropsWithChildren> = ({ children }) => {
const theme = useTheme();
const { setThemeMode } = useWeb3ModalTheme();

const { data: globalMessage } = trpc.messages.getGlobalMessage.useQuery();

// sync theme with web3modal
useEffect(
() => setThemeMode(theme ?? "light"),
Expand All @@ -49,6 +55,7 @@ const MainLayout: FC<PropsWithChildren> = ({ children }) => {
isSignInModalOpen,
DrawerSideContent,
isTestnetBannerDismissed,
isGlobalBannerDismissed,
},
actions,
] = useLayoutStateContainer();
Expand All @@ -72,6 +79,24 @@ const MainLayout: FC<PropsWithChildren> = ({ children }) => {
}
)}
>
{globalMessage && !isGlobalBannerDismissed && (
<div
role="alert"
className="bg-warning text-warning-content sticky top-0 z-20 p-4 px-8 text-center"
>
<Markdown>{globalMessage.content}</Markdown>

<Tooltip
tip="Dismiss this messages"
className="text-error absolute right-4 top-4"
position="left"
>
<button onClick={actions.dismissGlobalBanner}>
<XCircleIcon />
</button>
</Tooltip>
</div>
)}
<Appbar />

{children}
Expand Down
Loading

0 comments on commit 3956770

Please sign in to comment.