Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -5,6 +5,7 @@ The Aztec 3 system consists of the following sub projects.
- `acir-simulator`
- `archiver`
- `aztec-cli`
- `aztec-rpc`
- `aztec.js`
- `ethereum.js`
- `kernel-simulator`
Expand All @@ -13,4 +14,3 @@ The Aztec 3 system consists of the following sub projects.
- `prover-client`
- `public-client`
- `sequencer-client`
- `wallet`
2 changes: 1 addition & 1 deletion bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ PROJECTS=(
# "circuits:./bootstrap.sh db_cli rollup_cli"
# "yarn-project/acir-simulator:yarn build"
# "yarn-project/aztec-cli:yarn build"
"yarn-project/aztec-rpc:yarn build"
"yarn-project/aztec.js:yarn build"
"yarn-project/archiver:yarn build"
# "yarn-project/ethereum.js:yarn build"
Expand All @@ -54,7 +55,6 @@ PROJECTS=(
# "yarn-project/prover-client:yarn build"
# "yarn-project/public-client:yarn build"
# "yarn-project/sequencer-client:yarn build"
# "yarn-project/wallet:yarn build"
)

for E in "${PROJECTS[@]}"; do
Expand Down
14 changes: 7 additions & 7 deletions build_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@
"rebuildPatterns": ["^yarn-project/aztec-cli/"],
"dependencies": ["yarn-project-base"]
},
"aztec-rpc": {
"buildDir": "yarn-project",
"projectDir": "yarn-project/aztec-rpc",
"dockerfile": "aztec-rpc/Dockerfile",
"rebuildPatterns": ["^yarn-project/aztec-rpc/"],
"dependencies": ["yarn-project-base"]
},
"aztec.js": {
"buildDir": "yarn-project",
"projectDir": "yarn-project/aztec.js",
Expand Down Expand Up @@ -128,12 +135,5 @@
"dockerfile": "sequencer-client/Dockerfile",
"rebuildPatterns": ["^yarn-project/sequencer-client/"],
"dependencies": ["yarn-project-base"]
},
"wallet": {
"buildDir": "yarn-project",
"projectDir": "yarn-project/wallet",
"dockerfile": "wallet/Dockerfile",
"rebuildPatterns": ["^yarn-project/wallet/"],
"dependencies": ["yarn-project-base"]
}
}
2 changes: 1 addition & 1 deletion build_manifest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ PROJECTS=(
# acir-simulator:yarn-project
# archiver:yarn-project
# aztec-cli:yarn-project
# aztec-rpc:yarn-project
# aztec.js:yarn-project
# end-to-end:yarn-project
# ethereum.js:yarn-project
Expand All @@ -23,5 +24,4 @@ PROJECTS=(
# prover-client:yarn-project
# public-client:yarn-project
# sequencer-client:yarn-project
# wallet:yarn-project
)
21 changes: 21 additions & 0 deletions yarn-project/aztec-rpc/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require('@rushstack/eslint-patch/modern-module-resolution');

module.exports = {
extends: ['@aztec/eslint-config'],
parserOptions: { tsconfigRootDir: __dirname },
rules: {
'tsdoc/syntax': 'off',
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-description': 'off',
'jsdoc/require-description-complete-sentence': 'off',
'jsdoc/require-hyphen-before-param-description': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-param-name': 'off',
'jsdoc/require-property': 'off',
'jsdoc/require-property-description': 'off',
'jsdoc/require-property-name': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-description': 'off',
},
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/yarn-project-base AS builder

COPY wallet wallet
WORKDIR /usr/src/yarn-project/wallet
COPY aztec-rpc aztec-rpc
WORKDIR /usr/src/yarn-project/aztec-rpc
RUN yarn build && yarn formatting && yarn test

# Prune dev dependencies. See comment in base image.
RUN yarn cache clean
RUN yarn workspaces focus --production > /dev/null

FROM node:18-alpine
COPY --from=builder /usr/src/yarn-project/wallet /usr/src/yarn-project/wallet
WORKDIR /usr/src/yarn-project/wallet
COPY --from=builder /usr/src/yarn-project/aztec-rpc /usr/src/yarn-project/aztec-rpc
WORKDIR /usr/src/yarn-project/aztec-rpc
ENTRYPOINT ["yarn"]
1 change: 1 addition & 0 deletions yarn-project/aztec-rpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Aztec RPC Server & Client
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@aztec/wallet",
"name": "@aztec/aztec-rpc",
"version": "0.0.0",
"type": "module",
"exports": "./dest/index.js",
Expand Down
11 changes: 11 additions & 0 deletions yarn-project/aztec-rpc/src/abi_coder/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { keccak256 } from '../foundation.js';
import { ABIParameter } from '../noir.js';

export function generateFunctionSignature(name: string, parameters: ABIParameter[]) {
return name === 'constructor' ? name : `${name}(${parameters.map(p => p.type.kind).join(',')})`;
}

export function generateFunctionSelector(name: string, parameters: ABIParameter[]) {
const signature = generateFunctionSignature(name, parameters);
return keccak256(Buffer.from(signature)).slice(0, 4);
}
11 changes: 11 additions & 0 deletions yarn-project/aztec-rpc/src/account_state/account_state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { TxHash } from '../aztec_node.js';
import { AztecAddress } from '../circuits.js';
import { Database } from '../database/index.js';

export class AccountState {
constructor(public readonly publicKey: AztecAddress, private db: Database) {}

getTx(txHash: TxHash) {
return this.db.getTx(txHash);
}
}
1 change: 1 addition & 0 deletions yarn-project/aztec-rpc/src/account_state/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './account_state.js';
9 changes: 9 additions & 0 deletions yarn-project/aztec-rpc/src/acir_simulator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// TODO use @aztce/acir-simulator

import { PreviousKernelData, PrivateCallData, TxRequest } from './circuits.js';

export class AcirSimulator {
public simulate(txRequest: TxRequest) {
return Promise.resolve({ kernelData: new PreviousKernelData(), callData: new PrivateCallData() });
}
}
29 changes: 29 additions & 0 deletions yarn-project/aztec-rpc/src/aztec_node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { AccumulatedTxData } from './circuits.js';

export class TxHash {
public static SIZE = 32;

constructor(public readonly buffer: Buffer) {}

public equals(rhs: TxHash) {
return this.buffer.equals(rhs.buffer);
}
}

export class Tx {
constructor(public readonly proofData: Buffer, public readonly data: AccumulatedTxData) {}

get txHash() {
return new TxHash(Buffer.alloc(32));
}
}

export class AztecNode {
sendTx(tx: Tx) {
return Promise.resolve(tx.txHash);
}

getBlocks() {
return Promise.resolve([]);
}
}
23 changes: 23 additions & 0 deletions yarn-project/aztec-rpc/src/aztec_rpc_client/aztec_rpc_client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Tx, TxHash } from '../aztec_node.js';
import { AztecAddress, EthAddress, Fr, Signature, TxRequest } from '../circuits.js';
import { ContractAbi } from '../noir.js';
import { TxReceipt } from '../tx/index.js';

export interface AztecRPCClient {
addAccount(): Promise<AztecAddress>;
getAccounts(): Promise<AztecAddress[]>;
getCode(contract: AztecAddress, functionSelector?: Buffer): Promise<string | undefined>;
createDeploymentTxRequest(
abi: ContractAbi,
args: Fr[],
portalContract: EthAddress,
contractAddressSalt: Fr,
from: AztecAddress,
): Promise<TxRequest>;
createTxRequest(functionSelector: Buffer, args: Fr[], to: AztecAddress, from: AztecAddress): Promise<TxRequest>;
signTxRequest(txRequest: TxRequest): Promise<Signature>;
createTx(txRequest: TxRequest, signature: Signature): Promise<Tx>;
sendTx(tx: Tx): Promise<TxHash>;
// callTx(functionSelector: Buffer, args: Fr[], to: AztecAddress, from: AztecAddress): Promise<any>;
getTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined>;
}
1 change: 1 addition & 0 deletions yarn-project/aztec-rpc/src/aztec_rpc_client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './aztec_rpc_client.js';
155 changes: 155 additions & 0 deletions yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { generateFunctionSelector } from '../abi_coder/index.js';
import { AcirSimulator } from '../acir_simulator.js';
import { AztecNode, Tx, TxHash } from '../aztec_node.js';
import { AztecRPCClient } from '../aztec_rpc_client/index.js';
import {
AztecAddress,
ContractDeploymentData,
EthAddress,
Fr,
generateContractAddress,
KernelPrivateInputs,
Signature,
TxContext,
TxRequest,
} from '../circuits.js';
import { Database } from '../database/index.js';
import { KeyStore } from '../key_store/index.js';
import { ContractAbi } from '../noir.js';
import { ProofGenerator } from '../proof_generator/index.js';
import { Synchroniser } from '../synchroniser/index.js';

export class AztecRPCServer implements AztecRPCClient {
constructor(
private keyStore: KeyStore,
private synchroniser: Synchroniser,
private simulator: AcirSimulator,
private proofGenerator: ProofGenerator,
private node: AztecNode,
private db: Database,
) {}

public addAccount() {
return this.keyStore.addAccount();
}

public getAccounts() {
return this.keyStore.getAccounts();
}

public getCode(contract: AztecAddress, functionSelector?: Buffer) {
return this.db.getCode(contract, functionSelector || generateFunctionSelector('constructor', []));
}

public async createDeploymentTxRequest(
abi: ContractAbi,
args: Fr[],
portalContract: EthAddress,
contractAddressSalt: Fr,
from: AztecAddress,
) {
const constructorAbi = abi.functions.find(f => f.name === 'constructor');
if (!constructorAbi) {
throw new Error('Cannot find constructor in the ABI.');
}

const functionData = {
functionSelector: generateFunctionSelector(constructorAbi.name, constructorAbi.parameters),
isSecret: true,
isContructor: true,
};

const contractDataHash = Fr.ZERO;
const functionTreeRoot = Fr.ZERO;
const constructorHash = Fr.ZERO;
const contractDeploymentData = new ContractDeploymentData(
contractDataHash,
functionTreeRoot,
constructorHash,
contractAddressSalt,
portalContract,
);
const txContext = new TxContext(false, false, false, contractDeploymentData);

const contractAddress = generateContractAddress(from, contractAddressSalt, args);
await this.db.addContract(contractAddress, abi, false);

return new TxRequest(
from,
AztecAddress.ZERO, // to
functionData,
args,
txContext,
Fr.random(), // nonce
Fr.ZERO, // chainId
);
}

public async createTxRequest(functionSelector: Buffer, args: Fr[], to: AztecAddress, from: AztecAddress) {
const abi = await this.db.getContract(to);
if (!abi) {
throw new Error('Unknown contract.');
}

const functionAbi = abi.functions.find(f => f.selector.equals(functionSelector));
if (!functionAbi) {
throw new Error('Unknown function.');
}

const functionData = {
functionSelector,
isSecret: functionAbi.isSecret,
isContructor: false,
};

const txContext = new TxContext(false, false, false, ContractDeploymentData.EMPTY);

return new TxRequest(
from,
to,
functionData,
args,
txContext,
Fr.random(), // nonce
Fr.ZERO, // chainId
);
}

public signTxRequest(txRequest: TxRequest) {
return this.keyStore.signTxRequest(txRequest);
}

public async createTx(txRequest: TxRequest, signature: Signature) {
const { kernelData, callData } = await this.simulator.simulate(txRequest);
const privateInputs = new KernelPrivateInputs(txRequest, signature, kernelData, callData);
const { proofData, accumulatedTxData } = await this.proofGenerator.createProof(privateInputs);
return new Tx(proofData, accumulatedTxData);
}

public sendTx(tx: Tx) {
return this.node.sendTx(tx);
}

public async getTxReceipt(txHash: TxHash) {
const tx = await this.db.getTx(txHash);
if (!tx) {
return;
}

const account = this.synchroniser.getAccount(tx.from);
if (!account) {
throw new Error('Unauthorised account.');
}

return {
txHash: tx.txHash,
blockHash: tx.blockHash,
blockNumber: tx.blockNumber,
from: tx.from,
to: tx.to,
contractAddress: tx.contractAddress,
error: tx.error,
status: !tx.error,
};
}
}
Loading