Merge branch 'master' into instant-sale
This commit is contained in:
commit
c226677fc6
|
@ -0,0 +1,25 @@
|
|||
name: Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
eslint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install modules
|
||||
run: yarn install
|
||||
working-directory: js
|
||||
|
||||
- name: Run ESLint
|
||||
run: yarn lint:eslint
|
||||
working-directory: js
|
|
@ -17,6 +17,7 @@ yarn-error.log*
|
|||
*.css.map
|
||||
!js/packages/metaplex/src/fonts/fonts.css
|
||||
!js/packages/metaplex/src/utils/globals.css
|
||||
js/.eslintcache
|
||||
target
|
||||
.env
|
||||
.vscode
|
||||
|
|
|
@ -16,7 +16,7 @@ Metaplex is comprised of two core components: an on-chain program, and a self-ho
|
|||
|
||||
If you want to deep dive on the Architecture, you can do so here:
|
||||
|
||||
https://www.notion.so/Metaplex-Developer-Guide-afefbc19841744c28587ab948a08cfac
|
||||
https://docs.metaplex.com/
|
||||
|
||||
## Installing
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ yarn deploy
|
|||
|
||||
## Vercel
|
||||
|
||||
To publish the Metaplex app to Vercel, you first need to visit [https://vercel.com/](https://vercel.com/) and create a new project linked to your github repo.
|
||||
To publish the Metaplex app to Vercel, you first need to visit [https://vercel.com/](https://vercel.com/) and create a new project linked to your github repo. Then, create a `pages/` directory under `js`.
|
||||
|
||||
After that, configure this project with the following settings:
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended"
|
||||
],
|
||||
globals: {
|
||||
Atomics: 'readonly',
|
||||
SharedArrayBuffer: 'readonly',
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
ecmaVersion: 2018,
|
||||
},
|
||||
plugins: ['react', '@typescript-eslint'],
|
||||
settings: {
|
||||
react: {
|
||||
pragma: 'React',
|
||||
version: '17.0.2',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': ['error'],
|
||||
},
|
||||
};
|
|
@ -14,8 +14,9 @@
|
|||
"bootstrap": "lerna link && lerna bootstrap",
|
||||
"build": "lerna run build",
|
||||
"start": "cross-env CI=true lerna run start --scope @oyster/common --stream --parallel --scope web",
|
||||
"lint": "eslint 'packages/*/{src,test}/**/*.ts' && prettier -c 'packages/*/{src,test}/**/*.ts'",
|
||||
"lint:fix": "eslint --fix 'packages/*/{src,test}/**/*.ts' && prettier --write 'packages/*/{src,test}/**/*.{ts,tsx}'",
|
||||
"lint": "prettier -c 'packages/*/{src,test}/**/*.ts' && npm run lint:eslint",
|
||||
"lint:eslint": "eslint 'packages/*/{src,test}/**/*.ts'",
|
||||
"lint:fix": "prettier --write 'packages/*/{src,test}/**/*.{ts,tsx}' && eslint --fix 'packages/*/{src,test}/**/*.ts'",
|
||||
"format:fix": "lerna run format:fix",
|
||||
"deploy": "run-s deploy:docs build deploy:apps && gh-pages -d docs",
|
||||
"deploy:docs": "lerna run docs",
|
||||
|
@ -24,7 +25,8 @@
|
|||
},
|
||||
"lint-staged": {
|
||||
"packages/*/{src,test}/**/*.ts": [
|
||||
"prettier --write"
|
||||
"prettier --write",
|
||||
"eslint --cache --fix --max-warnings=0"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
|
@ -56,6 +58,7 @@
|
|||
"@types/jest": "^24.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.6.0",
|
||||
"@typescript-eslint/parser": "^4.6.0",
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"gh-pages": "^3.1.0",
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.13.2",
|
||||
"@solana/web3.js": "^1.24.1",
|
||||
"arweave": "^1.10.16",
|
||||
"bn.js": "^5.2.0",
|
||||
"commander": "^8.1.0",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,144 @@
|
|||
import { Keypair, PublicKey, SystemProgram } from '@solana/web3.js';
|
||||
import {
|
||||
CANDY_MACHINE,
|
||||
CANDY_MACHINE_PROGRAM_ID,
|
||||
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
TOKEN_METADATA_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from './constants';
|
||||
import * as anchor from '@project-serum/anchor';
|
||||
import fs from 'fs';
|
||||
import BN from 'bn.js';
|
||||
import { createConfigAccount } from './instructions';
|
||||
|
||||
export const createConfig = async function (
|
||||
anchorProgram: anchor.Program,
|
||||
payerWallet: Keypair,
|
||||
configData: {
|
||||
maxNumberOfLines: BN;
|
||||
symbol: string;
|
||||
sellerFeeBasisPoints: number;
|
||||
isMutable: boolean;
|
||||
maxSupply: BN;
|
||||
retainAuthority: boolean;
|
||||
creators: {
|
||||
address: PublicKey;
|
||||
verified: boolean;
|
||||
share: number;
|
||||
}[];
|
||||
},
|
||||
) {
|
||||
const configAccount = Keypair.generate();
|
||||
const uuid = configAccount.publicKey.toBase58().slice(0, 6);
|
||||
|
||||
return {
|
||||
config: configAccount.publicKey,
|
||||
uuid,
|
||||
txId: await anchorProgram.rpc.initializeConfig(
|
||||
{
|
||||
uuid,
|
||||
...configData,
|
||||
},
|
||||
{
|
||||
accounts: {
|
||||
config: configAccount.publicKey,
|
||||
authority: payerWallet.publicKey,
|
||||
payer: payerWallet.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||
},
|
||||
signers: [payerWallet, configAccount],
|
||||
instructions: [
|
||||
await createConfigAccount(
|
||||
anchorProgram,
|
||||
configData,
|
||||
payerWallet.publicKey,
|
||||
configAccount.publicKey,
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
export const getTokenWallet = async function (
|
||||
wallet: PublicKey,
|
||||
mint: PublicKey,
|
||||
) {
|
||||
return (
|
||||
await PublicKey.findProgramAddress(
|
||||
[wallet.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()],
|
||||
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
)
|
||||
)[0];
|
||||
};
|
||||
|
||||
export const getCandyMachineAddress = async (
|
||||
config: anchor.web3.PublicKey,
|
||||
uuid: string,
|
||||
) => {
|
||||
return await anchor.web3.PublicKey.findProgramAddress(
|
||||
[Buffer.from(CANDY_MACHINE), config.toBuffer(), Buffer.from(uuid)],
|
||||
CANDY_MACHINE_PROGRAM_ID,
|
||||
);
|
||||
};
|
||||
|
||||
export const getConfig = async (
|
||||
authority: anchor.web3.PublicKey,
|
||||
uuid: string,
|
||||
) => {
|
||||
return await anchor.web3.PublicKey.findProgramAddress(
|
||||
[Buffer.from(CANDY_MACHINE), authority.toBuffer(), Buffer.from(uuid)],
|
||||
CANDY_MACHINE_PROGRAM_ID,
|
||||
);
|
||||
};
|
||||
|
||||
export const getMetadata = async (
|
||||
mint: anchor.web3.PublicKey,
|
||||
): Promise<anchor.web3.PublicKey> => {
|
||||
return (
|
||||
await anchor.web3.PublicKey.findProgramAddress(
|
||||
[
|
||||
Buffer.from('metadata'),
|
||||
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
|
||||
mint.toBuffer(),
|
||||
],
|
||||
TOKEN_METADATA_PROGRAM_ID,
|
||||
)
|
||||
)[0];
|
||||
};
|
||||
|
||||
export const getMasterEdition = async (
|
||||
mint: anchor.web3.PublicKey,
|
||||
): Promise<anchor.web3.PublicKey> => {
|
||||
return (
|
||||
await anchor.web3.PublicKey.findProgramAddress(
|
||||
[
|
||||
Buffer.from('metadata'),
|
||||
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
|
||||
mint.toBuffer(),
|
||||
Buffer.from('edition'),
|
||||
],
|
||||
TOKEN_METADATA_PROGRAM_ID,
|
||||
)
|
||||
)[0];
|
||||
};
|
||||
|
||||
export function loadWalletKey(keypair): Keypair {
|
||||
return Keypair.fromSecretKey(
|
||||
new Uint8Array(JSON.parse(fs.readFileSync(keypair).toString())),
|
||||
);
|
||||
}
|
||||
|
||||
export async function loadAnchorProgram(walletKeyPair: Keypair, env: string) {
|
||||
const solConnection = new anchor.web3.Connection(
|
||||
`https://api.${env}.solana.com/`,
|
||||
);
|
||||
const walletWrapper = new anchor.Wallet(walletKeyPair);
|
||||
const provider = new anchor.Provider(solConnection, walletWrapper, {
|
||||
preflightCommitment: 'recent',
|
||||
});
|
||||
const idl = await anchor.Program.fetchIdl(CANDY_MACHINE_PROGRAM_ID, provider);
|
||||
|
||||
return new anchor.Program(idl, CANDY_MACHINE_PROGRAM_ID, provider);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
export const CANDY_MACHINE = 'candy_machine';
|
||||
|
||||
export const PAYMENT_WALLET = new PublicKey(
|
||||
'HvwC9QSAzvGXhhVrgPmauVwFWcYZhne3hVot9EbHuFTm',
|
||||
);
|
||||
export const CANDY_MACHINE_PROGRAM_ID = new PublicKey(
|
||||
'cndyAnrLdpjq1Ssp1z8xxDsB8dxe7u4HL5Nxi2K5WXZ',
|
||||
);
|
||||
export const TOKEN_METADATA_PROGRAM_ID = new PublicKey(
|
||||
'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',
|
||||
);
|
||||
export const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = new PublicKey(
|
||||
'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
|
||||
);
|
||||
export const TOKEN_PROGRAM_ID = new PublicKey(
|
||||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
||||
);
|
||||
|
||||
export const CONFIG_ARRAY_START =
|
||||
32 + // authority
|
||||
4 +
|
||||
6 + // uuid + u32 len
|
||||
4 +
|
||||
10 + // u32 len + symbol
|
||||
2 + // seller fee basis points
|
||||
1 +
|
||||
4 +
|
||||
5 * 34 + // optional + u32 len + actual vec
|
||||
8 + //max supply
|
||||
1 + //is mutable
|
||||
1 + // retain authority
|
||||
4; // max number of lines;
|
||||
export const CONFIG_LINE_SIZE = 4 + 32 + 4 + 200;
|
||||
|
||||
export const CACHE_PATH = './.cache';
|
||||
|
||||
export const DEFAULT_TIMEOUT = 15000;
|
||||
|
||||
export const EXTENSION_PNG = '.png';
|
||||
export const EXTENSION_JSON = '.json';
|
|
@ -0,0 +1,89 @@
|
|||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
SYSVAR_RENT_PUBKEY,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import {
|
||||
CANDY_MACHINE_PROGRAM_ID,
|
||||
CONFIG_ARRAY_START,
|
||||
CONFIG_LINE_SIZE,
|
||||
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from './constants';
|
||||
import * as anchor from '@project-serum/anchor';
|
||||
|
||||
export function createAssociatedTokenAccountInstruction(
|
||||
associatedTokenAddress: PublicKey,
|
||||
payer: PublicKey,
|
||||
walletAddress: PublicKey,
|
||||
splTokenMintAddress: PublicKey,
|
||||
) {
|
||||
const keys = [
|
||||
{
|
||||
pubkey: payer,
|
||||
isSigner: true,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: associatedTokenAddress,
|
||||
isSigner: false,
|
||||
isWritable: true,
|
||||
},
|
||||
{
|
||||
pubkey: walletAddress,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: splTokenMintAddress,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: SystemProgram.programId,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: TOKEN_PROGRAM_ID,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{
|
||||
pubkey: SYSVAR_RENT_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
return new TransactionInstruction({
|
||||
keys,
|
||||
programId: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
data: Buffer.from([]),
|
||||
});
|
||||
}
|
||||
|
||||
export async function createConfigAccount(
|
||||
anchorProgram,
|
||||
configData,
|
||||
payerWallet,
|
||||
configAccount,
|
||||
) {
|
||||
const size =
|
||||
CONFIG_ARRAY_START +
|
||||
4 +
|
||||
configData.maxNumberOfLines.toNumber() * CONFIG_LINE_SIZE +
|
||||
4 +
|
||||
Math.ceil(configData.maxNumberOfLines.toNumber() / 8);
|
||||
|
||||
return anchor.web3.SystemProgram.createAccount({
|
||||
fromPubkey: payerWallet,
|
||||
newAccountPubkey: configAccount,
|
||||
space: size,
|
||||
lamports:
|
||||
await anchorProgram.provider.connection.getMinimumBalanceForRentExemption(
|
||||
size,
|
||||
),
|
||||
programId: CANDY_MACHINE_PROGRAM_ID,
|
||||
});
|
||||
}
|
|
@ -1,30 +1,24 @@
|
|||
// const createPaymentTransaction = () => {
|
||||
// // TODO:
|
||||
// const tx = new Transaction();
|
||||
// tx.add(SystemProgram.transfer({
|
||||
// fromPubkey: walletKey.publicKey,
|
||||
// toPubkey: PAYMENT_WALLET,
|
||||
// lamports: storageCost,
|
||||
// }));
|
||||
|
||||
import {
|
||||
Connection,
|
||||
Keypair,
|
||||
TransactionInstruction,
|
||||
Blockhash,
|
||||
Commitment,
|
||||
Transaction,
|
||||
Connection,
|
||||
FeeCalculator,
|
||||
Keypair,
|
||||
RpcResponseAndContext,
|
||||
SignatureStatus,
|
||||
SimulatedTransactionResponse,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
FeeCalculator,
|
||||
Blockhash,
|
||||
} from '@solana/web3.js';
|
||||
import { getUnixTs, sleep } from './various';
|
||||
import { DEFAULT_TIMEOUT } from './constants';
|
||||
|
||||
interface BlockhashAndFeeCalculator {
|
||||
blockhash: Blockhash;
|
||||
feeCalculator: FeeCalculator;
|
||||
}
|
||||
|
||||
export const sendTransactionWithRetryWithKeypair = async (
|
||||
connection: Connection,
|
||||
wallet: Keypair,
|
||||
|
@ -35,7 +29,7 @@ export const sendTransactionWithRetryWithKeypair = async (
|
|||
block?: BlockhashAndFeeCalculator,
|
||||
beforeSend?: () => void,
|
||||
) => {
|
||||
let transaction = new Transaction();
|
||||
const transaction = new Transaction();
|
||||
instructions.forEach(instruction => transaction.add(instruction));
|
||||
transaction.recentBlockhash = (
|
||||
block || (await connection.getRecentBlockhash(commitment))
|
||||
|
@ -69,11 +63,6 @@ export const sendTransactionWithRetryWithKeypair = async (
|
|||
return { txid, slot };
|
||||
};
|
||||
|
||||
export const getUnixTs = () => {
|
||||
return new Date().getTime() / 1000;
|
||||
};
|
||||
const DEFAULT_TIMEOUT = 15000;
|
||||
|
||||
export async function sendSignedTransaction({
|
||||
signedTransaction,
|
||||
connection,
|
||||
|
@ -135,7 +124,9 @@ export async function sendSignedTransaction({
|
|||
simulateResult = (
|
||||
await simulateTransaction(connection, signedTransaction, 'single')
|
||||
).value;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
console.error('Simulate Transaction error', e);
|
||||
}
|
||||
if (simulateResult && simulateResult.err) {
|
||||
if (simulateResult.logs) {
|
||||
for (let i = simulateResult.logs.length - 1; i >= 0; --i) {
|
||||
|
@ -198,6 +189,7 @@ async function awaitTransactionSignatureConfirmation(
|
|||
err: null,
|
||||
};
|
||||
let subId = 0;
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
status = await new Promise(async (resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
if (done) {
|
||||
|
@ -271,47 +263,3 @@ async function awaitTransactionSignatureConfirmation(
|
|||
console.log('Returning status', status);
|
||||
return status;
|
||||
}
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function fromUTF8Array(data: number[]) {
|
||||
// array of bytes
|
||||
let str = '',
|
||||
i;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
const value = data[i];
|
||||
|
||||
if (value < 0x80) {
|
||||
str += String.fromCharCode(value);
|
||||
} else if (value > 0xbf && value < 0xe0) {
|
||||
str += String.fromCharCode(((value & 0x1f) << 6) | (data[i + 1] & 0x3f));
|
||||
i += 1;
|
||||
} else if (value > 0xdf && value < 0xf0) {
|
||||
str += String.fromCharCode(
|
||||
((value & 0x0f) << 12) |
|
||||
((data[i + 1] & 0x3f) << 6) |
|
||||
(data[i + 2] & 0x3f),
|
||||
);
|
||||
i += 2;
|
||||
} else {
|
||||
// surrogate pair
|
||||
const charCode =
|
||||
(((value & 0x07) << 18) |
|
||||
((data[i + 1] & 0x3f) << 12) |
|
||||
((data[i + 2] & 0x3f) << 6) |
|
||||
(data[i + 3] & 0x3f)) -
|
||||
0x010000;
|
||||
|
||||
str += String.fromCharCode(
|
||||
(charCode >> 10) | 0xd800,
|
||||
(charCode & 0x03ff) | 0xdc00,
|
||||
);
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
|
||||
import { CACHE_PATH } from './constants';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import FormData from 'form-data';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
export const getUnixTs = () => {
|
||||
return new Date().getTime() / 1000;
|
||||
};
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function fromUTF8Array(data: number[]) {
|
||||
// array of bytes
|
||||
let str = '',
|
||||
i;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
const value = data[i];
|
||||
|
||||
if (value < 0x80) {
|
||||
str += String.fromCharCode(value);
|
||||
} else if (value > 0xbf && value < 0xe0) {
|
||||
str += String.fromCharCode(((value & 0x1f) << 6) | (data[i + 1] & 0x3f));
|
||||
i += 1;
|
||||
} else if (value > 0xdf && value < 0xf0) {
|
||||
str += String.fromCharCode(
|
||||
((value & 0x0f) << 12) |
|
||||
((data[i + 1] & 0x3f) << 6) |
|
||||
(data[i + 2] & 0x3f),
|
||||
);
|
||||
i += 2;
|
||||
} else {
|
||||
// surrogate pair
|
||||
const charCode =
|
||||
(((value & 0x07) << 18) |
|
||||
((data[i + 1] & 0x3f) << 12) |
|
||||
((data[i + 2] & 0x3f) << 6) |
|
||||
(data[i + 3] & 0x3f)) -
|
||||
0x010000;
|
||||
|
||||
str += String.fromCharCode(
|
||||
(charCode >> 10) | 0xd800,
|
||||
(charCode & 0x03ff) | 0xdc00,
|
||||
);
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function chunks(array, size) {
|
||||
return Array.apply(0, new Array(Math.ceil(array.length / size))).map(
|
||||
(_, index) => array.slice(index * size, (index + 1) * size),
|
||||
);
|
||||
}
|
||||
|
||||
export function cachePath(env: string, cacheName: string) {
|
||||
return path.join(CACHE_PATH, `${env}-${cacheName}`);
|
||||
}
|
||||
|
||||
export function loadCache(cacheName: string, env: string) {
|
||||
const path = cachePath(env, cacheName);
|
||||
return fs.existsSync(path)
|
||||
? JSON.parse(fs.readFileSync(path).toString())
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function saveCache(cacheName: string, env: string, cacheContent) {
|
||||
fs.writeFileSync(cachePath(env, cacheName), JSON.stringify(cacheContent));
|
||||
}
|
||||
|
||||
export function parsePrice(price): number {
|
||||
return Math.ceil(parseFloat(price) * LAMPORTS_PER_SOL);
|
||||
}
|
||||
|
||||
export async function upload(data: FormData, manifest, index) {
|
||||
console.log(`trying to upload ${index}.png: ${manifest.name}`);
|
||||
return await (
|
||||
await fetch(
|
||||
'https://us-central1-principal-lane-200702.cloudfunctions.net/uploadFile4',
|
||||
{
|
||||
method: 'POST',
|
||||
// @ts-ignore
|
||||
body: data,
|
||||
},
|
||||
)
|
||||
).json();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { BN } from '@project-serum/anchor';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
export class Creator {
|
||||
address: string;
|
||||
verified: boolean;
|
||||
share: number;
|
||||
|
||||
constructor(args: { address: string; verified: boolean; share: number }) {
|
||||
this.address = args.address;
|
||||
this.verified = args.verified;
|
||||
this.share = args.share;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
authority: PublicKey;
|
||||
data: ConfigData;
|
||||
}
|
||||
|
||||
export class ConfigData {
|
||||
name: string;
|
||||
symbol: string;
|
||||
uri: string;
|
||||
sellerFeeBasisPoints: number;
|
||||
creators: Creator[] | null;
|
||||
maxNumberOfLines: BN | number;
|
||||
isMutable: boolean;
|
||||
maxSupply: BN;
|
||||
retainAuthority: boolean;
|
||||
constructor(args: {
|
||||
name: string;
|
||||
symbol: string;
|
||||
uri: string;
|
||||
sellerFeeBasisPoints: number;
|
||||
creators: Creator[] | null;
|
||||
maxNumberOfLines: BN;
|
||||
isMutable: boolean;
|
||||
maxSupply: BN;
|
||||
retainAuthority: boolean;
|
||||
}) {
|
||||
this.name = args.name;
|
||||
this.symbol = args.symbol;
|
||||
this.uri = args.uri;
|
||||
this.sellerFeeBasisPoints = args.sellerFeeBasisPoints;
|
||||
this.creators = args.creators;
|
||||
this.maxNumberOfLines = args.maxNumberOfLines;
|
||||
this.isMutable = args.isMutable;
|
||||
this.maxSupply = args.maxSupply;
|
||||
this.retainAuthority = args.retainAuthority;
|
||||
}
|
||||
}
|
|
@ -447,6 +447,7 @@ export const METADATA_SCHEMA = new Map<any, any>([
|
|||
],
|
||||
]);
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const METADATA_REPLACE = new RegExp('\u0000', 'g');
|
||||
|
||||
export const decodeMetadata = (buffer: Buffer): Metadata => {
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
MintLayout,
|
||||
AccountLayout,
|
||||
Token,
|
||||
AuthorityType,
|
||||
} from '@solana/spl-token';
|
||||
import { MintLayout, AccountLayout, Token } from '@solana/spl-token';
|
||||
import {
|
||||
Connection,
|
||||
PublicKey,
|
||||
|
@ -25,9 +20,9 @@ export const mintNFT = async (
|
|||
const TOKEN_PROGRAM_ID = new PublicKey(
|
||||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
||||
);
|
||||
const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = new PublicKey(
|
||||
'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
|
||||
);
|
||||
//const SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = new PublicKey(
|
||||
// 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
|
||||
//);
|
||||
const mintAccount = new Account();
|
||||
const tokenAccount = new Account();
|
||||
|
||||
|
@ -110,7 +105,7 @@ export const mintNFT = async (
|
|||
}
|
||||
transaction = await wallet.signTransaction(transaction);
|
||||
const rawTransaction = transaction.serialize();
|
||||
let options = {
|
||||
const options = {
|
||||
skipPreflight: true,
|
||||
commitment: 'singleGossip',
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ export function approve(
|
|||
const tokenProgram = TOKEN_PROGRAM_ID;
|
||||
|
||||
const transferAuthority = existingTransferAuthority || Keypair.generate();
|
||||
const delegateKey = delegate ?? transferAuthority.publicKey;
|
||||
//const delegateKey = delegate ?? transferAuthority.publicKey;
|
||||
|
||||
instructions.push(
|
||||
Token.createApproveInstruction(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PublicKey, AccountInfo, Account } from '@solana/web3.js';
|
||||
import { PublicKey, AccountInfo } from '@solana/web3.js';
|
||||
|
||||
export type StringPublicKey = string;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ export function decodeLength(bytes: Array<number>): number {
|
|||
let len = 0;
|
||||
let size = 0;
|
||||
for (;;) {
|
||||
let elem = bytes.shift();
|
||||
const elem = bytes.shift();
|
||||
//@ts-ignore
|
||||
len |= (elem & 0x7f) << (size * 7);
|
||||
size += 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// credit https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
|
||||
export function toUTF8Array(str: string) {
|
||||
let utf8 = [];
|
||||
const utf8: number[] = [];
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let charcode = str.charCodeAt(i);
|
||||
if (charcode < 0x80) utf8.push(charcode);
|
||||
|
|
|
@ -56,7 +56,7 @@ export const findProgramAddress = async (
|
|||
'pda-' +
|
||||
seeds.reduce((agg, item) => agg + item.toString('hex'), '') +
|
||||
programId.toString();
|
||||
let cached = localStorage.getItem(key);
|
||||
const cached = localStorage.getItem(key);
|
||||
if (cached) {
|
||||
const value = JSON.parse(cached);
|
||||
|
||||
|
@ -207,14 +207,14 @@ export const tryParseKey = (key: string): PublicKey | null => {
|
|||
}
|
||||
};
|
||||
|
||||
var SI_SYMBOL = ['', 'k', 'M', 'G', 'T', 'P', 'E'];
|
||||
const SI_SYMBOL = ['', 'k', 'M', 'G', 'T', 'P', 'E'] as const;
|
||||
|
||||
const abbreviateNumber = (number: number, precision: number) => {
|
||||
let tier = (Math.log10(number) / 3) | 0;
|
||||
const tier = (Math.log10(number) / 3) | 0;
|
||||
let scaled = number;
|
||||
let suffix = SI_SYMBOL[tier];
|
||||
const suffix = SI_SYMBOL[tier];
|
||||
if (tier !== 0) {
|
||||
let scale = Math.pow(10, tier * 3);
|
||||
const scale = Math.pow(10, tier * 3);
|
||||
scaled = number / scale;
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ export function convert(
|
|||
typeof account === 'number' ? account : account.info.amount?.toNumber();
|
||||
|
||||
const precision = Math.pow(10, mint?.decimals || 0);
|
||||
let result = (amount / precision) * rate;
|
||||
const result = (amount / precision) * rate;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
REACT_APP_STORE_OWNER_ADDRESS_ADDRESS=CduMjFZLBeg3A9wMP3hQCoU1RQzzCpgSvQNXfCi1GCSB
|
||||
REACT_APP_STORE_OWNER_ADDRESS_ADDRESS=
|
||||
REACT_APP_STORE_ADDRESS=
|
||||
REACT_APP_BIG_STORE=FALSE
|
||||
|
|
|
@ -51,9 +51,6 @@
|
|||
"deploy": "cross-env ASSET_PREFIX=/metaplex/ yarn build && yarn deploy:gh",
|
||||
"format:fix": "prettier --write \"**/*.+(js|jsx|ts|tsx|json|css|md)\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
|
|
|
@ -62,14 +62,14 @@ export async function addTokensToVault(
|
|||
|
||||
let batchCounter = 0;
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
let newStores: StringPublicKey[] = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
const newStores: StringPublicKey[] = [];
|
||||
|
||||
let currSigners: Keypair[] = [];
|
||||
let currInstructions: TransactionInstruction[] = [];
|
||||
for (let i = 0; i < nfts.length; i++) {
|
||||
let nft = nfts[i];
|
||||
const nft = nfts[i];
|
||||
if (nft.box.tokenAccount) {
|
||||
const newStoreAccount = createTokenAccount(
|
||||
currInstructions,
|
||||
|
|
|
@ -33,8 +33,8 @@ export async function sendCancelBid(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
if (
|
||||
auctionView.auction.info.ended() &&
|
||||
|
@ -112,11 +112,11 @@ export async function setupCancelBid(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let cancelSigners: Keypair[] = [];
|
||||
let cancelInstructions: TransactionInstruction[] = [];
|
||||
let cleanupInstructions: TransactionInstruction[] = [];
|
||||
const cancelSigners: Keypair[] = [];
|
||||
const cancelInstructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
let tokenAccount = accountsByMint.get(auctionView.auction.info.tokenMint);
|
||||
const tokenAccount = accountsByMint.get(auctionView.auction.info.tokenMint);
|
||||
const mint = cache.get(auctionView.auction.info.tokenMint);
|
||||
|
||||
if (mint && auctionView.myBidderPot) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
SafetyDepositBox,
|
||||
deprecatedGetReservationList,
|
||||
MasterEditionV1,
|
||||
MasterEditionV2,
|
||||
findProgramAddress,
|
||||
programIds,
|
||||
createAssociatedTokenAccountInstruction,
|
||||
|
@ -144,7 +143,7 @@ export async function claimUnusedPrizes(
|
|||
}
|
||||
}
|
||||
|
||||
let printingV2ByMint: Record<string, AuctionViewItem> = {};
|
||||
const printingV2ByMint: Record<string, AuctionViewItem> = {};
|
||||
|
||||
for (
|
||||
let winnerIndex = 0;
|
||||
|
@ -189,7 +188,7 @@ export async function claimUnusedPrizes(
|
|||
winnerIndex,
|
||||
);
|
||||
break;
|
||||
case WinningConfigType.PrintingV2:
|
||||
case WinningConfigType.PrintingV2: {
|
||||
const winningBidder =
|
||||
auctionView.auction.info.bidState.getWinnerAt(winnerIndex);
|
||||
if (winningBidder) {
|
||||
|
@ -215,6 +214,7 @@ export async function claimUnusedPrizes(
|
|||
}
|
||||
printingV2ByMint[item.metadata.info.mint] = item;
|
||||
break;
|
||||
}
|
||||
case WinningConfigType.FullRightsTransfer:
|
||||
console.log('Redeeming Full Rights');
|
||||
await setupRedeemFullRightsTransferInstructions(
|
||||
|
@ -246,9 +246,9 @@ export async function claimUnusedPrizes(
|
|||
}
|
||||
}
|
||||
|
||||
let allV2s = Object.values(printingV2ByMint);
|
||||
const allV2s = Object.values(printingV2ByMint);
|
||||
for (let i = 0; i < allV2s.length; i++) {
|
||||
let item = allV2s[i];
|
||||
const item = allV2s[i];
|
||||
await setupWithdrawMasterEditionInstructions(
|
||||
connection,
|
||||
auctionView,
|
||||
|
@ -273,8 +273,8 @@ async function setupRedeemInstructions(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
signers.push(winningPrizeSigner);
|
||||
instructions.push(winningPrizeInstructions);
|
||||
|
@ -327,8 +327,8 @@ async function setupRedeemFullRightsTransferInstructions(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const claimed = auctionView.auctionManager.isItemClaimed(
|
||||
winningConfigIndex,
|
||||
safetyDeposit.info.order,
|
||||
|
@ -452,8 +452,8 @@ async function deprecatedSetupRedeemPrintingInstructions(
|
|||
);
|
||||
console.log('This state item is', claimed);
|
||||
if (!claimed) {
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
signers.push(winningPrizeSigner);
|
||||
instructions.push(winningPrizeInstructions);
|
||||
|
|
|
@ -23,9 +23,9 @@ export async function closePersonalEscrow(
|
|||
|
||||
const PROGRAM_IDS = utils.programIds();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
|
||||
let instructions: TransactionInstruction[] = [
|
||||
const instructions: TransactionInstruction[] = [
|
||||
Token.createCloseAccountInstruction(
|
||||
PROGRAM_IDS.token,
|
||||
toPublicKey(ata),
|
||||
|
|
|
@ -32,8 +32,8 @@ export async function closeVault(
|
|||
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
);
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
await activateVault(
|
||||
new BN(0),
|
||||
|
@ -62,7 +62,7 @@ export async function closeVault(
|
|||
signers,
|
||||
);
|
||||
|
||||
let transferAuthority = Keypair.generate();
|
||||
const transferAuthority = Keypair.generate();
|
||||
|
||||
// Shouldn't need to pay anything since we activated vault with 0 shares, but we still
|
||||
// need this setup anyway.
|
||||
|
|
|
@ -53,7 +53,7 @@ export async function filterMetadata(
|
|||
console.log('Reviewing', masterEdition.pubkey);
|
||||
let printingBal = 0;
|
||||
try {
|
||||
let printingBalResp = await connection.getTokenSupply(
|
||||
const printingBalResp = await connection.getTokenSupply(
|
||||
toPublicKey(masterEdition.info.printingMint),
|
||||
);
|
||||
printingBal = printingBalResp.value.uiAmount || 0;
|
||||
|
@ -83,7 +83,7 @@ export async function filterMetadata(
|
|||
} else {
|
||||
let oneTimeBal = 0;
|
||||
try {
|
||||
let oneTimeBalResp = await connection.getTokenSupply(
|
||||
const oneTimeBalResp = await connection.getTokenSupply(
|
||||
toPublicKey(masterEdition.info.oneTimePrintingAuthorizationMint),
|
||||
);
|
||||
oneTimeBal = oneTimeBalResp.value.uiAmount || 0;
|
||||
|
@ -133,8 +133,8 @@ export async function convertMasterEditions(
|
|||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
const PROGRAM_IDS = programIds();
|
||||
let signers: Array<Array<Keypair[]>> = [];
|
||||
let instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
const signers: Array<Array<Keypair[]>> = [];
|
||||
const instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
|
||||
let currSignerBatch: Array<Keypair[]> = [];
|
||||
let currInstrBatch: Array<TransactionInstruction[]> = [];
|
||||
|
|
|
@ -142,7 +142,7 @@ export async function createAuctionManager(
|
|||
auction,
|
||||
} = await makeAuction(wallet, vault, auctionSettings);
|
||||
|
||||
let safetyDepositConfigsWithPotentiallyUnsetTokens =
|
||||
const safetyDepositConfigsWithPotentiallyUnsetTokens =
|
||||
await buildSafetyDepositArray(
|
||||
wallet,
|
||||
safetyDepositDrafts,
|
||||
|
@ -189,7 +189,7 @@ export async function createAuctionManager(
|
|||
safetyDepositConfigs,
|
||||
);
|
||||
|
||||
let lookup: byType = {
|
||||
const lookup: byType = {
|
||||
markItemsThatArentMineAsSold: await markItemsThatArentMineAsSold(
|
||||
wallet,
|
||||
safetyDepositDrafts,
|
||||
|
@ -277,7 +277,7 @@ export async function createAuctionManager(
|
|||
},
|
||||
};
|
||||
|
||||
let signers: Keypair[][] = [
|
||||
const signers: Keypair[][] = [
|
||||
...lookup.markItemsThatArentMineAsSold.signers,
|
||||
lookup.externalPriceAccount.signers,
|
||||
lookup.deprecatedBuildAndPopulateOneTimeAuthorizationAccount?.signers || [],
|
||||
|
@ -377,7 +377,7 @@ async function buildSafetyDepositArray(
|
|||
): Promise<SafetyDepositInstructionTemplate[]> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let safetyDepositTemplates: SafetyDepositInstructionTemplate[] = [];
|
||||
const safetyDepositTemplates: SafetyDepositInstructionTemplate[] = [];
|
||||
safetyDeposits.forEach((s, i) => {
|
||||
const maxAmount = [...s.amountRanges.map(a => a.amount)]
|
||||
.sort()
|
||||
|
@ -518,13 +518,13 @@ async function setupAuctionManagerInstructions(
|
|||
}> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let store = programIds().store?.toBase58();
|
||||
const store = programIds().store?.toBase58();
|
||||
if (!store) {
|
||||
throw new Error('Store not initialized');
|
||||
}
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
const { auctionManagerKey } = await getAuctionKeys(vault);
|
||||
|
||||
|
@ -572,8 +572,8 @@ async function setupStartAuction(
|
|||
}> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
await startAuction(vault, wallet.publicKey.toBase58(), instructions);
|
||||
|
||||
|
@ -599,8 +599,8 @@ async function deprecatedValidateParticipationHelper(
|
|||
throw new Error('Store not initialized');
|
||||
}
|
||||
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
let signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const whitelistedCreator = participationSafetyDepositDraft.metadata.info.data
|
||||
.creators
|
||||
? await findValidWhitelistedCreator(
|
||||
|
@ -684,12 +684,12 @@ async function validateBoxes(
|
|||
if (!store) {
|
||||
throw new Error('Store not initialized');
|
||||
}
|
||||
let signers: Keypair[][] = [];
|
||||
let instructions: TransactionInstruction[][] = [];
|
||||
const signers: Keypair[][] = [];
|
||||
const instructions: TransactionInstruction[][] = [];
|
||||
|
||||
for (let i = 0; i < safetyDeposits.length; i++) {
|
||||
let tokenSigners: Keypair[] = [];
|
||||
let tokenInstructions: TransactionInstruction[] = [];
|
||||
const tokenSigners: Keypair[] = [];
|
||||
const tokenInstructions: TransactionInstruction[] = [];
|
||||
|
||||
let safetyDepositBox: StringPublicKey;
|
||||
|
||||
|
@ -762,8 +762,8 @@ async function deprecatedBuildAndPopulateOneTimeAuthorizationAccount(
|
|||
|
||||
if (!oneTimePrintingAuthorizationMint)
|
||||
return { instructions: [], signers: [] };
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const recipientKey: StringPublicKey = (
|
||||
await findProgramAddress(
|
||||
[
|
||||
|
|
|
@ -35,17 +35,17 @@ export async function createExternalPriceAccount(
|
|||
|
||||
const PROGRAM_IDS = utils.programIds();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
const epaRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
MAX_EXTERNAL_ACCOUNT_SIZE,
|
||||
);
|
||||
|
||||
let externalPriceAccount = Keypair.generate();
|
||||
let key = externalPriceAccount.publicKey.toBase58();
|
||||
const externalPriceAccount = Keypair.generate();
|
||||
const key = externalPriceAccount.publicKey.toBase58();
|
||||
|
||||
let epaStruct = new ExternalPriceAccount({
|
||||
const epaStruct = new ExternalPriceAccount({
|
||||
pricePerShare: new BN(0),
|
||||
priceMint: QUOTE_MINT.toBase58(),
|
||||
allowedToCombine: true,
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
import { Keypair, TransactionInstruction } from '@solana/web3.js';
|
||||
import { Token } from '@solana/spl-token';
|
||||
import {
|
||||
createAssociatedTokenAccountInstruction,
|
||||
createMint,
|
||||
findProgramAddress,
|
||||
programIds,
|
||||
StringPublicKey,
|
||||
toPublicKey,
|
||||
} from '@oyster/common';
|
||||
import { WalletNotConnectedError } from '@solana/wallet-adapter-base';
|
||||
|
||||
export async function createMintAndAccountWithOne(
|
||||
wallet: any,
|
||||
receiverWallet: StringPublicKey,
|
||||
mintRent: any,
|
||||
instructions: TransactionInstruction[],
|
||||
signers: Keypair[],
|
||||
): Promise<{ mint: StringPublicKey; account: StringPublicKey }> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
const mint = createMint(
|
||||
instructions,
|
||||
wallet.publicKey,
|
||||
mintRent,
|
||||
0,
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
signers,
|
||||
);
|
||||
|
||||
const PROGRAM_IDS = programIds();
|
||||
|
||||
const account: StringPublicKey = (
|
||||
await findProgramAddress(
|
||||
[
|
||||
toPublicKey(receiverWallet).toBuffer(),
|
||||
PROGRAM_IDS.token.toBuffer(),
|
||||
mint.toBuffer(),
|
||||
],
|
||||
PROGRAM_IDS.associatedToken,
|
||||
)
|
||||
)[0];
|
||||
|
||||
createAssociatedTokenAccountInstruction(
|
||||
instructions,
|
||||
toPublicKey(account),
|
||||
wallet.publicKey,
|
||||
toPublicKey(receiverWallet),
|
||||
mint,
|
||||
);
|
||||
|
||||
instructions.push(
|
||||
Token.createMintToInstruction(
|
||||
PROGRAM_IDS.token,
|
||||
mint,
|
||||
toPublicKey(account),
|
||||
wallet.publicKey,
|
||||
[],
|
||||
1,
|
||||
),
|
||||
);
|
||||
|
||||
return { mint: mint.toBase58(), account };
|
||||
}
|
|
@ -38,8 +38,8 @@ export async function createVault(
|
|||
|
||||
const PROGRAM_IDS = utils.programIds();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
|
@ -53,7 +53,7 @@ export async function createVault(
|
|||
MAX_VAULT_SIZE,
|
||||
);
|
||||
|
||||
let vault = Keypair.generate();
|
||||
const vault = Keypair.generate();
|
||||
|
||||
const vaultAuthority = (
|
||||
await findProgramAddress(
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
sendTransactionsWithManualRetry,
|
||||
setAuctionAuthority,
|
||||
setVaultAuthority,
|
||||
TokenAccount,
|
||||
WalletSigner,
|
||||
} from '@oyster/common';
|
||||
import { WalletNotConnectedError } from '@solana/wallet-adapter-base';
|
||||
|
@ -25,12 +24,12 @@ export async function decommAuctionManagerAndReturnPrizes(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
if (auctionView.auctionManager.status === AuctionManagerStatus.Initialized) {
|
||||
let decomSigners: Keypair[] = [];
|
||||
let decomInstructions: TransactionInstruction[] = [];
|
||||
const decomSigners: Keypair[] = [];
|
||||
const decomInstructions: TransactionInstruction[] = [];
|
||||
|
||||
if (auctionView.auction.info.authority === wallet.publicKey.toBase58()) {
|
||||
await setAuctionAuthority(
|
||||
|
|
|
@ -23,8 +23,8 @@ export async function deprecatedCreateReservationListForTokens(
|
|||
|
||||
let batchCounter = 0;
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let currSigners: Keypair[] = [];
|
||||
let currInstructions: TransactionInstruction[] = [];
|
||||
|
|
|
@ -32,13 +32,13 @@ export async function deprecatedPopulatePrintingTokens(
|
|||
|
||||
let batchCounter = 0;
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let currSigners: Keypair[] = [];
|
||||
let currInstructions: TransactionInstruction[] = [];
|
||||
for (let i = 0; i < safetyDepositConfigs.length; i++) {
|
||||
let nft = safetyDepositConfigs[i];
|
||||
const nft = safetyDepositConfigs[i];
|
||||
if (nft.draft.masterEdition?.info.key != MetadataKey.MasterEditionV1) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ export async function makeAuction(
|
|||
|
||||
const PROGRAM_IDS = utils.programIds();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const auctionKey = (
|
||||
await findProgramAddress(
|
||||
[
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Keypair, Connection, TransactionInstruction } from '@solana/web3.js';
|
||||
import { Keypair, TransactionInstruction } from '@solana/web3.js';
|
||||
import {
|
||||
updatePrimarySaleHappenedViaToken,
|
||||
WalletSigner,
|
||||
|
@ -15,8 +15,8 @@ export async function markItemsThatArentMineAsSold(
|
|||
|
||||
const publicKey = wallet.publicKey.toBase58();
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let markSigners: Keypair[] = [];
|
||||
let markInstructions: TransactionInstruction[] = [];
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
import BN from 'bn.js';
|
||||
import { Connection, Keypair, TransactionInstruction } from '@solana/web3.js';
|
||||
import {
|
||||
sendTransactions,
|
||||
sendTransactionWithRetry,
|
||||
SequenceType,
|
||||
StringPublicKey,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
import { setupMintEditionIntoWalletInstructions } from './setupMintEditionIntoWalletInstructions';
|
||||
import { Art } from '../types';
|
||||
import { WalletContextState } from '@solana/wallet-adapter-react';
|
||||
|
||||
// TODO: Refactor. Extract batching logic,
|
||||
// as the similar one is used in settle.ts and convertMasterEditions.ts
|
||||
const MINT_TRANSACTION_SIZE = 5;
|
||||
const BATCH_SIZE = 10;
|
||||
|
||||
export async function mintEditionsToWallet(
|
||||
art: Art,
|
||||
wallet: WalletContextState,
|
||||
connection: Connection,
|
||||
mintTokenAccount: TokenAccount,
|
||||
editions: number = 1,
|
||||
mintDestination: StringPublicKey,
|
||||
) {
|
||||
const signers: Array<Array<Keypair[]>> = [];
|
||||
const instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
|
||||
let currSignerBatch: Array<Keypair[]> = [];
|
||||
let currInstrBatch: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let mintEditionIntoWalletSigners: Keypair[] = [];
|
||||
let mintEditionIntoWalletInstructions: TransactionInstruction[] = [];
|
||||
|
||||
// TODO replace all this with payer account so user doesnt need to click approve several times.
|
||||
|
||||
// Overall we have 10 parallel txns.
|
||||
// That's what this loop is building.
|
||||
for (let i = 0; i < editions; i++) {
|
||||
console.log('Minting', i);
|
||||
await setupMintEditionIntoWalletInstructions(
|
||||
art,
|
||||
wallet,
|
||||
connection,
|
||||
mintTokenAccount,
|
||||
new BN(art.supply! + 1 + i),
|
||||
mintEditionIntoWalletInstructions,
|
||||
mintEditionIntoWalletSigners,
|
||||
mintDestination,
|
||||
);
|
||||
|
||||
if (mintEditionIntoWalletInstructions.length === MINT_TRANSACTION_SIZE) {
|
||||
currSignerBatch.push(mintEditionIntoWalletSigners);
|
||||
currInstrBatch.push(mintEditionIntoWalletInstructions);
|
||||
mintEditionIntoWalletSigners = [];
|
||||
mintEditionIntoWalletInstructions = [];
|
||||
}
|
||||
|
||||
if (currInstrBatch.length === BATCH_SIZE) {
|
||||
signers.push(currSignerBatch);
|
||||
instructions.push(currInstrBatch);
|
||||
currSignerBatch = [];
|
||||
currInstrBatch = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
mintEditionIntoWalletInstructions.length < MINT_TRANSACTION_SIZE &&
|
||||
mintEditionIntoWalletInstructions.length > 0
|
||||
) {
|
||||
currSignerBatch.push(mintEditionIntoWalletSigners);
|
||||
currInstrBatch.push(mintEditionIntoWalletInstructions);
|
||||
}
|
||||
|
||||
if (currInstrBatch.length <= BATCH_SIZE && currInstrBatch.length > 0) {
|
||||
// add the last one on
|
||||
signers.push(currSignerBatch);
|
||||
instructions.push(currInstrBatch);
|
||||
}
|
||||
console.log('Instructions', instructions);
|
||||
for (let i = 0; i < instructions.length; i++) {
|
||||
const instructionBatch = instructions[i];
|
||||
const signerBatch = signers[i];
|
||||
console.log('Running batch', i);
|
||||
if (instructionBatch.length >= 2)
|
||||
// Pump em through!
|
||||
await sendTransactions(
|
||||
connection,
|
||||
wallet,
|
||||
instructionBatch,
|
||||
signerBatch,
|
||||
SequenceType.StopOnFailure,
|
||||
'single',
|
||||
);
|
||||
else
|
||||
await sendTransactionWithRetry(
|
||||
connection,
|
||||
wallet,
|
||||
instructionBatch[0],
|
||||
signerBatch[0],
|
||||
'single',
|
||||
);
|
||||
console.log('Done');
|
||||
}
|
||||
}
|
|
@ -20,11 +20,11 @@ export async function saveAdmin(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let storeSigners: Keypair[] = [];
|
||||
let storeInstructions: TransactionInstruction[] = [];
|
||||
const storeSigners: Keypair[] = [];
|
||||
const storeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
await setStore(
|
||||
isPublic,
|
||||
|
@ -37,8 +37,8 @@ export async function saveAdmin(
|
|||
|
||||
for (let i = 0; i < whitelistedCreators.length; i++) {
|
||||
const wc = whitelistedCreators[i];
|
||||
let wcSigners: Keypair[] = [];
|
||||
let wcInstructions: TransactionInstruction[] = [];
|
||||
const wcSigners: Keypair[] = [];
|
||||
const wcInstructions: TransactionInstruction[] = [];
|
||||
|
||||
await setWhitelistedCreator(
|
||||
wc.address,
|
||||
|
|
|
@ -31,9 +31,9 @@ export async function sendPlaceBid(
|
|||
// value entered by the user adjust to decimals of the mint
|
||||
amount: number | BN,
|
||||
) {
|
||||
let signers: Keypair[][] = [];
|
||||
let instructions: TransactionInstruction[][] = [];
|
||||
let bid = await setupPlaceBid(
|
||||
const signers: Keypair[][] = [];
|
||||
const instructions: TransactionInstruction[][] = [];
|
||||
const bid = await setupPlaceBid(
|
||||
connection,
|
||||
wallet,
|
||||
bidderTokenAccount,
|
||||
|
@ -73,7 +73,7 @@ export async function setupPlaceBid(
|
|||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
let cleanupInstructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
|
@ -86,7 +86,7 @@ export async function setupPlaceBid(
|
|||
tokenAccount ? tokenAccount.info.mint : QUOTE_MINT,
|
||||
) as ParsedAccount<MintInfo>;
|
||||
|
||||
let lamports =
|
||||
const lamports =
|
||||
accountRentExempt +
|
||||
(typeof amount === 'number'
|
||||
? toLamports(amount, mint.info)
|
||||
|
@ -105,8 +105,8 @@ export async function setupPlaceBid(
|
|||
} else {
|
||||
bidderPotTokenAccount = auctionView.myBidderPot?.info.bidderPot;
|
||||
if (!auctionView.auction.info.ended()) {
|
||||
let cancelSigners: Keypair[][] = [];
|
||||
let cancelInstr: TransactionInstruction[][] = [];
|
||||
const cancelSigners: Keypair[][] = [];
|
||||
const cancelInstr: TransactionInstruction[][] = [];
|
||||
await setupCancelBid(
|
||||
auctionView,
|
||||
accountsByMint,
|
||||
|
|
|
@ -16,15 +16,12 @@ import {
|
|||
sendTransactionsWithManualRetry,
|
||||
MasterEditionV1,
|
||||
MasterEditionV2,
|
||||
findProgramAddress,
|
||||
createAssociatedTokenAccountInstruction,
|
||||
deprecatedMintNewEditionFromMasterEditionViaPrintingToken,
|
||||
MetadataKey,
|
||||
TokenAccountParser,
|
||||
BidderMetadata,
|
||||
getEditionMarkPda,
|
||||
decodeEditionMarker,
|
||||
BidStateType,
|
||||
StringPublicKey,
|
||||
toPublicKey,
|
||||
WalletSigner,
|
||||
|
@ -44,13 +41,13 @@ import {
|
|||
PrizeTrackingTicket,
|
||||
getPrizeTrackingTicket,
|
||||
BidRedemptionTicket,
|
||||
getBidRedemption,
|
||||
} from '../models/metaplex';
|
||||
import { claimBid } from '../models/metaplex/claimBid';
|
||||
import { setupCancelBid } from './cancelBid';
|
||||
import { deprecatedPopulateParticipationPrintingAccount } from '../models/metaplex/deprecatedPopulateParticipationPrintingAccount';
|
||||
import { setupPlaceBid } from './sendPlaceBid';
|
||||
import { claimUnusedPrizes } from './claimUnusedPrizes';
|
||||
import { createMintAndAccountWithOne } from './createMintAndAccountWithOne';
|
||||
import { BN } from 'bn.js';
|
||||
import { QUOTE_MINT } from '../constants';
|
||||
import {
|
||||
|
@ -97,8 +94,8 @@ export async function sendRedeemBid(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
if (
|
||||
auctionView.auction.info.ended() &&
|
||||
|
@ -202,8 +199,8 @@ export async function sendRedeemBid(
|
|||
}
|
||||
|
||||
if (auctionView.myBidderMetadata && auctionView.myBidderPot) {
|
||||
let claimSigners: Keypair[] = [];
|
||||
let claimInstructions: TransactionInstruction[] = [];
|
||||
const claimSigners: Keypair[] = [];
|
||||
const claimInstructions: TransactionInstruction[] = [];
|
||||
instructions.push(claimInstructions);
|
||||
signers.push(claimSigners);
|
||||
console.log('Claimed');
|
||||
|
@ -306,8 +303,8 @@ async function setupRedeemInstructions(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
signers.push(winningPrizeSigner);
|
||||
instructions.push(winningPrizeInstructions);
|
||||
|
@ -366,8 +363,8 @@ async function setupRedeemFullRightsTransferInstructions(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
signers.push(winningPrizeSigner);
|
||||
instructions.push(winningPrizeInstructions);
|
||||
|
@ -413,60 +410,6 @@ async function setupRedeemFullRightsTransferInstructions(
|
|||
}
|
||||
}
|
||||
|
||||
async function createMintAndAccountWithOne(
|
||||
wallet: WalletSigner,
|
||||
receiverWallet: StringPublicKey,
|
||||
mintRent: any,
|
||||
instructions: TransactionInstruction[],
|
||||
signers: Keypair[],
|
||||
): Promise<{ mint: StringPublicKey; account: StringPublicKey }> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
const mint = createMint(
|
||||
instructions,
|
||||
wallet.publicKey,
|
||||
mintRent,
|
||||
0,
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
signers,
|
||||
);
|
||||
|
||||
const PROGRAM_IDS = programIds();
|
||||
|
||||
const account: StringPublicKey = (
|
||||
await findProgramAddress(
|
||||
[
|
||||
toPublicKey(receiverWallet).toBuffer(),
|
||||
PROGRAM_IDS.token.toBuffer(),
|
||||
mint.toBuffer(),
|
||||
],
|
||||
PROGRAM_IDS.associatedToken,
|
||||
)
|
||||
)[0];
|
||||
|
||||
createAssociatedTokenAccountInstruction(
|
||||
instructions,
|
||||
toPublicKey(account),
|
||||
wallet.publicKey,
|
||||
toPublicKey(receiverWallet),
|
||||
mint,
|
||||
);
|
||||
|
||||
instructions.push(
|
||||
Token.createMintToInstruction(
|
||||
PROGRAM_IDS.token,
|
||||
mint,
|
||||
toPublicKey(account),
|
||||
wallet.publicKey,
|
||||
[],
|
||||
1,
|
||||
),
|
||||
);
|
||||
|
||||
return { mint: mint.toBase58(), account };
|
||||
}
|
||||
|
||||
export async function setupRedeemPrintingV2Instructions(
|
||||
connection: Connection,
|
||||
auctionView: AuctionView,
|
||||
|
@ -515,8 +458,8 @@ export async function setupRedeemPrintingV2Instructions(
|
|||
);
|
||||
|
||||
for (let i = 0; i < item.amount.toNumber(); i++) {
|
||||
let myInstructions: TransactionInstruction[] = [];
|
||||
let mySigners: Keypair[] = [];
|
||||
const myInstructions: TransactionInstruction[] = [];
|
||||
const mySigners: Keypair[] = [];
|
||||
|
||||
const { mint, account } = await createMintAndAccountWithOne(
|
||||
wallet,
|
||||
|
@ -625,8 +568,8 @@ async function deprecatedSetupRedeemPrintingV1Instructions(
|
|||
if (updateAuth && auctionView.myBidderMetadata) {
|
||||
console.log('This state item is', claimed);
|
||||
if (!claimed) {
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
|
||||
signers.push(winningPrizeSigner);
|
||||
instructions.push(winningPrizeInstructions);
|
||||
|
@ -691,8 +634,8 @@ async function deprecatedRedeemPrintingV1Token(
|
|||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
if (!item.masterEdition) return;
|
||||
let cashInLimitedPrizeAuthorizationTokenSigner: Keypair[] = [];
|
||||
let cashInLimitedPrizeAuthorizationTokenInstruction: TransactionInstruction[] =
|
||||
const cashInLimitedPrizeAuthorizationTokenSigner: Keypair[] = [];
|
||||
const cashInLimitedPrizeAuthorizationTokenInstruction: TransactionInstruction[] =
|
||||
[];
|
||||
signers.push(cashInLimitedPrizeAuthorizationTokenSigner);
|
||||
instructions.push(cashInLimitedPrizeAuthorizationTokenInstruction);
|
||||
|
@ -787,8 +730,8 @@ export async function setupRedeemParticipationInstructions(
|
|||
const me = item.masterEdition as ParsedAccount<MasterEditionV2>;
|
||||
|
||||
// Super unfortunate but cant fit this all in one txn
|
||||
let mintingInstructions: TransactionInstruction[] = [];
|
||||
let mintingSigners: Keypair[] = [];
|
||||
const mintingInstructions: TransactionInstruction[] = [];
|
||||
const mintingSigners: Keypair[] = [];
|
||||
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
|
@ -802,7 +745,7 @@ export async function setupRedeemParticipationInstructions(
|
|||
|
||||
const fixedPrice =
|
||||
auctionView.auctionManager.participationConfig?.fixedPrice;
|
||||
let price: number =
|
||||
const price: number =
|
||||
fixedPrice !== undefined && fixedPrice !== null
|
||||
? fixedPrice.toNumber()
|
||||
: bid?.info.lastBid.toNumber() || 0;
|
||||
|
@ -838,9 +781,9 @@ export async function setupRedeemParticipationInstructions(
|
|||
instructions.push(mintingInstructions);
|
||||
signers.push(mintingSigners);
|
||||
|
||||
let myInstructions: TransactionInstruction[] = [];
|
||||
const myInstructions: TransactionInstruction[] = [];
|
||||
|
||||
let mySigners: Keypair[] = [];
|
||||
const mySigners: Keypair[] = [];
|
||||
|
||||
const transferAuthority = approve(
|
||||
myInstructions,
|
||||
|
@ -879,8 +822,9 @@ export async function setupRedeemParticipationInstructions(
|
|||
const metadata = await getMetadata(mint);
|
||||
|
||||
if (receiverWallet === wallet.publicKey.toBase58()) {
|
||||
let updatePrimarySaleHappenedInstructions: TransactionInstruction[] = [];
|
||||
let updatePrimarySaleHappenedSigners: Keypair[] = [];
|
||||
const updatePrimarySaleHappenedInstructions: TransactionInstruction[] =
|
||||
[];
|
||||
const updatePrimarySaleHappenedSigners: Keypair[] = [];
|
||||
|
||||
await updatePrimarySaleHappenedViaToken(
|
||||
metadata,
|
||||
|
@ -923,7 +867,7 @@ async function deprecatedSetupRedeemParticipationInstructions(
|
|||
return;
|
||||
|
||||
const updateAuth = item.metadata.info.updateAuthority;
|
||||
let tokenAccount = accountsByMint.get(auctionView.auction.info.tokenMint);
|
||||
const tokenAccount = accountsByMint.get(auctionView.auction.info.tokenMint);
|
||||
const mint = cache.get(auctionView.auction.info.tokenMint);
|
||||
|
||||
const participationBalance = await connection.getTokenAccountBalance(
|
||||
|
@ -938,8 +882,8 @@ async function deprecatedSetupRedeemParticipationInstructions(
|
|||
tokenBalance.value.uiAmount === 1
|
||||
) {
|
||||
// I'm the first, I need to populate for the others with a crank turn.
|
||||
let fillParticipationStashSigners: Keypair[] = [];
|
||||
let fillParticipationStashInstructions: TransactionInstruction[] = [];
|
||||
const fillParticipationStashSigners: Keypair[] = [];
|
||||
const fillParticipationStashInstructions: TransactionInstruction[] = [];
|
||||
const oneTimeTransient = createTokenAccount(
|
||||
fillParticipationStashInstructions,
|
||||
wallet.publicKey,
|
||||
|
@ -989,14 +933,14 @@ async function deprecatedSetupRedeemParticipationInstructions(
|
|||
safetyDeposit.info.order,
|
||||
)
|
||||
) {
|
||||
let winningPrizeSigner: Keypair[] = [];
|
||||
let winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
let cleanupInstructions: TransactionInstruction[] = [];
|
||||
const winningPrizeSigner: Keypair[] = [];
|
||||
const winningPrizeInstructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
if (!newTokenAccount) {
|
||||
// made a separate txn because we're over the txn limit by like 10 bytes.
|
||||
let newTokenAccountSigner: Keypair[] = [];
|
||||
let newTokenAccountInstructions: TransactionInstruction[] = [];
|
||||
const newTokenAccountSigner: Keypair[] = [];
|
||||
const newTokenAccountInstructions: TransactionInstruction[] = [];
|
||||
signers.push(newTokenAccountSigner);
|
||||
instructions.push(newTokenAccountInstructions);
|
||||
newTokenAccount = createTokenAccount(
|
||||
|
@ -1012,7 +956,7 @@ async function deprecatedSetupRedeemParticipationInstructions(
|
|||
|
||||
const fixedPrice =
|
||||
auctionView.auctionManager.participationConfig?.fixedPrice;
|
||||
let price: number =
|
||||
const price: number =
|
||||
fixedPrice !== undefined && fixedPrice !== null
|
||||
? fixedPrice.toNumber()
|
||||
: auctionView.myBidderMetadata.info.lastBid.toNumber() || 0;
|
||||
|
|
|
@ -14,8 +14,8 @@ export async function sendSignMetadata(
|
|||
) {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
await signMetadata(metadata, wallet.publicKey.toBase58(), instructions);
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ export async function setVaultAndAuctionAuthorities(
|
|||
}> {
|
||||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
let signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const signers: Keypair[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
await setAuctionAuthority(
|
||||
auction,
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
Keypair,
|
||||
Connection,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { Keypair, Connection, TransactionInstruction } from '@solana/web3.js';
|
||||
import {
|
||||
ParsedAccount,
|
||||
SequenceType,
|
||||
|
@ -42,8 +37,8 @@ export async function settle(
|
|||
auctionView.auction.info.ended() &&
|
||||
auctionView.auction.info.state !== AuctionState.Ended
|
||||
) {
|
||||
let signers: Keypair[][] = [];
|
||||
let instructions: TransactionInstruction[][] = [];
|
||||
const signers: Keypair[][] = [];
|
||||
const instructions: TransactionInstruction[][] = [];
|
||||
|
||||
await setupPlaceBid(
|
||||
connection,
|
||||
|
@ -76,15 +71,15 @@ async function emptyPaymentAccountForAllTokens(
|
|||
if (!wallet.publicKey) throw new WalletNotConnectedError();
|
||||
|
||||
const PROGRAM_IDS = programIds();
|
||||
let signers: Array<Array<Keypair[]>> = [];
|
||||
let instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
const signers: Array<Array<Keypair[]>> = [];
|
||||
const instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
|
||||
let currSignerBatch: Array<Keypair[]> = [];
|
||||
let currInstrBatch: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let settleSigners: Keypair[] = [];
|
||||
let settleInstructions: TransactionInstruction[] = [];
|
||||
let ataLookup: Record<string, boolean> = {};
|
||||
const ataLookup: Record<string, boolean> = {};
|
||||
// TODO replace all this with payer account so user doesnt need to click approve several times.
|
||||
|
||||
// Overall we have 10 parallel txns, of up to 4 settlements per txn
|
||||
|
@ -219,8 +214,8 @@ async function claimAllBids(
|
|||
auctionView: AuctionView,
|
||||
bids: ParsedAccount<BidderPot>[],
|
||||
) {
|
||||
let signers: Array<Array<Keypair[]>> = [];
|
||||
let instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
const signers: Array<Array<Keypair[]>> = [];
|
||||
const instructions: Array<Array<TransactionInstruction[]>> = [];
|
||||
|
||||
let currSignerBatch: Array<Keypair[]> = [];
|
||||
let currInstrBatch: Array<TransactionInstruction[]> = [];
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import { Connection } from '@solana/web3.js';
|
||||
import { MintLayout } from '@solana/spl-token';
|
||||
import BN from 'bn.js';
|
||||
import {
|
||||
mintNewEditionFromMasterEditionViaToken,
|
||||
StringPublicKey,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
import { createMintAndAccountWithOne } from './createMintAndAccountWithOne';
|
||||
import { Art } from '../types';
|
||||
import { WalletContextState } from '@solana/wallet-adapter-react';
|
||||
|
||||
export async function setupMintEditionIntoWalletInstructions(
|
||||
art: Art,
|
||||
wallet: WalletContextState,
|
||||
connection: Connection,
|
||||
mintTokenAccount: TokenAccount,
|
||||
edition: BN,
|
||||
instructions: any,
|
||||
signers: any,
|
||||
mintDestination: StringPublicKey,
|
||||
) {
|
||||
if (!art.mint) throw new Error('Art mint is not provided');
|
||||
if (typeof art.supply === 'undefined') {
|
||||
throw new Error('Art supply is not provided');
|
||||
}
|
||||
if (!wallet.publicKey) throw new Error('Wallet pubKey is not provided');
|
||||
if (!mintTokenAccount) {
|
||||
throw new Error('Art mint token account is not provided');
|
||||
}
|
||||
const walletPubKey = wallet.publicKey.toString();
|
||||
const { mint: tokenMint } = art;
|
||||
const { pubkey: mintTokenAccountPubKey } = mintTokenAccount;
|
||||
const mintTokenAccountOwner = mintTokenAccount.info.owner.toString();
|
||||
|
||||
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
MintLayout.span,
|
||||
);
|
||||
const { mint: newMint } = await createMintAndAccountWithOne(
|
||||
wallet,
|
||||
mintDestination,
|
||||
mintRentExempt,
|
||||
instructions,
|
||||
signers,
|
||||
);
|
||||
|
||||
await mintNewEditionFromMasterEditionViaToken(
|
||||
newMint,
|
||||
tokenMint,
|
||||
walletPubKey,
|
||||
walletPubKey,
|
||||
mintTokenAccountOwner,
|
||||
mintTokenAccountPubKey,
|
||||
instructions,
|
||||
walletPubKey,
|
||||
edition,
|
||||
);
|
||||
}
|
|
@ -10,7 +10,7 @@ export async function startAuctionManually(
|
|||
) {
|
||||
try {
|
||||
const signers: Keypair[] = [];
|
||||
let instructions: TransactionInstruction[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
await startAuction(
|
||||
auctionView.vault.pubkey,
|
||||
|
|
|
@ -34,8 +34,8 @@ export async function unwindVault(
|
|||
|
||||
let batchCounter = 0;
|
||||
const PROGRAM_IDS = programIds();
|
||||
let signers: Array<Keypair[]> = [];
|
||||
let instructions: Array<TransactionInstruction[]> = [];
|
||||
const signers: Array<Keypair[]> = [];
|
||||
const instructions: Array<TransactionInstruction[]> = [];
|
||||
|
||||
let currSigners: Keypair[] = [];
|
||||
let currInstructions: TransactionInstruction[] = [];
|
||||
|
@ -48,7 +48,7 @@ export async function unwindVault(
|
|||
if (epa) {
|
||||
const decoded = decodeExternalPriceAccount(epa.data);
|
||||
// "Closing" it here actually brings it to Combined state which means we can withdraw tokens.
|
||||
let { instructions: cvInstructions, signers: cvSigners } =
|
||||
const { instructions: cvInstructions, signers: cvSigners } =
|
||||
await closeVault(
|
||||
connection,
|
||||
wallet,
|
||||
|
@ -66,7 +66,7 @@ export async function unwindVault(
|
|||
}
|
||||
|
||||
const vaultKey = vault.pubkey;
|
||||
let boxes: ParsedAccount<SafetyDepositBox>[] = [];
|
||||
const boxes: ParsedAccount<SafetyDepositBox>[] = [];
|
||||
|
||||
let box = safetyDepositBoxesByVaultAndIndex[vaultKey + '-0'];
|
||||
if (box) {
|
||||
|
@ -80,7 +80,7 @@ export async function unwindVault(
|
|||
}
|
||||
console.log('Found boxes', boxes);
|
||||
for (let i = 0; i < boxes.length; i++) {
|
||||
let nft = boxes[i];
|
||||
const nft = boxes[i];
|
||||
const ata = (
|
||||
await findProgramAddress(
|
||||
[
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
import React, { useState, useMemo, useCallback, useEffect } from 'react';
|
||||
import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js';
|
||||
import { MintLayout, AccountLayout } from '@solana/spl-token';
|
||||
import { Button, Form, Input, Modal, InputNumber } from 'antd';
|
||||
import debounce from 'lodash/debounce';
|
||||
import {
|
||||
decodeMasterEdition,
|
||||
MAX_EDITION_LEN,
|
||||
MAX_METADATA_LEN,
|
||||
MetadataKey,
|
||||
MetaplexOverlay,
|
||||
useConnection,
|
||||
useUserAccounts,
|
||||
} from '@oyster/common';
|
||||
import { useArt } from '../../hooks';
|
||||
import { mintEditionsToWallet } from '../../actions/mintEditionsIntoWallet';
|
||||
import { ArtType } from '../../types';
|
||||
import { Confetti } from '../Confetti';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useWallet } from '@solana/wallet-adapter-react';
|
||||
|
||||
interface ArtMintingProps {
|
||||
id: string;
|
||||
onMint: Function;
|
||||
}
|
||||
|
||||
export const ArtMinting = ({ id, onMint }: ArtMintingProps) => {
|
||||
const wallet = useWallet();
|
||||
const connection = useConnection();
|
||||
const { accountByMint } = useUserAccounts();
|
||||
const [showMintModal, setShowMintModal] = useState<boolean>(false);
|
||||
const [showCongrats, setShowCongrats] = useState<boolean>(false);
|
||||
const [mintingDestination, setMintingDestination] = useState<string>('');
|
||||
const [editions, setEditions] = useState<number>(1);
|
||||
const [totalCost, setTotalCost] = useState<number>(0);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const art = useArt(id);
|
||||
|
||||
const walletPubKey = wallet?.publicKey?.toString() || '';
|
||||
const maxEditionsToMint = art.maxSupply! - art.supply!;
|
||||
const isArtMasterEdition = art.type === ArtType.Master;
|
||||
const artMintTokenAccount = accountByMint.get(art.mint!);
|
||||
const isArtOwnedByUser =
|
||||
((accountByMint.has(art.mint!) &&
|
||||
artMintTokenAccount?.info.amount.toNumber()) ||
|
||||
0) > 0;
|
||||
const isMasterEditionV1 = artMintTokenAccount
|
||||
? decodeMasterEdition(artMintTokenAccount.account.data).key ===
|
||||
MetadataKey.MasterEditionV1
|
||||
: false;
|
||||
const renderMintEdition =
|
||||
isArtMasterEdition &&
|
||||
isArtOwnedByUser &&
|
||||
!isMasterEditionV1 &&
|
||||
maxEditionsToMint !== 0;
|
||||
|
||||
const mintingDestinationErr = useMemo(() => {
|
||||
if (!mintingDestination) return 'Required';
|
||||
|
||||
try {
|
||||
new PublicKey(mintingDestination);
|
||||
return '';
|
||||
} catch (e) {
|
||||
return 'Invalid address format';
|
||||
}
|
||||
}, [mintingDestination]);
|
||||
|
||||
const isMintingDisabled =
|
||||
isLoading || editions < 1 || Boolean(mintingDestinationErr);
|
||||
|
||||
const debouncedEditionsChangeHandler = useCallback(
|
||||
debounce(val => {
|
||||
setEditions(val < 1 ? 1 : val);
|
||||
}, 300),
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (editions < 1) return;
|
||||
|
||||
(async () => {
|
||||
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
MintLayout.span,
|
||||
);
|
||||
const accountRentExempt =
|
||||
await connection.getMinimumBalanceForRentExemption(AccountLayout.span);
|
||||
const metadataRentExempt =
|
||||
await connection.getMinimumBalanceForRentExemption(MAX_METADATA_LEN);
|
||||
const editionRentExempt =
|
||||
await connection.getMinimumBalanceForRentExemption(MAX_EDITION_LEN);
|
||||
|
||||
const cost =
|
||||
((mintRentExempt +
|
||||
accountRentExempt +
|
||||
metadataRentExempt +
|
||||
editionRentExempt) *
|
||||
editions) /
|
||||
LAMPORTS_PER_SOL;
|
||||
|
||||
setTotalCost(cost);
|
||||
})();
|
||||
}, [connection, editions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!walletPubKey) return;
|
||||
|
||||
setMintingDestination(walletPubKey);
|
||||
}, [walletPubKey]);
|
||||
|
||||
useEffect(() => {
|
||||
return debouncedEditionsChangeHandler.cancel();
|
||||
}, []);
|
||||
|
||||
const onSuccessfulMint = () => {
|
||||
setShowMintModal(false);
|
||||
setMintingDestination(walletPubKey);
|
||||
setEditions(1);
|
||||
setShowCongrats(true);
|
||||
};
|
||||
|
||||
const mint = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await mintEditionsToWallet(
|
||||
art,
|
||||
wallet!,
|
||||
connection,
|
||||
artMintTokenAccount!,
|
||||
editions,
|
||||
mintingDestination,
|
||||
);
|
||||
onSuccessfulMint();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderMintEdition && (
|
||||
<div>
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
className="action-btn"
|
||||
style={{ marginTop: 20 }}
|
||||
onClick={() => setShowMintModal(true)}
|
||||
>
|
||||
Mint
|
||||
</Button>
|
||||
|
||||
<Modal
|
||||
visible={showMintModal}
|
||||
centered
|
||||
okText="Mint"
|
||||
closable={!isLoading}
|
||||
okButtonProps={{
|
||||
disabled: isMintingDisabled,
|
||||
}}
|
||||
cancelButtonProps={{ disabled: isLoading }}
|
||||
onOk={mint}
|
||||
onCancel={() => setShowMintModal(false)}
|
||||
>
|
||||
<Form.Item
|
||||
style={{
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
paddingTop: 30,
|
||||
marginBottom: 4,
|
||||
}}
|
||||
label={<h3>Mint to</h3>}
|
||||
labelAlign="left"
|
||||
colon={false}
|
||||
validateStatus={mintingDestinationErr ? 'error' : 'success'}
|
||||
help={mintingDestinationErr}
|
||||
>
|
||||
<Input
|
||||
placeholder="Address to mint edition to"
|
||||
value={mintingDestination}
|
||||
onChange={e => {
|
||||
setMintingDestination(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
paddingTop: 30,
|
||||
}}
|
||||
label={<h3>Number of editions to mint</h3>}
|
||||
labelAlign="left"
|
||||
colon={false}
|
||||
>
|
||||
<InputNumber
|
||||
type="number"
|
||||
placeholder="1"
|
||||
style={{ width: '100%' }}
|
||||
min={1}
|
||||
max={maxEditionsToMint}
|
||||
value={editions}
|
||||
precision={0}
|
||||
onChange={debouncedEditionsChangeHandler}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<div>Total cost: {`◎${totalCost}`}</div>
|
||||
</Modal>
|
||||
|
||||
<MetaplexOverlay visible={showCongrats}>
|
||||
<Confetti />
|
||||
<h1
|
||||
className="title"
|
||||
style={{
|
||||
fontSize: '3rem',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
Congratulations
|
||||
</h1>
|
||||
<p
|
||||
style={{
|
||||
color: 'white',
|
||||
textAlign: 'center',
|
||||
fontSize: '2rem',
|
||||
}}
|
||||
>
|
||||
New editions have been minted please view your NFTs in{' '}
|
||||
<Link to="/artworks">My Items</Link>.
|
||||
</p>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await onMint();
|
||||
setShowCongrats(false);
|
||||
}}
|
||||
className="overlay-btn"
|
||||
>
|
||||
Got it
|
||||
</Button>
|
||||
</MetaplexOverlay>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -12,12 +12,19 @@ export function MeshViewer(props: MeshViewerProps) {
|
|||
return (
|
||||
// @ts-ignore
|
||||
<model-viewer
|
||||
style={{ width: `100%`, height: `100%`, minHeight: 400, minWidth: 400, maxHeight: 400, ...props.style }}
|
||||
style={{
|
||||
width: `100%`,
|
||||
height: `100%`,
|
||||
minHeight: 400,
|
||||
minWidth: 400,
|
||||
maxHeight: 400,
|
||||
...props.style,
|
||||
}}
|
||||
src={props.url}
|
||||
auto-rotate
|
||||
rotation-per-second="40deg"
|
||||
className={props.className}
|
||||
camera-controls
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,14 +34,14 @@ async function getProgramAccounts(
|
|||
): Promise<Array<AccountAndPubkey>> {
|
||||
const extra: any = {};
|
||||
let commitment;
|
||||
let encoding;
|
||||
//let encoding;
|
||||
|
||||
if (configOrCommitment) {
|
||||
if (typeof configOrCommitment === 'string') {
|
||||
commitment = configOrCommitment;
|
||||
} else {
|
||||
commitment = configOrCommitment.commitment;
|
||||
encoding = configOrCommitment.encoding;
|
||||
//encoding = configOrCommitment.encoding;
|
||||
|
||||
if (configOrCommitment.dataSlice) {
|
||||
extra.dataSlice = configOrCommitment.dataSlice;
|
||||
|
@ -124,7 +124,6 @@ export const loadAccounts = async (connection: Connection, all: boolean) => {
|
|||
const promises = [
|
||||
getProgramAccounts(connection, VAULT_ID).then(forEach(processVaultData)),
|
||||
getProgramAccounts(connection, AUCTION_ID).then(forEach(processAuctions)),
|
||||
,
|
||||
getProgramAccounts(connection, METAPLEX_ID).then(
|
||||
forEach(processMetaplexAccounts),
|
||||
),
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
MasterEditionV2,
|
||||
PublicKeyStringAndAccount,
|
||||
} from '@oyster/common';
|
||||
import { AccountInfo, PublicKey } from '@solana/web3.js';
|
||||
import { AccountInfo } from '@solana/web3.js';
|
||||
import {
|
||||
BidRedemptionTicket,
|
||||
Store,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useMeta } from '../contexts';
|
||||
import { Art, Artist, ArtType } from '../types';
|
||||
import {
|
||||
|
|
|
@ -307,13 +307,13 @@ export function processAccountsIntoAuctionView(
|
|||
const vault = vaults[auctionManagerInstance.info.vault];
|
||||
const auctionManagerKey = auctionManagerInstance.pubkey;
|
||||
|
||||
let safetyDepositConfigs: ParsedAccount<SafetyDepositConfig>[] =
|
||||
const safetyDepositConfigs: ParsedAccount<SafetyDepositConfig>[] =
|
||||
buildListWhileNonZero(
|
||||
safetyDepositConfigsByAuctionManagerAndIndex,
|
||||
auctionManagerKey,
|
||||
);
|
||||
|
||||
let bidRedemptions: ParsedAccount<BidRedemptionTicketV2>[] =
|
||||
const bidRedemptions: ParsedAccount<BidRedemptionTicketV2>[] =
|
||||
buildListWhileNonZero(
|
||||
bidRedemptionV2sByAuctionManagerAndWinningIndex,
|
||||
auctionManagerKey,
|
||||
|
@ -337,7 +337,7 @@ export function processAccountsIntoAuctionView(
|
|||
|
||||
const boxesExpected = auctionManager.safetyDepositBoxesExpected.toNumber();
|
||||
|
||||
let bidRedemption: ParsedAccount<BidRedemptionTicket> | undefined =
|
||||
const bidRedemption: ParsedAccount<BidRedemptionTicket> | undefined =
|
||||
cachedRedemptionKeysByWallet[auction.pubkey]?.info
|
||||
? (cachedRedemptionKeysByWallet[
|
||||
auction.pubkey
|
||||
|
@ -370,7 +370,7 @@ export function processAccountsIntoAuctionView(
|
|||
metadataByMint[curr.safetyDeposit.info.tokenMint];
|
||||
if (!foundMetadata) {
|
||||
// Means is a limited edition, so the tokenMint is the printingMint
|
||||
let masterEdition =
|
||||
const masterEdition =
|
||||
masterEditionsByPrintingMint[curr.safetyDeposit.info.tokenMint];
|
||||
if (masterEdition) {
|
||||
foundMetadata = metadataByMasterEdition[masterEdition.pubkey];
|
||||
|
@ -384,7 +384,8 @@ export function processAccountsIntoAuctionView(
|
|||
!curr.masterEdition &&
|
||||
curr.metadata.info.masterEdition
|
||||
) {
|
||||
let foundMaster = masterEditions[curr.metadata.info.masterEdition];
|
||||
const foundMaster =
|
||||
masterEditions[curr.metadata.info.masterEdition];
|
||||
|
||||
curr.masterEdition = foundMaster;
|
||||
}
|
||||
|
@ -395,7 +396,7 @@ export function processAccountsIntoAuctionView(
|
|||
}
|
||||
|
||||
const vaultKey = auctionManager.vault;
|
||||
let boxes: ParsedAccount<SafetyDepositBox>[] = buildListWhileNonZero(
|
||||
const boxes: ParsedAccount<SafetyDepositBox>[] = buildListWhileNonZero(
|
||||
safetyDepositBoxesByVaultAndIndex,
|
||||
vaultKey,
|
||||
);
|
||||
|
@ -428,7 +429,7 @@ export function processAccountsIntoAuctionView(
|
|||
}
|
||||
}
|
||||
|
||||
let view: Partial<AuctionView> = {
|
||||
const view: Partial<AuctionView> = {
|
||||
auction,
|
||||
auctionManager,
|
||||
state,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
BidderMetadata,
|
||||
BidderMetadataParser,
|
||||
|
|
|
@ -38,10 +38,10 @@ export const useUserArts = (): SafetyDepositDraft[] => {
|
|||
m.info.masterEdition ? masterEditions[m.info.masterEdition] : undefined,
|
||||
);
|
||||
|
||||
let safetyDeposits: SafetyDepositDraft[] = [];
|
||||
const safetyDeposits: SafetyDepositDraft[] = [];
|
||||
let i = 0;
|
||||
ownedMetadata.forEach(m => {
|
||||
let a = accountByMint.get(m.info.mint);
|
||||
const a = accountByMint.get(m.info.mint);
|
||||
let masterA;
|
||||
const masterEdition = possibleMasterEditions[i];
|
||||
if (masterEdition?.info.key == MetadataKey.MasterEditionV1) {
|
||||
|
|
|
@ -156,7 +156,7 @@ export class BidRedemptionTicketV1 implements BidRedemptionTicket {
|
|||
Object.assign(this, args);
|
||||
}
|
||||
|
||||
getBidRedeemed(order: number): boolean {
|
||||
getBidRedeemed(): boolean {
|
||||
return this.participationRedeemed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
Vault,
|
||||
Metadata,
|
||||
MasterEditionV1,
|
||||
MetadataKey,
|
||||
SafetyDepositBox,
|
||||
MasterEditionV2,
|
||||
toPublicKey,
|
||||
|
@ -207,7 +206,7 @@ export class AuctionManager {
|
|||
metadataByMint[boxes[it.safetyDepositBoxIndex]?.info.tokenMint];
|
||||
if (!metadata) {
|
||||
// Means is a limited edition v1, so the tokenMint is the printingMint
|
||||
let masterEdition =
|
||||
const masterEdition =
|
||||
masterEditionsByPrintingMint[
|
||||
boxes[it.safetyDepositBoxIndex]?.info.tokenMint
|
||||
];
|
||||
|
@ -664,7 +663,7 @@ export class SafetyDepositConfig {
|
|||
this.winningConfigType = args.data[41];
|
||||
this.amountType = args.data[42];
|
||||
this.lengthType = args.data[43];
|
||||
let lengthOfArray = new BN(args.data.slice(44, 48), 'le');
|
||||
const lengthOfArray = new BN(args.data.slice(44, 48), 'le');
|
||||
this.amountRanges = [];
|
||||
let offset = 48;
|
||||
for (let i = 0; i < lengthOfArray.toNumber(); i++) {
|
||||
|
@ -735,7 +734,7 @@ export class SafetyDepositConfig {
|
|||
getAmountForWinner(winner: BN): BN {
|
||||
let start = new BN(0);
|
||||
for (let i = 0; i < this.amountRanges.length; i++) {
|
||||
let end = start.add(this.amountRanges[i].length);
|
||||
const end = start.add(this.amountRanges[i].length);
|
||||
if (winner.gte(start) && winner.lt(end)) {
|
||||
return this.amountRanges[i].amount;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const CreateReactAppEntryPoint = dynamic(() => import('../App'), {
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
import {
|
||||
getTokenName,
|
||||
getVerboseTokenName,
|
||||
KnownTokenMap,
|
||||
} from '@oyster/common';
|
||||
import { TokenInfo } from '@solana/spl-token-registry';
|
||||
|
||||
export const LAMPORT_MULTIPLIER = 10 ** 9;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Layout,
|
||||
Row,
|
||||
|
@ -21,7 +21,8 @@ import {
|
|||
StringPublicKey,
|
||||
useConnection,
|
||||
useStore,
|
||||
useUserAccounts, useWalletModal,
|
||||
useUserAccounts,
|
||||
useWalletModal,
|
||||
WalletSigner,
|
||||
} from '@oyster/common';
|
||||
import { useWallet } from '@solana/wallet-adapter-react';
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
import React from 'react';
|
||||
import { Row, Col, Divider, Layout, Tag, Button, Skeleton, List, Card } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Divider,
|
||||
Layout,
|
||||
Tag,
|
||||
Button,
|
||||
Skeleton,
|
||||
List,
|
||||
Card,
|
||||
} from 'antd';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useArt, useExtendedArt } from './../../hooks';
|
||||
import { useArt, useExtendedArt } from '../../hooks';
|
||||
|
||||
import { ArtContent } from '../../components/ArtContent';
|
||||
import { shortenAddress, useConnection } from '@oyster/common';
|
||||
import { useWallet } from '@solana/wallet-adapter-react';
|
||||
import { MetaAvatar } from '../../components/MetaAvatar';
|
||||
import { sendSignMetadata } from '../../actions/sendSignMetadata';
|
||||
import { ViewOn } from './../../components/ViewOn';
|
||||
import { ViewOn } from '../../components/ViewOn';
|
||||
import { ArtType } from '../../types';
|
||||
import { ArtMinting } from '../../components/ArtMinting';
|
||||
|
||||
const { Content } = Layout;
|
||||
|
||||
export const ArtView = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const wallet = useWallet();
|
||||
const [remountArtMinting, setRemountArtMinting] = useState(0);
|
||||
|
||||
const connection = useConnection();
|
||||
const art = useArt(id);
|
||||
|
@ -39,7 +51,7 @@ export const ArtView = () => {
|
|||
const description = data?.description;
|
||||
const attributes = data?.attributes;
|
||||
|
||||
const pubkey = wallet.publicKey?.toBase58() || '';
|
||||
const pubkey = wallet?.publicKey?.toBase58() || '';
|
||||
|
||||
const tag = (
|
||||
<div className="info-header">
|
||||
|
@ -181,6 +193,13 @@ export const ArtView = () => {
|
|||
>
|
||||
Mark as Sold
|
||||
</Button> */}
|
||||
|
||||
{/* TODO: Add conversion of MasterEditionV1 to MasterEditionV2 */}
|
||||
<ArtMinting
|
||||
id={id}
|
||||
key={remountArtMinting}
|
||||
onMint={async () => await setRemountArtMinting(prev => prev + 1)}
|
||||
/>
|
||||
</Col>
|
||||
<Col span="12">
|
||||
<Divider />
|
||||
|
@ -197,23 +216,22 @@ export const ArtView = () => {
|
|||
<div className="info-content">{art.about}</div> */}
|
||||
</Col>
|
||||
<Col span="12">
|
||||
{attributes &&
|
||||
{attributes && (
|
||||
<>
|
||||
<Divider />
|
||||
<br />
|
||||
<div className="info-header">Attributes</div>
|
||||
<List
|
||||
size="large"
|
||||
grid={{ column: 4 }}
|
||||
>
|
||||
{attributes.map(attribute =>
|
||||
<List size="large" grid={{ column: 4 }}>
|
||||
{attributes.map(attribute => (
|
||||
<List.Item>
|
||||
<Card title={attribute.trait_type}>{attribute.value}</Card>
|
||||
<Card title={attribute.trait_type}>
|
||||
{attribute.value}
|
||||
</Card>
|
||||
</List.Item>
|
||||
)}
|
||||
))}
|
||||
</List>
|
||||
</>
|
||||
}
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
|
|
|
@ -159,22 +159,20 @@ export const AuctionView = () => {
|
|||
No description provided.
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
|
||||
{attributes &&
|
||||
{attributes && (
|
||||
<>
|
||||
<h6>Attributes</h6>
|
||||
<List
|
||||
grid={{ column: 4 }}
|
||||
>
|
||||
{attributes.map(attribute =>
|
||||
<List grid={{ column: 4 }}>
|
||||
{attributes.map(attribute => (
|
||||
<List.Item>
|
||||
<Card title={attribute.trait_type}>{attribute.value}</Card>
|
||||
</List.Item>
|
||||
)}
|
||||
))}
|
||||
</List>
|
||||
</>}
|
||||
</>
|
||||
)}
|
||||
{/* {auctionData[id] && (
|
||||
<>
|
||||
<h6>About this Auction</h6>
|
||||
|
|
|
@ -83,8 +83,7 @@ export const AuctionListView = () => {
|
|||
.concat(auctionsEnded)
|
||||
.filter(
|
||||
(m, idx) =>
|
||||
m.myBidderMetadata?.info.bidderPubkey ==
|
||||
publicKey?.toBase58(),
|
||||
m.myBidderMetadata?.info.bidderPubkey == publicKey?.toBase58(),
|
||||
);
|
||||
break;
|
||||
case LiveAuctionViewState.Resale:
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { useConnection, useStore, useWalletModal, WalletSigner } from '@oyster/common';
|
||||
import {
|
||||
useConnection,
|
||||
useStore,
|
||||
useWalletModal,
|
||||
WalletSigner,
|
||||
} from '@oyster/common';
|
||||
import { useWallet } from '@solana/wallet-adapter-react';
|
||||
import { Button } from 'antd';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
|
166
js/yarn.lock
166
js/yarn.lock
|
@ -2211,26 +2211,6 @@
|
|||
superstruct "^0.14.2"
|
||||
tweetnacl "^1.0.0"
|
||||
|
||||
"@solana/web3.js@^1.24.1":
|
||||
version "1.24.1"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.24.1.tgz#1fb29f344454669183206f452ab3b8792567cade"
|
||||
integrity sha512-XImMWAvjcXteMQwe1FFjoe6u72xmcu+UYobPIxLEMX29XXWVTalyYRKBXvcOXwz6DliTYnFXmncNEwUDEFFHGg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@solana/buffer-layout" "^3.0.0"
|
||||
bn.js "^5.0.0"
|
||||
borsh "^0.4.0"
|
||||
bs58 "^4.0.1"
|
||||
buffer "6.0.1"
|
||||
crypto-hash "^1.2.2"
|
||||
jayson "^3.4.4"
|
||||
js-sha3 "^0.8.0"
|
||||
node-fetch "^2.6.1"
|
||||
rpc-websockets "^7.4.2"
|
||||
secp256k1 "^4.0.2"
|
||||
superstruct "^0.14.2"
|
||||
tweetnacl "^1.0.0"
|
||||
|
||||
"@testing-library/dom@*", "@testing-library/dom@^7.28.1":
|
||||
version "7.31.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.31.0.tgz#938451abd3ca27e1b69bb395d4a40759fd7f5b3b"
|
||||
|
@ -3438,6 +3418,17 @@ array-ify@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
|
||||
integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=
|
||||
|
||||
array-includes@^3.1.2, array-includes@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a"
|
||||
integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.2"
|
||||
get-intrinsic "^1.1.1"
|
||||
is-string "^1.0.5"
|
||||
|
||||
array-tree-filter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190"
|
||||
|
@ -3465,6 +3456,16 @@ array-unique@^0.3.2:
|
|||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
|
||||
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
|
||||
|
||||
array.prototype.flatmap@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9"
|
||||
integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==
|
||||
dependencies:
|
||||
call-bind "^1.0.0"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.1"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
arrify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||
|
@ -6067,6 +6068,13 @@ dns-txt@^2.0.2:
|
|||
dependencies:
|
||||
buffer-indexof "^1.0.0"
|
||||
|
||||
doctrine@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
||||
integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
doctrine@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
|
@ -6333,6 +6341,29 @@ es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2:
|
|||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-abstract@^1.18.2:
|
||||
version "1.18.5"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19"
|
||||
integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.2"
|
||||
internal-slot "^1.0.3"
|
||||
is-callable "^1.2.3"
|
||||
is-negative-zero "^2.0.1"
|
||||
is-regex "^1.1.3"
|
||||
is-string "^1.0.6"
|
||||
object-inspect "^1.11.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.2"
|
||||
string.prototype.trimend "^1.0.4"
|
||||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
|
@ -6436,6 +6467,25 @@ eslint-config-prettier@^6.15.0:
|
|||
dependencies:
|
||||
get-stdin "^6.0.0"
|
||||
|
||||
eslint-plugin-react@^7.25.1:
|
||||
version "7.25.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.25.1.tgz#9286b7cd9bf917d40309760f403e53016eda8331"
|
||||
integrity sha512-P4j9K1dHoFXxDNP05AtixcJEvIT6ht8FhYKsrkY0MPCPaUMYijhpWwNiRDZVtA8KFuZOkGSeft6QwH8KuVpJug==
|
||||
dependencies:
|
||||
array-includes "^3.1.3"
|
||||
array.prototype.flatmap "^1.2.4"
|
||||
doctrine "^2.1.0"
|
||||
estraverse "^5.2.0"
|
||||
has "^1.0.3"
|
||||
jsx-ast-utils "^2.4.1 || ^3.0.0"
|
||||
minimatch "^3.0.4"
|
||||
object.entries "^1.1.4"
|
||||
object.fromentries "^2.0.4"
|
||||
object.values "^1.1.4"
|
||||
prop-types "^15.7.2"
|
||||
resolve "^2.0.0-next.3"
|
||||
string.prototype.matchall "^4.0.5"
|
||||
|
||||
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
|
@ -7701,7 +7751,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
|||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1:
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
||||
integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
|
||||
|
@ -8535,6 +8585,15 @@ internal-ip@^4.3.0:
|
|||
default-gateway "^4.2.0"
|
||||
ipaddr.js "^1.9.0"
|
||||
|
||||
internal-slot@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
|
||||
integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.0"
|
||||
has "^1.0.3"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
interpret@^1.0.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
||||
|
@ -9677,6 +9736,14 @@ jsprim@^1.2.2:
|
|||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
"jsx-ast-utils@^2.4.1 || ^3.0.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82"
|
||||
integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==
|
||||
dependencies:
|
||||
array-includes "^3.1.2"
|
||||
object.assign "^4.1.2"
|
||||
|
||||
keccak256@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/keccak256/-/keccak256-1.0.2.tgz#ee0d38c2d5fb817f39d37c3fef842cab0164a067"
|
||||
|
@ -11179,6 +11246,11 @@ object-inspect@^1.10.3, object-inspect@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
|
||||
integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==
|
||||
|
||||
object-inspect@^1.11.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
|
||||
integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==
|
||||
|
||||
object-inspect@~1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
|
||||
|
@ -11219,6 +11291,25 @@ object.assign@^4.1.2:
|
|||
has-symbols "^1.0.1"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
object.entries@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd"
|
||||
integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.2"
|
||||
|
||||
object.fromentries@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8"
|
||||
integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.0-next.2"
|
||||
has "^1.0.3"
|
||||
|
||||
object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7"
|
||||
|
@ -11235,6 +11326,15 @@ object.pick@^1.3.0:
|
|||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
object.values@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30"
|
||||
integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.2"
|
||||
|
||||
oboe@2.1.4:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6"
|
||||
|
@ -13015,7 +13115,7 @@ regex-not@^1.0.0, regex-not@^1.0.2:
|
|||
extend-shallow "^3.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
regexp.prototype.flags@^1.2.0:
|
||||
regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
|
||||
integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==
|
||||
|
@ -13190,6 +13290,14 @@ resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0:
|
|||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^2.0.0-next.3:
|
||||
version "2.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
|
||||
integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@~1.17.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||
|
@ -14208,6 +14316,20 @@ string-width@^4.1.0, string-width@^4.2.0:
|
|||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string.prototype.matchall@^4.0.5:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da"
|
||||
integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.18.2"
|
||||
get-intrinsic "^1.1.1"
|
||||
has-symbols "^1.0.2"
|
||||
internal-slot "^1.0.3"
|
||||
regexp.prototype.flags "^1.3.1"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
string.prototype.padend@^3.0.0:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz#6858ca4f35c5268ebd5e8615e1327d55f59ee311"
|
||||
|
|
|
@ -3,7 +3,10 @@ url = "https://anchor.projectserum.com"
|
|||
|
||||
[provider]
|
||||
cluster = "localnet"
|
||||
wallet = "/Users/jprince/.config/solana/id.json"
|
||||
wallet = "~/.config/solana/id.json"
|
||||
|
||||
[programs.mainnet]
|
||||
nft_candy_machine = "cndyAnrLdpjq1Ssp1z8xxDsB8dxe7u4HL5Nxi2K5WXZ"
|
||||
|
||||
[scripts]
|
||||
test = "mocha -t 1000000 tests/"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,8 +15,7 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = "0.13.2"
|
||||
anchor-lang = "0.14.0"
|
||||
arrayref = "0.3.6"
|
||||
spl-token = { version="3.1.1", features = [ "no-entrypoint" ] }
|
||||
spl-token-metadata = { path = "../token-metadata/program", features = [ "no-entrypoint" ] }
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ pub mod nft_candy_machine {
|
|||
for c in &config.data.creators {
|
||||
creators.push(spl_token_metadata::state::Creator {
|
||||
address: c.address,
|
||||
verified: false,
|
||||
verified: true,
|
||||
share: c.share,
|
||||
});
|
||||
}
|
||||
|
@ -351,6 +351,7 @@ pub mod nft_candy_machine {
|
|||
position_from_right
|
||||
);
|
||||
if old_value_in_vec != data[my_position_in_vec] {
|
||||
msg!("Increasing count");
|
||||
new_count = new_count
|
||||
.checked_add(1)
|
||||
.ok_or(ErrorCode::NumericalOverflowError)?;
|
||||
|
@ -395,7 +396,7 @@ pub mod nft_candy_machine {
|
|||
}
|
||||
|
||||
if get_config_count(&ctx.accounts.config.to_account_info().data.borrow())?
|
||||
!= candy_machine.data.items_available as usize
|
||||
< candy_machine.data.items_available as usize
|
||||
{
|
||||
return Err(ErrorCode::ConfigLineMismatch.into());
|
||||
}
|
||||
|
@ -430,7 +431,7 @@ pub struct InitializeCandyMachine<'info> {
|
|||
#[derive(Accounts)]
|
||||
#[instruction(data: ConfigData)]
|
||||
pub struct InitializeConfig<'info> {
|
||||
#[account(mut, constraint= config.to_account_info().owner == program_id && config.to_account_info().data_len() > CONFIG_ARRAY_START+4+(data.max_number_of_lines as usize)*CONFIG_LINE_SIZE + 4 + (data.max_number_of_lines.checked_div(8).ok_or(ErrorCode::NumericalOverflowError)? as usize))]
|
||||
#[account(mut, constraint= config.to_account_info().owner == program_id && config.to_account_info().data_len() >= CONFIG_ARRAY_START+4+(data.max_number_of_lines as usize)*CONFIG_LINE_SIZE + 4 + (data.max_number_of_lines.checked_div(8).ok_or(ErrorCode::NumericalOverflowError)? as usize))]
|
||||
config: AccountInfo<'info>,
|
||||
#[account(constraint= authority.data_is_empty() && authority.lamports() > 0 )]
|
||||
authority: AccountInfo<'info>,
|
||||
|
@ -450,7 +451,13 @@ pub struct AddConfigLines<'info> {
|
|||
#[derive(Accounts)]
|
||||
pub struct MintNFT<'info> {
|
||||
config: ProgramAccount<'info, Config>,
|
||||
#[account(mut, has_one = config, has_one = wallet, seeds=[PREFIX.as_bytes(), config.key().as_ref(), candy_machine.data.uuid.as_bytes(), &[candy_machine.bump]])]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = config,
|
||||
has_one = wallet,
|
||||
seeds = [PREFIX.as_bytes(), config.key().as_ref(), candy_machine.data.uuid.as_bytes()],
|
||||
bump = candy_machine.bump,
|
||||
)]
|
||||
candy_machine: ProgramAccount<'info, CandyMachine>,
|
||||
#[account(mut, signer)]
|
||||
payer: AccountInfo<'info>,
|
||||
|
@ -480,7 +487,12 @@ pub struct MintNFT<'info> {
|
|||
|
||||
#[derive(Accounts)]
|
||||
pub struct UpdateCandyMachine<'info> {
|
||||
#[account(mut, has_one=authority, seeds=[PREFIX.as_bytes(), candy_machine.config.key().as_ref(), candy_machine.data.uuid.as_bytes(), &[candy_machine.bump]])]
|
||||
#[account(
|
||||
mut,
|
||||
has_one = authority,
|
||||
seeds = [PREFIX.as_bytes(), candy_machine.config.key().as_ref(), candy_machine.data.uuid.as_bytes()],
|
||||
bump = candy_machine.bump
|
||||
)]
|
||||
candy_machine: ProgramAccount<'info, CandyMachine>,
|
||||
#[account(signer)]
|
||||
authority: AccountInfo<'info>,
|
||||
|
@ -610,6 +622,6 @@ pub enum ErrorCode {
|
|||
CandyMachineEmpty,
|
||||
#[msg("Candy machine is not live yet!")]
|
||||
CandyMachineNotLiveYet,
|
||||
#[msg("Number of config lines must match items available")]
|
||||
#[msg("Number of config lines must be at least number of items available")]
|
||||
ConfigLineMismatch,
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ The Token Metadata Program's source is available on
|
|||
[github](https://github.com/metaplex-foundation/metaplex)
|
||||
|
||||
There is also an example Rust client located at
|
||||
[github](https://github.com/metaplex-foundation/metaplex/tree/master/token_metadata/test/src/main.rs)
|
||||
[github](https://github.com/metaplex-foundation/metaplex/tree/master/rust/token-metadata/test/src/main.rs)
|
||||
that can be perused for learning and run if desired with `cargo run --bin spl-token-metadata-test-client`. It allows testing out a variety of scenarios.
|
||||
|
||||
## Interface
|
||||
|
|
Loading…
Reference in New Issue