Batch fetch all market mints (#18)
This commit is contained in:
parent
599e54c415
commit
d7b8200b9d
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@project-serum/swap-ui",
|
"name": "@project-serum/swap-ui",
|
||||||
"version": "0.1.0-alpha.11",
|
"version": "0.1.0-alpha.17",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"homepage": ".",
|
"homepage": ".",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useContext, useState, useEffect } from "react";
|
import React, { useContext, useState, useEffect } from "react";
|
||||||
import { useAsync } from "react-async-hook";
|
import { useAsync } from "react-async-hook";
|
||||||
import { TokenInfo } from "@solana/spl-token-registry";
|
import { TokenInfo } from "@solana/spl-token-registry";
|
||||||
|
import { MintLayout } from "@solana/spl-token";
|
||||||
import { Connection, PublicKey } from "@solana/web3.js";
|
import { Connection, PublicKey } from "@solana/web3.js";
|
||||||
import * as anchor from "@project-serum/anchor";
|
import * as anchor from "@project-serum/anchor";
|
||||||
import { Swap as SwapClient } from "@project-serum/swap";
|
import { Swap as SwapClient } from "@project-serum/swap";
|
||||||
|
@ -21,6 +22,7 @@ import {
|
||||||
} from "../utils/pubkeys";
|
} from "../utils/pubkeys";
|
||||||
import { useTokenMap, useTokenListContext } from "./TokenList";
|
import { useTokenMap, useTokenListContext } from "./TokenList";
|
||||||
import { fetchSolletInfo, requestWormholeSwapMarketIfNeeded } from "./Sollet";
|
import { fetchSolletInfo, requestWormholeSwapMarketIfNeeded } from "./Sollet";
|
||||||
|
import { setMintCache } from "./Token";
|
||||||
|
|
||||||
export const BASE_TAKER_FEE_BPS = 0.0022;
|
export const BASE_TAKER_FEE_BPS = 0.0022;
|
||||||
|
|
||||||
|
@ -37,11 +39,11 @@ export function DexContextProvider(props: any) {
|
||||||
);
|
);
|
||||||
const swapClient = props.swapClient;
|
const swapClient = props.swapClient;
|
||||||
|
|
||||||
// Two operations:
|
// Three operations:
|
||||||
//
|
//
|
||||||
// 1. Fetch all open orders accounts for the connected wallet.
|
// 1. Fetch all open orders accounts for the connected wallet.
|
||||||
// 2. Batch fetch all market accounts for those open orders.
|
// 2. Batch fetch all market accounts for those open orders.
|
||||||
//
|
// 3. Batch fetch all mints associated with the markets.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!swapClient.program.provider.wallet.publicKey) {
|
if (!swapClient.program.provider.wallet.publicKey) {
|
||||||
setOoAccounts(new Map());
|
setOoAccounts(new Map());
|
||||||
|
@ -68,36 +70,55 @@ export function DexContextProvider(props: any) {
|
||||||
"Too many markets. Please file an issue to update this"
|
"Too many markets. Please file an issue to update this"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(
|
const multipleMarkets = await anchor.utils.getMultipleAccounts(
|
||||||
await anchor.utils.getMultipleAccounts(
|
|
||||||
swapClient.program.provider.connection,
|
swapClient.program.provider.connection,
|
||||||
// @ts-ignore
|
Array.from(markets.values()).map((m) => new PublicKey(m))
|
||||||
[...markets].map((m) => new PublicKey(m))
|
);
|
||||||
)
|
const marketClients = multipleMarkets.map((programAccount) => {
|
||||||
)
|
|
||||||
.map((programAccount) => {
|
|
||||||
return {
|
return {
|
||||||
publicKey: programAccount?.publicKey,
|
publicKey: programAccount?.publicKey,
|
||||||
account: new Promise<Market>((resolve) =>
|
account: new Market(
|
||||||
resolve(
|
Market.getLayout(DEX_PID).decode(programAccount?.account.data),
|
||||||
new Market(
|
|
||||||
Market.getLayout(DEX_PID).decode(
|
|
||||||
programAccount?.account.data
|
|
||||||
),
|
|
||||||
-1, // Not used so don't bother fetching.
|
-1, // Not used so don't bother fetching.
|
||||||
-1, // Not used so don't bother fetching.
|
-1, // Not used so don't bother fetching.
|
||||||
swapClient.program.provider.opts,
|
swapClient.program.provider.opts,
|
||||||
DEX_PID
|
DEX_PID
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
})
|
|
||||||
.forEach((m) => {
|
|
||||||
_MARKET_CACHE.set(m.publicKey!.toString(), m.account);
|
|
||||||
});
|
});
|
||||||
|
marketClients.forEach((m) => {
|
||||||
|
_MARKET_CACHE.set(
|
||||||
|
m.publicKey!.toString(),
|
||||||
|
new Promise<Market>((resolve) => resolve(m.account))
|
||||||
|
);
|
||||||
|
});
|
||||||
setOoAccounts(newOoAccounts);
|
setOoAccounts(newOoAccounts);
|
||||||
|
|
||||||
|
// Batch fetch all the mints, since we know we'll need them at some
|
||||||
|
// point.
|
||||||
|
const mintPubkeys = Array.from(
|
||||||
|
new Set<string>(
|
||||||
|
marketClients
|
||||||
|
.map((m) => [
|
||||||
|
m.account.baseMintAddress.toString(),
|
||||||
|
m.account.quoteMintAddress.toString(),
|
||||||
|
])
|
||||||
|
.flat()
|
||||||
|
).values()
|
||||||
|
).map((pk) => new PublicKey(pk));
|
||||||
|
|
||||||
|
if (mintPubkeys.length > 100) {
|
||||||
|
// Punt request chunking until there's user demand.
|
||||||
|
throw new Error("Too many mints. Please file an issue to update this");
|
||||||
|
}
|
||||||
|
|
||||||
|
const mints = await anchor.utils.getMultipleAccounts(
|
||||||
|
swapClient.program.provider.connection,
|
||||||
|
mintPubkeys
|
||||||
|
);
|
||||||
|
mints.forEach((mint) => {
|
||||||
|
setMintCache(mint!.publicKey, MintLayout.decode(mint!.account.data));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
swapClient.program.provider.connection,
|
swapClient.program.provider.connection,
|
||||||
|
|
|
@ -141,6 +141,10 @@ export function useMint(mint?: PublicKey): MintInfo | undefined | null {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setMintCache(pk: PublicKey, account: MintInfo) {
|
||||||
|
_MINT_CACHE.set(pk.toString(), new Promise((resolve) => resolve(account)));
|
||||||
|
}
|
||||||
|
|
||||||
// Cache storing all token accounts for the connected wallet provider.
|
// Cache storing all token accounts for the connected wallet provider.
|
||||||
const _OWNED_TOKEN_ACCOUNTS_CACHE: Array<{
|
const _OWNED_TOKEN_ACCOUNTS_CACHE: Array<{
|
||||||
publicKey: PublicKey;
|
publicKey: PublicKey;
|
||||||
|
|
|
@ -70,12 +70,6 @@ const ACCOUNT_LAYOUT = BufferLayout.struct([
|
||||||
BufferLayout.blob(93),
|
BufferLayout.blob(93),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const MINT_LAYOUT = BufferLayout.struct([
|
|
||||||
BufferLayout.blob(44),
|
|
||||||
BufferLayout.u8("decimals"),
|
|
||||||
BufferLayout.blob(37),
|
|
||||||
]);
|
|
||||||
|
|
||||||
export function parseTokenAccountData(data: Buffer): TokenAccount {
|
export function parseTokenAccountData(data: Buffer): TokenAccount {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let { mint, owner, amount } = ACCOUNT_LAYOUT.decode(data);
|
let { mint, owner, amount } = ACCOUNT_LAYOUT.decode(data);
|
||||||
|
@ -87,12 +81,6 @@ export function parseTokenAccountData(data: Buffer): TokenAccount {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseMintData(data: Buffer) {
|
|
||||||
// @ts-ignore
|
|
||||||
let { decimals } = MINT_LAYOUT.decode(data);
|
|
||||||
return { decimals };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOwnedAccountsFilters(publicKey: PublicKey) {
|
function getOwnedAccountsFilters(publicKey: PublicKey) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue