Skip to content

Commit 3d5301c

Browse files
committed
feat: correct osmosis swap data
1 parent 9eb8070 commit 3d5301c

File tree

8 files changed

+138
-48
lines changed

8 files changed

+138
-48
lines changed

apps/namadillo/index.html

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@
1515
<body>
1616
<noscript>You need to enable JavaScript to run this app.</noscript>
1717
<div id="root"></div>
18-
<script type="module">
19-
import { Buffer } from "buffer";
20-
import process from "process";
21-
22-
globalThis.process = process;
23-
globalThis.Buffer = Buffer;
24-
</script>
2518
<script type="module" src="/src/index.tsx"></script>
2619
</body>
2720
</html>

apps/namadillo/package.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"license": "MIT",
88
"private": true,
99
"dependencies": {
10-
"@chain-registry/assets": "^1.70.198",
1110
"@chain-registry/client": "^1.53.5",
1211
"@cosmjs/encoding": "^0.32.3",
1312
"@keplr-wallet/types": "^0.12.136",
@@ -20,7 +19,6 @@
2019
"@tanstack/react-query-persist-client": "^5.40.0",
2120
"animejs": "^3.2.2",
2221
"bignumber.js": "^9.1.1",
23-
"buffer": "^6.0.3",
2422
"clsx": "^2.1.1",
2523
"comlink": "^4.4.1",
2624
"crypto-browserify": "^3.12.0",
@@ -33,8 +31,6 @@
3331
"jotai-tanstack-query": "^0.8.5",
3432
"lodash.debounce": "^4.0.8",
3533
"lodash.isequal": "^4.5.0",
36-
"osmojs": "^16.15.0",
37-
"process": "^0.11.10",
3834
"react": "^18.3.1",
3935
"react-dom": "^18.3.1",
4036
"react-icons": "^5.1.0",
@@ -87,7 +83,6 @@
8783
]
8884
},
8985
"devDependencies": {
90-
"@chain-registry/types": "^0.50.125",
9186
"@eslint/js": "^9.9.1",
9287
"@playwright/test": "^1.24.1",
9388
"@svgr/webpack": "^6.5.1",
@@ -108,7 +103,6 @@
108103
"@types/styled-components": "^5.1.22",
109104
"@types/traverse": "^0.6.36",
110105
"@types/w3c-web-usb": "^1.0.10",
111-
"@vitejs/plugin-legacy": "^6.1.0",
112106
"@vitejs/plugin-react": "^4.3.1",
113107
"autoprefixer": "^10.4.16",
114108
"axios": "^1.8.2",

apps/namadillo/src/App/Ibc/OsmosisSwap.tsx

Lines changed: 107 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import { AccountType, BparamsMsgValue } from "@namada/types";
22
import { calcAmountWithSlippage } from "@osmonauts/math";
33
import { defaultAccountAtom } from "atoms/accounts";
4-
import { SwapResponse } from "atoms/swaps";
4+
import {
5+
namadaShieldedAssetsAtom,
6+
namadaTransparentAssetsAtom,
7+
} from "atoms/balance";
8+
import {
9+
osmosisBaseAssetMapAtom,
10+
osmosisSymbolAssetMapAtom,
11+
} from "atoms/chain";
12+
import { SwapResponse, SwapResponseError, SwapResponseOk } from "atoms/swaps";
513
import { createOsmosisSwapTxAtom } from "atoms/transfer/atoms";
614
import BigNumber from "bignumber.js";
715
import invariant from "invariant";
@@ -11,23 +19,34 @@ import { useEffect, useState } from "react";
1119
import { getSdkInstance } from "utils/sdk";
1220

1321
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14-
async function fetchPrices(coinGeckoIds: string[]): Promise<any> {
22+
async function _fetchPrices(coinGeckoIds: string[]): Promise<any> {
1523
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coinGeckoIds.join()}&vs_currencies=usd`;
1624
return await fetch(url).then((res) => res.json());
1725
}
1826

27+
const SUPPORTED_TOKENS_SYMBOLS = ["OSMO", "ATOM", "TIA"] as const;
28+
const SLIPPAGE = 0.1;
29+
1930
export const OsmosisSwap: React.FC = () => {
31+
const osmosisSymbolAssetsMap = useAtomValue(osmosisSymbolAssetMapAtom);
32+
const osmosisBaseAssetsMap = useAtomValue(osmosisBaseAssetMapAtom);
33+
const supportedAssets = SUPPORTED_TOKENS_SYMBOLS.map(
34+
(s) => osmosisSymbolAssetsMap[s]
35+
);
2036
const { mutateAsync: performOsmosisSwap } = useAtomValue(
2137
createOsmosisSwapTxAtom
2238
);
23-
24-
const [from, setFrom] = useState<string | null>(
25-
"ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2"
39+
const [shielded, _setShielded] = useState<boolean>(true);
40+
const { data: availableAssets, isLoading: _isLoadingAssets } = useAtomValue(
41+
shielded ? namadaShieldedAssetsAtom : namadaTransparentAssetsAtom
2642
);
27-
const [to, setTo] = useState<string>("uosmo");
28-
const [amount, setAmount] = useState<string>("10000");
43+
44+
// const www = Object.values(availableAssets || {})?.[0]?.asset.base || null;
45+
const [from, setFrom] = useState<string>("");
46+
const [to, setTo] = useState<string>("");
47+
const [amount, setAmount] = useState<string>("");
2948
const [quote, setQuote] = useState<
30-
(SwapResponse & { minAmount: string }) | null
49+
(SwapResponseOk & { minAmount: string }) | null
3150
>(null);
3251

3352
useEffect(() => {
@@ -42,11 +61,20 @@ export const OsmosisSwap: React.FC = () => {
4261
);
4362
const response: SwapResponse = await quote.json();
4463

45-
const minAmount = calcAmountWithSlippage(response.amount_out, 0.1);
46-
setQuote({ ...response, minAmount });
64+
if (!(response as SwapResponseError).message) {
65+
const minAmount = calcAmountWithSlippage(
66+
(response as SwapResponseOk).amount_out,
67+
SLIPPAGE
68+
);
69+
setQuote({ ...(response as SwapResponseOk), minAmount });
70+
} else {
71+
setQuote(null);
72+
}
4773
};
48-
call();
49-
}, []);
74+
if (from && to && amount) {
75+
call();
76+
}
77+
}, [from, to, amount]);
5078

5179
const account = useAtomValue(defaultAccountAtom);
5280

@@ -165,27 +193,79 @@ export const OsmosisSwap: React.FC = () => {
165193

166194
return (
167195
<div className="text-white">
168-
<div>From: {from}</div>
169-
<div>To: {to}</div>
170-
<div>Amount: {amount}</div>
196+
<div>From:</div>
197+
<select className="text-black" onChange={(e) => setFrom(e.target.value)}>
198+
<option value=""></option>
199+
{Object.values(availableAssets || {}).map((al) => (
200+
<option key={al.asset.base} value={al.asset.base}>
201+
{al.asset.symbol}
202+
</option>
203+
))}
204+
</select>
205+
<div>To:</div>
206+
<select className="text-black" onChange={(e) => setTo(e.target.value)}>
207+
<option value=""></option>
208+
{supportedAssets.map((asset) => (
209+
<option key={asset.base} value={asset.base}>
210+
{asset.symbol}
211+
</option>
212+
))}
213+
</select>
214+
<div>Amount in base denom:</div>
215+
<input
216+
className="text-black"
217+
type="text"
218+
onChange={(e) => setAmount(e.target.value)}
219+
/>
171220
<p>---</p>
172221
<div> Receive: </div>
173222
{quote && (
174223
<div>
175224
<div>
176-
Amount in: {quote.amount_in.denom}: {quote.amount_in.amount}
225+
Amount in: {quote.amount_in.amount}
226+
{osmosisBaseAssetsMap[from].denom_units[0].aliases?.[0] || from}
227+
</div>
228+
<div>
229+
Amount out: {quote.amount_out}
230+
{osmosisBaseAssetsMap[to].denom_units[0].aliases?.[0] || to}
231+
</div>
232+
<div>
233+
Min amount out: {quote.minAmount}
234+
{osmosisBaseAssetsMap[to].denom_units[0].aliases?.[0] || to}
235+
</div>
236+
<div>Slippage: {SLIPPAGE}%</div>
237+
<div>Routes: </div>
238+
<ul className="list-disc list-inside">
239+
{quote.route.map((r, i) => (
240+
<li key={i}>
241+
Route{i + 1}
242+
<ul className="list-disc list-inside pl-4">
243+
{r.pools.map((p, i) => (
244+
<li key={i}>
245+
{p.id}: {osmosisBaseAssetsMap[p.token_out_denom].symbol}
246+
(Fee: {BigNumber(p.taker_fee).toString()})
247+
</li>
248+
))}
249+
</ul>
250+
</li>
251+
))}
252+
</ul>
253+
<div>Effective fee: {BigNumber(quote.effective_fee).toString()}</div>
254+
<div>
255+
Price: 1 {osmosisBaseAssetsMap[from].symbol}{" "}
256+
{BigNumber(quote.in_base_out_quote_spot_price)
257+
.times(
258+
BigNumber(1)
259+
.minus(BigNumber(quote.effective_fee))
260+
.plus(BigNumber(quote.price_impact))
261+
)
262+
.dp(3)
263+
.toString()}{" "}
264+
{osmosisBaseAssetsMap[to].symbol}
265+
</div>
266+
<div>
267+
Price impact: {BigNumber(quote.price_impact).dp(3).toString()}
177268
</div>
178-
<div>Amount out: {quote.amount_out}</div>
179-
<div>Route: </div>
180-
{quote.route[0].pools.map((p, i) => (
181-
<div key={i}>
182-
{p.id}: {p.token_out_denom}(Fee: {p.taker_fee})
183-
</div>
184-
))}
185-
<div>Effective fee: {quote.effective_fee}</div>
186-
<div>Spot price: {quote.in_base_out_quote_spot_price}</div>
187-
<div>Price impact: {quote.price_impact}</div>
188-
<div> Min amount out: {quote.minAmount}</div>
189269
</div>
190270
)}
191271
</div>

apps/namadillo/src/atoms/chain/atoms.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,26 @@ export const chainAssetsMapAtom = atom<Record<Address, Asset | undefined>>(
103103
}
104104
);
105105

106+
export const osmosisSymbolAssetMapAtom = atom<Record<string, Asset>>(() => {
107+
const assets = osmosis.assets.assets;
108+
const symbolAssetMap: Record<Address, Asset> = {};
109+
assets.forEach((asset: Asset) => {
110+
symbolAssetMap[asset.symbol] = asset;
111+
});
112+
113+
return symbolAssetMap;
114+
});
115+
116+
export const osmosisBaseAssetMapAtom = atom<Record<string, Asset>>(() => {
117+
const assets = osmosis.assets.assets;
118+
const baseAssetMap: Record<Address, Asset> = {};
119+
assets.forEach((asset: Asset) => {
120+
baseAssetMap[asset.base] = asset;
121+
});
122+
123+
return baseAssetMap;
124+
});
125+
106126
// Prefer calling settings@rpcUrlAtom instead, because default rpc url might be
107127
// overrided by the user
108128
export const indexerRpcUrlAtom = atomWithQuery<string>((get) => {
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export * from "./OsmosisSqsApi";
21
export * from "./types";

apps/namadillo/src/atoms/swaps/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export type SwapResponse = {
1+
export type SwapResponseOk = {
22
amount_in: {
33
denom: string;
44
amount: string;
@@ -20,3 +20,8 @@ export type SwapResponse = {
2020
price_impact: string;
2121
in_base_out_quote_spot_price: string;
2222
};
23+
export type SwapResponseError = {
24+
message: string;
25+
};
26+
27+
export type SwapResponse = SwapResponseOk | SwapResponseError;

apps/namadillo/vite.config.mjs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import react from "@vitejs/plugin-react";
33
import { defineConfig } from "vite";
44
import checker from "vite-plugin-checker";
5+
import { nodePolyfills } from "vite-plugin-node-polyfills";
56
import { VitePWA } from "vite-plugin-pwa";
67
import tsconfigPaths from "vite-tsconfig-paths";
78

@@ -30,6 +31,9 @@ export default defineConfig(() => {
3031
}),
3132
react(),
3233
tsconfigPaths(),
34+
nodePolyfills({
35+
protocolImports: true,
36+
}),
3337
checker({
3438
typescript: true,
3539
eslint: { lintCommand: 'eslint "./src/**/*.{ts,tsx}"' },
@@ -40,12 +44,6 @@ export default defineConfig(() => {
4044
plugins: () => [tsconfigPaths()],
4145
format: "es",
4246
},
43-
resolve: {
44-
alias: {
45-
buffer: "buffer",
46-
process: "process/browser",
47-
},
48-
},
4947
optimizeDeps: {
5048
esbuildOptions: {
5149
// Node.js global to browser globalThis

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"docker-build-namadillo": "docker build -f docker/namadillo/Dockerfile ."
2323
},
2424
"devDependencies": {
25+
"@chain-registry/types": "^0.45.80",
2526
"@typescript-eslint/eslint-plugin": "^8.4.0",
2627
"@typescript-eslint/parser": "^8.4.0",
2728
"eslint": "^8.57.0",

0 commit comments

Comments
 (0)