@shapeshiftoss/swap-widget 0.5.2 → 0.7.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/dist/index.js +77 -34
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useAppKitAccount as useAppKitAccount3 } from "@reown/appkit/react";
|
|
|
3
3
|
import { useCallback as useCallback11, useEffect as useEffect10, useMemo as useMemo12, useRef as useRef7, useState as useState8 } from "react";
|
|
4
4
|
|
|
5
5
|
// src/api/client.ts
|
|
6
|
-
var DEFAULT_API_BASE_URL =
|
|
6
|
+
var DEFAULT_API_BASE_URL = "https://api.shapeshift.com";
|
|
7
7
|
var createApiClient = (config = {}) => {
|
|
8
8
|
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
9
9
|
const fetchWithConfig = async (endpoint, params, method = "GET", timeoutMs = 3e4) => {
|
|
@@ -1330,7 +1330,7 @@ var useStatusPolling = ({
|
|
|
1330
1330
|
|
|
1331
1331
|
// src/hooks/useSwapApproval.ts
|
|
1332
1332
|
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
1333
|
-
import { createPublicClient as createPublicClient2,
|
|
1333
|
+
import { createPublicClient as createPublicClient2, http as http2 } from "viem";
|
|
1334
1334
|
|
|
1335
1335
|
// src/constants/chains.ts
|
|
1336
1336
|
import {
|
|
@@ -1443,6 +1443,15 @@ var useSwapApproval = () => {
|
|
|
1443
1443
|
});
|
|
1444
1444
|
return;
|
|
1445
1445
|
}
|
|
1446
|
+
if (!sellAmountBaseUnit || sellAmountBaseUnit === "0") {
|
|
1447
|
+
actorRef.send({ type: "APPROVAL_ERROR", error: "No sell amount specified" });
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
const approvalTxs = quote.approval.approvalTxs;
|
|
1451
|
+
if (!approvalTxs?.length) {
|
|
1452
|
+
actorRef.send({ type: "APPROVAL_ERROR", error: "No approval transactions in quote" });
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1446
1455
|
const requiredChainId = getEvmNetworkId(sellAsset.chainId);
|
|
1447
1456
|
const client = walletClient;
|
|
1448
1457
|
const currentChainId = await client.getChainId();
|
|
@@ -1458,28 +1467,24 @@ var useSwapApproval = () => {
|
|
|
1458
1467
|
nativeCurrency,
|
|
1459
1468
|
rpcUrls: { default: { http: [] } }
|
|
1460
1469
|
};
|
|
1461
|
-
if (!sellAmountBaseUnit || sellAmountBaseUnit === "0") {
|
|
1462
|
-
actorRef.send({ type: "APPROVAL_ERROR", error: "No sell amount specified" });
|
|
1463
|
-
return;
|
|
1464
|
-
}
|
|
1465
|
-
const approvalData = encodeFunctionData({
|
|
1466
|
-
abi: erc20Abi2,
|
|
1467
|
-
functionName: "approve",
|
|
1468
|
-
args: [quote.approval.spender, BigInt(sellAmountBaseUnit)]
|
|
1469
|
-
});
|
|
1470
|
-
const approvalHash = await client.sendTransaction({
|
|
1471
|
-
to: sellAssetAddress,
|
|
1472
|
-
data: approvalData,
|
|
1473
|
-
value: BigInt(0),
|
|
1474
|
-
chain,
|
|
1475
|
-
account: walletAddress
|
|
1476
|
-
});
|
|
1477
1470
|
const rpcUrl = chain.rpcUrls?.default?.http?.[0];
|
|
1478
1471
|
const publicClient = createPublicClient2({
|
|
1479
1472
|
chain,
|
|
1480
1473
|
transport: rpcUrl ? http2(rpcUrl) : http2()
|
|
1481
1474
|
});
|
|
1482
|
-
|
|
1475
|
+
let approvalHash;
|
|
1476
|
+
for (const approvalTx of approvalTxs) {
|
|
1477
|
+
approvalHash = await client.sendTransaction({
|
|
1478
|
+
to: approvalTx.to,
|
|
1479
|
+
data: approvalTx.data,
|
|
1480
|
+
value: BigInt(approvalTx.value),
|
|
1481
|
+
chain,
|
|
1482
|
+
account: walletAddress
|
|
1483
|
+
});
|
|
1484
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: approvalHash });
|
|
1485
|
+
if (receipt.status !== "success") throw new Error("Approval transaction reverted");
|
|
1486
|
+
}
|
|
1487
|
+
if (!approvalHash) throw new Error("Expected at least one approval transaction");
|
|
1483
1488
|
actorRef.send({ type: "APPROVAL_SUCCESS", txHash: approvalHash });
|
|
1484
1489
|
} catch (error) {
|
|
1485
1490
|
actorRef.send({
|
|
@@ -1623,7 +1628,7 @@ import { useQueries, useQueryClient } from "@tanstack/react-query";
|
|
|
1623
1628
|
import { getBalance, readContract } from "@wagmi/core";
|
|
1624
1629
|
import PQueue from "p-queue";
|
|
1625
1630
|
import { useCallback as useCallback3, useMemo as useMemo4 } from "react";
|
|
1626
|
-
import { erc20Abi as
|
|
1631
|
+
import { erc20Abi as erc20Abi2 } from "viem";
|
|
1627
1632
|
import { useConfig } from "wagmi";
|
|
1628
1633
|
var CONCURRENCY_LIMIT = 5;
|
|
1629
1634
|
var DELAY_BETWEEN_BATCHES_MS = 50;
|
|
@@ -1823,7 +1828,7 @@ var useMultiChainBalance = (evmAddress, utxoAddress, solanaAddress, assetId, pre
|
|
|
1823
1828
|
if (isErc20 && evmParsed.tokenAddress) {
|
|
1824
1829
|
const result2 = await readContract(config, {
|
|
1825
1830
|
address: evmParsed.tokenAddress,
|
|
1826
|
-
abi:
|
|
1831
|
+
abi: erc20Abi2,
|
|
1827
1832
|
functionName: "balanceOf",
|
|
1828
1833
|
args: [evmAddress],
|
|
1829
1834
|
chainId: evmParsed.evmChainId
|
|
@@ -1936,7 +1941,7 @@ var useMultiChainBalances = (evmAddress, utxoAddress, solanaAddress, assetIds, a
|
|
|
1936
1941
|
if (asset.tokenAddress) {
|
|
1937
1942
|
const result2 = await readContract(config, {
|
|
1938
1943
|
address: asset.tokenAddress,
|
|
1939
|
-
abi:
|
|
1944
|
+
abi: erc20Abi2,
|
|
1940
1945
|
functionName: "balanceOf",
|
|
1941
1946
|
args: [evmAddress],
|
|
1942
1947
|
// @ts-ignore - swap-widget supports more chains than main app's wagmi type registration
|
|
@@ -2459,13 +2464,13 @@ var executeEvm = async (txData, walletClient, walletAddress) => {
|
|
|
2459
2464
|
account: getAddress2(walletAddress)
|
|
2460
2465
|
});
|
|
2461
2466
|
};
|
|
2462
|
-
var
|
|
2467
|
+
var executeUtxo = (txData, bitcoin3) => {
|
|
2463
2468
|
if (!bitcoin3.isConnected || !bitcoin3.address) throw new Error("Bitcoin wallet not connected");
|
|
2464
2469
|
bitcoin3.reset();
|
|
2465
2470
|
return bitcoin3.sendTransfer({
|
|
2466
|
-
recipientAddress: txData.
|
|
2471
|
+
recipientAddress: txData.to,
|
|
2467
2472
|
amount: txData.value,
|
|
2468
|
-
memo: txData.
|
|
2473
|
+
memo: txData.opReturnData
|
|
2469
2474
|
});
|
|
2470
2475
|
};
|
|
2471
2476
|
var executeSolana = async (txData, solana3) => {
|
|
@@ -2473,7 +2478,13 @@ var executeSolana = async (txData, solana3) => {
|
|
|
2473
2478
|
throw new Error("Solana wallet not connected");
|
|
2474
2479
|
}
|
|
2475
2480
|
solana3.reset();
|
|
2476
|
-
const {
|
|
2481
|
+
const {
|
|
2482
|
+
ComputeBudgetProgram,
|
|
2483
|
+
PublicKey: PublicKey3,
|
|
2484
|
+
TransactionInstruction,
|
|
2485
|
+
TransactionMessage,
|
|
2486
|
+
VersionedTransaction
|
|
2487
|
+
} = await import("@solana/web3.js");
|
|
2477
2488
|
const instructions = txData.instructions.map((ix) => {
|
|
2478
2489
|
return new TransactionInstruction({
|
|
2479
2490
|
keys: ix.keys.map((key) => ({
|
|
@@ -2485,11 +2496,41 @@ var executeSolana = async (txData, solana3) => {
|
|
|
2485
2496
|
data: Buffer.from(ix.data, "base64")
|
|
2486
2497
|
});
|
|
2487
2498
|
});
|
|
2488
|
-
const transaction = new Transaction().add(...instructions);
|
|
2489
2499
|
const conn = solana3.connection;
|
|
2500
|
+
const includeComputeBudget = instructions.some(
|
|
2501
|
+
(ix) => ix.programId.equals(ComputeBudgetProgram.programId)
|
|
2502
|
+
);
|
|
2503
|
+
if (includeComputeBudget) {
|
|
2504
|
+
const recentFees = await conn.getRecentPrioritizationFees();
|
|
2505
|
+
const fees = recentFees.map((fee) => fee.prioritizationFee).filter((fee) => fee > 0).sort((a, b) => a - b);
|
|
2506
|
+
const priorityFee = fees[Math.floor(fees.length * 0.75)] ?? 0;
|
|
2507
|
+
if (priorityFee > 0) {
|
|
2508
|
+
instructions.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFee }));
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
const lookupTableAccounts = (await Promise.all(
|
|
2512
|
+
txData.addressLookupTableAddresses.map(async (address) => {
|
|
2513
|
+
const { value } = await conn.getAddressLookupTable(new PublicKey3(address));
|
|
2514
|
+
return value;
|
|
2515
|
+
})
|
|
2516
|
+
)).filter((account) => account !== null);
|
|
2490
2517
|
const { blockhash } = await conn.getLatestBlockhash("confirmed");
|
|
2491
|
-
|
|
2492
|
-
|
|
2518
|
+
const message = new TransactionMessage({
|
|
2519
|
+
payerKey: new PublicKey3(solana3.address),
|
|
2520
|
+
recentBlockhash: blockhash,
|
|
2521
|
+
instructions
|
|
2522
|
+
}).compileToV0Message(lookupTableAccounts);
|
|
2523
|
+
return solana3.sendTransaction({ transaction: new VersionedTransaction(message) });
|
|
2524
|
+
};
|
|
2525
|
+
var executeSolanaSerializedTx = async (txData, solana3) => {
|
|
2526
|
+
if (!solana3.isConnected || !solana3.address || !solana3.connection) {
|
|
2527
|
+
throw new Error("Solana wallet not connected");
|
|
2528
|
+
}
|
|
2529
|
+
solana3.reset();
|
|
2530
|
+
const { VersionedTransaction } = await import("@solana/web3.js");
|
|
2531
|
+
const transaction = VersionedTransaction.deserialize(
|
|
2532
|
+
new Uint8Array(Buffer.from(txData.serializedTx, "base64"))
|
|
2533
|
+
);
|
|
2493
2534
|
return solana3.sendTransaction({ transaction });
|
|
2494
2535
|
};
|
|
2495
2536
|
var useSwapExecution = () => {
|
|
@@ -2525,12 +2566,14 @@ var useSwapExecution = () => {
|
|
|
2525
2566
|
switch (txData.type) {
|
|
2526
2567
|
case "evm":
|
|
2527
2568
|
return executeEvm(txData, walletClient, walletAddress);
|
|
2528
|
-
case "
|
|
2529
|
-
return
|
|
2530
|
-
case "
|
|
2569
|
+
case "utxo":
|
|
2570
|
+
return executeUtxo(txData, bitcoin3);
|
|
2571
|
+
case "solana_instructions":
|
|
2531
2572
|
return executeSolana(txData, solana3);
|
|
2532
|
-
case "
|
|
2533
|
-
|
|
2573
|
+
case "solana_serialized_tx":
|
|
2574
|
+
return executeSolanaSerializedTx(txData, solana3);
|
|
2575
|
+
case "cosmossdk_msg_send":
|
|
2576
|
+
case "cosmossdk_msg_deposit":
|
|
2534
2577
|
throw new Error("This swap is not yet supported \u2014 please try a different route");
|
|
2535
2578
|
default: {
|
|
2536
2579
|
const _exhaustive = txData;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swap-widget",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Embeddable swap widget using ShapeShift API",
|
|
5
5
|
"repository": "https://github.com/shapeshift/web",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"p-queue": "^8.0.1",
|
|
31
31
|
"react-virtuoso": "^4.7.11",
|
|
32
32
|
"xstate": "5.28.0",
|
|
33
|
+
"@shapeshiftoss/utils": "^1.1.0",
|
|
33
34
|
"@shapeshiftoss/caip": "^8.16.10",
|
|
34
|
-
"@shapeshiftoss/types": "^
|
|
35
|
-
"@shapeshiftoss/utils": "^1.1.0"
|
|
35
|
+
"@shapeshiftoss/types": "^9.0.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@wagmi/core": "^2.0.0",
|