Skip to content

Commit f1a9ec8

Browse files
update ton sui link
1 parent ddfc523 commit f1a9ec8

File tree

3 files changed

+398
-0
lines changed

3 files changed

+398
-0
lines changed

src/UI/MainWalletLinks/Sui.svelte

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
<script lang="ts">
2+
import { useQueryClient } from "@tanstack/svelte-query";
3+
import { SuiConnector, WalletState } from "nimbus-sui-kit";
4+
import { isDarkMode, user, suiWalletInstance } from "~/store";
5+
import { nimbus } from "~/lib/network";
6+
import { Toast } from "flowbite-svelte";
7+
import { blur } from "svelte/transition";
8+
9+
import ReactAdapter from "~/components/ReactAdapter.svelte";
10+
11+
import User from "~/assets/user.png";
12+
import SUI from "~/assets/chains/sui.png";
13+
14+
export let data;
15+
export let reCallAPI = () => {};
16+
17+
const queryClient = useQueryClient();
18+
const chains = [
19+
{
20+
id: "sui:mainnet",
21+
name: "Mainnet",
22+
rpcUrl: "https://fullnode.mainnet.sui.io",
23+
},
24+
];
25+
26+
const onConnectSuccess = (msg) => {
27+
console.log("Success connect: ", msg);
28+
if ($suiWalletInstance) {
29+
($suiWalletInstance as WalletState).toggleSelect();
30+
}
31+
};
32+
33+
const onConnectError = (msg) => {
34+
console.error("Error connect", msg);
35+
if ($suiWalletInstance) {
36+
($suiWalletInstance as WalletState).toggleSelect();
37+
}
38+
};
39+
40+
const widgetConfig = {
41+
walletFn: (wallet) => {
42+
suiWalletInstance.update((n) => (n = wallet));
43+
},
44+
onConnectSuccess,
45+
onConnectError,
46+
};
47+
48+
let toastMsg = "";
49+
let isSuccessToast = false;
50+
let counter = 3;
51+
let showToast = false;
52+
53+
const trigger = () => {
54+
showToast = true;
55+
counter = 3;
56+
timeout();
57+
};
58+
59+
const timeout = () => {
60+
if (--counter > 0) return setTimeout(timeout, 1000);
61+
showToast = false;
62+
toastMsg = "";
63+
isSuccessToast = false;
64+
};
65+
66+
const handleSUIAuth = async () => {
67+
try {
68+
if ($suiWalletInstance) {
69+
($suiWalletInstance as WalletState).toggleSelect();
70+
}
71+
} catch (e) {
72+
console.log("error: ", e);
73+
}
74+
};
75+
76+
$: {
77+
if (
78+
($suiWalletInstance as WalletState) &&
79+
($suiWalletInstance as WalletState).connected
80+
) {
81+
handleGetNonce(($suiWalletInstance as WalletState)?.account?.address);
82+
}
83+
}
84+
85+
const handleGetNonce = async (address: string) => {
86+
try {
87+
const res = await nimbus.post("/users/nonce", {
88+
publicAddress: address,
89+
referrer: undefined,
90+
});
91+
if (res && res.data) {
92+
const signature = await handleSignAddressMessage(
93+
res.data.nonce as string
94+
);
95+
if (signature) {
96+
const payload = {
97+
signature: signature.signature,
98+
bytes: signature.bytes,
99+
publicAddress: address?.toLowerCase(),
100+
};
101+
handleUpdatePublicAddress(payload, address);
102+
}
103+
}
104+
} catch (e) {
105+
console.error("error: ", e);
106+
}
107+
};
108+
109+
const handleSignAddressMessage = async (nonce: string) => {
110+
const msg = await ($suiWalletInstance as WalletState).signPersonalMessage({
111+
message: new TextEncoder().encode(
112+
`I am signing my one-time nonce: ${nonce}`
113+
),
114+
});
115+
return msg;
116+
};
117+
118+
const handleGetSUIToken = async (data) => {
119+
try {
120+
const res = await nimbus.post("/auth/sui", data);
121+
if (res?.data?.result) {
122+
localStorage.setItem("sui_token", res?.data?.result);
123+
user.update(
124+
(n) =>
125+
(n = {
126+
picture: User,
127+
})
128+
);
129+
queryClient?.invalidateQueries(["users-me"]);
130+
queryClient.invalidateQueries(["list-address"]);
131+
queryClient.invalidateQueries(["list-bundle"]);
132+
queryClient.invalidateQueries(["link-socials"]);
133+
reCallAPI();
134+
toastMsg = "Link your wallet successfully!";
135+
isSuccessToast = false;
136+
trigger();
137+
}
138+
} catch (e) {
139+
console.error("error: ", e);
140+
}
141+
};
142+
143+
const handleUpdatePublicAddress = async (payload, address) => {
144+
try {
145+
let params: any = {
146+
kind: "wallet",
147+
type: null,
148+
userPublicAddress: address,
149+
id: data?.uid,
150+
info: data?.info,
151+
displayName: data?.name,
152+
};
153+
const res = await nimbus.post("/accounts/link", params);
154+
if (res && res?.error) {
155+
toastMsg =
156+
"Your wallet already Nimbus user. Please try again with another wallet!";
157+
isSuccessToast = false;
158+
trigger();
159+
return;
160+
}
161+
localStorage.removeItem("auth_token");
162+
handleGetSUIToken(payload);
163+
} catch (e) {
164+
console.log(e);
165+
}
166+
};
167+
</script>
168+
169+
<div
170+
class={`flex items-center justify-center gap-2 text-white border cursor-pointer py-3 px-6 rounded-[12px] min-w-[250px] ${
171+
$isDarkMode ? "border-white text-white" : "border-[#27326f] text-[#27326f]"
172+
}`}
173+
on:click={handleSUIAuth}
174+
>
175+
<img src={SUI} class="h-[24px] w-auto" />
176+
<div class="font-semibold text-[15px]">Login with Sui</div>
177+
</div>
178+
179+
<ReactAdapter
180+
element={SuiConnector}
181+
config={widgetConfig}
182+
autoConnect={false}
183+
{chains}
184+
integrator="svelte-example"
185+
/>
186+
187+
{#if showToast}
188+
<div class="fixed top-3 right-3 w-full" style="z-index: 2147483648;">
189+
<Toast
190+
transition={blur}
191+
params={{ amount: 10 }}
192+
position="top-right"
193+
color={isSuccessToast ? "green" : "red"}
194+
bind:open={showToast}
195+
>
196+
<svelte:fragment slot="icon">
197+
{#if isSuccessToast}
198+
<svg
199+
aria-hidden="true"
200+
class="w-5 h-5"
201+
fill="currentColor"
202+
viewBox="0 0 20 20"
203+
xmlns="http://www.w3.org/2000/svg"
204+
><path
205+
fill-rule="evenodd"
206+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
207+
clip-rule="evenodd"
208+
/></svg
209+
>
210+
<span class="sr-only">Check icon</span>
211+
{:else}
212+
<svg
213+
aria-hidden="true"
214+
class="w-5 h-5"
215+
fill="currentColor"
216+
viewBox="0 0 20 20"
217+
xmlns="http://www.w3.org/2000/svg"
218+
><path
219+
fill-rule="evenodd"
220+
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
221+
clip-rule="evenodd"
222+
/></svg
223+
>
224+
<span class="sr-only">Error icon</span>
225+
{/if}
226+
</svelte:fragment>
227+
{toastMsg}
228+
</Toast>
229+
</div>
230+
{/if}
231+
232+
<style windi:preflights:global windi:safelist:global>
233+
</style>

src/UI/Option/TabLinks.svelte

+72
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
import Solana from "../MainWalletLinks/Solana.svelte";
1313
import Evm from "../MainWalletLinks/Evm.svelte";
1414
import Ton from "../MainWalletLinks/Ton.svelte";
15+
import Sui from "../MainWalletLinks/Sui.svelte";
1516
1617
import EvmLogo from "~/assets/chains/evm.png";
1718
import SolanaLogo from "~/assets/chains/solana.png";
19+
import SUILogo from "~/assets/chains/sui.png";
20+
import TonLogo from "~/assets/chains/ton.png";
1821
1922
const MultipleLang = {
2023
title: i18n("optionsPage.links-page-title", "Link Settings"),
@@ -31,6 +34,16 @@
3134
retry: false,
3235
});
3336
37+
const handleValidateAddress = async (address: string) => {
38+
try {
39+
const response = await nimbus.get(`/v2/address/${address}/validate`);
40+
return response?.data;
41+
} catch (e) {
42+
console.error(e);
43+
return undefined;
44+
}
45+
};
46+
3447
const getLinkData = async () => {
3548
const response: any = await nimbus.get("/accounts/link");
3649
return response;
@@ -45,10 +58,27 @@
4558
$queryLinkSocial?.data?.data[0]?.uid
4659
) {
4760
dataUserSocialLogin = $queryLinkSocial?.data?.data[0] || {};
61+
handleCheckChain(dataUserSocialLogin?.publicAddress);
4862
}
4963
}
5064
}
5165
66+
const handleCheckChain = async (address) => {
67+
try {
68+
const response = await handleValidateAddress(address);
69+
chain = response?.type;
70+
} catch (e) {
71+
console.log("e");
72+
chain = "";
73+
}
74+
};
75+
76+
$: {
77+
if ($userPublicAddress && Object.keys(userPublicAddress).length === 0) {
78+
handleCheckChain($userPublicAddress);
79+
}
80+
}
81+
5282
onMount(() => {
5383
mixpanel.track("accounts_page");
5484
});
@@ -107,6 +137,24 @@
107137
class="rounded-full"
108138
/>
109139
{/if}
140+
{#if chain === "MOVE"}
141+
<img
142+
src={SUILogo}
143+
alt=""
144+
width="28"
145+
height="28"
146+
class="rounded-full"
147+
/>
148+
{/if}
149+
{#if chain === "TON"}
150+
<img
151+
src={TonLogo}
152+
alt=""
153+
width="28"
154+
height="28"
155+
class="rounded-full"
156+
/>
157+
{/if}
110158
{shorterAddress(dataUserSocialLogin?.publicAddress)}
111159
</div>
112160
{:else}
@@ -129,6 +177,12 @@
129177
dataUserSocialLogin = {};
130178
}}
131179
/>
180+
<Sui
181+
data={dataUserSocialLogin}
182+
reCallAPI={() => {
183+
dataUserSocialLogin = {};
184+
}}
185+
/>
132186
</div>
133187
{/if}
134188
</div>
@@ -188,6 +242,24 @@
188242
class="rounded-full"
189243
/>
190244
{/if}
245+
{#if chain === "MOVE"}
246+
<img
247+
src={SUILogo}
248+
alt=""
249+
width="28"
250+
height="28"
251+
class="rounded-full"
252+
/>
253+
{/if}
254+
{#if chain === "TON"}
255+
<img
256+
src={TonLogo}
257+
alt=""
258+
width="28"
259+
height="28"
260+
class="rounded-full"
261+
/>
262+
{/if}
191263
{shorterAddress($userPublicAddress)}
192264
</div>
193265
</div>

0 commit comments

Comments
 (0)