@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.mjs CHANGED
@@ -1212,7 +1212,7 @@ var BaseWrapper = class {
1212
1212
  function generateCommonTestUtils(directory, filename) {
1213
1213
  const savedCode = `import fs from 'fs'
1214
1214
 
1215
- import { Address, Builder, Cell, Dictionary, SendMode, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1215
+ import { Address, Builder, Cell, Dictionary, SendMode, TupleItem, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1216
1216
  import {
1217
1217
  Blockchain,
1218
1218
  BlockchainTransaction,
@@ -1255,7 +1255,6 @@ import {
1255
1255
  OPCODES,
1256
1256
  TonContractWrapper,
1257
1257
  TonObjectUnwrapper,
1258
- bigintToAsciiString,
1259
1258
  deconstructorMap,
1260
1259
  keyMap,
1261
1260
  } from '../../src'
@@ -1265,12 +1264,10 @@ export const ActionTypes: { [key: string]: bigint } = {
1265
1264
  aba: BigInt(2),
1266
1265
  }
1267
1266
 
1268
- export interface PacketsInFlight {
1267
+ export interface PacketInFlight {
1269
1268
  fromEid: bigint
1270
1269
  toEid: bigint
1271
1270
  mdPacketSent: MdPacketSent
1272
- // nonce: bigint
1273
- // lzPacket: Cell
1274
1271
  }
1275
1272
 
1276
1273
  export interface SendOptions {
@@ -1291,7 +1288,6 @@ export const newTonObjectsContainer: { items: { [key: string]: unknown } } = {
1291
1288
 
1292
1289
  export const PUBLIC_KEY_BYTE_LENGTH = 64
1293
1290
  export const SIGNATURE_BYTE_LENGTH = 65
1294
- export const PUBLIC_KEY_HASH_BITS = 256
1295
1291
  const SEED_SIZE = 32
1296
1292
 
1297
1293
  // ==============================PROTOCOL SETUP GAS==============================
@@ -1597,6 +1593,21 @@ export async function createLzPacketFromPacketEncodedOverrideNonce(
1597
1593
  ).cell
1598
1594
  }
1599
1595
 
1596
+ export async function createLzPacketFromPacketEncodedOverrideNonceAndGuid(
1597
+ encodedPacket: Cell,
1598
+ newNonce: bigint,
1599
+ allStorages: SandboxContract<TonContractWrapper>
1600
+ ): Promise<Cell> {
1601
+ return (
1602
+ (
1603
+ await allStorages.getViewFunction('decodeAndOverrideNonceAndGuid<PacketV1>', [
1604
+ { type: 'cell', cell: encodedPacket },
1605
+ { type: 'int', value: newNonce },
1606
+ ])
1607
+ ).pop() as TupleItemCell
1608
+ ).cell
1609
+ }
1610
+
1600
1611
  export async function overrideNonceAndGuid(
1601
1612
  encodedPacket: Cell,
1602
1613
  newNonce: bigint,
@@ -1604,7 +1615,7 @@ export async function overrideNonceAndGuid(
1604
1615
  ): Promise<Cell> {
1605
1616
  return (
1606
1617
  (
1607
- await allStorages.getViewFunction('overrideNonceAndGuid<PacketV1>', [
1618
+ await allStorages.getViewFunction('decodeAndOverrideNonceAndGuidSerialized<PacketV1>', [
1608
1619
  { type: 'cell', cell: encodedPacket },
1609
1620
  { type: 'int', value: newNonce },
1610
1621
  ])
@@ -1971,6 +1982,47 @@ export async function assertFirstUncommitedNonce(
1971
1982
  expect(firstUncommittedNonce.value).toEqual(expectedValue - BigInt(1)) // _viewInboundNonce subtracts 1 from actual value
1972
1983
  }
1973
1984
 
1985
+ export async function assertCommittableView(
1986
+ ulnConnection: SandboxContract<TonContractWrapper>,
1987
+ nonce: bigint,
1988
+ packet: Cell,
1989
+ defaultUlnReceiveConfig: Cell
1990
+ ): Promise<bigint> {
1991
+ return (
1992
+ (
1993
+ await ulnConnection.getViewFunction('committableView', [
1994
+ { type: 'int', value: nonce },
1995
+ { type: 'cell', cell: packet },
1996
+ { type: 'cell', cell: defaultUlnReceiveConfig },
1997
+ ])
1998
+ ).pop() as TupleItemInt
1999
+ ).value
2000
+ }
2001
+
2002
+ export async function assertVerifiedView(
2003
+ contract: ExtendedContract<TonContractWrapper>,
2004
+ dvnAddress: bigint,
2005
+ nonce: bigint,
2006
+ packetHash: bigint,
2007
+ requiredConfirmations: bigint
2008
+ ): Promise<bigint> {
2009
+ const args: TupleItem[] = [
2010
+ { type: 'int', value: dvnAddress },
2011
+ { type: 'int', value: nonce },
2012
+ { type: 'int', value: packetHash },
2013
+ { type: 'int', value: requiredConfirmations },
2014
+ ]
2015
+ return (await contract.getViewFunction('verifiedView', args)).readBigNumber()
2016
+ }
2017
+
2018
+ export async function getExecutionStatus(
2019
+ contract: ExtendedContract<TonContractWrapper>,
2020
+ incomingNonce: bigint
2021
+ ): Promise<bigint> {
2022
+ const args: TupleItem[] = [{ type: 'int', value: incomingNonce }]
2023
+ return (await contract.getViewFunction('_viewExecutionStatus', args)).readBigNumber()
2024
+ }
2025
+
1974
2026
  export function addLibToBlockchain(blockchain: Blockchain, newLib: Cell): void {
1975
2027
  let libsDict: Dictionary<bigint, Cell>
1976
2028
  if (blockchain.libs) {
@@ -2633,15 +2685,13 @@ export async function assertZroBalance(
2633
2685
  expect(channelTS.zroBalance).toEqual(expectedValue)
2634
2686
  }
2635
2687
 
2636
- export function syncClTypeof(obj: Cell): string {
2637
- if (obj.bits.length === 0) {
2638
- return 'NULL'
2639
- }
2640
- try {
2641
- return bigintToAsciiString(obj.beginParse().preloadUintBig(80))
2642
- } catch (e) {
2643
- return 'UNKNOWN'
2688
+ export function isValidAscii(input: string): boolean {
2689
+ for (var i=0; i < input.length; i++) {
2690
+ if (input.charCodeAt(i)>127) {
2691
+ return false;
2692
+ }
2644
2693
  }
2694
+ return true;
2645
2695
  }
2646
2696
 
2647
2697
  export async function txDecoder(
@@ -2718,8 +2768,7 @@ export async function runtimeDecoder(contract: SandboxContract<TonContractWrappe
2718
2768
  newCellFieldType = 'cl::t::cellRef'
2719
2769
  } else {
2720
2770
  // Check if newCellFieldType is valid ASCII
2721
- // eslint-disable-next-line no-control-regex
2722
- if (!/^[p{ASCII}]+$/u.test(newCellFieldType)) {
2771
+ if (!isValidAscii(newCellFieldType)) {
2723
2772
  newCellFieldType = 'cl::t::cellRef'
2724
2773
  } else {
2725
2774
  newCellFieldType = keyMap[newCellFieldType] ?? newCellFieldType
@@ -3127,15 +3176,21 @@ import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager
3127
3176
  import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3128
3177
 
3129
3178
  import {
3179
+ ActionTypes,
3130
3180
  OAppFixture,
3131
3181
  OAppFlowGas,
3182
+ OutOfOrder,
3183
+ PacketInFlight,
3132
3184
  ProtocolFixture,
3133
3185
  SIGNATURE_BYTE_LENGTH,
3134
3186
  addMsgLibToController,
3187
+ assertCommittableView,
3188
+ assertVerifiedView,
3135
3189
  createLzPacketFromPacketEncoded,
3136
3190
  createVerifierDictSet,
3137
3191
  emptyObject,
3138
3192
  generateRandomVerifierSet,
3193
+ lzReceiveAndExpect,
3139
3194
  protocolSetupGas,
3140
3195
  publicKeyToHash,
3141
3196
  requireDefined,
@@ -3145,7 +3200,9 @@ import {
3145
3200
  setDefaultEndpointConfig,
3146
3201
  wireChannels,
3147
3202
  } from './auto-utils-common'
3203
+ import { ExpectedCounts, assertInboundCount, assertOutboundCount, incrementCounterAndExpectULN } from './utils'
3148
3204
  import {
3205
+ ERRORS,
3149
3206
  ExtendedContract,
3150
3207
  LzDict,
3151
3208
  LzEventHandler,
@@ -3159,6 +3216,12 @@ const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
3159
3216
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3160
3217
  const ULN_MANAGER_CUSTOM_VERSION = BigInt(2)
3161
3218
 
3219
+ export const TRUE = BigInt(-1)
3220
+ export const FALSE = BigInt(0)
3221
+ export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3222
+ export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3223
+ export const ChannelExecutionStatusExecutable = BigInt(2)
3224
+
3162
3225
  export interface SendDvnConfig {
3163
3226
  numReqDvns: bigint
3164
3227
  numOptDvns: bigint
@@ -3205,6 +3268,8 @@ export interface ProtocolFixtureULN extends ProtocolFixture {
3205
3268
  receiveDvnFixturesCustom: DvnFixture[]
3206
3269
  executorFixtures: ExecutorFixture
3207
3270
  priceFeedCacheFixture: PricedfeedCacheFixture
3271
+ defaultUlnSendConfig: Cell
3272
+ defaultUlnReceiveConfig: Cell
3208
3273
  }
3209
3274
 
3210
3275
  // ===============================INTERFACES===============================
@@ -3235,6 +3300,211 @@ export function serializeDvns(dvnList: bigint[]): Cell {
3235
3300
  return linkedList.endCell()
3236
3301
  }
3237
3302
 
3303
+ // ================================Out of order helper functions================================
3304
+
3305
+ export async function generateFromPacketsInFlight(
3306
+ outOfOrder: OutOfOrder,
3307
+ fixtures: Map<bigint, OAppFixtureULN>,
3308
+ expectedCounts: Map<bigint, ExpectedCounts>,
3309
+ packetsInFlight: Map<bigint, PacketInFlight[]>,
3310
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3311
+ eventHandler: LzEventHandler
3312
+ ): Promise<PacketInFlight[]> {
3313
+ let fromPacketsInFlight: PacketInFlight[] | undefined = []
3314
+
3315
+ for (const action of outOfOrder.actions) {
3316
+ const fromEidBigInt = BigInt(action.fromEid)
3317
+ const fromFixture = fixtures.get(fromEidBigInt)
3318
+ const fromExpectedCounts = expectedCounts.get(fromEidBigInt)
3319
+ fromPacketsInFlight = packetsInFlight.get(fromEidBigInt)
3320
+
3321
+ if (!fromFixture || !fromExpectedCounts || !fromPacketsInFlight) {
3322
+ throw new Error('Fixture, ExpectedCount, or PacketsInFlight not found')
3323
+ }
3324
+
3325
+ const mdPacketSent = await incrementCounterAndExpectULN(
3326
+ {
3327
+ dstEid: action.toEid,
3328
+ actionType: ActionTypes[action.actionType],
3329
+ extraOptions: beginCell().endCell(),
3330
+ nativeFee: toNano('0.000006240'),
3331
+ zroFee: toNano('0'),
3332
+ },
3333
+ multiSigOwner1,
3334
+ eventHandler,
3335
+ fromFixture.msglibConnection,
3336
+ fromFixture
3337
+ )
3338
+
3339
+ await assertOutboundCount(fromFixture.oApp, action.toEid, ++fromExpectedCounts.outbound)
3340
+
3341
+ fromPacketsInFlight.push({
3342
+ fromEid: action.fromEid,
3343
+ toEid: action.toEid,
3344
+ mdPacketSent,
3345
+ })
3346
+ }
3347
+ return fromPacketsInFlight
3348
+ }
3349
+
3350
+ export async function getRandomLzPacket(
3351
+ allStorages: SandboxContract<TonContractWrapper>,
3352
+ fromPacketsInFlight: PacketInFlight[],
3353
+ fixtures: Map<bigint, OAppFixtureULN>,
3354
+ expectedCounts: Map<bigint, ExpectedCounts>,
3355
+ pooos: Map<bigint, number[]>
3356
+ ): Promise<{
3357
+ randomPacketIndex: number
3358
+ randomPacketInFlight: PacketInFlight
3359
+ toFixture: OAppFixtureULN
3360
+ toExpectedCounts: ExpectedCounts
3361
+ lzPacket: Cell
3362
+ toPooo: number[]
3363
+ }> {
3364
+ if (fromPacketsInFlight.length === 0) {
3365
+ throw new Error('No packets in flight available')
3366
+ }
3367
+
3368
+ const randomPacketIndex = Math.floor(Math.random() * fromPacketsInFlight.length)
3369
+ const randomPacketInFlight = fromPacketsInFlight[randomPacketIndex]
3370
+
3371
+ const toEidBigInt = BigInt(randomPacketInFlight.toEid)
3372
+ const toFixture = fixtures.get(toEidBigInt)
3373
+ const toExpectedCounts = expectedCounts.get(toEidBigInt)
3374
+ const toPooo = pooos.get(toEidBigInt)
3375
+
3376
+ if (!toFixture || !toExpectedCounts || !toPooo) {
3377
+ throw new Error('Fixture, ExpectedCount, or POOO not found')
3378
+ }
3379
+
3380
+ const lzPacket = await createLzPacketFromPacketEncoded(randomPacketInFlight.mdPacketSent.packetEncoded, allStorages)
3381
+
3382
+ return {
3383
+ randomPacketIndex,
3384
+ randomPacketInFlight,
3385
+ toFixture,
3386
+ toExpectedCounts,
3387
+ lzPacket,
3388
+ toPooo,
3389
+ }
3390
+ }
3391
+
3392
+ export async function handleVerify(
3393
+ toFixture: OAppFixtureULN,
3394
+ randomPacketInFlight: PacketInFlight,
3395
+ lzPacket: Cell,
3396
+ allStorages: SandboxContract<TonContractWrapper>,
3397
+ eventHandler: LzEventHandler
3398
+ ): Promise<void> {
3399
+ let isVerified = true
3400
+ for (const dvnFixture of toFixture.receiveDvnFixturesCustom) {
3401
+ const isVerifiedView = await assertVerifiedView(
3402
+ toFixture.msglibConnection,
3403
+ addressToBigInt(dvnFixture.proxy.address),
3404
+ randomPacketInFlight.mdPacketSent.nonce,
3405
+ BigInt('0x' + lzPacket.hash().toString('hex')),
3406
+ BigInt(1) // requiredConfirmations
3407
+ )
3408
+
3409
+ if (isVerifiedView == FALSE) {
3410
+ isVerified = false
3411
+ }
3412
+ }
3413
+
3414
+ if (!isVerified) {
3415
+ await ulnVerifyAndExpect(
3416
+ allStorages,
3417
+ randomPacketInFlight.mdPacketSent,
3418
+ toFixture,
3419
+ toFixture.receiveDvnFixturesCustom,
3420
+ toFixture.msglibManager,
3421
+ toFixture.msglibConnection,
3422
+ eventHandler
3423
+ )
3424
+ }
3425
+ }
3426
+
3427
+ export async function handleCommit(
3428
+ toFixture: OAppFixtureULN,
3429
+ randomPacketInFlight: PacketInFlight,
3430
+ lzPacketWithGuid: Cell,
3431
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3432
+ eventHandler: LzEventHandler
3433
+ ): Promise<void> {
3434
+ const status = await assertCommittableView(
3435
+ toFixture.msglibConnection,
3436
+ randomPacketInFlight.mdPacketSent.nonce,
3437
+ lzPacketWithGuid,
3438
+ toFixture.defaultUlnReceiveConfig
3439
+ )
3440
+
3441
+ if (status == UlnConnectionVerificationStatusCommittable) {
3442
+ await commitVerificationAndExpect(lzPacketWithGuid, multiSigOwner1, eventHandler, toFixture)
3443
+ }
3444
+ }
3445
+
3446
+ export async function handleLzReceive(
3447
+ isExecutable: boolean,
3448
+ nonces: bigint[],
3449
+ toFixture: OAppFixtureULN,
3450
+ randomPacketInFlight: PacketInFlight,
3451
+ multiSigOwner1: SandboxContract<TreasuryContract>,
3452
+ allStorages: SandboxContract<TonContractWrapper>,
3453
+ lzReceivePrepareValue: bigint,
3454
+ eventHandler: LzEventHandler,
3455
+ toExpectedCounts: ExpectedCounts,
3456
+ randomPacketIndex: number | undefined,
3457
+ fromPacketsInFlight: PacketInFlight[] | undefined,
3458
+ totalPacketsDelivered?: number,
3459
+ opcode = OPCODES.Channel_OP_LZ_RECEIVE_PREPARE,
3460
+ profileGasFile = 'lz-receive-uln'
3461
+ ): Promise<number | undefined> {
3462
+ if (isExecutable) {
3463
+ for (const nonce of nonces) {
3464
+ await lzReceiveAndExpect({
3465
+ lzReceivePrepareMd: await allStorages.getNewMdLzReceivePrepare({
3466
+ nonce,
3467
+ nanotons: lzReceivePrepareValue,
3468
+ }),
3469
+ oAppFixture: toFixture,
3470
+ deployer: multiSigOwner1,
3471
+ eventHandler,
3472
+ profile: {
3473
+ profileGas: true,
3474
+ fileName: profileGasFile,
3475
+ },
3476
+ })
3477
+ await assertInboundCount(toFixture.oApp, randomPacketInFlight.fromEid, ++toExpectedCounts.inbound)
3478
+ if (totalPacketsDelivered !== undefined) totalPacketsDelivered++
3479
+ }
3480
+ if (fromPacketsInFlight && randomPacketIndex !== undefined) {
3481
+ fromPacketsInFlight.splice(randomPacketIndex, 1)
3482
+ }
3483
+ } else {
3484
+ await sendInternalMessageAndExpect({
3485
+ value: toNano('1'),
3486
+ sender: multiSigOwner1.getSender(),
3487
+ contract: toFixture.channel,
3488
+ opCode: opcode,
3489
+ md: await allStorages.getNewMdLzReceivePrepare({
3490
+ nonce: randomPacketInFlight.mdPacketSent.nonce,
3491
+ nanotons: lzReceivePrepareValue,
3492
+ }),
3493
+ expectedTransactions: [
3494
+ {
3495
+ from: multiSigOwner1.address,
3496
+ to: toFixture.channel.address,
3497
+ op: Number(opcode),
3498
+ exitCode: Number(ERRORS.Channel_ERROR_notExecutable),
3499
+ success: false,
3500
+ },
3501
+ ],
3502
+ })
3503
+ await assertInboundCount(toFixture.oApp, randomPacketInFlight.fromEid, toExpectedCounts.inbound)
3504
+ }
3505
+ return totalPacketsDelivered
3506
+ }
3507
+
3238
3508
  // ==============================ULN INTEGRATION FUNCTIONS==============================
3239
3509
 
3240
3510
  export async function commitVerificationAndExpect(
@@ -4126,6 +4396,8 @@ export async function deployConfigAndRegisterUln(
4126
4396
  confirmationsNull: BigInt(0),
4127
4397
  confirmations: BigInt(1),
4128
4398
  })
4399
+
4400
+ srcFixture.defaultUlnSendConfig = ulnSendConfig
4129
4401
 
4130
4402
  await sendMessageViaMultisigAndExpect({
4131
4403
  blockchain,
@@ -4176,6 +4448,8 @@ export async function deployConfigAndRegisterUln(
4176
4448
  optionalDVNThreshold: BigInt(optReceiveQuorum),
4177
4449
  })
4178
4450
 
4451
+ srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4452
+
4179
4453
  await sendMessageViaMultisigAndExpect({
4180
4454
  blockchain,
4181
4455
  multiSigContract: srcFixture.multisig,
@@ -4675,7 +4949,7 @@ export async function assertNewQuorum({ dvn, expectedQuorum }: AssertNewQuorumPa
4675
4949
 
4676
4950
  // ================================DVN ADMINS================================
4677
4951
 
4678
- export async function assertNewAdmins({ dvn, newDict: expectedAdmins }: AssertNewDictParams): Promise<void> {
4952
+ export async function assertNewDvnAdmins({ dvn, newDict: expectedAdmins }: AssertNewDictParams): Promise<void> {
4679
4953
  // check that the admins are set correctly (checking the hash is enough)
4680
4954
  const dvnStorageCell = await dvn.getCurrentStorageCell()
4681
4955
  const dvnStorage = await TonObjectUnwrapper.getDvnToTS(dvn, dvnStorageCell)