Skip to content

Commit

Permalink
Merge develop -> main (v2.0.7) (#81)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Roshan <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 19, 2024
1 parent 08e2fc1 commit 8e25a0e
Show file tree
Hide file tree
Showing 29 changed files with 806 additions and 160 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ on:
pull_request:

env:
PRIVATE_KEY_ANVIL: ${{ secrets.PRIVATE_KEY_ANVIL }}
PRIVATE_KEY_SEPOLIA: ${{ secrets.PRIVATE_KEY_SEPOLIA }}
PROVIDER_URI_SEPOLIA: ${{ secrets.PROVIDER_URI_SEPOLIA }}
PROVIDER_URI_GOERLI: ${{ secrets.PROVIDER_URI_GOERLI }}
PROVIDER_URI_84532: ${{ secrets.PROVIDER_URI_84532 }}
PINATA_JWT: ${{ secrets.PINATA_JWT }}

jobs:
Expand Down
4 changes: 2 additions & 2 deletions circuit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axiom-crypto/circuit",
"version": "2.0.6",
"version": "2.0.7",
"author": "Intrinsic Technologies",
"license": "MIT",
"description": "Client SDK to write custom queries for Axiom, the ZK Coprocessor for Ethereum.",
Expand All @@ -24,7 +24,7 @@
"crypto"
],
"dependencies": {
"@axiom-crypto/core": "2.3.7",
"@axiom-crypto/core": "2.3.8",
"@axiom-crypto/halo2-lib-js": "0.3.4",
"@axiom-crypto/halo2-wasm": "0.3.4",
"@axiom-crypto/tools": "2.1.0",
Expand Down
14 changes: 7 additions & 7 deletions circuit/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@axiom-crypto/client",
"version": "2.0.6",
"version": "2.0.7",
"author": "Intrinsic Technologies",
"license": "MIT",
"description": "Client SDK to write custom queries for Axiom, the ZK Coprocessor for Ethereum.",
Expand All @@ -25,7 +25,7 @@
],
"dependencies": {
"@axiom-crypto/circuit": "link:../circuit/dist",
"@axiom-crypto/core": "2.3.7",
"@axiom-crypto/core": "2.3.8",
"chalk": "^4.1.2",
"commander": "^11.1.0",
"prompts": "^2.4.2",
Expand Down
14 changes: 7 additions & 7 deletions client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 28 additions & 25 deletions client/src/axiom/axiom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {
AxiomV2CompiledCircuit,
AxiomV2SendQueryArgs,
} from "../types";
import { RawInput } from "@axiom-crypto/circuit/types";
import { AxiomV2CircuitCapacity, DEFAULT_CAPACITY } from "@axiom-crypto/circuit";
import { convertChainIdToViemChain } from "./utils";
import { TransactionReceipt, WalletClient, createPublicClient, createWalletClient, http, zeroAddress, zeroHash } from "viem";
import { AxiomV2CircuitCapacity, UserInput, DEFAULT_CAPACITY } from "@axiom-crypto/circuit";
import { validateChainId } from "./utils";
import { PublicClient, TransactionReceipt, WalletClient, createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from 'viem/accounts'
import { AxiomV2Callback } from "@axiom-crypto/core";
import { ClientConstants } from "../constants";
import { viemChain } from "../lib";
import { getChainDefaults } from "../lib/chain";

export class Axiom<T> {
protected config: AxiomV2ClientConfig<T>;
Expand All @@ -20,6 +20,7 @@ export class Axiom<T> {
protected callback: AxiomV2Callback;
protected options?: AxiomV2ClientOptions;
protected capacity?: AxiomV2CircuitCapacity;
protected publicClient: PublicClient;
protected walletClient?: WalletClient;
protected sendQueryArgs?: AxiomV2SendQueryArgs;

Expand All @@ -32,18 +33,29 @@ export class Axiom<T> {
extraData: config.callback.extraData ?? "0x",
};

this.options = config.options;
if (config.options?.overrides?.queryAddress === undefined) {
validateChainId(this.config.chainId);
}

this.axiomCircuit = new AxiomCircuit({
f: config.circuit,
provider: this.config.provider,
inputSchema: config.compiledCircuit.inputSchema,
chainId: this.config.chainId,
capacity: this.capacity,
capacity: this.capacity ?? this.compiledCircuit.capacity ?? DEFAULT_CAPACITY,
});

const publicClient = createPublicClient({
chain: viemChain(config.chainId, config.provider),
transport: http(config.provider),
});
this.publicClient = publicClient;

if (this.config.privateKey) {
const account = privateKeyToAccount(this.config.privateKey as `0x${string}`);
this.walletClient = createWalletClient({
chain: convertChainIdToViemChain(this.config.chainId),
chain: viemChain(config.chainId, config.provider),
account,
transport: http(this.config.provider),
});
Expand All @@ -56,7 +68,7 @@ export class Axiom<T> {
async init() {
await this.axiomCircuit.loadSaved({
config: this.compiledCircuit.config,
capacity: this.capacity ?? DEFAULT_CAPACITY,
capacity: this.capacity ?? this.compiledCircuit.capacity ?? DEFAULT_CAPACITY,
vk: this.compiledCircuit.vk,
});
}
Expand All @@ -82,23 +94,18 @@ export class Axiom<T> {
}
}

async prove(input: RawInput<T>): Promise<AxiomV2SendQueryArgs> {
async prove(input: UserInput<T>): Promise<AxiomV2SendQueryArgs> {
await this.axiomCircuit.run(input);
return await this.buildSendQueryArgs();
}

async sendQuery(): Promise<TransactionReceipt> {
const publicClient = createPublicClient({
chain: convertChainIdToViemChain(this.config.chainId),
transport: http(this.config.provider),
});

const args = this.getSendQueryArgs();
if (args === undefined) {
throw new Error("SendQuery args have not been built yet. Please run `prove` first.");
}
try {
const { request } = await publicClient.simulateContract({
const { request } = await this.publicClient.simulateContract({
address: args.address as `0x${string}`,
abi: args.abi,
functionName: args.functionName,
Expand All @@ -110,7 +117,7 @@ export class Axiom<T> {
if (hash === undefined) {
throw new Error("Failed to send the query transaction to AxiomV2Query");
}
return await publicClient.waitForTransactionReceipt({ hash });
return await this.publicClient.waitForTransactionReceipt({ hash });
} catch (e: any) {
if (e?.metaMessages !== undefined) {
throw new Error(e.metaMessages.join("\n"));
Expand All @@ -120,20 +127,16 @@ export class Axiom<T> {
}

async sendQueryWithIpfs(): Promise<TransactionReceipt> {
if (this.config.ipfsClient === undefined) {
if (this.config.options?.ipfsClient === undefined) {
throw new Error("Setting `ipfsClient` is required to send a Query with IPFS");
}
const publicClient = createPublicClient({
chain: convertChainIdToViemChain(this.config.chainId),
transport: http(this.config.provider),
});

const args = await this.getSendQueryArgs();
if (args === undefined) {
throw new Error("SendQuery args have not been built yet. Please run `prove` first.");
}
try {
const { request } = await publicClient.simulateContract({
const { request } = await this.publicClient.simulateContract({
address: args.address as `0x${string}`,
abi: args.abi,
functionName: args.functionName,
Expand All @@ -145,7 +148,7 @@ export class Axiom<T> {
if (hash === undefined) {
throw new Error("Failed to send the query transaction to AxiomV2Query");
}
return await publicClient.waitForTransactionReceipt({ hash });
return await this.publicClient.waitForTransactionReceipt({ hash });
} catch (e: any) {
if (e?.metaMessages !== undefined) {
throw new Error(e.metaMessages.join("\n"));
Expand All @@ -160,9 +163,9 @@ export class Axiom<T> {
}
const clientOptions: AxiomV2ClientOptions = {
...this.options,
callbackGasLimit: this.options?.callbackGasLimit ?? ClientConstants.CALLBACK_GAS_LIMIT,
callbackGasLimit: this.options?.callbackGasLimit ?? Number(getChainDefaults(this.config.chainId).callbackGasLimit),
refundee: this.options?.refundee ?? this.walletClient?.account?.address,
ipfsClient: this.config.ipfsClient,
overrides: this.options?.overrides,
};

this.sendQueryArgs = await this.axiomCircuit.getSendQueryArgs({
Expand Down
69 changes: 40 additions & 29 deletions client/src/axiom/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ import {
AxiomV2FeeData,
getByteLength,
} from "@axiom-crypto/core";
import { AxiomV2SendQueryArgsParams, CircuitInputType } from "../types";
import { AbiType, AxiomV2ClientOverrides, AxiomV2SendQueryArgsParams, CircuitInputType } from "../types";
import { createPublicClient, http } from 'viem';
import { mainnet, sepolia } from 'viem/chains';
import { ClientConstants } from "../constants";
import { getAxiomV2Abi, getAxiomV2QueryAddress, viemChain } from "../lib";
import { getChainDefaults } from "../lib/chain";

export function validateChainId(chainId: string) {
switch (chainId) {
case "1": // Mainnet
case "11155111": // Sepolia
case "8453": // Base
case "84532": // Base Sepolia
return;
default:
throw new Error(`Unsupported chainId ${chainId}`);
}
}

export function convertInputSchemaToJsonString(args: {[arg: string]: CircuitInputType}): string {
const inputs = Object.keys(args).map((key: string) => {
Expand All @@ -26,17 +38,6 @@ export function convertInputSchemaToJsonString(args: {[arg: string]: CircuitInpu
return `{${inputs.map((inputLine: string) => `\n ${inputLine}`)}\n}`;
}

export function convertChainIdToViemChain(chainId: string) {
switch(chainId) {
case "1":
return mainnet;
case "11155111":
return sepolia;
default:
throw new Error(`Unsupported chainId ${chainId}`);
}
}

export function argsArrToObj(
args: (string | AxiomV2Callback | AxiomV2ComputeQuery | AxiomV2FeeData)[]
): AxiomV2SendQueryArgsParams {
Expand Down Expand Up @@ -67,24 +68,34 @@ export function argsObjToArr(
]
}

export async function getMaxFeePerGas(axiom: AxiomSdkCore): Promise<string> {
export async function getMaxFeePerGas(axiom: AxiomSdkCore, overrides?: AxiomV2ClientOverrides): Promise<string> {
const chainId = axiom.config.chainId.toString();
const axiomQueryAddress = overrides?.queryAddress ?? getAxiomV2QueryAddress(chainId);

const providerFeeData = (await axiom.config.provider.getFeeData()).maxFeePerGas as bigint;
const publicClient = createPublicClient({
chain: convertChainIdToViemChain(axiom.config.chainId.toString()),
chain: viemChain(axiom.config.chainId.toString(), axiom.config.providerUri),
transport: http(axiom.config.providerUri),
});
let contractMinMaxFeePerGas = await publicClient.readContract({
address: axiom.getAxiomQueryAddress() as `0x${string}`,
abi: axiom.getAxiomQueryAbi(),
functionName: "minMaxFeePerGas",
args: [],
}) as bigint;
if (contractMinMaxFeePerGas === 0n) {
contractMinMaxFeePerGas = ClientConstants.MIN_MAX_FEE_PER_GAS;
}
if (providerFeeData > contractMinMaxFeePerGas) {
return providerFeeData.toString();

try {
let contractMinMaxFeePerGas = await publicClient.readContract({
address: axiomQueryAddress as `0x${string}`,
abi: getAxiomV2Abi(AbiType.Query),
functionName: "minMaxFeePerGas",
args: [],
}) as bigint;
if (contractMinMaxFeePerGas === 0n) {
contractMinMaxFeePerGas = getChainDefaults(chainId).minMaxFeePerGasWei;
}
if (providerFeeData > contractMinMaxFeePerGas) {
return providerFeeData.toString();
}
console.log(`Network gas price below threshold. Using contract-defined minimum minMaxFeePerGas of ${contractMinMaxFeePerGas.toString()}`);
return contractMinMaxFeePerGas.toString();
} catch (e) {
const defaultMinMaxFeePerGas = getChainDefaults(chainId).minMaxFeePerGasWei.toString();
console.log(`Unable to read minMaxFeePerGas from contract, returning default value of ${defaultMinMaxFeePerGas}`);
return defaultMinMaxFeePerGas;
}
console.log(`Network gas price below threshold. Using contract-defined minimum maxFeePerGas of ${contractMinMaxFeePerGas.toString()}`);
return contractMinMaxFeePerGas.toString();
}
24 changes: 21 additions & 3 deletions client/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
import { ChainDefaults } from "./types";

export const ClientConstants = Object.freeze({
MIN_MAX_FEE_PER_GAS: 5000000000n,
CALLBACK_GAS_LIMIT: 100000,
})
AXIOM_PROOF_CALLDATA_LEN: 2875, // bytes
AXIOM_PROOF_CALLDATA_BYTES: "0x" + "11".repeat(2875),
})

export const MainnetDefaults: Readonly<ChainDefaults> = Object.freeze({
maxFeePerGasWei: 25000000000n,
minMaxFeePerGasWei: 5000000000n,
callbackGasLimit: 100000n,
proofVerificationGas: 420000n,
axiomQueryFeeWei: 3000000000000000n,
});

export const BaseDefaults: Readonly<ChainDefaults> = Object.freeze({
maxFeePerGasWei: 10000000n,
minMaxFeePerGasWei: 10000000n,
callbackGasLimit: 100000n,
proofVerificationGas: 420000n,
axiomQueryFeeWei: 3000000000000000n,
});
Loading

0 comments on commit 8e25a0e

Please sign in to comment.