Skip to content

Commit 378407d

Browse files
authored
chore: aztec js circulars (AztecProtocol#3723)
* This attempts to unpick aztec.js. * Unfortunately, there was some heavy spaghettification here. There was no clear separation between most of the modules, with a lot of circular references. * I've had to move things around to get the structure sound, but now there are things in places that are named unintuitively. One major example being `Wallet` now being in the `account` module. * I think simply renaming some things, or e.g. introducing another module with tighter scope is the next step. * I flattened aztec.js a bit to try and make some sense. I also introduced `create_account` as the highest level module. * This definitely is not "complete" in terms of fixing the names/comments etc, but if agreed it's a good first step we can merge and iterate. Here are some notes I took as I picked apart. Each module and its dependencies: ``` account: account_contract: account contract: account contract_deployer: contract wallet: account account_contract contract account_manager: contract contract_deployer wallet account account_contract create_account: account_manager wallet ```
1 parent a1c701d commit 378407d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+331
-2656
lines changed

build_manifest.yml

-12
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,6 @@ aztec-faucet:
149149
dependencies:
150150
- yarn-project-prod
151151

152-
aztec-node:
153-
buildDir: yarn-project
154-
projectDir: yarn-project/aztec-node
155-
dependencies:
156-
- yarn-project-prod
157-
158-
p2p-bootstrap:
159-
buildDir: yarn-project
160-
projectDir: yarn-project/p2p-bootstrap
161-
dependencies:
162-
- yarn-project-prod
163-
164152
cli:
165153
buildDir: yarn-project
166154
projectDir: yarn-project/cli

docs/docs/dev_docs/wallets/main.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Wallets
22

3-
Wallets are the applications through which users manage their accounts. Users rely on wallets to browse through their accounts, monitor their balances, and create new accounts. Wallets also store seed phrases and private keys, or interact with external keystores such as hardware wallets.
3+
Wallets are the applications through which users manage their accounts. Users rely on wallets to browse through their accounts, monitor their balances, and create new accounts. Wallets also store seed phrases and private keys, or interact with external keystores such as hardware wallets.
44

55
Wallets also provide an interface for dapps. Dapps may request access to see the user accounts, in order to show the state of those accounts in the context of the application, and request to send transactions from those accounts as the user interacts with the dapp.
66

@@ -10,9 +10,9 @@ In this page we will cover the main responsibilities of a wallet in the Aztec ne
1010

1111
## Account setup
1212

13-
The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is represented on-chain by its corresponding account contract that the user must deploy to begin interacting with the network. This account contract dictates how transactions are authenticated and executed.
13+
The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is represented on-chain by its corresponding account contract that the user must deploy to begin interacting with the network. This account contract dictates how transactions are authenticated and executed.
1414

15-
A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as interacting with it when sending transactions. Code-wise, this requires [implementing the `AccountContract` interface](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/account/contract/index.ts).
15+
A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as interacting with it when sending transactions. Code-wise, this requires [implementing the `AccountContract` interface](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/account_contract/index.ts).
1616

1717
Note that users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share it with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialization arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin.
1818

@@ -64,4 +64,3 @@ At the time of this writing, all private state is encrypted and broadcasted thro
6464
Encrypted data blobs do not carry any public information as to whom their recipient is. Therefore, it is not possible for a remote node to identify the notes that belong to a user, and it is not possible for a wallet to query a remote node for its private state. As such, wallets need to keep a local database of their accounts private state, in order to be able to answer any queries on their private state.
6565

6666
Dapps may require access to the user's private state, in order to show information relevant to the current application. For instance, a dapp for a token may require access to the user's private notes in the token contract in order to display the user's balance. It is responsibility of the wallet to require authorization from the user before disclosing private state to a dapp.
67-

docs/docs/dev_docs/wallets/writing_an_account_contract.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ For our account contract, we will take the hash of the action to authorize, requ
6161

6262
Now that we have a valid account contract, we need to write the typescript glue code that will take care of formatting and authenticating transactions so they can be processed by our contract, as well as deploying the contract during account setup. This takes the form of implementing the `AccountContract` interface:
6363

64-
#include_code account-contract-interface yarn-project/aztec.js/src/account/contract/index.ts typescript
64+
#include_code account-contract-interface yarn-project/aztec.js/src/account_contract/account_contract.ts typescript
6565

6666
However, if you are using the default `AccountActions` module, then you can leverage the `BaseAccountContract` class and just implement the logic for generating an auth witness that matches the one you wrote in Noir:
6767

yarn-project/Dockerfile.prod

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ RUN ARCH= && \
4646
rm "node-v$NODE_VERSION-linux-$ARCH.tar.gz" && \
4747
node --version
4848
COPY --from=builder /usr/src /usr/src
49-
ENTRYPOINT ["/usr/bin/node"]
49+
ENTRYPOINT ["/usr/bin/node"]

yarn-project/aztec.js/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/account_contract/artifacts

yarn-project/aztec.js/src/account/defaults/entrypoint_payload.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { pedersenHash } from '@aztec/foundation/crypto';
44
import { FunctionCall, PackedArguments, emptyFunctionCall } from '@aztec/types';
55

66
// These must match the values defined in yarn-project/aztec-nr/aztec/src/entrypoint.nr
7-
export const ACCOUNT_MAX_CALLS = 4;
7+
const ACCOUNT_MAX_CALLS = 4;
88

99
/** Encoded function call for account contract entrypoint */
10-
export type EntrypointFunctionCall = {
10+
type EntrypointFunctionCall = {
1111
// eslint-disable-next-line camelcase
1212
/** Arguments hash for the call */
1313
args_hash: Fr;
@@ -76,7 +76,7 @@ export function hashPayload(payload: EntrypointPayload) {
7676
}
7777

7878
/** Flattens an entrypoint payload */
79-
export function flattenPayload(payload: EntrypointPayload) {
79+
function flattenPayload(payload: EntrypointPayload) {
8080
return [
8181
...payload.function_calls.flatMap(call => [
8282
call.args_hash,

yarn-project/aztec.js/src/account/index.ts

+3-96
Original file line numberDiff line numberDiff line change
@@ -19,106 +19,13 @@
1919
*
2020
* @packageDocumentation
2121
*/
22-
import { CompleteAddress, GrumpkinPrivateKey, PXE } from '@aztec/types';
22+
import { Fr } from '@aztec/circuits.js';
2323

24-
import { AccountContract, AccountWallet, AztecAddress, Fr } from '../index.js';
25-
import { EcdsaAccountContract } from './contract/ecdsa_account_contract.js';
26-
import { SchnorrAccountContract } from './contract/schnorr_account_contract.js';
27-
import { SingleKeyAccountContract } from './contract/single_key_account_contract.js';
28-
import { AccountManager } from './manager/index.js';
24+
export { CompleteAddress } from '@aztec/types';
2925

30-
export * from './contract/index.js';
3126
export * from './defaults/index.js';
32-
export * from './utils.js';
3327
export { AccountInterface, AuthWitnessProvider } from './interface.js';
34-
export { AccountManager, CompleteAddress };
28+
export * from './wallet.js';
3529

3630
/** A contract deployment salt. */
3731
export type Salt = Fr | number | bigint;
38-
39-
/**
40-
* Creates an Account that relies on an ECDSA signing key for authentication.
41-
* @param pxe - An PXE server instance.
42-
* @param encryptionPrivateKey - Grumpkin key used for note encryption.
43-
* @param signingPrivateKey - Secp256k1 key used for signing transactions.
44-
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
45-
*/
46-
export function getEcdsaAccount(
47-
pxe: PXE,
48-
encryptionPrivateKey: GrumpkinPrivateKey,
49-
signingPrivateKey: Buffer,
50-
saltOrAddress?: Salt | CompleteAddress,
51-
): AccountManager {
52-
return new AccountManager(pxe, encryptionPrivateKey, new EcdsaAccountContract(signingPrivateKey), saltOrAddress);
53-
}
54-
55-
/**
56-
* Creates an Account that relies on a Grumpkin signing key for authentication.
57-
* @param pxe - An PXE server instance.
58-
* @param encryptionPrivateKey - Grumpkin key used for note encryption.
59-
* @param signingPrivateKey - Grumpkin key used for signing transactions.
60-
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
61-
*/
62-
export function getSchnorrAccount(
63-
pxe: PXE,
64-
encryptionPrivateKey: GrumpkinPrivateKey,
65-
signingPrivateKey: GrumpkinPrivateKey,
66-
saltOrAddress?: Salt | CompleteAddress,
67-
): AccountManager {
68-
return new AccountManager(pxe, encryptionPrivateKey, new SchnorrAccountContract(signingPrivateKey), saltOrAddress);
69-
}
70-
71-
/**
72-
* Creates an Account that uses the same Grumpkin key for encryption and authentication.
73-
* @param pxe - An PXE server instance.
74-
* @param encryptionAndSigningPrivateKey - Grumpkin key used for note encryption and signing transactions.
75-
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
76-
*/
77-
export function getUnsafeSchnorrAccount(
78-
pxe: PXE,
79-
encryptionAndSigningPrivateKey: GrumpkinPrivateKey,
80-
saltOrAddress?: Salt | CompleteAddress,
81-
): AccountManager {
82-
return new AccountManager(
83-
pxe,
84-
encryptionAndSigningPrivateKey,
85-
new SingleKeyAccountContract(encryptionAndSigningPrivateKey),
86-
saltOrAddress,
87-
);
88-
}
89-
90-
/**
91-
* Gets a wallet for an already registered account using Schnorr signatures with a single key for encryption and authentication.
92-
* @param pxe - An PXE server instance.
93-
* @param address - Address for the account.
94-
* @param signingPrivateKey - Grumpkin key used for note encryption and signing transactions.
95-
* @returns A wallet for this account that can be used to interact with a contract instance.
96-
*/
97-
export function getUnsafeSchnorrWallet(
98-
pxe: PXE,
99-
address: AztecAddress,
100-
signingKey: GrumpkinPrivateKey,
101-
): Promise<AccountWallet> {
102-
return getWallet(pxe, address, new SingleKeyAccountContract(signingKey));
103-
}
104-
105-
/**
106-
* Gets a wallet for an already registered account.
107-
* @param pxe - PXE Service instance.
108-
* @param address - Address for the account.
109-
* @param accountContract - Account contract implementation.
110-
* @returns A wallet for this account that can be used to interact with a contract instance.
111-
*/
112-
export async function getWallet(
113-
pxe: PXE,
114-
address: AztecAddress,
115-
accountContract: AccountContract,
116-
): Promise<AccountWallet> {
117-
const completeAddress = await pxe.getRegisteredAccount(address);
118-
if (!completeAddress) {
119-
throw new Error(`Account ${address} not found`);
120-
}
121-
const nodeInfo = await pxe.getNodeInfo();
122-
const entrypoint = accountContract.getInterface(completeAddress, nodeInfo);
123-
return new AccountWallet(pxe, entrypoint);
124-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { PXE } from '@aztec/types';
2+
3+
import { AccountInterface } from './interface.js';
4+
5+
/**
6+
* The wallet interface.
7+
*/
8+
export type Wallet = AccountInterface & PXE;

yarn-project/aztec.js/src/account/contract/index.ts yarn-project/aztec.js/src/account_contract/account_contract.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { ContractArtifact } from '@aztec/foundation/abi';
22
import { CompleteAddress, NodeInfo } from '@aztec/types';
33

4-
import { AccountInterface } from '../interface.js';
5-
6-
export * from './ecdsa_account_contract.js';
7-
export * from './schnorr_account_contract.js';
8-
export * from './single_key_account_contract.js';
9-
export * from './base_account_contract.js';
4+
import { AccountInterface } from '../account/interface.js';
105

116
// docs:start:account-contract-interface
127
/**

yarn-project/aztec.js/src/account/contract/base_account_contract.ts yarn-project/aztec.js/src/account_contract/base_account_contract.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { ContractArtifact } from '@aztec/foundation/abi';
22
import { CompleteAddress, NodeInfo } from '@aztec/types';
33

4-
import { DefaultAccountInterface } from '../defaults/default_interface.js';
5-
import { AccountInterface, AuthWitnessProvider } from '../interface.js';
6-
import { AccountContract } from './index.js';
4+
import { DefaultAccountInterface } from '../account/defaults/default_interface.js';
5+
import { AccountInterface, AuthWitnessProvider } from '../account/interface.js';
6+
import { AccountContract } from './account_contract.js';
77

88
/**
99
* Base class for implementing an account contract. Requires that the account uses the

yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts yarn-project/aztec.js/src/account_contract/ecdsa_account_contract.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { ContractArtifact } from '@aztec/foundation/abi';
33
import { Fr } from '@aztec/foundation/fields';
44
import { AuthWitness, CompleteAddress } from '@aztec/types';
55

6-
import EcdsaAccountContractArtifact from '../../artifacts/ecdsa_account_contract.json' assert { type: 'json' };
7-
import { AuthWitnessProvider } from '../interface.js';
6+
import { AuthWitnessProvider } from '../account/interface.js';
7+
import EcdsaAccountContractArtifact from './artifacts/ecdsa_account_contract.json' assert { type: 'json' };
88
import { BaseAccountContract } from './base_account_contract.js';
99

1010
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './account_contract.js';
2+
export * from './ecdsa_account_contract.js';
3+
export * from './schnorr_account_contract.js';
4+
export * from './single_key_account_contract.js';
5+
export * from './base_account_contract.js';

yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts yarn-project/aztec.js/src/account_contract/schnorr_account_contract.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { ContractArtifact } from '@aztec/foundation/abi';
33
import { Fr } from '@aztec/foundation/fields';
44
import { AuthWitness, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types';
55

6-
import SchnorrAccountContractArtifact from '../../artifacts/schnorr_account_contract.json' assert { type: 'json' };
7-
import { AuthWitnessProvider } from '../interface.js';
6+
import { AuthWitnessProvider } from '../account/interface.js';
7+
import SchnorrAccountContractArtifact from './artifacts/schnorr_account_contract.json' assert { type: 'json' };
88
import { BaseAccountContract } from './base_account_contract.js';
99

1010
/**

yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts yarn-project/aztec.js/src/account_contract/single_key_account_contract.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { ContractArtifact } from '@aztec/foundation/abi';
44
import { Fr } from '@aztec/foundation/fields';
55
import { AuthWitness, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types';
66

7-
import SchnorrSingleKeyAccountContractArtifact from '../../artifacts/schnorr_single_key_account_contract.json' assert { type: 'json' };
8-
import { generatePublicKey } from '../../index.js';
9-
import { AuthWitnessProvider } from '../interface.js';
7+
import { AuthWitnessProvider } from '../account/interface.js';
8+
import { generatePublicKey } from '../utils/index.js';
9+
import SchnorrSingleKeyAccountContractArtifact from './artifacts/schnorr_single_key_account_contract.json' assert { type: 'json' };
1010
import { BaseAccountContract } from './base_account_contract.js';
1111

1212
/**

yarn-project/aztec.js/src/account/manager/deploy_account_sent_tx.ts yarn-project/aztec.js/src/account_manager/deploy_account_sent_tx.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { FieldsOf } from '@aztec/circuits.js';
22
import { TxHash, TxReceipt } from '@aztec/types';
33

4-
import { DefaultWaitOpts, SentTx, WaitOpts } from '../../contract/sent_tx.js';
5-
import { Wallet } from '../../wallet/index.js';
4+
import { Wallet } from '../account/index.js';
5+
import { DefaultWaitOpts, SentTx, WaitOpts } from '../contract/index.js';
66
import { waitForAccountSynch } from './util.js';
77

88
/** Extends a transaction receipt with a wallet instance for the newly deployed contract. */

yarn-project/aztec.js/src/account/manager/index.ts yarn-project/aztec.js/src/account_manager/index.ts

+62-9
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import { PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js';
22
import { Fr } from '@aztec/foundation/fields';
33
import { CompleteAddress, GrumpkinPrivateKey, PXE } from '@aztec/types';
44

5-
import { DefaultWaitOpts } from '../../contract/sent_tx.js';
5+
import { Salt } from '../account/index.js';
6+
import { AccountInterface } from '../account/interface.js';
67
import {
7-
AccountWalletWithPrivateKey,
8-
ContractDeployer,
9-
DeployMethod,
10-
WaitOpts,
11-
generatePublicKey,
12-
} from '../../index.js';
13-
import { AccountContract, Salt } from '../index.js';
14-
import { AccountInterface } from '../interface.js';
8+
AccountContract,
9+
EcdsaAccountContract,
10+
SchnorrAccountContract,
11+
SingleKeyAccountContract,
12+
} from '../account_contract/index.js';
13+
import { DefaultWaitOpts, DeployMethod, WaitOpts } from '../contract/index.js';
14+
import { ContractDeployer } from '../contract_deployer/index.js';
15+
import { generatePublicKey } from '../utils/index.js';
16+
import { AccountWalletWithPrivateKey } from '../wallet/index.js';
1517
import { DeployAccountSentTx } from './deploy_account_sent_tx.js';
1618
import { waitForAccountSynch } from './util.js';
1719

@@ -154,3 +156,54 @@ export class AccountManager {
154156
return completeAddress;
155157
}
156158
}
159+
160+
/**
161+
* Creates an Account that relies on an ECDSA signing key for authentication.
162+
* @param pxe - An PXE server instance.
163+
* @param encryptionPrivateKey - Grumpkin key used for note encryption.
164+
* @param signingPrivateKey - Secp256k1 key used for signing transactions.
165+
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
166+
*/
167+
export function getEcdsaAccount(
168+
pxe: PXE,
169+
encryptionPrivateKey: GrumpkinPrivateKey,
170+
signingPrivateKey: Buffer,
171+
saltOrAddress?: Salt | CompleteAddress,
172+
): AccountManager {
173+
return new AccountManager(pxe, encryptionPrivateKey, new EcdsaAccountContract(signingPrivateKey), saltOrAddress);
174+
}
175+
176+
/**
177+
* Creates an Account that relies on a Grumpkin signing key for authentication.
178+
* @param pxe - An PXE server instance.
179+
* @param encryptionPrivateKey - Grumpkin key used for note encryption.
180+
* @param signingPrivateKey - Grumpkin key used for signing transactions.
181+
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
182+
*/
183+
export function getSchnorrAccount(
184+
pxe: PXE,
185+
encryptionPrivateKey: GrumpkinPrivateKey,
186+
signingPrivateKey: GrumpkinPrivateKey,
187+
saltOrAddress?: Salt | CompleteAddress,
188+
): AccountManager {
189+
return new AccountManager(pxe, encryptionPrivateKey, new SchnorrAccountContract(signingPrivateKey), saltOrAddress);
190+
}
191+
192+
/**
193+
* Creates an Account that uses the same Grumpkin key for encryption and authentication.
194+
* @param pxe - An PXE server instance.
195+
* @param encryptionAndSigningPrivateKey - Grumpkin key used for note encryption and signing transactions.
196+
* @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
197+
*/
198+
export function getUnsafeSchnorrAccount(
199+
pxe: PXE,
200+
encryptionAndSigningPrivateKey: GrumpkinPrivateKey,
201+
saltOrAddress?: Salt | CompleteAddress,
202+
): AccountManager {
203+
return new AccountManager(
204+
pxe,
205+
encryptionAndSigningPrivateKey,
206+
new SingleKeyAccountContract(encryptionAndSigningPrivateKey),
207+
saltOrAddress,
208+
);
209+
}

yarn-project/aztec.js/src/account/manager/util.ts yarn-project/aztec.js/src/account_manager/util.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { CompleteAddress, PXE, WaitOpts, retryUntil } from '../../index.js';
1+
import { retryUntil } from '@aztec/foundation/retry';
2+
import { CompleteAddress, PXE } from '@aztec/types';
3+
4+
import { WaitOpts } from '../contract/index.js';
25

36
/**
47
* Waits for the account to finish synchronizing with the PXE Service.

0 commit comments

Comments
 (0)