@unlink-xyz/react 0.1.0 → 0.1.3-canary.01ac52d

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.js CHANGED
@@ -5292,6 +5292,12 @@ var ReconcileError = class extends CoreError {
5292
5292
  this.status = status;
5293
5293
  }
5294
5294
  };
5295
+ var AdapterError = class extends CoreError {
5296
+ constructor(message) {
5297
+ super(message);
5298
+ this.name = "AdapterError";
5299
+ }
5300
+ };
5295
5301
  init_process();
5296
5302
  init_buffer();
5297
5303
  var RESERVED_PREFIXES = [
@@ -9036,9 +9042,9 @@ function genBech32(encoding) {
9036
9042
  }
9037
9043
  var bech32m = /* @__PURE__ */ genBech32("bech32m");
9038
9044
  var VERSION = 1;
9039
- var LIMIT = 127;
9045
+ var LIMIT = 130;
9040
9046
  var ALL_CHAINS = "ffffffffffffffff";
9041
- var PREFIX = "0zk";
9047
+ var PREFIX = "unlink";
9042
9048
  var SALT = new TextEncoder().encode("unlink");
9043
9049
  function xorWithSalt(hex2) {
9044
9050
  const bytes2 = Hex.toBytes(hex2);
@@ -9156,7 +9162,7 @@ function parseZkAddress(value) {
9156
9162
  };
9157
9163
  } catch (err) {
9158
9164
  throw new ValidationError(
9159
- `Invalid ZK address (expected 0zk1... format): ${err instanceof Error ? err.message : "unknown error"}`
9165
+ `Invalid ZK address (expected unlink1... format): ${err instanceof Error ? err.message : "unknown error"}`
9160
9166
  );
9161
9167
  }
9162
9168
  }
@@ -9444,7 +9450,12 @@ var VALID_STATUSES = [
9444
9450
  "failed",
9445
9451
  "dead"
9446
9452
  ];
9447
- var VALID_KINDS = ["deposit", "transfer", "withdraw"];
9453
+ var VALID_KINDS = [
9454
+ "deposit",
9455
+ "transfer",
9456
+ "withdraw",
9457
+ "adapter"
9458
+ ];
9448
9459
  function assertStatus(status) {
9449
9460
  if (!VALID_STATUSES.includes(status)) {
9450
9461
  throw new CoreError(`invalid job status: ${status}`);
@@ -9524,6 +9535,12 @@ function validateDepositRecord(job) {
9524
9535
  }
9525
9536
  }
9526
9537
  }
9538
+ function validateAdapterRecord(job) {
9539
+ ensureAddress("adapter address", job.adapterAddress);
9540
+ if (!job.adapterCalldata) {
9541
+ throw new CoreError("adapterCalldata is required for adapter record");
9542
+ }
9543
+ }
9527
9544
  function validateJob(job) {
9528
9545
  if (!job.relayId) {
9529
9546
  throw new CoreError("relayId is required");
@@ -9543,6 +9560,9 @@ function validateJob(job) {
9543
9560
  validateDepositRecord(job);
9544
9561
  } else {
9545
9562
  validatePoolTransactionRecord(job);
9563
+ if (job.kind === "adapter") {
9564
+ validateAdapterRecord(job);
9565
+ }
9546
9566
  }
9547
9567
  }
9548
9568
  function buildJobKey(relayId) {
@@ -10047,6 +10067,9 @@ function randomBigint(bytes2 = 32) {
10047
10067
  function randomHex(bytes2) {
10048
10068
  return `0x${randomBigint(bytes2).toString(16).padStart(bytes2 * 2, "0")}`;
10049
10069
  }
10070
+ function generateRelayId(prefix) {
10071
+ return globalThis.crypto?.randomUUID?.() ?? `${prefix}-${randomHex(16).slice(2)}`;
10072
+ }
10050
10073
  function normalizeAddress(value) {
10051
10074
  return ensureAddress("address", value);
10052
10075
  }
@@ -35848,63 +35871,79 @@ var Runtime = {
35848
35871
  }
35849
35872
  };
35850
35873
  var CONFIG_URL = "https://config.unlink.xyz/networks.json";
35851
- function parseRequiredString(env22, field, value) {
35874
+ function parseRequiredString(chain2, field, value) {
35852
35875
  if (typeof value !== "string" || value.trim().length === 0) {
35853
35876
  throw new InitializationError(
35854
- `Invalid SDK config for ${env22}: ${field} must be a non-empty string`
35877
+ `Invalid SDK config for ${chain2}: ${field} must be a non-empty string`
35855
35878
  );
35856
35879
  }
35857
35880
  return value.trim();
35858
35881
  }
35859
- function parseOptionalString(env22, field, value) {
35882
+ function parseOptionalString(chain2, field, value) {
35860
35883
  if (value === void 0) return void 0;
35861
35884
  if (typeof value !== "string" || value.trim().length === 0) {
35862
35885
  throw new InitializationError(
35863
- `Invalid SDK config for ${env22}: ${field} must be a non-empty string when provided`
35886
+ `Invalid SDK config for ${chain2}: ${field} must be a non-empty string when provided`
35864
35887
  );
35865
35888
  }
35866
35889
  return value.trim();
35867
35890
  }
35868
- function parseEnvironmentConfig(env22, value) {
35891
+ function parseRequiredChainId(chain2, value) {
35892
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
35893
+ throw new InitializationError(
35894
+ `Invalid SDK config for ${chain2}: chainId must be a positive integer`
35895
+ );
35896
+ }
35897
+ return value;
35898
+ }
35899
+ function parseChainConfig(chain2, value) {
35869
35900
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
35870
35901
  throw new InitializationError(
35871
- `Invalid SDK config for ${env22}: expected object`
35902
+ `Invalid SDK config for ${chain2}: expected object`
35872
35903
  );
35873
35904
  }
35874
35905
  const raw = value;
35906
+ const chainId = parseRequiredChainId(chain2, raw.chainId);
35875
35907
  const gatewayUrl = parseRequiredString(
35876
- env22,
35908
+ chain2,
35877
35909
  "gatewayUrl",
35878
35910
  raw.gatewayUrl
35879
35911
  ).replace(/\/+$/, "");
35880
- const poolAddress = parseRequiredString(env22, "poolAddress", raw.poolAddress);
35912
+ const poolAddress = parseRequiredString(
35913
+ chain2,
35914
+ "poolAddress",
35915
+ raw.poolAddress
35916
+ );
35881
35917
  const artifactVersion = parseRequiredString(
35882
- env22,
35918
+ chain2,
35883
35919
  "artifactVersion",
35884
35920
  raw.artifactVersion
35885
35921
  ).replace(/^\/+|\/+$/g, "");
35886
35922
  const artifactBaseUrl = parseOptionalString(
35887
- env22,
35923
+ chain2,
35888
35924
  "artifactBaseUrl",
35889
35925
  raw.artifactBaseUrl
35890
35926
  )?.replace(/\/+$/, "");
35891
35927
  return {
35928
+ chainId,
35892
35929
  gatewayUrl,
35893
35930
  poolAddress,
35894
35931
  artifactVersion,
35895
35932
  ...artifactBaseUrl !== void 0 ? { artifactBaseUrl } : { artifactBaseUrl: DEFAULT_ARTIFACT_BASE_URL }
35896
35933
  };
35897
35934
  }
35898
- async function fetchEnvironmentConfig(env22) {
35935
+ async function fetchChainConfig(chain2) {
35899
35936
  const res = await fetch(CONFIG_URL);
35900
35937
  if (!res.ok) {
35901
35938
  throw new InitializationError(`Failed to fetch SDK config: ${res.status}`);
35902
35939
  }
35903
35940
  const config22 = await res.json();
35904
- if (!config22[env22]) {
35905
- throw new InitializationError(`Unknown environment: ${env22}`);
35941
+ if (!config22[chain2]) {
35942
+ throw new InitializationError(
35943
+ `Unknown chain: "${chain2}". Supported chains: ${Object.keys(config22).join(", ")}`
35944
+ );
35906
35945
  }
35907
- return parseEnvironmentConfig(env22, config22[env22]);
35946
+ return parseChainConfig(chain2, config22[chain2]);
35908
35947
  }
35909
35948
  function createServiceConfig(gatewayUrl) {
35910
35949
  const baseUrl = gatewayUrl.replace(/\/+$/, "");
@@ -36037,9 +36076,6 @@ function buildDepositCalldata(depositor, processedNotes) {
36037
36076
  }))
36038
36077
  ]);
36039
36078
  }
36040
- function generateRelayId(prefix) {
36041
- return globalThis.crypto?.randomUUID?.() ?? `${prefix}-${Date.now().toString(16)}`;
36042
- }
36043
36079
  async function deposit(store, req) {
36044
36080
  if (!req.notes?.length) {
36045
36081
  throw new ValidationError("At least one note is required for deposit");
@@ -53692,6 +53728,28 @@ function computeBoundParamsHash(chainId, poolAddress, adapterDataHash = 0n) {
53692
53728
  );
53693
53729
  return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;
53694
53730
  }
53731
+ function computeAdapterDataHash(params) {
53732
+ const coder = AbiCoder.defaultAbiCoder();
53733
+ const encoded = coder.encode(
53734
+ [
53735
+ "tuple(address to, bytes data, uint256 value)[]",
53736
+ "tuple(uint256 npk, uint256 random, address token, uint256 minAmount)[]",
53737
+ "address[]",
53738
+ "uint256",
53739
+ "uint256",
53740
+ "uint256"
53741
+ ],
53742
+ [
53743
+ params.calls,
53744
+ params.reshields,
53745
+ params.inputTokens,
53746
+ params.nonce,
53747
+ params.deadline,
53748
+ BigInt(params.chainId)
53749
+ ]
53750
+ );
53751
+ return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;
53752
+ }
53695
53753
  async function buildSingleTransactionProof(store, account, signer, chainId, poolAddress, tx, trees, baseIndex, opts) {
53696
53754
  if (!tx.inputs?.length)
53697
53755
  throw new ValidationError("at least one input note is required");
@@ -53873,7 +53931,7 @@ async function transact(store, req, opts) {
53873
53931
  ciphertexts: r2.ciphertexts
53874
53932
  }))
53875
53933
  ]);
53876
- const relayId = globalThis.crypto?.randomUUID?.() ?? `tx-${Date.now().toString(16)}`;
53934
+ const relayId = generateRelayId("tx");
53877
53935
  const hasAnyWithdrawal = results.some((r2) => r2.withdrawal.amount > 0n);
53878
53936
  const historyKind = hasAnyWithdrawal ? "Withdraw" : "Send";
53879
53937
  const deltasByToken = /* @__PURE__ */ new Map();
@@ -53960,11 +54018,13 @@ async function transact(store, req, opts) {
53960
54018
  throw new CoreError("broadcaster relay timed out");
53961
54019
  }
53962
54020
  }
53963
- await store.putJob({
53964
- ...job,
53965
- status: "broadcasting",
53966
- txHash
53967
- });
54021
+ if (opts.persistJob !== false) {
54022
+ await store.putJob({
54023
+ ...job,
54024
+ status: "broadcasting",
54025
+ txHash
54026
+ });
54027
+ }
53968
54028
  const transactionResults = results.map((r2) => ({
53969
54029
  proof: r2.proof,
53970
54030
  witnesses: r2.witnesses,
@@ -53979,7 +54039,7 @@ async function transact(store, req, opts) {
53979
54039
  }
53980
54040
  async function syncTransact(store, relayId, opts) {
53981
54041
  const record = await store.getJob(relayId);
53982
- if (!record || record.kind !== "transfer" && record.kind !== "withdraw")
54042
+ if (!record || record.kind !== "transfer" && record.kind !== "withdraw" && record.kind !== "adapter")
53983
54043
  throw new CoreError(`unknown pool transaction relay ${relayId}`);
53984
54044
  const job = record;
53985
54045
  const serviceConfig = createServiceConfig(opts.gatewayUrl);
@@ -54083,6 +54143,70 @@ async function syncTransact(store, relayId, opts) {
54083
54143
  }
54084
54144
  init_process();
54085
54145
  init_buffer();
54146
+ var ADAPTER_EXECUTE_ABI = [
54147
+ "function execute(bytes _transactData, (address to, bytes data, uint256 value)[] _calls, (uint256 npk, uint256 random, address token, uint256 minAmount)[] _reshields, address[] _inputTokens, uint256 _nonce, uint256 _deadline)"
54148
+ ];
54149
+ var adapterInterface = new Interface(ADAPTER_EXECUTE_ABI);
54150
+ var approveInterface = new Interface([
54151
+ "function approve(address spender, uint256 amount)"
54152
+ ]);
54153
+ var HEX_DATA_REGEX = /^0x[0-9a-fA-F]*$/;
54154
+ function ensureNonNegative(label, value) {
54155
+ if (value < 0n) {
54156
+ throw new AdapterError(`${label} must be non-negative`);
54157
+ }
54158
+ return value;
54159
+ }
54160
+ function ensureHexData(label, value) {
54161
+ if (typeof value !== "string" || !HEX_DATA_REGEX.test(value) || value.length % 2 !== 0) {
54162
+ throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);
54163
+ }
54164
+ return value;
54165
+ }
54166
+ function normalizeCall(call, index) {
54167
+ const to = ensureAddress(`calls[${index}].to`, call.to);
54168
+ const data = ensureHexData(`calls[${index}].data`, call.data);
54169
+ const value = ensureNonNegative(`calls[${index}].value`, call.value);
54170
+ return { to, data, value };
54171
+ }
54172
+ function normalizeReshield(reshield, index) {
54173
+ const token = ensureAddress(`reshields[${index}].token`, reshield.token);
54174
+ const npk = ensureNonNegative(`reshields[${index}].npk`, reshield.npk);
54175
+ const random = ensureNonNegative(
54176
+ `reshields[${index}].random`,
54177
+ reshield.random
54178
+ );
54179
+ const minAmount = ensureNonNegative(
54180
+ `reshields[${index}].minAmount`,
54181
+ reshield.minAmount
54182
+ );
54183
+ return { npk, random, token, minAmount };
54184
+ }
54185
+ function encodeAdapterExecute(params) {
54186
+ const transactCalldata = ensureHexData(
54187
+ "transactCalldata",
54188
+ params.transactCalldata
54189
+ );
54190
+ const calls = params.calls.map((call, i) => normalizeCall(call, i));
54191
+ const reshields = params.reshields.map(
54192
+ (reshield, i) => normalizeReshield(reshield, i)
54193
+ );
54194
+ const inputTokens = params.inputTokens.map(
54195
+ (token, i) => ensureAddress(`inputTokens[${i}]`, token)
54196
+ );
54197
+ const nonce = ensureNonNegative("nonce", params.nonce);
54198
+ const deadline = ensureNonNegative("deadline", params.deadline);
54199
+ return adapterInterface.encodeFunctionData("execute", [
54200
+ transactCalldata,
54201
+ calls,
54202
+ reshields,
54203
+ inputTokens,
54204
+ nonce,
54205
+ deadline
54206
+ ]);
54207
+ }
54208
+ init_process();
54209
+ init_buffer();
54086
54210
  init_process();
54087
54211
  init_buffer();
54088
54212
  var MAX_CIRCUIT_INPUTS = Math.max(
@@ -55447,6 +55571,239 @@ function createSeedService(deps) {
55447
55571
  }
55448
55572
  init_process();
55449
55573
  init_buffer();
55574
+ var DEFAULT_DEADLINE_WINDOW_SECONDS = 600n;
55575
+ var HEX_DATA_REGEX2 = /^0x[0-9a-fA-F]*$/;
55576
+ function ensureHexData2(label, value) {
55577
+ if (typeof value !== "string" || !HEX_DATA_REGEX2.test(value) || value.length % 2 !== 0) {
55578
+ throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);
55579
+ }
55580
+ return value;
55581
+ }
55582
+ function normalizeCall2(call, index) {
55583
+ const to = ensureAddress(`calls[${index}].to`, call.to);
55584
+ const data = ensureHexData2(`calls[${index}].data`, call.data);
55585
+ if (call.value < 0n) {
55586
+ throw new AdapterError(`calls[${index}].value must be non-negative`);
55587
+ }
55588
+ return {
55589
+ to,
55590
+ data,
55591
+ value: call.value
55592
+ };
55593
+ }
55594
+ function normalizeInputSpec(input, index) {
55595
+ const token = ensureAddress(`inputs[${index}].token`, input.token);
55596
+ if (input.amount <= 0n) {
55597
+ throw new AdapterError(`inputs[${index}].amount must be greater than zero`);
55598
+ }
55599
+ return {
55600
+ token,
55601
+ amount: input.amount
55602
+ };
55603
+ }
55604
+ function normalizeReshieldSpec(reshield, index) {
55605
+ const token = ensureAddress(`reshields[${index}].token`, reshield.token);
55606
+ if (reshield.minAmount < 0n) {
55607
+ throw new AdapterError(
55608
+ `reshields[${index}].minAmount must be non-negative`
55609
+ );
55610
+ }
55611
+ return {
55612
+ token,
55613
+ minAmount: reshield.minAmount
55614
+ };
55615
+ }
55616
+ function randomFieldElement(randomBigintFn) {
55617
+ const value = randomBigintFn() % SNARK_SCALAR_FIELD;
55618
+ return value < 0n ? value + SNARK_SCALAR_FIELD : value;
55619
+ }
55620
+ function createAdapterService(deps) {
55621
+ const planWithdrawalsImpl = deps.planWithdrawalsFn ?? planWithdrawals;
55622
+ const transactImpl = deps.transactFn ?? transact;
55623
+ const randomBigintImpl = deps.randomBigintFn ?? randomBigint;
55624
+ const nowImpl = deps.nowFn ?? Date.now;
55625
+ return {
55626
+ async execute(params, opts, overrides) {
55627
+ ensureChainId(params.chainId);
55628
+ const poolAddress = ensureAddress("poolAddress", params.poolAddress);
55629
+ const adapterAddress = ensureAddress(
55630
+ "adapterAddress",
55631
+ params.adapterAddress
55632
+ );
55633
+ if (!params.inputs.length) {
55634
+ throw new AdapterError("at least one input token is required");
55635
+ }
55636
+ if (!params.calls.length) {
55637
+ throw new AdapterError("at least one adapter call is required");
55638
+ }
55639
+ if (!params.reshields.length) {
55640
+ throw new AdapterError("at least one reshield output is required");
55641
+ }
55642
+ const inputs = params.inputs.map(
55643
+ (input, i) => normalizeInputSpec(input, i)
55644
+ );
55645
+ const seenTokens = /* @__PURE__ */ new Set();
55646
+ for (const input of inputs) {
55647
+ const lower = input.token.toLowerCase();
55648
+ if (seenTokens.has(lower)) {
55649
+ throw new AdapterError(
55650
+ `duplicate input token ${input.token}; combine amounts per token instead`
55651
+ );
55652
+ }
55653
+ seenTokens.add(lower);
55654
+ }
55655
+ const calls = params.calls.map((call, i) => normalizeCall2(call, i));
55656
+ const reshieldSpecs = params.reshields.map(
55657
+ (reshield, i) => normalizeReshieldSpec(reshield, i)
55658
+ );
55659
+ const seenReshieldTokens = /* @__PURE__ */ new Set();
55660
+ for (const r2 of reshieldSpecs) {
55661
+ const lower = r2.token.toLowerCase();
55662
+ if (seenReshieldTokens.has(lower)) {
55663
+ throw new AdapterError(
55664
+ `duplicate reshield token ${r2.token}; each reshield must target a unique token`
55665
+ );
55666
+ }
55667
+ seenReshieldTokens.add(lower);
55668
+ }
55669
+ const account = overrides?.account ?? await deps.requireActiveAccount();
55670
+ const signer = overrides?.signer ?? deps.requireSigner(account);
55671
+ const nowSeconds = BigInt(Math.floor(nowImpl() / 1e3));
55672
+ const deadline = params.deadline ?? nowSeconds + DEFAULT_DEADLINE_WINDOW_SECONDS;
55673
+ if (deadline <= nowSeconds) {
55674
+ throw new AdapterError("deadline must be in the future");
55675
+ }
55676
+ const executionCalls = calls;
55677
+ const reshields = reshieldSpecs.map(
55678
+ (reshield) => {
55679
+ const random = randomFieldElement(randomBigintImpl);
55680
+ const npk = poseidon([account.masterPublicKey, random]);
55681
+ return {
55682
+ npk,
55683
+ random,
55684
+ token: reshield.token,
55685
+ minAmount: reshield.minAmount
55686
+ };
55687
+ }
55688
+ );
55689
+ const inputTokens = inputs.map((input) => input.token);
55690
+ const nonce = randomFieldElement(randomBigintImpl);
55691
+ const adapterDataHash = computeAdapterDataHash({
55692
+ calls: executionCalls,
55693
+ reshields,
55694
+ inputTokens,
55695
+ nonce,
55696
+ deadline,
55697
+ chainId: params.chainId
55698
+ });
55699
+ const notes = await deps.stateStore.listNotes({
55700
+ chainId: params.chainId,
55701
+ mpk: formatUint256(account.masterPublicKey),
55702
+ includeSpent: false
55703
+ });
55704
+ const withdrawalPlans = planWithdrawalsImpl(
55705
+ notes,
55706
+ inputs.map((input) => ({
55707
+ token: input.token,
55708
+ amount: input.amount,
55709
+ recipient: adapterAddress
55710
+ })),
55711
+ account.masterPublicKey,
55712
+ account.viewingKeyPair.pubkey
55713
+ );
55714
+ const transactResult = await transactImpl(
55715
+ deps.stateStore,
55716
+ {
55717
+ account,
55718
+ signer,
55719
+ chainId: params.chainId,
55720
+ poolAddress,
55721
+ transactions: withdrawalPlans.map((plan) => ({
55722
+ token: plan.token,
55723
+ inputs: plan.inputs.map((note) => ({ index: note.index })),
55724
+ outputs: plan.outputNotes,
55725
+ withdrawal: plan.withdrawal,
55726
+ adapterDataHash
55727
+ }))
55728
+ },
55729
+ {
55730
+ ...deps.txOpts,
55731
+ skipBroadcast: true,
55732
+ persistJob: false
55733
+ }
55734
+ );
55735
+ const adapterCalldata = encodeAdapterExecute({
55736
+ transactCalldata: transactResult.calldata,
55737
+ calls: executionCalls,
55738
+ reshields,
55739
+ inputTokens,
55740
+ nonce,
55741
+ deadline
55742
+ });
55743
+ if (opts?.skipBroadcast) {
55744
+ return {
55745
+ relayId: transactResult.relayId,
55746
+ adapterCalldata,
55747
+ transactCalldata: transactResult.calldata,
55748
+ transactResult,
55749
+ reshields
55750
+ };
55751
+ }
55752
+ const relayId = generateRelayId("adapter");
55753
+ const submission = await deps.broadcasterClient.submitRelay({
55754
+ clientTxId: relayId,
55755
+ chainId: params.chainId,
55756
+ payload: {
55757
+ kind: "call_data",
55758
+ to: adapterAddress,
55759
+ data: adapterCalldata
55760
+ }
55761
+ });
55762
+ if (!submission.accepted) {
55763
+ throw new AdapterError(submission.message ?? "broadcaster rejected");
55764
+ }
55765
+ await deps.stateStore.putJob({
55766
+ relayId,
55767
+ kind: "adapter",
55768
+ chainId: params.chainId,
55769
+ mpk: formatUint256(account.masterPublicKey),
55770
+ status: "broadcasting",
55771
+ txHash: null,
55772
+ createdAt: nowImpl(),
55773
+ timeoutMs: DEFAULT_JOB_TIMEOUT_MS,
55774
+ poolAddress,
55775
+ calldata: transactResult.calldata,
55776
+ transactions: withdrawalPlans.map((plan, i) => ({
55777
+ token: plan.token,
55778
+ nullifiers: transactResult.transactions[i]?.nullifiers ?? [],
55779
+ predictedCommitments: (transactResult.transactions[i]?.predictedCommitments ?? []).map((hex2) => ({ hex: hex2 })),
55780
+ withdrawal: {
55781
+ amount: plan.withdrawal.amount.toString(),
55782
+ recipient: adapterAddress
55783
+ }
55784
+ })),
55785
+ adapterAddress,
55786
+ adapterCalldata,
55787
+ historyPreview: {
55788
+ kind: "Withdraw",
55789
+ amounts: inputs.map((input) => ({
55790
+ token: input.token,
55791
+ delta: (-input.amount).toString()
55792
+ }))
55793
+ }
55794
+ });
55795
+ return {
55796
+ relayId,
55797
+ adapterCalldata,
55798
+ transactCalldata: transactResult.calldata,
55799
+ transactResult,
55800
+ reshields
55801
+ };
55802
+ }
55803
+ };
55804
+ }
55805
+ init_process();
55806
+ init_buffer();
55450
55807
  var BIP44_ETH_PREFIX = "m/44'/60'/0'/0";
55451
55808
  var ERC20_BALANCE_OF = "function balanceOf(address) view returns (uint256)";
55452
55809
  function createBurnerService(deps) {
@@ -55803,7 +56160,14 @@ function createWalletSDK(deps, options) {
55803
56160
  spendingKeyPair.pubkey
55804
56161
  );
55805
56162
  }
55806
- if (configuredChainId) {
56163
+ const adapterService = createAdapterService({
56164
+ stateStore,
56165
+ txOpts,
56166
+ broadcasterClient,
56167
+ requireActiveAccount,
56168
+ requireSigner
56169
+ });
56170
+ if (configuredChainId && options.autoSync !== false) {
55807
56171
  scheduler.start();
55808
56172
  }
55809
56173
  let burnerService;
@@ -55903,10 +56267,13 @@ function createWalletSDK(deps, options) {
55903
56267
  return getBurnerService().sweepToPool(index, params);
55904
56268
  }
55905
56269
  },
56270
+ adapter: {
56271
+ execute: async (params, opts, overrides) => adapterService.execute(params, opts, overrides)
56272
+ },
55906
56273
  balances: {
55907
- async list(chainId) {
56274
+ async list(chainId, overrides) {
55908
56275
  ensureChainId(chainId);
55909
- const account = await requireActiveAccount();
56276
+ const account = overrides?.account ?? await requireActiveAccount();
55910
56277
  const notes = await stateStore.listNotes({
55911
56278
  chainId,
55912
56279
  mpk: formatUint256(account.masterPublicKey),
@@ -55914,15 +56281,15 @@ function createWalletSDK(deps, options) {
55914
56281
  });
55915
56282
  return computeBalances(notes);
55916
56283
  },
55917
- async get(chainId, token) {
55918
- const balances = await this.list(chainId);
56284
+ async get(chainId, token, overrides) {
56285
+ const balances = await this.list(chainId, overrides);
55919
56286
  return balances[token.toLowerCase()] ?? 0n;
55920
56287
  }
55921
56288
  },
55922
56289
  deposit: {
55923
56290
  async request(params) {
55924
56291
  ensureChainId(params.chainId);
55925
- const account = await requireActiveAccount();
56292
+ const account = params.account ?? await requireActiveAccount();
55926
56293
  const notes = params.deposits.map((d2) => {
55927
56294
  const randomBytes5 = rng(32);
55928
56295
  const random = BigInt(
@@ -55957,9 +56324,9 @@ function createWalletSDK(deps, options) {
55957
56324
  }
55958
56325
  },
55959
56326
  history: {
55960
- async list(chainId, options2) {
56327
+ async list(chainId, options2, overrides) {
55961
56328
  ensureChainId(chainId);
55962
- const account = await requireActiveAccount();
56329
+ const account = overrides?.account ?? await requireActiveAccount();
55963
56330
  return historyService.getHistory({
55964
56331
  chainId,
55965
56332
  mpk: formatUint256(account.masterPublicKey),
@@ -55984,9 +56351,9 @@ function createWalletSDK(deps, options) {
55984
56351
  });
55985
56352
  await historyService.rebuildHistory({ chainId: note.chainId, mpk });
55986
56353
  },
55987
- async list(chainId) {
56354
+ async list(chainId, overrides) {
55988
56355
  ensureChainId(chainId);
55989
- const account = await requireActiveAccount();
56356
+ const account = overrides?.account ?? await requireActiveAccount();
55990
56357
  return stateStore.listNotes({
55991
56358
  chainId,
55992
56359
  mpk: formatUint256(account.masterPublicKey),
@@ -56195,34 +56562,37 @@ var UnlinkWallet = class _UnlinkWallet {
56195
56562
  * Create a new UnlinkWallet instance.
56196
56563
  *
56197
56564
  * Handles all initialization internally:
56198
- * - Resolves environment config (if using `environment` instead of explicit URLs)
56565
+ * - Resolves chain config (if using `chain` instead of explicit URLs)
56199
56566
  * - Auto-detects storage (IndexedDB in browser) and rng (crypto.getRandomValues)
56200
56567
  * - Runs schema migration via `initCore()`
56201
56568
  * - Creates the internal SDK
56202
56569
  */
56203
56570
  static async create(config22) {
56571
+ let chainId;
56204
56572
  let gatewayUrl;
56205
56573
  let poolAddress;
56206
56574
  let proverConfig = config22.prover;
56207
- if ("gatewayUrl" in config22) {
56575
+ if ("chain" in config22) {
56576
+ const chainConfig = await fetchChainConfig(config22.chain);
56577
+ chainId = chainConfig.chainId;
56578
+ gatewayUrl = chainConfig.gatewayUrl;
56579
+ poolAddress = config22.poolAddress ?? chainConfig.poolAddress;
56580
+ proverConfig = {
56581
+ artifactSource: {
56582
+ baseUrl: config22.prover?.artifactSource?.baseUrl ?? chainConfig.artifactBaseUrl,
56583
+ version: config22.prover?.artifactSource?.version ?? chainConfig.artifactVersion,
56584
+ preferLocalFiles: config22.prover?.artifactSource?.preferLocalFiles
56585
+ }
56586
+ };
56587
+ } else {
56588
+ chainId = config22.chainId;
56208
56589
  gatewayUrl = config22.gatewayUrl;
56209
56590
  poolAddress = config22.poolAddress;
56210
56591
  if (typeof window !== "undefined" && !config22.prover?.artifactSource?.version) {
56211
56592
  throw new InitializationError(
56212
- "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use environment mode or provide a pinned artifact version."
56593
+ "prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use chain mode or provide a pinned artifact version."
56213
56594
  );
56214
56595
  }
56215
- } else {
56216
- const envConfig = await fetchEnvironmentConfig(config22.environment);
56217
- gatewayUrl = envConfig.gatewayUrl;
56218
- poolAddress = config22.poolAddress ?? envConfig.poolAddress;
56219
- proverConfig = {
56220
- artifactSource: {
56221
- baseUrl: config22.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,
56222
- version: config22.prover?.artifactSource?.version ?? envConfig.artifactVersion,
56223
- preferLocalFiles: config22.prover?.artifactSource?.preferLocalFiles
56224
- }
56225
- };
56226
56596
  }
56227
56597
  const storage = config22.storage ?? detectStorage();
56228
56598
  const rng = config22.rng ?? defaultRng;
@@ -56231,13 +56601,14 @@ var UnlinkWallet = class _UnlinkWallet {
56231
56601
  const sdk = createWalletSDK(
56232
56602
  { core, fetch: fetchImpl },
56233
56603
  {
56234
- chainId: config22.chainId,
56604
+ chainId,
56235
56605
  gatewayUrl,
56236
56606
  chainRpcUrl: config22.chainRpcUrl,
56237
- prover: proverConfig
56607
+ prover: proverConfig,
56608
+ autoSync: config22.autoSync
56238
56609
  }
56239
56610
  );
56240
- return new _UnlinkWallet(sdk, config22.chainId, poolAddress);
56611
+ return new _UnlinkWallet(sdk, chainId, poolAddress);
56241
56612
  }
56242
56613
  // ===== Seed Lifecycle =====
56243
56614
  /** Seed management (create, import, export, delete mnemonic). */
@@ -56259,7 +56630,8 @@ var UnlinkWallet = class _UnlinkWallet {
56259
56630
  chainId: this.chainId,
56260
56631
  poolAddress: this.poolAddress,
56261
56632
  depositor: params.depositor,
56262
- deposits: params.deposits
56633
+ deposits: params.deposits,
56634
+ account: params.account
56263
56635
  });
56264
56636
  }
56265
56637
  /** Wait for a deposit to be confirmed on-chain. */
@@ -56270,57 +56642,71 @@ var UnlinkWallet = class _UnlinkWallet {
56270
56642
  * Execute a private transfer (1 or more recipients).
56271
56643
  * Handles note selection, circuit selection, and proof generation automatically.
56272
56644
  */
56273
- async transfer(params) {
56274
- return this.sdk.transfer.send({
56275
- chainId: this.chainId,
56276
- poolAddress: this.poolAddress,
56277
- transfers: params.transfers
56278
- });
56645
+ async transfer(params, overrides) {
56646
+ return this.sdk.transfer.send(
56647
+ {
56648
+ chainId: this.chainId,
56649
+ poolAddress: this.poolAddress,
56650
+ transfers: params.transfers
56651
+ },
56652
+ overrides
56653
+ );
56279
56654
  }
56280
56655
  /**
56281
56656
  * Get a transfer plan without executing (for preview/confirmation UIs).
56282
56657
  */
56283
- async planTransfer(params) {
56284
- return this.sdk.transfer.plan({
56285
- chainId: this.chainId,
56286
- poolAddress: this.poolAddress,
56287
- transfers: params.transfers
56288
- });
56658
+ async planTransfer(params, account) {
56659
+ return this.sdk.transfer.plan(
56660
+ {
56661
+ chainId: this.chainId,
56662
+ poolAddress: this.poolAddress,
56663
+ transfers: params.transfers
56664
+ },
56665
+ account
56666
+ );
56289
56667
  }
56290
56668
  /** Execute a pre-built transfer plan. */
56291
- async executeTransfer(plans) {
56292
- return this.sdk.transfer.execute(plans, {
56293
- chainId: this.chainId,
56294
- poolAddress: this.poolAddress
56295
- });
56669
+ async executeTransfer(plans, overrides) {
56670
+ return this.sdk.transfer.execute(
56671
+ plans,
56672
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56673
+ overrides
56674
+ );
56296
56675
  }
56297
56676
  /**
56298
56677
  * Execute a withdrawal (1 or more recipients).
56299
56678
  * Handles note selection, circuit selection, and proof generation automatically.
56300
56679
  */
56301
- async withdraw(params) {
56302
- return this.sdk.withdraw.send({
56303
- chainId: this.chainId,
56304
- poolAddress: this.poolAddress,
56305
- withdrawals: params.withdrawals
56306
- });
56680
+ async withdraw(params, overrides) {
56681
+ return this.sdk.withdraw.send(
56682
+ {
56683
+ chainId: this.chainId,
56684
+ poolAddress: this.poolAddress,
56685
+ withdrawals: params.withdrawals
56686
+ },
56687
+ overrides
56688
+ );
56307
56689
  }
56308
56690
  /**
56309
56691
  * Get a withdrawal plan without executing (for preview/confirmation UIs).
56310
56692
  */
56311
- async planWithdraw(params) {
56312
- return this.sdk.withdraw.plan({
56313
- chainId: this.chainId,
56314
- poolAddress: this.poolAddress,
56315
- withdrawals: params.withdrawals
56316
- });
56693
+ async planWithdraw(params, account) {
56694
+ return this.sdk.withdraw.plan(
56695
+ {
56696
+ chainId: this.chainId,
56697
+ poolAddress: this.poolAddress,
56698
+ withdrawals: params.withdrawals
56699
+ },
56700
+ account
56701
+ );
56317
56702
  }
56318
56703
  /** Execute a pre-built withdrawal plan. */
56319
- async executeWithdraw(plans) {
56320
- return this.sdk.withdraw.execute(plans, {
56321
- chainId: this.chainId,
56322
- poolAddress: this.poolAddress
56323
- });
56704
+ async executeWithdraw(plans, overrides) {
56705
+ return this.sdk.withdraw.execute(
56706
+ plans,
56707
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56708
+ overrides
56709
+ );
56324
56710
  }
56325
56711
  /** Wait for a transfer or withdrawal to be confirmed on-chain. */
56326
56712
  async confirmTransaction(relayId) {
@@ -56331,28 +56717,28 @@ var UnlinkWallet = class _UnlinkWallet {
56331
56717
  * Get balance for a specific token (defaults to all tokens if no token specified).
56332
56718
  * @param token Token address. If omitted, returns balance for all tokens via getBalances().
56333
56719
  */
56334
- async getBalance(token) {
56335
- return this.sdk.balances.get(this.chainId, token);
56720
+ async getBalance(token, overrides) {
56721
+ return this.sdk.balances.get(this.chainId, token, overrides);
56336
56722
  }
56337
56723
  /** Get balances for all tokens. */
56338
- async getBalances() {
56339
- return this.sdk.balances.list(this.chainId);
56724
+ async getBalances(overrides) {
56725
+ return this.sdk.balances.list(this.chainId, overrides);
56340
56726
  }
56341
56727
  /** Get transaction history. */
56342
- async getHistory(options) {
56343
- return this.sdk.history.list(this.chainId, options);
56728
+ async getHistory(options, overrides) {
56729
+ return this.sdk.history.list(this.chainId, options, overrides);
56344
56730
  }
56345
- /** Get UTXO notes for the active account. */
56346
- async getNotes() {
56347
- return this.sdk.notes.list(this.chainId);
56731
+ /** Get UTXO notes for the active account (or override account). */
56732
+ async getNotes(overrides) {
56733
+ return this.sdk.notes.list(this.chainId, overrides);
56348
56734
  }
56349
56735
  // ===== Sync =====
56350
56736
  /**
56351
56737
  * Sync notes from the blockchain.
56352
56738
  * Automatically resolves the active account (no need to pass it).
56353
56739
  */
56354
- async sync(options) {
56355
- const account = await this.requireActiveAccount();
56740
+ async sync(options, overrides) {
56741
+ const account = overrides?.account ?? await this.requireActiveAccount();
56356
56742
  return this.sdk.sync.syncChain(this.chainId, account, options);
56357
56743
  }
56358
56744
  /** Start auto-sync at the given interval (default: 5000ms). */
@@ -56429,6 +56815,31 @@ var UnlinkWallet = class _UnlinkWallet {
56429
56815
  return this.sdk.burner.getBalance(address);
56430
56816
  }
56431
56817
  };
56818
+ // ===== Adapter =====
56819
+ /**
56820
+ * Private DeFi adapter operations.
56821
+ * chainId/poolAddress are injected automatically.
56822
+ */
56823
+ adapter = {
56824
+ /**
56825
+ * Execute an atomic unshield -> call(s) -> reshield flow through an adapter.
56826
+ */
56827
+ execute: (params, opts, overrides) => {
56828
+ return this.sdk.adapter.execute(
56829
+ {
56830
+ chainId: this.chainId,
56831
+ poolAddress: this.poolAddress,
56832
+ adapterAddress: params.adapterAddress,
56833
+ inputs: params.inputs,
56834
+ calls: params.calls,
56835
+ reshields: params.reshields,
56836
+ deadline: params.deadline
56837
+ },
56838
+ opts,
56839
+ overrides
56840
+ );
56841
+ }
56842
+ };
56432
56843
  // ===== Advanced =====
56433
56844
  /**
56434
56845
  * Advanced escape hatch for raw JoinSplit transaction building.
@@ -56553,8 +56964,10 @@ var initialState = {
56553
56964
  accounts: [],
56554
56965
  activeAccount: null,
56555
56966
  activeAccountIndex: null,
56967
+ chainId: null,
56556
56968
  notes: [],
56557
56969
  balances: {},
56970
+ burners: [],
56558
56971
  pendingDeposits: [],
56559
56972
  pendingTransfers: [],
56560
56973
  pendingWithdrawals: [],
@@ -56572,14 +56985,15 @@ function convertNotes(noteRecords) {
56572
56985
  }
56573
56986
  function UnlinkProvider({
56574
56987
  children,
56575
- chainId,
56576
56988
  poolAddress,
56577
56989
  syncInterval = 5e3,
56578
56990
  autoSync = true,
56579
- gatewayUrl,
56580
- environment,
56581
- prover
56991
+ prover,
56992
+ ...configProps
56582
56993
  }) {
56994
+ const chain2 = "chain" in configProps ? configProps.chain : void 0;
56995
+ const chainId = "chainId" in configProps ? configProps.chainId : void 0;
56996
+ const gatewayUrl = "gatewayUrl" in configProps ? configProps.gatewayUrl : void 0;
56583
56997
  const [state, setState] = useState(initialState);
56584
56998
  const walletRef = useRef(null);
56585
56999
  const proverKey = JSON.stringify(prover ?? null);
@@ -56591,8 +57005,8 @@ function UnlinkProvider({
56591
57005
  setState((prev2) => ({
56592
57006
  ...prev2,
56593
57007
  accounts,
56594
- activeAccount,
56595
- activeAccountIndex
57008
+ activeAccount: activeAccount ?? prev2.activeAccount,
57009
+ activeAccountIndex: activeAccountIndex ?? prev2.activeAccountIndex
56596
57010
  }));
56597
57011
  } catch (err) {
56598
57012
  console.error("[UnlinkProvider] refreshAccounts error", err);
@@ -56609,13 +57023,13 @@ function UnlinkProvider({
56609
57023
  }
56610
57024
  }, []);
56611
57025
  useEffect(() => {
56612
- if (!gatewayUrl && !environment) {
57026
+ if (!chain2 && !gatewayUrl) {
56613
57027
  const configError = new ValidationError(
56614
- "Either gatewayUrl or environment is required"
57028
+ "Either chain or gatewayUrl is required"
56615
57029
  );
56616
57030
  setState((prev2) => ({
56617
57031
  ...prev2,
56618
- status: "Error: Either gatewayUrl or environment is required",
57032
+ status: "Error: Either chain or gatewayUrl is required",
56619
57033
  error: createUnlinkError(configError, "init")
56620
57034
  }));
56621
57035
  return;
@@ -56629,14 +57043,13 @@ function UnlinkProvider({
56629
57043
  status: "Initializing SDK..."
56630
57044
  }));
56631
57045
  const wallet = await UnlinkWallet.create(
56632
- gatewayUrl ? {
56633
- chainId,
56634
- gatewayUrl,
57046
+ chain2 ? {
57047
+ chain: chain2,
56635
57048
  poolAddress,
56636
57049
  ...prover ? { prover } : {}
56637
57050
  } : {
56638
57051
  chainId,
56639
- environment,
57052
+ gatewayUrl,
56640
57053
  poolAddress,
56641
57054
  ...prover ? { prover } : {}
56642
57055
  }
@@ -56677,6 +57090,7 @@ function UnlinkProvider({
56677
57090
  accounts,
56678
57091
  activeAccount,
56679
57092
  activeAccountIndex,
57093
+ chainId: wallet.chainId,
56680
57094
  notes,
56681
57095
  balances,
56682
57096
  ready: true,
@@ -56687,7 +57101,7 @@ function UnlinkProvider({
56687
57101
  wallet.startAutoSync(syncInterval);
56688
57102
  }
56689
57103
  unsubscribe = wallet.on((event) => {
56690
- if (event.type === "notes-updated" && event.chainId === chainId) {
57104
+ if (event.type === "notes-updated" && event.chainId === wallet.chainId) {
56691
57105
  setState((prev2) => ({ ...prev2, syncError: null }));
56692
57106
  void refreshState(wallet);
56693
57107
  }
@@ -56721,13 +57135,13 @@ function UnlinkProvider({
56721
57135
  walletRef.current?.stopAutoSync();
56722
57136
  };
56723
57137
  }, [
57138
+ chain2,
56724
57139
  chainId,
56725
57140
  autoSync,
56726
57141
  syncInterval,
56727
57142
  refreshState,
56728
57143
  refreshAccounts,
56729
57144
  gatewayUrl,
56730
- environment,
56731
57145
  poolAddress,
56732
57146
  proverKey
56733
57147
  ]);
@@ -56775,6 +57189,7 @@ function UnlinkProvider({
56775
57189
  accounts,
56776
57190
  activeAccount,
56777
57191
  activeAccountIndex,
57192
+ burners: [],
56778
57193
  busy: false,
56779
57194
  status: accounts.length > 0 ? "Wallet imported" : "Wallet imported - create an account",
56780
57195
  syncError: null,
@@ -56809,6 +57224,7 @@ function UnlinkProvider({
56809
57224
  activeAccountIndex: null,
56810
57225
  notes: [],
56811
57226
  balances: {},
57227
+ burners: [],
56812
57228
  busy: false,
56813
57229
  status: "Wallet cleared",
56814
57230
  syncError: null,
@@ -57093,6 +57509,36 @@ function UnlinkProvider({
57093
57509
  },
57094
57510
  []
57095
57511
  );
57512
+ const executeAdapter = useCallback(
57513
+ async (params) => {
57514
+ const wallet = walletRef.current;
57515
+ if (!wallet) throw new Error("SDK not initialized");
57516
+ setState((prev2) => ({
57517
+ ...prev2,
57518
+ busy: true,
57519
+ status: "Executing adapter..."
57520
+ }));
57521
+ try {
57522
+ const result = await wallet.adapter.execute(params);
57523
+ setState((prev2) => ({
57524
+ ...prev2,
57525
+ busy: false,
57526
+ status: "Adapter execution submitted",
57527
+ error: null
57528
+ }));
57529
+ return result;
57530
+ } catch (err) {
57531
+ setState((prev2) => ({
57532
+ ...prev2,
57533
+ busy: false,
57534
+ status: `Error: ${err instanceof Error ? err.message : "Unknown"}`,
57535
+ error: createUnlinkError(err, "executeAdapter")
57536
+ }));
57537
+ throw err;
57538
+ }
57539
+ },
57540
+ []
57541
+ );
57096
57542
  const planWithdraw = useCallback(
57097
57543
  async (params) => {
57098
57544
  const wallet = walletRef.current;
@@ -57134,6 +57580,149 @@ function UnlinkProvider({
57134
57580
  throw err;
57135
57581
  }
57136
57582
  }, []);
57583
+ const createBurner = useCallback(async (index) => {
57584
+ const wallet = walletRef.current;
57585
+ if (!wallet) throw new Error("SDK not initialized");
57586
+ setState((prev2) => ({
57587
+ ...prev2,
57588
+ busy: true,
57589
+ status: `Creating burner ${index}...`
57590
+ }));
57591
+ try {
57592
+ const burner = await wallet.burner.addressOf(index);
57593
+ setState((prev2) => ({
57594
+ ...prev2,
57595
+ burners: [
57596
+ ...prev2.burners.filter((existing) => existing.index !== burner.index),
57597
+ burner
57598
+ ],
57599
+ busy: false,
57600
+ status: `Burner ${index} ready`,
57601
+ error: null
57602
+ }));
57603
+ return burner;
57604
+ } catch (err) {
57605
+ setState((prev2) => ({
57606
+ ...prev2,
57607
+ busy: false,
57608
+ status: `Error: ${err instanceof Error ? err.message : "Unknown"}`,
57609
+ error: createUnlinkError(err, "createBurner")
57610
+ }));
57611
+ throw err;
57612
+ }
57613
+ }, []);
57614
+ const removeBurner = useCallback((index) => {
57615
+ setState((prev2) => ({
57616
+ ...prev2,
57617
+ burners: prev2.burners.filter((burner) => burner.index !== index)
57618
+ }));
57619
+ }, []);
57620
+ const burnerSend = useCallback(
57621
+ async (index, tx) => {
57622
+ const wallet = walletRef.current;
57623
+ if (!wallet) throw new Error("SDK not initialized");
57624
+ setState((prev2) => ({
57625
+ ...prev2,
57626
+ busy: true,
57627
+ status: "Sending burner transaction..."
57628
+ }));
57629
+ try {
57630
+ const result = await wallet.burner.send(index, tx);
57631
+ setState((prev2) => ({
57632
+ ...prev2,
57633
+ busy: false,
57634
+ status: "Burner transaction sent",
57635
+ error: null
57636
+ }));
57637
+ return result;
57638
+ } catch (err) {
57639
+ setState((prev2) => ({
57640
+ ...prev2,
57641
+ busy: false,
57642
+ status: `Error: ${err instanceof Error ? err.message : "Unknown"}`,
57643
+ error: createUnlinkError(err, "burnerSend")
57644
+ }));
57645
+ throw err;
57646
+ }
57647
+ },
57648
+ []
57649
+ );
57650
+ const burnerFund = useCallback(
57651
+ async (index, params) => {
57652
+ const wallet = walletRef.current;
57653
+ if (!wallet) throw new Error("SDK not initialized");
57654
+ setState((prev2) => ({
57655
+ ...prev2,
57656
+ busy: true,
57657
+ status: "Funding burner..."
57658
+ }));
57659
+ try {
57660
+ const result = await wallet.burner.fund(index, params);
57661
+ setState((prev2) => ({
57662
+ ...prev2,
57663
+ busy: false,
57664
+ status: "Burner funded",
57665
+ error: null
57666
+ }));
57667
+ return result;
57668
+ } catch (err) {
57669
+ setState((prev2) => ({
57670
+ ...prev2,
57671
+ busy: false,
57672
+ status: `Error: ${err instanceof Error ? err.message : "Unknown"}`,
57673
+ error: createUnlinkError(err, "burnerFund")
57674
+ }));
57675
+ throw err;
57676
+ }
57677
+ },
57678
+ []
57679
+ );
57680
+ const burnerSweepToPool = useCallback(
57681
+ async (index, params) => {
57682
+ const wallet = walletRef.current;
57683
+ if (!wallet) throw new Error("SDK not initialized");
57684
+ setState((prev2) => ({
57685
+ ...prev2,
57686
+ busy: true,
57687
+ status: "Sweeping burner to pool..."
57688
+ }));
57689
+ try {
57690
+ const result = await wallet.burner.sweepToPool(index, params);
57691
+ setState((prev2) => ({
57692
+ ...prev2,
57693
+ busy: false,
57694
+ status: "Burner sweep submitted",
57695
+ error: null
57696
+ }));
57697
+ return result;
57698
+ } catch (err) {
57699
+ setState((prev2) => ({
57700
+ ...prev2,
57701
+ busy: false,
57702
+ status: `Error: ${err instanceof Error ? err.message : "Unknown"}`,
57703
+ error: createUnlinkError(err, "burnerSweepToPool")
57704
+ }));
57705
+ throw err;
57706
+ }
57707
+ },
57708
+ []
57709
+ );
57710
+ const burnerGetTokenBalance = useCallback(
57711
+ async (address, token) => {
57712
+ const wallet = walletRef.current;
57713
+ if (!wallet) throw new Error("SDK not initialized");
57714
+ return wallet.burner.getTokenBalance(address, token);
57715
+ },
57716
+ []
57717
+ );
57718
+ const burnerGetBalance = useCallback(
57719
+ async (address) => {
57720
+ const wallet = walletRef.current;
57721
+ if (!wallet) throw new Error("SDK not initialized");
57722
+ return wallet.burner.getBalance(address);
57723
+ },
57724
+ []
57725
+ );
57137
57726
  const refresh = useCallback(async () => {
57138
57727
  const wallet = walletRef.current;
57139
57728
  if (!wallet) return;
@@ -57249,7 +57838,6 @@ function UnlinkProvider({
57249
57838
  const value = useMemo(
57250
57839
  () => ({
57251
57840
  ...state,
57252
- chainId,
57253
57841
  // Wallet actions
57254
57842
  createWallet,
57255
57843
  importWallet,
@@ -57266,8 +57854,18 @@ function UnlinkProvider({
57266
57854
  requestDeposit,
57267
57855
  // Withdraw actions
57268
57856
  requestWithdraw,
57857
+ // Adapter actions
57858
+ executeAdapter,
57269
57859
  planWithdraw,
57270
57860
  executeWithdraw,
57861
+ // Burner actions
57862
+ createBurner,
57863
+ removeBurner,
57864
+ burnerSend,
57865
+ burnerFund,
57866
+ burnerSweepToPool,
57867
+ burnerGetTokenBalance,
57868
+ burnerGetBalance,
57271
57869
  // Sync actions
57272
57870
  refresh,
57273
57871
  forceResync,
@@ -57279,7 +57877,6 @@ function UnlinkProvider({
57279
57877
  }),
57280
57878
  [
57281
57879
  state,
57282
- chainId,
57283
57880
  createWallet,
57284
57881
  importWallet,
57285
57882
  exportMnemonic,
@@ -57291,8 +57888,16 @@ function UnlinkProvider({
57291
57888
  executeTransfer,
57292
57889
  requestDeposit,
57293
57890
  requestWithdraw,
57891
+ executeAdapter,
57294
57892
  planWithdraw,
57295
57893
  executeWithdraw,
57894
+ createBurner,
57895
+ removeBurner,
57896
+ burnerSend,
57897
+ burnerFund,
57898
+ burnerSweepToPool,
57899
+ burnerGetTokenBalance,
57900
+ burnerGetBalance,
57296
57901
  refresh,
57297
57902
  forceResync,
57298
57903
  clearError,
@@ -57528,6 +58133,57 @@ function useWithdraw() {
57528
58133
  );
57529
58134
  return useOperationMutation(op);
57530
58135
  }
58136
+
58137
+ // src/useAdapter.ts
58138
+ import { useCallback as useCallback8 } from "react";
58139
+ function useAdapter() {
58140
+ const { executeAdapter } = useUnlink();
58141
+ const op = useCallback8(
58142
+ (params) => executeAdapter(params),
58143
+ [executeAdapter]
58144
+ );
58145
+ return useOperationMutation(op);
58146
+ }
58147
+
58148
+ // src/useBurner.ts
58149
+ import { useCallback as useCallback9 } from "react";
58150
+ function useBurner() {
58151
+ const {
58152
+ burners,
58153
+ createBurner,
58154
+ removeBurner,
58155
+ burnerSend,
58156
+ burnerFund,
58157
+ burnerSweepToPool,
58158
+ burnerGetTokenBalance,
58159
+ burnerGetBalance
58160
+ } = useUnlink();
58161
+ const sendOp = useCallback9(
58162
+ (input) => burnerSend(input.index, input.tx),
58163
+ [burnerSend]
58164
+ );
58165
+ const fundOp = useCallback9(
58166
+ (input) => burnerFund(input.index, input.params),
58167
+ [burnerFund]
58168
+ );
58169
+ const sweepOp = useCallback9(
58170
+ (input) => burnerSweepToPool(input.index, input.params),
58171
+ [burnerSweepToPool]
58172
+ );
58173
+ const send = useOperationMutation(sendOp);
58174
+ const fund = useOperationMutation(fundOp);
58175
+ const sweepToPool = useOperationMutation(sweepOp);
58176
+ return {
58177
+ burners,
58178
+ createBurner,
58179
+ removeBurner,
58180
+ send,
58181
+ fund,
58182
+ sweepToPool,
58183
+ getTokenBalance: burnerGetTokenBalance,
58184
+ getBalance: burnerGetBalance
58185
+ };
58186
+ }
57531
58187
  export {
57532
58188
  CONFIRMATION_POLL_INTERVAL_MS,
57533
58189
  DEFAULT_CONFIRMATION_TIMEOUT_MS,
@@ -57544,6 +58200,8 @@ export {
57544
58200
  parseZkAddress,
57545
58201
  randomHex,
57546
58202
  shortenHex,
58203
+ useAdapter,
58204
+ useBurner,
57547
58205
  useDeposit,
57548
58206
  useOperationMutation,
57549
58207
  useTransfer,