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