ox 1.0.2 → 1.0.3
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 +6 -0
- package/dist/tempo/KeyAuthorization.d.ts +22 -16
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +31 -7
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +8 -4
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +16 -4
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +31 -13
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +172 -55
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +70 -60
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +0 -306
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.js +2 -2
- package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
- package/dist/zod/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/zod/tempo/MultisigConfig.js +5 -2
- package/dist/zod/tempo/MultisigConfig.js.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +28 -132
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +79 -18
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +39 -11
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +84 -396
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +42 -234
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +0 -108
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/tempo/KeyAuthorization.test-d.ts +62 -0
- package/src/tempo/KeyAuthorization.test.ts +53 -0
- package/src/tempo/KeyAuthorization.ts +69 -27
- package/src/tempo/MultisigConfig.test.ts +34 -2
- package/src/tempo/MultisigConfig.ts +18 -4
- package/src/tempo/SignatureEnvelope.test-d.ts +97 -0
- package/src/tempo/SignatureEnvelope.test.ts +247 -36
- package/src/tempo/SignatureEnvelope.ts +271 -85
- package/src/tempo/e2e.test.ts +0 -416
- package/src/tempo/multisig.e2e.test.ts +582 -0
- package/src/version.ts +1 -1
- package/src/zod/tempo/KeyAuthorization.ts +2 -2
- package/src/zod/tempo/MultisigConfig.ts +13 -5
- package/src/zod/tempo/SignatureEnvelope.ts +81 -18
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +25 -0
- package/src/zod/tempo/_test/MultisigConfig.test.ts +44 -0
- package/src/zod/tempo/_test/SignatureEnvelope.test-d.ts +9 -0
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +142 -6
|
@@ -84,10 +84,15 @@ export type GetType<
|
|
|
84
84
|
userAddress: Address.Address
|
|
85
85
|
}
|
|
86
86
|
? 'keychain'
|
|
87
|
-
: envelope extends
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
: envelope extends
|
|
88
|
+
| {
|
|
89
|
+
account: Address.Address
|
|
90
|
+
signatures: any
|
|
91
|
+
}
|
|
92
|
+
| {
|
|
93
|
+
init: MultisigConfig.Config
|
|
94
|
+
signatures: any
|
|
95
|
+
}
|
|
91
96
|
? 'multisig'
|
|
92
97
|
: never
|
|
93
98
|
|
|
@@ -129,6 +134,14 @@ export type SignatureEnvelopeRpc = OneOf<
|
|
|
129
134
|
Secp256k1Rpc | P256Rpc | WebAuthnRpc | KeychainRpc | MultisigRpc
|
|
130
135
|
>
|
|
131
136
|
|
|
137
|
+
/** Primitive signature envelope accepted by protocol sidecars. */
|
|
138
|
+
export type Primitive<numberType = number> = OneOf<
|
|
139
|
+
Secp256k1<numberType> | P256<numberType> | WebAuthn<numberType>
|
|
140
|
+
>
|
|
141
|
+
|
|
142
|
+
/** RPC-formatted primitive signature envelope. */
|
|
143
|
+
export type PrimitiveRpc = OneOf<Secp256k1Rpc | P256Rpc | WebAuthnRpc>
|
|
144
|
+
|
|
132
145
|
/**
|
|
133
146
|
* Keychain signature version.
|
|
134
147
|
*
|
|
@@ -186,16 +199,25 @@ export type Multisig<numberType = number> = {
|
|
|
186
199
|
init?: MultisigConfig.Config<numberType> | undefined
|
|
187
200
|
}
|
|
188
201
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
202
|
+
/** RPC-formatted native multisig signature. */
|
|
203
|
+
export type MultisigRpc = OneOf<
|
|
204
|
+
| {
|
|
205
|
+
/** Existing native multisig account. */
|
|
206
|
+
account: Address.Address
|
|
207
|
+
/** Structured owner approvals. */
|
|
208
|
+
signatures: readonly SignatureEnvelopeRpc[]
|
|
209
|
+
/** Multisig RPC signatures are untagged. */
|
|
210
|
+
type?: undefined
|
|
211
|
+
}
|
|
212
|
+
| {
|
|
213
|
+
/** Initial config for bootstrapping a native multisig account. */
|
|
214
|
+
init: MultisigConfig.Config
|
|
215
|
+
/** Structured owner approvals. */
|
|
216
|
+
signatures: readonly SignatureEnvelopeRpc[]
|
|
217
|
+
/** Multisig RPC signatures are untagged. */
|
|
218
|
+
type?: undefined
|
|
219
|
+
}
|
|
220
|
+
>
|
|
199
221
|
|
|
200
222
|
export type P256<numberType = number> = {
|
|
201
223
|
prehash: boolean
|
|
@@ -339,27 +361,7 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
339
361
|
|
|
340
362
|
if (type === 'multisig') {
|
|
341
363
|
const multisig = envelope as Multisig
|
|
342
|
-
|
|
343
|
-
if (!multisig.account) missing.push('account')
|
|
344
|
-
if (!Array.isArray(multisig.signatures)) missing.push('signatures')
|
|
345
|
-
if (missing.length > 0)
|
|
346
|
-
throw new MissingPropertiesError({ envelope, missing, type: 'multisig' })
|
|
347
|
-
if (getNestingDepth(multisig) > MultisigConfig.maxNestingDepth)
|
|
348
|
-
throw new InvalidMultisigApprovalError({
|
|
349
|
-
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
350
|
-
})
|
|
351
|
-
for (const inner of multisig.signatures) {
|
|
352
|
-
if (inner.type === 'keychain')
|
|
353
|
-
throw new InvalidMultisigApprovalError({
|
|
354
|
-
reason: 'keychain owner approvals are not allowed',
|
|
355
|
-
})
|
|
356
|
-
if (inner.type === 'multisig' && inner.init)
|
|
357
|
-
throw new InvalidMultisigApprovalError({
|
|
358
|
-
reason: 'nested multisig owner approvals cannot carry `init`',
|
|
359
|
-
})
|
|
360
|
-
assert(inner)
|
|
361
|
-
}
|
|
362
|
-
if (multisig.init) MultisigConfig.assert(multisig.init)
|
|
364
|
+
assertMultisig(multisig, 1)
|
|
363
365
|
return
|
|
364
366
|
}
|
|
365
367
|
}
|
|
@@ -370,17 +372,75 @@ export declare namespace assert {
|
|
|
370
372
|
| InvalidMultisigApprovalError
|
|
371
373
|
| MissingPropertiesError
|
|
372
374
|
| MultisigConfig.assert.ErrorType
|
|
375
|
+
| MultisigConfig.getAddress.ErrorType
|
|
373
376
|
| Signature.assert.ErrorType
|
|
374
377
|
| Errors.GlobalErrorType
|
|
375
378
|
}
|
|
376
379
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
380
|
+
function assertMultisig(envelope: Multisig, depth: number): void {
|
|
381
|
+
const missing: string[] = []
|
|
382
|
+
if (!envelope.account) missing.push('account')
|
|
383
|
+
if (!Array.isArray(envelope.signatures)) missing.push('signatures')
|
|
384
|
+
if (missing.length > 0)
|
|
385
|
+
throw new MissingPropertiesError({
|
|
386
|
+
envelope,
|
|
387
|
+
missing,
|
|
388
|
+
type: 'multisig',
|
|
389
|
+
})
|
|
390
|
+
if (depth > MultisigConfig.maxNestingDepth)
|
|
391
|
+
throw new InvalidMultisigApprovalError({
|
|
392
|
+
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
393
|
+
})
|
|
394
|
+
if (!Address.validate(envelope.account))
|
|
395
|
+
throw new InvalidMultisigApprovalError({
|
|
396
|
+
reason: 'multisig account is invalid',
|
|
397
|
+
})
|
|
398
|
+
if (Hex.toBigInt(envelope.account) === 0n)
|
|
399
|
+
throw new InvalidMultisigApprovalError({
|
|
400
|
+
reason: 'multisig account cannot be zero',
|
|
401
|
+
})
|
|
402
|
+
if (envelope.signatures.length === 0)
|
|
403
|
+
throw new InvalidMultisigApprovalError({
|
|
404
|
+
reason: 'multisig signatures cannot be empty',
|
|
405
|
+
})
|
|
406
|
+
if (envelope.signatures.length > MultisigConfig.maxSignatures)
|
|
407
|
+
throw new InvalidMultisigApprovalError({
|
|
408
|
+
reason: `multisig signatures exceed ${MultisigConfig.maxSignatures}`,
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
if (envelope.init) {
|
|
412
|
+
MultisigConfig.assert(envelope.init)
|
|
413
|
+
if (
|
|
414
|
+
!Address.isEqual(
|
|
415
|
+
MultisigConfig.getAddress(envelope.init),
|
|
416
|
+
envelope.account,
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
throw new InvalidMultisigApprovalError({
|
|
420
|
+
reason: 'multisig init does not derive account',
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
for (const inner of envelope.signatures) {
|
|
425
|
+
const type = getType(inner)
|
|
426
|
+
if (type === 'keychain')
|
|
427
|
+
throw new InvalidMultisigApprovalError({
|
|
428
|
+
reason: 'keychain owner approvals are not allowed',
|
|
429
|
+
})
|
|
430
|
+
if (type === 'multisig') {
|
|
431
|
+
const multisig = inner as Multisig
|
|
432
|
+
if (multisig.init)
|
|
433
|
+
throw new InvalidMultisigApprovalError({
|
|
434
|
+
reason: 'nested multisig owner approvals cannot carry `init`',
|
|
435
|
+
})
|
|
436
|
+
assertMultisig(multisig, depth + 1)
|
|
437
|
+
} else assert(inner)
|
|
438
|
+
|
|
439
|
+
if (Hex.size(serialize(inner)) > MultisigConfig.maxOwnerSignatureBytes)
|
|
440
|
+
throw new InvalidMultisigApprovalError({
|
|
441
|
+
reason: `multisig owner signature exceeds ${MultisigConfig.maxOwnerSignatureBytes} bytes`,
|
|
442
|
+
})
|
|
443
|
+
}
|
|
384
444
|
}
|
|
385
445
|
|
|
386
446
|
/**
|
|
@@ -536,6 +596,13 @@ export declare namespace extractPublicKey {
|
|
|
536
596
|
* @throws `CoercionError` if the serialized value cannot be coerced to a valid signature envelope.
|
|
537
597
|
*/
|
|
538
598
|
export function deserialize(value: Serialized): SignatureEnvelope {
|
|
599
|
+
return deserialize_(value, 0)
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function deserialize_(
|
|
603
|
+
value: Serialized,
|
|
604
|
+
multisigDepth: number,
|
|
605
|
+
): SignatureEnvelope {
|
|
539
606
|
const serialized = value.endsWith(magicBytes.slice(2))
|
|
540
607
|
? Hex.slice(value, 0, -Hex.size(magicBytes))
|
|
541
608
|
: value
|
|
@@ -638,7 +705,7 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
638
705
|
typeId === serializedKeychainV2Type
|
|
639
706
|
) {
|
|
640
707
|
const userAddress = Hex.slice(data, 0, 20)
|
|
641
|
-
const inner =
|
|
708
|
+
const inner = deserialize_(Hex.slice(data, 20), multisigDepth)
|
|
642
709
|
|
|
643
710
|
return {
|
|
644
711
|
userAddress,
|
|
@@ -649,28 +716,91 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
649
716
|
}
|
|
650
717
|
|
|
651
718
|
if (typeId === serializedMultisigType) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
// omitted entirely (the empty `0x80` placeholder is rejected).
|
|
655
|
-
const [account, signatures, init] = Rlp.toHex(data) as [
|
|
656
|
-
Hex.Hex,
|
|
657
|
-
readonly Hex.Hex[],
|
|
658
|
-
(Hex.Hex | MultisigConfig.Tuple)?,
|
|
659
|
-
]
|
|
660
|
-
if (typeof init !== 'undefined' && !Array.isArray(init))
|
|
719
|
+
const depth = multisigDepth + 1
|
|
720
|
+
if (depth > MultisigConfig.maxNestingDepth)
|
|
661
721
|
throw new InvalidSerializedError({
|
|
662
|
-
reason:
|
|
663
|
-
'Invalid multisig `init`: expected the bootstrap config list or an omitted trailing element',
|
|
722
|
+
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
664
723
|
serialized,
|
|
665
724
|
})
|
|
666
|
-
|
|
725
|
+
|
|
726
|
+
// The first field distinguishes the static wire shapes: a bootstrap init
|
|
727
|
+
// config is an RLP list, while an initialized account is a 20-byte string.
|
|
728
|
+
const decoded = Rlp.toHex(data)
|
|
729
|
+
if (!Array.isArray(decoded) || decoded.length !== 2)
|
|
730
|
+
throw new InvalidSerializedError({
|
|
731
|
+
reason: 'invalid multisig wire shape: expected exactly two fields',
|
|
732
|
+
serialized,
|
|
733
|
+
})
|
|
734
|
+
|
|
735
|
+
const [address, signatures] = decoded
|
|
736
|
+
if (!Array.isArray(signatures) || signatures.some(Array.isArray))
|
|
737
|
+
throw new InvalidSerializedError({
|
|
738
|
+
reason: 'invalid multisig signatures list',
|
|
739
|
+
serialized,
|
|
740
|
+
})
|
|
741
|
+
if (signatures.length === 0)
|
|
742
|
+
throw new InvalidSerializedError({
|
|
743
|
+
reason: 'multisig signatures cannot be empty',
|
|
744
|
+
serialized,
|
|
745
|
+
})
|
|
746
|
+
if (signatures.length > MultisigConfig.maxSignatures)
|
|
747
|
+
throw new InvalidSerializedError({
|
|
748
|
+
reason: `multisig signatures exceed ${MultisigConfig.maxSignatures}`,
|
|
749
|
+
serialized,
|
|
750
|
+
})
|
|
751
|
+
for (const signature of signatures)
|
|
752
|
+
if (
|
|
753
|
+
Hex.size(signature as Hex.Hex) > MultisigConfig.maxOwnerSignatureBytes
|
|
754
|
+
)
|
|
755
|
+
throw new InvalidSerializedError({
|
|
756
|
+
reason: `multisig owner signature exceeds ${MultisigConfig.maxOwnerSignatureBytes} bytes`,
|
|
757
|
+
serialized,
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
if (!Array.isArray(address) && !Address.validate(address))
|
|
761
|
+
throw new InvalidSerializedError({
|
|
762
|
+
reason: 'invalid multisig account',
|
|
763
|
+
serialized,
|
|
764
|
+
})
|
|
765
|
+
if (Array.isArray(address)) {
|
|
766
|
+
const [salt, threshold, owners] = address
|
|
767
|
+
if (
|
|
768
|
+
address.length !== 3 ||
|
|
769
|
+
Array.isArray(salt) ||
|
|
770
|
+
Hex.size(salt) !== 32 ||
|
|
771
|
+
Array.isArray(threshold) ||
|
|
772
|
+
Hex.size(threshold) > 1 ||
|
|
773
|
+
!Array.isArray(owners) ||
|
|
774
|
+
owners.some(
|
|
775
|
+
(owner) =>
|
|
776
|
+
!Array.isArray(owner) ||
|
|
777
|
+
owner.length !== 2 ||
|
|
778
|
+
owner.some(Array.isArray) ||
|
|
779
|
+
Hex.size(owner[1] as Hex.Hex) > 1,
|
|
780
|
+
)
|
|
781
|
+
)
|
|
782
|
+
throw new InvalidSerializedError({
|
|
783
|
+
reason: 'invalid multisig init config',
|
|
784
|
+
serialized,
|
|
785
|
+
})
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const init = Array.isArray(address)
|
|
789
|
+
? MultisigConfig.fromTuple(address as unknown as MultisigConfig.Tuple)
|
|
790
|
+
: undefined
|
|
791
|
+
const account = init
|
|
792
|
+
? MultisigConfig.getAddress(init)
|
|
793
|
+
: (address as Address.Address)
|
|
794
|
+
const envelope = {
|
|
667
795
|
type: 'multisig',
|
|
668
796
|
account,
|
|
669
|
-
signatures: signatures.map((signature) =>
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
797
|
+
signatures: signatures.map((signature) =>
|
|
798
|
+
deserialize_(signature as Hex.Hex, depth),
|
|
799
|
+
),
|
|
800
|
+
...(init ? { init } : {}),
|
|
673
801
|
} satisfies Multisig
|
|
802
|
+
assertMultisig(envelope, depth)
|
|
803
|
+
return envelope
|
|
674
804
|
}
|
|
675
805
|
|
|
676
806
|
throw new InvalidSerializedError({
|
|
@@ -1076,19 +1206,28 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
|
1076
1206
|
}
|
|
1077
1207
|
|
|
1078
1208
|
if (
|
|
1079
|
-
envelope.type === 'multisig' ||
|
|
1080
|
-
('
|
|
1209
|
+
(envelope as { type?: string | undefined }).type === 'multisig' ||
|
|
1210
|
+
('signatures' in envelope && ('account' in envelope || 'init' in envelope))
|
|
1081
1211
|
) {
|
|
1082
1212
|
const multisig = envelope as MultisigRpc
|
|
1083
|
-
|
|
1213
|
+
const hasAccount = typeof multisig.account !== 'undefined'
|
|
1214
|
+
const hasInit = typeof multisig.init !== 'undefined'
|
|
1215
|
+
if (hasAccount === hasInit)
|
|
1216
|
+
throw new InvalidMultisigApprovalError({
|
|
1217
|
+
reason: 'RPC multisig must contain exactly one of `account` or `init`',
|
|
1218
|
+
})
|
|
1219
|
+
const init = hasInit
|
|
1220
|
+
? MultisigConfig.from(multisig.init as MultisigConfig.Config)
|
|
1221
|
+
: undefined
|
|
1222
|
+
const account = init ? MultisigConfig.getAddress(init) : multisig.account
|
|
1223
|
+
const result = {
|
|
1084
1224
|
type: 'multisig',
|
|
1085
|
-
account:
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1225
|
+
account: account as Address.Address,
|
|
1226
|
+
signatures: multisig.signatures.map((signature) => fromRpc(signature)),
|
|
1227
|
+
...(init ? { init } : {}),
|
|
1228
|
+
} satisfies Multisig
|
|
1229
|
+
assert(result)
|
|
1230
|
+
return result
|
|
1092
1231
|
}
|
|
1093
1232
|
|
|
1094
1233
|
throw new CoercionError({ envelope })
|
|
@@ -1096,8 +1235,10 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
|
1096
1235
|
|
|
1097
1236
|
export declare namespace fromRpc {
|
|
1098
1237
|
type ErrorType =
|
|
1238
|
+
| assert.ErrorType
|
|
1099
1239
|
| CoercionError
|
|
1100
1240
|
| InvalidSerializedError
|
|
1241
|
+
| MultisigConfig.getAddress.ErrorType
|
|
1101
1242
|
| Signature.fromRpc.ErrorType
|
|
1102
1243
|
| Errors.GlobalErrorType
|
|
1103
1244
|
}
|
|
@@ -1173,7 +1314,9 @@ export function getType<
|
|
|
1173
1314
|
|
|
1174
1315
|
// Detect Multisig signature
|
|
1175
1316
|
if (
|
|
1176
|
-
('account' in envelope ||
|
|
1317
|
+
('account' in envelope ||
|
|
1318
|
+
'genesisConfig' in envelope ||
|
|
1319
|
+
'init' in envelope) &&
|
|
1177
1320
|
'signatures' in envelope
|
|
1178
1321
|
)
|
|
1179
1322
|
return 'multisig' as never
|
|
@@ -1192,6 +1335,7 @@ export function getType<
|
|
|
1192
1335
|
* - WebAuthn: `0x02` + webauthnData (variable) + r (32) + s (32) + pubKeyX (32) + pubKeyY (32)
|
|
1193
1336
|
* - Keychain V1: `0x03` + userAddress (20) + inner signature (recursive)
|
|
1194
1337
|
* - Keychain V2: `0x04` + userAddress (20) + inner signature (recursive)
|
|
1338
|
+
* - Multisig: `0x05` + RLP `[account | init, signatures]`
|
|
1195
1339
|
*
|
|
1196
1340
|
* [Signature Types](https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction#signature-types)
|
|
1197
1341
|
*
|
|
@@ -1277,15 +1421,16 @@ export function serialize(
|
|
|
1277
1421
|
|
|
1278
1422
|
if (type === 'multisig') {
|
|
1279
1423
|
const multisig = envelope as Multisig
|
|
1280
|
-
|
|
1281
|
-
//
|
|
1282
|
-
//
|
|
1424
|
+
assert(multisig)
|
|
1425
|
+
// The first field is either the initialized account or the bootstrap init
|
|
1426
|
+
// config. Each owner approval is an encoded signature.
|
|
1283
1427
|
return Hex.concat(
|
|
1284
1428
|
serializedMultisigType,
|
|
1285
1429
|
Rlp.fromHex([
|
|
1286
|
-
multisig.
|
|
1430
|
+
multisig.init
|
|
1431
|
+
? MultisigConfig.toTuple(multisig.init)
|
|
1432
|
+
: multisig.account,
|
|
1287
1433
|
multisig.signatures.map((signature) => serialize(signature)),
|
|
1288
|
-
...(multisig.init ? [MultisigConfig.toTuple(multisig.init)] : []),
|
|
1289
1434
|
]),
|
|
1290
1435
|
options.magic ? magicBytes : '0x',
|
|
1291
1436
|
)
|
|
@@ -1302,6 +1447,16 @@ export declare namespace serialize {
|
|
|
1302
1447
|
*/
|
|
1303
1448
|
magic?: boolean | undefined
|
|
1304
1449
|
}
|
|
1450
|
+
|
|
1451
|
+
type ErrorType =
|
|
1452
|
+
| assert.ErrorType
|
|
1453
|
+
| CoercionError
|
|
1454
|
+
| Hex.concat.ErrorType
|
|
1455
|
+
| Hex.fromNumber.ErrorType
|
|
1456
|
+
| Hex.fromString.ErrorType
|
|
1457
|
+
| Rlp.fromHex.ErrorType
|
|
1458
|
+
| Signature.toHex.ErrorType
|
|
1459
|
+
| Errors.GlobalErrorType
|
|
1305
1460
|
}
|
|
1306
1461
|
|
|
1307
1462
|
/**
|
|
@@ -1435,7 +1590,9 @@ export declare namespace sortMultisigApprovals {
|
|
|
1435
1590
|
* @param envelope - The signature envelope to convert.
|
|
1436
1591
|
* @returns The RPC signature envelope with hex values.
|
|
1437
1592
|
*/
|
|
1438
|
-
export function toRpc
|
|
1593
|
+
export function toRpc<const envelope extends toRpc.Input>(
|
|
1594
|
+
envelope: envelope,
|
|
1595
|
+
): toRpc.ReturnType<envelope> {
|
|
1439
1596
|
const type = getType(envelope)
|
|
1440
1597
|
|
|
1441
1598
|
if (type === 'secp256k1') {
|
|
@@ -1443,7 +1600,7 @@ export function toRpc(envelope: toRpc.Input): SignatureEnvelopeRpc {
|
|
|
1443
1600
|
return {
|
|
1444
1601
|
...Signature.toRpc(secp256k1.signature),
|
|
1445
1602
|
type: 'secp256k1',
|
|
1446
|
-
}
|
|
1603
|
+
} as never
|
|
1447
1604
|
}
|
|
1448
1605
|
|
|
1449
1606
|
if (type === 'p256') {
|
|
@@ -1455,7 +1612,7 @@ export function toRpc(envelope: toRpc.Input): SignatureEnvelopeRpc {
|
|
|
1455
1612
|
r: p256.signature.r,
|
|
1456
1613
|
s: p256.signature.s,
|
|
1457
1614
|
type: 'p256',
|
|
1458
|
-
}
|
|
1615
|
+
} as never
|
|
1459
1616
|
}
|
|
1460
1617
|
|
|
1461
1618
|
if (type === 'webAuthn') {
|
|
@@ -1472,7 +1629,7 @@ export function toRpc(envelope: toRpc.Input): SignatureEnvelopeRpc {
|
|
|
1472
1629
|
s: webauthn.signature.s,
|
|
1473
1630
|
type: 'webAuthn',
|
|
1474
1631
|
webauthnData,
|
|
1475
|
-
}
|
|
1632
|
+
} as never
|
|
1476
1633
|
}
|
|
1477
1634
|
|
|
1478
1635
|
if (type === 'keychain') {
|
|
@@ -1483,18 +1640,32 @@ export function toRpc(envelope: toRpc.Input): SignatureEnvelopeRpc {
|
|
|
1483
1640
|
signature: toRpc(keychain.inner),
|
|
1484
1641
|
...(keychain.keyId ? { keyId: keychain.keyId } : {}),
|
|
1485
1642
|
...(keychain.version ? { version: keychain.version } : {}),
|
|
1486
|
-
}
|
|
1643
|
+
} as never
|
|
1487
1644
|
}
|
|
1488
1645
|
|
|
1489
1646
|
if (type === 'multisig') {
|
|
1490
1647
|
const multisig = envelope as Multisig
|
|
1648
|
+
assert(multisig)
|
|
1649
|
+
const signatures = multisig.signatures.map((signature) => toRpc(signature))
|
|
1650
|
+
if (multisig.init) {
|
|
1651
|
+
const init = {
|
|
1652
|
+
...multisig.init,
|
|
1653
|
+
salt: multisig.init.salt ?? MultisigConfig.zeroSalt,
|
|
1654
|
+
threshold: Number(multisig.init.threshold),
|
|
1655
|
+
owners: multisig.init.owners.map((owner) => ({
|
|
1656
|
+
...owner,
|
|
1657
|
+
weight: Number(owner.weight),
|
|
1658
|
+
})),
|
|
1659
|
+
}
|
|
1660
|
+
return {
|
|
1661
|
+
init,
|
|
1662
|
+
signatures,
|
|
1663
|
+
} as never
|
|
1664
|
+
}
|
|
1491
1665
|
return {
|
|
1492
|
-
type: 'multisig',
|
|
1493
1666
|
account: multisig.account,
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
...(multisig.init ? { init: multisig.init } : {}),
|
|
1497
|
-
}
|
|
1667
|
+
signatures,
|
|
1668
|
+
} as never
|
|
1498
1669
|
}
|
|
1499
1670
|
|
|
1500
1671
|
throw new CoercionError({ envelope })
|
|
@@ -1504,7 +1675,22 @@ export declare namespace toRpc {
|
|
|
1504
1675
|
/** Numberish input accepted by {@link ox#SignatureEnvelope.(toRpc:function)}. */
|
|
1505
1676
|
type Input = SignatureEnvelope<Hex.Hex | number>
|
|
1506
1677
|
|
|
1678
|
+
/** RPC signature envelope inferred from the input type. */
|
|
1679
|
+
type ReturnType<envelope extends Input = Input> =
|
|
1680
|
+
GetType<envelope> extends 'secp256k1'
|
|
1681
|
+
? Secp256k1Rpc
|
|
1682
|
+
: GetType<envelope> extends 'p256'
|
|
1683
|
+
? P256Rpc
|
|
1684
|
+
: GetType<envelope> extends 'webAuthn'
|
|
1685
|
+
? WebAuthnRpc
|
|
1686
|
+
: GetType<envelope> extends 'keychain'
|
|
1687
|
+
? KeychainRpc
|
|
1688
|
+
: GetType<envelope> extends 'multisig'
|
|
1689
|
+
? MultisigRpc
|
|
1690
|
+
: SignatureEnvelopeRpc
|
|
1691
|
+
|
|
1507
1692
|
type ErrorType =
|
|
1693
|
+
| assert.ErrorType
|
|
1508
1694
|
| CoercionError
|
|
1509
1695
|
| Signature.toRpc.ErrorType
|
|
1510
1696
|
| Errors.GlobalErrorType
|