tempo.ts 0.10.5 → 0.11.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 (224) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +0 -41
  3. package/dist/viem/Account.d.ts +8 -3
  4. package/dist/viem/Account.d.ts.map +1 -1
  5. package/dist/viem/Account.js +9 -2
  6. package/dist/viem/Account.js.map +1 -1
  7. package/dist/viem/Actions/amm.d.ts +1 -1
  8. package/dist/viem/Actions/amm.d.ts.map +1 -1
  9. package/dist/viem/Actions/amm.js +1 -2
  10. package/dist/viem/Actions/amm.js.map +1 -1
  11. package/dist/viem/Actions/dex.d.ts +0 -35
  12. package/dist/viem/Actions/dex.d.ts.map +1 -1
  13. package/dist/viem/Actions/dex.js +0 -43
  14. package/dist/viem/Actions/dex.js.map +1 -1
  15. package/dist/viem/Actions/fee.d.ts +1 -1
  16. package/dist/viem/Actions/fee.d.ts.map +1 -1
  17. package/dist/viem/Actions/fee.js +1 -1
  18. package/dist/viem/Actions/fee.js.map +1 -1
  19. package/dist/viem/Actions/nonce.d.ts.map +1 -1
  20. package/dist/viem/Actions/nonce.js +6 -4
  21. package/dist/viem/Actions/nonce.js.map +1 -1
  22. package/dist/viem/Actions/token.d.ts +1 -2
  23. package/dist/viem/Actions/token.d.ts.map +1 -1
  24. package/dist/viem/Actions/token.js +1 -2
  25. package/dist/viem/Actions/token.js.map +1 -1
  26. package/dist/viem/Chain.d.ts +34 -34
  27. package/dist/viem/Chain.d.ts.map +1 -1
  28. package/dist/viem/Chain.js +2 -0
  29. package/dist/viem/Chain.js.map +1 -1
  30. package/dist/viem/Formatters.d.ts.map +1 -1
  31. package/dist/viem/Formatters.js +5 -3
  32. package/dist/viem/Formatters.js.map +1 -1
  33. package/dist/viem/Transaction.d.ts +8 -5
  34. package/dist/viem/Transaction.d.ts.map +1 -1
  35. package/dist/viem/Transaction.js +13 -3
  36. package/dist/viem/Transaction.js.map +1 -1
  37. package/dist/viem/internal/types.d.ts +1 -1
  38. package/dist/viem/internal/types.d.ts.map +1 -1
  39. package/dist/wagmi/Actions/dex.d.ts +1 -45
  40. package/dist/wagmi/Actions/dex.d.ts.map +1 -1
  41. package/dist/wagmi/Actions/dex.js +0 -55
  42. package/dist/wagmi/Actions/dex.js.map +1 -1
  43. package/dist/wagmi/Connector.d.ts +1 -1
  44. package/dist/wagmi/Connector.d.ts.map +1 -1
  45. package/dist/wagmi/Connector.js +1 -2
  46. package/dist/wagmi/Connector.js.map +1 -1
  47. package/dist/wagmi/Hooks/dex.d.ts +3 -46
  48. package/dist/wagmi/Hooks/dex.d.ts.map +1 -1
  49. package/dist/wagmi/Hooks/dex.js +2 -54
  50. package/dist/wagmi/Hooks/dex.js.map +1 -1
  51. package/dist/wagmi/index.d.ts +1 -1
  52. package/dist/wagmi/index.d.ts.map +1 -1
  53. package/dist/wagmi/index.js +1 -1
  54. package/dist/wagmi/index.js.map +1 -1
  55. package/package.json +5 -23
  56. package/src/viem/Account.test.ts +1 -1
  57. package/src/viem/Account.ts +11 -2
  58. package/src/viem/Actions/account.ts +1 -1
  59. package/src/viem/Actions/amm.ts +1 -2
  60. package/src/viem/Actions/dex.test.ts +1 -195
  61. package/src/viem/Actions/dex.ts +0 -53
  62. package/src/viem/Actions/fee.test.ts +2 -2
  63. package/src/viem/Actions/fee.ts +1 -1
  64. package/src/viem/Actions/nonce.test.ts +27 -14
  65. package/src/viem/Actions/nonce.ts +6 -4
  66. package/src/viem/Actions/token.test.ts +18 -52
  67. package/src/viem/Actions/token.ts +1 -2
  68. package/src/viem/Chain.ts +3 -1
  69. package/src/viem/Decorator.ts +0 -30
  70. package/src/viem/Formatters.ts +9 -3
  71. package/src/viem/Transaction.ts +23 -7
  72. package/src/viem/e2e.test.ts +19 -0
  73. package/src/viem/index.ts +12 -1
  74. package/src/viem/internal/types.ts +1 -1
  75. package/src/wagmi/Actions/dex.test.ts +0 -26
  76. package/src/wagmi/Actions/dex.ts +1 -111
  77. package/src/wagmi/Actions/nonce.test.ts +8 -4
  78. package/src/wagmi/Actions/token.test.ts +2 -2
  79. package/src/wagmi/Connector.ts +1 -2
  80. package/src/wagmi/Hooks/dex.test.ts +0 -26
  81. package/src/wagmi/Hooks/dex.ts +1 -88
  82. package/src/wagmi/Hooks/nonce.test.ts +3 -3
  83. package/src/wagmi/index.ts +4 -1
  84. package/dist/chains.d.ts +0 -73
  85. package/dist/chains.d.ts.map +0 -1
  86. package/dist/chains.js +0 -51
  87. package/dist/chains.js.map +0 -1
  88. package/dist/ox/AuthorizationTempo.d.ts +0 -450
  89. package/dist/ox/AuthorizationTempo.d.ts.map +0 -1
  90. package/dist/ox/AuthorizationTempo.js +0 -433
  91. package/dist/ox/AuthorizationTempo.js.map +0 -1
  92. package/dist/ox/KeyAuthorization.d.ts +0 -356
  93. package/dist/ox/KeyAuthorization.d.ts.map +0 -1
  94. package/dist/ox/KeyAuthorization.js +0 -359
  95. package/dist/ox/KeyAuthorization.js.map +0 -1
  96. package/dist/ox/Order.d.ts +0 -92
  97. package/dist/ox/Order.d.ts.map +0 -1
  98. package/dist/ox/Order.js +0 -88
  99. package/dist/ox/Order.js.map +0 -1
  100. package/dist/ox/OrdersFilters.d.ts +0 -72
  101. package/dist/ox/OrdersFilters.d.ts.map +0 -1
  102. package/dist/ox/OrdersFilters.js +0 -100
  103. package/dist/ox/OrdersFilters.js.map +0 -1
  104. package/dist/ox/Pagination.d.ts +0 -128
  105. package/dist/ox/Pagination.d.ts.map +0 -1
  106. package/dist/ox/Pagination.js +0 -78
  107. package/dist/ox/Pagination.js.map +0 -1
  108. package/dist/ox/PoolId.d.ts +0 -18
  109. package/dist/ox/PoolId.d.ts.map +0 -1
  110. package/dist/ox/PoolId.js +0 -13
  111. package/dist/ox/PoolId.js.map +0 -1
  112. package/dist/ox/RpcSchema.d.ts +0 -32
  113. package/dist/ox/RpcSchema.d.ts.map +0 -1
  114. package/dist/ox/RpcSchema.js +0 -2
  115. package/dist/ox/RpcSchema.js.map +0 -1
  116. package/dist/ox/SignatureEnvelope.d.ts +0 -260
  117. package/dist/ox/SignatureEnvelope.d.ts.map +0 -1
  118. package/dist/ox/SignatureEnvelope.js +0 -477
  119. package/dist/ox/SignatureEnvelope.js.map +0 -1
  120. package/dist/ox/Tick.d.ts +0 -115
  121. package/dist/ox/Tick.d.ts.map +0 -1
  122. package/dist/ox/Tick.js +0 -127
  123. package/dist/ox/Tick.js.map +0 -1
  124. package/dist/ox/TokenId.d.ts +0 -25
  125. package/dist/ox/TokenId.d.ts.map +0 -1
  126. package/dist/ox/TokenId.js +0 -41
  127. package/dist/ox/TokenId.js.map +0 -1
  128. package/dist/ox/TokenRole.d.ts +0 -11
  129. package/dist/ox/TokenRole.d.ts.map +0 -1
  130. package/dist/ox/TokenRole.js +0 -22
  131. package/dist/ox/TokenRole.js.map +0 -1
  132. package/dist/ox/Transaction.d.ts +0 -201
  133. package/dist/ox/Transaction.d.ts.map +0 -1
  134. package/dist/ox/Transaction.js +0 -167
  135. package/dist/ox/Transaction.js.map +0 -1
  136. package/dist/ox/TransactionEnvelopeTempo.d.ts +0 -470
  137. package/dist/ox/TransactionEnvelopeTempo.d.ts.map +0 -1
  138. package/dist/ox/TransactionEnvelopeTempo.js +0 -547
  139. package/dist/ox/TransactionEnvelopeTempo.js.map +0 -1
  140. package/dist/ox/TransactionReceipt.d.ts +0 -155
  141. package/dist/ox/TransactionReceipt.d.ts.map +0 -1
  142. package/dist/ox/TransactionReceipt.js +0 -136
  143. package/dist/ox/TransactionReceipt.js.map +0 -1
  144. package/dist/ox/TransactionRequest.d.ts +0 -76
  145. package/dist/ox/TransactionRequest.d.ts.map +0 -1
  146. package/dist/ox/TransactionRequest.js +0 -93
  147. package/dist/ox/TransactionRequest.js.map +0 -1
  148. package/dist/ox/index.d.ts +0 -14
  149. package/dist/ox/index.d.ts.map +0 -1
  150. package/dist/ox/index.js +0 -14
  151. package/dist/ox/index.js.map +0 -1
  152. package/dist/prool/Instance.d.ts +0 -101
  153. package/dist/prool/Instance.d.ts.map +0 -1
  154. package/dist/prool/Instance.js +0 -136
  155. package/dist/prool/Instance.js.map +0 -1
  156. package/dist/prool/chain.json +0 -238
  157. package/dist/prool/index.d.ts +0 -2
  158. package/dist/prool/index.d.ts.map +0 -1
  159. package/dist/prool/index.js +0 -2
  160. package/dist/prool/index.js.map +0 -1
  161. package/dist/viem/Actions/account.d.ts +0 -40
  162. package/dist/viem/Actions/account.d.ts.map +0 -1
  163. package/dist/viem/Actions/account.js +0 -86
  164. package/dist/viem/Actions/account.js.map +0 -1
  165. package/dist/viem/Actions/index.d.ts +0 -10
  166. package/dist/viem/Actions/index.d.ts.map +0 -1
  167. package/dist/viem/Actions/index.js +0 -10
  168. package/dist/viem/Actions/index.js.map +0 -1
  169. package/dist/viem/Decorator.d.ts +0 -2810
  170. package/dist/viem/Decorator.d.ts.map +0 -1
  171. package/dist/viem/Decorator.js +0 -138
  172. package/dist/viem/Decorator.js.map +0 -1
  173. package/dist/viem/P256.d.ts +0 -2
  174. package/dist/viem/P256.d.ts.map +0 -1
  175. package/dist/viem/P256.js +0 -2
  176. package/dist/viem/P256.js.map +0 -1
  177. package/dist/viem/Secp256k1.d.ts +0 -2
  178. package/dist/viem/Secp256k1.d.ts.map +0 -1
  179. package/dist/viem/Secp256k1.js +0 -2
  180. package/dist/viem/Secp256k1.js.map +0 -1
  181. package/dist/viem/TokenIds.d.ts +0 -2
  182. package/dist/viem/TokenIds.d.ts.map +0 -1
  183. package/dist/viem/TokenIds.js +0 -2
  184. package/dist/viem/TokenIds.js.map +0 -1
  185. package/dist/viem/index.d.ts +0 -17
  186. package/dist/viem/index.d.ts.map +0 -1
  187. package/dist/viem/index.js +0 -17
  188. package/dist/viem/index.js.map +0 -1
  189. package/src/ox/AuthorizationTempo.test.ts +0 -1256
  190. package/src/ox/AuthorizationTempo.ts +0 -648
  191. package/src/ox/KeyAuthorization.test.ts +0 -1332
  192. package/src/ox/KeyAuthorization.ts +0 -540
  193. package/src/ox/Order.test.ts +0 -78
  194. package/src/ox/Order.ts +0 -125
  195. package/src/ox/OrdersFilters.test.ts +0 -182
  196. package/src/ox/OrdersFilters.ts +0 -125
  197. package/src/ox/Pagination.test.ts +0 -162
  198. package/src/ox/Pagination.ts +0 -164
  199. package/src/ox/PoolId.test.ts +0 -33
  200. package/src/ox/PoolId.ts +0 -27
  201. package/src/ox/RpcSchema.ts +0 -35
  202. package/src/ox/SignatureEnvelope.test.ts +0 -1876
  203. package/src/ox/SignatureEnvelope.ts +0 -791
  204. package/src/ox/Tick.test.ts +0 -281
  205. package/src/ox/Tick.ts +0 -181
  206. package/src/ox/TokenId.test.ts +0 -40
  207. package/src/ox/TokenId.ts +0 -50
  208. package/src/ox/TokenRole.test.ts +0 -16
  209. package/src/ox/TokenRole.ts +0 -27
  210. package/src/ox/Transaction.test.ts +0 -523
  211. package/src/ox/Transaction.ts +0 -332
  212. package/src/ox/TransactionEnvelopeTempo.test.ts +0 -1352
  213. package/src/ox/TransactionEnvelopeTempo.ts +0 -905
  214. package/src/ox/TransactionReceipt.ts +0 -190
  215. package/src/ox/TransactionRequest.ts +0 -147
  216. package/src/ox/e2e.test.ts +0 -1393
  217. package/src/ox/index.ts +0 -13
  218. package/src/prool/Instance.test.ts +0 -43
  219. package/src/prool/Instance.ts +0 -247
  220. package/src/prool/chain.json +0 -238
  221. package/src/prool/index.ts +0 -1
  222. package/src/viem/Actions/__snapshots__/dex.test.ts.snap +0 -850
  223. package/src/wagmi/Actions/__snapshots__/dex.test.ts.snap +0 -310
  224. package/src/wagmi/Hooks/__snapshots__/dex.test.ts.snap +0 -457
@@ -1,791 +0,0 @@
1
- import type * as Address from 'ox/Address'
2
- import * as Errors from 'ox/Errors'
3
- import * as Hex from 'ox/Hex'
4
- import * as Json from 'ox/Json'
5
- import type * as PublicKey from 'ox/PublicKey'
6
- import * as Signature from 'ox/Signature'
7
- import type * as WebAuthnP256 from 'ox/WebAuthnP256'
8
- import type {
9
- Assign,
10
- Compute,
11
- IsNarrowable,
12
- OneOf,
13
- PartialBy,
14
- UnionPartialBy,
15
- } from '../internal/types.js'
16
-
17
- /** Signature type identifiers for encoding/decoding */
18
- const serializedP256Type = '0x01'
19
- const serializedWebAuthnType = '0x02'
20
- const serializedKeychainType = '0x03'
21
-
22
- /**
23
- * Statically determines the signature type of an envelope at compile time.
24
- *
25
- * @example
26
- * ```ts twoslash
27
- * import type { SignatureEnvelope } from 'tempo.ts/ox'
28
- *
29
- * type Type = SignatureEnvelope.GetType<{ r: bigint; s: bigint; yParity: number }>
30
- * // @log: 'secp256k1'
31
- * ```
32
- */
33
- export type GetType<
34
- envelope extends PartialBy<SignatureEnvelope, 'type'> | unknown,
35
- > = unknown extends envelope
36
- ? envelope extends unknown
37
- ? Type
38
- : never
39
- : envelope extends { type: infer T extends Type }
40
- ? T
41
- : envelope extends {
42
- signature: { r: bigint; s: bigint }
43
- prehash: boolean
44
- publicKey: PublicKey.PublicKey
45
- }
46
- ? 'p256'
47
- : envelope extends {
48
- signature: { r: bigint; s: bigint }
49
- metadata: any
50
- publicKey: PublicKey.PublicKey
51
- }
52
- ? 'webAuthn'
53
- : envelope extends { r: bigint; s: bigint; yParity: number }
54
- ? 'secp256k1'
55
- : envelope extends {
56
- signature: { r: bigint; s: bigint; yParity: number }
57
- }
58
- ? 'secp256k1'
59
- : envelope extends {
60
- userAddress: Address.Address
61
- }
62
- ? 'keychain'
63
- : never
64
-
65
- /**
66
- * Represents a signature envelope that can contain different signature types.
67
- *
68
- * Supports:
69
- * - secp256k1: Standard ECDSA signature (65 bytes)
70
- * - p256: P256 signature with embedded public key and prehash flag (130 bytes)
71
- * - webAuthn: WebAuthn signature with variable-length authenticator data
72
- */
73
- export type SignatureEnvelope<bigintType = bigint, numberType = number> = OneOf<
74
- | Secp256k1<bigintType, numberType>
75
- | P256<bigintType, numberType>
76
- | WebAuthn<bigintType, numberType>
77
- | Keychain<bigintType, numberType>
78
- >
79
-
80
- /**
81
- * RPC-formatted signature envelope.
82
- */
83
- export type SignatureEnvelopeRpc = OneOf<
84
- Secp256k1Rpc | P256Rpc | WebAuthnRpc | KeychainRpc
85
- >
86
-
87
- export type Keychain<bigintType = bigint, numberType = number> = {
88
- /** Root account address that this transaction is being executed for */
89
- userAddress: Address.Address
90
- /** The actual signature from the access key (can be Secp256k1, P256, or WebAuthn) */
91
- inner: SignatureEnvelope<bigintType, numberType>
92
- type: 'keychain'
93
- }
94
-
95
- export type KeychainRpc = {
96
- type: 'keychain'
97
- userAddress: Address.Address
98
- signature: SignatureEnvelopeRpc
99
- }
100
-
101
- export type P256<bigintType = bigint, numberType = number> = {
102
- prehash: boolean
103
- publicKey: PublicKey.PublicKey
104
- signature: Signature.Signature<false, bigintType, numberType>
105
- type: 'p256'
106
- }
107
-
108
- export type P256Rpc = {
109
- prehash: boolean
110
- pubKeyX: Hex.Hex
111
- pubKeyY: Hex.Hex
112
- r: Hex.Hex
113
- s: Hex.Hex
114
- type: 'p256'
115
- }
116
-
117
- export type Secp256k1<bigintType = bigint, numberType = number> = {
118
- signature: Signature.Signature<true, bigintType, numberType>
119
- type: 'secp256k1'
120
- }
121
-
122
- export type Secp256k1Rpc = Compute<
123
- Signature.Rpc<true> & {
124
- v?: Hex.Hex | undefined
125
- type: 'secp256k1'
126
- }
127
- >
128
-
129
- export type Secp256k1Flat<
130
- bigintType = bigint,
131
- numberType = number,
132
- > = Signature.Signature<true, bigintType, numberType> & {
133
- type?: 'secp256k1' | undefined
134
- }
135
-
136
- export type WebAuthn<bigintType = bigint, numberType = number> = {
137
- metadata: Pick<
138
- WebAuthnP256.SignMetadata,
139
- 'authenticatorData' | 'clientDataJSON'
140
- >
141
- signature: Signature.Signature<false, bigintType, numberType>
142
- publicKey: PublicKey.PublicKey
143
- type: 'webAuthn'
144
- }
145
-
146
- export type WebAuthnRpc = {
147
- pubKeyX: Hex.Hex
148
- pubKeyY: Hex.Hex
149
- r: Hex.Hex
150
- s: Hex.Hex
151
- type: 'webAuthn'
152
- webauthnData: Hex.Hex
153
- }
154
-
155
- /** Hex-encoded serialized signature envelope. */
156
- export type Serialized = Hex.Hex
157
-
158
- /** List of supported signature types. */
159
- export const types = ['secp256k1', 'p256', 'webAuthn'] as const
160
-
161
- /** Union type of supported signature types. */
162
- export type Type = (typeof types)[number]
163
-
164
- /**
165
- * Asserts that a {@link SignatureEnvelope} is valid.
166
- *
167
- * @example
168
- * ```ts twoslash
169
- * import { SignatureEnvelope } from 'tempo.ts/ox'
170
- *
171
- * SignatureEnvelope.assert({
172
- * r: 0n,
173
- * s: 0n,
174
- * yParity: 0,
175
- * type: 'secp256k1',
176
- * })
177
- * ```
178
- *
179
- * @param envelope - The signature envelope to assert.
180
- * @throws {CoercionError} If the envelope type cannot be determined.
181
- */
182
- export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
183
- const type = getType(envelope)
184
-
185
- if (type === 'secp256k1') {
186
- const secp256k1 = envelope as Secp256k1
187
- Signature.assert(secp256k1.signature)
188
- return
189
- }
190
-
191
- if (type === 'p256') {
192
- const p256 = envelope as P256
193
- const missing: string[] = []
194
-
195
- if (typeof p256.signature?.r !== 'bigint') missing.push('signature.r')
196
- if (typeof p256.signature?.s !== 'bigint') missing.push('signature.s')
197
- if (typeof p256.prehash !== 'boolean') missing.push('prehash')
198
- if (!p256.publicKey) missing.push('publicKey')
199
- else {
200
- if (typeof p256.publicKey.x !== 'bigint') missing.push('publicKey.x')
201
- if (typeof p256.publicKey.y !== 'bigint') missing.push('publicKey.y')
202
- }
203
-
204
- if (missing.length > 0)
205
- throw new MissingPropertiesError({ envelope, missing, type: 'p256' })
206
- return
207
- }
208
-
209
- if (type === 'webAuthn') {
210
- const webauthn = envelope as WebAuthn
211
- const missing: string[] = []
212
-
213
- if (typeof webauthn.signature?.r !== 'bigint') missing.push('signature.r')
214
- if (typeof webauthn.signature?.s !== 'bigint') missing.push('signature.s')
215
- if (!webauthn.metadata) missing.push('metadata')
216
- else {
217
- if (!webauthn.metadata.authenticatorData)
218
- missing.push('metadata.authenticatorData')
219
- if (!webauthn.metadata.clientDataJSON)
220
- missing.push('metadata.clientDataJSON')
221
- }
222
- if (!webauthn.publicKey) missing.push('publicKey')
223
- else {
224
- if (typeof webauthn.publicKey.x !== 'bigint') missing.push('publicKey.x')
225
- if (typeof webauthn.publicKey.y !== 'bigint') missing.push('publicKey.y')
226
- }
227
-
228
- if (missing.length > 0)
229
- throw new MissingPropertiesError({ envelope, missing, type: 'webAuthn' })
230
- return
231
- }
232
-
233
- if (type === 'keychain') {
234
- const keychain = envelope as Keychain
235
- assert(keychain.inner)
236
- return
237
- }
238
- }
239
-
240
- export declare namespace assert {
241
- type ErrorType =
242
- | CoercionError
243
- | MissingPropertiesError
244
- | Signature.assert.ErrorType
245
- | Errors.GlobalErrorType
246
- }
247
-
248
- /**
249
- * Deserializes a hex-encoded signature envelope into a typed signature object.
250
- *
251
- * For backward compatibility:
252
- * - 65 bytes: secp256k1 signature (no type identifier)
253
- * - 130 bytes: P256 signature (1 byte type + 129 bytes data)
254
- * - 129+ bytes: WebAuthn signature (1 byte type + variable data)
255
- *
256
- * @param serialized - The hex-encoded signature envelope to deserialize.
257
- * @returns The deserialized signature envelope.
258
- * @throws {CoercionError} If the serialized value cannot be coerced to a valid signature envelope.
259
- */
260
- export function deserialize(serialized: Serialized): SignatureEnvelope {
261
- const size = Hex.size(serialized)
262
-
263
- // Backward compatibility: 65 bytes means secp256k1 without type identifier
264
- if (size === 65) {
265
- const signature = Signature.fromHex(serialized)
266
- Signature.assert(signature)
267
- return { signature, type: 'secp256k1' } satisfies Secp256k1
268
- }
269
-
270
- // For all other lengths, first byte is the type identifier
271
- const typeId = Hex.slice(serialized, 0, 1)
272
- const data = Hex.slice(serialized, 1)
273
- const dataSize = Hex.size(data)
274
-
275
- if (typeId === serializedP256Type) {
276
- // P256: 32 (r) + 32 (s) + 32 (pubKeyX) + 32 (pubKeyY) + 1 (prehash) = 129 bytes
277
- if (dataSize !== 129)
278
- throw new InvalidSerializedError({
279
- reason: `Invalid P256 signature envelope size: expected 129 bytes, got ${dataSize} bytes`,
280
- serialized,
281
- })
282
-
283
- return {
284
- publicKey: {
285
- prefix: 4,
286
- x: Hex.toBigInt(Hex.slice(data, 64, 96)),
287
- y: Hex.toBigInt(Hex.slice(data, 96, 128)),
288
- },
289
- prehash: Hex.toNumber(Hex.slice(data, 128, 129)) !== 0,
290
- signature: {
291
- r: Hex.toBigInt(Hex.slice(data, 0, 32)),
292
- s: Hex.toBigInt(Hex.slice(data, 32, 64)),
293
- },
294
- type: 'p256',
295
- } satisfies P256
296
- }
297
-
298
- if (typeId === serializedWebAuthnType) {
299
- // WebAuthn: variable (webauthnData) + 32 (r) + 32 (s) + 32 (pubKeyX) + 32 (pubKeyY)
300
- // Minimum: 128 bytes (at least some authenticator data + signature components)
301
- if (dataSize < 128)
302
- throw new InvalidSerializedError({
303
- reason: `Invalid WebAuthn signature envelope size: expected at least 128 bytes, got ${dataSize} bytes`,
304
- serialized,
305
- })
306
-
307
- const webauthnDataSize = dataSize - 128
308
- const webauthnData = Hex.slice(data, 0, webauthnDataSize)
309
-
310
- // Parse webauthnData into authenticatorData and clientDataJSON
311
- // According to the Rust code, it's authenticatorData || clientDataJSON
312
- // We need to find the split point (minimum authenticatorData is 37 bytes)
313
- let authenticatorData: Hex.Hex | undefined
314
- let clientDataJSON: string | undefined
315
-
316
- // Try to find the JSON start (clientDataJSON should start with '{')
317
- for (let split = 37; split < webauthnDataSize; split++) {
318
- const potentialJson = Hex.toString(Hex.slice(webauthnData, split))
319
- if (potentialJson.startsWith('{') && potentialJson.endsWith('}')) {
320
- try {
321
- JSON.parse(potentialJson)
322
- authenticatorData = Hex.slice(webauthnData, 0, split)
323
- clientDataJSON = potentialJson
324
- break
325
- } catch {}
326
- }
327
- }
328
-
329
- if (!authenticatorData || !clientDataJSON)
330
- throw new InvalidSerializedError({
331
- reason:
332
- 'Unable to parse WebAuthn metadata: could not extract valid authenticatorData and clientDataJSON',
333
- serialized,
334
- })
335
-
336
- return {
337
- publicKey: {
338
- prefix: 4,
339
- x: Hex.toBigInt(
340
- Hex.slice(data, webauthnDataSize + 64, webauthnDataSize + 96),
341
- ),
342
- y: Hex.toBigInt(
343
- Hex.slice(data, webauthnDataSize + 96, webauthnDataSize + 128),
344
- ),
345
- },
346
- metadata: {
347
- authenticatorData,
348
- clientDataJSON,
349
- },
350
- signature: {
351
- r: Hex.toBigInt(
352
- Hex.slice(data, webauthnDataSize, webauthnDataSize + 32),
353
- ),
354
- s: Hex.toBigInt(
355
- Hex.slice(data, webauthnDataSize + 32, webauthnDataSize + 64),
356
- ),
357
- },
358
- type: 'webAuthn',
359
- } satisfies WebAuthn
360
- }
361
-
362
- if (typeId === serializedKeychainType) {
363
- const userAddress = Hex.slice(data, 0, 20)
364
- const inner = deserialize(Hex.slice(data, 20))
365
-
366
- return {
367
- userAddress,
368
- inner,
369
- type: 'keychain',
370
- } satisfies Keychain
371
- }
372
-
373
- throw new InvalidSerializedError({
374
- reason: `Unknown signature type identifier: ${typeId}. Expected ${serializedP256Type} (P256) or ${serializedWebAuthnType} (WebAuthn)`,
375
- serialized,
376
- })
377
- }
378
-
379
- /**
380
- * Coerces a value to a signature envelope.
381
- *
382
- * Accepts either a serialized hex string or an existing signature envelope object.
383
- *
384
- * @param value - The value to coerce (either a hex string or signature envelope).
385
- * @returns The signature envelope.
386
- */
387
- export function from<const value extends from.Value>(
388
- value: value | from.Value,
389
- ): from.ReturnValue<value> {
390
- if (typeof value === 'string') return deserialize(value) as never
391
-
392
- if (
393
- typeof value === 'object' &&
394
- value !== null &&
395
- 'r' in value &&
396
- 's' in value &&
397
- 'yParity' in value
398
- )
399
- return { signature: value, type: 'secp256k1' } as never
400
-
401
- const type = getType(value)
402
- return { ...value, type } as never
403
- }
404
-
405
- export declare namespace from {
406
- type Value =
407
- | UnionPartialBy<SignatureEnvelope, 'type'>
408
- | Secp256k1Flat
409
- | Serialized
410
-
411
- type ReturnValue<value extends Value> = Compute<
412
- OneOf<
413
- value extends Serialized
414
- ? SignatureEnvelope
415
- : value extends Secp256k1Flat
416
- ? Secp256k1
417
- : IsNarrowable<value, SignatureEnvelope> extends true
418
- ? SignatureEnvelope
419
- : Assign<value, { readonly type: GetType<value> }>
420
- >
421
- >
422
- }
423
-
424
- /**
425
- * Converts an {@link SignatureEnvelopeRpc} to a {@link SignatureEnvelope}.
426
- *
427
- * @param envelope - The RPC signature envelope to convert.
428
- * @returns The signature envelope with bigint values.
429
- */
430
- export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
431
- if (envelope.type === 'secp256k1')
432
- return {
433
- signature: Signature.fromRpc(envelope),
434
- type: 'secp256k1',
435
- }
436
-
437
- if (envelope.type === 'p256') {
438
- return {
439
- prehash: envelope.prehash,
440
- publicKey: {
441
- prefix: 4,
442
- x: Hex.toBigInt(envelope.pubKeyX),
443
- y: Hex.toBigInt(envelope.pubKeyY),
444
- },
445
- signature: {
446
- r: Hex.toBigInt(envelope.r),
447
- s: Hex.toBigInt(envelope.s),
448
- },
449
- type: 'p256',
450
- }
451
- }
452
-
453
- if (envelope.type === 'webAuthn') {
454
- const webauthnData = envelope.webauthnData
455
- const webauthnDataSize = Hex.size(webauthnData)
456
-
457
- // Parse webauthnData into authenticatorData and clientDataJSON
458
- let authenticatorData: Hex.Hex | undefined
459
- let clientDataJSON: string | undefined
460
-
461
- // Try to find the JSON start (clientDataJSON should start with '{')
462
- for (let split = 37; split < webauthnDataSize; split++) {
463
- const potentialJson = Hex.toString(Hex.slice(webauthnData, split))
464
- if (potentialJson.startsWith('{') && potentialJson.endsWith('}')) {
465
- try {
466
- JSON.parse(potentialJson)
467
- authenticatorData = Hex.slice(webauthnData, 0, split)
468
- clientDataJSON = potentialJson
469
- break
470
- } catch {}
471
- }
472
- }
473
-
474
- if (!authenticatorData || !clientDataJSON)
475
- throw new InvalidSerializedError({
476
- reason:
477
- 'Unable to parse WebAuthn metadata: could not extract valid authenticatorData and clientDataJSON',
478
- serialized: webauthnData,
479
- })
480
-
481
- return {
482
- metadata: {
483
- authenticatorData,
484
- clientDataJSON,
485
- },
486
- publicKey: {
487
- prefix: 4,
488
- x: Hex.toBigInt(envelope.pubKeyX),
489
- y: Hex.toBigInt(envelope.pubKeyY),
490
- },
491
- signature: {
492
- r: Hex.toBigInt(envelope.r),
493
- s: Hex.toBigInt(envelope.s),
494
- },
495
- type: 'webAuthn',
496
- }
497
- }
498
-
499
- if (
500
- envelope.type === 'keychain' ||
501
- ('userAddress' in envelope && 'signature' in envelope)
502
- )
503
- return {
504
- type: 'keychain',
505
- userAddress: envelope.userAddress,
506
- inner: fromRpc(envelope.signature),
507
- }
508
-
509
- throw new CoercionError({ envelope })
510
- }
511
-
512
- export declare namespace fromRpc {
513
- type ErrorType =
514
- | CoercionError
515
- | InvalidSerializedError
516
- | Signature.fromRpc.ErrorType
517
- | Errors.GlobalErrorType
518
- }
519
-
520
- /**
521
- * Determines the signature type of an envelope.
522
- *
523
- * @param envelope - The signature envelope to inspect.
524
- * @returns The signature type ('secp256k1', 'p256', or 'webAuthn').
525
- * @throws {CoercionError} If the envelope type cannot be determined.
526
- */
527
- export function getType<
528
- envelope extends
529
- | PartialBy<SignatureEnvelope, 'type'>
530
- | Secp256k1Flat
531
- | unknown,
532
- >(envelope: envelope): GetType<envelope> {
533
- if (typeof envelope !== 'object' || envelope === null)
534
- throw new CoercionError({ envelope })
535
-
536
- if ('type' in envelope && envelope.type) return envelope.type as never
537
-
538
- // Detect secp256k1 signature (backwards compatibility: also support flat structure)
539
- if (
540
- 'signature' in envelope &&
541
- !('publicKey' in envelope) &&
542
- typeof envelope.signature === 'object' &&
543
- envelope.signature !== null &&
544
- 'r' in envelope.signature &&
545
- 's' in envelope.signature &&
546
- 'yParity' in envelope.signature
547
- )
548
- return 'secp256k1' as never
549
-
550
- // Detect secp256k1 signature (flat structure)
551
- if ('r' in envelope && 's' in envelope && 'yParity' in envelope)
552
- return 'secp256k1' as never
553
-
554
- // Detect P256 signature
555
- if (
556
- 'signature' in envelope &&
557
- 'prehash' in envelope &&
558
- 'publicKey' in envelope &&
559
- typeof envelope.prehash === 'boolean'
560
- )
561
- return 'p256' as never
562
-
563
- // Detect WebAuthn signature
564
- if (
565
- 'signature' in envelope &&
566
- 'metadata' in envelope &&
567
- 'publicKey' in envelope
568
- )
569
- return 'webAuthn' as never
570
-
571
- // Detect Keychain signature
572
- if ('userAddress' in envelope && 'inner' in envelope)
573
- return 'keychain' as never
574
-
575
- throw new CoercionError({
576
- envelope,
577
- })
578
- }
579
-
580
- /**
581
- * Serializes a signature envelope to a hex-encoded string.
582
- *
583
- * For backward compatibility:
584
- * - secp256k1: encoded WITHOUT type identifier (65 bytes)
585
- * - P256: encoded WITH type identifier prefix (130 bytes)
586
- * - WebAuthn: encoded WITH type identifier prefix (variable length)
587
- *
588
- * @param envelope - The signature envelope to serialize.
589
- * @returns The hex-encoded serialized signature.
590
- * @throws {CoercionError} If the envelope cannot be serialized.
591
- */
592
- export function serialize(
593
- envelope: UnionPartialBy<SignatureEnvelope, 'prehash'>,
594
- ): Serialized {
595
- const type = getType(envelope)
596
-
597
- // Backward compatibility: no type identifier for secp256k1
598
- if (type === 'secp256k1') {
599
- const secp256k1 = envelope as Secp256k1
600
- return Signature.toHex(secp256k1.signature)
601
- }
602
-
603
- if (type === 'p256') {
604
- const p256 = envelope as P256
605
- // Format: 1 byte (type) + 32 (r) + 32 (s) + 32 (pubKeyX) + 32 (pubKeyY) + 1 (prehash)
606
- return Hex.concat(
607
- serializedP256Type,
608
- Hex.fromNumber(p256.signature.r, { size: 32 }),
609
- Hex.fromNumber(p256.signature.s, { size: 32 }),
610
- Hex.fromNumber(p256.publicKey.x, { size: 32 }),
611
- Hex.fromNumber(p256.publicKey.y, { size: 32 }),
612
- Hex.fromNumber(p256.prehash ? 1 : 0, { size: 1 }),
613
- )
614
- }
615
-
616
- if (type === 'webAuthn') {
617
- const webauthn = envelope as WebAuthn
618
- // Format: 1 byte (type) + variable (authenticatorData || clientDataJSON) + 32 (r) + 32 (s) + 32 (pubKeyX) + 32 (pubKeyY)
619
- const webauthnData = Hex.concat(
620
- webauthn.metadata.authenticatorData,
621
- Hex.fromString(webauthn.metadata.clientDataJSON),
622
- )
623
-
624
- return Hex.concat(
625
- serializedWebAuthnType,
626
- webauthnData,
627
- Hex.fromNumber(webauthn.signature.r, { size: 32 }),
628
- Hex.fromNumber(webauthn.signature.s, { size: 32 }),
629
- Hex.fromNumber(webauthn.publicKey.x, { size: 32 }),
630
- Hex.fromNumber(webauthn.publicKey.y, { size: 32 }),
631
- )
632
- }
633
-
634
- if (type === 'keychain') {
635
- const keychain = envelope as Keychain
636
- return Hex.concat(
637
- serializedKeychainType,
638
- keychain.userAddress,
639
- serialize(keychain.inner),
640
- )
641
- }
642
-
643
- throw new CoercionError({ envelope })
644
- }
645
-
646
- /**
647
- * Converts a {@link SignatureEnvelope} to an {@link SignatureEnvelopeRpc}.
648
- *
649
- * @param envelope - The signature envelope to convert.
650
- * @returns The RPC signature envelope with hex values.
651
- */
652
- export function toRpc(envelope: SignatureEnvelope): SignatureEnvelopeRpc {
653
- const type = getType(envelope)
654
-
655
- if (type === 'secp256k1') {
656
- const secp256k1 = envelope as Secp256k1
657
- return {
658
- ...Signature.toRpc(secp256k1.signature),
659
- type: 'secp256k1',
660
- }
661
- }
662
-
663
- if (type === 'p256') {
664
- const p256 = envelope as P256
665
- return {
666
- prehash: p256.prehash,
667
- pubKeyX: Hex.fromNumber(p256.publicKey.x, { size: 32 }),
668
- pubKeyY: Hex.fromNumber(p256.publicKey.y, { size: 32 }),
669
- r: Hex.fromNumber(p256.signature.r, { size: 32 }),
670
- s: Hex.fromNumber(p256.signature.s, { size: 32 }),
671
- type: 'p256',
672
- }
673
- }
674
-
675
- if (type === 'webAuthn') {
676
- const webauthn = envelope as WebAuthn
677
- const webauthnData = Hex.concat(
678
- webauthn.metadata.authenticatorData,
679
- Hex.fromString(webauthn.metadata.clientDataJSON),
680
- )
681
-
682
- return {
683
- pubKeyX: Hex.fromNumber(webauthn.publicKey.x, { size: 32 }),
684
- pubKeyY: Hex.fromNumber(webauthn.publicKey.y, { size: 32 }),
685
- r: Hex.fromNumber(webauthn.signature.r, { size: 32 }),
686
- s: Hex.fromNumber(webauthn.signature.s, { size: 32 }),
687
- type: 'webAuthn',
688
- webauthnData,
689
- }
690
- }
691
-
692
- if (type === 'keychain') {
693
- const keychain = envelope as Keychain
694
- return {
695
- type: 'keychain',
696
- userAddress: keychain.userAddress,
697
- signature: toRpc(keychain.inner),
698
- }
699
- }
700
-
701
- throw new CoercionError({ envelope })
702
- }
703
-
704
- export declare namespace toRpc {
705
- type ErrorType =
706
- | CoercionError
707
- | Signature.toRpc.ErrorType
708
- | Errors.GlobalErrorType
709
- }
710
-
711
- /**
712
- * Validates a {@link SignatureEnvelope}. Returns `true` if the envelope is valid, `false` otherwise.
713
- *
714
- * @example
715
- * ```ts twoslash
716
- * import { SignatureEnvelope } from 'tempo.ts/ox'
717
- *
718
- * const valid = SignatureEnvelope.validate({
719
- * signature: { r: 0n, s: 0n, yParity: 0 },
720
- * type: 'secp256k1',
721
- * })
722
- * // @log: true
723
- * ```
724
- *
725
- * @param envelope - The signature envelope to validate.
726
- * @returns `true` if valid, `false` otherwise.
727
- */
728
- export function validate(
729
- envelope: PartialBy<SignatureEnvelope, 'type'>,
730
- ): boolean {
731
- try {
732
- assert(envelope)
733
- return true
734
- } catch {
735
- return false
736
- }
737
- }
738
-
739
- export declare namespace validate {
740
- type ErrorType = Errors.GlobalErrorType
741
- }
742
-
743
- /**
744
- * Error thrown when a signature envelope cannot be coerced to a valid type.
745
- */
746
- export class CoercionError extends Errors.BaseError {
747
- override readonly name = 'SignatureEnvelope.CoercionError'
748
- constructor({ envelope }: { envelope: unknown }) {
749
- super(
750
- `Unable to coerce value (\`${Json.stringify(envelope)}\`) to a valid signature envelope.`,
751
- )
752
- }
753
- }
754
-
755
- /**
756
- * Error thrown when a signature envelope is missing required properties.
757
- */
758
- export class MissingPropertiesError extends Errors.BaseError {
759
- override readonly name = 'SignatureEnvelope.MissingPropertiesError'
760
- constructor({
761
- envelope,
762
- missing,
763
- type,
764
- }: {
765
- envelope: unknown
766
- missing: string[]
767
- type: Type
768
- }) {
769
- super(
770
- `Signature envelope of type "${type}" is missing required properties: ${missing.map((m) => `\`${m}\``).join(', ')}.\n\nProvided: ${Json.stringify(envelope)}`,
771
- )
772
- }
773
- }
774
-
775
- /**
776
- * Error thrown when a serialized signature envelope cannot be deserialized.
777
- */
778
- export class InvalidSerializedError extends Errors.BaseError {
779
- override readonly name = 'SignatureEnvelope.InvalidSerializedError'
780
- constructor({
781
- reason,
782
- serialized,
783
- }: {
784
- reason: string
785
- serialized: Hex.Hex
786
- }) {
787
- super(`Unable to deserialize signature envelope: ${reason}`, {
788
- metaMessages: [`Serialized: ${serialized}`],
789
- })
790
- }
791
- }