accounts 0.18.5 → 0.19.0
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 +10 -0
- package/dist/core/AccessKey.d.ts +5 -1
- package/dist/core/AccessKey.d.ts.map +1 -1
- package/dist/core/AccessKey.js +2 -0
- package/dist/core/AccessKey.js.map +1 -1
- package/dist/core/ExecutionError.d.ts.map +1 -1
- package/dist/core/ExecutionError.js +38 -3
- package/dist/core/ExecutionError.js.map +1 -1
- package/dist/core/Schema.d.ts +15 -0
- package/dist/core/Schema.d.ts.map +1 -1
- package/dist/core/zod/rpc.d.ts +1 -0
- package/dist/core/zod/rpc.d.ts.map +1 -1
- package/dist/core/zod/rpc.js +1 -1
- package/dist/core/zod/rpc.js.map +1 -1
- package/dist/server/CliAuth.d.ts.map +1 -1
- package/dist/server/CliAuth.js +6 -4
- package/dist/server/CliAuth.js.map +1 -1
- package/dist/server/internal/handlers/relay.d.ts +0 -7
- package/dist/server/internal/handlers/relay.d.ts.map +1 -1
- package/dist/server/internal/handlers/relay.js +0 -46
- package/dist/server/internal/handlers/relay.js.map +1 -1
- package/dist/server/internal/handlers/sponsorship.d.ts +0 -2
- package/dist/server/internal/handlers/sponsorship.d.ts.map +1 -1
- package/dist/server/internal/handlers/sponsorship.js +1 -2
- package/dist/server/internal/handlers/sponsorship.js.map +1 -1
- package/package.json +6 -6
- package/src/cli/Provider.localnet.test.ts +3 -3
- package/src/core/AccessKey.permissions.test.ts +73 -0
- package/src/core/AccessKey.test.ts +29 -27
- package/src/core/AccessKey.ts +7 -1
- package/src/core/ExecutionError.ts +39 -3
- package/src/core/Provider.localnet.test.ts +2 -1
- package/src/core/adapters/deviceCode/deviceCode.localnet.test.ts +4 -1
- package/src/core/adapters/privy.test.ts +1 -1
- package/src/core/zod/rpc.ts +2 -1
- package/src/server/CliAuth.test.ts +5 -3
- package/src/server/CliAuth.ts +6 -4
- package/src/server/internal/handlers/relay.ts +0 -56
- package/src/server/internal/handlers/sponsorship.ts +1 -4
- package/dist/server/internal/handlers/multisig.d.ts +0 -214
- package/dist/server/internal/handlers/multisig.d.ts.map +0 -1
- package/dist/server/internal/handlers/multisig.js +0 -505
- package/dist/server/internal/handlers/multisig.js.map +0 -1
- package/src/server/internal/handlers/multisig.localnet.test.ts +0 -94
- package/src/server/internal/handlers/multisig.test.ts +0 -743
- package/src/server/internal/handlers/multisig.ts +0 -774
|
@@ -21,7 +21,6 @@ export type Rpc = UnionOmit<ExecutionError, 'args'>
|
|
|
21
21
|
/** Human-readable messages keyed by ABI error name. */
|
|
22
22
|
export const messages: Record<AbiErrorName, string> = {
|
|
23
23
|
AbdicationAlreadyScheduled: 'Capability {0} abdication is already scheduled.',
|
|
24
|
-
AccountAlreadyInitialized: 'Account already initialized.',
|
|
25
24
|
AccountNotAllowed: 'Account {0} is not allowed.',
|
|
26
25
|
ActiveLeaderRemoved: 'The active leader cannot be removed.',
|
|
27
26
|
ActiveSupplyWithoutBacking: 'Active supply has no backing.',
|
|
@@ -32,6 +31,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
32
31
|
AlreadyInitialized: 'Already initialized.',
|
|
33
32
|
AmountExceedsDeposit: 'Amount exceeds deposit.',
|
|
34
33
|
AmountExceedsLimit: 'Amount exceeds limit.',
|
|
34
|
+
AmountIsZero: 'Amount cannot be zero.',
|
|
35
35
|
AmountNotIncreasing: 'Amount is not increasing.',
|
|
36
36
|
AmountOverflow: 'Amount overflow.',
|
|
37
37
|
AssetsNotArrived: 'Assets for request {0} have not arrived.',
|
|
@@ -56,6 +56,8 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
56
56
|
ContractPaused: 'Contract is paused.',
|
|
57
57
|
CreditExceedsBalance:
|
|
58
58
|
'Credit for asset {0} exceeds the balance. Available: {1}, requested total: {2}.',
|
|
59
|
+
CustomerIdIsZero: 'Customer ID cannot be zero.',
|
|
60
|
+
DeadlineExpired: 'Deadline {0} has expired at timestamp {1}.',
|
|
59
61
|
DepositBlockCapacityExceeded: 'Deposit block capacity of {0} exceeded.',
|
|
60
62
|
DepositOverflow: 'Deposit overflow.',
|
|
61
63
|
DepositTooSmall: 'Deposit too small.',
|
|
@@ -76,6 +78,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
76
78
|
EarnVaultNotSet: 'Earn vault is not set.',
|
|
77
79
|
EmptyDeploymentId: 'Deployment ID cannot be empty.',
|
|
78
80
|
EmptyEarnShareMetadata: 'Empty earn share metadata.',
|
|
81
|
+
EmptyInstallation: 'Installation cannot be empty.',
|
|
79
82
|
EmptyMetadata: 'Empty metadata.',
|
|
80
83
|
EmptyV1ValidatorSet: 'Validator set is empty.',
|
|
81
84
|
EncryptionKeyExpired: 'Encryption key {0}, activated at block {1}, expired at block {2}.',
|
|
@@ -86,6 +89,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
86
89
|
EngineEarnVaultMismatch: 'Engine earn vault mismatch.',
|
|
87
90
|
EngineExitUnsupported: 'This engine does not support exits.',
|
|
88
91
|
EngineSharesTooLarge: 'Engine share amount {0} is too large.',
|
|
92
|
+
ExactBalanceDeltaFailed: 'Balance change for {0} was {2}, expected {1}.',
|
|
89
93
|
ExceedsMaxEarnShares: 'Maximum earn shares exceeded.',
|
|
90
94
|
ExcessiveConversionLoss:
|
|
91
95
|
'Conversion loss is excessive. Input shares: {0}, represented shares: {1}.',
|
|
@@ -99,6 +103,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
99
103
|
FailedDeployment: 'Deployment failed.',
|
|
100
104
|
FeeValuationStale: 'Fee valuation is stale.',
|
|
101
105
|
FinalizedAssetMismatch: 'Finalized asset {0} does not match.',
|
|
106
|
+
FutureOracleTimestamp: 'Oracle timestamp {0} is after the current time ({1}).',
|
|
102
107
|
GasFeeRateTooHigh: 'Gas fee rate too high.',
|
|
103
108
|
GasLimitTooHigh: 'Gas limit too high.',
|
|
104
109
|
GlobalFeeDisableUnavailable: 'Global fee disabling is unavailable.',
|
|
@@ -117,11 +122,13 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
117
122
|
'Insufficient engine share surplus. Available: {0}, requested: {1}.',
|
|
118
123
|
InsufficientFeeTokenBalance: 'Insufficient fee token balance.',
|
|
119
124
|
InsufficientFunding: 'Insufficient funding. Required: {0}, actual: {1}.',
|
|
125
|
+
InsufficientInventory: 'Insufficient inventory for {0}: available {1}, required {2}.',
|
|
120
126
|
InsufficientLiquidity: 'Not enough liquidity in the order book to fill this trade.',
|
|
121
127
|
InsufficientOutput:
|
|
122
128
|
'The output amount is below the slippage minimum — try increasing slippage tolerance.',
|
|
123
129
|
InsufficientReserves: 'Insufficient reserves.',
|
|
124
130
|
InvalidAccount: 'Invalid account.',
|
|
131
|
+
InvalidAddress: 'Invalid address.',
|
|
125
132
|
InvalidAdmin: 'Invalid admin.',
|
|
126
133
|
InvalidAmount: 'Invalid amount.',
|
|
127
134
|
InvalidArrayLengths: 'Invalid array lengths.',
|
|
@@ -152,6 +159,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
152
159
|
InvalidEngine: 'Invalid engine.',
|
|
153
160
|
InvalidEngineShareScale: 'Invalid engine share scale.',
|
|
154
161
|
InvalidEphemeralPubkey: 'Invalid ephemeral pubkey.',
|
|
162
|
+
InvalidExistingDeployment: 'Existing deployment {0} is invalid.',
|
|
155
163
|
InvalidExpiringNonceExpiry: 'Invalid expiring nonce expiry.',
|
|
156
164
|
InvalidFallbackRecipient: 'Invalid fallback recipient.',
|
|
157
165
|
InvalidFeeClaimReceiver: 'Invalid fee claim receiver.',
|
|
@@ -163,16 +171,21 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
163
171
|
InvalidLeader: 'Invalid leader.',
|
|
164
172
|
InvalidLogoURI: 'Invalid logo URI.',
|
|
165
173
|
InvalidMasterAddress: 'Invalid master address.',
|
|
174
|
+
InvalidMaxOracleAge: 'Invalid maximum oracle age.',
|
|
175
|
+
InvalidMaxPriceDeviationBps: 'Maximum price deviation {0} exceeds {1} basis points.',
|
|
166
176
|
InvalidMaxRateAge: 'Invalid maximum rate age.',
|
|
167
177
|
InvalidMigrationIndex: 'Invalid migration index.',
|
|
168
178
|
InvalidMode: 'Invalid mode.',
|
|
169
179
|
InvalidMultiproof: 'Invalid multiproof.',
|
|
180
|
+
InvalidMultisigOwner: 'Invalid multisig owner.',
|
|
170
181
|
InvalidNonceKey: 'Invalid nonce key.',
|
|
182
|
+
InvalidOraclePriceToleranceBps: 'Oracle price tolerance {0} exceeds {1} basis points.',
|
|
171
183
|
InvalidOwner: 'Invalid owner.',
|
|
172
184
|
InvalidOwnerOrder: 'Invalid owner order.',
|
|
173
185
|
InvalidPayee: 'Invalid payee.',
|
|
174
186
|
InvalidPayload: 'Invalid payload.',
|
|
175
187
|
InvalidPolicyType: 'Invalid policy type.',
|
|
188
|
+
InvalidPrice: 'Invalid price.',
|
|
176
189
|
InvalidPrivateAsset: 'Invalid private asset.',
|
|
177
190
|
InvalidProof: 'Invalid proof.',
|
|
178
191
|
InvalidProofOfPossession: 'Invalid proof of possession.',
|
|
@@ -186,6 +199,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
186
199
|
InvalidRecoveryAuthority: 'Invalid recovery authority.',
|
|
187
200
|
InvalidReturnToken: 'Invalid return token.',
|
|
188
201
|
InvalidRevealTo: 'Invalid reveal to.',
|
|
202
|
+
InvalidRewardConfiguration: 'Invalid reward configuration.',
|
|
189
203
|
InvalidRoutePair: 'Invalid route pair.',
|
|
190
204
|
InvalidSequencerSet: 'Invalid sequencer set.',
|
|
191
205
|
InvalidSignature: 'Invalid signature.',
|
|
@@ -245,18 +259,21 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
245
259
|
NotEmergencyGuardianOrOperator: 'Caller is not the emergency guardian or operator.',
|
|
246
260
|
NotEngine: 'Not engine.',
|
|
247
261
|
NotFactory: 'Not factory.',
|
|
262
|
+
NotGuardianOrOwner: 'Not the guardian or owner.',
|
|
248
263
|
NotHostPort: '"{1}" is not a valid host:port for {0}.',
|
|
249
264
|
NotInitialized: 'Not initialized.',
|
|
250
265
|
NotIp: '"{0}" is not a valid IP address.',
|
|
251
266
|
NotIpPort: '"{1}" is not a valid IP:port for {0}.',
|
|
252
|
-
NotMultisigAccount: 'Not multisig account.',
|
|
253
267
|
NotOperator: 'Not operator.',
|
|
254
268
|
NotOwner: 'Not owner.',
|
|
255
269
|
NotPauseAuthority: 'Not pause authority.',
|
|
270
|
+
NotPaused: 'Not paused.',
|
|
256
271
|
NotPayeeOrOperator: 'Not payee or operator.',
|
|
257
272
|
NotPayer: 'Not payer.',
|
|
258
273
|
NotPendingAdmin: 'Not pending admin.',
|
|
259
274
|
NotPendingDistributor: 'Not pending distributor.',
|
|
275
|
+
NotPendingOperator: 'Not the pending operator.',
|
|
276
|
+
NotPendingOwner: 'Not the pending owner.',
|
|
260
277
|
NotRequesterOrJanitor: 'Caller is not the requester or janitor.',
|
|
261
278
|
NotSelf: 'Not self.',
|
|
262
279
|
NotSequencer: 'Not sequencer.',
|
|
@@ -266,6 +283,10 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
266
283
|
OnlySequencer: 'Only the sequencer may call this function.',
|
|
267
284
|
OnlyZoneInbox: 'Only the zone inbox may call this function.',
|
|
268
285
|
OperatorMigrationDisabled: 'Operator migration disabled.',
|
|
286
|
+
OperatorTransferNotPending: 'No operator transfer is pending.',
|
|
287
|
+
OracleDecimalsChanged: 'Oracle decimals changed from {0} to {1}.',
|
|
288
|
+
OraclePriceToleranceExceeded: 'Oracle price {1} differs from {0} by more than {2} basis points.',
|
|
289
|
+
OracleTimestampTooOld: 'Oracle timestamp {1} is before the minimum ({0}).',
|
|
269
290
|
OrderDoesNotExist: 'No order exists with the given ID.',
|
|
270
291
|
OrderNotStale: 'This order is not yet eligible for stale-cleanup.',
|
|
271
292
|
OwnableInvalidOwner: 'Owner {0} is invalid.',
|
|
@@ -281,13 +302,18 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
281
302
|
PolicyNotFound: 'Policy not found.',
|
|
282
303
|
PolicyNotSimple: 'Policy is not a simple policy.',
|
|
283
304
|
PortalIsPaused: 'Portal is paused.',
|
|
305
|
+
PriceAnchorNotInitialized: 'Price anchor is not initialized for direction {0}.',
|
|
306
|
+
PriceDeviationExceeded:
|
|
307
|
+
'Price {1} deviates from anchor {2} by more than {3} basis points for direction {0}.',
|
|
284
308
|
ProofOfWorkFailed: 'Proof of work failed.',
|
|
285
309
|
ProtectedAddress: 'Address is protected.',
|
|
286
310
|
ProtocolNonceNotSupported: 'Protocol nonce is not supported.',
|
|
287
311
|
PublicKeyAlreadyExists: 'Public key already exists.',
|
|
288
312
|
QueueTrackingDisabled: 'Tracking is disabled for queue {0}.',
|
|
289
313
|
QueueUnavailable: 'Queue unavailable.',
|
|
314
|
+
QueuedAssetsBelowMinimum: 'Queued assets ({1}) are below the minimum ({0}).',
|
|
290
315
|
RateChangedWithinTransaction: 'Rate changed within the transaction. Expected {0}, got {1}.',
|
|
316
|
+
RecipientNotAllowed: 'Recipient {0} is not allowed.',
|
|
291
317
|
ReentrancyGuardReentrantCall: 'Reentrant call blocked.',
|
|
292
318
|
ReentrantCall: 'Reentrant call blocked.',
|
|
293
319
|
ReentrantWithdrawal: 'Reentrant withdrawal blocked.',
|
|
@@ -299,18 +325,22 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
299
325
|
RootTotalDecreased: 'Root total decreased from {0} to {1}.',
|
|
300
326
|
RootTotalExceeded: 'Requested amount {0} exceeds the remaining entitlement {1}.',
|
|
301
327
|
SameEngine: 'Same engine.',
|
|
302
|
-
|
|
328
|
+
SameToken: 'Tokens must be different.',
|
|
303
329
|
SequencerConfigurationUnchanged: 'Sequencer configuration unchanged.',
|
|
330
|
+
SettlementAlreadyConsumed: 'Settlement {0} has already been consumed.',
|
|
304
331
|
SignatureTypeMismatch: 'Signature type mismatch. Expected {0}, got {1}.',
|
|
332
|
+
SlippageExceeded: 'Amount {1} exceeds slippage limit {0}.',
|
|
305
333
|
SolveUnderfunded: 'Solve for asset {0} is underfunded. Delivered: {1}, required: {2}.',
|
|
306
334
|
SpendingLimitExceeded: 'Spending limit exceeded.',
|
|
307
335
|
StaleAccountantRate: 'Accountant rate updated at {0} is stale at time {1}; maximum age is {2}.',
|
|
308
336
|
StaleLeadershipEpoch: 'Stale leadership epoch. Expected {0}, got {1}.',
|
|
337
|
+
StaleOraclePrice: 'Oracle price timestamp {0} exceeds the maximum age ({1}).',
|
|
309
338
|
StaleRootVersion: 'Stale root version. Expected {0}, got {1}.',
|
|
310
339
|
StaticCallNotAllowed: 'Static call not allowed.',
|
|
311
340
|
SupplyCapExceeded: 'Supply cap exceeded.',
|
|
312
341
|
SweepExceedsAvailableBalance:
|
|
313
342
|
'Sweep for token {0} exceeds the balance. Available: {1}, requested: {2}.',
|
|
343
|
+
TakerNotAllowed: 'Taker {0} is not allowed.',
|
|
314
344
|
TickOutOfBounds: 'Price tick {0} is outside the allowed range.',
|
|
315
345
|
TokenAlreadyEnabled: 'Token already enabled.',
|
|
316
346
|
TokenAlreadyExists: 'Token {0} already exists.',
|
|
@@ -319,6 +349,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
319
349
|
TokenEnablementBlockCapacityExceeded: 'Token enablement block capacity of {0} exceeded.',
|
|
320
350
|
TokenMetadataTooLong: 'Token metadata too long.',
|
|
321
351
|
TokenNotEnabled: 'Token not enabled.',
|
|
352
|
+
TokenTransferFailed: 'Transfer of token {0} failed.',
|
|
322
353
|
TokenTransferPolicyNotSet: 'Token transfer policy not set.',
|
|
323
354
|
TooManyOwners: 'Too many owners.',
|
|
324
355
|
TooManyWithdrawalsThisBlock: 'Too many withdrawals this block.',
|
|
@@ -327,6 +358,7 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
327
358
|
Unauthorized: 'Unauthorized.',
|
|
328
359
|
UnauthorizedCaller: 'Unauthorized caller.',
|
|
329
360
|
UnauthorizedClaimer: 'Unauthorized claimer.',
|
|
361
|
+
UnauthorizedMultisigCaller: 'Unauthorized multisig caller.',
|
|
330
362
|
UnexpectedAssetsReceived: 'Unexpected assets received. Expected {0}, got {1}.',
|
|
331
363
|
UnexpectedEarnShares: 'Unexpected earn shares. Reported: {0}, measured: {1}.',
|
|
332
364
|
UnexpectedRetainedAssets: 'Unexpected assets retained. Balance before: {0}, after: {1}.',
|
|
@@ -334,6 +366,8 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
334
366
|
UnexpectedVenueSharesQueued: 'Unexpected venue shares queued. Expected {0}, got {1}.',
|
|
335
367
|
Uninitialized: 'Uninitialized.',
|
|
336
368
|
UnsupportedAccountantFreshness: 'Accountant {0} does not support freshness checks.',
|
|
369
|
+
UnsupportedDecimals: 'Unsupported decimals: base {0}, quote {1}, oracle {2}.',
|
|
370
|
+
UnsupportedToken: 'Token {0} is not supported.',
|
|
337
371
|
UnsupportedTransferPolicy: 'Transfer policy {0} has unsupported type {1}.',
|
|
338
372
|
ValidatorAlreadyDeactivated: 'Validator is already deactivated.',
|
|
339
373
|
ValidatorAlreadyExists: 'Validator already exists.',
|
|
@@ -352,8 +386,10 @@ export const messages: Record<AbiErrorName, string> = {
|
|
|
352
386
|
ZeroMinimumAssets: 'Minimum assets cannot be zero.',
|
|
353
387
|
ZeroMinimumEarnShares: 'Minimum earn shares cannot be zero.',
|
|
354
388
|
ZeroMinimumEngineShares: 'Minimum engine shares cannot be zero.',
|
|
389
|
+
ZeroMinimumQueuedAssets: 'Minimum queued assets cannot be zero.',
|
|
355
390
|
ZeroPublicKey: 'Public key cannot be zero.',
|
|
356
391
|
ZeroRoot: 'Root cannot be zero.',
|
|
392
|
+
ZeroSettlementId: 'Settlement ID cannot be zero.',
|
|
357
393
|
ZeroStatementHash: 'Statement hash cannot be zero.',
|
|
358
394
|
}
|
|
359
395
|
|
|
@@ -1112,6 +1112,7 @@ describe.each(adapters)('$name', ({ adapter, name }: (typeof adapters)[number])
|
|
|
1112
1112
|
{
|
|
1113
1113
|
"contractAddress": null,
|
|
1114
1114
|
"feeToken": "0x20c0000000000000000000000000000000000000",
|
|
1115
|
+
"multisig": undefined,
|
|
1115
1116
|
"status": "success",
|
|
1116
1117
|
"to": "0x20c0000000000000000000000000000000000000",
|
|
1117
1118
|
"type": "0x76",
|
|
@@ -1389,7 +1390,7 @@ describe.each(adapters)('$name', ({ adapter, name }: (typeof adapters)[number])
|
|
|
1389
1390
|
from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
|
1390
1391
|
|
|
1391
1392
|
Details: plain send failure
|
|
1392
|
-
Version: viem@2.56.
|
|
1393
|
+
Version: viem@2.56.9]
|
|
1393
1394
|
`)
|
|
1394
1395
|
})
|
|
1395
1396
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Hex } from 'ox'
|
|
2
|
+
import { SignatureEnvelope } from 'ox/tempo'
|
|
2
3
|
import { describe, expect, test } from 'vp/test'
|
|
3
4
|
import type { DeviceCode } from 'wata'
|
|
4
5
|
|
|
@@ -61,7 +62,9 @@ describe('deviceCode', () => {
|
|
|
61
62
|
const keyAuthorization = account.capabilities.keyAuthorization
|
|
62
63
|
? {
|
|
63
64
|
...account.capabilities.keyAuthorization,
|
|
64
|
-
signature: {
|
|
65
|
+
signature: {
|
|
66
|
+
type: SignatureEnvelope.fromRpc(account.capabilities.keyAuthorization.signature).type,
|
|
67
|
+
},
|
|
65
68
|
}
|
|
66
69
|
: undefined
|
|
67
70
|
|
package/src/core/zod/rpc.ts
CHANGED
|
@@ -51,6 +51,7 @@ type KeyAuthorizationRpcDecoded = Omit<KeyAuthorization.Rpc, 'chainId' | 'expiry
|
|
|
51
51
|
address?: KeyAuthorization.Rpc['keyId'] | undefined
|
|
52
52
|
chainId: bigint
|
|
53
53
|
expiry: number | null | undefined
|
|
54
|
+
keyType: z.output<typeof keyType>
|
|
54
55
|
limits?:
|
|
55
56
|
| readonly {
|
|
56
57
|
token: KeyAuthorization.RpcTokenLimit['token']
|
|
@@ -133,7 +134,7 @@ export const keyAuthorization = z.codec(keyAuthorizationRpc, z.custom<KeyAuthori
|
|
|
133
134
|
chainId: keyAuthorization.chainId === '0x' ? 0n : Hex.toBigInt(keyAuthorization.chainId),
|
|
134
135
|
expiry: keyAuthorization.expiry == null ? null : Hex.toNumber(keyAuthorization.expiry),
|
|
135
136
|
keyId: keyAuthorization.keyId,
|
|
136
|
-
keyType: keyAuthorization.keyType,
|
|
137
|
+
keyType: z.parse(keyType, keyAuthorization.keyType),
|
|
137
138
|
limits: keyAuthorization.limits?.map(({ limit, period, token }) => ({
|
|
138
139
|
token,
|
|
139
140
|
limit: Hex.toBigInt(limit),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Base64, Hex } from 'ox'
|
|
2
|
-
import { KeyAuthorization } from 'ox/tempo'
|
|
2
|
+
import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo'
|
|
3
3
|
import { createClient, custom, encodeErrorResult, encodeFunctionResult } from 'viem'
|
|
4
4
|
import { Abis, Account as TempoAccount } from 'viem/tempo'
|
|
5
5
|
import { describe, expect, test } from 'vp/test'
|
|
@@ -89,6 +89,7 @@ async function authorize(
|
|
|
89
89
|
code,
|
|
90
90
|
keyAuthorization: z.decode(CliAuth.keyAuthorization, {
|
|
91
91
|
...keyAuthorization,
|
|
92
|
+
keyType: key.keyType,
|
|
92
93
|
address: keyAuthorization.keyId,
|
|
93
94
|
}),
|
|
94
95
|
} satisfies z.output<typeof CliAuth.authorizeRequest>
|
|
@@ -126,6 +127,7 @@ async function authorizeWebAuthn(
|
|
|
126
127
|
code,
|
|
127
128
|
keyAuthorization: z.decode(CliAuth.keyAuthorization, {
|
|
128
129
|
...keyAuthorization,
|
|
130
|
+
keyType: key.keyType,
|
|
129
131
|
address: keyAuthorization.keyId,
|
|
130
132
|
}),
|
|
131
133
|
} satisfies z.output<typeof CliAuth.authorizeRequest>
|
|
@@ -1199,7 +1201,7 @@ describe('poll', () => {
|
|
|
1199
1201
|
keyAuthorization: {
|
|
1200
1202
|
...first.keyAuthorization,
|
|
1201
1203
|
signature: {
|
|
1202
|
-
type: first.keyAuthorization.signature.type,
|
|
1204
|
+
type: SignatureEnvelope.fromRpc(first.keyAuthorization.signature).type,
|
|
1203
1205
|
},
|
|
1204
1206
|
},
|
|
1205
1207
|
}
|
|
@@ -1727,7 +1729,7 @@ describe('authorize', () => {
|
|
|
1727
1729
|
? {
|
|
1728
1730
|
...polled.keyAuthorization,
|
|
1729
1731
|
signature: {
|
|
1730
|
-
type: polled.keyAuthorization.signature.type,
|
|
1732
|
+
type: SignatureEnvelope.fromRpc(polled.keyAuthorization.signature).type,
|
|
1731
1733
|
},
|
|
1732
1734
|
}
|
|
1733
1735
|
: undefined
|
package/src/server/CliAuth.ts
CHANGED
|
@@ -765,11 +765,12 @@ export function from(options: from.Options = {}): CliAuth {
|
|
|
765
765
|
})
|
|
766
766
|
|
|
767
767
|
const client = options.client ?? cache.get(current.chainId)
|
|
768
|
+
const signature = SignatureEnvelope.fromRpc(actual.signature)
|
|
768
769
|
const valid = await verifyHash(client, {
|
|
769
770
|
address: options.request.accountAddress,
|
|
770
771
|
hash: TempoKeyAuthorization.getSignPayload(signed),
|
|
771
|
-
signature: SignatureEnvelope.serialize(
|
|
772
|
-
magic:
|
|
772
|
+
signature: SignatureEnvelope.serialize(signature, {
|
|
773
|
+
magic: signature.type === 'webAuthn',
|
|
773
774
|
}),
|
|
774
775
|
})
|
|
775
776
|
if (!valid) throw new Error('Key authorization signature is invalid.')
|
|
@@ -1258,11 +1259,12 @@ async function verifyKeyAuthorizationSignature(options: {
|
|
|
1258
1259
|
...(actual.limits ? { limits: actual.limits } : {}),
|
|
1259
1260
|
type: actual.keyType,
|
|
1260
1261
|
})
|
|
1262
|
+
const signature = SignatureEnvelope.fromRpc(actual.signature)
|
|
1261
1263
|
const valid = await verifyHash(options.client, {
|
|
1262
1264
|
address: options.account,
|
|
1263
1265
|
hash: TempoKeyAuthorization.getSignPayload(unsigned),
|
|
1264
|
-
signature: SignatureEnvelope.serialize(
|
|
1265
|
-
magic:
|
|
1266
|
+
signature: SignatureEnvelope.serialize(signature, {
|
|
1267
|
+
magic: signature.type === 'webAuthn',
|
|
1266
1268
|
}),
|
|
1267
1269
|
})
|
|
1268
1270
|
if (!valid) throw new Error('Key authorization signature is invalid.')
|
|
@@ -26,7 +26,6 @@ import { type Handler, from } from '../../Handler.js'
|
|
|
26
26
|
import * as Kv from '../../Kv.js'
|
|
27
27
|
import { cached } from '../kv.js'
|
|
28
28
|
import * as Tokenlist from '../tokenlist.js'
|
|
29
|
-
import * as Multisig from './multisig.js'
|
|
30
29
|
import * as Sponsorship from './sponsorship.js'
|
|
31
30
|
import * as Utils from './utils.js'
|
|
32
31
|
|
|
@@ -84,7 +83,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
84
83
|
...rest
|
|
85
84
|
} = options
|
|
86
85
|
const feePayerOptions = options.feePayer
|
|
87
|
-
const multisigOptions = options.multisig
|
|
88
86
|
|
|
89
87
|
// Resolves the verified tokenlist for `chainId`, sharing the KV cache with
|
|
90
88
|
// `Handler.exchange` so a single `kv: Kv.cloudflare(env.KV)` covers both.
|
|
@@ -519,33 +517,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
519
517
|
case 'eth_sendRawTransactionSync': {
|
|
520
518
|
try {
|
|
521
519
|
const serialized = params[0]
|
|
522
|
-
if (
|
|
523
|
-
multisigOptions &&
|
|
524
|
-
(request.method === 'eth_sendRawTransaction' ||
|
|
525
|
-
request.method === 'eth_sendRawTransactionSync') &&
|
|
526
|
-
typeof serialized === 'string' &&
|
|
527
|
-
Multisig.isMultisigTransaction(serialized as Hex.Hex)
|
|
528
|
-
) {
|
|
529
|
-
const result = await Multisig.handleRawTransaction({
|
|
530
|
-
claimTtl: multisigOptions.claimTtl,
|
|
531
|
-
finalize: multisigOptions.finalize,
|
|
532
|
-
getClient,
|
|
533
|
-
method: request.method,
|
|
534
|
-
request: { params: 'params' in request ? request.params : undefined },
|
|
535
|
-
resolveConfig: multisigOptions.resolveConfig,
|
|
536
|
-
sponsor: feePayerOptions
|
|
537
|
-
? {
|
|
538
|
-
account: feePayerOptions.account,
|
|
539
|
-
feeToken: feePayerOptions.feeToken,
|
|
540
|
-
resolveFeeToken: async (chainId) => (await getTokens(chainId))[0],
|
|
541
|
-
validate: feePayerOptions.validate,
|
|
542
|
-
}
|
|
543
|
-
: undefined,
|
|
544
|
-
store: multisigOptions.store,
|
|
545
|
-
})
|
|
546
|
-
return RpcResponse.from({ result } as never, { request } as never)
|
|
547
|
-
}
|
|
548
|
-
|
|
549
520
|
if (!feePayerOptions) {
|
|
550
521
|
// eth_signRawTransaction is a signing method that only the
|
|
551
522
|
// relay can fulfill — forwarding it to the RPC node returns
|
|
@@ -590,27 +561,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
590
561
|
}
|
|
591
562
|
}
|
|
592
563
|
|
|
593
|
-
case 'eth_getTransactionByHash':
|
|
594
|
-
case 'eth_getTransactionReceipt': {
|
|
595
|
-
try {
|
|
596
|
-
if (multisigOptions) {
|
|
597
|
-
const aliased = await Multisig.handleGetTransaction({
|
|
598
|
-
getClient,
|
|
599
|
-
method: request.method,
|
|
600
|
-
request: { params: 'params' in request ? request.params : undefined },
|
|
601
|
-
store: multisigOptions.store,
|
|
602
|
-
})
|
|
603
|
-
if (aliased)
|
|
604
|
-
return RpcResponse.from({ result: aliased.result } as never, { request } as never)
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
const result = await client.request(request as never)
|
|
608
|
-
return RpcResponse.from({ result }, { request })
|
|
609
|
-
} catch (error) {
|
|
610
|
-
return Utils.rpcErrorJson(request, error)
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
564
|
default: {
|
|
615
565
|
try {
|
|
616
566
|
const result = await client.request(request as never)
|
|
@@ -696,12 +646,6 @@ export namespace relay {
|
|
|
696
646
|
url?: string | undefined
|
|
697
647
|
}
|
|
698
648
|
| undefined
|
|
699
|
-
/**
|
|
700
|
-
* Native multisig configuration. When provided, the relay collects owner
|
|
701
|
-
* approvals from multisig raw transaction submissions and broadcasts once
|
|
702
|
-
* collected owner weight meets the configured threshold.
|
|
703
|
-
*/
|
|
704
|
-
multisig?: Multisig.Options | undefined
|
|
705
649
|
/**
|
|
706
650
|
* Relay features.
|
|
707
651
|
*
|
|
@@ -121,8 +121,7 @@ export async function handleRawTransaction(options: handleRawTransaction.Options
|
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
const transaction = Transaction.deserialize(serialized)
|
|
124
|
-
|
|
125
|
-
const sender = transaction.from ?? options.sender
|
|
124
|
+
const sender = transaction.from
|
|
126
125
|
|
|
127
126
|
// Sponsorship only applies after sender has signed original transaction.
|
|
128
127
|
if (!transaction.signature || !sender)
|
|
@@ -178,8 +177,6 @@ export declare namespace handleRawTransaction {
|
|
|
178
177
|
method: 'eth_signRawTransaction' | 'eth_sendRawTransaction' | 'eth_sendRawTransactionSync'
|
|
179
178
|
/** Incoming JSON-RPC request. */
|
|
180
179
|
request: { params?: readonly unknown[] | undefined }
|
|
181
|
-
/** Sender address to use if it cannot be recovered from the raw envelope. */
|
|
182
|
-
sender?: Address | undefined
|
|
183
180
|
/** Optional sponsorship approval callback. */
|
|
184
181
|
validate?: ((request: Transaction.TransactionRequest) => boolean | Promise<boolean>) | undefined
|
|
185
182
|
}
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { Hex } from 'ox';
|
|
2
|
-
import { MultisigConfig } from 'ox/tempo';
|
|
3
|
-
import type { Address, Client } from 'viem';
|
|
4
|
-
import type { LocalAccount } from 'viem/accounts';
|
|
5
|
-
import * as Sponsorship from './sponsorship.js';
|
|
6
|
-
/** Default submission-claim TTL in milliseconds. */
|
|
7
|
-
export declare const defaultClaimTtl = 30000;
|
|
8
|
-
/** Returns whether a raw transaction carries a native multisig signature. */
|
|
9
|
-
export declare function isMultisigTransaction(serialized: Hex.Hex): boolean;
|
|
10
|
-
/** Handles a native multisig raw transaction submission. */
|
|
11
|
-
export declare function handleRawTransaction(options: handleRawTransaction.Options): Promise<handleRawTransaction.ReturnType>;
|
|
12
|
-
export declare namespace handleRawTransaction {
|
|
13
|
-
/** Options for handling a raw multisig transaction submission. */
|
|
14
|
-
type Options = collect.Options;
|
|
15
|
-
/** Raw transaction handler return value. */
|
|
16
|
-
type ReturnType = Hex.Hex | unknown;
|
|
17
|
-
}
|
|
18
|
-
declare function collect(options: collect.Options): Promise<collect.ReturnType>;
|
|
19
|
-
/** Resolves a multisig operation id for standard transaction lookup methods. */
|
|
20
|
-
export declare function handleGetTransaction(options: handleGetTransaction.Options): Promise<handleGetTransaction.ReturnType>;
|
|
21
|
-
export declare namespace handleGetTransaction {
|
|
22
|
-
/** Options for resolving a multisig operation id through transaction lookup methods. */
|
|
23
|
-
type Options = {
|
|
24
|
-
/** Client resolver keyed by transaction `chainId`. */
|
|
25
|
-
getClient: (chainId?: number | undefined) => Client;
|
|
26
|
-
/** Standard transaction lookup method to handle. */
|
|
27
|
-
method: 'eth_getTransactionByHash' | 'eth_getTransactionReceipt';
|
|
28
|
-
/** Incoming JSON-RPC request. */
|
|
29
|
-
request: {
|
|
30
|
-
params?: readonly unknown[] | undefined;
|
|
31
|
-
};
|
|
32
|
-
/** Pending multisig operation store. */
|
|
33
|
-
store: Store;
|
|
34
|
-
};
|
|
35
|
-
/** Transaction lookup result wrapper. */
|
|
36
|
-
type ReturnType = {
|
|
37
|
-
result: unknown;
|
|
38
|
-
} | undefined;
|
|
39
|
-
}
|
|
40
|
-
declare namespace collect {
|
|
41
|
-
type Options = {
|
|
42
|
-
/** Submission claim TTL in milliseconds. @default 30000 */
|
|
43
|
-
claimTtl?: number | undefined;
|
|
44
|
-
/** How to broadcast once quorum is met. @default 'sync' */
|
|
45
|
-
finalize?: 'submitted' | 'sync' | undefined;
|
|
46
|
-
/** Client resolver keyed by transaction `chainId`. */
|
|
47
|
-
getClient: (chainId?: number | undefined) => Client;
|
|
48
|
-
/** Raw transaction method to handle. */
|
|
49
|
-
method: 'eth_sendRawTransaction' | 'eth_sendRawTransactionSync';
|
|
50
|
-
/** Incoming JSON-RPC request. */
|
|
51
|
-
request: {
|
|
52
|
-
params?: readonly unknown[] | undefined;
|
|
53
|
-
};
|
|
54
|
-
/** Resolves the genesis multisig config for quorum checks. */
|
|
55
|
-
resolveConfig?: ResolveConfig | undefined;
|
|
56
|
-
/** Optional fee payer used to sponsor finalized multisig transactions. */
|
|
57
|
-
sponsor?: Sponsor | undefined;
|
|
58
|
-
/** Pending multisig operation store. */
|
|
59
|
-
store: Store;
|
|
60
|
-
};
|
|
61
|
-
type ReturnType = {
|
|
62
|
-
/** Raw broadcast result once quorum is met and this caller claimed submission. */
|
|
63
|
-
broadcastResult?: unknown;
|
|
64
|
-
/** Structured operation claim status. */
|
|
65
|
-
status: ClaimSubmissionResult | {
|
|
66
|
-
operation: Operation;
|
|
67
|
-
status: 'claimed';
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/** Returns a stored native multisig operation status. */
|
|
72
|
-
export declare function getStatus(options: getStatus.Options): Promise<Status | null>;
|
|
73
|
-
export declare namespace getStatus {
|
|
74
|
-
/** Options for reading one multisig operation status. */
|
|
75
|
-
type Options = {
|
|
76
|
-
/** Operation id returned by a pending multisig submission. */
|
|
77
|
-
id: Hex.Hex;
|
|
78
|
-
/** Resolves the genesis multisig config for quorum status. */
|
|
79
|
-
resolveConfig?: ResolveConfig | undefined;
|
|
80
|
-
/** Pending multisig operation store. */
|
|
81
|
-
store: Store;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/** Returns pending native multisig operation statuses for an account. */
|
|
85
|
-
export declare function listStatuses(options: listStatuses.Options): Promise<readonly Status[]>;
|
|
86
|
-
export declare namespace listStatuses {
|
|
87
|
-
/** Options for listing multisig operation statuses. */
|
|
88
|
-
type Options = {
|
|
89
|
-
/** Native multisig account address. */
|
|
90
|
-
account: Address;
|
|
91
|
-
/** Resolves the genesis multisig config for quorum status. */
|
|
92
|
-
resolveConfig?: ResolveConfig | undefined;
|
|
93
|
-
/** Pending multisig operation store. */
|
|
94
|
-
store: Store;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
/** Creates an in-memory multisig operation store for development and tests only. */
|
|
98
|
-
export declare function memoryStore(): Store;
|
|
99
|
-
/** Native multisig relay options. */
|
|
100
|
-
export type Options = {
|
|
101
|
-
/** Submission claim TTL in milliseconds. @default 30000 */
|
|
102
|
-
claimTtl?: number | undefined;
|
|
103
|
-
/** How to broadcast once quorum is met. @default 'sync' */
|
|
104
|
-
finalize?: 'submitted' | 'sync' | undefined;
|
|
105
|
-
/** Resolves the genesis multisig config for quorum checks. */
|
|
106
|
-
resolveConfig?: ResolveConfig | undefined;
|
|
107
|
-
/** Pending multisig operation store. */
|
|
108
|
-
store: Store;
|
|
109
|
-
};
|
|
110
|
-
/** Resolves the genesis multisig config for quorum checks. */
|
|
111
|
-
export type ResolveConfig = (request: {
|
|
112
|
-
/** Native multisig account address. */
|
|
113
|
-
account: Address;
|
|
114
|
-
/** Transaction chain id. */
|
|
115
|
-
chainId: number;
|
|
116
|
-
/** Bootstrap config carried by the transaction, when present. */
|
|
117
|
-
init?: MultisigConfig.Config | undefined;
|
|
118
|
-
}) => MultisigConfig.Config | Promise<MultisigConfig.Config | undefined> | undefined;
|
|
119
|
-
/** Optional fee payer used to sponsor finalized multisig transactions. */
|
|
120
|
-
export type Sponsor = {
|
|
121
|
-
/** Account used as the fee payer. */
|
|
122
|
-
account: LocalAccount;
|
|
123
|
-
/** Fee token to set before fee payer signing. */
|
|
124
|
-
feeToken?: Address | undefined;
|
|
125
|
-
/** Resolves the default fee token for raw sponsorship. */
|
|
126
|
-
resolveFeeToken?: ((chainId: number) => Address | Promise<Address | undefined> | undefined) | undefined;
|
|
127
|
-
/** Optional sponsorship approval callback. */
|
|
128
|
-
validate?: Sponsorship.handleRawTransaction.Options['validate'];
|
|
129
|
-
};
|
|
130
|
-
/** Storage for native multisig operation approvals and submission claims. */
|
|
131
|
-
export type Store = {
|
|
132
|
-
/** Atomically claims submission for a quorum-ready operation. Only a `claimed` result may broadcast. */
|
|
133
|
-
claimSubmission: (operation: Operation, options: claimSubmission.Options) => Promise<ClaimSubmissionResult>;
|
|
134
|
-
/** Reads a stored operation. */
|
|
135
|
-
get: (id: Hex.Hex) => Promise<Operation | undefined>;
|
|
136
|
-
/** Lists non-submitted operations for a native multisig account address. */
|
|
137
|
-
listPendingByAddress: (address: Address) => Promise<readonly Operation[]>;
|
|
138
|
-
/** Saves a pending operation, preserving already-stored approvals. */
|
|
139
|
-
savePending: (operation: Operation) => Promise<Operation>;
|
|
140
|
-
/** Marks a claimed operation submitted with its real transaction hash. */
|
|
141
|
-
setSubmitted: (id: Hex.Hex, submittedHash: Hex.Hex) => Promise<Operation>;
|
|
142
|
-
};
|
|
143
|
-
/** `Store.claimSubmission` types. */
|
|
144
|
-
export declare namespace claimSubmission {
|
|
145
|
-
/** Options for claiming submission. */
|
|
146
|
-
type Options = {
|
|
147
|
-
/** Claim TTL in milliseconds. */
|
|
148
|
-
ttl: number;
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
/** Result of atomically claiming a multisig operation for submission. */
|
|
152
|
-
export type ClaimSubmissionResult = {
|
|
153
|
-
/** Operation this caller may broadcast. */
|
|
154
|
-
operation: Operation;
|
|
155
|
-
/** Claim status. */
|
|
156
|
-
status: 'claimed';
|
|
157
|
-
} | {
|
|
158
|
-
/** Current stored operation. */
|
|
159
|
-
operation: Operation;
|
|
160
|
-
/** Current non-claimed status. */
|
|
161
|
-
status: 'pending' | 'submitting' | 'submitted';
|
|
162
|
-
};
|
|
163
|
-
/** Stored native multisig operation. */
|
|
164
|
-
export type Operation = {
|
|
165
|
-
/** Native multisig account address. */
|
|
166
|
-
account: Address;
|
|
167
|
-
/** Transaction chain id. */
|
|
168
|
-
chainId: number;
|
|
169
|
-
/** Submission claim expiry timestamp in milliseconds. */
|
|
170
|
-
claimExpiresAt?: number | undefined;
|
|
171
|
-
/** Resolved genesis config used for approval checks. */
|
|
172
|
-
config?: MultisigConfig.Config | undefined;
|
|
173
|
-
/** Creation timestamp in milliseconds. */
|
|
174
|
-
createdAt: number;
|
|
175
|
-
/** Deterministic operation id. */
|
|
176
|
-
id: Hex.Hex;
|
|
177
|
-
/** Whether the finalized transaction must carry the genesis init config. */
|
|
178
|
-
init?: boolean | undefined;
|
|
179
|
-
/** Genesis init config to attach when finalizing a bootstrap transaction. */
|
|
180
|
-
initConfig?: MultisigConfig.Config | undefined;
|
|
181
|
-
/** Unsigned Tempo transaction sign payload. */
|
|
182
|
-
payload: Hex.Hex;
|
|
183
|
-
/** Collected owner approval signatures. */
|
|
184
|
-
signatures: readonly Hex.Hex[];
|
|
185
|
-
/** Operation state. */
|
|
186
|
-
status: 'pending' | 'submitting' | 'submitted';
|
|
187
|
-
/** Transaction hash once submitted. */
|
|
188
|
-
submittedHash?: Hex.Hex | undefined;
|
|
189
|
-
/** Last submitted serialized transaction carrying this operation. */
|
|
190
|
-
transaction: Hex.Hex;
|
|
191
|
-
/** Last update timestamp in milliseconds. */
|
|
192
|
-
updatedAt: number;
|
|
193
|
-
};
|
|
194
|
-
/** Native multisig operation status. */
|
|
195
|
-
export type Status = {
|
|
196
|
-
/** Native multisig account address. */
|
|
197
|
-
account: Address;
|
|
198
|
-
/** Transaction chain id. */
|
|
199
|
-
chainId: number;
|
|
200
|
-
/** Deterministic operation id. */
|
|
201
|
-
id: Hex.Hex;
|
|
202
|
-
/** Number of collected owner approvals. */
|
|
203
|
-
signatures: number;
|
|
204
|
-
/** Operation state. */
|
|
205
|
-
status: Operation['status'];
|
|
206
|
-
/** Submitted transaction hash. */
|
|
207
|
-
submittedHash?: Hex.Hex | undefined;
|
|
208
|
-
/** Required owner weight. */
|
|
209
|
-
threshold?: number | undefined;
|
|
210
|
-
/** Collected owner weight. */
|
|
211
|
-
weight?: number | undefined;
|
|
212
|
-
};
|
|
213
|
-
export {};
|
|
214
|
-
//# sourceMappingURL=multisig.d.ts.map
|