Skip to content

Commit

Permalink
feat: collapsable address/tx in auth signer
Browse files Browse the repository at this point in the history
  • Loading branch information
chalabi2 committed Jan 8, 2025
1 parent 12555f6 commit e342d83
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 21 deletions.
10 changes: 7 additions & 3 deletions components/icons/ArrowRightIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';
import { SVGProps } from 'react';

export const ArrowRightIcon: React.FC<SVGProps<SVGSVGElement>> = props => (
interface ArrowRightIconProps extends SVGProps<SVGSVGElement> {
size?: number;
}

export const ArrowRightIcon: React.FC<ArrowRightIconProps> = ({ size, ...props }) => (
<svg
width="24"
height="24"
width={size || 24}
height={size || 24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
Expand Down
20 changes: 20 additions & 0 deletions components/messageSyntax.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,23 @@ export function messageSyntax(fieldsToShow: string[], message: MessageType, them
</SyntaxHighlighter>
);
}

export function objectSyntax(object: Record<string, any>, theme: string) {
const prettyPrintJSON = (obj: Record<string, any>): string => {
return JSON.stringify(obj, null, 2);
};

return (
<SyntaxHighlighter
language="json"
style={theme === 'dark' ? oneDark : oneLight}
customStyle={{
backgroundColor: 'transparent',
padding: '1rem',
borderRadius: '0.5rem',
}}
>
{prettyPrintJSON(object)}

Check warning on line 50 in components/messageSyntax.tsx

View check run for this annotation

Codecov / codecov/patch

components/messageSyntax.tsx#L35-L50

Added lines #L35 - L50 were not covered by tests
</SyntaxHighlighter>
);
}
182 changes: 164 additions & 18 deletions components/react/authSignerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,154 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { SignData } from '@cosmos-kit/web3auth';
import { TxBody, AuthInfo } from '@liftedinit/manifestjs/dist/codegen/cosmos/tx/v1beta1/tx';
import { decodePubkey } from '@cosmjs/proto-signing';
import { useWallet, useChain } from '@cosmos-kit/react';
import { getRealLogo } from '@/utils';
import { useTheme } from '@/contexts';
import env from '@/config/env';
import { ArrowRightIcon } from '../icons';
import { objectSyntax } from '../messageSyntax';
import { MsgSend } from '@liftedinit/manifestjs/dist/codegen/cosmos/bank/v1beta1/tx';
import {
MsgCreateGroupWithPolicy,
MsgSubmitProposal,
MsgUpdateGroupMembers,
MsgUpdateGroupPolicyMetadata,
MsgUpdateGroupPolicyDecisionPolicy,
MsgUpdateGroupMetadata,
} from '@liftedinit/manifestjs/dist/codegen/cosmos/group/v1/tx';
import {
MsgCancelUpgrade,
MsgSoftwareUpgrade,
} from '@liftedinit/manifestjs/dist/codegen/cosmos/upgrade/v1beta1/tx';
import { MsgSetPower } from '@liftedinit/manifestjs/dist/codegen/strangelove_ventures/poa/v1/tx';
import {
MsgPayout,
MsgBurnHeldBalance,
} from '@liftedinit/manifestjs/dist/codegen/liftedinit/manifest/v1/tx';
import {
MsgSetDenomMetadata,
MsgCreateDenom,
} from '@liftedinit/manifestjs/dist/codegen/osmosis/tokenfactory/v1beta1/tx';

type DisplayDataToSignProps = {
data: SignData;
address: string;
};

// Message decoder registry
const messageDecoders: Record<string, (value: Uint8Array) => any> = {
'/cosmos.bank.v1beta1.MsgSend': (value: Uint8Array) => {
const decoded = MsgSend.decode(value);

Check warning on line 42 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L41-L42

Added lines #L41 - L42 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgCreateGroupWithPolicy': (value: Uint8Array) => {
const decoded = MsgCreateGroupWithPolicy.decode(value);

Check warning on line 46 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L45-L46

Added lines #L45 - L46 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgSubmitProposal': (value: Uint8Array) => {
const decoded = MsgSubmitProposal.decode(value);

Check warning on line 50 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L49-L50

Added lines #L49 - L50 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgUpdateGroupMetadata': (value: Uint8Array) => {
const decoded = MsgUpdateGroupMetadata.decode(value);

Check warning on line 54 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L53-L54

Added lines #L53 - L54 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgUpdateGroupPolicyMetadata': (value: Uint8Array) => {
const decoded = MsgUpdateGroupPolicyMetadata.decode(value);

Check warning on line 58 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L57-L58

Added lines #L57 - L58 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgUpdateGroupPolicyDecisionPolicy': (value: Uint8Array) => {
const decoded = MsgUpdateGroupPolicyDecisionPolicy.decode(value);

Check warning on line 62 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L61-L62

Added lines #L61 - L62 were not covered by tests
return { ...decoded };
},
'/cosmos.group.v1.MsgUpdateGroupMembers': (value: Uint8Array) => {
const decoded = MsgUpdateGroupMembers.decode(value);

Check warning on line 66 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L65-L66

Added lines #L65 - L66 were not covered by tests
return { ...decoded };
},
'/cosmos.upgrade.v1beta1.MsgCancelUpgrade': (value: Uint8Array) => {
const decoded = MsgCancelUpgrade.decode(value);

Check warning on line 70 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L69-L70

Added lines #L69 - L70 were not covered by tests
return { ...decoded };
},
'/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade': (value: Uint8Array) => {
const decoded = MsgSoftwareUpgrade.decode(value);

Check warning on line 74 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L73-L74

Added lines #L73 - L74 were not covered by tests
return { ...decoded };
},
'/strangelove_ventures.poa.v1.MsgSetPower': (value: Uint8Array) => {
const decoded = MsgSetPower.decode(value);

Check warning on line 78 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L77-L78

Added lines #L77 - L78 were not covered by tests
return { ...decoded };
},
'/liftedinit.manifest.v1.MsgPayout': (value: Uint8Array) => {
const decoded = MsgPayout.decode(value);

Check warning on line 82 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L81-L82

Added lines #L81 - L82 were not covered by tests
return { ...decoded };
},
'/liftedinit.manifest.v1.MsgBurnHeldBalance': (value: Uint8Array) => {
const decoded = MsgBurnHeldBalance.decode(value);

Check warning on line 86 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L85-L86

Added lines #L85 - L86 were not covered by tests
return { ...decoded };
},
'/osmosis.tokenfactory.v1beta1.MsgSetDenomMetadata': (value: Uint8Array) => {
const decoded = MsgSetDenomMetadata.decode(value);

Check warning on line 90 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L89-L90

Added lines #L89 - L90 were not covered by tests
return { ...decoded };
},
'/osmosis.tokenfactory.v1beta1.MsgCreateDenom': (value: Uint8Array) => {
const decoded = MsgCreateDenom.decode(value);

Check warning on line 94 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L93-L94

Added lines #L93 - L94 were not covered by tests
return { ...decoded };
},
};

const DisplayDataToSign = ({
data,
address,
className,
addressClassName,
txInfoClassName,
theme,

Check warning on line 105 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L105

Added line #L105 was not covered by tests
}: DisplayDataToSignProps & {
className?: string;
addressClassName?: string;
txInfoClassName?: string;
theme?: string;

Check warning on line 110 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L110

Added line #L110 was not covered by tests
}) => {
const [isAddressExpanded, setIsAddressExpanded] = useState(false);
const [isTxInfoExpanded, setIsTxInfoExpanded] = useState(false);

Check warning on line 114 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L112-L114

Added lines #L112 - L114 were not covered by tests
const decodeBodyBytes = (bodyBytes: Uint8Array) => {
try {
const decodedBody = TxBody.decode(bodyBytes);
return {
messages: decodedBody.messages.map(msg => ({
typeUrl: msg.typeUrl,
value: Buffer.from(msg.value).toString('base64'),
})),
messages: decodedBody.messages.map(msg => {
const base64Value = Buffer.from(msg.value).toString('base64');

try {
// Check if we have a specific decoder for this message type
if (messageDecoders[msg.typeUrl]) {
return {
typeUrl: msg.typeUrl,
value: messageDecoders[msg.typeUrl](msg.value),
};
}

// Fallback to generic base64 decoding
const decodedValue = Buffer.from(base64Value, 'base64').toString('utf8');
try {
return {
typeUrl: msg.typeUrl,
value: JSON.parse(decodedValue),
};
} catch {
return {
typeUrl: msg.typeUrl,
value: decodedValue,
};
}
} catch (error) {
console.error(`Failed to decode message of type ${msg.typeUrl}:`, error);
return {
typeUrl: msg.typeUrl,
value: base64Value,
};
}
}),

Check warning on line 151 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L119-L151

Added lines #L119 - L151 were not covered by tests
memo: decodedBody.memo,
timeoutHeight: decodedBody.timeoutHeight.toString(),
extensionOptions: decodedBody.extensionOptions,
Expand Down Expand Up @@ -64,7 +182,7 @@ const DisplayDataToSign = ({
}
};

const formatValue = (value: any): string => {
const formatValue = (value: any, theme: string) => {

Check warning on line 185 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L185

Added line #L185 was not covered by tests
if (value instanceof Uint8Array) {
return Buffer.from(value).toString('base64');
}
Expand All @@ -75,29 +193,56 @@ const DisplayDataToSign = ({
bodyBytes: decodeBodyBytes(value.bodyBytes),
authInfoBytes: decodeAuthInfoBytes(value.authInfoBytes),
};
return JSON.stringify(
decodedValue,
(_, v) => (typeof v === 'bigint' ? v.toString() : v),
2
return objectSyntax(
JSON.parse(
JSON.stringify(decodedValue, (_, v) => (typeof v === 'bigint' ? v.toString() : v))
),
theme

Check warning on line 200 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L196-L200

Added lines #L196 - L200 were not covered by tests
);
}
return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2);
}
if (typeof value === 'bigint') {
return value.toString();
return objectSyntax(
JSON.parse(JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v))),
theme
);

Check warning on line 206 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L203-L206

Added lines #L203 - L206 were not covered by tests
}
return String(value);
};

return (
<div className={className}>
<div className="flex flex-col gap-2">
<span className="text-sm font-medium">Address</span>
<pre className={addressClassName}>{address}</pre>
<button
onClick={() => setIsAddressExpanded(!isAddressExpanded)}
className="flex items-center gap-2 text-sm font-medium"
>
<div className="flex items-center gap-2 flex-row justify-between">
<span>Address</span>
{isAddressExpanded ? (
<ArrowRightIcon size={12} style={{ transform: 'rotate(90deg)' }} />
) : (
<ArrowRightIcon size={12} style={{ transform: 'rotate(180deg)' }} />
)}
</div>
</button>
{isAddressExpanded && <pre className={addressClassName}>{address}</pre>}

Check warning on line 227 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L214-L227

Added lines #L214 - L227 were not covered by tests
</div>
<div className="flex flex-col gap-2">
<span className="text-sm font-medium">Tx Info</span>
<pre className={txInfoClassName}>{formatValue(data.value)}</pre>
<button
onClick={() => setIsTxInfoExpanded(!isTxInfoExpanded)}
className="flex items-center gap-2 text-sm font-medium"
>
<div className="flex items-center gap-2 flex-row justify-between">
<span>Tx Info</span>
{isTxInfoExpanded ? (
<ArrowRightIcon size={12} style={{ transform: 'rotate(90deg)' }} />
) : (
<ArrowRightIcon size={12} style={{ transform: 'rotate(180deg)' }} />
)}
</div>
</button>
{isTxInfoExpanded && (
<div className={txInfoClassName}>{formatValue(data.value, theme ?? 'light')}</div>
)}

Check warning on line 245 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L230-L245

Added lines #L230 - L245 were not covered by tests
</div>
</div>
);
Expand Down Expand Up @@ -153,6 +298,7 @@ const SignModal = ({
<DisplayDataToSign
data={data}
address={address ?? ''}
theme={theme}

Check warning on line 301 in components/react/authSignerModal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/authSignerModal.tsx#L301

Added line #L301 was not covered by tests
className="space-y-4"
addressClassName="p-3 rounded-md text-sm overflow-auto h-12 dark:bg-[#E0E0FF0A] bg-[#E0E0FF0A] dark:border-[#FFFFFF33] border-[#00000033] border"
txInfoClassName="p-3 rounded-md text-sm overflow-auto h-[32rem] dark:bg-[#E0E0FF0A] bg-[#E0E0FF0A] dark:border-[#FFFFFF33] border-[#00000033] border"
Expand Down

0 comments on commit e342d83

Please sign in to comment.