@bloxchain/sdk 1.0.0-alpha
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 +338 -0
- package/abi/BareBlox.abi.json +1341 -0
- package/abi/BaseStateMachine.abi.json +1308 -0
- package/abi/ControlBlox.abi.json +6210 -0
- package/abi/EngineBlox.abi.json +872 -0
- package/abi/GuardController.abi.json +3045 -0
- package/abi/IDefinition.abi.json +94 -0
- package/abi/RoleBlox.abi.json +4569 -0
- package/abi/RuntimeRBAC.abi.json +1857 -0
- package/abi/RuntimeRBACDefinitions.abi.json +133 -0
- package/abi/SecureBlox.abi.json +4085 -0
- package/abi/SecureOwnable.abi.json +4085 -0
- package/abi/SecureOwnableDefinitions.abi.json +354 -0
- package/abi/SimpleRWA20.abi.json +5545 -0
- package/abi/SimpleRWA20Definitions.abi.json +172 -0
- package/abi/SimpleVault.abi.json +5208 -0
- package/abi/SimpleVaultDefinitions.abi.json +250 -0
- package/dist/abi/BaseStateMachine.abi.json +1308 -0
- package/dist/abi/GuardController.abi.json +3045 -0
- package/dist/abi/IDefinition.abi.json +94 -0
- package/dist/abi/RuntimeRBAC.abi.json +1857 -0
- package/dist/abi/SecureOwnable.abi.json +4085 -0
- package/dist/contracts/BaseStateMachine.d.ts +83 -0
- package/dist/contracts/BaseStateMachine.d.ts.map +1 -0
- package/dist/contracts/BaseStateMachine.js +251 -0
- package/dist/contracts/BaseStateMachine.js.map +1 -0
- package/dist/contracts/GuardController.d.ts +120 -0
- package/dist/contracts/GuardController.d.ts.map +1 -0
- package/dist/contracts/GuardController.js +149 -0
- package/dist/contracts/GuardController.js.map +1 -0
- package/dist/contracts/RuntimeRBAC.d.ts +56 -0
- package/dist/contracts/RuntimeRBAC.d.ts.map +1 -0
- package/dist/contracts/RuntimeRBAC.js +57 -0
- package/dist/contracts/RuntimeRBAC.js.map +1 -0
- package/dist/contracts/SecureOwnable.d.ts +41 -0
- package/dist/contracts/SecureOwnable.d.ts.map +1 -0
- package/dist/contracts/SecureOwnable.js +82 -0
- package/dist/contracts/SecureOwnable.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/base.index.d.ts +18 -0
- package/dist/interfaces/base.index.d.ts.map +1 -0
- package/dist/interfaces/base.index.js +2 -0
- package/dist/interfaces/base.index.js.map +1 -0
- package/dist/interfaces/base.state.machine.index.d.ts +72 -0
- package/dist/interfaces/base.state.machine.index.d.ts.map +1 -0
- package/dist/interfaces/base.state.machine.index.js +2 -0
- package/dist/interfaces/base.state.machine.index.js.map +1 -0
- package/dist/interfaces/core.access.index.d.ts +37 -0
- package/dist/interfaces/core.access.index.d.ts.map +1 -0
- package/dist/interfaces/core.access.index.js +2 -0
- package/dist/interfaces/core.access.index.js.map +1 -0
- package/dist/interfaces/core.execution.index.d.ts +44 -0
- package/dist/interfaces/core.execution.index.d.ts.map +1 -0
- package/dist/interfaces/core.execution.index.js +2 -0
- package/dist/interfaces/core.execution.index.js.map +1 -0
- package/dist/interfaces/core.security.index.d.ts +83 -0
- package/dist/interfaces/core.security.index.d.ts.map +1 -0
- package/dist/interfaces/core.security.index.js +2 -0
- package/dist/interfaces/core.security.index.js.map +1 -0
- package/dist/interfaces/definition.index.d.ts +38 -0
- package/dist/interfaces/definition.index.d.ts.map +1 -0
- package/dist/interfaces/definition.index.js +2 -0
- package/dist/interfaces/definition.index.js.map +1 -0
- package/dist/interfaces/lib.index.d.ts +83 -0
- package/dist/interfaces/lib.index.d.ts.map +1 -0
- package/dist/interfaces/lib.index.js +2 -0
- package/dist/interfaces/lib.index.js.map +1 -0
- package/dist/lib/Definition.d.ts +84 -0
- package/dist/lib/Definition.d.ts.map +1 -0
- package/dist/lib/Definition.js +159 -0
- package/dist/lib/Definition.js.map +1 -0
- package/dist/lib/EngineBlox.d.ts +167 -0
- package/dist/lib/EngineBlox.d.ts.map +1 -0
- package/dist/lib/EngineBlox.js +266 -0
- package/dist/lib/EngineBlox.js.map +1 -0
- package/dist/types/base.state.machine.index.d.ts +45 -0
- package/dist/types/base.state.machine.index.d.ts.map +1 -0
- package/dist/types/base.state.machine.index.js +49 -0
- package/dist/types/base.state.machine.index.js.map +1 -0
- package/dist/types/core.access.index.d.ts +51 -0
- package/dist/types/core.access.index.d.ts.map +1 -0
- package/dist/types/core.access.index.js +41 -0
- package/dist/types/core.access.index.js.map +1 -0
- package/dist/types/core.execution.index.d.ts +36 -0
- package/dist/types/core.execution.index.d.ts.map +1 -0
- package/dist/types/core.execution.index.js +30 -0
- package/dist/types/core.execution.index.js.map +1 -0
- package/dist/types/core.security.index.d.ts +36 -0
- package/dist/types/core.security.index.d.ts.map +1 -0
- package/dist/types/core.security.index.js +37 -0
- package/dist/types/core.security.index.js.map +1 -0
- package/dist/types/definition.index.d.ts +36 -0
- package/dist/types/definition.index.d.ts.map +1 -0
- package/dist/types/definition.index.js +4 -0
- package/dist/types/definition.index.js.map +1 -0
- package/dist/types/lib.index.d.ts +66 -0
- package/dist/types/lib.index.d.ts.map +1 -0
- package/dist/types/lib.index.js +68 -0
- package/dist/types/lib.index.js.map +1 -0
- package/dist/utils/bitmap.d.ts +75 -0
- package/dist/utils/bitmap.d.ts.map +1 -0
- package/dist/utils/bitmap.js +124 -0
- package/dist/utils/bitmap.js.map +1 -0
- package/dist/utils/contract-errors.d.ts +536 -0
- package/dist/utils/contract-errors.d.ts.map +1 -0
- package/dist/utils/contract-errors.js +412 -0
- package/dist/utils/contract-errors.js.map +1 -0
- package/dist/utils/erc20/ERC20Token.abi.json +217 -0
- package/dist/utils/erc20/erc20Token.d.ts +83 -0
- package/dist/utils/erc20/erc20Token.d.ts.map +1 -0
- package/dist/utils/erc20/erc20Token.js +173 -0
- package/dist/utils/erc20/erc20Token.js.map +1 -0
- package/dist/utils/interface-ids.d.ts +59 -0
- package/dist/utils/interface-ids.d.ts.map +1 -0
- package/dist/utils/interface-ids.js +149 -0
- package/dist/utils/interface-ids.js.map +1 -0
- package/dist/utils/metaTx/metaTransaction.d.ts +138 -0
- package/dist/utils/metaTx/metaTransaction.d.ts.map +1 -0
- package/dist/utils/metaTx/metaTransaction.js +271 -0
- package/dist/utils/metaTx/metaTransaction.js.map +1 -0
- package/dist/utils/validations.d.ts +104 -0
- package/dist/utils/validations.d.ts.map +1 -0
- package/dist/utils/validations.js +254 -0
- package/dist/utils/validations.js.map +1 -0
- package/dist/utils/viem-error-handler.d.ts +48 -0
- package/dist/utils/viem-error-handler.d.ts.map +1 -0
- package/dist/utils/viem-error-handler.js +172 -0
- package/dist/utils/viem-error-handler.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import BaseStateMachineABI from '../../abi/BaseStateMachine.abi.json';
|
|
2
|
+
/**
|
|
3
|
+
* @title MetaTransactionSigner
|
|
4
|
+
* @dev Standardized utility for creating and signing meta-transactions
|
|
5
|
+
*
|
|
6
|
+
* This utility leverages the contract's own EIP-712 message hash generation
|
|
7
|
+
* to avoid JavaScript replication issues and ensure signature compatibility.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* - Step 1: Create unsigned meta-transaction (contract generates message hash)
|
|
11
|
+
* - Step 2: Sign the message hash (programmatic or external wallet)
|
|
12
|
+
* - Step 3: Verify signature and return complete meta-transaction
|
|
13
|
+
*
|
|
14
|
+
* Key Features:
|
|
15
|
+
* - Contract-based message hash generation
|
|
16
|
+
* - Separated unsigned creation and signing steps
|
|
17
|
+
* - Support for programmatic and frontend wallet signing
|
|
18
|
+
* - Type-safe meta-transaction creation
|
|
19
|
+
* - Automatic signature verification
|
|
20
|
+
* - Support for both new and existing transactions
|
|
21
|
+
*
|
|
22
|
+
* Security: Uses the contract's generateUnsignedForNewMetaTx/generateUnsignedForExistingMetaTx
|
|
23
|
+
* functions to ensure exact EIP-712 compliance with the on-chain implementation.
|
|
24
|
+
*/
|
|
25
|
+
export class MetaTransactionSigner {
|
|
26
|
+
constructor(client, walletClient, contractAddress, chain) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
this.walletClient = walletClient;
|
|
29
|
+
this.contractAddress = contractAddress;
|
|
30
|
+
this.chain = chain;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @dev Creates an unsigned meta-transaction for a new operation
|
|
34
|
+
* @param txParams Transaction parameters
|
|
35
|
+
* @param metaTxParams Meta-transaction parameters
|
|
36
|
+
* @returns Unsigned meta-transaction ready for signing
|
|
37
|
+
*/
|
|
38
|
+
async createUnsignedMetaTransactionForNew(txParams, metaTxParams) {
|
|
39
|
+
// Call the private method which handles the contract call
|
|
40
|
+
return await this.generateUnsignedMetaTransactionForNew(txParams, metaTxParams);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @dev Creates an unsigned meta-transaction for an existing operation
|
|
44
|
+
* @param txId Existing transaction ID
|
|
45
|
+
* @param metaTxParams Meta-transaction parameters
|
|
46
|
+
* @returns Unsigned meta-transaction ready for signing
|
|
47
|
+
*/
|
|
48
|
+
async createUnsignedMetaTransactionForExisting(txId, metaTxParams) {
|
|
49
|
+
const result = await this.generateUnsignedMetaTransactionForExisting(txId, metaTxParams);
|
|
50
|
+
// The contract returns a complete MetaTransaction with data field populated
|
|
51
|
+
return {
|
|
52
|
+
txRecord: result.txRecord,
|
|
53
|
+
params: result.params,
|
|
54
|
+
message: result.message,
|
|
55
|
+
signature: result.signature,
|
|
56
|
+
data: result.data
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @dev Signs an unsigned meta-transaction using private key (for remote Ganache compatibility)
|
|
61
|
+
* @param unsignedMetaTx Unsigned meta-transaction
|
|
62
|
+
* @param signerAddress Address of the signer
|
|
63
|
+
* @param privateKey Private key for signing (required for remote Ganache)
|
|
64
|
+
* @returns Complete signed meta-transaction
|
|
65
|
+
*/
|
|
66
|
+
async signMetaTransaction(unsignedMetaTx, signerAddress, privateKey) {
|
|
67
|
+
// Use private key signing directly (matches sanity test pattern)
|
|
68
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
69
|
+
const account = privateKeyToAccount(privateKey);
|
|
70
|
+
// Sign the message hash using the account
|
|
71
|
+
const signature = await account.signMessage({
|
|
72
|
+
message: { raw: unsignedMetaTx.message }
|
|
73
|
+
});
|
|
74
|
+
// Verify signature matches expected signer
|
|
75
|
+
const recoveredAddress = await this.client.verifyMessage({
|
|
76
|
+
address: signerAddress,
|
|
77
|
+
message: { raw: unsignedMetaTx.message },
|
|
78
|
+
signature
|
|
79
|
+
});
|
|
80
|
+
if (!recoveredAddress) {
|
|
81
|
+
throw new Error('Signature verification failed');
|
|
82
|
+
}
|
|
83
|
+
// Return complete signed meta-transaction
|
|
84
|
+
return {
|
|
85
|
+
...unsignedMetaTx,
|
|
86
|
+
signature
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* @dev Creates a signed meta-transaction with external signature (for frontend wallets)
|
|
91
|
+
* @param unsignedMetaTx Unsigned meta-transaction
|
|
92
|
+
* @param signature External signature from wallet
|
|
93
|
+
* @returns Complete signed meta-transaction
|
|
94
|
+
*/
|
|
95
|
+
async createSignedMetaTransactionWithSignature(unsignedMetaTx, signature) {
|
|
96
|
+
// Verify signature
|
|
97
|
+
await this.verifySignature(unsignedMetaTx.message, signature, unsignedMetaTx.params.signer);
|
|
98
|
+
// Return complete signed meta-transaction
|
|
99
|
+
return {
|
|
100
|
+
...unsignedMetaTx,
|
|
101
|
+
signature
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @dev Creates a signed meta-transaction for a new operation (convenience method)
|
|
106
|
+
* @param txParams Transaction parameters
|
|
107
|
+
* @param metaTxParams Meta-transaction parameters
|
|
108
|
+
* @param signerAddress Address of the signer
|
|
109
|
+
* @param privateKey Private key for signing (required for remote Ganache)
|
|
110
|
+
* @returns Complete signed meta-transaction
|
|
111
|
+
*/
|
|
112
|
+
async createSignedMetaTransactionForNew(txParams, metaTxParams, signerAddress, privateKey) {
|
|
113
|
+
const unsignedMetaTx = await this.createUnsignedMetaTransactionForNew(txParams, metaTxParams);
|
|
114
|
+
return await this.signMetaTransaction(unsignedMetaTx, signerAddress, privateKey);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @dev Creates a signed meta-transaction for an existing transaction (convenience method)
|
|
118
|
+
* @param txId Existing transaction ID
|
|
119
|
+
* @param metaTxParams Meta-transaction parameters
|
|
120
|
+
* @param signerAddress Address of the signer
|
|
121
|
+
* @param privateKey Private key for signing (required for remote Ganache)
|
|
122
|
+
* @returns Complete signed meta-transaction
|
|
123
|
+
*/
|
|
124
|
+
async createSignedMetaTransactionForExisting(txId, metaTxParams, signerAddress, privateKey) {
|
|
125
|
+
const unsignedMetaTx = await this.createUnsignedMetaTransactionForExisting(txId, metaTxParams);
|
|
126
|
+
return await this.signMetaTransaction(unsignedMetaTx, signerAddress, privateKey);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* @dev Generates unsigned meta-transaction for new operation using contract
|
|
130
|
+
* @param txParams Transaction parameters
|
|
131
|
+
* @param metaTxParams Meta-transaction parameters
|
|
132
|
+
* @returns Complete MetaTransaction from contract (with data field populated)
|
|
133
|
+
*/
|
|
134
|
+
async generateUnsignedMetaTransactionForNew(txParams, metaTxParams) {
|
|
135
|
+
const result = await this.client.readContract({
|
|
136
|
+
address: this.contractAddress,
|
|
137
|
+
abi: this.getContractABI(),
|
|
138
|
+
functionName: 'generateUnsignedMetaTransactionForNew',
|
|
139
|
+
args: [
|
|
140
|
+
txParams.requester,
|
|
141
|
+
txParams.target,
|
|
142
|
+
txParams.value,
|
|
143
|
+
txParams.gasLimit,
|
|
144
|
+
txParams.operationType,
|
|
145
|
+
txParams.executionSelector,
|
|
146
|
+
txParams.executionParams,
|
|
147
|
+
metaTxParams
|
|
148
|
+
],
|
|
149
|
+
// Include account for permission checks if wallet client is available
|
|
150
|
+
account: this.walletClient?.account
|
|
151
|
+
});
|
|
152
|
+
// The contract returns a complete MetaTransaction struct
|
|
153
|
+
// Extract all fields including data which is computed by prepareTransactionData
|
|
154
|
+
const metaTx = result;
|
|
155
|
+
if (!metaTx.message || metaTx.message === '0x0000000000000000000000000000000000000000000000000000000000000000') {
|
|
156
|
+
throw new Error('Contract did not generate a valid message hash');
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
txRecord: metaTx.txRecord,
|
|
160
|
+
params: metaTx.params,
|
|
161
|
+
message: metaTx.message,
|
|
162
|
+
signature: metaTx.signature,
|
|
163
|
+
data: metaTx.data
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* @dev Generates unsigned meta-transaction for existing operation using contract
|
|
168
|
+
* @param txId Transaction ID
|
|
169
|
+
* @param metaTxParams Meta-transaction parameters
|
|
170
|
+
* @returns Complete MetaTransaction from contract (with data field populated)
|
|
171
|
+
*/
|
|
172
|
+
async generateUnsignedMetaTransactionForExisting(txId, metaTxParams) {
|
|
173
|
+
const result = await this.client.readContract({
|
|
174
|
+
address: this.contractAddress,
|
|
175
|
+
abi: this.getContractABI(),
|
|
176
|
+
functionName: 'generateUnsignedMetaTransactionForExisting',
|
|
177
|
+
args: [txId, metaTxParams],
|
|
178
|
+
// Include account for permission checks if wallet client is available
|
|
179
|
+
account: this.walletClient?.account
|
|
180
|
+
});
|
|
181
|
+
// The contract returns a complete MetaTransaction struct
|
|
182
|
+
// Extract all fields including data which is computed by prepareTransactionData
|
|
183
|
+
const metaTx = result;
|
|
184
|
+
if (!metaTx.message || metaTx.message === '0x0000000000000000000000000000000000000000000000000000000000000000') {
|
|
185
|
+
throw new Error('Contract did not generate a valid message hash');
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
txRecord: metaTx.txRecord,
|
|
189
|
+
params: metaTx.params,
|
|
190
|
+
message: metaTx.message,
|
|
191
|
+
signature: metaTx.signature,
|
|
192
|
+
data: metaTx.data
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* @dev Verifies a signature against a message hash and expected signer
|
|
197
|
+
* @param messageHash The message hash
|
|
198
|
+
* @param signature The signature to verify
|
|
199
|
+
* @param expectedSigner The expected signer address
|
|
200
|
+
*/
|
|
201
|
+
async verifySignature(messageHash, signature, expectedSigner) {
|
|
202
|
+
const recoveredAddress = await this.client.verifyMessage({
|
|
203
|
+
address: expectedSigner,
|
|
204
|
+
message: { raw: messageHash },
|
|
205
|
+
signature
|
|
206
|
+
});
|
|
207
|
+
if (!recoveredAddress) {
|
|
208
|
+
throw new Error('Signature verification failed');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* @dev Gets the contract ABI for meta-transaction functions
|
|
213
|
+
* Uses BaseStateMachine ABI to match the actual deployed contract
|
|
214
|
+
* @returns Contract ABI
|
|
215
|
+
*/
|
|
216
|
+
getContractABI() {
|
|
217
|
+
return BaseStateMachineABI;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* @dev Helper functions for creating meta-transaction parameters
|
|
222
|
+
*/
|
|
223
|
+
export class MetaTransactionBuilder {
|
|
224
|
+
/**
|
|
225
|
+
* @dev Creates meta-transaction parameters
|
|
226
|
+
* @param handlerContract Handler contract address
|
|
227
|
+
* @param handlerSelector Handler function selector
|
|
228
|
+
* @param action Transaction action
|
|
229
|
+
* @param deadline Deadline timestamp
|
|
230
|
+
* @param maxGasPrice Maximum gas price
|
|
231
|
+
* @param signer Signer address
|
|
232
|
+
* @param chainId Chain ID (optional, defaults to current chain)
|
|
233
|
+
* @param nonce Nonce (optional, will be fetched from contract)
|
|
234
|
+
* @returns Meta-transaction parameters
|
|
235
|
+
*/
|
|
236
|
+
static createMetaTxParams(handlerContract, handlerSelector, action, deadline, maxGasPrice, signer, chainId, nonce) {
|
|
237
|
+
return {
|
|
238
|
+
chainId: chainId, // Default to mainnet
|
|
239
|
+
nonce: nonce || 0n,
|
|
240
|
+
handlerContract,
|
|
241
|
+
handlerSelector,
|
|
242
|
+
action,
|
|
243
|
+
deadline,
|
|
244
|
+
maxGasPrice,
|
|
245
|
+
signer
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* @dev Creates transaction parameters
|
|
250
|
+
* @param requester Requester address
|
|
251
|
+
* @param target Target contract address
|
|
252
|
+
* @param value Value to send
|
|
253
|
+
* @param gasLimit Gas limit
|
|
254
|
+
* @param operationType Operation type
|
|
255
|
+
* @param executionSelector Execution selector (bytes4)
|
|
256
|
+
* @param executionParams Execution parameters
|
|
257
|
+
* @returns Transaction parameters
|
|
258
|
+
*/
|
|
259
|
+
static createTxParams(requester, target, value, gasLimit, operationType, executionSelector, executionParams) {
|
|
260
|
+
return {
|
|
261
|
+
requester,
|
|
262
|
+
target,
|
|
263
|
+
value,
|
|
264
|
+
gasLimit,
|
|
265
|
+
operationType,
|
|
266
|
+
executionSelector,
|
|
267
|
+
executionParams
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=metaTransaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metaTransaction.js","sourceRoot":"","sources":["../../../utils/metaTx/metaTransaction.tsx"],"names":[],"mappings":"AAcA,OAAO,mBAAmB,MAAM,qCAAqC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,qBAAqB;IAMhC,YACE,MAAoB,EACpB,YAAsC,EACtC,eAAwB,EACxB,KAAY;QAEZ,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,mCAAmC,CACvC,QAAkB,EAClB,YAA0B;QAE1B,0DAA0D;QAC1D,OAAO,MAAM,IAAI,CAAC,qCAAqC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAClF,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,wCAAwC,CAC5C,IAAY,EACZ,YAA0B;QAE1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,0CAA0C,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAEzF,4EAA4E;QAC5E,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAgB;YAClC,IAAI,EAAE,MAAM,CAAC,IAAW;SACzB,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,mBAAmB,CACvB,cAA+B,EAC/B,aAAsB,EACtB,UAAe;QAEf,iEAAiE;QACjE,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAEhD,0CAA0C;QAC1C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC;YAC1C,OAAO,EAAE,EAAE,GAAG,EAAE,cAAc,CAAC,OAAO,EAAE;SACzC,CAAC,CAAC;QAEH,2CAA2C;QAC3C,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;YACvD,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,EAAE,GAAG,EAAE,cAAc,CAAC,OAAO,EAAE;YACxC,SAAS;SACV,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,0CAA0C;QAC1C,OAAO;YACL,GAAG,cAAc;YACjB,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,wCAAwC,CAC5C,cAA+B,EAC/B,SAAc;QAEd,mBAAmB;QACnB,MAAM,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE5F,0CAA0C;QAC1C,OAAO;YACL,GAAG,cAAc;YACjB,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,iCAAiC,CACrC,QAAkB,EAClB,YAA0B,EAC1B,aAAsB,EACtB,UAAe;QAEf,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,mCAAmC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC9F,OAAO,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,sCAAsC,CAC1C,IAAY,EACZ,YAA0B,EAC1B,aAAsB,EACtB,UAAe;QAEf,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,wCAAwC,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAC/F,OAAO,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,qCAAqC,CACjD,QAAkB,EAClB,YAA0B;QAE1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC5C,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE;YAC1B,YAAY,EAAE,uCAAuC;YACrD,IAAI,EAAE;gBACJ,QAAQ,CAAC,SAAS;gBAClB,QAAQ,CAAC,MAAM;gBACf,QAAQ,CAAC,KAAK;gBACd,QAAQ,CAAC,QAAQ;gBACjB,QAAQ,CAAC,aAAa;gBACtB,QAAQ,CAAC,iBAAiB;gBAC1B,QAAQ,CAAC,eAAe;gBACxB,YAAY;aACb;YACD,sEAAsE;YACtE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO;SACpC,CAAC,CAAC;QAEH,yDAAyD;QACzD,gFAAgF;QAChF,MAAM,MAAM,GAAG,MAAa,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,KAAK,oEAAoE,EAAE,CAAC;YAC/G,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAgB;YAClC,IAAI,EAAE,MAAM,CAAC,IAAW;SACzB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,0CAA0C,CACtD,IAAY,EACZ,YAA0B;QAE1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC5C,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE;YAC1B,YAAY,EAAE,4CAA4C;YAC1D,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;YAC1B,sEAAsE;YACtE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO;SACpC,CAAC,CAAC;QAEH,yDAAyD;QACzD,gFAAgF;QAChF,MAAM,MAAM,GAAG,MAAa,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,KAAK,oEAAoE,EAAE,CAAC;YAC/G,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAgB;YAClC,IAAI,EAAE,MAAM,CAAC,IAAW;SACzB,CAAC;IACJ,CAAC;IAGD;;;;;OAKG;IACK,KAAK,CAAC,eAAe,CAC3B,WAAgB,EAChB,SAAc,EACd,cAAuB;QAEvB,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;YACvD,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE;YAC7B,SAAS;SACV,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAGD;;;;OAIG;IACK,cAAc;QACpB,OAAO,mBAA4B,CAAC;IACtC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAEjC;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,kBAAkB,CACvB,eAAwB,EACxB,eAAoB,EACpB,MAAgB,EAChB,QAAgB,EAChB,WAAmB,EACnB,MAAe,EACf,OAAe,EACf,KAAc;QAEd,OAAO;YACL,OAAO,EAAE,OAAO,EAAE,qBAAqB;YACvC,KAAK,EAAE,KAAK,IAAI,EAAE;YAClB,eAAe;YACf,eAAe;YACf,MAAM;YACN,QAAQ;YACR,WAAW;YACX,MAAM;SACP,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,cAAc,CACnB,SAAkB,EAClB,MAAe,EACf,KAAa,EACb,QAAgB,EAChB,aAAkB,EAClB,iBAAsB,EACtB,eAAoB;QAEpB,OAAO;YACL,SAAS;YACT,MAAM;YACN,KAAK;YACL,QAAQ;YACR,aAAa;YACb,iBAAiB;YACjB,eAAe;SAChB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Address, PublicClient } from 'viem';
|
|
2
|
+
import { MetaTransaction } from '../interfaces/lib.index';
|
|
3
|
+
export declare class ContractValidations {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: PublicClient);
|
|
6
|
+
/**
|
|
7
|
+
* @notice Validates a meta transaction's parameters
|
|
8
|
+
* @param metaTx The meta transaction to validate
|
|
9
|
+
* @throws Error if any validation fails
|
|
10
|
+
*/
|
|
11
|
+
validateMetaTransaction(metaTx: MetaTransaction): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* @notice Validates a transaction record's parameters
|
|
14
|
+
* @param txRecord The transaction record to validate
|
|
15
|
+
* @throws Error if any validation fails
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
private validateTxRecord;
|
|
19
|
+
/**
|
|
20
|
+
* @notice Validates transaction parameters
|
|
21
|
+
* @param params The transaction parameters to validate
|
|
22
|
+
* @throws Error if any validation fails
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
private validateTxParams;
|
|
26
|
+
/**
|
|
27
|
+
* @notice Validates if a string is a valid hex value
|
|
28
|
+
* @param value The hex string to validate
|
|
29
|
+
* @param exactBytes Optional parameter for exact byte length
|
|
30
|
+
* @returns boolean indicating if the hex string is valid
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
private isValidHex;
|
|
34
|
+
/**
|
|
35
|
+
* @notice Validates payment details
|
|
36
|
+
* @param payment The payment details to validate
|
|
37
|
+
* @throws Error if any validation fails
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
private validatePaymentDetails;
|
|
41
|
+
/**
|
|
42
|
+
* @notice Validates if a timestamp is in the future
|
|
43
|
+
* @param timestamp The timestamp to validate
|
|
44
|
+
* @param errorMessage Custom error message
|
|
45
|
+
* @throws Error if timestamp is not in the future
|
|
46
|
+
*/
|
|
47
|
+
validateFutureTimestamp(timestamp: number, errorMessage?: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* @notice Validates if a period in minutes is valid
|
|
50
|
+
* @param periodInMinutes The period to validate
|
|
51
|
+
* @param errorMessage Custom error message
|
|
52
|
+
* @throws Error if period is not valid
|
|
53
|
+
*/
|
|
54
|
+
validateTimePeriod(periodInMinutes: number, errorMessage?: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* @notice Validates if an address has admin owner role
|
|
57
|
+
* @dev Equivalent to onlyAdminOwner modifier in Solidity
|
|
58
|
+
* @param address The address to validate
|
|
59
|
+
* @param adminOwner The expected admin owner address
|
|
60
|
+
* @throws Error if address is not admin owner
|
|
61
|
+
*/
|
|
62
|
+
validateAdminOwner(address: Address | undefined, adminOwner: Address): void;
|
|
63
|
+
/**
|
|
64
|
+
* @notice Validates if an address has broadcaster role
|
|
65
|
+
* @dev Equivalent to onlyBroadcaster modifier in Solidity
|
|
66
|
+
* @param address The address to validate
|
|
67
|
+
* @param broadcaster The expected broadcaster address
|
|
68
|
+
* @throws Error if address is not broadcaster
|
|
69
|
+
*/
|
|
70
|
+
validateBroadcaster(address: Address | undefined, broadcaster: Address): void;
|
|
71
|
+
/**
|
|
72
|
+
* @notice Validates if an address has recovery role
|
|
73
|
+
* @dev Equivalent to onlyRecovery modifier in Solidity
|
|
74
|
+
* @param address The address to validate
|
|
75
|
+
* @param recovery The expected recovery address
|
|
76
|
+
* @throws Error if address is not recovery address
|
|
77
|
+
*/
|
|
78
|
+
validateRecovery(address: Address | undefined, recovery: Address): void;
|
|
79
|
+
/**
|
|
80
|
+
* @notice Validates if an address has a specific role
|
|
81
|
+
* @param address The address to validate
|
|
82
|
+
* @param roleAddress The expected role address
|
|
83
|
+
* @param roleName The name of the role for error messages
|
|
84
|
+
* @throws Error if address doesn't match role address
|
|
85
|
+
*/
|
|
86
|
+
validateRole(address: Address | undefined, roleAddress: Address, roleName: string): void;
|
|
87
|
+
/**
|
|
88
|
+
* @notice Validates if an address has either of two roles
|
|
89
|
+
* @param address The address to validate
|
|
90
|
+
* @param role1Address First role address
|
|
91
|
+
* @param role2Address Second role address
|
|
92
|
+
* @param roleNames Names of the roles for error messages
|
|
93
|
+
* @throws Error if address doesn't match either role
|
|
94
|
+
*/
|
|
95
|
+
validateMultipleRoles(address: Address | undefined, role1Address: Address, role2Address: Address, roleNames: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* @notice Validates native token balance
|
|
98
|
+
* @param contractAddress The contract address to check
|
|
99
|
+
* @param requiredAmount The required balance amount
|
|
100
|
+
* @throws Error if balance is insufficient
|
|
101
|
+
*/
|
|
102
|
+
validateNativeTokenBalance(contractAddress: Address, requiredAmount: bigint): Promise<void>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=validations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validations.d.ts","sourceRoot":"","sources":["../../utils/validations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAA4B,MAAM,MAAM,CAAC;AACvE,OAAO,EAAE,eAAe,EAAsC,MAAM,yBAAyB,CAAC;AAG9F,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,YAAY;IAG9B;;;;OAIG;IACG,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CrE;;;;;OAKG;YACW,gBAAgB;IAkC9B;;;;;OAKG;YACW,gBAAgB;IAsC9B;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAiBlB;;;;;OAKG;YACW,sBAAsB;IAwBpC;;;;;OAKG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,GAAE,MAA0C,GAAG,IAAI;IAM1G;;;;;OAKG;IACH,kBAAkB,CAAC,eAAe,EAAE,MAAM,EAAE,YAAY,GAAE,MAA8B,GAAG,IAAI;IAM/F;;;;;;OAMG;IACH,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI;IAI3E;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI;IAI7E;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAIvE;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMxF;;;;;;;OAOG;IACH,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAM1H;;;;;OAKG;IACG,0BAA0B,CAAC,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMlG"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { TxStatus } from '../types/lib.index';
|
|
2
|
+
export class ContractValidations {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @notice Validates a meta transaction's parameters
|
|
8
|
+
* @param metaTx The meta transaction to validate
|
|
9
|
+
* @throws Error if any validation fails
|
|
10
|
+
*/
|
|
11
|
+
async validateMetaTransaction(metaTx) {
|
|
12
|
+
// Validate signature
|
|
13
|
+
// 65 bytes signature when converted to hex string becomes 132 characters (0x + 130)
|
|
14
|
+
if (!metaTx.signature || metaTx.signature.length !== 132) {
|
|
15
|
+
throw new Error("Invalid signature length");
|
|
16
|
+
}
|
|
17
|
+
// Validate chain ID
|
|
18
|
+
const currentChainId = await this.client.getChainId();
|
|
19
|
+
if (BigInt(metaTx.params.chainId) !== BigInt(currentChainId)) {
|
|
20
|
+
throw new Error("Chain ID mismatch");
|
|
21
|
+
}
|
|
22
|
+
// Validate handler contract
|
|
23
|
+
if (!metaTx.params.handlerContract) {
|
|
24
|
+
throw new Error("Invalid handler contract address");
|
|
25
|
+
}
|
|
26
|
+
// Validate handler selector (must be 4 bytes)
|
|
27
|
+
if (!metaTx.params.handlerSelector || !(/^0x[0-9a-f]{8}$/i.test(metaTx.params.handlerSelector))) {
|
|
28
|
+
throw new Error("Invalid handler selector format");
|
|
29
|
+
}
|
|
30
|
+
// Validate deadline
|
|
31
|
+
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
32
|
+
if (currentTimestamp > metaTx.params.deadline) {
|
|
33
|
+
throw new Error("Meta-transaction expired");
|
|
34
|
+
}
|
|
35
|
+
// Validate max gas price
|
|
36
|
+
const currentGasPrice = await this.client.getGasPrice();
|
|
37
|
+
if (currentGasPrice > BigInt(metaTx.params.maxGasPrice) && metaTx.params.maxGasPrice > BigInt(0)) {
|
|
38
|
+
throw new Error(`Current gas price exceeds maximum allowed: ${currentGasPrice} > ${metaTx.params.maxGasPrice}`);
|
|
39
|
+
}
|
|
40
|
+
// Validate signer
|
|
41
|
+
if (!metaTx.params.signer) {
|
|
42
|
+
throw new Error("Invalid signer address");
|
|
43
|
+
}
|
|
44
|
+
// Validate transaction record
|
|
45
|
+
await this.validateTxRecord(metaTx.txRecord);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @notice Validates a transaction record's parameters
|
|
49
|
+
* @param txRecord The transaction record to validate
|
|
50
|
+
* @throws Error if any validation fails
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
async validateTxRecord(txRecord) {
|
|
54
|
+
// Validate txId
|
|
55
|
+
if (txRecord.txId <= 0) {
|
|
56
|
+
throw new Error("Invalid transaction ID");
|
|
57
|
+
}
|
|
58
|
+
// Validate status (must be PENDING for meta transactions)
|
|
59
|
+
if (txRecord.status !== TxStatus.PENDING) {
|
|
60
|
+
throw new Error(`Transaction must be in pending state: ${txRecord.status}`);
|
|
61
|
+
}
|
|
62
|
+
// Validate params
|
|
63
|
+
await this.validateTxParams(txRecord.params);
|
|
64
|
+
// Validate result (must be empty for pending transactions)
|
|
65
|
+
if (txRecord.result) {
|
|
66
|
+
// First check if it's a valid hex string
|
|
67
|
+
if (!this.isValidHex(txRecord.result)) {
|
|
68
|
+
throw new Error("Invalid hex format for transaction result");
|
|
69
|
+
}
|
|
70
|
+
// For pending transactions, only allow '0x' or '0x0' or '0x000000'
|
|
71
|
+
const strippedResult = txRecord.result.replace(/^0x0*$/, '0x');
|
|
72
|
+
if (strippedResult !== '0x') {
|
|
73
|
+
throw new Error("Result must be empty for pending transactions");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Validate payment details if present
|
|
77
|
+
if (txRecord.payment) {
|
|
78
|
+
await this.validatePaymentDetails(txRecord.payment);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @notice Validates transaction parameters
|
|
83
|
+
* @param params The transaction parameters to validate
|
|
84
|
+
* @throws Error if any validation fails
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
async validateTxParams(params) {
|
|
88
|
+
// Validate requester address
|
|
89
|
+
if (!params.requester) {
|
|
90
|
+
throw new Error("Invalid requester address");
|
|
91
|
+
}
|
|
92
|
+
// Validate target address
|
|
93
|
+
if (!params.target) {
|
|
94
|
+
throw new Error("Invalid target address");
|
|
95
|
+
}
|
|
96
|
+
// Validate value (must be non-negative)
|
|
97
|
+
if (BigInt(params.value) < BigInt(0)) {
|
|
98
|
+
throw new Error("Negative value not allowed");
|
|
99
|
+
}
|
|
100
|
+
// Validate gas limit (0 means use all available gas, which is valid)
|
|
101
|
+
if (params.gasLimit < 0) {
|
|
102
|
+
throw new Error("Invalid gas limit");
|
|
103
|
+
}
|
|
104
|
+
// Validate operation type (must be valid hex)
|
|
105
|
+
if (!(/^0x[0-9a-f]{64}$/i.test(params.operationType))) {
|
|
106
|
+
throw new Error("Invalid operation type format");
|
|
107
|
+
}
|
|
108
|
+
// Validate execution selector (must be valid bytes4)
|
|
109
|
+
if (!(/^0x[0-9a-f]{8}$/i.test(params.executionSelector))) {
|
|
110
|
+
throw new Error("Invalid execution selector format");
|
|
111
|
+
}
|
|
112
|
+
// Validate execution params (must be valid hex)
|
|
113
|
+
if (!params.executionParams || !(/^0x[0-9a-f]*$/i.test(params.executionParams))) {
|
|
114
|
+
throw new Error("Missing or invalid parameters");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* @notice Validates if a string is a valid hex value
|
|
119
|
+
* @param value The hex string to validate
|
|
120
|
+
* @param exactBytes Optional parameter for exact byte length
|
|
121
|
+
* @returns boolean indicating if the hex string is valid
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
isValidHex(value, exactBytes) {
|
|
125
|
+
if (!value || typeof value !== 'string' || !value.startsWith('0x')) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
const hexDigits = value.slice(2);
|
|
129
|
+
if (hexDigits.length % 2 !== 0) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
if (exactBytes !== undefined && hexDigits.length !== exactBytes * 2) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
return /^[0-9a-f]*$/i.test(hexDigits);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @notice Validates payment details
|
|
139
|
+
* @param payment The payment details to validate
|
|
140
|
+
* @throws Error if any validation fails
|
|
141
|
+
* @private
|
|
142
|
+
*/
|
|
143
|
+
async validatePaymentDetails(payment) {
|
|
144
|
+
// Validate recipient address if any payment is specified
|
|
145
|
+
if (BigInt(payment.nativeTokenAmount) > BigInt(0) || BigInt(payment.erc20TokenAmount) > BigInt(0)) {
|
|
146
|
+
if (!payment.recipient) {
|
|
147
|
+
throw new Error("Invalid payment recipient address");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Validate native token amount
|
|
151
|
+
if (BigInt(payment.nativeTokenAmount) < BigInt(0)) {
|
|
152
|
+
throw new Error("Negative native token amount not allowed");
|
|
153
|
+
}
|
|
154
|
+
// Validate ERC20 token details if specified
|
|
155
|
+
if (BigInt(payment.erc20TokenAmount) > BigInt(0)) {
|
|
156
|
+
if (!payment.erc20TokenAddress) {
|
|
157
|
+
throw new Error("Invalid ERC20 token address");
|
|
158
|
+
}
|
|
159
|
+
if (BigInt(payment.erc20TokenAmount) < BigInt(0)) {
|
|
160
|
+
throw new Error("Negative ERC20 token amount not allowed");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* @notice Validates if a timestamp is in the future
|
|
166
|
+
* @param timestamp The timestamp to validate
|
|
167
|
+
* @param errorMessage Custom error message
|
|
168
|
+
* @throws Error if timestamp is not in the future
|
|
169
|
+
*/
|
|
170
|
+
validateFutureTimestamp(timestamp, errorMessage = "Timestamp must be in the future") {
|
|
171
|
+
if (timestamp <= Math.floor(Date.now() / 1000)) {
|
|
172
|
+
throw new Error(errorMessage);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* @notice Validates if a period in minutes is valid
|
|
177
|
+
* @param periodInMinutes The period to validate
|
|
178
|
+
* @param errorMessage Custom error message
|
|
179
|
+
* @throws Error if period is not valid
|
|
180
|
+
*/
|
|
181
|
+
validateTimePeriod(periodInMinutes, errorMessage = "Invalid time period") {
|
|
182
|
+
if (periodInMinutes <= 0) {
|
|
183
|
+
throw new Error(errorMessage);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* @notice Validates if an address has admin owner role
|
|
188
|
+
* @dev Equivalent to onlyAdminOwner modifier in Solidity
|
|
189
|
+
* @param address The address to validate
|
|
190
|
+
* @param adminOwner The expected admin owner address
|
|
191
|
+
* @throws Error if address is not admin owner
|
|
192
|
+
*/
|
|
193
|
+
validateAdminOwner(address, adminOwner) {
|
|
194
|
+
this.validateRole(address, adminOwner, "admin owner");
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @notice Validates if an address has broadcaster role
|
|
198
|
+
* @dev Equivalent to onlyBroadcaster modifier in Solidity
|
|
199
|
+
* @param address The address to validate
|
|
200
|
+
* @param broadcaster The expected broadcaster address
|
|
201
|
+
* @throws Error if address is not broadcaster
|
|
202
|
+
*/
|
|
203
|
+
validateBroadcaster(address, broadcaster) {
|
|
204
|
+
this.validateRole(address, broadcaster, "broadcaster");
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* @notice Validates if an address has recovery role
|
|
208
|
+
* @dev Equivalent to onlyRecovery modifier in Solidity
|
|
209
|
+
* @param address The address to validate
|
|
210
|
+
* @param recovery The expected recovery address
|
|
211
|
+
* @throws Error if address is not recovery address
|
|
212
|
+
*/
|
|
213
|
+
validateRecovery(address, recovery) {
|
|
214
|
+
this.validateRole(address, recovery, "recovery owner");
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* @notice Validates if an address has a specific role
|
|
218
|
+
* @param address The address to validate
|
|
219
|
+
* @param roleAddress The expected role address
|
|
220
|
+
* @param roleName The name of the role for error messages
|
|
221
|
+
* @throws Error if address doesn't match role address
|
|
222
|
+
*/
|
|
223
|
+
validateRole(address, roleAddress, roleName) {
|
|
224
|
+
if (!address || address !== roleAddress) {
|
|
225
|
+
throw new Error(`Restricted to ${roleName}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* @notice Validates if an address has either of two roles
|
|
230
|
+
* @param address The address to validate
|
|
231
|
+
* @param role1Address First role address
|
|
232
|
+
* @param role2Address Second role address
|
|
233
|
+
* @param roleNames Names of the roles for error messages
|
|
234
|
+
* @throws Error if address doesn't match either role
|
|
235
|
+
*/
|
|
236
|
+
validateMultipleRoles(address, role1Address, role2Address, roleNames) {
|
|
237
|
+
if (!address || (address !== role1Address && address !== role2Address)) {
|
|
238
|
+
throw new Error(`Restricted to ${roleNames}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* @notice Validates native token balance
|
|
243
|
+
* @param contractAddress The contract address to check
|
|
244
|
+
* @param requiredAmount The required balance amount
|
|
245
|
+
* @throws Error if balance is insufficient
|
|
246
|
+
*/
|
|
247
|
+
async validateNativeTokenBalance(contractAddress, requiredAmount) {
|
|
248
|
+
const balance = await this.client.getBalance({ address: contractAddress });
|
|
249
|
+
if (balance < requiredAmount) {
|
|
250
|
+
throw new Error("Insufficient native token balance");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=validations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validations.js","sourceRoot":"","sources":["../../utils/validations.ts"],"names":[],"mappings":"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"}
|