Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const WalletSwitchEthereumChain = ({
if (import.meta.env.PROD)
return <RequestDisabled
headline={headline}
description="The Happy Wallet is an HappyChain exclusive 🤠"
description="The Happy Wallet is a HappyChain exclusive 🤠"
reject={reject}
/>

Expand Down
34 changes: 32 additions & 2 deletions apps/iframe/src/requests/handlers/injected.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import {
EIP1193SwitchChainError,
EIP1193UnauthorizedError,
EIP1474InvalidInput,
HappyWalletCapability,
type Msgs,
type ProviderMsgsFromApp,
WalletType,
} from "@happy.tech/wallet-common"
import type { Capabilities } from "viem"
import { privateKeyToAccount } from "viem/accounts"
import { checkAndChecksumAddress, checkedTx, checkedWatchedAsset } from "#src/requests/utils/checks"
import { checkAndChecksumAddress, checkAuthenticated, checkedTx, checkedWatchedAsset } from "#src/requests/utils/checks"
import { sendToPublicClient, sendToWalletClient } from "#src/requests/utils/sendToClient"
import {
getSessionKey,
Expand All @@ -25,7 +27,7 @@ import {
getTransactionReceipt,
} from "#src/requests/utils/shared"
import { eoaSigner, sessionKeySigner } from "#src/requests/utils/signers"
import { getChains, setChains, setCurrentChain } from "#src/state/chains"
import { getChains, getCurrentChain, setChains, setCurrentChain } from "#src/state/chains"
import { revokedSessionKeys } from "#src/state/interfaceState"
import { loadAbiForUser } from "#src/state/loadedAbis"
import { getPermissions, grantPermissions, revokePermissions } from "#src/state/permissions"
Expand Down Expand Up @@ -220,6 +222,34 @@ export async function dispatchInjectedRequest(request: ProviderMsgsFromApp[Msgs.
return addWatchedAsset(user.address, params)
}

case "wallet_getCapabilities": {
checkAuthenticated()
if (!request.payload?.params?.[0] || !request.payload?.params?.[1]) {
throw new EIP1474InvalidInput("Missing payload parameters")
}
checkAndChecksumAddress(request.payload.params[0])

const currentChainId = getCurrentChain().chainId
if (request.payload.params[1].length > 1) {
const requestedChainIds = request.payload.params[1]
for (const chainId of requestedChainIds) {
if (chainId !== currentChainId) {
console.warn(
`Unsupported chain ID requested: ${chainId}. The Happy Wallet is a HappyChain exclusive 🤠!`,
)
}
}
}

const capabilities: Capabilities = {
[currentChainId]: Object.fromEntries(
Object.values(HappyWalletCapability).map((capability) => [capability, { supported: true }]),
),
}

return capabilities
}

case HappyMethodNames.LOAD_ABI: {
return user ? loadAbiForUser(user.address, request.payload.params) : undefined
}
Expand Down
39 changes: 37 additions & 2 deletions apps/iframe/src/requests/handlers/permissionless.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { HappyMethodNames } from "@happy.tech/common"
import { EIP1193UserRejectedRequestError, type Msgs, type ProviderMsgsFromApp } from "@happy.tech/wallet-common"
import { isAddress } from "viem"
import { isAddress } from "@happy.tech/common"
import {
EIP1193UserRejectedRequestError,
EIP1474InvalidInput,
type Msgs,
type ProviderMsgsFromApp,
} from "@happy.tech/wallet-common"
import { HappyWalletCapability } from "@happy.tech/wallet-common"
import type { Capabilities } from "viem"
import { sendBoop } from "#src/requests/utils/boop"
import { checkAndChecksumAddress, checkAuthenticated, checkedTx } from "#src/requests/utils/checks"
import { sendToPublicClient } from "#src/requests/utils/sendToClient"
Expand Down Expand Up @@ -93,6 +100,34 @@ export async function dispatchedPermissionlessRequest(request: ProviderMsgsFromA
// If this is permissionless, we're already on the right chain so we simply succeed.
return null

case "wallet_getCapabilities": {
checkAuthenticated()
if (!request.payload?.params?.[0] || !request.payload?.params?.[1]) {
throw new EIP1474InvalidInput("Missing payload parameters")
}
checkAndChecksumAddress(request.payload.params[0])

const currentChainId = getCurrentChain().chainId
if (request.payload.params[1].length > 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess should also check if the length is one, and if any of the chains are happyChain/currentChain (if they only request mainnet right now, it would not behave correctly)

const requestedChainIds = request.payload.params[1]
for (const chainId of requestedChainIds) {
if (chainId !== currentChainId) {
console.warn(
`Unsupported chain ID requested: ${chainId}. The Happy Wallet is a HappyChain exclusive 🤠!`,
)
}
}
}

const capabilities: Capabilities = {
[currentChainId]: Object.fromEntries(
Object.values(HappyWalletCapability).map((capability) => [capability, { supported: true }]),
),
Comment on lines +123 to +125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could compute this once at a global level, instead on each request

// support/wallet-common/lib/interfaces/eip5792.ts
export const walletCapabilities = Object.fromEntries(
    Object.values(HappyWalletCapability)
        .map((capability) => [capability, { supported: true }])
)
Suggested change
[currentChainId]: Object.fromEntries(
Object.values(HappyWalletCapability).map((capability) => [capability, { supported: true }]),
),
[currentChainId]: walletCapabilities,

}

return capabilities
}

case HappyMethodNames.REQUEST_SESSION_KEY: {
getCheckedUser()
const target = checkAndChecksumAddress(request.payload.params[0])
Expand Down
4 changes: 2 additions & 2 deletions apps/iframe/src/requests/utils/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export function checkedWatchedAsset(params: WatchAssetParameters) {
* Checks that the address is valid, or throws.
* @throws EIP1474InvalidInput if the address is invalid
*/
export function checkAddress(address: string): asserts address is Address {
if (!isAddress(address)) throw new EIP1474InvalidInput(`invalid address: ${address}`)
export function checkAddress(address?: string): asserts address is Address {
if (!address || !isAddress(address)) throw new EIP1474InvalidInput(`invalid address: ${address}`)
}

/**
Expand Down
9 changes: 1 addition & 8 deletions apps/submitter/bin/benchmarkLatency.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
BoopClient,
CreateAccount,
type ExecuteSuccess,
GetNonce,
Onchain,
computeBoopHash,
} from "@happy.tech/boop-sdk"
import { BoopClient, CreateAccount, computeBoopHash } from "@happy.tech/boop-sdk"
import { delayed, stringify } from "@happy.tech/common"
import { type PrivateKeyAccount, generatePrivateKey, privateKeyToAccount } from "viem/accounts"
import { createAndSignMintBoop } from "#lib/utils/test/helpers"
Expand Down
1 change: 1 addition & 0 deletions support/wallet-common/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export { shortenAddress } from "./utils/shortenAddress"
export type { Chain, ChainBlockExplorer, ChainContract, ChainRpcUrls, ChainNativeCurrency } from "./chains/viem"
export { Msgs, WalletDisplayAction } from "./interfaces/events"
export type { RecordAbiPayload } from "./interfaces/eip1193"
export { HappyWalletCapability } from "./interfaces/eip5792"
export type { ChainParameters } from "./chains/utils"
export type { ConnectionProvider } from "./interfaces/connectionProvider"
export type { HappyUser } from "./interfaces/happyUser"
Expand Down
3 changes: 3 additions & 0 deletions support/wallet-common/lib/interfaces/eip5792.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum HappyWalletCapability {
BoopPaymaster = "boopPaymaster",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only capability we currently support!

}
1 change: 1 addition & 0 deletions support/wallet-common/lib/interfaces/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const safeList = new Set([
"wallet_revokePermissions", // https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-2.md
"web3_clientVersion",
"web3_sha3",
"wallet_getCapabilities",
])

/**
Expand Down