UNPKG

@perawallet/swap

Version:

Algorand swap utilities and widget integration

293 lines (286 loc) 8.13 kB
'use strict'; var algosdk = require('algosdk'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var algosdk__default = /*#__PURE__*/_interopDefault(algosdk); // src/utils.ts async function makeRequest(baseURL, endpoint, options = {}) { const url = `${baseURL}${endpoint}`; const response = await fetch(url, { headers: { "Content-Type": "application/json", ...options.headers }, ...options }); if (!response.ok) { let errorDetails = ""; try { errorDetails = await response.json(); } catch { try { errorDetails = await response.text(); } catch { errorDetails = "Unable to read error details"; } } throw new Error(JSON.stringify(errorDetails)); } return response.json(); } function getPeraBaseUrl(network) { return network === "mainnet" ? "https://mainnet.api.perawallet.app" : "https://testnet.api.perawallet.app"; } var DEFAULT_WIDGET_URL = "https://swap-widget.perawallet.app"; // src/swap.ts var PeraSwap = class { constructor(network = "mainnet", referrerUrl) { this.network = network; this.baseURL = getPeraBaseUrl(network); this.referrerUrl = referrerUrl; } /** * Update the network for all subsequent operations */ updateNetwork(network) { this.network = network; this.baseURL = getPeraBaseUrl(network); } /** * Get the current network */ getNetwork() { return this.network; } /** * Create a swap quote */ async createQuote(body, signal) { const bodyData = { ...body, referrer_url: this.referrerUrl }; return makeRequest(this.baseURL, "/v2/dex-swap/quotes/", { method: "POST", body: JSON.stringify(bodyData), signal }); } /** * Update the status of a swap */ async updateSwapStatus(swapId, body) { const bodyData = { ...body, platform: "js-sdk", swap_version: "v2" }; return makeRequest(this.baseURL, `/v2/dex-swap/swaps/${swapId}/`, { method: "PATCH", body: JSON.stringify(bodyData) }); } /** * Prepare transactions for a swap */ async prepareTransactions(quoteId, depositAddress) { return makeRequest( this.baseURL, `/v2/dex-swap/prepare-transactions/`, { method: "POST", body: JSON.stringify({ quote: quoteId, deposit_address: depositAddress }) } ); } /** * Get available assets for swapping */ async getAvailableAssets(params) { const searchParams = new URLSearchParams(); searchParams.append("asset_in_id", params.asset_in_id.toString()); if (params.q) searchParams.append("q", params.q); return makeRequest(this.baseURL, `/v1/dex-swap/available-assets/?${searchParams}`); } /** * Get assets by IDs or search query */ async getAssets(params) { const searchParams = new URLSearchParams(); if (params.asset_ids) searchParams.append("asset_ids", params.asset_ids.join(",")); if (params.q) searchParams.append("q", params.q); return makeRequest(this.baseURL, `/v1/assets/?${searchParams}`); } /** * Get ALGO price in USD */ async getAlgoPrice() { return makeRequest(this.baseURL, "/v1/currencies/USD/"); } /** * Get asset information by ID */ async getAsset(assetId) { try { const response = await this.getAssets({ asset_ids: [assetId.toString()] }); return response.results[0] || null; } catch (error) { console.error("Error fetching asset:", error); return null; } } /** * Search for assets by name */ async searchAssets(query) { try { const response = await this.getAssets({ q: query }); return response.results; } catch (error) { console.error("Error searching assets:", error); return []; } } }; // src/types.ts var SwapWidgetSearchParamKey = /* @__PURE__ */ ((SwapWidgetSearchParamKey2) => { SwapWidgetSearchParamKey2["USE_PARENT_SIGNER"] = "useParentSigner"; SwapWidgetSearchParamKey2["ACCOUNT_ADDRESS"] = "accountAddress"; SwapWidgetSearchParamKey2["NETWORK"] = "network"; SwapWidgetSearchParamKey2["THEME"] = "theme"; SwapWidgetSearchParamKey2["ASSET_IN"] = "assetIn"; SwapWidgetSearchParamKey2["ASSET_OUT"] = "assetOut"; SwapWidgetSearchParamKey2["IFRAME_BACKGROUND"] = "iframeBg"; return SwapWidgetSearchParamKey2; })(SwapWidgetSearchParamKey || {}); var WidgetController = class _WidgetController { constructor(config = {}) { this.config = config; } /** * Generate a URL for the Pera Swap Widget iframe */ static generateWidgetUrl(config = {}) { const url = new URL(DEFAULT_WIDGET_URL); if (config.network) { url.searchParams.set("network", config.network); } if (config.theme) { url.searchParams.set("theme", config.theme); } if (config.assetIn !== void 0) { url.searchParams.set("assetIn", String(config.assetIn)); } if (config.assetOut !== void 0) { url.searchParams.set("assetOut", String(config.assetOut)); } if (config.iframeBg) { url.searchParams.set("iframeBg", config.iframeBg); } if (config.useParentSigner) { url.searchParams.set("useParentSigner", "true"); if (config.accountAddress) { url.searchParams.set("accountAddress", config.accountAddress); } } return url.toString(); } /** * Create an iframe element with the swap widget */ static createWidgetIframe(config = {}, options = {}) { const iframe = document.createElement("iframe"); iframe.src = _WidgetController.generateWidgetUrl(config); iframe.width = options.width || "100%"; iframe.height = options.height || "488px"; if (options.className) { iframe.className = options.className; } if (options.id) { iframe.id = options.id; } return iframe; } /** * Send message to widget iframe */ static sendMessageToWidget({ data, targetWindow }) { if (targetWindow) { targetWindow.postMessage(data, "*"); } } /** * Add event listeners for widget communication */ addWidgetEventListeners() { window.addEventListener("message", this.handleMessage.bind(this)); } /** * Remove event listeners */ removeWidgetEventListeners() { window.removeEventListener("message", this.handleMessage.bind(this)); } /** * Handle messages from the widget */ handleMessage(event) { if (!event.data || !event.data.type || !event.data.message) { return; } switch (event.data.type) { case "TXN_SIGN_REQUEST": { const { txGroups } = event.data.message; const decodedTxGroups = txGroups.map( (group) => group.map((bytes) => algosdk__default.default.decodeUnsignedTransaction(bytes)) ); if (this.config.onTxnSignRequest) { this.config.onTxnSignRequest({ txGroups: decodedTxGroups }).then((signedTxns) => { _WidgetController.sendMessageToWidget({ data: { message: { type: "TXN_SIGN_RESPONSE", signedTxns } }, targetWindow: event.source }); }).catch((error) => { _WidgetController.sendMessageToWidget({ data: { message: { type: "FAILED_TXN_SIGN", error } }, targetWindow: event.source }); }); } break; } case "TXN_SIGN_REQUEST_TIMEOUT": { if (this.config.onTxnSignRequestTimeout) { this.config.onTxnSignRequestTimeout(); } break; } case "SWAP_SUCCESS": { if (this.config.onSwapSuccess) { this.config.onSwapSuccess(event.data.message); } break; } } } }; exports.PeraSwap = PeraSwap; exports.SwapWidgetSearchParamKey = SwapWidgetSearchParamKey; exports.WidgetController = WidgetController; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map