Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
sklppy88 committed Oct 30, 2024
1 parent 069c912 commit f0b49f5
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 15 deletions.
6 changes: 6 additions & 0 deletions yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ export abstract class BaseWallet implements Wallet {
getRegisteredAccount(address: AztecAddress): Promise<CompleteAddress | undefined> {
return this.pxe.getRegisteredAccount(address);
}
registerContact(address: AztecAddress): Promise<AztecAddress> {
return this.pxe.registerContact(address);
}
getContacts(): Promise<AztecAddress[]> {
return this.pxe.getContacts();
}
registerContract(contract: {
/** Instance */ instance: ContractInstanceWithAddress;
/** Associated artifact */ artifact?: ContractArtifact;
Expand Down
21 changes: 19 additions & 2 deletions yarn-project/circuit-types/src/interfaces/pxe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,23 @@ export interface PXE {
*/
getRegisteredAccount(address: AztecAddress): Promise<CompleteAddress | undefined>;

/**
* Registers a user contact in PXE.
*
* Once a new contact is registered, the PXE Service will be able to receive notes tagged from this contact.
* Will do nothing if the account is already registered.
*
* @param address - Address of the user to add to the address book
* @returns The address address of the account.
*/
registerContact(address: AztecAddress): Promise<AztecAddress>;

/**
* Retrieves the addresses stored as contacts on this PXE Service.
* @returns An array of the contacts on this PXE Service.
*/
getContacts(): Promise<AztecAddress[]>;

/**
* Registers a contract class in the PXE without registering any associated contract instance with it.
*
Expand Down Expand Up @@ -333,15 +350,15 @@ export interface PXE {
getSyncStats(): Promise<{ [key: string]: NoteProcessorStats }>;

/**
* Returns a Contact Instance given its address, which includes the contract class identifier,
* Returns a Contract Instance given its address, which includes the contract class identifier,
* initialization hash, deployment salt, and public keys hash.
* 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 Contact Class given its identifier.
* 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.
Expand Down
43 changes: 30 additions & 13 deletions yarn-project/pxe/src/database/kv_pxe_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ import { type PxeDatabase } from './pxe_database.js';
*/
export class KVPxeDatabase implements PxeDatabase {
#synchronizedBlock: AztecSingleton<Buffer>;
#addresses: AztecArray<Buffer>;
#addressIndex: AztecMap<string, number>;
#completeAddresses: AztecArray<Buffer>;
#completeAddressIndex: AztecMap<string, number>;
#addressBook: AztecSet<string>;
#authWitnesses: AztecMap<string, Buffer[]>;
#capsules: AztecArray<Buffer[]>;
#notes: AztecMap<string, Buffer>;
Expand Down Expand Up @@ -72,8 +73,10 @@ export class KVPxeDatabase implements PxeDatabase {
constructor(private db: AztecKVStore) {
this.#db = db;

this.#addresses = db.openArray('addresses');
this.#addressIndex = db.openMap('address_index');
this.#completeAddresses = db.openArray('addresses');
this.#completeAddressIndex = db.openMap('address_index');

this.#addressBook = db.openSet('address_book');

this.#authWitnesses = db.openMap('auth_witnesses');
this.#capsules = db.openArray('capsules');
Expand Down Expand Up @@ -509,15 +512,15 @@ export class KVPxeDatabase implements PxeDatabase {
return this.#db.transaction(() => {
const addressString = completeAddress.address.toString();
const buffer = completeAddress.toBuffer();
const existing = this.#addressIndex.get(addressString);
const existing = this.#completeAddressIndex.get(addressString);
if (typeof existing === 'undefined') {
const index = this.#addresses.length;
void this.#addresses.push(buffer);
void this.#addressIndex.set(addressString, index);
const index = this.#completeAddresses.length;
void this.#completeAddresses.push(buffer);
void this.#completeAddressIndex.set(addressString, index);

return true;
} else {
const existingBuffer = this.#addresses.at(existing);
const existingBuffer = this.#completeAddresses.at(existing);

if (existingBuffer?.equals(buffer)) {
return false;
Expand All @@ -531,12 +534,12 @@ export class KVPxeDatabase implements PxeDatabase {
}

#getCompleteAddress(address: AztecAddress): CompleteAddress | undefined {
const index = this.#addressIndex.get(address.toString());
const index = this.#completeAddressIndex.get(address.toString());
if (typeof index === 'undefined') {
return undefined;
}

const value = this.#addresses.at(index);
const value = this.#completeAddresses.at(index);
return value ? CompleteAddress.fromBuffer(value) : undefined;
}

Expand All @@ -545,7 +548,21 @@ export class KVPxeDatabase implements PxeDatabase {
}

getCompleteAddresses(): Promise<CompleteAddress[]> {
return Promise.resolve(Array.from(this.#addresses).map(v => CompleteAddress.fromBuffer(v)));
return Promise.resolve(Array.from(this.#completeAddresses).map(v => CompleteAddress.fromBuffer(v)));
}

async addContactAddress(address: AztecAddress): Promise<boolean> {
if (this.#addressBook.has(address.toString())) {
return false;
}

await this.#addressBook.add(address.toString());

return true;
}

getContactAddresses(): AztecAddress[] {
return [...this.#addressBook.entries()].map(AztecAddress.fromString);
}

getSynchedBlockNumberForAccount(account: AztecAddress): number | undefined {
Expand All @@ -570,7 +587,7 @@ export class KVPxeDatabase implements PxeDatabase {
(sum, value) => sum + value.length * Fr.SIZE_IN_BYTES,
0,
);
const addressesSize = this.#addresses.length * CompleteAddress.SIZE_IN_BYTES;
const addressesSize = this.#completeAddresses.length * CompleteAddress.SIZE_IN_BYTES;
const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;

return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize;
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/pxe/src/database/pxe_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
*/
setHeader(header: Header): Promise<void>;

addContactAddress(address: AztecAddress): Promise<boolean>;

getContactAddresses(): AztecAddress[];

/**
* Adds complete address to the database.
* @param address - The complete address to add.
Expand Down
24 changes: 24 additions & 0 deletions yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,30 @@ export class PXEService implements PXE {
return accountCompleteAddress;
}

public async registerContact(address: AztecAddress): Promise<AztecAddress> {
const accounts = await this.keyStore.getAccounts();
if (accounts.includes(address)) {
this.log.info(`Account:\n "${address.toString()}"\n already registered.`);
return address;
}

const wasAdded = await this.db.addContactAddress(address);

if (wasAdded) {
this.log.info(`Added contact:\n ${address.toString()}`);
} else {
this.log.info(`Contact:\n "${address.toString()}"\n already registered.`);
}

return address;
}

public getContacts(): Promise<AztecAddress[]> {
const contacts = this.db.getContactAddresses();

return Promise.resolve(contacts);
}

public async getRegisteredAccounts(): Promise<CompleteAddress[]> {
// Get complete addresses of both the recipients and the accounts
const completeAddresses = await this.db.getCompleteAddresses();
Expand Down
10 changes: 10 additions & 0 deletions yarn-project/pxe/src/simulator_oracle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,16 @@ export class SimulatorOracle implements DBOracle {
return this.contractDataOracle.getDebugFunctionName(contractAddress, selector);
}

/**
* Returns the full contents of your address book.
* This is used when calculating tags for incoming notes by deriving the shared secret, the contract-siloed tagging secret, and
* finally the index specified tag. We will then query the node with this tag for each address in the address book.
* @returns The full list of the users contact addresses.
*/
public getContacts(): AztecAddress[] {
return this.db.getContactAddresses();
}

/**
* Returns the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known.
* Includes the last known index used for tagging with this secret.
Expand Down

0 comments on commit f0b49f5

Please sign in to comment.