Skip to content

Commit

Permalink
chore: continued
Browse files Browse the repository at this point in the history
chore: lint
  • Loading branch information
joepegler committed Jul 2, 2024
1 parent aeab05f commit b9e2cb1
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 244 deletions.
Binary file modified bun.lockb
Binary file not shown.
207 changes: 39 additions & 168 deletions src/components/Modules/CreateDanSession.tsx
Original file line number Diff line number Diff line change
@@ -1,130 +1,38 @@
import {
type CreateSessionDataParams,
DEFAULT_SESSION_KEY_MANAGER_MODULE,
type DanModuleInfo,
PaymasterMode,
type Session,
SessionLocalStorage,
type Transaction,
createDANSessionKeyManagerModule,
createERC20SessionDatum,
createSessionKeyEOA,
getChain
getDANSessionKey
} from "@biconomy/account"
import { bigIntReplacer, useSmartAccount } from "@biconomy/use-aa"
import { makeStyles } from "@mui/styles"
import * as ed from "@noble/ed25519"
import { ethers } from "ethers"
import type React from "react"
import { useEffect, useState } from "react"
import { useState } from "react"
import { ToastContainer } from "react-toastify"
import "react-toastify/dist/ReactToastify.css"
import { type Hex, encodeAbiParameters, keccak256, parseUnits } from "viem"
import { useAccount, useClient } from "wagmi"
import { type Hex, encodeAbiParameters, parseUnits } from "viem"
import { useAccount } from "wagmi"
import Button from "../Button"
import UseDanSession from "./UseDanSession"

import {
EOAAuth,
type IBrowserWallet,
type KeygenResponse,
NetworkSigner,
type TypedData,
WalletProviderServiceClient
} from "@silencelaboratories/walletprovider-sdk"
import { configInfo } from "../../utils"

let ephSK: Uint8Array | null = null
let ephPK: Uint8Array | null = null
let keyIdToPass: string | null = null

interface EIP6963ProviderInfo {
uuid: string
name: string
icon: string
rdns: string
}

interface RequestArguments {
readonly method: string
readonly params?: readonly unknown[] | object
}

interface EIP1193Provider {
isStatus?: boolean
host?: string
path?: string

request: (request: RequestArguments) => Promise<unknown>
}

export type WalletProviderDefs = {
walletProviderId: string
walletProviderUrl: string
}

export type Config = {
walletProvider: WalletProviderDefs
}

const createWalletProviderService = async (config: Config) =>
new WalletProviderServiceClient({
walletProviderId: config.walletProvider.walletProviderId,
walletProviderUrl: config.walletProvider.walletProviderUrl
})

let selectedBrowserWallet: EIP1193Provider | null = null

// Sign data using the secret key stored on Browser Wallet
// It creates a popup window, presenting the human readable form of `request`
// Throws an error if User rejected signature
export class BrowserWallet implements IBrowserWallet {
async signTypedData<T>(
from: string,
request: TypedData<T>
): Promise<unknown> {
console.log(selectedBrowserWallet)

//should be provider
return await selectedBrowserWallet!.request({
method: "eth_signTypedData_v4",
params: [from, JSON.stringify(request)]
})
}
}

// Function to convert hex string to Uint8Array
function hexToUint8Array(hex: string) {
if (hex.length % 2 !== 0) {
throw new Error("Hex string must have an even number of characters")
}
const array = new Uint8Array(hex.length / 2)
for (let i = 0; i < hex.length; i += 2) {
array[i / 2] = Number.parseInt(hex.substr(i, 2), 16)
}
return array
}

const CreateDanSession: React.FC = () => {
const classes = useStyles()
const token = configInfo.usdc.address as Hex
const amount = parseUnits("50".toString(), 6)

const { address: eoa, connector } = useAccount()
const client = useClient()
const { address: eoa } = useAccount()
const { smartAccountAddress, smartAccountClient } = useSmartAccount()
const [session, setSession] = useState<Session | null>(null)
const [provider, setProvider] = useState<EIP1193Provider | null>(null)

useEffect(() => {
const fetchProvider = async () => {
if (connector) {
const prov = await connector.getProvider()
prov && setProvider(prov as EIP1193Provider)
selectedBrowserWallet = prov as EIP1193Provider
}
}
fetchProvider()
}, [connector])
const [danModuleInfo, setDanModuleInfo] = useState<
undefined | DanModuleInfo
>()

const policy: any[] = [
{ interval: { validAfter: 0, validUntil: 0 } },
Expand All @@ -147,68 +55,25 @@ const CreateDanSession: React.FC = () => {
"to create the session"
)

// const sk = ed.utils.randomPrivateKey();
const sk = hexToUint8Array(import.meta.env.VITE_EPHEMERAL_KEY!)
// Global variable for now
ephSK = sk
ephPK = await ed.getPublicKeyAsync(sk)

const clusterConfig = {
walletProvider: {
walletProviderId: "WalletProvider",
walletProviderUrl: "ws://localhost:8090/v1"
}
}

const wpClient = await createWalletProviderService(clusterConfig)

// Authenticate using EOA
const eoaAuth = new EOAAuth(
eoa!,
new BrowserWallet(),
ephPK,
// Lifetime of one hour
60 * 60
)

console.log("ephemeral public key:", ephPK)

const threshold = 11
const partiesNumber = 20

const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, eoaAuth)

// Generate a new key
const resp: KeygenResponse = await sdk.authenticateAndCreateKey(ephPK)

console.log("keygen response:", resp)

// resp.publicKey
// get EOA from public key which will be session key EOA

const pubKey = resp.publicKey

const keyId = resp.keyId
console.log("selected keyId", keyId)

keyIdToPass = keyId

if (pubKey.startsWith("0x")) {
// const pubKey = resp.publicKey;
}

// Compute the Keccak-256 hash of the public key
const hash = keccak256(("0x" + pubKey) as Hex)

// The Ethereum address is the last 20 bytes of the hash
const sessionKeyEOA = ("0x" + hash.slice(-40)) as Hex

console.log("sessionKeyEOA a", sessionKeyEOA)
const {
sessionKeyEOA,
mpcKeyId,
ephSK,
partiesNumber,
threshold,
eoaAddress
} = await getDANSessionKey(smartAccountClient)

setDanModuleInfo({
mpcKeyId,
ephSK,
partiesNumber,
threshold,
eoaAddress,
chainId: 80002
})

const { sessionStorageClient } = await createSessionKeyEOA(
smartAccountClient,
getChain(80002)
)
const sessionStorageClient = new SessionLocalStorage(smartAccountAddress)

const sessionsModule = await createDANSessionKeyManagerModule({
smartAccountAddress,
Expand All @@ -235,8 +100,11 @@ const CreateDanSession: React.FC = () => {
const { data: policyData, sessionIDInfo } =
await sessionsModule.createSessionData([createSessionDataParams])

console.log("policyData", policyData)
console.log("sessionIDInfo", sessionIDInfo)
console.log("sessionKeyEOA a", sessionKeyEOA, {
matchedLeaf: await sessionStorageClient.getSessionData({
sessionID: sessionIDInfo[0]
})
})

const permitTx = {
to: DEFAULT_SESSION_KEY_MANAGER_MODULE,
Expand Down Expand Up @@ -264,7 +132,10 @@ const CreateDanSession: React.FC = () => {
txs.push(permitTx)

const userOpResponse = await smartAccountClient.sendTransaction(txs, {
paymasterServiceData: { mode: PaymasterMode.SPONSORED }
paymasterServiceData: { mode: PaymasterMode.SPONSORED },
nonceOptions: {
nonceKey: Date.now()
}
})

console.log("userOpResponse", userOpResponse)
Expand All @@ -278,7 +149,7 @@ const CreateDanSession: React.FC = () => {

const resultingSession = {
sessionStorageClient,
sessionIDInfo,
sessionIDInfo
}

// Handle Success. Keep the "Session" (StorageClient and sessionIDs) and set it to the session
Expand Down Expand Up @@ -314,8 +185,8 @@ const CreateDanSession: React.FC = () => {

<pre>policy: {JSON.stringify(policy, bigIntReplacer, 2)}</pre>

{!!session ? (
<UseDanSession session={session} mpcKeyId={keyIdToPass!} />
{!!session && danModuleInfo ? (
<UseDanSession session={session} danModuleInfo={danModuleInfo!} />
) : (
<Button title="Create Session" onClickFunc={createDanSessionHandler} />
)}
Expand Down
19 changes: 12 additions & 7 deletions src/components/Modules/CreateSession.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const CreateSession: React.FC = () => {

const nftAddress: Hex = "0x1758f42Af7026fBbB559Dc60EcE0De3ef81f665e"

const [hasSession, setHasSession] = useState<boolean>(false)
const { address } = useAccount()
const { smartAccountAddress: scwAddress } = useSmartAccount()

Expand Down Expand Up @@ -53,6 +52,10 @@ const CreateSession: React.FC = () => {
isPending: isLoading
} = useCreateSession()

// @ts-ignore
const sessionID = userOpResponse?.session?.sessionIDInfo?.[0]
console.log(sessionID)

const {
isLoading: waitIsLoading,
isSuccess: waitIsSuccess,
Expand All @@ -62,7 +65,6 @@ const CreateSession: React.FC = () => {

useEffect(() => {
if (waitIsSuccess) {
setHasSession(true)
showSuccessMessage(
`Successful mint: ${polygonAmoy.blockExplorers.default.url}/tx/${waitData?.receipt?.transactionHash}`
)
Expand All @@ -79,12 +81,11 @@ const CreateSession: React.FC = () => {
<main className={classes.main}>
<ErrorGuard errors={[error, waitError]}>
<p style={{ color: "#7E7E7E" }}>
Use Cases {"->"} Modules {"->"} {hasSession ? "Use" : "Create"}{" "}
Session
Use Cases {"->"} Modules {"->"} {sessionID ? "Use" : "Create"} Session
</p>

<h3 className={classes.subTitle}>
{hasSession ? "Use" : "Create"} a Session
{sessionID ? "Use" : "Create"} a Session
</h3>

<ToastContainer
Expand All @@ -102,8 +103,12 @@ const CreateSession: React.FC = () => {

<pre>policy: {JSON.stringify(policy, bigIntReplacer, 2)}</pre>

{!!hasSession ? (
<UseSession smartAccountAddress={scwAddress} address={address!} />
{!!sessionID ? (
<UseSession
smartAccountAddress={scwAddress}
address={address!}
sessionID={sessionID}
/>
) : (
<Button
title="Create Session"
Expand Down
Loading

0 comments on commit b9e2cb1

Please sign in to comment.