@arcium-hq/client 0.6.4 → 0.6.6

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/README.md CHANGED
@@ -180,7 +180,7 @@ await uploadCircuit(
180
180
  "your_circuit_name",
181
181
  program.programId,
182
182
  rawCircuit,
183
- true // use raw circuit
183
+ true // enable logging
184
184
  );
185
185
  ```
186
186
 
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.6.4",
1812
+ version: "0.6.6",
1813
1813
  spec: "0.1.0",
1814
1814
  description: "The Arcium program"
1815
1815
  };
@@ -2904,6 +2904,107 @@ var instructions = [
2904
2904
  }
2905
2905
  ]
2906
2906
  },
2907
+ {
2908
+ name: "claim_node_fees",
2909
+ discriminator: [
2910
+ 68,
2911
+ 13,
2912
+ 185,
2913
+ 34,
2914
+ 151,
2915
+ 76,
2916
+ 194,
2917
+ 43
2918
+ ],
2919
+ accounts: [
2920
+ {
2921
+ name: "node_authority",
2922
+ writable: true,
2923
+ signer: true
2924
+ },
2925
+ {
2926
+ name: "recipient",
2927
+ writable: true
2928
+ },
2929
+ {
2930
+ name: "cluster",
2931
+ writable: true,
2932
+ pda: {
2933
+ seeds: [
2934
+ {
2935
+ kind: "const",
2936
+ value: [
2937
+ 67,
2938
+ 108,
2939
+ 117,
2940
+ 115,
2941
+ 116,
2942
+ 101,
2943
+ 114
2944
+ ]
2945
+ },
2946
+ {
2947
+ kind: "arg",
2948
+ path: "cluster_offset"
2949
+ }
2950
+ ]
2951
+ }
2952
+ },
2953
+ {
2954
+ name: "node",
2955
+ pda: {
2956
+ seeds: [
2957
+ {
2958
+ kind: "const",
2959
+ value: [
2960
+ 65,
2961
+ 114,
2962
+ 120,
2963
+ 78,
2964
+ 111,
2965
+ 100,
2966
+ 101
2967
+ ]
2968
+ },
2969
+ {
2970
+ kind: "arg",
2971
+ path: "node_offset"
2972
+ }
2973
+ ]
2974
+ }
2975
+ },
2976
+ {
2977
+ name: "pool",
2978
+ writable: true,
2979
+ pda: {
2980
+ seeds: [
2981
+ {
2982
+ kind: "const",
2983
+ value: [
2984
+ 70,
2985
+ 101,
2986
+ 101,
2987
+ 80,
2988
+ 111,
2989
+ 111,
2990
+ 108
2991
+ ]
2992
+ }
2993
+ ]
2994
+ }
2995
+ }
2996
+ ],
2997
+ args: [
2998
+ {
2999
+ name: "cluster_offset",
3000
+ type: "u32"
3001
+ },
3002
+ {
3003
+ name: "node_offset",
3004
+ type: "u32"
3005
+ }
3006
+ ]
3007
+ },
2907
3008
  {
2908
3009
  name: "close_key_recovery",
2909
3010
  docs: [
@@ -3964,6 +4065,29 @@ var instructions = [
3964
4065
  ]
3965
4066
  }
3966
4067
  },
4068
+ {
4069
+ name: "cluster_acc",
4070
+ pda: {
4071
+ seeds: [
4072
+ {
4073
+ kind: "const",
4074
+ value: [
4075
+ 67,
4076
+ 108,
4077
+ 117,
4078
+ 115,
4079
+ 116,
4080
+ 101,
4081
+ 114
4082
+ ]
4083
+ },
4084
+ {
4085
+ kind: "arg",
4086
+ path: "cluster_offset"
4087
+ }
4088
+ ]
4089
+ }
4090
+ },
3967
4091
  {
3968
4092
  name: "executing_pool",
3969
4093
  writable: true,
@@ -4052,6 +4176,17 @@ var instructions = [
4052
4176
  {
4053
4177
  name: "callback_transaction_index",
4054
4178
  type: "u8"
4179
+ },
4180
+ {
4181
+ name: "bls_sig",
4182
+ type: {
4183
+ option: {
4184
+ array: [
4185
+ "u8",
4186
+ 64
4187
+ ]
4188
+ }
4189
+ }
4055
4190
  }
4056
4191
  ]
4057
4192
  },
@@ -5143,6 +5278,17 @@ var instructions = [
5143
5278
  ]
5144
5279
  }
5145
5280
  },
5281
+ {
5282
+ name: "address_lookup_table",
5283
+ docs: [
5284
+ "Seeds are checked in the CPI to LUT program, so no need to check them here."
5285
+ ],
5286
+ writable: true
5287
+ },
5288
+ {
5289
+ name: "lut_program",
5290
+ address: "AddressLookupTab1e1111111111111111111111111"
5291
+ },
5146
5292
  {
5147
5293
  name: "comp_def_acc",
5148
5294
  writable: true,
@@ -5257,6 +5403,11 @@ var instructions = [
5257
5403
  224
5258
5404
  ],
5259
5405
  accounts: [
5406
+ {
5407
+ name: "authority",
5408
+ writable: true,
5409
+ signer: true
5410
+ },
5260
5411
  {
5261
5412
  name: "payer",
5262
5413
  writable: true,
@@ -6054,6 +6205,17 @@ var instructions = [
6054
6205
  ]
6055
6206
  }
6056
6207
  },
6208
+ {
6209
+ name: "address_lookup_table",
6210
+ docs: [
6211
+ "Seeds are checked in the CPI to LUT program, so no need to check them here."
6212
+ ],
6213
+ writable: true
6214
+ },
6215
+ {
6216
+ name: "lut_program",
6217
+ address: "AddressLookupTab1e1111111111111111111111111"
6218
+ },
6057
6219
  {
6058
6220
  name: "clock",
6059
6221
  writable: true,
@@ -7036,12 +7198,6 @@ var instructions = [
7036
7198
  name: "mxe_program",
7037
7199
  type: "pubkey"
7038
7200
  },
7039
- {
7040
- name: "callback_url",
7041
- type: {
7042
- option: "string"
7043
- }
7044
- },
7045
7201
  {
7046
7202
  name: "custom_callback_instructions",
7047
7203
  type: {
@@ -7432,16 +7588,16 @@ var instructions = [
7432
7588
  ]
7433
7589
  },
7434
7590
  {
7435
- name: "reclaim_failure_rent",
7591
+ name: "reclaim_failure_rent_idempotent",
7436
7592
  discriminator: [
7437
- 159,
7438
- 99,
7439
- 116,
7440
- 180,
7441
- 42,
7442
- 9,
7443
- 202,
7444
- 219
7593
+ 138,
7594
+ 13,
7595
+ 253,
7596
+ 191,
7597
+ 226,
7598
+ 239,
7599
+ 246,
7600
+ 10
7445
7601
  ],
7446
7602
  accounts: [
7447
7603
  {
@@ -7449,51 +7605,19 @@ var instructions = [
7449
7605
  writable: true,
7450
7606
  signer: true
7451
7607
  },
7608
+ {
7609
+ name: "recipient",
7610
+ docs: [
7611
+ "failure PDA"
7612
+ ],
7613
+ writable: true
7614
+ },
7452
7615
  {
7453
7616
  name: "failure_acc",
7454
- writable: true,
7455
- pda: {
7456
- seeds: [
7457
- {
7458
- kind: "const",
7459
- value: [
7460
- 70,
7461
- 97,
7462
- 105,
7463
- 108,
7464
- 117,
7465
- 114,
7466
- 101,
7467
- 67,
7468
- 108,
7469
- 97,
7470
- 105,
7471
- 109,
7472
- 65,
7473
- 99,
7474
- 99,
7475
- 111,
7476
- 117,
7477
- 110,
7478
- 116,
7479
- 72,
7480
- 101,
7481
- 97,
7482
- 100,
7483
- 101,
7484
- 114
7485
- ]
7486
- },
7487
- {
7488
- kind: "arg",
7489
- path: "mxe_program"
7490
- },
7491
- {
7492
- kind: "arg",
7493
- path: "comp_offset"
7494
- }
7495
- ]
7496
- }
7617
+ docs: [
7618
+ "the checks and close by hand in the instruction handler."
7619
+ ],
7620
+ writable: true
7497
7621
  }
7498
7622
  ],
7499
7623
  args: [
@@ -9590,6 +9714,19 @@ var events = [
9590
9714
  186
9591
9715
  ]
9592
9716
  },
9717
+ {
9718
+ name: "KeyRecoveryEvent",
9719
+ discriminator: [
9720
+ 83,
9721
+ 147,
9722
+ 226,
9723
+ 153,
9724
+ 39,
9725
+ 242,
9726
+ 109,
9727
+ 254
9728
+ ]
9729
+ },
9593
9730
  {
9594
9731
  name: "QueueComputationEvent",
9595
9732
  discriminator: [
@@ -9730,6 +9867,11 @@ var errors = [
9730
9867
  name: "InvalidCallbackIndex",
9731
9868
  msg: "Invalid callback transaction index"
9732
9869
  },
9870
+ {
9871
+ code: 6212,
9872
+ name: "MultiTxCallbacksDisabled",
9873
+ msg: "Multi-transaction callbacks disabled"
9874
+ },
9733
9875
  {
9734
9876
  code: 6300,
9735
9877
  name: "ComputationDefinitionNotCompleted",
@@ -9960,6 +10102,16 @@ var errors = [
9960
10102
  name: "MustNotBeCalledViaCpi",
9961
10103
  msg: "This instruction must be called directly, not via CPI"
9962
10104
  },
10105
+ {
10106
+ code: 6621,
10107
+ name: "FeePriceExceedsMax",
10108
+ msg: "Fee price exceeds maximum allowed"
10109
+ },
10110
+ {
10111
+ code: 6622,
10112
+ name: "NoFeesToClaim",
10113
+ msg: "No fees available to claim"
10114
+ },
9963
10115
  {
9964
10116
  code: 6700,
9965
10117
  name: "MxeNotInRecoveryState",
@@ -10042,8 +10194,8 @@ var errors = [
10042
10194
  },
10043
10195
  {
10044
10196
  code: 6716,
10045
- name: "FeePriceExceedsMax",
10046
- msg: "Fee price exceeds maximum allowed"
10197
+ name: "MxeInRecoveryState",
10198
+ msg: "MXE is in recovery state, cannot queue new computations"
10047
10199
  }
10048
10200
  ];
10049
10201
  var types = [
@@ -10886,12 +11038,6 @@ var types = [
10886
11038
  }
10887
11039
  }
10888
11040
  },
10889
- {
10890
- name: "callback_url",
10891
- type: {
10892
- option: "string"
10893
- }
10894
- },
10895
11041
  {
10896
11042
  name: "custom_callback_instructions",
10897
11043
  type: {
@@ -11371,6 +11517,26 @@ var types = [
11371
11517
  ]
11372
11518
  }
11373
11519
  },
11520
+ {
11521
+ name: "KeyRecoveryEvent",
11522
+ type: {
11523
+ kind: "struct",
11524
+ fields: [
11525
+ {
11526
+ name: "computation_offset",
11527
+ type: "u64"
11528
+ },
11529
+ {
11530
+ name: "mxe_program_id",
11531
+ type: "pubkey"
11532
+ },
11533
+ {
11534
+ name: "backup_mxe_program_id",
11535
+ type: "pubkey"
11536
+ }
11537
+ ]
11538
+ }
11539
+ },
11374
11540
  {
11375
11541
  name: "LargeExecPool",
11376
11542
  serialization: "bytemuckunsafe",
@@ -12949,6 +13115,11 @@ const RECOVERY_CLUSTER_ACC_SEED = 'RecoveryClusterAccount';
12949
13115
  * @constant {string}
12950
13116
  */
12951
13117
  const MXE_RECOVERY_ACC_SEED = 'MxeRecoveryAccount';
13118
+ /**
13119
+ * Seed for ComputationDefinitionRaw PDA
13120
+ * @constant {string}
13121
+ */
13122
+ const RAW_CIRCUIT_ACC_SEED = 'ComputationDefinitionRaw';
12952
13123
  /**
12953
13124
  * Maximum number of bytes that can be reallocated per instruction.
12954
13125
  * @constant {number}
@@ -13108,6 +13279,32 @@ function getMxeRecoveryAccAddress(backupMxeProgramId, originalMxeProgramId) {
13108
13279
  ];
13109
13280
  return generateArciumPDAFrom(seeds)[0];
13110
13281
  }
13282
+ /**
13283
+ * Derives the raw circuit account address for a given computation definition and index.
13284
+ * @param compDefPubkey - The public key of the computation definition account.
13285
+ * @param rawCircuitIndex - The index of the raw circuit account (0-based).
13286
+ * @returns The derived raw circuit account public key.
13287
+ */
13288
+ function getRawCircuitAccAddress(compDefPubkey, rawCircuitIndex) {
13289
+ const seeds = [
13290
+ Buffer.from(RAW_CIRCUIT_ACC_SEED),
13291
+ compDefPubkey.toBuffer(),
13292
+ Buffer.from([rawCircuitIndex]),
13293
+ ];
13294
+ return generateArciumPDAFrom(seeds)[0];
13295
+ }
13296
+ /**
13297
+ * Derives the address lookup table address for an MXE program.
13298
+ * @param mxeProgramId - The public key of the MXE program.
13299
+ * @param lutIndex - The index of the lookup table (defaults to 0).
13300
+ * @returns The derived address lookup table public key.
13301
+ */
13302
+ function getLookupTableAddress(mxeProgramId, lutIndex = 0) {
13303
+ const mxeAccount = getMXEAccAddress(mxeProgramId);
13304
+ const lutIndexBuffer = new anchor__namespace.BN(lutIndex).toArrayLike(Buffer, 'le', 8);
13305
+ const seeds = [mxeAccount.toBuffer(), lutIndexBuffer];
13306
+ return web3_js.PublicKey.findProgramAddressSync(seeds, web3_js.AddressLookupTableProgram.programId)[0];
13307
+ }
13111
13308
  /**
13112
13309
  * Generates a program-derived address (PDA) from the provided seeds and the Arcium program ID.
13113
13310
  * @param seeds - An array of Buffer seeds used for PDA derivation.
@@ -13360,6 +13557,21 @@ async function getMXEPublicKey(provider, mxeProgramId) {
13360
13557
  async function getMXEArcisEd25519VerifyingKey(provider, mxeProgramId) {
13361
13558
  return getMXEUtilityKey(provider, mxeProgramId, 'ed25519VerifyingKey');
13362
13559
  }
13560
+ /**
13561
+ * Determines the current state of a circuit based on its on-chain configuration.
13562
+ * @internal Called internally by `uploadCircuit` - most users don't need this directly.
13563
+ * @param circuitSource - The circuitSource field from ComputationDefinitionAccount.
13564
+ * @returns The current state of the circuit.
13565
+ */
13566
+ function getCircuitState(circuitSource) {
13567
+ if (!('onChain' in circuitSource) || !circuitSource.onChain) {
13568
+ return 'Offchain';
13569
+ }
13570
+ if (circuitSource.onChain[0].isCompleted) {
13571
+ return 'OnchainFinalized';
13572
+ }
13573
+ return 'OnchainPending';
13574
+ }
13363
13575
  /**
13364
13576
  * Uploads a circuit to the blockchain, splitting it into multiple accounts if necessary.
13365
13577
  * @param provider - The Anchor provider to use for transactions.
@@ -13371,10 +13583,17 @@ async function getMXEArcisEd25519VerifyingKey(provider, mxeProgramId) {
13371
13583
  * @returns An array of transaction signatures for all upload and finalize transactions.
13372
13584
  */
13373
13585
  async function uploadCircuit(provider, circuitName, mxeProgramId, rawCircuit, logging = true, chunkSize = 500) {
13374
- // 9 = 8-byte discriminator + 1-byte bump for ComputationDefinitionRaw account
13375
- const numAccs = Math.ceil(rawCircuit.length / (MAX_ACCOUNT_SIZE - 9));
13376
13586
  const compDefAccInfo = getCompDefAccInfo(circuitName, mxeProgramId);
13377
13587
  const program = getArciumProgram(provider);
13588
+ const compDefAcc = await program.account.computationDefinitionAccount.fetch(compDefAccInfo.pubkey);
13589
+ // Type assertion at boundary where Anchor's fetch() returns the account data
13590
+ const state = getCircuitState(compDefAcc.circuitSource);
13591
+ if (state !== 'OnchainPending') {
13592
+ optionalLog(logging, `Circuit ${circuitName} skipped: ${state}`);
13593
+ return [];
13594
+ }
13595
+ // 9 = 8-byte discriminator + 1-byte bump for ComputationDefinitionRaw account
13596
+ const numAccs = Math.ceil(rawCircuit.length / (MAX_ACCOUNT_SIZE - 9));
13378
13597
  const sigs = [];
13379
13598
  const uploadPromises = [];
13380
13599
  for (let i = 0; i < numAccs; i++) {
@@ -13417,15 +13636,26 @@ async function buildFinalizeCompDefTx(provider, compDefOffset, mxeProgramId) {
13417
13636
  .transaction();
13418
13637
  }
13419
13638
  async function uploadToCircuitAcc(provider, program, rawCircuitPart, rawCircuitIndex, compDefAccInfo, mxeProgramId, shouldLog = true, chunkSize = 500) {
13639
+ const rawCircuitPda = getRawCircuitAccAddress(compDefAccInfo.pubkey, rawCircuitIndex);
13640
+ const existingAcc = await provider.connection.getAccountInfo(rawCircuitPda);
13641
+ // Skip entirely if account exists with correct size (pre-seeded at genesis or already uploaded)
13642
+ // Account layout: 8-byte discriminator + 1-byte bump + circuit data
13643
+ const requiredAccountSize = rawCircuitPart.length + 9;
13644
+ if (existingAcc !== null && existingAcc.data.length >= requiredAccountSize) {
13645
+ optionalLog(shouldLog, `Raw circuit acc ${rawCircuitIndex} already exists with sufficient size, skipping`);
13646
+ return [];
13647
+ }
13420
13648
  const sigs = [];
13421
- const initTx = await program.methods
13422
- .initRawCircuitAcc(compDefAccInfo.offset, mxeProgramId, rawCircuitIndex)
13423
- .accounts({
13424
- signer: provider.publicKey,
13425
- })
13426
- .rpc();
13427
- optionalLog(shouldLog, `Initiated raw circuit acc with raw circuit index ${rawCircuitIndex}`);
13428
- sigs.push(initTx);
13649
+ if (existingAcc === null) {
13650
+ const initTx = await program.methods
13651
+ .initRawCircuitAcc(compDefAccInfo.offset, mxeProgramId, rawCircuitIndex)
13652
+ .accounts({
13653
+ signer: provider.publicKey,
13654
+ })
13655
+ .rpc();
13656
+ optionalLog(shouldLog, `Initiated raw circuit acc with raw circuit index ${rawCircuitIndex}`);
13657
+ sigs.push(initTx);
13658
+ }
13429
13659
  if (rawCircuitPart.length > MAX_REALLOC_PER_IX) {
13430
13660
  // We only need to add size if the init didn't already make us big enough
13431
13661
  const nonAsyncTxCount = Math.ceil(rawCircuitPart.length / (MAX_REALLOC_PER_IX * MAX_EMBIGGEN_IX_PER_TX));
@@ -13450,8 +13680,10 @@ async function uploadToCircuitAcc(provider, program, rawCircuitPart, rawCircuitI
13450
13680
  const blockInfo = await provider.connection.getLatestBlockhash();
13451
13681
  for (let i = 0; i < remainingTxCount; i += chunkSize) {
13452
13682
  optionalLog(shouldLog, `Sending chunk ${i / chunkSize + 1} of ${Math.ceil(remainingTxCount / chunkSize)}`);
13453
- const chunkPromises = []; // Array to hold promises for the current chunk
13454
- const currentChunkSize = Math.min(chunkSize, remainingTxCount - i); // Handle the last chunk
13683
+ // Array to hold promises for the current chunk
13684
+ const chunkPromises = [];
13685
+ // Handle the last chunk
13686
+ const currentChunkSize = Math.min(chunkSize, remainingTxCount - i);
13455
13687
  for (let j = 0; j < currentChunkSize; j++) {
13456
13688
  const offset = MAX_UPLOAD_PER_TX_BYTES * (i + j);
13457
13689
  // eslint-disable-next-line no-await-in-loop
@@ -13461,7 +13693,8 @@ async function uploadToCircuitAcc(provider, program, rawCircuitPart, rawCircuitI
13461
13693
  // Wait for the current chunk to complete before proceeding
13462
13694
  // eslint-disable-next-line no-await-in-loop
13463
13695
  const chunkResults = await Promise.all(chunkPromises);
13464
- remainingTxs.push(...chunkResults); // Add the results of the current chunk to the main array
13696
+ // Add the results of the current chunk to the main array
13697
+ remainingTxs.push(...chunkResults);
13465
13698
  optionalLog(shouldLog, `Done sending chunk ${i / chunkSize + 1} of ${Math.ceil(remainingTxCount / chunkSize)}`);
13466
13699
  }
13467
13700
  return sigs.concat(remainingTxs);
@@ -13711,6 +13944,7 @@ async function initMxePart2(provider, clusterOffset, mxeProgramId, recoveryPeers
13711
13944
  mxeProgram: mxeProgramId,
13712
13945
  poolAccount: getFeePoolAccAddress(),
13713
13946
  mxeAuthority: mxeAuthority ?? provider.publicKey,
13947
+ addressLookupTable: getLookupTableAddress(mxeProgramId),
13714
13948
  })
13715
13949
  .transaction();
13716
13950
  return signAndSendWithBlockhash(provider, tx, await provider.connection.getLatestBlockhash({ commitment: 'confirmed' }));
@@ -13807,6 +14041,7 @@ exports.getArciumEnv = getArciumEnv;
13807
14041
  exports.getArciumProgram = getArciumProgram;
13808
14042
  exports.getArciumProgramId = getArciumProgramId;
13809
14043
  exports.getArxNodeAccAddress = getArxNodeAccAddress;
14044
+ exports.getCircuitState = getCircuitState;
13810
14045
  exports.getClockAccAddress = getClockAccAddress;
13811
14046
  exports.getClusterAccAddress = getClusterAccAddress;
13812
14047
  exports.getCompDefAccAddress = getCompDefAccAddress;
@@ -13816,6 +14051,7 @@ exports.getComputationsInMempool = getComputationsInMempool;
13816
14051
  exports.getExecutingPoolAccAddress = getExecutingPoolAccAddress;
13817
14052
  exports.getExecutingPoolAccInfo = getExecutingPoolAccInfo;
13818
14053
  exports.getFeePoolAccAddress = getFeePoolAccAddress;
14054
+ exports.getLookupTableAddress = getLookupTableAddress;
13819
14055
  exports.getMXEAccAddress = getMXEAccAddress;
13820
14056
  exports.getMXEArcisEd25519VerifyingKey = getMXEArcisEd25519VerifyingKey;
13821
14057
  exports.getMXEPublicKey = getMXEPublicKey;
@@ -13823,6 +14059,7 @@ exports.getMempoolAccAddress = getMempoolAccAddress;
13823
14059
  exports.getMempoolAccInfo = getMempoolAccInfo;
13824
14060
  exports.getMempoolPriorityFeeStats = getMempoolPriorityFeeStats;
13825
14061
  exports.getMxeRecoveryAccAddress = getMxeRecoveryAccAddress;
14062
+ exports.getRawCircuitAccAddress = getRawCircuitAccAddress;
13826
14063
  exports.getRecoveryClusterAccAddress = getRecoveryClusterAccAddress;
13827
14064
  exports.initKeyRecoveryExecution = initKeyRecoveryExecution;
13828
14065
  exports.initMxePart1 = initMxePart1;