Skip to content

Commit 8c7e7da

Browse files
authored
Merge pull request #1 from DefichainCommunity/deploy
merge deploy back into main
2 parents a7e0b77 + c6d1822 commit 8c7e7da

6 files changed

Lines changed: 235 additions & 112 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ jobs:
2424
- name: Install Dioxus CLI
2525
run: cargo install dioxus-cli --locked
2626

27-
- name: Build Dioxus Web App
28-
run: dx build --release
27+
- name: Build Dioxus Web App (in frontend/)
28+
working-directory: frontend
29+
run: dx build --platform web
2930

30-
- name: Upload artifact
31+
- name: Upload GitHub Pages artifact
3132
uses: actions/upload-pages-artifact@v3
3233
with:
33-
path: target/dioxus/release/web
34+
path: frontend/target/dx/dioxus_meta_app/debug/web/public
3435

3536
deploy:
3637
runs-on: ubuntu-latest

frontend/Cargo.toml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7-
dioxus = { version = "0.7", features = ["macro","web"] }
8-
dioxus-web = "0.7"
9-
wasm-bindgen = "0.2"
10-
wasm-bindgen-futures = "0.4"
11-
js-sys = "0.3"
12-
web-sys = { version = "0.3", features = ["Window", "console", "HtmlInputElement"] }
7+
dioxus = { version = "0.7.1", features = ["asset", "devtools", "document", "hooks", "html", "launch", "macro", "signals"], default-features = false }
8+
wasm-bindgen = { version = "0.2", default-features = false }
9+
wasm-bindgen-futures = { version = "0.4", default-features = false }
10+
js-sys = { version = "0.3", default-features = false }
11+
web-sys = { version = "0.3", default-features = false }
1312
serde-wasm-bindgen = "0.6"
14-
serde = { version = "1.0", features = ["derive"] }
13+
serde = { version = "1.0", default-features = false }
1514
serde_json = "1.0"
1615
log = "0.4"
1716
console_log = "1.0"
1817
alloy = {version = "1.1", default-features = false }
1918

2019
[profile]
2120

21+
# [profile.release]
22+
# strip = false
23+
2224
[profile.wasm-dev]
2325
inherits = "dev"
2426
opt-level = 1

frontend/Dioxus.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[application]
2+
name = "cAssets_dToken_Wrapper"
3+
default_platform = "web"
4+
5+
[web.app]
6+
title = "cAssets_dToken_Wrapper"
7+
base_path = "cAssets_dToken_wrapper"
8+
## keeps CSP happy
9+
csp_hash = true
10+
## avoids SWC minifier errors
11+
minify_js = false
12+
13+
[web.wasm]
14+
## ensures WASM + JS are together
15+
mode = "bundled"

frontend/src/app.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloy::primitives::{utils::{format_units, parse_units},U256};
22
use dioxus::prelude::*;
33
use wasm_bindgen_futures::spawn_local;
44
use serde_wasm_bindgen::from_value;
5-
use crate::metamask::{TokenWrapperInfo, connect_metamask, get_token_balance, fetch_wrappers, wrap_tokens, unwrap_tokens};
5+
use crate::metamask::{TokenWrapperInfo, connect_metamask, get_token_balance, get_all_wrappers, wrap_tokens, unwrap_tokens};
66

77
#[derive(Clone, Debug)]
88
struct TokenInfo {
@@ -84,23 +84,27 @@ pub fn App() -> Element {
8484
let mut to_selected = to_selected;
8585

8686
async move {
87-
let addr = connect_metamask().await;
88-
address.set(addr.as_string().unwrap_or_default());
89-
let addr = address.read().clone();
90-
match fetch_wrappers(factory_address).await {
91-
Ok(list) => {
92-
if let Some(first) = list.first() {
93-
let (from,to) = update_pair(&first.d_token_symbol, &list);
94-
to_selected.set(to);
95-
from_selected.set(from);
96-
if let Ok(bal) = from_value::<String>(get_token_balance(&addr, &first.d_token_address).await) {
97-
log::debug!("GetTokenBalance of address {} for token address {} :{:?}",addr, first.d_token_address, bal);
98-
balance.set(bal);
99-
}
87+
match connect_metamask().await{
88+
Ok(addr) => {
89+
address.set(addr);
90+
let addr = address.read().clone();
91+
match get_all_wrappers(factory_address).await {
92+
Ok(list) => {
93+
if let Some(first) = list.first() {
94+
let (from,to) = update_pair(&first.d_token_symbol, &list);
95+
to_selected.set(to);
96+
from_selected.set(from);
97+
if let Ok(bal) = get_token_balance(&addr, &first.d_token_address).await {
98+
log::debug!("GetTokenBalance of address {} for token address {} :{:?}",addr, first.d_token_address, bal);
99+
balance.set(bal);
100+
}
101+
}
102+
wrappers.set(list);
103+
},
104+
Err(e) => log::error!("Error fetching wrappers: {:?}", e)
100105
}
101-
wrappers.set(list);
102106
},
103-
Err(e) => log::error!("Error fetching wrappers: {:?}", e)
107+
Err(e) => log::error!("Error connecting metamask: {:?}", e)
104108
}
105109
}
106110
});
@@ -114,7 +118,7 @@ pub fn App() -> Element {
114118

115119
spawn_local(async move {
116120
if let Some(from_sel) = from_sel
117-
&& let Ok(bal) = from_value::<String>(get_token_balance(&addr, &from_sel.address).await) {
121+
&& let Ok(bal) = get_token_balance(&addr, &from_sel.address).await {
118122
log::debug!("GetTokenBalance of address {} for token address {} :{:?}",addr, from_sel.address, bal);
119123
balance.set(bal);
120124
}
@@ -285,8 +289,8 @@ pub fn App() -> Element {
285289
} else {
286290
unwrap_tokens(router_address, &from_selected.address.to_string(), &amount.read(), &to_selected.address.to_string()).await
287291
};
288-
tx_status.set(format!("{:?}", serde_wasm_bindgen::from_value::<String>(res)));
289-
if let Ok(bal) = from_value::<String>(get_token_balance(&address(), &from_selected.address.to_string()).await) {
292+
tx_status.set(format!("{:?}", res));
293+
if let Ok(bal) = get_token_balance(&address(), &from_selected.address.to_string()).await {
290294
log::debug!("TokenBalance {:?}",bal);
291295
balance.set(bal);
292296
}

frontend/src/metamask.js

Lines changed: 113 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,92 +5,123 @@ let provider;
55
let signer;
66

77
// METAMASK
8-
export async function connect_metamask() {
9-
if (!window.ethereum) throw new Error("MetaMask not installed");
10-
await window.ethereum.request({ method: 'eth_requestAccounts' });
11-
provider = new ethers.BrowserProvider(window.ethereum);
12-
signer = await provider.getSigner();
13-
return await signer.getAddress();
8+
export async function js_connect_metamask() {
9+
try {
10+
if (!window.ethereum) throw new Error("MetaMask not installed");
11+
await window.ethereum.request({ method: 'eth_requestAccounts' });
12+
provider = new ethers.BrowserProvider(window.ethereum);
13+
signer = await provider.getSigner();
14+
const addr = await signer.getAddress();
15+
return {
16+
ok: true,
17+
value: JSON.stringify(addr)
18+
};
19+
}catch (err) {
20+
console.error(err);
21+
return {
22+
ok: false,
23+
value: err.reason || err.message || "Unknown error"
24+
};
25+
}
1426
}
1527

1628
// ERC20
17-
export async function get_token_balance(user, token) {
29+
export async function js_get_token_balance(user, token) {
1830
const abi = ["function balanceOf(address) view returns (uint256)",
1931
"function decimals() view returns (uint8)"];
2032
try {
2133
const erc20 = new ethers.Contract(token, abi, provider);
2234
const [bal, decimals] = await Promise.all([erc20.balanceOf(user), erc20.decimals()]);
23-
return ethers.formatUnits(bal, decimals);
35+
return {
36+
ok: true,
37+
value: JSON.stringify(ethers.formatUnits(bal, decimals))
38+
};
2439
} catch (err) {
25-
// console.error("ERC20 get balance error: ",err);
26-
return `Error: ${err.reason || err.message}`;
40+
console.error(err);
41+
return {
42+
ok: false,
43+
value: err.reason || err.message || "Unknown error"
44+
};
2745
}
2846
}
2947

3048
// FACTORY
31-
export async function get_all_wrappers(factoryAddress) {
49+
export async function js_get_all_wrappers(factoryAddress) {
3250
// Factory ABI
3351
console.log("GetAllWrappers called");
34-
const factoryAbi = ["function getAllWraps() view returns (address[])"];
35-
const factory = new ethers.Contract(factoryAddress, factoryAbi, provider);
36-
// Wrapper ABI
37-
const wrapperAbi = ["function info() view returns (tuple(address dTokenAddress, address cAssetAddress, uint8 dTokenDecimals, uint8 cAssetDecimals, uint256 dTokenInFeeBps, uint256 dTokenOutFeeBps, address dTokenTreasury, address cAssetTreasury))"];
38-
const wrapAddresses = await factory.getAllWraps();
39-
// console.log("WrapAddresses:", wrapAddresses);
40-
const tokenList = [];
41-
42-
for (const wrapperAddr of wrapAddresses) {
43-
console.log("WrapperAddress:", wrapperAddr);
44-
try {
45-
const wrapper = new ethers.Contract(wrapperAddr, wrapperAbi, provider);
46-
const info = await wrapper.info();
47-
48-
const dTokenContract = new ethers.Contract(
49-
info.dTokenAddress,
50-
["function symbol() view returns (string)", "function decimals() view returns (uint8)"],
51-
provider
52-
);
53-
54-
const [dtoken_symbol, dtoken_decimals] = await Promise.all([
55-
dTokenContract.symbol(),
56-
dTokenContract.decimals()
57-
]);
58-
59-
const cAssetContract = new ethers.Contract(
60-
info.cAssetAddress,
61-
["function symbol() view returns (string)", "function decimals() view returns (uint8)"],
62-
provider
63-
);
64-
65-
const [casset_symbol, casset_decimals] = await Promise.all([
66-
cAssetContract.symbol(),
67-
cAssetContract.decimals()
68-
]);
69-
70-
71-
tokenList.push({
72-
wrapper: wrapperAddr,
73-
dTokenSymbol: dtoken_symbol,
74-
dTokenAddress: info.dTokenAddress,
75-
dTokenDecimals: info.dTokenDecimals,
76-
cAssetSymbol: casset_symbol,
77-
cAssetAddress: info.cAssetAddress,
78-
cAssetDecimals: info.cAssetDecimals,
79-
fees: {
80-
inBps: info.dTokenInFeeBps,
81-
outBps: info.dTokenOutFeeBps
82-
}
83-
});
84-
} catch (err) {
85-
console.warn("Skipping wrapper", wrapperAddr, err);
52+
try {
53+
const factoryAbi = ["function getAllWraps() view returns (address[])"];
54+
const factory = new ethers.Contract(factoryAddress, factoryAbi, provider);
55+
// Wrapper ABI
56+
const wrapperAbi = ["function info() view returns (tuple(address dTokenAddress, address cAssetAddress, uint8 dTokenDecimals, uint8 cAssetDecimals, uint256 dTokenInFeeBps, uint256 dTokenOutFeeBps))"];
57+
const wrapAddresses = await factory.getAllWraps();
58+
// console.log("WrapAddresses:", wrapAddresses);
59+
const tokenList = [];
60+
61+
for (const wrapperAddr of wrapAddresses) {
62+
console.log("WrapperAddress:", wrapperAddr);
63+
try {
64+
const wrapper = new ethers.Contract(wrapperAddr, wrapperAbi, provider);
65+
const info = await wrapper.info();
66+
67+
const dTokenContract = new ethers.Contract(
68+
info.dTokenAddress,
69+
["function symbol() view returns (string)", "function decimals() view returns (uint8)"],
70+
provider
71+
);
72+
73+
const [dtoken_symbol, dtoken_decimals] = await Promise.all([
74+
dTokenContract.symbol(),
75+
dTokenContract.decimals()
76+
]);
77+
78+
const cAssetContract = new ethers.Contract(
79+
info.cAssetAddress,
80+
["function symbol() view returns (string)", "function decimals() view returns (uint8)"],
81+
provider
82+
);
83+
84+
const [casset_symbol, casset_decimals] = await Promise.all([
85+
cAssetContract.symbol(),
86+
cAssetContract.decimals()
87+
]);
88+
89+
90+
tokenList.push({
91+
wrapper: wrapperAddr,
92+
dTokenSymbol: dtoken_symbol,
93+
dTokenAddress: info.dTokenAddress,
94+
dTokenDecimals: info.dTokenDecimals,
95+
cAssetSymbol: casset_symbol,
96+
cAssetAddress: info.cAssetAddress,
97+
cAssetDecimals: info.cAssetDecimals,
98+
fees: {
99+
inBps: info.dTokenInFeeBps,
100+
outBps: info.dTokenOutFeeBps
101+
}
102+
});
103+
} catch (err) {
104+
console.warn("Skipping wrapper", wrapperAddr, err);
105+
}
86106
}
107+
return {
108+
ok: true,
109+
value: JSON.stringify(tokenList , (key, value) =>
110+
typeof value === "bigint" ? value.toString() : value
111+
)
112+
};
113+
} catch (err) {
114+
return {
115+
ok: false,
116+
value: err.reason || err.message || "Unknown error"
117+
};
118+
87119
}
88-
return tokenList; // Array of objects with wrapper + cAsset info
89120
}
90121

91122

92123
// ROUTER
93-
export async function wrap_tokens(contractAddress, dToken, amount, cAsset) {
124+
export async function js_wrap_tokens(contractAddress, dToken, amount, cAsset) {
94125
try {
95126
const abi = ["function wrap(address dTokent, uint256 amount, address cAsset) external"];
96127
const approveAbi = ["function approve(address spender, uint256 amount) external returns (bool)",
@@ -106,15 +137,21 @@ export async function wrap_tokens(contractAddress, dToken, amount, cAsset) {
106137
const connected = contract.connect(signer);
107138
const tx = await connected.wrap(dToken, amount_u256, cAsset);
108139
const receipt = await tx.wait();
109-
return "Wrap successful: ", receipt.hash;
140+
return {
141+
ok: true,
142+
value: JSON.stringify(`${receipt.hash}`)
143+
};
110144
} catch (err) {
111145
console.error(err);
112-
return `Error: ${err.reason || err.message}`;
146+
return {
147+
ok: false,
148+
value: err.reason || err.message || "Unknown error"
149+
};
113150
}
114151

115152
}
116153

117-
export async function unwrap_tokens(contractAddress, cAsset, amount, dToken) {
154+
export async function js_unwrap_tokens(contractAddress, cAsset, amount, dToken) {
118155
try {
119156
const abi = ["function unwrap(address cAsset, uint256 amount, address dToken) external"];
120157
const approveAbi = ["function approve(address spender, uint256 amount) external returns (bool)",
@@ -130,9 +167,15 @@ export async function unwrap_tokens(contractAddress, cAsset, amount, dToken) {
130167
const connected = contract.connect(signer);
131168
const tx = await connected.unwrap(cAsset, amount_u256, dToken);
132169
const receipt = await tx.wait();
133-
return "Unwrap successful: ", receipt.hash;
170+
return {
171+
ok: true,
172+
value: JSON.stringify(`${receipt.hash}`)
173+
};
134174
} catch (err) {
135175
console.error(err);
136-
return `Error: ${err.reason || err.message}`;
176+
return {
177+
ok: false,
178+
value: err.reason || err.message || "Unknown error"
179+
};
137180
}
138181
}

0 commit comments

Comments
 (0)