Skip to content

Commit

Permalink
Staking UI init
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Dec 7, 2020
1 parent e62c330 commit 61fde17
Show file tree
Hide file tree
Showing 75 changed files with 8,471 additions and 1,685 deletions.
1 change: 1 addition & 0 deletions packages/borsh/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'buffer-layout';
import { PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
export { u8, u32, struct } from 'buffer-layout';

export interface Layout<T> {
span: number;
Expand Down
1 change: 1 addition & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"scripts": {
"build": "tsc",
"watch": "tsc --watch",
"test": "jest test",
"clean": "rm -rf dist",
"prepare": "run-s clean build"
Expand Down
64 changes: 51 additions & 13 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ import {
} from '@solana/web3.js';
import { Provider } from './provider';
import { Layout, struct, Structure, u8, nu64, blob } from 'buffer-layout';
import { AccountInfo, AccountLayout, u64 } from '@solana/spl-token';
import {
MintInfo,
MintLayout,
AccountInfo,
AccountLayout,
u64,
} from '@solana/spl-token';
import { TokenInstructions } from '@project-serum/serum';
import BN from 'bn.js';

export * from './provider';
export * as token from './token';
export { networks, Network } from './networks';
export { simulateTransaction } from './simulate-transaction';

// Mainnet.
// export const SPL_SHARED_MEMORY_ID = new PublicKey(
// 'shmem4EWT2sPdVGvTZCzXXRAURL9G5vpPxNwSeKhHUL',
// );

// Devnet.
export const SPL_SHARED_MEMORY_ID = new PublicKey(
'3w2Q6XjS2BDpxHVRzs8oWbNuH7ivZp1mVo3mbq318oyG',
'shmem4EWT2sPdVGvTZCzXXRAURL9G5vpPxNwSeKhHUL',
);

export async function createMint(
Expand Down Expand Up @@ -125,23 +128,34 @@ export async function createTokenAccount(
const vault = new Account();
const tx = new Transaction();
tx.add(
...(await createTokenAccountInstrs(provider, vault.publicKey, mint, owner)),
);
await provider.send(tx, [vault]);
return vault.publicKey;
}

export async function createTokenAccountInstrs(
provider: Provider,
newAccountPubkey: PublicKey,
mint: PublicKey,
owner: PublicKey,
): Promise<TransactionInstruction[]> {
return [
SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: vault.publicKey,
newAccountPubkey,
space: 165,
lamports: await provider.connection.getMinimumBalanceForRentExemption(
165,
),
programId: TokenInstructions.TOKEN_PROGRAM_ID,
}),
TokenInstructions.initializeAccount({
account: vault.publicKey,
account: newAccountPubkey,
mint,
owner,
}),
);
await provider.send(tx, [vault]);
return vault.publicKey;
];
}

export async function createAccountRentExempt(
Expand All @@ -166,6 +180,25 @@ export async function createAccountRentExempt(
return acc;
}

export async function getMintInfo(
provider: Provider,
addr: PublicKey,
): Promise<MintInfo> {
let depositorAccInfo = await provider.connection.getAccountInfo(addr);
if (depositorAccInfo === null) {
throw new Error('Failed to find token account');
}
return parseMintAccount(depositorAccInfo.data);
}

function parseMintAccount(data: Buffer): MintInfo {
const m = MintLayout.decode(data);
m.mintAuthority = new PublicKey(m.mintAuthority);
m.supply = u64.fromBuffer(m.supply);
m.isInitialized = m.state !== 0;
return m;
}

export async function getTokenAccount(
provider: Provider,
addr: PublicKey,
Expand Down Expand Up @@ -215,3 +248,8 @@ export function parseTokenAccount(data: Buffer): AccountInfo {
export function sleep(ms: number): Promise<any> {
return new Promise(resolve => setTimeout(resolve, ms));
}

export type ProgramAccount<T> = {
publicKey: PublicKey;
account: T;
};
107 changes: 107 additions & 0 deletions packages/common/src/networks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { PublicKey } from '@solana/web3.js';

type Networks = { [label: string]: Network };

export type Network = {
label: string;
// Cluster.
url: string;
explorerClusterSuffix: string;

// Mints and god accounts.
srm: PublicKey;
msrm: PublicKey;
god: PublicKey;
megaGod: PublicKey;

// Programs.
registryProgramId: PublicKey;
stakeProgramId: PublicKey;
lockupProgramId: PublicKey;
retbufProgramId: PublicKey;
metaEntityProgramId: PublicKey;

// Program accounts.
safe: PublicKey;
registrar: PublicKey;
rewardEventQueue: PublicKey;
retbuf: PublicKey;

// Misc.
defaultEntity: PublicKey;
};

export const networks: Networks = {
devnet: {
// Cluster.
label: 'Devnet',
url: 'https://devnet.solana.com',
explorerClusterSuffix: 'devnet',

srm: new PublicKey('DLRk8GWo1YF4Kc5DrVQkaMDQti27VVGzR3Y1Tm8Frpyj'),
msrm: new PublicKey('CrtnNeZg3tnRKnxxYxjsnkYNk1xRjhEci8ZJhuRAU7WX'),
god: new PublicKey('HtbxQ8ZfenVhw5G8GSVK5nymbNXXo37fwwp9sjAjaBEx'),
megaGod: new PublicKey('DKmDLZUUkfaFEQ3PWYezmoL3BwaEt1QHHYrLGPWuCMiV'),
registryProgramId: new PublicKey(
'G5W9X8gjf2v8QH3D7aQrFhHSxMK7sxB1wQQpKPue2Nnv',
),
stakeProgramId: new PublicKey(
'APU8W2tEUhiAAeaiEtYKdaMtB3KrBQXqyiinvjGurvBf',
),
lockupProgramId: new PublicKey(
'Bk9M7yycNZiKkFtKDzzLQAhvQjWMqxYSFJzxFspL9uJ',
),
retbufProgramId: new PublicKey(
'3w2Q6XjS2BDpxHVRzs8oWbNuH7ivZp1mVo3mbq318oyG',
),
metaEntityProgramId: new PublicKey(
'H6PGzjRWMBd2dajxL5ZjDc9LU4onSB5PbrqHS94Hgoed',
),
registrar: new PublicKey('2w6i8FLi7DJ2UrTTGeKwkotgvM2k9FtfcP7vLfzT5pnx'),
rewardEventQueue: new PublicKey(
'ozD1sY1rdizmPkr29PCyrWVrUC73HLQurTnvtsFmC6P',
),
safe: new PublicKey('2u8tjVJuz8P7EYa4WL3x2oHndjZLZNfA4vkWaa3SP75f'),
retbuf: new PublicKey('8PUeeTe22fHJqTVB5wahQmqZjaHzDPC7arYhWSnTLqZA'),
defaultEntity: new PublicKey(
'GQmf9Ag2EHC6RyJuxyEkUMMRzB8zhhSEq8Bmae7Wxyhi',
),
},

// Fill in with your local cluster addresses.
localhost: {
// Cluster.
label: 'Localhost',
url: 'http://localhost:8899',
explorerClusterSuffix: 'localhost',

srm: new PublicKey('49uPApDJo81q2ruSV7QGcKbWvrvidwkuwiBdNGqNLEDj'),
msrm: new PublicKey('5WzVn4fzZwL1pHp3o1SnQwNhB6YjfinhQNZMRtv4PDRV'),
god: new PublicKey('8WmKCQiuBo97cGE7NTo6Gvfec8fi9sMCwbdyToXk99eS'),
megaGod: new PublicKey('4L6KRfJ2G1Gp59Cmav3Wux6wuyArvuhXx1R3ozCDF7Zy'),
registryProgramId: new PublicKey(
'7VA5eMqGwEvkkRsgrz28uFeqAKAMQ32TBHpTakKpWSBT',
),
stakeProgramId: new PublicKey(
'FcznkS6Yo6mfhG6Rp49A5GTiag9AE9g8sZdfb5tUV271',
),
lockupProgramId: new PublicKey(
'9quusFhQuZPHTCWRNAiZspJtei639KNgmaJNFYUxbPwZ',
),
retbufProgramId: new PublicKey(
'shmem4EWT2sPdVGvTZCzXXRAURL9G5vpPxNwSeKhHUL',
),
metaEntityProgramId: new PublicKey(
'Ftm99ezozbjdSZJBU3raB316jdijGDWx1uSxRDwK2UUZ',
),
registrar: new PublicKey('C8kZJRjMfQAC6Gjn8s25oHsDwQegMebWafDUBacmKCxR'),
rewardEventQueue: new PublicKey(
'5a4WCYb4bPWJE7e8VGdr5ntUsapE6z9RBpc4Ci5CYfWn',
),
safe: new PublicKey('Gqhc69ywiiWTaLEJArC6pqHwzPCqGRmNMaiLUbsD5jqU'),
retbuf: new PublicKey('7XxFAvQ9HoHch1jH1tJerPcAJ4zg65ZhusdMWeK5ZPx'),
defaultEntity: new PublicKey(
'AX1XPYdcgiSrkKupNr8ywWFE1sNe6Ln79c5qyHGsRvju',
),
},
};
34 changes: 34 additions & 0 deletions packages/common/src/simulate-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
Commitment,
Connection,
RpcResponseAndContext,
SimulatedTransactionResponse,
Transaction,
} from '@solana/web3.js';

/** Copy of Connection.simulateTransaction that takes a commitment parameter. */
export async function simulateTransaction(
connection: Connection,
transaction: Transaction,
commitment: Commitment,
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
// @ts-ignore
transaction.recentBlockhash = await connection._recentBlockhash(
// @ts-ignore
connection._disableBlockhashCaching,
);

const signData = transaction.serializeMessage();
// @ts-ignore
const wireTransaction = transaction._serialize(signData);
const encodedTransaction = wireTransaction.toString('base64');
const config: any = { encoding: 'base64', commitment };
const args = [encodedTransaction, config];

// @ts-ignore
const res = await connection._rpcRequest('simulateTransaction', args);
if (res.error) {
throw new Error('failed to simulate transaction: ' + res.error.message);
}
return res.result;
}
86 changes: 86 additions & 0 deletions packages/common/src/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Connection, PublicKey } from '@solana/web3.js';
import { ProgramAccount } from './';
import { AccountInfo as TokenAccount } from '@solana/spl-token';
import { TokenInstructions } from '@project-serum/serum';
import * as bs58 from 'bs58';
import * as BufferLayout from 'buffer-layout';

export async function getOwnedTokenAccounts(
connection: Connection,
publicKey: PublicKey,
): Promise<ProgramAccount<TokenAccount>[]> {
let filters = getOwnedAccountsFilters(publicKey);
// @ts-ignore
let resp = await connection._rpcRequest('getProgramAccounts', [
TokenInstructions.TOKEN_PROGRAM_ID.toBase58(),
{
commitment: connection.commitment,
filters,
},
]);
if (resp.error) {
throw new Error(
'failed to get token accounts owned by ' +
publicKey.toBase58() +
': ' +
resp.error.message,
);
}
return (
resp.result
// @ts-ignore
.map(({ pubkey, account: { data } }) => {
data = bs58.decode(data);
return {
publicKey: new PublicKey(pubkey),
account: parseTokenAccountData(data),
};
})
);
}

// todo: remove
export const ACCOUNT_LAYOUT = BufferLayout.struct([
BufferLayout.blob(32, 'mint'),
BufferLayout.blob(32, 'owner'),
BufferLayout.nu64('amount'),
BufferLayout.blob(93),
]);
export const MINT_LAYOUT = BufferLayout.struct([
BufferLayout.blob(44),
BufferLayout.u8('decimals'),
BufferLayout.blob(37),
]);

export function parseTokenAccountData(data: any) {
// @ts-ignore
let { mint, owner, amount } = ACCOUNT_LAYOUT.decode(data);
return {
mint: new PublicKey(mint),
owner: new PublicKey(owner),
amount,
};
}

// @ts-ignore
export function parseMintData(data) {
// @ts-ignore
let { decimals } = MINT_LAYOUT.decode(data);
return { decimals };
}

// @ts-ignore
export function getOwnedAccountsFilters(publicKey: PublicKey) {
return [
{
memcmp: {
// @ts-ignore
offset: ACCOUNT_LAYOUT.offsetOf('owner'),
bytes: publicKey.toBase58(),
},
},
{
dataSize: ACCOUNT_LAYOUT.span,
},
];
}
6 changes: 5 additions & 1 deletion packages/lockup-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@material-ui/icons": "^4.9.1",
"@project-serum/common": "^0.0.1-alpha.2",
"@project-serum/lockup": "^0.0.1-alpha.2",
"@project-serum/registry": "^0.0.1-alpha.3",
"@project-serum/sol-wallet-adapter": "^0.1.3",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
Expand All @@ -21,10 +22,12 @@
"@types/react-redux": "^7.1.11",
"@types/react-router-dom": "^5.1.6",
"chartist": "^0.11.4",
"eventemitter3": "^4.0.7",
"notistack": "^1.0.1",
"react": "^17.0.1",
"react-chartist": "^0.14.3",
"react-dom": "^17.0.1",
"react-image": "^4.0.3",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0",
Expand All @@ -37,7 +40,8 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test:ui": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"prettier:fix": "prettier src/** -w"
},
"eslintConfig": {
"extends": [
Expand Down
Binary file modified packages/lockup-ui/public/favicon.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/lockup-ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Serum</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Loading

0 comments on commit 61fde17

Please sign in to comment.