From a47367156bbf4210db32e2088021ed77f4403ace Mon Sep 17 00:00:00 2001 From: 0xshiba1 <158560741+0xshiba1@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:14:38 +0800 Subject: [PATCH] refactor sdk and cli as separate projects --- .gitignore | 38 ++- bun.lockb | Bin 0 -> 138344 bytes cli/.eslintrc.json | 38 +++ cli/.gitignore | 38 +++ cli/package.json | 38 +++ cli/prepublish.ts | 29 +++ cli/src/index.ts | 338 +++++++++++++++++++++++++ cli/tsconfig.json | 15 ++ package.json | 17 ++ sdk/bun.lockb | Bin 137149 -> 0 bytes sdk/package.json | 8 - sdk/prepublish.ts | 29 +++ sdk/src/createNewLst.ts | 3 +- sdk/src/functions.ts | 294 ---------------------- sdk/src/index.ts | 544 ++++++++++++++++++---------------------- 15 files changed, 830 insertions(+), 599 deletions(-) create mode 100755 bun.lockb create mode 100644 cli/.eslintrc.json create mode 100644 cli/.gitignore create mode 100644 cli/package.json create mode 100644 cli/prepublish.ts create mode 100644 cli/src/index.ts create mode 100644 cli/tsconfig.json create mode 100644 package.json delete mode 100755 sdk/bun.lockb create mode 100644 sdk/prepublish.ts delete mode 100644 sdk/src/functions.ts diff --git a/.gitignore b/.gitignore index 9e91684..838e9e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,36 @@ -build -suilend-cli/node_modules +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +**node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..a56567e8154485d227eabf633a372abd177c0f11 GIT binary patch literal 138344 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 = { + ".": "./index.js", +}; +const files = ( + fs.readdirSync("./dist/", { recursive: true }) as string[] +).filter((file) => file !== "index.js" && file.endsWith(".js")); +for (const file of files) { + const fileName = file.substring( + 0, + file.endsWith("index.js") + ? file.lastIndexOf("/index.js") + : file.lastIndexOf(".js"), + ); + exportsMap[`./${fileName}`] = `./${file}`; +} +newPackageJson["exports"] = exportsMap as any; + +newPackageJson["types"] = "./index.js"; + +fs.writeFileSync("./dist/package.json", JSON.stringify(newPackageJson), "utf8"); diff --git a/cli/src/index.ts b/cli/src/index.ts new file mode 100644 index 0000000..e8ae9ed --- /dev/null +++ b/cli/src/index.ts @@ -0,0 +1,338 @@ +import { SuiClient } from "@mysten/sui/client"; +import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; +import { Transaction } from "@mysten/sui/transactions"; +import { fromBase64 } from "@mysten/sui/utils"; +import { program } from "commander"; + +import * as sdk from "../../sdk/src"; +import { LstClient } from "../../sdk/src"; +import { PACKAGE_ID } from "../../sdk/src/_generated/liquid_staking"; + +const LIQUID_STAKING_INFO = { + id: "0xdae271405d47f04ab6c824d3b362b7375844ec987a2627845af715fdcd835795", + type: "0xba2a31b3b21776d859c9fdfe797f52b069fe8fe0961605ab093ca4eb437d2632::ripleys::RIPLEYS", + weightHookId: + "0xf244912738939d351aa762dd98c075f873fd95f2928db5fd9e74fbb01c9a686c", +}; + +const RPC_URL = "https://fullnode.mainnet.sui.io"; + +const keypair = Ed25519Keypair.fromSecretKey( + fromBase64(process.env.SUI_SECRET_KEY!), +); + +async function mint(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const tx = new Transaction(); + const [sui] = tx.splitCoins(tx.gas, [BigInt(options.amount)]); + const rSui = lstClient.mint(tx, sui); + tx.transferObjects([rSui], keypair.toSuiAddress()); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function redeem(options: any) { + const client = new SuiClient({ url: RPC_URL }); + + const lstCoins = await client.getCoins({ + owner: keypair.toSuiAddress(), + coinType: LIQUID_STAKING_INFO.type, + limit: 1000, + }); + + const tx = new Transaction(); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + if (lstCoins.data.length > 1) { + tx.mergeCoins( + lstCoins.data[0].coinObjectId, + lstCoins.data.slice(1).map((c) => c.coinObjectId), + ); + } + + const [lst] = tx.splitCoins(lstCoins.data[0].coinObjectId, [ + BigInt(options.amount), + ]); + const sui = lstClient.redeemLst(tx, lst); + + tx.transferObjects([sui], keypair.toSuiAddress()); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function increaseValidatorStake(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); + if (!adminCapId) return; + + const tx = new Transaction(); + lstClient.increaseValidatorStake( + tx, + adminCapId, + options.validatorAddress, + options.amount, + ); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function decreaseValidatorStake(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); + if (!adminCapId) return; + + const tx = new Transaction(); + lstClient.decreaseValidatorStake( + tx, + adminCapId, + options.validatorIndex, + options.amount, + ); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function updateFees(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const adminCap = ( + await client.getOwnedObjects({ + owner: keypair.toSuiAddress(), + filter: { + StructType: `${PACKAGE_ID}::liquid_staking::AdminCap<${LIQUID_STAKING_INFO.type}>`, + }, + }) + ).data[0]; + const adminCapId = adminCap.data?.objectId; + if (!adminCapId) return; + + const tx = new Transaction(); + lstClient.updateFees(tx, adminCapId, options); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function initializeWeightHook(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); + if (!adminCapId) return; + + const tx = new Transaction(); + const weightHookAdminCap = lstClient.initializeWeightHook(tx, adminCapId); + tx.transferObjects([weightHookAdminCap], keypair.toSuiAddress()); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function setValidatorAddressesAndWeights(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + if (options.validators.length != options.weights.length) { + throw new Error("Validators and weights arrays must be of the same length"); + } + + const validatorAddressesAndWeights = new Map(); + for (let i = 0; i < options.validators.length; i++) { + validatorAddressesAndWeights.set( + options.validators[i], + options.weights[i] as number, + ); + } + + console.log(validatorAddressesAndWeights); + + const weightHookAdminCapId = await lstClient.getWeightHookAdminCapId( + keypair.toSuiAddress(), + ); + if (!weightHookAdminCapId) return; + + const tx = new Transaction(); + lstClient.setValidatorAddressesAndWeights( + tx, + LIQUID_STAKING_INFO.weightHookId, + weightHookAdminCapId, + validatorAddressesAndWeights, + ); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +async function rebalance(options: any) { + const client = new SuiClient({ url: RPC_URL }); + const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + + const tx = new Transaction(); + lstClient.rebalance(tx, LIQUID_STAKING_INFO.weightHookId); + + const txResponse = await client.signAndExecuteTransaction({ + transaction: tx, + signer: keypair, + options: { + showEvents: true, + showEffects: true, + showObjectChanges: true, + }, + }); + + console.log(txResponse); +} + +program.version("1.0.0").description("Spring Sui CLI"); + +program + .command("mint") + .description("mint some rSui") + .option("--amount ", "Amount of SUI in MIST") + .action(mint); + +program + .command("redeem") + .description("redeem some SUI") + .option("--amount ", "Amount of LST to redeem") + .action(redeem); + +program + .command("increase-validator-stake") + .description("increase validator stake") + .option("--validator-address ", "Validator address") + .option("--amount ", "Amount of SUI to delegate to validator") + .action(increaseValidatorStake); + +program + .command("decrease-validator-stake") + .description("decrease validator stake") + .option("--validator-index ", "Validator index") + .option("--amount ", "Amount of SUI to undelegate from validator") + .action(decreaseValidatorStake); + +program + .command("update-fees") + .description("update fees") + .option("--mint-fee-bps ", "Mint fee bps") + .option("--redeem-fee-bps ", "Redeem fee bps") + .option("--spread-fee ", "Spread fee") + .action(updateFees); + +program + .command("fetch-state") + .description("fetch the current state of the liquid staking pool") + .action(async () => { + const client = new SuiClient({ url: RPC_URL }); + try { + const state = await sdk.fetchLiquidStakingInfo( + LIQUID_STAKING_INFO, + client, + ); + console.log("Current Liquid Staking State:"); + console.log(JSON.stringify(state, null, 2)); + } catch (error) { + console.error("Error fetching state:", error); + } + }); + +program + .command("initialize-weight-hook") + .description("initialize weight hook") + .action(initializeWeightHook); + +function collect(pair: any, previous: any) { + const [key, value] = pair.split("="); + if (!value) { + throw new Error(`Invalid format for ${pair}. Use key=value format.`); + } + return { ...previous, [key]: value }; +} + +program + .command("set-validator-addresses-and-weights") + .description("set validator addresses and weights") + .option("-v, --validators ", "Validator addresses") + .option("-w, --weights ", "Weights") + .action(setValidatorAddressesAndWeights); + +program + .command("rebalance") + .description("rebalance the validator set") + .action(rebalance); + +program.parse(process.argv); diff --git a/cli/tsconfig.json b/cli/tsconfig.json new file mode 100644 index 0000000..9c37b42 --- /dev/null +++ b/cli/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2016", + "module": "commonjs", + "resolveJsonModule": true, + "declaration": true, + "outDir": "dist", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + }, + "include": ["./src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..67c6804 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "8.57.0", + "eslint-config-next": "14.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "prettier": "^3.2.5" + }, + "private": true, + "workspaces": [ + "cli", + "sdk" + ] +} diff --git a/sdk/bun.lockb b/sdk/bun.lockb deleted file mode 100755 index 00a2372cd15376a7cf32d0fad0399aa5fe169357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137149 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 Se1jDKbx`47#QJ~upZ^6-c`qpd diff --git a/sdk/package.json b/sdk/package.json index bb643de..3e45947 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -32,14 +32,6 @@ }, "devDependencies": { "@types/node": "^20.12.7", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.0.0", - "eslint": "8.57.0", - "eslint-config-next": "14.1.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^5.1.3", - "prettier": "^3.2.5", "ts-node": "^10.9.2", "typescript": "^5.3.3" } diff --git a/sdk/prepublish.ts b/sdk/prepublish.ts new file mode 100644 index 0000000..e8b8aac --- /dev/null +++ b/sdk/prepublish.ts @@ -0,0 +1,29 @@ +import fs from "fs"; + +// 1. Update package.json +import packageJson from "./package.json"; +const newPackageJson = Object.assign({}, packageJson); + +newPackageJson["private"] = false; +newPackageJson["main"] = "./index.js"; + +const exportsMap: Record = { + ".": "./index.js", +}; +const files = ( + fs.readdirSync("./dist/", { recursive: true }) as string[] +).filter((file) => file !== "index.js" && file.endsWith(".js")); +for (const file of files) { + const fileName = file.substring( + 0, + file.endsWith("index.js") + ? file.lastIndexOf("/index.js") + : file.lastIndexOf(".js"), + ); + exportsMap[`./${fileName}`] = `./${file}`; +} +newPackageJson["exports"] = exportsMap as any; + +newPackageJson["types"] = "./index.js"; + +fs.writeFileSync("./dist/package.json", JSON.stringify(newPackageJson), "utf8"); diff --git a/sdk/src/createNewLst.ts b/sdk/src/createNewLst.ts index d9b85ed..3d088ff 100644 --- a/sdk/src/createNewLst.ts +++ b/sdk/src/createNewLst.ts @@ -9,7 +9,8 @@ import { } from "./_generated/liquid_staking/fees/functions"; import * as generated from "./_generated/liquid_staking/liquid-staking/functions"; import { LiquidStakingInfo } from "./_generated/liquid_staking/liquid-staking/structs"; -import { LstClient } from "./functions"; + +import { LstClient } from "./index"; const keypair = Ed25519Keypair.fromSecretKey( fromBase64(process.env.SUI_SECRET_KEY!), diff --git a/sdk/src/functions.ts b/sdk/src/functions.ts deleted file mode 100644 index cae90af..0000000 --- a/sdk/src/functions.ts +++ /dev/null @@ -1,294 +0,0 @@ -import { SuiClient } from "@mysten/sui/client"; -import { Transaction, TransactionObjectInput } from "@mysten/sui/transactions"; - -import { phantom } from "./_generated/_framework/reified"; -import { PACKAGE_ID, setPublishedAt } from "./_generated/liquid_staking"; -import { - newBuilder, - setRedeemFeeBps, - setSpreadFeeBps, - setSuiMintFeeBps, - toFeeConfig, -} from "./_generated/liquid_staking/fees/functions"; -import * as generated from "./_generated/liquid_staking/liquid-staking/functions"; -import { LiquidStakingInfo } from "./_generated/liquid_staking/liquid-staking/structs"; -import * as weightHookGenerated from "./_generated/liquid_staking/weight/functions"; -import { WeightHook } from "./_generated/liquid_staking/weight/structs"; - -export interface LiquidStakingObjectInfo { - id: string; - type: string; -} - -const SUI_SYSTEM_STATE_ID = - "0x0000000000000000000000000000000000000000000000000000000000000005"; -const SUILEND_VALIDATOR_ADDRESS = - "0xce8e537664ba5d1d5a6a857b17bd142097138706281882be6805e17065ecde89"; -const SPRING_SUI_UPGRADE_CAP_ID = - "0x393ea4538463add6f405f2b1e3e6d896e17850975c772135843de26d14cd17c6"; - -async function getLatestPackageId( - client: SuiClient, - upgradeCapId: string, -): Promise { - const object = await client.getObject({ - id: upgradeCapId, - options: { - showContent: true, - }, - }); - - return (object.data?.content as unknown as any).fields.package; -} - -export class LstClient { - liquidStakingObject: LiquidStakingObjectInfo; - client: SuiClient; - - static async initialize( - client: SuiClient, - liquidStakingObjectInfo: LiquidStakingObjectInfo, - ): Promise { - const publishedAt = await getLatestPackageId( - client, - SPRING_SUI_UPGRADE_CAP_ID, - ); - setPublishedAt(publishedAt); - console.log(`Initialized LstClient with package ID: ${publishedAt}`); - - return new LstClient(liquidStakingObjectInfo, client); - } - - constructor(liquidStakingObject: LiquidStakingObjectInfo, client: SuiClient) { - this.liquidStakingObject = liquidStakingObject; - this.client = client; - } - - async getAdminCapId(address: string): Promise { - const res = ( - await this.client.getOwnedObjects({ - owner: address, - filter: { - StructType: `${PACKAGE_ID}::liquid_staking::AdminCap<${this.liquidStakingObject.type}>`, - }, - }) - ).data; - - if (res.length == 0) { - return null; - } - - return res[0].data?.objectId; - } - - async getWeightHookAdminCapId( - address: string, - ): Promise { - const res = ( - await this.client.getOwnedObjects({ - owner: address, - filter: { - StructType: `${PACKAGE_ID}::weight::WeightHookAdminCap<${this.liquidStakingObject.type}>`, - }, - }) - ).data; - - if (res.length == 0) { - return null; - } - - return res[0].data?.objectId; - } - - // returns the lst object - mint(tx: Transaction, suiCoinId: TransactionObjectInput) { - const [rSui] = generated.mint(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - sui: suiCoinId, - systemState: SUI_SYSTEM_STATE_ID, - }); - - return rSui; - } - - // returns the sui coin - redeemLst(tx: Transaction, lstId: TransactionObjectInput) { - const [sui] = generated.redeem(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - systemState: SUI_SYSTEM_STATE_ID, - lst: lstId, - }); - - return sui; - } - - // admin functions - - increaseValidatorStake( - tx: Transaction, - adminCapId: TransactionObjectInput, - validatorAddress: string, - suiAmount: number, - ) { - generated.increaseValidatorStake(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - adminCap: adminCapId, - systemState: SUI_SYSTEM_STATE_ID, - validatorAddress, - suiAmount: BigInt(suiAmount), - }); - } - - decreaseValidatorStake( - tx: Transaction, - adminCapId: TransactionObjectInput, - validatorAddress: string, - maxSuiAmount: number, - ) { - generated.decreaseValidatorStake(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - adminCap: adminCapId, - systemState: SUI_SYSTEM_STATE_ID, - validatorAddress, - maxSuiAmount: BigInt(maxSuiAmount), - }); - } - - collectFees(tx: Transaction, adminCapId: TransactionObjectInput) { - const [sui] = generated.collectFees(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - systemState: SUI_SYSTEM_STATE_ID, - adminCap: adminCapId, - }); - - return sui; - } - - updateFees( - tx: Transaction, - adminCapId: TransactionObjectInput, - feeConfigArgs: FeeConfigArgs, - ) { - let [builder] = newBuilder(tx); - - if (feeConfigArgs.mintFeeBps != null) { - console.log(`Setting mint fee bps to ${feeConfigArgs.mintFeeBps}`); - - builder = setSuiMintFeeBps(tx, { - self: builder, - fee: BigInt(feeConfigArgs.mintFeeBps), - })[0]; - } - - if (feeConfigArgs.redeemFeeBps != null) { - console.log(`Setting redeem fee bps to ${feeConfigArgs.redeemFeeBps}`); - builder = setRedeemFeeBps(tx, { - self: builder, - fee: BigInt(feeConfigArgs.redeemFeeBps), - })[0]; - } - - if (feeConfigArgs.spreadFee != null) { - builder = setSpreadFeeBps(tx, { - self: builder, - fee: BigInt(feeConfigArgs.spreadFee), - })[0]; - } - - const [feeConfig] = toFeeConfig(tx, builder); - - generated.updateFees(tx, this.liquidStakingObject.type, { - self: this.liquidStakingObject.id, - adminCap: adminCapId, - feeConfig, - }); - } - - // weight hook functions - initializeWeightHook(tx: Transaction, adminCapId: TransactionObjectInput) { - const [weightHook, weightHookAdminCap] = weightHookGenerated.new_( - tx, - this.liquidStakingObject.type, - adminCapId, - ); - - tx.moveCall({ - target: `0x2::transfer::public_share_object`, - typeArguments: [ - `${WeightHook.$typeName}<${this.liquidStakingObject.type}>`, - ], - arguments: [weightHook], - }); - - return weightHookAdminCap; - } - - setValidatorAddressesAndWeights( - tx: Transaction, - weightHookId: TransactionObjectInput, - weightHookAdminCap: TransactionObjectInput, - validatorAddressesAndWeights: Map, - ) { - const [vecMap] = tx.moveCall({ - target: `0x2::vec_map::empty`, - typeArguments: ["address", "u64"], - arguments: [], - }); - - for (const [ - validatorAddress, - weight, - ] of validatorAddressesAndWeights.entries()) { - tx.moveCall({ - target: `0x2::vec_map::insert`, - typeArguments: ["address", "u64"], - arguments: [ - vecMap, - tx.pure.address(validatorAddress), - tx.pure.u64(weight), - ], - }); - } - - weightHookGenerated.setValidatorAddressesAndWeights( - tx, - this.liquidStakingObject.type, - { - self: weightHookId, - weightHookAdminCap, - validatorAddressesAndWeights: vecMap, - }, - ); - } - - rebalance(tx: Transaction, weightHookId: TransactionObjectInput) { - weightHookGenerated.rebalance(tx, this.liquidStakingObject.type, { - self: weightHookId, - systemState: SUI_SYSTEM_STATE_ID, - liquidStakingInfo: this.liquidStakingObject.id, - }); - } -} - -// user functions -export async function fetchLiquidStakingInfo( - info: LiquidStakingObjectInfo, - client: SuiClient, -): Promise> { - return LiquidStakingInfo.fetch(client, phantom(info.type), info.id); -} - -interface FeeConfigArgs { - mintFeeBps?: number; - redeemFeeBps?: number; - spreadFee?: number; -} - -// only works for sSui -export async function getSpringSuiApy(client: SuiClient) { - const res = await client.getValidatorsApy(); - const validatorApy = res.apys.find( - (apy) => apy.address == SUILEND_VALIDATOR_ADDRESS, - ); - return validatorApy?.apy; -} diff --git a/sdk/src/index.ts b/sdk/src/index.ts index 316fcf7..cae90af 100644 --- a/sdk/src/index.ts +++ b/sdk/src/index.ts @@ -1,338 +1,294 @@ import { SuiClient } from "@mysten/sui/client"; -import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; -import { Transaction } from "@mysten/sui/transactions"; -import { fromBase64 } from "@mysten/sui/utils"; -import { program } from "commander"; - -import { PACKAGE_ID } from "./_generated/liquid_staking"; -import * as sdk from "./functions"; -import { LstClient } from "./functions"; - -const LIQUID_STAKING_INFO = { - id: "0xdae271405d47f04ab6c824d3b362b7375844ec987a2627845af715fdcd835795", - type: "0xba2a31b3b21776d859c9fdfe797f52b069fe8fe0961605ab093ca4eb437d2632::ripleys::RIPLEYS", - weightHookId: - "0xf244912738939d351aa762dd98c075f873fd95f2928db5fd9e74fbb01c9a686c", -}; - -const RPC_URL = "https://fullnode.mainnet.sui.io"; - -const keypair = Ed25519Keypair.fromSecretKey( - fromBase64(process.env.SUI_SECRET_KEY!), -); - -async function mint(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); - - const tx = new Transaction(); - const [sui] = tx.splitCoins(tx.gas, [BigInt(options.amount)]); - const rSui = lstClient.mint(tx, sui); - tx.transferObjects([rSui], keypair.toSuiAddress()); - - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); - - console.log(txResponse); +import { Transaction, TransactionObjectInput } from "@mysten/sui/transactions"; + +import { phantom } from "./_generated/_framework/reified"; +import { PACKAGE_ID, setPublishedAt } from "./_generated/liquid_staking"; +import { + newBuilder, + setRedeemFeeBps, + setSpreadFeeBps, + setSuiMintFeeBps, + toFeeConfig, +} from "./_generated/liquid_staking/fees/functions"; +import * as generated from "./_generated/liquid_staking/liquid-staking/functions"; +import { LiquidStakingInfo } from "./_generated/liquid_staking/liquid-staking/structs"; +import * as weightHookGenerated from "./_generated/liquid_staking/weight/functions"; +import { WeightHook } from "./_generated/liquid_staking/weight/structs"; + +export interface LiquidStakingObjectInfo { + id: string; + type: string; } -async function redeem(options: any) { - const client = new SuiClient({ url: RPC_URL }); - - const lstCoins = await client.getCoins({ - owner: keypair.toSuiAddress(), - coinType: LIQUID_STAKING_INFO.type, - limit: 1000, - }); - - const tx = new Transaction(); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); - - if (lstCoins.data.length > 1) { - tx.mergeCoins( - lstCoins.data[0].coinObjectId, - lstCoins.data.slice(1).map((c) => c.coinObjectId), - ); - } - - const [lst] = tx.splitCoins(lstCoins.data[0].coinObjectId, [ - BigInt(options.amount), - ]); - const sui = lstClient.redeemLst(tx, lst); - - tx.transferObjects([sui], keypair.toSuiAddress()); - - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, +const SUI_SYSTEM_STATE_ID = + "0x0000000000000000000000000000000000000000000000000000000000000005"; +const SUILEND_VALIDATOR_ADDRESS = + "0xce8e537664ba5d1d5a6a857b17bd142097138706281882be6805e17065ecde89"; +const SPRING_SUI_UPGRADE_CAP_ID = + "0x393ea4538463add6f405f2b1e3e6d896e17850975c772135843de26d14cd17c6"; + +async function getLatestPackageId( + client: SuiClient, + upgradeCapId: string, +): Promise { + const object = await client.getObject({ + id: upgradeCapId, options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, + showContent: true, }, }); - console.log(txResponse); + return (object.data?.content as unknown as any).fields.package; } -async function increaseValidatorStake(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); +export class LstClient { + liquidStakingObject: LiquidStakingObjectInfo; + client: SuiClient; + + static async initialize( + client: SuiClient, + liquidStakingObjectInfo: LiquidStakingObjectInfo, + ): Promise { + const publishedAt = await getLatestPackageId( + client, + SPRING_SUI_UPGRADE_CAP_ID, + ); + setPublishedAt(publishedAt); + console.log(`Initialized LstClient with package ID: ${publishedAt}`); - const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); - if (!adminCapId) return; + return new LstClient(liquidStakingObjectInfo, client); + } - const tx = new Transaction(); - lstClient.increaseValidatorStake( - tx, - adminCapId, - options.validatorAddress, - options.amount, - ); + constructor(liquidStakingObject: LiquidStakingObjectInfo, client: SuiClient) { + this.liquidStakingObject = liquidStakingObject; + this.client = client; + } - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); + async getAdminCapId(address: string): Promise { + const res = ( + await this.client.getOwnedObjects({ + owner: address, + filter: { + StructType: `${PACKAGE_ID}::liquid_staking::AdminCap<${this.liquidStakingObject.type}>`, + }, + }) + ).data; + + if (res.length == 0) { + return null; + } - console.log(txResponse); -} + return res[0].data?.objectId; + } -async function decreaseValidatorStake(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + async getWeightHookAdminCapId( + address: string, + ): Promise { + const res = ( + await this.client.getOwnedObjects({ + owner: address, + filter: { + StructType: `${PACKAGE_ID}::weight::WeightHookAdminCap<${this.liquidStakingObject.type}>`, + }, + }) + ).data; + + if (res.length == 0) { + return null; + } - const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); - if (!adminCapId) return; + return res[0].data?.objectId; + } - const tx = new Transaction(); - lstClient.decreaseValidatorStake( - tx, - adminCapId, - options.validatorIndex, - options.amount, - ); + // returns the lst object + mint(tx: Transaction, suiCoinId: TransactionObjectInput) { + const [rSui] = generated.mint(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + sui: suiCoinId, + systemState: SUI_SYSTEM_STATE_ID, + }); - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); + return rSui; + } - console.log(txResponse); -} + // returns the sui coin + redeemLst(tx: Transaction, lstId: TransactionObjectInput) { + const [sui] = generated.redeem(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + systemState: SUI_SYSTEM_STATE_ID, + lst: lstId, + }); -async function updateFees(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + return sui; + } - const adminCap = ( - await client.getOwnedObjects({ - owner: keypair.toSuiAddress(), - filter: { - StructType: `${PACKAGE_ID}::liquid_staking::AdminCap<${LIQUID_STAKING_INFO.type}>`, - }, - }) - ).data[0]; - const adminCapId = adminCap.data?.objectId; - if (!adminCapId) return; + // admin functions + + increaseValidatorStake( + tx: Transaction, + adminCapId: TransactionObjectInput, + validatorAddress: string, + suiAmount: number, + ) { + generated.increaseValidatorStake(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + adminCap: adminCapId, + systemState: SUI_SYSTEM_STATE_ID, + validatorAddress, + suiAmount: BigInt(suiAmount), + }); + } - const tx = new Transaction(); - lstClient.updateFees(tx, adminCapId, options); + decreaseValidatorStake( + tx: Transaction, + adminCapId: TransactionObjectInput, + validatorAddress: string, + maxSuiAmount: number, + ) { + generated.decreaseValidatorStake(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + adminCap: adminCapId, + systemState: SUI_SYSTEM_STATE_ID, + validatorAddress, + maxSuiAmount: BigInt(maxSuiAmount), + }); + } - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); + collectFees(tx: Transaction, adminCapId: TransactionObjectInput) { + const [sui] = generated.collectFees(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + systemState: SUI_SYSTEM_STATE_ID, + adminCap: adminCapId, + }); - console.log(txResponse); -} + return sui; + } -async function initializeWeightHook(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + updateFees( + tx: Transaction, + adminCapId: TransactionObjectInput, + feeConfigArgs: FeeConfigArgs, + ) { + let [builder] = newBuilder(tx); - const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress()); - if (!adminCapId) return; + if (feeConfigArgs.mintFeeBps != null) { + console.log(`Setting mint fee bps to ${feeConfigArgs.mintFeeBps}`); - const tx = new Transaction(); - const weightHookAdminCap = lstClient.initializeWeightHook(tx, adminCapId); - tx.transferObjects([weightHookAdminCap], keypair.toSuiAddress()); + builder = setSuiMintFeeBps(tx, { + self: builder, + fee: BigInt(feeConfigArgs.mintFeeBps), + })[0]; + } - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); + if (feeConfigArgs.redeemFeeBps != null) { + console.log(`Setting redeem fee bps to ${feeConfigArgs.redeemFeeBps}`); + builder = setRedeemFeeBps(tx, { + self: builder, + fee: BigInt(feeConfigArgs.redeemFeeBps), + })[0]; + } - console.log(txResponse); -} + if (feeConfigArgs.spreadFee != null) { + builder = setSpreadFeeBps(tx, { + self: builder, + fee: BigInt(feeConfigArgs.spreadFee), + })[0]; + } -async function setValidatorAddressesAndWeights(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + const [feeConfig] = toFeeConfig(tx, builder); - if (options.validators.length != options.weights.length) { - throw new Error("Validators and weights arrays must be of the same length"); + generated.updateFees(tx, this.liquidStakingObject.type, { + self: this.liquidStakingObject.id, + adminCap: adminCapId, + feeConfig, + }); } - const validatorAddressesAndWeights = new Map(); - for (let i = 0; i < options.validators.length; i++) { - validatorAddressesAndWeights.set( - options.validators[i], - options.weights[i] as number, + // weight hook functions + initializeWeightHook(tx: Transaction, adminCapId: TransactionObjectInput) { + const [weightHook, weightHookAdminCap] = weightHookGenerated.new_( + tx, + this.liquidStakingObject.type, + adminCapId, ); - } - - console.log(validatorAddressesAndWeights); - - const weightHookAdminCapId = await lstClient.getWeightHookAdminCapId( - keypair.toSuiAddress(), - ); - if (!weightHookAdminCapId) return; - - const tx = new Transaction(); - lstClient.setValidatorAddressesAndWeights( - tx, - LIQUID_STAKING_INFO.weightHookId, - weightHookAdminCapId, - validatorAddressesAndWeights, - ); - - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); - - console.log(txResponse); -} -async function rebalance(options: any) { - const client = new SuiClient({ url: RPC_URL }); - const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO); + tx.moveCall({ + target: `0x2::transfer::public_share_object`, + typeArguments: [ + `${WeightHook.$typeName}<${this.liquidStakingObject.type}>`, + ], + arguments: [weightHook], + }); - const tx = new Transaction(); - lstClient.rebalance(tx, LIQUID_STAKING_INFO.weightHookId); - - const txResponse = await client.signAndExecuteTransaction({ - transaction: tx, - signer: keypair, - options: { - showEvents: true, - showEffects: true, - showObjectChanges: true, - }, - }); - - console.log(txResponse); -} + return weightHookAdminCap; + } -program.version("1.0.0").description("Spring Sui CLI"); - -program - .command("mint") - .description("mint some rSui") - .option("--amount ", "Amount of SUI in MIST") - .action(mint); - -program - .command("redeem") - .description("redeem some SUI") - .option("--amount ", "Amount of LST to redeem") - .action(redeem); - -program - .command("increase-validator-stake") - .description("increase validator stake") - .option("--validator-address ", "Validator address") - .option("--amount ", "Amount of SUI to delegate to validator") - .action(increaseValidatorStake); - -program - .command("decrease-validator-stake") - .description("decrease validator stake") - .option("--validator-index ", "Validator index") - .option("--amount ", "Amount of SUI to undelegate from validator") - .action(decreaseValidatorStake); - -program - .command("update-fees") - .description("update fees") - .option("--mint-fee-bps ", "Mint fee bps") - .option("--redeem-fee-bps ", "Redeem fee bps") - .option("--spread-fee ", "Spread fee") - .action(updateFees); - -program - .command("fetch-state") - .description("fetch the current state of the liquid staking pool") - .action(async () => { - const client = new SuiClient({ url: RPC_URL }); - try { - const state = await sdk.fetchLiquidStakingInfo( - LIQUID_STAKING_INFO, - client, - ); - console.log("Current Liquid Staking State:"); - console.log(JSON.stringify(state, null, 2)); - } catch (error) { - console.error("Error fetching state:", error); + setValidatorAddressesAndWeights( + tx: Transaction, + weightHookId: TransactionObjectInput, + weightHookAdminCap: TransactionObjectInput, + validatorAddressesAndWeights: Map, + ) { + const [vecMap] = tx.moveCall({ + target: `0x2::vec_map::empty`, + typeArguments: ["address", "u64"], + arguments: [], + }); + + for (const [ + validatorAddress, + weight, + ] of validatorAddressesAndWeights.entries()) { + tx.moveCall({ + target: `0x2::vec_map::insert`, + typeArguments: ["address", "u64"], + arguments: [ + vecMap, + tx.pure.address(validatorAddress), + tx.pure.u64(weight), + ], + }); } - }); -program - .command("initialize-weight-hook") - .description("initialize weight hook") - .action(initializeWeightHook); + weightHookGenerated.setValidatorAddressesAndWeights( + tx, + this.liquidStakingObject.type, + { + self: weightHookId, + weightHookAdminCap, + validatorAddressesAndWeights: vecMap, + }, + ); + } -function collect(pair: any, previous: any) { - const [key, value] = pair.split("="); - if (!value) { - throw new Error(`Invalid format for ${pair}. Use key=value format.`); + rebalance(tx: Transaction, weightHookId: TransactionObjectInput) { + weightHookGenerated.rebalance(tx, this.liquidStakingObject.type, { + self: weightHookId, + systemState: SUI_SYSTEM_STATE_ID, + liquidStakingInfo: this.liquidStakingObject.id, + }); } - return { ...previous, [key]: value }; } -program - .command("set-validator-addresses-and-weights") - .description("set validator addresses and weights") - .option("-v, --validators ", "Validator addresses") - .option("-w, --weights ", "Weights") - .action(setValidatorAddressesAndWeights); +// user functions +export async function fetchLiquidStakingInfo( + info: LiquidStakingObjectInfo, + client: SuiClient, +): Promise> { + return LiquidStakingInfo.fetch(client, phantom(info.type), info.id); +} -program - .command("rebalance") - .description("rebalance the validator set") - .action(rebalance); +interface FeeConfigArgs { + mintFeeBps?: number; + redeemFeeBps?: number; + spreadFee?: number; +} -program.parse(process.argv); +// only works for sSui +export async function getSpringSuiApy(client: SuiClient) { + const res = await client.getValidatorsApy(); + const validatorApy = res.apys.find( + (apy) => apy.address == SUILEND_VALIDATOR_ADDRESS, + ); + return validatorApy?.apy; +}