accounts 0.6.0 → 0.6.2

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.
Files changed (69) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/core/Adapter.d.ts +2 -2
  3. package/dist/core/Adapter.d.ts.map +1 -1
  4. package/dist/core/Client.d.ts +2 -2
  5. package/dist/core/Client.d.ts.map +1 -1
  6. package/dist/core/Client.js +13 -4
  7. package/dist/core/Client.js.map +1 -1
  8. package/dist/core/Provider.d.ts.map +1 -1
  9. package/dist/core/Provider.js +9 -2
  10. package/dist/core/Provider.js.map +1 -1
  11. package/dist/core/Schema.d.ts +22 -12
  12. package/dist/core/Schema.d.ts.map +1 -1
  13. package/dist/core/adapters/dialog.d.ts.map +1 -1
  14. package/dist/core/adapters/dialog.js +24 -4
  15. package/dist/core/adapters/dialog.js.map +1 -1
  16. package/dist/core/adapters/local.d.ts.map +1 -1
  17. package/dist/core/adapters/local.js +21 -3
  18. package/dist/core/adapters/local.js.map +1 -1
  19. package/dist/core/zod/rpc.d.ts +14 -9
  20. package/dist/core/zod/rpc.d.ts.map +1 -1
  21. package/dist/core/zod/rpc.js +8 -2
  22. package/dist/core/zod/rpc.js.map +1 -1
  23. package/dist/server/CliAuth.d.ts +11 -11
  24. package/dist/server/CliAuth.js +1 -1
  25. package/dist/server/CliAuth.js.map +1 -1
  26. package/dist/server/Handler.d.ts +4 -252
  27. package/dist/server/Handler.d.ts.map +1 -1
  28. package/dist/server/Handler.js +4 -573
  29. package/dist/server/Handler.js.map +1 -1
  30. package/dist/server/internal/handlers/codeAuth.d.ts +41 -0
  31. package/dist/server/internal/handlers/codeAuth.d.ts.map +1 -0
  32. package/dist/server/internal/handlers/codeAuth.js +104 -0
  33. package/dist/server/internal/handlers/codeAuth.js.map +1 -0
  34. package/dist/server/internal/handlers/feePayer.d.ts +73 -0
  35. package/dist/server/internal/handlers/feePayer.d.ts.map +1 -0
  36. package/dist/server/internal/handlers/feePayer.js +184 -0
  37. package/dist/server/internal/handlers/feePayer.js.map +1 -0
  38. package/dist/server/internal/handlers/relay.d.ts +148 -0
  39. package/dist/server/internal/handlers/relay.d.ts.map +1 -0
  40. package/dist/server/internal/handlers/relay.js +600 -0
  41. package/dist/server/internal/handlers/relay.js.map +1 -0
  42. package/dist/server/internal/handlers/utils.d.ts +12 -0
  43. package/dist/server/internal/handlers/utils.d.ts.map +1 -0
  44. package/dist/server/internal/handlers/utils.js +80 -0
  45. package/dist/server/internal/handlers/utils.js.map +1 -0
  46. package/dist/server/internal/handlers/webAuthn.d.ts +57 -0
  47. package/dist/server/internal/handlers/webAuthn.d.ts.map +1 -0
  48. package/dist/server/internal/handlers/webAuthn.js +143 -0
  49. package/dist/server/internal/handlers/webAuthn.js.map +1 -0
  50. package/package.json +2 -2
  51. package/src/core/Adapter.ts +2 -2
  52. package/src/core/Client.ts +13 -6
  53. package/src/core/Provider.connect.browser.test.ts +23 -2
  54. package/src/core/Provider.test.ts +292 -0
  55. package/src/core/Provider.ts +11 -3
  56. package/src/core/adapters/dialog.ts +21 -4
  57. package/src/core/adapters/local.ts +15 -3
  58. package/src/core/zod/rpc.ts +12 -2
  59. package/src/server/CliAuth.ts +1 -1
  60. package/src/server/Handler.test.ts +3 -418
  61. package/src/server/Handler.ts +5 -766
  62. package/src/server/internal/handlers/codeAuth.ts +148 -0
  63. package/src/server/internal/handlers/feePayer.test.ts +335 -0
  64. package/src/server/internal/handlers/feePayer.ts +271 -0
  65. package/src/server/internal/handlers/relay.test.ts +767 -0
  66. package/src/server/internal/handlers/relay.ts +817 -0
  67. package/src/server/internal/handlers/utils.ts +96 -0
  68. package/src/server/internal/handlers/webAuthn.test.ts +170 -0
  69. package/src/server/internal/handlers/webAuthn.ts +213 -0
@@ -727,6 +727,27 @@ describe.each(adapters)('$name', ({ adapter }: (typeof adapters)[number]) => {
727
727
  expect(Object.keys(result).length).toMatchInlineSnapshot(`2`)
728
728
  expect(result[Hex.fromNumber(tempo.id)]!.atomic.status).toMatchInlineSnapshot(`"supported"`)
729
729
  })
730
+
731
+ test('behavior: includes feePayer when configured', async () => {
732
+ const provider = Provider.create({
733
+ adapter: adapter(),
734
+ feePayer: 'https://fee-payer.example.com',
735
+ })
736
+
737
+ const result = await provider.request({ method: 'wallet_getCapabilities' })
738
+ expect(result[Hex.fromNumber(tempo.id)]!.feePayer).toMatchInlineSnapshot(`
739
+ {
740
+ "status": "supported",
741
+ }
742
+ `)
743
+ })
744
+
745
+ test('behavior: excludes feePayer when not configured', async () => {
746
+ const provider = Provider.create({ adapter: adapter() })
747
+
748
+ const result = await provider.request({ method: 'wallet_getCapabilities' })
749
+ expect(result[Hex.fromNumber(tempo.id)]!.feePayer).toBeUndefined()
750
+ })
730
751
  })
731
752
 
732
753
  describe('wallet_getBalances', () => {
@@ -1718,5 +1739,276 @@ describe.each(adapters)('$name', ({ adapter }: (typeof adapters)[number]) => {
1718
1739
  const receipt = await waitForTransactionReceipt(client, { hash })
1719
1740
  expect(receipt.feePayer).not.toBe(feePayerAccount.address.toLowerCase())
1720
1741
  })
1742
+
1743
+ test('behavior: precedence fee-payer-first (default) on eth_sendTransaction', async () => {
1744
+ const provider = Provider.create({
1745
+ adapter: adapter(),
1746
+ chains: [chain],
1747
+ feePayer: server.url,
1748
+ })
1749
+
1750
+ const connected = await connect(provider)
1751
+ await fund(connected)
1752
+
1753
+ const hash = await provider.request({
1754
+ method: 'eth_sendTransaction',
1755
+ params: [{ calls: [transferCall], feePayer: true }],
1756
+ })
1757
+
1758
+ const client = provider.getClient()
1759
+ const receipt = await waitForTransactionReceipt(client, { hash })
1760
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1761
+ })
1762
+
1763
+ test('behavior: precedence fee-payer-first (default) on eth_sendTransactionSync', async () => {
1764
+ const provider = Provider.create({
1765
+ adapter: adapter(),
1766
+ chains: [chain],
1767
+ feePayer: server.url,
1768
+ })
1769
+
1770
+ const connected = await connect(provider)
1771
+ await fund(connected)
1772
+ const syncTransferCall = Actions.token.transfer.call({
1773
+ to: '0x0000000000000000000000000000000000000001',
1774
+ token: Addresses.pathUsd,
1775
+ amount: parseUnits('5', 6),
1776
+ })
1777
+
1778
+ const receipt = await provider.request({
1779
+ method: 'eth_sendTransactionSync',
1780
+ params: [{ calls: [syncTransferCall], feePayer: true }],
1781
+ })
1782
+
1783
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1784
+ })
1785
+
1786
+ test('behavior: precedence user-first on eth_sendTransaction', async () => {
1787
+ const provider = Provider.create({
1788
+ adapter: adapter(),
1789
+ chains: [chain],
1790
+ feePayer: { url: server.url, precedence: 'user-first' },
1791
+ })
1792
+
1793
+ const connected = await connect(provider)
1794
+ await fund(connected)
1795
+
1796
+ const hash = await provider.request({
1797
+ method: 'eth_sendTransaction',
1798
+ params: [{ calls: [transferCall], feePayer: true }],
1799
+ })
1800
+
1801
+ const client = provider.getClient()
1802
+ const receipt = await waitForTransactionReceipt(client, { hash })
1803
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1804
+ })
1805
+
1806
+ test('behavior: precedence user-first on eth_sendTransactionSync', async () => {
1807
+ const provider = Provider.create({
1808
+ adapter: adapter(),
1809
+ chains: [chain],
1810
+ feePayer: { url: server.url, precedence: 'user-first' },
1811
+ })
1812
+
1813
+ const connected = await connect(provider)
1814
+ await fund(connected)
1815
+ const syncTransferCall = Actions.token.transfer.call({
1816
+ to: '0x0000000000000000000000000000000000000001',
1817
+ token: Addresses.pathUsd,
1818
+ amount: parseUnits('6', 6),
1819
+ })
1820
+
1821
+ const receipt = await provider.request({
1822
+ method: 'eth_sendTransactionSync',
1823
+ params: [{ calls: [syncTransferCall], feePayer: true }],
1824
+ })
1825
+
1826
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1827
+ })
1828
+
1829
+ test('behavior: precedence user-first on eth_signTransaction', async () => {
1830
+ const provider = Provider.create({
1831
+ adapter: adapter(),
1832
+ chains: [chain],
1833
+ feePayer: { url: server.url, precedence: 'user-first' },
1834
+ })
1835
+
1836
+ const connected = await connect(provider)
1837
+ await fund(connected)
1838
+
1839
+ const signed = await provider.request({
1840
+ method: 'eth_signTransaction',
1841
+ params: [{ calls: [transferCall], feePayer: true }],
1842
+ })
1843
+
1844
+ expect(signed).toMatch(/^0x78/)
1845
+ })
1846
+
1847
+ test('behavior: feePayer: false opts out on eth_sendTransaction', async () => {
1848
+ const provider = Provider.create({
1849
+ adapter: adapter(),
1850
+ chains: [chain],
1851
+ feePayer: server.url,
1852
+ })
1853
+
1854
+ const connected = await connect(provider)
1855
+ await fund(connected)
1856
+
1857
+ const hash = await provider.request({
1858
+ method: 'eth_sendTransaction',
1859
+ params: [{ calls: [transferCall], feePayer: false }],
1860
+ })
1861
+
1862
+ expect(hash).toMatch(/^0x[0-9a-f]{64}$/)
1863
+
1864
+ const client = provider.getClient()
1865
+ const receipt = await waitForTransactionReceipt(client, { hash })
1866
+ expect(receipt.feePayer).not.toBe(feePayerAccount.address.toLowerCase())
1867
+ })
1868
+
1869
+ test('behavior: feePayer: false opts out on eth_sendTransactionSync', async () => {
1870
+ const provider = Provider.create({
1871
+ adapter: adapter(),
1872
+ chains: [chain],
1873
+ feePayer: server.url,
1874
+ })
1875
+
1876
+ const connected = await connect(provider)
1877
+ await fund(connected)
1878
+ const syncTransferCall = Actions.token.transfer.call({
1879
+ to: '0x0000000000000000000000000000000000000001',
1880
+ token: Addresses.pathUsd,
1881
+ amount: parseUnits('4', 6),
1882
+ })
1883
+
1884
+ const receipt = await provider.request({
1885
+ method: 'eth_sendTransactionSync',
1886
+ params: [{ calls: [syncTransferCall], feePayer: false }],
1887
+ })
1888
+
1889
+ expect(receipt.feePayer).not.toBe(feePayerAccount.address.toLowerCase())
1890
+ })
1891
+
1892
+ test('behavior: feePayer: false opts out on eth_signTransaction', async () => {
1893
+ const provider = Provider.create({
1894
+ adapter: adapter(),
1895
+ chains: [chain],
1896
+ feePayer: server.url,
1897
+ })
1898
+
1899
+ const connected = await connect(provider)
1900
+ await fund(connected)
1901
+
1902
+ const signed = await provider.request({
1903
+ method: 'eth_signTransaction',
1904
+ params: [{ calls: [transferCall], feePayer: false }],
1905
+ })
1906
+
1907
+ expect(signed).toMatch(/^0x76/)
1908
+ })
1909
+
1910
+ test('behavior: wallet_sendCalls with feePayer capability', async () => {
1911
+ const provider = Provider.create({ adapter: adapter(), chains: [chain] })
1912
+
1913
+ const connected = await connect(provider)
1914
+ await fund(connected)
1915
+
1916
+ const result = await provider.request({
1917
+ method: 'wallet_sendCalls',
1918
+ params: [
1919
+ {
1920
+ calls: [transferCall],
1921
+ capabilities: { feePayer: server.url },
1922
+ },
1923
+ ],
1924
+ })
1925
+
1926
+ expect(result.id).toMatch(/^0x[0-9a-f]+$/)
1927
+
1928
+ const hash = result.id.slice(0, 66) as `0x${string}`
1929
+ const client = provider.getClient()
1930
+ const receipt = await waitForTransactionReceipt(client, { hash })
1931
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1932
+ })
1933
+
1934
+ test('behavior: wallet_sendCalls with feePayer: true uses provider default', async () => {
1935
+ const provider = Provider.create({
1936
+ adapter: adapter(),
1937
+ chains: [chain],
1938
+ feePayer: server.url,
1939
+ })
1940
+
1941
+ const connected = await connect(provider)
1942
+ await fund(connected)
1943
+
1944
+ const result = await provider.request({
1945
+ method: 'wallet_sendCalls',
1946
+ params: [
1947
+ {
1948
+ calls: [transferCall],
1949
+ capabilities: { feePayer: true },
1950
+ },
1951
+ ],
1952
+ })
1953
+
1954
+ expect(result.id).toMatch(/^0x[0-9a-f]+$/)
1955
+
1956
+ const hash = result.id.slice(0, 66) as `0x${string}`
1957
+ const client = provider.getClient()
1958
+ const receipt = await waitForTransactionReceipt(client, { hash })
1959
+ expect(receipt.feePayer).toBe(feePayerAccount.address.toLowerCase())
1960
+ })
1961
+
1962
+ test('behavior: wallet_sendCalls with feePayer: false opts out', async () => {
1963
+ const provider = Provider.create({
1964
+ adapter: adapter(),
1965
+ chains: [chain],
1966
+ feePayer: server.url,
1967
+ })
1968
+
1969
+ const connected = await connect(provider)
1970
+ await fund(connected)
1971
+
1972
+ const result = await provider.request({
1973
+ method: 'wallet_sendCalls',
1974
+ params: [
1975
+ {
1976
+ calls: [transferCall],
1977
+ capabilities: { feePayer: false },
1978
+ },
1979
+ ],
1980
+ })
1981
+
1982
+ expect(result.id).toMatch(/^0x[0-9a-f]+$/)
1983
+
1984
+ const hash = result.id.slice(0, 66) as `0x${string}`
1985
+ const client = provider.getClient()
1986
+ const receipt = await waitForTransactionReceipt(client, { hash })
1987
+ expect(receipt.feePayer).not.toBe(feePayerAccount.address.toLowerCase())
1988
+ })
1989
+
1990
+ test('behavior: wallet_sendCalls with sync and feePayer capability', async () => {
1991
+ const provider = Provider.create({ adapter: adapter(), chains: [chain] })
1992
+
1993
+ const connected = await connect(provider)
1994
+ await fund(connected)
1995
+ const syncTransferCall = Actions.token.transfer.call({
1996
+ to: '0x0000000000000000000000000000000000000001',
1997
+ token: Addresses.pathUsd,
1998
+ amount: parseUnits('7', 6),
1999
+ })
2000
+
2001
+ const result = await provider.request({
2002
+ method: 'wallet_sendCalls',
2003
+ params: [
2004
+ {
2005
+ calls: [syncTransferCall],
2006
+ capabilities: { feePayer: server.url, sync: true },
2007
+ },
2008
+ ],
2009
+ })
2010
+
2011
+ expect(result.receipts?.[0]?.feePayer).toBe(feePayerAccount.address.toLowerCase())
2012
+ })
1721
2013
  })
1722
2014
  })
@@ -82,12 +82,16 @@ export function create(options: create.Options = {}): create.ReturnType {
82
82
  let providerRef: ox_Provider.Provider | undefined
83
83
 
84
84
  function getClient(
85
- options: { chainId?: number | undefined; feePayer?: string | undefined } = {},
85
+ options: { chainId?: number | undefined; feePayer?: string | false | undefined } = {},
86
86
  ) {
87
87
  const { chainId, feePayer } = options
88
88
  return Client.fromChainId(chainId, {
89
89
  chains,
90
- feePayer: feePayer ? { url: feePayer, precedence: feePayerConfig?.precedence } : undefined,
90
+ feePayer: (() => {
91
+ if (feePayer === false) return false
92
+ if (feePayer) return { url: feePayer, precedence: feePayerConfig?.precedence }
93
+ return undefined
94
+ })(),
91
95
  store,
92
96
  })
93
97
  }
@@ -353,7 +357,9 @@ export function create(options: create.Options = {}): create.ReturnType {
353
357
  const decoded = request._decoded.params?.[0]
354
358
  const { calls = [], capabilities, chainId, from } = decoded ?? {}
355
359
  const sync = capabilities?.sync
356
- const feePayer = resolveFeePayer(feePayerConfig ? true : undefined)
360
+ const feePayer = resolveFeePayer(
361
+ capabilities?.feePayer ?? (feePayerConfig ? true : undefined),
362
+ )
357
363
  const txRequest = {
358
364
  calls,
359
365
  chainId,
@@ -473,12 +479,14 @@ export function create(options: create.Options = {}): create.ReturnType {
473
479
  {
474
480
  accessKeys: { status: 'supported' }
475
481
  atomic: { status: 'supported' }
482
+ feePayer?: { status: 'supported' } | undefined
476
483
  }
477
484
  > = {}
478
485
  for (const chain of filtered)
479
486
  result[Hex.fromNumber(chain.id)] = {
480
487
  accessKeys: { status: 'supported' },
481
488
  atomic: { status: 'supported' },
489
+ ...(feePayerConfig ? { feePayer: { status: 'supported' } } : {}),
482
490
  }
483
491
  return result as Rpc.wallet_getCapabilities.Encoded['returns']
484
492
  }
@@ -277,7 +277,11 @@ export function dialog(options: dialog.Options = {}): Adapter.Adapter {
277
277
  const result = await withAccessKey(async (account, keyAuthorization) => {
278
278
  const { feePayer, ...rest } = parameters
279
279
  const client = getClient({
280
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
280
+ feePayer: (() => {
281
+ if (feePayer === false) return false
282
+ if (typeof feePayer === 'string') return feePayer
283
+ return undefined
284
+ })(),
281
285
  })
282
286
  const prepared = await prepareTransactionRequest(client, {
283
287
  account,
@@ -303,7 +307,11 @@ export function dialog(options: dialog.Options = {}): Adapter.Adapter {
303
307
  const result = await withAccessKey(async (account, keyAuthorization) => {
304
308
  const { feePayer, ...rest } = parameters
305
309
  const client = getClient({
306
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
310
+ feePayer: (() => {
311
+ if (feePayer === false) return false
312
+ if (typeof feePayer === 'string') return feePayer
313
+ return undefined
314
+ })(),
307
315
  })
308
316
  const prepared = await prepareTransactionRequest(client, {
309
317
  account,
@@ -329,7 +337,11 @@ export function dialog(options: dialog.Options = {}): Adapter.Adapter {
329
337
  const result = await withAccessKey(async (account, keyAuthorization) => {
330
338
  const { feePayer, ...rest } = parameters
331
339
  const client = getClient({
332
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
340
+ feePayer: (() => {
341
+ if (feePayer === false) return false
342
+ if (typeof feePayer === 'string') return feePayer
343
+ return undefined
344
+ })(),
333
345
  })
334
346
  const prepared = await prepareTransactionRequest(client, {
335
347
  account,
@@ -356,7 +368,12 @@ export function dialog(options: dialog.Options = {}): Adapter.Adapter {
356
368
 
357
369
  const result = await provider.request({
358
370
  ...request,
359
- params: [z.encode(Rpc.wallet_connect.authorizeAccessKey, accessKey!.request)!],
371
+ params: [
372
+ z.encode(
373
+ Rpc.wallet_connect.authorizeAccessKey,
374
+ accessKey ? accessKey.request : parameters,
375
+ )!,
376
+ ],
360
377
  })
361
378
 
362
379
  if (accessKey) {
@@ -194,7 +194,11 @@ export function local(options: local.Options): Adapter.Adapter {
194
194
  async signTransaction(parameters) {
195
195
  const { feePayer, ...rest } = parameters
196
196
  const client = getClient({
197
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
197
+ feePayer: (() => {
198
+ if (feePayer === false) return false
199
+ if (typeof feePayer === 'string') return feePayer
200
+ return undefined
201
+ })(),
198
202
  })
199
203
  const { account, prepared } = await withAccessKey(async (account, keyAuthorization) => ({
200
204
  account,
@@ -221,7 +225,11 @@ export function local(options: local.Options): Adapter.Adapter {
221
225
  async sendTransaction(parameters) {
222
226
  const { feePayer, ...rest } = parameters
223
227
  const client = getClient({
224
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
228
+ feePayer: (() => {
229
+ if (feePayer === false) return false
230
+ if (typeof feePayer === 'string') return feePayer
231
+ return undefined
232
+ })(),
225
233
  })
226
234
  const { account, prepared } = await withAccessKey(async (account, keyAuthorization) => ({
227
235
  account,
@@ -242,7 +250,11 @@ export function local(options: local.Options): Adapter.Adapter {
242
250
  async sendTransactionSync(parameters) {
243
251
  const { feePayer, ...rest } = parameters
244
252
  const client = getClient({
245
- feePayer: typeof feePayer === 'string' ? feePayer : undefined,
253
+ feePayer: (() => {
254
+ if (feePayer === false) return false
255
+ if (typeof feePayer === 'string') return feePayer
256
+ return undefined
257
+ })(),
246
258
  })
247
259
  const { account, prepared } = await withAccessKey(async (account, keyAuthorization) => ({
248
260
  account,
@@ -48,7 +48,7 @@ export const keyType = z.union([z.literal('secp256k1'), z.literal('p256'), z.lit
48
48
  export const keyAuthorization = z.object({
49
49
  address: u.address(),
50
50
  chainId: u.bigint(),
51
- expiry: z.nullish(u.number()),
51
+ expiry: z.union([u.number(), z.null(), z.undefined()]),
52
52
  keyId: u.address(),
53
53
  keyType,
54
54
  limits: z.optional(z.readonly(z.array(z.object({ token: u.address(), limit: u.bigint() })))),
@@ -173,7 +173,12 @@ export namespace personal_sign {
173
173
  export type Decoded = Schema.Decoded<typeof schema>
174
174
  }
175
175
 
176
- const sendCallsCapabilities = z.optional(z.object({ sync: z.optional(z.boolean()) }))
176
+ const sendCallsCapabilities = z.optional(
177
+ z.object({
178
+ feePayer: z.optional(z.union([z.boolean(), z.string()])),
179
+ sync: z.optional(z.boolean()),
180
+ }),
181
+ )
177
182
 
178
183
  export namespace wallet_sendCalls {
179
184
  export const schema = Schema.defineItem({
@@ -256,6 +261,11 @@ export namespace wallet_getCapabilities {
256
261
  atomic: z.object({
257
262
  status: z.union([z.literal('supported'), z.literal('ready'), z.literal('unsupported')]),
258
263
  }),
264
+ feePayer: z.optional(
265
+ z.object({
266
+ status: z.union([z.literal('supported'), z.literal('unsupported')]),
267
+ }),
268
+ ),
259
269
  }),
260
270
  ),
261
271
  })
@@ -17,7 +17,7 @@ export const keyType = z.union([z.literal('secp256k1'), z.literal('p256'), z.lit
17
17
  export const keyAuthorization = z.object({
18
18
  address: u.address(),
19
19
  chainId: u.bigint(),
20
- expiry: z.nullish(u.number()),
20
+ expiry: z.union([u.number(), z.null(), z.undefined()]),
21
21
  keyId: u.address(),
22
22
  keyType,
23
23
  limits: z.optional(z.readonly(z.array(z.object({ token: u.address(), limit: u.bigint() })))),