Skip to content

Break apart Sandbox and PXE #80

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

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
13 changes: 9 additions & 4 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Install project dependencies
run: yarn

- name: Compile, generate code, and run tests
- name: Compile
run: script -e -c "${AZTEC_NARGO:-aztec-nargo} compile"

- name: Codegen
Expand All @@ -43,8 +43,13 @@ jobs:
- name: Change ownership # to get around Docker issues
run: sudo chown -R $(whoami) ~/nargo && sudo chown -R $(whoami) ~/nargo/github.com

- name: Run tests
run: script -e -c "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --config jest.integration.config.json && aztec test"
- name: Start PXE
run: |
aztec start --port 8081 --pxe --pxe.nodeUrl=http://localhost:8080/ --pxe.proverEnabled false &

# Tests arent set up to run an independent PXE yet
# - name: Run tests
# run: script -e -c "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --config jest.integration.config.json && aztec test"

- name: Run scripts
run: script -e -c "yarn deploy && yarn deploy-account && yarn fees"
run: script -e -c "yarn deploy && yarn deploy-account && yarn fees"
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ aztec-up 0.85.0
Start the sandbox with:

```bash
aztec start --sandbox
aztec start --sandbox --no-pxe
```

Start the PXE with:

```bash
aztec start --port 8081 --pxe --pxe.nodeUrl=http://localhost:8080/ --pxe.proverEnabled false
```

---
Expand Down
24 changes: 14 additions & 10 deletions scripts/deploy-account.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { AccountWallet, CompleteAddress, createLogger, Fr, PXE, waitForPXE, createPXEClient, Logger } from "@aztec/aztec.js";
import { AccountWallet, CompleteAddress, createLogger, Fr, PXE, waitForPXE, createPXEClient, Logger, getWallet, AccountWalletWithSecretKey } from "@aztec/aztec.js";
import { getSchnorrAccount } from '@aztec/accounts/schnorr';
import { deriveSigningKey } from '@aztec/stdlib/keys';
import { getInitialTestAccountsWallets } from "@aztec/accounts/testing";
import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing";
import { getDeployedSponsoredFPCAddress } from "../src/utils/sponsored_fpc.js";
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";

const setupSandbox = async () => {
const { PXE_URL = 'http://localhost:8080' } = process.env;
const { PXE_URL = 'http://localhost:8081' } = process.env;
const pxe = await createPXEClient(PXE_URL);
await waitForPXE(pxe);
return pxe;
};

async function main() {
export async function deploySchnorrAccount(): Promise<AccountWalletWithSecretKey> {

let pxe: PXE;
let wallets: AccountWallet[] = [];
Expand All @@ -22,18 +22,22 @@ async function main() {
logger = createLogger('aztec:aztec-starter');

pxe = await setupSandbox();
wallets = await getInitialTestAccountsWallets(pxe);
const deployedSponseredFPC = await getDeployedSponsoredFPCAddress(pxe);
const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(deployedSponseredFPC);

let secretKey = Fr.random();
let salt = Fr.random();

let schnorrAccount = await getSchnorrAccount(pxe, secretKey, deriveSigningKey(secretKey), salt);
let tx = await schnorrAccount.deploy({ fee: { paymentMethod: sponsoredPaymentMethod } }).wait();
let wallet = await schnorrAccount.getWallet();

const sponseredFPC = await getSponsoredFPCInstance();
await pxe.registerContract({instance: sponseredFPC, artifact: SponsoredFPCContract.artifact});
const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address);

let tx = await schnorrAccount.deploy({ fee: { paymentMethod } }).wait();

logger.info(`Schnorr account deployed at: ${wallet.getAddress()}`);

return wallet;
}

main();
deploySchnorrAccount();
17 changes: 11 additions & 6 deletions scripts/deploy-contract.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { EasyPrivateVotingContract } from "../src/artifacts/EasyPrivateVoting.js"
import { AccountWallet, createLogger, PXE, waitForPXE, createPXEClient, Logger } from "@aztec/aztec.js";
import { getInitialTestAccountsWallets } from "@aztec/accounts/testing";
import { createLogger, PXE, waitForPXE, createPXEClient, Logger, AztecAddress } from "@aztec/aztec.js";
import { TokenContract } from "@aztec/noir-contracts.js/Token"
import { getSponsoredFPCAddress } from "../src/utils/sponsored_fpc.js";
import { SponsoredFeePaymentMethod } from "@aztec/aztec.js/fee/testing";
import { deploySchnorrAccount } from "./deploy-account.js";

const setupSandbox = async () => {
const { PXE_URL = 'http://localhost:8080' } = process.env;
const { PXE_URL = 'http://localhost:8081' } = process.env;
const pxe = await createPXEClient(PXE_URL);
await waitForPXE(pxe);
return pxe;
Expand All @@ -13,15 +15,18 @@ const setupSandbox = async () => {
async function main() {

let pxe: PXE;
let wallets: AccountWallet[] = [];
let logger: Logger;

logger = createLogger('aztec:aztec-starter');

pxe = await setupSandbox();
wallets = await getInitialTestAccountsWallets(pxe);

const votingContract = await EasyPrivateVotingContract.deploy(wallets[0], wallets[0].getAddress()).send().deployed();
const wallet = await deploySchnorrAccount();

const sponseredFPCAddress = await getSponsoredFPCAddress();
const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPCAddress);

const votingContract = await EasyPrivateVotingContract.deploy(wallet, wallet.getAddress()).send({ fee: { paymentMethod }}).deployed();
logger.info(`Voting Contract deployed at: ${votingContract.address}`);
}

Expand Down
40 changes: 23 additions & 17 deletions scripts/fees.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AccountWallet, CompleteAddress, createLogger, FeeJuicePaymentMethodWithClaim, Fr, L1FeeJuicePortalManager, PXE, waitForPXE , createPXEClient, Logger, FeeJuicePaymentMethod, PrivateFeePaymentMethod, PublicFeePaymentMethod } from "@aztec/aztec.js";
import { getInitialTestAccountsWallets } from "@aztec/accounts/testing";
import { createLogger, FeeJuicePaymentMethodWithClaim, Fr, L1FeeJuicePortalManager, PXE, waitForPXE , createPXEClient, Logger, FeeJuicePaymentMethod, PrivateFeePaymentMethod, PublicFeePaymentMethod } from "@aztec/aztec.js";
import {
createPublicClient,
createWalletClient,
Expand All @@ -13,12 +12,15 @@ import { FeeJuiceContract } from "@aztec/noir-contracts.js/FeeJuice";
import { FPCContract } from "@aztec/noir-contracts.js/FPC";
import { EasyPrivateVotingContract } from "../src/artifacts/EasyPrivateVoting.js"
import { TokenContract } from "@aztec/noir-contracts.js/Token";
// TODO: replace with import from aztec.js when published
import { SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee/testing'
import { getDeployedSponsoredFPCAddress } from "../src/utils/sponsored_fpc.js";
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
import { deploySchnorrAccount } from "./deploy-account.js";
import { getSponsoredFPCInstance } from "../src/utils/sponsored_fpc.js";
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';

const setupSandbox = async () => {
const { PXE_URL = 'http://localhost:8080' } = process.env;
const { PXE_URL = 'http://localhost:8081' } = process.env;
const pxe = await createPXEClient(PXE_URL);
await waitForPXE(pxe);
return pxe;
Expand All @@ -28,7 +30,6 @@ const MNEMONIC = 'test test test test test test test test test test test junk';
const FEE_FUNDING_FOR_TESTER_ACCOUNT = 1000000000000000000n;

let walletClient = getL1WalletClient(foundry.rpcUrls.default.http[0], 0);
const ownerEthAddress = walletClient.account.address;

const publicClient = createPublicClient({
chain: foundry,
Expand All @@ -38,13 +39,11 @@ const publicClient = createPublicClient({
async function main() {

let pxe: PXE;
let wallets: AccountWallet[] = [];
let logger: Logger;

logger = createLogger('aztec:aztec-starter');

pxe = await setupSandbox();
wallets = await getInitialTestAccountsWallets(pxe);
const nodeInfo = (await pxe.getNodeInfo())

// Setup Schnorr AccountManager
Expand All @@ -53,6 +52,7 @@ async function main() {
let salt = Fr.random();
let schnorrAccount = await getSchnorrAccount(pxe, secretKey, deriveSigningKey(secretKey), salt);

const wallet1 = await deploySchnorrAccount()
const newWallet = await schnorrAccount.getWallet()
const feeJuiceReceipient = schnorrAccount.getAddress()

Expand All @@ -68,12 +68,15 @@ async function main() {

const claim = await feeJuicePortalManager.bridgeTokensPublic(feeJuiceReceipient, FEE_FUNDING_FOR_TESTER_ACCOUNT, true);

const feeJuice = await FeeJuiceContract.at(nodeInfo.protocolContractAddresses.feeJuice, wallets[0])
logger.info(`Fee Juice minted to ${feeJuiceReceipient} on L2.`)

// set up sponsored fee payments
const sponseredFPC = await getSponsoredFPCInstance();
await pxe.registerContract({instance: sponseredFPC, artifact: SponsoredFPCContract.artifact});
const paymentMethod = new SponsoredFeePaymentMethod(sponseredFPC.address);
// Two arbitraty txs to make the L1 message available on L2
const votingContract = await EasyPrivateVotingContract.deploy(wallets[0], wallets[0].getAddress()).send().deployed();
const bananaCoin = await TokenContract.deploy(wallets[0], wallets[0].getAddress(), "bananaCoin", "BNC", 18).send().deployed()
const votingContract = await EasyPrivateVotingContract.deploy(wallet1, wallet1.getAddress()).send({fee: {paymentMethod}}).deployed();
const bananaCoin = await TokenContract.deploy(wallet1, wallet1.getAddress(), "bananaCoin", "BNC", 18).send({fee: {paymentMethod}}).deployed()

// Claim Fee Juice & Pay Fees yourself

Expand All @@ -85,7 +88,7 @@ async function main() {

// Create a new voting contract instance, interacting from the newWallet
const useFeeJuice = new FeeJuicePaymentMethod(newWallet.getAddress())
await votingContract.withWallet(newWallet).methods.cast_vote(wallets[0].getAddress()).send({ fee: { paymentMethod: useFeeJuice }}).wait()
await votingContract.withWallet(newWallet).methods.cast_vote(wallet1.getAddress()).send({ fee: { paymentMethod: useFeeJuice }}).wait()
logger.info(`Vote cast from new account, paying fees via newWallet.`)

// Private Fee Payments via FPC
Expand All @@ -94,38 +97,41 @@ async function main() {
// Need to deploy an FPC to use Private Fee payment methods

// This uses bananaCoin as the fee paying asset that will be exchanged for fee juice
const fpc = await FPCContract.deploy(wallets[0], bananaCoin.address, wallets[0].getAddress()).send().deployed()
const fpc = await FPCContract.deploy(wallet1, bananaCoin.address, wallet1.getAddress()).send({fee: {paymentMethod}}).deployed()
const fpcClaim = await feeJuicePortalManager.bridgeTokensPublic(fpc.address, FEE_FUNDING_FOR_TESTER_ACCOUNT, true);
// 2 public txs to make the bridged fee juice available
// Mint some bananaCoin and send to the newWallet to pay fees privately
await bananaCoin.methods.mint_to_private(wallets[0].getAddress(), newWallet.getAddress(), FEE_FUNDING_FOR_TESTER_ACCOUNT).send().wait()
await bananaCoin.methods.mint_to_private(wallet1.getAddress(), newWallet.getAddress(), FEE_FUNDING_FOR_TESTER_ACCOUNT).send({fee: {paymentMethod}}).wait()
// mint some public bananaCoin to the newWallet to pay fees publicly
await bananaCoin.methods.mint_to_public(newWallet.getAddress(), FEE_FUNDING_FOR_TESTER_ACCOUNT).send().wait()
await bananaCoin.methods.mint_to_public(newWallet.getAddress(), FEE_FUNDING_FOR_TESTER_ACCOUNT).send({fee: {paymentMethod}}).wait()
const bananaBalance = await bananaCoin.withWallet(newWallet).methods.balance_of_private(newWallet.getAddress()).simulate()

logger.info(`BananaCoin balance of newWallet is ${bananaBalance}`)

const feeJuiceInstance = await getCanonicalFeeJuice();
// await pxe.registerContract({instance: feeJuiceInstance.instance, artifact: })
const feeJuice = await FeeJuiceContract.at(feeJuiceInstance.address, newWallet)
await feeJuice.methods.claim(fpc.address, fpcClaim.claimAmount, fpcClaim.claimSecret, fpcClaim.messageLeafIndex).send().wait()

logger.info(`Fpc fee juice balance ${await feeJuice.methods.balance_of_public(fpc.address).simulate()}`)

const privateFee = new PrivateFeePaymentMethod(fpc.address, newWallet)
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallets[0].getAddress(), 10, 0).send({ fee: { paymentMethod: privateFee }}).wait()
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallet1.getAddress(), 10, 0).send({ fee: { paymentMethod: privateFee }}).wait()

logger.info(`Transfer paid with fees via the FPC, privately.`)

// Public Fee Payments via FPC

const publicFee = new PublicFeePaymentMethod(fpc.address, newWallet)
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallets[0].getAddress(), 10, 0).send({ fee: { paymentMethod: publicFee }}).wait()
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallet1.getAddress(), 10, 0).send({ fee: { paymentMethod: publicFee }}).wait()
logger.info(`Transfer paid with fees via the FPC, publicly.`)

// Sponsored Fee Payment

// This method will only work in environments where there is a sponsored fee contract deployed
const deployedSponseredFPC = await getDeployedSponsoredFPCAddress(pxe);
const sponsoredPaymentMethod = new SponsoredFeePaymentMethod(deployedSponseredFPC);
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallets[0].getAddress(), 10, 0).send({ fee: { paymentMethod: sponsoredPaymentMethod }}).wait()
await bananaCoin.withWallet(newWallet).methods.transfer_in_private(newWallet.getAddress(), wallet1.getAddress(), 10, 0).send({ fee: { paymentMethod: sponsoredPaymentMethod }}).wait()
logger.info(`Transfer paid with fees from Sponsored FPC.`)
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/getBlock.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PXE, waitForPXE, createPXEClient } from "@aztec/aztec.js";

const setupSandbox = async () => {
const { PXE_URL = 'http://localhost:8080' } = process.env;
const { PXE_URL = 'http://localhost:8081' } = process.env;
const pxe = await createPXEClient(PXE_URL);
await waitForPXE(pxe);
return pxe;
Expand Down
2 changes: 1 addition & 1 deletion src/test/e2e/accounts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createEthereumChain, createL1Clients } from '@aztec/ethereum';
import { getDeployedSponsoredFPCAddress } from "../../utils/sponsored_fpc.js";

const setupSandbox = async () => {
const { PXE_URL = 'http://localhost:8080' } = process.env;
const { PXE_URL = 'http://localhost:8081' } = process.env;
const pxe = createPXEClient(PXE_URL);
await waitForPXE(pxe);
return pxe;
Expand Down
12 changes: 1 addition & 11 deletions src/utils/sponsored_fpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import {
type ContractInstanceWithAddress,
Fr,
type PXE,
type Wallet,
getContractInstanceFromDeployParams,
} from '@aztec/aztec.js';
import type { LogFn } from '@aztec/foundation/log';
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';

const SPONSORED_FPC_SALT = new Fr(0);

async function getSponsoredFPCInstance(): Promise<ContractInstanceWithAddress> {
export async function getSponsoredFPCInstance(): Promise<ContractInstanceWithAddress> {
return await getContractInstanceFromDeployParams(SponsoredFPCContract.artifact, {
salt: SPONSORED_FPC_SALT,
});
Expand All @@ -20,14 +18,6 @@ export async function getSponsoredFPCAddress() {
return (await getSponsoredFPCInstance()).address;
}

export async function setupSponsoredFPC(deployer: Wallet, log: LogFn) {
const deployed = await SponsoredFPCContract.deploy(deployer)
.send({ contractAddressSalt: SPONSORED_FPC_SALT, universalDeploy: true })
.deployed();

log(`SponsoredFPC: ${deployed.address}`);
}

export async function getDeployedSponsoredFPCAddress(pxe: PXE) {
const fpc = await getSponsoredFPCAddress();
const contracts = await pxe.getContracts();
Expand Down