Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
sklppy88 committed Dec 8, 2024
1 parent 4b6b5db commit 7927bf4
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 142 deletions.
6 changes: 5 additions & 1 deletion yarn-project/aztec.js/src/contract/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,11 @@ describe('Contract Class', () => {
wallet = mock<Wallet>();
wallet.simulateTx.mockResolvedValue(mockTxSimulationResult);
wallet.createTxExecutionRequest.mockResolvedValue(mockTxRequest);
wallet.getContractInstance.mockResolvedValue(contractInstance);
wallet.getContractMetadata.mockResolvedValue({
contractInstance,
isContractInitialized: true,
isContractPubliclyDeployed: true,
});
wallet.sendTx.mockResolvedValue(mockTxHash);
wallet.simulateUnconstrained.mockResolvedValue(mockUnconstrainedResultValue as any as AbiDecoded);
wallet.getTxReceipt.mockResolvedValue(mockTxReceipt);
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/contract/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Contract extends ContractBase {
* @returns A promise that resolves to a new Contract instance.
*/
public static async at(address: AztecAddress, artifact: ContractArtifact, wallet: Wallet): Promise<Contract> {
const instance = await wallet.getContractInstance(address);
const instance = (await wallet.getContractMetadata(address)).contractInstance;
if (instance === undefined) {
throw new Error(`Contract instance at ${address.toString()} has not been registered in the wallet's PXE`);
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/contract/deploy_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas

// Register the contract class if it hasn't been published already.
if (!options.skipClassRegistration) {
if (await this.wallet.isContractClassPubliclyRegistered(contractClass.id)) {
if ((await this.wallet.getContractClassMetadata(contractClass.id)).isContractClassPubliclyRegistered) {
this.log.debug(
`Skipping registration of already registered contract class ${contractClass.id.toString()} for ${instance.address.toString()}`,
);
Expand Down
26 changes: 8 additions & 18 deletions yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
type AuthWitness,
ContractClassMetadata,
ContractMetadata,
type EventMetadataDefinition,
type ExtendedNote,
type GetUnencryptedLogsResponse,
Expand Down Expand Up @@ -65,15 +67,6 @@ export abstract class BaseWallet implements Wallet {
getAddress() {
return this.getCompleteAddress().address;
}
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
return this.pxe.getContractInstance(address);
}
getContractClass(id: Fr): Promise<ContractClassWithId | undefined> {
return this.pxe.getContractClass(id);
}
getContractArtifact(id: Fr): Promise<ContractArtifact | undefined> {
return this.pxe.getContractArtifact(id);
}
addCapsule(capsule: Fr[]): Promise<void> {
return this.pxe.addCapsule(capsule);
}
Expand Down Expand Up @@ -181,18 +174,15 @@ export abstract class BaseWallet implements Wallet {
getAuthWitness(messageHash: Fr) {
return this.pxe.getAuthWitness(messageHash);
}
isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
return this.pxe.isContractClassPubliclyRegistered(id);
}
isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
return this.pxe.isContractPubliclyDeployed(address);
}
isContractInitialized(address: AztecAddress): Promise<boolean> {
return this.pxe.isContractInitialized(address);
}
getPXEInfo(): Promise<PXEInfo> {
return this.pxe.getPXEInfo();
}
getContractClassMetadata(id: Fr, includeArtifact: boolean = false): Promise<ContractClassMetadata> {
return this.pxe.getContractClassMetadata(id, includeArtifact);
}
getContractMetadata(address: AztecAddress): Promise<ContractMetadata> {
return this.pxe.getContractMetadata(address);
}
getEncryptedEvents<T>(
event: EventMetadataDefinition,
from: number,
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/aztec.js/src/wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export async function getWallet(
address: AztecAddress,
accountContract: AccountContract,
): Promise<AccountWallet> {
const completeAddress = (await pxe.getRegisteredAccounts()).find(completeAddress => completeAddress.address.equals(address));
const completeAddress = (await pxe.getRegisteredAccounts()).find(completeAddress =>
completeAddress.address.equals(address),
);
if (!completeAddress) {
throw new Error(`Account ${address} not found`);
}
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/bot/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class BotFactory {
const salt = Fr.ONE;
const signingKey = deriveSigningKey(this.config.senderPrivateKey);
const account = getSchnorrAccount(this.pxe, this.config.senderPrivateKey, signingKey, salt);
const isInit = await this.pxe.isContractInitialized(account.getAddress());
const isInit = (await this.pxe.getContractMetadata(account.getAddress())).isContractInitialized;
if (isInit) {
this.log.info(`Account at ${account.getAddress().toString()} already initialized`);
const wallet = await account.register();
Expand Down Expand Up @@ -122,7 +122,7 @@ export class BotFactory {
}

const address = deploy.getInstance(deployOpts).address;
if (await this.pxe.isContractPubliclyDeployed(address)) {
if ((await this.pxe.getContractMetadata(address)).isContractPubliclyDeployed) {
this.log.info(`Token at ${address.toString()} already deployed`);
return deploy.register();
} else {
Expand Down
91 changes: 45 additions & 46 deletions yarn-project/circuit-types/src/interfaces/pxe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ import { SiblingPath } from '../sibling_path/sibling_path.js';
import { Tx, TxHash, TxProvingResult, TxReceipt, TxSimulationResult } from '../tx/index.js';
import { TxEffect } from '../tx_effect.js';
import { TxExecutionRequest } from '../tx_execution_request.js';
import { type EventMetadataDefinition, type PXE, type PXEInfo, PXESchema } from './pxe.js';
import {
ContractClassMetadata,
ContractMetadata,
type EventMetadataDefinition,
type PXE,
type PXEInfo,
PXESchema,
} from './pxe.js';
import { type SyncStatus } from './sync-status.js';

jest.setTimeout(12_000);
Expand Down Expand Up @@ -264,36 +271,36 @@ describe('PXESchema', () => {
expect(result).toEqual(await handler.getSyncStatus());
});

it('getContractInstance', async () => {
const result = await context.client.getContractInstance(address);
expect(result).toEqual(instance);
});
// it('getContractInstance', async () => {
// const result = await context.client.getContractInstance(address);
// expect(result).toEqual(instance);
// });

it('getContractClass', async () => {
const result = await context.client.getContractClass(Fr.random());
const expected = omit(getContractClassFromArtifact(artifact), 'privateFunctionsRoot', 'publicBytecodeCommitment');
expect(result).toEqual(expected);
});
// it('getContractClass', async () => {
// const result = await context.client.getContractClass(Fr.random());
// const expected = omit(getContractClassFromArtifact(artifact), 'privateFunctionsRoot', 'publicBytecodeCommitment');
// expect(result).toEqual(expected);
// });

it('getContractArtifact', async () => {
const result = await context.client.getContractArtifact(Fr.random());
deepStrictEqual(result, artifact);
});
// it('getContractArtifact', async () => {
// const result = await context.client.getContractArtifact(Fr.random());
// deepStrictEqual(result, artifact);
// });

it('isContractClassPubliclyRegistered', async () => {
const result = await context.client.isContractClassPubliclyRegistered(Fr.random());
expect(result).toBe(true);
});
// it('isContractClassPubliclyRegistered', async () => {
// const result = await context.client.isContractClassPubliclyRegistered(Fr.random());
// expect(result).toBe(true);
// });

it('isContractPubliclyDeployed', async () => {
const result = await context.client.isContractPubliclyDeployed(address);
expect(result).toBe(true);
});
// it('isContractPubliclyDeployed', async () => {
// const result = await context.client.isContractPubliclyDeployed(address);
// expect(result).toBe(true);
// });

it('isContractInitialized', async () => {
const result = await context.client.isContractInitialized(address);
expect(result).toBe(true);
});
// it('isContractInitialized', async () => {
// const result = await context.client.isContractInitialized(address);
// expect(result).toBe(true);
// });

it('getEncryptedEvents', async () => {
const result = await context.client.getEncryptedEvents<EpochProofQuote>(
Expand Down Expand Up @@ -505,30 +512,22 @@ class MockPXE implements PXE {
blocks: 1,
});
}
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
expect(address).toEqual(this.address);
return Promise.resolve(this.instance);
}
getContractClass(id: Fr): Promise<ContractClassWithId | undefined> {
getContractClassMetadata(id: Fr, includeArtifact: boolean = false): Promise<ContractClassMetadata> {
expect(id).toBeInstanceOf(Fr);
const contractClass = getContractClassFromArtifact(this.artifact);
return Promise.resolve(contractClass);
}
getContractArtifact(id: Fr): Promise<ContractArtifact | undefined> {
expect(id).toBeInstanceOf(Fr);
return Promise.resolve(this.artifact);
}
isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
expect(id).toBeInstanceOf(Fr);
return Promise.resolve(true);
}
isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
expect(address).toEqual(this.address);
return Promise.resolve(true);
return Promise.resolve({
contractClass,
isContractClassPubliclyRegistered: true,
artifact: includeArtifact ? this.artifact : undefined,
});
}
isContractInitialized(address: AztecAddress): Promise<boolean> {
getContractMetadata(address: AztecAddress): Promise<ContractMetadata> {
expect(address).toEqual(this.address);
return Promise.resolve(true);
return Promise.resolve({
contractInstance: this.instance,
isContractInitialized: true,
isContractPubliclyDeployed: true,
});
}
getEncryptedEvents<T>(
_eventMetadata: EventMetadataDefinition,
Expand Down
81 changes: 42 additions & 39 deletions yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,44 +364,36 @@ export interface PXE {
* TODO(@spalladino): Should we return the public keys in plain as well here?
* @param address - Deployment address of the contract.
*/
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;

/**
* Returns a Contract Class given its identifier.
* TODO(@spalladino): The PXE actually holds artifacts and not classes, what should we return? Also,
* should the pxe query the node for contract public info, and merge it with its own definitions?
* @param id - Identifier of the class.
* Queries the node to check whether the contract instance with the given address has been publicly deployed,
* regardless of whether this PXE knows about the contract or not.
* TODO(@spalladino): Same notes as above.
*/
/**
* Queries the node to check whether the contract instance with the given address has been initialized,
* by checking the standard initialization nullifier.
* @param address - Address of the contract to check.
*/
getContractClass(id: Fr): Promise<ContractClassWithId | undefined>;
getContractMetadata(address: AztecAddress): Promise<ContractMetadata>;

/**
* Returns the contract artifact associated to a contract class.
* @param id - Identifier of the class.
*/
getContractArtifact(id: Fr): Promise<ContractArtifact | undefined>;

/**
* Returns a Contract Class given its identifier.
* TODO(@spalladino): The PXE actually holds artifacts and not classes, what should we return? Also,
* should the pxe query the node for contract public info, and merge it with its own definitions?
* @param id - Identifier of the class.
*/
/**
* Queries the node to check whether the contract class with the given id has been publicly registered.
* TODO(@spalladino): This method is strictly needed to decide whether to publicly register a class or not
* during a public deployment. We probably want a nicer and more general API for this, but it'll have to
* do for the time being.
* @param id - Identifier of the class.
*/
isContractClassPubliclyRegistered(id: Fr): Promise<boolean>;

/**
* Queries the node to check whether the contract instance with the given address has been publicly deployed,
* regardless of whether this PXE knows about the contract or not.
* TODO(@spalladino): Same notes as above.
*/
isContractPubliclyDeployed(address: AztecAddress): Promise<boolean>;

/**
* Queries the node to check whether the contract instance with the given address has been initialized,
* by checking the standard initialization nullifier.
* @param address - Address of the contract to check.
*/
isContractInitialized(address: AztecAddress): Promise<boolean>;
getContractClassMetadata(id: Fr, includeArtifact?: boolean): Promise<ContractClassMetadata>;

/**
* Returns the enctypred events given search parameters.
Expand Down Expand Up @@ -455,6 +447,30 @@ export interface PXEInfo {
protocolContractAddresses: ProtocolContractAddresses;
}

export interface ContractMetadata {
contractInstance?: ContractInstanceWithAddress | undefined;
isContractInitialized: boolean;
isContractPubliclyDeployed: boolean;
}

export interface ContractClassMetadata {
contractClass?: ContractClassWithId | undefined;
isContractClassPubliclyRegistered: boolean;
artifact?: ContractArtifact | undefined;
}

const ContractMetadataSchema = z.object({
contractInstance: z.union([ContractInstanceWithAddressSchema, z.undefined()]),
isContractInitialized: z.boolean(),
isContractPubliclyDeployed: z.boolean(),
}) satisfies ZodFor<ContractMetadata>;

const ContractClassMetadataSchema = z.object({
contractClass: z.union([ContractClassWithIdSchema, z.undefined()]),
isContractClassPubliclyRegistered: z.boolean(),
artifact: z.union([ContractArtifactSchema, z.undefined()]),
}) satisfies ZodFor<ContractClassMetadata>;

const PXEInfoSchema = z.object({
pxeVersion: z.string(),
protocolContractAddresses: ProtocolContractAddressesSchema,
Expand Down Expand Up @@ -529,21 +545,8 @@ export const PXESchema: ApiSchemaFor<PXE> = {
getPXEInfo: z.function().returns(PXEInfoSchema),
isGlobalStateSynchronized: z.function().returns(z.boolean()),
getSyncStatus: z.function().returns(SyncStatusSchema),
getContractInstance: z
.function()
.args(schemas.AztecAddress)
.returns(z.union([ContractInstanceWithAddressSchema, z.undefined()])),
getContractClass: z
.function()
.args(schemas.Fr)
.returns(z.union([ContractClassWithIdSchema, z.undefined()])),
getContractArtifact: z
.function()
.args(schemas.Fr)
.returns(z.union([ContractArtifactSchema, z.undefined()])),
isContractClassPubliclyRegistered: z.function().args(schemas.Fr).returns(z.boolean()),
isContractPubliclyDeployed: z.function().args(schemas.AztecAddress).returns(z.boolean()),
isContractInitialized: z.function().args(schemas.AztecAddress).returns(z.boolean()),
getContractMetadata: z.function().args(schemas.AztecAddress).returns(ContractMetadataSchema),
getContractClassMetadata: z.function().args(schemas.Fr, optional(z.boolean())).returns(ContractClassMetadataSchema),
getEncryptedEvents: z
.function()
.args(EventMetadataDefinitionSchema, z.number(), z.number(), z.array(schemas.Point))
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/cli/src/cmds/pxe/get_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { type DebugLogger, type LogFn } from '@aztec/foundation/log';

export async function getAccount(aztecAddress: AztecAddress, rpcUrl: string, debugLogger: DebugLogger, log: LogFn) {
const client = await createCompatibleClient(rpcUrl, debugLogger);
const account = (await client.getRegisteredAccounts()).find(completeAddress => completeAddress.address.equals(aztecAddress));
const account = (await client.getRegisteredAccounts()).find(completeAddress =>
completeAddress.address.equals(aztecAddress),
);

if (!account) {
log(`Unknown account ${aztecAddress.toString()}`);
Expand Down
11 changes: 7 additions & 4 deletions yarn-project/cli/src/cmds/pxe/get_contract_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ export async function getContractData(
log: LogFn,
) {
const client = await createCompatibleClient(rpcUrl, debugLogger);
const instance = await client.getContractInstance(contractAddress);
const contractClass = includeBytecode && instance && (await client.getContractClass(instance?.contractClassId));
const {
contractInstance: instance,
isContractInitialized: isInitialized,
isContractPubliclyDeployed: isPubliclyDeployed,
} = await client.getContractMetadata(contractAddress);
const contractClass =
includeBytecode && instance && (await client.getContractClassMetadata(instance?.contractClassId)).contractClass;

const isPrivatelyDeployed = !!instance;
const isPubliclyDeployed = await client.isContractPubliclyDeployed(contractAddress);
const isInitialized = await client.isContractInitialized(contractAddress);
const initStr = isInitialized ? 'initialized' : 'not initialized';
const addrStr = contractAddress.toString();

Expand Down
Loading

0 comments on commit 7927bf4

Please sign in to comment.