-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
Copy pathtoken.svelte
94 lines (91 loc) · 3.65 KB
/
token.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<script lang="ts">
import type { Chain } from "$lib/types"
import TokenQualityLevel from "$lib/components/token-quality-level.svelte"
import Truncate from "./truncate.svelte"
import ArrowLeftIcon from "virtual:icons/lucide/arrow-left"
import { toDisplayName } from "$lib/utilities/chains.ts"
import { formatUnits, parseUnits } from "viem"
import { tokenInfoQuery } from "$lib/queries/tokens"
import LoadingDots from "./loading-dots.svelte"
import { highlightItem } from "$lib/stores/highlight"
import { cn } from "$lib/utilities/shadcn"
export let chains: Array<Chain>
export let chainId: string
export let denom: string
export let amount: string | number | bigint | null = null
export let userAmount: string | null = null
export let expanded = false
$: chain = chains.find(c => c.chain_id === chainId) ?? null
$: tokenInfo = tokenInfoQuery(chainId, (denom ?? "").toLowerCase(), chains)
</script>
{#if $tokenInfo.data}
{@const token = $tokenInfo.data}
<!-- svelte-ignore a11y-interactive-supports-focus -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="flex flex-col gap-1"
on:mouseleave={() => highlightItem.set(null)}
on:mouseenter={() => {
highlightItem.set(denom ? { kind: "token", denom} : null)
}}>
<div class="flex gap-1 items-center">
<TokenQualityLevel level={token.graphql != null ? "GRAPHQL" : token.onchain != null ? "ONCHAIN" : "NONE"}/>
{#if amount !== null}
{formatUnits(BigInt(amount), token.combined.decimals)}
{/if}
{#if userAmount !== null}
{userAmount}
{/if}
<span class={cn("inline-flex gap-1", $highlightItem?.kind === "token" && $highlightItem.denom === denom ? "bg-union-accent-300 dark:bg-union-accent-950" : "")}><b><Truncate
value={token.combined.symbol} type="symbol"/></b>
<div class="text-muted-foreground text-xs flex gap-1 items-center">
{toDisplayName(chainId, chains)}
{#each token.combined.wrapping as wrapping}
<ArrowLeftIcon/>{toDisplayName(
wrapping.unwrapped_chain.chain_id,
chains,
)}
{/each}
</div></span>
</div>
{#if expanded}
<div class="text-xs flex flex-col gap gap-4 text-muted-foreground">
<section>
<h2 class="text-foreground">Denom</h2>
<div>
<Truncate value={denom} type="address"/>
</div>
</section>
{#if token.graphql}
<section>
<h2 class="text-foreground">GrapqhQL</h2>
<div>Name: {token.graphql.primaryRepresentation.name}</div>
<div>Symbol: {token.graphql.primaryRepresentation.symbol}</div>
<div>Decimals: {token.graphql.primaryRepresentation.decimals}</div>
{#if token.graphql.primaryRepresentation.sources}
<div>Sources:
{#each token.graphql.primaryRepresentation.sources as source}<a class="underline"
href={source.source.source_uri}> {source.source.name}</a>{/each}
</div>
{/if}
</section>
{/if}
{#if token.onchain}
<section>
<h2 class="text-foreground">Onchain</h2>
<div>Name: {token.onchain.name}</div>
<div>Symbol: {token.onchain.symbol}</div>
<div>Decimals: {token.onchain.decimals}</div>
</section>
{/if}
</div>
{/if}
</div>
{:else}
<div class="flex max-h-auto overflow-hidden text-muted-foreground">
<div class="relative w-12 h-4">
<LoadingDots class="absolute -top-4 size-12 h-12 w-12"/>
</div>
<Truncate value={denom} type="address"/>
</div>
{/if}