├── Cargo.toml
├── .DS_Store
├── programs
└── nut_marketplace
│ ├── Xargo.toml
│ ├── src
│ ├── constants.rs
│ ├── account.rs
│ └── error.rs
│ └── Cargo.toml
├── .prettierignore
├── target
├── deploy
│ ├── nut_marketplace.so
│ └── nut_marketplace-keypair.json
└── idl
│ └── nut_marketplace.json
├── .gitignore
├── tsconfig.json
├── Anchor.toml
├── migrations
└── deploy.ts
├── package.json
├── lib
├── types.ts
└── utils.ts
├── README.md
├── cli
├── be.ts
├── command.ts
└── scripts.ts
├── tests
└── nut_marketplace.ts
└── Cargo.lock
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "programs/*"
4 | ]
5 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/whisdev/magiceden-nutmarket/HEAD/.DS_Store
--------------------------------------------------------------------------------
/programs/nut_marketplace/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/target/deploy/nut_marketplace.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/whisdev/magiceden-nutmarket/HEAD/target/deploy/nut_marketplace.so
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .anchor
3 | .DS_Store
4 | target/bpfel*/
5 | target/debug/
6 | target/release/
7 | target/rls/
8 | target/*.*
9 | programs/**/target/
10 | dist/
11 | build/
12 | test-ledger/
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "types": ["mocha", "chai"],
4 | "typeRoots": ["./node_modules/@types"],
5 | "lib": ["es2015"],
6 | "module": "commonjs",
7 | "target": "es6",
8 | "esModuleInterop": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/target/deploy/nut_marketplace-keypair.json:
--------------------------------------------------------------------------------
1 | [125,195,174,34,205,50,107,154,129,35,171,176,178,178,28,79,65,29,61,246,184,175,21,43,58,242,7,226,198,131,46,205,31,125,212,197,234,176,38,97,51,170,223,71,58,140,185,98,64,151,189,129,196,176,240,46,69,230,103,242,119,155,241,130]
--------------------------------------------------------------------------------
/Anchor.toml:
--------------------------------------------------------------------------------
1 | [features]
2 | seeds = false
3 | [programs.devnet]
4 | nut_marketplace = "37vvcTUnSSstVDgzd1jhujmpbw3jtw8ioi3mB7YfZJuP"
5 |
6 | [registry]
7 | url = "https://anchor.projectserum.com"
8 |
9 | [provider]
10 | # cluster = "http://127.0.0.1:8899"
11 | cluster = "localnet"
12 | wallet = "/home/ubuntu/fury/deploy-keypair.json"
13 |
14 | [scripts]
15 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
16 |
--------------------------------------------------------------------------------
/programs/nut_marketplace/src/constants.rs:
--------------------------------------------------------------------------------
1 | pub const GLOBAL_AUTHORITY_SEED: &str = "global-authority-v1";
2 | pub const SELL_DATA_SEED: &str = "sell-info-v1";
3 | pub const OFFER_DATA_SEED: &str = "offer-info-v1";
4 | pub const USER_DATA_SEED: &str = "user-info-v1";
5 | pub const AUCTION_DATA_SEED: &str = "auction-info-v1";
6 | pub const ESCROW_VAULT_SEED: &str = "escrow-vault";
7 |
8 | pub const PERMYRIAD: u64 = 10_000; // Permyriad Measure Unit
--------------------------------------------------------------------------------
/migrations/deploy.ts:
--------------------------------------------------------------------------------
1 | // Migrations are an early feature. Currently, they're nothing more than this
2 | // single deploy script that's invoked from the CLI, injecting a provider
3 | // configured from the workspace's Anchor.toml.
4 |
5 | const anchor = require("@project-serum/anchor");
6 |
7 | module.exports = async function (provider) {
8 | // Configure client to use the provider.
9 | anchor.setProvider(provider);
10 |
11 | // Add your deploy script here.
12 | };
13 |
--------------------------------------------------------------------------------
/programs/nut_marketplace/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "nut_marketplace"
3 | version = "0.1.0"
4 | description = "Created with Anchor"
5 | edition = "2021"
6 |
7 | [lib]
8 | crate-type = ["cdylib", "lib"]
9 | name = "nut_marketplace"
10 |
11 | [features]
12 | no-entrypoint = []
13 | no-idl = []
14 | no-log-ix-name = []
15 | cpi = ["no-entrypoint"]
16 | default = []
17 |
18 | [profile.release]
19 | overflow-checks = true
20 |
21 | [dependencies]
22 | anchor-lang = "0.24.2"
23 | anchor-spl = "0.24.2"
24 | metaplex-token-metadata = { version = "0.0.1", features = ["no-entrypoint"] }
25 | spl-associated-token-account = {version = "1.0.3", features = [ "no-entrypoint" ]}
26 | solana-program = "1.9.5"
27 | spl-token = "3.3.0"
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check",
5 | "ts-node": "export ANCHOR_WALLET=/home/root/fury/deploy-231218.json&& ts-node ./cli/command.ts",
6 | "be": "export ANCHOR_WALLET=/home/root/fury/deploy-231218.json&& ts-node ./cli/be.ts"
7 | },
8 | "dependencies": {
9 | "@metaplex/js": "^4.12.0",
10 | "@project-serum/anchor": "^0.24.2",
11 | "@solana/spl-token": "^0.1.8",
12 | "commander": "^9.1.0",
13 | "fs": "^0.0.1-security"
14 | },
15 | "devDependencies": {
16 | "@types/bn.js": "^5.1.0",
17 | "@types/chai": "^4.3.0",
18 | "@types/mocha": "^9.0.0",
19 | "chai": "^4.3.4",
20 | "mocha": "^9.0.3",
21 | "prettier": "^2.6.2",
22 | "ts-mocha": "^8.0.0",
23 | "typescript": "^4.3.5"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/programs/nut_marketplace/src/account.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[account]
4 | #[derive(Default)]
5 | pub struct GlobalPool {
6 | // 8 + 368
7 | pub super_admin: Pubkey, // 32
8 | pub market_fee_sol: u64, // 8 Permyriad
9 | pub team_count: u64, // 8
10 | pub team_treasury: [Pubkey; 8], // 8 * 32
11 | pub treasury_rate: [u64; 8], // 8 * 8
12 | }
13 |
14 | #[account]
15 | #[derive(Default)]
16 | pub struct SellData {
17 | // 8 + 120
18 | pub mint: Pubkey, // 32
19 | pub seller: Pubkey, // 32
20 | pub collection: Pubkey, // 32
21 | pub price_sol: u64, // 8
22 | pub listed_date: i64, // 8
23 | pub active: u64, // 8
24 | }
25 |
26 | #[account]
27 | #[derive(Default)]
28 | pub struct OfferData {
29 | // 8 + 88
30 | pub mint: Pubkey, // 32
31 | pub buyer: Pubkey, // 32
32 | pub offer_price: u64, // 8
33 | pub offer_listing_date: i64, // 8
34 | pub active: u64, // 8
35 | }
36 |
37 | #[account]
38 | #[derive(Default)]
39 | pub struct AuctionData {
40 | // 8 + 152
41 | pub mint: Pubkey, // 32
42 | pub creator: Pubkey, // 32
43 | pub start_price: u64, // 8
44 | pub min_increase_amount: u64, // 8
45 | pub start_date: i64, // 8
46 | pub last_bid_date: i64, // 8
47 | pub last_bidder: Pubkey, // 32
48 | pub highest_bid: u64, // 8
49 | pub duration: i64, // 8
50 | // 0-canceled, 1-started, 2-claimed, 3-reserved
51 | pub status: u64, // 8
52 | }
53 |
54 | #[account]
55 | #[derive(Default)]
56 | pub struct UserData {
57 | // 8 + 48
58 | pub address: Pubkey, // 32
59 | pub traded_volume: u64, // 8
60 | pub escrow_sol_balance: u64, // 8
61 | }
62 |
63 | impl AuctionData {
64 | pub fn get_end_date(&self) -> i64 {
65 | self.start_date + self.duration
66 | }
67 | }
--------------------------------------------------------------------------------
/lib/types.ts:
--------------------------------------------------------------------------------
1 | import * as anchor from '@project-serum/anchor';
2 | import { PublicKey } from '@solana/web3.js';
3 |
4 | export const GLOBAL_AUTHORITY_SEED = "global-authority-v1";
5 | export const SELL_DATA_SEED = "sell-info-v1";
6 | export const SELL_DATA_SIZE = 128;
7 | export const OFFER_DATA_SEED = "offer-info-v1";
8 | export const OFFER_DATA_SIZE = 96;
9 | export const USER_DATA_SEED = "user-info-v1";
10 | export const AUCTION_DATA_SEED = "auction-info-v1";
11 | export const AUCTION_DATA_SIZE = 160;
12 | export const ESCROW_VAULT_SEED = "escrow-vault";
13 |
14 | export const MARKETPLACE_PROGRAM_ID = new PublicKey("37vvcTUnSSstVDgzd1jhujmpbw3jtw8ioi3mB7YfZJuP");
15 |
16 | export interface GlobalPool {
17 | // 8 + 368
18 | superAdmin: PublicKey, // 32
19 | marketFeeSol: anchor.BN, // 8
20 | teamCount: anchor.BN, // 8
21 | teamTreasury: PublicKey[], // 8 * 32
22 | treasuryRate: anchor.BN[], // 8 * 8
23 | }
24 |
25 | export interface SellData {
26 | // 8 + 120
27 | mint: PublicKey, // 32
28 | seller: PublicKey, // 32
29 | collection: PublicKey, // 32
30 | priceSol: anchor.BN, // 8
31 | listedDate: anchor.BN, // 8
32 | active: anchor.BN, // 8
33 | }
34 |
35 | export interface OfferData {
36 | // 8 + 88
37 | mint: PublicKey, // 32
38 | buyer: PublicKey, // 32
39 | offerPrice: anchor.BN, // 8
40 | offerListingDate: anchor.BN, // 8
41 | active: anchor.BN, // 8
42 | }
43 |
44 | export interface AuctionData {
45 | // 8 + 152
46 | mint: PublicKey, // 32
47 | creator: PublicKey, // 32
48 | startPrice: anchor.BN, // 8
49 | minIncreaseAmount: anchor.BN, // 8
50 | startDate: anchor.BN, // 8
51 | lastBidDate: anchor.BN, // 8
52 | lastBidder: PublicKey, // 32
53 | highestBid: anchor.BN, // 8
54 | duration: anchor.BN, // 8
55 | status: anchor.BN, // 8
56 | }
57 |
58 | export interface UserData {
59 | // 8 + 48
60 | address: PublicKey, // 32
61 | tradedVolume: anchor.BN, // 8
62 | escrowSolBalance: anchor.BN, // 8
63 | }
--------------------------------------------------------------------------------
/programs/nut_marketplace/src/error.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[error_code]
4 | pub enum MarketplaceError {
5 | // 0x1770 - 0
6 | #[msg("Invalid Super Owner")]
7 | InvalidSuperOwner,
8 | // 0x1771
9 | #[msg("Invalid Owner")]
10 | InvalidOwner,
11 | // 0x1772
12 | #[msg("Invalid Global Pool Address")]
13 | InvalidGlobalPool,
14 | // 0x1773
15 | #[msg("Marketplace Fee is Permyriad")]
16 | InvalidFeePercent,
17 |
18 | // 0x1774
19 | #[msg("Max Team Count is 8")]
20 | MaxTeamCountExceed,
21 | // 0x1775 - 5
22 | #[msg("Treasury Wallet Not Configured")]
23 | NoTeamTreasuryYet,
24 | // 0x1776
25 | #[msg("Treasury Address Not Exist")]
26 | TreasuryAddressNotFound,
27 | // 0x1777
28 | #[msg("Treasury Address Already Exist")]
29 | TreasuryAddressAlreadyAdded,
30 | // 0x1778
31 | #[msg("Total Treasury Rate Sum Should Less Than 100%")]
32 | MaxTreasuryRateSumExceed,
33 | // 0x1779
34 | #[msg("Team Treasury Wallet Count Mismatch")]
35 | TeamTreasuryCountMismatch,
36 | // 0x177a - 10
37 | #[msg("Team Treasury Wallet Address Mismatch")]
38 | TeamTreasuryAddressMismatch,
39 |
40 | // 0x177b
41 | #[msg("Uninitialized Account")]
42 | Uninitialized,
43 | // 0x177c
44 | #[msg("Instruction Parameter is Invalid")]
45 | InvalidParamInput,
46 |
47 | // 0x177d
48 | #[msg("Payer Mismatch with NFT Seller")]
49 | SellerMismatch,
50 | // 0x177e
51 | #[msg("Invalid NFT Data Account")]
52 | InvalidNFTDataAcount,
53 | // 0x177f - 15
54 | #[msg("The NFT Is Not Listed")]
55 | NotListedNFT,
56 |
57 | // 0x1780
58 | #[msg("Seller Account Mismatch with NFT Seller Data")]
59 | SellerAccountMismatch,
60 | // 0x1781
61 | #[msg("Buyer Sol Balance is Less than NFT SOL Price")]
62 | InsufficientBuyerSolBalance,
63 | // 0x1782
64 | #[msg("Buyer Token Balance is Less than NFT Token Price")]
65 | InsufficientBuyerTokenBalance,
66 |
67 | // 0x1783
68 | #[msg("Invalid Metadata Address")]
69 | InvaliedMetadata,
70 | // 0x1784 - 20
71 | #[msg("Can't Parse The NFT's Creators")]
72 | MetadataCreatorParseError,
73 |
74 | // 0x1785
75 | #[msg("Offer Data Mint mismatch with NFT Pubkey")]
76 | InvalidOfferDataMint,
77 | // 0x1786
78 | #[msg("Offer Data Buyer mismatch with Payer Pubkey")]
79 | InvalidOfferDataBuyer,
80 | // 0x1787
81 | #[msg("Making Offer for Not Listed NFT")]
82 | OfferForNotListedNFT,
83 | // 0x1788
84 | #[msg("Offer Price Over Thank Listed Price")]
85 | InvalidOfferPrice,
86 | // 0x1789 - 25
87 | #[msg("Already Canceled Offer")]
88 | DisabledOffer,
89 | // 0x178a
90 | #[msg("Offer For Sold Or Canceled NFT Listing")]
91 | OfferForExpiredListingNFT,
92 |
93 | // 0x178b
94 | #[msg("Placing Bid For Ended Auction")]
95 | EndedAuction,
96 | // 0x178c
97 | #[msg("Placing Bid With Lower Than Highest Bid")]
98 | InvalidBidPrice,
99 | // 0x178d
100 | #[msg("Placing Bid Double From One Bidder")]
101 | DoubleBidFromOneBidder,
102 | // 0x178e - 30
103 | #[msg("Out Bidder Account Mismatch With LastBidder Data")]
104 | OutBidderMismatch,
105 | // 0x178f
106 | #[msg("Claiming Auction For Not Ended Auction")]
107 | NotEndedAuction,
108 | // 0x1790
109 | #[msg("Creator Account Mismatch with Auction Data")]
110 | CreatorAccountMismatch,
111 | // 0x1791
112 | #[msg("Bidder Account Mismatch with Auction Data")]
113 | BidderAccountMismatch,
114 | // 0x1792
115 | #[msg("Canceling Auction which has Bid")]
116 | AuctionHasBid,
117 | // 0x1793
118 | #[msg("Placing Bid From Auction Creator")]
119 | BidFromAuctionCreator,
120 |
121 | // 0x1794
122 | #[msg("Only Listing and Reserved Auction are possible to exist together")]
123 | ListingNotAvailable,
124 | // 0x1795
125 | #[msg("NFT Is Not In User ATA")]
126 | NFTIsNotInUserATA,
127 | // 0x1796
128 | #[msg("NFT Is Not In Escrow ATA")]
129 | NFTIsNotInEscrowATA,
130 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nut-Marketplace-Contract
2 | Solana NFT Marketplace program with NFT Trading & Auction
3 |
4 | ## Prerequirements
5 |
6 | Need to build up anchor development environment
7 | ```
8 | anchor version 0.24.2
9 | solana version 1.14.17
10 | node version 18.17.0
11 | ```
12 |
13 | ## Program Deployment
14 |
15 | - Prepare anchor development environments
16 | - Prepare aroun 12 SOL in the deploy wallet keypair
17 | - Confirm Network cluster in `Anchor.toml` file : f.e. `[programs.devnet]`, `cluster = "devnet"`
18 | - Confirm deploy authority wallet keypair location : f.e. `wallet = "/home/ubuntu/deploy-keypair.json"
19 | - Configure solana cli with deploy authority keypair and deploying cluster : f.e. `solana config set -h`
20 | - Build program with `anchor build`
21 | - Copy and paste the result deploy scripts from Build terminal message : f.e. `solana program deploy /home/ubuntu/project/target/deploy/nut_marketplace.so`
22 |
23 | ### To Change Program Address
24 |
25 | - Delete the program keypair in `/target/deploy/nut_marketplace-keypair.json`
26 | - Build project with `anchor build`. This will generate new keypair
27 | - Get the address of new keypair with `solana address --keypair ./target/deploy/nut_marketplace-keypair.json`
28 | - Change program addresses in project code. `Anchor.toml`, `/program/nut_marketplace/src/lib.rs`
29 | - Build program object again with `anchor build`
30 | - Deploy newly built so file with `solana program deploy`
31 |
32 | ## Cli Command usage
33 |
34 | Able to run all commands in `/cli/command.ts` file by running `yarn ts-node xxx`.
35 | When you get this error
36 | `Error: Provider local is not available on browser.`
37 | You can run this command `export BROWSER=` once.
38 |
39 | ### Install Dependencies
40 |
41 | - Install `node` and `yarn`
42 | - Install `ts-node` as global command
43 | - Confirm the solana wallet preparation in `package.json`: `/home/fury/.config/solana/id.json` in test case
44 |
45 | ### Init Program
46 |
47 | - Initialize program with `init` command
48 | - Should configure the marketplace fee with `update_fee` command
49 | - Should add at least one `treasury` wallet with `add_treasury` command for the fee distribution
50 | - Should Initialize user PDA with `init_user` command for the first time usage
51 |
52 | ## Commands Help
53 |
54 | ### init
55 | Initialize Program with creating Global PDA account as Contract Deployer.
56 |
57 | ### status
58 | Get global PDA info of program. This will show marketplace fee the treasury wallet distributions.
59 |
60 | ### update_fee
61 | Admin able to update the Marketplace Fee with this command as Admin.
62 | - `sol_fee` is the fee in permyraid
63 |
64 | ### add_treasury
65 | Admin able to add the team treasury wallet distribution rate for the marketplace fee charge.
66 | - `address` is the treasury wallet
67 | - `rate` is the wallet's distribution rate by permyraid
68 |
69 | ### remove_treasury
70 | Admin able to remove the team treasury wallet.
71 | - `address` is the treasury wallet
72 |
73 | ### init_user
74 | Initialize User Data PDA for Escrow Balance & Traded Volume.
75 | This command should be executed for the first time usage of each traders.
76 |
77 | ### user_status
78 | Get user PDA info for traders. This will show user escrow balance and traded volume info.
79 | - `address` is the trader wallet address
80 |
81 | ### transfer
82 | Transfer NFT from Sender wallet or it's listed Escrow Account to the Recipient.
83 | - `address` is the NFT mint address
84 | - `recipient` is the recipient wallet address
85 |
86 | ### list
87 | List NFT for sale as Seller.
88 | - `address` is the NFT mint address
89 | - `price_sol` is the listing price of NFT
90 |
91 | ### delist
92 | Cancel Listing of NFT as Seller.
93 | - `address` is the NFT mint address
94 |
95 | ### purchase
96 | Purchase the Listed NFT with `Buy Now` price as Buyer.
97 | - `address` is the NFT mint address
98 |
99 | ### make_offer
100 | Make offer for a particular Listed NFT as Buyer.
101 | - `address` is the NFT mint address
102 | - `price` is the offering price. Should be in range of `x1 ~ x0.5` of listed price
103 |
104 | ### cancel_offer
105 | Cancel maden offer for a particular Listed NFT as Buyer.
106 | - `address` is the NFT mint address
107 |
108 | ### accept_offer
109 | Accpet proper offer from a certain Buyer as Seller.
110 | - `address` is the NFT mint addres
111 | - `buyer` is the Offer provider address
112 |
113 | ### create_auction
114 | Create Auction for a particular NFT for funny trading as Seller.
115 | - `address` is the NFT mint address
116 | - `start_price` is the bidding start price
117 | - `min_increase` is the minimum increasing amount for the higer bidding
118 | - `duration` is the auction period since started time by second
119 | - `reserve` if this is 1, then the auction is reserve to start from the first bid placed date. Default 0
120 |
121 | ### palce_bid
122 | Participate in auction with higher bidding as Buyer.
123 | - `address` is the NFT mint address
124 | - `price` is the higher bidding price. Should be more than the latest bid + min_increase_amount
125 |
126 | ### claim_auction
127 | Claim NFT for winner as Buyer when auction is ended.
128 | - `address` is the NFT mint address
129 |
130 | ### cancel_auction
131 | Cancel auction as Seller if there is no bid until auction ended.
132 | - `address` is the NFT mint address
133 |
134 | ### listed_nft_data
135 | Get nft Sell Data PDA info for a particular listed NFT status.
136 | - `address` NFT mint address
137 |
138 | ### get_offer_data
139 | Get Offer Data PDA info for a particular Offer status.
140 | - `address` NFT mint address
141 | - `buyer` is the offer provider address
142 |
143 | ### get_auction_data
144 | Get Auction Data PDA info for a particular auction status.
145 | - `address` NFT mint address
146 |
147 | ### get_all_listed_nfts
148 | Get all listed NFTs info which is active for sale now.
149 |
150 | ### get_all_offers_for_nft
151 | Get all offers info for a particular NFT which is active for accept now.
152 |
153 | ### get_all_auctions
154 | Get all auctions info which is live now or not claimed ended auction.
155 |
156 | ## Notes for FE Integration
157 |
158 | For the FE side web3 integration, the scripts in `lib` directory can be use without no change.
159 | The only thing the FE dev should change is providing `web3 connection` & the `anchor program` object from idl.
160 | There is the code part for the `keypair` wallet based `cli` environement case in `cli/scripts`.
161 | Should configure properly in `BROWSER` environment.
162 |
163 | ## BE Tracking Service Activity Parsing Script
164 | This script will fetch past Txs reacted with Our Marketplace Smartcontract. Then will parse an activity from each Txs so that use the info for DB sync up. \
165 | `yarn be`
166 |
--------------------------------------------------------------------------------
/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Connection,
3 | PublicKey,
4 | SystemProgram,
5 | SYSVAR_RENT_PUBKEY,
6 | TransactionInstruction,
7 | Transaction,
8 | Keypair,
9 | } from '@solana/web3.js';
10 | import { TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, Token, MintLayout } from "@solana/spl-token";
11 | import { ESCROW_VAULT_SEED, GLOBAL_AUTHORITY_SEED, MARKETPLACE_PROGRAM_ID, USER_DATA_SEED } from './types';
12 |
13 | export const METAPLEX = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s');
14 |
15 | export const getOwnerOfNFT = async (nftMintPk : PublicKey, connection: Connection) : Promise => {
16 | let tokenAccountPK = await getNFTTokenAccount(nftMintPk, connection);
17 | let tokenAccountInfo = await connection.getAccountInfo(tokenAccountPK);
18 |
19 | console.log("nftMintPk=", nftMintPk.toBase58());
20 | console.log("tokenAccountInfo =", tokenAccountInfo);
21 |
22 | if (tokenAccountInfo && tokenAccountInfo.data ) {
23 | let ownerPubkey = new PublicKey(tokenAccountInfo.data.slice(32, 64))
24 | console.log("ownerPubkey=", ownerPubkey.toBase58());
25 | return ownerPubkey;
26 | }
27 | return new PublicKey("");
28 | }
29 |
30 | export const getTokenAccount = async (mintPk : PublicKey, userPk: PublicKey, connection: Connection) : Promise => {
31 | let tokenAccount = await connection.getProgramAccounts(
32 | TOKEN_PROGRAM_ID,
33 | {
34 | filters: [
35 | {
36 | dataSize: 165
37 | },
38 | {
39 | memcmp: {
40 | offset: 0,
41 | bytes: mintPk.toBase58()
42 | }
43 | },
44 | {
45 | memcmp: {
46 | offset: 32,
47 | bytes: userPk.toBase58()
48 | }
49 | },
50 | ]
51 | }
52 | );
53 | return tokenAccount[0].pubkey;
54 | }
55 |
56 | export const getNFTTokenAccount = async (nftMintPk : PublicKey, connection: Connection) : Promise => {
57 | console.log("getNFTTokenAccount nftMintPk=", nftMintPk.toBase58());
58 | let tokenAccount = await connection.getProgramAccounts(
59 | TOKEN_PROGRAM_ID,
60 | {
61 | filters: [
62 | {
63 | dataSize: 165
64 | },
65 | {
66 | memcmp: {
67 | offset: 64,
68 | bytes: '2'
69 | }
70 | },
71 | {
72 | memcmp: {
73 | offset: 0,
74 | bytes: nftMintPk.toBase58()
75 | }
76 | },
77 | ]
78 | }
79 | );
80 | return tokenAccount[0].pubkey;
81 | }
82 |
83 | export const getAssociatedTokenAccount = async (ownerPubkey : PublicKey, mintPk : PublicKey) : Promise => {
84 | let associatedTokenAccountPubkey = (await PublicKey.findProgramAddress(
85 | [
86 | ownerPubkey.toBuffer(),
87 | TOKEN_PROGRAM_ID.toBuffer(),
88 | mintPk.toBuffer(), // mint address
89 | ],
90 | ASSOCIATED_TOKEN_PROGRAM_ID
91 | ))[0];
92 | return associatedTokenAccountPubkey;
93 | }
94 |
95 | export const getATokenAccountsNeedCreate = async (
96 | connection: Connection,
97 | walletAddress: PublicKey,
98 | owner: PublicKey,
99 | nfts: PublicKey[],
100 | ) => {
101 | let instructions = [], destinationAccounts = [];
102 | for (const mint of nfts) {
103 | const destinationPubkey = await getAssociatedTokenAccount(owner, mint);
104 | const response = await connection.getAccountInfo(destinationPubkey);
105 | if (!response) {
106 | const createATAIx = createAssociatedTokenAccountInstruction(
107 | destinationPubkey,
108 | walletAddress,
109 | owner,
110 | mint,
111 | );
112 | instructions.push(createATAIx);
113 | }
114 | destinationAccounts.push(destinationPubkey);
115 | }
116 | return {
117 | instructions,
118 | destinationAccounts,
119 | };
120 | }
121 |
122 | export const createAssociatedTokenAccountInstruction = (
123 | associatedTokenAddress: PublicKey,
124 | payer: PublicKey,
125 | walletAddress: PublicKey,
126 | splTokenMintAddress: PublicKey
127 | ) => {
128 | const keys = [
129 | { pubkey: payer, isSigner: true, isWritable: true },
130 | { pubkey: associatedTokenAddress, isSigner: false, isWritable: true },
131 | { pubkey: walletAddress, isSigner: false, isWritable: false },
132 | { pubkey: splTokenMintAddress, isSigner: false, isWritable: false },
133 | {
134 | pubkey: SystemProgram.programId,
135 | isSigner: false,
136 | isWritable: false,
137 | },
138 | { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
139 | {
140 | pubkey: SYSVAR_RENT_PUBKEY,
141 | isSigner: false,
142 | isWritable: false,
143 | },
144 | ];
145 | return new TransactionInstruction({
146 | keys,
147 | programId: ASSOCIATED_TOKEN_PROGRAM_ID,
148 | data: Buffer.from([]),
149 | });
150 | }
151 |
152 | /** Get metaplex mint metadata account address */
153 | export const getMetadata = async (mint: PublicKey): Promise => {
154 | return (
155 | await PublicKey.findProgramAddress([Buffer.from('metadata'), METAPLEX.toBuffer(), mint.toBuffer()], METAPLEX)
156 | )[0];
157 | };
158 |
159 | export const airdropSOL = async (address: PublicKey, amount: number, connection: Connection) => {
160 | try {
161 | const txId = await connection.requestAirdrop(address, amount);
162 | await connection.confirmTransaction(txId);
163 | } catch (e) {
164 | console.log('Aridrop Failure', address.toBase58(), amount);
165 | }
166 | }
167 |
168 | export const createTokenMint = async (
169 | connection: Connection,
170 | payer: Keypair,
171 | mint: Keypair,
172 | ) => {
173 | const ret = await connection.getAccountInfo(mint.publicKey);
174 | if(ret && ret.data) {
175 | console.log('Token already in use', mint.publicKey.toBase58());
176 | return;
177 | };
178 | // Allocate memory for the account
179 | const balanceNeeded = await Token.getMinBalanceRentForExemptMint(
180 | connection,
181 | );
182 | const transaction = new Transaction();
183 | transaction.add(
184 | SystemProgram.createAccount({
185 | fromPubkey: payer.publicKey,
186 | newAccountPubkey: mint.publicKey,
187 | lamports: balanceNeeded,
188 | space: MintLayout.span,
189 | programId: TOKEN_PROGRAM_ID,
190 | }),
191 | );
192 | transaction.add(
193 | Token.createInitMintInstruction(
194 | TOKEN_PROGRAM_ID,
195 | mint.publicKey,
196 | 9,
197 | payer.publicKey,
198 | payer.publicKey,
199 | ),
200 | );
201 | const txId = await connection.sendTransaction(transaction, [payer, mint]);
202 | await connection.confirmTransaction(txId);
203 |
204 | console.log('Tx Hash=', txId);
205 | }
206 |
207 | export const isExistAccount = async (address: PublicKey, connection: Connection) => {
208 | try {
209 | const res = await connection.getAccountInfo(address);
210 | if (res && res.data) return true;
211 | } catch (e) {
212 | return false;
213 | }
214 | }
215 |
216 | export const getTokenAccountBalance = async (account: PublicKey, connection: Connection) => {
217 | try {
218 | const res = await connection.getTokenAccountBalance(account);
219 | if (res && res.value) return res.value.uiAmount;
220 | return 0;
221 | } catch (e) {
222 | console.log(e)
223 | return 0;
224 | }
225 | }
226 |
227 | export const getEscrowBalance = async (connection: Connection) => {
228 | const [escrowVault] = await PublicKey.findProgramAddress(
229 | [Buffer.from(ESCROW_VAULT_SEED)],
230 | MARKETPLACE_PROGRAM_ID,
231 | );
232 |
233 | const res = await connection.getBalance(escrowVault);
234 |
235 | console.log('Escrow:', escrowVault.toBase58());
236 |
237 | return {
238 | sol: res,
239 | }
240 | }
241 |
242 | export const getGlobalNFTBalance = async (mint: PublicKey, connection: Connection) => {
243 | const [globalAuthority, _] = await PublicKey.findProgramAddress(
244 | [Buffer.from(GLOBAL_AUTHORITY_SEED)],
245 | MARKETPLACE_PROGRAM_ID,
246 | );
247 |
248 | const globalNFTAcount = await getAssociatedTokenAccount(globalAuthority, mint);
249 | console.log('GlobalNFTAccount:', globalNFTAcount.toBase58());
250 | return await getTokenAccountBalance(globalNFTAcount, connection);
251 | }
252 |
253 | export const isInitializedUser = async (address: PublicKey, connection: Connection) => {
254 | const [userPool, _] = await PublicKey.findProgramAddress(
255 | [Buffer.from(USER_DATA_SEED), address.toBuffer()],
256 | MARKETPLACE_PROGRAM_ID,
257 | );
258 | console.log('User Data PDA: ', userPool.toBase58());
259 | return await isExistAccount(userPool, connection);
260 | }
--------------------------------------------------------------------------------
/cli/be.ts:
--------------------------------------------------------------------------------
1 | import * as anchor from '@project-serum/anchor';
2 | import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
3 | import { Program, web3 } from '@project-serum/anchor';
4 | import {
5 | PublicKey,
6 | Connection,
7 | SystemProgram,
8 | SYSVAR_RENT_PUBKEY,
9 | Transaction,
10 | PartiallyDecodedInstruction,
11 | ParsedInstruction
12 | } from '@solana/web3.js';
13 | import { Buffer } from 'node:buffer';
14 | import fs from 'fs';
15 | import path from 'path';
16 | import NodeWallet from '@project-serum/anchor/dist/cjs/nodewallet';
17 | import { decode } from '@project-serum/anchor/dist/cjs/utils/bytes/base64';
18 | import { bs58 } from '@project-serum/anchor/dist/cjs/utils/bytes';
19 |
20 | anchor.setProvider(anchor.AnchorProvider.local(web3.clusterApiUrl("devnet")));
21 | const solConnection = anchor.getProvider().connection;
22 | const payer = anchor.AnchorProvider.local().wallet;
23 | var nonce = [
24 | 'AsUkG8p1',
25 | '3BzKBJUk',
26 | 'HY2XrSxn',
27 | 'AJbPzu2U',
28 | 'PcLYN6YP',
29 | '4G2WiD2C',
30 | '4eW8amCV',
31 | '6Ahuf6jr',
32 | 'UJJfJRLD',
33 | '5p6KPRCQ',
34 | 'QPHXB9jL',
35 | 'BE4DeeJT',
36 | 'AnGz4SzU',
37 | 'VcryEr2T',
38 | '3zENZMgC',
39 | '2BWUiNsL',
40 | '2SaBBC7P',
41 | 'ZkCkv1Hg',
42 | 'QMNFmXsk',
43 | 'AtH7do4b',
44 | '882wV271',
45 | '9mtdhZPt',
46 | '9mE5kJpm',
47 | 'Sc9FjYDt',
48 | ];
49 |
50 | const main = async () => {
51 |
52 | await getAllTransactions(new PublicKey("C29hER4SXQr3atHsuCrRmLAkXBpxvfLMCNeXg2TRTd9o"));
53 | // 44GoMVetnJTUJUYzbVbydKVU2f6UoK73Hhew7WW76xBRuyqJZwRXNcCt2dmPhnvjPjZmAsVCLoQDTDuKjQoYFZq3
54 | // 5JUKdSyZBVtiFxapy54dLoUda1muBeLhQNQcMXTrfU3CmrChmvAFbGxoxZW3s8vmpDzm18fCHBn6gmAyStUDw7Dh
55 | }
56 |
57 | export const getAllTransactions = async (
58 | contractId: PublicKey,
59 | ) => {
60 | const data = await solConnection.getSignaturesForAddress(contractId, {}, "confirmed");
61 | data.map( async (datum) => {
62 | let tx = await getDataFromSignature(datum.signature);
63 | console.log(tx);
64 | })
65 | }
66 |
67 | export const getDataFromSignature = async (
68 | sig: string
69 | ) => {
70 | const tx = await solConnection.getParsedTransaction(sig, 'confirmed');
71 | let length = tx.transaction.message.instructions.length;
72 | let valid = -1;
73 | let hash;
74 | let ixId;
75 |
76 | for (let i = 0; i < length; i ++) {
77 | for (let j = 0; j < nonce.length; j ++) {
78 | hash = (tx.transaction.message.instructions[i] as PartiallyDecodedInstruction).data;
79 | if (hash != undefined && hash.slice(0, 8) == nonce[j]) {
80 | valid = j;
81 | break;
82 | }
83 | }
84 | if (valid > -1) {
85 | ixId = i;
86 | break;
87 | }
88 | }
89 |
90 | let ts = tx.blockTime;
91 | let date = new Date(ts * 1000)
92 | if (valid == -1) return;
93 | // return {
94 | // 'type': 'Unknown',
95 | // 'address': tx.transaction.message.accountKeys[0].pubkey.toBase58(),
96 | // 'timestamp': ts,
97 | // 'date': date,
98 | // 'signature': sig,
99 | // };
100 |
101 | let innerIx;
102 | if (tx.meta.innerInstructions.length !== 0) {
103 | innerIx = tx.meta.innerInstructions[ixId].instructions;
104 | }
105 |
106 | let accountKeys = (tx.transaction.message.instructions[ixId] as PartiallyDecodedInstruction).accounts;
107 | let signer = accountKeys[0].toBase58();
108 | let result;
109 | switch (valid) {
110 | case 0:
111 | console.log("Initialize");
112 | result = {'type': "Initialize"}
113 | break;
114 | case 1: {
115 | console.log("UpdateFee");
116 | result = {'type': "UpdateFee"}
117 | break;
118 | }
119 | case 2:
120 | console.log("AddTeamTreasury");
121 | result = {'type': 'AddTeamTreasury'}
122 | break;
123 | case 3:
124 | console.log("RemoveTeamTreasury");
125 | result = {'type': 'RemoveTeamTreasury'}
126 | break;
127 | case 4:{
128 | console.log("InitUserPool");
129 | result = {'type': 'InitUserPool'}
130 | break;
131 | }
132 | case 5:
133 | console.log("InitSellData");
134 | break;
135 | case 6: {
136 | console.log("ListNftForSale");
137 | let bytes = bs58.decode(hash)
138 | let b = bytes.slice(10, 18).reverse();
139 | let sol_price = new anchor.BN(b).toNumber()
140 |
141 | result = {
142 | 'type': 'ListNftForSale',
143 | 'address': signer,
144 | 'mint': accountKeys[5].toBase58(),
145 | 'sol_price': sol_price,
146 | 'timestamp': ts,
147 | 'date': date,
148 | 'signature': sig,
149 | }
150 | break;
151 | }
152 | case 7: {
153 | console.log("DelistNft");
154 | result = {
155 | 'type': 'DelistNft',
156 | 'address': signer,
157 | 'mint': accountKeys[5].toBase58(),
158 | 'timestamp': ts,
159 | 'date': date,
160 | 'signature': sig,
161 | }
162 | break;
163 | }
164 | case 8: {
165 | console.log("Transfer");
166 | result = {
167 | 'type': 'Transfer',
168 | 'address': signer,
169 | 'recipient': accountKeys[2].toBase58(),
170 | 'mint': accountKeys[4].toBase58(),
171 | 'timestamp': ts,
172 | 'date': date,
173 | 'signature': sig,
174 | }
175 | break;
176 | }
177 | case 9:
178 | console.log("TransferFromVault");
179 | result = {
180 | 'type': 'TransferFromVault',
181 | 'address': signer,
182 | 'recipient': accountKeys[3].toBase58(),
183 | 'mint': accountKeys[6].toBase58(),
184 | 'timestamp': ts,
185 | 'date': date,
186 | 'signature': sig,
187 | }
188 | break;
189 | case 10:
190 | console.log("Purchase");
191 | let price = 0;
192 | for(let i = 0; i {
47 | const {
48 | env,
49 | } = cmd.opts();
50 | console.log('Solana config: ', env);
51 | await setClusterConfig(env);
52 | console.log(await getGlobalInfo());
53 | });
54 |
55 | programCommand('user_status')
56 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
57 | .option('-a, --address ', 'nft user pubkey')
58 | .action(async (directory, cmd) => {
59 | const {
60 | env,
61 | address,
62 | } = cmd.opts();
63 | console.log('Solana config: ', env);
64 | await setClusterConfig(env);
65 | if (address === undefined) {
66 | console.log("Error User Address input");
67 | return;
68 | }
69 | console.log(await getUserPoolInfo(new PublicKey(address)));
70 | });
71 |
72 | programCommand('update_fee')
73 | .option('-s, --sol_fee ', 'marketplace trading by sol fee as permyraid')
74 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
75 | .action(async (directory, cmd) => {
76 | const {
77 | env,
78 | sol_fee,
79 | } = cmd.opts();
80 |
81 | console.log('Solana config: ', env);
82 | await setClusterConfig(env);
83 |
84 | if (sol_fee === undefined || isNaN(parseInt(sol_fee))) {
85 | console.log("Error Sol Fee Input");
86 | return;
87 | }
88 |
89 | await updateFee(parseInt(sol_fee));
90 | });
91 |
92 | programCommand('add_treasury')
93 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
94 | .option('-a, --address ', 'team treasury account pubkey')
95 | .option('-r, --rate ', 'treasury distribution rate as permyraid')
96 | .action(async (directory, cmd) => {
97 | const {
98 | env,
99 | address,
100 | rate,
101 | } = cmd.opts();
102 | console.log('Solana config: ', env);
103 | await setClusterConfig(env);
104 | if (address === undefined) {
105 | console.log("Error Treasury input");
106 | return;
107 | }
108 | if (rate === undefined || isNaN(parseInt(rate))) {
109 | console.log("Error Treasury Rate Input");
110 | return;
111 | }
112 | await addTreasury(new PublicKey(address), parseInt(rate));
113 | });
114 |
115 | programCommand('remove_treasury')
116 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
117 | .option('-a, --address ', 'team treasury account pubkey')
118 | .action(async (directory, cmd) => {
119 | const {
120 | env,
121 | address,
122 | } = cmd.opts();
123 | console.log('Solana config: ', env);
124 | await setClusterConfig(env);
125 | if (address === undefined) {
126 | console.log("Error Treasury input");
127 | return;
128 | }
129 | await removeTreasury(new PublicKey(address));
130 | });
131 |
132 | programCommand('deposit')
133 | .option('-s, --sol ', 'deposit sol amount')
134 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
135 | .action(async (directory, cmd) => {
136 | const {
137 | env,
138 | sol,
139 | } = cmd.opts();
140 |
141 | console.log('Solana config: ', env);
142 | await setClusterConfig(env);
143 |
144 | if (sol === undefined || isNaN(parseFloat(sol))) {
145 | console.log("Error Sol Amount input");
146 | return;
147 | }
148 |
149 | await depositEscrow(parseFloat(sol) * LAMPORTS_PER_SOL);
150 | });
151 |
152 | programCommand('withdraw')
153 | .option('-s, --sol ', 'withdraw sol amount')
154 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
155 | .action(async (directory, cmd) => {
156 | const {
157 | env,
158 | sol,
159 | token,
160 | } = cmd.opts();
161 |
162 | console.log('Solana config: ', env);
163 | await setClusterConfig(env);
164 |
165 | if (sol === undefined || isNaN(parseFloat(sol))) {
166 | console.log("Error Sol Amount input");
167 | return;
168 | }
169 |
170 | await withdrawEscrow(parseFloat(sol) * LAMPORTS_PER_SOL);
171 | });
172 |
173 | programCommand('transfer')
174 | .option('-a, --address ', 'nft mint pubkey')
175 | .option('-r, --recipient ', 'recipient user address')
176 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
177 | .action(async (directory, cmd) => {
178 | const {
179 | env,
180 | address,
181 | recipient,
182 | } = cmd.opts();
183 |
184 | console.log('Solana config: ', env);
185 | await setClusterConfig(env);
186 |
187 | if (address === undefined) {
188 | console.log("Error Mint input");
189 | return;
190 | }
191 |
192 | if (recipient === undefined) {
193 | console.log("Error Recipint Address input");
194 | return;
195 | }
196 |
197 | await transfer(new PublicKey(address), new PublicKey(recipient));
198 | });
199 |
200 | programCommand('list')
201 | .option('-a, --address ', 'nft mint pubkey')
202 | .option('-p, --price_sol ', 'sell sol price')
203 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
204 | .action(async (directory, cmd) => {
205 | const {
206 | env,
207 | address,
208 | price_sol,
209 | } = cmd.opts();
210 |
211 | console.log('Solana config: ', env);
212 | await setClusterConfig(env);
213 |
214 | if (address === undefined) {
215 | console.log("Error Mint input");
216 | return;
217 | }
218 | if (price_sol === undefined || isNaN(parseFloat(price_sol))) {
219 | console.log("Error Sol Price input");
220 | return;
221 | }
222 |
223 | await listNftForSale(new PublicKey(address), parseFloat(price_sol) * LAMPORTS_PER_SOL);
224 | });
225 |
226 | programCommand('delist')
227 | .option('-a, --address ', 'nft mint pubkey')
228 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
229 | .action(async (directory, cmd) => {
230 | const {
231 | env,
232 | address,
233 | } = cmd.opts();
234 |
235 | console.log('Solana config: ', env);
236 | await setClusterConfig(env);
237 |
238 | if (address === undefined) {
239 | console.log("Error Mint input");
240 | return;
241 | }
242 |
243 | await delistNft(new PublicKey(address));
244 | });
245 |
246 | programCommand('set_price')
247 | .option('-a, --address ', 'nft mint pubkey')
248 | .option('-p, --price_sol ', 'new sell price')
249 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
250 | .action(async (directory, cmd) => {
251 | const {
252 | env,
253 | address,
254 | price_sol,
255 | } = cmd.opts();
256 |
257 | console.log('Solana config: ', env);
258 | await setClusterConfig(env);
259 |
260 | if (address === undefined) {
261 | console.log("Error Mint input");
262 | return;
263 | }
264 | if (price_sol === undefined || isNaN(parseFloat(price_sol))) {
265 | console.log("Error Sol Price input");
266 | return;
267 | }
268 |
269 | await setPrice(new PublicKey(address), parseFloat(price_sol) * LAMPORTS_PER_SOL);
270 | });
271 |
272 | programCommand('purchase')
273 | .option('-a, --address ', 'nft mint pubkey')
274 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
275 | .action(async (directory, cmd) => {
276 | const {
277 | env,
278 | address,
279 | } = cmd.opts();
280 |
281 | console.log('Solana config: ', env);
282 | await setClusterConfig(env);
283 |
284 | if (address === undefined) {
285 | console.log("Error Mint input");
286 | return;
287 | }
288 |
289 | await purchase(new PublicKey(address));
290 | });
291 |
292 | programCommand('make_offer')
293 | .option('-a, --address ', 'nft mint pubkey')
294 | .option('-p, --price ', 'offer price')
295 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
296 | .action(async (directory, cmd) => {
297 | const {
298 | env,
299 | address,
300 | price,
301 | } = cmd.opts();
302 |
303 | console.log('Solana config: ', env);
304 | await setClusterConfig(env);
305 |
306 | if (address === undefined) {
307 | console.log("Error Mint input");
308 | return;
309 | }
310 | if (price === undefined || isNaN(parseFloat(price))) {
311 | console.log("Error Offer Price input");
312 | return;
313 | }
314 |
315 | await makeOffer(new PublicKey(address), parseFloat(price) * LAMPORTS_PER_SOL);
316 | });
317 |
318 | programCommand('cancel_offer')
319 | .option('-a, --address ', 'nft mint pubkey')
320 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
321 | .action(async (directory, cmd) => {
322 | const {
323 | env,
324 | address,
325 | } = cmd.opts();
326 |
327 | console.log('Solana config: ', env);
328 | await setClusterConfig(env);
329 |
330 | if (address === undefined) {
331 | console.log("Error Mint input");
332 | return;
333 | }
334 |
335 | await cancelOffer(new PublicKey(address));
336 | });
337 |
338 | programCommand('accept_offer')
339 | .option('-a, --address ', 'nft mint pubkey')
340 | .option('-b, --buyer ', 'buyer address')
341 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
342 | .action(async (directory, cmd) => {
343 | const {
344 | env,
345 | address,
346 | buyer,
347 | } = cmd.opts();
348 |
349 | console.log('Solana config: ', env);
350 | await setClusterConfig(env);
351 |
352 | if (address === undefined) {
353 | console.log("Error Mint input");
354 | return;
355 | }
356 |
357 | if (buyer === undefined) {
358 | console.log("Error Buyer input");
359 | return;
360 | }
361 |
362 | await acceptOffer(new PublicKey(address), new PublicKey(buyer));
363 | });
364 |
365 | programCommand('create_auction')
366 | .option('-a, --address ', 'nft mint pubkey')
367 | .option('-p, --start_price ', 'start price')
368 | .option('-m, --min_increase ', 'min increase amount')
369 | .option('-d, --duration ', 'duration by second')
370 | .option('-r, --reserve ', 'reserved auction flag')
371 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
372 | .action(async (directory, cmd) => {
373 | const {
374 | env,
375 | address,
376 | start_price,
377 | min_increase,
378 | duration,
379 | reserve,
380 | } = cmd.opts();
381 |
382 | console.log('Solana config: ', env);
383 | await setClusterConfig(env);
384 |
385 | if (address === undefined) {
386 | console.log("Error Mint input");
387 | return;
388 | }
389 | if (start_price === undefined || isNaN(parseFloat(start_price))) {
390 | console.log("Error Auction Start Price input");
391 | return;
392 | }
393 | if (min_increase === undefined || isNaN(parseFloat(min_increase))) {
394 | console.log("Error Auction Min Increase Amount input");
395 | return;
396 | }
397 | if (duration === undefined || isNaN(parseInt(duration))) {
398 | console.log("Error Auction Duration input");
399 | return;
400 | }
401 | if (reserve === undefined || isNaN(parseInt(reserve)) || parseInt(reserve) > 1) {
402 | console.log("Error Reserve Flag input");
403 | return;
404 | }
405 |
406 | await createAuction(
407 | new PublicKey(address),
408 | parseFloat(start_price) * LAMPORTS_PER_SOL,
409 | parseFloat(min_increase) * LAMPORTS_PER_SOL,
410 | parseInt(duration),
411 | parseInt(reserve) == 1,
412 | );
413 | });
414 |
415 | programCommand('place_bid')
416 | .option('-a, --address ', 'nft mint pubkey')
417 | .option('-p, --price ', 'auction price')
418 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
419 | .action(async (directory, cmd) => {
420 | const {
421 | env,
422 | address,
423 | price,
424 | } = cmd.opts();
425 |
426 | console.log('Solana config: ', env);
427 | await setClusterConfig(env);
428 |
429 | if (address === undefined) {
430 | console.log("Error Mint input");
431 | return;
432 | }
433 | if (price === undefined || isNaN(parseFloat(price))) {
434 | console.log("Error Auction Price input");
435 | return;
436 | }
437 |
438 | await placeBid(new PublicKey(address), parseFloat(price) * 1e9);
439 | });
440 |
441 |
442 | programCommand('claim_auction')
443 | .option('-a, --address ', 'nft mint pubkey')
444 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
445 | .action(async (directory, cmd) => {
446 | const {
447 | env,
448 | address,
449 | } = cmd.opts();
450 |
451 | console.log('Solana config: ', env);
452 | await setClusterConfig(env);
453 |
454 | if (address === undefined) {
455 | console.log("Error Mint input");
456 | return;
457 | }
458 |
459 | await claimAuction(new PublicKey(address));
460 | });
461 |
462 | programCommand('update_reserve')
463 | .option('-a, --address ', 'nft mint pubkey')
464 | .option('-p, --start_price ', 'start price')
465 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
466 | .action(async (directory, cmd) => {
467 | const {
468 | env,
469 | address,
470 | start_price,
471 | } = cmd.opts();
472 |
473 | console.log('Solana config: ', env);
474 | await setClusterConfig(env);
475 |
476 | if (address === undefined) {
477 | console.log("Error Mint input");
478 | return;
479 | }
480 | if (start_price === undefined || isNaN(parseFloat(start_price))) {
481 | console.log("Error Auction Start Price input");
482 | return;
483 | }
484 |
485 | await updateReserve(
486 | new PublicKey(address),
487 | parseFloat(start_price) * LAMPORTS_PER_SOL,
488 | );
489 | });
490 |
491 | programCommand('cancel_auction')
492 | .option('-a, --address ', 'nft mint pubkey')
493 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
494 | .action(async (directory, cmd) => {
495 | const {
496 | env,
497 | address,
498 | } = cmd.opts();
499 |
500 | console.log('Solana config: ', env);
501 | await setClusterConfig(env);
502 |
503 | if (address === undefined) {
504 | console.log("Error Mint input");
505 | return;
506 | }
507 |
508 | await cancelAuction(new PublicKey(address));
509 | });
510 |
511 | programCommand('listed_nft_data')
512 | .option('-a, --address ', 'nft mint pubkey')
513 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
514 | .action(async (directory, cmd) => {
515 | const {
516 | env,
517 | address,
518 | } = cmd.opts();
519 |
520 | console.log('Solana config: ', env);
521 | await setClusterConfig(env);
522 |
523 | if (address === undefined) {
524 | console.log("Error input");
525 | return;
526 | }
527 | console.log(await getNFTPoolInfo(new PublicKey(address)));
528 | });
529 |
530 | programCommand('get_offer_data')
531 | .option('-a, --address ', 'nft mint pubkey')
532 | .option('-b, --buyer ', 'buyer address pubkey')
533 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
534 | .action(async (directory, cmd) => {
535 | const {
536 | env,
537 | address,
538 | buyer,
539 | } = cmd.opts();
540 |
541 | console.log('Solana config: ', env);
542 | await setClusterConfig(env);
543 |
544 | if (address === undefined) {
545 | console.log("Error Mint input");
546 | return;
547 | }
548 | if (buyer === undefined) {
549 | console.log("Error Buyer input");
550 | return;
551 | }
552 | console.log(await getOfferDataInfo(new PublicKey(address), new PublicKey(buyer)));
553 | });
554 |
555 | programCommand('get_auction_data')
556 | .option('-a, --address ', 'nft mint pubkey')
557 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
558 | .action(async (directory, cmd) => {
559 | const {
560 | env,
561 | address,
562 | } = cmd.opts();
563 |
564 | console.log('Solana config: ', env);
565 | await setClusterConfig(env);
566 |
567 | if (address === undefined) {
568 | console.log("Error Mint input");
569 | return;
570 | }
571 | console.log(await getAuctionDataInfo(new PublicKey(address)));
572 | });
573 |
574 | programCommand('get_all_listed_nfts')
575 | .option('-r, --rpc ', 'custom rpc url')
576 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
577 | .action(async (directory, cmd) => {
578 | const {
579 | env,
580 | rpc,
581 | } = cmd.opts();
582 |
583 | console.log('Solana config: ', env);
584 | await setClusterConfig(env);
585 |
586 | console.log(await getAllNFTs(rpc));
587 | });
588 |
589 | programCommand('get_all_offers_for_nft')
590 | .option('-a, --address ', 'nft mint pubkey')
591 | .option('-r, --rpc ', 'custom rpc url')
592 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
593 | .action(async (directory, cmd) => {
594 | const {
595 | env,
596 | address,
597 | rpc,
598 | } = cmd.opts();
599 |
600 | console.log('Solana config: ', env);
601 | await setClusterConfig(env);
602 |
603 | if (address === undefined) {
604 | console.log("Error input");
605 | return;
606 | }
607 | console.log(await getAllOffersForNFT(address, rpc));
608 | });
609 |
610 | programCommand('get_all_auctions')
611 | .option('-r, --rpc ', 'custom rpc url')
612 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
613 | .action(async (directory, cmd) => {
614 | const {
615 | env,
616 | rpc,
617 | } = cmd.opts();
618 |
619 | console.log('Solana config: ', env);
620 | await setClusterConfig(env);
621 |
622 | console.log(await getAllAuctions(rpc));
623 | });
624 |
625 | programCommand('init')
626 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
627 | .action(async (directory, cmd) => {
628 | const {
629 | env,
630 | } = cmd.opts();
631 | console.log('Solana config: ', env);
632 | await setClusterConfig(env);
633 |
634 | await initProject();
635 | });
636 |
637 | programCommand('init_user')
638 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
639 | .action(async (directory, cmd) => {
640 | const {
641 | env,
642 | } = cmd.opts();
643 | console.log('Solana config: ', env);
644 | await setClusterConfig(env);
645 | await initUserPool();
646 | });
647 |
648 | function programCommand(name: string) {
649 | return program
650 | .command(name)
651 | .option(
652 | '-e, --env ',
653 | 'Solana cluster env name',
654 | 'devnet', //mainnet-beta, testnet, devnet
655 | )
656 | }
657 |
658 | program.parse(process.argv);
659 |
--------------------------------------------------------------------------------
/cli/scripts.ts:
--------------------------------------------------------------------------------
1 | import { Program, web3 } from '@project-serum/anchor';
2 | import * as anchor from '@project-serum/anchor';
3 | import {
4 | Keypair,
5 | PublicKey,
6 | } from '@solana/web3.js';
7 | import fs from 'fs';
8 | import path from 'path';
9 | import NodeWallet from '@project-serum/anchor/dist/cjs/nodewallet';
10 |
11 | import { AuctionData, AUCTION_DATA_SEED, GlobalPool, GLOBAL_AUTHORITY_SEED, MARKETPLACE_PROGRAM_ID, OfferData, OFFER_DATA_SEED, SellData, SELL_DATA_SEED, UserData } from '../lib/types';
12 | import { IDL as MarketplaceIDL } from "../target/types/nut_marketplace";
13 | import {
14 | createAcceptOfferTx,
15 | createAddTreasuryTx,
16 | createCancelAuctionTx,
17 | createCancelOfferTx,
18 | createClaimAuctionTx,
19 | createCreateAuctionTx,
20 | createDelistNftTx,
21 | createDepositTx,
22 | createInitAuctionDataTx,
23 | createInitializeTx,
24 | createInitOfferDataTx,
25 | createInitSellDataTx,
26 | createInitUserTx,
27 | createListForSellNftTx,
28 | createMakeOfferTx,
29 | createPlaceBidTx,
30 | createPurchaseTx,
31 | createRemoveTreasuryTx,
32 | createSetPriceTx,
33 | createTransferFromVaultTx,
34 | createTransferTx,
35 | createUpdateFeeTx,
36 | createUpdateReserveTx,
37 | createWithdrawTx,
38 | getAllListedNFTs,
39 | getAllOffersForListedNFT,
40 | getAllStartedAuctions,
41 | getAuctionDataState,
42 | getGlobalState,
43 | getNFTPoolState,
44 | getOfferDataState,
45 | getUserPoolState
46 | } from '../lib/scripts';
47 | import { isInitializedUser } from '../lib/utils';
48 |
49 | let solConnection = null;
50 | let payer = null;
51 | let program: Program = null;
52 |
53 | // Address of the deployed program.
54 | let programId = new anchor.web3.PublicKey(MARKETPLACE_PROGRAM_ID);
55 |
56 | export const setClusterConfig = async (cluster: web3.Cluster) => {
57 | solConnection = new web3.Connection(web3.clusterApiUrl(cluster));
58 | const walletKeypair = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(fs.readFileSync(path.resolve(process.env.ANCHOR_WALLET), 'utf-8'))), { skipValidation: true });
59 | const wallet = new NodeWallet(walletKeypair);
60 | // anchor.setProvider(anchor.AnchorProvider.local(web3.clusterApiUrl(cluster)));
61 | // Configure the client to use the local cluster.
62 | anchor.setProvider(new anchor.AnchorProvider(solConnection, wallet, { skipPreflight: true, commitment: 'confirmed' }));
63 | payer = wallet;
64 |
65 | // Generate the program client from IDL.
66 | program = new anchor.Program(MarketplaceIDL as anchor.Idl, programId);
67 | console.log('ProgramId: ', program.programId.toBase58());
68 |
69 | const [globalAuthority, bump] = await PublicKey.findProgramAddress(
70 | [Buffer.from(GLOBAL_AUTHORITY_SEED)],
71 | program.programId
72 | );
73 | console.log('GlobalAuthority: ', globalAuthority.toBase58());
74 |
75 | // await main();
76 | }
77 |
78 | const main = async () => {
79 |
80 | // await initProject();
81 | // await addCollection(new PublicKey('B2FmSY81mionC1DYvKky5Y8nUXSWnhMmd5L5nbm99VHQ'));
82 | // await removeCollection(new PublicKey('B2FmSY81mionC1DYvKky5Y8nUXSWnhMmd5L5nbm99VHQ'));
83 |
84 | // const globalPool: GlobalPool = await getGlobalState();
85 | // console.log("globalPool =", globalPool.superAdmin.toBase58(), globalPool.fullStakePeriod.toNumber()
86 | // , globalPool.minStakePeriod.toNumber(), globalPool.rewardPeriod.toNumber()
87 | // , globalPool.rewardAmount.toNumber(), globalPool.totalStakedCount.toNumber(),
88 | // globalPool.collectionCount.toNumber(), globalPool.collections.slice(0, globalPool.collectionCount.toNumber()).map((addr) => addr.toBase58()));
89 |
90 | // await initUserPool(payer.publicKey);
91 |
92 | // await stakeNft(payer.publicKey, new PublicKey('554AJqCuVFWL7ZHtLqmh18NvuC4UYLP12Bc8fN4RvTex'));
93 | // await claimReward(payer.publicKey);
94 | // await withdrawNft(payer.publicKey, new PublicKey('554AJqCuVFWL7ZHtLqmh18NvuC4UYLP12Bc8fN4RvTex'));
95 | // await burnNft(payer.publicKey, new PublicKey('4Qw3PQqY3q8LbZAYXfwpjUGS4k7anqdRrPyDL9LWue4d'));
96 |
97 | // const userPool: UserPool = await getUserPoolState(new PublicKey('2EnGnSaf89uP6n7prHrKWK9Q41yAWbRkTN1b5ry8XxCw'));
98 | // console.log({
99 | // ...userPool,
100 | // owner: userPool.owner.toBase58(),
101 | // stakedMints: userPool.stakedMints.slice(0, userPool.stakedCount.toNumber()).map((info) => {
102 | // return {
103 | // mint: info.mint.toBase58(),
104 | // stakedTime: info.stakedTime.toNumber(),
105 | // }
106 | // })
107 | // });
108 | // calculateRewards(new PublicKey('GyjFWXkMn4AGrD5FPfBegP75zmodBeBxr9gBRJjr8qke'));
109 |
110 | };
111 |
112 | export const initProject = async (
113 | ) => {
114 | const tx = await createInitializeTx(payer.publicKey, program);
115 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
116 | tx.feePayer = payer.publicKey;
117 | tx.recentBlockhash = blockhash;
118 | payer.signTransaction(tx);
119 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
120 | await solConnection.confirmTransaction(txId, "confirmed");
121 | console.log("txHash =", txId);
122 | }
123 |
124 | export const initSellData = async (
125 | mint: PublicKey,
126 | ) => {
127 | const tx = await createInitSellDataTx(mint, payer.publicKey, program);
128 | const { blockhash } = await solConnection.getRecentBlockhash('finalized');
129 | tx.feePayer = payer.publicKey;
130 | tx.recentBlockhash = blockhash;
131 | payer.signTransaction(tx);
132 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
133 | await solConnection.confirmTransaction(txId, "finalized");
134 | console.log("Your transaction signature", txId);
135 | }
136 |
137 | export const initUserPool = async () => {
138 | const tx = await createInitUserTx(payer.publicKey, program);
139 | const { blockhash } = await solConnection.getRecentBlockhash('finalized');
140 | tx.feePayer = payer.publicKey;
141 | tx.recentBlockhash = blockhash;
142 | payer.signTransaction(tx);
143 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
144 | await solConnection.confirmTransaction(txId, "finalized");
145 | console.log("Your transaction signature", txId);
146 | }
147 |
148 | export const initAuctionData = async (
149 | mint: PublicKey,
150 | ) => {
151 | const tx = await createInitAuctionDataTx(mint, payer.publicKey, program);
152 | const { blockhash } = await solConnection.getRecentBlockhash('finalized');
153 | tx.feePayer = payer.publicKey;
154 | tx.recentBlockhash = blockhash;
155 | payer.signTransaction(tx);
156 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
157 | await solConnection.confirmTransaction(txId, "finalized");
158 | console.log("Your transaction signature", txId);
159 | }
160 |
161 | export const updateFee = async (
162 | solFee: number,
163 | ) => {
164 | console.log(solFee);
165 | const tx = await createUpdateFeeTx(payer.publicKey, program, solFee);
166 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
167 | tx.feePayer = payer.publicKey;
168 | tx.recentBlockhash = blockhash;
169 | payer.signTransaction(tx);
170 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
171 | await solConnection.confirmTransaction(txId, "confirmed");
172 | console.log("Your transaction signature", txId);
173 | }
174 |
175 | export const addTreasury = async (
176 | treasury: PublicKey,
177 | rate: number,
178 | ) => {
179 | console.log(treasury.toBase58(), rate);
180 |
181 | const tx = await createAddTreasuryTx(payer.publicKey, treasury, rate, program);
182 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
183 | tx.feePayer = payer.publicKey;
184 | tx.recentBlockhash = blockhash;
185 | payer.signTransaction(tx);
186 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
187 | await solConnection.confirmTransaction(txId, "confirmed");
188 | console.log("Your transaction signature", txId);
189 | }
190 |
191 | export const removeTreasury = async (
192 | treasury: PublicKey,
193 | ) => {
194 | console.log(treasury.toBase58());
195 |
196 | const tx = await createRemoveTreasuryTx(payer.publicKey, program, treasury);
197 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
198 | tx.feePayer = payer.publicKey;
199 | tx.recentBlockhash = blockhash;
200 | payer.signTransaction(tx);
201 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
202 | await solConnection.confirmTransaction(txId, "confirmed");
203 | console.log("Your transaction signature", txId);
204 | }
205 |
206 | export const depositEscrow = async (
207 | sol: number,
208 | ) => {
209 | let userAddress = payer.publicKey;
210 | console.log(userAddress.toBase58(), sol);
211 |
212 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
213 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
214 | return;
215 | }
216 |
217 | const tx = await createDepositTx(userAddress, sol, program);
218 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
219 | tx.feePayer = payer.publicKey;
220 | tx.recentBlockhash = blockhash;
221 | payer.signTransaction(tx);
222 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
223 | await solConnection.confirmTransaction(txId, "confirmed");
224 | console.log("Your transaction signature", txId);
225 | }
226 |
227 | export const withdrawEscrow = async (
228 | sol: number,
229 | ) => {
230 | let userAddress = payer.publicKey;
231 | console.log(userAddress.toBase58(), sol);
232 |
233 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
234 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
235 | return;
236 | }
237 |
238 | const tx = await createWithdrawTx(userAddress, sol, program);
239 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
240 | tx.feePayer = payer.publicKey;
241 | tx.recentBlockhash = blockhash;
242 | payer.signTransaction(tx);
243 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
244 | await solConnection.confirmTransaction(txId, "confirmed");
245 | console.log("Your transaction signature", txId);
246 | }
247 |
248 | export const transfer = async (
249 | mint: PublicKey,
250 | recipient: PublicKey,
251 | ) => {
252 | console.log(mint.toBase58(), recipient.toBase58());
253 |
254 | const [sellData, _] = await PublicKey.findProgramAddress(
255 | [Buffer.from(SELL_DATA_SEED), mint.toBuffer()],
256 | MARKETPLACE_PROGRAM_ID,
257 | );
258 | console.log('Sell Data PDA: ', sellData.toBase58());
259 |
260 | let fromVault = 1;
261 | let poolAccount = await solConnection.getAccountInfo(sellData);
262 | if (poolAccount === null || poolAccount.data === null) {
263 | fromVault = 0;
264 | } else {
265 | const data = await getNFTPoolInfo(mint);
266 | if (data.active != 1) fromVault = 0;
267 | }
268 |
269 | let tx;
270 | if (fromVault) tx = await createTransferFromVaultTx(mint, payer.publicKey, recipient, program, solConnection);
271 | else tx = await createTransferTx(mint, payer.publicKey, recipient, program, solConnection);
272 |
273 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
274 | tx.feePayer = payer.publicKey;
275 | tx.recentBlockhash = blockhash;
276 | payer.signTransaction(tx);
277 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
278 | await solConnection.confirmTransaction(txId, "confirmed");
279 | console.log("Your transaction signature", txId);
280 | }
281 |
282 | export const listNftForSale = async (
283 | mint: PublicKey,
284 | priceSol: number,
285 | ) => {
286 | console.log(mint.toBase58(), priceSol);
287 |
288 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
289 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
290 | return;
291 | }
292 |
293 | const [sellData, _] = await PublicKey.findProgramAddress(
294 | [Buffer.from(SELL_DATA_SEED), mint.toBuffer()],
295 | MARKETPLACE_PROGRAM_ID,
296 | );
297 | console.log('Sell Data PDA: ', sellData.toBase58());
298 |
299 | let poolAccount = await solConnection.getAccountInfo(sellData);
300 | if (poolAccount === null || poolAccount.data === null) {
301 | await initSellData(mint);
302 | }
303 |
304 | const [auctionData] = await PublicKey.findProgramAddress(
305 | [Buffer.from(AUCTION_DATA_SEED), mint.toBuffer()],
306 | MARKETPLACE_PROGRAM_ID,
307 | );
308 | console.log('Auction Data PDA: ', auctionData.toBase58());
309 |
310 | poolAccount = await solConnection.getAccountInfo(auctionData);
311 | if (poolAccount === null || poolAccount.data === null) {
312 | await initAuctionData(mint);
313 | }
314 |
315 | const tx = await createListForSellNftTx(mint, payer.publicKey, program, solConnection, priceSol);
316 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
317 | tx.feePayer = payer.publicKey;
318 | tx.recentBlockhash = blockhash;
319 | payer.signTransaction(tx);
320 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
321 | await solConnection.confirmTransaction(txId, "confirmed");
322 | console.log("Your transaction signature", txId);
323 | }
324 |
325 | export const delistNft = async (
326 | mint: PublicKey,
327 | ) => {
328 | console.log(mint.toBase58());
329 |
330 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
331 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
332 | return;
333 | }
334 |
335 | const tx = await createDelistNftTx(mint, payer.publicKey, program, solConnection);
336 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
337 | tx.feePayer = payer.publicKey;
338 | tx.recentBlockhash = blockhash;
339 | payer.signTransaction(tx);
340 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
341 | await solConnection.confirmTransaction(txId, "confirmed");
342 | console.log("Your transaction signature", txId);
343 | }
344 |
345 | export const setPrice = async (
346 | mint: PublicKey,
347 | newPrice: number,
348 | ) => {
349 | console.log(mint.toBase58(), newPrice);
350 |
351 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
352 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
353 | return;
354 | }
355 |
356 | const tx = await createSetPriceTx(mint, payer.publicKey, newPrice, program);
357 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
358 | tx.feePayer = payer.publicKey;
359 | tx.recentBlockhash = blockhash;
360 | payer.signTransaction(tx);
361 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
362 | await solConnection.confirmTransaction(txId, "confirmed");
363 | console.log("Your transaction signature", txId);
364 | }
365 |
366 | export const purchase = async (
367 | mint: PublicKey,
368 | ) => {
369 | console.log(mint.toBase58());
370 |
371 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
372 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
373 | return;
374 | }
375 |
376 | const globalPool: GlobalPool = await getGlobalState(program);
377 |
378 | const tx = await createPurchaseTx(mint, payer.publicKey, globalPool.teamTreasury.slice(0, globalPool.teamCount.toNumber()), program, solConnection);
379 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
380 | tx.feePayer = payer.publicKey;
381 | tx.recentBlockhash = blockhash;
382 | payer.signTransaction(tx);
383 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
384 | await solConnection.confirmTransaction(txId, "confirmed");
385 | console.log("Your transaction signature", txId);
386 | }
387 |
388 | export const initOfferData = async (
389 | mint: PublicKey,
390 | ) => {
391 | const tx = await createInitOfferDataTx(mint, payer.publicKey, program);
392 | const { blockhash } = await solConnection.getRecentBlockhash('finalized');
393 | tx.feePayer = payer.publicKey;
394 | tx.recentBlockhash = blockhash;
395 | payer.signTransaction(tx);
396 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
397 | await solConnection.confirmTransaction(txId, "finalized");
398 | console.log("Your transaction signature", txId);
399 | }
400 |
401 | export const makeOffer = async (
402 | mint: PublicKey,
403 | price: number,
404 | ) => {
405 | console.log(mint.toBase58(), price);
406 |
407 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
408 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
409 | return;
410 | }
411 |
412 | const [offerData, _] = await PublicKey.findProgramAddress(
413 | [Buffer.from(OFFER_DATA_SEED), mint.toBuffer(), payer.publicKey.toBuffer()],
414 | MARKETPLACE_PROGRAM_ID,
415 | );
416 | console.log('Offer Data PDA: ', offerData.toBase58());
417 |
418 | let poolAccount = await solConnection.getAccountInfo(offerData);
419 | if (poolAccount === null || poolAccount.data === null) {
420 | await initOfferData(mint);
421 | }
422 |
423 | const tx = await createMakeOfferTx(mint, payer.publicKey, price, program);
424 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
425 | tx.feePayer = payer.publicKey;
426 | tx.recentBlockhash = blockhash;
427 | payer.signTransaction(tx);
428 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
429 | await solConnection.confirmTransaction(txId, "confirmed");
430 | console.log("Your transaction signature", txId);
431 | }
432 |
433 | export const cancelOffer = async (
434 | mint: PublicKey,
435 | ) => {
436 | console.log(mint.toBase58());
437 |
438 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
439 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
440 | return;
441 | }
442 |
443 | const tx = await createCancelOfferTx(mint, payer.publicKey, program);
444 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
445 | tx.feePayer = payer.publicKey;
446 | tx.recentBlockhash = blockhash;
447 | payer.signTransaction(tx);
448 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
449 | await solConnection.confirmTransaction(txId, "confirmed");
450 | console.log("Your transaction signature", txId);
451 | }
452 |
453 | export const acceptOffer = async (
454 | mint: PublicKey,
455 | buyer: PublicKey,
456 | ) => {
457 | console.log(mint.toBase58(), buyer.toBase58());
458 |
459 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
460 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
461 | return;
462 | }
463 |
464 | const globalPool: GlobalPool = await getGlobalState(program);
465 |
466 | const tx = await createAcceptOfferTx(mint, buyer, globalPool.teamTreasury.slice(0, globalPool.teamCount.toNumber()), program, solConnection);
467 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
468 | tx.feePayer = payer.publicKey;
469 | tx.recentBlockhash = blockhash;
470 | payer.signTransaction(tx);
471 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
472 | await solConnection.confirmTransaction(txId, "confirmed");
473 | console.log("Your transaction signature", txId);
474 | }
475 |
476 | export const createAuction = async (
477 | mint: PublicKey,
478 | startPrice: number,
479 | minIncrease: number,
480 | duration: number,
481 | reserved: boolean,
482 | ) => {
483 | console.log(mint.toBase58(), startPrice, minIncrease, duration, reserved);
484 |
485 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
486 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
487 | return;
488 | }
489 |
490 | const [sellData, _] = await PublicKey.findProgramAddress(
491 | [Buffer.from(SELL_DATA_SEED), mint.toBuffer()],
492 | MARKETPLACE_PROGRAM_ID,
493 | );
494 | console.log('Sell Data PDA: ', sellData.toBase58());
495 |
496 | let poolAccount = await solConnection.getAccountInfo(sellData);
497 | if (poolAccount === null || poolAccount.data === null) {
498 | await initSellData(mint);
499 | }
500 |
501 | const [auctionData] = await PublicKey.findProgramAddress(
502 | [Buffer.from(AUCTION_DATA_SEED), mint.toBuffer()],
503 | MARKETPLACE_PROGRAM_ID,
504 | );
505 | console.log('Auction Data PDA: ', auctionData.toBase58());
506 |
507 | poolAccount = await solConnection.getAccountInfo(auctionData);
508 | if (poolAccount === null || poolAccount.data === null) {
509 | await initAuctionData(mint);
510 | }
511 |
512 | const tx = await createCreateAuctionTx(
513 | mint,
514 | payer.publicKey,
515 | startPrice,
516 | minIncrease,
517 | duration,
518 | reserved,
519 | program,
520 | solConnection,
521 | );
522 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
523 | tx.feePayer = payer.publicKey;
524 | tx.recentBlockhash = blockhash;
525 | payer.signTransaction(tx);
526 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
527 | await solConnection.confirmTransaction(txId, "confirmed");
528 | console.log("Your transaction signature", txId);
529 | }
530 |
531 | export const placeBid = async (
532 | mint: PublicKey,
533 | price: number,
534 | ) => {
535 | console.log(mint.toBase58(), price);
536 |
537 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
538 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
539 | return;
540 | }
541 |
542 | const tx = await createPlaceBidTx(mint, payer.publicKey, price, program);
543 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
544 | tx.feePayer = payer.publicKey;
545 | tx.recentBlockhash = blockhash;
546 | payer.signTransaction(tx);
547 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
548 | await solConnection.confirmTransaction(txId, "confirmed");
549 | console.log("Your transaction signature", txId);
550 | }
551 |
552 | export const claimAuction = async (
553 | mint: PublicKey,
554 | ) => {
555 | console.log(mint.toBase58());
556 |
557 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
558 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
559 | return;
560 | }
561 |
562 | const globalPool: GlobalPool = await getGlobalState(program);
563 |
564 | const tx = await createClaimAuctionTx(mint, payer.publicKey, globalPool.teamTreasury.slice(0, globalPool.teamCount.toNumber()), program, solConnection);
565 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
566 | tx.feePayer = payer.publicKey;
567 | tx.recentBlockhash = blockhash;
568 | payer.signTransaction(tx);
569 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
570 | await solConnection.confirmTransaction(txId, "confirmed");
571 | console.log("Your transaction signature", txId);
572 | }
573 |
574 | export const updateReserve = async (
575 | mint: PublicKey,
576 | newPrice: number,
577 | ) => {
578 | console.log(mint.toBase58(), newPrice);
579 |
580 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
581 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
582 | return;
583 | }
584 |
585 | const tx = await createUpdateReserveTx(mint, payer.publicKey, newPrice, program);
586 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
587 | tx.feePayer = payer.publicKey;
588 | tx.recentBlockhash = blockhash;
589 | payer.signTransaction(tx);
590 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
591 | await solConnection.confirmTransaction(txId, "confirmed");
592 | console.log("Your transaction signature", txId);
593 | }
594 |
595 | export const cancelAuction = async (
596 | mint: PublicKey,
597 | ) => {
598 | console.log(mint.toBase58());
599 |
600 | if (!await isInitializedUser(payer.publicKey, solConnection)) {
601 | console.log('User PDA is not Initialized. Should Init User PDA for first usage');
602 | return;
603 | }
604 |
605 | const tx = await createCancelAuctionTx(mint, payer.publicKey, program, solConnection);
606 | const { blockhash } = await solConnection.getRecentBlockhash('confirmed');
607 | tx.feePayer = payer.publicKey;
608 | tx.recentBlockhash = blockhash;
609 | payer.signTransaction(tx);
610 | let txId = await solConnection.sendTransaction(tx, [(payer as NodeWallet).payer]);
611 | await solConnection.confirmTransaction(txId, "confirmed");
612 | console.log("Your transaction signature", txId);
613 | }
614 |
615 | export const getNFTPoolInfo = async (
616 | mint: PublicKey,
617 | ) => {
618 | const nftData: SellData = await getNFTPoolState(mint, program);
619 | return {
620 | mint: nftData.mint.toBase58(),
621 | seller: nftData.seller.toBase58(),
622 | collection: nftData.collection.toBase58(),
623 | priceSol: nftData.priceSol.toNumber(),
624 | listedDate: nftData.listedDate.toNumber(),
625 | active: nftData.active.toNumber(),
626 | };
627 | }
628 |
629 | export const getOfferDataInfo = async (
630 | mint: PublicKey,
631 | userAddress: PublicKey,
632 | ) => {
633 | const offerData: OfferData = await getOfferDataState(mint, userAddress, program);
634 | return {
635 | mint: offerData.mint.toBase58(),
636 | buyer: offerData.buyer.toBase58(),
637 | offerPrice: offerData.offerPrice.toNumber(),
638 | offerListingDate: offerData.offerListingDate.toNumber(),
639 | active: offerData.active.toNumber(),
640 | };
641 | }
642 |
643 | export const getAuctionDataInfo = async (
644 | mint: PublicKey,
645 | ) => {
646 | const auctionData: AuctionData = await getAuctionDataState(mint, program);
647 | return {
648 | mint: auctionData.mint.toBase58(),
649 | creator: auctionData.creator.toBase58(),
650 | startPrice: auctionData.startPrice.toNumber(),
651 | minIncreaseAmount: auctionData.minIncreaseAmount.toNumber(),
652 | startDate: auctionData.startDate.toNumber(),
653 | lastBidder: auctionData.lastBidder.toBase58(),
654 | lastBidDate: auctionData.lastBidDate.toNumber(),
655 | highestBid: auctionData.highestBid.toNumber(),
656 | duration: auctionData.duration.toNumber(),
657 | status: auctionData.status.toNumber(),
658 | };
659 | }
660 |
661 | export const getUserPoolInfo = async (
662 | userAddress: PublicKey,
663 | ) => {
664 | const userData: UserData = await getUserPoolState(userAddress, program);
665 | return {
666 | address: userData.address.toBase58(),
667 | escrowSol: userData.escrowSolBalance.toNumber(),
668 | tradedVolume: userData.tradedVolume.toNumber(),
669 | };
670 | }
671 |
672 | export const getGlobalInfo = async () => {
673 | const globalPool: GlobalPool = await getGlobalState(program);
674 | const result = {
675 | admin: globalPool.superAdmin.toBase58(),
676 | marketFeeSol: globalPool.marketFeeSol.toNumber(),
677 | teamCount: globalPool.teamCount.toNumber(),
678 | teamTreasury: globalPool.teamTreasury.slice(0, globalPool.teamCount.toNumber()).map((info) => info.toBase58()),
679 | treasuryRate: globalPool.treasuryRate.slice(0, globalPool.teamCount.toNumber()).map((info) => info.toNumber()),
680 | };
681 |
682 | return result;
683 | }
684 |
685 | export const getAllNFTs = async (rpc?: string) => {
686 | return await getAllListedNFTs(solConnection, rpc);
687 | }
688 |
689 | export const getAllOffersForNFT = async (address: string, rpc?: string) => {
690 | return await getAllOffersForListedNFT(address, solConnection, rpc);
691 | }
692 |
693 | export const getAllAuctions = async (rpc?: string) => {
694 | return await getAllStartedAuctions(solConnection, rpc);
695 | }
--------------------------------------------------------------------------------
/target/idl/nut_marketplace.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "name": "nut_marketplace",
4 | "instructions": [
5 | {
6 | "name": "initialize",
7 | "accounts": [
8 | {
9 | "name": "admin",
10 | "isMut": true,
11 | "isSigner": true
12 | },
13 | {
14 | "name": "globalAuthority",
15 | "isMut": true,
16 | "isSigner": false
17 | },
18 | {
19 | "name": "escrowVault",
20 | "isMut": true,
21 | "isSigner": false
22 | },
23 | {
24 | "name": "systemProgram",
25 | "isMut": false,
26 | "isSigner": false
27 | },
28 | {
29 | "name": "rent",
30 | "isMut": false,
31 | "isSigner": false
32 | }
33 | ],
34 | "args": [
35 | {
36 | "name": "globalBump",
37 | "type": "u8"
38 | },
39 | {
40 | "name": "escrowBump",
41 | "type": "u8"
42 | }
43 | ]
44 | },
45 | {
46 | "name": "updateFee",
47 | "accounts": [
48 | {
49 | "name": "admin",
50 | "isMut": true,
51 | "isSigner": true
52 | },
53 | {
54 | "name": "globalAuthority",
55 | "isMut": true,
56 | "isSigner": false
57 | }
58 | ],
59 | "args": [
60 | {
61 | "name": "globalBump",
62 | "type": "u8"
63 | },
64 | {
65 | "name": "solFee",
66 | "type": "u64"
67 | }
68 | ]
69 | },
70 | {
71 | "name": "addTeamTreasury",
72 | "accounts": [
73 | {
74 | "name": "admin",
75 | "isMut": true,
76 | "isSigner": true
77 | },
78 | {
79 | "name": "globalAuthority",
80 | "isMut": true,
81 | "isSigner": false
82 | }
83 | ],
84 | "args": [
85 | {
86 | "name": "globalBump",
87 | "type": "u8"
88 | },
89 | {
90 | "name": "address",
91 | "type": "publicKey"
92 | },
93 | {
94 | "name": "rate",
95 | "type": "u64"
96 | }
97 | ]
98 | },
99 | {
100 | "name": "removeTeamTreasury",
101 | "accounts": [
102 | {
103 | "name": "admin",
104 | "isMut": true,
105 | "isSigner": true
106 | },
107 | {
108 | "name": "globalAuthority",
109 | "isMut": true,
110 | "isSigner": false
111 | }
112 | ],
113 | "args": [
114 | {
115 | "name": "globalBump",
116 | "type": "u8"
117 | },
118 | {
119 | "name": "address",
120 | "type": "publicKey"
121 | }
122 | ]
123 | },
124 | {
125 | "name": "initUserPool",
126 | "accounts": [
127 | {
128 | "name": "owner",
129 | "isMut": true,
130 | "isSigner": true
131 | },
132 | {
133 | "name": "userPool",
134 | "isMut": true,
135 | "isSigner": false
136 | },
137 | {
138 | "name": "systemProgram",
139 | "isMut": false,
140 | "isSigner": false
141 | },
142 | {
143 | "name": "rent",
144 | "isMut": false,
145 | "isSigner": false
146 | }
147 | ],
148 | "args": [
149 | {
150 | "name": "bump",
151 | "type": "u8"
152 | }
153 | ]
154 | },
155 | {
156 | "name": "initSellData",
157 | "accounts": [
158 | {
159 | "name": "payer",
160 | "isMut": true,
161 | "isSigner": true
162 | },
163 | {
164 | "name": "sellDataInfo",
165 | "isMut": true,
166 | "isSigner": false
167 | },
168 | {
169 | "name": "systemProgram",
170 | "isMut": false,
171 | "isSigner": false
172 | },
173 | {
174 | "name": "rent",
175 | "isMut": false,
176 | "isSigner": false
177 | }
178 | ],
179 | "args": [
180 | {
181 | "name": "nft",
182 | "type": "publicKey"
183 | },
184 | {
185 | "name": "bump",
186 | "type": "u8"
187 | }
188 | ]
189 | },
190 | {
191 | "name": "listNftForSale",
192 | "accounts": [
193 | {
194 | "name": "owner",
195 | "isMut": true,
196 | "isSigner": true
197 | },
198 | {
199 | "name": "globalAuthority",
200 | "isMut": true,
201 | "isSigner": false
202 | },
203 | {
204 | "name": "sellDataInfo",
205 | "isMut": true,
206 | "isSigner": false
207 | },
208 | {
209 | "name": "userTokenAccount",
210 | "isMut": true,
211 | "isSigner": false
212 | },
213 | {
214 | "name": "destNftTokenAccount",
215 | "isMut": true,
216 | "isSigner": false
217 | },
218 | {
219 | "name": "nftMint",
220 | "isMut": false,
221 | "isSigner": false
222 | },
223 | {
224 | "name": "mintMetadata",
225 | "isMut": true,
226 | "isSigner": false
227 | },
228 | {
229 | "name": "tokenProgram",
230 | "isMut": false,
231 | "isSigner": false
232 | },
233 | {
234 | "name": "tokenMetadataProgram",
235 | "isMut": false,
236 | "isSigner": false
237 | },
238 | {
239 | "name": "auctionDataInfo",
240 | "isMut": true,
241 | "isSigner": false
242 | }
243 | ],
244 | "args": [
245 | {
246 | "name": "globalBump",
247 | "type": "u8"
248 | },
249 | {
250 | "name": "sellBump",
251 | "type": "u8"
252 | },
253 | {
254 | "name": "auctionBump",
255 | "type": "u8"
256 | },
257 | {
258 | "name": "priceSol",
259 | "type": "u64"
260 | }
261 | ]
262 | },
263 | {
264 | "name": "delistNft",
265 | "accounts": [
266 | {
267 | "name": "owner",
268 | "isMut": true,
269 | "isSigner": true
270 | },
271 | {
272 | "name": "globalAuthority",
273 | "isMut": true,
274 | "isSigner": false
275 | },
276 | {
277 | "name": "sellDataInfo",
278 | "isMut": true,
279 | "isSigner": false
280 | },
281 | {
282 | "name": "userTokenAccount",
283 | "isMut": true,
284 | "isSigner": false
285 | },
286 | {
287 | "name": "destNftTokenAccount",
288 | "isMut": true,
289 | "isSigner": false
290 | },
291 | {
292 | "name": "nftMint",
293 | "isMut": false,
294 | "isSigner": false
295 | },
296 | {
297 | "name": "tokenProgram",
298 | "isMut": false,
299 | "isSigner": false
300 | },
301 | {
302 | "name": "auctionDataInfo",
303 | "isMut": true,
304 | "isSigner": false
305 | }
306 | ],
307 | "args": [
308 | {
309 | "name": "globalBump",
310 | "type": "u8"
311 | },
312 | {
313 | "name": "sellBump",
314 | "type": "u8"
315 | }
316 | ]
317 | },
318 | {
319 | "name": "setPrice",
320 | "accounts": [
321 | {
322 | "name": "owner",
323 | "isMut": true,
324 | "isSigner": true
325 | },
326 | {
327 | "name": "sellDataInfo",
328 | "isMut": true,
329 | "isSigner": false
330 | },
331 | {
332 | "name": "nftMint",
333 | "isMut": false,
334 | "isSigner": false
335 | }
336 | ],
337 | "args": [
338 | {
339 | "name": "sellBump",
340 | "type": "u8"
341 | },
342 | {
343 | "name": "price",
344 | "type": "u64"
345 | }
346 | ]
347 | },
348 | {
349 | "name": "transfer",
350 | "accounts": [
351 | {
352 | "name": "owner",
353 | "isMut": true,
354 | "isSigner": true
355 | },
356 | {
357 | "name": "userTokenAccount",
358 | "isMut": true,
359 | "isSigner": false
360 | },
361 | {
362 | "name": "recipient",
363 | "isMut": true,
364 | "isSigner": false
365 | },
366 | {
367 | "name": "destNftTokenAccount",
368 | "isMut": true,
369 | "isSigner": false
370 | },
371 | {
372 | "name": "nftMint",
373 | "isMut": false,
374 | "isSigner": false
375 | },
376 | {
377 | "name": "tokenProgram",
378 | "isMut": false,
379 | "isSigner": false
380 | }
381 | ],
382 | "args": []
383 | },
384 | {
385 | "name": "transferFromVault",
386 | "accounts": [
387 | {
388 | "name": "owner",
389 | "isMut": true,
390 | "isSigner": true
391 | },
392 | {
393 | "name": "globalAuthority",
394 | "isMut": true,
395 | "isSigner": false
396 | },
397 | {
398 | "name": "sellDataInfo",
399 | "isMut": true,
400 | "isSigner": false
401 | },
402 | {
403 | "name": "recipient",
404 | "isMut": true,
405 | "isSigner": false
406 | },
407 | {
408 | "name": "userTokenAccount",
409 | "isMut": true,
410 | "isSigner": false
411 | },
412 | {
413 | "name": "destNftTokenAccount",
414 | "isMut": true,
415 | "isSigner": false
416 | },
417 | {
418 | "name": "nftMint",
419 | "isMut": false,
420 | "isSigner": false
421 | },
422 | {
423 | "name": "tokenProgram",
424 | "isMut": false,
425 | "isSigner": false
426 | },
427 | {
428 | "name": "auctionDataInfo",
429 | "isMut": true,
430 | "isSigner": false
431 | }
432 | ],
433 | "args": [
434 | {
435 | "name": "globalBump",
436 | "type": "u8"
437 | },
438 | {
439 | "name": "sellBump",
440 | "type": "u8"
441 | }
442 | ]
443 | },
444 | {
445 | "name": "purchase",
446 | "accounts": [
447 | {
448 | "name": "buyer",
449 | "isMut": true,
450 | "isSigner": true
451 | },
452 | {
453 | "name": "globalAuthority",
454 | "isMut": true,
455 | "isSigner": false
456 | },
457 | {
458 | "name": "sellDataInfo",
459 | "isMut": true,
460 | "isSigner": false
461 | },
462 | {
463 | "name": "buyerUserPool",
464 | "isMut": true,
465 | "isSigner": false
466 | },
467 | {
468 | "name": "userNftTokenAccount",
469 | "isMut": true,
470 | "isSigner": false
471 | },
472 | {
473 | "name": "destNftTokenAccount",
474 | "isMut": true,
475 | "isSigner": false
476 | },
477 | {
478 | "name": "seller",
479 | "isMut": true,
480 | "isSigner": false
481 | },
482 | {
483 | "name": "sellerUserPool",
484 | "isMut": true,
485 | "isSigner": false
486 | },
487 | {
488 | "name": "nftMint",
489 | "isMut": false,
490 | "isSigner": false
491 | },
492 | {
493 | "name": "mintMetadata",
494 | "isMut": true,
495 | "isSigner": false
496 | },
497 | {
498 | "name": "tokenProgram",
499 | "isMut": false,
500 | "isSigner": false
501 | },
502 | {
503 | "name": "systemProgram",
504 | "isMut": false,
505 | "isSigner": false
506 | },
507 | {
508 | "name": "tokenMetadataProgram",
509 | "isMut": false,
510 | "isSigner": false
511 | },
512 | {
513 | "name": "auctionDataInfo",
514 | "isMut": true,
515 | "isSigner": false
516 | }
517 | ],
518 | "args": [
519 | {
520 | "name": "globalBump",
521 | "type": "u8"
522 | },
523 | {
524 | "name": "nftBump",
525 | "type": "u8"
526 | },
527 | {
528 | "name": "sellerBump",
529 | "type": "u8"
530 | },
531 | {
532 | "name": "buyerBump",
533 | "type": "u8"
534 | }
535 | ]
536 | },
537 | {
538 | "name": "depositToEscrow",
539 | "accounts": [
540 | {
541 | "name": "owner",
542 | "isMut": true,
543 | "isSigner": true
544 | },
545 | {
546 | "name": "userPool",
547 | "isMut": true,
548 | "isSigner": false
549 | },
550 | {
551 | "name": "escrowVault",
552 | "isMut": true,
553 | "isSigner": false
554 | },
555 | {
556 | "name": "systemProgram",
557 | "isMut": false,
558 | "isSigner": false
559 | }
560 | ],
561 | "args": [
562 | {
563 | "name": "userBump",
564 | "type": "u8"
565 | },
566 | {
567 | "name": "escrowBump",
568 | "type": "u8"
569 | },
570 | {
571 | "name": "sol",
572 | "type": "u64"
573 | }
574 | ]
575 | },
576 | {
577 | "name": "withdrawFromEscrow",
578 | "accounts": [
579 | {
580 | "name": "owner",
581 | "isMut": true,
582 | "isSigner": true
583 | },
584 | {
585 | "name": "userPool",
586 | "isMut": true,
587 | "isSigner": false
588 | },
589 | {
590 | "name": "escrowVault",
591 | "isMut": true,
592 | "isSigner": false
593 | },
594 | {
595 | "name": "systemProgram",
596 | "isMut": false,
597 | "isSigner": false
598 | }
599 | ],
600 | "args": [
601 | {
602 | "name": "userBump",
603 | "type": "u8"
604 | },
605 | {
606 | "name": "escrowBump",
607 | "type": "u8"
608 | },
609 | {
610 | "name": "sol",
611 | "type": "u64"
612 | }
613 | ]
614 | },
615 | {
616 | "name": "initOfferData",
617 | "accounts": [
618 | {
619 | "name": "payer",
620 | "isMut": true,
621 | "isSigner": true
622 | },
623 | {
624 | "name": "offerDataInfo",
625 | "isMut": true,
626 | "isSigner": false
627 | },
628 | {
629 | "name": "systemProgram",
630 | "isMut": false,
631 | "isSigner": false
632 | },
633 | {
634 | "name": "rent",
635 | "isMut": false,
636 | "isSigner": false
637 | }
638 | ],
639 | "args": [
640 | {
641 | "name": "nft",
642 | "type": "publicKey"
643 | },
644 | {
645 | "name": "bump",
646 | "type": "u8"
647 | }
648 | ]
649 | },
650 | {
651 | "name": "makeOffer",
652 | "accounts": [
653 | {
654 | "name": "owner",
655 | "isMut": true,
656 | "isSigner": true
657 | },
658 | {
659 | "name": "sellDataInfo",
660 | "isMut": true,
661 | "isSigner": false
662 | },
663 | {
664 | "name": "offerDataInfo",
665 | "isMut": true,
666 | "isSigner": false
667 | },
668 | {
669 | "name": "nftMint",
670 | "isMut": false,
671 | "isSigner": false
672 | },
673 | {
674 | "name": "userPool",
675 | "isMut": true,
676 | "isSigner": false
677 | },
678 | {
679 | "name": "escrowVault",
680 | "isMut": true,
681 | "isSigner": false
682 | },
683 | {
684 | "name": "systemProgram",
685 | "isMut": false,
686 | "isSigner": false
687 | }
688 | ],
689 | "args": [
690 | {
691 | "name": "sellBump",
692 | "type": "u8"
693 | },
694 | {
695 | "name": "offerBump",
696 | "type": "u8"
697 | },
698 | {
699 | "name": "userBump",
700 | "type": "u8"
701 | },
702 | {
703 | "name": "escrowBump",
704 | "type": "u8"
705 | },
706 | {
707 | "name": "price",
708 | "type": "u64"
709 | }
710 | ]
711 | },
712 | {
713 | "name": "cancelOffer",
714 | "accounts": [
715 | {
716 | "name": "owner",
717 | "isMut": true,
718 | "isSigner": true
719 | },
720 | {
721 | "name": "offerDataInfo",
722 | "isMut": true,
723 | "isSigner": false
724 | },
725 | {
726 | "name": "nftMint",
727 | "isMut": false,
728 | "isSigner": false
729 | }
730 | ],
731 | "args": [
732 | {
733 | "name": "offerBump",
734 | "type": "u8"
735 | }
736 | ]
737 | },
738 | {
739 | "name": "acceptOffer",
740 | "accounts": [
741 | {
742 | "name": "seller",
743 | "isMut": true,
744 | "isSigner": true
745 | },
746 | {
747 | "name": "sellDataInfo",
748 | "isMut": true,
749 | "isSigner": false
750 | },
751 | {
752 | "name": "buyer",
753 | "isMut": true,
754 | "isSigner": false
755 | },
756 | {
757 | "name": "offerDataInfo",
758 | "isMut": true,
759 | "isSigner": false
760 | },
761 | {
762 | "name": "sellerUserPool",
763 | "isMut": true,
764 | "isSigner": false
765 | },
766 | {
767 | "name": "nftMint",
768 | "isMut": false,
769 | "isSigner": false
770 | },
771 | {
772 | "name": "globalAuthority",
773 | "isMut": true,
774 | "isSigner": false
775 | },
776 | {
777 | "name": "buyerUserPool",
778 | "isMut": true,
779 | "isSigner": false
780 | },
781 | {
782 | "name": "userNftTokenAccount",
783 | "isMut": true,
784 | "isSigner": false
785 | },
786 | {
787 | "name": "destNftTokenAccount",
788 | "isMut": true,
789 | "isSigner": false
790 | },
791 | {
792 | "name": "escrowVault",
793 | "isMut": true,
794 | "isSigner": false
795 | },
796 | {
797 | "name": "mintMetadata",
798 | "isMut": true,
799 | "isSigner": false
800 | },
801 | {
802 | "name": "tokenProgram",
803 | "isMut": false,
804 | "isSigner": false
805 | },
806 | {
807 | "name": "systemProgram",
808 | "isMut": false,
809 | "isSigner": false
810 | },
811 | {
812 | "name": "tokenMetadataProgram",
813 | "isMut": false,
814 | "isSigner": false
815 | },
816 | {
817 | "name": "auctionDataInfo",
818 | "isMut": true,
819 | "isSigner": false
820 | }
821 | ],
822 | "args": [
823 | {
824 | "name": "globalBump",
825 | "type": "u8"
826 | },
827 | {
828 | "name": "nftBump",
829 | "type": "u8"
830 | },
831 | {
832 | "name": "offerBump",
833 | "type": "u8"
834 | },
835 | {
836 | "name": "buyerBump",
837 | "type": "u8"
838 | },
839 | {
840 | "name": "sellerBump",
841 | "type": "u8"
842 | },
843 | {
844 | "name": "escrowBump",
845 | "type": "u8"
846 | }
847 | ]
848 | },
849 | {
850 | "name": "initAuctionData",
851 | "accounts": [
852 | {
853 | "name": "payer",
854 | "isMut": true,
855 | "isSigner": true
856 | },
857 | {
858 | "name": "auctionDataInfo",
859 | "isMut": true,
860 | "isSigner": false
861 | },
862 | {
863 | "name": "systemProgram",
864 | "isMut": false,
865 | "isSigner": false
866 | },
867 | {
868 | "name": "rent",
869 | "isMut": false,
870 | "isSigner": false
871 | }
872 | ],
873 | "args": [
874 | {
875 | "name": "nft",
876 | "type": "publicKey"
877 | },
878 | {
879 | "name": "bump",
880 | "type": "u8"
881 | }
882 | ]
883 | },
884 | {
885 | "name": "createAuction",
886 | "accounts": [
887 | {
888 | "name": "owner",
889 | "isMut": true,
890 | "isSigner": true
891 | },
892 | {
893 | "name": "globalAuthority",
894 | "isMut": true,
895 | "isSigner": false
896 | },
897 | {
898 | "name": "auctionDataInfo",
899 | "isMut": true,
900 | "isSigner": false
901 | },
902 | {
903 | "name": "userTokenAccount",
904 | "isMut": true,
905 | "isSigner": false
906 | },
907 | {
908 | "name": "destNftTokenAccount",
909 | "isMut": true,
910 | "isSigner": false
911 | },
912 | {
913 | "name": "nftMint",
914 | "isMut": false,
915 | "isSigner": false
916 | },
917 | {
918 | "name": "tokenProgram",
919 | "isMut": false,
920 | "isSigner": false
921 | },
922 | {
923 | "name": "sellDataInfo",
924 | "isMut": true,
925 | "isSigner": false
926 | }
927 | ],
928 | "args": [
929 | {
930 | "name": "globalBump",
931 | "type": "u8"
932 | },
933 | {
934 | "name": "auctionBump",
935 | "type": "u8"
936 | },
937 | {
938 | "name": "sellBump",
939 | "type": "u8"
940 | },
941 | {
942 | "name": "startPrice",
943 | "type": "u64"
944 | },
945 | {
946 | "name": "minIncrease",
947 | "type": "u64"
948 | },
949 | {
950 | "name": "duration",
951 | "type": "i64"
952 | },
953 | {
954 | "name": "reserved",
955 | "type": "u8"
956 | }
957 | ]
958 | },
959 | {
960 | "name": "placeBid",
961 | "accounts": [
962 | {
963 | "name": "bidder",
964 | "isMut": true,
965 | "isSigner": true
966 | },
967 | {
968 | "name": "auctionDataInfo",
969 | "isMut": true,
970 | "isSigner": false
971 | },
972 | {
973 | "name": "nftMint",
974 | "isMut": false,
975 | "isSigner": false
976 | },
977 | {
978 | "name": "escrowVault",
979 | "isMut": true,
980 | "isSigner": false
981 | },
982 | {
983 | "name": "outBidder",
984 | "isMut": true,
985 | "isSigner": false
986 | },
987 | {
988 | "name": "systemProgram",
989 | "isMut": false,
990 | "isSigner": false
991 | },
992 | {
993 | "name": "sellDataInfo",
994 | "isMut": true,
995 | "isSigner": false
996 | }
997 | ],
998 | "args": [
999 | {
1000 | "name": "auctionBump",
1001 | "type": "u8"
1002 | },
1003 | {
1004 | "name": "escrowBump",
1005 | "type": "u8"
1006 | },
1007 | {
1008 | "name": "price",
1009 | "type": "u64"
1010 | }
1011 | ]
1012 | },
1013 | {
1014 | "name": "claimAuction",
1015 | "accounts": [
1016 | {
1017 | "name": "bidder",
1018 | "isMut": true,
1019 | "isSigner": true
1020 | },
1021 | {
1022 | "name": "globalAuthority",
1023 | "isMut": true,
1024 | "isSigner": false
1025 | },
1026 | {
1027 | "name": "auctionDataInfo",
1028 | "isMut": true,
1029 | "isSigner": false
1030 | },
1031 | {
1032 | "name": "userTokenAccount",
1033 | "isMut": true,
1034 | "isSigner": false
1035 | },
1036 | {
1037 | "name": "destNftTokenAccount",
1038 | "isMut": true,
1039 | "isSigner": false
1040 | },
1041 | {
1042 | "name": "nftMint",
1043 | "isMut": false,
1044 | "isSigner": false
1045 | },
1046 | {
1047 | "name": "escrowVault",
1048 | "isMut": true,
1049 | "isSigner": false
1050 | },
1051 | {
1052 | "name": "bidderUserPool",
1053 | "isMut": true,
1054 | "isSigner": false
1055 | },
1056 | {
1057 | "name": "creator",
1058 | "isMut": true,
1059 | "isSigner": false
1060 | },
1061 | {
1062 | "name": "creatorUserPool",
1063 | "isMut": true,
1064 | "isSigner": false
1065 | },
1066 | {
1067 | "name": "mintMetadata",
1068 | "isMut": true,
1069 | "isSigner": false
1070 | },
1071 | {
1072 | "name": "tokenProgram",
1073 | "isMut": false,
1074 | "isSigner": false
1075 | },
1076 | {
1077 | "name": "systemProgram",
1078 | "isMut": false,
1079 | "isSigner": false
1080 | },
1081 | {
1082 | "name": "tokenMetadataProgram",
1083 | "isMut": false,
1084 | "isSigner": false
1085 | }
1086 | ],
1087 | "args": [
1088 | {
1089 | "name": "globalBump",
1090 | "type": "u8"
1091 | },
1092 | {
1093 | "name": "auctionBump",
1094 | "type": "u8"
1095 | },
1096 | {
1097 | "name": "escrowBump",
1098 | "type": "u8"
1099 | }
1100 | ]
1101 | },
1102 | {
1103 | "name": "updateReserve",
1104 | "accounts": [
1105 | {
1106 | "name": "creator",
1107 | "isMut": true,
1108 | "isSigner": true
1109 | },
1110 | {
1111 | "name": "auctionDataInfo",
1112 | "isMut": true,
1113 | "isSigner": false
1114 | },
1115 | {
1116 | "name": "nftMint",
1117 | "isMut": false,
1118 | "isSigner": false
1119 | }
1120 | ],
1121 | "args": [
1122 | {
1123 | "name": "auctionBump",
1124 | "type": "u8"
1125 | },
1126 | {
1127 | "name": "price",
1128 | "type": "u64"
1129 | }
1130 | ]
1131 | },
1132 | {
1133 | "name": "cancelAuction",
1134 | "accounts": [
1135 | {
1136 | "name": "creator",
1137 | "isMut": true,
1138 | "isSigner": true
1139 | },
1140 | {
1141 | "name": "globalAuthority",
1142 | "isMut": true,
1143 | "isSigner": false
1144 | },
1145 | {
1146 | "name": "auctionDataInfo",
1147 | "isMut": true,
1148 | "isSigner": false
1149 | },
1150 | {
1151 | "name": "userTokenAccount",
1152 | "isMut": true,
1153 | "isSigner": false
1154 | },
1155 | {
1156 | "name": "destNftTokenAccount",
1157 | "isMut": true,
1158 | "isSigner": false
1159 | },
1160 | {
1161 | "name": "nftMint",
1162 | "isMut": false,
1163 | "isSigner": false
1164 | },
1165 | {
1166 | "name": "tokenProgram",
1167 | "isMut": false,
1168 | "isSigner": false
1169 | },
1170 | {
1171 | "name": "sellDataInfo",
1172 | "isMut": true,
1173 | "isSigner": false
1174 | }
1175 | ],
1176 | "args": [
1177 | {
1178 | "name": "globalBump",
1179 | "type": "u8"
1180 | },
1181 | {
1182 | "name": "auctionBump",
1183 | "type": "u8"
1184 | }
1185 | ]
1186 | }
1187 | ],
1188 | "accounts": [
1189 | {
1190 | "name": "GlobalPool",
1191 | "type": {
1192 | "kind": "struct",
1193 | "fields": [
1194 | {
1195 | "name": "superAdmin",
1196 | "type": "publicKey"
1197 | },
1198 | {
1199 | "name": "marketFeeSol",
1200 | "type": "u64"
1201 | },
1202 | {
1203 | "name": "teamCount",
1204 | "type": "u64"
1205 | },
1206 | {
1207 | "name": "teamTreasury",
1208 | "type": {
1209 | "array": [
1210 | "publicKey",
1211 | 8
1212 | ]
1213 | }
1214 | },
1215 | {
1216 | "name": "treasuryRate",
1217 | "type": {
1218 | "array": [
1219 | "u64",
1220 | 8
1221 | ]
1222 | }
1223 | }
1224 | ]
1225 | }
1226 | },
1227 | {
1228 | "name": "SellData",
1229 | "type": {
1230 | "kind": "struct",
1231 | "fields": [
1232 | {
1233 | "name": "mint",
1234 | "type": "publicKey"
1235 | },
1236 | {
1237 | "name": "seller",
1238 | "type": "publicKey"
1239 | },
1240 | {
1241 | "name": "collection",
1242 | "type": "publicKey"
1243 | },
1244 | {
1245 | "name": "priceSol",
1246 | "type": "u64"
1247 | },
1248 | {
1249 | "name": "listedDate",
1250 | "type": "i64"
1251 | },
1252 | {
1253 | "name": "active",
1254 | "type": "u64"
1255 | }
1256 | ]
1257 | }
1258 | },
1259 | {
1260 | "name": "OfferData",
1261 | "type": {
1262 | "kind": "struct",
1263 | "fields": [
1264 | {
1265 | "name": "mint",
1266 | "type": "publicKey"
1267 | },
1268 | {
1269 | "name": "buyer",
1270 | "type": "publicKey"
1271 | },
1272 | {
1273 | "name": "offerPrice",
1274 | "type": "u64"
1275 | },
1276 | {
1277 | "name": "offerListingDate",
1278 | "type": "i64"
1279 | },
1280 | {
1281 | "name": "active",
1282 | "type": "u64"
1283 | }
1284 | ]
1285 | }
1286 | },
1287 | {
1288 | "name": "AuctionData",
1289 | "type": {
1290 | "kind": "struct",
1291 | "fields": [
1292 | {
1293 | "name": "mint",
1294 | "type": "publicKey"
1295 | },
1296 | {
1297 | "name": "creator",
1298 | "type": "publicKey"
1299 | },
1300 | {
1301 | "name": "startPrice",
1302 | "type": "u64"
1303 | },
1304 | {
1305 | "name": "minIncreaseAmount",
1306 | "type": "u64"
1307 | },
1308 | {
1309 | "name": "startDate",
1310 | "type": "i64"
1311 | },
1312 | {
1313 | "name": "lastBidDate",
1314 | "type": "i64"
1315 | },
1316 | {
1317 | "name": "lastBidder",
1318 | "type": "publicKey"
1319 | },
1320 | {
1321 | "name": "highestBid",
1322 | "type": "u64"
1323 | },
1324 | {
1325 | "name": "duration",
1326 | "type": "i64"
1327 | },
1328 | {
1329 | "name": "status",
1330 | "type": "u64"
1331 | }
1332 | ]
1333 | }
1334 | },
1335 | {
1336 | "name": "UserData",
1337 | "type": {
1338 | "kind": "struct",
1339 | "fields": [
1340 | {
1341 | "name": "address",
1342 | "type": "publicKey"
1343 | },
1344 | {
1345 | "name": "tradedVolume",
1346 | "type": "u64"
1347 | },
1348 | {
1349 | "name": "escrowSolBalance",
1350 | "type": "u64"
1351 | }
1352 | ]
1353 | }
1354 | }
1355 | ],
1356 | "errors": [
1357 | {
1358 | "code": 6000,
1359 | "name": "InvalidSuperOwner",
1360 | "msg": "Invalid Super Owner"
1361 | },
1362 | {
1363 | "code": 6001,
1364 | "name": "InvalidOwner",
1365 | "msg": "Invalid Owner"
1366 | },
1367 | {
1368 | "code": 6002,
1369 | "name": "InvalidGlobalPool",
1370 | "msg": "Invalid Global Pool Address"
1371 | },
1372 | {
1373 | "code": 6003,
1374 | "name": "InvalidFeePercent",
1375 | "msg": "Marketplace Fee is Permyriad"
1376 | },
1377 | {
1378 | "code": 6004,
1379 | "name": "MaxTeamCountExceed",
1380 | "msg": "Max Team Count is 8"
1381 | },
1382 | {
1383 | "code": 6005,
1384 | "name": "NoTeamTreasuryYet",
1385 | "msg": "Treasury Wallet Not Configured"
1386 | },
1387 | {
1388 | "code": 6006,
1389 | "name": "TreasuryAddressNotFound",
1390 | "msg": "Treasury Address Not Exist"
1391 | },
1392 | {
1393 | "code": 6007,
1394 | "name": "TreasuryAddressAlreadyAdded",
1395 | "msg": "Treasury Address Already Exist"
1396 | },
1397 | {
1398 | "code": 6008,
1399 | "name": "MaxTreasuryRateSumExceed",
1400 | "msg": "Total Treasury Rate Sum Should Less Than 100%"
1401 | },
1402 | {
1403 | "code": 6009,
1404 | "name": "TeamTreasuryCountMismatch",
1405 | "msg": "Team Treasury Wallet Count Mismatch"
1406 | },
1407 | {
1408 | "code": 6010,
1409 | "name": "TeamTreasuryAddressMismatch",
1410 | "msg": "Team Treasury Wallet Address Mismatch"
1411 | },
1412 | {
1413 | "code": 6011,
1414 | "name": "Uninitialized",
1415 | "msg": "Uninitialized Account"
1416 | },
1417 | {
1418 | "code": 6012,
1419 | "name": "InvalidParamInput",
1420 | "msg": "Instruction Parameter is Invalid"
1421 | },
1422 | {
1423 | "code": 6013,
1424 | "name": "SellerMismatch",
1425 | "msg": "Payer Mismatch with NFT Seller"
1426 | },
1427 | {
1428 | "code": 6014,
1429 | "name": "InvalidNFTDataAcount",
1430 | "msg": "Invalid NFT Data Account"
1431 | },
1432 | {
1433 | "code": 6015,
1434 | "name": "NotListedNFT",
1435 | "msg": "The NFT Is Not Listed"
1436 | },
1437 | {
1438 | "code": 6016,
1439 | "name": "SellerAccountMismatch",
1440 | "msg": "Seller Account Mismatch with NFT Seller Data"
1441 | },
1442 | {
1443 | "code": 6017,
1444 | "name": "InsufficientBuyerSolBalance",
1445 | "msg": "Buyer Sol Balance is Less than NFT SOL Price"
1446 | },
1447 | {
1448 | "code": 6018,
1449 | "name": "InsufficientBuyerTokenBalance",
1450 | "msg": "Buyer Token Balance is Less than NFT Token Price"
1451 | },
1452 | {
1453 | "code": 6019,
1454 | "name": "InvaliedMetadata",
1455 | "msg": "Invalid Metadata Address"
1456 | },
1457 | {
1458 | "code": 6020,
1459 | "name": "MetadataCreatorParseError",
1460 | "msg": "Can't Parse The NFT's Creators"
1461 | },
1462 | {
1463 | "code": 6021,
1464 | "name": "InvalidOfferDataMint",
1465 | "msg": "Offer Data Mint mismatch with NFT Pubkey"
1466 | },
1467 | {
1468 | "code": 6022,
1469 | "name": "InvalidOfferDataBuyer",
1470 | "msg": "Offer Data Buyer mismatch with Payer Pubkey"
1471 | },
1472 | {
1473 | "code": 6023,
1474 | "name": "OfferForNotListedNFT",
1475 | "msg": "Making Offer for Not Listed NFT"
1476 | },
1477 | {
1478 | "code": 6024,
1479 | "name": "InvalidOfferPrice",
1480 | "msg": "Offer Price Over Thank Listed Price"
1481 | },
1482 | {
1483 | "code": 6025,
1484 | "name": "DisabledOffer",
1485 | "msg": "Already Canceled Offer"
1486 | },
1487 | {
1488 | "code": 6026,
1489 | "name": "OfferForExpiredListingNFT",
1490 | "msg": "Offer For Sold Or Canceled NFT Listing"
1491 | },
1492 | {
1493 | "code": 6027,
1494 | "name": "EndedAuction",
1495 | "msg": "Placing Bid For Ended Auction"
1496 | },
1497 | {
1498 | "code": 6028,
1499 | "name": "InvalidBidPrice",
1500 | "msg": "Placing Bid With Lower Than Highest Bid"
1501 | },
1502 | {
1503 | "code": 6029,
1504 | "name": "DoubleBidFromOneBidder",
1505 | "msg": "Placing Bid Double From One Bidder"
1506 | },
1507 | {
1508 | "code": 6030,
1509 | "name": "OutBidderMismatch",
1510 | "msg": "Out Bidder Account Mismatch With LastBidder Data"
1511 | },
1512 | {
1513 | "code": 6031,
1514 | "name": "NotEndedAuction",
1515 | "msg": "Claiming Auction For Not Ended Auction"
1516 | },
1517 | {
1518 | "code": 6032,
1519 | "name": "CreatorAccountMismatch",
1520 | "msg": "Creator Account Mismatch with Auction Data"
1521 | },
1522 | {
1523 | "code": 6033,
1524 | "name": "BidderAccountMismatch",
1525 | "msg": "Bidder Account Mismatch with Auction Data"
1526 | },
1527 | {
1528 | "code": 6034,
1529 | "name": "AuctionHasBid",
1530 | "msg": "Canceling Auction which has Bid"
1531 | },
1532 | {
1533 | "code": 6035,
1534 | "name": "BidFromAuctionCreator",
1535 | "msg": "Placing Bid From Auction Creator"
1536 | },
1537 | {
1538 | "code": 6036,
1539 | "name": "ListingNotAvailable",
1540 | "msg": "Only Listing and Reserved Auction are possible to exist together"
1541 | },
1542 | {
1543 | "code": 6037,
1544 | "name": "NFTIsNotInUserATA",
1545 | "msg": "NFT Is Not In User ATA"
1546 | },
1547 | {
1548 | "code": 6038,
1549 | "name": "NFTIsNotInEscrowATA",
1550 | "msg": "NFT Is Not In Escrow ATA"
1551 | }
1552 | ]
1553 | }
--------------------------------------------------------------------------------
/tests/nut_marketplace.ts:
--------------------------------------------------------------------------------
1 | import * as anchor from "@project-serum/anchor";
2 | import { Program } from "@project-serum/anchor";
3 | import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
4 | import { assert } from "chai";
5 | import fs from "fs";
6 | import {
7 | createAcceptOfferTx,
8 | createAddTreasuryTx,
9 | createCancelAuctionTx,
10 | createCancelOfferTx,
11 | createClaimAuctionTx,
12 | createCreateAuctionTx,
13 | createDelistNftTx,
14 | createDepositTx,
15 | createInitAuctionDataTx,
16 | createInitializeTx,
17 | createInitOfferDataTx,
18 | createInitSellDataTx,
19 | createInitUserTx,
20 | createListForSellNftTx,
21 | createMakeOfferTx,
22 | createPlaceBidTx,
23 | createPurchaseTx,
24 | createRemoveTreasuryTx,
25 | createUpdateFeeTx,
26 | createWithdrawTx,
27 | getAuctionDataState,
28 | getGlobalState,
29 | getNFTPoolState,
30 | getOfferDataState,
31 | getUserPoolState,
32 | } from "../lib/scripts";
33 | import { ABB_TOKEN_DECIMAL, ABB_TOKEN_MINT, MARKETPLACE_PROGRAM_ID, SELL_DATA_SEED, USER_DATA_SEED } from "../lib/types";
34 | import { airdropSOL, createTokenMint, getAssociatedTokenAccount, getATokenAccountsNeedCreate, getEscrowBalance, getTokenAccountBalance, isExistAccount } from "../lib/utils";
35 | import { NutMarketplace } from "../target/types/nut_marketplace";
36 |
37 | // Configure the client to use the local cluster.
38 | const provider = anchor.AnchorProvider.env();
39 | anchor.setProvider(provider);
40 | const payer = provider.wallet;
41 | console.log('Payer: ', payer.publicKey.toBase58());
42 |
43 | const program = anchor.workspace.NutMarketplace as Program;
44 |
45 | let superOwner = null;
46 | let user = null;
47 | let user1 = null;
48 | let reward = null;
49 | let nft = null;
50 |
51 | describe("Nut_Marketplace Load Program Object & Prepare testers", () => {
52 | assert(program.programId.toBase58() == MARKETPLACE_PROGRAM_ID.toBase58(), "Program load Failure!");
53 |
54 | it('Load Testers', async () => {
55 | const rawdata = fs.readFileSync(process.env.ANCHOR_WALLET);
56 | const keyData = JSON.parse(rawdata.toString());
57 |
58 | superOwner = anchor.web3.Keypair.fromSecretKey(new Uint8Array(keyData));
59 | user = anchor.web3.Keypair.generate();
60 | user1 = anchor.web3.Keypair.generate();
61 |
62 | console.log('Admin: ', superOwner.publicKey.toBase58());
63 | console.log('User: ', user.publicKey.toBase58());
64 | console.log('user1: ', user1.publicKey.toBase58());
65 | });
66 | it('Load Reward Token', async () => {
67 | const rawdata = fs.readFileSync('./tests/keys/reward_mint.json');
68 | const keyData = JSON.parse(rawdata.toString());
69 | reward = anchor.web3.Keypair.fromSecretKey(new Uint8Array(keyData));
70 | assert(reward.publicKey.toBase58() == ABB_TOKEN_MINT.toBase58(), 'Load ABB Token Keypair Failure!');
71 |
72 | await createTokenMint(
73 | provider.connection,
74 | superOwner,
75 | reward,
76 | );
77 |
78 | assert(await isExistAccount(reward.publicKey, provider.connection), 'Create ABB Token mint failure!');
79 | });
80 | it('Airdrop SOL for Testers', async () => {
81 | await airdropSOL(user.publicKey, 1000 * 1e9, provider.connection);
82 | let res = await provider.connection.getBalance(user.publicKey);
83 | assert(res == 1000 * 1e9, 'Airdrop 1000 SOL for user Failed');
84 |
85 | await airdropSOL(user1.publicKey, 1000 * 1e9, provider.connection);
86 | res = await provider.connection.getBalance(user1.publicKey);
87 | assert(res == 1000 * 1e9, 'Airdrop 1000 SOL for user1 Failed');
88 | });
89 | });
90 |
91 | describe('Contract Creation', async () => {
92 | it('Contract creator has a role of Admin', async () => {
93 | const tx = await createInitializeTx(
94 | superOwner.publicKey,
95 | program as unknown as anchor.Program,
96 | );
97 | const txId = await provider.connection.sendTransaction(tx, [superOwner]);
98 | await provider.connection.confirmTransaction(txId, 'confirmed');
99 | console.log("TxHash=", txId);
100 |
101 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
102 | assert(globalInfo.superAdmin.toBase58() == superOwner.publicKey.toBase58(), "GlobalInfo Admin Address mismatch with SuperOwner Pubkey");
103 | });
104 | it('Admin can change the Marketplace Fee', async () => {
105 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
106 | assert(globalInfo.superAdmin.toBase58() == superOwner.publicKey.toBase58(), "GlobalInfo Admin Address mismatch with SuperOwner Pubkey");
107 |
108 | const tx = await createUpdateFeeTx(
109 | superOwner.publicKey,
110 | program as unknown as anchor.Program,
111 | 100,
112 | 12,
113 | );
114 | const txId = await provider.connection.sendTransaction(tx, [superOwner]);
115 | await provider.connection.confirmTransaction(txId, 'confirmed');
116 | console.log("TxHash=", txId);
117 |
118 | globalInfo = await getGlobalState(program as unknown as anchor.Program);
119 | assert(globalInfo.marketFeeSol.toNumber() == 100, "Sol Fee is not 1%");
120 | assert(globalInfo.marketFeeToken.toNumber() == 12, "Token Fee is not 0.12%");
121 | });
122 | it('Admin can add himself as team', async () => {
123 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
124 | assert(globalInfo.superAdmin.toBase58() == superOwner.publicKey.toBase58(), "GlobalInfo Admin Address mismatch with SuperOwner Pubkey");
125 |
126 | const tx = await createAddTreasuryTx(
127 | superOwner.publicKey,
128 | program as unknown as anchor.Program,
129 | superOwner.publicKey,
130 | 500,
131 | );
132 | const txId = await provider.connection.sendTransaction(tx, [superOwner]);
133 | await provider.connection.confirmTransaction(txId, 'confirmed');
134 | console.log("TxHash=", txId);
135 |
136 | globalInfo = await getGlobalState(program as unknown as anchor.Program);
137 | assert(globalInfo.teamCount.toNumber() == 1, "No team treasury added");
138 | assert(globalInfo.teamTreasury[0].toBase58() == superOwner.publicKey.toBase58(), "Superowner is team");
139 | assert(globalInfo.treasuryRate[0].toNumber() == 500, "Superowner is treasury rate is 5%");
140 | });
141 | it('Admin can remove himself from team', async () => {
142 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
143 | assert(globalInfo.superAdmin.toBase58() == superOwner.publicKey.toBase58(), "GlobalInfo Admin Address mismatch with SuperOwner Pubkey");
144 | assert(globalInfo.teamCount.toNumber() == 1, "GlobalInfo Team Treasury Count is not 1");
145 |
146 | const tx = await createRemoveTreasuryTx(
147 | superOwner.publicKey,
148 | program as unknown as anchor.Program,
149 | superOwner.publicKey,
150 | );
151 | const txId = await provider.connection.sendTransaction(tx, [superOwner]);
152 | await provider.connection.confirmTransaction(txId, 'confirmed');
153 | console.log("TxHash=", txId);
154 |
155 | globalInfo = await getGlobalState(program as unknown as anchor.Program);
156 | assert(globalInfo.teamCount.toNumber() == 0, "Team treasury is still exist");
157 | });
158 | it('Admin can add himself as team', async () => {
159 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
160 | assert(globalInfo.superAdmin.toBase58() == superOwner.publicKey.toBase58(), "GlobalInfo Admin Address mismatch with SuperOwner Pubkey");
161 |
162 | const tx = await createAddTreasuryTx(
163 | superOwner.publicKey,
164 | program as unknown as anchor.Program,
165 | superOwner.publicKey,
166 | 30,
167 | );
168 | const txId = await provider.connection.sendTransaction(tx, [superOwner]);
169 | await provider.connection.confirmTransaction(txId, 'confirmed');
170 | console.log("TxHash=", txId);
171 |
172 | globalInfo = await getGlobalState(program as unknown as anchor.Program);
173 | assert(globalInfo.teamCount.toNumber() == 1, "No team treasury added");
174 | assert(globalInfo.teamTreasury[0].toBase58() == superOwner.publicKey.toBase58(), "Superowner is team");
175 | assert(globalInfo.treasuryRate[0].toNumber() == 30, "Superowner is treasury rate is 0.3% finally");
176 | });
177 | });
178 |
179 | describe('NFT Listing / Cancel Listing', async () => {
180 | it('Create one NFT for testing', async () => {
181 | nft = await Token.createMint(
182 | provider.connection,
183 | superOwner,
184 | superOwner.publicKey,
185 | superOwner.publicKey,
186 | 0,
187 | TOKEN_PROGRAM_ID,
188 | );
189 | console.log('NFT Address:', nft.publicKey.toBase58())
190 | assert(await isExistAccount(nft.publicKey, provider.connection), 'NFT Create Mint Failure');
191 | });
192 | it('User can init NFT SellData PDA', async () => {
193 | const [nftData, _] = await anchor.web3.PublicKey.findProgramAddress(
194 | [Buffer.from(SELL_DATA_SEED), nft.publicKey.toBuffer()],
195 | MARKETPLACE_PROGRAM_ID,
196 | );
197 |
198 | assert((await isExistAccount(nftData, provider.connection)) != true, 'NFT SellData PDA is Already Initialized');
199 |
200 | const tx = await createInitSellDataTx(
201 | nft.publicKey,
202 | user.publicKey,
203 | program as unknown as anchor.Program,
204 | );
205 | const txId = await provider.connection.sendTransaction(tx, [user]);
206 | await provider.connection.confirmTransaction(txId, 'confirmed');
207 | console.log("TxHash=", txId);
208 |
209 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
210 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
211 | });
212 | it('Mint one NFT in my ATA for testing', async () => {
213 | const userNFTAccount = await nft.createAssociatedTokenAccount(
214 | user.publicKey,
215 | );
216 | console.log('User NFT Account:', userNFTAccount.toBase58())
217 |
218 | await nft.mintTo(
219 | userNFTAccount,
220 | superOwner,
221 | [],
222 | 1,
223 | );
224 |
225 | assert((await getTokenAccountBalance(userNFTAccount, provider.connection)) == 1, 'Mint 1 NFT to User ATA failure');
226 | });
227 | it('User can list NFT for sale', async () => {
228 | const [nftData, _] = await anchor.web3.PublicKey.findProgramAddress(
229 | [Buffer.from(SELL_DATA_SEED), nft.publicKey.toBuffer()],
230 | MARKETPLACE_PROGRAM_ID,
231 | );
232 |
233 | assert((await isExistAccount(nftData, provider.connection)) == true, 'NFT SellData PDA is Not Initialized');
234 |
235 | const tx = await createListForSellNftTx(
236 | nft.publicKey,
237 | user.publicKey,
238 | program as unknown as anchor.Program,
239 | provider.connection,
240 | 1.2 * 1e9,
241 | 150 * ABB_TOKEN_DECIMAL,
242 | );
243 | const txId = await provider.connection.sendTransaction(tx, [user]);
244 | await provider.connection.confirmTransaction(txId, 'confirmed');
245 | console.log("TxHash=", txId);
246 |
247 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
248 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
249 | assert(nftInfo.priceSol.toNumber() == 1.2 * 1e9, "NFT SellData solPrice is not 1.2");
250 | assert(nftInfo.priceToken.toNumber() == 150 * ABB_TOKEN_DECIMAL, "NFT SellData TokenPrice is not 150");
251 | assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
252 | });
253 | // it('User can cancel listing', async () => {
254 | // const [nftData, _] = await anchor.web3.PublicKey.findProgramAddress(
255 | // [Buffer.from(SELL_DATA_SEED), nft.publicKey.toBuffer()],
256 | // MARKETPLACE_PROGRAM_ID,
257 | // );
258 |
259 | // assert((await isExistAccount(nftData, provider.connection)) == true, 'NFT SellData PDA is Not Initialized');
260 |
261 | // let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
262 | // assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
263 | // assert(nftInfo.seller.toBase58() == user.publicKey.toBase58(), "NFT Seller is not User Pubkey");
264 | // assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
265 |
266 | // const tx = await createDelistNftTx(
267 | // nft.publicKey,
268 | // user.publicKey,
269 | // program as unknown as anchor.Program,
270 | // provider.connection,
271 | // );
272 | // const txId = await provider.connection.sendTransaction(tx, [user]);
273 | // await provider.connection.confirmTransaction(txId, 'confirmed');
274 | // console.log("TxHash=", txId);
275 |
276 | // nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
277 | // assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
278 | // assert(nftInfo.active.toNumber() == 0, "NFT SellData is still actived");
279 | // });
280 | });
281 |
282 | describe('user1 Can Purchase NFT', async () => {
283 | it('Mint Enough ABB TOken in user1 ATA for staking', async () => {
284 | const rewardToken = new Token(
285 | provider.connection,
286 | ABB_TOKEN_MINT,
287 | TOKEN_PROGRAM_ID,
288 | superOwner,
289 | )
290 | let {instructions, destinationAccounts} = await getATokenAccountsNeedCreate(
291 | provider.connection,
292 | user1.publicKey,
293 | user1.publicKey,
294 | [ABB_TOKEN_MINT],
295 | );
296 | let user1ATA = destinationAccounts[0];
297 | console.log('user1ATA: ', user1ATA.toBase58());
298 |
299 | if (instructions.length > 0) {
300 | const tx = new anchor.web3.Transaction();
301 | tx.add(instructions[0]);
302 | const txId = await anchor.web3.sendAndConfirmTransaction(
303 | provider.connection,
304 | tx,
305 | [user1],
306 | );
307 | console.log("Tx Hash=", txId);
308 | }
309 |
310 | assert((await isExistAccount(user1ATA, provider.connection)), 'Create ABB ATA of my wallet failure!');
311 |
312 | await rewardToken.mintTo(user1ATA, superOwner, [], 100_000 * ABB_TOKEN_DECIMAL);
313 | assert((await getTokenAccountBalance(user1ATA, provider.connection)) == 100_000, 'Testing ABB Token amount is not 100_000');
314 | });
315 | it('User can init own UserPool PDA', async () => {
316 | const [userPool, _] = await anchor.web3.PublicKey.findProgramAddress(
317 | [Buffer.from(USER_DATA_SEED), user.publicKey.toBuffer()],
318 | MARKETPLACE_PROGRAM_ID,
319 | );
320 |
321 | assert((await isExistAccount(userPool, provider.connection)) != true, 'UserPool PDA is Already Initialized');
322 |
323 | const tx = await createInitUserTx(
324 | user.publicKey,
325 | program as unknown as anchor.Program,
326 | );
327 | const txId = await provider.connection.sendTransaction(tx, [user]);
328 | await provider.connection.confirmTransaction(txId, 'confirmed');
329 | console.log("TxHash=", txId);
330 |
331 | let userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
332 | assert(userInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
333 | });
334 | it('User1 can init own UserPool PDA', async () => {
335 | const [userPool, _] = await anchor.web3.PublicKey.findProgramAddress(
336 | [Buffer.from(USER_DATA_SEED), user1.publicKey.toBuffer()],
337 | MARKETPLACE_PROGRAM_ID,
338 | );
339 |
340 | assert((await isExistAccount(userPool, provider.connection)) != true, 'UserPool PDA is Already Initialized');
341 |
342 | const tx = await createInitUserTx(
343 | user1.publicKey,
344 | program as unknown as anchor.Program,
345 | );
346 | const txId = await provider.connection.sendTransaction(tx, [user1]);
347 | await provider.connection.confirmTransaction(txId, 'confirmed');
348 | console.log("TxHash=", txId);
349 |
350 | let userInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
351 | assert(userInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
352 | });
353 | it('user1 can purchase NFT from user with ABB Token payment', async () => {
354 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
355 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
356 | assert(nftInfo.priceSol.toNumber() == 1.2 * 1e9, "NFT SellData solPrice is not 1.2");
357 | assert(nftInfo.priceToken.toNumber() == 150 * ABB_TOKEN_DECIMAL, "NFT SellData TokenPrice is not 150");
358 | assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
359 | assert(nftInfo.seller.toBase58() == user.publicKey.toBase58(), "NFT Seller is not user Pubkey");
360 |
361 | let globalInfo = await getGlobalState(program as unknown as anchor.Program);
362 | assert(globalInfo.teamCount.toNumber() == 1, "No team treasury added");
363 | assert(globalInfo.teamTreasury[0].toBase58() == superOwner.publicKey.toBase58(), "Superowner is team");
364 | assert(globalInfo.treasuryRate[0].toNumber() == 30, "Superowner is treasury rate is 0.3% finally");
365 | console.log("Treasury Count:", globalInfo.teamCount.toNumber());
366 | const tx = await createPurchaseTx(
367 | nft.publicKey,
368 | user1.publicKey,
369 | true,
370 | globalInfo.teamTreasury.slice(0, globalInfo.teamCount.toNumber()),
371 | program as unknown as anchor.Program,
372 | provider.connection,
373 | );
374 | const txId = await provider.connection.sendTransaction(tx, [user1]);
375 | await provider.connection.confirmTransaction(txId, 'confirmed');
376 | console.log("TxHash=", txId);
377 |
378 | const user1ATA = await getAssociatedTokenAccount(user1.publicKey, nft.publicKey);
379 | assert((await getTokenAccountBalance(user1ATA, provider.connection)) == 1, 'Buyer NFT Account balance is zero');
380 | let fee_amount = Math.floor(nftInfo.priceToken.toNumber() * globalInfo.marketFeeToken.toNumber() / 10_000);
381 | const userATA = await getAssociatedTokenAccount(user.publicKey, ABB_TOKEN_MINT);
382 | console.log(await getTokenAccountBalance(userATA, provider.connection), (nftInfo.priceToken.toNumber() - fee_amount) / ABB_TOKEN_DECIMAL, fee_amount, 'Seller ABB Account balance is not same with TokenPrice');
383 | // assert((await getTokenAccountBalance(userATA, provider.connection)) - (nftInfo.priceToken.toNumber() - fee_amount) / ABB_TOKEN_DECIMAL, 'Seller ABB Account balance is not same with TokenPrice');
384 | let buyerUserInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
385 | assert(buyerUserInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
386 | assert(buyerUserInfo.tradedTokenVolume.toNumber() == nftInfo.priceToken.toNumber() - fee_amount, "UserData TradeVolume is not priceToken");
387 | let sellerUserInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
388 | assert(sellerUserInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
389 | assert(sellerUserInfo.tradedTokenVolume.toNumber() == nftInfo.priceToken.toNumber() - fee_amount, "UserData TradeVolume is not priceToken");
390 | });return;
391 | it('User1 can list NFT for sale', async () => {
392 | const [nftData, _] = await anchor.web3.PublicKey.findProgramAddress(
393 | [Buffer.from(SELL_DATA_SEED), nft.publicKey.toBuffer()],
394 | MARKETPLACE_PROGRAM_ID,
395 | );
396 |
397 | assert((await isExistAccount(nftData, provider.connection)) == true, 'NFT SellData PDA is Not Initialized');
398 |
399 | const tx = await createListForSellNftTx(
400 | nft.publicKey,
401 | user1.publicKey,
402 | program as unknown as anchor.Program,
403 | provider.connection,
404 | 1.2 * 1e9,
405 | 150 * ABB_TOKEN_DECIMAL,
406 | );
407 | const txId = await provider.connection.sendTransaction(tx, [user1]);
408 | await provider.connection.confirmTransaction(txId, 'confirmed');
409 | console.log("TxHash=", txId);
410 |
411 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
412 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
413 | assert(nftInfo.priceSol.toNumber() == 1.2 * 1e9, "NFT SellData solPrice is not 1.2");
414 | assert(nftInfo.priceToken.toNumber() == 150 * ABB_TOKEN_DECIMAL, "NFT SellData TokenPrice is not 150");
415 | assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
416 | });
417 | });
418 | /*
419 | describe('Deposit / Withdraw Escrow Balance', async () => {
420 | it('User1 can deposit sol', async () => {
421 | const tx = await createDepositTx(
422 | user1.publicKey,
423 | 1.2 * 1e9,
424 | 0,
425 | program as unknown as anchor.Program,
426 | provider.connection,
427 | );
428 | const txId = await provider.connection.sendTransaction(tx, [user1]);
429 | await provider.connection.confirmTransaction(txId, 'confirmed');
430 | console.log("TxHash=", txId);
431 |
432 | let userInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
433 | assert(userInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
434 | assert(userInfo.escrowSolBalance.toNumber() == 1.2 * 1e9, "UserData Sol Balance is not 1.2");
435 |
436 | const escrowBalance = await getEscrowBalance(provider.connection);
437 | assert(escrowBalance.sol == 1.2 * 1e9, 'Escrow Sol Balance is not 1.2');
438 | assert(escrowBalance.token == 0, 'Escrow ABB Token balance is not 0');
439 | });
440 | it('User1 can deposit token', async () => {
441 | const tx = await createDepositTx(
442 | user1.publicKey,
443 | 0,
444 | 1.3 * ABB_TOKEN_DECIMAL,
445 | program as unknown as anchor.Program,
446 | provider.connection,
447 | );
448 | const txId = await provider.connection.sendTransaction(tx, [user1]);
449 | await provider.connection.confirmTransaction(txId, 'confirmed');
450 | console.log("TxHash=", txId);
451 |
452 | let userInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
453 | assert(userInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
454 | assert(userInfo.escrowTokenBalance.toNumber() == 1.3 * ABB_TOKEN_DECIMAL, "UserData Token Balance is not 1.3");
455 |
456 | const escrowBalance = await getEscrowBalance(provider.connection);
457 | assert(escrowBalance.sol == 1.2 * 1e9, 'Escrow Sol Balance is not 1.2');
458 | assert(escrowBalance.token == 1.3 * ABB_TOKEN_DECIMAL, 'Escrow ABB Token balance is not 1.3');
459 | });
460 | it('User1 can withdraw token', async () => {
461 | const tx = await createWithdrawTx(
462 | user1.publicKey,
463 | 0,
464 | 0.2 * ABB_TOKEN_DECIMAL,
465 | program as unknown as anchor.Program,
466 | provider.connection,
467 | );
468 | const txId = await provider.connection.sendTransaction(tx, [user1]);
469 | await provider.connection.confirmTransaction(txId, 'confirmed');
470 | console.log("TxHash=", txId);
471 |
472 | let userInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
473 | assert(userInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
474 | assert(userInfo.escrowTokenBalance.toNumber() == 1.1 * ABB_TOKEN_DECIMAL, "UserData Token Balance is not 1.3");
475 |
476 | const escrowBalance = await getEscrowBalance(provider.connection);
477 | assert(escrowBalance.sol == 1.2 * 1e9, 'Escrow Sol Balance is not 1.2');
478 | assert(escrowBalance.token == 1.1 * ABB_TOKEN_DECIMAL, 'Escrow ABB Token balance is not 1.1');
479 | });
480 | it('User1 can withdraw sol', async () => {
481 | const tx = await createWithdrawTx(
482 | user1.publicKey,
483 | 0.3 * 1e9,
484 | 0,
485 | program as unknown as anchor.Program,
486 | provider.connection,
487 | );
488 | const txId = await provider.connection.sendTransaction(tx, [user1]);
489 | await provider.connection.confirmTransaction(txId, 'confirmed');
490 | console.log("TxHash=", txId);
491 |
492 | let userInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
493 | assert(userInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
494 | assert(userInfo.escrowSolBalance.toNumber() == 0.9 * 1e9, "UserData Sol Balance is not 0.9");
495 |
496 | const escrowBalance = await getEscrowBalance(provider.connection);
497 | assert(escrowBalance.sol == 0.9 * 1e9, 'Escrow Sol Balance is not 0.9');
498 | assert(escrowBalance.token == 1.1 * ABB_TOKEN_DECIMAL, 'Escrow ABB Token balance is not 1.1');
499 | });
500 | });
501 |
502 | describe('Offer for Listed NFT', async () => {
503 | it('User can init Offer Data for listed NFT', async () => {
504 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
505 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
506 | assert(nftInfo.seller.toBase58() == user1.publicKey.toBase58(), "NFT SellData Seller mismatch with User1 Pubkey");
507 | assert(nftInfo.priceSol.toNumber() == 1.2 * 1e9, "NFT SellData solPrice is not 1.2");
508 | assert(nftInfo.priceToken.toNumber() == 150 * ABB_TOKEN_DECIMAL, "NFT SellData TokenPrice is not 150");
509 | assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
510 |
511 | const tx = await createInitOfferDataTx(
512 | nft.publicKey,
513 | user.publicKey,
514 | program as unknown as anchor.Program,
515 | );
516 | const txId = await provider.connection.sendTransaction(tx, [user]);
517 | await provider.connection.confirmTransaction(txId, 'confirmed');
518 | console.log("TxHash=", txId);
519 |
520 | let offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
521 | assert(offerInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT OfferData Mint mismatch with NFT Pubkey");
522 | assert(offerInfo.buyer.toBase58() == user.publicKey.toBase58(), "NFT OfferData Buyer mismatch with User Pubkey");
523 | });
524 | it('User can make offer for listed NFT with depositing escrow', async () => {
525 | let userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
526 | assert(userInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
527 | assert(userInfo.escrowSolBalance.toNumber() == 0, "UserData Sol Balance is not 0");
528 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
529 |
530 | const tx = await createMakeOfferTx(
531 | nft.publicKey,
532 | user.publicKey,
533 | 0.7 * 1e9,
534 | false,
535 | program as unknown as anchor.Program,
536 | provider.connection,
537 | );
538 | const txId = await provider.connection.sendTransaction(tx, [user]);
539 | await provider.connection.confirmTransaction(txId, 'confirmed');
540 | console.log("TxHash=", txId);
541 |
542 | let offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
543 | assert(offerInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT OfferData Mint mismatch with NFT Pubkey");
544 | assert(offerInfo.buyer.toBase58() == user.publicKey.toBase58(), "NFT OfferData Buyer mismatch with User Pubkey");
545 | assert(offerInfo.offerPrice.toNumber() == 0.7 * 1e9, "NFT OfferData Offer Price is not 0.7 sol");
546 | assert(offerInfo.byToken.toNumber() == 0, "NFT OfferData ByToken is not 0");
547 | assert(offerInfo.active.toNumber() == 1, "NFT OfferData Active is not 1");
548 |
549 | userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
550 | assert(userInfo.escrowSolBalance.toNumber() == 0.7 * 1e9, "UserData Sol Balance is not 0.7");
551 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
552 | });
553 | it('User can cancel offer for listed NFT without withdrawing escrow', async () => {
554 | let userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
555 | assert(userInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
556 | assert(userInfo.escrowSolBalance.toNumber() == 0.7 * 1e9, "UserData Sol Balance is not 0.7");
557 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
558 |
559 | const tx = await createCancelOfferTx(
560 | nft.publicKey,
561 | user.publicKey,
562 | program as unknown as anchor.Program,
563 | );
564 | const txId = await provider.connection.sendTransaction(tx, [user]);
565 | await provider.connection.confirmTransaction(txId, 'confirmed');
566 | console.log("TxHash=", txId);
567 |
568 | let offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
569 | assert(offerInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT OfferData Mint mismatch with NFT Pubkey");
570 | assert(offerInfo.buyer.toBase58() == user.publicKey.toBase58(), "NFT OfferData Buyer mismatch with User Pubkey");
571 | assert(offerInfo.active.toNumber() == 0, "NFT OfferData Active is not 1");
572 |
573 | userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
574 | assert(userInfo.escrowSolBalance.toNumber() == 0.7 * 1e9, "UserData Sol Balance is not 0.7");
575 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
576 | });
577 | it('User can make offer for listed NFT finally', async () => {
578 | let userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
579 | assert(userInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
580 | assert(userInfo.escrowSolBalance.toNumber() == 0.7 * 1e9, "UserData Sol Balance is not 0.7 * 1e9");
581 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
582 |
583 | const tx = await createMakeOfferTx(
584 | nft.publicKey,
585 | user.publicKey,
586 | 0.6 * 1e9,
587 | false,
588 | program as unknown as anchor.Program,
589 | provider.connection,
590 | );
591 | const txId = await provider.connection.sendTransaction(tx, [user]);
592 | await provider.connection.confirmTransaction(txId, 'confirmed');
593 | console.log("TxHash=", txId);
594 |
595 | let offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
596 | assert(offerInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT OfferData Mint mismatch with NFT Pubkey");
597 | assert(offerInfo.buyer.toBase58() == user.publicKey.toBase58(), "NFT OfferData Buyer mismatch with User Pubkey");
598 | assert(offerInfo.offerPrice.toNumber() == 0.6 * 1e9, "NFT OfferData Offer Price is not 0.6 sol");
599 | assert(offerInfo.byToken.toNumber() == 0, "NFT OfferData ByToken is not 0");
600 | assert(offerInfo.active.toNumber() == 1, "NFT OfferData Active is not 1");
601 |
602 | userInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
603 | assert(userInfo.escrowSolBalance.toNumber() == 1.3 * 1e9, "UserData Sol Balance is not 1.3");
604 | assert(userInfo.escrowTokenBalance.toNumber() == 0, "UserData Token Balance is not 0");
605 | });
606 | it('User1 can accept user\'s offer', async () => {
607 | let nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
608 | assert(nftInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT SellData Mint mismatch with NFT Pubkey");
609 | assert(nftInfo.seller.toBase58() == user1.publicKey, "NFT SellData seller is not User1 Pubkey");
610 | assert(nftInfo.priceSol.toNumber() == 1.2 * 1e9, "NFT SellData solPrice is not 1.2");
611 | assert(nftInfo.priceToken.toNumber() == 150 * ABB_TOKEN_DECIMAL, "NFT SellData TokenPrice is not 150");
612 | assert(nftInfo.active.toNumber() == 1, "NFT SellData is not actived");
613 |
614 | let offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
615 | assert(offerInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT OfferData Mint mismatch with NFT Pubkey");
616 | assert(offerInfo.buyer.toBase58() == user.publicKey.toBase58(), "NFT OfferData Buyer mismatch with User Pubkey");
617 | assert(offerInfo.offerPrice.toNumber() == 0.6 * 1e9, "NFT OfferData Offer Price is not 0.6 sol");
618 | assert(offerInfo.byToken.toNumber() == 0, "NFT OfferData ByToken is not 0");
619 | assert(offerInfo.active.toNumber() == 1, "NFT OfferData Active is not 1");
620 |
621 | let escrowBalance = await getEscrowBalance(provider.connection);
622 | assert(escrowBalance.sol == 2.2 * 1e9, 'Escrow Sol Balance is not 2.2');
623 | assert(escrowBalance.token == 1.1 * ABB_TOKEN_DECIMAL, 'Escrow ABB Token balance is not 1.1');
624 |
625 | let sellerUserInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
626 | assert(sellerUserInfo.address.toBase58() == user1.publicKey.toBase58(), "UserData Address mismatch with User1 Pubkey");
627 | assert(sellerUserInfo.tradedVolume.toNumber() == 0, "UserData TradeVolume is not 0");
628 | let buyerUserInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
629 | assert(buyerUserInfo.address.toBase58() == user.publicKey.toBase58(), "UserData Address mismatch with User Pubkey");
630 | assert(buyerUserInfo.escrowSolBalance.toNumber() == 1.3 * 1e9, "UserData Sol Balance is not 1.3");
631 | assert(buyerUserInfo.tradedVolume.toNumber() == 0, "UserData TradeVolume is not 0");
632 |
633 | const tx = await createAcceptOfferTx(
634 | nft.publicKey,
635 | user.publicKey,
636 | program as unknown as anchor.Program,
637 | provider.connection,
638 | );
639 | const txId = await provider.connection.sendTransaction(tx, [user1]);
640 | await provider.connection.confirmTransaction(txId, 'confirmed');
641 | console.log("TxHash=", txId);
642 |
643 | nftInfo = await getNFTPoolState(nft.publicKey, program as unknown as anchor.Program);
644 | assert(nftInfo.active.toNumber() == 0, "NFT SellData is not 0");
645 | offerInfo = await getOfferDataState(nft.publicKey, user.publicKey, program as unknown as anchor.Program);
646 | assert(offerInfo.active.toNumber() == 0, "NFT OfferData Active is not 0");
647 | escrowBalance = await getEscrowBalance(provider.connection);
648 | assert(escrowBalance.sol == 1.6 * 1e9, 'Escrow Sol Balance is not 1.6');
649 | sellerUserInfo = await getUserPoolState(user1.publicKey, program as unknown as anchor.Program);
650 | assert(sellerUserInfo.tradedVolume.toNumber() == 0.6 * 1e9, "UserData TradeVolume is not 0.6");
651 | buyerUserInfo = await getUserPoolState(user.publicKey, program as unknown as anchor.Program);
652 | assert(buyerUserInfo.escrowSolBalance.toNumber() == 0.7 * 1e9, "UserData Sol Balance is not 0.7");
653 | assert(buyerUserInfo.tradedVolume.toNumber() == 0.6 * 1e9, "UserData TradeVolume is not 0.6");
654 | });
655 | });
656 |
657 | describe('Auction and Bid', async () => {
658 | it('User can init auction Data for Creating Auction', async () => {
659 | const tx = await createInitAuctionDataTx(
660 | nft.publicKey,
661 | user.publicKey,
662 | program as unknown as anchor.Program,
663 | );
664 | const txId = await provider.connection.sendTransaction(tx, [user]);
665 | await provider.connection.confirmTransaction(txId, 'confirmed');
666 | console.log("TxHash=", txId);
667 |
668 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
669 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
670 | });
671 | it('User can Create Auction', async () => {
672 | let now = Math.floor(Date.now() / 1000);
673 | const tx = await createCreateAuctionTx(
674 | nft.publicKey,
675 | user.publicKey,
676 | 1 * 1e9,
677 | 0.2 * 1e9,
678 | true,
679 | now + 10,
680 | program as unknown as anchor.Program,
681 | provider.connection,
682 | );
683 | const txId = await provider.connection.sendTransaction(tx, [user]);
684 | await provider.connection.confirmTransaction(txId, 'confirmed');
685 | console.log("TxHash=", txId);
686 |
687 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
688 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
689 | assert(auctionInfo.creator.toBase58() == user.publicKey.toBase58(), "NFT AuctionData Creator mismatch with User Pubkey");
690 | assert(auctionInfo.startPrice.toNumber() == 1 * 1e9, "StartPrice is not 1 SOL");
691 | assert(auctionInfo.minIncreaseAmount.toNumber() == 0.2 * 1e9, "MinIncreaseAmount is not 0.2 SOL");
692 | assert(auctionInfo.byToken.toNumber() == 1, "ByToken is not true");
693 | assert(auctionInfo.endDate.toNumber() == now + 10, `EndDate is not ${now + 10}`);
694 | assert(auctionInfo.status.toNumber() == 1, 'Status is not 1');
695 | });
696 | it('User1 can Place Bid', async () => {
697 | const tx = await createPlaceBidTx(
698 | nft.publicKey,
699 | user1.publicKey,
700 | 1.5 * 1e9,
701 | program as unknown as anchor.Program,
702 | provider.connection,
703 | );
704 | const txId = await provider.connection.sendTransaction(tx, [user1]);
705 | await provider.connection.confirmTransaction(txId, 'confirmed');
706 | console.log("TxHash=", txId);
707 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
708 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
709 | assert(auctionInfo.lastBidder.toBase58() == user1.publicKey.toBase58(), "LastBidder mismatch with User1 Pubkey");
710 | assert(auctionInfo.highestBid.toNumber() == 1.5 * 1e9, 'HighestBid is not 1.5');
711 | assert(auctionInfo.status.toNumber() == 1, 'Status is not 1');
712 |
713 | const escrowBalance = await getEscrowBalance(provider.connection);
714 | console.log(escrowBalance);
715 | // assert(escrowBalance.sol == 1.5, 'Escrow Sol Balance is not 1.5');
716 | // assert(escrowBalance.token == 0, 'Escrow ABB Token balance is not 0');
717 | });
718 | it('User1 can Claim Auction', async () => {
719 | await new Promise((resolve) => {
720 | setTimeout(() => {
721 | resolve(true);
722 | }, 11000);
723 | });
724 | const tx = await createClaimAuctionTx(
725 | nft.publicKey,
726 | user1.publicKey,
727 | program as unknown as anchor.Program,
728 | provider.connection,
729 | );
730 | const txId = await provider.connection.sendTransaction(tx, [user1]);
731 | await provider.connection.confirmTransaction(txId, 'confirmed');
732 | console.log("TxHash=", txId);
733 |
734 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
735 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
736 | assert(auctionInfo.status.toNumber() == 2, 'Status is not 2');
737 |
738 | const escrowBalance = await getEscrowBalance(provider.connection);
739 | console.log(escrowBalance);
740 | // assert(escrowBalance.sol == 0, 'Escrow Sol Balance is not 0');
741 | // assert(escrowBalance.token == 0, 'Escrow ABB Token balance is not 0');
742 |
743 | const user1ATA = await getAssociatedTokenAccount(user1.publicKey, nft.publicKey);
744 | assert((await getTokenAccountBalance(user1ATA, provider.connection)) == 1, 'Winner NFT Account balance is zero');
745 | });
746 | it('User1 can Create Auction', async () => {
747 | let now = Math.floor(Date.now() / 1000);
748 | const tx = await createCreateAuctionTx(
749 | nft.publicKey,
750 | user1.publicKey,
751 | 1 * 1e9,
752 | 0.2 * 1e9,
753 | false,
754 | now + 10,
755 | program as unknown as anchor.Program,
756 | provider.connection,
757 | );
758 | const txId = await provider.connection.sendTransaction(tx, [user1]);
759 | await provider.connection.confirmTransaction(txId, 'confirmed');
760 | console.log("TxHash=", txId);
761 |
762 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
763 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
764 | assert(auctionInfo.creator.toBase58() == user1.publicKey.toBase58(), "NFT AuctionData Creator mismatch with User Pubkey");
765 | assert(auctionInfo.startPrice.toNumber() == 1 * 1e9, "StartPrice is not 1 SOL");
766 | assert(auctionInfo.minIncreaseAmount.toNumber() == 0.2 * 1e9, "MinIncreaseAmount is not 0.2 SOL");
767 | assert(auctionInfo.byToken.toNumber() == 0, "ByToken is not false");
768 | assert(auctionInfo.endDate.toNumber() == now + 10, `EndDate is not ${now + 10}`);
769 | assert(auctionInfo.status.toNumber() == 1, 'Status is not 1');
770 | });
771 | it('User1 can Cancel Auction', async () => {
772 | await new Promise((resolve) => {
773 | setTimeout(() => {
774 | resolve(true);
775 | }, 11000);
776 | });
777 | const tx = await createCancelAuctionTx(
778 | nft.publicKey,
779 | user1.publicKey,
780 | program as unknown as anchor.Program,
781 | provider.connection,
782 | );
783 | const txId = await provider.connection.sendTransaction(tx, [user1]);
784 | await provider.connection.confirmTransaction(txId, 'confirmed');
785 | console.log("TxHash=", txId);
786 |
787 | let auctionInfo = await getAuctionDataState(nft.publicKey, program as unknown as anchor.Program);
788 | assert(auctionInfo.mint.toBase58() == nft.publicKey.toBase58(), "NFT AuctionData Mint mismatch with NFT Pubkey");
789 | assert(auctionInfo.status.toNumber() == 0, 'Status is not 0');
790 |
791 | const user1ATA = await getAssociatedTokenAccount(user1.publicKey, nft.publicKey);
792 | assert((await getTokenAccountBalance(user1ATA, provider.connection)) == 1, 'Creator NFT Account balance is zero');
793 | });
794 | }); */
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "ahash"
7 | version = "0.7.6"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
10 | dependencies = [
11 | "getrandom 0.2.6",
12 | "once_cell",
13 | "version_check",
14 | ]
15 |
16 | [[package]]
17 | name = "aho-corasick"
18 | version = "0.7.18"
19 | source = "registry+https://github.com/rust-lang/crates.io-index"
20 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
21 | dependencies = [
22 | "memchr",
23 | ]
24 |
25 | [[package]]
26 | name = "anchor-attribute-access-control"
27 | version = "0.24.2"
28 | source = "registry+https://github.com/rust-lang/crates.io-index"
29 | checksum = "a9b75d05b6b4ac9d95bb6e3b786b27d3a708c4c5a87c92ffaa25bbe9ae4c5d91"
30 | dependencies = [
31 | "anchor-syn",
32 | "anyhow",
33 | "proc-macro2",
34 | "quote",
35 | "regex",
36 | "syn",
37 | ]
38 |
39 | [[package]]
40 | name = "anchor-attribute-account"
41 | version = "0.24.2"
42 | source = "registry+https://github.com/rust-lang/crates.io-index"
43 | checksum = "485351a6d8157750d10d88c8e256f1bf8339262b2220ae9125aed3471309b5de"
44 | dependencies = [
45 | "anchor-syn",
46 | "anyhow",
47 | "bs58 0.4.0",
48 | "proc-macro2",
49 | "quote",
50 | "rustversion",
51 | "syn",
52 | ]
53 |
54 | [[package]]
55 | name = "anchor-attribute-constant"
56 | version = "0.24.2"
57 | source = "registry+https://github.com/rust-lang/crates.io-index"
58 | checksum = "dc632c540913dd051a78b00587cc47f57013d303163ddfaf4fa18717f7ccc1e0"
59 | dependencies = [
60 | "anchor-syn",
61 | "proc-macro2",
62 | "syn",
63 | ]
64 |
65 | [[package]]
66 | name = "anchor-attribute-error"
67 | version = "0.24.2"
68 | source = "registry+https://github.com/rust-lang/crates.io-index"
69 | checksum = "3b5bd1dcfa7f3bc22dacef233d70a9e0bee269c4ac484510662f257cba2353a1"
70 | dependencies = [
71 | "anchor-syn",
72 | "proc-macro2",
73 | "quote",
74 | "syn",
75 | ]
76 |
77 | [[package]]
78 | name = "anchor-attribute-event"
79 | version = "0.24.2"
80 | source = "registry+https://github.com/rust-lang/crates.io-index"
81 | checksum = "6c6f9e6ce551ac9a177a45c99a65699a860c9e95fac68675138af1246e2591b0"
82 | dependencies = [
83 | "anchor-syn",
84 | "anyhow",
85 | "proc-macro2",
86 | "quote",
87 | "syn",
88 | ]
89 |
90 | [[package]]
91 | name = "anchor-attribute-interface"
92 | version = "0.24.2"
93 | source = "registry+https://github.com/rust-lang/crates.io-index"
94 | checksum = "d104aa17418cb329ed7418b227e083d5f326a27f26ce98f5d92e33da62a5f459"
95 | dependencies = [
96 | "anchor-syn",
97 | "anyhow",
98 | "heck",
99 | "proc-macro2",
100 | "quote",
101 | "syn",
102 | ]
103 |
104 | [[package]]
105 | name = "anchor-attribute-program"
106 | version = "0.24.2"
107 | source = "registry+https://github.com/rust-lang/crates.io-index"
108 | checksum = "b6831b920b173c004ddf7ae1167d1d25e9f002ffcb1773bbc5c7ce532a4441e1"
109 | dependencies = [
110 | "anchor-syn",
111 | "anyhow",
112 | "proc-macro2",
113 | "quote",
114 | "syn",
115 | ]
116 |
117 | [[package]]
118 | name = "anchor-attribute-state"
119 | version = "0.24.2"
120 | source = "registry+https://github.com/rust-lang/crates.io-index"
121 | checksum = "cde147b10c71d95dc679785db0b5f3abac0091f789167aa62ac0135e2f54e8b9"
122 | dependencies = [
123 | "anchor-syn",
124 | "anyhow",
125 | "proc-macro2",
126 | "quote",
127 | "syn",
128 | ]
129 |
130 | [[package]]
131 | name = "anchor-derive-accounts"
132 | version = "0.24.2"
133 | source = "registry+https://github.com/rust-lang/crates.io-index"
134 | checksum = "9cde98a0e1a56046b040ff591dfda391f88917af2b6487d02b45093c05be3514"
135 | dependencies = [
136 | "anchor-syn",
137 | "anyhow",
138 | "proc-macro2",
139 | "quote",
140 | "syn",
141 | ]
142 |
143 | [[package]]
144 | name = "anchor-lang"
145 | version = "0.24.2"
146 | source = "registry+https://github.com/rust-lang/crates.io-index"
147 | checksum = "a85dd2c5e29e20c7f4701a43724d6cd5406d0ee5694705522e43da0f26542a84"
148 | dependencies = [
149 | "anchor-attribute-access-control",
150 | "anchor-attribute-account",
151 | "anchor-attribute-constant",
152 | "anchor-attribute-error",
153 | "anchor-attribute-event",
154 | "anchor-attribute-interface",
155 | "anchor-attribute-program",
156 | "anchor-attribute-state",
157 | "anchor-derive-accounts",
158 | "arrayref",
159 | "base64 0.13.0",
160 | "bincode",
161 | "borsh",
162 | "bytemuck",
163 | "solana-program",
164 | "thiserror",
165 | ]
166 |
167 | [[package]]
168 | name = "anchor-spl"
169 | version = "0.24.2"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | checksum = "0188c33b4a3c124c4e593f2b440415aaea70a7650fac6ba0772395385d71c003"
172 | dependencies = [
173 | "anchor-lang",
174 | "solana-program",
175 | "spl-associated-token-account",
176 | "spl-token",
177 | ]
178 |
179 | [[package]]
180 | name = "anchor-syn"
181 | version = "0.24.2"
182 | source = "registry+https://github.com/rust-lang/crates.io-index"
183 | checksum = "03549dc2eae0b20beba6333b14520e511822a6321cdb1760f841064a69347316"
184 | dependencies = [
185 | "anyhow",
186 | "bs58 0.3.1",
187 | "heck",
188 | "proc-macro2",
189 | "proc-macro2-diagnostics",
190 | "quote",
191 | "serde",
192 | "serde_json",
193 | "sha2",
194 | "syn",
195 | "thiserror",
196 | ]
197 |
198 | [[package]]
199 | name = "anyhow"
200 | version = "1.0.57"
201 | source = "registry+https://github.com/rust-lang/crates.io-index"
202 | checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
203 |
204 | [[package]]
205 | name = "arrayref"
206 | version = "0.3.6"
207 | source = "registry+https://github.com/rust-lang/crates.io-index"
208 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
209 |
210 | [[package]]
211 | name = "arrayvec"
212 | version = "0.7.2"
213 | source = "registry+https://github.com/rust-lang/crates.io-index"
214 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
215 |
216 | [[package]]
217 | name = "atty"
218 | version = "0.2.14"
219 | source = "registry+https://github.com/rust-lang/crates.io-index"
220 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
221 | dependencies = [
222 | "hermit-abi",
223 | "libc",
224 | "winapi",
225 | ]
226 |
227 | [[package]]
228 | name = "autocfg"
229 | version = "1.1.0"
230 | source = "registry+https://github.com/rust-lang/crates.io-index"
231 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
232 |
233 | [[package]]
234 | name = "base64"
235 | version = "0.12.3"
236 | source = "registry+https://github.com/rust-lang/crates.io-index"
237 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
238 |
239 | [[package]]
240 | name = "base64"
241 | version = "0.13.0"
242 | source = "registry+https://github.com/rust-lang/crates.io-index"
243 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
244 |
245 | [[package]]
246 | name = "bincode"
247 | version = "1.3.3"
248 | source = "registry+https://github.com/rust-lang/crates.io-index"
249 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
250 | dependencies = [
251 | "serde",
252 | ]
253 |
254 | [[package]]
255 | name = "bitflags"
256 | version = "1.3.2"
257 | source = "registry+https://github.com/rust-lang/crates.io-index"
258 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
259 |
260 | [[package]]
261 | name = "blake3"
262 | version = "1.3.1"
263 | source = "registry+https://github.com/rust-lang/crates.io-index"
264 | checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f"
265 | dependencies = [
266 | "arrayref",
267 | "arrayvec",
268 | "cc",
269 | "cfg-if",
270 | "constant_time_eq",
271 | "digest 0.10.3",
272 | ]
273 |
274 | [[package]]
275 | name = "block-buffer"
276 | version = "0.9.0"
277 | source = "registry+https://github.com/rust-lang/crates.io-index"
278 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
279 | dependencies = [
280 | "block-padding",
281 | "generic-array",
282 | ]
283 |
284 | [[package]]
285 | name = "block-buffer"
286 | version = "0.10.2"
287 | source = "registry+https://github.com/rust-lang/crates.io-index"
288 | checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
289 | dependencies = [
290 | "generic-array",
291 | ]
292 |
293 | [[package]]
294 | name = "block-padding"
295 | version = "0.2.1"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
298 |
299 | [[package]]
300 | name = "borsh"
301 | version = "0.9.3"
302 | source = "registry+https://github.com/rust-lang/crates.io-index"
303 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa"
304 | dependencies = [
305 | "borsh-derive",
306 | "hashbrown",
307 | ]
308 |
309 | [[package]]
310 | name = "borsh-derive"
311 | version = "0.9.3"
312 | source = "registry+https://github.com/rust-lang/crates.io-index"
313 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775"
314 | dependencies = [
315 | "borsh-derive-internal",
316 | "borsh-schema-derive-internal",
317 | "proc-macro-crate 0.1.5",
318 | "proc-macro2",
319 | "syn",
320 | ]
321 |
322 | [[package]]
323 | name = "borsh-derive-internal"
324 | version = "0.9.3"
325 | source = "registry+https://github.com/rust-lang/crates.io-index"
326 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065"
327 | dependencies = [
328 | "proc-macro2",
329 | "quote",
330 | "syn",
331 | ]
332 |
333 | [[package]]
334 | name = "borsh-schema-derive-internal"
335 | version = "0.9.3"
336 | source = "registry+https://github.com/rust-lang/crates.io-index"
337 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0"
338 | dependencies = [
339 | "proc-macro2",
340 | "quote",
341 | "syn",
342 | ]
343 |
344 | [[package]]
345 | name = "bs58"
346 | version = "0.3.1"
347 | source = "registry+https://github.com/rust-lang/crates.io-index"
348 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
349 |
350 | [[package]]
351 | name = "bs58"
352 | version = "0.4.0"
353 | source = "registry+https://github.com/rust-lang/crates.io-index"
354 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
355 |
356 | [[package]]
357 | name = "bumpalo"
358 | version = "3.10.0"
359 | source = "registry+https://github.com/rust-lang/crates.io-index"
360 | checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
361 |
362 | [[package]]
363 | name = "bv"
364 | version = "0.11.1"
365 | source = "registry+https://github.com/rust-lang/crates.io-index"
366 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340"
367 | dependencies = [
368 | "feature-probe",
369 | "serde",
370 | ]
371 |
372 | [[package]]
373 | name = "bytemuck"
374 | version = "1.9.1"
375 | source = "registry+https://github.com/rust-lang/crates.io-index"
376 | checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
377 | dependencies = [
378 | "bytemuck_derive",
379 | ]
380 |
381 | [[package]]
382 | name = "bytemuck_derive"
383 | version = "1.1.0"
384 | source = "registry+https://github.com/rust-lang/crates.io-index"
385 | checksum = "562e382481975bc61d11275ac5e62a19abd00b0547d99516a415336f183dcd0e"
386 | dependencies = [
387 | "proc-macro2",
388 | "quote",
389 | "syn",
390 | ]
391 |
392 | [[package]]
393 | name = "byteorder"
394 | version = "1.4.3"
395 | source = "registry+https://github.com/rust-lang/crates.io-index"
396 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
397 |
398 | [[package]]
399 | name = "cc"
400 | version = "1.0.73"
401 | source = "registry+https://github.com/rust-lang/crates.io-index"
402 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
403 |
404 | [[package]]
405 | name = "cfg-if"
406 | version = "1.0.0"
407 | source = "registry+https://github.com/rust-lang/crates.io-index"
408 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
409 |
410 | [[package]]
411 | name = "console_error_panic_hook"
412 | version = "0.1.7"
413 | source = "registry+https://github.com/rust-lang/crates.io-index"
414 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
415 | dependencies = [
416 | "cfg-if",
417 | "wasm-bindgen",
418 | ]
419 |
420 | [[package]]
421 | name = "console_log"
422 | version = "0.2.0"
423 | source = "registry+https://github.com/rust-lang/crates.io-index"
424 | checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494"
425 | dependencies = [
426 | "log",
427 | "web-sys",
428 | ]
429 |
430 | [[package]]
431 | name = "constant_time_eq"
432 | version = "0.1.5"
433 | source = "registry+https://github.com/rust-lang/crates.io-index"
434 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
435 |
436 | [[package]]
437 | name = "cpufeatures"
438 | version = "0.2.2"
439 | source = "registry+https://github.com/rust-lang/crates.io-index"
440 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
441 | dependencies = [
442 | "libc",
443 | ]
444 |
445 | [[package]]
446 | name = "crunchy"
447 | version = "0.2.2"
448 | source = "registry+https://github.com/rust-lang/crates.io-index"
449 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
450 |
451 | [[package]]
452 | name = "crypto-common"
453 | version = "0.1.3"
454 | source = "registry+https://github.com/rust-lang/crates.io-index"
455 | checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
456 | dependencies = [
457 | "generic-array",
458 | "typenum",
459 | ]
460 |
461 | [[package]]
462 | name = "crypto-mac"
463 | version = "0.8.0"
464 | source = "registry+https://github.com/rust-lang/crates.io-index"
465 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
466 | dependencies = [
467 | "generic-array",
468 | "subtle",
469 | ]
470 |
471 | [[package]]
472 | name = "curve25519-dalek"
473 | version = "3.2.1"
474 | source = "registry+https://github.com/rust-lang/crates.io-index"
475 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
476 | dependencies = [
477 | "byteorder",
478 | "digest 0.9.0",
479 | "rand_core",
480 | "subtle",
481 | "zeroize",
482 | ]
483 |
484 | [[package]]
485 | name = "digest"
486 | version = "0.9.0"
487 | source = "registry+https://github.com/rust-lang/crates.io-index"
488 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
489 | dependencies = [
490 | "generic-array",
491 | ]
492 |
493 | [[package]]
494 | name = "digest"
495 | version = "0.10.3"
496 | source = "registry+https://github.com/rust-lang/crates.io-index"
497 | checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
498 | dependencies = [
499 | "block-buffer 0.10.2",
500 | "crypto-common",
501 | "subtle",
502 | ]
503 |
504 | [[package]]
505 | name = "either"
506 | version = "1.6.1"
507 | source = "registry+https://github.com/rust-lang/crates.io-index"
508 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
509 |
510 | [[package]]
511 | name = "env_logger"
512 | version = "0.9.0"
513 | source = "registry+https://github.com/rust-lang/crates.io-index"
514 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
515 | dependencies = [
516 | "atty",
517 | "humantime",
518 | "log",
519 | "regex",
520 | "termcolor",
521 | ]
522 |
523 | [[package]]
524 | name = "feature-probe"
525 | version = "0.1.1"
526 | source = "registry+https://github.com/rust-lang/crates.io-index"
527 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da"
528 |
529 | [[package]]
530 | name = "generic-array"
531 | version = "0.14.5"
532 | source = "registry+https://github.com/rust-lang/crates.io-index"
533 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
534 | dependencies = [
535 | "serde",
536 | "typenum",
537 | "version_check",
538 | ]
539 |
540 | [[package]]
541 | name = "getrandom"
542 | version = "0.1.16"
543 | source = "registry+https://github.com/rust-lang/crates.io-index"
544 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
545 | dependencies = [
546 | "cfg-if",
547 | "js-sys",
548 | "libc",
549 | "wasi 0.9.0+wasi-snapshot-preview1",
550 | "wasm-bindgen",
551 | ]
552 |
553 | [[package]]
554 | name = "getrandom"
555 | version = "0.2.6"
556 | source = "registry+https://github.com/rust-lang/crates.io-index"
557 | checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
558 | dependencies = [
559 | "cfg-if",
560 | "libc",
561 | "wasi 0.10.2+wasi-snapshot-preview1",
562 | ]
563 |
564 | [[package]]
565 | name = "hashbrown"
566 | version = "0.11.2"
567 | source = "registry+https://github.com/rust-lang/crates.io-index"
568 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
569 | dependencies = [
570 | "ahash",
571 | ]
572 |
573 | [[package]]
574 | name = "heck"
575 | version = "0.3.3"
576 | source = "registry+https://github.com/rust-lang/crates.io-index"
577 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
578 | dependencies = [
579 | "unicode-segmentation",
580 | ]
581 |
582 | [[package]]
583 | name = "hermit-abi"
584 | version = "0.1.19"
585 | source = "registry+https://github.com/rust-lang/crates.io-index"
586 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
587 | dependencies = [
588 | "libc",
589 | ]
590 |
591 | [[package]]
592 | name = "hmac"
593 | version = "0.8.1"
594 | source = "registry+https://github.com/rust-lang/crates.io-index"
595 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
596 | dependencies = [
597 | "crypto-mac",
598 | "digest 0.9.0",
599 | ]
600 |
601 | [[package]]
602 | name = "hmac-drbg"
603 | version = "0.3.0"
604 | source = "registry+https://github.com/rust-lang/crates.io-index"
605 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
606 | dependencies = [
607 | "digest 0.9.0",
608 | "generic-array",
609 | "hmac",
610 | ]
611 |
612 | [[package]]
613 | name = "humantime"
614 | version = "2.1.0"
615 | source = "registry+https://github.com/rust-lang/crates.io-index"
616 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
617 |
618 | [[package]]
619 | name = "instant"
620 | version = "0.1.12"
621 | source = "registry+https://github.com/rust-lang/crates.io-index"
622 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
623 | dependencies = [
624 | "cfg-if",
625 | ]
626 |
627 | [[package]]
628 | name = "itertools"
629 | version = "0.10.3"
630 | source = "registry+https://github.com/rust-lang/crates.io-index"
631 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
632 | dependencies = [
633 | "either",
634 | ]
635 |
636 | [[package]]
637 | name = "itoa"
638 | version = "1.0.2"
639 | source = "registry+https://github.com/rust-lang/crates.io-index"
640 | checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
641 |
642 | [[package]]
643 | name = "js-sys"
644 | version = "0.3.57"
645 | source = "registry+https://github.com/rust-lang/crates.io-index"
646 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
647 | dependencies = [
648 | "wasm-bindgen",
649 | ]
650 |
651 | [[package]]
652 | name = "keccak"
653 | version = "0.1.2"
654 | source = "registry+https://github.com/rust-lang/crates.io-index"
655 | checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
656 |
657 | [[package]]
658 | name = "lazy_static"
659 | version = "1.4.0"
660 | source = "registry+https://github.com/rust-lang/crates.io-index"
661 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
662 |
663 | [[package]]
664 | name = "libc"
665 | version = "0.2.126"
666 | source = "registry+https://github.com/rust-lang/crates.io-index"
667 | checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
668 |
669 | [[package]]
670 | name = "libsecp256k1"
671 | version = "0.6.0"
672 | source = "registry+https://github.com/rust-lang/crates.io-index"
673 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73"
674 | dependencies = [
675 | "arrayref",
676 | "base64 0.12.3",
677 | "digest 0.9.0",
678 | "hmac-drbg",
679 | "libsecp256k1-core",
680 | "libsecp256k1-gen-ecmult",
681 | "libsecp256k1-gen-genmult",
682 | "rand",
683 | "serde",
684 | "sha2",
685 | "typenum",
686 | ]
687 |
688 | [[package]]
689 | name = "libsecp256k1-core"
690 | version = "0.2.2"
691 | source = "registry+https://github.com/rust-lang/crates.io-index"
692 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80"
693 | dependencies = [
694 | "crunchy",
695 | "digest 0.9.0",
696 | "subtle",
697 | ]
698 |
699 | [[package]]
700 | name = "libsecp256k1-gen-ecmult"
701 | version = "0.2.1"
702 | source = "registry+https://github.com/rust-lang/crates.io-index"
703 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3"
704 | dependencies = [
705 | "libsecp256k1-core",
706 | ]
707 |
708 | [[package]]
709 | name = "libsecp256k1-gen-genmult"
710 | version = "0.2.1"
711 | source = "registry+https://github.com/rust-lang/crates.io-index"
712 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d"
713 | dependencies = [
714 | "libsecp256k1-core",
715 | ]
716 |
717 | [[package]]
718 | name = "lock_api"
719 | version = "0.4.7"
720 | source = "registry+https://github.com/rust-lang/crates.io-index"
721 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
722 | dependencies = [
723 | "autocfg",
724 | "scopeguard",
725 | ]
726 |
727 | [[package]]
728 | name = "log"
729 | version = "0.4.17"
730 | source = "registry+https://github.com/rust-lang/crates.io-index"
731 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
732 | dependencies = [
733 | "cfg-if",
734 | ]
735 |
736 | [[package]]
737 | name = "memchr"
738 | version = "2.5.0"
739 | source = "registry+https://github.com/rust-lang/crates.io-index"
740 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
741 |
742 | [[package]]
743 | name = "memmap2"
744 | version = "0.5.4"
745 | source = "registry+https://github.com/rust-lang/crates.io-index"
746 | checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"
747 | dependencies = [
748 | "libc",
749 | ]
750 |
751 | [[package]]
752 | name = "metaplex-token-metadata"
753 | version = "0.0.1"
754 | source = "registry+https://github.com/rust-lang/crates.io-index"
755 | checksum = "abcc939f0afdc6db054b9998a1292d0a016244b382462e61cfc7c570624982cb"
756 | dependencies = [
757 | "arrayref",
758 | "borsh",
759 | "metaplex-token-vault",
760 | "num-derive",
761 | "num-traits",
762 | "solana-program",
763 | "spl-token",
764 | "thiserror",
765 | ]
766 |
767 | [[package]]
768 | name = "metaplex-token-vault"
769 | version = "0.0.1"
770 | source = "registry+https://github.com/rust-lang/crates.io-index"
771 | checksum = "a5211991ba3273df89cd5e0f6f558bc8d7453c87c0546f915b4a319e1541df33"
772 | dependencies = [
773 | "borsh",
774 | "num-derive",
775 | "num-traits",
776 | "solana-program",
777 | "spl-token",
778 | "thiserror",
779 | ]
780 |
781 | [[package]]
782 | name = "num-derive"
783 | version = "0.3.3"
784 | source = "registry+https://github.com/rust-lang/crates.io-index"
785 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
786 | dependencies = [
787 | "proc-macro2",
788 | "quote",
789 | "syn",
790 | ]
791 |
792 | [[package]]
793 | name = "num-traits"
794 | version = "0.2.15"
795 | source = "registry+https://github.com/rust-lang/crates.io-index"
796 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
797 | dependencies = [
798 | "autocfg",
799 | ]
800 |
801 | [[package]]
802 | name = "num_enum"
803 | version = "0.5.7"
804 | source = "registry+https://github.com/rust-lang/crates.io-index"
805 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
806 | dependencies = [
807 | "num_enum_derive",
808 | ]
809 |
810 | [[package]]
811 | name = "num_enum_derive"
812 | version = "0.5.7"
813 | source = "registry+https://github.com/rust-lang/crates.io-index"
814 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
815 | dependencies = [
816 | "proc-macro-crate 1.1.3",
817 | "proc-macro2",
818 | "quote",
819 | "syn",
820 | ]
821 |
822 | [[package]]
823 | name = "nut_marketplace"
824 | version = "0.1.0"
825 | dependencies = [
826 | "anchor-lang",
827 | "anchor-spl",
828 | "metaplex-token-metadata",
829 | "solana-program",
830 | "spl-associated-token-account",
831 | "spl-token",
832 | ]
833 |
834 | [[package]]
835 | name = "once_cell"
836 | version = "1.12.0"
837 | source = "registry+https://github.com/rust-lang/crates.io-index"
838 | checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
839 |
840 | [[package]]
841 | name = "opaque-debug"
842 | version = "0.3.0"
843 | source = "registry+https://github.com/rust-lang/crates.io-index"
844 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
845 |
846 | [[package]]
847 | name = "parking_lot"
848 | version = "0.11.2"
849 | source = "registry+https://github.com/rust-lang/crates.io-index"
850 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
851 | dependencies = [
852 | "instant",
853 | "lock_api",
854 | "parking_lot_core",
855 | ]
856 |
857 | [[package]]
858 | name = "parking_lot_core"
859 | version = "0.8.5"
860 | source = "registry+https://github.com/rust-lang/crates.io-index"
861 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
862 | dependencies = [
863 | "cfg-if",
864 | "instant",
865 | "libc",
866 | "redox_syscall",
867 | "smallvec",
868 | "winapi",
869 | ]
870 |
871 | [[package]]
872 | name = "ppv-lite86"
873 | version = "0.2.16"
874 | source = "registry+https://github.com/rust-lang/crates.io-index"
875 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
876 |
877 | [[package]]
878 | name = "proc-macro-crate"
879 | version = "0.1.5"
880 | source = "registry+https://github.com/rust-lang/crates.io-index"
881 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
882 | dependencies = [
883 | "toml",
884 | ]
885 |
886 | [[package]]
887 | name = "proc-macro-crate"
888 | version = "1.1.3"
889 | source = "registry+https://github.com/rust-lang/crates.io-index"
890 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
891 | dependencies = [
892 | "thiserror",
893 | "toml",
894 | ]
895 |
896 | [[package]]
897 | name = "proc-macro2"
898 | version = "1.0.39"
899 | source = "registry+https://github.com/rust-lang/crates.io-index"
900 | checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
901 | dependencies = [
902 | "unicode-ident",
903 | ]
904 |
905 | [[package]]
906 | name = "proc-macro2-diagnostics"
907 | version = "0.9.1"
908 | source = "registry+https://github.com/rust-lang/crates.io-index"
909 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada"
910 | dependencies = [
911 | "proc-macro2",
912 | "quote",
913 | "syn",
914 | "version_check",
915 | "yansi",
916 | ]
917 |
918 | [[package]]
919 | name = "quote"
920 | version = "1.0.18"
921 | source = "registry+https://github.com/rust-lang/crates.io-index"
922 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
923 | dependencies = [
924 | "proc-macro2",
925 | ]
926 |
927 | [[package]]
928 | name = "rand"
929 | version = "0.7.3"
930 | source = "registry+https://github.com/rust-lang/crates.io-index"
931 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
932 | dependencies = [
933 | "getrandom 0.1.16",
934 | "libc",
935 | "rand_chacha",
936 | "rand_core",
937 | "rand_hc",
938 | ]
939 |
940 | [[package]]
941 | name = "rand_chacha"
942 | version = "0.2.2"
943 | source = "registry+https://github.com/rust-lang/crates.io-index"
944 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
945 | dependencies = [
946 | "ppv-lite86",
947 | "rand_core",
948 | ]
949 |
950 | [[package]]
951 | name = "rand_core"
952 | version = "0.5.1"
953 | source = "registry+https://github.com/rust-lang/crates.io-index"
954 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
955 | dependencies = [
956 | "getrandom 0.1.16",
957 | ]
958 |
959 | [[package]]
960 | name = "rand_hc"
961 | version = "0.2.0"
962 | source = "registry+https://github.com/rust-lang/crates.io-index"
963 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
964 | dependencies = [
965 | "rand_core",
966 | ]
967 |
968 | [[package]]
969 | name = "redox_syscall"
970 | version = "0.2.13"
971 | source = "registry+https://github.com/rust-lang/crates.io-index"
972 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
973 | dependencies = [
974 | "bitflags",
975 | ]
976 |
977 | [[package]]
978 | name = "regex"
979 | version = "1.5.6"
980 | source = "registry+https://github.com/rust-lang/crates.io-index"
981 | checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
982 | dependencies = [
983 | "aho-corasick",
984 | "memchr",
985 | "regex-syntax",
986 | ]
987 |
988 | [[package]]
989 | name = "regex-syntax"
990 | version = "0.6.26"
991 | source = "registry+https://github.com/rust-lang/crates.io-index"
992 | checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
993 |
994 | [[package]]
995 | name = "rustc_version"
996 | version = "0.4.0"
997 | source = "registry+https://github.com/rust-lang/crates.io-index"
998 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
999 | dependencies = [
1000 | "semver",
1001 | ]
1002 |
1003 | [[package]]
1004 | name = "rustversion"
1005 | version = "1.0.6"
1006 | source = "registry+https://github.com/rust-lang/crates.io-index"
1007 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
1008 |
1009 | [[package]]
1010 | name = "ryu"
1011 | version = "1.0.10"
1012 | source = "registry+https://github.com/rust-lang/crates.io-index"
1013 | checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
1014 |
1015 | [[package]]
1016 | name = "scopeguard"
1017 | version = "1.1.0"
1018 | source = "registry+https://github.com/rust-lang/crates.io-index"
1019 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1020 |
1021 | [[package]]
1022 | name = "semver"
1023 | version = "1.0.10"
1024 | source = "registry+https://github.com/rust-lang/crates.io-index"
1025 | checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c"
1026 |
1027 | [[package]]
1028 | name = "serde"
1029 | version = "1.0.137"
1030 | source = "registry+https://github.com/rust-lang/crates.io-index"
1031 | checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
1032 | dependencies = [
1033 | "serde_derive",
1034 | ]
1035 |
1036 | [[package]]
1037 | name = "serde_bytes"
1038 | version = "0.11.6"
1039 | source = "registry+https://github.com/rust-lang/crates.io-index"
1040 | checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54"
1041 | dependencies = [
1042 | "serde",
1043 | ]
1044 |
1045 | [[package]]
1046 | name = "serde_derive"
1047 | version = "1.0.137"
1048 | source = "registry+https://github.com/rust-lang/crates.io-index"
1049 | checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
1050 | dependencies = [
1051 | "proc-macro2",
1052 | "quote",
1053 | "syn",
1054 | ]
1055 |
1056 | [[package]]
1057 | name = "serde_json"
1058 | version = "1.0.81"
1059 | source = "registry+https://github.com/rust-lang/crates.io-index"
1060 | checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
1061 | dependencies = [
1062 | "itoa",
1063 | "ryu",
1064 | "serde",
1065 | ]
1066 |
1067 | [[package]]
1068 | name = "sha2"
1069 | version = "0.9.9"
1070 | source = "registry+https://github.com/rust-lang/crates.io-index"
1071 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
1072 | dependencies = [
1073 | "block-buffer 0.9.0",
1074 | "cfg-if",
1075 | "cpufeatures",
1076 | "digest 0.9.0",
1077 | "opaque-debug",
1078 | ]
1079 |
1080 | [[package]]
1081 | name = "sha3"
1082 | version = "0.9.1"
1083 | source = "registry+https://github.com/rust-lang/crates.io-index"
1084 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
1085 | dependencies = [
1086 | "block-buffer 0.9.0",
1087 | "digest 0.9.0",
1088 | "keccak",
1089 | "opaque-debug",
1090 | ]
1091 |
1092 | [[package]]
1093 | name = "smallvec"
1094 | version = "1.8.0"
1095 | source = "registry+https://github.com/rust-lang/crates.io-index"
1096 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
1097 |
1098 | [[package]]
1099 | name = "solana-frozen-abi"
1100 | version = "1.9.29"
1101 | source = "registry+https://github.com/rust-lang/crates.io-index"
1102 | checksum = "2d4fcb89eb3d0f30bd4b4a31ad1825c9d95cd638509acead00969d7601713288"
1103 | dependencies = [
1104 | "bs58 0.4.0",
1105 | "bv",
1106 | "generic-array",
1107 | "log",
1108 | "memmap2",
1109 | "rustc_version",
1110 | "serde",
1111 | "serde_derive",
1112 | "sha2",
1113 | "solana-frozen-abi-macro",
1114 | "solana-logger",
1115 | "thiserror",
1116 | ]
1117 |
1118 | [[package]]
1119 | name = "solana-frozen-abi-macro"
1120 | version = "1.9.29"
1121 | source = "registry+https://github.com/rust-lang/crates.io-index"
1122 | checksum = "d63ab101db88ecccd8da34065b9097b88367e0744fdfd05cb7de87b4ede3717f"
1123 | dependencies = [
1124 | "proc-macro2",
1125 | "quote",
1126 | "rustc_version",
1127 | "syn",
1128 | ]
1129 |
1130 | [[package]]
1131 | name = "solana-logger"
1132 | version = "1.9.29"
1133 | source = "registry+https://github.com/rust-lang/crates.io-index"
1134 | checksum = "9ce1805d52fc8277a84c4803c7850c8f41471b57fb0dec7750338955ad6e43e2"
1135 | dependencies = [
1136 | "env_logger",
1137 | "lazy_static",
1138 | "log",
1139 | ]
1140 |
1141 | [[package]]
1142 | name = "solana-program"
1143 | version = "1.9.29"
1144 | source = "registry+https://github.com/rust-lang/crates.io-index"
1145 | checksum = "f5deafc4902425d40197f74166640300dd20b078e4ffd518c1bb56ceb7e01680"
1146 | dependencies = [
1147 | "base64 0.13.0",
1148 | "bincode",
1149 | "bitflags",
1150 | "blake3",
1151 | "borsh",
1152 | "borsh-derive",
1153 | "bs58 0.4.0",
1154 | "bv",
1155 | "bytemuck",
1156 | "console_error_panic_hook",
1157 | "console_log",
1158 | "curve25519-dalek",
1159 | "getrandom 0.1.16",
1160 | "itertools",
1161 | "js-sys",
1162 | "lazy_static",
1163 | "libsecp256k1",
1164 | "log",
1165 | "num-derive",
1166 | "num-traits",
1167 | "parking_lot",
1168 | "rand",
1169 | "rustc_version",
1170 | "rustversion",
1171 | "serde",
1172 | "serde_bytes",
1173 | "serde_derive",
1174 | "sha2",
1175 | "sha3",
1176 | "solana-frozen-abi",
1177 | "solana-frozen-abi-macro",
1178 | "solana-logger",
1179 | "solana-sdk-macro",
1180 | "thiserror",
1181 | "wasm-bindgen",
1182 | ]
1183 |
1184 | [[package]]
1185 | name = "solana-sdk-macro"
1186 | version = "1.9.29"
1187 | source = "registry+https://github.com/rust-lang/crates.io-index"
1188 | checksum = "3db4c93bd43c91290ad54fe6ff86179a859954f196507c4789a4876d38a62f17"
1189 | dependencies = [
1190 | "bs58 0.4.0",
1191 | "proc-macro2",
1192 | "quote",
1193 | "rustversion",
1194 | "syn",
1195 | ]
1196 |
1197 | [[package]]
1198 | name = "spl-associated-token-account"
1199 | version = "1.0.5"
1200 | source = "registry+https://github.com/rust-lang/crates.io-index"
1201 | checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490"
1202 | dependencies = [
1203 | "borsh",
1204 | "solana-program",
1205 | "spl-token",
1206 | ]
1207 |
1208 | [[package]]
1209 | name = "spl-token"
1210 | version = "3.3.0"
1211 | source = "registry+https://github.com/rust-lang/crates.io-index"
1212 | checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb"
1213 | dependencies = [
1214 | "arrayref",
1215 | "num-derive",
1216 | "num-traits",
1217 | "num_enum",
1218 | "solana-program",
1219 | "thiserror",
1220 | ]
1221 |
1222 | [[package]]
1223 | name = "subtle"
1224 | version = "2.4.1"
1225 | source = "registry+https://github.com/rust-lang/crates.io-index"
1226 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
1227 |
1228 | [[package]]
1229 | name = "syn"
1230 | version = "1.0.96"
1231 | source = "registry+https://github.com/rust-lang/crates.io-index"
1232 | checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
1233 | dependencies = [
1234 | "proc-macro2",
1235 | "quote",
1236 | "unicode-ident",
1237 | ]
1238 |
1239 | [[package]]
1240 | name = "termcolor"
1241 | version = "1.1.3"
1242 | source = "registry+https://github.com/rust-lang/crates.io-index"
1243 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
1244 | dependencies = [
1245 | "winapi-util",
1246 | ]
1247 |
1248 | [[package]]
1249 | name = "thiserror"
1250 | version = "1.0.31"
1251 | source = "registry+https://github.com/rust-lang/crates.io-index"
1252 | checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
1253 | dependencies = [
1254 | "thiserror-impl",
1255 | ]
1256 |
1257 | [[package]]
1258 | name = "thiserror-impl"
1259 | version = "1.0.31"
1260 | source = "registry+https://github.com/rust-lang/crates.io-index"
1261 | checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
1262 | dependencies = [
1263 | "proc-macro2",
1264 | "quote",
1265 | "syn",
1266 | ]
1267 |
1268 | [[package]]
1269 | name = "toml"
1270 | version = "0.5.9"
1271 | source = "registry+https://github.com/rust-lang/crates.io-index"
1272 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
1273 | dependencies = [
1274 | "serde",
1275 | ]
1276 |
1277 | [[package]]
1278 | name = "typenum"
1279 | version = "1.15.0"
1280 | source = "registry+https://github.com/rust-lang/crates.io-index"
1281 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
1282 |
1283 | [[package]]
1284 | name = "unicode-ident"
1285 | version = "1.0.0"
1286 | source = "registry+https://github.com/rust-lang/crates.io-index"
1287 | checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
1288 |
1289 | [[package]]
1290 | name = "unicode-segmentation"
1291 | version = "1.9.0"
1292 | source = "registry+https://github.com/rust-lang/crates.io-index"
1293 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
1294 |
1295 | [[package]]
1296 | name = "version_check"
1297 | version = "0.9.4"
1298 | source = "registry+https://github.com/rust-lang/crates.io-index"
1299 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
1300 |
1301 | [[package]]
1302 | name = "wasi"
1303 | version = "0.9.0+wasi-snapshot-preview1"
1304 | source = "registry+https://github.com/rust-lang/crates.io-index"
1305 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1306 |
1307 | [[package]]
1308 | name = "wasi"
1309 | version = "0.10.2+wasi-snapshot-preview1"
1310 | source = "registry+https://github.com/rust-lang/crates.io-index"
1311 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
1312 |
1313 | [[package]]
1314 | name = "wasm-bindgen"
1315 | version = "0.2.80"
1316 | source = "registry+https://github.com/rust-lang/crates.io-index"
1317 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
1318 | dependencies = [
1319 | "cfg-if",
1320 | "wasm-bindgen-macro",
1321 | ]
1322 |
1323 | [[package]]
1324 | name = "wasm-bindgen-backend"
1325 | version = "0.2.80"
1326 | source = "registry+https://github.com/rust-lang/crates.io-index"
1327 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
1328 | dependencies = [
1329 | "bumpalo",
1330 | "lazy_static",
1331 | "log",
1332 | "proc-macro2",
1333 | "quote",
1334 | "syn",
1335 | "wasm-bindgen-shared",
1336 | ]
1337 |
1338 | [[package]]
1339 | name = "wasm-bindgen-macro"
1340 | version = "0.2.80"
1341 | source = "registry+https://github.com/rust-lang/crates.io-index"
1342 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
1343 | dependencies = [
1344 | "quote",
1345 | "wasm-bindgen-macro-support",
1346 | ]
1347 |
1348 | [[package]]
1349 | name = "wasm-bindgen-macro-support"
1350 | version = "0.2.80"
1351 | source = "registry+https://github.com/rust-lang/crates.io-index"
1352 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
1353 | dependencies = [
1354 | "proc-macro2",
1355 | "quote",
1356 | "syn",
1357 | "wasm-bindgen-backend",
1358 | "wasm-bindgen-shared",
1359 | ]
1360 |
1361 | [[package]]
1362 | name = "wasm-bindgen-shared"
1363 | version = "0.2.80"
1364 | source = "registry+https://github.com/rust-lang/crates.io-index"
1365 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
1366 |
1367 | [[package]]
1368 | name = "web-sys"
1369 | version = "0.3.57"
1370 | source = "registry+https://github.com/rust-lang/crates.io-index"
1371 | checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
1372 | dependencies = [
1373 | "js-sys",
1374 | "wasm-bindgen",
1375 | ]
1376 |
1377 | [[package]]
1378 | name = "winapi"
1379 | version = "0.3.9"
1380 | source = "registry+https://github.com/rust-lang/crates.io-index"
1381 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1382 | dependencies = [
1383 | "winapi-i686-pc-windows-gnu",
1384 | "winapi-x86_64-pc-windows-gnu",
1385 | ]
1386 |
1387 | [[package]]
1388 | name = "winapi-i686-pc-windows-gnu"
1389 | version = "0.4.0"
1390 | source = "registry+https://github.com/rust-lang/crates.io-index"
1391 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1392 |
1393 | [[package]]
1394 | name = "winapi-util"
1395 | version = "0.1.5"
1396 | source = "registry+https://github.com/rust-lang/crates.io-index"
1397 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1398 | dependencies = [
1399 | "winapi",
1400 | ]
1401 |
1402 | [[package]]
1403 | name = "winapi-x86_64-pc-windows-gnu"
1404 | version = "0.4.0"
1405 | source = "registry+https://github.com/rust-lang/crates.io-index"
1406 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1407 |
1408 | [[package]]
1409 | name = "yansi"
1410 | version = "0.5.1"
1411 | source = "registry+https://github.com/rust-lang/crates.io-index"
1412 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
1413 |
1414 | [[package]]
1415 | name = "zeroize"
1416 | version = "1.3.0"
1417 | source = "registry+https://github.com/rust-lang/crates.io-index"
1418 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
1419 |
--------------------------------------------------------------------------------