@aboutcircles/sdk-rpc 0.1.0

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 (68) hide show
  1. package/README.md +169 -0
  2. package/dist/client.d.ts +58 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +194 -0
  5. package/dist/errors.d.ts +44 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +63 -0
  8. package/dist/events/index.d.ts +8 -0
  9. package/dist/events/index.d.ts.map +1 -0
  10. package/dist/events/index.js +8 -0
  11. package/dist/events/observable.d.ts +23 -0
  12. package/dist/events/observable.d.ts.map +1 -0
  13. package/dist/events/observable.js +37 -0
  14. package/dist/events/parser.d.ts +10 -0
  15. package/dist/events/parser.d.ts.map +1 -0
  16. package/dist/events/parser.js +103 -0
  17. package/dist/events/types.d.ts +7 -0
  18. package/dist/events/types.d.ts.map +1 -0
  19. package/dist/events/types.js +11 -0
  20. package/dist/index.d.ts +12 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +2654 -0
  23. package/dist/methods/avatar.d.ts +51 -0
  24. package/dist/methods/avatar.d.ts.map +1 -0
  25. package/dist/methods/avatar.js +64 -0
  26. package/dist/methods/balance.d.ts +37 -0
  27. package/dist/methods/balance.d.ts.map +1 -0
  28. package/dist/methods/balance.js +50 -0
  29. package/dist/methods/group.d.ts +145 -0
  30. package/dist/methods/group.d.ts.map +1 -0
  31. package/dist/methods/group.js +380 -0
  32. package/dist/methods/index.d.ts +11 -0
  33. package/dist/methods/index.d.ts.map +1 -0
  34. package/dist/methods/index.js +10 -0
  35. package/dist/methods/invitation.d.ts +61 -0
  36. package/dist/methods/invitation.d.ts.map +1 -0
  37. package/dist/methods/invitation.js +230 -0
  38. package/dist/methods/pathfinder.d.ts +41 -0
  39. package/dist/methods/pathfinder.d.ts.map +1 -0
  40. package/dist/methods/pathfinder.js +53 -0
  41. package/dist/methods/profile.d.ts +109 -0
  42. package/dist/methods/profile.d.ts.map +1 -0
  43. package/dist/methods/profile.js +166 -0
  44. package/dist/methods/query.d.ts +79 -0
  45. package/dist/methods/query.d.ts.map +1 -0
  46. package/dist/methods/query.js +87 -0
  47. package/dist/methods/token.d.ts +61 -0
  48. package/dist/methods/token.d.ts.map +1 -0
  49. package/dist/methods/token.js +99 -0
  50. package/dist/methods/transaction.d.ts +41 -0
  51. package/dist/methods/transaction.d.ts.map +1 -0
  52. package/dist/methods/transaction.js +111 -0
  53. package/dist/methods/trust.d.ts +114 -0
  54. package/dist/methods/trust.d.ts.map +1 -0
  55. package/dist/methods/trust.js +245 -0
  56. package/dist/pagedQuery.d.ts +106 -0
  57. package/dist/pagedQuery.d.ts.map +1 -0
  58. package/dist/pagedQuery.js +254 -0
  59. package/dist/rpc.d.ts +61 -0
  60. package/dist/rpc.d.ts.map +1 -0
  61. package/dist/rpc.js +76 -0
  62. package/dist/types.d.ts +82 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +1 -0
  65. package/dist/utils.d.ts +27 -0
  66. package/dist/utils.d.ts.map +1 -0
  67. package/dist/utils.js +111 -0
  68. package/package.json +32 -0
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # @aboutcircles/sdk-rpc
2
+
3
+ TypeScript wrapper for Circles RPC methods.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun install
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { CirclesRpc } from '@aboutcircles/sdk-rpc';
15
+
16
+ // Create RPC instance with default endpoint (https://rpc.circlesubi.network/)
17
+ const rpc = new CirclesRpc();
18
+
19
+ // Or use custom RPC endpoint
20
+ const rpc = new CirclesRpc('https://rpc.aboutcircles.com/');
21
+
22
+ // Note: All addresses are automatically normalized to lowercase
23
+ // since the Circles indexer stores addresses in lowercase
24
+
25
+ // Note: All numeric values (balances, amounts, timestamps) are returned as bigint
26
+ const balance = await rpc.circlesV2.getTotalBalance('0xcadd4ea3bcc361fc4af2387937d7417be8d7dfc2');
27
+ console.log(balance); // 1000000000000000000n
28
+
29
+ // Find a path between two addresses
30
+ const path = await rpc.circlesV2.findPath({
31
+ from: '0x749c930256b47049cb65adcd7c25e72d5de44b3b',
32
+ to: '0xde374ece6fa50e781e81aac78e811b33d16912c7',
33
+ targetFlow: 99999999999999999999999999999999999n
34
+ });
35
+
36
+ // Query trust relations
37
+ const trustRelations = await rpc.query.query({
38
+ Namespace: 'V_CrcV2',
39
+ Table: 'TrustRelations',
40
+ Columns: [],
41
+ Filter: [{
42
+ Type: 'Conjunction',
43
+ ConjunctionType: 'Or',
44
+ Predicates: [
45
+ {
46
+ Type: 'FilterPredicate',
47
+ FilterType: 'Equals',
48
+ Column: 'truster',
49
+ Value: '0xae3a29a9ff24d0e936a5579bae5c4179c4dff565'
50
+ },
51
+ {
52
+ Type: 'FilterPredicate',
53
+ FilterType: 'Equals',
54
+ Column: 'trustee',
55
+ Value: '0xae3a29a9ff24d0e936a5579bae5c4179c4dff565'
56
+ }
57
+ ]
58
+ }],
59
+ Order: []
60
+ });
61
+
62
+ // Get common trust
63
+ const commonTrust = await rpc.trust.getCommonTrust(
64
+ '0xde374ece6fa50e781e81aac78e811b33d16912c7',
65
+ '0xe8fc7a2d0573e5164597b05f14fa9a7fca7b215c'
66
+ );
67
+
68
+ // Get token balances
69
+ const balances = await rpc.balance.getTokenBalances('0x7cadf434b692ca029d950607a4b3f139c30d4e98');
70
+ // Each balance includes:
71
+ // - attoCircles, staticAttoCircles, attoCrc (as bigint)
72
+ // - circles, staticCircles, crc (as number)
73
+ // - token type flags (isErc20, isErc1155, isWrapped, etc.)
74
+
75
+ // Get avatar info
76
+ const avatarInfo = await rpc.avatar.getAvatarInfo('0xde374ece6fa50e781e81aac78e811b33d16912c7');
77
+
78
+ // Get network snapshot
79
+ const snapshot = await rpc.avatar.getNetworkSnapshot();
80
+
81
+ // Get profile by address
82
+ const profile = await rpc.profile.getProfileByAddress('0xc3a1428c04c426cdf513c6fc8e09f55ddaf50cd7');
83
+
84
+ // Get profiles by address batch
85
+ const profiles = await rpc.profile.getProfileByAddressBatch([
86
+ '0xc3a1428c04c426cdf513c6fc8e09f55ddaf50cd7',
87
+ '0xf712d3b31de494b5c0ea51a6a407460ca66b12e8'
88
+ ]);
89
+
90
+ // Search profiles
91
+ const results = await rpc.profile.searchProfiles('alice', 10, 0);
92
+
93
+ // Get available tables
94
+ const tables = await rpc.query.tables();
95
+
96
+ // Query events
97
+ const events = await rpc.query.events(
98
+ 38000000,
99
+ null,
100
+ ['CrcV1_Trust'],
101
+ null,
102
+ false
103
+ );
104
+ ```
105
+
106
+ ## API
107
+
108
+ **Note:** All balance and amount values are returned as `bigint` for safe handling of large numbers.
109
+
110
+ ### CirclesV2 Methods
111
+
112
+ - `getTotalBalanceV1(address, asTimeCircles?): Promise<bigint>` - Get total v1 Circles balance
113
+ - `getTotalBalance(address, asTimeCircles?): Promise<bigint>` - Get total v2 Circles balance
114
+ - `findPath(params): Promise<PathResponse>` - Calculate transfer path between addresses
115
+ - **params**: `{ from, to, targetFlow, useWrappedBalances?, fromTokens?, toTokens?, excludeFromTokens?, excludeToTokens?, simulatedBalances? }`
116
+ - All amounts are `bigint`, addresses normalized to lowercase
117
+ - Returns path with `flow` and `transfers` (all amounts as `bigint`)
118
+
119
+ ### Query Methods
120
+
121
+ - `query(params)` - Query tables with filters
122
+ - `tables()` - Get available namespaces and tables
123
+ - `events(fromBlock, toBlock, eventTypes, address, includeTransactionData)` - Query events
124
+
125
+ ### Trust Methods
126
+
127
+ - `getCommonTrust(address1, address2)` - Get common trust relations
128
+
129
+ ### Balance Methods
130
+
131
+ - `getTokenBalances(address): Promise<TokenBalance[]>` - Get token balance breakdown
132
+ - Returns balances with raw amounts as `bigint` (attoCircles, staticAttoCircles, attoCrc)
133
+ - And converted amounts as `number` (circles, staticCircles, crc)
134
+ - Includes token type flags (isErc20, isErc1155, isWrapped, isInflationary, isGroup)
135
+
136
+ ### Avatar Methods
137
+
138
+ - `getAvatarInfo(address): Promise<AvatarInfo | undefined>` - Get avatar information
139
+ - `getAvatarInfoBatch(addresses[]): Promise<AvatarInfo[]>` - Get multiple avatar infos in batch
140
+ - `getNetworkSnapshot(): Promise<NetworkSnapshot>` - Get full network snapshot
141
+
142
+ ### Profile Methods
143
+
144
+ - `getProfileByCid(cid): Promise<Profile | null>` - Get profile by CID
145
+ - `getProfileByCidBatch(cids[]): Promise<(Profile | null)[]>` - Get multiple profiles by CID
146
+ - `getProfileByAddress(address): Promise<Profile | null>` - Get profile by address
147
+ - `getProfileByAddressBatch(addresses[]): Promise<(Profile | null)[]>` - Get multiple profiles by address
148
+ - `searchProfiles(query, limit?, offset?): Promise<Profile[]>` - Search profiles
149
+
150
+ ### Token Methods
151
+
152
+ - `getTokenInfo(address): Promise<TokenInfo | undefined>` - Get token information
153
+ - `getTokenInfoBatch(addresses[]): Promise<TokenInfo[]>` - Get multiple token infos in batch
154
+
155
+ ### Invitation Methods
156
+
157
+ - `getInvitedBy(address): Promise<Address | undefined>` - Get the avatar that invited a specific address
158
+
159
+ ## Build
160
+
161
+ ```bash
162
+ bun run build
163
+ ```
164
+
165
+ ## Development
166
+
167
+ ```bash
168
+ bun run dev
169
+ ```
@@ -0,0 +1,58 @@
1
+ import type { Address } from '@aboutcircles/sdk-types';
2
+ import { Observable } from './events';
3
+ import type { CirclesEvent } from './events';
4
+ /**
5
+ * Base RPC client for making JSON-RPC calls to Circles RPC endpoints
6
+ * Supports both HTTP requests and WebSocket subscriptions
7
+ */
8
+ export declare class RpcClient {
9
+ private rpcUrl;
10
+ private requestId;
11
+ private websocket;
12
+ private websocketConnected;
13
+ private pendingResponses;
14
+ private subscriptionListeners;
15
+ private reconnectAttempt;
16
+ private readonly initialBackoff;
17
+ private readonly maxBackoff;
18
+ constructor(rpcUrl: string);
19
+ /**
20
+ * Make a JSON-RPC call
21
+ */
22
+ call<TParams = unknown[], TResult = unknown>(method: string, params: TParams): Promise<TResult>;
23
+ /**
24
+ * Update the RPC URL
25
+ */
26
+ setRpcUrl(rpcUrl: string): void;
27
+ /**
28
+ * Get the current RPC URL
29
+ */
30
+ getRpcUrl(): string;
31
+ /**
32
+ * Initiates a WebSocket connection
33
+ * @private
34
+ */
35
+ private connect;
36
+ /**
37
+ * Schedules a reconnect using exponential backoff with random jitter
38
+ * @private
39
+ */
40
+ private scheduleReconnect;
41
+ /**
42
+ * Attempts to reconnect the WebSocket
43
+ * @private
44
+ */
45
+ private reconnect;
46
+ /**
47
+ * Sends a message over WebSocket
48
+ * @private
49
+ */
50
+ private sendMessage;
51
+ /**
52
+ * Subscribe to Circles events via WebSocket
53
+ * @param address Optional address to filter events for a specific avatar
54
+ * @returns Observable that emits CirclesEvent objects
55
+ */
56
+ subscribe(address?: Address): Promise<Observable<CirclesEvent>>;
57
+ }
58
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,UAAU,EAA+B,MAAM,UAAU,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAa;IAG9B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,qBAAqB,CAEtB;IAGP,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;gBAEzB,MAAM,EAAE,MAAM;IAI1B;;OAEG;IACG,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,EAC/C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,CAAC;IA6CnB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAiDf;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;;OAGG;YACW,SAAS;IAWvB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAmBnB;;;;OAIG;IACG,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;CAsBtE"}
package/dist/client.js ADDED
@@ -0,0 +1,194 @@
1
+ import { Observable, parseRpcSubscriptionMessage } from './events';
2
+ import { RpcError } from './errors';
3
+ /**
4
+ * Base RPC client for making JSON-RPC calls to Circles RPC endpoints
5
+ * Supports both HTTP requests and WebSocket subscriptions
6
+ */
7
+ export class RpcClient {
8
+ rpcUrl;
9
+ requestId = 0;
10
+ // WebSocket fields
11
+ websocket = null;
12
+ websocketConnected = false;
13
+ pendingResponses = {};
14
+ subscriptionListeners = {};
15
+ // Backoff-related fields for reconnection
16
+ reconnectAttempt = 0;
17
+ initialBackoff = 2000; // 2 seconds
18
+ maxBackoff = 120000; // 2 minutes
19
+ constructor(rpcUrl) {
20
+ this.rpcUrl = rpcUrl;
21
+ }
22
+ /**
23
+ * Make a JSON-RPC call
24
+ */
25
+ async call(method, params) {
26
+ this.requestId++;
27
+ const request = {
28
+ jsonrpc: '2.0',
29
+ id: this.requestId,
30
+ method,
31
+ params,
32
+ };
33
+ try {
34
+ const response = await fetch(this.rpcUrl, {
35
+ method: 'POST',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ },
39
+ body: JSON.stringify(request),
40
+ });
41
+ if (!response.ok) {
42
+ throw RpcError.connectionFailed(this.rpcUrl, new Error(`HTTP ${response.status}: ${response.statusText}`));
43
+ }
44
+ const jsonResponse = await response.json();
45
+ if (jsonResponse.error) {
46
+ throw RpcError.fromJsonRpcError(jsonResponse.error);
47
+ }
48
+ if (jsonResponse.result === undefined) {
49
+ throw RpcError.invalidResponse(method, jsonResponse);
50
+ }
51
+ return jsonResponse.result;
52
+ }
53
+ catch (error) {
54
+ if (error instanceof RpcError) {
55
+ throw error;
56
+ }
57
+ throw RpcError.connectionFailed(this.rpcUrl, error);
58
+ }
59
+ }
60
+ /**
61
+ * Update the RPC URL
62
+ */
63
+ setRpcUrl(rpcUrl) {
64
+ this.rpcUrl = rpcUrl;
65
+ }
66
+ /**
67
+ * Get the current RPC URL
68
+ */
69
+ getRpcUrl() {
70
+ return this.rpcUrl;
71
+ }
72
+ /**
73
+ * Initiates a WebSocket connection
74
+ * @private
75
+ */
76
+ connect() {
77
+ return new Promise((resolve) => {
78
+ let wsUrl = this.rpcUrl.replace('http', 'ws');
79
+ if (wsUrl.endsWith('/')) {
80
+ wsUrl += 'ws';
81
+ }
82
+ else {
83
+ wsUrl += '/ws';
84
+ }
85
+ this.websocket = new WebSocket(wsUrl);
86
+ this.websocket.onopen = () => {
87
+ console.log('WebSocket connected');
88
+ this.websocketConnected = true;
89
+ // Reset the reconnect backoff attempts
90
+ this.reconnectAttempt = 0;
91
+ resolve();
92
+ };
93
+ this.websocket.onmessage = (event) => {
94
+ const message = JSON.parse(event.data);
95
+ const { id, method, params } = message;
96
+ if (id !== undefined && this.pendingResponses[id]) {
97
+ this.pendingResponses[id].resolve(message);
98
+ delete this.pendingResponses[id];
99
+ }
100
+ if (method === 'eth_subscription' && params) {
101
+ const { subscription, result } = params;
102
+ if (this.subscriptionListeners[subscription]) {
103
+ this.subscriptionListeners[subscription].forEach(listener => listener(result));
104
+ }
105
+ }
106
+ };
107
+ this.websocket.onclose = () => {
108
+ console.warn('WebSocket closed');
109
+ this.websocketConnected = false;
110
+ };
111
+ this.websocket.onerror = (error) => {
112
+ console.error('WebSocket error:', error);
113
+ this.websocketConnected = false;
114
+ // Schedule a reconnect
115
+ this.scheduleReconnect();
116
+ };
117
+ });
118
+ }
119
+ /**
120
+ * Schedules a reconnect using exponential backoff with random jitter
121
+ * @private
122
+ */
123
+ scheduleReconnect() {
124
+ // Exponential backoff: 2^attempt * initialBackoff
125
+ const delay = Math.min(this.initialBackoff * Math.pow(2, this.reconnectAttempt), this.maxBackoff);
126
+ // Add proportional jitter (between 0% and 50% of the delay)
127
+ const jitter = delay * (Math.random() * 0.5);
128
+ const timeout = delay + jitter;
129
+ console.log(`Reconnecting in ${Math.round(timeout)}ms (attempt #${this.reconnectAttempt + 1})`);
130
+ this.reconnectAttempt++;
131
+ setTimeout(() => {
132
+ this.reconnect();
133
+ }, timeout);
134
+ }
135
+ /**
136
+ * Attempts to reconnect the WebSocket
137
+ * @private
138
+ */
139
+ async reconnect() {
140
+ if (this.websocketConnected)
141
+ return;
142
+ try {
143
+ await this.connect();
144
+ console.log('Reconnection successful');
145
+ }
146
+ catch (err) {
147
+ console.error('Reconnection attempt failed:', err);
148
+ this.scheduleReconnect();
149
+ }
150
+ }
151
+ /**
152
+ * Sends a message over WebSocket
153
+ * @private
154
+ */
155
+ sendMessage(method, params, timeout = 5000) {
156
+ if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
157
+ return Promise.reject(RpcError.connectionFailed(this.rpcUrl));
158
+ }
159
+ const id = this.requestId++;
160
+ const message = { jsonrpc: '2.0', method, params, id };
161
+ return new Promise((resolve, reject) => {
162
+ this.pendingResponses[id] = { resolve, reject };
163
+ this.websocket.send(JSON.stringify(message));
164
+ setTimeout(() => {
165
+ if (this.pendingResponses[id]) {
166
+ this.pendingResponses[id].reject(RpcError.timeout(method, timeout));
167
+ delete this.pendingResponses[id];
168
+ }
169
+ }, timeout);
170
+ });
171
+ }
172
+ /**
173
+ * Subscribe to Circles events via WebSocket
174
+ * @param address Optional address to filter events for a specific avatar
175
+ * @returns Observable that emits CirclesEvent objects
176
+ */
177
+ async subscribe(address) {
178
+ const normalizedAddress = address?.toLowerCase();
179
+ if (!this.websocketConnected) {
180
+ await this.connect();
181
+ }
182
+ const observable = Observable.create();
183
+ const subscriptionArgs = JSON.stringify(normalizedAddress ? { address: normalizedAddress } : {});
184
+ const response = await this.sendMessage('eth_subscribe', ['circles', subscriptionArgs]);
185
+ const subscriptionId = response.result;
186
+ if (!this.subscriptionListeners[subscriptionId]) {
187
+ this.subscriptionListeners[subscriptionId] = [];
188
+ }
189
+ this.subscriptionListeners[subscriptionId].push((events) => {
190
+ parseRpcSubscriptionMessage(events).forEach(event => observable.emit(event));
191
+ });
192
+ return observable.property;
193
+ }
194
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * RPC Package Error Types
3
+ */
4
+ import { CirclesError } from '@aboutcircles/sdk-utils';
5
+ /**
6
+ * RPC-specific error sources
7
+ */
8
+ export type RpcErrorSource = 'RPC_CONNECTION' | 'RPC_REQUEST' | 'RPC_RESPONSE' | 'RPC_TIMEOUT' | 'RPC_WEBSOCKET';
9
+ /**
10
+ * RPC-related errors
11
+ */
12
+ export declare class RpcError extends CirclesError<RpcErrorSource> {
13
+ constructor(message: string, options?: {
14
+ code?: string | number;
15
+ source?: RpcErrorSource;
16
+ cause?: unknown;
17
+ context?: Record<string, any>;
18
+ });
19
+ /**
20
+ * Create error for connection failures
21
+ */
22
+ static connectionFailed(url: string, cause?: unknown): RpcError;
23
+ /**
24
+ * Create error for timeout
25
+ */
26
+ static timeout(method: string, timeout: number): RpcError;
27
+ /**
28
+ * Create error for invalid response
29
+ */
30
+ static invalidResponse(method: string, response: any): RpcError;
31
+ /**
32
+ * Create error from JSON-RPC error response
33
+ */
34
+ static fromJsonRpcError(error: {
35
+ code: number;
36
+ message: string;
37
+ data?: any;
38
+ }): RpcError;
39
+ /**
40
+ * Create error for WebSocket failures
41
+ */
42
+ static websocketError(message: string, cause?: unknown): RpcError;
43
+ }
44
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,aAAa,GACb,eAAe,CAAC;AAEpB;;GAEG;AACH,qBAAa,QAAS,SAAQ,YAAY,CAAC,cAAc,CAAC;gBAEtD,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC/B;IAKH;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ;IAS/D;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;IAQzD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,QAAQ;IAQ/D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAA;KAAE,GAAG,QAAQ;IAQvF;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ;CAOlE"}
package/dist/errors.js ADDED
@@ -0,0 +1,63 @@
1
+ /**
2
+ * RPC Package Error Types
3
+ */
4
+ import { CirclesError } from '@aboutcircles/sdk-utils';
5
+ /**
6
+ * RPC-related errors
7
+ */
8
+ export class RpcError extends CirclesError {
9
+ constructor(message, options) {
10
+ super('RpcError', message, { ...options, source: options?.source ?? 'RPC_REQUEST' });
11
+ }
12
+ /**
13
+ * Create error for connection failures
14
+ */
15
+ static connectionFailed(url, cause) {
16
+ return new RpcError('Failed to connect to RPC endpoint', {
17
+ code: 'RPC_CONNECTION_FAILED',
18
+ source: 'RPC_CONNECTION',
19
+ cause,
20
+ context: { url },
21
+ });
22
+ }
23
+ /**
24
+ * Create error for timeout
25
+ */
26
+ static timeout(method, timeout) {
27
+ return new RpcError('RPC request timed out', {
28
+ code: 'RPC_TIMEOUT',
29
+ source: 'RPC_TIMEOUT',
30
+ context: { method, timeout },
31
+ });
32
+ }
33
+ /**
34
+ * Create error for invalid response
35
+ */
36
+ static invalidResponse(method, response) {
37
+ return new RpcError('Invalid RPC response', {
38
+ code: 'RPC_INVALID_RESPONSE',
39
+ source: 'RPC_RESPONSE',
40
+ context: { method, response },
41
+ });
42
+ }
43
+ /**
44
+ * Create error from JSON-RPC error response
45
+ */
46
+ static fromJsonRpcError(error) {
47
+ return new RpcError(error.message, {
48
+ code: error.code,
49
+ source: 'RPC_RESPONSE',
50
+ context: { data: error.data },
51
+ });
52
+ }
53
+ /**
54
+ * Create error for WebSocket failures
55
+ */
56
+ static websocketError(message, cause) {
57
+ return new RpcError(message, {
58
+ code: 'RPC_WEBSOCKET_ERROR',
59
+ source: 'RPC_WEBSOCKET',
60
+ cause,
61
+ });
62
+ }
63
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Event observation and subscription system
3
+ */
4
+ export type { CirclesEvent, CirclesEventType, CirclesBaseEvent, CirclesEventOfType, RpcSubscriptionEvent, } from './types';
5
+ export { isCirclesEvent } from './types';
6
+ export { parseRpcEvent, parseRpcSubscriptionMessage } from './parser';
7
+ export { Observable } from './observable';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAGtE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Event observation and subscription system
3
+ */
4
+ export { isCirclesEvent } from './types';
5
+ // Parser
6
+ export { parseRpcEvent, parseRpcSubscriptionMessage } from './parser';
7
+ // Observable
8
+ export { Observable } from './observable';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Observable class for event streaming
3
+ * Provides a simple publish-subscribe pattern for Circles events
4
+ */
5
+ export declare class Observable<TEvent> {
6
+ private readonly _subscribers;
7
+ /**
8
+ * Subscribe to events
9
+ * @param subscriber Callback function to be called for each event
10
+ * @returns Unsubscribe function to stop receiving events
11
+ */
12
+ subscribe(subscriber: (value: TEvent) => void): () => void;
13
+ protected constructor();
14
+ protected emit(value: TEvent): void;
15
+ /**
16
+ * Create a new Observable with an emitter
17
+ */
18
+ static create<T>(): {
19
+ property: Observable<T>;
20
+ emit: (e: T) => void;
21
+ };
22
+ }
23
+ //# sourceMappingURL=observable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observable.d.ts","sourceRoot":"","sources":["../../src/events/observable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,UAAU,CAAC,MAAM;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAEhE;;;;OAIG;IACH,SAAS,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAU1D,SAAS;IAIT,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM;IAI5B;;OAEG;WACW,MAAM,CAAC,CAAC,KAAK;QAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAA;KAAE;CAO7E"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Observable class for event streaming
3
+ * Provides a simple publish-subscribe pattern for Circles events
4
+ */
5
+ export class Observable {
6
+ _subscribers = [];
7
+ /**
8
+ * Subscribe to events
9
+ * @param subscriber Callback function to be called for each event
10
+ * @returns Unsubscribe function to stop receiving events
11
+ */
12
+ subscribe(subscriber) {
13
+ this._subscribers.push(subscriber);
14
+ return () => {
15
+ const index = this._subscribers.indexOf(subscriber);
16
+ if (index > -1) {
17
+ this._subscribers.splice(index, 1);
18
+ }
19
+ };
20
+ }
21
+ constructor() {
22
+ this._subscribers = [];
23
+ }
24
+ emit(value) {
25
+ this._subscribers.forEach(sub => sub(value));
26
+ }
27
+ /**
28
+ * Create a new Observable with an emitter
29
+ */
30
+ static create() {
31
+ const observable = new Observable();
32
+ return {
33
+ property: observable,
34
+ emit: (e) => observable.emit(e)
35
+ };
36
+ }
37
+ }
@@ -0,0 +1,10 @@
1
+ import type { CirclesEvent, RpcSubscriptionEvent } from './types';
2
+ /**
3
+ * Parse a single RPC subscription event into a CirclesEvent
4
+ */
5
+ export declare function parseRpcEvent(rpcEvent: RpcSubscriptionEvent): CirclesEvent;
6
+ /**
7
+ * Parse an array of RPC subscription events
8
+ */
9
+ export declare function parseRpcSubscriptionMessage(message: RpcSubscriptionEvent[]): CirclesEvent[];
10
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/events/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAgFlE;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,oBAAoB,GAAG,YAAY,CAwB1E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,YAAY,EAAE,CAE3F"}