@aztec/aztec.js 0.1.0-alpha13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/.tsbuildinfo +1 -0
- package/README.md +44 -0
- package/dest/account_impl/account_collection.d.ts +24 -0
- package/dest/account_impl/account_collection.d.ts.map +1 -0
- package/dest/account_impl/account_collection.js +36 -0
- package/dest/account_impl/account_contract.d.ts +45 -0
- package/dest/account_impl/account_contract.d.ts.map +1 -0
- package/dest/account_impl/account_contract.js +108 -0
- package/dest/account_impl/index.d.ts +11 -0
- package/dest/account_impl/index.d.ts.map +1 -0
- package/dest/account_impl/index.js +3 -0
- package/dest/auth/ecdsa.d.ts +13 -0
- package/dest/auth/ecdsa.d.ts.map +1 -0
- package/dest/auth/ecdsa.js +17 -0
- package/dest/auth/index.d.ts +25 -0
- package/dest/auth/index.d.ts.map +1 -0
- package/dest/auth/index.js +13 -0
- package/dest/aztec_rpc_client/aztec_rpc_client.d.ts +25 -0
- package/dest/aztec_rpc_client/aztec_rpc_client.d.ts.map +1 -0
- package/dest/aztec_rpc_client/aztec_rpc_client.js +20 -0
- package/dest/aztec_rpc_client/index.d.ts +3 -0
- package/dest/aztec_rpc_client/index.d.ts.map +1 -0
- package/dest/aztec_rpc_client/index.js +3 -0
- package/dest/aztec_rpc_client/wallet.d.ts +44 -0
- package/dest/aztec_rpc_client/wallet.d.ts.map +1 -0
- package/dest/aztec_rpc_client/wallet.js +69 -0
- package/dest/contract/checker.d.ts +11 -0
- package/dest/contract/checker.d.ts.map +1 -0
- package/dest/contract/checker.js +98 -0
- package/dest/contract/checker.test.d.ts +2 -0
- package/dest/contract/checker.test.d.ts.map +1 -0
- package/dest/contract/checker.test.js +168 -0
- package/dest/contract/contract.d.ts +69 -0
- package/dest/contract/contract.d.ts.map +1 -0
- package/dest/contract/contract.js +64 -0
- package/dest/contract/contract.test.d.ts +2 -0
- package/dest/contract/contract.test.d.ts.map +1 -0
- package/dest/contract/contract.test.js +141 -0
- package/dest/contract/contract_function_interaction.d.ts +81 -0
- package/dest/contract/contract_function_interaction.d.ts.map +1 -0
- package/dest/contract/contract_function_interaction.js +96 -0
- package/dest/contract/index.d.ts +4 -0
- package/dest/contract/index.d.ts.map +1 -0
- package/dest/contract/index.js +4 -0
- package/dest/contract/sent_tx.d.ts +36 -0
- package/dest/contract/sent_tx.d.ts.map +1 -0
- package/dest/contract/sent_tx.js +50 -0
- package/dest/contract_deployer/contract_deployer.d.ts +23 -0
- package/dest/contract_deployer/contract_deployer.d.ts.map +1 -0
- package/dest/contract_deployer/contract_deployer.js +25 -0
- package/dest/contract_deployer/contract_deployer.test.d.ts +2 -0
- package/dest/contract_deployer/contract_deployer.test.d.ts.map +1 -0
- package/dest/contract_deployer/contract_deployer.test.js +48 -0
- package/dest/contract_deployer/deploy_method.d.ts +72 -0
- package/dest/contract_deployer/deploy_method.d.ts.map +1 -0
- package/dest/contract_deployer/deploy_method.js +114 -0
- package/dest/contract_deployer/index.d.ts +2 -0
- package/dest/contract_deployer/index.d.ts.map +1 -0
- package/dest/contract_deployer/index.js +2 -0
- package/dest/index.d.ts +8 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +9 -0
- package/dest/utils/account.d.ts +9 -0
- package/dest/utils/account.d.ts.map +1 -0
- package/dest/utils/account.js +38 -0
- package/dest/utils/index.d.ts +4 -0
- package/dest/utils/index.d.ts.map +1 -0
- package/dest/utils/index.js +4 -0
- package/dest/utils/pub_key.d.ts +18 -0
- package/dest/utils/pub_key.d.ts.map +1 -0
- package/dest/utils/pub_key.js +25 -0
- package/dest/utils/secrets.d.ts +8 -0
- package/dest/utils/secrets.d.ts.map +1 -0
- package/dest/utils/secrets.js +12 -0
- package/package.json +14 -0
- package/src/account_impl/account_collection.ts +41 -0
- package/src/account_impl/account_contract.ts +173 -0
- package/src/account_impl/index.ts +12 -0
- package/src/auth/ecdsa.ts +18 -0
- package/src/auth/index.ts +32 -0
- package/src/aztec_rpc_client/aztec_rpc_client.ts +59 -0
- package/src/aztec_rpc_client/index.ts +2 -0
- package/src/aztec_rpc_client/wallet.ts +87 -0
- package/src/contract/checker.test.ts +177 -0
- package/src/contract/checker.ts +117 -0
- package/src/contract/contract.test.ts +160 -0
- package/src/contract/contract.ts +80 -0
- package/src/contract/contract_function_interaction.ts +141 -0
- package/src/contract/index.ts +3 -0
- package/src/contract/sent_tx.ts +55 -0
- package/src/contract_deployer/contract_deployer.test.ts +56 -0
- package/src/contract_deployer/contract_deployer.ts +24 -0
- package/src/contract_deployer/deploy_method.ts +165 -0
- package/src/contract_deployer/index.ts +1 -0
- package/src/index.ts +9 -0
- package/src/utils/account.ts +59 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/pub_key.ts +26 -0
- package/src/utils/secrets.ts +12 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './secrets.js';
|
|
2
|
+
export * from './account.js';
|
|
3
|
+
export * from './pub_key.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxjQUFjLENBQUMifQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Point } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a Point type to a public key represented by BigInt coordinates
|
|
5
|
+
* @param point - The Point to convert.
|
|
6
|
+
* @returns An object with x & y coordinates represented as bigints.
|
|
7
|
+
*/
|
|
8
|
+
export declare function pointToPublicKey(point: Point): {
|
|
9
|
+
x: bigint;
|
|
10
|
+
y: bigint;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Method for generating a public grumpkin key from a private key.
|
|
14
|
+
* @param privateKey - The private key.
|
|
15
|
+
* @returns The generated public key.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generatePublicKey(privateKey: Buffer): Promise<Point>;
|
|
18
|
+
//# sourceMappingURL=pub_key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pub_key.d.ts","sourceRoot":"","sources":["../../src/utils/pub_key.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK;;;EAO5C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAG1E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
2
|
+
import { Point } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a Point type to a public key represented by BigInt coordinates
|
|
5
|
+
* @param point - The Point to convert.
|
|
6
|
+
* @returns An object with x & y coordinates represented as bigints.
|
|
7
|
+
*/
|
|
8
|
+
export function pointToPublicKey(point) {
|
|
9
|
+
const x = point.x.toBigInt();
|
|
10
|
+
const y = point.y.toBigInt();
|
|
11
|
+
return {
|
|
12
|
+
x,
|
|
13
|
+
y,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Method for generating a public grumpkin key from a private key.
|
|
18
|
+
* @param privateKey - The private key.
|
|
19
|
+
* @returns The generated public key.
|
|
20
|
+
*/
|
|
21
|
+
export async function generatePublicKey(privateKey) {
|
|
22
|
+
const grumpkin = await Grumpkin.new();
|
|
23
|
+
return Point.fromBuffer(grumpkin.mul(grumpkin.generator(), privateKey));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHViX2tleS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9wdWJfa2V5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXBDOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsS0FBWTtJQUMzQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzdCLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsT0FBTztRQUNMLENBQUM7UUFDRCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxVQUFrQjtJQUN4RCxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN0QyxPQUFPLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUMxRSxDQUFDIn0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fr } from '@aztec/circuits.js';
|
|
2
|
+
/**
|
|
3
|
+
* Given a secret, it computes its pedersen hash - used to send l1 to l2 messages
|
|
4
|
+
* @param secret - the secret to hash - secret could be generated however you want e.g. `Fr.random()`
|
|
5
|
+
* @returns the hash
|
|
6
|
+
*/
|
|
7
|
+
export declare function computeMessageSecretHash(secret: Fr): Promise<Fr>;
|
|
8
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAGtE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CircuitsWasm } from '@aztec/circuits.js';
|
|
2
|
+
import { computeSecretMessageHash } from '@aztec/circuits.js/abis';
|
|
3
|
+
/**
|
|
4
|
+
* Given a secret, it computes its pedersen hash - used to send l1 to l2 messages
|
|
5
|
+
* @param secret - the secret to hash - secret could be generated however you want e.g. `Fr.random()`
|
|
6
|
+
* @returns the hash
|
|
7
|
+
*/
|
|
8
|
+
export async function computeMessageSecretHash(secret) {
|
|
9
|
+
const wasm = await CircuitsWasm.get();
|
|
10
|
+
return computeSecretMessageHash(wasm, secret);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9zZWNyZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQU0sTUFBTSxvQkFBb0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRTs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx3QkFBd0IsQ0FBQyxNQUFVO0lBQ3ZELE1BQU0sSUFBSSxHQUFHLE1BQU0sWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3RDLE9BQU8sd0JBQXdCLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2hELENBQUMifQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aztec/aztec.js",
|
|
3
|
+
"version": "0.1.0-alpha13",
|
|
4
|
+
"exports": "./dest/index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@aztec/aztec-rpc": "0.1.0-alpha13",
|
|
8
|
+
"@aztec/circuits.js": "0.1.0-alpha13",
|
|
9
|
+
"@aztec/foundation": "0.1.0-alpha13",
|
|
10
|
+
"@aztec/key-store": "0.1.0-alpha13",
|
|
11
|
+
"@aztec/noir-contracts": "0.1.0-alpha13",
|
|
12
|
+
"tslib": "^2.4.0"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AztecAddress, TxContext } from '@aztec/circuits.js';
|
|
2
|
+
import { ExecutionRequest, TxExecutionRequest } from '@aztec/types';
|
|
3
|
+
import { AccountImplementation } from './index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A concrete account implementation that manages multiple accounts.
|
|
7
|
+
*/
|
|
8
|
+
export class AccountCollection implements AccountImplementation {
|
|
9
|
+
private accounts: Map<AztecAddress, AccountImplementation> = new Map();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Registers an account implementation against an aztec address
|
|
13
|
+
* @param addr - The aztec address agianst which to register the implementation.
|
|
14
|
+
* @param impl - The account implementation to be registered.
|
|
15
|
+
*/
|
|
16
|
+
public registerAccount(addr: AztecAddress, impl: AccountImplementation) {
|
|
17
|
+
this.accounts.set(addr, impl);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getAddress(): AztecAddress {
|
|
21
|
+
if (!this.accounts) throw new Error(`No accounts registered`);
|
|
22
|
+
return this.accounts.keys().next().value as AztecAddress;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Uses a registered account implementation to generate an authenticated request
|
|
27
|
+
* @param executions - The execution intent to be authenticated.
|
|
28
|
+
* @param txContext - The tx context under with the execution is to be made.
|
|
29
|
+
* @returns - The authenticated transaction execution request.
|
|
30
|
+
*/
|
|
31
|
+
public createAuthenticatedTxRequest(
|
|
32
|
+
executions: ExecutionRequest[],
|
|
33
|
+
txContext: TxContext,
|
|
34
|
+
): Promise<TxExecutionRequest> {
|
|
35
|
+
// TODO: Check all executions have the same origin
|
|
36
|
+
const sender = executions[0].from;
|
|
37
|
+
const impl = this.accounts.get(sender);
|
|
38
|
+
if (!impl) throw new Error(`No account implementation registered for ${sender}`);
|
|
39
|
+
return impl.createAuthenticatedTxRequest(executions, txContext);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { encodeArguments } from '@aztec/acir-simulator';
|
|
2
|
+
import { AztecAddress, CircuitsWasm, Fr, FunctionData, TxContext } from '@aztec/circuits.js';
|
|
3
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
4
|
+
import { sha256 } from '@aztec/foundation/crypto';
|
|
5
|
+
import { PublicKey } from '@aztec/key-store';
|
|
6
|
+
import { ExecutionRequest, PackedArguments, PartialContractAddress, TxExecutionRequest } from '@aztec/types';
|
|
7
|
+
import partition from 'lodash.partition';
|
|
8
|
+
import { generateFunctionSelector } from '../index.js';
|
|
9
|
+
import { AccountImplementation } from './index.js';
|
|
10
|
+
import { ContractAbi } from '@aztec/foundation/abi';
|
|
11
|
+
import { TxAuthProvider } from '../auth/index.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Account backed by an account contract
|
|
15
|
+
*/
|
|
16
|
+
export class AccountContract implements AccountImplementation {
|
|
17
|
+
constructor(
|
|
18
|
+
private address: AztecAddress,
|
|
19
|
+
private pubKey: PublicKey,
|
|
20
|
+
private authProvider: TxAuthProvider,
|
|
21
|
+
private partialContractAddress: PartialContractAddress,
|
|
22
|
+
private contractAbi: ContractAbi,
|
|
23
|
+
private wasm: CircuitsWasm,
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
getAddress(): AztecAddress {
|
|
27
|
+
return this.address;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async createAuthenticatedTxRequest(
|
|
31
|
+
executions: ExecutionRequest[],
|
|
32
|
+
txContext: TxContext,
|
|
33
|
+
): Promise<TxExecutionRequest> {
|
|
34
|
+
this.checkSender(executions);
|
|
35
|
+
this.checkIsNotDeployment(txContext);
|
|
36
|
+
|
|
37
|
+
const [privateCalls, publicCalls] = partition(executions, exec => exec.functionData.isPrivate).map(execs =>
|
|
38
|
+
execs.map(exec => ({
|
|
39
|
+
args: exec.args,
|
|
40
|
+
selector: exec.functionData.functionSelectorBuffer,
|
|
41
|
+
target: exec.to,
|
|
42
|
+
})),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const { payload, packedArguments: callsPackedArguments } = await buildPayload(privateCalls, publicCalls, this.wasm);
|
|
46
|
+
const hash = hashPayload(payload);
|
|
47
|
+
|
|
48
|
+
const signature = await this.authProvider.authenticateTx(payload, hash, this.address);
|
|
49
|
+
const signatureAsFrArray = signature.toFields();
|
|
50
|
+
const publicKeyAsBuffer = this.pubKey.toBuffer();
|
|
51
|
+
const args = [payload, publicKeyAsBuffer, signatureAsFrArray, this.partialContractAddress];
|
|
52
|
+
const abi = this.getEntrypointAbi();
|
|
53
|
+
const selector = generateFunctionSelector(abi.name, abi.parameters);
|
|
54
|
+
const packedArgs = await PackedArguments.fromArgs(encodeArguments(abi, args), this.wasm);
|
|
55
|
+
const txRequest = TxExecutionRequest.from({
|
|
56
|
+
argsHash: packedArgs.hash,
|
|
57
|
+
origin: this.address,
|
|
58
|
+
functionData: new FunctionData(selector, true, false),
|
|
59
|
+
txContext,
|
|
60
|
+
packedArguments: [...callsPackedArguments, packedArgs],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return txRequest;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private getEntrypointAbi() {
|
|
67
|
+
const abi = this.contractAbi.functions.find(f => f.name === 'entrypoint');
|
|
68
|
+
if (!abi) throw new Error(`Entrypoint abi for account contract not found`);
|
|
69
|
+
return abi;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private checkIsNotDeployment(txContext: TxContext) {
|
|
73
|
+
if (txContext.isContractDeploymentTx) {
|
|
74
|
+
throw new Error(`Cannot yet deploy contracts from an account contract`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private checkSender(executions: ExecutionRequest[]) {
|
|
79
|
+
const wrongSender = executions.find(e => !e.from.equals(this.address));
|
|
80
|
+
if (wrongSender) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Sender ${wrongSender.from.toString()} does not match account address ${this.address.toString()}`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const ACCOUNT_MAX_PRIVATE_CALLS = 1;
|
|
89
|
+
const ACCOUNT_MAX_PUBLIC_CALLS = 1;
|
|
90
|
+
|
|
91
|
+
/** A call to a function in a noir contract */
|
|
92
|
+
export type FunctionCall = {
|
|
93
|
+
/** The encoded arguments */
|
|
94
|
+
args: Fr[];
|
|
95
|
+
/** The function selector */
|
|
96
|
+
selector: Buffer;
|
|
97
|
+
/** The address of the contract */
|
|
98
|
+
target: AztecAddress;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** Encoded payload for the account contract entrypoint */
|
|
102
|
+
export type EntrypointPayload = {
|
|
103
|
+
// eslint-disable-next-line camelcase
|
|
104
|
+
/** Concatenated arguments for every call */
|
|
105
|
+
flattened_args_hashes: Fr[];
|
|
106
|
+
// eslint-disable-next-line camelcase
|
|
107
|
+
/** Concatenated selectors for every call */
|
|
108
|
+
flattened_selectors: Fr[];
|
|
109
|
+
// eslint-disable-next-line camelcase
|
|
110
|
+
/** Concatenated target addresses for every call */
|
|
111
|
+
flattened_targets: Fr[];
|
|
112
|
+
/** A nonce for replay protection */
|
|
113
|
+
nonce: Fr;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/** Assembles an entrypoint payload from a set of private and public function calls */
|
|
117
|
+
async function buildPayload(
|
|
118
|
+
privateCalls: FunctionCall[],
|
|
119
|
+
publicCalls: FunctionCall[],
|
|
120
|
+
wasm: CircuitsWasm,
|
|
121
|
+
): Promise<{
|
|
122
|
+
/**
|
|
123
|
+
* The payload for the entrypoint function
|
|
124
|
+
*/
|
|
125
|
+
payload: EntrypointPayload;
|
|
126
|
+
/**
|
|
127
|
+
* The packed arguments of functions called
|
|
128
|
+
*/
|
|
129
|
+
packedArguments: PackedArguments[];
|
|
130
|
+
}> {
|
|
131
|
+
const nonce = Fr.random();
|
|
132
|
+
const emptyCall = { args: [], selector: Buffer.alloc(32), target: AztecAddress.ZERO };
|
|
133
|
+
|
|
134
|
+
const calls = [
|
|
135
|
+
...padArrayEnd(privateCalls, emptyCall, ACCOUNT_MAX_PRIVATE_CALLS),
|
|
136
|
+
...padArrayEnd(publicCalls, emptyCall, ACCOUNT_MAX_PUBLIC_CALLS),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const packedArguments = [];
|
|
140
|
+
|
|
141
|
+
for (const call of calls) {
|
|
142
|
+
packedArguments.push(await PackedArguments.fromArgs(call.args, wasm));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
payload: {
|
|
147
|
+
// eslint-disable-next-line camelcase
|
|
148
|
+
flattened_args_hashes: packedArguments.map(args => args.hash),
|
|
149
|
+
// eslint-disable-next-line camelcase
|
|
150
|
+
flattened_selectors: calls.map(call => Fr.fromBuffer(call.selector)),
|
|
151
|
+
// eslint-disable-next-line camelcase
|
|
152
|
+
flattened_targets: calls.map(call => call.target.toField()),
|
|
153
|
+
nonce,
|
|
154
|
+
},
|
|
155
|
+
packedArguments,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Hashes an entrypoint payload (useful for signing) */
|
|
160
|
+
function hashPayload(payload: EntrypointPayload) {
|
|
161
|
+
// TODO: Switch to keccak when avaiable in Noir
|
|
162
|
+
return sha256(Buffer.concat(flattenPayload(payload).map(fr => fr.toBuffer())));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Flattens an entrypoint payload */
|
|
166
|
+
function flattenPayload(payload: EntrypointPayload) {
|
|
167
|
+
return [
|
|
168
|
+
...payload.flattened_args_hashes,
|
|
169
|
+
...payload.flattened_selectors,
|
|
170
|
+
...payload.flattened_targets,
|
|
171
|
+
payload.nonce,
|
|
172
|
+
];
|
|
173
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AztecAddress, TxContext } from '@aztec/circuits.js';
|
|
2
|
+
import { ExecutionRequest, TxExecutionRequest } from '@aztec/types';
|
|
3
|
+
|
|
4
|
+
export * from './account_contract.js';
|
|
5
|
+
export * from './account_collection.js';
|
|
6
|
+
|
|
7
|
+
/** Represents an implementation for a user account contract. Knows how to encode and sign a tx for that particular implementation. */
|
|
8
|
+
export interface AccountImplementation {
|
|
9
|
+
getAddress(): AztecAddress;
|
|
10
|
+
/** Creates a tx to be sent from a given account contract given a set of execution requests. */
|
|
11
|
+
createAuthenticatedTxRequest(executions: ExecutionRequest[], txContext: TxContext): Promise<TxExecutionRequest>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
2
|
+
import { AztecAddress } from '../index.js';
|
|
3
|
+
import { AuthPayload, TxAuthProvider } from './index.js';
|
|
4
|
+
|
|
5
|
+
import { EntrypointPayload } from '../account_impl/account_contract.js';
|
|
6
|
+
import { EcdsaSignature } from '@aztec/circuits.js/barretenberg';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An ecdsa implementation of TxAuthProvider.
|
|
10
|
+
*/
|
|
11
|
+
export class EcdsaAuthProvider implements TxAuthProvider {
|
|
12
|
+
constructor(private privKey: Buffer) {}
|
|
13
|
+
authenticateTx(payload: EntrypointPayload, payloadHash: Buffer, _address: AztecAddress): Promise<AuthPayload> {
|
|
14
|
+
const sig = secp256k1.sign(payloadHash, this.privKey);
|
|
15
|
+
if (sig.recovery === undefined) throw new Error(`Missing recovery from signature`);
|
|
16
|
+
return Promise.resolve(EcdsaSignature.fromBigInts(sig.r, sig.s, sig.recovery));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AztecAddress, Fr } from '@aztec/circuits.js';
|
|
2
|
+
import { EntrypointPayload } from '../account_impl/account_contract.js';
|
|
3
|
+
|
|
4
|
+
export * from './ecdsa.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* An interface for the payload returned from auth operations.
|
|
8
|
+
*/
|
|
9
|
+
export interface AuthPayload {
|
|
10
|
+
toBuffer(): Buffer;
|
|
11
|
+
toFields(): Fr[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The interface for an auth operations provider.
|
|
16
|
+
* TODO: How coupled should the auth provider be a to a specific account contract implementation? Can we remove the dependency on a specific EntrypointPayload format here?
|
|
17
|
+
*/
|
|
18
|
+
export interface TxAuthProvider {
|
|
19
|
+
authenticateTx(payload: EntrypointPayload, payloadHash: Buffer, address: AztecAddress): Promise<AuthPayload>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A dummy implementation of the auth provider
|
|
24
|
+
*/
|
|
25
|
+
export class DummyAuthProvider implements TxAuthProvider {
|
|
26
|
+
authenticateTx(_payload: EntrypointPayload, _payloadHash: Buffer, _address: AztecAddress): Promise<AuthPayload> {
|
|
27
|
+
return Promise.resolve({
|
|
28
|
+
toBuffer: () => Buffer.alloc(0),
|
|
29
|
+
toFields: () => [],
|
|
30
|
+
} as AuthPayload);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AztecAddress, AztecRPC, EthAddress, Fr, Point, Tx, TxHash } from '@aztec/aztec-rpc';
|
|
2
|
+
import { createJsonRpcClient } from '@aztec/foundation/json-rpc';
|
|
3
|
+
import { ContractData, ContractDeploymentTx, ContractPublicData, TxExecutionRequest } from '@aztec/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A dictionary of the Aztec-deployed L1 contracts.
|
|
7
|
+
*/
|
|
8
|
+
export type L1ContractAddresses = {
|
|
9
|
+
/**
|
|
10
|
+
* Address fo the main Aztec rollup contract.
|
|
11
|
+
*/
|
|
12
|
+
rollup: EthAddress;
|
|
13
|
+
/**
|
|
14
|
+
* Address of the contract that emits events on public contract deployment.
|
|
15
|
+
*/
|
|
16
|
+
contractDeploymentEmitter: EthAddress;
|
|
17
|
+
/**
|
|
18
|
+
* Address of the L1/L2 messaging inbox contract.
|
|
19
|
+
*/
|
|
20
|
+
inbox: EthAddress;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Registry Address.
|
|
24
|
+
*/
|
|
25
|
+
registry: EthAddress;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* string dictionary of aztec contract addresses that we receive over http.
|
|
30
|
+
*/
|
|
31
|
+
type L1ContractAddressesResp = {
|
|
32
|
+
[K in keyof L1ContractAddresses]: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const createAztecRpcClient = (url: string): AztecRPC =>
|
|
36
|
+
createJsonRpcClient<AztecRPC>(
|
|
37
|
+
url,
|
|
38
|
+
{
|
|
39
|
+
AztecAddress,
|
|
40
|
+
TxExecutionRequest,
|
|
41
|
+
ContractData,
|
|
42
|
+
ContractPublicData,
|
|
43
|
+
TxHash,
|
|
44
|
+
EthAddress,
|
|
45
|
+
Point,
|
|
46
|
+
Fr,
|
|
47
|
+
},
|
|
48
|
+
{ Tx, ContractDeploymentTx },
|
|
49
|
+
false,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export const getL1ContractAddresses = async (url: string): Promise<L1ContractAddresses> => {
|
|
53
|
+
const reqUrl = new URL(`${url}/api/l1-contract-addresses`);
|
|
54
|
+
const response = (await (await fetch(reqUrl.toString())).json()) as unknown as L1ContractAddressesResp;
|
|
55
|
+
const result = Object.fromEntries(
|
|
56
|
+
Object.entries(response).map(([key, value]) => [key, EthAddress.fromString(value)]),
|
|
57
|
+
);
|
|
58
|
+
return result as L1ContractAddresses;
|
|
59
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { AztecAddress, AztecRPC, DeployedContract, Fr, NodeInfo, Point, Tx, TxHash, TxReceipt } from '@aztec/aztec-rpc';
|
|
2
|
+
import { TxContext } from '@aztec/circuits.js';
|
|
3
|
+
import { ContractAbi } from '@aztec/foundation/abi';
|
|
4
|
+
import { ContractData, ContractPublicData, ExecutionRequest, L2BlockL2Logs, TxExecutionRequest } from '@aztec/types';
|
|
5
|
+
import { AccountImplementation } from '../account_impl/index.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The wallet interface.
|
|
9
|
+
*/
|
|
10
|
+
export type Wallet = AccountImplementation & AztecRPC;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A base class for Wallet implementations
|
|
14
|
+
*/
|
|
15
|
+
export abstract class BaseWallet implements Wallet {
|
|
16
|
+
constructor(protected readonly rpc: AztecRPC) {}
|
|
17
|
+
abstract getAddress(): AztecAddress;
|
|
18
|
+
abstract createAuthenticatedTxRequest(
|
|
19
|
+
executions: ExecutionRequest[],
|
|
20
|
+
txContext: TxContext,
|
|
21
|
+
): Promise<TxExecutionRequest>;
|
|
22
|
+
addAccount(
|
|
23
|
+
privKey: Buffer,
|
|
24
|
+
address: AztecAddress,
|
|
25
|
+
partialContractAddress: Fr,
|
|
26
|
+
abi?: ContractAbi | undefined,
|
|
27
|
+
): Promise<AztecAddress> {
|
|
28
|
+
return this.rpc.addAccount(privKey, address, partialContractAddress, abi);
|
|
29
|
+
}
|
|
30
|
+
getAccounts(): Promise<AztecAddress[]> {
|
|
31
|
+
return this.rpc.getAccounts();
|
|
32
|
+
}
|
|
33
|
+
getAccountPublicKey(address: AztecAddress): Promise<Point> {
|
|
34
|
+
return this.rpc.getAccountPublicKey(address);
|
|
35
|
+
}
|
|
36
|
+
addContracts(contracts: DeployedContract[]): Promise<void> {
|
|
37
|
+
return this.rpc.addContracts(contracts);
|
|
38
|
+
}
|
|
39
|
+
isContractDeployed(contract: AztecAddress): Promise<boolean> {
|
|
40
|
+
return this.rpc.isContractDeployed(contract);
|
|
41
|
+
}
|
|
42
|
+
simulateTx(txRequest: TxExecutionRequest, optionalFromAddress?: AztecAddress | undefined): Promise<Tx> {
|
|
43
|
+
return this.rpc.simulateTx(txRequest, optionalFromAddress);
|
|
44
|
+
}
|
|
45
|
+
sendTx(tx: Tx): Promise<TxHash> {
|
|
46
|
+
return this.rpc.sendTx(tx);
|
|
47
|
+
}
|
|
48
|
+
getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
49
|
+
return this.rpc.getTxReceipt(txHash);
|
|
50
|
+
}
|
|
51
|
+
getStorageAt(contract: AztecAddress, storageSlot: Fr): Promise<any> {
|
|
52
|
+
return this.rpc.getStorageAt(contract, storageSlot);
|
|
53
|
+
}
|
|
54
|
+
viewTx(functionName: string, args: any[], to: AztecAddress, from?: AztecAddress | undefined): Promise<any> {
|
|
55
|
+
return this.rpc.viewTx(functionName, args, to, from);
|
|
56
|
+
}
|
|
57
|
+
getContractData(contractAddress: AztecAddress): Promise<ContractPublicData | undefined> {
|
|
58
|
+
return this.rpc.getContractData(contractAddress);
|
|
59
|
+
}
|
|
60
|
+
getContractInfo(contractAddress: AztecAddress): Promise<ContractData | undefined> {
|
|
61
|
+
return this.rpc.getContractInfo(contractAddress);
|
|
62
|
+
}
|
|
63
|
+
getUnencryptedLogs(from: number, take: number): Promise<L2BlockL2Logs[]> {
|
|
64
|
+
return this.rpc.getUnencryptedLogs(from, take);
|
|
65
|
+
}
|
|
66
|
+
getBlockNum(): Promise<number> {
|
|
67
|
+
return this.rpc.getBlockNum();
|
|
68
|
+
}
|
|
69
|
+
getNodeInfo(): Promise<NodeInfo> {
|
|
70
|
+
return this.rpc.getNodeInfo();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A simple wallet implementation that forwards authentication requests to a provided account implementation.
|
|
76
|
+
*/
|
|
77
|
+
export class AccountWallet extends BaseWallet {
|
|
78
|
+
constructor(rpc: AztecRPC, protected accountImpl: AccountImplementation) {
|
|
79
|
+
super(rpc);
|
|
80
|
+
}
|
|
81
|
+
getAddress(): AztecAddress {
|
|
82
|
+
return this.accountImpl.getAddress();
|
|
83
|
+
}
|
|
84
|
+
createAuthenticatedTxRequest(executions: ExecutionRequest[], txContext: TxContext): Promise<TxExecutionRequest> {
|
|
85
|
+
return this.accountImpl.createAuthenticatedTxRequest(executions, txContext);
|
|
86
|
+
}
|
|
87
|
+
}
|