@mercurial-finance/dynamic-amm-sdk
Version:
Mercurial Vaults SDK is a typescript library that allows you to interact with Mercurial v2's AMM.
103 lines • 5.43 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const web3_js_1 = require("@solana/web3.js");
const bn_js_1 = __importDefault(require("bn.js"));
const anchor_1 = require("@coral-xyz/anchor");
const amm_1 = __importDefault(require("../amm"));
const constants_1 = require("../amm/constants");
const utils_1 = require("../amm/utils");
const fs_1 = __importDefault(require("fs"));
function loadKeypairFromFile(filename) {
const secret = JSON.parse(fs_1.default.readFileSync(filename).toString());
const secretKey = Uint8Array.from(secret);
return web3_js_1.Keypair.fromSecretKey(secretKey);
}
const mainnetConnection = new web3_js_1.Connection('https://api.devnet.solana.com');
const payerKP = loadKeypairFromFile('~/.config/solana/id.json');
const payerWallet = new anchor_1.Wallet(payerKP);
console.log('payer %s', payerKP.publicKey);
const provider = new anchor_1.AnchorProvider(mainnetConnection, payerWallet, {
commitment: 'confirmed',
});
function fromAllocationsToAmount(lpAmount, allocations) {
const sumPercentage = allocations.reduce((partialSum, a) => partialSum + a.percentage, 0);
if (sumPercentage === 0) {
throw Error('sumPercentage is zero');
}
let amounts = [];
let sum = new bn_js_1.default(0);
for (let i = 0; i < allocations.length - 1; i++) {
const amount = lpAmount.mul(new bn_js_1.default(allocations[i].percentage)).div(new bn_js_1.default(sumPercentage));
sum = sum.add(amount);
amounts.push({
address: allocations[i].address,
amount,
});
}
// the last wallet get remaining amount
amounts.push({
address: allocations[allocations.length - 1].address,
amount: lpAmount.sub(sum),
});
return amounts;
}
async function createPoolAndLockLiquidity(tokenAMint, tokenBMint, tokenAAmount, tokenBAmount, config, allocations) {
const programID = new web3_js_1.PublicKey(constants_1.PROGRAM_ID);
const poolPubkey = (0, utils_1.derivePoolAddressWithConfig)(tokenAMint, tokenBMint, config, programID);
// Create the pool
console.log('create pool %s', poolPubkey);
let transactions = await amm_1.default.createPermissionlessConstantProductPoolWithConfig(provider.connection, payerWallet.publicKey, tokenAMint, tokenBMint, tokenAAmount, tokenBAmount, config);
for (const transaction of transactions) {
transaction.sign(payerWallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
// Create escrow and lock liquidity
const [lpMint] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from(constants_1.SEEDS.LP_MINT), poolPubkey.toBuffer()], programID);
const payerPoolLp = await (0, utils_1.getAssociatedTokenAccount)(lpMint, payerWallet.publicKey);
const payerPoolLpBalance = (await provider.connection.getTokenAccountBalance(payerPoolLp)).value.amount;
console.log('payerPoolLpBalance %s', payerPoolLpBalance.toString());
let allocationByAmounts = fromAllocationsToAmount(new bn_js_1.default(payerPoolLpBalance), allocations);
const pool = await amm_1.default.create(provider.connection, poolPubkey);
for (const allocation of allocationByAmounts) {
console.log('Lock liquidity %s', allocation.address.toString());
let transaction = await pool.lockLiquidity(allocation.address, allocation.amount, payerWallet.publicKey);
transaction.sign(payerWallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
}
/**
* Example script to create a new pool and lock liquidity to it
*/
async function main() {
// 1. Token A/B address of the pool.
const tokenAMint = new web3_js_1.PublicKey('BjhBG7jkHYMBMos2HtRdFrw8rvSguBe5c3a3EJYXhyUf');
const tokenBMint = new web3_js_1.PublicKey('9KMeJp868Pdk8PrJEkwoAHMA1ctdxfVhe2TjeS4BcWjs');
// 2. Configuration address for the pool. It will decide the fees of the pool.
const config = new web3_js_1.PublicKey('21PjsfQVgrn56jSypUT5qXwwSjwKWvuoBCKbVZrgTLz4');
// 3. Allocation of the locked LP to multiple address. In the below example
// 4sBMz7zmDWPzdEnECJW3NA9mEcNwkjYtVnL2KySaWYAf will get 80% of the fee of the locked liquidity
// CVV5MxfwA24PsM7iuS2ddssYgySf5SxVJ8PpAwGN2yVy will get 20% of the fee of the locked liquidity
let allocations = [
{
address: new web3_js_1.PublicKey('4sBMz7zmDWPzdEnECJW3NA9mEcNwkjYtVnL2KySaWYAf'),
percentage: 80,
},
{
address: new web3_js_1.PublicKey('CVV5MxfwA24PsM7iuS2ddssYgySf5SxVJ8PpAwGN2yVy'),
percentage: 20,
},
];
// 4. Amount of token A and B to be deposited to the pool, and will be locked.
let tokenAAmount = new bn_js_1.default(100_000);
let tokenBAmount = new bn_js_1.default(500_000);
await createPoolAndLockLiquidity(tokenAMint, tokenBMint, tokenAAmount, tokenBAmount, config, allocations);
}
main();
//# sourceMappingURL=create_pool_and_lock_liquidity.js.map