ts: client and script fixes
This commit is contained in:
parent
55e891417e
commit
3257017770
|
@ -128,9 +128,7 @@ export class MangoClient {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getGroupsForCreator(
|
public async getGroupsForCreator(creatorPk: PublicKey): Promise<Group[]> {
|
||||||
creatorPk: PublicKey,
|
|
||||||
): Promise<Group[]> {
|
|
||||||
const filters: MemcmpFilter[] = [
|
const filters: MemcmpFilter[] = [
|
||||||
{
|
{
|
||||||
memcmp: {
|
memcmp: {
|
||||||
|
@ -140,8 +138,8 @@ export class MangoClient {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (await this.program.account.group.all(filters)).map(
|
return (await this.program.account.group.all(filters)).map((tuple) =>
|
||||||
(tuple) => Group.from(tuple.publicKey, tuple.account),
|
Group.from(tuple.publicKey, tuple.account),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,14 +147,15 @@ export class MangoClient {
|
||||||
creatorPk: PublicKey,
|
creatorPk: PublicKey,
|
||||||
groupNum?: number,
|
groupNum?: number,
|
||||||
): Promise<Group> {
|
): Promise<Group> {
|
||||||
const groups = (await this.getGroupsForCreator(creatorPk))
|
const groups = (await this.getGroupsForCreator(creatorPk)).filter(
|
||||||
.filter((group) => {
|
(group) => {
|
||||||
if (groupNum !== undefined) {
|
if (groupNum !== undefined) {
|
||||||
return group.groupNum == groupNum;
|
return group.groupNum == groupNum;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
await groups[0].reloadAll(this);
|
await groups[0].reloadAll(this);
|
||||||
return groups[0];
|
return groups[0];
|
||||||
|
@ -475,12 +474,35 @@ export class MangoClient {
|
||||||
accountNumber?: number,
|
accountNumber?: number,
|
||||||
name?: string,
|
name?: string,
|
||||||
): Promise<MangoAccount> {
|
): Promise<MangoAccount> {
|
||||||
let mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
// TODO: this function discards accountSize and name when the account exists already!
|
||||||
if (mangoAccounts.length === 0) {
|
// TODO: this function always creates accounts for this.program.owner, and not
|
||||||
await this.createMangoAccount(group, accountNumber, name);
|
// ownerPk! It needs to get passed a keypair, and we need to add
|
||||||
mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
// createMangoAccountForOwner
|
||||||
|
if (accountNumber === undefined) {
|
||||||
|
// Get any MangoAccount
|
||||||
|
// TODO: should probably sort by accountNum for deterministic output!
|
||||||
|
let mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
||||||
|
if (mangoAccounts.length === 0) {
|
||||||
|
await this.createMangoAccount(group, accountNumber, name);
|
||||||
|
mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
||||||
|
}
|
||||||
|
return mangoAccounts[0];
|
||||||
|
} else {
|
||||||
|
let account = await this.getMangoAccountForOwner(
|
||||||
|
group,
|
||||||
|
ownerPk,
|
||||||
|
accountNumber,
|
||||||
|
);
|
||||||
|
if (account === undefined) {
|
||||||
|
await this.createMangoAccount(group, accountNumber, name);
|
||||||
|
account = await this.getMangoAccountForOwner(
|
||||||
|
group,
|
||||||
|
ownerPk,
|
||||||
|
accountNumber,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return account;
|
||||||
}
|
}
|
||||||
return mangoAccounts[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createMangoAccount(
|
public async createMangoAccount(
|
||||||
|
@ -540,6 +562,16 @@ export class MangoClient {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getMangoAccountForOwner(
|
||||||
|
group: Group,
|
||||||
|
ownerPk: PublicKey,
|
||||||
|
accountNumber: number,
|
||||||
|
): Promise<MangoAccount> {
|
||||||
|
return (await this.getMangoAccountsForOwner(group, ownerPk)).find(
|
||||||
|
(a) => a.accountNum == accountNumber,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async getMangoAccountsForOwner(
|
public async getMangoAccountsForOwner(
|
||||||
group: Group,
|
group: Group,
|
||||||
ownerPk: PublicKey,
|
ownerPk: PublicKey,
|
||||||
|
@ -626,6 +658,22 @@ export class MangoClient {
|
||||||
amount: number,
|
amount: number,
|
||||||
): Promise<TransactionSignature> {
|
): Promise<TransactionSignature> {
|
||||||
const bank = group.banksMap.get(tokenName)!;
|
const bank = group.banksMap.get(tokenName)!;
|
||||||
|
const nativeAmount = toNativeDecimals(amount, bank.mintDecimals).toNumber();
|
||||||
|
return await this.tokenDepositNative(
|
||||||
|
group,
|
||||||
|
mangoAccount,
|
||||||
|
tokenName,
|
||||||
|
nativeAmount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async tokenDepositNative(
|
||||||
|
group: Group,
|
||||||
|
mangoAccount: MangoAccount,
|
||||||
|
tokenName: string,
|
||||||
|
nativeAmount: number,
|
||||||
|
) {
|
||||||
|
const bank = group.banksMap.get(tokenName)!;
|
||||||
|
|
||||||
const tokenAccountPk = await getAssociatedTokenAddress(
|
const tokenAccountPk = await getAssociatedTokenAddress(
|
||||||
bank.mint,
|
bank.mint,
|
||||||
|
@ -638,7 +686,7 @@ export class MangoClient {
|
||||||
const additionalSigners: Signer[] = [];
|
const additionalSigners: Signer[] = [];
|
||||||
if (bank.mint.equals(WRAPPED_SOL_MINT)) {
|
if (bank.mint.equals(WRAPPED_SOL_MINT)) {
|
||||||
wrappedSolAccount = new Keypair();
|
wrappedSolAccount = new Keypair();
|
||||||
const lamports = Math.round(amount * LAMPORTS_PER_SOL) + 1e7;
|
const lamports = nativeAmount + 1e7;
|
||||||
|
|
||||||
preInstructions = [
|
preInstructions = [
|
||||||
SystemProgram.createAccount({
|
SystemProgram.createAccount({
|
||||||
|
@ -673,7 +721,7 @@ export class MangoClient {
|
||||||
);
|
);
|
||||||
|
|
||||||
return await this.program.methods
|
return await this.program.methods
|
||||||
.tokenDeposit(toNativeDecimals(amount, bank.mintDecimals))
|
.tokenDeposit(new BN(nativeAmount))
|
||||||
.accounts({
|
.accounts({
|
||||||
group: group.publicKey,
|
group: group.publicKey,
|
||||||
account: mangoAccount.publicKey,
|
account: mangoAccount.publicKey,
|
||||||
|
@ -702,45 +750,14 @@ export class MangoClient {
|
||||||
allowBorrow: boolean,
|
allowBorrow: boolean,
|
||||||
): Promise<TransactionSignature> {
|
): Promise<TransactionSignature> {
|
||||||
const bank = group.banksMap.get(tokenName)!;
|
const bank = group.banksMap.get(tokenName)!;
|
||||||
|
const nativeAmount = toNativeDecimals(amount, bank.mintDecimals).toNumber();
|
||||||
const tokenAccountPk = await getAssociatedTokenAddress(
|
return await this.tokenWithdrawNative(
|
||||||
bank.mint,
|
group,
|
||||||
mangoAccount.owner,
|
mangoAccount,
|
||||||
|
tokenName,
|
||||||
|
nativeAmount,
|
||||||
|
allowBorrow,
|
||||||
);
|
);
|
||||||
|
|
||||||
const healthRemainingAccounts: PublicKey[] =
|
|
||||||
this.buildHealthRemainingAccounts(
|
|
||||||
AccountRetriever.Fixed,
|
|
||||||
group,
|
|
||||||
[mangoAccount],
|
|
||||||
[bank],
|
|
||||||
);
|
|
||||||
|
|
||||||
return await this.program.methods
|
|
||||||
.tokenWithdraw(toNativeDecimals(amount, bank.mintDecimals), allowBorrow)
|
|
||||||
.accounts({
|
|
||||||
group: group.publicKey,
|
|
||||||
account: mangoAccount.publicKey,
|
|
||||||
bank: bank.publicKey,
|
|
||||||
vault: bank.vault,
|
|
||||||
tokenAccount: tokenAccountPk,
|
|
||||||
owner: mangoAccount.owner,
|
|
||||||
})
|
|
||||||
.remainingAccounts(
|
|
||||||
healthRemainingAccounts.map(
|
|
||||||
(pk) =>
|
|
||||||
({ pubkey: pk, isWritable: false, isSigner: false } as AccountMeta),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.preInstructions([
|
|
||||||
// ensure withdraws don't fail with missing ATAs
|
|
||||||
await createAssociatedTokenAccountIdempotentInstruction(
|
|
||||||
mangoAccount.owner,
|
|
||||||
mangoAccount.owner,
|
|
||||||
bank.mint,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
.rpc({ skipPreflight: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async tokenWithdrawNative(
|
public async tokenWithdrawNative(
|
||||||
|
@ -781,6 +798,14 @@ export class MangoClient {
|
||||||
({ pubkey: pk, isWritable: false, isSigner: false } as AccountMeta),
|
({ pubkey: pk, isWritable: false, isSigner: false } as AccountMeta),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.preInstructions([
|
||||||
|
// ensure withdraws don't fail with missing ATAs
|
||||||
|
await createAssociatedTokenAccountIdempotentInstruction(
|
||||||
|
mangoAccount.owner,
|
||||||
|
mangoAccount.owner,
|
||||||
|
bank.mint,
|
||||||
|
),
|
||||||
|
])
|
||||||
.rpc({ skipPreflight: true });
|
.rpc({ skipPreflight: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,12 @@ async function main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const groups = await (async () => {
|
const groups = await (async () => {
|
||||||
if (GROUP_NUM === "all") {
|
if (GROUP_NUM === 'all') {
|
||||||
return await client.getGroupsForCreator(admin.publicKey);
|
return await client.getGroupsForCreator(admin.publicKey);
|
||||||
} else {
|
} else {
|
||||||
return [await client.getGroupForCreator(admin.publicKey, Number(GROUP_NUM))];
|
return [
|
||||||
|
await client.getGroupForCreator(admin.publicKey, Number(GROUP_NUM)),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
for (const group of groups) {
|
for (const group of groups) {
|
||||||
|
|
|
@ -65,9 +65,7 @@ async function main() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
const oracle = (
|
const oracle = (await client.getStubOracle(group, mintPk))[0];
|
||||||
await client.getStubOracle(group, mintPk)
|
|
||||||
)[0];
|
|
||||||
console.log(`...created stub oracle ${oracle.publicKey}`);
|
console.log(`...created stub oracle ${oracle.publicKey}`);
|
||||||
oracles.set(name, oracle.publicKey);
|
oracles.set(name, oracle.publicKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,9 @@ async function main() {
|
||||||
|
|
||||||
const admin = Keypair.fromSecretKey(
|
const admin = Keypair.fromSecretKey(
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
JSON.parse(fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
|
JSON.parse(
|
||||||
|
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const userWallet = new Wallet(admin);
|
const userWallet = new Wallet(admin);
|
||||||
|
@ -45,16 +47,16 @@ async function main() {
|
||||||
|
|
||||||
// deposit
|
// deposit
|
||||||
try {
|
try {
|
||||||
console.log(`...depositing 1 USDC`);
|
console.log(`...depositing 10 USDC`);
|
||||||
await client.tokenDeposit(group, mangoAccount, 'USDC', 1);
|
await client.tokenDeposit(group, mangoAccount, 'USDC', 10);
|
||||||
await mangoAccount.reload(client, group);
|
await mangoAccount.reload(client, group);
|
||||||
|
|
||||||
console.log(`...depositing 0.00004 BTC`);
|
console.log(`...depositing 0.0004 BTC`);
|
||||||
await client.tokenDeposit(group, mangoAccount, 'BTC', 0.00004);
|
await client.tokenDeposit(group, mangoAccount, 'BTC', 0.0004);
|
||||||
await mangoAccount.reload(client, group);
|
await mangoAccount.reload(client, group);
|
||||||
|
|
||||||
console.log(`...depositing 0.025 SOL`);
|
console.log(`...depositing 0.25 SOL`);
|
||||||
await client.tokenDeposit(group, mangoAccount, 'SOL', 0.025);
|
await client.tokenDeposit(group, mangoAccount, 'SOL', 0.25);
|
||||||
await mangoAccount.reload(client, group);
|
await mangoAccount.reload(client, group);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
import { AnchorProvider, Wallet } from '@project-serum/anchor';
|
|
||||||
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
|
||||||
import fs from 'fs';
|
|
||||||
import { MangoClient } from '../client';
|
|
||||||
import { MANGO_V4_ID } from '../constants';
|
|
||||||
|
|
||||||
//
|
|
||||||
// This script tries to withdraw all positive balances for all accounts
|
|
||||||
// by MANGO_MAINNET_PAYER_KEYPAIR in the group.
|
|
||||||
//
|
|
||||||
|
|
||||||
const GROUP_NUM = Number(process.env.GROUP_NUM || 1);
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const options = AnchorProvider.defaultOptions();
|
|
||||||
const connection = new Connection(process.env.CLUSTER_URL, options);
|
|
||||||
|
|
||||||
const admin = Keypair.fromSecretKey(
|
|
||||||
Buffer.from(
|
|
||||||
JSON.parse(fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const userWallet = new Wallet(admin);
|
|
||||||
const userProvider = new AnchorProvider(connection, userWallet, options);
|
|
||||||
const client = await MangoClient.connect(
|
|
||||||
userProvider,
|
|
||||||
'mainnet-beta',
|
|
||||||
MANGO_V4_ID['mainnet-beta'],
|
|
||||||
);
|
|
||||||
console.log(`User ${userWallet.publicKey.toBase58()}`);
|
|
||||||
|
|
||||||
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
|
|
||||||
console.log(group.toString());
|
|
||||||
|
|
||||||
const accounts = await client.getMangoAccountsForOwner(group, admin.publicKey);
|
|
||||||
for (let account of accounts) {
|
|
||||||
console.log(`account: ${account.publicKey}`);
|
|
||||||
for (let token of account.tokensActive()) {
|
|
||||||
const bank = group.findBank(token.tokenIndex);
|
|
||||||
const amount = token.native(bank).toNumber();
|
|
||||||
if (amount > 0) {
|
|
||||||
try {
|
|
||||||
const allowBorrow = true; // TODO: set this to false once the withdraw amount ___<___ nativePosition bug is fixed
|
|
||||||
await client.tokenWithdrawNative(group, account, bank.name, amount, allowBorrow);
|
|
||||||
await account.reload(client, group);
|
|
||||||
} catch(error) {
|
|
||||||
console.log(`failed to withdraw ${bank.name} from ${account.publicKey}: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await client.closeMangoAccount(group, account);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`failed to close ${account.publicKey}: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
|
@ -17,7 +17,9 @@ async function main() {
|
||||||
|
|
||||||
const admin = Keypair.fromSecretKey(
|
const admin = Keypair.fromSecretKey(
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
JSON.parse(fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
|
JSON.parse(
|
||||||
|
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const userWallet = new Wallet(admin);
|
const userWallet = new Wallet(admin);
|
||||||
|
@ -32,19 +34,30 @@ async function main() {
|
||||||
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
|
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
|
||||||
console.log(group.toString());
|
console.log(group.toString());
|
||||||
|
|
||||||
const accounts = await client.getMangoAccountsForOwner(group, admin.publicKey);
|
const accounts = await client.getMangoAccountsForOwner(
|
||||||
|
group,
|
||||||
|
admin.publicKey,
|
||||||
|
);
|
||||||
for (let account of accounts) {
|
for (let account of accounts) {
|
||||||
console.log(`account: ${account.publicKey}`);
|
console.log(`account: ${account}`);
|
||||||
for (let token of account.tokensActive()) {
|
for (let token of account.tokensActive()) {
|
||||||
const bank = group.findBank(token.tokenIndex);
|
const bank = group.findBank(token.tokenIndex);
|
||||||
const amount = token.native(bank).toNumber();
|
const amount = token.native(bank).toNumber();
|
||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
try {
|
try {
|
||||||
const allowBorrow = true; // TODO: set this to false once the withdraw amount ___<___ nativePosition bug is fixed
|
const allowBorrow = true; // TODO: set this to false once the withdraw amount ___<___ nativePosition bug is fixed
|
||||||
await client.tokenWithdrawNative(group, account, bank.name, amount, allowBorrow);
|
await client.tokenWithdrawNative(
|
||||||
|
group,
|
||||||
|
account,
|
||||||
|
bank.name,
|
||||||
|
amount,
|
||||||
|
allowBorrow,
|
||||||
|
);
|
||||||
await account.reload(client, group);
|
await account.reload(client, group);
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
console.log(`failed to withdraw ${bank.name} from ${account.publicKey}: ${error}`);
|
console.log(
|
||||||
|
`failed to withdraw ${bank.name} from ${account.publicKey}: ${error}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue