@tokenflight/swap 0.0.0 → 0.0.2

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.
@@ -4783,7 +4783,7 @@ const styles$6 = {
4783
4783
  footerBrandAccent,
4784
4784
  footerArrow
4785
4785
  };
4786
- var _tmpl$$d = /* @__PURE__ */ template(`<span aria-label=TokenFlight role=img style=line-height:1>✈️`), _tmpl$3$8 = /* @__PURE__ */ template(`<div>`), _tmpl$4$8 = /* @__PURE__ */ template(`<img>`), _tmpl$5$8 = /* @__PURE__ */ template(`<img alt>`), _tmpl$6$6 = /* @__PURE__ */ template(`<a href=https://tokenflight.ai target=_blank rel="noopener noreferrer"part=fee-info data-testid=footer><span>Powered by</span><span>✈️</span><span>Token<span>Flight`);
4786
+ var _tmpl$$d = /* @__PURE__ */ template(`<span aria-label=TokenFlight role=img style=line-height:1>✈️`), _tmpl$3$8 = /* @__PURE__ */ template(`<div>`), _tmpl$4$8 = /* @__PURE__ */ template(`<img>`), _tmpl$5$8 = /* @__PURE__ */ template(`<img alt>`), _tmpl$6$7 = /* @__PURE__ */ template(`<a href=https://tokenflight.ai target=_blank rel="noopener noreferrer"part=fee-info data-testid=footer><span>Powered by</span><span>✈️</span><span>Token<span>Flight`);
4787
4787
  function chainIconUrl(apiEndpoint, chainId) {
4788
4788
  if (!apiEndpoint) return void 0;
4789
4789
  return `${apiEndpoint.replace(/\/$/, "")}/v1/chain/${chainId}/icon`;
@@ -4902,7 +4902,7 @@ function ChainDot(props) {
4902
4902
  }
4903
4903
  function PoweredByTokenFlight() {
4904
4904
  return (() => {
4905
- var _el$7 = _tmpl$6$6(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$0 = _el$9.nextSibling, _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling;
4905
+ var _el$7 = _tmpl$6$7(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$0 = _el$9.nextSibling, _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling;
4906
4906
  insert(_el$7, createComponent(external_link_default, {
4907
4907
  size: 12,
4908
4908
  get ["class"]() {
@@ -5613,7 +5613,7 @@ const actionStyles = {
5613
5613
  btnInner,
5614
5614
  spinner
5615
5615
  };
5616
- var _tmpl$$8 = /* @__PURE__ */ template(`<div part=button-primary data-testid=btn-primary>`), _tmpl$2$7 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary>`), _tmpl$3$6 = /* @__PURE__ */ template(`<button part=button-secondary data-testid=btn-connect>`), _tmpl$4$6 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary disabled><span><span>`), _tmpl$5$6 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-recipient>`), _tmpl$6$5 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary disabled style=opacity:0.6>`);
5616
+ var _tmpl$$8 = /* @__PURE__ */ template(`<div part=button-primary data-testid=btn-primary>`), _tmpl$2$7 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary>`), _tmpl$3$6 = /* @__PURE__ */ template(`<button part=button-secondary data-testid=btn-connect>`), _tmpl$4$6 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary disabled><span><span>`), _tmpl$5$6 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-recipient>`), _tmpl$6$6 = /* @__PURE__ */ template(`<button part=button-primary data-testid=btn-primary disabled style=opacity:0.6>`);
5617
5617
  function ActionButton(props) {
5618
5618
  return createComponent(Switch, {
5619
5619
  get children() {
@@ -5691,7 +5691,7 @@ function ActionButton(props) {
5691
5691
  return props.insufficientBalance;
5692
5692
  },
5693
5693
  get children() {
5694
- var _el$8 = _tmpl$6$5();
5694
+ var _el$8 = _tmpl$6$6();
5695
5695
  insert(_el$8, () => t("error.insufficientBalance"));
5696
5696
  createRenderEffect(() => className(_el$8, actionStyles.btnPrimary));
5697
5697
  return _el$8;
@@ -5712,7 +5712,7 @@ function ActionButton(props) {
5712
5712
  return props.phase === "idle" || props.phase === "quoting" || props.phase === "quoted";
5713
5713
  },
5714
5714
  get children() {
5715
- var _el$0 = _tmpl$6$5();
5715
+ var _el$0 = _tmpl$6$6();
5716
5716
  insert(_el$0, () => t("swap.reviewSwap"));
5717
5717
  createRenderEffect(() => className(_el$0, actionStyles.btnPrimary));
5718
5718
  return _el$0;
@@ -5759,6 +5759,8 @@ function shortenTxHash(hash) {
5759
5759
  const progress = "tf-5835df";
5760
5760
  const header$4 = "tf-9322ae";
5761
5761
  const tokenCol = "tf-7d5519";
5762
+ const tokenColFrom = "tf-0b8d30";
5763
+ const tokenColInner = "tf-bfbd0b";
5762
5764
  const tokenIconWrap$2 = "tf-7e8fdf";
5763
5765
  const chainBadge = "tf-37f3cf";
5764
5766
  const tokenInfo = "tf-9401fd";
@@ -5794,6 +5796,8 @@ const styles$3 = {
5794
5796
  progress,
5795
5797
  header: header$4,
5796
5798
  tokenCol,
5799
+ tokenColFrom,
5800
+ tokenColInner,
5797
5801
  tokenIconWrap: tokenIconWrap$2,
5798
5802
  chainBadge,
5799
5803
  tokenInfo,
@@ -5826,7 +5830,15 @@ const styles$3 = {
5826
5830
  retryHidden,
5827
5831
  retryBtn
5828
5832
  };
5829
- var _tmpl$$7 = /* @__PURE__ */ template(`<div><div><div><div></div></div><div><div></div><span></span></div></div><div></div><div><div><div></div></div><div><div></div><span>`), _tmpl$2$6 = /* @__PURE__ */ template(`<img>`), _tmpl$3$5 = /* @__PURE__ */ template(`<div>`), _tmpl$4$5 = /* @__PURE__ */ template(`<div><button>`), _tmpl$5$5 = /* @__PURE__ */ template(`<a target=_blank rel="noopener noreferrer"> `), _tmpl$6$4 = /* @__PURE__ */ template(`<button>`), _tmpl$7$4 = /* @__PURE__ */ template(`<div><div>`), _tmpl$8$4 = /* @__PURE__ */ template(`<div part=progress><div>`), _tmpl$9$4 = /* @__PURE__ */ template(`<div><div></div><div><div></div><div><span>`), _tmpl$0$3 = /* @__PURE__ */ template(`<span style=font-size:14px>!`), _tmpl$1$3 = /* @__PURE__ */ template(`<span>`);
5833
+ var _tmpl$$7 = /* @__PURE__ */ template(`<div><div><div><div><div></div></div><div><div></div><span></span></div></div></div><div></div><div><div><div><div></div></div><div><div></div><span>`), _tmpl$2$6 = /* @__PURE__ */ template(`<img>`), _tmpl$3$5 = /* @__PURE__ */ template(`<div>`), _tmpl$4$5 = /* @__PURE__ */ template(`<div><button>`), _tmpl$5$5 = /* @__PURE__ */ template(`<a target=_blank rel="noopener noreferrer"> `), _tmpl$6$5 = /* @__PURE__ */ template(`<button>`), _tmpl$7$4 = /* @__PURE__ */ template(`<div><div>`), _tmpl$8$4 = /* @__PURE__ */ template(`<div part=progress><div>`), _tmpl$9$4 = /* @__PURE__ */ template(`<div><div></div><div><div></div><div><span>`), _tmpl$0$3 = /* @__PURE__ */ template(`<span style=font-size:14px>!`), _tmpl$1$3 = /* @__PURE__ */ template(`<span>`);
5834
+ function autoScale(el) {
5835
+ el.style.transform = "";
5836
+ if (el.scrollWidth > el.clientWidth) {
5837
+ const scale = el.clientWidth / el.scrollWidth;
5838
+ el.style.transform = `scale(${scale})`;
5839
+ el.style.transformOrigin = "left";
5840
+ }
5841
+ }
5830
5842
  function OrderProgress(props) {
5831
5843
  const fromChainName = () => props.fromToken ? getChainName(props.fromToken.chainId, props.chainMap) : "";
5832
5844
  const toChainName = () => props.toToken ? getChainName(props.toToken.chainId, props.chainMap) : "";
@@ -5970,15 +5982,15 @@ function OrderProgress(props) {
5970
5982
  return txHash && chainId ? getExplorerTxUrl(chainId, txHash, props.chainMap) : null;
5971
5983
  };
5972
5984
  return (() => {
5973
- var _el$ = _tmpl$8$4(), _el$16 = _el$.firstChild;
5985
+ var _el$ = _tmpl$8$4(), _el$18 = _el$.firstChild;
5974
5986
  insert(_el$, createComponent(Show, {
5975
5987
  get when() {
5976
5988
  return memo(() => !!props.fromToken)() && props.toToken;
5977
5989
  },
5978
5990
  get children() {
5979
5991
  return [(() => {
5980
- var _el$2 = _tmpl$$7(), _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.firstChild, _el$6 = _el$4.nextSibling, _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling, _el$9 = _el$3.nextSibling, _el$0 = _el$9.nextSibling, _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$11 = _el$1.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling;
5981
- insert(_el$4, createComponent(TokenIcon, {
5992
+ var _el$2 = _tmpl$$7(), _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$5.nextSibling, _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$0 = _el$3.nextSibling, _el$1 = _el$0.nextSibling, _el$10 = _el$1.firstChild, _el$11 = _el$10.firstChild, _el$12 = _el$11.firstChild, _el$13 = _el$11.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.nextSibling;
5993
+ insert(_el$5, createComponent(TokenIcon, {
5982
5994
  get symbol() {
5983
5995
  return props.fromToken.symbol ?? "?";
5984
5996
  },
@@ -5987,15 +5999,20 @@ function OrderProgress(props) {
5987
5999
  get logoURI() {
5988
6000
  return props.fromToken.logoURI;
5989
6001
  }
5990
- }), _el$5);
5991
- insert(_el$5, createComponent(ChainDot, {
6002
+ }), _el$6);
6003
+ insert(_el$6, createComponent(ChainDot, {
5992
6004
  color: null,
5993
6005
  size: 14,
5994
6006
  get iconUrl() {
5995
6007
  return chainIconUrl(props.apiEndpoint, props.fromToken.chainId);
5996
6008
  }
5997
6009
  }));
5998
- insert(_el$7, createComponent(Show, {
6010
+ use((el) => createEffect(() => {
6011
+ void props.inputAmount;
6012
+ void props.fromToken;
6013
+ autoScale(el);
6014
+ }), _el$8);
6015
+ insert(_el$8, createComponent(Show, {
5999
6016
  get when() {
6000
6017
  return props.inputAmount;
6001
6018
  },
@@ -6008,12 +6025,12 @@ function OrderProgress(props) {
6008
6025
  }), " "];
6009
6026
  }
6010
6027
  }), null);
6011
- insert(_el$7, () => props.fromToken.symbol ?? "", null);
6012
- insert(_el$8, fromChainName);
6013
- insert(_el$9, createComponent(arrow_right_default, {
6028
+ insert(_el$8, () => props.fromToken.symbol ?? "", null);
6029
+ insert(_el$9, fromChainName);
6030
+ insert(_el$0, createComponent(arrow_right_default, {
6014
6031
  size: 14
6015
6032
  }));
6016
- insert(_el$1, createComponent(TokenIcon, {
6033
+ insert(_el$11, createComponent(TokenIcon, {
6017
6034
  get symbol() {
6018
6035
  return props.toToken.symbol ?? "?";
6019
6036
  },
@@ -6022,15 +6039,20 @@ function OrderProgress(props) {
6022
6039
  get logoURI() {
6023
6040
  return props.toToken.logoURI;
6024
6041
  }
6025
- }), _el$10);
6026
- insert(_el$10, createComponent(ChainDot, {
6042
+ }), _el$12);
6043
+ insert(_el$12, createComponent(ChainDot, {
6027
6044
  color: null,
6028
6045
  size: 14,
6029
6046
  get iconUrl() {
6030
6047
  return chainIconUrl(props.apiEndpoint, props.toToken.chainId);
6031
6048
  }
6032
6049
  }));
6033
- insert(_el$12, createComponent(Show, {
6050
+ use((el) => createEffect(() => {
6051
+ void props.outputAmount;
6052
+ void props.toToken;
6053
+ autoScale(el);
6054
+ }), _el$14);
6055
+ insert(_el$14, createComponent(Show, {
6034
6056
  get when() {
6035
6057
  return props.outputAmount;
6036
6058
  },
@@ -6043,10 +6065,10 @@ function OrderProgress(props) {
6043
6065
  }), " "];
6044
6066
  }
6045
6067
  }), null);
6046
- insert(_el$12, () => props.toToken.symbol ?? "", null);
6047
- insert(_el$13, toChainName);
6068
+ insert(_el$14, () => props.toToken.symbol ?? "", null);
6069
+ insert(_el$15, toChainName);
6048
6070
  createRenderEffect((_p$) => {
6049
- var _v$ = styles$3.header, _v$2 = styles$3.tokenCol, _v$3 = styles$3.tokenIconWrap, _v$4 = styles$3.chainBadge, _v$5 = styles$3.tokenInfo, _v$6 = styles$3.tokenAmount, _v$7 = styles$3.tokenChain, _v$8 = styles$3.arrow, _v$9 = styles$3.tokenCol, _v$0 = styles$3.tokenIconWrap, _v$1 = styles$3.chainBadge, _v$10 = styles$3.tokenInfo, _v$11 = styles$3.tokenAmount, _v$12 = styles$3.tokenChain;
6071
+ var _v$ = styles$3.header, _v$2 = `${styles$3.tokenCol} ${styles$3.tokenColFrom}`, _v$3 = styles$3.tokenColInner, _v$4 = styles$3.tokenIconWrap, _v$5 = styles$3.chainBadge, _v$6 = styles$3.tokenInfo, _v$7 = styles$3.tokenAmount, _v$8 = styles$3.tokenChain, _v$9 = styles$3.arrow, _v$0 = styles$3.tokenCol, _v$1 = styles$3.tokenColInner, _v$10 = styles$3.tokenIconWrap, _v$11 = styles$3.chainBadge, _v$12 = styles$3.tokenInfo, _v$13 = styles$3.tokenAmount, _v$14 = styles$3.tokenChain;
6050
6072
  _v$ !== _p$.e && className(_el$2, _p$.e = _v$);
6051
6073
  _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2);
6052
6074
  _v$3 !== _p$.a && className(_el$4, _p$.a = _v$3);
@@ -6061,6 +6083,8 @@ function OrderProgress(props) {
6061
6083
  _v$10 !== _p$.u && className(_el$11, _p$.u = _v$10);
6062
6084
  _v$11 !== _p$.c && className(_el$12, _p$.c = _v$11);
6063
6085
  _v$12 !== _p$.w && className(_el$13, _p$.w = _v$12);
6086
+ _v$13 !== _p$.m && className(_el$14, _p$.m = _v$13);
6087
+ _v$14 !== _p$.f && className(_el$15, _p$.f = _v$14);
6064
6088
  return _p$;
6065
6089
  }, {
6066
6090
  e: void 0,
@@ -6076,7 +6100,9 @@ function OrderProgress(props) {
6076
6100
  l: void 0,
6077
6101
  u: void 0,
6078
6102
  c: void 0,
6079
- w: void 0
6103
+ w: void 0,
6104
+ m: void 0,
6105
+ f: void 0
6080
6106
  });
6081
6107
  return _el$2;
6082
6108
  })(), createComponent(Show, {
@@ -6084,37 +6110,37 @@ function OrderProgress(props) {
6084
6110
  return props.providerName;
6085
6111
  },
6086
6112
  get children() {
6087
- var _el$14 = _tmpl$3$5();
6088
- insert(_el$14, createComponent(Show, {
6113
+ var _el$16 = _tmpl$3$5();
6114
+ insert(_el$16, createComponent(Show, {
6089
6115
  get when() {
6090
6116
  return props.providerIcon;
6091
6117
  },
6092
6118
  get children() {
6093
- var _el$15 = _tmpl$2$6();
6119
+ var _el$17 = _tmpl$2$6();
6094
6120
  createRenderEffect((_p$) => {
6095
- var _v$13 = props.providerIcon, _v$14 = props.providerName, _v$15 = styles$3.viaIcon;
6096
- _v$13 !== _p$.e && setAttribute(_el$15, "src", _p$.e = _v$13);
6097
- _v$14 !== _p$.t && setAttribute(_el$15, "alt", _p$.t = _v$14);
6098
- _v$15 !== _p$.a && className(_el$15, _p$.a = _v$15);
6121
+ var _v$15 = props.providerIcon, _v$16 = props.providerName, _v$17 = styles$3.viaIcon;
6122
+ _v$15 !== _p$.e && setAttribute(_el$17, "src", _p$.e = _v$15);
6123
+ _v$16 !== _p$.t && setAttribute(_el$17, "alt", _p$.t = _v$16);
6124
+ _v$17 !== _p$.a && className(_el$17, _p$.a = _v$17);
6099
6125
  return _p$;
6100
6126
  }, {
6101
6127
  e: void 0,
6102
6128
  t: void 0,
6103
6129
  a: void 0
6104
6130
  });
6105
- return _el$15;
6131
+ return _el$17;
6106
6132
  }
6107
6133
  }), null);
6108
- insert(_el$14, () => t("tracking.via", {
6134
+ insert(_el$16, () => t("tracking.via", {
6109
6135
  provider: props.providerName
6110
6136
  }), null);
6111
- createRenderEffect(() => className(_el$14, styles$3.via));
6112
- return _el$14;
6137
+ createRenderEffect(() => className(_el$16, styles$3.via));
6138
+ return _el$16;
6113
6139
  }
6114
6140
  })];
6115
6141
  }
6116
- }), _el$16);
6117
- insert(_el$16, createComponent(For, {
6142
+ }), _el$18);
6143
+ insert(_el$18, createComponent(For, {
6118
6144
  get each() {
6119
6145
  return steps2();
6120
6146
  },
@@ -6126,52 +6152,52 @@ function OrderProgress(props) {
6126
6152
  return `${styles$3.step} ${styles$3.pending}`;
6127
6153
  };
6128
6154
  return (() => {
6129
- var _el$24 = _tmpl$9$4(), _el$25 = _el$24.firstChild, _el$26 = _el$25.nextSibling, _el$27 = _el$26.firstChild, _el$28 = _el$27.nextSibling, _el$29 = _el$28.firstChild;
6130
- insert(_el$25, (() => {
6155
+ var _el$26 = _tmpl$9$4(), _el$27 = _el$26.firstChild, _el$28 = _el$27.nextSibling, _el$29 = _el$28.firstChild, _el$30 = _el$29.nextSibling, _el$31 = _el$30.firstChild;
6156
+ insert(_el$27, (() => {
6131
6157
  var _c$3 = memo(() => !!(step2.status === "completed" && !step2.isWarning));
6132
6158
  return () => _c$3() ? createComponent(check_default, {
6133
6159
  size: 14
6134
6160
  }) : memo(() => !!(step2.status === "active" && step2.isWarning))() ? _tmpl$0$3() : memo(() => step2.status === "active")() ? (() => {
6135
- var _el$33 = _tmpl$3$5();
6136
- createRenderEffect(() => className(_el$33, styles$3.stepSpinner));
6137
- return _el$33;
6138
- })() : memo(() => !!(step2.isWarning && step2.status === "completed"))() ? _tmpl$0$3() : (() => {
6139
- var _el$35 = _tmpl$1$3();
6140
- insert(_el$35, () => index() + 1);
6161
+ var _el$35 = _tmpl$3$5();
6162
+ createRenderEffect(() => className(_el$35, styles$3.stepSpinner));
6141
6163
  return _el$35;
6164
+ })() : memo(() => !!(step2.isWarning && step2.status === "completed"))() ? _tmpl$0$3() : (() => {
6165
+ var _el$37 = _tmpl$1$3();
6166
+ insert(_el$37, () => index() + 1);
6167
+ return _el$37;
6142
6168
  })();
6143
6169
  })());
6144
- insert(_el$27, () => step2.title);
6145
- insert(_el$29, () => step2.subtitle);
6146
- insert(_el$28, createComponent(Show, {
6170
+ insert(_el$29, () => step2.title);
6171
+ insert(_el$31, () => step2.subtitle);
6172
+ insert(_el$30, createComponent(Show, {
6147
6173
  get when() {
6148
6174
  return step2.explorerUrl;
6149
6175
  },
6150
6176
  get children() {
6151
- var _el$30 = _tmpl$5$5(), _el$31 = _el$30.firstChild;
6152
- insert(_el$30, () => t("tracking.viewOnExplorer"), _el$31);
6153
- insert(_el$30, createComponent(external_link_default, {
6177
+ var _el$32 = _tmpl$5$5(), _el$33 = _el$32.firstChild;
6178
+ insert(_el$32, () => t("tracking.viewOnExplorer"), _el$33);
6179
+ insert(_el$32, createComponent(external_link_default, {
6154
6180
  size: 10
6155
6181
  }), null);
6156
6182
  createRenderEffect((_p$) => {
6157
- var _v$24 = step2.explorerUrl, _v$25 = styles$3.stepExplorer;
6158
- _v$24 !== _p$.e && setAttribute(_el$30, "href", _p$.e = _v$24);
6159
- _v$25 !== _p$.t && className(_el$30, _p$.t = _v$25);
6183
+ var _v$26 = step2.explorerUrl, _v$27 = styles$3.stepExplorer;
6184
+ _v$26 !== _p$.e && setAttribute(_el$32, "href", _p$.e = _v$26);
6185
+ _v$27 !== _p$.t && className(_el$32, _p$.t = _v$27);
6160
6186
  return _p$;
6161
6187
  }, {
6162
6188
  e: void 0,
6163
6189
  t: void 0
6164
6190
  });
6165
- return _el$30;
6191
+ return _el$32;
6166
6192
  }
6167
6193
  }), null);
6168
6194
  createRenderEffect((_p$) => {
6169
- var _v$26 = stepClass(), _v$27 = `${styles$3.stepIcon} ${step2.isWarning && (step2.status === "completed" || step2.status === "active") ? styles$3.stepIconWarning : step2.status === "completed" ? styles$3.stepIconCompleted : step2.status === "active" ? styles$3.stepIconActive : styles$3.stepIconPending}`, _v$28 = styles$3.stepBody, _v$29 = styles$3.stepTitle, _v$30 = styles$3.stepSubtitle;
6170
- _v$26 !== _p$.e && className(_el$24, _p$.e = _v$26);
6171
- _v$27 !== _p$.t && className(_el$25, _p$.t = _v$27);
6172
- _v$28 !== _p$.a && className(_el$26, _p$.a = _v$28);
6173
- _v$29 !== _p$.o && className(_el$27, _p$.o = _v$29);
6174
- _v$30 !== _p$.i && className(_el$28, _p$.i = _v$30);
6195
+ var _v$28 = stepClass(), _v$29 = `${styles$3.stepIcon} ${step2.isWarning && (step2.status === "completed" || step2.status === "active") ? styles$3.stepIconWarning : step2.status === "completed" ? styles$3.stepIconCompleted : step2.status === "active" ? styles$3.stepIconActive : styles$3.stepIconPending}`, _v$30 = styles$3.stepBody, _v$31 = styles$3.stepTitle, _v$32 = styles$3.stepSubtitle;
6196
+ _v$28 !== _p$.e && className(_el$26, _p$.e = _v$28);
6197
+ _v$29 !== _p$.t && className(_el$27, _p$.t = _v$29);
6198
+ _v$30 !== _p$.a && className(_el$28, _p$.a = _v$30);
6199
+ _v$31 !== _p$.o && className(_el$29, _p$.o = _v$31);
6200
+ _v$32 !== _p$.i && className(_el$30, _p$.i = _v$32);
6175
6201
  return _p$;
6176
6202
  }, {
6177
6203
  e: void 0,
@@ -6180,7 +6206,7 @@ function OrderProgress(props) {
6180
6206
  o: void 0,
6181
6207
  i: void 0
6182
6208
  });
6183
- return _el$24;
6209
+ return _el$26;
6184
6210
  })();
6185
6211
  }
6186
6212
  }));
@@ -6189,19 +6215,19 @@ function OrderProgress(props) {
6189
6215
  return props.onRetry;
6190
6216
  },
6191
6217
  get children() {
6192
- var _el$17 = _tmpl$4$5(), _el$18 = _el$17.firstChild;
6193
- addEventListener(_el$18, "click", props.onRetry);
6194
- insert(_el$18, () => t("tracking.retry"));
6218
+ var _el$19 = _tmpl$4$5(), _el$20 = _el$19.firstChild;
6219
+ addEventListener(_el$20, "click", props.onRetry);
6220
+ insert(_el$20, () => t("tracking.retry"));
6195
6221
  createRenderEffect((_p$) => {
6196
- var _v$16 = `${styles$3.retry}${props.executionError ? "" : ` ${styles$3.retryHidden}`}`, _v$17 = styles$3.retryBtn;
6197
- _v$16 !== _p$.e && className(_el$17, _p$.e = _v$16);
6198
- _v$17 !== _p$.t && className(_el$18, _p$.t = _v$17);
6222
+ var _v$18 = `${styles$3.retry}${props.executionError ? "" : ` ${styles$3.retryHidden}`}`, _v$19 = styles$3.retryBtn;
6223
+ _v$18 !== _p$.e && className(_el$19, _p$.e = _v$18);
6224
+ _v$19 !== _p$.t && className(_el$20, _p$.t = _v$19);
6199
6225
  return _p$;
6200
6226
  }, {
6201
6227
  e: void 0,
6202
6228
  t: void 0
6203
6229
  });
6204
- return _el$17;
6230
+ return _el$19;
6205
6231
  }
6206
6232
  }), null);
6207
6233
  insert(_el$, createComponent(Show, {
@@ -6209,64 +6235,64 @@ function OrderProgress(props) {
6209
6235
  return isTerminalFailure();
6210
6236
  },
6211
6237
  get children() {
6212
- var _el$19 = _tmpl$7$4(), _el$20 = _el$19.firstChild;
6213
- insert(_el$20, (() => {
6238
+ var _el$21 = _tmpl$7$4(), _el$22 = _el$21.firstChild;
6239
+ insert(_el$22, (() => {
6214
6240
  var _c$ = memo(() => props.order?.status === "refunded");
6215
6241
  return () => _c$() ? t("failure.refundedSubtitle") : t("failure.subtitle");
6216
6242
  })());
6217
- insert(_el$19, createComponent(Show, {
6243
+ insert(_el$21, createComponent(Show, {
6218
6244
  get when() {
6219
6245
  return refundExplorerUrl();
6220
6246
  },
6221
6247
  get children() {
6222
- var _el$21 = _tmpl$5$5(), _el$22 = _el$21.firstChild;
6223
- insert(_el$21, () => t("failure.refundTx"), _el$22);
6224
- insert(_el$21, createComponent(external_link_default, {
6248
+ var _el$23 = _tmpl$5$5(), _el$24 = _el$23.firstChild;
6249
+ insert(_el$23, () => t("failure.refundTx"), _el$24);
6250
+ insert(_el$23, createComponent(external_link_default, {
6225
6251
  size: 10
6226
6252
  }), null);
6227
6253
  createRenderEffect((_p$) => {
6228
- var _v$18 = refundExplorerUrl(), _v$19 = styles$3.failureLink;
6229
- _v$18 !== _p$.e && setAttribute(_el$21, "href", _p$.e = _v$18);
6230
- _v$19 !== _p$.t && className(_el$21, _p$.t = _v$19);
6254
+ var _v$20 = refundExplorerUrl(), _v$21 = styles$3.failureLink;
6255
+ _v$20 !== _p$.e && setAttribute(_el$23, "href", _p$.e = _v$20);
6256
+ _v$21 !== _p$.t && className(_el$23, _p$.t = _v$21);
6231
6257
  return _p$;
6232
6258
  }, {
6233
6259
  e: void 0,
6234
6260
  t: void 0
6235
6261
  });
6236
- return _el$21;
6262
+ return _el$23;
6237
6263
  }
6238
6264
  }), null);
6239
- insert(_el$19, createComponent(Show, {
6265
+ insert(_el$21, createComponent(Show, {
6240
6266
  get when() {
6241
6267
  return props.onNewSwap;
6242
6268
  },
6243
6269
  get children() {
6244
- var _el$23 = _tmpl$6$4();
6245
- addEventListener(_el$23, "click", props.onNewSwap);
6246
- insert(_el$23, (() => {
6270
+ var _el$25 = _tmpl$6$5();
6271
+ addEventListener(_el$25, "click", props.onNewSwap);
6272
+ insert(_el$25, (() => {
6247
6273
  var _c$2 = memo(() => props.mode === "receive");
6248
6274
  return () => _c$2() ? t("success.newPurchase") : t("success.newSwap");
6249
6275
  })());
6250
- createRenderEffect(() => className(_el$23, styles$3.failureBtn));
6251
- return _el$23;
6276
+ createRenderEffect(() => className(_el$25, styles$3.failureBtn));
6277
+ return _el$25;
6252
6278
  }
6253
6279
  }), null);
6254
6280
  createRenderEffect((_p$) => {
6255
- var _v$20 = styles$3.failure, _v$21 = styles$3.failureMessage;
6256
- _v$20 !== _p$.e && className(_el$19, _p$.e = _v$20);
6257
- _v$21 !== _p$.t && className(_el$20, _p$.t = _v$21);
6281
+ var _v$22 = styles$3.failure, _v$23 = styles$3.failureMessage;
6282
+ _v$22 !== _p$.e && className(_el$21, _p$.e = _v$22);
6283
+ _v$23 !== _p$.t && className(_el$22, _p$.t = _v$23);
6258
6284
  return _p$;
6259
6285
  }, {
6260
6286
  e: void 0,
6261
6287
  t: void 0
6262
6288
  });
6263
- return _el$19;
6289
+ return _el$21;
6264
6290
  }
6265
6291
  }), null);
6266
6292
  createRenderEffect((_p$) => {
6267
- var _v$22 = styles$3.progress, _v$23 = styles$3.steps;
6268
- _v$22 !== _p$.e && className(_el$, _p$.e = _v$22);
6269
- _v$23 !== _p$.t && className(_el$16, _p$.t = _v$23);
6293
+ var _v$24 = styles$3.progress, _v$25 = styles$3.steps;
6294
+ _v$24 !== _p$.e && className(_el$, _p$.e = _v$24);
6295
+ _v$25 !== _p$.t && className(_el$18, _p$.t = _v$25);
6270
6296
  return _p$;
6271
6297
  }, {
6272
6298
  e: void 0,
@@ -6281,10 +6307,11 @@ const heroIcon = "tf-73631f";
6281
6307
  const title$2 = "tf-9e3a66";
6282
6308
  const subtitle = "tf-db06d4";
6283
6309
  const receivedCard = "tf-c9a5e1";
6284
- const receivedIcon = "tf-789d4e";
6310
+ const receivedIconWrap = "tf-7b3b5b";
6311
+ const receivedChainBadge = "tf-651299";
6285
6312
  const receivedAmount = "tf-f52291";
6286
6313
  const receivedSymbol = "tf-8cfc86";
6287
- const receivedChain = "tf-4f945b";
6314
+ const receivedChainName = "tf-5f768d";
6288
6315
  const journey = "tf-75f592";
6289
6316
  const journeyToggle = "tf-73910d";
6290
6317
  const journeyChevron = "tf-1afb0a";
@@ -6301,10 +6328,11 @@ const styles$2 = {
6301
6328
  title: title$2,
6302
6329
  subtitle,
6303
6330
  receivedCard,
6304
- receivedIcon,
6331
+ receivedIconWrap,
6332
+ receivedChainBadge,
6305
6333
  receivedAmount,
6306
6334
  receivedSymbol,
6307
- receivedChain,
6335
+ receivedChainName,
6308
6336
  journey,
6309
6337
  journeyToggle,
6310
6338
  "journeyToggle--open": "tf-ae94a0",
@@ -6317,7 +6345,7 @@ const styles$2 = {
6317
6345
  journeyLink,
6318
6346
  primaryBtn
6319
6347
  };
6320
- var _tmpl$$6 = /* @__PURE__ */ template(`<div>`), _tmpl$2$5 = /* @__PURE__ */ template(`<div><span></span><span>`), _tmpl$3$4 = /* @__PURE__ */ template(`<div><span></span><a target=_blank rel="noopener noreferrer"> `), _tmpl$4$4 = /* @__PURE__ */ template(`<div><button><span> <span style="font-family:'JetBrains Mono', monospace;font-weight:600;color:var(--tf-text)"> </span> </span><span>`), _tmpl$5$4 = /* @__PURE__ */ template(`<div part=success data-testid=success-page><div><div></div></div><div data-testid=success-title></div><div></div><div><div><span></span></div><div><span></span></div></div><button data-testid=success-primary-btn>`);
6348
+ var _tmpl$$6 = /* @__PURE__ */ template(`<div><div>`), _tmpl$2$5 = /* @__PURE__ */ template(`<div><span></span><span>`), _tmpl$3$4 = /* @__PURE__ */ template(`<div><span></span><a target=_blank rel="noopener noreferrer"> `), _tmpl$4$4 = /* @__PURE__ */ template(`<div>`), _tmpl$5$4 = /* @__PURE__ */ template(`<div><button><span> <span style=font-family:var(--tf-font-family-mono);font-weight:600;color:var(--tf-text)> </span> </span><span>`), _tmpl$6$4 = /* @__PURE__ */ template(`<div part=success data-testid=success-page><div><div></div></div><div data-testid=success-title></div><div></div><div><div><span></span><span></span></div></div><button data-testid=success-primary-btn>`);
6321
6349
  function TransactionComplete(props) {
6322
6350
  const [detailsOpen, setDetailsOpen] = createSignal(false);
6323
6351
  const receivedAmount2 = () => {
@@ -6354,7 +6382,7 @@ function TransactionComplete(props) {
6354
6382
  const fromChainName = () => getChainName(props.order.fromChainId, props.chainMap);
6355
6383
  const buttonLabel = () => props.mode === "receive" ? t("success.newPurchase") : t("success.newSwap");
6356
6384
  return (() => {
6357
- var _el$ = _tmpl$5$4(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling, _el$8 = _el$6.firstChild, _el$9 = _el$8.firstChild, _el$0 = _el$8.nextSibling, _el$1 = _el$0.firstChild, _el$36 = _el$6.nextSibling;
6385
+ var _el$ = _tmpl$6$4(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling, _el$9 = _el$6.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$36 = _el$6.nextSibling;
6358
6386
  insert(_el$3, createComponent(AirplaneLogo, {
6359
6387
  size: 28
6360
6388
  }));
@@ -6370,7 +6398,7 @@ function TransactionComplete(props) {
6370
6398
  return props.toToken;
6371
6399
  },
6372
6400
  get children() {
6373
- var _el$7 = _tmpl$$6();
6401
+ var _el$7 = _tmpl$$6(), _el$8 = _el$7.firstChild;
6374
6402
  insert(_el$7, createComponent(TokenIcon, {
6375
6403
  get symbol() {
6376
6404
  return props.toToken.symbol ?? "?";
@@ -6380,32 +6408,42 @@ function TransactionComplete(props) {
6380
6408
  get logoURI() {
6381
6409
  return props.toToken.logoURI;
6382
6410
  }
6411
+ }), _el$8);
6412
+ insert(_el$8, createComponent(ChainDot, {
6413
+ color: null,
6414
+ size: 14,
6415
+ get iconUrl() {
6416
+ return chainIconUrl(props.apiEndpoint, props.order.toChainId);
6417
+ }
6383
6418
  }));
6384
- createRenderEffect(() => className(_el$7, styles$2.receivedIcon));
6419
+ createRenderEffect((_p$) => {
6420
+ var _v$ = styles$2.receivedIconWrap, _v$2 = styles$2.receivedChainBadge;
6421
+ _v$ !== _p$.e && className(_el$7, _p$.e = _v$);
6422
+ _v$2 !== _p$.t && className(_el$8, _p$.t = _v$2);
6423
+ return _p$;
6424
+ }, {
6425
+ e: void 0,
6426
+ t: void 0
6427
+ });
6385
6428
  return _el$7;
6386
6429
  }
6387
- }), _el$8);
6388
- insert(_el$8, createComponent(SignificantNumber, {
6430
+ }), _el$9);
6431
+ insert(_el$9, createComponent(SignificantNumber, {
6389
6432
  get value() {
6390
6433
  return receivedAmount2();
6391
6434
  },
6392
6435
  digits: 8
6393
- }), _el$9);
6394
- insert(_el$9, () => props.toToken?.symbol ?? "");
6395
- insert(_el$0, createComponent(ChainDot, {
6396
- color: null,
6397
- size: 12,
6398
- get iconUrl() {
6399
- return chainIconUrl(props.apiEndpoint, props.order.toChainId);
6400
- }
6401
- }), _el$1);
6402
- insert(_el$1, toChainName);
6436
+ }), _el$0);
6437
+ insert(_el$0, () => props.toToken?.symbol ?? "");
6438
+ insert(_el$1, () => t("success.onChain", {
6439
+ chain: toChainName()
6440
+ }));
6403
6441
  insert(_el$, createComponent(Show, {
6404
6442
  get when() {
6405
6443
  return props.fromToken;
6406
6444
  },
6407
6445
  get children() {
6408
- var _el$10 = _tmpl$4$4(), _el$11 = _el$10.firstChild, _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$14 = _el$13.nextSibling, _el$15 = _el$14.firstChild;
6446
+ var _el$10 = _tmpl$5$4(), _el$11 = _el$10.firstChild, _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$14 = _el$13.nextSibling, _el$15 = _el$14.firstChild;
6409
6447
  _el$14.nextSibling;
6410
6448
  var _el$17 = _el$12.nextSibling;
6411
6449
  addEventListener(_el$11, "click", () => setDetailsOpen(!detailsOpen()));
@@ -6428,7 +6466,7 @@ function TransactionComplete(props) {
6428
6466
  return detailsOpen();
6429
6467
  },
6430
6468
  get children() {
6431
- var _el$18 = _tmpl$$6();
6469
+ var _el$18 = _tmpl$4$4();
6432
6470
  insert(_el$18, createComponent(Show, {
6433
6471
  get when() {
6434
6472
  return props.order.author;
@@ -6438,10 +6476,10 @@ function TransactionComplete(props) {
6438
6476
  insert(_el$20, () => t("success.sender"));
6439
6477
  insert(_el$21, () => truncateAddress(props.order.author));
6440
6478
  createRenderEffect((_p$) => {
6441
- var _v$ = styles$2.journeyRow, _v$2 = styles$2.journeyLabel, _v$3 = styles$2.journeyValue;
6442
- _v$ !== _p$.e && className(_el$19, _p$.e = _v$);
6443
- _v$2 !== _p$.t && className(_el$20, _p$.t = _v$2);
6444
- _v$3 !== _p$.a && className(_el$21, _p$.a = _v$3);
6479
+ var _v$3 = styles$2.journeyRow, _v$4 = styles$2.journeyLabel, _v$5 = styles$2.journeyValue;
6480
+ _v$3 !== _p$.e && className(_el$19, _p$.e = _v$3);
6481
+ _v$4 !== _p$.t && className(_el$20, _p$.t = _v$4);
6482
+ _v$5 !== _p$.a && className(_el$21, _p$.a = _v$5);
6445
6483
  return _p$;
6446
6484
  }, {
6447
6485
  e: void 0,
@@ -6460,10 +6498,10 @@ function TransactionComplete(props) {
6460
6498
  insert(_el$23, () => t("success.recipient"));
6461
6499
  insert(_el$24, () => truncateAddress(props.order.recipient));
6462
6500
  createRenderEffect((_p$) => {
6463
- var _v$4 = styles$2.journeyRow, _v$5 = styles$2.journeyLabel, _v$6 = styles$2.journeyValue;
6464
- _v$4 !== _p$.e && className(_el$22, _p$.e = _v$4);
6465
- _v$5 !== _p$.t && className(_el$23, _p$.t = _v$5);
6466
- _v$6 !== _p$.a && className(_el$24, _p$.a = _v$6);
6501
+ var _v$6 = styles$2.journeyRow, _v$7 = styles$2.journeyLabel, _v$8 = styles$2.journeyValue;
6502
+ _v$6 !== _p$.e && className(_el$22, _p$.e = _v$6);
6503
+ _v$7 !== _p$.t && className(_el$23, _p$.t = _v$7);
6504
+ _v$8 !== _p$.a && className(_el$24, _p$.a = _v$8);
6467
6505
  return _p$;
6468
6506
  }, {
6469
6507
  e: void 0,
@@ -6485,11 +6523,11 @@ function TransactionComplete(props) {
6485
6523
  size: 10
6486
6524
  }), null);
6487
6525
  createRenderEffect((_p$) => {
6488
- var _v$7 = styles$2.journeyRow, _v$8 = styles$2.journeyLabel, _v$9 = depositExplorerUrl(), _v$0 = styles$2.journeyLink;
6489
- _v$7 !== _p$.e && className(_el$25, _p$.e = _v$7);
6490
- _v$8 !== _p$.t && className(_el$26, _p$.t = _v$8);
6491
- _v$9 !== _p$.a && setAttribute(_el$27, "href", _p$.a = _v$9);
6492
- _v$0 !== _p$.o && className(_el$27, _p$.o = _v$0);
6526
+ var _v$9 = styles$2.journeyRow, _v$0 = styles$2.journeyLabel, _v$1 = depositExplorerUrl(), _v$10 = styles$2.journeyLink;
6527
+ _v$9 !== _p$.e && className(_el$25, _p$.e = _v$9);
6528
+ _v$0 !== _p$.t && className(_el$26, _p$.t = _v$0);
6529
+ _v$1 !== _p$.a && setAttribute(_el$27, "href", _p$.a = _v$1);
6530
+ _v$10 !== _p$.o && className(_el$27, _p$.o = _v$10);
6493
6531
  return _p$;
6494
6532
  }, {
6495
6533
  e: void 0,
@@ -6512,11 +6550,11 @@ function TransactionComplete(props) {
6512
6550
  size: 10
6513
6551
  }), null);
6514
6552
  createRenderEffect((_p$) => {
6515
- var _v$1 = styles$2.journeyRow, _v$10 = styles$2.journeyLabel, _v$11 = fillExplorerUrl(), _v$12 = styles$2.journeyLink;
6516
- _v$1 !== _p$.e && className(_el$29, _p$.e = _v$1);
6517
- _v$10 !== _p$.t && className(_el$30, _p$.t = _v$10);
6518
- _v$11 !== _p$.a && setAttribute(_el$31, "href", _p$.a = _v$11);
6519
- _v$12 !== _p$.o && className(_el$31, _p$.o = _v$12);
6553
+ var _v$11 = styles$2.journeyRow, _v$12 = styles$2.journeyLabel, _v$13 = fillExplorerUrl(), _v$14 = styles$2.journeyLink;
6554
+ _v$11 !== _p$.e && className(_el$29, _p$.e = _v$11);
6555
+ _v$12 !== _p$.t && className(_el$30, _p$.t = _v$12);
6556
+ _v$13 !== _p$.a && setAttribute(_el$31, "href", _p$.a = _v$13);
6557
+ _v$14 !== _p$.o && className(_el$31, _p$.o = _v$14);
6520
6558
  return _p$;
6521
6559
  }, {
6522
6560
  e: void 0,
@@ -6536,10 +6574,10 @@ function TransactionComplete(props) {
6536
6574
  insert(_el$34, () => t("success.provider"));
6537
6575
  insert(_el$35, () => props.providerName);
6538
6576
  createRenderEffect((_p$) => {
6539
- var _v$13 = styles$2.journeyRow, _v$14 = styles$2.journeyLabel, _v$15 = styles$2.journeyValue;
6540
- _v$13 !== _p$.e && className(_el$33, _p$.e = _v$13);
6541
- _v$14 !== _p$.t && className(_el$34, _p$.t = _v$14);
6542
- _v$15 !== _p$.a && className(_el$35, _p$.a = _v$15);
6577
+ var _v$15 = styles$2.journeyRow, _v$16 = styles$2.journeyLabel, _v$17 = styles$2.journeyValue;
6578
+ _v$15 !== _p$.e && className(_el$33, _p$.e = _v$15);
6579
+ _v$16 !== _p$.t && className(_el$34, _p$.t = _v$16);
6580
+ _v$17 !== _p$.a && className(_el$35, _p$.a = _v$17);
6543
6581
  return _p$;
6544
6582
  }, {
6545
6583
  e: void 0,
@@ -6554,10 +6592,10 @@ function TransactionComplete(props) {
6554
6592
  }
6555
6593
  }), null);
6556
6594
  createRenderEffect((_p$) => {
6557
- var _v$16 = styles$2.journey, _v$17 = `${styles$2.journeyToggle}${detailsOpen() ? ` ${styles$2["journeyToggle--open"]}` : ""}`, _v$18 = `${styles$2.journeyChevron}${detailsOpen() ? ` ${styles$2["journeyChevron--open"]}` : ""}`;
6558
- _v$16 !== _p$.e && className(_el$10, _p$.e = _v$16);
6559
- _v$17 !== _p$.t && className(_el$11, _p$.t = _v$17);
6560
- _v$18 !== _p$.a && className(_el$17, _p$.a = _v$18);
6595
+ var _v$18 = styles$2.journey, _v$19 = `${styles$2.journeyToggle}${detailsOpen() ? ` ${styles$2["journeyToggle--open"]}` : ""}`, _v$20 = `${styles$2.journeyChevron}${detailsOpen() ? ` ${styles$2["journeyChevron--open"]}` : ""}`;
6596
+ _v$18 !== _p$.e && className(_el$10, _p$.e = _v$18);
6597
+ _v$19 !== _p$.t && className(_el$11, _p$.t = _v$19);
6598
+ _v$20 !== _p$.a && className(_el$17, _p$.a = _v$20);
6561
6599
  return _p$;
6562
6600
  }, {
6563
6601
  e: void 0,
@@ -6570,17 +6608,17 @@ function TransactionComplete(props) {
6570
6608
  addEventListener(_el$36, "click", props.onNewSwap);
6571
6609
  insert(_el$36, buttonLabel);
6572
6610
  createRenderEffect((_p$) => {
6573
- var _v$19 = styles$2.page, _v$20 = styles$2.hero, _v$21 = styles$2.heroIcon, _v$22 = styles$2.title, _v$23 = styles$2.subtitle, _v$24 = styles$2.receivedCard, _v$25 = styles$2.receivedAmount, _v$26 = styles$2.receivedSymbol, _v$27 = styles$2.receivedChain, _v$28 = styles$2.primaryBtn;
6574
- _v$19 !== _p$.e && className(_el$, _p$.e = _v$19);
6575
- _v$20 !== _p$.t && className(_el$2, _p$.t = _v$20);
6576
- _v$21 !== _p$.a && className(_el$3, _p$.a = _v$21);
6577
- _v$22 !== _p$.o && className(_el$4, _p$.o = _v$22);
6578
- _v$23 !== _p$.i && className(_el$5, _p$.i = _v$23);
6579
- _v$24 !== _p$.n && className(_el$6, _p$.n = _v$24);
6580
- _v$25 !== _p$.s && className(_el$8, _p$.s = _v$25);
6581
- _v$26 !== _p$.h && className(_el$9, _p$.h = _v$26);
6582
- _v$27 !== _p$.r && className(_el$0, _p$.r = _v$27);
6583
- _v$28 !== _p$.d && className(_el$36, _p$.d = _v$28);
6611
+ var _v$21 = styles$2.page, _v$22 = styles$2.hero, _v$23 = styles$2.heroIcon, _v$24 = styles$2.title, _v$25 = styles$2.subtitle, _v$26 = styles$2.receivedCard, _v$27 = styles$2.receivedAmount, _v$28 = styles$2.receivedSymbol, _v$29 = styles$2.receivedChainName, _v$30 = styles$2.primaryBtn;
6612
+ _v$21 !== _p$.e && className(_el$, _p$.e = _v$21);
6613
+ _v$22 !== _p$.t && className(_el$2, _p$.t = _v$22);
6614
+ _v$23 !== _p$.a && className(_el$3, _p$.a = _v$23);
6615
+ _v$24 !== _p$.o && className(_el$4, _p$.o = _v$24);
6616
+ _v$25 !== _p$.i && className(_el$5, _p$.i = _v$25);
6617
+ _v$26 !== _p$.n && className(_el$6, _p$.n = _v$26);
6618
+ _v$27 !== _p$.s && className(_el$9, _p$.s = _v$27);
6619
+ _v$28 !== _p$.h && className(_el$0, _p$.h = _v$28);
6620
+ _v$29 !== _p$.r && className(_el$1, _p$.r = _v$29);
6621
+ _v$30 !== _p$.d && className(_el$36, _p$.d = _v$30);
6584
6622
  return _p$;
6585
6623
  }, {
6586
6624
  e: void 0,
@@ -8364,267 +8402,135 @@ function RecipientEditor(props) {
8364
8402
  return _el$;
8365
8403
  })();
8366
8404
  }
8367
- const VALID_TRANSITIONS = {
8368
- idle: ["quoting", "quoted", "error"],
8369
- quoting: ["quoted", "error", "idle"],
8370
- quoted: ["building", "quoting", "idle", "error"],
8371
- building: ["awaiting-wallet", "error", "quoted"],
8372
- "awaiting-wallet": ["submitting", "error", "quoted"],
8373
- submitting: ["tracking", "error", "quoted"],
8374
- tracking: ["success", "error"],
8375
- success: ["idle", "error"],
8376
- error: ["idle", "quoting", "quoted"]
8377
- };
8378
- function createSwapStateMachine() {
8379
- const [state, setState] = createSignal({
8380
- phase: "idle",
8381
- fromToken: null,
8382
- toToken: null,
8383
- inputAmount: "",
8384
- outputAmount: "",
8385
- routes: [],
8386
- quoteId: null,
8387
- selectedRouteId: null,
8388
- order: null,
8389
- walletAddress: null,
8390
- isStreaming: false,
8391
- error: null,
8392
- errorCode: null,
8393
- recipient: null
8394
- });
8395
- function transition(nextPhase) {
8396
- const current = state().phase;
8397
- const allowed = VALID_TRANSITIONS[current];
8398
- if (!allowed?.includes(nextPhase)) {
8399
- console.warn(
8400
- `[TokenFlight] Invalid state transition: ${current} → ${nextPhase}`
8401
- );
8402
- return false;
8403
- }
8404
- setState((prev) => ({ ...prev, phase: nextPhase }));
8405
- return true;
8406
- }
8407
- function setFromToken(token) {
8408
- setState((prev) => ({ ...prev, fromToken: token }));
8409
- }
8410
- function setToToken(token) {
8411
- setState((prev) => ({ ...prev, toToken: token }));
8412
- }
8413
- function setInputAmount(amount2) {
8414
- setState((prev) => ({ ...prev, inputAmount: amount2 }));
8415
- }
8416
- function setOutputAmount(amount2) {
8417
- setState((prev) => ({ ...prev, outputAmount: amount2 }));
8418
- }
8419
- function setQuoteData(quoteId, routes, selectedRouteId) {
8405
+ function deriveSwapPhase(execPhase, error2, isFetching, routeCount, hasQuoteRequest) {
8406
+ if (execPhase) return execPhase;
8407
+ if (error2) return "error";
8408
+ if (isFetching && routeCount === 0 && hasQuoteRequest) return "quoting";
8409
+ if (routeCount > 0) return "quoted";
8410
+ return "idle";
8411
+ }
8412
+ function deriveReceivePhase(execPhase, error2, loadingQuotes, quoteCount) {
8413
+ if (execPhase) return execPhase;
8414
+ if (error2) return "error";
8415
+ if (loadingQuotes && quoteCount === 0) return "quoting";
8416
+ if (quoteCount > 0) return "quoted";
8417
+ return "idle";
8418
+ }
8419
+ function createSwapStore() {
8420
+ const [fromToken, setFromToken] = createSignal(null);
8421
+ const [toToken, setToToken] = createSignal(null);
8422
+ const [inputAmount, setInputAmount] = createSignal("");
8423
+ const [recipient, _setRecipient] = createSignal(null);
8424
+ const [walletAddress2, _setWalletAddress] = createSignal(null);
8425
+ const [execPhase, setExecPhase] = createSignal(null);
8426
+ const [order, setOrder] = createSignal(null);
8427
+ const [error2, setError] = createSignal(null);
8428
+ const [errorCode, setErrorCode] = createSignal(null);
8429
+ function setWalletAddress(addr) {
8430
+ if (walletAddress2() === addr) return;
8431
+ _setWalletAddress(addr);
8432
+ }
8433
+ function setRecipient(r) {
8434
+ if (recipient() === r) return;
8435
+ _setRecipient(r);
8436
+ }
8437
+ function clearError() {
8420
8438
  batch(() => {
8421
- setState((prev) => ({
8422
- ...prev,
8423
- quoteId,
8424
- routes,
8425
- selectedRouteId
8426
- }));
8427
- });
8428
- }
8429
- function addStreamingRoute(quoteId, route) {
8430
- setState((prev) => {
8431
- if (prev.routes.some((r) => r.routeId === route.routeId)) {
8432
- return { ...prev, quoteId };
8433
- }
8434
- return { ...prev, quoteId, routes: [...prev.routes, route] };
8439
+ setError(null);
8440
+ setErrorCode(null);
8435
8441
  });
8436
8442
  }
8437
- function clearRoutes() {
8438
- setState((prev) => ({
8439
- ...prev,
8440
- routes: [],
8441
- quoteId: null,
8442
- selectedRouteId: null
8443
- }));
8444
- }
8445
- function setSelectedRouteId(routeId) {
8446
- setState((prev) => ({ ...prev, selectedRouteId: routeId }));
8447
- }
8448
- function setStreaming(isStreaming) {
8449
- setState((prev) => ({ ...prev, isStreaming }));
8450
- }
8451
- function setOrder(order) {
8452
- setState((prev) => ({ ...prev, order }));
8453
- }
8454
- function setWalletAddress(address) {
8455
- if (state().walletAddress === address) return;
8456
- setState((prev) => ({ ...prev, walletAddress: address }));
8457
- }
8458
- function setError(error2, errorCode = null) {
8459
- const current = state().phase;
8460
- const allowed = VALID_TRANSITIONS[current];
8461
- if (allowed?.includes("error")) {
8462
- setState((prev) => ({ ...prev, error: error2, errorCode, phase: "error" }));
8463
- } else {
8464
- setState((prev) => ({ ...prev, error: error2, errorCode }));
8465
- }
8466
- }
8467
- function setRecipient(recipient) {
8468
- if (state().recipient === recipient) return;
8469
- setState((prev) => ({ ...prev, recipient }));
8470
- }
8471
8443
  function reset() {
8472
- setState((prev) => ({
8473
- ...prev,
8474
- phase: "idle",
8475
- inputAmount: "",
8476
- outputAmount: "",
8477
- routes: [],
8478
- quoteId: null,
8479
- selectedRouteId: null,
8480
- order: null,
8481
- isStreaming: false,
8482
- error: null,
8483
- errorCode: null
8484
- }));
8444
+ batch(() => {
8445
+ setInputAmount("");
8446
+ setOrder(null);
8447
+ setExecPhase(null);
8448
+ setError(null);
8449
+ setErrorCode(null);
8450
+ });
8485
8451
  }
8486
8452
  return {
8487
- state,
8488
- transition,
8453
+ // Accessors
8454
+ fromToken,
8455
+ toToken,
8456
+ inputAmount,
8457
+ recipient,
8458
+ walletAddress: walletAddress2,
8459
+ execPhase,
8460
+ order,
8461
+ error: error2,
8462
+ errorCode,
8463
+ // Setters
8489
8464
  setFromToken,
8490
8465
  setToToken,
8491
8466
  setInputAmount,
8492
- setOutputAmount,
8493
- setQuoteData,
8494
- addStreamingRoute,
8495
- clearRoutes,
8496
- setSelectedRouteId,
8497
- setStreaming,
8498
- setOrder,
8467
+ setRecipient,
8499
8468
  setWalletAddress,
8469
+ setExecPhase,
8470
+ setOrder,
8500
8471
  setError,
8501
- setRecipient,
8472
+ setErrorCode,
8473
+ // Batch helpers
8474
+ clearError,
8502
8475
  reset
8503
8476
  };
8504
8477
  }
8505
- function createReceiveStateMachine() {
8506
- const [state, setState] = createSignal({
8507
- phase: "idle",
8508
- targetToken: null,
8509
- fromToken: null,
8510
- targetAmount: "",
8511
- paymentAmount: "",
8512
- routes: [],
8513
- quoteId: null,
8514
- selectedRouteId: null,
8515
- order: null,
8516
- walletAddress: null,
8517
- isStreaming: false,
8518
- error: null,
8519
- errorCode: null,
8520
- recipient: null
8521
- });
8522
- function transition(nextPhase) {
8523
- const current = state().phase;
8524
- const allowed = VALID_TRANSITIONS[current];
8525
- if (!allowed?.includes(nextPhase)) {
8526
- console.warn(
8527
- `[TokenFlight] Invalid state transition: ${current} → ${nextPhase}`
8528
- );
8529
- return false;
8530
- }
8531
- setState((prev) => ({ ...prev, phase: nextPhase }));
8532
- return true;
8533
- }
8534
- function setTargetToken(token) {
8535
- setState((prev) => ({ ...prev, targetToken: token }));
8536
- }
8537
- function setFromToken(token) {
8538
- setState((prev) => ({ ...prev, fromToken: token }));
8539
- }
8540
- function setTargetAmount(amount2) {
8541
- setState((prev) => ({ ...prev, targetAmount: amount2 }));
8542
- }
8543
- function setPaymentAmount(amount2) {
8544
- setState((prev) => ({ ...prev, paymentAmount: amount2 }));
8545
- }
8546
- function setQuoteData(quoteId, routes, selectedRouteId) {
8478
+ function createReceiveStore() {
8479
+ const [targetToken, setTargetToken] = createSignal(null);
8480
+ const [targetAmount, setTargetAmount] = createSignal("");
8481
+ const [fromToken, setFromToken] = createSignal(null);
8482
+ const [recipient, _setRecipient] = createSignal(null);
8483
+ const [walletAddress2, _setWalletAddress] = createSignal(null);
8484
+ const [execPhase, setExecPhase] = createSignal(null);
8485
+ const [order, setOrder] = createSignal(null);
8486
+ const [error2, setError] = createSignal(null);
8487
+ const [errorCode, setErrorCode] = createSignal(null);
8488
+ function setWalletAddress(addr) {
8489
+ if (walletAddress2() === addr) return;
8490
+ _setWalletAddress(addr);
8491
+ }
8492
+ function setRecipient(r) {
8493
+ if (recipient() === r) return;
8494
+ _setRecipient(r);
8495
+ }
8496
+ function clearError() {
8547
8497
  batch(() => {
8548
- setState((prev) => ({
8549
- ...prev,
8550
- quoteId,
8551
- routes,
8552
- selectedRouteId
8553
- }));
8554
- });
8555
- }
8556
- function addStreamingRoute(quoteId, route) {
8557
- setState((prev) => {
8558
- if (prev.routes.some((r) => r.routeId === route.routeId)) {
8559
- return { ...prev, quoteId };
8560
- }
8561
- return { ...prev, quoteId, routes: [...prev.routes, route] };
8498
+ setError(null);
8499
+ setErrorCode(null);
8562
8500
  });
8563
8501
  }
8564
- function clearRoutes() {
8565
- setState((prev) => ({
8566
- ...prev,
8567
- routes: [],
8568
- quoteId: null,
8569
- selectedRouteId: null
8570
- }));
8571
- }
8572
- function setSelectedRouteId(routeId) {
8573
- setState((prev) => ({ ...prev, selectedRouteId: routeId }));
8574
- }
8575
- function setStreaming(isStreaming) {
8576
- setState((prev) => ({ ...prev, isStreaming }));
8577
- }
8578
- function setOrder(order) {
8579
- setState((prev) => ({ ...prev, order }));
8580
- }
8581
- function setWalletAddress(address) {
8582
- if (state().walletAddress === address) return;
8583
- setState((prev) => ({ ...prev, walletAddress: address }));
8584
- }
8585
- function setRecipient(recipient) {
8586
- if (state().recipient === recipient) return;
8587
- setState((prev) => ({ ...prev, recipient }));
8588
- }
8589
- function setError(error2, errorCode = null) {
8590
- const current = state().phase;
8591
- const allowed = VALID_TRANSITIONS[current];
8592
- if (allowed?.includes("error")) {
8593
- setState((prev) => ({ ...prev, error: error2, errorCode, phase: "error" }));
8594
- } else {
8595
- setState((prev) => ({ ...prev, error: error2, errorCode }));
8596
- }
8597
- }
8598
8502
  function reset() {
8599
- setState((prev) => ({
8600
- ...prev,
8601
- phase: "idle",
8602
- routes: [],
8603
- quoteId: null,
8604
- selectedRouteId: null,
8605
- order: null,
8606
- error: null,
8607
- errorCode: null,
8608
- paymentAmount: "",
8609
- isStreaming: false
8610
- }));
8503
+ batch(() => {
8504
+ setFromToken(null);
8505
+ setOrder(null);
8506
+ setExecPhase(null);
8507
+ setError(null);
8508
+ setErrorCode(null);
8509
+ });
8611
8510
  }
8612
8511
  return {
8613
- state,
8614
- transition,
8512
+ // Accessors
8513
+ targetToken,
8514
+ targetAmount,
8515
+ fromToken,
8516
+ recipient,
8517
+ walletAddress: walletAddress2,
8518
+ execPhase,
8519
+ order,
8520
+ error: error2,
8521
+ errorCode,
8522
+ // Setters
8615
8523
  setTargetToken,
8616
- setFromToken,
8617
8524
  setTargetAmount,
8618
- setPaymentAmount,
8619
- setQuoteData,
8620
- addStreamingRoute,
8621
- clearRoutes,
8622
- setSelectedRouteId,
8623
- setStreaming,
8624
- setOrder,
8625
- setWalletAddress,
8525
+ setFromToken,
8626
8526
  setRecipient,
8527
+ setWalletAddress,
8528
+ setExecPhase,
8529
+ setOrder,
8627
8530
  setError,
8531
+ setErrorCode,
8532
+ // Batch helpers
8533
+ clearError,
8628
8534
  reset
8629
8535
  };
8630
8536
  }
@@ -8820,6 +8726,328 @@ function getBestOverallRouteId(routes, tradeType) {
8820
8726
  const ranked = rankOffers(offers);
8821
8727
  return ranked[0] ?? null;
8822
8728
  }
8729
+ function useWalletConnection(params) {
8730
+ const [isConnected, setIsConnected] = createSignal(false);
8731
+ const [walletAddress2, setWalletAddress] = createSignal(null);
8732
+ const detectChainType = () => {
8733
+ const adapter = params.walletAdapter();
8734
+ if (!adapter) return "evm";
8735
+ return adapter.supportedActionTypes.some((t2) => t2.startsWith("solana_")) ? "solana" : "evm";
8736
+ };
8737
+ let cleanupPrev;
8738
+ createEffect(
8739
+ on(params.walletAdapter, (adapter) => {
8740
+ cleanupPrev?.();
8741
+ cleanupPrev = void 0;
8742
+ if (!adapter) return;
8743
+ const connected = adapter.isConnected();
8744
+ setIsConnected(connected);
8745
+ if (connected) {
8746
+ void adapter.getAddress().then((addr) => {
8747
+ setWalletAddress(addr);
8748
+ params.onAddressChange(addr);
8749
+ params.callbacks()?.onWalletConnected?.({
8750
+ address: addr ?? "",
8751
+ chainType: detectChainType()
8752
+ });
8753
+ });
8754
+ }
8755
+ const handleWalletConnect = async () => {
8756
+ const addr = await adapter.getAddress();
8757
+ if (isConnected() && walletAddress2() === addr) return;
8758
+ batch(() => {
8759
+ setIsConnected(true);
8760
+ setWalletAddress(addr);
8761
+ params.onAddressChange(addr);
8762
+ });
8763
+ params.callbacks()?.onWalletConnected?.({
8764
+ address: addr ?? "",
8765
+ chainType: detectChainType()
8766
+ });
8767
+ };
8768
+ const handleWalletDisconnect = () => {
8769
+ if (!isConnected()) return;
8770
+ batch(() => {
8771
+ setIsConnected(false);
8772
+ setWalletAddress(null);
8773
+ params.onAddressChange(null);
8774
+ });
8775
+ params.onDisconnect?.();
8776
+ };
8777
+ adapter.on("connect", handleWalletConnect);
8778
+ adapter.on("disconnect", handleWalletDisconnect);
8779
+ cleanupPrev = () => {
8780
+ adapter.off("connect", handleWalletConnect);
8781
+ adapter.off("disconnect", handleWalletDisconnect);
8782
+ };
8783
+ })
8784
+ );
8785
+ onCleanup(() => cleanupPrev?.());
8786
+ const handleConnect = async () => {
8787
+ const adapter = params.walletAdapter();
8788
+ if (!adapter) {
8789
+ console.warn(
8790
+ "[TokenFlight] No wallet adapter configured. Pass a walletAdapter to enable wallet connection.\nSee: https://embed.tokenflight.ai/guides/wallet-adapter/"
8791
+ );
8792
+ params.callbacks()?.onConnectWallet?.();
8793
+ return;
8794
+ }
8795
+ try {
8796
+ await adapter.connect();
8797
+ } catch {
8798
+ params.onConnectError?.(
8799
+ "Failed to connect wallet",
8800
+ ErrorCode.WALLET_CONNECTION_FAILED
8801
+ );
8802
+ }
8803
+ };
8804
+ return {
8805
+ isConnected,
8806
+ walletAddress: walletAddress2,
8807
+ detectChainType,
8808
+ handleConnect
8809
+ };
8810
+ }
8811
+ function useQuoteCountdown(params) {
8812
+ const interval = params.intervalSeconds ?? QUOTE_REFRESH_SECONDS;
8813
+ const [countdownSeconds, setCountdownSeconds] = createSignal(interval);
8814
+ createEffect(
8815
+ on(params.phase, (p) => {
8816
+ if (p !== "quoted") {
8817
+ setCountdownSeconds(interval);
8818
+ return;
8819
+ }
8820
+ setCountdownSeconds(interval);
8821
+ const timer = setInterval(() => {
8822
+ setCountdownSeconds((prev) => {
8823
+ if (prev <= 1) {
8824
+ params.onExpired();
8825
+ return interval;
8826
+ }
8827
+ return prev - 1;
8828
+ });
8829
+ }, 1e3);
8830
+ onCleanup(() => clearInterval(timer));
8831
+ })
8832
+ );
8833
+ return { countdownSeconds };
8834
+ }
8835
+ function useRecipient(params) {
8836
+ const needRecipient = createMemo(() => {
8837
+ const to = params.toToken();
8838
+ if (!to || !params.isConnected()) return false;
8839
+ const addr = params.walletAddress();
8840
+ if (!addr) return false;
8841
+ const toChainType = getChainType(to.chainId);
8842
+ return !isAddressForChainType(addr, toChainType);
8843
+ });
8844
+ const recipientDisplay = createMemo(() => {
8845
+ const r = params.recipient();
8846
+ if (r) return r;
8847
+ if (params.isConnected() && params.walletAddress() && !needRecipient())
8848
+ return params.walletAddress();
8849
+ return null;
8850
+ });
8851
+ createEffect(
8852
+ on(needRecipient, (need) => {
8853
+ if (need && !params.recipient() && params.walletAdapter()) {
8854
+ const to = params.toToken();
8855
+ if (!to) return;
8856
+ const targetChainType = getChainType(to.chainId);
8857
+ params.walletAdapter().getAddress(targetChainType).then((addr) => {
8858
+ if (addr && isAddressForChainType(addr, targetChainType) && !params.recipient() && needRecipient()) {
8859
+ params.setRecipient(addr);
8860
+ }
8861
+ }).catch(() => {
8862
+ });
8863
+ }
8864
+ })
8865
+ );
8866
+ const handleRecipientChange = (value2) => {
8867
+ params.setRecipient(value2.trim() || null);
8868
+ };
8869
+ return {
8870
+ needRecipient,
8871
+ recipientDisplay,
8872
+ handleRecipientChange
8873
+ };
8874
+ }
8875
+ function useOrderTracking(params) {
8876
+ const orderQuery = createOrderQuery(
8877
+ params.client,
8878
+ params.walletAddress,
8879
+ params.trackingOrderId,
8880
+ () => params.phase() === "tracking" && !!params.trackingOrderId()
8881
+ );
8882
+ createEffect(
8883
+ on(
8884
+ () => orderQuery.data,
8885
+ (order) => {
8886
+ if (!order || params.execPhase() !== "tracking") return;
8887
+ const isFilled = order.status === "filled" || order.stepsCompleted?.includes("filled");
8888
+ const isFailed = order.status === "failed" || order.status === "refunded";
8889
+ batch(() => {
8890
+ params.setOrder(order);
8891
+ if (isFilled) {
8892
+ params.setExecPhase("success");
8893
+ queryClient.invalidateQueries({
8894
+ queryKey: ["tokenBalances", params.client().baseUrl]
8895
+ });
8896
+ params.onOrderFilled(order);
8897
+ } else if (isFailed) {
8898
+ queryClient.invalidateQueries({
8899
+ queryKey: ["tokenBalances", params.client().baseUrl]
8900
+ });
8901
+ params.onOrderFailed(order);
8902
+ }
8903
+ });
8904
+ }
8905
+ )
8906
+ );
8907
+ return { orderQuery };
8908
+ }
8909
+ function useSwapExecution(params) {
8910
+ const [trackingOrderId, setTrackingOrderId] = createSignal(
8911
+ null
8912
+ );
8913
+ const [trackingProviderName, setTrackingProviderName] = createSignal(null);
8914
+ const [trackingProviderIcon, setTrackingProviderIcon] = createSignal(null);
8915
+ const [executionError, setExecutionError] = createSignal(null);
8916
+ const handleConfirm = async () => {
8917
+ const currentRoutes = params.routes();
8918
+ const currentQuoteId = params.quoteId();
8919
+ const selectedRoute = currentRoutes.find((r) => r.routeId === params.selectedRouteId()) ?? currentRoutes[0];
8920
+ if (!selectedRoute || !currentQuoteId || !params.client() || !params.walletAdapter())
8921
+ return;
8922
+ if (params.needRecipient() && !params.recipient()) {
8923
+ params.setError("Recipient address is required for cross-chain swaps");
8924
+ params.setErrorCode(ErrorCode.INVALID_CONFIG);
8925
+ return;
8926
+ }
8927
+ const fromChainType = getChainType(params.fromToken().chainId);
8928
+ const addr = params.walletAddress();
8929
+ if (!addr) {
8930
+ params.setError("Wallet not connected");
8931
+ params.setErrorCode(ErrorCode.WALLET_CONNECTION_FAILED);
8932
+ return;
8933
+ }
8934
+ if (!isAddressForChainType(addr, fromChainType)) {
8935
+ params.setError(t("error.walletChainMismatch"));
8936
+ params.setErrorCode(ErrorCode.INVALID_CONFIG);
8937
+ return;
8938
+ }
8939
+ setTrackingProviderName(selectedRoute.routeId ?? null);
8940
+ const apiBase = params.apiEndpoint() ?? DEFAULT_API_ENDPOINT;
8941
+ setTrackingProviderIcon(
8942
+ selectedRoute.icon ? `${apiBase}${selectedRoute.icon}` : null
8943
+ );
8944
+ setExecutionError(null);
8945
+ params.setExecPhase("building");
8946
+ try {
8947
+ const depositData = await params.client().buildDeposit({
8948
+ from: addr,
8949
+ quoteId: currentQuoteId,
8950
+ routeId: selectedRoute.routeId
8951
+ });
8952
+ params.setExecPhase("awaiting-wallet");
8953
+ let txHash;
8954
+ let signedTransaction;
8955
+ if (depositData.kind === "CONTRACT_CALL" && depositData.approvals) {
8956
+ for (const approval of depositData.approvals) {
8957
+ if (approval.type === "eip1193_request") {
8958
+ const result = await params.walletAdapter().executeWalletAction({
8959
+ type: "eip1193_request",
8960
+ chainId: params.fromToken().chainId,
8961
+ method: approval.request.method,
8962
+ params: approval.request.params
8963
+ });
8964
+ if (!result.success) {
8965
+ throw new TokenFlightError(
8966
+ ErrorCode.WALLET_ACTION_FAILED,
8967
+ result.error ?? "Wallet action failed"
8968
+ );
8969
+ }
8970
+ if (approval.deposit) {
8971
+ txHash = result.txHash ?? txHash;
8972
+ }
8973
+ } else if (approval.type === "solana_sendTransaction") {
8974
+ const result = await params.walletAdapter().executeWalletAction({
8975
+ type: "solana_signTransaction",
8976
+ transaction: approval.transaction
8977
+ });
8978
+ if (!result.success) {
8979
+ throw new TokenFlightError(
8980
+ ErrorCode.WALLET_ACTION_FAILED,
8981
+ result.error ?? "Wallet action failed"
8982
+ );
8983
+ }
8984
+ if (approval.deposit) {
8985
+ signedTransaction = typeof result.data === "string" ? result.data : void 0;
8986
+ }
8987
+ }
8988
+ }
8989
+ }
8990
+ if (!txHash && !signedTransaction) {
8991
+ throw new TokenFlightError(
8992
+ ErrorCode.TRANSACTION_FAILED,
8993
+ "No deposit transaction received"
8994
+ );
8995
+ }
8996
+ params.setExecPhase("submitting");
8997
+ const submitResult = await params.client().submitDeposit(
8998
+ signedTransaction ? {
8999
+ quoteId: currentQuoteId,
9000
+ routeId: selectedRoute.routeId,
9001
+ signedTransaction
9002
+ } : {
9003
+ quoteId: currentQuoteId,
9004
+ routeId: selectedRoute.routeId,
9005
+ txHash
9006
+ }
9007
+ );
9008
+ params.setExecPhase("tracking");
9009
+ setTrackingOrderId(submitResult.orderId);
9010
+ } catch (err) {
9011
+ const errorMsg = err instanceof Error ? err.message : typeof err === "string" ? err : "Transaction failed";
9012
+ setExecutionError(errorMsg);
9013
+ if (err instanceof TokenFlightError) {
9014
+ params.callbacks()?.onSwapError?.({
9015
+ code: err.code,
9016
+ message: err.message,
9017
+ details: err.details
9018
+ });
9019
+ } else {
9020
+ params.callbacks()?.onSwapError?.({
9021
+ code: ErrorCode.TRANSACTION_FAILED,
9022
+ message: String(err)
9023
+ });
9024
+ }
9025
+ }
9026
+ };
9027
+ const handleRetry = () => {
9028
+ setExecutionError(null);
9029
+ params.setExecPhase(null);
9030
+ };
9031
+ const handleNewSwap = () => {
9032
+ params.storeReset();
9033
+ setTrackingOrderId(null);
9034
+ setTrackingProviderName(null);
9035
+ setTrackingProviderIcon(null);
9036
+ setExecutionError(null);
9037
+ queryClient.removeQueries({ queryKey: ["quote", params.client().baseUrl] });
9038
+ queryClient.removeQueries({ queryKey: ["order", params.client().baseUrl] });
9039
+ params.onReset?.();
9040
+ };
9041
+ return {
9042
+ trackingOrderId,
9043
+ trackingProviderName,
9044
+ trackingProviderIcon,
9045
+ executionError,
9046
+ handleConfirm,
9047
+ handleRetry,
9048
+ handleNewSwap
9049
+ };
9050
+ }
8823
9051
  const header$1 = "tf-dc5721";
8824
9052
  const headerLeft = "tf-68123c";
8825
9053
  const headerLogoImage = "tf-532d07";
@@ -8882,23 +9110,23 @@ const swapStyles = {
8882
9110
  };
8883
9111
  var _tmpl$$3 = /* @__PURE__ */ template(`<div data-testid=selector-overlay>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div part=container><div part=accent-line data-testid=accent-line>`), _tmpl$4$2 = /* @__PURE__ */ template(`<img width=22 height=22>`), _tmpl$5$2 = /* @__PURE__ */ template(`<button part=wallet-info><div data-testid=wallet-dot></div><span data-testid=wallet-address>`), _tmpl$6$2 = /* @__PURE__ */ template(`<div part=header><div><span data-testid=header-title>`), _tmpl$7$2 = /* @__PURE__ */ template(`<div><span part=balance data-testid=panel-balance></span><button data-testid=max-btn>`), _tmpl$8$2 = /* @__PURE__ */ template(`<button part=token-display data-testid=token-btn><div data-testid=token-icon-wrap><div data-testid=token-chain-dot></div></div><span data-testid=token-name></span><span data-testid=caret>`), _tmpl$9$2 = /* @__PURE__ */ template(`<div part=panel-from><div><div><span data-testid=panel-label></span></div><div></div><div><span data-testid=fiat>`), _tmpl$0$2 = /* @__PURE__ */ template(`<div part=swap-arrow><button type=button data-testid=swap-arrow-inner>`), _tmpl$1$2 = /* @__PURE__ */ template(`<button part=recipient-badge data-testid=recipient-badge><span>`), _tmpl$10$2 = /* @__PURE__ */ template(`<span part=amount-display data-testid=amount style=cursor:default>`), _tmpl$11$1 = /* @__PURE__ */ template(`<div part=panel-to data-testid=panel-wrapper-to><div><div><span data-testid=panel-label></span></div><div></div><div><span data-testid=fiat>`), _tmpl$12$1 = /* @__PURE__ */ template(`<div part=price-preview data-testid=quote>`), _tmpl$13 = /* @__PURE__ */ template(`<div part=no-offer><div><svg width=28 height=28 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round><circle cx=11 cy=11 r=8></circle><path d="m21 21-4.35-4.35"></path><path d="M8 11h6"></path></svg></div><span>`), _tmpl$14 = /* @__PURE__ */ template(`<div part=cta-wrapper>`), _tmpl$15 = /* @__PURE__ */ template(`<span>Flight`), _tmpl$16 = /* @__PURE__ */ template(`<button data-testid=token-btn><span data-testid=token-name></span><span data-testid=caret>`), _tmpl$17 = /* @__PURE__ */ template(`<div style=width:120px;height:28px>`);
8884
9112
  function SwapComponent(props) {
8885
- const sm = createSwapStateMachine();
9113
+ const store = createSwapStore();
8886
9114
  const [selectorOpen, setSelectorOpen] = createSignal(null);
8887
- const [isConnected, setIsConnected] = createSignal(false);
8888
- const [walletAddress2, setWalletAddress] = createSignal(null);
8889
- const [trackingOrderId, setTrackingOrderId] = createSignal(null);
8890
9115
  const [recipientEditorOpen, setRecipientEditorOpen] = createSignal(false);
8891
- const [noRoutes, setNoRoutes] = createSignal(false);
8892
- const [trackingProviderName, setTrackingProviderName] = createSignal(null);
8893
- const [trackingProviderIcon, setTrackingProviderIcon] = createSignal(null);
8894
- const [executionError, setExecutionError] = createSignal(null);
9116
+ const {
9117
+ isConnected,
9118
+ walletAddress: walletAddress2,
9119
+ handleConnect
9120
+ } = useWalletConnection({
9121
+ walletAdapter: () => props.walletAdapter,
9122
+ callbacks: () => props.callbacks,
9123
+ onAddressChange: (addr) => store.setWalletAddress(addr),
9124
+ onConnectError: (msg, code) => {
9125
+ store.setError(msg);
9126
+ store.setErrorCode(code);
9127
+ }
9128
+ });
8895
9129
  const [debouncedAmount, setDebouncedAmount, setDebouncedAmountImmediate] = createDebounced("", 300);
8896
- const phase = createMemo(() => sm.state().phase);
8897
- const fromToken = createMemo(() => sm.state().fromToken);
8898
- const toToken = createMemo(() => sm.state().toToken);
8899
- const inputAmount = createMemo(() => sm.state().inputAmount);
8900
- const outputAmount = createMemo(() => sm.state().outputAmount);
8901
- const recipient = createMemo(() => sm.state().recipient);
8902
9130
  const client = createMemo(() => {
8903
9131
  const endpoint = props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
8904
9132
  return new HyperstreamApi({
@@ -8907,7 +9135,7 @@ function SwapComponent(props) {
8907
9135
  });
8908
9136
  const balancesQuery = createTokenBalancesQuery(client, walletAddress2, () => isConnected() && !!walletAddress2(), () => props.walletAdapter?.supportedChainIds);
8909
9137
  const fromBalance = createMemo(() => {
8910
- const from = fromToken();
9138
+ const from = store.fromToken();
8911
9139
  if (!from || typeof from.decimals !== "number" || !balancesQuery.data) return null;
8912
9140
  const match = balancesQuery.data.find((tk) => tk.address.toLowerCase() === from.address.toLowerCase() && tk.chainId === from.chainId);
8913
9141
  if (match?.extensions?.balance) {
@@ -8916,14 +9144,14 @@ function SwapComponent(props) {
8916
9144
  return "0";
8917
9145
  });
8918
9146
  const fromBalanceRaw = createMemo(() => {
8919
- const from = fromToken();
9147
+ const from = store.fromToken();
8920
9148
  if (!from || typeof from.decimals !== "number" || !balancesQuery.data) return null;
8921
9149
  const match = balancesQuery.data.find((tk) => tk.address.toLowerCase() === from.address.toLowerCase() && tk.chainId === from.chainId);
8922
9150
  return match?.extensions?.balance ?? "0";
8923
9151
  });
8924
9152
  const insufficientBalance = createMemo(() => {
8925
- const input = inputAmount();
8926
- const from = fromToken();
9153
+ const input = store.inputAmount();
9154
+ const from = store.fromToken();
8927
9155
  const balRaw = fromBalanceRaw();
8928
9156
  if (!from || typeof from.decimals !== "number" || !balRaw || !input || input === "0" || input === "") {
8929
9157
  return false;
@@ -8935,7 +9163,7 @@ function SwapComponent(props) {
8935
9163
  }
8936
9164
  });
8937
9165
  const fromUnitPriceUsd = createMemo(() => {
8938
- const from = fromToken();
9166
+ const from = store.fromToken();
8939
9167
  if (!from) return null;
8940
9168
  if (typeof from.priceUsd === "number" && Number.isFinite(from.priceUsd)) {
8941
9169
  return from.priceUsd;
@@ -8945,7 +9173,7 @@ function SwapComponent(props) {
8945
9173
  return Number.isFinite(parsed) ? parsed : null;
8946
9174
  });
8947
9175
  const toUnitPriceUsd = createMemo(() => {
8948
- const to = toToken();
9176
+ const to = store.toToken();
8949
9177
  if (!to) return null;
8950
9178
  if (typeof to.priceUsd === "number" && Number.isFinite(to.priceUsd)) {
8951
9179
  return to.priceUsd;
@@ -8957,8 +9185,83 @@ function SwapComponent(props) {
8957
9185
  if (value2 < 0.01) return "<0.01";
8958
9186
  return value2.toFixed(2).replace(/\.?0+$/, "");
8959
9187
  };
9188
+ const {
9189
+ needRecipient,
9190
+ recipientDisplay,
9191
+ handleRecipientChange
9192
+ } = useRecipient({
9193
+ fromToken: store.fromToken,
9194
+ toToken: store.toToken,
9195
+ recipient: store.recipient,
9196
+ isConnected,
9197
+ walletAddress: walletAddress2,
9198
+ walletAdapter: () => props.walletAdapter,
9199
+ setRecipient: store.setRecipient
9200
+ });
9201
+ const quoteRequest = createMemo(() => {
9202
+ const amount2 = debouncedAmount();
9203
+ const from = store.fromToken();
9204
+ const to = store.toToken();
9205
+ const r = store.recipient();
9206
+ if (!amount2 || parseFloat(amount2) <= 0 || !from || typeof from.decimals !== "number" || !to || !client()) return null;
9207
+ if (needRecipient() && !r) return null;
9208
+ return {
9209
+ tradeType: "EXACT_INPUT",
9210
+ fromChainId: from.chainId,
9211
+ fromToken: from.address,
9212
+ toChainId: to.chainId,
9213
+ toToken: to.address,
9214
+ amount: toBaseUnits(amount2, from.decimals),
9215
+ fromAddress: walletAddress2() ?? getDefaultAddress(from.chainId),
9216
+ ...r && {
9217
+ recipient: r
9218
+ }
9219
+ };
9220
+ });
9221
+ const quoteQueryEnabled = createMemo(() => !!quoteRequest() && !store.execPhase());
9222
+ const quoteQuery = createQuoteQuery(client, quoteRequest, quoteQueryEnabled);
9223
+ const routes = createMemo(() => {
9224
+ const amount2 = store.inputAmount();
9225
+ if (!amount2 || parseFloat(amount2) <= 0) return [];
9226
+ if (!store.fromToken() || !store.toToken()) return [];
9227
+ return quoteQuery.data?.routes ?? [];
9228
+ });
9229
+ const quoteId = createMemo(() => quoteQuery.data?.quoteId ?? null);
9230
+ const selectedRouteId = createMemo(() => {
9231
+ const r = routes();
9232
+ return r.length > 0 ? getBestOverallSwapRouteId(r) : null;
9233
+ });
9234
+ const bestRoute = createMemo(() => {
9235
+ const r = routes();
9236
+ const sel = selectedRouteId();
9237
+ return r.find((rt) => rt.routeId === sel) ?? r[0] ?? null;
9238
+ });
9239
+ const outputAmount = createMemo(() => {
9240
+ const route = bestRoute();
9241
+ const to = store.toToken();
9242
+ if (!route || !to || typeof to.decimals !== "number") return "";
9243
+ return formatDisplayAmount(toDisplayAmount(route.quote.amountOut, to.decimals));
9244
+ });
9245
+ const phase = createMemo(() => deriveSwapPhase(store.execPhase(), store.error(), quoteQuery.isFetching, routes().length, !!quoteRequest()));
9246
+ const noRoutes = createMemo(() => {
9247
+ if (store.execPhase()) return false;
9248
+ if (!quoteRequest()) return false;
9249
+ return !quoteQuery.isFetching && quoteQuery.isSuccess && routes().length === 0;
9250
+ });
9251
+ const showQuote = createMemo(() => {
9252
+ const p = phase();
9253
+ return p === "quoted" || p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking" || p === "success";
9254
+ });
9255
+ const isExecuting = createMemo(() => {
9256
+ const p = phase();
9257
+ return p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking";
9258
+ });
9259
+ const isQuoteLoading = createMemo(() => {
9260
+ if (!store.fromToken() || !store.toToken()) return false;
9261
+ return phase() === "quoting" && parseFloat(store.inputAmount()) > 0 && routes().length === 0;
9262
+ });
8960
9263
  const inputFiatText = createMemo(() => {
8961
- const amount2 = Number(inputAmount());
9264
+ const amount2 = Number(store.inputAmount());
8962
9265
  const price = fromUnitPriceUsd();
8963
9266
  if (!Number.isFinite(amount2) || amount2 <= 0 || price === null) return null;
8964
9267
  return t("swap.fiatValue", {
@@ -8968,45 +9271,95 @@ function SwapComponent(props) {
8968
9271
  const outputFiatText = createMemo(() => {
8969
9272
  const amount2 = Number(outputAmount() || "0");
8970
9273
  const price = toUnitPriceUsd();
8971
- const p = phase();
8972
- const show = p === "quoted" || p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking" || p === "success";
8973
- if (!show || !Number.isFinite(amount2) || amount2 <= 0 || price === null) return null;
9274
+ if (!showQuote() || !Number.isFinite(amount2) || amount2 <= 0 || price === null) return null;
8974
9275
  return t("swap.fiatValue", {
8975
9276
  value: formatUsd(amount2 * price)
8976
9277
  });
8977
9278
  });
8978
- const orderQuery = createOrderQuery(client, walletAddress2, trackingOrderId, () => phase() === "tracking" && !!trackingOrderId());
8979
- createEffect(on(() => orderQuery.data, (order) => {
8980
- if (!order || sm.state().phase !== "tracking") return;
8981
- const isFilled = order.status === "filled" || order.stepsCompleted?.includes("filled");
8982
- const isFailed = order.status === "failed" || order.status === "refunded";
8983
- batch(() => {
8984
- sm.setOrder(order);
8985
- if (isFilled) {
8986
- sm.transition("success");
8987
- queryClient.invalidateQueries({
8988
- queryKey: ["tokenBalances", client().baseUrl]
8989
- });
8990
- const state2 = sm.state();
8991
- props.callbacks?.onSwapSuccess?.({
8992
- orderId: order.id,
8993
- fromToken: state2.fromToken.symbol ?? state2.fromToken.address,
8994
- toToken: state2.toToken.symbol ?? state2.toToken.address,
8995
- fromAmount: order.srcAmount,
8996
- toAmount: order.destAmount,
8997
- txHash: order.depositTxHash
8998
- });
8999
- } else if (isFailed) {
9000
- queryClient.invalidateQueries({
9001
- queryKey: ["tokenBalances", client().baseUrl]
9002
- });
9003
- props.callbacks?.onSwapError?.({
9004
- code: ErrorCode.ORDER_FAILED,
9005
- message: "Order " + order.status
9006
- });
9279
+ const {
9280
+ trackingOrderId,
9281
+ trackingProviderName,
9282
+ trackingProviderIcon,
9283
+ executionError,
9284
+ handleConfirm,
9285
+ handleRetry,
9286
+ handleNewSwap
9287
+ } = useSwapExecution({
9288
+ client,
9289
+ walletAdapter: () => props.walletAdapter,
9290
+ callbacks: () => props.callbacks,
9291
+ apiEndpoint: () => props.config.apiEndpoint,
9292
+ fromToken: store.fromToken,
9293
+ recipient: store.recipient,
9294
+ needRecipient,
9295
+ walletAddress: walletAddress2,
9296
+ routes,
9297
+ quoteId,
9298
+ selectedRouteId,
9299
+ setExecPhase: store.setExecPhase,
9300
+ setError: store.setError,
9301
+ setErrorCode: store.setErrorCode,
9302
+ storeReset: store.reset,
9303
+ onReset: () => setDebouncedAmountImmediate("")
9304
+ });
9305
+ useOrderTracking({
9306
+ client,
9307
+ walletAddress: walletAddress2,
9308
+ trackingOrderId,
9309
+ phase,
9310
+ execPhase: store.execPhase,
9311
+ setOrder: store.setOrder,
9312
+ setExecPhase: store.setExecPhase,
9313
+ onOrderFilled: (order) => {
9314
+ props.callbacks?.onSwapSuccess?.({
9315
+ orderId: order.id,
9316
+ fromToken: store.fromToken().symbol ?? store.fromToken().address,
9317
+ toToken: store.toToken().symbol ?? store.toToken().address,
9318
+ fromAmount: order.srcAmount,
9319
+ toAmount: order.destAmount,
9320
+ txHash: order.depositTxHash
9321
+ });
9322
+ },
9323
+ onOrderFailed: (order) => {
9324
+ props.callbacks?.onSwapError?.({
9325
+ code: ErrorCode.ORDER_FAILED,
9326
+ message: "Order " + order.status
9327
+ });
9328
+ }
9329
+ });
9330
+ createEffect(on(() => quoteQuery.data, (data) => {
9331
+ if (data) props.callbacks?.onQuoteReceived?.(data);
9332
+ }));
9333
+ createEffect(on(() => ({
9334
+ isError: quoteQuery.isError,
9335
+ error: quoteQuery.error,
9336
+ data: quoteQuery.data
9337
+ }), ({
9338
+ isError,
9339
+ error: error2,
9340
+ data
9341
+ }) => {
9342
+ if (store.execPhase()) return;
9343
+ if (isError && !data) {
9344
+ if (error2 instanceof TokenFlightError) {
9345
+ store.setError(error2.message);
9346
+ store.setErrorCode(error2.code);
9347
+ } else {
9348
+ store.setError(String(error2));
9349
+ store.setErrorCode(null);
9007
9350
  }
9008
- });
9351
+ } else if (store.error() && !isError) {
9352
+ store.clearError();
9353
+ }
9009
9354
  }));
9355
+ const {
9356
+ countdownSeconds
9357
+ } = useQuoteCountdown({
9358
+ phase,
9359
+ onExpired: () => {
9360
+ quoteQuery.refetch();
9361
+ }
9362
+ });
9010
9363
  onMount(() => {
9011
9364
  if (props.config.locale) {
9012
9365
  setLocale(props.config.locale);
@@ -9026,7 +9379,7 @@ function SwapComponent(props) {
9026
9379
  if (typeof resolved.decimals !== "number") {
9027
9380
  throw new TokenFlightError(ErrorCode.INVALID_TOKEN_IDENTIFIER, "Failed to resolve fromToken metadata");
9028
9381
  }
9029
- sm.setFromToken(resolved);
9382
+ store.setFromToken(resolved);
9030
9383
  } catch (err) {
9031
9384
  props.callbacks?.onSwapError?.({
9032
9385
  code: ErrorCode.INVALID_TOKEN_IDENTIFIER,
@@ -9041,7 +9394,7 @@ function SwapComponent(props) {
9041
9394
  if (typeof resolved.decimals !== "number") {
9042
9395
  throw new TokenFlightError(ErrorCode.INVALID_TOKEN_IDENTIFIER, "Failed to resolve toToken metadata");
9043
9396
  }
9044
- sm.setToToken(resolved);
9397
+ store.setToToken(resolved);
9045
9398
  } catch (err) {
9046
9399
  props.callbacks?.onSwapError?.({
9047
9400
  code: ErrorCode.INVALID_TOKEN_IDENTIFIER,
@@ -9050,333 +9403,20 @@ function SwapComponent(props) {
9050
9403
  }
9051
9404
  }
9052
9405
  });
9053
- const detectChainType = () => {
9054
- if (!props.walletAdapter) return "evm";
9055
- return props.walletAdapter.supportedActionTypes.some((t2) => t2.startsWith("solana_")) ? "solana" : "evm";
9056
- };
9057
- const needRecipient = createMemo(() => {
9058
- const from = fromToken();
9059
- const to = toToken();
9060
- if (!from || !to || !isConnected()) return false;
9061
- return isCrossChainSwap(from.chainId, to.chainId);
9062
- });
9063
- const recipientDisplay = createMemo(() => {
9064
- const r = recipient();
9065
- if (r) return r;
9066
- if (isConnected() && walletAddress2() && !needRecipient()) return walletAddress2();
9067
- return null;
9068
- });
9069
9406
  onMount(() => {
9070
9407
  if (props.config.recipient) {
9071
- sm.setRecipient(props.config.recipient);
9072
- }
9073
- });
9074
- const handleRecipientChange = (value2) => {
9075
- const trimmed = value2.trim() || null;
9076
- sm.setRecipient(trimmed);
9077
- if (!trimmed) {
9078
- sm.clearRoutes();
9079
- sm.setOutputAmount("");
9080
- if (sm.state().phase !== "idle") {
9081
- sm.transition("idle");
9082
- }
9083
- }
9084
- };
9085
- onMount(async () => {
9086
- if (props.walletAdapter) {
9087
- const connected = props.walletAdapter.isConnected();
9088
- setIsConnected(connected);
9089
- if (connected) {
9090
- const addr = await props.walletAdapter.getAddress();
9091
- setWalletAddress(addr);
9092
- sm.setWalletAddress(addr);
9093
- props.callbacks?.onWalletConnected?.({
9094
- address: addr ?? "",
9095
- chainType: detectChainType()
9096
- });
9097
- }
9098
- const handleWalletConnect = async () => {
9099
- const addr = await props.walletAdapter.getAddress();
9100
- if (isConnected() && walletAddress2() === addr) return;
9101
- batch(() => {
9102
- setIsConnected(true);
9103
- setWalletAddress(addr);
9104
- sm.setWalletAddress(addr);
9105
- });
9106
- props.callbacks?.onWalletConnected?.({
9107
- address: addr ?? "",
9108
- chainType: detectChainType()
9109
- });
9110
- };
9111
- const handleWalletDisconnect = () => {
9112
- if (!isConnected()) return;
9113
- batch(() => {
9114
- setIsConnected(false);
9115
- setWalletAddress(null);
9116
- sm.setWalletAddress(null);
9117
- });
9118
- };
9119
- props.walletAdapter.on("connect", handleWalletConnect);
9120
- props.walletAdapter.on("disconnect", handleWalletDisconnect);
9121
- onCleanup(() => {
9122
- props.walletAdapter.off("connect", handleWalletConnect);
9123
- props.walletAdapter.off("disconnect", handleWalletDisconnect);
9124
- });
9408
+ store.setRecipient(props.config.recipient);
9125
9409
  }
9126
9410
  });
9127
- const quoteRequest = createMemo(() => {
9128
- const amount2 = debouncedAmount();
9129
- const from = fromToken();
9130
- const to = toToken();
9131
- const r = recipient();
9132
- if (!amount2 || parseFloat(amount2) <= 0 || !from || typeof from.decimals !== "number" || !to || !client()) return null;
9133
- if (needRecipient() && !r) return null;
9134
- return {
9135
- tradeType: "EXACT_INPUT",
9136
- fromChainId: from.chainId,
9137
- fromToken: from.address,
9138
- toChainId: to.chainId,
9139
- toToken: to.address,
9140
- amount: toBaseUnits(amount2, from.decimals),
9141
- fromAddress: walletAddress2() ?? getDefaultAddress(from.chainId),
9142
- ...r && {
9143
- recipient: r
9144
- }
9145
- };
9146
- });
9147
- const quoteQueryEnabled = createMemo(() => {
9148
- const p = phase();
9149
- const hasRequest = !!quoteRequest();
9150
- return hasRequest && (p === "idle" || p === "quoting" || p === "quoted");
9151
- });
9152
- const quoteQuery = createQuoteQuery(client, quoteRequest, quoteQueryEnabled);
9153
- createEffect(on(() => quoteQuery.data, (data) => {
9154
- if (data) props.callbacks?.onQuoteReceived?.(data);
9155
- }));
9156
- createEffect(on(() => ({
9157
- data: quoteQuery.data,
9158
- isFetching: quoteQuery.isFetching,
9159
- isError: quoteQuery.isError,
9160
- error: quoteQuery.error
9161
- }), ({
9162
- data,
9163
- isFetching,
9164
- isError,
9165
- error: error2
9166
- }) => {
9167
- const phase2 = sm.state().phase;
9168
- if (phase2 === "building" || phase2 === "awaiting-wallet" || phase2 === "submitting" || phase2 === "tracking" || phase2 === "success") return;
9169
- if (isFetching && !data) {
9170
- if (phase2 !== "quoting") {
9171
- sm.clearRoutes();
9172
- setNoRoutes(false);
9173
- sm.transition("quoting");
9174
- }
9175
- return;
9176
- }
9177
- if (isError && !data) {
9178
- if (error2 instanceof TokenFlightError) {
9179
- sm.setError(error2.message, error2.code);
9180
- } else {
9181
- sm.setError(String(error2));
9182
- }
9183
- return;
9184
- }
9185
- if (data) {
9186
- const toDecimals = sm.state().toToken?.decimals ?? 18;
9187
- const bestId = getBestOverallSwapRouteId(data.routes);
9188
- sm.setQuoteData(data.quoteId, data.routes, bestId);
9189
- if (bestId) {
9190
- const bestRoute2 = data.routes.find((r) => r.routeId === bestId);
9191
- if (bestRoute2) {
9192
- sm.setOutputAmount(formatDisplayAmount(toDisplayAmount(bestRoute2.quote.amountOut, toDecimals)));
9193
- }
9194
- }
9195
- if (data.routes.length > 0) {
9196
- setNoRoutes(false);
9197
- if (phase2 !== "quoted") sm.transition("quoted");
9198
- } else {
9199
- setNoRoutes(true);
9200
- if (phase2 !== "idle") sm.transition("idle");
9201
- }
9202
- }
9203
- }));
9204
- const [countdownSeconds, setCountdownSeconds] = createSignal(QUOTE_REFRESH_SECONDS);
9205
- createEffect(on(phase, (p) => {
9206
- if (p !== "quoted") {
9207
- setCountdownSeconds(QUOTE_REFRESH_SECONDS);
9208
- return;
9209
- }
9210
- setCountdownSeconds(QUOTE_REFRESH_SECONDS);
9211
- const timer = setInterval(() => {
9212
- setCountdownSeconds((prev) => {
9213
- if (prev <= 1) {
9214
- quoteQuery.refetch();
9215
- return QUOTE_REFRESH_SECONDS;
9216
- }
9217
- return prev - 1;
9218
- });
9219
- }, 1e3);
9220
- onCleanup(() => clearInterval(timer));
9221
- }));
9222
9411
  const handleAmountChange = (amount2) => {
9223
- sm.setInputAmount(amount2);
9412
+ store.setInputAmount(amount2);
9224
9413
  props.callbacks?.onAmountChanged?.({
9225
9414
  amount: amount2,
9226
9415
  direction: "from"
9227
9416
  });
9228
- if (!amount2 || parseFloat(amount2) <= 0) {
9229
- sm.clearRoutes();
9230
- sm.setOutputAmount("");
9231
- setNoRoutes(false);
9232
- if (sm.state().phase !== "idle") {
9233
- sm.transition("idle");
9234
- }
9235
- } else if (sm.state().phase === "error") {
9236
- sm.transition("idle");
9237
- }
9417
+ if (store.error()) store.clearError();
9238
9418
  setDebouncedAmount(amount2);
9239
9419
  };
9240
- createEffect(on(needRecipient, (need) => {
9241
- if (need && !recipient() && props.walletAdapter) {
9242
- const to = toToken();
9243
- if (!to) return;
9244
- const targetChainType = getChainType(to.chainId);
9245
- props.walletAdapter.getAddress(targetChainType).then((addr) => {
9246
- if (addr && isAddressForChainType(addr, targetChainType) && !recipient() && needRecipient()) {
9247
- sm.setRecipient(addr);
9248
- }
9249
- }).catch(() => {
9250
- });
9251
- }
9252
- }));
9253
- const handleConnect = async () => {
9254
- if (!props.walletAdapter) {
9255
- console.warn("[TokenFlight] No wallet adapter configured. Pass a walletAdapter to enable wallet connection.\nSee: https://embed.tokenflight.ai/guides/wallet-adapter/");
9256
- props.callbacks?.onConnectWallet?.();
9257
- return;
9258
- }
9259
- try {
9260
- await props.walletAdapter.connect();
9261
- } catch {
9262
- sm.setError("Failed to connect wallet", ErrorCode.WALLET_CONNECTION_FAILED);
9263
- }
9264
- };
9265
- const handleConfirm = async () => {
9266
- const state2 = sm.state();
9267
- const selectedRoute = state2.routes.find((r) => r.routeId === state2.selectedRouteId) ?? state2.routes[0];
9268
- if (!selectedRoute || !state2.quoteId || !client() || !props.walletAdapter) return;
9269
- if (needRecipient() && !state2.recipient) {
9270
- sm.setError("Recipient address is required for cross-chain swaps", ErrorCode.INVALID_CONFIG);
9271
- return;
9272
- }
9273
- const fromChainType = getChainType(state2.fromToken.chainId);
9274
- const addr = walletAddress2();
9275
- if (!addr) {
9276
- sm.setError("Wallet not connected", ErrorCode.WALLET_CONNECTION_FAILED);
9277
- return;
9278
- }
9279
- if (!isAddressForChainType(addr, fromChainType)) {
9280
- sm.setError(t("error.walletChainMismatch"), ErrorCode.INVALID_CONFIG);
9281
- return;
9282
- }
9283
- setTrackingProviderName(selectedRoute.routeId ?? null);
9284
- const apiBase = props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
9285
- setTrackingProviderIcon(selectedRoute.icon ? `${apiBase}${selectedRoute.icon}` : null);
9286
- setExecutionError(null);
9287
- sm.transition("building");
9288
- try {
9289
- const depositData = await client().buildDeposit({
9290
- from: walletAddress2(),
9291
- quoteId: state2.quoteId,
9292
- routeId: selectedRoute.routeId
9293
- });
9294
- sm.transition("awaiting-wallet");
9295
- let txHash;
9296
- let signedTransaction;
9297
- if (depositData.kind === "CONTRACT_CALL" && depositData.approvals) {
9298
- for (const approval of depositData.approvals) {
9299
- if (approval.type === "eip1193_request") {
9300
- const result = await props.walletAdapter.executeWalletAction({
9301
- type: "eip1193_request",
9302
- chainId: state2.fromToken.chainId,
9303
- method: approval.request.method,
9304
- params: approval.request.params
9305
- });
9306
- if (!result.success) {
9307
- throw new TokenFlightError(ErrorCode.WALLET_ACTION_FAILED, result.error ?? "Wallet action failed");
9308
- }
9309
- if (approval.deposit) {
9310
- txHash = result.txHash ?? txHash;
9311
- }
9312
- } else if (approval.type === "solana_sendTransaction") {
9313
- const result = await props.walletAdapter.executeWalletAction({
9314
- type: "solana_signTransaction",
9315
- transaction: approval.transaction
9316
- });
9317
- if (!result.success) {
9318
- throw new TokenFlightError(ErrorCode.WALLET_ACTION_FAILED, result.error ?? "Wallet action failed");
9319
- }
9320
- if (approval.deposit) {
9321
- signedTransaction = typeof result.data === "string" ? result.data : void 0;
9322
- }
9323
- }
9324
- }
9325
- }
9326
- if (!txHash && !signedTransaction) {
9327
- throw new TokenFlightError(ErrorCode.TRANSACTION_FAILED, "No deposit transaction received");
9328
- }
9329
- sm.transition("submitting");
9330
- const submitResult = await client().submitDeposit(signedTransaction ? {
9331
- quoteId: state2.quoteId,
9332
- routeId: selectedRoute.routeId,
9333
- signedTransaction
9334
- } : {
9335
- quoteId: state2.quoteId,
9336
- routeId: selectedRoute.routeId,
9337
- txHash
9338
- });
9339
- sm.transition("tracking");
9340
- setTrackingOrderId(submitResult.orderId);
9341
- } catch (err) {
9342
- const errorMsg = err instanceof Error ? err.message : typeof err === "string" ? err : "Transaction failed";
9343
- setExecutionError(errorMsg);
9344
- if (err instanceof TokenFlightError) {
9345
- props.callbacks?.onSwapError?.({
9346
- code: err.code,
9347
- message: err.message,
9348
- details: err.details
9349
- });
9350
- } else {
9351
- props.callbacks?.onSwapError?.({
9352
- code: ErrorCode.TRANSACTION_FAILED,
9353
- message: String(err)
9354
- });
9355
- }
9356
- }
9357
- };
9358
- const handleRetry = () => {
9359
- setExecutionError(null);
9360
- sm.transition("quoted");
9361
- };
9362
- const handleNewSwap = () => {
9363
- sm.clearRoutes();
9364
- sm.setOutputAmount("");
9365
- sm.setInputAmount("");
9366
- sm.setOrder(null);
9367
- setDebouncedAmountImmediate("");
9368
- setTrackingOrderId(null);
9369
- setTrackingProviderName(null);
9370
- setTrackingProviderIcon(null);
9371
- setExecutionError(null);
9372
- queryClient.removeQueries({
9373
- queryKey: ["quote", client().baseUrl]
9374
- });
9375
- queryClient.removeQueries({
9376
- queryKey: ["order", client().baseUrl]
9377
- });
9378
- sm.transition("idle");
9379
- };
9380
9420
  const handleTokenSelect = (token) => {
9381
9421
  const resolved = {
9382
9422
  chainId: token.chainId,
@@ -9388,43 +9428,29 @@ function SwapComponent(props) {
9388
9428
  priceUsd: token.priceUsd
9389
9429
  };
9390
9430
  if (selectorOpen() === "from") {
9391
- sm.setFromToken(resolved);
9431
+ store.setFromToken(resolved);
9392
9432
  } else {
9393
- sm.setToToken(resolved);
9433
+ store.setToToken(resolved);
9394
9434
  }
9395
9435
  setSelectorOpen(null);
9396
- const amount2 = sm.state().inputAmount;
9397
- if (!amount2 || parseFloat(amount2) <= 0) {
9398
- sm.clearRoutes();
9399
- sm.setOutputAmount("");
9400
- if (sm.state().phase !== "idle") {
9401
- sm.transition("idle");
9402
- }
9403
- }
9404
9436
  };
9405
9437
  const handleSwapTokens = () => {
9406
- const current = sm.state();
9407
- const phase2 = current.phase;
9408
- const isBusy = phase2 === "building" || phase2 === "awaiting-wallet" || phase2 === "submitting" || phase2 === "tracking";
9409
- if (isBusy || !current.fromToken || !current.toToken) return;
9410
- sm.setFromToken(current.toToken);
9411
- sm.setToToken(current.fromToken);
9412
- sm.clearRoutes();
9413
- sm.setOutputAmount("");
9414
- if (phase2 === "success") {
9415
- sm.transition("idle");
9416
- }
9417
- const amount2 = current.inputAmount;
9418
- if (!amount2 || parseFloat(amount2) <= 0) {
9419
- if (sm.state().phase !== "idle") {
9420
- sm.transition("idle");
9421
- }
9422
- }
9438
+ if (isExecuting() || !store.fromToken() || !store.toToken()) return;
9439
+ const from = store.fromToken();
9440
+ const to = store.toToken();
9441
+ batch(() => {
9442
+ store.setFromToken(to);
9443
+ store.setToToken(from);
9444
+ if (store.execPhase() === "success") store.setExecPhase(null);
9445
+ });
9423
9446
  };
9424
9447
  const handleMaxClick = () => {
9425
- const bal = fromBalance();
9426
- if (bal && bal !== "0") {
9427
- handleAmountChange(bal);
9448
+ const from = store.fromToken();
9449
+ const balRaw = fromBalanceRaw();
9450
+ if (!from || typeof from.decimals !== "number" || !balRaw || balRaw === "0") return;
9451
+ const fullPrecision = toDisplayAmount(balRaw, from.decimals);
9452
+ if (fullPrecision && fullPrecision !== "0") {
9453
+ handleAmountChange(fullPrecision);
9428
9454
  }
9429
9455
  };
9430
9456
  const handleAccountClick = async () => {
@@ -9435,20 +9461,12 @@ function SwapComponent(props) {
9435
9461
  }
9436
9462
  };
9437
9463
  const truncateAddress = (addr) => `${addr.slice(0, 6)}...${addr.slice(-4)}`;
9438
- const showQuote = () => {
9439
- const p = phase();
9440
- return p === "quoted" || p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking" || p === "success";
9441
- };
9442
- const isExecuting = () => {
9443
- const p = phase();
9444
- return p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking";
9445
- };
9446
- const state = sm.state;
9447
- const bestRoute = () => {
9448
- const s = sm.state();
9449
- if (s.routes.length === 0) return null;
9450
- return s.routes.find((r) => r.routeId === s.selectedRouteId) ?? s.routes[0] ?? null;
9451
- };
9464
+ const quotePreviewRoute = createMemo(() => {
9465
+ const route = bestRoute();
9466
+ if (!route || !store.fromToken() || !store.toToken()) return null;
9467
+ if (phase() === "quoting" || showQuote()) return route;
9468
+ return null;
9469
+ });
9452
9470
  const titleText = createMemo(() => {
9453
9471
  const raw = props.config.titleText?.trim();
9454
9472
  return raw && raw.length > 0 ? raw : "TokenFlight";
@@ -9461,23 +9479,11 @@ function SwapComponent(props) {
9461
9479
  const raw = props.config.titleImageUrl?.trim();
9462
9480
  return raw && raw.length > 0 ? raw : null;
9463
9481
  });
9464
- const isQuoteLoading = createMemo(() => {
9465
- const s = sm.state();
9466
- if (!s.fromToken || !s.toToken) return false;
9467
- return s.phase === "quoting" && parseFloat(s.inputAmount) > 0 && s.routes.length === 0;
9468
- });
9469
- const quotePreviewRoute = createMemo(() => {
9470
- const s = sm.state();
9471
- const route = bestRoute();
9472
- if (!route || !s.fromToken || !s.toToken) return null;
9473
- if (s.phase === "quoting" || showQuote()) return route;
9474
- return null;
9475
- });
9476
9482
  return (() => {
9477
9483
  var _el$ = _tmpl$3$2(), _el$2 = _el$.firstChild;
9478
9484
  insert(_el$, createComponent(Show, {
9479
9485
  get when() {
9480
- return memo(() => state().phase === "success")() && state().order;
9486
+ return memo(() => phase() === "success")() && store.order();
9481
9487
  },
9482
9488
  get fallback() {
9483
9489
  return createComponent(Show, {
@@ -9595,7 +9601,7 @@ function SwapComponent(props) {
9595
9601
  }), null);
9596
9602
  insert(_el$17, createComponent(AmountInput, {
9597
9603
  get value() {
9598
- return state().inputAmount;
9604
+ return store.inputAmount();
9599
9605
  },
9600
9606
  onChange: handleAmountChange,
9601
9607
  get disabled() {
@@ -9604,7 +9610,7 @@ function SwapComponent(props) {
9604
9610
  }), null);
9605
9611
  insert(_el$17, createComponent(Show, {
9606
9612
  get when() {
9607
- return state().fromToken;
9613
+ return store.fromToken();
9608
9614
  },
9609
9615
  get fallback() {
9610
9616
  return (() => {
@@ -9633,21 +9639,21 @@ function SwapComponent(props) {
9633
9639
  addEventListener(_el$18, "click", () => setSelectorOpen("from"));
9634
9640
  insert(_el$19, createComponent(TokenIcon, {
9635
9641
  get symbol() {
9636
- return state().fromToken.symbol ?? "?";
9642
+ return store.fromToken().symbol ?? "?";
9637
9643
  },
9638
9644
  color: "#2775CA",
9639
9645
  size: 24,
9640
9646
  get logoURI() {
9641
- return state().fromToken.logoURI;
9647
+ return store.fromToken().logoURI;
9642
9648
  }
9643
9649
  }), _el$20);
9644
9650
  insert(_el$20, createComponent(ChainDot, {
9645
9651
  size: 10,
9646
9652
  get iconUrl() {
9647
- return chainIconUrl(client().baseUrl, state().fromToken.chainId);
9653
+ return chainIconUrl(client().baseUrl, store.fromToken().chainId);
9648
9654
  }
9649
9655
  }));
9650
- insert(_el$21, () => state().fromToken.symbol);
9656
+ insert(_el$21, () => store.fromToken().symbol);
9651
9657
  insert(_el$22, createComponent(chevron_down_default, {
9652
9658
  size: 14
9653
9659
  }));
@@ -9713,7 +9719,7 @@ function SwapComponent(props) {
9713
9719
  insert(_el$30, () => t("swap.youReceive"));
9714
9720
  insert(_el$29, createComponent(Show, {
9715
9721
  get when() {
9716
- return memo(() => !!isConnected())() && state().toToken;
9722
+ return memo(() => !!isConnected())() && store.toToken();
9717
9723
  },
9718
9724
  get children() {
9719
9725
  var _el$31 = _tmpl$1$2(), _el$32 = _el$31.firstChild;
@@ -9752,17 +9758,17 @@ function SwapComponent(props) {
9752
9758
  var _el$34 = _tmpl$10$2();
9753
9759
  insert(_el$34, createComponent(SignificantNumber, {
9754
9760
  get value() {
9755
- return memo(() => !!(showQuote() || state().phase === "quoting"))() ? state().outputAmount || "0" : "0";
9761
+ return memo(() => !!(showQuote() || phase() === "quoting"))() ? outputAmount() || "0" : "0";
9756
9762
  },
9757
9763
  digits: 8
9758
9764
  }));
9759
- createRenderEffect(() => className(_el$34, `${amountStyles.amount} ${!showQuote() && state().phase !== "quoting" ? amountStyles.muted : ""}`));
9765
+ createRenderEffect(() => className(_el$34, `${amountStyles.amount} ${!showQuote() && phase() !== "quoting" ? amountStyles.muted : ""}`));
9760
9766
  return _el$34;
9761
9767
  }
9762
9768
  }), null);
9763
9769
  insert(_el$33, createComponent(Show, {
9764
9770
  get when() {
9765
- return state().toToken;
9771
+ return store.toToken();
9766
9772
  },
9767
9773
  get fallback() {
9768
9774
  return (() => {
@@ -9791,21 +9797,21 @@ function SwapComponent(props) {
9791
9797
  addEventListener(_el$35, "click", () => setSelectorOpen("to"));
9792
9798
  insert(_el$36, createComponent(TokenIcon, {
9793
9799
  get symbol() {
9794
- return state().toToken.symbol ?? "?";
9800
+ return store.toToken().symbol ?? "?";
9795
9801
  },
9796
9802
  color: "#0052FF",
9797
9803
  size: 24,
9798
9804
  get logoURI() {
9799
- return state().toToken.logoURI;
9805
+ return store.toToken().logoURI;
9800
9806
  }
9801
9807
  }), _el$37);
9802
9808
  insert(_el$37, createComponent(ChainDot, {
9803
9809
  size: 10,
9804
9810
  get iconUrl() {
9805
- return chainIconUrl(client().baseUrl, state().toToken.chainId);
9811
+ return chainIconUrl(client().baseUrl, store.toToken().chainId);
9806
9812
  }
9807
9813
  }));
9808
- insert(_el$38, () => state().toToken.symbol);
9814
+ insert(_el$38, () => store.toToken().symbol);
9809
9815
  insert(_el$39, createComponent(chevron_down_default, {
9810
9816
  size: 14
9811
9817
  }));
@@ -9857,7 +9863,7 @@ function SwapComponent(props) {
9857
9863
  }
9858
9864
  }), createComponent(Show, {
9859
9865
  get when() {
9860
- return memo(() => !!(quotePreviewRoute() && state().fromToken))() && state().toToken;
9866
+ return memo(() => !!(quotePreviewRoute() && store.fromToken()))() && store.toToken();
9861
9867
  },
9862
9868
  get children() {
9863
9869
  var _el$42 = _tmpl$12$1();
@@ -9866,15 +9872,15 @@ function SwapComponent(props) {
9866
9872
  return quotePreviewRoute();
9867
9873
  },
9868
9874
  get fromToken() {
9869
- return state().fromToken;
9875
+ return store.fromToken();
9870
9876
  },
9871
9877
  get toToken() {
9872
- return state().toToken;
9878
+ return store.toToken();
9873
9879
  },
9874
9880
  inline: true,
9875
9881
  countdownSeconds,
9876
9882
  countdownTotal: QUOTE_REFRESH_SECONDS,
9877
- showCountdown: () => state().phase === "quoted"
9883
+ showCountdown: () => phase() === "quoted"
9878
9884
  }));
9879
9885
  createRenderEffect(() => className(_el$42, quoteStyles.quote));
9880
9886
  return _el$42;
@@ -9903,7 +9909,7 @@ function SwapComponent(props) {
9903
9909
  var _el$46 = _tmpl$14();
9904
9910
  insert(_el$46, createComponent(ActionButton, {
9905
9911
  get phase() {
9906
- return state().phase;
9912
+ return phase();
9907
9913
  },
9908
9914
  get isConnected() {
9909
9915
  return isConnected();
@@ -9915,10 +9921,10 @@ function SwapComponent(props) {
9915
9921
  onConfirm: handleConfirm,
9916
9922
  onRetry: handleRetry,
9917
9923
  get errorLabel() {
9918
- return state().error ?? void 0;
9924
+ return store.error() ?? void 0;
9919
9925
  },
9920
9926
  get needsRecipient() {
9921
- return memo(() => !!needRecipient())() && !state().recipient;
9927
+ return memo(() => !!needRecipient())() && !store.recipient();
9922
9928
  },
9923
9929
  onEnterRecipient: () => setRecipientEditorOpen(true),
9924
9930
  get insufficientBalance() {
@@ -9932,13 +9938,13 @@ function SwapComponent(props) {
9932
9938
  get children() {
9933
9939
  return createComponent(OrderProgress, {
9934
9940
  get order() {
9935
- return state().order;
9941
+ return store.order();
9936
9942
  },
9937
9943
  get fromToken() {
9938
- return state().fromToken;
9944
+ return store.fromToken();
9939
9945
  },
9940
9946
  get toToken() {
9941
- return state().toToken;
9947
+ return store.toToken();
9942
9948
  },
9943
9949
  get providerName() {
9944
9950
  return trackingProviderName();
@@ -9950,10 +9956,10 @@ function SwapComponent(props) {
9950
9956
  return props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
9951
9957
  },
9952
9958
  get inputAmount() {
9953
- return state().inputAmount;
9959
+ return store.inputAmount();
9954
9960
  },
9955
9961
  get outputAmount() {
9956
- return state().outputAmount;
9962
+ return outputAmount();
9957
9963
  },
9958
9964
  onNewSwap: handleNewSwap,
9959
9965
  onRetry: handleRetry,
@@ -9974,13 +9980,13 @@ function SwapComponent(props) {
9974
9980
  get children() {
9975
9981
  return createComponent(TransactionComplete, {
9976
9982
  get order() {
9977
- return state().order;
9983
+ return store.order();
9978
9984
  },
9979
9985
  get fromToken() {
9980
- return state().fromToken;
9986
+ return store.fromToken();
9981
9987
  },
9982
9988
  get toToken() {
9983
- return state().toToken;
9989
+ return store.toToken();
9984
9990
  },
9985
9991
  onNewSwap: handleNewSwap,
9986
9992
  get apiEndpoint() {
@@ -10032,16 +10038,16 @@ function SwapComponent(props) {
10032
10038
  }), null);
10033
10039
  insert(_el$, createComponent(Show, {
10034
10040
  get when() {
10035
- return memo(() => !!recipientEditorOpen())() && state().toToken;
10041
+ return memo(() => !!recipientEditorOpen())() && store.toToken();
10036
10042
  },
10037
10043
  get children() {
10038
10044
  var _el$4 = _tmpl$2$2();
10039
10045
  insert(_el$4, createComponent(RecipientEditor, {
10040
10046
  get initialValue() {
10041
- return state().recipient ?? "";
10047
+ return store.recipient() ?? "";
10042
10048
  },
10043
10049
  get chainType() {
10044
- return getChainType(state().toToken.chainId);
10050
+ return getChainType(store.toToken().chainId);
10045
10051
  },
10046
10052
  onConfirm: (addr) => {
10047
10053
  handleRecipientChange(addr);
@@ -10624,21 +10630,219 @@ function rankPayTokens(balances, targetSymbol, targetChainId, targetAddress, des
10624
10630
  if (!hasEnoughGasOnChain(t2.address, t2.chainId, nativeBalanceByChain)) {
10625
10631
  continue;
10626
10632
  }
10627
- const tier = getTier(
10628
- { symbol: t2.symbol, chainId: t2.chainId },
10629
- { symbol: targetSymbol, chainId: targetChainId }
10630
- );
10631
- candidates.push({
10632
- token: t2,
10633
- tier,
10634
- gasCostScore: getChainGasCostScore(t2.chainId)
10633
+ const tier = getTier(
10634
+ { symbol: t2.symbol, chainId: t2.chainId },
10635
+ { symbol: targetSymbol, chainId: targetChainId }
10636
+ );
10637
+ candidates.push({
10638
+ token: t2,
10639
+ tier,
10640
+ gasCostScore: getChainGasCostScore(t2.chainId)
10641
+ });
10642
+ }
10643
+ candidates.sort((a, b) => {
10644
+ if (a.tier !== b.tier) return a.tier - b.tier;
10645
+ return a.gasCostScore - b.gasCostScore;
10646
+ });
10647
+ return candidates.map((c) => c.token);
10648
+ }
10649
+ function isSameToken$1(a, b) {
10650
+ return a.chainId === b.chainId && a.address.toLowerCase() === b.address.toLowerCase();
10651
+ }
10652
+ function useReceiveExecution(params) {
10653
+ const [trackingOrderId, setTrackingOrderId] = createSignal(
10654
+ null
10655
+ );
10656
+ const [trackingProviderName, setTrackingProviderName] = createSignal(null);
10657
+ const [trackingProviderIcon, setTrackingProviderIcon] = createSignal(null);
10658
+ const [trackingInputAmount, setTrackingInputAmount] = createSignal(null);
10659
+ const [executionError, setExecutionError] = createSignal(null);
10660
+ const handleConfirm = async () => {
10661
+ const selectedToken = params.selectedPayToken();
10662
+ const selected2 = selectedToken ? params.payTokenQuotes().find((quote2) => isSameToken$1(quote2.token, selectedToken)) : null;
10663
+ const addr = params.walletAddress();
10664
+ if (!selected2 || !params.client() || !params.walletAdapter() || !addr)
10665
+ return;
10666
+ if (params.needRecipient() && !params.recipient()) {
10667
+ params.setError("Recipient address is required for cross-chain swaps");
10668
+ params.setErrorCode(ErrorCode.INVALID_CONFIG);
10669
+ return;
10670
+ }
10671
+ const validBefore = selected2.route.quote.validBefore;
10672
+ if (validBefore && Date.now() / 1e3 > validBefore) {
10673
+ params.setLoadingQuotes(true);
10674
+ try {
10675
+ const target2 = params.targetToken();
10676
+ if (!target2 || typeof target2.decimals !== "number") return;
10677
+ const baseAmount = toBaseUnits(params.configAmount(), target2.decimals);
10678
+ const refreshed = await params.fetchSingleQuote(
10679
+ params.client(),
10680
+ selected2.token,
10681
+ baseAmount,
10682
+ addr,
10683
+ target2,
10684
+ params.recipient()
10685
+ );
10686
+ if (refreshed) {
10687
+ const updated = [...params.payTokenQuotes()];
10688
+ const existingIdx = updated.findIndex(
10689
+ (quote2) => isSameToken$1(quote2.token, selected2.token)
10690
+ );
10691
+ if (existingIdx >= 0) {
10692
+ updated[existingIdx] = refreshed;
10693
+ } else {
10694
+ updated.push(refreshed);
10695
+ }
10696
+ params.setPayTokenQuotes(updated);
10697
+ } else {
10698
+ params.setError("Quote expired and could not be refreshed");
10699
+ params.setErrorCode(ErrorCode.QUOTE_EXPIRED);
10700
+ return;
10701
+ }
10702
+ } catch {
10703
+ params.setError("Quote expired and could not be refreshed");
10704
+ params.setErrorCode(ErrorCode.QUOTE_EXPIRED);
10705
+ return;
10706
+ } finally {
10707
+ params.setLoadingQuotes(false);
10708
+ }
10709
+ }
10710
+ const confirmedToken = params.selectedPayToken();
10711
+ const confirmedQuote = confirmedToken ? params.payTokenQuotes().find((quote2) => isSameToken$1(quote2.token, confirmedToken)) : null;
10712
+ if (!confirmedQuote) return;
10713
+ params.setFromToken({
10714
+ chainId: confirmedQuote.token.chainId,
10715
+ address: confirmedQuote.token.address,
10716
+ symbol: confirmedQuote.token.symbol,
10717
+ name: confirmedQuote.token.name,
10718
+ decimals: confirmedQuote.token.decimals,
10719
+ logoURI: confirmedQuote.token.logoURI
10720
+ });
10721
+ setTrackingProviderName(confirmedQuote.route.routeId ?? null);
10722
+ const apiBase = params.apiEndpoint() ?? DEFAULT_API_ENDPOINT;
10723
+ setTrackingProviderIcon(
10724
+ confirmedQuote.route.icon ? `${apiBase}${confirmedQuote.route.icon}` : null
10725
+ );
10726
+ setTrackingInputAmount(
10727
+ toDisplayAmount(
10728
+ confirmedQuote.route.quote.amountIn,
10729
+ confirmedQuote.token.decimals
10730
+ )
10731
+ );
10732
+ setExecutionError(null);
10733
+ params.setExecPhase("building");
10734
+ try {
10735
+ const depositData = await params.client().buildDeposit({
10736
+ from: addr,
10737
+ quoteId: confirmedQuote.quoteId,
10738
+ routeId: confirmedQuote.route.routeId
10739
+ });
10740
+ params.setExecPhase("awaiting-wallet");
10741
+ let txHash;
10742
+ let signedTransaction;
10743
+ if (depositData.kind === "CONTRACT_CALL" && depositData.approvals) {
10744
+ for (const approval of depositData.approvals) {
10745
+ if (approval.type === "eip1193_request") {
10746
+ const result = await params.walletAdapter().executeWalletAction({
10747
+ type: "eip1193_request",
10748
+ chainId: confirmedQuote.token.chainId,
10749
+ method: approval.request.method,
10750
+ params: approval.request.params
10751
+ });
10752
+ if (!result.success) {
10753
+ throw new TokenFlightError(
10754
+ ErrorCode.WALLET_ACTION_FAILED,
10755
+ result.error ?? "Wallet action failed"
10756
+ );
10757
+ }
10758
+ if (approval.deposit) txHash = result.txHash ?? txHash;
10759
+ } else if (approval.type === "solana_sendTransaction") {
10760
+ const result = await params.walletAdapter().executeWalletAction({
10761
+ type: "solana_signTransaction",
10762
+ transaction: approval.transaction
10763
+ });
10764
+ if (!result.success) {
10765
+ throw new TokenFlightError(
10766
+ ErrorCode.WALLET_ACTION_FAILED,
10767
+ result.error ?? "Wallet action failed"
10768
+ );
10769
+ }
10770
+ if (approval.deposit) {
10771
+ signedTransaction = typeof result.data === "string" ? result.data : void 0;
10772
+ }
10773
+ }
10774
+ }
10775
+ }
10776
+ if (!txHash && !signedTransaction) {
10777
+ throw new TokenFlightError(
10778
+ ErrorCode.TRANSACTION_FAILED,
10779
+ "No deposit transaction received"
10780
+ );
10781
+ }
10782
+ params.setExecPhase("submitting");
10783
+ const submitResult = await params.client().submitDeposit(
10784
+ signedTransaction ? {
10785
+ quoteId: confirmedQuote.quoteId,
10786
+ routeId: confirmedQuote.route.routeId,
10787
+ signedTransaction
10788
+ } : {
10789
+ quoteId: confirmedQuote.quoteId,
10790
+ routeId: confirmedQuote.route.routeId,
10791
+ txHash
10792
+ }
10793
+ );
10794
+ params.setExecPhase("tracking");
10795
+ setTrackingOrderId(submitResult.orderId);
10796
+ } catch (err) {
10797
+ const errorMsg = err instanceof Error ? err.message : typeof err === "string" ? err : "Transaction failed";
10798
+ setExecutionError(errorMsg);
10799
+ if (err instanceof TokenFlightError) {
10800
+ params.callbacks()?.onSwapError?.({
10801
+ code: err.code,
10802
+ message: err.message,
10803
+ details: err.details
10804
+ });
10805
+ } else {
10806
+ params.callbacks()?.onSwapError?.({
10807
+ code: ErrorCode.TRANSACTION_FAILED,
10808
+ message: String(err)
10809
+ });
10810
+ }
10811
+ }
10812
+ };
10813
+ const handleRetry = () => {
10814
+ batch(() => {
10815
+ setExecutionError(null);
10816
+ params.setExecPhase(null);
10817
+ params.storeClearError();
10818
+ params.setPayTokenQuotes([]);
10635
10819
  });
10636
- }
10637
- candidates.sort((a, b) => {
10638
- if (a.tier !== b.tier) return a.tier - b.tier;
10639
- return a.gasCostScore - b.gasCostScore;
10640
- });
10641
- return candidates.map((c) => c.token);
10820
+ params.onRetry?.();
10821
+ };
10822
+ const handleNewSwap = () => {
10823
+ batch(() => {
10824
+ params.storeReset();
10825
+ setTrackingOrderId(null);
10826
+ setTrackingProviderName(null);
10827
+ setTrackingProviderIcon(null);
10828
+ setTrackingInputAmount(null);
10829
+ setExecutionError(null);
10830
+ params.setPayTokenQuotes([]);
10831
+ });
10832
+ queryClient.removeQueries({ queryKey: ["quote", params.client().baseUrl] });
10833
+ queryClient.removeQueries({ queryKey: ["order", params.client().baseUrl] });
10834
+ params.onReset?.();
10835
+ };
10836
+ return {
10837
+ trackingOrderId,
10838
+ trackingProviderName,
10839
+ trackingProviderIcon,
10840
+ trackingInputAmount,
10841
+ executionError,
10842
+ handleConfirm,
10843
+ handleRetry,
10844
+ handleNewSwap
10845
+ };
10642
10846
  }
10643
10847
  const header = "tf-9b71d6";
10644
10848
  const section = "tf-4c9136";
@@ -10661,24 +10865,40 @@ const styles = {
10661
10865
  fiat
10662
10866
  };
10663
10867
  var _tmpl$$1 = /* @__PURE__ */ template(`<div data-testid=selector-overlay>`), _tmpl$2 = /* @__PURE__ */ template(`<div>`), _tmpl$3 = /* @__PURE__ */ template(`<div part=container><div part=accent-line data-testid=accent-line>`), _tmpl$4 = /* @__PURE__ */ template(`<img width=22 height=22>`), _tmpl$5 = /* @__PURE__ */ template(`<button part=wallet-info><div data-testid=wallet-dot></div><span data-testid=wallet-address>`), _tmpl$6 = /* @__PURE__ */ template(`<div part=header><div><span data-testid=header-title>`), _tmpl$7 = /* @__PURE__ */ template(`<button part=recipient-badge data-testid=recipient-badge><span>`), _tmpl$8 = /* @__PURE__ */ template(`<div><div data-testid=receive-section-label style=display:flex;justify-content:space-between;align-items:center><span></span></div><div part=target-token><div data-testid=receive-target-icon></div><span data-testid=receive-amount></span><span data-testid=receive-symbol></span><span>`), _tmpl$9 = /* @__PURE__ */ template(`<div style="padding:0 20px"><div>`), _tmpl$0 = /* @__PURE__ */ template(`<div part=price-preview data-testid=quote>`), _tmpl$1 = /* @__PURE__ */ template(`<div part=cta-wrapper>`), _tmpl$10 = /* @__PURE__ */ template(`<span>Flight`), _tmpl$11 = /* @__PURE__ */ template(`<div style="padding:0 20px"><div><div><div></div><div><div></div><div></div></div></div><div><div></div><div>`), _tmpl$12 = /* @__PURE__ */ template(`<div part=no-offer><div><svg width=28 height=28 viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round><circle cx=11 cy=11 r=8></circle><path d="m21 21-4.35-4.35"></path><path d="M8 11h6"></path></svg></div><span>`);
10868
+ function normalizeTokenAddress(address) {
10869
+ if (isNativeToken(address) && (address.startsWith("0x") || address.startsWith("0X"))) {
10870
+ return "0x0000000000000000000000000000000000000000";
10871
+ }
10872
+ return address.toLowerCase();
10873
+ }
10664
10874
  function isSameToken(a, b) {
10665
- return a.chainId === b.chainId && a.address.toLowerCase() === b.address.toLowerCase();
10875
+ return a.chainId === b.chainId && normalizeTokenAddress(a.address) === normalizeTokenAddress(b.address);
10666
10876
  }
10667
10877
  function ReceiveComponent(props) {
10668
- const sm = createReceiveStateMachine();
10878
+ const store = createReceiveStore();
10669
10879
  const [selectedPayIndex, setSelectedPayIndex] = createSignal(0);
10670
10880
  const [payTokenSelectorOpen, setPayTokenSelectorOpen] = createSignal(false);
10671
10881
  const [selectorOpen, setSelectorOpen] = createSignal(false);
10672
- const [isConnected, setIsConnected] = createSignal(false);
10673
- const [walletAddress2, setWalletAddress] = createSignal(null);
10674
10882
  const [payTokenQuotes, setPayTokenQuotes] = createSignal([]);
10675
10883
  const [loadingQuotes, setLoadingQuotes] = createSignal(false);
10676
- const [trackingOrderId, setTrackingOrderId] = createSignal(null);
10677
- const [trackingProviderName, setTrackingProviderName] = createSignal(null);
10678
- const [trackingProviderIcon, setTrackingProviderIcon] = createSignal(null);
10679
- const [trackingInputAmount, setTrackingInputAmount] = createSignal(null);
10680
- const [executionError, setExecutionError] = createSignal(null);
10681
10884
  const [selectedPayToken, setSelectedPayToken] = createSignal(null);
10885
+ const {
10886
+ isConnected,
10887
+ walletAddress: walletAddress2,
10888
+ handleConnect
10889
+ } = useWalletConnection({
10890
+ walletAdapter: () => props.walletAdapter,
10891
+ callbacks: () => props.callbacks,
10892
+ onAddressChange: (addr) => store.setWalletAddress(addr),
10893
+ onDisconnect: () => {
10894
+ setPayTokenQuotes([]);
10895
+ setSelectedPayToken(null);
10896
+ },
10897
+ onConnectError: (msg, code) => {
10898
+ store.setError(msg);
10899
+ store.setErrorCode(code);
10900
+ }
10901
+ });
10682
10902
  const client = createMemo(() => {
10683
10903
  const endpoint = props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
10684
10904
  return new HyperstreamApi({
@@ -10686,79 +10906,35 @@ function ReceiveComponent(props) {
10686
10906
  });
10687
10907
  });
10688
10908
  const apiBase = () => client().baseUrl;
10689
- const targetToken = createMemo(() => sm.state().targetToken);
10690
- const phase = createMemo(() => sm.state().phase);
10909
+ const phase = createMemo(() => deriveReceivePhase(store.execPhase(), store.error(), loadingQuotes(), payTokenQuotes().length));
10910
+ const isExecuting = createMemo(() => {
10911
+ const p = phase();
10912
+ return p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking";
10913
+ });
10691
10914
  const [recipientEditorOpen, setRecipientEditorOpen] = createSignal(false);
10692
- const recipientR = createMemo(() => sm.state().recipient);
10693
10915
  const recipientLocked = createMemo(() => !!props.config.recipient);
10694
- const needRecipient = createMemo(() => {
10695
- const target2 = targetToken();
10696
- const from = selectedPayToken();
10697
- if (!target2 || !from || !isConnected()) return false;
10698
- return isCrossChainSwap(from.chainId, target2.chainId);
10699
- });
10700
- const recipientDisplay = createMemo(() => {
10701
- const r = recipientR();
10702
- if (r) return r;
10703
- if (isConnected() && walletAddress2() && !needRecipient()) return walletAddress2();
10704
- return null;
10916
+ const {
10917
+ needRecipient,
10918
+ recipientDisplay,
10919
+ handleRecipientChange
10920
+ } = useRecipient({
10921
+ fromToken: selectedPayToken,
10922
+ toToken: store.targetToken,
10923
+ recipient: store.recipient,
10924
+ isConnected,
10925
+ walletAddress: walletAddress2,
10926
+ walletAdapter: () => props.walletAdapter,
10927
+ setRecipient: store.setRecipient
10705
10928
  });
10706
- const handleRecipientChange = (value2) => {
10707
- const trimmed = value2.trim() || null;
10708
- sm.setRecipient(trimmed);
10709
- };
10710
10929
  const balancesQuery = createTokenBalancesQuery(client, walletAddress2, () => isConnected() && !!walletAddress2(), () => props.walletAdapter?.supportedChainIds);
10711
- const orderQuery = createOrderQuery(client, walletAddress2, trackingOrderId, () => phase() === "tracking" && !!trackingOrderId());
10712
- createEffect(on(() => orderQuery.data, (order) => {
10713
- if (!order || phase() !== "tracking") return;
10714
- sm.setOrder(order);
10715
- if (order.status === "failed" || order.status === "refunded") {
10716
- queryClient.invalidateQueries({
10717
- queryKey: ["tokenBalances", client().baseUrl]
10718
- });
10719
- props.callbacks?.onSwapError?.({
10720
- code: ErrorCode.ORDER_FAILED,
10721
- message: "Order " + order.status
10722
- });
10723
- return;
10724
- }
10725
- if (order.status === "filled") {
10726
- sm.transition("success");
10727
- queryClient.invalidateQueries({
10728
- queryKey: ["tokenBalances", client().baseUrl]
10729
- });
10730
- const selected2 = selectedPayToken();
10731
- props.callbacks?.onSwapSuccess?.({
10732
- orderId: order.id,
10733
- fromToken: selected2?.symbol ?? "",
10734
- toToken: sm.state().targetToken?.symbol ?? "",
10735
- fromAmount: order.srcAmount,
10736
- toAmount: order.destAmount,
10737
- txHash: order.depositTxHash
10738
- });
10739
- }
10740
- }));
10741
10930
  onMount(() => {
10742
10931
  if (props.config.locale) {
10743
10932
  setLocale(props.config.locale);
10744
10933
  }
10745
10934
  if (props.config.recipient) {
10746
- sm.setRecipient(props.config.recipient);
10935
+ store.setRecipient(props.config.recipient);
10747
10936
  }
10748
10937
  });
10749
- createEffect(on(needRecipient, (need) => {
10750
- if (need && !sm.state().recipient && props.walletAdapter) {
10751
- const target2 = sm.state().targetToken;
10752
- if (!target2) return;
10753
- const targetChainType = getChainType(target2.chainId);
10754
- props.walletAdapter.getAddress(targetChainType).then((addr) => {
10755
- if (addr && isAddressForChainType(addr, targetChainType) && !sm.state().recipient && needRecipient()) {
10756
- sm.setRecipient(addr);
10757
- }
10758
- }).catch(() => {
10759
- });
10760
- }
10761
- }));
10762
10938
  const chainsQuery = createChainsQuery(client, () => true);
10763
10939
  const chainMap = createMemo(() => {
10764
10940
  const data = chainsQuery.data;
@@ -10768,18 +10944,20 @@ function ReceiveComponent(props) {
10768
10944
  const c = client();
10769
10945
  const amount2 = Number(props.config.amount);
10770
10946
  if (!Number.isFinite(amount2) || amount2 <= 0) {
10771
- sm.setError("Invalid amount: must be greater than zero", ErrorCode.INVALID_AMOUNT);
10947
+ store.setError("Invalid amount: must be greater than zero");
10948
+ store.setErrorCode(ErrorCode.INVALID_AMOUNT);
10772
10949
  return;
10773
10950
  }
10774
10951
  try {
10775
10952
  const target2 = parseTokenIdentifier(props.config.target);
10776
10953
  const resolved = await resolveToken(target2.chainId, target2.address, props.config.apiEndpoint, c);
10777
10954
  if (typeof resolved.decimals !== "number") {
10778
- sm.setError("Failed to resolve target token metadata", ErrorCode.INVALID_CONFIG);
10955
+ store.setError("Failed to resolve target token metadata");
10956
+ store.setErrorCode(ErrorCode.INVALID_CONFIG);
10779
10957
  return;
10780
10958
  }
10781
- sm.setTargetToken(resolved);
10782
- sm.setTargetAmount(props.config.amount);
10959
+ store.setTargetToken(resolved);
10960
+ store.setTargetAmount(props.config.amount);
10783
10961
  if (props.config.fromToken) {
10784
10962
  try {
10785
10963
  const fromTarget = parseTokenIdentifier(props.config.fromToken);
@@ -10809,60 +10987,13 @@ function ReceiveComponent(props) {
10809
10987
  }
10810
10988
  }
10811
10989
  } catch (err) {
10812
- sm.setError(err instanceof Error ? err.message : "Failed to resolve target token", ErrorCode.INVALID_CONFIG);
10813
- }
10814
- });
10815
- const detectChainType = () => {
10816
- if (!props.walletAdapter) return "evm";
10817
- return props.walletAdapter.supportedActionTypes.some((t2) => t2.startsWith("solana_")) ? "solana" : "evm";
10818
- };
10819
- onMount(async () => {
10820
- if (props.walletAdapter) {
10821
- const connected = props.walletAdapter.isConnected();
10822
- setIsConnected(connected);
10823
- if (connected) {
10824
- const addr = await props.walletAdapter.getAddress();
10825
- setWalletAddress(addr);
10826
- sm.setWalletAddress(addr);
10827
- props.callbacks?.onWalletConnected?.({
10828
- address: addr ?? "",
10829
- chainType: detectChainType()
10830
- });
10831
- }
10832
- const handleWalletConnect = async () => {
10833
- const addr = await props.walletAdapter.getAddress();
10834
- if (isConnected() && walletAddress2() === addr) return;
10835
- batch(() => {
10836
- setIsConnected(true);
10837
- setWalletAddress(addr);
10838
- sm.setWalletAddress(addr);
10839
- });
10840
- props.callbacks?.onWalletConnected?.({
10841
- address: addr ?? "",
10842
- chainType: detectChainType()
10843
- });
10844
- };
10845
- const handleWalletDisconnect = () => {
10846
- if (!isConnected()) return;
10847
- batch(() => {
10848
- setIsConnected(false);
10849
- setWalletAddress(null);
10850
- sm.setWalletAddress(null);
10851
- });
10852
- setPayTokenQuotes([]);
10853
- setSelectedPayToken(null);
10854
- };
10855
- props.walletAdapter.on("connect", handleWalletConnect);
10856
- props.walletAdapter.on("disconnect", handleWalletDisconnect);
10857
- onCleanup(() => {
10858
- props.walletAdapter.off("connect", handleWalletConnect);
10859
- props.walletAdapter.off("disconnect", handleWalletDisconnect);
10860
- });
10990
+ store.setError(err instanceof Error ? err.message : "Failed to resolve target token");
10991
+ store.setErrorCode(ErrorCode.INVALID_CONFIG);
10861
10992
  }
10862
10993
  });
10863
10994
  const balancePayTokens = createMemo(() => {
10864
10995
  const data = balancesQuery.data;
10865
- const target2 = targetToken();
10996
+ const target2 = store.targetToken();
10866
10997
  if (!data || data.length === 0 || !target2) return [];
10867
10998
  const supported = props.walletAdapter?.supportedChainIds;
10868
10999
  const filtered = supported?.length ? data.filter((t2) => supported.includes(t2.chainId)) : data;
@@ -10872,17 +11003,26 @@ function ReceiveComponent(props) {
10872
11003
  return rankPayTokens(filtered, target2.symbol ?? "", target2.chainId, target2.address, desiredUsdAmount > 0 ? desiredUsdAmount : void 0);
10873
11004
  });
10874
11005
  createEffect(on(balancePayTokens, (tokens) => {
10875
- const p = sm.state().phase;
11006
+ const p = phase();
10876
11007
  if (tokens.length > 0 && (p === "idle" || p === "error")) {
10877
11008
  fetchPayTokenQuotes(tokens);
10878
11009
  }
10879
11010
  }));
11011
+ createEffect(on(() => store.recipient(), () => {
11012
+ const tokens = balancePayTokens();
11013
+ const p = phase();
11014
+ if (tokens.length > 0 && (p === "idle" || p === "quoted" || p === "error")) {
11015
+ fetchPayTokenQuotes(tokens);
11016
+ }
11017
+ }, {
11018
+ defer: true
11019
+ }));
10880
11020
  const selectedQuoteRequest = createMemo(() => {
10881
11021
  const token = selectedPayToken();
10882
11022
  if (!token) return null;
10883
- const target2 = targetToken();
11023
+ const target2 = store.targetToken();
10884
11024
  const addr = walletAddress2();
10885
- const recipient = sm.state().recipient;
11025
+ const recipient = store.recipient();
10886
11026
  if (!target2 || typeof target2.decimals !== "number" || !addr) return null;
10887
11027
  if (needRecipient() && !recipient) return null;
10888
11028
  return {
@@ -10925,25 +11065,15 @@ function ReceiveComponent(props) {
10925
11065
  }
10926
11066
  }
10927
11067
  }));
10928
- const [countdownSeconds, setCountdownSeconds] = createSignal(QUOTE_REFRESH_SECONDS);
10929
- createEffect(() => {
10930
- if (phase() !== "quoted") {
10931
- setCountdownSeconds(QUOTE_REFRESH_SECONDS);
10932
- return;
11068
+ const {
11069
+ countdownSeconds
11070
+ } = useQuoteCountdown({
11071
+ phase,
11072
+ onExpired: () => {
11073
+ selectedQuoteQuery.refetch();
10933
11074
  }
10934
- setCountdownSeconds(QUOTE_REFRESH_SECONDS);
10935
- const timer = setInterval(() => {
10936
- setCountdownSeconds((prev) => {
10937
- if (prev <= 1) {
10938
- selectedQuoteQuery.refetch();
10939
- return QUOTE_REFRESH_SECONDS;
10940
- }
10941
- return prev - 1;
10942
- });
10943
- }, 1e3);
10944
- onCleanup(() => clearInterval(timer));
10945
11075
  });
10946
- const fetchSingleQuote = async (c, payToken, baseAmount, addr, target2, recipient) => {
11076
+ const fetchSingleQuote = async (c, payToken, baseAmount, addr, target2, recipient, signal) => {
10947
11077
  try {
10948
11078
  const request = {
10949
11079
  tradeType: "EXACT_OUTPUT",
@@ -10957,9 +11087,11 @@ function ReceiveComponent(props) {
10957
11087
  recipient
10958
11088
  }
10959
11089
  };
10960
- const quoteResp = await queryClient.ensureQueryData({
11090
+ const quoteResp = await queryClient.fetchQuery({
10961
11091
  queryKey: ["quote", c.baseUrl, request],
10962
- queryFn: () => c.getQuotes(request),
11092
+ queryFn: ({
11093
+ signal: querySignal
11094
+ }) => c.getQuotes(request, signal ?? querySignal),
10963
11095
  staleTime: 15e3
10964
11096
  });
10965
11097
  if (quoteResp.routes.length > 0) {
@@ -10982,13 +11114,10 @@ function ReceiveComponent(props) {
10982
11114
  const fetchPayTokenQuotes = async (tokensToQuote) => {
10983
11115
  const c = client();
10984
11116
  const addr = walletAddress2();
10985
- const target2 = sm.state().targetToken;
11117
+ const target2 = store.targetToken();
10986
11118
  if (!c || !addr || !target2 || typeof target2.decimals !== "number" || tokensToQuote.length === 0) return;
10987
- const phase2 = sm.state().phase;
10988
- if (phase2 === "idle" || phase2 === "quoted" || phase2 === "error") {
10989
- if (phase2 === "error") sm.transition("idle");
10990
- sm.transition("quoting");
10991
- }
11119
+ if (payTokenQuotes().length > 0) setPayTokenQuotes([]);
11120
+ if (store.error()) store.clearError();
10992
11121
  setLoadingQuotes(true);
10993
11122
  fetchAbortController?.abort();
10994
11123
  const abortController = new AbortController();
@@ -11000,7 +11129,7 @@ function ReceiveComponent(props) {
11000
11129
  const orderedTokens = preferredToken ? [preferredToken, ...tokensToQuote.filter((token) => !isSameToken(token, preferredToken))] : tokensToQuote;
11001
11130
  for (const payToken of orderedTokens) {
11002
11131
  if (abortController.signal.aborted) return;
11003
- const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, sm.state().recipient);
11132
+ const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, store.recipient(), abortController.signal);
11004
11133
  if (abortController.signal.aborted) return;
11005
11134
  if (quote2) {
11006
11135
  setPayTokenQuotes([quote2]);
@@ -11008,18 +11137,13 @@ function ReceiveComponent(props) {
11008
11137
  setSelectedPayIndex(index >= 0 ? index : 0);
11009
11138
  setSelectedPayToken(payToken);
11010
11139
  setLoadingQuotes(false);
11011
- sm.transition("quoted");
11012
11140
  return;
11013
11141
  }
11014
11142
  }
11015
11143
  if (!abortController.signal.aborted) {
11016
11144
  setPayTokenQuotes([]);
11017
- sm.transition("idle");
11018
11145
  }
11019
11146
  } catch {
11020
- if (!abortController.signal.aborted) {
11021
- sm.transition("idle");
11022
- }
11023
11147
  } finally {
11024
11148
  setLoadingQuotes(false);
11025
11149
  }
@@ -11030,7 +11154,7 @@ function ReceiveComponent(props) {
11030
11154
  const paymentTokens = createMemo(() => {
11031
11155
  const tokens = balancePayTokens();
11032
11156
  const quotes = payTokenQuotes();
11033
- const target2 = targetToken();
11157
+ const target2 = store.targetToken();
11034
11158
  const chains = chainMap();
11035
11159
  if (tokens.length === 0 || !target2) return [];
11036
11160
  const quoteMap = /* @__PURE__ */ new Map();
@@ -11110,13 +11234,81 @@ function ReceiveComponent(props) {
11110
11234
  logoURI: q.token.logoURI
11111
11235
  };
11112
11236
  });
11237
+ const {
11238
+ trackingOrderId,
11239
+ trackingProviderName,
11240
+ trackingProviderIcon,
11241
+ trackingInputAmount,
11242
+ executionError,
11243
+ handleConfirm,
11244
+ handleRetry,
11245
+ handleNewSwap
11246
+ } = useReceiveExecution({
11247
+ client,
11248
+ walletAdapter: () => props.walletAdapter,
11249
+ callbacks: () => props.callbacks,
11250
+ apiEndpoint: () => props.config.apiEndpoint,
11251
+ recipient: store.recipient,
11252
+ needRecipient,
11253
+ walletAddress: walletAddress2,
11254
+ targetToken: store.targetToken,
11255
+ selectedPayToken,
11256
+ payTokenQuotes,
11257
+ setPayTokenQuotes,
11258
+ setLoadingQuotes,
11259
+ fetchSingleQuote,
11260
+ configAmount: () => props.config.amount,
11261
+ setExecPhase: store.setExecPhase,
11262
+ setFromToken: store.setFromToken,
11263
+ setError: store.setError,
11264
+ setErrorCode: store.setErrorCode,
11265
+ storeReset: store.reset,
11266
+ storeClearError: store.clearError,
11267
+ onRetry: () => {
11268
+ setSelectedPayToken(null);
11269
+ const tokens = balancePayTokens();
11270
+ if (tokens.length > 0) fetchPayTokenQuotes(tokens);
11271
+ },
11272
+ onReset: () => {
11273
+ setSelectedPayIndex(0);
11274
+ setSelectedPayToken(null);
11275
+ const tokens = balancePayTokens();
11276
+ if (tokens.length > 0) fetchPayTokenQuotes(tokens);
11277
+ }
11278
+ });
11279
+ useOrderTracking({
11280
+ client,
11281
+ walletAddress: walletAddress2,
11282
+ trackingOrderId,
11283
+ phase,
11284
+ execPhase: store.execPhase,
11285
+ setOrder: store.setOrder,
11286
+ setExecPhase: store.setExecPhase,
11287
+ onOrderFilled: (order) => {
11288
+ const selected2 = selectedPayToken();
11289
+ props.callbacks?.onSwapSuccess?.({
11290
+ orderId: order.id,
11291
+ fromToken: selected2?.symbol ?? "",
11292
+ toToken: store.targetToken()?.symbol ?? "",
11293
+ fromAmount: order.srcAmount,
11294
+ toAmount: order.destAmount,
11295
+ txHash: order.depositTxHash
11296
+ });
11297
+ },
11298
+ onOrderFailed: (order) => {
11299
+ props.callbacks?.onSwapError?.({
11300
+ code: ErrorCode.ORDER_FAILED,
11301
+ message: "Order " + order.status
11302
+ });
11303
+ }
11304
+ });
11113
11305
  const refreshSinglePayTokenQuote = async (payToken) => {
11114
11306
  const c = client();
11115
11307
  const addr = walletAddress2();
11116
- const target2 = sm.state().targetToken;
11308
+ const target2 = store.targetToken();
11117
11309
  if (!c || !addr || !target2 || typeof target2.decimals !== "number") return;
11118
11310
  const baseAmount = toBaseUnits(props.config.amount, target2.decimals);
11119
- const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, sm.state().recipient);
11311
+ const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, store.recipient());
11120
11312
  if (quote2) {
11121
11313
  const existing = payTokenQuotes();
11122
11314
  const updated = [...existing];
@@ -11127,10 +11319,6 @@ function ReceiveComponent(props) {
11127
11319
  updated.push(quote2);
11128
11320
  }
11129
11321
  setPayTokenQuotes(updated);
11130
- if (sm.state().phase === "idle" || sm.state().phase === "quoting") {
11131
- if (sm.state().phase === "idle") sm.transition("quoting");
11132
- sm.transition("quoted");
11133
- }
11134
11322
  }
11135
11323
  };
11136
11324
  const handlePayTokenSelect = (index) => {
@@ -11143,24 +11331,12 @@ function ReceiveComponent(props) {
11143
11331
  void refreshSinglePayTokenQuote(payToken);
11144
11332
  }
11145
11333
  };
11146
- const handleConnect = async () => {
11147
- if (!props.walletAdapter) {
11148
- console.warn("[TokenFlight] No wallet adapter configured. Pass a walletAdapter to enable wallet connection.\nSee: https://embed.tokenflight.ai/guides/wallet-adapter/");
11149
- props.callbacks?.onConnectWallet?.();
11150
- return;
11151
- }
11152
- try {
11153
- await props.walletAdapter.connect();
11154
- } catch {
11155
- sm.setError("Failed to connect wallet", ErrorCode.WALLET_CONNECTION_FAILED);
11156
- }
11157
- };
11158
11334
  const handleTokenSelect = async (token) => {
11159
11335
  setSelectorOpen(false);
11160
11336
  setPayTokenSelectorOpen(false);
11161
11337
  const c = client();
11162
11338
  const addr = walletAddress2();
11163
- const target2 = sm.state().targetToken;
11339
+ const target2 = store.targetToken();
11164
11340
  if (!c || !addr || !target2 || typeof target2.decimals !== "number" || !token.address || typeof token.decimals !== "number") return;
11165
11341
  setLoadingQuotes(true);
11166
11342
  try {
@@ -11176,7 +11352,7 @@ function ReceiveComponent(props) {
11176
11352
  balance: toBaseUnits(token.balance, token.decimals)
11177
11353
  } : void 0
11178
11354
  };
11179
- const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, sm.state().recipient);
11355
+ const quote2 = await fetchSingleQuote(c, payToken, baseAmount, addr, target2, store.recipient());
11180
11356
  if (quote2) {
11181
11357
  const existing = payTokenQuotes();
11182
11358
  const idx = existing.findIndex((q) => q.token.address.toLowerCase() === token.address.toLowerCase() && q.token.chainId === token.chainId);
@@ -11193,165 +11369,12 @@ function ReceiveComponent(props) {
11193
11369
  if (rankedIndex >= 0) {
11194
11370
  setSelectedPayIndex(rankedIndex);
11195
11371
  }
11196
- if (sm.state().phase === "idle" || sm.state().phase === "quoting") {
11197
- if (sm.state().phase === "idle") sm.transition("quoting");
11198
- sm.transition("quoted");
11199
- }
11200
11372
  }
11201
11373
  } catch {
11202
11374
  } finally {
11203
11375
  setLoadingQuotes(false);
11204
11376
  }
11205
11377
  };
11206
- const handleConfirm = async () => {
11207
- const selectedToken = selectedPayToken();
11208
- const selected2 = selectedToken ? payTokenQuotes().find((quote2) => isSameToken(quote2.token, selectedToken)) : null;
11209
- const addr = walletAddress2();
11210
- if (!selected2 || !client() || !props.walletAdapter || !addr) return;
11211
- if (needRecipient() && !sm.state().recipient) {
11212
- sm.setError("Recipient address is required for cross-chain swaps", ErrorCode.INVALID_CONFIG);
11213
- return;
11214
- }
11215
- const validBefore = selected2.route.quote.validBefore;
11216
- if (validBefore && Date.now() / 1e3 > validBefore) {
11217
- setLoadingQuotes(true);
11218
- try {
11219
- const target2 = sm.state().targetToken;
11220
- if (!target2 || typeof target2.decimals !== "number") return;
11221
- const baseAmount = toBaseUnits(props.config.amount, target2.decimals);
11222
- const refreshed = await fetchSingleQuote(client(), selected2.token, baseAmount, addr, target2, sm.state().recipient);
11223
- if (refreshed) {
11224
- const updated = [...payTokenQuotes()];
11225
- const existingIdx = updated.findIndex((quote2) => isSameToken(quote2.token, selected2.token));
11226
- if (existingIdx >= 0) {
11227
- updated[existingIdx] = refreshed;
11228
- } else {
11229
- updated.push(refreshed);
11230
- }
11231
- setPayTokenQuotes(updated);
11232
- } else {
11233
- sm.setError("Quote expired and could not be refreshed", ErrorCode.QUOTE_EXPIRED);
11234
- return;
11235
- }
11236
- } catch {
11237
- sm.setError("Quote expired and could not be refreshed", ErrorCode.QUOTE_EXPIRED);
11238
- return;
11239
- } finally {
11240
- setLoadingQuotes(false);
11241
- }
11242
- }
11243
- const confirmedToken = selectedPayToken();
11244
- const confirmedQuote = confirmedToken ? payTokenQuotes().find((quote2) => isSameToken(quote2.token, confirmedToken)) : null;
11245
- if (!confirmedQuote) return;
11246
- sm.setFromToken({
11247
- chainId: confirmedQuote.token.chainId,
11248
- address: confirmedQuote.token.address,
11249
- symbol: confirmedQuote.token.symbol,
11250
- name: confirmedQuote.token.name,
11251
- decimals: confirmedQuote.token.decimals,
11252
- logoURI: confirmedQuote.token.logoURI
11253
- });
11254
- setTrackingProviderName(confirmedQuote.route.routeId ?? null);
11255
- const apiBase2 = props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
11256
- setTrackingProviderIcon(confirmedQuote.route.icon ? `${apiBase2}${confirmedQuote.route.icon}` : null);
11257
- setTrackingInputAmount(toDisplayAmount(confirmedQuote.route.quote.amountIn, confirmedQuote.token.decimals));
11258
- setExecutionError(null);
11259
- sm.transition("building");
11260
- try {
11261
- const depositData = await client().buildDeposit({
11262
- from: addr,
11263
- quoteId: confirmedQuote.quoteId,
11264
- routeId: confirmedQuote.route.routeId
11265
- });
11266
- sm.transition("awaiting-wallet");
11267
- let txHash;
11268
- if (depositData.kind === "CONTRACT_CALL" && depositData.approvals) {
11269
- for (const approval of depositData.approvals) {
11270
- if (approval.type === "eip1193_request") {
11271
- const result = await props.walletAdapter.executeWalletAction({
11272
- type: "eip1193_request",
11273
- chainId: confirmedQuote.token.chainId,
11274
- method: approval.request.method,
11275
- params: approval.request.params
11276
- });
11277
- if (!result.success) {
11278
- throw new TokenFlightError(ErrorCode.WALLET_ACTION_FAILED, result.error ?? "Wallet action failed");
11279
- }
11280
- if (approval.deposit) txHash = result.txHash ?? txHash;
11281
- } else if (approval.type === "solana_sendTransaction") {
11282
- const result = await props.walletAdapter.executeWalletAction({
11283
- type: "solana_signAndSendTransaction",
11284
- transaction: approval.transaction
11285
- });
11286
- if (!result.success) {
11287
- throw new TokenFlightError(ErrorCode.WALLET_ACTION_FAILED, result.error ?? "Wallet action failed");
11288
- }
11289
- if (approval.deposit) txHash = result.txHash ?? txHash;
11290
- }
11291
- }
11292
- }
11293
- if (!txHash) {
11294
- throw new TokenFlightError(ErrorCode.TRANSACTION_FAILED, "No deposit transaction hash received");
11295
- }
11296
- sm.transition("submitting");
11297
- const submitResult = await client().submitDeposit({
11298
- quoteId: confirmedQuote.quoteId,
11299
- routeId: confirmedQuote.route.routeId,
11300
- txHash
11301
- });
11302
- sm.transition("tracking");
11303
- setTrackingOrderId(submitResult.orderId);
11304
- } catch (err) {
11305
- const errorMsg = err instanceof Error ? err.message : typeof err === "string" ? err : "Transaction failed";
11306
- setExecutionError(errorMsg);
11307
- if (err instanceof TokenFlightError) {
11308
- props.callbacks?.onSwapError?.({
11309
- code: err.code,
11310
- message: err.message,
11311
- details: err.details
11312
- });
11313
- } else {
11314
- props.callbacks?.onSwapError?.({
11315
- code: ErrorCode.TRANSACTION_FAILED,
11316
- message: String(err)
11317
- });
11318
- }
11319
- }
11320
- };
11321
- const handleRetry = () => {
11322
- setExecutionError(null);
11323
- setSelectedPayToken(null);
11324
- sm.transition("idle");
11325
- const tokens = balancePayTokens();
11326
- if (tokens.length > 0) {
11327
- fetchPayTokenQuotes(tokens);
11328
- }
11329
- };
11330
- const handleNewSwap = () => {
11331
- sm.clearRoutes();
11332
- sm.setPaymentAmount("");
11333
- sm.setFromToken(null);
11334
- sm.setOrder(null);
11335
- setSelectedPayIndex(0);
11336
- setSelectedPayToken(null);
11337
- setTrackingOrderId(null);
11338
- setTrackingProviderName(null);
11339
- setTrackingProviderIcon(null);
11340
- setTrackingInputAmount(null);
11341
- setExecutionError(null);
11342
- setPayTokenQuotes([]);
11343
- queryClient.removeQueries({
11344
- queryKey: ["quote", client().baseUrl]
11345
- });
11346
- queryClient.removeQueries({
11347
- queryKey: ["order", client().baseUrl]
11348
- });
11349
- sm.transition("idle");
11350
- const tokens = balancePayTokens();
11351
- if (tokens.length > 0) {
11352
- fetchPayTokenQuotes(tokens);
11353
- }
11354
- };
11355
11378
  const handleAccountClick = async () => {
11356
11379
  if (props.walletAdapter?.openAccountModal) {
11357
11380
  await props.walletAdapter.openAccountModal();
@@ -11360,13 +11383,8 @@ function ReceiveComponent(props) {
11360
11383
  }
11361
11384
  };
11362
11385
  const truncateAddress = (addr) => `${addr.slice(0, 6)}...${addr.slice(-4)}`;
11363
- const state = sm.state;
11364
- const isExecuting = () => {
11365
- const p = phase();
11366
- return p === "building" || p === "awaiting-wallet" || p === "submitting" || p === "tracking";
11367
- };
11368
- const targetSymbol = () => state().targetToken?.symbol ?? "USDC";
11369
- const targetAmount = () => state().targetAmount || props.config.amount;
11386
+ const targetSymbol = () => store.targetToken()?.symbol ?? "USDC";
11387
+ const targetAmount = () => store.targetAmount() || props.config.amount;
11370
11388
  const titleText = createMemo(() => {
11371
11389
  const raw = props.config.titleText?.trim();
11372
11390
  return raw && raw.length > 0 ? raw : "TokenFlight";
@@ -11383,7 +11401,7 @@ function ReceiveComponent(props) {
11383
11401
  var _el$ = _tmpl$3(), _el$2 = _el$.firstChild;
11384
11402
  insert(_el$, createComponent(Show, {
11385
11403
  get when() {
11386
- return memo(() => state().phase === "success")() && state().order;
11404
+ return memo(() => phase() === "success")() && store.order();
11387
11405
  },
11388
11406
  get fallback() {
11389
11407
  return createComponent(Show, {
@@ -11516,19 +11534,19 @@ function ReceiveComponent(props) {
11516
11534
  color: "#0052FF",
11517
11535
  size: 32,
11518
11536
  get logoURI() {
11519
- return state().targetToken?.logoURI;
11537
+ return store.targetToken()?.logoURI;
11520
11538
  }
11521
11539
  }), null);
11522
11540
  insert(_el$16, createComponent(Show, {
11523
11541
  get when() {
11524
- return state().targetToken?.chainId;
11542
+ return store.targetToken()?.chainId;
11525
11543
  },
11526
11544
  get children() {
11527
11545
  var _el$17 = _tmpl$2();
11528
11546
  insert(_el$17, createComponent(ChainDot, {
11529
11547
  size: 12,
11530
11548
  get iconUrl() {
11531
- return chainIconUrl(apiBase(), state().targetToken.chainId);
11549
+ return chainIconUrl(apiBase(), store.targetToken().chainId);
11532
11550
  }
11533
11551
  }));
11534
11552
  createRenderEffect(() => className(_el$17, styles.targetChainDot));
@@ -11631,7 +11649,7 @@ function ReceiveComponent(props) {
11631
11649
  }
11632
11650
  }), createComponent(Show, {
11633
11651
  get when() {
11634
- return memo(() => !!(selectedQuoteRoute() && selectedFromToken()))() && state().targetToken;
11652
+ return memo(() => !!(selectedQuoteRoute() && selectedFromToken()))() && store.targetToken();
11635
11653
  },
11636
11654
  get fallback() {
11637
11655
  return createComponent(Show, {
@@ -11666,7 +11684,7 @@ function ReceiveComponent(props) {
11666
11684
  return selectedFromToken();
11667
11685
  },
11668
11686
  get toToken() {
11669
- return state().targetToken;
11687
+ return store.targetToken();
11670
11688
  },
11671
11689
  inline: true,
11672
11690
  countdownSeconds,
@@ -11680,7 +11698,7 @@ function ReceiveComponent(props) {
11680
11698
  var _el$24 = _tmpl$1();
11681
11699
  insert(_el$24, createComponent(ActionButton, {
11682
11700
  get phase() {
11683
- return state().phase;
11701
+ return phase();
11684
11702
  },
11685
11703
  get isConnected() {
11686
11704
  return isConnected();
@@ -11692,7 +11710,7 @@ function ReceiveComponent(props) {
11692
11710
  onConfirm: handleConfirm,
11693
11711
  onRetry: handleRetry,
11694
11712
  get needsRecipient() {
11695
- return memo(() => !!needRecipient())() && !sm.state().recipient;
11713
+ return memo(() => !!needRecipient())() && !store.recipient();
11696
11714
  },
11697
11715
  onEnterRecipient: () => setRecipientEditorOpen(true),
11698
11716
  get label() {
@@ -11709,13 +11727,13 @@ function ReceiveComponent(props) {
11709
11727
  get children() {
11710
11728
  return createComponent(OrderProgress, {
11711
11729
  get order() {
11712
- return state().order;
11730
+ return store.order();
11713
11731
  },
11714
11732
  get fromToken() {
11715
- return state().fromToken;
11733
+ return store.fromToken();
11716
11734
  },
11717
11735
  get toToken() {
11718
- return state().targetToken;
11736
+ return store.targetToken();
11719
11737
  },
11720
11738
  get providerName() {
11721
11739
  return trackingProviderName();
@@ -11727,10 +11745,10 @@ function ReceiveComponent(props) {
11727
11745
  return props.config.apiEndpoint ?? DEFAULT_API_ENDPOINT;
11728
11746
  },
11729
11747
  get inputAmount() {
11730
- return trackingInputAmount() ?? state().paymentAmount;
11748
+ return trackingInputAmount() ?? "";
11731
11749
  },
11732
11750
  get outputAmount() {
11733
- return state().targetAmount;
11751
+ return store.targetAmount();
11734
11752
  },
11735
11753
  onNewSwap: handleNewSwap,
11736
11754
  mode: "receive",
@@ -11751,13 +11769,13 @@ function ReceiveComponent(props) {
11751
11769
  get children() {
11752
11770
  return createComponent(TransactionComplete, {
11753
11771
  get order() {
11754
- return state().order;
11772
+ return store.order();
11755
11773
  },
11756
11774
  get fromToken() {
11757
- return state().fromToken;
11775
+ return store.fromToken();
11758
11776
  },
11759
11777
  get toToken() {
11760
- return state().targetToken;
11778
+ return store.targetToken();
11761
11779
  },
11762
11780
  onNewSwap: handleNewSwap,
11763
11781
  get apiEndpoint() {
@@ -11807,16 +11825,16 @@ function ReceiveComponent(props) {
11807
11825
  }), null);
11808
11826
  insert(_el$, createComponent(Show, {
11809
11827
  get when() {
11810
- return memo(() => !!recipientEditorOpen())() && sm.state().targetToken;
11828
+ return memo(() => !!recipientEditorOpen())() && store.targetToken();
11811
11829
  },
11812
11830
  get children() {
11813
11831
  var _el$4 = _tmpl$2();
11814
11832
  insert(_el$4, createComponent(RecipientEditor, {
11815
11833
  get initialValue() {
11816
- return sm.state().recipient ?? "";
11834
+ return store.recipient() ?? "";
11817
11835
  },
11818
11836
  get chainType() {
11819
- return getChainType(sm.state().targetToken.chainId);
11837
+ return getChainType(store.targetToken().chainId);
11820
11838
  },
11821
11839
  onConfirm: (addr) => {
11822
11840
  handleRecipientChange(addr);
@@ -11840,22 +11858,22 @@ function ReceiveComponent(props) {
11840
11858
  return _el$;
11841
11859
  })();
11842
11860
  }
11843
- const css0 = ".tf-2de115{width:100%;padding:14px 0;border-radius:14px;border:none;background:linear-gradient(135deg,var(--tf-primary),color-mix(in srgb,var(--tf-primary) 80%,#000));color:var(--tf-text-on-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;box-shadow:0 4px 16px var(--tf-primary-glow);letter-spacing:-.01em;font-family:DM Sans,sans-serif;transition:transform .15s ease,opacity .15s ease,box-shadow .15s ease}.tf-2de115:hover{opacity:.95;transform:translateY(-1px);box-shadow:0 6px 20px var(--tf-primary-glow)}.tf-2de115:active{transform:translateY(0)}.tf-47dc2a{background:var(--tf-primary);cursor:wait;opacity:.85}.tf-44b8f1{width:100%;padding:14px 0;border-radius:14px;border:1px solid var(--tf-primary);background:var(--tf-primary-light);color:var(--tf-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:DM Sans,sans-serif;transition:transform .15s ease,background .15s ease}.tf-44b8f1:hover{transform:translateY(-1px)}.tf-44b8f1:active{transform:translateY(0)}.tf-04fe16{width:100%;padding:14px 0;border-radius:14px;border:1.5px dashed var(--tf-primary);background:var(--tf-primary-light);color:var(--tf-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:DM Sans,sans-serif;transition:transform .15s ease,background .15s ease;animation:tf-d53743 2s ease-in-out infinite}.tf-04fe16:hover{transform:translateY(-1px);background:var(--tf-primary-glow)}.tf-04fe16:active{transform:translateY(0)}.tf-65cf23{width:100%;padding:14px 0;border-radius:14px;text-align:center;background:var(--tf-success-bg);color:var(--tf-success);font-weight:600;font-size:var(--tf-font-xl);display:flex;align-items:center;justify-content:center;gap:8px;border:none}.tf-2f0314{width:100%;padding:14px 0;border-radius:14px;text-align:center;background:var(--tf-error-bg);color:var(--tf-error);font-weight:600;font-size:var(--tf-font-xl);display:flex;align-items:center;justify-content:center;gap:8px;border:none;cursor:pointer}.tf-20b1ac{display:flex;align-items:center;justify-content:center;gap:8px}.tf-e6dae0{display:inline-block;width:16px;height:16px;border-radius:50%;border:2px solid rgba(255,255,255,.3);border-top-color:var(--tf-text-on-primary, #fff);animation:tf-8a3bc2 .8s linear infinite}.tf-90e712{width:14px;height:14px}";
11844
- const css1$1 = ".tf-59b76a{font-size:var(--tf-font-amount);font-weight:700;line-height:100%;letter-spacing:-.02em;color:var(--tf-text);font-family:DM Sans,sans-serif;background:none;border:none;outline:none;width:100%;min-width:0;text-align:left}.tf-59b76a::-webkit-outer-spin-button,.tf-59b76a::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.tf-59b76a{-moz-appearance:textfield}.tf-59b76a::placeholder{color:var(--tf-text-tertiary)}.tf-a859d8{color:var(--tf-text-tertiary)}";
11845
- const css1 = '@keyframes tf-d36961{to{transform:rotate(360deg)}}.tf-5835df{padding:24px 20px 16px;animation:tf-e061c9 .3s ease both}.tf-9322ae{display:flex;align-items:center;justify-content:center;gap:12px;padding-bottom:20px;margin-bottom:4px;border-bottom:1px solid var(--tf-border-light)}.tf-7d5519{display:flex;align-items:center;gap:8px}.tf-7e8fdf{position:relative;width:32px;height:32px;flex-shrink:0}.tf-37f3cf{position:absolute;bottom:-2px;right:-2px;width:16px;height:16px;border-radius:50%;background:var(--tf-bg);display:flex;align-items:center;justify-content:center;border:1.5px solid var(--tf-bg)}.tf-9401fd{display:flex;flex-direction:column}.tf-832fae{font-family:JetBrains Mono,monospace;font-weight:600;font-size:var(--tf-font-lg);color:var(--tf-text);white-space:nowrap;line-height:1.2}.tf-b557fc{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-weight:500;line-height:1.2}.tf-5953e8{color:var(--tf-text-tertiary);flex-shrink:0}.tf-a168c7{display:flex;align-items:center;justify-content:center;gap:6px;text-align:center;font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);padding-bottom:16px}.tf-062404{width:16px;height:16px;border-radius:4px;object-fit:contain}.tf-26af4c{display:flex;flex-direction:column}.tf-4b9be7{display:flex;gap:12px}.tf-036db2{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:var(--tf-font-base);font-weight:600;z-index:1}.tf-09b7bb{background:var(--tf-success-bg);color:var(--tf-success)}.tf-aef7e0{background:var(--tf-primary-light)}.tf-5c628c{background:var(--tf-input-bg);color:var(--tf-text-tertiary);border:1px solid var(--tf-border-light)}.tf-a5abdf{background:var(--tf-error-bg);color:var(--tf-error)}.tf-9efe7c{width:14px;height:14px;border-radius:50%;border:2px solid var(--tf-primary-light);border-top-color:var(--tf-primary);animation:tf-d36961 .8s linear infinite}.tf-5c7806{border-color:#ff475733;border-top-color:var(--tf-error)}.tf-185719{flex:1;padding-bottom:20px;position:relative}.tf-185719:before{content:"";position:absolute;left:-26px;top:28px;bottom:0;width:2px;background:var(--tf-border-light)}.tf-4b9be7:last-child .tf-185719:before{display:none}.tf-4b9be7:last-child .tf-185719{padding-bottom:4px}.tf-84527b .tf-185719:before{background:var(--tf-success)}.tf-417d35 .tf-185719:before{background:var(--tf-error)}.tf-aad7e9{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-text);line-height:28px}.tf-8de1c6 .tf-aad7e9{color:var(--tf-text-tertiary)}.tf-417d35 .tf-aad7e9{color:var(--tf-error)}.tf-bcb46a{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);margin-top:2px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.tf-16cfdc .tf-bcb46a{color:var(--tf-primary)}.tf-0aa291{font-size:var(--tf-font-sm);color:var(--tf-primary);text-decoration:none;display:inline-flex;align-items:center;gap:3px;transition:opacity .15s}.tf-0aa291:hover{opacity:.7}.tf-234e31{margin-top:20px;padding:16px;border-radius:12px;background:var(--tf-error-alpha, rgba(239, 68, 68, .06));border:1px solid var(--tf-error-bg);text-align:center}.tf-adb588{font-size:var(--tf-font-md);color:var(--tf-text-secondary);line-height:1.5;margin-bottom:12px}.tf-11fa21{display:inline-flex;align-items:center;gap:4px;font-size:var(--tf-font-base);color:var(--tf-primary);text-decoration:none;margin-bottom:12px;transition:opacity .15s}.tf-11fa21:hover{opacity:.7}.tf-4f7573{width:100%;padding:12px;border-radius:12px;background:linear-gradient(135deg,var(--tf-success),color-mix(in srgb,var(--tf-success) 80%,#000));color:var(--tf-text-on-primary);font-size:var(--tf-font-lg);font-weight:600;cursor:pointer;border:none;transition:opacity .2s,transform .15s}.tf-4f7573:hover{opacity:.9;transform:translateY(-1px)}.tf-4f7573:active{transform:scale(.98)}.tf-c918a2{margin-top:16px;text-align:center}.tf-ad7aab{visibility:hidden;pointer-events:none}.tf-1e22cb{width:100%;padding:12px;border-radius:12px;background:var(--tf-bg-secondary);color:var(--tf-text);font-size:var(--tf-font-lg);font-weight:600;cursor:pointer;border:1px solid var(--tf-border);transition:opacity .2s,transform .15s}.tf-1e22cb:hover{opacity:.85;transform:translateY(-1px)}.tf-1e22cb:active{transform:scale(.98)}';
11861
+ const css0 = ".tf-2de115{width:100%;padding:14px 0;border-radius:14px;border:none;background:linear-gradient(135deg,var(--tf-primary),color-mix(in srgb,var(--tf-primary) 80%,#000));color:var(--tf-text-on-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;box-shadow:0 4px 16px var(--tf-primary-glow);letter-spacing:-.01em;font-family:var(--tf-font-family);transition:transform .15s ease,opacity .15s ease,box-shadow .15s ease}.tf-2de115:hover{opacity:.95;transform:translateY(-1px);box-shadow:0 6px 20px var(--tf-primary-glow)}.tf-2de115:active{transform:translateY(0)}.tf-47dc2a{background:var(--tf-primary);cursor:wait;opacity:.85}.tf-44b8f1{width:100%;padding:14px 0;border-radius:14px;border:1px solid var(--tf-primary);background:var(--tf-primary-light);color:var(--tf-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:var(--tf-font-family);transition:transform .15s ease,background .15s ease}.tf-44b8f1:hover{transform:translateY(-1px)}.tf-44b8f1:active{transform:translateY(0)}.tf-04fe16{width:100%;padding:14px 0;border-radius:14px;border:1.5px dashed var(--tf-primary);background:var(--tf-primary-light);color:var(--tf-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:var(--tf-font-family);transition:transform .15s ease,background .15s ease;animation:tf-d53743 2s ease-in-out infinite}.tf-04fe16:hover{transform:translateY(-1px);background:var(--tf-primary-glow)}.tf-04fe16:active{transform:translateY(0)}.tf-65cf23{width:100%;padding:14px 0;border-radius:14px;text-align:center;background:var(--tf-success-bg);color:var(--tf-success);font-weight:600;font-size:var(--tf-font-xl);display:flex;align-items:center;justify-content:center;gap:8px;border:none}.tf-2f0314{width:100%;padding:14px 0;border-radius:14px;text-align:center;background:var(--tf-error-bg);color:var(--tf-error);font-weight:600;font-size:var(--tf-font-xl);display:flex;align-items:center;justify-content:center;gap:8px;border:none;cursor:pointer}.tf-20b1ac{display:flex;align-items:center;justify-content:center;gap:8px}.tf-e6dae0{display:inline-block;width:16px;height:16px;border-radius:50%;border:2px solid rgba(255,255,255,.3);border-top-color:var(--tf-text-on-primary, #fff);animation:tf-8a3bc2 .8s linear infinite}.tf-90e712{width:14px;height:14px}";
11862
+ const css1$1 = ".tf-59b76a{font-size:var(--tf-font-amount);font-weight:700;line-height:100%;letter-spacing:-.02em;color:var(--tf-text);font-family:var(--tf-font-family);background:none;border:none;outline:none;width:100%;min-width:0;text-align:left}.tf-59b76a::-webkit-outer-spin-button,.tf-59b76a::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.tf-59b76a{-moz-appearance:textfield}.tf-59b76a::placeholder{color:var(--tf-text-tertiary)}.tf-a859d8{color:var(--tf-text-tertiary)}";
11863
+ const css1 = '@keyframes tf-d36961{to{transform:rotate(360deg)}}.tf-5835df{padding:24px 20px 16px;animation:tf-e061c9 .3s ease both;overflow:hidden}.tf-9322ae{display:flex;align-items:center;justify-content:center;gap:12px;padding-bottom:20px;margin-bottom:4px;border-bottom:1px solid var(--tf-border-light)}.tf-7d5519{display:flex;align-items:center;justify-content:flex-start;min-width:0;flex:1}.tf-0b8d30{justify-content:flex-end}.tf-bfbd0b{display:flex;align-items:center;gap:8px;min-width:0}.tf-7e8fdf{position:relative;width:32px;height:32px;flex-shrink:0}.tf-37f3cf{position:absolute;bottom:-2px;right:-2px;width:16px;height:16px;border-radius:50%;background:var(--tf-bg);display:flex;align-items:center;justify-content:center;border:1.5px solid var(--tf-bg)}.tf-9401fd{display:flex;flex-direction:column;min-width:0;overflow:hidden}.tf-832fae{font-family:var(--tf-font-family-mono);font-weight:600;font-size:var(--tf-font-lg);color:var(--tf-text);white-space:nowrap;line-height:1.2}.tf-b557fc{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-weight:500;line-height:1.2}.tf-5953e8{color:var(--tf-text-tertiary);flex-shrink:0}.tf-a168c7{display:flex;align-items:center;justify-content:center;gap:6px;text-align:center;font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);padding-bottom:16px}.tf-062404{width:16px;height:16px;border-radius:4px;object-fit:contain}.tf-26af4c{display:flex;flex-direction:column}.tf-4b9be7{display:flex;gap:12px}.tf-036db2{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:var(--tf-font-base);font-weight:600;z-index:1}.tf-09b7bb{background:var(--tf-success-bg);color:var(--tf-success)}.tf-aef7e0{background:var(--tf-primary-light)}.tf-5c628c{background:var(--tf-input-bg);color:var(--tf-text-tertiary);border:1px solid var(--tf-border-light)}.tf-a5abdf{background:var(--tf-error-bg);color:var(--tf-error)}.tf-9efe7c{width:14px;height:14px;border-radius:50%;border:2px solid var(--tf-primary-light);border-top-color:var(--tf-primary);animation:tf-d36961 .8s linear infinite}.tf-5c7806{border-color:#ff475733;border-top-color:var(--tf-error)}.tf-185719{flex:1;min-width:0;padding-bottom:20px;position:relative}.tf-185719:before{content:"";position:absolute;left:-26px;top:28px;bottom:0;width:2px;background:var(--tf-border-light)}.tf-4b9be7:last-child .tf-185719:before{display:none}.tf-4b9be7:last-child .tf-185719{padding-bottom:4px}.tf-84527b .tf-185719:before{background:var(--tf-success)}.tf-417d35 .tf-185719:before{background:var(--tf-error)}.tf-aad7e9{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-text);line-height:28px}.tf-8de1c6 .tf-aad7e9{color:var(--tf-text-tertiary)}.tf-417d35 .tf-aad7e9{color:var(--tf-error)}.tf-bcb46a{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);margin-top:2px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;word-break:break-word;overflow-wrap:break-word}.tf-16cfdc .tf-bcb46a{color:var(--tf-primary)}.tf-0aa291{font-size:var(--tf-font-sm);color:var(--tf-primary);text-decoration:none;display:inline-flex;align-items:center;gap:3px;transition:opacity .15s}.tf-0aa291:hover{opacity:.7}.tf-234e31{margin-top:20px;padding:16px;border-radius:12px;background:var(--tf-error-alpha, rgba(239, 68, 68, .06));border:1px solid var(--tf-error-bg);text-align:center}.tf-adb588{font-size:var(--tf-font-md);color:var(--tf-text-secondary);line-height:1.5;margin-bottom:12px}.tf-11fa21{display:inline-flex;align-items:center;gap:4px;font-size:var(--tf-font-base);color:var(--tf-primary);text-decoration:none;margin-bottom:12px;transition:opacity .15s}.tf-11fa21:hover{opacity:.7}.tf-4f7573{width:100%;padding:12px;border-radius:12px;background:linear-gradient(135deg,var(--tf-success),color-mix(in srgb,var(--tf-success) 80%,#000));color:var(--tf-text-on-primary);font-size:var(--tf-font-lg);font-weight:600;cursor:pointer;border:none;transition:opacity .2s,transform .15s}.tf-4f7573:hover{opacity:.9;transform:translateY(-1px)}.tf-4f7573:active{transform:scale(.98)}.tf-c918a2{margin-top:16px;text-align:center}.tf-ad7aab{visibility:hidden;pointer-events:none}.tf-1e22cb{width:100%;padding:12px;border-radius:12px;background:var(--tf-bg-secondary);color:var(--tf-text);font-size:var(--tf-font-lg);font-weight:600;cursor:pointer;border:1px solid var(--tf-border);transition:opacity .2s,transform .15s}.tf-1e22cb:hover{opacity:.85;transform:translateY(-1px)}.tf-1e22cb:active{transform:scale(.98)}';
11846
11864
  const css3 = ".tf-216412{display:inline-flex;align-items:center;gap:4px}.tf-52dc68{flex-shrink:0}.tf-fd32be{font-size:var(--tf-font-sm);color:var(--tf-text-secondary);min-width:20px}";
11847
- const css4 = ".tf-1019c2{margin:12px 20px 0;padding:14px;background:var(--tf-primary-light);border-radius:10px;font-size:var(--tf-font-base);color:var(--tf-text-secondary);animation:tf-42889f .25s ease both}.tf-4922f1{display:flex;justify-content:space-between;align-items:center;min-height:16px;margin-bottom:4px}.tf-4922f1:last-child{margin-bottom:0}.tf-57f45f{font-family:JetBrains Mono,monospace;font-size:var(--tf-font-sm)}.tf-a57ec8{display:block;height:131px;box-sizing:border-box}.tf-d74ccc{display:flex;justify-content:space-between;align-items:center;height:22px}.tf-92e7a8{width:68px;height:14px}.tf-d20f50{width:56px}.tf-a9a96f{width:150px;height:14px}.tf-0134eb{width:126px}.tf-91635c{width:80px}.tf-ca1291{cursor:pointer;border-bottom:1px solid var(--tf-border-light);margin-bottom:10px;transition:opacity .15s}.tf-ca1291:hover{opacity:.7}.tf-ca1291 .tf-57f45f{display:inline-flex;align-items:center;gap:4px}.tf-ca1291 .tf-57f45f svg{opacity:.35;flex-shrink:0;transition:opacity .15s}.tf-ca1291:hover .tf-57f45f svg{opacity:.7}.tf-a249b3 .tf-recipient-placeholder{color:var(--tf-error)}.tf-adeddd{border:1px dashed var(--tf-primary);border-radius:var(--tf-radius, 10px);padding:8px 12px;margin-bottom:10px;animation:tf-d990e5 2s ease-in-out infinite}.tf-adeddd .tf-recipient-placeholder{color:var(--tf-primary);font-style:normal}";
11848
- const css6 = ".tf-636daf{width:100%;height:100%;background:var(--tf-bg);display:flex;flex-direction:column;border-radius:20px;overflow:hidden}.tf-fddfab{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--tf-border-light)}.tf-970eb9{font-size:var(--tf-font-2xl);font-weight:600;color:var(--tf-text)}.tf-de123a{background:none;border:none;padding:4px;cursor:pointer;color:var(--tf-text-secondary);display:flex;align-items:center;justify-content:center;border-radius:6px;transition:background .15s}.tf-de123a:hover{background:var(--tf-bg-elevated)}.tf-0445e3{flex:1;padding:20px;display:flex;flex-direction:column;gap:8px}.tf-9a65ec{width:100%;min-height:80px;background:var(--tf-input-bg);border:1px solid var(--tf-border-light);border-radius:12px;padding:12px 14px;font-size:var(--tf-font-lg);font-family:JetBrains Mono,monospace;color:var(--tf-text);outline:none;resize:none;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.tf-9a65ec::placeholder{color:var(--tf-text-tertiary)}.tf-9a65ec:focus{border-color:var(--tf-primary);box-shadow:0 0 0 3px var(--tf-primary-alpha)}.tf-c5ea21{border-color:var(--tf-error)}.tf-c5ea21:focus{border-color:var(--tf-error);box-shadow:0 0 0 3px var(--tf-error-alpha)}.tf-9d4bba{font-size:var(--tf-font-base);color:var(--tf-error);padding:0 2px}.tf-cb9b60{padding:16px 20px 20px}.tf-2cba65{width:100%}.tf-2cba65:disabled{opacity:.5;cursor:not-allowed}";
11865
+ const css4 = ".tf-1019c2{margin:12px 20px 0;padding:14px;background:var(--tf-primary-light);border-radius:10px;font-size:var(--tf-font-base);color:var(--tf-text-secondary);animation:tf-42889f .25s ease both}.tf-4922f1{display:flex;justify-content:space-between;align-items:center;min-height:16px;margin-bottom:4px}.tf-4922f1:last-child{margin-bottom:0}.tf-57f45f{font-family:var(--tf-font-family-mono);font-size:var(--tf-font-sm)}.tf-a57ec8{display:block;height:131px;box-sizing:border-box}.tf-d74ccc{display:flex;justify-content:space-between;align-items:center;height:22px}.tf-92e7a8{width:68px;height:14px}.tf-d20f50{width:56px}.tf-a9a96f{width:150px;height:14px}.tf-0134eb{width:126px}.tf-91635c{width:80px}.tf-ca1291{cursor:pointer;border-bottom:1px solid var(--tf-border-light);margin-bottom:10px;transition:opacity .15s}.tf-ca1291:hover{opacity:.7}.tf-ca1291 .tf-57f45f{display:inline-flex;align-items:center;gap:4px}.tf-ca1291 .tf-57f45f svg{opacity:.35;flex-shrink:0;transition:opacity .15s}.tf-ca1291:hover .tf-57f45f svg{opacity:.7}.tf-a249b3 .tf-recipient-placeholder{color:var(--tf-error)}.tf-adeddd{border:1px dashed var(--tf-primary);border-radius:var(--tf-radius, 10px);padding:8px 12px;margin-bottom:10px;animation:tf-d990e5 2s ease-in-out infinite}.tf-adeddd .tf-recipient-placeholder{color:var(--tf-primary);font-style:normal}";
11866
+ const css6 = ".tf-636daf{width:100%;height:100%;background:var(--tf-bg);display:flex;flex-direction:column;border-radius:20px;overflow:hidden}.tf-fddfab{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--tf-border-light)}.tf-970eb9{font-size:var(--tf-font-2xl);font-weight:600;color:var(--tf-text)}.tf-de123a{background:none;border:none;padding:4px;cursor:pointer;color:var(--tf-text-secondary);display:flex;align-items:center;justify-content:center;border-radius:6px;transition:background .15s}.tf-de123a:hover{background:var(--tf-bg-elevated)}.tf-0445e3{flex:1;padding:20px;display:flex;flex-direction:column;gap:8px}.tf-9a65ec{width:100%;min-height:80px;background:var(--tf-input-bg);border:1px solid var(--tf-border-light);border-radius:12px;padding:12px 14px;font-size:var(--tf-font-lg);font-family:var(--tf-font-family-mono);color:var(--tf-text);outline:none;resize:none;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.tf-9a65ec::placeholder{color:var(--tf-text-tertiary)}.tf-9a65ec:focus{border-color:var(--tf-primary);box-shadow:0 0 0 3px var(--tf-primary-alpha)}.tf-c5ea21{border-color:var(--tf-error)}.tf-c5ea21:focus{border-color:var(--tf-error);box-shadow:0 0 0 3px var(--tf-error-alpha)}.tf-9d4bba{font-size:var(--tf-font-base);color:var(--tf-error);padding:0 2px}.tf-cb9b60{padding:16px 20px 20px}.tf-2cba65{width:100%}.tf-2cba65:disabled{opacity:.5;cursor:not-allowed}";
11849
11867
  const css7 = ".tf-ba406b{display:inline-flex;align-items:baseline}.tf-9d81a4{font-size:.7em;line-height:1;opacity:.85}.tf-7977ef{cursor:help}";
11850
- const css8 = "@keyframes tf-07c947{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.tf-dc5721{padding:18px 20px 0;display:flex;justify-content:space-between;align-items:center}.tf-68123c{display:flex;align-items:center;gap:7px}.tf-43dda9{visibility:hidden}.tf-532d07{width:22px;height:22px;object-fit:contain;flex-shrink:0}.tf-b7936a{font-size:var(--tf-font-xl);font-weight:600;letter-spacing:-.01em}.tf-883305{color:var(--tf-primary)}.tf-6da3db{display:flex;gap:6px;align-items:center;cursor:pointer;background:none;border:none;padding:4px 8px;border-radius:8px;font-family:inherit;transition:background .15s ease}.tf-6da3db:hover{background:var(--tf-surface-hover)}.tf-6da3db:focus-visible{outline:2px solid var(--tf-primary);outline-offset:2px}.tf-d25568{width:8px;height:8px;border-radius:50%;background:var(--tf-primary);box-shadow:0 0 8px var(--tf-primary-glow)}.tf-16ce7d{background:var(--tf-success);box-shadow:0 0 8px var(--tf-success)}.tf-11bb1d{font-size:var(--tf-font-base);color:var(--tf-text-secondary);font-family:JetBrains Mono,monospace}.tf-98d625{padding:14px 20px 0;animation:tf-07c947 .3s ease both}.tf-8b7743{padding:0 20px;animation:tf-07c947 .35s ease both}.tf-677ece{background:var(--tf-input-bg);border-radius:14px;padding:14px 16px;border:1px solid var(--tf-border-light);transition:border-color .2s,background .25s ease,box-shadow .2s ease}.tf-635915{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.tf-b8a04a{display:inline-flex;align-items:center;gap:8px}.tf-0d1ef8{font-size:var(--tf-font-base);color:var(--tf-text-tertiary);font-weight:500;text-align:left}.tf-d04a4e{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}.tf-d7140f{display:flex;justify-content:space-between;align-items:center}.tf-dcd620{display:flex;align-items:center;gap:8px;background:var(--tf-surface);border-radius:10px;padding:6px 12px 6px 8px;height:36px;box-sizing:border-box;border:1px solid var(--tf-border);cursor:pointer;flex-shrink:0;font-family:DM Sans,sans-serif;transition:background .15s ease,border-color .15s ease,transform .1s ease}.tf-dcd620:hover{background:var(--tf-surface-hover);transform:scale(1.02)}.tf-e25a5c{padding:0 12px}.tf-038cf1{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-33c9cb{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-primary)}.tf-b1e4a6{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary)}.tf-d168ae{display:flex;justify-content:space-between;align-items:center;margin-top:6px;min-height:16px;font-size:var(--tf-font-base);line-height:100%}.tf-b2b098{margin-top:6px;min-height:16px;display:flex;align-items:center}.tf-92acfd{display:inline-block;min-height:16px;font-size:var(--tf-font-base);line-height:100%;color:var(--tf-text-tertiary)}.tf-bd2f5c{visibility:hidden}.tf-5f8805{font-size:var(--tf-font-sm);font-weight:600;color:var(--tf-primary);background:var(--tf-primary-light);border:none;padding:2px 8px;border-radius:6px;cursor:pointer;font-family:DM Sans,sans-serif}.tf-5f8805:hover{opacity:.8}.tf-af41ab{display:flex;justify-content:center;margin:-6px 0;position:relative;z-index:2}.tf-18c3f4{width:36px;height:36px;padding:0;appearance:none;-webkit-appearance:none;border-radius:10px;background:var(--tf-surface);border:3px solid var(--tf-bg);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px #0000000f;font-size:var(--tf-font-lg);color:var(--tf-text-secondary);transition:transform .2s ease,background .15s ease,color .15s ease}.tf-18c3f4:hover{transform:scale(1.1);color:var(--tf-primary)}.tf-18c3f4:active{transform:scale(.95) rotate(180deg)}.tf-a04b23{position:relative;flex-shrink:0}.tf-57762e{position:absolute;bottom:-2px;right:-2px}";
11851
- const css9 = ".tf-140273{width:100%;max-width:400px;border-radius:20px;overflow:hidden;background:var(--tf-bg);border:1px solid var(--tf-border);box-shadow:var(--tf-shadow-lg);font-family:DM Sans,sans-serif;color:var(--tf-text);height:100%;display:flex;flex-direction:column}.tf-45030f{padding:18px 20px 14px;flex-shrink:0}.tf-ce0622{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}.tf-0c1692{font-size:var(--tf-font-xl);font-weight:600}.tf-64aa3f{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--tf-text-tertiary);font-size:var(--tf-font-2xl);font-weight:300;background:var(--tf-input-bg);border:none;font-family:DM Sans,sans-serif}.tf-9819ca{display:flex;align-items:center;gap:10px;background:var(--tf-input-bg);border-radius:12px;padding:10px 14px;border:1px solid var(--tf-border-light);transition:border-color .15s}.tf-9819ca.tf-d9fcd6{border-color:var(--tf-primary)}.tf-4ad0e7{color:var(--tf-text-tertiary);font-size:var(--tf-font-lg);flex-shrink:0}.tf-9ea859{flex:1;border:none;background:none;outline:none;font-size:var(--tf-font-lg);color:var(--tf-text);font-family:DM Sans,sans-serif}.tf-9ea859::placeholder{color:var(--tf-text-tertiary)}.tf-25e112{display:flex;gap:4px;margin-top:12px;overflow-x:auto;padding-bottom:2px}.tf-478cb9{display:flex;align-items:center;gap:5px;padding:4px 10px;border-radius:8px;border:none;font-size:var(--tf-font-sm);font-weight:500;cursor:pointer;white-space:nowrap;font-family:DM Sans,sans-serif;background:var(--tf-input-bg);color:var(--tf-text-secondary)}.tf-478cb9.tf-125be5{background:var(--tf-primary-light);color:var(--tf-primary);outline:1px solid var(--tf-primary);outline-offset:-1px}.tf-bb4fb1{height:24px;border-radius:8px;flex-shrink:0}.tf-ad5703{height:1px;background:var(--tf-border);margin:0 20px;flex-shrink:0}.tf-de9986{flex:1;min-height:0;overflow-y:auto;padding:6px 8px}.tf-7ac0fe{display:flex;flex-direction:column}.tf-c6ef08{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px}.tf-3643cf{display:flex;align-items:center;gap:12px}.tf-9b3d59{width:36px;height:36px;border-radius:50%}.tf-a4cc17{display:flex;flex-direction:column;gap:6px}.tf-7f1baf{display:flex;flex-direction:column;align-items:flex-end;gap:6px}.tf-9171a2{height:10px}.tf-9171a2.tf-71ea5d{width:88px}.tf-9171a2.tf-dfb33a{width:64px}.tf-9171a2.tf-43fbf4{width:56px}.tf-9171a2.tf-61ca3c{width:44px}.tf-512365{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px;cursor:pointer;background:transparent;transition:background .1s;border:none;width:100%;font-family:DM Sans,sans-serif}.tf-512365:hover{background:var(--tf-surface-hover)}.tf-512365.tf-9f601f{background:var(--tf-primary-light)}.tf-a0b0d9{display:flex;align-items:center;gap:12px}.tf-1e7a62{position:relative}.tf-67f18a{position:absolute;bottom:-1px;right:-1px;width:13px;height:13px;border-radius:50%;background:var(--tf-surface);border:1px solid var(--tf-border);display:flex;align-items:center;justify-content:center}.tf-cd76b9{text-align:left;display:flex;flex-direction:column;align-items:flex-start}.tf-8f4efd{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-51bf2b{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-87740a{text-align:right}.tf-43fbf4{font-size:var(--tf-font-md);font-weight:500;font-family:JetBrains Mono,monospace}.tf-43fbf4.tf-2ee375{color:var(--tf-text-tertiary)}.tf-61ca3c{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}";
11852
- const css10 = "@keyframes tf-72a7b4{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.05)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes tf-7ca8ca{0%{transform:translateY(0) rotate(0)}to{transform:translateY(-4px) rotate(8deg)}}@keyframes tf-2b6de5{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes tf-5b8ef8{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.tf-e98a9a{padding:28px 20px 24px;display:flex;flex-direction:column;align-items:center;animation:tf-2b6de5 .35s ease both}.tf-1f9019{width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,var(--tf-success),#00E6A0);display:flex;align-items:center;justify-content:center;margin-bottom:16px;animation:tf-72a7b4 .6s ease both;box-shadow:0 8px 32px #00c48c40;color:var(--tf-text-on-primary)}.tf-73631f{animation:tf-7ca8ca 2s ease-in-out infinite alternate;display:flex}.tf-9e3a66{font-size:var(--tf-font-heading);font-weight:700;color:var(--tf-text);margin-bottom:4px;letter-spacing:-.01em}.tf-db06d4{font-size:var(--tf-font-md);color:var(--tf-text-secondary);margin-bottom:20px}.tf-c9a5e1{width:100%;padding:20px;border-radius:16px;background:linear-gradient(135deg,#00c48c14,#00e6a00a);border:1px solid rgba(0,196,140,.15);display:flex;flex-direction:column;align-items:center;gap:6px;margin-bottom:16px;animation:tf-2b6de5 .4s ease .2s both}.tf-789d4e{margin-bottom:4px}.tf-f52291{font-size:var(--tf-font-amount-lg);font-weight:700;color:var(--tf-text);font-family:JetBrains Mono,monospace;letter-spacing:-.02em;display:flex;align-items:baseline;gap:8px}.tf-8cfc86{font-size:var(--tf-font-lg);font-weight:500;color:var(--tf-text-secondary)}.tf-4f945b{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-weight:500;display:flex;align-items:center;gap:5px}.tf-75f592{width:100%;margin-bottom:16px}.tf-73910d{width:100%;display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--tf-input-bg);border:1px solid var(--tf-border-light);border-radius:10px;cursor:pointer;font-size:var(--tf-font-base);font-weight:500;color:var(--tf-text-secondary);font-family:DM Sans,sans-serif;transition:background .15s}.tf-73910d:hover{background:var(--tf-bg-secondary)}.tf-ae94a0{border-radius:10px 10px 0 0}.tf-1afb0a{transition:transform .2s ease;color:var(--tf-text-tertiary)}.tf-7737cf{transform:rotate(180deg)}.tf-92a530{padding:8px 14px 12px;border:1px solid var(--tf-border-light);border-top:none;border-radius:0 0 10px 10px;background:var(--tf-input-bg);animation:tf-5b8ef8 .15s ease both}.tf-6e8c3e{display:flex;justify-content:space-between;align-items:center;font-size:var(--tf-font-sm);padding:5px 0}.tf-4b5396{color:var(--tf-text-tertiary);font-weight:500}.tf-63cca1{color:var(--tf-text-secondary);font-family:JetBrains Mono,monospace;font-size:var(--tf-font-sm);display:flex;align-items:center;gap:4px}.tf-18c122{color:var(--tf-primary);text-decoration:none;font-size:var(--tf-font-sm);font-family:JetBrains Mono,monospace;display:inline-flex;align-items:center;gap:3px;transition:opacity .15s}.tf-18c122:hover{opacity:.7}.tf-d7e813{width:100%;padding:14px 0;border-radius:14px;border:none;background:var(--tf-primary);color:var(--tf-text-on-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:DM Sans,sans-serif;box-shadow:0 4px 16px color-mix(in srgb,var(--tf-primary) 25%,transparent);transition:transform .15s ease,opacity .15s ease}.tf-d7e813:hover{opacity:.95;transform:translateY(-1px)}.tf-d7e813:active{transform:translateY(0)}";
11853
- const css11 = ".tf-c63ac0{border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tf-text-on-primary);font-weight:700;font-family:DM Sans,sans-serif;flex-shrink:0;overflow:hidden}.tf-59aca7{width:100%;height:100%;object-fit:cover;border-radius:50%}.tf-dbfbb3{border-radius:50%;flex-shrink:0;overflow:hidden;display:flex;align-items:center;justify-content:center}.tf-f89395{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}.tf-cdfe94{display:flex;align-items:center;justify-content:center;gap:6px;padding:12px 0 14px;border-top:1px solid var(--tf-border-light);margin:8px 20px 0;text-decoration:none}.tf-7c0c36{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-26d5ea{font-size:var(--tf-font-base);line-height:1}.tf-8b1e15{font-size:var(--tf-font-sm);font-weight:600;letter-spacing:.02em;color:var(--tf-text-secondary)}.tf-3852e5,.tf-b35860{color:var(--tf-primary)}";
11854
- const css12 = "@keyframes tf-80a677{to{transform:rotate(360deg)}}@keyframes tf-d97ff2{0%,to{opacity:1}50%{opacity:.4}}@keyframes tf-c3558b{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes tf-89a83e{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(6px)}}@keyframes tf-ca9155{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes tf-d2dbc4{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes tf-54b7e7{0%,to{border-color:var(--tf-primary)}50%{border-color:var(--tf-primary-light)}}@keyframes tf-194f18{to{transform:rotate(360deg)}}@keyframes tf-cdef4a{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.05)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes tf-fd8795{0%{transform:translateY(0) rotate(0)}to{transform:translateY(-4px) rotate(8deg)}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important}}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{display:block;font-family:DM Sans,sans-serif;color:var(--tf-text);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--tf-font-2xs: 10px;--tf-font-xs: 11px;--tf-font-sm: 12px;--tf-font-base: 13px;--tf-font-md: 14px;--tf-font-lg: 15px;--tf-font-xl: 16px;--tf-font-2xl: 17px;--tf-font-heading: 20px;--tf-font-amount: 28px;--tf-font-amount-lg: 24px;--tf-font-amount-sm: 22px}button:focus-visible,a:focus-visible{outline:2px solid var(--tf-primary);outline-offset:2px;border-radius:4px}";
11855
- const css13 = ".tf-1ac2ef{border-radius:6px;background:var(--tf-skeleton);animation:tf-90e981 1.5s infinite}.tf-68a980{position:absolute;inset:0;border-radius:20px;display:flex;align-items:flex-start;z-index:10;overflow:hidden;animation:tf-552c66 .2s ease both}.tf-e7b9c7{width:100%;max-width:400px;min-width:360px;border-radius:20px;overflow:hidden;background:var(--tf-bg);border:1px solid var(--tf-border);box-shadow:var(--tf-shadow-lg);font-family:DM Sans,sans-serif;color:var(--tf-text);position:relative;transition:background .25s ease,border-color .25s ease,box-shadow .25s ease}.tf-b4f391{background:transparent}.tf-118b57{border:none;box-shadow:none}.tf-118b57 .tf-07225e{display:none}.tf-07225e{height:2px;background:linear-gradient(90deg,transparent,var(--tf-primary),transparent);opacity:.6}.tf-d01dff{padding:16px 20px 20px;animation:tf-ed0355 .3s ease .1s both}.tf-5bb68c{padding:12px 20px 0}.tf-04e1e2{margin:12px 20px 0;padding:14px;background:var(--tf-primary-light);border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;height:131px;box-sizing:border-box;animation:tf-b61e63 .25s ease both}.tf-d01908{color:var(--tf-text-tertiary);opacity:.4}.tf-1cc72b{font-size:var(--tf-font-base);color:var(--tf-text-secondary)}.tf-480f1a{padding:0 20px 16px;text-align:center}.tf-480f1a a{font-size:var(--tf-font-base);color:var(--tf-primary);text-decoration:none;font-family:JetBrains Mono,monospace}.tf-bc7950{text-align:center;margin-top:8px;margin-bottom:10px}.tf-bc7950 a{font-size:var(--tf-font-sm);color:var(--tf-primary);text-decoration:none;font-family:JetBrains Mono,monospace}.tf-d9b7b4{display:inline-flex;align-items:center;gap:4px;background:var(--tf-surface);border:1px solid var(--tf-border);border-radius:6px;padding:2px 8px;cursor:pointer;font-size:var(--tf-font-sm);font-family:JetBrains Mono,monospace;color:var(--tf-text-secondary);transition:background .15s,border-color .15s}.tf-d9b7b4:hover{background:var(--tf-surface-hover)}.tf-d9b7b4 svg{opacity:.4;transition:opacity .15s}.tf-d9b7b4:hover svg{opacity:.7}.tf-9398ea{border-style:dashed;border-color:var(--tf-primary)}.tf-9398ea .tf-2d9323{color:var(--tf-primary);font-style:italic;font-family:DM Sans,sans-serif}.tf-4567e1{cursor:default;opacity:.8}.tf-4567e1:hover{background:var(--tf-surface)}.tf-58881e{color:var(--tf-text-tertiary);font-style:italic}";
11868
+ const css8 = "@keyframes tf-07c947{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.tf-dc5721{padding:18px 20px 0;display:flex;justify-content:space-between;align-items:center}.tf-68123c{display:flex;align-items:center;gap:7px}.tf-43dda9{visibility:hidden}.tf-532d07{width:22px;height:22px;object-fit:contain;flex-shrink:0}.tf-b7936a{font-size:var(--tf-font-xl);font-weight:600;letter-spacing:-.01em}.tf-883305{color:var(--tf-primary)}.tf-6da3db{display:flex;gap:6px;align-items:center;cursor:pointer;background:none;border:none;padding:4px 8px;border-radius:8px;font-family:inherit;transition:background .15s ease}.tf-6da3db:hover{background:var(--tf-surface-hover)}.tf-6da3db:focus-visible{outline:2px solid var(--tf-primary);outline-offset:2px}.tf-d25568{width:8px;height:8px;border-radius:50%;background:var(--tf-primary);box-shadow:0 0 8px var(--tf-primary-glow)}.tf-16ce7d{background:var(--tf-success);box-shadow:0 0 8px var(--tf-success)}.tf-11bb1d{font-size:var(--tf-font-base);color:var(--tf-text-secondary);font-family:var(--tf-font-family-mono)}.tf-98d625{padding:14px 20px 0;animation:tf-07c947 .3s ease both}.tf-8b7743{padding:0 20px;animation:tf-07c947 .35s ease both}.tf-677ece{background:var(--tf-input-bg);border-radius:14px;padding:14px 16px;border:1px solid var(--tf-border-light);transition:border-color .2s,background .25s ease,box-shadow .2s ease}.tf-635915{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.tf-b8a04a{display:inline-flex;align-items:center;gap:8px}.tf-0d1ef8{font-size:var(--tf-font-base);color:var(--tf-text-tertiary);font-weight:500;text-align:left}.tf-d04a4e{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}.tf-d7140f{display:flex;justify-content:space-between;align-items:center}.tf-dcd620{display:flex;align-items:center;gap:8px;background:var(--tf-surface);border-radius:10px;padding:6px 12px 6px 8px;height:36px;box-sizing:border-box;border:1px solid var(--tf-border);cursor:pointer;flex-shrink:0;font-family:var(--tf-font-family);transition:background .15s ease,border-color .15s ease,transform .1s ease}.tf-dcd620:hover{background:var(--tf-surface-hover);transform:scale(1.02)}.tf-e25a5c{padding:0 12px}.tf-038cf1{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-33c9cb{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-primary)}.tf-b1e4a6{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary)}.tf-d168ae{display:flex;justify-content:space-between;align-items:center;margin-top:6px;min-height:16px;font-size:var(--tf-font-base);line-height:100%}.tf-b2b098{margin-top:6px;min-height:16px;display:flex;align-items:center}.tf-92acfd{display:inline-block;min-height:16px;font-size:var(--tf-font-base);line-height:100%;color:var(--tf-text-tertiary)}.tf-bd2f5c{visibility:hidden}.tf-5f8805{font-size:var(--tf-font-sm);font-weight:600;color:var(--tf-primary);background:var(--tf-primary-light);border:none;padding:2px 8px;border-radius:6px;cursor:pointer;font-family:var(--tf-font-family)}.tf-5f8805:hover{opacity:.8}.tf-af41ab{display:flex;justify-content:center;margin:-6px 0;position:relative;z-index:2}.tf-18c3f4{width:36px;height:36px;padding:0;appearance:none;-webkit-appearance:none;border-radius:10px;background:var(--tf-surface);border:3px solid var(--tf-bg);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px #0000000f;font-size:var(--tf-font-lg);color:var(--tf-text-secondary);transition:transform .2s ease,background .15s ease,color .15s ease}.tf-18c3f4:hover{transform:scale(1.1);color:var(--tf-primary)}.tf-18c3f4:active{transform:scale(.95) rotate(180deg)}.tf-a04b23{position:relative;flex-shrink:0}.tf-57762e{position:absolute;bottom:-2px;right:-2px}";
11869
+ const css9 = ".tf-140273{width:100%;max-width:400px;border-radius:20px;overflow:hidden;background:var(--tf-bg);border:1px solid var(--tf-border);box-shadow:var(--tf-shadow-lg);font-family:var(--tf-font-family);color:var(--tf-text);height:100%;display:flex;flex-direction:column}.tf-45030f{padding:18px 20px 14px;flex-shrink:0}.tf-ce0622{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}.tf-0c1692{font-size:var(--tf-font-xl);font-weight:600}.tf-64aa3f{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--tf-text-tertiary);font-size:var(--tf-font-2xl);font-weight:300;background:var(--tf-input-bg);border:none;font-family:var(--tf-font-family)}.tf-9819ca{display:flex;align-items:center;gap:10px;background:var(--tf-input-bg);border-radius:12px;padding:10px 14px;border:1px solid var(--tf-border-light);transition:border-color .15s}.tf-9819ca.tf-d9fcd6{border-color:var(--tf-primary)}.tf-4ad0e7{color:var(--tf-text-tertiary);font-size:var(--tf-font-lg);flex-shrink:0}.tf-9ea859{flex:1;border:none;background:none;outline:none;font-size:var(--tf-font-lg);color:var(--tf-text);font-family:var(--tf-font-family)}.tf-9ea859::placeholder{color:var(--tf-text-tertiary)}.tf-25e112{display:flex;gap:4px;margin-top:12px;overflow-x:auto;padding-bottom:2px}.tf-478cb9{display:flex;align-items:center;gap:5px;padding:4px 10px;border-radius:8px;border:none;font-size:var(--tf-font-sm);font-weight:500;cursor:pointer;white-space:nowrap;font-family:var(--tf-font-family);background:var(--tf-input-bg);color:var(--tf-text-secondary)}.tf-478cb9.tf-125be5{background:var(--tf-primary-light);color:var(--tf-primary);outline:1px solid var(--tf-primary);outline-offset:-1px}.tf-bb4fb1{height:24px;border-radius:8px;flex-shrink:0}.tf-ad5703{height:1px;background:var(--tf-border);margin:0 20px;flex-shrink:0}.tf-de9986{flex:1;min-height:0;overflow-y:auto;padding:6px 8px}.tf-7ac0fe{display:flex;flex-direction:column}.tf-c6ef08{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px}.tf-3643cf{display:flex;align-items:center;gap:12px}.tf-9b3d59{width:36px;height:36px;border-radius:50%}.tf-a4cc17{display:flex;flex-direction:column;gap:6px}.tf-7f1baf{display:flex;flex-direction:column;align-items:flex-end;gap:6px}.tf-9171a2{height:10px}.tf-9171a2.tf-71ea5d{width:88px}.tf-9171a2.tf-dfb33a{width:64px}.tf-9171a2.tf-43fbf4{width:56px}.tf-9171a2.tf-61ca3c{width:44px}.tf-512365{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px;cursor:pointer;background:transparent;transition:background .1s;border:none;width:100%;font-family:var(--tf-font-family)}.tf-512365:hover{background:var(--tf-surface-hover)}.tf-512365.tf-9f601f{background:var(--tf-primary-light)}.tf-a0b0d9{display:flex;align-items:center;gap:12px}.tf-1e7a62{position:relative}.tf-67f18a{position:absolute;bottom:-1px;right:-1px;width:13px;height:13px;border-radius:50%;background:var(--tf-surface);border:1px solid var(--tf-border);display:flex;align-items:center;justify-content:center}.tf-cd76b9{text-align:left;display:flex;flex-direction:column;align-items:flex-start}.tf-8f4efd{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-51bf2b{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-87740a{text-align:right}.tf-43fbf4{color:var(--tf-text);font-size:var(--tf-font-md);font-weight:500;font-family:var(--tf-font-family-mono)}.tf-43fbf4.tf-2ee375{color:var(--tf-text-tertiary)}.tf-61ca3c{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}";
11870
+ const css10 = "@keyframes tf-72a7b4{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.05)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes tf-7ca8ca{0%{transform:translateY(0) rotate(0)}to{transform:translateY(-4px) rotate(8deg)}}@keyframes tf-2b6de5{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes tf-5b8ef8{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.tf-e98a9a{padding:28px 20px 24px;display:flex;flex-direction:column;align-items:center;animation:tf-2b6de5 .35s ease both}.tf-1f9019{width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,var(--tf-success),#00E6A0);display:flex;align-items:center;justify-content:center;margin-bottom:16px;animation:tf-72a7b4 .6s ease both;box-shadow:0 8px 32px #00c48c40;color:var(--tf-text-on-primary)}.tf-73631f{animation:tf-7ca8ca 2s ease-in-out infinite alternate;display:flex}.tf-9e3a66{font-size:var(--tf-font-heading);font-weight:700;color:var(--tf-text);margin-bottom:4px;letter-spacing:-.01em}.tf-db06d4{font-size:var(--tf-font-md);color:var(--tf-text-secondary);margin-bottom:20px}.tf-c9a5e1{width:100%;padding:20px;border-radius:16px;background:linear-gradient(135deg,#00c48c14,#00e6a00a);border:1px solid rgba(0,196,140,.15);display:flex;flex-direction:column;align-items:center;gap:6px;margin-bottom:16px;animation:tf-2b6de5 .4s ease .2s both}.tf-7b3b5b{position:relative;width:40px;height:40px;margin-bottom:4px}.tf-651299{position:absolute;bottom:-2px;right:-2px;width:16px;height:16px;border-radius:50%;background:var(--tf-bg);display:flex;align-items:center;justify-content:center;border:1.5px solid rgba(0,196,140,.15)}.tf-f52291{font-size:var(--tf-font-amount-lg);font-weight:700;color:var(--tf-text);font-family:var(--tf-font-family-mono);letter-spacing:-.02em;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;justify-content:center}.tf-8cfc86{font-size:var(--tf-font-lg);font-weight:500;color:var(--tf-text-secondary)}.tf-5f768d{font-size:var(--tf-font-sm);font-weight:500;font-family:var(--tf-font-family);color:var(--tf-text-tertiary);letter-spacing:0}.tf-75f592{width:100%;margin-bottom:16px}.tf-73910d{width:100%;display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:var(--tf-input-bg);border:1px solid var(--tf-border-light);border-radius:10px;cursor:pointer;font-size:var(--tf-font-base);font-weight:500;color:var(--tf-text-secondary);font-family:var(--tf-font-family);transition:background .15s}.tf-73910d:hover{background:var(--tf-bg-secondary)}.tf-ae94a0{border-radius:10px 10px 0 0}.tf-1afb0a{transition:transform .2s ease;color:var(--tf-text-tertiary)}.tf-7737cf{transform:rotate(180deg)}.tf-92a530{padding:8px 14px 12px;border:1px solid var(--tf-border-light);border-top:none;border-radius:0 0 10px 10px;background:var(--tf-input-bg);animation:tf-5b8ef8 .15s ease both}.tf-6e8c3e{display:flex;justify-content:space-between;align-items:center;font-size:var(--tf-font-sm);padding:5px 0}.tf-4b5396{color:var(--tf-text-tertiary);font-weight:500}.tf-63cca1{color:var(--tf-text-secondary);font-family:var(--tf-font-family-mono);font-size:var(--tf-font-sm);display:flex;align-items:center;gap:4px}.tf-18c122{color:var(--tf-primary);text-decoration:none;font-size:var(--tf-font-sm);font-family:var(--tf-font-family-mono);display:inline-flex;align-items:center;gap:3px;transition:opacity .15s}.tf-18c122:hover{opacity:.7}.tf-d7e813{width:100%;padding:14px 0;border-radius:14px;border:none;background:var(--tf-primary);color:var(--tf-text-on-primary);font-weight:600;font-size:var(--tf-font-xl);cursor:pointer;font-family:var(--tf-font-family);box-shadow:0 4px 16px color-mix(in srgb,var(--tf-primary) 25%,transparent);transition:transform .15s ease,opacity .15s ease}.tf-d7e813:hover{opacity:.95;transform:translateY(-1px)}.tf-d7e813:active{transform:translateY(0)}";
11871
+ const css11 = ".tf-c63ac0{border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tf-text-on-primary);font-weight:700;font-family:var(--tf-font-family);flex-shrink:0;overflow:hidden}.tf-59aca7{width:100%;height:100%;object-fit:cover;border-radius:50%}.tf-dbfbb3{border-radius:50%;flex-shrink:0;overflow:hidden;display:flex;align-items:center;justify-content:center}.tf-f89395{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}.tf-cdfe94{display:flex;align-items:center;justify-content:center;gap:6px;padding:12px 0 14px;border-top:1px solid var(--tf-border-light);margin:8px 20px 0;text-decoration:none}.tf-7c0c36{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-26d5ea{font-size:var(--tf-font-base);line-height:1}.tf-8b1e15{font-size:var(--tf-font-sm);font-weight:600;letter-spacing:.02em;color:var(--tf-text-secondary)}.tf-3852e5,.tf-b35860{color:var(--tf-primary)}";
11872
+ const css12 = '@keyframes tf-80a677{to{transform:rotate(360deg)}}@keyframes tf-d97ff2{0%,to{opacity:1}50%{opacity:.4}}@keyframes tf-c3558b{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes tf-89a83e{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(6px)}}@keyframes tf-ca9155{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes tf-d2dbc4{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes tf-54b7e7{0%,to{border-color:var(--tf-primary)}50%{border-color:var(--tf-primary-light)}}@keyframes tf-194f18{to{transform:rotate(360deg)}}@keyframes tf-cdef4a{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.05)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes tf-fd8795{0%{transform:translateY(0) rotate(0)}to{transform:translateY(-4px) rotate(8deg)}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important}}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{display:block;color:var(--tf-text);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--tf-font-family: "DM Sans", sans-serif;--tf-font-family-mono: "JetBrains Mono", monospace;font-family:var(--tf-font-family);--tf-font-2xs: 10px;--tf-font-xs: 11px;--tf-font-sm: 12px;--tf-font-base: 13px;--tf-font-md: 14px;--tf-font-lg: 15px;--tf-font-xl: 16px;--tf-font-2xl: 17px;--tf-font-heading: 20px;--tf-font-amount: 28px;--tf-font-amount-lg: 24px;--tf-font-amount-sm: 22px}button:focus-visible,a:focus-visible{outline:2px solid var(--tf-primary);outline-offset:2px;border-radius:4px}';
11873
+ const css13 = ".tf-1ac2ef{border-radius:6px;background:var(--tf-skeleton);animation:tf-90e981 1.5s infinite}.tf-68a980{position:absolute;inset:0;border-radius:20px;display:flex;align-items:flex-start;z-index:10;overflow:hidden;animation:tf-552c66 .2s ease both}.tf-e7b9c7{width:100%;max-width:400px;min-width:360px;border-radius:20px;overflow:hidden;background:var(--tf-bg);border:1px solid var(--tf-border);box-shadow:var(--tf-shadow-lg);font-family:var(--tf-font-family);color:var(--tf-text);position:relative;transition:background .25s ease,border-color .25s ease,box-shadow .25s ease}.tf-b4f391{background:transparent}.tf-118b57{border:none;box-shadow:none}.tf-118b57 .tf-07225e{display:none}.tf-07225e{height:2px;background:linear-gradient(90deg,transparent,var(--tf-primary),transparent);opacity:.6}.tf-d01dff{padding:16px 20px 20px;animation:tf-ed0355 .3s ease .1s both}.tf-5bb68c{padding:12px 20px 0}.tf-04e1e2{margin:12px 20px 0;padding:14px;background:var(--tf-primary-light);border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;height:131px;box-sizing:border-box;animation:tf-b61e63 .25s ease both}.tf-d01908{color:var(--tf-text-tertiary);opacity:.4}.tf-1cc72b{font-size:var(--tf-font-base);color:var(--tf-text-secondary)}.tf-480f1a{padding:0 20px 16px;text-align:center}.tf-480f1a a{font-size:var(--tf-font-base);color:var(--tf-primary);text-decoration:none;font-family:var(--tf-font-family-mono)}.tf-bc7950{text-align:center;margin-top:8px;margin-bottom:10px}.tf-bc7950 a{font-size:var(--tf-font-sm);color:var(--tf-primary);text-decoration:none;font-family:var(--tf-font-family-mono)}.tf-d9b7b4{display:inline-flex;align-items:center;gap:4px;background:var(--tf-surface);border:1px solid var(--tf-border);border-radius:6px;padding:2px 8px;cursor:pointer;font-size:var(--tf-font-sm);font-family:var(--tf-font-family-mono);color:var(--tf-text-secondary);transition:background .15s,border-color .15s}.tf-d9b7b4:hover{background:var(--tf-surface-hover)}.tf-d9b7b4 svg{opacity:.4;transition:opacity .15s}.tf-d9b7b4:hover svg{opacity:.7}.tf-9398ea{border-style:dashed;border-color:var(--tf-primary)}.tf-9398ea .tf-2d9323{color:var(--tf-primary);font-style:italic;font-family:var(--tf-font-family)}.tf-4567e1{cursor:default;opacity:.8}.tf-4567e1:hover{background:var(--tf-surface)}.tf-58881e{color:var(--tf-text-tertiary);font-style:italic}";
11856
11874
  const swapCss = [css0, css1$1, css1, css3, css4, css6, css7, css8, css9, css10, css11, css12, css13].join("\n");
11857
- const css2 = "@keyframes tf-540423{to{transform:rotate(360deg)}}.tf-d61a98{padding:0 20px}.tf-4574e9{height:162px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--tf-border) transparent}.tf-4574e9::-webkit-scrollbar{width:4px}.tf-4574e9::-webkit-scrollbar-track{background:transparent}.tf-4574e9::-webkit-scrollbar-thumb{background:var(--tf-border);border-radius:2px}.tf-2f8db2{display:flex;align-items:center;justify-content:space-between;padding:9px 11px;border-radius:11px;margin-bottom:4px;cursor:pointer;border:1px solid var(--tf-border-light);background:transparent;width:100%;font-family:DM Sans,sans-serif;transition:background .15s ease,border-color .15s ease}.tf-aaf1d0{border-color:var(--tf-primary);outline:.5px solid var(--tf-primary);outline-offset:-1px;background:var(--tf-primary-light)}.tf-328e9e{opacity:.4;cursor:not-allowed}.tf-af2c71{cursor:default;pointer-events:none}.tf-d7d776{width:32px;height:32px;border-radius:50%}.tf-c3e864{display:flex;align-items:center;padding:10px 14px;border-radius:12px;border:1px solid var(--tf-border-light);background:var(--tf-input-bg);cursor:default;pointer-events:none}.tf-44450a{display:flex;flex-direction:column;gap:6px}.tf-6c1e97{height:10px}.tf-2174f1{width:52px}.tf-2d3530{width:40px}.tf-2733a9{display:flex;flex-direction:column;align-items:flex-end;gap:6px}.tf-54150b{width:60px}.tf-7aabe1{width:44px}.tf-c41b7c{display:flex;align-items:center;gap:9px}.tf-142024{position:relative}.tf-3b42da{position:absolute;bottom:-1px;right:-1px;width:11px;height:11px;border-radius:50%;background:var(--tf-surface);border:1px solid var(--tf-border);display:flex;align-items:center;justify-content:center}.tf-b7faa4{text-align:left}.tf-1ae7a3{display:flex;align-items:center;gap:5px}.tf-b949b8{font-size:var(--tf-font-base);font-weight:600;color:var(--tf-text)}.tf-2f811b{font-size:var(--tf-font-2xs);font-weight:700;padding:1px 4px;border-radius:3px;background:var(--tf-success-bg);color:var(--tf-success);letter-spacing:.03em}.tf-6542b9{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary)}.tf-e613ff{text-align:right}.tf-630df3{font-size:var(--tf-font-base);font-weight:600;font-family:JetBrains Mono,monospace;color:var(--tf-text)}.tf-0be2ff{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}.tf-dad192{font-size:var(--tf-font-base);font-weight:600;font-family:JetBrains Mono,monospace;color:var(--tf-text)}.tf-840c29{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}.tf-09818b{display:flex;align-items:center;padding:10px 14px;border-radius:12px;border:1px solid var(--tf-border-light);background:var(--tf-input-bg);cursor:pointer;width:100%;font-family:DM Sans,sans-serif;transition:background .15s ease,border-color .15s ease}.tf-09818b:hover{border-color:var(--tf-primary);background:var(--tf-primary-light)}.tf-c7ba0f{display:flex;align-items:center;gap:9px}.tf-dea0cb{text-align:left}.tf-41931a{display:flex;align-items:center;gap:5px}.tf-3d2f5a{margin-left:auto;text-align:right;margin-right:8px}.tf-9a379d{font-size:var(--tf-font-lg);font-weight:500;font-family:JetBrains Mono,monospace;color:var(--tf-text);letter-spacing:-.02em}.tf-c11354{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}.tf-864468{color:var(--tf-text-tertiary);display:flex;align-items:center;flex-shrink:0;transition:transform .2s ease}.tf-8299cf{flex:1;overflow-y:auto;padding:0 8px 8px;scrollbar-width:thin;scrollbar-color:var(--tf-border) transparent}.tf-176d77{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px;cursor:pointer;background:transparent;transition:background .1s;border:none;width:100%;font-family:DM Sans,sans-serif;color:var(--tf-text)}.tf-176d77:hover{background:var(--tf-surface-hover)}.tf-2df5d9{background:var(--tf-primary-light)}.tf-dc503e{opacity:.4;cursor:not-allowed}.tf-ebbc44{display:flex;align-items:center;gap:12px}.tf-5f455f{text-align:left}.tf-15ee78{display:flex;align-items:center;gap:6px}.tf-976d83{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-ba2eec{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-a37921{text-align:right}.tf-cf71b6{font-size:var(--tf-font-md);font-weight:600;font-family:JetBrains Mono,monospace;color:var(--tf-text)}.tf-7474a9{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}.tf-772a9c{flex-shrink:0;padding:4px 8px 12px;border-top:1px solid var(--tf-border-light)}.tf-5fb6ad{display:flex;flex-direction:column;align-items:center;justify-content:center;height:197px;gap:8px;padding:16px 20px}.tf-86e8e0{flex-direction:row;gap:10px}.tf-66007c{color:var(--tf-text-tertiary);opacity:.5}.tf-73bbbc{width:24px;height:24px;display:flex;align-items:center;justify-content:center;opacity:.6;color:var(--tf-primary);animation:tf-540423 1s linear infinite}.tf-12c6bb{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-text-secondary)}.tf-7a8fe0{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);text-align:center;line-height:1.4}.tf-22f94f{display:flex;align-items:center;justify-content:center;gap:4px;padding:4px 0 2px;font-size:var(--tf-font-sm);color:var(--tf-primary);cursor:pointer;font-weight:500;background:none;border:none;width:100%;font-family:DM Sans,sans-serif}";
11858
- const css5 = ".tf-9b71d6{padding:16px 20px 12px;display:flex;justify-content:space-between;align-items:center;gap:7px}.tf-4c9136{padding:0 20px 10px}.tf-febe61{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-weight:500;margin-bottom:6px;text-align:left}.tf-a27aab{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--tf-input-bg);border-radius:12px;border:1px solid var(--tf-border-light)}.tf-f0b3f5{position:relative;flex-shrink:0}.tf-7a6fbc{position:absolute;bottom:-1px;right:-1px;width:12px;height:12px}.tf-e9e9a1{font-size:var(--tf-font-amount-sm);font-weight:700;letter-spacing:-.02em}.tf-f3baad{font-size:var(--tf-font-lg);font-weight:500;color:var(--tf-text-secondary)}.tf-0131e4{margin-left:auto;font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:JetBrains Mono,monospace}";
11875
+ const css2 = "@keyframes tf-540423{to{transform:rotate(360deg)}}.tf-d61a98{padding:0 20px}.tf-4574e9{height:162px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--tf-border) transparent}.tf-4574e9::-webkit-scrollbar{width:4px}.tf-4574e9::-webkit-scrollbar-track{background:transparent}.tf-4574e9::-webkit-scrollbar-thumb{background:var(--tf-border);border-radius:2px}.tf-2f8db2{display:flex;align-items:center;justify-content:space-between;padding:9px 11px;border-radius:11px;margin-bottom:4px;cursor:pointer;border:1px solid var(--tf-border-light);background:transparent;width:100%;font-family:var(--tf-font-family);transition:background .15s ease,border-color .15s ease}.tf-aaf1d0{border-color:var(--tf-primary);outline:.5px solid var(--tf-primary);outline-offset:-1px;background:var(--tf-primary-light)}.tf-328e9e{opacity:.4;cursor:not-allowed}.tf-af2c71{cursor:default;pointer-events:none}.tf-d7d776{width:32px;height:32px;border-radius:50%}.tf-c3e864{display:flex;align-items:center;padding:11px 14px;border-radius:12px;border:1px solid var(--tf-border-light);background:var(--tf-input-bg);cursor:default;pointer-events:none}.tf-44450a{display:flex;flex-direction:column;gap:6px}.tf-6c1e97{height:10px}.tf-2174f1{width:52px}.tf-2d3530{width:40px}.tf-2733a9{display:flex;flex-direction:column;align-items:flex-end;gap:6px;margin-left:auto}.tf-54150b{width:60px}.tf-7aabe1{width:44px}.tf-c41b7c{display:flex;align-items:center;gap:9px}.tf-142024{position:relative}.tf-3b42da{position:absolute;bottom:-1px;right:-1px;width:11px;height:11px;border-radius:50%;background:var(--tf-surface);border:1px solid var(--tf-border);display:flex;align-items:center;justify-content:center}.tf-b7faa4{text-align:left}.tf-1ae7a3{display:flex;align-items:center;gap:5px}.tf-b949b8{font-size:var(--tf-font-base);font-weight:600;color:var(--tf-text)}.tf-2f811b{font-size:var(--tf-font-2xs);font-weight:700;padding:1px 4px;border-radius:3px;background:var(--tf-success-bg);color:var(--tf-success);letter-spacing:.03em}.tf-6542b9{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary)}.tf-e613ff{text-align:right}.tf-630df3{font-size:var(--tf-font-base);font-weight:600;font-family:var(--tf-font-family-mono);color:var(--tf-text)}.tf-0be2ff{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}.tf-dad192{font-size:var(--tf-font-base);font-weight:600;font-family:var(--tf-font-family-mono);color:var(--tf-text)}.tf-840c29{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}.tf-09818b{display:flex;align-items:center;padding:10px 14px;border-radius:12px;border:1px solid var(--tf-border-light);background:var(--tf-input-bg);cursor:pointer;width:100%;font-family:var(--tf-font-family);transition:background .15s ease,border-color .15s ease}.tf-09818b:hover{border-color:var(--tf-primary);background:var(--tf-primary-light)}.tf-c7ba0f{display:flex;align-items:center;gap:9px}.tf-dea0cb{text-align:left}.tf-41931a{display:flex;align-items:center;gap:5px}.tf-3d2f5a{margin-left:auto;text-align:right;margin-right:8px}.tf-9a379d{font-size:var(--tf-font-lg);font-weight:500;font-family:var(--tf-font-family-mono);color:var(--tf-text);letter-spacing:-.02em}.tf-c11354{font-size:var(--tf-font-xs);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}.tf-864468{color:var(--tf-text-tertiary);display:flex;align-items:center;flex-shrink:0;transition:transform .2s ease}.tf-8299cf{flex:1;overflow-y:auto;padding:0 8px 8px;scrollbar-width:thin;scrollbar-color:var(--tf-border) transparent}.tf-176d77{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-radius:12px;cursor:pointer;background:transparent;transition:background .1s;border:none;width:100%;font-family:var(--tf-font-family);color:var(--tf-text)}.tf-176d77:hover{background:var(--tf-surface-hover)}.tf-2df5d9{background:var(--tf-primary-light)}.tf-dc503e{opacity:.4;cursor:not-allowed}.tf-ebbc44{display:flex;align-items:center;gap:12px}.tf-5f455f{text-align:left}.tf-15ee78{display:flex;align-items:center;gap:6px}.tf-976d83{font-size:var(--tf-font-lg);font-weight:600;color:var(--tf-text)}.tf-ba2eec{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary)}.tf-a37921{text-align:right}.tf-cf71b6{font-size:var(--tf-font-md);font-weight:600;font-family:var(--tf-font-family-mono);color:var(--tf-text)}.tf-7474a9{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}.tf-772a9c{flex-shrink:0;padding:4px 8px 12px;border-top:1px solid var(--tf-border-light)}.tf-5fb6ad{display:flex;flex-direction:column;align-items:center;justify-content:center;height:197px;gap:8px;padding:16px 20px}.tf-86e8e0{flex-direction:row;gap:10px}.tf-66007c{color:var(--tf-text-tertiary);opacity:.5}.tf-73bbbc{width:24px;height:24px;display:flex;align-items:center;justify-content:center;opacity:.6;color:var(--tf-primary);animation:tf-540423 1s linear infinite}.tf-12c6bb{font-size:var(--tf-font-md);font-weight:600;color:var(--tf-text-secondary)}.tf-7a8fe0{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);text-align:center;line-height:1.4}.tf-22f94f{display:flex;align-items:center;justify-content:center;gap:4px;padding:4px 0 2px;font-size:var(--tf-font-sm);color:var(--tf-primary);cursor:pointer;font-weight:500;background:none;border:none;width:100%;font-family:var(--tf-font-family)}";
11876
+ const css5 = ".tf-9b71d6{padding:16px 20px 12px;display:flex;justify-content:space-between;align-items:center;gap:7px}.tf-4c9136{padding:0 20px 10px}.tf-febe61{font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-weight:500;margin-bottom:6px;text-align:left}.tf-a27aab{display:flex;align-items:center;gap:10px;padding:8px 14px;background:var(--tf-input-bg);border-radius:12px;border:1px solid var(--tf-border-light)}.tf-f0b3f5{position:relative;flex-shrink:0}.tf-7a6fbc{position:absolute;bottom:-1px;right:-1px;width:12px;height:12px}.tf-e9e9a1{font-size:var(--tf-font-amount-sm);font-weight:700;letter-spacing:-.02em}.tf-f3baad{font-size:var(--tf-font-lg);font-weight:500;color:var(--tf-text-secondary)}.tf-0131e4{margin-left:auto;font-size:var(--tf-font-sm);color:var(--tf-text-tertiary);font-family:var(--tf-font-family-mono)}";
11859
11877
  const receiveCss = [css0, css1, css2, css3, css4, css5, css6, css7, css8, css9, css10, css11, css12, css13].join("\n");
11860
11878
  const lightVars = {
11861
11879
  "--tf-bg": "#ffffff",
@@ -12439,14 +12457,30 @@ function parseBooleanProp(value2) {
12439
12457
  }
12440
12458
  return void 0;
12441
12459
  }
12442
- let defaultWalletAdapter;
12443
- let defaultCallbacks;
12460
+ const [defaultWalletAdapter, setDefaultWalletAdapter] = createSignal();
12461
+ const [defaultCallbacks, setDefaultCallbacks] = createSignal();
12462
+ const [defaultCustomColors, setDefaultCustomColors] = createSignal();
12463
+ const [defaultApiEndpoint, setDefaultApiEndpoint] = createSignal();
12464
+ const [defaultTheme, setDefaultTheme] = createSignal();
12465
+ const [defaultLocale, setDefaultLocale] = createSignal();
12444
12466
  function registerElements(options = {}) {
12445
12467
  if ("walletAdapter" in options) {
12446
- defaultWalletAdapter = options.walletAdapter;
12468
+ setDefaultWalletAdapter(() => options.walletAdapter);
12447
12469
  }
12448
12470
  if ("callbacks" in options) {
12449
- defaultCallbacks = options.callbacks;
12471
+ setDefaultCallbacks(() => options.callbacks);
12472
+ }
12473
+ if ("customColors" in options) {
12474
+ setDefaultCustomColors(() => options.customColors);
12475
+ }
12476
+ if ("apiEndpoint" in options) {
12477
+ setDefaultApiEndpoint(options.apiEndpoint);
12478
+ }
12479
+ if ("theme" in options) {
12480
+ setDefaultTheme(options.theme);
12481
+ }
12482
+ if ("locale" in options) {
12483
+ setDefaultLocale(options.locale);
12450
12484
  }
12451
12485
  if (typeof customElements === "undefined") return;
12452
12486
  if (!customElements.get("tokenflight-swap")) {
@@ -12457,8 +12491,8 @@ function registerElements(options = {}) {
12457
12491
  recipient: "",
12458
12492
  "title-text": "",
12459
12493
  "title-image": "",
12460
- theme: "light",
12461
- locale: "en-US",
12494
+ theme: "",
12495
+ locale: "",
12462
12496
  "csp-nonce": "",
12463
12497
  "hide-title": false,
12464
12498
  "hide-powered-by": false,
@@ -12468,14 +12502,14 @@ function registerElements(options = {}) {
12468
12502
  element
12469
12503
  }) => {
12470
12504
  const config = {
12471
- apiEndpoint: props["api-endpoint"] || void 0,
12505
+ apiEndpoint: props["api-endpoint"] || defaultApiEndpoint() || void 0,
12472
12506
  fromToken: props["from-token"] || void 0,
12473
12507
  toToken: props["to-token"] || void 0,
12474
12508
  recipient: props.recipient || void 0,
12475
12509
  titleText: props["title-text"] || void 0,
12476
12510
  titleImageUrl: props["title-image"] || void 0,
12477
- theme: props.theme || "light",
12478
- locale: props.locale || "en-US",
12511
+ theme: props.theme || defaultTheme() || "light",
12512
+ locale: props.locale || defaultLocale() || "en-US",
12479
12513
  hideTitle: parseBooleanProp(props["hide-title"]),
12480
12514
  hidePoweredBy: parseBooleanProp(props["hide-powered-by"]),
12481
12515
  noBackground: parseBooleanProp(props["no-background"]),
@@ -12487,20 +12521,22 @@ function registerElements(options = {}) {
12487
12521
  setSystemDark(vars === darkVars);
12488
12522
  });
12489
12523
  onCleanup(unwatch);
12524
+ const elementCustomColors = element.__customColors;
12490
12525
  const styleContent = createMemo(() => {
12491
- const theme = props.theme || "light";
12526
+ const theme = props.theme || defaultTheme() || "light";
12492
12527
  const isDark = theme === "auto" ? systemDark() : theme === "dark";
12493
12528
  const themeVars = isDark ? darkVars : lightVars;
12494
- return `:host { ${buildCssVarString(themeVars)} }
12529
+ const colors = defaultCustomColors();
12530
+ const merged = colors || elementCustomColors ? {
12531
+ ...themeVars,
12532
+ ...colors,
12533
+ ...elementCustomColors
12534
+ } : themeVars;
12535
+ return `:host { ${buildCssVarString(merged)} }
12495
12536
  ${swapCss}`;
12496
12537
  });
12497
12538
  const elementWalletAdapter = element.__walletAdapter;
12498
12539
  const elementCallbacks = element.__callbacks;
12499
- const walletAdapter = elementWalletAdapter ?? defaultWalletAdapter;
12500
- const callbacks = elementCallbacks ? {
12501
- ...defaultCallbacks,
12502
- ...elementCallbacks
12503
- } : defaultCallbacks;
12504
12540
  return [(() => {
12505
12541
  var _el$ = _tmpl$();
12506
12542
  setAttribute(_el$, "nonce", nonce);
@@ -12511,8 +12547,15 @@ ${swapCss}`;
12511
12547
  get children() {
12512
12548
  return createComponent(SwapComponent, {
12513
12549
  config,
12514
- walletAdapter,
12515
- callbacks
12550
+ get walletAdapter() {
12551
+ return elementWalletAdapter ?? defaultWalletAdapter();
12552
+ },
12553
+ get callbacks() {
12554
+ return elementCallbacks ? {
12555
+ ...defaultCallbacks(),
12556
+ ...elementCallbacks
12557
+ } : defaultCallbacks();
12558
+ }
12516
12559
  });
12517
12560
  }
12518
12561
  })];
@@ -12527,8 +12570,8 @@ ${swapCss}`;
12527
12570
  recipient: "",
12528
12571
  "title-text": "",
12529
12572
  "title-image": "",
12530
- theme: "light",
12531
- locale: "en-US",
12573
+ theme: "",
12574
+ locale: "",
12532
12575
  "csp-nonce": "",
12533
12576
  icon: "",
12534
12577
  "hide-title": false,
@@ -12539,15 +12582,15 @@ ${swapCss}`;
12539
12582
  element
12540
12583
  }) => {
12541
12584
  const config = {
12542
- apiEndpoint: props["api-endpoint"] || void 0,
12585
+ apiEndpoint: props["api-endpoint"] || defaultApiEndpoint() || void 0,
12543
12586
  target: props.target || "",
12544
12587
  amount: props.amount || "",
12545
12588
  fromToken: props["from-token"] || void 0,
12546
12589
  recipient: props.recipient || void 0,
12547
12590
  titleText: props["title-text"] || void 0,
12548
12591
  titleImageUrl: props["title-image"] || void 0,
12549
- theme: props.theme || "light",
12550
- locale: props.locale || "en-US",
12592
+ theme: props.theme || defaultTheme() || "light",
12593
+ locale: props.locale || defaultLocale() || "en-US",
12551
12594
  icon: props.icon || void 0,
12552
12595
  hideTitle: parseBooleanProp(props["hide-title"]),
12553
12596
  hidePoweredBy: parseBooleanProp(props["hide-powered-by"]),
@@ -12560,20 +12603,22 @@ ${swapCss}`;
12560
12603
  setSystemDark(vars === darkVars);
12561
12604
  });
12562
12605
  onCleanup(unwatch);
12606
+ const elementCustomColors = element.__customColors;
12563
12607
  const styleContent = createMemo(() => {
12564
- const theme = props.theme || "light";
12608
+ const theme = props.theme || defaultTheme() || "light";
12565
12609
  const isDark = theme === "auto" ? systemDark() : theme === "dark";
12566
12610
  const themeVars = isDark ? darkVars : lightVars;
12567
- return `:host { ${buildCssVarString(themeVars)} }
12611
+ const colors = defaultCustomColors();
12612
+ const merged = colors || elementCustomColors ? {
12613
+ ...themeVars,
12614
+ ...colors,
12615
+ ...elementCustomColors
12616
+ } : themeVars;
12617
+ return `:host { ${buildCssVarString(merged)} }
12568
12618
  ${receiveCss}`;
12569
12619
  });
12570
12620
  const elementWalletAdapter = element.__walletAdapter;
12571
12621
  const elementCallbacks = element.__callbacks;
12572
- const walletAdapter = elementWalletAdapter ?? defaultWalletAdapter;
12573
- const callbacks = elementCallbacks ? {
12574
- ...defaultCallbacks,
12575
- ...elementCallbacks
12576
- } : defaultCallbacks;
12577
12622
  return [(() => {
12578
12623
  var _el$2 = _tmpl$();
12579
12624
  setAttribute(_el$2, "nonce", nonce);
@@ -12584,8 +12629,15 @@ ${receiveCss}`;
12584
12629
  get children() {
12585
12630
  return createComponent(ReceiveComponent, {
12586
12631
  config,
12587
- walletAdapter,
12588
- callbacks
12632
+ get walletAdapter() {
12633
+ return elementWalletAdapter ?? defaultWalletAdapter();
12634
+ },
12635
+ get callbacks() {
12636
+ return elementCallbacks ? {
12637
+ ...defaultCallbacks(),
12638
+ ...elementCallbacks
12639
+ } : defaultCallbacks();
12640
+ }
12589
12641
  });
12590
12642
  }
12591
12643
  })];