@nonnux/world-swap 0.1.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 +21 -0
- package/README.md +165 -0
- package/package.json +49 -0
- package/src/client.js +851 -0
- package/src/defaults.js +187 -0
- package/src/server.js +458 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 nonnux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# @nonnux/world-swap
|
|
2
|
+
|
|
3
|
+
A drop-in **token swap** for [World App](https://world.org/world-app) mini apps —
|
|
4
|
+
a ready-made swap card plus the quote API behind it. Routes through Uniswap
|
|
5
|
+
**V2, V3 and cross-version** pools on **World Chain**, with a 1% platform fee.
|
|
6
|
+
|
|
7
|
+
It's the same swap that powers the nonnux mini apps (UFO PIZZA SLICE, PAU$, REI$
|
|
8
|
+
Slots, …), packaged so you can add it to your own mini app in a couple of lines.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌──────────────────────────┐ ┌──────────────────────────────┐
|
|
12
|
+
│ <SwapCard /> (client) │ ─────▶ │ /api/swap/quote (server) │
|
|
13
|
+
│ wallet · UI · tx via │ POST │ reads Uniswap V2/V3 via RPC │
|
|
14
|
+
│ MiniKit.sendTransaction │ ◀───── │ (ethers, no DB, no secrets) │
|
|
15
|
+
└──────────────────────────┘ └──────────────────────────────┘
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- A **Next.js** app (App Router) — it provides the API route.
|
|
23
|
+
- **Tailwind CSS v4** — the card is styled with Tailwind utility classes.
|
|
24
|
+
- Peer deps (you almost certainly already have these): `react`, `react-dom`,
|
|
25
|
+
`ethers@^6`, `@worldcoin/minikit-js@>=1.9`.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @nonnux/world-swap
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Because the package ships source (not pre-bundled, for now), let Next transpile
|
|
34
|
+
it — add this to `next.config.js`:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
const nextConfig = {
|
|
38
|
+
transpilePackages: ['@nonnux/world-swap'],
|
|
39
|
+
};
|
|
40
|
+
module.exports = nextConfig;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
### 1. Mount the quote API
|
|
46
|
+
|
|
47
|
+
Create `app/api/swap/quote/route.js`:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
// Batteries-included: nonnux token list + World Chain contracts.
|
|
51
|
+
export { POST, GET } from '@nonnux/world-swap/server';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Render the card
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
'use client';
|
|
58
|
+
import { SwapCard } from '@nonnux/world-swap';
|
|
59
|
+
import { Button } from '@/components/ui/Button'; // your own button
|
|
60
|
+
|
|
61
|
+
export default function SwapTab({ user }) {
|
|
62
|
+
return <SwapCard walletUser={user} Button={Button} />;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
That's it. `walletUser` is your connected user object (`{ address }`); pass
|
|
67
|
+
`null` to show the "connect your wallet" state. `Button` is your own button
|
|
68
|
+
component so the CTA matches your app's look.
|
|
69
|
+
|
|
70
|
+
> Token icons are loaded from `/<icon>` (e.g. `/tokens/slice.gif`) in your
|
|
71
|
+
> `public/` folder. Copy the icons you need, or point `tokens[].icon` at a URL.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Customising
|
|
76
|
+
|
|
77
|
+
Everything is optional and falls back to the nonnux / World Chain defaults.
|
|
78
|
+
|
|
79
|
+
### Your own token list
|
|
80
|
+
|
|
81
|
+
`app/api/swap/quote/route.js`:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
import { createSwapQuoteHandler } from '@nonnux/world-swap/server';
|
|
85
|
+
import { MY_TOKENS } from '@/config/tokens';
|
|
86
|
+
|
|
87
|
+
export const { POST, GET } = createSwapQuoteHandler({ tokens: MY_TOKENS });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Component:
|
|
91
|
+
|
|
92
|
+
```jsx
|
|
93
|
+
import { SwapCard } from '@nonnux/world-swap';
|
|
94
|
+
import { MY_TOKENS } from '@/config/tokens';
|
|
95
|
+
|
|
96
|
+
<SwapCard walletUser={user} Button={Button} tokens={MY_TOKENS} />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A token looks like:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
{
|
|
103
|
+
symbol: 'SLICE',
|
|
104
|
+
name: 'UFO PIZZA',
|
|
105
|
+
address: '0x...',
|
|
106
|
+
icon: '/tokens/slice.gif', // path in /public or a URL
|
|
107
|
+
gradient: 'from-orange-500 to-yellow-500', // Tailwind gradient
|
|
108
|
+
decimals: 18,
|
|
109
|
+
emoji: '🍕', // fallback if icon fails
|
|
110
|
+
externalTaxPercent: 0, // token transfer tax, if any
|
|
111
|
+
poolVersion: 'v2', // 'v2' | 'v3'
|
|
112
|
+
v3FeeTier: 10000, // only for v3 tokens
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `<SwapCard />` props
|
|
117
|
+
|
|
118
|
+
| Prop | Default | Description |
|
|
119
|
+
| ---------------- | ------------------------ | ------------------------------------------------------ |
|
|
120
|
+
| `walletUser` | — | Connected user `{ address }`. `null` → connect state. |
|
|
121
|
+
| `Button` | — | Your button component for the CTA. |
|
|
122
|
+
| `tokens` | nonnux list | Token list to swap between. |
|
|
123
|
+
| `contracts` | World Chain | Override any contract address (merged with defaults). |
|
|
124
|
+
| `rpcUrl` | Alchemy public | JSON-RPC URL for balance reads. |
|
|
125
|
+
| `apiBasePath` | `/api/swap` | Base path of your quote route (`${base}/quote`). |
|
|
126
|
+
| `explorerUrl` | `https://worldscan.org` | Block explorer for the "view tx" link. |
|
|
127
|
+
| `ImageComponent` | `<img>` | Pass `next/image` (or a wrapper) to optimise icons. |
|
|
128
|
+
| `storagePrefix` | `world_swap` | localStorage key prefix (avoid cross-app collisions). |
|
|
129
|
+
| `title` | `Swap` | Header title. |
|
|
130
|
+
|
|
131
|
+
### `createSwapQuoteHandler(config)` options
|
|
132
|
+
|
|
133
|
+
`tokens`, `contracts`, `rpcUrl`, `directV3Pairs`, `platformFeeBps`, `v3FeeTiers`.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## How it works
|
|
138
|
+
|
|
139
|
+
- **Quote** (`/api/swap/quote`, server): given a token pair + amount, it reads
|
|
140
|
+
Uniswap pools on World Chain via `ethers` and returns the best route
|
|
141
|
+
(direct V2, V2 multi-hop through WLD, direct V3, or V3↔V2 cross-version),
|
|
142
|
+
plus price impact and the min-received after fee.
|
|
143
|
+
- **Swap** (client): builds a 2-step transaction (ERC-20 `transfer` to the swap
|
|
144
|
+
contract, then the swap call) and submits it with
|
|
145
|
+
`MiniKit.commandsAsync.sendTransaction`. The contract enforces `minAmountOut`.
|
|
146
|
+
|
|
147
|
+
No database, no API keys, no env vars required — the quote route only needs a
|
|
148
|
+
public World Chain RPC.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Add this swap to your own mini app
|
|
153
|
+
|
|
154
|
+
Building a World App mini app and want a swap tab without writing one? Install
|
|
155
|
+
`@nonnux/world-swap`, mount the quote route, and drop in `<SwapCard />` — about
|
|
156
|
+
two lines each (see **Usage** above). Bring your own token list or use the
|
|
157
|
+
defaults.
|
|
158
|
+
|
|
159
|
+
**Need a hand?** Read the guide: https://github.com/nonnux/world-swap#readme
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT © nonnux
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nonnux/world-swap",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Drop-in token swap card + quote API for World App mini apps (Uniswap V2/V3 on World Chain).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"worldcoin",
|
|
7
|
+
"world-app",
|
|
8
|
+
"minikit",
|
|
9
|
+
"worldchain",
|
|
10
|
+
"uniswap",
|
|
11
|
+
"swap",
|
|
12
|
+
"defi",
|
|
13
|
+
"react",
|
|
14
|
+
"nextjs"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "nonnux",
|
|
18
|
+
"homepage": "https://github.com/nonnux/world-swap#readme",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/nonnux/world-swap.git"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"src",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"exports": {
|
|
34
|
+
".": "./src/client.js",
|
|
35
|
+
"./server": "./src/server.js",
|
|
36
|
+
"./defaults": "./src/defaults.js"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@worldcoin/minikit-js": ">=1.9",
|
|
40
|
+
"ethers": "^6",
|
|
41
|
+
"react": ">=18",
|
|
42
|
+
"react-dom": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@worldcoin/minikit-js": {
|
|
46
|
+
"optional": false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|