ox 0.12.4 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/_cjs/core/P256.js +1 -1
- package/_cjs/core/P256.js.map +1 -1
- package/_cjs/core/WebAuthnP256.js +15 -256
- package/_cjs/core/WebAuthnP256.js.map +1 -1
- package/_cjs/core/WebCryptoP256.js +3 -1
- package/_cjs/core/WebCryptoP256.js.map +1 -1
- package/_cjs/core/internal/webauthn.js +5 -13
- package/_cjs/core/internal/webauthn.js.map +1 -1
- package/_cjs/index.docs.js +1 -0
- package/_cjs/index.docs.js.map +1 -1
- package/_cjs/tempo/KeyAuthorization.js +18 -3
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/SignatureEnvelope.js +26 -0
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/TxEnvelopeTempo.js +5 -10
- package/_cjs/tempo/TxEnvelopeTempo.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_cjs/webauthn/Authentication.js +246 -0
- package/_cjs/webauthn/Authentication.js.map +1 -0
- package/_cjs/webauthn/Authenticator.js +55 -0
- package/_cjs/webauthn/Authenticator.js.map +1 -0
- package/_cjs/webauthn/Credential.js +53 -0
- package/_cjs/webauthn/Credential.js.map +1 -0
- package/_cjs/webauthn/Registration.js +349 -0
- package/_cjs/webauthn/Registration.js.map +1 -0
- package/_cjs/webauthn/Types.js +3 -0
- package/_cjs/webauthn/Types.js.map +1 -0
- package/_cjs/webauthn/index.js +9 -0
- package/_cjs/webauthn/index.js.map +1 -0
- package/_cjs/webauthn/internal/utils.js +53 -0
- package/_cjs/webauthn/internal/utils.js.map +1 -0
- package/_esm/core/P256.js +1 -1
- package/_esm/core/P256.js.map +1 -1
- package/_esm/core/WebAuthnP256.js +13 -261
- package/_esm/core/WebAuthnP256.js.map +1 -1
- package/_esm/core/WebCryptoP256.js +4 -1
- package/_esm/core/WebCryptoP256.js.map +1 -1
- package/_esm/core/internal/webauthn.js +5 -13
- package/_esm/core/internal/webauthn.js.map +1 -1
- package/_esm/erc8021/index.js +2 -2
- package/_esm/index.docs.js +1 -0
- package/_esm/index.docs.js.map +1 -1
- package/_esm/tempo/KeyAuthorization.js +66 -3
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/SignatureEnvelope.js +74 -0
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/TransactionReceipt.js +1 -1
- package/_esm/tempo/TransactionRequest.js +1 -1
- package/_esm/tempo/TxEnvelopeTempo.js +5 -10
- package/_esm/tempo/TxEnvelopeTempo.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_esm/webauthn/Authentication.js +453 -0
- package/_esm/webauthn/Authentication.js.map +1 -0
- package/_esm/webauthn/Authenticator.js +176 -0
- package/_esm/webauthn/Authenticator.js.map +1 -0
- package/_esm/webauthn/Credential.js +95 -0
- package/_esm/webauthn/Credential.js.map +1 -0
- package/_esm/webauthn/Registration.js +512 -0
- package/_esm/webauthn/Registration.js.map +1 -0
- package/_esm/webauthn/Types.js +2 -0
- package/_esm/webauthn/Types.js.map +1 -0
- package/_esm/webauthn/index.js +31 -0
- package/_esm/webauthn/index.js.map +1 -0
- package/_esm/webauthn/internal/utils.js +52 -0
- package/_esm/webauthn/internal/utils.js.map +1 -0
- package/_types/core/WebAuthnP256.d.ts +33 -208
- package/_types/core/WebAuthnP256.d.ts.map +1 -1
- package/_types/core/WebCryptoP256.d.ts +2 -0
- package/_types/core/WebCryptoP256.d.ts.map +1 -1
- package/_types/core/internal/webauthn.d.ts +2 -110
- package/_types/core/internal/webauthn.d.ts.map +1 -1
- package/_types/erc8021/index.d.ts +2 -2
- package/_types/index.docs.d.ts +1 -0
- package/_types/index.docs.d.ts.map +1 -1
- package/_types/tempo/KeyAuthorization.d.ts +57 -0
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/SignatureEnvelope.d.ts +75 -0
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/Transaction.d.ts +2 -2
- package/_types/tempo/TransactionReceipt.d.ts +2 -2
- package/_types/tempo/TransactionRequest.d.ts +2 -2
- package/_types/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/_types/webauthn/Authentication.d.ts +324 -0
- package/_types/webauthn/Authentication.d.ts.map +1 -0
- package/_types/webauthn/Authenticator.d.ts +182 -0
- package/_types/webauthn/Authenticator.d.ts.map +1 -0
- package/_types/webauthn/Credential.d.ts +77 -0
- package/_types/webauthn/Credential.d.ts.map +1 -0
- package/_types/webauthn/Registration.d.ts +308 -0
- package/_types/webauthn/Registration.d.ts.map +1 -0
- package/_types/webauthn/Types.d.ts +106 -0
- package/_types/webauthn/Types.d.ts.map +1 -0
- package/_types/webauthn/index.d.ts +33 -0
- package/_types/webauthn/index.d.ts.map +1 -0
- package/_types/webauthn/internal/utils.d.ts +17 -0
- package/_types/webauthn/internal/utils.d.ts.map +1 -0
- package/core/P256.ts +1 -1
- package/core/WebAuthnP256.ts +37 -582
- package/core/WebCryptoP256.ts +6 -1
- package/core/internal/webauthn.ts +6 -165
- package/erc8021/index.ts +2 -2
- package/index.docs.ts +1 -0
- package/package.json +31 -1
- package/tempo/KeyAuthorization.test.ts +139 -0
- package/tempo/KeyAuthorization.ts +82 -3
- package/tempo/SignatureEnvelope.test.ts +147 -0
- package/tempo/SignatureEnvelope.ts +113 -0
- package/tempo/Transaction.ts +2 -2
- package/tempo/TransactionReceipt.ts +2 -2
- package/tempo/TransactionRequest.ts +2 -2
- package/tempo/TxEnvelopeTempo.ts +5 -12
- package/tempo/e2e.test.ts +265 -0
- package/version.ts +1 -1
- package/webauthn/Authentication/package.json +6 -0
- package/webauthn/Authentication.ts +673 -0
- package/webauthn/Authenticator/package.json +6 -0
- package/webauthn/Authenticator.ts +259 -0
- package/webauthn/Credential/package.json +6 -0
- package/webauthn/Credential.ts +146 -0
- package/webauthn/Registration/package.json +6 -0
- package/webauthn/Registration.ts +805 -0
- package/webauthn/Types/package.json +6 -0
- package/webauthn/Types.ts +158 -0
- package/webauthn/index.ts +38 -0
- package/webauthn/internal/utils.ts +63 -0
- package/webauthn/package.json +6 -0
package/core/WebCryptoP256.ts
CHANGED
|
@@ -283,7 +283,10 @@ export declare namespace sign {
|
|
|
283
283
|
* @returns Whether the payload was signed by the provided public key.
|
|
284
284
|
*/
|
|
285
285
|
export async function verify(options: verify.Options): Promise<boolean> {
|
|
286
|
-
const { payload, signature } = options
|
|
286
|
+
const { lowS = true, payload, signature } = options
|
|
287
|
+
|
|
288
|
+
// Reject high-S signatures if lowS is enabled.
|
|
289
|
+
if (lowS && signature.s > p256.CURVE.n / 2n) return false
|
|
287
290
|
|
|
288
291
|
const publicKey = await globalThis.crypto.subtle.importKey(
|
|
289
292
|
'raw',
|
|
@@ -306,6 +309,8 @@ export async function verify(options: verify.Options): Promise<boolean> {
|
|
|
306
309
|
|
|
307
310
|
export declare namespace verify {
|
|
308
311
|
type Options = {
|
|
312
|
+
/** If set to `true`, only low-S signatures will be accepted. @default true */
|
|
313
|
+
lowS?: boolean | undefined
|
|
309
314
|
/** Public key that signed the payload. */
|
|
310
315
|
publicKey: PublicKey.PublicKey<boolean>
|
|
311
316
|
/** Signature of the payload. */
|
|
@@ -1,157 +1,7 @@
|
|
|
1
1
|
import { p256 } from '@noble/curves/p256'
|
|
2
|
+
import * as Registration from '../../webauthn/Registration.js'
|
|
2
3
|
import type * as Errors from '../Errors.js'
|
|
3
|
-
import * as Hex from '../Hex.js'
|
|
4
4
|
import * as PublicKey from '../PublicKey.js'
|
|
5
|
-
import { CredentialCreationFailedError } from '../WebAuthnP256.js'
|
|
6
|
-
|
|
7
|
-
/** @internal */
|
|
8
|
-
export type AttestationConveyancePreference =
|
|
9
|
-
| 'direct'
|
|
10
|
-
| 'enterprise'
|
|
11
|
-
| 'indirect'
|
|
12
|
-
| 'none'
|
|
13
|
-
|
|
14
|
-
/** @internal */
|
|
15
|
-
export type AuthenticatorAttachment = 'cross-platform' | 'platform'
|
|
16
|
-
|
|
17
|
-
/** @internal */
|
|
18
|
-
export type AuthenticatorTransport =
|
|
19
|
-
| 'ble'
|
|
20
|
-
| 'hybrid'
|
|
21
|
-
| 'internal'
|
|
22
|
-
| 'nfc'
|
|
23
|
-
| 'usb'
|
|
24
|
-
|
|
25
|
-
/** @internal */
|
|
26
|
-
export type COSEAlgorithmIdentifier = number
|
|
27
|
-
|
|
28
|
-
/** @internal */
|
|
29
|
-
export type CredentialMediationRequirement =
|
|
30
|
-
| 'conditional'
|
|
31
|
-
| 'optional'
|
|
32
|
-
| 'required'
|
|
33
|
-
| 'silent'
|
|
34
|
-
|
|
35
|
-
/** @internal */
|
|
36
|
-
export type PublicKeyCredentialType = 'public-key'
|
|
37
|
-
|
|
38
|
-
/** @internal */
|
|
39
|
-
export type ResidentKeyRequirement = 'discouraged' | 'preferred' | 'required'
|
|
40
|
-
|
|
41
|
-
/** @internal */
|
|
42
|
-
export type UserVerificationRequirement =
|
|
43
|
-
| 'discouraged'
|
|
44
|
-
| 'preferred'
|
|
45
|
-
| 'required'
|
|
46
|
-
|
|
47
|
-
/** @internal */
|
|
48
|
-
export type LargeBlobSupport = {
|
|
49
|
-
support: 'required' | 'preferred'
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** @internal */
|
|
53
|
-
export type BufferSource = ArrayBufferView | ArrayBuffer
|
|
54
|
-
|
|
55
|
-
/** @internal */
|
|
56
|
-
export type PrfExtension = Record<'eval', Record<'first', Uint8Array>>
|
|
57
|
-
|
|
58
|
-
/** @internal */
|
|
59
|
-
export interface AuthenticationExtensionsClientInputs {
|
|
60
|
-
appid?: string
|
|
61
|
-
credProps?: boolean
|
|
62
|
-
hmacCreateSecret?: boolean
|
|
63
|
-
minPinLength?: boolean
|
|
64
|
-
prf?: PrfExtension
|
|
65
|
-
largeBlob?: LargeBlobSupport
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** @internal */
|
|
69
|
-
export interface AuthenticatorSelectionCriteria {
|
|
70
|
-
authenticatorAttachment?: AuthenticatorAttachment
|
|
71
|
-
requireResidentKey?: boolean
|
|
72
|
-
residentKey?: ResidentKeyRequirement
|
|
73
|
-
userVerification?: UserVerificationRequirement
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** @internal */
|
|
77
|
-
export interface Credential {
|
|
78
|
-
readonly id: string
|
|
79
|
-
readonly type: string
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** @internal */
|
|
83
|
-
export interface CredentialCreationOptions {
|
|
84
|
-
publicKey?: PublicKeyCredentialCreationOptions
|
|
85
|
-
signal?: AbortSignal
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** @internal */
|
|
89
|
-
export interface CredentialRequestOptions {
|
|
90
|
-
mediation?: CredentialMediationRequirement
|
|
91
|
-
publicKey?: PublicKeyCredentialRequestOptions
|
|
92
|
-
signal?: AbortSignal
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** @internal */
|
|
96
|
-
export interface PublicKeyCredential extends Credential {
|
|
97
|
-
readonly authenticatorAttachment: string | null
|
|
98
|
-
readonly rawId: ArrayBuffer
|
|
99
|
-
readonly response: AuthenticatorResponse
|
|
100
|
-
getClientExtensionResults(): AuthenticationExtensionsClientOutputs
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** @internal */
|
|
104
|
-
export interface PublicKeyCredentialCreationOptions {
|
|
105
|
-
attestation?: AttestationConveyancePreference
|
|
106
|
-
authenticatorSelection?: AuthenticatorSelectionCriteria
|
|
107
|
-
challenge: BufferSource
|
|
108
|
-
excludeCredentials?: PublicKeyCredentialDescriptor[]
|
|
109
|
-
extensions?: AuthenticationExtensionsClientInputs
|
|
110
|
-
pubKeyCredParams: PublicKeyCredentialParameters[]
|
|
111
|
-
rp: PublicKeyCredentialRpEntity
|
|
112
|
-
timeout?: number
|
|
113
|
-
user: PublicKeyCredentialUserEntity
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** @internal */
|
|
117
|
-
export interface PublicKeyCredentialDescriptor {
|
|
118
|
-
id: BufferSource
|
|
119
|
-
transports?: AuthenticatorTransport[]
|
|
120
|
-
type: PublicKeyCredentialType
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** @internal */
|
|
124
|
-
export interface PublicKeyCredentialEntity {
|
|
125
|
-
name: string
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** @internal */
|
|
129
|
-
export interface PublicKeyCredentialParameters {
|
|
130
|
-
alg: COSEAlgorithmIdentifier
|
|
131
|
-
type: PublicKeyCredentialType
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** @internal */
|
|
135
|
-
export interface PublicKeyCredentialRequestOptions {
|
|
136
|
-
allowCredentials?: PublicKeyCredentialDescriptor[]
|
|
137
|
-
challenge: BufferSource
|
|
138
|
-
extensions?: AuthenticationExtensionsClientInputs
|
|
139
|
-
rpId?: string
|
|
140
|
-
timeout?: number
|
|
141
|
-
userVerification?: UserVerificationRequirement
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** @internal */
|
|
145
|
-
export interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity {
|
|
146
|
-
id?: string
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** @internal */
|
|
150
|
-
export interface PublicKeyCredentialUserEntity
|
|
151
|
-
extends PublicKeyCredentialEntity {
|
|
152
|
-
displayName: string
|
|
153
|
-
id: BufferSource
|
|
154
|
-
}
|
|
155
5
|
|
|
156
6
|
/**
|
|
157
7
|
* Parses an ASN.1 signature into a r and s value.
|
|
@@ -159,17 +9,8 @@ export interface PublicKeyCredentialUserEntity
|
|
|
159
9
|
* @internal
|
|
160
10
|
*/
|
|
161
11
|
export function parseAsn1Signature(bytes: Uint8Array) {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
const s_start = bytes[r_end + 2] === 0 ? r_end + 3 : r_end + 2
|
|
165
|
-
|
|
166
|
-
const r = BigInt(Hex.fromBytes(bytes.slice(r_start, r_end)))
|
|
167
|
-
const s = BigInt(Hex.fromBytes(bytes.slice(s_start)))
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
r,
|
|
171
|
-
s: s > p256.CURVE.n / 2n ? p256.CURVE.n - s : s,
|
|
172
|
-
}
|
|
12
|
+
const sig = p256.Signature.fromDER(bytes).normalizeS()
|
|
13
|
+
return { r: sig.r, s: sig.s }
|
|
173
14
|
}
|
|
174
15
|
|
|
175
16
|
/**
|
|
@@ -183,7 +24,7 @@ export async function parseCredentialPublicKey(
|
|
|
183
24
|
): Promise<PublicKey.PublicKey> {
|
|
184
25
|
try {
|
|
185
26
|
const publicKeyBuffer = response.getPublicKey()
|
|
186
|
-
if (!publicKeyBuffer) throw new
|
|
27
|
+
if (!publicKeyBuffer) throw new Registration.CreateFailedError()
|
|
187
28
|
|
|
188
29
|
// Converting `publicKeyBuffer` throws when credential is created by 1Password Firefox Add-on
|
|
189
30
|
const publicKeyBytes = new Uint8Array(publicKeyBuffer)
|
|
@@ -218,7 +59,7 @@ export async function parseCredentialPublicKey(
|
|
|
218
59
|
for (let i = 0; i < data.length - coordinate.length; i++)
|
|
219
60
|
if (coordinate.every((byte, j) => data[i + j] === byte))
|
|
220
61
|
return i + coordinate.length
|
|
221
|
-
throw new
|
|
62
|
+
throw new Registration.CreateFailedError()
|
|
222
63
|
}
|
|
223
64
|
|
|
224
65
|
const xStart = findStart(0x21)
|
|
@@ -235,5 +76,5 @@ export async function parseCredentialPublicKey(
|
|
|
235
76
|
}
|
|
236
77
|
|
|
237
78
|
export declare namespace parseCredentialPublicKey {
|
|
238
|
-
type ErrorType =
|
|
79
|
+
type ErrorType = Registration.CreateFailedError | Errors.GlobalErrorType
|
|
239
80
|
}
|
package/erc8021/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type {}
|
|
|
17
17
|
*
|
|
18
18
|
* const dataSuffix2 = Attribution.toDataSuffix({
|
|
19
19
|
* codes: ['baseapp', 'morpho'],
|
|
20
|
-
*
|
|
20
|
+
* codeRegistry: { address: '0x0000000000000000000000000000000000000000', chainId: 1 },
|
|
21
21
|
* })
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
@@ -30,7 +30,7 @@ export type {}
|
|
|
30
30
|
* const attribution = Attribution.fromData('0x...')
|
|
31
31
|
*
|
|
32
32
|
* console.log(attribution)
|
|
33
|
-
* // @log: { codes: ['baseapp', 'morpho'],
|
|
33
|
+
* // @log: { codes: ['baseapp', 'morpho'], codeRegistry: { address: '0x...', chainId: 1 } }
|
|
34
34
|
* ```
|
|
35
35
|
*
|
|
36
36
|
* @category ERC-8021
|
package/index.docs.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ox",
|
|
3
3
|
"description": "Ethereum Standard Library",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.1",
|
|
5
5
|
"main": "./_cjs/index.js",
|
|
6
6
|
"module": "./_esm/index.js",
|
|
7
7
|
"types": "./_types/index.d.ts",
|
|
@@ -554,6 +554,36 @@
|
|
|
554
554
|
"import": "./_esm/trusted-setups/index.js",
|
|
555
555
|
"default": "./_cjs/trusted-setups/index.js"
|
|
556
556
|
},
|
|
557
|
+
"./webauthn/Authentication": {
|
|
558
|
+
"types": "./_types/webauthn/Authentication.d.ts",
|
|
559
|
+
"import": "./_esm/webauthn/Authentication.js",
|
|
560
|
+
"default": "./_cjs/webauthn/Authentication.js"
|
|
561
|
+
},
|
|
562
|
+
"./webauthn/Authenticator": {
|
|
563
|
+
"types": "./_types/webauthn/Authenticator.d.ts",
|
|
564
|
+
"import": "./_esm/webauthn/Authenticator.js",
|
|
565
|
+
"default": "./_cjs/webauthn/Authenticator.js"
|
|
566
|
+
},
|
|
567
|
+
"./webauthn/Credential": {
|
|
568
|
+
"types": "./_types/webauthn/Credential.d.ts",
|
|
569
|
+
"import": "./_esm/webauthn/Credential.js",
|
|
570
|
+
"default": "./_cjs/webauthn/Credential.js"
|
|
571
|
+
},
|
|
572
|
+
"./webauthn/Registration": {
|
|
573
|
+
"types": "./_types/webauthn/Registration.d.ts",
|
|
574
|
+
"import": "./_esm/webauthn/Registration.js",
|
|
575
|
+
"default": "./_cjs/webauthn/Registration.js"
|
|
576
|
+
},
|
|
577
|
+
"./webauthn/Types": {
|
|
578
|
+
"types": "./_types/webauthn/Types.d.ts",
|
|
579
|
+
"import": "./_esm/webauthn/Types.js",
|
|
580
|
+
"default": "./_cjs/webauthn/Types.js"
|
|
581
|
+
},
|
|
582
|
+
"./webauthn": {
|
|
583
|
+
"types": "./_types/webauthn/index.d.ts",
|
|
584
|
+
"import": "./_esm/webauthn/index.js",
|
|
585
|
+
"default": "./_cjs/webauthn/index.js"
|
|
586
|
+
},
|
|
557
587
|
"./window": {
|
|
558
588
|
"types": "./_types/window/index.d.ts",
|
|
559
589
|
"import": "./_esm/window/index.js",
|
|
@@ -927,6 +927,74 @@ describe('getSignPayload', () => {
|
|
|
927
927
|
})
|
|
928
928
|
})
|
|
929
929
|
|
|
930
|
+
describe('deserialize', () => {
|
|
931
|
+
test('default', () => {
|
|
932
|
+
const authorization = KeyAuthorization.from({
|
|
933
|
+
address,
|
|
934
|
+
expiry,
|
|
935
|
+
type: 'secp256k1',
|
|
936
|
+
limits: [
|
|
937
|
+
{
|
|
938
|
+
token,
|
|
939
|
+
limit: Value.from('10', 6),
|
|
940
|
+
},
|
|
941
|
+
],
|
|
942
|
+
})
|
|
943
|
+
|
|
944
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
945
|
+
const deserialized = KeyAuthorization.deserialize(serialized)
|
|
946
|
+
|
|
947
|
+
expect(deserialized).toEqual(authorization)
|
|
948
|
+
})
|
|
949
|
+
|
|
950
|
+
test('signed (secp256k1)', () => {
|
|
951
|
+
const authorization = KeyAuthorization.from(
|
|
952
|
+
{
|
|
953
|
+
address,
|
|
954
|
+
expiry,
|
|
955
|
+
type: 'secp256k1',
|
|
956
|
+
limits: [
|
|
957
|
+
{
|
|
958
|
+
token,
|
|
959
|
+
limit: Value.from('10', 6),
|
|
960
|
+
},
|
|
961
|
+
],
|
|
962
|
+
},
|
|
963
|
+
{ signature: signature_secp256k1 },
|
|
964
|
+
)
|
|
965
|
+
|
|
966
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
967
|
+
const deserialized = KeyAuthorization.deserialize(serialized)
|
|
968
|
+
|
|
969
|
+
expect(deserialized).toEqual(authorization)
|
|
970
|
+
})
|
|
971
|
+
|
|
972
|
+
test('no limits', () => {
|
|
973
|
+
const authorization = KeyAuthorization.from({
|
|
974
|
+
address,
|
|
975
|
+
expiry,
|
|
976
|
+
type: 'secp256k1',
|
|
977
|
+
})
|
|
978
|
+
|
|
979
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
980
|
+
const deserialized = KeyAuthorization.deserialize(serialized)
|
|
981
|
+
|
|
982
|
+
expect(deserialized).toEqual(authorization)
|
|
983
|
+
})
|
|
984
|
+
|
|
985
|
+
test('no expiry', () => {
|
|
986
|
+
const authorization = KeyAuthorization.from({
|
|
987
|
+
address,
|
|
988
|
+
type: 'secp256k1',
|
|
989
|
+
})
|
|
990
|
+
|
|
991
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
992
|
+
const deserialized = KeyAuthorization.deserialize(serialized)
|
|
993
|
+
|
|
994
|
+
expect(deserialized).toEqual(authorization)
|
|
995
|
+
})
|
|
996
|
+
})
|
|
997
|
+
|
|
930
998
|
describe('hash', () => {
|
|
931
999
|
test('default', () => {
|
|
932
1000
|
const authorization = KeyAuthorization.from({
|
|
@@ -949,6 +1017,77 @@ describe('hash', () => {
|
|
|
949
1017
|
})
|
|
950
1018
|
})
|
|
951
1019
|
|
|
1020
|
+
describe('serialize', () => {
|
|
1021
|
+
test('default', () => {
|
|
1022
|
+
const authorization = KeyAuthorization.from({
|
|
1023
|
+
address,
|
|
1024
|
+
expiry,
|
|
1025
|
+
type: 'secp256k1',
|
|
1026
|
+
limits: [
|
|
1027
|
+
{
|
|
1028
|
+
token,
|
|
1029
|
+
limit: Value.from('10', 6),
|
|
1030
|
+
},
|
|
1031
|
+
],
|
|
1032
|
+
})
|
|
1033
|
+
|
|
1034
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
1035
|
+
|
|
1036
|
+
expect(serialized).toMatchInlineSnapshot(
|
|
1037
|
+
`"0xf838f7808094be95c3f554e9fc85ec51be69a3d807a0d55bcf2c84499602d2dad99420c000000000000000000000000000000000000183989680"`,
|
|
1038
|
+
)
|
|
1039
|
+
})
|
|
1040
|
+
|
|
1041
|
+
test('signed (secp256k1)', () => {
|
|
1042
|
+
const authorization = KeyAuthorization.from(
|
|
1043
|
+
{
|
|
1044
|
+
address,
|
|
1045
|
+
expiry,
|
|
1046
|
+
type: 'secp256k1',
|
|
1047
|
+
limits: [
|
|
1048
|
+
{
|
|
1049
|
+
token,
|
|
1050
|
+
limit: Value.from('10', 6),
|
|
1051
|
+
},
|
|
1052
|
+
],
|
|
1053
|
+
},
|
|
1054
|
+
{ signature: signature_secp256k1 },
|
|
1055
|
+
)
|
|
1056
|
+
|
|
1057
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
1058
|
+
const deserialized = KeyAuthorization.deserialize(serialized)
|
|
1059
|
+
|
|
1060
|
+
expect(deserialized).toEqual(authorization)
|
|
1061
|
+
})
|
|
1062
|
+
|
|
1063
|
+
test('no limits', () => {
|
|
1064
|
+
const authorization = KeyAuthorization.from({
|
|
1065
|
+
address,
|
|
1066
|
+
expiry,
|
|
1067
|
+
type: 'secp256k1',
|
|
1068
|
+
})
|
|
1069
|
+
|
|
1070
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
1071
|
+
|
|
1072
|
+
expect(serialized).toMatchInlineSnapshot(
|
|
1073
|
+
`"0xdddc808094be95c3f554e9fc85ec51be69a3d807a0d55bcf2c84499602d2"`,
|
|
1074
|
+
)
|
|
1075
|
+
})
|
|
1076
|
+
|
|
1077
|
+
test('no expiry', () => {
|
|
1078
|
+
const authorization = KeyAuthorization.from({
|
|
1079
|
+
address,
|
|
1080
|
+
type: 'secp256k1',
|
|
1081
|
+
})
|
|
1082
|
+
|
|
1083
|
+
const serialized = KeyAuthorization.serialize(authorization)
|
|
1084
|
+
|
|
1085
|
+
expect(serialized).toMatchInlineSnapshot(
|
|
1086
|
+
`"0xd8d7808094be95c3f554e9fc85ec51be69a3d807a0d55bcf2c"`,
|
|
1087
|
+
)
|
|
1088
|
+
})
|
|
1089
|
+
})
|
|
1090
|
+
|
|
952
1091
|
describe('toRpc', () => {
|
|
953
1092
|
test('secp256k1', () => {
|
|
954
1093
|
const authorization = KeyAuthorization.from({
|
|
@@ -458,6 +458,43 @@ export declare namespace getSignPayload {
|
|
|
458
458
|
type ErrorType = hash.ErrorType | Errors.GlobalErrorType
|
|
459
459
|
}
|
|
460
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Deserializes an RLP-encoded {@link ox#KeyAuthorization.KeyAuthorization}.
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```ts twoslash
|
|
466
|
+
* import { KeyAuthorization } from 'ox/tempo'
|
|
467
|
+
* import { Value } from 'ox'
|
|
468
|
+
*
|
|
469
|
+
* const authorization = KeyAuthorization.from({
|
|
470
|
+
* expiry: 1234567890,
|
|
471
|
+
* address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
472
|
+
* type: 'secp256k1',
|
|
473
|
+
* limits: [{
|
|
474
|
+
* token: '0x20c0000000000000000000000000000000000001',
|
|
475
|
+
* limit: Value.from('10', 6)
|
|
476
|
+
* }],
|
|
477
|
+
* })
|
|
478
|
+
*
|
|
479
|
+
* const serialized = KeyAuthorization.serialize(authorization)
|
|
480
|
+
* const deserialized = KeyAuthorization.deserialize(serialized) // [!code focus]
|
|
481
|
+
* ```
|
|
482
|
+
*
|
|
483
|
+
* @param serialized - The RLP-encoded Key Authorization.
|
|
484
|
+
* @returns The {@link ox#KeyAuthorization.KeyAuthorization}.
|
|
485
|
+
*/
|
|
486
|
+
export function deserialize(serialized: Hex.Hex): KeyAuthorization {
|
|
487
|
+
const tuple = Rlp.toHex(serialized) as unknown as Tuple
|
|
488
|
+
return fromTuple(tuple)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export declare namespace deserialize {
|
|
492
|
+
type ErrorType =
|
|
493
|
+
| Rlp.toHex.ErrorType
|
|
494
|
+
| fromTuple.ErrorType
|
|
495
|
+
| Errors.GlobalErrorType
|
|
496
|
+
}
|
|
497
|
+
|
|
461
498
|
/**
|
|
462
499
|
* Computes the hash for an {@link ox#KeyAuthorization.KeyAuthorization}.
|
|
463
500
|
*
|
|
@@ -497,6 +534,42 @@ export declare namespace hash {
|
|
|
497
534
|
| Errors.GlobalErrorType
|
|
498
535
|
}
|
|
499
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Serializes a {@link ox#KeyAuthorization.KeyAuthorization} to RLP-encoded hex.
|
|
539
|
+
*
|
|
540
|
+
* @example
|
|
541
|
+
* ```ts twoslash
|
|
542
|
+
* import { KeyAuthorization } from 'ox/tempo'
|
|
543
|
+
* import { Value } from 'ox'
|
|
544
|
+
*
|
|
545
|
+
* const authorization = KeyAuthorization.from({
|
|
546
|
+
* expiry: 1234567890,
|
|
547
|
+
* address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
|
|
548
|
+
* type: 'secp256k1',
|
|
549
|
+
* limits: [{
|
|
550
|
+
* token: '0x20c0000000000000000000000000000000000001',
|
|
551
|
+
* limit: Value.from('10', 6)
|
|
552
|
+
* }],
|
|
553
|
+
* })
|
|
554
|
+
*
|
|
555
|
+
* const serialized = KeyAuthorization.serialize(authorization) // [!code focus]
|
|
556
|
+
* ```
|
|
557
|
+
*
|
|
558
|
+
* @param authorization - The {@link ox#KeyAuthorization.KeyAuthorization}.
|
|
559
|
+
* @returns The RLP-encoded Key Authorization.
|
|
560
|
+
*/
|
|
561
|
+
export function serialize(authorization: KeyAuthorization): Hex.Hex {
|
|
562
|
+
const tuple = toTuple(authorization)
|
|
563
|
+
return Rlp.fromHex(tuple as any)
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export declare namespace serialize {
|
|
567
|
+
type ErrorType =
|
|
568
|
+
| toTuple.ErrorType
|
|
569
|
+
| Rlp.fromHex.ErrorType
|
|
570
|
+
| Errors.GlobalErrorType
|
|
571
|
+
}
|
|
572
|
+
|
|
500
573
|
/**
|
|
501
574
|
* Converts an {@link ox#KeyAuthorization.KeyAuthorization} to an {@link ox#KeyAuthorization.Rpc}.
|
|
502
575
|
*
|
|
@@ -603,13 +676,19 @@ export function toTuple<const authorization extends KeyAuthorization>(
|
|
|
603
676
|
throw new Error(`Invalid key type: ${authorization.type}`)
|
|
604
677
|
}
|
|
605
678
|
})()
|
|
679
|
+
const limitsValue = limits?.map((limit) => [
|
|
680
|
+
limit.token,
|
|
681
|
+
bigintToHex(limit.limit),
|
|
682
|
+
])
|
|
606
683
|
const authorizationTuple = [
|
|
607
684
|
bigintToHex(chainId),
|
|
608
685
|
type,
|
|
609
686
|
address,
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
687
|
+
// expiry is required in the tuple when limits are present
|
|
688
|
+
typeof expiry === 'number' || limitsValue
|
|
689
|
+
? numberToHex(expiry ?? 0)
|
|
690
|
+
: undefined,
|
|
691
|
+
limitsValue,
|
|
613
692
|
].filter(Boolean)
|
|
614
693
|
return [authorizationTuple, ...(signature ? [signature] : [])] as never
|
|
615
694
|
}
|