UNPKG

@safe-stars/components

Version:

React component library for buying Telegram Stars in Telegram Mini Apps via Safe Stars.

579 lines (576 loc) 23 kB
import { e as g, B as A, k as N, A as v, N as l, u as j, w as Q, b as $, v as V, y as H, d as D, C as K, c as Y, S as f, R as b, z as R, n as J, f as x, W as F, i as X, r as Z, h as ee, a as te, x as M } from "./index-B5pm1jHN.js"; import { n as q, c as ne } from "./if-defined-CTZGcMnO.js"; import "./index-CIwP1liu.js"; import "./index-Cpy9YpFe.js"; const W = { async getTokenList() { var a; const t = g.state.activeCaipNetwork, n = await A.fetchSwapTokens({ chainId: t == null ? void 0 : t.caipNetworkId }); return ((a = n == null ? void 0 : n.tokens) == null ? void 0 : a.map((s) => ({ ...s, eip2612: !1, quantity: { decimals: "0", numeric: "0" }, price: 0, value: 0 }))) || []; }, async fetchGasPrice() { var n, o; const t = g.state.activeCaipNetwork; if (!t) return null; try { switch (t.chainNamespace) { case "solana": const a = (o = await ((n = N) == null ? void 0 : n.estimateGas({ chainNamespace: "solana" }))) == null ? void 0 : o.toString(); return { standard: a, fast: a, instant: a }; case "eip155": default: return await A.fetchGasPrice({ chainId: t.caipNetworkId }); } } catch { return null; } }, async fetchSwapAllowance({ tokenAddress: t, userAddress: n, sourceTokenAmount: o, sourceTokenDecimals: a }) { const s = await A.fetchSwapAllowance({ tokenAddress: t, userAddress: n }); if (s != null && s.allowance && o && a) { const i = N.parseUnits(o, a) || 0; return BigInt(s.allowance) >= i; } return !1; }, async getMyTokensWithBalance(t) { const n = v.state.address, o = g.state.activeCaipNetwork; if (!n || !o) return []; const s = (await A.getBalance(n, o.caipNetworkId, t)).balances.filter((i) => i.quantity.decimals !== "0"); return v.setTokenBalance(s, g.state.activeChain), this.mapBalancesToSwapTokens(s); }, mapBalancesToSwapTokens(t) { return (t == null ? void 0 : t.map((n) => ({ ...n, address: n != null && n.address ? n.address : g.getActiveNetworkTokenAddress(), decimals: parseInt(n.quantity.decimals, 10), logoUri: n.iconUrl, eip2612: !1 }))) || []; } }, S = { getGasPriceInEther(t, n) { const o = n * t; return Number(o) / 1e18; }, getGasPriceInUSD(t, n, o) { const a = S.getGasPriceInEther(n, o); return l.bigNumber(t).times(a).toNumber(); }, getPriceImpact({ sourceTokenAmount: t, sourceTokenPriceInUSD: n, toTokenPriceInUSD: o, toTokenAmount: a }) { const s = l.bigNumber(t).times(n), i = l.bigNumber(a).times(o); return s.minus(i).div(s).times(100).toNumber(); }, getMaxSlippage(t, n) { const o = l.bigNumber(t).div(100); return l.multiply(n, o).toNumber(); }, getProviderFee(t, n = 85e-4) { return l.bigNumber(t).times(n).toString(); }, isInsufficientNetworkTokenForGas(t, n) { const o = n || "0"; return l.bigNumber(t).eq(0) ? !0 : l.bigNumber(l.bigNumber(o)).gt(t); }, isInsufficientSourceTokenForSwap(t, n, o) { var i, u; const a = (u = (i = o == null ? void 0 : o.find((c) => c.address === n)) == null ? void 0 : i.quantity) == null ? void 0 : u.numeric; return l.bigNumber(a || "0").lt(t); }, getToTokenAmount({ sourceToken: t, toToken: n, sourceTokenPrice: o, toTokenPrice: a, sourceTokenAmount: s }) { if (s === "0" || !t || !n) return "0"; const i = t.decimals, u = o, c = n.decimals, T = a; if (T <= 0) return "0"; const d = l.bigNumber(s).times(85e-4), w = l.bigNumber(s).minus(d).times(l.bigNumber(10).pow(i)), h = l.bigNumber(u).div(T), P = i - c; return w.times(h).div(l.bigNumber(10).pow(P)).div(l.bigNumber(10).pow(c)).toFixed(c).toString(); } }, z = 15e4, oe = 6, k = { // Loading states initializing: !1, initialized: !1, loadingPrices: !1, loadingQuote: !1, loadingApprovalTransaction: !1, loadingBuildTransaction: !1, loadingTransaction: !1, // Error states fetchError: !1, // Approval & Swap transaction states approvalTransaction: void 0, swapTransaction: void 0, transactionError: void 0, // Input values sourceToken: void 0, sourceTokenAmount: "", sourceTokenPriceInUSD: 0, toToken: void 0, toTokenAmount: "", toTokenPriceInUSD: 0, networkPrice: "0", networkBalanceInUSD: "0", networkTokenSymbol: "", inputError: void 0, // Request values slippage: $.CONVERT_SLIPPAGE_TOLERANCE, // Tokens tokens: void 0, popularTokens: void 0, suggestedTokens: void 0, foundTokens: void 0, myTokensWithBalance: void 0, tokensPriceMap: {}, // Calculations gasFee: "0", gasPriceInUSD: 0, priceImpact: void 0, maxSlippage: void 0, providerFee: void 0 }, e = j(k), U = { state: e, subscribe(t) { return V(e, () => t(e)); }, subscribeKey(t, n) { return H(e, t, n); }, getParams() { var T, d, m, w, h, P, I, y; const t = g.state.activeCaipAddress, n = g.state.activeChain, o = D.getPlainAddress(t), a = g.getActiveNetworkTokenAddress(), s = K.getConnectorId(n); if (!o) throw new Error("No address found to swap the tokens from."); const i = !((T = e.toToken) != null && T.address) || !((d = e.toToken) != null && d.decimals), u = !((m = e.sourceToken) != null && m.address) || !((w = e.sourceToken) != null && w.decimals) || !l.bigNumber(e.sourceTokenAmount).gt(0), c = !e.sourceTokenAmount; return { networkAddress: a, fromAddress: o, fromCaipAddress: t, sourceTokenAddress: (h = e.sourceToken) == null ? void 0 : h.address, toTokenAddress: (P = e.toToken) == null ? void 0 : P.address, toTokenAmount: e.toTokenAmount, toTokenDecimals: (I = e.toToken) == null ? void 0 : I.decimals, sourceTokenAmount: e.sourceTokenAmount, sourceTokenDecimals: (y = e.sourceToken) == null ? void 0 : y.decimals, invalidToToken: i, invalidSourceToken: u, invalidSourceTokenAmount: c, availableToSwap: t && !i && !u && !c, isAuthConnector: s === Y.CONNECTOR_ID.AUTH }; }, setSourceToken(t) { if (!t) { e.sourceToken = t, e.sourceTokenAmount = "", e.sourceTokenPriceInUSD = 0; return; } e.sourceToken = t, r.setTokenPrice(t.address, "sourceToken"); }, setSourceTokenAmount(t) { e.sourceTokenAmount = t; }, setToToken(t) { if (!t) { e.toToken = t, e.toTokenAmount = "", e.toTokenPriceInUSD = 0; return; } e.toToken = t, r.setTokenPrice(t.address, "toToken"); }, setToTokenAmount(t) { e.toTokenAmount = t ? l.formatNumberToLocalString(t, oe) : ""; }, async setTokenPrice(t, n) { let o = e.tokensPriceMap[t] || 0; o || (e.loadingPrices = !0, o = await r.getAddressPrice(t)), n === "sourceToken" ? e.sourceTokenPriceInUSD = o : n === "toToken" && (e.toTokenPriceInUSD = o), e.loadingPrices && (e.loadingPrices = !1), r.getParams().availableToSwap && r.swapTokens(); }, switchTokens() { if (e.initializing || !e.initialized) return; const t = e.toToken ? { ...e.toToken } : void 0, n = e.sourceToken ? { ...e.sourceToken } : void 0, o = t && e.toTokenAmount === "" ? "1" : e.toTokenAmount; r.setSourceToken(t), r.setToToken(n), r.setSourceTokenAmount(o), r.setToTokenAmount(""), r.swapTokens(); }, resetState() { e.myTokensWithBalance = k.myTokensWithBalance, e.tokensPriceMap = k.tokensPriceMap, e.initialized = k.initialized, e.sourceToken = k.sourceToken, e.sourceTokenAmount = k.sourceTokenAmount, e.sourceTokenPriceInUSD = k.sourceTokenPriceInUSD, e.toToken = k.toToken, e.toTokenAmount = k.toTokenAmount, e.toTokenPriceInUSD = k.toTokenPriceInUSD, e.networkPrice = k.networkPrice, e.networkTokenSymbol = k.networkTokenSymbol, e.networkBalanceInUSD = k.networkBalanceInUSD, e.inputError = k.inputError, e.myTokensWithBalance = k.myTokensWithBalance; }, resetValues() { var o; const { networkAddress: t } = r.getParams(), n = (o = e.tokens) == null ? void 0 : o.find((a) => a.address === t); r.setSourceToken(n), r.setToToken(void 0); }, getApprovalLoadingState() { return e.loadingApprovalTransaction; }, clearError() { e.transactionError = void 0; }, async initializeState() { if (!e.initializing) { if (e.initializing = !0, !e.initialized) try { await r.fetchTokens(), e.initialized = !0; } catch { e.initialized = !1, f.showError("Failed to initialize swap"), b.goBack(); } e.initializing = !1; } }, async fetchTokens() { var o; const { networkAddress: t } = r.getParams(); await r.getTokenList(), await r.getNetworkTokenPrice(), await r.getMyTokensWithBalance(); const n = (o = e.tokens) == null ? void 0 : o.find((a) => a.address === t); n && (e.networkTokenSymbol = n.symbol, r.setSourceToken(n), r.setSourceTokenAmount("1")); }, async getTokenList() { const t = await W.getTokenList(); e.tokens = t, e.popularTokens = t.sort((n, o) => n.symbol < o.symbol ? -1 : n.symbol > o.symbol ? 1 : 0), e.suggestedTokens = t.filter((n) => !!$.SWAP_SUGGESTED_TOKENS.includes(n.symbol), {}); }, async getAddressPrice(t) { var T, d; const n = e.tokensPriceMap[t]; if (n) return n; const o = await A.fetchTokenPrice({ addresses: [t] }), a = (o == null ? void 0 : o.fungibles) || [], s = [...e.tokens || [], ...e.myTokensWithBalance || []], i = (T = s == null ? void 0 : s.find((m) => m.address === t)) == null ? void 0 : T.symbol, u = ((d = a.find((m) => m.symbol.toLowerCase() === (i == null ? void 0 : i.toLowerCase()))) == null ? void 0 : d.price) || 0, c = parseFloat(u.toString()); return e.tokensPriceMap[t] = c, c; }, async getNetworkTokenPrice() { var s; const { networkAddress: t } = r.getParams(), o = (s = (await A.fetchTokenPrice({ addresses: [t] }).catch(() => (f.showError("Failed to fetch network token price"), { fungibles: [] }))).fungibles) == null ? void 0 : s[0], a = (o == null ? void 0 : o.price.toString()) || "0"; e.tokensPriceMap[t] = parseFloat(a), e.networkTokenSymbol = (o == null ? void 0 : o.symbol) || "", e.networkPrice = a; }, async getMyTokensWithBalance(t) { const n = await R.getMyTokensWithBalance(t), o = R.mapBalancesToSwapTokens(n); o && (await r.getInitialGasPrice(), r.setBalances(o)); }, setBalances(t) { const { networkAddress: n } = r.getParams(), o = g.state.activeCaipNetwork; if (!o) return; const a = t.find((s) => s.address === n); t.forEach((s) => { e.tokensPriceMap[s.address] = s.price || 0; }), e.myTokensWithBalance = t.filter((s) => s.address.startsWith(o.caipNetworkId)), e.networkBalanceInUSD = a ? l.multiply(a.quantity.numeric, a.price).toString() : "0"; }, async getInitialGasPrice() { var n, o; const t = await W.fetchGasPrice(); if (!t) return { gasPrice: null, gasPriceInUSD: null }; switch ((o = (n = g.state) == null ? void 0 : n.activeCaipNetwork) == null ? void 0 : o.chainNamespace) { case "solana": return e.gasFee = t.standard ?? "0", e.gasPriceInUSD = l.multiply(t.standard, e.networkPrice).div(1e9).toNumber(), { gasPrice: BigInt(e.gasFee), gasPriceInUSD: Number(e.gasPriceInUSD) }; case "eip155": default: const a = t.standard ?? "0", s = BigInt(a), i = BigInt(z), u = S.getGasPriceInUSD(e.networkPrice, i, s); return e.gasFee = a, e.gasPriceInUSD = u, { gasPrice: s, gasPriceInUSD: u }; } }, // -- Swap -------------------------------------- // async swapTokens() { var i, u; const t = v.state.address, n = e.sourceToken, o = e.toToken, a = l.bigNumber(e.sourceTokenAmount).gt(0); if (a || r.setToTokenAmount(""), !o || !n || e.loadingPrices || !a) return; e.loadingQuote = !0; const s = l.bigNumber(e.sourceTokenAmount).times(10 ** n.decimals).round(0); try { const c = await A.fetchSwapQuote({ userAddress: t, from: n.address, to: o.address, gasPrice: e.gasFee, amount: s.toString() }); e.loadingQuote = !1; const T = (u = (i = c == null ? void 0 : c.quotes) == null ? void 0 : i[0]) == null ? void 0 : u.toAmount; if (!T) { J.open({ shortMessage: "Incorrect amount", longMessage: "Please enter a valid amount" }, "error"); return; } const d = l.bigNumber(T).div(10 ** o.decimals).toString(); r.setToTokenAmount(d), r.hasInsufficientToken(e.sourceTokenAmount, n.address) ? e.inputError = "Insufficient balance" : (e.inputError = void 0, r.setTransactionDetails()); } catch { e.loadingQuote = !1, e.inputError = "Insufficient balance"; } }, // -- Create Transactions -------------------------------------- // async getTransaction() { const { fromCaipAddress: t, availableToSwap: n } = r.getParams(), o = e.sourceToken, a = e.toToken; if (!(!t || !n || !o || !a || e.loadingQuote)) try { e.loadingBuildTransaction = !0; const s = await W.fetchSwapAllowance({ userAddress: t, tokenAddress: o.address, sourceTokenAmount: e.sourceTokenAmount, sourceTokenDecimals: o.decimals }); let i; return s ? i = await r.createSwapTransaction() : i = await r.createAllowanceTransaction(), e.loadingBuildTransaction = !1, e.fetchError = !1, i; } catch { b.goBack(), f.showError("Failed to check allowance"), e.loadingBuildTransaction = !1, e.approvalTransaction = void 0, e.swapTransaction = void 0, e.fetchError = !0; return; } }, async createAllowanceTransaction() { const { fromCaipAddress: t, sourceTokenAddress: n, toTokenAddress: o } = r.getParams(); if (!(!t || !o)) { if (!n) throw new Error("createAllowanceTransaction - No source token address found."); try { const a = await A.generateApproveCalldata({ from: n, to: o, userAddress: t }), s = { data: a.tx.data, to: D.getPlainAddress(a.tx.from), gasPrice: BigInt(a.tx.eip155.gasPrice), value: BigInt(a.tx.value), toAmount: e.toTokenAmount }; return e.swapTransaction = void 0, e.approvalTransaction = { data: s.data, to: s.to, gasPrice: s.gasPrice, value: s.value, toAmount: s.toAmount }, { data: s.data, to: s.to, gasPrice: s.gasPrice, value: s.value, toAmount: s.toAmount }; } catch { b.goBack(), f.showError("Failed to create approval transaction"), e.approvalTransaction = void 0, e.swapTransaction = void 0, e.fetchError = !0; return; } } }, async createSwapTransaction() { var u; const { networkAddress: t, fromCaipAddress: n, sourceTokenAmount: o } = r.getParams(), a = e.sourceToken, s = e.toToken; if (!n || !o || !a || !s) return; const i = (u = N.parseUnits(o, a.decimals)) == null ? void 0 : u.toString(); try { const c = await A.generateSwapCalldata({ userAddress: n, from: a.address, to: s.address, amount: i, disableEstimate: !0 }), T = a.address === t, d = BigInt(c.tx.eip155.gas), m = BigInt(c.tx.eip155.gasPrice), w = { data: c.tx.data, to: D.getPlainAddress(c.tx.to), gas: d, gasPrice: m, value: BigInt(T ? i ?? "0" : "0"), toAmount: e.toTokenAmount }; return e.gasPriceInUSD = S.getGasPriceInUSD(e.networkPrice, d, m), e.approvalTransaction = void 0, e.swapTransaction = w, w; } catch { b.goBack(), f.showError("Failed to create transaction"), e.approvalTransaction = void 0, e.swapTransaction = void 0, e.fetchError = !0; return; } }, // -- Send Transactions --------------------------------- // async sendTransactionForApproval(t) { var s, i, u, c; const { fromAddress: n, isAuthConnector: o } = r.getParams(); e.loadingApprovalTransaction = !0; const a = "Approve limit increase in your wallet"; o ? b.pushTransactionStack({ view: null, goBack: !0, onSuccess() { f.showLoading(a); } }) : f.showLoading(a); try { await N.sendTransaction({ address: n, to: t.to, data: t.data, value: t.value, chainNamespace: "eip155" }), await r.swapTokens(), await r.getTransaction(), e.approvalTransaction = void 0, e.loadingApprovalTransaction = !1; } catch (T) { const d = T; e.transactionError = d == null ? void 0 : d.shortMessage, e.loadingApprovalTransaction = !1, f.showError((d == null ? void 0 : d.shortMessage) || "Transaction error"), x.sendEvent({ type: "track", event: "SWAP_APPROVAL_ERROR", properties: { message: (d == null ? void 0 : d.shortMessage) || (d == null ? void 0 : d.message) || "Unknown", network: ((s = g.state.activeCaipNetwork) == null ? void 0 : s.caipNetworkId) || "", swapFromToken: ((i = r.state.sourceToken) == null ? void 0 : i.symbol) || "", swapToToken: ((u = r.state.toToken) == null ? void 0 : u.symbol) || "", swapFromAmount: r.state.sourceTokenAmount || "", swapToAmount: r.state.toTokenAmount || "", isSmartAccount: ((c = v.state.preferredAccountTypes) == null ? void 0 : c.eip155) === F.ACCOUNT_TYPES.SMART_ACCOUNT } }); } }, async sendTransactionForSwap(t) { var u, c, T, d, m, w, h, P, I, y, B, L, G, O; if (!t) return; const { fromAddress: n, toTokenAmount: o, isAuthConnector: a } = r.getParams(); e.loadingTransaction = !0; const s = `Swapping ${(u = e.sourceToken) == null ? void 0 : u.symbol} to ${l.formatNumberToLocalString(o, 3)} ${(c = e.toToken) == null ? void 0 : c.symbol}`, i = `Swapped ${(T = e.sourceToken) == null ? void 0 : T.symbol} to ${l.formatNumberToLocalString(o, 3)} ${(d = e.toToken) == null ? void 0 : d.symbol}`; a ? b.pushTransactionStack({ view: "Account", goBack: !1, onSuccess() { f.showLoading(s), U.resetState(); } }) : f.showLoading("Confirm transaction in your wallet"); try { const E = [(m = e.sourceToken) == null ? void 0 : m.address, (w = e.toToken) == null ? void 0 : w.address].join(","), p = await N.sendTransaction({ address: n, to: t.to, data: t.data, value: t.value, chainNamespace: "eip155" }); return e.loadingTransaction = !1, f.showSuccess(i), x.sendEvent({ type: "track", event: "SWAP_SUCCESS", properties: { network: ((h = g.state.activeCaipNetwork) == null ? void 0 : h.caipNetworkId) || "", swapFromToken: ((P = r.state.sourceToken) == null ? void 0 : P.symbol) || "", swapToToken: ((I = r.state.toToken) == null ? void 0 : I.symbol) || "", swapFromAmount: r.state.sourceTokenAmount || "", swapToAmount: r.state.toTokenAmount || "", isSmartAccount: ((y = v.state.preferredAccountTypes) == null ? void 0 : y.eip155) === F.ACCOUNT_TYPES.SMART_ACCOUNT } }), U.resetState(), a || b.replace("Account"), U.getMyTokensWithBalance(E), p; } catch (E) { const p = E; e.transactionError = p == null ? void 0 : p.shortMessage, e.loadingTransaction = !1, f.showError((p == null ? void 0 : p.shortMessage) || "Transaction error"), x.sendEvent({ type: "track", event: "SWAP_ERROR", properties: { message: (p == null ? void 0 : p.shortMessage) || (p == null ? void 0 : p.message) || "Unknown", network: ((B = g.state.activeCaipNetwork) == null ? void 0 : B.caipNetworkId) || "", swapFromToken: ((L = r.state.sourceToken) == null ? void 0 : L.symbol) || "", swapToToken: ((G = r.state.toToken) == null ? void 0 : G.symbol) || "", swapFromAmount: r.state.sourceTokenAmount || "", swapToAmount: r.state.toTokenAmount || "", isSmartAccount: ((O = v.state.preferredAccountTypes) == null ? void 0 : O.eip155) === F.ACCOUNT_TYPES.SMART_ACCOUNT } }); return; } }, // -- Checks -------------------------------------------- // hasInsufficientToken(t, n) { return S.isInsufficientSourceTokenForSwap(t, n, e.myTokensWithBalance); }, // -- Calculations -------------------------------------- // setTransactionDetails() { const { toTokenAddress: t, toTokenDecimals: n } = r.getParams(); !t || !n || (e.gasPriceInUSD = S.getGasPriceInUSD(e.networkPrice, BigInt(e.gasFee), BigInt(z)), e.priceImpact = S.getPriceImpact({ sourceTokenAmount: e.sourceTokenAmount, sourceTokenPriceInUSD: e.sourceTokenPriceInUSD, toTokenPriceInUSD: e.toTokenPriceInUSD, toTokenAmount: e.toTokenAmount }), e.maxSlippage = S.getMaxSlippage(e.slippage, e.toTokenAmount), e.providerFee = S.getProviderFee(e.sourceTokenAmount)); } }, r = Q(U), se = X` :host { display: block; } :host > button { gap: var(--wui-spacing-xxs); padding: var(--wui-spacing-xs); padding-right: var(--wui-spacing-1xs); height: 40px; border-radius: var(--wui-border-radius-l); background: var(--wui-color-gray-glass-002); border-width: 0px; box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-002); } :host > button wui-image { width: 24px; height: 24px; border-radius: var(--wui-border-radius-s); box-shadow: inset 0 0 0 1px var(--wui-color-gray-glass-010); } `; var _ = function(t, n, o, a) { var s = arguments.length, i = s < 3 ? n : a === null ? a = Object.getOwnPropertyDescriptor(n, o) : a, u; if (typeof Reflect == "object" && typeof Reflect.decorate == "function") i = Reflect.decorate(t, n, o, a); else for (var c = t.length - 1; c >= 0; c--) (u = t[c]) && (i = (s < 3 ? u(i) : s > 3 ? u(n, o, i) : u(n, o)) || i); return s > 3 && i && Object.defineProperty(n, o, i), i; }; let C = class extends te { constructor() { super(...arguments), this.text = ""; } render() { return M` <button> ${this.tokenTemplate()} <wui-text variant="paragraph-600" color="fg-100">${this.text}</wui-text> </button> `; } tokenTemplate() { return this.imageSrc ? M`<wui-image src=${this.imageSrc}></wui-image>` : M` <wui-icon-box size="sm" iconColor="fg-200" backgroundColor="fg-300" icon="networkPlaceholder" ></wui-icon-box> `; } }; C.styles = [Z, ee, se]; _([ q() ], C.prototype, "imageSrc", void 0); _([ q() ], C.prototype, "text", void 0); C = _([ ne("wui-token-button") ], C); export { r as S }; //# sourceMappingURL=index-C4sVDH8m.js.map