diff --git a/README.md b/README.md index d37842f..9f4cff0 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ const rates = await new Coingecko().getRate([Currency.AR, Currency.SOL], Currenc - [x] RedeemBid - [ ] RedeemFullRightsTransferBid - [x] StartAuction + - [ ] EndAuction - [x] ClaimBid - [ ] EmptyPaymentAccount - [x] SetStore @@ -108,7 +109,6 @@ const rates = await new Coingecko().getRate([Currency.AR, Currency.SOL], Currenc - [x] InitAuctionManagerV2 - [ ] ValidateSafetyDepositBoxV2 - [ ] RedeemParticipationBidV3 - - [ ] EndAuction - [ ] SetStoreIndex - [ ] SetAuctionCache - [ ] Actions @@ -120,17 +120,15 @@ const rates = await new Coingecko().getRate([Currency.AR, Currency.SOL], Currenc - [x] Bidder Meta - [ ] Instructions - [x] CancelBid - - [ ] CreateAuctionV2 - - [ ] ClaimBid - - [ ] EndAuction - - [ ] StartAuction + - [x] CreateAuction + - [x] CreateAuctionV2 - [x] SetAuthority - [x] PlaceBid - [ ] Actions (no standalone actions) - [x] Cancel Bid - [x] Place Bid - - [ ] Redeem Bid - - [ ] Instant Sale + - [x] Redeem Bid + - [x] Instant Sale - [ ] Vault - [ ] Accounts - [x] Safety Deposit Box diff --git a/src/programs/auction/transactions/CreateAuction.ts b/src/programs/auction/transactions/CreateAuction.ts index 8e66e01..9acfa1a 100644 --- a/src/programs/auction/transactions/CreateAuction.ts +++ b/src/programs/auction/transactions/CreateAuction.ts @@ -21,6 +21,7 @@ type WinnerLimitArgs = { type: WinnerLimitType; usize: BN; }; + export class WinnerLimit extends Borsh.Data { static readonly SCHEMA = this.struct([ ['type', 'u8'], @@ -31,7 +32,7 @@ export class WinnerLimit extends Borsh.Data { usize: BN; } -type Args = { +export type Args = { winners: WinnerLimit; endAuctionAt: BN | null; auctionGap: BN | null; @@ -42,6 +43,7 @@ type Args = { tickSize: BN | null; gapTickSizePercentage: number | null; }; + export class CreateAuctionArgs extends Borsh.Data { static readonly SCHEMA = new Map([ ...WinnerLimit.SCHEMA, @@ -73,8 +75,11 @@ export class CreateAuctionArgs extends Borsh.Data { authority: StringPublicKey; /// The resource being auctioned. See AuctionData. resource: StringPublicKey; + /// Set a price floor. priceFloor: PriceFloor; + /// Add a tick size increment tickSize: BN | null; + /// Add a minimum percentage increase each bid must meet. gapTickSizePercentage: number | null; } diff --git a/src/programs/auction/transactions/CreateAuctionV2.ts b/src/programs/auction/transactions/CreateAuctionV2.ts new file mode 100644 index 0000000..ee834de --- /dev/null +++ b/src/programs/auction/transactions/CreateAuctionV2.ts @@ -0,0 +1,103 @@ +import { StringPublicKey } from '@metaplex/types'; +import { Borsh } from '@metaplex/utils'; +import { + PublicKey, + SystemProgram, + SYSVAR_RENT_PUBKEY, + TransactionCtorFields, + TransactionInstruction, +} from '@solana/web3.js'; +import BN from 'bn.js'; +import { AuctionProgram } from '../AuctionProgram'; +import { Transaction } from '../../../Transaction'; +import { PriceFloor } from '../accounts/Auction'; +import { Args as CreateAuctionArgsType, CreateAuctionArgs, WinnerLimit } from './CreateAuction'; + +type Args = CreateAuctionArgsType & { + instantSalePrice: BN | null; + name: number[] | null; +}; + +export class CreateAuctionV2Args extends Borsh.Data { + static readonly SCHEMA = new Map([ + ...CreateAuctionArgs.SCHEMA, + ...this.struct([ + ['instantSalePrice', { kind: 'option', type: 'u64' }], + ['name', { kind: 'option', type: [32] }], + ]), + ]); + + instruction = 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. + endAuctionAt: BN | null; + /// Gap time is how much time after the previous bid where the auction ends. See AuctionData. + auctionGap: BN | null; + /// Token mint for the SPL token used for bidding. + tokenMint: StringPublicKey; + /// Authority + authority: StringPublicKey; + /// The resource being auctioned. See AuctionData. + resource: StringPublicKey; + /// Set a price floor. + priceFloor: PriceFloor; + /// Add a tick size increment + tickSize: BN | null; + /// Add a minimum percentage increase each bid must meet. + gapTickSizePercentage: number | null; + /// Add a instant sale price. + instantSalePrice: BN | null; + /// Auction name + name: number[] | null; +} + +type CreateAuctionV2Params = { + auction: PublicKey; + auctionExtended: PublicKey; + creator: PublicKey; + args: CreateAuctionV2Args; +}; + +export class CreateAuctionV2 extends Transaction { + constructor(options: TransactionCtorFields, params: CreateAuctionV2Params) { + super(options); + const { args, auction, auctionExtended, creator } = params; + + const data = CreateAuctionV2Args.serialize(args); + + this.add( + new TransactionInstruction({ + keys: [ + { + pubkey: creator, + isSigner: true, + isWritable: true, + }, + { + pubkey: auction, + isSigner: false, + isWritable: true, + }, + { + pubkey: auctionExtended, + isSigner: false, + isWritable: true, + }, + { + pubkey: SYSVAR_RENT_PUBKEY, + isSigner: false, + isWritable: false, + }, + { + pubkey: SystemProgram.programId, + isSigner: false, + isWritable: false, + }, + ], + programId: AuctionProgram.PUBKEY, + data, + }), + ); + } +} diff --git a/src/programs/auction/transactions/index.ts b/src/programs/auction/transactions/index.ts index d4fee0a..8311c3f 100644 --- a/src/programs/auction/transactions/index.ts +++ b/src/programs/auction/transactions/index.ts @@ -1,4 +1,5 @@ export * from './CancelBid'; export * from './CreateAuction'; +export * from './CreateAuctionV2'; export * from './PlaceBid'; export * from './SetAuctionAuthority'; diff --git a/test/transactions/__snapshots__/auction.test.ts.snap b/test/transactions/__snapshots__/auction.test.ts.snap new file mode 100644 index 0000000..694defb --- /dev/null +++ b/test/transactions/__snapshots__/auction.test.ts.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Auction transactions CreateAuction 1`] = `"{\\"type\\":\\"Buffer\\",\\"data\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,7,93,135,29,120,250,13,109,171,35,122,77,213,58,178,208,153,32,156,150,192,153,14,177,253,172,197,7,247,216,61,254,175,187,209,148,182,34,149,175,173,192,85,175,252,231,130,76,40,175,177,44,111,250,168,3,236,149,34,236,19,46,9,66,138,155,76,202,43,34,141,168,115,82,176,65,170,75,45,110,185,97,234,236,43,234,0,144,234,95,255,33,107,30,38,145,153,130,131,135,32,113,60,44,78,85,97,231,146,60,57,129,72,71,229,99,140,205,42,175,85,79,60,2,195,134,224,132,55,6,167,213,23,25,44,92,81,33,140,201,76,61,74,241,127,88,218,238,8,155,161,253,68,227,219,217,138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,175,169,191,10,132,153,239,245,177,12,199,221,36,59,224,20,103,70,219,249,150,85,157,145,130,193,93,188,24,246,87,131,79,219,30,88,36,153,69,200,48,40,136,227,246,197,102,213,141,122,4,186,57,98,62,139,154,145,152,59,13,211,149,1,6,5,1,2,3,4,5,168,1,1,1,1,0,0,0,0,0,0,0,1,195,115,146,97,0,0,0,0,1,30,0,0,0,0,0,0,0,113,178,77,47,3,206,165,188,130,225,172,175,199,64,162,55,188,104,159,223,218,116,88,247,167,60,131,209,170,44,208,98,70,65,21,141,143,89,143,146,210,57,211,217,223,24,20,153,223,130,92,14,226,188,44,87,44,70,212,74,67,174,21,67,151,236,219,224,54,47,112,197,46,29,246,29,105,42,66,214,178,206,61,219,206,132,245,159,159,124,100,29,253,0,131,115,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,0,0,0,0,0,0,1,1]}"`; + +exports[`Auction transactions CreateAuctionV2 1`] = `"{\\"type\\":\\"Buffer\\",\\"data\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,7,93,135,29,120,250,13,109,171,35,122,77,213,58,178,208,153,32,156,150,192,153,14,177,253,172,197,7,247,216,61,254,175,187,209,148,182,34,149,175,173,192,85,175,252,231,130,76,40,175,177,44,111,250,168,3,236,149,34,236,19,46,9,66,138,155,76,202,43,34,141,168,115,82,176,65,170,75,45,110,185,97,234,236,43,234,0,144,234,95,255,33,107,30,38,145,153,130,131,135,32,113,60,44,78,85,97,231,146,60,57,129,72,71,229,99,140,205,42,175,85,79,60,2,195,134,224,132,55,6,167,213,23,25,44,92,81,33,140,201,76,61,74,241,127,88,218,238,8,155,161,253,68,227,219,217,138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,175,169,191,10,132,153,239,245,177,12,199,221,36,59,224,20,103,70,219,249,150,85,157,145,130,193,93,188,24,246,87,131,79,219,30,88,36,153,69,200,48,40,136,227,246,197,102,213,141,122,4,186,57,98,62,139,154,145,152,59,13,211,149,1,6,5,1,2,3,4,5,10,1,0,202,154,59,0,0,0,0,0]}"`; diff --git a/test/transactions/auction.test.ts b/test/transactions/auction.test.ts new file mode 100644 index 0000000..faa7af6 --- /dev/null +++ b/test/transactions/auction.test.ts @@ -0,0 +1,72 @@ +import BN from 'bn.js'; +import { LAMPORTS_PER_SOL } from '@solana/web3.js'; +import { + AUCTION_EXTENDED_PUBKEY, + AUCTION_PUBKEY, + FEE_PAYER, + mockTransaction, + NEW_AUTHORITY_PUBKEY, + serializeConfig, + TOKEN_MINT_PUBKEY, + VAULT_PUBKEY, +} from '../utils'; +import { + CreateAuctionV2, + CreateAuctionV2Args, +} from '../../src/programs/auction/transactions/CreateAuctionV2'; +import { + CreateAuction, + CreateAuctionArgs, + PriceFloor, + PriceFloorType, + WinnerLimit, + WinnerLimitType, +} from '../../src/programs/auction'; + +describe('Auction transactions', () => { + test('CreateAuction', async () => { + const data = new CreateAuction(mockTransaction, { + auction: AUCTION_PUBKEY, + auctionExtended: AUCTION_EXTENDED_PUBKEY, + creator: FEE_PAYER.publicKey, + args: new CreateAuctionArgs({ + winners: new WinnerLimit({ type: WinnerLimitType.Capped, usize: new BN(1) }), + endAuctionAt: new BN(1636987843), + auctionGap: new BN(30), + tokenMint: TOKEN_MINT_PUBKEY.toString(), + authority: NEW_AUTHORITY_PUBKEY.toString(), + resource: VAULT_PUBKEY.toString(), + priceFloor: new PriceFloor({ type: PriceFloorType.Minimum }), + tickSize: new BN(10), + gapTickSizePercentage: 1, + }), + }); + + const serializedData = data.serialize(serializeConfig); + expect(JSON.stringify(serializedData)).toMatchSnapshot(); + }); + + test('CreateAuctionV2', async () => { + const data = new CreateAuctionV2(mockTransaction, { + auction: AUCTION_PUBKEY, + auctionExtended: AUCTION_EXTENDED_PUBKEY, + creator: FEE_PAYER.publicKey, + args: new CreateAuctionV2Args({ + winners: new WinnerLimit({ type: WinnerLimitType.Capped, usize: new BN(1) }), + endAuctionAt: new BN(1636987843), + auctionGap: new BN(30), + tokenMint: TOKEN_MINT_PUBKEY.toString(), + authority: NEW_AUTHORITY_PUBKEY.toString(), + resource: VAULT_PUBKEY.toString(), + priceFloor: new PriceFloor({ type: PriceFloorType.Minimum }), + tickSize: new BN(10), + gapTickSizePercentage: 1, + instantSalePrice: new BN(LAMPORTS_PER_SOL), + name: null, + }), + }); + + const serializedData = data.serialize(serializeConfig); + expect(JSON.stringify(serializedData)).toMatchSnapshot(); + }); +});