@aztec/aztec.js 0.33.0 → 0.35.0
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/dest/account/contract.d.ts +6 -1
- package/dest/account/contract.d.ts.map +1 -1
- package/dest/account/contract.js +1 -1
- package/dest/account_manager/deploy_account_method.d.ts +15 -0
- package/dest/account_manager/deploy_account_method.d.ts.map +1 -0
- package/dest/account_manager/deploy_account_method.js +43 -0
- package/dest/account_manager/deploy_account_sent_tx.d.ts +3 -3
- package/dest/account_manager/deploy_account_sent_tx.d.ts.map +1 -1
- package/dest/account_manager/deploy_account_sent_tx.js +7 -6
- package/dest/account_manager/index.d.ts +9 -3
- package/dest/account_manager/index.d.ts.map +1 -1
- package/dest/account_manager/index.js +21 -17
- package/dest/contract/batch_call.d.ts.map +1 -1
- package/dest/contract/batch_call.js +5 -2
- package/dest/contract/contract_function_interaction.d.ts +4 -4
- package/dest/contract/contract_function_interaction.d.ts.map +1 -1
- package/dest/contract/contract_function_interaction.js +9 -5
- package/dest/contract/deploy_method.d.ts +11 -4
- package/dest/contract/deploy_method.d.ts.map +1 -1
- package/dest/contract/deploy_method.js +33 -15
- package/dest/contract/deploy_sent_tx.js +2 -2
- package/dest/entrypoint/default_entrypoint.d.ts +3 -3
- package/dest/entrypoint/default_entrypoint.d.ts.map +1 -1
- package/dest/entrypoint/default_entrypoint.js +11 -7
- package/dest/entrypoint/default_multi_call_entrypoint.d.ts +15 -0
- package/dest/entrypoint/default_multi_call_entrypoint.d.ts.map +1 -0
- package/dest/entrypoint/default_multi_call_entrypoint.js +85 -0
- package/dest/entrypoint/entrypoint.d.ts +17 -14
- package/dest/entrypoint/entrypoint.d.ts.map +1 -1
- package/dest/entrypoint/entrypoint.js +5 -2
- package/dest/entrypoint/payload.d.ts +73 -0
- package/dest/entrypoint/payload.d.ts.map +1 -0
- package/dest/entrypoint/payload.js +109 -0
- package/dest/fee/fee_payment_method.d.ts +3 -4
- package/dest/fee/fee_payment_method.d.ts.map +1 -1
- package/dest/fee/native_fee_payment_method.d.ts +4 -5
- package/dest/fee/native_fee_payment_method.d.ts.map +1 -1
- package/dest/fee/native_fee_payment_method.js +5 -5
- package/dest/fee/private_fee_payment_method.d.ts +3 -2
- package/dest/fee/private_fee_payment_method.d.ts.map +1 -1
- package/dest/fee/private_fee_payment_method.js +4 -3
- package/dest/fee/public_fee_payment_method.d.ts +3 -3
- package/dest/fee/public_fee_payment_method.d.ts.map +1 -1
- package/dest/fee/public_fee_payment_method.js +4 -3
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -2
- package/dest/utils/authwit.d.ts.map +1 -1
- package/dest/utils/authwit.js +3 -3
- package/dest/utils/cheat_codes.d.ts +4 -4
- package/dest/utils/cheat_codes.d.ts.map +1 -1
- package/dest/utils/cheat_codes.js +11 -11
- package/dest/utils/pxe.js +3 -3
- package/dest/wallet/account_wallet.d.ts +2 -2
- package/dest/wallet/account_wallet.d.ts.map +1 -1
- package/dest/wallet/account_wallet.js +3 -3
- package/dest/wallet/base_wallet.d.ts +2 -2
- package/dest/wallet/base_wallet.d.ts.map +1 -1
- package/dest/wallet/signerless_wallet.d.ts +3 -3
- package/dest/wallet/signerless_wallet.d.ts.map +1 -1
- package/dest/wallet/signerless_wallet.js +3 -3
- package/package.json +7 -7
- package/src/account/contract.ts +7 -1
- package/src/account_manager/deploy_account_method.ts +74 -0
- package/src/account_manager/deploy_account_sent_tx.ts +6 -5
- package/src/account_manager/index.ts +39 -23
- package/src/contract/batch_call.ts +4 -1
- package/src/contract/contract_function_interaction.ts +11 -7
- package/src/contract/deploy_method.ts +44 -22
- package/src/contract/deploy_sent_tx.ts +1 -1
- package/src/entrypoint/default_entrypoint.ts +18 -11
- package/src/entrypoint/default_multi_call_entrypoint.ts +89 -0
- package/src/entrypoint/entrypoint.ts +19 -14
- package/src/entrypoint/payload.ts +144 -0
- package/src/fee/fee_payment_method.ts +3 -4
- package/src/fee/native_fee_payment_method.ts +5 -6
- package/src/fee/private_fee_payment_method.ts +4 -3
- package/src/fee/public_fee_payment_method.ts +4 -4
- package/src/index.ts +2 -2
- package/src/utils/authwit.ts +2 -2
- package/src/utils/cheat_codes.ts +10 -10
- package/src/utils/pxe.ts +2 -2
- package/src/wallet/account_wallet.ts +3 -3
- package/src/wallet/base_wallet.ts +2 -2
- package/src/wallet/signerless_wallet.ts +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TxHash, type TxReceipt } from '@aztec/circuit-types';
|
|
1
|
+
import { type PXE, type TxHash, type TxReceipt } from '@aztec/circuit-types';
|
|
2
2
|
import { type FieldsOf } from '@aztec/foundation/types';
|
|
3
3
|
|
|
4
4
|
import { type Wallet } from '../account/index.js';
|
|
@@ -15,8 +15,8 @@ export type DeployAccountTxReceipt = FieldsOf<TxReceipt> & {
|
|
|
15
15
|
* A deployment transaction for an account contract sent to the network, extending SentTx with methods to get the resulting wallet.
|
|
16
16
|
*/
|
|
17
17
|
export class DeployAccountSentTx extends SentTx {
|
|
18
|
-
constructor(
|
|
19
|
-
super(
|
|
18
|
+
constructor(pxe: PXE, txHashPromise: Promise<TxHash>, private getWalletPromise: Promise<Wallet>) {
|
|
19
|
+
super(pxe, txHashPromise);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -36,7 +36,8 @@ export class DeployAccountSentTx extends SentTx {
|
|
|
36
36
|
*/
|
|
37
37
|
public async wait(opts: WaitOpts = DefaultWaitOpts): Promise<DeployAccountTxReceipt> {
|
|
38
38
|
const receipt = await super.wait(opts);
|
|
39
|
-
await
|
|
40
|
-
|
|
39
|
+
const wallet = await this.getWalletPromise;
|
|
40
|
+
await waitForAccountSynch(this.pxe, wallet.getCompleteAddress(), opts);
|
|
41
|
+
return { ...receipt, wallet };
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -6,14 +6,20 @@ import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
|
6
6
|
import { type AccountContract } from '../account/contract.js';
|
|
7
7
|
import { type Salt } from '../account/index.js';
|
|
8
8
|
import { type AccountInterface } from '../account/interface.js';
|
|
9
|
-
import { type
|
|
9
|
+
import { type DeployOptions } from '../contract/deploy_method.js';
|
|
10
10
|
import { DefaultWaitOpts, type WaitOpts } from '../contract/sent_tx.js';
|
|
11
|
-
import {
|
|
11
|
+
import { DefaultMultiCallEntrypoint } from '../entrypoint/default_multi_call_entrypoint.js';
|
|
12
12
|
import { waitForAccountSynch } from '../utils/account.js';
|
|
13
13
|
import { generatePublicKey } from '../utils/index.js';
|
|
14
14
|
import { AccountWalletWithPrivateKey, SignerlessWallet } from '../wallet/index.js';
|
|
15
|
+
import { DeployAccountMethod } from './deploy_account_method.js';
|
|
15
16
|
import { DeployAccountSentTx } from './deploy_account_sent_tx.js';
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Options to deploy an account contract.
|
|
20
|
+
*/
|
|
21
|
+
export type DeployAccountOptions = Pick<DeployOptions, 'fee' | 'skipClassRegistration' | 'skipPublicDeployment'>;
|
|
22
|
+
|
|
17
23
|
/**
|
|
18
24
|
* Manages a user account. Provides methods for calculating the account's address, deploying the account contract,
|
|
19
25
|
* and creating and registering the user wallet in the PXE Service.
|
|
@@ -26,7 +32,7 @@ export class AccountManager {
|
|
|
26
32
|
private completeAddress?: CompleteAddress;
|
|
27
33
|
private instance?: ContractInstanceWithAddress;
|
|
28
34
|
private encryptionPublicKey?: PublicKey;
|
|
29
|
-
private deployMethod?:
|
|
35
|
+
private deployMethod?: DeployAccountMethod;
|
|
30
36
|
|
|
31
37
|
constructor(
|
|
32
38
|
private pxe: PXE,
|
|
@@ -34,7 +40,7 @@ export class AccountManager {
|
|
|
34
40
|
private accountContract: AccountContract,
|
|
35
41
|
salt?: Salt,
|
|
36
42
|
) {
|
|
37
|
-
this.salt = salt ? new Fr(salt) : Fr.random();
|
|
43
|
+
this.salt = salt !== undefined ? new Fr(salt) : Fr.random();
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
protected getEncryptionPublicKey() {
|
|
@@ -128,17 +134,22 @@ export class AccountManager {
|
|
|
128
134
|
}
|
|
129
135
|
await this.#register();
|
|
130
136
|
const encryptionPublicKey = this.getEncryptionPublicKey();
|
|
131
|
-
|
|
137
|
+
const { chainId, protocolVersion } = await this.pxe.getNodeInfo();
|
|
138
|
+
const deployWallet = new SignerlessWallet(this.pxe, new DefaultMultiCallEntrypoint(chainId, protocolVersion));
|
|
139
|
+
|
|
140
|
+
// We use a signerless wallet with the multi call entrypoint in order to make multiple calls in one go
|
|
132
141
|
// If we used getWallet, the deployment would get routed via the account contract entrypoint
|
|
133
|
-
//
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
this.accountContract.
|
|
137
|
-
deployWallet,
|
|
142
|
+
// and it can't be used unless the contract is initialized
|
|
143
|
+
const args = this.accountContract.getDeploymentArgs() ?? [];
|
|
144
|
+
this.deployMethod = new DeployAccountMethod(
|
|
145
|
+
this.accountContract.getAuthWitnessProvider(this.getCompleteAddress()),
|
|
138
146
|
encryptionPublicKey,
|
|
147
|
+
deployWallet,
|
|
148
|
+
this.accountContract.getContractArtifact(),
|
|
149
|
+
args,
|
|
150
|
+
'constructor',
|
|
151
|
+
'entrypoint',
|
|
139
152
|
);
|
|
140
|
-
const args = this.accountContract.getDeploymentArgs() ?? [];
|
|
141
|
-
this.deployMethod = deployer.deploy(...args);
|
|
142
153
|
}
|
|
143
154
|
return this.deployMethod;
|
|
144
155
|
}
|
|
@@ -148,18 +159,23 @@ export class AccountManager {
|
|
|
148
159
|
* Does not register the associated class nor publicly deploy the instance by default.
|
|
149
160
|
* Uses the salt provided in the constructor or a randomly generated one.
|
|
150
161
|
* Registers the account in the PXE Service before deploying the contract.
|
|
162
|
+
* @param opts - Fee options to be used for the deployment.
|
|
151
163
|
* @returns A SentTx object that can be waited to get the associated Wallet.
|
|
152
164
|
*/
|
|
153
|
-
public
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
public deploy(opts?: DeployAccountOptions): DeployAccountSentTx {
|
|
166
|
+
const sentTx = this.getDeployMethod()
|
|
167
|
+
.then(deployMethod =>
|
|
168
|
+
deployMethod.send({
|
|
169
|
+
contractAddressSalt: this.salt,
|
|
170
|
+
skipClassRegistration: opts?.skipClassRegistration ?? true,
|
|
171
|
+
skipPublicDeployment: opts?.skipPublicDeployment ?? true,
|
|
172
|
+
skipInitialization: false,
|
|
173
|
+
universalDeploy: true,
|
|
174
|
+
fee: opts?.fee,
|
|
175
|
+
}),
|
|
176
|
+
)
|
|
177
|
+
.then(tx => tx.getTxHash());
|
|
178
|
+
return new DeployAccountSentTx(this.pxe, sentTx, this.getWallet());
|
|
163
179
|
}
|
|
164
180
|
|
|
165
181
|
/**
|
|
@@ -170,7 +186,7 @@ export class AccountManager {
|
|
|
170
186
|
* @returns A Wallet instance.
|
|
171
187
|
*/
|
|
172
188
|
public async waitSetup(opts: WaitOpts = DefaultWaitOpts): Promise<AccountWalletWithPrivateKey> {
|
|
173
|
-
await (this.isDeployable() ? this.deploy().
|
|
189
|
+
await (this.isDeployable() ? this.deploy().wait(opts) : this.register());
|
|
174
190
|
return this.getWallet();
|
|
175
191
|
}
|
|
176
192
|
|
|
@@ -17,7 +17,10 @@ export class BatchCall extends BaseContractInteraction {
|
|
|
17
17
|
*/
|
|
18
18
|
public async create(opts?: SendMethodOptions): Promise<TxExecutionRequest> {
|
|
19
19
|
if (!this.txRequest) {
|
|
20
|
-
this.txRequest = await this.wallet.createTxExecutionRequest(
|
|
20
|
+
this.txRequest = await this.wallet.createTxExecutionRequest({
|
|
21
|
+
calls: this.calls,
|
|
22
|
+
fee: opts?.fee,
|
|
23
|
+
});
|
|
21
24
|
}
|
|
22
25
|
return this.txRequest;
|
|
23
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type FunctionCall,
|
|
2
|
-
import { type AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js';
|
|
1
|
+
import { type FunctionCall, PackedValues, TxExecutionRequest } from '@aztec/circuit-types';
|
|
2
|
+
import { type AztecAddress, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js';
|
|
3
3
|
import { type FunctionAbi, FunctionType, encodeArguments } from '@aztec/foundation/abi';
|
|
4
4
|
|
|
5
5
|
import { type Wallet } from '../account/wallet.js';
|
|
@@ -13,10 +13,10 @@ export { SendMethodOptions };
|
|
|
13
13
|
* Disregarded for simulation of public functions
|
|
14
14
|
*/
|
|
15
15
|
export type SimulateMethodOptions = {
|
|
16
|
-
/**
|
|
17
|
-
* The sender's Aztec address.
|
|
18
|
-
*/
|
|
16
|
+
/** The sender's Aztec address. */
|
|
19
17
|
from?: AztecAddress;
|
|
18
|
+
/** Gas settings for the simulation. */
|
|
19
|
+
gasSettings?: GasSettings;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -47,7 +47,10 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
|
|
|
47
47
|
throw new Error("Can't call `create` on an unconstrained function.");
|
|
48
48
|
}
|
|
49
49
|
if (!this.txRequest) {
|
|
50
|
-
this.txRequest = await this.wallet.createTxExecutionRequest(
|
|
50
|
+
this.txRequest = await this.wallet.createTxExecutionRequest({
|
|
51
|
+
calls: [this.request()],
|
|
52
|
+
fee: opts?.fee,
|
|
53
|
+
});
|
|
51
54
|
}
|
|
52
55
|
return this.txRequest;
|
|
53
56
|
}
|
|
@@ -89,7 +92,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
|
|
|
89
92
|
|
|
90
93
|
if (this.functionDao.functionType == FunctionType.SECRET) {
|
|
91
94
|
const nodeInfo = await this.wallet.getNodeInfo();
|
|
92
|
-
const packedArgs =
|
|
95
|
+
const packedArgs = PackedValues.fromValues(encodeArguments(this.functionDao, this.args));
|
|
93
96
|
|
|
94
97
|
const txRequest = TxExecutionRequest.from({
|
|
95
98
|
argsHash: packedArgs.hash,
|
|
@@ -98,6 +101,7 @@ export class ContractFunctionInteraction extends BaseContractInteraction {
|
|
|
98
101
|
txContext: TxContext.empty(nodeInfo.chainId, nodeInfo.protocolVersion),
|
|
99
102
|
packedArguments: [packedArgs],
|
|
100
103
|
authWitnesses: [],
|
|
104
|
+
gasSettings: options.gasSettings ?? GasSettings.simulation(),
|
|
101
105
|
});
|
|
102
106
|
const simulatedTx = await this.pxe.simulateTx(txRequest, false, options.from ?? this.wallet.getAddress());
|
|
103
107
|
return simulatedTx.privateReturnValues?.[0];
|
|
@@ -14,6 +14,7 @@ import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
|
14
14
|
import { type Wallet } from '../account/index.js';
|
|
15
15
|
import { deployInstance } from '../deployment/deploy_instance.js';
|
|
16
16
|
import { registerContractClass } from '../deployment/register_class.js';
|
|
17
|
+
import { type ExecutionRequestInit } from '../entrypoint/entrypoint.js';
|
|
17
18
|
import { BaseContractInteraction, type SendMethodOptions } from './base_contract_interaction.js';
|
|
18
19
|
import { type Contract } from './contract.js';
|
|
19
20
|
import { type ContractBase } from './contract_base.js';
|
|
@@ -53,7 +54,7 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
53
54
|
private constructorArtifact: FunctionArtifact | undefined;
|
|
54
55
|
|
|
55
56
|
/** Cached call to request() */
|
|
56
|
-
private functionCalls
|
|
57
|
+
private functionCalls?: ExecutionRequestInit;
|
|
57
58
|
|
|
58
59
|
private log = createDebugLogger('aztec:js:deploy_method');
|
|
59
60
|
|
|
@@ -80,10 +81,6 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
80
81
|
*/
|
|
81
82
|
public async create(options: DeployOptions = {}): Promise<TxExecutionRequest> {
|
|
82
83
|
if (!this.txRequest) {
|
|
83
|
-
const calls = await this.request(options);
|
|
84
|
-
if (calls.length === 0) {
|
|
85
|
-
throw new Error(`No function calls needed to deploy contract ${this.artifact.name}`);
|
|
86
|
-
}
|
|
87
84
|
this.txRequest = await this.wallet.createTxExecutionRequest(await this.request(options));
|
|
88
85
|
// TODO: Should we add the contracts to the DB here, or once the tx has been sent or mined?
|
|
89
86
|
await this.pxe.registerContract({ artifact: this.artifact, instance: this.instance! });
|
|
@@ -99,20 +96,21 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
99
96
|
* @remarks This method does not have the same return type as the `request` in the ContractInteraction object,
|
|
100
97
|
* it returns a promise for an array instead of a function call directly.
|
|
101
98
|
*/
|
|
102
|
-
public async request(options: DeployOptions = {}): Promise<
|
|
99
|
+
public async request(options: DeployOptions = {}): Promise<ExecutionRequestInit> {
|
|
103
100
|
if (!this.functionCalls) {
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
address,
|
|
110
|
-
this.constructorArtifact,
|
|
111
|
-
this.args,
|
|
112
|
-
);
|
|
113
|
-
calls.push(constructorCall.request());
|
|
101
|
+
const deployment = await this.getDeploymentFunctionCalls(options);
|
|
102
|
+
const bootstrap = await this.getInitializeFunctionCalls(options);
|
|
103
|
+
|
|
104
|
+
if (deployment.calls.length + bootstrap.calls.length === 0) {
|
|
105
|
+
throw new Error(`No function calls needed to deploy contract ${this.artifact.name}`);
|
|
114
106
|
}
|
|
115
|
-
|
|
107
|
+
|
|
108
|
+
this.functionCalls = {
|
|
109
|
+
calls: [...deployment.calls, ...bootstrap.calls],
|
|
110
|
+
authWitnesses: [...(deployment.authWitnesses ?? []), ...(bootstrap.authWitnesses ?? [])],
|
|
111
|
+
packedArguments: [...(deployment.packedArguments ?? []), ...(bootstrap.packedArguments ?? [])],
|
|
112
|
+
fee: options.fee,
|
|
113
|
+
};
|
|
116
114
|
}
|
|
117
115
|
return this.functionCalls;
|
|
118
116
|
}
|
|
@@ -122,7 +120,7 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
122
120
|
* @param options - Deployment options.
|
|
123
121
|
* @returns A function call array with potentially requests to the class registerer and instance deployer.
|
|
124
122
|
*/
|
|
125
|
-
protected async getDeploymentFunctionCalls(options: DeployOptions = {}): Promise<
|
|
123
|
+
protected async getDeploymentFunctionCalls(options: DeployOptions = {}): Promise<ExecutionRequestInit> {
|
|
126
124
|
const calls: FunctionCall[] = [];
|
|
127
125
|
|
|
128
126
|
// Set contract instance object so it's available for populating the DeploySendTx object
|
|
@@ -140,11 +138,11 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
140
138
|
// Register the contract class if it hasn't been published already.
|
|
141
139
|
if (!options.skipClassRegistration) {
|
|
142
140
|
if (await this.pxe.isContractClassPubliclyRegistered(contractClass.id)) {
|
|
143
|
-
this.log(
|
|
141
|
+
this.log.debug(
|
|
144
142
|
`Skipping registration of already registered contract class ${contractClass.id.toString()} for ${instance.address.toString()}`,
|
|
145
143
|
);
|
|
146
144
|
} else {
|
|
147
|
-
this.log(
|
|
145
|
+
this.log.info(
|
|
148
146
|
`Creating request for registering contract class ${contractClass.id.toString()} as part of deployment for ${instance.address.toString()}`,
|
|
149
147
|
);
|
|
150
148
|
calls.push((await registerContractClass(this.wallet, this.artifact)).request());
|
|
@@ -156,7 +154,31 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
156
154
|
calls.push(deployInstance(this.wallet, instance).request());
|
|
157
155
|
}
|
|
158
156
|
|
|
159
|
-
return
|
|
157
|
+
return {
|
|
158
|
+
calls,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Returns the calls necessary to initialize the contract.
|
|
164
|
+
* @param options - Deployment options.
|
|
165
|
+
* @returns - An array of function calls.
|
|
166
|
+
*/
|
|
167
|
+
protected getInitializeFunctionCalls(options: DeployOptions): Promise<ExecutionRequestInit> {
|
|
168
|
+
const { address } = this.getInstance(options);
|
|
169
|
+
const calls: FunctionCall[] = [];
|
|
170
|
+
if (this.constructorArtifact && !options.skipInitialization) {
|
|
171
|
+
const constructorCall = new ContractFunctionInteraction(
|
|
172
|
+
this.wallet,
|
|
173
|
+
address,
|
|
174
|
+
this.constructorArtifact,
|
|
175
|
+
this.args,
|
|
176
|
+
);
|
|
177
|
+
calls.push(constructorCall.request());
|
|
178
|
+
}
|
|
179
|
+
return Promise.resolve({
|
|
180
|
+
calls,
|
|
181
|
+
});
|
|
160
182
|
}
|
|
161
183
|
|
|
162
184
|
/**
|
|
@@ -170,7 +192,7 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
|
|
|
170
192
|
public send(options: DeployOptions = {}): DeploySentTx<TContract> {
|
|
171
193
|
const txHashPromise = super.send(options).getTxHash();
|
|
172
194
|
const instance = this.getInstance(options);
|
|
173
|
-
this.log(
|
|
195
|
+
this.log.debug(
|
|
174
196
|
`Sent deployment tx of ${this.artifact.name} contract with deployment address ${instance.address.toString()}`,
|
|
175
197
|
);
|
|
176
198
|
return new DeploySentTx(this.pxe, txHashPromise, this.postDeployCtor, instance);
|
|
@@ -44,7 +44,7 @@ export class DeploySentTx<TContract extends Contract = Contract> extends SentTx
|
|
|
44
44
|
*/
|
|
45
45
|
public async deployed(opts?: DeployedWaitOpts): Promise<TContract> {
|
|
46
46
|
const receipt = await this.wait(opts);
|
|
47
|
-
this.log(`Contract ${this.instance.address.toString()} successfully deployed.`);
|
|
47
|
+
this.log.info(`Contract ${this.instance.address.toString()} successfully deployed.`);
|
|
48
48
|
return receipt.contract;
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { TxContext } from '@aztec/circuits.js';
|
|
1
|
+
import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types';
|
|
2
|
+
import { GasSettings, TxContext } from '@aztec/circuits.js';
|
|
3
3
|
|
|
4
|
-
import { type EntrypointInterface } from './entrypoint.js';
|
|
4
|
+
import { type EntrypointInterface, type ExecutionRequestInit } from './entrypoint.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Default implementation of the entrypoint interface. It calls a function on a contract directly
|
|
@@ -9,18 +9,25 @@ import { type EntrypointInterface } from './entrypoint.js';
|
|
|
9
9
|
export class DefaultEntrypoint implements EntrypointInterface {
|
|
10
10
|
constructor(private chainId: number, private protocolVersion: number) {}
|
|
11
11
|
|
|
12
|
-
createTxExecutionRequest(
|
|
13
|
-
const [
|
|
14
|
-
|
|
12
|
+
createTxExecutionRequest(exec: ExecutionRequestInit): Promise<TxExecutionRequest> {
|
|
13
|
+
const { calls, authWitnesses = [], packedArguments = [] } = exec;
|
|
14
|
+
|
|
15
|
+
if (calls.length > 1) {
|
|
16
|
+
throw new Error(`Expected a single call, got ${calls.length}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const call = calls[0];
|
|
20
|
+
const entrypointPackedValues = PackedValues.fromValues(call.args);
|
|
15
21
|
const txContext = TxContext.empty(this.chainId, this.protocolVersion);
|
|
16
22
|
return Promise.resolve(
|
|
17
23
|
new TxExecutionRequest(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
call.to,
|
|
25
|
+
call.functionData,
|
|
26
|
+
entrypointPackedValues.hash,
|
|
21
27
|
txContext,
|
|
22
|
-
[packedArguments],
|
|
23
|
-
|
|
28
|
+
[...packedArguments, entrypointPackedValues],
|
|
29
|
+
authWitnesses,
|
|
30
|
+
exec.fee?.gasSettings ?? GasSettings.default(),
|
|
24
31
|
),
|
|
25
32
|
);
|
|
26
33
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type EntrypointInterface, EntrypointPayload, type ExecutionRequestInit } from '@aztec/aztec.js/entrypoint';
|
|
2
|
+
import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types';
|
|
3
|
+
import { type AztecAddress, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js';
|
|
4
|
+
import { type FunctionAbi, encodeArguments } from '@aztec/foundation/abi';
|
|
5
|
+
import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Implementation for an entrypoint interface that can execute multiple function calls in a single transaction
|
|
9
|
+
*/
|
|
10
|
+
export class DefaultMultiCallEntrypoint implements EntrypointInterface {
|
|
11
|
+
constructor(
|
|
12
|
+
private chainId: number,
|
|
13
|
+
private version: number,
|
|
14
|
+
private address: AztecAddress = getCanonicalMultiCallEntrypointAddress(),
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
createTxExecutionRequest(executions: ExecutionRequestInit): Promise<TxExecutionRequest> {
|
|
18
|
+
const { calls, authWitnesses = [], packedArguments = [] } = executions;
|
|
19
|
+
const payload = EntrypointPayload.fromAppExecution(calls);
|
|
20
|
+
const abi = this.getEntrypointAbi();
|
|
21
|
+
const entrypointPackedArgs = PackedValues.fromValues(encodeArguments(abi, [payload]));
|
|
22
|
+
|
|
23
|
+
const txRequest = TxExecutionRequest.from({
|
|
24
|
+
argsHash: entrypointPackedArgs.hash,
|
|
25
|
+
origin: this.address,
|
|
26
|
+
functionData: FunctionData.fromAbi(abi),
|
|
27
|
+
txContext: TxContext.empty(this.chainId, this.version),
|
|
28
|
+
packedArguments: [...payload.packedArguments, ...packedArguments, entrypointPackedArgs],
|
|
29
|
+
authWitnesses,
|
|
30
|
+
gasSettings: executions.fee?.gasSettings ?? GasSettings.default(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return Promise.resolve(txRequest);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private getEntrypointAbi() {
|
|
37
|
+
return {
|
|
38
|
+
name: 'entrypoint',
|
|
39
|
+
isInitializer: false,
|
|
40
|
+
functionType: 'secret',
|
|
41
|
+
isInternal: false,
|
|
42
|
+
parameters: [
|
|
43
|
+
{
|
|
44
|
+
name: 'app_payload',
|
|
45
|
+
type: {
|
|
46
|
+
kind: 'struct',
|
|
47
|
+
path: 'authwit::entrypoint::app::AppPayload',
|
|
48
|
+
fields: [
|
|
49
|
+
{
|
|
50
|
+
name: 'function_calls',
|
|
51
|
+
type: {
|
|
52
|
+
kind: 'array',
|
|
53
|
+
length: 4,
|
|
54
|
+
type: {
|
|
55
|
+
kind: 'struct',
|
|
56
|
+
path: 'authwit::entrypoint::function_call::FunctionCall',
|
|
57
|
+
fields: [
|
|
58
|
+
{ name: 'args_hash', type: { kind: 'field' } },
|
|
59
|
+
{
|
|
60
|
+
name: 'function_selector',
|
|
61
|
+
type: {
|
|
62
|
+
kind: 'struct',
|
|
63
|
+
path: 'authwit::aztec::protocol_types::abis::function_selector::FunctionSelector',
|
|
64
|
+
fields: [{ name: 'inner', type: { kind: 'integer', sign: 'unsigned', width: 32 } }],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'target_address',
|
|
69
|
+
type: {
|
|
70
|
+
kind: 'struct',
|
|
71
|
+
path: 'authwit::aztec::protocol_types::address::AztecAddress',
|
|
72
|
+
fields: [{ name: 'inner', type: { kind: 'field' } }],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{ name: 'is_public', type: { kind: 'boolean' } },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{ name: 'nonce', type: { kind: 'field' } },
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
visibility: 'public',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
returnTypes: [],
|
|
87
|
+
} as FunctionAbi;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import { type FunctionCall, type TxExecutionRequest } from '@aztec/circuit-types';
|
|
2
|
-
import { type Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { type AuthWitness, type FunctionCall, type PackedValues, type TxExecutionRequest } from '@aztec/circuit-types';
|
|
3
2
|
|
|
4
|
-
import { type
|
|
3
|
+
import { EntrypointPayload, type FeeOptions } from './payload.js';
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
export { EntrypointPayload, FeeOptions };
|
|
6
|
+
|
|
7
|
+
export { DefaultEntrypoint } from './default_entrypoint.js';
|
|
8
|
+
export { DefaultMultiCallEntrypoint } from './default_multi_call_entrypoint.js';
|
|
9
|
+
|
|
10
|
+
/** Encodes the calls to be done in a transaction. */
|
|
11
|
+
export type ExecutionRequestInit = {
|
|
12
|
+
/** The function calls to be executed. */
|
|
13
|
+
calls: FunctionCall[];
|
|
14
|
+
/** Any transient auth witnesses needed for this execution */
|
|
15
|
+
authWitnesses?: AuthWitness[];
|
|
16
|
+
/** Any transient packed arguments for this execution */
|
|
17
|
+
packedArguments?: PackedValues[];
|
|
18
|
+
/** How the fee is going to be payed */
|
|
19
|
+
fee?: FeeOptions;
|
|
14
20
|
};
|
|
15
21
|
|
|
16
22
|
/** Creates transaction execution requests out of a set of function calls. */
|
|
17
23
|
export interface EntrypointInterface {
|
|
18
24
|
/**
|
|
19
25
|
* Generates an execution request out of set of function calls.
|
|
20
|
-
* @param
|
|
21
|
-
* @param feeOpts - The fee to be paid for the transaction.
|
|
26
|
+
* @param execution - The execution intents to be run.
|
|
22
27
|
* @returns The authenticated transaction execution request.
|
|
23
28
|
*/
|
|
24
|
-
createTxExecutionRequest(
|
|
29
|
+
createTxExecutionRequest(execution: ExecutionRequestInit): Promise<TxExecutionRequest>;
|
|
25
30
|
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type FunctionCall, PackedValues, emptyFunctionCall } from '@aztec/circuit-types';
|
|
2
|
+
import { Fr, type GasSettings, GeneratorIndex } from '@aztec/circuits.js';
|
|
3
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
4
|
+
import { pedersenHash } from '@aztec/foundation/crypto';
|
|
5
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
6
|
+
|
|
7
|
+
import { type FeePaymentMethod } from '../fee/fee_payment_method.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Fee payment options for a transaction.
|
|
11
|
+
*/
|
|
12
|
+
export type FeeOptions = {
|
|
13
|
+
/** The fee payment method to use */
|
|
14
|
+
paymentMethod: FeePaymentMethod;
|
|
15
|
+
/** The gas settings */
|
|
16
|
+
gasSettings: GasSettings;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// These must match the values defined in:
|
|
20
|
+
// - noir-projects/aztec-nr/aztec/src/entrypoint/app.nr
|
|
21
|
+
const APP_MAX_CALLS = 4;
|
|
22
|
+
// - and noir-projects/aztec-nr/aztec/src/entrypoint/fee.nr
|
|
23
|
+
const FEE_MAX_CALLS = 2;
|
|
24
|
+
|
|
25
|
+
/* eslint-disable camelcase */
|
|
26
|
+
/** Encoded function call for account contract entrypoint */
|
|
27
|
+
type EncodedFunctionCall = {
|
|
28
|
+
/** Arguments hash for the call */
|
|
29
|
+
args_hash: Fr;
|
|
30
|
+
/** Selector of the function to call */
|
|
31
|
+
function_selector: Fr;
|
|
32
|
+
/** Address of the contract to call */
|
|
33
|
+
target_address: Fr;
|
|
34
|
+
/** Whether the function is public or private */
|
|
35
|
+
is_public: boolean;
|
|
36
|
+
};
|
|
37
|
+
/* eslint-enable camelcase */
|
|
38
|
+
|
|
39
|
+
/** Assembles an entrypoint payload */
|
|
40
|
+
export class EntrypointPayload {
|
|
41
|
+
#packedArguments: PackedValues[] = [];
|
|
42
|
+
#functionCalls: EncodedFunctionCall[] = [];
|
|
43
|
+
#nonce = Fr.random();
|
|
44
|
+
#generatorIndex: number;
|
|
45
|
+
|
|
46
|
+
private constructor(functionCalls: FunctionCall[], generatorIndex: number) {
|
|
47
|
+
for (const call of functionCalls) {
|
|
48
|
+
this.#packedArguments.push(PackedValues.fromValues(call.args));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* eslint-disable camelcase */
|
|
52
|
+
this.#functionCalls = functionCalls.map((call, index) => ({
|
|
53
|
+
args_hash: this.#packedArguments[index].hash,
|
|
54
|
+
function_selector: call.functionData.selector.toField(),
|
|
55
|
+
target_address: call.to.toField(),
|
|
56
|
+
is_public: !call.functionData.isPrivate,
|
|
57
|
+
}));
|
|
58
|
+
/* eslint-enable camelcase */
|
|
59
|
+
|
|
60
|
+
this.#generatorIndex = generatorIndex;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* eslint-disable camelcase */
|
|
64
|
+
/**
|
|
65
|
+
* The function calls to execute. This uses snake_case naming so that it is compatible with Noir encoding
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
get function_calls() {
|
|
69
|
+
return this.#functionCalls;
|
|
70
|
+
}
|
|
71
|
+
/* eslint-enable camelcase */
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The nonce
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
get nonce() {
|
|
78
|
+
return this.#nonce;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The packed arguments for the function calls
|
|
83
|
+
*/
|
|
84
|
+
get packedArguments() {
|
|
85
|
+
return this.#packedArguments;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Serializes the payload to an array of fields
|
|
90
|
+
* @returns The fields of the payload
|
|
91
|
+
*/
|
|
92
|
+
toFields(): Fr[] {
|
|
93
|
+
return [
|
|
94
|
+
...this.#functionCalls.flatMap(call => [
|
|
95
|
+
call.args_hash,
|
|
96
|
+
call.function_selector,
|
|
97
|
+
call.target_address,
|
|
98
|
+
new Fr(call.is_public),
|
|
99
|
+
]),
|
|
100
|
+
this.#nonce,
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Hashes the payload
|
|
106
|
+
* @returns The hash of the payload
|
|
107
|
+
*/
|
|
108
|
+
hash() {
|
|
109
|
+
return pedersenHash(this.toFields(), this.#generatorIndex);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Creates an execution payload from a set of function calls
|
|
114
|
+
* @param functionCalls - The function calls to execute
|
|
115
|
+
* @returns The execution payload
|
|
116
|
+
*/
|
|
117
|
+
static fromFunctionCalls(functionCalls: FunctionCall[]) {
|
|
118
|
+
return new EntrypointPayload(functionCalls, 0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Creates an execution payload for the app-portion of a transaction from a set of function calls
|
|
123
|
+
* @param functionCalls - The function calls to execute
|
|
124
|
+
* @returns The execution payload
|
|
125
|
+
*/
|
|
126
|
+
static fromAppExecution(functionCalls: FunctionCall[] | Tuple<FunctionCall, 4>) {
|
|
127
|
+
if (functionCalls.length > APP_MAX_CALLS) {
|
|
128
|
+
throw new Error(`Expected at most ${APP_MAX_CALLS} function calls, got ${functionCalls.length}`);
|
|
129
|
+
}
|
|
130
|
+
const paddedCalls = padArrayEnd(functionCalls, emptyFunctionCall(), APP_MAX_CALLS);
|
|
131
|
+
return new EntrypointPayload(paddedCalls, GeneratorIndex.SIGNATURE_PAYLOAD);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Creates an execution payload to pay the fee for a transaction
|
|
136
|
+
* @param feeOpts - The fee payment options
|
|
137
|
+
* @returns The execution payload
|
|
138
|
+
*/
|
|
139
|
+
static async fromFeeOptions(feeOpts?: FeeOptions) {
|
|
140
|
+
const calls = feeOpts ? await feeOpts.paymentMethod.getFunctionCalls(feeOpts?.gasSettings) : [];
|
|
141
|
+
const paddedCalls = padArrayEnd(calls, emptyFunctionCall(), FEE_MAX_CALLS);
|
|
142
|
+
return new EntrypointPayload(paddedCalls, GeneratorIndex.FEE_PAYLOAD);
|
|
143
|
+
}
|
|
144
|
+
}
|