@layerzerolabs/ton-sdk-tools 3.0.59 → 3.0.60

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/dist/index.cjs CHANGED
@@ -362,6 +362,7 @@ import {
362
362
  TupleItem,
363
363
  TupleReader,
364
364
  contractAddress,
365
+ beginCell,
365
366
  } from '@ton/core'
366
367
 
367
368
  ${baseWrapper}
@@ -393,6 +394,18 @@ export class TonContractWrapper extends BaseWrapper {
393
394
  return this.buildSenderArguments(body, opts)
394
395
  }
395
396
 
397
+ async sendTonPayment(
398
+ provider: ContractProvider,
399
+ via: Sender,
400
+ opts: SendRequestOptions,
401
+ ): Promise<void> {
402
+ if (via.address === undefined) {
403
+ throw new Error('Sender address is not defined')
404
+ }
405
+ const request = this.buildSenderArguments(beginCell().endCell(), opts)
406
+ return this.sendRequest(provider, via, request)
407
+ }
408
+
396
409
  async sendInternalMessage(
397
410
  provider: ContractProvider,
398
411
  via: Sender,
@@ -1244,7 +1257,18 @@ var BaseWrapper = class {
1244
1257
  function generateCommonTestUtils(directory, filename) {
1245
1258
  const savedCode = `import fs from 'fs'
1246
1259
 
1247
- import { Address, Builder, Cell, Dictionary, SendMode, TupleItem, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1260
+ import {
1261
+ Address,
1262
+ Builder,
1263
+ Cell,
1264
+ Dictionary,
1265
+ SendMode,
1266
+ TupleItem,
1267
+ TupleItemCell,
1268
+ TupleItemInt,
1269
+ beginCell,
1270
+ toNano,
1271
+ } from '@ton/core'
1248
1272
  import {
1249
1273
  Blockchain,
1250
1274
  BlockchainTransaction,
@@ -1483,7 +1507,7 @@ export interface ProtocolFixture {
1483
1507
  eid: bigint
1484
1508
  controller: SandboxContract<TonContractWrapper>
1485
1509
  endpoint: SandboxContract<TonContractWrapper>
1486
- msglib: SandboxContract<TonContractWrapper>
1510
+ msglib: Map<bigint, SandboxContract<TonContractWrapper>>
1487
1511
  msglibManager: SandboxContract<TonContractWrapper>
1488
1512
  msglibManagerCustom?: SandboxContract<TonContractWrapper>
1489
1513
  }
@@ -1515,17 +1539,18 @@ export function logAddresses(
1515
1539
  prefix: string,
1516
1540
  protocolHeader: string,
1517
1541
  oappHeader: string,
1518
- fixture: OAppFixture
1542
+ fixture: OAppFixture,
1543
+ eid: bigint
1519
1544
  ) => {
1520
1545
  [p: string]: string | bigint | null
1521
- } = function (prefix: string, protocolHeader: string, oappHeader: string, fixture: OAppFixture) {
1546
+ } = function (prefix: string, protocolHeader: string, oappHeader: string, fixture: OAppFixture, eid: bigint) {
1522
1547
  return {
1523
1548
  [\`--- \${protocolHeader} ---\`]: '', // Custom separator
1524
1549
  [\`\${prefix}.multisig.address\`]: formatAddress(fixture.multisig.address),
1525
1550
  [\`\${prefix}.controller.address\`]: formatAddress(fixture.controller.address),
1526
1551
  [\`\${prefix}.endpoint.address\`]: formatAddress(fixture.endpoint.address),
1527
1552
  [\`\${prefix}.msglibManager.address\`]: formatAddress(fixture.msglibManager.address),
1528
- [\`\${prefix}.msglib.address\`]: formatAddress(fixture.msglib.address),
1553
+ [\`\${prefix}.msglib.address\`]: formatAddress(fixture.msglib.get(eid)?.address ?? ''),
1529
1554
  [\`\${prefix}.smlManagerCustom.address\`]: formatAddress(fixture.msglibManagerCustom?.address ?? ''),
1530
1555
  [\`--- \${oappHeader} ---\`]: '', // Custom separator
1531
1556
  [\`\${prefix}.owner.address\`]: formatAddress(fixture.owner.address),
@@ -1542,9 +1567,21 @@ export function logAddresses(
1542
1567
  'multiSigOwner1.address': formatAddress(multiSigOwner1.address),
1543
1568
  'multiSigOwner2.address': formatAddress(multiSigOwner2.address),
1544
1569
  'multiSigOwner3.address': formatAddress(multiSigOwner3.address),
1545
- ...collectAddresses('srcFixture', 'Source Protocol Addresses', 'Source OApp Addresses', srcFixture),
1570
+ ...collectAddresses(
1571
+ 'srcFixture',
1572
+ 'Source Protocol Addresses',
1573
+ 'Source OApp Addresses',
1574
+ srcFixture,
1575
+ dstFixture?.eid ?? 0n
1576
+ ),
1546
1577
  ...(dstFixture
1547
- ? collectAddresses('dstFixture', 'Destination Protocol Addresses', 'Destination OApp Addresses', dstFixture)
1578
+ ? collectAddresses(
1579
+ 'dstFixture',
1580
+ 'Destination Protocol Addresses',
1581
+ 'Destination OApp Addresses',
1582
+ dstFixture,
1583
+ srcFixture.eid
1584
+ )
1548
1585
  : {}),
1549
1586
  }
1550
1587
 
@@ -2720,12 +2757,12 @@ export async function assertZroBalance(
2720
2757
  }
2721
2758
 
2722
2759
  export function isValidAscii(input: string): boolean {
2723
- for (var i=0; i < input.length; i++) {
2724
- if (input.charCodeAt(i)>127) {
2725
- return false;
2760
+ for (let i = 0; i < input.length; i++) {
2761
+ if (input.charCodeAt(i) > 127) {
2762
+ return false
2726
2763
  }
2727
2764
  }
2728
- return true;
2765
+ return true
2729
2766
  }
2730
2767
 
2731
2768
  export async function txDecoder(
@@ -2824,432 +2861,427 @@ export async function runtimeDecoder(contract: SandboxContract<TonContractWrappe
2824
2861
  }
2825
2862
  function generateSmlTestUtils(directory, filename) {
2826
2863
  const savedCode = `import { Cell, toNano } from '@ton/core'
2827
- import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
2828
- import '@ton/test-utils'
2829
-
2830
- import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
2831
- import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
2832
- import SmlConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlConnection.compiled.json'
2833
- import SmlManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlManager.compiled.json'
2834
- import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
2835
-
2836
- import {
2837
- OAppFixture,
2838
- OAppFlowGas,
2839
- addMsgLibToController,
2840
- emptyObject,
2841
- protocolSetupGas,
2842
- sendInternalMessageAndExpect,
2843
- setDefaultEndpointConfig,
2844
- wireChannels,
2845
- } from './auto-utils-common'
2846
- import { LzEventHandler, OPCODES, TonContractWrapper } from '../../src'
2847
-
2848
- const SML_MANAGER_DEFAULT_VERSION = BigInt(1)
2849
- const SML_MANAGER_CUSTOM_VERSION = BigInt(2)
2850
-
2851
- // ==============================SML INTEGRATION FUNCTIONS==============================
2852
-
2853
- export async function commitVerificationAndExpectSml(
2854
- lzPacketCell: Cell,
2855
- deployer: SandboxContract<TreasuryContract>,
2856
- eventHandler: LzEventHandler,
2857
- {
2858
- endpoint,
2859
- channel,
2860
- msglibManager: smlManager,
2861
- msglibConnection: smlConnection,
2862
- controller,
2863
- }: OAppFixture,
2864
- profile?: Profile
2865
- ): Promise<void> {
2866
- const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
2867
- profile,
2868
- value: OAppFlowGas['Msglib.COMMIT_PACKET'],
2869
- sender: deployer.getSender(),
2870
- contract: smlManager,
2871
- opCode: OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET,
2872
- md: await smlManager.getNewMdMdAddress({
2873
- md: lzPacketCell,
2874
- address: addressToBigInt(endpoint.address),
2875
- }),
2876
- expectedTransactions: [
2877
- {
2878
- from: deployer.address,
2879
- to: smlManager.address,
2880
- op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET),
2881
- success: true,
2882
- },
2883
- {
2884
- from: smlManager.address,
2885
- to: smlConnection.address,
2886
- op: Number(OPCODES.SmlConnection_OP_SML_CONNECTION_COMMIT_PACKET),
2887
- success: true,
2888
- },
2889
- {
2890
- from: smlConnection.address,
2891
- to: endpoint.address,
2892
- op: Number(OPCODES.Endpoint_OP_ENDPOINT_COMMIT_PACKET),
2893
- success: true,
2894
- },
2895
- {
2896
- from: endpoint.address,
2897
- to: channel.address,
2898
- op: Number(OPCODES.Channel_OP_CHANNEL_COMMIT_PACKET),
2899
- success: true,
2900
- },
2901
- // emit event channel::EVENT::MESSAGE_COMMITTED
2902
- {
2903
- from: channel.address,
2904
- to: controller.address,
2905
- op: Number(OPCODES.BaseInterface_OP_EVENT),
2906
- success: false, // events are supposed to fail
2907
- },
2908
- {
2909
- from: channel.address,
2910
- to: smlConnection.address,
2911
- op: Number(OPCODES.MsglibConnection_OP_MSGLIB_CONNECTION_COMMIT_PACKET_CALLBACK),
2912
- success: true,
2913
- },
2914
- {
2915
- from: smlConnection.address,
2916
- to: smlManager.address,
2917
- op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET_CALLBACK),
2918
- success: true,
2919
- },
2920
- // refund excess ton
2921
- {
2922
- from: smlManager.address,
2923
- to: deployer.address,
2924
- success: true,
2925
- },
2926
- ],
2927
- })
2928
-
2929
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, smlManager)
2930
- expect(eventHandler.allFailures.txList).toHaveLength(0)
2931
- }
2932
-
2933
- // ===============================HELPER ASSERTS===============================
2934
-
2935
- export async function openAndDeploySmlManager(
2936
- blockchain: Blockchain,
2937
- allStorages: SandboxContract<TonContractWrapper>,
2938
- fixture: OAppFixture,
2939
- version: bigint
2940
- ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2941
- const smlManager: SandboxContract<TonContractWrapper> = blockchain.openContract(
2942
- TonContractWrapper.create(
2943
- cellFromArtifact(SmlManagerArtifact),
2944
- await allStorages.getNewSmlManager({
2945
- owner: addressToBigInt(fixture.owner.address),
2946
- eid: fixture.eid,
2947
- version,
2948
- controllerAddress: addressToBigInt(fixture.controller.address),
2949
- endpointCode: cellFromArtifact(EndpointArtifact),
2950
- channelCode: cellFromArtifact(ChannelArtifact),
2951
- smlConnectionCode: cellFromArtifact(SmlConnectionArtifact),
2952
- })
2953
- )
2954
- )
2955
-
2956
- const internalMsgResults = await sendInternalMessageAndExpect({
2957
- value: protocolSetupGas['MsgLib.INITIALIZE'],
2958
- sender: fixture.owner.getSender(),
2959
- contract: smlManager,
2960
- expectedTransactions: [
2961
- {
2962
- from: fixture.owner.address,
2963
- to: smlManager.address,
2964
- success: true,
2965
- },
2966
- ],
2967
- opCode: OPCODES.BaseInterface_OP_INITIALIZE,
2968
- md: emptyObject,
2969
- balanceRefill: toNano('1'),
2970
- })
2971
-
2972
- return [smlManager, internalMsgResults]
2973
- }
2974
-
2975
- export async function openAndDeploySmlConnection(
2976
- blockchain: Blockchain,
2977
- allStorages: SandboxContract<TonContractWrapper>,
2978
- srcFixture: OAppFixture,
2979
- dstFixture: OAppFixture,
2980
- smlManager: SandboxContract<TonContractWrapper>
2981
- ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2982
- const smlConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
2983
- TonContractWrapper.create(
2984
- cellFromArtifact(SmlConnectionArtifact),
2985
- await allStorages.getNewSmlConnection({
2986
- owner: addressToBigInt(smlManager.address),
2987
- path: srcFixture.path,
2988
- })
2989
- )
2990
- )
2991
-
2992
- const internalMsgResults = await sendInternalMessageAndExpect({
2993
- value: toNano('10'),
2994
- sender: srcFixture.owner.getSender(),
2995
- contract: srcFixture.oApp,
2996
- opCode: OPCODES.OP_DeployConnection,
2997
- md: await allStorages.getNewMdMdAddress({
2998
- md: await allStorages.getNewMdDeploy({
2999
- dstEid: dstFixture.eid,
3000
- dstOApp: addressToBigInt(dstFixture.oApp.address),
3001
- initialDeposit: toNano('1'),
3002
- }),
3003
- address: addressToBigInt(smlManager.address),
3004
- }),
3005
- expectedTransactions: [
3006
- {
3007
- from: srcFixture.owner.address,
3008
- to: srcFixture.oApp.address,
3009
- op: Number(OPCODES.OP_DeployConnection),
3010
- success: true,
3011
- },
3012
- {
3013
- from: srcFixture.oApp.address,
3014
- to: smlManager.address,
3015
- op: Number(OPCODES.MsglibManager_OP_DEPLOY_CONNECTION),
3016
- success: true,
3017
- },
3018
- {
3019
- from: smlManager.address,
3020
- to: smlConnection.address,
3021
- op: Number(OPCODES.BaseInterface_OP_INITIALIZE),
3022
- deploy: true,
3023
- success: true,
3024
- },
3025
- ],
3026
- })
3027
-
3028
- return [smlConnection, internalMsgResults]
3029
- }
3030
-
3031
- export async function deployConfigAndRegisterSml(
3032
- blockchain: Blockchain,
3033
- multiSigners: SandboxContract<TreasuryContract>[],
3034
- allStorages: SandboxContract<TonContractWrapper>,
3035
- srcFixture: OAppFixture,
3036
- dstFixture: OAppFixture,
3037
- version: bigint,
3038
- nativeFee: bigint,
3039
- zroFee: bigint,
3040
- eventHandler: LzEventHandler
3041
- ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>]> {
3042
- // ===================================open and deploy sml manager =====================================
3043
- const [msglibManager, internalMsgResults_1] = await openAndDeploySmlManager(
3044
- blockchain,
3045
- allStorages,
3046
- srcFixture,
3047
- version
3048
- )
3049
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_1, msglibManager)
3050
-
3051
- // ===================================open and deploy sml connection =====================================
3052
- const [msglibConnection, internalMsgResults_2] = await openAndDeploySmlConnection(
3053
- blockchain,
3054
- allStorages,
3055
- srcFixture,
3056
- dstFixture,
3057
- msglibManager
3058
- )
3059
-
3060
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_2, srcFixture.oApp)
3061
-
3062
- // ===================================configure sml =====================================
3063
-
3064
- const set_sml_config_md = await msglibManager.getNewMdSetSmlManagerConfig({
3065
- nativeFee,
3066
- zroFee,
3067
- })
3068
-
3069
- const set_sml_config_extended_md = await msglibManager.getNewMdExtendedMd({
3070
- md: set_sml_config_md,
3071
- obj: emptyObject,
3072
- forwardingAddress: BigInt(0),
3073
- })
3074
-
3075
- let internalMsgResults: SendMessageResult = await msglibManager.sendInternalMessage(
3076
- srcFixture.owner.getSender(),
3077
- OPCODES.SmlManager_OP_SET_MSGLIB_CONFIG,
3078
- set_sml_config_extended_md,
3079
- { value: protocolSetupGas['Msglib.SET_MSGLIB_CONFIG'] }
3080
- )
3081
-
3082
- // emits 1 event
3083
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, msglibManager)
3084
-
3085
- internalMsgResults = await addMsgLibToController(blockchain, multiSigners, srcFixture, dstFixture, msglibManager)
3086
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3087
-
3088
- return [msglibManager, msglibConnection]
3089
- }
3090
-
3091
- export async function wireFixtureWithSML(
3092
- blockchain: Blockchain,
3093
- allStorages: SandboxContract<TonContractWrapper>,
3094
- multiSigners: SandboxContract<TreasuryContract>[],
3095
- srcFixture: OAppFixture,
3096
- dstFixture: OAppFixture,
3097
- customNativeFee: bigint = toNano('0'),
3098
- customZroFee: bigint = toNano('0.000000050'),
3099
- defaultNativeFee: bigint = toNano('0.000000100'),
3100
- defaultZroFee: bigint = toNano('0'),
3101
- eventHandler: LzEventHandler
3102
- ): Promise<void> {
3103
- // ===================================wire channels=====================================
3104
-
3105
- await wireChannels(blockchain, allStorages, srcFixture, dstFixture, eventHandler)
3106
-
3107
- // ===================================deploy and configure sml custom=====================================
3108
- ;[srcFixture.msglibManagerCustom, srcFixture.msglibConnectionCustom] = await deployConfigAndRegisterSml(
3109
- blockchain,
3110
- multiSigners,
3111
- allStorages,
3112
- srcFixture,
3113
- dstFixture,
3114
- SML_MANAGER_CUSTOM_VERSION,
3115
- customNativeFee,
3116
- customZroFee,
3117
- eventHandler
3118
- )
3119
-
3120
- // ===================================deploy and configure sml default=====================================
3121
- ;[srcFixture.msglibManager, srcFixture.msglibConnection] = await deployConfigAndRegisterSml(
3122
- blockchain,
3123
- multiSigners,
3124
- allStorages,
3125
- srcFixture,
3126
- dstFixture,
3127
- SML_MANAGER_DEFAULT_VERSION,
3128
- defaultNativeFee,
3129
- defaultZroFee,
3130
- eventHandler
3131
- )
3132
-
3133
- // ===================================set default endpoint config=====================================
3134
-
3135
- const internalMsgResults = await setDefaultEndpointConfig(
3136
- blockchain,
3137
- allStorages,
3138
- multiSigners,
3139
- srcFixture.msglibManager,
3140
- srcFixture.msglibManager,
3141
- srcFixture,
3142
- dstFixture
3143
- )
3144
-
3145
- // in SML, the connection is the Msglib
3146
- srcFixture.msglib = srcFixture.msglibConnection
3147
-
3148
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3149
- expect(eventHandler.allFailures.txList).toHaveLength(0)
3150
- }
3151
-
3152
- export async function wireFixturesTogetherWithSML(
3153
- blockchain: Blockchain,
3154
- allStorages: SandboxContract<TonContractWrapper>,
3155
- multiSigners: SandboxContract<TreasuryContract>[],
3156
- srcFixture: OAppFixture,
3157
- dstFixture: OAppFixture,
3158
- customNativeFee: bigint = toNano('0'),
3159
- customZroFee: bigint = toNano('0.000000050'),
3160
- defaultNativeFee: bigint = toNano('0.000000100'),
3161
- defaultZroFee: bigint = toNano('0'),
3162
- eventHandler: LzEventHandler
3163
- ): Promise<void> {
3164
- await wireFixtureWithSML(
3165
- blockchain,
3166
- allStorages,
3167
- multiSigners,
3168
- srcFixture,
3169
- dstFixture,
3170
- customNativeFee,
3171
- customZroFee,
3172
- defaultNativeFee,
3173
- defaultZroFee,
3174
- eventHandler
3175
- )
3176
- await wireFixtureWithSML(
3177
- blockchain,
3178
- allStorages,
3179
- multiSigners,
3180
- dstFixture,
3181
- srcFixture,
3182
- customNativeFee,
3183
- customZroFee,
3184
- defaultNativeFee,
3185
- defaultZroFee,
3186
- eventHandler
3187
- )
3188
- }
3189
- `;
3190
- fs__namespace.default.writeFileSync(path__namespace.default.join(directory, filename), savedCode);
3191
- }
3192
- function generateUlnTestUtils(directory, filename) {
3193
- const savedCode = `import { Address, Cell, TupleItemCell, beginCell, toNano } from '@ton/core'
3194
2864
  import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
3195
- import { FlatTransactionComparable } from '@ton/test-utils'
3196
- import { ethers } from 'ethers'
2865
+ import '@ton/test-utils'
3197
2866
 
3198
2867
  import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
3199
- import DvnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Dvn.compiled.json'
3200
- import DvnFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/DvnFeeLib.compiled.json'
3201
2868
  import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
3202
- import ExecutorArtifact from '@layerzerolabs/layerzero-v2-ton/build/Executor.compiled.json'
3203
- import ExecutorFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/ExecutorFeeLib.compiled.json'
3204
- import PriceFeedCacheArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedCache.compiled.json'
3205
- import PriceFeedFeeLibDefaultArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedFeeLibDefault.compiled.json'
3206
- import ProxyArtifact from '@layerzerolabs/layerzero-v2-ton/build/Proxy.compiled.json'
3207
- import UlnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Uln.compiled.json'
3208
- import UlnConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnConnection.compiled.json'
3209
- import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager.compiled.json'
2869
+ import SmlConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlConnection.compiled.json'
2870
+ import SmlManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlManager.compiled.json'
3210
2871
  import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3211
2872
 
3212
2873
  import {
3213
2874
  OAppFixture,
3214
2875
  OAppFlowGas,
3215
- ProtocolFixture,
3216
- SIGNATURE_BYTE_LENGTH,
3217
2876
  addMsgLibToController,
3218
- createLzPacketFromPacketEncoded,
3219
- createVerifierDictSet,
3220
2877
  emptyObject,
3221
- generateRandomVerifierSet,
3222
2878
  protocolSetupGas,
3223
- publicKeyToHash,
3224
- requireDefined,
3225
2879
  sendInternalMessageAndExpect,
3226
- sendMessageViaMultisigAndExpect,
3227
- serializeAddressList,
3228
2880
  setDefaultEndpointConfig,
3229
2881
  wireChannels,
3230
2882
  } from './auto-utils-common'
3231
- import {
3232
- ExtendedContract,
3233
- LzDict,
3234
- LzEventHandler,
3235
- MdPacketSent,
3236
- OPCODES,
3237
- TonContractWrapper,
3238
- TonObjectUnwrapper,
3239
- } from '../../src'
2883
+ import { LzEventHandler, OPCODES, TonContractWrapper } from '../../src'
3240
2884
 
3241
- const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
2885
+ const SML_MANAGER_DEFAULT_VERSION = BigInt(1)
2886
+ const SML_MANAGER_CUSTOM_VERSION = BigInt(2)
3242
2887
 
3243
- export const TRUE = BigInt(-1)
3244
- export const FALSE = BigInt(0)
3245
- export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3246
- export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3247
- export const ChannelExecutionStatusExecutable = BigInt(2)
2888
+ // ==============================SML INTEGRATION FUNCTIONS==============================
3248
2889
 
3249
- export interface SendUlnConfig {
3250
- workerQuoteGasLimit: bigint
3251
- maxMessageBytes: bigint
3252
- }
2890
+ export async function commitVerificationAndExpectSml(
2891
+ lzPacketCell: Cell,
2892
+ deployer: SandboxContract<TreasuryContract>,
2893
+ eventHandler: LzEventHandler,
2894
+ { endpoint, channel, msglibManager: smlManager, msglibConnection: smlConnection, controller }: OAppFixture,
2895
+ profile?: Profile
2896
+ ): Promise<void> {
2897
+ const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
2898
+ profile,
2899
+ value: OAppFlowGas['Msglib.COMMIT_PACKET'],
2900
+ sender: deployer.getSender(),
2901
+ contract: smlManager,
2902
+ opCode: OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET,
2903
+ md: await smlManager.getNewMdMdAddress({
2904
+ md: lzPacketCell,
2905
+ address: addressToBigInt(endpoint.address),
2906
+ }),
2907
+ expectedTransactions: [
2908
+ {
2909
+ from: deployer.address,
2910
+ to: smlManager.address,
2911
+ op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET),
2912
+ success: true,
2913
+ },
2914
+ {
2915
+ from: smlManager.address,
2916
+ to: smlConnection.address,
2917
+ op: Number(OPCODES.SmlConnection_OP_SML_CONNECTION_COMMIT_PACKET),
2918
+ success: true,
2919
+ },
2920
+ {
2921
+ from: smlConnection.address,
2922
+ to: endpoint.address,
2923
+ op: Number(OPCODES.Endpoint_OP_ENDPOINT_COMMIT_PACKET),
2924
+ success: true,
2925
+ },
2926
+ {
2927
+ from: endpoint.address,
2928
+ to: channel.address,
2929
+ op: Number(OPCODES.Channel_OP_CHANNEL_COMMIT_PACKET),
2930
+ success: true,
2931
+ },
2932
+ // emit event channel::EVENT::MESSAGE_COMMITTED
2933
+ {
2934
+ from: channel.address,
2935
+ to: controller.address,
2936
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
2937
+ success: false, // events are supposed to fail
2938
+ },
2939
+ {
2940
+ from: channel.address,
2941
+ to: smlConnection.address,
2942
+ op: Number(OPCODES.MsglibConnection_OP_MSGLIB_CONNECTION_COMMIT_PACKET_CALLBACK),
2943
+ success: true,
2944
+ },
2945
+ {
2946
+ from: smlConnection.address,
2947
+ to: smlManager.address,
2948
+ op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET_CALLBACK),
2949
+ success: true,
2950
+ },
2951
+ // refund excess ton
2952
+ {
2953
+ from: smlManager.address,
2954
+ to: deployer.address,
2955
+ success: true,
2956
+ },
2957
+ ],
2958
+ })
2959
+
2960
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, smlManager)
2961
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
2962
+ }
2963
+
2964
+ // ===============================HELPER ASSERTS===============================
2965
+
2966
+ export async function openAndDeploySmlManager(
2967
+ blockchain: Blockchain,
2968
+ allStorages: SandboxContract<TonContractWrapper>,
2969
+ fixture: OAppFixture,
2970
+ version: bigint
2971
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2972
+ const smlManager: SandboxContract<TonContractWrapper> = blockchain.openContract(
2973
+ TonContractWrapper.create(
2974
+ cellFromArtifact(SmlManagerArtifact),
2975
+ await allStorages.getNewSmlManager({
2976
+ owner: addressToBigInt(fixture.owner.address),
2977
+ eid: fixture.eid,
2978
+ version,
2979
+ controllerAddress: addressToBigInt(fixture.controller.address),
2980
+ endpointCode: cellFromArtifact(EndpointArtifact),
2981
+ channelCode: cellFromArtifact(ChannelArtifact),
2982
+ smlConnectionCode: cellFromArtifact(SmlConnectionArtifact),
2983
+ })
2984
+ )
2985
+ )
2986
+
2987
+ const internalMsgResults = await sendInternalMessageAndExpect({
2988
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
2989
+ sender: fixture.owner.getSender(),
2990
+ contract: smlManager,
2991
+ expectedTransactions: [
2992
+ {
2993
+ from: fixture.owner.address,
2994
+ to: smlManager.address,
2995
+ success: true,
2996
+ },
2997
+ ],
2998
+ opCode: OPCODES.BaseInterface_OP_INITIALIZE,
2999
+ md: emptyObject,
3000
+ balanceRefill: toNano('1'),
3001
+ })
3002
+
3003
+ return [smlManager, internalMsgResults]
3004
+ }
3005
+
3006
+ export async function openAndDeploySmlConnection(
3007
+ blockchain: Blockchain,
3008
+ allStorages: SandboxContract<TonContractWrapper>,
3009
+ srcFixture: OAppFixture,
3010
+ dstFixture: OAppFixture,
3011
+ smlManager: SandboxContract<TonContractWrapper>
3012
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
3013
+ const smlConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
3014
+ TonContractWrapper.create(
3015
+ cellFromArtifact(SmlConnectionArtifact),
3016
+ await allStorages.getNewSmlConnection({
3017
+ owner: addressToBigInt(smlManager.address),
3018
+ path: srcFixture.path,
3019
+ })
3020
+ )
3021
+ )
3022
+
3023
+ const internalMsgResults = await sendInternalMessageAndExpect({
3024
+ value: toNano('10'),
3025
+ sender: srcFixture.owner.getSender(),
3026
+ contract: srcFixture.oApp,
3027
+ opCode: OPCODES.OP_DeployConnection,
3028
+ md: await allStorages.getNewMdMdAddress({
3029
+ md: await allStorages.getNewMdDeploy({
3030
+ dstEid: dstFixture.eid,
3031
+ dstOApp: addressToBigInt(dstFixture.oApp.address),
3032
+ initialDeposit: toNano('1'),
3033
+ }),
3034
+ address: addressToBigInt(smlManager.address),
3035
+ }),
3036
+ expectedTransactions: [
3037
+ {
3038
+ from: srcFixture.owner.address,
3039
+ to: srcFixture.oApp.address,
3040
+ op: Number(OPCODES.OP_DeployConnection),
3041
+ success: true,
3042
+ },
3043
+ {
3044
+ from: srcFixture.oApp.address,
3045
+ to: smlManager.address,
3046
+ op: Number(OPCODES.MsglibManager_OP_DEPLOY_CONNECTION),
3047
+ success: true,
3048
+ },
3049
+ {
3050
+ from: smlManager.address,
3051
+ to: smlConnection.address,
3052
+ op: Number(OPCODES.BaseInterface_OP_INITIALIZE),
3053
+ deploy: true,
3054
+ success: true,
3055
+ },
3056
+ ],
3057
+ })
3058
+
3059
+ return [smlConnection, internalMsgResults]
3060
+ }
3061
+
3062
+ export async function deployConfigAndRegisterSml(
3063
+ blockchain: Blockchain,
3064
+ multiSigners: SandboxContract<TreasuryContract>[],
3065
+ allStorages: SandboxContract<TonContractWrapper>,
3066
+ srcFixture: OAppFixture,
3067
+ dstFixture: OAppFixture,
3068
+ version: bigint,
3069
+ nativeFee: bigint,
3070
+ zroFee: bigint,
3071
+ eventHandler: LzEventHandler
3072
+ ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>]> {
3073
+ // ===================================open and deploy sml manager =====================================
3074
+ const [msglibManager, internalMsgResults_1] = await openAndDeploySmlManager(
3075
+ blockchain,
3076
+ allStorages,
3077
+ srcFixture,
3078
+ version
3079
+ )
3080
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_1, msglibManager)
3081
+
3082
+ // ===================================open and deploy sml connection =====================================
3083
+ const [msglibConnection, internalMsgResults_2] = await openAndDeploySmlConnection(
3084
+ blockchain,
3085
+ allStorages,
3086
+ srcFixture,
3087
+ dstFixture,
3088
+ msglibManager
3089
+ )
3090
+
3091
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_2, srcFixture.oApp)
3092
+
3093
+ // ===================================configure sml =====================================
3094
+
3095
+ const set_sml_config_md = await msglibManager.getNewMdSetSmlManagerConfig({
3096
+ nativeFee,
3097
+ zroFee,
3098
+ })
3099
+
3100
+ const set_sml_config_extended_md = await msglibManager.getNewMdExtendedMd({
3101
+ md: set_sml_config_md,
3102
+ obj: emptyObject,
3103
+ forwardingAddress: BigInt(0),
3104
+ })
3105
+
3106
+ let internalMsgResults: SendMessageResult = await msglibManager.sendInternalMessage(
3107
+ srcFixture.owner.getSender(),
3108
+ OPCODES.SmlManager_OP_SET_MSGLIB_CONFIG,
3109
+ set_sml_config_extended_md,
3110
+ { value: protocolSetupGas['Msglib.SET_MSGLIB_CONFIG'] }
3111
+ )
3112
+
3113
+ // emits 1 event
3114
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, msglibManager)
3115
+
3116
+ internalMsgResults = await addMsgLibToController(blockchain, multiSigners, srcFixture, dstFixture, msglibManager)
3117
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3118
+
3119
+ return [msglibManager, msglibConnection]
3120
+ }
3121
+
3122
+ export async function wireFixtureWithSML(
3123
+ blockchain: Blockchain,
3124
+ allStorages: SandboxContract<TonContractWrapper>,
3125
+ multiSigners: SandboxContract<TreasuryContract>[],
3126
+ srcFixture: OAppFixture,
3127
+ dstFixture: OAppFixture,
3128
+ customNativeFee: bigint = toNano('0'),
3129
+ customZroFee: bigint = toNano('0.000000050'),
3130
+ defaultNativeFee: bigint = toNano('0.000000100'),
3131
+ defaultZroFee: bigint = toNano('0'),
3132
+ eventHandler: LzEventHandler
3133
+ ): Promise<void> {
3134
+ // ===================================wire channels=====================================
3135
+
3136
+ await wireChannels(blockchain, allStorages, srcFixture, dstFixture, eventHandler)
3137
+
3138
+ // ===================================deploy and configure sml custom=====================================
3139
+ ;[srcFixture.msglibManagerCustom, srcFixture.msglibConnectionCustom] = await deployConfigAndRegisterSml(
3140
+ blockchain,
3141
+ multiSigners,
3142
+ allStorages,
3143
+ srcFixture,
3144
+ dstFixture,
3145
+ SML_MANAGER_CUSTOM_VERSION,
3146
+ customNativeFee,
3147
+ customZroFee,
3148
+ eventHandler
3149
+ )
3150
+
3151
+ // ===================================deploy and configure sml default=====================================
3152
+ ;[srcFixture.msglibManager, srcFixture.msglibConnection] = await deployConfigAndRegisterSml(
3153
+ blockchain,
3154
+ multiSigners,
3155
+ allStorages,
3156
+ srcFixture,
3157
+ dstFixture,
3158
+ SML_MANAGER_DEFAULT_VERSION,
3159
+ defaultNativeFee,
3160
+ defaultZroFee,
3161
+ eventHandler
3162
+ )
3163
+
3164
+ // ===================================set default endpoint config=====================================
3165
+
3166
+ const internalMsgResults = await setDefaultEndpointConfig(
3167
+ blockchain,
3168
+ allStorages,
3169
+ multiSigners,
3170
+ srcFixture.msglibManager,
3171
+ srcFixture.msglibManager,
3172
+ srcFixture,
3173
+ dstFixture
3174
+ )
3175
+
3176
+ // in SML, the connection is the Msglib
3177
+ srcFixture.msglib = new Map()
3178
+ srcFixture.msglib.set(srcFixture.eid, srcFixture.msglibConnection)
3179
+
3180
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3181
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
3182
+ }
3183
+
3184
+ export async function wireFixturesTogetherWithSML(
3185
+ blockchain: Blockchain,
3186
+ allStorages: SandboxContract<TonContractWrapper>,
3187
+ multiSigners: SandboxContract<TreasuryContract>[],
3188
+ srcFixture: OAppFixture,
3189
+ dstFixture: OAppFixture,
3190
+ customNativeFee: bigint = toNano('0'),
3191
+ customZroFee: bigint = toNano('0.000000050'),
3192
+ defaultNativeFee: bigint = toNano('0.000000100'),
3193
+ defaultZroFee: bigint = toNano('0'),
3194
+ eventHandler: LzEventHandler
3195
+ ): Promise<void> {
3196
+ await wireFixtureWithSML(
3197
+ blockchain,
3198
+ allStorages,
3199
+ multiSigners,
3200
+ srcFixture,
3201
+ dstFixture,
3202
+ customNativeFee,
3203
+ customZroFee,
3204
+ defaultNativeFee,
3205
+ defaultZroFee,
3206
+ eventHandler
3207
+ )
3208
+ await wireFixtureWithSML(
3209
+ blockchain,
3210
+ allStorages,
3211
+ multiSigners,
3212
+ dstFixture,
3213
+ srcFixture,
3214
+ customNativeFee,
3215
+ customZroFee,
3216
+ defaultNativeFee,
3217
+ defaultZroFee,
3218
+ eventHandler
3219
+ )
3220
+ }
3221
+ `;
3222
+ fs__namespace.default.writeFileSync(path__namespace.default.join(directory, filename), savedCode);
3223
+ }
3224
+ function generateUlnTestUtils(directory, filename) {
3225
+ const savedCode = `import { Address, Cell, TupleItemCell, beginCell, toNano } from '@ton/core'
3226
+ import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
3227
+ import { FlatTransactionComparable } from '@ton/test-utils'
3228
+ import { ethers } from 'ethers'
3229
+
3230
+ import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
3231
+ import DvnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Dvn.compiled.json'
3232
+ import DvnFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/DvnFeeLib.compiled.json'
3233
+ import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
3234
+ import ExecutorArtifact from '@layerzerolabs/layerzero-v2-ton/build/Executor.compiled.json'
3235
+ import ExecutorFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/ExecutorFeeLib.compiled.json'
3236
+ import PriceFeedCacheArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedCache.compiled.json'
3237
+ import PriceFeedFeeLibDefaultArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedFeeLibDefault.compiled.json'
3238
+ import ProxyArtifact from '@layerzerolabs/layerzero-v2-ton/build/Proxy.compiled.json'
3239
+ import UlnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Uln.compiled.json'
3240
+ import UlnConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnConnection.compiled.json'
3241
+ import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager.compiled.json'
3242
+ import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3243
+
3244
+ import {
3245
+ OAppFixture,
3246
+ OAppFlowGas,
3247
+ ProtocolFixture,
3248
+ SIGNATURE_BYTE_LENGTH,
3249
+ addMsgLibToController,
3250
+ createLzPacketFromPacketEncoded,
3251
+ createVerifierDictSet,
3252
+ emptyObject,
3253
+ generateRandomVerifierSet,
3254
+ protocolSetupGas,
3255
+ publicKeyToHash,
3256
+ requireDefined,
3257
+ sendInternalMessageAndExpect,
3258
+ sendMessageViaMultisigAndExpect,
3259
+ serializeAddressList,
3260
+ setDefaultEndpointConfig,
3261
+ wireChannels,
3262
+ } from './auto-utils-common'
3263
+ import {
3264
+ ExtendedContract,
3265
+ LzDict,
3266
+ LzEventHandler,
3267
+ MdPacketSent,
3268
+ OPCODES,
3269
+ TonContractWrapper,
3270
+ TonObjectUnwrapper,
3271
+ } from '../../src'
3272
+
3273
+ const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
3274
+
3275
+ export const TRUE = BigInt(-1)
3276
+ export const FALSE = BigInt(0)
3277
+ export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3278
+ export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3279
+ export const ChannelExecutionStatusExecutable = BigInt(2)
3280
+
3281
+ export interface SendUlnConfig {
3282
+ workerQuoteGasLimit: bigint
3283
+ maxMessageBytes: bigint
3284
+ }
3253
3285
 
3254
3286
  export interface ReceiveUlnConfig {
3255
3287
  minCommitPacketGas: bigint
@@ -3310,7 +3342,7 @@ export interface ProtocolFixtureULN extends ProtocolFixture {
3310
3342
  receiveDvnFixtures: DvnFixture[]
3311
3343
  receiveDvnFixturesCustom: DvnFixture[]
3312
3344
  executorFixtures: ExecutorFixture
3313
- priceFeedCacheFixture: PricedfeedCacheFixture
3345
+ priceFeedCacheFixtures: Map<bigint, PricedfeedCacheFixture>
3314
3346
  defaultUlnSendConfig: Cell
3315
3347
  defaultUlnReceiveConfig: Cell
3316
3348
  }
@@ -3357,14 +3389,16 @@ export async function commitVerificationAndExpect(
3357
3389
  msglibConnection: ulnConnection,
3358
3390
  controller,
3359
3391
  }: OAppFixture,
3392
+ dstEid: bigint,
3360
3393
  profile?: Profile
3361
3394
  ): Promise<void> {
3362
- requireDefined(uln)
3395
+ const msglib = uln.get(dstEid)
3396
+ requireDefined(msglib)
3363
3397
  const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
3364
3398
  profile,
3365
3399
  value: OAppFlowGas['Msglib.COMMIT_PACKET'],
3366
3400
  sender: deployer.getSender(),
3367
- contract: uln,
3401
+ contract: msglib,
3368
3402
  opCode: OPCODES.Uln_OP_ULN_COMMIT_PACKET,
3369
3403
  md: await ulnManager.getNewMdMdAddress({
3370
3404
  md: lzPacketCell,
@@ -3373,12 +3407,12 @@ export async function commitVerificationAndExpect(
3373
3407
  expectedTransactions: [
3374
3408
  {
3375
3409
  from: deployer.address,
3376
- to: uln.address,
3410
+ to: msglib.address,
3377
3411
  op: Number(OPCODES.Uln_OP_ULN_COMMIT_PACKET),
3378
3412
  success: true,
3379
3413
  },
3380
3414
  {
3381
- from: uln.address,
3415
+ from: msglib.address,
3382
3416
  to: ulnConnection.address,
3383
3417
  op: Number(OPCODES.UlnConnection_OP_ULN_CONNECTION_COMMIT_PACKET),
3384
3418
  success: true,
@@ -3451,7 +3485,8 @@ export async function addDvnWorkers(
3451
3485
  ): Promise<void> {
3452
3486
  requireDefined(sendDvnFixtures)
3453
3487
  requireDefined(receiveDvnFixtures)
3454
- requireDefined(uln)
3488
+ const msglib = uln.get(dstEid)
3489
+ requireDefined(msglib)
3455
3490
  for (const dvnFixture of [...sendDvnFixtures, ...receiveDvnFixtures]) {
3456
3491
  const dvnWorkerCallMd = await allStorages.getNewMdExecuteParams({
3457
3492
  target: addressToBigInt(msglibManager.address),
@@ -3495,13 +3530,13 @@ export async function addDvnWorkers(
3495
3530
  },
3496
3531
  {
3497
3532
  from: msglibManager.address,
3498
- to: uln.address,
3533
+ to: msglib.address,
3499
3534
  success: true,
3500
3535
  op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
3501
3536
  },
3502
3537
  // emit event Uln::EVENT::ULN_WORKER_REGISTERED
3503
3538
  {
3504
- from: uln.address,
3539
+ from: msglib.address,
3505
3540
  to: msglibManager.address,
3506
3541
  op: Number(OPCODES.BaseInterface_OP_EVENT),
3507
3542
  success: false, // events are supposed to fail
@@ -3533,7 +3568,7 @@ export async function openAndDeployUln(
3533
3568
  multiSigners: SandboxContract<TreasuryContract>[],
3534
3569
  deployMd: Cell,
3535
3570
  srcFixture: OAppFixture,
3536
- dstFixture: OAppFixture
3571
+ dstEid: bigint
3537
3572
  ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
3538
3573
  const uln: SandboxContract<TonContractWrapper> = blockchain.openContract(
3539
3574
  TonContractWrapper.create(
@@ -3541,7 +3576,7 @@ export async function openAndDeployUln(
3541
3576
  await allStorages.getNewUln({
3542
3577
  owner: addressToBigInt(srcFixture.msglibManager.address),
3543
3578
  eid: srcFixture.eid,
3544
- dstEid: dstFixture.eid,
3579
+ dstEid,
3545
3580
  })
3546
3581
  )
3547
3582
  )
@@ -3580,6 +3615,13 @@ export async function openAndDeployUln(
3580
3615
  ],
3581
3616
  })
3582
3617
 
3618
+ requireDefined(uln)
3619
+ // Initialize Map if it doesn't exist , otherwise preserve existing entries
3620
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
3621
+ if (srcFixture.msglib == undefined) {
3622
+ srcFixture.msglib = new Map()
3623
+ }
3624
+ srcFixture.msglib.set(dstEid, uln)
3583
3625
  return [uln, internalMsgResults]
3584
3626
  }
3585
3627
 
@@ -3635,13 +3677,15 @@ export async function openAndDeployUlnConnection(
3635
3677
  srcFixture: OAppFixtureULN,
3636
3678
  dstFixture: OAppFixtureULN
3637
3679
  ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
3680
+ const msglib = srcFixture.msglib.get(dstFixture.eid)
3681
+ requireDefined(msglib)
3638
3682
  const ulnConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
3639
3683
  TonContractWrapper.create(
3640
3684
  cellFromArtifact(UlnConnectionArtifact),
3641
3685
  await allStorages.getNewUlnConnection({
3642
3686
  owner: addressToBigInt(srcFixture.msglibManager.address),
3643
3687
  path: srcFixture.path,
3644
- ulnAddress: addressToBigInt(srcFixture.msglib.address),
3688
+ ulnAddress: addressToBigInt(msglib.address),
3645
3689
  })
3646
3690
  )
3647
3691
  )
@@ -3733,7 +3777,7 @@ export async function openAndDeployProxyWorker(
3733
3777
  TonContractWrapper.create(
3734
3778
  cellFromArtifact(ProxyArtifact),
3735
3779
  await allStorages.getNewProxy({
3736
- admins: serializeAddressList([worker]),
3780
+ admins: serializeAddressList([srcFixture.owner, worker]),
3737
3781
  version: 0n,
3738
3782
  })
3739
3783
  )
@@ -3826,7 +3870,7 @@ export async function openAndDeployPriceFeedCacheAndProxy(
3826
3870
  blockchain: Blockchain,
3827
3871
  allStorages: SandboxContract<TonContractWrapper>,
3828
3872
  srcFixture: OAppFixture,
3829
- dstFixture: OAppFixture,
3873
+ dstEid: bigint,
3830
3874
  adminSet: SandboxContract<TreasuryContract>[]
3831
3875
  ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>, SendMessageResult]> {
3832
3876
  // todo: fix this with real values
@@ -3837,7 +3881,7 @@ export async function openAndDeployPriceFeedCacheAndProxy(
3837
3881
  // owner: addressToBigInt(srcFixture.multisig.address),
3838
3882
  admins: serializeAddressList(adminSet),
3839
3883
  version: 0n,
3840
- dstEid: dstFixture.eid,
3884
+ dstEid,
3841
3885
  priceFeedFeeLib: await allStorages.getNewPriceFeedFeelib({
3842
3886
  priceRatio: BigInt(1851851),
3843
3887
  gasPriceInRemoteUnit: BigInt(36000000000),
@@ -3995,14 +4039,19 @@ export async function deployConfigAndRegisterUln(
3995
4039
  blockchain,
3996
4040
  allStorages,
3997
4041
  srcFixture,
3998
- dstFixture,
4042
+ dstFixture.eid,
3999
4043
  priceFeedCacheAdmins
4000
4044
  )
4001
- srcFixture.priceFeedCacheFixture = {
4002
- priceFeedCache,
4003
- proxy: priceFeedCacheProxy,
4004
- admins: priceFeedCacheAdmins,
4005
- }
4045
+ srcFixture.priceFeedCacheFixtures = new Map([
4046
+ [
4047
+ dstFixture.eid,
4048
+ {
4049
+ priceFeedCache,
4050
+ proxy: priceFeedCacheProxy,
4051
+ admins: priceFeedCacheAdmins,
4052
+ },
4053
+ ],
4054
+ ])
4006
4055
  await eventHandler.addCurrentEventsToAllEvents(priceFeedCacheMsgResults, priceFeedCache)
4007
4056
 
4008
4057
  // ===================================registerUlnWorkerInfo - dvnFeeLib=======================================
@@ -4057,21 +4106,329 @@ export async function deployConfigAndRegisterUln(
4057
4106
  }),
4058
4107
  }),
4059
4108
  srcFixture,
4060
- dstFixture
4109
+ dstFixture.eid
4061
4110
  )
4062
4111
  requireDefined(uln)
4063
- srcFixture.msglib = uln
4064
- await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, srcFixture.msglib)
4112
+ // Initialize Map if it doesn't exist, otherwise preserve existing entries
4113
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
4114
+ if (srcFixture.msglib === undefined) {
4115
+ srcFixture.msglib = new Map()
4116
+ }
4117
+ srcFixture.msglib.set(dstFixture.eid, uln)
4118
+ await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, uln)
4065
4119
 
4066
4120
  // ===================================addUlnWorker - dvn =======================================
4067
4121
 
4122
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstFixture.eid)
4123
+ requireDefined(priceFeedCacheFixture)
4068
4124
  await addDvnWorkers(
4069
4125
  allStorages,
4070
4126
  srcFixture,
4071
4127
  srcFixture.sendDvnFixtures,
4072
4128
  srcFixture.receiveDvnFixtures,
4073
4129
  dstFixture.eid,
4074
- priceFeedCacheProxy.address,
4130
+ priceFeedCacheFixture.proxy.address,
4131
+ eventHandler
4132
+ )
4133
+
4134
+ // ===================================addUlnWorker - executor =======================================
4135
+
4136
+ const executorWorkerCallMd = await allStorages.getNewMdExecuteParams({
4137
+ target: addressToBigInt(srcFixture.msglibManager.address),
4138
+ callData: await allStorages.getNewUlnWorkerFeelibInfo({
4139
+ workerAddress: addressToBigInt(executor.address),
4140
+ workerFeelibBytecode: cellFromArtifact(ExecutorFeelibArtifact),
4141
+ workerFeelibStorage: await allStorages.getNewExecutorFeelib({
4142
+ lzReceiveBaseGas: BigInt(0),
4143
+ multiplierBps: BigInt(0),
4144
+ floorMarginUSD: BigInt(0),
4145
+ nativeCap: BigInt(0),
4146
+ lzComposeBaseGas: BigInt(0),
4147
+ }),
4148
+ friendWorkerAddress: addressToBigInt(priceFeedCacheProxy.address),
4149
+ dstEid: dstFixture.eid,
4150
+ rentBalance: toNano('260'),
4151
+ isAdmin: BigInt(0),
4152
+ }),
4153
+ expiration: BigInt(0),
4154
+ opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4155
+ forwardingAddress: 0n,
4156
+ })
4157
+ const msglib = srcFixture.msglib.get(dstFixture.eid)
4158
+ requireDefined(msglib)
4159
+
4160
+ internalMsgResults = await addUlnWorker(srcFixture.executorFixtures.admins[0], executor, executorWorkerCallMd, [
4161
+ {
4162
+ from: srcFixture.executorFixtures.admins[0].address,
4163
+ to: executor.address,
4164
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4165
+ success: true,
4166
+ },
4167
+ {
4168
+ from: executor.address,
4169
+ to: srcFixture.executorFixtures.proxy.address,
4170
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4171
+ success: true,
4172
+ },
4173
+ {
4174
+ from: srcFixture.executorFixtures.proxy.address,
4175
+ to: srcFixture.msglibManager.address,
4176
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4177
+ success: true,
4178
+ },
4179
+ {
4180
+ from: srcFixture.msglibManager.address,
4181
+ to: msglib.address,
4182
+ success: true,
4183
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4184
+ },
4185
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4186
+ {
4187
+ from: msglib.address,
4188
+ to: srcFixture.msglibManager.address,
4189
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4190
+ success: false, // events are supposed to fail
4191
+ },
4192
+ ])
4193
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4194
+
4195
+ // ===================================addUlnWorker - priceFeedCache =======================================
4196
+
4197
+ const priceFeedCacheWorkerCallMd = await allStorages.getNewMdExecuteParams({
4198
+ target: addressToBigInt(srcFixture.msglibManager.address),
4199
+ callData: await allStorages.getNewUlnWorkerFeelibInfo({
4200
+ workerAddress: addressToBigInt(priceFeedCacheProxy.address),
4201
+ workerFeelibBytecode: cellFromArtifact(PriceFeedFeeLibDefaultArtifact),
4202
+ workerFeelibStorage: await allStorages.getNewPriceFeedFeelib({
4203
+ // priceRatio: BigInt(0),
4204
+ // gasPriceInUnit: BigInt(0),
4205
+ // gasPerByte: BigInt(0),
4206
+ // nativePriceUsd: BigInt(0),
4207
+ priceRatio: BigInt(1851851),
4208
+ gasPriceInRemoteUnit: BigInt(36000000000),
4209
+ gasPerByte: BigInt(1000),
4210
+ nativePriceUsd: BigInt(1),
4211
+ arbitrumExtension: beginCell().endCell(),
4212
+ optimismExtension: beginCell().endCell(),
4213
+ }),
4214
+ friendWorkerAddress: BigInt(0),
4215
+ dstEid: dstFixture.eid,
4216
+ rentBalance: toNano('260'),
4217
+ isAdmin: BigInt(0),
4218
+ }),
4219
+ expiration: BigInt(0),
4220
+ opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4221
+ forwardingAddress: 0n,
4222
+ })
4223
+
4224
+ internalMsgResults = await addUlnWorker(
4225
+ priceFeedCacheFixture.admins[0],
4226
+ priceFeedCache,
4227
+ priceFeedCacheWorkerCallMd,
4228
+ [
4229
+ {
4230
+ from: priceFeedCacheFixture.admins[0].address,
4231
+ to: priceFeedCache.address,
4232
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4233
+ success: true,
4234
+ },
4235
+ {
4236
+ from: priceFeedCache.address,
4237
+ to: priceFeedCacheProxy.address,
4238
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4239
+ success: true,
4240
+ },
4241
+ {
4242
+ from: priceFeedCacheProxy.address,
4243
+ to: srcFixture.msglibManager.address,
4244
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4245
+ success: true,
4246
+ },
4247
+ {
4248
+ from: srcFixture.msglibManager.address,
4249
+ to: msglib.address,
4250
+ success: true,
4251
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4252
+ },
4253
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4254
+ {
4255
+ from: msglib.address,
4256
+ to: srcFixture.msglibManager.address,
4257
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4258
+ success: false, // events are supposed to fail
4259
+ },
4260
+ ]
4261
+ )
4262
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4263
+
4264
+ // ===================================configure default send and receive config =====================================
4265
+
4266
+ // requireDefined(srcFixture.dvnFixtures)
4267
+ // const [reqDvns, optDvns, optThreshold] = getDvnArrayFromDvnFixtures(srcFixture.dvnFixtures, dvnConfig)
4268
+ requireDefined(srcFixture.sendDvnFixtures)
4269
+ const [reqSendDvns, optSendDvns] = getDvnArrayFromDvnFixtures(srcFixture.sendDvnFixtures, dvnConfigs.send)
4270
+
4271
+ const ulnSendConfig = await allStorages.getNewUlnSendConfig({
4272
+ workerQuoteGasLimit: ulnConfigs.send.workerQuoteGasLimit,
4273
+ maxMessageBytes: ulnConfigs.send.maxMessageBytes,
4274
+ executorNull: BigInt(0),
4275
+ executor: addressToBigInt(executorProxy.address),
4276
+ requiredDVNsNull: BigInt(0),
4277
+ requiredDVNs: serializeDvns(reqSendDvns),
4278
+ optionalDVNsNull: BigInt(0),
4279
+ optionalDVNs: serializeDvns(optSendDvns),
4280
+ confirmationsNull: BigInt(0),
4281
+ confirmations: BigInt(1),
4282
+ })
4283
+
4284
+ srcFixture.defaultUlnSendConfig = ulnSendConfig
4285
+
4286
+ await sendMessageViaMultisigAndExpect({
4287
+ blockchain,
4288
+ multiSigContract: srcFixture.multisig,
4289
+ messageBody: allStorages.buildRequest(
4290
+ OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG,
4291
+ await allStorages.getNewMdMdEid({
4292
+ md: ulnSendConfig,
4293
+ eid: dstFixture.eid,
4294
+ }),
4295
+ { value: toNano('10') },
4296
+ toNano('0.1')
4297
+ ).body!,
4298
+ signers: multiSigners,
4299
+ targetContract: srcFixture.msglibManager,
4300
+ deploy: false,
4301
+ expectedTransactions: [
4302
+ {
4303
+ from: srcFixture.multisig.address,
4304
+ to: srcFixture.msglibManager.address,
4305
+ success: true,
4306
+ op: Number(OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4307
+ },
4308
+ {
4309
+ from: srcFixture.msglibManager.address,
4310
+ to: msglib.address,
4311
+ success: true,
4312
+ op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4313
+ },
4314
+ ],
4315
+ })
4316
+
4317
+ requireDefined(srcFixture.receiveDvnFixtures)
4318
+ const [reqReceiveDvns, optReceiveDvns, optReceiveQuorum] = getDvnArrayFromDvnFixtures(
4319
+ srcFixture.receiveDvnFixtures,
4320
+ dvnConfigs.receive
4321
+ )
4322
+
4323
+ const ulnReceiveConfig = await allStorages.getNewUlnReceiveConfig({
4324
+ minCommitPacketGasNull: BigInt(0),
4325
+ minCommitPacketGas: ulnConfigs.receive.minCommitPacketGas,
4326
+ confirmationsNull: BigInt(0),
4327
+ confirmations: BigInt(1),
4328
+ requiredDVNsNull: BigInt(0),
4329
+ requiredDVNs: serializeDvns(reqReceiveDvns),
4330
+ optionalDVNsNull: BigInt(0),
4331
+ optionalDVNs: serializeDvns(optReceiveDvns),
4332
+ optionalDVNThreshold: BigInt(optReceiveQuorum),
4333
+ })
4334
+
4335
+ srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4336
+
4337
+ await sendMessageViaMultisigAndExpect({
4338
+ blockchain,
4339
+ multiSigContract: srcFixture.multisig,
4340
+ messageBody: allStorages.buildRequest(
4341
+ OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG,
4342
+ await allStorages.getNewMdMdEid({
4343
+ md: ulnReceiveConfig,
4344
+ eid: dstFixture.eid,
4345
+ }),
4346
+ { value: toNano('10') },
4347
+ toNano('0.1')
4348
+ ).body!,
4349
+ signers: multiSigners,
4350
+ targetContract: srcFixture.msglibManager,
4351
+ deploy: false,
4352
+ expectedTransactions: [
4353
+ {
4354
+ from: srcFixture.multisig.address,
4355
+ to: srcFixture.msglibManager.address,
4356
+ success: true,
4357
+ op: Number(OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4358
+ },
4359
+ {
4360
+ from: srcFixture.msglibManager.address,
4361
+ to: msglib.address,
4362
+ success: true,
4363
+ op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4364
+ },
4365
+ ],
4366
+ })
4367
+
4368
+ return msglibManager
4369
+ }
4370
+
4371
+ export async function deployAndRegisterNewUln(
4372
+ blockchain: Blockchain,
4373
+ multiSigners: SandboxContract<TreasuryContract>[],
4374
+ allStorages: SandboxContract<TonContractWrapper>,
4375
+ srcFixture: OAppFixtureULN,
4376
+ priceFeedFeeLib: Cell,
4377
+ dstEid: bigint,
4378
+ dstOApp: SandboxContract<TonContractWrapper>,
4379
+ existingDstEid: bigint,
4380
+ eventHandler: LzEventHandler
4381
+ ): Promise<void> {
4382
+ // ===================================open and deploy PriceFeedCache & Proxy=======================
4383
+
4384
+ const priceFeedCacheAdmins = [srcFixture.owner]
4385
+ const existingPriceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(existingDstEid)
4386
+ requireDefined(existingPriceFeedCacheFixture)
4387
+ const currentAdminsWorkers = [existingPriceFeedCacheFixture.priceFeedCache]
4388
+
4389
+ await registerAdditionalPriceFeedCache(
4390
+ blockchain,
4391
+ allStorages,
4392
+ srcFixture,
4393
+ dstEid,
4394
+ priceFeedCacheAdmins,
4395
+ existingPriceFeedCacheFixture.proxy,
4396
+ priceFeedFeeLib,
4397
+ currentAdminsWorkers
4398
+ )
4399
+
4400
+ // ===================================open and deploy uln =============================================
4401
+
4402
+ const [uln, ulnMsgResults] = await openAndDeployUln(
4403
+ blockchain,
4404
+ allStorages,
4405
+ multiSigners,
4406
+ await allStorages.getNewMdDeployNewWithExtraInfo({
4407
+ initialDeposit: toNano('2'),
4408
+ dstEid,
4409
+ dstOApp: addressToBigInt(dstOApp.address),
4410
+ extraInfo: await allStorages.getNewMdInitUln({
4411
+ connectionCode: beginCell().endCell(),
4412
+ treasuryFeeBps: 100n, // 100bps todo: turn this into a constant
4413
+ }),
4414
+ }),
4415
+ srcFixture,
4416
+ dstEid
4417
+ )
4418
+ srcFixture.msglib.set(dstEid, uln)
4419
+ await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, uln)
4420
+
4421
+ // ===================================addUlnWorker - dvn =======================================
4422
+
4423
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstEid)
4424
+ requireDefined(priceFeedCacheFixture)
4425
+ await addDvnWorkers(
4426
+ allStorages,
4427
+ srcFixture,
4428
+ srcFixture.sendDvnFixtures,
4429
+ srcFixture.receiveDvnFixtures,
4430
+ dstEid,
4431
+ priceFeedCacheFixture.proxy.address,
4075
4432
  eventHandler
4076
4433
  )
4077
4434
 
@@ -4080,7 +4437,7 @@ export async function deployConfigAndRegisterUln(
4080
4437
  const executorWorkerCallMd = await allStorages.getNewMdExecuteParams({
4081
4438
  target: addressToBigInt(srcFixture.msglibManager.address),
4082
4439
  callData: await allStorages.getNewUlnWorkerFeelibInfo({
4083
- workerAddress: addressToBigInt(executor.address),
4440
+ workerAddress: addressToBigInt(srcFixture.executorFixtures.executor.address),
4084
4441
  workerFeelibBytecode: cellFromArtifact(ExecutorFeelibArtifact),
4085
4442
  workerFeelibStorage: await allStorages.getNewExecutorFeelib({
4086
4443
  lzReceiveBaseGas: BigInt(0),
@@ -4089,8 +4446,8 @@ export async function deployConfigAndRegisterUln(
4089
4446
  nativeCap: BigInt(0),
4090
4447
  lzComposeBaseGas: BigInt(0),
4091
4448
  }),
4092
- friendWorkerAddress: addressToBigInt(priceFeedCacheProxy.address),
4093
- dstEid: dstFixture.eid,
4449
+ friendWorkerAddress: addressToBigInt(existingPriceFeedCacheFixture.proxy.address),
4450
+ dstEid: dstEid,
4094
4451
  rentBalance: toNano('260'),
4095
4452
  isAdmin: BigInt(0),
4096
4453
  }),
@@ -4098,40 +4455,47 @@ export async function deployConfigAndRegisterUln(
4098
4455
  opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4099
4456
  forwardingAddress: 0n,
4100
4457
  })
4458
+ const msglib = srcFixture.msglib.get(dstEid)
4459
+ requireDefined(msglib)
4101
4460
 
4102
- internalMsgResults = await addUlnWorker(srcFixture.executorFixtures.admins[0], executor, executorWorkerCallMd, [
4103
- {
4104
- from: srcFixture.executorFixtures.admins[0].address,
4105
- to: executor.address,
4106
- op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4107
- success: true,
4108
- },
4109
- {
4110
- from: executor.address,
4111
- to: srcFixture.executorFixtures.proxy.address,
4112
- op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4113
- success: true,
4114
- },
4115
- {
4116
- from: srcFixture.executorFixtures.proxy.address,
4117
- to: srcFixture.msglibManager.address,
4118
- op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4119
- success: true,
4120
- },
4121
- {
4122
- from: srcFixture.msglibManager.address,
4123
- to: srcFixture.msglib.address,
4124
- success: true,
4125
- op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4126
- },
4127
- // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4128
- {
4129
- from: srcFixture.msglib.address,
4130
- to: srcFixture.msglibManager.address,
4131
- op: Number(OPCODES.BaseInterface_OP_EVENT),
4132
- success: false, // events are supposed to fail
4133
- },
4134
- ])
4461
+ let internalMsgResults = await addUlnWorker(
4462
+ srcFixture.executorFixtures.admins[0],
4463
+ srcFixture.executorFixtures.executor,
4464
+ executorWorkerCallMd,
4465
+ [
4466
+ {
4467
+ from: srcFixture.executorFixtures.admins[0].address,
4468
+ to: srcFixture.executorFixtures.executor.address,
4469
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4470
+ success: true,
4471
+ },
4472
+ {
4473
+ from: srcFixture.executorFixtures.executor.address,
4474
+ to: srcFixture.executorFixtures.proxy.address,
4475
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4476
+ success: true,
4477
+ },
4478
+ {
4479
+ from: srcFixture.executorFixtures.proxy.address,
4480
+ to: srcFixture.msglibManager.address,
4481
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4482
+ success: true,
4483
+ },
4484
+ {
4485
+ from: srcFixture.msglibManager.address,
4486
+ to: msglib.address,
4487
+ success: true,
4488
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4489
+ },
4490
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4491
+ {
4492
+ from: msglib.address,
4493
+ to: srcFixture.msglibManager.address,
4494
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4495
+ success: false, // events are supposed to fail
4496
+ },
4497
+ ]
4498
+ )
4135
4499
  await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4136
4500
 
4137
4501
  // ===================================addUlnWorker - priceFeedCache =======================================
@@ -4139,7 +4503,7 @@ export async function deployConfigAndRegisterUln(
4139
4503
  const priceFeedCacheWorkerCallMd = await allStorages.getNewMdExecuteParams({
4140
4504
  target: addressToBigInt(srcFixture.msglibManager.address),
4141
4505
  callData: await allStorages.getNewUlnWorkerFeelibInfo({
4142
- workerAddress: addressToBigInt(priceFeedCacheProxy.address),
4506
+ workerAddress: addressToBigInt(existingPriceFeedCacheFixture.proxy.address),
4143
4507
  workerFeelibBytecode: cellFromArtifact(PriceFeedFeeLibDefaultArtifact),
4144
4508
  workerFeelibStorage: await allStorages.getNewPriceFeedFeelib({
4145
4509
  // priceRatio: BigInt(0),
@@ -4154,7 +4518,7 @@ export async function deployConfigAndRegisterUln(
4154
4518
  optimismExtension: beginCell().endCell(),
4155
4519
  }),
4156
4520
  friendWorkerAddress: BigInt(0),
4157
- dstEid: dstFixture.eid,
4521
+ dstEid,
4158
4522
  rentBalance: toNano('260'),
4159
4523
  isAdmin: BigInt(0),
4160
4524
  }),
@@ -4164,37 +4528,37 @@ export async function deployConfigAndRegisterUln(
4164
4528
  })
4165
4529
 
4166
4530
  internalMsgResults = await addUlnWorker(
4167
- srcFixture.priceFeedCacheFixture.admins[0],
4168
- priceFeedCache,
4531
+ priceFeedCacheFixture.admins[0],
4532
+ priceFeedCacheFixture.priceFeedCache,
4169
4533
  priceFeedCacheWorkerCallMd,
4170
4534
  [
4171
4535
  {
4172
- from: srcFixture.priceFeedCacheFixture.admins[0].address,
4173
- to: priceFeedCache.address,
4536
+ from: priceFeedCacheFixture.admins[0].address,
4537
+ to: priceFeedCacheFixture.priceFeedCache.address,
4174
4538
  op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4175
4539
  success: true,
4176
4540
  },
4177
4541
  {
4178
- from: priceFeedCache.address,
4179
- to: priceFeedCacheProxy.address,
4542
+ from: priceFeedCacheFixture.priceFeedCache.address,
4543
+ to: priceFeedCacheFixture.proxy.address,
4180
4544
  op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4181
4545
  success: true,
4182
4546
  },
4183
4547
  {
4184
- from: priceFeedCacheProxy.address,
4548
+ from: priceFeedCacheFixture.proxy.address,
4185
4549
  to: srcFixture.msglibManager.address,
4186
4550
  op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4187
4551
  success: true,
4188
4552
  },
4189
4553
  {
4190
4554
  from: srcFixture.msglibManager.address,
4191
- to: srcFixture.msglib.address,
4555
+ to: msglib.address,
4192
4556
  success: true,
4193
4557
  op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4194
4558
  },
4195
4559
  // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4196
4560
  {
4197
- from: srcFixture.msglib.address,
4561
+ from: msglib.address,
4198
4562
  to: srcFixture.msglibManager.address,
4199
4563
  op: Number(OPCODES.BaseInterface_OP_EVENT),
4200
4564
  success: false, // events are supposed to fail
@@ -4205,34 +4569,14 @@ export async function deployConfigAndRegisterUln(
4205
4569
 
4206
4570
  // ===================================configure default send and receive config =====================================
4207
4571
 
4208
- // requireDefined(srcFixture.dvnFixtures)
4209
- // const [reqDvns, optDvns, optThreshold] = getDvnArrayFromDvnFixtures(srcFixture.dvnFixtures, dvnConfig)
4210
- requireDefined(srcFixture.sendDvnFixtures)
4211
- const [reqSendDvns, optSendDvns] = getDvnArrayFromDvnFixtures(srcFixture.sendDvnFixtures, dvnConfigs.send)
4212
-
4213
- const ulnSendConfig = await allStorages.getNewUlnSendConfig({
4214
- workerQuoteGasLimit: ulnConfigs.send.workerQuoteGasLimit,
4215
- maxMessageBytes: ulnConfigs.send.maxMessageBytes,
4216
- executorNull: BigInt(0),
4217
- executor: addressToBigInt(executorProxy.address),
4218
- requiredDVNsNull: BigInt(0),
4219
- requiredDVNs: serializeDvns(reqSendDvns),
4220
- optionalDVNsNull: BigInt(0),
4221
- optionalDVNs: serializeDvns(optSendDvns),
4222
- confirmationsNull: BigInt(0),
4223
- confirmations: BigInt(1),
4224
- })
4225
-
4226
- srcFixture.defaultUlnSendConfig = ulnSendConfig
4227
-
4228
4572
  await sendMessageViaMultisigAndExpect({
4229
4573
  blockchain,
4230
4574
  multiSigContract: srcFixture.multisig,
4231
4575
  messageBody: allStorages.buildRequest(
4232
4576
  OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG,
4233
4577
  await allStorages.getNewMdMdEid({
4234
- md: ulnSendConfig,
4235
- eid: dstFixture.eid,
4578
+ md: srcFixture.defaultUlnSendConfig,
4579
+ eid: dstEid,
4236
4580
  }),
4237
4581
  { value: toNano('10') },
4238
4582
  toNano('0.1')
@@ -4249,41 +4593,21 @@ export async function deployConfigAndRegisterUln(
4249
4593
  },
4250
4594
  {
4251
4595
  from: srcFixture.msglibManager.address,
4252
- to: srcFixture.msglib.address,
4596
+ to: msglib.address,
4253
4597
  success: true,
4254
4598
  op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4255
4599
  },
4256
4600
  ],
4257
4601
  })
4258
4602
 
4259
- requireDefined(srcFixture.receiveDvnFixtures)
4260
- const [reqReceiveDvns, optReceiveDvns, optReceiveQuorum] = getDvnArrayFromDvnFixtures(
4261
- srcFixture.receiveDvnFixtures,
4262
- dvnConfigs.receive
4263
- )
4264
-
4265
- const ulnReceiveConfig = await allStorages.getNewUlnReceiveConfig({
4266
- minCommitPacketGasNull: BigInt(0),
4267
- minCommitPacketGas: ulnConfigs.receive.minCommitPacketGas,
4268
- confirmationsNull: BigInt(0),
4269
- confirmations: BigInt(1),
4270
- requiredDVNsNull: BigInt(0),
4271
- requiredDVNs: serializeDvns(reqReceiveDvns),
4272
- optionalDVNsNull: BigInt(0),
4273
- optionalDVNs: serializeDvns(optReceiveDvns),
4274
- optionalDVNThreshold: BigInt(optReceiveQuorum),
4275
- })
4276
-
4277
- srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4278
-
4279
4603
  await sendMessageViaMultisigAndExpect({
4280
4604
  blockchain,
4281
4605
  multiSigContract: srcFixture.multisig,
4282
4606
  messageBody: allStorages.buildRequest(
4283
4607
  OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG,
4284
4608
  await allStorages.getNewMdMdEid({
4285
- md: ulnReceiveConfig,
4286
- eid: dstFixture.eid,
4609
+ md: srcFixture.defaultUlnReceiveConfig,
4610
+ eid: dstEid,
4287
4611
  }),
4288
4612
  { value: toNano('10') },
4289
4613
  toNano('0.1')
@@ -4300,14 +4624,12 @@ export async function deployConfigAndRegisterUln(
4300
4624
  },
4301
4625
  {
4302
4626
  from: srcFixture.msglibManager.address,
4303
- to: srcFixture.msglib.address,
4627
+ to: msglib.address,
4304
4628
  success: true,
4305
4629
  op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4306
4630
  },
4307
4631
  ],
4308
4632
  })
4309
-
4310
- return msglibManager
4311
4633
  }
4312
4634
 
4313
4635
  export async function wireFixtureWithUln(
@@ -4414,13 +4736,15 @@ export async function wireFixtureWithUln(
4414
4736
 
4415
4737
  // ===================================addUlnWorker - dvn =======================================
4416
4738
 
4739
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstFixture.eid)
4740
+ requireDefined(priceFeedCacheFixture)
4417
4741
  await addDvnWorkers(
4418
4742
  allStorages,
4419
4743
  srcFixture,
4420
4744
  srcFixture.sendDvnFixturesCustom,
4421
4745
  srcFixture.receiveDvnFixturesCustom,
4422
4746
  dstFixture.eid,
4423
- srcFixture.priceFeedCacheFixture.proxy.address,
4747
+ priceFeedCacheFixture.proxy.address,
4424
4748
  eventHandler
4425
4749
  )
4426
4750
 
@@ -4881,7 +5205,7 @@ export async function callVerifyOnDvn({
4881
5205
  export async function ulnVerifyAndExpect(
4882
5206
  allStorages: SandboxContract<TonContractWrapper>,
4883
5207
  mdPacketSent: MdPacketSent,
4884
- { msglib: uln }: OAppFixtureULN,
5208
+ msglib: SandboxContract<TonContractWrapper>,
4885
5209
  receiveDvnFixtures: DvnFixture[],
4886
5210
  msglibManager: SandboxContract<TonContractWrapper>,
4887
5211
  msglibConnection: SandboxContract<TonContractWrapper>,
@@ -4889,12 +5213,9 @@ export async function ulnVerifyAndExpect(
4889
5213
  confirmations = 1n,
4890
5214
  profile?: Profile
4891
5215
  ): Promise<Cell> {
4892
- requireDefined(uln)
4893
-
4894
5216
  const oneDayFromNow = BigInt(Math.floor(Date.now() / 1000) + 86400)
4895
5217
 
4896
5218
  const lzPacket = await createLzPacketFromPacketEncoded(mdPacketSent.packetEncoded, allStorages)
4897
-
4898
5219
  for (const { dvn, proxy, admins, verifiers } of receiveDvnFixtures) {
4899
5220
  const requestMd = await allStorages.getNewMdExecuteParams({
4900
5221
  target: addressToBigInt(dvn.address),
@@ -4908,7 +5229,7 @@ export async function ulnVerifyAndExpect(
4908
5229
  }),
4909
5230
  expiration: oneDayFromNow,
4910
5231
  opcode: OPCODES.Uln_OP_ULN_VERIFY,
4911
- forwardingAddress: addressToBigInt(uln.address),
5232
+ forwardingAddress: addressToBigInt(msglib.address),
4912
5233
  })
4913
5234
 
4914
5235
  const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
@@ -4936,12 +5257,12 @@ export async function ulnVerifyAndExpect(
4936
5257
  },
4937
5258
  {
4938
5259
  from: proxy.address,
4939
- to: uln.address,
5260
+ to: msglib.address,
4940
5261
  op: Number(OPCODES.Uln_OP_ULN_VERIFY),
4941
5262
  success: true,
4942
5263
  },
4943
5264
  {
4944
- from: uln.address,
5265
+ from: msglib.address,
4945
5266
  to: msglibConnection.address,
4946
5267
  op: Number(OPCODES.UlnConnection_OP_ULN_CONNECTION_VERIFY),
4947
5268
  success: true,
@@ -4967,6 +5288,167 @@ export async function ulnVerifyAndExpect(
4967
5288
 
4968
5289
  return lzPacket
4969
5290
  }
5291
+
5292
+ export async function registerAdditionalPriceFeedCache(
5293
+ blockchain: Blockchain,
5294
+ allStorages: SandboxContract<TonContractWrapper>,
5295
+ srcFixture: OAppFixtureULN,
5296
+ dstEid: bigint,
5297
+ adminSet: SandboxContract<TreasuryContract>[],
5298
+ existingProxy: SandboxContract<TonContractWrapper>,
5299
+ priceFeedFeeLib: Cell,
5300
+ currentAdminsWorkers: SandboxContract<TonContractWrapper>[]
5301
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
5302
+ // Create new price feed cache worker
5303
+ const priceFeedCache = blockchain.openContract(
5304
+ TonContractWrapper.create(
5305
+ cellFromArtifact(PriceFeedCacheArtifact),
5306
+ await allStorages.getNewPriceFeedCache({
5307
+ admins: serializeAddressList(adminSet),
5308
+ version: 0n,
5309
+ dstEid,
5310
+ priceFeedFeeLib,
5311
+ })
5312
+ )
5313
+ )
5314
+
5315
+ // 1) Deploy the worker
5316
+ const internalMsgResults = await sendInternalMessageAndExpect({
5317
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5318
+ sender: srcFixture.owner.getSender(),
5319
+ contract: priceFeedCache,
5320
+ expectedTransactions: [
5321
+ {
5322
+ from: srcFixture.owner.address,
5323
+ to: priceFeedCache.address,
5324
+ deploy: true,
5325
+ success: true,
5326
+ },
5327
+ ],
5328
+ opCode: OPCODES.BaseInterface_OP_INITIALIZE,
5329
+ md: emptyObject,
5330
+ balanceRefill: toNano('1'),
5331
+ })
5332
+
5333
+ // 2) Update proxy admins list (including the new worker)
5334
+ await sendInternalMessageAndExpect({
5335
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5336
+ sender: srcFixture.owner.getSender(),
5337
+ contract: existingProxy,
5338
+ expectedTransactions: [
5339
+ {
5340
+ from: srcFixture.owner.address,
5341
+ to: existingProxy.address,
5342
+ success: true,
5343
+ },
5344
+ ],
5345
+ opCode: OPCODES.Worker_OP_SET_ADMINS,
5346
+ md: serializeAddressList([...currentAdminsWorkers, priceFeedCache]),
5347
+ balanceRefill: toNano('0'),
5348
+ })
5349
+
5350
+ // 3) Set proxy on worker
5351
+ await sendInternalMessageAndExpect({
5352
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5353
+ sender: srcFixture.owner.getSender(),
5354
+ contract: priceFeedCache,
5355
+ expectedTransactions: [
5356
+ {
5357
+ from: srcFixture.owner.address,
5358
+ to: priceFeedCache.address,
5359
+ success: true,
5360
+ },
5361
+ ],
5362
+ opCode: OPCODES.Worker_OP_SET_PROXY,
5363
+ md: await allStorages.getNewMdSetAddress({
5364
+ address: addressToBigInt(existingProxy.address),
5365
+ }),
5366
+ balanceRefill: toNano('0'),
5367
+ })
5368
+
5369
+ srcFixture.priceFeedCacheFixtures.set(dstEid, {
5370
+ priceFeedCache,
5371
+ proxy: existingProxy,
5372
+ admins: [...adminSet],
5373
+ })
5374
+
5375
+ return [priceFeedCache, internalMsgResults]
5376
+ }
5377
+
5378
+ export async function wireFixtureWithNewUln(
5379
+ blockchain: Blockchain,
5380
+ allStorages: SandboxContract<TonContractWrapper>,
5381
+ multiSigners: SandboxContract<TreasuryContract>[],
5382
+ srcFixture: OAppFixtureULN,
5383
+ dstFixture: OAppFixtureULN,
5384
+ eventHandler: LzEventHandler
5385
+ ): Promise<void> {
5386
+ // ===================================default config =====================================
5387
+
5388
+ const ulnConfigDefault: UlnConfig = {
5389
+ send: {
5390
+ workerQuoteGasLimit: BigInt(100000000),
5391
+ maxMessageBytes: BigInt(100000000),
5392
+ },
5393
+ receive: {
5394
+ minCommitPacketGas: BigInt(1),
5395
+ },
5396
+ }
5397
+
5398
+ const dvnConfigsDefault: DvnConfigs = {
5399
+ send: {
5400
+ numReqDvns: 2n,
5401
+ numOptDvns: 0n,
5402
+ },
5403
+ receive: {
5404
+ numReqDvns: 2n,
5405
+ numOptDvns: 0n,
5406
+ optDvnQuorum: 0n,
5407
+ },
5408
+ }
5409
+
5410
+ // ===================================deploy, configue, and register uln =====================================
5411
+
5412
+ srcFixture.msglibManager = await deployConfigAndRegisterUln(
5413
+ blockchain,
5414
+ multiSigners,
5415
+ allStorages,
5416
+ srcFixture,
5417
+ dstFixture,
5418
+ ulnConfigDefault,
5419
+ ULN_MANAGER_DEFAULT_VERSION,
5420
+ eventHandler,
5421
+ dvnConfigsDefault
5422
+ )
5423
+
5424
+ // ===================================add msg lib to controller =====================================
5425
+
5426
+ let internalMsgResults = await addMsgLibToController(
5427
+ blockchain,
5428
+ multiSigners,
5429
+ srcFixture,
5430
+ dstFixture,
5431
+ srcFixture.msglibManager
5432
+ )
5433
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
5434
+
5435
+ // ===================================set default endpoint config=====================================
5436
+
5437
+ internalMsgResults = await setDefaultEndpointConfig(
5438
+ blockchain,
5439
+ allStorages,
5440
+ multiSigners,
5441
+ srcFixture.msglibManager,
5442
+ srcFixture.msglibManager,
5443
+ srcFixture,
5444
+ dstFixture
5445
+ )
5446
+
5447
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
5448
+
5449
+ // expect no failures
5450
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
5451
+ }
4970
5452
  `;
4971
5453
  fs__namespace.default.writeFileSync(path__namespace.default.join(directory, filename), savedCode);
4972
5454
  }