Skip to content

Commit

Permalink
Add CLI management tool (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
dankelleher committed Sep 10, 2024
1 parent 5f0b51e commit 49b7561
Show file tree
Hide file tree
Showing 20 changed files with 582 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ANCHOR_PROVIDER_URL=
ANCHOR_WALLET=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ test-ledger

devnet.json
yarn-error.log

.env*
!.env.example
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
"@types/chai-as-promised": "^7.1.5",
"@types/mocha": "^9.0.0",
"@types/node": "^18",
"@types/readline-sync": "^1.4.8",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.42.1",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"chalk": "^5.3.0",
"cli-table3": "^0.6.5",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard-with-typescript": "^23.0.0",
Expand All @@ -42,6 +45,7 @@
"eslint-plugin-react": "^7.31.10",
"mocha": "^10.2.0",
"prettier": "^2.6.2",
"readline-sync": "^1.4.10",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
Expand Down
17 changes: 17 additions & 0 deletions packages/fund-sender/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,23 @@ export class FundSenderClient {
return this;
}

public async sendFromState(

Check failure on line 376 in packages/fund-sender/client/index.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Delete `⏎··`
): Promise<FundSenderClient> {
if (!this.config) {
throw new Error("Client not initialized");
}

await this.program.methods
.sendFromState()
.accounts({
state: this.stateAddress,
})
.rpc()
.then(confirm(this.provider.connection));

return this

Check failure on line 390 in packages/fund-sender/client/index.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Insert `;`
}

/**
* Sends specified amount of NFTs from input account to hold account.
*
Expand Down
23 changes: 23 additions & 0 deletions packages/fund-sender/scripts/getStateFromAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FundSenderClient } from "../client";
import { logBalance } from "./lib/util";
import {PublicKey} from "@solana/web3.js";

Check failure on line 3 in packages/fund-sender/scripts/getStateFromAddress.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Replace `PublicKey` with `·PublicKey·`

// USAGE: yarn ts-node packages/fund-sender/getStateFromAddress.ts stateAddress
const stateAddress = process.argv[2];

(async () => {
const client = await FundSenderClient.fetch(new PublicKey(stateAddress));
const log = logBalance(client);

console.log("state address", stateAddress);
console.log("state account data", {
destinationName: client.config.destinationName,
updateAuthority: client.config.updateAuthority.toBase58(),
destinationAccount: client.config.destinationAccount.toBase58(),
certificateVault: client.config.certificateVault.toBase58(),
spendThreshold: client.config.spendThreshold.toNumber(),
});
console.log("input address", client.getInputAccount().toBase58());

await log("input token", client.getInputAccount());
})().catch(console.error);
2 changes: 1 addition & 1 deletion packages/fund-sender/scripts/registerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const sunriseTreasuryAddress = new PublicKey(
process.env.TREASURY_ADDRESS ?? defaultSunriseTreasuryAddress
);

// USAGE: yarn ts-node packages/fund-sender/resgisterState.ts destinationName destinationAccount
// USAGE: yarn ts-node packages/fund-sender/registerState.ts destinationName destinationAccount
const destinationName = process.argv[2];
const destinationAccount = new PublicKey(process.argv[3]);

Expand Down
29 changes: 29 additions & 0 deletions packages/fund-sender/scripts/sendFromState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FundSenderClient } from "../client";
import { PublicKey } from "@solana/web3.js";

// mainnet Sunrise
const defaultSunriseStateAddress =
"43m66crxGfXSJpmx5wXRoFuHubhHA1GCvtHgmHW6cM1P";
const sunriseStateAddress = new PublicKey(
process.env.STATE_ADDRESS ?? defaultSunriseStateAddress
);

// USAGE: yarn ts-node packages/fund-sender/sendFromState.ts destinationName
const destinationName = process.argv[2];

(async () => {
const stateAddress = FundSenderClient.getStateAddressFromSunriseAddress(
sunriseStateAddress,

Check failure on line 16 in packages/fund-sender/scripts/sendFromState.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Delete `··`
destinationName

Check failure on line 17 in packages/fund-sender/scripts/sendFromState.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Delete `··`
);
const client = await FundSenderClient.fetch(stateAddress);

console.log("state address", stateAddress.toBase58());
console.log("input address", client.getInputAccount().toBase58());

const stateBalance = await client.provider.connection.getBalance(stateAddress);

Check failure on line 24 in packages/fund-sender/scripts/sendFromState.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Replace `stateAddress` with `⏎····stateAddress⏎··`
console.log("state balance", stateBalance);

console.log("Sending fund...");
await client.sendFromState();
})().catch(console.error);
54 changes: 54 additions & 0 deletions packages/idl/fund_sender.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,60 @@
}
]
},
{
"name": "send_from_state",
"discriminator": [
119,
32,
214,
129,
74,
57,
186,
185
],
"accounts": [
{
"name": "state",
"writable": true
},
{
"name": "input_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
105,
110,
112,
117,
116,
95,
97,
99,
99,
111,
117,
110,
116
]
},
{
"kind": "account",
"path": "state"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "send_fund",
"discriminator": [
Expand Down
54 changes: 54 additions & 0 deletions packages/types/fund_sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,60 @@ export type FundSender = {
}
]
},
{
"name": "sendFromState",
"discriminator": [
119,
32,
214,
129,
74,
57,
186,
185
],
"accounts": [
{
"name": "state",
"writable": true
},
{
"name": "inputAccount",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
105,
110,
112,
117,
116,
95,
97,
99,
99,
111,
117,
110,
116
]
},
{
"kind": "account",
"path": "state"
}
]
}
},
{
"name": "systemProgram",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "sendFund",
"discriminator": [
Expand Down
2 changes: 1 addition & 1 deletion packages/yield-router/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export interface YieldRouterConfig {
spendThreshold: BN;
}

type InitialisedClient = YieldRouterClient & {
export type InitialisedClient = YieldRouterClient & {
config: YieldRouterConfig;
};

Expand Down
10 changes: 6 additions & 4 deletions packages/yield-router/scripts/updateState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ const sunriseStateAddress = new PublicKey(
);

(async () => {
const stateAddress =
YieldRouterClient.getStateAddressFromSunriseAddress(sunriseStateAddress);

Check failure on line 20 in packages/yield-router/scripts/updateState.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Delete `··`
const client = await YieldRouterClient.fetch(stateAddress);

console.log("Updating yield router state:", stateAddress.toBase58());

// Get new update authority
let newUpdateAuthority: PublicKey | undefined;

Expand Down Expand Up @@ -84,10 +90,6 @@ const sunriseStateAddress = new PublicKey(

rl.close();

const stateAddress =
YieldRouterClient.getStateAddressFromSunriseAddress(sunriseStateAddress);
const client = await YieldRouterClient.fetch(stateAddress);

// Update output yield accounts and proportions
if (sumProportions === 100 && answer.toLocaleLowerCase() === "y") {
const state = await client.updateOutputYieldAccounts(
Expand Down
14 changes: 14 additions & 0 deletions programs/fund-sender/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ pub mod fund_sender {
Ok(())
}

pub fn send_from_state(
ctx: Context<SendFromState>,
) -> Result<()> {
let state = &ctx.accounts.state;
let amount = state.get_lamports();

if amount > 0 {
**state.to_account_info().try_borrow_mut_lamports()? -= amount;
**ctx.accounts.input_account.try_borrow_mut_lamports()? += amount;
}

Ok(())
}

pub fn send_fund<'info>(
ctx: Context<'_, '_, '_, 'info, SendFund<'info>>,
amount: u64,
Expand Down
20 changes: 20 additions & 0 deletions programs/fund-sender/src/utils/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,26 @@ pub struct SendFund<'info> {
pub system_program: Program<'info, System>,
}

/// If someone sent funds to the state account, this instruction will send it to the input account
#[derive(Accounts)]
// #[instruction(sunrise_state: Pubkey, destination_name: String)]
pub struct SendFromState<'info> {
#[account(
mut,
// seeds = [STATE, &destination_name.as_bytes(), sunrise_state.key().as_ref()],
// bump,
)]
pub state: Account<'info, State>,
#[account(
mut,
seeds = [INPUT_ACCOUNT, state.key().as_ref()],
bump = state.input_account_bump,
)]
/// CHECK: Must be correctly derived from the state
pub input_account: UncheckedAccount<'info>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct StoreCertificates<'info> {
// to send the received retired climate token to a hold account
Expand Down
6 changes: 6 additions & 0 deletions scripts/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {showData} from "./util";

Check failure on line 1 in scripts/manager.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Replace `showData` with `·showData·`
import {showMenu} from "./prompt";

Check failure on line 2 in scripts/manager.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Replace `showMenu` with `·showMenu·`

await showData();

showMenu();

Check failure on line 6 in scripts/manager.ts

View workflow job for this annotation

GitHub Actions / lint-client (20)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
52 changes: 52 additions & 0 deletions scripts/prompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import chalk from 'chalk';
import readlineSync from 'readline-sync';
import {showData} from "./util";
import {submenuRouteToRecipient} from "./submenu/routeToRecipient";
import {submenuAllocateYield} from "./submenu/allocateYield";

export const showMenu = async () => {
console.log(chalk.magentaBright('\nChoose an option:'));
console.log(chalk.cyanBright('1) Refresh'));
console.log(chalk.cyanBright('2) Allocate Yield'));
console.log(chalk.cyanBright('3) Route Funds to Recipient'));
console.log(chalk.cyanBright('4) Update Proportions'));
console.log(chalk.cyanBright('5) Add Recipient'));
console.log(chalk.cyanBright('6) Remove Recipient'));
console.log(chalk.cyanBright('7) Quit'));

const choice = readlineSync.keyIn(chalk.yellow('\nEnter your choice: '), { limit: '$<1-7>' });

switch (choice) {
case '1':
console.log(chalk.green('Refreshing...'));
await showData();
break;
case '2':
await submenuAllocateYield();
break;
case '3':
await submenuRouteToRecipient();
break;
case '4':
console.log(chalk.green('Updating proportions...'));
// Call your update proportions function here
break;
case '5':
console.log(chalk.green('Adding recipient...'));
// Call your add recipient function here
break;
case '6':
console.log(chalk.green('Removing recipient...'));
// Call your remove recipient function here
break;
case '7':
console.log(chalk.green('Exiting...'));
process.exit(0);
break;
default:
console.log(chalk.red('Invalid choice, please try again.'));
showMenu(); // Re-display menu for invalid input
break;
}
showMenu();
};
Loading

0 comments on commit 49b7561

Please sign in to comment.