amped-defi 1.0.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 (189) hide show
  1. package/README.md +757 -0
  2. package/dist/__mocks__/@sodax/sdk.d.ts +24 -0
  3. package/dist/__mocks__/@sodax/sdk.d.ts.map +1 -0
  4. package/dist/__mocks__/@sodax/sdk.js +24 -0
  5. package/dist/__mocks__/@sodax/sdk.js.map +1 -0
  6. package/dist/__tests__/setup.d.ts +4 -0
  7. package/dist/__tests__/setup.d.ts.map +1 -0
  8. package/dist/__tests__/setup.js +32 -0
  9. package/dist/__tests__/setup.js.map +1 -0
  10. package/dist/index.d.ts +66 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +281 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/policy/policyEngine.d.ts +119 -0
  15. package/dist/policy/policyEngine.d.ts.map +1 -0
  16. package/dist/policy/policyEngine.js +322 -0
  17. package/dist/policy/policyEngine.js.map +1 -0
  18. package/dist/providers/spokeProviderFactory.d.ts +38 -0
  19. package/dist/providers/spokeProviderFactory.d.ts.map +1 -0
  20. package/dist/providers/spokeProviderFactory.js +212 -0
  21. package/dist/providers/spokeProviderFactory.js.map +1 -0
  22. package/dist/sodax/client.d.ts +34 -0
  23. package/dist/sodax/client.d.ts.map +1 -0
  24. package/dist/sodax/client.js +99 -0
  25. package/dist/sodax/client.js.map +1 -0
  26. package/dist/tools/bridge.d.ts +105 -0
  27. package/dist/tools/bridge.d.ts.map +1 -0
  28. package/dist/tools/bridge.js +334 -0
  29. package/dist/tools/bridge.js.map +1 -0
  30. package/dist/tools/discovery.d.ts +141 -0
  31. package/dist/tools/discovery.d.ts.map +1 -0
  32. package/dist/tools/discovery.js +777 -0
  33. package/dist/tools/discovery.js.map +1 -0
  34. package/dist/tools/moneyMarket.d.ts +227 -0
  35. package/dist/tools/moneyMarket.d.ts.map +1 -0
  36. package/dist/tools/moneyMarket.js +867 -0
  37. package/dist/tools/moneyMarket.js.map +1 -0
  38. package/dist/tools/portfolio.d.ts +43 -0
  39. package/dist/tools/portfolio.d.ts.map +1 -0
  40. package/dist/tools/portfolio.js +538 -0
  41. package/dist/tools/portfolio.js.map +1 -0
  42. package/dist/tools/swap.d.ts +71 -0
  43. package/dist/tools/swap.d.ts.map +1 -0
  44. package/dist/tools/swap.js +762 -0
  45. package/dist/tools/swap.js.map +1 -0
  46. package/dist/tools/walletManagement.d.ts +80 -0
  47. package/dist/tools/walletManagement.d.ts.map +1 -0
  48. package/dist/tools/walletManagement.js +289 -0
  49. package/dist/tools/walletManagement.js.map +1 -0
  50. package/dist/types.d.ts +205 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +5 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/utils/errorUtils.d.ts +2 -0
  55. package/dist/utils/errorUtils.d.ts.map +1 -0
  56. package/dist/utils/errorUtils.js +19 -0
  57. package/dist/utils/errorUtils.js.map +1 -0
  58. package/dist/utils/errors.d.ts +144 -0
  59. package/dist/utils/errors.d.ts.map +1 -0
  60. package/dist/utils/errors.js +310 -0
  61. package/dist/utils/errors.js.map +1 -0
  62. package/dist/utils/positionAggregator.d.ts +122 -0
  63. package/dist/utils/positionAggregator.d.ts.map +1 -0
  64. package/dist/utils/positionAggregator.js +377 -0
  65. package/dist/utils/positionAggregator.js.map +1 -0
  66. package/dist/utils/priceService.d.ts +45 -0
  67. package/dist/utils/priceService.d.ts.map +1 -0
  68. package/dist/utils/priceService.js +108 -0
  69. package/dist/utils/priceService.js.map +1 -0
  70. package/dist/utils/sodaxApi.d.ts +92 -0
  71. package/dist/utils/sodaxApi.d.ts.map +1 -0
  72. package/dist/utils/sodaxApi.js +143 -0
  73. package/dist/utils/sodaxApi.js.map +1 -0
  74. package/dist/utils/tokenResolver.d.ts +54 -0
  75. package/dist/utils/tokenResolver.d.ts.map +1 -0
  76. package/dist/utils/tokenResolver.js +252 -0
  77. package/dist/utils/tokenResolver.js.map +1 -0
  78. package/dist/wallet/backendConfig.d.ts +37 -0
  79. package/dist/wallet/backendConfig.d.ts.map +1 -0
  80. package/dist/wallet/backendConfig.js +125 -0
  81. package/dist/wallet/backendConfig.js.map +1 -0
  82. package/dist/wallet/backends/BankrBackend.d.ts +73 -0
  83. package/dist/wallet/backends/BankrBackend.d.ts.map +1 -0
  84. package/dist/wallet/backends/BankrBackend.js +315 -0
  85. package/dist/wallet/backends/BankrBackend.js.map +1 -0
  86. package/dist/wallet/backends/BankrWalletProvider.d.ts +75 -0
  87. package/dist/wallet/backends/BankrWalletProvider.d.ts.map +1 -0
  88. package/dist/wallet/backends/BankrWalletProvider.js +243 -0
  89. package/dist/wallet/backends/BankrWalletProvider.js.map +1 -0
  90. package/dist/wallet/backends/EnvBackend.d.ts +50 -0
  91. package/dist/wallet/backends/EnvBackend.d.ts.map +1 -0
  92. package/dist/wallet/backends/EnvBackend.js +114 -0
  93. package/dist/wallet/backends/EnvBackend.js.map +1 -0
  94. package/dist/wallet/backends/EvmWalletSkillBackend.d.ts +40 -0
  95. package/dist/wallet/backends/EvmWalletSkillBackend.d.ts.map +1 -0
  96. package/dist/wallet/backends/EvmWalletSkillBackend.js +81 -0
  97. package/dist/wallet/backends/EvmWalletSkillBackend.js.map +1 -0
  98. package/dist/wallet/backends/index.d.ts +10 -0
  99. package/dist/wallet/backends/index.d.ts.map +1 -0
  100. package/dist/wallet/backends/index.js +10 -0
  101. package/dist/wallet/backends/index.js.map +1 -0
  102. package/dist/wallet/index.d.ts +9 -0
  103. package/dist/wallet/index.d.ts.map +1 -0
  104. package/dist/wallet/index.js +12 -0
  105. package/dist/wallet/index.js.map +1 -0
  106. package/dist/wallet/providers/AmpedWalletProvider.d.ts +107 -0
  107. package/dist/wallet/providers/AmpedWalletProvider.d.ts.map +1 -0
  108. package/dist/wallet/providers/AmpedWalletProvider.js +208 -0
  109. package/dist/wallet/providers/AmpedWalletProvider.js.map +1 -0
  110. package/dist/wallet/providers/BankrBackend.d.ts +105 -0
  111. package/dist/wallet/providers/BankrBackend.d.ts.map +1 -0
  112. package/dist/wallet/providers/BankrBackend.js +327 -0
  113. package/dist/wallet/providers/BankrBackend.js.map +1 -0
  114. package/dist/wallet/providers/LocalKeyBackend.d.ts +62 -0
  115. package/dist/wallet/providers/LocalKeyBackend.d.ts.map +1 -0
  116. package/dist/wallet/providers/LocalKeyBackend.js +152 -0
  117. package/dist/wallet/providers/LocalKeyBackend.js.map +1 -0
  118. package/dist/wallet/providers/chainConfig.d.ts +209 -0
  119. package/dist/wallet/providers/chainConfig.d.ts.map +1 -0
  120. package/dist/wallet/providers/chainConfig.js +175 -0
  121. package/dist/wallet/providers/chainConfig.js.map +1 -0
  122. package/dist/wallet/providers/index.d.ts +30 -0
  123. package/dist/wallet/providers/index.d.ts.map +1 -0
  124. package/dist/wallet/providers/index.js +32 -0
  125. package/dist/wallet/providers/index.js.map +1 -0
  126. package/dist/wallet/providers/types.d.ts +156 -0
  127. package/dist/wallet/providers/types.d.ts.map +1 -0
  128. package/dist/wallet/providers/types.js +11 -0
  129. package/dist/wallet/providers/types.js.map +1 -0
  130. package/dist/wallet/skillWalletAdapter.d.ts +96 -0
  131. package/dist/wallet/skillWalletAdapter.d.ts.map +1 -0
  132. package/dist/wallet/skillWalletAdapter.js +280 -0
  133. package/dist/wallet/skillWalletAdapter.js.map +1 -0
  134. package/dist/wallet/types.d.ts +134 -0
  135. package/dist/wallet/types.d.ts.map +1 -0
  136. package/dist/wallet/types.js +138 -0
  137. package/dist/wallet/types.js.map +1 -0
  138. package/dist/wallet/walletManager.d.ts +111 -0
  139. package/dist/wallet/walletManager.d.ts.map +1 -0
  140. package/dist/wallet/walletManager.js +476 -0
  141. package/dist/wallet/walletManager.js.map +1 -0
  142. package/dist/wallet/walletRegistry.d.ts +95 -0
  143. package/dist/wallet/walletRegistry.d.ts.map +1 -0
  144. package/dist/wallet/walletRegistry.js +184 -0
  145. package/dist/wallet/walletRegistry.js.map +1 -0
  146. package/index.js +2 -0
  147. package/openclaw.plugin.json +37 -0
  148. package/package.json +69 -0
  149. package/src/__mocks__/@sodax/sdk.ts +28 -0
  150. package/src/__tests__/errors.test.ts +238 -0
  151. package/src/__tests__/policyEngine.test.ts +354 -0
  152. package/src/__tests__/positionAggregator.test.ts +271 -0
  153. package/src/__tests__/setup.ts +35 -0
  154. package/src/__tests__/sodaxApi.test.ts +203 -0
  155. package/src/__tests__/walletRegistry.test.ts +155 -0
  156. package/src/index.ts +376 -0
  157. package/src/policy/policyEngine.ts +389 -0
  158. package/src/providers/spokeProviderFactory.ts +283 -0
  159. package/src/sodax/client.ts +113 -0
  160. package/src/tools/bridge.ts +425 -0
  161. package/src/tools/discovery.ts +989 -0
  162. package/src/tools/moneyMarket.ts +1265 -0
  163. package/src/tools/portfolio.ts +697 -0
  164. package/src/tools/swap.ts +926 -0
  165. package/src/tools/walletManagement.ts +359 -0
  166. package/src/types.ts +228 -0
  167. package/src/utils/errorUtils.ts +16 -0
  168. package/src/utils/errors.ts +396 -0
  169. package/src/utils/positionAggregator.ts +559 -0
  170. package/src/utils/priceService.ts +153 -0
  171. package/src/utils/sodaxApi.ts +261 -0
  172. package/src/utils/tokenResolver.ts +286 -0
  173. package/src/wallet/backendConfig.ts +151 -0
  174. package/src/wallet/backends/BankrBackend.ts +399 -0
  175. package/src/wallet/backends/BankrWalletProvider.ts +329 -0
  176. package/src/wallet/backends/EnvBackend.ts +149 -0
  177. package/src/wallet/backends/EvmWalletSkillBackend.ts +110 -0
  178. package/src/wallet/backends/index.ts +10 -0
  179. package/src/wallet/index.ts +14 -0
  180. package/src/wallet/providers/AmpedWalletProvider.ts +267 -0
  181. package/src/wallet/providers/BankrBackend.ts +407 -0
  182. package/src/wallet/providers/LocalKeyBackend.ts +184 -0
  183. package/src/wallet/providers/chainConfig.ts +194 -0
  184. package/src/wallet/providers/index.ts +62 -0
  185. package/src/wallet/providers/types.ts +186 -0
  186. package/src/wallet/skillWalletAdapter.ts +335 -0
  187. package/src/wallet/types.ts +248 -0
  188. package/src/wallet/walletManager.ts +561 -0
  189. package/src/wallet/walletRegistry.ts +216 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Wallet Registry
3
+ *
4
+ * Manages wallet resolution by walletId.
5
+ * Supports execution mode (with private key) and prepare mode (address-only).
6
+ *
7
+ * Now integrates with evm-wallet-skill for seamless wallet configuration.
8
+ * @see https://github.com/surfer77/evm-wallet-skill
9
+ */
10
+ import { WalletConfig } from '../types';
11
+ /**
12
+ * Wallet registry entry
13
+ */
14
+ interface WalletEntry extends WalletConfig {
15
+ mode: 'execute' | 'prepare';
16
+ }
17
+ /**
18
+ * Wallet Registry class for resolving wallet configurations
19
+ */
20
+ export declare class WalletRegistry {
21
+ private wallets;
22
+ private skillAdapter;
23
+ constructor();
24
+ /**
25
+ * Load wallet configurations from environment
26
+ *
27
+ * @returns Map of walletId to wallet entry
28
+ */
29
+ private loadWallets;
30
+ /**
31
+ * Get a wallet by its ID (synchronous version)
32
+ * Only checks local registry, not skill adapter
33
+ *
34
+ * @param walletId - The wallet identifier
35
+ * @returns The wallet configuration or null if not found
36
+ */
37
+ getWallet(walletId: string): WalletEntry | null;
38
+ /**
39
+ * Resolve a wallet by its ID (async version)
40
+ * Checks local registry first, then tries skill adapter
41
+ *
42
+ * @param walletId - The wallet identifier
43
+ * @returns The wallet configuration or null if not found
44
+ */
45
+ resolveWallet(walletId: string): Promise<WalletEntry | null>;
46
+ /**
47
+ * Validate a wallet entry
48
+ */
49
+ private validateWallet;
50
+ /**
51
+ * Get the wallet mode (execute or prepare)
52
+ *
53
+ * @returns The current wallet mode
54
+ */
55
+ getMode(): 'execute' | 'prepare';
56
+ /**
57
+ * Check if running in execute mode
58
+ *
59
+ * @returns True if in execute mode
60
+ */
61
+ isExecuteMode(): boolean;
62
+ /**
63
+ * Check if running in prepare mode
64
+ *
65
+ * @returns True if in prepare mode
66
+ */
67
+ isPrepareMode(): boolean;
68
+ /**
69
+ * Get all registered wallet IDs (local + skill)
70
+ *
71
+ * @returns Array of wallet IDs
72
+ */
73
+ getWalletIds(): string[];
74
+ /**
75
+ * Get the count of registered wallets (local + skill)
76
+ *
77
+ * @returns Number of wallets
78
+ */
79
+ getWalletCount(): number;
80
+ /**
81
+ * Reload wallets from environment (useful for hot-reloading)
82
+ */
83
+ reload(): void;
84
+ }
85
+ /**
86
+ * Get the singleton wallet registry instance
87
+ * @returns The WalletRegistry singleton
88
+ */
89
+ export declare function getWalletRegistry(): WalletRegistry;
90
+ /**
91
+ * Reset the wallet registry (useful for testing)
92
+ */
93
+ export declare function resetWalletRegistry(): void;
94
+ export {};
95
+ //# sourceMappingURL=walletRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletRegistry.d.ts","sourceRoot":"","sources":["../../src/wallet/walletRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC;;GAEG;AACH,UAAU,WAAY,SAAQ,YAAY;IACxC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,YAAY,CAAwB;;IAY5C;;;;OAIG;IACH,OAAO,CAAC,WAAW;IA4BnB;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAU/C;;;;;;OAMG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA2BlE;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;;;OAIG;IACH,OAAO,IAAI,SAAS,GAAG,SAAS;IAIhC;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACH,YAAY,IAAI,MAAM,EAAE;IAOxB;;;;OAIG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAKD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Wallet Registry
3
+ *
4
+ * Manages wallet resolution by walletId.
5
+ * Supports execution mode (with private key) and prepare mode (address-only).
6
+ *
7
+ * Now integrates with evm-wallet-skill for seamless wallet configuration.
8
+ * @see https://github.com/surfer77/evm-wallet-skill
9
+ */
10
+ import { getWalletAdapter } from './skillWalletAdapter';
11
+ /**
12
+ * Wallet Registry class for resolving wallet configurations
13
+ */
14
+ export class WalletRegistry {
15
+ wallets;
16
+ skillAdapter;
17
+ constructor() {
18
+ this.skillAdapter = getWalletAdapter();
19
+ this.wallets = this.loadWallets();
20
+ // Log skill adapter status
21
+ if (this.skillAdapter.isUsingSkillWallets()) {
22
+ console.log('[walletRegistry] evm-wallet-skill integration active');
23
+ }
24
+ }
25
+ /**
26
+ * Load wallet configurations from environment
27
+ *
28
+ * @returns Map of walletId to wallet entry
29
+ */
30
+ loadWallets() {
31
+ const walletsJson = process.env.AMPED_OC_WALLETS_JSON;
32
+ const mode = process.env.AMPED_OC_MODE || 'execute';
33
+ if (!walletsJson) {
34
+ console.warn('[walletRegistry] AMPED_OC_WALLETS_JSON not set');
35
+ return new Map();
36
+ }
37
+ try {
38
+ const walletConfigs = JSON.parse(walletsJson);
39
+ const wallets = new Map();
40
+ for (const [walletId, config] of Object.entries(walletConfigs)) {
41
+ wallets.set(walletId, {
42
+ ...config,
43
+ mode,
44
+ });
45
+ }
46
+ console.log(`[walletRegistry] Loaded ${wallets.size} wallet(s) in ${mode} mode`);
47
+ return wallets;
48
+ }
49
+ catch (error) {
50
+ console.error('[walletRegistry] Failed to parse AMPED_OC_WALLETS_JSON', error);
51
+ return new Map();
52
+ }
53
+ }
54
+ /**
55
+ * Get a wallet by its ID (synchronous version)
56
+ * Only checks local registry, not skill adapter
57
+ *
58
+ * @param walletId - The wallet identifier
59
+ * @returns The wallet configuration or null if not found
60
+ */
61
+ getWallet(walletId) {
62
+ const wallet = this.wallets.get(walletId);
63
+ if (wallet) {
64
+ return this.validateWallet(wallet, walletId);
65
+ }
66
+ console.error(`[walletRegistry] Wallet not found: ${walletId}`);
67
+ return null;
68
+ }
69
+ /**
70
+ * Resolve a wallet by its ID (async version)
71
+ * Checks local registry first, then tries skill adapter
72
+ *
73
+ * @param walletId - The wallet identifier
74
+ * @returns The wallet configuration or null if not found
75
+ */
76
+ async resolveWallet(walletId) {
77
+ // Try local registry first (synchronous)
78
+ const wallet = this.getWallet(walletId);
79
+ if (wallet) {
80
+ return wallet;
81
+ }
82
+ // Try skill adapter (includes ~/.evm-wallet.json)
83
+ if (this.skillAdapter.isUsingSkillWallets()) {
84
+ try {
85
+ const config = await this.skillAdapter.getWalletConfig(walletId);
86
+ const mode = this.getMode();
87
+ return {
88
+ address: config.address,
89
+ privateKey: config.privateKey,
90
+ mode,
91
+ };
92
+ }
93
+ catch (error) {
94
+ console.error(`[walletRegistry] Skill wallet resolution failed: ${error}`);
95
+ }
96
+ }
97
+ console.error(`[walletRegistry] Wallet not found: ${walletId}`);
98
+ return null;
99
+ }
100
+ /**
101
+ * Validate a wallet entry
102
+ */
103
+ validateWallet(wallet, walletId) {
104
+ // In execute mode, validate that private key is present
105
+ if (wallet.mode === 'execute' && !wallet.privateKey) {
106
+ console.error(`[walletRegistry] Wallet ${walletId} missing privateKey in execute mode`);
107
+ return null;
108
+ }
109
+ // Validate address format (basic check)
110
+ if (!wallet.address || !wallet.address.startsWith('0x')) {
111
+ console.error(`[walletRegistry] Wallet ${walletId} has invalid address: ${wallet.address}`);
112
+ return null;
113
+ }
114
+ return wallet;
115
+ }
116
+ /**
117
+ * Get the wallet mode (execute or prepare)
118
+ *
119
+ * @returns The current wallet mode
120
+ */
121
+ getMode() {
122
+ return process.env.AMPED_OC_MODE || 'execute';
123
+ }
124
+ /**
125
+ * Check if running in execute mode
126
+ *
127
+ * @returns True if in execute mode
128
+ */
129
+ isExecuteMode() {
130
+ return this.getMode() === 'execute';
131
+ }
132
+ /**
133
+ * Check if running in prepare mode
134
+ *
135
+ * @returns True if in prepare mode
136
+ */
137
+ isPrepareMode() {
138
+ return this.getMode() === 'prepare';
139
+ }
140
+ /**
141
+ * Get all registered wallet IDs (local + skill)
142
+ *
143
+ * @returns Array of wallet IDs
144
+ */
145
+ getWalletIds() {
146
+ const localIds = Array.from(this.wallets.keys());
147
+ const skillIds = this.skillAdapter.getWalletIds();
148
+ // Merge unique IDs
149
+ return [...new Set([...localIds, ...skillIds])];
150
+ }
151
+ /**
152
+ * Get the count of registered wallets (local + skill)
153
+ *
154
+ * @returns Number of wallets
155
+ */
156
+ getWalletCount() {
157
+ return this.getWalletIds().length;
158
+ }
159
+ /**
160
+ * Reload wallets from environment (useful for hot-reloading)
161
+ */
162
+ reload() {
163
+ this.wallets = this.loadWallets();
164
+ }
165
+ }
166
+ // Singleton instance
167
+ let walletRegistryInstance = null;
168
+ /**
169
+ * Get the singleton wallet registry instance
170
+ * @returns The WalletRegistry singleton
171
+ */
172
+ export function getWalletRegistry() {
173
+ if (!walletRegistryInstance) {
174
+ walletRegistryInstance = new WalletRegistry();
175
+ }
176
+ return walletRegistryInstance;
177
+ }
178
+ /**
179
+ * Reset the wallet registry (useful for testing)
180
+ */
181
+ export function resetWalletRegistry() {
182
+ walletRegistryInstance = null;
183
+ }
184
+ //# sourceMappingURL=walletRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletRegistry.js","sourceRoot":"","sources":["../../src/wallet/walletRegistry.ts"],"names":[],"mappings":"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"}
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // Re-export from compiled dist
2
+ module.exports = require('./dist/index.js');
@@ -0,0 +1,37 @@
1
+ {
2
+ "id": "amped-defi",
3
+ "kind": "tools",
4
+ "uiHints": {
5
+ "walletsJson": {
6
+ "label": "Wallets JSON",
7
+ "sensitive": true,
8
+ "placeholder": "{\"default\": {\"privateKey\": \"0x...\"}}",
9
+ "help": "JSON object mapping wallet IDs to configs. Or use ${AMPED_OC_WALLETS_JSON}"
10
+ },
11
+ "rpcUrlsJson": {
12
+ "label": "RPC URLs JSON",
13
+ "placeholder": "{\"sonic\": \"https://rpc.sonic.fantom.network\"}",
14
+ "help": "JSON object mapping chain IDs to RPC URLs. Or use ${AMPED_OC_RPC_URLS_JSON}"
15
+ },
16
+ "mode": {
17
+ "label": "Execution Mode",
18
+ "help": "'execute' (default) = execute transactions, 'simulate' = dry-run only"
19
+ },
20
+ "dynamicConfig": {
21
+ "label": "Dynamic SDK Config",
22
+ "help": "Fetch fresh configuration from SODAX API on startup",
23
+ "advanced": true
24
+ }
25
+ },
26
+ "configSchema": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "properties": {
30
+ "walletsJson": { "type": "string" },
31
+ "rpcUrlsJson": { "type": "string" },
32
+ "mode": { "type": "string", "enum": ["execute", "simulate"] },
33
+ "dynamicConfig": { "type": "boolean" }
34
+ },
35
+ "required": []
36
+ }
37
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "amped-defi",
3
+ "version": "1.0.0",
4
+ "description": "Amped DeFi plugin for cross-chain swaps, bridging, and money markets via SODAX SDK",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "src",
10
+ "index.js",
11
+ "README.md",
12
+ "openclaw.plugin.json"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "clean": "rm -rf dist",
17
+ "typecheck": "tsc --noEmit",
18
+ "lint": "eslint src --ext .ts",
19
+ "test": "jest",
20
+ "test:watch": "jest --watch",
21
+ "test:coverage": "jest --coverage"
22
+ },
23
+ "openclaw": {
24
+ "extensions": [
25
+ "./index.js"
26
+ ]
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/amped-finance/amped-openclaw.git"
31
+ },
32
+ "homepage": "https://github.com/amped-finance/amped-openclaw#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/amped-finance/amped-openclaw/issues"
35
+ },
36
+ "author": "Amped Finance",
37
+ "dependencies": {
38
+ "@sinclair/typebox": "^0.32.0",
39
+ "@sodax/sdk": "1.1.0-beta-rc2",
40
+ "@sodax/wallet-sdk-core": "1.1.0-beta-rc2",
41
+ "@sodax/types": "1.1.0-beta-rc2",
42
+ "viem": "^2.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.0.0",
46
+ "typescript": "^5.3.0",
47
+ "eslint": "^8.0.0",
48
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
49
+ "@typescript-eslint/parser": "^6.0.0",
50
+ "jest": "^29.0.0",
51
+ "@types/jest": "^29.0.0",
52
+ "ts-jest": "^29.0.0"
53
+ },
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ },
57
+ "keywords": [
58
+ "openclaw",
59
+ "plugin",
60
+ "defi",
61
+ "sodax",
62
+ "bridge",
63
+ "swap",
64
+ "money-market",
65
+ "cross-chain",
66
+ "intent"
67
+ ],
68
+ "license": "MIT"
69
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Mock for @sodax/sdk
3
+ */
4
+
5
+ export class Sodax {
6
+ static initialize = jest.fn().mockResolvedValue(undefined);
7
+
8
+ swaps = {
9
+ getQuote: jest.fn(),
10
+ executeSwap: jest.fn(),
11
+ cancelIntent: jest.fn(),
12
+ };
13
+
14
+ bridge = {
15
+ getBridgeableTokens: jest.fn(),
16
+ bridge: jest.fn(),
17
+ };
18
+
19
+ moneyMarket = {
20
+ supply: jest.fn(),
21
+ withdraw: jest.fn(),
22
+ borrow: jest.fn(),
23
+ repay: jest.fn(),
24
+ getUserAccountDataOnSpoke: jest.fn(),
25
+ };
26
+ }
27
+
28
+ export const Intent = {};
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Error Handling Utilities Tests
3
+ */
4
+
5
+ import {
6
+ ErrorCode,
7
+ ErrorSeverity,
8
+ AmpedDefiError,
9
+ createPolicyError,
10
+ createWalletError,
11
+ createTransactionError,
12
+ wrapError,
13
+ isRetryableError,
14
+ getRetryDelay,
15
+ logError,
16
+ } from '../utils/errors';
17
+
18
+ describe('Error Utilities', () => {
19
+ describe('AmpedDefiError', () => {
20
+ it('should create error with all properties', () => {
21
+ const error = new AmpedDefiError(
22
+ ErrorCode.POLICY_SLIPPAGE_EXCEEDED,
23
+ 'Slippage too high',
24
+ {
25
+ severity: ErrorSeverity.WARNING,
26
+ remediation: 'Increase slippage tolerance',
27
+ details: { current: 100, limit: 50 },
28
+ context: { operation: 'swap', walletId: 'test' },
29
+ }
30
+ );
31
+
32
+ expect(error.code).toBe(ErrorCode.POLICY_SLIPPAGE_EXCEEDED);
33
+ expect(error.message).toBe('Slippage too high');
34
+ expect(error.severity).toBe(ErrorSeverity.WARNING);
35
+ expect(error.remediation).toBe('Increase slippage tolerance');
36
+ expect(error.details).toEqual({ current: 100, limit: 50 });
37
+ expect(error.context).toEqual({ operation: 'swap', walletId: 'test' });
38
+ expect(error.name).toBe('AmpedDefiError');
39
+ });
40
+
41
+ it('should default severity to ERROR', () => {
42
+ const error = new AmpedDefiError(
43
+ ErrorCode.UNKNOWN_ERROR,
44
+ 'Something went wrong'
45
+ );
46
+
47
+ expect(error.severity).toBe(ErrorSeverity.ERROR);
48
+ });
49
+
50
+ it('should serialize to JSON correctly', () => {
51
+ const error = new AmpedDefiError(
52
+ ErrorCode.WALLET_NOT_FOUND,
53
+ 'Wallet not found',
54
+ { remediation: 'Check configuration' }
55
+ );
56
+
57
+ const json = error.toJSON();
58
+ expect(json.code).toBe(ErrorCode.WALLET_NOT_FOUND);
59
+ expect(json.message).toBe('Wallet not found');
60
+ expect(json.remediation).toBe('Check configuration');
61
+ });
62
+
63
+ it('should generate user-friendly message', () => {
64
+ const error = new AmpedDefiError(
65
+ ErrorCode.TRANSACTION_FAILED,
66
+ 'Transaction failed',
67
+ { remediation: 'Try again later' }
68
+ );
69
+
70
+ const userMsg = error.toUserMessage();
71
+ expect(userMsg).toContain('[TRANSACTION_FAILED] Transaction failed');
72
+ expect(userMsg).toContain('Suggestion: Try again later');
73
+ });
74
+ });
75
+
76
+ describe('Error Factory Functions', () => {
77
+ it('should create policy error with remediation', () => {
78
+ const error = createPolicyError(
79
+ ErrorCode.POLICY_SLIPPAGE_EXCEEDED,
80
+ 'Slippage exceeds limit',
81
+ { current: 150, limit: 100 }
82
+ );
83
+
84
+ expect(error.code).toBe(ErrorCode.POLICY_SLIPPAGE_EXCEEDED);
85
+ expect(error.severity).toBe(ErrorSeverity.WARNING);
86
+ expect(error.remediation).toContain('150');
87
+ expect(error.remediation).toContain('100');
88
+ expect(error.remediation).toContain('exceeds limit');
89
+ });
90
+
91
+ it('should create wallet error with context', () => {
92
+ const cause = new Error('Original error');
93
+ const error = createWalletError(
94
+ ErrorCode.WALLET_NOT_FOUND,
95
+ 'my-wallet',
96
+ cause,
97
+ { operation: 'borrow' }
98
+ );
99
+
100
+ expect(error.code).toBe(ErrorCode.WALLET_NOT_FOUND);
101
+ expect(error.message).toContain('my-wallet');
102
+ expect(error.context).toEqual({ operation: 'borrow', walletId: 'my-wallet' });
103
+ expect(error.cause).toBe(cause);
104
+ });
105
+
106
+ it('should create transaction error with txHash', () => {
107
+ const error = createTransactionError(
108
+ ErrorCode.TRANSACTION_TIMEOUT,
109
+ 'Transaction timed out',
110
+ '0xabc123'
111
+ );
112
+
113
+ expect(error.code).toBe(ErrorCode.TRANSACTION_TIMEOUT);
114
+ expect(error.details).toEqual({ txHash: '0xabc123' });
115
+ expect(error.context).toEqual({ txHash: '0xabc123' });
116
+ });
117
+ });
118
+
119
+ describe('wrapError', () => {
120
+ it('should return AmpedDefiError as-is', () => {
121
+ const original = new AmpedDefiError(
122
+ ErrorCode.SDK_NOT_INITIALIZED,
123
+ 'SDK not ready'
124
+ );
125
+ const wrapped = wrapError(original);
126
+
127
+ expect(wrapped).toBe(original);
128
+ });
129
+
130
+ it('should wrap standard Error and infer code', () => {
131
+ const original = new Error('Insufficient balance for transaction');
132
+ const wrapped = wrapError(original);
133
+
134
+ expect(wrapped).toBeInstanceOf(AmpedDefiError);
135
+ expect(wrapped.code).toBe(ErrorCode.INSUFFICIENT_BALANCE);
136
+ expect(wrapped.message).toBe('Insufficient balance for transaction');
137
+ });
138
+
139
+ it('should use fallback code when unable to infer', () => {
140
+ const original = new Error('Some random error');
141
+ const wrapped = wrapError(original, ErrorCode.UNKNOWN_ERROR);
142
+
143
+ expect(wrapped.code).toBe(ErrorCode.UNKNOWN_ERROR);
144
+ });
145
+
146
+ it('should wrap non-error values', () => {
147
+ const wrapped = wrapError('string error');
148
+
149
+ expect(wrapped).toBeInstanceOf(AmpedDefiError);
150
+ expect(wrapped.message).toBe('string error');
151
+ });
152
+ });
153
+
154
+ describe('isRetryableError', () => {
155
+ it('should identify retryable error codes', () => {
156
+ const timeoutError = new AmpedDefiError(
157
+ ErrorCode.TRANSACTION_TIMEOUT,
158
+ 'Timeout'
159
+ );
160
+ expect(isRetryableError(timeoutError)).toBe(true);
161
+
162
+ const rpcError = new AmpedDefiError(
163
+ ErrorCode.RPC_URL_NOT_CONFIGURED,
164
+ 'RPC error'
165
+ );
166
+ expect(isRetryableError(rpcError)).toBe(true);
167
+ });
168
+
169
+ it('should identify non-retryable error codes', () => {
170
+ const policyError = new AmpedDefiError(
171
+ ErrorCode.POLICY_SLIPPAGE_EXCEEDED,
172
+ 'Slippage'
173
+ );
174
+ expect(isRetryableError(policyError)).toBe(false);
175
+ });
176
+
177
+ it('should check message patterns for generic errors', () => {
178
+ const networkError = new Error('Network connection failed');
179
+ expect(isRetryableError(networkError)).toBe(true);
180
+
181
+ const randomError = new Error('Something broke');
182
+ expect(isRetryableError(randomError)).toBe(false);
183
+ });
184
+ });
185
+
186
+ describe('getRetryDelay', () => {
187
+ it('should calculate exponential backoff', () => {
188
+ expect(getRetryDelay(0)).toBe(1000);
189
+ expect(getRetryDelay(1)).toBe(2000);
190
+ expect(getRetryDelay(2)).toBe(4000);
191
+ expect(getRetryDelay(3)).toBe(8000);
192
+ });
193
+
194
+ it('should cap at 30 seconds', () => {
195
+ expect(getRetryDelay(10)).toBe(30000);
196
+ expect(getRetryDelay(20)).toBe(30000);
197
+ });
198
+
199
+ it('should use custom base delay', () => {
200
+ expect(getRetryDelay(0, 500)).toBe(500);
201
+ expect(getRetryDelay(1, 500)).toBe(1000);
202
+ });
203
+ });
204
+
205
+ describe('logError', () => {
206
+ it('should log structured error', () => {
207
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
208
+
209
+ const error = new AmpedDefiError(
210
+ ErrorCode.TRANSACTION_FAILED,
211
+ 'Transaction failed'
212
+ );
213
+
214
+ logError(error, { operation: 'swap', walletId: 'test' });
215
+
216
+ expect(consoleSpy).toHaveBeenCalled();
217
+ const logged = JSON.parse(consoleSpy.mock.calls[0][0]);
218
+ expect(logged.component).toBe('amped-defi');
219
+ expect(logged.code).toBe(ErrorCode.TRANSACTION_FAILED);
220
+ expect(logged.level).toBe('error');
221
+
222
+ consoleSpy.mockRestore();
223
+ });
224
+
225
+ it('should handle standard errors', () => {
226
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
227
+
228
+ const error = new Error('Standard error');
229
+ logError(error);
230
+
231
+ expect(consoleSpy).toHaveBeenCalled();
232
+ const logged = JSON.parse(consoleSpy.mock.calls[0][0]);
233
+ expect(logged.code).toBe(ErrorCode.UNKNOWN_ERROR);
234
+
235
+ consoleSpy.mockRestore();
236
+ });
237
+ });
238
+ });