@renec-foundation/metaplex-js
Version:
Metaplex JavaScript API
113 lines (102 loc) • 3.67 kB
text/typescript
import { PublicKey, TransactionSignature } from '@solana/web3.js';
import { Wallet } from '../wallet';
import { Connection } from '../Connection';
import { Auction, AuctionExtended } from '@metaplex-foundation/mpl-auction';
import {
AuctionManager,
SafetyDepositConfig,
WinningConfigType,
} from '@metaplex-foundation/mpl-metaplex';
import { placeBid } from './placeBid';
import { claimBid } from './claimBid';
import { Vault } from '@metaplex-foundation/mpl-token-vault';
import { redeemFullRightsTransferBid } from './redeemFullRightsTransferBid';
import { redeemPrintingV2Bid } from './redeemPrintingV2Bid';
import {
isEligibleForParticipationPrize,
redeemParticipationBidV3,
} from './redeemParticipationBidV3';
import { cancelBid } from './cancelBid';
export interface InstantSaleParams {
connection: Connection;
wallet: Wallet;
auction: PublicKey;
store: PublicKey;
}
export interface InstantSaleResponse {
txIds: TransactionSignature[];
}
export const instantSale = async ({
connection,
wallet,
store,
auction,
}: InstantSaleParams): Promise<InstantSaleResponse> => {
const txIds = [];
// get data for transactions
const auctionManagerPDA = await AuctionManager.getPDA(auction);
const manager = await AuctionManager.load(connection, auctionManagerPDA);
const vault = await Vault.load(connection, manager.data.vault);
const auctionExtendedPDA = await AuctionExtended.getPDA(vault.pubkey);
const {
data: { instantSalePrice },
} = await AuctionExtended.load(connection, auctionExtendedPDA);
const [safetyDepositBox] = await vault.getSafetyDepositBoxes(connection);
const safetyDepositConfigPDA = await SafetyDepositConfig.getPDA(
auctionManagerPDA,
safetyDepositBox.pubkey,
);
const {
data: { winningConfigType, participationConfig },
} = await SafetyDepositConfig.load(connection, safetyDepositConfigPDA);
////
const { txId: placeBidTxId, bidderPotToken } = await placeBid({
connection,
wallet,
amount: instantSalePrice,
auction,
});
txIds.push(placeBidTxId);
// wait for all accounts to be created
await connection.confirmTransaction(placeBidTxId, 'finalized');
const {
data: { bidState },
} = await Auction.load(connection, auction);
const winIndex = bidState.getWinnerIndex(wallet.publicKey.toBase58());
const hasWinner = winIndex !== null;
// NOTE: it's divided into several transactions since transaction size is restricted
if (hasWinner) {
switch (winningConfigType) {
case WinningConfigType.FullRightsTransfer: {
const { txId } = await redeemFullRightsTransferBid({ connection, wallet, store, auction });
txIds.push(txId);
break;
}
case WinningConfigType.PrintingV2: {
const { txId } = await redeemPrintingV2Bid({ connection, wallet, store, auction });
txIds.push(txId);
break;
}
default:
throw new Error(`${winningConfigType} winning type isn't supported yet`);
}
const { txId: claimBidTxId } = await claimBid({
connection,
wallet,
store,
auction,
bidderPotToken,
});
txIds.push(claimBidTxId);
} else {
// if user didn't win, user must have a bid we can refund before we check for open editions
const { txId } = await cancelBid({ connection, wallet, auction, bidderPotToken });
txIds.push(txId);
}
const hasWonParticipationPrize = isEligibleForParticipationPrize(winIndex, participationConfig);
if (hasWonParticipationPrize) {
const { txIds } = await redeemParticipationBidV3({ connection, wallet, store, auction });
txIds.push(...txIds);
}
return { txIds: txIds };
};