@aztec-labs/aztec.js 6.0.0-nightly.20260829
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/README.md +44 -0
- package/dest/account/account.d.ts +44 -0
- package/dest/account/account.d.ts.map +1 -0
- package/dest/account/account.js +31 -0
- package/dest/account/account_contract.d.ts +49 -0
- package/dest/account/account_contract.d.ts.map +1 -0
- package/dest/account/account_contract.js +20 -0
- package/dest/account/index.d.ts +11 -0
- package/dest/account/index.d.ts.map +1 -0
- package/dest/account/index.js +6 -0
- package/dest/api/abi.d.ts +4 -0
- package/dest/api/abi.d.ts.map +1 -0
- package/dest/api/abi.js +1 -0
- package/dest/api/account.d.ts +5 -0
- package/dest/api/account.d.ts.map +1 -0
- package/dest/api/account.js +3 -0
- package/dest/api/addresses.d.ts +4 -0
- package/dest/api/addresses.d.ts.map +1 -0
- package/dest/api/addresses.js +3 -0
- package/dest/api/authorization.d.ts +5 -0
- package/dest/api/authorization.d.ts.map +1 -0
- package/dest/api/authorization.js +4 -0
- package/dest/api/block.d.ts +3 -0
- package/dest/api/block.d.ts.map +1 -0
- package/dest/api/block.js +2 -0
- package/dest/api/contract.d.ts +48 -0
- package/dest/api/contract.d.ts.map +1 -0
- package/dest/api/contract.js +46 -0
- package/dest/api/crypto.d.ts +2 -0
- package/dest/api/crypto.d.ts.map +1 -0
- package/dest/api/crypto.js +1 -0
- package/dest/api/deployment.d.ts +4 -0
- package/dest/api/deployment.d.ts.map +1 -0
- package/dest/api/deployment.js +3 -0
- package/dest/api/eth_address.d.ts +2 -0
- package/dest/api/eth_address.d.ts.map +1 -0
- package/dest/api/eth_address.js +1 -0
- package/dest/api/ethereum.d.ts +2 -0
- package/dest/api/ethereum.d.ts.map +1 -0
- package/dest/api/ethereum.js +1 -0
- package/dest/api/event_cursor.d.ts +44 -0
- package/dest/api/event_cursor.d.ts.map +1 -0
- package/dest/api/event_cursor.js +42 -0
- package/dest/api/events.d.ts +36 -0
- package/dest/api/events.d.ts.map +1 -0
- package/dest/api/events.js +59 -0
- package/dest/api/fee.d.ts +6 -0
- package/dest/api/fee.d.ts.map +1 -0
- package/dest/api/fee.js +4 -0
- package/dest/api/fee_testing.d.ts +2 -0
- package/dest/api/fee_testing.d.ts.map +1 -0
- package/dest/api/fee_testing.js +1 -0
- package/dest/api/fields.d.ts +4 -0
- package/dest/api/fields.d.ts.map +1 -0
- package/dest/api/fields.js +3 -0
- package/dest/api/keys.d.ts +4 -0
- package/dest/api/keys.d.ts.map +1 -0
- package/dest/api/keys.js +3 -0
- package/dest/api/log.d.ts +3 -0
- package/dest/api/log.d.ts.map +1 -0
- package/dest/api/log.js +2 -0
- package/dest/api/messaging.d.ts +3 -0
- package/dest/api/messaging.d.ts.map +1 -0
- package/dest/api/messaging.js +2 -0
- package/dest/api/node.d.ts +25 -0
- package/dest/api/node.d.ts.map +1 -0
- package/dest/api/node.js +22 -0
- package/dest/api/note.d.ts +2 -0
- package/dest/api/note.d.ts.map +1 -0
- package/dest/api/note.js +1 -0
- package/dest/api/protocol.d.ts +6 -0
- package/dest/api/protocol.d.ts.map +1 -0
- package/dest/api/protocol.js +5 -0
- package/dest/api/trees.d.ts +3 -0
- package/dest/api/trees.d.ts.map +1 -0
- package/dest/api/trees.js +2 -0
- package/dest/api/tx.d.ts +3 -0
- package/dest/api/tx.d.ts.map +1 -0
- package/dest/api/tx.js +1 -0
- package/dest/api/utils.d.ts +13 -0
- package/dest/api/utils.d.ts.map +1 -0
- package/dest/api/utils.js +12 -0
- package/dest/api/wallet.d.ts +8 -0
- package/dest/api/wallet.d.ts.map +1 -0
- package/dest/api/wallet.js +7 -0
- package/dest/authorization/call_authorization_request.d.ts +46 -0
- package/dest/authorization/call_authorization_request.d.ts.map +1 -0
- package/dest/authorization/call_authorization_request.js +72 -0
- package/dest/contract/base_contract_interaction.d.ts +32 -0
- package/dest/contract/base_contract_interaction.d.ts.map +1 -0
- package/dest/contract/base_contract_interaction.js +24 -0
- package/dest/contract/batch_call.d.ts +27 -0
- package/dest/contract/batch_call.d.ts.map +1 -0
- package/dest/contract/batch_call.js +152 -0
- package/dest/contract/checker.d.ts +11 -0
- package/dest/contract/checker.d.ts.map +1 -0
- package/dest/contract/checker.js +107 -0
- package/dest/contract/contract.d.ts +33 -0
- package/dest/contract/contract.d.ts.map +1 -0
- package/dest/contract/contract.js +36 -0
- package/dest/contract/contract_base.d.ts +51 -0
- package/dest/contract/contract_base.d.ts.map +1 -0
- package/dest/contract/contract_base.js +38 -0
- package/dest/contract/contract_function_interaction.d.ts +67 -0
- package/dest/contract/contract_function_interaction.d.ts.map +1 -0
- package/dest/contract/contract_function_interaction.js +218 -0
- package/dest/contract/deploy_method.d.ts +433 -0
- package/dest/contract/deploy_method.d.ts.map +1 -0
- package/dest/contract/deploy_method.js +471 -0
- package/dest/contract/fastforward_contract_update.d.ts +25 -0
- package/dest/contract/fastforward_contract_update.d.ts.map +1 -0
- package/dest/contract/fastforward_contract_update.js +57 -0
- package/dest/contract/interaction_options.d.ts +213 -0
- package/dest/contract/interaction_options.d.ts.map +1 -0
- package/dest/contract/interaction_options.js +87 -0
- package/dest/contract/protocol_contracts/contract-class-registry.d.ts +18 -0
- package/dest/contract/protocol_contracts/contract-class-registry.d.ts.map +1 -0
- package/dest/contract/protocol_contracts/contract-class-registry.js +137 -0
- package/dest/contract/protocol_contracts/contract-instance-registry.d.ts +25 -0
- package/dest/contract/protocol_contracts/contract-instance-registry.d.ts.map +1 -0
- package/dest/contract/protocol_contracts/contract-instance-registry.js +366 -0
- package/dest/contract/protocol_contracts/fee-juice.d.ts +24 -0
- package/dest/contract/protocol_contracts/fee-juice.d.ts.map +1 -0
- package/dest/contract/protocol_contracts/fee-juice.js +383 -0
- package/dest/contract/wait_for_proven.d.ts +18 -0
- package/dest/contract/wait_for_proven.d.ts.map +1 -0
- package/dest/contract/wait_for_proven.js +17 -0
- package/dest/contract/wait_opts.d.ts +21 -0
- package/dest/contract/wait_opts.d.ts.map +1 -0
- package/dest/contract/wait_opts.js +5 -0
- package/dest/deployment/contract_deployer.d.ts +28 -0
- package/dest/deployment/contract_deployer.d.ts.map +1 -0
- package/dest/deployment/contract_deployer.js +35 -0
- package/dest/deployment/publish_class.d.ts +6 -0
- package/dest/deployment/publish_class.d.ts.map +1 -0
- package/dest/deployment/publish_class.js +17 -0
- package/dest/deployment/publish_instance.d.ts +10 -0
- package/dest/deployment/publish_instance.d.ts.map +1 -0
- package/dest/deployment/publish_instance.js +11 -0
- package/dest/ethereum/portal_manager.d.ts +146 -0
- package/dest/ethereum/portal_manager.d.ts.map +1 -0
- package/dest/ethereum/portal_manager.js +415 -0
- package/dest/fee/fee_juice_payment_method_with_claim.d.ts +23 -0
- package/dest/fee/fee_juice_payment_method_with_claim.d.ts.map +1 -0
- package/dest/fee/fee_juice_payment_method_with_claim.js +46 -0
- package/dest/fee/fee_payment_method.d.ts +26 -0
- package/dest/fee/fee_payment_method.d.ts.map +1 -0
- package/dest/fee/fee_payment_method.js +3 -0
- package/dest/fee/private_fee_payment_method.d.ts +69 -0
- package/dest/fee/private_fee_payment_method.d.ts.map +1 -0
- package/dest/fee/private_fee_payment_method.js +122 -0
- package/dest/fee/public_fee_payment_method.d.ts +59 -0
- package/dest/fee/public_fee_payment_method.d.ts.map +1 -0
- package/dest/fee/public_fee_payment_method.js +116 -0
- package/dest/fee/sponsored_fee_payment.d.ts +17 -0
- package/dest/fee/sponsored_fee_payment.d.ts.map +1 -0
- package/dest/fee/sponsored_fee_payment.js +33 -0
- package/dest/scripts/generate_protocol_contract_types.d.ts +2 -0
- package/dest/scripts/generate_protocol_contract_types.d.ts.map +1 -0
- package/dest/scripts/generate_protocol_contract_types.js +128 -0
- package/dest/test/fixtures.d.ts +13 -0
- package/dest/test/fixtures.d.ts.map +1 -0
- package/dest/test/fixtures.js +185 -0
- package/dest/utils/abi_types.d.ts +32 -0
- package/dest/utils/abi_types.d.ts.map +1 -0
- package/dest/utils/abi_types.js +1 -0
- package/dest/utils/authwit.d.ts +119 -0
- package/dest/utils/authwit.d.ts.map +1 -0
- package/dest/utils/authwit.js +266 -0
- package/dest/utils/cross_chain.d.ts +28 -0
- package/dest/utils/cross_chain.d.ts.map +1 -0
- package/dest/utils/cross_chain.js +26 -0
- package/dest/utils/fee_juice.d.ts +8 -0
- package/dest/utils/fee_juice.d.ts.map +1 -0
- package/dest/utils/fee_juice.js +10 -0
- package/dest/utils/field_compressed_string.d.ts +17 -0
- package/dest/utils/field_compressed_string.d.ts.map +1 -0
- package/dest/utils/field_compressed_string.js +15 -0
- package/dest/utils/node.d.ts +24 -0
- package/dest/utils/node.d.ts.map +1 -0
- package/dest/utils/node.js +80 -0
- package/dest/utils/pub_key.d.ts +9 -0
- package/dest/utils/pub_key.d.ts.map +1 -0
- package/dest/utils/pub_key.js +8 -0
- package/dest/wallet/account_entrypoint_meta_payment_method.d.ts +33 -0
- package/dest/wallet/account_entrypoint_meta_payment_method.d.ts.map +1 -0
- package/dest/wallet/account_entrypoint_meta_payment_method.js +63 -0
- package/dest/wallet/account_manager.d.ts +73 -0
- package/dest/wallet/account_manager.d.ts.map +1 -0
- package/dest/wallet/account_manager.js +102 -0
- package/dest/wallet/capabilities.d.ts +456 -0
- package/dest/wallet/capabilities.d.ts.map +1 -0
- package/dest/wallet/capabilities.js +3 -0
- package/dest/wallet/deploy_account_method.d.ts +97 -0
- package/dest/wallet/deploy_account_method.d.ts.map +1 -0
- package/dest/wallet/deploy_account_method.js +127 -0
- package/dest/wallet/index.d.ts +5 -0
- package/dest/wallet/index.d.ts.map +1 -0
- package/dest/wallet/index.js +4 -0
- package/dest/wallet/tx_simulation_result_with_app_offset.d.ts +40 -0
- package/dest/wallet/tx_simulation_result_with_app_offset.d.ts.map +1 -0
- package/dest/wallet/tx_simulation_result_with_app_offset.js +65 -0
- package/dest/wallet/wallet.d.ts +1451 -0
- package/dest/wallet/wallet.d.ts.map +1 -0
- package/dest/wallet/wallet.js +430 -0
- package/package.json +138 -0
- package/src/account/account.ts +72 -0
- package/src/account/account_contract.ts +80 -0
- package/src/account/index.ts +12 -0
- package/src/api/README.md +7 -0
- package/src/api/abi.ts +42 -0
- package/src/api/account.ts +12 -0
- package/src/api/addresses.ts +3 -0
- package/src/api/authorization.ts +15 -0
- package/src/api/block.ts +2 -0
- package/src/api/contract.ts +86 -0
- package/src/api/crypto.ts +1 -0
- package/src/api/deployment.ts +3 -0
- package/src/api/eth_address.ts +1 -0
- package/src/api/ethereum.ts +10 -0
- package/src/api/event_cursor.ts +60 -0
- package/src/api/events.ts +79 -0
- package/src/api/fee.ts +5 -0
- package/src/api/fee_testing.ts +1 -0
- package/src/api/fields.ts +3 -0
- package/src/api/keys.ts +8 -0
- package/src/api/log.ts +2 -0
- package/src/api/messaging.ts +2 -0
- package/src/api/node.ts +30 -0
- package/src/api/note.ts +1 -0
- package/src/api/protocol.ts +6 -0
- package/src/api/trees.ts +2 -0
- package/src/api/tx.ts +20 -0
- package/src/api/utils.ts +14 -0
- package/src/api/wallet.ts +83 -0
- package/src/authorization/call_authorization_request.ts +93 -0
- package/src/contract/base_contract_interaction.ts +62 -0
- package/src/contract/batch_call.ts +188 -0
- package/src/contract/checker.ts +122 -0
- package/src/contract/contract.ts +52 -0
- package/src/contract/contract_base.ts +73 -0
- package/src/contract/contract_function_interaction.ts +297 -0
- package/src/contract/deploy_method.ts +877 -0
- package/src/contract/fastforward_contract_update.ts +71 -0
- package/src/contract/interaction_options.ts +301 -0
- package/src/contract/protocol_contracts/contract-class-registry.ts +104 -0
- package/src/contract/protocol_contracts/contract-instance-registry.ts +241 -0
- package/src/contract/protocol_contracts/fee-juice.ts +257 -0
- package/src/contract/wait_for_proven.ts +43 -0
- package/src/contract/wait_opts.ts +26 -0
- package/src/deployment/contract_deployer.ts +40 -0
- package/src/deployment/publish_class.ts +34 -0
- package/src/deployment/publish_instance.ts +24 -0
- package/src/ethereum/portal_manager.ts +539 -0
- package/src/fee/fee_juice_payment_method_with_claim.ts +63 -0
- package/src/fee/fee_payment_method.ts +26 -0
- package/src/fee/private_fee_payment_method.ts +145 -0
- package/src/fee/public_fee_payment_method.ts +145 -0
- package/src/fee/sponsored_fee_payment.ts +45 -0
- package/src/scripts/generate_protocol_contract_types.ts +160 -0
- package/src/test/fixtures.ts +126 -0
- package/src/utils/abi_types.ts +32 -0
- package/src/utils/authwit.ts +327 -0
- package/src/utils/cross_chain.ts +55 -0
- package/src/utils/fee_juice.ts +14 -0
- package/src/utils/field_compressed_string.ts +27 -0
- package/src/utils/node.ts +110 -0
- package/src/utils/pub_key.ts +12 -0
- package/src/wallet/account_entrypoint_meta_payment_method.ts +76 -0
- package/src/wallet/account_manager.ts +164 -0
- package/src/wallet/capabilities.ts +505 -0
- package/src/wallet/deploy_account_method.ts +234 -0
- package/src/wallet/index.ts +4 -0
- package/src/wallet/tx_simulation_result_with_app_offset.ts +100 -0
- package/src/wallet/wallet.ts +668 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
2
|
+
import { getInitializer } from '@aztec-labs/stdlib/abi';
|
|
3
|
+
import { AztecAddress } from '@aztec-labs/stdlib/aztec-address';
|
|
4
|
+
import { computePartialAddress, getContractClassFromArtifact, getContractInstanceFromInstantiationParams } from '@aztec-labs/stdlib/contract';
|
|
5
|
+
import { PublicKeys } from '@aztec-labs/stdlib/keys';
|
|
6
|
+
import { ExecutionPayload, mergeExecutionPayloads } from '@aztec-labs/stdlib/tx';
|
|
7
|
+
import { publishContractClass } from '../deployment/publish_class.js';
|
|
8
|
+
import { publishInstance } from '../deployment/publish_instance.js';
|
|
9
|
+
import { BaseContractInteraction } from './base_contract_interaction.js';
|
|
10
|
+
import { ContractFunctionInteraction } from './contract_function_interaction.js';
|
|
11
|
+
import { NO_FROM, NO_WAIT, extractOffchainOutput, toProfileOptions, toSendOptions, toSimulateOptions } from './interaction_options.js';
|
|
12
|
+
/**
|
|
13
|
+
* Umbrella type for a contract deployment interaction.
|
|
14
|
+
*
|
|
15
|
+
* `DeployMethod` is abstract: callers always interact with one of three concrete flavors —
|
|
16
|
+
* {@link BoundDeployMethod}, {@link UniversalDeployMethod}, or {@link PendingDeployMethod} —
|
|
17
|
+
* picked by {@link DeployMethod.create} based on the supplied {@link DeployInstantiationOptions}.
|
|
18
|
+
* The flavors only differ in their initial deployer-lock state; the full API
|
|
19
|
+
* (`request` / `send` / `simulate` / `profile` / `getInstance` / `getAddress` /
|
|
20
|
+
* `getPartialAddress` / `register` / `with`) lives on this base, so consumers can type
|
|
21
|
+
* variables as `DeployMethod<T>` and treat all three uniformly.
|
|
22
|
+
*
|
|
23
|
+
* The deployer (and therefore the deployed address) is locked once and never changes. Locking
|
|
24
|
+
* happens either at construction (via `deployer` or `universalDeploy: true` in the instantiation
|
|
25
|
+
* options) or lazily on the first `send` / `simulate` / `profile` call, which lock from
|
|
26
|
+
* `options.from`. Once locked:
|
|
27
|
+
*
|
|
28
|
+
* - The address is stable for the lifetime of this object.
|
|
29
|
+
* - Subsequent `send` / `simulate` / `profile` calls with a `from` that would imply a different
|
|
30
|
+
* deployer throw, to prevent silently deploying at a different address than `getAddress()`
|
|
31
|
+
* reported.
|
|
32
|
+
* - A locked universal deployer (`AztecAddress.ZERO`) is compatible with any `from`, since the
|
|
33
|
+
* address does not depend on the sender.
|
|
34
|
+
*
|
|
35
|
+
* Note that for some contracts, a tx is not required as part of its "creation":
|
|
36
|
+
* If there are no public functions, and if there are no initialization functions,
|
|
37
|
+
* then technically the contract has already been "created", and all of the contract's
|
|
38
|
+
* functions (private and utility) can be interacted-with immediately, without any
|
|
39
|
+
* "deployment tx".
|
|
40
|
+
*/ export class DeployMethod extends BaseContractInteraction {
|
|
41
|
+
/** Salt used in the address preimage. */ salt;
|
|
42
|
+
/** Public keys mixed into the address preimage. */ publicKeys;
|
|
43
|
+
/** Immutables hash folded into the salted initialization hash. */ immutablesHash;
|
|
44
|
+
/** Cached instance promise; resolved once the deployer is known. */ #instancePromise;
|
|
45
|
+
/** Resolved value of `#instancePromise`, populated synchronously once the promise settles. */ #resolvedInstance;
|
|
46
|
+
/** Constructor function to call. */ constructorArtifact;
|
|
47
|
+
/** Build artifact of the contract being deployed. */ artifact;
|
|
48
|
+
/** Factory invoked after deployment to produce the typed contract handle. */ postDeployCtor;
|
|
49
|
+
/** Encoded constructor arguments for the contract. */ args;
|
|
50
|
+
/** Extra hashed args propagated through `with(...)` and into the deploy payload. */ extraHashedArgs;
|
|
51
|
+
constructor(wallet, contract, salt, publicKeys, immutablesHash, payload = {}){
|
|
52
|
+
super(wallet, payload.authWitnesses ?? [], payload.capsules ?? []);
|
|
53
|
+
this.artifact = contract.artifact;
|
|
54
|
+
this.postDeployCtor = contract.postDeployCtor;
|
|
55
|
+
this.args = contract.args ?? [];
|
|
56
|
+
this.constructorArtifact = getInitializer(contract.artifact, contract.constructorNameOrArtifact);
|
|
57
|
+
this.salt = salt ?? Fr.random();
|
|
58
|
+
this.publicKeys = publicKeys ?? PublicKeys.default();
|
|
59
|
+
this.immutablesHash = immutablesHash ?? Fr.ZERO;
|
|
60
|
+
this.extraHashedArgs = payload.extraHashedArgs ?? [];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Constructs the right concrete `DeployMethod` flavor for the supplied instantiation options:
|
|
64
|
+
* - `{ deployer: <addr> }` → {@link BoundDeployMethod}
|
|
65
|
+
* - `{ universalDeploy: true }` → {@link UniversalDeployMethod}
|
|
66
|
+
* - neither set → {@link PendingDeployMethod}
|
|
67
|
+
*
|
|
68
|
+
* Mixing `deployer` and `universalDeploy` throws. Returns the umbrella `DeployMethod<T>` type so
|
|
69
|
+
* callers can use the result generically without narrowing.
|
|
70
|
+
*
|
|
71
|
+
* @param wallet - Wallet used to send / simulate the deploy tx.
|
|
72
|
+
* @param contract - The contract being deployed (artifact, factory, args, initializer).
|
|
73
|
+
* @param instantiation - Address-affecting parameters (salt, deployer / universalDeploy, publicKeys). Defaults to pending.
|
|
74
|
+
* @param payload - Auth witnesses, capsules, and extra hashed args propagated to the deploy. Defaults to empty.
|
|
75
|
+
*/ static create(wallet, contract, instantiation = {}, payload = {}) {
|
|
76
|
+
if (instantiation.deployer !== undefined && instantiation.universalDeploy) {
|
|
77
|
+
throw new Error('DeployInstantiationOptions: `deployer` and `universalDeploy` are mutually exclusive.');
|
|
78
|
+
}
|
|
79
|
+
const { salt, publicKeys, immutablesHash, deployer, universalDeploy } = instantiation;
|
|
80
|
+
if (universalDeploy) {
|
|
81
|
+
return new UniversalDeployMethod(wallet, contract, {
|
|
82
|
+
salt,
|
|
83
|
+
publicKeys,
|
|
84
|
+
immutablesHash,
|
|
85
|
+
universalDeploy: true
|
|
86
|
+
}, payload);
|
|
87
|
+
}
|
|
88
|
+
if (deployer !== undefined) {
|
|
89
|
+
return new BoundDeployMethod(wallet, contract, {
|
|
90
|
+
salt,
|
|
91
|
+
publicKeys,
|
|
92
|
+
immutablesHash,
|
|
93
|
+
deployer
|
|
94
|
+
}, payload);
|
|
95
|
+
}
|
|
96
|
+
return new PendingDeployMethod(wallet, contract, {
|
|
97
|
+
salt,
|
|
98
|
+
publicKeys,
|
|
99
|
+
immutablesHash
|
|
100
|
+
}, payload);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Returns the execution payload that allows this operation to happen on chain. Requires the
|
|
104
|
+
* deployer to be known — call `getDeployerAddress()` first; on a `PendingDeployMethod` this
|
|
105
|
+
* throws unless a prior `send` / `simulate` / `profile` has already locked the deployer.
|
|
106
|
+
*
|
|
107
|
+
* @param options - Configuration options.
|
|
108
|
+
* @returns The execution payload for this operation
|
|
109
|
+
*/ async request(options = {}) {
|
|
110
|
+
const publication = await this.getPublicationExecutionPayload(options);
|
|
111
|
+
if (!options?.skipRegistration) {
|
|
112
|
+
await this.wallet.registerContract(await this.getInstance(), this.artifact);
|
|
113
|
+
}
|
|
114
|
+
const { authWitnesses, capsules } = options;
|
|
115
|
+
// Propagates the included authwitnesses, capsules, and extraHashedArgs
|
|
116
|
+
// potentially baked into the interaction
|
|
117
|
+
const initialExecutionPayload = new ExecutionPayload([], this.authWitnesses.concat(authWitnesses ?? []), this.capsules.concat(capsules ?? []), this.extraHashedArgs);
|
|
118
|
+
const initialization = await this.getInitializationExecutionPayload(options);
|
|
119
|
+
const feeExecutionPayload = options?.fee?.paymentMethod ? await options.fee.paymentMethod.getExecutionPayload() : undefined;
|
|
120
|
+
const finalExecutionPayload = feeExecutionPayload ? mergeExecutionPayloads([
|
|
121
|
+
initialExecutionPayload,
|
|
122
|
+
feeExecutionPayload,
|
|
123
|
+
publication,
|
|
124
|
+
initialization
|
|
125
|
+
]) : mergeExecutionPayloads([
|
|
126
|
+
initialExecutionPayload,
|
|
127
|
+
publication,
|
|
128
|
+
initialization
|
|
129
|
+
]);
|
|
130
|
+
if (!finalExecutionPayload.calls.length) {
|
|
131
|
+
throw new Error(`No transactions are needed to publish or initialize contract ${this.artifact.name}`);
|
|
132
|
+
}
|
|
133
|
+
return finalExecutionPayload;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Converts DeployOptions to SendOptions.
|
|
137
|
+
* @param options - Deploy options with wait parameter.
|
|
138
|
+
*/ convertDeployOptionsToSendOptions(options) {
|
|
139
|
+
return toSendOptions({
|
|
140
|
+
...options,
|
|
141
|
+
wait: options.wait
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Converts deploy simulation options into wallet-level simulate options.
|
|
146
|
+
* @param options - The deploy simulation options to convert.
|
|
147
|
+
*/ convertDeployOptionsToSimulateOptions(options) {
|
|
148
|
+
return toSimulateOptions(options);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Converts deploy profile options into wallet-level profile options.
|
|
152
|
+
* @param options - The deploy profile options to convert.
|
|
153
|
+
*/ convertDeployOptionsToProfileOptions(options) {
|
|
154
|
+
return toProfileOptions(options);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Adds this contract to the wallet and returns the Contract object.
|
|
158
|
+
*/ async register() {
|
|
159
|
+
const instance = await this.getInstance();
|
|
160
|
+
await this.wallet.registerContract(instance, this.artifact);
|
|
161
|
+
return this.postDeployCtor(instance, this.wallet);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Returns an execution payload for:
|
|
165
|
+
* - publication of the contract class and
|
|
166
|
+
* - publication of the contract instance to enable public execution
|
|
167
|
+
* depending on the provided options.
|
|
168
|
+
* @param options - Contract creation options.
|
|
169
|
+
* @returns An execution payload with potentially calls (and bytecode capsule) to the class registry and instance registry.
|
|
170
|
+
*/ async getPublicationExecutionPayload(options) {
|
|
171
|
+
const calls = [];
|
|
172
|
+
// Set contract instance object so it's available for populating the DeploySendTx object
|
|
173
|
+
const instance = await this.getInstance();
|
|
174
|
+
// Obtain contract class from artifact and check it matches the reported one by the instance.
|
|
175
|
+
// TODO(@spalladino): We're unnecessarily calculating the contract class multiple times here.
|
|
176
|
+
const contractClass = await getContractClassFromArtifact(this.artifact);
|
|
177
|
+
if (!instance.currentContractClassId.equals(contractClass.id)) {
|
|
178
|
+
throw new Error(`Contract class mismatch when deploying contract: got ${instance.currentContractClassId.toString()} from instance and ${contractClass.id.toString()} from artifact`);
|
|
179
|
+
}
|
|
180
|
+
// Publish the contract class if it hasn't been published already.
|
|
181
|
+
if (!options?.skipClassPublication) {
|
|
182
|
+
const classMetadata = await this.wallet.getContractClassMetadata(contractClass.id);
|
|
183
|
+
if (!classMetadata.isContractClassPubliclyRegistered) {
|
|
184
|
+
this.log.info(`Creating request for publishing contract class ${contractClass.id.toString()} as part of deployment for ${instance.address.toString()}`);
|
|
185
|
+
const registerContractClassInteraction = await publishContractClass(this.wallet, this.artifact);
|
|
186
|
+
calls.push(await registerContractClassInteraction.request());
|
|
187
|
+
} else {
|
|
188
|
+
this.log.debug(`Skipping contract class publication for ${contractClass.id.toString()} as it is already registered`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Publish the contract instance:
|
|
192
|
+
if (!options?.skipInstancePublication) {
|
|
193
|
+
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/15596):
|
|
194
|
+
// Read the artifact, and if there are no public functions, warn the caller that publication of the
|
|
195
|
+
// contract instance is not necessary (until such time as they wish to update the instance (i.e. change its class_id)).
|
|
196
|
+
const deploymentInteraction = publishInstance(this.wallet, instance);
|
|
197
|
+
calls.push(await deploymentInteraction.request());
|
|
198
|
+
}
|
|
199
|
+
return mergeExecutionPayloads(calls);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Returns the calls necessary to initialize the contract.
|
|
203
|
+
* @param options - Deployment options.
|
|
204
|
+
* @returns - An array of function calls.
|
|
205
|
+
*/ async getInitializationExecutionPayload(options) {
|
|
206
|
+
const executionsPayloads = [];
|
|
207
|
+
if (this.constructorArtifact && !options?.skipInitialization) {
|
|
208
|
+
const { address } = await this.getInstance();
|
|
209
|
+
const constructorCall = new ContractFunctionInteraction(this.wallet, address, this.constructorArtifact, this.args);
|
|
210
|
+
executionsPayloads.push(await constructorCall.request());
|
|
211
|
+
}
|
|
212
|
+
return mergeExecutionPayloads(executionsPayloads);
|
|
213
|
+
}
|
|
214
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
215
|
+
async send(options) {
|
|
216
|
+
this.lockDeployer(options.from);
|
|
217
|
+
const executionPayload = await this.request(options);
|
|
218
|
+
const sendOptions = this.convertDeployOptionsToSendOptions(options);
|
|
219
|
+
if (options.wait === NO_WAIT) {
|
|
220
|
+
const result = await this.wallet.sendTx(executionPayload, sendOptions);
|
|
221
|
+
this.log.debug(`Sent deployment tx ${result.txHash.hash} of ${this.artifact.name} contract`);
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
const { receipt, ...offchainOutput } = await this.wallet.sendTx(executionPayload, sendOptions);
|
|
225
|
+
this.log.debug(`Deployed ${this.artifact.name} contract in tx ${receipt.txHash}`);
|
|
226
|
+
// Attach contract instance
|
|
227
|
+
const instance = await this.getInstance();
|
|
228
|
+
const contract = this.postDeployCtor(instance, this.wallet);
|
|
229
|
+
return {
|
|
230
|
+
contract,
|
|
231
|
+
receipt,
|
|
232
|
+
instance,
|
|
233
|
+
...offchainOutput
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Builds the contract instance and returns it. The instance is computed once and cached for
|
|
238
|
+
* the lifetime of this DeployMethod; subsequent calls return the same instance.
|
|
239
|
+
*
|
|
240
|
+
* On a {@link PendingDeployMethod} this throws unless a prior `send` / `simulate` / `profile`
|
|
241
|
+
* call has already locked the deployer — otherwise the resolved address could silently differ
|
|
242
|
+
* from the eventually-deployed one.
|
|
243
|
+
*
|
|
244
|
+
* @returns An instance object.
|
|
245
|
+
*/ getInstance() {
|
|
246
|
+
const deployer = this.getDeployerAddress();
|
|
247
|
+
if (!this.#instancePromise) {
|
|
248
|
+
this.#instancePromise = getContractInstanceFromInstantiationParams(this.artifact, {
|
|
249
|
+
constructorArgs: this.args,
|
|
250
|
+
salt: this.salt,
|
|
251
|
+
publicKeys: this.publicKeys,
|
|
252
|
+
immutablesHash: this.immutablesHash,
|
|
253
|
+
constructorArtifact: this.constructorArtifact,
|
|
254
|
+
deployer
|
|
255
|
+
}).then((instance)=>{
|
|
256
|
+
this.#resolvedInstance = instance;
|
|
257
|
+
return instance;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return this.#instancePromise;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Simulate the deployment
|
|
264
|
+
*
|
|
265
|
+
* @param options - An optional object containing additional configuration for the simulation.
|
|
266
|
+
* @returns A simulation result object containing metadata of the execution, including gas
|
|
267
|
+
* estimations (if requested via options), execution statistics and emitted offchain effects
|
|
268
|
+
*/ async simulate(options) {
|
|
269
|
+
this.lockDeployer(options.from);
|
|
270
|
+
const executionPayload = await this.request(options);
|
|
271
|
+
const simulatedTx = await this.wallet.simulateTx(executionPayload, this.convertDeployOptionsToSimulateOptions(options));
|
|
272
|
+
return {
|
|
273
|
+
stats: simulatedTx.stats,
|
|
274
|
+
...extractOffchainOutput(simulatedTx.offchainEffects, simulatedTx.publicInputs.constants.anchorBlockHeader.globalVariables.timestamp),
|
|
275
|
+
result: undefined,
|
|
276
|
+
gasUsed: simulatedTx.gasUsed
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Simulate a deployment and profile the gate count for each function in the transaction.
|
|
281
|
+
* @param options - Same options as `send`, plus extra profiling options.
|
|
282
|
+
*
|
|
283
|
+
* @returns An object containing the function return value and profile result.
|
|
284
|
+
*/ async profile(options) {
|
|
285
|
+
this.lockDeployer(options.from);
|
|
286
|
+
const executionPayload = await this.request(options);
|
|
287
|
+
return await this.wallet.profileTx(executionPayload, this.convertDeployOptionsToProfileOptions(options));
|
|
288
|
+
}
|
|
289
|
+
/** Returns the deployed contract address. */ async getAddress() {
|
|
290
|
+
return (await this.getInstance()).address;
|
|
291
|
+
}
|
|
292
|
+
/** Returns the partial address for this deployment. */ async getPartialAddress() {
|
|
293
|
+
return computePartialAddress(await this.getInstance());
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Returns the cached resolved instance synchronously, or throws if no instance has been computed yet.
|
|
297
|
+
* Intended for subclasses that run inside a code path where `getInstance()` is guaranteed to have already
|
|
298
|
+
* been awaited (e.g. `request()` invoked it). Not part of the public API.
|
|
299
|
+
*/ getCachedInstanceOrThrow() {
|
|
300
|
+
if (!this.#resolvedInstance) {
|
|
301
|
+
throw new Error('Contract instance has not been computed yet. Call getInstance() first.');
|
|
302
|
+
}
|
|
303
|
+
return this.#resolvedInstance;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Augments this DeployMethod with additional metadata, such as authWitnesses and capsules. The
|
|
307
|
+
* deployer lock is preserved: a Pending that has not yet been locked stays Pending; a Pending
|
|
308
|
+
* that has already locked, along with Owned and Universal, returns the matching locked flavor
|
|
309
|
+
* so the cloned method deploys at the same address as `this`.
|
|
310
|
+
* @param options - An object containing the metadata to add to the interaction
|
|
311
|
+
* @returns A new DeployMethod with the added metadata, but calling the same original function in the same manner
|
|
312
|
+
*/ with({ authWitnesses = [], capsules = [], extraHashedArgs = [] }) {
|
|
313
|
+
return DeployMethod.create(this.wallet, {
|
|
314
|
+
artifact: this.artifact,
|
|
315
|
+
postDeployCtor: this.postDeployCtor,
|
|
316
|
+
args: this.args,
|
|
317
|
+
constructorNameOrArtifact: this.constructorArtifact?.name
|
|
318
|
+
}, this.cloneInstantiation(), {
|
|
319
|
+
authWitnesses: this.authWitnesses.concat(authWitnesses),
|
|
320
|
+
capsules: this.capsules.concat(capsules),
|
|
321
|
+
extraHashedArgs: this.extraHashedArgs.concat(extraHashedArgs)
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Deploy method whose deployer is fixed at construction to a concrete {@link AztecAddress}. The
|
|
327
|
+
* deployer is mixed into the address preimage, so the contract address is fully determined.
|
|
328
|
+
*
|
|
329
|
+
* Sending from a different account throws — letting it through would silently produce a deployed
|
|
330
|
+
* address different from the one `getAddress()` reported.
|
|
331
|
+
*/ export class BoundDeployMethod extends DeployMethod {
|
|
332
|
+
/** The address baked into the address preimage. Read-only — set at construction. */ deployer;
|
|
333
|
+
constructor(wallet, contract, instantiation, payload = {}){
|
|
334
|
+
// `BoundInstantiationOptions` requires a `deployer` and forbids `universalDeploy` at the type
|
|
335
|
+
// level. We still reject `AztecAddress.ZERO` here because the type system can't model it.
|
|
336
|
+
if (instantiation.deployer.equals(AztecAddress.ZERO)) {
|
|
337
|
+
throw new Error('BoundDeployMethod requires a non-zero `deployer`; use `UniversalDeployMethod` (`{ universalDeploy: true }`) for universal deploys.');
|
|
338
|
+
}
|
|
339
|
+
super(wallet, contract, instantiation.salt, instantiation.publicKeys, instantiation.immutablesHash, payload);
|
|
340
|
+
this.deployer = instantiation.deployer;
|
|
341
|
+
}
|
|
342
|
+
/** Returns the locked deployer baked into the address preimage. */ getDeployerAddress() {
|
|
343
|
+
return this.deployer;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Throws unless `from` matches the locked deployer; the deployer is part of the address.
|
|
347
|
+
* @param from - The send-time `from` value (`AztecAddress`, `NO_FROM`, or `undefined`).
|
|
348
|
+
*/ lockDeployer(from) {
|
|
349
|
+
if (from === undefined || from === NO_FROM || !this.deployer.equals(from)) {
|
|
350
|
+
const sender = from === undefined ? '<unspecified>' : from === NO_FROM ? 'NO_FROM' : from.toString();
|
|
351
|
+
throw new Error(`Deployer for this DeployMethod is locked to ${this.deployer.toString()}; cannot send from ${sender} ` + `because that would imply a different deployer than the one used to derive the address. ` + `Pass \`from: ${this.deployer.toString()}\` to send from the locked deployer, or reconstruct the ` + `deploy with a different \`deployer\` if you need a different sender.`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ cloneInstantiation() {
|
|
355
|
+
return {
|
|
356
|
+
salt: this.salt,
|
|
357
|
+
publicKeys: this.publicKeys,
|
|
358
|
+
immutablesHash: this.immutablesHash,
|
|
359
|
+
deployer: this.deployer
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Deploy method whose deployer is fixed at construction to {@link AztecAddress.ZERO} (universal
|
|
365
|
+
* deploy). The address does not depend on the sender, so any account may sign the deploy tx.
|
|
366
|
+
*/ export class UniversalDeployMethod extends DeployMethod {
|
|
367
|
+
constructor(wallet, contract, instantiation, payload = {}){
|
|
368
|
+
// `UniversalInstantiationOptions` forbids `deployer` and requires `universalDeploy: true` at
|
|
369
|
+
// the type level — no runtime check is needed.
|
|
370
|
+
super(wallet, contract, instantiation.salt, instantiation.publicKeys, instantiation.immutablesHash, payload);
|
|
371
|
+
}
|
|
372
|
+
/** Universal deploys are anchored at `AztecAddress.ZERO`; the sender does not enter the preimage. */ getDeployerAddress() {
|
|
373
|
+
return AztecAddress.ZERO;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Universal deploys accept any sender, including `NO_FROM` / `undefined`.
|
|
377
|
+
* @param _from - Ignored.
|
|
378
|
+
*/ lockDeployer(_from) {
|
|
379
|
+
// No-op.
|
|
380
|
+
}
|
|
381
|
+
/** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ cloneInstantiation() {
|
|
382
|
+
return {
|
|
383
|
+
salt: this.salt,
|
|
384
|
+
publicKeys: this.publicKeys,
|
|
385
|
+
immutablesHash: this.immutablesHash,
|
|
386
|
+
universalDeploy: true
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Deploy method whose deployer is not yet decided. The first `send` / `simulate` / `profile` call
|
|
392
|
+
* promotes this into an {@link BoundDeployMethod} or {@link UniversalDeployMethod} (depending on
|
|
393
|
+
* whether `options.from` is an address or `NO_FROM` / `undefined`); subsequent calls reuse that
|
|
394
|
+
* promotion and reject mismatching `from` values.
|
|
395
|
+
*
|
|
396
|
+
* Reading the address (`getInstance` / `getAddress` / `getPartialAddress`) or building a payload
|
|
397
|
+
* (`request`) before the promotion happens throws — the address would otherwise be ambiguous and
|
|
398
|
+
* could differ from what `send()` ends up deploying.
|
|
399
|
+
*/ export class PendingDeployMethod extends DeployMethod {
|
|
400
|
+
/**
|
|
401
|
+
* The locked sibling created on the first send-side call. Once set, all flavor-specific
|
|
402
|
+
* decisions (sender compatibility, address derivation, clone shape) delegate to it, so a second
|
|
403
|
+
* call with a mismatched `from` is rejected by `BoundDeployMethod.lockDeployer`.
|
|
404
|
+
*/ #locked;
|
|
405
|
+
constructor(wallet, contract, instantiation = {}, payload = {}){
|
|
406
|
+
super(wallet, contract, instantiation.salt, instantiation.publicKeys, instantiation.immutablesHash, payload);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Returns the locked deployer once it has happened. Throws while still pending — the
|
|
410
|
+
* address would otherwise differ from what `send()` ends up deploying.
|
|
411
|
+
*/ getDeployerAddress() {
|
|
412
|
+
if (!this.#locked) {
|
|
413
|
+
throw new Error('Cannot resolve contract address: deployer is not yet locked. Pass `deployer: <address>` ' + 'or `universalDeploy: true` as the instantiation option when constructing the deploy ' + '(e.g. `MyContract.deploy(wallet, ...args, { deployer: alice })`), or call `.send` / ' + '`.simulate` / `.profile` first to lock the deployer from the sender. ');
|
|
414
|
+
}
|
|
415
|
+
return this.#locked.getDeployerAddress();
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* On the first call, promotes this pending method into a locked sibling and remembers it. On
|
|
419
|
+
* subsequent calls, defers to the locked sibling — so a mismatched `from` is rejected by the
|
|
420
|
+
* sibling's own policy, not a duplicate one here.
|
|
421
|
+
* @param from - The send-time `from` value (`AztecAddress`, `NO_FROM`, or `undefined`).
|
|
422
|
+
*/ lockDeployer(from) {
|
|
423
|
+
if (!this.#locked) {
|
|
424
|
+
this.#locked = this.#promoteFrom(from);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
this.#locked.lockDeployer(from);
|
|
428
|
+
}
|
|
429
|
+
/** Re-emits this method's `DeployInstantiationOptions` for `with(...)` to consume. */ cloneInstantiation() {
|
|
430
|
+
if (!this.#locked) {
|
|
431
|
+
return {
|
|
432
|
+
salt: this.salt,
|
|
433
|
+
publicKeys: this.publicKeys,
|
|
434
|
+
immutablesHash: this.immutablesHash
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
return this.#locked.cloneInstantiation();
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Builds the locked sibling implied by a send-time `from`: an `AztecAddress` becomes
|
|
441
|
+
* {@link BoundDeployMethod}; `NO_FROM` / `undefined` becomes {@link UniversalDeployMethod}.
|
|
442
|
+
* @param from - The send-time `from` value.
|
|
443
|
+
*/ #promoteFrom(from) {
|
|
444
|
+
const { wallet, artifact, postDeployCtor, args, salt, publicKeys, immutablesHash, authWitnesses, capsules, extraHashedArgs } = this;
|
|
445
|
+
const contract = {
|
|
446
|
+
artifact,
|
|
447
|
+
postDeployCtor,
|
|
448
|
+
args,
|
|
449
|
+
constructorNameOrArtifact: this.constructorArtifact?.name
|
|
450
|
+
};
|
|
451
|
+
const payload = {
|
|
452
|
+
authWitnesses,
|
|
453
|
+
capsules,
|
|
454
|
+
extraHashedArgs
|
|
455
|
+
};
|
|
456
|
+
if (from === undefined || from === NO_FROM) {
|
|
457
|
+
return new UniversalDeployMethod(wallet, contract, {
|
|
458
|
+
salt,
|
|
459
|
+
publicKeys,
|
|
460
|
+
immutablesHash,
|
|
461
|
+
universalDeploy: true
|
|
462
|
+
}, payload);
|
|
463
|
+
}
|
|
464
|
+
return new BoundDeployMethod(wallet, contract, {
|
|
465
|
+
salt,
|
|
466
|
+
publicKeys,
|
|
467
|
+
immutablesHash,
|
|
468
|
+
deployer: from
|
|
469
|
+
}, payload);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
2
|
+
import type { AztecAddress } from '@aztec-labs/stdlib/aztec-address';
|
|
3
|
+
import type { AztecNode } from '@aztec-labs/stdlib/interfaces/client';
|
|
4
|
+
import { SimulationOverrides } from '@aztec-labs/stdlib/tx';
|
|
5
|
+
/**
|
|
6
|
+
* Builds `SimulationOverrides` that simulate a deployed instance as if it had already been upgraded to a
|
|
7
|
+
* new contract class. Mirrors a real onchain upgrade (scheduling the new class and waiting out the delay):
|
|
8
|
+
*
|
|
9
|
+
* - `publicStorage` rewrites the `ContractInstanceRegistry`'s delayed-public-mutable storage so the AVM's
|
|
10
|
+
* `UpdateCheck` resolves to the new class id.
|
|
11
|
+
* - `contracts` swaps the deployed instance for one whose `currentContractClassId` is bumped to the new class.
|
|
12
|
+
*
|
|
13
|
+
* The new class must already be registered on chain.
|
|
14
|
+
*
|
|
15
|
+
* @throws If the instance is not deployed, the class is not registered on chain, or the instance is already on the target class.
|
|
16
|
+
*/
|
|
17
|
+
export declare function fastForwardContractUpdate(args: {
|
|
18
|
+
/** Address of the deployed instance to upgrade. */
|
|
19
|
+
instanceAddress: AztecAddress;
|
|
20
|
+
/** ID of the (already-registered) class to upgrade to. */
|
|
21
|
+
newClassId: Fr;
|
|
22
|
+
/** Node used to fetch the existing instance and validate the class is registered. */
|
|
23
|
+
node: AztecNode;
|
|
24
|
+
}): Promise<SimulationOverrides>;
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFzdGZvcndhcmRfY29udHJhY3RfdXBkYXRlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29udHJhY3QvZmFzdGZvcndhcmRfY29udHJhY3RfdXBkYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQU1yRSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUU1RDs7Ozs7Ozs7Ozs7R0FXRztBQUNILHdCQUFzQix5QkFBeUIsQ0FBQyxJQUFJLEVBQUU7SUFDcEQsbURBQW1EO0lBQ25ELGVBQWUsRUFBRSxZQUFZLENBQUM7SUFDOUIsMERBQTBEO0lBQzFELFVBQVUsRUFBRSxFQUFFLENBQUM7SUFDZixxRkFBcUY7SUFDckYsSUFBSSxFQUFFLFNBQVMsQ0FBQztDQUNqQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQXdDL0IifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastforward_contract_update.d.ts","sourceRoot":"","sources":["../../src/contract/fastforward_contract_update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,qCAAqC,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAMrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,mDAAmD;IACnD,eAAe,EAAE,YAAY,CAAC;IAC9B,0DAA0D;IAC1D,UAAU,EAAE,EAAE,CAAC;IACf,qFAAqF;IACrF,IAAI,EAAE,SAAS,CAAC;CACjB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAwC/B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
2
|
+
import { ProtocolContractAddress } from '@aztec-labs/protocol-contracts';
|
|
3
|
+
import { DelayedPublicMutableValuesWithHash, ScheduledDelayChange, ScheduledValueChange } from '@aztec-labs/stdlib/delayed-public-mutable';
|
|
4
|
+
import { SimulationOverrides } from '@aztec-labs/stdlib/tx';
|
|
5
|
+
/**
|
|
6
|
+
* Builds `SimulationOverrides` that simulate a deployed instance as if it had already been upgraded to a
|
|
7
|
+
* new contract class. Mirrors a real onchain upgrade (scheduling the new class and waiting out the delay):
|
|
8
|
+
*
|
|
9
|
+
* - `publicStorage` rewrites the `ContractInstanceRegistry`'s delayed-public-mutable storage so the AVM's
|
|
10
|
+
* `UpdateCheck` resolves to the new class id.
|
|
11
|
+
* - `contracts` swaps the deployed instance for one whose `currentContractClassId` is bumped to the new class.
|
|
12
|
+
*
|
|
13
|
+
* The new class must already be registered on chain.
|
|
14
|
+
*
|
|
15
|
+
* @throws If the instance is not deployed, the class is not registered on chain, or the instance is already on the target class.
|
|
16
|
+
*/ export async function fastForwardContractUpdate(args) {
|
|
17
|
+
const { instanceAddress, newClassId, node } = args;
|
|
18
|
+
const instance = await node.getContract(instanceAddress);
|
|
19
|
+
if (!instance) {
|
|
20
|
+
throw new Error(`Instance not deployed at ${instanceAddress}. Deploy it before fast-forwarding an update.`);
|
|
21
|
+
}
|
|
22
|
+
const klass = await node.getContractClass(newClassId);
|
|
23
|
+
if (!klass) {
|
|
24
|
+
throw new Error(`Contract class ${newClassId} is not registered on chain. Publish it before fast-forwarding to it.`);
|
|
25
|
+
}
|
|
26
|
+
if (instance.currentContractClassId.equals(newClassId)) {
|
|
27
|
+
throw new Error(`Instance ${instanceAddress} is already on class ${newClassId}. Nothing to fast-forward.`);
|
|
28
|
+
}
|
|
29
|
+
// Build the SVC the same way `ContractInstanceRegistry::update` would have, but with a timestamp_of_change
|
|
30
|
+
// safely in the past so the AVM's UpdateCheck resolves to the post-upgrade class id at any sim timestamp.
|
|
31
|
+
const svc = new ScheduledValueChange(/*previous=*/ [
|
|
32
|
+
new Fr(0)
|
|
33
|
+
], /*post=*/ [
|
|
34
|
+
newClassId
|
|
35
|
+
], /*timestampOfChange=*/ 1n);
|
|
36
|
+
const sdc = ScheduledDelayChange.empty();
|
|
37
|
+
const dpmv = new DelayedPublicMutableValuesWithHash(svc, sdc);
|
|
38
|
+
const { delayedPublicMutableSlot } = await DelayedPublicMutableValuesWithHash.getContractUpdateSlots(instanceAddress);
|
|
39
|
+
const fields = await dpmv.toFields();
|
|
40
|
+
const publicStorage = fields.map((value, i)=>({
|
|
41
|
+
contract: ProtocolContractAddress.ContractInstanceRegistry,
|
|
42
|
+
slot: delayedPublicMutableSlot.add(new Fr(i)),
|
|
43
|
+
value
|
|
44
|
+
}));
|
|
45
|
+
const upgradedInstance = {
|
|
46
|
+
...instance,
|
|
47
|
+
currentContractClassId: newClassId
|
|
48
|
+
};
|
|
49
|
+
return new SimulationOverrides({
|
|
50
|
+
publicStorage,
|
|
51
|
+
contracts: {
|
|
52
|
+
[instanceAddress.toString()]: {
|
|
53
|
+
instance: upgradedInstance
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|