|
| 1 | +import { sortBy } from "lodash" |
| 2 | +import { fromUnit, Lucid } from "lucid-cardano" |
| 3 | +import { useCallback, useEffect, useState } from "react" |
| 4 | + |
| 5 | +import { Responses } from "@blockfrost/blockfrost-js" |
| 6 | + |
| 7 | +type Value = ReturnType<typeof fromUnit> |
| 8 | + |
| 9 | +interface ValueWithName extends Omit<Value, "name"> { |
| 10 | + value: number |
| 11 | + name: string |
| 12 | +} |
| 13 | + |
| 14 | +const useAssets = (lucid?: Lucid, networkId?: number) => { |
| 15 | + const [assets, setAssets] = useState<Responses["asset"][]>([]) |
| 16 | + const [lovelace, setLovelace] = useState(0) |
| 17 | + |
| 18 | + const fetchAssets = useCallback(async () => { |
| 19 | + if (!lucid?.wallet) return |
| 20 | + |
| 21 | + const utxos = await lucid.wallet.getUtxos() |
| 22 | + |
| 23 | + const allUtxos = utxos |
| 24 | + .map((u) => Object.keys(u.assets).map((key) => ({ key, value: u.assets[key] }))) |
| 25 | + .reduce((acc, curr) => [...acc, ...curr], []) |
| 26 | + .map((a) => ({ |
| 27 | + ...fromUnit(a.key), |
| 28 | + value: Number(a.value), |
| 29 | + })) |
| 30 | + |
| 31 | + const lovelaces = allUtxos |
| 32 | + .filter((u) => u.policyId === "lovelace") |
| 33 | + .reduce((acc, curr) => acc + curr.value, 0) |
| 34 | + |
| 35 | + const utxoAssets = allUtxos |
| 36 | + .filter((u) => u.policyId !== "lovelace") |
| 37 | + .filter((v: Value): v is ValueWithName => v.name !== null) |
| 38 | + .map((a) => ({ |
| 39 | + ...a, |
| 40 | + fullyQualifiedAssetName: `${a.policyId}${a.name}`, |
| 41 | + })) |
| 42 | + |
| 43 | + const assetsWithMetadata: Responses["asset"][] = await Promise.all( |
| 44 | + utxoAssets.map((a) => |
| 45 | + fetch(`/api/blockfrost/${networkId}/assets/${a.fullyQualifiedAssetName}`).then((r) => |
| 46 | + r.json() |
| 47 | + ) |
| 48 | + ) |
| 49 | + ) |
| 50 | + |
| 51 | + const sortedAssets = sortBy( |
| 52 | + assetsWithMetadata, |
| 53 | + (a) => (Number(a.quantity) === 1 ? 1 : -1), |
| 54 | + "policy_id", |
| 55 | + "metadata.name", |
| 56 | + "onchain_metadata.name" |
| 57 | + ) |
| 58 | + |
| 59 | + setLovelace(lovelaces) |
| 60 | + setAssets(sortedAssets) |
| 61 | + }, [lucid?.wallet, networkId]) |
| 62 | + |
| 63 | + useEffect(() => { |
| 64 | + fetchAssets() |
| 65 | + }, [fetchAssets]) |
| 66 | + |
| 67 | + return { |
| 68 | + lovelace, |
| 69 | + assets, |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +export { useAssets } |
0 commit comments