@aboutcircles/sdk 0.1.10 → 0.1.12
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/dist/Sdk.d.ts +5 -8
- package/dist/Sdk.d.ts.map +1 -1
- package/dist/Sdk.js +10 -35
- package/dist/avatars/HumanAvatar.d.ts +40 -146
- package/dist/avatars/HumanAvatar.d.ts.map +1 -1
- package/dist/avatars/HumanAvatar.js +55 -228
- package/dist/index.js +6059 -7352
- package/package.json +2 -1
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { ValidationError } from '@aboutcircles/sdk-utils';
|
|
2
2
|
import { SdkError } from '../errors';
|
|
3
3
|
import { BaseGroupContract } from '@aboutcircles/sdk-core';
|
|
4
|
-
import { encodeAbiParameters, parseAbiParameters, encodeFunctionData } from 'viem';
|
|
5
|
-
import { referralsModuleAbi } from '@aboutcircles/sdk-abis';
|
|
6
|
-
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
|
|
7
4
|
import { CommonAvatar } from './CommonAvatar';
|
|
5
|
+
import { Invitations, InviteFarm } from '@aboutcircles/sdk-invitations';
|
|
8
6
|
/**
|
|
9
7
|
* HumanAvatar class implementation
|
|
10
8
|
* Provides a simplified, user-friendly wrapper around Circles protocol for human avatars
|
|
@@ -96,252 +94,81 @@ export class HumanAvatar extends CommonAvatar {
|
|
|
96
94
|
// ============================================================================
|
|
97
95
|
// Trust methods are inherited from CommonAvatar
|
|
98
96
|
// ============================================================================
|
|
99
|
-
//
|
|
100
|
-
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Invitation methods using the Invitations module
|
|
99
|
+
// ============================================================================
|
|
100
|
+
_invitations = new Invitations(this.core.config);
|
|
101
|
+
_inviteFarm = new InviteFarm(this.core.config);
|
|
102
|
+
invitation = {
|
|
101
103
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* 1. Establishes trust with the invitee (with indefinite expiry)
|
|
106
|
-
* 2. Transfers 100 of your personal CRC tokens to the InvitationEscrow contract
|
|
107
|
-
*
|
|
108
|
-
* The tokens are held in escrow until the invitee redeems the invitation by registering.
|
|
109
|
-
*
|
|
110
|
-
* Requirements:
|
|
111
|
-
* - You must have at least 100 CRC available
|
|
112
|
-
* - Invitee must not be already registered in Circles
|
|
113
|
-
* - You can only have one active invitation per invitee
|
|
114
|
-
*
|
|
115
|
-
* @param invitee The address to invite
|
|
116
|
-
* @returns Transaction response
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* // Invite someone with 100 CRC (automatically establishes trust)
|
|
121
|
-
* await avatar.invite.send('0x123...');
|
|
122
|
-
* ```
|
|
104
|
+
* Get a referral code for inviting a new user who doesn't have a Safe wallet yet.
|
|
105
|
+
* Generates private key, finds proxy inviters, builds tx batch, saves referral data.
|
|
106
|
+
* @returns Transactions to execute and the private key to share with invitee
|
|
123
107
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// Create trust transaction (indefinite trust)
|
|
127
|
-
const trustTx = this.core.hubV2.trust(invitee, BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFF'));
|
|
128
|
-
// Get the token ID for this avatar's personal token
|
|
129
|
-
const tokenId = await this.core.hubV2.toTokenId(this.address);
|
|
130
|
-
// ABI-encode the invitee address as 32 bytes
|
|
131
|
-
const encodedInvitee = encodeAbiParameters(parseAbiParameters('address'), [invitee]);
|
|
132
|
-
// Create the safeTransferFrom transaction to the InvitationEscrow contract
|
|
133
|
-
const transferTx = this.core.hubV2.safeTransferFrom(this.address, this.core.config.invitationEscrowAddress, tokenId, BigInt(100e18), encodedInvitee);
|
|
134
|
-
// Batch both transactions: trust + invitation transfer
|
|
135
|
-
return await this.runner.sendTransaction([trustTx, transferTx]);
|
|
108
|
+
getReferralCode: async () => {
|
|
109
|
+
return this._invitations.generateReferral(this.address);
|
|
136
110
|
},
|
|
137
111
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* This returns the escrowed tokens (with demurrage applied) back to you
|
|
141
|
-
* as wrapped ERC20 tokens.
|
|
142
|
-
*
|
|
143
|
-
* @param invitee The address whose invitation to revoke
|
|
144
|
-
* @returns Transaction response
|
|
145
|
-
*
|
|
146
|
-
* @example
|
|
147
|
-
* ```typescript
|
|
148
|
-
* await avatar.invite.revoke('0x123...');
|
|
149
|
-
* ```
|
|
112
|
+
* Invite a user who already has a Safe wallet but is not yet registered in Circles.
|
|
113
|
+
* @param invitee Address of the invitee (must have existing Safe, NOT registered in Circles)
|
|
150
114
|
*/
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return await this.runner.sendTransaction([revokeTx]);
|
|
115
|
+
invite: async (invitee) => {
|
|
116
|
+
return this._invitations.generateInvite(this.address, invitee);
|
|
154
117
|
},
|
|
155
118
|
/**
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* as wrapped ERC20 tokens in a single transaction.
|
|
160
|
-
*
|
|
161
|
-
* @returns Transaction response
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```typescript
|
|
165
|
-
* await avatar.invite.revokeAll();
|
|
166
|
-
* ```
|
|
119
|
+
* Get proxy inviters who can facilitate invitations.
|
|
120
|
+
* These are addresses that trust this avatar, are trusted by the invitation module,
|
|
121
|
+
* and have sufficient balance (96 CRC per invite).
|
|
167
122
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return await this.runner.sendTransaction([revokeAllTx]);
|
|
123
|
+
getProxyInviters: async () => {
|
|
124
|
+
return this._invitations.getRealInviters(this.address);
|
|
171
125
|
},
|
|
172
126
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* This claims the escrowed tokens from a specific inviter and refunds
|
|
176
|
-
* all other inviters' escrows back to them.
|
|
177
|
-
*
|
|
178
|
-
* @param inviter The address of the inviter whose invitation to redeem
|
|
179
|
-
* @returns Transaction response
|
|
180
|
-
*
|
|
181
|
-
* @example
|
|
182
|
-
* ```typescript
|
|
183
|
-
* // Get all inviters first
|
|
184
|
-
* const inviters = await avatar.invite.getInviters();
|
|
185
|
-
*
|
|
186
|
-
* // Redeem invitation from the first inviter
|
|
187
|
-
* await avatar.invite.redeem(inviters[0]);
|
|
188
|
-
* ```
|
|
127
|
+
* Find a path from this avatar to the invitation module.
|
|
128
|
+
* @param proxyInviterAddress Optional specific proxy inviter to route through
|
|
189
129
|
*/
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const redeemTx = this.core.invitationEscrow.redeemInvitation(inviter);
|
|
193
|
-
return await this.runner.sendTransaction([redeemTx]);
|
|
130
|
+
findInvitePath: async (proxyInviterAddress) => {
|
|
131
|
+
return this._invitations.findInvitePath(this.address, proxyInviterAddress);
|
|
194
132
|
},
|
|
195
133
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* @returns Array of inviter addresses
|
|
199
|
-
*
|
|
200
|
-
* @example
|
|
201
|
-
* ```typescript
|
|
202
|
-
* const inviters = await avatar.invite.getInviters();
|
|
203
|
-
* console.log(`You have ${inviters.length} pending invitations`);
|
|
204
|
-
* ```
|
|
134
|
+
* Compute the deterministic Safe address for a given signer using CREATE2.
|
|
135
|
+
* @param signer The signer public address
|
|
205
136
|
*/
|
|
206
|
-
|
|
207
|
-
return
|
|
137
|
+
computeAddress: (signer) => {
|
|
138
|
+
return this._invitations.computeAddress(signer);
|
|
208
139
|
},
|
|
209
140
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* @returns Array of invitee addresses
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* ```typescript
|
|
216
|
-
* const invitees = await avatar.invite.getInvitees();
|
|
217
|
-
* console.log(`You have invited ${invitees.length} people`);
|
|
218
|
-
* ```
|
|
141
|
+
* Generate batch invitations using the InvitationFarm.
|
|
142
|
+
* @param count Number of invitations to generate
|
|
219
143
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
144
|
+
generateInvites: async (count) => {
|
|
145
|
+
const result = await this._inviteFarm.generateInvites(this.address, count);
|
|
146
|
+
const receipt = await this.runner.sendTransaction(result.transactions);
|
|
147
|
+
return {
|
|
148
|
+
secrets: result.invites.map((inv) => inv.secret),
|
|
149
|
+
signers: result.invites.map((inv) => inv.signer),
|
|
150
|
+
transactionReceipt: receipt,
|
|
151
|
+
};
|
|
222
152
|
},
|
|
223
|
-
/**
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
* // Check an invitation you sent
|
|
235
|
-
* const { escrowedAmount, days_ } = await avatar.invite.getEscrowedAmount(
|
|
236
|
-
* avatar.address,
|
|
237
|
-
* '0xinvitee...'
|
|
238
|
-
* );
|
|
239
|
-
* console.log(`Escrowed: ${CirclesConverter.attoCirclesToCircles(escrowedAmount)} CRC`);
|
|
240
|
-
* console.log(`Days since escrow: ${days_}`);
|
|
241
|
-
*
|
|
242
|
-
* // Check an invitation you received
|
|
243
|
-
* const { escrowedAmount, days_ } = await avatar.invite.getEscrowedAmount(
|
|
244
|
-
* '0xinviter...',
|
|
245
|
-
* avatar.address
|
|
246
|
-
* );
|
|
247
|
-
* ```
|
|
248
|
-
*/
|
|
249
|
-
getEscrowedAmount: async (inviter, invitee) => {
|
|
250
|
-
return await this.core.invitationEscrow.getEscrowedAmountAndDays(inviter, invitee);
|
|
153
|
+
/** Get the remaining invite quota for this avatar */
|
|
154
|
+
getQuota: async () => {
|
|
155
|
+
return this._inviteFarm.getQuota(this.address);
|
|
156
|
+
},
|
|
157
|
+
/** Get the invitation fee (96 CRC) */
|
|
158
|
+
getInvitationFee: async () => {
|
|
159
|
+
return this._inviteFarm.getInvitationFee();
|
|
160
|
+
},
|
|
161
|
+
/** Get the invitation module address from the farm */
|
|
162
|
+
getInvitationModule: async () => {
|
|
163
|
+
return this._inviteFarm.getInvitationModule();
|
|
251
164
|
},
|
|
252
165
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
* 1. Calls invitationFarm.claimInvites() to get invitation IDs via eth_call
|
|
257
|
-
* 2. Generates random secrets for each invitation
|
|
258
|
-
* 3. Derives signer addresses from the secrets using ECDSA
|
|
259
|
-
* 4. Batches the claimInvites write call with safeBatchTransferFrom to transfer
|
|
260
|
-
* invitation tokens (96 CRC each) to the invitation module
|
|
261
|
-
* 5. Returns the list of secrets and corresponding signers
|
|
262
|
-
*
|
|
263
|
-
* The data field in the batch transfer contains the count of generated secrets,
|
|
264
|
-
* which the contract uses to validate the transfer.
|
|
265
|
-
*
|
|
266
|
-
* @param numberOfInvites The number of invitations to generate
|
|
267
|
-
* @returns Promise containing arrays of secrets and signers for each generated invitation
|
|
268
|
-
*
|
|
269
|
-
* @throws {SdkError} If the transaction fails or invitations cannot be claimed
|
|
270
|
-
*
|
|
271
|
-
* @example
|
|
272
|
-
* ```typescript
|
|
273
|
-
* // Generate 5 invitations
|
|
274
|
-
* const result = await avatar.invite.generateInvites(5n);
|
|
275
|
-
*
|
|
276
|
-
* console.log('Generated invitations:');
|
|
277
|
-
* result.secrets.forEach((secret, index) => {
|
|
278
|
-
* console.log(`Invitation ${index + 1}:`);
|
|
279
|
-
* console.log(` Secret: ${secret}`);
|
|
280
|
-
* console.log(` Signer: ${result.signers[index]}`);
|
|
281
|
-
* });
|
|
282
|
-
* ```
|
|
166
|
+
* List referrals for this avatar with key previews.
|
|
167
|
+
* @param limit Max referrals to return (default 10)
|
|
168
|
+
* @param offset Pagination offset (default 0)
|
|
283
169
|
*/
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
throw SdkError.operationFailed('generateInvites', 'numberOfInvites must be greater than 0');
|
|
287
|
-
}
|
|
288
|
-
// Step 1: Call eth_call to claimInvites to get invitation IDs (read-only simulation)
|
|
289
|
-
// This simulates the claimInvites call without actually modifying state
|
|
290
|
-
// to get the IDs that would be returned
|
|
291
|
-
const ids = (await this.core.invitationFarm.read('claimInvites', [numberOfInvites], {
|
|
292
|
-
from: this.address
|
|
293
|
-
}));
|
|
294
|
-
console.log("ids", ids);
|
|
295
|
-
if (!ids || ids.length === 0) {
|
|
296
|
-
throw SdkError.operationFailed('generateInvites', 'No invitation IDs returned from claimInvites');
|
|
297
|
-
}
|
|
298
|
-
// Step 2: Generate random secrets and derive signers
|
|
299
|
-
const secrets = [];
|
|
300
|
-
const signers = [];
|
|
301
|
-
for (let i = 0; i < numberOfInvites; i++) {
|
|
302
|
-
// Generate a random private key
|
|
303
|
-
const privateKey = generatePrivateKey();
|
|
304
|
-
secrets.push(privateKey);
|
|
305
|
-
// Derive the signer address from the private key
|
|
306
|
-
const account = privateKeyToAccount(privateKey);
|
|
307
|
-
signers.push(account.address.toLowerCase());
|
|
308
|
-
}
|
|
309
|
-
// Step 3: Get invitation module address
|
|
310
|
-
const invitationModuleAddress = await this.core.invitationFarm.invitationModule();
|
|
311
|
-
// Step 4: Referrals module address
|
|
312
|
-
const referralsModuleAddress = this.core.config.referralsModuleAddress;
|
|
313
|
-
// Step 5: Build the batch transaction
|
|
314
|
-
// - claimInvites write call (to actually claim the invites)
|
|
315
|
-
// - safeBatchTransferFrom to transfer invitation tokens to the invitation module
|
|
316
|
-
// Create the claimInvites write transaction
|
|
317
|
-
const claimInvitesWriteTx = this.core.invitationFarm.claimInvites(numberOfInvites);
|
|
318
|
-
// Step 6: Encode the createAccounts function call to the referrals module
|
|
319
|
-
// This call will be executed by the invitation module via the generic call proxy
|
|
320
|
-
const createAccountsCallData = encodeFunctionData({
|
|
321
|
-
abi: referralsModuleAbi,
|
|
322
|
-
functionName: 'createAccounts',
|
|
323
|
-
args: [signers],
|
|
324
|
-
});
|
|
325
|
-
// Step 7: Create safeBatchTransferFrom transaction to transfer invitation tokens to the invitation module
|
|
326
|
-
// - from: this avatar
|
|
327
|
-
// - to: invitation module
|
|
328
|
-
// - ids: the invitation IDs returned from claimInvites
|
|
329
|
-
// - amounts: all 96 CRC (96 * 10^18) per invitation
|
|
330
|
-
// - data: encoded as (address referralsModule, bytes callData) for the invitation module to execute
|
|
331
|
-
const amounts = [];
|
|
332
|
-
for (let i = 0; i < ids.length; i++) {
|
|
333
|
-
amounts.push(BigInt(96e18)); // 96 CRC in atto-circles
|
|
334
|
-
}
|
|
335
|
-
// Encode the data as (address, bytes) - referrals module address + createAccounts call data
|
|
336
|
-
const encodedData = encodeAbiParameters(parseAbiParameters('address, bytes'), [referralsModuleAddress, createAccountsCallData]);
|
|
337
|
-
const batchTransferTx = this.core.hubV2.safeBatchTransferFrom(this.address, invitationModuleAddress, ids, amounts, encodedData);
|
|
338
|
-
// Step 7: Execute the batch transaction
|
|
339
|
-
const receipt = await this.runner.sendTransaction([claimInvitesWriteTx, batchTransferTx]);
|
|
340
|
-
return {
|
|
341
|
-
secrets,
|
|
342
|
-
signers,
|
|
343
|
-
transactionReceipt: receipt,
|
|
344
|
-
};
|
|
170
|
+
listReferrals: async (limit = 10, offset = 0) => {
|
|
171
|
+
return this._inviteFarm.listReferrals(this.address, limit, offset);
|
|
345
172
|
},
|
|
346
173
|
};
|
|
347
174
|
// Personal token / Minting methods
|