viem 2.57.4 → 2.57.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/_cjs/actions/public/waitForTransactionReceipt.js +5 -2
- package/_cjs/actions/public/waitForTransactionReceipt.js.map +1 -1
- package/_cjs/actions/wallet/waitForCallsStatus.js +25 -2
- package/_cjs/actions/wallet/waitForCallsStatus.js.map +1 -1
- package/_cjs/chains/definitions/arcTestnet.js +11 -8
- package/_cjs/chains/definitions/arcTestnet.js.map +1 -1
- package/_cjs/chains/definitions/qmsTestnet.js +30 -0
- package/_cjs/chains/definitions/qmsTestnet.js.map +1 -0
- package/_cjs/chains/definitions/tempo.js +1 -1
- package/_cjs/chains/definitions/tempoModerato.js +2 -2
- package/_cjs/chains/index.js +7 -5
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/clients/transports/ipc.js +19 -10
- package/_cjs/clients/transports/ipc.js.map +1 -1
- package/_cjs/clients/transports/webSocket.js +19 -10
- package/_cjs/clients/transports/webSocket.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/tempo/Account.js +40 -40
- package/_cjs/tempo/Account.js.map +1 -1
- package/_cjs/tempo/Decorator.js +9 -8
- package/_cjs/tempo/Decorator.js.map +1 -1
- package/_cjs/tempo/ExecutionError.js +1 -1
- package/_cjs/tempo/ExecutionError.js.map +1 -1
- package/_cjs/tempo/Formatters.js +8 -7
- package/_cjs/tempo/Formatters.js.map +1 -1
- package/_cjs/tempo/KeyAuthorizationManager.js +25 -16
- package/_cjs/tempo/KeyAuthorizationManager.js.map +1 -1
- package/_cjs/tempo/Relay.js +9 -4
- package/_cjs/tempo/Relay.js.map +1 -1
- package/_cjs/tempo/Transaction.js +9 -9
- package/_cjs/tempo/Transaction.js.map +1 -1
- package/_cjs/tempo/Transport.js +21 -11
- package/_cjs/tempo/Transport.js.map +1 -1
- package/_cjs/tempo/{multisig → accounts}/Config.js +8 -8
- package/_cjs/tempo/{multisig → accounts}/Config.js.map +1 -1
- package/_cjs/tempo/{multisig → accounts}/Operation.js +10 -10
- package/_cjs/tempo/{multisig → accounts}/Operation.js.map +1 -1
- package/_cjs/tempo/{multisig → accounts}/Signature.js +2 -2
- package/_cjs/tempo/accounts/Signature.js.map +1 -0
- package/_cjs/tempo/actions/accessKey.js +60 -37
- package/_cjs/tempo/actions/accessKey.js.map +1 -1
- package/_cjs/tempo/actions/{multisig.js → accounts.js} +13 -18
- package/_cjs/tempo/actions/accounts.js.map +1 -0
- package/_cjs/tempo/actions/index.js +2 -2
- package/_cjs/tempo/actions/index.js.map +1 -1
- package/_cjs/tempo/chainConfig.js +37 -37
- package/_cjs/tempo/chainConfig.js.map +1 -1
- package/_cjs/tempo/index.js +3 -3
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/tempo/internal/relay/{multisig.js → accounts.js} +90 -93
- package/_cjs/tempo/internal/relay/accounts.js.map +1 -0
- package/_cjs/tempo/internal/relay/keyAuthorization.js +296 -0
- package/_cjs/tempo/internal/relay/keyAuthorization.js.map +1 -0
- package/_cjs/tempo/internal/relay/plugin.js +17 -7
- package/_cjs/tempo/internal/relay/plugin.js.map +1 -1
- package/_cjs/utils/hash/normalizeSignature.js +1 -1
- package/_cjs/utils/hash/normalizeSignature.js.map +1 -1
- package/_cjs/utils/rpc/http.js +66 -31
- package/_cjs/utils/rpc/http.js.map +1 -1
- package/_cjs/utils/rpc/socket.js +1 -1
- package/_cjs/utils/rpc/socket.js.map +1 -1
- package/_esm/actions/public/waitForTransactionReceipt.js +5 -2
- package/_esm/actions/public/waitForTransactionReceipt.js.map +1 -1
- package/_esm/actions/wallet/waitForCallsStatus.js +39 -2
- package/_esm/actions/wallet/waitForCallsStatus.js.map +1 -1
- package/_esm/chains/definitions/arcTestnet.js +11 -8
- package/_esm/chains/definitions/arcTestnet.js.map +1 -1
- package/_esm/chains/definitions/qmsTestnet.js +27 -0
- package/_esm/chains/definitions/qmsTestnet.js.map +1 -0
- package/_esm/chains/definitions/tempo.js +1 -1
- package/_esm/chains/definitions/tempoModerato.js +2 -2
- package/_esm/chains/index.js +1 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/clients/transports/ipc.js +21 -10
- package/_esm/clients/transports/ipc.js.map +1 -1
- package/_esm/clients/transports/webSocket.js +21 -10
- package/_esm/clients/transports/webSocket.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/tempo/Account.js +42 -42
- package/_esm/tempo/Account.js.map +1 -1
- package/_esm/tempo/Client.js +3 -3
- package/_esm/tempo/Decorator.js +9 -8
- package/_esm/tempo/Decorator.js.map +1 -1
- package/_esm/tempo/ExecutionError.js +1 -1
- package/_esm/tempo/ExecutionError.js.map +1 -1
- package/_esm/tempo/Formatters.js +11 -10
- package/_esm/tempo/Formatters.js.map +1 -1
- package/_esm/tempo/KeyAuthorizationManager.js +58 -16
- package/_esm/tempo/KeyAuthorizationManager.js.map +1 -1
- package/_esm/tempo/Relay.js +49 -8
- package/_esm/tempo/Relay.js.map +1 -1
- package/_esm/tempo/Transaction.js +11 -11
- package/_esm/tempo/Transaction.js.map +1 -1
- package/_esm/tempo/Transport.js +22 -12
- package/_esm/tempo/Transport.js.map +1 -1
- package/_esm/tempo/{multisig → accounts}/Config.js +14 -14
- package/_esm/tempo/{multisig → accounts}/Config.js.map +1 -1
- package/_esm/tempo/{multisig → accounts}/Operation.js +17 -17
- package/_esm/tempo/{multisig → accounts}/Operation.js.map +1 -1
- package/_esm/tempo/accounts/Signature.js +9 -0
- package/_esm/tempo/accounts/Signature.js.map +1 -0
- package/_esm/tempo/actions/accessKey.js +93 -38
- package/_esm/tempo/actions/accessKey.js.map +1 -1
- package/_esm/tempo/actions/{multisig.js → accounts.js} +31 -36
- package/_esm/tempo/actions/accounts.js.map +1 -0
- package/_esm/tempo/actions/index.js +1 -1
- package/_esm/tempo/actions/index.js.map +1 -1
- package/_esm/tempo/chainConfig.js +38 -38
- package/_esm/tempo/chainConfig.js.map +1 -1
- package/_esm/tempo/index.js +2 -1
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/tempo/internal/relay/{multisig.js → accounts.js} +93 -98
- package/_esm/tempo/internal/relay/accounts.js.map +1 -0
- package/_esm/tempo/internal/relay/feePayer.js +1 -1
- package/_esm/tempo/internal/relay/feePayer.js.map +1 -1
- package/_esm/tempo/internal/relay/keyAuthorization.js +334 -0
- package/_esm/tempo/internal/relay/keyAuthorization.js.map +1 -0
- package/_esm/tempo/internal/relay/plugin.js +15 -6
- package/_esm/tempo/internal/relay/plugin.js.map +1 -1
- package/_esm/utils/hash/normalizeSignature.js +3 -2
- package/_esm/utils/hash/normalizeSignature.js.map +1 -1
- package/_esm/utils/rpc/http.js +74 -31
- package/_esm/utils/rpc/http.js.map +1 -1
- package/_esm/utils/rpc/socket.js +3 -1
- package/_esm/utils/rpc/socket.js.map +1 -1
- package/_types/actions/public/waitForTransactionReceipt.d.ts.map +1 -1
- package/_types/actions/wallet/waitForCallsStatus.d.ts.map +1 -1
- package/_types/chains/definitions/arcTestnet.d.ts +5 -5
- package/_types/chains/definitions/arcTestnet.d.ts.map +1 -1
- package/_types/chains/definitions/qmsTestnet.d.ts +50 -0
- package/_types/chains/definitions/qmsTestnet.d.ts.map +1 -0
- package/_types/chains/definitions/tempo.d.ts +2 -2
- package/_types/chains/definitions/tempoModerato.d.ts +4 -4
- package/_types/chains/index.d.ts +1 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/clients/transports/ipc.d.ts.map +1 -1
- package/_types/clients/transports/webSocket.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/tempo/Account.d.ts +28 -28
- package/_types/tempo/Account.d.ts.map +1 -1
- package/_types/tempo/Client.d.ts +3 -3
- package/_types/tempo/Decorator.d.ts +63 -37
- package/_types/tempo/Decorator.d.ts.map +1 -1
- package/_types/tempo/Formatters.d.ts.map +1 -1
- package/_types/tempo/KeyAuthorizationManager.d.ts +45 -2
- package/_types/tempo/KeyAuthorizationManager.d.ts.map +1 -1
- package/_types/tempo/Relay.d.ts +62 -12
- package/_types/tempo/Relay.d.ts.map +1 -1
- package/_types/tempo/Transaction.d.ts +14 -11
- package/_types/tempo/Transaction.d.ts.map +1 -1
- package/_types/tempo/Transport.d.ts +20 -7
- package/_types/tempo/Transport.d.ts.map +1 -1
- package/_types/tempo/{multisig → accounts}/Config.d.ts +7 -7
- package/_types/tempo/accounts/Config.d.ts.map +1 -0
- package/_types/tempo/{multisig → accounts}/Operation.d.ts +7 -7
- package/_types/tempo/accounts/Operation.d.ts.map +1 -0
- package/_types/tempo/{multisig → accounts}/Signature.d.ts +1 -1
- package/_types/tempo/accounts/Signature.d.ts.map +1 -0
- package/_types/tempo/actions/accessKey.d.ts +59 -17
- package/_types/tempo/actions/accessKey.d.ts.map +1 -1
- package/_types/tempo/actions/{multisig.d.ts → accounts.d.ts} +28 -28
- package/_types/tempo/actions/{multisig.d.ts.map → accounts.d.ts.map} +1 -1
- package/_types/tempo/actions/index.d.ts +1 -1
- package/_types/tempo/actions/index.d.ts.map +1 -1
- package/_types/tempo/index.d.ts +3 -2
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/tempo/internal/relay/accounts.d.ts +15 -0
- package/_types/tempo/internal/relay/accounts.d.ts.map +1 -0
- package/_types/tempo/internal/relay/keyAuthorization.d.ts +25 -0
- package/_types/tempo/internal/relay/keyAuthorization.d.ts.map +1 -0
- package/_types/tempo/internal/relay/plugin.d.ts +6 -3
- package/_types/tempo/internal/relay/plugin.d.ts.map +1 -1
- package/_types/utils/hash/normalizeSignature.d.ts.map +1 -1
- package/_types/utils/rpc/http.d.ts.map +1 -1
- package/_types/utils/rpc/socket.d.ts.map +1 -1
- package/actions/public/waitForTransactionReceipt.ts +8 -2
- package/actions/wallet/waitForCallsStatus.ts +41 -2
- package/chains/definitions/arcTestnet.ts +11 -8
- package/chains/definitions/qmsTestnet.ts +27 -0
- package/chains/definitions/tempo.ts +1 -1
- package/chains/definitions/tempoModerato.ts +2 -2
- package/chains/index.ts +1 -0
- package/clients/transports/ipc.ts +38 -29
- package/clients/transports/webSocket.ts +42 -33
- package/errors/version.ts +1 -1
- package/package.json +2 -2
- package/tempo/Account.ts +95 -84
- package/tempo/Client.ts +3 -3
- package/tempo/Decorator.ts +86 -57
- package/tempo/ExecutionError.ts +1 -1
- package/tempo/Formatters.ts +14 -13
- package/tempo/KeyAuthorizationManager.ts +71 -19
- package/tempo/Relay.ts +70 -14
- package/tempo/Transaction.ts +31 -23
- package/tempo/Transport.ts +49 -21
- package/tempo/{multisig → accounts}/Config.ts +21 -21
- package/tempo/{multisig → accounts}/Operation.ts +26 -26
- package/tempo/{multisig → accounts}/Signature.ts +5 -3
- package/tempo/actions/accessKey.ts +179 -79
- package/tempo/actions/{multisig.ts → accounts.ts} +47 -56
- package/tempo/actions/index.ts +1 -1
- package/tempo/chainConfig.ts +52 -52
- package/tempo/index.ts +5 -4
- package/tempo/internal/relay/{multisig.ts → accounts.ts} +118 -118
- package/tempo/internal/relay/feePayer.ts +1 -1
- package/tempo/internal/relay/keyAuthorization.ts +415 -0
- package/tempo/internal/relay/plugin.ts +20 -7
- package/utils/hash/normalizeSignature.ts +3 -2
- package/utils/rpc/http.ts +76 -30
- package/utils/rpc/socket.ts +3 -1
- package/_cjs/tempo/actions/multisig.js.map +0 -1
- package/_cjs/tempo/internal/relay/multisig.js.map +0 -1
- package/_cjs/tempo/multisig/Signature.js.map +0 -1
- package/_esm/tempo/actions/multisig.js.map +0 -1
- package/_esm/tempo/internal/relay/multisig.js.map +0 -1
- package/_esm/tempo/multisig/Signature.js +0 -9
- package/_esm/tempo/multisig/Signature.js.map +0 -1
- package/_types/tempo/internal/relay/multisig.d.ts +0 -4
- package/_types/tempo/internal/relay/multisig.d.ts.map +0 -1
- package/_types/tempo/multisig/Config.d.ts.map +0 -1
- package/_types/tempo/multisig/Operation.d.ts.map +0 -1
- package/_types/tempo/multisig/Signature.d.ts.map +0 -1
package/tempo/Transport.ts
CHANGED
|
@@ -86,7 +86,7 @@ type RelayProxyParameters = {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export type FeePayer = Transport<typeof withFeePayer.type>
|
|
89
|
-
export type Relay = Transport<typeof withRelay.type, {
|
|
89
|
+
export type Relay = Transport<typeof withRelay.type, { accounts: true }>
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Creates a relay transport that routes requests between
|
|
@@ -94,8 +94,10 @@ export type Relay = Transport<typeof withRelay.type, { multisig: true }>
|
|
|
94
94
|
*
|
|
95
95
|
* All `eth_fillTransaction` requests are sent to the relay with the request's
|
|
96
96
|
* `feePayer` value preserved so the relay can decide whether to sponsor the transaction.
|
|
97
|
-
*
|
|
97
|
+
* Owner approvals, configs, operations, and operation-aware transaction
|
|
98
98
|
* lookups are also sent to the relay so it can coordinate approvals in its store.
|
|
99
|
+
* Signed key authorizations are saved to relays with key authorization storage
|
|
100
|
+
* so they can attach them to the access key's next transaction.
|
|
99
101
|
*
|
|
100
102
|
* The policy parameter controls how the relay handles sponsored transactions:
|
|
101
103
|
* - `'sign-only'`: Relay co-signs the transaction and returns it to the client transport, which then broadcasts it via the default transport
|
|
@@ -116,11 +118,11 @@ export function withRelay<
|
|
|
116
118
|
defaultTransport: transport,
|
|
117
119
|
options: withRelay.LocalOptions<plugins>,
|
|
118
120
|
): withRelay.LocalReturnValue<transport, plugins>
|
|
119
|
-
export function withRelay(
|
|
121
|
+
export function withRelay<const parameters extends withRelay.Parameters = {}>(
|
|
120
122
|
defaultTransport: Transport,
|
|
121
123
|
relayTransport: Transport,
|
|
122
|
-
parameters?: withRelay.Parameters,
|
|
123
|
-
): withRelay.ReturnValue
|
|
124
|
+
parameters?: parameters | withRelay.Parameters,
|
|
125
|
+
): withRelay.ReturnValue<parameters>
|
|
124
126
|
export function withRelay(
|
|
125
127
|
defaultTransport: Transport,
|
|
126
128
|
relayTransport: Transport | withRelay.LocalOptions,
|
|
@@ -145,14 +147,17 @@ export function withRelay(
|
|
|
145
147
|
})) as typeof transport.request,
|
|
146
148
|
value: {
|
|
147
149
|
...transport.value,
|
|
148
|
-
...(relayTransport.plugins?.some(Plugin_.
|
|
149
|
-
? {
|
|
150
|
+
...(relayTransport.plugins?.some(Plugin_.isAccounts)
|
|
151
|
+
? { accounts: true }
|
|
152
|
+
: {}),
|
|
153
|
+
...(relayTransport.plugins?.some(Plugin_.isKeyAuthorization)
|
|
154
|
+
? { keyAuthorization: true }
|
|
150
155
|
: {}),
|
|
151
156
|
},
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
|
|
155
|
-
const { policy = 'sign-only' } = parameters ?? {}
|
|
160
|
+
const { keyAuthorization, policy = 'sign-only' } = parameters ?? {}
|
|
156
161
|
|
|
157
162
|
return (config) => {
|
|
158
163
|
const transport_default = defaultTransport(config)
|
|
@@ -179,7 +184,7 @@ export function withRelay(
|
|
|
179
184
|
const operation = await (async () => {
|
|
180
185
|
try {
|
|
181
186
|
return await transport_relay.request(
|
|
182
|
-
{ method: '
|
|
187
|
+
{ method: 'account_getOperation', params },
|
|
183
188
|
options,
|
|
184
189
|
)
|
|
185
190
|
} catch (error) {
|
|
@@ -187,7 +192,7 @@ export function withRelay(
|
|
|
187
192
|
error instanceof MethodNotFoundRpcError ||
|
|
188
193
|
error instanceof MethodNotSupportedRpcError
|
|
189
194
|
) {
|
|
190
|
-
// Relays
|
|
195
|
+
// Relays without the accounts plugin do not expose this method.
|
|
191
196
|
return null
|
|
192
197
|
}
|
|
193
198
|
throw error
|
|
@@ -204,11 +209,12 @@ export function withRelay(
|
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
if (
|
|
207
|
-
method === '
|
|
208
|
-
method === '
|
|
209
|
-
method === '
|
|
210
|
-
method === '
|
|
211
|
-
method === '
|
|
212
|
+
method === 'account_approveKeyAuthorization' ||
|
|
213
|
+
method === 'account_approveRawTransaction' ||
|
|
214
|
+
method === 'account_approveRawTransactionSync' ||
|
|
215
|
+
method === 'account_getConfig' ||
|
|
216
|
+
method === 'account_getOperation' ||
|
|
217
|
+
method === 'relay_saveKeyAuthorization'
|
|
212
218
|
)
|
|
213
219
|
return transport_relay.request({ method, params }, options) as never
|
|
214
220
|
|
|
@@ -219,7 +225,7 @@ export function withRelay(
|
|
|
219
225
|
const serialized = (params as any)[0] as `0x76${string}`
|
|
220
226
|
const transaction = Transaction.deserialize(serialized)
|
|
221
227
|
|
|
222
|
-
if (transaction.signature?.type === '
|
|
228
|
+
if (transaction.signature?.type === 'configurable')
|
|
223
229
|
return transport_relay.request({ method, params }, options) as never
|
|
224
230
|
|
|
225
231
|
// Serialized Tempo envelopes encode `feePayer: true` as a missing fee payer
|
|
@@ -259,14 +265,23 @@ export function withRelay(
|
|
|
259
265
|
},
|
|
260
266
|
type: withRelay.type,
|
|
261
267
|
})
|
|
262
|
-
return {
|
|
268
|
+
return {
|
|
269
|
+
...transport,
|
|
270
|
+
value: {
|
|
271
|
+
accounts: true,
|
|
272
|
+
...(keyAuthorization ? { keyAuthorization } : {}),
|
|
273
|
+
},
|
|
274
|
+
}
|
|
263
275
|
}
|
|
264
276
|
}
|
|
265
277
|
|
|
266
278
|
export declare namespace withRelay {
|
|
267
279
|
export const type = 'relay'
|
|
268
280
|
|
|
269
|
-
export type Parameters = RelayProxyParameters
|
|
281
|
+
export type Parameters = RelayProxyParameters & {
|
|
282
|
+
/** Whether the relay stores key authorizations with `Relay.keyAuthorization`. Defaults to `false`. */
|
|
283
|
+
keyAuthorization?: boolean | undefined
|
|
284
|
+
}
|
|
270
285
|
|
|
271
286
|
/** Plugins applied directly to the default transport. */
|
|
272
287
|
export type LocalOptions<
|
|
@@ -284,14 +299,27 @@ export declare namespace withRelay {
|
|
|
284
299
|
? Transport<
|
|
285
300
|
type,
|
|
286
301
|
attributes &
|
|
287
|
-
(Extract<plugins[number], Relay_.
|
|
302
|
+
(Extract<plugins[number], Relay_.accounts.ReturnType> extends never
|
|
303
|
+
? {}
|
|
304
|
+
: { accounts: true }) &
|
|
305
|
+
(Extract<
|
|
306
|
+
plugins[number],
|
|
307
|
+
Relay_.keyAuthorization.ReturnType
|
|
308
|
+
> extends never
|
|
288
309
|
? {}
|
|
289
|
-
: {
|
|
310
|
+
: { keyAuthorization: true }),
|
|
290
311
|
request
|
|
291
312
|
>
|
|
292
313
|
: never
|
|
293
314
|
|
|
294
|
-
|
|
315
|
+
/** Remote relay transport, advertising key authorization storage when enabled. */
|
|
316
|
+
export type ReturnValue<parameters extends Parameters = {}> =
|
|
317
|
+
parameters extends { keyAuthorization: true }
|
|
318
|
+
? Transport<
|
|
319
|
+
typeof withRelay.type,
|
|
320
|
+
{ accounts: true; keyAuthorization: true }
|
|
321
|
+
>
|
|
322
|
+
: Relay
|
|
295
323
|
}
|
|
296
324
|
|
|
297
325
|
/** @deprecated Use `withRelay` instead. */
|
|
@@ -2,7 +2,7 @@ import * as Address from 'ox/Address'
|
|
|
2
2
|
import * as Hash from 'ox/Hash'
|
|
3
3
|
import type * as Hex from 'ox/Hex'
|
|
4
4
|
import * as Json from 'ox/Json'
|
|
5
|
-
import {
|
|
5
|
+
import { AccountConfig } from 'ox/tempo'
|
|
6
6
|
import { BaseError } from '../../errors/base.js'
|
|
7
7
|
import { nativeMultisigFactory } from '../Addresses.js'
|
|
8
8
|
import type * as Store from '../Store.js'
|
|
@@ -13,11 +13,11 @@ const maxStoredValueLength = 65_536
|
|
|
13
13
|
/** Zero commitment used before an account is initialized. */
|
|
14
14
|
const zeroCommitment = `0x${'00'.repeat(32)}` as const
|
|
15
15
|
|
|
16
|
-
/** Reads a cached
|
|
16
|
+
/** Reads a cached account config. */
|
|
17
17
|
export async function read(
|
|
18
18
|
store: Store.Store,
|
|
19
19
|
options: read.Options,
|
|
20
|
-
): Promise<
|
|
20
|
+
): Promise<AccountConfig.Config | null> {
|
|
21
21
|
const { address, commitment } = options
|
|
22
22
|
const value = await store.getItem(key({ address, commitment }))
|
|
23
23
|
if (value === null || value === undefined) return null
|
|
@@ -29,27 +29,27 @@ export async function read(
|
|
|
29
29
|
export declare namespace read {
|
|
30
30
|
/** Parameters for {@link read}. */
|
|
31
31
|
export type Options = {
|
|
32
|
-
/**
|
|
32
|
+
/** Configurable account address. */
|
|
33
33
|
address: Address.Address
|
|
34
34
|
/** Config commitment observed onchain. */
|
|
35
35
|
commitment: Hex.Hex
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/** Writes a validated
|
|
39
|
+
/** Writes a validated account config. */
|
|
40
40
|
export async function write(
|
|
41
41
|
store: Store.Store,
|
|
42
42
|
options: write.Options,
|
|
43
43
|
): Promise<void> {
|
|
44
44
|
const { address, commitment } = options
|
|
45
|
-
const config =
|
|
45
|
+
const config = AccountConfig.from(options.config)
|
|
46
46
|
assertKey({ address, commitment, config })
|
|
47
47
|
const value = serialize(config)
|
|
48
48
|
await store.setItem(key({ address, commitment }), value)
|
|
49
49
|
// Initialization commits the version-zero config without changing its version.
|
|
50
50
|
if (commitment.toLowerCase() === zeroCommitment)
|
|
51
51
|
await store.setItem(
|
|
52
|
-
key({ address, commitment:
|
|
52
|
+
key({ address, commitment: AccountConfig.getCommitment(config) }),
|
|
53
53
|
value,
|
|
54
54
|
)
|
|
55
55
|
}
|
|
@@ -57,12 +57,12 @@ export async function write(
|
|
|
57
57
|
export declare namespace write {
|
|
58
58
|
/** Parameters for {@link write}. */
|
|
59
59
|
export type Options = {
|
|
60
|
-
/**
|
|
60
|
+
/** Configurable account address. */
|
|
61
61
|
address: Address.Address
|
|
62
62
|
/** Config commitment used for lookup. */
|
|
63
63
|
commitment: Hex.Hex
|
|
64
64
|
/** Complete config. */
|
|
65
|
-
config:
|
|
65
|
+
config: AccountConfig.Config
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -70,7 +70,7 @@ export declare namespace write {
|
|
|
70
70
|
function assertKey(options: {
|
|
71
71
|
address: Address.Address
|
|
72
72
|
commitment: Hex.Hex
|
|
73
|
-
config:
|
|
73
|
+
config: AccountConfig.Config
|
|
74
74
|
}) {
|
|
75
75
|
const { address, commitment, config } = options
|
|
76
76
|
if (!Address.validate(address) || !Hash.validate(commitment))
|
|
@@ -78,7 +78,7 @@ function assertKey(options: {
|
|
|
78
78
|
if (config.version === 0n) {
|
|
79
79
|
if (
|
|
80
80
|
!Address.isEqual(
|
|
81
|
-
|
|
81
|
+
AccountConfig.getAddress(config, { factory: nativeMultisigFactory }),
|
|
82
82
|
address,
|
|
83
83
|
)
|
|
84
84
|
)
|
|
@@ -86,17 +86,17 @@ function assertKey(options: {
|
|
|
86
86
|
if (commitment.toLowerCase() === zeroCommitment) return
|
|
87
87
|
}
|
|
88
88
|
if (
|
|
89
|
-
|
|
89
|
+
AccountConfig.getCommitment(config).toLowerCase() !==
|
|
90
90
|
commitment.toLowerCase()
|
|
91
91
|
)
|
|
92
92
|
throw new InvalidStoreValueError()
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
/** Deserializes
|
|
96
|
-
function deserialize(value: string):
|
|
95
|
+
/** Deserializes an account config from storage. */
|
|
96
|
+
function deserialize(value: string): AccountConfig.Config {
|
|
97
97
|
try {
|
|
98
98
|
if (value.length > maxStoredValueLength) throw new InvalidStoreValueError()
|
|
99
|
-
return
|
|
99
|
+
return AccountConfig.fromRpc(Json.parse(value) as never)
|
|
100
100
|
} catch (cause) {
|
|
101
101
|
if (cause instanceof InvalidStoreValueError) throw cause
|
|
102
102
|
throw new InvalidStoreValueError({ cause })
|
|
@@ -109,10 +109,10 @@ function key(options: { address: Address.Address; commitment: Hex.Hex }) {
|
|
|
109
109
|
return `multisig:config:${address.toLowerCase()}:${commitment.toLowerCase()}`
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
/** Serializes
|
|
113
|
-
function serialize(config:
|
|
112
|
+
/** Serializes an account config for storage. */
|
|
113
|
+
function serialize(config: AccountConfig.Config): string {
|
|
114
114
|
try {
|
|
115
|
-
const value = Json.stringify(
|
|
115
|
+
const value = Json.stringify(AccountConfig.toRpc(config))
|
|
116
116
|
if (value.length > maxStoredValueLength) throw new InvalidStoreValueError()
|
|
117
117
|
return value
|
|
118
118
|
} catch (cause) {
|
|
@@ -121,14 +121,14 @@ function serialize(config: MultisigConfig.Config): string {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/** Thrown when a stored
|
|
124
|
+
/** Thrown when a stored account config is malformed or mismatched. */
|
|
125
125
|
// biome-ignore lint/correctness/noUnusedVariables: declaration merge
|
|
126
126
|
class InvalidStoreValueError extends BaseError {
|
|
127
127
|
/** Creates an invalid store value error. */
|
|
128
128
|
constructor(options: InvalidStoreValueError.Options = {}) {
|
|
129
|
-
super('Stored
|
|
129
|
+
super('Stored account config is malformed or mismatched.', {
|
|
130
130
|
cause: options.cause as Error | undefined,
|
|
131
|
-
name: '
|
|
131
|
+
name: 'Accounts.Config.InvalidStoreValueError',
|
|
132
132
|
})
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as Hex from 'ox/Hex'
|
|
2
2
|
import * as Json from 'ox/Json'
|
|
3
|
-
import {
|
|
3
|
+
import { AccountOperation, SignatureEnvelope, TxEnvelopeTempo } from 'ox/tempo'
|
|
4
4
|
import { BaseError } from '../../errors/base.js'
|
|
5
5
|
import type * as Store from '../Store.js'
|
|
6
6
|
|
|
@@ -13,11 +13,11 @@ const maxUpdateAttempts = 32
|
|
|
13
13
|
/** Bounds abandoned operation state while allowing long-lived approval ceremonies. */
|
|
14
14
|
const pendingOperationTtl = 30 * 24 * 60 * 60 * 1_000
|
|
15
15
|
|
|
16
|
-
/** Reads a persisted
|
|
16
|
+
/** Reads a persisted account operation. */
|
|
17
17
|
export async function read(
|
|
18
18
|
store: Store.Store,
|
|
19
19
|
hash: Hex.Hex,
|
|
20
|
-
): Promise<
|
|
20
|
+
): Promise<AccountOperation.Operation | null> {
|
|
21
21
|
const value = await store.getItem(operationKey(hash))
|
|
22
22
|
if (value === null || value === undefined) return null
|
|
23
23
|
const operation = deserialize(value)
|
|
@@ -26,14 +26,14 @@ export async function read(
|
|
|
26
26
|
return operation
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** Atomically updates
|
|
29
|
+
/** Atomically updates an account operation. */
|
|
30
30
|
export async function update(
|
|
31
31
|
store: Store.Atomic,
|
|
32
32
|
hash: Hex.Hex,
|
|
33
33
|
update: (
|
|
34
|
-
operation:
|
|
35
|
-
) =>
|
|
36
|
-
): Promise<
|
|
34
|
+
operation: AccountOperation.Operation | null,
|
|
35
|
+
) => AccountOperation.Operation | Promise<AccountOperation.Operation>,
|
|
36
|
+
): Promise<AccountOperation.Operation> {
|
|
37
37
|
const key = operationKey(hash)
|
|
38
38
|
for (let attempt = 0; attempt < maxUpdateAttempts; attempt++) {
|
|
39
39
|
const value = (await store.getItem(key)) ?? null
|
|
@@ -41,9 +41,9 @@ export async function update(
|
|
|
41
41
|
if (current && current.hash.toLowerCase() !== hash.toLowerCase())
|
|
42
42
|
throw new InvalidStoreValueError()
|
|
43
43
|
const value_ = await update(current)
|
|
44
|
-
let next:
|
|
44
|
+
let next: AccountOperation.Operation
|
|
45
45
|
try {
|
|
46
|
-
next =
|
|
46
|
+
next = AccountOperation.from(value_)
|
|
47
47
|
} catch (cause) {
|
|
48
48
|
throw new InvalidStoreValueError({ cause })
|
|
49
49
|
}
|
|
@@ -62,7 +62,7 @@ export async function update(
|
|
|
62
62
|
/** Reads a submission hash without rebuilding its envelope from mutable configurations. */
|
|
63
63
|
export async function readSubmission(
|
|
64
64
|
store: Store.Store,
|
|
65
|
-
operation:
|
|
65
|
+
operation: AccountOperation.TransactionOperation,
|
|
66
66
|
submissionId: Hex.Hex,
|
|
67
67
|
): Promise<Hex.Hex | null> {
|
|
68
68
|
const value = await store.getItem(submissionKey(operation.hash, submissionId))
|
|
@@ -72,9 +72,9 @@ export async function readSubmission(
|
|
|
72
72
|
const transaction = TxEnvelopeTempo.deserialize(
|
|
73
73
|
value as TxEnvelopeTempo.Serialized,
|
|
74
74
|
)
|
|
75
|
-
if (transaction.signature?.type !== '
|
|
75
|
+
if (transaction.signature?.type !== 'configurable')
|
|
76
76
|
throw new InvalidStoreValueError()
|
|
77
|
-
const serialized =
|
|
77
|
+
const serialized = AccountOperation.serializeTransaction(operation, {
|
|
78
78
|
approvals: transaction.signature.signatures.map((signature) =>
|
|
79
79
|
SignatureEnvelope.serialize(signature),
|
|
80
80
|
),
|
|
@@ -123,11 +123,11 @@ export async function writeSubmission(
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
/** Deserializes
|
|
127
|
-
function deserialize(value: string):
|
|
126
|
+
/** Deserializes an account operation from storage. */
|
|
127
|
+
function deserialize(value: string): AccountOperation.Operation {
|
|
128
128
|
try {
|
|
129
129
|
if (value.length > maxStoredValueLength) throw new InvalidStoreValueError()
|
|
130
|
-
const operation =
|
|
130
|
+
const operation = AccountOperation.from(Json.parse(value) as never)
|
|
131
131
|
assertHash(operation)
|
|
132
132
|
return operation
|
|
133
133
|
} catch (cause) {
|
|
@@ -136,10 +136,10 @@ function deserialize(value: string): MultisigOperation.Operation {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
/** Serializes
|
|
140
|
-
function serialize(operation:
|
|
139
|
+
/** Serializes an account operation for storage. */
|
|
140
|
+
function serialize(operation: AccountOperation.Operation): string {
|
|
141
141
|
try {
|
|
142
|
-
const operation_ =
|
|
142
|
+
const operation_ = AccountOperation.from(operation)
|
|
143
143
|
assertHash(operation_)
|
|
144
144
|
const value = Json.stringify(operation_)
|
|
145
145
|
if (value.length > maxStoredValueLength) throw new InvalidStoreValueError()
|
|
@@ -151,8 +151,8 @@ function serialize(operation: MultisigOperation.Operation): string {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/** Verifies that the operation hash commits to its stored payload. */
|
|
154
|
-
function assertHash(operation:
|
|
155
|
-
const hash =
|
|
154
|
+
function assertHash(operation: AccountOperation.Operation) {
|
|
155
|
+
const hash = AccountOperation.getHash(
|
|
156
156
|
operation.type === 'transaction'
|
|
157
157
|
? {
|
|
158
158
|
account: operation.account,
|
|
@@ -181,13 +181,13 @@ function submissionKey(hash: Hex.Hex, submissionId: Hex.Hex) {
|
|
|
181
181
|
return `multisig:submission:${hash.toLowerCase()}:${submissionId.toLowerCase()}`
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/** Thrown when a stored
|
|
184
|
+
/** Thrown when a stored account operation is malformed or unsupported. */
|
|
185
185
|
export class InvalidStoreValueError extends BaseError {
|
|
186
186
|
/** Creates an invalid store value error. */
|
|
187
187
|
constructor(options: InvalidStoreValueError.Options = {}) {
|
|
188
|
-
super('Stored
|
|
188
|
+
super('Stored account operation is malformed or unsupported.', {
|
|
189
189
|
cause: options.cause as Error | undefined,
|
|
190
|
-
name: '
|
|
190
|
+
name: 'Accounts.Operation.InvalidStoreValueError',
|
|
191
191
|
})
|
|
192
192
|
}
|
|
193
193
|
}
|
|
@@ -200,12 +200,12 @@ export declare namespace InvalidStoreValueError {
|
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
/** Thrown when
|
|
203
|
+
/** Thrown when an account operation cannot be updated due to contention. */
|
|
204
204
|
class StoreConflictError extends BaseError {
|
|
205
205
|
/** Creates a store conflict error. */
|
|
206
206
|
constructor() {
|
|
207
|
-
super('
|
|
208
|
-
name: '
|
|
207
|
+
super('Account operation could not be updated after repeated conflicts.', {
|
|
208
|
+
name: 'Accounts.Operation.StoreConflictError',
|
|
209
209
|
})
|
|
210
210
|
}
|
|
211
211
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { SignatureEnvelope } from 'ox/tempo'
|
|
2
2
|
|
|
3
|
-
/** Parses a primitive
|
|
3
|
+
/** Parses a primitive owner approval. */
|
|
4
4
|
export function parseApproval(
|
|
5
5
|
signature: SignatureEnvelope.Serialized,
|
|
6
6
|
): SignatureEnvelope.Primitive {
|
|
7
7
|
const approval = SignatureEnvelope.from(signature)
|
|
8
|
-
if (approval.type === '
|
|
9
|
-
throw new Error(
|
|
8
|
+
if (approval.type === 'configurable' || approval.type === 'keychain')
|
|
9
|
+
throw new Error(
|
|
10
|
+
'Configurable account owners must use primitive signatures.',
|
|
11
|
+
)
|
|
10
12
|
return approval
|
|
11
13
|
}
|