viem 2.57.5 → 2.57.7
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 +14 -0
- package/_cjs/actions/wallet/prepareTransactionRequest.js +10 -0
- package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/tempo/Abis.js +297 -1
- package/_cjs/tempo/Abis.js.map +1 -1
- package/_cjs/tempo/Addresses.js +2 -1
- package/_cjs/tempo/Addresses.js.map +1 -1
- package/_cjs/tempo/Decorator.js.map +1 -1
- package/_cjs/tempo/ExecutionError.js +94 -3
- package/_cjs/tempo/ExecutionError.js.map +1 -1
- package/_cjs/tempo/actions/accessKey.js +382 -10
- package/_cjs/tempo/actions/accessKey.js.map +1 -1
- package/_cjs/tempo/actions/accounts.js +3 -2
- package/_cjs/tempo/actions/accounts.js.map +1 -1
- package/_cjs/tempo/actions/amm.js +90 -4
- package/_cjs/tempo/actions/amm.js.map +1 -1
- package/_cjs/tempo/actions/channel.js +183 -7
- package/_cjs/tempo/actions/channel.js.map +1 -1
- package/_cjs/tempo/actions/dex.js +507 -14
- package/_cjs/tempo/actions/dex.js.map +1 -1
- package/_cjs/tempo/actions/earn/deployment.js +4 -3
- package/_cjs/tempo/actions/earn/deployment.js.map +1 -1
- package/_cjs/tempo/actions/earn.js +22 -21
- package/_cjs/tempo/actions/earn.js.map +1 -1
- package/_cjs/tempo/actions/fee.js +85 -5
- package/_cjs/tempo/actions/fee.js.map +1 -1
- package/_cjs/tempo/actions/nonce.js +54 -1
- package/_cjs/tempo/actions/nonce.js.map +1 -1
- package/_cjs/tempo/actions/policy.js +35 -6
- package/_cjs/tempo/actions/policy.js.map +1 -1
- package/_cjs/tempo/actions/propAmm.js +18 -8
- package/_cjs/tempo/actions/propAmm.js.map +1 -1
- package/_cjs/tempo/actions/receivePolicy.js +7 -6
- package/_cjs/tempo/actions/receivePolicy.js.map +1 -1
- package/_cjs/tempo/actions/reward.js +7 -6
- package/_cjs/tempo/actions/reward.js.map +1 -1
- package/_cjs/tempo/actions/token.js +433 -22
- package/_cjs/tempo/actions/token.js.map +1 -1
- package/_cjs/tempo/actions/validator.js +12 -11
- package/_cjs/tempo/actions/validator.js.map +1 -1
- package/_cjs/tempo/actions/virtualAddress.js +3 -2
- package/_cjs/tempo/actions/virtualAddress.js.map +1 -1
- package/_cjs/tempo/actions/zone.js +12 -11
- package/_cjs/tempo/actions/zone.js.map +1 -1
- package/_cjs/tempo/errors.js +57 -1
- package/_cjs/tempo/errors.js.map +1 -1
- package/_cjs/tempo/internal/errors.js +46 -0
- package/_cjs/tempo/internal/errors.js.map +1 -0
- package/_cjs/tempo/internal/resolveError.js +128 -0
- package/_cjs/tempo/internal/resolveError.js.map +1 -0
- package/_cjs/tempo/internal/utils.js +1 -0
- package/_cjs/tempo/internal/utils.js.map +1 -1
- package/_esm/actions/wallet/prepareTransactionRequest.js +11 -0
- package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/tempo/Abis.js +297 -0
- package/_esm/tempo/Abis.js.map +1 -1
- package/_esm/tempo/Addresses.js +1 -0
- package/_esm/tempo/Addresses.js.map +1 -1
- package/_esm/tempo/Decorator.js.map +1 -1
- package/_esm/tempo/ExecutionError.js +95 -2
- package/_esm/tempo/ExecutionError.js.map +1 -1
- package/_esm/tempo/actions/accessKey.js +406 -10
- package/_esm/tempo/actions/accessKey.js.map +1 -1
- package/_esm/tempo/actions/accounts.js +3 -2
- package/_esm/tempo/actions/accounts.js.map +1 -1
- package/_esm/tempo/actions/amm.js +95 -4
- package/_esm/tempo/actions/amm.js.map +1 -1
- package/_esm/tempo/actions/channel.js +191 -7
- package/_esm/tempo/actions/channel.js.map +1 -1
- package/_esm/tempo/actions/dex.js +537 -14
- package/_esm/tempo/actions/dex.js.map +1 -1
- package/_esm/tempo/actions/earn/deployment.js +4 -3
- package/_esm/tempo/actions/earn/deployment.js.map +1 -1
- package/_esm/tempo/actions/earn.js +22 -21
- package/_esm/tempo/actions/earn.js.map +1 -1
- package/_esm/tempo/actions/fee.js +90 -6
- package/_esm/tempo/actions/fee.js.map +1 -1
- package/_esm/tempo/actions/nonce.js +57 -1
- package/_esm/tempo/actions/nonce.js.map +1 -1
- package/_esm/tempo/actions/policy.js +36 -6
- package/_esm/tempo/actions/policy.js.map +1 -1
- package/_esm/tempo/actions/propAmm.js +18 -8
- package/_esm/tempo/actions/propAmm.js.map +1 -1
- package/_esm/tempo/actions/receivePolicy.js +7 -6
- package/_esm/tempo/actions/receivePolicy.js.map +1 -1
- package/_esm/tempo/actions/reward.js +7 -6
- package/_esm/tempo/actions/reward.js.map +1 -1
- package/_esm/tempo/actions/token.js +461 -22
- package/_esm/tempo/actions/token.js.map +1 -1
- package/_esm/tempo/actions/validator.js +12 -11
- package/_esm/tempo/actions/validator.js.map +1 -1
- package/_esm/tempo/actions/virtualAddress.js +3 -2
- package/_esm/tempo/actions/virtualAddress.js.map +1 -1
- package/_esm/tempo/actions/zone.js +12 -11
- package/_esm/tempo/actions/zone.js.map +1 -1
- package/_esm/tempo/errors.js +63 -0
- package/_esm/tempo/errors.js.map +1 -1
- package/_esm/tempo/internal/errors.js +51 -0
- package/_esm/tempo/internal/errors.js.map +1 -0
- package/_esm/tempo/internal/resolveError.js +130 -0
- package/_esm/tempo/internal/resolveError.js.map +1 -0
- package/_esm/tempo/internal/utils.js +2 -0
- package/_esm/tempo/internal/utils.js.map +1 -1
- package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/tempo/Abis.d.ts +807 -0
- package/_types/tempo/Abis.d.ts.map +1 -1
- package/_types/tempo/Addresses.d.ts +1 -0
- package/_types/tempo/Addresses.d.ts.map +1 -1
- package/_types/tempo/Decorator.d.ts +1 -1
- package/_types/tempo/Decorator.d.ts.map +1 -1
- package/_types/tempo/ExecutionError.d.ts +3 -1
- package/_types/tempo/ExecutionError.d.ts.map +1 -1
- package/_types/tempo/actions/accessKey.d.ts +155 -8
- package/_types/tempo/actions/accessKey.d.ts.map +1 -1
- package/_types/tempo/actions/accounts.d.ts +3 -1
- package/_types/tempo/actions/accounts.d.ts.map +1 -1
- package/_types/tempo/actions/amm.d.ts +39 -0
- package/_types/tempo/actions/amm.d.ts.map +1 -1
- package/_types/tempo/actions/channel.d.ts +77 -7
- package/_types/tempo/actions/channel.d.ts.map +1 -1
- package/_types/tempo/actions/dex.d.ts +222 -16
- package/_types/tempo/actions/dex.d.ts.map +1 -1
- package/_types/tempo/actions/earn/deployment.d.ts +7 -6
- package/_types/tempo/actions/earn/deployment.d.ts.map +1 -1
- package/_types/tempo/actions/earn.d.ts +15 -14
- package/_types/tempo/actions/earn.d.ts.map +1 -1
- package/_types/tempo/actions/fee.d.ts +32 -6
- package/_types/tempo/actions/fee.d.ts.map +1 -1
- package/_types/tempo/actions/nonce.d.ts +35 -0
- package/_types/tempo/actions/nonce.d.ts.map +1 -1
- package/_types/tempo/actions/policy.d.ts +29 -8
- package/_types/tempo/actions/policy.d.ts.map +1 -1
- package/_types/tempo/actions/propAmm.d.ts +9 -1
- package/_types/tempo/actions/propAmm.d.ts.map +1 -1
- package/_types/tempo/actions/receivePolicy.d.ts +10 -6
- package/_types/tempo/actions/receivePolicy.d.ts.map +1 -1
- package/_types/tempo/actions/reward.d.ts +7 -3
- package/_types/tempo/actions/reward.d.ts.map +1 -1
- package/_types/tempo/actions/token.d.ts +200 -32
- package/_types/tempo/actions/token.d.ts.map +1 -1
- package/_types/tempo/actions/validator.d.ts +17 -5
- package/_types/tempo/actions/validator.d.ts.map +1 -1
- package/_types/tempo/actions/virtualAddress.d.ts +4 -3
- package/_types/tempo/actions/virtualAddress.d.ts.map +1 -1
- package/_types/tempo/actions/zone.d.ts +10 -9
- package/_types/tempo/actions/zone.d.ts.map +1 -1
- package/_types/tempo/errors.d.ts +63 -1
- package/_types/tempo/errors.d.ts.map +1 -1
- package/_types/tempo/internal/errors.d.ts +59 -0
- package/_types/tempo/internal/errors.d.ts.map +1 -0
- package/_types/tempo/internal/relay/utils.d.ts +16 -16
- package/_types/tempo/internal/resolveError.d.ts +8 -0
- package/_types/tempo/internal/resolveError.d.ts.map +1 -0
- package/_types/tempo/internal/utils.d.ts.map +1 -1
- package/actions/wallet/prepareTransactionRequest.ts +11 -0
- package/errors/version.ts +1 -1
- package/package.json +1 -1
- package/tempo/Abis.ts +298 -0
- package/tempo/Addresses.ts +1 -0
- package/tempo/Decorator.ts +5 -3
- package/tempo/ExecutionError.ts +101 -3
- package/tempo/actions/accessKey.ts +496 -25
- package/tempo/actions/accounts.ts +7 -3
- package/tempo/actions/amm.ts +126 -4
- package/tempo/actions/channel.ts +248 -14
- package/tempo/actions/dex.ts +599 -33
- package/tempo/actions/earn/deployment.ts +11 -9
- package/tempo/actions/earn.ts +40 -35
- package/tempo/actions/fee.ts +111 -9
- package/tempo/actions/nonce.ts +86 -1
- package/tempo/actions/policy.ts +66 -14
- package/tempo/actions/propAmm.ts +36 -9
- package/tempo/actions/receivePolicy.ts +26 -15
- package/tempo/actions/reward.ts +17 -9
- package/tempo/actions/token.ts +519 -54
- package/tempo/actions/validator.ts +40 -16
- package/tempo/actions/virtualAddress.ts +7 -5
- package/tempo/actions/zone.ts +25 -20
- package/tempo/errors.ts +114 -1
- package/tempo/internal/errors.ts +110 -0
- package/tempo/internal/resolveError.ts +169 -0
- package/tempo/internal/utils.ts +2 -0
|
@@ -18,6 +18,8 @@ import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
|
|
|
18
18
|
import * as Abis from '../Abis.js'
|
|
19
19
|
import { type ConfigurableAccount, fromConfig } from '../Account.js'
|
|
20
20
|
import * as Addresses from '../Addresses.js'
|
|
21
|
+
import type * as Errors from '../errors.js'
|
|
22
|
+
import { withExecutionError } from '../internal/errors.js'
|
|
21
23
|
import type { ReadParameters, WriteParameters } from '../internal/types.js'
|
|
22
24
|
import { defineCall } from '../internal/utils.js'
|
|
23
25
|
import type * as Transaction from '../Transaction.js'
|
|
@@ -101,7 +103,7 @@ export async function getConfigCommitment<
|
|
|
101
103
|
parameters: getConfigCommitment.Parameters,
|
|
102
104
|
): Promise<getConfigCommitment.ReturnValue> {
|
|
103
105
|
const { account, ...rest } = parameters
|
|
104
|
-
return readContract(client, {
|
|
106
|
+
return withExecutionError(readContract)(client, {
|
|
105
107
|
...rest,
|
|
106
108
|
...getConfigCommitment.call({ account }),
|
|
107
109
|
})
|
|
@@ -137,6 +139,8 @@ export namespace getConfigCommitment {
|
|
|
137
139
|
functionName: 'getConfigCommitment',
|
|
138
140
|
})
|
|
139
141
|
}
|
|
142
|
+
|
|
143
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
/**
|
|
@@ -250,7 +254,7 @@ export namespace updateConfig {
|
|
|
250
254
|
export type ReturnValue = WriteContractReturnType
|
|
251
255
|
|
|
252
256
|
// TODO: exhaustive error type
|
|
253
|
-
export type ErrorType = BaseErrorType
|
|
257
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
254
258
|
|
|
255
259
|
/** @internal */
|
|
256
260
|
export async function inner<
|
|
@@ -307,7 +311,7 @@ export namespace updateConfig {
|
|
|
307
311
|
if (address) return fromConfig({ address, ...currentConfig })
|
|
308
312
|
return undefined
|
|
309
313
|
})()
|
|
310
|
-
return (await action(client, {
|
|
314
|
+
return (await withExecutionError(action)(client, {
|
|
311
315
|
...rest,
|
|
312
316
|
...(resolvedAccount ? { account: resolvedAccount } : {}),
|
|
313
317
|
...updateConfig.call({ currentConfig, nextConfig }),
|
package/tempo/actions/amm.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { writeContract } from '../../actions/wallet/writeContract.js'
|
|
|
12
12
|
import { writeContractSync } from '../../actions/wallet/writeContractSync.js'
|
|
13
13
|
import type { Client } from '../../clients/createClient.js'
|
|
14
14
|
import type { Transport } from '../../clients/transports/createTransport.js'
|
|
15
|
+
import type { BaseErrorType } from '../../errors/base.js'
|
|
15
16
|
import type { Chain } from '../../types/chain.js'
|
|
16
17
|
import type { ExtractAbiItem, GetEventArgs } from '../../types/contract.js'
|
|
17
18
|
import type { Log, Log as viem_Log } from '../../types/log.js'
|
|
@@ -19,8 +20,16 @@ import type { Hex } from '../../types/misc.js'
|
|
|
19
20
|
import type { TransactionReceipt } from '../../types/transaction.js'
|
|
20
21
|
import type { Compute, OneOf, UnionOmit } from '../../types/utils.js'
|
|
21
22
|
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
|
|
23
|
+
import { isAddressEqual } from '../../utils/address/isAddressEqual.js'
|
|
22
24
|
import * as Abis from '../Abis.js'
|
|
23
25
|
import * as Addresses from '../Addresses.js'
|
|
26
|
+
import type * as Errors from '../errors.js'
|
|
27
|
+
import { TempoExecutionError } from '../errors.js'
|
|
28
|
+
import {
|
|
29
|
+
type Context,
|
|
30
|
+
type Resolvers,
|
|
31
|
+
withExecutionError,
|
|
32
|
+
} from '../internal/errors.js'
|
|
24
33
|
import type { ReadParameters, WriteParameters } from '../internal/types.js'
|
|
25
34
|
import { defineCall } from '../internal/utils.js'
|
|
26
35
|
import type { TransactionReceipt as TempoTransactionReceipt } from '../Transaction.js'
|
|
@@ -149,7 +158,7 @@ export async function getLiquidityBalance<chain extends Chain | undefined>(
|
|
|
149
158
|
parameters: getLiquidityBalance.Parameters,
|
|
150
159
|
): Promise<getLiquidityBalance.ReturnValue> {
|
|
151
160
|
const { address, poolId, userToken, validatorToken, ...rest } = parameters
|
|
152
|
-
return readContract(client, {
|
|
161
|
+
return withExecutionError(readContract)(client, {
|
|
153
162
|
...rest,
|
|
154
163
|
...getLiquidityBalance.call({
|
|
155
164
|
address,
|
|
@@ -211,6 +220,8 @@ export namespace getLiquidityBalance {
|
|
|
211
220
|
functionName: 'liquidityBalances',
|
|
212
221
|
})
|
|
213
222
|
}
|
|
223
|
+
|
|
224
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
/**
|
|
@@ -287,7 +298,7 @@ export namespace rebalanceSwap {
|
|
|
287
298
|
amountOut,
|
|
288
299
|
to,
|
|
289
300
|
})
|
|
290
|
-
return (await action(client, {
|
|
301
|
+
return (await withExecutionError(action)(client, {
|
|
291
302
|
...rest,
|
|
292
303
|
...call,
|
|
293
304
|
} as never)) as never
|
|
@@ -364,6 +375,9 @@ export namespace rebalanceSwap {
|
|
|
364
375
|
if (!log) throw new Error('`RebalanceSwap` event not found.')
|
|
365
376
|
return log
|
|
366
377
|
}
|
|
378
|
+
|
|
379
|
+
// TODO: exhaustive error type
|
|
380
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
367
381
|
}
|
|
368
382
|
|
|
369
383
|
/**
|
|
@@ -433,6 +447,8 @@ export namespace rebalanceSwapSync {
|
|
|
433
447
|
receipt: TransactionReceipt
|
|
434
448
|
}
|
|
435
449
|
>
|
|
450
|
+
|
|
451
|
+
export type ErrorType = rebalanceSwap.ErrorType
|
|
436
452
|
}
|
|
437
453
|
|
|
438
454
|
/**
|
|
@@ -515,7 +531,7 @@ export namespace mint {
|
|
|
515
531
|
validatorTokenAddress,
|
|
516
532
|
validatorTokenAmount,
|
|
517
533
|
})
|
|
518
|
-
return (await action(client, {
|
|
534
|
+
return (await withExecutionError(action)(client, {
|
|
519
535
|
...rest,
|
|
520
536
|
...call,
|
|
521
537
|
} as never)) as never
|
|
@@ -597,6 +613,9 @@ export namespace mint {
|
|
|
597
613
|
if (!log) throw new Error('`Mint` event not found.')
|
|
598
614
|
return log
|
|
599
615
|
}
|
|
616
|
+
|
|
617
|
+
// TODO: exhaustive error type
|
|
618
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
600
619
|
}
|
|
601
620
|
|
|
602
621
|
/**
|
|
@@ -666,6 +685,8 @@ export namespace mintSync {
|
|
|
666
685
|
receipt: TransactionReceipt
|
|
667
686
|
}
|
|
668
687
|
>
|
|
688
|
+
|
|
689
|
+
export type ErrorType = mint.ErrorType
|
|
669
690
|
}
|
|
670
691
|
|
|
671
692
|
/**
|
|
@@ -737,7 +758,7 @@ export namespace burn {
|
|
|
737
758
|
): Promise<ReturnType<action>> {
|
|
738
759
|
const { liquidity, to, userToken, validatorToken, ...rest } = parameters
|
|
739
760
|
const call = burn.call({ liquidity, to, userToken, validatorToken })
|
|
740
|
-
return (await action(client, {
|
|
761
|
+
return (await withExecutionError(action)(client, {
|
|
741
762
|
...rest,
|
|
742
763
|
...call,
|
|
743
764
|
} as never)) as never
|
|
@@ -814,6 +835,9 @@ export namespace burn {
|
|
|
814
835
|
if (!log) throw new Error('`Burn` event not found.')
|
|
815
836
|
return log
|
|
816
837
|
}
|
|
838
|
+
|
|
839
|
+
// TODO: exhaustive error type
|
|
840
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
817
841
|
}
|
|
818
842
|
|
|
819
843
|
/**
|
|
@@ -883,6 +907,8 @@ export namespace burnSync {
|
|
|
883
907
|
receipt: TransactionReceipt
|
|
884
908
|
}
|
|
885
909
|
>
|
|
910
|
+
|
|
911
|
+
export type ErrorType = burn.ErrorType
|
|
886
912
|
}
|
|
887
913
|
|
|
888
914
|
/**
|
|
@@ -1124,3 +1150,99 @@ export declare namespace watchBurn {
|
|
|
1124
1150
|
validatorToken?: TokenId.TokenIdOrAddress | undefined
|
|
1125
1151
|
}
|
|
1126
1152
|
}
|
|
1153
|
+
|
|
1154
|
+
// Errors
|
|
1155
|
+
|
|
1156
|
+
/** Errors this module throws for decoded Tempo errors. Narrow with `error.name`. */
|
|
1157
|
+
export type ExecutionErrorType = AmmInsufficientLiquidityErrorType
|
|
1158
|
+
|
|
1159
|
+
/** `AmmInsufficientLiquidityError` with a literal `name`, for narrowing. */
|
|
1160
|
+
export type AmmInsufficientLiquidityErrorType =
|
|
1161
|
+
AmmInsufficientLiquidityError & {
|
|
1162
|
+
name: 'AmmInsufficientLiquidityError'
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/** Thrown when a fee AMM pool cannot cover a swap, deposit, or withdrawal. */
|
|
1166
|
+
export class AmmInsufficientLiquidityError extends TempoExecutionError<
|
|
1167
|
+
Errors.TempoExecutionError.Decoded<
|
|
1168
|
+
'InsufficientLiquidity' | 'InsufficientReserves'
|
|
1169
|
+
>
|
|
1170
|
+
> {
|
|
1171
|
+
/** Amount of the call (`amountOut`, `amountValidatorToken`, or `liquidity`). */
|
|
1172
|
+
amount: bigint | undefined
|
|
1173
|
+
/** Pool reserve of `userToken`, when known. */
|
|
1174
|
+
reserveUserToken: bigint | undefined
|
|
1175
|
+
/** Pool reserve of `validatorToken`, when known. */
|
|
1176
|
+
reserveValidatorToken: bigint | undefined
|
|
1177
|
+
/** User token of the pool. */
|
|
1178
|
+
userToken: Address | undefined
|
|
1179
|
+
/** Validator token of the pool. */
|
|
1180
|
+
validatorToken: Address | undefined
|
|
1181
|
+
|
|
1182
|
+
constructor(
|
|
1183
|
+
parameters: Errors.TempoExecutionError.Parameters & {
|
|
1184
|
+
amount?: bigint | undefined
|
|
1185
|
+
reserveUserToken?: bigint | undefined
|
|
1186
|
+
reserveValidatorToken?: bigint | undefined
|
|
1187
|
+
userToken?: Address | undefined
|
|
1188
|
+
validatorToken?: Address | undefined
|
|
1189
|
+
},
|
|
1190
|
+
) {
|
|
1191
|
+
const {
|
|
1192
|
+
amount,
|
|
1193
|
+
reserveUserToken,
|
|
1194
|
+
reserveValidatorToken,
|
|
1195
|
+
userToken,
|
|
1196
|
+
validatorToken,
|
|
1197
|
+
} = parameters
|
|
1198
|
+
super(parameters, {
|
|
1199
|
+
details: {
|
|
1200
|
+
'user token': userToken,
|
|
1201
|
+
'validator token': validatorToken,
|
|
1202
|
+
amount,
|
|
1203
|
+
'user token reserve': reserveUserToken,
|
|
1204
|
+
'validator token reserve': reserveValidatorToken,
|
|
1205
|
+
},
|
|
1206
|
+
name: 'AmmInsufficientLiquidityError',
|
|
1207
|
+
})
|
|
1208
|
+
this.amount = amount
|
|
1209
|
+
this.reserveUserToken = reserveUserToken
|
|
1210
|
+
this.reserveValidatorToken = reserveValidatorToken
|
|
1211
|
+
this.userToken = userToken
|
|
1212
|
+
this.validatorToken = validatorToken
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
async function resolvePool(context: Context) {
|
|
1217
|
+
const { call } = context
|
|
1218
|
+
if (!call || !isAddressEqual(call.address, Addresses.feeManager))
|
|
1219
|
+
return undefined
|
|
1220
|
+
const userToken = call.arg<Address>('userToken')
|
|
1221
|
+
const validatorToken = call.arg<Address>('validatorToken')
|
|
1222
|
+
if (!userToken || !validatorToken) return undefined
|
|
1223
|
+
const [pool] = await context.read([
|
|
1224
|
+
{
|
|
1225
|
+
address: Addresses.feeManager,
|
|
1226
|
+
abi: Abis.feeAmm,
|
|
1227
|
+
functionName: 'getPool',
|
|
1228
|
+
args: [userToken, validatorToken],
|
|
1229
|
+
},
|
|
1230
|
+
])
|
|
1231
|
+
return new AmmInsufficientLiquidityError({
|
|
1232
|
+
...context.base,
|
|
1233
|
+
amount:
|
|
1234
|
+
call.arg<bigint>('amountOut') ??
|
|
1235
|
+
call.arg<bigint>('amountValidatorToken') ??
|
|
1236
|
+
call.arg<bigint>('liquidity'),
|
|
1237
|
+
reserveUserToken: pool?.result?.reserveUserToken,
|
|
1238
|
+
reserveValidatorToken: pool?.result?.reserveValidatorToken,
|
|
1239
|
+
userToken,
|
|
1240
|
+
validatorToken,
|
|
1241
|
+
})
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
/** @internal */
|
|
1245
|
+
export const errorResolvers: Resolvers = {
|
|
1246
|
+
'InsufficientLiquidity()': resolvePool,
|
|
1247
|
+
'InsufficientReserves()': resolvePool,
|
|
1248
|
+
}
|
package/tempo/actions/channel.ts
CHANGED
|
@@ -17,8 +17,18 @@ import type { GetEventArgs } from '../../types/contract.js'
|
|
|
17
17
|
import type { Log } from '../../types/log.js'
|
|
18
18
|
import type { Compute } from '../../types/utils.js'
|
|
19
19
|
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
|
|
20
|
+
import { isAddressEqual } from '../../utils/address/isAddressEqual.js'
|
|
20
21
|
import * as Abis from '../Abis.js'
|
|
21
22
|
import { signVoucher as signVoucher_ } from '../Account.js'
|
|
23
|
+
import * as Addresses from '../Addresses.js'
|
|
24
|
+
import type * as Errors from '../errors.js'
|
|
25
|
+
import { TempoExecutionError } from '../errors.js'
|
|
26
|
+
import {
|
|
27
|
+
type Context,
|
|
28
|
+
formatTime,
|
|
29
|
+
type Resolvers,
|
|
30
|
+
withExecutionError,
|
|
31
|
+
} from '../internal/errors.js'
|
|
22
32
|
import type {
|
|
23
33
|
GetAccountParameter,
|
|
24
34
|
ReadParameters,
|
|
@@ -76,7 +86,7 @@ export namespace close {
|
|
|
76
86
|
export type ReturnValue = WriteContractReturnType
|
|
77
87
|
|
|
78
88
|
// TODO: exhaustive error type
|
|
79
|
-
export type ErrorType = BaseErrorType
|
|
89
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
80
90
|
|
|
81
91
|
/** @internal */
|
|
82
92
|
export async function inner<
|
|
@@ -90,7 +100,7 @@ export namespace close {
|
|
|
90
100
|
): Promise<ReturnType<action>> {
|
|
91
101
|
const { captureAmount, cumulativeAmount, channel, signature, ...rest } =
|
|
92
102
|
parameters
|
|
93
|
-
return (await action(client, {
|
|
103
|
+
return (await withExecutionError(action)(client, {
|
|
94
104
|
...rest,
|
|
95
105
|
...close.call({
|
|
96
106
|
captureAmount,
|
|
@@ -195,6 +205,8 @@ export namespace closeSync {
|
|
|
195
205
|
receipt: TransactionReceipt
|
|
196
206
|
}
|
|
197
207
|
>
|
|
208
|
+
|
|
209
|
+
export type ErrorType = close.ErrorType
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
/**
|
|
@@ -230,7 +242,7 @@ export async function getStates<
|
|
|
230
242
|
const chainId = client.chain?.id
|
|
231
243
|
const { channel, ...rest } = parameters
|
|
232
244
|
|
|
233
|
-
return readContract(client, {
|
|
245
|
+
return withExecutionError(readContract)(client, {
|
|
234
246
|
...rest,
|
|
235
247
|
...getStates.call({ channel, chainId } as never),
|
|
236
248
|
} as never) as never
|
|
@@ -269,7 +281,7 @@ export namespace getStates {
|
|
|
269
281
|
channel extends readonly Channel[] ? readonly State[] : State
|
|
270
282
|
|
|
271
283
|
// TODO: exhaustive error type
|
|
272
|
-
export type ErrorType = BaseErrorType
|
|
284
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
273
285
|
|
|
274
286
|
/**
|
|
275
287
|
* Defines a call to the `getChannelState` or `getChannelStatesBatch` function.
|
|
@@ -398,7 +410,7 @@ export namespace open {
|
|
|
398
410
|
export type ReturnValue = WriteContractReturnType
|
|
399
411
|
|
|
400
412
|
// TODO: exhaustive error type
|
|
401
|
-
export type ErrorType = BaseErrorType
|
|
413
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
402
414
|
|
|
403
415
|
/** @internal */
|
|
404
416
|
export async function inner<
|
|
@@ -412,7 +424,7 @@ export namespace open {
|
|
|
412
424
|
): Promise<ReturnType<action>> {
|
|
413
425
|
const { authorizedSigner, deposit, operator, payee, salt, token, ...rest } =
|
|
414
426
|
parameters
|
|
415
|
-
return (await action(client, {
|
|
427
|
+
return (await withExecutionError(action)(client, {
|
|
416
428
|
...rest,
|
|
417
429
|
...open.call({
|
|
418
430
|
authorizedSigner,
|
|
@@ -537,6 +549,8 @@ export namespace openSync {
|
|
|
537
549
|
receipt: TransactionReceipt
|
|
538
550
|
}
|
|
539
551
|
>
|
|
552
|
+
|
|
553
|
+
export type ErrorType = open.ErrorType
|
|
540
554
|
}
|
|
541
555
|
|
|
542
556
|
/**
|
|
@@ -579,7 +593,7 @@ export namespace requestClose {
|
|
|
579
593
|
export type ReturnValue = WriteContractReturnType
|
|
580
594
|
|
|
581
595
|
// TODO: exhaustive error type
|
|
582
|
-
export type ErrorType = BaseErrorType
|
|
596
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
583
597
|
|
|
584
598
|
/** @internal */
|
|
585
599
|
export async function inner<
|
|
@@ -592,7 +606,7 @@ export namespace requestClose {
|
|
|
592
606
|
parameters: Parameters<chain, account>,
|
|
593
607
|
): Promise<ReturnType<action>> {
|
|
594
608
|
const { channel, ...rest } = parameters
|
|
595
|
-
return (await action(client, {
|
|
609
|
+
return (await withExecutionError(action)(client, {
|
|
596
610
|
...rest,
|
|
597
611
|
...requestClose.call({ channel }),
|
|
598
612
|
} as never)) as never
|
|
@@ -684,6 +698,8 @@ export namespace requestCloseSync {
|
|
|
684
698
|
receipt: TransactionReceipt
|
|
685
699
|
}
|
|
686
700
|
>
|
|
701
|
+
|
|
702
|
+
export type ErrorType = requestClose.ErrorType
|
|
687
703
|
}
|
|
688
704
|
|
|
689
705
|
/**
|
|
@@ -734,7 +750,7 @@ export namespace settle {
|
|
|
734
750
|
export type ReturnValue = WriteContractReturnType
|
|
735
751
|
|
|
736
752
|
// TODO: exhaustive error type
|
|
737
|
-
export type ErrorType = BaseErrorType
|
|
753
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
738
754
|
|
|
739
755
|
/** @internal */
|
|
740
756
|
export async function inner<
|
|
@@ -747,7 +763,7 @@ export namespace settle {
|
|
|
747
763
|
parameters: Parameters<chain, account>,
|
|
748
764
|
): Promise<ReturnType<action>> {
|
|
749
765
|
const { cumulativeAmount, channel, signature, ...rest } = parameters
|
|
750
|
-
return (await action(client, {
|
|
766
|
+
return (await withExecutionError(action)(client, {
|
|
751
767
|
...rest,
|
|
752
768
|
...settle.call({ cumulativeAmount, channel, signature }),
|
|
753
769
|
} as never)) as never
|
|
@@ -841,6 +857,8 @@ export namespace settleSync {
|
|
|
841
857
|
receipt: TransactionReceipt
|
|
842
858
|
}
|
|
843
859
|
>
|
|
860
|
+
|
|
861
|
+
export type ErrorType = settle.ErrorType
|
|
844
862
|
}
|
|
845
863
|
|
|
846
864
|
/**
|
|
@@ -951,7 +969,7 @@ export namespace topUp {
|
|
|
951
969
|
export type ReturnValue = WriteContractReturnType
|
|
952
970
|
|
|
953
971
|
// TODO: exhaustive error type
|
|
954
|
-
export type ErrorType = BaseErrorType
|
|
972
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
955
973
|
|
|
956
974
|
/** @internal */
|
|
957
975
|
export async function inner<
|
|
@@ -964,7 +982,7 @@ export namespace topUp {
|
|
|
964
982
|
parameters: Parameters<chain, account>,
|
|
965
983
|
): Promise<ReturnType<action>> {
|
|
966
984
|
const { additionalDeposit, channel, ...rest } = parameters
|
|
967
|
-
return (await action(client, {
|
|
985
|
+
return (await withExecutionError(action)(client, {
|
|
968
986
|
...rest,
|
|
969
987
|
...topUp.call({ additionalDeposit, channel }),
|
|
970
988
|
} as never)) as never
|
|
@@ -1058,6 +1076,8 @@ export namespace topUpSync {
|
|
|
1058
1076
|
receipt: TransactionReceipt
|
|
1059
1077
|
}
|
|
1060
1078
|
>
|
|
1079
|
+
|
|
1080
|
+
export type ErrorType = topUp.ErrorType
|
|
1061
1081
|
}
|
|
1062
1082
|
|
|
1063
1083
|
/**
|
|
@@ -1100,7 +1120,7 @@ export namespace withdraw {
|
|
|
1100
1120
|
export type ReturnValue = WriteContractReturnType
|
|
1101
1121
|
|
|
1102
1122
|
// TODO: exhaustive error type
|
|
1103
|
-
export type ErrorType = BaseErrorType
|
|
1123
|
+
export type ErrorType = Errors.ExecutionErrorType | BaseErrorType
|
|
1104
1124
|
|
|
1105
1125
|
/** @internal */
|
|
1106
1126
|
export async function inner<
|
|
@@ -1113,7 +1133,7 @@ export namespace withdraw {
|
|
|
1113
1133
|
parameters: Parameters<chain, account>,
|
|
1114
1134
|
): Promise<ReturnType<action>> {
|
|
1115
1135
|
const { channel, ...rest } = parameters
|
|
1116
|
-
return (await action(client, {
|
|
1136
|
+
return (await withExecutionError(action)(client, {
|
|
1117
1137
|
...rest,
|
|
1118
1138
|
...withdraw.call({ channel }),
|
|
1119
1139
|
} as never)) as never
|
|
@@ -1206,4 +1226,218 @@ export namespace withdrawSync {
|
|
|
1206
1226
|
receipt: TransactionReceipt
|
|
1207
1227
|
}
|
|
1208
1228
|
>
|
|
1229
|
+
|
|
1230
|
+
export type ErrorType = withdraw.ErrorType
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
// Errors
|
|
1234
|
+
|
|
1235
|
+
/** Errors this module throws for decoded Tempo errors. Narrow with `error.name`. */
|
|
1236
|
+
export type ExecutionErrorType =
|
|
1237
|
+
| ChannelAmountExceedsDepositErrorType
|
|
1238
|
+
| ChannelAmountNotIncreasingErrorType
|
|
1239
|
+
| ChannelCloseNotReadyErrorType
|
|
1240
|
+
| ChannelNotFoundErrorType
|
|
1241
|
+
|
|
1242
|
+
/** `ChannelNotFoundError` with a literal `name`, for narrowing. */
|
|
1243
|
+
export type ChannelNotFoundErrorType = ChannelNotFoundError & {
|
|
1244
|
+
name: 'ChannelNotFoundError'
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/** Thrown when a payment channel does not exist. */
|
|
1248
|
+
export class ChannelNotFoundError extends TempoExecutionError<
|
|
1249
|
+
Errors.TempoExecutionError.Decoded<'ChannelNotFound'>
|
|
1250
|
+
> {
|
|
1251
|
+
/** Channel descriptor, when known. */
|
|
1252
|
+
descriptor: Record<string, unknown> | undefined
|
|
1253
|
+
|
|
1254
|
+
constructor(
|
|
1255
|
+
parameters: Errors.TempoExecutionError.Parameters & {
|
|
1256
|
+
descriptor?: Record<string, unknown> | undefined
|
|
1257
|
+
},
|
|
1258
|
+
) {
|
|
1259
|
+
const { descriptor } = parameters
|
|
1260
|
+
super(parameters, {
|
|
1261
|
+
details: {
|
|
1262
|
+
payer: descriptor?.payer,
|
|
1263
|
+
payee: descriptor?.payee,
|
|
1264
|
+
token: descriptor?.token,
|
|
1265
|
+
},
|
|
1266
|
+
name: 'ChannelNotFoundError',
|
|
1267
|
+
})
|
|
1268
|
+
this.descriptor = descriptor
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/** `ChannelCloseNotReadyError` with a literal `name`, for narrowing. */
|
|
1273
|
+
export type ChannelCloseNotReadyErrorType = ChannelCloseNotReadyError & {
|
|
1274
|
+
name: 'ChannelCloseNotReadyError'
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
/** Thrown when withdrawing from a channel before its close grace period ends. */
|
|
1278
|
+
export class ChannelCloseNotReadyError extends TempoExecutionError<
|
|
1279
|
+
Errors.TempoExecutionError.Decoded<'CloseNotReady'>
|
|
1280
|
+
> {
|
|
1281
|
+
/** When the close was requested (Unix seconds), or `0` when it was not. */
|
|
1282
|
+
closeRequestedAt: number | undefined
|
|
1283
|
+
/** When the channel can be withdrawn from (Unix seconds), when known. */
|
|
1284
|
+
readyAt: bigint | undefined
|
|
1285
|
+
|
|
1286
|
+
constructor(
|
|
1287
|
+
parameters: Errors.TempoExecutionError.Parameters & {
|
|
1288
|
+
closeRequestedAt?: number | undefined
|
|
1289
|
+
readyAt?: bigint | undefined
|
|
1290
|
+
},
|
|
1291
|
+
) {
|
|
1292
|
+
const { closeRequestedAt, readyAt } = parameters
|
|
1293
|
+
super(parameters, {
|
|
1294
|
+
details: {
|
|
1295
|
+
'close requested at': formatTime(closeRequestedAt),
|
|
1296
|
+
'ready at': formatTime(readyAt),
|
|
1297
|
+
},
|
|
1298
|
+
name: 'ChannelCloseNotReadyError',
|
|
1299
|
+
shortMessage:
|
|
1300
|
+
closeRequestedAt === 0
|
|
1301
|
+
? 'Channel close has not been requested.'
|
|
1302
|
+
: readyAt
|
|
1303
|
+
? `Channel is not ready to close until ${formatTime(readyAt)}.`
|
|
1304
|
+
: undefined,
|
|
1305
|
+
})
|
|
1306
|
+
this.closeRequestedAt = closeRequestedAt
|
|
1307
|
+
this.readyAt = readyAt
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/** `ChannelAmountExceedsDepositError` with a literal `name`, for narrowing. */
|
|
1312
|
+
export type ChannelAmountExceedsDepositErrorType =
|
|
1313
|
+
ChannelAmountExceedsDepositError & {
|
|
1314
|
+
name: 'ChannelAmountExceedsDepositError'
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
/** Thrown when a voucher amount exceeds the channel deposit. */
|
|
1318
|
+
export class ChannelAmountExceedsDepositError extends TempoExecutionError<
|
|
1319
|
+
Errors.TempoExecutionError.Decoded<'AmountExceedsDeposit'>
|
|
1320
|
+
> {
|
|
1321
|
+
/** Cumulative voucher amount. */
|
|
1322
|
+
amount: bigint | undefined
|
|
1323
|
+
/** Channel deposit, when known. */
|
|
1324
|
+
deposit: bigint | undefined
|
|
1325
|
+
|
|
1326
|
+
constructor(
|
|
1327
|
+
parameters: Errors.TempoExecutionError.Parameters & {
|
|
1328
|
+
amount?: bigint | undefined
|
|
1329
|
+
deposit?: bigint | undefined
|
|
1330
|
+
},
|
|
1331
|
+
) {
|
|
1332
|
+
const { amount, deposit } = parameters
|
|
1333
|
+
super(parameters, {
|
|
1334
|
+
details: { amount, deposit },
|
|
1335
|
+
name: 'ChannelAmountExceedsDepositError',
|
|
1336
|
+
})
|
|
1337
|
+
this.amount = amount
|
|
1338
|
+
this.deposit = deposit
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/** `ChannelAmountNotIncreasingError` with a literal `name`, for narrowing. */
|
|
1343
|
+
export type ChannelAmountNotIncreasingErrorType =
|
|
1344
|
+
ChannelAmountNotIncreasingError & {
|
|
1345
|
+
name: 'ChannelAmountNotIncreasingError'
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
/** Thrown when a voucher amount is not above the amount already settled. */
|
|
1349
|
+
export class ChannelAmountNotIncreasingError extends TempoExecutionError<
|
|
1350
|
+
Errors.TempoExecutionError.Decoded<'AmountNotIncreasing'>
|
|
1351
|
+
> {
|
|
1352
|
+
/** Cumulative voucher amount. */
|
|
1353
|
+
amount: bigint | undefined
|
|
1354
|
+
/** Amount already settled, when known. */
|
|
1355
|
+
settled: bigint | undefined
|
|
1356
|
+
|
|
1357
|
+
constructor(
|
|
1358
|
+
parameters: Errors.TempoExecutionError.Parameters & {
|
|
1359
|
+
amount?: bigint | undefined
|
|
1360
|
+
settled?: bigint | undefined
|
|
1361
|
+
},
|
|
1362
|
+
) {
|
|
1363
|
+
const { amount, settled } = parameters
|
|
1364
|
+
super(parameters, {
|
|
1365
|
+
details: { amount, settled },
|
|
1366
|
+
name: 'ChannelAmountNotIncreasingError',
|
|
1367
|
+
})
|
|
1368
|
+
this.amount = amount
|
|
1369
|
+
this.settled = settled
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
const reserve = {
|
|
1374
|
+
address: Addresses.tip20ChannelReserve,
|
|
1375
|
+
abi: Abis.tip20ChannelReserve,
|
|
1376
|
+
} as const
|
|
1377
|
+
|
|
1378
|
+
/** Reads the channel state of the failed call, when it targets the channel reserve. */
|
|
1379
|
+
async function readChannel(context: Context) {
|
|
1380
|
+
const { call } = context
|
|
1381
|
+
if (!call || !isAddressEqual(call.address, Addresses.tip20ChannelReserve))
|
|
1382
|
+
return undefined
|
|
1383
|
+
const descriptor = call.arg<ox_Channel.Resolved>('descriptor')
|
|
1384
|
+
if (!descriptor) return { call, descriptor }
|
|
1385
|
+
const [channel, gracePeriod] = await context.read([
|
|
1386
|
+
{
|
|
1387
|
+
...reserve,
|
|
1388
|
+
functionName: 'getChannel',
|
|
1389
|
+
args: [descriptor as never],
|
|
1390
|
+
},
|
|
1391
|
+
{ ...reserve, functionName: 'CLOSE_GRACE_PERIOD' },
|
|
1392
|
+
])
|
|
1393
|
+
return {
|
|
1394
|
+
call,
|
|
1395
|
+
descriptor,
|
|
1396
|
+
gracePeriod: gracePeriod?.result,
|
|
1397
|
+
state: channel?.result?.state,
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
/** @internal */
|
|
1402
|
+
export const errorResolvers: Resolvers = {
|
|
1403
|
+
'AmountExceedsDeposit()': async (context) => {
|
|
1404
|
+
const channel = await readChannel(context)
|
|
1405
|
+
if (!channel) return undefined
|
|
1406
|
+
return new ChannelAmountExceedsDepositError({
|
|
1407
|
+
...context.base,
|
|
1408
|
+
amount: channel.call.arg<bigint>('cumulativeAmount'),
|
|
1409
|
+
deposit: channel.state?.deposit,
|
|
1410
|
+
})
|
|
1411
|
+
},
|
|
1412
|
+
'AmountNotIncreasing()': async (context) => {
|
|
1413
|
+
const channel = await readChannel(context)
|
|
1414
|
+
if (!channel) return undefined
|
|
1415
|
+
return new ChannelAmountNotIncreasingError({
|
|
1416
|
+
...context.base,
|
|
1417
|
+
amount: channel.call.arg<bigint>('cumulativeAmount'),
|
|
1418
|
+
settled: channel.state?.settled,
|
|
1419
|
+
})
|
|
1420
|
+
},
|
|
1421
|
+
'ChannelNotFound()': (context) => {
|
|
1422
|
+
const { call } = context
|
|
1423
|
+
if (!call || !isAddressEqual(call.address, Addresses.tip20ChannelReserve))
|
|
1424
|
+
return undefined
|
|
1425
|
+
return new ChannelNotFoundError({
|
|
1426
|
+
...context.base,
|
|
1427
|
+
descriptor: call.arg<Record<string, unknown>>('descriptor'),
|
|
1428
|
+
})
|
|
1429
|
+
},
|
|
1430
|
+
'CloseNotReady()': async (context) => {
|
|
1431
|
+
const channel = await readChannel(context)
|
|
1432
|
+
if (!channel) return undefined
|
|
1433
|
+
const closeRequestedAt = channel.state?.closeRequestedAt
|
|
1434
|
+
return new ChannelCloseNotReadyError({
|
|
1435
|
+
...context.base,
|
|
1436
|
+
closeRequestedAt,
|
|
1437
|
+
readyAt:
|
|
1438
|
+
closeRequestedAt && channel.gracePeriod !== undefined
|
|
1439
|
+
? BigInt(closeRequestedAt) + channel.gracePeriod
|
|
1440
|
+
: undefined,
|
|
1441
|
+
})
|
|
1442
|
+
},
|
|
1209
1443
|
}
|