mirror of https://github.com/certusone/oyster.git
Merge remote-tracking branch 'origin/feature/m-jordan' into feature/m
This commit is contained in:
commit
bb3f9fd192
|
@ -49,6 +49,18 @@ export const decodeAuction = (buffer: Buffer) => {
|
||||||
return deserializeBorsh(AUCTION_SCHEMA, AuctionData, buffer) as AuctionData;
|
return deserializeBorsh(AUCTION_SCHEMA, AuctionData, buffer) as AuctionData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const decodeBidderPot = (buffer: Buffer) => {
|
||||||
|
return deserializeBorsh(AUCTION_SCHEMA, BidderPot, buffer) as BidderPot;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const decodeBidderMetadata = (buffer: Buffer) => {
|
||||||
|
return deserializeBorsh(
|
||||||
|
AUCTION_SCHEMA,
|
||||||
|
BidderMetadata,
|
||||||
|
buffer,
|
||||||
|
) as BidderMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
export const BASE_AUCTION_DATA_SIZE = 32 + 32 + 32 + 8 + 8 + 1 + 9 + 9 + 9 + 9;
|
export const BASE_AUCTION_DATA_SIZE = 32 + 32 + 32 + 8 + 8 + 1 + 9 + 9 + 9 + 9;
|
||||||
|
|
||||||
export class AuctionData {
|
export class AuctionData {
|
||||||
|
@ -127,8 +139,16 @@ export class BidderMetadata {
|
||||||
export class BidderPot {
|
export class BidderPot {
|
||||||
/// Points at actual pot that is a token account
|
/// Points at actual pot that is a token account
|
||||||
bidderPot: PublicKey;
|
bidderPot: PublicKey;
|
||||||
constructor(args: { bidderPot: PublicKey }) {
|
bidderAct: PublicKey;
|
||||||
|
auctionAct: PublicKey;
|
||||||
|
constructor(args: {
|
||||||
|
bidderPot: PublicKey;
|
||||||
|
bidderAct: PublicKey;
|
||||||
|
auctionAct: PublicKey;
|
||||||
|
}) {
|
||||||
this.bidderPot = args.bidderPot;
|
this.bidderPot = args.bidderPot;
|
||||||
|
this.bidderAct = args.bidderAct;
|
||||||
|
this.auctionAct = args.auctionAct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,8 +260,8 @@ export const AUCTION_SCHEMA = new Map<any, any>([
|
||||||
kind: 'struct',
|
kind: 'struct',
|
||||||
fields: [
|
fields: [
|
||||||
['instruction', 'u8'],
|
['instruction', 'u8'],
|
||||||
['resource', 'pubkey'],
|
|
||||||
['amount', 'u64'],
|
['amount', 'u64'],
|
||||||
|
['resource', 'pubkey'],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -300,7 +320,11 @@ export const AUCTION_SCHEMA = new Map<any, any>([
|
||||||
BidderPot,
|
BidderPot,
|
||||||
{
|
{
|
||||||
kind: 'struct',
|
kind: 'struct',
|
||||||
fields: [['bidderPot', 'pubkey']],
|
fields: [
|
||||||
|
['bidderPot', 'pubkey'],
|
||||||
|
['bidderAct', 'pubkey'],
|
||||||
|
['auctionAct', 'pubkey'],
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
@ -490,7 +514,7 @@ export async function placeBid(
|
||||||
const keys = [
|
const keys = [
|
||||||
{
|
{
|
||||||
pubkey: bidderPubkey,
|
pubkey: bidderPubkey,
|
||||||
isSigner: true,
|
isSigner: false,
|
||||||
isWritable: true,
|
isWritable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import {
|
||||||
|
Account,
|
||||||
|
Connection,
|
||||||
|
PublicKey,
|
||||||
|
TransactionInstruction,
|
||||||
|
} from '@solana/web3.js';
|
||||||
|
import {
|
||||||
|
actions,
|
||||||
|
ParsedAccount,
|
||||||
|
SequenceType,
|
||||||
|
sendTransactionWithRetry,
|
||||||
|
placeBid,
|
||||||
|
programIds,
|
||||||
|
BidderPot,
|
||||||
|
models,
|
||||||
|
} from '@oyster/common';
|
||||||
|
|
||||||
|
import { AccountLayout } from '@solana/spl-token';
|
||||||
|
import { AuctionView } from '../hooks';
|
||||||
|
import BN from 'bn.js';
|
||||||
|
const { createTokenAccount } = actions;
|
||||||
|
const { approve } = models;
|
||||||
|
|
||||||
|
export async function sendPlaceBid(
|
||||||
|
connection: Connection,
|
||||||
|
wallet: any,
|
||||||
|
bidderAccount: PublicKey,
|
||||||
|
auctionView: AuctionView,
|
||||||
|
amount: number,
|
||||||
|
) {
|
||||||
|
let signers: Account[] = [];
|
||||||
|
let instructions: TransactionInstruction[] = [];
|
||||||
|
|
||||||
|
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||||
|
AccountLayout.span,
|
||||||
|
);
|
||||||
|
|
||||||
|
let bidderPotTokenAccount: PublicKey;
|
||||||
|
if (!auctionView.myBidderPot) {
|
||||||
|
bidderPotTokenAccount = createTokenAccount(
|
||||||
|
instructions,
|
||||||
|
wallet.publicKey,
|
||||||
|
accountRentExempt,
|
||||||
|
auctionView.auction.info.tokenMint,
|
||||||
|
programIds().auction,
|
||||||
|
signers,
|
||||||
|
);
|
||||||
|
} else bidderPotTokenAccount = auctionView.myBidderPot?.info.bidderPot;
|
||||||
|
|
||||||
|
const transferAuthority = approve(
|
||||||
|
instructions,
|
||||||
|
[],
|
||||||
|
bidderAccount,
|
||||||
|
wallet.publicKey,
|
||||||
|
amount,
|
||||||
|
);
|
||||||
|
|
||||||
|
signers.push(transferAuthority);
|
||||||
|
|
||||||
|
await placeBid(
|
||||||
|
bidderAccount,
|
||||||
|
bidderPotTokenAccount,
|
||||||
|
auctionView.auction.info.tokenMint,
|
||||||
|
transferAuthority.publicKey,
|
||||||
|
wallet.publicKey,
|
||||||
|
auctionView.auctionManager.info.vault,
|
||||||
|
new BN(amount),
|
||||||
|
instructions,
|
||||||
|
);
|
||||||
|
|
||||||
|
await sendTransactionWithRetry(
|
||||||
|
connection,
|
||||||
|
wallet,
|
||||||
|
instructions,
|
||||||
|
signers,
|
||||||
|
'single',
|
||||||
|
);
|
||||||
|
}
|
|
@ -10,16 +10,21 @@ import {
|
||||||
TokenAccount,
|
TokenAccount,
|
||||||
useConnection,
|
useConnection,
|
||||||
useUserAccounts,
|
useUserAccounts,
|
||||||
|
hooks,
|
||||||
|
contexts,
|
||||||
} from '@oyster/common';
|
} from '@oyster/common';
|
||||||
import { AuctionView } from '../../hooks';
|
import { AuctionView } from '../../hooks';
|
||||||
|
import { sendPlaceBid } from '../../actions/sendPlaceBid';
|
||||||
|
const { useWallet } = contexts.Wallet;
|
||||||
export const AuctionCard = ({ auctionView }: { auctionView: AuctionView }) => {
|
export const AuctionCard = ({ auctionView }: { auctionView: AuctionView }) => {
|
||||||
const [hours, setHours] = useState<number>(23);
|
const [hours, setHours] = useState<number>(23);
|
||||||
const [minutes, setMinutes] = useState<number>(59);
|
const [minutes, setMinutes] = useState<number>(59);
|
||||||
const [seconds, setSeconds] = useState<number>(59);
|
const [seconds, setSeconds] = useState<number>(59);
|
||||||
const [clock, setClock] = useState<number>(0);
|
const [clock, setClock] = useState<number>(0);
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
|
const { wallet } = useWallet();
|
||||||
const { userAccounts } = useUserAccounts();
|
const { userAccounts } = useUserAccounts();
|
||||||
|
const [value, setValue] = useState<number>();
|
||||||
const accountByMint = userAccounts.reduce((prev, acc) => {
|
const accountByMint = userAccounts.reduce((prev, acc) => {
|
||||||
prev.set(acc.info.mint.toBase58(), acc);
|
prev.set(acc.info.mint.toBase58(), acc);
|
||||||
return prev;
|
return prev;
|
||||||
|
@ -84,14 +89,8 @@ export const AuctionCard = ({ auctionView }: { auctionView: AuctionView }) => {
|
||||||
<InputNumber
|
<InputNumber
|
||||||
autoFocus
|
autoFocus
|
||||||
className="input"
|
className="input"
|
||||||
placeholder="Max 50 characters"
|
value={value}
|
||||||
// value={props.attributes.name}
|
onChange={setValue}
|
||||||
// onChange={info =>
|
|
||||||
// props.setAttributes({
|
|
||||||
// ...props.attributes,
|
|
||||||
// name: info.target.value,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -106,6 +105,18 @@ export const AuctionCard = ({ auctionView }: { auctionView: AuctionView }) => {
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
className="action-btn"
|
className="action-btn"
|
||||||
|
disabled={!myPayingAccount || value === undefined}
|
||||||
|
onClick={() => {
|
||||||
|
console.log('Auctionview', auctionView);
|
||||||
|
if (myPayingAccount && value)
|
||||||
|
sendPlaceBid(
|
||||||
|
connection,
|
||||||
|
wallet,
|
||||||
|
myPayingAccount.pubkey,
|
||||||
|
auctionView,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
}}
|
||||||
style={{ marginTop: 20 }}
|
style={{ marginTop: 20 }}
|
||||||
>
|
>
|
||||||
PLACE BID
|
PLACE BID
|
||||||
|
|
|
@ -20,6 +20,10 @@ import {
|
||||||
SafetyDepositBox,
|
SafetyDepositBox,
|
||||||
VaultKey,
|
VaultKey,
|
||||||
decodeSafetyDeposit,
|
decodeSafetyDeposit,
|
||||||
|
BidderMetadata,
|
||||||
|
decodeBidderMetadata,
|
||||||
|
BidderPot,
|
||||||
|
decodeBidderPot,
|
||||||
} from '@oyster/common';
|
} from '@oyster/common';
|
||||||
import { MintInfo } from '@solana/spl-token';
|
import { MintInfo } from '@solana/spl-token';
|
||||||
import { Connection, PublicKey, PublicKeyAndAccount } from '@solana/web3.js';
|
import { Connection, PublicKey, PublicKeyAndAccount } from '@solana/web3.js';
|
||||||
|
@ -42,10 +46,15 @@ export interface MetaContextState {
|
||||||
masterEditions: Record<string, ParsedAccount<MasterEdition>>;
|
masterEditions: Record<string, ParsedAccount<MasterEdition>>;
|
||||||
auctionManagers: Record<string, ParsedAccount<AuctionManager>>;
|
auctionManagers: Record<string, ParsedAccount<AuctionManager>>;
|
||||||
auctions: Record<string, ParsedAccount<AuctionData>>;
|
auctions: Record<string, ParsedAccount<AuctionData>>;
|
||||||
|
bidderMetadataByAuctionAndBidder: Record<
|
||||||
|
string,
|
||||||
|
ParsedAccount<BidderMetadata>
|
||||||
|
>;
|
||||||
safetyDepositBoxesByVaultAndIndex: Record<
|
safetyDepositBoxesByVaultAndIndex: Record<
|
||||||
string,
|
string,
|
||||||
ParsedAccount<SafetyDepositBox>
|
ParsedAccount<SafetyDepositBox>
|
||||||
>;
|
>;
|
||||||
|
bidderPotsByAuctionAndBidder: Record<string, ParsedAccount<BidderPot>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MetaContext = React.createContext<MetaContextState>({
|
const MetaContext = React.createContext<MetaContextState>({
|
||||||
|
@ -56,7 +65,9 @@ const MetaContext = React.createContext<MetaContextState>({
|
||||||
editions: {},
|
editions: {},
|
||||||
auctionManagers: {},
|
auctionManagers: {},
|
||||||
auctions: {},
|
auctions: {},
|
||||||
|
bidderMetadataByAuctionAndBidder: {},
|
||||||
safetyDepositBoxesByVaultAndIndex: {},
|
safetyDepositBoxesByVaultAndIndex: {},
|
||||||
|
bidderPotsByAuctionAndBidder: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function MetaProvider({ children = null as any }) {
|
export function MetaProvider({ children = null as any }) {
|
||||||
|
@ -80,6 +91,14 @@ export function MetaProvider({ children = null as any }) {
|
||||||
const [auctions, setAuctions] = useState<
|
const [auctions, setAuctions] = useState<
|
||||||
Record<string, ParsedAccount<AuctionData>>
|
Record<string, ParsedAccount<AuctionData>>
|
||||||
>({});
|
>({});
|
||||||
|
const [
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
setBidderMetadataByAuctionAndBidder,
|
||||||
|
] = useState<Record<string, ParsedAccount<BidderMetadata>>>({});
|
||||||
|
const [
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
|
setBidderPotsByAuctionAndBidder,
|
||||||
|
] = useState<Record<string, ParsedAccount<BidderPot>>>({});
|
||||||
const [
|
const [
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
setSafetyDepositBoxesByVaultAndIndex,
|
setSafetyDepositBoxesByVaultAndIndex,
|
||||||
|
@ -107,6 +126,42 @@ export function MetaProvider({ children = null as any }) {
|
||||||
} catch {
|
} catch {
|
||||||
// ignore errors
|
// ignore errors
|
||||||
// add type as first byte for easier deserialization
|
// add type as first byte for easier deserialization
|
||||||
|
try {
|
||||||
|
const bidderMetadata = await decodeBidderMetadata(a.account.data);
|
||||||
|
|
||||||
|
const account: ParsedAccount<BidderMetadata> = {
|
||||||
|
pubkey: a.pubkey,
|
||||||
|
account: a.account,
|
||||||
|
info: bidderMetadata,
|
||||||
|
};
|
||||||
|
setBidderMetadataByAuctionAndBidder(e => ({
|
||||||
|
...e,
|
||||||
|
[bidderMetadata.auctionPubkey.toBase58() +
|
||||||
|
'-' +
|
||||||
|
bidderMetadata.bidderPubkey.toBase58()]: account,
|
||||||
|
}));
|
||||||
|
} catch {
|
||||||
|
// ignore errors
|
||||||
|
// add type as first byte for easier deserialization
|
||||||
|
try {
|
||||||
|
const bidderPot = await decodeBidderPot(a.account.data);
|
||||||
|
|
||||||
|
const account: ParsedAccount<BidderPot> = {
|
||||||
|
pubkey: a.pubkey,
|
||||||
|
account: a.account,
|
||||||
|
info: bidderPot,
|
||||||
|
};
|
||||||
|
setBidderPotsByAuctionAndBidder(e => ({
|
||||||
|
...e,
|
||||||
|
[bidderPot.auctionAct.toBase58() +
|
||||||
|
'-' +
|
||||||
|
bidderPot.bidderAct.toBase58()]: account,
|
||||||
|
}));
|
||||||
|
} catch {
|
||||||
|
// ignore errors
|
||||||
|
// add type as first byte for easier deserialization
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -355,6 +410,8 @@ export function MetaProvider({ children = null as any }) {
|
||||||
auctions,
|
auctions,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
import { useConnection } from '@oyster/common';
|
import { TokenAccount, useConnection, useUserAccounts } from '@oyster/common';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { AuctionView, processAccountsIntoAuctionView } from '.';
|
import { AuctionView, processAccountsIntoAuctionView } from '.';
|
||||||
import { useMeta } from '../contexts';
|
import { useMeta } from '../contexts';
|
||||||
|
|
||||||
export const useAuction = (id: string) => {
|
export const useAuction = (id: string) => {
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
|
const { userAccounts } = useUserAccounts();
|
||||||
|
const accountByMint = userAccounts.reduce((prev, acc) => {
|
||||||
|
prev.set(acc.info.mint.toBase58(), acc);
|
||||||
|
return prev;
|
||||||
|
}, new Map<string, TokenAccount>());
|
||||||
const [clock, setClock] = useState<number>(0);
|
const [clock, setClock] = useState<number>(0);
|
||||||
const [auctionView, setAuctionView] = useState<AuctionView | null>(null);
|
const [existingAuctionView, setAuctionView] = useState<AuctionView | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
connection.getSlot().then(setClock);
|
connection.getSlot().then(setClock);
|
||||||
}, [connection]);
|
}, [connection]);
|
||||||
|
@ -16,6 +23,8 @@ export const useAuction = (id: string) => {
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
} = useMeta();
|
} = useMeta();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -26,8 +35,12 @@ export const useAuction = (id: string) => {
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
|
accountByMint,
|
||||||
clock,
|
clock,
|
||||||
undefined,
|
undefined,
|
||||||
|
existingAuctionView || undefined,
|
||||||
);
|
);
|
||||||
if (auctionView) setAuctionView(auctionView);
|
if (auctionView) setAuctionView(auctionView);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +50,9 @@ export const useAuction = (id: string) => {
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
|
userAccounts,
|
||||||
]);
|
]);
|
||||||
return auctionView;
|
return existingAuctionView;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,11 @@ import {
|
||||||
AuctionData,
|
AuctionData,
|
||||||
useConnection,
|
useConnection,
|
||||||
AuctionState,
|
AuctionState,
|
||||||
|
BidderMetadata,
|
||||||
|
BidderPot,
|
||||||
|
useWallet,
|
||||||
|
useUserAccounts,
|
||||||
|
TokenAccount,
|
||||||
} from '@oyster/common';
|
} from '@oyster/common';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useMeta } from '../contexts';
|
import { useMeta } from '../contexts';
|
||||||
|
@ -30,12 +35,23 @@ export interface AuctionView {
|
||||||
openEditionItem?: AuctionViewItem;
|
openEditionItem?: AuctionViewItem;
|
||||||
state: AuctionViewState;
|
state: AuctionViewState;
|
||||||
thumbnail: AuctionViewItem;
|
thumbnail: AuctionViewItem;
|
||||||
|
myBidderMetadata?: ParsedAccount<BidderMetadata>;
|
||||||
|
myBidderPot?: ParsedAccount<BidderPot>;
|
||||||
|
totallyComplete: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAuctions = (state: AuctionViewState) => {
|
export const useAuctions = (state: AuctionViewState) => {
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
|
const { userAccounts } = useUserAccounts();
|
||||||
|
const accountByMint = userAccounts.reduce((prev, acc) => {
|
||||||
|
prev.set(acc.info.mint.toBase58(), acc);
|
||||||
|
return prev;
|
||||||
|
}, new Map<string, TokenAccount>());
|
||||||
|
|
||||||
const [clock, setClock] = useState<number>(0);
|
const [clock, setClock] = useState<number>(0);
|
||||||
const [auctionViews, setAuctionViews] = useState<AuctionView[]>([]);
|
const [auctionViews, setAuctionViews] = useState<
|
||||||
|
Record<string, AuctionView | undefined>
|
||||||
|
>({});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
connection.getSlot().then(setClock);
|
connection.getSlot().then(setClock);
|
||||||
}, [connection]);
|
}, [connection]);
|
||||||
|
@ -45,23 +61,28 @@ export const useAuctions = (state: AuctionViewState) => {
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
} = useMeta();
|
} = useMeta();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newAuctionViews: AuctionView[] = [];
|
|
||||||
Object.keys(auctions).forEach(a => {
|
Object.keys(auctions).forEach(a => {
|
||||||
const auction = auctions[a];
|
const auction = auctions[a];
|
||||||
const auctionView = processAccountsIntoAuctionView(
|
const existingAuctionView = auctionViews[a];
|
||||||
|
const nextAuctionView = processAccountsIntoAuctionView(
|
||||||
auction,
|
auction,
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
|
accountByMint,
|
||||||
clock,
|
clock,
|
||||||
state,
|
state,
|
||||||
|
existingAuctionView,
|
||||||
);
|
);
|
||||||
if (auctionView) newAuctionViews.push(auctionView);
|
setAuctionViews(nA => ({ ...nA, [a]: nextAuctionView }));
|
||||||
});
|
});
|
||||||
setAuctionViews(newAuctionViews);
|
|
||||||
}, [
|
}, [
|
||||||
clock,
|
clock,
|
||||||
state,
|
state,
|
||||||
|
@ -69,9 +90,12 @@ export const useAuctions = (state: AuctionViewState) => {
|
||||||
auctionManagers,
|
auctionManagers,
|
||||||
safetyDepositBoxesByVaultAndIndex,
|
safetyDepositBoxesByVaultAndIndex,
|
||||||
metadataByMint,
|
metadataByMint,
|
||||||
|
bidderMetadataByAuctionAndBidder,
|
||||||
|
bidderPotsByAuctionAndBidder,
|
||||||
|
userAccounts,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return auctionViews;
|
return Object.values(auctionViews).filter(v => v) as AuctionView[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function processAccountsIntoAuctionView(
|
export function processAccountsIntoAuctionView(
|
||||||
|
@ -82,9 +106,16 @@ export function processAccountsIntoAuctionView(
|
||||||
ParsedAccount<SafetyDepositBox>
|
ParsedAccount<SafetyDepositBox>
|
||||||
>,
|
>,
|
||||||
metadataByMint: Record<string, ParsedAccount<Metadata>>,
|
metadataByMint: Record<string, ParsedAccount<Metadata>>,
|
||||||
|
bidderMetadataByAuctionAndBidder: Record<
|
||||||
|
string,
|
||||||
|
ParsedAccount<BidderMetadata>
|
||||||
|
>,
|
||||||
|
bidderPotsByAuctionAndBidder: Record<string, ParsedAccount<BidderPot>>,
|
||||||
|
accountByMint: Map<string, TokenAccount>,
|
||||||
clock: number,
|
clock: number,
|
||||||
desiredState: AuctionViewState | undefined,
|
desiredState: AuctionViewState | undefined,
|
||||||
) {
|
existingAuctionView?: AuctionView,
|
||||||
|
): AuctionView | undefined {
|
||||||
let state: AuctionViewState;
|
let state: AuctionViewState;
|
||||||
if (
|
if (
|
||||||
auction.info.state == AuctionState.Ended ||
|
auction.info.state == AuctionState.Ended ||
|
||||||
|
@ -102,12 +133,32 @@ export function processAccountsIntoAuctionView(
|
||||||
state = AuctionViewState.BuyNow;
|
state = AuctionViewState.BuyNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desiredState && desiredState != state) return null;
|
if (desiredState && desiredState != state) return undefined;
|
||||||
|
|
||||||
|
const myPayingAccount = accountByMint.get(auction.info.tokenMint.toBase58());
|
||||||
|
|
||||||
const auctionManager =
|
const auctionManager =
|
||||||
auctionManagers[auction.info.auctionManagerKey?.toBase58() || ''];
|
auctionManagers[auction.info.auctionManagerKey?.toBase58() || ''];
|
||||||
if (auctionManager) {
|
if (auctionManager) {
|
||||||
|
const boxesExpected = auctionManager.info.state.winningConfigsValidated;
|
||||||
|
const bidderMetadata =
|
||||||
|
bidderMetadataByAuctionAndBidder[
|
||||||
|
auction.pubkey.toBase58() + '-' + myPayingAccount?.pubkey.toBase58()
|
||||||
|
];
|
||||||
|
const bidderPot =
|
||||||
|
bidderPotsByAuctionAndBidder[
|
||||||
|
auction.pubkey.toBase58() + '-' + myPayingAccount?.pubkey.toBase58()
|
||||||
|
];
|
||||||
|
if (existingAuctionView && existingAuctionView.totallyComplete) {
|
||||||
|
// If totally complete, we know we arent updating anythign else, let's speed things up
|
||||||
|
// and only update the two things that could possibly change
|
||||||
|
existingAuctionView.myBidderPot = bidderPot;
|
||||||
|
existingAuctionView.myBidderMetadata = bidderMetadata;
|
||||||
|
return existingAuctionView;
|
||||||
|
}
|
||||||
|
|
||||||
let boxes: ParsedAccount<SafetyDepositBox>[] = [];
|
let boxes: ParsedAccount<SafetyDepositBox>[] = [];
|
||||||
|
|
||||||
let box =
|
let box =
|
||||||
safetyDepositBoxesByVaultAndIndex[
|
safetyDepositBoxesByVaultAndIndex[
|
||||||
auctionManager.info.vault.toBase58() + '-0'
|
auctionManager.info.vault.toBase58() + '-0'
|
||||||
|
@ -126,7 +177,7 @@ export function processAccountsIntoAuctionView(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boxes.length > 0) {
|
if (boxes.length > 0) {
|
||||||
let view: any = {
|
let view: Partial<AuctionView> = {
|
||||||
auction,
|
auction,
|
||||||
auctionManager,
|
auctionManager,
|
||||||
state,
|
state,
|
||||||
|
@ -150,13 +201,22 @@ export function processAccountsIntoAuctionView(
|
||||||
boxes[auctionManager.info.settings.openEditionConfig],
|
boxes[auctionManager.info.settings.openEditionConfig],
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
myBidderMetadata: bidderMetadata,
|
||||||
|
myBidderPot: bidderPot,
|
||||||
};
|
};
|
||||||
|
|
||||||
view.thumbnail = view.items[0] || view.openEditionItem;
|
view.thumbnail = (view.items || [])[0] || view.openEditionItem;
|
||||||
if (!view.thumbnail || !view.thumbnail.metadata) return null;
|
view.totallyComplete = !!(
|
||||||
return view;
|
view.thumbnail &&
|
||||||
|
boxesExpected == (view.items || []).length &&
|
||||||
|
(auctionManager.info.settings.openEditionConfig == null ||
|
||||||
|
(auctionManager.info.settings.openEditionConfig != null &&
|
||||||
|
view.openEditionItem))
|
||||||
|
);
|
||||||
|
if (!view.thumbnail || !view.thumbnail.metadata) return undefined;
|
||||||
|
return view as AuctionView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue