eco-solver 0.0.1-security → 1.5.2

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.

Potentially problematic release.


This version of eco-solver might be problematic. Click here for more details.

Files changed (244) hide show
  1. package/.eslintignore +8 -0
  2. package/.eslintrc.js +24 -0
  3. package/.github/workflows/ci.yaml +38 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +8 -0
  7. package/Dockerfile +11 -0
  8. package/LICENSE +21 -0
  9. package/README.md +29 -5
  10. package/config/default.ts +135 -0
  11. package/config/development.ts +95 -0
  12. package/config/preproduction.ts +17 -0
  13. package/config/production.ts +17 -0
  14. package/config/staging.ts +17 -0
  15. package/config/test.ts +7 -0
  16. package/index.js +43 -0
  17. package/jest.config.ts +14 -0
  18. package/nest-cli.json +8 -0
  19. package/package.json +117 -6
  20. package/src/api/api.module.ts +27 -0
  21. package/src/api/balance.controller.ts +41 -0
  22. package/src/api/quote.controller.ts +54 -0
  23. package/src/api/tests/balance.controller.spec.ts +113 -0
  24. package/src/api/tests/quote.controller.spec.ts +83 -0
  25. package/src/app.module.ts +74 -0
  26. package/src/balance/balance.module.ts +14 -0
  27. package/src/balance/balance.service.ts +230 -0
  28. package/src/balance/balance.ws.service.ts +104 -0
  29. package/src/balance/types.ts +16 -0
  30. package/src/bullmq/bullmq.helper.ts +41 -0
  31. package/src/bullmq/processors/eth-ws.processor.ts +47 -0
  32. package/src/bullmq/processors/inbox.processor.ts +55 -0
  33. package/src/bullmq/processors/interval.processor.ts +54 -0
  34. package/src/bullmq/processors/processor.module.ts +14 -0
  35. package/src/bullmq/processors/signer.processor.ts +41 -0
  36. package/src/bullmq/processors/solve-intent.processor.ts +73 -0
  37. package/src/bullmq/processors/tests/solve-intent.processor.spec.ts +3 -0
  38. package/src/bullmq/utils/queue.ts +22 -0
  39. package/src/chain-monitor/chain-monitor.module.ts +12 -0
  40. package/src/chain-monitor/chain-sync.service.ts +134 -0
  41. package/src/chain-monitor/tests/chain-sync.service.spec.ts +190 -0
  42. package/src/commander/.eslintrc.js +6 -0
  43. package/src/commander/balance/balance-command.module.ts +12 -0
  44. package/src/commander/balance/balance.command.ts +73 -0
  45. package/src/commander/command-main.ts +15 -0
  46. package/src/commander/commander-app.module.ts +31 -0
  47. package/src/commander/eco-config.command.ts +20 -0
  48. package/src/commander/safe/safe-command.module.ts +11 -0
  49. package/src/commander/safe/safe.command.ts +70 -0
  50. package/src/commander/transfer/client.command.ts +24 -0
  51. package/src/commander/transfer/transfer-command.module.ts +26 -0
  52. package/src/commander/transfer/transfer.command.ts +138 -0
  53. package/src/commander/utils.ts +8 -0
  54. package/src/common/chains/definitions/arbitrum.ts +12 -0
  55. package/src/common/chains/definitions/base.ts +21 -0
  56. package/src/common/chains/definitions/eco.ts +54 -0
  57. package/src/common/chains/definitions/ethereum.ts +22 -0
  58. package/src/common/chains/definitions/helix.ts +53 -0
  59. package/src/common/chains/definitions/mantle.ts +12 -0
  60. package/src/common/chains/definitions/optimism.ts +22 -0
  61. package/src/common/chains/definitions/polygon.ts +12 -0
  62. package/src/common/chains/supported.ts +26 -0
  63. package/src/common/chains/transport.ts +19 -0
  64. package/src/common/errors/eco-error.ts +155 -0
  65. package/src/common/events/constants.ts +3 -0
  66. package/src/common/events/viem.ts +22 -0
  67. package/src/common/logging/eco-log-message.ts +74 -0
  68. package/src/common/redis/constants.ts +55 -0
  69. package/src/common/redis/redis-connection-utils.ts +106 -0
  70. package/src/common/routes/constants.ts +3 -0
  71. package/src/common/utils/objects.ts +34 -0
  72. package/src/common/utils/strings.ts +49 -0
  73. package/src/common/utils/tests/objects.spec.ts +23 -0
  74. package/src/common/utils/tests/strings.spec.ts +22 -0
  75. package/src/common/viem/contracts.ts +25 -0
  76. package/src/common/viem/tests/utils.spec.ts +115 -0
  77. package/src/common/viem/utils.ts +78 -0
  78. package/src/contracts/ERC20.contract.ts +389 -0
  79. package/src/contracts/EntryPoint.V6.contract.ts +1309 -0
  80. package/src/contracts/KernelAccount.abi.ts +87 -0
  81. package/src/contracts/OwnableExecutor.abi.ts +128 -0
  82. package/src/contracts/SimpleAccount.contract.ts +524 -0
  83. package/src/contracts/inbox.ts +8 -0
  84. package/src/contracts/index.ts +9 -0
  85. package/src/contracts/intent-source.ts +55 -0
  86. package/src/contracts/interfaces/index.ts +1 -0
  87. package/src/contracts/interfaces/prover.interface.ts +22 -0
  88. package/src/contracts/prover.ts +9 -0
  89. package/src/contracts/tests/erc20.contract.spec.ts +59 -0
  90. package/src/contracts/utils.ts +31 -0
  91. package/src/decoder/decoder.interface.ts +3 -0
  92. package/src/decoder/tests/utils.spec.ts +36 -0
  93. package/src/decoder/utils.ts +24 -0
  94. package/src/decorators/cacheable.decorator.ts +48 -0
  95. package/src/eco-configs/aws-config.service.ts +75 -0
  96. package/src/eco-configs/eco-config.module.ts +44 -0
  97. package/src/eco-configs/eco-config.service.ts +220 -0
  98. package/src/eco-configs/eco-config.types.ts +278 -0
  99. package/src/eco-configs/interfaces/config-source.interface.ts +3 -0
  100. package/src/eco-configs/tests/aws-config.service.spec.ts +52 -0
  101. package/src/eco-configs/tests/eco-config.service.spec.ts +137 -0
  102. package/src/eco-configs/tests/utils.spec.ts +84 -0
  103. package/src/eco-configs/utils.ts +49 -0
  104. package/src/fee/fee.module.ts +10 -0
  105. package/src/fee/fee.service.ts +467 -0
  106. package/src/fee/tests/fee.service.spec.ts +909 -0
  107. package/src/fee/tests/utils.spec.ts +49 -0
  108. package/src/fee/types.ts +44 -0
  109. package/src/fee/utils.ts +23 -0
  110. package/src/flags/flags.module.ts +10 -0
  111. package/src/flags/flags.service.ts +112 -0
  112. package/src/flags/tests/flags.service.spec.ts +68 -0
  113. package/src/flags/utils.ts +22 -0
  114. package/src/health/constants.ts +1 -0
  115. package/src/health/health.controller.ts +23 -0
  116. package/src/health/health.module.ts +25 -0
  117. package/src/health/health.service.ts +40 -0
  118. package/src/health/indicators/balance.indicator.ts +196 -0
  119. package/src/health/indicators/eco-redis.indicator.ts +23 -0
  120. package/src/health/indicators/git-commit.indicator.ts +67 -0
  121. package/src/health/indicators/mongodb.indicator.ts +11 -0
  122. package/src/health/indicators/permission.indicator.ts +64 -0
  123. package/src/intent/create-intent.service.ts +129 -0
  124. package/src/intent/feasable-intent.service.ts +80 -0
  125. package/src/intent/fulfill-intent.service.ts +318 -0
  126. package/src/intent/intent.controller.ts +199 -0
  127. package/src/intent/intent.module.ts +49 -0
  128. package/src/intent/schemas/intent-call-data.schema.ts +16 -0
  129. package/src/intent/schemas/intent-data.schema.ts +114 -0
  130. package/src/intent/schemas/intent-source.schema.ts +33 -0
  131. package/src/intent/schemas/intent-token-amount.schema.ts +14 -0
  132. package/src/intent/schemas/reward-data.schema.ts +48 -0
  133. package/src/intent/schemas/route-data.schema.ts +52 -0
  134. package/src/intent/schemas/watch-event.schema.ts +32 -0
  135. package/src/intent/tests/create-intent.service.spec.ts +215 -0
  136. package/src/intent/tests/feasable-intent.service.spec.ts +155 -0
  137. package/src/intent/tests/fulfill-intent.service.spec.ts +564 -0
  138. package/src/intent/tests/utils-intent.service.spec.ts +308 -0
  139. package/src/intent/tests/utils.spec.ts +62 -0
  140. package/src/intent/tests/validate-intent.service.spec.ts +297 -0
  141. package/src/intent/tests/validation.service.spec.ts +337 -0
  142. package/src/intent/utils-intent.service.ts +168 -0
  143. package/src/intent/utils.ts +37 -0
  144. package/src/intent/validate-intent.service.ts +176 -0
  145. package/src/intent/validation.sevice.ts +223 -0
  146. package/src/interceptors/big-int.interceptor.ts +30 -0
  147. package/src/intervals/interval.module.ts +18 -0
  148. package/src/intervals/retry-infeasable-intents.service.ts +89 -0
  149. package/src/intervals/tests/retry-infeasable-intents.service.spec.ts +167 -0
  150. package/src/kms/errors.ts +0 -0
  151. package/src/kms/kms.module.ts +12 -0
  152. package/src/kms/kms.service.ts +65 -0
  153. package/src/kms/tests/kms.service.spec.ts +60 -0
  154. package/src/liquidity-manager/jobs/check-balances-cron.job.ts +229 -0
  155. package/src/liquidity-manager/jobs/liquidity-manager.job.ts +52 -0
  156. package/src/liquidity-manager/jobs/rebalance.job.ts +61 -0
  157. package/src/liquidity-manager/liquidity-manager.module.ts +29 -0
  158. package/src/liquidity-manager/processors/base.processor.ts +117 -0
  159. package/src/liquidity-manager/processors/eco-protocol-intents.processor.ts +34 -0
  160. package/src/liquidity-manager/processors/grouped-jobs.processor.ts +103 -0
  161. package/src/liquidity-manager/queues/liquidity-manager.queue.ts +48 -0
  162. package/src/liquidity-manager/schemas/rebalance-token.schema.ts +32 -0
  163. package/src/liquidity-manager/schemas/rebalance.schema.ts +32 -0
  164. package/src/liquidity-manager/services/liquidity-manager.service.ts +188 -0
  165. package/src/liquidity-manager/services/liquidity-provider.service.ts +25 -0
  166. package/src/liquidity-manager/services/liquidity-providers/LiFi/lifi-provider.service.spec.ts +125 -0
  167. package/src/liquidity-manager/services/liquidity-providers/LiFi/lifi-provider.service.ts +117 -0
  168. package/src/liquidity-manager/services/liquidity-providers/LiFi/utils/get-transaction-hashes.ts +16 -0
  169. package/src/liquidity-manager/tests/liquidity-manager.service.spec.ts +142 -0
  170. package/src/liquidity-manager/types/token-state.enum.ts +5 -0
  171. package/src/liquidity-manager/types/types.d.ts +52 -0
  172. package/src/liquidity-manager/utils/address.ts +5 -0
  173. package/src/liquidity-manager/utils/math.ts +9 -0
  174. package/src/liquidity-manager/utils/serialize.spec.ts +24 -0
  175. package/src/liquidity-manager/utils/serialize.ts +47 -0
  176. package/src/liquidity-manager/utils/token.ts +91 -0
  177. package/src/main.ts +63 -0
  178. package/src/nest-redlock/nest-redlock.config.ts +14 -0
  179. package/src/nest-redlock/nest-redlock.interface.ts +5 -0
  180. package/src/nest-redlock/nest-redlock.module.ts +64 -0
  181. package/src/nest-redlock/nest-redlock.service.ts +59 -0
  182. package/src/prover/proof.service.ts +184 -0
  183. package/src/prover/prover.module.ts +10 -0
  184. package/src/prover/tests/proof.service.spec.ts +154 -0
  185. package/src/quote/dto/quote.intent.data.dto.ts +35 -0
  186. package/src/quote/dto/quote.reward.data.dto.ts +67 -0
  187. package/src/quote/dto/quote.route.data.dto.ts +71 -0
  188. package/src/quote/dto/types.ts +18 -0
  189. package/src/quote/errors.ts +215 -0
  190. package/src/quote/quote.module.ts +17 -0
  191. package/src/quote/quote.service.ts +299 -0
  192. package/src/quote/schemas/quote-call.schema.ts +16 -0
  193. package/src/quote/schemas/quote-intent.schema.ts +27 -0
  194. package/src/quote/schemas/quote-reward.schema.ts +24 -0
  195. package/src/quote/schemas/quote-route.schema.ts +30 -0
  196. package/src/quote/schemas/quote-token.schema.ts +14 -0
  197. package/src/quote/tests/quote.service.spec.ts +444 -0
  198. package/src/sign/atomic-signer.service.ts +24 -0
  199. package/src/sign/atomic.nonce.service.ts +114 -0
  200. package/src/sign/kms-account/kmsToAccount.ts +73 -0
  201. package/src/sign/kms-account/signKms.ts +30 -0
  202. package/src/sign/kms-account/signKmsTransaction.ts +37 -0
  203. package/src/sign/kms-account/signKmsTypedData.ts +21 -0
  204. package/src/sign/nonce.service.ts +89 -0
  205. package/src/sign/schemas/nonce.schema.ts +36 -0
  206. package/src/sign/sign.controller.ts +52 -0
  207. package/src/sign/sign.helper.ts +23 -0
  208. package/src/sign/sign.module.ts +27 -0
  209. package/src/sign/signer-kms.service.ts +27 -0
  210. package/src/sign/signer.service.ts +26 -0
  211. package/src/solver/filters/tests/valid-smart-wallet.service.spec.ts +87 -0
  212. package/src/solver/filters/valid-smart-wallet.service.ts +58 -0
  213. package/src/solver/solver.module.ts +10 -0
  214. package/src/transaction/multichain-public-client.service.ts +15 -0
  215. package/src/transaction/smart-wallets/kernel/actions/encodeData.kernel.ts +57 -0
  216. package/src/transaction/smart-wallets/kernel/create-kernel-client-v2.account.ts +183 -0
  217. package/src/transaction/smart-wallets/kernel/create.kernel.account.ts +270 -0
  218. package/src/transaction/smart-wallets/kernel/index.ts +2 -0
  219. package/src/transaction/smart-wallets/kernel/kernel-account-client-v2.service.ts +90 -0
  220. package/src/transaction/smart-wallets/kernel/kernel-account-client.service.ts +107 -0
  221. package/src/transaction/smart-wallets/kernel/kernel-account.client.ts +105 -0
  222. package/src/transaction/smart-wallets/kernel/kernel-account.config.ts +34 -0
  223. package/src/transaction/smart-wallets/simple-account/create.simple.account.ts +19 -0
  224. package/src/transaction/smart-wallets/simple-account/index.ts +2 -0
  225. package/src/transaction/smart-wallets/simple-account/simple-account-client.service.ts +42 -0
  226. package/src/transaction/smart-wallets/simple-account/simple-account.client.ts +83 -0
  227. package/src/transaction/smart-wallets/simple-account/simple-account.config.ts +5 -0
  228. package/src/transaction/smart-wallets/smart-wallet.types.ts +38 -0
  229. package/src/transaction/smart-wallets/utils.ts +14 -0
  230. package/src/transaction/transaction.module.ts +25 -0
  231. package/src/transaction/viem_multichain_client.service.ts +100 -0
  232. package/src/transforms/viem-address.decorator.ts +14 -0
  233. package/src/utils/bigint.ts +44 -0
  234. package/src/utils/types.ts +18 -0
  235. package/src/watch/intent/tests/watch-create-intent.service.spec.ts +257 -0
  236. package/src/watch/intent/tests/watch-fulfillment.service.spec.ts +141 -0
  237. package/src/watch/intent/watch-create-intent.service.ts +106 -0
  238. package/src/watch/intent/watch-event.service.ts +133 -0
  239. package/src/watch/intent/watch-fulfillment.service.ts +115 -0
  240. package/src/watch/watch.module.ts +13 -0
  241. package/test/app.e2e-spec.ts +21 -0
  242. package/test/jest-e2e.json +9 -0
  243. package/tsconfig.build.json +4 -0
  244. package/tsconfig.json +29 -0
@@ -0,0 +1,54 @@
1
+ import { defineChain } from 'viem'
2
+ import { chainConfig } from 'viem/op-stack'
3
+
4
+ // settlement chain
5
+ const sourceId = 84532 //base sepolia
6
+
7
+ export const ecoSepolia = /*#__PURE__*/ defineChain({
8
+ ...chainConfig,
9
+ id: 471923,
10
+ name: 'Eco Test',
11
+ nativeCurrency: { name: 'Sepolia Ether', symbol: 'ETH', decimals: 18 },
12
+ rpcUrls: {
13
+ default: {
14
+ http: ['https://eco-testnet.rpc.caldera.xyz/http'],
15
+ webSocket: ['wss://eco-testnet.rpc.caldera.xyz/ws'],
16
+ },
17
+ },
18
+ blockExplorers: {
19
+ default: {
20
+ name: 'eco-testnet explorer',
21
+ url: 'https://eco-testnet.explorer.caldera.xyz/',
22
+ apiUrl: 'https://eco-testnet.explorer.caldera.xyz/api/v2',
23
+ },
24
+ },
25
+ contracts: {
26
+ ...chainConfig.contracts,
27
+ disputeGameFactory: {
28
+ [sourceId]: {
29
+ address: '0x01C6834a6EA1bd8CD69F38D5E657B53BdA53d684',
30
+ },
31
+ },
32
+ l2OutputOracle: {
33
+ [sourceId]: {
34
+ address: '0xb3EDAE5AB86f16242018c7cED4fBCabb3c784951',
35
+ },
36
+ },
37
+ multicall3: {
38
+ address: '0xcA11bde05977b3631167028862bE2a173976CA11',
39
+ blockCreated: 4286263,
40
+ },
41
+ portal: {
42
+ [sourceId]: {
43
+ address: '0xb94EFa2bba9d52A67944c4bE1014D1A09F5d8939',
44
+ },
45
+ },
46
+ l1StandardBridge: {
47
+ [sourceId]: {
48
+ address: '0x635f8f0Ae3fEE30C408C5c4E0C44115a2d636e29',
49
+ },
50
+ },
51
+ },
52
+ sourceId,
53
+ testnet: true,
54
+ })
@@ -0,0 +1,22 @@
1
+ import { Chain } from 'viem'
2
+ import { mainnet as vmainnet, sepolia as vsepolia } from 'viem/chains'
3
+
4
+ export const ethereum: Chain = {
5
+ ...vmainnet,
6
+ rpcUrls: {
7
+ ...vmainnet.rpcUrls,
8
+ alchemy: {
9
+ http: ['https://eth-mainnet.g.alchemy.com/v2'],
10
+ },
11
+ },
12
+ }
13
+
14
+ export const sepolia: Chain = {
15
+ ...vsepolia,
16
+ rpcUrls: {
17
+ ...vsepolia.rpcUrls,
18
+ alchemy: {
19
+ http: ['https://eth-sepolia.g.alchemy.com/v2'],
20
+ },
21
+ },
22
+ }
@@ -0,0 +1,53 @@
1
+ import { defineChain } from 'viem'
2
+ import { chainConfig } from 'viem/op-stack'
3
+
4
+ // settlement chain
5
+ const sourceId = 8453 //base mainnet
6
+
7
+ export const helix = /*#__PURE__*/ defineChain({
8
+ ...chainConfig,
9
+ id: 8921733,
10
+ name: 'Helix Test',
11
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
12
+ rpcUrls: {
13
+ default: {
14
+ http: ['https://helix-test.calderachain.xyz/http'],
15
+ webSocket: ['wss://helix-test.calderachain.xyz/ws'],
16
+ },
17
+ },
18
+ blockExplorers: {
19
+ default: {
20
+ name: 'helix-test explorer',
21
+ url: 'https://helix-test.calderaexplorer.xyz',
22
+ apiUrl: 'https://helix-test.calderaexplorer.xyz/api/v2',
23
+ },
24
+ },
25
+ contracts: {
26
+ ...chainConfig.contracts,
27
+ disputeGameFactory: {
28
+ [sourceId]: {
29
+ address: '0x685eeDFd7280cbdC1B49E766a06b31D00dAEab2b',
30
+ },
31
+ },
32
+ l2OutputOracle: {
33
+ [sourceId]: {
34
+ address: '0xf3B21c72BFd684eC459697c48f995CDeb5E5DB9d',
35
+ },
36
+ },
37
+ multicall3: {
38
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
39
+ blockCreated: 4286263,
40
+ },
41
+ portal: {
42
+ [sourceId]: {
43
+ address: '0x8C3df798e9CA0826Cb9DB3530635aa719EB1E562',
44
+ },
45
+ },
46
+ l1StandardBridge: {
47
+ [sourceId]: {
48
+ address: '0xe746B6ac4c5Fca4770e0468D9aA62CbE6c55803A',
49
+ },
50
+ },
51
+ },
52
+ sourceId,
53
+ })
@@ -0,0 +1,12 @@
1
+ import { Chain } from 'viem'
2
+ import { mantle as vmantle } from 'viem/chains'
3
+
4
+ export const mantle: Chain = {
5
+ ...vmantle,
6
+ rpcUrls: {
7
+ ...vmantle.rpcUrls,
8
+ alchemy: {
9
+ http: ['https://mantle-mainnet.g.alchemy.com/v2'],
10
+ },
11
+ },
12
+ }
@@ -0,0 +1,22 @@
1
+ import { Chain } from 'viem'
2
+ import { optimism as vop, optimismSepolia as vops } from 'viem/chains'
3
+
4
+ export const optimism: Chain = {
5
+ ...vop,
6
+ rpcUrls: {
7
+ ...vop.rpcUrls,
8
+ alchemy: {
9
+ http: ['https://opt-mainnet.g.alchemy.com/v2'],
10
+ },
11
+ },
12
+ }
13
+
14
+ export const optimismSepolia: Chain = {
15
+ ...vops,
16
+ rpcUrls: {
17
+ ...vops.rpcUrls,
18
+ alchemy: {
19
+ http: ['https://opt-sepolia.g.alchemy.com/v2'],
20
+ },
21
+ },
22
+ }
@@ -0,0 +1,12 @@
1
+ import { Chain } from 'viem'
2
+ import { polygon as vpolygon } from 'viem/chains'
3
+
4
+ export const polygon: Chain = {
5
+ ...vpolygon,
6
+ rpcUrls: {
7
+ ...vpolygon.rpcUrls,
8
+ alchemy: {
9
+ http: ['https://polygon-mainnet.g.alchemy.com/v2'],
10
+ },
11
+ },
12
+ }
@@ -0,0 +1,26 @@
1
+ import { Chain } from 'viem'
2
+ import { ecoSepolia } from './definitions/eco'
3
+ import { helix } from './definitions/helix'
4
+ import { optimism, optimismSepolia } from './definitions/optimism'
5
+ import { base, baseSepolia } from './definitions/base'
6
+ import { arbitrum } from './definitions/arbitrum'
7
+ import { mantle } from './definitions/mantle'
8
+ import { polygon } from './definitions/polygon'
9
+ import { ethereum, sepolia } from './definitions/ethereum'
10
+
11
+ /**
12
+ * List of supported chains for the solver that have modified RPC URLs or are defined in the project
13
+ */
14
+ export const ChainsSupported: Chain[] = [
15
+ optimism,
16
+ optimismSepolia,
17
+ base,
18
+ baseSepolia,
19
+ ecoSepolia,
20
+ helix,
21
+ arbitrum,
22
+ mantle,
23
+ polygon,
24
+ ethereum,
25
+ sepolia,
26
+ ]
@@ -0,0 +1,19 @@
1
+ import { Chain, http, HttpTransport, webSocket, WebSocketTransport } from 'viem'
2
+ import { getRpcUrl } from '../viem/utils'
3
+
4
+ /**
5
+ * Returns a transport for the chain with the given api key
6
+ *
7
+ * @param chain the chain to get the transport for
8
+ * @param apiKey the alchemy api key
9
+ * @param websocketEnabled whether to use websocket or not, defaults to true
10
+ * @returns the websocket or http transport
11
+ */
12
+ export function getTransport(
13
+ chain: Chain,
14
+ apiKey?: string,
15
+ websocketEnabled: boolean = false,
16
+ ): WebSocketTransport | HttpTransport {
17
+ const { url, isWebsocket } = getRpcUrl(chain, apiKey, websocketEnabled)
18
+ return isWebsocket ? webSocket(url, { keepAlive: true, reconnect: true }) : http(url)
19
+ }
@@ -0,0 +1,155 @@
1
+ import { Network } from 'alchemy-sdk'
2
+ import { Logger } from '@nestjs/common'
3
+ import * as _ from 'lodash'
4
+ import { EcoLogMessage } from '../logging/eco-log-message'
5
+ import { Chain, TransactionReceipt } from 'viem'
6
+ import { AwsCredential } from '@/eco-configs/eco-config.types'
7
+
8
+ export class EcoError extends Error {
9
+ // Alchemy Service
10
+ static AlchemyUnsupportedNetworkError(network: Network) {
11
+ return new EcoError(`App does not support network ${network}, check your config file`)
12
+ }
13
+ static AlchemyUnsupportedNetworkIDError(id: number) {
14
+ return new EcoError(`App does not support network ${id}, check your config file`)
15
+ }
16
+
17
+ static AlchemyServiceProviderError(network: string) {
18
+ return new EcoError(`Could not create alchemy provider ${network}`)
19
+ }
20
+
21
+ static BalanceServiceInvalidDecimals(address: string) {
22
+ return new EcoError(`Token has to be decimals 6, verify conversions before allowing ${address}`)
23
+ }
24
+
25
+ static IntentSourceDataNotFound(intentHash: string) {
26
+ return new EcoError(`Could not find data for intent hash ${intentHash}`)
27
+ }
28
+
29
+ static IntentValidationFailed(hash: string) {
30
+ return new EcoError(`Intent validation failed for intent hash ${hash}`)
31
+ }
32
+
33
+ static IntentSourceNotFound(chainID: number) {
34
+ return new EcoError(`Could not find an intent source for chain ${chainID}`)
35
+ }
36
+
37
+ static IntentSourceDataInvalidParams = new Error(
38
+ 'IntentSource calls or tokens must have non-zero length',
39
+ )
40
+
41
+ static IntentSourceTargetConfigNotFound(target: string) {
42
+ return new EcoError(`Solver does not have target: ${target}`)
43
+ }
44
+
45
+ static TargetSelectorNotSupported(target: string) {
46
+ return new EcoError(`Solver does not have target: ${target}`)
47
+ }
48
+
49
+ static IntentSourceUnsupportedTargetType(targetType: string) {
50
+ return new EcoError(`Unsupported target type ${targetType}`)
51
+ }
52
+
53
+ static ChainConfigNotFound(chainID: string) {
54
+ return new EcoError(`Chain config not found for chain ${chainID}`)
55
+ }
56
+
57
+ static InvalidSimpleAccountConfig() {
58
+ return new EcoError(`The simple account config is invalid`)
59
+ }
60
+
61
+ static InvalidKernelAccountConfig() {
62
+ return new EcoError(`The kernel account config is invalid`)
63
+ }
64
+
65
+ static FeasibilityIntentNoTransactionError = new Error('No transaction data found')
66
+ static FulfillIntentNoTransactionError = new Error('No transaction data found')
67
+ static FulfillIntentBatchError = new Error('Could not fulfill batch transaction')
68
+ static FulfillIntentRevertError(receipt: TransactionReceipt) {
69
+ const msg = JSON.stringify(receipt, (_, v) => (typeof v === 'bigint' ? v.toString() : v))
70
+ return new Error(msg)
71
+ }
72
+
73
+ // ValidateIntent Service
74
+ static ValidateIntentDescructureFailed(err?: Error) {
75
+ return err || new Error('Desctructuring the intent from the intent hash failed')
76
+ }
77
+
78
+ // WatchIntent Service
79
+ static WatchEventUnsubscribeError = new Error('Could not unsubscribe from watch event')
80
+ static WatchEventUnsubscribeFromError(chainID: number) {
81
+ return new Error(`Could not unsubscribe from watch event for chain : ${chainID}`)
82
+ }
83
+ static WatchEventNoUnsubscribeError(chainID: number) {
84
+ return new Error(`There is no unwatch for chain : ${chainID}`)
85
+ }
86
+
87
+ // Viem
88
+
89
+ static UnsupportedChainError(chain: Chain) {
90
+ return new EcoError(
91
+ `App does not support chain ${chain.id}:${chain.name}, check your config file`,
92
+ )
93
+ }
94
+
95
+ static KmsCredentialsError(config?: AwsCredential) {
96
+ return new EcoError(`Could not get AWS KMS credentials: ${config}`)
97
+ }
98
+
99
+ // EcoConfig Service
100
+
101
+ static isEcoError(error: any): boolean {
102
+ return error instanceof EcoError
103
+ }
104
+
105
+ static getErrorObject(error: any): Error {
106
+ if (error instanceof Error) {
107
+ return error
108
+ }
109
+
110
+ return new Error(this.getErrorMessage(error))
111
+ }
112
+
113
+ static logErrorWithStack(error: any, caller: string, srcLogger: Logger, properties: object = {}) {
114
+ return this._logError(this.getErrorObject(error), caller, srcLogger, properties, true)
115
+ }
116
+
117
+ static _logError(
118
+ error: Error,
119
+ caller: string,
120
+ srcLogger: Logger,
121
+ properties: object,
122
+ logStack?: boolean,
123
+ ) {
124
+ srcLogger.error(
125
+ EcoLogMessage.fromDefault({
126
+ message: `${caller}: error`,
127
+ properties: {
128
+ error: error.message,
129
+ ...properties,
130
+ },
131
+ }),
132
+
133
+ logStack && error.stack,
134
+ )
135
+ }
136
+
137
+ static getErrorMessage(error: any): string {
138
+ if (_.isString(error)) {
139
+ return error
140
+ }
141
+
142
+ if (EcoError.isEcoError(error)) {
143
+ return error.toString()
144
+ }
145
+
146
+ return (
147
+ error.body ||
148
+ error.error?.reason ||
149
+ error.reason ||
150
+ error.message ||
151
+ error.enumKey ||
152
+ 'Unexpected error occurred'
153
+ )
154
+ }
155
+ }
@@ -0,0 +1,3 @@
1
+ export const EVENTS = {
2
+ SOURCE_INTENT_CREATED: 'source_intent.created',
3
+ }
@@ -0,0 +1,22 @@
1
+ import { Log } from 'viem'
2
+
3
+ /**
4
+ * {
5
+ blockNumber: 14672041,
6
+ blockHash: '0x8bc8fd6c46154a8b58b14ebfeb0a11e912eeb590b12a21d56a003269f8ed07f4',
7
+ transactionIndex: 1,
8
+ removed: false,
9
+ address: '0x6B79cD3fE2Eccd3a69c52e621a81d26E75983787',
10
+ data: '0x00000000000000000000000013e12300ad48e11df1b2d7b0f4d276e138cc566d00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000020059e4a58f9021a6f643125c738ee2b329b2233465b89bb3bcb4f22e3774c562310000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ab1d243b07e99c91de9e4b80dfc2b07a8332a2f7000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000cd80b973e7cbb93c21cc5ac0a5f45d12a32582aa00000000000000000000000000000000000000000000000000000000000004d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d2d1162c689179e8ba7a3b936f80a010a0b5cf000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000004d2',
11
+ topics: [
12
+ '0x4d57d71884135619aa0097f5e665cc0257fcf37b35433f4b554f57a182e77416',
13
+ '0x341c195547c8becccdcb8390a2fd8bc416316224d7d4e1938137d45829407044',
14
+ '0x0000000000000000000000000000000000000000000000000000000000014a34',
15
+ '0x000000000000000000000000000000000000000000000000000000006696ab0a'
16
+ ],
17
+ transactionHash: '0xea380e5bc9ee1c4e196ac7548881fefaf9e5cc033aca8cdac9764cebd0b2d743',
18
+ logIndex: 2
19
+ }
20
+ */
21
+
22
+ export type ViemEventLog = Log & { sourceNetwork: string; sourceChainID: bigint }
@@ -0,0 +1,74 @@
1
+ import { EcoError } from '../errors/eco-error'
2
+
3
+ interface BaseLoggingDataParams {
4
+ message: string
5
+ properties?: object
6
+ }
7
+
8
+ interface LoggingDataParamsWithUser extends BaseLoggingDataParams {
9
+ userID: string
10
+ }
11
+
12
+ interface LoggingDataParamsWithError extends BaseLoggingDataParams {
13
+ error: EcoError
14
+ }
15
+
16
+ interface LoggingDataParamsWithErrorAndUser extends LoggingDataParamsWithError {
17
+ userID: string
18
+ }
19
+
20
+ export class EcoLogMessage {
21
+ private readonly _content: object
22
+
23
+ private constructor(params: BaseLoggingDataParams) {
24
+ this._content = {
25
+ msg: params.message,
26
+ ...params.properties,
27
+ }
28
+ }
29
+
30
+ get content(): object {
31
+ return this._content
32
+ }
33
+
34
+ static fromDefault(params: BaseLoggingDataParams): object {
35
+ return new EcoLogMessage(params).content
36
+ }
37
+
38
+ static withUser(params: LoggingDataParamsWithUser): object {
39
+ const { message, userID, properties } = params
40
+
41
+ return this.fromDefault({
42
+ message,
43
+ properties: {
44
+ userID,
45
+ ...properties,
46
+ },
47
+ })
48
+ }
49
+
50
+ static withError(params: LoggingDataParamsWithError): object {
51
+ const { message, error, properties } = params
52
+
53
+ return this.fromDefault({
54
+ message,
55
+ properties: {
56
+ error: error.toString(),
57
+ ...properties,
58
+ },
59
+ })
60
+ }
61
+
62
+ static withErrorAndUser(params: LoggingDataParamsWithErrorAndUser): object {
63
+ const { message, userID, error, properties } = params
64
+
65
+ return this.fromDefault({
66
+ message,
67
+ properties: {
68
+ userID,
69
+ error: error.toString(),
70
+ ...properties,
71
+ },
72
+ })
73
+ }
74
+ }
@@ -0,0 +1,55 @@
1
+ export const QUEUES: Record<any, QueueInterface> = {
2
+ SOURCE_INTENT: {
3
+ queue: 'source_intent',
4
+ prefix: '{source-intent}',
5
+ jobs: {
6
+ create_intent: 'create_intent',
7
+ validate_intent: 'validate_intent',
8
+ feasable_intent: 'feasable_intent',
9
+ fulfill_intent: 'fulfill_intent',
10
+ retry_intent: 'retry_intent',
11
+ },
12
+ },
13
+ INTERVAL: {
14
+ queue: 'interval',
15
+ prefix: '{interval}',
16
+ jobs: {
17
+ retry_infeasable_intents: 'retry_infeasable_intents',
18
+ },
19
+ },
20
+ INBOX: {
21
+ queue: 'inbox',
22
+ prefix: '{inbox}',
23
+ jobs: {
24
+ fulfillment: 'fulfillment',
25
+ },
26
+ },
27
+ ETH_SOCKET: {
28
+ queue: 'eth_socket',
29
+ prefix: '{eth_socket}',
30
+ jobs: {
31
+ erc20_balance_socket: 'erc20_balance_socket',
32
+ },
33
+ },
34
+ SIGNER: {
35
+ queue: 'signer',
36
+ prefix: '{signer}',
37
+ jobs: {
38
+ nonce_sync: 'nonce_sync',
39
+ },
40
+ },
41
+ SOLVER: {
42
+ queue: 'solver',
43
+ prefix: '{solver}',
44
+ jobs: {},
45
+ },
46
+ }
47
+
48
+ export interface QueueMetadata {
49
+ queue: string
50
+ prefix: string
51
+ }
52
+
53
+ export interface QueueInterface extends QueueMetadata {
54
+ jobs: Record<string, string>
55
+ }
@@ -0,0 +1,106 @@
1
+ import { Logger } from '@nestjs/common'
2
+ import { RegisterQueueOptions } from '@nestjs/bullmq'
3
+ import * as Redis from 'ioredis'
4
+ import { EcoError } from '../errors/eco-error'
5
+ import { EcoLogMessage } from '../logging/eco-log-message'
6
+ import { QueueMetadata } from './constants'
7
+ import { RedisConfig } from '../../eco-configs/eco-config.types'
8
+ import { RedlockRedisClient } from '../../nest-redlock/nest-redlock.service'
9
+
10
+ export class RedisConnectionUtils {
11
+ private static logger = new Logger(RedisConnectionUtils.name)
12
+
13
+ static getRedisConnection(redisConfig: RedisConfig): Redis.Redis | Redis.Cluster {
14
+ const connection = redisConfig.connection
15
+
16
+ if (this.isClusterConnection(connection)) {
17
+ return new Redis.Cluster(
18
+ connection as Redis.ClusterNode[],
19
+ RedisConnectionUtils.getClusterOptions(redisConfig),
20
+ )
21
+ }
22
+
23
+ return new Redis.Redis(connection as Redis.RedisOptions)
24
+ }
25
+
26
+ static getQueueOptions(queue: QueueMetadata, redisConfig: RedisConfig): RegisterQueueOptions {
27
+ try {
28
+ const connection = redisConfig.connection
29
+ const { queue: name, prefix } = queue
30
+
31
+ if (this.isClusterConnection(connection)) {
32
+ return this.getQueueOptionsForCluster(
33
+ name,
34
+ prefix,
35
+ connection as Redis.ClusterNode[],
36
+ redisConfig,
37
+ )
38
+ }
39
+
40
+ return {
41
+ name,
42
+ prefix,
43
+ connection,
44
+ } as RegisterQueueOptions
45
+ } catch (ex) {
46
+ EcoError.logErrorWithStack(
47
+ ex.message,
48
+ `getQueueOptions: Invalid queue configuration`,
49
+ this.logger,
50
+ {
51
+ queue,
52
+ },
53
+ )
54
+
55
+ throw ex
56
+ }
57
+ }
58
+
59
+ static getClientsForRedlock(redisConfig: RedisConfig): RedlockRedisClient[] {
60
+ const connection = redisConfig.connection
61
+ if (this.isClusterConnection(connection)) {
62
+ return [
63
+ new Redis.Cluster(
64
+ connection as Redis.ClusterNode[],
65
+ RedisConnectionUtils.getClusterOptions(redisConfig),
66
+ ),
67
+ ]
68
+ }
69
+
70
+ return [new Redis.Redis(connection as Redis.RedisOptions)]
71
+ }
72
+
73
+ private static isClusterConnection(connection: Redis.ClusterNode | Redis.ClusterNode[]): boolean {
74
+ return Array.isArray(connection)
75
+ }
76
+
77
+ private static getQueueOptionsForCluster(
78
+ name: string,
79
+ prefix: string,
80
+ connection: Redis.ClusterNode[],
81
+ redisConfig: RedisConfig,
82
+ ): RegisterQueueOptions {
83
+ // Setup a cluster.
84
+ this.logger.debug(
85
+ EcoLogMessage.fromDefault({
86
+ message: `getQueueOptionsForCluster: Setting up a redis cluster`,
87
+ }),
88
+ )
89
+
90
+ return {
91
+ name,
92
+ prefix,
93
+ connection: new Redis.Cluster(
94
+ connection,
95
+ RedisConnectionUtils.getClusterOptions(redisConfig),
96
+ ),
97
+ } as RegisterQueueOptions
98
+ }
99
+
100
+ private static getClusterOptions(redisConfig: RedisConfig): Redis.ClusterOptions {
101
+ return {
102
+ ...redisConfig.options.cluster,
103
+ redisOptions: redisConfig.options.single,
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,3 @@
1
+ export const API_ROOT = '/api/v1'
2
+ export const BALANCE_ROUTE = '/balance'
3
+ export const QUOTE_ROUTE = '/quote'
@@ -0,0 +1,34 @@
1
+ import { Hex, keccak256, toBytes } from 'viem'
2
+
3
+ /**
4
+ * Deterministically serializes an object into a JSON string
5
+ */
6
+ export function serializeObject(obj: object): string {
7
+ return JSON.stringify(obj, Object.keys(obj).sort())
8
+ }
9
+
10
+ /**
11
+ * Hashes an object using keccak256
12
+ */
13
+ export function hashObject(obj: object): Hex {
14
+ const json = serializeObject(obj)
15
+ const hash = keccak256(toBytes(json))
16
+ return hash
17
+ }
18
+
19
+ /**
20
+ * Lowercase all top-level keys of the given `object` to lowercase.
21
+ *
22
+ * @returns {Object}
23
+ */
24
+ export function lowercaseKeys(obj: Record<string, any>): Record<string, any> | undefined {
25
+ if (!obj) {
26
+ return undefined
27
+ }
28
+
29
+ return Object.entries(obj).reduce((carry, [key, value]) => {
30
+ carry[key.toLowerCase()] = value
31
+
32
+ return carry
33
+ }, {})
34
+ }