[xc-admin] enable publisher key and multisig signer key mapping when available (#663)
* enable publisher key and multisig signer key mapping when available * fix permission/depermission button border radius * address comments and add mapping filepath * fix precommit error
This commit is contained in:
parent
55a8f85254
commit
60b1a3688b
|
@ -34,3 +34,8 @@ yarn-error.log*
|
|||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
|
||||
# mappings
|
||||
publishers.json
|
||||
signers.json
|
||||
|
|
|
@ -144,7 +144,7 @@ const PermissionDepermissionKey = ({
|
|||
{({ open }) => (
|
||||
<>
|
||||
<Menu.Button
|
||||
className={`inline-flex w-full items-center justify-between rounded-lg bg-darkGray2 py-3 px-6 text-sm outline-0`}
|
||||
className={`inline-flex w-full items-center justify-between bg-darkGray2 py-3 px-6 text-sm outline-0`}
|
||||
>
|
||||
<span className="mr-3">
|
||||
{isPermission ? 'Permission Key' : 'Depermission Key'}
|
||||
|
|
|
@ -173,12 +173,16 @@ const ParsedAccountPubkeyRow = ({
|
|||
}
|
||||
|
||||
const Proposal = ({
|
||||
publisherKeyToNameMapping,
|
||||
multisigSignerKeyToNameMapping,
|
||||
proposal,
|
||||
proposalIndex,
|
||||
instructions,
|
||||
verified,
|
||||
multisig,
|
||||
}: {
|
||||
publisherKeyToNameMapping: Record<string, string>
|
||||
multisigSignerKeyToNameMapping: Record<string, string>
|
||||
proposal: TransactionAccount | undefined
|
||||
proposalIndex: number
|
||||
instructions: MultisigInstruction[]
|
||||
|
@ -425,10 +429,20 @@ const Proposal = ({
|
|||
</h4>
|
||||
<hr className="border-gray-700" />
|
||||
{currentProposal.approved.map((pubkey, idx) => (
|
||||
<div className="flex justify-between" key={pubkey.toBase58()}>
|
||||
<div>Key {idx + 1}</div>
|
||||
<CopyPubkey pubkey={pubkey.toBase58()} />
|
||||
</div>
|
||||
<>
|
||||
<div className="flex justify-between" key={pubkey.toBase58()}>
|
||||
<div>Key {idx + 1}</div>
|
||||
<CopyPubkey pubkey={pubkey.toBase58()} />
|
||||
</div>
|
||||
{pubkey.toBase58() in multisigSignerKeyToNameMapping ? (
|
||||
<ParsedAccountPubkeyRow
|
||||
key={`${idx}_${pubkey.toBase58()}_confirmed`}
|
||||
mapping={multisigSignerKeyToNameMapping}
|
||||
title="owner"
|
||||
pubkey={pubkey.toBase58()}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
@ -439,10 +453,20 @@ const Proposal = ({
|
|||
</h4>
|
||||
<hr className="border-gray-700" />
|
||||
{currentProposal.rejected.map((pubkey, idx) => (
|
||||
<div className="flex justify-between" key={pubkey.toBase58()}>
|
||||
<div>Key {idx + 1}</div>
|
||||
<CopyPubkey pubkey={pubkey.toBase58()} />
|
||||
</div>
|
||||
<>
|
||||
<div className="flex justify-between" key={pubkey.toBase58()}>
|
||||
<div>Key {idx + 1}</div>
|
||||
<CopyPubkey pubkey={pubkey.toBase58()} />
|
||||
</div>
|
||||
{pubkey.toBase58() in multisigSignerKeyToNameMapping ? (
|
||||
<ParsedAccountPubkeyRow
|
||||
key={`${idx}_${pubkey.toBase58()}_rejected`}
|
||||
mapping={multisigSignerKeyToNameMapping}
|
||||
title="owner"
|
||||
pubkey={pubkey.toBase58()}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
@ -525,28 +549,42 @@ const Proposal = ({
|
|||
<div>Value</div>
|
||||
</div>
|
||||
{Object.keys(instruction.args).map((key, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex justify-between border-t border-beige-300 py-3"
|
||||
>
|
||||
<div>{key}</div>
|
||||
{instruction.args[key] instanceof PublicKey ? (
|
||||
<CopyPubkey
|
||||
<>
|
||||
<div
|
||||
key={index}
|
||||
className="flex justify-between border-t border-beige-300 py-3"
|
||||
>
|
||||
<div>{key}</div>
|
||||
{instruction.args[key] instanceof PublicKey ? (
|
||||
<CopyPubkey
|
||||
pubkey={instruction.args[key].toBase58()}
|
||||
/>
|
||||
) : typeof instruction.args[key] === 'string' &&
|
||||
isPubkey(instruction.args[key]) ? (
|
||||
<CopyPubkey pubkey={instruction.args[key]} />
|
||||
) : (
|
||||
<div className="max-w-sm break-all">
|
||||
{typeof instruction.args[key] === 'string'
|
||||
? instruction.args[key]
|
||||
: instruction.args[key] instanceof Uint8Array
|
||||
? instruction.args[key].toString('hex')
|
||||
: JSON.stringify(instruction.args[key])}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{key === 'pub' &&
|
||||
instruction.args[key].toBase58() in
|
||||
publisherKeyToNameMapping ? (
|
||||
<ParsedAccountPubkeyRow
|
||||
key={`${index}_${instruction.args[
|
||||
key
|
||||
].toBase58()}`}
|
||||
mapping={publisherKeyToNameMapping}
|
||||
title="publisher"
|
||||
pubkey={instruction.args[key].toBase58()}
|
||||
/>
|
||||
) : typeof instruction.args[key] === 'string' &&
|
||||
isPubkey(instruction.args[key]) ? (
|
||||
<CopyPubkey pubkey={instruction.args[key]} />
|
||||
) : (
|
||||
<div className="max-w-sm break-all">
|
||||
{typeof instruction.args[key] === 'string'
|
||||
? instruction.args[key]
|
||||
: instruction.args[key] instanceof Uint8Array
|
||||
? instruction.args[key].toString('hex')
|
||||
: JSON.stringify(instruction.args[key])}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
@ -739,45 +777,69 @@ const Proposal = ({
|
|||
</div>
|
||||
{Object.keys(parsedInstruction.args).map(
|
||||
(key, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex justify-between border-t border-beige-300 py-3"
|
||||
>
|
||||
<div>{key}</div>
|
||||
{parsedInstruction.args[
|
||||
<>
|
||||
<div
|
||||
key={index}
|
||||
className="flex justify-between border-t border-beige-300 py-3"
|
||||
>
|
||||
<div>{key}</div>
|
||||
{parsedInstruction.args[
|
||||
key
|
||||
] instanceof PublicKey ? (
|
||||
<CopyPubkey
|
||||
pubkey={parsedInstruction.args[
|
||||
key
|
||||
].toBase58()}
|
||||
/>
|
||||
) : typeof instruction.args[key] ===
|
||||
'string' &&
|
||||
isPubkey(
|
||||
instruction.args[key]
|
||||
) ? (
|
||||
<CopyPubkey
|
||||
pubkey={
|
||||
parsedInstruction.args[key]
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="max-w-sm break-all">
|
||||
{typeof parsedInstruction.args[
|
||||
key
|
||||
] === 'string'
|
||||
? parsedInstruction.args[key]
|
||||
: parsedInstruction.args[
|
||||
key
|
||||
] instanceof Uint8Array
|
||||
? parsedInstruction.args[
|
||||
key
|
||||
].toString('hex')
|
||||
: JSON.stringify(
|
||||
parsedInstruction.args[
|
||||
key
|
||||
]
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{key === 'pub' &&
|
||||
parsedInstruction.args[
|
||||
key
|
||||
] instanceof PublicKey ? (
|
||||
<CopyPubkey
|
||||
].toBase58() in
|
||||
publisherKeyToNameMapping ? (
|
||||
<ParsedAccountPubkeyRow
|
||||
key={`${index}_${parsedInstruction.args[
|
||||
key
|
||||
].toBase58()}`}
|
||||
mapping={
|
||||
publisherKeyToNameMapping
|
||||
}
|
||||
title="publisher"
|
||||
pubkey={parsedInstruction.args[
|
||||
key
|
||||
].toBase58()}
|
||||
/>
|
||||
) : typeof instruction.args[key] ===
|
||||
'string' &&
|
||||
isPubkey(instruction.args[key]) ? (
|
||||
<CopyPubkey
|
||||
pubkey={
|
||||
parsedInstruction.args[key]
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="max-w-sm break-all">
|
||||
{typeof parsedInstruction.args[
|
||||
key
|
||||
] === 'string'
|
||||
? parsedInstruction.args[key]
|
||||
: parsedInstruction.args[
|
||||
key
|
||||
] instanceof Uint8Array
|
||||
? parsedInstruction.args[
|
||||
key
|
||||
].toString('hex')
|
||||
: JSON.stringify(
|
||||
parsedInstruction.args[key]
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
@ -962,7 +1024,13 @@ const Proposal = ({
|
|||
)
|
||||
}
|
||||
|
||||
const Proposals = () => {
|
||||
const Proposals = ({
|
||||
publisherKeyToNameMapping,
|
||||
multisigSignerKeyToNameMapping,
|
||||
}: {
|
||||
publisherKeyToNameMapping: Record<string, string>
|
||||
multisigSignerKeyToNameMapping: Record<string, string>
|
||||
}) => {
|
||||
const router = useRouter()
|
||||
const [currentProposal, setCurrentProposal] = useState<TransactionAccount>()
|
||||
const [currentProposalIndex, setCurrentProposalIndex] = useState<number>()
|
||||
|
@ -1112,6 +1180,8 @@ const Proposals = () => {
|
|||
</div>
|
||||
<div className="relative mt-6">
|
||||
<Proposal
|
||||
publisherKeyToNameMapping={publisherKeyToNameMapping}
|
||||
multisigSignerKeyToNameMapping={multisigSignerKeyToNameMapping}
|
||||
proposal={currentProposal}
|
||||
proposalIndex={currentProposalIndex}
|
||||
instructions={allProposalsIxsParsed[currentProposalIndex]}
|
||||
|
|
|
@ -5,6 +5,7 @@ const nextConfig = {
|
|||
externalDir: true,
|
||||
},
|
||||
webpack(config) {
|
||||
config.resolve.fallback = { fs: false }
|
||||
const fileLoaderRule = config.module.rules.find(
|
||||
(rule) => rule.test && rule.test.test('.svg')
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Tab } from '@headlessui/react'
|
||||
import type { NextPage } from 'next'
|
||||
import * as fs from 'fs'
|
||||
import type { GetStaticProps, NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Layout from '../components/layout/Layout'
|
||||
|
@ -10,6 +11,34 @@ import { MultisigContextProvider } from '../contexts/MultisigContext'
|
|||
import { PythContextProvider } from '../contexts/PythContext'
|
||||
import { classNames } from '../utils/classNames'
|
||||
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
const publisherMappingFilePath = `${
|
||||
process.env.MAPPING_BASE_PATH || ''
|
||||
}publishers.json`
|
||||
const publisherKeyToNameMapping = fs.existsSync(publisherMappingFilePath)
|
||||
? JSON.parse(
|
||||
(await fs.promises.readFile(publisherMappingFilePath)).toString()
|
||||
)
|
||||
: {}
|
||||
const multisigSignerMappingFilePath = `${
|
||||
process.env.MAPPING_BASE_PATH || ''
|
||||
}signers.json`
|
||||
const multisigSignerKeyToNameMapping = fs.existsSync(
|
||||
multisigSignerMappingFilePath
|
||||
)
|
||||
? JSON.parse(
|
||||
(await fs.promises.readFile(multisigSignerMappingFilePath)).toString()
|
||||
)
|
||||
: {}
|
||||
|
||||
return {
|
||||
props: {
|
||||
publisherKeyToNameMapping,
|
||||
multisigSignerKeyToNameMapping,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const TAB_INFO = {
|
||||
General: {
|
||||
title: 'General',
|
||||
|
@ -30,7 +59,10 @@ const TAB_INFO = {
|
|||
|
||||
const DEFAULT_TAB = 'general'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const Home: NextPage<{
|
||||
publisherKeyToNameMapping: Record<string, string>
|
||||
multisigSignerKeyToNameMapping: Record<string, string>
|
||||
}> = ({ publisherKeyToNameMapping, multisigSignerKeyToNameMapping }) => {
|
||||
const [currentTabIndex, setCurrentTabIndex] = useState(0)
|
||||
const tabInfoArray = Object.values(TAB_INFO)
|
||||
|
||||
|
@ -100,7 +132,10 @@ const Home: NextPage = () => {
|
|||
<UpdatePermissions />
|
||||
) : tabInfoArray[currentTabIndex].queryString ===
|
||||
TAB_INFO.Proposals.queryString ? (
|
||||
<Proposals />
|
||||
<Proposals
|
||||
publisherKeyToNameMapping={publisherKeyToNameMapping}
|
||||
multisigSignerKeyToNameMapping={multisigSignerKeyToNameMapping}
|
||||
/>
|
||||
) : null}
|
||||
</MultisigContextProvider>
|
||||
</PythContextProvider>
|
||||
|
|
Loading…
Reference in New Issue