@layerzerolabs/lz-sui-sdk-v2 3.0.134 → 3.0.135
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 +8 -0
- package/deployments/sui-sandbox-local/blocked_message_lib.json +22 -22
- package/deployments/sui-sandbox-local/blocked_msglib_ptb_builder.json +22 -22
- package/deployments/sui-sandbox-local/counter.json +79 -44
- package/deployments/sui-sandbox-local/dvn.json +23 -22
- package/deployments/sui-sandbox-local/dvn_call_type.json +28 -28
- package/deployments/sui-sandbox-local/dvn_fee_lib.json +27 -27
- package/deployments/sui-sandbox-local/dvn_layerzero.json +17 -17
- package/deployments/sui-sandbox-local/dvn_ptb_builder.json +21 -21
- package/deployments/sui-sandbox-local/endpoint_ptb_builder.json +30 -30
- package/deployments/sui-sandbox-local/endpoint_v2.json +25 -25
- package/deployments/sui-sandbox-local/executor.json +15 -14
- package/deployments/sui-sandbox-local/executor_call_type.json +28 -28
- package/deployments/sui-sandbox-local/executor_fee_lib.json +28 -28
- package/deployments/sui-sandbox-local/executor_layerzero.json +17 -17
- package/deployments/sui-sandbox-local/executor_ptb_builder.json +14 -14
- package/deployments/sui-sandbox-local/layerzero_views.json +21 -21
- package/deployments/sui-sandbox-local/message_lib_common.json +21 -21
- package/deployments/sui-sandbox-local/msglib_ptb_builder_call_types.json +13 -13
- package/deployments/sui-sandbox-local/oapp.json +15 -13
- package/deployments/sui-sandbox-local/object-BlockedMessageLib.json +5 -5
- package/deployments/sui-sandbox-local/object-BlockedMsglibPtbBuilder.json +5 -5
- package/deployments/sui-sandbox-local/object-Counter.json +5 -5
- package/deployments/sui-sandbox-local/object-CounterAdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-CounterOApp.json +5 -5
- package/deployments/sui-sandbox-local/object-DVN.json +2 -2
- package/deployments/sui-sandbox-local/object-DVNCap.json +4 -4
- package/deployments/sui-sandbox-local/object-DVNFeeLib.json +5 -5
- package/deployments/sui-sandbox-local/object-EndpointPtbBuilder.json +5 -5
- package/deployments/sui-sandbox-local/object-EndpointPtbBuilderAdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-EndpointV2.json +5 -5
- package/deployments/sui-sandbox-local/object-EndpointV2AdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-Executor.json +2 -2
- package/deployments/sui-sandbox-local/object-ExecutorCap.json +4 -4
- package/deployments/sui-sandbox-local/object-ExecutorFeeLib.json +5 -5
- package/deployments/sui-sandbox-local/object-ExecutorOwnerCap.json +2 -2
- package/deployments/sui-sandbox-local/object-PackageWhitelistValidator.json +5 -5
- package/deployments/sui-sandbox-local/object-PriceFeed.json +5 -5
- package/deployments/sui-sandbox-local/object-PriceFeedOwnerCap.json +5 -5
- package/deployments/sui-sandbox-local/object-SimpleMessageLib.json +5 -5
- package/deployments/sui-sandbox-local/object-SimpleMessageLibAdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-SmlPtbBuilder.json +5 -5
- package/deployments/sui-sandbox-local/object-Treasury.json +5 -5
- package/deployments/sui-sandbox-local/object-TreasuryAdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-ULN302.json +5 -5
- package/deployments/sui-sandbox-local/object-ULN302AdminCap.json +5 -5
- package/deployments/sui-sandbox-local/object-Uln302PtbBuilder.json +5 -5
- package/deployments/sui-sandbox-local/object-Uln302Verification.json +5 -5
- package/deployments/sui-sandbox-local/object-WorkerRegistry.json +9 -0
- package/deployments/sui-sandbox-local/package_whitelist_validator.json +51 -51
- package/deployments/sui-sandbox-local/price_feed.json +39 -39
- package/deployments/sui-sandbox-local/price_feed_call_types.json +19 -19
- package/deployments/sui-sandbox-local/ptb_move_call.json +20 -20
- package/deployments/sui-sandbox-local/sequential_multi_call.json +45 -0
- package/deployments/sui-sandbox-local/simple_message_lib.json +33 -33
- package/deployments/sui-sandbox-local/simple_msglib_ptb_builder.json +22 -22
- package/deployments/sui-sandbox-local/treasury.json +40 -40
- package/deployments/sui-sandbox-local/uln_302.json +35 -39
- package/deployments/sui-sandbox-local/uln_302_ptb_builder.json +25 -25
- package/deployments/sui-sandbox-local/uln_common.json +49 -0
- package/deployments/sui-sandbox-local/worker_common.json +15 -14
- package/deployments/sui-sandbox-local/worker_registry.json +58 -0
- package/deployments/sui-testnet/blocked_message_lib.json +22 -22
- package/deployments/sui-testnet/blocked_msglib_ptb_builder.json +29 -29
- package/deployments/sui-testnet/call.json +21 -21
- package/deployments/sui-testnet/counter.json +40 -40
- package/deployments/sui-testnet/dvn.json +22 -21
- package/deployments/sui-testnet/dvn_call_type.json +19 -19
- package/deployments/sui-testnet/dvn_fee_lib.json +26 -26
- package/deployments/sui-testnet/dvn_layerzero.json +24 -24
- package/deployments/sui-testnet/dvn_ptb_builder.json +20 -20
- package/deployments/sui-testnet/endpoint_ptb_builder.json +30 -30
- package/deployments/sui-testnet/endpoint_v2.json +26 -26
- package/deployments/sui-testnet/executor.json +22 -21
- package/deployments/sui-testnet/executor_call_type.json +19 -19
- package/deployments/sui-testnet/executor_fee_lib.json +18 -18
- package/deployments/sui-testnet/executor_layerzero.json +25 -25
- package/deployments/sui-testnet/executor_ptb_builder.json +20 -20
- package/deployments/sui-testnet/layerzero_views.json +13 -13
- package/deployments/sui-testnet/message_lib_common.json +21 -21
- package/deployments/sui-testnet/msglib_ptb_builder_call_types.json +13 -13
- package/deployments/sui-testnet/oapp.json +15 -13
- package/deployments/sui-testnet/object-BlockedMessageLib.json +5 -5
- package/deployments/sui-testnet/object-BlockedMsglibPtbBuilder.json +5 -5
- package/deployments/sui-testnet/object-Counter.json +5 -5
- package/deployments/sui-testnet/object-CounterAdminCap.json +5 -5
- package/deployments/sui-testnet/object-CounterOApp.json +5 -5
- package/deployments/sui-testnet/object-DVN.json +2 -2
- package/deployments/sui-testnet/object-DVNCap.json +5 -5
- package/deployments/sui-testnet/object-DVNFeeLib.json +5 -5
- package/deployments/sui-testnet/object-EndpointPtbBuilder.json +5 -5
- package/deployments/sui-testnet/object-EndpointPtbBuilderAdminCap.json +5 -5
- package/deployments/sui-testnet/object-EndpointV2.json +5 -5
- package/deployments/sui-testnet/object-EndpointV2AdminCap.json +5 -5
- package/deployments/sui-testnet/object-Executor.json +2 -2
- package/deployments/sui-testnet/object-ExecutorCap.json +5 -5
- package/deployments/sui-testnet/object-ExecutorFeeLib.json +5 -5
- package/deployments/sui-testnet/object-ExecutorOwnerCap.json +2 -2
- package/deployments/sui-testnet/object-PackageWhitelistValidator.json +5 -5
- package/deployments/sui-testnet/object-PriceFeed.json +5 -5
- package/deployments/sui-testnet/object-PriceFeedOwnerCap.json +5 -5
- package/deployments/sui-testnet/object-SimpleMessageLib.json +5 -5
- package/deployments/sui-testnet/object-SimpleMessageLibAdminCap.json +5 -5
- package/deployments/sui-testnet/object-SmlPtbBuilder.json +5 -5
- package/deployments/sui-testnet/object-Treasury.json +5 -5
- package/deployments/sui-testnet/object-TreasuryAdminCap.json +5 -5
- package/deployments/sui-testnet/object-ULN302.json +5 -5
- package/deployments/sui-testnet/object-ULN302AdminCap.json +5 -5
- package/deployments/sui-testnet/object-Uln302PtbBuilder.json +5 -5
- package/deployments/sui-testnet/object-Uln302Verification.json +5 -5
- package/deployments/sui-testnet/object-WorkerRegistry.json +9 -0
- package/deployments/sui-testnet/object-ZroCoinMetadata.json +5 -5
- package/deployments/sui-testnet/object-ZroTreasuryCap.json +5 -5
- package/deployments/sui-testnet/package_whitelist_validator.json +44 -44
- package/deployments/sui-testnet/price_feed.json +25 -25
- package/deployments/sui-testnet/price_feed_call_types.json +12 -12
- package/deployments/sui-testnet/ptb_move_call.json +21 -21
- package/deployments/sui-testnet/sequential_multi_call.json +45 -0
- package/deployments/sui-testnet/simple_message_lib.json +29 -29
- package/deployments/sui-testnet/simple_msglib_ptb_builder.json +26 -26
- package/deployments/sui-testnet/treasury.json +30 -58
- package/deployments/sui-testnet/uln_302.json +28 -32
- package/deployments/sui-testnet/uln_302_ptb_builder.json +25 -25
- package/deployments/sui-testnet/uln_common.json +49 -0
- package/deployments/sui-testnet/utils.json +12 -12
- package/deployments/sui-testnet/worker_common.json +21 -20
- package/deployments/sui-testnet/worker_registry.json +58 -0
- package/deployments/sui-testnet/zro.json +28 -28
- package/dist/index.cjs +1193 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +702 -352
- package/dist/index.d.ts +702 -352
- package/dist/index.mjs +1182 -418
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/bcs/index.ts +2 -1
- package/src/bcs/oapp.ts +14 -0
- package/src/generated/addresses.ts +123 -105
- package/src/module-manager.ts +15 -3
- package/src/modules/call.ts +16 -6
- package/src/modules/endpoint.ts +12 -4
- package/src/modules/message-libs/simple-message-lib.ts +3 -2
- package/src/modules/message-libs/uln302.ts +28 -26
- package/src/modules/oapps/counter.ts +34 -50
- package/src/modules/oapps/oapp.ts +489 -74
- package/src/modules/ptb-builders/endpoint-ptb-builder.ts +9 -3
- package/src/modules/ptb-builders/ptb-builder.ts +19 -4
- package/src/modules/ptb-builders/uln302-ptb-builder.ts +5 -0
- package/src/modules/workers/dvn-layerzero.ts +9 -0
- package/src/modules/workers/dvn.ts +214 -6
- package/src/modules/workers/executor-fee-lib.ts +11 -3
- package/src/modules/workers/executor-layerzero.ts +9 -0
- package/src/modules/workers/executor.ts +115 -0
- package/src/modules/workers/index.ts +1 -0
- package/src/modules/workers/treasury.ts +4 -4
- package/src/modules/workers/worker-registry.ts +110 -0
- package/src/resource.ts +3 -0
- package/src/sdk.ts +7 -2
- package/src/types/endpoint.ts +2 -1
- package/src/types/modules.ts +1 -0
- package/src/types/oapp.ts +6 -0
- package/src/types/options.ts +15 -0
- package/src/utils/transaction.ts +3 -3
|
@@ -6,9 +6,15 @@ import { ModuleManager } from '../../module-manager'
|
|
|
6
6
|
import { ObjectOptions } from '../../types'
|
|
7
7
|
import { asAddress, asBool, asU32, executeSimulate } from '../../utils'
|
|
8
8
|
|
|
9
|
-
export const
|
|
10
|
-
//
|
|
11
|
-
|
|
9
|
+
export const EndpointPtbBuilderErrorCode = {
|
|
10
|
+
// EndpointPtbBuilder related errors (matching endpoint_ptb_builder.move)
|
|
11
|
+
EndpointPtbBuilder_EBuilderNotFound: 1,
|
|
12
|
+
EndpointPtbBuilder_EBuilderRegistered: 2,
|
|
13
|
+
EndpointPtbBuilder_EBuilderUnsupported: 3,
|
|
14
|
+
EndpointPtbBuilder_EInvalidBounds: 4,
|
|
15
|
+
EndpointPtbBuilder_EInvalidBuilderAddress: 5,
|
|
16
|
+
EndpointPtbBuilder_EInvalidLibrary: 6,
|
|
17
|
+
EndpointPtbBuilder_EUnauthorized: 7,
|
|
12
18
|
} as const
|
|
13
19
|
|
|
14
20
|
const ModuleName = 'endpoint_ptb_builder'
|
|
@@ -2,14 +2,14 @@ import { bcs } from '@mysten/sui/bcs'
|
|
|
2
2
|
import { SuiClient } from '@mysten/sui/client'
|
|
3
3
|
import { Transaction, TransactionResult } from '@mysten/sui/transactions'
|
|
4
4
|
|
|
5
|
-
import { VectorMoveCallBCS } from '../../bcs'
|
|
5
|
+
import { OAppInfoV1Bcs, VectorMoveCallBCS } from '../../bcs'
|
|
6
6
|
import {
|
|
7
7
|
Argument,
|
|
8
8
|
BuilderPlaceholderInfo,
|
|
9
9
|
DEFAULT_SIMULATION_TIMES,
|
|
10
10
|
LzComposeVersion,
|
|
11
|
-
LzReceiveVersion,
|
|
12
11
|
MoveCall,
|
|
12
|
+
OAppInfoVersion,
|
|
13
13
|
SimulateResult,
|
|
14
14
|
} from '../../types'
|
|
15
15
|
import { simulateTransaction } from '../../utils/transaction'
|
|
@@ -17,6 +17,15 @@ import { normalizeSuiPackageId } from '../../utils/type-name'
|
|
|
17
17
|
|
|
18
18
|
const MOVE_CALL_MODULE_NAME = 'move_call'
|
|
19
19
|
|
|
20
|
+
export const PtbBuilderErrorCode = {
|
|
21
|
+
// MoveCallsBuilder related errors (matching move_calls_builder.move)
|
|
22
|
+
MoveCallsBuilder_EInvalidMoveCallResult: 1,
|
|
23
|
+
MoveCallsBuilder_EResultIDNotFound: 2,
|
|
24
|
+
|
|
25
|
+
// Argument related errors (matching argument.move)
|
|
26
|
+
Argument_EInvalidArgument: 1,
|
|
27
|
+
} as const
|
|
28
|
+
|
|
20
29
|
export class PtbBuilder {
|
|
21
30
|
public packageId: string
|
|
22
31
|
public readonly client: SuiClient
|
|
@@ -48,9 +57,10 @@ export class PtbBuilder {
|
|
|
48
57
|
async simulateLzReceivePtb(tx: Transaction, sender?: string): Promise<MoveCall[]> {
|
|
49
58
|
const ptbCallsResult = await simulateTransaction(this.client, tx, sender)
|
|
50
59
|
const buffer = Buffer.from(bcs.vector(bcs.u8()).parse(ptbCallsResult[0].value))
|
|
60
|
+
|
|
51
61
|
const version = buffer.readInt16BE()
|
|
52
|
-
if (version ===
|
|
53
|
-
return this.#
|
|
62
|
+
if (version === OAppInfoVersion.VERSION_1) {
|
|
63
|
+
return this.#decodeMoveCallsFromOAppInfoV1(new Uint8Array(buffer.subarray(2)))
|
|
54
64
|
}
|
|
55
65
|
throw new Error(`Unknown version: ${version}`)
|
|
56
66
|
}
|
|
@@ -285,6 +295,11 @@ export class PtbBuilder {
|
|
|
285
295
|
return this.#decodeMoveCallsBytes(value)
|
|
286
296
|
}
|
|
287
297
|
|
|
298
|
+
#decodeMoveCallsFromOAppInfoV1(bytes: Uint8Array): MoveCall[] {
|
|
299
|
+
const oappInfo = OAppInfoV1Bcs.parse(bytes)
|
|
300
|
+
return this.#decodeMoveCallsBytes(new Uint8Array(oappInfo.lz_receive_info).subarray(2)) // remove the version prefix
|
|
301
|
+
}
|
|
302
|
+
|
|
288
303
|
/**
|
|
289
304
|
* Decode move calls from raw bytes
|
|
290
305
|
* @param bytes - The raw bytes containing encoded move calls
|
|
@@ -8,6 +8,11 @@ import { asAddress, executeSimulate } from '../../utils'
|
|
|
8
8
|
|
|
9
9
|
const MODULE_NAME = 'uln_302_ptb_builder'
|
|
10
10
|
|
|
11
|
+
export const Uln302PtbBuilderErrorCode = {
|
|
12
|
+
// ULN302 PTB Builder related errors (matching uln_302_ptb_builder.move)
|
|
13
|
+
Uln302PtbBuilder_EWorkerPtbsNotFound: 1,
|
|
14
|
+
} as const
|
|
15
|
+
|
|
11
16
|
export class Uln302PtbBuilder {
|
|
12
17
|
public packageId: string
|
|
13
18
|
public readonly client: SuiClient
|
|
@@ -6,6 +6,11 @@ import { asAddress, asAddressVector, asBytesVector, asObject, asU16, asU32, asU6
|
|
|
6
6
|
|
|
7
7
|
const MODULE_NAME = 'dvn_layerzero'
|
|
8
8
|
|
|
9
|
+
export const DVNLayerzeroErrorCode = {
|
|
10
|
+
// DVNLayerzero related errors (matching dvn_layerzero.move)
|
|
11
|
+
DVNLayerzero_EWorkerCapNotFromPackage: 1,
|
|
12
|
+
} as const
|
|
13
|
+
|
|
9
14
|
export class DvnLayerZero {
|
|
10
15
|
public packageId: string
|
|
11
16
|
public readonly client: SuiClient
|
|
@@ -28,6 +33,7 @@ export class DvnLayerZero {
|
|
|
28
33
|
* @param workerCap - Worker capability object ID or transaction argument
|
|
29
34
|
* @param vid - Verifier ID for the DVN or transaction argument
|
|
30
35
|
* @param depositAddress - Address for fee deposits or transaction argument
|
|
36
|
+
* @param supportedMessageLibs - Array of supported message library addresses or transaction argument
|
|
31
37
|
* @param priceFeed - Price feed object address or transaction argument
|
|
32
38
|
* @param workerFeeLib - Worker fee library address or transaction argument
|
|
33
39
|
* @param defaultMultiplierBps - Default multiplier in basis points or transaction argument
|
|
@@ -40,6 +46,7 @@ export class DvnLayerZero {
|
|
|
40
46
|
workerCap: string | TransactionArgument,
|
|
41
47
|
vid: number | TransactionArgument,
|
|
42
48
|
depositAddress: string | TransactionArgument,
|
|
49
|
+
supportedMessageLibs: string[] | TransactionArgument,
|
|
43
50
|
priceFeed: string | TransactionArgument,
|
|
44
51
|
workerFeeLib: string | TransactionArgument,
|
|
45
52
|
defaultMultiplierBps: number | TransactionArgument,
|
|
@@ -53,12 +60,14 @@ export class DvnLayerZero {
|
|
|
53
60
|
asObject(tx, workerCap),
|
|
54
61
|
asU32(tx, vid),
|
|
55
62
|
asAddress(tx, depositAddress),
|
|
63
|
+
asAddressVector(tx, supportedMessageLibs),
|
|
56
64
|
asAddress(tx, priceFeed),
|
|
57
65
|
asAddress(tx, workerFeeLib),
|
|
58
66
|
asU16(tx, defaultMultiplierBps),
|
|
59
67
|
asAddressVector(tx, admins),
|
|
60
68
|
asBytesVector(tx, signers),
|
|
61
69
|
asU64(tx, quorum),
|
|
70
|
+
tx.object(this.moduleManager.objects.workerRegistry),
|
|
62
71
|
],
|
|
63
72
|
})
|
|
64
73
|
}
|
|
@@ -27,6 +27,21 @@ export const DVNErrorCode = {
|
|
|
27
27
|
DVN_EEidNotSupported: 2,
|
|
28
28
|
DVN_EHashAlreadyUsed: 3,
|
|
29
29
|
DVN_EPtbBuilderAlreadyInitialized: 4,
|
|
30
|
+
|
|
31
|
+
// Multisig related errors (matching multisig.move)
|
|
32
|
+
Multisig_EDuplicatedSigner: 1,
|
|
33
|
+
Multisig_EInvalidSignatureLength: 2,
|
|
34
|
+
Multisig_EInvalidSignerLength: 3,
|
|
35
|
+
Multisig_EQuorumIsZero: 4,
|
|
36
|
+
Multisig_ESignaturesLessThanQuorum: 5,
|
|
37
|
+
Multisig_ESignerAlreadyExists: 6,
|
|
38
|
+
Multisig_ESignerNotFound: 7,
|
|
39
|
+
Multisig_ESignerNotInCommittee: 8,
|
|
40
|
+
Multisig_ESignersSizeIsLessThanQuorum: 9,
|
|
41
|
+
|
|
42
|
+
// DVNInfoV1 related errors (matching dvn_info_v1.move)
|
|
43
|
+
DVNInfoV1_EInvalidData: 1,
|
|
44
|
+
DVNInfoV1_EInvalidVersion: 2,
|
|
30
45
|
} as const
|
|
31
46
|
|
|
32
47
|
export class DVN {
|
|
@@ -253,6 +268,37 @@ export class DVN {
|
|
|
253
268
|
|
|
254
269
|
// === Set Functions with Signatures ===
|
|
255
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Set supported message library (admin with signatures)
|
|
273
|
+
* @param tx - The transaction to add the move call to
|
|
274
|
+
* @param adminCap - The admin capability object ID
|
|
275
|
+
* @param messageLib - The message library address
|
|
276
|
+
* @param supported - Whether to support or remove support for the message library
|
|
277
|
+
* @param expiration - Signature expiration timestamp
|
|
278
|
+
* @param signatures - Multisig signatures for authorization
|
|
279
|
+
*/
|
|
280
|
+
setSupportedMessageLibMoveCall(
|
|
281
|
+
tx: Transaction,
|
|
282
|
+
adminCap: string | TransactionArgument,
|
|
283
|
+
messageLib: string | TransactionArgument,
|
|
284
|
+
supported: boolean | TransactionArgument,
|
|
285
|
+
expiration: bigint | number | string | TransactionArgument,
|
|
286
|
+
signatures: Uint8Array | TransactionArgument
|
|
287
|
+
): void {
|
|
288
|
+
tx.moveCall({
|
|
289
|
+
target: this.#target('set_supported_message_lib'),
|
|
290
|
+
arguments: [
|
|
291
|
+
tx.object(this.objects.dvn),
|
|
292
|
+
asObject(tx, adminCap),
|
|
293
|
+
asAddress(tx, messageLib),
|
|
294
|
+
asBool(tx, supported),
|
|
295
|
+
asU64(tx, expiration),
|
|
296
|
+
asBytes(tx, signatures),
|
|
297
|
+
tx.object.clock(),
|
|
298
|
+
],
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
|
|
256
302
|
/**
|
|
257
303
|
* Set allowlist status for an OApp sender (admin with signatures)
|
|
258
304
|
* @param tx - The transaction to add the move call to
|
|
@@ -433,32 +479,33 @@ export class DVN {
|
|
|
433
479
|
// Verification Functions
|
|
434
480
|
|
|
435
481
|
/**
|
|
436
|
-
* Verify a packet with DVN signatures (admin with signatures)
|
|
482
|
+
* Verify a packet with DVN signatures (admin with signatures) - returns Call object for ULN302
|
|
437
483
|
* @param tx - The transaction to add the move call to
|
|
438
484
|
* @param adminCap - The admin capability object ID
|
|
439
|
-
* @param
|
|
485
|
+
* @param targetMessageLib - The target message library address (usually ULN302)
|
|
440
486
|
* @param packetHeader - The packet header as bytes
|
|
441
487
|
* @param payloadHash - The payload hash as bytes
|
|
442
488
|
* @param confirmations - Required confirmations count
|
|
443
489
|
* @param expiration - Signature expiration timestamp
|
|
444
490
|
* @param signatures - DVN multisig signatures
|
|
491
|
+
* @returns Transaction result containing the verification Call object
|
|
445
492
|
*/
|
|
446
493
|
verifyMoveCall(
|
|
447
494
|
tx: Transaction,
|
|
448
495
|
adminCap: string | TransactionArgument,
|
|
449
|
-
|
|
496
|
+
targetMessageLib: string | TransactionArgument,
|
|
450
497
|
packetHeader: Uint8Array | TransactionArgument,
|
|
451
498
|
payloadHash: Uint8Array | TransactionArgument,
|
|
452
499
|
confirmations: bigint | number | string | TransactionArgument,
|
|
453
500
|
expiration: bigint | number | string | TransactionArgument,
|
|
454
501
|
signatures: Uint8Array | TransactionArgument
|
|
455
|
-
):
|
|
456
|
-
tx.moveCall({
|
|
502
|
+
): TransactionResult {
|
|
503
|
+
return tx.moveCall({
|
|
457
504
|
target: this.#target('verify'),
|
|
458
505
|
arguments: [
|
|
459
506
|
tx.object(this.objects.dvn),
|
|
460
507
|
asObject(tx, adminCap),
|
|
461
|
-
|
|
508
|
+
asAddress(tx, targetMessageLib),
|
|
462
509
|
asBytes(tx, packetHeader),
|
|
463
510
|
asBytes32(tx, payloadHash, this.moduleManager.getUtils()),
|
|
464
511
|
asU64(tx, confirmations),
|
|
@@ -755,6 +802,34 @@ export class DVN {
|
|
|
755
802
|
)
|
|
756
803
|
}
|
|
757
804
|
|
|
805
|
+
/**
|
|
806
|
+
* Check if a message library is supported by this DVN
|
|
807
|
+
* @param tx - The transaction to add the move call to
|
|
808
|
+
* @param messageLib - The message library address to check
|
|
809
|
+
* @returns Transaction result containing the support status
|
|
810
|
+
*/
|
|
811
|
+
isSupportedMessageLibMoveCall(tx: Transaction, messageLib: string | TransactionArgument): TransactionResult {
|
|
812
|
+
return tx.moveCall({
|
|
813
|
+
target: this.#target('is_supported_message_lib'),
|
|
814
|
+
arguments: [tx.object(this.objects.dvn), asAddress(tx, messageLib)],
|
|
815
|
+
})
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* Check if a message library is supported by this DVN
|
|
820
|
+
* @param messageLib - The message library address to check
|
|
821
|
+
* @returns Promise<boolean> - True if the message library is supported
|
|
822
|
+
*/
|
|
823
|
+
async isSupportedMessageLib(messageLib: string): Promise<boolean> {
|
|
824
|
+
return executeSimulate(
|
|
825
|
+
this.client,
|
|
826
|
+
(tx) => {
|
|
827
|
+
this.isSupportedMessageLibMoveCall(tx, messageLib)
|
|
828
|
+
},
|
|
829
|
+
(result) => bcs.Bool.parse(result[0].value)
|
|
830
|
+
)
|
|
831
|
+
}
|
|
832
|
+
|
|
758
833
|
/**
|
|
759
834
|
* Check if an address is allowlisted
|
|
760
835
|
* @param tx - The transaction to add the move call to
|
|
@@ -1135,6 +1210,65 @@ export class DVN {
|
|
|
1135
1210
|
)
|
|
1136
1211
|
}
|
|
1137
1212
|
|
|
1213
|
+
/**
|
|
1214
|
+
* Get DVN object address from worker registry using this DVN's worker capability (as a move call)
|
|
1215
|
+
* This function chains Move calls to decode worker info and extract the DVN object address
|
|
1216
|
+
* @param tx - The transaction to add the move call to
|
|
1217
|
+
* @returns Transaction result containing the DVN object address
|
|
1218
|
+
*/
|
|
1219
|
+
getDvnObjectAddressMoveCall(tx: Transaction): TransactionResult {
|
|
1220
|
+
// Step 1: Get this DVN's worker capability address
|
|
1221
|
+
const workerCapAddress = this.workerCapAddressMoveCall(tx)
|
|
1222
|
+
|
|
1223
|
+
// Step 2: Get worker info bytes from registry
|
|
1224
|
+
const workerInfoBytes = this.moduleManager
|
|
1225
|
+
.getWorkerRegistry(this.client)
|
|
1226
|
+
.getWorkerInfoMoveCall(tx, workerCapAddress)
|
|
1227
|
+
|
|
1228
|
+
// Step 3: Decode worker info using worker_common::worker_info_v1::decode
|
|
1229
|
+
const workerInfo = tx.moveCall({
|
|
1230
|
+
target: `${this.moduleManager.packages.workerCommon}::worker_info_v1::decode`,
|
|
1231
|
+
arguments: [workerInfoBytes],
|
|
1232
|
+
})
|
|
1233
|
+
|
|
1234
|
+
// Step 4: Extract worker_info field from decoded WorkerInfoV1
|
|
1235
|
+
const dvnInfoBytes = tx.moveCall({
|
|
1236
|
+
target: `${this.moduleManager.packages.workerCommon}::worker_info_v1::worker_info`,
|
|
1237
|
+
arguments: [workerInfo],
|
|
1238
|
+
})
|
|
1239
|
+
|
|
1240
|
+
// Step 5: Decode DVN info using dvn::dvn_info_v1::decode
|
|
1241
|
+
const dvnInfo = tx.moveCall({
|
|
1242
|
+
target: `${this.packageId}::dvn_info_v1::decode`,
|
|
1243
|
+
arguments: [dvnInfoBytes],
|
|
1244
|
+
})
|
|
1245
|
+
|
|
1246
|
+
// Step 6: Extract dvn_object address from decoded DVNInfoV1
|
|
1247
|
+
return tx.moveCall({
|
|
1248
|
+
target: `${this.packageId}::dvn_info_v1::dvn_object`,
|
|
1249
|
+
arguments: [dvnInfo],
|
|
1250
|
+
})
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* Get DVN object address from worker registry using this DVN's worker capability
|
|
1255
|
+
* This function uses Move calls to decode worker info and extract the DVN object address
|
|
1256
|
+
* @returns Promise<string> - The DVN object address
|
|
1257
|
+
* @throws Will throw an error if worker info is not found or if decoding fails
|
|
1258
|
+
*/
|
|
1259
|
+
async getDvnObjectAddress(): Promise<string> {
|
|
1260
|
+
return executeSimulate(
|
|
1261
|
+
this.client,
|
|
1262
|
+
(tx) => {
|
|
1263
|
+
this.getDvnObjectAddressMoveCall(tx)
|
|
1264
|
+
},
|
|
1265
|
+
(result) => {
|
|
1266
|
+
// The result is the DVN object address directly from the Move call chain
|
|
1267
|
+
return bcs.Address.parse(result[0].value)
|
|
1268
|
+
}
|
|
1269
|
+
)
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1138
1272
|
// === Witness Functions ===
|
|
1139
1273
|
|
|
1140
1274
|
/**
|
|
@@ -1506,6 +1640,80 @@ export class DVN {
|
|
|
1506
1640
|
})
|
|
1507
1641
|
}
|
|
1508
1642
|
|
|
1643
|
+
/**
|
|
1644
|
+
* Populate verify with DVN verification and ULN verify call
|
|
1645
|
+
* @param tx - The transaction to add the move call to
|
|
1646
|
+
* @param adminCap - The admin capability object ID
|
|
1647
|
+
* @param targetMessageLib - The target message library address (usually ULN302)
|
|
1648
|
+
* @param targetVerification - The verification object address for the target message library
|
|
1649
|
+
* @param packetHeader - The packet header as bytes
|
|
1650
|
+
* @param payloadHash - The payload hash as bytes
|
|
1651
|
+
* @param confirmations - Required confirmations count
|
|
1652
|
+
* @param expiration - Signature expiration timestamp
|
|
1653
|
+
* @param signatures - DVN multisig signatures
|
|
1654
|
+
*/
|
|
1655
|
+
populateVerify(
|
|
1656
|
+
tx: Transaction,
|
|
1657
|
+
adminCap: string | TransactionArgument,
|
|
1658
|
+
targetMessageLib: string,
|
|
1659
|
+
targetVerification: string,
|
|
1660
|
+
packetHeader: Uint8Array | TransactionArgument,
|
|
1661
|
+
payloadHash: Uint8Array | TransactionArgument,
|
|
1662
|
+
confirmations: bigint | number | string | TransactionArgument,
|
|
1663
|
+
expiration: bigint | number | string | TransactionArgument,
|
|
1664
|
+
signatures: Uint8Array | TransactionArgument
|
|
1665
|
+
): void {
|
|
1666
|
+
// Step 1: Call DVN's verifyMoveCall to get the verification call
|
|
1667
|
+
const dvnCall = this.verifyMoveCall(
|
|
1668
|
+
tx,
|
|
1669
|
+
adminCap,
|
|
1670
|
+
targetMessageLib,
|
|
1671
|
+
packetHeader,
|
|
1672
|
+
payloadHash,
|
|
1673
|
+
confirmations,
|
|
1674
|
+
expiration,
|
|
1675
|
+
signatures
|
|
1676
|
+
)
|
|
1677
|
+
|
|
1678
|
+
// Step 2: Get the message library object address based on targetMessageLib
|
|
1679
|
+
const messageLibObjectAddress = this.#getUlnObjectAddress(targetMessageLib)
|
|
1680
|
+
|
|
1681
|
+
tx.moveCall({
|
|
1682
|
+
target: this.#getUlnVerifyTarget(targetMessageLib),
|
|
1683
|
+
arguments: [tx.object(messageLibObjectAddress), asObject(tx, targetVerification), dvnCall],
|
|
1684
|
+
})
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
/**
|
|
1688
|
+
* Get message library object address based on targetMessageLib package address
|
|
1689
|
+
* @param targetMessageLib - The target message library package address
|
|
1690
|
+
* @returns Message library object address
|
|
1691
|
+
* @throws Error if targetMessageLib doesn't match any known message library
|
|
1692
|
+
* @private
|
|
1693
|
+
*/
|
|
1694
|
+
#getUlnObjectAddress(targetMessageLib: string): string {
|
|
1695
|
+
// Check if targetMessageLib equals ULN302 package address
|
|
1696
|
+
if (targetMessageLib === this.moduleManager.packages.uln302) {
|
|
1697
|
+
return this.objects.uln302
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
throw new Error('Target message library not match objects')
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
/**
|
|
1704
|
+
* Get ULN verify target path based on targetMessageLib package address
|
|
1705
|
+
* @param targetMessageLib - The target message library package address
|
|
1706
|
+
* @returns Message library verify target path
|
|
1707
|
+
* @throws Error if targetMessageLib doesn't match any known message library
|
|
1708
|
+
* @private
|
|
1709
|
+
*/
|
|
1710
|
+
#getUlnVerifyTarget(targetMessageLib: string): string {
|
|
1711
|
+
if (targetMessageLib === this.moduleManager.packages.uln302) {
|
|
1712
|
+
return `${targetMessageLib}::uln_302::verify`
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
throw new Error('Target message library not match any target')
|
|
1716
|
+
}
|
|
1509
1717
|
/**
|
|
1510
1718
|
* Generate the full target path for move calls
|
|
1511
1719
|
* @param name - The function name to call
|
|
@@ -7,10 +7,18 @@ import { ObjectOptions } from '../../types'
|
|
|
7
7
|
const MODULE_NAME = 'executor_fee_lib'
|
|
8
8
|
|
|
9
9
|
export const ExecutorFeeLibErrorCode = {
|
|
10
|
-
// Executor Fee Lib related errors (
|
|
10
|
+
// Executor Fee Lib related errors (matching executor_fee_lib.move)
|
|
11
11
|
ExecutorFeeLib_EEidNotSupported: 1,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
// ExecutorOption related errors (matching executor_option.move)
|
|
14
|
+
ExecutorOption_ENoOptions: 1,
|
|
15
|
+
ExecutorOption_EUnsupportedOptionType: 2,
|
|
16
|
+
ExecutorOption_EZeroLzReceiveGasProvided: 3,
|
|
17
|
+
ExecutorOption_EZeroLzComposeGasProvided: 4,
|
|
18
|
+
ExecutorOption_ENativeAmountExceedsCap: 5,
|
|
19
|
+
ExecutorOption_EInvalidLzReceiveOption: 6,
|
|
20
|
+
ExecutorOption_EInvalidNativeDropOption: 7,
|
|
21
|
+
ExecutorOption_EInvalidLzComposeOption: 8,
|
|
14
22
|
} as const
|
|
15
23
|
|
|
16
24
|
export class ExecutorFeeLib {
|
|
@@ -6,6 +6,11 @@ import { asAddress, asAddressVector, asObject, asU16 } from '../../utils'
|
|
|
6
6
|
|
|
7
7
|
const MODULE_NAME = 'executor_layerzero'
|
|
8
8
|
|
|
9
|
+
export const ExecutorLayerzeroErrorCode = {
|
|
10
|
+
// ExecutorLayerzero related errors (matching executor_layerzero.move)
|
|
11
|
+
ExecutorLayerzero_EWorkerCapNotFromPackage: 1,
|
|
12
|
+
} as const
|
|
13
|
+
|
|
9
14
|
export class ExecutorLayerZero {
|
|
10
15
|
public packageId: string
|
|
11
16
|
public readonly client: SuiClient
|
|
@@ -27,6 +32,7 @@ export class ExecutorLayerZero {
|
|
|
27
32
|
* @param tx - The transaction to add the move call to
|
|
28
33
|
* @param workerCap - Worker capability object ID or transaction argument
|
|
29
34
|
* @param depositAddress - Address for fee deposits or transaction argument
|
|
35
|
+
* @param supportedMessageLibs - Array of supported message library addresses or transaction argument
|
|
30
36
|
* @param priceFeed - Price feed object address or transaction argument
|
|
31
37
|
* @param workerFeeLib - Worker fee library address or transaction argument
|
|
32
38
|
* @param defaultMultiplierBps - Default multiplier in basis points or transaction argument
|
|
@@ -37,6 +43,7 @@ export class ExecutorLayerZero {
|
|
|
37
43
|
tx: Transaction,
|
|
38
44
|
workerCap: string | TransactionArgument,
|
|
39
45
|
depositAddress: string | TransactionArgument,
|
|
46
|
+
supportedMessageLibs: string[] | TransactionArgument,
|
|
40
47
|
priceFeed: string | TransactionArgument,
|
|
41
48
|
workerFeeLib: string | TransactionArgument,
|
|
42
49
|
defaultMultiplierBps: number | TransactionArgument,
|
|
@@ -48,11 +55,13 @@ export class ExecutorLayerZero {
|
|
|
48
55
|
arguments: [
|
|
49
56
|
asObject(tx, workerCap),
|
|
50
57
|
asAddress(tx, depositAddress),
|
|
58
|
+
asAddressVector(tx, supportedMessageLibs),
|
|
51
59
|
asAddress(tx, priceFeed),
|
|
52
60
|
asAddress(tx, workerFeeLib),
|
|
53
61
|
asU16(tx, defaultMultiplierBps),
|
|
54
62
|
asAddress(tx, owner),
|
|
55
63
|
asAddressVector(tx, admins),
|
|
64
|
+
tx.object(this.moduleManager.objects.workerRegistry),
|
|
56
65
|
],
|
|
57
66
|
})
|
|
58
67
|
}
|
|
@@ -25,6 +25,10 @@ export const ExecutorErrorCode = {
|
|
|
25
25
|
// Executor related errors (with Executor_ prefix)
|
|
26
26
|
Executor_EEidNotSupported: 1,
|
|
27
27
|
Executor_EInvalidNativeDropAmount: 2,
|
|
28
|
+
|
|
29
|
+
// ExecutorInfoV1 related errors (matching executor_info_v1.move)
|
|
30
|
+
ExecutorInfoV1_EInvalidData: 1,
|
|
31
|
+
ExecutorInfoV1_EInvalidVersion: 2,
|
|
28
32
|
} as const
|
|
29
33
|
|
|
30
34
|
export class Executor {
|
|
@@ -524,6 +528,30 @@ export class Executor {
|
|
|
524
528
|
})
|
|
525
529
|
}
|
|
526
530
|
|
|
531
|
+
/**
|
|
532
|
+
* Set supported message library (owner only)
|
|
533
|
+
* @param tx - The transaction to add the move call to
|
|
534
|
+
* @param ownerCap - The owner capability object ID
|
|
535
|
+
* @param messageLib - The message library address
|
|
536
|
+
* @param supported - Whether to support or remove support for the message library
|
|
537
|
+
*/
|
|
538
|
+
setSupportedMessageLibMoveCall(
|
|
539
|
+
tx: Transaction,
|
|
540
|
+
ownerCap: string | TransactionArgument,
|
|
541
|
+
messageLib: string | TransactionArgument,
|
|
542
|
+
supported: boolean | TransactionArgument
|
|
543
|
+
): void {
|
|
544
|
+
tx.moveCall({
|
|
545
|
+
target: this.#target('set_supported_message_lib'),
|
|
546
|
+
arguments: [
|
|
547
|
+
tx.object(this.objects.executor),
|
|
548
|
+
asObject(tx, ownerCap),
|
|
549
|
+
asAddress(tx, messageLib),
|
|
550
|
+
asBool(tx, supported),
|
|
551
|
+
],
|
|
552
|
+
})
|
|
553
|
+
}
|
|
554
|
+
|
|
527
555
|
/**
|
|
528
556
|
* Set allowlist status for an OApp sender (owner only)
|
|
529
557
|
* @param tx - The transaction to add the move call to
|
|
@@ -810,6 +838,34 @@ export class Executor {
|
|
|
810
838
|
)
|
|
811
839
|
}
|
|
812
840
|
|
|
841
|
+
/**
|
|
842
|
+
* Check if a message library is supported by this executor
|
|
843
|
+
* @param tx - The transaction to add the move call to
|
|
844
|
+
* @param messageLib - The message library address to check
|
|
845
|
+
* @returns Transaction result containing the support status
|
|
846
|
+
*/
|
|
847
|
+
isSupportedMessageLibMoveCall(tx: Transaction, messageLib: string | TransactionArgument): TransactionResult {
|
|
848
|
+
return tx.moveCall({
|
|
849
|
+
target: this.#target('is_supported_message_lib'),
|
|
850
|
+
arguments: [tx.object(this.objects.executor), asAddress(tx, messageLib)],
|
|
851
|
+
})
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Check if a message library is supported by this executor
|
|
856
|
+
* @param messageLib - The message library address to check
|
|
857
|
+
* @returns Promise<boolean> - True if the message library is supported
|
|
858
|
+
*/
|
|
859
|
+
async isSupportedMessageLib(messageLib: string): Promise<boolean> {
|
|
860
|
+
return executeSimulate(
|
|
861
|
+
this.client,
|
|
862
|
+
(tx) => {
|
|
863
|
+
this.isSupportedMessageLibMoveCall(tx, messageLib)
|
|
864
|
+
},
|
|
865
|
+
(result) => bcs.Bool.parse(result[0].value)
|
|
866
|
+
)
|
|
867
|
+
}
|
|
868
|
+
|
|
813
869
|
/**
|
|
814
870
|
* Check if an address is allowlisted
|
|
815
871
|
* @param tx - The transaction to add the move call to
|
|
@@ -1029,6 +1085,65 @@ export class Executor {
|
|
|
1029
1085
|
)
|
|
1030
1086
|
}
|
|
1031
1087
|
|
|
1088
|
+
/**
|
|
1089
|
+
* Get Executor object address from worker registry using this Executor's worker capability (as a move call)
|
|
1090
|
+
* This function chains Move calls to decode worker info and extract the Executor object address
|
|
1091
|
+
* @param tx - The transaction to add the move call to
|
|
1092
|
+
* @returns Transaction result containing the Executor object address
|
|
1093
|
+
*/
|
|
1094
|
+
getExecutorObjectAddressMoveCall(tx: Transaction): TransactionResult {
|
|
1095
|
+
// Step 1: Get this Executor's worker capability address
|
|
1096
|
+
const workerCapAddress = this.workerCapAddressMoveCall(tx)
|
|
1097
|
+
|
|
1098
|
+
// Step 2: Get worker info bytes from registry
|
|
1099
|
+
const workerInfoBytes = this.moduleManager
|
|
1100
|
+
.getWorkerRegistry(this.client)
|
|
1101
|
+
.getWorkerInfoMoveCall(tx, workerCapAddress)
|
|
1102
|
+
|
|
1103
|
+
// Step 3: Decode worker info using worker_common::worker_info_v1::decode
|
|
1104
|
+
const workerInfo = tx.moveCall({
|
|
1105
|
+
target: `${this.moduleManager.packages.workerCommon}::worker_info_v1::decode`,
|
|
1106
|
+
arguments: [workerInfoBytes],
|
|
1107
|
+
})
|
|
1108
|
+
|
|
1109
|
+
// Step 4: Extract worker_info field from decoded WorkerInfoV1
|
|
1110
|
+
const executorInfoBytes = tx.moveCall({
|
|
1111
|
+
target: `${this.moduleManager.packages.workerCommon}::worker_info_v1::worker_info`,
|
|
1112
|
+
arguments: [workerInfo],
|
|
1113
|
+
})
|
|
1114
|
+
|
|
1115
|
+
// Step 5: Decode Executor info using executor::executor_info_v1::decode
|
|
1116
|
+
const executorInfo = tx.moveCall({
|
|
1117
|
+
target: `${this.packageId}::executor_info_v1::decode`,
|
|
1118
|
+
arguments: [executorInfoBytes],
|
|
1119
|
+
})
|
|
1120
|
+
|
|
1121
|
+
// Step 6: Extract executor_object address from decoded ExecutorInfoV1
|
|
1122
|
+
return tx.moveCall({
|
|
1123
|
+
target: `${this.packageId}::executor_info_v1::executor_object`,
|
|
1124
|
+
arguments: [executorInfo],
|
|
1125
|
+
})
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* Get Executor object address from worker registry using this Executor's worker capability
|
|
1130
|
+
* This function uses Move calls to decode worker info and extract the Executor object address
|
|
1131
|
+
* @returns Promise<string> - The Executor object address
|
|
1132
|
+
* @throws Will throw an error if worker info is not found or if decoding fails
|
|
1133
|
+
*/
|
|
1134
|
+
async getExecutorObjectAddress(): Promise<string> {
|
|
1135
|
+
return executeSimulate(
|
|
1136
|
+
this.client,
|
|
1137
|
+
(tx) => {
|
|
1138
|
+
this.getExecutorObjectAddressMoveCall(tx)
|
|
1139
|
+
},
|
|
1140
|
+
(result) => {
|
|
1141
|
+
// The result is the Executor object address directly from the Move call chain
|
|
1142
|
+
return bcs.Address.parse(result[0].value)
|
|
1143
|
+
}
|
|
1144
|
+
)
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1032
1147
|
// === Private Helper Functions ===
|
|
1033
1148
|
|
|
1034
1149
|
private parseDstConfig(data: Uint8Array): DstConfig {
|
|
@@ -9,10 +9,10 @@ import { asAddress, asBool, asU64, executeSimulate } from '../../utils'
|
|
|
9
9
|
const MODULE_NAME = 'treasury'
|
|
10
10
|
|
|
11
11
|
export const TreasuryErrorCode = {
|
|
12
|
-
// Treasury related errors
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
// Treasury related errors (matching treasury.move)
|
|
13
|
+
TREASURY_EInvalidFeeRecipient: 1,
|
|
14
|
+
TREASURY_EInvalidNativeFeeBp: 2,
|
|
15
|
+
TREASURY_EZroNotEnabled: 3,
|
|
16
16
|
} as const
|
|
17
17
|
|
|
18
18
|
export class Treasury {
|