@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,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blockchain Network Configuration
|
|
3
|
+
*/
|
|
4
|
+
export declare const NETWORKS: {
|
|
5
|
+
readonly sepolia: {
|
|
6
|
+
readonly chainId: 11155111;
|
|
7
|
+
readonly name: "Sepolia";
|
|
8
|
+
readonly rpcUrl: "https://rpc.sepolia.org";
|
|
9
|
+
readonly blockExplorer: "https://sepolia.etherscan.io";
|
|
10
|
+
readonly nativeCurrency: {
|
|
11
|
+
readonly name: "Sepolia ETH";
|
|
12
|
+
readonly symbol: "ETH";
|
|
13
|
+
readonly decimals: 18;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
readonly anvil: {
|
|
17
|
+
readonly chainId: 31337;
|
|
18
|
+
readonly name: "Anvil";
|
|
19
|
+
readonly rpcUrl: "http://127.0.0.1:8545";
|
|
20
|
+
readonly blockExplorer: "";
|
|
21
|
+
readonly nativeCurrency: {
|
|
22
|
+
readonly name: "ETH";
|
|
23
|
+
readonly symbol: "ETH";
|
|
24
|
+
readonly decimals: 18;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type SupportedNetwork = keyof typeof NETWORKS;
|
|
29
|
+
/**
|
|
30
|
+
* Get network configuration
|
|
31
|
+
*
|
|
32
|
+
* @param network - Network name
|
|
33
|
+
* @returns Network configuration
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const network = getNetwork('sepolia');
|
|
38
|
+
* console.log(network.chainId); // 11155111
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function getNetwork(network: SupportedNetwork): {
|
|
42
|
+
readonly chainId: 11155111;
|
|
43
|
+
readonly name: "Sepolia";
|
|
44
|
+
readonly rpcUrl: "https://rpc.sepolia.org";
|
|
45
|
+
readonly blockExplorer: "https://sepolia.etherscan.io";
|
|
46
|
+
readonly nativeCurrency: {
|
|
47
|
+
readonly name: "Sepolia ETH";
|
|
48
|
+
readonly symbol: "ETH";
|
|
49
|
+
readonly decimals: 18;
|
|
50
|
+
};
|
|
51
|
+
} | {
|
|
52
|
+
readonly chainId: 31337;
|
|
53
|
+
readonly name: "Anvil";
|
|
54
|
+
readonly rpcUrl: "http://127.0.0.1:8545";
|
|
55
|
+
readonly blockExplorer: "";
|
|
56
|
+
readonly nativeCurrency: {
|
|
57
|
+
readonly name: "ETH";
|
|
58
|
+
readonly symbol: "ETH";
|
|
59
|
+
readonly decimals: 18;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Get RPC URL for a network
|
|
64
|
+
*
|
|
65
|
+
* @param network - Network name
|
|
66
|
+
* @returns Public RPC URL
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const rpcUrl = getRpcUrl('sepolia');
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function getRpcUrl(network: SupportedNetwork): "https://rpc.sepolia.org" | "http://127.0.0.1:8545";
|
|
74
|
+
/**
|
|
75
|
+
* Get block explorer URL
|
|
76
|
+
*
|
|
77
|
+
* @param network - Network name
|
|
78
|
+
* @returns Block explorer base URL
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const explorer = getBlockExplorer('sepolia');
|
|
83
|
+
* // 'https://sepolia.etherscan.io'
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare function getBlockExplorer(network: SupportedNetwork): "" | "https://sepolia.etherscan.io";
|
|
87
|
+
/**
|
|
88
|
+
* Get transaction URL on block explorer
|
|
89
|
+
*
|
|
90
|
+
* @param network - Network name
|
|
91
|
+
* @param txHash - Transaction hash
|
|
92
|
+
* @returns Full transaction URL
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* const url = getTxUrl('sepolia', '0x123...');
|
|
97
|
+
* // 'https://sepolia.etherscan.io/tx/0x123...'
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function getTxUrl(network: SupportedNetwork, txHash: string): string;
|
|
101
|
+
/**
|
|
102
|
+
* Get address URL on block explorer
|
|
103
|
+
*
|
|
104
|
+
* @param network - Network name
|
|
105
|
+
* @param address - Contract or wallet address
|
|
106
|
+
* @returns Full address URL
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const url = getAddressUrl('sepolia', '0xabc...');
|
|
111
|
+
* // 'https://sepolia.etherscan.io/address/0xabc...'
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function getAddressUrl(network: SupportedNetwork, address: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Get chain ID for a network
|
|
117
|
+
*
|
|
118
|
+
* @param network - Network name
|
|
119
|
+
* @returns Chain ID number
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const chainId = getChainId('sepolia');
|
|
124
|
+
* // 11155111
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export declare function getChainId(network: SupportedNetwork): number;
|
package/dist/networks.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blockchain Network Configuration
|
|
3
|
+
*/
|
|
4
|
+
export const NETWORKS = {
|
|
5
|
+
sepolia: {
|
|
6
|
+
chainId: 11155111,
|
|
7
|
+
name: 'Sepolia',
|
|
8
|
+
rpcUrl: 'https://rpc.sepolia.org',
|
|
9
|
+
blockExplorer: 'https://sepolia.etherscan.io',
|
|
10
|
+
nativeCurrency: {
|
|
11
|
+
name: 'Sepolia ETH',
|
|
12
|
+
symbol: 'ETH',
|
|
13
|
+
decimals: 18,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
anvil: {
|
|
17
|
+
chainId: 31337,
|
|
18
|
+
name: 'Anvil',
|
|
19
|
+
rpcUrl: 'http://127.0.0.1:8545',
|
|
20
|
+
blockExplorer: '',
|
|
21
|
+
nativeCurrency: {
|
|
22
|
+
name: 'ETH',
|
|
23
|
+
symbol: 'ETH',
|
|
24
|
+
decimals: 18,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Get network configuration
|
|
30
|
+
*
|
|
31
|
+
* @param network - Network name
|
|
32
|
+
* @returns Network configuration
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const network = getNetwork('sepolia');
|
|
37
|
+
* console.log(network.chainId); // 11155111
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function getNetwork(network) {
|
|
41
|
+
return NETWORKS[network];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get RPC URL for a network
|
|
45
|
+
*
|
|
46
|
+
* @param network - Network name
|
|
47
|
+
* @returns Public RPC URL
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const rpcUrl = getRpcUrl('sepolia');
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function getRpcUrl(network) {
|
|
55
|
+
return NETWORKS[network].rpcUrl;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get block explorer URL
|
|
59
|
+
*
|
|
60
|
+
* @param network - Network name
|
|
61
|
+
* @returns Block explorer base URL
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const explorer = getBlockExplorer('sepolia');
|
|
66
|
+
* // 'https://sepolia.etherscan.io'
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function getBlockExplorer(network) {
|
|
70
|
+
return NETWORKS[network].blockExplorer;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get transaction URL on block explorer
|
|
74
|
+
*
|
|
75
|
+
* @param network - Network name
|
|
76
|
+
* @param txHash - Transaction hash
|
|
77
|
+
* @returns Full transaction URL
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const url = getTxUrl('sepolia', '0x123...');
|
|
82
|
+
* // 'https://sepolia.etherscan.io/tx/0x123...'
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function getTxUrl(network, txHash) {
|
|
86
|
+
return `${getBlockExplorer(network)}/tx/${txHash}`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get address URL on block explorer
|
|
90
|
+
*
|
|
91
|
+
* @param network - Network name
|
|
92
|
+
* @param address - Contract or wallet address
|
|
93
|
+
* @returns Full address URL
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const url = getAddressUrl('sepolia', '0xabc...');
|
|
98
|
+
* // 'https://sepolia.etherscan.io/address/0xabc...'
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function getAddressUrl(network, address) {
|
|
102
|
+
return `${getBlockExplorer(network)}/address/${address}`;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get chain ID for a network
|
|
106
|
+
*
|
|
107
|
+
* @param network - Network name
|
|
108
|
+
* @returns Chain ID number
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* const chainId = getChainId('sepolia');
|
|
113
|
+
* // 11155111
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export function getChainId(network) {
|
|
117
|
+
return NETWORKS[network].chainId;
|
|
118
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified requirement checker for role registration
|
|
3
|
+
* Provides centralized validation for GToken, aPNTs, MySBT, and role permissions
|
|
4
|
+
*/
|
|
5
|
+
import { Address, PublicClient } from 'viem';
|
|
6
|
+
import type { RoleRequirement } from './roles.js';
|
|
7
|
+
/**
|
|
8
|
+
* Requirement Checker Utility
|
|
9
|
+
*
|
|
10
|
+
* Centralized validation for all role requirements
|
|
11
|
+
*/
|
|
12
|
+
export declare class RequirementChecker {
|
|
13
|
+
private publicClient;
|
|
14
|
+
private addresses?;
|
|
15
|
+
constructor(publicClient: PublicClient, addresses?: {
|
|
16
|
+
registry?: Address;
|
|
17
|
+
gtoken?: Address;
|
|
18
|
+
apnts?: Address;
|
|
19
|
+
mysbt?: Address;
|
|
20
|
+
} | undefined);
|
|
21
|
+
checkRequirements(params: {
|
|
22
|
+
address: Address;
|
|
23
|
+
roleId?: `0x${string}`;
|
|
24
|
+
requiredGToken?: bigint;
|
|
25
|
+
requiredAPNTs?: bigint;
|
|
26
|
+
requireSBT?: boolean;
|
|
27
|
+
}): Promise<RoleRequirement>;
|
|
28
|
+
checkGTokenBalance(address: Address, required: bigint): Promise<{
|
|
29
|
+
balance: bigint;
|
|
30
|
+
hasEnough: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
checkAPNTsBalance(address: Address, required: bigint): Promise<{
|
|
33
|
+
balance: bigint;
|
|
34
|
+
hasEnough: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
checkHasSBT(address: Address): Promise<boolean>;
|
|
37
|
+
checkHasRole(roleId: `0x${string}`, address: Address): Promise<boolean>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified requirement checker for role registration
|
|
3
|
+
* Provides centralized validation for GToken, aPNTs, MySBT, and role permissions
|
|
4
|
+
*/
|
|
5
|
+
import { parseAbi } from 'viem';
|
|
6
|
+
const ERC20_ABI = parseAbi([
|
|
7
|
+
'function balanceOf(address) view returns (uint256)'
|
|
8
|
+
]);
|
|
9
|
+
const REGISTRY_ABI = parseAbi([
|
|
10
|
+
'function hasRole(bytes32, address) view returns (bool)',
|
|
11
|
+
'function roleStakes(bytes32, address) view returns (uint256)'
|
|
12
|
+
]);
|
|
13
|
+
const MYSBT_ABI = parseAbi([
|
|
14
|
+
'function balanceOf(address) view returns (uint256)'
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Requirement Checker Utility
|
|
18
|
+
*
|
|
19
|
+
* Centralized validation for all role requirements
|
|
20
|
+
*/
|
|
21
|
+
export class RequirementChecker {
|
|
22
|
+
publicClient;
|
|
23
|
+
addresses;
|
|
24
|
+
constructor(publicClient, addresses) {
|
|
25
|
+
this.publicClient = publicClient;
|
|
26
|
+
this.addresses = addresses;
|
|
27
|
+
}
|
|
28
|
+
async checkRequirements(params) {
|
|
29
|
+
const { address, roleId, requiredGToken = 0n, requiredAPNTs = 0n, requireSBT = false } = params;
|
|
30
|
+
const missingRequirements = [];
|
|
31
|
+
let hasRole = false;
|
|
32
|
+
if (roleId) {
|
|
33
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
34
|
+
hasRole = await this.publicClient.readContract({
|
|
35
|
+
address: this.addresses?.registry || CORE_ADDRESSES.registry,
|
|
36
|
+
abi: REGISTRY_ABI,
|
|
37
|
+
functionName: 'hasRole',
|
|
38
|
+
args: [roleId, address]
|
|
39
|
+
});
|
|
40
|
+
if (!hasRole && params.roleId) {
|
|
41
|
+
missingRequirements.push(`Does not have required role`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let hasEnoughGToken = true;
|
|
45
|
+
if (requiredGToken > 0n) {
|
|
46
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
47
|
+
const gtokenBalance = await this.publicClient.readContract({
|
|
48
|
+
address: this.addresses?.gtoken || CORE_ADDRESSES.gToken,
|
|
49
|
+
abi: ERC20_ABI,
|
|
50
|
+
functionName: 'balanceOf',
|
|
51
|
+
args: [address]
|
|
52
|
+
});
|
|
53
|
+
hasEnoughGToken = gtokenBalance >= requiredGToken;
|
|
54
|
+
if (!hasEnoughGToken) {
|
|
55
|
+
missingRequirements.push(`Need ${requiredGToken.toString()} GToken, have ${gtokenBalance.toString()}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
let hasEnoughAPNTs = true;
|
|
59
|
+
if (requiredAPNTs > 0n) {
|
|
60
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
61
|
+
const apntsBalance = await this.publicClient.readContract({
|
|
62
|
+
address: this.addresses?.apnts || CORE_ADDRESSES.aPNTs,
|
|
63
|
+
abi: ERC20_ABI,
|
|
64
|
+
functionName: 'balanceOf',
|
|
65
|
+
args: [address]
|
|
66
|
+
});
|
|
67
|
+
hasEnoughAPNTs = apntsBalance >= requiredAPNTs;
|
|
68
|
+
if (!hasEnoughAPNTs) {
|
|
69
|
+
missingRequirements.push(`Need ${requiredAPNTs.toString()} aPNTs, have ${apntsBalance.toString()}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
let hasSBT = false;
|
|
73
|
+
if (requireSBT) {
|
|
74
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
75
|
+
const sbtBalance = await this.publicClient.readContract({
|
|
76
|
+
address: this.addresses?.mysbt || CORE_ADDRESSES.mySBT,
|
|
77
|
+
abi: MYSBT_ABI,
|
|
78
|
+
functionName: 'balanceOf',
|
|
79
|
+
args: [address]
|
|
80
|
+
});
|
|
81
|
+
hasSBT = sbtBalance > 0n;
|
|
82
|
+
if (!hasSBT) {
|
|
83
|
+
missingRequirements.push('Must hold at least one MySBT');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
hasRole,
|
|
88
|
+
hasEnoughGToken,
|
|
89
|
+
hasEnoughAPNTs,
|
|
90
|
+
hasSBT,
|
|
91
|
+
missingRequirements
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
async checkGTokenBalance(address, required) {
|
|
95
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
96
|
+
const balance = await this.publicClient.readContract({
|
|
97
|
+
address: this.addresses?.gtoken || CORE_ADDRESSES.gToken,
|
|
98
|
+
abi: ERC20_ABI,
|
|
99
|
+
functionName: 'balanceOf',
|
|
100
|
+
args: [address]
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
balance,
|
|
104
|
+
hasEnough: balance >= required
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async checkAPNTsBalance(address, required) {
|
|
108
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
109
|
+
const balance = await this.publicClient.readContract({
|
|
110
|
+
address: this.addresses?.apnts || CORE_ADDRESSES.aPNTs,
|
|
111
|
+
abi: ERC20_ABI,
|
|
112
|
+
functionName: 'balanceOf',
|
|
113
|
+
args: [address]
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
balance,
|
|
117
|
+
hasEnough: balance >= required
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async checkHasSBT(address) {
|
|
121
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
122
|
+
const balance = await this.publicClient.readContract({
|
|
123
|
+
address: this.addresses?.mysbt || CORE_ADDRESSES.mySBT,
|
|
124
|
+
abi: MYSBT_ABI,
|
|
125
|
+
functionName: 'balanceOf',
|
|
126
|
+
args: [address]
|
|
127
|
+
});
|
|
128
|
+
return balance > 0n;
|
|
129
|
+
}
|
|
130
|
+
async checkHasRole(roleId, address) {
|
|
131
|
+
const { CORE_ADDRESSES } = await import('./contract-addresses.js');
|
|
132
|
+
return await this.publicClient.readContract({
|
|
133
|
+
address: this.addresses?.registry || CORE_ADDRESSES.registry,
|
|
134
|
+
abi: REGISTRY_ABI,
|
|
135
|
+
functionName: 'hasRole',
|
|
136
|
+
args: [roleId, address]
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { RequirementChecker } from './requirementChecker.js';
|
|
3
|
+
describe('RequirementChecker', () => {
|
|
4
|
+
const MOCK_ADDR = '0x1111111111111111111111111111111111111111';
|
|
5
|
+
let mockPublicClient;
|
|
6
|
+
let checker;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
mockPublicClient = {
|
|
9
|
+
readContract: vi.fn(),
|
|
10
|
+
};
|
|
11
|
+
checker = new RequirementChecker(mockPublicClient);
|
|
12
|
+
});
|
|
13
|
+
it('should check full requirements successfully', async () => {
|
|
14
|
+
mockPublicClient.readContract
|
|
15
|
+
.mockResolvedValueOnce(true) // hasRole
|
|
16
|
+
.mockResolvedValueOnce(1000n) // GToken balance
|
|
17
|
+
.mockResolvedValueOnce(500n) // aPNTs balance
|
|
18
|
+
.mockResolvedValueOnce(1n); // SBT balance
|
|
19
|
+
const result = await checker.checkRequirements({
|
|
20
|
+
address: MOCK_ADDR,
|
|
21
|
+
roleId: '0x1',
|
|
22
|
+
requiredGToken: 500n,
|
|
23
|
+
requiredAPNTs: 200n,
|
|
24
|
+
requireSBT: true
|
|
25
|
+
});
|
|
26
|
+
expect(result.hasRole).toBe(true);
|
|
27
|
+
expect(result.hasEnoughGToken).toBe(true);
|
|
28
|
+
expect(result.hasEnoughAPNTs).toBe(true);
|
|
29
|
+
expect(result.hasSBT).toBe(true);
|
|
30
|
+
expect(result.missingRequirements.length).toBe(0);
|
|
31
|
+
});
|
|
32
|
+
it('should identify missing requirements', async () => {
|
|
33
|
+
mockPublicClient.readContract
|
|
34
|
+
.mockResolvedValueOnce(false) // hasRole
|
|
35
|
+
.mockResolvedValueOnce(10n) // GToken balance
|
|
36
|
+
.mockResolvedValueOnce(0n) // aPNTs balance
|
|
37
|
+
.mockResolvedValueOnce(0n); // SBT balance
|
|
38
|
+
const result = await checker.checkRequirements({
|
|
39
|
+
address: MOCK_ADDR,
|
|
40
|
+
roleId: '0x1',
|
|
41
|
+
requiredGToken: 500n,
|
|
42
|
+
requiredAPNTs: 200n,
|
|
43
|
+
requireSBT: true
|
|
44
|
+
});
|
|
45
|
+
expect(result.hasRole).toBe(false);
|
|
46
|
+
expect(result.hasEnoughGToken).toBe(false);
|
|
47
|
+
expect(result.missingRequirements.length).toBe(4);
|
|
48
|
+
});
|
|
49
|
+
it('should check GToken balance shortcut', async () => {
|
|
50
|
+
mockPublicClient.readContract.mockResolvedValue(100n);
|
|
51
|
+
const result = await checker.checkGTokenBalance(MOCK_ADDR, 50n);
|
|
52
|
+
expect(result.hasEnough).toBe(true);
|
|
53
|
+
expect(result.balance).toBe(100n);
|
|
54
|
+
});
|
|
55
|
+
it('should check hasSBT shortcut', async () => {
|
|
56
|
+
mockPublicClient.readContract.mockResolvedValue(1n);
|
|
57
|
+
const hasSBT = await checker.checkHasSBT(MOCK_ADDR);
|
|
58
|
+
expect(hasSBT).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
});
|
package/dist/roles.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role constants and utilities for AAstar SDK
|
|
3
|
+
* @remarks
|
|
4
|
+
* All role hashes and configurations match exactly with Registry.sol v3.0.0
|
|
5
|
+
*
|
|
6
|
+
* **Source**: /contracts/src/core/Registry.sol
|
|
7
|
+
*/
|
|
8
|
+
import { type Hash } from 'viem';
|
|
9
|
+
/**
|
|
10
|
+
* Default Admin Role (OpenZeppelin AccessControl)
|
|
11
|
+
* @remarks
|
|
12
|
+
* - **Description**: Highest privilege, can grant/revoke all roles
|
|
13
|
+
* - **Permission**: Protocol governance only
|
|
14
|
+
* - **Source**: OpenZeppelin AccessControl DEFAULT_ADMIN_ROLE
|
|
15
|
+
*/
|
|
16
|
+
export declare const DEFAULT_ADMIN_ROLE: Hash;
|
|
17
|
+
/**
|
|
18
|
+
* Community Role
|
|
19
|
+
* @remarks
|
|
20
|
+
* - **Description**: Community administrator, can issue xPNTs, configure SBT rules
|
|
21
|
+
* - **Permission**: Community-level governance
|
|
22
|
+
* - **Requirement**: minStake: 30 GT, entryBurn: 3 GT (line 99)
|
|
23
|
+
* - **Exit Fee**: 5% (500 basis points), min 1 GT
|
|
24
|
+
* - **Lock Duration**: 30 days
|
|
25
|
+
* - **Source**: Registry.sol line 32: ROLE_COMMUNITY = keccak256("COMMUNITY")
|
|
26
|
+
*/
|
|
27
|
+
export declare const ROLE_COMMUNITY: Hash;
|
|
28
|
+
/**
|
|
29
|
+
* End User Role
|
|
30
|
+
* @remarks
|
|
31
|
+
* - **Description**: Community member, can participate and use gasless transactions
|
|
32
|
+
* - **Permission**: Basic user level
|
|
33
|
+
* - **Requirement**: minStake: 0.3 GT, entryBurn: 0.05 GT (line 100)
|
|
34
|
+
* - **Additional Requirement**: Must hold MySBT from community
|
|
35
|
+
* - **Exit Fee**: 10% (1000 basis points), min 0.05 GT
|
|
36
|
+
* - **Lock Duration**: 7 days
|
|
37
|
+
* - **Source**: Registry.sol line 33: ROLE_ENDUSER = keccak256("ENDUSER")
|
|
38
|
+
*/
|
|
39
|
+
export declare const ROLE_ENDUSER: Hash;
|
|
40
|
+
/**
|
|
41
|
+
* Paymaster AOA Role (Account Ownership Authentication)
|
|
42
|
+
* @remarks
|
|
43
|
+
* - **Description**: Basic Paymaster node operator with account-based auth
|
|
44
|
+
* - **Permission**: Infrastructure operator
|
|
45
|
+
* - **Requirement**: minStake: 30 GT, entryBurn: 3 GT (line 92)
|
|
46
|
+
* - **Exit Fee**: 10% (1000 basis points), min 1 GT
|
|
47
|
+
* - **Lock Duration**: 30 days
|
|
48
|
+
* - **Source**: Registry.sol line 34: ROLE_PAYMASTER_AOA = keccak256("PAYMASTER_AOA")
|
|
49
|
+
*/
|
|
50
|
+
export declare const ROLE_PAYMASTER_AOA: Hash;
|
|
51
|
+
/**
|
|
52
|
+
* Paymaster Super Role
|
|
53
|
+
* @remarks
|
|
54
|
+
* - **Description**: Advanced Paymaster operator, can use SuperPaymaster with aPNTs collateral
|
|
55
|
+
* - **Permission**: Infrastructure operator (higher tier)
|
|
56
|
+
* - **Requirement**: minStake: 50 GT, entryBurn: 5 GT (line 93)
|
|
57
|
+
* - **Additional Requirement**: aPNTs collateral in SuperPaymaster contract
|
|
58
|
+
* - **Exit Fee**: 10% (1000 basis points), min 2 GT
|
|
59
|
+
* - **Lock Duration**: 30 days
|
|
60
|
+
* - **Source**: Registry.sol line 35: ROLE_PAYMASTER_SUPER = keccak256("PAYMASTER_SUPER")
|
|
61
|
+
*/
|
|
62
|
+
export declare const ROLE_PAYMASTER_SUPER: Hash;
|
|
63
|
+
/**
|
|
64
|
+
* DVT Role (Distributed Validator Technology)
|
|
65
|
+
* @remarks
|
|
66
|
+
* - **Description**: DVT node operator for consensus validation
|
|
67
|
+
* - **Permission**: Infrastructure operator
|
|
68
|
+
* - **Requirement**: minStake: 30 GT, entryBurn: 3 GT (line 94)
|
|
69
|
+
* - **Exit Fee**: 10% (1000 basis points), min 1 GT
|
|
70
|
+
* - **Lock Duration**: 30 days
|
|
71
|
+
* - **Source**: Registry.sol line 36: ROLE_DVT = keccak256("DVT")
|
|
72
|
+
*/
|
|
73
|
+
export declare const ROLE_DVT: Hash;
|
|
74
|
+
/**
|
|
75
|
+
* ANODE Role (Anonymous Node)
|
|
76
|
+
* @remarks
|
|
77
|
+
* - **Description**: Anonymous infrastructure node operator
|
|
78
|
+
* - **Permission**: Infrastructure operator
|
|
79
|
+
* - **Requirement**: minStake: 20 GT, entryBurn: 2 GT (line 95)
|
|
80
|
+
* - **Exit Fee**: 10% (1000 basis points), min 1 GT
|
|
81
|
+
* - **Lock Duration**: 30 days
|
|
82
|
+
* - **Source**: Registry.sol line 37: ROLE_ANODE = keccak256("ANODE")
|
|
83
|
+
*/
|
|
84
|
+
export declare const ROLE_ANODE: Hash;
|
|
85
|
+
/**
|
|
86
|
+
* KMS Role (Key Management Service)
|
|
87
|
+
* @remarks
|
|
88
|
+
* - **Description**: KMS operator for secure key storage and management
|
|
89
|
+
* - **Permission**: Infrastructure operator (highest stake)
|
|
90
|
+
* - **Requirement**: minStake: 100 GT, entryBurn: 10 GT (line 98)
|
|
91
|
+
* - **Exit Fee**: 10% (1000 basis points), min 5 GT
|
|
92
|
+
* - **Lock Duration**: 30 days
|
|
93
|
+
* - **Source**: Registry.sol line 38: ROLE_KMS = keccak256("KMS")
|
|
94
|
+
*/
|
|
95
|
+
export declare const ROLE_KMS: Hash;
|
|
96
|
+
/**
|
|
97
|
+
* Role configuration structure (matches Registry.sol RoleConfig struct)
|
|
98
|
+
*/
|
|
99
|
+
export interface RoleConfig {
|
|
100
|
+
minStake: bigint;
|
|
101
|
+
entryBurn: bigint;
|
|
102
|
+
slashThreshold: number;
|
|
103
|
+
slashBase: number;
|
|
104
|
+
slashIncrement: number;
|
|
105
|
+
slashMax: number;
|
|
106
|
+
exitFeePercent: bigint;
|
|
107
|
+
minExitFee: bigint;
|
|
108
|
+
isActive: boolean;
|
|
109
|
+
description: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Role requirement check result
|
|
113
|
+
*/
|
|
114
|
+
export interface RoleRequirement {
|
|
115
|
+
hasRole: boolean;
|
|
116
|
+
hasEnoughGToken: boolean;
|
|
117
|
+
hasEnoughAPNTs: boolean;
|
|
118
|
+
hasSBT: boolean;
|
|
119
|
+
missingRequirements: string[];
|
|
120
|
+
}
|
|
121
|
+
export declare const ROLE_NAMES: Record<string, string>;
|
|
122
|
+
/**
|
|
123
|
+
* Get human-readable role name
|
|
124
|
+
*/
|
|
125
|
+
export declare function getRoleName(roleHash: Hash): string;
|
|
126
|
+
/**
|
|
127
|
+
* Role permission levels (for UI sorting/filtering)
|
|
128
|
+
*/
|
|
129
|
+
export declare enum RolePermissionLevel {
|
|
130
|
+
PROTOCOL = 100,// Default Admin
|
|
131
|
+
KMS = 80,// Key Management (highest stake)
|
|
132
|
+
OPERATOR = 50,// Infrastructure Operators
|
|
133
|
+
COMMUNITY = 30,// Community Admin
|
|
134
|
+
USER = 10
|
|
135
|
+
}
|
|
136
|
+
export declare const ROLE_PERMISSION_LEVELS: Record<string, RolePermissionLevel>;
|
|
137
|
+
/**
|
|
138
|
+
* Exact stake requirements from Registry.sol constructor (lines 92-100)
|
|
139
|
+
* @remarks
|
|
140
|
+
* **Warning**: These are initial values, always query contract for current configuration
|
|
141
|
+
*/
|
|
142
|
+
export declare const INITIAL_ROLE_STAKES: {
|
|
143
|
+
readonly [x: string]: {
|
|
144
|
+
readonly minStake: "30 GT";
|
|
145
|
+
readonly entryBurn: "3 GT";
|
|
146
|
+
readonly exitFeePercent: "10%";
|
|
147
|
+
readonly minExitFee: "1 GT";
|
|
148
|
+
readonly lockDuration: "30 days";
|
|
149
|
+
readonly line: 92;
|
|
150
|
+
readonly additionalRequirement?: undefined;
|
|
151
|
+
} | {
|
|
152
|
+
readonly minStake: "50 GT";
|
|
153
|
+
readonly entryBurn: "5 GT";
|
|
154
|
+
readonly exitFeePercent: "10%";
|
|
155
|
+
readonly minExitFee: "2 GT";
|
|
156
|
+
readonly lockDuration: "30 days";
|
|
157
|
+
readonly additionalRequirement: "aPNTs collateral in SuperPaymaster";
|
|
158
|
+
readonly line: 93;
|
|
159
|
+
} | {
|
|
160
|
+
readonly minStake: "30 GT";
|
|
161
|
+
readonly entryBurn: "3 GT";
|
|
162
|
+
readonly exitFeePercent: "10%";
|
|
163
|
+
readonly minExitFee: "1 GT";
|
|
164
|
+
readonly lockDuration: "30 days";
|
|
165
|
+
readonly line: 94;
|
|
166
|
+
readonly additionalRequirement?: undefined;
|
|
167
|
+
} | {
|
|
168
|
+
readonly minStake: "20 GT";
|
|
169
|
+
readonly entryBurn: "2 GT";
|
|
170
|
+
readonly exitFeePercent: "10%";
|
|
171
|
+
readonly minExitFee: "1 GT";
|
|
172
|
+
readonly lockDuration: "30 days";
|
|
173
|
+
readonly line: 95;
|
|
174
|
+
readonly additionalRequirement?: undefined;
|
|
175
|
+
} | {
|
|
176
|
+
readonly minStake: "100 GT";
|
|
177
|
+
readonly entryBurn: "10 GT";
|
|
178
|
+
readonly exitFeePercent: "10%";
|
|
179
|
+
readonly minExitFee: "5 GT";
|
|
180
|
+
readonly lockDuration: "30 days";
|
|
181
|
+
readonly line: 98;
|
|
182
|
+
readonly additionalRequirement?: undefined;
|
|
183
|
+
} | {
|
|
184
|
+
readonly minStake: "30 GT";
|
|
185
|
+
readonly entryBurn: "3 GT";
|
|
186
|
+
readonly exitFeePercent: "5%";
|
|
187
|
+
readonly minExitFee: "1 GT";
|
|
188
|
+
readonly lockDuration: "30 days";
|
|
189
|
+
readonly line: 99;
|
|
190
|
+
readonly additionalRequirement?: undefined;
|
|
191
|
+
} | {
|
|
192
|
+
readonly minStake: "0.3 GT";
|
|
193
|
+
readonly entryBurn: "0.05 GT";
|
|
194
|
+
readonly exitFeePercent: "10%";
|
|
195
|
+
readonly minExitFee: "0.05 GT";
|
|
196
|
+
readonly lockDuration: "7 days";
|
|
197
|
+
readonly additionalRequirement: "Must hold MySBT from community";
|
|
198
|
+
readonly line: 100;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* All defined roles array (for iteration)
|
|
203
|
+
*/
|
|
204
|
+
export declare const ALL_ROLES: readonly [`0x${string}`, `0x${string}`, `0x${string}`, `0x${string}`, `0x${string}`, `0x${string}`, `0x${string}`];
|