Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a typescript/js SDK for interacting with the Solido program #467

Open
ruuda opened this issue Dec 1, 2021 · 3 comments
Open

Add a typescript/js SDK for interacting with the Solido program #467

ruuda opened this issue Dec 1, 2021 · 3 comments
Assignees

Comments

@ruuda
Copy link
Contributor

ruuda commented Dec 1, 2021

Summary

There are various parties interacting with Solido from javascript. Until now we just had a dump of some useful snippets on https://docs.solana.lido.fi/development/frontend-integration, but we can do much better than this by offering a library.

  • Constructing a deposit instruction manually is a bit tedious but doable, but to construct an unstake instruction is a bit involved, and it relies on things that I would consider implementation details.
  • If integrations write their own logic for interacting with the Solido program, it also makes it more difficult for us to change things in the future without breaking these use cases.
  • It will be smoother for new integrations if they can use a library, instead of having to copy some snippets from the docs site.

Details

We should offer the following functions:

  • Get the current Total Value Locked (amount in stake accounts + reserve) in SOL
  • Get the current stSOL supply.
  • Get the epoch exchange rate (from the instance, it is not just TVL / stSOL supply).
  • Construct a deposit instruction.
  • Construct a withdraw instruction.

Probably we should parametrize those functions over the addresses, and then also offer one constant that contains the official mainnet addresses.

An attempt at defining this, but I know nothing about Typescript so feel free to correct me here:

// TODO: Is it better to use an interface or class for this?
interface Addresses {
    solidoProgramId: PublicKey;
    solidoInstanceId: PublicKey;
    stSolMintAddress: PublicKey;
}

const MAINNET_ADDRESSES: Addresses = {
    solidoProgramId: web3.PublicKey("CrX7kMhLC3cSsXJdT7JDgqrRVWGnUpX3gfEfxxU2NVLi"),
    solidoInstanceId: web3.PublicKey("49Yi1TKkNyYjPAFdR9LBvoHcUjuPX4Df5T5yv39w2XTn"),
    stSolMintAddress: web3.PublicKey("7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj"),
};

interface Lamports { lamports: BigNumber; }
interface StLamports { stLamports: BigNumber; }

interface ExchangeRate {
    solBalance: Lamports;
    stSolSupply: StLamports;
}

interface Snapshot { /* Should hold the data for all relevant accounts. */ }

// Reads the Solido instance and stSOL mint through getMultipleAccounts.
function getSnapshot(connection: Connection, addrs: Addresses): Snapshot { /* ... */ }

// Or maybe these should be methods on `Snapshot`, that would work as well.
function getTotalValueLocked(snapshot: Snapshot): Lamports { /* ... */ }
function getStSolSupply(snapshot: Snapshot): StLamports { /* ... */ }
function getExchangeRate(snapshot: Snapshot): ExchangeRate { /* ... */ }

function deposit(senderSol: PublicKey, recipientStSol, amount: Lamports): TransactionInstruction { /* ... */ }
// Maybe we can also have an function to build the instruction to initialize the associated token account.

// Note: Withdraw initializes the recipient stake account; it should be a new fresh address.
// Would throw an exception if the amount is too low (can happen due to the stake account rent exemption requirement)
// or too high (can happen due to balancing requirements).
function withdraw(
    snapshot: Snapshot,
    senderStSol: PublicKey,
    recipientWithdrawAuthority: PublicKey,
    recipientStakeAccount: PublicKey,
    amount: StLamports,
): TransactionInstruction { /* ... */ }

Open questions

We can put the thing in this repository. @hritique, I am not very familiar with the js ecosystem ... should we also upload a package to NPM or something?

Also, my impression is that Typescript is taking over, and a Typescript library can be used from js after compilation, right? So probably it is most useful to offer it in Typescript so users who are also using it get maximum type safety, but users who are using legacy js can still use it? I see solana-web3 is also written in Typescript, so that would fit in nicely.

@ruuda
Copy link
Contributor Author

ruuda commented Dec 1, 2021

Also, the code in this repository is currently licensed under the GPLv3, but for a library that is not ideal, we should go with something permissive for this part.

@AlexBHarley
Copy link

We already have some of these features pulled together for Steakwallet.

What we could do is separate it out into an MIT based library and someone with more knowhow fills in the rest of the functions. The withdraw functionality is a little complicated, for example, which is what we're blocked on right now

@ruuda
Copy link
Contributor Author

ruuda commented Dec 13, 2021

A work in progress is in #478.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants