ox 0.14.55 → 0.14.57
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 +48 -0
- package/_cjs/tempo/{MultisigConfig.js → AccountConfig.js} +32 -9
- package/_cjs/tempo/AccountConfig.js.map +1 -0
- package/_cjs/tempo/{MultisigOperation.js → AccountOperation.js} +29 -29
- package/_cjs/tempo/AccountOperation.js.map +1 -0
- package/_cjs/tempo/{MultisigSimulation.js → AccountSimulation.js} +22 -13
- package/_cjs/tempo/AccountSimulation.js.map +1 -0
- package/_cjs/tempo/KeyAuthorization.js +10 -18
- package/_cjs/tempo/KeyAuthorization.js.map +1 -1
- package/_cjs/tempo/SignatureEnvelope.js +64 -64
- package/_cjs/tempo/SignatureEnvelope.js.map +1 -1
- package/_cjs/tempo/TransactionRequest.js +15 -10
- package/_cjs/tempo/TransactionRequest.js.map +1 -1
- package/_cjs/tempo/index.js +4 -4
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/tempo/{MultisigConfig.js → AccountConfig.js} +161 -64
- package/_esm/tempo/AccountConfig.js.map +1 -0
- package/_esm/tempo/{MultisigOperation.js → AccountOperation.js} +64 -64
- package/_esm/tempo/AccountOperation.js.map +1 -0
- package/_esm/tempo/{MultisigSimulation.js → AccountSimulation.js} +35 -25
- package/_esm/tempo/AccountSimulation.js.map +1 -0
- package/_esm/tempo/KeyAuthorization.js +16 -19
- package/_esm/tempo/KeyAuthorization.js.map +1 -1
- package/_esm/tempo/SignatureEnvelope.js +71 -71
- package/_esm/tempo/SignatureEnvelope.js.map +1 -1
- package/_esm/tempo/TransactionRequest.js +15 -10
- package/_esm/tempo/TransactionRequest.js.map +1 -1
- package/_esm/tempo/index.js +50 -48
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/tempo/{MultisigConfig.d.ts → AccountConfig.d.ts} +156 -66
- package/_types/tempo/AccountConfig.d.ts.map +1 -0
- package/_types/tempo/{MultisigOperation.d.ts → AccountOperation.d.ts} +62 -62
- package/_types/tempo/AccountOperation.d.ts.map +1 -0
- package/_types/tempo/{MultisigSimulation.d.ts → AccountSimulation.d.ts} +25 -21
- package/_types/tempo/AccountSimulation.d.ts.map +1 -0
- package/_types/tempo/KeyAuthorization.d.ts +28 -23
- package/_types/tempo/KeyAuthorization.d.ts.map +1 -1
- package/_types/tempo/RpcSchemaTempo.d.ts +13 -13
- package/_types/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/_types/tempo/SignatureEnvelope.d.ts +36 -33
- package/_types/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/_types/tempo/TransactionRequest.d.ts +11 -9
- package/_types/tempo/TransactionRequest.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +50 -48
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/version.d.ts +1 -1
- package/package.json +31 -31
- package/tempo/AccountConfig/package.json +6 -0
- package/tempo/AccountConfig.test-d/package.json +6 -0
- package/tempo/AccountConfig.test-d.ts +72 -0
- package/tempo/AccountConfig.test.ts +642 -0
- package/tempo/{MultisigConfig.ts → AccountConfig.ts} +212 -75
- package/tempo/AccountOperation/package.json +6 -0
- package/tempo/AccountOperation.test-d/package.json +6 -0
- package/tempo/AccountOperation.test-d.ts +71 -0
- package/tempo/{MultisigOperation.test.ts → AccountOperation.test.ts} +129 -129
- package/tempo/{MultisigOperation.ts → AccountOperation.ts} +95 -97
- package/tempo/AccountSimulation/package.json +6 -0
- package/tempo/AccountSimulation.test-d/package.json +6 -0
- package/tempo/{MultisigSimulation.test-d.ts → AccountSimulation.test-d.ts} +7 -9
- package/tempo/{MultisigSimulation.test.ts → AccountSimulation.test.ts} +73 -29
- package/tempo/{MultisigSimulation.ts → AccountSimulation.ts} +47 -35
- package/tempo/KeyAuthorization.test-d.ts +19 -29
- package/tempo/KeyAuthorization.test.ts +151 -74
- package/tempo/KeyAuthorization.ts +40 -61
- package/tempo/RpcSchemaTempo.test-d.ts +20 -20
- package/tempo/RpcSchemaTempo.ts +13 -13
- package/tempo/SignatureEnvelope.test-d.ts +7 -7
- package/tempo/SignatureEnvelope.test.ts +34 -34
- package/tempo/SignatureEnvelope.ts +107 -103
- package/tempo/Transaction.test.ts +4 -4
- package/tempo/TransactionRequest.test-d.ts +17 -8
- package/tempo/TransactionRequest.test.ts +31 -21
- package/tempo/TransactionRequest.ts +29 -20
- package/tempo/{multisig.e2e.test.ts → configurableAccounts.e2e.test.ts} +16 -16
- package/tempo/index.ts +50 -48
- package/version.ts +1 -1
- package/_cjs/tempo/MultisigConfig.js.map +0 -1
- package/_cjs/tempo/MultisigOperation.js.map +0 -1
- package/_cjs/tempo/MultisigSimulation.js.map +0 -1
- package/_esm/tempo/MultisigConfig.js.map +0 -1
- package/_esm/tempo/MultisigOperation.js.map +0 -1
- package/_esm/tempo/MultisigSimulation.js.map +0 -1
- package/_types/tempo/MultisigConfig.d.ts.map +0 -1
- package/_types/tempo/MultisigOperation.d.ts.map +0 -1
- package/_types/tempo/MultisigSimulation.d.ts.map +0 -1
- package/tempo/MultisigConfig/package.json +0 -6
- package/tempo/MultisigConfig.test-d/package.json +0 -6
- package/tempo/MultisigConfig.test-d.ts +0 -52
- package/tempo/MultisigConfig.test.ts +0 -391
- package/tempo/MultisigOperation/package.json +0 -6
- package/tempo/MultisigOperation.test-d/package.json +0 -6
- package/tempo/MultisigOperation.test-d.ts +0 -71
- package/tempo/MultisigSimulation/package.json +0 -6
- package/tempo/MultisigSimulation.test-d/package.json +0 -6
|
@@ -2,22 +2,22 @@ import * as Address from '../core/Address.js'
|
|
|
2
2
|
import * as Errors from '../core/Errors.js'
|
|
3
3
|
import * as Hash from '../core/Hash.js'
|
|
4
4
|
import * as Hex from '../core/Hex.js'
|
|
5
|
+
import * as AccountConfig from './AccountConfig.js'
|
|
5
6
|
import * as KeyAuthorization_ from './KeyAuthorization.js'
|
|
6
|
-
import * as MultisigConfig from './MultisigConfig.js'
|
|
7
7
|
import * as SignatureEnvelope from './SignatureEnvelope.js'
|
|
8
8
|
import * as TxEnvelopeTempo from './TxEnvelopeTempo.js'
|
|
9
9
|
|
|
10
|
-
/** Fields shared by every
|
|
10
|
+
/** Fields shared by every account operation. */
|
|
11
11
|
export type Base<quantity = bigint> = {
|
|
12
|
-
/** Root
|
|
12
|
+
/** Root configurable account. */
|
|
13
13
|
account: Address.Address
|
|
14
14
|
/** Every retained serialized owner approval. */
|
|
15
15
|
approvals: readonly Hex.Hex[]
|
|
16
16
|
/** Root configuration used to verify approvals. */
|
|
17
|
-
config:
|
|
17
|
+
config: AccountConfig.Config<quantity>
|
|
18
18
|
/** Unix creation time in milliseconds. */
|
|
19
19
|
createdAt: number
|
|
20
|
-
/** Deterministic
|
|
20
|
+
/** Deterministic account operation hash. */
|
|
21
21
|
hash: Hex.Hex
|
|
22
22
|
/** Number of approvals selected for quorum evaluation. */
|
|
23
23
|
signatureCount: number
|
|
@@ -29,7 +29,7 @@ export type Base<quantity = bigint> = {
|
|
|
29
29
|
weight: number
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/**
|
|
32
|
+
/** Account transaction approval operation. */
|
|
33
33
|
export type TransactionOperation<quantity = bigint> = Base<quantity> & {
|
|
34
34
|
/** Time when another relay may reclaim the submission lease. */
|
|
35
35
|
expiresAt?: number | undefined
|
|
@@ -45,7 +45,7 @@ export type TransactionOperation<quantity = bigint> = Base<quantity> & {
|
|
|
45
45
|
type: 'transaction'
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/**
|
|
48
|
+
/** Account key authorization approval operation. */
|
|
49
49
|
export type KeyAuthorizationOperation<quantity = bigint> = Base<quantity> & {
|
|
50
50
|
/** Canonical serialized key authorization. */
|
|
51
51
|
keyAuthorization: Hex.Hex
|
|
@@ -55,29 +55,29 @@ export type KeyAuthorizationOperation<quantity = bigint> = Base<quantity> & {
|
|
|
55
55
|
type: 'keyAuthorization'
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
/** Transaction or key authorization
|
|
58
|
+
/** Transaction or key authorization account operation. */
|
|
59
59
|
export type Operation<quantity = bigint> =
|
|
60
60
|
| TransactionOperation<quantity>
|
|
61
61
|
| KeyAuthorizationOperation<quantity>
|
|
62
62
|
|
|
63
|
-
/** JSON-RPC
|
|
63
|
+
/** JSON-RPC account transaction operation. */
|
|
64
64
|
export type TransactionRpc = TransactionOperation<Hex.Hex>
|
|
65
65
|
|
|
66
|
-
/** JSON-RPC
|
|
66
|
+
/** JSON-RPC account key authorization operation. */
|
|
67
67
|
export type KeyAuthorizationRpc = KeyAuthorizationOperation<Hex.Hex>
|
|
68
68
|
|
|
69
|
-
/** JSON-RPC
|
|
69
|
+
/** JSON-RPC account operation. */
|
|
70
70
|
export type Rpc = Operation<Hex.Hex>
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
* Derives the deterministic hash for
|
|
73
|
+
* Derives the deterministic hash for an account operation.
|
|
74
74
|
*
|
|
75
75
|
* @example
|
|
76
76
|
* ```ts twoslash
|
|
77
77
|
* // @noErrors
|
|
78
|
-
* import {
|
|
78
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
79
79
|
*
|
|
80
|
-
* const hash =
|
|
80
|
+
* const hash = AccountOperation.getHash({
|
|
81
81
|
* account,
|
|
82
82
|
* config,
|
|
83
83
|
* transaction,
|
|
@@ -85,7 +85,7 @@ export type Rpc = Operation<Hex.Hex>
|
|
|
85
85
|
* })
|
|
86
86
|
* ```
|
|
87
87
|
*
|
|
88
|
-
* @param options - Operation payload and
|
|
88
|
+
* @param options - Operation payload and account identity.
|
|
89
89
|
* @returns The operation hash signed by each owner.
|
|
90
90
|
*/
|
|
91
91
|
export function getHash(options: getHash.Options): Hex.Hex {
|
|
@@ -100,7 +100,7 @@ export function getHash(options: getHash.Options): Hex.Hex {
|
|
|
100
100
|
: KeyAuthorization_.getSignPayload(
|
|
101
101
|
KeyAuthorization_.deserialize(options.keyAuthorization),
|
|
102
102
|
)
|
|
103
|
-
return
|
|
103
|
+
return AccountConfig.getSignPayload({
|
|
104
104
|
account,
|
|
105
105
|
config,
|
|
106
106
|
payload,
|
|
@@ -110,10 +110,10 @@ export function getHash(options: getHash.Options): Hex.Hex {
|
|
|
110
110
|
export declare namespace getHash {
|
|
111
111
|
/** Parameters for `getHash`. */
|
|
112
112
|
export type Options = {
|
|
113
|
-
/** Root
|
|
113
|
+
/** Root configurable account. */
|
|
114
114
|
account: Address.Address
|
|
115
|
-
/** Complete root
|
|
116
|
-
config:
|
|
115
|
+
/** Complete root account configuration witness. */
|
|
116
|
+
config: AccountConfig.Config
|
|
117
117
|
} & (
|
|
118
118
|
| {
|
|
119
119
|
/** Canonical serialized key authorization. */
|
|
@@ -133,7 +133,7 @@ export declare namespace getHash {
|
|
|
133
133
|
export type ErrorType =
|
|
134
134
|
| KeyAuthorization_.deserialize.ErrorType
|
|
135
135
|
| KeyAuthorization_.getSignPayload.ErrorType
|
|
136
|
-
|
|
|
136
|
+
| AccountConfig.getSignPayload.ErrorType
|
|
137
137
|
| TxEnvelopeTempo.deserialize.ErrorType
|
|
138
138
|
| TxEnvelopeTempo.getSignPayload.ErrorType
|
|
139
139
|
| Errors.GlobalErrorType
|
|
@@ -150,9 +150,9 @@ export declare namespace getHash {
|
|
|
150
150
|
* @example
|
|
151
151
|
* ```ts twoslash
|
|
152
152
|
* // @noErrors
|
|
153
|
-
* import {
|
|
153
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
154
154
|
*
|
|
155
|
-
* const selection = await
|
|
155
|
+
* const selection = await AccountOperation.selectApprovals({
|
|
156
156
|
* account,
|
|
157
157
|
* approvals,
|
|
158
158
|
* config,
|
|
@@ -171,7 +171,7 @@ export async function selectApprovals(
|
|
|
171
171
|
throw new InvalidApprovalError({ reason: 'account is invalid' })
|
|
172
172
|
if (!Hash.validate(hash))
|
|
173
173
|
throw new InvalidApprovalError({ reason: 'hash is invalid' })
|
|
174
|
-
const config =
|
|
174
|
+
const config = AccountConfig.from(options.config)
|
|
175
175
|
return selectApprovals_internal({
|
|
176
176
|
account,
|
|
177
177
|
approvals,
|
|
@@ -183,12 +183,12 @@ export async function selectApprovals(
|
|
|
183
183
|
export declare namespace selectApprovals {
|
|
184
184
|
/** Parameters for `selectApprovals`. */
|
|
185
185
|
export type Options = {
|
|
186
|
-
/** Root
|
|
186
|
+
/** Root configurable account. */
|
|
187
187
|
account: Address.Address
|
|
188
188
|
/** Serialized primitive owner approvals. */
|
|
189
189
|
approvals: readonly SignatureEnvelope.Serialized[]
|
|
190
|
-
/** Current root
|
|
191
|
-
config:
|
|
190
|
+
/** Current root account configuration. */
|
|
191
|
+
config: AccountConfig.Config
|
|
192
192
|
/** Deterministic operation hash approved by root owners. */
|
|
193
193
|
hash: Hex.Hex
|
|
194
194
|
}
|
|
@@ -210,8 +210,8 @@ export declare namespace selectApprovals {
|
|
|
210
210
|
/** Error type for `selectApprovals`. */
|
|
211
211
|
export type ErrorType =
|
|
212
212
|
| InvalidApprovalError
|
|
213
|
-
|
|
|
214
|
-
|
|
|
213
|
+
| AccountConfig.assert.ErrorType
|
|
214
|
+
| AccountConfig.getSignPayload.ErrorType
|
|
215
215
|
| SignatureEnvelope.CoercionError
|
|
216
216
|
| SignatureEnvelope.extractAddress.ErrorType
|
|
217
217
|
| SignatureEnvelope.serialize.ErrorType
|
|
@@ -220,14 +220,14 @@ export declare namespace selectApprovals {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
/**
|
|
223
|
-
* Serializes a key authorization with selected
|
|
223
|
+
* Serializes a key authorization with selected owner approvals.
|
|
224
224
|
*
|
|
225
225
|
* @example
|
|
226
226
|
* ```ts twoslash
|
|
227
227
|
* // @noErrors
|
|
228
|
-
* import {
|
|
228
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
229
229
|
*
|
|
230
|
-
* const authorization =
|
|
230
|
+
* const authorization = AccountOperation.serializeKeyAuthorization(
|
|
231
231
|
* keyAuthorization,
|
|
232
232
|
* {
|
|
233
233
|
* account,
|
|
@@ -238,7 +238,7 @@ export declare namespace selectApprovals {
|
|
|
238
238
|
* ```
|
|
239
239
|
*
|
|
240
240
|
* @param keyAuthorization - Canonical serialized unsigned key authorization.
|
|
241
|
-
* @param options -
|
|
241
|
+
* @param options - Configurable account, config, and selected approvals.
|
|
242
242
|
* @returns The signed serialized key authorization.
|
|
243
243
|
*/
|
|
244
244
|
export function serializeKeyAuthorization(
|
|
@@ -257,8 +257,8 @@ export function serializeKeyAuthorization(
|
|
|
257
257
|
throw new InvalidOperationError({
|
|
258
258
|
reason: 'keyAuthorization is not canonically serialized',
|
|
259
259
|
})
|
|
260
|
-
const config =
|
|
261
|
-
const signatures = SignatureEnvelope.
|
|
260
|
+
const config = AccountConfig.from(options.config)
|
|
261
|
+
const signatures = SignatureEnvelope.sortApprovals({
|
|
262
262
|
account: options.account,
|
|
263
263
|
config,
|
|
264
264
|
payload: KeyAuthorization_.getSignPayload(authorization),
|
|
@@ -280,12 +280,12 @@ export function serializeKeyAuthorization(
|
|
|
280
280
|
export declare namespace serializeKeyAuthorization {
|
|
281
281
|
/** Options for `serializeKeyAuthorization`. */
|
|
282
282
|
export type Options = {
|
|
283
|
-
/** Root
|
|
283
|
+
/** Root configurable account. */
|
|
284
284
|
account: Address.Address
|
|
285
285
|
/** Selected serialized owner approvals. */
|
|
286
286
|
approvals: readonly SignatureEnvelope.Serialized[]
|
|
287
|
-
/** Complete applicable root
|
|
288
|
-
config:
|
|
287
|
+
/** Complete applicable root account config. */
|
|
288
|
+
config: AccountConfig.Config
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
/** Error type for `serializeKeyAuthorization`. */
|
|
@@ -295,27 +295,27 @@ export declare namespace serializeKeyAuthorization {
|
|
|
295
295
|
| KeyAuthorization_.from.ErrorType
|
|
296
296
|
| KeyAuthorization_.getSignPayload.ErrorType
|
|
297
297
|
| KeyAuthorization_.serialize.ErrorType
|
|
298
|
-
|
|
|
298
|
+
| AccountConfig.assert.ErrorType
|
|
299
299
|
| SignatureEnvelope.assert.ErrorType
|
|
300
300
|
| SignatureEnvelope.InvalidSerializedError
|
|
301
|
-
| SignatureEnvelope.
|
|
301
|
+
| SignatureEnvelope.sortApprovals.ErrorType
|
|
302
302
|
| Errors.GlobalErrorType
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
/**
|
|
306
|
-
* Serializes
|
|
306
|
+
* Serializes an account transaction operation with selected owner approvals.
|
|
307
307
|
*
|
|
308
308
|
* @example
|
|
309
309
|
* ```ts twoslash
|
|
310
310
|
* // @noErrors
|
|
311
|
-
* import {
|
|
311
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
312
312
|
*
|
|
313
|
-
* const transaction =
|
|
313
|
+
* const transaction = AccountOperation.serializeTransaction(operation, {
|
|
314
314
|
* approvals: selection.selectedApprovals,
|
|
315
315
|
* })
|
|
316
316
|
* ```
|
|
317
317
|
*
|
|
318
|
-
* @param operation -
|
|
318
|
+
* @param operation - Account transaction operation.
|
|
319
319
|
* @param options - Transaction serialization options.
|
|
320
320
|
* @returns The signed serialized Tempo transaction.
|
|
321
321
|
*/
|
|
@@ -331,7 +331,7 @@ export function serializeTransaction(
|
|
|
331
331
|
assertApproval(value.account, approval, value.config),
|
|
332
332
|
)
|
|
333
333
|
assertRetainedApprovals(value, approvals)
|
|
334
|
-
const signatures = SignatureEnvelope.
|
|
334
|
+
const signatures = SignatureEnvelope.sortApprovals({
|
|
335
335
|
account: value.account,
|
|
336
336
|
config: value.config,
|
|
337
337
|
payload: TxEnvelopeTempo.getSignPayload(envelope),
|
|
@@ -365,7 +365,7 @@ export declare namespace serializeTransaction {
|
|
|
365
365
|
export type ErrorType =
|
|
366
366
|
| from.ErrorType
|
|
367
367
|
| InvalidOperationError
|
|
368
|
-
| SignatureEnvelope.
|
|
368
|
+
| SignatureEnvelope.sortApprovals.ErrorType
|
|
369
369
|
| TxEnvelopeTempo.deserialize.ErrorType
|
|
370
370
|
| TxEnvelopeTempo.getSignPayload.ErrorType
|
|
371
371
|
| TxEnvelopeTempo.serialize.ErrorType
|
|
@@ -373,24 +373,24 @@ export declare namespace serializeTransaction {
|
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
/**
|
|
376
|
-
* Validates and normalizes
|
|
376
|
+
* Validates and normalizes an account operation.
|
|
377
377
|
*
|
|
378
378
|
* @example
|
|
379
379
|
* ```ts twoslash
|
|
380
380
|
* // @noErrors
|
|
381
|
-
* import {
|
|
381
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
382
382
|
*
|
|
383
|
-
* const operation =
|
|
383
|
+
* const operation = AccountOperation.from(value)
|
|
384
384
|
* ```
|
|
385
385
|
*
|
|
386
|
-
* @param operation -
|
|
386
|
+
* @param operation - Account operation.
|
|
387
387
|
* @returns The validated operation.
|
|
388
388
|
*/
|
|
389
389
|
export function from<const operation extends Operation>(
|
|
390
390
|
operation: operation,
|
|
391
391
|
): from.ReturnValue<operation> {
|
|
392
392
|
try {
|
|
393
|
-
const config =
|
|
393
|
+
const config = AccountConfig.from(operation.config)
|
|
394
394
|
if (
|
|
395
395
|
typeof config.threshold !== 'number' ||
|
|
396
396
|
config.owners.some((owner) => typeof owner.weight !== 'number')
|
|
@@ -423,17 +423,17 @@ export declare namespace from {
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
/**
|
|
426
|
-
* Converts a JSON-RPC
|
|
426
|
+
* Converts a JSON-RPC account operation to its domain representation.
|
|
427
427
|
*
|
|
428
428
|
* @example
|
|
429
429
|
* ```ts twoslash
|
|
430
430
|
* // @noErrors
|
|
431
|
-
* import {
|
|
431
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
432
432
|
*
|
|
433
|
-
* const operation =
|
|
433
|
+
* const operation = AccountOperation.fromRpc(value)
|
|
434
434
|
* ```
|
|
435
435
|
*
|
|
436
|
-
* @param operation - JSON-RPC
|
|
436
|
+
* @param operation - JSON-RPC account operation.
|
|
437
437
|
* @returns The validated operation.
|
|
438
438
|
*/
|
|
439
439
|
export function fromRpc<const operation extends Rpc>(
|
|
@@ -452,7 +452,7 @@ export function fromRpc<const operation extends Rpc>(
|
|
|
452
452
|
})
|
|
453
453
|
return from({
|
|
454
454
|
...operation,
|
|
455
|
-
config:
|
|
455
|
+
config: AccountConfig.fromRpc(operation.config),
|
|
456
456
|
} as Operation) as never
|
|
457
457
|
} catch (cause) {
|
|
458
458
|
if (cause instanceof InvalidOperationError) throw cause
|
|
@@ -472,17 +472,17 @@ export declare namespace fromRpc {
|
|
|
472
472
|
}
|
|
473
473
|
|
|
474
474
|
/**
|
|
475
|
-
* Converts
|
|
475
|
+
* Converts an account operation to its JSON-RPC representation.
|
|
476
476
|
*
|
|
477
477
|
* @example
|
|
478
478
|
* ```ts twoslash
|
|
479
479
|
* // @noErrors
|
|
480
|
-
* import {
|
|
480
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
481
481
|
*
|
|
482
|
-
* const operationRpc =
|
|
482
|
+
* const operationRpc = AccountOperation.toRpc(operation)
|
|
483
483
|
* ```
|
|
484
484
|
*
|
|
485
|
-
* @param operation -
|
|
485
|
+
* @param operation - Account operation.
|
|
486
486
|
* @returns The JSON-RPC operation.
|
|
487
487
|
*/
|
|
488
488
|
export function toRpc<const operation extends Operation>(
|
|
@@ -491,7 +491,7 @@ export function toRpc<const operation extends Operation>(
|
|
|
491
491
|
const value = from(operation)
|
|
492
492
|
return {
|
|
493
493
|
...value,
|
|
494
|
-
config:
|
|
494
|
+
config: AccountConfig.toRpc(value.config),
|
|
495
495
|
} as never
|
|
496
496
|
}
|
|
497
497
|
|
|
@@ -503,7 +503,7 @@ export declare namespace toRpc {
|
|
|
503
503
|
: KeyAuthorizationRpc
|
|
504
504
|
|
|
505
505
|
/** Error type for `toRpc`. */
|
|
506
|
-
export type ErrorType = from.ErrorType |
|
|
506
|
+
export type ErrorType = from.ErrorType | AccountConfig.toRpc.ErrorType
|
|
507
507
|
}
|
|
508
508
|
|
|
509
509
|
/**
|
|
@@ -523,9 +523,9 @@ async function selectApprovals_internal(
|
|
|
523
523
|
const groups = new Map<string, ApprovalGroup>()
|
|
524
524
|
for (const serialized of options.approvals) {
|
|
525
525
|
const signature = SignatureEnvelope.from(serialized)
|
|
526
|
-
if (signature.type === 'keychain' || signature.type === '
|
|
526
|
+
if (signature.type === 'keychain' || signature.type === 'configurable')
|
|
527
527
|
throw new InvalidApprovalError({
|
|
528
|
-
reason: 'only primitive signatures can approve
|
|
528
|
+
reason: 'only primitive signatures can approve an account operation',
|
|
529
529
|
})
|
|
530
530
|
const address = SignatureEnvelope.extractAddress({
|
|
531
531
|
payload: options.hash,
|
|
@@ -576,7 +576,7 @@ async function selectApprovals_internal(
|
|
|
576
576
|
)
|
|
577
577
|
const selected: typeof ranked = []
|
|
578
578
|
let weight = 0
|
|
579
|
-
for (const approval of ranked.slice(0,
|
|
579
|
+
for (const approval of ranked.slice(0, AccountConfig.maxSignatures)) {
|
|
580
580
|
if (weight >= Number(options.config.threshold)) break
|
|
581
581
|
selected.push(approval)
|
|
582
582
|
weight += approval.weight
|
|
@@ -652,7 +652,7 @@ function compareHex(a: Hex.Hex, b: Hex.Hex) {
|
|
|
652
652
|
*
|
|
653
653
|
* @internal
|
|
654
654
|
*/
|
|
655
|
-
function assertBase(operation: Operation, config:
|
|
655
|
+
function assertBase(operation: Operation, config: AccountConfig.Config): void {
|
|
656
656
|
if (!Address.validate(operation.account))
|
|
657
657
|
throw new InvalidOperationError({ reason: 'account is invalid' })
|
|
658
658
|
if (Hex.toBigInt(operation.account) === 0n)
|
|
@@ -674,7 +674,7 @@ function assertBase(operation: Operation, config: MultisigConfig.Config): void {
|
|
|
674
674
|
})
|
|
675
675
|
if (operation.weight > 0xff)
|
|
676
676
|
throw new InvalidOperationError({ reason: 'weight exceeds u8 max' })
|
|
677
|
-
if (operation.signatureCount >
|
|
677
|
+
if (operation.signatureCount > AccountConfig.maxSignatures)
|
|
678
678
|
throw new InvalidOperationError({ reason: 'too many selected signatures' })
|
|
679
679
|
if (!Array.isArray(operation.approvals))
|
|
680
680
|
throw new InvalidOperationError({ reason: 'approvals must be an array' })
|
|
@@ -835,7 +835,7 @@ function assertTransaction(operation: TransactionOperation): void {
|
|
|
835
835
|
*/
|
|
836
836
|
function assertKeyAuthorization(
|
|
837
837
|
operation: KeyAuthorizationOperation,
|
|
838
|
-
config:
|
|
838
|
+
config: AccountConfig.Config,
|
|
839
839
|
): void {
|
|
840
840
|
const transactionFields = operation as KeyAuthorizationOperation & {
|
|
841
841
|
expiresAt?: unknown
|
|
@@ -885,9 +885,10 @@ function assertKeyAuthorization(
|
|
|
885
885
|
reason: 'pending key authorizations must be unsigned',
|
|
886
886
|
})
|
|
887
887
|
if (operation.status === 'success') {
|
|
888
|
-
if (signature?.type !== '
|
|
888
|
+
if (signature?.type !== 'configurable')
|
|
889
889
|
throw new InvalidOperationError({
|
|
890
|
-
reason:
|
|
890
|
+
reason:
|
|
891
|
+
'successful key authorizations require a configurable account signature',
|
|
891
892
|
})
|
|
892
893
|
if (signature.account.toLowerCase() !== operation.account.toLowerCase())
|
|
893
894
|
throw new InvalidOperationError({
|
|
@@ -924,10 +925,10 @@ function assertKeyAuthorization(
|
|
|
924
925
|
function assertApproval(
|
|
925
926
|
account: Address.Address,
|
|
926
927
|
serialized: SignatureEnvelope.Serialized,
|
|
927
|
-
config:
|
|
928
|
+
config: AccountConfig.Config,
|
|
928
929
|
): SignatureEnvelope.Primitive {
|
|
929
930
|
const approval = SignatureEnvelope.deserialize(serialized)
|
|
930
|
-
if (approval.type === 'keychain' || approval.type === '
|
|
931
|
+
if (approval.type === 'keychain' || approval.type === 'configurable')
|
|
931
932
|
throw new InvalidOperationError({
|
|
932
933
|
reason: 'only primitive owner approvals are allowed',
|
|
933
934
|
})
|
|
@@ -935,7 +936,7 @@ function assertApproval(
|
|
|
935
936
|
account,
|
|
936
937
|
config,
|
|
937
938
|
signatures: [approval],
|
|
938
|
-
type: '
|
|
939
|
+
type: 'configurable',
|
|
939
940
|
})
|
|
940
941
|
if (
|
|
941
942
|
SignatureEnvelope.serialize(approval).toLowerCase() !==
|
|
@@ -997,7 +998,7 @@ function assertSelectedApprovals(
|
|
|
997
998
|
retained.splice(index, 1)
|
|
998
999
|
}
|
|
999
1000
|
|
|
1000
|
-
const digest =
|
|
1001
|
+
const digest = AccountConfig.getSignPayload({
|
|
1001
1002
|
account: operation.account,
|
|
1002
1003
|
config: operation.config,
|
|
1003
1004
|
payload: KeyAuthorization_.getSignPayload(authorization),
|
|
@@ -1047,7 +1048,7 @@ function isWeightReachable(
|
|
|
1047
1048
|
* @internal
|
|
1048
1049
|
*/
|
|
1049
1050
|
function assertOperationHash(operation: Operation, payload: Hex.Hex): void {
|
|
1050
|
-
const hash =
|
|
1051
|
+
const hash = AccountConfig.getSignPayload({
|
|
1051
1052
|
account: operation.account,
|
|
1052
1053
|
config: operation.config,
|
|
1053
1054
|
payload,
|
|
@@ -1071,20 +1072,17 @@ function assertInteger(value: unknown, field: string): asserts value is number {
|
|
|
1071
1072
|
}
|
|
1072
1073
|
|
|
1073
1074
|
/**
|
|
1074
|
-
* Compares normalized
|
|
1075
|
+
* Compares normalized account configurations.
|
|
1075
1076
|
*
|
|
1076
1077
|
* @internal
|
|
1077
1078
|
*/
|
|
1078
|
-
function sameConfig(
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
): boolean {
|
|
1082
|
-
const configA = MultisigConfig.from(a)
|
|
1083
|
-
const configB = MultisigConfig.from(b)
|
|
1079
|
+
function sameConfig(a: AccountConfig.Config, b: AccountConfig.Config): boolean {
|
|
1080
|
+
const configA = AccountConfig.from(a)
|
|
1081
|
+
const configB = AccountConfig.from(b)
|
|
1084
1082
|
return (
|
|
1085
1083
|
Hex.isEqual(
|
|
1086
|
-
configA.salt ??
|
|
1087
|
-
configB.salt ??
|
|
1084
|
+
configA.salt ?? AccountConfig.zeroSalt,
|
|
1085
|
+
configB.salt ?? AccountConfig.zeroSalt,
|
|
1088
1086
|
) &&
|
|
1089
1087
|
configA.threshold === configB.threshold &&
|
|
1090
1088
|
configA.version === configB.version &&
|
|
@@ -1099,18 +1097,18 @@ function sameConfig(
|
|
|
1099
1097
|
)
|
|
1100
1098
|
}
|
|
1101
1099
|
|
|
1102
|
-
/** Thrown when
|
|
1100
|
+
/** Thrown when an account operation owner approval is invalid. */
|
|
1103
1101
|
export class InvalidApprovalError extends Errors.BaseError<Error | undefined> {
|
|
1104
|
-
override readonly name = '
|
|
1102
|
+
override readonly name = 'AccountOperation.InvalidApprovalError'
|
|
1105
1103
|
|
|
1106
1104
|
/**
|
|
1107
|
-
* Creates an invalid
|
|
1105
|
+
* Creates an invalid operation approval error.
|
|
1108
1106
|
*
|
|
1109
1107
|
* @example
|
|
1110
1108
|
* ```ts twoslash
|
|
1111
|
-
* import {
|
|
1109
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
1112
1110
|
*
|
|
1113
|
-
* throw new
|
|
1111
|
+
* throw new AccountOperation.InvalidApprovalError({
|
|
1114
1112
|
* reason: 'signature is from a non-owner',
|
|
1115
1113
|
* })
|
|
1116
1114
|
* ```
|
|
@@ -1120,8 +1118,8 @@ export class InvalidApprovalError extends Errors.BaseError<Error | undefined> {
|
|
|
1120
1118
|
constructor(options: InvalidApprovalError.Options = {}) {
|
|
1121
1119
|
super(
|
|
1122
1120
|
options.reason
|
|
1123
|
-
? `Invalid
|
|
1124
|
-
: 'Invalid
|
|
1121
|
+
? `Invalid operation approval: ${options.reason}.`
|
|
1122
|
+
: 'Invalid operation approval.',
|
|
1125
1123
|
{ cause: options.cause as Error | undefined },
|
|
1126
1124
|
)
|
|
1127
1125
|
}
|
|
@@ -1137,18 +1135,18 @@ export declare namespace InvalidApprovalError {
|
|
|
1137
1135
|
}
|
|
1138
1136
|
}
|
|
1139
1137
|
|
|
1140
|
-
/** Thrown when
|
|
1138
|
+
/** Thrown when an account operation is malformed or internally inconsistent. */
|
|
1141
1139
|
export class InvalidOperationError extends Errors.BaseError<Error | undefined> {
|
|
1142
|
-
override readonly name = '
|
|
1140
|
+
override readonly name = 'AccountOperation.InvalidOperationError'
|
|
1143
1141
|
|
|
1144
1142
|
/**
|
|
1145
|
-
* Creates an invalid
|
|
1143
|
+
* Creates an invalid account operation error.
|
|
1146
1144
|
*
|
|
1147
1145
|
* @example
|
|
1148
1146
|
* ```ts twoslash
|
|
1149
|
-
* import {
|
|
1147
|
+
* import { AccountOperation } from 'ox/tempo'
|
|
1150
1148
|
*
|
|
1151
|
-
* throw new
|
|
1149
|
+
* throw new AccountOperation.InvalidOperationError({
|
|
1152
1150
|
* reason: 'hash does not match the operation payload',
|
|
1153
1151
|
* })
|
|
1154
1152
|
* ```
|
|
@@ -1158,8 +1156,8 @@ export class InvalidOperationError extends Errors.BaseError<Error | undefined> {
|
|
|
1158
1156
|
constructor(options: InvalidOperationError.Options = {}) {
|
|
1159
1157
|
super(
|
|
1160
1158
|
options.reason
|
|
1161
|
-
? `Invalid
|
|
1162
|
-
: 'Invalid
|
|
1159
|
+
? `Invalid account operation: ${options.reason}.`
|
|
1160
|
+
: 'Invalid account operation.',
|
|
1163
1161
|
{ cause: options.cause as Error | undefined },
|
|
1164
1162
|
)
|
|
1165
1163
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expectTypeOf, test } from 'vitest'
|
|
2
|
-
import * as
|
|
2
|
+
import * as AccountSimulation from './AccountSimulation.js'
|
|
3
3
|
|
|
4
4
|
const rpc = {
|
|
5
5
|
approvals: [
|
|
@@ -11,23 +11,21 @@ const rpc = {
|
|
|
11
11
|
],
|
|
12
12
|
config:
|
|
13
13
|
'0xf83ba000000000000000000000000000000000000000000000000000000000000000008001d7d694111111111111111111111111111111111111111101',
|
|
14
|
-
} as const satisfies
|
|
14
|
+
} as const satisfies AccountSimulation.Rpc
|
|
15
15
|
|
|
16
16
|
test('fromRpc returns a domain spec', () => {
|
|
17
|
-
const spec =
|
|
17
|
+
const spec = AccountSimulation.fromRpc(rpc)
|
|
18
18
|
|
|
19
|
-
expectTypeOf(spec).toEqualTypeOf<
|
|
19
|
+
expectTypeOf(spec).toEqualTypeOf<AccountSimulation.Spec>()
|
|
20
20
|
expectTypeOf(spec.config.version).toEqualTypeOf<bigint>()
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
test('RPC specs use encoded configurations', () => {
|
|
24
|
-
expectTypeOf<
|
|
25
|
-
MultisigSimulation.Rpc['config']
|
|
26
|
-
>().toEqualTypeOf<`0x${string}`>()
|
|
24
|
+
expectTypeOf<AccountSimulation.Rpc['config']>().toEqualTypeOf<`0x${string}`>()
|
|
27
25
|
})
|
|
28
26
|
|
|
29
27
|
test('toRpc returns an RPC spec', () => {
|
|
30
28
|
expectTypeOf(
|
|
31
|
-
|
|
32
|
-
).toEqualTypeOf<
|
|
29
|
+
AccountSimulation.toRpc(AccountSimulation.fromRpc(rpc)),
|
|
30
|
+
).toEqualTypeOf<AccountSimulation.Rpc>()
|
|
33
31
|
})
|