ox 1.7.2 → 1.7.5
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 +43 -0
- package/dist/core/AbiEvent.d.ts.map +1 -1
- package/dist/core/AbiEvent.js +10 -9
- package/dist/core/AbiEvent.js.map +1 -1
- package/dist/core/Blobs.d.ts.map +1 -1
- package/dist/core/Blobs.js +6 -2
- package/dist/core/Blobs.js.map +1 -1
- package/dist/core/Signature.d.ts +6 -5
- package/dist/core/Signature.d.ts.map +1 -1
- package/dist/core/Signature.js +17 -7
- package/dist/core/Signature.js.map +1 -1
- package/dist/core/Siwe.d.ts.map +1 -1
- package/dist/core/Siwe.js +21 -1
- package/dist/core/Siwe.js.map +1 -1
- package/dist/tempo/KeyAuthorization.d.ts +43 -39
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +24 -4
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +18 -15
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +49 -20
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/MultisigOperation.d.ts +45 -28
- package/dist/tempo/MultisigOperation.d.ts.map +1 -1
- package/dist/tempo/MultisigOperation.js +81 -131
- package/dist/tempo/MultisigOperation.js.map +1 -1
- package/dist/tempo/MultisigSimulation.d.ts +85 -0
- package/dist/tempo/MultisigSimulation.d.ts.map +1 -0
- package/dist/tempo/MultisigSimulation.js +112 -0
- package/dist/tempo/MultisigSimulation.js.map +1 -0
- package/dist/tempo/RpcSchemaTempo.d.ts +20 -10
- package/dist/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +74 -153
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +130 -187
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/TransactionRequest.d.ts +9 -7
- package/dist/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/tempo/TransactionRequest.js +12 -7
- package/dist/tempo/TransactionRequest.js.map +1 -1
- package/dist/tempo/index.d.ts +7 -5
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +7 -5
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +360 -140
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +247 -487
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.js +29 -31
- package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
- package/dist/zod/tempo/MultisigOperation.d.ts +0 -10
- package/dist/zod/tempo/MultisigOperation.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigOperation.js +0 -3
- package/dist/zod/tempo/MultisigOperation.js.map +1 -1
- package/dist/zod/tempo/MultisigSimulation.d.ts +52 -0
- package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -0
- package/dist/zod/tempo/MultisigSimulation.js +44 -0
- package/dist/zod/tempo/MultisigSimulation.js.map +1 -0
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +357 -422
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.js +19 -10
- package/dist/zod/tempo/RpcSchemaTempo.js.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +108 -42
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +21 -19
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +678 -666
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +580 -619
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +18 -10
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +327 -213
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +105 -3
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
- package/dist/zod/tempo/z.d.ts +1 -1
- package/dist/zod/tempo/z.d.ts.map +1 -1
- package/dist/zod/tempo/z.js +1 -1
- package/dist/zod/tempo/z.js.map +1 -1
- package/package.json +9 -9
- package/src/core/AbiEvent.ts +11 -9
- package/src/core/Blobs.ts +6 -2
- package/src/core/Signature.ts +41 -11
- package/src/core/Siwe.ts +20 -1
- package/src/core/_test/AbiEvent.test.ts +45 -0
- package/src/core/_test/Blobs.test.ts +22 -0
- package/src/core/_test/Signature.test.ts +166 -0
- package/src/core/_test/Siwe.test.ts +100 -1
- package/src/tempo/AuthorizationTempo.test.ts +8 -0
- package/src/tempo/KeyAuthorization.test-d.ts +16 -74
- package/src/tempo/KeyAuthorization.test.ts +113 -14
- package/src/tempo/KeyAuthorization.ts +110 -66
- package/src/tempo/MultisigConfig.test.ts +44 -20
- package/src/tempo/MultisigConfig.ts +65 -23
- package/src/tempo/MultisigOperation.test-d.ts +8 -6
- package/src/tempo/MultisigOperation.test.ts +187 -591
- package/src/tempo/MultisigOperation.ts +129 -205
- package/src/tempo/MultisigSimulation.test-d.ts +33 -0
- package/src/tempo/MultisigSimulation.test.ts +194 -0
- package/src/tempo/MultisigSimulation.ts +192 -0
- package/src/tempo/RpcSchemaTempo.test-d.ts +45 -10
- package/src/tempo/RpcSchemaTempo.ts +15 -6
- package/src/tempo/SignatureEnvelope.test-d.ts +27 -101
- package/src/tempo/SignatureEnvelope.test.ts +330 -533
- package/src/tempo/SignatureEnvelope.ts +198 -310
- package/src/tempo/Transaction.test.ts +61 -0
- package/src/tempo/TransactionRequest.test-d.ts +7 -7
- package/src/tempo/TransactionRequest.test.ts +81 -223
- package/src/tempo/TransactionRequest.ts +34 -13
- package/src/tempo/index.ts +7 -5
- package/src/tempo/multisig.e2e.test.ts +329 -818
- package/src/version.ts +1 -1
- package/src/zod/tempo/KeyAuthorization.ts +50 -39
- package/src/zod/tempo/MultisigOperation.ts +0 -3
- package/src/zod/tempo/MultisigSimulation.ts +53 -0
- package/src/zod/tempo/RpcSchemaTempo.ts +20 -10
- package/src/zod/tempo/SignatureEnvelope.ts +46 -59
- package/src/zod/tempo/TransactionRequest.ts +28 -14
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +66 -30
- package/src/zod/tempo/_test/MultisigOperation.test.ts +0 -2
- package/src/zod/tempo/_test/MultisigSimulation.test-d.ts +13 -0
- package/src/zod/tempo/_test/MultisigSimulation.test.ts +53 -0
- package/src/zod/tempo/_test/RpcSchemaTempo.test-d.ts +19 -2
- package/src/zod/tempo/_test/RpcSchemaTempo.test.ts +46 -4
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +108 -129
- package/src/zod/tempo/_test/TransactionRequest.test.ts +17 -168
- package/src/zod/tempo/z.ts +1 -1
- package/dist/tempo/MultisigWitness.d.ts +0 -106
- package/dist/tempo/MultisigWitness.d.ts.map +0 -1
- package/dist/tempo/MultisigWitness.js +0 -118
- package/dist/tempo/MultisigWitness.js.map +0 -1
- package/dist/zod/tempo/MultisigWitness.d.ts +0 -152
- package/dist/zod/tempo/MultisigWitness.d.ts.map +0 -1
- package/dist/zod/tempo/MultisigWitness.js +0 -76
- package/dist/zod/tempo/MultisigWitness.js.map +0 -1
- package/src/tempo/MultisigWitness.test-d.ts +0 -42
- package/src/tempo/MultisigWitness.test.ts +0 -288
- package/src/tempo/MultisigWitness.ts +0 -210
- package/src/zod/tempo/MultisigWitness.ts +0 -101
- package/src/zod/tempo/_test/MultisigWitness.test-d.ts +0 -13
- package/src/zod/tempo/_test/MultisigWitness.test.ts +0 -149
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
IsNarrowable,
|
|
9
9
|
OneOf,
|
|
10
10
|
PartialBy,
|
|
11
|
-
Undefined,
|
|
12
11
|
UnionPartialBy,
|
|
13
12
|
} from '../core/internal/types.js'
|
|
14
13
|
import * as Json from '../core/Json.js'
|
|
@@ -28,15 +27,6 @@ const serializedKeychainType = '0x03'
|
|
|
28
27
|
const serializedKeychainV2Type = '0x04'
|
|
29
28
|
const serializedMultisigType = '0x05'
|
|
30
29
|
|
|
31
|
-
type NonMultisig<numberType = number> = OneOf<
|
|
32
|
-
| Secp256k1<numberType>
|
|
33
|
-
| P256<numberType>
|
|
34
|
-
| WebAuthn<numberType>
|
|
35
|
-
| Keychain<numberType>
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
type NonMultisigRpc = OneOf<Secp256k1Rpc | P256Rpc | WebAuthnRpc | KeychainRpc>
|
|
39
|
-
|
|
40
30
|
/** Serialized magic identifier for Tempo signature envelopes. */
|
|
41
31
|
export const magicBytes =
|
|
42
32
|
'0x7777777777777777777777777777777777777777777777777777777777777777' // 32 "T"s
|
|
@@ -65,15 +55,15 @@ export type GetType<
|
|
|
65
55
|
: envelope extends { type: infer T extends Type }
|
|
66
56
|
? T
|
|
67
57
|
: envelope extends {
|
|
68
|
-
signature: { r: `0x${string}`; s: `0x${string}` }
|
|
69
58
|
prehash: boolean
|
|
70
59
|
publicKey: PublicKey.PublicKey
|
|
60
|
+
signature: { r: `0x${string}`; s: `0x${string}` }
|
|
71
61
|
}
|
|
72
62
|
? 'p256'
|
|
73
63
|
: envelope extends {
|
|
74
|
-
signature: { r: `0x${string}`; s: `0x${string}` }
|
|
75
64
|
metadata: any
|
|
76
65
|
publicKey: PublicKey.PublicKey
|
|
66
|
+
signature: { r: `0x${string}`; s: `0x${string}` }
|
|
77
67
|
}
|
|
78
68
|
? 'webAuthn'
|
|
79
69
|
: envelope extends {
|
|
@@ -94,7 +84,11 @@ export type GetType<
|
|
|
94
84
|
userAddress: Address.Address
|
|
95
85
|
}
|
|
96
86
|
? 'keychain'
|
|
97
|
-
: envelope extends {
|
|
87
|
+
: envelope extends {
|
|
88
|
+
account: Address.Address
|
|
89
|
+
config: MultisigConfig.Input
|
|
90
|
+
signatures: any
|
|
91
|
+
}
|
|
98
92
|
? 'multisig'
|
|
99
93
|
: never
|
|
100
94
|
|
|
@@ -121,14 +115,20 @@ export type GetType<
|
|
|
121
115
|
*
|
|
122
116
|
* [Signature Types Specification](https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction#signature-types)
|
|
123
117
|
*/
|
|
124
|
-
export type SignatureEnvelope<numberType = number> =
|
|
125
|
-
|
|
|
126
|
-
|
|
|
118
|
+
export type SignatureEnvelope<numberType = number> = OneOf<
|
|
119
|
+
| Secp256k1<numberType>
|
|
120
|
+
| P256<numberType>
|
|
121
|
+
| WebAuthn<numberType>
|
|
122
|
+
| Keychain<numberType>
|
|
123
|
+
| Multisig<numberType>
|
|
124
|
+
>
|
|
127
125
|
|
|
128
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* RPC-formatted signature envelope.
|
|
128
|
+
*/
|
|
129
129
|
export type SignatureEnvelopeRpc =
|
|
130
|
-
|
|
|
131
|
-
|
|
|
130
|
+
| OneOf<Secp256k1Rpc | P256Rpc | WebAuthnRpc | KeychainRpc>
|
|
131
|
+
| MultisigRpc
|
|
132
132
|
|
|
133
133
|
/** Primitive signature envelope accepted by protocol sidecars. */
|
|
134
134
|
export type Primitive<numberType = number> = OneOf<
|
|
@@ -148,68 +148,44 @@ export type PrimitiveRpc = OneOf<Secp256k1Rpc | P256Rpc | WebAuthnRpc>
|
|
|
148
148
|
export type KeychainVersion = 'v1' | 'v2'
|
|
149
149
|
|
|
150
150
|
export type Keychain<numberType = number> = {
|
|
151
|
-
/** Root account address that this transaction is being executed for */
|
|
152
|
-
userAddress: Address.Address
|
|
153
151
|
/** The actual signature from the access key (can be Secp256k1, P256, or WebAuthn) */
|
|
154
152
|
inner: SignatureEnvelope<numberType>
|
|
155
153
|
/** The access key address (recovered address of the access key signer). */
|
|
156
154
|
keyId?: Address.Address | undefined
|
|
157
155
|
type: 'keychain'
|
|
156
|
+
/** Root account address that this transaction is being executed for */
|
|
157
|
+
userAddress: Address.Address
|
|
158
158
|
/** Keychain signature version. @default 'v1' */
|
|
159
159
|
version?: KeychainVersion | undefined
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
export type KeychainRpc = {
|
|
163
|
-
type: 'keychain'
|
|
164
|
-
userAddress: Address.Address
|
|
165
163
|
keyId?: Address.Address | undefined
|
|
166
164
|
signature: SignatureEnvelopeRpc
|
|
165
|
+
type: 'keychain'
|
|
166
|
+
userAddress: Address.Address
|
|
167
167
|
version?: KeychainVersion | undefined
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
171
|
* Native multisig signature (type `0x05`).
|
|
172
172
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* configured threshold.
|
|
177
|
-
*
|
|
178
|
-
* [TIP-1061](https://tips.sh/1061)
|
|
173
|
+
* Carries the account's complete current configuration and primitive owner
|
|
174
|
+
* approvals over its version-bound digest. The node validates the account
|
|
175
|
+
* identity or stored commitment and the owner quorum against chain state.
|
|
179
176
|
*/
|
|
180
177
|
export type Multisig<numberType = number> = {
|
|
181
|
-
/**
|
|
178
|
+
/** Permanent native multisig account address. */
|
|
182
179
|
account: Address.Address
|
|
183
|
-
/** Complete
|
|
180
|
+
/** Complete current configuration, included in every signature. */
|
|
184
181
|
config: MultisigConfig.Config<bigint, numberType>
|
|
185
|
-
/**
|
|
186
|
-
|
|
187
|
-
* either a primitive signature or a nested multisig signature (keychain
|
|
188
|
-
* approvals are invalid).
|
|
189
|
-
*/
|
|
190
|
-
signatures: readonly SignatureEnvelope<numberType>[]
|
|
182
|
+
/** Primitive owner approvals in ascending recovered-address order. */
|
|
183
|
+
signatures: readonly Primitive<numberType>[]
|
|
191
184
|
type: 'multisig'
|
|
192
185
|
}
|
|
193
186
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
Multisig<numberType>,
|
|
197
|
-
Undefined<Omit<NonMultisig<numberType>, 'type'>> {}
|
|
198
|
-
|
|
199
|
-
/** RPC-formatted native multisig signature. */
|
|
200
|
-
export type MultisigRpc = {
|
|
201
|
-
/** Native multisig account address. */
|
|
202
|
-
account: Address.Address
|
|
203
|
-
/** Complete applicable multisig configuration witness. */
|
|
204
|
-
config: MultisigConfig.Rpc
|
|
205
|
-
/** Structured owner approvals. */
|
|
206
|
-
signatures: readonly SignatureEnvelopeRpc[]
|
|
207
|
-
/** Multisig RPC signatures are untagged. */
|
|
208
|
-
type?: undefined
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
interface MultisigRpcOneOf
|
|
212
|
-
extends MultisigRpc, Undefined<Omit<NonMultisigRpc, 'type'>> {}
|
|
187
|
+
/** RLP-encoded `[account, config, signatures]`, without the `0x05` type byte. */
|
|
188
|
+
export type MultisigRpc = Hex.Hex
|
|
213
189
|
|
|
214
190
|
export type P256<numberType = number> = {
|
|
215
191
|
prehash: boolean
|
|
@@ -234,8 +210,8 @@ export type Secp256k1<numberType = number> = {
|
|
|
234
210
|
|
|
235
211
|
export type Secp256k1Rpc = Compute<
|
|
236
212
|
Signature.Rpc<true> & {
|
|
237
|
-
v?: Hex.Hex | undefined
|
|
238
213
|
type: 'secp256k1'
|
|
214
|
+
v?: Hex.Hex | undefined
|
|
239
215
|
}
|
|
240
216
|
>
|
|
241
217
|
|
|
@@ -251,8 +227,8 @@ export type WebAuthn<numberType = number> = {
|
|
|
251
227
|
WebAuthnP256.SignMetadata,
|
|
252
228
|
'authenticatorData' | 'clientDataJSON'
|
|
253
229
|
>
|
|
254
|
-
signature: Signature.Signature<false, numberType>
|
|
255
230
|
publicKey: PublicKey.PublicKey
|
|
231
|
+
signature: Signature.Signature<false, numberType>
|
|
256
232
|
type: 'webAuthn'
|
|
257
233
|
}
|
|
258
234
|
|
|
@@ -347,13 +323,14 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
347
323
|
|
|
348
324
|
if (type === 'keychain') {
|
|
349
325
|
const keychain = envelope as Keychain
|
|
326
|
+
assertKeychainVersion(keychain)
|
|
350
327
|
assert(keychain.inner)
|
|
351
328
|
return
|
|
352
329
|
}
|
|
353
330
|
|
|
354
331
|
if (type === 'multisig') {
|
|
355
332
|
const multisig = envelope as Multisig
|
|
356
|
-
assertMultisig(multisig
|
|
333
|
+
assertMultisig(multisig)
|
|
357
334
|
return
|
|
358
335
|
}
|
|
359
336
|
}
|
|
@@ -369,7 +346,17 @@ export declare namespace assert {
|
|
|
369
346
|
| Errors.GlobalErrorType
|
|
370
347
|
}
|
|
371
348
|
|
|
372
|
-
function
|
|
349
|
+
function assertKeychainVersion(keychain: Keychain): void {
|
|
350
|
+
if (keychain.version !== 'v1') return
|
|
351
|
+
let inner = keychain.inner
|
|
352
|
+
while (getType(inner) === 'keychain') inner = (inner as Keychain).inner
|
|
353
|
+
if (getType(inner) === 'multisig')
|
|
354
|
+
throw new InvalidMultisigApprovalError({
|
|
355
|
+
reason: 'multisig access keys require keychain V2',
|
|
356
|
+
})
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function assertMultisig(envelope: Multisig): void {
|
|
373
360
|
const missing: string[] = []
|
|
374
361
|
if (!envelope.account) missing.push('account')
|
|
375
362
|
if (!envelope.config) missing.push('config')
|
|
@@ -380,10 +367,6 @@ function assertMultisig(envelope: Multisig, depth: number): void {
|
|
|
380
367
|
missing,
|
|
381
368
|
type: 'multisig',
|
|
382
369
|
})
|
|
383
|
-
if (depth > MultisigConfig.maxNestingDepth)
|
|
384
|
-
throw new InvalidMultisigApprovalError({
|
|
385
|
-
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
386
|
-
})
|
|
387
370
|
if (!Address.validate(envelope.account))
|
|
388
371
|
throw new InvalidMultisigApprovalError({
|
|
389
372
|
reason: 'multisig account is invalid',
|
|
@@ -392,25 +375,6 @@ function assertMultisig(envelope: Multisig, depth: number): void {
|
|
|
392
375
|
throw new InvalidMultisigApprovalError({
|
|
393
376
|
reason: 'multisig account cannot be zero',
|
|
394
377
|
})
|
|
395
|
-
MultisigConfig.assert(envelope.config)
|
|
396
|
-
if (
|
|
397
|
-
envelope.config.owners.some((owner) =>
|
|
398
|
-
Address.isEqual(owner.owner, envelope.account),
|
|
399
|
-
)
|
|
400
|
-
)
|
|
401
|
-
throw new InvalidMultisigApprovalError({
|
|
402
|
-
reason: 'multisig account cannot be an owner',
|
|
403
|
-
})
|
|
404
|
-
if (
|
|
405
|
-
envelope.config.version === 0n &&
|
|
406
|
-
!Address.isEqual(
|
|
407
|
-
MultisigConfig.getAddress(envelope.config),
|
|
408
|
-
envelope.account,
|
|
409
|
-
)
|
|
410
|
-
)
|
|
411
|
-
throw new InvalidMultisigApprovalError({
|
|
412
|
-
reason: 'initial multisig config does not derive account',
|
|
413
|
-
})
|
|
414
378
|
if (envelope.signatures.length === 0)
|
|
415
379
|
throw new InvalidMultisigApprovalError({
|
|
416
380
|
reason: 'multisig signatures cannot be empty',
|
|
@@ -420,20 +384,29 @@ function assertMultisig(envelope: Multisig, depth: number): void {
|
|
|
420
384
|
reason: `multisig signatures exceed ${MultisigConfig.maxSignatures}`,
|
|
421
385
|
})
|
|
422
386
|
|
|
387
|
+
MultisigConfig.assert(envelope.config)
|
|
388
|
+
if (
|
|
389
|
+
(envelope.config.version ?? 0n) === 0n &&
|
|
390
|
+
envelope.config.owners.some((owner) =>
|
|
391
|
+
Address.isEqual(owner.owner, envelope.account),
|
|
392
|
+
)
|
|
393
|
+
)
|
|
394
|
+
throw new InvalidMultisigApprovalError({
|
|
395
|
+
reason: 'initial account cannot be an owner',
|
|
396
|
+
})
|
|
397
|
+
|
|
423
398
|
for (const inner of envelope.signatures) {
|
|
424
|
-
const type = getType(inner)
|
|
425
|
-
if (type === 'keychain')
|
|
399
|
+
const type = getType(inner as SignatureEnvelope)
|
|
400
|
+
if (type === 'keychain' || type === 'multisig')
|
|
426
401
|
throw new InvalidMultisigApprovalError({
|
|
427
|
-
reason: '
|
|
402
|
+
reason: 'owner approvals must be primitive signatures',
|
|
403
|
+
})
|
|
404
|
+
assert(inner)
|
|
405
|
+
|
|
406
|
+
if (Hex.size(serialize(inner)) > MultisigConfig.maxOwnerSignatureBytes)
|
|
407
|
+
throw new InvalidMultisigApprovalError({
|
|
408
|
+
reason: `multisig owner signature exceeds ${MultisigConfig.maxOwnerSignatureBytes} bytes`,
|
|
428
409
|
})
|
|
429
|
-
if (type === 'multisig') assertMultisig(inner as Multisig, depth + 1)
|
|
430
|
-
else {
|
|
431
|
-
assert(inner)
|
|
432
|
-
if (Hex.size(serialize(inner)) > MultisigConfig.maxOwnerSignatureBytes)
|
|
433
|
-
throw new InvalidMultisigApprovalError({
|
|
434
|
-
reason: `multisig owner signature exceeds ${MultisigConfig.maxOwnerSignatureBytes} bytes`,
|
|
435
|
-
})
|
|
436
|
-
}
|
|
437
410
|
}
|
|
438
411
|
}
|
|
439
412
|
|
|
@@ -484,10 +457,10 @@ export declare namespace extractAddress {
|
|
|
484
457
|
type Options = {
|
|
485
458
|
/** The sign payload that was signed (only required for secp256k1 signatures). */
|
|
486
459
|
payload: Hex.Hex | Bytes.Bytes
|
|
487
|
-
/** The signature envelope. */
|
|
488
|
-
signature: SignatureEnvelope
|
|
489
460
|
/** Whether to return the root `userAddress` for keychain signatures instead of extracting from the inner signature. */
|
|
490
461
|
root?: boolean | undefined
|
|
462
|
+
/** The signature envelope. */
|
|
463
|
+
signature: SignatureEnvelope
|
|
491
464
|
}
|
|
492
465
|
|
|
493
466
|
type ReturnType = Address.Address
|
|
@@ -590,13 +563,10 @@ export declare namespace extractPublicKey {
|
|
|
590
563
|
* @throws `CoercionError` if the serialized value cannot be coerced to a valid signature envelope.
|
|
591
564
|
*/
|
|
592
565
|
export function deserialize(value: Serialized): SignatureEnvelope {
|
|
593
|
-
return deserialize_(value
|
|
566
|
+
return deserialize_(value)
|
|
594
567
|
}
|
|
595
568
|
|
|
596
|
-
function deserialize_(
|
|
597
|
-
value: Serialized,
|
|
598
|
-
multisigDepth: number,
|
|
599
|
-
): SignatureEnvelope {
|
|
569
|
+
function deserialize_(value: Serialized): SignatureEnvelope {
|
|
600
570
|
const serialized = value.endsWith(magicBytes.slice(2))
|
|
601
571
|
? Hex.slice(value, 0, -Hex.size(magicBytes))
|
|
602
572
|
: value
|
|
@@ -699,33 +669,27 @@ function deserialize_(
|
|
|
699
669
|
typeId === serializedKeychainV2Type
|
|
700
670
|
) {
|
|
701
671
|
const userAddress = Hex.slice(data, 0, 20)
|
|
702
|
-
const inner = deserialize_(Hex.slice(data, 20)
|
|
672
|
+
const inner = deserialize_(Hex.slice(data, 20))
|
|
703
673
|
|
|
704
|
-
|
|
674
|
+
const envelope = {
|
|
705
675
|
userAddress,
|
|
706
676
|
inner,
|
|
707
677
|
type: 'keychain',
|
|
708
678
|
version: typeId === serializedKeychainV2Type ? 'v2' : 'v1',
|
|
709
679
|
} satisfies Keychain
|
|
680
|
+
assert(envelope)
|
|
681
|
+
return envelope
|
|
710
682
|
}
|
|
711
683
|
|
|
712
684
|
if (typeId === serializedMultisigType) {
|
|
713
|
-
const depth = multisigDepth + 1
|
|
714
|
-
if (depth > MultisigConfig.maxNestingDepth)
|
|
715
|
-
throw new InvalidSerializedError({
|
|
716
|
-
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
717
|
-
serialized,
|
|
718
|
-
})
|
|
719
|
-
|
|
720
685
|
const decoded = Rlp.toHex(data)
|
|
721
686
|
if (!Array.isArray(decoded) || decoded.length !== 3)
|
|
722
687
|
throw new InvalidSerializedError({
|
|
723
688
|
reason: 'invalid multisig wire shape: expected exactly three fields',
|
|
724
689
|
serialized,
|
|
725
690
|
})
|
|
726
|
-
|
|
727
691
|
const [account, config, signatures] = decoded
|
|
728
|
-
if (!Address.validate(account))
|
|
692
|
+
if (typeof account !== 'string' || !Address.validate(account))
|
|
729
693
|
throw new InvalidSerializedError({
|
|
730
694
|
reason: 'invalid multisig account',
|
|
731
695
|
serialized,
|
|
@@ -735,68 +699,43 @@ function deserialize_(
|
|
|
735
699
|
reason: 'invalid multisig config',
|
|
736
700
|
serialized,
|
|
737
701
|
})
|
|
738
|
-
const [salt, version, threshold, owners] = config
|
|
739
702
|
if (
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
Array.isArray(version) ||
|
|
744
|
-
Hex.size(version) > 8 ||
|
|
745
|
-
(version !== '0x' && Hex.slice(version, 0, 1) === '0x00') ||
|
|
746
|
-
Array.isArray(threshold) ||
|
|
747
|
-
Hex.size(threshold) > 1 ||
|
|
748
|
-
!Array.isArray(owners) ||
|
|
749
|
-
owners.some(
|
|
750
|
-
(owner) =>
|
|
751
|
-
!Array.isArray(owner) ||
|
|
752
|
-
owner.length !== 2 ||
|
|
753
|
-
owner.some(Array.isArray) ||
|
|
754
|
-
!Address.validate(owner[0]) ||
|
|
755
|
-
Hex.size(owner[1] as Hex.Hex) > 1,
|
|
756
|
-
)
|
|
703
|
+
!Array.isArray(signatures) ||
|
|
704
|
+
signatures.length === 0 ||
|
|
705
|
+
signatures.length > MultisigConfig.maxSignatures
|
|
757
706
|
)
|
|
758
|
-
throw new InvalidSerializedError({
|
|
759
|
-
reason: 'invalid multisig config',
|
|
760
|
-
serialized,
|
|
761
|
-
})
|
|
762
|
-
if (!Array.isArray(signatures) || signatures.some(Array.isArray))
|
|
763
707
|
throw new InvalidSerializedError({
|
|
764
708
|
reason: 'invalid multisig signatures list',
|
|
765
709
|
serialized,
|
|
766
710
|
})
|
|
767
|
-
if (signatures.length === 0)
|
|
768
|
-
throw new InvalidSerializedError({
|
|
769
|
-
reason: 'multisig signatures cannot be empty',
|
|
770
|
-
serialized,
|
|
771
|
-
})
|
|
772
|
-
if (signatures.length > MultisigConfig.maxSignatures)
|
|
773
|
-
throw new InvalidSerializedError({
|
|
774
|
-
reason: `multisig signatures exceed ${MultisigConfig.maxSignatures}`,
|
|
775
|
-
serialized,
|
|
776
|
-
})
|
|
777
|
-
for (const signature of signatures)
|
|
778
|
-
if (
|
|
779
|
-
Hex.size(signature as Hex.Hex) >
|
|
780
|
-
MultisigConfig.maxOwnerSignatureBytes &&
|
|
781
|
-
Hex.slice(signature as Hex.Hex, 0, 1) !==
|
|
782
|
-
MultisigConfig.signatureTypeByte
|
|
783
|
-
)
|
|
784
|
-
throw new InvalidSerializedError({
|
|
785
|
-
reason: `multisig owner signature exceeds ${MultisigConfig.maxOwnerSignatureBytes} bytes`,
|
|
786
|
-
serialized,
|
|
787
|
-
})
|
|
788
|
-
|
|
789
711
|
const envelope = {
|
|
790
|
-
|
|
712
|
+
type: 'multisig',
|
|
713
|
+
account,
|
|
791
714
|
config: MultisigConfig.fromTuple(
|
|
792
715
|
config as unknown as MultisigConfig.Tuple,
|
|
793
716
|
),
|
|
794
|
-
signatures: signatures.map((signature) =>
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
717
|
+
signatures: signatures.map((signature) => {
|
|
718
|
+
if (
|
|
719
|
+
!Hex.validate(signature) ||
|
|
720
|
+
Hex.size(signature) > MultisigConfig.maxOwnerSignatureBytes
|
|
721
|
+
)
|
|
722
|
+
throw new InvalidSerializedError({
|
|
723
|
+
reason: 'invalid multisig owner signature',
|
|
724
|
+
serialized,
|
|
725
|
+
})
|
|
726
|
+
// Reject recursive envelopes before decoding their contents.
|
|
727
|
+
if (
|
|
728
|
+
Hex.size(signature) !== 65 &&
|
|
729
|
+
!['0x01', '0x02'].includes(Hex.slice(signature, 0, 1))
|
|
730
|
+
)
|
|
731
|
+
throw new InvalidSerializedError({
|
|
732
|
+
reason: 'owner approvals must be primitive signatures',
|
|
733
|
+
serialized,
|
|
734
|
+
})
|
|
735
|
+
return deserialize(signature) as Primitive
|
|
736
|
+
}),
|
|
798
737
|
} satisfies Multisig
|
|
799
|
-
assertMultisig(envelope
|
|
738
|
+
assertMultisig(envelope)
|
|
800
739
|
return envelope
|
|
801
740
|
}
|
|
802
741
|
|
|
@@ -934,28 +873,30 @@ function deserialize_(
|
|
|
934
873
|
* @example
|
|
935
874
|
* ### Multisig
|
|
936
875
|
*
|
|
937
|
-
*
|
|
938
|
-
* import { Secp256k1 } from 'ox'
|
|
939
|
-
* import { MultisigConfig, SignatureEnvelope } from 'ox/tempo'
|
|
940
|
-
*
|
|
941
|
-
* const config = MultisigConfig.from({
|
|
942
|
-
* owners: [
|
|
943
|
-
* {
|
|
944
|
-
* owner: '0x1111111111111111111111111111111111111111',
|
|
945
|
-
* weight: 1
|
|
946
|
-
* }
|
|
947
|
-
* ],
|
|
948
|
-
* threshold: 1
|
|
949
|
-
* })
|
|
876
|
+
* Include the permanent account and current configuration on every transaction.
|
|
950
877
|
*
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
* Secp256k1.sign({ payload: '0xdeadbeef', privateKey })
|
|
954
|
-
* )
|
|
878
|
+
* ```ts twoslash
|
|
879
|
+
* import { SignatureEnvelope } from 'ox/tempo'
|
|
955
880
|
*
|
|
956
|
-
* const
|
|
957
|
-
*
|
|
958
|
-
*
|
|
881
|
+
* const envelope = SignatureEnvelope.from({
|
|
882
|
+
* account: '0x2222222222222222222222222222222222222222',
|
|
883
|
+
* config: {
|
|
884
|
+
* version: 0n,
|
|
885
|
+
* threshold: 1,
|
|
886
|
+
* owners: [
|
|
887
|
+
* {
|
|
888
|
+
* owner: '0x1111111111111111111111111111111111111111',
|
|
889
|
+
* weight: 1
|
|
890
|
+
* }
|
|
891
|
+
* ]
|
|
892
|
+
* },
|
|
893
|
+
* signatures: [
|
|
894
|
+
* SignatureEnvelope.from({
|
|
895
|
+
* r: '0x01',
|
|
896
|
+
* s: '0x02',
|
|
897
|
+
* yParity: 0
|
|
898
|
+
* })
|
|
899
|
+
* ]
|
|
959
900
|
* })
|
|
960
901
|
* ```
|
|
961
902
|
*
|
|
@@ -980,17 +921,13 @@ export function from<const value extends from.Value>(
|
|
|
980
921
|
const type = getType(value)
|
|
981
922
|
|
|
982
923
|
if (type === 'multisig') {
|
|
983
|
-
const multisig = value as
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
account,
|
|
988
|
-
config,
|
|
924
|
+
const multisig = value as Multisig
|
|
925
|
+
return {
|
|
926
|
+
...multisig,
|
|
927
|
+
config: MultisigConfig.from(multisig.config),
|
|
989
928
|
signatures: multisig.signatures.map((signature) => from(signature)),
|
|
990
929
|
type,
|
|
991
|
-
}
|
|
992
|
-
assert(envelope)
|
|
993
|
-
return envelope as never
|
|
930
|
+
} as never
|
|
994
931
|
}
|
|
995
932
|
|
|
996
933
|
return {
|
|
@@ -1035,32 +972,17 @@ export declare namespace from {
|
|
|
1035
972
|
payload?: Hex.Hex | Bytes.Bytes | undefined
|
|
1036
973
|
}
|
|
1037
974
|
|
|
1038
|
-
/** Multisig
|
|
1039
|
-
type MultisigFromConfig =
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
/** Initial version-0 multisig configuration witness. */
|
|
1044
|
-
config: MultisigConfig.Input<0 | 0n>
|
|
1045
|
-
/** Primitive or nested owner approvals. */
|
|
1046
|
-
signatures: readonly SignatureEnvelope[]
|
|
1047
|
-
type?: 'multisig' | undefined
|
|
1048
|
-
}
|
|
1049
|
-
| {
|
|
1050
|
-
/** Native multisig account. */
|
|
1051
|
-
account: Address.Address
|
|
1052
|
-
/** Complete applicable multisig configuration witness. */
|
|
1053
|
-
config: MultisigConfig.Input
|
|
1054
|
-
/** Primitive or nested owner approvals. */
|
|
1055
|
-
signatures: readonly SignatureEnvelope[]
|
|
1056
|
-
type?: 'multisig' | undefined
|
|
1057
|
-
}
|
|
975
|
+
/** Multisig input with an explicit account and a normalizable configuration. */
|
|
976
|
+
type MultisigFromConfig = Omit<Multisig, 'config' | 'type'> & {
|
|
977
|
+
config: MultisigConfig.Input
|
|
978
|
+
type?: 'multisig' | undefined
|
|
979
|
+
}
|
|
1058
980
|
|
|
1059
981
|
type Value =
|
|
982
|
+
| MultisigFromConfig
|
|
1060
983
|
| UnionPartialBy<SignatureEnvelope, 'prehash' | 'type'>
|
|
1061
984
|
| Secp256k1Flat
|
|
1062
985
|
| Serialized
|
|
1063
|
-
| MultisigFromConfig
|
|
1064
986
|
|
|
1065
987
|
type ReturnValue<value extends Value> = Compute<
|
|
1066
988
|
OneOf<
|
|
@@ -1069,7 +991,7 @@ export declare namespace from {
|
|
|
1069
991
|
: value extends Secp256k1Flat
|
|
1070
992
|
? Secp256k1
|
|
1071
993
|
: value extends MultisigFromConfig
|
|
1072
|
-
?
|
|
994
|
+
? Extract<SignatureEnvelope, { type: 'multisig' }>
|
|
1073
995
|
: IsNarrowable<value, SignatureEnvelope> extends true
|
|
1074
996
|
? SignatureEnvelope
|
|
1075
997
|
: Assign<
|
|
@@ -1103,6 +1025,11 @@ export declare namespace from {
|
|
|
1103
1025
|
* @returns The signature envelope with bigint values.
|
|
1104
1026
|
*/
|
|
1105
1027
|
export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
1028
|
+
if (typeof envelope === 'string') {
|
|
1029
|
+
const signature = deserialize(Hex.concat(serializedMultisigType, envelope))
|
|
1030
|
+
if (signature.type !== 'multisig') throw new CoercionError({ envelope })
|
|
1031
|
+
return signature
|
|
1032
|
+
}
|
|
1106
1033
|
if (envelope.type === 'secp256k1')
|
|
1107
1034
|
return {
|
|
1108
1035
|
signature: Signature.fromRpc(envelope),
|
|
@@ -1176,26 +1103,13 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
|
1176
1103
|
('userAddress' in envelope && 'signature' in envelope)
|
|
1177
1104
|
) {
|
|
1178
1105
|
const keychain = envelope as KeychainRpc
|
|
1179
|
-
|
|
1106
|
+
const result = {
|
|
1180
1107
|
type: 'keychain',
|
|
1181
1108
|
userAddress: keychain.userAddress,
|
|
1182
1109
|
inner: fromRpc(keychain.signature),
|
|
1183
1110
|
...(keychain.keyId ? { keyId: keychain.keyId } : {}),
|
|
1184
1111
|
...(keychain.version ? { version: keychain.version } : {}),
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
if (
|
|
1189
|
-
(envelope as { type?: string | undefined }).type === 'multisig' ||
|
|
1190
|
-
('config' in envelope && 'signatures' in envelope)
|
|
1191
|
-
) {
|
|
1192
|
-
const multisig = envelope as MultisigRpc
|
|
1193
|
-
const result = {
|
|
1194
|
-
account: multisig.account,
|
|
1195
|
-
config: MultisigConfig.fromRpc(multisig.config),
|
|
1196
|
-
signatures: multisig.signatures.map((signature) => fromRpc(signature)),
|
|
1197
|
-
type: 'multisig',
|
|
1198
|
-
} satisfies Multisig
|
|
1112
|
+
} satisfies Keychain
|
|
1199
1113
|
assert(result)
|
|
1200
1114
|
return result
|
|
1201
1115
|
}
|
|
@@ -1208,7 +1122,7 @@ export declare namespace fromRpc {
|
|
|
1208
1122
|
| assert.ErrorType
|
|
1209
1123
|
| CoercionError
|
|
1210
1124
|
| InvalidSerializedError
|
|
1211
|
-
| MultisigConfig.
|
|
1125
|
+
| MultisigConfig.getAddress.ErrorType
|
|
1212
1126
|
| Signature.fromRpc.ErrorType
|
|
1213
1127
|
| Errors.GlobalErrorType
|
|
1214
1128
|
}
|
|
@@ -1283,7 +1197,7 @@ export function getType<
|
|
|
1283
1197
|
return 'keychain' as never
|
|
1284
1198
|
|
|
1285
1199
|
// Detect Multisig signature
|
|
1286
|
-
if ('config' in envelope && 'signatures' in envelope)
|
|
1200
|
+
if ('account' in envelope && 'config' in envelope && 'signatures' in envelope)
|
|
1287
1201
|
return 'multisig' as never
|
|
1288
1202
|
|
|
1289
1203
|
throw new CoercionError({
|
|
@@ -1372,6 +1286,7 @@ export function serialize(
|
|
|
1372
1286
|
|
|
1373
1287
|
if (type === 'keychain') {
|
|
1374
1288
|
const keychain = envelope as Keychain
|
|
1289
|
+
assert(keychain)
|
|
1375
1290
|
const keychainTypeId =
|
|
1376
1291
|
keychain.version === 'v1'
|
|
1377
1292
|
? serializedKeychainType
|
|
@@ -1422,79 +1337,31 @@ export declare namespace serialize {
|
|
|
1422
1337
|
}
|
|
1423
1338
|
|
|
1424
1339
|
/**
|
|
1425
|
-
*
|
|
1426
|
-
* recovered-owner order the Tempo node requires for the multisig `signatures`
|
|
1427
|
-
* array (the node enforces "recovered owners must be strictly ascending").
|
|
1340
|
+
* Sorts primitive owner approvals by recovered address.
|
|
1428
1341
|
*
|
|
1429
|
-
*
|
|
1430
|
-
*
|
|
1431
|
-
* every approval is recovered against that digest and the list is sorted by the
|
|
1432
|
-
* recovered owner address. Works for any owner key type (secp256k1, p256,
|
|
1433
|
-
* webAuthn).
|
|
1342
|
+
* Recovery uses the account and current config version's multisig digest.
|
|
1343
|
+
* Duplicate or non-owner approvals must still be rejected by the node.
|
|
1434
1344
|
*
|
|
1435
1345
|
* @example
|
|
1436
1346
|
* ```ts twoslash
|
|
1437
|
-
* import {
|
|
1438
|
-
* import {
|
|
1439
|
-
* MultisigConfig,
|
|
1440
|
-
* SignatureEnvelope,
|
|
1441
|
-
* TxEnvelopeTempo
|
|
1442
|
-
* } from 'ox/tempo'
|
|
1443
|
-
*
|
|
1444
|
-
* const config = MultisigConfig.from({
|
|
1445
|
-
* owners: [
|
|
1446
|
-
* {
|
|
1447
|
-
* owner: '0x1111111111111111111111111111111111111111',
|
|
1448
|
-
* weight: 1
|
|
1449
|
-
* },
|
|
1450
|
-
* {
|
|
1451
|
-
* owner: '0x2222222222222222222222222222222222222222',
|
|
1452
|
-
* weight: 1
|
|
1453
|
-
* }
|
|
1454
|
-
* ],
|
|
1455
|
-
* threshold: 2
|
|
1456
|
-
* })
|
|
1457
|
-
* const account = MultisigConfig.getAddress(config)
|
|
1458
|
-
*
|
|
1459
|
-
* const tx = TxEnvelopeTempo.from({ chainId: 1, calls: [] })
|
|
1460
|
-
* const payload = TxEnvelopeTempo.getSignPayload(tx)
|
|
1461
|
-
*
|
|
1462
|
-
* const privateKeys = [
|
|
1463
|
-
* Secp256k1.randomPrivateKey(),
|
|
1464
|
-
* Secp256k1.randomPrivateKey()
|
|
1465
|
-
* ]
|
|
1466
|
-
* const digest = MultisigConfig.getSignPayload({
|
|
1467
|
-
* account,
|
|
1468
|
-
* config,
|
|
1469
|
-
* payload
|
|
1470
|
-
* })
|
|
1471
|
-
* const signatures = privateKeys.map((privateKey) =>
|
|
1472
|
-
* SignatureEnvelope.from(
|
|
1473
|
-
* Secp256k1.sign({ payload: digest, privateKey })
|
|
1474
|
-
* )
|
|
1475
|
-
* )
|
|
1347
|
+
* import { SignatureEnvelope } from 'ox/tempo'
|
|
1476
1348
|
*
|
|
1477
1349
|
* const ordered = SignatureEnvelope.sortMultisigApprovals({
|
|
1478
|
-
*
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
* }) // [!code focus]
|
|
1350
|
+
* account: '0x2222222222222222222222222222222222222222',
|
|
1351
|
+
* config: { version: 0n },
|
|
1352
|
+
* payload: `0x${'ab'.repeat(32)}`,
|
|
1353
|
+
* signatures: []
|
|
1354
|
+
* })
|
|
1484
1355
|
* ```
|
|
1485
1356
|
*
|
|
1486
|
-
* @param value -
|
|
1487
|
-
* @returns The
|
|
1357
|
+
* @param value - Account, version, payload, and primitive approvals.
|
|
1358
|
+
* @returns The approvals in ascending recovered-address order.
|
|
1488
1359
|
*/
|
|
1489
1360
|
export function sortMultisigApprovals(
|
|
1490
1361
|
value: sortMultisigApprovals.Value,
|
|
1491
|
-
): readonly
|
|
1492
|
-
const {
|
|
1493
|
-
const digest = MultisigConfig.getSignPayload(
|
|
1494
|
-
account,
|
|
1495
|
-
config: MultisigConfig.from(config),
|
|
1496
|
-
payload,
|
|
1497
|
-
})
|
|
1362
|
+
): readonly Primitive[] {
|
|
1363
|
+
const { signatures } = value
|
|
1364
|
+
const digest = MultisigConfig.getSignPayload(value)
|
|
1498
1365
|
// Recover each signer once (decorate–sort–undecorate) rather than inside the
|
|
1499
1366
|
// comparator.
|
|
1500
1367
|
return signatures
|
|
@@ -1507,15 +1374,9 @@ export function sortMultisigApprovals(
|
|
|
1507
1374
|
}
|
|
1508
1375
|
|
|
1509
1376
|
export declare namespace sortMultisigApprovals {
|
|
1510
|
-
type Value = {
|
|
1511
|
-
/**
|
|
1512
|
-
|
|
1513
|
-
/** Complete applicable multisig configuration witness. */
|
|
1514
|
-
config: MultisigConfig.Input
|
|
1515
|
-
/** The inner transaction sign payload (`tx.signature_hash()`). */
|
|
1516
|
-
payload: Hex.Hex | Bytes.Bytes
|
|
1517
|
-
/** The owner approvals to order. */
|
|
1518
|
-
signatures: readonly SignatureEnvelope[]
|
|
1377
|
+
type Value = MultisigConfig.getSignPayload.Value & {
|
|
1378
|
+
/** Primitive owner approvals to order. */
|
|
1379
|
+
signatures: readonly Primitive[]
|
|
1519
1380
|
}
|
|
1520
1381
|
|
|
1521
1382
|
type ErrorType =
|
|
@@ -1588,6 +1449,7 @@ export function toRpc<const envelope extends toRpc.Input>(
|
|
|
1588
1449
|
|
|
1589
1450
|
if (type === 'keychain') {
|
|
1590
1451
|
const keychain = envelope as Keychain
|
|
1452
|
+
assertKeychainVersion(keychain)
|
|
1591
1453
|
return {
|
|
1592
1454
|
type: 'keychain',
|
|
1593
1455
|
userAddress: keychain.userAddress,
|
|
@@ -1598,13 +1460,38 @@ export function toRpc<const envelope extends toRpc.Input>(
|
|
|
1598
1460
|
}
|
|
1599
1461
|
|
|
1600
1462
|
if (type === 'multisig') {
|
|
1601
|
-
const multisig = envelope as Multisig
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1463
|
+
const multisig = envelope as Multisig<Hex.Hex | number>
|
|
1464
|
+
return Hex.slice(
|
|
1465
|
+
serialize({
|
|
1466
|
+
...multisig,
|
|
1467
|
+
config: {
|
|
1468
|
+
...multisig.config,
|
|
1469
|
+
threshold: Number(multisig.config.threshold),
|
|
1470
|
+
owners: multisig.config.owners.map((owner) => ({
|
|
1471
|
+
...owner,
|
|
1472
|
+
weight: Number(owner.weight),
|
|
1473
|
+
})),
|
|
1474
|
+
},
|
|
1475
|
+
signatures: multisig.signatures.map((signature) =>
|
|
1476
|
+
signature.type === 'secp256k1'
|
|
1477
|
+
? {
|
|
1478
|
+
...signature,
|
|
1479
|
+
signature: {
|
|
1480
|
+
...signature.signature,
|
|
1481
|
+
yParity: Number(signature.signature.yParity),
|
|
1482
|
+
},
|
|
1483
|
+
}
|
|
1484
|
+
: {
|
|
1485
|
+
...signature,
|
|
1486
|
+
signature: {
|
|
1487
|
+
r: signature.signature.r,
|
|
1488
|
+
s: signature.signature.s,
|
|
1489
|
+
},
|
|
1490
|
+
},
|
|
1491
|
+
),
|
|
1492
|
+
}),
|
|
1493
|
+
1,
|
|
1494
|
+
) as never
|
|
1608
1495
|
}
|
|
1609
1496
|
|
|
1610
1497
|
throw new CoercionError({ envelope })
|
|
@@ -1631,7 +1518,8 @@ export declare namespace toRpc {
|
|
|
1631
1518
|
type ErrorType =
|
|
1632
1519
|
| assert.ErrorType
|
|
1633
1520
|
| CoercionError
|
|
1634
|
-
|
|
|
1521
|
+
| Hex.slice.ErrorType
|
|
1522
|
+
| serialize.ErrorType
|
|
1635
1523
|
| Signature.toRpc.ErrorType
|
|
1636
1524
|
| Errors.GlobalErrorType
|
|
1637
1525
|
}
|