eco-solver 0.0.1-security → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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 +66 -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,183 @@
1
+ import { SmartAccountActions, SmartAccountClient } from 'permissionless'
2
+ import {
3
+ KernelVersion,
4
+ toEcdsaKernelSmartAccount,
5
+ ToEcdsaKernelSmartAccountParameters,
6
+ ToEcdsaKernelSmartAccountReturnType,
7
+ } from 'permissionless/accounts'
8
+ import {
9
+ Account,
10
+ Chain,
11
+ Client,
12
+ ClientConfig,
13
+ createClient,
14
+ createWalletClient,
15
+ Hash,
16
+ LocalAccount,
17
+ OneOf,
18
+ Prettify,
19
+ RpcSchema,
20
+ SendTransactionParameters,
21
+ SendTransactionRequest,
22
+ Transport,
23
+ WalletClient,
24
+ } from 'viem'
25
+ import { SendUserOperationParameters } from 'viem/account-abstraction'
26
+ import { encodeKernelExecuteCallData } from '@/transaction/smart-wallets/kernel/actions/encodeData.kernel'
27
+ import { entryPointV_0_7 } from '@/transaction/smart-wallets/kernel/create.kernel.account'
28
+ import { sendTransaction } from 'viem/actions'
29
+ import { EthereumProvider } from 'permissionless/utils/toOwner'
30
+
31
+ export type KernelAccountClientV2Config<
32
+ entryPointVersion extends '0.6' | '0.7',
33
+ kernelVersion extends KernelVersion<entryPointVersion>,
34
+ owner extends OneOf<
35
+ EthereumProvider | WalletClient<Transport, Chain | undefined, Account> | LocalAccount
36
+ >,
37
+ transport extends Transport = Transport,
38
+ chain extends Chain | undefined = Chain | undefined,
39
+ account extends ToEcdsaKernelSmartAccountReturnType<entryPointVersion> | undefined =
40
+ | ToEcdsaKernelSmartAccountReturnType<entryPointVersion>
41
+ | undefined,
42
+ rpcSchema extends RpcSchema | undefined = undefined,
43
+ > = Prettify<
44
+ ClientConfig<transport, chain, account, rpcSchema> &
45
+ ToEcdsaKernelSmartAccountParameters<entryPointVersion, kernelVersion, owner> & {
46
+ ownerAccount: Account
47
+ }
48
+ >
49
+
50
+ export type KernelAccountClientV2<
51
+ entryPointVersion extends '0.6' | '0.7',
52
+ transport extends Transport = Transport,
53
+ chain extends Chain | undefined = Chain | undefined,
54
+ account extends ToEcdsaKernelSmartAccountReturnType<entryPointVersion> | undefined =
55
+ | ToEcdsaKernelSmartAccountReturnType<entryPointVersion>
56
+ | undefined,
57
+ client extends Client | undefined = undefined,
58
+ rpcSchema extends RpcSchema | undefined = undefined,
59
+ > = Prettify<
60
+ SmartAccountClient<transport, chain, account, client, rpcSchema> & {
61
+ ownerAccount: Account
62
+ }
63
+ >
64
+
65
+ export async function createKernelAccountClientV2<
66
+ entryPointVersion extends '0.6' | '0.7' = entryPointV_0_7,
67
+ owner extends OneOf<
68
+ EthereumProvider | WalletClient<Transport, Chain | undefined, Account> | LocalAccount
69
+ > = LocalAccount,
70
+ >(
71
+ _parameters: KernelAccountClientV2Config<
72
+ entryPointVersion,
73
+ KernelVersion<entryPointVersion>,
74
+ owner
75
+ >,
76
+ ): Promise<KernelAccountClientV2<entryPointVersion>> {
77
+ const { ownerAccount, ...parameters } = _parameters
78
+
79
+ const { key = 'kernelAccountClientV2', name = 'Kernel Account Client V2', transport } = parameters
80
+ const { account } = parameters
81
+
82
+ const walletClient = createWalletClient({
83
+ ...parameters,
84
+ account,
85
+ key,
86
+ name,
87
+ transport,
88
+ })
89
+
90
+ const kernelAccount = await toEcdsaKernelSmartAccount<
91
+ entryPointVersion,
92
+ KernelVersion<entryPointVersion>,
93
+ owner
94
+ >({
95
+ ...parameters,
96
+ client: walletClient,
97
+ })
98
+
99
+ const client = Object.assign(
100
+ createClient({
101
+ ...parameters,
102
+ account: kernelAccount,
103
+ chain: parameters.chain ?? walletClient?.chain,
104
+ }),
105
+ { ownerAccount },
106
+ )
107
+
108
+ return client.extend(kernelAccountV2Actions) as KernelAccountClientV2<entryPointVersion>
109
+ }
110
+
111
+ function kernelAccountV2Actions<
112
+ entryPointVersion extends '0.6' | '0.7',
113
+ TChain extends Chain | undefined = Chain | undefined,
114
+ account extends ToEcdsaKernelSmartAccountReturnType<entryPointVersion> | undefined =
115
+ | ToEcdsaKernelSmartAccountReturnType<entryPointVersion>
116
+ | undefined,
117
+ >(
118
+ client: KernelAccountClientV2<entryPointVersion, Transport, TChain, account>,
119
+ ): Pick<SmartAccountActions<TChain, account>, 'sendTransaction'> {
120
+ return {
121
+ sendTransaction: (args) => sendTransactionWithSWC(client, args as any),
122
+ }
123
+ }
124
+
125
+ async function sendTransactionWithSWC<
126
+ entryPointVersion extends '0.6' | '0.7',
127
+ account extends ToEcdsaKernelSmartAccountReturnType<entryPointVersion> | undefined =
128
+ | ToEcdsaKernelSmartAccountReturnType<entryPointVersion>
129
+ | undefined,
130
+ chain extends Chain | undefined = Chain | undefined,
131
+ accountOverride extends ToEcdsaKernelSmartAccountReturnType<entryPointVersion> | undefined =
132
+ | ToEcdsaKernelSmartAccountReturnType<entryPointVersion>
133
+ | undefined,
134
+ chainOverride extends Chain | undefined = Chain | undefined,
135
+ calls extends readonly unknown[] = readonly unknown[],
136
+ const request extends SendTransactionRequest<chain, chainOverride> = SendTransactionRequest<
137
+ chain,
138
+ chainOverride
139
+ >,
140
+ >(
141
+ client: KernelAccountClientV2<entryPointVersion, Transport, chain, account>,
142
+ args:
143
+ | SendTransactionParameters<chain, account, chainOverride>
144
+ | SendUserOperationParameters<account, accountOverride, calls>,
145
+ ): Promise<Hash> {
146
+ const account = (args.account as Account) ?? client.account
147
+ if (account?.type !== 'smart') {
148
+ if (!('to' in args)) throw new Error('Unsupported args')
149
+ return sendTransaction(client, args as any)
150
+ }
151
+
152
+ let calls: calls
153
+ let request: request
154
+
155
+ if ('to' in args) {
156
+ const { data, maxFeePerGas, maxPriorityFeePerGas, to, value } =
157
+ args as SendTransactionParameters<chain, account, chainOverride>
158
+
159
+ calls = [{ to, data, value }] as unknown as calls
160
+ request = { maxFeePerGas, maxPriorityFeePerGas } as request
161
+ } else if ('calls' in args) {
162
+ calls = args.calls as unknown as calls
163
+ request = {} as request
164
+ } else {
165
+ throw new Error('Unsupported action in Kernel Client V2')
166
+ }
167
+
168
+ if (!client.account) {
169
+ throw new Error('Account not defined in Kernel Client V2')
170
+ }
171
+
172
+ const txs = calls.map((tx: any) => ({ to: tx.to, data: tx.data, value: tx.value }))
173
+ const kernelVersion = client.account.entryPoint.version == '0.6' ? '0.2.4' : '0.3.1'
174
+ const data = encodeKernelExecuteCallData({ calls: txs, kernelVersion })
175
+ return sendTransaction(client, {
176
+ ...(request as any),
177
+ data: data,
178
+ kzg: undefined,
179
+ to: client.account.address,
180
+ chain: client.chain,
181
+ account: client.ownerAccount,
182
+ })
183
+ }
@@ -0,0 +1,270 @@
1
+ import {
2
+ Account,
3
+ Chain,
4
+ createWalletClient,
5
+ encodeFunctionData,
6
+ encodePacked,
7
+ erc20Abi,
8
+ getAddress,
9
+ Hex,
10
+ LocalAccount,
11
+ OneOf,
12
+ publicActions,
13
+ Transport,
14
+ WalletClient,
15
+ } from 'viem'
16
+ import { KernelAccountClientConfig } from './kernel-account.config'
17
+ import {
18
+ DeployFactoryArgs,
19
+ KernelAccountActions,
20
+ KernelAccountClient,
21
+ } from './kernel-account.client'
22
+ import { EthereumProvider } from 'permissionless/utils/toOwner'
23
+ import { KernelVersion } from 'permissionless/accounts'
24
+ import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator'
25
+ import { KERNEL_V3_1 } from '@zerodev/sdk/constants'
26
+ import { entryPoint07Address, EntryPointVersion } from 'viem/account-abstraction'
27
+ import { createKernelAccount } from '@zerodev/sdk'
28
+ import {
29
+ getAccount,
30
+ getOwnableExecutor,
31
+ GLOBAL_CONSTANTS,
32
+ installModule,
33
+ isModuleInstalled,
34
+ } from '@rhinestone/module-sdk'
35
+ import { Logger } from '@nestjs/common'
36
+ import { EcoLogMessage } from '@/common/logging/eco-log-message'
37
+ import { OwnableExecutorAbi } from '@/contracts'
38
+
39
+ export type entryPointV_0_7 = '0.7'
40
+
41
+ /**
42
+ * Creates a kernel account client with a kernel account.
43
+ *
44
+ * @param parameters the kernel account client config
45
+ * @returns
46
+ */
47
+ export async function createKernelAccountClient<
48
+ entryPointVersion extends '0.6' | '0.7' = entryPointV_0_7,
49
+ owner extends OneOf<
50
+ EthereumProvider | WalletClient<Transport, Chain | undefined, Account> | LocalAccount
51
+ > = LocalAccount,
52
+ >(
53
+ parameters: KernelAccountClientConfig<entryPointVersion, KernelVersion<entryPointVersion>, owner>,
54
+ ): Promise<{ client: KernelAccountClient<entryPointVersion>; args: DeployFactoryArgs }> {
55
+ const { key = 'kernelAccountClient', name = 'Kernel Account Client', transport } = parameters
56
+ const { account } = parameters
57
+
58
+ let walletClient = createWalletClient({
59
+ ...parameters,
60
+ account,
61
+ key,
62
+ name,
63
+ transport,
64
+ }) as KernelAccountClient<entryPointVersion>
65
+ const kernelVersion = KERNEL_V3_1
66
+ const entryPoint = {
67
+ address: entryPoint07Address,
68
+ version: '0.7' as EntryPointVersion,
69
+ }
70
+
71
+ const ecdsaValidator = await signerToEcdsaValidator(walletClient, {
72
+ signer: account as LocalAccount,
73
+ entryPoint: entryPoint!,
74
+ kernelVersion,
75
+ })
76
+
77
+ const kernelAccount = await createKernelAccount(walletClient, {
78
+ plugins: {
79
+ sudo: ecdsaValidator,
80
+ },
81
+ useMetaFactory: false,
82
+ entryPoint: entryPoint as any,
83
+ kernelVersion,
84
+ })
85
+
86
+ walletClient.kernelAccount = kernelAccount as any
87
+ walletClient.kernelAccountAddress = kernelAccount.address
88
+ walletClient = walletClient.extend(KernelAccountActions).extend(publicActions) as any
89
+
90
+ //conditionally deploys kernel account if it doesn't exist
91
+ const args = await walletClient.deployKernelAccount()
92
+ return { client: walletClient, args }
93
+ }
94
+
95
+ /**
96
+ * Adds a {@link OwnableExecutor} module to the kernel account. The module is used to
97
+ * execute transactions on behalf of the kernel account. Owner is usually
98
+ * a multisig safe account.
99
+ *
100
+ * @param client the kernel account client
101
+ * @param owner the owner to add to the kernel account, a multisig usually
102
+ */
103
+ export async function addExecutorToKernelAccount<
104
+ entryPointVersion extends '0.6' | '0.7' = entryPointV_0_7,
105
+ >(client: KernelAccountClient<entryPointVersion>, owner: Hex) {
106
+ const logger = getLogger()
107
+
108
+ // Ensure the owner is valid and checksummed
109
+ owner = getAddress(owner)
110
+
111
+ // Create the account object
112
+ const account = getAccount({
113
+ address: client.kernelAccount.address,
114
+ type: 'kernel',
115
+ })
116
+ const executor = getOwnableExecutor({
117
+ owner,
118
+ })
119
+
120
+ const executorInstalled = await isModuleInstalled({
121
+ client: client as any,
122
+ account: account,
123
+ module: executor,
124
+ })
125
+
126
+ logger.log(
127
+ EcoLogMessage.fromDefault({
128
+ message: `isModuleInstalled OwnableExecutor: ${executorInstalled}`,
129
+ properties: {
130
+ kernelAccount: client.kernelAccount.address,
131
+ owner,
132
+ },
133
+ }),
134
+ )
135
+
136
+ if (!executorInstalled) {
137
+ logger.log(
138
+ EcoLogMessage.fromDefault({
139
+ message: `installing OwnableExecutor`,
140
+ properties: {
141
+ kernelAccount: client.kernelAccount.address,
142
+ owner,
143
+ },
144
+ }),
145
+ )
146
+ const installExecutes = await installModule({
147
+ client: client as any,
148
+ account: account,
149
+ module: executor,
150
+ })
151
+
152
+ try {
153
+ const transactionHash = await client.execute(installExecutes as any)
154
+ const receipt = await client.waitForTransactionReceipt({
155
+ hash: transactionHash,
156
+ confirmations: 5,
157
+ })
158
+ logger.log(
159
+ EcoLogMessage.fromDefault({
160
+ message: `installed OwnableExecutor`,
161
+ properties: {
162
+ kernelAccount: client.kernelAccount.address,
163
+ owner,
164
+ transactionHash,
165
+ receipt,
166
+ },
167
+ }),
168
+ )
169
+ } catch (e) {
170
+ // Clients do not cache, so an install can go through but the
171
+ // client still tries to install it on a subsequent call
172
+ logger.error(
173
+ EcoLogMessage.fromDefault({
174
+ message: `install OwnableExecutor failed`,
175
+ properties: {
176
+ kernelAccount: client.kernelAccount.address,
177
+ owner,
178
+ error: e,
179
+ },
180
+ }),
181
+ )
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Encodes the calldata for the OwnableExecutor executeOnOwnedAccount function in order to
188
+ * transfer an erc20 token owned by the kernel account.
189
+ * @param kernelAccountAddress the kernel account address
190
+ * @param tx the transfer transaction on the erc20 token to encode
191
+ * @returns
192
+ */
193
+ export function getExecutorTransferData(
194
+ kernelAccountAddress: Hex,
195
+ tx: { to: Hex; amount: bigint; tokenAddress: Hex },
196
+ ) {
197
+ //Encode the transfer function of the ERC20 token
198
+ const transferCalldata = encodeFunctionData({
199
+ abi: erc20Abi,
200
+ functionName: 'transfer',
201
+ args: [tx.to, tx.amount],
202
+ })
203
+
204
+ //Encode the calldata for the OwnableExecutor executeOnOwnedAccount function
205
+ const packed = encodePacked(
206
+ ['address', 'uint256', 'bytes'],
207
+ [tx.tokenAddress, BigInt(Number(0)), transferCalldata],
208
+ )
209
+
210
+ const executorCall = encodeFunctionData({
211
+ abi: OwnableExecutorAbi,
212
+ functionName: 'executeOnOwnedAccount',
213
+ args: [kernelAccountAddress, packed], //the owned account is the kernel account
214
+ })
215
+ return executorCall
216
+ }
217
+
218
+ /**
219
+ * Transfers an ERC20 token from an OwnableExecutor eip-7975 module. It
220
+ * calls the underlying `executeOnOwnedAccount` function of the module that then calls the
221
+ * owned Kernel wallet. Serves for generating the calldata needed for the transfer.
222
+ * Calldata should be executed on the executor contract.
223
+ *
224
+ * @param client the kernel account client
225
+ * @param tx the token tx data
226
+ */
227
+ export async function executorTransferERC20Token<
228
+ entryPointVersion extends '0.6' | '0.7' = entryPointV_0_7,
229
+ >(
230
+ client: KernelAccountClient<entryPointVersion>,
231
+ tx: { to: Hex; amount: bigint; tokenAddress: Hex },
232
+ ) {
233
+ const logger = getLogger()
234
+
235
+ //Encode the transfer function of the ERC20 token
236
+ const transferCalldata = encodeFunctionData({
237
+ abi: erc20Abi,
238
+ functionName: 'transfer',
239
+ args: [tx.to, tx.amount],
240
+ })
241
+
242
+ //Encode the calldata for the OwnableExecutor executeOnOwnedAccount function
243
+ const packed = encodePacked(
244
+ ['address', 'uint256', 'bytes'],
245
+ [tx.tokenAddress, BigInt(Number(0)), transferCalldata],
246
+ )
247
+
248
+ // Simulate the contract call
249
+ const { request } = await client.simulateContract({
250
+ address: GLOBAL_CONSTANTS.OWNABLE_EXECUTOR_ADDRESS,
251
+ abi: OwnableExecutorAbi,
252
+ functionName: 'executeOnOwnedAccount',
253
+ args: [client.kernelAccount.address, packed], //the owned account is the kernel account
254
+ account: client.kernelAccount.client.account, //assumes the kernel account signer is the owner of the executor for the kernel contract
255
+ })
256
+
257
+ logger.log(
258
+ EcoLogMessage.fromDefault({
259
+ message: `simulated OwnableExecutor executeOnOwnedAccount token transfer`,
260
+ properties: {
261
+ kernelAccount: client.kernelAccount.address,
262
+ request,
263
+ },
264
+ }),
265
+ )
266
+ }
267
+
268
+ function getLogger() {
269
+ return new Logger('OwnableExecutor')
270
+ }
@@ -0,0 +1,2 @@
1
+ export * from './kernel-account.client'
2
+ export * from './kernel-account.config'
@@ -0,0 +1,90 @@
1
+ import { Injectable, Logger } from '@nestjs/common'
2
+ import { ViemMultichainClientService } from '../../viem_multichain_client.service'
3
+ import { entryPoint07Address } from 'viem/account-abstraction'
4
+ import { EcoConfigService } from '@/eco-configs/eco-config.service'
5
+ import {
6
+ Account,
7
+ Chain,
8
+ Hex,
9
+ LocalAccount,
10
+ OneOf,
11
+ Transport,
12
+ WalletClient,
13
+ zeroAddress,
14
+ } from 'viem'
15
+ import { KernelVersion } from 'permissionless/accounts'
16
+ import { entryPointV_0_7 } from './create.kernel.account'
17
+ import {
18
+ createKernelAccountClientV2,
19
+ KernelAccountClientV2,
20
+ KernelAccountClientV2Config,
21
+ } from '@/transaction/smart-wallets/kernel/create-kernel-client-v2.account'
22
+ import { EthereumProvider } from 'permissionless/utils/toOwner'
23
+ import { SignerKmsService } from '@/sign/signer-kms.service'
24
+
25
+ class KernelAccountClientV2ServiceBase<
26
+ entryPointVersion extends '0.6' | '0.7',
27
+ kernelVersion extends KernelVersion<entryPointVersion>,
28
+ owner extends OneOf<
29
+ EthereumProvider | WalletClient<Transport, Chain | undefined, Account> | LocalAccount
30
+ > = LocalAccount,
31
+ > extends ViemMultichainClientService<
32
+ KernelAccountClientV2<entryPointVersion>,
33
+ KernelAccountClientV2Config<entryPointVersion, kernelVersion, owner>
34
+ > {
35
+ private logger = new Logger(KernelAccountClientV2ServiceBase.name)
36
+
37
+ constructor(
38
+ readonly ecoConfigService: EcoConfigService,
39
+ private readonly signerService: SignerKmsService,
40
+ ) {
41
+ super(ecoConfigService)
42
+ }
43
+
44
+ /**
45
+ * Returns the address of the wallet for the first solver in the config.
46
+ * @returns
47
+ */
48
+ public override async getAddress(): Promise<Hex> {
49
+ const solvers = this.ecoConfigService.getSolvers()
50
+ if (!solvers || Object.values(solvers).length == 0) {
51
+ return zeroAddress
52
+ }
53
+
54
+ const clientKernel = await this.getClient(Object.values(solvers)[0].chainID)
55
+ return clientKernel.account!.address
56
+ }
57
+
58
+ protected override async createInstanceClient(
59
+ configs: KernelAccountClientV2Config<entryPointVersion, kernelVersion, owner>,
60
+ ): Promise<KernelAccountClientV2<entryPointVersion>> {
61
+ return createKernelAccountClientV2(configs)
62
+ }
63
+
64
+ protected override async buildChainConfig(
65
+ chain: Chain,
66
+ ): Promise<KernelAccountClientV2Config<entryPointVersion, kernelVersion, owner>> {
67
+ const base = await super.buildChainConfig(chain)
68
+ return {
69
+ ...base,
70
+ ownerAccount: this.signerService.getAccount(),
71
+ useMetaFactory: false,
72
+ entryPoint: {
73
+ address: entryPoint07Address,
74
+ version: '0.7' as entryPointVersion,
75
+ },
76
+ owners: [this.signerService.getAccount() as owner],
77
+ index: 0n, // optional
78
+ }
79
+ }
80
+ }
81
+
82
+ @Injectable()
83
+ export class KernelAccountClientV2Service extends KernelAccountClientV2ServiceBase<
84
+ entryPointV_0_7,
85
+ KernelVersion<entryPointV_0_7>
86
+ > {
87
+ constructor(ecoConfigService: EcoConfigService, signerService: SignerKmsService) {
88
+ super(ecoConfigService, signerService)
89
+ }
90
+ }
@@ -0,0 +1,107 @@
1
+ import { Injectable, Logger } from '@nestjs/common'
2
+ import { ViemMultichainClientService } from '../../viem_multichain_client.service'
3
+ import { entryPoint07Address } from 'viem/account-abstraction'
4
+ import { EcoConfigService } from '@/eco-configs/eco-config.service'
5
+ import {
6
+ Account,
7
+ Chain,
8
+ Hex,
9
+ LocalAccount,
10
+ OneOf,
11
+ Transport,
12
+ WalletClient,
13
+ zeroAddress,
14
+ } from 'viem'
15
+ import { KernelAccountClientConfig } from './kernel-account.config'
16
+ import { KernelVersion } from 'permissionless/accounts'
17
+ import {
18
+ addExecutorToKernelAccount,
19
+ createKernelAccountClient,
20
+ entryPointV_0_7,
21
+ } from './create.kernel.account'
22
+ import { KernelAccountClient } from './kernel-account.client'
23
+ import { EthereumProvider } from 'permissionless/utils/toOwner'
24
+ import { EcoLogMessage } from '../../../common/logging/eco-log-message'
25
+ import { SignerKmsService } from '@/sign/signer-kms.service'
26
+
27
+ @Injectable()
28
+ export class KernelAccountClientServiceBase<
29
+ entryPointVersion extends '0.6' | '0.7',
30
+ kernelVersion extends KernelVersion<entryPointVersion>,
31
+ owner extends OneOf<
32
+ EthereumProvider | WalletClient<Transport, Chain | undefined, Account> | LocalAccount
33
+ >,
34
+ > extends ViemMultichainClientService<
35
+ KernelAccountClient<entryPointVersion>,
36
+ KernelAccountClientConfig<entryPointVersion, kernelVersion, owner>
37
+ > {
38
+ private logger = new Logger(KernelAccountClientServiceBase.name)
39
+
40
+ constructor(
41
+ readonly ecoConfigService: EcoConfigService,
42
+ private readonly signerService: SignerKmsService,
43
+ ) {
44
+ super(ecoConfigService)
45
+ }
46
+
47
+ protected override async createInstanceClient(
48
+ configs: KernelAccountClientConfig<entryPointVersion, kernelVersion, owner>,
49
+ ): Promise<KernelAccountClient<entryPointVersion>> {
50
+ const { client, args } = await createKernelAccountClient(configs)
51
+ if (args && args.deployReceipt) {
52
+ this.logger.log(
53
+ EcoLogMessage.fromDefault({
54
+ message: `Deploying Kernel Account`,
55
+ properties: {
56
+ ...args,
57
+ kernelAccount: client.kernelAccount.address,
58
+ },
59
+ }),
60
+ )
61
+ }
62
+ //Conditionally adds an OwnableExecutor to the Kernel Account
63
+ await addExecutorToKernelAccount(client, this.ecoConfigService.getSafe().owner)
64
+ return client
65
+ }
66
+
67
+ protected override async buildChainConfig(
68
+ chain: Chain,
69
+ ): Promise<KernelAccountClientConfig<entryPointVersion, kernelVersion, owner>> {
70
+ const base = await super.buildChainConfig(chain)
71
+ return {
72
+ ...base,
73
+ account: this.signerService.getAccount(),
74
+ useMetaFactory: false,
75
+ entryPoint: {
76
+ address: entryPoint07Address,
77
+ version: '0.7' as entryPointVersion,
78
+ },
79
+ owners: [this.signerService.getAccount() as owner],
80
+ index: 0n, // optional
81
+ }
82
+ }
83
+ /**
84
+ * Returns the address of the wallet for the first solver in the config.
85
+ * @returns
86
+ */
87
+ public override async getAddress(): Promise<Hex> {
88
+ const solvers = this.ecoConfigService.getSolvers()
89
+ if (!solvers || Object.values(solvers).length == 0) {
90
+ return zeroAddress
91
+ }
92
+
93
+ const clientKernel = await this.getClient(Object.values(solvers)[0].chainID)
94
+ return clientKernel.kernelAccount?.address
95
+ }
96
+ }
97
+
98
+ @Injectable()
99
+ export class KernelAccountClientService extends KernelAccountClientServiceBase<
100
+ entryPointV_0_7,
101
+ KernelVersion<entryPointV_0_7>,
102
+ LocalAccount
103
+ > {
104
+ constructor(ecoConfigService: EcoConfigService, signerService: SignerKmsService) {
105
+ super(ecoConfigService, signerService)
106
+ }
107
+ }