diff --git a/packages/app/package.json b/packages/app/package.json index b68cac88..09950cfa 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,6 +15,7 @@ "@solana/web3.js": "^1.66.2", "@sunrisestake/client": "0.1.0", "@sunrisestake/marinade-ts-sdk": "4.0.4-alpha.18", + "@sunrisestake/yield-controller": "^0.0.3", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.7", "@testing-library/jest-dom": "^5.16.5", diff --git a/packages/app/src/hooks/useCarbon.ts b/packages/app/src/hooks/useCarbon.ts index 81c6565a..70598022 100644 --- a/packages/app/src/hooks/useCarbon.ts +++ b/packages/app/src/hooks/useCarbon.ts @@ -1,13 +1,12 @@ -import { useSunriseStake } from "../context/sunriseStakeContext"; -import { useEffect, useState } from "react"; import BN from "bn.js"; +import { useEffect, useState } from "react"; import { solToCarbon, toSol } from "../lib/util"; -import { useConnection } from "@solana/wallet-adapter-react"; -import { HOLDING_ACCOUNT } from "@sunrisestake/client"; +import { useSunriseStake } from "../context/sunriseStakeContext"; +import { useYieldController } from "./useYieldController"; -export const useCarbon = (): { totalCarbon: number | undefined } => { - const { connection } = useConnection(); +const useCarbon = (): { totalCarbon: number | undefined } => { const { details } = useSunriseStake(); + const yieldControllerState = useYieldController(); const [totalCarbon, setTotalCarbon] = useState(); useEffect(() => { @@ -17,26 +16,34 @@ export const useCarbon = (): { totalCarbon: number | undefined } => { // Total carbon is the carbon value of // 1. the extractable yield // 2. the treasury balance - // 3. the holding account balance - // (TODO this last one will be replaced with the TreasuryController total_spent value) + // 3. the YieldController totalTokensPurchased value const extractableYield = details.extractableYield; const treasuryBalance = new BN(details.balances.treasuryBalance); + // no longer used to calculate the amount - can be removed const holdingAccountBalance = new BN( - await connection.getBalance(HOLDING_ACCOUNT) + details.balances.holdingAccountBalance ); + // this is the amount of carbon tokens burned so far by the protocol + const totalTokensPurchased = + yieldControllerState?.totalTokensPurchased ?? new BN(0); + + // this is the current price set in the yield controller for buying carbon tokens + // TODO use this instead of the hard-coded values to convert SOL to Carbon + // const price = yieldControllerState?.price ?? 0; - const totalLamports = extractableYield - .add(treasuryBalance) - .add(holdingAccountBalance); + const totalLamportsWaiting = extractableYield.add(treasuryBalance); - const carbon = solToCarbon(toSol(totalLamports)); + const carbon = + solToCarbon(toSol(totalLamportsWaiting)) + + totalTokensPurchased.toNumber(); console.log({ extractableYield: toSol(extractableYield), treasuryBalance: toSol(treasuryBalance), holdingAccountBalance: toSol(holdingAccountBalance), - totalLamports: toSol(totalLamports), + totalLamportsWaiting: toSol(totalLamportsWaiting), + totalTokensPurchased: totalTokensPurchased.toNumber(), totalCarbon: carbon, }); @@ -49,3 +56,5 @@ export const useCarbon = (): { totalCarbon: number | undefined } => { return { totalCarbon }; }; + +export { useCarbon }; diff --git a/packages/app/src/hooks/useYieldController.ts b/packages/app/src/hooks/useYieldController.ts new file mode 100644 index 00000000..a38035cc --- /dev/null +++ b/packages/app/src/hooks/useYieldController.ts @@ -0,0 +1,23 @@ +import { useSunriseStake } from "../context/sunriseStakeContext"; +import { useEffect, useState } from "react"; +import { + type YieldControllerState, + YieldControllerClient, +} from "@sunrisestake/yield-controller"; + +export const useYieldController = (): YieldControllerState | undefined => { + const { client } = useSunriseStake(); + const [yieldState, setYieldState] = useState(); + useEffect(() => { + void (async () => { + if (!client) return; + const yieldControllerClient = await YieldControllerClient.get( + client.internal().provider, + client.yieldControllerState + ); + yieldControllerClient.getState().then(setYieldState).catch(console.error); + })(); + }, [client?.yieldControllerState]); + + return yieldState; +}; diff --git a/packages/app/src/lib/sunriseClientWrapper.ts b/packages/app/src/lib/sunriseClientWrapper.ts index 76fba0d1..2b282575 100644 --- a/packages/app/src/lib/sunriseClientWrapper.ts +++ b/packages/app/src/lib/sunriseClientWrapper.ts @@ -124,4 +124,8 @@ export class SunriseClientWrapper { .sendAndConfirm(tx, []) .then(this.triggerUpdateAndReturn.bind(this)); } + + get yieldControllerState(): PublicKey { + return this.client.env.yieldControllerState; + } } diff --git a/packages/app/src/utils/tooltips.tsx b/packages/app/src/utils/tooltips.tsx index 2012fcaf..4eb3f95a 100644 --- a/packages/app/src/utils/tooltips.tsx +++ b/packages/app/src/utils/tooltips.tsx @@ -3,7 +3,7 @@ export const tooltips = { totalStake: <>The sum of everyones staked SOL, offsetCO2: ( <> - Tonnes of Carbon Dioxide or equivalent (tCO2e) offset by Sunrise so far. + Tonnes of Carbon Dioxide or equivalent (tCO₂E) offset by Sunrise so far. Note: This number includes yield that Sunrise has accrued, but not yet spent diff --git a/packages/client/src/constants.ts b/packages/client/src/constants.ts index 1defe797..4e47bdbd 100644 --- a/packages/client/src/constants.ts +++ b/packages/client/src/constants.ts @@ -13,6 +13,7 @@ interface BlazeConfig { interface EnvironmentConfig { state: PublicKey; holdingAccount: PublicKey; + yieldControllerState: PublicKey; percentageStakeToMarinade: number; blaze: BlazeConfig; } @@ -22,6 +23,9 @@ export const Environment: Record = { holdingAccount: new PublicKey( "shcFT8Ur2mzpX61uWQRL9KyERZp4w2ehDEvA7iaAthn" ), + yieldControllerState: new PublicKey( + "htGs6L3pCRxgfkJP2vLUdb9hVPtcE4mKsdWP4CnirQA" + ), percentageStakeToMarinade: 200, // TODO TEMP fix blaze: { pool: new PublicKey("stk9ApL5HeVAwPLr3TLhDXdZS8ptVu7zp6ov8HFDuMi"), @@ -33,6 +37,9 @@ export const Environment: Record = { state: new PublicKey("DR3hrjH6SZefraRu8vaQfEhG5e6E25ZwccakQxWRePkC"), // Warning obsolete holdingAccount: PublicKey.default, percentageStakeToMarinade: 75, + yieldControllerState: new PublicKey( + "77aJfgRudbv9gFfjRQw3tuYzgnjoDgs9jorVTmK7cv73" + ), blaze: { pool: PublicKey.default, bsolMint: PublicKey.default, @@ -43,6 +50,26 @@ export const Environment: Record = { holdingAccount: new PublicKey( "dhcB568T3skiP2D9ujf4eAJEnW2gACaaA9BUCVbwbXD" ), + yieldControllerState: new PublicKey( + "77aJfgRudbv9gFfjRQw3tuYzgnjoDgs9jorVTmK7cv73" + ), + yieldControllerState: new PublicKey( + "77aJfgRudbv9gFfjRQw3tuYzgnjoDgs9jorVTmK7cv73" + ), + percentageStakeToMarinade: 75, + blaze: { + pool: new PublicKey("azFVdHtAJN8BX3sbGAYkXvtdjdrT5U6rj9rovvUFos9"), + bsolMint: new PublicKey("bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1"), + }, + }, + localnet: { + state: new PublicKey("28SkW4iD7UJc9zkxcq6yNb1MFX2hxqdJjxjZs67Jwr2b"), + holdingAccount: new PublicKey( + "dhcB568T3skiP2D9ujf4eAJEnW2gACaaA9BUCVbwbXD" + ), + yieldControllerState: new PublicKey( + "77aJfgRudbv9gFfjRQw3tuYzgnjoDgs9jorVTmK7cv73" + ), percentageStakeToMarinade: 75, blaze: { pool: new PublicKey("azFVdHtAJN8BX3sbGAYkXvtdjdrT5U6rj9rovvUFos9"), diff --git a/yarn.lock b/yarn.lock index 1cd4bf3c..9853265f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1125,6 +1125,27 @@ eventemitter3 "^4.0.7" uuid "^8.3.2" +"@coral-xyz/anchor@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.26.0.tgz#c8e4f7177e93441afd030f22d777d54d0194d7d1" + integrity sha512-PxRl+wu5YyptWiR9F2MBHOLLibm87Z4IMUBPreX+DYBtPM+xggvcPi0KAN7+kIL4IrIhXI8ma5V0MCXxSN1pHg== + dependencies: + "@coral-xyz/borsh" "^0.26.0" + "@solana/web3.js" "^1.68.0" + base64-js "^1.5.1" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.2" + camelcase "^6.3.0" + cross-fetch "^3.1.5" + crypto-hash "^1.3.0" + eventemitter3 "^4.0.7" + js-sha256 "^0.9.0" + pako "^2.0.3" + snake-case "^3.0.4" + superstruct "^0.15.4" + toml "^3.0.0" + "@coral-xyz/borsh@^0.26.0": version "0.26.0" resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5" @@ -3519,7 +3540,7 @@ dependencies: buffer "~6.0.3" -"@solana/spl-token@^0.3.5", "@solana/spl-token@^0.3.6": +"@solana/spl-token@^0.3.5", "@solana/spl-token@^0.3.6", "@solana/spl-token@^0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.7.tgz#6f027f9ad8e841f792c32e50920d9d2e714fc8da" integrity sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg== @@ -4180,6 +4201,14 @@ borsh "^0.6.0" bs58 "^5.0.0" +"@sunrisestake/yield-controller@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@sunrisestake/yield-controller/-/yield-controller-0.0.3.tgz#f49b334126e9e3e26dfbea7ac107d56146a5b89d" + integrity sha512-IQOSzrsZsR7QTiDamXZOP/FRoxJMulDSJ9boA4qd054/OzhtSKy6TQD2/oOX6Grp3garMk5REu594+XD65GejA== + dependencies: + "@coral-xyz/anchor" "^0.26.0" + "@solana/spl-token" "^0.3.7" + "@supercharge/promise-pool@^2.1.0": version "2.3.2" resolved "https://registry.yarnpkg.com/@supercharge/promise-pool/-/promise-pool-2.3.2.tgz#6366894a7e7bc699bb65e58d8c828113729cf481"