@aboutcircles/sdk-rpc 0.1.28 → 0.1.30

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 (40) hide show
  1. package/dist/client.d.ts +9 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +58 -11
  4. package/dist/index.js +2 -2
  5. package/dist/methods/group.d.ts +30 -60
  6. package/dist/methods/group.d.ts.map +1 -1
  7. package/dist/methods/group.js +86 -160
  8. package/dist/methods/index.d.ts +1 -0
  9. package/dist/methods/index.d.ts.map +1 -1
  10. package/dist/methods/index.js +1 -0
  11. package/dist/methods/invitation.d.ts +99 -5
  12. package/dist/methods/invitation.d.ts.map +1 -1
  13. package/dist/methods/invitation.js +130 -164
  14. package/dist/methods/profile.d.ts +12 -4
  15. package/dist/methods/profile.d.ts.map +1 -1
  16. package/dist/methods/profile.js +16 -43
  17. package/dist/methods/query.d.ts +38 -9
  18. package/dist/methods/query.d.ts.map +1 -1
  19. package/dist/methods/query.js +38 -13
  20. package/dist/methods/sdk.d.ts +142 -0
  21. package/dist/methods/sdk.d.ts.map +1 -0
  22. package/dist/methods/sdk.js +165 -0
  23. package/dist/methods/token.d.ts +9 -15
  24. package/dist/methods/token.d.ts.map +1 -1
  25. package/dist/methods/token.js +14 -39
  26. package/dist/methods/transaction.d.ts +20 -21
  27. package/dist/methods/transaction.d.ts.map +1 -1
  28. package/dist/methods/transaction.js +32 -89
  29. package/dist/methods/trust.d.ts +30 -6
  30. package/dist/methods/trust.d.ts.map +1 -1
  31. package/dist/methods/trust.js +46 -50
  32. package/dist/pagedQuery.d.ts +7 -49
  33. package/dist/pagedQuery.d.ts.map +1 -1
  34. package/dist/pagedQuery.js +17 -146
  35. package/dist/rpc.d.ts +8 -3
  36. package/dist/rpc.d.ts.map +1 -1
  37. package/dist/rpc.js +14 -4
  38. package/dist/types.d.ts +4 -5
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +1 -1
@@ -1,25 +1,38 @@
1
1
  import { normalizeAddress, checksumAddresses } from '../utils.js';
2
2
  /**
3
3
  * Invitation RPC methods
4
+ *
5
+ * All methods delegate to dedicated RPC endpoints for server-side SQL optimization.
4
6
  */
5
7
  export class InvitationMethods {
6
8
  client;
7
9
  constructor(client) {
8
10
  this.client = client;
9
11
  }
10
- transformQueryResponse(response) {
11
- const { columns, rows } = response;
12
- return rows.map((row) => {
13
- const obj = {};
14
- columns.forEach((col, index) => {
15
- obj[col] = row[index];
16
- });
17
- return obj;
18
- });
12
+ /**
13
+ * Get the invitation origin for an address — how they were invited to Circles
14
+ *
15
+ * @param address - The address of the invited avatar
16
+ * @returns Full invitation origin details or null if not registered
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const origin = await rpc.invitation.getInvitationOrigin('0xde374ece6fa50e781e81aac78e811b33d16912c7');
21
+ * console.log(origin?.invitationType); // 'v2_standard', 'v2_escrow', 'v2_at_scale', 'v1_signup'
22
+ * console.log(origin?.inviter); // '0x...' or null
23
+ * ```
24
+ */
25
+ async getInvitationOrigin(address) {
26
+ const normalized = normalizeAddress(address);
27
+ const response = await this.client.call('circles_getInvitationOrigin', [normalized]);
28
+ return response ? checksumAddresses(response) : null;
19
29
  }
20
30
  /**
21
31
  * Get the avatar that invited a specific avatar
22
32
  *
33
+ * Uses `circles_getInvitationOrigin` for a single optimized query that checks
34
+ * all invitation mechanisms (at-scale, escrow, v2 standard, v1 signup).
35
+ *
23
36
  * @param address - The address of the invited avatar
24
37
  * @returns The address of the inviting avatar or undefined if not found
25
38
  *
@@ -30,38 +43,32 @@ export class InvitationMethods {
30
43
  * ```
31
44
  */
32
45
  async getInvitedBy(address) {
33
- const normalized = normalizeAddress(address);
34
- const results = await this.client.call('circles_query', [
35
- {
36
- Namespace: 'CrcV2',
37
- Table: 'RegisterHuman',
38
- Columns: ['inviter'],
39
- Filter: [
40
- {
41
- Type: 'FilterPredicate',
42
- FilterType: 'Equals',
43
- Column: 'avatar',
44
- Value: normalized,
45
- },
46
- ],
47
- Order: [
48
- {
49
- Column: 'blockNumber',
50
- SortOrder: 'DESC',
51
- },
52
- ],
53
- Limit: 1,
54
- },
55
- ]);
56
- if (results.length > 0) {
57
- return checksumAddresses(results[0].inviter);
46
+ const origin = await this.getInvitationOrigin(address);
47
+ if (origin?.inviter) {
48
+ return checksumAddresses(origin.inviter);
58
49
  }
59
50
  return undefined;
60
51
  }
52
+ /**
53
+ * Get trust-based invitations (addresses that trust you with sufficient balance)
54
+ *
55
+ * Uses dedicated `circles_getTrustInvitations` endpoint.
56
+ *
57
+ * @param address - The address to check for trust invitations
58
+ * @param minimumBalance - Optional minimum balance threshold (as CRC string)
59
+ * @returns Array of trust invitations
60
+ */
61
+ async getTrustInvitations(address, minimumBalance) {
62
+ const normalized = normalizeAddress(address);
63
+ const response = await this.client.call('circles_getTrustInvitations', minimumBalance ? [normalized, minimumBalance] : [normalized]);
64
+ return checksumAddresses(response);
65
+ }
61
66
  /**
62
67
  * Get the list of avatars who have invited this avatar
63
68
  * Checks v2 trust relations and validates that inviters have enough balance
64
69
  *
70
+ * Uses the native RPC method for efficient server-side filtering and validation.
71
+ *
65
72
  * @param address - The address to check for invitations
66
73
  * @returns Array of avatar info for valid inviters
67
74
  *
@@ -71,73 +78,33 @@ export class InvitationMethods {
71
78
  * console.log(invitations); // Array of AvatarInfo
72
79
  * ```
73
80
  */
74
- async getInvitations(address) {
81
+ async getInvitations(address, minimumBalance) {
82
+ const response = await this.getValidInviters(address, minimumBalance);
83
+ const inviters = response.results
84
+ .map((entry) => entry.avatarInfo)
85
+ .filter((info) => info !== undefined && info !== null);
86
+ return checksumAddresses(inviters);
87
+ }
88
+ /**
89
+ * Fetch valid inviters along with balances and avatar info
90
+ *
91
+ * @param address - Address to find inviters for
92
+ * @param minimumBalance - Optional minimum balance to filter inviters
93
+ * @returns Valid inviters response as provided by the RPC host
94
+ */
95
+ async getValidInviters(address, minimumBalance) {
75
96
  const normalized = normalizeAddress(address);
76
- const MIN_TOKENS_REQUIRED = 96;
77
- // Check if the avatar is still on v1
78
- const avatarInfoResults = await this.client.call('circles_getAvatarInfoBatch', [[normalized]]);
79
- const avatarInfo = avatarInfoResults.length > 0 ? avatarInfoResults[0] : undefined;
80
- if (avatarInfo?.version === 2) {
81
- // Already on v2, no invitations needed
82
- return [];
83
- }
84
- // Get trust relations where others trust this avatar
85
- const response = await this.client.call('circles_query', [
86
- {
87
- Namespace: 'V_Crc',
88
- Table: 'TrustRelations',
89
- Columns: ['truster', 'trustee'],
90
- Filter: [
91
- {
92
- Type: 'Conjunction',
93
- ConjunctionType: 'And',
94
- Predicates: [
95
- {
96
- Type: 'FilterPredicate',
97
- FilterType: 'Equals',
98
- Column: 'version',
99
- Value: 2,
100
- },
101
- {
102
- Type: 'FilterPredicate',
103
- FilterType: 'Equals',
104
- Column: 'trustee',
105
- Value: normalized,
106
- },
107
- ],
108
- },
109
- ],
110
- Order: [],
111
- },
112
- ]);
113
- const trustRelations = this.transformQueryResponse(response);
114
- const v2Trusters = trustRelations.map((r) => r.truster);
115
- if (v2Trusters.length === 0) {
116
- return [];
117
- }
118
- // Get avatar info for all trusters
119
- const trusterInfos = await this.client.call('circles_getAvatarInfoBatch', [v2Trusters]);
120
- const humanInviters = [];
121
- for (const trusterInfo of trusterInfos) {
122
- // Only humans can invite other humans
123
- if (!trusterInfo?.isHuman) {
124
- continue;
125
- }
126
- // Check if the inviter has enough tokens
127
- const balances = await this.client.call('circles_getTokenBalances', [trusterInfo.avatar]);
128
- const inviterOwnToken = balances.find((b) => normalizeAddress(b.tokenAddress) === normalizeAddress(trusterInfo.avatar));
129
- if (inviterOwnToken && inviterOwnToken.circles >= MIN_TOKENS_REQUIRED) {
130
- humanInviters.push(trusterInfo);
131
- }
132
- }
133
- return checksumAddresses(humanInviters);
97
+ const response = await this.client.call('circles_getValidInviters', minimumBalance ? [normalized, minimumBalance] : [normalized]);
98
+ return checksumAddresses(response);
134
99
  }
135
100
  /**
136
101
  * Get the list of accounts that were invited by a specific avatar
137
102
  *
103
+ * Uses dedicated `circles_getInvitationsFrom` endpoint with server-side SQL.
104
+ *
138
105
  * @param address - The address of the inviter
139
106
  * @param accepted - If true, returns accepted invitations; if false, returns pending invitations
140
- * @returns Array of invited addresses
107
+ * @returns Enriched response with invited account info and avatar data
141
108
  *
142
109
  * @example
143
110
  * ```typescript
@@ -146,85 +113,84 @@ export class InvitationMethods {
146
113
  * '0xde374ece6fa50e781e81aac78e811b33d16912c7',
147
114
  * true
148
115
  * );
116
+ * console.log(accepted.results); // [{address, status: 'accepted', avatarInfo, ...}]
149
117
  *
150
118
  * // Get pending invitations
151
119
  * const pending = await rpc.invitation.getInvitationsFrom(
152
120
  * '0xde374ece6fa50e781e81aac78e811b33d16912c7',
153
121
  * false
154
122
  * );
123
+ * console.log(pending.results); // [{address, status: 'pending'}]
155
124
  * ```
156
125
  */
157
126
  async getInvitationsFrom(address, accepted = false) {
158
127
  const normalized = normalizeAddress(address);
159
- if (accepted) {
160
- // Query for accounts that have registered using this avatar as inviter
161
- const response = await this.client.call('circles_query', [
162
- {
163
- Namespace: 'CrcV2',
164
- Table: 'RegisterHuman',
165
- Columns: ['avatar'],
166
- Filter: [
167
- {
168
- Type: 'FilterPredicate',
169
- FilterType: 'Equals',
170
- Column: 'inviter',
171
- Value: normalized,
172
- },
173
- ],
174
- Order: [
175
- {
176
- Column: 'blockNumber',
177
- SortOrder: 'DESC',
178
- },
179
- ],
180
- },
181
- ]);
182
- const results = this.transformQueryResponse(response);
183
- const avatars = results.map((r) => r.avatar);
184
- return checksumAddresses(avatars);
185
- }
186
- else {
187
- // Find accounts that this avatar trusts without mutual trust
188
- const response = await this.client.call('circles_query', [
189
- {
190
- Namespace: 'V_Crc',
191
- Table: 'TrustRelations',
192
- Columns: ['trustee', 'truster'],
193
- Filter: [
194
- {
195
- Type: 'Conjunction',
196
- ConjunctionType: 'And',
197
- Predicates: [
198
- {
199
- Type: 'FilterPredicate',
200
- FilterType: 'Equals',
201
- Column: 'version',
202
- Value: 2,
203
- },
204
- {
205
- Type: 'FilterPredicate',
206
- FilterType: 'Equals',
207
- Column: 'truster',
208
- Value: normalized,
209
- },
210
- ],
211
- },
212
- ],
213
- Order: [],
214
- },
215
- ]);
216
- const trustRelations = this.transformQueryResponse(response);
217
- const v2Trusted = trustRelations.map((r) => r.trustee);
218
- if (v2Trusted.length === 0) {
219
- return [];
220
- }
221
- // Get avatar info for trusted accounts
222
- const trustedAvatarsInfo = await this.client.call('circles_getAvatarInfoBatch', [v2Trusted]);
223
- // Create a Set of registered avatars (filter out null values) - normalize for comparison
224
- const registeredAvatarsSet = new Set(trustedAvatarsInfo.filter((a) => a !== null).map((a) => normalizeAddress(a.avatar)));
225
- // Return only unregistered accounts (pending invitations)
226
- const pending = v2Trusted.filter((addr) => !registeredAvatarsSet.has(normalizeAddress(addr)));
227
- return checksumAddresses(pending);
228
- }
128
+ const response = await this.client.call('circles_getInvitationsFrom', [normalized, accepted]);
129
+ return checksumAddresses(response);
130
+ }
131
+ /**
132
+ * Get escrow-based invitations for an address
133
+ *
134
+ * Uses dedicated `circles_getEscrowInvitations` endpoint which handles all filtering
135
+ * server-side (redeemed, revoked, refunded) in a single optimized SQL query.
136
+ *
137
+ * @param address - The address to check for escrow invitations
138
+ * @returns Array of active escrow invitations
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * const escrowInvites = await rpc.invitation.getEscrowInvitations('0xde374ece6fa50e781e81aac78e811b33d16912c7');
143
+ * console.log(escrowInvites); // Array of EscrowInvitation
144
+ * ```
145
+ */
146
+ async getEscrowInvitations(address) {
147
+ const normalized = normalizeAddress(address);
148
+ const response = await this.client.call('circles_getEscrowInvitations', [normalized]);
149
+ return checksumAddresses(response);
150
+ }
151
+ /**
152
+ * Get at-scale invitations for an address
153
+ *
154
+ * Uses dedicated `circles_getAtScaleInvitations` endpoint which checks for
155
+ * unclaimed pre-created accounts in a single optimized SQL query.
156
+ *
157
+ * @param address - The address to check for at-scale invitations
158
+ * @returns Array of at-scale invitations (unclaimed pre-created accounts)
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * const atScaleInvites = await rpc.invitation.getAtScaleInvitations('0xde374ece6fa50e781e81aac78e811b33d16912c7');
163
+ * console.log(atScaleInvites); // Array of AtScaleInvitation
164
+ * ```
165
+ */
166
+ async getAtScaleInvitations(address) {
167
+ const normalized = normalizeAddress(address);
168
+ const response = await this.client.call('circles_getAtScaleInvitations', [normalized]);
169
+ return checksumAddresses(response);
170
+ }
171
+ /**
172
+ * Get all invitations from all sources (trust, escrow, at-scale)
173
+ * This is the recommended method to use for getting a complete view of available invitations
174
+ *
175
+ * Uses the optimized `circles_getAllInvitations` RPC method which fetches all invitation
176
+ * types in a single round-trip with server-side SQL JOINs for efficiency.
177
+ *
178
+ * @param address - The address to check for invitations
179
+ * @param minimumBalance - Optional minimum balance for trust-based invitations
180
+ * @returns All invitations from all sources
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const allInvites = await rpc.invitation.getAllInvitations('0xde374ece6fa50e781e81aac78e811b33d16912c7');
185
+ * console.log(`Trust invites: ${allInvites.trustInvitations.length}`);
186
+ * console.log(`Escrow invites: ${allInvites.escrowInvitations.length}`);
187
+ * console.log(`At-scale invites: ${allInvites.atScaleInvitations.length}`);
188
+ * ```
189
+ */
190
+ async getAllInvitations(address, minimumBalance) {
191
+ const normalized = normalizeAddress(address);
192
+ // Use the optimized RPC method that fetches all invitation types in a single call
193
+ const response = await this.client.call('circles_getAllInvitations', minimumBalance ? [normalized, minimumBalance] : [normalized]);
194
+ return checksumAddresses(response);
229
195
  }
230
196
  }
@@ -1,5 +1,5 @@
1
1
  import type { RpcClient } from '../client.js';
2
- import type { Address, Profile } from '@aboutcircles/sdk-types';
2
+ import type { Address, Profile, ProfileView, ProfileSearchResponse } from '@aboutcircles/sdk-types';
3
3
  import type { SearchResultProfile } from '../types.js';
4
4
  /**
5
5
  * Profile RPC methods
@@ -91,9 +91,9 @@ export declare class ProfileMethods {
91
91
  *
92
92
  * @param query - Search query (address or username)
93
93
  * @param limit - Maximum number of results (default: 10)
94
- * @param offset - Offset for pagination (default: 0)
94
+ * @param cursor - Pagination cursor from previous response (null for first page)
95
95
  * @param avatarTypes - Optional array of avatar types to filter by
96
- * @returns Array of matching profiles, with exact address match (if valid) at the top
96
+ * @returns Search results with profiles and search type indicator
97
97
  *
98
98
  * @example
99
99
  * ```typescript
@@ -104,6 +104,14 @@ export declare class ProfileMethods {
104
104
  * const results = await rpc.profile.searchByAddressOrName('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', 20);
105
105
  * ```
106
106
  */
107
- searchByAddressOrName(query: string, limit?: number, offset?: number, avatarTypes?: string[]): Promise<SearchResultProfile[]>;
107
+ searchByAddressOrName(query: string, limit?: number, cursor?: string | null, avatarTypes?: string[]): Promise<ProfileSearchResponse>;
108
+ /**
109
+ * Get a consolidated profile view
110
+ * Combines avatar info, profile data, trust stats, and balances in a single call
111
+ *
112
+ * @param address - The address to get the view for
113
+ * @returns Profile view data
114
+ */
115
+ getProfileView(address: Address): Promise<ProfileView>;
108
116
  }
109
117
  //# sourceMappingURL=profile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/methods/profile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD;;GAEG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAErC;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3D;;;;;;;;;;;;;;OAcG;IACG,oBAAoB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAOhF;;;;;;;;;;;OAWG;IACG,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAMpE;;;;;;;;;;;;;;OAcG;IACG,wBAAwB,CAAC,SAAS,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAO1F;;;;;;;;;;;;;;;;;OAiBG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,EAClB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAYjC;;;;;;;;;;;;;;;;;;;OAmBG;IACG,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,EAClB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;CA8ClC"}
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/methods/profile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD;;GAEG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAErC;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI3D;;;;;;;;;;;;;;OAcG;IACG,oBAAoB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAOhF;;;;;;;;;;;OAWG;IACG,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAMpE;;;;;;;;;;;;;;OAcG;IACG,wBAAwB,CAAC,SAAS,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAO1F;;;;;;;;;;;;;;;;;OAiBG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAU,EAClB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAYjC;;;;;;;;;;;;;;;;;;;OAmBG;IACG,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,qBAAqB,CAAC;IAMjC;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;CAK7D"}
@@ -108,9 +108,9 @@ export class ProfileMethods {
108
108
  *
109
109
  * @param query - Search query (address or username)
110
110
  * @param limit - Maximum number of results (default: 10)
111
- * @param offset - Offset for pagination (default: 0)
111
+ * @param cursor - Pagination cursor from previous response (null for first page)
112
112
  * @param avatarTypes - Optional array of avatar types to filter by
113
- * @returns Array of matching profiles, with exact address match (if valid) at the top
113
+ * @returns Search results with profiles and search type indicator
114
114
  *
115
115
  * @example
116
116
  * ```typescript
@@ -121,46 +121,19 @@ export class ProfileMethods {
121
121
  * const results = await rpc.profile.searchByAddressOrName('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', 20);
122
122
  * ```
123
123
  */
124
- async searchByAddressOrName(query, limit = 10, offset = 0, avatarTypes) {
125
- const results = [];
126
- // Check if query is a valid address
127
- const isAddress = /^0x[a-fA-F0-9]{40}$/.test(query);
128
- if (isAddress) {
129
- // Try to get profile by address first
130
- try {
131
- const profile = await this.getProfileByAddress(query);
132
- if (profile) {
133
- // Convert Profile to SearchResultProfile by adding address
134
- const searchResult = {
135
- ...profile,
136
- address: query
137
- };
138
- // Check if profile matches avatar type filter
139
- if (!avatarTypes || !searchResult.avatarType || avatarTypes.includes(searchResult.avatarType)) {
140
- results.push(searchResult);
141
- }
142
- }
143
- }
144
- catch (error) {
145
- console.warn('Failed to get profile by address:', error);
146
- }
147
- }
148
- // Always search by text as well
149
- try {
150
- const textResults = await this.searchProfiles(query, limit, offset, avatarTypes);
151
- // If we already added an address match, filter it out from text results to avoid duplicates
152
- if (isAddress && results.length > 0) {
153
- const addressLower = query.toLowerCase();
154
- const filteredResults = textResults.filter(p => p.address?.toLowerCase() !== addressLower);
155
- results.push(...filteredResults);
156
- }
157
- else {
158
- results.push(...textResults);
159
- }
160
- }
161
- catch (error) {
162
- console.warn('Failed to search profiles by text:', error);
163
- }
164
- return results.slice(0, limit);
124
+ async searchByAddressOrName(query, limit = 10, cursor, avatarTypes) {
125
+ return this.client.call('circles_searchProfileByAddressOrName', avatarTypes ? [query, limit, cursor ?? null, avatarTypes] : [query, limit, cursor ?? null]);
126
+ }
127
+ /**
128
+ * Get a consolidated profile view
129
+ * Combines avatar info, profile data, trust stats, and balances in a single call
130
+ *
131
+ * @param address - The address to get the view for
132
+ * @returns Profile view data
133
+ */
134
+ async getProfileView(address) {
135
+ return this.client.call('circles_getProfileView', [
136
+ normalizeAddress(address),
137
+ ]);
165
138
  }
166
139
  }
@@ -1,5 +1,21 @@
1
1
  import type { RpcClient } from '../client.js';
2
2
  import type { QueryParams, TableInfo, EventType } from '@aboutcircles/sdk-types';
3
+ /**
4
+ * Filter predicate for advanced event queries
5
+ */
6
+ export interface FilterPredicate {
7
+ column: string;
8
+ filterType: string;
9
+ value: string;
10
+ }
11
+ /**
12
+ * Paginated events response
13
+ */
14
+ export interface PagedEventsResponse<T = unknown> {
15
+ events: T[];
16
+ hasMore: boolean;
17
+ nextCursor: string | null;
18
+ }
3
19
  /**
4
20
  * Query and table RPC methods
5
21
  */
@@ -54,26 +70,39 @@ export declare class QueryMethods {
54
70
  */
55
71
  tables(): Promise<TableInfo[]>;
56
72
  /**
57
- * Query events of specific types within a block range
73
+ * Query events of specific types within a block range with pagination support.
58
74
  *
75
+ * @param address - Optional address filter (null for all addresses)
59
76
  * @param fromBlock - Starting block number (null for genesis)
60
77
  * @param toBlock - Ending block number (null for latest)
61
78
  * @param eventTypes - Array of event types to filter (null for all)
62
- * @param address - Optional address filter
63
- * @param includeTransactionData - Whether to include transaction data
64
- * @returns Array of events
79
+ * @param filterPredicates - Advanced filter predicates (null for none)
80
+ * @param sortAscending - Sort order (default: false = descending)
81
+ * @param limit - Maximum events to return (default: 100, max: 1000)
82
+ * @param cursor - Pagination cursor from previous response (null for first page)
83
+ * @returns Paginated events response with events array, hasMore flag, and nextCursor
65
84
  *
66
85
  * @example
67
86
  * ```typescript
68
- * const events = await rpc.query.events(
87
+ * // Basic usage - get first page of events for an address
88
+ * const result = await rpc.query.events(
89
+ * '0xde374ece6fa50e781e81aac78e811b33d16912c7',
69
90
  * 38000000,
70
91
  * null,
71
- * ['CrcV1_Trust'],
72
- * null,
73
- * false
92
+ * ['CrcV1_Trust']
74
93
  * );
94
+ * console.log(result.events);
95
+ * console.log(result.hasMore, result.nextCursor);
96
+ *
97
+ * // Paginate through results
98
+ * let cursor: string | null = null;
99
+ * do {
100
+ * const page = await rpc.query.events(address, fromBlock, null, null, null, false, 100, cursor);
101
+ * console.log(page.events);
102
+ * cursor = page.nextCursor;
103
+ * } while (cursor);
75
104
  * ```
76
105
  */
77
- events<T = unknown>(fromBlock: number | null, toBlock: number | null, eventTypes?: EventType[] | null, address?: string | null, includeTransactionData?: boolean): Promise<T[]>;
106
+ events<T = unknown>(address?: string | null, fromBlock?: number | null, toBlock?: number | null, eventTypes?: EventType[] | null, filterPredicates?: FilterPredicate[] | null, sortAscending?: boolean, limit?: number, cursor?: string | null): Promise<PagedEventsResponse<T>>;
78
107
  }
79
108
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/methods/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGjF;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAK3D;;;;;;;;;;OAUG;IACG,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpC;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,MAAM,CAAC,CAAC,GAAG,OAAO,EACtB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,UAAU,GAAE,SAAS,EAAE,GAAG,IAAW,EACrC,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,sBAAsB,GAAE,OAAe,GACtC,OAAO,CAAC,CAAC,EAAE,CAAC;CAOhB"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/methods/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAqC,MAAM,yBAAyB,CAAC;AAGpH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAa3D;;;;;;;;;;OAUG;IACG,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACG,MAAM,CAAC,CAAC,GAAG,OAAO,EACtB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,UAAU,GAAE,SAAS,EAAE,GAAG,IAAW,EACrC,gBAAgB,GAAE,eAAe,EAAE,GAAG,IAAW,EACjD,aAAa,GAAE,OAAe,EAC9B,KAAK,GAAE,MAAY,EACnB,MAAM,GAAE,MAAM,GAAG,IAAW,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAYnC"}
@@ -42,8 +42,16 @@ export class QueryMethods {
42
42
  * ```
43
43
  */
44
44
  async query(params) {
45
- const result = await this.client.call('circles_query', [params]);
46
- return checksumAddresses(result);
45
+ const response = await this.client.call('circles_query', [params]);
46
+ const { columns, rows } = response;
47
+ const objects = rows.map(row => {
48
+ const obj = {};
49
+ columns.forEach((col, index) => {
50
+ obj[col] = row[index];
51
+ });
52
+ return obj;
53
+ });
54
+ return checksumAddresses(objects);
47
55
  }
48
56
  /**
49
57
  * Return all available namespaces and tables which can be queried
@@ -60,28 +68,45 @@ export class QueryMethods {
60
68
  return this.client.call('circles_tables', []);
61
69
  }
62
70
  /**
63
- * Query events of specific types within a block range
71
+ * Query events of specific types within a block range with pagination support.
64
72
  *
73
+ * @param address - Optional address filter (null for all addresses)
65
74
  * @param fromBlock - Starting block number (null for genesis)
66
75
  * @param toBlock - Ending block number (null for latest)
67
76
  * @param eventTypes - Array of event types to filter (null for all)
68
- * @param address - Optional address filter
69
- * @param includeTransactionData - Whether to include transaction data
70
- * @returns Array of events
77
+ * @param filterPredicates - Advanced filter predicates (null for none)
78
+ * @param sortAscending - Sort order (default: false = descending)
79
+ * @param limit - Maximum events to return (default: 100, max: 1000)
80
+ * @param cursor - Pagination cursor from previous response (null for first page)
81
+ * @returns Paginated events response with events array, hasMore flag, and nextCursor
71
82
  *
72
83
  * @example
73
84
  * ```typescript
74
- * const events = await rpc.query.events(
85
+ * // Basic usage - get first page of events for an address
86
+ * const result = await rpc.query.events(
87
+ * '0xde374ece6fa50e781e81aac78e811b33d16912c7',
75
88
  * 38000000,
76
89
  * null,
77
- * ['CrcV1_Trust'],
78
- * null,
79
- * false
90
+ * ['CrcV1_Trust']
80
91
  * );
92
+ * console.log(result.events);
93
+ * console.log(result.hasMore, result.nextCursor);
94
+ *
95
+ * // Paginate through results
96
+ * let cursor: string | null = null;
97
+ * do {
98
+ * const page = await rpc.query.events(address, fromBlock, null, null, null, false, 100, cursor);
99
+ * console.log(page.events);
100
+ * cursor = page.nextCursor;
101
+ * } while (cursor);
81
102
  * ```
82
103
  */
83
- async events(fromBlock, toBlock, eventTypes = null, address = null, includeTransactionData = false) {
84
- const result = await this.client.call('circles_events', [fromBlock, toBlock, eventTypes, address, includeTransactionData]);
85
- return checksumAddresses(result);
104
+ async events(address = null, fromBlock = null, toBlock = null, eventTypes = null, filterPredicates = null, sortAscending = false, limit = 100, cursor = null) {
105
+ const result = await this.client.call('circles_events_paginated', [address, fromBlock, toBlock, eventTypes, filterPredicates, sortAscending, limit, cursor]);
106
+ return {
107
+ events: checksumAddresses(result.events),
108
+ hasMore: result.hasMore,
109
+ nextCursor: result.nextCursor
110
+ };
86
111
  }
87
112
  }