@unlink-xyz/core 0.1.5 → 0.1.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.
@@ -3707,63 +3707,85 @@ var Runtime = {
3707
3707
 
3708
3708
  // config.ts
3709
3709
  var CONFIG_URL = "https://config.unlink.xyz/networks.json";
3710
- function parseRequiredString(env2, field, value) {
3710
+ function parseRequiredString(chain2, field, value) {
3711
3711
  if (typeof value !== "string" || value.trim().length === 0) {
3712
3712
  throw new InitializationError(
3713
- `Invalid SDK config for ${env2}: ${field} must be a non-empty string`
3713
+ `Invalid SDK config for ${chain2}: ${field} must be a non-empty string`
3714
3714
  );
3715
3715
  }
3716
3716
  return value.trim();
3717
3717
  }
3718
- function parseOptionalString(env2, field, value) {
3718
+ function parseOptionalString(chain2, field, value) {
3719
3719
  if (value === void 0) return void 0;
3720
3720
  if (typeof value !== "string" || value.trim().length === 0) {
3721
3721
  throw new InitializationError(
3722
- `Invalid SDK config for ${env2}: ${field} must be a non-empty string when provided`
3722
+ `Invalid SDK config for ${chain2}: ${field} must be a non-empty string when provided`
3723
3723
  );
3724
3724
  }
3725
3725
  return value.trim();
3726
3726
  }
3727
- function parseEnvironmentConfig(env2, value) {
3727
+ function parseRequiredChainId(chain2, value) {
3728
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
3729
+ throw new InitializationError(
3730
+ `Invalid SDK config for ${chain2}: chainId must be a positive integer`
3731
+ );
3732
+ }
3733
+ return value;
3734
+ }
3735
+ function parseChainConfig(chain2, value) {
3728
3736
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
3729
3737
  throw new InitializationError(
3730
- `Invalid SDK config for ${env2}: expected object`
3738
+ `Invalid SDK config for ${chain2}: expected object`
3731
3739
  );
3732
3740
  }
3733
3741
  const raw = value;
3742
+ const chainId = parseRequiredChainId(chain2, raw.chainId);
3734
3743
  const gatewayUrl = parseRequiredString(
3735
- env2,
3744
+ chain2,
3736
3745
  "gatewayUrl",
3737
3746
  raw.gatewayUrl
3738
3747
  ).replace(/\/+$/, "");
3739
- const poolAddress = parseRequiredString(env2, "poolAddress", raw.poolAddress);
3748
+ const poolAddress = parseRequiredString(
3749
+ chain2,
3750
+ "poolAddress",
3751
+ raw.poolAddress
3752
+ );
3740
3753
  const artifactVersion = parseRequiredString(
3741
- env2,
3754
+ chain2,
3742
3755
  "artifactVersion",
3743
3756
  raw.artifactVersion
3744
3757
  ).replace(/^\/+|\/+$/g, "");
3758
+ const frostUrl = parseOptionalString(
3759
+ chain2,
3760
+ "frostUrl",
3761
+ raw.frostUrl
3762
+ )?.replace(/\/+$/, "");
3745
3763
  const artifactBaseUrl = parseOptionalString(
3746
- env2,
3764
+ chain2,
3747
3765
  "artifactBaseUrl",
3748
3766
  raw.artifactBaseUrl
3749
3767
  )?.replace(/\/+$/, "");
3750
3768
  return {
3769
+ chainId,
3751
3770
  gatewayUrl,
3771
+ ...frostUrl !== void 0 ? { frostUrl } : {},
3752
3772
  poolAddress,
3753
3773
  artifactVersion,
3754
3774
  ...artifactBaseUrl !== void 0 ? { artifactBaseUrl } : { artifactBaseUrl: DEFAULT_ARTIFACT_BASE_URL }
3755
3775
  };
3756
3776
  }
3757
- async function fetchEnvironmentConfig(env2) {
3777
+ async function fetchChainConfig(chain2) {
3758
3778
  const res = await fetch(CONFIG_URL);
3759
3779
  if (!res.ok) {
3760
3780
  throw new InitializationError(`Failed to fetch SDK config: ${res.status}`);
3761
3781
  }
3762
3782
  const config2 = await res.json();
3763
- if (!config2[env2]) {
3764
- throw new InitializationError(`Unknown environment: ${env2}`);
3783
+ if (!config2[chain2]) {
3784
+ throw new InitializationError(
3785
+ `Unknown chain: "${chain2}". Supported chains: ${Object.keys(config2).join(", ")}`
3786
+ );
3765
3787
  }
3766
- return parseEnvironmentConfig(env2, config2[env2]);
3788
+ return parseChainConfig(chain2, config2[chain2]);
3767
3789
  }
3768
3790
  function createServiceConfig(gatewayUrl) {
3769
3791
  const baseUrl = gatewayUrl.replace(/\/+$/, "");
@@ -4512,9 +4534,9 @@ var Hex = class _Hex {
4512
4534
 
4513
4535
  // keys/address.ts
4514
4536
  var VERSION = 1;
4515
- var LIMIT = 127;
4537
+ var LIMIT = 130;
4516
4538
  var ALL_CHAINS = "ffffffffffffffff";
4517
- var PREFIX = "0zk";
4539
+ var PREFIX = "unlink";
4518
4540
  var SALT = new TextEncoder().encode("unlink");
4519
4541
  function xorWithSalt(hex2) {
4520
4542
  const bytes2 = Hex.toBytes(hex2);
@@ -13376,29 +13398,41 @@ function createJsonHttpClient(baseUrl, deps) {
13376
13398
  fetch: fetchImpl,
13377
13399
  // Disable ky's automatic error throwing to prevent browser DevTools
13378
13400
  // from logging expected 404s as network errors
13379
- throwHttpErrors: false
13401
+ throwHttpErrors: false,
13402
+ retry: 0
13380
13403
  });
13404
+ const RETRYABLE_STATUSES = [502, 503, 504];
13405
+ const MAX_RETRIES = 3;
13406
+ const BASE_DELAY_MS = 500;
13381
13407
  return {
13382
13408
  async request(opts) {
13383
13409
  let res;
13384
- try {
13385
- res = await api(opts.path.replace(/^\//, ""), {
13386
- method: opts.method,
13387
- searchParams: opts.query,
13388
- json: opts.json,
13389
- body: opts.body,
13390
- headers: opts.headers,
13391
- signal: opts.signal
13392
- });
13393
- } catch (err) {
13394
- if (err instanceof TimeoutError) {
13395
- throw new HttpError("HTTP timeout", 408, null);
13410
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
13411
+ try {
13412
+ res = await api(opts.path.replace(/^\//, ""), {
13413
+ method: opts.method,
13414
+ searchParams: opts.query,
13415
+ json: opts.json,
13416
+ body: opts.body,
13417
+ headers: opts.headers,
13418
+ signal: opts.signal
13419
+ });
13420
+ } catch (err) {
13421
+ if (err instanceof TimeoutError) {
13422
+ throw new HttpError("HTTP timeout", 408, null);
13423
+ }
13424
+ throw new HttpError(
13425
+ err instanceof Error ? err.message : "Network error",
13426
+ 0,
13427
+ null
13428
+ );
13396
13429
  }
13397
- throw new HttpError(
13398
- err instanceof Error ? err.message : "Network error",
13399
- 0,
13400
- null
13401
- );
13430
+ if (RETRYABLE_STATUSES.includes(res.status) && attempt < MAX_RETRIES) {
13431
+ const delay2 = BASE_DELAY_MS * 2 ** attempt + Math.random() * 200;
13432
+ await new Promise((r2) => setTimeout(r2, delay2));
13433
+ continue;
13434
+ }
13435
+ break;
13402
13436
  }
13403
13437
  if (!res.ok) {
13404
13438
  const body = await readErrorBodySafe(res);
@@ -13624,7 +13658,7 @@ function parseZkAddress(value) {
13624
13658
  };
13625
13659
  } catch (err) {
13626
13660
  throw new ValidationError(
13627
- `Invalid ZK address (expected 0zk1... format): ${err instanceof Error ? err.message : "unknown error"}`
13661
+ `Invalid ZK address (expected unlink1... format): ${err instanceof Error ? err.message : "unknown error"}`
13628
13662
  );
13629
13663
  }
13630
13664
  }
@@ -52395,6 +52429,114 @@ var circuits_default = {
52395
52429
  template: "JoinSplit",
52396
52430
  pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52397
52431
  params: [5, 2, 16]
52432
+ },
52433
+ joinsplit_1x3_16: {
52434
+ file: "joinsplit",
52435
+ template: "JoinSplit",
52436
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52437
+ params: [1, 3, 16]
52438
+ },
52439
+ joinsplit_4x3_16: {
52440
+ file: "joinsplit",
52441
+ template: "JoinSplit",
52442
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52443
+ params: [4, 3, 16]
52444
+ },
52445
+ joinsplit_5x3_16: {
52446
+ file: "joinsplit",
52447
+ template: "JoinSplit",
52448
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52449
+ params: [5, 3, 16]
52450
+ },
52451
+ joinsplit_6x1_16: {
52452
+ file: "joinsplit",
52453
+ template: "JoinSplit",
52454
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52455
+ params: [6, 1, 16]
52456
+ },
52457
+ joinsplit_6x2_16: {
52458
+ file: "joinsplit",
52459
+ template: "JoinSplit",
52460
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52461
+ params: [6, 2, 16]
52462
+ },
52463
+ joinsplit_6x3_16: {
52464
+ file: "joinsplit",
52465
+ template: "JoinSplit",
52466
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52467
+ params: [6, 3, 16]
52468
+ },
52469
+ joinsplit_7x1_16: {
52470
+ file: "joinsplit",
52471
+ template: "JoinSplit",
52472
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52473
+ params: [7, 1, 16]
52474
+ },
52475
+ joinsplit_7x2_16: {
52476
+ file: "joinsplit",
52477
+ template: "JoinSplit",
52478
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52479
+ params: [7, 2, 16]
52480
+ },
52481
+ joinsplit_7x3_16: {
52482
+ file: "joinsplit",
52483
+ template: "JoinSplit",
52484
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52485
+ params: [7, 3, 16]
52486
+ },
52487
+ joinsplit_8x1_16: {
52488
+ file: "joinsplit",
52489
+ template: "JoinSplit",
52490
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52491
+ params: [8, 1, 16]
52492
+ },
52493
+ joinsplit_8x2_16: {
52494
+ file: "joinsplit",
52495
+ template: "JoinSplit",
52496
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52497
+ params: [8, 2, 16]
52498
+ },
52499
+ joinsplit_8x3_16: {
52500
+ file: "joinsplit",
52501
+ template: "JoinSplit",
52502
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52503
+ params: [8, 3, 16]
52504
+ },
52505
+ joinsplit_9x1_16: {
52506
+ file: "joinsplit",
52507
+ template: "JoinSplit",
52508
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52509
+ params: [9, 1, 16]
52510
+ },
52511
+ joinsplit_9x2_16: {
52512
+ file: "joinsplit",
52513
+ template: "JoinSplit",
52514
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52515
+ params: [9, 2, 16]
52516
+ },
52517
+ joinsplit_9x3_16: {
52518
+ file: "joinsplit",
52519
+ template: "JoinSplit",
52520
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52521
+ params: [9, 3, 16]
52522
+ },
52523
+ joinsplit_10x1_16: {
52524
+ file: "joinsplit",
52525
+ template: "JoinSplit",
52526
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52527
+ params: [10, 1, 16]
52528
+ },
52529
+ joinsplit_10x2_16: {
52530
+ file: "joinsplit",
52531
+ template: "JoinSplit",
52532
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52533
+ params: [10, 2, 16]
52534
+ },
52535
+ joinsplit_10x3_16: {
52536
+ file: "joinsplit",
52537
+ template: "JoinSplit",
52538
+ pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
52539
+ params: [10, 3, 16]
52398
52540
  }
52399
52541
  };
52400
52542
 
@@ -52414,7 +52556,7 @@ function getCircuitConfig(inputs, outputs) {
52414
52556
  }
52415
52557
 
52416
52558
  // prover/prover.ts
52417
- var MAX_ARTIFACT_CACHE_ENTRIES = 8;
52559
+ var MAX_ARTIFACT_CACHE_ENTRIES = 16;
52418
52560
  var artifactCache = /* @__PURE__ */ new Map();
52419
52561
  function selectCircuit(inputs, outputs) {
52420
52562
  const config2 = getCircuitConfig(inputs, outputs);
@@ -54481,6 +54623,16 @@ function createAdapterService(deps) {
54481
54623
  const reshieldSpecs = params.reshields.map(
54482
54624
  (reshield, i) => normalizeReshieldSpec(reshield, i)
54483
54625
  );
54626
+ const seenReshieldTokens = /* @__PURE__ */ new Set();
54627
+ for (const r2 of reshieldSpecs) {
54628
+ const lower = r2.token.toLowerCase();
54629
+ if (seenReshieldTokens.has(lower)) {
54630
+ throw new AdapterError(
54631
+ `duplicate reshield token ${r2.token}; each reshield must target a unique token`
54632
+ );
54633
+ }
54634
+ seenReshieldTokens.add(lower);
54635
+ }
54484
54636
  const account = overrides?.account ?? await deps.requireActiveAccount();
54485
54637
  const signer = overrides?.signer ?? deps.requireSigner(account);
54486
54638
  const nowSeconds = BigInt(Math.floor(nowImpl() / 1e3));
@@ -55366,28 +55518,31 @@ function createWalletSDK(deps, options) {
55366
55518
  return sdk;
55367
55519
  }
55368
55520
  async function createBrowserWalletSDK(options) {
55521
+ let chainId;
55369
55522
  let gatewayUrl;
55370
55523
  let poolAddress;
55371
55524
  let prover = options.prover;
55372
- if ("gatewayUrl" in options) {
55525
+ if ("chain" in options) {
55526
+ const chainConfig = await fetchChainConfig(options.chain);
55527
+ chainId = chainConfig.chainId;
55528
+ gatewayUrl = chainConfig.gatewayUrl;
55529
+ poolAddress = options.poolAddress ?? chainConfig.poolAddress;
55530
+ prover = {
55531
+ artifactSource: {
55532
+ baseUrl: options.prover?.artifactSource?.baseUrl ?? chainConfig.artifactBaseUrl,
55533
+ version: options.prover?.artifactSource?.version ?? chainConfig.artifactVersion,
55534
+ preferLocalFiles: options.prover?.artifactSource?.preferLocalFiles
55535
+ }
55536
+ };
55537
+ } else {
55538
+ chainId = options.chainId;
55373
55539
  gatewayUrl = options.gatewayUrl;
55374
55540
  poolAddress = options.poolAddress;
55375
55541
  if (typeof window !== "undefined" && !options.prover?.artifactSource?.version) {
55376
55542
  throw new InitializationError(
55377
- "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use environment mode or provide a pinned artifact version."
55543
+ "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use chain mode or provide a pinned artifact version."
55378
55544
  );
55379
55545
  }
55380
- } else {
55381
- const envConfig = await fetchEnvironmentConfig(options.environment);
55382
- gatewayUrl = envConfig.gatewayUrl;
55383
- poolAddress = options.poolAddress ?? envConfig.poolAddress;
55384
- prover = {
55385
- artifactSource: {
55386
- baseUrl: options.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,
55387
- version: options.prover?.artifactSource?.version ?? envConfig.artifactVersion,
55388
- preferLocalFiles: options.prover?.artifactSource?.preferLocalFiles
55389
- }
55390
- };
55391
55546
  }
55392
55547
  const storage = createIndexedDbStorage({ name: "unlink-wallet" });
55393
55548
  const rng = (n2) => {
@@ -55404,7 +55559,7 @@ async function createBrowserWalletSDK(options) {
55404
55559
  core,
55405
55560
  fetch: globalThis.fetch
55406
55561
  },
55407
- { chainId: options.chainId, gatewayUrl, prover }
55562
+ { chainId, gatewayUrl, prover }
55408
55563
  );
55409
55564
  return {
55410
55565
  sdk,
@@ -55434,34 +55589,37 @@ var UnlinkWallet = class _UnlinkWallet {
55434
55589
  * Create a new UnlinkWallet instance.
55435
55590
  *
55436
55591
  * Handles all initialization internally:
55437
- * - Resolves environment config (if using `environment` instead of explicit URLs)
55592
+ * - Resolves chain config (if using `chain` instead of explicit URLs)
55438
55593
  * - Auto-detects storage (IndexedDB in browser) and rng (crypto.getRandomValues)
55439
55594
  * - Runs schema migration via `initCore()`
55440
55595
  * - Creates the internal SDK
55441
55596
  */
55442
55597
  static async create(config2) {
55598
+ let chainId;
55443
55599
  let gatewayUrl;
55444
55600
  let poolAddress;
55445
55601
  let proverConfig = config2.prover;
55446
- if ("gatewayUrl" in config2) {
55602
+ if ("chain" in config2) {
55603
+ const chainConfig = await fetchChainConfig(config2.chain);
55604
+ chainId = chainConfig.chainId;
55605
+ gatewayUrl = chainConfig.gatewayUrl;
55606
+ poolAddress = config2.poolAddress ?? chainConfig.poolAddress;
55607
+ proverConfig = {
55608
+ artifactSource: {
55609
+ baseUrl: config2.prover?.artifactSource?.baseUrl ?? chainConfig.artifactBaseUrl,
55610
+ version: config2.prover?.artifactSource?.version ?? chainConfig.artifactVersion,
55611
+ preferLocalFiles: config2.prover?.artifactSource?.preferLocalFiles
55612
+ }
55613
+ };
55614
+ } else {
55615
+ chainId = config2.chainId;
55447
55616
  gatewayUrl = config2.gatewayUrl;
55448
55617
  poolAddress = config2.poolAddress;
55449
55618
  if (typeof window !== "undefined" && !config2.prover?.artifactSource?.version) {
55450
55619
  throw new InitializationError(
55451
- "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use environment mode or provide a pinned artifact version."
55620
+ "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use chain mode or provide a pinned artifact version."
55452
55621
  );
55453
55622
  }
55454
- } else {
55455
- const envConfig = await fetchEnvironmentConfig(config2.environment);
55456
- gatewayUrl = envConfig.gatewayUrl;
55457
- poolAddress = config2.poolAddress ?? envConfig.poolAddress;
55458
- proverConfig = {
55459
- artifactSource: {
55460
- baseUrl: config2.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,
55461
- version: config2.prover?.artifactSource?.version ?? envConfig.artifactVersion,
55462
- preferLocalFiles: config2.prover?.artifactSource?.preferLocalFiles
55463
- }
55464
- };
55465
55623
  }
55466
55624
  const storage = config2.storage ?? detectStorage();
55467
55625
  const rng = config2.rng ?? defaultRng;
@@ -55470,14 +55628,14 @@ var UnlinkWallet = class _UnlinkWallet {
55470
55628
  const sdk = createWalletSDK(
55471
55629
  { core, fetch: fetchImpl },
55472
55630
  {
55473
- chainId: config2.chainId,
55631
+ chainId,
55474
55632
  gatewayUrl,
55475
55633
  chainRpcUrl: config2.chainRpcUrl,
55476
55634
  prover: proverConfig,
55477
55635
  autoSync: config2.autoSync
55478
55636
  }
55479
55637
  );
55480
- return new _UnlinkWallet(sdk, config2.chainId, poolAddress);
55638
+ return new _UnlinkWallet(sdk, chainId, poolAddress);
55481
55639
  }
55482
55640
  // ===== Seed Lifecycle =====
55483
55641
  /** Seed management (create, import, export, delete mnemonic). */