@layerzerolabs/ton-sdk-tools 3.0.22-ton.1 → 3.0.24-ton.0

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
@@ -1234,7 +1234,7 @@ var BaseWrapper = class {
1234
1234
  function generateCommonTestUtils(directory, filename) {
1235
1235
  const savedCode = `import fs from 'fs'
1236
1236
 
1237
- import { Address, Builder, Cell, Dictionary, SendMode, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1237
+ import { Address, Builder, Cell, Dictionary, SendMode, TupleItem, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1238
1238
  import {
1239
1239
  Blockchain,
1240
1240
  BlockchainTransaction,
@@ -1277,7 +1277,6 @@ import {
1277
1277
  OPCODES,
1278
1278
  TonContractWrapper,
1279
1279
  TonObjectUnwrapper,
1280
- bigintToAsciiString,
1281
1280
  deconstructorMap,
1282
1281
  keyMap,
1283
1282
  } from '../../src'
@@ -1287,12 +1286,10 @@ export const ActionTypes: { [key: string]: bigint } = {
1287
1286
  aba: BigInt(2),
1288
1287
  }
1289
1288
 
1290
- export interface PacketsInFlight {
1289
+ export interface PacketInFlight {
1291
1290
  fromEid: bigint
1292
1291
  toEid: bigint
1293
1292
  mdPacketSent: MdPacketSent
1294
- // nonce: bigint
1295
- // lzPacket: Cell
1296
1293
  }
1297
1294
 
1298
1295
  export interface SendOptions {
@@ -1313,7 +1310,6 @@ export const newTonObjectsContainer: { items: { [key: string]: unknown } } = {
1313
1310
 
1314
1311
  export const PUBLIC_KEY_BYTE_LENGTH = 64
1315
1312
  export const SIGNATURE_BYTE_LENGTH = 65
1316
- export const PUBLIC_KEY_HASH_BITS = 256
1317
1313
  const SEED_SIZE = 32
1318
1314
 
1319
1315
  // ==============================PROTOCOL SETUP GAS==============================
@@ -1619,6 +1615,21 @@ export async function createLzPacketFromPacketEncodedOverrideNonce(
1619
1615
  ).cell
1620
1616
  }
1621
1617
 
1618
+ export async function createLzPacketFromPacketEncodedOverrideNonceAndGuid(
1619
+ encodedPacket: Cell,
1620
+ newNonce: bigint,
1621
+ allStorages: SandboxContract<TonContractWrapper>
1622
+ ): Promise<Cell> {
1623
+ return (
1624
+ (
1625
+ await allStorages.getViewFunction('decodeAndOverrideNonceAndGuid<PacketV1>', [
1626
+ { type: 'cell', cell: encodedPacket },
1627
+ { type: 'int', value: newNonce },
1628
+ ])
1629
+ ).pop() as TupleItemCell
1630
+ ).cell
1631
+ }
1632
+
1622
1633
  export async function overrideNonceAndGuid(
1623
1634
  encodedPacket: Cell,
1624
1635
  newNonce: bigint,
@@ -1626,7 +1637,7 @@ export async function overrideNonceAndGuid(
1626
1637
  ): Promise<Cell> {
1627
1638
  return (
1628
1639
  (
1629
- await allStorages.getViewFunction('overrideNonceAndGuid<PacketV1>', [
1640
+ await allStorages.getViewFunction('decodeAndOverrideNonceAndGuidSerialized<PacketV1>', [
1630
1641
  { type: 'cell', cell: encodedPacket },
1631
1642
  { type: 'int', value: newNonce },
1632
1643
  ])
@@ -1993,6 +2004,47 @@ export async function assertFirstUncommitedNonce(
1993
2004
  expect(firstUncommittedNonce.value).toEqual(expectedValue - BigInt(1)) // _viewInboundNonce subtracts 1 from actual value
1994
2005
  }
1995
2006
 
2007
+ export async function assertCommittableView(
2008
+ ulnConnection: SandboxContract<TonContractWrapper>,
2009
+ nonce: bigint,
2010
+ packet: Cell,
2011
+ defaultUlnReceiveConfig: Cell
2012
+ ): Promise<bigint> {
2013
+ return (
2014
+ (
2015
+ await ulnConnection.getViewFunction('committableView', [
2016
+ { type: 'int', value: nonce },
2017
+ { type: 'cell', cell: packet },
2018
+ { type: 'cell', cell: defaultUlnReceiveConfig },
2019
+ ])
2020
+ ).pop() as TupleItemInt
2021
+ ).value
2022
+ }
2023
+
2024
+ export async function assertVerifiedView(
2025
+ contract: ExtendedContract<TonContractWrapper>,
2026
+ dvnAddress: bigint,
2027
+ nonce: bigint,
2028
+ packetHash: bigint,
2029
+ requiredConfirmations: bigint
2030
+ ): Promise<bigint> {
2031
+ const args: TupleItem[] = [
2032
+ { type: 'int', value: dvnAddress },
2033
+ { type: 'int', value: nonce },
2034
+ { type: 'int', value: packetHash },
2035
+ { type: 'int', value: requiredConfirmations },
2036
+ ]
2037
+ return (await contract.getViewFunction('verifiedView', args)).readBigNumber()
2038
+ }
2039
+
2040
+ export async function getExecutionStatus(
2041
+ contract: ExtendedContract<TonContractWrapper>,
2042
+ incomingNonce: bigint
2043
+ ): Promise<bigint> {
2044
+ const args: TupleItem[] = [{ type: 'int', value: incomingNonce }]
2045
+ return (await contract.getViewFunction('_viewExecutionStatus', args)).readBigNumber()
2046
+ }
2047
+
1996
2048
  export function addLibToBlockchain(blockchain: Blockchain, newLib: Cell): void {
1997
2049
  let libsDict: Dictionary<bigint, Cell>
1998
2050
  if (blockchain.libs) {
@@ -2655,15 +2707,13 @@ export async function assertZroBalance(
2655
2707
  expect(channelTS.zroBalance).toEqual(expectedValue)
2656
2708
  }
2657
2709
 
2658
- export function syncClTypeof(obj: Cell): string {
2659
- if (obj.bits.length === 0) {
2660
- return 'NULL'
2661
- }
2662
- try {
2663
- return bigintToAsciiString(obj.beginParse().preloadUintBig(80))
2664
- } catch (e) {
2665
- return 'UNKNOWN'
2710
+ export function isValidAscii(input: string): boolean {
2711
+ for (var i=0; i < input.length; i++) {
2712
+ if (input.charCodeAt(i)>127) {
2713
+ return false;
2714
+ }
2666
2715
  }
2716
+ return true;
2667
2717
  }
2668
2718
 
2669
2719
  export async function txDecoder(
@@ -2740,8 +2790,7 @@ export async function runtimeDecoder(contract: SandboxContract<TonContractWrappe
2740
2790
  newCellFieldType = 'cl::t::cellRef'
2741
2791
  } else {
2742
2792
  // Check if newCellFieldType is valid ASCII
2743
- // eslint-disable-next-line no-control-regex
2744
- if (!/^[p{ASCII}]+$/u.test(newCellFieldType)) {
2793
+ if (!isValidAscii(newCellFieldType)) {
2745
2794
  newCellFieldType = 'cl::t::cellRef'
2746
2795
  } else {
2747
2796
  newCellFieldType = keyMap[newCellFieldType] ?? newCellFieldType
@@ -3149,15 +3198,21 @@ import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager
3149
3198
  import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3150
3199
 
3151
3200
  import {
3201
+ ActionTypes,
3152
3202
  OAppFixture,
3153
3203
  OAppFlowGas,
3204
+ OutOfOrder,
3205
+ PacketInFlight,
3154
3206
  ProtocolFixture,
3155
3207
  SIGNATURE_BYTE_LENGTH,
3156
3208
  addMsgLibToController,
3209
+ assertCommittableView,
3210
+ assertVerifiedView,
3157
3211
  createLzPacketFromPacketEncoded,
3158
3212
  createVerifierDictSet,
3159
3213
  emptyObject,
3160
3214
  generateRandomVerifierSet,
3215
+ lzReceiveAndExpect,
3161
3216
  protocolSetupGas,
3162
3217
  publicKeyToHash,
3163
3218
  requireDefined,
@@ -3167,7 +3222,9 @@ import {
3167
3222
  setDefaultEndpointConfig,
3168
3223
  wireChannels,
3169
3224
  } from './auto-utils-common'
3225
+ import { ExpectedCounts, assertInboundCount, assertOutboundCount, incrementCounterAndExpectULN } from './utils'
3170
3226
  import {
3227
+ ERRORS,
3171
3228
  ExtendedContract,
3172
3229
  LzDict,
3173
3230
  LzEventHandler,
@@ -3181,6 +3238,12 @@ const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
3181
3238
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3182
3239
  const ULN_MANAGER_CUSTOM_VERSION = BigInt(2)
3183
3240
 
3241
+ export const TRUE = BigInt(-1)
3242
+ export const FALSE = BigInt(0)
3243
+ export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3244
+ export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3245
+ export const ChannelExecutionStatusExecutable = BigInt(2)
3246
+
3184
3247
  export interface SendDvnConfig {
3185
3248
  numReqDvns: bigint
3186
3249
  numOptDvns: bigint
@@ -3227,6 +3290,8 @@ export interface ProtocolFixtureULN extends ProtocolFixture {
3227
3290
  receiveDvnFixturesCustom: DvnFixture[]
3228
3291
  executorFixtures: ExecutorFixture
3229
3292
  priceFeedCacheFixture: PricedfeedCacheFixture
3293
+ defaultUlnSendConfig: Cell
3294
+ defaultUlnReceiveConfig: Cell
3230
3295
  }
3231
3296
 
3232
3297
  // ===============================INTERFACES===============================
@@ -3257,6 +3322,211 @@ export function serializeDvns(dvnList: bigint[]): Cell {
3257
3322
  return linkedList.endCell()
3258
3323
  }
3259
3324
 
3325
+ // ================================Out of order helper functions================================
3326
+
3327
+ export async function generateFromPacketsInFlight(
3328
+ outOfOrder: OutOfOrder,
3329
+ fixtures: Map<bigint, OAppFixtureULN>,
3330
+ expectedCounts: Map<bigint, ExpectedCounts>,
3331
+ packetsInFlight: Map<bigint, PacketInFlight[]>,
3332
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3333
+ eventHandler: LzEventHandler
3334
+ ): Promise<PacketInFlight[]> {
3335
+ let fromPacketsInFlight: PacketInFlight[] | undefined = []
3336
+
3337
+ for (const action of outOfOrder.actions) {
3338
+ const fromEidBigInt = BigInt(action.fromEid)
3339
+ const fromFixture = fixtures.get(fromEidBigInt)
3340
+ const fromExpectedCounts = expectedCounts.get(fromEidBigInt)
3341
+ fromPacketsInFlight = packetsInFlight.get(fromEidBigInt)
3342
+
3343
+ if (!fromFixture || !fromExpectedCounts || !fromPacketsInFlight) {
3344
+ throw new Error('Fixture, ExpectedCount, or PacketsInFlight not found')
3345
+ }
3346
+
3347
+ const mdPacketSent = await incrementCounterAndExpectULN(
3348
+ {
3349
+ dstEid: action.toEid,
3350
+ actionType: ActionTypes[action.actionType],
3351
+ extraOptions: beginCell().endCell(),
3352
+ nativeFee: toNano('0.000006240'),
3353
+ zroFee: toNano('0'),
3354
+ },
3355
+ multiSigOwner1,
3356
+ eventHandler,
3357
+ fromFixture.msglibConnection,
3358
+ fromFixture
3359
+ )
3360
+
3361
+ await assertOutboundCount(fromFixture.oApp, action.toEid, ++fromExpectedCounts.outbound)
3362
+
3363
+ fromPacketsInFlight.push({
3364
+ fromEid: action.fromEid,
3365
+ toEid: action.toEid,
3366
+ mdPacketSent,
3367
+ })
3368
+ }
3369
+ return fromPacketsInFlight
3370
+ }
3371
+
3372
+ export async function getRandomLzPacket(
3373
+ allStorages: SandboxContract<TonContractWrapper>,
3374
+ fromPacketsInFlight: PacketInFlight[],
3375
+ fixtures: Map<bigint, OAppFixtureULN>,
3376
+ expectedCounts: Map<bigint, ExpectedCounts>,
3377
+ pooos: Map<bigint, number[]>
3378
+ ): Promise<{
3379
+ randomPacketIndex: number
3380
+ randomPacketInFlight: PacketInFlight
3381
+ toFixture: OAppFixtureULN
3382
+ toExpectedCounts: ExpectedCounts
3383
+ lzPacket: Cell
3384
+ toPooo: number[]
3385
+ }> {
3386
+ if (fromPacketsInFlight.length === 0) {
3387
+ throw new Error('No packets in flight available')
3388
+ }
3389
+
3390
+ const randomPacketIndex = Math.floor(Math.random() * fromPacketsInFlight.length)
3391
+ const randomPacketInFlight = fromPacketsInFlight[randomPacketIndex]
3392
+
3393
+ const toEidBigInt = BigInt(randomPacketInFlight.toEid)
3394
+ const toFixture = fixtures.get(toEidBigInt)
3395
+ const toExpectedCounts = expectedCounts.get(toEidBigInt)
3396
+ const toPooo = pooos.get(toEidBigInt)
3397
+
3398
+ if (!toFixture || !toExpectedCounts || !toPooo) {
3399
+ throw new Error('Fixture, ExpectedCount, or POOO not found')
3400
+ }
3401
+
3402
+ const lzPacket = await createLzPacketFromPacketEncoded(randomPacketInFlight.mdPacketSent.packetEncoded, allStorages)
3403
+
3404
+ return {
3405
+ randomPacketIndex,
3406
+ randomPacketInFlight,
3407
+ toFixture,
3408
+ toExpectedCounts,
3409
+ lzPacket,
3410
+ toPooo,
3411
+ }
3412
+ }
3413
+
3414
+ export async function handleVerify(
3415
+ toFixture: OAppFixtureULN,
3416
+ randomPacketInFlight: PacketInFlight,
3417
+ lzPacket: Cell,
3418
+ allStorages: SandboxContract<TonContractWrapper>,
3419
+ eventHandler: LzEventHandler
3420
+ ): Promise<void> {
3421
+ let isVerified = true
3422
+ for (const dvnFixture of toFixture.receiveDvnFixturesCustom) {
3423
+ const isVerifiedView = await assertVerifiedView(
3424
+ toFixture.msglibConnection,
3425
+ addressToBigInt(dvnFixture.proxy.address),
3426
+ randomPacketInFlight.mdPacketSent.nonce,
3427
+ BigInt('0x' + lzPacket.hash().toString('hex')),
3428
+ BigInt(1) // requiredConfirmations
3429
+ )
3430
+
3431
+ if (isVerifiedView == FALSE) {
3432
+ isVerified = false
3433
+ }
3434
+ }
3435
+
3436
+ if (!isVerified) {
3437
+ await ulnVerifyAndExpect(
3438
+ allStorages,
3439
+ randomPacketInFlight.mdPacketSent,
3440
+ toFixture,
3441
+ toFixture.receiveDvnFixturesCustom,
3442
+ toFixture.msglibManager,
3443
+ toFixture.msglibConnection,
3444
+ eventHandler
3445
+ )
3446
+ }
3447
+ }
3448
+
3449
+ export async function handleCommit(
3450
+ toFixture: OAppFixtureULN,
3451
+ randomPacketInFlight: PacketInFlight,
3452
+ lzPacketWithGuid: Cell,
3453
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3454
+ eventHandler: LzEventHandler
3455
+ ): Promise<void> {
3456
+ const status = await assertCommittableView(
3457
+ toFixture.msglibConnection,
3458
+ randomPacketInFlight.mdPacketSent.nonce,
3459
+ lzPacketWithGuid,
3460
+ toFixture.defaultUlnReceiveConfig
3461
+ )
3462
+
3463
+ if (status == UlnConnectionVerificationStatusCommittable) {
3464
+ await commitVerificationAndExpect(lzPacketWithGuid, multiSigOwner1, eventHandler, toFixture)
3465
+ }
3466
+ }
3467
+
3468
+ export async function handleLzReceive(
3469
+ isExecutable: boolean,
3470
+ nonces: bigint[],
3471
+ toFixture: OAppFixtureULN,
3472
+ randomPacketInFlight: PacketInFlight,
3473
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3474
+ allStorages: SandboxContract<TonContractWrapper>,
3475
+ lzReceivePrepareValue: bigint,
3476
+ eventHandler: LzEventHandler,
3477
+ toExpectedCounts: ExpectedCounts,
3478
+ randomPacketIndex: number | undefined,
3479
+ fromPacketsInFlight: PacketInFlight[] | undefined,
3480
+ totalPacketsDelivered?: number,
3481
+ opcode = OPCODES.Channel_OP_LZ_RECEIVE_PREPARE,
3482
+ profileGasFile = 'lz-receive-uln'
3483
+ ): Promise<number | undefined> {
3484
+ if (isExecutable) {
3485
+ for (const nonce of nonces) {
3486
+ await lzReceiveAndExpect({
3487
+ lzReceivePrepareMd: await allStorages.getNewMdLzReceivePrepare({
3488
+ nonce,
3489
+ nanotons: lzReceivePrepareValue,
3490
+ }),
3491
+ oAppFixture: toFixture,
3492
+ deployer: multiSigOwner1,
3493
+ eventHandler,
3494
+ profile: {
3495
+ profileGas: true,
3496
+ fileName: profileGasFile,
3497
+ },
3498
+ })
3499
+ await assertInboundCount(toFixture.oApp, randomPacketInFlight.fromEid, ++toExpectedCounts.inbound)
3500
+ if (totalPacketsDelivered !== undefined) totalPacketsDelivered++
3501
+ }
3502
+ if (fromPacketsInFlight && randomPacketIndex !== undefined) {
3503
+ fromPacketsInFlight.splice(randomPacketIndex, 1)
3504
+ }
3505
+ } else {
3506
+ await sendInternalMessageAndExpect({
3507
+ value: toNano('1'),
3508
+ sender: multiSigOwner1.getSender(),
3509
+ contract: toFixture.channel,
3510
+ opCode: opcode,
3511
+ md: await allStorages.getNewMdLzReceivePrepare({
3512
+ nonce: randomPacketInFlight.mdPacketSent.nonce,
3513
+ nanotons: lzReceivePrepareValue,
3514
+ }),
3515
+ expectedTransactions: [
3516
+ {
3517
+ from: multiSigOwner1.address,
3518
+ to: toFixture.channel.address,
3519
+ op: Number(opcode),
3520
+ exitCode: Number(ERRORS.Channel_ERROR_notExecutable),
3521
+ success: false,
3522
+ },
3523
+ ],
3524
+ })
3525
+ await assertInboundCount(toFixture.oApp, randomPacketInFlight.fromEid, toExpectedCounts.inbound)
3526
+ }
3527
+ return totalPacketsDelivered
3528
+ }
3529
+
3260
3530
  // ==============================ULN INTEGRATION FUNCTIONS==============================
3261
3531
 
3262
3532
  export async function commitVerificationAndExpect(
@@ -4148,6 +4418,8 @@ export async function deployConfigAndRegisterUln(
4148
4418
  confirmationsNull: BigInt(0),
4149
4419
  confirmations: BigInt(1),
4150
4420
  })
4421
+
4422
+ srcFixture.defaultUlnSendConfig = ulnSendConfig
4151
4423
 
4152
4424
  await sendMessageViaMultisigAndExpect({
4153
4425
  blockchain,
@@ -4198,6 +4470,8 @@ export async function deployConfigAndRegisterUln(
4198
4470
  optionalDVNThreshold: BigInt(optReceiveQuorum),
4199
4471
  })
4200
4472
 
4473
+ srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4474
+
4201
4475
  await sendMessageViaMultisigAndExpect({
4202
4476
  blockchain,
4203
4477
  multiSigContract: srcFixture.multisig,
@@ -4697,7 +4971,7 @@ export async function assertNewQuorum({ dvn, expectedQuorum }: AssertNewQuorumPa
4697
4971
 
4698
4972
  // ================================DVN ADMINS================================
4699
4973
 
4700
- export async function assertNewAdmins({ dvn, newDict: expectedAdmins }: AssertNewDictParams): Promise<void> {
4974
+ export async function assertNewDvnAdmins({ dvn, newDict: expectedAdmins }: AssertNewDictParams): Promise<void> {
4701
4975
  // check that the admins are set correctly (checking the hash is enough)
4702
4976
  const dvnStorageCell = await dvn.getCurrentStorageCell()
4703
4977
  const dvnStorage = await TonObjectUnwrapper.getDvnToTS(dvn, dvnStorageCell)