ox 1.7.0 → 1.7.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 (126) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/core/Hash.js +1 -1
  3. package/dist/core/Hash.js.map +1 -1
  4. package/dist/core/Siwe.d.ts.map +1 -1
  5. package/dist/core/Siwe.js +45 -6
  6. package/dist/core/Siwe.js.map +1 -1
  7. package/dist/tempo/KeyAuthorization.d.ts +1 -1
  8. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  9. package/dist/tempo/MultisigConfig.d.ts +151 -83
  10. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  11. package/dist/tempo/MultisigConfig.js +164 -86
  12. package/dist/tempo/MultisigConfig.js.map +1 -1
  13. package/dist/tempo/MultisigOperation.d.ts +324 -0
  14. package/dist/tempo/MultisigOperation.d.ts.map +1 -0
  15. package/dist/tempo/MultisigOperation.js +809 -0
  16. package/dist/tempo/MultisigOperation.js.map +1 -0
  17. package/dist/tempo/MultisigWitness.d.ts +106 -0
  18. package/dist/tempo/MultisigWitness.d.ts.map +1 -0
  19. package/dist/tempo/MultisigWitness.js +118 -0
  20. package/dist/tempo/MultisigWitness.js.map +1 -0
  21. package/dist/tempo/RpcSchemaTempo.d.ts +35 -0
  22. package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
  23. package/dist/tempo/SignatureEnvelope.d.ts +60 -80
  24. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  25. package/dist/tempo/SignatureEnvelope.js +87 -146
  26. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  27. package/dist/tempo/TransactionRequest.d.ts +9 -17
  28. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  29. package/dist/tempo/TransactionRequest.js +7 -7
  30. package/dist/tempo/TransactionRequest.js.map +1 -1
  31. package/dist/tempo/TxEnvelopeTempo.d.ts +3 -2
  32. package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  33. package/dist/tempo/TxEnvelopeTempo.js +3 -2
  34. package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
  35. package/dist/tempo/index.d.ts +22 -2
  36. package/dist/tempo/index.d.ts.map +1 -1
  37. package/dist/tempo/index.js +22 -2
  38. package/dist/tempo/index.js.map +1 -1
  39. package/dist/zod/tempo/AuthorizationTempo.d.ts +110 -110
  40. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  41. package/dist/zod/tempo/KeyAuthorization.d.ts +90 -83
  42. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  43. package/dist/zod/tempo/MultisigConfig.d.ts +31 -2
  44. package/dist/zod/tempo/MultisigConfig.d.ts.map +1 -1
  45. package/dist/zod/tempo/MultisigConfig.js +26 -3
  46. package/dist/zod/tempo/MultisigConfig.js.map +1 -1
  47. package/dist/zod/tempo/MultisigOperation.d.ts +168 -0
  48. package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -0
  49. package/dist/zod/tempo/MultisigOperation.js +65 -0
  50. package/dist/zod/tempo/MultisigOperation.js.map +1 -0
  51. package/dist/zod/tempo/MultisigWitness.d.ts +152 -0
  52. package/dist/zod/tempo/MultisigWitness.d.ts.map +1 -0
  53. package/dist/zod/tempo/MultisigWitness.js +76 -0
  54. package/dist/zod/tempo/MultisigWitness.js.map +1 -0
  55. package/dist/zod/tempo/RpcSchemaTempo.d.ts +607 -102
  56. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  57. package/dist/zod/tempo/RpcSchemaTempo.js +38 -0
  58. package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
  59. package/dist/zod/tempo/SignatureEnvelope.d.ts +33 -33
  60. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  61. package/dist/zod/tempo/SignatureEnvelope.js +9 -16
  62. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  63. package/dist/zod/tempo/Transaction.d.ts +228 -222
  64. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  65. package/dist/zod/tempo/TransactionRequest.d.ts +379 -176
  66. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  67. package/dist/zod/tempo/TransactionRequest.js +11 -22
  68. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  69. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +60 -48
  70. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  71. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +15 -12
  72. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  73. package/dist/zod/tempo/z.d.ts +2 -0
  74. package/dist/zod/tempo/z.d.ts.map +1 -1
  75. package/dist/zod/tempo/z.js +2 -0
  76. package/dist/zod/tempo/z.js.map +1 -1
  77. package/package.json +21 -1
  78. package/src/core/Hash.ts +1 -1
  79. package/src/core/Siwe.ts +45 -5
  80. package/src/core/_test/Hash.test.ts +15 -0
  81. package/src/core/_test/Siwe.test.ts +98 -0
  82. package/src/tempo/KeyAuthorization.test-d.ts +13 -1
  83. package/src/tempo/KeyAuthorization.test.ts +65 -0
  84. package/src/tempo/KeyAuthorization.ts +1 -1
  85. package/src/tempo/MultisigConfig.test-d.ts +52 -0
  86. package/src/tempo/MultisigConfig.test.ts +288 -227
  87. package/src/tempo/MultisigConfig.ts +275 -104
  88. package/src/tempo/MultisigOperation.test-d.ts +77 -0
  89. package/src/tempo/MultisigOperation.test.ts +1883 -0
  90. package/src/tempo/MultisigOperation.ts +1254 -0
  91. package/src/tempo/MultisigWitness.test-d.ts +42 -0
  92. package/src/tempo/MultisigWitness.test.ts +288 -0
  93. package/src/tempo/MultisigWitness.ts +210 -0
  94. package/src/tempo/RpcSchemaTempo.test-d.ts +56 -0
  95. package/src/tempo/RpcSchemaTempo.ts +37 -0
  96. package/src/tempo/SignatureEnvelope.test-d.ts +63 -46
  97. package/src/tempo/SignatureEnvelope.test.ts +523 -500
  98. package/src/tempo/SignatureEnvelope.ts +172 -242
  99. package/src/tempo/TransactionRequest.test-d.ts +11 -0
  100. package/src/tempo/TransactionRequest.test.ts +285 -33
  101. package/src/tempo/TransactionRequest.ts +15 -20
  102. package/src/tempo/TxEnvelopeTempo.test-d.ts +7 -0
  103. package/src/tempo/TxEnvelopeTempo.test.ts +25 -0
  104. package/src/tempo/TxEnvelopeTempo.ts +5 -3
  105. package/src/tempo/index.ts +22 -2
  106. package/src/tempo/multisig.e2e.test.ts +113 -86
  107. package/src/version.ts +1 -1
  108. package/src/zod/tempo/MultisigConfig.ts +29 -3
  109. package/src/zod/tempo/MultisigOperation.ts +69 -0
  110. package/src/zod/tempo/MultisigWitness.ts +101 -0
  111. package/src/zod/tempo/RpcSchemaTempo.ts +43 -0
  112. package/src/zod/tempo/SignatureEnvelope.ts +20 -38
  113. package/src/zod/tempo/TransactionRequest.ts +17 -26
  114. package/src/zod/tempo/_test/KeyAuthorization.test.ts +11 -0
  115. package/src/zod/tempo/_test/MultisigConfig.test-d.ts +13 -0
  116. package/src/zod/tempo/_test/MultisigConfig.test.ts +13 -2
  117. package/src/zod/tempo/_test/MultisigOperation.test-d.ts +27 -0
  118. package/src/zod/tempo/_test/MultisigOperation.test.ts +68 -0
  119. package/src/zod/tempo/_test/MultisigWitness.test-d.ts +13 -0
  120. package/src/zod/tempo/_test/MultisigWitness.test.ts +149 -0
  121. package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +31 -0
  122. package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +41 -0
  123. package/src/zod/tempo/_test/SignatureEnvelope.test-d.ts +1 -1
  124. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +25 -34
  125. package/src/zod/tempo/_test/TransactionRequest.test.ts +176 -8
  126. package/src/zod/tempo/z.ts +2 -0
package/src/core/Siwe.ts CHANGED
@@ -23,6 +23,36 @@ export const prefixRegex =
23
23
  export const suffixRegex =
24
24
  /(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId>.+))?/
25
25
 
26
+ const siweDateTimeRegex =
27
+ /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])[Tt]([01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/
28
+
29
+ function parseSiweDateTime(value: string): Date {
30
+ const match = value.match(siweDateTimeRegex)
31
+ if (!match) return new Date(Number.NaN)
32
+
33
+ const year = Number(match[1])
34
+ const month = Number(match[2])
35
+ const day = Number(match[3])
36
+ const days = [
37
+ 31,
38
+ year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28,
39
+ 31,
40
+ 30,
41
+ 31,
42
+ 30,
43
+ 31,
44
+ 31,
45
+ 30,
46
+ 31,
47
+ 30,
48
+ 31,
49
+ ]
50
+ const daysInMonth = days[month - 1]
51
+ if (!daysInMonth || day > daysInMonth) return new Date(Number.NaN)
52
+
53
+ return new Date(value.toUpperCase())
54
+ }
55
+
26
56
  /** [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) message fields. */
27
57
  export type Message = {
28
58
  /**
@@ -388,9 +418,11 @@ export function parseMessage(message: string): ExactPartial<Message> {
388
418
  ...prefix,
389
419
  ...suffix,
390
420
  ...(chainId ? { chainId: Number(chainId) } : {}),
391
- ...(expirationTime ? { expirationTime: new Date(expirationTime) } : {}),
392
- ...(issuedAt ? { issuedAt: new Date(issuedAt) } : {}),
393
- ...(notBefore ? { notBefore: new Date(notBefore) } : {}),
421
+ ...(expirationTime
422
+ ? { expirationTime: parseSiweDateTime(expirationTime) }
423
+ : {}),
424
+ ...(issuedAt ? { issuedAt: parseSiweDateTime(issuedAt) } : {}),
425
+ ...(notBefore ? { notBefore: parseSiweDateTime(notBefore) } : {}),
394
426
  ...(requestId ? { requestId } : {}),
395
427
  ...(resources ? { resources } : {}),
396
428
  ...(scheme ? { scheme } : {}),
@@ -431,8 +463,16 @@ export function validateMessage(value: validateMessage.Value): boolean {
431
463
  if (nonce && message.nonce !== nonce) return false
432
464
  if (scheme && message.scheme !== scheme) return false
433
465
 
434
- if (message.expirationTime && time >= message.expirationTime) return false
435
- if (message.notBefore && time < message.notBefore) return false
466
+ if (Number.isNaN(time.getTime())) return false
467
+
468
+ if (message.expirationTime) {
469
+ if (Number.isNaN(message.expirationTime.getTime())) return false
470
+ if (time >= message.expirationTime) return false
471
+ }
472
+ if (message.notBefore) {
473
+ if (Number.isNaN(message.notBefore.getTime())) return false
474
+ if (time < message.notBefore) return false
475
+ }
436
476
 
437
477
  try {
438
478
  if (!message.address) return false
@@ -762,6 +762,21 @@ describe('validate', () => {
762
762
  expect(
763
763
  Hash.validate('a5cc3c03994db5b0d9a5eEdD10Cabab0813678ac'),
764
764
  ).toBeFalsy()
765
+ expect(
766
+ Hash.validate(
767
+ '0xgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg',
768
+ ),
769
+ ).toBeFalsy()
770
+ expect(
771
+ Hash.validate(
772
+ '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72f',
773
+ ),
774
+ ).toBeFalsy()
775
+ expect(
776
+ Hash.validate(
777
+ '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe0',
778
+ ),
779
+ ).toBeFalsy()
765
780
  expect(
766
781
  Hash.validate(
767
782
  '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe',
@@ -546,6 +546,81 @@ Expiration Time: 2022-02-04T00:00:00.000Z`
546
546
  )
547
547
  })
548
548
 
549
+ test.each([
550
+ ['never', '2023-02-01T00:00:00Z'],
551
+ ['2023-02-29T00:00:00Z', '2023-02-28T12:00:00Z'],
552
+ ['2023-04-31T00:00:00Z', '2023-04-30T12:00:00Z'],
553
+ ['2023-02-01T24:00:00Z', '2023-02-01T12:00:00Z'],
554
+ ])(
555
+ 'behavior: invalid RFC 3339 expirationTime `%s`',
556
+ (expirationTime, time) => {
557
+ const message = `https://example.com wants you to sign in with your Ethereum account:
558
+ 0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
559
+
560
+ URI: https://example.com/path
561
+ Version: 1
562
+ Chain ID: 1
563
+ Nonce: foobarbaz
564
+ Issued At: 2023-02-01T00:00:00.000Z
565
+ Expiration Time: ${expirationTime}`
566
+ const parsed = Siwe.parseMessage(message)
567
+ expect({
568
+ invalid: Number.isNaN(parsed.expirationTime?.getTime()),
569
+ valid: Siwe.validateMessage({
570
+ message: parsed,
571
+ time: new Date(time),
572
+ }),
573
+ }).toMatchInlineSnapshot(`
574
+ {
575
+ "invalid": true,
576
+ "valid": false,
577
+ }
578
+ `)
579
+ },
580
+ )
581
+
582
+ test.each([
583
+ '2030-02-04t00:00:00Z',
584
+ '2030-02-04T00:00:00z',
585
+ '2030-02-04t00:00:00z',
586
+ ])('behavior: lowercase RFC 3339 expirationTime `%s`', (expirationTime) => {
587
+ const message = `https://example.com wants you to sign in with your Ethereum account:
588
+ 0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
589
+
590
+ URI: https://example.com/path
591
+ Version: 1
592
+ Chain ID: 1
593
+ Nonce: foobarbaz
594
+ Issued At: 2023-02-01T00:00:00.000Z
595
+ Expiration Time: ${expirationTime}`
596
+ const parsed = Siwe.parseMessage(message)
597
+ expect(parsed.expirationTime).toMatchInlineSnapshot(
598
+ '2030-02-04T00:00:00.000Z',
599
+ )
600
+ expect(
601
+ Siwe.validateMessage({
602
+ message: parsed,
603
+ time: new Date('2029-02-04T00:00:00Z'),
604
+ }),
605
+ ).toBeTruthy()
606
+ })
607
+
608
+ test('behavior: leap-year expirationTime', () => {
609
+ const message = `https://example.com wants you to sign in with your Ethereum account:
610
+ 0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
611
+
612
+ URI: https://example.com/path
613
+ Version: 1
614
+ Chain ID: 1
615
+ Nonce: foobarbaz
616
+ Issued At: 2023-02-01T00:00:00.000Z
617
+ Expiration Time: 2032-02-29T00:00:00Z`
618
+ const parsed = Siwe.parseMessage(message)
619
+ expect(parsed.expirationTime).toMatchInlineSnapshot(
620
+ '2032-02-29T00:00:00.000Z',
621
+ )
622
+ })
623
+
549
624
  test('behavior: with notBefore', () => {
550
625
  const message = `https://example.com wants you to sign in with your Ethereum account:
551
626
  0xA0Cf798816D4b9b9866b5330EEa46a18382f251e
@@ -730,6 +805,29 @@ describe('validateMessage', () => {
730
805
  ).toBeFalsy()
731
806
  })
732
807
 
808
+ test.each(['expirationTime', 'notBefore'] as const)(
809
+ 'behavior: invalid %s',
810
+ (field) => {
811
+ expect(
812
+ Siwe.validateMessage({
813
+ message: {
814
+ ...message,
815
+ [field]: new Date('never'),
816
+ },
817
+ }),
818
+ ).toBeFalsy()
819
+ },
820
+ )
821
+
822
+ test('behavior: invalid time', () => {
823
+ expect(
824
+ Siwe.validateMessage({
825
+ message,
826
+ time: new Date('never'),
827
+ }),
828
+ ).toBeFalsy()
829
+ })
830
+
733
831
  test('behavior: time is before notBefore', () => {
734
832
  vi.useFakeTimers()
735
833
  vi.setSystemTime(new Date(Date.UTC(2023, 1, 1)))
@@ -1,6 +1,7 @@
1
1
  import { expectTypeOf, test } from 'vp/test'
2
2
  import * as KeyAuthorization from './KeyAuthorization.js'
3
- import * as SignatureEnvelope from './SignatureEnvelope.js'
3
+ import * as MultisigConfig from './MultisigConfig.js'
4
+ import type * as SignatureEnvelope from './SignatureEnvelope.js'
4
5
 
5
6
  const authorization = {
6
7
  address: '0x1111111111111111111111111111111111111111',
@@ -19,6 +20,16 @@ const signature = {
19
20
 
20
21
  const multisig = {
21
22
  account: '0x2222222222222222222222222222222222222222',
23
+ config: MultisigConfig.from({
24
+ owners: [
25
+ {
26
+ owner: '0x1111111111111111111111111111111111111111',
27
+ weight: 1,
28
+ },
29
+ ],
30
+ threshold: 1,
31
+ version: 1n,
32
+ }),
22
33
  signatures: [signature],
23
34
  type: 'multisig',
24
35
  } as const satisfies SignatureEnvelope.Multisig
@@ -46,6 +57,7 @@ test('accepts multisig signatures', () => {
46
57
 
47
58
  const multisigRpc = {
48
59
  account: multisig.account,
60
+ config: MultisigConfig.toRpc(multisig.config),
49
61
  signatures: [
50
62
  {
51
63
  r: '0x01',
@@ -9,6 +9,7 @@ import {
9
9
  } from 'ox'
10
10
  import { describe, expect, test } from 'vp/test'
11
11
  import * as KeyAuthorization from './KeyAuthorization.js'
12
+ import * as MultisigConfig from './MultisigConfig.js'
12
13
  import * as Period from './Period.js'
13
14
  import * as SignatureEnvelope from './SignatureEnvelope.js'
14
15
 
@@ -55,6 +56,16 @@ const signature_webauthn = SignatureEnvelope.from({
55
56
 
56
57
  const signature_multisig = {
57
58
  account: address,
59
+ config: MultisigConfig.from({
60
+ owners: [
61
+ {
62
+ owner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
63
+ weight: 1,
64
+ },
65
+ ],
66
+ threshold: 1,
67
+ version: 1n,
68
+ }),
58
69
  signatures: [SignatureEnvelope.from(signature_secp256k1)],
59
70
  type: 'multisig',
60
71
  } as const satisfies SignatureEnvelope.Multisig
@@ -1071,6 +1082,60 @@ describe('getSignPayload', () => {
1071
1082
  })
1072
1083
 
1073
1084
  describe('deserialize', () => {
1085
+ test('example: matches the frozen multisig witness vector', () => {
1086
+ const serialized =
1087
+ '0xf8f1f85382107980941eff47bc3a10a45d4b230b5d10e37751fe6aa718808080a0535353535353535353535353535353535353535353535353535353535353535380949dba7f426b711d4893c11611eacf7cc334e7146bb89a05f897949dba7f426b711d4893c11611eacf7cc334e7146bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b8412cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e21451b' as const
1088
+ const authorization = KeyAuthorization.deserialize(serialized)
1089
+
1090
+ expect(authorization).toMatchInlineSnapshot(`
1091
+ {
1092
+ "account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
1093
+ "address": "0x1eff47bc3a10a45d4b230b5d10e37751fe6aa718",
1094
+ "chainId": 4217n,
1095
+ "isAdmin": false,
1096
+ "signature": {
1097
+ "account": "0x9dba7f426b711d4893c11611eacf7cc334e7146b",
1098
+ "config": {
1099
+ "owners": [
1100
+ {
1101
+ "owner": "0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",
1102
+ "weight": 1,
1103
+ },
1104
+ ],
1105
+ "salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
1106
+ "threshold": 1,
1107
+ "version": 0n,
1108
+ },
1109
+ "signatures": [
1110
+ {
1111
+ "signature": {
1112
+ "r": "0x2cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8",
1113
+ "s": "0x359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e2145",
1114
+ "yParity": 0,
1115
+ },
1116
+ "type": "secp256k1",
1117
+ },
1118
+ ],
1119
+ "type": "multisig",
1120
+ },
1121
+ "type": "secp256k1",
1122
+ "witness": "0x5353535353535353535353535353535353535353535353535353535353535353",
1123
+ }
1124
+ `)
1125
+ expect(KeyAuthorization.serialize(authorization)).toBe(serialized)
1126
+ })
1127
+
1128
+ test('multisig', () => {
1129
+ const serialized = Rlp.fromHex([
1130
+ ['0x1', '0x', address],
1131
+ SignatureEnvelope.serialize(signature_multisig),
1132
+ ])
1133
+
1134
+ expect(KeyAuthorization.deserialize(serialized).signature).toEqual(
1135
+ signature_multisig,
1136
+ )
1137
+ })
1138
+
1074
1139
  test('default', () => {
1075
1140
  const authorization = KeyAuthorization.from({
1076
1141
  address,
@@ -151,7 +151,7 @@ type SignatureValue =
151
151
  | UnionPartialBy<Signature, 'prehash' | 'type'>
152
152
  | SignatureEnvelope.Secp256k1Flat
153
153
  | SignatureEnvelope.Serialized
154
- | SignatureEnvelope.from.MultisigFromInitialConfig
154
+ | SignatureEnvelope.from.MultisigFromConfig
155
155
 
156
156
  type BaseTuple = readonly [
157
157
  chainId: Hex.Hex,
@@ -0,0 +1,52 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import * as MultisigConfig from './MultisigConfig.js'
3
+
4
+ const input = {
5
+ owners: [
6
+ {
7
+ owner: '0x1111111111111111111111111111111111111111',
8
+ weight: 1,
9
+ },
10
+ ],
11
+ threshold: 1,
12
+ } as const satisfies MultisigConfig.Input
13
+
14
+ test('from returns a complete configuration', () => {
15
+ const config = MultisigConfig.from(input)
16
+ const numeric = MultisigConfig.from({ ...input, version: 1 })
17
+ const zero = MultisigConfig.from({ ...input, version: 0 })
18
+
19
+ expectTypeOf(config).toMatchTypeOf<MultisigConfig.Config>()
20
+ expectTypeOf(config.version).toEqualTypeOf<0n>()
21
+ expectTypeOf(numeric.version).toEqualTypeOf<bigint>()
22
+ expectTypeOf(zero.version).toEqualTypeOf<0n>()
23
+ })
24
+
25
+ test('RPC configurations use hexadecimal versions', () => {
26
+ const rpc = MultisigConfig.toRpc(MultisigConfig.from(input))
27
+
28
+ expectTypeOf(rpc).toEqualTypeOf<MultisigConfig.Rpc>()
29
+ expectTypeOf(rpc.version).toEqualTypeOf<`0x${string}`>()
30
+ })
31
+
32
+ test('complete configurations require a version', () => {
33
+ // @ts-expect-error Complete configurations include their version.
34
+ const config: MultisigConfig.Config = input
35
+
36
+ expectTypeOf(config).toEqualTypeOf<MultisigConfig.Config>()
37
+ })
38
+
39
+ test('sign payloads take the version from config', () => {
40
+ MultisigConfig.getSignPayload({
41
+ account: '0x2222222222222222222222222222222222222222',
42
+ config: { version: 1 },
43
+ payload: '0x1234',
44
+ })
45
+
46
+ MultisigConfig.getSignPayload({
47
+ account: '0x2222222222222222222222222222222222222222',
48
+ // @ts-expect-error A configuration version is required.
49
+ config: {},
50
+ payload: '0x1234',
51
+ })
52
+ })