@aastar/core 0.16.7
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/LICENSE +21 -0
- package/dist/abis/BLSAggregator.json +686 -0
- package/dist/abis/BLSValidator.json +42 -0
- package/dist/abis/DVTValidator.json +368 -0
- package/dist/abis/Eip7702Support.json +24 -0
- package/dist/abis/EntryPoint.json +1382 -0
- package/dist/abis/GToken.json +513 -0
- package/dist/abis/GTokenStaking.json +949 -0
- package/dist/abis/LegacyAccount.json +625 -0
- package/dist/abis/MySBT.json +1518 -0
- package/dist/abis/Paymaster.json +1143 -0
- package/dist/abis/PaymasterFactory.json +640 -0
- package/dist/abis/Registry.json +1942 -0
- package/dist/abis/ReputationSystem.json +699 -0
- package/dist/abis/SenderCreator.json +99 -0
- package/dist/abis/Simple7702Account.json +395 -0
- package/dist/abis/SimpleAccount.json +560 -0
- package/dist/abis/SimpleAccountFactory.json +111 -0
- package/dist/abis/SimpleAccountFactoryV08.json +87 -0
- package/dist/abis/SimpleAccountV08.json +557 -0
- package/dist/abis/SuperPaymaster.json +1781 -0
- package/dist/abis/UserOperationLib.json +57 -0
- package/dist/abis/abi.config.json +24 -0
- package/dist/abis/index.d.ts +1126 -0
- package/dist/abis/index.js +91 -0
- package/dist/abis/xPNTsFactory.json +718 -0
- package/dist/abis/xPNTsToken.json +1280 -0
- package/dist/actions/StateValidator.d.ts +68 -0
- package/dist/actions/StateValidator.js +187 -0
- package/dist/actions/StateValidator.test.d.ts +1 -0
- package/dist/actions/StateValidator.test.js +144 -0
- package/dist/actions/account.d.ts +55 -0
- package/dist/actions/account.js +133 -0
- package/dist/actions/account.test.d.ts +1 -0
- package/dist/actions/account.test.js +118 -0
- package/dist/actions/aggregator.d.ts +17 -0
- package/dist/actions/aggregator.js +31 -0
- package/dist/actions/aggregator.test.d.ts +1 -0
- package/dist/actions/aggregator.test.js +67 -0
- package/dist/actions/dvt.d.ts +30 -0
- package/dist/actions/dvt.js +41 -0
- package/dist/actions/dvt.test.d.ts +1 -0
- package/dist/actions/dvt.test.js +98 -0
- package/dist/actions/entryPoint.d.ts +90 -0
- package/dist/actions/entryPoint.js +211 -0
- package/dist/actions/entryPoint.test.d.ts +1 -0
- package/dist/actions/entryPoint.test.js +139 -0
- package/dist/actions/factory.d.ts +215 -0
- package/dist/actions/factory.js +442 -0
- package/dist/actions/factory.test.d.ts +1 -0
- package/dist/actions/factory.test.js +197 -0
- package/dist/actions/faucet.d.ts +48 -0
- package/dist/actions/faucet.js +337 -0
- package/dist/actions/faucet.test.d.ts +1 -0
- package/dist/actions/faucet.test.js +120 -0
- package/dist/actions/gtokenExtended.d.ts +39 -0
- package/dist/actions/gtokenExtended.js +115 -0
- package/dist/actions/gtokenExtended.test.d.ts +1 -0
- package/dist/actions/gtokenExtended.test.js +118 -0
- package/dist/actions/index.d.ts +15 -0
- package/dist/actions/index.js +17 -0
- package/dist/actions/paymasterV4.d.ts +170 -0
- package/dist/actions/paymasterV4.js +334 -0
- package/dist/actions/paymasterV4.test.d.ts +1 -0
- package/dist/actions/paymasterV4.test.js +159 -0
- package/dist/actions/registry.d.ts +246 -0
- package/dist/actions/registry.js +667 -0
- package/dist/actions/registry.test.d.ts +1 -0
- package/dist/actions/registry.test.js +360 -0
- package/dist/actions/reputation.d.ts +129 -0
- package/dist/actions/reputation.js +281 -0
- package/dist/actions/reputation.test.d.ts +1 -0
- package/dist/actions/reputation.test.js +169 -0
- package/dist/actions/sbt.d.ts +191 -0
- package/dist/actions/sbt.js +533 -0
- package/dist/actions/sbt.test.d.ts +1 -0
- package/dist/actions/sbt.test.js +256 -0
- package/dist/actions/staking.d.ts +132 -0
- package/dist/actions/staking.js +330 -0
- package/dist/actions/staking.test.d.ts +1 -0
- package/dist/actions/staking.test.js +223 -0
- package/dist/actions/superPaymaster.d.ts +237 -0
- package/dist/actions/superPaymaster.js +644 -0
- package/dist/actions/superPaymaster.test.d.ts +1 -0
- package/dist/actions/superPaymaster.test.js +287 -0
- package/dist/actions/tokens.d.ts +229 -0
- package/dist/actions/tokens.js +415 -0
- package/dist/actions/tokens.test.d.ts +1 -0
- package/dist/actions/tokens.test.js +53 -0
- package/dist/actions/validators.d.ts +194 -0
- package/dist/actions/validators.js +433 -0
- package/dist/actions/validators.test.d.ts +1 -0
- package/dist/actions/validators.test.js +215 -0
- package/dist/branding.d.ts +30 -0
- package/dist/branding.js +30 -0
- package/dist/clients/BaseClient.d.ts +25 -0
- package/dist/clients/BaseClient.js +66 -0
- package/dist/clients/types.d.ts +60 -0
- package/dist/clients/types.js +1 -0
- package/dist/clients.d.ts +5 -0
- package/dist/clients.js +11 -0
- package/dist/communities.d.ts +52 -0
- package/dist/communities.js +73 -0
- package/dist/config/ContractConfigManager.d.ts +20 -0
- package/dist/config/ContractConfigManager.js +48 -0
- package/dist/constants.d.ts +88 -0
- package/dist/constants.js +125 -0
- package/dist/contract-addresses.d.ts +110 -0
- package/dist/contract-addresses.js +99 -0
- package/dist/contracts.d.ts +424 -0
- package/dist/contracts.js +343 -0
- package/dist/contracts.test.d.ts +1 -0
- package/dist/contracts.test.js +40 -0
- package/dist/crypto/blsSigner.d.ts +64 -0
- package/dist/crypto/blsSigner.js +98 -0
- package/dist/crypto/index.d.ts +1 -0
- package/dist/crypto/index.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +21 -0
- package/dist/networks.d.ts +127 -0
- package/dist/networks.js +118 -0
- package/dist/requirementChecker.d.ts +38 -0
- package/dist/requirementChecker.js +139 -0
- package/dist/requirementChecker.test.d.ts +1 -0
- package/dist/requirementChecker.test.js +60 -0
- package/dist/roles.d.ts +204 -0
- package/dist/roles.js +211 -0
- package/dist/roles.test.d.ts +1 -0
- package/dist/roles.test.js +23 -0
- package/dist/utils/validation.d.ts +24 -0
- package/dist/utils/validation.js +56 -0
- package/dist/utils/validation.test.d.ts +1 -0
- package/dist/utils/validation.test.js +40 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +14 -0
- package/package.json +33 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Hex, type Address, type Chain } from 'viem';
|
|
2
|
+
/**
|
|
3
|
+
* Interface definitions
|
|
4
|
+
*/
|
|
5
|
+
export interface ValidationParams {
|
|
6
|
+
rpcUrl: string;
|
|
7
|
+
chain: Chain;
|
|
8
|
+
}
|
|
9
|
+
export interface RoleValidationParams extends ValidationParams {
|
|
10
|
+
registryAddress: Address;
|
|
11
|
+
roleId: Hex;
|
|
12
|
+
userAddress: Address;
|
|
13
|
+
}
|
|
14
|
+
export interface BalanceValidationParams extends ValidationParams {
|
|
15
|
+
address: Address;
|
|
16
|
+
minBalance?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TokenBalanceValidationParams extends BalanceValidationParams {
|
|
19
|
+
tokenAddress: Address;
|
|
20
|
+
}
|
|
21
|
+
export interface DeploymentValidationParams extends ValidationParams {
|
|
22
|
+
contractAddress: Address;
|
|
23
|
+
}
|
|
24
|
+
export interface ValidationResult {
|
|
25
|
+
valid: boolean;
|
|
26
|
+
message?: string;
|
|
27
|
+
data?: any;
|
|
28
|
+
}
|
|
29
|
+
export interface AccountBalance {
|
|
30
|
+
address: Address;
|
|
31
|
+
eth: bigint;
|
|
32
|
+
gToken: bigint;
|
|
33
|
+
aPNTs: bigint;
|
|
34
|
+
xPNTs: bigint;
|
|
35
|
+
}
|
|
36
|
+
export declare class StateValidator {
|
|
37
|
+
/**
|
|
38
|
+
* Create PublicClient helper
|
|
39
|
+
*/
|
|
40
|
+
private static createClient;
|
|
41
|
+
/**
|
|
42
|
+
* Batch fetch balances for multiple accounts
|
|
43
|
+
*/
|
|
44
|
+
static getAccountBalances(params: {
|
|
45
|
+
rpcUrl: string;
|
|
46
|
+
chain: Chain;
|
|
47
|
+
addresses: Address[];
|
|
48
|
+
gTokenAddress?: Address;
|
|
49
|
+
aPNTsAddress?: Address;
|
|
50
|
+
xPNTsAddress?: Address;
|
|
51
|
+
}): Promise<AccountBalance[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Role Validation
|
|
54
|
+
*/
|
|
55
|
+
static validateRole(params: RoleValidationParams): Promise<ValidationResult>;
|
|
56
|
+
/**
|
|
57
|
+
* ETH Balance Validation
|
|
58
|
+
*/
|
|
59
|
+
static validateETHBalance(params: BalanceValidationParams): Promise<ValidationResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Token Balance Validation
|
|
62
|
+
*/
|
|
63
|
+
static validateTokenBalance(params: TokenBalanceValidationParams): Promise<ValidationResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Deployment Validation
|
|
66
|
+
*/
|
|
67
|
+
static validateDeployment(params: DeploymentValidationParams): Promise<ValidationResult>;
|
|
68
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createPublicClient, http, erc20Abi, formatEther } from 'viem';
|
|
2
|
+
export class StateValidator {
|
|
3
|
+
/**
|
|
4
|
+
* Create PublicClient helper
|
|
5
|
+
*/
|
|
6
|
+
static createClient(params) {
|
|
7
|
+
return createPublicClient({
|
|
8
|
+
chain: params.chain,
|
|
9
|
+
transport: http(params.rpcUrl)
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Batch fetch balances for multiple accounts
|
|
14
|
+
*/
|
|
15
|
+
static async getAccountBalances(params) {
|
|
16
|
+
const client = this.createClient({ rpcUrl: params.rpcUrl, chain: params.chain });
|
|
17
|
+
const results = await Promise.all(params.addresses.map(async (address) => {
|
|
18
|
+
const [eth, gToken, aPNTs, xPNTs] = await Promise.all([
|
|
19
|
+
client.getBalance({ address }),
|
|
20
|
+
params.gTokenAddress
|
|
21
|
+
? client.readContract({
|
|
22
|
+
address: params.gTokenAddress,
|
|
23
|
+
abi: erc20Abi,
|
|
24
|
+
functionName: 'balanceOf',
|
|
25
|
+
args: [address]
|
|
26
|
+
})
|
|
27
|
+
: Promise.resolve(0n),
|
|
28
|
+
params.aPNTsAddress
|
|
29
|
+
? client.readContract({
|
|
30
|
+
address: params.aPNTsAddress,
|
|
31
|
+
abi: erc20Abi,
|
|
32
|
+
functionName: 'balanceOf',
|
|
33
|
+
args: [address]
|
|
34
|
+
})
|
|
35
|
+
: Promise.resolve(0n),
|
|
36
|
+
params.xPNTsAddress
|
|
37
|
+
? client.readContract({
|
|
38
|
+
address: params.xPNTsAddress,
|
|
39
|
+
abi: erc20Abi,
|
|
40
|
+
functionName: 'balanceOf',
|
|
41
|
+
args: [address]
|
|
42
|
+
})
|
|
43
|
+
: Promise.resolve(0n)
|
|
44
|
+
]);
|
|
45
|
+
return {
|
|
46
|
+
address,
|
|
47
|
+
eth,
|
|
48
|
+
gToken,
|
|
49
|
+
aPNTs,
|
|
50
|
+
xPNTs
|
|
51
|
+
};
|
|
52
|
+
}));
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Role Validation
|
|
57
|
+
*/
|
|
58
|
+
static async validateRole(params) {
|
|
59
|
+
try {
|
|
60
|
+
const client = this.createClient(params);
|
|
61
|
+
const hasRole = await client.readContract({
|
|
62
|
+
address: params.registryAddress,
|
|
63
|
+
abi: [{
|
|
64
|
+
name: 'hasRole',
|
|
65
|
+
type: 'function',
|
|
66
|
+
stateMutability: 'view',
|
|
67
|
+
inputs: [
|
|
68
|
+
{ name: 'roleId', type: 'bytes32' },
|
|
69
|
+
{ name: 'user', type: 'address' }
|
|
70
|
+
],
|
|
71
|
+
outputs: [{ name: '', type: 'bool' }]
|
|
72
|
+
}],
|
|
73
|
+
functionName: 'hasRole',
|
|
74
|
+
args: [params.roleId, params.userAddress]
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
valid: hasRole,
|
|
78
|
+
message: hasRole
|
|
79
|
+
? `✅ User ${params.userAddress} has role ${params.roleId}`
|
|
80
|
+
: `❌ User ${params.userAddress} does NOT have role ${params.roleId}`,
|
|
81
|
+
data: { hasRole }
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return {
|
|
86
|
+
valid: false,
|
|
87
|
+
message: `❌ Role validation failed: ${error.message}`,
|
|
88
|
+
data: { error }
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* ETH Balance Validation
|
|
94
|
+
*/
|
|
95
|
+
static async validateETHBalance(params) {
|
|
96
|
+
try {
|
|
97
|
+
const client = this.createClient(params);
|
|
98
|
+
const balance = await client.getBalance({ address: params.address });
|
|
99
|
+
const balanceETH = Number(formatEther(balance));
|
|
100
|
+
if (params.minBalance) {
|
|
101
|
+
const minBalanceWei = BigInt(Math.floor(parseFloat(params.minBalance) * 1e18));
|
|
102
|
+
const sufficient = balance >= minBalanceWei;
|
|
103
|
+
return {
|
|
104
|
+
valid: sufficient,
|
|
105
|
+
message: sufficient
|
|
106
|
+
? `✅ ETH balance (${balanceETH.toFixed(4)}) meets minimum (${params.minBalance})`
|
|
107
|
+
: `❌ ETH balance (${balanceETH.toFixed(4)}) below minimum (${params.minBalance})`,
|
|
108
|
+
data: { balance, balanceETH, minBalance: params.minBalance }
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
valid: true,
|
|
113
|
+
message: `ℹ️ ETH balance: ${balanceETH.toFixed(4)} ETH`,
|
|
114
|
+
data: { balance, balanceETH }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
return {
|
|
119
|
+
valid: false,
|
|
120
|
+
message: `❌ ETH balance validation failed: ${error.message}`,
|
|
121
|
+
data: { error }
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Token Balance Validation
|
|
127
|
+
*/
|
|
128
|
+
static async validateTokenBalance(params) {
|
|
129
|
+
try {
|
|
130
|
+
const client = this.createClient(params);
|
|
131
|
+
const balance = await client.readContract({
|
|
132
|
+
address: params.tokenAddress,
|
|
133
|
+
abi: erc20Abi,
|
|
134
|
+
functionName: 'balanceOf',
|
|
135
|
+
args: [params.address]
|
|
136
|
+
});
|
|
137
|
+
const balanceToken = Number(formatEther(balance));
|
|
138
|
+
if (params.minBalance) {
|
|
139
|
+
const minBalanceWei = BigInt(Math.floor(parseFloat(params.minBalance) * 1e18));
|
|
140
|
+
const sufficient = balance >= minBalanceWei;
|
|
141
|
+
return {
|
|
142
|
+
valid: sufficient,
|
|
143
|
+
message: sufficient
|
|
144
|
+
? `✅ Token balance (${balanceToken.toFixed(4)}) meets minimum (${params.minBalance})`
|
|
145
|
+
: `❌ Token balance (${balanceToken.toFixed(4)}) below minimum (${params.minBalance})`,
|
|
146
|
+
data: { balance, balanceToken, minBalance: params.minBalance }
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
valid: true,
|
|
151
|
+
message: `ℹ️ Token balance: ${balanceToken.toFixed(4)}`,
|
|
152
|
+
data: { balance, balanceToken }
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return {
|
|
157
|
+
valid: false,
|
|
158
|
+
message: `❌ Token balance validation failed: ${error.message}`,
|
|
159
|
+
data: { error }
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Deployment Validation
|
|
165
|
+
*/
|
|
166
|
+
static async validateDeployment(params) {
|
|
167
|
+
try {
|
|
168
|
+
const client = this.createClient(params);
|
|
169
|
+
const code = await client.getBytecode({ address: params.contractAddress });
|
|
170
|
+
const isDeployed = code !== undefined && code !== '0x';
|
|
171
|
+
return {
|
|
172
|
+
valid: isDeployed,
|
|
173
|
+
message: isDeployed
|
|
174
|
+
? `✅ Contract deployed at ${params.contractAddress}`
|
|
175
|
+
: `❌ No contract found at ${params.contractAddress}`,
|
|
176
|
+
data: { code, isDeployed }
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
valid: false,
|
|
182
|
+
message: `❌ Deployment validation failed: ${error.message}`,
|
|
183
|
+
data: { error }
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { parseEther } from 'viem';
|
|
3
|
+
import { StateValidator } from './StateValidator.js';
|
|
4
|
+
import { sepolia } from 'viem/chains';
|
|
5
|
+
// Mock viem
|
|
6
|
+
vi.mock('viem', async () => {
|
|
7
|
+
const actual = await vi.importActual('viem');
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
createPublicClient: vi.fn(),
|
|
11
|
+
http: vi.fn(),
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
import { createPublicClient } from 'viem';
|
|
15
|
+
describe('StateValidator', () => {
|
|
16
|
+
let mockClient;
|
|
17
|
+
const MOCK_USER = '0x1234567890123456789012345678901234567890';
|
|
18
|
+
const MOCK_RPC = 'https://mock.rpc';
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
mockClient = {
|
|
22
|
+
getBalance: vi.fn(),
|
|
23
|
+
readContract: vi.fn(),
|
|
24
|
+
getBytecode: vi.fn(),
|
|
25
|
+
};
|
|
26
|
+
createPublicClient.mockReturnValue(mockClient);
|
|
27
|
+
});
|
|
28
|
+
describe('getAccountBalances', () => {
|
|
29
|
+
it('should fetch balances for multiple accounts', async () => {
|
|
30
|
+
mockClient.getBalance.mockResolvedValue(parseEther('1.5'));
|
|
31
|
+
mockClient.readContract.mockResolvedValue(parseEther('1000'));
|
|
32
|
+
const balances = await StateValidator.getAccountBalances({
|
|
33
|
+
rpcUrl: MOCK_RPC,
|
|
34
|
+
chain: sepolia,
|
|
35
|
+
addresses: [MOCK_USER],
|
|
36
|
+
gTokenAddress: '0xGTOKEN',
|
|
37
|
+
aPNTsAddress: '0xAPNTS',
|
|
38
|
+
xPNTsAddress: '0xXPNTS'
|
|
39
|
+
});
|
|
40
|
+
expect(balances).toHaveLength(1);
|
|
41
|
+
expect(balances[0].eth).toBe(parseEther('1.5'));
|
|
42
|
+
expect(balances[0].gToken).toBe(parseEther('1000'));
|
|
43
|
+
expect(mockClient.getBalance).toHaveBeenCalledWith({ address: MOCK_USER });
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('validateRole', () => {
|
|
47
|
+
it('should return valid if user has role', async () => {
|
|
48
|
+
mockClient.readContract.mockResolvedValue(true);
|
|
49
|
+
const result = await StateValidator.validateRole({
|
|
50
|
+
rpcUrl: MOCK_RPC,
|
|
51
|
+
chain: sepolia,
|
|
52
|
+
registryAddress: '0xREGISTRY',
|
|
53
|
+
roleId: '0xROLE',
|
|
54
|
+
userAddress: MOCK_USER
|
|
55
|
+
});
|
|
56
|
+
expect(result.valid).toBe(true);
|
|
57
|
+
expect(result.message).toContain('has role');
|
|
58
|
+
});
|
|
59
|
+
it('should return invalid if user does not have role', async () => {
|
|
60
|
+
mockClient.readContract.mockResolvedValue(false);
|
|
61
|
+
const result = await StateValidator.validateRole({
|
|
62
|
+
rpcUrl: MOCK_RPC,
|
|
63
|
+
chain: sepolia,
|
|
64
|
+
registryAddress: '0xREGISTRY',
|
|
65
|
+
roleId: '0xROLE',
|
|
66
|
+
userAddress: MOCK_USER
|
|
67
|
+
});
|
|
68
|
+
expect(result.valid).toBe(false);
|
|
69
|
+
expect(result.message).toContain('does NOT have role');
|
|
70
|
+
});
|
|
71
|
+
it('should handle errors', async () => {
|
|
72
|
+
mockClient.readContract.mockRejectedValue(new Error('Contract error'));
|
|
73
|
+
const result = await StateValidator.validateRole({
|
|
74
|
+
rpcUrl: MOCK_RPC,
|
|
75
|
+
chain: sepolia,
|
|
76
|
+
registryAddress: '0xREGISTRY',
|
|
77
|
+
roleId: '0xROLE',
|
|
78
|
+
userAddress: MOCK_USER
|
|
79
|
+
});
|
|
80
|
+
expect(result.valid).toBe(false);
|
|
81
|
+
expect(result.message).toContain('validation failed');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe('validateETHBalance', () => {
|
|
85
|
+
it('should validate sufficient balance', async () => {
|
|
86
|
+
mockClient.getBalance.mockResolvedValue(parseEther('1.0'));
|
|
87
|
+
const result = await StateValidator.validateETHBalance({
|
|
88
|
+
rpcUrl: MOCK_RPC,
|
|
89
|
+
chain: sepolia,
|
|
90
|
+
address: MOCK_USER,
|
|
91
|
+
minBalance: '0.5'
|
|
92
|
+
});
|
|
93
|
+
expect(result.valid).toBe(true);
|
|
94
|
+
expect(result.message).toContain('meets minimum');
|
|
95
|
+
});
|
|
96
|
+
it('should validate insufficient balance', async () => {
|
|
97
|
+
mockClient.getBalance.mockResolvedValue(parseEther('0.1'));
|
|
98
|
+
const result = await StateValidator.validateETHBalance({
|
|
99
|
+
rpcUrl: MOCK_RPC,
|
|
100
|
+
chain: sepolia,
|
|
101
|
+
address: MOCK_USER,
|
|
102
|
+
minBalance: '0.5'
|
|
103
|
+
});
|
|
104
|
+
expect(result.valid).toBe(false);
|
|
105
|
+
expect(result.message).toContain('below minimum');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('validateTokenBalance', () => {
|
|
109
|
+
it('should validate token balance', async () => {
|
|
110
|
+
mockClient.readContract.mockResolvedValue(parseEther('100'));
|
|
111
|
+
const result = await StateValidator.validateTokenBalance({
|
|
112
|
+
rpcUrl: MOCK_RPC,
|
|
113
|
+
chain: sepolia,
|
|
114
|
+
address: MOCK_USER,
|
|
115
|
+
tokenAddress: '0xTOKEN',
|
|
116
|
+
minBalance: '50'
|
|
117
|
+
});
|
|
118
|
+
expect(result.valid).toBe(true);
|
|
119
|
+
expect(result.message).toContain('meets minimum');
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe('validateDeployment', () => {
|
|
123
|
+
it('should return valid if contract is deployed', async () => {
|
|
124
|
+
mockClient.getBytecode.mockResolvedValue('0x1234');
|
|
125
|
+
const result = await StateValidator.validateDeployment({
|
|
126
|
+
rpcUrl: MOCK_RPC,
|
|
127
|
+
chain: sepolia,
|
|
128
|
+
contractAddress: '0xCONTRACT'
|
|
129
|
+
});
|
|
130
|
+
expect(result.valid).toBe(true);
|
|
131
|
+
expect(result.message).toContain('deployed at');
|
|
132
|
+
});
|
|
133
|
+
it('should return invalid if contract is not deployed', async () => {
|
|
134
|
+
mockClient.getBytecode.mockResolvedValue('0x');
|
|
135
|
+
const result = await StateValidator.validateDeployment({
|
|
136
|
+
rpcUrl: MOCK_RPC,
|
|
137
|
+
chain: sepolia,
|
|
138
|
+
contractAddress: '0xCONTRACT'
|
|
139
|
+
});
|
|
140
|
+
expect(result.valid).toBe(false);
|
|
141
|
+
expect(result.message).toContain('No contract found');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Address, type PublicClient, type WalletClient, type Hex, type Hash, type Account } from 'viem';
|
|
2
|
+
export type AccountActions = {
|
|
3
|
+
execute: (args: {
|
|
4
|
+
dest: Address;
|
|
5
|
+
value: bigint;
|
|
6
|
+
func: Hex;
|
|
7
|
+
account?: Account | Address;
|
|
8
|
+
}) => Promise<Hash>;
|
|
9
|
+
executeBatch: (args: {
|
|
10
|
+
dest: Address[];
|
|
11
|
+
value: bigint[];
|
|
12
|
+
func: Hex[];
|
|
13
|
+
account?: Account | Address;
|
|
14
|
+
}) => Promise<Hash>;
|
|
15
|
+
getNonce: () => Promise<bigint>;
|
|
16
|
+
entryPoint: () => Promise<Address>;
|
|
17
|
+
addDeposit: (args: {
|
|
18
|
+
account?: Account | Address;
|
|
19
|
+
}) => Promise<Hash>;
|
|
20
|
+
withdrawDepositTo: (args: {
|
|
21
|
+
withdrawAddress: Address;
|
|
22
|
+
amount: bigint;
|
|
23
|
+
account?: Account | Address;
|
|
24
|
+
}) => Promise<Hash>;
|
|
25
|
+
getDeposit: () => Promise<bigint>;
|
|
26
|
+
owner: () => Promise<Address>;
|
|
27
|
+
initialize: (args: {
|
|
28
|
+
owner: Address;
|
|
29
|
+
account?: Account | Address;
|
|
30
|
+
}) => Promise<Hash>;
|
|
31
|
+
upgradeToAndCall: (args: {
|
|
32
|
+
newImplementation: Address;
|
|
33
|
+
data: Hex;
|
|
34
|
+
account?: Account | Address;
|
|
35
|
+
}) => Promise<Hash>;
|
|
36
|
+
proxiableUUID: () => Promise<Hex>;
|
|
37
|
+
supportsInterface: (args: {
|
|
38
|
+
interfaceId: Hex;
|
|
39
|
+
}) => Promise<boolean>;
|
|
40
|
+
UPGRADE_INTERFACE_VERSION: () => Promise<string>;
|
|
41
|
+
};
|
|
42
|
+
export type AccountFactoryActions = {
|
|
43
|
+
createAccount: (args: {
|
|
44
|
+
owner: Address;
|
|
45
|
+
salt: bigint;
|
|
46
|
+
account?: Account | Address;
|
|
47
|
+
}) => Promise<Hash>;
|
|
48
|
+
getAddress: (args: {
|
|
49
|
+
owner: Address;
|
|
50
|
+
salt: bigint;
|
|
51
|
+
}) => Promise<Address>;
|
|
52
|
+
accountImplementation: () => Promise<Address>;
|
|
53
|
+
};
|
|
54
|
+
export declare const accountActions: (address: Address) => (client: PublicClient | WalletClient) => AccountActions;
|
|
55
|
+
export declare const accountFactoryActions: (address: Address) => (client: PublicClient | WalletClient) => AccountFactoryActions;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { SimpleAccountABI, SimpleAccountFactoryABI } from '../abis/index.js';
|
|
2
|
+
export const accountActions = (address) => (client) => ({
|
|
3
|
+
async execute({ dest, value, func, account }) {
|
|
4
|
+
return client.writeContract({
|
|
5
|
+
address,
|
|
6
|
+
abi: SimpleAccountABI,
|
|
7
|
+
functionName: 'execute',
|
|
8
|
+
args: [dest, value, func],
|
|
9
|
+
account: account,
|
|
10
|
+
chain: client.chain
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
async executeBatch({ dest, value, func, account }) {
|
|
14
|
+
// Zip arguments into Call[] struct format
|
|
15
|
+
const calls = dest.map((t, i) => ({
|
|
16
|
+
target: t,
|
|
17
|
+
value: value[i],
|
|
18
|
+
data: func[i]
|
|
19
|
+
}));
|
|
20
|
+
return client.writeContract({
|
|
21
|
+
address,
|
|
22
|
+
abi: SimpleAccountABI,
|
|
23
|
+
functionName: 'executeBatch',
|
|
24
|
+
args: [calls],
|
|
25
|
+
account: account,
|
|
26
|
+
chain: client.chain
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
async getNonce() {
|
|
30
|
+
return client.readContract({
|
|
31
|
+
address,
|
|
32
|
+
abi: SimpleAccountABI,
|
|
33
|
+
functionName: 'getNonce',
|
|
34
|
+
args: []
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
async entryPoint() {
|
|
38
|
+
return client.readContract({
|
|
39
|
+
address,
|
|
40
|
+
abi: SimpleAccountABI,
|
|
41
|
+
functionName: 'entryPoint',
|
|
42
|
+
args: []
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
async addDeposit({ account }) {
|
|
46
|
+
return client.writeContract({
|
|
47
|
+
address,
|
|
48
|
+
abi: SimpleAccountABI,
|
|
49
|
+
functionName: 'addDeposit',
|
|
50
|
+
args: [],
|
|
51
|
+
account: account,
|
|
52
|
+
chain: client.chain
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
async withdrawDepositTo({ withdrawAddress, amount, account }) {
|
|
56
|
+
return client.writeContract({
|
|
57
|
+
address,
|
|
58
|
+
abi: SimpleAccountABI,
|
|
59
|
+
functionName: 'withdrawDepositTo',
|
|
60
|
+
args: [withdrawAddress, amount],
|
|
61
|
+
account: account,
|
|
62
|
+
chain: client.chain
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
async getDeposit() {
|
|
66
|
+
return client.readContract({
|
|
67
|
+
address,
|
|
68
|
+
abi: SimpleAccountABI,
|
|
69
|
+
functionName: 'getDeposit',
|
|
70
|
+
args: []
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
async owner() {
|
|
74
|
+
return client.readContract({
|
|
75
|
+
address,
|
|
76
|
+
abi: SimpleAccountABI,
|
|
77
|
+
functionName: 'owner',
|
|
78
|
+
args: []
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
async initialize({ owner, account }) {
|
|
82
|
+
return client.writeContract({
|
|
83
|
+
address,
|
|
84
|
+
abi: SimpleAccountABI,
|
|
85
|
+
functionName: 'initialize',
|
|
86
|
+
args: [owner],
|
|
87
|
+
account: account,
|
|
88
|
+
chain: client.chain
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
async upgradeToAndCall({ newImplementation, data, account }) {
|
|
92
|
+
return client.writeContract({
|
|
93
|
+
address,
|
|
94
|
+
abi: SimpleAccountABI,
|
|
95
|
+
functionName: 'upgradeToAndCall',
|
|
96
|
+
args: [newImplementation, data],
|
|
97
|
+
account: account,
|
|
98
|
+
chain: client.chain
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
async proxiableUUID() {
|
|
102
|
+
return client.readContract({ address, abi: SimpleAccountABI, functionName: 'proxiableUUID', args: [] });
|
|
103
|
+
},
|
|
104
|
+
async supportsInterface({ interfaceId }) {
|
|
105
|
+
return client.readContract({ address, abi: SimpleAccountABI, functionName: 'supportsInterface', args: [interfaceId] });
|
|
106
|
+
},
|
|
107
|
+
async UPGRADE_INTERFACE_VERSION() {
|
|
108
|
+
return client.readContract({ address, abi: SimpleAccountABI, functionName: 'UPGRADE_INTERFACE_VERSION', args: [] });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
export const accountFactoryActions = (address) => (client) => ({
|
|
112
|
+
async createAccount({ owner, salt, account }) {
|
|
113
|
+
return client.writeContract({
|
|
114
|
+
address,
|
|
115
|
+
abi: SimpleAccountFactoryABI,
|
|
116
|
+
functionName: 'createAccount',
|
|
117
|
+
args: [owner, salt],
|
|
118
|
+
account: account,
|
|
119
|
+
chain: client.chain
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
async getAddress({ owner, salt }) {
|
|
123
|
+
return client.readContract({
|
|
124
|
+
address,
|
|
125
|
+
abi: SimpleAccountFactoryABI,
|
|
126
|
+
functionName: 'getAddress',
|
|
127
|
+
args: [owner, salt]
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
async accountImplementation() {
|
|
131
|
+
return client.readContract({ address, abi: SimpleAccountFactoryABI, functionName: 'accountImplementation', args: [] });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|