diff --git a/src/components/AssetSelect.tsx b/src/components/AssetSelect.tsx
index 83bbc6a2..75f387cf 100644
--- a/src/components/AssetSelect.tsx
+++ b/src/components/AssetSelect.tsx
@@ -6,6 +6,7 @@ import {
} from "lucide-react";
import { useEffect, useState } from "react";
+import { Token } from "../hooks/types";
import AssetList from "./AssetList";
import Modal from "./Modal";
import TokenAvatar from "./TokenAvatar";
@@ -15,6 +16,11 @@ export default function AssetSelect({
assets,
onSelect,
className = "",
+}: {
+ selectedAsset: Token | null;
+ assets: Token[];
+ onSelect: (asset: Token | null) => void;
+ className?: string;
}) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
diff --git a/src/components/TokenAvatar.tsx b/src/components/TokenAvatar.tsx
index 7ea2ce44..e61beddc 100644
--- a/src/components/TokenAvatar.tsx
+++ b/src/components/TokenAvatar.tsx
@@ -7,8 +7,15 @@ import {
TOKEN_ASSETS_CDN,
TOKEN_ICON,
} from "../constants";
+import { Address } from "../hooks/types";
-export default function TokenAvatar({ address, className = null }) {
+export default function TokenAvatar({
+ address,
+ className = null,
+}: {
+ address: Address;
+ className?: string;
+}) {
if (!address) {
return <>>;
}
diff --git a/src/constants.ts b/src/constants.ts
index b5a3dbb0..94a5ccdb 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,11 +1,13 @@
import { optimism } from "viem/chains";
-export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
+import { Address } from "./hooks/types";
+
+export const ZERO_ADDRESS: Address =
+ "0x0000000000000000000000000000000000000000";
export const TOKEN_ICON = "/svg/coin.svg";
export const RPC_URI = import.meta.env.VITE_RPC_URI;
-export const TOKEN_ADDRESSES = String(
- import.meta.env.VITE_TOKEN_ADDRESSES,
-).split(",");
+export const TOKEN_ADDRESSES: Address[] =
+ import.meta.env.VITE_TOKEN_ADDRESSES.split(",");
export const TOKEN_ASSETS_CDN = String(
import.meta.env.VITE_TOKEN_ASSETS_CDN,
).split(",");
@@ -13,9 +15,17 @@ export const DEFAULT_CHAIN = optimism;
export const NATIVE_TOKEN_LOGO = import.meta.env.VITE_NATIVE_TOKEN_LOGO;
export const NATIVE_TOKEN = {
...DEFAULT_CHAIN.nativeCurrency,
- wrappedAddress: import.meta.env.VITE_WRAPPED_NATIVE_TOKEN.toLowerCase(),
- address: DEFAULT_CHAIN.nativeCurrency.symbol.toLowerCase(),
+ wrappedAddress:
+ import.meta.env.VITE_WRAPPED_NATIVE_TOKEN.toLowerCase() as Address,
+ /**
+ * TODO: This is an exception for the native token where "address" is "ETH"
+ * - Change this later so it's type-safe
+ * Discussion: https://github.com/velodrome-finance/app/pull/347#discussion_r1380073009
+ */
+
+ address: DEFAULT_CHAIN.nativeCurrency.symbol.toLowerCase() as Address,
};
+
export const WALLETCONNECT_PROJECT_ID = import.meta.env
.VITE_WALLETCONNECT_PROJECT_ID;
@@ -23,3 +33,7 @@ export const WALLETCONNECT_PROJECT_ID = import.meta.env
export const FEATURE_FLAGS = String(
import.meta.env.VITE_FEATURE_FLAGS
).split(",");
+
+export const CURRENCY_MAXIMUM_FRACTION_DIGITS = parseInt(
+ import.meta.env.VITE_CURRENCY_MAXIMUM_FRACTION_DIGITS || "5",
+);
diff --git a/src/hooks/token.ts b/src/hooks/token.ts
index 64310d1c..3101d06d 100644
--- a/src/hooks/token.ts
+++ b/src/hooks/token.ts
@@ -2,16 +2,19 @@ import { useQuery } from "@tanstack/react-query";
import { getBalance } from "@wagmi/core";
import { TOKEN_ADDRESSES } from "../constants";
-import rpc from "../rpc";
+import config from "../rpc";
+import { Address, Token } from "./types";
-async function fetchTokens(accountAddress) {
- const tokens = TOKEN_ADDRESSES.map(async (tokenAddress) => {
- const token = await getBalance(rpc, {
- address: accountAddress,
- token: tokenAddress as `0x${string}`,
- });
- return { ...token, address: tokenAddress };
- });
+async function fetchTokens(accountAddress: Address): Promise
{
+ const tokens = TOKEN_ADDRESSES.map(
+ async (tokenAddress: Address): Promise => {
+ const token = await getBalance(config, {
+ address: accountAddress,
+ token: tokenAddress,
+ });
+ return { ...token, address: tokenAddress };
+ },
+ );
return Promise.all(tokens);
}
diff --git a/src/hooks/types.ts b/src/hooks/types.ts
new file mode 100644
index 00000000..fb405f1b
--- /dev/null
+++ b/src/hooks/types.ts
@@ -0,0 +1,11 @@
+import { Address } from "viem";
+
+export type { Address };
+
+export type Token = {
+ address: Address;
+ decimals: number;
+ formatted: string;
+ symbol: string;
+ value: bigint;
+};
diff --git a/src/pages/Create/components/Creator.tsx b/src/pages/Create/components/Creator.tsx
index da8b69c3..b46f5663 100644
--- a/src/pages/Create/components/Creator.tsx
+++ b/src/pages/Create/components/Creator.tsx
@@ -6,12 +6,12 @@ import {
ToggleSwitch,
} from "flowbite-react";
import { useEffect, useState } from "react";
-import { parseUnits } from "viem";
-import { isAddress } from "viem";
+import { isAddress, parseUnits } from "viem";
import { useAccount } from "wagmi";
import AssetInput from "../../../components/AssetInput";
import { useTokens } from "../../../hooks/token";
+import { Token } from "../../../hooks/types";
import Checklist from "./Checklist";
import Graph from "./Graph";
import Preview from "./Preview";
@@ -31,7 +31,7 @@ export default function Creator() {
const { address: accountAddress } = useAccount();
const { data: tokens } = useTokens(accountAddress);
- const [token, setToken] = useState();
+ const [token, setToken] = useState(null);
// Set default token if non selected
useEffect(() => {
diff --git a/src/pages/Dashboard/components/Govnft.tsx b/src/pages/Dashboard/components/Govnft.tsx
index 69527bb3..1535205f 100644
--- a/src/pages/Dashboard/components/Govnft.tsx
+++ b/src/pages/Dashboard/components/Govnft.tsx
@@ -51,7 +51,7 @@ export default function Govnft({ withdraw }) {
@@ -61,13 +61,15 @@ export default function Govnft({ withdraw }) {
Vesting
-
+
Ends in 2 years
@@ -80,7 +82,7 @@ export default function Govnft({ withdraw }) {
diff --git a/src/pages/Delegate/components/DelegateNft.tsx b/src/pages/Delegate/components/DelegateNft.tsx
index d9223688..9247606b 100644
--- a/src/pages/Delegate/components/DelegateNft.tsx
+++ b/src/pages/Delegate/components/DelegateNft.tsx
@@ -44,7 +44,7 @@ export default function DelegateNft() {
@@ -62,7 +62,7 @@ export default function DelegateNft() {
diff --git a/src/pages/Transfer/components/TransferNft.tsx b/src/pages/Transfer/components/TransferNft.tsx
index ce5ace51..95bcf650 100644
--- a/src/pages/Transfer/components/TransferNft.tsx
+++ b/src/pages/Transfer/components/TransferNft.tsx
@@ -44,7 +44,7 @@ export default function TransferNft() {
@@ -62,7 +62,7 @@ export default function TransferNft() {
diff --git a/yarn.lock b/yarn.lock
index acdb495e..88f440ba 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1498,6 +1498,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.5.tgz#3af577099a99c61479149b716183e70b5239324a"
integrity sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==
+"@types/node@18.15.13":
+ version "18.15.13"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
+ integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
+
"@types/parse-json@^4.0.0":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239"
@@ -1999,6 +2004,11 @@ acorn@^8.8.2, acorn@^8.9.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
+aes-js@4.0.0-beta.5:
+ version "4.0.0-beta.5"
+ resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873"
+ integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==
+
ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -3216,6 +3226,19 @@ ethereum-cryptography@^2.0.0:
"@scure/bip32" "1.3.1"
"@scure/bip39" "1.2.1"
+ethers@^6.10.0:
+ version "6.10.0"
+ resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.10.0.tgz#20f3c63c60d59a993f8090ad423d8a3854b3b1cd"
+ integrity sha512-nMNwYHzs6V1FR3Y4cdfxSQmNgZsRj1RiTU25JwvnJLmyzw9z3SKxNc2XKDuiXXo/v9ds5Mp9m6HBabgYQQ26tA==
+ dependencies:
+ "@adraffy/ens-normalize" "1.10.0"
+ "@noble/curves" "1.2.0"
+ "@noble/hashes" "1.3.2"
+ "@types/node" "18.15.13"
+ aes-js "4.0.0-beta.5"
+ tslib "2.4.0"
+ ws "8.5.0"
+
eventemitter2@^6.4.5, eventemitter2@^6.4.7:
version "6.4.9"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125"
@@ -6381,6 +6404,11 @@ tslib@1.14.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+tslib@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
tslib@^2.0.0, tslib@^2.3.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
@@ -6901,6 +6929,11 @@ ws@8.13.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
+ws@8.5.0:
+ version "8.5.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
+ integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
+
ws@^7.5.1:
version "7.5.9"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"