diff --git a/packages/react-components/package.json b/packages/react-components/package.json index 0133888..cb739a8 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -25,8 +25,8 @@ "prepack": "yarn build" }, "dependencies": { - "@agoric/rpc": "^0.9.0", - "@agoric/web-components": "^0.15.0", + "@agoric/rpc": "0.9.1-dev-02a116c.0+02a116c", + "@agoric/web-components": "0.15.1-dev-02a116c.0+02a116c", "@cosmos-kit/core": "2.8.9", "@cosmos-kit/react": "2.10.10", "@interchain-ui/react": "1.21.18", diff --git a/packages/react-components/src/lib/components/NoticeBanner.tsx b/packages/react-components/src/lib/components/NoticeBanner.tsx new file mode 100644 index 0000000..3c436b8 --- /dev/null +++ b/packages/react-components/src/lib/components/NoticeBanner.tsx @@ -0,0 +1,90 @@ +import { FiX } from 'react-icons/fi'; +import { GrAnnounce } from 'react-icons/gr'; +import { motion, AnimatePresence } from 'framer-motion'; +import { useState } from 'react'; +import { activeNotices, loadNetworkConfig } from '../utils/networkConfig'; +import { atom, useAtomValue } from 'jotai'; +import { loadable, atomWithStorage } from 'jotai/utils'; + +const networkConfigs = { + mainnet: { + label: 'Agoric Mainnet', + url: 'https://main.agoric.net/network-config', + }, + testnet: { + label: 'Agoric Testnet', + url: 'https://testnet.agoric.net/network-config', + }, + devnet: { + label: 'Agoric Devnet', + url: 'https://devnet.agoric.net/network-config', + }, + ollinet: { + label: 'Agoric Ollinet', + url: 'https://ollinet.agoric.net/network-config', + }, + emerynet: { + label: 'Agoric Emerynet', + url: 'https://emerynet.agoric.net/network-config', + }, + localhost: { + label: 'Local Network', + url: 'https://wallet.agoric.app/wallet/network-config', + }, +}; + +const networkConfigAtom = atomWithStorage( + 'agoric-network-config', + networkConfigs.mainnet +); + +const networkConfigPAtom = atom(async get => + loadNetworkConfig(get(networkConfigAtom).url) +); + +export const NoticeBanner = () => { + const [isDismissed, setIsDismissed] = useState(false); + const config = useAtomValue(loadable(networkConfigPAtom)); + const bannerContent = + config.state === 'hasData' && activeNotices(config.data).join(' • '); + const isVisible = + !isDismissed && bannerContent && bannerContent.trim().length; + + return ( + + {isVisible && ( + + + + + + +

{bannerContent}

+
+ + + +
+
+
+ )} +
+ ); +}; + diff --git a/packages/react-components/src/lib/components/index.ts b/packages/react-components/src/lib/components/index.ts index cd0cc84..6c6d722 100644 --- a/packages/react-components/src/lib/components/index.ts +++ b/packages/react-components/src/lib/components/index.ts @@ -3,3 +3,4 @@ export * from './NodeSelectorModal'; export * from './AmountInput'; export * from './NetworkDropdown'; export * from './OnboardIstModal'; +export * from './NoticeBanner'; diff --git a/packages/react-components/src/lib/utils/networkConfig.ts b/packages/react-components/src/lib/utils/networkConfig.ts new file mode 100644 index 0000000..ea2ff35 --- /dev/null +++ b/packages/react-components/src/lib/utils/networkConfig.ts @@ -0,0 +1,35 @@ +type NetworkNotice = { + start: string; + // In the future this might be optional to indicate that it's user-dismissable. + // In that case the client would need some persistent state, perhaps keyed by `message`. + end: string; + message: string; + }; + + export type MinimalNetworkConfig = { + rpcAddrs: string[]; + chainName: string; + notices?: NetworkNotice[]; + }; + + export const loadNetworkConfig = (url: string): Promise => + fetch(url).then(res => res.json()); + + export const activeNotices = ( + config: Pick, + ) => { + const { notices } = config; + if (!notices) return []; + + const now = Date.now(); + const active = notices.filter(n => { + const startD = Date.parse(n.start); + if (startD > now) { + return false; + } + const endD = Date.parse(n.end); + return startD < endD; + }); + return active.map(n => n.message); + }; + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2f4738f..a86cd33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -332,8 +332,8 @@ __metadata: version: 0.0.0-use.local resolution: "@agoric/react-components@workspace:packages/react-components" dependencies: - "@agoric/rpc": "npm:^0.9.0" - "@agoric/web-components": "npm:^0.15.0" + "@agoric/rpc": "npm:0.9.1-dev-02a116c.0+02a116c" + "@agoric/web-components": "npm:0.15.1-dev-02a116c.0+02a116c" "@babel/core": "npm:7.22.10" "@chain-registry/types": "npm:^0.25.7" "@cosmos-kit/core": "npm:2.8.9" @@ -384,6 +384,19 @@ __metadata: languageName: unknown linkType: soft +"@agoric/rpc@npm:0.9.1-dev-02a116c.0+02a116c": + version: 0.9.1-dev-02a116c.0 + resolution: "@agoric/rpc@npm:0.9.1-dev-02a116c.0" + dependencies: + "@endo/marshal": "npm:^0.8.9" + axios: "npm:^1.6.2" + axios-retry: "npm:^4.0.0" + vite: "npm:^4.3.2" + vite-tsconfig-paths: "npm:^4.2.0" + checksum: 10c0/d652c8e8591cd959cdff20ba4bb9461023dc54a6ba74cb30ac71c3bde85f55ada58c291f7a53a9d8fe74ebe85650878b9e222b7765a3d6b26174abfff2d968a3 + languageName: node + linkType: hard + "@agoric/rpc@npm:^0.9.0, @agoric/rpc@workspace:packages/rpc": version: 0.0.0-use.local resolution: "@agoric/rpc@workspace:packages/rpc" @@ -774,7 +787,25 @@ __metadata: languageName: node linkType: hard -"@agoric/web-components@npm:^0.15.0, @agoric/web-components@workspace:packages/web-components": +"@agoric/web-components@npm:0.15.1-dev-02a116c.0+02a116c": + version: 0.15.1-dev-02a116c.0 + resolution: "@agoric/web-components@npm:0.15.1-dev-02a116c.0" + dependencies: + "@agoric/assert": "npm:^0.6.0" + "@agoric/cache": "npm:^0.3.2" + "@agoric/casting": "npm:^0.4.3-u13.0" + "@agoric/cosmic-proto": "npm:0.3.0" + "@agoric/ertp": "npm:^0.16.3-dev-e2e36cc.0" + "@agoric/notifier": "npm:^0.6.3-dev-8c14632.0" + "@agoric/smart-wallet": "npm:^0.5.3" + "@endo/captp": "npm:^3.1.1" + "@endo/eventual-send": "npm:^0.17.5" + "@endo/marshal": "npm:^0.8.5" + checksum: 10c0/64c2687ee1dfb5cc3c4728026d951322754fd2a402cd630394728c0e09a7c7d48959839ed8ae290d7365e92144fa6750be60c47501bedee2faf0857cf8401f15 + languageName: node + linkType: hard + +"@agoric/web-components@workspace:packages/web-components": version: 0.0.0-use.local resolution: "@agoric/web-components@workspace:packages/web-components" dependencies: