@aastar/sdk 0.20.8 → 0.20.9

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.
Files changed (88) hide show
  1. package/dist/BaseClient-CkBhQ1ou.d.cts +88 -0
  2. package/dist/UserClient-2J6XMTNV.cjs +15 -0
  3. package/dist/UserClient-2J6XMTNV.cjs.map +1 -0
  4. package/dist/account.cjs +31 -0
  5. package/dist/account.cjs.map +1 -0
  6. package/dist/account.d.cts +48 -0
  7. package/dist/admin.cjs +15 -0
  8. package/dist/admin.cjs.map +1 -0
  9. package/dist/admin.d.cts +62 -0
  10. package/dist/airaccount.cjs +452 -0
  11. package/dist/airaccount.cjs.map +1 -0
  12. package/dist/airaccount.d.cts +4 -0
  13. package/dist/channel-CkRRbzT8.d.cts +77 -0
  14. package/dist/channel.cjs +27 -0
  15. package/dist/channel.cjs.map +1 -0
  16. package/dist/channel.d.cts +64 -0
  17. package/dist/chunk-2RCJBWPO.cjs +1168 -0
  18. package/dist/chunk-2RCJBWPO.cjs.map +1 -0
  19. package/dist/chunk-FTJD2DWE.cjs +42472 -0
  20. package/dist/chunk-FTJD2DWE.cjs.map +1 -0
  21. package/dist/chunk-GRDC6ZRA.cjs +118 -0
  22. package/dist/chunk-GRDC6ZRA.cjs.map +1 -0
  23. package/dist/chunk-GX7NROST.cjs +421 -0
  24. package/dist/chunk-GX7NROST.cjs.map +1 -0
  25. package/dist/chunk-HSVQIFIK.cjs +128 -0
  26. package/dist/chunk-HSVQIFIK.cjs.map +1 -0
  27. package/dist/chunk-JTWY2XEG.cjs +115 -0
  28. package/dist/chunk-JTWY2XEG.cjs.map +1 -0
  29. package/dist/chunk-MRREGCWN.cjs +585 -0
  30. package/dist/chunk-MRREGCWN.cjs.map +1 -0
  31. package/dist/chunk-NT26BDGN.cjs +228 -0
  32. package/dist/chunk-NT26BDGN.cjs.map +1 -0
  33. package/dist/chunk-Q7SFCCGT.cjs +11 -0
  34. package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
  35. package/dist/chunk-QLF7N6H7.cjs +448 -0
  36. package/dist/chunk-QLF7N6H7.cjs.map +1 -0
  37. package/dist/chunk-RNHSA3LO.cjs +108 -0
  38. package/dist/chunk-RNHSA3LO.cjs.map +1 -0
  39. package/dist/chunk-S5IKOOUR.cjs +393 -0
  40. package/dist/chunk-S5IKOOUR.cjs.map +1 -0
  41. package/dist/chunk-TFLZETWB.cjs +4693 -0
  42. package/dist/chunk-TFLZETWB.cjs.map +1 -0
  43. package/dist/chunk-WQREDGUF.cjs +435 -0
  44. package/dist/chunk-WQREDGUF.cjs.map +1 -0
  45. package/dist/chunk-XQROKLZI.cjs +4521 -0
  46. package/dist/chunk-XQROKLZI.cjs.map +1 -0
  47. package/dist/contract-addresses-TANQ5DLX.cjs +49 -0
  48. package/dist/contract-addresses-TANQ5DLX.cjs.map +1 -0
  49. package/dist/core.cjs +894 -0
  50. package/dist/core.cjs.map +1 -0
  51. package/dist/core.d.cts +6930 -0
  52. package/dist/dapp.cjs +289 -0
  53. package/dist/dapp.cjs.map +1 -0
  54. package/dist/dapp.d.cts +127 -0
  55. package/dist/doc-types-471vSmPO.d.cts +16 -0
  56. package/dist/enduser.cjs +24 -0
  57. package/dist/enduser.cjs.map +1 -0
  58. package/dist/enduser.d.cts +261 -0
  59. package/dist/identity.cjs +23 -0
  60. package/dist/identity.cjs.map +1 -0
  61. package/dist/identity.d.cts +81 -0
  62. package/dist/index-B6SfEQxo.d.cts +47 -0
  63. package/dist/index.cjs +2814 -0
  64. package/dist/index.cjs.map +1 -0
  65. package/dist/index.d.cts +656 -0
  66. package/dist/kms.cjs +452 -0
  67. package/dist/kms.cjs.map +1 -0
  68. package/dist/kms.d.cts +3054 -0
  69. package/dist/lib-FE4GR7TO.cjs +1865 -0
  70. package/dist/lib-FE4GR7TO.cjs.map +1 -0
  71. package/dist/operator.cjs +27 -0
  72. package/dist/operator.cjs.map +1 -0
  73. package/dist/operator.d.cts +164 -0
  74. package/dist/paymaster.cjs +63 -0
  75. package/dist/paymaster.cjs.map +1 -0
  76. package/dist/paymaster.d.cts +312 -0
  77. package/dist/src-ENPA7D2S.cjs +63 -0
  78. package/dist/src-ENPA7D2S.cjs.map +1 -0
  79. package/dist/src-TQKEO2I4.cjs +894 -0
  80. package/dist/src-TQKEO2I4.cjs.map +1 -0
  81. package/dist/tier-router-DeeVg69O.d.cts +370 -0
  82. package/dist/tokens.cjs +15 -0
  83. package/dist/tokens.cjs.map +1 -0
  84. package/dist/tokens.d.cts +64 -0
  85. package/dist/x402.cjs +103 -0
  86. package/dist/x402.cjs.map +1 -0
  87. package/dist/x402.d.cts +373 -0
  88. package/package.json +32 -32
@@ -0,0 +1,435 @@
1
+ 'use strict';
2
+
3
+ var chunkFTJD2DWE_cjs = require('./chunk-FTJD2DWE.cjs');
4
+ var viem = require('viem');
5
+
6
+ var CommunityClient = class extends chunkFTJD2DWE_cjs.BaseClient {
7
+ sbtAddress;
8
+ factoryAddress;
9
+ reputationAddress;
10
+ constructor(config) {
11
+ super(config);
12
+ this.sbtAddress = config.sbtAddress;
13
+ this.factoryAddress = config.factoryAddress;
14
+ this.reputationAddress = config.reputationAddress;
15
+ }
16
+ // ========================================
17
+ // 1. 社区创建与配置
18
+ // ========================================
19
+ /**
20
+ * Create a new Community Token (xPNTs) and register it.
21
+ * Note: In the current architecture, creating a community often involves:
22
+ * 1. Registering the ROLE_COMMUNITY on Registry (if not exists) -> usually manual or self-register
23
+ * 2. Deploying a Token (xPNTs) via Factory
24
+ * 3. Linking the Token to the Community in Registry
25
+ */
26
+ async createCommunityToken(params, options) {
27
+ try {
28
+ if (!this.factoryAddress) {
29
+ throw new Error("Factory address required for this client");
30
+ }
31
+ const factory = chunkFTJD2DWE_cjs.xPNTsFactoryActions(this.factoryAddress);
32
+ return await factory(this.client).createToken({
33
+ name: params.name,
34
+ symbol: params.tokenSymbol,
35
+ community: this.getAddress(),
36
+ account: options?.account
37
+ });
38
+ } catch (error) {
39
+ throw error;
40
+ }
41
+ }
42
+ /**
43
+ * Get Community Details (Decodes Role Metadata)
44
+ * @param communityAddress - The address of the community manager (defaults to self)
45
+ */
46
+ async getCommunityInfo(communityAddress) {
47
+ try {
48
+ const target = communityAddress || this.getAddress();
49
+ const registryAddr = this.requireRegistry();
50
+ const registry = chunkFTJD2DWE_cjs.registryActions(registryAddr);
51
+ const publicClient = this.getStartPublicClient();
52
+ const API_ROLE_COMMUNITY = await registry(publicClient).ROLE_COMMUNITY();
53
+ let metadataHex;
54
+ try {
55
+ metadataHex = await registry(publicClient).roleMetadata({
56
+ roleId: API_ROLE_COMMUNITY,
57
+ user: target
58
+ });
59
+ } catch (err) {
60
+ const m = (err instanceof Error ? `${err.message} ${err.cause?.message ?? ""}` : String(err)).toLowerCase();
61
+ const isContractGap = m.includes("revert") || m.includes("returned no data") || m.includes("does not exist") || m.includes("is not a function") || m.includes("no data was returned");
62
+ if (!isContractGap) throw err;
63
+ metadataHex = void 0;
64
+ }
65
+ if (!metadataHex || metadataHex === "0x") {
66
+ let stakeAmount2 = 0n;
67
+ try {
68
+ stakeAmount2 = await registry(publicClient).roleStakes({ roleId: API_ROLE_COMMUNITY, user: target });
69
+ } catch {
70
+ }
71
+ return { name: "", ensName: "", website: "", description: "", logoURI: "", stakeAmount: stakeAmount2 };
72
+ }
73
+ let dataToDecode = metadataHex;
74
+ if (metadataHex.startsWith("0x0000000000000000000000000000000000000000000000000000000000000020")) {
75
+ dataToDecode = `0x${metadataHex.slice(66)}`;
76
+ }
77
+ const { decodeAbiParameters, parseAbiParameters: parseAbiParameters2 } = await import('viem');
78
+ const [name, ensName, website, description, logoURI, stakeAmount] = decodeAbiParameters(
79
+ parseAbiParameters2("string, string, string, string, string, uint256"),
80
+ dataToDecode
81
+ );
82
+ return {
83
+ name,
84
+ ensName,
85
+ website,
86
+ description,
87
+ logoURI,
88
+ stakeAmount
89
+ };
90
+ } catch (error) {
91
+ throw error;
92
+ }
93
+ }
94
+ /**
95
+ * Register self as a Community Manager.
96
+ * This method handles all necessary steps:
97
+ * 1. Checks and approves GToken to GTokenStaking
98
+ * 2. Encodes CommunityRoleData with provided parameters
99
+ * 3. Calls registerRoleSelf on Registry
100
+ *
101
+ * @param params Community registration parameters
102
+ * @param options Transaction options
103
+ * @returns Transaction hash
104
+ */
105
+ async registerAsCommunity(params, options) {
106
+ try {
107
+ const registryAddr = this.requireRegistry();
108
+ const registry = chunkFTJD2DWE_cjs.registryActions(registryAddr);
109
+ const gTokenStakingAddr = this.requireGTokenStaking();
110
+ const gTokenAddr = this.requireGToken();
111
+ const roleCommunity = await registry(this.getStartPublicClient()).ROLE_COMMUNITY();
112
+ const stakeAmount = params.stakeAmount || viem.parseEther("30");
113
+ const gToken = chunkFTJD2DWE_cjs.tokenActions();
114
+ const allowance = await gToken(this.getStartPublicClient()).allowance({
115
+ token: gTokenAddr,
116
+ owner: this.getAddress(),
117
+ spender: gTokenStakingAddr
118
+ });
119
+ if (allowance < stakeAmount) {
120
+ const approveHash = await gToken(this.client).approve({
121
+ token: gTokenAddr,
122
+ spender: gTokenStakingAddr,
123
+ amount: stakeAmount * BigInt(2),
124
+ // Approve 2x for future use
125
+ account: options?.account
126
+ });
127
+ await this.getStartPublicClient().waitForTransactionReceipt({ hash: approveHash });
128
+ }
129
+ const communityData = viem.encodeAbiParameters(
130
+ viem.parseAbiParameters("string, string, string, string, string, uint256"),
131
+ [
132
+ params.name,
133
+ params.ensName || "",
134
+ params.website || "",
135
+ params.description || `${params.name} Community`,
136
+ params.logoURI || "",
137
+ stakeAmount
138
+ ]
139
+ );
140
+ return await registry(this.client).registerRoleSelf({
141
+ roleId: roleCommunity,
142
+ data: communityData,
143
+ account: options?.account
144
+ });
145
+ } catch (error) {
146
+ throw error;
147
+ }
148
+ }
149
+ /**
150
+ * One-click Setup: Register Community + Deploy Token
151
+ * Orchestrates the complete community initialization flow.
152
+ */
153
+ async setupCommunity(params, options) {
154
+ const hashes = [];
155
+ let tokenAddress = "0x0000000000000000000000000000000000000000";
156
+ const registry = chunkFTJD2DWE_cjs.registryActions(this.requireRegistry())(this.getStartPublicClient());
157
+ const ROLE_COMMUNITY = await registry.ROLE_COMMUNITY();
158
+ const hasRole = await registry.hasRole({ roleId: ROLE_COMMUNITY, user: this.getAddress() });
159
+ if (!hasRole) {
160
+ const hReg = await this.registerAsCommunity({
161
+ name: params.name,
162
+ ensName: params.website,
163
+ // Mapping website to ENS param for now as per legacy behavior
164
+ website: params.website,
165
+ description: params.description,
166
+ logoURI: params.logoURI,
167
+ stakeAmount: params.stakeAmount
168
+ }, options);
169
+ hashes.push(hReg);
170
+ await this.getStartPublicClient().waitForTransactionReceipt({ hash: hReg });
171
+ }
172
+ if (this.factoryAddress) {
173
+ const factoryReader = chunkFTJD2DWE_cjs.xPNTsFactoryActions(this.factoryAddress)(this.getStartPublicClient());
174
+ const existingToken = await factoryReader.getTokenAddress({ community: this.getAddress() });
175
+ if (existingToken && existingToken !== "0x0000000000000000000000000000000000000000") {
176
+ tokenAddress = existingToken;
177
+ } else {
178
+ const hToken = await this.createCommunityToken({
179
+ name: params.tokenName,
180
+ tokenSymbol: params.tokenSymbol,
181
+ description: params.description
182
+ }, options);
183
+ hashes.push(hToken);
184
+ await this.getStartPublicClient().waitForTransactionReceipt({ hash: hToken });
185
+ for (let i = 0; i < 5; i++) {
186
+ tokenAddress = await factoryReader.getTokenAddress({ community: this.getAddress() });
187
+ if (tokenAddress && tokenAddress !== "0x0000000000000000000000000000000000000000") break;
188
+ await new Promise((r) => setTimeout(r, 2e3));
189
+ }
190
+ if (!tokenAddress || tokenAddress === "0x0000000000000000000000000000000000000000") {
191
+ console.warn(`Warning: Token address not found after 10s. Factory might be slow indexing.`);
192
+ }
193
+ }
194
+ }
195
+ return { tokenAddress, hashes };
196
+ }
197
+ // ========================================
198
+ // 2. 成员管理
199
+ // ========================================
200
+ /**
201
+ * Airdrop SBTs to users to make them members
202
+ */
203
+ async airdropSBT(users, roleId, options) {
204
+ try {
205
+ if (!this.sbtAddress) throw new Error("SBT address required for this client");
206
+ const sbt = chunkFTJD2DWE_cjs.sbtActions(this.sbtAddress);
207
+ if (users.length === 1) {
208
+ const roleIdHex = `0x${roleId.toString(16).padStart(64, "0")}`;
209
+ return await sbt(this.client).mintForRole({
210
+ user: users[0],
211
+ roleId: roleIdHex,
212
+ roleData: "0x",
213
+ account: options?.account
214
+ });
215
+ }
216
+ throw new Error("Batch airdrop not fully implemented in L1 yet, use single user");
217
+ } catch (error) {
218
+ throw error;
219
+ }
220
+ }
221
+ // ========================================
222
+ // 3. 信誉系统
223
+ // ========================================
224
+ async setReputationRule(ruleId, ruleConfig, options) {
225
+ try {
226
+ if (!this.reputationAddress) throw new Error("Reputation address required for this client");
227
+ const reputation = chunkFTJD2DWE_cjs.reputationActions(this.reputationAddress);
228
+ const ruleIdHex = `0x${ruleId.toString(16).padStart(64, "0")}`;
229
+ return await reputation(this.client).setReputationRule({
230
+ ruleId: ruleIdHex,
231
+ rule: ruleConfig,
232
+ account: options?.account
233
+ });
234
+ } catch (error) {
235
+ throw error;
236
+ }
237
+ }
238
+ // ========================================
239
+ // 4. 管理功能
240
+ // ========================================
241
+ /**
242
+ * Revoke membership (Burn SBT)
243
+ */
244
+ async revokeMembership(userAddr, options) {
245
+ try {
246
+ if (!this.sbtAddress) throw new Error("SBT address required for this client");
247
+ const sbt = chunkFTJD2DWE_cjs.sbtActions(this.sbtAddress);
248
+ return await sbt(this.client).burnSBT({
249
+ user: userAddr,
250
+ account: options?.account
251
+ });
252
+ } catch (error) {
253
+ throw error;
254
+ }
255
+ }
256
+ /**
257
+ * Transfer ownership of the Community Token
258
+ */
259
+ async transferCommunityTokenOwnership(tokenAddress, newOwner, options) {
260
+ try {
261
+ const token = chunkFTJD2DWE_cjs.tokenActions()(this.client);
262
+ return await token.transferOwnership({
263
+ token: tokenAddress,
264
+ newOwner,
265
+ account: options?.account
266
+ });
267
+ } catch (error) {
268
+ throw error;
269
+ }
270
+ }
271
+ };
272
+ var UserLifecycle = class extends chunkFTJD2DWE_cjs.BaseClient {
273
+ accountAddress;
274
+ registryAddress;
275
+ sbtAddress;
276
+ gTokenAddress;
277
+ gTokenStakingAddress;
278
+ entryPointAddress;
279
+ gaslessConfig;
280
+ config;
281
+ constructor(config) {
282
+ super(config);
283
+ this.config = config;
284
+ this.accountAddress = config.accountAddress;
285
+ this.registryAddress = config.registryAddress;
286
+ this.sbtAddress = config.sbtAddress;
287
+ this.gTokenAddress = config.gTokenAddress;
288
+ this.gTokenStakingAddress = config.gTokenStakingAddress;
289
+ this.entryPointAddress = config.entryPointAddress;
290
+ this.gaslessConfig = config.gasless;
291
+ }
292
+ // ===========================================
293
+ // 1. Onboarding Phase (Registration)
294
+ // ===========================================
295
+ /**
296
+ * Check if user is eligible to join a community
297
+ * @param community Address of the community
298
+ */
299
+ async checkEligibility(community) {
300
+ const publicClient = this.getStartPublicClient();
301
+ chunkFTJD2DWE_cjs.registryActions(this.registryAddress)(publicClient);
302
+ return true;
303
+ }
304
+ /**
305
+ * One-click Onboarding: Approve -> Stake -> Register -> Mint SBT
306
+ * @param community Address of the community to join
307
+ * @param stakeAmount Amount of GToken to stake (default 0.4 GT)
308
+ */
309
+ async onboard(community, stakeAmount = viem.parseEther("0.4")) {
310
+ try {
311
+ const registry = chunkFTJD2DWE_cjs.registryActions(this.registryAddress)(this.getStartPublicClient());
312
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
313
+ ...this.config,
314
+ accountAddress: this.accountAddress,
315
+ registryAddress: this.registryAddress,
316
+ gTokenStakingAddress: this.gTokenStakingAddress,
317
+ gTokenAddress: this.gTokenAddress,
318
+ sbtAddress: this.sbtAddress
319
+ }));
320
+ const txHash = await userClient.registerAsEndUser(community, stakeAmount);
321
+ let hasRole = false;
322
+ for (let i = 0; i < 5; i++) {
323
+ hasRole = await registry.hasRole({
324
+ roleId: await registry.ROLE_ENDUSER(),
325
+ user: this.accountAddress
326
+ });
327
+ if (hasRole) break;
328
+ await new Promise((r) => setTimeout(r, 2e3));
329
+ }
330
+ return {
331
+ success: hasRole,
332
+ txHash
333
+ };
334
+ } catch (error) {
335
+ console.error("Onboarding failed:", error);
336
+ return { success: false };
337
+ }
338
+ }
339
+ /**
340
+ * Enable or update Gasless configuration
341
+ */
342
+ async enableGasless(config) {
343
+ this.gaslessConfig = config;
344
+ }
345
+ // ===========================================
346
+ // 2. Operational Phase (Execute & Interact)
347
+ // ===========================================
348
+ /**
349
+ * Execute a transaction effectively using Gasless configuration if available
350
+ */
351
+ async executeGaslessTx(params) {
352
+ if (!this.gaslessConfig) {
353
+ throw new Error("Gasless configuration not enabled. Call enableGasless() first.");
354
+ }
355
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
356
+ ...this.config,
357
+ accountAddress: this.accountAddress,
358
+ // Pass minimal config needed for execution
359
+ entryPointAddress: this.entryPointAddress,
360
+ bundlerClient: this.config.bundlerClient
361
+ }));
362
+ const paymasterType = this.gaslessConfig.policy === "CREDIT" ? "Super" : "V4";
363
+ const registry = chunkFTJD2DWE_cjs.registryActions(this.registryAddress)(this.client);
364
+ const paymasterAddress = await registry.SUPER_PAYMASTER();
365
+ return await userClient.executeGasless({
366
+ target: params.target,
367
+ value: params.value,
368
+ data: params.data,
369
+ paymaster: paymasterAddress,
370
+ paymasterType,
371
+ operator: params.operator
372
+ });
373
+ }
374
+ async claimSBT(roleId, options) {
375
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
376
+ ...this.config,
377
+ accountAddress: this.accountAddress,
378
+ sbtAddress: this.sbtAddress
379
+ }));
380
+ return await userClient.mintSBT(roleId, options);
381
+ }
382
+ // ===========================================
383
+ // 3. Query Phase (Info & Stats)
384
+ // ===========================================
385
+ async getMyReputation() {
386
+ const publicClient = this.getStartPublicClient();
387
+ const registry = chunkFTJD2DWE_cjs.registryActions(this.registryAddress)(publicClient);
388
+ const [score, creditLimit] = await Promise.all([
389
+ registry.globalReputation({ user: this.accountAddress }),
390
+ registry.getCreditLimit({ user: this.accountAddress })
391
+ ]);
392
+ return {
393
+ score,
394
+ level: 0n,
395
+ // TODO: Add level calculation logic
396
+ creditLimit
397
+ };
398
+ }
399
+ async getCreditLimit() {
400
+ const registry = chunkFTJD2DWE_cjs.registryActions(this.registryAddress)(this.client);
401
+ return await registry.getCreditLimit({ user: this.accountAddress });
402
+ }
403
+ // ===========================================
404
+ // 4. Exit Phase (Cleanup)
405
+ // ===========================================
406
+ async leaveCommunity(community, options) {
407
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
408
+ ...this.config,
409
+ accountAddress: this.accountAddress,
410
+ sbtAddress: this.sbtAddress
411
+ }));
412
+ return await userClient.leaveCommunity(community, options);
413
+ }
414
+ async exitRole(roleId, options) {
415
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
416
+ ...this.config,
417
+ accountAddress: this.accountAddress,
418
+ registryAddress: this.registryAddress
419
+ }));
420
+ return await userClient.exitRole(roleId, options);
421
+ }
422
+ async unstakeAll(roleId, options) {
423
+ const userClient = await import('./UserClient-2J6XMTNV.cjs').then((m) => new m.UserClient({
424
+ ...this.config,
425
+ accountAddress: this.accountAddress,
426
+ gTokenStakingAddress: this.gTokenStakingAddress
427
+ }));
428
+ return await userClient.unstakeFromRole(roleId, options);
429
+ }
430
+ };
431
+
432
+ exports.CommunityClient = CommunityClient;
433
+ exports.UserLifecycle = UserLifecycle;
434
+ //# sourceMappingURL=chunk-WQREDGUF.cjs.map
435
+ //# sourceMappingURL=chunk-WQREDGUF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../enduser/src/CommunityClient.ts","../../enduser/src/UserLifecycle.ts"],"names":["BaseClient","xPNTsFactoryActions","registryActions","stakeAmount","parseAbiParameters","parseEther","tokenActions","encodeAbiParameters","sbtActions","reputationActions"],"mappings":"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","file":"chunk-WQREDGUF.cjs","sourcesContent":["import { type Address, type Hash, type Hex, parseEther, encodeAbiParameters, parseAbiParameters } from 'viem';\nimport { BaseClient, type ClientConfig, type TransactionOptions } from '@aastar/core';\nimport { registryActions, sbtActions, xPNTsFactoryActions, reputationActions, tokenActions } from '@aastar/core';\n\nexport interface CommunityClientConfig extends ClientConfig {\n sbtAddress?: Address;\n factoryAddress?: Address;\n reputationAddress?: Address;\n}\n\nexport interface CreateCommunityParams {\n name: string;\n tokenSymbol: string;\n ensName?: string;\n description?: string;\n}\n\nexport interface CommunityInfo {\n address: Address; // Community ID (hash) usually, but here likely the SBT/profile? No, Community in Registry is bytes32 ID.\n // Wait, Registry defines Community as a Role (ROLE_COMMUNITY).\n // The \"Community\" entity usually implies a collection of contracts (Token, maybe Paymaster).\n}\n\n/**\n * Client for Community Managers (`ROLE_COMMUNITY`)\n */\nexport class CommunityClient extends BaseClient {\n public sbtAddress?: Address;\n public factoryAddress?: Address;\n public reputationAddress?: Address;\n\n constructor(config: CommunityClientConfig) {\n super(config);\n this.sbtAddress = config.sbtAddress;\n this.factoryAddress = config.factoryAddress;\n this.reputationAddress = config.reputationAddress;\n }\n\n // ========================================\n // 1. 社区创建与配置\n // ========================================\n\n /**\n * Create a new Community Token (xPNTs) and register it.\n * Note: In the current architecture, creating a community often involves:\n * 1. Registering the ROLE_COMMUNITY on Registry (if not exists) -> usually manual or self-register\n * 2. Deploying a Token (xPNTs) via Factory\n * 3. Linking the Token to the Community in Registry\n */\n async createCommunityToken(params: CreateCommunityParams, options?: TransactionOptions): Promise<Hash> {\n try {\n if (!this.factoryAddress) {\n throw new Error('Factory address required for this client');\n }\n const factory = xPNTsFactoryActions(this.factoryAddress);\n\n // 1. Deploy Token\n // Note: The address calculation should be handled via event parsing or predictive deployment\n // For now, returning the transaction hash as per L1 pattern\n return await factory(this.client).createToken({\n name: params.name,\n symbol: params.tokenSymbol,\n community: this.getAddress(),\n account: options?.account\n });\n } catch (error) {\n // Error is likely already an AAStarError from L1, but we wrap it for context\n throw error; \n }\n }\n\n /**\n * Get Community Details (Decodes Role Metadata)\n * @param communityAddress - The address of the community manager (defaults to self)\n */\n async getCommunityInfo(communityAddress?: Address): Promise<{\n name: string;\n ensName: string;\n website: string;\n description: string;\n logoURI: string;\n stakeAmount: bigint;\n }> {\n try {\n const target = communityAddress || this.getAddress();\n const registryAddr = this.requireRegistry();\n const registry = registryActions(registryAddr);\n const publicClient = this.getStartPublicClient();\n \n // 1. Get Role ID\n const API_ROLE_COMMUNITY = await registry(publicClient).ROLE_COMMUNITY();\n\n // 2. Fetch Metadata (Hex).\n // NOTE: in the deployed v5 Registry, `roleMetadata` is an INTERNAL mapping with no\n // public getter (the rich community profile — name/website/logo — is written on\n // registerRole but not readable on-chain). When the getter is absent the call\n // reverts; degrade gracefully to the on-chain-readable fields (stake) with an\n // empty profile rather than throwing, so callers can still resolve the community.\n let metadataHex: Hex | undefined;\n try {\n metadataHex = await registry(publicClient).roleMetadata({\n roleId: API_ROLE_COMMUNITY,\n user: target\n });\n } catch (err) {\n // Degrade ONLY on contract-level \"no getter / reverted\" errors — the deployed\n // v5 Registry genuinely lacks a public roleMetadata getter. Re-throw genuine\n // transport/RPC errors so a transient network failure is not silently masked as\n // \"no community profile\".\n const m = (err instanceof Error ? `${err.message} ${(err as { cause?: { message?: string } }).cause?.message ?? ''}` : String(err)).toLowerCase();\n const isContractGap =\n m.includes('revert') || m.includes('returned no data') ||\n m.includes('does not exist') || m.includes('is not a function') ||\n m.includes('no data was returned');\n if (!isContractGap) throw err;\n metadataHex = undefined;\n }\n\n if (!metadataHex || metadataHex === '0x') {\n let stakeAmount = 0n;\n try {\n stakeAmount = await registry(publicClient).roleStakes({ roleId: API_ROLE_COMMUNITY, user: target });\n } catch { /* stake unreadable too — leave 0 */ }\n return { name: '', ensName: '', website: '', description: '', logoURI: '', stakeAmount };\n }\n\n // 3. Decode\n // struct CommunityRoleData { string name; string ensName; string website; string description; string logoURI; uint256 stakeAmount; }\n let dataToDecode = metadataHex;\n \n // Check for common 'bytes' or 'tuple' wrapper offset (0x20)\n if (metadataHex.startsWith('0x0000000000000000000000000000000000000000000000000000000000000020')) {\n dataToDecode = `0x${metadataHex.slice(66)}`; \n }\n\n const { decodeAbiParameters, parseAbiParameters } = await import('viem');\n const [name, ensName, website, description, logoURI, stakeAmount] = decodeAbiParameters(\n parseAbiParameters('string, string, string, string, string, uint256'),\n dataToDecode as Hex\n );\n\n return {\n name,\n ensName,\n website,\n description,\n logoURI,\n stakeAmount\n };\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Register self as a Community Manager.\n * This method handles all necessary steps:\n * 1. Checks and approves GToken to GTokenStaking\n * 2. Encodes CommunityRoleData with provided parameters\n * 3. Calls registerRoleSelf on Registry\n * \n * @param params Community registration parameters\n * @param options Transaction options\n * @returns Transaction hash\n */\n async registerAsCommunity(params: {\n name: string;\n ensName?: string;\n website?: string;\n description?: string;\n logoURI?: string;\n stakeAmount?: bigint;\n }, options?: TransactionOptions): Promise<Hash> {\n try {\n const registryAddr = this.requireRegistry();\n const registry = registryActions(registryAddr);\n const gTokenStakingAddr = this.requireGTokenStaking();\n const gTokenAddr = this.requireGToken();\n \n // 1. Get ROLE_COMMUNITY\n const roleCommunity = await registry(this.getStartPublicClient()).ROLE_COMMUNITY();\n \n // 2. Prepare stake amount (default 30 GToken as per Registry config)\n const stakeAmount = params.stakeAmount || parseEther('30');\n \n // 3. Check and approve GToken to GTokenStaking if needed\n const gToken = tokenActions();\n \n const allowance = await gToken(this.getStartPublicClient()).allowance({\n token: gTokenAddr,\n owner: this.getAddress(),\n spender: gTokenStakingAddr\n });\n \n if (allowance < stakeAmount) {\n const approveHash = await gToken(this.client).approve({\n token: gTokenAddr,\n spender: gTokenStakingAddr,\n amount: stakeAmount * BigInt(2), // Approve 2x for future use\n account: options?.account\n });\n await (this.getStartPublicClient() as any).waitForTransactionReceipt({ hash: approveHash });\n }\n \n // 4. Encode CommunityRoleData\n // struct CommunityRoleData { string name; string ensName; string website; string description; string logoURI; uint256 stakeAmount; }\n const communityData = encodeAbiParameters(\n parseAbiParameters('string, string, string, string, string, uint256'),\n [\n params.name,\n params.ensName || '',\n params.website || '',\n params.description || `${params.name} Community`,\n params.logoURI || '',\n stakeAmount\n ]\n );\n \n // 5. Register role\n return await registry(this.client).registerRoleSelf({\n roleId: roleCommunity,\n data: communityData,\n account: options?.account\n });\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * One-click Setup: Register Community + Deploy Token\n * Orchestrates the complete community initialization flow.\n */\n async setupCommunity(params: {\n name: string;\n tokenName: string;\n tokenSymbol: string;\n description?: string;\n logoURI?: string;\n website?: string;\n stakeAmount?: bigint;\n }, options?: TransactionOptions): Promise<{ tokenAddress: Address; hashes: Hash[] }> {\n const hashes: Hash[] = [];\n let tokenAddress: Address = '0x0000000000000000000000000000000000000000';\n\n // 1. Register as Community (Idempotent check handled inside or by registry)\n // We should check hasRole first to avoid errors if already registered\n const registry = registryActions(this.requireRegistry())(this.getStartPublicClient());\n const ROLE_COMMUNITY = await registry.ROLE_COMMUNITY();\n const hasRole = await registry.hasRole({ roleId: ROLE_COMMUNITY, user: this.getAddress() });\n\n if (!hasRole) {\n const hReg = await this.registerAsCommunity({\n name: params.name,\n ensName: params.website, // Mapping website to ENS param for now as per legacy behavior\n website: params.website,\n description: params.description,\n logoURI: params.logoURI,\n stakeAmount: params.stakeAmount\n }, options);\n hashes.push(hReg);\n \n // Critical: Factory requires caller to be registered in Registry.\n // We must wait for the registration to be mined.\n await (this.getStartPublicClient() as any).waitForTransactionReceipt({ hash: hReg });\n }\n\n // 2. Deploy Token (Idempotent check via Factory)\n if (this.factoryAddress) {\n const factoryReader = xPNTsFactoryActions(this.factoryAddress)(this.getStartPublicClient());\n const existingToken = await factoryReader.getTokenAddress({ community: this.getAddress() });\n\n if (existingToken && existingToken !== '0x0000000000000000000000000000000000000000') {\n tokenAddress = existingToken;\n } else {\n const hToken = await this.createCommunityToken({\n name: params.tokenName,\n tokenSymbol: params.tokenSymbol,\n description: params.description\n }, options);\n hashes.push(hToken);\n \n // Critical: Wait for token deployment to fetch the address\n await (this.getStartPublicClient() as any).waitForTransactionReceipt({ hash: hToken });\n \n // Fetch the actual address (with retries for latency)\n for (let i = 0; i < 5; i++) {\n tokenAddress = await factoryReader.getTokenAddress({ community: this.getAddress() });\n if (tokenAddress && tokenAddress !== '0x0000000000000000000000000000000000000000') break;\n await new Promise(r => setTimeout(r, 2000));\n }\n \n if (!tokenAddress || tokenAddress === '0x0000000000000000000000000000000000000000') {\n console.warn(`Warning: Token address not found after 10s. Factory might be slow indexing.`);\n }\n }\n }\n\n return { tokenAddress, hashes };\n }\n\n // ========================================\n // 2. 成员管理\n // ========================================\n\n /**\n * Airdrop SBTs to users to make them members\n */\n async airdropSBT(users: Address[], roleId: bigint, options?: TransactionOptions): Promise<Hash> {\n try {\n if (!this.sbtAddress) throw new Error('SBT address required for this client');\n const sbt = sbtActions(this.sbtAddress);\n\n if (users.length === 1) {\n // Convert roleId to Hex (bytes32)\n const roleIdHex = `0x${roleId.toString(16).padStart(64, '0')}` as Hash;\n\n return await sbt(this.client).mintForRole({\n user: users[0],\n roleId: roleIdHex,\n roleData: '0x',\n account: options?.account\n });\n }\n \n throw new Error('Batch airdrop not fully implemented in L1 yet, use single user');\n } catch (error) {\n throw error;\n }\n }\n\n // ========================================\n // 3. 信誉系统\n // ========================================\n\n async setReputationRule(ruleId: bigint, ruleConfig: any, options?: TransactionOptions): Promise<Hash> {\n try {\n if (!this.reputationAddress) throw new Error('Reputation address required for this client');\n const reputation = reputationActions(this.reputationAddress);\n \n const ruleIdHex = `0x${ruleId.toString(16).padStart(64, '0')}` as Hash;\n\n return await reputation(this.client).setReputationRule({\n ruleId: ruleIdHex,\n rule: ruleConfig,\n account: options?.account\n });\n } catch (error) {\n throw error;\n }\n }\n\n // ========================================\n // 4. 管理功能\n // ========================================\n\n /**\n * Revoke membership (Burn SBT)\n */\n async revokeMembership(userAddr: Address, options?: TransactionOptions): Promise<Hash> {\n try {\n if (!this.sbtAddress) throw new Error('SBT address required for this client');\n const sbt = sbtActions(this.sbtAddress);\n \n return await sbt(this.client).burnSBT({\n user: userAddr,\n account: options?.account\n });\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Transfer ownership of the Community Token\n */\n async transferCommunityTokenOwnership(tokenAddress: Address, newOwner: Address, options?: TransactionOptions): Promise<Hash> {\n try {\n const token = tokenActions()(this.client);\n \n return await token.transferOwnership({\n token: tokenAddress,\n newOwner,\n account: options?.account\n });\n } catch (error) {\n throw error;\n }\n }\n}\n","import { type Address, type Hash, type Hex, parseEther } from 'viem';\nimport { BaseClient, type ClientConfig, type TransactionOptions } from '@aastar/core';\nimport { registryActions, sbtActions, tokenActions, stakingActions, entryPointActions } from '@aastar/core'; // L2/L1 Actions\n\nexport interface GaslessConfig {\n paymasterUrl: string;\n policy?: 'CREDIT' | 'TOKEN' | 'SPONSORED';\n}\n\nexport interface UserLifecycleConfig extends ClientConfig {\n accountAddress: Address;\n registryAddress: Address;\n sbtAddress: Address;\n gTokenAddress: Address;\n gTokenStakingAddress: Address;\n entryPointAddress: Address;\n gasless?: GaslessConfig; // Optional gasless config\n}\n\nexport interface OnboardResult {\n success: boolean;\n sbtId?: bigint;\n txHash?: Hash;\n}\n\nexport interface ReputationData {\n score: bigint;\n level: bigint;\n creditLimit: bigint;\n}\n\n/**\n * UserLifecycle - L3 Pattern\n * \n * Responsibilities:\n * 1. Managing the complete lifecycle of an End User (Onboard -> Operate -> Exit)\n * 2. Providing a unified interface for Gasless operations\n * 3. Abstracting underlying contract interactions via L2 Actions\n */\nexport class UserLifecycle extends BaseClient {\n public accountAddress: Address;\n public registryAddress: Address;\n public sbtAddress: Address;\n public gTokenAddress: Address;\n public gTokenStakingAddress: Address;\n public entryPointAddress: Address;\n public gaslessConfig?: GaslessConfig;\n\n public config: UserLifecycleConfig;\n\n constructor(config: UserLifecycleConfig) {\n super(config);\n this.config = config;\n this.accountAddress = config.accountAddress;\n this.registryAddress = config.registryAddress;\n this.sbtAddress = config.sbtAddress;\n this.gTokenAddress = config.gTokenAddress;\n this.gTokenStakingAddress = config.gTokenStakingAddress;\n this.entryPointAddress = config.entryPointAddress;\n this.gaslessConfig = config.gasless;\n }\n\n // ===========================================\n // 1. Onboarding Phase (Registration)\n // ===========================================\n\n /**\n * Check if user is eligible to join a community\n * @param community Address of the community\n */\n async checkEligibility(community: Address): Promise<boolean> {\n // Validation logic (e.g., check blacklist or whitelist via Registry)\n const publicClient = this.getStartPublicClient();\n const registry = registryActions(this.registryAddress)(publicClient);\n // Placeholder: simplistic check, real logic might involve community specific rules\n return true; \n }\n\n /**\n * One-click Onboarding: Approve -> Stake -> Register -> Mint SBT\n * @param community Address of the community to join\n * @param stakeAmount Amount of GToken to stake (default 0.4 GT)\n */\n async onboard(community: Address, stakeAmount: bigint = parseEther('0.4')): Promise<OnboardResult> {\n try {\n const registry = registryActions(this.registryAddress)(this.getStartPublicClient());\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n registryAddress: this.registryAddress,\n gTokenStakingAddress: this.gTokenStakingAddress,\n gTokenAddress: this.gTokenAddress,\n sbtAddress: this.sbtAddress\n }));\n\n // Use UserClient's batch execution capability for atomic onboarding\n const txHash = await userClient.registerAsEndUser(community, stakeAmount);\n \n // Post-check: Verify role with retry\n let hasRole = false;\n for (let i = 0; i < 5; i++) {\n hasRole = await registry.hasRole({ \n roleId: await registry.ROLE_ENDUSER(), \n user: this.accountAddress \n });\n if (hasRole) break;\n await new Promise(r => setTimeout(r, 2000));\n }\n\n return {\n success: hasRole,\n txHash\n };\n } catch (error) {\n console.error(\"Onboarding failed:\", error);\n return { success: false };\n }\n }\n\n /**\n * Enable or update Gasless configuration\n */\n async enableGasless(config: GaslessConfig): Promise<void> {\n this.gaslessConfig = config;\n // In future: verify paymaster connection here\n }\n\n // ===========================================\n // 2. Operational Phase (Execute & Interact)\n // ===========================================\n\n /**\n * Execute a transaction effectively using Gasless configuration if available\n */\n async executeGaslessTx(params: {\n target: Address;\n value: bigint;\n data: Hex;\n operator?: Address; // Optional specific operator\n }): Promise<Hash> {\n if (!this.gaslessConfig) {\n throw new Error(\"Gasless configuration not enabled. Call enableGasless() first.\");\n }\n\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n // Pass minimal config needed for execution\n entryPointAddress: this.entryPointAddress,\n bundlerClient: (this.config as any).bundlerClient \n }));\n\n // Determine Paymaster Type based on policy\n const paymasterType = this.gaslessConfig.policy === 'CREDIT' ? 'Super' : 'V4'; \n // Note: Real implementation needs to resolve actual Paymaster Address from Registry/Config\n // This is a placeholder address resolution\n const registry = registryActions(this.registryAddress)(this.client);\n const paymasterAddress = await registry.SUPER_PAYMASTER(); \n\n return await userClient.executeGasless({\n target: params.target,\n value: params.value,\n data: params.data,\n paymaster: paymasterAddress,\n paymasterType,\n operator: params.operator\n });\n }\n\n async claimSBT(roleId: Hex, options?: TransactionOptions): Promise<Hash> {\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n sbtAddress: this.sbtAddress\n }));\n return await userClient.mintSBT(roleId, options);\n }\n\n // ===========================================\n // 3. Query Phase (Info & Stats)\n // ===========================================\n\n async getMyReputation(): Promise<ReputationData> {\n const publicClient = this.getStartPublicClient();\n const registry = registryActions(this.registryAddress)(publicClient);\n \n const [score, creditLimit] = await Promise.all([\n registry.globalReputation({ user: this.accountAddress }),\n registry.getCreditLimit({ user: this.accountAddress })\n ]);\n\n return {\n score,\n level: 0n, // TODO: Add level calculation logic\n creditLimit\n };\n }\n\n async getCreditLimit(): Promise<bigint> {\n const registry = registryActions(this.registryAddress)(this.client);\n return await registry.getCreditLimit({ user: this.accountAddress });\n }\n\n // ===========================================\n // 4. Exit Phase (Cleanup)\n // ===========================================\n\n async leaveCommunity(community: Address, options?: TransactionOptions): Promise<Hash> {\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n sbtAddress: this.sbtAddress\n }));\n return await userClient.leaveCommunity(community, options);\n }\n\n async exitRole(roleId: Hex, options?: TransactionOptions): Promise<Hash> {\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n registryAddress: this.registryAddress\n }));\n return await userClient.exitRole(roleId, options);\n }\n\n async unstakeAll(roleId: Hex, options?: TransactionOptions): Promise<Hash> {\n const userClient = await import('./UserClient.js').then(m => new m.UserClient({\n ...this.config,\n accountAddress: this.accountAddress,\n gTokenStakingAddress: this.gTokenStakingAddress\n }));\n return await userClient.unstakeFromRole(roleId, options);\n }\n}\n"]}