@arcium-hq/client 0.8.4 → 0.8.5

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
@@ -1809,7 +1809,7 @@ function createPacker(fields, typeName = 'Packer') {
1809
1809
  var address = "Arcj82pX7HxYKLR92qvgZUAd7vGS1k4hQvAFcPATFdEQ";
1810
1810
  var metadata = {
1811
1811
  name: "arcium",
1812
- version: "0.8.4",
1812
+ version: "0.8.5",
1813
1813
  spec: "0.1.0",
1814
1814
  description: "The Arcium program"
1815
1815
  };
@@ -14039,38 +14039,78 @@ function getArciumEnv() {
14039
14039
  }
14040
14040
  }
14041
14041
 
14042
+ const POLL_INTERVAL_MS = 500;
14042
14043
  /**
14043
- * Waits for the finalization of a computation by listening for the finalizeComputationEvent.
14044
- * Resolves with the transaction signature once the computation is finalized.
14045
- * @param provider - The Anchor provider to use for event listening.
14046
- * @param computationOffset - The offset of the computation to wait for.
14047
- * @param mxeProgramId - The public key of the MXE program.
14048
- * @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
14049
- * @returns The transaction signature of the finalization event.
14044
+ * Waits for a computation to finalize by polling the computation account
14045
+ * status via HTTP RPC. Does not use WebSocket subscriptions.
14046
+ *
14047
+ * Polls every 500ms (same as Agave's send_and_confirm_transaction_with_config).
14048
+ * Returns the most recent transaction signature on the computation account
14049
+ * once finalization is detected.
14050
+ *
14051
+ * @param provider - The Anchor provider.
14052
+ * @param computationOffset - The computation offset to wait for.
14053
+ * @param mxeProgramId - The MXE program public key.
14054
+ * @param commitment - Commitment level for RPC calls (default: 'confirmed').
14055
+ * @param timeoutMs - Maximum wait time in milliseconds (default: 120000).
14056
+ * @returns The transaction signature from the finalization.
14057
+ * @throws Error if the MXE account has no cluster assigned.
14058
+ * @throws Error if the computation does not finalize within timeoutMs.
14050
14059
  */
14051
- async function awaitComputationFinalization(provider, computationOffset, mxeProgramId, commitment = 'confirmed') {
14060
+ async function awaitComputationFinalization(provider, computationOffset, mxeProgramId, commitment = 'confirmed', timeoutMs = 120_000) {
14061
+ const conn = provider.connection;
14052
14062
  const arciumProgram = getArciumProgram(provider);
14053
- const eventListener = new anchor.EventManager(arciumProgram.programId, provider, arciumProgram.coder);
14054
- const finalizeComp = await awaitEvent(eventListener, 'finalizeComputationEvent', (e) => mxeProgramId.equals(e.mxeProgramId) && e.computationOffset.eq(computationOffset), commitment);
14055
- return finalizeComp.sig;
14056
- }
14057
- /**
14058
- * Waits for a specific event to occur, matching a custom check, and returns the event and its signature.
14059
- * @param eventListener - The EventManager instance to use for listening.
14060
- * @param eventName - The name of the event to listen for.
14061
- * @param eventCheck - A predicate function to check if the event matches the desired criteria.
14062
- * @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
14063
- * @returns An object containing the event and its transaction signature.
14064
- */
14065
- async function awaitEvent(eventListener, eventName, eventCheck, commitment = 'confirmed') {
14066
- const foundEvent = await new Promise((res) => {
14067
- const listenerId = eventListener.addEventListener(eventName, (event, _slot, signature) => {
14068
- if (eventCheck(event))
14069
- res([event, signature, listenerId]);
14070
- }, commitment);
14071
- });
14072
- await eventListener.removeEventListener(foundEvent[2]);
14073
- return { event: foundEvent[0], sig: foundEvent[1] };
14063
+ // Derive computation account PDA (requires clusterOffset from MXE account)
14064
+ const mxeAccAddress = getMXEAccAddress(mxeProgramId);
14065
+ const mxeAcc = await arciumProgram.account.mxeAccount.fetch(mxeAccAddress, commitment);
14066
+ if (mxeAcc.cluster === null) {
14067
+ throw new Error('MXE account has no cluster assigned');
14068
+ }
14069
+ const compAccAddress = getComputationAccAddress(mxeAcc.cluster, computationOffset);
14070
+ const startTime = Date.now();
14071
+ let lastStatus = 'unknown';
14072
+ let rpcErrorCount = 0;
14073
+ let lastError;
14074
+ while (Date.now() - startTime < timeoutMs) {
14075
+ let compAcc;
14076
+ try {
14077
+ // eslint-disable-next-line no-await-in-loop
14078
+ compAcc = await arciumProgram.account.computationAccount.fetchNullable(compAccAddress, commitment);
14079
+ }
14080
+ catch (e) {
14081
+ rpcErrorCount++;
14082
+ lastError = e instanceof Error ? e.message : String(e);
14083
+ // eslint-disable-next-line no-await-in-loop
14084
+ await new Promise((r) => {
14085
+ setTimeout(r, POLL_INTERVAL_MS);
14086
+ });
14087
+ continue;
14088
+ }
14089
+ if (compAcc !== null && 'finalized' in compAcc.status) {
14090
+ lastStatus = 'finalized';
14091
+ for (let sigRetry = 0; sigRetry < 10; sigRetry++) {
14092
+ // eslint-disable-next-line no-await-in-loop
14093
+ const sigs = await conn.getSignaturesForAddress(compAccAddress, { limit: 1 }, commitment);
14094
+ if (sigs.length > 0)
14095
+ return sigs[0].signature;
14096
+ // eslint-disable-next-line no-await-in-loop
14097
+ await new Promise((r) => {
14098
+ setTimeout(r, POLL_INTERVAL_MS);
14099
+ });
14100
+ }
14101
+ throw new Error('Computation finalized but transaction signature not indexed after retries.');
14102
+ }
14103
+ if (compAcc !== null)
14104
+ lastStatus = 'queued';
14105
+ // eslint-disable-next-line no-await-in-loop
14106
+ await new Promise((r) => {
14107
+ setTimeout(r, POLL_INTERVAL_MS);
14108
+ });
14109
+ }
14110
+ const timeoutMsg = `Computation did not finalize within ${timeoutMs}ms (status: ${lastStatus})`;
14111
+ throw rpcErrorCount > 0
14112
+ ? new Error(timeoutMsg, { cause: new Error(`${rpcErrorCount} RPC errors, last: ${lastError}`) })
14113
+ : new Error(timeoutMsg);
14074
14114
  }
14075
14115
 
14076
14116
  Object.defineProperty(exports, "x25519", {
package/build/index.d.ts CHANGED
@@ -456,7 +456,7 @@ type Arcium = {
456
456
  "address": "Arcj82pX7HxYKLR92qvgZUAd7vGS1k4hQvAFcPATFdEQ";
457
457
  "metadata": {
458
458
  "name": "arcium";
459
- "version": "0.8.4";
459
+ "version": "0.8.5";
460
460
  "spec": "0.1.0";
461
461
  "description": "The Arcium program";
462
462
  };
@@ -11975,19 +11975,23 @@ type ArciumLocalEnv = {
11975
11975
  declare function getArciumEnv(): ArciumLocalEnv;
11976
11976
 
11977
11977
  /**
11978
- * Represents possible error messages that can occur during computation processing or transaction handling.
11979
- */
11980
- type ComputationErrorType = `Transaction ${string} not found` | 'Transaction inner instructions not found' | `Transaction failed with error: ${string}` | 'No log messages found' | 'No queue computation instruction found' | `Invalid computation offset: ${string}` | 'Computation not found in executing pool, might have already executed' | `Error fetching transactions: ${string}` | `Instruction at index ${number} not found` | 'Account keys or program ID index not found' | `No Program ID found for instruction at index ${number}` | 'Max retries reached while searching for transaction';
11981
- /**
11982
- * Waits for the finalization of a computation by listening for the finalizeComputationEvent.
11983
- * Resolves with the transaction signature once the computation is finalized.
11984
- * @param provider - The Anchor provider to use for event listening.
11985
- * @param computationOffset - The offset of the computation to wait for.
11986
- * @param mxeProgramId - The public key of the MXE program.
11987
- * @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
11988
- * @returns The transaction signature of the finalization event.
11978
+ * Waits for a computation to finalize by polling the computation account
11979
+ * status via HTTP RPC. Does not use WebSocket subscriptions.
11980
+ *
11981
+ * Polls every 500ms (same as Agave's send_and_confirm_transaction_with_config).
11982
+ * Returns the most recent transaction signature on the computation account
11983
+ * once finalization is detected.
11984
+ *
11985
+ * @param provider - The Anchor provider.
11986
+ * @param computationOffset - The computation offset to wait for.
11987
+ * @param mxeProgramId - The MXE program public key.
11988
+ * @param commitment - Commitment level for RPC calls (default: 'confirmed').
11989
+ * @param timeoutMs - Maximum wait time in milliseconds (default: 120000).
11990
+ * @returns The transaction signature from the finalization.
11991
+ * @throws Error if the MXE account has no cluster assigned.
11992
+ * @throws Error if the computation does not finalize within timeoutMs.
11989
11993
  */
11990
- declare function awaitComputationFinalization(provider: AnchorProvider, computationOffset: BN, mxeProgramId: PublicKey, commitment?: Finality): Promise<string>;
11994
+ declare function awaitComputationFinalization(provider: AnchorProvider, computationOffset: BN, mxeProgramId: PublicKey, commitment?: Finality, timeoutMs?: number): Promise<string>;
11991
11995
 
11992
11996
  /**
11993
11997
  * Returns the public key of the deployed Arcium program on Solana.
@@ -12077,4 +12081,4 @@ declare function getRawCircuitAccAddress(compDefPubkey: PublicKey, rawCircuitInd
12077
12081
  declare function getLookupTableAddress(mxeProgramId: PublicKey, lutOffset: anchor.BN): PublicKey;
12078
12082
 
12079
12083
  export { ARCIUM_ADDR, ARCIUM_IDL, Aes128Cipher, Aes192Cipher, Aes256Cipher, ArcisModule, ArcisType, ArcisValueField, CSplRescueCipher, CURVE25519_BASE_FIELD, CURVE25519_SCALAR_FIELD, CURVE25519_SCALAR_FIELD_MODULUS, IntegerInfo, Matrix, RescueCipher, RescueDesc, RescuePrimeHash, arcisEd25519, awaitComputationFinalization, buildFinalizeCompDefTx, createPacker, deserializeLE, finalizeKeyRecoveryExecution, generateRandomFieldElem, getArciumAccountBaseSeed, getArciumEnv, getArciumProgram, getArciumProgramId, getArxNodeAccAddress, getCircuitState, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getCompDefAccOffset, getComputationAccAddress, getComputationsInMempool, getExecutingPoolAccAddress, getExecutingPoolAccInfo, getFeePoolAccAddress, getLookupTableAddress, getMXEAccAddress, getMXEArcisEd25519VerifyingKey, getMXEPublicKey, getMempoolAccAddress, getMempoolAccInfo, getMempoolPriorityFeeStats, getMxeRecoveryAccAddress, getRawCircuitAccAddress, getRecoveryClusterAccAddress, initKeyRecoveryExecution, initMxePart1, initMxePart2, isNullRef, positiveModulo, queueKeyRecoveryInit, randMatrix, recoverMxe, serializeLE, sha256, submitKeyRecoveryShare, toVec, uploadCircuit };
12080
- export type { Arcium as ArciumIdlType, ArciumLocalEnv, CircuitSource, CircuitState, ComputationErrorType, ComputationReference, ExecutingPoolAccount, FieldInfo, FpField, MempoolAccount, MempoolPriorityFeeStats, Packer };
12084
+ export type { Arcium as ArciumIdlType, ArciumLocalEnv, CircuitSource, CircuitState, ComputationReference, ExecutingPoolAccount, FieldInfo, FpField, MempoolAccount, MempoolPriorityFeeStats, Packer };
package/build/index.mjs CHANGED
@@ -4,7 +4,7 @@ export { x25519 } from '@noble/curves/ed25519';
4
4
  import { shake256, sha3_512 } from '@noble/hashes/sha3';
5
5
  import { invert, mod, isNegativeLE, pow2 } from '@noble/curves/abstract/modular';
6
6
  import * as anchor from '@coral-xyz/anchor';
7
- import { Program, EventManager } from '@coral-xyz/anchor';
7
+ import { Program } from '@coral-xyz/anchor';
8
8
  import { randomBytes as randomBytes$1 } from '@noble/hashes/utils';
9
9
  import { twistedEdwards } from '@noble/curves/abstract/edwards';
10
10
  import fs from 'fs';
@@ -1790,7 +1790,7 @@ function createPacker(fields, typeName = 'Packer') {
1790
1790
  var address = "Arcj82pX7HxYKLR92qvgZUAd7vGS1k4hQvAFcPATFdEQ";
1791
1791
  var metadata = {
1792
1792
  name: "arcium",
1793
- version: "0.8.4",
1793
+ version: "0.8.5",
1794
1794
  spec: "0.1.0",
1795
1795
  description: "The Arcium program"
1796
1796
  };
@@ -14020,38 +14020,78 @@ function getArciumEnv() {
14020
14020
  }
14021
14021
  }
14022
14022
 
14023
+ const POLL_INTERVAL_MS = 500;
14023
14024
  /**
14024
- * Waits for the finalization of a computation by listening for the finalizeComputationEvent.
14025
- * Resolves with the transaction signature once the computation is finalized.
14026
- * @param provider - The Anchor provider to use for event listening.
14027
- * @param computationOffset - The offset of the computation to wait for.
14028
- * @param mxeProgramId - The public key of the MXE program.
14029
- * @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
14030
- * @returns The transaction signature of the finalization event.
14025
+ * Waits for a computation to finalize by polling the computation account
14026
+ * status via HTTP RPC. Does not use WebSocket subscriptions.
14027
+ *
14028
+ * Polls every 500ms (same as Agave's send_and_confirm_transaction_with_config).
14029
+ * Returns the most recent transaction signature on the computation account
14030
+ * once finalization is detected.
14031
+ *
14032
+ * @param provider - The Anchor provider.
14033
+ * @param computationOffset - The computation offset to wait for.
14034
+ * @param mxeProgramId - The MXE program public key.
14035
+ * @param commitment - Commitment level for RPC calls (default: 'confirmed').
14036
+ * @param timeoutMs - Maximum wait time in milliseconds (default: 120000).
14037
+ * @returns The transaction signature from the finalization.
14038
+ * @throws Error if the MXE account has no cluster assigned.
14039
+ * @throws Error if the computation does not finalize within timeoutMs.
14031
14040
  */
14032
- async function awaitComputationFinalization(provider, computationOffset, mxeProgramId, commitment = 'confirmed') {
14041
+ async function awaitComputationFinalization(provider, computationOffset, mxeProgramId, commitment = 'confirmed', timeoutMs = 120_000) {
14042
+ const conn = provider.connection;
14033
14043
  const arciumProgram = getArciumProgram(provider);
14034
- const eventListener = new EventManager(arciumProgram.programId, provider, arciumProgram.coder);
14035
- const finalizeComp = await awaitEvent(eventListener, 'finalizeComputationEvent', (e) => mxeProgramId.equals(e.mxeProgramId) && e.computationOffset.eq(computationOffset), commitment);
14036
- return finalizeComp.sig;
14037
- }
14038
- /**
14039
- * Waits for a specific event to occur, matching a custom check, and returns the event and its signature.
14040
- * @param eventListener - The EventManager instance to use for listening.
14041
- * @param eventName - The name of the event to listen for.
14042
- * @param eventCheck - A predicate function to check if the event matches the desired criteria.
14043
- * @param commitment - (Optional) The desired finality/commitment level (default: 'confirmed').
14044
- * @returns An object containing the event and its transaction signature.
14045
- */
14046
- async function awaitEvent(eventListener, eventName, eventCheck, commitment = 'confirmed') {
14047
- const foundEvent = await new Promise((res) => {
14048
- const listenerId = eventListener.addEventListener(eventName, (event, _slot, signature) => {
14049
- if (eventCheck(event))
14050
- res([event, signature, listenerId]);
14051
- }, commitment);
14052
- });
14053
- await eventListener.removeEventListener(foundEvent[2]);
14054
- return { event: foundEvent[0], sig: foundEvent[1] };
14044
+ // Derive computation account PDA (requires clusterOffset from MXE account)
14045
+ const mxeAccAddress = getMXEAccAddress(mxeProgramId);
14046
+ const mxeAcc = await arciumProgram.account.mxeAccount.fetch(mxeAccAddress, commitment);
14047
+ if (mxeAcc.cluster === null) {
14048
+ throw new Error('MXE account has no cluster assigned');
14049
+ }
14050
+ const compAccAddress = getComputationAccAddress(mxeAcc.cluster, computationOffset);
14051
+ const startTime = Date.now();
14052
+ let lastStatus = 'unknown';
14053
+ let rpcErrorCount = 0;
14054
+ let lastError;
14055
+ while (Date.now() - startTime < timeoutMs) {
14056
+ let compAcc;
14057
+ try {
14058
+ // eslint-disable-next-line no-await-in-loop
14059
+ compAcc = await arciumProgram.account.computationAccount.fetchNullable(compAccAddress, commitment);
14060
+ }
14061
+ catch (e) {
14062
+ rpcErrorCount++;
14063
+ lastError = e instanceof Error ? e.message : String(e);
14064
+ // eslint-disable-next-line no-await-in-loop
14065
+ await new Promise((r) => {
14066
+ setTimeout(r, POLL_INTERVAL_MS);
14067
+ });
14068
+ continue;
14069
+ }
14070
+ if (compAcc !== null && 'finalized' in compAcc.status) {
14071
+ lastStatus = 'finalized';
14072
+ for (let sigRetry = 0; sigRetry < 10; sigRetry++) {
14073
+ // eslint-disable-next-line no-await-in-loop
14074
+ const sigs = await conn.getSignaturesForAddress(compAccAddress, { limit: 1 }, commitment);
14075
+ if (sigs.length > 0)
14076
+ return sigs[0].signature;
14077
+ // eslint-disable-next-line no-await-in-loop
14078
+ await new Promise((r) => {
14079
+ setTimeout(r, POLL_INTERVAL_MS);
14080
+ });
14081
+ }
14082
+ throw new Error('Computation finalized but transaction signature not indexed after retries.');
14083
+ }
14084
+ if (compAcc !== null)
14085
+ lastStatus = 'queued';
14086
+ // eslint-disable-next-line no-await-in-loop
14087
+ await new Promise((r) => {
14088
+ setTimeout(r, POLL_INTERVAL_MS);
14089
+ });
14090
+ }
14091
+ const timeoutMsg = `Computation did not finalize within ${timeoutMs}ms (status: ${lastStatus})`;
14092
+ throw rpcErrorCount > 0
14093
+ ? new Error(timeoutMsg, { cause: new Error(`${rpcErrorCount} RPC errors, last: ${lastError}`) })
14094
+ : new Error(timeoutMsg);
14055
14095
  }
14056
14096
 
14057
14097
  export { ARCIUM_ADDR, ARCIUM_IDL, Aes128Cipher, Aes192Cipher, Aes256Cipher, ArcisModule, ArcisType, ArcisValueField, CSplRescueCipher, CURVE25519_BASE_FIELD, CURVE25519_SCALAR_FIELD, CURVE25519_SCALAR_FIELD_MODULUS, IntegerInfo, Matrix, RescueCipher, RescueDesc, RescuePrimeHash, arcisEd25519, awaitComputationFinalization, buildFinalizeCompDefTx, createPacker, deserializeLE, finalizeKeyRecoveryExecution, generateRandomFieldElem, getArciumAccountBaseSeed, getArciumEnv, getArciumProgram, getArciumProgramId, getArxNodeAccAddress, getCircuitState, getClockAccAddress, getClusterAccAddress, getCompDefAccAddress, getCompDefAccOffset, getComputationAccAddress, getComputationsInMempool, getExecutingPoolAccAddress, getExecutingPoolAccInfo, getFeePoolAccAddress, getLookupTableAddress, getMXEAccAddress, getMXEArcisEd25519VerifyingKey, getMXEPublicKey, getMempoolAccAddress, getMempoolAccInfo, getMempoolPriorityFeeStats, getMxeRecoveryAccAddress, getRawCircuitAccAddress, getRecoveryClusterAccAddress, initKeyRecoveryExecution, initMxePart1, initMxePart2, isNullRef, positiveModulo, queueKeyRecoveryInit, randMatrix, recoverMxe, serializeLE, sha256, submitKeyRecoveryShare, toVec, uploadCircuit };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcium-hq/client",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Client SDK for interacting with encrypted Solana programs",
5
5
  "author": "Arcium",
6
6
  "license": "GPL-3.0-only",