@aztec/aztec.js 0.23.0 → 0.26.1
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/index.d.ts +1 -1
- package/dest/account/index.d.ts.map +1 -1
- package/dest/account/interface.d.ts +12 -2
- package/dest/account/interface.d.ts.map +1 -1
- package/dest/account/interface.js +1 -1
- package/dest/account_manager/index.d.ts +4 -2
- package/dest/account_manager/index.d.ts.map +1 -1
- package/dest/account_manager/index.js +15 -6
- package/dest/api/account.d.ts +1 -1
- package/dest/api/account.d.ts.map +1 -1
- package/dest/api/account.js +1 -1
- package/dest/api/deployment.d.ts +4 -0
- package/dest/api/deployment.d.ts.map +1 -0
- package/dest/api/deployment.js +4 -0
- package/dest/api/fee.d.ts +5 -0
- package/dest/api/fee.d.ts.map +1 -0
- package/dest/api/fee.js +4 -0
- package/dest/contract/base_contract_interaction.d.ts +5 -0
- package/dest/contract/base_contract_interaction.d.ts.map +1 -1
- package/dest/contract/base_contract_interaction.js +1 -1
- package/dest/contract/batch_call.d.ts +3 -2
- package/dest/contract/batch_call.d.ts.map +1 -1
- package/dest/contract/batch_call.js +4 -3
- package/dest/contract/contract.d.ts +4 -2
- package/dest/contract/contract.d.ts.map +1 -1
- package/dest/contract/contract.js +7 -5
- package/dest/contract/contract_function_interaction.d.ts +2 -2
- package/dest/contract/contract_function_interaction.d.ts.map +1 -1
- package/dest/contract/contract_function_interaction.js +4 -4
- package/dest/contract/deploy_method.d.ts +37 -12
- package/dest/contract/deploy_method.d.ts.map +1 -1
- package/dest/contract/deploy_method.js +79 -35
- package/dest/contract/deploy_sent_tx.d.ts +3 -3
- package/dest/contract/deploy_sent_tx.d.ts.map +1 -1
- package/dest/contract/deploy_sent_tx.js +4 -7
- package/dest/contract/sent_tx.d.ts.map +1 -1
- package/dest/contract/sent_tx.js +10 -10
- package/dest/contract/unsafe_contract.d.ts +15 -0
- package/dest/contract/unsafe_contract.d.ts.map +1 -0
- package/dest/contract/unsafe_contract.js +14 -0
- package/dest/deployment/broadcast_function.d.ts +24 -0
- package/dest/deployment/broadcast_function.d.ts.map +1 -0
- package/dest/deployment/broadcast_function.js +67 -0
- package/dest/{contract_deployer → deployment}/contract_deployer.d.ts +4 -3
- package/dest/deployment/contract_deployer.d.ts.map +1 -0
- package/dest/{contract_deployer → deployment}/contract_deployer.js +5 -4
- package/dest/deployment/deploy_instance.d.ts +13 -0
- package/dest/deployment/deploy_instance.d.ts.map +1 -0
- package/dest/deployment/deploy_instance.js +13 -0
- package/dest/deployment/index.d.ts.map +1 -0
- package/dest/{contract_deployer → deployment}/index.js +1 -1
- package/dest/deployment/protocol_contracts.d.ts +7 -0
- package/dest/deployment/protocol_contracts.d.ts.map +1 -0
- package/dest/deployment/protocol_contracts.js +14 -0
- package/dest/deployment/register_class.d.ts +6 -0
- package/dest/deployment/register_class.d.ts.map +1 -0
- package/dest/deployment/register_class.js +12 -0
- package/dest/fee/fee_payment_method.d.ts +24 -0
- package/dest/fee/fee_payment_method.d.ts.map +1 -0
- package/dest/fee/fee_payment_method.js +2 -0
- package/dest/fee/native_fee_payment_method.d.ts +32 -0
- package/dest/fee/native_fee_payment_method.d.ts.map +1 -0
- package/dest/fee/native_fee_payment_method.js +54 -0
- package/dest/fee/private_fee_payment_method.d.ts +52 -0
- package/dest/fee/private_fee_payment_method.d.ts.map +1 -0
- package/dest/fee/private_fee_payment_method.js +62 -0
- package/dest/fee/public_fee_payment_method.d.ts +52 -0
- package/dest/fee/public_fee_payment_method.d.ts.map +1 -0
- package/dest/fee/public_fee_payment_method.js +62 -0
- package/dest/index.d.ts +6 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +7 -5
- package/dest/rpc_clients/pxe_client.d.ts.map +1 -1
- package/dest/rpc_clients/pxe_client.js +15 -15
- package/dest/utils/authwit.d.ts +30 -4
- package/dest/utils/authwit.d.ts.map +1 -1
- package/dest/utils/authwit.js +35 -5
- package/dest/utils/cheat_codes.js +3 -3
- package/dest/utils/index.d.ts +0 -1
- package/dest/utils/index.d.ts.map +1 -1
- package/dest/utils/index.js +1 -2
- package/dest/utils/l2_contracts.js +2 -2
- package/dest/wallet/account_wallet.d.ts +10 -3
- package/dest/wallet/account_wallet.d.ts.map +1 -1
- package/dest/wallet/account_wallet.js +34 -10
- package/dest/wallet/base_wallet.d.ts +7 -4
- package/dest/wallet/base_wallet.d.ts.map +1 -1
- package/dest/wallet/base_wallet.js +9 -3
- package/dest/wallet/signerless_wallet.js +2 -2
- package/package.json +9 -6
- package/src/account/contract.ts +33 -0
- package/src/account/index.ts +16 -0
- package/src/account/interface.ts +47 -0
- package/src/account/wallet.ts +8 -0
- package/src/account_manager/deploy_account_sent_tx.ts +42 -0
- package/src/account_manager/index.ts +188 -0
- package/src/api/README.md +7 -0
- package/src/api/abi.ts +3 -0
- package/src/api/account.ts +13 -0
- package/src/api/aztec_address.ts +1 -0
- package/src/api/deployment.ts +3 -0
- package/src/api/eth_address.ts +1 -0
- package/src/api/ethereum.ts +6 -0
- package/src/api/fee.ts +4 -0
- package/src/api/fields.ts +1 -0
- package/src/api/init.ts +10 -0
- package/src/api/interfaces/pxe.ts +1 -0
- package/src/api/log_id.ts +1 -0
- package/src/api/tx_hash.ts +1 -0
- package/src/api/wallet.ts +1 -0
- package/src/contract/base_contract_interaction.ts +67 -0
- package/src/contract/batch_call.ts +24 -0
- package/src/contract/checker.ts +117 -0
- package/src/contract/contract.ts +64 -0
- package/src/contract/contract_base.ts +72 -0
- package/src/contract/contract_function_interaction.ts +80 -0
- package/src/contract/deploy_method.ts +192 -0
- package/src/contract/deploy_sent_tx.ts +66 -0
- package/src/contract/index.ts +44 -0
- package/src/contract/sent_tx.ts +135 -0
- package/src/contract/unsafe_contract.ts +19 -0
- package/src/deployment/broadcast_function.ts +118 -0
- package/src/deployment/contract_deployer.ts +42 -0
- package/src/deployment/deploy_instance.ts +28 -0
- package/src/deployment/index.ts +1 -0
- package/src/deployment/protocol_contracts.ts +17 -0
- package/src/deployment/register_class.ts +19 -0
- package/src/fee/fee_payment_method.ts +25 -0
- package/src/fee/native_fee_payment_method.ts +60 -0
- package/src/fee/private_fee_payment_method.ts +79 -0
- package/src/fee/public_fee_payment_method.ts +79 -0
- package/src/index.ts +150 -0
- package/src/rpc_clients/index.ts +1 -0
- package/src/rpc_clients/pxe_client.ts +63 -0
- package/src/utils/abi_types.ts +16 -0
- package/src/utils/account.ts +32 -0
- package/src/utils/authwit.ts +62 -0
- package/src/utils/cheat_codes.ts +297 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/l1_contracts.ts +21 -0
- package/src/utils/l2_contracts.ts +12 -0
- package/src/utils/pub_key.ts +12 -0
- package/src/utils/pxe.ts +16 -0
- package/src/wallet/account_wallet.ts +94 -0
- package/src/wallet/account_wallet_with_private_key.ts +28 -0
- package/src/wallet/base_wallet.ts +129 -0
- package/src/wallet/create_recipient.ts +13 -0
- package/src/wallet/index.ts +31 -0
- package/src/wallet/signerless_wallet.ts +37 -0
- package/dest/contract_deployer/contract_deployer.d.ts.map +0 -1
- package/dest/contract_deployer/index.d.ts.map +0 -1
- package/dest/utils/secrets.d.ts +0 -8
- package/dest/utils/secrets.d.ts.map +0 -1
- package/dest/utils/secrets.js +0 -10
- /package/dest/{contract_deployer → deployment}/index.d.ts +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { Note, PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { AztecAddress, EthAddress, Fr } from '@aztec/circuits.js';
|
|
3
|
+
import { toBigIntBE, toHex } from '@aztec/foundation/bigint-buffer';
|
|
4
|
+
import { keccak, pedersenHash } from '@aztec/foundation/crypto';
|
|
5
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A class that provides utility functions for interacting with the chain.
|
|
11
|
+
*/
|
|
12
|
+
export class CheatCodes {
|
|
13
|
+
constructor(
|
|
14
|
+
/**
|
|
15
|
+
* The cheat codes for ethereum (L1).
|
|
16
|
+
*/
|
|
17
|
+
public eth: EthCheatCodes,
|
|
18
|
+
/**
|
|
19
|
+
* The cheat codes for aztec.
|
|
20
|
+
*/
|
|
21
|
+
public aztec: AztecCheatCodes,
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
static create(rpcUrl: string, pxe: PXE): CheatCodes {
|
|
25
|
+
const ethCheatCodes = new EthCheatCodes(rpcUrl);
|
|
26
|
+
const aztecCheatCodes = new AztecCheatCodes(pxe, ethCheatCodes);
|
|
27
|
+
return new CheatCodes(ethCheatCodes, aztecCheatCodes);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A class that provides utility functions for interacting with ethereum (L1).
|
|
33
|
+
*/
|
|
34
|
+
export class EthCheatCodes {
|
|
35
|
+
constructor(
|
|
36
|
+
/**
|
|
37
|
+
* The RPC URL to use for interacting with the chain
|
|
38
|
+
*/
|
|
39
|
+
public rpcUrl: string,
|
|
40
|
+
/**
|
|
41
|
+
* The logger to use for the eth cheatcodes
|
|
42
|
+
*/
|
|
43
|
+
public logger = createDebugLogger('aztec:cheat_codes:eth'),
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
async rpcCall(method: string, params: any[]) {
|
|
47
|
+
const paramsString = JSON.stringify(params);
|
|
48
|
+
const content = {
|
|
49
|
+
body: `{"jsonrpc":"2.0", "method": "${method}", "params": ${paramsString}, "id": 1}`,
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: { 'Content-Type': 'application/json' },
|
|
52
|
+
};
|
|
53
|
+
return await (await fetch(this.rpcUrl, content)).json();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get the current blocknumber
|
|
58
|
+
* @returns The current block number
|
|
59
|
+
*/
|
|
60
|
+
public async blockNumber(): Promise<number> {
|
|
61
|
+
const res = await this.rpcCall('eth_blockNumber', []);
|
|
62
|
+
return parseInt(res.result, 16);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get the current chainId
|
|
67
|
+
* @returns The current chainId
|
|
68
|
+
*/
|
|
69
|
+
public async chainId(): Promise<number> {
|
|
70
|
+
const res = await this.rpcCall('eth_chainId', []);
|
|
71
|
+
return parseInt(res.result, 16);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get the current timestamp
|
|
76
|
+
* @returns The current timestamp
|
|
77
|
+
*/
|
|
78
|
+
public async timestamp(): Promise<number> {
|
|
79
|
+
const res = await this.rpcCall('eth_getBlockByNumber', ['latest', true]);
|
|
80
|
+
return parseInt(res.result.timestamp, 16);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Advance the chain by a number of blocks
|
|
85
|
+
* @param numberOfBlocks - The number of blocks to mine
|
|
86
|
+
* @returns The current chainId
|
|
87
|
+
*/
|
|
88
|
+
public async mine(numberOfBlocks = 1): Promise<void> {
|
|
89
|
+
const res = await this.rpcCall('hardhat_mine', [numberOfBlocks]);
|
|
90
|
+
if (res.error) {
|
|
91
|
+
throw new Error(`Error mining: ${res.error.message}`);
|
|
92
|
+
}
|
|
93
|
+
this.logger(`Mined ${numberOfBlocks} blocks`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Set the next block timestamp
|
|
98
|
+
* @param timestamp - The timestamp to set the next block to
|
|
99
|
+
*/
|
|
100
|
+
public async setNextBlockTimestamp(timestamp: number): Promise<void> {
|
|
101
|
+
const res = await this.rpcCall('evm_setNextBlockTimestamp', [timestamp]);
|
|
102
|
+
if (res.error) {
|
|
103
|
+
throw new Error(`Error setting next block timestamp: ${res.error.message}`);
|
|
104
|
+
}
|
|
105
|
+
this.logger(`Set next block timestamp to ${timestamp}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Dumps the current chain state to a file.
|
|
110
|
+
* @param fileName - The file name to dump state into
|
|
111
|
+
*/
|
|
112
|
+
public async dumpChainState(fileName: string): Promise<void> {
|
|
113
|
+
const res = await this.rpcCall('hardhat_dumpState', []);
|
|
114
|
+
if (res.error) {
|
|
115
|
+
throw new Error(`Error dumping state: ${res.error.message}`);
|
|
116
|
+
}
|
|
117
|
+
const jsonContent = JSON.stringify(res.result);
|
|
118
|
+
fs.writeFileSync(`${fileName}.json`, jsonContent, 'utf8');
|
|
119
|
+
this.logger(`Dumped state to ${fileName}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Loads the chain state from a file.
|
|
124
|
+
* @param fileName - The file name to load state from
|
|
125
|
+
*/
|
|
126
|
+
public async loadChainState(fileName: string): Promise<void> {
|
|
127
|
+
const data = JSON.parse(fs.readFileSync(`${fileName}.json`, 'utf8'));
|
|
128
|
+
const res = await this.rpcCall('hardhat_loadState', [data]);
|
|
129
|
+
if (res.error) {
|
|
130
|
+
throw new Error(`Error loading state: ${res.error.message}`);
|
|
131
|
+
}
|
|
132
|
+
this.logger(`Loaded state from ${fileName}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Load the value at a storage slot of a contract address on eth
|
|
137
|
+
* @param contract - The contract address
|
|
138
|
+
* @param slot - The storage slot
|
|
139
|
+
* @returns - The value at the storage slot
|
|
140
|
+
*/
|
|
141
|
+
public async load(contract: EthAddress, slot: bigint): Promise<bigint> {
|
|
142
|
+
const res = await this.rpcCall('eth_getStorageAt', [contract.toString(), toHex(slot), 'latest']);
|
|
143
|
+
return BigInt(res.result);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Set the value at a storage slot of a contract address on eth
|
|
148
|
+
* @param contract - The contract address
|
|
149
|
+
* @param slot - The storage slot
|
|
150
|
+
* @param value - The value to set the storage slot to
|
|
151
|
+
*/
|
|
152
|
+
public async store(contract: EthAddress, slot: bigint, value: bigint): Promise<void> {
|
|
153
|
+
// for the rpc call, we need to change value to be a 32 byte hex string.
|
|
154
|
+
const res = await this.rpcCall('hardhat_setStorageAt', [contract.toString(), toHex(slot), toHex(value, true)]);
|
|
155
|
+
if (res.error) {
|
|
156
|
+
throw new Error(`Error setting storage for contract ${contract} at ${slot}: ${res.error.message}`);
|
|
157
|
+
}
|
|
158
|
+
this.logger(`Set storage for contract ${contract} at ${slot} to ${value}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Computes the slot value for a given map and key.
|
|
163
|
+
* @param baseSlot - The base slot of the map (specified in Aztec.nr contract)
|
|
164
|
+
* @param key - The key to lookup in the map
|
|
165
|
+
* @returns The storage slot of the value in the map
|
|
166
|
+
*/
|
|
167
|
+
public keccak256(baseSlot: bigint, key: bigint): bigint {
|
|
168
|
+
// abi encode (removing the 0x) - concat key and baseSlot (both padded to 32 bytes)
|
|
169
|
+
const abiEncoded = toHex(key, true).substring(2) + toHex(baseSlot, true).substring(2);
|
|
170
|
+
return toBigIntBE(keccak(Buffer.from(abiEncoded, 'hex')));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Send transactions impersonating an externally owned account or contract.
|
|
175
|
+
* @param who - The address to impersonate
|
|
176
|
+
*/
|
|
177
|
+
public async startImpersonating(who: EthAddress): Promise<void> {
|
|
178
|
+
const res = await this.rpcCall('hardhat_impersonateAccount', [who.toString()]);
|
|
179
|
+
if (res.error) {
|
|
180
|
+
throw new Error(`Error impersonating ${who}: ${res.error.message}`);
|
|
181
|
+
}
|
|
182
|
+
this.logger(`Impersonating ${who}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Stop impersonating an account that you are currently impersonating.
|
|
187
|
+
* @param who - The address to stop impersonating
|
|
188
|
+
*/
|
|
189
|
+
public async stopImpersonating(who: EthAddress): Promise<void> {
|
|
190
|
+
const res = await this.rpcCall('hardhat_stopImpersonatingAccount', [who.toString()]);
|
|
191
|
+
if (res.error) {
|
|
192
|
+
throw new Error(`Error when stopping the impersonation of ${who}: ${res.error.message}`);
|
|
193
|
+
}
|
|
194
|
+
this.logger(`Stopped impersonating ${who}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Set the bytecode for a contract
|
|
199
|
+
* @param contract - The contract address
|
|
200
|
+
* @param bytecode - The bytecode to set
|
|
201
|
+
*/
|
|
202
|
+
public async etch(contract: EthAddress, bytecode: `0x${string}`): Promise<void> {
|
|
203
|
+
const res = await this.rpcCall('hardhat_setCode', [contract.toString(), bytecode]);
|
|
204
|
+
if (res.error) {
|
|
205
|
+
throw new Error(`Error setting bytecode for ${contract}: ${res.error.message}`);
|
|
206
|
+
}
|
|
207
|
+
this.logger(`Set bytecode for ${contract} to ${bytecode}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get the bytecode for a contract
|
|
212
|
+
* @param contract - The contract address
|
|
213
|
+
* @returns The bytecode for the contract
|
|
214
|
+
*/
|
|
215
|
+
public async getBytecode(contract: EthAddress): Promise<`0x${string}`> {
|
|
216
|
+
const res = await this.rpcCall('eth_getCode', [contract.toString(), 'latest']);
|
|
217
|
+
return res.result;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* A class that provides utility functions for interacting with the aztec chain.
|
|
223
|
+
*/
|
|
224
|
+
export class AztecCheatCodes {
|
|
225
|
+
constructor(
|
|
226
|
+
/**
|
|
227
|
+
* The PXE Service to use for interacting with the chain
|
|
228
|
+
*/
|
|
229
|
+
public pxe: PXE,
|
|
230
|
+
/**
|
|
231
|
+
* The eth cheat codes.
|
|
232
|
+
*/
|
|
233
|
+
public eth: EthCheatCodes,
|
|
234
|
+
/**
|
|
235
|
+
* The logger to use for the aztec cheatcodes
|
|
236
|
+
*/
|
|
237
|
+
public logger = createDebugLogger('aztec:cheat_codes:aztec'),
|
|
238
|
+
) {}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Computes the slot value for a given map and key.
|
|
242
|
+
* @param baseSlot - The base slot of the map (specified in Aztec.nr contract)
|
|
243
|
+
* @param key - The key to lookup in the map
|
|
244
|
+
* @returns The storage slot of the value in the map
|
|
245
|
+
*/
|
|
246
|
+
public computeSlotInMap(baseSlot: Fr | bigint, key: Fr | bigint | AztecAddress): Fr {
|
|
247
|
+
// Based on `at` function in
|
|
248
|
+
// aztec3-packages/aztec-nr/aztec/src/state_vars/map.nr
|
|
249
|
+
return pedersenHash([new Fr(baseSlot), new Fr(key)].map(f => f.toBuffer()));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Get the current blocknumber
|
|
254
|
+
* @returns The current block number
|
|
255
|
+
*/
|
|
256
|
+
public async blockNumber(): Promise<number> {
|
|
257
|
+
return await this.pxe.getBlockNumber();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Set time of the next execution on aztec.
|
|
262
|
+
* It also modifies time on eth for next execution and stores this time as the last rollup block on the rollup contract.
|
|
263
|
+
* @param to - The timestamp to set the next block to (must be greater than current time)
|
|
264
|
+
*/
|
|
265
|
+
public async warp(to: number): Promise<void> {
|
|
266
|
+
const rollupContract = (await this.pxe.getNodeInfo()).l1ContractAddresses.rollupAddress;
|
|
267
|
+
await this.eth.setNextBlockTimestamp(to);
|
|
268
|
+
// also store this time on the rollup contract (slot 1 tracks `lastBlockTs`).
|
|
269
|
+
// This is because when the sequencer executes public functions, it uses the timestamp stored in the rollup contract.
|
|
270
|
+
await this.eth.store(rollupContract, 1n, BigInt(to));
|
|
271
|
+
// also store this on slot 2 of the rollup contract (`lastWarpedBlockTs`) which tracks the last time warp was used.
|
|
272
|
+
await this.eth.store(rollupContract, 2n, BigInt(to));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Loads the value stored at the given slot in the public storage of the given contract.
|
|
277
|
+
* @param who - The address of the contract
|
|
278
|
+
* @param slot - The storage slot to lookup
|
|
279
|
+
* @returns The value stored at the given slot
|
|
280
|
+
*/
|
|
281
|
+
public async loadPublic(who: AztecAddress, slot: Fr | bigint): Promise<Fr> {
|
|
282
|
+
const storageValue = await this.pxe.getPublicStorageAt(who, new Fr(slot));
|
|
283
|
+
return storageValue;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Loads the value stored at the given slot in the private storage of the given contract.
|
|
288
|
+
* @param contract - The address of the contract
|
|
289
|
+
* @param owner - The owner for whom the notes are encrypted
|
|
290
|
+
* @param slot - The storage slot to lookup
|
|
291
|
+
* @returns The notes stored at the given slot
|
|
292
|
+
*/
|
|
293
|
+
public async loadPrivate(owner: AztecAddress, contract: AztecAddress, slot: Fr | bigint): Promise<Note[]> {
|
|
294
|
+
const extendedNotes = await this.pxe.getNotes({ owner, contractAddress: contract, storageSlot: new Fr(slot) });
|
|
295
|
+
return extendedNotes.map(extendedNote => extendedNote.note);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { L1ContractAddresses } from '@aztec/ethereum';
|
|
2
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
3
|
+
|
|
4
|
+
import { createPXEClient } from '../rpc_clients/index.js';
|
|
5
|
+
|
|
6
|
+
export const getL1ContractAddresses = async (url: string): Promise<L1ContractAddresses> => {
|
|
7
|
+
const pxeClient = createPXEClient(url);
|
|
8
|
+
const response = await retryUntil(
|
|
9
|
+
async () => {
|
|
10
|
+
try {
|
|
11
|
+
return (await pxeClient.getNodeInfo()).l1ContractAddresses;
|
|
12
|
+
} catch (err) {
|
|
13
|
+
// do nothing
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
'isNodeReady',
|
|
17
|
+
120,
|
|
18
|
+
1,
|
|
19
|
+
);
|
|
20
|
+
return response;
|
|
21
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks whether a give contract is deployed on the network.
|
|
6
|
+
* @param pxe - The PXE to use to obtain the information.
|
|
7
|
+
* @param contractAddress - The address of the contract to check.
|
|
8
|
+
* @returns A flag indicating whether the contract is deployed.
|
|
9
|
+
*/
|
|
10
|
+
export async function isContractDeployed(pxe: PXE, contractAddress: AztecAddress): Promise<boolean> {
|
|
11
|
+
return !!(await pxe.getContractData(contractAddress)) || !!(await pxe.getContractInstance(contractAddress));
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js';
|
|
2
|
+
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Method for generating a public grumpkin key from a private key.
|
|
6
|
+
* @param privateKey - The private key.
|
|
7
|
+
* @returns The generated public key.
|
|
8
|
+
*/
|
|
9
|
+
export function generatePublicKey(privateKey: GrumpkinPrivateKey): PublicKey {
|
|
10
|
+
const grumpkin = new Grumpkin();
|
|
11
|
+
return grumpkin.mul(grumpkin.generator(), privateKey);
|
|
12
|
+
}
|
package/src/utils/pxe.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { DebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
4
|
+
|
|
5
|
+
export const waitForPXE = async (pxe: PXE, logger?: DebugLogger) => {
|
|
6
|
+
await retryUntil(async () => {
|
|
7
|
+
try {
|
|
8
|
+
logger?.('Attempting to contact PXE...');
|
|
9
|
+
await pxe.getNodeInfo();
|
|
10
|
+
return true;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
logger?.('Failed to contact PXE!');
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}, 'RPC Get Node Info');
|
|
16
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { AuthWitness, FunctionCall, PXE, TxExecutionRequest } from '@aztec/circuit-types';
|
|
2
|
+
import { Fr } from '@aztec/circuits.js';
|
|
3
|
+
import { ABIParameterVisibility, FunctionAbi, FunctionType } from '@aztec/foundation/abi';
|
|
4
|
+
|
|
5
|
+
import { AccountInterface, FeeOptions } from '../account/interface.js';
|
|
6
|
+
import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js';
|
|
7
|
+
import { BaseWallet } from './base_wallet.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A wallet implementation that forwards authentication requests to a provided account.
|
|
11
|
+
*/
|
|
12
|
+
export class AccountWallet extends BaseWallet {
|
|
13
|
+
constructor(pxe: PXE, protected account: AccountInterface) {
|
|
14
|
+
super(pxe);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
createTxExecutionRequest(execs: FunctionCall[], fee?: FeeOptions): Promise<TxExecutionRequest> {
|
|
18
|
+
return this.account.createTxExecutionRequest(execs, fee);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async createAuthWitness(message: Fr | Buffer): Promise<AuthWitness> {
|
|
22
|
+
message = Buffer.isBuffer(message) ? Fr.fromBuffer(message) : message;
|
|
23
|
+
const witness = await this.account.createAuthWitness(message);
|
|
24
|
+
await this.pxe.addAuthWitness(witness);
|
|
25
|
+
return witness;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns a function interaction to set a message hash as authorized in this account.
|
|
30
|
+
* Public calls can then consume this authorization.
|
|
31
|
+
* @param message - Message hash to authorize.
|
|
32
|
+
* @param authorized - True to authorize, false to revoke authorization.
|
|
33
|
+
* @returns - A function interaction.
|
|
34
|
+
*/
|
|
35
|
+
public setPublicAuth(message: Fr | Buffer, authorized: boolean): ContractFunctionInteraction {
|
|
36
|
+
if (authorized) {
|
|
37
|
+
return new ContractFunctionInteraction(this, this.getAddress(), this.getApprovePublicAuthwitAbi(), [message]);
|
|
38
|
+
} else {
|
|
39
|
+
return this.cancelAuthWit(message);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns a function interaction to cancel a message hash as authorized in this account.
|
|
45
|
+
* @param message - Message hash to authorize.
|
|
46
|
+
* @returns - A function interaction.
|
|
47
|
+
*/
|
|
48
|
+
public cancelAuthWit(message: Fr | Buffer): ContractFunctionInteraction {
|
|
49
|
+
const args = [message];
|
|
50
|
+
return new ContractFunctionInteraction(this, this.getAddress(), this.getCancelAuthwitAbi(), args);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Returns the complete address of the account that implements this wallet. */
|
|
54
|
+
public getCompleteAddress() {
|
|
55
|
+
return this.account.getCompleteAddress();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Returns the address of the account that implements this wallet. */
|
|
59
|
+
public getAddress() {
|
|
60
|
+
return this.getCompleteAddress().address;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private getApprovePublicAuthwitAbi(): FunctionAbi {
|
|
64
|
+
return {
|
|
65
|
+
name: 'approve_public_authwit',
|
|
66
|
+
functionType: FunctionType.OPEN,
|
|
67
|
+
isInternal: true,
|
|
68
|
+
parameters: [
|
|
69
|
+
{
|
|
70
|
+
name: 'message_hash',
|
|
71
|
+
type: { kind: 'field' },
|
|
72
|
+
visibility: 'private' as ABIParameterVisibility,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
returnTypes: [],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private getCancelAuthwitAbi(): FunctionAbi {
|
|
80
|
+
return {
|
|
81
|
+
name: 'cancel_authwit',
|
|
82
|
+
functionType: FunctionType.SECRET,
|
|
83
|
+
isInternal: true,
|
|
84
|
+
parameters: [
|
|
85
|
+
{
|
|
86
|
+
name: 'message_hash',
|
|
87
|
+
type: { kind: 'field' },
|
|
88
|
+
visibility: 'private' as ABIParameterVisibility,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
returnTypes: [],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { GrumpkinPrivateKey } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
import { Salt } from '../account/index.js';
|
|
5
|
+
import { AccountInterface } from '../account/interface.js';
|
|
6
|
+
import { AccountWallet } from './account_wallet.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extends {@link AccountWallet} with the encryption private key. Not required for
|
|
10
|
+
* implementing the wallet interface but useful for testing purposes or exporting
|
|
11
|
+
* an account to another pxe.
|
|
12
|
+
*/
|
|
13
|
+
export class AccountWalletWithPrivateKey extends AccountWallet {
|
|
14
|
+
constructor(
|
|
15
|
+
pxe: PXE,
|
|
16
|
+
account: AccountInterface,
|
|
17
|
+
private encryptionPrivateKey: GrumpkinPrivateKey,
|
|
18
|
+
/** Deployment salt for this account contract. */
|
|
19
|
+
public readonly salt: Salt,
|
|
20
|
+
) {
|
|
21
|
+
super(pxe, account);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Returns the encryption private key associated with this account. */
|
|
25
|
+
public getEncryptionPrivateKey() {
|
|
26
|
+
return this.encryptionPrivateKey;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthWitness,
|
|
3
|
+
ContractData,
|
|
4
|
+
DeployedContract,
|
|
5
|
+
ExtendedContractData,
|
|
6
|
+
ExtendedNote,
|
|
7
|
+
FunctionCall,
|
|
8
|
+
GetUnencryptedLogsResponse,
|
|
9
|
+
L2Block,
|
|
10
|
+
LogFilter,
|
|
11
|
+
NoteFilter,
|
|
12
|
+
PXE,
|
|
13
|
+
SyncStatus,
|
|
14
|
+
Tx,
|
|
15
|
+
TxEffect,
|
|
16
|
+
TxExecutionRequest,
|
|
17
|
+
TxHash,
|
|
18
|
+
TxReceipt,
|
|
19
|
+
} from '@aztec/circuit-types';
|
|
20
|
+
import { AztecAddress, CompleteAddress, Fr, GrumpkinPrivateKey, PartialAddress } from '@aztec/circuits.js';
|
|
21
|
+
import { ContractClassWithId, ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
22
|
+
import { NodeInfo } from '@aztec/types/interfaces';
|
|
23
|
+
|
|
24
|
+
import { FeeOptions } from '../account/interface.js';
|
|
25
|
+
import { Wallet } from '../account/wallet.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A base class for Wallet implementations
|
|
29
|
+
*/
|
|
30
|
+
export abstract class BaseWallet implements Wallet {
|
|
31
|
+
constructor(protected readonly pxe: PXE) {}
|
|
32
|
+
|
|
33
|
+
abstract getCompleteAddress(): CompleteAddress;
|
|
34
|
+
|
|
35
|
+
abstract createTxExecutionRequest(execs: FunctionCall[], fee?: FeeOptions): Promise<TxExecutionRequest>;
|
|
36
|
+
|
|
37
|
+
abstract createAuthWitness(message: Fr): Promise<AuthWitness>;
|
|
38
|
+
|
|
39
|
+
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
40
|
+
return this.pxe.getContractInstance(address);
|
|
41
|
+
}
|
|
42
|
+
getContractClass(id: Fr): Promise<ContractClassWithId | undefined> {
|
|
43
|
+
return this.pxe.getContractClass(id);
|
|
44
|
+
}
|
|
45
|
+
addCapsule(capsule: Fr[]): Promise<void> {
|
|
46
|
+
return this.pxe.addCapsule(capsule);
|
|
47
|
+
}
|
|
48
|
+
registerAccount(privKey: GrumpkinPrivateKey, partialAddress: PartialAddress): Promise<CompleteAddress> {
|
|
49
|
+
return this.pxe.registerAccount(privKey, partialAddress);
|
|
50
|
+
}
|
|
51
|
+
registerRecipient(account: CompleteAddress): Promise<void> {
|
|
52
|
+
return this.pxe.registerRecipient(account);
|
|
53
|
+
}
|
|
54
|
+
getRegisteredAccounts(): Promise<CompleteAddress[]> {
|
|
55
|
+
return this.pxe.getRegisteredAccounts();
|
|
56
|
+
}
|
|
57
|
+
getRegisteredAccount(address: AztecAddress): Promise<CompleteAddress | undefined> {
|
|
58
|
+
return this.pxe.getRegisteredAccount(address);
|
|
59
|
+
}
|
|
60
|
+
getRecipients(): Promise<CompleteAddress[]> {
|
|
61
|
+
return this.pxe.getRecipients();
|
|
62
|
+
}
|
|
63
|
+
getRecipient(address: AztecAddress): Promise<CompleteAddress | undefined> {
|
|
64
|
+
return this.pxe.getRecipient(address);
|
|
65
|
+
}
|
|
66
|
+
addContracts(contracts: DeployedContract[]): Promise<void> {
|
|
67
|
+
return this.pxe.addContracts(contracts);
|
|
68
|
+
}
|
|
69
|
+
getContracts(): Promise<AztecAddress[]> {
|
|
70
|
+
return this.pxe.getContracts();
|
|
71
|
+
}
|
|
72
|
+
simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx> {
|
|
73
|
+
return this.pxe.simulateTx(txRequest, simulatePublic);
|
|
74
|
+
}
|
|
75
|
+
sendTx(tx: Tx): Promise<TxHash> {
|
|
76
|
+
return this.pxe.sendTx(tx);
|
|
77
|
+
}
|
|
78
|
+
getTxEffect(txHash: TxHash): Promise<TxEffect | undefined> {
|
|
79
|
+
return this.pxe.getTxEffect(txHash);
|
|
80
|
+
}
|
|
81
|
+
getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
82
|
+
return this.pxe.getTxReceipt(txHash);
|
|
83
|
+
}
|
|
84
|
+
getNotes(filter: NoteFilter): Promise<ExtendedNote[]> {
|
|
85
|
+
return this.pxe.getNotes(filter);
|
|
86
|
+
}
|
|
87
|
+
getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise<any> {
|
|
88
|
+
return this.pxe.getPublicStorageAt(contract, storageSlot);
|
|
89
|
+
}
|
|
90
|
+
addNote(note: ExtendedNote): Promise<void> {
|
|
91
|
+
return this.pxe.addNote(note);
|
|
92
|
+
}
|
|
93
|
+
getBlock(number: number): Promise<L2Block | undefined> {
|
|
94
|
+
return this.pxe.getBlock(number);
|
|
95
|
+
}
|
|
96
|
+
viewTx(functionName: string, args: any[], to: AztecAddress, from?: AztecAddress | undefined): Promise<any> {
|
|
97
|
+
return this.pxe.viewTx(functionName, args, to, from);
|
|
98
|
+
}
|
|
99
|
+
getExtendedContractData(contractAddress: AztecAddress): Promise<ExtendedContractData | undefined> {
|
|
100
|
+
return this.pxe.getExtendedContractData(contractAddress);
|
|
101
|
+
}
|
|
102
|
+
getContractData(contractAddress: AztecAddress): Promise<ContractData | undefined> {
|
|
103
|
+
return this.pxe.getContractData(contractAddress);
|
|
104
|
+
}
|
|
105
|
+
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
|
|
106
|
+
return this.pxe.getUnencryptedLogs(filter);
|
|
107
|
+
}
|
|
108
|
+
getBlockNumber(): Promise<number> {
|
|
109
|
+
return this.pxe.getBlockNumber();
|
|
110
|
+
}
|
|
111
|
+
getNodeInfo(): Promise<NodeInfo> {
|
|
112
|
+
return this.pxe.getNodeInfo();
|
|
113
|
+
}
|
|
114
|
+
isGlobalStateSynchronized() {
|
|
115
|
+
return this.pxe.isGlobalStateSynchronized();
|
|
116
|
+
}
|
|
117
|
+
isAccountStateSynchronized(account: AztecAddress) {
|
|
118
|
+
return this.pxe.isAccountStateSynchronized(account);
|
|
119
|
+
}
|
|
120
|
+
getSyncStatus(): Promise<SyncStatus> {
|
|
121
|
+
return this.pxe.getSyncStatus();
|
|
122
|
+
}
|
|
123
|
+
addAuthWitness(authWitness: AuthWitness) {
|
|
124
|
+
return this.pxe.addAuthWitness(authWitness);
|
|
125
|
+
}
|
|
126
|
+
isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
|
|
127
|
+
return this.pxe.isContractClassPubliclyRegistered(id);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { CompleteAddress } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a random address and registers it as a recipient on the pxe server. Useful for testing.
|
|
6
|
+
* @param pxe - PXE.
|
|
7
|
+
* @returns Complete address of the registered recipient.
|
|
8
|
+
*/
|
|
9
|
+
export async function createRecipient(pxe: PXE): Promise<CompleteAddress> {
|
|
10
|
+
const completeAddress = CompleteAddress.random();
|
|
11
|
+
await pxe.registerRecipient(completeAddress);
|
|
12
|
+
return completeAddress;
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PXE } from '@aztec/circuit-types';
|
|
2
|
+
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
3
|
+
|
|
4
|
+
import { AccountContract } from '../account/contract.js';
|
|
5
|
+
import { AccountWallet } from './account_wallet.js';
|
|
6
|
+
|
|
7
|
+
export * from '../account/wallet.js';
|
|
8
|
+
export * from './account_wallet.js';
|
|
9
|
+
export * from './account_wallet_with_private_key.js';
|
|
10
|
+
export * from './signerless_wallet.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Gets a wallet for an already registered account.
|
|
14
|
+
* @param pxe - PXE Service instance.
|
|
15
|
+
* @param address - Address for the account.
|
|
16
|
+
* @param accountContract - Account contract implementation.
|
|
17
|
+
* @returns A wallet for this account that can be used to interact with a contract instance.
|
|
18
|
+
*/
|
|
19
|
+
export async function getWallet(
|
|
20
|
+
pxe: PXE,
|
|
21
|
+
address: AztecAddress,
|
|
22
|
+
accountContract: AccountContract,
|
|
23
|
+
): Promise<AccountWallet> {
|
|
24
|
+
const completeAddress = await pxe.getRegisteredAccount(address);
|
|
25
|
+
if (!completeAddress) {
|
|
26
|
+
throw new Error(`Account ${address} not found`);
|
|
27
|
+
}
|
|
28
|
+
const nodeInfo = await pxe.getNodeInfo();
|
|
29
|
+
const entrypoint = accountContract.getInterface(completeAddress, nodeInfo);
|
|
30
|
+
return new AccountWallet(pxe, entrypoint);
|
|
31
|
+
}
|