@tonconnect/ui 2.2.0-beta.0 → 2.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -465,12 +465,16 @@ declare class TonConnectUI {
465
465
  * @param tx transaction to send.
466
466
  * @param options modal and notifications behaviour settings. Default is show only 'before' modal and all notifications.
467
467
  */
468
- sendTransaction(tx: SendTransactionRequest, options?: ActionConfiguration): Promise<SendTransactionResponse>;
468
+ sendTransaction(tx: SendTransactionRequest, options?: ActionConfiguration & {
469
+ onRequestSent?: (redirectToWallet: () => void) => void;
470
+ }): Promise<SendTransactionResponse>;
469
471
  /**
470
472
  * Signs the data and returns the signature.
471
473
  * @param data data to sign.
472
474
  */
473
- signData(data: SignDataPayload): Promise<SignDataResponse>;
475
+ signData(data: SignDataPayload, options?: {
476
+ onRequestSent?: (redirectToWallet: () => void) => void;
477
+ }): Promise<SignDataResponse>;
474
478
  private redirectAfterRequestSent;
475
479
  /**
476
480
  * TODO: remove in the next major version.
package/lib/index.mjs CHANGED
@@ -17,6 +17,18 @@ var __spreadValues = (a2, b) => {
17
17
  return a2;
18
18
  };
19
19
  var __spreadProps = (a2, b) => __defProps(a2, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
20
32
  var __publicField = (obj, key, value) => {
21
33
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
34
  return value;
@@ -1820,8 +1832,10 @@ function fixMobileSafariActiveTransition() {
1820
1832
  }
1821
1833
  }
1822
1834
  function defineStylesRoot() {
1823
- customElements.define(globalStylesTag, class TcRootElement extends HTMLElement {
1824
- });
1835
+ if (!customElements.get("tc-root")) {
1836
+ customElements.define(globalStylesTag, class TcRootElement extends HTMLElement {
1837
+ });
1838
+ }
1825
1839
  }
1826
1840
  function createMacrotask(callback) {
1827
1841
  return __async(this, null, function* () {
@@ -3029,6 +3043,7 @@ function useDataAttributes(props) {
3029
3043
  const Button = (props) => {
3030
3044
  const dataAttrs = useDataAttributes(props);
3031
3045
  return createComponent(ButtonStyled$1, mergeProps({
3046
+ type: "button",
3032
3047
  get appearance() {
3033
3048
  return props.appearance || "primary";
3034
3049
  },
@@ -4910,16 +4925,16 @@ var qrcode$1 = { exports: {} };
4910
4925
  };
4911
4926
  return _this;
4912
4927
  }();
4913
- function qrPolynomial(num, shift) {
4928
+ function qrPolynomial(num, shift2) {
4914
4929
  if (typeof num.length == "undefined") {
4915
- throw num.length + "/" + shift;
4930
+ throw num.length + "/" + shift2;
4916
4931
  }
4917
4932
  var _num = function() {
4918
4933
  var offset = 0;
4919
4934
  while (offset < num.length && num[offset] == 0) {
4920
4935
  offset += 1;
4921
4936
  }
4922
- var _num2 = new Array(num.length - offset + shift);
4937
+ var _num2 = new Array(num.length - offset + shift2);
4923
4938
  for (var i2 = 0; i2 < num.length - offset; i2 += 1) {
4924
4939
  _num2[i2] = num[i2 + offset];
4925
4940
  }
@@ -7460,6 +7475,22 @@ const computePosition$1 = (reference, floating, config) => __async(void 0, null,
7460
7475
  middlewareData
7461
7476
  };
7462
7477
  });
7478
+ function expandPaddingObject(padding) {
7479
+ return __spreadValues({
7480
+ top: 0,
7481
+ right: 0,
7482
+ bottom: 0,
7483
+ left: 0
7484
+ }, padding);
7485
+ }
7486
+ function getSideObjectFromPadding(padding) {
7487
+ return typeof padding !== "number" ? expandPaddingObject(padding) : {
7488
+ top: padding,
7489
+ right: padding,
7490
+ bottom: padding,
7491
+ left: padding
7492
+ };
7493
+ }
7463
7494
  function rectToClientRect(rect) {
7464
7495
  return __spreadProps(__spreadValues({}, rect), {
7465
7496
  top: rect.y,
@@ -7468,6 +7499,270 @@ function rectToClientRect(rect) {
7468
7499
  bottom: rect.y + rect.height
7469
7500
  });
7470
7501
  }
7502
+ function detectOverflow(middlewareArguments, options) {
7503
+ return __async(this, null, function* () {
7504
+ var _await$platform$isEle;
7505
+ if (options === void 0) {
7506
+ options = {};
7507
+ }
7508
+ const {
7509
+ x,
7510
+ y,
7511
+ platform: platform2,
7512
+ rects,
7513
+ elements,
7514
+ strategy
7515
+ } = middlewareArguments;
7516
+ const {
7517
+ boundary = "clippingAncestors",
7518
+ rootBoundary = "viewport",
7519
+ elementContext = "floating",
7520
+ altBoundary = false,
7521
+ padding = 0
7522
+ } = options;
7523
+ const paddingObject = getSideObjectFromPadding(padding);
7524
+ const altContext = elementContext === "floating" ? "reference" : "floating";
7525
+ const element = elements[altBoundary ? altContext : elementContext];
7526
+ const clippingClientRect = rectToClientRect(yield platform2.getClippingRect({
7527
+ element: ((_await$platform$isEle = yield platform2.isElement == null ? void 0 : platform2.isElement(element)) != null ? _await$platform$isEle : true) ? element : element.contextElement || (yield platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
7528
+ boundary,
7529
+ rootBoundary,
7530
+ strategy
7531
+ }));
7532
+ const rect = elementContext === "floating" ? __spreadProps(__spreadValues({}, rects.floating), {
7533
+ x,
7534
+ y
7535
+ }) : rects.reference;
7536
+ const offsetParent = yield platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating);
7537
+ const offsetScale = (yield platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? (yield platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
7538
+ x: 1,
7539
+ y: 1
7540
+ } : {
7541
+ x: 1,
7542
+ y: 1
7543
+ };
7544
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? yield platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
7545
+ rect,
7546
+ offsetParent,
7547
+ strategy
7548
+ }) : rect);
7549
+ return {
7550
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
7551
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
7552
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
7553
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
7554
+ };
7555
+ });
7556
+ }
7557
+ const min$1 = Math.min;
7558
+ const max$1 = Math.max;
7559
+ function within(min$1$1, value, max$1$1) {
7560
+ return max$1(min$1$1, min$1(value, max$1$1));
7561
+ }
7562
+ const hash$1 = {
7563
+ left: "right",
7564
+ right: "left",
7565
+ bottom: "top",
7566
+ top: "bottom"
7567
+ };
7568
+ function getOppositePlacement(placement) {
7569
+ return placement.replace(/left|right|bottom|top/g, (matched) => hash$1[matched]);
7570
+ }
7571
+ function getAlignmentSides(placement, rects, rtl) {
7572
+ if (rtl === void 0) {
7573
+ rtl = false;
7574
+ }
7575
+ const alignment = getAlignment(placement);
7576
+ const mainAxis = getMainAxisFromPlacement(placement);
7577
+ const length = getLengthFromAxis(mainAxis);
7578
+ let mainAlignmentSide = mainAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
7579
+ if (rects.reference[length] > rects.floating[length]) {
7580
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
7581
+ }
7582
+ return {
7583
+ main: mainAlignmentSide,
7584
+ cross: getOppositePlacement(mainAlignmentSide)
7585
+ };
7586
+ }
7587
+ const hash = {
7588
+ start: "end",
7589
+ end: "start"
7590
+ };
7591
+ function getOppositeAlignmentPlacement(placement) {
7592
+ return placement.replace(/start|end/g, (matched) => hash[matched]);
7593
+ }
7594
+ function getExpandedPlacements(placement) {
7595
+ const oppositePlacement = getOppositePlacement(placement);
7596
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
7597
+ }
7598
+ const flip = function(options) {
7599
+ if (options === void 0) {
7600
+ options = {};
7601
+ }
7602
+ return {
7603
+ name: "flip",
7604
+ options,
7605
+ fn(middlewareArguments) {
7606
+ return __async(this, null, function* () {
7607
+ var _middlewareData$flip;
7608
+ const {
7609
+ placement,
7610
+ middlewareData,
7611
+ rects,
7612
+ initialPlacement,
7613
+ platform: platform2,
7614
+ elements
7615
+ } = middlewareArguments;
7616
+ const _a3 = options, {
7617
+ mainAxis: checkMainAxis = true,
7618
+ crossAxis: checkCrossAxis = true,
7619
+ fallbackPlacements: specifiedFallbackPlacements,
7620
+ fallbackStrategy = "bestFit",
7621
+ flipAlignment = true
7622
+ } = _a3, detectOverflowOptions = __objRest(_a3, [
7623
+ "mainAxis",
7624
+ "crossAxis",
7625
+ "fallbackPlacements",
7626
+ "fallbackStrategy",
7627
+ "flipAlignment"
7628
+ ]);
7629
+ const side = getSide(placement);
7630
+ const isBasePlacement = side === initialPlacement;
7631
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
7632
+ const placements = [initialPlacement, ...fallbackPlacements];
7633
+ const overflow = yield detectOverflow(middlewareArguments, detectOverflowOptions);
7634
+ const overflows = [];
7635
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
7636
+ if (checkMainAxis) {
7637
+ overflows.push(overflow[side]);
7638
+ }
7639
+ if (checkCrossAxis) {
7640
+ const {
7641
+ main,
7642
+ cross
7643
+ } = getAlignmentSides(placement, rects, yield platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
7644
+ overflows.push(overflow[main], overflow[cross]);
7645
+ }
7646
+ overflowsData = [...overflowsData, {
7647
+ placement,
7648
+ overflows
7649
+ }];
7650
+ if (!overflows.every((side2) => side2 <= 0)) {
7651
+ var _middlewareData$flip$, _middlewareData$flip2;
7652
+ const nextIndex = ((_middlewareData$flip$ = (_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) != null ? _middlewareData$flip$ : 0) + 1;
7653
+ const nextPlacement = placements[nextIndex];
7654
+ if (nextPlacement) {
7655
+ return {
7656
+ data: {
7657
+ index: nextIndex,
7658
+ overflows: overflowsData
7659
+ },
7660
+ reset: {
7661
+ placement: nextPlacement
7662
+ }
7663
+ };
7664
+ }
7665
+ let resetPlacement = "bottom";
7666
+ switch (fallbackStrategy) {
7667
+ case "bestFit": {
7668
+ var _overflowsData$map$so;
7669
+ const placement2 = (_overflowsData$map$so = overflowsData.map((d) => [d, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a2, b) => a2[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0].placement;
7670
+ if (placement2) {
7671
+ resetPlacement = placement2;
7672
+ }
7673
+ break;
7674
+ }
7675
+ case "initialPlacement":
7676
+ resetPlacement = initialPlacement;
7677
+ break;
7678
+ }
7679
+ if (placement !== resetPlacement) {
7680
+ return {
7681
+ reset: {
7682
+ placement: resetPlacement
7683
+ }
7684
+ };
7685
+ }
7686
+ }
7687
+ return {};
7688
+ });
7689
+ }
7690
+ };
7691
+ };
7692
+ function getCrossAxis(axis) {
7693
+ return axis === "x" ? "y" : "x";
7694
+ }
7695
+ const shift = function(options) {
7696
+ if (options === void 0) {
7697
+ options = {};
7698
+ }
7699
+ return {
7700
+ name: "shift",
7701
+ options,
7702
+ fn(middlewareArguments) {
7703
+ return __async(this, null, function* () {
7704
+ const {
7705
+ x,
7706
+ y,
7707
+ placement
7708
+ } = middlewareArguments;
7709
+ const _a3 = options, {
7710
+ mainAxis: checkMainAxis = true,
7711
+ crossAxis: checkCrossAxis = false,
7712
+ limiter = {
7713
+ fn: (_ref) => {
7714
+ let {
7715
+ x: x2,
7716
+ y: y2
7717
+ } = _ref;
7718
+ return {
7719
+ x: x2,
7720
+ y: y2
7721
+ };
7722
+ }
7723
+ }
7724
+ } = _a3, detectOverflowOptions = __objRest(_a3, [
7725
+ "mainAxis",
7726
+ "crossAxis",
7727
+ "limiter"
7728
+ ]);
7729
+ const coords = {
7730
+ x,
7731
+ y
7732
+ };
7733
+ const overflow = yield detectOverflow(middlewareArguments, detectOverflowOptions);
7734
+ const mainAxis = getMainAxisFromPlacement(getSide(placement));
7735
+ const crossAxis = getCrossAxis(mainAxis);
7736
+ let mainAxisCoord = coords[mainAxis];
7737
+ let crossAxisCoord = coords[crossAxis];
7738
+ if (checkMainAxis) {
7739
+ const minSide = mainAxis === "y" ? "top" : "left";
7740
+ const maxSide = mainAxis === "y" ? "bottom" : "right";
7741
+ const min2 = mainAxisCoord + overflow[minSide];
7742
+ const max2 = mainAxisCoord - overflow[maxSide];
7743
+ mainAxisCoord = within(min2, mainAxisCoord, max2);
7744
+ }
7745
+ if (checkCrossAxis) {
7746
+ const minSide = crossAxis === "y" ? "top" : "left";
7747
+ const maxSide = crossAxis === "y" ? "bottom" : "right";
7748
+ const min2 = crossAxisCoord + overflow[minSide];
7749
+ const max2 = crossAxisCoord - overflow[maxSide];
7750
+ crossAxisCoord = within(min2, crossAxisCoord, max2);
7751
+ }
7752
+ const limitedCoords = limiter.fn(__spreadProps(__spreadValues({}, middlewareArguments), {
7753
+ [mainAxis]: mainAxisCoord,
7754
+ [crossAxis]: crossAxisCoord
7755
+ }));
7756
+ return __spreadProps(__spreadValues({}, limitedCoords), {
7757
+ data: {
7758
+ x: limitedCoords.x - x,
7759
+ y: limitedCoords.y - y
7760
+ }
7761
+ });
7762
+ });
7763
+ }
7764
+ };
7765
+ };
7471
7766
  function getWindow(node) {
7472
7767
  var _node$ownerDocument;
7473
7768
  return ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
@@ -8050,7 +8345,8 @@ const AccountButton = () => {
8050
8345
  const [anchor, setAnchor] = createSignal();
8051
8346
  const position = P(anchor, floating, {
8052
8347
  whileElementsMounted: autoUpdate,
8053
- placement: "bottom-end"
8348
+ placement: "bottom-end",
8349
+ middleware: [flip(), shift()]
8054
8350
  });
8055
8351
  const normalizedAddress = () => {
8056
8352
  const acc = account();
@@ -11365,9 +11661,13 @@ const ActionModal = (props) => {
11365
11661
  const tonConnectUI = useContext(TonConnectUiContext);
11366
11662
  const [firstClick, setFirstClick] = createSignal(true);
11367
11663
  const [sent, setSent] = createSignal(false);
11664
+ const [signed, setSigned] = createSignal(false);
11665
+ const [canceled, setCanceled] = createSignal(false);
11368
11666
  createEffect(() => {
11369
11667
  const currentAction = action();
11370
- setSent(!!currentAction && "sent" in currentAction && currentAction.sent);
11668
+ setSent(!!currentAction && ("sent" in currentAction && currentAction.sent || currentAction.name === "transaction-sent"));
11669
+ setSigned(!!currentAction && ("signed" in currentAction && currentAction.signed || currentAction.name === "data-signed"));
11670
+ setCanceled(!!currentAction && (currentAction.name === "transaction-canceled" || currentAction.name === "sign-data-canceled"));
11371
11671
  });
11372
11672
  let universalLink;
11373
11673
  if ((tonConnectUI == null ? void 0 : tonConnectUI.wallet) && "universalLink" in tonConnectUI.wallet && (tonConnectUI.wallet.openMethod === "universal-link" || isTelegramUrl(tonConnectUI.wallet.universalLink) && isInTMA())) {
@@ -11414,7 +11714,7 @@ const ActionModal = (props) => {
11414
11714
  }
11415
11715
  }), createComponent(Show, {
11416
11716
  get when() {
11417
- return !sent() && (props.showButton === "open-wallet" && universalLink || props.showButton !== "open-wallet");
11717
+ return !sent() && !signed() && !canceled() && (props.showButton === "open-wallet" && universalLink || props.showButton !== "open-wallet");
11418
11718
  },
11419
11719
  get children() {
11420
11720
  return createComponent(LoaderButtonStyled, {
@@ -11427,7 +11727,7 @@ const ActionModal = (props) => {
11427
11727
  }
11428
11728
  }), createComponent(Show, {
11429
11729
  get when() {
11430
- return sent();
11730
+ return sent() || signed();
11431
11731
  },
11432
11732
  get children() {
11433
11733
  return [createComponent(Show, {
@@ -11510,6 +11810,7 @@ const TransactionSentModal = (props) => {
11510
11810
  size: "m"
11511
11811
  });
11512
11812
  },
11813
+ showButton: "open-wallet",
11513
11814
  onClose: () => props.onClose(),
11514
11815
  "data-tc-transaction-sent-modal": "true"
11515
11816
  });
@@ -12147,7 +12448,7 @@ class TonConnectUITracker {
12147
12448
  }
12148
12449
  }
12149
12450
  }
12150
- const tonConnectUiVersion = "2.2.0-beta.0";
12451
+ const tonConnectUiVersion = "2.3.0-beta.0";
12151
12452
  class TonConnectUI {
12152
12453
  constructor(options) {
12153
12454
  __publicField(this, "walletInfoStorage", new WalletInfoStorage());
@@ -12383,6 +12684,7 @@ class TonConnectUI {
12383
12684
  });
12384
12685
  const abortController = new AbortController();
12385
12686
  const onRequestSent = () => {
12687
+ var _a2;
12386
12688
  if (abortController.signal.aborted) {
12387
12689
  return;
12388
12690
  }
@@ -12396,6 +12698,20 @@ class TonConnectUI {
12396
12698
  returnStrategy,
12397
12699
  twaReturnUrl
12398
12700
  });
12701
+ let firstClick = true;
12702
+ const redirectToWallet2 = () => {
12703
+ if (abortController.signal.aborted) {
12704
+ return;
12705
+ }
12706
+ const forceRedirect = !firstClick;
12707
+ firstClick = false;
12708
+ this.redirectAfterRequestSent({
12709
+ returnStrategy,
12710
+ twaReturnUrl,
12711
+ forceRedirect
12712
+ });
12713
+ };
12714
+ (_a2 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a2.call(options, redirectToWallet2);
12399
12715
  };
12400
12716
  const unsubscribe = this.onTransactionModalStateChange((action2) => {
12401
12717
  if (action2 == null ? void 0 : action2.openModal) {
@@ -12443,7 +12759,7 @@ class TonConnectUI {
12443
12759
  }
12444
12760
  });
12445
12761
  }
12446
- signData(data) {
12762
+ signData(data, options) {
12447
12763
  return __async(this, null, function* () {
12448
12764
  this.tracker.trackDataSentForSignature(this.wallet, data);
12449
12765
  if (!this.connected) {
@@ -12462,6 +12778,7 @@ class TonConnectUI {
12462
12778
  });
12463
12779
  const abortController = new AbortController();
12464
12780
  const onRequestSent = () => {
12781
+ var _a2;
12465
12782
  if (abortController.signal.aborted) {
12466
12783
  return;
12467
12784
  }
@@ -12475,6 +12792,20 @@ class TonConnectUI {
12475
12792
  returnStrategy,
12476
12793
  twaReturnUrl
12477
12794
  });
12795
+ let firstClick = true;
12796
+ const redirectToWallet2 = () => {
12797
+ if (abortController.signal.aborted) {
12798
+ return;
12799
+ }
12800
+ const forceRedirect = !firstClick;
12801
+ firstClick = false;
12802
+ this.redirectAfterRequestSent({
12803
+ returnStrategy,
12804
+ twaReturnUrl,
12805
+ forceRedirect
12806
+ });
12807
+ };
12808
+ (_a2 = options == null ? void 0 : options.onRequestSent) == null ? void 0 : _a2.call(options, redirectToWallet2);
12478
12809
  };
12479
12810
  const unsubscribe = this.onTransactionModalStateChange((action2) => {
12480
12811
  if (action2 == null ? void 0 : action2.openModal) {
@@ -12524,14 +12855,15 @@ class TonConnectUI {
12524
12855
  }
12525
12856
  redirectAfterRequestSent({
12526
12857
  returnStrategy,
12527
- twaReturnUrl
12858
+ twaReturnUrl,
12859
+ forceRedirect
12528
12860
  }) {
12529
12861
  if (this.walletInfo && "universalLink" in this.walletInfo && (this.walletInfo.openMethod === "universal-link" || this.walletInfo.openMethod === "custom-deeplink")) {
12530
12862
  if (isTelegramUrl(this.walletInfo.universalLink)) {
12531
12863
  redirectToTelegram(this.walletInfo.universalLink, {
12532
12864
  returnStrategy,
12533
12865
  twaReturnUrl: twaReturnUrl || appState.twaReturnUrl,
12534
- forceRedirect: false
12866
+ forceRedirect: forceRedirect || false
12535
12867
  });
12536
12868
  } else {
12537
12869
  redirectToWallet(
@@ -12539,7 +12871,7 @@ class TonConnectUI {
12539
12871
  this.walletInfo.deepLink,
12540
12872
  {
12541
12873
  returnStrategy,
12542
- forceRedirect: false
12874
+ forceRedirect: forceRedirect || false
12543
12875
  },
12544
12876
  () => {
12545
12877
  }