@arcanetech/privacy-sdk-stellar 0.2.3 → 0.3.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.
@@ -90,6 +90,12 @@ interface StellarKytEnvironment {
90
90
  }
91
91
  interface StellarTransactEnvironment {
92
92
  network: StellarNetworkConfig;
93
+ /**
94
+ * Nonce (persistent storage key) of the pool's `ZkConfig` entry this
95
+ * environment's proofs/circuit shape target. Defaults to `0n` (the
96
+ * standard circuit) when omitted.
97
+ */
98
+ zkConfigNonce?: bigint;
93
99
  auditPublicKey?: AuditPublicKey;
94
100
  kyt: StellarKytEnvironment;
95
101
  signTransaction?: StellarSignTransaction;
@@ -1155,6 +1155,12 @@ async function registerKytPassage(parameters) {
1155
1155
  await waitForKytRegistration({ server, hash: result.hash });
1156
1156
  }
1157
1157
 
1158
+ // src/transact/environment/zk-config-nonce.ts
1159
+ var DEFAULT_ZK_CONFIG_NONCE = 0n;
1160
+ function resolveZkConfigNonce(transactEnvironment) {
1161
+ return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1162
+ }
1163
+
1158
1164
  // src/transact/kyt/passage/inspect.ts
1159
1165
  function buildApplicationIdHints(applicationId) {
1160
1166
  return [applicationId, applicationId, applicationId, applicationId];
@@ -1208,6 +1214,7 @@ async function requestKytPassageForPoolInteraction(input) {
1208
1214
  decryptedAuditSlots: input.decryptedAuditSlots,
1209
1215
  onboarding: input.onboarding,
1210
1216
  nonce: buildNonce(),
1217
+ zkConfigNonce: resolveZkConfigNonce(input.transactEnvironment),
1211
1218
  currentLedger
1212
1219
  },
1213
1220
  kytJsonReplacer
@@ -1274,11 +1281,123 @@ async function runTtlPreflight(assembledTransaction) {
1274
1281
  await maybeCallFunction(assembledTransaction, "simulate");
1275
1282
  }
1276
1283
 
1284
+ // src/transact/submit/zk-config-ttl.ts
1285
+ import {
1286
+ Address,
1287
+ Operation as Operation2,
1288
+ SorobanDataBuilder,
1289
+ TransactionBuilder as TransactionBuilder2,
1290
+ rpc as rpc3,
1291
+ xdr as xdr2
1292
+ } from "@stellar/stellar-sdk";
1293
+ var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
1294
+ var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
1295
+ var EXTEND_TTL_FEE_STROOPS = "1000000";
1296
+ var EXTEND_TTL_TIMEOUT_SECONDS = 300;
1297
+ var EXTEND_TTL_MAX_POLLS = 60;
1298
+ var EXTEND_TTL_POLL_INTERVAL_MS = 1e3;
1299
+ async function waitForExtendFootprintTtlConfirmation(parameters) {
1300
+ for (let attempt = 0; attempt < EXTEND_TTL_MAX_POLLS; attempt += 1) {
1301
+ const response = await parameters.server.getTransaction(parameters.hash);
1302
+ if (response.status === "SUCCESS") {
1303
+ return;
1304
+ }
1305
+ if (response.status === "FAILED") {
1306
+ throw new Error("ZK config TTL extension failed on-chain");
1307
+ }
1308
+ await new Promise((resolve) => {
1309
+ setTimeout(resolve, EXTEND_TTL_POLL_INTERVAL_MS);
1310
+ });
1311
+ }
1312
+ throw new Error("ZK config TTL extension was not confirmed in time");
1313
+ }
1314
+ function zkConfigLedgerKey(contractId, nonce) {
1315
+ const configKeyScValue = xdr2.ScVal.scvVec([
1316
+ xdr2.ScVal.scvSymbol("Config"),
1317
+ xdr2.ScVal.scvU64(xdr2.Uint64.fromString(nonce.toString()))
1318
+ ]);
1319
+ return xdr2.LedgerKey.contractData(
1320
+ new xdr2.LedgerKeyContractData({
1321
+ contract: new Address(contractId).toScAddress(),
1322
+ key: configKeyScValue,
1323
+ durability: xdr2.ContractDataDurability.persistent()
1324
+ })
1325
+ );
1326
+ }
1327
+ async function needsTtlExtension(parameters) {
1328
+ const [entriesResponse, latestLedger] = await Promise.all([
1329
+ parameters.server.getLedgerEntries(parameters.ledgerKey),
1330
+ parameters.server.getLatestLedger()
1331
+ ]);
1332
+ const entry = entriesResponse.entries.at(0);
1333
+ if (!entry || entry.liveUntilLedgerSeq === void 0) {
1334
+ return false;
1335
+ }
1336
+ const remainingLedgers = entry.liveUntilLedgerSeq - latestLedger.sequence;
1337
+ return remainingLedgers < ZK_CONFIG_TTL_THRESHOLD_LEDGERS;
1338
+ }
1339
+ async function submitExtendFootprintTtlTransaction(parameters) {
1340
+ const sourceAccount = await parameters.server.getAccount(parameters.sourcePublicKey);
1341
+ const transaction = new TransactionBuilder2(sourceAccount, {
1342
+ fee: EXTEND_TTL_FEE_STROOPS,
1343
+ networkPassphrase: parameters.networkPassphrase
1344
+ }).addOperation(
1345
+ Operation2.extendFootprintTtl({ extendTo: ZK_CONFIG_TTL_EXTEND_TO_LEDGERS })
1346
+ ).setSorobanData(
1347
+ new SorobanDataBuilder().setReadOnly([parameters.ledgerKey]).build()
1348
+ ).setTimeout(EXTEND_TTL_TIMEOUT_SECONDS).build();
1349
+ const preparedTransaction = await parameters.server.prepareTransaction(transaction);
1350
+ const { signedTxXdr } = await parameters.signTransaction({
1351
+ xdr: preparedTransaction.toXDR(),
1352
+ networkPassphrase: parameters.networkPassphrase,
1353
+ address: parameters.sourcePublicKey
1354
+ });
1355
+ const signedTransaction = TransactionBuilder2.fromXDR(
1356
+ signedTxXdr,
1357
+ parameters.networkPassphrase
1358
+ );
1359
+ const result = await parameters.server.sendTransaction(signedTransaction);
1360
+ const status = String(result.status);
1361
+ if (status !== "PENDING" && status !== "SUCCESS") {
1362
+ throw new Error(`ZK config TTL extension submit failed: ${status}`);
1363
+ }
1364
+ await waitForExtendFootprintTtlConfirmation({
1365
+ server: parameters.server,
1366
+ hash: result.hash
1367
+ });
1368
+ }
1369
+ async function extendZkConfigTtlIfNeeded(parameters) {
1370
+ if (!parameters.signTransaction) {
1371
+ return;
1372
+ }
1373
+ const server = new rpc3.Server(parameters.sorobanRpcUrl, { allowHttp: true });
1374
+ const ledgerKey = zkConfigLedgerKey(parameters.contractId, parameters.nonce);
1375
+ if (!await needsTtlExtension({ server, ledgerKey })) {
1376
+ return;
1377
+ }
1378
+ await submitExtendFootprintTtlTransaction({
1379
+ server,
1380
+ ledgerKey,
1381
+ networkPassphrase: parameters.networkPassphrase,
1382
+ sourcePublicKey: parameters.sourcePublicKey,
1383
+ signTransaction: parameters.signTransaction
1384
+ });
1385
+ }
1386
+
1277
1387
  // src/transact/submit/pool-transact.ts
1278
1388
  import { Buffer as Buffer11 } from "buffer";
1279
1389
  async function submitPoolTransact(parameters) {
1390
+ await extendZkConfigTtlIfNeeded({
1391
+ sorobanRpcUrl: parameters.sorobanRpcUrl,
1392
+ networkPassphrase: parameters.networkPassphrase,
1393
+ contractId: parameters.contractId,
1394
+ nonce: parameters.nonce,
1395
+ sourcePublicKey: parameters.from,
1396
+ signTransaction: parameters.transactEnvironment.signTransaction
1397
+ });
1280
1398
  const assembledTransaction = await parameters.contractClient.transact({
1281
1399
  from: parameters.from,
1400
+ nonce: parameters.nonce,
1282
1401
  proof_bytes: Buffer11.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
1283
1402
  pub_signals_bytes: Buffer11.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
1284
1403
  onboarding: parameters.onboarding,
@@ -1325,10 +1444,15 @@ async function submitSorobanDeposit(input) {
1325
1444
  });
1326
1445
  return submitPoolTransact({
1327
1446
  contractClient: poolClient,
1447
+ contractId: input.contractId,
1328
1448
  from: input.walletPublicKey,
1449
+ nonce: resolveZkConfigNonce(input.transactEnvironment),
1329
1450
  proofHex: proof_hex,
1330
1451
  publicHex: public_hex,
1331
- approval
1452
+ approval,
1453
+ networkPassphrase: input.networkPassphrase,
1454
+ sorobanRpcUrl: input.sorobanRpcUrl,
1455
+ transactEnvironment: input.transactEnvironment
1332
1456
  });
1333
1457
  }
1334
1458
 
@@ -1353,11 +1477,16 @@ async function submitSorobanConfidentialTransfer(input) {
1353
1477
  });
1354
1478
  return submitPoolTransact({
1355
1479
  contractClient: poolClient,
1480
+ contractId: input.contractId,
1356
1481
  from: input.walletPublicKey,
1482
+ nonce: resolveZkConfigNonce(input.transactEnvironment),
1357
1483
  proofHex: input.proofHex,
1358
1484
  publicHex: input.publicHex,
1359
1485
  ...input.onboarding ? { onboarding: input.onboarding } : {},
1360
- approval
1486
+ approval,
1487
+ networkPassphrase: input.networkPassphrase,
1488
+ sorobanRpcUrl: input.sorobanRpcUrl,
1489
+ transactEnvironment: input.transactEnvironment
1361
1490
  });
1362
1491
  }
1363
1492