Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: collapsable address/tx in auth signer #183

Merged
merged 1 commit into from
Jan 8, 2025
Merged
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
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 @@
</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 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 @@
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 @@
<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
Loading