Merge pull request #6 from blockworks-foundation/srm_account
PR: Support MangoSrmAccount for fee discount deposit and withdraws
This commit is contained in:
commit
d0d38ea41b
102
src/client.ts
102
src/client.ts
|
@ -12,7 +12,7 @@ import {
|
|||
} from '@solana/web3.js';
|
||||
import {
|
||||
encodeMangoInstruction,
|
||||
MangoGroupLayout,
|
||||
MangoGroupLayout, MangoSrmAccountLayout,
|
||||
MarginAccountLayout,
|
||||
MAX_RATE,
|
||||
NUM_MARKETS,
|
||||
|
@ -157,7 +157,6 @@ export class MarginAccount {
|
|||
deposits!: number[];
|
||||
borrows!: number[];
|
||||
openOrders!: PublicKey[];
|
||||
srmBalance!: number;
|
||||
openOrdersAccounts: (OpenOrders | undefined)[] // undefined if an openOrdersAccount not yet initialized and has zeroKey
|
||||
// TODO keep updated with websocket
|
||||
|
||||
|
@ -181,9 +180,7 @@ export class MarginAccount {
|
|||
return nativeToUi(this.getNativeBorrow(mangoGroup, tokenIndex), mangoGroup.mintDecimals[tokenIndex])
|
||||
}
|
||||
|
||||
getUiSrmBalance() {
|
||||
return nativeToUi(this.srmBalance, SRM_DECIMALS)
|
||||
}
|
||||
|
||||
|
||||
async loadOpenOrders(
|
||||
connection: Connection,
|
||||
|
@ -362,6 +359,24 @@ export class MarginAccount {
|
|||
|
||||
}
|
||||
|
||||
|
||||
export class MangoSrmAccount {
|
||||
publicKey: PublicKey;
|
||||
accountFlags!: WideBits;
|
||||
mangoGroup!: PublicKey;
|
||||
amount!: number;
|
||||
|
||||
constructor(publicKey: PublicKey, decoded: any) {
|
||||
this.publicKey = publicKey
|
||||
Object.assign(this, decoded)
|
||||
}
|
||||
|
||||
getUiSrmAmount() {
|
||||
return nativeToUi(this.amount, SRM_DECIMALS)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class MangoClient {
|
||||
|
||||
async sendTransaction(
|
||||
|
@ -766,39 +781,48 @@ export class MangoClient {
|
|||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account,
|
||||
srmAccount: PublicKey,
|
||||
quantity: number,
|
||||
|
||||
mangoSrmAccount?: PublicKey
|
||||
): Promise<PublicKey> {
|
||||
|
||||
const transaction = new Transaction()
|
||||
const additionalSigners: Account[] = []
|
||||
if (!mangoSrmAccount) {
|
||||
const accInstr = await createAccountInstruction(connection,
|
||||
owner.publicKey, MangoSrmAccountLayout.span, programId)
|
||||
transaction.add(accInstr.instruction)
|
||||
additionalSigners.push(accInstr.account)
|
||||
mangoSrmAccount = accInstr.account.publicKey
|
||||
}
|
||||
|
||||
quantity: number
|
||||
): Promise<TransactionSignature> {
|
||||
const nativeQuantity = uiToNative(quantity, SRM_DECIMALS)
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoSrmAccount },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: srmAccount },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.srmVault },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY }
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_RENT_PUBKEY }
|
||||
]
|
||||
const data = encodeMangoInstruction({DepositSrm: {quantity: nativeQuantity}})
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
||||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
return mangoSrmAccount
|
||||
}
|
||||
|
||||
async withdrawSrm(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
mangoSrmAccount: MangoSrmAccount,
|
||||
owner: Account,
|
||||
srmAccount: PublicKey,
|
||||
|
||||
|
@ -808,7 +832,7 @@ export class MangoClient {
|
|||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoSrmAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: srmAccount },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.srmVault },
|
||||
|
@ -930,6 +954,7 @@ export class MangoClient {
|
|||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
}
|
||||
|
||||
async settleFunds(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
|
@ -1143,5 +1168,48 @@ export class MangoClient {
|
|||
|
||||
return marginAccounts
|
||||
}
|
||||
|
||||
async getMangoSrmAccount(
|
||||
connection: Connection,
|
||||
mangoSrmAccountPk: PublicKey
|
||||
): Promise<MangoSrmAccount> {
|
||||
const acc = await connection.getAccountInfo(mangoSrmAccountPk, 'singleGossip')
|
||||
return new MangoSrmAccount(mangoSrmAccountPk, MangoSrmAccountLayout.decode(acc == null ? undefined : acc.data))
|
||||
}
|
||||
|
||||
async getMangoSrmAccountsForOwner(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
owner: Account | Wallet
|
||||
): Promise<MangoSrmAccount[]> {
|
||||
const filters = [
|
||||
{
|
||||
memcmp: {
|
||||
offset: MangoSrmAccountLayout.offsetOf('mangoGroup'),
|
||||
bytes: mangoGroup.publicKey.toBase58(),
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
offset: MangoSrmAccountLayout.offsetOf('owner'),
|
||||
bytes: owner.publicKey.toBase58(),
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
dataSize: MangoSrmAccountLayout.span,
|
||||
},
|
||||
];
|
||||
|
||||
const accounts = await getFilteredProgramAccounts(connection, programId, filters);
|
||||
|
||||
const srmAccounts = accounts.map(
|
||||
({ publicKey, accountInfo }) =>
|
||||
new MangoSrmAccount(publicKey, MangoSrmAccountLayout.decode(accountInfo == null ? undefined : accountInfo.data))
|
||||
)
|
||||
|
||||
return srmAccounts
|
||||
}
|
||||
}
|
||||
|
||||
|
|
24
src/ids.json
24
src/ids.json
|
@ -41,15 +41,15 @@
|
|||
]
|
||||
},
|
||||
"BTC_ETH_USDT": {
|
||||
"mango_group_pk": "5faCLrkbaLhp4kDUiwkEZP2CsH6pHFRV8NSC8kgDf4bm",
|
||||
"mango_group_pk": "CAsLeiWN4S2Q8SAcbo6P7nLUaxs4urVSpzrHpgZLPGLL",
|
||||
"mint_pks": [
|
||||
"C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6",
|
||||
"8p968u9m7jZzKSsqxFDqki69MjqdFkwPM9FN4AN8hvHR",
|
||||
"7tSPGVhneTBWZjLGJGZb9V2UntC7T98cwtSLtgcXjeSs"
|
||||
],
|
||||
"oracle_pks": [
|
||||
"3iQqi9nBREjVvKtVWd44Jcbvs39CDAe6zSd613QzxuPE",
|
||||
"5qxMJFJXB42j3kKo3FbTughREjziottXHcgLnjCNwjEs"
|
||||
"EHasrbBk5mFnTYPjmdNzDoa7cEBH3yN8D4DLJn7Q41hY",
|
||||
"3ynBi9nQyKoEJwC47cmXviLSgHaaXQBKRxukatYYLN1Y"
|
||||
],
|
||||
"spot_market_pks": [
|
||||
"ELXP9wTE4apvK9sxAqtCtMidbAvJJDrNVg4wL6jqQEBA",
|
||||
|
@ -59,25 +59,25 @@
|
|||
"BTC/USDT": "ELXP9wTE4apvK9sxAqtCtMidbAvJJDrNVg4wL6jqQEBA",
|
||||
"ETH/USDT": "97mbLfi4S56y5Vg2LCF4Z7ru8jD1QjHa5SH3eyFYrMdg"
|
||||
},
|
||||
"srm_vault_pk": "Bf9VhCut3mfkz2xbVs4N7Q2ddLoRxLxoGNakBAWFfKDJ",
|
||||
"srm_vault_pk": "BnYohERJjx6sADWe1P3n5cwr2JJFz3HaBidqspDMezm6",
|
||||
"symbols": {
|
||||
"BTC": "C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6",
|
||||
"ETH": "8p968u9m7jZzKSsqxFDqki69MjqdFkwPM9FN4AN8hvHR",
|
||||
"USDT": "7tSPGVhneTBWZjLGJGZb9V2UntC7T98cwtSLtgcXjeSs"
|
||||
},
|
||||
"vault_pks": [
|
||||
"EP1oJGFhYTR6Vfr3zGrRySiwcCcNiJRkppBreVsuaLR9",
|
||||
"AsyDJrq2TRewDGa4hiyWoHF6R4Los5y7yt5XjxergNzM",
|
||||
"5CHhWpkWCevB3CDnf7jSVV7vagRq3CpHv6vZ48LNYLsP"
|
||||
"DKh18z5VYwGNergmKztewEBAe6SCQXaMuJkYVDQhWcyY",
|
||||
"3vyfCDP4EyZPVHMHgJLhFjZrYdQpv5cKrcdKjm8KAFKQ",
|
||||
"BMfn9XdjGQUpdZRLS8TEf1oX9n5cDhgUxJBuqUz7E3k9"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mango_program_id": "Ahf4Q9U9sh86YzRHNkR6u94iRacd9XL2zvUtp2iN94wb",
|
||||
"mango_program_id": "JD3bq9hGdy38PuWQ4h2YJpELmHVGPPfFSuFkpzAd9zfu",
|
||||
"oracles": {
|
||||
"BTC/USDC": "3iQqi9nBREjVvKtVWd44Jcbvs39CDAe6zSd613QzxuPE",
|
||||
"BTC/USDT": "3iQqi9nBREjVvKtVWd44Jcbvs39CDAe6zSd613QzxuPE",
|
||||
"ETH/USDC": "5qxMJFJXB42j3kKo3FbTughREjziottXHcgLnjCNwjEs",
|
||||
"ETH/USDT": "5qxMJFJXB42j3kKo3FbTughREjziottXHcgLnjCNwjEs"
|
||||
"BTC/USDC": "EHasrbBk5mFnTYPjmdNzDoa7cEBH3yN8D4DLJn7Q41hY",
|
||||
"BTC/USDT": "EHasrbBk5mFnTYPjmdNzDoa7cEBH3yN8D4DLJn7Q41hY",
|
||||
"ETH/USDC": "3ynBi9nQyKoEJwC47cmXviLSgHaaXQBKRxukatYYLN1Y",
|
||||
"ETH/USDT": "3ynBi9nQyKoEJwC47cmXviLSgHaaXQBKRxukatYYLN1Y"
|
||||
},
|
||||
"spot_markets": {
|
||||
"BTC/USDC": "FKysSZkCCh41G1SCxpE7Cb7eaLofYBhEneLzHFz6JvjH",
|
||||
|
|
47
src/index.ts
47
src/index.ts
|
@ -1,5 +1,10 @@
|
|||
import { MangoClient, MangoGroup } from './client';
|
||||
import IDS from './ids.json';
|
||||
import { Account, Connection, PublicKey } from '@solana/web3.js';
|
||||
import { Aggregator } from './schema';
|
||||
import { homedir } from 'os';
|
||||
import fs from 'fs';
|
||||
import { sleep } from './utils';
|
||||
|
||||
export { MangoClient, MangoGroup, MarginAccount } from './client';
|
||||
export { MangoIndexLayout, MarginAccountLayout, MangoGroupLayout } from './layout';
|
||||
|
@ -7,3 +12,45 @@ export * from './layout';
|
|||
export * from './utils'
|
||||
|
||||
export { IDS }
|
||||
|
||||
|
||||
// async function tests() {
|
||||
// const cluster = "devnet";
|
||||
// const client = new MangoClient();
|
||||
// const clusterIds = IDS[cluster]
|
||||
//
|
||||
// const connection = new Connection(IDS.cluster_urls[cluster], 'singleGossip')
|
||||
// const mangoGroupPk = new PublicKey(clusterIds.mango_groups['BTC_ETH_USDT'].mango_group_pk);
|
||||
// const mangoProgramId = new PublicKey(clusterIds.mango_program_id);
|
||||
//
|
||||
// const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id.json'
|
||||
// const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')))
|
||||
//
|
||||
//
|
||||
// async function testSolink() {
|
||||
//
|
||||
// const oraclePk = new PublicKey(IDS[cluster].oracles['ETH/USDT'])
|
||||
// const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
//
|
||||
// // const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
// console.log(agg.answer.median.toNumber(), agg.answer.updatedAt.toNumber(), agg.round.id.toNumber())
|
||||
//
|
||||
// }
|
||||
//
|
||||
// async function testDepositSrm() {
|
||||
// const srmVaultPk = new PublicKey(clusterIds['mango_groups']['BTC_ETH_USDT']['srm_vault_pk'])
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk, srmVaultPk)
|
||||
// const srmAccountPk = new PublicKey("6utvndL8EEjpwK5QVtguErncQEPVbkuyABmXu6FeygeV")
|
||||
// const mangoSrmAccountPk = await client.depositSrm(connection, mangoProgramId, mangoGroup, payer, srmAccountPk, 100)
|
||||
// console.log(mangoSrmAccountPk.toBase58())
|
||||
// await sleep(2000)
|
||||
// const mangoSrmAccount = await client.getMangoSrmAccount(connection, mangoSrmAccountPk)
|
||||
// const txid = await client.withdrawSrm(connection, mangoProgramId, mangoGroup, mangoSrmAccount, payer, srmAccountPk, 50)
|
||||
// console.log('success', txid)
|
||||
// }
|
||||
//
|
||||
// // await testSolink()
|
||||
// testDepositSrm()
|
||||
// }
|
||||
//
|
||||
// tests()
|
|
@ -111,6 +111,7 @@ const ACCOUNT_FLAGS_LAYOUT = new WideBits(undefined);
|
|||
ACCOUNT_FLAGS_LAYOUT.addBoolean('Initialized');
|
||||
ACCOUNT_FLAGS_LAYOUT.addBoolean('MangoGroup');
|
||||
ACCOUNT_FLAGS_LAYOUT.addBoolean('MarginAccount');
|
||||
ACCOUNT_FLAGS_LAYOUT.addBoolean('MangoSrmAccount');
|
||||
|
||||
export function accountFlagsLayout(property = 'accountFlags') {
|
||||
return ACCOUNT_FLAGS_LAYOUT.replicate(property); // TODO: when ts check is on, replicate throws error, doesn't compile
|
||||
|
@ -153,8 +154,14 @@ export const MarginAccountLayout = struct([
|
|||
|
||||
seq(U64F64(), NUM_TOKENS, 'deposits'),
|
||||
seq(U64F64(), NUM_TOKENS, 'borrows'),
|
||||
seq(publicKeyLayout(), NUM_MARKETS, 'openOrders'),
|
||||
u64('srmBalance')
|
||||
seq(publicKeyLayout(), NUM_MARKETS, 'openOrders')
|
||||
]);
|
||||
|
||||
export const MangoSrmAccountLayout = struct([
|
||||
accountFlagsLayout('accountFlags'),
|
||||
publicKeyLayout('mangoGroup'),
|
||||
publicKeyLayout('owner'),
|
||||
u64('amount')
|
||||
]);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue