Skip to content

Commit

Permalink
add experimental/smart-session (#2875)
Browse files Browse the repository at this point in the history
Co-authored-by: tomiir <rocchitomas@gmail.com>
  • Loading branch information
KannuSingh and tomiir authored Oct 7, 2024
1 parent c5a2107 commit d0f4d54
Show file tree
Hide file tree
Showing 54 changed files with 2,562 additions and 1,175 deletions.
2 changes: 2 additions & 0 deletions apps/laboratory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@
"@reown/appkit-solana": "workspace:*",
"@reown/appkit-wagmi": "workspace:*",
"@reown/appkit-wallet": "workspace:*",
"@reown/appkit-experimental": "workspace:*",
"@reown/appkit-adapter-solana": "workspace:*",
"@reown/appkit-adapter-ethers": "workspace:*",
"@reown/appkit-adapter-ethers5": "workspace:*",
"@reown/appkit-adapter-wagmi": "workspace:*",
"axios": "1.7.2",
"bs58": "6.0.0",
"date-fns": "4.1.0",
"ethers": "6.13.2",
"ethers5": "npm:ethers@5.7.2",
"framer-motion": "10.17.9",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react'
import { StackDivider, Heading, Box, Stack, Text } from '@chakra-ui/react'
import { getChain } from '../utils/NetworksUtil'
import { formatDistanceToNow } from 'date-fns'
import type { SmartSessionGrantPermissionsResponse } from '@reown/appkit-experimental/smart-session'

export function SmartSessionGrantedPermissionsInfo({
grantedPermissions
}: {
grantedPermissions: SmartSessionGrantPermissionsResponse | undefined
}) {
if (!grantedPermissions?.context) {
return (
<Text fontSize="md" color="yellow">
Dapp does not have any stored permissions
</Text>
)
}

const { address, chainId, expiry } = grantedPermissions
const parsedExpiry = formatDistanceToNow(new Date(expiry * 1000), { addSuffix: true })
const parsedChainId = parseInt(chainId, 16)
const chain = getChain(parsedChainId)

return (
<Stack direction={['column', 'column', 'row']} divider={<StackDivider />} spacing="4">
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Account Address
</Heading>
<Text>{address}</Text>
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Chain Id
</Heading>
<Text>{chain?.name || chainId}</Text>
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Expiry
</Heading>
<Text>{parsedExpiry}</Text>
</Box>
</Stack>
)
}
12 changes: 12 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiPermissionsAsyncTest.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { Box, Card, CardBody, CardHeader, Heading, Stack, StackDivider } from '@chakra-ui/react'
import { WagmiRequestPermissionsAsyncTest } from './WagmiRequestPermissionsAsyncTest'
import { WagmiPurchaseDonutAsyncPermissionsTest } from './WagmiPurchaseDonutAsyncPermissionsTest'
import { SmartSessionGrantedPermissionsInfo } from '../SmartSessionGrantedPermissionsInfo'
import { useERC7715Permissions } from '../../hooks/useERC7715Permissions'

export function WagmiPermissionsAsyncTest() {
const { smartSession } = useERC7715Permissions()
const grantedPermissions =
smartSession?.type === 'async' ? smartSession.grantedPermissions : undefined

return (
<Card marginTop={10} marginBottom={10}>
<CardHeader>
<Heading size="md">Test Interactions</Heading>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />} spacing="4">
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Existing Session Information
</Heading>
<SmartSessionGrantedPermissionsInfo grantedPermissions={grantedPermissions} />
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Request Permissions
Expand Down
12 changes: 12 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiPermissionsSyncTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@ import { Box, Card, CardBody, CardHeader, Heading, Stack, StackDivider } from '@
import { WagmiRequestPermissionsSyncTest } from './WagmiRequestPermissionsSyncTest'
import { WagmiPurchaseDonutSyncPermissionsTest } from './WagmiPurchaseDonutSyncPermissionsTest'
import { WagmiCreatePasskeySignerTest } from './WagmiCreatePasskeySignerTest'
import { SmartSessionGrantedPermissionsInfo } from '../SmartSessionGrantedPermissionsInfo'
import { useERC7715Permissions } from '../../hooks/useERC7715Permissions'

export function WagmiPermissionsSyncTest() {
const { smartSession } = useERC7715Permissions()
const grantedPermissions =
smartSession?.type === 'sync' ? smartSession.grantedPermissions : undefined

return (
<Card marginTop={10} marginBottom={10}>
<CardHeader>
<Heading size="md">Test Interactions</Heading>
</CardHeader>
<CardBody>
<Stack divider={<StackDivider />} spacing="4">
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Existing Session Information
</Heading>
<SmartSessionGrantedPermissionsInfo grantedPermissions={grantedPermissions} />
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
New Passkey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,34 @@ import { useState } from 'react'
import { useChakraToast } from '../Toast'
import { encodeFunctionData, parseEther } from 'viem'
import { abi as donutContractAbi, address as donutContractaddress } from '../../utils/DonutContract'
import { sepolia } from 'viem/chains'
import { useLocalEcdsaKey } from '../../context/LocalEcdsaKeyContext'
import { useERC7715Permissions } from '../../hooks/useERC7715Permissions'
import { executeActionsWithECDSAAndCosignerPermissions } from '../../utils/ERC7715Utils'
import { executeActionsWithECDSAKey } from '../../utils/ERC7715Utils'
import { getChain } from '../../utils/NetworksUtil'
import type { SmartSessionGrantPermissionsResponse } from '@reown/appkit-experimental/smart-session'

export function WagmiPurchaseDonutAsyncPermissionsTest() {
const { privateKey } = useLocalEcdsaKey()
const { smartSession } = useERC7715Permissions()

if (smartSession?.type !== 'async' || !smartSession.grantedPermissions?.context) {
return (
<Text fontSize="md" color="yellow">
Dapp does not have the permissions
</Text>
)
}

const { grantedPermissions, pci } = useERC7715Permissions()
return <ConnectedTestContent grantedPermissions={smartSession.grantedPermissions} />
}

function ConnectedTestContent({
grantedPermissions
}: {
grantedPermissions: SmartSessionGrantPermissionsResponse
}) {
const { privateKey } = useLocalEcdsaKey()
const toast = useChakraToast()
const [isTransactionPending, setTransactionPending] = useState<boolean>(false)

const {
data: donutsOwned,
Expand All @@ -23,24 +42,24 @@ export function WagmiPurchaseDonutAsyncPermissionsTest() {
abi: donutContractAbi,
address: donutContractaddress,
functionName: 'getBalance',
args: [grantedPermissions?.signerData?.submitToAddress || '0x']
args: [grantedPermissions.address]
})

const [isTransactionPending, setTransactionPending] = useState<boolean>(false)
const toast = useChakraToast()

async function onPurchaseDonutWithPermissions() {
setTransactionPending(true)
try {
if (!privateKey) {
throw new Error(`Unable to get dApp private key`)
const chainId = parseInt(grantedPermissions.chainId, 16)
if (!chainId) {
throw new Error('Chain ID not available in granted permissions')
}
if (!grantedPermissions) {
throw Error('No permissions available')
const chain = getChain(chainId)
if (!chain) {
throw new Error('Unknown chainId')
}
if (!pci) {
throw Error('No WC cosigner data(PCI) available')
if (!privateKey) {
throw new Error(`Unable to get dApp private key`)
}

const purchaseDonutCallData = encodeFunctionData({
abi: donutContractAbi,
functionName: 'purchase',
Expand All @@ -53,12 +72,12 @@ export function WagmiPurchaseDonutAsyncPermissionsTest() {
data: purchaseDonutCallData
}
]
const txHash = await executeActionsWithECDSAAndCosignerPermissions({
const txHash = await executeActionsWithECDSAKey({
actions: purchaseDonutCallDataExecution,
chain: sepolia,
chain,
ecdsaPrivateKey: privateKey as `0x${string}`,
permissions: grantedPermissions,
pci
accountAddress: grantedPermissions.address,
permissionsContext: grantedPermissions.context
})
if (txHash) {
toast({
Expand All @@ -77,16 +96,9 @@ export function WagmiPurchaseDonutAsyncPermissionsTest() {
}
setTransactionPending(false)
}
if (!grantedPermissions) {
return (
<Text fontSize="md" color="yellow">
Dapp does not have the permissions
</Text>
)
}

return (
<Stack direction={['column', 'column', 'row']}>
<Stack direction={['column']}>
<Button
isDisabled={!grantedPermissions}
isLoading={isTransactionPending}
Expand All @@ -99,7 +111,7 @@ export function WagmiPurchaseDonutAsyncPermissionsTest() {
<Text>Fetching donuts...</Text>
) : (
<>
<Text marginRight="5px">Crypto donuts left:</Text>
<Text marginRight="5px">Crypto donuts purchased:</Text>
<Text>{donutsOwned?.toString()}</Text>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,31 @@ import { encodeFunctionData, parseEther } from 'viem'
import { abi as donutContractAbi, address as donutContractaddress } from '../../utils/DonutContract'
import { useERC7715Permissions } from '../../hooks/useERC7715Permissions'
import { usePasskey } from '../../context/PasskeyContext'
import { sepolia } from 'viem/chains'
import { executeActionsWithPasskeyAndCosignerPermissions } from '../../utils/ERC7715Utils'
import { executeActionsWithPasskey } from '../../utils/ERC7715Utils'
import { getChain } from '../../utils/NetworksUtil'
import type { SmartSessionGrantPermissionsResponse } from '@reown/appkit-experimental/smart-session'

export function WagmiPurchaseDonutSyncPermissionsTest() {
const { smartSession } = useERC7715Permissions()

if (smartSession?.type !== 'sync' || !smartSession.grantedPermissions?.context) {
return (
<Text fontSize="md" color="yellow">
Dapp does not have the permissions
</Text>
)
}

return <ConnectedTestContent grantedPermissions={smartSession.grantedPermissions} />
}
function ConnectedTestContent({
grantedPermissions
}: {
grantedPermissions: SmartSessionGrantPermissionsResponse
}) {
const { passkeyId } = usePasskey()
const { grantedPermissions, pci } = useERC7715Permissions()
const toast = useChakraToast()
const [isTransactionPending, setTransactionPending] = useState<boolean>(false)

const {
data: donutsOwned,
Expand All @@ -22,22 +41,23 @@ export function WagmiPurchaseDonutSyncPermissionsTest() {
abi: donutContractAbi,
address: donutContractaddress,
functionName: 'getBalance',
args: [grantedPermissions?.signerData?.submitToAddress || '0x']
args: [grantedPermissions.address]
})

const [isTransactionPending, setTransactionPending] = useState<boolean>(false)
const toast = useChakraToast()

async function onPurchaseDonutWithPermissions() {
setTransactionPending(true)
try {
if (!grantedPermissions) {
throw Error('No permissions available')
const chainId = parseInt(grantedPermissions.chainId, 16)
if (!chainId) {
throw new Error('Chain ID not available in granted permissions')
}
if (!pci) {
throw Error('No WC cosigner data(PCI) available')
const chain = getChain(chainId)
if (!chain) {
throw new Error('Unknown chainId')
}
if (!passkeyId) {
throw new Error(`Unable to get passkeyId`)
}

const purchaseDonutCallData = encodeFunctionData({
abi: donutContractAbi,
functionName: 'purchase',
Expand All @@ -50,12 +70,12 @@ export function WagmiPurchaseDonutSyncPermissionsTest() {
data: purchaseDonutCallData
}
]
const txHash = await executeActionsWithPasskeyAndCosignerPermissions({
const txHash = await executeActionsWithPasskey({
accountAddress: grantedPermissions.address,
actions: purchaseDonutCallDataExecution,
chain: sepolia,
chain,
passkeyId,
permissions: grantedPermissions,
pci
permissionsContext: grantedPermissions.context
})
if (txHash) {
toast({
Expand All @@ -75,14 +95,6 @@ export function WagmiPurchaseDonutSyncPermissionsTest() {
setTransactionPending(false)
}

if (!grantedPermissions) {
return (
<Text fontSize="md" color="yellow">
Dapp does not have the permissions
</Text>
)
}

return (
<Stack direction={['column', 'column', 'row']}>
<Button
Expand Down
Loading

0 comments on commit d0f4d54

Please sign in to comment.