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

feat(aztec-js): Account class #1429

Merged
merged 5 commits into from
Aug 7, 2023
Merged

feat(aztec-js): Account class #1429

merged 5 commits into from
Aug 7, 2023

Conversation

spalladino
Copy link
Collaborator

@spalladino spalladino commented Aug 4, 2023

Fixes #1342. Introduces a new Account class for managing a user account:

/**
 * Manages a user account. Provides methods for calculating the account's address, deploying the account contract,
 * and creating and registering the user wallet in the RPC server.
 */
export class Account {
  /**
   * Gets the calculated complete address associated with this account.
   * Does not require the account to be deployed or registered.
   * @returns The address, partial address, and encryption public key.
   */
  public async getCompleteAddress(): Promise<CompleteAddress> {...}

  /**
   * Returns a Wallet instance associated with this account. Use it to create Contract
   * instances to be interacted with from this account.
   * @returns A Wallet instance.
   */
  public async getWallet(): Promise<Wallet> {...}

  /**
   * Registers this account in the RPC server and returns the associated wallet. Registering
   * the account on the RPC server is required for managing private state associated with it.
   * Use the returned wallet to create Contract instances to be interacted with from this account.
   * @returns A Wallet instance.
   */
  public async register(): Promise<Wallet> {...}

  /**
   * Deploys the account contract that backs this account.
   * Uses the salt provided in the constructor or a randomly generated one.
   * Note that if the Account is constructed with an explicit complete address
   * it is assumed that the account contract has already been deployed and this method will throw.
   * Registers the account in the RPC server before deploying the contract.
   * @returns A SentTx object that can be waited to get the associated Wallet.
   */
  public async deploy(): Promise<DeployAccountSentTx> {...}
}

This class is constructed out of an RPC server, an encryption private key, and an instance of a new AccountContract interface. This interface is all a dev needs to implement on ts to build their own flavor of account abstraction:

/**
 * An account contract instance. Knows its ABI, deployment arguments, and to create transaction execution
 * requests out of function calls through an entrypoint.
 */
export interface AccountContract {
  /** Returns the ABI of this account contract. */
  getContractAbi(): ContractAbi;
  /** Returns the deployment arguments for this instance. */
  getDeploymentArgs(): Promise<any[]>;
  /**
   * Creates an entrypoint for creating transaction execution requests for this account contract.
   * @param address - Complete address of the deployed account contract.
   * @param nodeInfo - Chain id and protocol version where the account contract is deployed.
   */
  getEntrypoint(address: CompleteAddress, nodeInfo: NodeInfo): Promise<Entrypoint>;
}

Along with these changes, the old AccountImplementation was renamed to Entrypoint, since its only concern was formatting FunctionCalls to be sent through an account's entrypoint. I'm still not in love with this new name, so suggestions are welcome.

For the user's convenience, we are also exposing methods that build Account instances out of the well known kinds, such as:

/**
 * Creates an Account that relies on an ECDSA signing key for authentication.
 * @param rpc - An AztecRPC server instance.
 * @param encryptionPrivateKey - Grumpkin key used for note encryption.
 * @param signingPrivateKey - Secp256k1 key used for signing transactions.
 * @param saltOrAddress - Deployment salt or complete address if account contract is already deployed.
 */
export function getEcdsaAccount(
  rpc: AztecRPC,
  encryptionPrivateKey: PrivateKey,
  signingPrivateKey: PrivateKey,
  saltOrAddress?: Salt | CompleteAddress,
): Account {
  return new Account(rpc, encryptionPrivateKey, new EcdsaAccountContract(signingPrivateKey), saltOrAddress);
}

Example usage from the user's perspective:

// Create a new ECDSA account
const account = getEcdsaAccount(rpc, Privatekey.random(), Privatekey.random());
// Register it on the RPC server and deploy its contract
const wallet = await account.deploy().then(tx => tx.getWallet());
// Deploy a new child contract
const contract = await ChildContract.deploy(wallet).send().deployed();
// Send and await a tx to the new contract through the new wallet
await child.methods.value(42).send().wait();

Pending tasks, which can be done on a subsequent PR:

  • Add unit tests for the Account class.
  • Use the new Account class in e2e tests setup.
  • Use the new Account class in the CLI.
  • Review all names. Account, AccountContract, Entrypoint, these are all still somewhat confusing.
  • Definitely rename SchnorrMultiKeyAccount and SchnorrSingleKeyAccount contracts.
  • Ensure that accounts work in the browser (not sure if webpack is picking up the JSON files for ABIs).

@spalladino spalladino requested review from iAmMichaelConnor and PhilWindle and removed request for iAmMichaelConnor August 4, 2023 21:42
@spalladino spalladino enabled auto-merge (squash) August 4, 2023 21:46
Copy link
Collaborator

@PhilWindle PhilWindle left a comment

Choose a reason for hiding this comment

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

Looks nice. Was going to suggest updating the e2e tests but I see you have marked that as follow up work.

@spalladino spalladino merged commit e788745 into master Aug 7, 2023
@spalladino spalladino deleted the palla/aztecjs-account branch August 7, 2023 12:01
spalladino added a commit that referenced this pull request Aug 7, 2023
Uses the `Account` class introduced in #1429 for e2e test setup. This
required adding new methods to the `Account` class for being able to
simulate the deployment without sending and assembling an
`EntrypointCollection` out of multiple `Account`s.
Maddiaa0 pushed a commit that referenced this pull request Aug 8, 2023
Use the `Account` class introduced in #1429 for the e2e browser tests.
This checks that the ABIs of the account contracts are properly packaged
by webpack. Also removes the usage of custom utils for creating and
retrieving wallets (we just need to remove them from the CLI now).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Better API for creating and registering accounts
2 participants