ox 0.14.54 → 0.14.56
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 +35 -0
- package/_cjs/tempo/{MultisigConfig.js → AccountConfig.js} +16 -4
- package/_cjs/tempo/AccountConfig.js.map +1 -0
- package/_cjs/tempo/{MultisigOperation.js → AccountOperation.js} +29 -29
- package/_cjs/tempo/AccountOperation.js.map +1 -0
- package/_cjs/tempo/{MultisigSimulation.js → AccountSimulation.js} +9 -9
- package/_cjs/tempo/AccountSimulation.js.map +1 -0
- package/_cjs/tempo/KeyAuthorization.js +12 -11
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/SignatureEnvelope.js +64 -64
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/Transaction.js +2 -0
- package/_cjs/tempo/Transaction.js.map +1 -1
- package/_cjs/tempo/TransactionRequest.js +12 -9
- package/_cjs/tempo/TransactionRequest.js.map +1 -1
- package/_cjs/tempo/index.js +4 -4
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/{MultisigConfig.js → AccountConfig.js} +103 -55
- package/_esm/tempo/AccountConfig.js.map +1 -0
- package/_esm/tempo/{MultisigOperation.js → AccountOperation.js} +64 -64
- package/_esm/tempo/AccountOperation.js.map +1 -0
- package/_esm/tempo/{MultisigSimulation.js → AccountSimulation.js} +20 -20
- package/_esm/tempo/AccountSimulation.js.map +1 -0
- package/_esm/tempo/KeyAuthorization.js +13 -12
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/SignatureEnvelope.js +71 -71
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/Transaction.js +2 -0
- package/_esm/tempo/Transaction.js.map +1 -1
- package/_esm/tempo/TransactionRequest.js +12 -9
- package/_esm/tempo/TransactionRequest.js.map +1 -1
- package/_esm/tempo/index.js +50 -48
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/tempo/{MultisigConfig.d.ts → AccountConfig.d.ts} +110 -63
- package/_types/tempo/AccountConfig.d.ts.map +1 -0
- package/_types/tempo/{MultisigOperation.d.ts → AccountOperation.d.ts} +62 -62
- package/_types/tempo/AccountOperation.d.ts.map +1 -0
- package/_types/tempo/{MultisigSimulation.d.ts → AccountSimulation.d.ts} +21 -21
- package/_types/tempo/AccountSimulation.d.ts.map +1 -0
- package/_types/tempo/KeyAuthorization.d.ts +14 -14
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/RpcSchemaTempo.d.ts +13 -13
- package/_types/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/_types/tempo/SignatureEnvelope.d.ts +36 -33
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/Transaction.d.ts.map +1 -1
- package/_types/tempo/TransactionRequest.d.ts +11 -9
- package/_types/tempo/TransactionRequest.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +50 -48
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/package.json +31 -31
- package/tempo/AccountConfig/package.json +6 -0
- package/tempo/AccountConfig.test-d/package.json +6 -0
- package/tempo/{MultisigConfig.test-d.ts → AccountConfig.test-d.ts} +22 -12
- package/tempo/{MultisigConfig.test.ts → AccountConfig.test.ts} +155 -37
- package/tempo/{MultisigConfig.ts → AccountConfig.ts} +132 -66
- package/tempo/AccountOperation/package.json +6 -0
- package/tempo/AccountOperation.test-d/package.json +6 -0
- package/tempo/AccountOperation.test-d.ts +71 -0
- package/tempo/{MultisigOperation.test.ts → AccountOperation.test.ts} +97 -97
- package/tempo/{MultisigOperation.ts → AccountOperation.ts} +95 -97
- package/tempo/AccountSimulation/package.json +6 -0
- package/tempo/AccountSimulation.test-d/package.json +6 -0
- package/tempo/{MultisigSimulation.test-d.ts → AccountSimulation.test-d.ts} +7 -9
- package/tempo/{MultisigSimulation.test.ts → AccountSimulation.test.ts} +29 -29
- package/tempo/{MultisigSimulation.ts → AccountSimulation.ts} +28 -30
- package/tempo/KeyAuthorization.test-d.ts +14 -14
- package/tempo/KeyAuthorization.test.ts +70 -49
- package/tempo/KeyAuthorization.ts +29 -27
- package/tempo/RpcSchemaTempo.test-d.ts +19 -19
- package/tempo/RpcSchemaTempo.ts +13 -13
- package/tempo/SignatureEnvelope.test-d.ts +7 -7
- package/tempo/SignatureEnvelope.test.ts +34 -34
- package/tempo/SignatureEnvelope.ts +107 -103
- package/tempo/Transaction.test.ts +40 -4
- package/tempo/Transaction.ts +2 -0
- package/tempo/TransactionRequest.test-d.ts +16 -7
- package/tempo/TransactionRequest.test.ts +25 -17
- package/tempo/TransactionRequest.ts +25 -18
- package/tempo/{multisig.e2e.test.ts → configurableAccounts.e2e.test.ts} +16 -16
- package/tempo/index.ts +50 -48
- package/version.ts +1 -1
- package/_cjs/tempo/MultisigConfig.js.map +0 -1
- package/_cjs/tempo/MultisigOperation.js.map +0 -1
- package/_cjs/tempo/MultisigSimulation.js.map +0 -1
- package/_esm/tempo/MultisigConfig.js.map +0 -1
- package/_esm/tempo/MultisigOperation.js.map +0 -1
- package/_esm/tempo/MultisigSimulation.js.map +0 -1
- package/_types/tempo/MultisigConfig.d.ts.map +0 -1
- package/_types/tempo/MultisigOperation.d.ts.map +0 -1
- package/_types/tempo/MultisigSimulation.d.ts.map +0 -1
- package/tempo/MultisigConfig/package.json +0 -6
- package/tempo/MultisigConfig.test-d/package.json +0 -6
- package/tempo/MultisigOperation/package.json +0 -6
- package/tempo/MultisigOperation.test-d/package.json +0 -6
- package/tempo/MultisigOperation.test-d.ts +0 -71
- package/tempo/MultisigSimulation/package.json +0 -6
- package/tempo/MultisigSimulation.test-d/package.json +0 -6
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
WebAuthnP256,
|
|
9
9
|
} from 'ox'
|
|
10
10
|
import { describe, expect, test } from 'vitest'
|
|
11
|
+
import * as AccountConfig from './AccountConfig.js'
|
|
11
12
|
import * as KeyAuthorization from './KeyAuthorization.js'
|
|
12
|
-
import * as MultisigConfig from './MultisigConfig.js'
|
|
13
13
|
import * as Period from './Period.js'
|
|
14
14
|
import * as SignatureEnvelope from './SignatureEnvelope.js'
|
|
15
15
|
|
|
@@ -71,9 +71,9 @@ const signature_webauthn = SignatureEnvelope.from({
|
|
|
71
71
|
},
|
|
72
72
|
})
|
|
73
73
|
|
|
74
|
-
const
|
|
74
|
+
const signature_configurable = {
|
|
75
75
|
account: address,
|
|
76
|
-
config:
|
|
76
|
+
config: AccountConfig.from({
|
|
77
77
|
owners: [
|
|
78
78
|
{
|
|
79
79
|
owner: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
|
|
@@ -84,9 +84,9 @@ const signature_multisig = {
|
|
|
84
84
|
version: 1n,
|
|
85
85
|
}),
|
|
86
86
|
signatures: [SignatureEnvelope.from(signature_secp256k1)],
|
|
87
|
-
type: '
|
|
88
|
-
} as const satisfies SignatureEnvelope.
|
|
89
|
-
const
|
|
87
|
+
type: 'configurable',
|
|
88
|
+
} as const satisfies SignatureEnvelope.Configurable
|
|
89
|
+
const signature_configurable_rpc =
|
|
90
90
|
'0xf89794be95c3f554e9fc85ec51be69a3d807a0d55bcf2cf83ba000000000000000000000000000000000000000000000000000000000000000000101d7d694f39fd6e51aad88f6f4ce6ab8827279cfffb9226601f843b841fa78c5905fb0b9d6066ef531f962a62bc6ef0d5eb59ecb134056d206f75aaed7780926ff2601a935c2c79707d9e1799948c9f19dcdde1e090e903b19a07923d01c' as const
|
|
91
91
|
|
|
92
92
|
const signature_keychain = {
|
|
@@ -95,10 +95,15 @@ const signature_keychain = {
|
|
|
95
95
|
userAddress: address,
|
|
96
96
|
} as const satisfies SignatureEnvelope.Keychain
|
|
97
97
|
|
|
98
|
-
describe('
|
|
98
|
+
describe('configurable account binding', () => {
|
|
99
99
|
test('resolves Tempo account bindings before encoding', () => {
|
|
100
100
|
const signed = KeyAuthorization.from(
|
|
101
|
-
{
|
|
101
|
+
{
|
|
102
|
+
account: `tempox${address}`,
|
|
103
|
+
address,
|
|
104
|
+
chainId: 1n,
|
|
105
|
+
type: 'configurable',
|
|
106
|
+
},
|
|
102
107
|
{ signature: signature_secp256k1 },
|
|
103
108
|
)
|
|
104
109
|
expect(signed.account).toMatchInlineSnapshot(
|
|
@@ -113,36 +118,40 @@ describe('multisig account binding', () => {
|
|
|
113
118
|
})
|
|
114
119
|
|
|
115
120
|
test('rejects unbound grants before signing or encoding', () => {
|
|
116
|
-
const authorization = {
|
|
121
|
+
const authorization = {
|
|
122
|
+
address,
|
|
123
|
+
chainId: 1n,
|
|
124
|
+
type: 'configurable',
|
|
125
|
+
} as const
|
|
117
126
|
const signed = {
|
|
118
127
|
...authorization,
|
|
119
128
|
signature: SignatureEnvelope.from(signature_secp256k1),
|
|
120
129
|
}
|
|
121
130
|
for (const encode of [
|
|
122
|
-
// @ts-expect-error Deliberately unbound
|
|
131
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
123
132
|
() => KeyAuthorization.from(authorization),
|
|
124
|
-
// @ts-expect-error Deliberately unbound
|
|
133
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
125
134
|
() => KeyAuthorization.toTuple(authorization),
|
|
126
|
-
// @ts-expect-error Deliberately unbound
|
|
135
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
127
136
|
() => KeyAuthorization.getSignPayload(authorization),
|
|
128
|
-
// @ts-expect-error Deliberately unbound
|
|
137
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
129
138
|
() => KeyAuthorization.serialize(authorization),
|
|
130
|
-
// @ts-expect-error Deliberately unbound
|
|
139
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
131
140
|
() => KeyAuthorization.toRpc(signed),
|
|
132
141
|
])
|
|
133
142
|
expect(encode).toThrowErrorMatchingInlineSnapshot(
|
|
134
|
-
`[KeyAuthorization.MissingAccountError:
|
|
143
|
+
`[KeyAuthorization.MissingAccountError: Configurable account key grants require a parent account binding.]`,
|
|
135
144
|
)
|
|
136
145
|
})
|
|
137
146
|
|
|
138
147
|
test('rejects unbound RPC and RLP grants', () => {
|
|
139
148
|
const signed = KeyAuthorization.from(
|
|
140
|
-
{ account: address, address, chainId: 1n, type: '
|
|
149
|
+
{ account: address, address, chainId: 1n, type: 'configurable' },
|
|
141
150
|
{ signature: signature_secp256k1 },
|
|
142
151
|
)
|
|
143
152
|
const rpc = KeyAuthorization.toRpc(signed)
|
|
144
153
|
for (const account of [undefined, null]) {
|
|
145
|
-
// @ts-expect-error Deliberately unbound
|
|
154
|
+
// @ts-expect-error Deliberately unbound configurable grant.
|
|
146
155
|
expect(() => KeyAuthorization.fromRpc({ ...rpc, account })).toThrowError(
|
|
147
156
|
KeyAuthorization.MissingAccountError,
|
|
148
157
|
)
|
|
@@ -179,15 +188,15 @@ describe('from', () => {
|
|
|
179
188
|
}).toEqual(limitsVectors)
|
|
180
189
|
})
|
|
181
190
|
|
|
182
|
-
test('accepts
|
|
191
|
+
test('accepts configurable grants and delegates', () => {
|
|
183
192
|
const signed = KeyAuthorization.from(
|
|
184
193
|
{
|
|
185
194
|
address,
|
|
186
195
|
chainId: 1n,
|
|
187
|
-
type: '
|
|
188
|
-
account:
|
|
196
|
+
type: 'configurable',
|
|
197
|
+
account: signature_configurable.account,
|
|
189
198
|
},
|
|
190
|
-
{ signature:
|
|
199
|
+
{ signature: signature_configurable },
|
|
191
200
|
)
|
|
192
201
|
expect(
|
|
193
202
|
KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
|
|
@@ -587,7 +596,7 @@ describe('fromRpc', () => {
|
|
|
587
596
|
`)
|
|
588
597
|
})
|
|
589
598
|
|
|
590
|
-
test('with signature (
|
|
599
|
+
test('with signature (configurable)', () => {
|
|
591
600
|
const authorization = KeyAuthorization.from({
|
|
592
601
|
address,
|
|
593
602
|
chainId: 1n,
|
|
@@ -595,20 +604,20 @@ describe('fromRpc', () => {
|
|
|
595
604
|
})
|
|
596
605
|
|
|
597
606
|
const signed = KeyAuthorization.from(authorization, {
|
|
598
|
-
signature:
|
|
607
|
+
signature: signature_configurable,
|
|
599
608
|
})
|
|
600
|
-
expect(signed.signature).toEqual(
|
|
609
|
+
expect(signed.signature).toEqual(signature_configurable)
|
|
601
610
|
expect(
|
|
602
611
|
KeyAuthorization.from(authorization, {
|
|
603
|
-
signature: SignatureEnvelope.serialize(
|
|
612
|
+
signature: SignatureEnvelope.serialize(signature_configurable),
|
|
604
613
|
}).signature,
|
|
605
|
-
).toEqual(
|
|
614
|
+
).toEqual(signature_configurable)
|
|
606
615
|
expect(
|
|
607
616
|
KeyAuthorization.from({
|
|
608
617
|
...authorization,
|
|
609
|
-
signature:
|
|
618
|
+
signature: signature_configurable,
|
|
610
619
|
}).signature,
|
|
611
|
-
).toEqual(
|
|
620
|
+
).toEqual(signature_configurable)
|
|
612
621
|
expect(
|
|
613
622
|
KeyAuthorization.deserialize(KeyAuthorization.serialize(signed)),
|
|
614
623
|
).toEqual(signed)
|
|
@@ -626,7 +635,7 @@ describe('fromRpc', () => {
|
|
|
626
635
|
signature: signature_keychain as never,
|
|
627
636
|
}),
|
|
628
637
|
).toThrowErrorMatchingInlineSnapshot(
|
|
629
|
-
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`
|
|
638
|
+
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
|
|
630
639
|
)
|
|
631
640
|
|
|
632
641
|
expect(() =>
|
|
@@ -634,7 +643,7 @@ describe('fromRpc', () => {
|
|
|
634
643
|
signature: SignatureEnvelope.serialize(signature_keychain),
|
|
635
644
|
}),
|
|
636
645
|
).toThrowErrorMatchingInlineSnapshot(
|
|
637
|
-
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`
|
|
646
|
+
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
|
|
638
647
|
)
|
|
639
648
|
|
|
640
649
|
expect(() =>
|
|
@@ -643,19 +652,19 @@ describe('fromRpc', () => {
|
|
|
643
652
|
signature: signature_keychain,
|
|
644
653
|
} as never),
|
|
645
654
|
).toThrowErrorMatchingInlineSnapshot(
|
|
646
|
-
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`
|
|
655
|
+
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
|
|
647
656
|
)
|
|
648
657
|
})
|
|
649
658
|
})
|
|
650
659
|
|
|
651
660
|
describe('fromRpc', () => {
|
|
652
|
-
test('behavior:
|
|
661
|
+
test('behavior: configurable', () => {
|
|
653
662
|
const authorization = KeyAuthorization.fromRpc({
|
|
654
663
|
chainId: '0x1',
|
|
655
664
|
expiry: null,
|
|
656
665
|
keyId: address,
|
|
657
666
|
keyType: 'secp256k1',
|
|
658
|
-
signature:
|
|
667
|
+
signature: signature_configurable_rpc,
|
|
659
668
|
})
|
|
660
669
|
|
|
661
670
|
expect(authorization.signature).toMatchInlineSnapshot(`
|
|
@@ -682,7 +691,7 @@ describe('fromRpc', () => {
|
|
|
682
691
|
"type": "secp256k1",
|
|
683
692
|
},
|
|
684
693
|
],
|
|
685
|
-
"type": "
|
|
694
|
+
"type": "configurable",
|
|
686
695
|
}
|
|
687
696
|
`)
|
|
688
697
|
})
|
|
@@ -697,7 +706,7 @@ describe('fromRpc', () => {
|
|
|
697
706
|
signature: SignatureEnvelope.toRpc(signature_keychain),
|
|
698
707
|
} as never),
|
|
699
708
|
).toThrowErrorMatchingInlineSnapshot(
|
|
700
|
-
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`
|
|
709
|
+
`[KeyAuthorization.InvalidSignatureTypeError: Signature type \`keychain\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.]`,
|
|
701
710
|
)
|
|
702
711
|
})
|
|
703
712
|
|
|
@@ -934,13 +943,13 @@ describe('fromTuple', () => {
|
|
|
934
943
|
`)
|
|
935
944
|
})
|
|
936
945
|
|
|
937
|
-
test('
|
|
946
|
+
test('configurable', () => {
|
|
938
947
|
const authorization = KeyAuthorization.fromTuple([
|
|
939
948
|
['0x1', '0x', address],
|
|
940
|
-
SignatureEnvelope.serialize(
|
|
949
|
+
SignatureEnvelope.serialize(signature_configurable),
|
|
941
950
|
])
|
|
942
951
|
|
|
943
|
-
expect(authorization.signature).toEqual(
|
|
952
|
+
expect(authorization.signature).toEqual(signature_configurable)
|
|
944
953
|
})
|
|
945
954
|
|
|
946
955
|
test('default', () => {
|
|
@@ -1280,7 +1289,7 @@ describe('getSignPayload', () => {
|
|
|
1280
1289
|
})
|
|
1281
1290
|
|
|
1282
1291
|
describe('deserialize', () => {
|
|
1283
|
-
test('example: matches the frozen
|
|
1292
|
+
test('example: matches the frozen configurable witness vector', () => {
|
|
1284
1293
|
const serialized =
|
|
1285
1294
|
'0xf8f1f85382107980941eff47bc3a10a45d4b230b5d10e37751fe6aa718808080a053535353535353535353535353535353535353535353535353535353535353538094c4a590afa7337e5cd5eb3aa60cacf91c5400044bb89a05f89794c4a590afa7337e5cd5eb3aa60cacf91c5400044bf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d6947e5f4552091a69125d5dfcb7b8c2659029395bdf01f843b8412cfed9350faf80e4115e3c4c967356b80a8e6ee42e4a49ab953c8c8a3537d8d8359bf035a9bea18f32b0da7129cdce3ce701abc09ad8919b93da21a0d57e21451b' as const
|
|
1286
1295
|
const authorization = KeyAuthorization.deserialize(serialized)
|
|
@@ -1313,7 +1322,7 @@ describe('deserialize', () => {
|
|
|
1313
1322
|
"type": "secp256k1",
|
|
1314
1323
|
},
|
|
1315
1324
|
],
|
|
1316
|
-
"type": "
|
|
1325
|
+
"type": "configurable",
|
|
1317
1326
|
},
|
|
1318
1327
|
"type": "secp256k1",
|
|
1319
1328
|
"witness": "0x5353535353535353535353535353535353535353535353535353535353535353",
|
|
@@ -1322,14 +1331,14 @@ describe('deserialize', () => {
|
|
|
1322
1331
|
expect(KeyAuthorization.serialize(authorization)).toBe(serialized)
|
|
1323
1332
|
})
|
|
1324
1333
|
|
|
1325
|
-
test('
|
|
1334
|
+
test('configurable', () => {
|
|
1326
1335
|
const serialized = Rlp.fromHex([
|
|
1327
1336
|
['0x1', '0x', address],
|
|
1328
|
-
SignatureEnvelope.serialize(
|
|
1337
|
+
SignatureEnvelope.serialize(signature_configurable),
|
|
1329
1338
|
])
|
|
1330
1339
|
|
|
1331
1340
|
expect(KeyAuthorization.deserialize(serialized).signature).toEqual(
|
|
1332
|
-
|
|
1341
|
+
signature_configurable,
|
|
1333
1342
|
)
|
|
1334
1343
|
})
|
|
1335
1344
|
|
|
@@ -1503,16 +1512,28 @@ describe('serialize', () => {
|
|
|
1503
1512
|
})
|
|
1504
1513
|
|
|
1505
1514
|
describe('toRpc', () => {
|
|
1506
|
-
test('behavior: multisig', () => {
|
|
1515
|
+
test('behavior: configurable key type uses the RPC multisig key type', () => {
|
|
1516
|
+
const authorization = KeyAuthorization.from(
|
|
1517
|
+
{ account: address, address, chainId: 1n, type: 'configurable' },
|
|
1518
|
+
{ signature: signature_secp256k1 },
|
|
1519
|
+
)
|
|
1520
|
+
const rpc = KeyAuthorization.toRpc(authorization)
|
|
1521
|
+
expect(rpc.keyType).toMatchInlineSnapshot(`"multisig"`)
|
|
1522
|
+
expect(KeyAuthorization.fromRpc(rpc).type).toMatchInlineSnapshot(
|
|
1523
|
+
`"configurable"`,
|
|
1524
|
+
)
|
|
1525
|
+
})
|
|
1526
|
+
|
|
1527
|
+
test('behavior: configurable', () => {
|
|
1507
1528
|
const authorization = KeyAuthorization.toRpc({
|
|
1508
1529
|
address,
|
|
1509
1530
|
chainId: 1n,
|
|
1510
|
-
signature:
|
|
1531
|
+
signature: signature_configurable,
|
|
1511
1532
|
type: 'secp256k1',
|
|
1512
1533
|
})
|
|
1513
1534
|
|
|
1514
1535
|
expect(authorization.signature).toMatchInlineSnapshot(
|
|
1515
|
-
`"${
|
|
1536
|
+
`"${signature_configurable_rpc}"`,
|
|
1516
1537
|
)
|
|
1517
1538
|
})
|
|
1518
1539
|
|
|
@@ -1783,15 +1804,15 @@ describe('toTuple', () => {
|
|
|
1783
1804
|
}
|
|
1784
1805
|
})
|
|
1785
1806
|
|
|
1786
|
-
test('
|
|
1807
|
+
test('configurable', () => {
|
|
1787
1808
|
const tuple = KeyAuthorization.toTuple({
|
|
1788
1809
|
address,
|
|
1789
1810
|
chainId: 1n,
|
|
1790
|
-
signature:
|
|
1811
|
+
signature: signature_configurable,
|
|
1791
1812
|
type: 'secp256k1',
|
|
1792
1813
|
})
|
|
1793
1814
|
|
|
1794
|
-
expect(tuple[1]).toBe(SignatureEnvelope.serialize(
|
|
1815
|
+
expect(tuple[1]).toBe(SignatureEnvelope.serialize(signature_configurable))
|
|
1795
1816
|
})
|
|
1796
1817
|
|
|
1797
1818
|
test('default', () => {
|
|
@@ -29,7 +29,7 @@ import * as TempoAddress from './TempoAddress.js'
|
|
|
29
29
|
* - `chainId`: Chain ID for replay protection (0 = valid on any chain)
|
|
30
30
|
* - `expiry`: Unix timestamp when the key expires (undefined = never expires)
|
|
31
31
|
* - `limits`: Per-TIP-20 token spending limits (only applies to `transfer()` and `approve()` calls)
|
|
32
|
-
* - `type`: Key type (`secp256k1`, `p256`, `webAuthn`, or `
|
|
32
|
+
* - `type`: Key type (`secp256k1`, `p256`, `webAuthn`, or `configurable`)
|
|
33
33
|
*
|
|
34
34
|
* [Access Keys Specification](https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction#access-keys)
|
|
35
35
|
*/
|
|
@@ -83,33 +83,33 @@ export type KeyAuthorization<
|
|
|
83
83
|
type: SignatureEnvelope.Type
|
|
84
84
|
}
|
|
85
85
|
| {
|
|
86
|
-
/** Required parent account binding for a
|
|
86
|
+
/** Required parent account binding for a configurable account grant. */
|
|
87
87
|
account: addressType
|
|
88
|
-
/**
|
|
89
|
-
type: '
|
|
88
|
+
/** Configurable account key type. */
|
|
89
|
+
type: 'configurable'
|
|
90
90
|
}
|
|
91
91
|
) &
|
|
92
92
|
(signed extends true
|
|
93
93
|
? {
|
|
94
94
|
signature:
|
|
95
95
|
| SignatureEnvelope.Primitive<bigintType, numberType>
|
|
96
|
-
| SignatureEnvelope.
|
|
96
|
+
| SignatureEnvelope.Configurable<bigintType, numberType>
|
|
97
97
|
}
|
|
98
98
|
: {
|
|
99
99
|
signature?:
|
|
100
100
|
| SignatureEnvelope.Primitive<bigintType, numberType>
|
|
101
|
-
| SignatureEnvelope.
|
|
101
|
+
| SignatureEnvelope.Configurable<bigintType, numberType>
|
|
102
102
|
| undefined
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
/** Signature that can authorize an access key. */
|
|
106
106
|
export type Signature<bigintType = bigint, numberType = number> =
|
|
107
107
|
| SignatureEnvelope.Primitive<bigintType, numberType>
|
|
108
|
-
| SignatureEnvelope.
|
|
108
|
+
| SignatureEnvelope.Configurable<bigintType, numberType>
|
|
109
109
|
|
|
110
110
|
/** RPC-formatted signature that can authorize an access key. */
|
|
111
111
|
export type SignatureRpc =
|
|
112
|
-
| SignatureEnvelope.
|
|
112
|
+
| SignatureEnvelope.ConfigurableRpc
|
|
113
113
|
| SignatureEnvelope.PrimitiveRpc
|
|
114
114
|
|
|
115
115
|
/** Input type for a Key Authorization. */
|
|
@@ -146,9 +146,9 @@ export type Rpc = {
|
|
|
146
146
|
keyType: SignatureEnvelope.Type
|
|
147
147
|
}
|
|
148
148
|
| {
|
|
149
|
-
/** Required parent account binding for a
|
|
149
|
+
/** Required parent account binding for a configurable account grant. */
|
|
150
150
|
account: Address.Address
|
|
151
|
-
/**
|
|
151
|
+
/** Configurable account key type, named `multisig` by the node. */
|
|
152
152
|
keyType: 'multisig'
|
|
153
153
|
}
|
|
154
154
|
)
|
|
@@ -180,9 +180,9 @@ export type Signed<
|
|
|
180
180
|
> = KeyAuthorization<true, bigintType, numberType, addressType>
|
|
181
181
|
|
|
182
182
|
type SignatureValue =
|
|
183
|
-
| SignatureEnvelope.from.
|
|
183
|
+
| SignatureEnvelope.from.ConfigurableFromConfig
|
|
184
184
|
| UnionPartialBy<SignatureEnvelope.Primitive, 'prehash' | 'type'>
|
|
185
|
-
| PartialBy<SignatureEnvelope.
|
|
185
|
+
| PartialBy<SignatureEnvelope.Configurable, 'type'>
|
|
186
186
|
| SignatureEnvelope.Secp256k1Flat
|
|
187
187
|
| SignatureEnvelope.Serialized
|
|
188
188
|
|
|
@@ -508,11 +508,11 @@ export declare namespace from {
|
|
|
508
508
|
type Options<
|
|
509
509
|
signature extends SignatureValue | undefined = SignatureValue | undefined,
|
|
510
510
|
> = {
|
|
511
|
-
/** The primitive or
|
|
511
|
+
/** The primitive or configurable account signature to attach to the Key Authorization. */
|
|
512
512
|
signature?:
|
|
513
513
|
| signature
|
|
514
514
|
| SignatureEnvelope.Primitive
|
|
515
|
-
| SignatureEnvelope.
|
|
515
|
+
| SignatureEnvelope.Configurable
|
|
516
516
|
| undefined
|
|
517
517
|
}
|
|
518
518
|
|
|
@@ -572,7 +572,8 @@ export function fromRpc(authorization: Rpc): Signed {
|
|
|
572
572
|
const witness = authorization.witness ?? undefined
|
|
573
573
|
const isAdmin = authorization.isAdmin ?? undefined
|
|
574
574
|
const account = authorization.account ?? undefined
|
|
575
|
-
|
|
575
|
+
const type = keyType === 'multisig' ? 'configurable' : keyType
|
|
576
|
+
assertAccountBinding(type, account)
|
|
576
577
|
const signature = SignatureEnvelope.fromRpc(authorization.signature)
|
|
577
578
|
assertSignature(signature)
|
|
578
579
|
if (witness !== undefined) assertWitness(witness)
|
|
@@ -607,9 +608,7 @@ export function fromRpc(authorization: Rpc): Signed {
|
|
|
607
608
|
})),
|
|
608
609
|
...(scopes ? { scopes } : {}),
|
|
609
610
|
signature,
|
|
610
|
-
...(
|
|
611
|
-
? { account: account!, type: keyType }
|
|
612
|
-
: { type: keyType }),
|
|
611
|
+
...(type === 'configurable' ? { account: account!, type } : { type }),
|
|
613
612
|
...(witness !== undefined ? { witness } : {}),
|
|
614
613
|
...(account !== undefined ? { account } : {}),
|
|
615
614
|
...(isAdmin ? { isAdmin: true as const } : {}),
|
|
@@ -683,7 +682,7 @@ export function fromTuple<const tuple extends Tuple>(
|
|
|
683
682
|
case '0x02':
|
|
684
683
|
return 'webAuthn'
|
|
685
684
|
case '0x03':
|
|
686
|
-
return '
|
|
685
|
+
return 'configurable'
|
|
687
686
|
default:
|
|
688
687
|
throw new Error(`Invalid key type: ${keyType_hex}`)
|
|
689
688
|
}
|
|
@@ -744,7 +743,7 @@ export function fromTuple<const tuple extends Tuple>(
|
|
|
744
743
|
const args: KeyAuthorization = {
|
|
745
744
|
address: keyId,
|
|
746
745
|
chainId: chainId === '0x' ? 0n : Hex.toBigInt(chainId),
|
|
747
|
-
...(keyType === '
|
|
746
|
+
...(keyType === 'configurable'
|
|
748
747
|
? { account: account!, type: keyType }
|
|
749
748
|
: { type: keyType }),
|
|
750
749
|
...(expiry !== undefined ? { expiry } : {}),
|
|
@@ -1006,7 +1005,9 @@ export function toRpc(authorization: Signed): Rpc {
|
|
|
1006
1005
|
chainId: chainId === 0n ? '0x' : Hex.fromNumber(chainId),
|
|
1007
1006
|
expiry: typeof expiry === 'number' ? Hex.fromNumber(expiry) : null,
|
|
1008
1007
|
keyId: TempoAddress.resolve(address),
|
|
1009
|
-
...(type === '
|
|
1008
|
+
...(type === 'configurable'
|
|
1009
|
+
? { account, keyType: 'multisig' as const }
|
|
1010
|
+
: { keyType: type }),
|
|
1010
1011
|
limits: limits?.map(({ token, limit, period }) => ({
|
|
1011
1012
|
token,
|
|
1012
1013
|
limit: Hex.fromNumber(limit),
|
|
@@ -1014,7 +1015,7 @@ export function toRpc(authorization: Signed): Rpc {
|
|
|
1014
1015
|
})),
|
|
1015
1016
|
signature: SignatureEnvelope.toRpc(signature) as
|
|
1016
1017
|
| SignatureEnvelope.PrimitiveRpc
|
|
1017
|
-
| SignatureEnvelope.
|
|
1018
|
+
| SignatureEnvelope.ConfigurableRpc,
|
|
1018
1019
|
...(allowedCalls ? { allowedCalls } : {}),
|
|
1019
1020
|
...(witness !== undefined ? { witness } : {}),
|
|
1020
1021
|
...(isAdmin ? { isAdmin: true } : {}),
|
|
@@ -1089,7 +1090,7 @@ export function toTuple<const authorization extends KeyAuthorization>(
|
|
|
1089
1090
|
return '0x01'
|
|
1090
1091
|
case 'webAuthn':
|
|
1091
1092
|
return '0x02'
|
|
1092
|
-
case '
|
|
1093
|
+
case 'configurable':
|
|
1093
1094
|
return '0x03'
|
|
1094
1095
|
default:
|
|
1095
1096
|
throw new Error(`Invalid key type: ${keyType}`)
|
|
@@ -1213,7 +1214,8 @@ function assertAccountBinding(
|
|
|
1213
1214
|
type: KeyAuthorization['type'],
|
|
1214
1215
|
account: TempoAddress.Address | null | undefined,
|
|
1215
1216
|
): void {
|
|
1216
|
-
if (type === '
|
|
1217
|
+
if (type === 'configurable' && account == null)
|
|
1218
|
+
throw new MissingAccountError()
|
|
1217
1219
|
}
|
|
1218
1220
|
|
|
1219
1221
|
function assertWitness(witness: Hex.Hex): void {
|
|
@@ -1256,15 +1258,15 @@ export class InvalidSignatureTypeError extends Error {
|
|
|
1256
1258
|
override readonly name = 'KeyAuthorization.InvalidSignatureTypeError'
|
|
1257
1259
|
constructor(type: SignatureEnvelope.SignatureEnvelope['type']) {
|
|
1258
1260
|
super(
|
|
1259
|
-
`Signature type \`${type}\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`
|
|
1261
|
+
`Signature type \`${type}\` is invalid for key authorizations; expected \`secp256k1\`, \`p256\`, \`webAuthn\`, or \`configurable\`.`,
|
|
1260
1262
|
)
|
|
1261
1263
|
}
|
|
1262
1264
|
}
|
|
1263
1265
|
|
|
1264
|
-
/** Thrown when a
|
|
1266
|
+
/** Thrown when a configurable account key grant omits its parent account binding. */
|
|
1265
1267
|
export class MissingAccountError extends Error {
|
|
1266
1268
|
override readonly name = 'KeyAuthorization.MissingAccountError'
|
|
1267
1269
|
constructor() {
|
|
1268
|
-
super('
|
|
1270
|
+
super('Configurable account key grants require a parent account binding.')
|
|
1269
1271
|
}
|
|
1270
1272
|
}
|
|
@@ -1,76 +1,76 @@
|
|
|
1
1
|
import type { Provider } from 'ox'
|
|
2
2
|
import type {
|
|
3
|
+
AccountConfig,
|
|
4
|
+
AccountOperation,
|
|
5
|
+
AccountSimulation,
|
|
3
6
|
KeyAuthorization,
|
|
4
|
-
MultisigConfig,
|
|
5
|
-
MultisigOperation,
|
|
6
|
-
MultisigSimulation,
|
|
7
7
|
RpcSchemaTempo,
|
|
8
8
|
} from 'ox/tempo'
|
|
9
9
|
import { expectTypeOf, test } from 'vitest'
|
|
10
10
|
import type * as Address from '../core/Address.js'
|
|
11
11
|
import type * as Hex from '../core/Hex.js'
|
|
12
12
|
|
|
13
|
-
declare const provider: Provider.Provider<{ schema: RpcSchemaTempo.
|
|
13
|
+
declare const provider: Provider.Provider<{ schema: RpcSchemaTempo.Account }>
|
|
14
14
|
declare const tempoProvider: Provider.Provider<{
|
|
15
15
|
schema: RpcSchemaTempo.Tempo
|
|
16
16
|
}>
|
|
17
17
|
declare const address: Address.Address
|
|
18
18
|
declare const hash: Hex.Hex
|
|
19
19
|
declare const keyAuthorization: KeyAuthorization.Rpc
|
|
20
|
-
declare const multisigSimulation:
|
|
20
|
+
declare const multisigSimulation: AccountSimulation.Rpc
|
|
21
21
|
declare const serializedTransaction: Hex.Hex
|
|
22
22
|
declare const signature: Hex.Hex
|
|
23
23
|
|
|
24
|
-
test('
|
|
24
|
+
test('account provider methods', () => {
|
|
25
25
|
expectTypeOf(
|
|
26
26
|
provider.request({
|
|
27
|
-
method: '
|
|
27
|
+
method: 'account_approveRawTransaction',
|
|
28
28
|
params: [serializedTransaction],
|
|
29
29
|
}),
|
|
30
30
|
).resolves.toEqualTypeOf<Hex.Hex>()
|
|
31
31
|
|
|
32
32
|
expectTypeOf(
|
|
33
33
|
provider.request({
|
|
34
|
-
method: '
|
|
34
|
+
method: 'account_approveRawTransactionSync',
|
|
35
35
|
params: [serializedTransaction],
|
|
36
36
|
}),
|
|
37
|
-
).resolves.toEqualTypeOf<
|
|
37
|
+
).resolves.toEqualTypeOf<AccountOperation.TransactionRpc>()
|
|
38
38
|
|
|
39
39
|
provider.request({
|
|
40
|
-
method: '
|
|
40
|
+
method: 'account_approveRawTransactionSync',
|
|
41
41
|
params: [serializedTransaction, 30_000],
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
expectTypeOf(
|
|
45
45
|
provider.request({
|
|
46
|
-
method: '
|
|
46
|
+
method: 'account_approveKeyAuthorization',
|
|
47
47
|
params: [{ keyAuthorization }],
|
|
48
48
|
}),
|
|
49
|
-
).resolves.toEqualTypeOf<
|
|
49
|
+
).resolves.toEqualTypeOf<AccountOperation.KeyAuthorizationRpc>()
|
|
50
50
|
|
|
51
51
|
expectTypeOf(
|
|
52
52
|
provider.request({
|
|
53
|
-
method: '
|
|
53
|
+
method: 'account_approveKeyAuthorization',
|
|
54
54
|
params: [{ hash, signature }],
|
|
55
55
|
}),
|
|
56
|
-
).resolves.toEqualTypeOf<
|
|
56
|
+
).resolves.toEqualTypeOf<AccountOperation.KeyAuthorizationRpc>()
|
|
57
57
|
|
|
58
58
|
expectTypeOf(
|
|
59
59
|
provider.request({
|
|
60
|
-
method: '
|
|
60
|
+
method: 'account_getConfig',
|
|
61
61
|
params: [{ address }],
|
|
62
62
|
}),
|
|
63
|
-
).resolves.toEqualTypeOf<
|
|
63
|
+
).resolves.toEqualTypeOf<AccountConfig.Rpc | null>()
|
|
64
64
|
|
|
65
65
|
expectTypeOf(
|
|
66
66
|
provider.request({
|
|
67
|
-
method: '
|
|
67
|
+
method: 'account_getOperation',
|
|
68
68
|
params: [hash],
|
|
69
69
|
}),
|
|
70
|
-
).resolves.toEqualTypeOf<
|
|
70
|
+
).resolves.toEqualTypeOf<AccountOperation.Rpc | null>()
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
test('tempo simulation accepts
|
|
73
|
+
test('tempo simulation accepts account simulation specs', () => {
|
|
74
74
|
tempoProvider.request({
|
|
75
75
|
method: 'tempo_simulateV1',
|
|
76
76
|
params: [
|
package/tempo/RpcSchemaTempo.ts
CHANGED
|
@@ -5,9 +5,9 @@ import type * as Hex from '../core/Hex.js'
|
|
|
5
5
|
import type * as Log from '../core/Log.js'
|
|
6
6
|
import type * as RpcSchema from '../core/RpcSchema.js'
|
|
7
7
|
import type * as StateOverrides from '../core/StateOverrides.js'
|
|
8
|
+
import type * as AccountConfig from './AccountConfig.js'
|
|
9
|
+
import type * as AccountOperation from './AccountOperation.js'
|
|
8
10
|
import type * as KeyAuthorization from './KeyAuthorization.js'
|
|
9
|
-
import type * as MultisigConfig from './MultisigConfig.js'
|
|
10
|
-
import type * as MultisigOperation from './MultisigOperation.js'
|
|
11
11
|
import type * as TransactionRequest from './TransactionRequest.js'
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -58,44 +58,44 @@ export type Tempo = RpcSchema.From<{
|
|
|
58
58
|
}
|
|
59
59
|
}>
|
|
60
60
|
|
|
61
|
-
/** Union of all JSON-RPC methods for the `
|
|
62
|
-
export type
|
|
61
|
+
/** Union of all JSON-RPC methods for the `account_` namespace. */
|
|
62
|
+
export type Account = RpcSchema.From<
|
|
63
63
|
| {
|
|
64
64
|
Request: {
|
|
65
|
-
method: '
|
|
65
|
+
method: 'account_approveRawTransaction'
|
|
66
66
|
params: [serializedTransaction: Hex.Hex]
|
|
67
67
|
}
|
|
68
68
|
ReturnType: Hex.Hex
|
|
69
69
|
}
|
|
70
70
|
| {
|
|
71
71
|
Request: {
|
|
72
|
-
method: '
|
|
72
|
+
method: 'account_approveRawTransactionSync'
|
|
73
73
|
params: [serializedTransaction: Hex.Hex, timeout?: number]
|
|
74
74
|
}
|
|
75
|
-
ReturnType:
|
|
75
|
+
ReturnType: AccountOperation.TransactionRpc
|
|
76
76
|
}
|
|
77
77
|
| {
|
|
78
78
|
Request: {
|
|
79
|
-
method: '
|
|
79
|
+
method: 'account_approveKeyAuthorization'
|
|
80
80
|
params: [
|
|
81
81
|
| { keyAuthorization: KeyAuthorization.Rpc }
|
|
82
82
|
| { hash: Hex.Hex; signature: Hex.Hex },
|
|
83
83
|
]
|
|
84
84
|
}
|
|
85
|
-
ReturnType:
|
|
85
|
+
ReturnType: AccountOperation.KeyAuthorizationRpc
|
|
86
86
|
}
|
|
87
87
|
| {
|
|
88
88
|
Request: {
|
|
89
|
-
method: '
|
|
89
|
+
method: 'account_getConfig'
|
|
90
90
|
params: [{ address: Address.Address }]
|
|
91
91
|
}
|
|
92
|
-
ReturnType:
|
|
92
|
+
ReturnType: AccountConfig.Rpc | null
|
|
93
93
|
}
|
|
94
94
|
| {
|
|
95
95
|
Request: {
|
|
96
|
-
method: '
|
|
96
|
+
method: 'account_getOperation'
|
|
97
97
|
params: [hash: Hex.Hex]
|
|
98
98
|
}
|
|
99
|
-
ReturnType:
|
|
99
|
+
ReturnType: AccountOperation.Rpc | null
|
|
100
100
|
}
|
|
101
101
|
>
|