@eth-optimism/actions-sdk 0.0.3 → 0.1.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.
Files changed (243) hide show
  1. package/dist/actions.d.ts +19 -7
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +49 -19
  4. package/dist/actions.js.map +1 -1
  5. package/dist/actions.test.js +51 -81
  6. package/dist/actions.test.js.map +1 -1
  7. package/dist/constants/assets.d.ts.map +1 -1
  8. package/dist/constants/assets.js +2 -1
  9. package/dist/constants/assets.js.map +1 -1
  10. package/dist/constants/supportedChains.d.ts +1 -1
  11. package/dist/constants/supportedChains.d.ts.map +1 -1
  12. package/dist/constants/supportedChains.js +2 -1
  13. package/dist/constants/supportedChains.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/lend/core/LendProvider.d.ts +3 -2
  18. package/dist/lend/core/LendProvider.d.ts.map +1 -1
  19. package/dist/lend/core/LendProvider.js.map +1 -1
  20. package/dist/lend/core/__tests__/LendProvider.test.js +18 -48
  21. package/dist/lend/core/__tests__/LendProvider.test.js.map +1 -1
  22. package/dist/lend/index.d.ts +1 -0
  23. package/dist/lend/index.d.ts.map +1 -1
  24. package/dist/lend/index.js +1 -0
  25. package/dist/lend/index.js.map +1 -1
  26. package/dist/lend/namespaces/ActionsLendNamespace.d.ts +35 -8
  27. package/dist/lend/namespaces/ActionsLendNamespace.d.ts.map +1 -1
  28. package/dist/lend/namespaces/ActionsLendNamespace.js +45 -8
  29. package/dist/lend/namespaces/ActionsLendNamespace.js.map +1 -1
  30. package/dist/lend/namespaces/WalletLendNamespace.d.ts +43 -10
  31. package/dist/lend/namespaces/WalletLendNamespace.d.ts.map +1 -1
  32. package/dist/lend/namespaces/WalletLendNamespace.js +67 -13
  33. package/dist/lend/namespaces/WalletLendNamespace.js.map +1 -1
  34. package/dist/lend/namespaces/__tests__/ActionsLendNamespace.spec.js +23 -15
  35. package/dist/lend/namespaces/__tests__/ActionsLendNamespace.spec.js.map +1 -1
  36. package/dist/lend/namespaces/__tests__/WalletLendNamespace.spec.js +29 -11
  37. package/dist/lend/namespaces/__tests__/WalletLendNamespace.spec.js.map +1 -1
  38. package/dist/lend/providers/aave/AaveLendProvider.d.ts +82 -0
  39. package/dist/lend/providers/aave/AaveLendProvider.d.ts.map +1 -0
  40. package/dist/lend/providers/aave/AaveLendProvider.js +346 -0
  41. package/dist/lend/providers/aave/AaveLendProvider.js.map +1 -0
  42. package/dist/lend/providers/aave/addresses.d.ts +57 -0
  43. package/dist/lend/providers/aave/addresses.d.ts.map +1 -0
  44. package/dist/lend/providers/aave/addresses.js +83 -0
  45. package/dist/lend/providers/aave/addresses.js.map +1 -0
  46. package/dist/lend/providers/aave/sdk.d.ts +57 -0
  47. package/dist/lend/providers/aave/sdk.d.ts.map +1 -0
  48. package/dist/lend/providers/aave/sdk.js +260 -0
  49. package/dist/lend/providers/aave/sdk.js.map +1 -0
  50. package/dist/lend/providers/morpho/MorphoLendProvider.d.ts +4 -3
  51. package/dist/lend/providers/morpho/MorphoLendProvider.d.ts.map +1 -1
  52. package/dist/lend/providers/morpho/MorphoLendProvider.js +2 -2
  53. package/dist/lend/providers/morpho/MorphoLendProvider.js.map +1 -1
  54. package/dist/lend/providers/morpho/__tests__/MorphoLendProvider.test.js +1 -33
  55. package/dist/lend/providers/morpho/__tests__/MorphoLendProvider.test.js.map +1 -1
  56. package/dist/lend/providers/morpho/__tests__/sdk.test.js +1 -0
  57. package/dist/lend/providers/morpho/__tests__/sdk.test.js.map +1 -1
  58. package/dist/lend/providers/morpho/sdk.d.ts +4 -3
  59. package/dist/lend/providers/morpho/sdk.d.ts.map +1 -1
  60. package/dist/lend/providers/morpho/sdk.js +0 -1
  61. package/dist/lend/providers/morpho/sdk.js.map +1 -1
  62. package/dist/services/ChainManager.d.ts +1 -1
  63. package/dist/supported/tokens.d.ts.map +1 -1
  64. package/dist/supported/tokens.js +18 -2
  65. package/dist/supported/tokens.js.map +1 -1
  66. package/dist/test/MockLendProvider.d.ts +5 -4
  67. package/dist/test/MockLendProvider.d.ts.map +1 -1
  68. package/dist/test/MockLendProvider.js +5 -5
  69. package/dist/test/MockLendProvider.js.map +1 -1
  70. package/dist/test/MockPrivyClient.d.ts +10 -49
  71. package/dist/test/MockPrivyClient.d.ts.map +1 -1
  72. package/dist/test/MockPrivyClient.js +13 -72
  73. package/dist/test/MockPrivyClient.js.map +1 -1
  74. package/dist/types/actions.d.ts +26 -2
  75. package/dist/types/actions.d.ts.map +1 -1
  76. package/dist/types/lend/base.d.ts +6 -19
  77. package/dist/types/lend/base.d.ts.map +1 -1
  78. package/dist/wallet/core/namespace/WalletNamespace.d.ts +13 -13
  79. package/dist/wallet/core/namespace/WalletNamespace.d.ts.map +1 -1
  80. package/dist/wallet/core/namespace/WalletNamespace.js +13 -13
  81. package/dist/wallet/core/namespace/WalletNamespace.js.map +1 -1
  82. package/dist/wallet/core/namespace/__tests__/WalletNamespace.spec.js +64 -42
  83. package/dist/wallet/core/namespace/__tests__/WalletNamespace.spec.js.map +1 -1
  84. package/dist/wallet/core/providers/__tests__/WalletProvider.spec.js +51 -23
  85. package/dist/wallet/core/providers/__tests__/WalletProvider.spec.js.map +1 -1
  86. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts +12 -3
  87. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts.map +1 -1
  88. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js +3 -2
  89. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js.map +1 -1
  90. package/dist/wallet/core/providers/hosted/registry/__tests__/HostedWalletProviderRegistry.spec.js +14 -4
  91. package/dist/wallet/core/providers/hosted/registry/__tests__/HostedWalletProviderRegistry.spec.js.map +1 -1
  92. package/dist/wallet/core/providers/hosted/types/index.d.ts +8 -2
  93. package/dist/wallet/core/providers/hosted/types/index.d.ts.map +1 -1
  94. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts +14 -6
  95. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts.map +1 -1
  96. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js +10 -6
  97. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js.map +1 -1
  98. package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js +36 -13
  99. package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js.map +1 -1
  100. package/dist/wallet/core/wallets/abstract/Wallet.d.ts +19 -7
  101. package/dist/wallet/core/wallets/abstract/Wallet.d.ts.map +1 -1
  102. package/dist/wallet/core/wallets/abstract/Wallet.js +9 -7
  103. package/dist/wallet/core/wallets/abstract/Wallet.js.map +1 -1
  104. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts +9 -3
  105. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts.map +1 -1
  106. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js +4 -4
  107. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js.map +1 -1
  108. package/dist/wallet/core/wallets/smart/default/__tests__/DefaultSmartWallet.spec.js +1 -1
  109. package/dist/wallet/core/wallets/smart/default/__tests__/DefaultSmartWallet.spec.js.map +1 -1
  110. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +24 -4
  111. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
  112. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js +21 -6
  113. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
  114. package/dist/wallet/node/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js +34 -14
  115. package/dist/wallet/node/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js.map +1 -1
  116. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.d.ts.map +1 -1
  117. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js +10 -4
  118. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js.map +1 -1
  119. package/dist/wallet/node/providers/hosted/registry/__tests__/NodeHostedWalletProviderRegistry.spec.js +9 -1
  120. package/dist/wallet/node/providers/hosted/registry/__tests__/NodeHostedWalletProviderRegistry.spec.js.map +1 -1
  121. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +9 -2
  122. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
  123. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +6 -3
  124. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
  125. package/dist/wallet/node/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.js +4 -3
  126. package/dist/wallet/node/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.js.map +1 -1
  127. package/dist/wallet/node/providers/hosted/types/index.d.ts +6 -1
  128. package/dist/wallet/node/providers/hosted/types/index.d.ts.map +1 -1
  129. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts +19 -7
  130. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
  131. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js +13 -7
  132. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js.map +1 -1
  133. package/dist/wallet/node/wallets/hosted/privy/__tests__/PrivyWallet.spec.js +26 -28
  134. package/dist/wallet/node/wallets/hosted/privy/__tests__/PrivyWallet.spec.js.map +1 -1
  135. package/dist/wallet/node/wallets/hosted/privy/utils/__tests__/createSigner.spec.js +12 -12
  136. package/dist/wallet/node/wallets/hosted/privy/utils/__tests__/createSigner.spec.js.map +1 -1
  137. package/dist/wallet/node/wallets/hosted/privy/utils/createSigner.d.ts +6 -2
  138. package/dist/wallet/node/wallets/hosted/privy/utils/createSigner.d.ts.map +1 -1
  139. package/dist/wallet/node/wallets/hosted/privy/utils/createSigner.js +10 -7
  140. package/dist/wallet/node/wallets/hosted/privy/utils/createSigner.js.map +1 -1
  141. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts +8 -2
  142. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
  143. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
  144. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
  145. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts +6 -2
  146. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts.map +1 -1
  147. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js +3 -3
  148. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js.map +1 -1
  149. package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js +19 -7
  150. package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js.map +1 -1
  151. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +6 -2
  152. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
  153. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js +3 -3
  154. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
  155. package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js +7 -3
  156. package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js.map +1 -1
  157. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +6 -2
  158. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
  159. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +3 -3
  160. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
  161. package/dist/wallet/react/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.js +6 -3
  162. package/dist/wallet/react/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.js.map +1 -1
  163. package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js +6 -6
  164. package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js.map +1 -1
  165. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts +6 -2
  166. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts.map +1 -1
  167. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js +3 -3
  168. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js.map +1 -1
  169. package/dist/wallet/react/wallets/hosted/dynamic/__mocks__/DynamicWalletMock.d.ts +6 -0
  170. package/dist/wallet/react/wallets/hosted/dynamic/__mocks__/DynamicWalletMock.d.ts.map +1 -1
  171. package/dist/wallet/react/wallets/hosted/dynamic/__mocks__/DynamicWalletMock.js.map +1 -1
  172. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts +6 -2
  173. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
  174. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js +3 -3
  175. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js.map +1 -1
  176. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts +6 -2
  177. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
  178. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
  179. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
  180. package/package.json +5 -2
  181. package/src/actions.test.ts +55 -96
  182. package/src/actions.ts +82 -26
  183. package/src/constants/assets.ts +8 -1
  184. package/src/constants/supportedChains.ts +8 -1
  185. package/src/index.ts +1 -2
  186. package/src/lend/core/LendProvider.ts +6 -5
  187. package/src/lend/core/__tests__/LendProvider.test.ts +19 -61
  188. package/src/lend/index.ts +1 -0
  189. package/src/lend/namespaces/ActionsLendNamespace.ts +77 -13
  190. package/src/lend/namespaces/WalletLendNamespace.ts +106 -20
  191. package/src/lend/namespaces/__tests__/ActionsLendNamespace.spec.ts +24 -18
  192. package/src/lend/namespaces/__tests__/WalletLendNamespace.spec.ts +49 -11
  193. package/src/lend/providers/aave/AaveLendProvider.ts +463 -0
  194. package/src/lend/providers/aave/addresses.ts +95 -0
  195. package/src/lend/providers/aave/sdk.ts +369 -0
  196. package/src/lend/providers/morpho/MorphoLendProvider.ts +5 -5
  197. package/src/lend/providers/morpho/__tests__/MorphoLendProvider.test.ts +5 -53
  198. package/src/lend/providers/morpho/__tests__/sdk.test.ts +1 -0
  199. package/src/lend/providers/morpho/sdk.ts +3 -4
  200. package/src/supported/tokens.ts +24 -2
  201. package/src/test/MockLendProvider.ts +9 -9
  202. package/src/test/MockPrivyClient.ts +24 -91
  203. package/src/types/actions.ts +30 -2
  204. package/src/types/lend/base.ts +6 -22
  205. package/src/wallet/core/namespace/WalletNamespace.ts +13 -13
  206. package/src/wallet/core/namespace/__tests__/WalletNamespace.spec.ts +69 -70
  207. package/src/wallet/core/providers/__tests__/WalletProvider.spec.ts +55 -47
  208. package/src/wallet/core/providers/hosted/abstract/HostedWalletProvider.ts +15 -4
  209. package/src/wallet/core/providers/hosted/registry/__tests__/HostedWalletProviderRegistry.spec.ts +20 -7
  210. package/src/wallet/core/providers/hosted/types/index.ts +8 -2
  211. package/src/wallet/core/providers/smart/default/DefaultSmartWalletProvider.ts +24 -9
  212. package/src/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.ts +38 -46
  213. package/src/wallet/core/wallets/abstract/Wallet.ts +25 -17
  214. package/src/wallet/core/wallets/smart/default/DefaultSmartWallet.ts +17 -10
  215. package/src/wallet/core/wallets/smart/default/__tests__/DefaultSmartWallet.spec.ts +4 -7
  216. package/src/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.ts +37 -11
  217. package/src/wallet/node/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.ts +43 -24
  218. package/src/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.ts +10 -7
  219. package/src/wallet/node/providers/hosted/registry/__tests__/NodeHostedWalletProviderRegistry.spec.ts +17 -2
  220. package/src/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +13 -4
  221. package/src/wallet/node/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.ts +4 -4
  222. package/src/wallet/node/providers/hosted/types/index.ts +9 -2
  223. package/src/wallet/node/wallets/hosted/privy/PrivyWallet.ts +31 -11
  224. package/src/wallet/node/wallets/hosted/privy/__tests__/PrivyWallet.spec.ts +35 -40
  225. package/src/wallet/node/wallets/hosted/privy/utils/__tests__/createSigner.spec.ts +18 -14
  226. package/src/wallet/node/wallets/hosted/privy/utils/createSigner.ts +11 -9
  227. package/src/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.ts +16 -5
  228. package/src/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.ts +8 -4
  229. package/src/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.ts +25 -14
  230. package/src/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.ts +8 -4
  231. package/src/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.ts +7 -7
  232. package/src/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +8 -4
  233. package/src/wallet/react/providers/hosted/turnkey/__tests__/TurnkeyHostedWalletProvider.spec.ts +6 -7
  234. package/src/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.ts +6 -6
  235. package/src/wallet/react/wallets/hosted/dynamic/DynamicWallet.ts +12 -5
  236. package/src/wallet/react/wallets/hosted/dynamic/__mocks__/DynamicWalletMock.ts +6 -0
  237. package/src/wallet/react/wallets/hosted/privy/PrivyWallet.ts +12 -5
  238. package/src/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.ts +12 -5
  239. package/dist/constants/config.d.ts +0 -10
  240. package/dist/constants/config.d.ts.map +0 -1
  241. package/dist/constants/config.js +0 -10
  242. package/dist/constants/config.js.map +0 -1
  243. package/src/constants/config.ts +0 -9
@@ -12,9 +12,29 @@ describe('WalletLendNamespace', () => {
12
12
  const mockWalletAddress = getRandomAddress()
13
13
  let mockProvider: LendProvider
14
14
  let mockWallet: SmartWallet
15
+ let mockMarketId: { address: any; chainId: 130 }
15
16
 
16
17
  beforeEach(() => {
17
- mockProvider = createMockLendProvider()
18
+ // Create a consistent market ID for all tests
19
+ mockMarketId = { address: getRandomAddress(), chainId: 130 as const }
20
+
21
+ // Create mock provider with the market in its allowlist
22
+ mockProvider = createMockLendProvider({
23
+ marketAllowlist: [
24
+ {
25
+ address: mockMarketId.address,
26
+ chainId: mockMarketId.chainId,
27
+ name: 'Test Market',
28
+ asset: {
29
+ address: { 130: getRandomAddress() },
30
+ metadata: { symbol: 'USDC', name: 'USD Coin', decimals: 6 },
31
+ type: 'erc20' as const,
32
+ },
33
+ lendProvider: 'morpho',
34
+ },
35
+ ],
36
+ })
37
+
18
38
  // Create a mock SmartWallet with send and sendBatch methods
19
39
  mockWallet = createSmartWalletMock({
20
40
  address: mockWalletAddress,
@@ -32,13 +52,19 @@ describe('WalletLendNamespace', () => {
32
52
  })
33
53
 
34
54
  it('should create an instance with a lend provider and wallet', () => {
35
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
55
+ const namespace = new WalletLendNamespace(
56
+ { morpho: mockProvider as any },
57
+ mockWallet,
58
+ )
36
59
 
37
60
  expect(namespace).toBeInstanceOf(WalletLendNamespace)
38
61
  })
39
62
 
40
63
  it('should inherit read operations from ActionsLendNamespace', async () => {
41
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
64
+ const namespace = new WalletLendNamespace(
65
+ { morpho: mockProvider as any },
66
+ mockWallet,
67
+ )
42
68
  const mockMarkets = [
43
69
  {
44
70
  marketId: {
@@ -75,19 +101,22 @@ describe('WalletLendNamespace', () => {
75
101
  const result = await namespace.getMarkets()
76
102
 
77
103
  expect(mockProvider.getMarkets).toHaveBeenCalled()
78
- expect(result).toBe(mockMarkets)
104
+ expect(result).toStrictEqual(mockMarkets)
79
105
  })
80
106
 
81
107
  describe('openPosition', () => {
82
108
  it('should call provider openPosition with wallet address as receiver', async () => {
83
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
109
+ const namespace = new WalletLendNamespace(
110
+ { morpho: mockProvider as any },
111
+ mockWallet,
112
+ )
84
113
  const mockAsset = {
85
114
  address: { 130: getRandomAddress() },
86
115
  metadata: { symbol: 'USDC', name: 'USD Coin', decimals: 6 },
87
116
  type: 'erc20' as const,
88
117
  }
89
118
  const amount = 1000
90
- const marketId = { address: getRandomAddress(), chainId: 130 as const }
119
+ const marketId = mockMarketId
91
120
  const mockTransaction = {
92
121
  amount: 1000000000n,
93
122
  asset: mockAsset.address[130],
@@ -128,10 +157,13 @@ describe('WalletLendNamespace', () => {
128
157
 
129
158
  describe('closePosition', () => {
130
159
  it('should call provider closePosition and execute transaction for SmartWallet', async () => {
131
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
160
+ const namespace = new WalletLendNamespace(
161
+ { morpho: mockProvider as any },
162
+ mockWallet,
163
+ )
132
164
  const closeParams = {
133
165
  amount: 100,
134
- marketId: { address: getRandomAddress(), chainId: 130 as const },
166
+ marketId: mockMarketId,
135
167
  }
136
168
 
137
169
  const mockTransaction = {
@@ -169,20 +201,26 @@ describe('WalletLendNamespace', () => {
169
201
  })
170
202
 
171
203
  it('should store the wallet reference', () => {
172
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
204
+ const namespace = new WalletLendNamespace(
205
+ { morpho: mockProvider as any },
206
+ mockWallet,
207
+ )
173
208
 
174
209
  expect(namespace['wallet']).toBe(mockWallet)
175
210
  expect(namespace['wallet'].address).toBe(mockWalletAddress)
176
211
  })
177
212
 
178
213
  it('should execute transaction with approval when present', async () => {
179
- const namespace = new WalletLendNamespace(mockProvider, mockWallet)
214
+ const namespace = new WalletLendNamespace(
215
+ { morpho: mockProvider as any },
216
+ mockWallet,
217
+ )
180
218
  const mockAsset = {
181
219
  address: { 130: getRandomAddress() },
182
220
  metadata: { symbol: 'USDC', name: 'USD Coin', decimals: 6 },
183
221
  type: 'erc20' as const,
184
222
  }
185
- const marketId = { address: getRandomAddress(), chainId: 130 as const }
223
+ const marketId = mockMarketId
186
224
  const approval: TransactionData = {
187
225
  to: mockAsset.address[130],
188
226
  value: 0n,
@@ -0,0 +1,463 @@
1
+ import type { Address } from 'viem'
2
+ import { encodeFunctionData, erc20Abi, formatUnits, parseAbi } from 'viem'
3
+
4
+ import { LendProvider } from '@/lend/core/LendProvider.js'
5
+ import type { ChainManager } from '@/services/ChainManager.js'
6
+ import type { LendProviderConfig } from '@/types/actions.js'
7
+ import type {
8
+ GetLendMarketsParams,
9
+ GetMarketBalanceParams,
10
+ LendClosePositionParams,
11
+ LendMarket,
12
+ LendMarketId,
13
+ LendMarketPosition,
14
+ LendOpenPositionInternalParams,
15
+ LendTransaction,
16
+ } from '@/types/lend/index.js'
17
+ import { getAssetAddress } from '@/utils/assets.js'
18
+
19
+ import {
20
+ getPoolAddress,
21
+ getSupportedChainIds,
22
+ getWETHGatewayAddress,
23
+ } from './addresses.js'
24
+ import { getReserve, getReserves } from './sdk.js'
25
+
26
+ /**
27
+ * WETH predeploy address on OP Stack chains
28
+ * @description WETH is deployed at the same address on all OP Stack chains (Optimism, Base, etc.)
29
+ */
30
+ const WETH_ADDRESS = '0x4200000000000000000000000000000000000006'
31
+
32
+ /**
33
+ * Aave Pool ABI - only the functions we need
34
+ */
35
+ const POOL_ABI = parseAbi([
36
+ 'function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)',
37
+ 'function withdraw(address asset, uint256 amount, address to) returns (uint256)',
38
+ ])
39
+
40
+ /**
41
+ * Aave WETHGateway ABI - for native ETH deposits/withdrawals
42
+ */
43
+ const WETH_GATEWAY_ABI = parseAbi([
44
+ 'function depositETH(address pool, address onBehalfOf, uint16 referralCode) payable',
45
+ 'function withdrawETH(address pool, uint256 amount, address to)',
46
+ ])
47
+
48
+ /**
49
+ * Supported chain IDs for Aave lending
50
+ * @description Array of chain IDs where Aave V3 is available on Optimism Superchain
51
+ */
52
+ export const SUPPORTED_CHAIN_IDS = getSupportedChainIds() as readonly number[]
53
+
54
+ /**
55
+ * Aave lending provider implementation
56
+ * @description Lending provider implementation using Aave V3 protocol
57
+ */
58
+ export class AaveLendProvider extends LendProvider<LendProviderConfig> {
59
+ protected readonly SUPPORTED_CHAIN_IDS = SUPPORTED_CHAIN_IDS
60
+
61
+ private chainManager: ChainManager
62
+
63
+ /**
64
+ * Create a new Aave lending provider
65
+ * @param config - Aave lending configuration
66
+ * @param chainManager - Chain manager for blockchain interactions
67
+ */
68
+ constructor(config: LendProviderConfig, chainManager: ChainManager) {
69
+ super(config)
70
+ this.chainManager = chainManager
71
+ }
72
+
73
+ /**
74
+ * Check if market is a WETH market
75
+ * @param marketId - Market identifier
76
+ * @returns true if market is for WETH
77
+ * @description WETH is a predeploy at the same address on all OP Stack chains
78
+ */
79
+ private isWETHMarket(marketId: LendMarketId): boolean {
80
+ return marketId.address.toLowerCase() === WETH_ADDRESS.toLowerCase()
81
+ }
82
+
83
+ /**
84
+ * Open a lending position in an Aave market
85
+ * @description Opens a lending position by supplying assets to an Aave reserve
86
+ * @param params - Position opening parameters
87
+ * @returns Promise resolving to lending transaction details
88
+ */
89
+ protected async _openPosition(
90
+ params: LendOpenPositionInternalParams,
91
+ ): Promise<LendTransaction> {
92
+ try {
93
+ // Get Pool address for this chain
94
+ const poolAddress = getPoolAddress(params.marketId.chainId)
95
+ if (!poolAddress) {
96
+ throw new Error(
97
+ `Aave V3 not deployed on chain ${params.marketId.chainId}`,
98
+ )
99
+ }
100
+
101
+ // Get market information for APY
102
+ const marketInfo = await this.getMarket({
103
+ address: params.marketId.address,
104
+ chainId: params.marketId.chainId,
105
+ })
106
+
107
+ // Check if this is a WETH market
108
+ if (this.isWETHMarket(params.marketId)) {
109
+ return this._openWETHPosition(params, poolAddress, marketInfo)
110
+ }
111
+
112
+ // Standard ERC-20 flow
113
+ return this._openERC20Position(params, poolAddress, marketInfo)
114
+ } catch (error) {
115
+ throw new Error(
116
+ `Failed to open position with ${params.amountWei} of ${params.asset.metadata.symbol}: ${
117
+ error instanceof Error ? error.message : 'Unknown error'
118
+ }`,
119
+ )
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Open position for WETH market using WETHGateway
125
+ * @description Deposits native ETH via WETHGateway which wraps and deposits in one tx
126
+ */
127
+ private async _openWETHPosition(
128
+ params: LendOpenPositionInternalParams,
129
+ poolAddress: Address,
130
+ marketInfo: LendMarket,
131
+ ): Promise<LendTransaction> {
132
+ const gatewayAddress = getWETHGatewayAddress(params.marketId.chainId)
133
+ if (!gatewayAddress) {
134
+ throw new Error(
135
+ `WETHGateway not available on chain ${params.marketId.chainId}`,
136
+ )
137
+ }
138
+
139
+ // Generate depositETH transaction
140
+ const depositCallData = encodeFunctionData({
141
+ abi: WETH_GATEWAY_ABI,
142
+ functionName: 'depositETH',
143
+ args: [
144
+ poolAddress, // pool address
145
+ params.walletAddress, // onBehalfOf (receives aWETH)
146
+ 0, // referralCode (0 = no referral)
147
+ ],
148
+ })
149
+
150
+ return {
151
+ amount: params.amountWei,
152
+ asset: WETH_ADDRESS,
153
+ marketId: params.marketId.address,
154
+ apy: marketInfo.apy.total,
155
+ transactionData: {
156
+ openPosition: {
157
+ to: gatewayAddress,
158
+ data: depositCallData,
159
+ value: params.amountWei, // Send ETH as msg.value
160
+ },
161
+ },
162
+ slippage: params.options?.slippage ?? 50,
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Open position for standard ERC-20 tokens
168
+ * @description Standard approve + supply flow for non-WETH assets
169
+ */
170
+ private async _openERC20Position(
171
+ params: LendOpenPositionInternalParams,
172
+ poolAddress: Address,
173
+ marketInfo: LendMarket,
174
+ ): Promise<LendTransaction> {
175
+ // Get asset address for the chain
176
+ const assetAddress = params.asset.address[params.marketId.chainId]
177
+ if (!assetAddress) {
178
+ throw new Error(`Asset not supported on chain ${params.marketId.chainId}`)
179
+ }
180
+
181
+ // Generate approval transaction
182
+ const approvalCallData = encodeFunctionData({
183
+ abi: erc20Abi,
184
+ functionName: 'approve',
185
+ args: [poolAddress, params.amountWei],
186
+ })
187
+
188
+ // Generate supply transaction
189
+ const supplyCallData = encodeFunctionData({
190
+ abi: POOL_ABI,
191
+ functionName: 'supply',
192
+ args: [
193
+ assetAddress, // asset
194
+ params.amountWei, // amount
195
+ params.walletAddress, // onBehalfOf
196
+ 0, // referralCode
197
+ ],
198
+ })
199
+
200
+ return {
201
+ amount: params.amountWei,
202
+ asset: assetAddress,
203
+ marketId: params.marketId.address,
204
+ apy: marketInfo.apy.total,
205
+ transactionData: {
206
+ approval: {
207
+ to: assetAddress,
208
+ data: approvalCallData,
209
+ value: 0n,
210
+ },
211
+ openPosition: {
212
+ to: poolAddress,
213
+ data: supplyCallData,
214
+ value: 0n,
215
+ },
216
+ },
217
+ slippage: params.options?.slippage ?? 50,
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Close a position in an Aave market
223
+ * @description Withdraws assets from an Aave reserve
224
+ * @param params - Position closing operation parameters
225
+ * @returns Promise resolving to withdrawal transaction details
226
+ */
227
+ protected async _closePosition(
228
+ params: LendClosePositionParams,
229
+ ): Promise<LendTransaction> {
230
+ try {
231
+ // Get Pool address for this chain
232
+ const poolAddress = getPoolAddress(params.marketId.chainId)
233
+ if (!poolAddress) {
234
+ throw new Error(
235
+ `Aave V3 not deployed on chain ${params.marketId.chainId}`,
236
+ )
237
+ }
238
+
239
+ const marketInfo = await this.getMarket({
240
+ address: params.marketId.address,
241
+ chainId: params.marketId.chainId,
242
+ })
243
+
244
+ // Check if this is a WETH market
245
+ if (this.isWETHMarket(params.marketId)) {
246
+ return this._closeWETHPosition(params, poolAddress, marketInfo)
247
+ }
248
+
249
+ // Standard ERC-20 flow
250
+ return this._closeERC20Position(params, poolAddress, marketInfo)
251
+ } catch (error) {
252
+ throw new Error(
253
+ `Failed to close position: ${
254
+ error instanceof Error ? error.message : 'Unknown error'
255
+ }`,
256
+ )
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Close position for WETH market using WETHGateway
262
+ * @description Withdraws aWETH, unwraps to ETH, and sends to user
263
+ */
264
+ private async _closeWETHPosition(
265
+ params: LendClosePositionParams,
266
+ poolAddress: Address,
267
+ marketInfo: LendMarket,
268
+ ): Promise<LendTransaction> {
269
+ const gatewayAddress = getWETHGatewayAddress(params.marketId.chainId)
270
+ if (!gatewayAddress) {
271
+ throw new Error(
272
+ `WETHGateway not available on chain ${params.marketId.chainId}`,
273
+ )
274
+ }
275
+
276
+ // Get the aToken address for the underlying WETH asset
277
+ // Note: params.marketId.address is the underlying WETH address, not the aToken
278
+ const { getATokenAddress } = await import('./sdk.js')
279
+ const aWETHAddress = await getATokenAddress({
280
+ underlyingAsset: params.marketId.address,
281
+ chainId: params.marketId.chainId,
282
+ chainManager: this.chainManager,
283
+ })
284
+
285
+ // First: User must approve aWETH to WETHGateway
286
+ const approvalCallData = encodeFunctionData({
287
+ abi: erc20Abi,
288
+ functionName: 'approve',
289
+ args: [gatewayAddress, params.amount],
290
+ })
291
+
292
+ // Second: Call withdrawETH on gateway
293
+ const withdrawCallData = encodeFunctionData({
294
+ abi: WETH_GATEWAY_ABI,
295
+ functionName: 'withdrawETH',
296
+ args: [
297
+ poolAddress, // pool
298
+ params.amount, // amount
299
+ params.walletAddress, // to (receives native ETH)
300
+ ],
301
+ })
302
+
303
+ return {
304
+ amount: params.amount,
305
+ asset: WETH_ADDRESS,
306
+ marketId: params.marketId.address,
307
+ apy: marketInfo.apy.total,
308
+ transactionData: {
309
+ approval: {
310
+ to: aWETHAddress,
311
+ data: approvalCallData,
312
+ value: 0n,
313
+ },
314
+ closePosition: {
315
+ to: gatewayAddress,
316
+ data: withdrawCallData,
317
+ value: 0n,
318
+ },
319
+ },
320
+ slippage: params.options?.slippage ?? 50,
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Close position for standard ERC-20 tokens
326
+ */
327
+ private async _closeERC20Position(
328
+ params: LendClosePositionParams,
329
+ poolAddress: Address,
330
+ marketInfo: LendMarket,
331
+ ): Promise<LendTransaction> {
332
+ // Get asset address for the market's chain
333
+ const assetAddress = getAssetAddress(
334
+ marketInfo.asset,
335
+ params.marketId.chainId,
336
+ )
337
+
338
+ // Generate withdraw transaction
339
+ const withdrawCallData = encodeFunctionData({
340
+ abi: POOL_ABI,
341
+ functionName: 'withdraw',
342
+ args: [
343
+ assetAddress, // asset
344
+ params.amount, // amount
345
+ params.walletAddress, // to
346
+ ],
347
+ })
348
+
349
+ return {
350
+ amount: params.amount,
351
+ asset: assetAddress,
352
+ marketId: params.marketId.address,
353
+ apy: marketInfo.apy.total,
354
+ transactionData: {
355
+ closePosition: {
356
+ to: poolAddress,
357
+ data: withdrawCallData,
358
+ value: 0n,
359
+ },
360
+ },
361
+ slippage: params.options?.slippage ?? 50,
362
+ }
363
+ }
364
+
365
+ /**
366
+ * Get detailed market information
367
+ * @param marketId - Market identifier containing address and chainId
368
+ * @returns Promise resolving to market information
369
+ */
370
+ protected async _getMarket(marketId: LendMarketId): Promise<LendMarket> {
371
+ return getReserve({
372
+ marketId,
373
+ chainManager: this.chainManager,
374
+ lendConfig: this._config,
375
+ })
376
+ }
377
+
378
+ /**
379
+ * Get list of available lending markets
380
+ * @param params - Filtering parameters
381
+ * @returns Promise resolving to array of market information
382
+ */
383
+ protected async _getMarkets(
384
+ params: GetLendMarketsParams,
385
+ ): Promise<LendMarket[]> {
386
+ const marketConfigs = params.markets || []
387
+
388
+ return getReserves({
389
+ chainManager: this.chainManager,
390
+ lendConfig: this._config,
391
+ markets: marketConfigs,
392
+ })
393
+ }
394
+
395
+ /**
396
+ * Get position for a specific wallet address
397
+ * @param params - Parameters for fetching position
398
+ * @returns Promise resolving to position information
399
+ */
400
+ protected async _getPosition(
401
+ params: GetMarketBalanceParams,
402
+ ): Promise<LendMarketPosition> {
403
+ try {
404
+ const publicClient = this.chainManager.getPublicClient(
405
+ params.marketId.chainId,
406
+ )
407
+ const market = await this._getMarket(params.marketId)
408
+ const poolAddress = getPoolAddress(params.marketId.chainId)
409
+
410
+ if (!poolAddress) {
411
+ throw new Error(
412
+ `Aave V3 not deployed on chain ${params.marketId.chainId}`,
413
+ )
414
+ }
415
+
416
+ // Get the aToken address from Pool.getReserveData
417
+ const assetAddress = getAssetAddress(
418
+ market.asset,
419
+ params.marketId.chainId,
420
+ )
421
+
422
+ const reserveData = (await publicClient.readContract({
423
+ address: poolAddress,
424
+ abi: parseAbi([
425
+ 'struct ReserveData { uint256 configuration; uint128 liquidityIndex; uint128 currentLiquidityRate; uint128 variableBorrowIndex; uint128 currentVariableBorrowRate; uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; uint16 id; address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; address interestRateStrategyAddress; uint128 accruedToTreasury; uint128 unbacked; uint128 isolationModeTotalDebt; }',
426
+ 'function getReserveData(address asset) view returns (ReserveData)',
427
+ ]),
428
+ functionName: 'getReserveData',
429
+ args: [assetAddress],
430
+ })) as {
431
+ aTokenAddress: Address
432
+ }
433
+
434
+ const aTokenAddress = reserveData.aTokenAddress
435
+
436
+ const balance = await publicClient.readContract({
437
+ address: aTokenAddress,
438
+ abi: erc20Abi,
439
+ functionName: 'balanceOf',
440
+ args: [params.walletAddress],
441
+ })
442
+
443
+ const balanceFormatted = formatUnits(
444
+ balance,
445
+ market.asset.metadata.decimals,
446
+ )
447
+
448
+ return {
449
+ balance,
450
+ balanceFormatted,
451
+ shares: balance, // In Aave, aTokens are 1:1 with underlying
452
+ sharesFormatted: balanceFormatted,
453
+ marketId: params.marketId,
454
+ }
455
+ } catch (error) {
456
+ throw new Error(
457
+ `Failed to get market balance for ${params.walletAddress} in market ${params.marketId.address}: ${
458
+ error instanceof Error ? error.message : 'Unknown error'
459
+ }`,
460
+ )
461
+ }
462
+ }
463
+ }
@@ -0,0 +1,95 @@
1
+ import type { Address } from 'viem'
2
+ import { base, baseSepolia, optimism, optimismSepolia } from 'viem/chains'
3
+
4
+ /**
5
+ * Aave V3 Pool addresses for Optimism Superchain networks
6
+ * @description Hardcoded Pool contract addresses for each supported chain
7
+ */
8
+
9
+ /**
10
+ * Mainnet Pool addresses
11
+ */
12
+ export const POOL_ADDRESSES_MAINNET: Record<number, Address> = {
13
+ [optimism.id]: '0x794a61358D6845594F94dc1DB02A252b5b4814aD',
14
+ [base.id]: '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5',
15
+ } as const
16
+
17
+ /**
18
+ * Testnet Pool addresses
19
+ */
20
+ export const POOL_ADDRESSES_TESTNET: Record<number, Address> = {
21
+ [optimismSepolia.id]: '0xb50201558b00496a145fe76f7424749556e326d8',
22
+ [baseSepolia.id]: '0x8bAB6d1b75f19e9eD9fCe8b9BD338844fF79aE27',
23
+ } as const
24
+
25
+ /**
26
+ * All Pool addresses (mainnet + testnet)
27
+ */
28
+ export const POOL_ADDRESSES: Record<number, Address> = {
29
+ ...POOL_ADDRESSES_MAINNET,
30
+ ...POOL_ADDRESSES_TESTNET,
31
+ } as const
32
+
33
+ /**
34
+ * Get Pool address for a given chain ID
35
+ * @param chainId - Chain ID
36
+ * @returns Pool address if supported, undefined otherwise
37
+ */
38
+ export function getPoolAddress(chainId: number): Address | undefined {
39
+ return POOL_ADDRESSES[chainId]
40
+ }
41
+
42
+ /**
43
+ * Check if a chain ID has Aave V3 deployed
44
+ * @param chainId - Chain ID to check
45
+ * @returns true if Aave V3 is deployed on this chain
46
+ */
47
+ export function isAaveChainSupported(chainId: number): boolean {
48
+ return chainId in POOL_ADDRESSES
49
+ }
50
+
51
+ /**
52
+ * Get all supported chain IDs
53
+ * @returns Array of chain IDs with Aave V3 deployed
54
+ */
55
+ export function getSupportedChainIds(): number[] {
56
+ return Object.keys(POOL_ADDRESSES).map(Number)
57
+ }
58
+
59
+ /**
60
+ * Aave V3 WETHGateway addresses for Optimism Superchain networks
61
+ * @description Gateway contracts that handle native ETH wrapping and depositing
62
+ */
63
+
64
+ /**
65
+ * Mainnet WETHGateway addresses
66
+ */
67
+ export const WETH_GATEWAY_ADDRESSES_MAINNET: Record<number, Address> = {
68
+ [optimism.id]: '0x5f2508cAE9923b02316254026CD43d7902866725',
69
+ [base.id]: '0xa0d9C1E9E48Ca30c8d8C3B5D69FF5dc1f6DFfC24',
70
+ } as const
71
+
72
+ /**
73
+ * Testnet WETHGateway addresses
74
+ */
75
+ export const WETH_GATEWAY_ADDRESSES_TESTNET: Record<number, Address> = {
76
+ [optimismSepolia.id]: '0x589750BA8aF186cE5B55391B0b7148cAD43a1619',
77
+ [baseSepolia.id]: '0x0568130e794429D2eEBC4dafE18f25Ff1a1ed8b6',
78
+ } as const
79
+
80
+ /**
81
+ * All WETHGateway addresses (mainnet + testnet)
82
+ */
83
+ export const WETH_GATEWAY_ADDRESSES: Record<number, Address> = {
84
+ ...WETH_GATEWAY_ADDRESSES_MAINNET,
85
+ ...WETH_GATEWAY_ADDRESSES_TESTNET,
86
+ } as const
87
+
88
+ /**
89
+ * Get WETHGateway address for a given chain ID
90
+ * @param chainId - Chain ID
91
+ * @returns WETHGateway address if supported, undefined otherwise
92
+ */
93
+ export function getWETHGatewayAddress(chainId: number): Address | undefined {
94
+ return WETH_GATEWAY_ADDRESSES[chainId]
95
+ }