eco-solver 0.0.1-security → 1.5.1

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 +115 -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,278 @@
1
+ import { Network } from 'alchemy-sdk'
2
+ import { ClusterNode } from 'ioredis'
3
+ import { Params as PinoParams } from 'nestjs-pino'
4
+ import * as Redis from 'ioredis'
5
+ import { Settings } from 'redlock'
6
+ import { JobsOptions, RepeatOptions } from 'bullmq'
7
+ import { Hex } from 'viem'
8
+ import { LDOptions } from '@launchdarkly/node-server-sdk'
9
+ import { CacheModuleOptions } from '@nestjs/cache-manager'
10
+
11
+ // The config type that we store in json
12
+ export type EcoConfigType = {
13
+ server: {
14
+ url: string
15
+ }
16
+ safe: SafeType
17
+ externalAPIs: unknown
18
+ redis: RedisConfig
19
+ intervals: IntervalConfig
20
+ intentConfigs: IntentConfig
21
+ alchemy: AlchemyConfigType
22
+ cache: CacheModuleOptions
23
+ launchDarkly: LaunchDarklyConfig
24
+ eth: {
25
+ privateKey: string
26
+ simpleAccount: {
27
+ walletAddr: Hex
28
+ signerPrivateKey: Hex
29
+ minEthBalanceWei: number
30
+ contracts: {
31
+ entryPoint: {
32
+ contractAddress: Hex
33
+ }
34
+ paymaster: {
35
+ contractAddresses: Hex[]
36
+ }
37
+ simpleAccountFactory: {
38
+ contractAddress: Hex
39
+ }
40
+ }
41
+ }
42
+ claimant: Hex
43
+ nonce: {
44
+ update_interval_ms: number
45
+ }
46
+ pollingInterval: number
47
+ }
48
+ fulfill: FulfillType
49
+ aws: AwsCredential[]
50
+ kms: KmsConfig
51
+ whitelist: WhitelistFeeRecord
52
+ database: {
53
+ auth: MongoAuthType
54
+ uriPrefix: string
55
+ uri: string
56
+ dbName: string
57
+ enableJournaling: boolean
58
+ }
59
+ intentSources: IntentSource[]
60
+ //chainID to Solver type mapping
61
+ solvers: Record<number, Solver>
62
+ logger: {
63
+ usePino: boolean
64
+ pinoConfig: PinoParams
65
+ }
66
+ liquidityManager: LiquidityManagerConfig
67
+ }
68
+
69
+ export type EcoConfigKeys = keyof EcoConfigType
70
+
71
+ /**
72
+ * The config type for the launch darkly feature flagging service
73
+ */
74
+ export type LaunchDarklyConfig = {
75
+ apiKey: string
76
+ options?: LDOptions
77
+ }
78
+
79
+ /**
80
+ * The configs for the fulfillment params
81
+ */
82
+ export type FulfillType = {
83
+ run: 'batch' | 'single'
84
+ }
85
+
86
+ /**
87
+ * The config type for the safe multisig wallet
88
+ */
89
+ export type SafeType = {
90
+ owner: Hex
91
+ }
92
+
93
+ /**
94
+ * The config type for the redis section
95
+ */
96
+ export type RedisConfig = {
97
+ connection: ClusterNode | ClusterNode[]
98
+ options: {
99
+ single: Redis.RedisOptions
100
+ cluster: Redis.ClusterOptions
101
+ }
102
+ redlockSettings?: Partial<Settings>
103
+ jobs: {
104
+ intentJobConfig: JobsOptions
105
+ }
106
+ }
107
+
108
+ /**
109
+ * The config type for the intervals section
110
+ */
111
+ export type IntervalConfig = {
112
+ retryInfeasableIntents: {
113
+ repeatOpts: Omit<RepeatOptions, 'key'>
114
+ jobTemplate: {
115
+ name?: string
116
+ opts: Omit<JobsOptions, 'jobId' | 'repeat' | 'delay'>
117
+ }
118
+ }
119
+ defaults: {
120
+ repeatOpts: Omit<RepeatOptions, 'key'>
121
+ jobTemplate?: {
122
+ name?: string
123
+ opts?: Omit<JobsOptions, 'jobId' | 'repeat' | 'delay'>
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * The config type for the intent section
130
+ */
131
+ export type IntentConfig = {
132
+ defaultFee: FeeConfigType
133
+ proofs: {
134
+ storage_duration_seconds: number
135
+ hyperlane_duration_seconds: number
136
+ }
137
+ }
138
+
139
+ /**
140
+ * The config type for the aws credentials
141
+ */
142
+ export type AwsCredential = {
143
+ region: string
144
+ secretID: string
145
+ }
146
+
147
+ /**
148
+ * The config type for the aws kms
149
+ */
150
+ export type KmsConfig = {
151
+ region: string
152
+ keyID: string
153
+ }
154
+
155
+ /**
156
+ * The config type for a ERC20 transfer
157
+ */
158
+ export type FeeConfigType = {
159
+ //the maximum amount of tokens that can be filled in a single transaction,
160
+ //defaults to 1000 USDC decimal 6 equivalent {@link ValidationService.DEFAULT_MAX_FILL_BASE_6}
161
+ limitFillBase6: bigint
162
+ algorithm: FeeAlgorithm
163
+ constants: FeeAlgorithmConfig<FeeAlgorithm>
164
+ }
165
+
166
+ /**
167
+ * The config type for a whitelisted address for a set of chains
168
+ * Chains must be explicitly listed in the chainIDs array
169
+ */
170
+ export type FeeConfigDefaultType = FeeConfigType & {
171
+ chainIDs: number[]
172
+ }
173
+
174
+ /**
175
+ * The config type for fees for a whitelisted address
176
+ */
177
+ export type FeeChainType = {
178
+ [chainID: number]: FeeConfigType
179
+ default?: FeeConfigDefaultType
180
+ }
181
+
182
+ /**
183
+ * The config type for a fee record for whitelisted addresses. A default is
184
+ * partial FeeConfigType, so that it can be overridden by chain specific fees.
185
+ */
186
+ export type WhitelistFeeRecord = {
187
+ [whitelistedWalletAddress: Hex]: Partial<FeeChainType>
188
+ }
189
+
190
+ /**
191
+ * The config type for the auth section of the database.
192
+ */
193
+ export type MongoAuthType = {
194
+ enabled: boolean
195
+ username: string
196
+ password: string
197
+ type: string
198
+ }
199
+
200
+ /**
201
+ * The whole config type for alchemy.
202
+ */
203
+ export type AlchemyConfigType = {
204
+ apiKey: string
205
+ networks: AlchemyNetwork[]
206
+ }
207
+
208
+ export type AlchemyNetwork = {
209
+ name: Network
210
+ id: number
211
+ }
212
+
213
+ /**
214
+ * The config type for a single solver configuration
215
+ */
216
+ export type Solver = {
217
+ inboxAddress: Hex
218
+ //target address to contract type mapping
219
+ targets: Record<Hex, TargetContract>
220
+ network: Network
221
+ fee: FeeConfigType
222
+ chainID: number
223
+ }
224
+
225
+ /**
226
+ * The fee algorithm types
227
+ */
228
+ export type FeeAlgorithm = 'linear' | 'quadratic'
229
+
230
+ /**
231
+ * The fee algorithm constant config types
232
+ */
233
+ export type FeeAlgorithmConfig<T extends FeeAlgorithm> = T extends 'linear'
234
+ ? { baseFee: bigint; tranche: { unitFee: bigint; unitSize: bigint } }
235
+ : T extends 'quadratic'
236
+ ? { baseFee: bigint; quadraticFactor: bigint }
237
+ : never
238
+
239
+ /**
240
+ * The config type for a supported target contract
241
+ */
242
+ export interface TargetContract {
243
+ contractType: TargetContractType
244
+ selectors: string[]
245
+ minBalance: number
246
+ targetBalance: number
247
+ }
248
+
249
+ /**
250
+ * The types of contracts that we support
251
+ */
252
+ export type TargetContractType = 'erc20' | 'erc721' | 'erc1155'
253
+
254
+ /**
255
+ * The config type for a single prover source configuration
256
+ */
257
+ export class IntentSource {
258
+ // The network that the prover is on
259
+ network: Network
260
+ // The chain ID of the network
261
+ chainID: number
262
+ // The address that the IntentSource contract is deployed at, we read events from this contract to fulfill
263
+ sourceAddress: Hex
264
+ // The addresses of the tokens that we support as rewards
265
+ tokens: Hex[]
266
+ // The addresses of the provers that we support
267
+ provers: Hex[]
268
+ }
269
+
270
+ export interface LiquidityManagerConfig {
271
+ // The maximum slippage around target balance for a token
272
+ targetSlippage: number
273
+ intervalDuration: number
274
+ thresholds: {
275
+ surplus: number // Percentage above target balance
276
+ deficit: number // Percentage below target balance
277
+ }
278
+ }
@@ -0,0 +1,3 @@
1
+ export interface ConfigSource {
2
+ getConfig(): any
3
+ }
@@ -0,0 +1,52 @@
1
+ const mockConfigGet = jest.fn()
2
+ import { Test, TestingModule } from '@nestjs/testing'
3
+ import { AwsConfigService } from '../aws-config.service'
4
+ import { merge } from 'lodash'
5
+
6
+ jest.mock('config', () => {
7
+ return {
8
+ get: mockConfigGet,
9
+ }
10
+ })
11
+
12
+ describe('Aws Config Helper Tests', () => {
13
+ let awsConfigService: AwsConfigService
14
+ let mockLog: jest.Mock
15
+ let mockAwsGet: jest.Mock
16
+ const awsConfigSingle = { region: 'us-florida', secretID: 'secrets' }
17
+ const awsConfigSingleData = { key: 1, value: 'value1' }
18
+ const awsConfigArray = [awsConfigSingle, { region: 'us-california', secretID: 'configs' }]
19
+ const awsConfigArrayData = [awsConfigSingleData, { key: 3, value_second: 'value3' }]
20
+ beforeEach(async () => {
21
+ const configMod: TestingModule = await Test.createTestingModule({
22
+ providers: [AwsConfigService],
23
+ }).compile()
24
+
25
+ awsConfigService = configMod.get<AwsConfigService>(AwsConfigService)
26
+ mockLog = jest.fn()
27
+ mockAwsGet = jest.fn()
28
+ })
29
+
30
+ it('should read single aws credential', async () => {
31
+ mockConfigGet.mockReturnValue(awsConfigSingle)
32
+ awsConfigService['getAwsSecrets'] = mockAwsGet.mockResolvedValue(awsConfigSingleData)
33
+ await awsConfigService.initConfigs()
34
+ expect(awsConfigService.getConfig()).toEqual(awsConfigSingleData)
35
+ })
36
+
37
+ it('should read array of aws credentials', async () => {
38
+ mockConfigGet.mockReturnValue(awsConfigArray)
39
+ let index = 0
40
+ awsConfigService['getAwsSecrets'] = mockAwsGet.mockImplementation(() => {
41
+ return awsConfigArrayData[index++]
42
+ })
43
+ const me = {}
44
+ awsConfigArrayData.forEach((data) => {
45
+ merge(me, data)
46
+ })
47
+ merge({}, ...awsConfigArrayData)
48
+
49
+ await awsConfigService.initConfigs()
50
+ expect(awsConfigService.getConfig()).toEqual(me)
51
+ })
52
+ })
@@ -0,0 +1,137 @@
1
+ const mockgetChainConfig = jest.fn()
2
+ import { DeepMocked, createMock } from '@golevelup/ts-jest'
3
+ import { Test, TestingModule } from '@nestjs/testing'
4
+ import { EcoConfigService } from '../eco-config.service'
5
+ import { AwsConfigService } from '../aws-config.service'
6
+
7
+ jest.mock('../utils', () => {
8
+ return {
9
+ ...jest.requireActual('../utils'),
10
+ getChainConfig: mockgetChainConfig,
11
+ }
12
+ })
13
+
14
+ describe('Eco Config Helper Tests', () => {
15
+ let ecoConfigService: EcoConfigService
16
+ let awsConfigService: DeepMocked<AwsConfigService>
17
+ let mockLog: jest.Mock
18
+ const awsConfig = { aws: { faceAws: 'asdf', region: 'not-a-region' } }
19
+ beforeEach(async () => {
20
+ awsConfigService = createMock<AwsConfigService>()
21
+ awsConfigService.getConfig = jest.fn().mockReturnValue(awsConfig)
22
+ const configMod: TestingModule = await Test.createTestingModule({
23
+ providers: [
24
+ {
25
+ provide: EcoConfigService,
26
+ useFactory: async (awsConfigService: AwsConfigService) => {
27
+ await awsConfigService.initConfigs()
28
+ return new EcoConfigService([awsConfigService])
29
+ },
30
+ inject: [AwsConfigService],
31
+ },
32
+ { provide: AwsConfigService, useValue: awsConfigService },
33
+ ],
34
+ }).compile()
35
+
36
+ ecoConfigService = configMod.get<EcoConfigService>(EcoConfigService)
37
+ mockLog = jest.fn()
38
+ })
39
+
40
+ it('should merge configs correctly', async () => {
41
+ const oldConfig = ecoConfigService.get('aws') as any
42
+ ecoConfigService.onModuleInit()
43
+ expect(ecoConfigService.get('aws')).toEqual({
44
+ ...awsConfig.aws,
45
+ ...oldConfig,
46
+ })
47
+ })
48
+
49
+ describe('on getIntentSources', () => {
50
+ const mockIS = {
51
+ chainID: 1,
52
+ tokens: ['0x12346817e7F6210A5b320F1A0bC96FfCf713A9b9'],
53
+ }
54
+ const mockChainConfig = {
55
+ IntentSource: 'source',
56
+ Prover: 'prover',
57
+ HyperProver: 'hyperprover',
58
+ }
59
+
60
+ beforeEach(() => {
61
+ jest.spyOn(ecoConfigService, 'get').mockReturnValue([mockIS])
62
+ })
63
+
64
+ it('should throw if not a correct address', () => {
65
+ ecoConfigService.get = jest.fn().mockReturnValue([
66
+ {
67
+ chainID: 1,
68
+ tokens: ['not-an-address'],
69
+ },
70
+ ])
71
+ expect(() => ecoConfigService.getIntentSources()).toThrow()
72
+ })
73
+
74
+ it("should throw if chain config doesn't have a chain for that source", () => {
75
+ mockgetChainConfig.mockReturnValue(undefined)
76
+ expect(() => ecoConfigService.getIntentSources()).toThrow()
77
+ expect(mockgetChainConfig).toHaveBeenCalled()
78
+ })
79
+
80
+ it('should return the intent sources', () => {
81
+ mockgetChainConfig.mockReturnValue(mockChainConfig)
82
+ ecoConfigService.get = jest.fn().mockReturnValue([mockIS])
83
+ const result = ecoConfigService.getIntentSources()
84
+ expect(result).toEqual([
85
+ {
86
+ ...mockIS,
87
+ sourceAddress: mockChainConfig.IntentSource,
88
+ provers: [mockChainConfig.HyperProver], // removed per audit warn => , mockChainConfig.Prover
89
+ },
90
+ ])
91
+ expect(mockgetChainConfig).toHaveBeenCalled()
92
+ expect(mockgetChainConfig).toHaveBeenCalledWith(mockIS.chainID)
93
+ })
94
+ })
95
+
96
+ describe('on getSolvers', () => {
97
+ const mockSolver = {
98
+ chainID: 1,
99
+ targets: {
100
+ '0x12346817e7F6210A5b320F1A0bC96FfCf713A9b9': '0x12346817e7F6210A5b320F1A0bC96FfCf713A9b9',
101
+ },
102
+ }
103
+ const mockChainConfig = {
104
+ Inbox: 'inbox',
105
+ }
106
+
107
+ beforeEach(() => {
108
+ jest.spyOn(ecoConfigService, 'get').mockReturnValue({ 1: mockSolver })
109
+ })
110
+
111
+ it('should throw if not a correct address', () => {
112
+ mockgetChainConfig.mockReturnValue(mockChainConfig)
113
+ ecoConfigService.get = jest.fn().mockReturnValue([
114
+ {
115
+ ...mockSolver,
116
+ targets: { adf: 'not-an-address' },
117
+ },
118
+ ])
119
+ expect(() => ecoConfigService.getSolvers()).toThrow()
120
+ })
121
+
122
+ it("should throw if chain config doesn't have a chain for that solver", () => {
123
+ mockgetChainConfig.mockReturnValue(undefined)
124
+ expect(() => ecoConfigService.getSolvers()).toThrow()
125
+ expect(mockgetChainConfig).toHaveBeenCalled()
126
+ })
127
+
128
+ it('should return the solvers', () => {
129
+ mockgetChainConfig.mockReturnValue(mockChainConfig)
130
+ ecoConfigService.get = jest.fn().mockReturnValue([mockSolver])
131
+ const result = ecoConfigService.getSolvers()
132
+ expect(result).toEqual([{ ...mockSolver, inboxAddress: mockChainConfig.Inbox }])
133
+ expect(mockgetChainConfig).toHaveBeenCalled()
134
+ expect(mockgetChainConfig).toHaveBeenCalledWith(mockSolver.chainID)
135
+ })
136
+ })
137
+ })
@@ -0,0 +1,84 @@
1
+ const mockRoutes = {
2
+ EcoProtocolAddresses: {
3
+ '10': { name: 'prod' },
4
+ '10-pre': { name: 'preprod' },
5
+ '84523': { name: 'staging' },
6
+ '84523-pre': { name: 'development' },
7
+ },
8
+ }
9
+ import { getNodeEnv, isPreEnv, getChainConfig, NodeEnv, ChainPrefix } from '../utils'
10
+ import { EcoError } from '../../common/errors/eco-error'
11
+ import * as config from 'config'
12
+
13
+ jest.mock('config')
14
+
15
+ jest.mock('@eco-foundation/routes-ts', () => mockRoutes)
16
+
17
+ describe('config utils tests', () => {
18
+ describe('on getNodeEnv', () => {
19
+ it('should return the correct NodeEnv value', () => {
20
+ config.util.getEnv = jest.fn().mockReturnValue('production')
21
+ expect(getNodeEnv()).toBe(NodeEnv.production)
22
+
23
+ config.util.getEnv = jest.fn().mockReturnValue('preproduction')
24
+ expect(getNodeEnv()).toBe(NodeEnv.preproduction)
25
+
26
+ config.util.getEnv = jest.fn().mockReturnValue('staging')
27
+ expect(getNodeEnv()).toBe(NodeEnv.staging)
28
+
29
+ config.util.getEnv = jest.fn().mockReturnValue('development')
30
+ expect(getNodeEnv()).toBe(NodeEnv.development)
31
+
32
+ config.util.getEnv = jest.fn().mockReturnValue('unknown')
33
+ expect(getNodeEnv()).toBe(NodeEnv.development)
34
+ })
35
+ })
36
+
37
+ describe('on isPreEnv', () => {
38
+ it('should return true if the environment is pre', () => {
39
+ config.util.getEnv = jest.fn().mockReturnValue('preproduction')
40
+ expect(isPreEnv()).toBe(true)
41
+
42
+ config.util.getEnv = jest.fn().mockReturnValue('development')
43
+ expect(isPreEnv()).toBe(true)
44
+ })
45
+
46
+ it('should return false if the environment is not pre', () => {
47
+ config.util.getEnv = jest.fn().mockReturnValue('production')
48
+ expect(isPreEnv()).toBe(false)
49
+
50
+ config.util.getEnv = jest.fn().mockReturnValue('staging')
51
+ expect(isPreEnv()).toBe(false)
52
+ })
53
+ })
54
+
55
+ describe('on getChainConfig', () => {
56
+ it('should return the correct chain configuration', () => {
57
+ config.util.getEnv = jest.fn().mockReturnValue('production')
58
+ expect(getChainConfig(10)).toEqual(mockRoutes.EcoProtocolAddresses['10'])
59
+
60
+ config.util.getEnv = jest.fn().mockReturnValue('preproduction')
61
+ expect(getChainConfig(10)).toEqual(mockRoutes.EcoProtocolAddresses['10-pre'])
62
+
63
+ config.util.getEnv = jest.fn().mockReturnValue('staging')
64
+ expect(getChainConfig(84523)).toEqual(mockRoutes.EcoProtocolAddresses['84523'])
65
+
66
+ config.util.getEnv = jest.fn().mockReturnValue('development')
67
+ expect(getChainConfig(84523)).toEqual(mockRoutes.EcoProtocolAddresses['84523-pre'])
68
+ })
69
+
70
+ it('should throw an error if the chain configuration is not found', () => {
71
+ config.util.getEnv = jest.fn().mockReturnValue('production')
72
+ expect(() => getChainConfig(3)).toThrow(EcoError.ChainConfigNotFound('3'))
73
+
74
+ config.util.getEnv = jest.fn().mockReturnValue('preproduction')
75
+ expect(() => getChainConfig(4)).toThrow(EcoError.ChainConfigNotFound('4-pre'))
76
+
77
+ config.util.getEnv = jest.fn().mockReturnValue('staging')
78
+ expect(() => getChainConfig(3)).toThrow(EcoError.ChainConfigNotFound('3'))
79
+
80
+ config.util.getEnv = jest.fn().mockReturnValue('development')
81
+ expect(() => getChainConfig(4)).toThrow(EcoError.ChainConfigNotFound('4-pre'))
82
+ })
83
+ })
84
+ })
@@ -0,0 +1,49 @@
1
+ import { EcoChainConfig, EcoProtocolAddresses } from '@eco-foundation/routes-ts'
2
+ import * as config from 'config'
3
+ import { EcoError } from '../common/errors/eco-error'
4
+
5
+ /**
6
+ * The prefix for non-production deploys on a chain
7
+ */
8
+ export const ChainPrefix = 'pre'
9
+
10
+ export enum NodeEnv {
11
+ production = 'production',
12
+ preproduction = 'preproduction',
13
+ staging = 'staging',
14
+ development = 'development',
15
+ }
16
+
17
+ /**
18
+ * Returns the NodeEnv enum value from the string node env, defaults to Development
19
+ *
20
+ * @param env the string node env
21
+ * @returns
22
+ */
23
+ export function getNodeEnv(): NodeEnv {
24
+ const env: string = config.util.getEnv('NODE_ENV')
25
+ const normalizedEnv = env.toLowerCase() as keyof typeof NodeEnv
26
+ return NodeEnv[normalizedEnv] || NodeEnv.development
27
+ }
28
+
29
+ /**
30
+ * @returns true if the node env is preproduction or development
31
+ */
32
+ export function isPreEnv(): boolean {
33
+ return getNodeEnv() === NodeEnv.preproduction || getNodeEnv() === NodeEnv.development
34
+ }
35
+
36
+ /**
37
+ * Gets the chain configuration for the given chain id from the
38
+ * eco protocol addresses library
39
+ * @param chainID the chain id
40
+ * @returns
41
+ */
42
+ export function getChainConfig(chainID: number | string): EcoChainConfig {
43
+ const id = isPreEnv() ? `${chainID}-${ChainPrefix}` : chainID.toString()
44
+ const config = EcoProtocolAddresses[id]
45
+ if (config === undefined) {
46
+ throw EcoError.ChainConfigNotFound(id)
47
+ }
48
+ return config
49
+ }
@@ -0,0 +1,10 @@
1
+ import { BalanceModule } from '@/balance/balance.module'
2
+ import { FeeService } from '@/fee/fee.service'
3
+ import { Module } from '@nestjs/common'
4
+
5
+ @Module({
6
+ imports: [BalanceModule],
7
+ providers: [FeeService],
8
+ exports: [FeeService],
9
+ })
10
+ export class FeeModule {}