@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 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
+ }