Skip to content

Commit

Permalink
feat: create vault + test (#82)
Browse files Browse the repository at this point in the history
feat: fixup

Co-authored-by: Valentine Panchin <vpanchyn@markerr.com>
  • Loading branch information
b2kdaman and Valentine Panchin committed Nov 30, 2021
1 parent f1ccb0a commit c9d5524
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
125 changes: 125 additions & 0 deletions src/actions/createVault.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Connection } from '../Connection';
import { Wallet } from '../wallet';

import { InitVault, Vault, VaultProgram } from '../programs/vault';
import { Keypair, PublicKey, SystemProgram } from '@solana/web3.js';
import { AccountLayout, MintLayout, NATIVE_MINT } from '@solana/spl-token';
import { CreateMint, CreateTokenAccount, Transaction } from '../programs';
import { sendTransaction } from '.';
import { TransactionsBatch } from '../utils/transactions-batch';

interface CreateVaultParams {
connection: Connection;
wallet: Wallet;
priceMint: PublicKey;
externalPriceAccount: PublicKey;
}

interface CreateVaultResponse {
txId;
vault: PublicKey;
fractionMint: PublicKey;
redeemTreasury: PublicKey;
fractionTreasury: PublicKey;
}

// This command creates the external pricing oracle a vault
// This gets the vault ready for adding the tokens.
export const createVault = async ({
connection,
wallet,
priceMint = NATIVE_MINT,
externalPriceAccount,
}: CreateVaultParams): Promise<CreateVaultResponse> => {
const accountRent = await connection.getMinimumBalanceForRentExemption(AccountLayout.span);

const mintRent = await connection.getMinimumBalanceForRentExemption(MintLayout.span);

const vaultRent = await connection.getMinimumBalanceForRentExemption(Vault.MAX_VAULT_SIZE);

const vault = Keypair.generate();

const vaultAuthority = await Vault.getPDA(vault.publicKey);

const txBatch = new TransactionsBatch({ transactions: [] });

const fractionMint = Keypair.generate();
const fractionMintTx = new CreateMint(
{ feePayer: wallet.publicKey },
{
newAccountPubkey: fractionMint.publicKey,
lamports: mintRent,
owner: vaultAuthority,
freezeAuthority: vaultAuthority,
},
);
txBatch.addTransaction(fractionMintTx);
txBatch.addSigner(fractionMint);

const redeemTreasury = Keypair.generate();
const redeemTreasuryTx = new CreateTokenAccount(
{ feePayer: wallet.publicKey },
{
newAccountPubkey: redeemTreasury.publicKey,
lamports: accountRent,
mint: priceMint,
owner: vaultAuthority,
},
);
txBatch.addTransaction(redeemTreasuryTx);
txBatch.addSigner(redeemTreasury);

const fractionTreasury = Keypair.generate();
const fractionTreasuryTx = new CreateTokenAccount(
{ feePayer: wallet.publicKey },
{
newAccountPubkey: fractionTreasury.publicKey,
lamports: accountRent,
mint: fractionMint.publicKey,
owner: vaultAuthority,
},
);
txBatch.addTransaction(fractionTreasuryTx);
txBatch.addSigner(fractionTreasury);

const uninitializedVaultTx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: vault.publicKey,
lamports: vaultRent,
space: Vault.MAX_VAULT_SIZE,
programId: VaultProgram.PUBKEY,
}),
);
txBatch.addTransaction(uninitializedVaultTx);
txBatch.addSigner(vault);

const initVaultTx = new InitVault(
{ feePayer: wallet.publicKey },
{
vault: vault.publicKey,
vaultAuthority: wallet.publicKey,
fractionalTreasury: fractionTreasury.publicKey,
pricingLookupAddress: externalPriceAccount,
redeemTreasury: redeemTreasury.publicKey,
fractionalMint: fractionMint.publicKey,
allowFurtherShareCreation: true,
},
);
txBatch.addTransaction(initVaultTx);

const txId = await sendTransaction({
connection,
signers: txBatch.signers,
txs: txBatch.transactions,
wallet,
});

return {
txId,
vault: vault.publicKey,
fractionMint: fractionMint.publicKey,
redeemTreasury: redeemTreasury.publicKey,
fractionTreasury: fractionTreasury.publicKey,
};
};
1 change: 1 addition & 0 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './transactions';
export * from './initStore';
export * from './mintNFT';
export * from './mintEditionFromMaster';
export * from './createVault';
export * from './createMetadata';
export * from './createMasterEdition';
export * from './signMetadata';
Expand Down
3 changes: 3 additions & 0 deletions src/programs/vault/accounts/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ export class VaultData extends Borsh.Data<Args> {
}

export class Vault extends Account<VaultData> {
static MAX_VAULT_SIZE = 1 + 32 + 32 + 32 + 32 + 1 + 32 + 1 + 32 + 1 + 1 + 8;
static MAX_EXTERNAL_ACCOUNT_SIZE = 1 + 8 + 32 + 1;

constructor(pubkey: AnyPublicKey, info: AccountInfo<Buffer>) {
super(pubkey, info);

Expand Down
34 changes: 34 additions & 0 deletions test/actions/createVault.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { NATIVE_MINT } from '@solana/spl-token';
import { Connection, NodeWallet } from '../../src';
import { createVault } from '../../src/actions';
import { FEE_PAYER, pause, VAULT_EXTENRNAL_PRICE_ACCOUNT } from '../utils';
import { mockAxios200 } from './shared';
import { Vault } from '../../src/programs/vault';

jest.mock('axios');

describe('creating a Vault', () => {
const connection = new Connection('devnet');
const wallet = new NodeWallet(FEE_PAYER);

jest.setTimeout(30000);

describe('success', () => {
beforeEach(() => {
mockAxios200(wallet);
});

test('generates vault', async () => {
const vaultResponse = await createVault({
connection,
wallet,
priceMint: NATIVE_MINT,
externalPriceAccount: VAULT_EXTENRNAL_PRICE_ACCOUNT,
});

await pause(20000);

expect(await Vault.load(connection, vaultResponse.vault)).toHaveProperty('data');
});
});
});
4 changes: 4 additions & 0 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export const PROCEEDS_ACCOUNT_PUBKEY = new PublicKey(
export const SOURCE_PUBKEY = new PublicKey('4CkQJBxhU8EZ2UjhigbtdaPbpTe6mqf811fipYBFbSYN');
export const DESTINATION_PUBKEY = new PublicKey('CZXESU6tu9m4YDs2wfQFbXmjbaDtJKBgurgYzGmeoArh');

export const VAULT_EXTENRNAL_PRICE_ACCOUNT = new PublicKey(
'4FB1P1tewZsXq7FbrSDqkQw319FfWMA4Go2DG3Rdt39K',
);

export const mockTransaction: TransactionCtorFields = {
feePayer: new PublicKey('7J6QvJGCB22vDvYB33ikrWCXRBRsFY74ntAArSK4KJUn'),
recentBlockhash: RECENT_ISH_BLOCKHASH,
Expand Down

0 comments on commit c9d5524

Please sign in to comment.