wip margin trade with spl token transfers
This commit is contained in:
parent
54c0306ae7
commit
997d363195
|
@ -55,11 +55,10 @@
|
|||
"trailingComma": "all"
|
||||
},
|
||||
"dependencies": {
|
||||
"@orca-so/sdk": "^1.2.24",
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@project-serum/serum": "^0.13.65",
|
||||
"@pythnetwork/client": "^2.7.0",
|
||||
"@solana/spl-token": "~0.1.8",
|
||||
"@solana/spl-token": "^0.2.0",
|
||||
"big.js": "^6.1.1",
|
||||
"bs58": "^5.0.0"
|
||||
},
|
||||
|
|
|
@ -6,8 +6,13 @@ import {
|
|||
initializeAccount,
|
||||
WRAPPED_SOL_MINT,
|
||||
} from '@project-serum/serum/lib/token-instructions';
|
||||
import { parsePriceData, PriceData } from '@pythnetwork/client';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
import { parsePriceData } from '@pythnetwork/client';
|
||||
import {
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
createAssociatedTokenAccountInstruction,
|
||||
createTransferInstruction,
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from '@solana/spl-token';
|
||||
import {
|
||||
AccountMeta,
|
||||
Cluster,
|
||||
|
@ -36,10 +41,10 @@ import {
|
|||
} from './accounts/serum3';
|
||||
import { SERUM3_PROGRAM_ID } from './constants';
|
||||
import { Id } from './ids';
|
||||
import {
|
||||
buildOrcaInstruction,
|
||||
ORCA_TOKEN_SWAP_ID_DEVNET,
|
||||
} from './integrations/orca/index';
|
||||
// import {
|
||||
// buildOrcaInstruction,
|
||||
// ORCA_TOKEN_SWAP_ID_DEVNET,
|
||||
// } from './integrations/orca/index';
|
||||
import { IDL, MangoV4 } from './mango_v4';
|
||||
import { FlashLoanWithdraw } from './types';
|
||||
import {
|
||||
|
@ -267,8 +272,6 @@ export class MangoClient {
|
|||
if (banks[index].name === 'USDC') {
|
||||
banks[index].price = 1;
|
||||
} else {
|
||||
console.log('parsePriceData(price.data)', parsePriceData(price.data));
|
||||
|
||||
banks[index].price = parsePriceData(price.data).previousPrice;
|
||||
}
|
||||
}
|
||||
|
@ -1135,41 +1138,128 @@ export class MangoClient {
|
|||
} as AccountMeta),
|
||||
);
|
||||
|
||||
const targetProgramId = ORCA_TOKEN_SWAP_ID_DEVNET;
|
||||
|
||||
const { instruction, signers } = await buildOrcaInstruction(
|
||||
targetProgramId,
|
||||
inputBank,
|
||||
outputBank,
|
||||
toU64(amountIn, 9),
|
||||
toU64(minimumAmountOut, 6),
|
||||
/*
|
||||
*
|
||||
* Find or create associated token account
|
||||
*
|
||||
*/
|
||||
let tokenAccountPk = await getAssociatedTokenAddress(
|
||||
inputBank.mint,
|
||||
mangoAccount.owner,
|
||||
);
|
||||
const targetRemainingAccounts = instruction.keys;
|
||||
const tokenAccExists =
|
||||
await this.program.provider.connection.getAccountInfo(tokenAccountPk);
|
||||
|
||||
let preInstructions = [];
|
||||
if (!tokenAccExists) {
|
||||
preInstructions.push(
|
||||
createAssociatedTokenAccountInstruction(
|
||||
mangoAccount.owner,
|
||||
tokenAccountPk,
|
||||
mangoAccount.owner,
|
||||
inputBank.mint,
|
||||
TOKEN_PROGRAM_ID,
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Borrow a token and transfer to wallet then transfer back
|
||||
*
|
||||
*/
|
||||
// TODO don't hard code decimal #
|
||||
const decimals = 6;
|
||||
const nativeAmount = toU64(amountIn, decimals);
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const transferIx = createTransferInstruction(
|
||||
inputBank.vault,
|
||||
tokenAccountPk,
|
||||
inputBank.publicKey,
|
||||
nativeAmount,
|
||||
[],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
const inputBankKey = transferIx.keys[2];
|
||||
transferIx.keys[2] = { ...inputBankKey, isWritable: true, isSigner: false };
|
||||
instructions.push(transferIx);
|
||||
|
||||
const transferIx2 = createTransferInstruction(
|
||||
tokenAccountPk,
|
||||
inputBank.vault,
|
||||
mangoAccount.owner,
|
||||
nativeAmount,
|
||||
[],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
instructions.push(transferIx2);
|
||||
|
||||
/*
|
||||
*
|
||||
* Build data objects for margin trade instructions
|
||||
*
|
||||
*/
|
||||
const targetRemainingAccounts = instructions
|
||||
.map((ix) => [
|
||||
{
|
||||
pubkey: ix.programId,
|
||||
isWritable: false,
|
||||
isSigner: false,
|
||||
} as AccountMeta,
|
||||
...ix.keys,
|
||||
])
|
||||
.flat();
|
||||
|
||||
const banks = Array.from(group.banksMap.values());
|
||||
const bankPks = banks.map((b) => b.publicKey.toString());
|
||||
const bankIndex = bankPks.indexOf(inputBank.publicKey.toString());
|
||||
|
||||
const withdraws: FlashLoanWithdraw[] = [
|
||||
{ index: 3, amount: toU64(amountIn, 9) },
|
||||
];
|
||||
const cpiData = instruction.data;
|
||||
|
||||
let cpiDatas = [];
|
||||
for (const [index, ix] of instructions.entries()) {
|
||||
if (index === 0) {
|
||||
cpiDatas.push({
|
||||
accountStart: new BN(parsedHealthAccounts.length),
|
||||
data: ix.data,
|
||||
});
|
||||
} else {
|
||||
cpiDatas.push({
|
||||
accountStart: cpiDatas[index - 1].accountStart.add(
|
||||
new BN(instructions[index - 1].keys.length + 1),
|
||||
),
|
||||
data: ix.data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log('instruction1', transferIx);
|
||||
console.log('instruction2', transferIx2);
|
||||
|
||||
console.log('cpiDatas', cpiDatas);
|
||||
console.log(
|
||||
'targetRemainingAccounts',
|
||||
targetRemainingAccounts.map((t) => ({
|
||||
...t,
|
||||
pubkey: t.pubkey.toString(),
|
||||
})),
|
||||
);
|
||||
|
||||
return await this.program.methods
|
||||
.flashLoan(withdraws, [
|
||||
{ accountStart: new BN(parsedHealthAccounts.length), data: cpiData },
|
||||
{ accountStart: new BN(parsedHealthAccounts.length), data: cpiDatas },
|
||||
])
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
account: mangoAccount.publicKey,
|
||||
owner: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
})
|
||||
.remainingAccounts([
|
||||
...parsedHealthAccounts,
|
||||
{
|
||||
pubkey: targetProgramId,
|
||||
isWritable: false,
|
||||
isSigner: false,
|
||||
} as AccountMeta,
|
||||
...targetRemainingAccounts,
|
||||
])
|
||||
.signers(signers)
|
||||
.remainingAccounts([...parsedHealthAccounts, ...targetRemainingAccounts])
|
||||
.preInstructions(preInstructions)
|
||||
.signers([])
|
||||
.rpc({ skipPreflight: true });
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export {
|
|||
Serum3Side,
|
||||
} from './accounts/serum3';
|
||||
export * from './constants';
|
||||
export * from './integrations/orca/index';
|
||||
// export * from './integrations/orca/index';
|
||||
export {
|
||||
Group,
|
||||
StubOracle,
|
||||
|
|
|
@ -1,200 +1,200 @@
|
|||
import {
|
||||
OrcaPoolToken,
|
||||
ORCA_TOKEN_SWAP_ID_DEVNET,
|
||||
PoolTokenCount,
|
||||
} from '@orca-so/sdk';
|
||||
import { orcaDevnetPoolConfigs } from '@orca-so/sdk/dist/constants/devnet/pools';
|
||||
import { OrcaPoolParams } from '@orca-so/sdk/dist/model/orca/pool/pool-types';
|
||||
import { OrcaPoolConfig as OrcaDevnetPoolConfig } from '@orca-so/sdk/dist/public/devnet/pools/config';
|
||||
import { BN } from '@project-serum/anchor';
|
||||
import {
|
||||
AccountInfo,
|
||||
AccountLayout,
|
||||
TOKEN_PROGRAM_ID,
|
||||
u64,
|
||||
} from '@solana/spl-token';
|
||||
import { TokenSwap } from '@solana/spl-token-swap';
|
||||
import { Connection, PublicKey } from '@solana/web3.js';
|
||||
// import {
|
||||
// OrcaPoolToken,
|
||||
// ORCA_TOKEN_SWAP_ID_DEVNET,
|
||||
// PoolTokenCount,
|
||||
// } from '@orca-so/sdk';
|
||||
// import { orcaDevnetPoolConfigs } from '@orca-so/sdk/dist/constants/devnet/pools';
|
||||
// import { OrcaPoolParams } from '@orca-so/sdk/dist/model/orca/pool/pool-types';
|
||||
// import { OrcaPoolConfig as OrcaDevnetPoolConfig } from '@orca-so/sdk/dist/public/devnet/pools/config';
|
||||
// import { BN } from '@project-serum/anchor';
|
||||
// import {
|
||||
// AccountInfo,
|
||||
// AccountLayout,
|
||||
// TOKEN_PROGRAM_ID,
|
||||
// u64,
|
||||
// } from '@solana/spl-token';
|
||||
// import { TokenSwap } from '@solana/spl-token-swap';
|
||||
// import { Connection, PublicKey } from '@solana/web3.js';
|
||||
|
||||
import { Bank } from '../../accounts/bank';
|
||||
import { toNativeDecimals, toUiDecimals } from '../../utils';
|
||||
import * as Tokens from './tokens';
|
||||
// import { Bank } from '../../accounts/bank';
|
||||
// import { toNativeDecimals, toUiDecimals } from '../../utils';
|
||||
// import * as Tokens from './tokens';
|
||||
|
||||
export { ORCA_TOKEN_SWAP_ID_DEVNET };
|
||||
// export { ORCA_TOKEN_SWAP_ID_DEVNET };
|
||||
|
||||
/*
|
||||
Orca ix references:
|
||||
swap fn: https://github.com/orca-so/typescript-sdk/blob/main/src/model/orca/pool/orca-pool.ts#L162
|
||||
swap ix: https://github.com/orca-so/typescript-sdk/blob/main/src/public/utils/web3/instructions/pool-instructions.ts#L41
|
||||
*/
|
||||
export const buildOrcaInstruction = async (
|
||||
orcaTokenSwapId: PublicKey,
|
||||
inputBank: Bank,
|
||||
outputBank: Bank,
|
||||
amountInU64: BN,
|
||||
minimumAmountOutU64: BN,
|
||||
) => {
|
||||
// TODO: select the correct pool params based on passed in banks
|
||||
const poolParams = orcaDevnetPoolConfigs[OrcaDevnetPoolConfig.ORCA_SOL];
|
||||
// /*
|
||||
// Orca ix references:
|
||||
// swap fn: https://github.com/orca-so/typescript-sdk/blob/main/src/model/orca/pool/orca-pool.ts#L162
|
||||
// swap ix: https://github.com/orca-so/typescript-sdk/blob/main/src/public/utils/web3/instructions/pool-instructions.ts#L41
|
||||
// */
|
||||
// export const buildOrcaInstruction = async (
|
||||
// orcaTokenSwapId: PublicKey,
|
||||
// inputBank: Bank,
|
||||
// outputBank: Bank,
|
||||
// amountInU64: BN,
|
||||
// minimumAmountOutU64: BN,
|
||||
// ) => {
|
||||
// // TODO: select the correct pool params based on passed in banks
|
||||
// const poolParams = orcaDevnetPoolConfigs[OrcaDevnetPoolConfig.ORCA_SOL];
|
||||
|
||||
const [authorityForPoolAddress] = await PublicKey.findProgramAddress(
|
||||
[poolParams.address.toBuffer()],
|
||||
orcaTokenSwapId,
|
||||
);
|
||||
// const [authorityForPoolAddress] = await PublicKey.findProgramAddress(
|
||||
// [poolParams.address.toBuffer()],
|
||||
// orcaTokenSwapId,
|
||||
// );
|
||||
|
||||
const instruction = TokenSwap.swapInstruction(
|
||||
poolParams.address,
|
||||
authorityForPoolAddress,
|
||||
inputBank.publicKey, // userTransferAuthority
|
||||
inputBank.vault, // inputTokenUserAddress
|
||||
poolParams.tokens[inputBank.mint.toString()].addr, // inputToken.addr
|
||||
poolParams.tokens[outputBank.mint.toString()].addr, // outputToken.addr
|
||||
outputBank.vault, // outputTokenUserAddress
|
||||
poolParams.poolTokenMint,
|
||||
poolParams.feeAccount,
|
||||
null, // hostFeeAccount
|
||||
orcaTokenSwapId,
|
||||
TOKEN_PROGRAM_ID,
|
||||
amountInU64,
|
||||
minimumAmountOutU64,
|
||||
);
|
||||
// const instruction = TokenSwap.swapInstruction(
|
||||
// poolParams.address,
|
||||
// authorityForPoolAddress,
|
||||
// inputBank.publicKey, // userTransferAuthority
|
||||
// inputBank.vault, // inputTokenUserAddress
|
||||
// poolParams.tokens[inputBank.mint.toString()].addr, // inputToken.addr
|
||||
// poolParams.tokens[outputBank.mint.toString()].addr, // outputToken.addr
|
||||
// outputBank.vault, // outputTokenUserAddress
|
||||
// poolParams.poolTokenMint,
|
||||
// poolParams.feeAccount,
|
||||
// null, // hostFeeAccount
|
||||
// orcaTokenSwapId,
|
||||
// TOKEN_PROGRAM_ID,
|
||||
// amountInU64,
|
||||
// minimumAmountOutU64,
|
||||
// );
|
||||
|
||||
instruction.keys[2].isSigner = false;
|
||||
instruction.keys[2].isWritable = true;
|
||||
// instruction.keys[2].isSigner = false;
|
||||
// instruction.keys[2].isWritable = true;
|
||||
|
||||
return { instruction, signers: [] };
|
||||
};
|
||||
// return { instruction, signers: [] };
|
||||
// };
|
||||
|
||||
export const getOrcaOutputAmount = async (
|
||||
connection: Connection,
|
||||
inputToken: string,
|
||||
outputToken: string,
|
||||
amountIn: number,
|
||||
): Promise<number> => {
|
||||
// TODO: select the correct pool params based on passed in banks
|
||||
const inputMint = Tokens.solToken;
|
||||
const poolParams = getOrcaPoolParams(inputToken, outputToken);
|
||||
// export const getOrcaOutputAmount = async (
|
||||
// connection: Connection,
|
||||
// inputToken: string,
|
||||
// outputToken: string,
|
||||
// amountIn: number,
|
||||
// ): Promise<number> => {
|
||||
// // TODO: select the correct pool params based on passed in banks
|
||||
// const inputMint = Tokens.solToken;
|
||||
// const poolParams = getOrcaPoolParams(inputToken, outputToken);
|
||||
|
||||
const { inputPoolToken, outputPoolToken } = getTokens(
|
||||
poolParams,
|
||||
inputMint.mint.toString(),
|
||||
);
|
||||
// const { inputPoolToken, outputPoolToken } = getTokens(
|
||||
// poolParams,
|
||||
// inputMint.mint.toString(),
|
||||
// );
|
||||
|
||||
const { inputTokenCount, outputTokenCount } = await getTokenCount(
|
||||
connection,
|
||||
poolParams,
|
||||
inputPoolToken,
|
||||
outputPoolToken,
|
||||
);
|
||||
// const { inputTokenCount, outputTokenCount } = await getTokenCount(
|
||||
// connection,
|
||||
// poolParams,
|
||||
// inputPoolToken,
|
||||
// outputPoolToken,
|
||||
// );
|
||||
|
||||
const [poolInputAmount, poolOutputAmount] = [
|
||||
inputTokenCount,
|
||||
outputTokenCount,
|
||||
];
|
||||
// const [poolInputAmount, poolOutputAmount] = [
|
||||
// inputTokenCount,
|
||||
// outputTokenCount,
|
||||
// ];
|
||||
|
||||
const invariant = poolInputAmount.mul(poolOutputAmount);
|
||||
const nativeAmountIn = toNativeDecimals(amountIn, 9);
|
||||
// const invariant = poolInputAmount.mul(poolOutputAmount);
|
||||
// const nativeAmountIn = toNativeDecimals(amountIn, 9);
|
||||
|
||||
const [newPoolOutputAmount] = ceilingDivision(
|
||||
invariant,
|
||||
poolInputAmount.add(nativeAmountIn),
|
||||
);
|
||||
// const [newPoolOutputAmount] = ceilingDivision(
|
||||
// invariant,
|
||||
// poolInputAmount.add(nativeAmountIn),
|
||||
// );
|
||||
|
||||
const outputAmount = poolOutputAmount.sub(newPoolOutputAmount);
|
||||
// const outputAmount = poolOutputAmount.sub(newPoolOutputAmount);
|
||||
|
||||
return toUiDecimals(outputAmount.toNumber(), 6);
|
||||
};
|
||||
// return toUiDecimals(outputAmount.toNumber(), 6);
|
||||
// };
|
||||
|
||||
function getTokens(poolParams: OrcaPoolParams, inputTokenId: string) {
|
||||
if (poolParams.tokens[inputTokenId] == undefined) {
|
||||
throw new Error('Input token not part of pool');
|
||||
}
|
||||
// function getTokens(poolParams: OrcaPoolParams, inputTokenId: string) {
|
||||
// if (poolParams.tokens[inputTokenId] == undefined) {
|
||||
// throw new Error('Input token not part of pool');
|
||||
// }
|
||||
|
||||
const tokenAId = poolParams.tokenIds[0];
|
||||
const tokenBId = poolParams.tokenIds[1];
|
||||
// const tokenAId = poolParams.tokenIds[0];
|
||||
// const tokenBId = poolParams.tokenIds[1];
|
||||
|
||||
const forward = tokenAId == inputTokenId;
|
||||
// const forward = tokenAId == inputTokenId;
|
||||
|
||||
const inputOrcaToken = forward
|
||||
? poolParams.tokens[tokenAId]
|
||||
: poolParams.tokens[tokenBId];
|
||||
const outputOrcaToken = forward
|
||||
? poolParams.tokens[tokenBId]
|
||||
: poolParams.tokens[tokenAId];
|
||||
return { inputPoolToken: inputOrcaToken, outputPoolToken: outputOrcaToken };
|
||||
}
|
||||
// const inputOrcaToken = forward
|
||||
// ? poolParams.tokens[tokenAId]
|
||||
// : poolParams.tokens[tokenBId];
|
||||
// const outputOrcaToken = forward
|
||||
// ? poolParams.tokens[tokenBId]
|
||||
// : poolParams.tokens[tokenAId];
|
||||
// return { inputPoolToken: inputOrcaToken, outputPoolToken: outputOrcaToken };
|
||||
// }
|
||||
|
||||
const getOrcaPoolParams = (inputToken: string, outputToken: string) => {
|
||||
return orcaDevnetPoolConfigs[OrcaDevnetPoolConfig.ORCA_SOL];
|
||||
};
|
||||
// const getOrcaPoolParams = (inputToken: string, outputToken: string) => {
|
||||
// return orcaDevnetPoolConfigs[OrcaDevnetPoolConfig.ORCA_SOL];
|
||||
// };
|
||||
|
||||
async function getTokenCount(
|
||||
connection: Connection,
|
||||
poolParams: OrcaPoolParams,
|
||||
inputPoolToken: OrcaPoolToken,
|
||||
outputPoolToken: OrcaPoolToken,
|
||||
): Promise<PoolTokenCount> {
|
||||
if (poolParams.tokens[inputPoolToken.mint.toString()] == undefined) {
|
||||
throw new Error('Input token not part of pool');
|
||||
}
|
||||
// async function getTokenCount(
|
||||
// connection: Connection,
|
||||
// poolParams: OrcaPoolParams,
|
||||
// inputPoolToken: OrcaPoolToken,
|
||||
// outputPoolToken: OrcaPoolToken,
|
||||
// ): Promise<PoolTokenCount> {
|
||||
// if (poolParams.tokens[inputPoolToken.mint.toString()] == undefined) {
|
||||
// throw new Error('Input token not part of pool');
|
||||
// }
|
||||
|
||||
if (poolParams.tokens[outputPoolToken.mint.toString()] == undefined) {
|
||||
throw new Error('Output token not part of pool');
|
||||
}
|
||||
// if (poolParams.tokens[outputPoolToken.mint.toString()] == undefined) {
|
||||
// throw new Error('Output token not part of pool');
|
||||
// }
|
||||
|
||||
const accountInfos = await connection.getMultipleAccountsInfo([
|
||||
inputPoolToken.addr,
|
||||
outputPoolToken.addr,
|
||||
]);
|
||||
// const accountInfos = await connection.getMultipleAccountsInfo([
|
||||
// inputPoolToken.addr,
|
||||
// outputPoolToken.addr,
|
||||
// ]);
|
||||
|
||||
const tokens = accountInfos.map((info) =>
|
||||
info != undefined ? deserializeAccount(info.data) : undefined,
|
||||
);
|
||||
const inputTokenAccount = tokens[0],
|
||||
outputTokenAccount = tokens[1];
|
||||
// const tokens = accountInfos.map((info) =>
|
||||
// info != undefined ? deserializeAccount(info.data) : undefined,
|
||||
// );
|
||||
// const inputTokenAccount = tokens[0],
|
||||
// outputTokenAccount = tokens[1];
|
||||
|
||||
if (inputTokenAccount === undefined || outputTokenAccount === undefined) {
|
||||
throw new Error('Unable to fetch accounts for specified tokens.');
|
||||
}
|
||||
// if (inputTokenAccount === undefined || outputTokenAccount === undefined) {
|
||||
// throw new Error('Unable to fetch accounts for specified tokens.');
|
||||
// }
|
||||
|
||||
return {
|
||||
inputTokenCount: inputTokenAccount.amount,
|
||||
outputTokenCount: outputTokenAccount.amount,
|
||||
};
|
||||
}
|
||||
// return {
|
||||
// inputTokenCount: inputTokenAccount.amount,
|
||||
// outputTokenCount: outputTokenAccount.amount,
|
||||
// };
|
||||
// }
|
||||
|
||||
const deserializeAccount = (
|
||||
data: Buffer | undefined,
|
||||
): AccountInfo | undefined => {
|
||||
if (data == undefined || data.length == 0) {
|
||||
return undefined;
|
||||
}
|
||||
// const deserializeAccount = (
|
||||
// data: Buffer | undefined,
|
||||
// ): AccountInfo | undefined => {
|
||||
// if (data == undefined || data.length == 0) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
const accountInfo = AccountLayout.decode(data);
|
||||
accountInfo.mint = new PublicKey(accountInfo.mint);
|
||||
accountInfo.owner = new PublicKey(accountInfo.owner);
|
||||
accountInfo.amount = u64.fromBuffer(accountInfo.amount);
|
||||
// const accountInfo = AccountLayout.decode(data);
|
||||
// accountInfo.mint = new PublicKey(accountInfo.mint);
|
||||
// accountInfo.owner = new PublicKey(accountInfo.owner);
|
||||
// accountInfo.amount = u64.fromBuffer(accountInfo.amount);
|
||||
|
||||
return accountInfo;
|
||||
};
|
||||
// return accountInfo;
|
||||
// };
|
||||
|
||||
const ZERO = new BN(0);
|
||||
const ONE = new BN(1);
|
||||
const ceilingDivision = (dividend: u64, divisor: u64): [u64, u64] => {
|
||||
let quotient = dividend.div(divisor);
|
||||
if (quotient.eq(ZERO)) {
|
||||
return [ZERO, divisor];
|
||||
}
|
||||
// const ZERO = new BN(0);
|
||||
// const ONE = new BN(1);
|
||||
// const ceilingDivision = (dividend: u64, divisor: u64): [u64, u64] => {
|
||||
// let quotient = dividend.div(divisor);
|
||||
// if (quotient.eq(ZERO)) {
|
||||
// return [ZERO, divisor];
|
||||
// }
|
||||
|
||||
let remainder = dividend.mod(divisor);
|
||||
if (remainder.gt(ZERO)) {
|
||||
quotient = quotient.add(ONE);
|
||||
divisor = dividend.div(quotient);
|
||||
remainder = dividend.mod(quotient);
|
||||
if (remainder.gt(ZERO)) {
|
||||
divisor = divisor.add(ONE);
|
||||
}
|
||||
}
|
||||
// let remainder = dividend.mod(divisor);
|
||||
// if (remainder.gt(ZERO)) {
|
||||
// quotient = quotient.add(ONE);
|
||||
// divisor = dividend.div(quotient);
|
||||
// remainder = dividend.mod(quotient);
|
||||
// if (remainder.gt(ZERO)) {
|
||||
// divisor = divisor.add(ONE);
|
||||
// }
|
||||
// }
|
||||
|
||||
return [quotient, divisor];
|
||||
};
|
||||
// return [quotient, divisor];
|
||||
// };
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
import { OrcaToken } from '@orca-so/sdk';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
// import { OrcaToken } from '@orca-so/sdk';
|
||||
// import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
/**
|
||||
* The following content is auto-generated.
|
||||
*/
|
||||
// /**
|
||||
// * The following content is auto-generated.
|
||||
// */
|
||||
|
||||
export const ethToken: OrcaToken = Object.freeze({
|
||||
tag: 'ETH',
|
||||
name: 'Ethereum',
|
||||
mint: new PublicKey('Ff5JqsAYUD4vAfQUtfRprT4nXu9e28tTBZTDFMnJNdvd'),
|
||||
scale: 9,
|
||||
});
|
||||
// export const ethToken: OrcaToken = Object.freeze({
|
||||
// tag: 'ETH',
|
||||
// name: 'Ethereum',
|
||||
// mint: new PublicKey('Ff5JqsAYUD4vAfQUtfRprT4nXu9e28tTBZTDFMnJNdvd'),
|
||||
// scale: 9,
|
||||
// });
|
||||
|
||||
export const orcaToken: OrcaToken = Object.freeze({
|
||||
tag: 'ORCA',
|
||||
name: 'Orca',
|
||||
mint: new PublicKey('orcarKHSqC5CDDsGbho8GKvwExejWHxTqGzXgcewB9L'),
|
||||
scale: 6,
|
||||
});
|
||||
// export const orcaToken: OrcaToken = Object.freeze({
|
||||
// tag: 'ORCA',
|
||||
// name: 'Orca',
|
||||
// mint: new PublicKey('orcarKHSqC5CDDsGbho8GKvwExejWHxTqGzXgcewB9L'),
|
||||
// scale: 6,
|
||||
// });
|
||||
|
||||
export const solToken: OrcaToken = Object.freeze({
|
||||
tag: 'SOL',
|
||||
name: 'Solana',
|
||||
mint: new PublicKey('So11111111111111111111111111111111111111112'),
|
||||
scale: 9,
|
||||
});
|
||||
// export const solToken: OrcaToken = Object.freeze({
|
||||
// tag: 'SOL',
|
||||
// name: 'Solana',
|
||||
// mint: new PublicKey('So11111111111111111111111111111111111111112'),
|
||||
// scale: 9,
|
||||
// });
|
||||
|
||||
export const usdcToken: OrcaToken = Object.freeze({
|
||||
tag: 'USDC',
|
||||
name: 'USD Coin',
|
||||
mint: new PublicKey('EmXq3Ni9gfudTiyNKzzYvpnQqnJEMRw2ttnVXoJXjLo1'),
|
||||
scale: 6,
|
||||
});
|
||||
// export const usdcToken: OrcaToken = Object.freeze({
|
||||
// tag: 'USDC',
|
||||
// name: 'USD Coin',
|
||||
// mint: new PublicKey('EmXq3Ni9gfudTiyNKzzYvpnQqnJEMRw2ttnVXoJXjLo1'),
|
||||
// scale: 6,
|
||||
// });
|
||||
|
||||
export const usdtToken: OrcaToken = Object.freeze({
|
||||
tag: 'USDT',
|
||||
name: 'Tether USD',
|
||||
mint: new PublicKey('6PE3Mwjzx9h8kCoBp5YPed9TFoG7du8L98yucBP5ps3x'),
|
||||
scale: 6,
|
||||
});
|
||||
// export const usdtToken: OrcaToken = Object.freeze({
|
||||
// tag: 'USDT',
|
||||
// name: 'Tether USD',
|
||||
// mint: new PublicKey('6PE3Mwjzx9h8kCoBp5YPed9TFoG7du8L98yucBP5ps3x'),
|
||||
// scale: 6,
|
||||
// });
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// import { Connection, PublicKey } from '@solana/web3.js';
|
||||
|
||||
// export const getSerumOutputAmount = async (
|
||||
// connection: Connection,
|
||||
// inputMint: string,
|
||||
// outputToken: string,
|
||||
// amountIn: number,
|
||||
// ): Promise<number> => {
|
||||
// // TODO: select the correct pool params based on passed in banks
|
||||
// const poolParams = getOrcaPoolParams(inputToken, outputToken);
|
||||
|
||||
// const { inputPoolToken, outputPoolToken } = getTokens(
|
||||
// poolParams,
|
||||
// inputMint.mint.toString(),
|
||||
// );
|
||||
|
||||
// const { inputTokenCount, outputTokenCount } = await getTokenCount(
|
||||
// connection,
|
||||
// poolParams,
|
||||
// inputPoolToken,
|
||||
// outputPoolToken,
|
||||
// );
|
||||
|
||||
// const [poolInputAmount, poolOutputAmount] = [
|
||||
// inputTokenCount,
|
||||
// outputTokenCount,
|
||||
// ];
|
||||
|
||||
// const invariant = poolInputAmount.mul(poolOutputAmount);
|
||||
// const nativeAmountIn = toNativeDecimals(amountIn, 9);
|
||||
|
||||
// const [newPoolOutputAmount] = ceilingDivision(
|
||||
// invariant,
|
||||
// poolInputAmount.add(nativeAmountIn),
|
||||
// );
|
||||
|
||||
// const outputAmount = poolOutputAmount.sub(newPoolOutputAmount);
|
||||
|
||||
// return toUiDecimals(outputAmount.toNumber(), 6);
|
||||
// };
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
u64,
|
||||
} from '@solana/spl-token';
|
||||
import { AccountMeta, PublicKey } from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
|
@ -81,7 +80,7 @@ export function toU64(amount: number, decimals): BN {
|
|||
const bn = toNativeDecimals(amount, decimals).toString();
|
||||
console.log('bn', bn);
|
||||
|
||||
return new u64(bn);
|
||||
return new BN(bn);
|
||||
}
|
||||
|
||||
export function nativeI80F48ToUi(amount: I80F48, decimals: number): I80F48 {
|
||||
|
|
Loading…
Reference in New Issue