ox 0.9.16 → 0.10.0

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 (216) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +4 -4
  3. package/TxEnvelope/package.json +6 -0
  4. package/TxEnvelopeEip1559/package.json +6 -0
  5. package/TxEnvelopeEip2930/package.json +6 -0
  6. package/TxEnvelopeEip4844/package.json +6 -0
  7. package/TxEnvelopeEip7702/package.json +6 -0
  8. package/TxEnvelopeLegacy/package.json +6 -0
  9. package/_cjs/core/{TransactionEnvelope.js → TxEnvelope.js} +1 -1
  10. package/_cjs/core/TxEnvelope.js.map +1 -0
  11. package/_cjs/core/{TransactionEnvelopeEip1559.js → TxEnvelopeEip1559.js} +2 -2
  12. package/_cjs/core/TxEnvelopeEip1559.js.map +1 -0
  13. package/_cjs/core/{TransactionEnvelopeEip2930.js → TxEnvelopeEip2930.js} +2 -2
  14. package/_cjs/core/TxEnvelopeEip2930.js.map +1 -0
  15. package/_cjs/core/{TransactionEnvelopeEip4844.js → TxEnvelopeEip4844.js} +4 -4
  16. package/_cjs/core/TxEnvelopeEip4844.js.map +1 -0
  17. package/_cjs/core/{TransactionEnvelopeEip7702.js → TxEnvelopeEip7702.js} +4 -4
  18. package/_cjs/core/TxEnvelopeEip7702.js.map +1 -0
  19. package/_cjs/core/{TransactionEnvelopeLegacy.js → TxEnvelopeLegacy.js} +2 -2
  20. package/_cjs/core/TxEnvelopeLegacy.js.map +1 -0
  21. package/_cjs/core/WebAuthnP256.js +1 -1
  22. package/_cjs/core/WebAuthnP256.js.map +1 -1
  23. package/_cjs/erc8021/Attribution.js +36 -6
  24. package/_cjs/erc8021/Attribution.js.map +1 -1
  25. package/_cjs/index.docs.js +1 -0
  26. package/_cjs/index.docs.js.map +1 -1
  27. package/_cjs/index.js +7 -7
  28. package/_cjs/index.js.map +1 -1
  29. package/_cjs/tempo/AuthorizationTempo.js +101 -0
  30. package/_cjs/tempo/AuthorizationTempo.js.map +1 -0
  31. package/_cjs/tempo/KeyAuthorization.js +123 -0
  32. package/_cjs/tempo/KeyAuthorization.js.map +1 -0
  33. package/_cjs/tempo/PoolId.js +10 -0
  34. package/_cjs/tempo/PoolId.js.map +1 -0
  35. package/_cjs/tempo/SignatureEnvelope.js +394 -0
  36. package/_cjs/tempo/SignatureEnvelope.js.map +1 -0
  37. package/_cjs/tempo/Tick.js +77 -0
  38. package/_cjs/tempo/Tick.js.map +1 -0
  39. package/_cjs/tempo/TokenId.js +28 -0
  40. package/_cjs/tempo/TokenId.js.map +1 -0
  41. package/_cjs/tempo/TokenRole.js +26 -0
  42. package/_cjs/tempo/TokenRole.js.map +1 -0
  43. package/_cjs/tempo/Transaction.js +80 -0
  44. package/_cjs/tempo/Transaction.js.map +1 -0
  45. package/_cjs/tempo/TransactionReceipt.js +26 -0
  46. package/_cjs/tempo/TransactionReceipt.js.map +1 -0
  47. package/_cjs/tempo/TransactionRequest.js +53 -0
  48. package/_cjs/tempo/TransactionRequest.js.map +1 -0
  49. package/_cjs/tempo/TxEnvelopeTempo.js +267 -0
  50. package/_cjs/tempo/TxEnvelopeTempo.js.map +1 -0
  51. package/_cjs/tempo/index.js +15 -0
  52. package/_cjs/tempo/index.js.map +1 -0
  53. package/_cjs/version.js +1 -1
  54. package/_esm/core/Blobs.js +8 -8
  55. package/_esm/core/{TransactionEnvelope.js → TxEnvelope.js} +11 -11
  56. package/_esm/core/TxEnvelope.js.map +1 -0
  57. package/_esm/core/{TransactionEnvelopeEip1559.js → TxEnvelopeEip1559.js} +42 -42
  58. package/_esm/core/TxEnvelopeEip1559.js.map +1 -0
  59. package/_esm/core/{TransactionEnvelopeEip2930.js → TxEnvelopeEip2930.js} +43 -43
  60. package/_esm/core/TxEnvelopeEip2930.js.map +1 -0
  61. package/_esm/core/{TransactionEnvelopeEip4844.js → TxEnvelopeEip4844.js} +42 -42
  62. package/_esm/core/TxEnvelopeEip4844.js.map +1 -0
  63. package/_esm/core/{TransactionEnvelopeEip7702.js → TxEnvelopeEip7702.js} +40 -40
  64. package/_esm/core/TxEnvelopeEip7702.js.map +1 -0
  65. package/_esm/core/{TransactionEnvelopeLegacy.js → TxEnvelopeLegacy.js} +42 -42
  66. package/_esm/core/TxEnvelopeLegacy.js.map +1 -0
  67. package/_esm/core/WebAuthnP256.js +1 -1
  68. package/_esm/core/WebAuthnP256.js.map +1 -1
  69. package/_esm/erc8021/Attribution.js +58 -13
  70. package/_esm/erc8021/Attribution.js.map +1 -1
  71. package/_esm/index.docs.js +1 -0
  72. package/_esm/index.docs.js.map +1 -1
  73. package/_esm/index.js +192 -192
  74. package/_esm/index.js.map +1 -1
  75. package/_esm/tempo/AuthorizationTempo.js +664 -0
  76. package/_esm/tempo/AuthorizationTempo.js.map +1 -0
  77. package/_esm/tempo/KeyAuthorization.js +426 -0
  78. package/_esm/tempo/KeyAuthorization.js.map +1 -0
  79. package/_esm/tempo/PoolId.js +28 -0
  80. package/_esm/tempo/PoolId.js.map +1 -0
  81. package/_esm/tempo/SignatureEnvelope.js +660 -0
  82. package/_esm/tempo/SignatureEnvelope.js.map +1 -0
  83. package/_esm/tempo/Tick.js +147 -0
  84. package/_esm/tempo/Tick.js.map +1 -0
  85. package/_esm/tempo/TokenId.js +71 -0
  86. package/_esm/tempo/TokenId.js.map +1 -0
  87. package/_esm/tempo/TokenRole.js +40 -0
  88. package/_esm/tempo/TokenRole.js.map +1 -0
  89. package/_esm/tempo/Transaction.js +167 -0
  90. package/_esm/tempo/Transaction.js.map +1 -0
  91. package/_esm/tempo/TransactionReceipt.js +138 -0
  92. package/_esm/tempo/TransactionReceipt.js.map +1 -0
  93. package/_esm/tempo/TransactionRequest.js +99 -0
  94. package/_esm/tempo/TransactionRequest.js.map +1 -0
  95. package/_esm/tempo/TxEnvelopeTempo.js +607 -0
  96. package/_esm/tempo/TxEnvelopeTempo.js.map +1 -0
  97. package/_esm/tempo/index.js +298 -0
  98. package/_esm/tempo/index.js.map +1 -0
  99. package/_esm/version.js +1 -1
  100. package/_types/core/Blobs.d.ts +8 -8
  101. package/_types/core/{TransactionEnvelope.d.ts → TxEnvelope.d.ts} +11 -11
  102. package/_types/core/TxEnvelope.d.ts.map +1 -0
  103. package/_types/core/{TransactionEnvelopeEip1559.d.ts → TxEnvelopeEip1559.d.ts} +54 -54
  104. package/_types/core/TxEnvelopeEip1559.d.ts.map +1 -0
  105. package/_types/core/{TransactionEnvelopeEip2930.d.ts → TxEnvelopeEip2930.d.ts} +55 -55
  106. package/_types/core/TxEnvelopeEip2930.d.ts.map +1 -0
  107. package/_types/core/{TransactionEnvelopeEip4844.d.ts → TxEnvelopeEip4844.d.ts} +54 -54
  108. package/_types/core/TxEnvelopeEip4844.d.ts.map +1 -0
  109. package/_types/core/{TransactionEnvelopeEip7702.d.ts → TxEnvelopeEip7702.d.ts} +49 -49
  110. package/_types/core/TxEnvelopeEip7702.d.ts.map +1 -0
  111. package/_types/core/{TransactionEnvelopeLegacy.d.ts → TxEnvelopeLegacy.d.ts} +54 -54
  112. package/_types/core/TxEnvelopeLegacy.d.ts.map +1 -0
  113. package/_types/core/WebAuthnP256.d.ts +1 -1
  114. package/_types/core/WebAuthnP256.d.ts.map +1 -1
  115. package/_types/erc8021/Attribution.d.ts +20 -6
  116. package/_types/erc8021/Attribution.d.ts.map +1 -1
  117. package/_types/index.d.ts +192 -192
  118. package/_types/index.d.ts.map +1 -1
  119. package/_types/index.docs.d.ts +1 -0
  120. package/_types/index.docs.d.ts.map +1 -1
  121. package/_types/tempo/AuthorizationTempo.d.ts +688 -0
  122. package/_types/tempo/AuthorizationTempo.d.ts.map +1 -0
  123. package/_types/tempo/KeyAuthorization.d.ts +437 -0
  124. package/_types/tempo/KeyAuthorization.d.ts.map +1 -0
  125. package/_types/tempo/PoolId.d.ts +33 -0
  126. package/_types/tempo/PoolId.d.ts.map +1 -0
  127. package/_types/tempo/SignatureEnvelope.d.ts +438 -0
  128. package/_types/tempo/SignatureEnvelope.d.ts.map +1 -0
  129. package/_types/tempo/Tick.d.ts +120 -0
  130. package/_types/tempo/Tick.d.ts.map +1 -0
  131. package/_types/tempo/TokenId.d.ts +55 -0
  132. package/_types/tempo/TokenId.d.ts.map +1 -0
  133. package/_types/tempo/TokenRole.d.ts +29 -0
  134. package/_types/tempo/TokenRole.d.ts.map +1 -0
  135. package/_types/tempo/Transaction.d.ts +208 -0
  136. package/_types/tempo/Transaction.d.ts.map +1 -0
  137. package/_types/tempo/TransactionReceipt.d.ts +165 -0
  138. package/_types/tempo/TransactionReceipt.d.ts.map +1 -0
  139. package/_types/tempo/TransactionRequest.d.ts +89 -0
  140. package/_types/tempo/TransactionRequest.d.ts.map +1 -0
  141. package/_types/tempo/TxEnvelopeTempo.d.ts +551 -0
  142. package/_types/tempo/TxEnvelopeTempo.d.ts.map +1 -0
  143. package/_types/tempo/index.d.ts +300 -0
  144. package/_types/tempo/index.d.ts.map +1 -0
  145. package/_types/version.d.ts +1 -1
  146. package/core/Blobs.ts +8 -8
  147. package/core/{TransactionEnvelope.ts → TxEnvelope.ts} +10 -10
  148. package/core/{TransactionEnvelopeEip1559.ts → TxEnvelopeEip1559.ts} +60 -69
  149. package/core/{TransactionEnvelopeEip2930.ts → TxEnvelopeEip2930.ts} +61 -72
  150. package/core/{TransactionEnvelopeEip4844.ts → TxEnvelopeEip4844.ts} +62 -71
  151. package/core/{TransactionEnvelopeEip7702.ts → TxEnvelopeEip7702.ts} +58 -67
  152. package/core/{TransactionEnvelopeLegacy.ts → TxEnvelopeLegacy.ts} +59 -68
  153. package/core/WebAuthnP256.ts +3 -1
  154. package/erc8021/Attribution.ts +77 -15
  155. package/index.docs.ts +1 -0
  156. package/index.ts +192 -195
  157. package/package.json +91 -31
  158. package/tempo/AuthorizationTempo/package.json +6 -0
  159. package/tempo/AuthorizationTempo.test.ts +1293 -0
  160. package/tempo/AuthorizationTempo.ts +884 -0
  161. package/tempo/KeyAuthorization/package.json +6 -0
  162. package/tempo/KeyAuthorization.test.ts +1373 -0
  163. package/tempo/KeyAuthorization.ts +622 -0
  164. package/tempo/PoolId/package.json +6 -0
  165. package/tempo/PoolId.test.ts +33 -0
  166. package/tempo/PoolId.ts +42 -0
  167. package/tempo/SignatureEnvelope/package.json +6 -0
  168. package/tempo/SignatureEnvelope.test.ts +1877 -0
  169. package/tempo/SignatureEnvelope.ts +973 -0
  170. package/tempo/Tick/package.json +6 -0
  171. package/tempo/Tick.test.ts +281 -0
  172. package/tempo/Tick.ts +186 -0
  173. package/tempo/TokenId/package.json +6 -0
  174. package/tempo/TokenId.test.ts +40 -0
  175. package/tempo/TokenId.ts +80 -0
  176. package/tempo/TokenRole/package.json +6 -0
  177. package/tempo/TokenRole.test.ts +16 -0
  178. package/tempo/TokenRole.ts +45 -0
  179. package/tempo/Transaction/package.json +6 -0
  180. package/tempo/Transaction.test.ts +523 -0
  181. package/tempo/Transaction.ts +339 -0
  182. package/tempo/TransactionReceipt/package.json +6 -0
  183. package/tempo/TransactionReceipt.ts +200 -0
  184. package/tempo/TransactionRequest/package.json +6 -0
  185. package/tempo/TransactionRequest.ts +160 -0
  186. package/tempo/TxEnvelopeTempo/package.json +6 -0
  187. package/tempo/TxEnvelopeTempo.test.ts +1371 -0
  188. package/tempo/TxEnvelopeTempo.ts +972 -0
  189. package/tempo/e2e.test.ts +1387 -0
  190. package/tempo/index.ts +308 -0
  191. package/tempo/package.json +6 -0
  192. package/version.ts +1 -1
  193. package/TransactionEnvelope/package.json +0 -6
  194. package/TransactionEnvelopeEip1559/package.json +0 -6
  195. package/TransactionEnvelopeEip2930/package.json +0 -6
  196. package/TransactionEnvelopeEip4844/package.json +0 -6
  197. package/TransactionEnvelopeEip7702/package.json +0 -6
  198. package/TransactionEnvelopeLegacy/package.json +0 -6
  199. package/_cjs/core/TransactionEnvelope.js.map +0 -1
  200. package/_cjs/core/TransactionEnvelopeEip1559.js.map +0 -1
  201. package/_cjs/core/TransactionEnvelopeEip2930.js.map +0 -1
  202. package/_cjs/core/TransactionEnvelopeEip4844.js.map +0 -1
  203. package/_cjs/core/TransactionEnvelopeEip7702.js.map +0 -1
  204. package/_cjs/core/TransactionEnvelopeLegacy.js.map +0 -1
  205. package/_esm/core/TransactionEnvelope.js.map +0 -1
  206. package/_esm/core/TransactionEnvelopeEip1559.js.map +0 -1
  207. package/_esm/core/TransactionEnvelopeEip2930.js.map +0 -1
  208. package/_esm/core/TransactionEnvelopeEip4844.js.map +0 -1
  209. package/_esm/core/TransactionEnvelopeEip7702.js.map +0 -1
  210. package/_esm/core/TransactionEnvelopeLegacy.js.map +0 -1
  211. package/_types/core/TransactionEnvelope.d.ts.map +0 -1
  212. package/_types/core/TransactionEnvelopeEip1559.d.ts.map +0 -1
  213. package/_types/core/TransactionEnvelopeEip2930.d.ts.map +0 -1
  214. package/_types/core/TransactionEnvelopeEip4844.d.ts.map +0 -1
  215. package/_types/core/TransactionEnvelopeEip7702.d.ts.map +0 -1
  216. package/_types/core/TransactionEnvelopeLegacy.d.ts.map +0 -1
@@ -0,0 +1,1293 @@
1
+ import { P256, Secp256k1 } from 'ox'
2
+ import { describe, expect, expectTypeOf, test } from 'vitest'
3
+ import * as AuthorizationTempo from './AuthorizationTempo.js'
4
+ import * as SignatureEnvelope from './SignatureEnvelope.js'
5
+
6
+ // Use a fixed private key for testing signatures
7
+ const testPrivateKey =
8
+ '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' as const
9
+
10
+ describe('from', () => {
11
+ test('default', () => {
12
+ {
13
+ const authorization = AuthorizationTempo.from({
14
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
15
+ chainId: 1,
16
+ nonce: 40n,
17
+ })
18
+ expectTypeOf(authorization).toEqualTypeOf<{
19
+ readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
20
+ readonly chainId: 1
21
+ readonly nonce: 40n
22
+ }>()
23
+ expectTypeOf(authorization).toExtend<
24
+ AuthorizationTempo.AuthorizationTempo<false>
25
+ >()
26
+ expect(authorization).toMatchInlineSnapshot(
27
+ `
28
+ {
29
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
30
+ "chainId": 1,
31
+ "nonce": 40n,
32
+ }
33
+ `,
34
+ )
35
+ }
36
+
37
+ {
38
+ const authorization = AuthorizationTempo.from({
39
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
40
+ chainId: 1,
41
+ nonce: 40n,
42
+ signature: {
43
+ signature: {
44
+ r: 49782753348462494199823712700004552394425719014458918871452329774910450607807n,
45
+ s: 33726695977844476214676913201140481102225469284307016937915595756355928419768n,
46
+ yParity: 0,
47
+ },
48
+ type: 'secp256k1' as const,
49
+ },
50
+ })
51
+ expectTypeOf(authorization).toEqualTypeOf<{
52
+ readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
53
+ readonly chainId: 1
54
+ readonly nonce: 40n
55
+ readonly signature: {
56
+ readonly signature: {
57
+ readonly r: 49782753348462494199823712700004552394425719014458918871452329774910450607807n
58
+ readonly s: 33726695977844476214676913201140481102225469284307016937915595756355928419768n
59
+ readonly yParity: 0
60
+ }
61
+ readonly type: 'secp256k1'
62
+ }
63
+ }>()
64
+ expectTypeOf(authorization).toExtend<
65
+ AuthorizationTempo.AuthorizationTempo<true>
66
+ >()
67
+ expect(authorization).toMatchInlineSnapshot(
68
+ `
69
+ {
70
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
71
+ "chainId": 1,
72
+ "nonce": 40n,
73
+ "signature": {
74
+ "signature": {
75
+ "r": 49782753348462494199823712700004552394425719014458918871452329774910450607807n,
76
+ "s": 33726695977844476214676913201140481102225469284307016937915595756355928419768n,
77
+ "yParity": 0,
78
+ },
79
+ "type": "secp256k1",
80
+ },
81
+ }
82
+ `,
83
+ )
84
+ }
85
+ })
86
+
87
+ test('options: signature (secp256k1)', () => {
88
+ const authorization = AuthorizationTempo.from({
89
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
90
+ chainId: 1,
91
+ nonce: 40n,
92
+ })
93
+ const signature = Secp256k1.sign({
94
+ payload: AuthorizationTempo.getSignPayload(authorization),
95
+ privateKey: testPrivateKey,
96
+ })
97
+ const authorization_signed = AuthorizationTempo.from(authorization, {
98
+ signature,
99
+ })
100
+ expectTypeOf(authorization_signed).toExtend<{
101
+ readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
102
+ readonly chainId: 1
103
+ readonly nonce: 40n
104
+ }>()
105
+ expectTypeOf(authorization_signed).toExtend<
106
+ AuthorizationTempo.AuthorizationTempo<true>
107
+ >()
108
+ expect(authorization_signed).toMatchInlineSnapshot(
109
+ `
110
+ {
111
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
112
+ "chainId": 1,
113
+ "nonce": 40n,
114
+ "signature": {
115
+ "r": 74666311849961653398815470296948700361392062371901161364182304079113687952627n,
116
+ "s": 24912990662134805731506157958890440652926649106845286943280690489391727501383n,
117
+ "yParity": 1,
118
+ },
119
+ }
120
+ `,
121
+ )
122
+ })
123
+
124
+ test('options: signature (secp256k1)', () => {
125
+ const authorization = AuthorizationTempo.from({
126
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
127
+ chainId: 1,
128
+ nonce: 40n,
129
+ })
130
+ const signature = Secp256k1.sign({
131
+ payload: AuthorizationTempo.getSignPayload(authorization),
132
+ privateKey: testPrivateKey,
133
+ })
134
+ const signatureEnvelope = SignatureEnvelope.from({
135
+ signature,
136
+ type: 'secp256k1',
137
+ })
138
+ const authorization_signed = AuthorizationTempo.from(authorization, {
139
+ signature: signatureEnvelope,
140
+ })
141
+ expectTypeOf(authorization_signed).toExtend<{
142
+ readonly address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c'
143
+ readonly chainId: 1
144
+ readonly nonce: 40n
145
+ }>()
146
+ expectTypeOf(authorization_signed).toExtend<
147
+ AuthorizationTempo.AuthorizationTempo<true>
148
+ >()
149
+ expect(authorization_signed).toMatchInlineSnapshot(
150
+ `
151
+ {
152
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
153
+ "chainId": 1,
154
+ "nonce": 40n,
155
+ "signature": {
156
+ "signature": {
157
+ "r": 74666311849961653398815470296948700361392062371901161364182304079113687952627n,
158
+ "s": 24912990662134805731506157958890440652926649106845286943280690489391727501383n,
159
+ "yParity": 1,
160
+ },
161
+ "type": "secp256k1",
162
+ },
163
+ }
164
+ `,
165
+ )
166
+ })
167
+
168
+ test('options: signature (p256)', () => {
169
+ const authorization = AuthorizationTempo.from({
170
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
171
+ chainId: 1,
172
+ nonce: 40n,
173
+ })
174
+
175
+ const privateKey = P256.randomPrivateKey()
176
+ const publicKey = P256.getPublicKey({ privateKey })
177
+ const payload = AuthorizationTempo.getSignPayload(authorization)
178
+ const signature = P256.sign({ payload, privateKey })
179
+
180
+ const signatureEnvelope: SignatureEnvelope.P256 = {
181
+ prehash: true,
182
+ publicKey,
183
+ signature,
184
+ type: 'p256',
185
+ }
186
+
187
+ const authorization_signed = AuthorizationTempo.from(authorization, {
188
+ signature: signatureEnvelope,
189
+ })
190
+
191
+ expectTypeOf(authorization_signed).toExtend<
192
+ AuthorizationTempo.AuthorizationTempo<true>
193
+ >()
194
+ expect(authorization_signed.signature.type).toBe('p256')
195
+ expect(authorization_signed.signature.prehash).toBe(true)
196
+ expect(authorization_signed.signature.publicKey).toEqual(publicKey)
197
+ })
198
+
199
+ test('options: signature (webAuthn)', () => {
200
+ const authorization = AuthorizationTempo.from({
201
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
202
+ chainId: 1,
203
+ nonce: 40n,
204
+ })
205
+
206
+ const signatureEnvelope = SignatureEnvelope.from({
207
+ metadata: {
208
+ authenticatorData:
209
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000',
210
+ clientDataJSON:
211
+ '{"type":"webauthn.get","challenge":"","origin":"https://example.com","crossOrigin":false}',
212
+ },
213
+ publicKey: { prefix: 4, x: 1n, y: 2n },
214
+ signature: { r: 3n, s: 4n },
215
+ type: 'webAuthn',
216
+ })
217
+
218
+ const authorization_signed = AuthorizationTempo.from(authorization, {
219
+ signature: signatureEnvelope,
220
+ })
221
+
222
+ expectTypeOf(authorization_signed).toExtend<
223
+ AuthorizationTempo.AuthorizationTempo<true>
224
+ >()
225
+ expect(authorization_signed.signature.type).toBe('webAuthn')
226
+ expect(authorization_signed.signature.metadata).toBeDefined()
227
+ expect(authorization_signed.signature.publicKey).toEqual(
228
+ signatureEnvelope.publicKey,
229
+ )
230
+ })
231
+
232
+ test('behavior: rpc', () => {
233
+ {
234
+ const authorization = AuthorizationTempo.from({
235
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
236
+ chainId: '0x1',
237
+ nonce: '0x1',
238
+ signature: {
239
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
240
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
241
+ yParity: '0x0',
242
+ type: 'secp256k1',
243
+ },
244
+ })
245
+ expectTypeOf(
246
+ authorization,
247
+ ).toExtend<AuthorizationTempo.AuthorizationTempo>()
248
+ expect(authorization).toMatchInlineSnapshot(
249
+ `
250
+ {
251
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
252
+ "chainId": 1,
253
+ "nonce": 1n,
254
+ "signature": {
255
+ "signature": {
256
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
257
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
258
+ "yParity": 0,
259
+ },
260
+ "type": "secp256k1",
261
+ },
262
+ }
263
+ `,
264
+ )
265
+ }
266
+ })
267
+ })
268
+
269
+ describe('fromRpc', () => {
270
+ test('secp256k1', () => {
271
+ expect(
272
+ AuthorizationTempo.fromRpc({
273
+ address: '0x0000000000000000000000000000000000000000',
274
+ chainId: '0x1',
275
+ nonce: '0x1',
276
+ signature: {
277
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
278
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
279
+ yParity: '0x0',
280
+ type: 'secp256k1',
281
+ },
282
+ }),
283
+ ).toMatchInlineSnapshot(`
284
+ {
285
+ "address": "0x0000000000000000000000000000000000000000",
286
+ "chainId": 1,
287
+ "nonce": 1n,
288
+ "signature": {
289
+ "signature": {
290
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
291
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
292
+ "yParity": 0,
293
+ },
294
+ "type": "secp256k1",
295
+ },
296
+ }
297
+ `)
298
+ })
299
+
300
+ test('p256', () => {
301
+ const result = AuthorizationTempo.fromRpc({
302
+ address: '0x0000000000000000000000000000000000000000',
303
+ chainId: '0x1',
304
+ nonce: '0x1',
305
+ signature: {
306
+ prehash: true,
307
+ pubKeyX:
308
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
309
+ pubKeyY:
310
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
311
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
312
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
313
+ type: 'p256',
314
+ },
315
+ })
316
+ expect(result.signature.type).toBe('p256')
317
+ expect(result.signature).toHaveProperty('prehash', true)
318
+ expect(result.signature).toHaveProperty('publicKey')
319
+ })
320
+
321
+ test('webAuthn', () => {
322
+ const result = AuthorizationTempo.fromRpc({
323
+ address: '0x0000000000000000000000000000000000000000',
324
+ chainId: '0x1',
325
+ nonce: '0x1',
326
+ signature: {
327
+ pubKeyX:
328
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
329
+ pubKeyY:
330
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
331
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
332
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
333
+ type: 'webAuthn',
334
+ webauthnData:
335
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22222c226f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c2263726f73734f726967696e223a66616c73657d',
336
+ },
337
+ })
338
+ expect(result.signature.type).toBe('webAuthn')
339
+ expect(result.signature).toHaveProperty('metadata')
340
+ expect(result.signature).toHaveProperty('publicKey')
341
+ })
342
+ })
343
+
344
+ describe('fromRpcList', () => {
345
+ test('secp256k1', () => {
346
+ expect(
347
+ AuthorizationTempo.fromRpcList([
348
+ {
349
+ address: '0x0000000000000000000000000000000000000000',
350
+ chainId: '0x1',
351
+ nonce: '0x1',
352
+ signature: {
353
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
354
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
355
+ yParity: '0x0',
356
+ type: 'secp256k1',
357
+ },
358
+ },
359
+ {
360
+ address: '0x0000000000000000000000000000000000000000',
361
+ chainId: '0x1',
362
+ nonce: '0x1',
363
+ signature: {
364
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
365
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
366
+ yParity: '0x0',
367
+ type: 'secp256k1',
368
+ },
369
+ },
370
+ ]),
371
+ ).toMatchInlineSnapshot(`
372
+ [
373
+ {
374
+ "address": "0x0000000000000000000000000000000000000000",
375
+ "chainId": 1,
376
+ "nonce": 1n,
377
+ "signature": {
378
+ "signature": {
379
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
380
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
381
+ "yParity": 0,
382
+ },
383
+ "type": "secp256k1",
384
+ },
385
+ },
386
+ {
387
+ "address": "0x0000000000000000000000000000000000000000",
388
+ "chainId": 1,
389
+ "nonce": 1n,
390
+ "signature": {
391
+ "signature": {
392
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
393
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
394
+ "yParity": 0,
395
+ },
396
+ "type": "secp256k1",
397
+ },
398
+ },
399
+ ]
400
+ `)
401
+ })
402
+
403
+ test('p256', () => {
404
+ expect(
405
+ AuthorizationTempo.fromRpcList([
406
+ {
407
+ address: '0x0000000000000000000000000000000000000000',
408
+ chainId: '0x1',
409
+ nonce: '0x1',
410
+ signature: {
411
+ prehash: true,
412
+ pubKeyX:
413
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
414
+ pubKeyY:
415
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
416
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
417
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
418
+ type: 'p256',
419
+ },
420
+ },
421
+ {
422
+ address: '0x0000000000000000000000000000000000000001',
423
+ chainId: '0x2',
424
+ nonce: '0x2',
425
+ signature: {
426
+ prehash: false,
427
+ pubKeyX:
428
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
429
+ pubKeyY:
430
+ '0x0000000000000000000000000000000000000000000000000000000000000004',
431
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
432
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
433
+ type: 'p256',
434
+ },
435
+ },
436
+ ]),
437
+ ).toMatchInlineSnapshot(`
438
+ [
439
+ {
440
+ "address": "0x0000000000000000000000000000000000000000",
441
+ "chainId": 1,
442
+ "nonce": 1n,
443
+ "signature": {
444
+ "prehash": true,
445
+ "publicKey": {
446
+ "prefix": 4,
447
+ "x": 1n,
448
+ "y": 2n,
449
+ },
450
+ "signature": {
451
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
452
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
453
+ },
454
+ "type": "p256",
455
+ },
456
+ },
457
+ {
458
+ "address": "0x0000000000000000000000000000000000000001",
459
+ "chainId": 2,
460
+ "nonce": 2n,
461
+ "signature": {
462
+ "prehash": false,
463
+ "publicKey": {
464
+ "prefix": 4,
465
+ "x": 3n,
466
+ "y": 4n,
467
+ },
468
+ "signature": {
469
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
470
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
471
+ },
472
+ "type": "p256",
473
+ },
474
+ },
475
+ ]
476
+ `)
477
+ })
478
+
479
+ test('webAuthn', () => {
480
+ expect(
481
+ AuthorizationTempo.fromRpcList([
482
+ {
483
+ address: '0x0000000000000000000000000000000000000000',
484
+ chainId: '0x1',
485
+ nonce: '0x1',
486
+ signature: {
487
+ pubKeyX:
488
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
489
+ pubKeyY:
490
+ '0x0000000000000000000000000000000000000000000000000000000000000002',
491
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
492
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
493
+ type: 'webAuthn',
494
+ webauthnData:
495
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22222c226f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c2263726f73734f726967696e223a66616c73657d',
496
+ },
497
+ },
498
+ {
499
+ address: '0x0000000000000000000000000000000000000001',
500
+ chainId: '0x2',
501
+ nonce: '0x2',
502
+ signature: {
503
+ pubKeyX:
504
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
505
+ pubKeyY:
506
+ '0x0000000000000000000000000000000000000000000000000000000000000004',
507
+ r: '0x1',
508
+ s: '0x2',
509
+ type: 'webAuthn',
510
+ webauthnData:
511
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22222c226f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c2263726f73734f726967696e223a66616c73657d',
512
+ },
513
+ },
514
+ ]),
515
+ ).toMatchInlineSnapshot(`
516
+ [
517
+ {
518
+ "address": "0x0000000000000000000000000000000000000000",
519
+ "chainId": 1,
520
+ "nonce": 1n,
521
+ "signature": {
522
+ "metadata": {
523
+ "authenticatorData": "0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000",
524
+ "clientDataJSON": "{"type":"webauthn.get","challenge":"","origin":"https://example.com","crossOrigin":false}",
525
+ },
526
+ "publicKey": {
527
+ "prefix": 4,
528
+ "x": 1n,
529
+ "y": 2n,
530
+ },
531
+ "signature": {
532
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
533
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
534
+ },
535
+ "type": "webAuthn",
536
+ },
537
+ },
538
+ {
539
+ "address": "0x0000000000000000000000000000000000000001",
540
+ "chainId": 2,
541
+ "nonce": 2n,
542
+ "signature": {
543
+ "metadata": {
544
+ "authenticatorData": "0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000",
545
+ "clientDataJSON": "{"type":"webauthn.get","challenge":"","origin":"https://example.com","crossOrigin":false}",
546
+ },
547
+ "publicKey": {
548
+ "prefix": 4,
549
+ "x": 3n,
550
+ "y": 4n,
551
+ },
552
+ "signature": {
553
+ "r": 1n,
554
+ "s": 2n,
555
+ },
556
+ "type": "webAuthn",
557
+ },
558
+ },
559
+ ]
560
+ `)
561
+ })
562
+
563
+ test('mixed signature types', () => {
564
+ expect(
565
+ AuthorizationTempo.fromRpcList([
566
+ {
567
+ address: '0x0000000000000000000000000000000000000000',
568
+ chainId: '0x1',
569
+ nonce: '0x1',
570
+ signature: {
571
+ r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
572
+ s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
573
+ yParity: '0x0',
574
+ type: 'secp256k1',
575
+ },
576
+ },
577
+ {
578
+ address: '0x0000000000000000000000000000000000000001',
579
+ chainId: '0x2',
580
+ nonce: '0x2',
581
+ signature: {
582
+ prehash: true,
583
+ pubKeyX:
584
+ '0x0000000000000000000000000000000000000000000000000000000000000003',
585
+ pubKeyY:
586
+ '0x0000000000000000000000000000000000000000000000000000000000000004',
587
+ r: '0x1',
588
+ s: '0x2',
589
+ type: 'p256',
590
+ },
591
+ },
592
+ {
593
+ address: '0x0000000000000000000000000000000000000002',
594
+ chainId: '0x3',
595
+ nonce: '0x3',
596
+ signature: {
597
+ pubKeyX:
598
+ '0x0000000000000000000000000000000000000000000000000000000000000005',
599
+ pubKeyY:
600
+ '0x0000000000000000000000000000000000000000000000000000000000000006',
601
+ r: '0x3',
602
+ s: '0x4',
603
+ type: 'webAuthn',
604
+ webauthnData:
605
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000007b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22222c226f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c2263726f73734f726967696e223a66616c73657d',
606
+ },
607
+ },
608
+ ]),
609
+ ).toMatchInlineSnapshot(`
610
+ [
611
+ {
612
+ "address": "0x0000000000000000000000000000000000000000",
613
+ "chainId": 1,
614
+ "nonce": 1n,
615
+ "signature": {
616
+ "signature": {
617
+ "r": 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
618
+ "s": 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
619
+ "yParity": 0,
620
+ },
621
+ "type": "secp256k1",
622
+ },
623
+ },
624
+ {
625
+ "address": "0x0000000000000000000000000000000000000001",
626
+ "chainId": 2,
627
+ "nonce": 2n,
628
+ "signature": {
629
+ "prehash": true,
630
+ "publicKey": {
631
+ "prefix": 4,
632
+ "x": 3n,
633
+ "y": 4n,
634
+ },
635
+ "signature": {
636
+ "r": 1n,
637
+ "s": 2n,
638
+ },
639
+ "type": "p256",
640
+ },
641
+ },
642
+ {
643
+ "address": "0x0000000000000000000000000000000000000002",
644
+ "chainId": 3,
645
+ "nonce": 3n,
646
+ "signature": {
647
+ "metadata": {
648
+ "authenticatorData": "0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000",
649
+ "clientDataJSON": "{"type":"webauthn.get","challenge":"","origin":"https://example.com","crossOrigin":false}",
650
+ },
651
+ "publicKey": {
652
+ "prefix": 4,
653
+ "x": 5n,
654
+ "y": 6n,
655
+ },
656
+ "signature": {
657
+ "r": 3n,
658
+ "s": 4n,
659
+ },
660
+ "type": "webAuthn",
661
+ },
662
+ },
663
+ ]
664
+ `)
665
+ })
666
+ })
667
+
668
+ describe('fromTuple', () => {
669
+ test('default', () => {
670
+ const tuple = [
671
+ '0x1',
672
+ '0x0000000000000000000000000000000000000000',
673
+ '0x3',
674
+ ] as const satisfies AuthorizationTempo.Tuple
675
+ const authorization = AuthorizationTempo.fromTuple(tuple)
676
+ expect(authorization).toMatchInlineSnapshot(`
677
+ {
678
+ "address": "0x0000000000000000000000000000000000000000",
679
+ "chainId": 1,
680
+ "nonce": 3n,
681
+ }
682
+ `)
683
+ })
684
+
685
+ test('behavior: zeroish nonce + chainId', () => {
686
+ const tuple = [
687
+ '0x',
688
+ '0x0000000000000000000000000000000000000000',
689
+ '0x',
690
+ ] as const satisfies AuthorizationTempo.Tuple
691
+ const authorization = AuthorizationTempo.fromTuple(tuple)
692
+ expect(authorization).toMatchInlineSnapshot(`
693
+ {
694
+ "address": "0x0000000000000000000000000000000000000000",
695
+ "chainId": 0,
696
+ "nonce": 0n,
697
+ }
698
+ `)
699
+ })
700
+
701
+ test('behavior: signature (secp256k1)', () => {
702
+ const signatureEnvelope = SignatureEnvelope.from({
703
+ signature: { r: 1n, s: 2n, yParity: 0 },
704
+ type: 'secp256k1',
705
+ })
706
+ const serialized = SignatureEnvelope.serialize(signatureEnvelope)
707
+
708
+ const tuple = [
709
+ '0x1',
710
+ '0x0000000000000000000000000000000000000000',
711
+ '0x3',
712
+ serialized,
713
+ ] as const satisfies AuthorizationTempo.Tuple
714
+ const authorization = AuthorizationTempo.fromTuple(tuple)
715
+ expect(authorization).toMatchInlineSnapshot(`
716
+ {
717
+ "address": "0x0000000000000000000000000000000000000000",
718
+ "chainId": 1,
719
+ "nonce": 3n,
720
+ "signature": {
721
+ "signature": {
722
+ "r": 1n,
723
+ "s": 2n,
724
+ "yParity": 0,
725
+ },
726
+ "type": "secp256k1",
727
+ },
728
+ }
729
+ `)
730
+ })
731
+
732
+ test('behavior: signature (p256)', () => {
733
+ const signatureEnvelope = SignatureEnvelope.from({
734
+ prehash: true,
735
+ publicKey: { prefix: 4, x: 1n, y: 2n },
736
+ signature: { r: 3n, s: 4n },
737
+ type: 'p256',
738
+ })
739
+ const serialized = SignatureEnvelope.serialize(signatureEnvelope)
740
+
741
+ const tuple = [
742
+ '0x1',
743
+ '0x0000000000000000000000000000000000000000',
744
+ '0x3',
745
+ serialized,
746
+ ] as const satisfies AuthorizationTempo.Tuple
747
+ const authorization = AuthorizationTempo.fromTuple(tuple)
748
+ expect(authorization.signature?.type).toBe('p256')
749
+ })
750
+ })
751
+
752
+ describe('fromTupleList', () => {
753
+ test('default', () => {
754
+ const tupleList = [
755
+ ['0x01', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x28'],
756
+ ['0x03', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x14'],
757
+ ] as const satisfies AuthorizationTempo.TupleList
758
+ const authorization = AuthorizationTempo.fromTupleList(tupleList)
759
+ expect(authorization).toMatchInlineSnapshot(`
760
+ [
761
+ {
762
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
763
+ "chainId": 1,
764
+ "nonce": 40n,
765
+ },
766
+ {
767
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
768
+ "chainId": 3,
769
+ "nonce": 20n,
770
+ },
771
+ ]
772
+ `)
773
+ })
774
+
775
+ test('behavior: signature', () => {
776
+ const signatureEnvelope1 = SignatureEnvelope.from({
777
+ signature: { r: 1n, s: 2n, yParity: 0 },
778
+ type: 'secp256k1',
779
+ })
780
+ const signatureEnvelope2 = SignatureEnvelope.from({
781
+ signature: { r: 4n, s: 5n, yParity: 0 },
782
+ type: 'secp256k1',
783
+ })
784
+
785
+ const authorization = AuthorizationTempo.fromTupleList([
786
+ [
787
+ '0x05',
788
+ '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
789
+ '0x2a',
790
+ SignatureEnvelope.serialize(signatureEnvelope1),
791
+ ],
792
+ [
793
+ '0x02',
794
+ '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
795
+ '0x2b',
796
+ SignatureEnvelope.serialize(signatureEnvelope2),
797
+ ],
798
+ ])
799
+ expect(authorization).toMatchInlineSnapshot(`
800
+ [
801
+ {
802
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
803
+ "chainId": 5,
804
+ "nonce": 42n,
805
+ "signature": {
806
+ "signature": {
807
+ "r": 1n,
808
+ "s": 2n,
809
+ "yParity": 0,
810
+ },
811
+ "type": "secp256k1",
812
+ },
813
+ },
814
+ {
815
+ "address": "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
816
+ "chainId": 2,
817
+ "nonce": 43n,
818
+ "signature": {
819
+ "signature": {
820
+ "r": 4n,
821
+ "s": 5n,
822
+ "yParity": 0,
823
+ },
824
+ "type": "secp256k1",
825
+ },
826
+ },
827
+ ]
828
+ `)
829
+ })
830
+ })
831
+
832
+ describe('getSignPayload', () => {
833
+ test('default', () => {
834
+ expect(
835
+ AuthorizationTempo.getSignPayload({
836
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
837
+ chainId: 1,
838
+ nonce: 40n,
839
+ }),
840
+ ).toMatchInlineSnapshot(
841
+ `"0x5919da563810a99caf657d42bd10905adbd28b3b89b8a4577efa471e5e4b3914"`,
842
+ )
843
+
844
+ expect(
845
+ AuthorizationTempo.getSignPayload({
846
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
847
+ chainId: 69,
848
+ nonce: 420n,
849
+ }),
850
+ ).toMatchInlineSnapshot(
851
+ `"0x7bdd120f6437316be99b11232d472bb0209d20d7c564f4dfbad855189e830b15"`,
852
+ )
853
+ })
854
+ })
855
+
856
+ describe('hash', () => {
857
+ test('default', () => {
858
+ expect(
859
+ AuthorizationTempo.hash({
860
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
861
+ chainId: 1,
862
+ nonce: 40n,
863
+ }),
864
+ ).toMatchInlineSnapshot(
865
+ `"0x5919da563810a99caf657d42bd10905adbd28b3b89b8a4577efa471e5e4b3914"`,
866
+ )
867
+
868
+ expect(
869
+ AuthorizationTempo.hash({
870
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
871
+ chainId: 69,
872
+ nonce: 420n,
873
+ }),
874
+ ).toMatchInlineSnapshot(
875
+ `"0x7bdd120f6437316be99b11232d472bb0209d20d7c564f4dfbad855189e830b15"`,
876
+ )
877
+ })
878
+
879
+ test('options: presign equals getSignPayload', () => {
880
+ const authorization = {
881
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
882
+ chainId: 1,
883
+ nonce: 40n,
884
+ } as const
885
+ const payload = AuthorizationTempo.getSignPayload(authorization)
886
+ const hash_presign = AuthorizationTempo.hash(authorization, {
887
+ presign: true,
888
+ })
889
+ expect(hash_presign).toEqual(payload)
890
+ })
891
+ })
892
+
893
+ describe('toRpc', () => {
894
+ test('secp256k1', () => {
895
+ expect(
896
+ AuthorizationTempo.toRpc({
897
+ address: '0x0000000000000000000000000000000000000000',
898
+ chainId: 1,
899
+ nonce: 1n,
900
+ signature: {
901
+ signature: {
902
+ r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
903
+ s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
904
+ yParity: 0,
905
+ },
906
+ type: 'secp256k1',
907
+ },
908
+ }),
909
+ ).toMatchInlineSnapshot(`
910
+ {
911
+ "address": "0x0000000000000000000000000000000000000000",
912
+ "chainId": "0x1",
913
+ "nonce": "0x1",
914
+ "signature": {
915
+ "r": "0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d",
916
+ "s": "0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540",
917
+ "type": "secp256k1",
918
+ "yParity": "0x0",
919
+ },
920
+ }
921
+ `)
922
+ })
923
+
924
+ test('p256', () => {
925
+ const result = AuthorizationTempo.toRpc({
926
+ address: '0x0000000000000000000000000000000000000000',
927
+ chainId: 1,
928
+ nonce: 1n,
929
+ signature: {
930
+ prehash: true,
931
+ publicKey: { prefix: 4, x: 1n, y: 2n },
932
+ signature: {
933
+ r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
934
+ s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
935
+ },
936
+ type: 'p256',
937
+ },
938
+ })
939
+ expect(result.signature.type).toBe('p256')
940
+ })
941
+
942
+ test('webAuthn', () => {
943
+ const result = AuthorizationTempo.toRpc({
944
+ address: '0x0000000000000000000000000000000000000000',
945
+ chainId: 1,
946
+ nonce: 1n,
947
+ signature: {
948
+ metadata: {
949
+ authenticatorData: '0x1234',
950
+ clientDataJSON: '0x5678',
951
+ },
952
+ publicKey: { prefix: 4, x: 1n, y: 2n },
953
+ signature: {
954
+ r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
955
+ s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
956
+ },
957
+ type: 'webAuthn',
958
+ },
959
+ })
960
+ expect(result.signature.type).toBe('webAuthn')
961
+ })
962
+ })
963
+
964
+ describe('toRpcList', () => {
965
+ test('default', () => {
966
+ expect(
967
+ AuthorizationTempo.toRpcList([
968
+ {
969
+ address: '0x0000000000000000000000000000000000000000',
970
+ chainId: 1,
971
+ nonce: 1n,
972
+ signature: {
973
+ signature: {
974
+ r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
975
+ s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
976
+ yParity: 0,
977
+ },
978
+ type: 'secp256k1',
979
+ },
980
+ },
981
+ ]),
982
+ ).toMatchInlineSnapshot(`
983
+ [
984
+ {
985
+ "address": "0x0000000000000000000000000000000000000000",
986
+ "chainId": "0x1",
987
+ "nonce": "0x1",
988
+ "signature": {
989
+ "r": "0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d",
990
+ "s": "0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540",
991
+ "type": "secp256k1",
992
+ "yParity": "0x0",
993
+ },
994
+ },
995
+ ]
996
+ `)
997
+ })
998
+ })
999
+
1000
+ describe('toTuple', () => {
1001
+ test('default', () => {
1002
+ {
1003
+ const authorization = AuthorizationTempo.from({
1004
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1005
+ chainId: 1,
1006
+ nonce: 40n,
1007
+ })
1008
+ const tuple = AuthorizationTempo.toTuple(authorization)
1009
+ expect(tuple).toMatchInlineSnapshot(`
1010
+ [
1011
+ "0x1",
1012
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1013
+ "0x28",
1014
+ ]
1015
+ `)
1016
+ }
1017
+
1018
+ {
1019
+ const signatureEnvelope: SignatureEnvelope.Secp256k1 = {
1020
+ signature: { r: 1n, s: 2n, yParity: 0 },
1021
+ type: 'secp256k1',
1022
+ }
1023
+ const authorization = AuthorizationTempo.from({
1024
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1025
+ chainId: 1,
1026
+ nonce: 40n,
1027
+ signature: signatureEnvelope,
1028
+ })
1029
+ const tuple = AuthorizationTempo.toTuple(authorization)
1030
+ expect(tuple).toMatchInlineSnapshot(`
1031
+ [
1032
+ "0x1",
1033
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1034
+ "0x28",
1035
+ "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021b",
1036
+ ]
1037
+ `)
1038
+ }
1039
+
1040
+ {
1041
+ const authorization = AuthorizationTempo.from({
1042
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1043
+ chainId: 0,
1044
+ nonce: 0n,
1045
+ })
1046
+ const tuple = AuthorizationTempo.toTuple(authorization)
1047
+ expect(tuple).toMatchInlineSnapshot(`
1048
+ [
1049
+ "0x",
1050
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1051
+ "0x",
1052
+ ]
1053
+ `)
1054
+ }
1055
+ })
1056
+ })
1057
+
1058
+ describe('toTupleList', () => {
1059
+ test('default', () => {
1060
+ {
1061
+ const tuple = AuthorizationTempo.toTupleList([])
1062
+ expect(tuple).toMatchInlineSnapshot('[]')
1063
+ }
1064
+
1065
+ {
1066
+ const authorization_1 = AuthorizationTempo.from({
1067
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1068
+ chainId: 1,
1069
+ nonce: 40n,
1070
+ })
1071
+ const authorization_2 = AuthorizationTempo.from({
1072
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1073
+ chainId: 3,
1074
+ nonce: 20n,
1075
+ })
1076
+ const tuple = AuthorizationTempo.toTupleList([
1077
+ authorization_1,
1078
+ authorization_2,
1079
+ ])
1080
+ expect(tuple).toMatchInlineSnapshot(`
1081
+ [
1082
+ [
1083
+ "0x1",
1084
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1085
+ "0x28",
1086
+ ],
1087
+ [
1088
+ "0x3",
1089
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1090
+ "0x14",
1091
+ ],
1092
+ ]
1093
+ `)
1094
+ }
1095
+
1096
+ {
1097
+ const signatureEnvelope1 = SignatureEnvelope.from({
1098
+ signature: { r: 1n, s: 2n, yParity: 0 },
1099
+ type: 'secp256k1',
1100
+ })
1101
+ const signatureEnvelope2 = SignatureEnvelope.from({
1102
+ signature: { r: 4n, s: 5n, yParity: 0 },
1103
+ type: 'secp256k1',
1104
+ })
1105
+ const authorization_3 = AuthorizationTempo.from({
1106
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1107
+ chainId: 5,
1108
+ nonce: 42n,
1109
+ signature: signatureEnvelope1,
1110
+ })
1111
+ const authorization_4 = AuthorizationTempo.from({
1112
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1113
+ chainId: 2,
1114
+ nonce: 43n,
1115
+ signature: signatureEnvelope2,
1116
+ })
1117
+ const tuple = AuthorizationTempo.toTupleList([
1118
+ authorization_3,
1119
+ authorization_4,
1120
+ ])
1121
+ expect(tuple).toMatchInlineSnapshot(`
1122
+ [
1123
+ [
1124
+ "0x5",
1125
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1126
+ "0x2a",
1127
+ "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021b",
1128
+ ],
1129
+ [
1130
+ "0x2",
1131
+ "0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c",
1132
+ "0x2b",
1133
+ "0x000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000051b",
1134
+ ],
1135
+ ]
1136
+ `)
1137
+ }
1138
+ })
1139
+
1140
+ test('behavior: undefined input returns empty', () => {
1141
+ const tuple = AuthorizationTempo.toTupleList()
1142
+ expect(tuple).toMatchInlineSnapshot('[]')
1143
+ })
1144
+ })
1145
+
1146
+ describe('signature type interoperability', () => {
1147
+ test('secp256k1 signature round trip', () => {
1148
+ const authorization = AuthorizationTempo.from({
1149
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1150
+ chainId: 1,
1151
+ nonce: 40n,
1152
+ })
1153
+
1154
+ const signature = Secp256k1.sign({
1155
+ payload: AuthorizationTempo.getSignPayload(authorization),
1156
+ privateKey: testPrivateKey,
1157
+ })
1158
+ const signatureEnvelope = SignatureEnvelope.from({
1159
+ signature,
1160
+ type: 'secp256k1',
1161
+ })
1162
+
1163
+ const signed = AuthorizationTempo.from(authorization, {
1164
+ signature: signatureEnvelope,
1165
+ })
1166
+ const rpc = AuthorizationTempo.toRpc(signed)
1167
+ const restored = AuthorizationTempo.fromRpc(rpc)
1168
+
1169
+ expect(restored).toEqual(signed)
1170
+ })
1171
+
1172
+ test('p256 signature round trip', () => {
1173
+ const authorization = AuthorizationTempo.from({
1174
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1175
+ chainId: 1,
1176
+ nonce: 40n,
1177
+ })
1178
+
1179
+ const privateKey = P256.randomPrivateKey()
1180
+ const publicKey = P256.getPublicKey({ privateKey })
1181
+ const payload = AuthorizationTempo.getSignPayload(authorization)
1182
+ const signature = P256.sign({ payload, privateKey })
1183
+
1184
+ const signatureEnvelope = SignatureEnvelope.from({
1185
+ prehash: true,
1186
+ publicKey,
1187
+ signature,
1188
+ type: 'p256',
1189
+ })
1190
+
1191
+ const signed = AuthorizationTempo.from(authorization, {
1192
+ signature: signatureEnvelope,
1193
+ })
1194
+ const rpc = AuthorizationTempo.toRpc(signed)
1195
+ const restored = AuthorizationTempo.fromRpc(rpc)
1196
+
1197
+ expect(restored.signature.type).toBe('p256')
1198
+ expect(restored.address).toEqual(signed.address)
1199
+ expect(restored.chainId).toEqual(signed.chainId)
1200
+ expect(restored.nonce).toEqual(signed.nonce)
1201
+ expect(restored.signature.type).toEqual(signed.signature.type)
1202
+ expect(restored.signature.prehash).toEqual(signed.signature.prehash)
1203
+ expect(restored.signature.publicKey).toEqual(signed.signature.publicKey)
1204
+ expect(restored.signature.signature?.r).toEqual(
1205
+ signed.signature.signature?.r,
1206
+ )
1207
+ expect(restored.signature.signature?.s).toEqual(
1208
+ signed.signature.signature?.s,
1209
+ )
1210
+ })
1211
+
1212
+ test('webAuthn signature round trip', () => {
1213
+ const authorization = AuthorizationTempo.from({
1214
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1215
+ chainId: 1,
1216
+ nonce: 40n,
1217
+ })
1218
+
1219
+ const signatureEnvelope = SignatureEnvelope.from({
1220
+ metadata: {
1221
+ authenticatorData:
1222
+ '0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000',
1223
+ clientDataJSON:
1224
+ '{"type":"webauthn.get","challenge":"","origin":"https://example.com","crossOrigin":false}',
1225
+ },
1226
+ publicKey: { prefix: 4, x: 1n, y: 2n },
1227
+ signature: {
1228
+ r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
1229
+ s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
1230
+ },
1231
+ type: 'webAuthn',
1232
+ })
1233
+
1234
+ const signed = AuthorizationTempo.from(authorization, {
1235
+ signature: signatureEnvelope,
1236
+ })
1237
+ const rpc = AuthorizationTempo.toRpc(signed)
1238
+ const restored = AuthorizationTempo.fromRpc(rpc)
1239
+
1240
+ expect(restored.signature.type).toBe('webAuthn')
1241
+ expect(restored.address).toEqual(signed.address)
1242
+ expect(restored.chainId).toEqual(signed.chainId)
1243
+ expect(restored.nonce).toEqual(signed.nonce)
1244
+ expect(restored.signature.type).toEqual(signed.signature.type)
1245
+ expect(restored.signature.metadata).toEqual(signed.signature.metadata)
1246
+ expect(restored.signature.publicKey).toEqual(signed.signature.publicKey)
1247
+ expect(restored.signature.signature?.r).toEqual(
1248
+ signed.signature.signature?.r,
1249
+ )
1250
+ expect(restored.signature.signature?.s).toEqual(
1251
+ signed.signature.signature?.s,
1252
+ )
1253
+ })
1254
+
1255
+ test('tuple serialization preserves signature type', () => {
1256
+ const signatureEnvelope = SignatureEnvelope.from({
1257
+ prehash: true,
1258
+ publicKey: { prefix: 4, x: 1n, y: 2n },
1259
+ signature: { r: 3n, s: 4n },
1260
+ type: 'p256',
1261
+ })
1262
+
1263
+ const authorization = AuthorizationTempo.from({
1264
+ address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
1265
+ chainId: 1,
1266
+ nonce: 40n,
1267
+ signature: signatureEnvelope,
1268
+ })
1269
+
1270
+ const tuple = AuthorizationTempo.toTuple(authorization)
1271
+ const restored = AuthorizationTempo.fromTuple(tuple)
1272
+
1273
+ expect(restored.signature?.type).toBe('p256')
1274
+ })
1275
+ })
1276
+
1277
+ test('exports', () => {
1278
+ expect(Object.keys(AuthorizationTempo)).toMatchInlineSnapshot(`
1279
+ [
1280
+ "from",
1281
+ "fromRpc",
1282
+ "fromRpcList",
1283
+ "fromTuple",
1284
+ "fromTupleList",
1285
+ "getSignPayload",
1286
+ "hash",
1287
+ "toRpc",
1288
+ "toRpcList",
1289
+ "toTuple",
1290
+ "toTupleList",
1291
+ ]
1292
+ `)
1293
+ })