Working on instant sale
This commit is contained in:
parent
b4f5b4b29b
commit
bf22676c2c
|
@ -373,10 +373,14 @@ export interface IPartialCreateAuctionArgs {
|
|||
tickSize: BN | null;
|
||||
|
||||
gapTickSizePercentage: number | null;
|
||||
|
||||
instantSalePrice: BN | null;
|
||||
|
||||
name: number[] | null;
|
||||
}
|
||||
|
||||
export class CreateAuctionArgs implements IPartialCreateAuctionArgs {
|
||||
instruction: number = 1;
|
||||
instruction: number = 7;
|
||||
/// How many winners are allowed for this auction. See AuctionData.
|
||||
winners: WinnerLimit;
|
||||
/// End time is the cut-off point that the auction is forced to end by. See AuctionData.
|
||||
|
@ -396,6 +400,10 @@ export class CreateAuctionArgs implements IPartialCreateAuctionArgs {
|
|||
|
||||
gapTickSizePercentage: number | null;
|
||||
|
||||
instantSalePrice: BN | null;
|
||||
|
||||
name: number[] | null;
|
||||
|
||||
constructor(args: {
|
||||
winners: WinnerLimit;
|
||||
endAuctionAt: BN | null;
|
||||
|
@ -406,6 +414,8 @@ export class CreateAuctionArgs implements IPartialCreateAuctionArgs {
|
|||
priceFloor: PriceFloor;
|
||||
tickSize: BN | null;
|
||||
gapTickSizePercentage: number | null;
|
||||
name: number[] | null;
|
||||
instantSalePrice: BN | null;
|
||||
}) {
|
||||
this.winners = args.winners;
|
||||
this.endAuctionAt = args.endAuctionAt;
|
||||
|
@ -416,6 +426,8 @@ export class CreateAuctionArgs implements IPartialCreateAuctionArgs {
|
|||
this.priceFloor = args.priceFloor;
|
||||
this.tickSize = args.tickSize;
|
||||
this.gapTickSizePercentage = args.gapTickSizePercentage;
|
||||
this.name = args.name;
|
||||
this.instantSalePrice = args.instantSalePrice;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,6 +480,8 @@ export const AUCTION_SCHEMA = new Map<any, any>([
|
|||
['priceFloor', PriceFloor],
|
||||
['tickSize', { kind: 'option', type: 'u64' }],
|
||||
['gapTickSizePercentage', { kind: 'option', type: 'u8' }],
|
||||
['instantSalePrice', { kind: 'option', type: 'u64' }],
|
||||
['name', { kind: 'option', type: [32] }],
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -545,6 +559,8 @@ export const AUCTION_SCHEMA = new Map<any, any>([
|
|||
['totalUncancelledBids', 'u64'],
|
||||
['tickSize', { kind: 'option', type: 'u64' }],
|
||||
['gapTickSizePercentage', { kind: 'option', type: 'u8' }],
|
||||
['instantSalePrice', { kind: 'option', type: 'u64' }],
|
||||
['name', { kind: 'option', type: [32] }],
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -237,7 +237,20 @@ export class Metadata {
|
|||
}
|
||||
|
||||
public async init() {
|
||||
const edition = await getEdition(this.mint);
|
||||
const edition: PublicKey;
|
||||
if (this.info.editionNonce != null) {
|
||||
edition = await PublicKey.createProgramAddress(
|
||||
[
|
||||
Buffer.from(METADATA_PREFIX),
|
||||
METADATA_PROGRAM_ID.toBuffer(),
|
||||
tempCache.metadata[i].info.mint.toBuffer(),
|
||||
new Uint8Array([tempCache.metadata[i].info.editionNonce || 0]),
|
||||
],
|
||||
METADATA_PROGRAM_ID,
|
||||
);
|
||||
} else {
|
||||
edition = await getEdition(tempCache.metadata[i].info.mint);
|
||||
}
|
||||
this.edition = edition;
|
||||
this.masterEdition = edition;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import { getAuctionExtended, programIds } from '@oyster/common';
|
||||
import {
|
||||
PublicKey,
|
||||
SYSVAR_CLOCK_PUBKEY,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { serialize } from 'borsh';
|
||||
|
||||
import { EndAuctionArgs, getAuctionKeys, SCHEMA } from '.';
|
||||
|
||||
export async function endAuction(
|
||||
vault: PublicKey,
|
||||
auctionManagerAuthority: PublicKey,
|
||||
instructions: TransactionInstruction[],
|
||||
) {
|
||||
const PROGRAM_IDS = programIds();
|
||||
const store = PROGRAM_IDS.store;
|
||||
if (!store) {
|
||||
throw new Error('Store not initialized');
|
||||
}
|
||||
|
||||
const { auctionKey, auctionManagerKey } = await getAuctionKeys(vault);
|
||||
const auctionExtended = await getAuctionExtended({
|
||||
auctionProgramId: PROGRAM_IDS.auction,
|
||||
resource: vault,
|
||||
});
|
||||
const value = new EndAuctionArgs({ reveal: null });
|
||||
const data = Buffer.from(serialize(SCHEMA, value));
|
||||
|
||||
const keys = [
|
||||
{
|
||||
pubkey: auctionManagerKey,
|
||||
isSigner: false,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: auctionKey,
|
||||
isSigner: false,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: auctionExtended,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: auctionManagerAuthority,
|
||||
isSigner: true,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: store,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: PROGRAM_IDS.auction,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: SYSVAR_CLOCK_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
|
||||
instructions.push(
|
||||
new TransactionInstruction({
|
||||
keys,
|
||||
programId: PROGRAM_IDS.metaplex,
|
||||
data,
|
||||
}),
|
||||
);
|
||||
}
|
|
@ -320,6 +320,15 @@ export class RedeemFullRightsTransferBidArgs {
|
|||
export class StartAuctionArgs {
|
||||
instruction = 5;
|
||||
}
|
||||
|
||||
export class EndAuctionArgs {
|
||||
instruction = 21;
|
||||
reveal: BN[] | null;
|
||||
constructor(args: { reveal: BN[] | null }) {
|
||||
this.reveal = args.reveal;
|
||||
}
|
||||
}
|
||||
|
||||
export class ClaimBidArgs {
|
||||
instruction = 6;
|
||||
}
|
||||
|
@ -953,6 +962,16 @@ export const SCHEMA = new Map<any, any>([
|
|||
fields: [['instruction', 'u8']],
|
||||
},
|
||||
],
|
||||
[
|
||||
EndAuctionArgs,
|
||||
{
|
||||
kind: 'struct',
|
||||
fields: [
|
||||
['instruction', 'u8'],
|
||||
['reveal', { kind: 'option', type: [BN] }],
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
ClaimBidArgs,
|
||||
{
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { findProgramAddress, programIds, VAULT_PREFIX } from '@oyster/common';
|
||||
import {
|
||||
findProgramAddress,
|
||||
getAuctionExtended,
|
||||
programIds,
|
||||
VAULT_PREFIX,
|
||||
} from '@oyster/common';
|
||||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
|
@ -63,6 +68,11 @@ export async function redeemBid(
|
|||
safetyDeposit,
|
||||
);
|
||||
|
||||
const auctionExtended = await getAuctionExtended({
|
||||
auctionProgramId: PROGRAM_IDS.auction,
|
||||
resource: vault,
|
||||
});
|
||||
|
||||
const value =
|
||||
auctioneerReclaimIndex !== undefined
|
||||
? new RedeemUnusedWinningConfigItemsAsAuctioneerArgs({
|
||||
|
@ -167,6 +177,11 @@ export async function redeemBid(
|
|||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: auctionExtended,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
|
||||
if (isPrintingType && masterEdition && reservationList) {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { programIds, VAULT_PREFIX, findProgramAddress } from '@oyster/common';
|
||||
import {
|
||||
programIds,
|
||||
VAULT_PREFIX,
|
||||
findProgramAddress,
|
||||
getAuctionExtended,
|
||||
} from '@oyster/common';
|
||||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
|
@ -62,6 +67,11 @@ export async function redeemFullRightsTransferBid(
|
|||
safetyDeposit,
|
||||
);
|
||||
|
||||
const auctionExtended = await getAuctionExtended({
|
||||
auctionProgramId: PROGRAM_IDS.auction,
|
||||
resource: vault,
|
||||
});
|
||||
|
||||
const value =
|
||||
auctioneerReclaimIndex !== undefined
|
||||
? new RedeemUnusedWinningConfigItemsAsAuctioneerArgs({
|
||||
|
@ -176,6 +186,12 @@ export async function redeemFullRightsTransferBid(
|
|||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
|
||||
{
|
||||
pubkey: auctionExtended,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
|
||||
instructions.push(
|
||||
|
|
|
@ -36,14 +36,7 @@ import { Connection, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js';
|
|||
import { MintLayout } from '@solana/spl-token';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { capitalize } from 'lodash';
|
||||
import {
|
||||
WinningConfigType,
|
||||
NonWinningConstraint,
|
||||
WinningConstraint,
|
||||
ParticipationConfigV2,
|
||||
SafetyDepositConfig,
|
||||
AmountRange,
|
||||
} from '../../models/metaplex';
|
||||
import { WinningConfigType, AmountRange } from '../../models/metaplex';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
createAuctionManager,
|
||||
|
@ -124,6 +117,8 @@ export interface AuctionState {
|
|||
tiers?: Array<Tier>;
|
||||
|
||||
winnersCount: number;
|
||||
|
||||
instantSalePrice?: number;
|
||||
}
|
||||
|
||||
export const AuctionCreateView = () => {
|
||||
|
@ -413,6 +408,10 @@ export const AuctionCreateView = () => {
|
|||
tickSize: attributes.priceTick
|
||||
? new BN(attributes.priceTick * LAMPORTS_PER_SOL)
|
||||
: null,
|
||||
instantSalePrice: attributes.instantSalePrice
|
||||
? new BN((attributes.instantSalePrice || 0) * LAMPORTS_PER_SOL)
|
||||
: null,
|
||||
name: null,
|
||||
};
|
||||
|
||||
const _auctionObj = await createAuctionManager(
|
||||
|
@ -856,6 +855,22 @@ const SaleTypeStep = (props: {
|
|||
Allow bidding on your NFT(s).
|
||||
</div>
|
||||
</Radio.Group>
|
||||
<Radio.Group
|
||||
defaultValue={props.attributes.saleType}
|
||||
onChange={info =>
|
||||
props.setAttributes({
|
||||
...props.attributes,
|
||||
saleType: info.target.value,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Radio className="radio-field" value="auction">
|
||||
Instant Sale
|
||||
</Radio>
|
||||
<div className="radio-subtitle">
|
||||
Instant purchase and redemption of your NFT.
|
||||
</div>
|
||||
</Radio.Group>
|
||||
</label>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -898,13 +913,13 @@ const PriceSale = (props: {
|
|||
<>
|
||||
<Row className="call-to-action">
|
||||
<h2>Price</h2>
|
||||
<p>Set the price for your auction.</p>
|
||||
<p>Set the fixed price for your instant sale.</p>
|
||||
</Row>
|
||||
<Row className="content-action">
|
||||
<label className="action-field">
|
||||
<span className="field-title">Sale price</span>
|
||||
<span className="field-info">
|
||||
This is the starting bid price for your auction.
|
||||
This is the price of purchasing the item(s).
|
||||
</span>
|
||||
<Input
|
||||
type="number"
|
||||
|
@ -917,7 +932,8 @@ const PriceSale = (props: {
|
|||
onChange={info =>
|
||||
props.setAttributes({
|
||||
...props.attributes,
|
||||
price: parseFloat(info.target.value) || undefined,
|
||||
priceFloor: parseFloat(info.target.value),
|
||||
instantSalePrice: parseFloat(info.target.value),
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
@ -1228,7 +1244,10 @@ const EndingPhaseAuction = (props: {
|
|||
<Row className="content-action">
|
||||
<Col className="section" xl={24}>
|
||||
<div className="action-field">
|
||||
<span className="field-title">Auction Duration</span>
|
||||
<span className="field-title">
|
||||
{props.attributes.saleType == 'auction' ? 'Auction' : 'Sale'}{' '}
|
||||
Duration
|
||||
</span>
|
||||
<span className="field-info">
|
||||
This is how long the auction will last for.
|
||||
</span>
|
||||
|
@ -1261,12 +1280,14 @@ const EndingPhaseAuction = (props: {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{props.attributes.saleType == 'auction' && (
|
||||
<>
|
||||
<div className="action-field">
|
||||
<span className="field-title">Gap Time</span>
|
||||
<span className="field-info">
|
||||
The final phase of the auction will begin when there is this much
|
||||
time left on the countdown. Any bids placed during the final phase
|
||||
will extend the end time by this same duration.
|
||||
The final phase of the auction will begin when there is this
|
||||
much time left on the countdown. Any bids placed during the
|
||||
final phase will extend the end time by this same duration.
|
||||
</span>
|
||||
<Input
|
||||
addonAfter={
|
||||
|
@ -1299,9 +1320,9 @@ const EndingPhaseAuction = (props: {
|
|||
<label className="action-field">
|
||||
<span className="field-title">Tick Size for Ending Phase</span>
|
||||
<span className="field-info">
|
||||
In order for winners to move up in the auction, they must place a
|
||||
bid that’s at least this percentage higher than the next highest
|
||||
bid.
|
||||
In order for winners to move up in the auction, they must
|
||||
place a bid that’s at least this percentage higher than the
|
||||
next highest bid.
|
||||
</span>
|
||||
<Input
|
||||
type="number"
|
||||
|
@ -1316,6 +1337,8 @@ const EndingPhaseAuction = (props: {
|
|||
}
|
||||
/>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
|
|
|
@ -45,10 +45,10 @@ pub struct CreateAuctionArgsV2 {
|
|||
pub tick_size: Option<u64>,
|
||||
/// Add a minimum percentage increase each bid must meet.
|
||||
pub gap_tick_size_percentage: Option<u8>,
|
||||
/// Auction name
|
||||
pub name: AuctionName,
|
||||
/// Add a instant sale price.
|
||||
pub instant_sale_price: Option<u64>,
|
||||
/// Auction name
|
||||
pub name: Option<AuctionName>,
|
||||
}
|
||||
|
||||
struct Accounts<'a, 'b: 'a> {
|
||||
|
@ -94,6 +94,6 @@ pub fn create_auction_v2(
|
|||
gap_tick_size_percentage: args.gap_tick_size_percentage,
|
||||
},
|
||||
args.instant_sale_price,
|
||||
Some(args.name),
|
||||
args.name,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue