@0xsequence/catapult 1.3.2 → 1.3.4

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 (67) hide show
  1. package/CONCEPT.md +24 -0
  2. package/README.md +16 -0
  3. package/dist/commands/run.d.ts.map +1 -1
  4. package/dist/commands/run.js +4 -2
  5. package/dist/commands/run.js.map +1 -1
  6. package/dist/lib/__tests__/deployer.spec.js +71 -1
  7. package/dist/lib/__tests__/deployer.spec.js.map +1 -1
  8. package/dist/lib/core/__tests__/engine.spec.js +270 -0
  9. package/dist/lib/core/__tests__/engine.spec.js.map +1 -1
  10. package/dist/lib/core/__tests__/resolver.spec.js +132 -0
  11. package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
  12. package/dist/lib/core/engine.d.ts +13 -0
  13. package/dist/lib/core/engine.d.ts.map +1 -1
  14. package/dist/lib/core/engine.js +148 -15
  15. package/dist/lib/core/engine.js.map +1 -1
  16. package/dist/lib/core/resolver.d.ts +1 -0
  17. package/dist/lib/core/resolver.d.ts.map +1 -1
  18. package/dist/lib/core/resolver.js +24 -7
  19. package/dist/lib/core/resolver.js.map +1 -1
  20. package/dist/lib/deployer.d.ts +2 -0
  21. package/dist/lib/deployer.d.ts.map +1 -1
  22. package/dist/lib/deployer.js +18 -1
  23. package/dist/lib/deployer.js.map +1 -1
  24. package/dist/lib/events/__tests__/event-system.spec.js +30 -0
  25. package/dist/lib/events/__tests__/event-system.spec.js.map +1 -1
  26. package/dist/lib/events/cli-adapter.d.ts.map +1 -1
  27. package/dist/lib/events/cli-adapter.js +25 -1
  28. package/dist/lib/events/cli-adapter.js.map +1 -1
  29. package/dist/lib/events/types.d.ts +26 -2
  30. package/dist/lib/events/types.d.ts.map +1 -1
  31. package/dist/lib/std/templates/assured-deployment.yaml +4 -3
  32. package/dist/lib/std/templates/era-evm-predeploy.yaml +35 -0
  33. package/dist/lib/std/templates/erc-2470.yaml +3 -0
  34. package/dist/lib/std/templates/min-balance.yaml +3 -0
  35. package/dist/lib/std/templates/nano-universal-deployer.yaml +2 -0
  36. package/dist/lib/std/templates/raw-erc-2470.yaml +3 -0
  37. package/dist/lib/std/templates/raw-nano-universal-deployer.yaml +3 -0
  38. package/dist/lib/std/templates/raw-sequence-universal-deployer-2.yaml +4 -0
  39. package/dist/lib/std/templates/sequence-universal-deployer-2.yaml +4 -0
  40. package/dist/lib/types/values.d.ts +8 -1
  41. package/dist/lib/types/values.d.ts.map +1 -1
  42. package/dist/lib/utils/assertion.d.ts +4 -0
  43. package/dist/lib/utils/assertion.d.ts.map +1 -0
  44. package/dist/lib/utils/assertion.js +27 -0
  45. package/dist/lib/utils/assertion.js.map +1 -0
  46. package/package.json +12 -13
  47. package/src/commands/run.ts +4 -1
  48. package/src/lib/__tests__/deployer.spec.ts +108 -1
  49. package/src/lib/core/__tests__/engine.spec.ts +321 -0
  50. package/src/lib/core/__tests__/resolver.spec.ts +150 -1
  51. package/src/lib/core/engine.ts +188 -17
  52. package/src/lib/core/resolver.ts +29 -8
  53. package/src/lib/deployer.ts +28 -1
  54. package/src/lib/events/__tests__/event-system.spec.ts +51 -2
  55. package/src/lib/events/cli-adapter.ts +32 -4
  56. package/src/lib/events/types.ts +30 -2
  57. package/src/lib/std/templates/assured-deployment.yaml +4 -3
  58. package/src/lib/std/templates/era-evm-predeploy.yaml +35 -0
  59. package/src/lib/std/templates/erc-2470.yaml +3 -0
  60. package/src/lib/std/templates/min-balance.yaml +3 -0
  61. package/src/lib/std/templates/nano-universal-deployer.yaml +2 -0
  62. package/src/lib/std/templates/raw-erc-2470.yaml +3 -0
  63. package/src/lib/std/templates/raw-nano-universal-deployer.yaml +3 -0
  64. package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +4 -0
  65. package/src/lib/std/templates/sequence-universal-deployer-2.yaml +4 -0
  66. package/src/lib/types/values.ts +10 -1
  67. package/src/lib/utils/assertion.ts +24 -0
@@ -117,7 +117,8 @@ describe('Deployer', () => {
117
117
  } as any
118
118
 
119
119
  mockEngine = {
120
- executeJob: jest.fn().mockResolvedValue(undefined)
120
+ executeJob: jest.fn().mockResolvedValue(undefined),
121
+ getVerificationWarnings: jest.fn().mockReturnValue([])
121
122
  } as any
122
123
 
123
124
  mockContext = {
@@ -1199,4 +1200,110 @@ describe('Deployer', () => {
1199
1200
  expect(mockEngine.executeJob).toHaveBeenCalledTimes(2)
1200
1201
  })
1201
1202
  })
1203
+
1204
+ describe('ignore verify errors feature', () => {
1205
+ it('should pass ignoreVerifyErrors option to ExecutionEngine', async () => {
1206
+ const optionsWithIgnoreVerifyErrors = {
1207
+ ...deployerOptions,
1208
+ ignoreVerifyErrors: true
1209
+ }
1210
+
1211
+ const deployer = new Deployer(optionsWithIgnoreVerifyErrors)
1212
+ await deployer.run()
1213
+
1214
+ // Verify that ExecutionEngine was created with ignoreVerifyErrors option
1215
+ expect(MockExecutionEngine).toHaveBeenCalledWith(
1216
+ expect.anything(),
1217
+ expect.objectContaining({
1218
+ ignoreVerifyErrors: true
1219
+ })
1220
+ )
1221
+ })
1222
+
1223
+ it('should emit verification warnings report when ignoreVerifyErrors is enabled', async () => {
1224
+ const mockWarnings = [
1225
+ {
1226
+ actionName: 'verify-test',
1227
+ address: '0x1234567890123456789012345678901234567890',
1228
+ contractName: 'TestContract',
1229
+ platform: 'etherscan_v2',
1230
+ error: 'Failed to verify contract',
1231
+ networkName: 'mainnet'
1232
+ }
1233
+ ]
1234
+
1235
+ // Mock engine to return warnings
1236
+ mockEngine.getVerificationWarnings = jest.fn().mockReturnValue(mockWarnings)
1237
+
1238
+ const optionsWithIgnoreVerifyErrors = {
1239
+ ...deployerOptions,
1240
+ ignoreVerifyErrors: true
1241
+ }
1242
+
1243
+ const deployer = new Deployer(optionsWithIgnoreVerifyErrors)
1244
+
1245
+ // Mock event emitter to track events
1246
+ const mockEmitEvent = jest.fn()
1247
+ ;(deployer as any).events = { emitEvent: mockEmitEvent }
1248
+
1249
+ await deployer.run()
1250
+
1251
+ // Verify that verification warnings report was emitted
1252
+ expect(mockEmitEvent).toHaveBeenCalledWith({
1253
+ type: 'verification_warnings_report',
1254
+ level: 'warn',
1255
+ data: {
1256
+ totalWarnings: 1,
1257
+ warnings: mockWarnings
1258
+ }
1259
+ })
1260
+ })
1261
+
1262
+ it('should not emit verification warnings report when ignoreVerifyErrors is disabled', async () => {
1263
+ const optionsWithoutIgnoreVerifyErrors = {
1264
+ ...deployerOptions,
1265
+ ignoreVerifyErrors: false
1266
+ }
1267
+
1268
+ const deployer = new Deployer(optionsWithoutIgnoreVerifyErrors)
1269
+
1270
+ // Mock event emitter to track events
1271
+ const mockEmitEvent = jest.fn()
1272
+ ;(deployer as any).events = { emitEvent: mockEmitEvent }
1273
+
1274
+ await deployer.run()
1275
+
1276
+ // Verify that verification warnings report was NOT emitted
1277
+ expect(mockEmitEvent).not.toHaveBeenCalledWith(
1278
+ expect.objectContaining({
1279
+ type: 'verification_warnings_report'
1280
+ })
1281
+ )
1282
+ })
1283
+
1284
+ it('should not emit verification warnings report when there are no warnings', async () => {
1285
+ // Mock engine to return no warnings
1286
+ mockEngine.getVerificationWarnings = jest.fn().mockReturnValue([])
1287
+
1288
+ const optionsWithIgnoreVerifyErrors = {
1289
+ ...deployerOptions,
1290
+ ignoreVerifyErrors: true
1291
+ }
1292
+
1293
+ const deployer = new Deployer(optionsWithIgnoreVerifyErrors)
1294
+
1295
+ // Mock event emitter to track events
1296
+ const mockEmitEvent = jest.fn()
1297
+ ;(deployer as any).events = { emitEvent: mockEmitEvent }
1298
+
1299
+ await deployer.run()
1300
+
1301
+ // Verify that verification warnings report was NOT emitted when no warnings
1302
+ expect(mockEmitEvent).not.toHaveBeenCalledWith(
1303
+ expect.objectContaining({
1304
+ type: 'verification_warnings_report'
1305
+ })
1306
+ )
1307
+ })
1308
+ })
1202
1309
  })
@@ -1542,4 +1542,325 @@ describe('ExecutionEngine', () => {
1542
1542
  expect(context.getOutput('nick-test-default-bytecode.success')).toBe(true)
1543
1543
  })
1544
1544
  })
1545
+
1546
+ describe('ignore verify errors feature', () => {
1547
+ beforeEach(() => {
1548
+ // Mock fs.readFile to return valid build info
1549
+ jest.doMock('fs/promises', () => ({
1550
+ readFile: jest.fn().mockResolvedValue(JSON.stringify({
1551
+ _format: 'hh-sol-build-info-1',
1552
+ id: 'test-id',
1553
+ solcVersion: '0.8.0',
1554
+ input: {
1555
+ language: 'Solidity',
1556
+ sources: {
1557
+ 'TestContract.sol': {
1558
+ content: 'contract TestContract { }'
1559
+ }
1560
+ },
1561
+ settings: {
1562
+ optimizer: { enabled: true, runs: 200 },
1563
+ outputSelection: { '*': { '*': ['*'] } }
1564
+ }
1565
+ },
1566
+ output: {
1567
+ contracts: {},
1568
+ sources: {}
1569
+ }
1570
+ }))
1571
+ }))
1572
+
1573
+ // Create a mock verification registry with a failing platform
1574
+ const mockVerificationRegistry = new VerificationPlatformRegistry()
1575
+ const mockPlatform = {
1576
+ name: 'mock-platform',
1577
+ supportsNetwork: jest.fn().mockReturnValue(true),
1578
+ isConfigured: jest.fn().mockReturnValue(true),
1579
+ getConfigurationRequirements: jest.fn().mockReturnValue(''),
1580
+ isContractAlreadyVerified: jest.fn().mockResolvedValue(false),
1581
+ verifyContract: jest.fn().mockRejectedValue(new Error('Verification failed'))
1582
+ }
1583
+ mockVerificationRegistry.register(mockPlatform)
1584
+
1585
+ engine = new ExecutionEngine(templates, {
1586
+ verificationRegistry: mockVerificationRegistry,
1587
+ ignoreVerifyErrors: true
1588
+ })
1589
+ })
1590
+
1591
+ it('should collect verification warnings when ignoreVerifyErrors is enabled', async () => {
1592
+ const mockContract = {
1593
+ sourceName: 'TestContract.sol',
1594
+ contractName: 'TestContract',
1595
+ compiler: { version: '0.8.0' },
1596
+ buildInfoId: 'test-build-id',
1597
+ source: 'contract TestContract { }',
1598
+ creationCode: '0x608060405234801561000f575f5ffd5b50602a5f526020601ff3',
1599
+ abi: [],
1600
+ _sources: new Set(['TestContract.sol', '/path/to/build-info/test.json'])
1601
+ }
1602
+
1603
+ context.contractRepository.addForTesting({
1604
+ contractName: mockContract.contractName,
1605
+ abi: mockContract.abi,
1606
+ bytecode: mockContract.creationCode,
1607
+ sourceName: mockContract.sourceName,
1608
+ source: mockContract.source,
1609
+ compiler: mockContract.compiler,
1610
+ buildInfoId: mockContract.buildInfoId,
1611
+ _path: '/test/path',
1612
+ _hash: 'test-hash'
1613
+ })
1614
+
1615
+ const action: Action = {
1616
+ type: 'verify-contract',
1617
+ name: 'test-verify',
1618
+ arguments: {
1619
+ address: TEST_ADDRESSES.RECIPIENT_1,
1620
+ contract: '{{Contract(TestContract)}}',
1621
+ platform: 'mock-platform'
1622
+ }
1623
+ }
1624
+
1625
+ // Should not throw even though verification fails
1626
+ await expect((engine as any).executePrimitive(action, context, new Map()))
1627
+ .resolves.not.toThrow()
1628
+
1629
+ // Should have collected the warning
1630
+ const warnings = engine.getVerificationWarnings()
1631
+ expect(warnings).toHaveLength(1)
1632
+ expect(warnings[0]).toMatchObject({
1633
+ actionName: 'test-verify',
1634
+ address: TEST_ADDRESSES.RECIPIENT_1,
1635
+ contractName: 'TestContract.sol:TestContract',
1636
+ platform: 'mock-platform',
1637
+ error: 'Action "test-verify": No build-info file found in contract sources'
1638
+ })
1639
+ })
1640
+
1641
+ it('should throw verification errors when ignoreVerifyErrors is disabled', async () => {
1642
+ // Create engine with ignoreVerifyErrors disabled
1643
+ const mockVerificationRegistry = new VerificationPlatformRegistry()
1644
+ const mockPlatform = {
1645
+ name: 'mock-platform',
1646
+ supportsNetwork: jest.fn().mockReturnValue(true),
1647
+ isConfigured: jest.fn().mockReturnValue(true),
1648
+ getConfigurationRequirements: jest.fn().mockReturnValue(''),
1649
+ isContractAlreadyVerified: jest.fn().mockResolvedValue(false),
1650
+ verifyContract: jest.fn().mockRejectedValue(new Error('Verification failed'))
1651
+ }
1652
+ mockVerificationRegistry.register(mockPlatform)
1653
+
1654
+ const engineWithoutIgnore = new ExecutionEngine(templates, {
1655
+ verificationRegistry: mockVerificationRegistry,
1656
+ ignoreVerifyErrors: false
1657
+ })
1658
+
1659
+ const mockContract = {
1660
+ sourceName: 'TestContract.sol',
1661
+ contractName: 'TestContract',
1662
+ compiler: { version: '0.8.0' },
1663
+ buildInfoId: 'test-build-id',
1664
+ source: 'contract TestContract { }',
1665
+ creationCode: '0x608060405234801561000f575f5ffd5b50602a5f526020601ff3',
1666
+ abi: [],
1667
+ _sources: new Set(['TestContract.sol', '/path/to/build-info/test.json'])
1668
+ }
1669
+
1670
+ context.contractRepository.addForTesting({
1671
+ contractName: mockContract.contractName,
1672
+ abi: mockContract.abi,
1673
+ bytecode: mockContract.creationCode,
1674
+ sourceName: mockContract.sourceName,
1675
+ source: mockContract.source,
1676
+ compiler: mockContract.compiler,
1677
+ buildInfoId: mockContract.buildInfoId,
1678
+ _path: '/test/path',
1679
+ _hash: 'test-hash'
1680
+ })
1681
+
1682
+ const action: Action = {
1683
+ type: 'verify-contract',
1684
+ name: 'test-verify',
1685
+ arguments: {
1686
+ address: TEST_ADDRESSES.RECIPIENT_1,
1687
+ contract: '{{Contract(TestContract)}}',
1688
+ platform: 'mock-platform'
1689
+ }
1690
+ }
1691
+
1692
+ // Should throw when ignoreVerifyErrors is disabled
1693
+ await expect((engineWithoutIgnore as any).executePrimitive(action, context, new Map()))
1694
+ .rejects.toThrow('Action "test-verify": No build-info file found in contract sources')
1695
+ })
1696
+
1697
+ it('should handle multiple platform verification failures with ignoreVerifyErrors', async () => {
1698
+ const mockVerificationRegistry = new VerificationPlatformRegistry()
1699
+
1700
+ // Create multiple failing platforms
1701
+ const platforms = ['platform1', 'platform2', 'platform3']
1702
+ platforms.forEach(name => {
1703
+ const mockPlatform = {
1704
+ name,
1705
+ supportsNetwork: jest.fn().mockReturnValue(true),
1706
+ isConfigured: jest.fn().mockReturnValue(true),
1707
+ getConfigurationRequirements: jest.fn().mockReturnValue(''),
1708
+ isContractAlreadyVerified: jest.fn().mockResolvedValue(false),
1709
+ verifyContract: jest.fn().mockRejectedValue(new Error(`${name} verification failed`))
1710
+ }
1711
+ mockVerificationRegistry.register(mockPlatform)
1712
+ })
1713
+
1714
+ engine = new ExecutionEngine(templates, {
1715
+ verificationRegistry: mockVerificationRegistry,
1716
+ ignoreVerifyErrors: true
1717
+ })
1718
+
1719
+ const mockContract = {
1720
+ sourceName: 'TestContract.sol',
1721
+ contractName: 'TestContract',
1722
+ compiler: { version: '0.8.0' },
1723
+ buildInfoId: 'test-build-id',
1724
+ source: 'contract TestContract { }',
1725
+ creationCode: '0x608060405234801561000f575f5ffd5b50602a5f526020601ff3',
1726
+ abi: [],
1727
+ _sources: new Set(['TestContract.sol', '/path/to/build-info/test.json'])
1728
+ }
1729
+
1730
+ context.contractRepository.addForTesting({
1731
+ contractName: mockContract.contractName,
1732
+ abi: mockContract.abi,
1733
+ bytecode: mockContract.creationCode,
1734
+ sourceName: mockContract.sourceName,
1735
+ source: mockContract.source,
1736
+ compiler: mockContract.compiler,
1737
+ buildInfoId: mockContract.buildInfoId,
1738
+ _path: '/test/path',
1739
+ _hash: 'test-hash'
1740
+ })
1741
+
1742
+ const action: Action = {
1743
+ type: 'verify-contract',
1744
+ name: 'test-verify',
1745
+ arguments: {
1746
+ address: TEST_ADDRESSES.RECIPIENT_1,
1747
+ contract: '{{Contract(TestContract)}}',
1748
+ platform: platforms
1749
+ }
1750
+ }
1751
+
1752
+ // Should not throw even with multiple platform failures
1753
+ await expect((engine as any).executePrimitive(action, context, new Map()))
1754
+ .resolves.not.toThrow()
1755
+
1756
+ // Should have collected warnings for all platforms
1757
+ const warnings = engine.getVerificationWarnings()
1758
+ expect(warnings).toHaveLength(3)
1759
+
1760
+ platforms.forEach((platform, index) => {
1761
+ expect(warnings[index]).toMatchObject({
1762
+ actionName: 'test-verify',
1763
+ platform,
1764
+ error: 'Action "test-verify": No build-info file found in contract sources'
1765
+ })
1766
+ })
1767
+ })
1768
+
1769
+ it('should provide methods to get and clear verification warnings', () => {
1770
+ // Initially empty
1771
+ expect(engine.getVerificationWarnings()).toEqual([])
1772
+
1773
+ // Manually add a warning (simulating what happens during verification)
1774
+ ;(engine as any).verificationWarnings.push({
1775
+ actionName: 'test',
1776
+ address: '0x123',
1777
+ contractName: 'Test',
1778
+ platform: 'test-platform',
1779
+ error: 'test error'
1780
+ })
1781
+
1782
+ // Should return the warning
1783
+ const warnings = engine.getVerificationWarnings()
1784
+ expect(warnings).toHaveLength(1)
1785
+ expect(warnings[0]).toMatchObject({
1786
+ actionName: 'test',
1787
+ error: 'test error'
1788
+ })
1789
+
1790
+ // Clear warnings
1791
+ engine.clearVerificationWarnings()
1792
+ expect(engine.getVerificationWarnings()).toEqual([])
1793
+ })
1794
+
1795
+ it('should emit verification_skipped events when all platforms fail and ignoreVerifyErrors is enabled', async () => {
1796
+ const mockVerificationRegistry = new VerificationPlatformRegistry()
1797
+ const mockPlatform = {
1798
+ name: 'mock-platform',
1799
+ supportsNetwork: jest.fn().mockReturnValue(true),
1800
+ isConfigured: jest.fn().mockReturnValue(true),
1801
+ getConfigurationRequirements: jest.fn().mockReturnValue(''),
1802
+ isContractAlreadyVerified: jest.fn().mockResolvedValue(false),
1803
+ verifyContract: jest.fn().mockRejectedValue(new Error('Verification failed'))
1804
+ }
1805
+ mockVerificationRegistry.register(mockPlatform)
1806
+ mockVerificationRegistry.getConfiguredPlatforms = jest.fn().mockReturnValue([mockPlatform])
1807
+
1808
+ const mockEventEmitter = {
1809
+ emitEvent: jest.fn()
1810
+ }
1811
+
1812
+ engine = new ExecutionEngine(templates, {
1813
+ verificationRegistry: mockVerificationRegistry,
1814
+ ignoreVerifyErrors: true,
1815
+ eventEmitter: mockEventEmitter as any
1816
+ })
1817
+
1818
+ const mockContract = {
1819
+ sourceName: 'TestContract.sol',
1820
+ contractName: 'TestContract',
1821
+ compiler: { version: '0.8.0' },
1822
+ buildInfoId: 'test-build-id',
1823
+ source: 'contract TestContract { }',
1824
+ creationCode: '0x608060405234801561000f575f5ffd5b50602a5f526020601ff3',
1825
+ abi: [],
1826
+ _sources: new Set(['TestContract.sol', '/path/to/build-info/test.json'])
1827
+ }
1828
+
1829
+ context.contractRepository.addForTesting({
1830
+ contractName: mockContract.contractName,
1831
+ abi: mockContract.abi,
1832
+ bytecode: mockContract.creationCode,
1833
+ sourceName: mockContract.sourceName,
1834
+ source: mockContract.source,
1835
+ compiler: mockContract.compiler,
1836
+ buildInfoId: mockContract.buildInfoId,
1837
+ _path: '/test/path',
1838
+ _hash: 'test-hash'
1839
+ })
1840
+
1841
+ const action: Action = {
1842
+ type: 'verify-contract',
1843
+ name: 'test-verify',
1844
+ arguments: {
1845
+ address: TEST_ADDRESSES.RECIPIENT_1,
1846
+ contract: '{{Contract(TestContract)}}',
1847
+ platform: 'all'
1848
+ }
1849
+ }
1850
+
1851
+ await (engine as any).executePrimitive(action, context, new Map())
1852
+
1853
+ // Should emit verification_skipped event
1854
+ expect(mockEventEmitter.emitEvent).toHaveBeenCalledWith(
1855
+ expect.objectContaining({
1856
+ type: 'verification_skipped',
1857
+ level: 'warn',
1858
+ data: expect.objectContaining({
1859
+ actionName: 'test-verify',
1860
+ reason: expect.stringContaining('continuing due to --ignore-verify-errors')
1861
+ })
1862
+ })
1863
+ )
1864
+ })
1865
+ })
1545
1866
  })
@@ -1,7 +1,7 @@
1
1
  import { ethers } from 'ethers'
2
2
  import { ValueResolver } from '../resolver'
3
3
  import { ExecutionContext } from '../context'
4
- import { BasicArithmeticValue, Network, ReadBalanceValue, ComputeCreate2Value, ConstructorEncodeValue, AbiEncodeValue, AbiPackValue, CallValue, ContractExistsValue } from '../../types'
4
+ import { BasicArithmeticValue, Network, ReadBalanceValue, ComputeCreate2Value, ConstructorEncodeValue, AbiEncodeValue, AbiPackValue, CallValue, ContractExistsValue, ComputeCreateValue } from '../../types'
5
5
  import { ContractRepository } from '../../contracts/repository'
6
6
 
7
7
  describe('ValueResolver', () => {
@@ -494,6 +494,155 @@ describe('ValueResolver', () => {
494
494
  })
495
495
  })
496
496
 
497
+ describe('compute-create', () => {
498
+ it('should compute CREATE address with hardcoded test case 1', async () => {
499
+ const value: ComputeCreateValue = {
500
+ type: 'compute-create',
501
+ arguments: {
502
+ deployerAddress: '0x0000000000000000000000000000000000000000',
503
+ nonce: '0',
504
+ },
505
+ }
506
+ const result = await resolver.resolve(value, context)
507
+ expect(result).toBe('0xBd770416a3345F91E4B34576cb804a576fa48EB1')
508
+ })
509
+
510
+ it('should compute CREATE address with hardcoded test case 2', async () => {
511
+ const value: ComputeCreateValue = {
512
+ type: 'compute-create',
513
+ arguments: {
514
+ deployerAddress: '0xC6064FfBaDB0687Da29721C8EC02ACa71e735a3e',
515
+ nonce: '1',
516
+ },
517
+ }
518
+ const result = await resolver.resolve(value, context)
519
+ expect(result).toBe('0x6d2E686984620c01Af3cd125F9E1A2E23a972FFc')
520
+ })
521
+
522
+ it('should compute CREATE address with hardcoded test case 3', async () => {
523
+ const value: ComputeCreateValue = {
524
+ type: 'compute-create',
525
+ arguments: {
526
+ deployerAddress: '0xC6064FfBaDB0687Da29721C8EC02ACa71e735a3e',
527
+ nonce: '2',
528
+ },
529
+ }
530
+ const result = await resolver.resolve(value, context)
531
+ expect(result).toBe('0xBA6CfaFc33eD8229D2Af9a5a7BC22e8834cE0873')
532
+ })
533
+
534
+ it('should compute CREATE address with hardcoded test case ERC-2470', async () => {
535
+ const value: ComputeCreateValue = {
536
+ type: 'compute-create',
537
+ arguments: {
538
+ deployerAddress: '0xBb6e024b9cFFACB947A71991E386681B1Cd1477D',
539
+ nonce: '0',
540
+ },
541
+ }
542
+ const result = await resolver.resolve(value, context)
543
+ expect(result).toBe('0xce0042B868300000d44A59004Da54A005ffdcf9f')
544
+ })
545
+
546
+ it('should compute CREATE address with hardcoded test case Universal Deployer', async () => {
547
+ const value: ComputeCreateValue = {
548
+ type: 'compute-create',
549
+ arguments: {
550
+ deployerAddress: '0x9c5a87452d4FAC0cbd53BDCA580b20A45526B3AB',
551
+ nonce: '0',
552
+ },
553
+ }
554
+ const result = await resolver.resolve(value, context)
555
+ expect(result).toBe('0x1B926fBB24A9F78DCDd3272f2d86F5D0660E59c0')
556
+ })
557
+
558
+ it('should resolve values from context before computing CREATE address', async () => {
559
+ context.setOutput('myDeployer', '0x0000000000000000000000000000000000000000')
560
+ context.setOutput('myNonce', '0')
561
+
562
+ const value: ComputeCreateValue = {
563
+ type: 'compute-create',
564
+ arguments: {
565
+ deployerAddress: '{{myDeployer}}',
566
+ nonce: '{{myNonce}}',
567
+ },
568
+ }
569
+ const result = await resolver.resolve(value, context)
570
+ expect(result).toBe('0xBd770416a3345F91E4B34576cb804a576fa48EB1')
571
+ })
572
+
573
+ it('should throw error for invalid deployer address', async () => {
574
+ const value: ComputeCreateValue = {
575
+ type: 'compute-create',
576
+ arguments: {
577
+ deployerAddress: 'invalid-address',
578
+ nonce: '0',
579
+ },
580
+ }
581
+
582
+ await expect(resolver.resolve(value, context)).rejects.toThrow('Invalid deployer address: invalid-address')
583
+ })
584
+
585
+ it('should throw error for invalid nonce', async () => {
586
+ const value: ComputeCreateValue = {
587
+ type: 'compute-create',
588
+ arguments: {
589
+ deployerAddress: '0x0000000000000000000000000000000000000000',
590
+ nonce: 'invalid-nonce',
591
+ },
592
+ }
593
+
594
+ await expect(resolver.resolve(value, context)).rejects.toThrow('Invalid nonce: invalid-nonce')
595
+ })
596
+
597
+ it('should throw error for null deployer address', async () => {
598
+ const value: ComputeCreateValue = {
599
+ type: 'compute-create',
600
+ arguments: {
601
+ deployerAddress: null as any,
602
+ nonce: '0',
603
+ },
604
+ }
605
+
606
+ await expect(resolver.resolve(value, context)).rejects.toThrow('Invalid deployer address: null')
607
+ })
608
+
609
+ it('should throw error for undefined nonce', async () => {
610
+ const value: ComputeCreateValue = {
611
+ type: 'compute-create',
612
+ arguments: {
613
+ deployerAddress: '0x0000000000000000000000000000000000000000',
614
+ nonce: undefined as any,
615
+ },
616
+ }
617
+
618
+ await expect(resolver.resolve(value, context)).rejects.toThrow('Invalid nonce: undefined')
619
+ })
620
+
621
+ it('should handle checksummed addresses', async () => {
622
+ const value: ComputeCreateValue = {
623
+ type: 'compute-create',
624
+ arguments: {
625
+ deployerAddress: '0xdEADBEeF00000000000000000000000000000000',
626
+ nonce: '0',
627
+ },
628
+ }
629
+ const result = await resolver.resolve(value, context)
630
+ expect(result).toBe('0xf2048C36a5536FeA3Bc71d49ed59f2c65C546EEA')
631
+ })
632
+
633
+ it('should handle number nonce', async () => {
634
+ const value: ComputeCreateValue = {
635
+ type: 'compute-create',
636
+ arguments: {
637
+ deployerAddress: '0x0000000000000000000000000000000000000000',
638
+ nonce: 69420,
639
+ },
640
+ }
641
+ const result = await resolver.resolve(value, context)
642
+ expect(result).toBe('0x7Bd7F19787DA009bD75b849c92Db10CE11916487')
643
+ })
644
+ })
645
+
497
646
  describe('constructor-encode', () => {
498
647
  it('should encode creation code with no constructor arguments', async () => {
499
648
  const value = {