@manifoldxyz/dropkit 0.3.0 → 0.4.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.
package/dist/index.cjs CHANGED
@@ -27,7 +27,7 @@
27
27
 
28
28
 
29
29
 
30
- var _chunkOO6QQT3Mcjs = require('./chunk-OO6QQT3M.cjs');
30
+ var _chunkGO4TR3HBcjs = require('./chunk-GO4TR3HB.cjs');
31
31
 
32
32
  // src/react/useMint.ts
33
33
  var _react = require('react');
@@ -70,7 +70,7 @@ function revertReason(errorData) {
70
70
  function parseQuote(body, originChainId) {
71
71
  const b = obj(body);
72
72
  const steps = Array.isArray(b.steps) ? b.steps.map(obj) : [];
73
- const unknownStep = () => new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", "Relay returned a route this button cannot execute.");
73
+ const unknownStep = () => new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", "Relay returned a route this button cannot execute.");
74
74
  if (steps.length !== 1 || steps[0].kind !== "transaction") throw unknownStep();
75
75
  const step = steps[0];
76
76
  const rawItems = Array.isArray(step.items) ? step.items.map(obj) : [];
@@ -83,8 +83,8 @@ function parseQuote(body, originChainId) {
83
83
  });
84
84
  const requestId = _viem.isHex.call(void 0, step.requestId) ? step.requestId : _viem.isHex.call(void 0, b.requestId) ? b.requestId : null;
85
85
  if (!requestId) throw unknownStep();
86
- const details = obj(b.details);
87
- const currencyIn = obj(details.currencyIn);
86
+ const details2 = obj(b.details);
87
+ const currencyIn = obj(details2.currencyIn);
88
88
  const fees = obj(b.fees);
89
89
  const amountIn = moneyOf(currencyIn.amount, currencyIn.currency);
90
90
  if (obj(currencyIn.currency).address !== void 0 && obj(currencyIn.currency).address !== _viem.zeroAddress) throw unknownStep();
@@ -163,21 +163,21 @@ async function requestQuote(a) {
163
163
  body: JSON.stringify(body)
164
164
  }, RELAY_TIMEOUTS.quoteMs);
165
165
  } catch (e) {
166
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", "Could not reach Relay for a cross-chain quote.", { cause: e });
166
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", "Could not reach Relay for a cross-chain quote.", { cause: e });
167
167
  }
168
168
  const json = res.json;
169
169
  if (res.ok) return parseQuote(json, a.originChainId);
170
170
  const j = obj(json);
171
171
  if (j.errorCode === "DESTINATION_TX_FAILED") {
172
172
  const reason = revertReason(j.errorData);
173
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", reason || "The mint would fail on the drop network.", { cause: json, domain: "relay" });
173
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", reason || "The mint would fail on the drop network.", { cause: json, domain: "relay" });
174
174
  }
175
175
  if (res.status === 401 || j.errorCode === "UNAUTHORIZED_QUOTE") {
176
176
  console.warn("dropkit: Relay rejected the quote (401 UNAUTHORIZED_QUOTE). Relay gates quotes that carry a referrer or need an API key.");
177
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", "Relay refused the cross-chain quote.", { cause: json });
177
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", "Relay refused the cross-chain quote.", { cause: json });
178
178
  }
179
- if (res.status === 429) throw new (0, _chunkOO6QQT3Mcjs.MintError)("RATE_LIMITED", "Relay is rate limiting quotes. Try again in a moment.", { cause: json });
180
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", `Relay could not quote this mint (${String(res.status)}).`, { cause: json });
179
+ if (res.status === 429) throw new (0, _chunkGO4TR3HBcjs.MintError)("RATE_LIMITED", "Relay is rate limiting quotes. Try again in a moment.", { cause: json });
180
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", `Relay could not quote this mint (${String(res.status)}).`, { cause: json });
181
181
  }
182
182
  function getQuote(a) {
183
183
  const k = cacheKey(a);
@@ -243,12 +243,605 @@ async function pollUntilTerminal(a) {
243
243
  }
244
244
  }
245
245
 
246
+ // src/core/adapters/tl-stacks/index.ts
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+ // src/core/adapters/tl-stacks/abis.ts
261
+ var DROP_PHASE = { NOT_CONFIGURED: 0, NOT_STARTED: 1, PRESALE: 2, PUBLIC_SALE: 3, ENDED: 4 };
262
+ var SUPPORTED_VERSIONS = ["2.3.0", "2.3.1"];
263
+ var stacksAbi = [
264
+ { type: "function", name: "VERSION", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] },
265
+ { type: "function", name: "protocolFee", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "uint256" }] },
266
+ {
267
+ type: "function",
268
+ name: "getDrop",
269
+ stateMutability: "view",
270
+ inputs: [{ name: "nftAddress", type: "address" }],
271
+ outputs: [
272
+ {
273
+ name: "",
274
+ type: "tuple",
275
+ components: [
276
+ { name: "dropType", type: "uint8" },
277
+ { name: "payoutReceiver", type: "address" },
278
+ { name: "initialSupply", type: "uint256" },
279
+ { name: "supply", type: "uint256" },
280
+ { name: "allowance", type: "uint256" },
281
+ { name: "currencyAddress", type: "address" },
282
+ { name: "startTime", type: "uint256" },
283
+ { name: "presaleDuration", type: "uint256" },
284
+ { name: "presaleCost", type: "uint256" },
285
+ { name: "presaleMerkleRoot", type: "bytes32" },
286
+ { name: "publicDuration", type: "uint256" },
287
+ { name: "publicCost", type: "uint256" },
288
+ { name: "decayRate", type: "int256" },
289
+ { name: "baseUri", type: "string" }
290
+ ]
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ type: "function",
296
+ name: "getDropPhase",
297
+ stateMutability: "view",
298
+ inputs: [{ name: "nftAddress", type: "address" }],
299
+ outputs: [{ name: "", type: "uint8" }]
300
+ },
301
+ {
302
+ type: "function",
303
+ name: "getNumberMinted",
304
+ stateMutability: "view",
305
+ inputs: [
306
+ { name: "nftAddress", type: "address" },
307
+ { name: "recipient", type: "address" }
308
+ ],
309
+ outputs: [{ name: "", type: "uint256" }]
310
+ },
311
+ {
312
+ type: "function",
313
+ name: "purchase",
314
+ stateMutability: "payable",
315
+ inputs: [
316
+ { name: "nftAddress", type: "address" },
317
+ { name: "recipient", type: "address" },
318
+ { name: "numberToMint", type: "uint256" },
319
+ { name: "presaleNumberCanMint", type: "uint256" },
320
+ { name: "proof", type: "bytes32[]" }
321
+ ],
322
+ outputs: [{ name: "refundAmount", type: "uint256" }]
323
+ },
324
+ { type: "error", name: "MintZeroTokens", inputs: [] },
325
+ { type: "error", name: "NotOnAllowlist", inputs: [] },
326
+ { type: "error", name: "YouShallNotMint", inputs: [] },
327
+ { type: "error", name: "AlreadyReachedMintAllowance", inputs: [] },
328
+ { type: "error", name: "InsufficientFunds", inputs: [] },
329
+ { type: "error", name: "SanctionedAddress", inputs: [] },
330
+ // OpenZeppelin v5 Pausable: purchase is whenNotPaused.
331
+ { type: "error", name: "EnforcedPause", inputs: [] }
332
+ ];
333
+
334
+ // src/core/adapters/tl-stacks/allowlist.ts
335
+
336
+ var HASH = /^0x[0-9a-fA-F]{64}$/;
337
+ var UINT = /^\d+$/;
338
+ var MAX_UINT256 = 2n ** 256n - 1n;
339
+ var unavailable = (message, cause) => new (0, _chunkGO4TR3HBcjs.MintError)("ALLOWLIST_UNAVAILABLE", message, cause === void 0 ? void 0 : { cause });
340
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
341
+ var hashWallet = (wallet) => _viem.keccak256.call(void 0, _viem.encodeAbiParameters.call(void 0, [{ type: "address" }], [_viem.getAddress.call(void 0, wallet)]));
342
+ var leafOf = (hashedWallet, allowance) => _viem.keccak256.call(void 0, _viem.concatHex.call(void 0, [_viem.keccak256.call(void 0, _viem.encodeAbiParameters.call(void 0, [{ type: "bytes32" }, { type: "uint256" }], [hashedWallet, allowance]))]));
343
+ var hashPair = (a, b) => BigInt(a) < BigInt(b) ? _viem.keccak256.call(void 0, _viem.concatHex.call(void 0, [a, b])) : _viem.keccak256.call(void 0, _viem.concatHex.call(void 0, [b, a]));
344
+ var processProof = (leaf, proof) => proof.reduce((node, sibling) => hashPair(node, sibling), leaf);
345
+ function parseAllowlist(body) {
346
+ if (!isRecord(body)) throw unavailable("The allowlist file is not a merkle tree dump.");
347
+ if (body.format !== "standard-v1") throw unavailable("The allowlist file is in an unsupported format.");
348
+ const enc = body.leafEncoding;
349
+ if (!Array.isArray(enc) || enc.length !== 2 || enc[0] !== "bytes32" || enc[1] !== "uint256") {
350
+ throw unavailable("The allowlist file uses an unsupported leaf encoding.");
351
+ }
352
+ const { tree, values } = body;
353
+ if (!Array.isArray(tree) || tree.length === 0 || !tree.every((n) => typeof n === "string" && HASH.test(n))) {
354
+ throw unavailable("The allowlist file has no readable merkle tree.");
355
+ }
356
+ if (!Array.isArray(values)) throw unavailable("The allowlist file has no wallet values.");
357
+ const entries = /* @__PURE__ */ new Map();
358
+ for (const row of values) {
359
+ const value = isRecord(row) ? row.value : void 0;
360
+ const treeIndex = isRecord(row) ? row.treeIndex : void 0;
361
+ if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "string" || !HASH.test(value[0])) {
362
+ throw unavailable("The allowlist file has an unreadable wallet entry.");
363
+ }
364
+ const raw = value[1];
365
+ const allowanceText = typeof raw === "string" ? raw : typeof raw === "number" && Number.isSafeInteger(raw) ? String(raw) : "";
366
+ if (!UINT.test(allowanceText) || BigInt(allowanceText) > MAX_UINT256) throw unavailable("The allowlist file has an unreadable allowance.");
367
+ if (typeof treeIndex !== "number") throw unavailable("The allowlist file has an unreadable tree index.");
368
+ const key = value[0].toLowerCase();
369
+ const allowance = BigInt(allowanceText);
370
+ const prev = entries.get(key);
371
+ if (!prev || allowance > prev.allowance) entries.set(key, { allowance, treeIndex });
372
+ }
373
+ return { root: tree[0].toLowerCase(), tree, entries };
374
+ }
375
+ var findEntry = (list, recipient) => _nullishCoalesce(list.entries.get(hashWallet(recipient).toLowerCase()), () => ( null));
376
+ function assertRoot(list, presaleMerkleRoot) {
377
+ if (list.root !== presaleMerkleRoot.toLowerCase()) {
378
+ throw unavailable("The allowlist file does not match this drop. The creator may have updated the allowlist; reload the page.");
379
+ }
380
+ }
381
+ var buildProof = (list, recipient, entry) => buildProofForHash(list, hashWallet(recipient), entry);
382
+ function buildProofForHash(list, hashedWallet, entry) {
383
+ const { tree } = list;
384
+ const { treeIndex } = entry;
385
+ if (!Number.isInteger(treeIndex) || treeIndex < 1 || treeIndex >= tree.length) {
386
+ throw unavailable("The allowlist file has a tree index outside the tree.");
387
+ }
388
+ const leaf = leafOf(hashedWallet, entry.allowance);
389
+ if (tree[treeIndex].toLowerCase() !== leaf.toLowerCase()) throw unavailable("The allowlist file entry does not match its merkle leaf.");
390
+ const proof = [];
391
+ let i = treeIndex;
392
+ while (i > 0) {
393
+ const sibling = i % 2 === 0 ? i - 1 : i + 1;
394
+ const node = tree[sibling];
395
+ if (node === void 0) throw unavailable("The allowlist file has a broken merkle tree.");
396
+ proof.push(node);
397
+ i = Math.floor((i - 1) / 2);
398
+ }
399
+ if (processProof(leaf, proof).toLowerCase() !== list.root) throw unavailable("The allowlist file does not produce a valid proof for this wallet.");
400
+ return proof;
401
+ }
402
+ var scopeCaches = /* @__PURE__ */ new WeakMap();
403
+ function withSignal(p, signal) {
404
+ if (!signal) return p;
405
+ return new Promise((resolve, reject) => {
406
+ const onAbort = () => reject(unavailable("The allowlist request was cancelled.", signal.reason));
407
+ p.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
408
+ if (signal.aborted) return onAbort();
409
+ signal.addEventListener("abort", onAbort, { once: true });
410
+ });
411
+ }
412
+ var ALLOWLIST_TIMEOUT_MS = 3e4;
413
+ var ALLOWLIST_MAX_BYTES = 10 * 1024 * 1024;
414
+ var tooLarge = () => unavailable(`The allowlist file is larger than ${ALLOWLIST_MAX_BYTES / (1024 * 1024)} MB.`);
415
+ async function readCapped(res) {
416
+ const declared = Number(res.headers.get("content-length"));
417
+ if (Number.isFinite(declared) && declared > ALLOWLIST_MAX_BYTES) throw tooLarge();
418
+ if (!res.body) return "";
419
+ const reader = res.body.getReader();
420
+ const chunks = [];
421
+ let total = 0;
422
+ for (; ; ) {
423
+ const { done, value } = await reader.read();
424
+ if (done) break;
425
+ total += value.byteLength;
426
+ if (total > ALLOWLIST_MAX_BYTES) {
427
+ void reader.cancel().catch(() => void 0);
428
+ throw tooLarge();
429
+ }
430
+ chunks.push(value);
431
+ }
432
+ const bytes = new Uint8Array(total);
433
+ let offset = 0;
434
+ for (const c of chunks) {
435
+ bytes.set(c, offset);
436
+ offset += c.byteLength;
437
+ }
438
+ return new TextDecoder().decode(bytes);
439
+ }
440
+ async function fetchAndParse(fetchFn, url, signal) {
441
+ let res;
442
+ try {
443
+ signal.throwIfAborted();
444
+ res = await fetchFn(url, { signal });
445
+ } catch (cause) {
446
+ throw unavailable("Could not reach the allowlist file.", cause);
447
+ }
448
+ if (res.status === 429) throw new (0, _chunkGO4TR3HBcjs.MintError)("RATE_LIMITED", "The allowlist host is rate limiting requests. Try again shortly.");
449
+ if (!res.ok) throw unavailable(`The allowlist file is not available (HTTP ${res.status}).`);
450
+ let body;
451
+ try {
452
+ const text = await readCapped(res);
453
+ body = JSON.parse(text);
454
+ } catch (cause) {
455
+ if (cause instanceof _chunkGO4TR3HBcjs.MintError) throw cause;
456
+ throw unavailable("The allowlist file could not be read.", cause);
457
+ }
458
+ return parseAllowlist(body);
459
+ }
460
+ async function download(fetchFn, url, signal) {
461
+ const controller = new AbortController();
462
+ let onAbort;
463
+ const stopped = new Promise((_, reject) => {
464
+ onAbort = () => {
465
+ const reason = controller.signal.reason;
466
+ reject(reason instanceof _chunkGO4TR3HBcjs.MintError ? reason : unavailable("The allowlist request was cancelled.", reason));
467
+ };
468
+ controller.signal.addEventListener("abort", onAbort, { once: true });
469
+ });
470
+ const onLifetimeAbort = () => controller.abort(_optionalChain([signal, 'optionalAccess', _12 => _12.reason]));
471
+ if (_optionalChain([signal, 'optionalAccess', _13 => _13.aborted])) onLifetimeAbort();
472
+ else _optionalChain([signal, 'optionalAccess', _14 => _14.addEventListener, 'call', _15 => _15("abort", onLifetimeAbort, { once: true })]);
473
+ const timer = setTimeout(
474
+ () => controller.abort(unavailable(`The allowlist file did not load within ${ALLOWLIST_TIMEOUT_MS / 1e3} seconds. Try again.`)),
475
+ ALLOWLIST_TIMEOUT_MS
476
+ );
477
+ try {
478
+ return await Promise.race([fetchAndParse(fetchFn, url, controller.signal), stopped]);
479
+ } finally {
480
+ clearTimeout(timer);
481
+ if (onAbort) controller.signal.removeEventListener("abort", onAbort);
482
+ _optionalChain([signal, 'optionalAccess', _16 => _16.removeEventListener, 'call', _17 => _17("abort", onLifetimeAbort)]);
483
+ }
484
+ }
485
+ function loadAllowlist(args) {
486
+ if (!args.url) {
487
+ return Promise.reject(unavailable("This presale has no allowlist file configured (allowlistUrl). Ask the creator to add it."));
488
+ }
489
+ if (_optionalChain([args, 'access', _18 => _18.signal, 'optionalAccess', _19 => _19.aborted])) return Promise.reject(unavailable("The allowlist request was cancelled.", args.signal.reason));
490
+ const fetchFn = _nullishCoalesce(args.fetch, () => ( ((input, init) => globalThis.fetch(input, init))));
491
+ let scoped = scopeCaches.get(args.scope);
492
+ if (!scoped || _optionalChain([scoped, 'access', _20 => _20.signal, 'optionalAccess', _21 => _21.aborted])) {
493
+ scoped = { signal: args.signal, loads: /* @__PURE__ */ new Map() };
494
+ scopeCaches.set(args.scope, scoped);
495
+ }
496
+ const cache2 = scoped;
497
+ const hit = cache2.loads.get(args.url);
498
+ if (hit) return hit;
499
+ const url = args.url;
500
+ const p = withSignal(download(fetchFn, url, cache2.signal), cache2.signal);
501
+ cache2.loads.set(url, p);
502
+ p.catch(() => {
503
+ if (cache2.loads.get(url) === p) cache2.loads.delete(url);
504
+ });
505
+ return p;
506
+ }
507
+
508
+ // src/core/adapters/tl-stacks/index.ts
509
+ var FALLBACK_GAS_BASE = 150000n;
510
+ var FALLBACK_GAS_PER_TOKEN = 150000n;
511
+ var details = /* @__PURE__ */ new WeakMap();
512
+ function bad(field, message) {
513
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} ${message}`, { field });
514
+ }
515
+ function validateTlStacksConfig(config) {
516
+ if (!Number.isInteger(config.chainId) || config.chainId <= 0) bad("chainId", "must be a positive integer");
517
+ if (typeof config.stacks !== "string" || !_viem.isAddress.call(void 0, config.stacks, { strict: false })) bad("stacks", "is not a valid address");
518
+ if (typeof config.nftContract !== "string" || !_viem.isAddress.call(void 0, config.nftContract, { strict: false })) bad("nftContract", "is not a valid address");
519
+ if (config.allowlistUrl !== void 0) {
520
+ const https = (() => {
521
+ try {
522
+ return typeof config.allowlistUrl === "string" && new URL(config.allowlistUrl).protocol === "https:";
523
+ } catch (e2) {
524
+ return false;
525
+ }
526
+ })();
527
+ if (!https) bad("allowlistUrl", "must be an https: URL");
528
+ }
529
+ }
530
+ var abortError = () => new DOMException("The operation was aborted", "AbortError");
531
+ var isAbortError = (e) => _optionalChain([e, 'optionalAccess', _22 => _22.name]) === "AbortError";
532
+ function throwIfAborted(ctx) {
533
+ if (_optionalChain([ctx, 'access', _23 => _23.signal, 'optionalAccess', _24 => _24.aborted])) throw abortError();
534
+ }
535
+ function io(ctx, start) {
536
+ const signal = ctx.signal;
537
+ if (!signal) return start();
538
+ if (signal.aborted) return Promise.reject(abortError());
539
+ return new Promise((resolve, reject) => {
540
+ const onAbort = () => reject(abortError());
541
+ signal.addEventListener("abort", onAbort, { once: true });
542
+ start().then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
543
+ });
544
+ }
545
+ var shortMessage = (e) => e instanceof _viem.BaseError ? e.shortMessage : e instanceof Error ? e.message : String(e);
546
+ function rpcError(e) {
547
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e) || isAbortError(e)) throw e;
548
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage(e)}`, { cause: e });
549
+ }
550
+ async function readStacks(ctx, config, functionName, args = []) {
551
+ try {
552
+ return await io(
553
+ ctx,
554
+ () => ctx.client.readContract({ address: _viem.getAddress.call(void 0, config.stacks), abi: stacksAbi, functionName, args })
555
+ );
556
+ } catch (e) {
557
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e) || isAbortError(e)) throw e;
558
+ if (e instanceof _viem.BaseError && e.walk((x) => x instanceof _viem.ContractFunctionRevertedError || x instanceof _viem.ContractFunctionZeroDataError)) {
559
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `stacks ${functionName}() reverted or returned no data. Is ${config.stacks} a TL Stacks 721 contract on chain ${config.chainId}?`, {
560
+ field: "stacks",
561
+ cause: e
562
+ });
563
+ }
564
+ return rpcError(e);
565
+ }
566
+ }
567
+ var versions = /* @__PURE__ */ new WeakMap();
568
+ async function checkVersion(ctx, config) {
569
+ const load = () => readStacks(ctx, config, "VERSION");
570
+ let version;
571
+ if (ctx.cacheScope) {
572
+ let byStacks = versions.get(ctx.cacheScope);
573
+ if (!byStacks) versions.set(ctx.cacheScope, byStacks = /* @__PURE__ */ new Map());
574
+ const key = `${config.chainId}:${config.stacks.toLowerCase()}`;
575
+ const cache2 = byStacks;
576
+ let hit = cache2.get(key);
577
+ if (!hit) {
578
+ const p = load();
579
+ cache2.set(key, hit = p);
580
+ p.catch(() => {
581
+ if (cache2.get(key) === p) cache2.delete(key);
582
+ });
583
+ }
584
+ version = hit;
585
+ } else {
586
+ version = load();
587
+ }
588
+ const v = await version;
589
+ if (!SUPPORTED_VERSIONS.includes(v)) {
590
+ bad("stacks", `is TL Stacks ${v}. Dropkit supports ${SUPPORTED_VERSIONS.join(" and ")} only.`);
591
+ }
592
+ }
593
+ var money = (value, decimals, symbol) => ({ value, decimals, symbol, formatted: _viem.formatUnits.call(void 0, value, decimals) });
594
+ function nativeMeta(ctx) {
595
+ const n = _optionalChain([ctx, 'access', _25 => _25.client, 'access', _26 => _26.chain, 'optionalAccess', _27 => _27.nativeCurrency]);
596
+ return { decimals: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _28 => _28.decimals]), () => ( 18)), symbol: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _29 => _29.symbol]), () => ( "ETH")) };
597
+ }
598
+ function seconds(v, field) {
599
+ if (v > BigInt(Number.MAX_SAFE_INTEGER)) throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} is too large for a unix timestamp`, { field });
600
+ return Number(v);
601
+ }
602
+ async function readDrop(ctx, config) {
603
+ validateTlStacksConfig(config);
604
+ throwIfAborted(ctx);
605
+ await checkVersion(ctx, config);
606
+ const nft = _viem.getAddress.call(void 0, config.nftContract);
607
+ const [drop, phaseRaw, fee] = await Promise.all([
608
+ readStacks(ctx, config, "getDrop", [nft]),
609
+ readStacks(ctx, config, "getDropPhase", [nft]),
610
+ readStacks(ctx, config, "protocolFee")
611
+ ]);
612
+ const phase = Number(phaseRaw);
613
+ if (phase === DROP_PHASE.NOT_CONFIGURED) {
614
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("DROP_NOT_FOUND", "No Transient Labs drop is configured for this NFT contract on this chain.");
615
+ }
616
+ if (drop.currencyAddress !== _viem.zeroAddress) {
617
+ bad("nftContract", `is sold for an ERC-20 (${drop.currencyAddress}). Dropkit supports drops priced in the native token only.`);
618
+ }
619
+ const hasPresale = drop.presaleDuration > 0n;
620
+ const presalePrice = phase === DROP_PHASE.PRESALE || phase === DROP_PHASE.NOT_STARTED && hasPresale;
621
+ const unitPrice = presalePrice ? drop.presaleCost : drop.publicCost;
622
+ const startTime = seconds(drop.startTime, "startTime");
623
+ const presaleEnd = seconds(drop.startTime + drop.presaleDuration, "presaleDuration");
624
+ const soldOut = drop.supply === 0n;
625
+ const neverMintable = drop.initialSupply === 0n;
626
+ const native = nativeMeta(ctx);
627
+ const info = {
628
+ chainId: config.chainId,
629
+ unitPrice: money(unitPrice, native.decimals, native.symbol),
630
+ unitFee: money(fee, native.decimals, native.symbol),
631
+ totalMinted: drop.initialSupply - drop.supply,
632
+ maxSupply: drop.initialSupply,
633
+ // A never-mintable drop has no start either, so the hook clock has no boundary ahead to tick towards (review F13).
634
+ startTime: neverMintable || startTime === 0 ? null : startTime,
635
+ // At supply 0 the drop is sold out for good: no end time, so it never turns into `ended` (D14).
636
+ endTime: neverMintable ? 0 : soldOut ? null : seconds(drop.startTime + drop.presaleDuration + drop.publicDuration, "publicDuration"),
637
+ isAllowlist: phase === DROP_PHASE.PRESALE,
638
+ paymentToken: null,
639
+ pricePer: "unit",
640
+ phaseEndsAt: presalePrice ? presaleEnd : null,
641
+ walletKey: `${phase}:${drop.presaleMerkleRoot}:${unitPrice}:${fee}`
642
+ };
643
+ details.set(info, {
644
+ phase,
645
+ presaleMerkleRoot: drop.presaleMerkleRoot,
646
+ allowance: drop.allowance,
647
+ presaleDuration: drop.presaleDuration,
648
+ publicDuration: drop.publicDuration,
649
+ startTime: drop.startTime
650
+ });
651
+ return info;
652
+ }
653
+ async function detailOf(ctx, config, drop) {
654
+ const hit = details.get(drop);
655
+ if (hit) return hit;
656
+ const nft = _viem.getAddress.call(void 0, config.nftContract);
657
+ const [raw, phase] = await Promise.all([
658
+ readStacks(ctx, config, "getDrop", [nft]),
659
+ readStacks(ctx, config, "getDropPhase", [nft])
660
+ ]);
661
+ return {
662
+ phase: Number(phase),
663
+ presaleMerkleRoot: raw.presaleMerkleRoot,
664
+ allowance: raw.allowance,
665
+ presaleDuration: raw.presaleDuration,
666
+ publicDuration: raw.publicDuration,
667
+ startTime: raw.startTime
668
+ };
669
+ }
670
+ var dayTime = (unix) => new Date(unix * 1e3).toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
671
+ function notOnAllowlist(d) {
672
+ const opens = Number(d.startTime + d.presaleDuration);
673
+ const message = d.publicDuration > 0n ? `This wallet is not on the allowlist. The public sale opens ${dayTime(opens)}.` : "This wallet is not on the allowlist. This drop is allowlist only.";
674
+ return { reason: "NOT_ON_ALLOWLIST", message };
675
+ }
676
+ async function readWallet(ctx, config, { payer, recipient, quantity, drop }) {
677
+ validateTlStacksConfig(config);
678
+ throwIfAborted(ctx);
679
+ const detail = await detailOf(ctx, config, drop);
680
+ const nft = _viem.getAddress.call(void 0, config.nftContract);
681
+ const presale = detail.phase === DROP_PHASE.PRESALE;
682
+ const [minted, native, gasPrice, list] = await Promise.all([
683
+ readStacks(ctx, config, "getNumberMinted", [nft, _viem.getAddress.call(void 0, recipient)]),
684
+ io(ctx, () => ctx.client.getBalance({ address: payer })).catch(rpcError),
685
+ io(ctx, () => ctx.client.getGasPrice()).catch(rpcError),
686
+ presale ? loadAllowlist({ scope: _nullishCoalesce(ctx.cacheScope, () => ( drop)), url: config.allowlistUrl, fetch: ctx.fetch, signal: ctx.signal }) : Promise.resolve(null)
687
+ ]);
688
+ let walletMax = detail.allowance;
689
+ let proof = [];
690
+ let presaleNumberCanMint = 0n;
691
+ let ineligible = null;
692
+ let allowlistRemaining = null;
693
+ if (presale && list) {
694
+ assertRoot(list, detail.presaleMerkleRoot);
695
+ const entry = findEntry(list, recipient);
696
+ if (!entry) {
697
+ walletMax = 0n;
698
+ ineligible = notOnAllowlist(detail);
699
+ } else {
700
+ walletMax = entry.allowance;
701
+ presaleNumberCanMint = entry.allowance;
702
+ proof = buildProof(list, recipient, entry);
703
+ }
704
+ }
705
+ const remaining = walletMax > minted ? walletMax - minted : 0n;
706
+ if (presale && ineligible === null) {
707
+ allowlistRemaining = Number(remaining < BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY) ? remaining : BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY));
708
+ if (remaining === 0n) ineligible = { reason: "ALLOWLIST_USED", message: `This wallet has already minted its allowlist allocation of ${walletMax}.` };
709
+ } else if (!presale && remaining === 0n) {
710
+ ineligible = { reason: "WALLET_LIMIT", message: `This wallet has already minted its limit of ${walletMax}.` };
711
+ }
712
+ const maxQuantity = Number(remaining < BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY) ? remaining : BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY));
713
+ const data = { presaleNumberCanMint, proof, unitPrice: drop.unitPrice.value, unitFee: drop.unitFee.value };
714
+ const qty = BigInt(quantity);
715
+ const value = qty * (data.unitPrice + data.unitFee);
716
+ let gas = FALLBACK_GAS_BASE + FALLBACK_GAS_PER_TOKEN * qty;
717
+ const open = detail.phase === DROP_PHASE.PRESALE || detail.phase === DROP_PHASE.PUBLIC_SALE;
718
+ if (open && ineligible === null && native >= value) {
719
+ try {
720
+ const estimated = await io(
721
+ ctx,
722
+ () => ctx.client.estimateGas({ account: payer, to: _viem.getAddress.call(void 0, config.stacks), data: encodePurchase(config, recipient, qty, data), value })
723
+ );
724
+ gas = estimated;
725
+ } catch (e) {
726
+ if (isAbortError(e)) throw e;
727
+ }
728
+ }
729
+ return {
730
+ walletMinted: minted,
731
+ walletMax,
732
+ allowlistRemaining,
733
+ maxQuantity,
734
+ ineligible,
735
+ balances: { native, erc20: null },
736
+ gasReserve: gas * gasPrice,
737
+ data
738
+ };
739
+ }
740
+ function encodePurchase(config, recipient, quantity, data) {
741
+ return _viem.encodeFunctionData.call(void 0, {
742
+ abi: stacksAbi,
743
+ functionName: "purchase",
744
+ args: [_viem.getAddress.call(void 0, config.nftContract), _viem.getAddress.call(void 0, recipient), quantity, data.presaleNumberCanMint, [...data.proof]]
745
+ });
746
+ }
747
+ function walletData(wallet) {
748
+ const d = wallet.data;
749
+ if (!d || typeof d.presaleNumberCanMint !== "bigint" || typeof d.unitPrice !== "bigint" || typeof d.unitFee !== "bigint" || !Array.isArray(d.proof)) {
750
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("RPC_ERROR", "The wallet read is missing the data this mint needs. Reload and try again.");
751
+ }
752
+ return d;
753
+ }
754
+ async function buildPlan(ctx, attempt, wallet) {
755
+ const { config, recipient } = attempt;
756
+ validateTlStacksConfig(config);
757
+ throwIfAborted(ctx);
758
+ if (!Number.isInteger(attempt.quantity) || attempt.quantity < 1) {
759
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", "Choose at least one token to mint.");
760
+ }
761
+ const data = walletData(wallet);
762
+ const qty = BigInt(attempt.quantity);
763
+ return {
764
+ approve: null,
765
+ mint: {
766
+ to: _viem.getAddress.call(void 0, config.stacks),
767
+ data: encodePurchase(config, recipient, qty, data),
768
+ value: qty * (data.unitPrice + data.unitFee)
769
+ },
770
+ tokenContract: _viem.getAddress.call(void 0, config.nftContract)
771
+ };
772
+ }
773
+ var TL_MESSAGES = {
774
+ NotOnAllowlist: "This wallet is not on the allowlist for the current sale.",
775
+ YouShallNotMint: "This drop is not open for minting right now.",
776
+ AlreadyReachedMintAllowance: "This wallet has already minted its limit.",
777
+ InsufficientFunds: "The price or fee changed since the page loaded, so the payment is too low. Reload the page and try again.",
778
+ MintZeroTokens: "Choose at least one token to mint.",
779
+ SanctionedAddress: "This wallet or the recipient is blocked by a sanctions check, so it cannot mint.",
780
+ EnforcedPause: "Minting is paused by Transient Labs right now. Try again later."
781
+ };
782
+ function revertData(e) {
783
+ for (let cur = e, depth = 0; cur && depth < 12; depth++) {
784
+ const d = cur.data;
785
+ if (typeof d === "string" && d.startsWith("0x") && d.length >= 10) return d;
786
+ if (d && typeof d === "object" && typeof d.data === "string") {
787
+ const inner = d.data;
788
+ if (inner.startsWith("0x") && inner.length >= 10) return inner;
789
+ }
790
+ cur = cur.cause;
791
+ }
792
+ return null;
793
+ }
794
+ function decodeTlRevert(e) {
795
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e)) return e;
796
+ if (isAbortError(e)) throw e;
797
+ if (e instanceof _viem.BaseError && e.walk((x) => x instanceof _viem.InsufficientFundsError)) {
798
+ return new (0, _chunkGO4TR3HBcjs.MintError)("INSUFFICIENT_FUNDS", `The wallet cannot cover the mint: ${e.shortMessage}`, { cause: e });
799
+ }
800
+ const data = revertData(e);
801
+ if (data) {
802
+ try {
803
+ const { errorName, args } = _viem.decodeErrorResult.call(void 0, { abi: stacksAbi, data });
804
+ const known = TL_MESSAGES[errorName];
805
+ if (known) return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", known, { cause: e, domain: "tl-stacks" });
806
+ const shown = (_nullishCoalesce(args, () => ( []))).map(String).join(", ");
807
+ return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", `Transient Labs rejected the mint (${errorName}(${shown})).`, { cause: e, domain: "tl-stacks" });
808
+ } catch (e3) {
809
+ return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", `Transient Labs rejected the mint (unrecognized error ${data.slice(0, 10)}).`, { cause: e, domain: "tl-stacks" });
810
+ }
811
+ }
812
+ const reverted = e instanceof _viem.BaseError && e.walk((x) => x.code === 3 || /execution reverted/i.test(x.message));
813
+ if (reverted) return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", shortMessage(e), { cause: e });
814
+ return new (0, _chunkGO4TR3HBcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage(e)}`, { cause: e });
815
+ }
816
+ async function simulate(ctx, attempt, plan) {
817
+ throwIfAborted(ctx);
818
+ try {
819
+ await io(ctx, () => ctx.client.call({ account: attempt.payer, to: plan.mint.to, data: plan.mint.data, value: plan.mint.value }));
820
+ } catch (e) {
821
+ throw decodeTlRevert(e);
822
+ }
823
+ }
824
+ var tlStacksAdapter = { readDrop, readWallet, buildPlan, simulate };
825
+
246
826
  // src/core/relay/outstanding.ts
247
827
  var memory = /* @__PURE__ */ new Map();
248
828
  var claimed = /* @__PURE__ */ new Set();
829
+ function targetOf(config) {
830
+ switch (config.type) {
831
+ case "manifold-claim":
832
+ return `${config.creatorContract.toLowerCase()}:${config.instanceId}`;
833
+ case "contract":
834
+ return config.address.toLowerCase();
835
+ case "tl-stacks":
836
+ return `stacks:${config.nftContract.toLowerCase()}`;
837
+ default: {
838
+ const unreachable = config;
839
+ return unreachable;
840
+ }
841
+ }
842
+ }
249
843
  function outstandingKey(config, payer) {
250
- const target = config.type === "manifold-claim" ? `${config.creatorContract.toLowerCase()}:${config.instanceId}` : config.address.toLowerCase();
251
- return `${String(config.chainId)}:${target}:${payer.toLowerCase()}`;
844
+ return `${String(config.chainId)}:${targetOf(config)}:${payer.toLowerCase()}`;
252
845
  }
253
846
  var getOutstanding = (key) => _nullishCoalesce(memory.get(key), () => ( null));
254
847
  var setOutstanding = (key, out) => void memory.set(key, out);
@@ -287,8 +880,8 @@ var APPROVE_GAS = 65000n;
287
880
  var PLACEHOLDER_TOKEN = /\{[A-Za-z_]\w*\}/g;
288
881
  var DISPLAY_AMOUNT = /^\d+(\.\d+)?$/;
289
882
  var NUMERIC_TYPE = /^u?int\d*$/;
290
- function bad(field, message) {
291
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} ${message}`, { field });
883
+ function bad2(field, message) {
884
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} ${message}`, { field });
292
885
  }
293
886
  var isHexAddress = (a) => typeof a === "string" && _viem.isAddress.call(void 0, a, { strict: false });
294
887
  function functionsNamed(abi, name) {
@@ -297,15 +890,15 @@ function functionsNamed(abi, name) {
297
890
  function validateTemplate(t, path, allowed) {
298
891
  if (typeof t === "string") {
299
892
  for (const token of _nullishCoalesce(t.match(PLACEHOLDER_TOKEN), () => ( []))) {
300
- if (!PLACEHOLDERS.includes(token)) bad(path, `"${t}" is not a known placeholder (${token})`);
301
- if (!allowed.includes(token)) bad(path, `"${t}" uses ${token}, which is not available in this field`);
893
+ if (!PLACEHOLDERS.includes(token)) bad2(path, `"${t}" is not a known placeholder (${token})`);
894
+ if (!allowed.includes(token)) bad2(path, `"${t}" uses ${token}, which is not available in this field`);
302
895
  }
303
896
  } else if (Array.isArray(t)) {
304
897
  t.forEach((x, i) => validateTemplate(x, `${path}[${i}]`, allowed));
305
898
  } else if (typeof t === "number") {
306
- if (!Number.isSafeInteger(t)) bad(path, `${t} is not a safe integer; pass larger or fractional values as a bigint or decimal string`);
899
+ if (!Number.isSafeInteger(t)) bad2(path, `${t} is not a safe integer; pass larger or fractional values as a bigint or decimal string`);
307
900
  } else if (typeof t !== "bigint" && typeof t !== "boolean") {
308
- bad(path, "must be a string, number, bigint, boolean or array");
901
+ bad2(path, "must be a string, number, bigint, boolean or array");
309
902
  }
310
903
  }
311
904
  var ARRAY_TYPE = /^(.*)\[(\d*)\]$/;
@@ -373,15 +966,15 @@ var NO_PLACEHOLDERS = [];
373
966
  function validateCall(abi, call, prefix, kind, allowed) {
374
967
  const c = _nullishCoalesce(call, () => ( {}));
375
968
  const named = typeof c.functionName === "string" ? functionsNamed(abi, c.functionName) : [];
376
- if (named.length === 0) bad(`${prefix}.functionName`, `"${String(c.functionName)}" is not a function in the abi`);
377
- if (c.args !== void 0 && !Array.isArray(c.args)) bad(`${prefix}.args`, "must be an array");
378
- if (kind === "mint" && c.args === void 0) bad(`${prefix}.args`, "is required");
969
+ if (named.length === 0) bad2(`${prefix}.functionName`, `"${String(c.functionName)}" is not a function in the abi`);
970
+ if (c.args !== void 0 && !Array.isArray(c.args)) bad2(`${prefix}.args`, "must be an array");
971
+ if (kind === "mint" && c.args === void 0) bad2(`${prefix}.args`, "is required");
379
972
  const args = _nullishCoalesce(c.args, () => ( []));
380
973
  args.forEach((a, i) => validateTemplate(a, `${prefix}.args[${i}]`, allowed));
381
974
  const sameArity = named.filter((f) => f.inputs.length === args.length);
382
975
  if (sameArity.length === 0) {
383
976
  const want = [...new Set(named.map((f) => f.inputs.length))].join(" or ");
384
- bad(`${prefix}.args`, `has ${args.length} argument(s) but "${String(c.functionName)}" takes ${want}`);
977
+ bad2(`${prefix}.args`, `has ${args.length} argument(s) but "${String(c.functionName)}" takes ${want}`);
385
978
  }
386
979
  const checked = sameArity.map((f) => {
387
980
  let issue = null;
@@ -391,75 +984,75 @@ function validateCall(abi, call, prefix, kind, allowed) {
391
984
  const fits = checked.filter((x) => !x.issue);
392
985
  if (fits.length === 0) {
393
986
  const first = checked[0].issue;
394
- if (sameArity.length === 1) bad(first.path, first.message);
395
- bad(`${prefix}.args`, `fit none of the overloads ${sameArity.map(signature).join(", ")}: ${first.path} ${first.message}`);
987
+ if (sameArity.length === 1) bad2(first.path, first.message);
988
+ bad2(`${prefix}.args`, `fit none of the overloads ${sameArity.map(signature).join(", ")}: ${first.path} ${first.message}`);
396
989
  }
397
990
  const roleFits = fits.filter(
398
991
  ({ f }) => kind === "read" ? f.stateMutability === "view" || f.stateMutability === "pure" : f.stateMutability === "payable" || f.stateMutability === "nonpayable"
399
992
  );
400
993
  if (roleFits.length === 0) {
401
994
  const name = fits[0].f.name;
402
- if (kind === "read") bad(`${prefix}.functionName`, `"${name}" is not a view or pure function`);
995
+ if (kind === "read") bad2(`${prefix}.functionName`, `"${name}" is not a view or pure function`);
403
996
  if (fits.some(({ f }) => f.stateMutability !== "view" && f.stateMutability !== "pure")) {
404
- bad(`${prefix}.functionName`, `"${name}" has missing or invalid stateMutability; mint requires payable or nonpayable`);
997
+ bad2(`${prefix}.functionName`, `"${name}" has missing or invalid stateMutability; mint requires payable or nonpayable`);
405
998
  }
406
- bad(`${prefix}.functionName`, `"${name}" is a view or pure function and cannot mint`);
999
+ bad2(`${prefix}.functionName`, `"${name}" is a view or pure function and cannot mint`);
407
1000
  }
408
1001
  if (roleFits.length > 1) {
409
- bad(`${prefix}.functionName`, `"${String(c.functionName)}" is ambiguous: ${roleFits.map((x) => signature(x.f)).join(" and ")} both accept these arguments`);
1002
+ bad2(`${prefix}.functionName`, `"${String(c.functionName)}" is ambiguous: ${roleFits.map((x) => signature(x.f)).join(" and ")} both accept these arguments`);
410
1003
  }
411
1004
  return roleFits[0].f;
412
1005
  }
413
1006
  function resolveOutput(fn, output, path) {
414
1007
  const outs = fn.outputs;
415
- if (outs.length === 0) bad(`${path}.functionName`, `"${fn.name}" returns nothing`);
1008
+ if (outs.length === 0) bad2(`${path}.functionName`, `"${fn.name}" returns nothing`);
416
1009
  const first = outs[0];
417
1010
  const tuple = outs.length === 1 && first.type === "tuple";
418
1011
  const members = tuple ? _nullishCoalesce(first.components, () => ( [])) : outs;
419
1012
  const memberNames = members.map((m, i) => m.name || String(i)).join(", ");
420
1013
  let index;
421
1014
  if (output === void 0) {
422
- if (members.length !== 1) bad(`${path}.output`, `is required: "${fn.name}" returns several values (${memberNames})`);
1015
+ if (members.length !== 1) bad2(`${path}.output`, `is required: "${fn.name}" returns several values (${memberNames})`);
423
1016
  index = 0;
424
1017
  } else if (typeof output === "number") {
425
1018
  if (!Number.isInteger(output) || output < 0 || output >= members.length) {
426
- bad(`${path}.output`, `${output} is not in the abi outputs of "${fn.name}" (${memberNames})`);
1019
+ bad2(`${path}.output`, `${output} is not in the abi outputs of "${fn.name}" (${memberNames})`);
427
1020
  }
428
1021
  index = output;
429
1022
  } else if (typeof output === "string") {
430
1023
  index = members.findIndex((m) => m.name === output);
431
- if (index < 0) bad(`${path}.output`, `"${output}" is not in the abi outputs of "${fn.name}" (${memberNames})`);
1024
+ if (index < 0) bad2(`${path}.output`, `"${output}" is not in the abi outputs of "${fn.name}" (${memberNames})`);
432
1025
  } else {
433
- return bad(`${path}.output`, "must be an index or a name");
1026
+ return bad2(`${path}.output`, "must be an index or a name");
434
1027
  }
435
1028
  const type = members[index].type;
436
1029
  if (!NUMERIC_TYPE.test(type)) {
437
1030
  const reason = `returns ${type}, not a number`;
438
- if (output === void 0) bad(`${path}.functionName`, `"${fn.name}" ${reason}`);
439
- bad(`${path}.output`, `selects a value that is ${type}, not a number`);
1031
+ if (output === void 0) bad2(`${path}.functionName`, `"${fn.name}" ${reason}`);
1032
+ bad2(`${path}.output`, `selects a value that is ${type}, not a number`);
440
1033
  }
441
1034
  return { tuple, index, type };
442
1035
  }
443
1036
  function validateField(abi, name, src, allowed, isPrice) {
444
- if (typeof src !== "object" || src === null) bad(name, "is required and must be { value } or { read }");
1037
+ if (typeof src !== "object" || src === null) bad2(name, "is required and must be { value } or { read }");
445
1038
  const s = src;
446
1039
  const hasRead = Object.hasOwn(s, "read");
447
1040
  const hasValue = Object.hasOwn(s, "value");
448
- if (hasRead && hasValue) bad(name, "must be exactly one of { value } or { read }, not both");
1041
+ if (hasRead && hasValue) bad2(name, "must be exactly one of { value } or { read }, not both");
449
1042
  if (hasRead) {
450
- if (typeof s.read !== "object" || s.read === null) bad(`${name}.read`, "must be { functionName, args?, output? }");
451
- if (s.unit !== void 0) bad(name, "unit is only valid with a string value");
1043
+ if (typeof s.read !== "object" || s.read === null) bad2(`${name}.read`, "must be { functionName, args?, output? }");
1044
+ if (s.unit !== void 0) bad2(name, "unit is only valid with a string value");
452
1045
  const fn = validateCall(abi, s.read, `${name}.read`, "read", allowed);
453
1046
  resolveOutput(fn, s.read.output, `${name}.read`);
454
1047
  } else if (typeof s.value === "bigint") {
455
- if (s.unit !== void 0) bad(name, "unit is only valid with a string value");
456
- if (s.value < 0n) bad(`${name}.value`, "must not be negative");
1048
+ if (s.unit !== void 0) bad2(name, "unit is only valid with a string value");
1049
+ if (s.value < 0n) bad2(`${name}.value`, "must not be negative");
457
1050
  } else if (typeof s.value === "string") {
458
- if (s.unit !== "display") bad(name, 'string values need unit: "display"');
459
- if (!isPrice) bad(name, "display units are only valid for price; use a bigint in base units");
460
- if (!DISPLAY_AMOUNT.test(s.value)) bad(`${name}.value`, `"${s.value}" is not a decimal number like "0.01"`);
1051
+ if (s.unit !== "display") bad2(name, 'string values need unit: "display"');
1052
+ if (!isPrice) bad2(name, "display units are only valid for price; use a bigint in base units");
1053
+ if (!DISPLAY_AMOUNT.test(s.value)) bad2(`${name}.value`, `"${s.value}" is not a decimal number like "0.01"`);
461
1054
  } else {
462
- bad(name, 'must be { value: bigint }, { value: string, unit: "display" } (price only) or { read: {...} }');
1055
+ bad2(name, 'must be { value: bigint }, { value: string, unit: "display" } (price only) or { read: {...} }');
463
1056
  }
464
1057
  }
465
1058
  function hasNonzeroStaticPrice(price) {
@@ -469,27 +1062,27 @@ function hasNonzeroStaticPrice(price) {
469
1062
  }
470
1063
  function validateContractConfig(config) {
471
1064
  const c = config;
472
- if (!c || typeof c !== "object") bad("config", "must be an object");
473
- if (c.type !== "contract") bad("type", 'must be "contract"');
474
- if (!Number.isSafeInteger(c.chainId) || c.chainId <= 0) bad("chainId", "must be a positive safe integer");
475
- if (!isHexAddress(c.address)) bad("address", `"${String(c.address)}" is not a valid address`);
1065
+ if (!c || typeof c !== "object") bad2("config", "must be an object");
1066
+ if (c.type !== "contract") bad2("type", 'must be "contract"');
1067
+ if (!Number.isSafeInteger(c.chainId) || c.chainId <= 0) bad2("chainId", "must be a positive safe integer");
1068
+ if (!isHexAddress(c.address)) bad2("address", `"${String(c.address)}" is not a valid address`);
476
1069
  if (c.tokenContract !== void 0 && !isHexAddress(c.tokenContract)) {
477
- bad("tokenContract", `"${String(c.tokenContract)}" is not a valid address`);
1070
+ bad2("tokenContract", `"${String(c.tokenContract)}" is not a valid address`);
478
1071
  }
479
- if (!Array.isArray(c.abi)) bad("abi", "must be an abi array");
1072
+ if (!Array.isArray(c.abi)) bad2("abi", "must be an abi array");
480
1073
  const abi = c.abi;
481
1074
  const mintFn = validateCall(abi, c.mint, "mint", "mint", PLACEHOLDERS);
482
- if (c.price === void 0 || c.price === null) bad("price", "is required");
1075
+ if (c.price === void 0 || c.price === null) bad2("price", "is required");
483
1076
  validateField(abi, "price", c.price, NO_PLACEHOLDERS, true);
484
1077
  const cur = c.price.currency;
485
1078
  if (cur !== "native" && !(typeof cur === "object" && cur !== null && isHexAddress(cur.address))) {
486
- bad("price.currency", 'must be "native" or { address } with a valid ERC20 address');
1079
+ bad2("price.currency", 'must be "native" or { address } with a valid ERC20 address');
487
1080
  }
488
1081
  if (cur === "native" && mintFn.stateMutability === "nonpayable" && hasNonzeroStaticPrice(c.price)) {
489
- bad("price", `is a native price, but "${mintFn.name}" is nonpayable and cannot take value`);
1082
+ bad2("price", `is a native price, but "${mintFn.name}" is nonpayable and cannot take value`);
490
1083
  }
491
1084
  const per = c.price.per;
492
- if (per !== void 0 && per !== "unit" && per !== "total") bad("price.per", 'must be "unit" or "total"');
1085
+ if (per !== void 0 && per !== "unit" && per !== "total") bad2("price.per", 'must be "unit" or "total"');
493
1086
  validateOptional(abi, "totalMinted", c.totalMinted, NO_PLACEHOLDERS);
494
1087
  validateOptional(abi, "maxSupply", c.maxSupply, NO_PLACEHOLDERS);
495
1088
  validateOptional(abi, "startTime", c.startTime, NO_PLACEHOLDERS);
@@ -503,7 +1096,7 @@ function validateOptional(abi, name, src, allowed) {
503
1096
  function varFor(token, vars) {
504
1097
  const key = token.slice(1, -1);
505
1098
  const v = vars[key];
506
- if (v === void 0) throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `placeholder ${token} has no value here`);
1099
+ if (v === void 0) throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `placeholder ${token} has no value here`);
507
1100
  return typeof v === "string" ? _viem.getAddress.call(void 0, v) : v;
508
1101
  }
509
1102
  function fill(t, p, vars) {
@@ -519,46 +1112,46 @@ function fill(t, p, vars) {
519
1112
  }
520
1113
  var fillArgs = (args, inputs, vars) => (_nullishCoalesce(args, () => ( []))).map((a, i) => fill(a, inputs[i], vars));
521
1114
  var totalFor = (per, price, quantity) => per === "total" ? price : price * quantity;
522
- function shortMessage(e) {
1115
+ function shortMessage2(e) {
523
1116
  return e instanceof _viem.BaseError ? e.shortMessage : e instanceof Error ? e.message : String(e);
524
1117
  }
525
- var abortError = () => new DOMException("The operation was aborted", "AbortError");
526
- var isAbortError = (e) => _optionalChain([e, 'optionalAccess', _12 => _12.name]) === "AbortError";
527
- function throwIfAborted(ctx) {
528
- if (_optionalChain([ctx, 'access', _13 => _13.signal, 'optionalAccess', _14 => _14.aborted])) throw abortError();
1118
+ var abortError2 = () => new DOMException("The operation was aborted", "AbortError");
1119
+ var isAbortError2 = (e) => _optionalChain([e, 'optionalAccess', _30 => _30.name]) === "AbortError";
1120
+ function throwIfAborted2(ctx) {
1121
+ if (_optionalChain([ctx, 'access', _31 => _31.signal, 'optionalAccess', _32 => _32.aborted])) throw abortError2();
529
1122
  }
530
- function io(ctx, start) {
1123
+ function io2(ctx, start) {
531
1124
  const signal = ctx.signal;
532
1125
  if (!signal) return start();
533
- if (signal.aborted) return Promise.reject(abortError());
1126
+ if (signal.aborted) return Promise.reject(abortError2());
534
1127
  return new Promise((resolve, reject) => {
535
- const onAbort = () => reject(abortError());
1128
+ const onAbort = () => reject(abortError2());
536
1129
  signal.addEventListener("abort", onAbort, { once: true });
537
1130
  start().then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
538
1131
  });
539
1132
  }
540
- function rpcError(e) {
541
- if (_chunkOO6QQT3Mcjs.isMintError.call(void 0, e) || isAbortError(e)) throw e;
542
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage(e)}`, { cause: e });
1133
+ function rpcError2(e) {
1134
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e) || isAbortError2(e)) throw e;
1135
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage2(e)}`, { cause: e });
543
1136
  }
544
1137
  function classifyReadError(e, field) {
545
- if (_chunkOO6QQT3Mcjs.isMintError.call(void 0, e) || isAbortError(e)) throw e;
1138
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e) || isAbortError2(e)) throw e;
546
1139
  if (e instanceof _viem.BaseError && e.walk((x) => x instanceof _viem.ContractFunctionRevertedError || x instanceof _viem.ContractFunctionZeroDataError)) {
547
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} read reverted or returned no data: ${e.shortMessage}`, { field, cause: e });
1140
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} read reverted or returned no data: ${e.shortMessage}`, { field, cause: e });
548
1141
  }
549
- return rpcError(e);
1142
+ return rpcError2(e);
550
1143
  }
551
1144
  async function readCall(ctx, params, field) {
552
1145
  try {
553
- return await io(ctx, () => ctx.client.readContract(params));
1146
+ return await io2(ctx, () => ctx.client.readContract(params));
554
1147
  } catch (e) {
555
1148
  return classifyReadError(e, field);
556
1149
  }
557
1150
  }
558
1151
  function toBigInt(v, field) {
559
1152
  const n = typeof v === "number" ? BigInt(v) : v;
560
- if (typeof n !== "bigint") throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} did not return a number`, { field });
561
- if (n < 0n) throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} returned a negative number`, { field });
1153
+ if (typeof n !== "bigint") throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} did not return a number`, { field });
1154
+ if (n < 0n) throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} returned a negative number`, { field });
562
1155
  return n;
563
1156
  }
564
1157
  async function readField(ctx, config, name, src, vars) {
@@ -574,43 +1167,43 @@ async function readField(ctx, config, name, src, vars) {
574
1167
  }
575
1168
  const value = src.value;
576
1169
  if (typeof value === "bigint") return value;
577
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${name} display units are only valid for price`, { field: name });
1170
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${name} display units are only valid for price`, { field: name });
578
1171
  }
579
1172
  function tupleMembers(res, fn, index) {
580
1173
  if (Array.isArray(res)) return res;
581
1174
  const comps = _nullishCoalesce(fn.outputs[0].components, () => ( []));
582
1175
  const out = [];
583
- out[index] = res[_nullishCoalesce(_optionalChain([comps, 'access', _15 => _15[index], 'optionalAccess', _16 => _16.name]), () => ( ""))];
1176
+ out[index] = res[_nullishCoalesce(_optionalChain([comps, 'access', _33 => _33[index], 'optionalAccess', _34 => _34.name]), () => ( ""))];
584
1177
  return out;
585
1178
  }
586
1179
  var optField = (ctx, config, name, src, vars) => src ? readField(ctx, config, name, src, vars) : Promise.resolve(null);
587
1180
  function toSeconds(v, field) {
588
1181
  if (v === null || v === 0n) return null;
589
- if (v > BigInt(Number.MAX_SAFE_INTEGER)) throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} is too large for a unix timestamp`, { field });
1182
+ if (v > BigInt(Number.MAX_SAFE_INTEGER)) throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} is too large for a unix timestamp`, { field });
590
1183
  return Number(v);
591
1184
  }
592
- function nativeMeta(ctx) {
593
- const n = _optionalChain([ctx, 'access', _17 => _17.client, 'access', _18 => _18.chain, 'optionalAccess', _19 => _19.nativeCurrency]);
594
- return { decimals: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _20 => _20.decimals]), () => ( 18)), symbol: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _21 => _21.symbol]), () => ( "ETH")) };
1185
+ function nativeMeta2(ctx) {
1186
+ const n = _optionalChain([ctx, 'access', _35 => _35.client, 'access', _36 => _36.chain, 'optionalAccess', _37 => _37.nativeCurrency]);
1187
+ return { decimals: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _38 => _38.decimals]), () => ( 18)), symbol: _nullishCoalesce(_optionalChain([n, 'optionalAccess', _39 => _39.symbol]), () => ( "ETH")) };
595
1188
  }
596
1189
  var erc20Of = (config) => config.price.currency === "native" ? null : _viem.getAddress.call(void 0, config.price.currency.address);
597
1190
  async function currencyMeta(ctx, config) {
598
1191
  const token = erc20Of(config);
599
- if (!token) return { token, ...nativeMeta(ctx) };
1192
+ if (!token) return { token, ...nativeMeta2(ctx) };
600
1193
  const field = "price.currency.address";
601
1194
  const [symbol, decimals] = await Promise.all([
602
1195
  readCall(ctx, { address: token, abi: ERC20_ABI, functionName: "symbol" }, field),
603
1196
  readCall(ctx, { address: token, abi: ERC20_ABI, functionName: "decimals" }, field)
604
1197
  ]);
605
1198
  if (typeof symbol !== "string" || typeof decimals !== "number") {
606
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `${field} ${token} is not an ERC20 (symbol/decimals unreadable)`, { field });
1199
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `${field} ${token} is not an ERC20 (symbol/decimals unreadable)`, { field });
607
1200
  }
608
1201
  return { token, decimals, symbol };
609
1202
  }
610
1203
  function parseDisplay(value, decimals) {
611
1204
  const frac = _nullishCoalesce(value.split(".")[1], () => ( ""));
612
1205
  if (frac.length > decimals) {
613
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `price.value "${value}" has more than ${decimals} decimal places`, { field: "price.value" });
1206
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `price.value "${value}" has more than ${decimals} decimal places`, { field: "price.value" });
614
1207
  }
615
1208
  return _viem.parseUnits.call(void 0, value, decimals);
616
1209
  }
@@ -621,13 +1214,13 @@ async function resolvePrice(ctx, config, meta) {
621
1214
  if (typeof value === "bigint") return value;
622
1215
  return parseDisplay(value, (await _asyncNullishCoalesce(meta, async () => ( await currencyMeta(ctx, config)))).decimals);
623
1216
  }
624
- var money = (value, decimals, symbol) => ({
1217
+ var money2 = (value, decimals, symbol) => ({
625
1218
  value,
626
1219
  decimals,
627
1220
  symbol,
628
1221
  formatted: _viem.formatUnits.call(void 0, value, decimals)
629
1222
  });
630
- function revertData(e) {
1223
+ function revertData2(e) {
631
1224
  for (let cur = e, depth = 0; cur && depth < 12; depth++) {
632
1225
  const d = cur.data;
633
1226
  if (typeof d === "string" && d.startsWith("0x") && d.length >= 10) return d;
@@ -644,28 +1237,28 @@ function describeRevert(abi, data) {
644
1237
  const d = _viem.decodeErrorResult.call(void 0, { abi, data });
645
1238
  const args = _nullishCoalesce(d.args, () => ( []));
646
1239
  if (d.errorName === "Error") return String(_nullishCoalesce(args[0], () => ( "execution reverted")));
647
- const inputs = _nullishCoalesce(_optionalChain([d, 'access', _22 => _22.abiItem, 'optionalAccess', _23 => _23.inputs]), () => ( []));
648
- const shown = args.map((a, i) => _optionalChain([inputs, 'access', _24 => _24[i], 'optionalAccess', _25 => _25.name]) ? `${inputs[i].name}: ${String(a)}` : String(a));
1240
+ const inputs = _nullishCoalesce(_optionalChain([d, 'access', _40 => _40.abiItem, 'optionalAccess', _41 => _41.inputs]), () => ( []));
1241
+ const shown = args.map((a, i) => _optionalChain([inputs, 'access', _42 => _42[i], 'optionalAccess', _43 => _43.name]) ? `${inputs[i].name}: ${String(a)}` : String(a));
649
1242
  return `${d.errorName}(${shown.join(", ")})`;
650
- } catch (e2) {
1243
+ } catch (e4) {
651
1244
  return `reverted with unrecognized error ${data.slice(0, 10)}`;
652
1245
  }
653
1246
  }
654
1247
  function toSimulationError(e, abi) {
655
- if (_chunkOO6QQT3Mcjs.isMintError.call(void 0, e)) return e;
656
- if (isAbortError(e)) throw e;
1248
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e)) return e;
1249
+ if (isAbortError2(e)) throw e;
657
1250
  if (e instanceof _viem.BaseError && e.walk((x) => x instanceof _viem.InsufficientFundsError)) {
658
- return new (0, _chunkOO6QQT3Mcjs.MintError)("INSUFFICIENT_FUNDS", `Payer cannot cover the mint: ${e.shortMessage}`, { cause: e });
1251
+ return new (0, _chunkGO4TR3HBcjs.MintError)("INSUFFICIENT_FUNDS", `Payer cannot cover the mint: ${e.shortMessage}`, { cause: e });
659
1252
  }
660
- const data = revertData(e);
661
- if (data) return new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", describeRevert(abi, data), { cause: e });
1253
+ const data = revertData2(e);
1254
+ if (data) return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", describeRevert(abi, data), { cause: e });
662
1255
  const isRevert = e instanceof _viem.BaseError && e.walk((x) => x.code === 3 || /execution reverted/i.test(x.message));
663
- if (isRevert) return new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", shortMessage(e), { cause: e });
664
- return new (0, _chunkOO6QQT3Mcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage(e)}`, { cause: e });
1256
+ if (isRevert) return new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", shortMessage2(e), { cause: e });
1257
+ return new (0, _chunkGO4TR3HBcjs.MintError)("RPC_ERROR", `RPC request failed: ${shortMessage2(e)}`, { cause: e });
665
1258
  }
666
1259
  async function simulateMint(ctx, config, call) {
667
1260
  try {
668
- await io(ctx, () => ctx.client.call({ account: call.payer, to: call.to, data: call.data, value: call.value }));
1261
+ await io2(ctx, () => ctx.client.call({ account: call.payer, to: call.to, data: call.data, value: call.value }));
669
1262
  } catch (e) {
670
1263
  throw toSimulationError(e, config.abi);
671
1264
  }
@@ -675,22 +1268,22 @@ function encodeMint(config, vars) {
675
1268
  try {
676
1269
  return _viem.encodeFunctionData.call(void 0, { abi: [fn], functionName: fn.name, args: fillArgs(config.mint.args, fn.inputs, vars) });
677
1270
  } catch (e) {
678
- if (_chunkOO6QQT3Mcjs.isMintError.call(void 0, e)) throw e;
679
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INVALID_CONFIG", `mint.args cannot be encoded for ${signature(fn)}: ${shortMessage(e)}`, { field: "mint.args", cause: e });
1271
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e)) throw e;
1272
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INVALID_CONFIG", `mint.args cannot be encoded for ${signature(fn)}: ${shortMessage2(e)}`, { field: "mint.args", cause: e });
680
1273
  }
681
1274
  }
682
1275
  function mintValue(config, token, totalPrice) {
683
1276
  if (token) return 0n;
684
1277
  const fn = validateCall(config.abi, config.mint, "mint", "mint", PLACEHOLDERS);
685
1278
  if (fn.stateMutability === "nonpayable") {
686
- if (totalPrice > 0n) bad("price", `is ${totalPrice} wei in native currency, but "${fn.name}" is nonpayable and cannot take value`);
1279
+ if (totalPrice > 0n) bad2("price", `is ${totalPrice} wei in native currency, but "${fn.name}" is nonpayable and cannot take value`);
687
1280
  return 0n;
688
1281
  }
689
1282
  return totalPrice;
690
1283
  }
691
- async function readDrop(ctx, config) {
1284
+ async function readDrop2(ctx, config) {
692
1285
  validateContractConfig(config);
693
- throwIfAborted(ctx);
1286
+ throwIfAborted2(ctx);
694
1287
  const meta = await currencyMeta(ctx, config);
695
1288
  const none = {};
696
1289
  const [price, totalMinted, maxSupply, start, end] = await Promise.all([
@@ -701,11 +1294,11 @@ async function readDrop(ctx, config) {
701
1294
  optField(ctx, config, "endTime", config.endTime, none)
702
1295
  ]);
703
1296
  mintValue(config, meta.token, price);
704
- const native = nativeMeta(ctx);
1297
+ const native = nativeMeta2(ctx);
705
1298
  return {
706
1299
  chainId: config.chainId,
707
- unitPrice: money(price, meta.decimals, meta.symbol),
708
- unitFee: money(0n, native.decimals, native.symbol),
1300
+ unitPrice: money2(price, meta.decimals, meta.symbol),
1301
+ unitFee: money2(0n, native.decimals, native.symbol),
709
1302
  totalMinted: _nullishCoalesce(totalMinted, () => ( 0n)),
710
1303
  maxSupply: maxSupply === null || maxSupply === 0n ? null : maxSupply,
711
1304
  startTime: toSeconds(start, "startTime"),
@@ -715,9 +1308,9 @@ async function readDrop(ctx, config) {
715
1308
  pricePer: _nullishCoalesce(config.price.per, () => ( "unit"))
716
1309
  };
717
1310
  }
718
- async function readWallet(ctx, config, { payer, recipient, quantity, drop }) {
1311
+ async function readWallet2(ctx, config, { payer, recipient, quantity, drop }) {
719
1312
  validateContractConfig(config);
720
- throwIfAborted(ctx);
1313
+ throwIfAborted2(ctx);
721
1314
  const qty = BigInt(quantity);
722
1315
  const unitPrice = drop.unitPrice.value;
723
1316
  const totalPrice = totalFor(drop.pricePer, unitPrice, qty);
@@ -725,14 +1318,14 @@ async function readWallet(ctx, config, { payer, recipient, quantity, drop }) {
725
1318
  const [walletMinted, rawMax, native, erc20] = await Promise.all([
726
1319
  optField(ctx, config, "walletMinted", config.walletMinted, vars),
727
1320
  optField(ctx, config, "walletMax", config.walletMax, vars),
728
- io(ctx, () => ctx.client.getBalance({ address: payer })).catch(rpcError),
1321
+ io2(ctx, () => ctx.client.getBalance({ address: payer })).catch(rpcError2),
729
1322
  drop.paymentToken ? readCall(ctx, { address: drop.paymentToken, abi: ERC20_ABI, functionName: "balanceOf", args: [payer] }, "price.currency.address").then(
730
1323
  (v) => toBigInt(v, "price.currency.address")
731
1324
  ) : Promise.resolve(null)
732
1325
  ]);
733
1326
  const walletMax = rawMax === null || rawMax === 0n ? null : rawMax;
734
1327
  const remaining = walletMax === null ? null : walletMax > (_nullishCoalesce(walletMinted, () => ( 0n))) ? walletMax - (_nullishCoalesce(walletMinted, () => ( 0n))) : 0n;
735
- const maxQuantity = remaining === null ? null : Number(remaining < BigInt(_chunkOO6QQT3Mcjs.MAX_QUANTITY) ? remaining : BigInt(_chunkOO6QQT3Mcjs.MAX_QUANTITY));
1328
+ const maxQuantity = remaining === null ? null : Number(remaining < BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY) ? remaining : BigInt(_chunkGO4TR3HBcjs.MAX_QUANTITY));
736
1329
  let ineligible = null;
737
1330
  let gas = FALLBACK_MINT_GAS;
738
1331
  if (remaining === 0n) {
@@ -741,16 +1334,16 @@ async function readWallet(ctx, config, { payer, recipient, quantity, drop }) {
741
1334
  const call = { payer, to: _viem.getAddress.call(void 0, config.address), data: encodeMint(config, vars), value: mintValue(config, null, totalPrice) };
742
1335
  try {
743
1336
  await simulateMint(ctx, config, call);
744
- gas = await io(ctx, () => ctx.client.estimateGas({ account: payer, to: call.to, data: call.data, value: call.value })).catch((e) => {
1337
+ gas = await io2(ctx, () => ctx.client.estimateGas({ account: payer, to: call.to, data: call.data, value: call.value })).catch((e) => {
745
1338
  throw toSimulationError(e, config.abi);
746
1339
  });
747
1340
  } catch (e) {
748
- if (!_chunkOO6QQT3Mcjs.isMintError.call(void 0, e) || e.reason !== "SIMULATION_REVERTED") throw e;
1341
+ if (!_chunkGO4TR3HBcjs.isMintError.call(void 0, e) || e.reason !== "SIMULATION_REVERTED") throw e;
749
1342
  ineligible = { reason: "SIMULATION_REVERTED", message: e.message };
750
1343
  }
751
1344
  }
752
1345
  if (drop.paymentToken) gas += APPROVE_GAS;
753
- const gasPrice = await io(ctx, () => ctx.client.getGasPrice()).catch(rpcError);
1346
+ const gasPrice = await io2(ctx, () => ctx.client.getGasPrice()).catch(rpcError2);
754
1347
  return {
755
1348
  walletMinted,
756
1349
  walletMax,
@@ -761,11 +1354,11 @@ async function readWallet(ctx, config, { payer, recipient, quantity, drop }) {
761
1354
  gasReserve: gas * gasPrice
762
1355
  };
763
1356
  }
764
- async function buildPlan(ctx, attempt, wallet) {
1357
+ async function buildPlan2(ctx, attempt, wallet) {
765
1358
  void wallet;
766
1359
  const { config, payer, recipient } = attempt;
767
1360
  validateContractConfig(config);
768
- throwIfAborted(ctx);
1361
+ throwIfAborted2(ctx);
769
1362
  const qty = BigInt(attempt.quantity);
770
1363
  const unitPrice = await resolvePrice(ctx, config);
771
1364
  const totalPrice = totalFor(_nullishCoalesce(config.price.per, () => ( "unit")), unitPrice, qty);
@@ -793,11 +1386,11 @@ async function buildPlan(ctx, attempt, wallet) {
793
1386
  }
794
1387
  return { approve, mint, tokenContract: _viem.getAddress.call(void 0, attempt.tokenContract) };
795
1388
  }
796
- async function simulate(ctx, attempt, plan) {
797
- throwIfAborted(ctx);
1389
+ async function simulate2(ctx, attempt, plan) {
1390
+ throwIfAborted2(ctx);
798
1391
  await simulateMint(ctx, attempt.config, { payer: attempt.payer, to: plan.mint.to, data: plan.mint.data, value: plan.mint.value });
799
1392
  }
800
- var contractAdapter = { readDrop, readWallet, buildPlan, simulate };
1393
+ var contractAdapter = { readDrop: readDrop2, readWallet: readWallet2, buildPlan: buildPlan2, simulate: simulate2 };
801
1394
 
802
1395
  // src/react/useMint.ts
803
1396
  var REFRESH_MS = 3e4;
@@ -811,7 +1404,18 @@ function configKeyOf(config) {
811
1404
  return JSON.stringify(config, (_k, v) => typeof v === "bigint" ? { __dropkitBigInt: v.toString() } : v);
812
1405
  }
813
1406
  function adapterFor(config) {
814
- return config.type === "manifold-claim" ? _chunkOO6QQT3Mcjs.manifoldClaimAdapter : contractAdapter;
1407
+ switch (config.type) {
1408
+ case "manifold-claim":
1409
+ return _chunkGO4TR3HBcjs.manifoldClaimAdapter;
1410
+ case "contract":
1411
+ return contractAdapter;
1412
+ case "tl-stacks":
1413
+ return tlStacksAdapter;
1414
+ default: {
1415
+ const unreachable = config;
1416
+ return unreachable;
1417
+ }
1418
+ }
815
1419
  }
816
1420
  var bridgeEnabled = (config) => config.type === "manifold-claim";
817
1421
  function payChainsOf(config, option) {
@@ -827,36 +1431,58 @@ function routeChainOf(payChains, accountChainId, payChainId) {
827
1431
  var ROUTE_DEBOUNCE_MS = 500;
828
1432
  var symbolOf = (chainId) => {
829
1433
  try {
830
- return _chunkOO6QQT3Mcjs.getChain.call(void 0, chainId).nativeCurrency.symbol;
831
- } catch (e3) {
1434
+ return _chunkGO4TR3HBcjs.getChain.call(void 0, chainId).nativeCurrency.symbol;
1435
+ } catch (e5) {
832
1436
  return "ETH";
833
1437
  }
834
1438
  };
835
- var shortOf = (chainId) => ({ chainId, symbol: symbolOf(chainId), name: _chunkOO6QQT3Mcjs.chainName.call(void 0, chainId) });
1439
+ var shortOf = (chainId) => ({ chainId, symbol: symbolOf(chainId), name: _chunkGO4TR3HBcjs.chainName.call(void 0, chainId) });
836
1440
  function tokenContractOf(config) {
837
- return config.type === "manifold-claim" ? config.creatorContract : _nullishCoalesce(config.tokenContract, () => ( config.address));
1441
+ switch (config.type) {
1442
+ case "manifold-claim":
1443
+ return config.creatorContract;
1444
+ case "contract":
1445
+ return _nullishCoalesce(config.tokenContract, () => ( config.address));
1446
+ case "tl-stacks":
1447
+ return config.nftContract;
1448
+ default: {
1449
+ const unreachable = config;
1450
+ return unreachable;
1451
+ }
1452
+ }
838
1453
  }
839
1454
  function eventAddressOf(config) {
840
- return config.type === "manifold-claim" ? config.creatorContract : config.address;
1455
+ switch (config.type) {
1456
+ case "manifold-claim":
1457
+ return config.creatorContract;
1458
+ case "contract":
1459
+ return config.address;
1460
+ case "tl-stacks":
1461
+ return config.nftContract;
1462
+ default: {
1463
+ const unreachable = config;
1464
+ return unreachable;
1465
+ }
1466
+ }
841
1467
  }
842
- var isUnsupported = (reason) => _chunkOO6QQT3Mcjs.UNSUPPORTED_REASONS.includes(reason);
1468
+ var isUnsupported = (reason) => _chunkGO4TR3HBcjs.UNSUPPORTED_REASONS.includes(reason);
843
1469
  function errorReasonOf(e) {
844
- const { reason, message } = _chunkOO6QQT3Mcjs.toReason.call(void 0, e);
1470
+ const { reason, message } = _chunkGO4TR3HBcjs.toReason.call(void 0, e);
845
1471
  const ok = ["USER_REJECTED", "TX_REVERTED", "RATE_LIMITED", "RPC_ERROR", "CHAIN_SWITCH_FAILED", "ALLOWLIST_UNAVAILABLE"];
846
1472
  return { reason: ok.includes(reason) ? reason : "RPC_ERROR", message };
847
1473
  }
848
1474
  function explorerUrlFor(chainId, hash) {
849
1475
  try {
850
- const url = _optionalChain([_chunkOO6QQT3Mcjs.getChain.call(void 0, chainId), 'access', _26 => _26.blockExplorers, 'optionalAccess', _27 => _27.default, 'access', _28 => _28.url]);
1476
+ const url = _optionalChain([_chunkGO4TR3HBcjs.getChain.call(void 0, chainId), 'access', _44 => _44.blockExplorers, 'optionalAccess', _45 => _45.default, 'access', _46 => _46.url]);
851
1477
  return url ? `${url.replace(/\/$/, "")}/tx/${hash}` : null;
852
- } catch (e4) {
1478
+ } catch (e6) {
853
1479
  return null;
854
1480
  }
855
1481
  }
856
1482
  var receiptOk = (status) => status === "success" || status === 1 || status === 1n || status === "0x1";
857
1483
  function useMint(options) {
858
1484
  const { config, recipient, quantity: quantityProp, connect } = options;
859
- const [machine, rawDispatch] = _react.useReducer.call(void 0, _chunkOO6QQT3Mcjs.reducer, void 0, () => _chunkOO6QQT3Mcjs.initialState.call(void 0, { quantity: quantityProp }));
1485
+ const [machine, rawDispatch] = _react.useReducer.call(void 0, _chunkGO4TR3HBcjs.reducer, void 0, () => _chunkGO4TR3HBcjs.initialState.call(void 0, { quantity: quantityProp }));
860
1486
  const [widgetFail, setWidgetFail] = _react.useState.call(void 0, null);
861
1487
  const [widgetRetry, setWidgetRetry] = _react.useState.call(void 0, 0);
862
1488
  const configKey = configKeyOf(config);
@@ -883,15 +1509,15 @@ function useMint(options) {
883
1509
  });
884
1510
  const dispatch = _react.useCallback.call(void 0, (event) => {
885
1511
  if (!mounted.current) return;
886
- stateRef.current = _chunkOO6QQT3Mcjs.reducer.call(void 0, stateRef.current, event);
1512
+ stateRef.current = _chunkGO4TR3HBcjs.reducer.call(void 0, stateRef.current, event);
887
1513
  rawDispatch(event);
888
1514
  }, []);
889
1515
  const emit = _react.useCallback.call(void 0, (type, over = {}) => {
890
1516
  const handler = propsRef.current.onEvent;
891
1517
  if (!handler || !mounted.current) return;
892
- const cfg = _nullishCoalesce(_optionalChain([attemptRef, 'access', _29 => _29.current, 'optionalAccess', _30 => _30.config]), () => ( propsRef.current.config));
1518
+ const cfg = _nullishCoalesce(_optionalChain([attemptRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.config]), () => ( propsRef.current.config));
893
1519
  const s = stateRef.current;
894
- const originChainId = _nullishCoalesce(_optionalChain([attemptRef, 'access', _31 => _31.current, 'optionalAccess', _32 => _32.originChainId]), () => ( (_optionalChain([s, 'access', _33 => _33.route, 'optionalAccess', _34 => _34.kind]) === "relay" ? s.route.originChainId : _nullishCoalesce(_optionalChain([s, 'access', _35 => _35.short, 'optionalAccess', _36 => _36.chainId]), () => ( cfg.chainId)))));
1520
+ const originChainId = _nullishCoalesce(_optionalChain([attemptRef, 'access', _49 => _49.current, 'optionalAccess', _50 => _50.originChainId]), () => ( (_optionalChain([s, 'access', _51 => _51.route, 'optionalAccess', _52 => _52.kind]) === "relay" ? s.route.originChainId : _nullishCoalesce(_optionalChain([s, 'access', _53 => _53.short, 'optionalAccess', _54 => _54.chainId]), () => ( cfg.chainId)))));
895
1521
  const payload = {
896
1522
  type,
897
1523
  state: s.name,
@@ -905,14 +1531,14 @@ function useMint(options) {
905
1531
  };
906
1532
  try {
907
1533
  handler(payload);
908
- } catch (e5) {
1534
+ } catch (e7) {
909
1535
  }
910
1536
  }, []);
911
1537
  const clientFor = _react.useCallback.call(void 0, (life, cfg) => {
912
- const rpcUrl = _optionalChain([propsRef, 'access', _37 => _37.current, 'access', _38 => _38.rpcUrls, 'optionalAccess', _39 => _39[cfg.chainId]]);
1538
+ const rpcUrl = _optionalChain([propsRef, 'access', _55 => _55.current, 'access', _56 => _56.rpcUrls, 'optionalAccess', _57 => _57[cfg.chainId]]);
913
1539
  if (!life.client || life.rpcUrl !== rpcUrl) {
914
1540
  life.rpcUrl = rpcUrl;
915
- life.client = _chunkOO6QQT3Mcjs.createReadClient.call(void 0, { chainId: cfg.chainId, rpcUrls: propsRef.current.rpcUrls, useBridge: bridgeEnabled(cfg) });
1541
+ life.client = _chunkGO4TR3HBcjs.createReadClient.call(void 0, { chainId: cfg.chainId, rpcUrls: propsRef.current.rpcUrls, useBridge: bridgeEnabled(cfg) });
916
1542
  }
917
1543
  return life.client;
918
1544
  }, []);
@@ -925,7 +1551,7 @@ function useMint(options) {
925
1551
  }),
926
1552
  [clientFor]
927
1553
  );
928
- const readDrop2 = _react.useCallback.call(void 0,
1554
+ const readDrop3 = _react.useCallback.call(void 0,
929
1555
  async (life, gen, cfg) => {
930
1556
  const adapter = adapterFor(cfg);
931
1557
  try {
@@ -934,7 +1560,7 @@ function useMint(options) {
934
1560
  dispatch({ type: "DROP_LOADED", gen, drop, now: Math.max(stateRef.current.now, nowSec()) });
935
1561
  } catch (e) {
936
1562
  if (life.controller.signal.aborted || life.gen !== gen || lifeRef.current !== life) return;
937
- const { reason, message } = _chunkOO6QQT3Mcjs.toReason.call(void 0, e);
1563
+ const { reason, message } = _chunkGO4TR3HBcjs.toReason.call(void 0, e);
938
1564
  if (isUnsupported(reason)) dispatch({ type: "DROP_UNSUPPORTED", gen, reason, message });
939
1565
  else dispatch({ type: "READ_FAILED", gen, ...errorReasonOf(e) });
940
1566
  }
@@ -945,14 +1571,14 @@ function useMint(options) {
945
1571
  (key, cfg) => {
946
1572
  const prev = lifeRef.current;
947
1573
  lifeRef.current = null;
948
- _optionalChain([prev, 'optionalAccess', _40 => _40.controller, 'access', _41 => _41.abort, 'call', _42 => _42()]);
1574
+ _optionalChain([prev, 'optionalAccess', _58 => _58.controller, 'access', _59 => _59.abort, 'call', _60 => _60()]);
949
1575
  const gen = ++genRef.current;
950
1576
  const life = { key, controller: new AbortController(), cacheScope: {}, gen };
951
1577
  lifeRef.current = life;
952
1578
  dispatch({ type: "LOAD", gen, kind: "config" });
953
- void readDrop2(life, gen, cfg);
1579
+ void readDrop3(life, gen, cfg);
954
1580
  },
955
- [dispatch, readDrop2]
1581
+ [dispatch, readDrop3]
956
1582
  );
957
1583
  const refreshNow = _react.useCallback.call(void 0,
958
1584
  async (kind = "refresh") => {
@@ -965,13 +1591,13 @@ function useMint(options) {
965
1591
  const gen = ++genRef.current;
966
1592
  life.gen = gen;
967
1593
  dispatch({ type: "LOAD", gen, kind });
968
- await readDrop2(life, gen, propsRef.current.config);
1594
+ await readDrop3(life, gen, propsRef.current.config);
969
1595
  },
970
- [dispatch, readDrop2]
1596
+ [dispatch, readDrop3]
971
1597
  );
972
1598
  const refresh = _react.useCallback.call(void 0, () => refreshNow("refresh"), [refreshNow]);
973
1599
  const isBusy = _react.useCallback.call(void 0,
974
- () => connectingRef.current || attemptRef.current !== null || stateRef.current.attempt !== null || _chunkOO6QQT3Mcjs.IN_FLIGHT_STATES.includes(stateRef.current.name),
1600
+ () => connectingRef.current || attemptRef.current !== null || stateRef.current.attempt !== null || _chunkGO4TR3HBcjs.IN_FLIGHT_STATES.includes(stateRef.current.name),
975
1601
  []
976
1602
  );
977
1603
  const executeAttempt = _react.useCallback.call(void 0,
@@ -987,20 +1613,20 @@ function useMint(options) {
987
1613
  };
988
1614
  const assertPayer = () => {
989
1615
  assertActive();
990
- const live = _chunkOO6QQT3Mcjs.getAccount.call(void 0, );
1616
+ const live = _chunkGO4TR3HBcjs.getAccount.call(void 0, );
991
1617
  if (!live || live.address.toLowerCase() !== attempt.payer.toLowerCase()) {
992
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("USER_REJECTED", "The connected wallet changed before the transaction was sent.");
1618
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("USER_REJECTED", "The connected wallet changed before the transaction was sent.");
993
1619
  }
994
1620
  };
995
1621
  let wallet2 = null;
996
1622
  const walletFor = () => {
997
- if (!wallet2) wallet2 = _chunkOO6QQT3Mcjs.getWalletClient.call(void 0, attempt.chainId);
1623
+ if (!wallet2) wallet2 = _chunkGO4TR3HBcjs.getWalletClient.call(void 0, attempt.chainId);
998
1624
  return wallet2;
999
1625
  };
1000
1626
  const submit = async (tx) => {
1001
1627
  assertPayer();
1002
1628
  const w = walletFor();
1003
- return w.sendTransaction({ account: attempt.payer, to: tx.to, data: tx.data, value: tx.value, chain: _chunkOO6QQT3Mcjs.getChain.call(void 0, attempt.chainId) });
1629
+ return w.sendTransaction({ account: attempt.payer, to: tx.to, data: tx.data, value: tx.value, chain: _chunkGO4TR3HBcjs.getChain.call(void 0, attempt.chainId) });
1004
1630
  };
1005
1631
  const waitReceipt = async (hash2) => {
1006
1632
  let cancelled = false;
@@ -1017,19 +1643,19 @@ function useMint(options) {
1017
1643
  receipt2 = await client.waitForTransactionReceipt(params);
1018
1644
  } catch (e) {
1019
1645
  assertActive();
1020
- if (cancelled) throw new (0, _chunkOO6QQT3Mcjs.MintError)("USER_REJECTED", "The transaction was cancelled or replaced with a different transaction.");
1646
+ if (cancelled) throw new (0, _chunkGO4TR3HBcjs.MintError)("USER_REJECTED", "The transaction was cancelled or replaced with a different transaction.");
1021
1647
  if (await walletFor().getChainId() !== attempt.chainId) throw e;
1022
1648
  assertActive();
1023
1649
  receipt2 = await walletFor().extend(_viem.publicActions).waitForTransactionReceipt(params);
1024
1650
  }
1025
1651
  assertActive();
1026
- if (cancelled) throw new (0, _chunkOO6QQT3Mcjs.MintError)("USER_REJECTED", "The transaction was cancelled or replaced with a different transaction.");
1652
+ if (cancelled) throw new (0, _chunkGO4TR3HBcjs.MintError)("USER_REJECTED", "The transaction was cancelled or replaced with a different transaction.");
1027
1653
  return receipt2;
1028
1654
  };
1029
1655
  assertPayer();
1030
1656
  if (account2.chainId !== attempt.chainId) {
1031
1657
  dispatch({ type: "SWITCHING_CHAIN", attemptId: attempt.attemptId });
1032
- await _chunkOO6QQT3Mcjs.switchToChain.call(void 0, attempt.chainId);
1658
+ await _chunkGO4TR3HBcjs.switchToChain.call(void 0, attempt.chainId);
1033
1659
  }
1034
1660
  assertPayer();
1035
1661
  let plan = await adapter.buildPlan(ctx, attempt, walletRead);
@@ -1039,13 +1665,13 @@ function useMint(options) {
1039
1665
  try {
1040
1666
  const simulated = await client.call({ account: attempt.payer, to: a.tx.to, data: a.tx.data, value: a.tx.value });
1041
1667
  if (simulated.data && simulated.data !== "0x" && BigInt(simulated.data) === 0n) {
1042
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", "The token refused the approval.");
1668
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", "The token refused the approval.");
1043
1669
  }
1044
1670
  } catch (e) {
1045
- if (_chunkOO6QQT3Mcjs.isMintError.call(void 0, e)) throw e;
1671
+ if (_chunkGO4TR3HBcjs.isMintError.call(void 0, e)) throw e;
1046
1672
  const reverted = e instanceof _viem.BaseError ? e.walk((cause) => cause instanceof _viem.ExecutionRevertedError) : null;
1047
1673
  if (reverted instanceof _viem.ExecutionRevertedError) {
1048
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", reverted.shortMessage);
1674
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", reverted.shortMessage);
1049
1675
  }
1050
1676
  throw e;
1051
1677
  }
@@ -1057,7 +1683,7 @@ function useMint(options) {
1057
1683
  const approveReceipt = await waitReceipt(approveHash);
1058
1684
  assertActive();
1059
1685
  if (!receiptOk(approveReceipt.status)) {
1060
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("TX_REVERTED", `The approval transaction reverted (${approveHash}).`);
1686
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("TX_REVERTED", `The approval transaction reverted (${approveHash}).`);
1061
1687
  }
1062
1688
  const freshDrop = await adapter.readDrop(ctx, cfg);
1063
1689
  assertActive();
@@ -1068,11 +1694,11 @@ function useMint(options) {
1068
1694
  drop: freshDrop
1069
1695
  });
1070
1696
  assertPayer();
1071
- let checked = _chunkOO6QQT3Mcjs.reducer.call(void 0, _chunkOO6QQT3Mcjs.initialState.call(void 0, { quantity: attempt.quantity }), { type: "ACCOUNT_CHANGED", account: account2 });
1072
- checked = _chunkOO6QQT3Mcjs.reducer.call(void 0, checked, { type: "DROP_LOADED", gen: checked.readGen, drop: freshDrop, now: nowSec() });
1073
- checked = _chunkOO6QQT3Mcjs.reducer.call(void 0, checked, { type: "WALLET_LOADED", gen: checked.walletGen, read: freshWallet });
1074
- if (checked.name !== "live" || (_nullishCoalesce(_chunkOO6QQT3Mcjs.selectMaxQuantity.call(void 0, checked), () => ( 0))) < attempt.quantity) {
1075
- throw new (0, _chunkOO6QQT3Mcjs.MintError)(_nullishCoalesce(checked.reason, () => ( "SIMULATION_REVERTED")), _nullishCoalesce(checked.message, () => ( "The drop is no longer available for this quantity.")));
1697
+ let checked = _chunkGO4TR3HBcjs.reducer.call(void 0, _chunkGO4TR3HBcjs.initialState.call(void 0, { quantity: attempt.quantity }), { type: "ACCOUNT_CHANGED", account: account2 });
1698
+ checked = _chunkGO4TR3HBcjs.reducer.call(void 0, checked, { type: "DROP_LOADED", gen: checked.readGen, drop: freshDrop, now: nowSec() });
1699
+ checked = _chunkGO4TR3HBcjs.reducer.call(void 0, checked, { type: "WALLET_LOADED", gen: checked.walletGen, read: freshWallet });
1700
+ if (checked.name !== "live" || (_nullishCoalesce(_chunkGO4TR3HBcjs.selectMaxQuantity.call(void 0, checked), () => ( 0))) < attempt.quantity) {
1701
+ throw new (0, _chunkGO4TR3HBcjs.MintError)(_nullishCoalesce(checked.reason, () => ( "SIMULATION_REVERTED")), _nullishCoalesce(checked.message, () => ( "The drop is no longer available for this quantity.")));
1076
1702
  }
1077
1703
  plan = await adapter.buildPlan(ctx, attempt, freshWallet);
1078
1704
  assertPayer();
@@ -1088,13 +1714,13 @@ function useMint(options) {
1088
1714
  assertActive();
1089
1715
  const confirmedHash = _nullishCoalesce(receipt.transactionHash, () => ( hash));
1090
1716
  if (!receiptOk(receipt.status)) {
1091
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("TX_REVERTED", `The mint transaction reverted (${confirmedHash}).`);
1717
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("TX_REVERTED", `The mint transaction reverted (${confirmedHash}).`);
1092
1718
  }
1093
- const tokens = _chunkOO6QQT3Mcjs.parseMintReceipt.call(void 0, _nullishCoalesce(receipt.logs, () => ( [])), {
1719
+ const tokens = _chunkGO4TR3HBcjs.parseMintReceipt.call(void 0, _nullishCoalesce(receipt.logs, () => ( [])), {
1094
1720
  tokenContract: _nullishCoalesce(plan.tokenContract, () => ( attempt.tokenContract)),
1095
1721
  recipient: attempt.recipient
1096
1722
  });
1097
- const result = { txHash: confirmedHash, explorerUrl: explorerUrlFor(attempt.chainId, confirmedHash), tokens };
1723
+ const result = { txHash: confirmedHash, explorerUrl: explorerUrlFor(attempt.chainId, confirmedHash), tokens, requested: attempt.quantity };
1098
1724
  dispatch({ type: "ATTEMPT_SUCCEEDED", attemptId: attempt.attemptId, result });
1099
1725
  emit("success", { state: "success", reason: null, txHash: confirmedHash, quantity: attempt.quantity, chainId: attempt.chainId });
1100
1726
  },
@@ -1111,20 +1737,20 @@ function useMint(options) {
1111
1737
  };
1112
1738
  const outcome = await pollUntilTerminal({ testnet: out.testnet, requestId: out.requestId, signal: life.controller.signal, assertActive });
1113
1739
  assertActive();
1114
- const where = _chunkOO6QQT3Mcjs.chainName.call(void 0, out.originChainId);
1740
+ const where = _chunkGO4TR3HBcjs.chainName.call(void 0, out.originChainId);
1115
1741
  if (outcome.kind === "timeout") {
1116
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_TIMEOUT", "The bridge is still processing. Your mint may still complete.");
1742
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_TIMEOUT", "The bridge is still processing. Your mint may still complete.");
1117
1743
  }
1118
1744
  const key = outstandingKey(attempt.config, attempt.payer);
1119
1745
  const { status } = outcome;
1120
1746
  if (status.status !== "success") clearOutstanding(key);
1121
1747
  if (status.status === "refund") {
1122
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_REFUNDED", `Relay could not complete the mint and is refunding your payment. Relay request ${out.requestId}.`);
1748
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_REFUNDED", `Relay could not complete the mint and is refunding your payment. Relay request ${out.requestId}.`);
1123
1749
  }
1124
1750
  if (status.status === "failure") {
1125
1751
  const why = status.failReason ? ` (${status.failReason})` : "";
1126
1752
  const noRefund = status.refundFailReason ? ` No automatic refund was sent. Contact support with Relay request ${out.requestId}.` : "";
1127
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_FAILED", `Relay could not complete the mint paid on ${where}${why}.${noRefund}`);
1753
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_FAILED", `Relay could not complete the mint paid on ${where}${why}.${noRefund}`);
1128
1754
  }
1129
1755
  const fillHash = _nullishCoalesce(status.txHashes[0], () => ( null));
1130
1756
  let tokens = [];
@@ -1132,9 +1758,9 @@ function useMint(options) {
1132
1758
  try {
1133
1759
  const receipt = await client.waitForTransactionReceipt({ hash: fillHash, confirmations: 1, timeout: 6e4 });
1134
1760
  if (receiptOk(receipt.status)) {
1135
- tokens = _chunkOO6QQT3Mcjs.parseMintReceipt.call(void 0, _nullishCoalesce(receipt.logs, () => ( [])), { tokenContract: attempt.tokenContract, recipient: attempt.recipient });
1761
+ tokens = _chunkGO4TR3HBcjs.parseMintReceipt.call(void 0, _nullishCoalesce(receipt.logs, () => ( [])), { tokenContract: attempt.tokenContract, recipient: attempt.recipient });
1136
1762
  }
1137
- } catch (e6) {
1763
+ } catch (e8) {
1138
1764
  }
1139
1765
  assertActive();
1140
1766
  }
@@ -1143,6 +1769,7 @@ function useMint(options) {
1143
1769
  txHash,
1144
1770
  explorerUrl: explorerUrlFor(fillHash ? cfg.chainId : out.originChainId, txHash),
1145
1771
  tokens,
1772
+ requested: attempt.quantity,
1146
1773
  relay: { requestId: out.requestId, originTxHash: out.originTxHash, originChainId: out.originChainId }
1147
1774
  };
1148
1775
  clearOutstanding(key);
@@ -1162,19 +1789,19 @@ function useMint(options) {
1162
1789
  if (!mounted.current || life.controller.signal.aborted || lifeRef.current !== life || attemptRef.current !== attempt) {
1163
1790
  throw new DOMException("Mint attempt cancelled", "AbortError");
1164
1791
  }
1165
- const live = _chunkOO6QQT3Mcjs.getAccount.call(void 0, );
1792
+ const live = _chunkGO4TR3HBcjs.getAccount.call(void 0, );
1166
1793
  if (!live || live.address.toLowerCase() !== attempt.payer.toLowerCase()) {
1167
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("USER_REJECTED", "The connected wallet changed before the transaction was sent.");
1794
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("USER_REJECTED", "The connected wallet changed before the transaction was sent.");
1168
1795
  }
1169
1796
  };
1170
1797
  assertPayer();
1171
1798
  if (account2.chainId !== origin) {
1172
1799
  dispatch({ type: "SWITCHING_CHAIN", attemptId: attempt.attemptId });
1173
- await _chunkOO6QQT3Mcjs.switchToChain.call(void 0, origin);
1800
+ await _chunkGO4TR3HBcjs.switchToChain.call(void 0, origin);
1174
1801
  }
1175
1802
  assertPayer();
1176
1803
  const plan = await adapter.buildPlan(ctx, attempt, walletRead);
1177
- if (plan.approve) throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", "Cross-chain mint supports native-priced drops only.");
1804
+ if (plan.approve) throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", "Cross-chain mint supports native-priced drops only.");
1178
1805
  assertPayer();
1179
1806
  const quote = await getQuote({
1180
1807
  testnet,
@@ -1187,18 +1814,18 @@ function useMint(options) {
1187
1814
  signal: life.controller.signal
1188
1815
  });
1189
1816
  assertPayer();
1190
- const balance = await _chunkOO6QQT3Mcjs.getConnectedBalance.call(void 0, attempt.payer, origin);
1817
+ const balance = await _chunkGO4TR3HBcjs.getConnectedBalance.call(void 0, attempt.payer, origin);
1191
1818
  if (balance < quote.amountIn.value + quote.originGas.value) {
1192
1819
  const s = shortOf(origin);
1193
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("INSUFFICIENT_FUNDS", `Not enough ${s.symbol} on ${s.name}. Pick another network to pay from.`);
1820
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("INSUFFICIENT_FUNDS", `Not enough ${s.symbol} on ${s.name}. Pick another network to pay from.`);
1194
1821
  }
1195
1822
  assertPayer();
1196
1823
  const item = quote.items[0];
1197
1824
  const key = outstandingKey(cfg, attempt.payer);
1198
- const wallet2 = _chunkOO6QQT3Mcjs.getWalletClient.call(void 0, origin);
1825
+ const wallet2 = _chunkGO4TR3HBcjs.getWalletClient.call(void 0, origin);
1199
1826
  assertPayer();
1200
1827
  if (!claimDeposit(key)) {
1201
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("BRIDGE_UNAVAILABLE", "A cross-chain payment for this drop is already in progress. Try again once it finishes.");
1828
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("BRIDGE_UNAVAILABLE", "A cross-chain payment for this drop is already in progress. Try again once it finishes.");
1202
1829
  }
1203
1830
  let out;
1204
1831
  try {
@@ -1210,7 +1837,7 @@ function useMint(options) {
1210
1837
  data: item.data,
1211
1838
  value: item.value,
1212
1839
  ...item.gas !== null && item.gas > 0n ? { gas: item.gas } : {},
1213
- chain: _chunkOO6QQT3Mcjs.getChain.call(void 0, origin)
1840
+ chain: _chunkGO4TR3HBcjs.getChain.call(void 0, origin)
1214
1841
  });
1215
1842
  out = { requestId: quote.requestId, testnet, originChainId: origin, originTxHash: originTxHash2, attempt };
1216
1843
  setOutstanding(key, out);
@@ -1221,10 +1848,10 @@ function useMint(options) {
1221
1848
  autoResumedRef.current.add(key);
1222
1849
  dispatch({ type: "TX_SUBMITTED", attemptId: attempt.attemptId });
1223
1850
  emit("tx-submitted", { state: "confirming", reason: null, txHash: originTxHash, quantity: attempt.quantity, chainId: cfg.chainId });
1224
- const deposit = await _chunkOO6QQT3Mcjs.waitForDeposit.call(void 0, origin, originTxHash);
1851
+ const deposit = await _chunkGO4TR3HBcjs.waitForDeposit.call(void 0, origin, originTxHash);
1225
1852
  if (deposit === "reverted") {
1226
1853
  clearOutstanding(key);
1227
- throw new (0, _chunkOO6QQT3Mcjs.MintError)("TX_REVERTED", `The payment transaction reverted (${originTxHash}).`);
1854
+ throw new (0, _chunkGO4TR3HBcjs.MintError)("TX_REVERTED", `The payment transaction reverted (${originTxHash}).`);
1228
1855
  }
1229
1856
  await finishRelay(attempt, out, life);
1230
1857
  },
@@ -1241,7 +1868,7 @@ function useMint(options) {
1241
1868
  await finishRelay(attempt, out, life);
1242
1869
  } catch (e) {
1243
1870
  if (!mounted.current || life.controller.signal.aborted || lifeRef.current !== life) return;
1244
- const { reason, message } = _chunkOO6QQT3Mcjs.toReason.call(void 0, e);
1871
+ const { reason, message } = _chunkGO4TR3HBcjs.toReason.call(void 0, e);
1245
1872
  dispatch({ type: "ATTEMPT_FAILED", attemptId: attempt.attemptId, reason, message });
1246
1873
  emit("error", { quantity: attempt.quantity, chainId: attempt.chainId });
1247
1874
  } finally {
@@ -1262,31 +1889,31 @@ function useMint(options) {
1262
1889
  return;
1263
1890
  }
1264
1891
  const s = stateRef.current;
1265
- if (!_chunkOO6QQT3Mcjs.canAct.call(void 0, s) || s.attempt !== null) return;
1892
+ if (!_chunkGO4TR3HBcjs.canAct.call(void 0, s) || s.attempt !== null) return;
1266
1893
  if (s.name === "disconnected") {
1267
1894
  if (connectingRef.current) return;
1268
1895
  connectingRef.current = true;
1269
1896
  dispatch({ type: "CONNECT_STARTED" });
1270
1897
  const connectLife = lifeRef.current;
1271
- const active = () => mounted.current && lifeRef.current === connectLife && !_optionalChain([connectLife, 'optionalAccess', _43 => _43.controller, 'access', _44 => _44.signal, 'access', _45 => _45.aborted]);
1898
+ const active = () => mounted.current && lifeRef.current === connectLife && !_optionalChain([connectLife, 'optionalAccess', _61 => _61.controller, 'access', _62 => _62.signal, 'access', _63 => _63.aborted]);
1272
1899
  try {
1273
1900
  await widgetLoadRef.current;
1274
1901
  if (!active()) return;
1275
- const outcome = await _chunkOO6QQT3Mcjs.openConnectModal.call(void 0, );
1902
+ const outcome = await _chunkGO4TR3HBcjs.openConnectModal.call(void 0, );
1276
1903
  if (!active()) return;
1277
1904
  connectingRef.current = false;
1278
1905
  if (outcome === "connected") {
1279
1906
  accountKeyRef.current = null;
1280
- _optionalChain([pushAccountRef, 'access', _46 => _46.current, 'optionalCall', _47 => _47(_chunkOO6QQT3Mcjs.getAccount.call(void 0, ))]);
1907
+ _optionalChain([pushAccountRef, 'access', _64 => _64.current, 'optionalCall', _65 => _65(_chunkGO4TR3HBcjs.getAccount.call(void 0, ))]);
1281
1908
  } else dispatch({ type: "CONNECT_DISMISSED" });
1282
- } catch (e7) {
1909
+ } catch (e9) {
1283
1910
  if (active()) dispatch({ type: "CONNECT_DISMISSED" });
1284
1911
  } finally {
1285
1912
  connectingRef.current = false;
1286
1913
  }
1287
1914
  return;
1288
1915
  }
1289
- const payer = _optionalChain([s, 'access', _48 => _48.account, 'optionalAccess', _49 => _49.address]);
1916
+ const payer = _optionalChain([s, 'access', _66 => _66.account, 'optionalAccess', _67 => _67.address]);
1290
1917
  const out = payer ? getOutstanding(outstandingKey(propsRef.current.config, payer)) : null;
1291
1918
  if (out && lifeRef.current) {
1292
1919
  await resumeOutstanding(out, lifeRef.current);
@@ -1298,7 +1925,7 @@ function useMint(options) {
1298
1925
  if (life2) life2.gen = gen;
1299
1926
  dispatch({ type: "RESET", gen });
1300
1927
  dispatch({ type: "LOAD", gen, kind: "config" });
1301
- if (life2) void readDrop2(life2, gen, propsRef.current.config);
1928
+ if (life2) void readDrop3(life2, gen, propsRef.current.config);
1302
1929
  return;
1303
1930
  }
1304
1931
  if (s.name !== "live") return;
@@ -1307,7 +1934,7 @@ function useMint(options) {
1307
1934
  const life = lifeRef.current;
1308
1935
  if (!account2 || !walletRead || !life) return;
1309
1936
  const cfg = propsRef.current.config;
1310
- const relayRoute = _optionalChain([s, 'access', _50 => _50.route, 'optionalAccess', _51 => _51.kind]) === "relay" ? s.route : null;
1937
+ const relayRoute = _optionalChain([s, 'access', _68 => _68.route, 'optionalAccess', _69 => _69.kind]) === "relay" ? s.route : null;
1311
1938
  const attempt = Object.freeze({
1312
1939
  attemptId: ++attemptIdRef.current,
1313
1940
  config: structuredClone(cfg),
@@ -1326,13 +1953,13 @@ function useMint(options) {
1326
1953
  else await executeAttempt(attempt, walletRead, life, account2);
1327
1954
  } catch (e) {
1328
1955
  if (!mounted.current || life.controller.signal.aborted || lifeRef.current !== life) return;
1329
- const { reason, message } = _chunkOO6QQT3Mcjs.toReason.call(void 0, e);
1956
+ const { reason, message } = _chunkGO4TR3HBcjs.toReason.call(void 0, e);
1330
1957
  dispatch({ type: "ATTEMPT_FAILED", attemptId: attempt.attemptId, reason, message });
1331
1958
  emit("error", { quantity: attempt.quantity, chainId: attempt.chainId });
1332
1959
  } finally {
1333
1960
  attemptRef.current = null;
1334
1961
  }
1335
- }, [dispatch, emit, readDrop2, executeAttempt, executeRelayAttempt, resumeOutstanding, refreshNow]);
1962
+ }, [dispatch, emit, readDrop3, executeAttempt, executeRelayAttempt, resumeOutstanding, refreshNow]);
1336
1963
  const mint = _react.useCallback.call(void 0, () => {
1337
1964
  void runMint();
1338
1965
  }, [runMint]);
@@ -1340,7 +1967,7 @@ function useMint(options) {
1340
1967
  mounted.current = true;
1341
1968
  return () => {
1342
1969
  mounted.current = false;
1343
- _optionalChain([lifeRef, 'access', _52 => _52.current, 'optionalAccess', _53 => _53.controller, 'access', _54 => _54.abort, 'call', _55 => _55()]);
1970
+ _optionalChain([lifeRef, 'access', _70 => _70.current, 'optionalAccess', _71 => _71.controller, 'access', _72 => _72.abort, 'call', _73 => _73()]);
1344
1971
  lifeRef.current = null;
1345
1972
  };
1346
1973
  }, []);
@@ -1353,8 +1980,8 @@ function useMint(options) {
1353
1980
  dispatch({ type: "ACCOUNT_CHANGED", account: a });
1354
1981
  };
1355
1982
  pushAccountRef.current = push;
1356
- push(_chunkOO6QQT3Mcjs.getAccount.call(void 0, ));
1357
- const unsubscribe = _chunkOO6QQT3Mcjs.subscribeAccount.call(void 0, push);
1983
+ push(_chunkGO4TR3HBcjs.getAccount.call(void 0, ));
1984
+ const unsubscribe = _chunkGO4TR3HBcjs.subscribeAccount.call(void 0, push);
1358
1985
  return () => {
1359
1986
  unsubscribe();
1360
1987
  };
@@ -1364,13 +1991,13 @@ function useMint(options) {
1364
1991
  if (isBusy() || recipientRef.current === recipient) return;
1365
1992
  recipientRef.current = recipient;
1366
1993
  accountKeyRef.current = null;
1367
- _optionalChain([pushAccountRef, 'access', _56 => _56.current, 'optionalCall', _57 => _57(_chunkOO6QQT3Mcjs.getAccount.call(void 0, ))]);
1994
+ _optionalChain([pushAccountRef, 'access', _74 => _74.current, 'optionalCall', _75 => _75(_chunkGO4TR3HBcjs.getAccount.call(void 0, ))]);
1368
1995
  }, [recipient, machine.attempt, isBusy]);
1369
- const projectId = _optionalChain([connect, 'optionalAccess', _58 => _58.walletConnectProjectId]);
1996
+ const projectId = _optionalChain([connect, 'optionalAccess', _76 => _76.walletConnectProjectId]);
1370
1997
  const widgetChains = [config.chainId, ...payChainsOf(config, options.crossChain).filter((id) => id !== config.chainId)].join(",");
1371
1998
  _react.useEffect.call(void 0, () => {
1372
1999
  let alive = true;
1373
- const loading = _chunkOO6QQT3Mcjs.loadConnectWidget.call(void 0, { chainIds: widgetChains.split(",").map(Number), ...projectId ? { walletConnectProjectId: projectId } : {} });
2000
+ const loading = _chunkGO4TR3HBcjs.loadConnectWidget.call(void 0, { chainIds: widgetChains.split(",").map(Number), ...projectId ? { walletConnectProjectId: projectId } : {} });
1374
2001
  widgetLoadRef.current = loading;
1375
2002
  loading.then(
1376
2003
  () => {
@@ -1378,7 +2005,7 @@ function useMint(options) {
1378
2005
  },
1379
2006
  (e) => {
1380
2007
  if (!alive) return;
1381
- const { reason, message } = _chunkOO6QQT3Mcjs.toReason.call(void 0, e);
2008
+ const { reason, message } = _chunkGO4TR3HBcjs.toReason.call(void 0, e);
1382
2009
  setWidgetFail({ reason, message });
1383
2010
  }
1384
2011
  );
@@ -1394,10 +2021,10 @@ function useMint(options) {
1394
2021
  pendingQuantityRef.current = null;
1395
2022
  dispatch({ type: "SET_QUANTITY", quantity });
1396
2023
  }
1397
- if (_optionalChain([lifeRef, 'access', _59 => _59.current, 'optionalAccess', _60 => _60.key]) !== configKey) {
2024
+ if (_optionalChain([lifeRef, 'access', _77 => _77.current, 'optionalAccess', _78 => _78.key]) !== configKey) {
1398
2025
  pendingRefreshRef.current = false;
1399
2026
  startLifetime(configKey, config);
1400
- } else if (pendingRefreshRef.current || lifeRef.current.rpcUrl !== _optionalChain([options, 'access', _61 => _61.rpcUrls, 'optionalAccess', _62 => _62[config.chainId]])) {
2027
+ } else if (pendingRefreshRef.current || lifeRef.current.rpcUrl !== _optionalChain([options, 'access', _79 => _79.rpcUrls, 'optionalAccess', _80 => _80[config.chainId]])) {
1401
2028
  pendingRefreshRef.current = false;
1402
2029
  void refreshNow();
1403
2030
  }
@@ -1431,7 +2058,7 @@ function useMint(options) {
1431
2058
  _react.useEffect.call(void 0, () => {
1432
2059
  if (!account || !loadedDrop || isBusy()) return;
1433
2060
  const previous = lastWalletRead.current;
1434
- if (stateRef.current.blocked && _optionalChain([previous, 'optionalAccess', _63 => _63.drop]) === loadedDrop && previous.gen === walletGen && previous.quantity === machine.quantity) return;
2061
+ if (stateRef.current.blocked && _optionalChain([previous, 'optionalAccess', _81 => _81.drop]) === loadedDrop && previous.gen === walletGen && previous.quantity === machine.quantity) return;
1435
2062
  lastWalletRead.current = { drop: loadedDrop, gen: walletGen, quantity: machine.quantity };
1436
2063
  const life = lifeRef.current;
1437
2064
  const drop = stateRef.current.drop;
@@ -1449,10 +2076,10 @@ function useMint(options) {
1449
2076
  drop
1450
2077
  });
1451
2078
  if (!alive || life.controller.signal.aborted || lifeRef.current !== life || life.gen !== readGen) return;
1452
- const ineligible = _optionalChain([read, 'access', _64 => _64.ineligible, 'optionalAccess', _65 => _65.reason]) === "SIMULATION_REVERTED" ? { ...read.ineligible, message: _chunkOO6QQT3Mcjs.friendlyErrorMessage.call(void 0, new (0, _chunkOO6QQT3Mcjs.MintError)("SIMULATION_REVERTED", read.ineligible.message)) } : read.ineligible;
2079
+ const ineligible = _optionalChain([read, 'access', _82 => _82.ineligible, 'optionalAccess', _83 => _83.reason]) === "SIMULATION_REVERTED" ? { ...read.ineligible, message: _chunkGO4TR3HBcjs.friendlyErrorMessage.call(void 0, new (0, _chunkGO4TR3HBcjs.MintError)("SIMULATION_REVERTED", read.ineligible.message)) } : read.ineligible;
1453
2080
  const fullRead = { ...read, ineligible };
1454
2081
  const payChains = payChainsOf(cfg, propsRef.current.crossChain);
1455
- const crossChain = payChains.length > 0 && ineligible === null && (_nullishCoalesce(_optionalChain([adapter, 'access', _66 => _66.supportsRelay, 'optionalCall', _67 => _67(drop)]), () => ( false)));
2082
+ const crossChain = payChains.length > 0 && ineligible === null && (_nullishCoalesce(_optionalChain([adapter, 'access', _84 => _84.supportsRelay, 'optionalCall', _85 => _85(drop)]), () => ( false)));
1456
2083
  const routeChain = routeChainOf(payChains, account.chainId, propsRef.current.payChainId);
1457
2084
  const routePending = crossChain && routeChain !== cfg.chainId && payChains.includes(routeChain);
1458
2085
  dispatch({ type: "WALLET_LOADED", gen: walletGen, read: fullRead, crossChain, routePending });
@@ -1475,7 +2102,7 @@ function useMint(options) {
1475
2102
  let tx;
1476
2103
  try {
1477
2104
  tx = (await adapter.buildPlan(ctxFor(life, cfg), draft, fullRead)).mint;
1478
- } catch (e8) {
2105
+ } catch (e10) {
1479
2106
  if (!alive) return;
1480
2107
  setCrossChainInfo(null);
1481
2108
  if (routePending) dispatch({ type: "ROUTE_LOADED", gen: walletGen, route: { kind: "direct", chainId: cfg.chainId }, short: null });
@@ -1497,11 +2124,11 @@ function useMint(options) {
1497
2124
  if (routeChain !== account.chainId) {
1498
2125
  route = relay;
1499
2126
  } else {
1500
- const balance = await _chunkOO6QQT3Mcjs.getConnectedBalance.call(void 0, account.address, routeChain);
2127
+ const balance = await _chunkGO4TR3HBcjs.getConnectedBalance.call(void 0, account.address, routeChain);
1501
2128
  if (balance >= quote.amountIn.value + quote.originGas.value) route = relay;
1502
2129
  else short = shortOf(routeChain);
1503
2130
  }
1504
- } catch (e9) {
2131
+ } catch (e11) {
1505
2132
  }
1506
2133
  if (!alive || life.controller.signal.aborted || lifeRef.current !== life) return;
1507
2134
  dispatch({ type: "ROUTE_LOADED", gen: walletGen, route: short ? null : route, short });
@@ -1523,9 +2150,9 @@ function useMint(options) {
1523
2150
  const state = stateRef.current;
1524
2151
  if (!propChanged && state.account && !state.walletRead) return;
1525
2152
  const event = { type: "SET_QUANTITY", quantity: quantityProp };
1526
- const clamped = _chunkOO6QQT3Mcjs.reducer.call(void 0, state, event).quantity;
2153
+ const clamped = _chunkGO4TR3HBcjs.reducer.call(void 0, state, event).quantity;
1527
2154
  if (clamped !== state.quantity) dispatch(event);
1528
- if (clamped !== quantityProp) _optionalChain([propsRef, 'access', _68 => _68.current, 'access', _69 => _69.onQuantityChange, 'optionalCall', _70 => _70(clamped)]);
2155
+ if (clamped !== quantityProp) _optionalChain([propsRef, 'access', _86 => _86.current, 'access', _87 => _87.onQuantityChange, 'optionalCall', _88 => _88(clamped)]);
1529
2156
  }, [quantityProp, machine.quantity, machine.drop, machine.walletRead, machine.attempt, dispatch, isBusy]);
1530
2157
  _react.useEffect.call(void 0, () => {
1531
2158
  const timer = setInterval(() => {
@@ -1541,13 +2168,13 @@ function useMint(options) {
1541
2168
  document.removeEventListener("visibilitychange", onVisible);
1542
2169
  };
1543
2170
  }, [refreshNow]);
1544
- const boundary = machine.drop ? [machine.drop.startTime, machine.drop.endTime].some((t) => t !== null && t > machine.now) : false;
2171
+ const boundary = machine.drop ? [machine.drop.startTime, machine.drop.endTime, _nullishCoalesce(machine.drop.phaseEndsAt, () => ( null))].some((t) => t !== null && t > machine.now) : false;
1545
2172
  _react.useEffect.call(void 0, () => {
1546
2173
  if (!boundary) return;
1547
2174
  const timer = setInterval(() => {
1548
2175
  const s = stateRef.current;
1549
2176
  const now = nowSec();
1550
- const crossed = s.drop && [s.drop.startTime, s.drop.endTime].some((t) => t !== null && t > s.now && t <= now);
2177
+ const crossed = s.drop && [s.drop.startTime, s.drop.endTime, _nullishCoalesce(s.drop.phaseEndsAt, () => ( null))].some((t) => t !== null && t > s.now && t <= now);
1551
2178
  dispatch({ type: "TICK", now });
1552
2179
  if (crossed) void refreshNow();
1553
2180
  }, TICK_MS);
@@ -1558,12 +2185,12 @@ function useMint(options) {
1558
2185
  const name = widgetFail ? isUnsupported(widgetFail.reason) ? "unsupported" : "error" : machine.name;
1559
2186
  if (prevName.current === name) return;
1560
2187
  prevName.current = name;
1561
- emit("state", { state: name, reason: _nullishCoalesce(_optionalChain([widgetFail, 'optionalAccess', _71 => _71.reason]), () => ( machine.reason)) });
2188
+ emit("state", { state: name, reason: _nullishCoalesce(_optionalChain([widgetFail, 'optionalAccess', _89 => _89.reason]), () => ( machine.reason)) });
1562
2189
  }, [machine.name, machine.reason, widgetFail, emit]);
1563
2190
  const setQuantity = _react.useCallback.call(void 0,
1564
2191
  (next) => {
1565
2192
  const s = stateRef.current;
1566
- const max = _nullishCoalesce(_chunkOO6QQT3Mcjs.selectMaxQuantity.call(void 0, s), () => ( 65535));
2193
+ const max = _nullishCoalesce(_chunkGO4TR3HBcjs.selectMaxQuantity.call(void 0, s), () => ( 65535));
1567
2194
  const clamped = Math.max(1, Math.min(Math.floor(Number.isNaN(next) ? 1 : next), max));
1568
2195
  const handler = propsRef.current.onQuantityChange;
1569
2196
  if (handler) {
@@ -1598,16 +2225,16 @@ function useMint(options) {
1598
2225
  wallet,
1599
2226
  quantity: machine.quantity,
1600
2227
  setQuantity,
1601
- maxQuantity: _chunkOO6QQT3Mcjs.selectMaxQuantity.call(void 0, machine),
1602
- total: _chunkOO6QQT3Mcjs.selectTotal.call(void 0, machine),
2228
+ maxQuantity: _chunkGO4TR3HBcjs.selectMaxQuantity.call(void 0, machine),
2229
+ total: _chunkGO4TR3HBcjs.selectTotal.call(void 0, machine),
1603
2230
  mint,
1604
2231
  result: machine.result,
1605
2232
  refresh,
1606
2233
  // An attempt claimed by a click is not clickable, even while the reducer still reads 'live'.
1607
- canAct: _chunkOO6QQT3Mcjs.canAct.call(void 0, { ...machine, name: effective.name }) && machine.attempt === null,
2234
+ canAct: _chunkGO4TR3HBcjs.canAct.call(void 0, { ...machine, name: effective.name }) && machine.attempt === null,
1608
2235
  // Short on the wallet chain is neither route: nothing can be paid until the collector picks another chain.
1609
2236
  route: _nullishCoalesce(machine.route, () => ( (machine.walletRead && machine.drop && !machine.routePending && machine.short === null ? { kind: "direct", chainId: machine.drop.chainId } : null))),
1610
- crossChain: machine.crossChain && machine.account && _optionalChain([crossChainInfo, 'optionalAccess', _72 => _72.gen]) === machine.walletGen ? crossChainInfo.info : null
2237
+ crossChain: machine.crossChain && machine.account && _optionalChain([crossChainInfo, 'optionalAccess', _90 => _90.gen]) === machine.walletGen ? crossChainInfo.info : null
1611
2238
  };
1612
2239
  }
1613
2240
 
@@ -1617,13 +2244,13 @@ function useMint(options) {
1617
2244
  var PICKER_REFRESH_MS = 2e4;
1618
2245
  var PICKER_DEBOUNCE_MS = 500;
1619
2246
  var RELAY_REASONS = /* @__PURE__ */ new Set(["BRIDGE_UNAVAILABLE", "BRIDGE_TIMEOUT", "BRIDGE_REFUNDED", "BRIDGE_FAILED"]);
1620
- var money2 = (value, chainId) => {
1621
- const c = _chunkOO6QQT3Mcjs.getChain.call(void 0, chainId).nativeCurrency;
2247
+ var money3 = (value, chainId) => {
2248
+ const c = _chunkGO4TR3HBcjs.getChain.call(void 0, chainId).nativeCurrency;
1622
2249
  return { value, decimals: c.decimals, symbol: c.symbol, formatted: _viem.formatUnits.call(void 0, value, c.decimals) };
1623
2250
  };
1624
2251
  function usePayOptions(mint, onSelect) {
1625
2252
  const info = mint.crossChain;
1626
- const current = _nullishCoalesce(_optionalChain([mint, 'access', _73 => _73.wallet, 'optionalAccess', _74 => _74.chainId]), () => ( null));
2253
+ const current = _nullishCoalesce(_optionalChain([mint, 'access', _91 => _91.wallet, 'optionalAccess', _92 => _92.chainId]), () => ( null));
1627
2254
  const [quotes, setQuotes] = _react.useState.call(void 0, {});
1628
2255
  const [balance, setBalance] = _react.useState.call(void 0, null);
1629
2256
  const [tick, setTick] = _react.useState.call(void 0, 0);
@@ -1648,7 +2275,7 @@ function usePayOptions(mint, onSelect) {
1648
2275
  if (!controller.signal.aborted) setQuotes((prev) => ({ ...prev, [chainId]: { relayFee: q.relayFee, amountIn: q.amountIn } }));
1649
2276
  },
1650
2277
  (e) => {
1651
- if (controller.signal.aborted || _optionalChain([e, 'optionalAccess', _75 => _75.reason]) === "RATE_LIMITED") return;
2278
+ if (controller.signal.aborted || _optionalChain([e, 'optionalAccess', _93 => _93.reason]) === "RATE_LIMITED") return;
1652
2279
  setQuotes((prev) => ({ ...prev, [chainId]: "failed" }));
1653
2280
  }
1654
2281
  );
@@ -1662,7 +2289,7 @@ function usePayOptions(mint, onSelect) {
1662
2289
  _react.useEffect.call(void 0, () => {
1663
2290
  if (!info || current === null || !mint.wallet) return;
1664
2291
  let alive = true;
1665
- _chunkOO6QQT3Mcjs.getConnectedBalance.call(void 0, mint.wallet.address, current).then(
2292
+ _chunkGO4TR3HBcjs.getConnectedBalance.call(void 0, mint.wallet.address, current).then(
1666
2293
  (value) => {
1667
2294
  if (alive) setBalance({ chainId: current, value });
1668
2295
  },
@@ -1673,12 +2300,12 @@ function usePayOptions(mint, onSelect) {
1673
2300
  return () => {
1674
2301
  alive = false;
1675
2302
  };
1676
- }, [current, _optionalChain([mint, 'access', _76 => _76.wallet, 'optionalAccess', _77 => _77.address]), key, tick]);
2303
+ }, [current, _optionalChain([mint, 'access', _94 => _94.wallet, 'optionalAccess', _95 => _95.address]), key, tick]);
1677
2304
  const select = _react.useCallback.call(void 0,
1678
2305
  (chainId) => {
1679
- _chunkOO6QQT3Mcjs.switchToChain.call(void 0, chainId).then(
1680
- () => _optionalChain([onSelect, 'optionalCall', _78 => _78(chainId, null)]),
1681
- (e) => _optionalChain([onSelect, 'optionalCall', _79 => _79(chainId, e)])
2306
+ _chunkGO4TR3HBcjs.switchToChain.call(void 0, chainId).then(
2307
+ () => _optionalChain([onSelect, 'optionalCall', _96 => _96(chainId, null)]),
2308
+ (e) => _optionalChain([onSelect, 'optionalCall', _97 => _97(chainId, e)])
1682
2309
  );
1683
2310
  },
1684
2311
  [onSelect]
@@ -1690,12 +2317,12 @@ function usePayOptions(mint, onSelect) {
1690
2317
  const quoted = q && q !== "failed" ? q : null;
1691
2318
  return {
1692
2319
  chainId,
1693
- name: _chunkOO6QQT3Mcjs.chainName.call(void 0, chainId),
2320
+ name: _chunkGO4TR3HBcjs.chainName.call(void 0, chainId),
1694
2321
  selected: chainId === current,
1695
2322
  isDropChain,
1696
- relayFee: isDropChain ? null : _nullishCoalesce(_optionalChain([quoted, 'optionalAccess', _80 => _80.relayFee]), () => ( null)),
1697
- amountIn: isDropChain ? null : _nullishCoalesce(_optionalChain([quoted, 'optionalAccess', _81 => _81.amountIn]), () => ( null)),
1698
- balance: balance && balance.chainId === chainId && chainId === current ? money2(balance.value, chainId) : null,
2323
+ relayFee: isDropChain ? null : _nullishCoalesce(_optionalChain([quoted, 'optionalAccess', _98 => _98.relayFee]), () => ( null)),
2324
+ amountIn: isDropChain ? null : _nullishCoalesce(_optionalChain([quoted, 'optionalAccess', _99 => _99.amountIn]), () => ( null)),
2325
+ balance: balance && balance.chainId === chainId && chainId === current ? money3(balance.value, chainId) : null,
1699
2326
  loading: !isDropChain && q === void 0,
1700
2327
  select: () => select(chainId)
1701
2328
  };
@@ -1736,14 +2363,14 @@ function PayWithPicker(props) {
1736
2363
  // src/react/MintButton.ts
1737
2364
 
1738
2365
  function defaultLabel(m) {
1739
- const symbol = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([m, 'access', _82 => _82.total, 'optionalAccess', _83 => _83.erc20, 'optionalAccess', _84 => _84.symbol]), () => ( _optionalChain([m, 'access', _85 => _85.total, 'optionalAccess', _86 => _86.native, 'access', _87 => _87.symbol]))), () => ( _optionalChain([m, 'access', _88 => _88.drop, 'optionalAccess', _89 => _89.unitPrice, 'access', _90 => _90.symbol]))), () => ( ""));
2366
+ const symbol = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([m, 'access', _100 => _100.total, 'optionalAccess', _101 => _101.erc20, 'optionalAccess', _102 => _102.symbol]), () => ( _optionalChain([m, 'access', _103 => _103.total, 'optionalAccess', _104 => _104.native, 'access', _105 => _105.symbol]))), () => ( _optionalChain([m, 'access', _106 => _106.drop, 'optionalAccess', _107 => _107.unitPrice, 'access', _108 => _108.symbol]))), () => ( ""));
1740
2367
  switch (m.state) {
1741
2368
  case "loading":
1742
2369
  return "Loading\u2026";
1743
2370
  case "unsupported":
1744
2371
  return "Unavailable";
1745
2372
  case "upcoming": {
1746
- const t = _optionalChain([m, 'access', _91 => _91.drop, 'optionalAccess', _92 => _92.startTime]);
2373
+ const t = _optionalChain([m, 'access', _109 => _109.drop, 'optionalAccess', _110 => _110.startTime]);
1747
2374
  return `Starts ${t ? new Date(t * 1e3).toLocaleString() : "soon"}`;
1748
2375
  }
1749
2376
  case "ended":
@@ -1756,8 +2383,8 @@ function defaultLabel(m) {
1756
2383
  return "Connecting\u2026";
1757
2384
  case "live": {
1758
2385
  const route = m.route;
1759
- if (_optionalChain([route, 'optionalAccess', _93 => _93.kind]) === "relay") {
1760
- return `Mint \xB7 ${route.amountIn.formatted} ${route.amountIn.symbol} on ${_chunkOO6QQT3Mcjs.chainName.call(void 0, route.originChainId)}`;
2386
+ if (_optionalChain([route, 'optionalAccess', _111 => _111.kind]) === "relay") {
2387
+ return `Mint \xB7 ${route.amountIn.formatted} ${route.amountIn.symbol} on ${_chunkGO4TR3HBcjs.chainName.call(void 0, route.originChainId)}`;
1761
2388
  }
1762
2389
  const total = m.total;
1763
2390
  if (!total) return "Mint";
@@ -1767,8 +2394,8 @@ function defaultLabel(m) {
1767
2394
  case "ineligible":
1768
2395
  return "Not eligible";
1769
2396
  case "insufficient-funds": {
1770
- const erc20 = _optionalChain([m, 'access', _94 => _94.total, 'optionalAccess', _95 => _95.erc20]);
1771
- const shortage = erc20 && m.message === `Not enough ${erc20.symbol} to cover the mint.` ? erc20.symbol : _nullishCoalesce(_optionalChain([m, 'access', _96 => _96.total, 'optionalAccess', _97 => _97.native, 'access', _98 => _98.symbol]), () => ( symbol));
2397
+ const erc20 = _optionalChain([m, 'access', _112 => _112.total, 'optionalAccess', _113 => _113.erc20]);
2398
+ const shortage = erc20 && m.message === `Not enough ${erc20.symbol} to cover the mint.` ? erc20.symbol : _nullishCoalesce(_optionalChain([m, 'access', _114 => _114.total, 'optionalAccess', _115 => _115.native, 'access', _116 => _116.symbol]), () => ( symbol));
1772
2399
  return `Insufficient ${shortage}`.trimEnd();
1773
2400
  }
1774
2401
  case "switching-chain":
@@ -1789,7 +2416,7 @@ function MintButton(props) {
1789
2416
  const { className, labels, children, ...options } = props;
1790
2417
  const m = useMint(options);
1791
2418
  if (typeof children === "function") return children(m);
1792
- const label = _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _99 => _99[m.state]]), () => ( defaultLabel(m)));
2419
+ const label = _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _117 => _117[m.state]]), () => ( defaultLabel(m)));
1793
2420
  return _react.createElement.call(void 0,
1794
2421
  "button",
1795
2422
  {
@@ -1806,7 +2433,7 @@ function MintButton(props) {
1806
2433
  }
1807
2434
 
1808
2435
  // src/index.ts
1809
- var VERSION = "0.3.0";
2436
+ var VERSION = "0.4.0";
1810
2437
 
1811
2438
 
1812
2439
 
@@ -1819,5 +2446,5 @@ var VERSION = "0.3.0";
1819
2446
 
1820
2447
 
1821
2448
 
1822
- exports.CLICKABLE_STATES = _chunkOO6QQT3Mcjs.CLICKABLE_STATES; exports.MAX_QUANTITY = _chunkOO6QQT3Mcjs.MAX_QUANTITY; exports.MINT_STATES = _chunkOO6QQT3Mcjs.MINT_STATES; exports.MintButton = MintButton; exports.MintError = _chunkOO6QQT3Mcjs.MintError; exports.PayWithPicker = PayWithPicker; exports.REASON_CODES = _chunkOO6QQT3Mcjs.REASON_CODES; exports.VERSION = VERSION; exports.isMintError = _chunkOO6QQT3Mcjs.isMintError; exports.useMint = useMint; exports.usePayOptions = usePayOptions;
2449
+ exports.CLICKABLE_STATES = _chunkGO4TR3HBcjs.CLICKABLE_STATES; exports.MAX_QUANTITY = _chunkGO4TR3HBcjs.MAX_QUANTITY; exports.MINT_STATES = _chunkGO4TR3HBcjs.MINT_STATES; exports.MintButton = MintButton; exports.MintError = _chunkGO4TR3HBcjs.MintError; exports.PayWithPicker = PayWithPicker; exports.REASON_CODES = _chunkGO4TR3HBcjs.REASON_CODES; exports.VERSION = VERSION; exports.isMintError = _chunkGO4TR3HBcjs.isMintError; exports.useMint = useMint; exports.usePayOptions = usePayOptions;
1823
2450
  //# sourceMappingURL=index.cjs.map