Merge pull request #523 from metaplex-foundation/feat/incredible-speed-loading-2
feat: useAuctions on store-related auctions
This commit is contained in:
commit
301e832f27
|
@ -37,7 +37,7 @@ import { ParsedAccount } from '../accounts/types';
|
||||||
import { getEmptyMetaState } from './getEmptyMetaState';
|
import { getEmptyMetaState } from './getEmptyMetaState';
|
||||||
import { getMultipleAccounts } from '../accounts/getMultipleAccounts';
|
import { getMultipleAccounts } from '../accounts/getMultipleAccounts';
|
||||||
import { getProgramAccounts } from './web3';
|
import { getProgramAccounts } from './web3';
|
||||||
import { createPipelineExecutor } from './createPipelineExecutor';
|
import { createPipelineExecutor } from '../../utils/createPipelineExecutor';
|
||||||
|
|
||||||
export const USE_SPEED_RUN = false;
|
export const USE_SPEED_RUN = false;
|
||||||
const WHITELISTED_METADATA = ['98vYFjBYS9TguUMWQRPjy2SZuxKuUMcqR4vnQiLjZbte'];
|
const WHITELISTED_METADATA = ['98vYFjBYS9TguUMWQRPjy2SZuxKuUMcqR4vnQiLjZbte'];
|
||||||
|
|
|
@ -12,7 +12,6 @@ export async function createPipelineExecutor<T>(
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
function execute<T>(iter: IteratorResult<T, any>) {
|
function execute<T>(iter: IteratorResult<T, any>) {
|
||||||
// TODO: wait for async executor
|
|
||||||
executor(iter.value);
|
executor(iter.value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,4 @@ export * from './strings';
|
||||||
export * as shortvec from './shortvec';
|
export * as shortvec from './shortvec';
|
||||||
export * from './isValidHttpUrl';
|
export * from './isValidHttpUrl';
|
||||||
export * from './borsh';
|
export * from './borsh';
|
||||||
|
export * from './createPipelineExecutor';
|
||||||
|
|
|
@ -11,10 +11,11 @@ import {
|
||||||
MasterEditionV2,
|
MasterEditionV2,
|
||||||
StringPublicKey,
|
StringPublicKey,
|
||||||
AuctionDataExtended,
|
AuctionDataExtended,
|
||||||
|
createPipelineExecutor,
|
||||||
} from '@oyster/common';
|
} from '@oyster/common';
|
||||||
import { useWallet } from '@solana/wallet-adapter-react';
|
import { useWallet } from '@solana/wallet-adapter-react';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useMeta } from '../contexts';
|
import { useMeta } from '../contexts';
|
||||||
import {
|
import {
|
||||||
AuctionManager,
|
AuctionManager,
|
||||||
|
@ -58,51 +59,54 @@ export interface AuctionView {
|
||||||
isInstantSale: boolean;
|
isInstantSale: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CachedRedemptionKeys = Record<
|
||||||
|
string,
|
||||||
|
ParsedAccount<BidRedemptionTicket> | { pubkey: StringPublicKey; info: null }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export function useStoreAuctionsList() {
|
||||||
|
const { auctions, auctionManagersByAuction } = useMeta();
|
||||||
|
const result = useMemo(() => {
|
||||||
|
return Object.values(auctionManagersByAuction).map(
|
||||||
|
manager => auctions[manager.info.auction],
|
||||||
|
);
|
||||||
|
}, [auctions, auctionManagersByAuction]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function useCachedRedemptionKeysByWallet() {
|
export function useCachedRedemptionKeysByWallet() {
|
||||||
const { auctions, bidRedemptions } = useMeta();
|
const { bidRedemptions } = useMeta();
|
||||||
|
const auctions = useStoreAuctionsList();
|
||||||
const { publicKey } = useWallet();
|
const { publicKey } = useWallet();
|
||||||
|
|
||||||
const [cachedRedemptionKeys, setCachedRedemptionKeys] = useState<
|
const [cachedRedemptionKeys, setCachedRedemptionKeys] =
|
||||||
Record<
|
useState<CachedRedemptionKeys>({});
|
||||||
string,
|
|
||||||
| ParsedAccount<BidRedemptionTicket>
|
|
||||||
| { pubkey: StringPublicKey; info: null }
|
|
||||||
>
|
|
||||||
>({});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!publicKey) return;
|
||||||
(async () => {
|
(async () => {
|
||||||
if (publicKey) {
|
const temp: CachedRedemptionKeys = {};
|
||||||
const temp: Record<
|
await createPipelineExecutor(
|
||||||
string,
|
auctions.values(),
|
||||||
| ParsedAccount<BidRedemptionTicket>
|
async auction => {
|
||||||
| { pubkey: StringPublicKey; info: null }
|
if (!cachedRedemptionKeys[auction.pubkey]) {
|
||||||
> = {};
|
await getBidderKeys(auction.pubkey, publicKey.toBase58()).then(
|
||||||
const keys = Object.keys(auctions);
|
|
||||||
const tasks: Promise<void>[] = [];
|
|
||||||
for (let i = 0; i < keys.length; i++) {
|
|
||||||
const a = keys[i];
|
|
||||||
if (!cachedRedemptionKeys[a])
|
|
||||||
tasks.push(
|
|
||||||
getBidderKeys(auctions[a].pubkey, publicKey.toBase58()).then(
|
|
||||||
key => {
|
key => {
|
||||||
temp[a] = bidRedemptions[key.bidRedemption]
|
temp[auction.pubkey] = bidRedemptions[key.bidRedemption]
|
||||||
? bidRedemptions[key.bidRedemption]
|
? bidRedemptions[key.bidRedemption]
|
||||||
: { pubkey: key.bidRedemption, info: null };
|
: { pubkey: key.bidRedemption, info: null };
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
else if (!cachedRedemptionKeys[a].info) {
|
} else if (!cachedRedemptionKeys[auction.pubkey].info) {
|
||||||
temp[a] =
|
temp[auction.pubkey] =
|
||||||
bidRedemptions[cachedRedemptionKeys[a].pubkey] ||
|
bidRedemptions[cachedRedemptionKeys[auction.pubkey].pubkey] ||
|
||||||
cachedRedemptionKeys[a];
|
cachedRedemptionKeys[auction.pubkey];
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{ delay: 1, sequence: 2 },
|
||||||
await Promise.all(tasks);
|
);
|
||||||
|
|
||||||
setCachedRedemptionKeys(temp);
|
setCachedRedemptionKeys(temp);
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
}, [auctions, bidRedemptions, publicKey]);
|
}, [auctions, bidRedemptions, publicKey]);
|
||||||
|
|
||||||
|
@ -113,9 +117,9 @@ export const useAuctions = (state?: AuctionViewState) => {
|
||||||
const [auctionViews, setAuctionViews] = useState<AuctionView[]>([]);
|
const [auctionViews, setAuctionViews] = useState<AuctionView[]>([]);
|
||||||
const { publicKey } = useWallet();
|
const { publicKey } = useWallet();
|
||||||
const cachedRedemptionKeys = useCachedRedemptionKeysByWallet();
|
const cachedRedemptionKeys = useCachedRedemptionKeysByWallet();
|
||||||
|
const auctions = useStoreAuctionsList();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
auctions,
|
|
||||||
auctionManagersByAuction,
|
auctionManagersByAuction,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
@ -132,9 +136,13 @@ export const useAuctions = (state?: AuctionViewState) => {
|
||||||
} = useMeta();
|
} = useMeta();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const map = Object.keys(auctions).reduce((agg, a) => {
|
(async () => {
|
||||||
const auction = auctions[a];
|
const auctionViews: AuctionView[] = [];
|
||||||
const nextAuctionView = processAccountsIntoAuctionView(
|
|
||||||
|
await createPipelineExecutor(
|
||||||
|
auctions.values(),
|
||||||
|
auction => {
|
||||||
|
const auctionView = processAccountsIntoAuctionView(
|
||||||
publicKey?.toBase58(),
|
publicKey?.toBase58(),
|
||||||
auction,
|
auction,
|
||||||
auctionDataExtended,
|
auctionDataExtended,
|
||||||
|
@ -153,19 +161,14 @@ export const useAuctions = (state?: AuctionViewState) => {
|
||||||
cachedRedemptionKeys,
|
cachedRedemptionKeys,
|
||||||
state,
|
state,
|
||||||
);
|
);
|
||||||
agg[a] = nextAuctionView;
|
if (auctionView) {
|
||||||
return agg;
|
auctionViews.push(auctionView);
|
||||||
}, {} as Record<string, AuctionView | undefined>);
|
}
|
||||||
|
},
|
||||||
setAuctionViews(
|
{ delay: 1, sequence: 2 },
|
||||||
(Object.values(map).filter(v => v) as AuctionView[]).sort((a, b) => {
|
|
||||||
return (
|
|
||||||
b?.auction.info.endedAt
|
|
||||||
?.sub(a?.auction.info.endedAt || new BN(0))
|
|
||||||
.toNumber() || 0
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
setAuctionViews(auctionViews.sort(sortByEnded));
|
||||||
|
})();
|
||||||
}, [
|
}, [
|
||||||
state,
|
state,
|
||||||
auctions,
|
auctions,
|
||||||
|
@ -190,6 +193,13 @@ export const useAuctions = (state?: AuctionViewState) => {
|
||||||
return auctionViews;
|
return auctionViews;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function sortByEnded(a: AuctionView, b: AuctionView) {
|
||||||
|
return (
|
||||||
|
(b.auction.info.endedAt?.toNumber() || 0) -
|
||||||
|
(a.auction.info.endedAt?.toNumber() || 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function isInstantSale(
|
function isInstantSale(
|
||||||
auctionDataExt: ParsedAccount<AuctionDataExtended> | null,
|
auctionDataExt: ParsedAccount<AuctionDataExtended> | null,
|
||||||
auction: ParsedAccount<AuctionData>,
|
auction: ParsedAccount<AuctionData>,
|
||||||
|
|
Loading…
Reference in New Issue