@saberhq/sail
Version:
Account caching and batched loading for React-based Solana applications.
94 lines • 3.38 kB
JavaScript
import { getATAAddress, RAW_SOL_MINT, TokenAmount } from "@saberhq/token-utils";
import { useConnectedWallet } from "@saberhq/use-solana";
import { useMemo } from "react";
import { useQuery } from "react-query";
import { useSOLBalance } from "../native";
import { useBatchedTokenAccounts } from "../parsers/splHooks";
/**
* Cache of token/owner mapped to its ATA.
*/
const ataCache = {};
/**
* Loads ATAs owned by the provided owner.
* @param owner
* @param tokens
* @returns
*/
export const useATAs = (owner, tokens) => {
const solBalance = useSOLBalance(owner);
const memoTokens = useMemo(() => tokens,
// eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(tokens.map((tok) => tok === null || tok === void 0 ? void 0 : tok.mintAccount.toString()))]);
const { data: userATAKeys } = useQuery([
"userATAKeys",
owner === null || owner === void 0 ? void 0 : owner.toString(),
...memoTokens.map((tok) => tok === null || tok === void 0 ? void 0 : tok.address),
], async () => {
return await Promise.all(memoTokens.map(async (token) => {
if (!token) {
return token;
}
if (!owner) {
return null;
}
const cacheKey = `${token.address}_${owner.toString()}`;
if (ataCache[cacheKey]) {
return ataCache[cacheKey];
}
const ata = await getATAAddress({
mint: token.mintAccount,
owner,
});
ataCache[cacheKey] = ata;
return ata;
}));
}, {
staleTime: Infinity,
});
const { data: atas } = useBatchedTokenAccounts(userATAKeys);
return useMemo(() => {
if (!owner) {
return null;
}
if (!atas) {
return atas;
}
return atas.map((datum, i) => {
var _a;
const token = memoTokens[i];
if (token === null || token === void 0 ? void 0 : token.mintAccount.equals(RAW_SOL_MINT)) {
return {
key: owner,
balance: solBalance !== null && solBalance !== void 0 ? solBalance : new TokenAmount(token, 0),
isInitialized: !!(solBalance && !solBalance.isZero()),
};
}
if (!token) {
return token;
}
const key = userATAKeys === null || userATAKeys === void 0 ? void 0 : userATAKeys[i];
if (!key) {
return key;
}
return {
key,
balance: new TokenAmount(token, (_a = datum === null || datum === void 0 ? void 0 : datum.account.amount) !== null && _a !== void 0 ? _a : 0),
isInitialized: datum === null || datum === void 0 ? void 0 : datum.account.isInitialized,
};
});
}, [atas, memoTokens, owner, solBalance, userATAKeys]);
};
/**
* Loads ATAs owned by a user.
* @param tokens
* @returns
*/
export const useUserATAs = (...tokens) => {
const wallet = useConnectedWallet();
const atasList = useATAs(wallet === null || wallet === void 0 ? void 0 : wallet.publicKey, tokens);
if (!atasList) {
return tokens.map(() => atasList);
}
return atasList;
};
//# sourceMappingURL=useUserATAs.js.map