Skip to content

Commit

Permalink
prepare sdk (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xshiba1 authored Oct 30, 2024
1 parent 783dcf3 commit 0470f8d
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 409 deletions.
15 changes: 15 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",

"eslint.format.enable": true,
"eslint.validate": ["typescript", "typescriptreact"],

"[typescript][typescriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"typescript.tsdk": "node_modules/typescript/lib"
}
38 changes: 38 additions & 0 deletions sdk/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"ignorePatterns": ["_generated"],
"extends": [
"prettier",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["prettier"],
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "warn",
"prettier/prettier": ["error"],
"import/order": [
"error",
{
"pathGroups": [],
"groups": [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"object",
"type"
],
"newlines-between": "always",
"alphabetize": { "order": "asc", "caseInsensitive": true }
}
],
"sort-imports": [
"error",
{
"ignoreDeclarationSort": true
}
]
}
}
39 changes: 38 additions & 1 deletion sdk/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,38 @@
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

dist/
1 change: 1 addition & 0 deletions sdk/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_generated
Binary file added sdk/bun.lockb
Binary file not shown.
33 changes: 31 additions & 2 deletions sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
{
"name": "sdk",
"name": "@suilend/springsui-sdk",
"version": "1.0.0",
"main": "index.js",
"private": true,
"description": "A TypeScript SDK for interacting with the SpringSui program",
"author": "Suilend",
"license": "MIT",
"main": "./src/index.ts",
"exports": {
".": "./src/index.js"
},
"types": "./src/index.ts",
"scripts": {
"build": "rm -rf ./dist && bun tsc",
"eslint": "eslint --fix \"./src/**/*.ts\"",
"prettier": "prettier --write \"./src/**/*\"",
"lint": "bun eslint && bun prettier && bun tsc",
"release": "bun run build && bun ts-node ./prepublish.ts && cd ./dist && npm publish --access public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/solendprotocol/liquid-staking.git"
},
"bugs": {
"url": "https://github.com/solendprotocol/liquid-staking/issues"
},
"dependencies": {
"@mysten/bcs": "1.1.0",
"@mysten/sui": "1.12.0",
Expand All @@ -11,6 +32,14 @@
},
"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"
}
Expand Down
68 changes: 34 additions & 34 deletions sdk/src/createNewLst.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
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 {
Transaction,
TransactionObjectInput,
TransactionResult,
} from "@mysten/sui/transactions";
newBuilder,
toFeeConfig,
} from "./_generated/liquid_staking/fees/functions";
import * as generated from "./_generated/liquid_staking/liquid-staking/functions";
import { newBuilder, setRedeemFeeBps, setSpreadFeeBps, setSuiMintFeeBps, toFeeConfig } from "./_generated/liquid_staking/fees/functions";
import { fromBase64 } from "@mysten/sui/utils";
import { LiquidStakingInfo } from "./_generated/liquid_staking/liquid-staking/structs";
import { phantom } from "./_generated/_framework/reified";
import { fetchLiquidStakingInfo, getSpringSuiApy, LstClient } from "./functions";
import { PACKAGE_ID } from "./_generated/liquid_staking";
import { LstClient } from "./functions";

const keypair = Ed25519Keypair.fromSecretKey(
fromBase64(process.env.SUI_SECRET_KEY!)
fromBase64(process.env.SUI_SECRET_KEY!),
);

const LIQUID_STAKING_INFO = {
Expand All @@ -23,65 +21,67 @@ const LIQUID_STAKING_INFO = {
};

async function createNewLst() {
let client = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
let tx = new Transaction();
const client = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
const tx = new Transaction();

const [feeConfigBuilder] = newBuilder(tx);
const [feeConfig] = toFeeConfig(tx, feeConfigBuilder);

let [feeConfigBuilder] = newBuilder(tx);
let [feeConfig] = toFeeConfig(tx, feeConfigBuilder);

let liquidStakingInfoType = "0xba2a31b3b21776d859c9fdfe797f52b069fe8fe0961605ab093ca4eb437d2632::ripleys::RIPLEYS";
let [adminCap, liquidStakingInfo] = generated.createLst(
const liquidStakingInfoType =
"0xba2a31b3b21776d859c9fdfe797f52b069fe8fe0961605ab093ca4eb437d2632::ripleys::RIPLEYS";
const [adminCap, liquidStakingInfo] = generated.createLst(
tx,
liquidStakingInfoType,
{
feeConfig,
lstTreasuryCap: "0x272a461ab0f142c5bae0e88aeeb7009b51e1bf12d543856764fc413cea046529",
}
lstTreasuryCap:
"0x272a461ab0f142c5bae0e88aeeb7009b51e1bf12d543856764fc413cea046529",
},
);

tx.moveCall({
target: `0x2::transfer::public_share_object`,
typeArguments: [`${LiquidStakingInfo.$typeName}<${liquidStakingInfoType}>}`],
typeArguments: [
`${LiquidStakingInfo.$typeName}<${liquidStakingInfoType}>}`,
],
arguments: [liquidStakingInfo],
});

tx.transferObjects([adminCap], keypair.toSuiAddress());


let txResponse = await client.signAndExecuteTransaction({
const txResponse = await client.signAndExecuteTransaction({
transaction: tx,
signer: keypair,
});
}

async function getValidatorApys() {
let client = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
const client = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });

let res = await client.getValidatorsApy();
const res = await client.getValidatorsApy();

let validatorAddresses = res.apys.map((apy) => apy.address);
let lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO);
let adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress());
const validatorAddresses = res.apys.map((apy) => apy.address);
const lstClient = await LstClient.initialize(client, LIQUID_STAKING_INFO);
const adminCapId = await lstClient.getAdminCapId(keypair.toSuiAddress());
if (!adminCapId) return;

for (let i = 0; i < 50; i++) {
let tx = new Transaction();
const tx = new Transaction();
lstClient.increaseValidatorStake(
tx,
tx,
adminCapId,
validatorAddresses[i],
1_000_000_000
1_000_000_000,
);

let txResponse = await client.signAndExecuteTransaction({
const txResponse = await client.signAndExecuteTransaction({
transaction: tx,
signer: keypair,
});
console.log(txResponse);
await new Promise(resolve => setTimeout(resolve, 1000));
await new Promise((resolve) => setTimeout(resolve, 1000));
}

}

// createNewLst();
getValidatorApys();
getValidatorApys();
47 changes: 22 additions & 25 deletions sdk/src/functions.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import { SuiClient } from "@mysten/sui/client";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import {
Transaction,
TransactionObjectInput,
TransactionResult,
} from "@mysten/sui/transactions";
import * as generated from "./_generated/liquid_staking/liquid-staking/functions";
import * as weightHookGenerated from "./_generated/liquid_staking/weight/functions";
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 { fromBase64 } from "@mysten/sui/utils";
import * as generated from "./_generated/liquid_staking/liquid-staking/functions";
import { LiquidStakingInfo } from "./_generated/liquid_staking/liquid-staking/structs";
import { phantom } from "./_generated/_framework/reified";
import { PACKAGE_ID, setPublishedAt } from "./_generated/liquid_staking";
import * as weightHookGenerated from "./_generated/liquid_staking/weight/functions";
import { WeightHook } from "./_generated/liquid_staking/weight/structs";

export interface LiquidStakingObjectInfo {
Expand Down Expand Up @@ -69,8 +64,8 @@ export class LstClient {
this.client = client;
}

async getAdminCapId(address: string): Promise<string | null> {
let res = (
async getAdminCapId(address: string): Promise<string | null | undefined> {
const res = (
await this.client.getOwnedObjects({
owner: address,
filter: {
Expand All @@ -83,11 +78,13 @@ export class LstClient {
return null;
}

return res[0].data.objectId;
return res[0].data?.objectId;
}

async getWeightHookAdminCapId(address: string): Promise<string | null> {
let res = (
async getWeightHookAdminCapId(
address: string,
): Promise<string | null | undefined> {
const res = (
await this.client.getOwnedObjects({
owner: address,
filter: {
Expand All @@ -100,12 +97,12 @@ export class LstClient {
return null;
}

return res[0].data.objectId;
return res[0].data?.objectId;
}

// returns the lst object
mint(tx: Transaction, suiCoinId: TransactionObjectInput) {
let [rSui] = generated.mint(tx, this.liquidStakingObject.type, {
const [rSui] = generated.mint(tx, this.liquidStakingObject.type, {
self: this.liquidStakingObject.id,
sui: suiCoinId,
systemState: SUI_SYSTEM_STATE_ID,
Expand All @@ -116,7 +113,7 @@ export class LstClient {

// returns the sui coin
redeemLst(tx: Transaction, lstId: TransactionObjectInput) {
let [sui] = generated.redeem(tx, this.liquidStakingObject.type, {
const [sui] = generated.redeem(tx, this.liquidStakingObject.type, {
self: this.liquidStakingObject.id,
systemState: SUI_SYSTEM_STATE_ID,
lst: lstId,
Expand Down Expand Up @@ -158,7 +155,7 @@ export class LstClient {
}

collectFees(tx: Transaction, adminCapId: TransactionObjectInput) {
let [sui] = generated.collectFees(tx, this.liquidStakingObject.type, {
const [sui] = generated.collectFees(tx, this.liquidStakingObject.type, {
self: this.liquidStakingObject.id,
systemState: SUI_SYSTEM_STATE_ID,
adminCap: adminCapId,
Expand Down Expand Up @@ -198,7 +195,7 @@ export class LstClient {
})[0];
}

let [feeConfig] = toFeeConfig(tx, builder);
const [feeConfig] = toFeeConfig(tx, builder);

generated.updateFees(tx, this.liquidStakingObject.type, {
self: this.liquidStakingObject.id,
Expand All @@ -209,7 +206,7 @@ export class LstClient {

// weight hook functions
initializeWeightHook(tx: Transaction, adminCapId: TransactionObjectInput) {
let [weightHook, weightHookAdminCap] = weightHookGenerated.new_(
const [weightHook, weightHookAdminCap] = weightHookGenerated.new_(
tx,
this.liquidStakingObject.type,
adminCapId,
Expand All @@ -232,7 +229,7 @@ export class LstClient {
weightHookAdminCap: TransactionObjectInput,
validatorAddressesAndWeights: Map<string, number>,
) {
let [vecMap] = tx.moveCall({
const [vecMap] = tx.moveCall({
target: `0x2::vec_map::empty`,
typeArguments: ["address", "u64"],
arguments: [],
Expand Down Expand Up @@ -289,8 +286,8 @@ interface FeeConfigArgs {

// only works for sSui
export async function getSpringSuiApy(client: SuiClient) {
let res = await client.getValidatorsApy();
let validatorApy = res.apys.find(
const res = await client.getValidatorsApy();
const validatorApy = res.apys.find(
(apy) => apy.address == SUILEND_VALIDATOR_ADDRESS,
);
return validatorApy?.apy;
Expand Down
Loading

0 comments on commit 0470f8d

Please sign in to comment.