viem 2.55.13 → 2.55.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/_cjs/actions/index.js +4 -2
- package/_cjs/actions/index.js.map +1 -1
- package/_cjs/actions/public/simulateCalls.js +213 -142
- package/_cjs/actions/public/simulateCalls.js.map +1 -1
- package/_cjs/actions/public/watchBlockHeaders.js +61 -0
- package/_cjs/actions/public/watchBlockHeaders.js.map +1 -0
- package/_cjs/clients/decorators/public.js +2 -0
- package/_cjs/clients/decorators/public.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/index.js.map +1 -1
- package/_cjs/tempo/actions/earn.js +2 -0
- package/_cjs/tempo/actions/earn.js.map +1 -1
- package/_cjs/tempo/actions/zone.js +18 -8
- package/_cjs/tempo/actions/zone.js.map +1 -1
- package/_cjs/utils/siwe/parseSiweMessage.js +16 -3
- package/_cjs/utils/siwe/parseSiweMessage.js.map +1 -1
- package/_cjs/utils/siwe/validateSiweMessage.js +13 -3
- package/_cjs/utils/siwe/validateSiweMessage.js.map +1 -1
- package/_esm/actions/index.js +1 -0
- package/_esm/actions/index.js.map +1 -1
- package/_esm/actions/public/simulateCalls.js +238 -150
- package/_esm/actions/public/simulateCalls.js.map +1 -1
- package/_esm/actions/public/watchBlockHeaders.js +81 -0
- package/_esm/actions/public/watchBlockHeaders.js.map +1 -0
- package/_esm/clients/decorators/public.js +2 -0
- package/_esm/clients/decorators/public.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/index.js.map +1 -1
- package/_esm/tempo/actions/earn.js +2 -0
- package/_esm/tempo/actions/earn.js.map +1 -1
- package/_esm/tempo/actions/zone.js +20 -8
- package/_esm/tempo/actions/zone.js.map +1 -1
- package/_esm/utils/siwe/parseSiweMessage.js +18 -3
- package/_esm/utils/siwe/parseSiweMessage.js.map +1 -1
- package/_esm/utils/siwe/validateSiweMessage.js +16 -3
- package/_esm/utils/siwe/validateSiweMessage.js.map +1 -1
- package/_types/actions/index.d.ts +1 -0
- package/_types/actions/index.d.ts.map +1 -1
- package/_types/actions/public/simulateCalls.d.ts +5 -3
- package/_types/actions/public/simulateCalls.d.ts.map +1 -1
- package/_types/actions/public/watchBlockHeaders.d.ts +45 -0
- package/_types/actions/public/watchBlockHeaders.d.ts.map +1 -0
- package/_types/clients/decorators/public.d.ts +24 -0
- package/_types/clients/decorators/public.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/index.d.ts +1 -0
- package/_types/index.d.ts.map +1 -1
- package/_types/tempo/actions/earn.d.ts.map +1 -1
- package/_types/tempo/actions/zone.d.ts +21 -5
- package/_types/tempo/actions/zone.d.ts.map +1 -1
- package/_types/utils/siwe/parseSiweMessage.d.ts.map +1 -1
- package/_types/utils/siwe/validateSiweMessage.d.ts.map +1 -1
- package/actions/index.ts +9 -0
- package/actions/public/simulateCalls.ts +324 -181
- package/actions/public/watchBlockHeaders.ts +131 -0
- package/clients/decorators/public.ts +33 -0
- package/errors/version.ts +1 -1
- package/index.ts +8 -0
- package/package.json +1 -1
- package/tempo/actions/earn.ts +2 -0
- package/tempo/actions/zone.ts +56 -5
- package/utils/siwe/parseSiweMessage.ts +20 -3
- package/utils/siwe/validateSiweMessage.ts +13 -2
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Client } from '../../clients/createClient.js'
|
|
2
|
+
import type { Transport } from '../../clients/transports/createTransport.js'
|
|
3
|
+
import type { ErrorType } from '../../errors/utils.js'
|
|
4
|
+
import type { Chain } from '../../types/chain.js'
|
|
5
|
+
import type { HasTransportType } from '../../types/transport.js'
|
|
6
|
+
import { formatBlock } from '../../utils/formatters/block.js'
|
|
7
|
+
import { observe } from '../../utils/observe.js'
|
|
8
|
+
import { type StringifyErrorType, stringify } from '../../utils/stringify.js'
|
|
9
|
+
|
|
10
|
+
import type { GetBlockReturnType } from './getBlock.js'
|
|
11
|
+
|
|
12
|
+
const blockFields = [
|
|
13
|
+
'size',
|
|
14
|
+
'totalDifficulty',
|
|
15
|
+
'transactions',
|
|
16
|
+
'uncles',
|
|
17
|
+
'withdrawals',
|
|
18
|
+
] as const
|
|
19
|
+
|
|
20
|
+
export type BlockHeader<chain extends Chain | undefined = Chain> = Omit<
|
|
21
|
+
GetBlockReturnType<chain, false, 'latest'>,
|
|
22
|
+
(typeof blockFields)[number]
|
|
23
|
+
>
|
|
24
|
+
|
|
25
|
+
export type OnBlockHeaderParameter<chain extends Chain | undefined = Chain> =
|
|
26
|
+
BlockHeader<chain>
|
|
27
|
+
|
|
28
|
+
export type OnBlockHeader<chain extends Chain | undefined = Chain> = (
|
|
29
|
+
blockHeader: OnBlockHeaderParameter<chain>,
|
|
30
|
+
prevBlockHeader: OnBlockHeaderParameter<chain> | undefined,
|
|
31
|
+
) => void
|
|
32
|
+
|
|
33
|
+
export type WatchBlockHeadersParameters<
|
|
34
|
+
chain extends Chain | undefined = Chain,
|
|
35
|
+
> = {
|
|
36
|
+
/** The callback to call when a new block header is received. */
|
|
37
|
+
onBlockHeader: OnBlockHeader<chain>
|
|
38
|
+
/** The callback to call when an error occurs while watching block headers. */
|
|
39
|
+
onError?: ((error: Error) => void) | undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type WatchBlockHeadersReturnType = () => void
|
|
43
|
+
|
|
44
|
+
export type WatchBlockHeadersErrorType = StringifyErrorType | ErrorType
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Watches and returns incoming block headers.
|
|
48
|
+
*
|
|
49
|
+
* - Docs: https://viem.sh/docs/actions/public/watchBlockHeaders
|
|
50
|
+
* - JSON-RPC Methods: Uses a WebSocket or IPC subscription via [`eth_subscribe`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_subscribe) and the `"newHeads"` event.
|
|
51
|
+
*
|
|
52
|
+
* @param client - Client to use
|
|
53
|
+
* @param parameters - {@link WatchBlockHeadersParameters}
|
|
54
|
+
* @returns A function that can be invoked to stop watching for new block headers. {@link WatchBlockHeadersReturnType}
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* import { createPublicClient, webSocket } from 'viem'
|
|
58
|
+
* import { watchBlockHeaders } from 'viem/actions'
|
|
59
|
+
* import { mainnet } from 'viem/chains'
|
|
60
|
+
*
|
|
61
|
+
* const client = createPublicClient({
|
|
62
|
+
* chain: mainnet,
|
|
63
|
+
* transport: webSocket(),
|
|
64
|
+
* })
|
|
65
|
+
* const unwatch = watchBlockHeaders(client, {
|
|
66
|
+
* onBlockHeader: (blockHeader) => console.log(blockHeader),
|
|
67
|
+
* })
|
|
68
|
+
*/
|
|
69
|
+
export function watchBlockHeaders<
|
|
70
|
+
transport extends Transport,
|
|
71
|
+
chain extends Chain | undefined,
|
|
72
|
+
>(
|
|
73
|
+
client: Client<transport, chain>,
|
|
74
|
+
{
|
|
75
|
+
onBlockHeader,
|
|
76
|
+
onError,
|
|
77
|
+
}: HasTransportType<transport, 'webSocket' | 'ipc'> extends true
|
|
78
|
+
? WatchBlockHeadersParameters<chain>
|
|
79
|
+
: never,
|
|
80
|
+
): WatchBlockHeadersReturnType {
|
|
81
|
+
let prevBlockHeader: OnBlockHeaderParameter<chain> | undefined
|
|
82
|
+
|
|
83
|
+
const observerId = stringify(['watchBlockHeaders', client.uid])
|
|
84
|
+
|
|
85
|
+
return observe(observerId, { onBlockHeader, onError }, (emit) => {
|
|
86
|
+
let active = true
|
|
87
|
+
let subscribed = false
|
|
88
|
+
let unsubscribe = () => (active = false)
|
|
89
|
+
;(async () => {
|
|
90
|
+
try {
|
|
91
|
+
const transport = (() => {
|
|
92
|
+
if (client.transport.type === 'fallback') {
|
|
93
|
+
const transport = client.transport.transports.find(
|
|
94
|
+
(transport: ReturnType<Transport>) =>
|
|
95
|
+
transport.config.type === 'webSocket' ||
|
|
96
|
+
transport.config.type === 'ipc',
|
|
97
|
+
)
|
|
98
|
+
if (!transport) return client.transport
|
|
99
|
+
return transport.value
|
|
100
|
+
}
|
|
101
|
+
return client.transport
|
|
102
|
+
})()
|
|
103
|
+
|
|
104
|
+
const { unsubscribe: unsubscribe_ } = await transport.subscribe({
|
|
105
|
+
params: ['newHeads'],
|
|
106
|
+
onData(data: any) {
|
|
107
|
+
if (!active) return
|
|
108
|
+
const blockHeader = (
|
|
109
|
+
client.chain?.formatters?.block?.format || formatBlock
|
|
110
|
+
)(data.result, 'watchBlockHeaders')
|
|
111
|
+
for (const field of blockFields) delete blockHeader[field]
|
|
112
|
+
emit.onBlockHeader(
|
|
113
|
+
blockHeader as OnBlockHeaderParameter<chain>,
|
|
114
|
+
prevBlockHeader,
|
|
115
|
+
)
|
|
116
|
+
prevBlockHeader = blockHeader as OnBlockHeaderParameter<chain>
|
|
117
|
+
},
|
|
118
|
+
onError(error: Error) {
|
|
119
|
+
if (subscribed) emit.onError?.(error)
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
subscribed = true
|
|
123
|
+
unsubscribe = unsubscribe_
|
|
124
|
+
if (!active) unsubscribe()
|
|
125
|
+
} catch (err) {
|
|
126
|
+
emit.onError?.(err as Error)
|
|
127
|
+
}
|
|
128
|
+
})()
|
|
129
|
+
return () => unsubscribe()
|
|
130
|
+
})
|
|
131
|
+
}
|
|
@@ -240,6 +240,11 @@ import {
|
|
|
240
240
|
type WaitForTransactionReceiptReturnType,
|
|
241
241
|
waitForTransactionReceipt,
|
|
242
242
|
} from '../../actions/public/waitForTransactionReceipt.js'
|
|
243
|
+
import {
|
|
244
|
+
type WatchBlockHeadersParameters,
|
|
245
|
+
type WatchBlockHeadersReturnType,
|
|
246
|
+
watchBlockHeaders,
|
|
247
|
+
} from '../../actions/public/watchBlockHeaders.js'
|
|
243
248
|
import {
|
|
244
249
|
type WatchBlockNumberParameters,
|
|
245
250
|
type WatchBlockNumberReturnType,
|
|
@@ -305,6 +310,7 @@ import type {
|
|
|
305
310
|
} from '../../types/contract.js'
|
|
306
311
|
import type { FeeValuesType } from '../../types/fee.js'
|
|
307
312
|
import type { FilterType } from '../../types/filter.js'
|
|
313
|
+
import type { HasTransportType } from '../../types/transport.js'
|
|
308
314
|
import { bindActionDecorators, type Client } from '../createClient.js'
|
|
309
315
|
import type { Transport } from '../transports/createTransport.js'
|
|
310
316
|
|
|
@@ -1988,6 +1994,32 @@ export type PublicActions<
|
|
|
1988
1994
|
watchBlockNumber: (
|
|
1989
1995
|
args: WatchBlockNumberParameters,
|
|
1990
1996
|
) => WatchBlockNumberReturnType
|
|
1997
|
+
/**
|
|
1998
|
+
* Watches and returns incoming block headers without fetching full blocks.
|
|
1999
|
+
*
|
|
2000
|
+
* - Docs: https://viem.sh/docs/actions/public/watchBlockHeaders
|
|
2001
|
+
* - JSON-RPC Methods: Uses a WebSocket or IPC subscription via [`eth_subscribe`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_subscribe) and the `"newHeads"` event.
|
|
2002
|
+
*
|
|
2003
|
+
* @param args - {@link WatchBlockHeadersParameters}
|
|
2004
|
+
* @returns A function that can be invoked to stop watching for new block headers. {@link WatchBlockHeadersReturnType}
|
|
2005
|
+
*
|
|
2006
|
+
* @example
|
|
2007
|
+
* import { createPublicClient, webSocket } from 'viem'
|
|
2008
|
+
* import { mainnet } from 'viem/chains'
|
|
2009
|
+
*
|
|
2010
|
+
* const client = createPublicClient({
|
|
2011
|
+
* chain: mainnet,
|
|
2012
|
+
* transport: webSocket(),
|
|
2013
|
+
* })
|
|
2014
|
+
* const unwatch = client.watchBlockHeaders({
|
|
2015
|
+
* onBlockHeader: (blockHeader) => console.log(blockHeader),
|
|
2016
|
+
* })
|
|
2017
|
+
*/
|
|
2018
|
+
watchBlockHeaders: (
|
|
2019
|
+
args: HasTransportType<transport, 'webSocket' | 'ipc'> extends true
|
|
2020
|
+
? WatchBlockHeadersParameters<chain>
|
|
2021
|
+
: never,
|
|
2022
|
+
) => WatchBlockHeadersReturnType
|
|
1991
2023
|
/**
|
|
1992
2024
|
* Watches and returns information for incoming blocks.
|
|
1993
2025
|
*
|
|
@@ -2337,6 +2369,7 @@ export function publicActions<
|
|
|
2337
2369
|
uninstallFilter: (args) => uninstallFilter(client, args),
|
|
2338
2370
|
waitForTransactionReceipt: (args) =>
|
|
2339
2371
|
waitForTransactionReceipt(client, args),
|
|
2372
|
+
watchBlockHeaders: (args) => watchBlockHeaders(client, args),
|
|
2340
2373
|
watchBlocks: (args) => watchBlocks(client, args),
|
|
2341
2374
|
watchBlockNumber: (args) => watchBlockNumber(client, args),
|
|
2342
2375
|
watchContractEvent: (args) => watchContractEvent(client, args),
|
package/errors/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.55.
|
|
1
|
+
export const version = '2.55.16'
|
package/index.ts
CHANGED
|
@@ -320,6 +320,14 @@ export type {
|
|
|
320
320
|
WaitForTransactionReceiptParameters,
|
|
321
321
|
WaitForTransactionReceiptReturnType,
|
|
322
322
|
} from './actions/public/waitForTransactionReceipt.js'
|
|
323
|
+
export type {
|
|
324
|
+
BlockHeader,
|
|
325
|
+
OnBlockHeader,
|
|
326
|
+
OnBlockHeaderParameter,
|
|
327
|
+
WatchBlockHeadersErrorType,
|
|
328
|
+
WatchBlockHeadersParameters,
|
|
329
|
+
WatchBlockHeadersReturnType,
|
|
330
|
+
} from './actions/public/watchBlockHeaders.js'
|
|
323
331
|
export type {
|
|
324
332
|
OnBlockNumberFn,
|
|
325
333
|
OnBlockNumberParameter,
|
package/package.json
CHANGED
package/tempo/actions/earn.ts
CHANGED
|
@@ -1051,6 +1051,7 @@ export namespace privateDeposit {
|
|
|
1051
1051
|
memo: returnMemo,
|
|
1052
1052
|
portalAddress: config.zonePortal,
|
|
1053
1053
|
recipient,
|
|
1054
|
+
sender: gateway,
|
|
1054
1055
|
zoneId: config.zoneId,
|
|
1055
1056
|
})
|
|
1056
1057
|
const shareAmountMin = resolveMinimumShareAmount(parameters)
|
|
@@ -2429,6 +2430,7 @@ export namespace privateRedeem {
|
|
|
2429
2430
|
memo: returnMemo,
|
|
2430
2431
|
portalAddress: config.zonePortal,
|
|
2431
2432
|
recipient,
|
|
2433
|
+
sender: gateway,
|
|
2432
2434
|
zoneId: config.zoneId,
|
|
2433
2435
|
}),
|
|
2434
2436
|
(async () => {
|
package/tempo/actions/zone.ts
CHANGED
|
@@ -28,7 +28,12 @@ import type { Transport } from '../../clients/transports/createTransport.js'
|
|
|
28
28
|
import { zeroHash } from '../../constants/bytes.js'
|
|
29
29
|
import type { BaseErrorType } from '../../errors/base.js'
|
|
30
30
|
import type { Chain, GetChainParameter } from '../../types/chain.js'
|
|
31
|
-
import type {
|
|
31
|
+
import type {
|
|
32
|
+
Compute,
|
|
33
|
+
IsUndefined,
|
|
34
|
+
MaybeRequired,
|
|
35
|
+
UnionOmit,
|
|
36
|
+
} from '../../types/utils.js'
|
|
32
37
|
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
|
|
33
38
|
import type { RequestErrorType } from '../../utils/buildRequest.js'
|
|
34
39
|
import { type ObserveErrorType, observe } from '../../utils/observe.js'
|
|
@@ -81,6 +86,8 @@ export type PreparedEncryptedDeposit = {
|
|
|
81
86
|
keyIndex: bigint
|
|
82
87
|
/** Zone portal address on the parent chain. */
|
|
83
88
|
portalAddress: Address
|
|
89
|
+
/** Address that will call the Zone portal. */
|
|
90
|
+
sender: Address
|
|
84
91
|
/** Token address or ID to deposit. */
|
|
85
92
|
token: TokenId.TokenIdOrAddress
|
|
86
93
|
/** Zone ID (e.g. `7`). */
|
|
@@ -96,6 +103,8 @@ export type PreparedEncryptedDepositRecipient = {
|
|
|
96
103
|
keyIndex: bigint
|
|
97
104
|
/** Zone portal address on the parent chain. */
|
|
98
105
|
portalAddress: Address
|
|
106
|
+
/** Address that will call the Zone portal. */
|
|
107
|
+
sender: Address
|
|
99
108
|
/** Zone ID (e.g. `7`). */
|
|
100
109
|
zoneId: number
|
|
101
110
|
}
|
|
@@ -494,6 +503,7 @@ export async function encryptedDeposit<
|
|
|
494
503
|
memo: parameters.memo,
|
|
495
504
|
portalAddress: parameters.portalAddress,
|
|
496
505
|
recipient,
|
|
506
|
+
sender: account_.address,
|
|
497
507
|
token: parameters.token,
|
|
498
508
|
zoneId: parameters.zoneId,
|
|
499
509
|
})
|
|
@@ -573,6 +583,7 @@ export namespace encryptedDeposit {
|
|
|
573
583
|
* amount: 1_000_000n,
|
|
574
584
|
* bouncebackRecipient: '0x...',
|
|
575
585
|
* recipient: '0x...',
|
|
586
|
+
* sender: '0x...',
|
|
576
587
|
* zoneId: 7,
|
|
577
588
|
* })
|
|
578
589
|
* ```
|
|
@@ -586,7 +597,7 @@ export namespace encryptedDeposit {
|
|
|
586
597
|
account extends Account | undefined,
|
|
587
598
|
>(
|
|
588
599
|
client: Client<Transport, chain, account>,
|
|
589
|
-
parameters: prepare.Parameters
|
|
600
|
+
parameters: prepare.Parameters<account>,
|
|
590
601
|
): Promise<prepare.ReturnValue> {
|
|
591
602
|
const chainId = client.chain?.id
|
|
592
603
|
if (!chainId) throw new Error('`chain` is required.')
|
|
@@ -597,10 +608,13 @@ export namespace encryptedDeposit {
|
|
|
597
608
|
memo,
|
|
598
609
|
portalAddress: portalAddress_,
|
|
599
610
|
recipient,
|
|
611
|
+
sender: sender_ = client.account?.address,
|
|
600
612
|
token,
|
|
601
613
|
zoneId,
|
|
602
614
|
...rest
|
|
603
615
|
} = parameters
|
|
616
|
+
if (!sender_) throw new Error('`sender` is required.')
|
|
617
|
+
const sender = sender_
|
|
604
618
|
const portalAddress = portalAddress_ ?? getPortalAddress(chainId, zoneId)
|
|
605
619
|
|
|
606
620
|
const { keyIndex, publicKey } = await getEncryptionKey(client, {
|
|
@@ -612,6 +626,7 @@ export namespace encryptedDeposit {
|
|
|
612
626
|
const encrypted = await encryptDepositPayload(
|
|
613
627
|
publicKey,
|
|
614
628
|
recipient,
|
|
629
|
+
sender,
|
|
615
630
|
portalAddress,
|
|
616
631
|
keyIndex,
|
|
617
632
|
memo,
|
|
@@ -624,13 +639,24 @@ export namespace encryptedDeposit {
|
|
|
624
639
|
encrypted,
|
|
625
640
|
keyIndex,
|
|
626
641
|
portalAddress,
|
|
642
|
+
sender,
|
|
627
643
|
token,
|
|
628
644
|
zoneId,
|
|
629
645
|
}
|
|
630
646
|
}
|
|
631
647
|
|
|
632
648
|
export namespace prepare {
|
|
633
|
-
export type Parameters
|
|
649
|
+
export type Parameters<
|
|
650
|
+
account extends Account | undefined = Account | undefined,
|
|
651
|
+
> = ReadParameters &
|
|
652
|
+
Omit<Args, 'sender'> &
|
|
653
|
+
MaybeRequired<
|
|
654
|
+
{
|
|
655
|
+
/** Address that will call the Zone portal. @default `client.account.address` */
|
|
656
|
+
sender?: Address | undefined
|
|
657
|
+
},
|
|
658
|
+
IsUndefined<account>
|
|
659
|
+
>
|
|
634
660
|
|
|
635
661
|
export type Args = {
|
|
636
662
|
/** Amount of tokens to deposit. */
|
|
@@ -643,6 +669,8 @@ export namespace encryptedDeposit {
|
|
|
643
669
|
portalAddress?: Address | undefined
|
|
644
670
|
/** Recipient address in the zone. */
|
|
645
671
|
recipient: Address
|
|
672
|
+
/** Address that will call the Zone portal. */
|
|
673
|
+
sender: Address
|
|
646
674
|
/** Token address or ID to deposit. */
|
|
647
675
|
token: TokenId.TokenIdOrAddress
|
|
648
676
|
/** Zone ID (e.g. `7`). */
|
|
@@ -674,6 +702,7 @@ export namespace encryptedDeposit {
|
|
|
674
702
|
*
|
|
675
703
|
* const recipient = await Actions.zone.encryptedDeposit.prepareRecipient(client, {
|
|
676
704
|
* recipient: '0x...',
|
|
705
|
+
* sender: '0x...',
|
|
677
706
|
* zoneId: 7,
|
|
678
707
|
* })
|
|
679
708
|
* ```
|
|
@@ -687,7 +716,7 @@ export namespace encryptedDeposit {
|
|
|
687
716
|
account extends Account | undefined,
|
|
688
717
|
>(
|
|
689
718
|
client: Client<Transport, chain, account>,
|
|
690
|
-
parameters: prepareRecipient.Parameters
|
|
719
|
+
parameters: prepareRecipient.Parameters<account>,
|
|
691
720
|
): Promise<prepareRecipient.ReturnValue> {
|
|
692
721
|
const chainId = client.chain?.id
|
|
693
722
|
if (!chainId) throw new Error('`chain` is required.')
|
|
@@ -696,9 +725,12 @@ export namespace encryptedDeposit {
|
|
|
696
725
|
memo,
|
|
697
726
|
portalAddress: portalAddress_,
|
|
698
727
|
recipient,
|
|
728
|
+
sender: sender_ = client.account?.address,
|
|
699
729
|
zoneId,
|
|
700
730
|
...rest
|
|
701
731
|
} = parameters
|
|
732
|
+
if (!sender_) throw new Error('`sender` is required.')
|
|
733
|
+
const sender = sender_
|
|
702
734
|
const portalAddress = portalAddress_ ?? getPortalAddress(chainId, zoneId)
|
|
703
735
|
const { keyIndex, publicKey } = await getEncryptionKey(client, {
|
|
704
736
|
...rest,
|
|
@@ -708,6 +740,7 @@ export namespace encryptedDeposit {
|
|
|
708
740
|
const encrypted = await encryptDepositPayload(
|
|
709
741
|
publicKey,
|
|
710
742
|
recipient,
|
|
743
|
+
sender,
|
|
711
744
|
portalAddress,
|
|
712
745
|
keyIndex,
|
|
713
746
|
memo,
|
|
@@ -718,12 +751,23 @@ export namespace encryptedDeposit {
|
|
|
718
751
|
encrypted,
|
|
719
752
|
keyIndex,
|
|
720
753
|
portalAddress,
|
|
754
|
+
sender,
|
|
721
755
|
zoneId,
|
|
722
756
|
}
|
|
723
757
|
}
|
|
724
758
|
|
|
725
759
|
export namespace prepareRecipient {
|
|
726
|
-
export type Parameters
|
|
760
|
+
export type Parameters<
|
|
761
|
+
account extends Account | undefined = Account | undefined,
|
|
762
|
+
> = ReadParameters &
|
|
763
|
+
Omit<Args, 'sender'> &
|
|
764
|
+
MaybeRequired<
|
|
765
|
+
{
|
|
766
|
+
/** Address that will call the Zone portal. @default `client.account.address` */
|
|
767
|
+
sender?: Address | undefined
|
|
768
|
+
},
|
|
769
|
+
IsUndefined<account>
|
|
770
|
+
>
|
|
727
771
|
|
|
728
772
|
export type Args = {
|
|
729
773
|
/** Optional deposit memo. @default `0x00...00` */
|
|
@@ -732,6 +776,8 @@ export namespace encryptedDeposit {
|
|
|
732
776
|
portalAddress?: Address | undefined
|
|
733
777
|
/** Recipient address in the zone. */
|
|
734
778
|
recipient: Address
|
|
779
|
+
/** Address that will call the Zone portal. */
|
|
780
|
+
sender: Address
|
|
735
781
|
/** Zone ID (e.g. `7`). */
|
|
736
782
|
zoneId: number
|
|
737
783
|
}
|
|
@@ -864,6 +910,7 @@ export async function encryptedDepositSync<
|
|
|
864
910
|
memo: parameters.memo,
|
|
865
911
|
portalAddress: parameters.portalAddress,
|
|
866
912
|
recipient,
|
|
913
|
+
sender: account_.address,
|
|
867
914
|
token: parameters.token,
|
|
868
915
|
zoneId: parameters.zoneId,
|
|
869
916
|
})
|
|
@@ -1883,6 +1930,7 @@ export namespace signAuthorizationToken {
|
|
|
1883
1930
|
async function encryptDepositPayload(
|
|
1884
1931
|
publicKey: { prefix: 2 | 3; x: Hex.Hex },
|
|
1885
1932
|
recipient: Address,
|
|
1933
|
+
sender: Address,
|
|
1886
1934
|
portalAddress: Address,
|
|
1887
1935
|
keyIndex: bigint,
|
|
1888
1936
|
memo: Hex.Hex = zeroHash,
|
|
@@ -1918,6 +1966,7 @@ async function encryptDepositPayload(
|
|
|
1918
1966
|
portalAddress,
|
|
1919
1967
|
keyIndex,
|
|
1920
1968
|
Hex.fromNumber(compressedEphemeral.x, { size: 32 }),
|
|
1969
|
+
sender,
|
|
1921
1970
|
) as BufferSource,
|
|
1922
1971
|
},
|
|
1923
1972
|
hkdfKey,
|
|
@@ -1961,11 +2010,13 @@ function buildDepositHkdfInfo(
|
|
|
1961
2010
|
portalAddress: Address,
|
|
1962
2011
|
keyIndex: bigint,
|
|
1963
2012
|
ephemeralPubkeyX: Hex.Hex,
|
|
2013
|
+
sender: Address,
|
|
1964
2014
|
): Bytes.Bytes {
|
|
1965
2015
|
return Bytes.concat(
|
|
1966
2016
|
Bytes.from(portalAddress),
|
|
1967
2017
|
Bytes.fromNumber(keyIndex, { size: 32 }),
|
|
1968
2018
|
Bytes.from(ephemeralPubkeyX),
|
|
2019
|
+
Bytes.from(sender),
|
|
1969
2020
|
)
|
|
1970
2021
|
}
|
|
1971
2022
|
|
|
@@ -3,6 +3,21 @@ import type { Address } from 'abitype'
|
|
|
3
3
|
import type { ExactPartial, Prettify } from '../../types/utils.js'
|
|
4
4
|
import type { SiweMessage } from './types.js'
|
|
5
5
|
|
|
6
|
+
const siweDateTimeRegex =
|
|
7
|
+
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/
|
|
8
|
+
|
|
9
|
+
function isValidSiweDateTime(value: string): boolean {
|
|
10
|
+
if (!siweDateTimeRegex.test(value)) return false
|
|
11
|
+
return !Number.isNaN(new Date(value).getTime())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function parseSiweDateTime(value: string): Date {
|
|
15
|
+
// Reject non-RFC-3339 / non-EIP-4361 date-time strings before Date coercion
|
|
16
|
+
// (JS Date accepts many non-SIWE forms that would otherwise look "valid").
|
|
17
|
+
if (!isValidSiweDateTime(value)) return new Date(Number.NaN)
|
|
18
|
+
return new Date(value)
|
|
19
|
+
}
|
|
20
|
+
|
|
6
21
|
/**
|
|
7
22
|
* @description Parses EIP-4361 formatted message into message fields object.
|
|
8
23
|
*
|
|
@@ -36,9 +51,11 @@ export function parseSiweMessage(
|
|
|
36
51
|
...prefix,
|
|
37
52
|
...suffix,
|
|
38
53
|
...(chainId ? { chainId: Number(chainId) } : {}),
|
|
39
|
-
...(expirationTime
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
...(expirationTime
|
|
55
|
+
? { expirationTime: parseSiweDateTime(expirationTime) }
|
|
56
|
+
: {}),
|
|
57
|
+
...(issuedAt ? { issuedAt: parseSiweDateTime(issuedAt) } : {}),
|
|
58
|
+
...(notBefore ? { notBefore: parseSiweDateTime(notBefore) } : {}),
|
|
42
59
|
...(requestId ? { requestId } : {}),
|
|
43
60
|
...(resources ? { resources } : {}),
|
|
44
61
|
...(scheme ? { scheme } : {}),
|
|
@@ -57,8 +57,19 @@ export function validateSiweMessage(
|
|
|
57
57
|
if (nonce && message.nonce !== nonce) return false
|
|
58
58
|
if (scheme && message.scheme !== scheme) return false
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
if (
|
|
60
|
+
// Invalid `time` makes both lifetime comparisons false in JS; reject first.
|
|
61
|
+
if (Number.isNaN(time.getTime())) return false
|
|
62
|
+
|
|
63
|
+
// Invalid Date (e.g. non-RFC-3339 SIWE timestamp coerced at parse) is truthy;
|
|
64
|
+
// comparisons against it are always false and previously skipped checks.
|
|
65
|
+
if (message.expirationTime) {
|
|
66
|
+
if (Number.isNaN(message.expirationTime.getTime())) return false
|
|
67
|
+
if (time >= message.expirationTime) return false
|
|
68
|
+
}
|
|
69
|
+
if (message.notBefore) {
|
|
70
|
+
if (Number.isNaN(message.notBefore.getTime())) return false
|
|
71
|
+
if (time < message.notBefore) return false
|
|
72
|
+
}
|
|
62
73
|
|
|
63
74
|
try {
|
|
64
75
|
if (!message.address) return false
|