Skip to content

chore(release): merge dev into main #1791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Aug 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
209e105
fix(website): initialize only once Tooltip providers (#1771)
nicosampler Apr 25, 2025
03a6e27
refactor(website): Interact-refactor-2 (#1758)
nicosampler Apr 27, 2025
97805bf
Merge remote-tracking branch 'origin/main' into dev
Apr 28, 2025
915d095
fix(website): reset default per section (#1774)
AkihisaY May 5, 2025
15f8a5a
Merge remote-tracking branch 'origin/main' into dev
May 15, 2025
81275a2
Merge remote-tracking branch 'origin/main' into dev
May 18, 2025
c85b971
Merge remote-tracking branch 'origin/main' into dev
May 18, 2025
12dba93
prevent browser from pushing path to history when (#1777)
dbeal-eth May 20, 2025
c77d2a3
fix(builder): event information not parsed properly for factory (#1779)
dbeal-eth May 20, 2025
ff67f5b
Fix/website/CAN-744 (#1782)
nicosampler May 20, 2025
96ffe27
fix(builder): regression ipfs hash cannon package url not specifyable…
dbeal-eth May 21, 2025
367bd69
fix(website): siderbar sticky (#1773)
AkihisaY May 21, 2025
89d3934
add field to get current deployer from inside cannon context (#1780)
dbeal-eth May 21, 2025
5ce910b
Merge remote-tracking branch 'origin/main' into dev
May 21, 2025
1956cfe
Release v2.23.0 (#1786)
dbeal-eth May 21, 2025
c17227c
Interact-refactor-3 (#1768)
nicosampler May 27, 2025
73c95c6
fix: CAN-747 (#1788)
nicosampler May 30, 2025
475ce39
update pnpm
mjlescano May 30, 2025
fd092f5
fix(website): CAN-748 (#1792)
nicosampler Jun 5, 2025
a7db96f
fix(website): fix scroll bug (#1789)
AkihisaY Jun 6, 2025
a87d62f
hotfix(website): merge main into dev (#1796)
nicosampler Jun 6, 2025
13a7964
remove @skip test
mjlescano Jun 6, 2025
ee5f864
feat(registry): Add registry subscription model (#1636)
mjlescano Jun 8, 2025
92b1a51
chore(ci): backmerge main → dev (#1801)
github-actions[bot] Jun 9, 2025
4f0def4
feat: registry immutability (#1803)
dbeal-eth Jun 16, 2025
73904e6
fix(registry): prior release issues (#1805)
dbeal-eth Jun 17, 2025
8d4ed20
fix initial address
dbeal-eth Jun 23, 2025
6b339bf
fix(website): adjust icon size and space (#1808)
AkihisaY Jun 27, 2025
874277f
feat(cli): generate etches (#1809)
dbeal-eth Jun 27, 2025
51f831c
fix(builder): script no overwrite (#1799)
dbeal-eth Jun 27, 2025
3a7a7a8
fix(cli): etherscan verify (#1814)
dbeal-eth Jul 1, 2025
c966944
fix(cli): add missing foundry-portable (#1813)
dbeal-eth Jul 1, 2025
99f3b3b
feat(website): update docs (#1810)
dbeal-eth Jul 2, 2025
9055179
Merge remote-tracking branch 'origin/main' into dev
dbeal-eth Jul 2, 2025
6c0e9e4
bump version to where it should be
dbeal-eth Jul 2, 2025
b125cef
fix(website): adjust clipboard icon
AkihisaY Jul 8, 2025
f0131f0
fix copy icon
AkihisaY Jul 9, 2025
ed9d992
run pnpm i
AkihisaY Jul 9, 2025
32d6977
fix(website): adjust clipboard icon (#1818)
AkihisaY Jul 10, 2025
022b4e4
feat(indexer): integrate 4byte directory (#1790)
dbeal-eth Aug 1, 2025
6fc3ea6
fix(website): copy and import settings (#1822)
AkihisaY Aug 6, 2025
d98c554
fix(website): add custom rpc alert (#1819)
AkihisaY Aug 6, 2025
bf0a9ea
feat(website): New Address Page (#1807)
AkihisaY Aug 7, 2025
17828f3
feat(website): setup default otterscan url (#1828)
AkihisaY Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Cannon is a DevOps tool for EVM chains. It's a tool for testing, deploying, and publishing of smart contracts.

This is the monorepo for Cannon. If you're just interested in using the project, [visit the website](https://usecannon.com).
This is the monorepo for Cannon. If you're just interested in using the project, [visit the website](https://usecannon.com/learn).

**⚠️ Cannon is under active development. While the interface and functionality are generally stable, use the tool with caution when conducting high-risk deployments.**

Expand Down
8 changes: 4 additions & 4 deletions examples/sample-hardhat-project/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
"@typechain/ethers-v5": "^7.2.0",
"@typechain/hardhat": "^2.3.1",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.1.0",
"@types/node": "^16.0.0",
"@types/mocha": "^10.0.10",
"@types/node": "^22.14.0",
"chai": "^4.3.6",
"dotenv": "^10.0.0",
"ethers": "^5.7.1",
"hardhat-cannon": "workspace:*",
"hardhat": "^2.13.1",
"hardhat-gas-reporter": "^1.0.9",
"solidity-coverage": "^0.8.5",
"ts-node": "^10.5.0",
"ts-node": "^10.9.2",
"typechain": "^5.2.0",
"typescript": "^5.3.3"
"typescript": "^5.8.3"
}
}
2 changes: 1 addition & 1 deletion examples/sample-hardhat-toolbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"hardhat": "^2.19.2",
"hardhat-cannon": "workspace:*",
"viem": "^2.21.15"
"viem": "^2.25.1"
}
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@
"release-please": "^15.12.0",
"solhint": "^3.4.1",
"solhint-plugin-prettier": "^0.0.5",
"ts-node": "^10.9.1",
"typescript": "^5.3.3"
"syncpack": "^13.0.4",
"ts-node": "^10.9.2",
"typescript": "^5.8.3"
},
"license": "GNU GPL V3.0",
"dependencies": {
Expand Down
6 changes: 3 additions & 3 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
"helmet": "^7.1.0",
"prom-client": "^15.1.2",
"redis": "^4.6.13",
"viem": "^2.23.1"
"viem": "^2.25.1"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/node": "^20.12.7",
"@types/node": "^22.14.0",
"ts-node-dev": "^2.0.0",
"typescript": "^5.4.5"
"typescript": "^5.8.3"
}
}
45 changes: 28 additions & 17 deletions packages/api/src/db/transformers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PackageReference } from '@usecannon/builder';
import * as viem from 'viem';
import { isChainId, isContractName, isFunctionSelector } from '../helpers';
import { ApiFunction, ApiPackage, IpfsUrl, RedisDocument, RedisFunction, RedisPackage, RedisTag } from '../types';
import { ApiSelectorResult, ApiPackage, IpfsUrl, RedisDocument, RedisFunction, RedisPackage, RedisTag } from '../types';

export function findPackageByTag(documents: { value: RedisDocument }[], tag: RedisTag) {
const result = documents.find(
Expand Down Expand Up @@ -53,21 +53,32 @@ export function transformFunction(value: RedisFunction) {
if (typeof value.name !== 'string' || !value.name) return;
if (!isFunctionSelector(value.selector)) return;
if (typeof value.timestamp !== 'string' || !value.timestamp) return;
if (!PackageReference.isValid(value.package)) return;
if (!isChainId(value.chainId)) return;
if (!viem.isAddress(value.address)) return;
if (!isContractName(value.contractName)) return;
if (value.package && !PackageReference.isValid(value.package)) return;
if (value.chainId && !isChainId(value.chainId)) return;
if (value.address && !viem.isAddress(value.address)) return;
if (value.contractName && !isContractName(value.contractName)) return;

const ref = new PackageReference(value.package);
return {
type: 'function',
name: value.name,
selector: value.selector,
contractName: value.contractName,
chainId: Number.parseInt(value.chainId),
address: viem.getAddress(value.address),
packageName: ref.name,
preset: ref.preset,
version: ref.version,
} satisfies ApiFunction;
if (value.package) {
const ref = new PackageReference(value.package);
return {
type: 'function',
name: value.name,
selector: value.selector,
contractName: value.contractName,
chainId: Number.parseInt(value.chainId),
address: viem.getAddress(value.address),
packageName: ref.name,
preset: ref.preset,
version: ref.version,
} satisfies ApiSelectorResult;
} else {
return {
type: 'function',
name: value.name,
selector: value.selector,
contractName: value.contractName,
chainId: value.chainId ? Number.parseInt(value.chainId) : undefined,
address: value.address ? viem.getAddress(value.address) : undefined,
} satisfies ApiSelectorResult;
}
}
1 change: 1 addition & 0 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ app.use(
})
);

app.use(routes.selector);
app.use(routes.metrics);
app.use(routes.chains);
app.use(routes.packages);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import * as viem from 'viem';
import * as keys from '../db/keys';
import { transformFunction } from '../db/transformers';
import { useRedis } from '../redis';
import { ApiFunction, RedisFunction } from '../types';
import { ApiSelectorResult, RedisFunction } from '../types';

async function _queryAbiFunctions(params: { query: string; limit?: number }) {
async function _querySelectors(params: { query: string; limit?: number }) {
const redis = await useRedis();

const results = (await redis.ft.search(keys.RKEY_ABI_SEARCHABLE, params.query)) as unknown as {
const results = (await redis.ft.search(keys.RKEY_ABI_SEARCHABLE, params.query, {
SORTBY: { BY: 'timestamp', DIRECTION: 'ASC' },
})) as unknown as {
total: number;
documents: { value: RedisFunction }[];
};

const data: ApiFunction[] = [];
const data: ApiSelectorResult[] = [];

for (const { value } of results.documents) {
const parsed = transformFunction(value);
Expand All @@ -37,16 +39,20 @@ async function _queryAbiFunctions(params: { query: string; limit?: number }) {
data,
} satisfies {
total: number;
data: ApiFunction[];
data: ApiSelectorResult[];
};
}

export async function findFunctionsBySelector(params: { selector: viem.Hex; limit: number }) {
return _queryAbiFunctions({ query: `@selector:{${params.selector}}`, limit: params.limit });
export async function findSelector(params: { selector: viem.Hex; type?: 'function' | 'event' | 'error'; limit: number }) {
let query = `@selector:{${params.selector}}`;
if (params.type) {
query += `,@type:{${params.type}}`;
}
return _querySelectors({ query, limit: params.limit });
}

export async function searchFunctions(params: { query: string; limit: number }) {
return _queryAbiFunctions({
return _querySelectors({
query: `@name:'${params.query}' | @name:${params.query}* | @name:*${params.query}*`,
limit: params.limit,
});
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { metrics } from './metrics';
export { chains } from './chains';
export { packages } from './packages';
export { search } from './search';
export { selector } from './selector';
6 changes: 3 additions & 3 deletions packages/api/src/routes/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
parseTextQuery,
} from '../helpers';
import { findContractsByAddress, searchContracts } from '../queries/contracts';
import { findFunctionsBySelector, searchFunctions } from '../queries/functions';
import { findSelector, searchFunctions } from '../queries/selectors';
import { findPackagesByPartialRef, searchPackages } from '../queries/packages';
import { ApiDocument } from '../types';

Expand Down Expand Up @@ -76,15 +76,15 @@ search.get('/search', async (req, res) => {
} else if (response.isHex) {
if (query.length >= 10) {
const selector = query.slice(0, 10);
const result = await findFunctionsBySelector({
const result = await findSelector({
selector: selector as viem.Hex,
limit: 20,
});

_pushResults(response, result);
}
} else if (response.isFunctionSelector) {
const result = await findFunctionsBySelector({
const result = await findSelector({
selector: query as viem.Hex,
limit: 20,
});
Expand Down
34 changes: 34 additions & 0 deletions packages/api/src/routes/selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as viem from 'viem';
import { Request, Response, Router } from 'express';
import { BadRequestError } from '../errors';
import { findSelector } from '../queries/selectors';
import { ApiSelectorResult } from '../types';

const selector: Router = Router();

selector.get('/selector', async (req: Request, res: Response) => {
if (typeof req.query.q !== 'string') {
throw new BadRequestError('Query selector not specified');
}
const selectors = req.query.q.split(',') as viem.Hex[];
const type = req.query.type as 'function' | 'event' | 'error';

const results: Record<string, ApiSelectorResult[]> = {};

for (const selector of selectors) {
results[selector] = (
await findSelector({
selector,
type,
limit: 10,
})
).data;
}

res.json({
status: 200,
results,
});
});

export { selector };
18 changes: 9 additions & 9 deletions packages/api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,19 @@ export interface ApiContract {
version: string;
}

export interface ApiFunction {
type: 'function';
export interface ApiSelectorResult {
type: 'function' | 'event' | 'error';
name: string;
selector: string;
contractName: string;
chainId: number;
address: Address;
packageName: string;
preset: string;
version: string;
contractName?: string;
chainId?: number;
address?: Address;
packageName?: string;
preset?: string;
version?: string;
}

export type ApiDocument = ApiNamespace | ApiPackage | ApiContract | ApiFunction;
export type ApiDocument = ApiNamespace | ApiPackage | ApiContract | ApiSelectorResult;

type ExtractType<T> = T extends { type: infer U } ? U : never;
export type ApiDocumentType = ExtractType<ApiDocument>;
6 changes: 3 additions & 3 deletions packages/builder/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@usecannon/builder",
"version": "2.24.0",
"version": "2.23.0",
"description": "Assembles cannonfile.toml manifests into cannon packages.",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand Down Expand Up @@ -49,7 +49,7 @@
"@usecannon/router": "^4.1.3",
"@usecannon/web-solc": "0.5.1",
"acorn": "^8.14.1",
"axios": "^1.8.4",
"axios": "^1.9.0",
"axios-retry": "^4.5.0",
"buffer": "^6.0.3",
"chalk": "^4.1.2",
Expand All @@ -63,7 +63,7 @@
"rfdc": "^1.4.1",
"ses": "^1.12.0",
"typestub-ipfs-only-hash": "^4.0.0",
"viem": "^2.25.0",
"viem": "^2.25.1",
"zod": "^3.24.2"
},
"engines": {
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@usecannon/cli",
"version": "2.24.0",
"version": "2.23.0",
"description": "Utility for instantly loading cannon packages in standalone contexts",
"main": "dist/src/index.js",
"scripts": {
Expand Down Expand Up @@ -50,7 +50,7 @@
"@types/prompts": "^2.4.9",
"@types/semver": "^7.7.0",
"@types/sinon": "^17.0.4",
"axios": "^1.8.4",
"axios": "^1.9.0",
"jest": "^29.7.0",
"mock-fs": "^5.5.0",
"tmp-promise": "^3.0.3",
Expand Down Expand Up @@ -80,7 +80,7 @@
"table": "^6.9.0",
"tildify": "3.0.0",
"untildify": "^4.0.0",
"viem": "^2.25.0",
"viem": "^2.25.1",
"znv": "^0.4.0",
"zod": "^3.24.2"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/commands/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export async function verify(packageRef: string, cliSettings: CliSettings, chain
getMainLoader(cliSettings)
);

const etherscanApi = cliSettings.etherscanApiUrl || 'https://api.etherscan.io/api';
const etherscanApi = cliSettings.etherscanApiUrl || 'https://api.etherscan.io/v2/api';

if (!etherscanApi) {
throw new Error(
Expand Down Expand Up @@ -100,7 +100,7 @@ export async function verify(packageRef: string, cliSettings: CliSettings, chain
continue;
}

if (await isVerified(contractInfo.address, etherscanApi, cliSettings.etherscanApiKey, chainId)) {
if (await isVerified(contractInfo.address, chainId, etherscanApi, cliSettings.etherscanApiKey)) {
log(`✅ ${c}: Contract source code already verified`);
await sleep(500);
continue;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/util/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export type EtherscanGetSourceCodeResponse = EtherscanGetSourceCodeNotOkResponse
* @returns True if the contract is verified, false otherwise.
*/

export async function isVerified(address: string, apiUrl: string, apiKey: string, chainId: number): Promise<boolean> {
export async function isVerified(address: string, chainId: number, apiUrl: string, apiKey: string): Promise<boolean> {
const parameters = new URLSearchParams({
apikey: apiKey,
chainid: chainId.toString(),
Expand Down
Loading
Loading