Skip to content
This repository was archived by the owner on Mar 6, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 123 additions & 113 deletions app/(app)/config/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import AddMemberInput from "@/components/AddMemberInput";
import ChangeThresholdInput from "@/components/ChangeThresholdInput";
import ChangeUpgradeAuthorityInput from "@/components/ChangeUpgradeAuthorityInput";
import RemoveMemberButton from "@/components/RemoveMemberButton";
import AddMemberInput from "@/components/config/add-member";
import ChangeThresholdInput from "@/components/config/change-threshold";
import RemoveMemberButton from "@/components/config/remove-member";
import Chip from "@/components/ui/chip";
import CopyTextButton from "@/components/ui/misc/copy-text";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
} from "@/components/ui/primitives/card";
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
import * as multisig from "@sqds/multisig";
import { ArrowUp01, UserPlus, Users } from "lucide-react";
import { cookies, headers } from "next/headers";
const ConfigurationPage = async () => {
import SectionHeader from "@/components/layout/section-header";

export default async function Configuration() {
const rpcUrl = headers().get("x-rpc-url");

const connection = new Connection(rpcUrl || clusterApiUrl("mainnet-beta"));
const multisigCookie = headers().get("x-multisig");
const multisigPda = new PublicKey(multisigCookie!);
const vaultIndex = Number(headers().get("x-vault-index"));
const programIdCookie = cookies().get("x-program-id")?.value;
const programId = programIdCookie
? new PublicKey(programIdCookie!)
Expand All @@ -28,117 +31,124 @@ const ConfigurationPage = async () => {
connection,
multisigPda
);

return (
<div className="">
<h1 className="text-3xl font-bold mb-4">Multisig Configuration</h1>
<Card>
<CardHeader>
<CardTitle>Members</CardTitle>
<CardDescription>
List of members in the multisig as well as their permissions.
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-8">
{multisigInfo.members.map((member) => (
<div key={member.key.toBase58()}>
<div className="flex items-center">
<div className="ml-4 space-y-1">
<p className="text-sm font-medium leading-none">
Public Key: {member.key.toBase58()}
</p>
<p className="text-sm text-muted-foreground">
Permission Mask:
{member.permissions.mask.toString()}
</p>
</div>
<div className="ml-auto">
<RemoveMemberButton
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
memberKey={member.key.toBase58()}
multisigPda={multisigCookie!}
transactionIndex={
Number(multisigInfo.transactionIndex) + 1
}
programId={
programId.toBase58()
? programId.toBase58()
: multisig.PROGRAM_ID.toBase58()
}
/>
</div>
</div>
<hr className="mt-2" />
</div>
))}
</div>
</CardContent>
</Card>
<div className="flex pb-4">
<Card className="mt-4 w-1/2 mr-2">
<CardHeader>
<CardTitle>Add Member</CardTitle>
<CardDescription>Add a member to the Multisig</CardDescription>
</CardHeader>
<CardContent>
<AddMemberInput
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={Number(multisigInfo.transactionIndex) + 1}
programId={
programIdCookie
? programIdCookie
: multisig.PROGRAM_ID.toBase58()
}
/>
</CardContent>
</Card>
<Card className="mt-4 w-1/2">
<CardHeader>
<CardTitle>Change Threshold</CardTitle>
<CardDescription>
Change the threshold required to execute a multisig transaction.
<div className="font-neue">
<SectionHeader
title="Config"
description="Manage members and edit your Squad's threshold."
/>
<section className="px-8 my-14">
<div className="mt-4 pb-4 flex gap-4">
<Card className="w-1/2 dark:bg-darkforeground dark:border-darkborder/10">
<CardHeader className="space-y-3">
<CardTitle className="inline-flex gap-2 items-center tracking-wide">
<UserPlus size={24} />
Add Member
</CardTitle>
<CardDescription className="text-stone-500 dark:text-white/50">
Add a member to the Multisig
</CardDescription>
</CardHeader>
<CardContent>
<AddMemberInput
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={Number(multisigInfo.transactionIndex) + 1}
programId={
programIdCookie
? programIdCookie
: multisig.PROGRAM_ID.toBase58()
}
/>
</CardContent>
</Card>
<Card className="w-1/2 dark:bg-darkforeground dark:border-darkborder/10">
<CardHeader className="space-y-3">
<CardTitle className="inline-flex gap-2 items-center tracking-wide">
<ArrowUp01 size={24} />
Change Threshold
</CardTitle>
<CardDescription className="text-stone-500 dark:text-white/50">
Change the threshold required to execute a multisig transaction.
</CardDescription>
</CardHeader>
<CardContent>
<ChangeThresholdInput
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={Number(multisigInfo.transactionIndex) + 1}
programId={
programIdCookie
? programIdCookie
: multisig.PROGRAM_ID.toBase58()
}
/>
</CardContent>
</Card>
</div>
<Card className="dark:bg-darkforeground dark:border-darkborder/10">
<CardHeader className="space-y-3">
<CardTitle className="inline-flex gap-2 items-center tracking-wide">
<Users size={24} />
Members
</CardTitle>
<CardDescription className="text-stone-500 dark:text-white/50">
List of members in the multisig as well as their permissions.
</CardDescription>
</CardHeader>
<CardContent>
<ChangeThresholdInput
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={Number(multisigInfo.transactionIndex) + 1}
programId={
programIdCookie
? programIdCookie
: multisig.PROGRAM_ID.toBase58()
}
/>
</CardContent>
</Card>
</div>
<div className="pb-4">
<Card className="w-1/2">
<CardHeader>
<CardTitle>Change program Upgrade authority</CardTitle>
<CardDescription>
Change the upgrade authority of one of your programs.
</CardDescription>
</CardHeader>
<CardContent>
<ChangeUpgradeAuthorityInput
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={Number(multisigInfo.transactionIndex) + 1}
vaultIndex={vaultIndex}
globalProgramId={
programIdCookie
? programIdCookie
: multisig.PROGRAM_ID.toBase58()
}
/>
<div className="mt-3">
{multisigInfo.members.map((member, i) => (
<div key={member.key.toBase58()}>
{i > 0 && i < multisigInfo.members.length && (
<hr className="my-6 dark:border-darkborder/10" />
)}
<div className="flex items-center">
<div className="ml-4 space-y-3">
<div className="flex items-center gap-2">
<p className="text-lg font-medium leading-none">
{member.key.toString().slice(0, 4) +
"..." +
member.key.toString().slice(-4)}
</p>
<CopyTextButton text={member.key.toString()} />
</div>
<p className="inline-flex gap-2 items-center text-sm text-stone-500 dark:text-white/50">
Permissions:{" "}
{member.permissions.mask == 1 ? (
<Chip label="Proposer" color="blue" />
) : member.permissions.mask == 2 ? (
<Chip label="Voter" color="green" />
) : member.permissions.mask == 4 ? (
<Chip label="Executor" color="orange" />
) : (
<Chip label="All" color="yellow" />
)}
</p>
</div>
<div className="ml-auto">
<RemoveMemberButton
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
memberKey={member.key.toBase58()}
multisigPda={multisigCookie!}
transactionIndex={
Number(multisigInfo.transactionIndex) + 1
}
programId={
programId.toBase58()
? programId.toBase58()
: multisig.PROGRAM_ID.toBase58()
}
/>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</div>
</section>
</div>
);
};

export default ConfigurationPage;
}
34 changes: 18 additions & 16 deletions app/(app)/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import CreateSquadForm from "@/components/CreateSquadForm";
import { Card, CardContent } from "@/components/ui/card";
import CreateSquadForm from "@/components/create/create-squad-form";
import PageHeader from "@/components/layout/page-header";
import SectionHeader from "@/components/layout/section-header";
import { Card, CardContent } from "@/components/ui/primitives/card";
import { PROGRAM_ID } from "@sqds/multisig";
import { cookies, headers } from "next/headers";

Expand All @@ -9,20 +11,20 @@ export default async function CreateSquad() {

return (
<div className="">
<div className="flex-col space-y-1 mb-4">
<h1 className="text-3xl font-bold">Create a Squad</h1>
<h3 className="text-base text-slate-500">
Create a Squad and set it as your default account.
</h3>
</div>
<Card className="pt-5">
<CardContent>
<CreateSquadForm
rpc={rpcUrl!}
programId={programId ? programId : PROGRAM_ID.toBase58()}
/>
</CardContent>
</Card>
<SectionHeader
title="Create"
description="Create a multisig on the current cluster."
/>
<section className="px-8 my-14">
<Card className="pt-5 font-neue dark:bg-darkforeground dark:border-darkborder/30">
<CardContent>
<CreateSquadForm
rpc={rpcUrl!}
programId={programId ? programId : PROGRAM_ID.toBase58()}
/>
</CardContent>
</Card>
</section>
</div>
);
}
46 changes: 46 additions & 0 deletions app/(app)/developers/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
import * as multisig from "@sqds/multisig";
import { cookies, headers } from "next/headers";
import SectionHeader from "@/components/layout/section-header";
import ChangeUpgradeAuth from "@/components/config/change-upgrade-auth";

export default async function Configuration() {
const rpcUrl = headers().get("x-rpc-url");
const vaultIndex = Number(headers().get("x-vault-index"));
const connection = new Connection(rpcUrl || clusterApiUrl("mainnet-beta"));
const multisigCookie = headers().get("x-multisig");
const multisigPda = new PublicKey(multisigCookie!);
const programIdCookie = cookies().get("x-program-id")?.value;
const programId = programIdCookie
? new PublicKey(programIdCookie!)
: multisig.PROGRAM_ID;

const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress(
connection,
multisigPda
);

return (
<div className="font-neue">
<SectionHeader
title="Developers"
description="Manage authorities for programs and tokens."
/>
<section className="px-8 my-14">
<ChangeUpgradeAuth
multisigPda={multisigCookie!}
rpcUrl={rpcUrl || clusterApiUrl("mainnet-beta")}
transactionIndex={
multisigInfo.transactionIndex
? Number(multisigInfo.transactionIndex) + 1
: 1
}
vaultIndex={vaultIndex}
programId={
programIdCookie ? programIdCookie : multisig.PROGRAM_ID.toBase58()
}
/>
</section>
</div>
);
}
Loading