@coin-voyage/swapkit 0.3.0 → 0.4.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/LICENSE +8 -8
- package/README.md +68 -68
- package/dist/components/execution-modal.d.ts +1 -1
- package/dist/components/execution-modal.js +6 -2
- package/dist/components/styles.d.ts +1 -1
- package/dist/components/styles.js +1282 -1281
- package/dist/components/swap-recipient.test.d.ts +1 -0
- package/dist/components/swap-recipient.test.js +136 -0
- package/dist/components/swap.d.ts +3 -3
- package/dist/components/swap.js +35 -23
- package/dist/components/swap.test.d.ts +1 -0
- package/dist/components/swap.test.js +76 -0
- package/dist/components/token-picker.js +1 -1
- package/dist/components/wallet-connector.d.ts +1 -1
- package/dist/components/wallet-connector.js +24 -4
- package/dist/components/wallet-connector.test.js +55 -1
- package/dist/hooks/use-order-status.d.ts +1 -1
- package/dist/hooks/use-token-data.d.ts +3 -2
- package/dist/hooks/use-token-data.js +41 -12
- package/dist/hooks/use-token-data.test.d.ts +1 -0
- package/dist/hooks/use-token-data.test.js +81 -0
- package/dist/lib/amount-input.d.ts +1 -0
- package/dist/lib/amount-input.js +7 -0
- package/dist/lib/amount-input.test.d.ts +1 -0
- package/dist/lib/amount-input.test.js +17 -0
- package/dist/lib/execution.d.ts +2 -0
- package/dist/lib/execution.js +6 -0
- package/dist/lib/execution.test.d.ts +1 -0
- package/dist/lib/execution.test.js +24 -0
- package/dist/lib/output-wallet.d.ts +1 -2
- package/dist/lib/output-wallet.js +2 -2
- package/dist/lib/output-wallet.test.d.ts +1 -0
- package/dist/lib/output-wallet.test.js +26 -0
- package/dist/providers/swapkit-context.d.ts +1 -1
- package/dist/providers/swapkit-provider.js +1 -1
- package/dist/styles/root.js +59 -59
- package/dist/styles/theme.js +1 -1
- package/package.json +8 -8
package/LICENSE
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
Copyright (c) 2026 Coin Voyage
|
|
2
|
-
|
|
3
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
-
|
|
5
|
-
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
-
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
7
|
-
|
|
8
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
1
|
+
Copyright (c) 2026 Coin Voyage
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
7
|
+
|
|
8
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
# @coin-voyage/swapkit
|
|
2
|
-
|
|
3
|
-
Embeddable Coin Voyage swap UI for React applications. SwapKit uses styled-components and does not require Tailwind CSS.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```sh
|
|
8
|
-
pnpm add @coin-voyage/swapkit @tanstack/react-query react react-dom styled-components
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Install the wallet peer dependencies listed in this package's `package.json` for the chains your application supports.
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```tsx
|
|
16
|
-
import { Swap, SwapKitProvider, WalletProvider } from "@coin-voyage/swapkit"
|
|
17
|
-
|
|
18
|
-
export function App() {
|
|
19
|
-
return (
|
|
20
|
-
<WalletProvider>
|
|
21
|
-
<SwapKitProvider apiKey={process.env.NEXT_PUBLIC_COIN_VOYAGE_API_KEY!} environment="development" mode="dark">
|
|
22
|
-
<Swap
|
|
23
|
-
defaultSourceCurrency={{ chain_id: 1 }}
|
|
24
|
-
defaultDestinationCurrency={{
|
|
25
|
-
chain_id: 30000000000001,
|
|
26
|
-
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
27
|
-
}}
|
|
28
|
-
/>
|
|
29
|
-
</SwapKitProvider>
|
|
30
|
-
</WalletProvider>
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
`SwapKitProvider` deliberately uses the public API client and never accepts an admin signing key. It must be rendered
|
|
36
|
-
inside `WalletProvider`, which SwapKit re-exports from its canonical implementation in `@coin-voyage/crypto/wallets`.
|
|
37
|
-
The wallet provider supplies React Query and the supported chain contexts, while reusing a compatible host Query
|
|
38
|
-
Client when one already exists.
|
|
39
|
-
|
|
40
|
-
`Swap` optionally accepts `defaultSourceCurrency`, `defaultDestinationCurrency`, and `defaultSlippageBps`, plus
|
|
41
|
-
`onComplete` and `onError` callbacks for host notifications. Currency defaults use `{ chain_id, address? }`; token
|
|
42
|
-
addresses are matched case-insensitively. Slippage is an integer from `0` to `10000` basis points.
|
|
43
|
-
|
|
44
|
-
When `defaultSlippageBps` is omitted, slippage starts in Auto mode and SwapKit lets the quote service choose the
|
|
45
|
-
appropriate tolerance. The custom control retains a `1%` draft. Supplying `defaultSlippageBps` starts the widget in
|
|
46
|
-
Custom mode and sends that value with quote and execution requests.
|
|
47
|
-
|
|
48
|
-
Defaults are read once when a widget mounts. Changing them later does not interrupt an in-progress swap; remount the
|
|
49
|
-
widget with a new React `key` to apply a new set of defaults. Unsupported defaults fall back to the normal automatic
|
|
50
|
-
selection.
|
|
51
|
-
|
|
52
|
-
### Theming
|
|
53
|
-
|
|
54
|
-
Use `mode="light"` or `mode="dark"`. The optional `theme` prop overrides individual widget colors:
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<SwapKitProvider apiKey={apiKey} mode="dark" theme={{ accent: "#7c3aed", radius: "18px" }}>
|
|
58
|
-
<Swap />
|
|
59
|
-
</SwapKitProvider>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Development
|
|
63
|
-
|
|
64
|
-
```sh
|
|
65
|
-
pnpm --filter @coin-voyage/swapkit test
|
|
66
|
-
pnpm --filter @coin-voyage/swapkit type-check
|
|
67
|
-
pnpm --filter @coin-voyage/swapkit build
|
|
68
|
-
```
|
|
1
|
+
# @coin-voyage/swapkit
|
|
2
|
+
|
|
3
|
+
Embeddable Coin Voyage swap UI for React applications. SwapKit uses styled-components and does not require Tailwind CSS.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @coin-voyage/swapkit @tanstack/react-query react react-dom styled-components
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install the wallet peer dependencies listed in this package's `package.json` for the chains your application supports.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Swap, SwapKitProvider, WalletProvider } from "@coin-voyage/swapkit"
|
|
17
|
+
|
|
18
|
+
export function App() {
|
|
19
|
+
return (
|
|
20
|
+
<WalletProvider>
|
|
21
|
+
<SwapKitProvider apiKey={process.env.NEXT_PUBLIC_COIN_VOYAGE_API_KEY!} environment="development" mode="dark">
|
|
22
|
+
<Swap
|
|
23
|
+
defaultSourceCurrency={{ chain_id: 1 }}
|
|
24
|
+
defaultDestinationCurrency={{
|
|
25
|
+
chain_id: 30000000000001,
|
|
26
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
</SwapKitProvider>
|
|
30
|
+
</WalletProvider>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`SwapKitProvider` deliberately uses the public API client and never accepts an admin signing key. It must be rendered
|
|
36
|
+
inside `WalletProvider`, which SwapKit re-exports from its canonical implementation in `@coin-voyage/crypto/wallets`.
|
|
37
|
+
The wallet provider supplies React Query and the supported chain contexts, while reusing a compatible host Query
|
|
38
|
+
Client when one already exists.
|
|
39
|
+
|
|
40
|
+
`Swap` optionally accepts `defaultSourceCurrency`, `defaultDestinationCurrency`, and `defaultSlippageBps`, plus
|
|
41
|
+
`onComplete` and `onError` callbacks for host notifications. Currency defaults use `{ chain_id, address? }`; token
|
|
42
|
+
addresses are matched case-insensitively. Slippage is an integer from `0` to `10000` basis points.
|
|
43
|
+
|
|
44
|
+
When `defaultSlippageBps` is omitted, slippage starts in Auto mode and SwapKit lets the quote service choose the
|
|
45
|
+
appropriate tolerance. The custom control retains a `1%` draft. Supplying `defaultSlippageBps` starts the widget in
|
|
46
|
+
Custom mode and sends that value with quote and execution requests.
|
|
47
|
+
|
|
48
|
+
Defaults are read once when a widget mounts. Changing them later does not interrupt an in-progress swap; remount the
|
|
49
|
+
widget with a new React `key` to apply a new set of defaults. Unsupported defaults fall back to the normal automatic
|
|
50
|
+
selection.
|
|
51
|
+
|
|
52
|
+
### Theming
|
|
53
|
+
|
|
54
|
+
Use `mode="light"` or `mode="dark"`. The optional `theme` prop overrides individual widget colors:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<SwapKitProvider apiKey={apiKey} mode="dark" theme={{ accent: "#7c3aed", radius: "18px" }}>
|
|
58
|
+
<Swap />
|
|
59
|
+
</SwapKitProvider>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
pnpm --filter @coin-voyage/swapkit test
|
|
66
|
+
pnpm --filter @coin-voyage/swapkit type-check
|
|
67
|
+
pnpm --filter @coin-voyage/swapkit build
|
|
68
|
+
```
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { getChainExplorerTxUrl, getChainName } from "@coin-voyage/shared/chain";
|
|
3
|
+
import { deliversInSwapTransaction } from "../lib/execution";
|
|
3
4
|
import { AlertCircleIcon, ArrowRightIcon, CheckIcon, StatusDot, WarningIcon } from "./icons";
|
|
4
5
|
import { Modal } from "./modal";
|
|
5
6
|
import { ExecutionContent, ExecutionState, ExplorerLink, ProgressConnector, ProgressItem, ProgressLabel, ProgressList, ProgressMarker, ProgressMarkerColumn, ProgressText, RouteArrow, Spinner, TokenAmount, TokenRoute, } from "./styles";
|
|
@@ -79,7 +80,10 @@ export function ExecutionModal({ stage, onClose }) {
|
|
|
79
80
|
const open = stage.kind !== "idle";
|
|
80
81
|
const swapData = "swapData" in stage ? stage.swapData : null;
|
|
81
82
|
const preventDismiss = stage.kind !== "done" && stage.kind !== "refunded" && stage.kind !== "error";
|
|
82
|
-
|
|
83
|
+
// A same-chain swap settles in the user's own transaction, so a receive step would only repeat the swap step.
|
|
84
|
+
const hasSeparateDelivery = stage.kind === "done" && stage.destinationTxHash !== undefined && stage.destinationTxHash !== stage.sourceTxHash;
|
|
85
|
+
const showOutcome = stage.kind === "refunded" || hasSeparateDelivery || !swapData || !deliversInSwapTransaction(swapData);
|
|
86
|
+
return (_jsx(Modal, { open: open, title: "Transaction Details", onClose: onClose, preventDismiss: preventDismiss, maxWidth: 384, children: stage.kind === "error" ? (_jsxs(ExecutionState, { "$tone": "danger", children: [_jsx(AlertCircleIcon, {}), _jsx("p", { children: stage.message })] })) : !swapData ? (_jsxs(ExecutionState, { children: [_jsx(Spinner, {}), _jsx("p", { children: "Loading swap data..." })] })) : (_jsxs(ExecutionContent, { children: [_jsxs(TokenRoute, { children: [_jsxs(TokenAmount, { children: [_jsx(TokenIcon, { currency: swapData.data.input.currency, size: 40 }), _jsxs("strong", { children: [swapData.data.input.amount.ui, " ", swapData.data.input.currency.symbol] })] }), _jsx(RouteArrow, { children: _jsx(ArrowRightIcon, {}) }), _jsxs(TokenAmount, { "$align": "end", children: [_jsx(TokenIcon, { currency: swapData.data.output.currency, size: 40 }), _jsxs("strong", { children: [swapData.data.output.amount.ui, " ", swapData.data.output.currency.symbol] })] })] }), _jsxs(ProgressList, { "aria-label": "Swap progress", children: [swapData.data.steps.map((step, index) => (_jsx(ProgressStep, { title: stepTitle(step, swapData.data.input.currency.symbol, getChainName(swapData.data.input.currency.chain_id) ?? "Unknown network"), state: paymentStepState(stage, step, index, swapData.data.steps.length), connected: showOutcome || index < swapData.data.steps.length - 1 }, step.id ?? index))), showOutcome && (_jsx(ProgressStep, { title: stage.kind === "refunded"
|
|
83
87
|
? `Refund ${swapData.data.input.currency.symbol} on ${getChainName(swapData.data.input.currency.chain_id) ?? "Unknown network"}`
|
|
84
|
-
: `Receive ${swapData.data.output.currency.symbol} on ${getChainName(swapData.data.output.currency.chain_id) ?? "Unknown network"}`, state: outcomeState(stage), connected: false })] })] })) }));
|
|
88
|
+
: `Receive ${swapData.data.output.currency.symbol} on ${getChainName(swapData.data.output.currency.chain_id) ?? "Unknown network"}`, state: outcomeState(stage), connected: false }))] })] })) }));
|
|
85
89
|
}
|
|
@@ -28,6 +28,7 @@ export declare const Hint: import("styled-components").StyledComponent<"p", any,
|
|
|
28
28
|
export declare const CardWrap: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
29
29
|
export declare const CurrencyCard: import("styled-components").StyledComponent<"section", any, {}, never>;
|
|
30
30
|
export declare const CardTitle: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
31
|
+
export declare const CardHeaderAction: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
31
32
|
export declare const QuickAmountActions: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
32
33
|
export declare const QuickAmountButton: import("styled-components").StyledComponent<"button", any, {}, never>;
|
|
33
34
|
export declare const AmountRow: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -45,7 +46,6 @@ export declare const ChainBadge: import("styled-components").StyledComponent<"sp
|
|
|
45
46
|
$size: number;
|
|
46
47
|
}, never>;
|
|
47
48
|
export declare const CardFooter: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
48
|
-
export declare const InlineActions: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
49
49
|
export declare const OutputWalletControl: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
50
50
|
export declare const OutputWalletTrigger: import("styled-components").StyledComponent<"button", any, {}, never>;
|
|
51
51
|
export declare const OutputWalletMenu: import("styled-components").StyledComponent<"span", any, {}, never>;
|