Skip to content

Commit

Permalink
fix: account passthrough (#3533)
Browse files Browse the repository at this point in the history
* fix: account passthrough

* chore: snaps

* refactor: up

* chore: changeset

* chore: snaps

* chore: up
  • Loading branch information
tmm committed Jan 30, 2024
1 parent 347c535 commit 9c3b85d
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-bats-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wagmi/core": patch
---

Fixed `account` property passthrough for actions.
39 changes: 38 additions & 1 deletion packages/core/src/actions/prepareTransactionRequest.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { accounts, config } from '@wagmi/test'
import { accounts, config, privateKey } from '@wagmi/test'
import { expect, test } from 'vitest'

import { parseEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { connect } from './connect.js'
import { disconnect } from './disconnect.js'
import { prepareTransactionRequest } from './prepareTransactionRequest.js'
Expand Down Expand Up @@ -53,6 +54,7 @@ test('parameters: account', async () => {
} = request
expect(rest).toMatchInlineSnapshot(`
{
"account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
"type": "eip1559",
Expand Down Expand Up @@ -90,3 +92,38 @@ test('parameters: connector', async () => {

await disconnect(config, { connector })
})

test('behavior: local account', async () => {
const account = privateKeyToAccount(privateKey)

const request = await prepareTransactionRequest(config, {
account,
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1'),
})

const {
gas: _gas,
maxFeePerGas: _mfpg,
maxPriorityFeePerGas: _mpfpg,
nonce: _nonce,
...rest
} = request
expect(rest).toMatchInlineSnapshot(`
{
"account": {
"address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"publicKey": "0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5",
"signMessage": [Function],
"signTransaction": [Function],
"signTypedData": [Function],
"source": "privateKey",
"type": "local",
},
"from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
"type": "eip1559",
"value": 1000000000000000000n,
}
`)
})
19 changes: 11 additions & 8 deletions packages/core/src/actions/prepareTransactionRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,22 @@ export async function prepareTransactionRequest<
PrepareTransactionRequestReturnType<parameterType, config, chainId>
> {
const { account, chainId, connector, ...rest } = parameters
const client = await getConnectorClient(config, {
account,
chainId,
connector,
})

let client
if (typeof account === 'object' && account.type === 'local')
client = config.getClient({ chainId })
else
client = await getConnectorClient(config, { account, chainId, connector })

const action = getAction(
client,
viem_prepareTransactionRequest,
'prepareTransactionRequest',
)
return action(
rest as unknown as viem_PrepareTransactionRequestParameters,
) as unknown as Promise<
return action({
...rest,
...(account ? { account } : {}),
} as unknown as viem_PrepareTransactionRequestParameters) as unknown as Promise<
PrepareTransactionRequestReturnType<parameterType, config, chainId>
>
}
14 changes: 13 additions & 1 deletion packages/core/src/actions/sendTransaction.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { config, transactionHashRegex } from '@wagmi/test'
import { config, privateKey, transactionHashRegex } from '@wagmi/test'
import { parseEther } from 'viem'
import { expect, test } from 'vitest'

import { privateKeyToAccount } from 'viem/accounts'
import { connect } from './connect.js'
import { disconnect } from './disconnect.js'
import { sendTransaction } from './sendTransaction.js'
Expand Down Expand Up @@ -81,3 +82,14 @@ test('behavior: value exceeds balance', async () => {
`)
await disconnect(config, { connector })
})

test('behavior: local account', async () => {
const account = privateKeyToAccount(privateKey)
await expect(
sendTransaction(config, {
account,
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
}),
).resolves.toMatch(transactionHashRegex)
})
12 changes: 7 additions & 5 deletions packages/core/src/actions/sendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ export async function sendTransaction<
): Promise<SendTransactionReturnType> {
const { account, chainId, connector, gas: gas_, ...rest } = parameters

const client = await getConnectorClient(config, {
account,
chainId,
connector,
})
let client
if (typeof account === 'object' && account.type === 'local')
client = config.getClient({ chainId })
else
client = await getConnectorClient(config, { account, chainId, connector })

const gas = await (async () => {
// Skip gas estimation if `null` is provided.
Expand All @@ -83,6 +83,7 @@ export async function sendTransaction<
const action = getAction(client, viem_estimateGas, 'estimateGas')
return action({
...(rest as any),
account,
chain: chainId ? { id: chainId } : null,
})
}
Expand All @@ -94,6 +95,7 @@ export async function sendTransaction<
const action = getAction(client, viem_sendTransaction, 'sendTransaction')
const hash = await action({
...(rest as any),
...(account ? { account } : {}),
gas,
chain: chainId ? { id: chainId } : null,
})
Expand Down
17 changes: 16 additions & 1 deletion packages/core/src/actions/signMessage.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { accounts, config } from '@wagmi/test'
import { accounts, config, privateKey } from '@wagmi/test'
import { recoverMessageAddress } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { expect, test } from 'vitest'

import { mock } from '../connectors/mock.js'
Expand All @@ -22,6 +23,20 @@ test('default', async () => {
await disconnect(config, { connector })
})

test('behavior: local account', async () => {
const account = privateKeyToAccount(privateKey)
const signature = await signMessage(config, {
account,
message: 'foo bar baz',
})
await expect(
recoverMessageAddress({
message: 'foo bar baz',
signature,
}),
).resolves.toEqual(account.address)
})

test('behavior: user rejected request', async () => {
const connector_ = config._internal.connectors.setup(
mock({
Expand Down
16 changes: 12 additions & 4 deletions packages/core/src/actions/signMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
} from 'viem/actions'

import { type Config } from '../createConfig.js'
import type { BaseErrorType, ErrorType } from '../errors/base.js'
import type { ConnectorParameter } from '../types/properties.js'
import { type BaseErrorType, type ErrorType } from '../errors/base.js'
import { type ConnectorParameter } from '../types/properties.js'
import { type Evaluate } from '../types/utils.js'
import { getAction } from '../utils/getAction.js'
import {
Expand Down Expand Up @@ -37,7 +37,15 @@ export async function signMessage(
parameters: SignMessageParameters,
): Promise<SignMessageReturnType> {
const { account, connector, ...rest } = parameters
const client = await getConnectorClient(config, { account, connector })

let client
if (typeof account === 'object' && account.type === 'local')
client = config.getClient()
else client = await getConnectorClient(config, { account, connector })

const action = getAction(client, viem_signMessage, 'signMessage')
return action(rest as viem_SignMessageParameters<Account>)
return action({
...rest,
...(account ? { account } : {}),
} as viem_SignMessageParameters<Account>)
}
21 changes: 20 additions & 1 deletion packages/core/src/actions/signTypedData.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { accounts, config, typedData } from '@wagmi/test'
import { accounts, config, privateKey, typedData } from '@wagmi/test'
import { recoverTypedDataAddress } from 'viem'
import { expect, test } from 'vitest'

import { privateKeyToAccount } from 'viem/accounts'
import { mock } from '../connectors/mock.js'
import { connect } from './connect.js'
import { disconnect } from './disconnect.js'
Expand Down Expand Up @@ -64,3 +65,21 @@ test('behavior: not connected', async () => {
Version: @wagmi/core@x.y.z]
`)
})

test('behavior: local account', async () => {
const account = privateKeyToAccount(privateKey)
const signature = await signTypedData(config, {
account,
types: typedData.basic.types,
primaryType: 'Mail',
message: typedData.basic.message,
})
await expect(
recoverTypedDataAddress({
types: typedData.basic.types,
primaryType: 'Mail',
message: typedData.basic.message,
signature,
}),
).resolves.toBe(account.address)
})
12 changes: 10 additions & 2 deletions packages/core/src/actions/signTypedData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,15 @@ export async function signTypedData<
parameters: SignTypedDataParameters<typedData, primaryType>,
): Promise<SignTypedDataReturnType> {
const { account, connector, ...rest } = parameters
const client = await getConnectorClient(config, { account, connector })

let client
if (typeof account === 'object' && account.type === 'local')
client = config.getClient()
else client = await getConnectorClient(config, { account, connector })

const action = getAction(client, viem_signTypedData, 'signTypedData')
return action(rest as unknown as viem_SignTypedDataParameters)
return action({
...rest,
...(account ? { account } : {}),
} as unknown as viem_SignTypedDataParameters)
}
19 changes: 10 additions & 9 deletions packages/core/src/actions/writeContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,26 @@ export async function writeContract<
): Promise<WriteContractReturnType> {
const { account, chainId, connector, __mode, ...rest } = parameters

const client = await getConnectorClient(config, {
account,
chainId,
connector,
})
let client
if (typeof account === 'object' && account.type === 'local')
client = config.getClient({ chainId })
else
client = await getConnectorClient(config, { account, chainId, connector })

let request
if (__mode === 'prepared') request = rest
else {
const { request: simulateRequest } = await simulateContract(
config,
rest as any,
)
const { request: simulateRequest } = await simulateContract(config, {
...rest,
account,
} as any)
request = simulateRequest
}

const action = getAction(client, viem_writeContract, 'writeContract')
const hash = await action({
...(request as any),
...(account ? { account } : {}),
chain: chainId ? { id: chainId } : null,
})

Expand Down
18 changes: 17 additions & 1 deletion packages/react/src/hooks/useSignMessage.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { connect, disconnect, getAccount } from '@wagmi/core'
import { config } from '@wagmi/test'
import { config, privateKey } from '@wagmi/test'
import { renderHook, waitFor } from '@wagmi/test/react'
import { recoverMessageAddress } from 'viem'
import { expect, test } from 'vitest'

import { privateKeyToAccount } from 'viem/accounts'
import { useSignMessage } from './useSignMessage.js'

const connector = config.connectors[0]!
Expand All @@ -25,3 +26,18 @@ test('default', async () => {

await disconnect(config, { connector })
})

test('behavior: local account', async () => {
const { result } = renderHook(() => useSignMessage())

const account = privateKeyToAccount(privateKey)
result.current.signMessage({ account, message: 'foo bar baz' })
await waitFor(() => expect(result.current.isSuccess).toBeTruthy())

await expect(
recoverMessageAddress({
message: 'foo bar baz',
signature: result.current.data!,
}),
).resolves.toEqual(account.address)
})
25 changes: 24 additions & 1 deletion packages/react/src/hooks/useSignTypedData.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { connect, disconnect, getAccount } from '@wagmi/core'
import { config, typedData } from '@wagmi/test'
import { config, privateKey, typedData } from '@wagmi/test'
import { renderHook, waitFor } from '@wagmi/test/react'
import { recoverTypedDataAddress } from 'viem'
import { expect, test } from 'vitest'

import { privateKeyToAccount } from 'viem/accounts'
import { useSignTypedData } from './useSignTypedData.js'

const connector = config.connectors[0]!
Expand Down Expand Up @@ -31,3 +32,25 @@ test('default', async () => {

await disconnect(config, { connector })
})

test('behavior: local account', async () => {
const { result } = renderHook(() => useSignTypedData())

const account = privateKeyToAccount(privateKey)
result.current.signTypedData({
account,
types: typedData.basic.types,
primaryType: 'Mail',
message: typedData.basic.message,
})
await waitFor(() => expect(result.current.isSuccess).toBeTruthy())

await expect(
recoverTypedDataAddress({
types: typedData.basic.types,
primaryType: 'Mail',
message: typedData.basic.message,
signature: result.current.data!,
}),
).resolves.toEqual(account.address)
})
4 changes: 4 additions & 0 deletions packages/test/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const accounts = [
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
] as const

// for `'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'`
export const privateKey =
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'

export let walletConnectProjectId: string
if (process.env.VITE_WC_PROJECT_ID)
walletConnectProjectId = process.env.VITE_WC_PROJECT_ID
Expand Down
1 change: 1 addition & 0 deletions packages/test/src/exports/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ test('exports', () => {
"abi",
"address",
"accounts",
"privateKey",
"typedData",
"walletConnectProjectId",
"testClient",
Expand Down
1 change: 1 addition & 0 deletions packages/test/src/exports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export {
abi,
address,
accounts,
privateKey,
typedData,
walletConnectProjectId,
} from '../constants.js'
Expand Down

0 comments on commit 9c3b85d

Please sign in to comment.