@unlink-xyz/react 0.1.0 → 0.1.3-canary.09d69c8

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 = [
@@ -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
  }
@@ -36037,9 +36060,6 @@ function buildDepositCalldata(depositor, processedNotes) {
36037
36060
  }))
36038
36061
  ]);
36039
36062
  }
36040
- function generateRelayId(prefix) {
36041
- return globalThis.crypto?.randomUUID?.() ?? `${prefix}-${Date.now().toString(16)}`;
36042
- }
36043
36063
  async function deposit(store, req) {
36044
36064
  if (!req.notes?.length) {
36045
36065
  throw new ValidationError("At least one note is required for deposit");
@@ -53692,6 +53712,28 @@ function computeBoundParamsHash(chainId, poolAddress, adapterDataHash = 0n) {
53692
53712
  );
53693
53713
  return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;
53694
53714
  }
53715
+ function computeAdapterDataHash(params) {
53716
+ const coder = AbiCoder.defaultAbiCoder();
53717
+ const encoded = coder.encode(
53718
+ [
53719
+ "tuple(address to, bytes data, uint256 value)[]",
53720
+ "tuple(uint256 npk, uint256 random, address token, uint256 minAmount)[]",
53721
+ "address[]",
53722
+ "uint256",
53723
+ "uint256",
53724
+ "uint256"
53725
+ ],
53726
+ [
53727
+ params.calls,
53728
+ params.reshields,
53729
+ params.inputTokens,
53730
+ params.nonce,
53731
+ params.deadline,
53732
+ BigInt(params.chainId)
53733
+ ]
53734
+ );
53735
+ return parseHexToBigInt(keccak256(encoded)) % SNARK_SCALAR_FIELD;
53736
+ }
53695
53737
  async function buildSingleTransactionProof(store, account, signer, chainId, poolAddress, tx, trees, baseIndex, opts) {
53696
53738
  if (!tx.inputs?.length)
53697
53739
  throw new ValidationError("at least one input note is required");
@@ -53873,7 +53915,7 @@ async function transact(store, req, opts) {
53873
53915
  ciphertexts: r2.ciphertexts
53874
53916
  }))
53875
53917
  ]);
53876
- const relayId = globalThis.crypto?.randomUUID?.() ?? `tx-${Date.now().toString(16)}`;
53918
+ const relayId = generateRelayId("tx");
53877
53919
  const hasAnyWithdrawal = results.some((r2) => r2.withdrawal.amount > 0n);
53878
53920
  const historyKind = hasAnyWithdrawal ? "Withdraw" : "Send";
53879
53921
  const deltasByToken = /* @__PURE__ */ new Map();
@@ -53960,11 +54002,13 @@ async function transact(store, req, opts) {
53960
54002
  throw new CoreError("broadcaster relay timed out");
53961
54003
  }
53962
54004
  }
53963
- await store.putJob({
53964
- ...job,
53965
- status: "broadcasting",
53966
- txHash
53967
- });
54005
+ if (opts.persistJob !== false) {
54006
+ await store.putJob({
54007
+ ...job,
54008
+ status: "broadcasting",
54009
+ txHash
54010
+ });
54011
+ }
53968
54012
  const transactionResults = results.map((r2) => ({
53969
54013
  proof: r2.proof,
53970
54014
  witnesses: r2.witnesses,
@@ -53979,7 +54023,7 @@ async function transact(store, req, opts) {
53979
54023
  }
53980
54024
  async function syncTransact(store, relayId, opts) {
53981
54025
  const record = await store.getJob(relayId);
53982
- if (!record || record.kind !== "transfer" && record.kind !== "withdraw")
54026
+ if (!record || record.kind !== "transfer" && record.kind !== "withdraw" && record.kind !== "adapter")
53983
54027
  throw new CoreError(`unknown pool transaction relay ${relayId}`);
53984
54028
  const job = record;
53985
54029
  const serviceConfig = createServiceConfig(opts.gatewayUrl);
@@ -54083,6 +54127,70 @@ async function syncTransact(store, relayId, opts) {
54083
54127
  }
54084
54128
  init_process();
54085
54129
  init_buffer();
54130
+ var ADAPTER_EXECUTE_ABI = [
54131
+ "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)"
54132
+ ];
54133
+ var adapterInterface = new Interface(ADAPTER_EXECUTE_ABI);
54134
+ var approveInterface = new Interface([
54135
+ "function approve(address spender, uint256 amount)"
54136
+ ]);
54137
+ var HEX_DATA_REGEX = /^0x[0-9a-fA-F]*$/;
54138
+ function ensureNonNegative(label, value) {
54139
+ if (value < 0n) {
54140
+ throw new AdapterError(`${label} must be non-negative`);
54141
+ }
54142
+ return value;
54143
+ }
54144
+ function ensureHexData(label, value) {
54145
+ if (typeof value !== "string" || !HEX_DATA_REGEX.test(value) || value.length % 2 !== 0) {
54146
+ throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);
54147
+ }
54148
+ return value;
54149
+ }
54150
+ function normalizeCall(call, index) {
54151
+ const to = ensureAddress(`calls[${index}].to`, call.to);
54152
+ const data = ensureHexData(`calls[${index}].data`, call.data);
54153
+ const value = ensureNonNegative(`calls[${index}].value`, call.value);
54154
+ return { to, data, value };
54155
+ }
54156
+ function normalizeReshield(reshield, index) {
54157
+ const token = ensureAddress(`reshields[${index}].token`, reshield.token);
54158
+ const npk = ensureNonNegative(`reshields[${index}].npk`, reshield.npk);
54159
+ const random = ensureNonNegative(
54160
+ `reshields[${index}].random`,
54161
+ reshield.random
54162
+ );
54163
+ const minAmount = ensureNonNegative(
54164
+ `reshields[${index}].minAmount`,
54165
+ reshield.minAmount
54166
+ );
54167
+ return { npk, random, token, minAmount };
54168
+ }
54169
+ function encodeAdapterExecute(params) {
54170
+ const transactCalldata = ensureHexData(
54171
+ "transactCalldata",
54172
+ params.transactCalldata
54173
+ );
54174
+ const calls = params.calls.map((call, i) => normalizeCall(call, i));
54175
+ const reshields = params.reshields.map(
54176
+ (reshield, i) => normalizeReshield(reshield, i)
54177
+ );
54178
+ const inputTokens = params.inputTokens.map(
54179
+ (token, i) => ensureAddress(`inputTokens[${i}]`, token)
54180
+ );
54181
+ const nonce = ensureNonNegative("nonce", params.nonce);
54182
+ const deadline = ensureNonNegative("deadline", params.deadline);
54183
+ return adapterInterface.encodeFunctionData("execute", [
54184
+ transactCalldata,
54185
+ calls,
54186
+ reshields,
54187
+ inputTokens,
54188
+ nonce,
54189
+ deadline
54190
+ ]);
54191
+ }
54192
+ init_process();
54193
+ init_buffer();
54086
54194
  init_process();
54087
54195
  init_buffer();
54088
54196
  var MAX_CIRCUIT_INPUTS = Math.max(
@@ -55447,6 +55555,229 @@ function createSeedService(deps) {
55447
55555
  }
55448
55556
  init_process();
55449
55557
  init_buffer();
55558
+ var DEFAULT_DEADLINE_WINDOW_SECONDS = 600n;
55559
+ var HEX_DATA_REGEX2 = /^0x[0-9a-fA-F]*$/;
55560
+ function ensureHexData2(label, value) {
55561
+ if (typeof value !== "string" || !HEX_DATA_REGEX2.test(value) || value.length % 2 !== 0) {
55562
+ throw new AdapterError(`${label} must be 0x-prefixed even-length hex data`);
55563
+ }
55564
+ return value;
55565
+ }
55566
+ function normalizeCall2(call, index) {
55567
+ const to = ensureAddress(`calls[${index}].to`, call.to);
55568
+ const data = ensureHexData2(`calls[${index}].data`, call.data);
55569
+ if (call.value < 0n) {
55570
+ throw new AdapterError(`calls[${index}].value must be non-negative`);
55571
+ }
55572
+ return {
55573
+ to,
55574
+ data,
55575
+ value: call.value
55576
+ };
55577
+ }
55578
+ function normalizeInputSpec(input, index) {
55579
+ const token = ensureAddress(`inputs[${index}].token`, input.token);
55580
+ if (input.amount <= 0n) {
55581
+ throw new AdapterError(`inputs[${index}].amount must be greater than zero`);
55582
+ }
55583
+ return {
55584
+ token,
55585
+ amount: input.amount
55586
+ };
55587
+ }
55588
+ function normalizeReshieldSpec(reshield, index) {
55589
+ const token = ensureAddress(`reshields[${index}].token`, reshield.token);
55590
+ if (reshield.minAmount < 0n) {
55591
+ throw new AdapterError(
55592
+ `reshields[${index}].minAmount must be non-negative`
55593
+ );
55594
+ }
55595
+ return {
55596
+ token,
55597
+ minAmount: reshield.minAmount
55598
+ };
55599
+ }
55600
+ function randomFieldElement(randomBigintFn) {
55601
+ const value = randomBigintFn() % SNARK_SCALAR_FIELD;
55602
+ return value < 0n ? value + SNARK_SCALAR_FIELD : value;
55603
+ }
55604
+ function createAdapterService(deps) {
55605
+ const planWithdrawalsImpl = deps.planWithdrawalsFn ?? planWithdrawals;
55606
+ const transactImpl = deps.transactFn ?? transact;
55607
+ const randomBigintImpl = deps.randomBigintFn ?? randomBigint;
55608
+ const nowImpl = deps.nowFn ?? Date.now;
55609
+ return {
55610
+ async execute(params, opts, overrides) {
55611
+ ensureChainId(params.chainId);
55612
+ const poolAddress = ensureAddress("poolAddress", params.poolAddress);
55613
+ const adapterAddress = ensureAddress(
55614
+ "adapterAddress",
55615
+ params.adapterAddress
55616
+ );
55617
+ if (!params.inputs.length) {
55618
+ throw new AdapterError("at least one input token is required");
55619
+ }
55620
+ if (!params.calls.length) {
55621
+ throw new AdapterError("at least one adapter call is required");
55622
+ }
55623
+ if (!params.reshields.length) {
55624
+ throw new AdapterError("at least one reshield output is required");
55625
+ }
55626
+ const inputs = params.inputs.map(
55627
+ (input, i) => normalizeInputSpec(input, i)
55628
+ );
55629
+ const seenTokens = /* @__PURE__ */ new Set();
55630
+ for (const input of inputs) {
55631
+ const lower = input.token.toLowerCase();
55632
+ if (seenTokens.has(lower)) {
55633
+ throw new AdapterError(
55634
+ `duplicate input token ${input.token}; combine amounts per token instead`
55635
+ );
55636
+ }
55637
+ seenTokens.add(lower);
55638
+ }
55639
+ const calls = params.calls.map((call, i) => normalizeCall2(call, i));
55640
+ const reshieldSpecs = params.reshields.map(
55641
+ (reshield, i) => normalizeReshieldSpec(reshield, i)
55642
+ );
55643
+ const account = overrides?.account ?? await deps.requireActiveAccount();
55644
+ const signer = overrides?.signer ?? deps.requireSigner(account);
55645
+ const nowSeconds = BigInt(Math.floor(nowImpl() / 1e3));
55646
+ const deadline = params.deadline ?? nowSeconds + DEFAULT_DEADLINE_WINDOW_SECONDS;
55647
+ if (deadline <= nowSeconds) {
55648
+ throw new AdapterError("deadline must be in the future");
55649
+ }
55650
+ const executionCalls = calls;
55651
+ const reshields = reshieldSpecs.map(
55652
+ (reshield) => {
55653
+ const random = randomFieldElement(randomBigintImpl);
55654
+ const npk = poseidon([account.masterPublicKey, random]);
55655
+ return {
55656
+ npk,
55657
+ random,
55658
+ token: reshield.token,
55659
+ minAmount: reshield.minAmount
55660
+ };
55661
+ }
55662
+ );
55663
+ const inputTokens = inputs.map((input) => input.token);
55664
+ const nonce = randomFieldElement(randomBigintImpl);
55665
+ const adapterDataHash = computeAdapterDataHash({
55666
+ calls: executionCalls,
55667
+ reshields,
55668
+ inputTokens,
55669
+ nonce,
55670
+ deadline,
55671
+ chainId: params.chainId
55672
+ });
55673
+ const notes = await deps.stateStore.listNotes({
55674
+ chainId: params.chainId,
55675
+ mpk: formatUint256(account.masterPublicKey),
55676
+ includeSpent: false
55677
+ });
55678
+ const withdrawalPlans = planWithdrawalsImpl(
55679
+ notes,
55680
+ inputs.map((input) => ({
55681
+ token: input.token,
55682
+ amount: input.amount,
55683
+ recipient: adapterAddress
55684
+ })),
55685
+ account.masterPublicKey,
55686
+ account.viewingKeyPair.pubkey
55687
+ );
55688
+ const transactResult = await transactImpl(
55689
+ deps.stateStore,
55690
+ {
55691
+ account,
55692
+ signer,
55693
+ chainId: params.chainId,
55694
+ poolAddress,
55695
+ transactions: withdrawalPlans.map((plan) => ({
55696
+ token: plan.token,
55697
+ inputs: plan.inputs.map((note) => ({ index: note.index })),
55698
+ outputs: plan.outputNotes,
55699
+ withdrawal: plan.withdrawal,
55700
+ adapterDataHash
55701
+ }))
55702
+ },
55703
+ {
55704
+ ...deps.txOpts,
55705
+ skipBroadcast: true,
55706
+ persistJob: false
55707
+ }
55708
+ );
55709
+ const adapterCalldata = encodeAdapterExecute({
55710
+ transactCalldata: transactResult.calldata,
55711
+ calls: executionCalls,
55712
+ reshields,
55713
+ inputTokens,
55714
+ nonce,
55715
+ deadline
55716
+ });
55717
+ if (opts?.skipBroadcast) {
55718
+ return {
55719
+ relayId: transactResult.relayId,
55720
+ adapterCalldata,
55721
+ transactCalldata: transactResult.calldata,
55722
+ transactResult,
55723
+ reshields
55724
+ };
55725
+ }
55726
+ const relayId = generateRelayId("adapter");
55727
+ const submission = await deps.broadcasterClient.submitRelay({
55728
+ clientTxId: relayId,
55729
+ chainId: params.chainId,
55730
+ payload: {
55731
+ kind: "call_data",
55732
+ to: adapterAddress,
55733
+ data: adapterCalldata
55734
+ }
55735
+ });
55736
+ if (!submission.accepted) {
55737
+ throw new AdapterError(submission.message ?? "broadcaster rejected");
55738
+ }
55739
+ await deps.stateStore.putJob({
55740
+ relayId,
55741
+ kind: "adapter",
55742
+ chainId: params.chainId,
55743
+ mpk: formatUint256(account.masterPublicKey),
55744
+ status: "broadcasting",
55745
+ txHash: null,
55746
+ createdAt: nowImpl(),
55747
+ timeoutMs: DEFAULT_JOB_TIMEOUT_MS,
55748
+ poolAddress,
55749
+ calldata: transactResult.calldata,
55750
+ transactions: withdrawalPlans.map((plan, i) => ({
55751
+ token: plan.token,
55752
+ nullifiers: transactResult.transactions[i]?.nullifiers ?? [],
55753
+ predictedCommitments: (transactResult.transactions[i]?.predictedCommitments ?? []).map((hex2) => ({ hex: hex2 })),
55754
+ withdrawal: {
55755
+ amount: plan.withdrawal.amount.toString(),
55756
+ recipient: adapterAddress
55757
+ }
55758
+ })),
55759
+ adapterAddress,
55760
+ adapterCalldata,
55761
+ historyPreview: {
55762
+ kind: "Withdraw",
55763
+ amounts: inputs.map((input) => ({
55764
+ token: input.token,
55765
+ delta: (-input.amount).toString()
55766
+ }))
55767
+ }
55768
+ });
55769
+ return {
55770
+ relayId,
55771
+ adapterCalldata,
55772
+ transactCalldata: transactResult.calldata,
55773
+ transactResult,
55774
+ reshields
55775
+ };
55776
+ }
55777
+ };
55778
+ }
55779
+ init_process();
55780
+ init_buffer();
55450
55781
  var BIP44_ETH_PREFIX = "m/44'/60'/0'/0";
55451
55782
  var ERC20_BALANCE_OF = "function balanceOf(address) view returns (uint256)";
55452
55783
  function createBurnerService(deps) {
@@ -55803,7 +56134,14 @@ function createWalletSDK(deps, options) {
55803
56134
  spendingKeyPair.pubkey
55804
56135
  );
55805
56136
  }
55806
- if (configuredChainId) {
56137
+ const adapterService = createAdapterService({
56138
+ stateStore,
56139
+ txOpts,
56140
+ broadcasterClient,
56141
+ requireActiveAccount,
56142
+ requireSigner
56143
+ });
56144
+ if (configuredChainId && options.autoSync !== false) {
55807
56145
  scheduler.start();
55808
56146
  }
55809
56147
  let burnerService;
@@ -55903,10 +56241,13 @@ function createWalletSDK(deps, options) {
55903
56241
  return getBurnerService().sweepToPool(index, params);
55904
56242
  }
55905
56243
  },
56244
+ adapter: {
56245
+ execute: async (params, opts, overrides) => adapterService.execute(params, opts, overrides)
56246
+ },
55906
56247
  balances: {
55907
- async list(chainId) {
56248
+ async list(chainId, overrides) {
55908
56249
  ensureChainId(chainId);
55909
- const account = await requireActiveAccount();
56250
+ const account = overrides?.account ?? await requireActiveAccount();
55910
56251
  const notes = await stateStore.listNotes({
55911
56252
  chainId,
55912
56253
  mpk: formatUint256(account.masterPublicKey),
@@ -55914,15 +56255,15 @@ function createWalletSDK(deps, options) {
55914
56255
  });
55915
56256
  return computeBalances(notes);
55916
56257
  },
55917
- async get(chainId, token) {
55918
- const balances = await this.list(chainId);
56258
+ async get(chainId, token, overrides) {
56259
+ const balances = await this.list(chainId, overrides);
55919
56260
  return balances[token.toLowerCase()] ?? 0n;
55920
56261
  }
55921
56262
  },
55922
56263
  deposit: {
55923
56264
  async request(params) {
55924
56265
  ensureChainId(params.chainId);
55925
- const account = await requireActiveAccount();
56266
+ const account = params.account ?? await requireActiveAccount();
55926
56267
  const notes = params.deposits.map((d2) => {
55927
56268
  const randomBytes5 = rng(32);
55928
56269
  const random = BigInt(
@@ -55957,9 +56298,9 @@ function createWalletSDK(deps, options) {
55957
56298
  }
55958
56299
  },
55959
56300
  history: {
55960
- async list(chainId, options2) {
56301
+ async list(chainId, options2, overrides) {
55961
56302
  ensureChainId(chainId);
55962
- const account = await requireActiveAccount();
56303
+ const account = overrides?.account ?? await requireActiveAccount();
55963
56304
  return historyService.getHistory({
55964
56305
  chainId,
55965
56306
  mpk: formatUint256(account.masterPublicKey),
@@ -55984,9 +56325,9 @@ function createWalletSDK(deps, options) {
55984
56325
  });
55985
56326
  await historyService.rebuildHistory({ chainId: note.chainId, mpk });
55986
56327
  },
55987
- async list(chainId) {
56328
+ async list(chainId, overrides) {
55988
56329
  ensureChainId(chainId);
55989
- const account = await requireActiveAccount();
56330
+ const account = overrides?.account ?? await requireActiveAccount();
55990
56331
  return stateStore.listNotes({
55991
56332
  chainId,
55992
56333
  mpk: formatUint256(account.masterPublicKey),
@@ -56234,7 +56575,8 @@ var UnlinkWallet = class _UnlinkWallet {
56234
56575
  chainId: config22.chainId,
56235
56576
  gatewayUrl,
56236
56577
  chainRpcUrl: config22.chainRpcUrl,
56237
- prover: proverConfig
56578
+ prover: proverConfig,
56579
+ autoSync: config22.autoSync
56238
56580
  }
56239
56581
  );
56240
56582
  return new _UnlinkWallet(sdk, config22.chainId, poolAddress);
@@ -56259,7 +56601,8 @@ var UnlinkWallet = class _UnlinkWallet {
56259
56601
  chainId: this.chainId,
56260
56602
  poolAddress: this.poolAddress,
56261
56603
  depositor: params.depositor,
56262
- deposits: params.deposits
56604
+ deposits: params.deposits,
56605
+ account: params.account
56263
56606
  });
56264
56607
  }
56265
56608
  /** Wait for a deposit to be confirmed on-chain. */
@@ -56270,57 +56613,71 @@ var UnlinkWallet = class _UnlinkWallet {
56270
56613
  * Execute a private transfer (1 or more recipients).
56271
56614
  * Handles note selection, circuit selection, and proof generation automatically.
56272
56615
  */
56273
- async transfer(params) {
56274
- return this.sdk.transfer.send({
56275
- chainId: this.chainId,
56276
- poolAddress: this.poolAddress,
56277
- transfers: params.transfers
56278
- });
56616
+ async transfer(params, overrides) {
56617
+ return this.sdk.transfer.send(
56618
+ {
56619
+ chainId: this.chainId,
56620
+ poolAddress: this.poolAddress,
56621
+ transfers: params.transfers
56622
+ },
56623
+ overrides
56624
+ );
56279
56625
  }
56280
56626
  /**
56281
56627
  * Get a transfer plan without executing (for preview/confirmation UIs).
56282
56628
  */
56283
- async planTransfer(params) {
56284
- return this.sdk.transfer.plan({
56285
- chainId: this.chainId,
56286
- poolAddress: this.poolAddress,
56287
- transfers: params.transfers
56288
- });
56629
+ async planTransfer(params, account) {
56630
+ return this.sdk.transfer.plan(
56631
+ {
56632
+ chainId: this.chainId,
56633
+ poolAddress: this.poolAddress,
56634
+ transfers: params.transfers
56635
+ },
56636
+ account
56637
+ );
56289
56638
  }
56290
56639
  /** 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
- });
56640
+ async executeTransfer(plans, overrides) {
56641
+ return this.sdk.transfer.execute(
56642
+ plans,
56643
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56644
+ overrides
56645
+ );
56296
56646
  }
56297
56647
  /**
56298
56648
  * Execute a withdrawal (1 or more recipients).
56299
56649
  * Handles note selection, circuit selection, and proof generation automatically.
56300
56650
  */
56301
- async withdraw(params) {
56302
- return this.sdk.withdraw.send({
56303
- chainId: this.chainId,
56304
- poolAddress: this.poolAddress,
56305
- withdrawals: params.withdrawals
56306
- });
56651
+ async withdraw(params, overrides) {
56652
+ return this.sdk.withdraw.send(
56653
+ {
56654
+ chainId: this.chainId,
56655
+ poolAddress: this.poolAddress,
56656
+ withdrawals: params.withdrawals
56657
+ },
56658
+ overrides
56659
+ );
56307
56660
  }
56308
56661
  /**
56309
56662
  * Get a withdrawal plan without executing (for preview/confirmation UIs).
56310
56663
  */
56311
- async planWithdraw(params) {
56312
- return this.sdk.withdraw.plan({
56313
- chainId: this.chainId,
56314
- poolAddress: this.poolAddress,
56315
- withdrawals: params.withdrawals
56316
- });
56664
+ async planWithdraw(params, account) {
56665
+ return this.sdk.withdraw.plan(
56666
+ {
56667
+ chainId: this.chainId,
56668
+ poolAddress: this.poolAddress,
56669
+ withdrawals: params.withdrawals
56670
+ },
56671
+ account
56672
+ );
56317
56673
  }
56318
56674
  /** 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
- });
56675
+ async executeWithdraw(plans, overrides) {
56676
+ return this.sdk.withdraw.execute(
56677
+ plans,
56678
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56679
+ overrides
56680
+ );
56324
56681
  }
56325
56682
  /** Wait for a transfer or withdrawal to be confirmed on-chain. */
56326
56683
  async confirmTransaction(relayId) {
@@ -56331,28 +56688,28 @@ var UnlinkWallet = class _UnlinkWallet {
56331
56688
  * Get balance for a specific token (defaults to all tokens if no token specified).
56332
56689
  * @param token Token address. If omitted, returns balance for all tokens via getBalances().
56333
56690
  */
56334
- async getBalance(token) {
56335
- return this.sdk.balances.get(this.chainId, token);
56691
+ async getBalance(token, overrides) {
56692
+ return this.sdk.balances.get(this.chainId, token, overrides);
56336
56693
  }
56337
56694
  /** Get balances for all tokens. */
56338
- async getBalances() {
56339
- return this.sdk.balances.list(this.chainId);
56695
+ async getBalances(overrides) {
56696
+ return this.sdk.balances.list(this.chainId, overrides);
56340
56697
  }
56341
56698
  /** Get transaction history. */
56342
- async getHistory(options) {
56343
- return this.sdk.history.list(this.chainId, options);
56699
+ async getHistory(options, overrides) {
56700
+ return this.sdk.history.list(this.chainId, options, overrides);
56344
56701
  }
56345
- /** Get UTXO notes for the active account. */
56346
- async getNotes() {
56347
- return this.sdk.notes.list(this.chainId);
56702
+ /** Get UTXO notes for the active account (or override account). */
56703
+ async getNotes(overrides) {
56704
+ return this.sdk.notes.list(this.chainId, overrides);
56348
56705
  }
56349
56706
  // ===== Sync =====
56350
56707
  /**
56351
56708
  * Sync notes from the blockchain.
56352
56709
  * Automatically resolves the active account (no need to pass it).
56353
56710
  */
56354
- async sync(options) {
56355
- const account = await this.requireActiveAccount();
56711
+ async sync(options, overrides) {
56712
+ const account = overrides?.account ?? await this.requireActiveAccount();
56356
56713
  return this.sdk.sync.syncChain(this.chainId, account, options);
56357
56714
  }
56358
56715
  /** Start auto-sync at the given interval (default: 5000ms). */
@@ -56429,6 +56786,31 @@ var UnlinkWallet = class _UnlinkWallet {
56429
56786
  return this.sdk.burner.getBalance(address);
56430
56787
  }
56431
56788
  };
56789
+ // ===== Adapter =====
56790
+ /**
56791
+ * Private DeFi adapter operations.
56792
+ * chainId/poolAddress are injected automatically.
56793
+ */
56794
+ adapter = {
56795
+ /**
56796
+ * Execute an atomic unshield -> call(s) -> reshield flow through an adapter.
56797
+ */
56798
+ execute: (params, opts, overrides) => {
56799
+ return this.sdk.adapter.execute(
56800
+ {
56801
+ chainId: this.chainId,
56802
+ poolAddress: this.poolAddress,
56803
+ adapterAddress: params.adapterAddress,
56804
+ inputs: params.inputs,
56805
+ calls: params.calls,
56806
+ reshields: params.reshields,
56807
+ deadline: params.deadline
56808
+ },
56809
+ opts,
56810
+ overrides
56811
+ );
56812
+ }
56813
+ };
56432
56814
  // ===== Advanced =====
56433
56815
  /**
56434
56816
  * Advanced escape hatch for raw JoinSplit transaction building.
@@ -56591,8 +56973,8 @@ function UnlinkProvider({
56591
56973
  setState((prev2) => ({
56592
56974
  ...prev2,
56593
56975
  accounts,
56594
- activeAccount,
56595
- activeAccountIndex
56976
+ activeAccount: activeAccount ?? prev2.activeAccount,
56977
+ activeAccountIndex: activeAccountIndex ?? prev2.activeAccountIndex
56596
56978
  }));
56597
56979
  } catch (err) {
56598
56980
  console.error("[UnlinkProvider] refreshAccounts error", err);