@aastar/sdk 0.18.0 → 0.20.2
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 +180 -21
- package/dist/UserClient-YUHCJJJL.js +6 -0
- package/dist/UserClient-YUHCJJJL.js.map +1 -0
- package/dist/account.d.ts +1 -0
- package/dist/account.js +6 -0
- package/dist/account.js.map +1 -0
- package/dist/admin.d.ts +1 -0
- package/dist/admin.js +6 -0
- package/dist/admin.js.map +1 -0
- package/dist/airaccount.d.ts +2 -0
- package/dist/airaccount.js +4501 -0
- package/dist/airaccount.js.map +1 -0
- package/dist/channel.d.ts +1 -0
- package/dist/channel.js +6 -0
- package/dist/channel.js.map +1 -0
- package/dist/chunk-4DVUM4MC.js +106 -0
- package/dist/chunk-4DVUM4MC.js.map +1 -0
- package/dist/chunk-4KRQXOTI.js +4421 -0
- package/dist/chunk-4KRQXOTI.js.map +1 -0
- package/dist/chunk-DI3E6PMI.js +426 -0
- package/dist/chunk-DI3E6PMI.js.map +1 -0
- package/dist/chunk-DSZ372PH.js +333 -0
- package/dist/chunk-DSZ372PH.js.map +1 -0
- package/dist/chunk-HVAB4TTT.js +116 -0
- package/dist/chunk-HVAB4TTT.js.map +1 -0
- package/dist/chunk-MPOMWT2J.js +1140 -0
- package/dist/chunk-MPOMWT2J.js.map +1 -0
- package/dist/chunk-NZGXB2C5.js +115 -0
- package/dist/chunk-NZGXB2C5.js.map +1 -0
- package/dist/chunk-O3Y7II3B.js +578 -0
- package/dist/chunk-O3Y7II3B.js.map +1 -0
- package/dist/chunk-OSPRJZ5T.js +113 -0
- package/dist/chunk-OSPRJZ5T.js.map +1 -0
- package/dist/chunk-PCLPYRTX.js +229 -0
- package/dist/chunk-PCLPYRTX.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +9 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-XFI3AK32.js +416 -0
- package/dist/chunk-XFI3AK32.js.map +1 -0
- package/dist/chunk-YHM77LIP.js +432 -0
- package/dist/chunk-YHM77LIP.js.map +1 -0
- package/dist/chunk-ZSSNU3UF.js +42091 -0
- package/dist/chunk-ZSSNU3UF.js.map +1 -0
- package/dist/contract-addresses-JE3X6DFY.js +4 -0
- package/dist/contract-addresses-JE3X6DFY.js.map +1 -0
- package/dist/core.d.ts +13 -0
- package/dist/core.js +5 -0
- package/dist/core.js.map +1 -0
- package/dist/dapp.d.ts +1 -0
- package/dist/dapp.js +283 -0
- package/dist/dapp.js.map +1 -0
- package/dist/dist-GHTBO7CD.js +6 -0
- package/dist/dist-GHTBO7CD.js.map +1 -0
- package/dist/enduser.d.ts +1 -0
- package/dist/enduser.js +7 -0
- package/dist/enduser.js.map +1 -0
- package/dist/identity.d.ts +1 -0
- package/dist/identity.js +6 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +601 -13
- package/dist/index.js +1639 -28
- package/dist/index.js.map +1 -0
- package/dist/index.node-55LOPHNQ.js +5 -0
- package/dist/index.node-55LOPHNQ.js.map +1 -0
- package/dist/lib-VRTYVDUO.js +1861 -0
- package/dist/lib-VRTYVDUO.js.map +1 -0
- package/dist/operator.d.ts +1 -0
- package/dist/operator.js +6 -0
- package/dist/operator.js.map +1 -0
- package/dist/paymaster.d.ts +1 -0
- package/dist/paymaster.js +6 -0
- package/dist/paymaster.js.map +1 -0
- package/dist/tokens.d.ts +1 -0
- package/dist/tokens.js +6 -0
- package/dist/tokens.js.map +1 -0
- package/dist/x402.d.ts +1 -0
- package/dist/x402.js +6 -0
- package/dist/x402.js.map +1 -0
- package/package.json +87 -18
- package/dist/clients/ExperimentClient.d.ts +0 -34
- package/dist/clients/ExperimentClient.js +0 -58
- package/dist/clients/admin.d.ts +0 -11
- package/dist/clients/admin.js +0 -20
- package/dist/clients/community.d.ts +0 -40
- package/dist/clients/community.js +0 -300
- package/dist/clients/endUser.d.ts +0 -77
- package/dist/clients/endUser.js +0 -298
- package/dist/clients/operator.d.ts +0 -66
- package/dist/clients/operator.js +0 -209
- package/dist/errors/decoder.d.ts +0 -6
- package/dist/errors/decoder.js +0 -44
- package/dist/utils/errorHandler.d.ts +0 -40
- package/dist/utils/errorHandler.js +0 -114
- package/dist/utils/funding.d.ts +0 -115
- package/dist/utils/funding.js +0 -188
- package/dist/utils/keys.d.ts +0 -61
- package/dist/utils/keys.js +0 -130
- package/dist/utils/roleData.d.ts +0 -66
- package/dist/utils/roleData.js +0 -128
- package/dist/utils/testScenarios.d.ts +0 -33
- package/dist/utils/testScenarios.js +0 -85
- package/dist/utils/userOp.d.ts +0 -89
- package/dist/utils/userOp.js +0 -231
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { type Client, type Transport, type Chain, type Account, type PublicActions, type WalletActions, type Address, type Hex, type Hash } from 'viem';
|
|
2
|
-
import { type RegistryActions, type SBTActions, type SuperPaymasterActions, type PaymasterActions } from '@aastar/core';
|
|
3
|
-
export type EndUserClient = Client<Transport, Chain, Account | undefined> & PublicActions<Transport, Chain, Account | undefined> & WalletActions<Chain, Account | undefined> & RegistryActions & SBTActions & SuperPaymasterActions & PaymasterActions & {
|
|
4
|
-
/**
|
|
5
|
-
* High-level API: Onboard user to community with automatic funding
|
|
6
|
-
*/
|
|
7
|
-
onboard: (args: {
|
|
8
|
-
community: Address;
|
|
9
|
-
roleId: Hex;
|
|
10
|
-
roleData: Hex;
|
|
11
|
-
}) => Promise<{
|
|
12
|
-
tx: Hash;
|
|
13
|
-
sbtId: bigint;
|
|
14
|
-
}>;
|
|
15
|
-
/**
|
|
16
|
-
* Orchestrates the user joining a community and activating gas credit flow:
|
|
17
|
-
* 1. Mint SBT for the community (Register ENDUSER role)
|
|
18
|
-
* 2. Verify Credit is active (Reputation check)
|
|
19
|
-
*/
|
|
20
|
-
joinAndActivate: (args: {
|
|
21
|
-
community: Address;
|
|
22
|
-
roleId: Hex;
|
|
23
|
-
roleData?: Hex;
|
|
24
|
-
}) => Promise<{
|
|
25
|
-
tx: Hash;
|
|
26
|
-
sbtId: bigint;
|
|
27
|
-
initialCredit: bigint;
|
|
28
|
-
}>;
|
|
29
|
-
/**
|
|
30
|
-
* Executes a gasless transaction via SuperPaymaster.
|
|
31
|
-
*/
|
|
32
|
-
executeGasless: (args: {
|
|
33
|
-
target: Address;
|
|
34
|
-
data: Hex;
|
|
35
|
-
value?: bigint;
|
|
36
|
-
operator: Address;
|
|
37
|
-
}) => Promise<Hash>;
|
|
38
|
-
/**
|
|
39
|
-
* Check if the user meets the requirements to join a community (stake, sbt, etc.)
|
|
40
|
-
*/
|
|
41
|
-
checkJoinRequirements: (address?: Address) => Promise<{
|
|
42
|
-
hasEnoughGToken: boolean;
|
|
43
|
-
hasSBT: boolean;
|
|
44
|
-
missingRequirements: string[];
|
|
45
|
-
}>;
|
|
46
|
-
/**
|
|
47
|
-
* Predict or deploy a SimpleAccount (ERC-4337)
|
|
48
|
-
*/
|
|
49
|
-
deploySmartAccount: (params: {
|
|
50
|
-
owner: Address;
|
|
51
|
-
salt?: bigint;
|
|
52
|
-
fundWithETH?: bigint;
|
|
53
|
-
}) => Promise<{
|
|
54
|
-
accountAddress: Address;
|
|
55
|
-
deployTxHash: Hash;
|
|
56
|
-
isDeployed: boolean;
|
|
57
|
-
}>;
|
|
58
|
-
/**
|
|
59
|
-
* Predict the address of a SimpleAccount without deploying
|
|
60
|
-
*/
|
|
61
|
-
createSmartAccount: (params: {
|
|
62
|
-
owner: Address;
|
|
63
|
-
salt?: bigint;
|
|
64
|
-
}) => Promise<{
|
|
65
|
-
accountAddress: Address;
|
|
66
|
-
initCode: Hex;
|
|
67
|
-
isDeployed: boolean;
|
|
68
|
-
}>;
|
|
69
|
-
};
|
|
70
|
-
export declare function createEndUserClient({ chain, transport, account, addresses }: {
|
|
71
|
-
chain: Chain;
|
|
72
|
-
transport: Transport;
|
|
73
|
-
account?: Account;
|
|
74
|
-
addresses?: {
|
|
75
|
-
[key: string]: Address;
|
|
76
|
-
};
|
|
77
|
-
}): EndUserClient;
|
package/dist/clients/endUser.js
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
import { createClient, publicActions, walletActions, parseAbi } from 'viem';
|
|
2
|
-
import { registryActions, sbtActions, superPaymasterActions, paymasterActions, CORE_ADDRESSES, TOKEN_ADDRESSES, TEST_ACCOUNT_ADDRESSES, RegistryABI } from '@aastar/core';
|
|
3
|
-
export function createEndUserClient({ chain, transport, account, addresses }) {
|
|
4
|
-
const client = createClient({
|
|
5
|
-
chain,
|
|
6
|
-
transport,
|
|
7
|
-
account
|
|
8
|
-
})
|
|
9
|
-
.extend(publicActions)
|
|
10
|
-
.extend(walletActions);
|
|
11
|
-
const usedAddresses = { ...CORE_ADDRESSES, ...TOKEN_ADDRESSES, ...TEST_ACCOUNT_ADDRESSES, ...addresses };
|
|
12
|
-
console.log(' SDK Debug: simpleAccountFactory from usedAddresses:', usedAddresses.simpleAccountFactory);
|
|
13
|
-
console.log(' SDK Debug: process.env.SIMPLE_ACCOUNT_FACTORY:', process.env.SIMPLE_ACCOUNT_FACTORY);
|
|
14
|
-
const actions = {
|
|
15
|
-
...registryActions(usedAddresses.registry)(client),
|
|
16
|
-
...sbtActions(usedAddresses.mySBT)(client),
|
|
17
|
-
...superPaymasterActions(usedAddresses.superPaymaster)(client),
|
|
18
|
-
...paymasterActions(usedAddresses.paymasterV4)(client)
|
|
19
|
-
};
|
|
20
|
-
return Object.assign(client, actions, {
|
|
21
|
-
async onboard({ community, roleId, roleData }) {
|
|
22
|
-
console.log('👤 Onboarding user to community...');
|
|
23
|
-
const result = await this.joinAndActivate({ community, roleId, roleData });
|
|
24
|
-
console.log(`✅ User onboarded! SBT ID: ${result.sbtId}`);
|
|
25
|
-
return { tx: result.tx, sbtId: result.sbtId };
|
|
26
|
-
},
|
|
27
|
-
async joinAndActivate({ community, roleId, roleData }) {
|
|
28
|
-
const accountToUse = account;
|
|
29
|
-
if (!accountToUse)
|
|
30
|
-
throw new Error("Account required for joinAndActivate");
|
|
31
|
-
console.log(` SDK: Joining community ${community}...`);
|
|
32
|
-
// Registry.registerRoleSelf is now idempotent (modified contract)
|
|
33
|
-
// First call: Mints SBT + grants role
|
|
34
|
-
// Subsequent calls: Adds community membership
|
|
35
|
-
// If roleData not provided, encode EndUserRoleData structure
|
|
36
|
-
let finalData;
|
|
37
|
-
if (roleData) {
|
|
38
|
-
finalData = roleData;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
// Encode EndUserRoleData: (address account, address community, string avatarURI, string ensName, uint256 stakeAmount)
|
|
42
|
-
const { encodeAbiParameters } = await import('viem');
|
|
43
|
-
finalData = encodeAbiParameters([
|
|
44
|
-
{ name: 'account', type: 'address' },
|
|
45
|
-
{ name: 'community', type: 'address' },
|
|
46
|
-
{ name: 'avatarURI', type: 'string' },
|
|
47
|
-
{ name: 'ensName', type: 'string' },
|
|
48
|
-
{ name: 'stakeAmount', type: 'uint256' }
|
|
49
|
-
], [accountToUse.address, community, '', '', 0n] // Use minimum stake (Registry will use roleConfig.minStake)
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
const regTx = await client.writeContract({
|
|
53
|
-
address: usedAddresses.registry,
|
|
54
|
-
abi: RegistryABI,
|
|
55
|
-
functionName: 'registerRoleSelf',
|
|
56
|
-
args: [roleId, finalData],
|
|
57
|
-
account: accountToUse,
|
|
58
|
-
chain
|
|
59
|
-
});
|
|
60
|
-
await client.waitForTransactionReceipt({ hash: regTx });
|
|
61
|
-
// 2. Fetch SBT ID
|
|
62
|
-
const sbtId = await actions.getUserSBT({ user: accountToUse.address });
|
|
63
|
-
console.log(` SDK: User joined. SBT ID: ${sbtId}`);
|
|
64
|
-
// 3. Fetch Initial Credit for verification
|
|
65
|
-
let credit = 0n;
|
|
66
|
-
try {
|
|
67
|
-
const factoryAbi = parseAbi(['function communityToToken(address) view returns (address)']);
|
|
68
|
-
const tokenAddress = await client.readContract({
|
|
69
|
-
address: usedAddresses.xPNTsFactory,
|
|
70
|
-
abi: factoryAbi,
|
|
71
|
-
functionName: 'communityToToken',
|
|
72
|
-
args: [community]
|
|
73
|
-
});
|
|
74
|
-
credit = await actions.getAvailableCredit({
|
|
75
|
-
user: client.aaAddress || accountToUse.address,
|
|
76
|
-
token: tokenAddress
|
|
77
|
-
});
|
|
78
|
-
console.log(` SDK: Activation complete. Current Credit: ${credit} points.`);
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
console.log(` SDK: Credit system not available (${error.message.split('\n')[0]}). Continuing...`);
|
|
82
|
-
}
|
|
83
|
-
return {
|
|
84
|
-
tx: regTx,
|
|
85
|
-
sbtId,
|
|
86
|
-
initialCredit: credit
|
|
87
|
-
};
|
|
88
|
-
},
|
|
89
|
-
async executeGasless({ target, data, value = 0n, operator }) {
|
|
90
|
-
const accountToUse = account;
|
|
91
|
-
if (!accountToUse)
|
|
92
|
-
throw new Error("Wallet account required for gasless execution");
|
|
93
|
-
// 1. Get AA Address (Predict if necessary)
|
|
94
|
-
const { accountAddress } = await this.createSmartAccount({ owner: accountToUse.address });
|
|
95
|
-
console.log(` SDK: Executing gasless via AA ${accountAddress} Sponsored by ${operator}`);
|
|
96
|
-
// 2. Fetch Nonce from EntryPoint (v0.7 standard)
|
|
97
|
-
// Note: In v0.7, nonce is managed by EntryPoint, not the account itself
|
|
98
|
-
let nonce = 0n;
|
|
99
|
-
try {
|
|
100
|
-
nonce = await client.readContract({
|
|
101
|
-
address: usedAddresses.entryPoint,
|
|
102
|
-
abi: [{
|
|
103
|
-
type: 'function',
|
|
104
|
-
name: 'getNonce',
|
|
105
|
-
inputs: [{ type: 'address', name: 'sender' }, { type: 'uint192', name: 'key' }],
|
|
106
|
-
outputs: [{ type: 'uint256' }],
|
|
107
|
-
stateMutability: 'view'
|
|
108
|
-
}],
|
|
109
|
-
functionName: 'getNonce',
|
|
110
|
-
args: [accountAddress, 0n] // 0 = default nonce key
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
console.warn(` ⚠️ Failed to fetch nonce from EntryPoint, using default 0:`, e.message);
|
|
115
|
-
// For initial transactions, nonce is always 0
|
|
116
|
-
nonce = 0n;
|
|
117
|
-
}
|
|
118
|
-
// 3. Build CallData (execute(target, value, data))
|
|
119
|
-
const { encodeFunctionData, concat, pad, keccak256 } = await import('viem');
|
|
120
|
-
const executeData = encodeFunctionData({
|
|
121
|
-
abi: [{ type: 'function', name: 'execute', inputs: [{ type: 'address' }, { type: 'uint256' }, { type: 'bytes' }] }],
|
|
122
|
-
functionName: 'execute',
|
|
123
|
-
args: [target, value, data]
|
|
124
|
-
});
|
|
125
|
-
// 4. Build Gas Limits & Fees (Benchmarked for experiments)
|
|
126
|
-
const accountGasLimits = concat([
|
|
127
|
-
pad(`0x${(100000).toString(16)}`, { dir: 'left', size: 16 }), // verification
|
|
128
|
-
pad(`0x${(100000).toString(16)}`, { dir: 'left', size: 16 }) // call
|
|
129
|
-
]);
|
|
130
|
-
const gasFees = concat([
|
|
131
|
-
pad(`0x${(2000000000).toString(16)}`, { dir: 'left', size: 16 }), // 2 gwei
|
|
132
|
-
pad(`0x${(2000000000).toString(16)}`, { dir: 'left', size: 16 }) // 2 gwei
|
|
133
|
-
]);
|
|
134
|
-
// 5. Build PaymasterAndData (v0.7 packed format)
|
|
135
|
-
const paymasterVerificationGas = 250000n;
|
|
136
|
-
const paymasterPostOpGas = 50000n;
|
|
137
|
-
const paymasterAndData = concat([
|
|
138
|
-
usedAddresses.superPaymaster,
|
|
139
|
-
pad(`0x${paymasterVerificationGas.toString(16)}`, { dir: 'left', size: 16 }),
|
|
140
|
-
pad(`0x${paymasterPostOpGas.toString(16)}`, { dir: 'left', size: 16 }),
|
|
141
|
-
operator
|
|
142
|
-
]);
|
|
143
|
-
// 6. Construct UserOperation v0.7
|
|
144
|
-
const userOp = {
|
|
145
|
-
sender: accountAddress,
|
|
146
|
-
nonce,
|
|
147
|
-
initCode: '0x',
|
|
148
|
-
callData: executeData,
|
|
149
|
-
accountGasLimits,
|
|
150
|
-
preVerificationGas: 50000n,
|
|
151
|
-
gasFees,
|
|
152
|
-
paymasterAndData,
|
|
153
|
-
signature: '0x'
|
|
154
|
-
};
|
|
155
|
-
// 7. Sign UserOp Hash
|
|
156
|
-
const entryPointAddress = usedAddresses.entryPoint || '0x0000000071727De22E5E9d8BAf0edAc6f37da032';
|
|
157
|
-
const userOpHash = await client.readContract({
|
|
158
|
-
address: entryPointAddress,
|
|
159
|
-
abi: [{
|
|
160
|
-
type: 'function',
|
|
161
|
-
name: 'getUserOpHash',
|
|
162
|
-
inputs: [{
|
|
163
|
-
type: 'tuple',
|
|
164
|
-
components: [
|
|
165
|
-
{ name: 'sender', type: 'address' },
|
|
166
|
-
{ name: 'nonce', type: 'uint256' },
|
|
167
|
-
{ name: 'initCode', type: 'bytes' },
|
|
168
|
-
{ name: 'callData', type: 'bytes' },
|
|
169
|
-
{ name: 'accountGasLimits', type: 'bytes32' },
|
|
170
|
-
{ name: 'preVerificationGas', type: 'uint256' },
|
|
171
|
-
{ name: 'gasFees', type: 'bytes32' },
|
|
172
|
-
{ name: 'paymasterAndData', type: 'bytes' },
|
|
173
|
-
{ name: 'signature', type: 'bytes' }
|
|
174
|
-
]
|
|
175
|
-
}],
|
|
176
|
-
outputs: [{ type: 'bytes32' }],
|
|
177
|
-
stateMutability: 'view'
|
|
178
|
-
}],
|
|
179
|
-
functionName: 'getUserOpHash',
|
|
180
|
-
args: [userOp]
|
|
181
|
-
});
|
|
182
|
-
const signature = await accountToUse.signMessage({
|
|
183
|
-
message: { raw: userOpHash }
|
|
184
|
-
});
|
|
185
|
-
userOp.signature = signature;
|
|
186
|
-
// 8. Submit via handleOps
|
|
187
|
-
console.log(` SDK: Submitting UserOp ${userOpHash}...`);
|
|
188
|
-
const tx = await client.writeContract({
|
|
189
|
-
address: entryPointAddress,
|
|
190
|
-
abi: [{
|
|
191
|
-
type: 'function',
|
|
192
|
-
name: 'handleOps',
|
|
193
|
-
inputs: [
|
|
194
|
-
{
|
|
195
|
-
type: 'tuple[]',
|
|
196
|
-
components: [
|
|
197
|
-
{ name: 'sender', type: 'address' },
|
|
198
|
-
{ name: 'nonce', type: 'uint256' },
|
|
199
|
-
{ name: 'initCode', type: 'bytes' },
|
|
200
|
-
{ name: 'callData', type: 'bytes' },
|
|
201
|
-
{ name: 'accountGasLimits', type: 'bytes32' },
|
|
202
|
-
{ name: 'preVerificationGas', type: 'uint256' },
|
|
203
|
-
{ name: 'gasFees', type: 'bytes32' },
|
|
204
|
-
{ name: 'paymasterAndData', type: 'bytes' },
|
|
205
|
-
{ name: 'signature', type: 'bytes' }
|
|
206
|
-
]
|
|
207
|
-
},
|
|
208
|
-
{ name: 'beneficiary', type: 'address' }
|
|
209
|
-
],
|
|
210
|
-
outputs: [],
|
|
211
|
-
stateMutability: 'nonpayable'
|
|
212
|
-
}],
|
|
213
|
-
functionName: 'handleOps',
|
|
214
|
-
args: [[userOp], accountToUse.address],
|
|
215
|
-
account,
|
|
216
|
-
chain
|
|
217
|
-
});
|
|
218
|
-
await client.waitForTransactionReceipt({ hash: tx });
|
|
219
|
-
return tx;
|
|
220
|
-
},
|
|
221
|
-
async checkJoinRequirements(address) {
|
|
222
|
-
const accountToUse = address || account?.address;
|
|
223
|
-
if (!accountToUse)
|
|
224
|
-
throw new Error("Account address required for requirement check");
|
|
225
|
-
const { RequirementChecker } = await import('@aastar/core');
|
|
226
|
-
const checker = new RequirementChecker(client, usedAddresses);
|
|
227
|
-
// Default requirements for standard community joining
|
|
228
|
-
return await checker.checkRequirements({
|
|
229
|
-
address: accountToUse,
|
|
230
|
-
requiredGToken: 440000000000000000n, // 0.44 GT (stake + burn)
|
|
231
|
-
requireSBT: false
|
|
232
|
-
});
|
|
233
|
-
},
|
|
234
|
-
async createSmartAccount({ owner, salt = 0n }) {
|
|
235
|
-
const { SimpleAccountFactoryABI } = await import('@aastar/core');
|
|
236
|
-
const { encodeFunctionData, concat } = await import('viem');
|
|
237
|
-
let factoryAddress = usedAddresses.simpleAccountFactory;
|
|
238
|
-
console.log(` SDK: Using SimpleAccountFactory: ${factoryAddress} (Owner: ${owner}, Salt: ${salt})`);
|
|
239
|
-
// Fallback to official v0.7 factory if not provided
|
|
240
|
-
if (!factoryAddress || factoryAddress === '0x0000000000000000000000000000000000000000') {
|
|
241
|
-
console.warn(" ⚠️ SimpleAccountFactory not found in configuration. Using default fallback.");
|
|
242
|
-
factoryAddress = '0x9406Cc6185a346906296840746125a0E44976454';
|
|
243
|
-
}
|
|
244
|
-
const accountAddress = await client.readContract({
|
|
245
|
-
address: factoryAddress,
|
|
246
|
-
abi: SimpleAccountFactoryABI,
|
|
247
|
-
functionName: 'getAddress',
|
|
248
|
-
args: [owner, salt]
|
|
249
|
-
});
|
|
250
|
-
const createAccountData = encodeFunctionData({
|
|
251
|
-
abi: SimpleAccountFactoryABI,
|
|
252
|
-
functionName: 'createAccount',
|
|
253
|
-
args: [owner, salt]
|
|
254
|
-
});
|
|
255
|
-
const initCode = concat([factoryAddress, createAccountData]);
|
|
256
|
-
const byteCode = await client.getBytecode({ address: accountAddress });
|
|
257
|
-
const isDeployed = byteCode !== undefined && byteCode !== '0x';
|
|
258
|
-
return { accountAddress, initCode, isDeployed };
|
|
259
|
-
},
|
|
260
|
-
async deploySmartAccount({ owner, salt = 0n, fundWithETH = 0n }) {
|
|
261
|
-
const { accountAddress, isDeployed } = await this.createSmartAccount({ owner, salt });
|
|
262
|
-
const { formatEther } = await import('viem');
|
|
263
|
-
let deployHash = '0x0';
|
|
264
|
-
if (isDeployed) {
|
|
265
|
-
console.log(` ℹ️ Account ${accountAddress} already deployed.`);
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
const { SimpleAccountFactoryABI } = await import('@aastar/core');
|
|
269
|
-
let factoryAddress = usedAddresses.simpleAccountFactory;
|
|
270
|
-
if (!factoryAddress || factoryAddress === '0x0000000000000000000000000000000000000000') {
|
|
271
|
-
factoryAddress = '0x9406Cc6185a346906296840746125a0E44976454';
|
|
272
|
-
}
|
|
273
|
-
console.log(` 🏭 Deploying Smart Account for ${owner}...`);
|
|
274
|
-
deployHash = await client.writeContract({
|
|
275
|
-
address: factoryAddress,
|
|
276
|
-
abi: SimpleAccountFactoryABI,
|
|
277
|
-
functionName: 'createAccount',
|
|
278
|
-
args: [owner, salt],
|
|
279
|
-
account,
|
|
280
|
-
chain
|
|
281
|
-
});
|
|
282
|
-
await client.waitForTransactionReceipt({ hash: deployHash });
|
|
283
|
-
console.log(` ✅ Deployed at ${accountAddress}`);
|
|
284
|
-
}
|
|
285
|
-
if (fundWithETH > 0n) {
|
|
286
|
-
console.log(` ⛽ Funding account with ${formatEther(fundWithETH)} ETH...`);
|
|
287
|
-
const tx = await client.sendTransaction({
|
|
288
|
-
to: accountAddress,
|
|
289
|
-
value: fundWithETH,
|
|
290
|
-
account,
|
|
291
|
-
chain
|
|
292
|
-
});
|
|
293
|
-
await client.waitForTransactionReceipt({ hash: tx });
|
|
294
|
-
}
|
|
295
|
-
return { accountAddress, deployTxHash: deployHash, isDeployed: true };
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { type Client, type Transport, type Chain, type Account, type Hash, type Hex, type PublicActions, type WalletActions, type Address } from 'viem';
|
|
2
|
-
import { type StakingActions, type RegistryActions, type SuperPaymasterActions, type PaymasterActions } from '@aastar/core';
|
|
3
|
-
export type OperatorClient = Client<Transport, Chain, Account | undefined> & PublicActions<Transport, Chain, Account | undefined> & WalletActions<Chain, Account | undefined> & RegistryActions & SuperPaymasterActions & PaymasterActions & StakingActions & {
|
|
4
|
-
/**
|
|
5
|
-
* High-level API: Setup operator with automatic funding and onboarding
|
|
6
|
-
*/
|
|
7
|
-
setup: (args: {
|
|
8
|
-
stakeAmount: bigint;
|
|
9
|
-
depositAmount: bigint;
|
|
10
|
-
roleId: Hex;
|
|
11
|
-
roleData?: Hex;
|
|
12
|
-
}) => Promise<{
|
|
13
|
-
txs: Hash[];
|
|
14
|
-
}>;
|
|
15
|
-
deployPaymasterV4: (args?: {
|
|
16
|
-
version?: string;
|
|
17
|
-
initData?: Hex;
|
|
18
|
-
}) => Promise<Hash>;
|
|
19
|
-
/**
|
|
20
|
-
* Orchestrates the full onboarding flow:
|
|
21
|
-
* 1. Approve GToken (Stake)
|
|
22
|
-
* 2. Register Role (Stake Lock)
|
|
23
|
-
* 3. Approve aPNTs (Deposit)
|
|
24
|
-
* 4. Deposit aPNTs (SuperPaymaster)
|
|
25
|
-
*/
|
|
26
|
-
onboardOperator: (args: {
|
|
27
|
-
stakeAmount: bigint;
|
|
28
|
-
depositAmount: bigint;
|
|
29
|
-
roleId: Hex;
|
|
30
|
-
roleData?: Hex;
|
|
31
|
-
}) => Promise<Hash[]>;
|
|
32
|
-
/** @deprecated Use onboardOperator */
|
|
33
|
-
onboardToSuperPaymaster: (args: {
|
|
34
|
-
stakeAmount: bigint;
|
|
35
|
-
depositAmount: bigint;
|
|
36
|
-
roleId: Hex;
|
|
37
|
-
}) => Promise<Hash[]>;
|
|
38
|
-
configureOperator: (args: {
|
|
39
|
-
xPNTsToken: Address;
|
|
40
|
-
treasury: Address;
|
|
41
|
-
exchangeRate: bigint;
|
|
42
|
-
account?: Account | Address;
|
|
43
|
-
}) => Promise<Hash>;
|
|
44
|
-
getOperatorStatus: (accountAddress: Address) => Promise<{
|
|
45
|
-
type: 'super' | 'v4' | null;
|
|
46
|
-
superPaymaster: {
|
|
47
|
-
hasRole: boolean;
|
|
48
|
-
isConfigured: boolean;
|
|
49
|
-
balance: bigint;
|
|
50
|
-
exchangeRate: bigint;
|
|
51
|
-
treasury: Address;
|
|
52
|
-
} | null;
|
|
53
|
-
paymasterV4: {
|
|
54
|
-
address: Address;
|
|
55
|
-
balance: bigint;
|
|
56
|
-
} | null;
|
|
57
|
-
}>;
|
|
58
|
-
};
|
|
59
|
-
export declare function createOperatorClient({ chain, transport, account, addresses }: {
|
|
60
|
-
chain: Chain;
|
|
61
|
-
transport: Transport;
|
|
62
|
-
account?: Account;
|
|
63
|
-
addresses?: {
|
|
64
|
-
[key: string]: Address;
|
|
65
|
-
};
|
|
66
|
-
}): OperatorClient;
|
package/dist/clients/operator.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { createClient, erc20Abi, parseAbi, publicActions, walletActions, keccak256, stringToBytes } from 'viem';
|
|
2
|
-
import { stakingActions, registryActions, RegistryABI, superPaymasterActions, paymasterActions, PaymasterFactoryABI, CORE_ADDRESSES, TEST_TOKEN_ADDRESSES, TEST_ACCOUNT_ADDRESSES } from '@aastar/core';
|
|
3
|
-
import { RoleDataFactory } from '../utils/roleData.js';
|
|
4
|
-
import { decodeContractError } from '../errors/decoder.js';
|
|
5
|
-
export function createOperatorClient({ chain, transport, account, addresses }) {
|
|
6
|
-
const client = createClient({
|
|
7
|
-
chain,
|
|
8
|
-
transport,
|
|
9
|
-
account
|
|
10
|
-
})
|
|
11
|
-
.extend(publicActions)
|
|
12
|
-
.extend(walletActions);
|
|
13
|
-
const usedAddresses = { ...CORE_ADDRESSES, ...TEST_TOKEN_ADDRESSES, ...TEST_ACCOUNT_ADDRESSES, ...addresses };
|
|
14
|
-
const spActions = superPaymasterActions(usedAddresses.superPaymaster)(client);
|
|
15
|
-
const regActions = registryActions(usedAddresses.registry)(client);
|
|
16
|
-
const stkActions = stakingActions(usedAddresses.gTokenStaking)(client);
|
|
17
|
-
const pmV4Actions = paymasterActions(usedAddresses.paymasterV4)(client);
|
|
18
|
-
const actions = {
|
|
19
|
-
...stkActions,
|
|
20
|
-
...spActions,
|
|
21
|
-
...pmV4Actions,
|
|
22
|
-
...regActions,
|
|
23
|
-
async setup(args) {
|
|
24
|
-
console.log('⚙️ Setting up operator...');
|
|
25
|
-
const txs = await this._onboardOperator(args);
|
|
26
|
-
console.log(`✅ Operator setup complete! Transactions: ${txs.length}`);
|
|
27
|
-
return { txs };
|
|
28
|
-
},
|
|
29
|
-
async onboardOperator(args) {
|
|
30
|
-
return this.onboardFully(args);
|
|
31
|
-
},
|
|
32
|
-
async onboardFully(args) {
|
|
33
|
-
return this._onboardOperator(args);
|
|
34
|
-
},
|
|
35
|
-
async deployPaymasterV4({ version = 'v4.1', initData = '0x' } = {}) {
|
|
36
|
-
console.log(` SDK: Deploying Paymaster V4 (${version})...`);
|
|
37
|
-
const tx = await client.writeContract({
|
|
38
|
-
address: usedAddresses.paymasterFactory,
|
|
39
|
-
abi: PaymasterFactoryABI,
|
|
40
|
-
functionName: 'deployPaymaster',
|
|
41
|
-
args: [version, initData],
|
|
42
|
-
account,
|
|
43
|
-
chain
|
|
44
|
-
});
|
|
45
|
-
await client.waitForTransactionReceipt({ hash: tx });
|
|
46
|
-
return tx;
|
|
47
|
-
},
|
|
48
|
-
async _onboardOperator({ stakeAmount, depositAmount, roleId, roleData }) {
|
|
49
|
-
const txs = [];
|
|
50
|
-
const accountToUse = account;
|
|
51
|
-
if (!accountToUse)
|
|
52
|
-
throw new Error("Account required for onboarding");
|
|
53
|
-
try {
|
|
54
|
-
// 1. Fetch Entry Burn & Approve GToken
|
|
55
|
-
console.log(' SDK: Fetching role config for entry burn...');
|
|
56
|
-
const roleConfig = await client.readContract({
|
|
57
|
-
address: usedAddresses.registry,
|
|
58
|
-
abi: RegistryABI,
|
|
59
|
-
functionName: 'roleConfigs',
|
|
60
|
-
args: [roleId]
|
|
61
|
-
});
|
|
62
|
-
const entryBurn = roleConfig[1];
|
|
63
|
-
const totalStakeNeeded = stakeAmount + entryBurn;
|
|
64
|
-
console.log(` SDK: Approving GToken (Stake: ${stakeAmount}, Burn: ${entryBurn})...`);
|
|
65
|
-
const approveGToken = await client.writeContract({
|
|
66
|
-
address: usedAddresses.gToken,
|
|
67
|
-
abi: erc20Abi,
|
|
68
|
-
functionName: 'approve',
|
|
69
|
-
args: [usedAddresses.gTokenStaking, totalStakeNeeded],
|
|
70
|
-
account: accountToUse,
|
|
71
|
-
chain
|
|
72
|
-
});
|
|
73
|
-
await client.waitForTransactionReceipt({ hash: approveGToken });
|
|
74
|
-
txs.push(approveGToken);
|
|
75
|
-
// 2. Register Role
|
|
76
|
-
let data;
|
|
77
|
-
if (roleData && roleData !== '0x') {
|
|
78
|
-
data = roleData;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
console.log(` SDK: Auto-generating roleData for roleId ${roleId}...`);
|
|
82
|
-
if (roleId === keccak256(stringToBytes('COMMUNITY'))) {
|
|
83
|
-
data = RoleDataFactory.community();
|
|
84
|
-
}
|
|
85
|
-
else if (roleId === keccak256(stringToBytes('ENDUSER'))) {
|
|
86
|
-
data = RoleDataFactory.endUser();
|
|
87
|
-
}
|
|
88
|
-
else if (roleId === keccak256(stringToBytes('PAYMASTER_SUPER'))) {
|
|
89
|
-
data = RoleDataFactory.paymasterSuper();
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
data = RoleDataFactory.paymasterSuper();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
console.log(` SDK: Checking if role already granted...`);
|
|
96
|
-
const hasRoleResult = await client.readContract({
|
|
97
|
-
address: usedAddresses.registry,
|
|
98
|
-
abi: RegistryABI,
|
|
99
|
-
functionName: 'hasRole',
|
|
100
|
-
args: [roleId, accountToUse.address]
|
|
101
|
-
});
|
|
102
|
-
if (hasRoleResult) {
|
|
103
|
-
console.log(` ℹ️ Role already granted, skipping registration`);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
console.log(` SDK: Registering role ${roleId}...`);
|
|
107
|
-
const registerTx = await actions.registerRoleSelf({
|
|
108
|
-
roleId,
|
|
109
|
-
data,
|
|
110
|
-
account: accountToUse
|
|
111
|
-
});
|
|
112
|
-
await client.waitForTransactionReceipt({ hash: registerTx });
|
|
113
|
-
txs.push(registerTx);
|
|
114
|
-
}
|
|
115
|
-
if (depositAmount > 0n) {
|
|
116
|
-
console.log(' SDK: Depositing aPNTs via depositFor...');
|
|
117
|
-
const depositTx = await client.writeContract({
|
|
118
|
-
address: usedAddresses.superPaymaster,
|
|
119
|
-
abi: parseAbi(['function depositFor(address targetOperator, uint256 amount) external']),
|
|
120
|
-
functionName: 'depositFor',
|
|
121
|
-
args: [accountToUse.address, depositAmount],
|
|
122
|
-
account: accountToUse,
|
|
123
|
-
chain
|
|
124
|
-
});
|
|
125
|
-
await client.waitForTransactionReceipt({ hash: depositTx });
|
|
126
|
-
txs.push(depositTx);
|
|
127
|
-
}
|
|
128
|
-
return txs;
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
const decodedMsg = decodeContractError(error);
|
|
132
|
-
throw decodedMsg ? new Error(`Onboarding Failed: ${decodedMsg}`) : error;
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
async onboardToSuperPaymaster(args) {
|
|
136
|
-
return this.onboardOperator(args);
|
|
137
|
-
},
|
|
138
|
-
async configureOperator({ xPNTsToken, treasury, exchangeRate, account: accountOverride }) {
|
|
139
|
-
const tx = await spActions.configureOperator({
|
|
140
|
-
xPNTsToken,
|
|
141
|
-
opTreasury: treasury,
|
|
142
|
-
exchangeRate,
|
|
143
|
-
account: accountOverride || account
|
|
144
|
-
});
|
|
145
|
-
await client.waitForTransactionReceipt({ hash: tx });
|
|
146
|
-
return tx;
|
|
147
|
-
},
|
|
148
|
-
async getOperatorStatus(accountAddress) {
|
|
149
|
-
try {
|
|
150
|
-
const hasRole = await client.readContract({
|
|
151
|
-
address: usedAddresses.registry,
|
|
152
|
-
abi: RegistryABI,
|
|
153
|
-
functionName: 'hasRole',
|
|
154
|
-
args: [keccak256(stringToBytes('PAYMASTER_SUPER')), accountAddress]
|
|
155
|
-
});
|
|
156
|
-
let operatorType = null;
|
|
157
|
-
let superPaymasterInfo = null;
|
|
158
|
-
let paymasterV4Info = null;
|
|
159
|
-
if (hasRole && usedAddresses.superPaymaster) {
|
|
160
|
-
const pmAbi = parseAbi(['function operators(address) view returns (uint128 balance, uint96 exchangeRate, bool isConfigured, bool isPaused, address token, uint32 reputation, address treasury, uint256 spent, uint256 txSponsored)']);
|
|
161
|
-
const operatorData = await client.readContract({
|
|
162
|
-
address: usedAddresses.superPaymaster,
|
|
163
|
-
abi: pmAbi,
|
|
164
|
-
functionName: 'operators',
|
|
165
|
-
args: [accountAddress]
|
|
166
|
-
});
|
|
167
|
-
if (operatorData && operatorData[2]) { // isConfigured
|
|
168
|
-
operatorType = 'super';
|
|
169
|
-
superPaymasterInfo = {
|
|
170
|
-
hasRole: true,
|
|
171
|
-
isConfigured: true,
|
|
172
|
-
balance: operatorData[0],
|
|
173
|
-
exchangeRate: operatorData[1],
|
|
174
|
-
treasury: operatorData[6]
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// 检查 Paymaster V4 (Direct)
|
|
179
|
-
if (usedAddresses.paymasterFactory && usedAddresses.paymasterFactory !== '0x0000000000000000000000000000000000000000') {
|
|
180
|
-
try {
|
|
181
|
-
const factoryAbi = parseAbi(['function getPaymasterByOperator(address) view returns (address)']);
|
|
182
|
-
const pmAddr = await client.readContract({
|
|
183
|
-
address: usedAddresses.paymasterFactory,
|
|
184
|
-
abi: factoryAbi,
|
|
185
|
-
functionName: 'getPaymasterByOperator',
|
|
186
|
-
args: [accountAddress]
|
|
187
|
-
});
|
|
188
|
-
if (pmAddr !== '0x0000000000000000000000000000000000000000') {
|
|
189
|
-
operatorType = operatorType || 'v4';
|
|
190
|
-
paymasterV4Info = {
|
|
191
|
-
address: pmAddr,
|
|
192
|
-
balance: await client.getBalance({ address: pmAddr })
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
catch (e) {
|
|
197
|
-
console.warn(` ⚠️ Failed to fetch V4 info from factory ${usedAddresses.paymasterFactory}:`, e);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return { type: operatorType, superPaymaster: superPaymasterInfo, paymasterV4: paymasterV4Info };
|
|
201
|
-
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
console.error('Error in getOperatorStatus:', error);
|
|
204
|
-
return { type: null, superPaymaster: null, paymasterV4: null };
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
return Object.assign(client, actions);
|
|
209
|
-
}
|
package/dist/errors/decoder.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const CustomErrors: {
|
|
2
|
-
readonly RoleNotConfigured: "RoleNotConfigured(bytes32,bool)";
|
|
3
|
-
readonly RoleAlreadyGranted: "RoleAlreadyGranted(bytes32,address)";
|
|
4
|
-
readonly InsufficientStake: "InsufficientStake(uint256,uint256)";
|
|
5
|
-
};
|
|
6
|
-
export declare function decodeContractError(error: any): string | null;
|