Skip to content

Commit 510c394

Browse files
authored
feat!: remove proveTx from Wallet interface (#17835)
Closes: https://linear.app/aztec-labs/issue/F-71/evaluate-collapsing-provetx-and-sendtx Removes `proveTx` from the wallet interface, since it has been deemed dangerous (app could route proven txs to malicious nodes) and inconvenient (wallet loses track of txs). Maintained it on `TestWallet` since in e2e it is useful to bulk prove txs and then send them together. Removed `cancelTx` from `cli-wallet` since it was already broken and the new approach requires a new way to handle it anyways. Created https://linear.app/aztec-labs/issue/F-88/add-cancel-tx-to-cli-wallet to track this task
2 parents aef6e7e + 1899cb5 commit 510c394

File tree

63 files changed

+556
-683
lines changed

Some content is hidden

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

63 files changed

+556
-683
lines changed

boxes/boxes/vanilla/app/embedded-wallet.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ export class EmbeddedWallet extends BaseWallet {
237237
skipInstancePublication: true,
238238
};
239239

240-
const provenInteraction = await deployMethod.prove(deployOpts);
241-
const receipt = await provenInteraction.send().wait({ timeout: 120 });
240+
const receipt = await deployMethod.send(deployOpts).wait({ timeout: 120 });
242241

243242
logger.info('Account deployed', receipt);
244243

boxes/boxes/vanilla/scripts/deploy.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ async function createAccount(wallet: TestWallet) {
7878
skipClassPublication: true,
7979
skipInstancePublication: true,
8080
};
81-
const provenInteraction = await deployMethod.prove(deployOpts);
82-
await provenInteraction.send().wait({ timeout: 120 });
81+
await deployMethod.send(deployOpts).wait({ timeout: 120 });
8382

8483
return accountManager.address;
8584
}
@@ -111,16 +110,17 @@ async function deployContract(wallet: Wallet, deployer: AztecAddress) {
111110

112111
const sponsoredPFCContract = await getSponsoredPFCContract();
113112

114-
const provenInteraction = await deployMethod.prove({
115-
from: deployer,
116-
contractAddressSalt: salt,
117-
fee: {
118-
paymentMethod: new SponsoredFeePaymentMethod(
119-
sponsoredPFCContract.address
120-
),
121-
},
122-
});
123-
await provenInteraction.send().wait({ timeout: 120 });
113+
await deployMethod
114+
.send({
115+
from: deployer,
116+
contractAddressSalt: salt,
117+
fee: {
118+
paymentMethod: new SponsoredFeePaymentMethod(
119+
sponsoredPFCContract.address
120+
),
121+
},
122+
})
123+
.wait({ timeout: 120 });
124124
await wallet.registerContract(contract, PrivateVotingContract.artifact);
125125

126126
return {

docs/docs/developers/docs/concepts/transactions.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,6 @@ Most transaction requests are created as interactions with specific contracts. T
8585

8686
#include_code simulate yarn-project/aztec.js/src/contract/contract_function_interaction.ts javascript
8787

88-
##### `prove`
89-
90-
#include_code prove yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript
91-
9288
##### `send`
9389

9490
#include_code send yarn-project/aztec.js/src/contract/base_contract_interaction.ts javascript
@@ -101,7 +97,7 @@ Batched transactions are a way to send multiple transactions in a single call. T
10197

10298
There are two kernel circuits in Aztec, the private kernel and the public kernel. Each circuit validates the correct execution of a particular function call.
10399

104-
A transaction is built up by generating proofs for multiple recursive iterations of kernel circuits. Each call in the call stack is modeled as new iteration of the kernel circuit and are managed by a [FIFO](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) queue containing pending function calls. There are two call stacks, one for private calls and one for public calls.
100+
A transaction is built up by generating proofs for multiple recursive iterations of kernel circuits. Each call in the call stack is modeled as new iteration of the kernel circuit and are managed by a [FIFO](<https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)>) queue containing pending function calls. There are two call stacks, one for private calls and one for public calls.
105101

106102
One iteration of a kernel circuit will pop a call off of the stack and execute the call. If the call triggers subsequent contract calls, these are pushed onto the stack.
107103

docs/docs/developers/migration_notes.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Aztec is in full-speed development. Literally every version breaks compatibility
99

1010
## TBD
1111

12+
### Removal of `proveTx` from `Wallet` interface
13+
14+
Exposing this method on the interface opened the door for certain types of attacks, were an app could route proven transactions through malicious nodes (that stored them for later decryption, or collected user IPs for example). It also made transactions difficult to track for the wallet, since they could be sent without their knowledge at any time. This change also affects `ContractFunctionInteraction` and `DeployMethod`, which no longer expose a `prove()` method.
15+
1216
### `msg_sender` is now an `Option<AztecAddress>` type.
1317

1418
Because Aztec has native account abstraction, the very first function call of a tx has no `msg_sender`. (Recall, the first function call of an Aztec transaction is always a _private_ function call).
@@ -103,7 +107,6 @@ When lining up a new tx, the `FunctionCall` struct has been extended to include
103107
- `!is_public & hide_msg_sender` -- Incompatible flags.
104108
- `!is_public & !hide_msg_sender` -- will make a private call with a visible `msg_sender` (noting that since it's a private function call, the `msg_sender` will only be visible to the called private function, but not to the rest of the world).
105109

106-
107110
## [cli-wallet]
108111

109112
The `deploy-account` command now requires the address (or alias) of the account to deploy as an argument, not a parameter

playground/src/hooks/useTransaction.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,19 @@ export function useTransaction() {
3838
setCurrentTx(tx);
3939

4040
try {
41-
notifications.show('Proving transaction...', {
41+
notifications.show('Sending transaction...', {
4242
severity: 'info',
4343
});
44-
const provenInteraction = await interaction.prove(opts);
44+
const tx = await interaction.send(opts);
4545

46-
if (showNotifications) {
47-
notifications.show('Proof generated successfully, sending transaction...', {
48-
severity: 'success',
49-
});
50-
}
51-
52-
txHash = await provenInteraction.getTxHash();
46+
txHash = await tx.getTxHash();
5347
setCurrentTx({
5448
...currentTx,
5549
...{ txHash, status: 'sending' },
5650
});
5751

5852
// TODO: Don't send the tx if the user has cancelled the transaction
59-
receipt = await provenInteraction.send().wait({ dontThrowOnRevert: true, timeout: TX_TIMEOUT, interval: 5 });
53+
receipt = await tx.wait({ dontThrowOnRevert: true, timeout: TX_TIMEOUT, interval: 5 });
6054

6155
if (showNotifications && receipt.status === TxStatus.SUCCESS) {
6256
notifications.show('Congratulations! Your transaction was included in a block.', {

yarn-project/aztec.js/src/api/contract.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,21 @@ export {
4444
type ProfileInteractionOptions,
4545
type SimulateInteractionOptions,
4646
type InteractionFeeOptions,
47+
toProfileOptions,
48+
toSendOptions,
49+
toSimulateOptions,
4750
} from '../contract/interaction_options.js';
4851

4952
export { TxProfileResult } from '@aztec/stdlib/tx';
5053
export { DefaultWaitOpts, SentTx, type WaitOpts } from '../contract/sent_tx.js';
51-
export { ProvenTx } from '../contract/proven_tx.js';
5254
export { ContractBase, type ContractMethod, type ContractStorageLayout } from '../contract/contract_base.js';
5355
export { BatchCall } from '../contract/batch_call.js';
54-
export { type DeployOptions, DeployMethod } from '../contract/deploy_method.js';
56+
export {
57+
type DeployOptions,
58+
DeployMethod,
59+
type RequestDeployOptions,
60+
type SimulateDeployOptions,
61+
} from '../contract/deploy_method.js';
5562
export { DeploySentTx } from '../contract/deploy_sent_tx.js';
5663
export { waitForProven, type WaitForProvenOpts, DefaultWaitForProvenOpts } from '../contract/wait_for_proven.js';
5764
export { getGasLimits } from '../contract/get_gas_limits.js';
Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
export {
22
type Aliased,
3-
BaseWallet,
4-
type Wallet,
5-
AccountManager,
6-
WalletSchema,
7-
type FeeOptions,
3+
type ContractInstanceAndArtifact,
84
type UserFeeOptions,
95
type SimulateOptions,
10-
type SendOptions,
116
type ProfileOptions,
12-
} from '../wallet/index.js';
7+
type SendOptions,
8+
type BatchableMethods,
9+
type BatchedMethod,
10+
type BatchedMethodResult,
11+
type BatchedMethodResultWrapper,
12+
type BatchResults,
13+
type Wallet,
14+
ContractInstantiationDataSchema,
15+
FunctionCallSchema,
16+
ExecutionPayloadSchema,
17+
UserFeeOptionsSchema,
18+
WalletSimulationFeeOptionSchema,
19+
SendOptionsSchema,
20+
SimulateOptionsSchema,
21+
ProfileOptionsSchema,
22+
InstanceDataSchema,
23+
MessageHashOrIntentSchema,
24+
BatchedMethodSchema,
25+
ContractMetadataSchema,
26+
ContractClassMetadataSchema,
27+
EventMetadataDefinitionSchema,
28+
WalletSchema,
29+
} from '../wallet/wallet.js';
30+
31+
export { type FeeOptions, BaseWallet } from '../wallet/base_wallet.js';
32+
33+
export { AccountManager } from '../wallet/account_manager.js';
1334

1435
export { type DeployAccountOptions, DeployAccountMethod } from '../wallet/deploy_account_method.js';

yarn-project/aztec.js/src/contract/base_contract_interaction.ts

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import type { ExecutionPayload } from '@aztec/entrypoints/payload';
22
import { createLogger } from '@aztec/foundation/log';
33
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
4-
import type { Capsule, TxProvingResult } from '@aztec/stdlib/tx';
4+
import type { Capsule } from '@aztec/stdlib/tx';
55

66
import type { Wallet } from '../wallet/wallet.js';
77
import { type RequestInteractionOptions, type SendInteractionOptions, toSendOptions } from './interaction_options.js';
8-
import { ProvenTx } from './proven_tx.js';
98
import { SentTx } from './sent_tx.js';
109

1110
/**
@@ -29,51 +28,22 @@ export abstract class BaseContractInteraction {
2928
*/
3029
public abstract request(options?: RequestInteractionOptions): Promise<ExecutionPayload>;
3130

32-
/**
33-
* Creates a transaction execution request, simulates and proves it. Differs from .prove in
34-
* that its result does not include the wallet nor the composed tx object, but only the proving result.
35-
* This object can then be used to either create a ProvenTx ready to be sent, or directly send the transaction.
36-
* @param options - optional arguments to be used in the creation of the transaction
37-
* @returns The proving result.
38-
*/
39-
protected async proveInternal(options: SendInteractionOptions): Promise<TxProvingResult> {
40-
const executionPayload = await this.request(options);
41-
const proveOptions = await toSendOptions(options);
42-
return await this.wallet.proveTx(executionPayload, proveOptions);
43-
}
44-
45-
// docs:start:prove
46-
/**
47-
* Proves a transaction execution request and returns a tx object ready to be sent.
48-
* @param options - optional arguments to be used in the creation of the transaction
49-
* @returns The resulting transaction
50-
*/
51-
public async prove(options: SendInteractionOptions): Promise<ProvenTx> {
52-
// docs:end:prove
53-
const txProvingResult = await this.proveInternal(options);
54-
return new ProvenTx(
55-
this.wallet,
56-
await txProvingResult.toTx(),
57-
txProvingResult.getOffchainEffects(),
58-
txProvingResult.stats,
59-
);
60-
}
61-
6231
// docs:start:send
6332
/**
6433
* Sends a transaction to the contract function with the specified options.
6534
* This function throws an error if called on a utility function.
6635
* It creates and signs the transaction if necessary, and returns a SentTx instance,
6736
* which can be used to track the transaction status, receipt, and events.
68-
* @param options - An optional object containing 'from' property representing
69-
* the AztecAddress of the sender. If not provided, the default address is used.
37+
* @param options - An object containing 'from' property representing
38+
* the AztecAddress of the sender and optional fee configuration
7039
* @returns A SentTx instance for tracking the transaction status and information.
7140
*/
7241
public send(options: SendInteractionOptions): SentTx {
7342
// docs:end:send
7443
const sendTx = async () => {
75-
const txProvingResult = await this.proveInternal(options);
76-
return this.wallet.sendTx(await txProvingResult.toTx());
44+
const executionPayload = await this.request(options);
45+
const sendOptions = await toSendOptions(options);
46+
return this.wallet.sendTx(executionPayload, sendOptions);
7747
};
7848
return new SentTx(this.wallet, sendTx);
7949
}

yarn-project/aztec.js/src/contract/contract.test.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ import {
66
getContractClassFromArtifact,
77
} from '@aztec/stdlib/contract';
88
import type {
9-
Tx,
109
TxExecutionRequest,
1110
TxHash,
12-
TxProvingResult,
1311
TxReceipt,
1412
TxSimulationResult,
1513
UtilitySimulationResult,
@@ -28,8 +26,6 @@ describe('Contract Class', () => {
2826
let accountAddress: CompleteAddress;
2927
let contractInstance: ContractInstanceWithAddress;
3028

31-
const mockTx = { type: 'Tx' } as any as Tx;
32-
const mockTxProvingResult = { type: 'TxProvingResult', toTx: () => mockTx } as any as TxProvingResult;
3329
const mockTxRequest = { type: 'TxRequest' } as any as TxExecutionRequest;
3430
const mockTxHash = { type: 'TxHash' } as any as TxHash;
3531
const mockTxReceipt = { type: 'TxReceipt' } as any as TxReceipt;
@@ -142,7 +138,7 @@ describe('Contract Class', () => {
142138
wallet.sendTx.mockResolvedValue(mockTxHash);
143139
wallet.simulateUtility.mockResolvedValue(mockUtilityResultValue);
144140
wallet.getTxReceipt.mockResolvedValue(mockTxReceipt);
145-
wallet.proveTx.mockResolvedValue(mockTxProvingResult);
141+
wallet.sendTx.mockResolvedValue(mockTxHash);
146142
});
147143

148144
it('should create and send a contract method tx', async () => {
@@ -156,7 +152,6 @@ describe('Contract Class', () => {
156152
expect(txHash).toBe(mockTxHash);
157153
expect(receipt).toBe(mockTxReceipt);
158154
expect(wallet.sendTx).toHaveBeenCalledTimes(1);
159-
expect(wallet.sendTx).toHaveBeenCalledWith(mockTx);
160155
});
161156

162157
it('should call view on a utility function', async () => {

yarn-project/aztec.js/src/contract/deploy_method.ts

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
getContractInstanceFromInstantiationParams,
1111
} from '@aztec/stdlib/contract';
1212
import type { PublicKeys } from '@aztec/stdlib/keys';
13-
import { type Capsule, type TxProfileResult, TxProvingResult, collectOffchainEffects } from '@aztec/stdlib/tx';
13+
import { type Capsule, type TxProfileResult, collectOffchainEffects } from '@aztec/stdlib/tx';
1414

1515
import { publishContractClass } from '../deployment/publish_class.js';
1616
import { publishInstance } from '../deployment/publish_instance.js';
@@ -19,7 +19,6 @@ import { BaseContractInteraction } from './base_contract_interaction.js';
1919
import type { Contract } from './contract.js';
2020
import type { ContractBase } from './contract_base.js';
2121
import { ContractFunctionInteraction } from './contract_function_interaction.js';
22-
import { DeployProvenTx } from './deploy_proven_tx.js';
2322
import { DeploySentTx } from './deploy_sent_tx.js';
2423
import { getGasLimits } from './get_gas_limits.js';
2524
import {
@@ -142,7 +141,7 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
142141
return finalExecutionPayload;
143142
}
144143

145-
protected convertDeployOptionsToRequestOptions(options: DeployOptions): RequestDeployOptions {
144+
convertDeployOptionsToRequestOptions(options: DeployOptions): RequestDeployOptions {
146145
return {
147146
...options,
148147
deployer: !options?.universalDeploy ? options.from : undefined,
@@ -229,12 +228,6 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
229228
return mergeExecutionPayloads(executionsPayloads);
230229
}
231230

232-
override async proveInternal(options: DeployOptions): Promise<TxProvingResult> {
233-
const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options));
234-
const proveOptions = await toSendOptions(options);
235-
return await this.wallet.proveTx(executionPayload, proveOptions);
236-
}
237-
238231
/**
239232
* Send a contract deployment transaction (initialize and/or publish) using the provided options.
240233
* This function extends the 'send' method from the ContractFunctionInteraction class,
@@ -244,8 +237,10 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
244237
* @returns A SentTx object that returns the receipt and the deployed contract instance.
245238
*/
246239
public override send(options: DeployOptions): DeploySentTx<TContract> {
247-
const sendTx = () => {
248-
return super.send(options).getTxHash();
240+
const sendTx = async () => {
241+
const executionPayload = await this.request(this.convertDeployOptionsToRequestOptions(options));
242+
const sendOptions = await toSendOptions(options);
243+
return this.wallet.sendTx(executionPayload, sendOptions);
249244
};
250245
this.log.debug(`Sent deployment tx of ${this.artifact.name} contract`);
251246
return new DeploySentTx(this.wallet, sendTx, this.postDeployCtor, () => this.getInstance(options));
@@ -270,22 +265,6 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
270265
return this.instance;
271266
}
272267

273-
/**
274-
* Prove the request.
275-
* @param options - initialization and publication options.
276-
* @returns The proven tx.
277-
*/
278-
public override async prove(options: DeployOptions): Promise<DeployProvenTx<TContract>> {
279-
const txProvingResult = await this.proveInternal(options);
280-
return await DeployProvenTx.fromProvingResult(
281-
this.wallet,
282-
txProvingResult,
283-
this.postDeployCtor,
284-
() => this.getInstance(options),
285-
txProvingResult.stats,
286-
);
287-
}
288-
289268
/**
290269
* Simulate the deployment
291270
*

0 commit comments

Comments
 (0)