@aztec/entrypoints 0.0.1-fake-ceab37513c → 0.0.6-commit.a2d1860fe9
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_entrypoint.d.ts +49 -8
- package/dest/account_entrypoint.d.ts.map +1 -1
- package/dest/account_entrypoint.js +97 -121
- package/dest/constants.d.ts +1 -1
- package/dest/default_entrypoint.d.ts +6 -8
- package/dest/default_entrypoint.d.ts.map +1 -1
- package/dest/default_entrypoint.js +16 -12
- package/dest/default_multi_call_entrypoint.d.ts +8 -8
- package/dest/default_multi_call_entrypoint.d.ts.map +1 -1
- package/dest/default_multi_call_entrypoint.js +62 -34
- package/dest/encoding.d.ts +10 -43
- package/dest/encoding.d.ts.map +1 -1
- package/dest/encoding.js +22 -70
- package/dest/index.d.ts +1 -1
- package/dest/interfaces.d.ts +40 -60
- package/dest/interfaces.d.ts.map +1 -1
- package/dest/interfaces.js +8 -2
- package/package.json +11 -9
- package/src/account_entrypoint.ts +120 -93
- package/src/default_entrypoint.ts +24 -14
- package/src/default_multi_call_entrypoint.ts +69 -36
- package/src/encoding.ts +16 -102
- package/src/interfaces.ts +37 -65
- package/dest/payload.d.ts +0 -32
- package/dest/payload.d.ts.map +0 -1
- package/dest/payload.js +0 -27
- package/src/payload.ts +0 -35
|
@@ -1,12 +1,53 @@
|
|
|
1
|
-
import { Fr } from '@aztec/foundation/
|
|
2
|
-
import { type FunctionAbi, FunctionSelector, encodeArguments } from '@aztec/stdlib/abi';
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import { type FunctionAbi, FunctionCall, FunctionSelector, encodeArguments } from '@aztec/stdlib/abi';
|
|
3
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import {
|
|
4
|
+
import type { GasSettings } from '@aztec/stdlib/gas';
|
|
5
|
+
import { ExecutionPayload, HashedValues, TxContext, TxExecutionRequest } from '@aztec/stdlib/tx';
|
|
5
6
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import { EncodedAppEntrypointCalls } from './encoding.js';
|
|
8
|
+
import type { AuthWitnessProvider, ChainInfo, EntrypointInterface } from './interfaces.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The mechanism via which an account contract will pay for a transaction in which it gets invoked.
|
|
12
|
+
*/
|
|
13
|
+
export enum AccountFeePaymentMethodOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Signals that some other contract is in charge of paying the fee, nothing needs to be done.
|
|
16
|
+
*/
|
|
17
|
+
EXTERNAL = 0,
|
|
18
|
+
/**
|
|
19
|
+
* Used to make the account contract publicly pay for the transaction with its own fee juice balance,
|
|
20
|
+
* **which it must already have prior to this transaction**.
|
|
21
|
+
*
|
|
22
|
+
* The contract will set itself as the fee payer and end the setup phase.
|
|
23
|
+
*/
|
|
24
|
+
PREEXISTING_FEE_JUICE = 1,
|
|
25
|
+
/**
|
|
26
|
+
* Used to make the account contract publicly pay for the transaction with its own fee juice balance
|
|
27
|
+
* **which is being claimed in the same transaction**.
|
|
28
|
+
*
|
|
29
|
+
* The contract will set itself as the fee payer but not end setup phase - this is done by the Fee Juice
|
|
30
|
+
* contract after enqueuing a public call, which unlike most public calls is whitelisted by the nodes
|
|
31
|
+
* to be executable during the setup phase.
|
|
32
|
+
*/
|
|
33
|
+
FEE_JUICE_WITH_CLAIM = 2,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* General options for the tx execution.
|
|
38
|
+
*/
|
|
39
|
+
export type DefaultAccountEntrypointOptions = {
|
|
40
|
+
/** Whether the transaction can be cancelled. */
|
|
41
|
+
cancellable?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* A nonce to inject into the app payload of the transaction. When used with cancellable=true, this nonce will be
|
|
44
|
+
* used to compute a nullifier that allows cancelling this transaction by submitting a new one with the same nonce
|
|
45
|
+
* but higher fee. The nullifier ensures only one transaction can succeed.
|
|
46
|
+
*/
|
|
47
|
+
txNonce?: Fr;
|
|
48
|
+
/** Options that configure how the account contract behaves depending on the fee payment method of the tx */
|
|
49
|
+
feePaymentMethodOptions: AccountFeePaymentMethodOptions;
|
|
50
|
+
};
|
|
10
51
|
|
|
11
52
|
/**
|
|
12
53
|
* Implementation for an entrypoint interface that follows the default entrypoint signature
|
|
@@ -16,54 +57,24 @@ export class DefaultAccountEntrypoint implements EntrypointInterface {
|
|
|
16
57
|
constructor(
|
|
17
58
|
private address: AztecAddress,
|
|
18
59
|
private auth: AuthWitnessProvider,
|
|
19
|
-
private chainId: number = DEFAULT_CHAIN_ID,
|
|
20
|
-
private version: number = DEFAULT_VERSION,
|
|
21
60
|
) {}
|
|
22
61
|
|
|
23
62
|
async createTxExecutionRequest(
|
|
24
63
|
exec: ExecutionPayload,
|
|
25
|
-
|
|
26
|
-
|
|
64
|
+
gasSettings: GasSettings,
|
|
65
|
+
chainInfo: ChainInfo,
|
|
66
|
+
options: DefaultAccountEntrypointOptions,
|
|
27
67
|
): Promise<TxExecutionRequest> {
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const { cancellable, txNonce } = options;
|
|
32
|
-
// Encode the calls for the app
|
|
33
|
-
const appEncodedCalls = await EncodedCallsForEntrypoint.fromAppExecution(calls, txNonce);
|
|
34
|
-
// Get the execution payload for the fee, it includes the calls and potentially authWitnesses
|
|
35
|
-
const { calls: feeCalls, authWitnesses: feeAuthwitnesses } = await fee.paymentMethod.getExecutionPayload(
|
|
36
|
-
fee.gasSettings,
|
|
37
|
-
);
|
|
38
|
-
// Encode the calls for the fee
|
|
39
|
-
const feePayer = await fee.paymentMethod.getFeePayer(fee.gasSettings);
|
|
40
|
-
const isFeePayer = feePayer.equals(this.address);
|
|
41
|
-
const feeEncodedCalls = await EncodedCallsForEntrypoint.fromFeeCalls(feeCalls, isFeePayer);
|
|
42
|
-
|
|
43
|
-
// Obtain the entrypoint hashed args, built from the app and fee encoded calls
|
|
44
|
-
const abi = this.getEntrypointAbi();
|
|
45
|
-
const entrypointHashedArgs = await HashedValues.fromArgs(
|
|
46
|
-
encodeArguments(abi, [appEncodedCalls, feeEncodedCalls, !!cancellable]),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
// Generate the combined payload auth witness, by signing the hash of the combined payload
|
|
50
|
-
const combinedPayloadAuthWitness = await this.auth.createAuthWit(
|
|
51
|
-
await computeCombinedPayloadHash(appEncodedCalls, feeEncodedCalls),
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
// Assemble the tx request
|
|
68
|
+
const { authWitnesses, capsules, extraHashedArgs } = exec;
|
|
69
|
+
const callData = await this.#buildEntrypointCallData(exec, options);
|
|
70
|
+
const entrypointHashedArgs = await HashedValues.fromArgs(callData.encodedArgs);
|
|
55
71
|
const txRequest = TxExecutionRequest.from({
|
|
56
72
|
firstCallArgsHash: entrypointHashedArgs.hash,
|
|
57
73
|
origin: this.address,
|
|
58
|
-
functionSelector:
|
|
59
|
-
txContext: new TxContext(
|
|
60
|
-
argsOfCalls: [
|
|
61
|
-
|
|
62
|
-
...feeEncodedCalls.hashedArguments,
|
|
63
|
-
entrypointHashedArgs,
|
|
64
|
-
...extraHashedArgs,
|
|
65
|
-
],
|
|
66
|
-
authWitnesses: [...authWitnesses, ...feeAuthwitnesses, combinedPayloadAuthWitness],
|
|
74
|
+
functionSelector: callData.functionSelector,
|
|
75
|
+
txContext: new TxContext(chainInfo.chainId.toNumber(), chainInfo.version.toNumber(), gasSettings),
|
|
76
|
+
argsOfCalls: [...callData.encodedCalls.hashedArguments, entrypointHashedArgs, ...extraHashedArgs],
|
|
77
|
+
authWitnesses: [...authWitnesses, callData.payloadAuthWitness],
|
|
67
78
|
capsules,
|
|
68
79
|
salt: Fr.random(),
|
|
69
80
|
});
|
|
@@ -71,12 +82,70 @@ export class DefaultAccountEntrypoint implements EntrypointInterface {
|
|
|
71
82
|
return txRequest;
|
|
72
83
|
}
|
|
73
84
|
|
|
85
|
+
async wrapExecutionPayload(
|
|
86
|
+
exec: ExecutionPayload,
|
|
87
|
+
options: DefaultAccountEntrypointOptions,
|
|
88
|
+
): Promise<ExecutionPayload> {
|
|
89
|
+
const { authWitnesses, capsules, extraHashedArgs, feePayer } = exec;
|
|
90
|
+
const callData = await this.#buildEntrypointCallData(exec, options);
|
|
91
|
+
|
|
92
|
+
// Build the entrypoint function call
|
|
93
|
+
const entrypointCall = FunctionCall.from({
|
|
94
|
+
name: callData.abi.name,
|
|
95
|
+
to: this.address,
|
|
96
|
+
selector: callData.functionSelector,
|
|
97
|
+
type: callData.abi.functionType,
|
|
98
|
+
hideMsgSender: false,
|
|
99
|
+
isStatic: callData.abi.isStatic,
|
|
100
|
+
args: callData.encodedArgs,
|
|
101
|
+
returnTypes: callData.abi.returnTypes,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return new ExecutionPayload(
|
|
105
|
+
[entrypointCall],
|
|
106
|
+
[callData.payloadAuthWitness, ...authWitnesses],
|
|
107
|
+
capsules,
|
|
108
|
+
[...callData.encodedCalls.hashedArguments, ...extraHashedArgs],
|
|
109
|
+
feePayer ?? this.address,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Builds the shared data needed for both creating a tx execution request and wrapping an execution payload.
|
|
115
|
+
* This includes encoding calls, building entrypoint arguments, and creating the authwitness.
|
|
116
|
+
* @param exec - The execution payload containing calls to encode
|
|
117
|
+
* @param options - Account entrypoint options including tx nonce and fee payment method
|
|
118
|
+
* @returns Encoded call data, ABI, function selector, and auth witness
|
|
119
|
+
*/
|
|
120
|
+
async #buildEntrypointCallData(exec: ExecutionPayload, options: DefaultAccountEntrypointOptions) {
|
|
121
|
+
const { calls } = exec;
|
|
122
|
+
const { cancellable, txNonce, feePaymentMethodOptions } = options;
|
|
123
|
+
|
|
124
|
+
const encodedCalls = await EncodedAppEntrypointCalls.create(calls, txNonce);
|
|
125
|
+
|
|
126
|
+
const abi = this.getEntrypointAbi();
|
|
127
|
+
const args = [encodedCalls, feePaymentMethodOptions, !!cancellable];
|
|
128
|
+
const encodedArgs = encodeArguments(abi, args);
|
|
129
|
+
|
|
130
|
+
const functionSelector = await FunctionSelector.fromNameAndParameters(abi.name, abi.parameters);
|
|
131
|
+
|
|
132
|
+
const payloadAuthWitness = await this.auth.createAuthWit(await encodedCalls.hash());
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
encodedCalls,
|
|
136
|
+
abi,
|
|
137
|
+
encodedArgs,
|
|
138
|
+
functionSelector,
|
|
139
|
+
payloadAuthWitness,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
74
143
|
private getEntrypointAbi() {
|
|
75
144
|
return {
|
|
76
145
|
name: 'entrypoint',
|
|
77
146
|
isInitializer: false,
|
|
78
147
|
functionType: 'private',
|
|
79
|
-
|
|
148
|
+
isOnlySelf: false,
|
|
80
149
|
isStatic: false,
|
|
81
150
|
parameters: [
|
|
82
151
|
{
|
|
@@ -89,50 +158,7 @@ export class DefaultAccountEntrypoint implements EntrypointInterface {
|
|
|
89
158
|
name: 'function_calls',
|
|
90
159
|
type: {
|
|
91
160
|
kind: 'array',
|
|
92
|
-
length:
|
|
93
|
-
type: {
|
|
94
|
-
kind: 'struct',
|
|
95
|
-
path: 'authwit::entrypoint::function_call::FunctionCall',
|
|
96
|
-
fields: [
|
|
97
|
-
{ name: 'args_hash', type: { kind: 'field' } },
|
|
98
|
-
{
|
|
99
|
-
name: 'function_selector',
|
|
100
|
-
type: {
|
|
101
|
-
kind: 'struct',
|
|
102
|
-
path: 'authwit::aztec::protocol_types::abis::function_selector::FunctionSelector',
|
|
103
|
-
fields: [{ name: 'inner', type: { kind: 'integer', sign: 'unsigned', width: 32 } }],
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: 'target_address',
|
|
108
|
-
type: {
|
|
109
|
-
kind: 'struct',
|
|
110
|
-
path: 'authwit::aztec::protocol_types::address::AztecAddress',
|
|
111
|
-
fields: [{ name: 'inner', type: { kind: 'field' } }],
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
{ name: 'is_public', type: { kind: 'boolean' } },
|
|
115
|
-
{ name: 'is_static', type: { kind: 'boolean' } },
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
{ name: 'tx_nonce', type: { kind: 'field' } },
|
|
121
|
-
],
|
|
122
|
-
},
|
|
123
|
-
visibility: 'public',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: 'fee_payload',
|
|
127
|
-
type: {
|
|
128
|
-
kind: 'struct',
|
|
129
|
-
path: 'authwit::entrypoint::fee::FeePayload',
|
|
130
|
-
fields: [
|
|
131
|
-
{
|
|
132
|
-
name: 'function_calls',
|
|
133
|
-
type: {
|
|
134
|
-
kind: 'array',
|
|
135
|
-
length: 2,
|
|
161
|
+
length: 5,
|
|
136
162
|
type: {
|
|
137
163
|
kind: 'struct',
|
|
138
164
|
path: 'authwit::entrypoint::function_call::FunctionCall',
|
|
@@ -155,17 +181,18 @@ export class DefaultAccountEntrypoint implements EntrypointInterface {
|
|
|
155
181
|
},
|
|
156
182
|
},
|
|
157
183
|
{ name: 'is_public', type: { kind: 'boolean' } },
|
|
184
|
+
{ name: 'hide_msg_sender', type: { kind: 'boolean' } },
|
|
158
185
|
{ name: 'is_static', type: { kind: 'boolean' } },
|
|
159
186
|
],
|
|
160
187
|
},
|
|
161
188
|
},
|
|
162
189
|
},
|
|
163
190
|
{ name: 'tx_nonce', type: { kind: 'field' } },
|
|
164
|
-
{ name: 'is_fee_payer', type: { kind: 'boolean' } },
|
|
165
191
|
],
|
|
166
192
|
},
|
|
167
193
|
visibility: 'public',
|
|
168
194
|
},
|
|
195
|
+
{ name: 'fee_payment_method', type: { kind: 'integer', sign: 'unsigned', width: 8 } },
|
|
169
196
|
{ name: 'cancellable', type: { kind: 'boolean' } },
|
|
170
197
|
],
|
|
171
198
|
returnTypes: [],
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import { FunctionType } from '@aztec/stdlib/abi';
|
|
2
|
-
import {
|
|
2
|
+
import type { GasSettings } from '@aztec/stdlib/gas';
|
|
3
|
+
import { ExecutionPayload, HashedValues, TxContext, TxExecutionRequest } from '@aztec/stdlib/tx';
|
|
3
4
|
|
|
4
|
-
import type {
|
|
5
|
-
import type { ExecutionPayload } from './payload.js';
|
|
5
|
+
import type { ChainInfo, EntrypointInterface } from './interfaces.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Default implementation of the entrypoint interface. It calls a function on a contract directly
|
|
9
9
|
*/
|
|
10
10
|
export class DefaultEntrypoint implements EntrypointInterface {
|
|
11
|
-
constructor(
|
|
12
|
-
private chainId: number,
|
|
13
|
-
private rollupVersion: number,
|
|
14
|
-
) {}
|
|
15
|
-
|
|
16
11
|
async createTxExecutionRequest(
|
|
17
12
|
exec: ExecutionPayload,
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
gasSettings: GasSettings,
|
|
14
|
+
chainInfo: ChainInfo,
|
|
20
15
|
): Promise<TxExecutionRequest> {
|
|
21
|
-
if (options.txNonce || options.cancellable !== undefined) {
|
|
22
|
-
throw new Error('TxExecutionOptions are not supported in DefaultEntrypoint');
|
|
23
|
-
}
|
|
24
16
|
// Initial request with calls, authWitnesses and capsules
|
|
25
17
|
const { calls, authWitnesses, capsules, extraHashedArgs } = exec;
|
|
26
18
|
|
|
@@ -42,10 +34,28 @@ export class DefaultEntrypoint implements EntrypointInterface {
|
|
|
42
34
|
call.to,
|
|
43
35
|
call.selector,
|
|
44
36
|
hashedArguments[0].hash,
|
|
45
|
-
new TxContext(
|
|
37
|
+
new TxContext(chainInfo.chainId.toNumber(), chainInfo.version.toNumber(), gasSettings),
|
|
46
38
|
[...hashedArguments, ...extraHashedArgs],
|
|
47
39
|
authWitnesses,
|
|
48
40
|
capsules,
|
|
49
41
|
);
|
|
50
42
|
}
|
|
43
|
+
|
|
44
|
+
async wrapExecutionPayload(exec: ExecutionPayload, _options?: any): Promise<ExecutionPayload> {
|
|
45
|
+
if (exec.calls.length !== 1) {
|
|
46
|
+
throw new Error(`DefaultEntrypoint can only wrap a single call, got ${exec.calls.length}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const call = exec.calls[0];
|
|
50
|
+
|
|
51
|
+
const hashedArguments = await HashedValues.fromArgs(call.args);
|
|
52
|
+
|
|
53
|
+
return new ExecutionPayload(
|
|
54
|
+
[call],
|
|
55
|
+
exec.authWitnesses,
|
|
56
|
+
exec.capsules,
|
|
57
|
+
[hashedArguments, ...exec.extraHashedArgs],
|
|
58
|
+
exec.feePayer,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
51
61
|
}
|
|
@@ -1,50 +1,35 @@
|
|
|
1
|
-
import { Fr } from '@aztec/foundation/
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
2
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
3
|
-
import { type FunctionAbi, FunctionSelector, encodeArguments } from '@aztec/stdlib/abi';
|
|
3
|
+
import { type FunctionAbi, FunctionCall, FunctionSelector, encodeArguments } from '@aztec/stdlib/abi';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import {
|
|
5
|
+
import type { GasSettings } from '@aztec/stdlib/gas';
|
|
6
|
+
import { ExecutionPayload, HashedValues, TxContext, TxExecutionRequest } from '@aztec/stdlib/tx';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
import type {
|
|
9
|
-
import type { ExecutionPayload } from './payload.js';
|
|
8
|
+
import { EncodedAppEntrypointCalls } from './encoding.js';
|
|
9
|
+
import type { ChainInfo, EntrypointInterface } from './interfaces.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Implementation for an entrypoint interface that can execute multiple function calls in a single transaction
|
|
13
13
|
*/
|
|
14
14
|
export class DefaultMultiCallEntrypoint implements EntrypointInterface {
|
|
15
|
-
constructor(
|
|
16
|
-
private chainId: number,
|
|
17
|
-
private version: number,
|
|
18
|
-
private address: AztecAddress = ProtocolContractAddress.MultiCallEntrypoint,
|
|
19
|
-
) {}
|
|
15
|
+
constructor(private address: AztecAddress = ProtocolContractAddress.MultiCallEntrypoint) {}
|
|
20
16
|
|
|
21
|
-
async createTxExecutionRequest(
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
async createTxExecutionRequest(
|
|
18
|
+
exec: ExecutionPayload,
|
|
19
|
+
gasSettings: GasSettings,
|
|
20
|
+
chainInfo: ChainInfo,
|
|
21
|
+
): Promise<TxExecutionRequest> {
|
|
22
|
+
const { authWitnesses, capsules, extraHashedArgs } = exec;
|
|
23
|
+
const callData = await this.#buildEntrypointCallData(exec);
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
const {
|
|
27
|
-
calls: feeCalls,
|
|
28
|
-
authWitnesses: feeAuthwitnesses,
|
|
29
|
-
extraHashedArgs: feeExtraHashedArgs,
|
|
30
|
-
} = await fee.paymentMethod.getExecutionPayload(fee.gasSettings);
|
|
31
|
-
|
|
32
|
-
// Encode the calls, including the fee calls
|
|
33
|
-
// (since this entrypoint does not distinguish between app and fee calls)
|
|
34
|
-
const encodedCalls = await EncodedCallsForEntrypoint.fromAppExecution(calls.concat(feeCalls));
|
|
35
|
-
|
|
36
|
-
// Obtain the entrypoint hashed args, built from the encoded calls
|
|
37
|
-
const abi = this.getEntrypointAbi();
|
|
38
|
-
const entrypointHashedArgs = await HashedValues.fromArgs(encodeArguments(abi, [encodedCalls]));
|
|
39
|
-
|
|
40
|
-
// Assemble the tx request
|
|
25
|
+
const entrypointHashedArgs = await HashedValues.fromArgs(callData.encodedArgs);
|
|
41
26
|
const txRequest = TxExecutionRequest.from({
|
|
42
27
|
firstCallArgsHash: entrypointHashedArgs.hash,
|
|
43
28
|
origin: this.address,
|
|
44
|
-
functionSelector:
|
|
45
|
-
txContext: new TxContext(
|
|
46
|
-
argsOfCalls: [...encodedCalls.hashedArguments, entrypointHashedArgs, ...extraHashedArgs
|
|
47
|
-
authWitnesses
|
|
29
|
+
functionSelector: callData.functionSelector,
|
|
30
|
+
txContext: new TxContext(chainInfo.chainId.toNumber(), chainInfo.version.toNumber(), gasSettings),
|
|
31
|
+
argsOfCalls: [...callData.encodedCalls.hashedArguments, entrypointHashedArgs, ...extraHashedArgs],
|
|
32
|
+
authWitnesses,
|
|
48
33
|
capsules,
|
|
49
34
|
salt: Fr.random(),
|
|
50
35
|
});
|
|
@@ -52,12 +37,59 @@ export class DefaultMultiCallEntrypoint implements EntrypointInterface {
|
|
|
52
37
|
return Promise.resolve(txRequest);
|
|
53
38
|
}
|
|
54
39
|
|
|
40
|
+
async wrapExecutionPayload(exec: ExecutionPayload, _options?: any): Promise<ExecutionPayload> {
|
|
41
|
+
const { authWitnesses, capsules, extraHashedArgs } = exec;
|
|
42
|
+
const callData = await this.#buildEntrypointCallData(exec);
|
|
43
|
+
const entrypointCall = FunctionCall.from({
|
|
44
|
+
name: callData.abi.name,
|
|
45
|
+
to: this.address,
|
|
46
|
+
selector: callData.functionSelector,
|
|
47
|
+
type: callData.abi.functionType,
|
|
48
|
+
hideMsgSender: false,
|
|
49
|
+
isStatic: callData.abi.isStatic,
|
|
50
|
+
args: callData.encodedArgs,
|
|
51
|
+
returnTypes: callData.abi.returnTypes,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return new ExecutionPayload(
|
|
55
|
+
[entrypointCall],
|
|
56
|
+
authWitnesses,
|
|
57
|
+
capsules,
|
|
58
|
+
[...callData.encodedCalls.hashedArguments, ...extraHashedArgs],
|
|
59
|
+
exec.feePayer,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Builds the shared data needed for both creating a tx execution request and wrapping an execution payload.
|
|
65
|
+
* This includes encoding calls and building entrypoint arguments.
|
|
66
|
+
* @param exec - The execution payload containing calls to encode
|
|
67
|
+
* @returns Encoded call data, ABI, encoded arguments, and function selector
|
|
68
|
+
*/
|
|
69
|
+
async #buildEntrypointCallData(exec: ExecutionPayload) {
|
|
70
|
+
const { calls } = exec;
|
|
71
|
+
|
|
72
|
+
const encodedCalls = await EncodedAppEntrypointCalls.create(calls);
|
|
73
|
+
|
|
74
|
+
const abi = this.getEntrypointAbi();
|
|
75
|
+
const encodedArgs = encodeArguments(abi, [encodedCalls]);
|
|
76
|
+
|
|
77
|
+
const functionSelector = await FunctionSelector.fromNameAndParameters(abi.name, abi.parameters);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
encodedCalls,
|
|
81
|
+
abi,
|
|
82
|
+
encodedArgs,
|
|
83
|
+
functionSelector,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
55
87
|
private getEntrypointAbi() {
|
|
56
88
|
return {
|
|
57
89
|
name: 'entrypoint',
|
|
58
90
|
isInitializer: false,
|
|
59
91
|
functionType: 'private',
|
|
60
|
-
|
|
92
|
+
isOnlySelf: false,
|
|
61
93
|
isStatic: false,
|
|
62
94
|
parameters: [
|
|
63
95
|
{
|
|
@@ -70,7 +102,7 @@ export class DefaultMultiCallEntrypoint implements EntrypointInterface {
|
|
|
70
102
|
name: 'function_calls',
|
|
71
103
|
type: {
|
|
72
104
|
kind: 'array',
|
|
73
|
-
length:
|
|
105
|
+
length: 5,
|
|
74
106
|
type: {
|
|
75
107
|
kind: 'struct',
|
|
76
108
|
path: 'authwit::entrypoint::function_call::FunctionCall',
|
|
@@ -93,6 +125,7 @@ export class DefaultMultiCallEntrypoint implements EntrypointInterface {
|
|
|
93
125
|
},
|
|
94
126
|
},
|
|
95
127
|
{ name: 'is_public', type: { kind: 'boolean' } },
|
|
128
|
+
{ name: 'hide_msg_sender', type: { kind: 'boolean' } },
|
|
96
129
|
{ name: 'is_static', type: { kind: 'boolean' } },
|
|
97
130
|
],
|
|
98
131
|
},
|
package/src/encoding.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DomainSeparator } from '@aztec/constants';
|
|
2
2
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
|
-
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto';
|
|
4
|
-
import { Fr } from '@aztec/foundation/
|
|
3
|
+
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import type { Tuple } from '@aztec/foundation/serialize';
|
|
6
6
|
import { FunctionCall, FunctionType } from '@aztec/stdlib/abi';
|
|
7
7
|
import { HashedValues } from '@aztec/stdlib/tx';
|
|
8
8
|
|
|
9
9
|
// These must match the values defined in:
|
|
10
10
|
// - noir-projects/aztec-nr/aztec/src/entrypoint/app.nr
|
|
11
|
-
const APP_MAX_CALLS =
|
|
12
|
-
// - and noir-projects/aztec-nr/aztec/src/entrypoint/fee.nr
|
|
13
|
-
const FEE_MAX_CALLS = 2;
|
|
11
|
+
export const APP_MAX_CALLS = 5;
|
|
14
12
|
|
|
15
13
|
/** Encoded function call for an Aztec entrypoint */
|
|
16
14
|
export type EncodedFunctionCall = {
|
|
@@ -23,6 +21,8 @@ export type EncodedFunctionCall = {
|
|
|
23
21
|
target_address: Fr;
|
|
24
22
|
/** Whether the function is public or private */
|
|
25
23
|
is_public: boolean;
|
|
24
|
+
/** Only applicable for enqueued public function calls. Whether the msg_sender will be set to "null". */
|
|
25
|
+
hide_msg_sender: boolean;
|
|
26
26
|
/** Whether the function can alter state */
|
|
27
27
|
is_static: boolean;
|
|
28
28
|
};
|
|
@@ -40,14 +40,14 @@ export type EncodedCalls = {
|
|
|
40
40
|
* This utility class helps in creating the payload for the entrypoint by taking into
|
|
41
41
|
* account how the calls are encoded and hashed.
|
|
42
42
|
* */
|
|
43
|
-
export
|
|
43
|
+
export class EncodedAppEntrypointCalls implements EncodedCalls {
|
|
44
44
|
constructor(
|
|
45
45
|
/** Function calls in the expected format (Noir's convention) */
|
|
46
46
|
public encodedFunctionCalls: EncodedFunctionCall[],
|
|
47
47
|
/** The hashed args for the call, ready to be injected in the execution cache */
|
|
48
48
|
public hashedArguments: HashedValues[],
|
|
49
49
|
/** The index of the generator to use for hashing */
|
|
50
|
-
public
|
|
50
|
+
public domainSeparator: number,
|
|
51
51
|
/**
|
|
52
52
|
* A nonce to inject into the payload of the transaction. When used with cancellable=true, this nonce will be
|
|
53
53
|
* used to compute a nullifier that allows cancelling this transaction by submitting a new one with the same nonce
|
|
@@ -71,14 +71,16 @@ export abstract class EncodedCallsForEntrypoint implements EncodedCalls {
|
|
|
71
71
|
* Serializes the payload to an array of fields
|
|
72
72
|
* @returns The fields of the payload
|
|
73
73
|
*/
|
|
74
|
-
|
|
74
|
+
toFields(): Fr[] {
|
|
75
|
+
return [...this.functionCallsToFields(), this.tx_nonce];
|
|
76
|
+
}
|
|
75
77
|
|
|
76
78
|
/**
|
|
77
79
|
* Hashes the payload
|
|
78
80
|
* @returns The hash of the payload
|
|
79
81
|
*/
|
|
80
82
|
hash() {
|
|
81
|
-
return poseidon2HashWithSeparator(this.toFields(), this.
|
|
83
|
+
return poseidon2HashWithSeparator(this.toFields(), this.domainSeparator);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/** Serializes the function calls to an array of fields. */
|
|
@@ -88,20 +90,11 @@ export abstract class EncodedCallsForEntrypoint implements EncodedCalls {
|
|
|
88
90
|
call.function_selector,
|
|
89
91
|
call.target_address,
|
|
90
92
|
new Fr(call.is_public),
|
|
93
|
+
new Fr(call.hide_msg_sender),
|
|
91
94
|
new Fr(call.is_static),
|
|
92
95
|
]);
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
/**
|
|
96
|
-
* Encodes a set of function calls for a dapp entrypoint
|
|
97
|
-
* @param functionCalls - The function calls to execute
|
|
98
|
-
* @returns The encoded calls
|
|
99
|
-
*/
|
|
100
|
-
static async fromFunctionCalls(functionCalls: FunctionCall[]) {
|
|
101
|
-
const encoded = await encode(functionCalls);
|
|
102
|
-
return new EncodedAppEntrypointCalls(encoded.encodedFunctionCalls, encoded.hashedArguments, 0, Fr.random());
|
|
103
|
-
}
|
|
104
|
-
|
|
105
98
|
/**
|
|
106
99
|
* Encodes the functions for the app-portion of a transaction from a set of function calls and a nonce
|
|
107
100
|
* @param functionCalls - The function calls to execute
|
|
@@ -109,7 +102,7 @@ export abstract class EncodedCallsForEntrypoint implements EncodedCalls {
|
|
|
109
102
|
* nonce can be replaced by submitting a new one with a higher fee.
|
|
110
103
|
* @returns The encoded calls
|
|
111
104
|
*/
|
|
112
|
-
static async
|
|
105
|
+
static async create(
|
|
113
106
|
functionCalls: FunctionCall[] | Tuple<FunctionCall, typeof APP_MAX_CALLS>,
|
|
114
107
|
txNonce = Fr.random(),
|
|
115
108
|
) {
|
|
@@ -121,90 +114,10 @@ export abstract class EncodedCallsForEntrypoint implements EncodedCalls {
|
|
|
121
114
|
return new EncodedAppEntrypointCalls(
|
|
122
115
|
encoded.encodedFunctionCalls,
|
|
123
116
|
encoded.hashedArguments,
|
|
124
|
-
|
|
117
|
+
DomainSeparator.SIGNATURE_PAYLOAD,
|
|
125
118
|
txNonce,
|
|
126
119
|
);
|
|
127
120
|
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Creates an encoded set of functions to pay the fee for a transaction
|
|
131
|
-
* @param functionCalls - The calls generated by the payment method
|
|
132
|
-
* @param isFeePayer - Whether the sender should be appointed as fee payer
|
|
133
|
-
* @returns The encoded calls
|
|
134
|
-
*/
|
|
135
|
-
static async fromFeeCalls(
|
|
136
|
-
functionCalls: FunctionCall[] | Tuple<FunctionCall, typeof FEE_MAX_CALLS>,
|
|
137
|
-
isFeePayer: boolean,
|
|
138
|
-
) {
|
|
139
|
-
const paddedCalls = padArrayEnd(functionCalls, FunctionCall.empty(), FEE_MAX_CALLS);
|
|
140
|
-
const encoded = await encode(paddedCalls);
|
|
141
|
-
return new EncodedFeeEntrypointCalls(
|
|
142
|
-
encoded.encodedFunctionCalls,
|
|
143
|
-
encoded.hashedArguments,
|
|
144
|
-
GeneratorIndex.FEE_PAYLOAD,
|
|
145
|
-
Fr.random(),
|
|
146
|
-
isFeePayer,
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** Encoded calls for app phase execution. */
|
|
152
|
-
export class EncodedAppEntrypointCalls extends EncodedCallsForEntrypoint {
|
|
153
|
-
constructor(
|
|
154
|
-
encodedFunctionCalls: EncodedFunctionCall[],
|
|
155
|
-
hashedArguments: HashedValues[],
|
|
156
|
-
generatorIndex: number,
|
|
157
|
-
txNonce: Fr,
|
|
158
|
-
) {
|
|
159
|
-
super(encodedFunctionCalls, hashedArguments, generatorIndex, txNonce);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
override toFields(): Fr[] {
|
|
163
|
-
return [...this.functionCallsToFields(), this.tx_nonce];
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** Encoded calls for fee payment */
|
|
168
|
-
export class EncodedFeeEntrypointCalls extends EncodedCallsForEntrypoint {
|
|
169
|
-
#isFeePayer: boolean;
|
|
170
|
-
|
|
171
|
-
constructor(
|
|
172
|
-
encodedFunctionCalls: EncodedFunctionCall[],
|
|
173
|
-
hashedArguments: HashedValues[],
|
|
174
|
-
generatorIndex: number,
|
|
175
|
-
txNonce: Fr,
|
|
176
|
-
isFeePayer: boolean,
|
|
177
|
-
) {
|
|
178
|
-
super(encodedFunctionCalls, hashedArguments, generatorIndex, txNonce);
|
|
179
|
-
this.#isFeePayer = isFeePayer;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
override toFields(): Fr[] {
|
|
183
|
-
return [...this.functionCallsToFields(), this.tx_nonce, new Fr(this.#isFeePayer)];
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/* eslint-disable camelcase */
|
|
187
|
-
/** Whether the sender should be appointed as fee payer. */
|
|
188
|
-
get is_fee_payer() {
|
|
189
|
-
return this.#isFeePayer;
|
|
190
|
-
}
|
|
191
|
-
/* eslint-enable camelcase */
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Computes a hash of a combined set of app and fee calls.
|
|
196
|
-
* @param appCalls - A set of app calls.
|
|
197
|
-
* @param feeCalls - A set of calls used to pay fees.
|
|
198
|
-
* @returns A hash of a combined call set.
|
|
199
|
-
*/
|
|
200
|
-
export async function computeCombinedPayloadHash(
|
|
201
|
-
appPayload: EncodedAppEntrypointCalls,
|
|
202
|
-
feePayload: EncodedFeeEntrypointCalls,
|
|
203
|
-
): Promise<Fr> {
|
|
204
|
-
return poseidon2HashWithSeparator(
|
|
205
|
-
[await appPayload.hash(), await feePayload.hash()],
|
|
206
|
-
GeneratorIndex.COMBINED_PAYLOAD,
|
|
207
|
-
);
|
|
208
121
|
}
|
|
209
122
|
|
|
210
123
|
/** Encodes FunctionCalls for execution, following Noir's convention */
|
|
@@ -224,6 +137,7 @@ export async function encode(calls: FunctionCall[]): Promise<EncodedCalls> {
|
|
|
224
137
|
function_selector: call.selector.toField(),
|
|
225
138
|
target_address: call.to.toField(),
|
|
226
139
|
is_public: call.type == FunctionType.PUBLIC,
|
|
140
|
+
hide_msg_sender: call.hideMsgSender,
|
|
227
141
|
is_static: call.isStatic,
|
|
228
142
|
}));
|
|
229
143
|
|