@arcium-hq/reader 0.2.0 → 0.4.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.
package/build/index.cjs CHANGED
@@ -22,7 +22,7 @@ function _interopNamespaceDefault(e) {
22
22
 
23
23
  var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
24
24
 
25
- const ARCIUM_PROGRAM_ID_STRING = 'BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6';
25
+ const ARCIUM_PROGRAM_ID_STRING = 'Bv3Fb9VjzjWGfX18QTUcVycAfeLoQ5zZN6vv2g3cTZxp';
26
26
  /**
27
27
  * Discriminator for the ArxNode account type. Used to filter and identify ArxNode accounts on-chain.
28
28
  */
@@ -46,7 +46,12 @@ new anchor__namespace.BorshInstructionCoder(client.ARCIUM_IDL);
46
46
  /**
47
47
  * Anchor event parser for parsing Arcium program events from transaction logs.
48
48
  */
49
- const ARCIUM_EVENT_CODER = new anchor__namespace.EventParser(ARCIUM_PROGRAM_ID, new anchor__namespace.BorshCoder(client.ARCIUM_IDL));
49
+ new anchor__namespace.EventParser(ARCIUM_PROGRAM_ID, new anchor__namespace.BorshCoder(client.ARCIUM_IDL));
50
+ /**
51
+ * BorshCoder instance for decoding Arcium events.
52
+ * Used directly instead of accessing EventParser's private coder property.
53
+ */
54
+ const ARCIUM_BORSH_CODER = new anchor__namespace.BorshCoder(client.ARCIUM_IDL);
50
55
 
51
56
  /**
52
57
  * Returns all MXE account addresses.
@@ -227,13 +232,53 @@ function getComputationOffset(tx) {
227
232
  }
228
233
  /**
229
234
  * Get the events related to arcium computations from a transaction's logs
235
+ *
236
+ * Note: This implements a direct decode approach instead of using Anchor's EventParser.parseLogs().
237
+ *
238
+ * BREAKING CHANGE IN ANCHOR v0.32.0 (PR #3657, commit 34b6d19):
239
+ * EventParser.parseLogs was hardened to prevent malicious log injection attacks. It now:
240
+ * 1. Requires the first log to match "Program X invoke [1]" (root invocation)
241
+ * 2. Pre-seeds the execution stack with program X from the first log
242
+ * 3. Only parses events when execution.program() === EventParser.programId
243
+ *
244
+ * This breaks our use case:
245
+ * - We subscribe to MXE program logs (line 29) via conn.onLogs(mxeProgramId, ...)
246
+ * - But we need to parse Arcium events emitted during MXE→Arcium CPI calls
247
+ * - When MXE is the root program, execution.program() = MXE_PROGRAM_ID
248
+ * - EventParser expects execution.program() = ARCIUM_PROGRAM_ID
249
+ * - Result: All Arcium events are silently skipped
250
+ *
251
+ * Our discriminator-based approach:
252
+ * - Scans all logs for "Program data:" and "Program log:" prefixes
253
+ * - Uses event discriminators to identify valid Arcium events (no program context check)
254
+ * - Works regardless of which program is root or subscription target
255
+ * - Handles both MXE→Arcium and Arcium→MXE CPI patterns
256
+ *
230
257
  * @param logs - The logs to get the events from
231
258
  * @returns The events in the logs.
232
259
  */
233
260
  function getComputationEventsFromLogs(logs) {
234
- return Array.from(ARCIUM_EVENT_CODER.parseLogs(logs))
235
- .filter((e) => ArciumEventNames.includes(e.name))
236
- .map((e) => {
261
+ const events = [];
262
+ // Scan all event logs and rely on discriminators to identify valid Arcium events.
263
+ // This works for both MXE→Arcium CPI and Arcium→MXE CPI transactions.
264
+ for (const log of logs) {
265
+ if (log.startsWith('Program data: ')) {
266
+ const eventData = log.slice('Program data: '.length);
267
+ const decoded = ARCIUM_BORSH_CODER.events.decode(eventData);
268
+ if (decoded && ArciumEventNames.includes(decoded.name)) {
269
+ events.push(decoded);
270
+ }
271
+ }
272
+ else if (log.startsWith('Program log: ')) {
273
+ const eventData = log.slice('Program log: '.length);
274
+ const decoded = ARCIUM_BORSH_CODER.events.decode(eventData);
275
+ if (decoded && ArciumEventNames.includes(decoded.name)) {
276
+ events.push(decoded);
277
+ }
278
+ }
279
+ }
280
+ // Map to existing return format
281
+ return events.map((e) => {
237
282
  const eventData = {
238
283
  computationOffset: e.data.computation_offset,
239
284
  ...e.data,
@@ -276,6 +321,10 @@ Object.defineProperty(exports, "getExecutingPoolAccAddress", {
276
321
  enumerable: true,
277
322
  get: function () { return client.getExecutingPoolAccAddress; }
278
323
  });
324
+ Object.defineProperty(exports, "getFeePoolAccAddress", {
325
+ enumerable: true,
326
+ get: function () { return client.getFeePoolAccAddress; }
327
+ });
279
328
  Object.defineProperty(exports, "getMXEAccAddress", {
280
329
  enumerable: true,
281
330
  get: function () { return client.getMXEAccAddress; }
@@ -284,10 +333,6 @@ Object.defineProperty(exports, "getMempoolAccAddress", {
284
333
  enumerable: true,
285
334
  get: function () { return client.getMempoolAccAddress; }
286
335
  });
287
- Object.defineProperty(exports, "getStakingPoolAccAddress", {
288
- enumerable: true,
289
- get: function () { return client.getStakingPoolAccAddress; }
290
- });
291
336
  exports.getArxNodeAccAddresses = getArxNodeAccAddresses;
292
337
  exports.getArxNodeAccInfo = getArxNodeAccInfo;
293
338
  exports.getClusterAccAddresses = getClusterAccAddresses;
package/build/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ArciumIdlType } from '@arcium-hq/client';
2
- export { getArciumProgramReadonly, getArxNodeAccAddress, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getComputationAccAddress, getExecutingPoolAccAddress, getMXEAccAddress, getMempoolAccAddress, getStakingPoolAccAddress } from '@arcium-hq/client';
2
+ export { getArciumProgramReadonly, getArxNodeAccAddress, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getComputationAccAddress, getExecutingPoolAccAddress, getFeePoolAccAddress, getMXEAccAddress, getMempoolAccAddress } from '@arcium-hq/client';
3
3
  import * as anchor from '@coral-xyz/anchor';
4
4
 
5
5
  /**
@@ -29,9 +29,8 @@ type ArxNodeAccount = ArciumTypes['arxNode'];
29
29
  type ComputationAccount = ArciumTypes['computationAccount'];
30
30
  type ComputationReference = ArciumTypes['computationReference'];
31
31
  type ComputationDefinitionAccount = ArciumTypes['computationDefinitionAccount'];
32
- type QueueComputationIx = ArciumIdlType['instructions']['23'];
32
+ type QueueComputationIx = ArciumIdlType['instructions']['25'];
33
33
  type CallbackComputationIx = ArciumIdlType['instructions']['3'];
34
- type FinalizeComputationIx = ArciumIdlType['instructions']['8'];
35
34
  /**
36
35
  * Status values for a computation, as defined by the Arcium protocol.
37
36
  */
@@ -127,4 +126,4 @@ declare function unsubscribeComputations(conn: Connection, subscriptionId: numbe
127
126
  declare function getComputationOffset(tx: anchor.web3.VersionedTransactionResponse): anchor.BN | undefined;
128
127
 
129
128
  export { getArxNodeAccAddresses, getArxNodeAccInfo, getClusterAccAddresses, getClusterAccInfo, getCompDefAccInfo, getComputationAccInfo, getComputationOffset, getComputationsInMempool, getMXEAccAddresses, getMXEAccInfo, subscribeComputations, unsubscribeComputations };
130
- export type { ArciumEvent, ArciumEventData, ArciumEventName, ArciumTypes, ArxNodeAccount, CallbackComputationIx, ClusterAccount, ComputationAccount, ComputationDefinitionAccount, ComputationReference, ComputationStatus, Connection, FinalizeComputationIx, MXEAccount, Program, PublicKey, QueueComputationIx };
129
+ export type { ArciumEvent, ArciumEventData, ArciumEventName, ArciumTypes, ArxNodeAccount, CallbackComputationIx, ClusterAccount, ComputationAccount, ComputationDefinitionAccount, ComputationReference, ComputationStatus, Connection, MXEAccount, Program, PublicKey, QueueComputationIx };
package/build/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ARCIUM_IDL, getMempoolAccData } from '@arcium-hq/client';
2
- export { getArciumProgramReadonly, getArxNodeAccAddress, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getComputationAccAddress, getExecutingPoolAccAddress, getMXEAccAddress, getMempoolAccAddress, getStakingPoolAccAddress } from '@arcium-hq/client';
2
+ export { getArciumProgramReadonly, getArxNodeAccAddress, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getComputationAccAddress, getExecutingPoolAccAddress, getFeePoolAccAddress, getMXEAccAddress, getMempoolAccAddress } from '@arcium-hq/client';
3
3
  import * as anchor from '@coral-xyz/anchor';
4
4
 
5
- const ARCIUM_PROGRAM_ID_STRING = 'BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6';
5
+ const ARCIUM_PROGRAM_ID_STRING = 'Bv3Fb9VjzjWGfX18QTUcVycAfeLoQ5zZN6vv2g3cTZxp';
6
6
  /**
7
7
  * Discriminator for the ArxNode account type. Used to filter and identify ArxNode accounts on-chain.
8
8
  */
@@ -26,7 +26,12 @@ new anchor.BorshInstructionCoder(ARCIUM_IDL);
26
26
  /**
27
27
  * Anchor event parser for parsing Arcium program events from transaction logs.
28
28
  */
29
- const ARCIUM_EVENT_CODER = new anchor.EventParser(ARCIUM_PROGRAM_ID, new anchor.BorshCoder(ARCIUM_IDL));
29
+ new anchor.EventParser(ARCIUM_PROGRAM_ID, new anchor.BorshCoder(ARCIUM_IDL));
30
+ /**
31
+ * BorshCoder instance for decoding Arcium events.
32
+ * Used directly instead of accessing EventParser's private coder property.
33
+ */
34
+ const ARCIUM_BORSH_CODER = new anchor.BorshCoder(ARCIUM_IDL);
30
35
 
31
36
  /**
32
37
  * Returns all MXE account addresses.
@@ -207,13 +212,53 @@ function getComputationOffset(tx) {
207
212
  }
208
213
  /**
209
214
  * Get the events related to arcium computations from a transaction's logs
215
+ *
216
+ * Note: This implements a direct decode approach instead of using Anchor's EventParser.parseLogs().
217
+ *
218
+ * BREAKING CHANGE IN ANCHOR v0.32.0 (PR #3657, commit 34b6d19):
219
+ * EventParser.parseLogs was hardened to prevent malicious log injection attacks. It now:
220
+ * 1. Requires the first log to match "Program X invoke [1]" (root invocation)
221
+ * 2. Pre-seeds the execution stack with program X from the first log
222
+ * 3. Only parses events when execution.program() === EventParser.programId
223
+ *
224
+ * This breaks our use case:
225
+ * - We subscribe to MXE program logs (line 29) via conn.onLogs(mxeProgramId, ...)
226
+ * - But we need to parse Arcium events emitted during MXE→Arcium CPI calls
227
+ * - When MXE is the root program, execution.program() = MXE_PROGRAM_ID
228
+ * - EventParser expects execution.program() = ARCIUM_PROGRAM_ID
229
+ * - Result: All Arcium events are silently skipped
230
+ *
231
+ * Our discriminator-based approach:
232
+ * - Scans all logs for "Program data:" and "Program log:" prefixes
233
+ * - Uses event discriminators to identify valid Arcium events (no program context check)
234
+ * - Works regardless of which program is root or subscription target
235
+ * - Handles both MXE→Arcium and Arcium→MXE CPI patterns
236
+ *
210
237
  * @param logs - The logs to get the events from
211
238
  * @returns The events in the logs.
212
239
  */
213
240
  function getComputationEventsFromLogs(logs) {
214
- return Array.from(ARCIUM_EVENT_CODER.parseLogs(logs))
215
- .filter((e) => ArciumEventNames.includes(e.name))
216
- .map((e) => {
241
+ const events = [];
242
+ // Scan all event logs and rely on discriminators to identify valid Arcium events.
243
+ // This works for both MXE→Arcium CPI and Arcium→MXE CPI transactions.
244
+ for (const log of logs) {
245
+ if (log.startsWith('Program data: ')) {
246
+ const eventData = log.slice('Program data: '.length);
247
+ const decoded = ARCIUM_BORSH_CODER.events.decode(eventData);
248
+ if (decoded && ArciumEventNames.includes(decoded.name)) {
249
+ events.push(decoded);
250
+ }
251
+ }
252
+ else if (log.startsWith('Program log: ')) {
253
+ const eventData = log.slice('Program log: '.length);
254
+ const decoded = ARCIUM_BORSH_CODER.events.decode(eventData);
255
+ if (decoded && ArciumEventNames.includes(decoded.name)) {
256
+ events.push(decoded);
257
+ }
258
+ }
259
+ }
260
+ // Map to existing return format
261
+ return events.map((e) => {
217
262
  const eventData = {
218
263
  computationOffset: e.data.computation_offset,
219
264
  ...e.data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcium-hq/reader",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Reader SDK for fetching onchain data for Arcium network programs",
5
5
  "author": "Arcium",
6
6
  "license": "GPL-3.0-only",
@@ -57,10 +57,10 @@
57
57
  "typescript-eslint": "^8.15.0"
58
58
  },
59
59
  "dependencies": {
60
- "@coral-xyz/anchor": "^0.31.1",
61
- "@noble/curves": "^1.8.1",
60
+ "@coral-xyz/anchor": "^0.32.1",
61
+ "@noble/curves": "^1.9.5",
62
62
  "@noble/hashes": "^1.7.1",
63
- "@arcium-hq/client": "0.2.0"
63
+ "@arcium-hq/client": "0.4.0"
64
64
  },
65
65
  "keywords": [
66
66
  "Cryptography",