@arcanetech/privacy-sdk-stellar 0.4.1 → 0.5.1

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
@@ -61,7 +61,7 @@ const clientOrRejected = await createStellarPrivacyClientFromNodeConfig({
61
61
 
62
62
  ## Required Assets
63
63
 
64
- The Stellar preset loads proving artifacts from the GitHub release for `@arcanetech/stellar-privacy-pool-zk-sdk`. Pass `sdkWasm` (browser) or `sdkWasmPath` (Node). Override `transactEnvironment.zkArtifactBaseUrl` for local files. Custom circuit URLs are only for development. Do not regenerate `ptau` or Groth16 zkey files inside this repository.
64
+ The Stellar preset loads proving artifacts from the CDN baked into `@arcanetech/stellar-privacy-pool-zk-sdk`. Pass `sdkWasm` (browser) or `sdkWasmPath` (Node). Override `transactEnvironment.zkArtifactBaseUrl` for local files. The browser bundle stores those proving files in Cache Storage (keyed by zk-sdk version) so a later visit or a second `init` in the same origin reuses the download. Node still reads files from disk or HTTP without Cache Storage. Custom circuit URLs are only for development. Do not regenerate `ptau` or Groth16 zkey files inside this repository.
65
65
 
66
66
  ## Related Docs
67
67
 
package/dist/index.d.ts CHANGED
@@ -243,7 +243,7 @@ interface StellarTransactEnvironment {
243
243
  zkCircuits?: Record<string, StellarZkCircuitDefinition>;
244
244
  /**
245
245
  * Directory or HTTP prefix for graph / r1cs / proving-key files.
246
- * Defaults to the GitHub release for `@arcanetech/stellar-privacy-pool-zk-sdk`.
246
+ * Defaults to the CDN prefix baked into `@arcanetech/stellar-privacy-pool-zk-sdk`.
247
247
  * Staging and local stands override this to serve files from disk.
248
248
  */
249
249
  zkArtifactBaseUrl?: string;
package/dist/index.js CHANGED
@@ -1155,6 +1155,111 @@ function resolveZkConfigNonce(transactEnvironment) {
1155
1155
  return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1156
1156
  }
1157
1157
 
1158
+ // src/transact/zk/browser-artifact-cache.ts
1159
+ import { ZK_ARTIFACT_VERSION } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1160
+ var ZK_ARTIFACT_CACHE_NAME = `privacy-sdk-stellar-zk-artifacts:${ZK_ARTIFACT_VERSION}`;
1161
+ function isBrowserCacheApiAvailable() {
1162
+ return browserCacheStorage() !== void 0;
1163
+ }
1164
+ function readCaches() {
1165
+ return globalThis.caches;
1166
+ }
1167
+ function browserCacheStorage() {
1168
+ const cachesValue = readCaches();
1169
+ if (cachesValue === void 0 || cachesValue === null) {
1170
+ return void 0;
1171
+ }
1172
+ return cachesValue;
1173
+ }
1174
+ function absoluteArtifactUrl(url) {
1175
+ if (/^[a-z][a-z0-9+.-]*:/i.test(url)) {
1176
+ return url;
1177
+ }
1178
+ const href = globalThis.location?.href;
1179
+ if (href === void 0) {
1180
+ return url;
1181
+ }
1182
+ return new URL(url, href).href;
1183
+ }
1184
+ async function rememberResponse(url, response) {
1185
+ const storage = browserCacheStorage();
1186
+ if (storage === void 0) {
1187
+ return;
1188
+ }
1189
+ try {
1190
+ const cache = await storage.open(ZK_ARTIFACT_CACHE_NAME);
1191
+ await cache.put(url, response.clone());
1192
+ } catch {
1193
+ return;
1194
+ }
1195
+ }
1196
+ async function fetchNetworkArrayBuffer(url) {
1197
+ const response = await fetch(url);
1198
+ if (!response.ok) {
1199
+ throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
1200
+ }
1201
+ await rememberResponse(url, response);
1202
+ return response.arrayBuffer();
1203
+ }
1204
+ async function fetchArrayBufferWithBrowserCache(url) {
1205
+ const requestUrl = absoluteArtifactUrl(url);
1206
+ const storage = browserCacheStorage();
1207
+ if (storage !== void 0) {
1208
+ const cache = await storage.open(ZK_ARTIFACT_CACHE_NAME);
1209
+ const cached = await cache.match(requestUrl);
1210
+ if (cached?.ok === true) {
1211
+ return cached.arrayBuffer();
1212
+ }
1213
+ }
1214
+ return fetchNetworkArrayBuffer(requestUrl);
1215
+ }
1216
+
1217
+ // src/transact/zk/prefetch-bundled-circuit.ts
1218
+ import {
1219
+ bundledCircuitFileNames,
1220
+ defaultZkArtifactBaseUrl
1221
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1222
+ function resolveArtifactBaseUrl(explicit) {
1223
+ const trimmed = explicit?.trim();
1224
+ if (trimmed === void 0 || trimmed === "") {
1225
+ return defaultZkArtifactBaseUrl();
1226
+ }
1227
+ let withoutSlash = trimmed;
1228
+ while (withoutSlash.endsWith("/")) {
1229
+ withoutSlash = withoutSlash.slice(0, -1);
1230
+ }
1231
+ return withoutSlash;
1232
+ }
1233
+ function artifactHref(base, fileName) {
1234
+ const withSlash = `${base}/`;
1235
+ if (/^https?:\/\//i.test(withSlash) || withSlash.startsWith("file:")) {
1236
+ return new URL(fileName, withSlash).href;
1237
+ }
1238
+ const href = globalThis.location?.href;
1239
+ if (href !== void 0) {
1240
+ return new URL(fileName, new URL(withSlash, href)).href;
1241
+ }
1242
+ return `${withSlash}${fileName}`;
1243
+ }
1244
+ async function materializeBundledCircuitWithBrowserCache(definition, zkArtifactBaseUrl) {
1245
+ const base = resolveArtifactBaseUrl(zkArtifactBaseUrl);
1246
+ const names = bundledCircuitFileNames(definition.circuit);
1247
+ const [circuitGraph, r1cs, provingKey] = await Promise.all([
1248
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.graphFileName)),
1249
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.r1csFileName)),
1250
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.provingKeyFileName))
1251
+ ]);
1252
+ return {
1253
+ nIns: definition.nIns,
1254
+ nOuts: definition.nOuts,
1255
+ publicNInputs: definition.publicNInputs,
1256
+ publicNOutputs: definition.publicNOutputs,
1257
+ circuitGraph,
1258
+ r1cs,
1259
+ provingKey
1260
+ };
1261
+ }
1262
+
1158
1263
  // src/transact/zk/circuit-config.ts
1159
1264
  import { BundledZkCircuit as BundledZkCircuit2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1160
1265
  var DEFAULT_STELLAR_ZK_CIRCUITS = {
@@ -1176,31 +1281,23 @@ var DEFAULT_STELLAR_ZK_CIRCUITS = {
1176
1281
  function isBundledDefinition(definition) {
1177
1282
  return "circuit" in definition;
1178
1283
  }
1179
- async function fetchBuffer(url) {
1180
- const response = await fetch(url);
1181
- if (!response.ok) {
1182
- throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
1183
- }
1184
- return response.arrayBuffer();
1284
+ function bundledConfig(definition) {
1285
+ return {
1286
+ nIns: definition.nIns,
1287
+ nOuts: definition.nOuts,
1288
+ publicNInputs: definition.publicNInputs,
1289
+ publicNOutputs: definition.publicNOutputs,
1290
+ circuit: definition.circuit
1291
+ };
1185
1292
  }
1186
- async function materializeDefinition(definition) {
1187
- if (isBundledDefinition(definition)) {
1188
- const bundled = {
1189
- nIns: definition.nIns,
1190
- nOuts: definition.nOuts,
1191
- publicNInputs: definition.publicNInputs,
1192
- publicNOutputs: definition.publicNOutputs,
1193
- circuit: definition.circuit
1194
- };
1195
- return bundled;
1196
- }
1293
+ async function materializeCustomDefinition(definition) {
1197
1294
  const [zkey, circuitGraph, r1cs, provingKey] = await Promise.all([
1198
- fetchBuffer(definition.zkeyUrl),
1199
- fetchBuffer(definition.circuitGraphUrl),
1200
- fetchBuffer(definition.r1csUrl),
1201
- fetchBuffer(definition.provingKeyUrl)
1295
+ fetchArrayBufferWithBrowserCache(definition.zkeyUrl),
1296
+ fetchArrayBufferWithBrowserCache(definition.circuitGraphUrl),
1297
+ fetchArrayBufferWithBrowserCache(definition.r1csUrl),
1298
+ fetchArrayBufferWithBrowserCache(definition.provingKeyUrl)
1202
1299
  ]);
1203
- const custom = {
1300
+ return {
1204
1301
  nIns: definition.nIns,
1205
1302
  nOuts: definition.nOuts,
1206
1303
  publicNInputs: definition.publicNInputs,
@@ -1210,16 +1307,24 @@ async function materializeDefinition(definition) {
1210
1307
  r1cs,
1211
1308
  provingKey
1212
1309
  };
1213
- return custom;
1214
1310
  }
1215
- async function materializeSelectedZkCircuit(circuits, nonce) {
1311
+ async function materializeDefinition(definition, zkArtifactBaseUrl) {
1312
+ if (!isBundledDefinition(definition)) {
1313
+ return materializeCustomDefinition(definition);
1314
+ }
1315
+ if (isBrowserCacheApiAvailable()) {
1316
+ return materializeBundledCircuitWithBrowserCache(definition, zkArtifactBaseUrl);
1317
+ }
1318
+ return bundledConfig(definition);
1319
+ }
1320
+ async function materializeSelectedZkCircuit(circuits, nonce, zkArtifactBaseUrl) {
1216
1321
  const map = stellarCircuitsOrDefault(circuits);
1217
1322
  const key = nonce.toString();
1218
1323
  const definition = Object.entries(map).find(([nonceKey]) => nonceKey === key)?.[1];
1219
1324
  if (!definition) {
1220
1325
  throw new Error(`no zk circuit configured for nonce ${key}`);
1221
1326
  }
1222
- return { [key]: await materializeDefinition(definition) };
1327
+ return { [key]: await materializeDefinition(definition, zkArtifactBaseUrl) };
1223
1328
  }
1224
1329
  function stellarCircuitsOrDefault(circuits) {
1225
1330
  return circuits ?? DEFAULT_STELLAR_ZK_CIRCUITS;
@@ -1335,7 +1440,8 @@ var PrivacyPoolService = class {
1335
1440
  const zkConfigNonce = this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1336
1441
  const zkCircuits = await materializeSelectedZkCircuit(
1337
1442
  this.zkCircuits,
1338
- zkConfigNonce
1443
+ zkConfigNonce,
1444
+ this.zkArtifactBaseUrl
1339
1445
  );
1340
1446
  this.sdk = await PrivacyPoolSDK2.init({
1341
1447
  wasmBinary: this.assets.sdkWasm,
@@ -6698,7 +6804,8 @@ async function privacyPoolInitOptions(assets, transactEnvironment) {
6698
6804
  const zkConfigNonce = resolveZkConfigNonce(transactEnvironment);
6699
6805
  const zkCircuits = await materializeSelectedZkCircuit(
6700
6806
  transactEnvironment.zkCircuits,
6701
- zkConfigNonce
6807
+ zkConfigNonce,
6808
+ transactEnvironment.zkArtifactBaseUrl
6702
6809
  );
6703
6810
  return {
6704
6811
  wasmBinary: assets.sdkWasm,