@unlink-xyz/core 0.1.7-canary.252b8ea → 0.1.7-canary.74fbd72

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.
@@ -55222,6 +55222,9 @@ function resolveWalletProverConfig(prover) {
55222
55222
  }
55223
55223
  return void 0;
55224
55224
  }
55225
+ function formatWithdrawalRecipient(npk) {
55226
+ return `0x${npk.toString(16).padStart(40, "0")}`.toLowerCase();
55227
+ }
55225
55228
  function createEventBus() {
55226
55229
  const listeners = /* @__PURE__ */ new Set();
55227
55230
  return {
@@ -55740,6 +55743,108 @@ function createWalletSDK(deps, options) {
55740
55743
  async send(params, overrides) {
55741
55744
  const plans = await this.plan(params, overrides?.account);
55742
55745
  return this.execute(plans, params, overrides);
55746
+ },
55747
+ async prove(plans, params, overrides) {
55748
+ const acct = overrides?.account ?? await requireActiveAccount();
55749
+ const signer = overrides?.signer ?? requireSigner(acct);
55750
+ const transactions = plans.map((plan) => ({
55751
+ token: plan.token,
55752
+ inputs: plan.inputs.map((note) => ({
55753
+ index: note.index
55754
+ })),
55755
+ outputs: plan.outputNotes
55756
+ }));
55757
+ const transactResult = await transact(
55758
+ stateStore,
55759
+ {
55760
+ account: acct,
55761
+ signer,
55762
+ chainId: params.chainId,
55763
+ poolAddress: params.poolAddress,
55764
+ transactions
55765
+ },
55766
+ { ...txOpts, skipBroadcast: true, persistJob: false }
55767
+ );
55768
+ return {
55769
+ plans,
55770
+ chainId: params.chainId,
55771
+ poolAddress: params.poolAddress,
55772
+ transactResult,
55773
+ provedAt: Date.now()
55774
+ };
55775
+ },
55776
+ async submit(prepared) {
55777
+ const relayId = generateRelayId("tx");
55778
+ const deltasByToken = /* @__PURE__ */ new Map();
55779
+ for (const plan of prepared.plans) {
55780
+ const recipientAmount = plan.outputNotes.filter((o) => o.owner === "recipient").reduce((sum, o) => sum + o.amount, 0n);
55781
+ const existing = deltasByToken.get(plan.token) ?? 0n;
55782
+ deltasByToken.set(plan.token, existing - recipientAmount);
55783
+ }
55784
+ const jobBase = {
55785
+ relayId,
55786
+ kind: "transfer",
55787
+ chainId: prepared.chainId,
55788
+ txHash: null,
55789
+ createdAt: Date.now(),
55790
+ timeoutMs: DEFAULT_JOB_TIMEOUT_MS,
55791
+ poolAddress: prepared.poolAddress,
55792
+ calldata: prepared.transactResult.calldata,
55793
+ transactions: prepared.transactResult.transactions.map((tx, i) => ({
55794
+ token: prepared.plans[i].token,
55795
+ nullifiers: tx.nullifiers,
55796
+ predictedCommitments: tx.predictedCommitments.map((hex2) => ({
55797
+ hex: hex2
55798
+ }))
55799
+ })),
55800
+ historyPreview: {
55801
+ kind: "Send",
55802
+ amounts: [...deltasByToken.entries()].map(([token, delta]) => ({
55803
+ token,
55804
+ delta: delta.toString()
55805
+ }))
55806
+ }
55807
+ };
55808
+ let submission;
55809
+ try {
55810
+ submission = await broadcasterClient.submitRelay({
55811
+ clientTxId: relayId,
55812
+ chainId: prepared.chainId,
55813
+ payload: {
55814
+ kind: "call_data",
55815
+ to: prepared.poolAddress,
55816
+ data: prepared.transactResult.calldata
55817
+ }
55818
+ });
55819
+ } catch (err) {
55820
+ const message = err instanceof Error ? err.message : "broadcaster submission failed";
55821
+ await stateStore.putJob({
55822
+ ...jobBase,
55823
+ status: "failed",
55824
+ lastCheckedAt: Date.now(),
55825
+ error: message
55826
+ });
55827
+ throw err;
55828
+ }
55829
+ if (!submission.accepted) {
55830
+ const message = submission.message ?? "broadcaster rejected";
55831
+ await stateStore.putJob({
55832
+ ...jobBase,
55833
+ status: "failed",
55834
+ lastCheckedAt: Date.now(),
55835
+ error: message
55836
+ });
55837
+ throw new CoreError(message);
55838
+ }
55839
+ await stateStore.putJob({
55840
+ ...jobBase,
55841
+ status: "broadcasting"
55842
+ });
55843
+ return {
55844
+ relayId,
55845
+ plans: prepared.plans,
55846
+ transactResult: { ...prepared.transactResult, relayId }
55847
+ };
55743
55848
  }
55744
55849
  },
55745
55850
  withdraw: {
@@ -55793,6 +55898,114 @@ function createWalletSDK(deps, options) {
55793
55898
  async send(params, overrides) {
55794
55899
  const plans = await this.plan(params, overrides?.account);
55795
55900
  return this.execute(plans, params, overrides);
55901
+ },
55902
+ async prove(plans, params, overrides) {
55903
+ const acct = overrides?.account ?? await requireActiveAccount();
55904
+ const signer = overrides?.signer ?? requireSigner(acct);
55905
+ const transactions = plans.map((plan) => ({
55906
+ token: plan.token,
55907
+ inputs: plan.inputs.map((note) => ({
55908
+ index: note.index
55909
+ })),
55910
+ outputs: plan.outputNotes,
55911
+ withdrawal: plan.withdrawal
55912
+ }));
55913
+ const transactResult = await transact(
55914
+ stateStore,
55915
+ {
55916
+ account: acct,
55917
+ signer,
55918
+ chainId: params.chainId,
55919
+ poolAddress: params.poolAddress,
55920
+ transactions
55921
+ },
55922
+ { ...txOpts, skipBroadcast: true, persistJob: false }
55923
+ );
55924
+ return {
55925
+ plans,
55926
+ chainId: params.chainId,
55927
+ poolAddress: params.poolAddress,
55928
+ transactResult,
55929
+ provedAt: Date.now()
55930
+ };
55931
+ },
55932
+ async submit(prepared) {
55933
+ const relayId = generateRelayId("tx");
55934
+ const deltasByToken = /* @__PURE__ */ new Map();
55935
+ for (const plan of prepared.plans) {
55936
+ const existing = deltasByToken.get(plan.token) ?? 0n;
55937
+ deltasByToken.set(plan.token, existing - plan.withdrawal.amount);
55938
+ }
55939
+ const jobBase = {
55940
+ relayId,
55941
+ kind: "withdraw",
55942
+ chainId: prepared.chainId,
55943
+ txHash: null,
55944
+ createdAt: Date.now(),
55945
+ timeoutMs: DEFAULT_JOB_TIMEOUT_MS,
55946
+ poolAddress: prepared.poolAddress,
55947
+ calldata: prepared.transactResult.calldata,
55948
+ transactions: prepared.transactResult.transactions.map((tx, i) => ({
55949
+ token: prepared.plans[i].token,
55950
+ nullifiers: tx.nullifiers,
55951
+ predictedCommitments: tx.predictedCommitments.map((hex2) => ({
55952
+ hex: hex2
55953
+ })),
55954
+ withdrawal: {
55955
+ amount: prepared.plans[i].withdrawal.amount.toString(),
55956
+ recipient: formatWithdrawalRecipient(
55957
+ prepared.plans[i].withdrawal.npk
55958
+ )
55959
+ }
55960
+ })),
55961
+ historyPreview: {
55962
+ kind: "Withdraw",
55963
+ amounts: [...deltasByToken.entries()].map(([token, delta]) => ({
55964
+ token,
55965
+ delta: delta.toString()
55966
+ }))
55967
+ }
55968
+ };
55969
+ let submission;
55970
+ try {
55971
+ submission = await broadcasterClient.submitRelay({
55972
+ clientTxId: relayId,
55973
+ chainId: prepared.chainId,
55974
+ payload: {
55975
+ kind: "call_data",
55976
+ to: prepared.poolAddress,
55977
+ data: prepared.transactResult.calldata
55978
+ }
55979
+ });
55980
+ } catch (err) {
55981
+ const message = err instanceof Error ? err.message : "broadcaster submission failed";
55982
+ await stateStore.putJob({
55983
+ ...jobBase,
55984
+ status: "failed",
55985
+ lastCheckedAt: Date.now(),
55986
+ error: message
55987
+ });
55988
+ throw err;
55989
+ }
55990
+ if (!submission.accepted) {
55991
+ const message = submission.message ?? "broadcaster rejected";
55992
+ await stateStore.putJob({
55993
+ ...jobBase,
55994
+ status: "failed",
55995
+ lastCheckedAt: Date.now(),
55996
+ error: message
55997
+ });
55998
+ throw new CoreError(message);
55999
+ }
56000
+ await stateStore.putJob({
56001
+ ...jobBase,
56002
+ status: "broadcasting"
56003
+ });
56004
+ return {
56005
+ relayId,
56006
+ plans: prepared.plans,
56007
+ transactResult: { ...prepared.transactResult, relayId }
56008
+ };
55796
56009
  }
55797
56010
  },
55798
56011
  events: {
@@ -55965,7 +56178,7 @@ var Unlink = class _Unlink {
55965
56178
  {
55966
56179
  chainId,
55967
56180
  gatewayUrl,
55968
- chainRpcUrl: config2.chainRpcUrl,
56181
+ chainRpcUrl: config2.chainRpcUrl ?? ("chain" in config2 ? DEFAULT_RPC_URLS[config2.chain] : void 0),
55969
56182
  prover: proverConfig,
55970
56183
  autoSync: config2.autoSync
55971
56184
  }
@@ -56070,6 +56283,40 @@ var Unlink = class _Unlink {
56070
56283
  overrides
56071
56284
  );
56072
56285
  }
56286
+ // ===== Three-Phase Flow (plan → prove → submit) =====
56287
+ /**
56288
+ * Generate ZK proofs for a pre-built send plan without broadcasting.
56289
+ * Returns a PreparedSend that can later be submitted via submitSend().
56290
+ *
56291
+ * Proofs remain valid as long as the input notes are not spent
56292
+ * in another transaction. Historical merkle roots are accepted forever.
56293
+ */
56294
+ async proveSend(plans, overrides) {
56295
+ return this.sdk.transfer.prove(
56296
+ plans,
56297
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56298
+ overrides
56299
+ );
56300
+ }
56301
+ /** Submit a pre-proved send to the broadcaster. */
56302
+ async submitSend(prepared) {
56303
+ return this.sdk.transfer.submit(prepared);
56304
+ }
56305
+ /**
56306
+ * Generate ZK proofs for a pre-built withdrawal plan without broadcasting.
56307
+ * Returns a PreparedWithdraw that can later be submitted via submitWithdraw().
56308
+ */
56309
+ async proveWithdraw(plans, overrides) {
56310
+ return this.sdk.withdraw.prove(
56311
+ plans,
56312
+ { chainId: this.chainId, poolAddress: this.poolAddress },
56313
+ overrides
56314
+ );
56315
+ }
56316
+ /** Submit a pre-proved withdrawal to the broadcaster. */
56317
+ async submitWithdraw(prepared) {
56318
+ return this.sdk.withdraw.submit(prepared);
56319
+ }
56073
56320
  /** Wait for a transfer or withdrawal to be confirmed on-chain. */
56074
56321
  async confirmTransaction(relayId) {
56075
56322
  return this.sdk.transact.reconcile(relayId);