hak-saucerswap-plugin 1.0.1 → 2.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.
- package/LICENSE +1 -1
- package/README.md +17 -93
- package/dist/index.cjs +179 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +179 -90
- package/dist/index.js.map +1 -1
- package/package.json +5 -16
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -15,6 +15,14 @@ lets AI agents:
|
|
|
15
15
|
- Add/remove liquidity via router transactions
|
|
16
16
|
- Discover farming opportunities
|
|
17
17
|
|
|
18
|
+
## Documentation
|
|
19
|
+
|
|
20
|
+
- **[Configuration](./docs/CONFIGURATION.md)** — full settings table, env vs. plugin-config
|
|
21
|
+
precedence, and pointers to the official SaucerSwap contract deployment list.
|
|
22
|
+
- **[Tools](./docs/TOOLS.md)** — per-tool reference (parameters, return shape, example prompts,
|
|
23
|
+
error behavior) for all six tools registered by the plugin.
|
|
24
|
+
- **[Examples](./docs/EXAMPLES.md)** — dry-run swap, CLI wrapper, and integration smoke test.
|
|
25
|
+
|
|
18
26
|
## Installation
|
|
19
27
|
|
|
20
28
|
```bash
|
|
@@ -26,106 +34,22 @@ npm install hak-saucerswap-plugin
|
|
|
26
34
|
```ts
|
|
27
35
|
import { saucerswapPlugin } from "hak-saucerswap-plugin";
|
|
28
36
|
|
|
29
|
-
const agent = new HederaAgent({
|
|
30
|
-
plugins: [saucerswapPlugin]
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Configuration
|
|
35
|
-
|
|
36
|
-
Provide router contract IDs and (optionally) token aliases via environment or plugin config.
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
export SAUCERSWAP_ROUTER_CONTRACT_ID=0.0.123456
|
|
40
|
-
export SAUCERSWAP_ROUTER_V2_CONTRACT_ID=0.0.654321
|
|
41
|
-
export SAUCERSWAP_WRAPPED_HBAR_TOKEN_ID=0.0.987654
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
```ts
|
|
45
37
|
const agent = new HederaAgent({
|
|
46
38
|
plugins: [saucerswapPlugin],
|
|
47
39
|
config: {
|
|
48
40
|
saucerswap: {
|
|
49
|
-
|
|
50
|
-
routerV2ContractId: "0.0.
|
|
51
|
-
wrappedHbarTokenId: "0.0.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Tools
|
|
60
|
-
|
|
61
|
-
- `saucerswap_get_swap_quote` - Fetches swap quotes from SaucerSwap API.
|
|
62
|
-
- `saucerswap_swap_tokens` - Builds/executes swap transactions with slippage protection.
|
|
63
|
-
- `saucerswap_get_pools` - Lists pools or finds a pool by token pair.
|
|
64
|
-
- `saucerswap_add_liquidity` - Builds/executes add-liquidity transactions.
|
|
65
|
-
- `saucerswap_remove_liquidity` - Builds/executes remove-liquidity transactions.
|
|
66
|
-
- `saucerswap_get_farms` - Lists farming opportunities.
|
|
67
|
-
|
|
68
|
-
## Dry-Run Swap Example
|
|
69
|
-
|
|
70
|
-
Build a swap transaction without executing it by setting `mode` to `returnBytes`.
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
import { Client } from "@hashgraph/sdk";
|
|
74
|
-
import { saucerswapPlugin } from "@your-org/hak-saucerswap-plugin";
|
|
75
|
-
|
|
76
|
-
const client = Client.forTestnet();
|
|
77
|
-
client.setOperator(process.env.HEDERA_ACCOUNT_ID!, process.env.HEDERA_PRIVATE_KEY!);
|
|
78
|
-
|
|
79
|
-
const context = { mode: "returnBytes" };
|
|
80
|
-
const tools = saucerswapPlugin.tools(context);
|
|
81
|
-
const swapTool = tools.find((tool) => tool.method === "saucerswap_swap_tokens");
|
|
82
|
-
|
|
83
|
-
if (!swapTool) {
|
|
84
|
-
throw new Error("Swap tool not registered.");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const result = await swapTool.execute(client, context, {
|
|
88
|
-
fromToken: "0.0.123456",
|
|
89
|
-
toToken: "0.0.654321",
|
|
90
|
-
amount: "1.5",
|
|
91
|
-
slippageTolerance: 0.5
|
|
41
|
+
apiKey: process.env.SAUCERSWAP_API_KEY,
|
|
42
|
+
routerV2ContractId: "0.0.1414040",
|
|
43
|
+
wrappedHbarTokenId: "0.0.15058",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
92
46
|
});
|
|
93
|
-
|
|
94
|
-
console.log(result);
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Or run the built-in CLI wrapper after building:
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
npm run build
|
|
101
|
-
|
|
102
|
-
export HEDERA_NETWORK=testnet
|
|
103
|
-
export HEDERA_ACCOUNT_ID=0.0.1234
|
|
104
|
-
export HEDERA_PRIVATE_KEY=302e020100300506032b657004220420...
|
|
105
|
-
export SAUCERSWAP_ROUTER_CONTRACT_ID=0.0.123456
|
|
106
|
-
export SAUCERSWAP_SWAP_FROM=0.0.111111
|
|
107
|
-
export SAUCERSWAP_SWAP_TO=0.0.222222
|
|
108
|
-
export SAUCERSWAP_SWAP_AMOUNT=1.5
|
|
109
|
-
|
|
110
|
-
npm run dry-run:swap
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Integration Smoke Test
|
|
114
|
-
|
|
115
|
-
Hit the SaucerSwap API and print basic counts.
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
npm run test:integration
|
|
119
47
|
```
|
|
120
48
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
export SAUCERSWAP_TEST_FROM_TOKEN=0.0.123456
|
|
126
|
-
export SAUCERSWAP_TEST_TO_TOKEN=0.0.654321
|
|
127
|
-
export SAUCERSWAP_TEST_AMOUNT=1
|
|
128
|
-
```
|
|
49
|
+
The SaucerSwap API requires an `x-api-key` header. Get a key from
|
|
50
|
+
[saucerswap.finance](https://www.saucerswap.finance) and supply it via either
|
|
51
|
+
`SAUCERSWAP_API_KEY` in the environment or `config.saucerswap.apiKey`. See
|
|
52
|
+
[`.env.example`](./.env.example) for a copy-paste template of all supported environment variables.
|
|
129
53
|
|
|
130
54
|
## Development
|
|
131
55
|
|
package/dist/index.cjs
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var hederaAgentKit = require('@hashgraph/hedera-agent-kit');
|
|
5
6
|
var zod = require('zod');
|
|
6
7
|
var axios = require('axios');
|
|
7
|
-
var sdk = require('@
|
|
8
|
-
var hederaAgentKit = require('hedera-agent-kit');
|
|
8
|
+
var sdk = require('@hiero-ledger/sdk');
|
|
9
9
|
|
|
10
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
|
|
@@ -42,7 +42,8 @@ var SaucerSwapClient = class {
|
|
|
42
42
|
this.retries = options.retries ?? 2;
|
|
43
43
|
this.http = options.http ?? axios__default.default.create({
|
|
44
44
|
baseURL: options.baseUrl ?? "https://api.saucerswap.finance",
|
|
45
|
-
timeout: options.timeoutMs ?? 1e4
|
|
45
|
+
timeout: options.timeoutMs ?? 1e4,
|
|
46
|
+
headers: options.apiKey ? { "x-api-key": options.apiKey } : void 0
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
async request(path, params) {
|
|
@@ -184,6 +185,7 @@ var resolveSaucerSwapConfig = (context) => {
|
|
|
184
185
|
baseUrl: ctxConfig.baseUrl ?? process.env.SAUCERSWAP_BASE_URL ?? DEFAULT_CONFIG.baseUrl,
|
|
185
186
|
timeoutMs: ctxConfig.timeoutMs ?? toNumber(process.env.SAUCERSWAP_TIMEOUT_MS, DEFAULT_CONFIG.timeoutMs),
|
|
186
187
|
retries: ctxConfig.retries ?? toNumber(process.env.SAUCERSWAP_RETRIES, DEFAULT_CONFIG.retries),
|
|
188
|
+
apiKey: ctxConfig.apiKey ?? process.env.SAUCERSWAP_API_KEY,
|
|
187
189
|
routerContractId: ctxConfig.routerContractId ?? process.env.SAUCERSWAP_ROUTER_CONTRACT_ID,
|
|
188
190
|
routerV2ContractId: ctxConfig.routerV2ContractId ?? process.env.SAUCERSWAP_ROUTER_V2_CONTRACT_ID,
|
|
189
191
|
wrappedHbarTokenId: ctxConfig.wrappedHbarTokenId ?? process.env.SAUCERSWAP_WRAPPED_HBAR_TOKEN_ID,
|
|
@@ -201,13 +203,18 @@ var resolveSaucerSwapConfig = (context) => {
|
|
|
201
203
|
var farmsInputSchema = zod.z.object({
|
|
202
204
|
poolId: zod.z.number().int().positive().optional().describe("Optional pool ID to filter farms")
|
|
203
205
|
});
|
|
204
|
-
var
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
206
|
+
var FarmsTool = class extends hederaAgentKit.BaseTool {
|
|
207
|
+
constructor() {
|
|
208
|
+
super(...arguments);
|
|
209
|
+
this.method = "saucerswap_get_farms";
|
|
210
|
+
this.name = "SaucerSwap Get Farms";
|
|
211
|
+
this.description = "Get active farming opportunities on SaucerSwap.";
|
|
212
|
+
this.parameters = farmsInputSchema;
|
|
213
|
+
}
|
|
214
|
+
async normalizeParams(params, _context, _client) {
|
|
215
|
+
return farmsInputSchema.parse(params);
|
|
216
|
+
}
|
|
217
|
+
async coreAction(args, context, _client) {
|
|
211
218
|
const config = resolveSaucerSwapConfig(context);
|
|
212
219
|
const api = context.saucerswapClient ?? createSaucerSwapClient(config);
|
|
213
220
|
try {
|
|
@@ -224,7 +231,14 @@ var farmsTool = {
|
|
|
224
231
|
};
|
|
225
232
|
}
|
|
226
233
|
}
|
|
234
|
+
async shouldSecondaryAction(_coreActionResult, _context) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
async secondaryAction(_request, _client, _context) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
227
240
|
};
|
|
241
|
+
var farmsTool = new FarmsTool();
|
|
228
242
|
|
|
229
243
|
// src/utils/amm.ts
|
|
230
244
|
var calculatePriceImpact = (inputAmount, outputAmount, poolReserveIn, poolReserveOut) => {
|
|
@@ -274,25 +288,6 @@ var accountIdToSolidityAddress = (accountId) => {
|
|
|
274
288
|
var contractIdFromString = (contractId) => {
|
|
275
289
|
return sdk.ContractId.fromString(contractId);
|
|
276
290
|
};
|
|
277
|
-
var finalizeTransaction = async (transaction, client, context, extra) => {
|
|
278
|
-
const mode = context.mode;
|
|
279
|
-
if (mode === hederaAgentKit.AgentMode.RETURN_BYTES || mode === "returnBytes" || mode === "RETURN_BYTES") {
|
|
280
|
-
const txBytes = await transaction.toBytes();
|
|
281
|
-
return {
|
|
282
|
-
success: true,
|
|
283
|
-
transactionBytes: Buffer.from(txBytes).toString("base64"),
|
|
284
|
-
...extra
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
const response = await transaction.execute(client);
|
|
288
|
-
const receipt = await response.getReceipt(client);
|
|
289
|
-
return {
|
|
290
|
-
success: true,
|
|
291
|
-
transactionId: response.transactionId?.toString(),
|
|
292
|
-
status: receipt.status.toString(),
|
|
293
|
-
...extra
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
291
|
|
|
297
292
|
// src/utils/units.ts
|
|
298
293
|
var parseUnits = (amount, decimals) => {
|
|
@@ -331,6 +326,9 @@ var removeLiquidityInputSchema = zod.z.object({
|
|
|
331
326
|
minAmountA: zod.z.string().describe("Minimum amount of tokenA to receive"),
|
|
332
327
|
minAmountB: zod.z.string().describe("Minimum amount of tokenB to receive")
|
|
333
328
|
});
|
|
329
|
+
var isLiquidityCorePayload = (value) => typeof value === "object" && value !== null && "transaction" in value;
|
|
330
|
+
var addLiquidityPostProcess = (response) => `SaucerSwap add liquidity submitted. Status: ${response.status}. Transaction ID: ${response.transactionId}`;
|
|
331
|
+
var removeLiquidityPostProcess = (response) => `SaucerSwap remove liquidity submitted. Status: ${response.status}. Transaction ID: ${response.transactionId}`;
|
|
334
332
|
var resolveDeadline = (defaultMinutes) => {
|
|
335
333
|
return Math.floor(Date.now() / 1e3) + defaultMinutes * 60;
|
|
336
334
|
};
|
|
@@ -341,13 +339,18 @@ var resolveRouterContract = (config) => {
|
|
|
341
339
|
}
|
|
342
340
|
return routerContractId;
|
|
343
341
|
};
|
|
344
|
-
var
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
342
|
+
var AddLiquidityTool = class extends hederaAgentKit.BaseTool {
|
|
343
|
+
constructor() {
|
|
344
|
+
super(...arguments);
|
|
345
|
+
this.method = "saucerswap_add_liquidity";
|
|
346
|
+
this.name = "SaucerSwap Add Liquidity";
|
|
347
|
+
this.description = "Add liquidity to a SaucerSwap pool.";
|
|
348
|
+
this.parameters = addLiquidityInputSchema;
|
|
349
|
+
}
|
|
350
|
+
async normalizeParams(params, _context, _client) {
|
|
351
|
+
return addLiquidityInputSchema.parse(params);
|
|
352
|
+
}
|
|
353
|
+
async coreAction(args, context, client) {
|
|
351
354
|
const config = resolveSaucerSwapConfig(context);
|
|
352
355
|
const operatorAccountId = client?.operatorAccountId?.toString();
|
|
353
356
|
const slippageTolerance = args.slippageTolerance ?? 0.5;
|
|
@@ -378,14 +381,13 @@ var addLiquidityTool = {
|
|
|
378
381
|
const routerContractId = resolveRouterContract(config);
|
|
379
382
|
const deadline = resolveDeadline(config.deadlineMinutes);
|
|
380
383
|
const toAddress = accountIdToSolidityAddress(operatorAccountId);
|
|
381
|
-
const
|
|
382
|
-
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("addLiquidity",
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
amountBDesired,
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
});
|
|
384
|
+
const params = new sdk.ContractFunctionParameters().addAddress(tokenIdToSolidityAddress(requireTokenId(tokenAId))).addAddress(tokenIdToSolidityAddress(requireTokenId(tokenBId))).addUint256(amountADesired).addUint256(amountBDesired).addUint256(amountAMin).addUint256(amountBMin).addAddress(toAddress).addUint256(deadline);
|
|
385
|
+
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("addLiquidity", params);
|
|
386
|
+
const payload = {
|
|
387
|
+
transaction,
|
|
388
|
+
extras: { amountADesired, amountBDesired, amountAMin, amountBMin }
|
|
389
|
+
};
|
|
390
|
+
return payload;
|
|
389
391
|
} catch (error) {
|
|
390
392
|
return {
|
|
391
393
|
success: false,
|
|
@@ -393,14 +395,31 @@ var addLiquidityTool = {
|
|
|
393
395
|
};
|
|
394
396
|
}
|
|
395
397
|
}
|
|
398
|
+
async shouldSecondaryAction(coreActionResult, _context) {
|
|
399
|
+
return isLiquidityCorePayload(coreActionResult);
|
|
400
|
+
}
|
|
401
|
+
async secondaryAction(payload, client, context) {
|
|
402
|
+
const result = await hederaAgentKit.handleTransaction(
|
|
403
|
+
payload.transaction,
|
|
404
|
+
client,
|
|
405
|
+
context,
|
|
406
|
+
addLiquidityPostProcess
|
|
407
|
+
);
|
|
408
|
+
return { ...result, ...payload.extras };
|
|
409
|
+
}
|
|
396
410
|
};
|
|
397
|
-
var
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
411
|
+
var RemoveLiquidityTool = class extends hederaAgentKit.BaseTool {
|
|
412
|
+
constructor() {
|
|
413
|
+
super(...arguments);
|
|
414
|
+
this.method = "saucerswap_remove_liquidity";
|
|
415
|
+
this.name = "SaucerSwap Remove Liquidity";
|
|
416
|
+
this.description = "Remove liquidity from a SaucerSwap pool.";
|
|
417
|
+
this.parameters = removeLiquidityInputSchema;
|
|
418
|
+
}
|
|
419
|
+
async normalizeParams(params, _context, _client) {
|
|
420
|
+
return removeLiquidityInputSchema.parse(params);
|
|
421
|
+
}
|
|
422
|
+
async coreAction(args, context, client) {
|
|
404
423
|
const config = resolveSaucerSwapConfig(context);
|
|
405
424
|
const operatorAccountId = client?.operatorAccountId?.toString();
|
|
406
425
|
if (!operatorAccountId) {
|
|
@@ -436,13 +455,13 @@ var removeLiquidityTool = {
|
|
|
436
455
|
const routerContractId = resolveRouterContract(config);
|
|
437
456
|
const deadline = resolveDeadline(config.deadlineMinutes);
|
|
438
457
|
const toAddress = accountIdToSolidityAddress(operatorAccountId);
|
|
439
|
-
const
|
|
440
|
-
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("removeLiquidity",
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
minAmountA,
|
|
444
|
-
|
|
445
|
-
|
|
458
|
+
const params = new sdk.ContractFunctionParameters().addAddress(tokenIdToSolidityAddress(requireTokenId(tokenAId))).addAddress(tokenIdToSolidityAddress(requireTokenId(tokenBId))).addUint256(lpAmount).addUint256(minAmountA).addUint256(minAmountB).addAddress(toAddress).addUint256(deadline);
|
|
459
|
+
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("removeLiquidity", params);
|
|
460
|
+
const payload = {
|
|
461
|
+
transaction,
|
|
462
|
+
extras: { lpAmount, minAmountA, minAmountB }
|
|
463
|
+
};
|
|
464
|
+
return payload;
|
|
446
465
|
} catch (error) {
|
|
447
466
|
return {
|
|
448
467
|
success: false,
|
|
@@ -450,20 +469,39 @@ var removeLiquidityTool = {
|
|
|
450
469
|
};
|
|
451
470
|
}
|
|
452
471
|
}
|
|
472
|
+
async shouldSecondaryAction(coreActionResult, _context) {
|
|
473
|
+
return isLiquidityCorePayload(coreActionResult);
|
|
474
|
+
}
|
|
475
|
+
async secondaryAction(payload, client, context) {
|
|
476
|
+
const result = await hederaAgentKit.handleTransaction(
|
|
477
|
+
payload.transaction,
|
|
478
|
+
client,
|
|
479
|
+
context,
|
|
480
|
+
removeLiquidityPostProcess
|
|
481
|
+
);
|
|
482
|
+
return { ...result, ...payload.extras };
|
|
483
|
+
}
|
|
453
484
|
};
|
|
485
|
+
var addLiquidityTool = new AddLiquidityTool();
|
|
486
|
+
var removeLiquidityTool = new RemoveLiquidityTool();
|
|
454
487
|
var poolsInputSchema = zod.z.object({
|
|
455
488
|
tokenA: zod.z.string().optional().describe("First token ID or symbol"),
|
|
456
489
|
tokenB: zod.z.string().optional().describe("Second token ID or symbol"),
|
|
457
490
|
version: zod.z.enum(["v1", "v2"]).optional().describe("Pool version"),
|
|
458
491
|
limit: zod.z.number().int().positive().optional().describe("Maximum number of pools to return")
|
|
459
492
|
});
|
|
460
|
-
var
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
493
|
+
var PoolsTool = class extends hederaAgentKit.BaseTool {
|
|
494
|
+
constructor() {
|
|
495
|
+
super(...arguments);
|
|
496
|
+
this.method = "saucerswap_get_pools";
|
|
497
|
+
this.name = "SaucerSwap Get Pools";
|
|
498
|
+
this.description = "Query SaucerSwap liquidity pools and reserves.";
|
|
499
|
+
this.parameters = poolsInputSchema;
|
|
500
|
+
}
|
|
501
|
+
async normalizeParams(params, _context, _client) {
|
|
502
|
+
return poolsInputSchema.parse(params);
|
|
503
|
+
}
|
|
504
|
+
async coreAction(args, context, _client) {
|
|
467
505
|
const config = resolveSaucerSwapConfig(context);
|
|
468
506
|
const api = context.saucerswapClient ?? createSaucerSwapClient(config);
|
|
469
507
|
try {
|
|
@@ -496,7 +534,14 @@ var poolsTool = {
|
|
|
496
534
|
};
|
|
497
535
|
}
|
|
498
536
|
}
|
|
537
|
+
async shouldSecondaryAction(_coreActionResult, _context) {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
async secondaryAction(_request, _client, _context) {
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
499
543
|
};
|
|
544
|
+
var poolsTool = new PoolsTool();
|
|
500
545
|
|
|
501
546
|
// src/utils/quote.ts
|
|
502
547
|
var readAmount = (value) => {
|
|
@@ -530,16 +575,21 @@ var quoteInputSchema = zod.z.object({
|
|
|
530
575
|
amount: zod.z.string().describe("Amount to swap (decimal format)"),
|
|
531
576
|
slippageTolerance: zod.z.number().optional().default(0.5).describe("Maximum slippage tolerance percentage")
|
|
532
577
|
});
|
|
533
|
-
var
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
578
|
+
var QuoteTool = class extends hederaAgentKit.BaseTool {
|
|
579
|
+
constructor() {
|
|
580
|
+
super(...arguments);
|
|
581
|
+
this.method = "saucerswap_get_swap_quote";
|
|
582
|
+
this.name = "SaucerSwap Get Swap Quote";
|
|
583
|
+
this.description = "Get a price quote for swapping tokens on SaucerSwap.";
|
|
584
|
+
this.parameters = quoteInputSchema;
|
|
585
|
+
}
|
|
586
|
+
async normalizeParams(params, _context, _client) {
|
|
587
|
+
return quoteInputSchema.parse(params);
|
|
588
|
+
}
|
|
589
|
+
async coreAction(args, context, _client) {
|
|
540
590
|
const config = resolveSaucerSwapConfig(context);
|
|
541
|
-
const
|
|
542
|
-
const api =
|
|
591
|
+
const cachedApi = context.saucerswapClient;
|
|
592
|
+
const api = cachedApi ?? createSaucerSwapClient(config);
|
|
543
593
|
const slippageTolerance = args.slippageTolerance ?? 0.5;
|
|
544
594
|
try {
|
|
545
595
|
const fromToken = normalizeTokenAlias(args.fromToken, config);
|
|
@@ -585,7 +635,14 @@ var quoteTool = {
|
|
|
585
635
|
};
|
|
586
636
|
}
|
|
587
637
|
}
|
|
638
|
+
async shouldSecondaryAction(_coreActionResult, _context) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
async secondaryAction(_request, _client, _context) {
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
588
644
|
};
|
|
645
|
+
var quoteTool = new QuoteTool();
|
|
589
646
|
var swapInputSchema = zod.z.object({
|
|
590
647
|
fromToken: zod.z.string().describe("Token ID to swap from (e.g., 'HBAR' or '0.0.123456')"),
|
|
591
648
|
toToken: zod.z.string().describe("Token ID to swap to"),
|
|
@@ -593,6 +650,8 @@ var swapInputSchema = zod.z.object({
|
|
|
593
650
|
slippageTolerance: zod.z.number().optional().default(0.5).describe("Maximum slippage tolerance percentage"),
|
|
594
651
|
deadline: zod.z.number().optional().describe("Transaction deadline in minutes from now or a unix timestamp")
|
|
595
652
|
});
|
|
653
|
+
var isSwapCorePayload = (value) => typeof value === "object" && value !== null && "transaction" in value;
|
|
654
|
+
var swapPostProcess = (response) => `SaucerSwap swap submitted. Status: ${response.status}. Transaction ID: ${response.transactionId}`;
|
|
596
655
|
var resolveDeadline2 = (deadlineInput, defaultMinutes) => {
|
|
597
656
|
const now = Math.floor(Date.now() / 1e3);
|
|
598
657
|
if (!deadlineInput) {
|
|
@@ -609,13 +668,18 @@ var amountToSmallest = (amount, decimals) => {
|
|
|
609
668
|
var expectedToSmallest = (amount, decimals) => {
|
|
610
669
|
return amount.includes(".") ? parseUnits(amount, decimals) : amount;
|
|
611
670
|
};
|
|
612
|
-
var
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
671
|
+
var SwapTool = class extends hederaAgentKit.BaseTool {
|
|
672
|
+
constructor() {
|
|
673
|
+
super(...arguments);
|
|
674
|
+
this.method = "saucerswap_swap_tokens";
|
|
675
|
+
this.name = "SaucerSwap Swap Tokens";
|
|
676
|
+
this.description = "Execute a token swap on SaucerSwap DEX.";
|
|
677
|
+
this.parameters = swapInputSchema;
|
|
678
|
+
}
|
|
679
|
+
async normalizeParams(params, _context, _client) {
|
|
680
|
+
return swapInputSchema.parse(params);
|
|
681
|
+
}
|
|
682
|
+
async coreAction(args, context, client) {
|
|
619
683
|
const config = resolveSaucerSwapConfig(context);
|
|
620
684
|
const operatorAccountId = client?.operatorAccountId?.toString();
|
|
621
685
|
const slippageTolerance = args.slippageTolerance ?? 0.5;
|
|
@@ -663,14 +727,18 @@ var swapTool = {
|
|
|
663
727
|
tokenIdToSolidityAddress(requireTokenId(fromTokenId)),
|
|
664
728
|
tokenIdToSolidityAddress(requireTokenId(toTokenId))
|
|
665
729
|
];
|
|
666
|
-
const
|
|
667
|
-
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("swapExactTokensForTokens",
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
730
|
+
const params = new sdk.ContractFunctionParameters().addUint256(amountInSmallest).addUint256(minOutSmallest).addAddressArray(path).addAddress(toAddress).addUint256(deadline);
|
|
731
|
+
const transaction = new sdk.ContractExecuteTransaction().setContractId(contractIdFromString(routerContractId)).setGas(config.gasLimit).setFunction("swapExactTokensForTokens", params);
|
|
732
|
+
const payload = {
|
|
733
|
+
transaction,
|
|
734
|
+
extras: {
|
|
735
|
+
estimatedOutput: quote.expectedOutput,
|
|
736
|
+
minOutput: minOutSmallest,
|
|
737
|
+
priceImpact: quote.priceImpact,
|
|
738
|
+
route: quote.route
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
return payload;
|
|
674
742
|
} catch (error) {
|
|
675
743
|
return {
|
|
676
744
|
success: false,
|
|
@@ -678,9 +746,30 @@ var swapTool = {
|
|
|
678
746
|
};
|
|
679
747
|
}
|
|
680
748
|
}
|
|
749
|
+
async shouldSecondaryAction(coreActionResult, _context) {
|
|
750
|
+
return isSwapCorePayload(coreActionResult);
|
|
751
|
+
}
|
|
752
|
+
async secondaryAction(payload, client, context) {
|
|
753
|
+
const result = await hederaAgentKit.handleTransaction(
|
|
754
|
+
payload.transaction,
|
|
755
|
+
client,
|
|
756
|
+
context,
|
|
757
|
+
swapPostProcess
|
|
758
|
+
);
|
|
759
|
+
return { ...result, ...payload.extras };
|
|
760
|
+
}
|
|
681
761
|
};
|
|
762
|
+
var swapTool = new SwapTool();
|
|
682
763
|
|
|
683
764
|
// src/index.ts
|
|
765
|
+
var saucerswapPluginToolNames = {
|
|
766
|
+
SAUCERSWAP_GET_SWAP_QUOTE_TOOL: "saucerswap_get_swap_quote",
|
|
767
|
+
SAUCERSWAP_SWAP_TOKENS_TOOL: "saucerswap_swap_tokens",
|
|
768
|
+
SAUCERSWAP_GET_POOLS_TOOL: "saucerswap_get_pools",
|
|
769
|
+
SAUCERSWAP_ADD_LIQUIDITY_TOOL: "saucerswap_add_liquidity",
|
|
770
|
+
SAUCERSWAP_REMOVE_LIQUIDITY_TOOL: "saucerswap_remove_liquidity",
|
|
771
|
+
SAUCERSWAP_GET_FARMS_TOOL: "saucerswap_get_farms"
|
|
772
|
+
};
|
|
684
773
|
var saucerswapPlugin = {
|
|
685
774
|
name: "saucerswap",
|
|
686
775
|
description: "Integration with SaucerSwap DEX for token swaps, liquidity provision, and yield farming",
|
|
@@ -689,5 +778,6 @@ var saucerswapPlugin = {
|
|
|
689
778
|
|
|
690
779
|
exports.default = saucerswapPlugin;
|
|
691
780
|
exports.saucerswapPlugin = saucerswapPlugin;
|
|
781
|
+
exports.saucerswapPluginToolNames = saucerswapPluginToolNames;
|
|
692
782
|
//# sourceMappingURL=index.cjs.map
|
|
693
783
|
//# sourceMappingURL=index.cjs.map
|