Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into fix/template-security-…
Browse files Browse the repository at this point in the history
…hole
  • Loading branch information
mjlescano committed Dec 28, 2024
2 parents 95251d7 + b1e4c0b commit 7c70cb7
Show file tree
Hide file tree
Showing 60 changed files with 3,664 additions and 2,238 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export function getProvider(expectedAnvilInstance: ChildProcess): typeof anvilPr

export function createProviderProxy(provider: viem.Client): Promise<string> {
return new Promise((resolve) => {
const server = http.createServer(async (req, res) => {
const server = http.createServer(async (req: any, res: any) => {
res.setHeader('Content-Type', 'application/json');
const reqJson = JSON.parse(await streamToString(req));

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/util/on-keypress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ interface Controls {
export default function onKeypress(handleKeyPress: (evt: KeyboardEvent, controls: Controls) => void) {
return new Promise((resolve) => {
const rl = readline.createInterface({
input: process.stdin,
input: process.stdin as unknown as any,
escapeCodeTimeout: 50,
});

readline.emitKeypressEvents(process.stdin, rl);
readline.emitKeypressEvents(process.stdin as unknown as any, rl);
if (process.stdin.isTTY) {
process.stdin.setRawMode(true);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/registry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@typechain/ethers-v5": "10.1.0",
"@typechain/hardhat": "6.1.2",
"@types/mocha": "9.1.1",
"@types/node": "18.0.0",
"@types/node": "22.7.5",
"@usecannon/builder": "workspace:*",
"@usecannon/cli": "workspace:*",
"at-least-node": "^1.0.0",
Expand All @@ -40,6 +40,7 @@
"solidity-coverage": "0.7.21",
"ts-node": "10.8.1",
"typechain": "8.1.0",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"viem": "^2.21.15"
}
}
79 changes: 50 additions & 29 deletions packages/registry/scripts/list-packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,82 @@

/* eslint-disable no-console */

import 'dotenv/config';
import { DEFAULT_REGISTRY_ADDRESS } from '@usecannon/builder';
import CannonRegistryAbi from '@usecannon/builder/dist/src/abis/CannonRegistry';
import * as viem from 'viem';
import { mainnet, optimism } from 'viem/chains';

const { PROVIDER_URL } = process.env;
const { ETHEREUM_PROVIDER_URL, OPTIMISM_PROVIDER_URL } = process.env;

// Used only for getting additional publishers
const OPTIMISM_PROVIDER_URL = 'wss://optimism-rpc.publicnode.com';
const ETH_START_BLOCK = 19543644;
const OP_START_BLOCK = 119000000;

// const REGISTRY_DEPLOY_BLOCK = 16493645; // Contract deployment block
const REGISTRY_DEPLOY_BLOCK = 19543644; // First publish event emitted
if (typeof ETHEREUM_PROVIDER_URL !== 'string' || !ETHEREUM_PROVIDER_URL) {
throw new Error('Missing RPC Provider url to use. Needs to have archival node, e.g. Alchemy.');
}

if (typeof PROVIDER_URL !== 'string' || !PROVIDER_URL) {
if (typeof OPTIMISM_PROVIDER_URL !== 'string' || !OPTIMISM_PROVIDER_URL) {
throw new Error('Missing RPC Provider url to use. Needs to have archival node, e.g. Alchemy.');
}

const ownerOrPublisher = process.argv[2] ? viem.getAddress(process.argv[2]) : undefined;

async function main() {
const client = viem.createPublicClient({
const ethClient = viem.createPublicClient({
chain: mainnet,
transport: PROVIDER_URL?.startsWith('wss://') ? viem.webSocket(PROVIDER_URL) : viem.http(PROVIDER_URL),
transport: ETHEREUM_PROVIDER_URL!.startsWith('wss://')
? viem.webSocket(ETHEREUM_PROVIDER_URL)
: viem.http(ETHEREUM_PROVIDER_URL),
});

const opClient = viem.createPublicClient({
chain: optimism,
transport: OPTIMISM_PROVIDER_URL!.startsWith('wss://')
? viem.webSocket(OPTIMISM_PROVIDER_URL)
: viem.http(OPTIMISM_PROVIDER_URL),
});

const contract = viem.getContract({
const ethContract = viem.getContract({
address: DEFAULT_REGISTRY_ADDRESS,
abi: CannonRegistryAbi,
client,
client: ethClient,
});

const opContract = viem.getContract({
address: DEFAULT_REGISTRY_ADDRESS,
abi: CannonRegistryAbi,
client: viem.createPublicClient({
chain: optimism,
transport: OPTIMISM_PROVIDER_URL?.startsWith('wss://')
? viem.webSocket(OPTIMISM_PROVIDER_URL)
: viem.http(OPTIMISM_PROVIDER_URL),
}),
client: opClient,
});

const packageNames = await getPackageNames(client);
const [ethPackageNames, opPackageNames] = await Promise.all([
_getPackageNames(ethClient as viem.PublicClient, ETH_START_BLOCK),
_getPackageNames(opClient as viem.PublicClient, OP_START_BLOCK),
]);

const packageNames = new Set([...Array.from(ethPackageNames), ...Array.from(opPackageNames)]);

console.log('{');
for (const [i, [bytes32name, name]] of Object.entries(packageNames)) {
const owner = await contract.read.getPackageOwner([bytes32name]);
for (const [i, bytes32name] of packageNames.entries()) {
const name = viem.hexToString(bytes32name, { size: 32 });
const [owner, ethPublishers, opPublishers] = await Promise.all([
ethContract.read.getPackageOwner([bytes32name]).then((o: any) => viem.getAddress(o)),
ethContract.read.getAdditionalPublishers([bytes32name]).then((p: any) => p.map((p: any) => viem.getAddress(p))),
opContract.read.getAdditionalPublishers([bytes32name]).then((p: any) => p.map((p: any) => viem.getAddress(p))),
]);

const ethPublishers = await contract.read.getAdditionalPublishers([bytes32name]);
const opPublishers = await opContract.read.getAdditionalPublishers([bytes32name]);
const publishers = Array.from(new Set([...ethPublishers, ...opPublishers]));

const comma = Number.parseInt(i) === packageNames.length - 1 ? '' : ',';
if (ownerOrPublisher && !viem.isAddressEqual(owner, ownerOrPublisher) && !publishers.includes(ownerOrPublisher)) {
continue;
}

const comma = Number.parseInt(i) === packageNames.size - 1 ? '' : ',';
console.log(` "${name}": { "owner:": "${owner}", "publishers": ${JSON.stringify(publishers)} }${comma}`);
}
console.log('}');

process.exit(0);
}

const _packagePublishEvents = viem.parseAbi([
Expand Down Expand Up @@ -93,12 +115,12 @@ const _packagePublishEvents = viem.parseAbi([
* OwnerNominated (address newOwner)
*/

async function getPackageNames(client: viem.PublicClient) {
const names = new Set<[string, string]>();
async function _getPackageNames(client: viem.PublicClient, startBlock: number) {
const names = new Set<viem.Hex>();

const latestBlock = Number((await client.getBlockNumber()).toString());

for (const [fromBlock, toBlock] of batches(REGISTRY_DEPLOY_BLOCK, latestBlock, 50000)) {
for (const [fromBlock, toBlock] of _batches(startBlock, latestBlock, 50000)) {
const filter = await client.createEventFilter({
address: DEFAULT_REGISTRY_ADDRESS,
events: _packagePublishEvents,
Expand All @@ -112,15 +134,14 @@ async function getPackageNames(client: viem.PublicClient) {
console.error(log);
throw new Error('Invalid event');
}
const name = viem.hexToString(log.args.name, { size: 32 });
names.add([log.args.name, name]);
names.add(log.args.name);
}
}

return Array.from(names);
return names;
}

function* batches(start: number, end: number, batchSize: number) {
function* _batches(start: number, end: number, batchSize: number) {
const count = Math.ceil((end - start) / batchSize);
for (let i = 0; i < count; i++) {
const batchStart = start + batchSize * i;
Expand Down
1 change: 1 addition & 0 deletions packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"chakra-react-select": "^4.7.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "1.0.0",
"contentlayer": "^0.3.4",
"crypto-js": "^4.1.1",
"d3": "^7.8.5",
Expand Down
4 changes: 2 additions & 2 deletions packages/website/src/components/CodePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const EditorStyles = createGlobalStyle`
export const CodePreview: FC<ICodePreviewProps> = ({
code,
language,
height = '190px',
line,
height,
editorProps,
}) => {
const editorRef = useRef<any>(null);
Expand Down Expand Up @@ -62,7 +62,7 @@ export const CodePreview: FC<ICodePreviewProps> = ({
<>
<EditorStyles />
<Editor
height={height}
height={height || '100%'}
theme="vs-dark"
defaultLanguage={language || 'javascript'}
value={code}
Expand Down
15 changes: 15 additions & 0 deletions packages/website/src/components/MainContentLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { CustomSpinner } from '@/components/CustomSpinner';

/* {
hasSubheader,
}: {
hasSubheader?: boolean;
} */

export default function MainContentLoading() {
return (
<div className={'h-screen w-screen flex justify-center items-center'}>
<CustomSpinner />
</div>
);
}
2 changes: 1 addition & 1 deletion packages/website/src/components/PageLoading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CustomSpinner } from '@/components/CustomSpinner';

export default function PageLoading() {
return (
<div className="flex min-h-screen w-full flex-col items-center justify-center">
<div className="h-screen w-screen flex items-center justify-center">
<CustomSpinner />
</div>
);
Expand Down
119 changes: 119 additions & 0 deletions packages/website/src/components/layouts/SidebarLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use client';

import { ReactNode, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Menu } from 'lucide-react';
import {
Sidebar,
SidebarContent,
SidebarProvider,
SidebarTrigger,
useSidebar,
} from '@/components/ui/sidebar';
import { useRouter } from 'next/router';

const CloseOnLeave = () => {
const { setOpenMobile } = useSidebar();
const router = useRouter();
const fullPath = router.asPath;

useEffect(() => {
const handleHashChange = () => {
setOpenMobile(false);
};

// Detect initial load and hash change
handleHashChange();

// Add listener for hash changes
window.addEventListener('hashchange', handleHashChange);

// Cleanup the listener on unmount
return () => {
window.removeEventListener('hashchange', handleHashChange);
};
}, [setOpenMobile, fullPath]);

return null;
};

interface SidebarLayoutProps {
children: ReactNode;
sidebarContent?: ReactNode;
centered?: boolean;
hasSubheader?: boolean;
fixedFooter?: boolean;
contentHeight?: string;
sidebarTop?: string;
mainContentOverflowY?: 'auto' | 'visible';
borderlessSidebar?: boolean;
}

export function SidebarLayout({
children,
sidebarContent,
centered = true,
hasSubheader = false,
fixedFooter = true,
contentHeight,
sidebarTop,
mainContentOverflowY = 'auto',
borderlessSidebar = false,
}: SidebarLayoutProps) {
const headerVar = 'var(--header-height)';
const subheaderVar = hasSubheader ? 'var(--subheader-height)' : '0px';
const footerVar = fixedFooter ? 'var(--footer-height)' : '0px';

const sidebarStyles = {
top: sidebarTop ? sidebarTop : `calc(${headerVar} + ${subheaderVar})`,
height: contentHeight
? contentHeight
: `calc(100vh - ${headerVar} - ${subheaderVar} - ${footerVar})`,
};

return (
<SidebarProvider>
<CloseOnLeave />
{/* Mobile Sidebar Trigger - Fixed to left side */}
{sidebarContent && (
<main className="fixed left-0 top-1/2 -translate-y-1/2 z-[50] md:hidden bg-black border border-border border-l-0 rounded-r-lg [&:has([data-state=open])]:hidden">
<SidebarTrigger>
<Button
size="icon"
className="h-8 w-8 rounded-r-lg rounded-l-none border-l-0"
aria-label="Toggle sidebar"
>
<Menu className="h-4 w-4" />
</Button>
</SidebarTrigger>
</main>
)}

{sidebarContent && (
<Sidebar
style={sidebarStyles}
className={`z-[100] sticky w-[280px] md:w-[280px] shrink-0 overflow-y-auto ${
borderlessSidebar ? 'border-none' : 'border-r border-border'
}`}
>
<SidebarContent
/* className={centered ? 'py-6 lg:py-8 bg-black' : 'overflow-y-auto'} */
className={centered ? 'bg-black' : ''}
>
{sidebarContent}
</SidebarContent>
</Sidebar>
)}

{/* Main content */}
<main
className={`cannon-page-main-content overflow-y-${mainContentOverflowY} flex-1 h-[${
contentHeight ? contentHeight : 'auto'
}]`}
>
{/* container p-4 md:px-6 lg:px-8 ml-0 */}
<div className="h-full w-full">{children}</div>
</main>
</SidebarProvider>
);
}
Loading

0 comments on commit 7c70cb7

Please sign in to comment.