Skip to content
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

docs: updating key docs in concepts section #6387

Merged
merged 16 commits into from
May 16, 2024
190 changes: 130 additions & 60 deletions docs/docs/aztec/aztec/concepts/accounts/keys.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,15 @@ Unlike on Ethereum, there are 2 types of events supported by Aztec: [encrypted](

Encrypted events can only be emitted by private functions and are encrypted using a public key of a recipient.
For this reason it is necessary to register a recipient in the Private Execution Environment (PXE) before encrypting the events for them.
Recipients can be registered using Aztec.js:

```ts
const aztecAddress = AztecAddress.fromString(
"0x147392a39e593189902458f4303bc6e0a39128c5a1c1612f76527a162d36d529"
);
const publicKey = Point.fromString(
"0x26e193aef4f83c70651485b5526c6d01a36d763223ab24efd1f9ff91b394ac0c20ad99d0ef669dc0dde8d5f5996c63105de8e15c2c87d8260b9e6f02f72af622"
);
const partialAddress = Fr.fromString(
"0x200e9a6c2d2e8352012e51c6637659713d336405c29386c7c4ac56779ab54fa7"
);

const completeAddress = new CompleteAddress(
aztecAddress,
publicKey,
partialKey
);
await pxe.registerRecipient(completeAddress);
```

First we need to get a hold of recipient's [complete address](#complete-address).
Bellow are some ways how we could instantiate it after getting the information in a string form from a recipient:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below


#include_code instantiate-complete-address /yarn-project/circuits.js/src/structs/complete_address.test.ts rust

Then to register the recipient's [complete address](/aztec/aztec/concepts/accounts/keys.md#complete-address) in PXE we would call `registerRecipient` PXE endpoint using [Aztec.js](/aztec/aztec/core_components.md#aztecjs):

#include_code register-recipient /yarn-project/aztec.js/src/wallet/create_recipient.ts rust

:::info
If a note recipient is one of the accounts inside the PXE, we don't need to register it as a recipient because we already have the public key available. You can register a recipient as shown [here](../how_to_deploy_contract.md)
Expand Down
2 changes: 2 additions & 0 deletions noir-projects/aztec-nr/aztec/src/keys/getters.nr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{

global DELAY = 5;

// docs:start:key-getters
pub fn get_npk_m(context: &mut PrivateContext, address: AztecAddress) -> GrumpkinPoint {
get_master_key(context, address, NULLIFIER_INDEX)
}
Expand All @@ -34,6 +35,7 @@ pub fn get_ivpk_m(context: &mut PrivateContext, address: AztecAddress) -> Grumpk
// pub fn get_tpk_m(context: &mut PrivateContext, address: AztecAddress) -> GrumpkinPoint {
// get_master_key(context, address, TAGGING_INDEX)
// }
// docs:end:key-getters

fn get_master_key(
context: &mut PrivateContext,
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/wallet/create_recipient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { CompleteAddress } from '@aztec/circuits.js';
*/
export async function createRecipient(pxe: PXE): Promise<CompleteAddress> {
const completeAddress = CompleteAddress.random();
// docs:start:register-recipient
await pxe.registerRecipient(completeAddress);
// docs:end:register-recipient
return completeAddress;
}
34 changes: 34 additions & 0 deletions yarn-project/circuits.js/src/structs/complete_address.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,38 @@ describe('CompleteAddress', () => {
const address = CompleteAddress.fromBuffer(expectedAddress.toBuffer());
expect(address.equals(expectedAddress)).toBe(true);
});

it('instantiates from string and individual components', () => {
// docs:start:instantiate-complete-address
// Typically a recipient would share their complete address with the sender
const completeAddressFromString = CompleteAddress.fromString(
'0x09bc7031bb21627cce6aac1dc710ecc92acd8475149c530a4bb57df63d9d6fe902a9372135ce5b49b46102732fabd742c31642543396013dde5b460075864607264c605bc115c6cb92a4db0a6b893fd3777341078693d0af22e3ff53f4c2ee2a2fae73914fc50d325e2707a8e996f1ad498429f715f998225dc6bd2ede05aaee055ee137d28b634322e0ea98afc42dfc48833e8d2879c34d23d6d1d337069cca212af0f28b7865b339e202a0077fd3bd8dddc472d055945ad99c02dcccd28bb22bb3585fca3e5751c9913521a390458d63e4d9b292e4872582f3b13da214470c14083a4567cf4f1e92696e6c01923bc6a8b414159446268b12fe8669ce44f1f5196561aca6c654d2405a5653002cba5552b50b6ce1afc9515ed6682507abcb3010040d791aeb30138efc9c7d36b47684af2f26f686672448349f05934ae7bbbf',
);

// Alternatively, a recipient could share the individual components with the sender
const address = Fr.fromString('0x09bc7031bb21627cce6aac1dc710ecc92acd8475149c530a4bb57df63d9d6fe9');
const npkM = Point.fromString(
'0x02a9372135ce5b49b46102732fabd742c31642543396013dde5b460075864607264c605bc115c6cb92a4db0a6b893fd3777341078693d0af22e3ff53f4c2ee2a',
);
const ivpkM = Point.fromString(
'0x2fae73914fc50d325e2707a8e996f1ad498429f715f998225dc6bd2ede05aaee055ee137d28b634322e0ea98afc42dfc48833e8d2879c34d23d6d1d337069cca',
);
const ovpkM = Point.fromString(
'0x212af0f28b7865b339e202a0077fd3bd8dddc472d055945ad99c02dcccd28bb22bb3585fca3e5751c9913521a390458d63e4d9b292e4872582f3b13da214470c',
);
const tpkM = Point.fromString(
'0x14083a4567cf4f1e92696e6c01923bc6a8b414159446268b12fe8669ce44f1f5196561aca6c654d2405a5653002cba5552b50b6ce1afc9515ed6682507abcb30',
);

const partialAddress = Fr.fromString('0x10040d791aeb30138efc9c7d36b47684af2f26f686672448349f05934ae7bbbf');

const completeAddressFromComponents = new CompleteAddress(
address,
new PublicKeys(npkM, ivpkM, ovpkM, tpkM),
partialAddress,
);
// docs:end:instantiate-complete-address

expect(completeAddressFromComponents.equals(completeAddressFromString)).toBe(true);
});
});
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/e2e_key_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,13 @@ describe('Key Registry', () => {
const secondNewMasterNullifierPublicKey = Point.random();

it('rotates npk_m', async () => {
// docs:start:key-rotation
await keyRegistry
.withWallet(wallets[0])
.methods.rotate_npk_m(wallets[0].getAddress(), firstNewMasterNullifierPublicKey, Fr.ZERO)
.send()
.wait();
// docs:end:key-rotation

// We check if our rotated nullifier key is equal to the key obtained from the getter by reading our registry
// contract from the test contract. We expect this to fail because the change has not been applied yet
Expand Down
47 changes: 24 additions & 23 deletions yarn-project/end-to-end/src/flakey_e2e_account_init_fees.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { getSchnorrAccount } from '@aztec/accounts/schnorr';
Copy link
Contributor Author

@benesjan benesjan May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to include some code of this test in docs and I felt that the use of ctx instead of destructuring made it harder to read so I changed that.

import {
type AccountManager,
type AztecNode,
type DebugLogger,
type DeployL1Contracts,
ExtendedNote,
Fr,
NativeFeePaymentMethod,
Note,
type PXE,
PrivateFeePaymentMethod,
PublicFeePaymentMethod,
Schnorr,
Expand All @@ -25,14 +28,7 @@ import {

import { jest } from '@jest/globals';

import {
type BalancesFn,
type EndToEndContext,
expectMapping,
getBalancesFn,
publicDeployAccounts,
setup,
} from './fixtures/utils.js';
import { type BalancesFn, expectMapping, getBalancesFn, publicDeployAccounts, setup } from './fixtures/utils.js';
import { GasPortalTestingHarnessFactory, type IGasBridgingTestHarness } from './shared/gas_portal_test_harness.js';

const TOKEN_NAME = 'BananaCoin';
Expand All @@ -43,8 +39,11 @@ const BRIDGED_FPC_GAS = BigInt(10e12);
jest.setTimeout(1_000_000);

describe('e2e_fees_account_init', () => {
let ctx: EndToEndContext;
let logger: DebugLogger;
let aztecNode: AztecNode;
let pxe: PXE;
let teardown: () => Promise<void>;

let sequencer: Wallet;
let sequencersAddress: AztecAddress;
let alice: Wallet;
Expand Down Expand Up @@ -84,22 +83,24 @@ describe('e2e_fees_account_init', () => {
}

beforeAll(async () => {
ctx = await setup(2, {}, {}, true);
logger = ctx.logger;
[sequencer, alice] = ctx.wallets;
let wallets: Wallet[];
let wallet: Wallet;
let deployL1ContractsValues: DeployL1Contracts;
({ logger, wallets, wallet, aztecNode, pxe, deployL1ContractsValues } = await setup(2, {}, {}, true));
[sequencer, alice] = wallets;
sequencersAddress = sequencer.getAddress();

await ctx.aztecNode.setConfig({
await aztecNode.setConfig({
feeRecipient: sequencersAddress,
});

gasBridgeTestHarness = await GasPortalTestingHarnessFactory.create({
aztecNode: ctx.aztecNode,
pxeService: ctx.pxe,
publicClient: ctx.deployL1ContractsValues.publicClient,
walletClient: ctx.deployL1ContractsValues.walletClient,
wallet: ctx.wallet,
logger: ctx.logger,
aztecNode,
pxeService: pxe,
publicClient: deployL1ContractsValues.publicClient,
walletClient: deployL1ContractsValues.walletClient,
wallet,
logger,
mockL1: false,
});

Expand All @@ -122,15 +123,15 @@ describe('e2e_fees_account_init', () => {
gasBalances = getBalancesFn('⛽', gas.methods.balance_of_public, logger);
});

afterAll(() => ctx.teardown());
afterAll(() => teardown());

beforeEach(() => {
gasSettings = GasSettings.default();
maxFee = gasSettings.getFeeLimit().toBigInt();
actualFee = 1n;
bobsSecretKey = Fr.random();
bobsPrivateSigningKey = Fq.random();
bobsAccountManager = getSchnorrAccount(ctx.pxe, bobsSecretKey, bobsPrivateSigningKey, Fr.random());
bobsAccountManager = getSchnorrAccount(pxe, bobsSecretKey, bobsPrivateSigningKey, Fr.random());
bobsAddress = bobsAccountManager.getCompleteAddress().address;
});

Expand Down Expand Up @@ -292,7 +293,7 @@ describe('e2e_fees_account_init', () => {
const completeAddress = CompleteAddress.fromSecretKeyAndInstance(bobsSecretKey, instance);

// alice registers the keys in the PXE
await ctx.pxe.registerRecipient(completeAddress);
await pxe.registerRecipient(completeAddress);

// and deploys bob's account, paying the fee from her balance
const publicKeysHash = deriveKeys(bobsSecretKey).publicKeys.hash();
Expand Down Expand Up @@ -339,6 +340,6 @@ describe('e2e_fees_account_init', () => {
const note = new Note([new Fr(amount), secretHash]);
// this note isn't encrypted but we need to provide a registered public key
const extendedNote = new ExtendedNote(note, owner, bananaCoin.address, storageSlot, noteTypeId, txHash);
await ctx.pxe.addNote(extendedNote);
await pxe.addNote(extendedNote);
}
});
Loading