@xyo-network/chain-bridge 1.16.15 → 1.16.17

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.
Files changed (22) hide show
  1. package/package.json +11 -8
  2. package/dist/node/driver/indexer/spec/ChainBlocksObservable.spec.d.ts +0 -2
  3. package/dist/node/driver/indexer/spec/ChainBlocksObservable.spec.d.ts.map +0 -1
  4. package/dist/node/driver/indexer/spec/ChainHydratedBlocksObservable.spec.d.ts +0 -2
  5. package/dist/node/driver/indexer/spec/ChainHydratedBlocksObservable.spec.d.ts.map +0 -1
  6. package/dist/node/interface/service/Observer/ERC20TransferObserver/spec/ERC20TransferObserver.spec.d.ts +0 -2
  7. package/dist/node/interface/service/Observer/ERC20TransferObserver/spec/ERC20TransferObserver.spec.d.ts.map +0 -1
  8. package/dist/node/interface/service/Observer/LiquidityPoolBridgeObserver/spec/LiquidityPoolBridgeObserver.spec.d.ts +0 -2
  9. package/dist/node/interface/service/Observer/LiquidityPoolBridgeObserver/spec/LiquidityPoolBridgeObserver.spec.d.ts.map +0 -1
  10. package/dist/node/interface/service/Relay/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.d.ts +0 -2
  11. package/dist/node/interface/service/Relay/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.d.ts.map +0 -1
  12. package/dist/node/interface/service/Relay/LiquidityPoolBridgeRelay/spec/LiquidityPoolBridgeRelay.spec.d.ts +0 -2
  13. package/dist/node/interface/service/Relay/LiquidityPoolBridgeRelay/spec/LiquidityPoolBridgeRelay.spec.d.ts.map +0 -1
  14. package/dist/node/manifest/public/spec/Node.spec.d.ts +0 -2
  15. package/dist/node/manifest/public/spec/Node.spec.d.ts.map +0 -1
  16. package/src/driver/indexer/spec/ChainBlocksObservable.spec.ts +0 -62
  17. package/src/driver/indexer/spec/ChainHydratedBlocksObservable.spec.ts +0 -64
  18. package/src/interface/service/Observer/ERC20TransferObserver/spec/ERC20TransferObserver.spec.ts +0 -272
  19. package/src/interface/service/Observer/LiquidityPoolBridgeObserver/spec/LiquidityPoolBridgeObserver.spec.ts +0 -314
  20. package/src/interface/service/Relay/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.ts +0 -266
  21. package/src/interface/service/Relay/LiquidityPoolBridgeRelay/spec/LiquidityPoolBridgeRelay.spec.ts +0 -238
  22. package/src/manifest/public/spec/Node.spec.ts +0 -32
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/chain-bridge",
3
- "version": "1.16.15",
3
+ "version": "1.16.17",
4
4
  "description": "XYO Layer One Bridge",
5
5
  "homepage": "https://xylabs.com",
6
6
  "bugs": {
@@ -33,7 +33,10 @@
33
33
  "types": "./dist/node/index.d.ts",
34
34
  "files": [
35
35
  "dist",
36
- "src"
36
+ "src",
37
+ "!**/*.bench.*",
38
+ "!**/*.spec.*",
39
+ "!**/*.test.*"
37
40
  ],
38
41
  "scripts": {
39
42
  "build-tests": "tsc --noEmit --lib dom,esnext",
@@ -53,7 +56,7 @@
53
56
  "@xylabs/sdk-js": "~5.0.34",
54
57
  "@xyo-network/archivist-model": "~5.1.23",
55
58
  "@xyo-network/boundwitness-model": "~5.1.23",
56
- "@xyo-network/chain-protocol": "~1.16.15",
59
+ "@xyo-network/chain-protocol": "~1.16.17",
57
60
  "@xyo-network/manifest-model": "~5.1.23",
58
61
  "@xyo-network/module-factory-locator": "~5.1.23",
59
62
  "@xyo-network/module-model": "~5.1.23",
@@ -65,7 +68,7 @@
65
68
  "@xyo-network/typechain": "~4.0.10",
66
69
  "@xyo-network/wallet-model": "~5.1.23",
67
70
  "@xyo-network/xl1-protocol": "~1.13.11",
68
- "@xyo-network/xl1-protocol-sdk": "~1.16.15",
71
+ "@xyo-network/xl1-protocol-sdk": "~1.16.17",
69
72
  "compression": "~1.8.1",
70
73
  "cors": "~2.8.5",
71
74
  "express": "~5.1.0",
@@ -93,10 +96,10 @@
93
96
  "@xyo-network/bios": "~7.1.1",
94
97
  "@xyo-network/bios-model": "~7.1.1",
95
98
  "@xyo-network/boundwitness-builder": "~5.1.23",
96
- "@xyo-network/chain-modules": "~1.16.15",
97
- "@xyo-network/chain-protocol": "~1.16.15",
98
- "@xyo-network/chain-services": "~1.16.15",
99
- "@xyo-network/chain-telemetry": "~1.16.15",
99
+ "@xyo-network/chain-modules": "~1.16.17",
100
+ "@xyo-network/chain-protocol": "~1.16.17",
101
+ "@xyo-network/chain-services": "~1.16.17",
102
+ "@xyo-network/chain-telemetry": "~1.16.17",
100
103
  "@xyo-network/manifest-wrapper": "~5.1.23",
101
104
  "@xyo-network/module-abstract": "~5.1.23",
102
105
  "@xyo-network/module-abstract-mongodb": "~5.1.23",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ChainBlocksObservable.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ChainBlocksObservable.spec.d.ts","sourceRoot":"","sources":["../../../../../src/driver/indexer/spec/ChainBlocksObservable.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ChainHydratedBlocksObservable.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ChainHydratedBlocksObservable.spec.d.ts","sourceRoot":"","sources":["../../../../../src/driver/indexer/spec/ChainHydratedBlocksObservable.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ERC20TransferObserver.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ERC20TransferObserver.spec.d.ts","sourceRoot":"","sources":["../../../../../../../src/interface/service/Observer/ERC20TransferObserver/spec/ERC20TransferObserver.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=LiquidityPoolBridgeObserver.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LiquidityPoolBridgeObserver.spec.d.ts","sourceRoot":"","sources":["../../../../../../../src/interface/service/Observer/LiquidityPoolBridgeObserver/spec/LiquidityPoolBridgeObserver.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ChainBridgeRelayService.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ChainBridgeRelayService.spec.d.ts","sourceRoot":"","sources":["../../../../../../../src/interface/service/Relay/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=LiquidityPoolBridgeRelay.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LiquidityPoolBridgeRelay.spec.d.ts","sourceRoot":"","sources":["../../../../../../../src/interface/service/Relay/LiquidityPoolBridgeRelay/spec/LiquidityPoolBridgeRelay.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=Node.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Node.spec.d.ts","sourceRoot":"","sources":["../../../../../src/manifest/public/spec/Node.spec.ts"],"names":[],"mappings":""}
@@ -1,62 +0,0 @@
1
- import { Account } from '@xyo-network/account'
2
- import type { AccountInstance } from '@xyo-network/account-model'
3
- import { MemoryArchivist, MemoryArchivistConfigSchema } from '@xyo-network/archivist-memory'
4
- import type { ArchivistInstance } from '@xyo-network/archivist-model'
5
- import { buildRandomChain } from '@xyo-network/chain-protocol'
6
- import { ChainBlockNumberIterationService } from '@xyo-network/chain-services'
7
- import type { HydratedBlock } from '@xyo-network/xl1-protocol'
8
- import type { EventingChainBlockNumberIteratorService } from '@xyo-network/xl1-protocol-sdk'
9
- import {
10
- flattenHydratedBlocks, getDefaultConfig, readPayloadMapFromStore,
11
- } from '@xyo-network/xl1-protocol-sdk'
12
- import {
13
- firstValueFrom, take, toArray,
14
- } from 'rxjs'
15
- import {
16
- beforeAll, beforeEach, describe, expect, it,
17
- } from 'vitest'
18
-
19
- import { chainBlocks$ } from '../ChainBlocksObservable.ts'
20
-
21
- describe('chainBlocks$', () => {
22
- let chainArchivist: ArchivistInstance
23
- let producer: AccountInstance
24
- let chain: HydratedBlock[]
25
- let chainIterator: EventingChainBlockNumberIteratorService
26
- const config = getDefaultConfig()
27
-
28
- beforeAll(async () => {
29
- producer = await Account.random()
30
- })
31
-
32
- beforeEach(async () => {
33
- chain = await buildRandomChain(producer, 10)
34
- chainArchivist = await MemoryArchivist.create({ config: { schema: MemoryArchivistConfigSchema }, account: 'random' })
35
- await chainArchivist.insert(flattenHydratedBlocks(chain))
36
- const chainMap = readPayloadMapFromStore(chainArchivist)
37
- chainIterator = await ChainBlockNumberIterationService.create({ chainMap, config })
38
- })
39
- it('emits blocks in order when head updates', async () => {
40
- // Arrange
41
- // Setup initial head
42
- await chainIterator.updateHead(chain[4][0])
43
-
44
- // Setup observable to collect 3 blocks
45
- const resultPromise = firstValueFrom(
46
- chainBlocks$(chainIterator).pipe(
47
- take(3), // wait for 3 blocks
48
- toArray(), // collect into array
49
- ),
50
- )
51
-
52
- // Act
53
- // Simulate head updates
54
- await chainIterator.updateHead(chain[6][0])
55
- await chainIterator.updateHead(chain[7][0])
56
- const blocks = await resultPromise
57
-
58
- // Assert
59
- // Assert blocks are in ascending order
60
- expect(blocks.map(b => b.block)).toEqual([5, 6, 7])
61
- })
62
- })
@@ -1,64 +0,0 @@
1
- import { Account } from '@xyo-network/account'
2
- import type { AccountInstance } from '@xyo-network/account-model'
3
- import { MemoryArchivist, MemoryArchivistConfigSchema } from '@xyo-network/archivist-memory'
4
- import type { ArchivistInstance } from '@xyo-network/archivist-model'
5
- import { buildRandomChain } from '@xyo-network/chain-protocol'
6
- import { ChainBlockNumberIterationService } from '@xyo-network/chain-services'
7
- import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
8
- import type { HydratedBlock } from '@xyo-network/xl1-protocol'
9
- import type { EventingChainBlockNumberIteratorService, PayloadMapRead } from '@xyo-network/xl1-protocol-sdk'
10
- import {
11
- flattenHydratedBlocks, getDefaultConfig, readPayloadMapFromStore,
12
- } from '@xyo-network/xl1-protocol-sdk'
13
- import {
14
- firstValueFrom, take, toArray,
15
- } from 'rxjs'
16
- import {
17
- beforeAll, beforeEach, describe, expect, it,
18
- } from 'vitest'
19
-
20
- import { hydratedChainBlocks$ } from '../ChainHydratedBlocksObservable.ts'
21
-
22
- describe('hydratedChainBlocks$', () => {
23
- let chainArchivist: ArchivistInstance
24
- let producer: AccountInstance
25
- let chain: HydratedBlock[]
26
- let chainIterator: EventingChainBlockNumberIteratorService
27
- let chainMap: PayloadMapRead<WithStorageMeta<Payload>>
28
- const config = getDefaultConfig()
29
-
30
- beforeAll(async () => {
31
- producer = await Account.random()
32
- })
33
-
34
- beforeEach(async () => {
35
- chain = await buildRandomChain(producer, 10)
36
- chainArchivist = await MemoryArchivist.create({ config: { schema: MemoryArchivistConfigSchema }, account: 'random' })
37
- await chainArchivist.insert(flattenHydratedBlocks(chain))
38
- chainMap = readPayloadMapFromStore(chainArchivist)
39
- chainIterator = await ChainBlockNumberIterationService.create({ chainMap, config })
40
- })
41
- it('emits blocks in order when head updates', async () => {
42
- // Arrange
43
- // Setup initial head
44
- await chainIterator.updateHead(chain[4][0])
45
-
46
- // Setup observable to collect 3 blocks
47
- const resultPromise = firstValueFrom(
48
- hydratedChainBlocks$(chainIterator, { chainMap }).pipe(
49
- take(3), // wait for 3 blocks
50
- toArray(), // collect into array
51
- ),
52
- )
53
-
54
- // Act
55
- // Simulate head updates
56
- await chainIterator.updateHead(chain[6][0])
57
- await chainIterator.updateHead(chain[7][0])
58
- const blocks = await resultPromise
59
-
60
- // Assert
61
- // Assert blocks are in ascending order
62
- expect(blocks.map(b => b[0].block)).toEqual([5, 6, 7])
63
- })
64
- })
@@ -1,272 +0,0 @@
1
- import type { Address } from '@xylabs/sdk-js'
2
- import {
3
- assertEx, delay,
4
- toAddress, toHex,
5
- } from '@xylabs/sdk-js'
6
- import { Account } from '@xyo-network/account'
7
- import type { BridgeableToken } from '@xyo-network/typechain'
8
- import { BridgeableToken__factory } from '@xyo-network/typechain'
9
- import {
10
- AttoXL1ConvertFactor, type BridgeIntent, BridgeIntentSchema, type ChainId,
11
- } from '@xyo-network/xl1-protocol'
12
- import {
13
- parseEther, Wallet, WebSocketProvider,
14
- } from 'ethers'
15
- import {
16
- beforeAll, beforeEach, describe, expect, it, vi,
17
- } from 'vitest'
18
-
19
- import type {
20
- BridgeDestinationObservationIndexerInterface, BridgeIntentIndexerInterface, BridgeSourceObservationIndexerInterface,
21
- } from '../../../../interface/index.ts'
22
- import { ERC20TransferObserver } from '../ERC20TransferObserver.ts'
23
-
24
- describe.skip('ERC20TransferObserver', () => {
25
- // Test ERC-20 deployed to Hardhat local chain
26
- const TOKEN_ADDRESS = '0x5FbDB2315678afecb367f032d93F642f64180aa3'
27
- const WS_URL = 'ws://127.0.0.1:8545'
28
- const provider = new WebSocketProvider(WS_URL)
29
- let ethBridgeSender: Wallet
30
- let ethBridgeReceiver: Wallet
31
- let custodialWallet: Wallet
32
- let token: BridgeableToken
33
- let xl1Address: Address
34
- let xl1ChainId: ChainId
35
- let sourceObservations: BridgeSourceObservationIndexerInterface
36
- let destinationObservations: BridgeDestinationObservationIndexerInterface
37
- let intents: BridgeIntentIndexerInterface
38
-
39
- const srcAmountBigint = 100n * AttoXL1ConvertFactor.xl1
40
- const srcAmount = toHex(srcAmountBigint)
41
- const destAmount = srcAmount // 1:1 for test
42
- const ethChainId = toHex('0x7A69')
43
- const bridgeableTokenContract = toHex(TOKEN_ADDRESS)
44
-
45
- const createRandomWallet = async (): Promise<Wallet> => {
46
- // Create random account
47
- const account = await Account.random()
48
- expect(account.private?.hex).toBeDefined()
49
- const key = assertEx(account.private?.hex)
50
-
51
- // Create a wallet from the private key
52
- const wallet = new Wallet(key, provider)
53
- const deployer = await provider.getSigner(0)
54
-
55
- // Fund the wallet with some ETH for gas
56
- const fundTx = await deployer.sendTransaction({ to: wallet.address, value: parseEther('1') })
57
- await fundTx.wait()
58
-
59
- // Ensure wallet has ETH
60
- const balance = await provider.getBalance(wallet.address)
61
- expect(balance).toBeGreaterThan(0n)
62
-
63
- // Return the created wallet
64
- return wallet
65
- }
66
-
67
- beforeAll(async () => {
68
- const tokenOwner = await provider.getSigner(0)
69
- ethBridgeSender = await createRandomWallet()
70
- ethBridgeReceiver = await createRandomWallet()
71
- custodialWallet = await createRandomWallet()
72
-
73
- token = BridgeableToken__factory.connect(TOKEN_ADDRESS, tokenOwner)
74
- await token.mint(custodialWallet.address, parseEther((srcAmountBigint * 2n).toString()))
75
- await token.mint(ethBridgeSender.address, parseEther((srcAmountBigint * 2n).toString()))
76
- })
77
-
78
- beforeEach(async () => {
79
- xl1Address = (await Account.random()).address
80
- xl1ChainId = (await Account.random()).address
81
- })
82
-
83
- describe('when bridging from Ethereum', () => {
84
- beforeEach(() => {
85
- sourceObservations = {
86
- addObservation: vi.fn().mockResolvedValue(true),
87
- getObservationForIntent: vi.fn().mockResolvedValue(null),
88
- getIntentForObservation: vi.fn().mockResolvedValue(null),
89
- }
90
- destinationObservations = {
91
- addObservation: vi.fn().mockResolvedValue(true),
92
- getObservationForIntent: vi.fn().mockResolvedValue(null),
93
- getIntentForObservation: vi.fn().mockResolvedValue(null),
94
- }
95
- const nonce = Date.now().toString()
96
- const intent: BridgeIntent = {
97
- // Source
98
- src: ethChainId,
99
- srcAddress: toAddress(ethBridgeSender.address),
100
- srcAmount,
101
- srcToken: bridgeableTokenContract,
102
-
103
- // Destination
104
- dest: xl1ChainId,
105
- destAddress: xl1Address,
106
- destAmount,
107
- destToken: xl1ChainId,
108
-
109
- // Details
110
- nonce,
111
-
112
- schema: BridgeIntentSchema,
113
- }
114
- intents = {
115
- addIntent: vi.fn().mockResolvedValue(true),
116
- getIntentByNonce: vi.fn().mockResolvedValue(intent),
117
- getIntentsForDestination: vi.fn().mockResolvedValue([]),
118
- getIntentsForSource: vi.fn().mockResolvedValue([intent]),
119
- }
120
- })
121
- describe('for new transfers to custodial wallet', () => {
122
- it('should observe transfer', async () => {
123
- // Arrange
124
- // Create observer before transfer
125
- const observer = await ERC20TransferObserver.create({
126
- destinationObservations,
127
- intents,
128
- provider,
129
- sourceObservations,
130
- tokenAddress: TOKEN_ADDRESS,
131
- watchAddress: toAddress(custodialWallet.address),
132
- watchDirection: 'incoming',
133
- })
134
- expect(observer).toBeDefined()
135
- // Ensure sender has tokens
136
- const balance = await token.balanceOf(ethBridgeSender.address)
137
- expect(balance).toBeGreaterThan(0n)
138
- const sender = token.connect(ethBridgeSender)
139
-
140
- // Act
141
- // Transfer from sender to custodial wallet
142
- await sender.transfer(custodialWallet.address, srcAmountBigint)
143
-
144
- // Wait for event
145
- await delay(2000)
146
-
147
- // Assert
148
- // Ensure transfer was observed
149
- expect(sourceObservations.addObservation).toHaveBeenCalled()
150
- })
151
- })
152
- describe('for previous transfers to custodial wallet', () => {
153
- it('should observe transfer', async () => {
154
- // Arrange
155
- // Ensure sender has tokens
156
- const balance = await token.balanceOf(ethBridgeSender.address)
157
- expect(balance).toBeGreaterThan(0n)
158
- const sender = token.connect(ethBridgeSender)
159
- // Transfer from sender to custodial wallet
160
- await sender.transfer(custodialWallet.address, srcAmountBigint)
161
-
162
- // Act
163
- // Create observer after transfer
164
- const observer = await ERC20TransferObserver.create({
165
- destinationObservations,
166
- intents,
167
- provider,
168
- sourceObservations,
169
- tokenAddress: TOKEN_ADDRESS,
170
- watchAddress: toAddress(custodialWallet.address),
171
- watchDirection: 'incoming',
172
- })
173
- expect(observer).toBeDefined()
174
-
175
- // Assert
176
- // Ensure transfer was observed
177
- expect(sourceObservations.addObservation).toHaveBeenCalled()
178
- })
179
- })
180
- })
181
-
182
- describe('when bridging to Ethereum', () => {
183
- beforeEach(() => {
184
- sourceObservations = {
185
- addObservation: vi.fn().mockResolvedValue(true),
186
- getObservationForIntent: vi.fn().mockResolvedValue(null),
187
- getIntentForObservation: vi.fn().mockResolvedValue(null),
188
- }
189
- destinationObservations = {
190
- addObservation: vi.fn().mockResolvedValue(true),
191
- getObservationForIntent: vi.fn().mockResolvedValue(null),
192
- getIntentForObservation: vi.fn().mockResolvedValue(null),
193
- }
194
- const nonce = Date.now().toString()
195
- const intent: BridgeIntent = {
196
- // Source
197
- src: xl1ChainId, // From XL1
198
- srcAddress: xl1Address, // From XL1 sender
199
- srcAmount,
200
- srcToken: xl1ChainId, // In XL1
201
-
202
- // Destination
203
- dest: ethChainId, // To Ethereum
204
- destAddress: toAddress(ethBridgeReceiver.address),
205
- destAmount,
206
- destToken: bridgeableTokenContract,
207
-
208
- // Details
209
- nonce,
210
-
211
- schema: BridgeIntentSchema,
212
- }
213
- intents = {
214
- addIntent: vi.fn().mockResolvedValue(true),
215
- getIntentByNonce: vi.fn().mockResolvedValue(intent),
216
- getIntentsForDestination: vi.fn().mockResolvedValue([intent]),
217
- getIntentsForSource: vi.fn().mockResolvedValue([]),
218
- }
219
- })
220
- describe('for new transfers from custodial wallet', () => {
221
- it('should observe transfer', async () => {
222
- // Arrange
223
- // Create observer before transfer
224
- const observer = await ERC20TransferObserver.create({
225
- destinationObservations,
226
- intents,
227
- provider,
228
- sourceObservations,
229
- tokenAddress: TOKEN_ADDRESS,
230
- watchAddress: toAddress(custodialWallet.address),
231
- watchDirection: 'outgoing',
232
- })
233
- expect(observer).toBeDefined()
234
-
235
- // Act
236
- const sender = token.connect(custodialWallet)
237
- await sender.transfer(ethBridgeReceiver.address, srcAmountBigint.toString())
238
-
239
- // Wait for event
240
- await delay(2000)
241
-
242
- // Assert
243
- // Ensure transfer was observed
244
- expect(destinationObservations.addObservation).toHaveBeenCalled()
245
- })
246
- })
247
- describe('for previous transfers from custodial wallet', () => {
248
- it('should observe transfer', async () => {
249
- // Arrange
250
- const sender = token.connect(custodialWallet)
251
- await sender.transfer(ethBridgeReceiver.address, srcAmountBigint.toString())
252
-
253
- // Act
254
- // Create observer after transfer
255
- const observer = await ERC20TransferObserver.create({
256
- destinationObservations,
257
- intents,
258
- provider,
259
- sourceObservations,
260
- tokenAddress: TOKEN_ADDRESS,
261
- watchAddress: toAddress(custodialWallet.address),
262
- watchDirection: 'outgoing',
263
- })
264
- expect(observer).toBeDefined()
265
-
266
- // Assert
267
- // Ensure transfer was observed
268
- expect(destinationObservations.addObservation).toHaveBeenCalled()
269
- })
270
- })
271
- })
272
- })