Skip to content

Commit

Permalink
wip: popup ui
Browse files Browse the repository at this point in the history
  • Loading branch information
kamescg committed Dec 14, 2024
1 parent d00bbb8 commit 20e2adb
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Delegation } from 'universal-types';
import { cn } from '@/lib/utils';
import { useMemo } from 'react';
import { universalDeployments } from 'universal-data';
import type { Delegation } from 'universal-types';
import type { Chain } from 'viem';
import { CardPaymentBasic } from './card-payment-basic';
import { ERC20SwapAuthorization } from './erc20-swap-authorization';

export type DelegationDefaultParsedView = React.HTMLAttributes<HTMLElement> & {
chainId: Chain['id'];
Expand All @@ -17,6 +18,7 @@ export const DelegationDefaultParsedView = ({
chainId,
}: DelegationDefaultParsedView) => {
const delegationType = useMemo(() => {
console.log(typedData.caveats[0], 'typedData.caveats[0]');
if (!typedData) {
return;
}
Expand All @@ -28,6 +30,16 @@ export const DelegationDefaultParsedView = ({
case universalDeployments.ERC20TransferAmountEnforcer:
case universalDeployments.NativeTokenPaymentEnforcer:
return 'CardPayment';
case universalDeployments.ERC20BalanceGteWrapEnforcer:
return 'ERC20Swap';
default:
return 'Default';
}
}
if (typedData.caveats.length === 3) {
switch (typedData.caveats[0].enforcer) {
case universalDeployments.ERC20BalanceGteWrapEnforcer:
return 'ERC20Swap';
default:
return 'Default';
}
Expand All @@ -45,5 +57,14 @@ export const DelegationDefaultParsedView = ({
</div>
);
}

if (delegationType === 'ERC20Swap') {
return (
<div className={cn(className)}>
<ERC20SwapAuthorization typedData={typedData} chainId={chainId} />
</div>
);
}

return <div className={cn(className)}>{children}</div>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { cn } from '@/lib/utils';
import { ArrowDown } from 'lucide-react';
import Image from 'next/image';
import { useMemo } from 'react';
import { findToken, getDefaultTokenList } from 'universal-data';
import {
decodeERC20BalanceGteWrapEnforcerTerms,
decodeEnforcerERC20TransferAmount,
getERC20BalanceGteWrapEnforcerFromDelegation,
getErc20TransferAmountEnforcerFromDelegation,
} from 'universal-delegations-sdk';
import type { Delegation } from 'universal-types';
import { type Address, formatUnits } from 'viem';

export type ERC20SwapAuthorization = React.HTMLAttributes<HTMLElement> & {
typedData: Delegation;
chainId: number;
};

export const ERC20SwapAuthorization = ({
className,
typedData,
chainId,
}: ERC20SwapAuthorization) => {
const data = useMemo(() => {
const { terms: erc20BalanceGteWrapEnforcerTerms } =
getERC20BalanceGteWrapEnforcerFromDelegation(typedData);
const { terms: erc20TransferAmountEnforceTerms } =
getErc20TransferAmountEnforcerFromDelegation(typedData);
const erc20TransferAmountEnforcerFormattedTerms =
decodeEnforcerERC20TransferAmount(erc20TransferAmountEnforceTerms);
const erc20BalanceGteWrapEnforcerFormattedTerms =
decodeERC20BalanceGteWrapEnforcerTerms(erc20BalanceGteWrapEnforcerTerms);

const addressOut = erc20TransferAmountEnforcerFormattedTerms[0] as Address;
const addressIn = erc20BalanceGteWrapEnforcerFormattedTerms[0] as Address;
const tokenList = getDefaultTokenList({ chainId });
const tokenOut = findToken({ tokenList, address: addressOut });
const tokenIn = findToken({ tokenList, address: addressIn });
if (!tokenOut || !tokenIn) {
throw new Error(`Token not found: ${addressIn}`);
}
return {
to: typedData.delegate,
amountOutFormatted: erc20TransferAmountEnforcerFormattedTerms[1],
amountInFormatted: erc20BalanceGteWrapEnforcerFormattedTerms[1],
tokenIn: tokenIn,
tokenOut: tokenOut,
};
}, [typedData, chainId]);

return (
<div className={cn(className)}>
<div className="flex flex-col justify-center gap-y-2 bg-neutral-100 p-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-x-1">
<Image
alt="Token Out"
src={data.tokenOut.logoURI}
className="size-8 rounded-full"
width={20}
height={20}
/>
<div className="flex flex-col gap-y-0">
<span className="font-bold text-lg text-primary/80">
{data.tokenOut.symbol}
</span>
<span className="font-light text-muted-foreground text-xs">
{data.tokenOut.name}
</span>
</div>
</div>
<span className="font-black text-2xl">
{formatUnits(
BigInt(data.amountOutFormatted),
data.tokenOut.decimals,
).toString()}
</span>
</div>
<ArrowDown className="ml-1.5 size-4 text-muted-foreground" />
<div className="flex items-center justify-between">
<div className="flex items-center gap-x-1">
<Image
alt="Token In"
src={data.tokenIn.logoURI}
className="size-8 rounded-full"
width={20}
height={50}
/>
<div className="flex flex-col gap-y-0">
<span className="font-bold text-lg text-primary/80">
{data.tokenIn.symbol}
</span>
<span className="font-light text-muted-foreground text-xs">
{data.tokenIn.name}
</span>
</div>
</div>
<span className="font-black text-2xl">
{formatUnits(
BigInt(data.amountInFormatted),
data.tokenIn.decimals,
).toString()}
</span>
</div>
</div>
</div>
);
};
4 changes: 2 additions & 2 deletions apps/popup/app/(site)/sign/eth-sign-typed-data-v-4/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import { RowBasic } from '@/components/row-basic';
import { Toggle } from '@/components/toggle';
import { Button } from '@/components/ui/button';
import type { Delegation } from 'universal-types';
import { useGetMessageChainId } from '@/lib/pop-up/hooks/use-get-message-chain-id';
import { useMemo, useState } from 'react';
import type { UniversalDID, VerificationRequest } from 'universal-identity-sdk';
import type { Delegation } from 'universal-types';
import type { TypedDataDefinition } from 'viem';
import { ActionRequestFooter } from '../components/action-request-footer';
import { ActionRequestHeader } from '../components/action-request-header';
Expand Down Expand Up @@ -65,7 +65,7 @@ export default function EthSignTypedDataV4Page() {
/>
</span>
</ActionRequestHeader>
<ActionRequestMain className="w-full px-4 py-4">
<ActionRequestMain className="w-full p-0">
{viewModeAdvanced === false && (
<DefaultRender
chainId={chain?.id || 1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,19 @@ export const stablecoinTokenList: TokenList = {
chainId: 8453,
name: 'Compound USDC',
symbol: 'cUSDCv3',
logoURI: 'https://ethereum-optimism.github.io/data/USDC/logo.png',
logoURI:
'https://assets.coingecko.com/coins/images/9442/standard/Compound_USDC.png?1696509534',
address: '0xb125e6687d4313864e53df431d5425969c15eb2f',
decimals: 6,
extensions: {
protocol: 'compound-v3',
metadata: {
protocol: 'Compound',
type: 'Yield Bearing',
url: 'https://compound.finance',
description:
'Compound USDC is a derivative of USDC, created after depositing into the Compound protocol. When you deposit your USDC into Compound, it gets lent out to others, and you earn fees paid by borrowers.',
},
},
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { universalDeployments } from 'universal-data';
import type { Delegation, DelegationCaveat } from 'universal-types';
import {
type Address,
type Hex,
Expand Down Expand Up @@ -30,3 +32,18 @@ export function decodeERC20BalanceGteWrapEnforcerTerms(data: Hex) {

return [token, BigInt(amount)] as const;
}

export function getERC20BalanceGteWrapEnforcerFromDelegation(
delegation: Delegation,
): DelegationCaveat {
const erc20TransferAmountEnforcer = delegation.caveats.find(
({ enforcer }) =>
enforcer.toLowerCase() ===
universalDeployments.ERC20BalanceGteWrapEnforcer.toLowerCase(),
);
if (!erc20TransferAmountEnforcer) {
throw new Error('No ERC20TransferAmountEnforcer found');
}

return erc20TransferAmountEnforcer;
}
13 changes: 7 additions & 6 deletions packages/universal-delegations-sdk/src/exports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,23 @@ export {
useDelegationsApiClient,
type DelegationsApiClient,
} from '../api/client.js';
export {
decodeEnforcerERC20TransferAmount,
encodeEnforcerERC20TransferAmount,
getErc20TransferAmountEnforcerFromDelegation,
} from '../enforcers/enforcer-erc20-transfer-amount.js';
export { encodeExternalCallEnforcerArgs } from '../enforcers/enforcer-external-call.js';
export { eip712DelegationTypes } from '../delegation/eip712-delegation-type.js';
export { encodeDelegation } from '../delegation/encode-delegation.js';
export {
getCaveatArrayPacketHash,
getCaveatPacketHash,
getDelegationHash,
} from '../delegation/get-delegation-hash.js';
export {
decodeEnforcerERC20TransferAmount,
encodeEnforcerERC20TransferAmount,
getErc20TransferAmountEnforcerFromDelegation,
} from '../enforcers/enforcer-erc20-transfer-amount.js';
export { encodeExternalCallEnforcerArgs } from '../enforcers/enforcer-external-call.js';
export {
decodeERC20BalanceGteWrapEnforcerTerms,
encodeERC20BalanceGteWrapEnforcerTerms,
getERC20BalanceGteWrapEnforcerFromDelegation,
} from '../enforcers/erc20-balance-gte-wrap-enforcer.js';
export { encodeBatchExecution } from '../execution/encode-batch-execution.js';
export { encodeSingleExecution } from '../execution/encode-single-execution.js';

0 comments on commit 20e2adb

Please sign in to comment.