UNPKG

goosefx-ssl-sdk-prism

Version:

SDK for interacting with GooseFX Single-sided Liquidity pools

291 lines 14.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Swap = exports.deserializeAccount = void 0; const layouts_1 = require("../layouts"); const web3_js_1 = require("@solana/web3.js"); const buffer_1 = require("buffer"); const constants_1 = require("../constants"); const utils_1 = require("./utils"); const gfx_ssl_wasm_data_1 = __importDefault(require("../wasm/gfx_ssl_wasm_data")); const gfx_ssl_wasm_1 = __importStar(require("../wasm/gfx_ssl_wasm")), wasm = gfx_ssl_wasm_1; const ssl_1 = require("./ssl"); const borsh_1 = require("@project-serum/borsh"); let wasmInited = false; function deserializeAccount(account) { const TOKEN_ACCOUNT_LAYOUT = (0, borsh_1.struct)([ (0, borsh_1.publicKey)("mint"), (0, borsh_1.publicKey)("authority"), (0, borsh_1.u64)("amount"), (0, borsh_1.publicKey)("delegate"), (0, borsh_1.u8)("state"), (0, borsh_1.u64)("isNative"), (0, borsh_1.u64)("delegatedAmount"), (0, borsh_1.publicKey)("closeAuthority"), ]); return TOKEN_ACCOUNT_LAYOUT.decode(account); } exports.deserializeAccount = deserializeAccount; class Swap { constructor(connection, controller = constants_1.ADDRESSES["MAINNET"].GFX_CONTROLLER, programId = constants_1.ADDRESSES["MAINNET"].SSL_PROGRAM_ID) { this.connection = connection; this.controller = controller; this.programId = programId; this.getPairAddress = (tokenA, tokenB) => { const addresses = [tokenA.toBuffer(), tokenB.toBuffer()].sort(buffer_1.Buffer.compare); const pairArr = web3_js_1.PublicKey.findProgramAddressSync([ buffer_1.Buffer.from("GFX-SSL-Pair", "utf-8"), this.controller.toBuffer(), addresses[0], addresses[1], ], this.programId); return pairArr[0]; }; this.getQuoterSync = (tokenIn, tokenOut) => { let wasm = this.getWasm(); return new Quoter(this.connection, this.programId, this.controller, tokenIn, tokenOut, wasm); }; this.getQuoter = (tokenIn, tokenOut) => __awaiter(this, void 0, void 0, function* () { let wasm = yield this.getWasm(); return new Quoter(this.connection, this.programId, this.controller, tokenIn, tokenOut, wasm); }); this.getQuote = (tokenIn, tokenOut, inTokenAmount) => __awaiter(this, void 0, void 0, function* () { const quoter = yield this.getQuoter(tokenIn, tokenOut); yield quoter.prepare(); return quoter.quote(inTokenAmount); }); this.getMinimumQuote = (tokenA, tokenB, inTokenAmount, slippage) => __awaiter(this, void 0, void 0, function* () { const result = yield this.getQuote(tokenA, tokenB, inTokenAmount); const minAmountOut = (result.out * (10000n - BigInt(slippage * 10000))) / 10000n; return minAmountOut; }); } getWasm() { return __awaiter(this, void 0, void 0, function* () { if (!wasmInited) { yield (0, gfx_ssl_wasm_1.default)(buffer_1.Buffer.from(gfx_ssl_wasm_data_1.default, "base64")); wasmInited = true; } return wasm; }); } getWasmSync() { return wasm; } } exports.Swap = Swap; class Quoter { constructor(connection, programId, controller, tokenIn, tokenOut, wasm) { this.connection = connection; this.programId = programId; this.controller = controller; this.tokenIn = tokenIn; this.tokenOut = tokenOut; this.wasm = wasm; this.prepared = undefined; this.getPairAddress = (tokenA, tokenB) => { const addresses = [tokenA.toBuffer(), tokenB.toBuffer()].sort(buffer_1.Buffer.compare); const pairArr = web3_js_1.PublicKey.findProgramAddressSync([ buffer_1.Buffer.from("GFX-SSL-Pair", "utf-8"), this.controller.toBuffer(), addresses[0], addresses[1], ], this.programId); return pairArr[0]; }; } getAccountsForUpdate(pairData) { let accounts = []; const pair = this.getPairAddress(this.tokenIn, this.tokenOut); accounts.push(pair); const sslIn = ssl_1.SSL.findAddress(this.controller, this.tokenIn, this.programId); accounts.push(sslIn); const sslOut = ssl_1.SSL.findAddress(this.controller, this.tokenOut, this.programId); accounts.push(sslOut); accounts.push((0, utils_1.findAssociatedTokenAddress)(sslIn, this.tokenIn)); accounts.push((0, utils_1.findAssociatedTokenAddress)(sslIn, this.tokenOut)); accounts.push((0, utils_1.findAssociatedTokenAddress)(sslOut, this.tokenOut)); accounts.push((0, utils_1.findAssociatedTokenAddress)(sslOut, this.tokenIn)); const decoded = layouts_1.PAIR_LAYOUT.decode(pairData.data); let oracles = decoded.oracles; let nOracle = decoded.nOracle; const n = Number(nOracle.toString()); for (const oracle of oracles.slice(0, n)) { const n = Number(oracle.n); for (const elem of oracle.elements.slice(0, n)) { accounts.push(elem.address); } } return accounts; } prepareSync(parsedAccounts) { var _a, _b, _c, _d; const pairData = parsedAccounts[0]; const sslInData = parsedAccounts[1]; const sslOutData = parsedAccounts[2]; const liabilityVaultIn = parsedAccounts[3]; const swappedLiabilityVaultIn = parsedAccounts[4]; const liabilityVaultOut = parsedAccounts[5]; const swappedLiabilityVaultOut = parsedAccounts[6]; const OracleRegistry = wasm.OracleRegistry; const decoded = layouts_1.PAIR_LAYOUT.decode(pairData.data); let oracles = decoded.oracles; let nOracle = decoded.nOracle; const n = Number(nOracle.toString()); const registry = new OracleRegistry(); let count = 7; for (const oracle of oracles.slice(0, n)) { const n = Number(oracle.n); for (const elem of oracle.elements.slice(0, n)) { const acctInfo = parsedAccounts[count]; count++; if (acctInfo === null || acctInfo === void 0 ? void 0 : acctInfo.data) { registry.add_oracle(elem.address.toBuffer(), acctInfo.data); } } } this.prepared = { pairData: pairData.data, sslInData: sslInData.data, sslOutData: sslOutData.data, liabilityIn: BigInt((_a = deserializeAccount(liabilityVaultIn.data)) === null || _a === void 0 ? void 0 : _a.amount.toString()), swappedLiabilityIn: BigInt((_b = deserializeAccount(swappedLiabilityVaultIn.data)) === null || _b === void 0 ? void 0 : _b.amount.toString()), liabilityOut: BigInt((_c = deserializeAccount(liabilityVaultOut.data)) === null || _c === void 0 ? void 0 : _c.amount.toString()), swappedLiabilityOut: BigInt((_d = deserializeAccount(swappedLiabilityVaultOut.data)) === null || _d === void 0 ? void 0 : _d.amount.toString()), registry: registry, suspended: (new ssl_1.SSL(sslInData)).isSuspended() || (new ssl_1.SSL(sslOutData)).isSuspended(), }; } prepare() { var _a, _b, _c, _d; return __awaiter(this, void 0, void 0, function* () { const pair = this.getPairAddress(this.tokenIn, this.tokenOut); const pairData = yield this.connection.getAccountInfo(pair); if (!pairData) throw "Cannot get Pair"; const sslIn = ssl_1.SSL.findAddress(this.controller, this.tokenIn, this.programId); const sslInData = yield this.connection.getAccountInfo(sslIn); if (!sslInData) throw "Cannot get SSL for tokenIn"; const sslOut = ssl_1.SSL.findAddress(this.controller, this.tokenOut, this.programId); const sslOutData = yield this.connection.getAccountInfo(sslOut); if (!sslOutData) throw "Cannot get SSL for tokenOut"; const liabilityVaultIn = yield this.connection.getAccountInfo((0, utils_1.findAssociatedTokenAddress)(sslIn, this.tokenIn)); const swappedLiabilityVaultIn = yield this.connection.getAccountInfo((0, utils_1.findAssociatedTokenAddress)(sslIn, this.tokenOut)); const liabilityVaultOut = yield this.connection.getAccountInfo((0, utils_1.findAssociatedTokenAddress)(sslOut, this.tokenOut)); const swappedLiabilityVaultOut = yield this.connection.getAccountInfo((0, utils_1.findAssociatedTokenAddress)(sslOut, this.tokenIn)); const OracleRegistry = wasm.OracleRegistry; const decoded = layouts_1.PAIR_LAYOUT.decode(pairData.data); let oracles = decoded.oracles; let nOracle = decoded.nOracle; const n = Number(nOracle.toString()); const registry = new OracleRegistry(); for (const oracle of oracles.slice(0, n)) { const n = Number(oracle.n); for (const elem of oracle.elements.slice(0, n)) { const acctInfo = yield this.connection.getAccountInfo(elem.address); if (acctInfo === null || acctInfo === void 0 ? void 0 : acctInfo.data) { registry.add_oracle(elem.address.toBuffer(), acctInfo.data); } } } this.prepared = { pairData: pairData.data, sslInData: sslInData.data, sslOutData: sslOutData.data, liabilityIn: BigInt((_a = deserializeAccount(liabilityVaultIn.data)) === null || _a === void 0 ? void 0 : _a.amount.toString()), swappedLiabilityIn: BigInt((_b = deserializeAccount(swappedLiabilityVaultIn.data)) === null || _b === void 0 ? void 0 : _b.amount.toString()), liabilityOut: BigInt((_c = deserializeAccount(liabilityVaultOut.data)) === null || _c === void 0 ? void 0 : _c.amount.toString()), swappedLiabilityOut: BigInt((_d = deserializeAccount(swappedLiabilityVaultOut.data)) === null || _d === void 0 ? void 0 : _d.amount.toString()), registry: registry, suspended: (new ssl_1.SSL(sslInData)).isSuspended() || (new ssl_1.SSL(sslOutData)).isSuspended(), }; }); } isSuspended() { if (this.prepared === undefined) throw "Run prepare first"; return this.prepared.suspended; } quote(inTokenAmount, silent = true) { const swapWASM = wasm.swap; if (inTokenAmount === BigInt(0)) return { amountIn: BigInt(0), fee: BigInt(0), amountOut: BigInt(0), impact: 0, swapPrice: 0, instantPrice: 0, oraclePrice: 0, }; if (this.prepared === undefined) throw "Run prepare first"; const prepared = this.prepared; let out; try { out = swapWASM(prepared.sslInData.slice(), prepared.sslOutData.slice(), prepared.pairData.slice(), prepared.liabilityIn, prepared.liabilityOut, prepared.swappedLiabilityIn, prepared.swappedLiabilityOut, prepared.registry, inTokenAmount); } catch (e) { if (silent) { return { amountIn: inTokenAmount, fee: BigInt(0), amountOut: BigInt(0), impact: 1, swapPrice: 0, instantPrice: 0, oraclePrice: 0, }; } else { throw e; } } return { amountIn: out.amount_in, fee: out.fee_paid, amountOut: out.amount_out, impact: out.price_impact, swapPrice: out.swap_price, instantPrice: out.insta_price, oraclePrice: out.oracle_price, }; } } //# sourceMappingURL=swap.js.map