@owney/sdk 0.3.5 → 0.4.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/README.md +64 -8
- package/dist/index.cjs +166 -61
- package/dist/index.d.cts +29 -7
- package/dist/index.d.ts +29 -7
- package/dist/index.js +165 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -298,11 +298,17 @@ console.log(allApy.apyByChainAndAsset[42161]?.USDT); // 4.7
|
|
|
298
298
|
|
|
299
299
|
Get transaction history for a specific agent, or all agents. When querying all agents, results are merged into a single list sorted by date (newest first). Each entry includes the originating `agent` and a `transactions` array with typed on-chain transaction details.
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
|
301
|
+
Results are **cursor-paginated**. The first call (no `cursor`) anchors a stable snapshot at the current time; subsequent pages within that same snapshot are consistent. Each new cursorless call captures a fresh snapshot — if you need to preserve scroll position while paging, always carry forward the cursor returned by the previous call rather than starting a new cursorless fetch.
|
|
302
|
+
|
|
303
|
+
> **Per-chain filtering:** The Zyfai backend no longer accepts a `chainId` filter directly. The SDK performs a bounded internal drain (up to 5 backend round-trips per logical page) to fill the requested `limit` with entries matching the active chain. This is transparent to callers — the `getHistory` API is unchanged.
|
|
304
|
+
|
|
305
|
+
| Param | Type | Description |
|
|
306
|
+
| ------------------ | ------------------------------ | -------------------------------------------------------- |
|
|
307
|
+
| `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
|
|
308
|
+
| `filters.fromDate` | `string` (optional) | Start date (`YYYY-MM-DD`) |
|
|
309
|
+
| `filters.toDate` | `string` (optional) | End date (`YYYY-MM-DD`) |
|
|
310
|
+
| `filters.limit` | `number` (optional) | Max entries returned per call. Defaults to `10`. |
|
|
311
|
+
| `filters.cursor` | `string` (optional) | Opaque cursor returned by a previous `getHistory` call. |
|
|
306
312
|
|
|
307
313
|
Returns: `OwneyAgentHistory`
|
|
308
314
|
|
|
@@ -312,7 +318,7 @@ const history = await sdk.getHistory({
|
|
|
312
318
|
agentId: "zyfai",
|
|
313
319
|
filters: { fromDate: "2025-01-01" },
|
|
314
320
|
});
|
|
315
|
-
console.log(history.
|
|
321
|
+
console.log(history.hasMore); // true | false
|
|
316
322
|
console.log(history.data[0].agent); // "zyfai"
|
|
317
323
|
console.log(history.data[0].action); // "Rebalance"
|
|
318
324
|
console.log(history.data[0].date); // "2025-03-15T12:00:00Z"
|
|
@@ -329,9 +335,20 @@ console.log(history.data[0].rebalanceLog[0].status); // "success"
|
|
|
329
335
|
|
|
330
336
|
// All agents (merged and sorted by date)
|
|
331
337
|
const allHistory = await sdk.getHistory();
|
|
332
|
-
console.log(allHistory.
|
|
338
|
+
console.log(allHistory.hasMore); // true | false
|
|
333
339
|
console.log(allHistory.data[0].agent); // "sail" (most recent entry)
|
|
334
340
|
console.log(allHistory.data[0].action); // "Rebalance"
|
|
341
|
+
|
|
342
|
+
// Paginate through all history (per-chain, anchored to a single snapshot)
|
|
343
|
+
const allEntries: AgentHistoryEntry[] = [];
|
|
344
|
+
let cursor: string | undefined;
|
|
345
|
+
do {
|
|
346
|
+
const page = await sdk.getHistory({
|
|
347
|
+
filters: { cursor, limit: 50 },
|
|
348
|
+
});
|
|
349
|
+
allEntries.push(...page.data);
|
|
350
|
+
cursor = page.hasMore ? page.nextCursor : undefined;
|
|
351
|
+
} while (cursor);
|
|
335
352
|
```
|
|
336
353
|
|
|
337
354
|
### `pauseAgent(agentId)`
|
|
@@ -481,6 +498,10 @@ interface ConnectionState {
|
|
|
481
498
|
type HistoryFilters = {
|
|
482
499
|
fromDate?: string; // YYYY-MM-DD
|
|
483
500
|
toDate?: string; // YYYY-MM-DD
|
|
501
|
+
/** Max entries returned per call. Defaults to 10. */
|
|
502
|
+
limit?: number;
|
|
503
|
+
/** Opaque cursor returned by a previous getHistory call. */
|
|
504
|
+
cursor?: string;
|
|
484
505
|
};
|
|
485
506
|
|
|
486
507
|
type HistoryOptions = {
|
|
@@ -612,7 +633,10 @@ interface AgentHistoryEntry {
|
|
|
612
633
|
|
|
613
634
|
interface OwneyAgentHistory {
|
|
614
635
|
data: AgentHistoryEntry[];
|
|
615
|
-
|
|
636
|
+
/** True iff a subsequent page exists; pair with `nextCursor`. */
|
|
637
|
+
hasMore: boolean;
|
|
638
|
+
/** Opaque cursor for the next page. Present iff `hasMore === true`. */
|
|
639
|
+
nextCursor?: string;
|
|
616
640
|
}
|
|
617
641
|
|
|
618
642
|
interface OwneyAgentStatus {
|
|
@@ -750,6 +774,38 @@ The three convenience subclasses extend `OwneyError` and remain backwards-compat
|
|
|
750
774
|
| `AgentNotFoundError` | `AGENT_NOT_FOUND` | — |
|
|
751
775
|
| `AgentChainIncompatibleError` | `AGENT_CHAIN_INCOMPATIBLE` | `incompatibleAgents`, `connectedChainId` |
|
|
752
776
|
|
|
777
|
+
### Cursor errors
|
|
778
|
+
|
|
779
|
+
`InvalidHistoryCursorError` is thrown by `getHistory` when the supplied cursor is invalid. It extends `Error` directly — **not** `OwneyError` — so a `catch` block that only checks `instanceof OwneyError` will not catch it. Catch it separately:
|
|
780
|
+
|
|
781
|
+
```typescript
|
|
782
|
+
import { InvalidHistoryCursorError } from "@owney/sdk";
|
|
783
|
+
|
|
784
|
+
try {
|
|
785
|
+
const page = await sdk.getHistory({ filters: { cursor: storedCursor } });
|
|
786
|
+
} catch (error) {
|
|
787
|
+
if (error instanceof InvalidHistoryCursorError) {
|
|
788
|
+
// Stored cursor is stale or malformed — reset pagination.
|
|
789
|
+
storedCursor = undefined;
|
|
790
|
+
// Refetch first page...
|
|
791
|
+
} else {
|
|
792
|
+
throw error;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
`InvalidHistoryCursorError` carries a stable `code` property (value: `"invalid_cursor"`) and is thrown when:
|
|
798
|
+
|
|
799
|
+
- The supplied cursor is an empty string.
|
|
800
|
+
- The cursor is not valid base64 JSON.
|
|
801
|
+
- The cursor payload has the wrong shape (e.g. a cursor from a different pagination context).
|
|
802
|
+
|
|
803
|
+
**Recovery:** catch `InvalidHistoryCursorError`, clear your stored cursor, and refetch from page 1.
|
|
804
|
+
|
|
805
|
+
| Class | `code` | Extends |
|
|
806
|
+
| ---------------------------- | ----------------- | ---------- |
|
|
807
|
+
| `InvalidHistoryCursorError` | `"invalid_cursor"`| `Error` |
|
|
808
|
+
|
|
753
809
|
## License
|
|
754
810
|
|
|
755
811
|
ELv2
|
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
AgentChainIncompatibleError: () => AgentChainIncompatibleError,
|
|
24
24
|
AgentNotFoundError: () => AgentNotFoundError,
|
|
25
|
+
InvalidHistoryCursorError: () => InvalidHistoryCursorError,
|
|
25
26
|
NotConnectedError: () => NotConnectedError,
|
|
26
27
|
OwneyError: () => OwneyError,
|
|
27
28
|
OwneySDK: () => OwneySDK
|
|
@@ -237,7 +238,7 @@ function mapApyHistory(raw) {
|
|
|
237
238
|
apyByChainAndAsset: mapWeightedApyByChain(raw.weightedApyAfterFeeByChain)
|
|
238
239
|
};
|
|
239
240
|
}
|
|
240
|
-
function
|
|
241
|
+
function mapEntries(rawEntries, chainId) {
|
|
241
242
|
const actionMap = {
|
|
242
243
|
"Deposit to protocol": "Deposit",
|
|
243
244
|
"Top up wallet": "Top up",
|
|
@@ -245,50 +246,47 @@ function mapHistory(raw, chainId) {
|
|
|
245
246
|
"Withdraw from protocol": "Withdraw",
|
|
246
247
|
Rebalance: "Rebalance"
|
|
247
248
|
};
|
|
248
|
-
return {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
};
|
|
290
|
-
})
|
|
291
|
-
};
|
|
249
|
+
return rawEntries.map((entry) => {
|
|
250
|
+
const rawLog = entry.rebalanceLog;
|
|
251
|
+
const positions = entry.positions ?? [];
|
|
252
|
+
let rebalanceLog = [];
|
|
253
|
+
let oldApy = null;
|
|
254
|
+
let newApy = null;
|
|
255
|
+
if (rawLog) {
|
|
256
|
+
const matched = positions.find(
|
|
257
|
+
(p) => p.protocol_name ? rawLog.newOpportunity.includes(`${p.protocol_name} (${p.pool})`) : false
|
|
258
|
+
);
|
|
259
|
+
oldApy = Number(rawLog.oldApy);
|
|
260
|
+
newApy = Number(rawLog.newApy);
|
|
261
|
+
rebalanceLog = [
|
|
262
|
+
{
|
|
263
|
+
fromProtocol: rawLog.oldOpportunity.replace(/\s*\(.*?\)/g, "").trim(),
|
|
264
|
+
toProtocol: rawLog.newOpportunity.replace(/\s*\(.*?\)/g, "").trim(),
|
|
265
|
+
tokenSymbol: matched?.token_symbol ?? "",
|
|
266
|
+
amount: matched ? String(hexToDecimal(matched.amount || "0x")) : "",
|
|
267
|
+
status: "success"
|
|
268
|
+
}
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
const rawAmount = entry?.positions?.[0]?.amount;
|
|
272
|
+
const hasAmount = typeof rawAmount === "string" && rawAmount !== "" && rawAmount !== "0x" && rawAmount !== "0x0" && rawAmount !== "0";
|
|
273
|
+
return {
|
|
274
|
+
agent: "zyfai",
|
|
275
|
+
action: (entry.action ? actionMap[entry.action] : void 0) ?? entry.action,
|
|
276
|
+
date: entry.date || "",
|
|
277
|
+
newApy: newApy === null ? null : String(newApy),
|
|
278
|
+
oldApy: oldApy === null ? null : String(oldApy),
|
|
279
|
+
transactions: [
|
|
280
|
+
{
|
|
281
|
+
txHashes: entry.transactionHash ? [entry.transactionHash] : [],
|
|
282
|
+
chainId: entry.chainId,
|
|
283
|
+
tokenSymbol: entry?.positions?.[0]?.token_symbol,
|
|
284
|
+
amount: hasAmount ? String(hexToDecimal(rawAmount)) : void 0
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
rebalanceLog
|
|
288
|
+
};
|
|
289
|
+
});
|
|
292
290
|
}
|
|
293
291
|
function mapAgentStatus(raw) {
|
|
294
292
|
return {
|
|
@@ -333,6 +331,33 @@ function mapApyByStrategy(raw) {
|
|
|
333
331
|
};
|
|
334
332
|
}
|
|
335
333
|
|
|
334
|
+
// src/agents/zyfai/zyfai.history-cursor.ts
|
|
335
|
+
var InvalidHistoryCursorError = class extends Error {
|
|
336
|
+
code = "invalid_cursor";
|
|
337
|
+
constructor(message) {
|
|
338
|
+
super(message);
|
|
339
|
+
this.name = "InvalidHistoryCursorError";
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
function encodeHistoryCursor(payload) {
|
|
343
|
+
return Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
|
|
344
|
+
}
|
|
345
|
+
function decodeHistoryCursor(token) {
|
|
346
|
+
if (!token)
|
|
347
|
+
throw new InvalidHistoryCursorError("Cursor is empty.");
|
|
348
|
+
let parsed;
|
|
349
|
+
try {
|
|
350
|
+
const json = Buffer.from(token, "base64").toString("utf8");
|
|
351
|
+
parsed = JSON.parse(json);
|
|
352
|
+
} catch {
|
|
353
|
+
throw new InvalidHistoryCursorError("Cursor is not valid base64 JSON.");
|
|
354
|
+
}
|
|
355
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.toDate !== "string" || parsed.toDate.length === 0 || Number.isNaN(Date.parse(parsed.toDate)) || typeof parsed.rawOffset !== "number" || !Number.isFinite(parsed.rawOffset) || parsed.rawOffset < 0 || !Number.isInteger(parsed.rawOffset)) {
|
|
356
|
+
throw new InvalidHistoryCursorError("Cursor payload has wrong shape.");
|
|
357
|
+
}
|
|
358
|
+
return parsed;
|
|
359
|
+
}
|
|
360
|
+
|
|
336
361
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
337
362
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
338
363
|
var storage = () => {
|
|
@@ -647,8 +672,38 @@ var ZyfaiAgent = class {
|
|
|
647
672
|
}
|
|
648
673
|
async getHistory(state, chainId, options) {
|
|
649
674
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
650
|
-
const
|
|
651
|
-
|
|
675
|
+
const limit = options?.limit ?? 10;
|
|
676
|
+
const cursor = options?.cursor ? decodeHistoryCursor(options.cursor) : null;
|
|
677
|
+
const toDate = cursor?.toDate ?? options?.toDate ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
678
|
+
let offset = cursor?.rawOffset ?? 0;
|
|
679
|
+
const MAX_BACKEND_CALLS = 5;
|
|
680
|
+
const MIN_BACKEND_PAGE_SIZE = 20;
|
|
681
|
+
const backendPageSize = Math.max(limit, MIN_BACKEND_PAGE_SIZE);
|
|
682
|
+
const matched = [];
|
|
683
|
+
let backendExhausted = false;
|
|
684
|
+
for (let i = 0; i < MAX_BACKEND_CALLS && matched.length < limit; i++) {
|
|
685
|
+
const raw = await this.sdk.getHistory(smartWallet, validChainId, {
|
|
686
|
+
limit: backendPageSize,
|
|
687
|
+
offset,
|
|
688
|
+
fromDate: options?.fromDate,
|
|
689
|
+
toDate
|
|
690
|
+
});
|
|
691
|
+
matched.push(...raw.data.filter((e) => e.chainId === validChainId));
|
|
692
|
+
offset += raw.data.length;
|
|
693
|
+
if (raw.data.length < backendPageSize) {
|
|
694
|
+
backendExhausted = true;
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
const overshoot = Math.max(0, matched.length - limit);
|
|
699
|
+
const pageData = matched.slice(0, limit);
|
|
700
|
+
const hasMore = !backendExhausted || overshoot > 0;
|
|
701
|
+
const nextCursor = hasMore ? encodeHistoryCursor({ toDate, rawOffset: offset - overshoot }) : void 0;
|
|
702
|
+
return {
|
|
703
|
+
data: mapEntries(pageData, validChainId),
|
|
704
|
+
hasMore,
|
|
705
|
+
nextCursor
|
|
706
|
+
};
|
|
652
707
|
}
|
|
653
708
|
// --- IAgent: Agent control ---
|
|
654
709
|
async pause(state, chainId) {
|
|
@@ -840,6 +895,26 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
840
895
|
}
|
|
841
896
|
|
|
842
897
|
// src/client.ts
|
|
898
|
+
function encodeMultiAgentCursor(map) {
|
|
899
|
+
return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
|
|
900
|
+
}
|
|
901
|
+
function decodeMultiAgentCursor(token) {
|
|
902
|
+
let parsed;
|
|
903
|
+
try {
|
|
904
|
+
const json = Buffer.from(token, "base64").toString("utf8");
|
|
905
|
+
parsed = JSON.parse(json);
|
|
906
|
+
} catch {
|
|
907
|
+
throw new InvalidHistoryCursorError(
|
|
908
|
+
"Multi-agent cursor is not valid base64 JSON."
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
if (!parsed || typeof parsed !== "object" || !Object.values(parsed).every((v) => typeof v === "string")) {
|
|
912
|
+
throw new InvalidHistoryCursorError(
|
|
913
|
+
"Multi-agent cursor payload has wrong shape."
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
return parsed;
|
|
917
|
+
}
|
|
843
918
|
var OwneySDK = class {
|
|
844
919
|
agents = /* @__PURE__ */ new Map();
|
|
845
920
|
activeAgents = /* @__PURE__ */ new Set();
|
|
@@ -1509,10 +1584,20 @@ var OwneySDK = class {
|
|
|
1509
1584
|
}
|
|
1510
1585
|
/**
|
|
1511
1586
|
* Get transaction history for a specific agent, or all agents.
|
|
1512
|
-
*
|
|
1513
|
-
*
|
|
1514
|
-
*
|
|
1515
|
-
*
|
|
1587
|
+
*
|
|
1588
|
+
* Pagination uses an opaque cursor (`filters.cursor`). The first call without
|
|
1589
|
+
* a cursor anchors a snapshot at "now"; subsequent pages within that snapshot
|
|
1590
|
+
* are stable. Each cursorless call captures a NEW snapshot, so do not mix
|
|
1591
|
+
* cursors issued by different first-page calls — refreshes that need to
|
|
1592
|
+
* preserve the user's scroll position should keep using cursors from the
|
|
1593
|
+
* original snapshot.
|
|
1594
|
+
*
|
|
1595
|
+
* @param params.agentId - Optional. Agent to query. Omit for all active agents.
|
|
1596
|
+
* @param params.filters - Optional. Pagination + date filters.
|
|
1597
|
+
* - `limit`: max entries per page (default 10)
|
|
1598
|
+
* - `cursor`: opaque cursor returned by a previous call
|
|
1599
|
+
* - `fromDate` / `toDate`: ISO 8601 date strings
|
|
1600
|
+
* @returns {OwneyAgentHistory} `data` (up to `limit` entries), `hasMore`, `nextCursor`.
|
|
1516
1601
|
*/
|
|
1517
1602
|
async getHistory(params) {
|
|
1518
1603
|
const state = this.requireState();
|
|
@@ -1521,21 +1606,40 @@ var OwneySDK = class {
|
|
|
1521
1606
|
if (agentId) {
|
|
1522
1607
|
return this.getAgent(agentId).getHistory(state, chainId, filters);
|
|
1523
1608
|
}
|
|
1524
|
-
const
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
)
|
|
1609
|
+
const activeAgents = [...this.getActiveAgents().values()];
|
|
1610
|
+
const cursorMap = filters?.cursor ? decodeMultiAgentCursor(filters.cursor) : {};
|
|
1611
|
+
const perAgent = await Promise.all(
|
|
1612
|
+
activeAgents.map(async (agent) => {
|
|
1613
|
+
const agentCursor = cursorMap[agent.id];
|
|
1614
|
+
if (filters?.cursor && agentCursor === void 0) {
|
|
1615
|
+
return { agentId: agent.id, page: null };
|
|
1616
|
+
}
|
|
1617
|
+
const page = await agent.getHistory(state, chainId, {
|
|
1618
|
+
...filters,
|
|
1619
|
+
cursor: agentCursor
|
|
1620
|
+
});
|
|
1621
|
+
return { agentId: agent.id, page };
|
|
1622
|
+
})
|
|
1528
1623
|
);
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1624
|
+
const merged = [];
|
|
1625
|
+
const nextCursorMap = {};
|
|
1626
|
+
let hasMore = false;
|
|
1627
|
+
for (const { agentId: id, page } of perAgent) {
|
|
1628
|
+
if (!page)
|
|
1629
|
+
continue;
|
|
1630
|
+
merged.push(...page.data);
|
|
1631
|
+
if (page.hasMore && page.nextCursor) {
|
|
1632
|
+
nextCursorMap[id] = page.nextCursor;
|
|
1633
|
+
hasMore = true;
|
|
1634
|
+
}
|
|
1532
1635
|
}
|
|
1533
|
-
|
|
1636
|
+
merged.sort(
|
|
1534
1637
|
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
|
|
1535
1638
|
);
|
|
1536
1639
|
return {
|
|
1537
|
-
|
|
1538
|
-
|
|
1640
|
+
data: merged,
|
|
1641
|
+
hasMore,
|
|
1642
|
+
nextCursor: hasMore ? encodeMultiAgentCursor(nextCursorMap) : void 0
|
|
1539
1643
|
};
|
|
1540
1644
|
}
|
|
1541
1645
|
// --- Agent control ---
|
|
@@ -1690,6 +1794,7 @@ var OwneySDK = class {
|
|
|
1690
1794
|
0 && (module.exports = {
|
|
1691
1795
|
AgentChainIncompatibleError,
|
|
1692
1796
|
AgentNotFoundError,
|
|
1797
|
+
InvalidHistoryCursorError,
|
|
1693
1798
|
NotConnectedError,
|
|
1694
1799
|
OwneyError,
|
|
1695
1800
|
OwneySDK
|
package/dist/index.d.cts
CHANGED
|
@@ -48,7 +48,7 @@ type AgentApyOptions = {
|
|
|
48
48
|
chainId?: number;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
type AgentId = "zyfai";
|
|
51
|
+
type AgentId = "zyfai" | "sail";
|
|
52
52
|
type Asset = string;
|
|
53
53
|
type AgentSupportedAsset = {
|
|
54
54
|
readonly symbol: string;
|
|
@@ -63,6 +63,10 @@ type DailyApyDays = "7D" | "14D" | "30D";
|
|
|
63
63
|
type HistoryFilters = {
|
|
64
64
|
fromDate?: string;
|
|
65
65
|
toDate?: string;
|
|
66
|
+
/** Max entries returned per call. Defaults to 10. */
|
|
67
|
+
limit?: number;
|
|
68
|
+
/** Opaque cursor returned by a previous getHistory call. */
|
|
69
|
+
cursor?: string;
|
|
66
70
|
};
|
|
67
71
|
type HistoryOptions = {
|
|
68
72
|
agentId?: AgentId;
|
|
@@ -177,7 +181,10 @@ interface AgentHistoryEntry {
|
|
|
177
181
|
}
|
|
178
182
|
interface OwneyAgentHistory {
|
|
179
183
|
data: AgentHistoryEntry[];
|
|
180
|
-
|
|
184
|
+
/** True iff a subsequent page exists; pair with `nextCursor`. */
|
|
185
|
+
hasMore: boolean;
|
|
186
|
+
/** Opaque cursor for the next page. Present iff `hasMore === true`. */
|
|
187
|
+
nextCursor?: string;
|
|
181
188
|
}
|
|
182
189
|
interface OwneyAgentStatus {
|
|
183
190
|
success: boolean;
|
|
@@ -320,10 +327,20 @@ declare class OwneySDK {
|
|
|
320
327
|
getAccountApy({ agentId, days, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
|
|
321
328
|
/**
|
|
322
329
|
* Get transaction history for a specific agent, or all agents.
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
330
|
+
*
|
|
331
|
+
* Pagination uses an opaque cursor (`filters.cursor`). The first call without
|
|
332
|
+
* a cursor anchors a snapshot at "now"; subsequent pages within that snapshot
|
|
333
|
+
* are stable. Each cursorless call captures a NEW snapshot, so do not mix
|
|
334
|
+
* cursors issued by different first-page calls — refreshes that need to
|
|
335
|
+
* preserve the user's scroll position should keep using cursors from the
|
|
336
|
+
* original snapshot.
|
|
337
|
+
*
|
|
338
|
+
* @param params.agentId - Optional. Agent to query. Omit for all active agents.
|
|
339
|
+
* @param params.filters - Optional. Pagination + date filters.
|
|
340
|
+
* - `limit`: max entries per page (default 10)
|
|
341
|
+
* - `cursor`: opaque cursor returned by a previous call
|
|
342
|
+
* - `fromDate` / `toDate`: ISO 8601 date strings
|
|
343
|
+
* @returns {OwneyAgentHistory} `data` (up to `limit` entries), `hasMore`, `nextCursor`.
|
|
327
344
|
*/
|
|
328
345
|
getHistory(params?: HistoryOptions): Promise<OwneyAgentHistory>;
|
|
329
346
|
/**
|
|
@@ -389,4 +406,9 @@ declare class AgentChainIncompatibleError extends OwneyError {
|
|
|
389
406
|
}>, connectedChainId: number);
|
|
390
407
|
}
|
|
391
408
|
|
|
392
|
-
|
|
409
|
+
declare class InvalidHistoryCursorError extends Error {
|
|
410
|
+
readonly code: "invalid_cursor";
|
|
411
|
+
constructor(message: string);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneySDK, OwneySDKConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ type AgentApyOptions = {
|
|
|
48
48
|
chainId?: number;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
type AgentId = "zyfai";
|
|
51
|
+
type AgentId = "zyfai" | "sail";
|
|
52
52
|
type Asset = string;
|
|
53
53
|
type AgentSupportedAsset = {
|
|
54
54
|
readonly symbol: string;
|
|
@@ -63,6 +63,10 @@ type DailyApyDays = "7D" | "14D" | "30D";
|
|
|
63
63
|
type HistoryFilters = {
|
|
64
64
|
fromDate?: string;
|
|
65
65
|
toDate?: string;
|
|
66
|
+
/** Max entries returned per call. Defaults to 10. */
|
|
67
|
+
limit?: number;
|
|
68
|
+
/** Opaque cursor returned by a previous getHistory call. */
|
|
69
|
+
cursor?: string;
|
|
66
70
|
};
|
|
67
71
|
type HistoryOptions = {
|
|
68
72
|
agentId?: AgentId;
|
|
@@ -177,7 +181,10 @@ interface AgentHistoryEntry {
|
|
|
177
181
|
}
|
|
178
182
|
interface OwneyAgentHistory {
|
|
179
183
|
data: AgentHistoryEntry[];
|
|
180
|
-
|
|
184
|
+
/** True iff a subsequent page exists; pair with `nextCursor`. */
|
|
185
|
+
hasMore: boolean;
|
|
186
|
+
/** Opaque cursor for the next page. Present iff `hasMore === true`. */
|
|
187
|
+
nextCursor?: string;
|
|
181
188
|
}
|
|
182
189
|
interface OwneyAgentStatus {
|
|
183
190
|
success: boolean;
|
|
@@ -320,10 +327,20 @@ declare class OwneySDK {
|
|
|
320
327
|
getAccountApy({ agentId, days, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
|
|
321
328
|
/**
|
|
322
329
|
* Get transaction history for a specific agent, or all agents.
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
330
|
+
*
|
|
331
|
+
* Pagination uses an opaque cursor (`filters.cursor`). The first call without
|
|
332
|
+
* a cursor anchors a snapshot at "now"; subsequent pages within that snapshot
|
|
333
|
+
* are stable. Each cursorless call captures a NEW snapshot, so do not mix
|
|
334
|
+
* cursors issued by different first-page calls — refreshes that need to
|
|
335
|
+
* preserve the user's scroll position should keep using cursors from the
|
|
336
|
+
* original snapshot.
|
|
337
|
+
*
|
|
338
|
+
* @param params.agentId - Optional. Agent to query. Omit for all active agents.
|
|
339
|
+
* @param params.filters - Optional. Pagination + date filters.
|
|
340
|
+
* - `limit`: max entries per page (default 10)
|
|
341
|
+
* - `cursor`: opaque cursor returned by a previous call
|
|
342
|
+
* - `fromDate` / `toDate`: ISO 8601 date strings
|
|
343
|
+
* @returns {OwneyAgentHistory} `data` (up to `limit` entries), `hasMore`, `nextCursor`.
|
|
327
344
|
*/
|
|
328
345
|
getHistory(params?: HistoryOptions): Promise<OwneyAgentHistory>;
|
|
329
346
|
/**
|
|
@@ -389,4 +406,9 @@ declare class AgentChainIncompatibleError extends OwneyError {
|
|
|
389
406
|
}>, connectedChainId: number);
|
|
390
407
|
}
|
|
391
408
|
|
|
392
|
-
|
|
409
|
+
declare class InvalidHistoryCursorError extends Error {
|
|
410
|
+
readonly code: "invalid_cursor";
|
|
411
|
+
constructor(message: string);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneySDK, OwneySDKConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
package/dist/index.js
CHANGED
|
@@ -207,7 +207,7 @@ function mapApyHistory(raw) {
|
|
|
207
207
|
apyByChainAndAsset: mapWeightedApyByChain(raw.weightedApyAfterFeeByChain)
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
|
-
function
|
|
210
|
+
function mapEntries(rawEntries, chainId) {
|
|
211
211
|
const actionMap = {
|
|
212
212
|
"Deposit to protocol": "Deposit",
|
|
213
213
|
"Top up wallet": "Top up",
|
|
@@ -215,50 +215,47 @@ function mapHistory(raw, chainId) {
|
|
|
215
215
|
"Withdraw from protocol": "Withdraw",
|
|
216
216
|
Rebalance: "Rebalance"
|
|
217
217
|
};
|
|
218
|
-
return {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
};
|
|
260
|
-
})
|
|
261
|
-
};
|
|
218
|
+
return rawEntries.map((entry) => {
|
|
219
|
+
const rawLog = entry.rebalanceLog;
|
|
220
|
+
const positions = entry.positions ?? [];
|
|
221
|
+
let rebalanceLog = [];
|
|
222
|
+
let oldApy = null;
|
|
223
|
+
let newApy = null;
|
|
224
|
+
if (rawLog) {
|
|
225
|
+
const matched = positions.find(
|
|
226
|
+
(p) => p.protocol_name ? rawLog.newOpportunity.includes(`${p.protocol_name} (${p.pool})`) : false
|
|
227
|
+
);
|
|
228
|
+
oldApy = Number(rawLog.oldApy);
|
|
229
|
+
newApy = Number(rawLog.newApy);
|
|
230
|
+
rebalanceLog = [
|
|
231
|
+
{
|
|
232
|
+
fromProtocol: rawLog.oldOpportunity.replace(/\s*\(.*?\)/g, "").trim(),
|
|
233
|
+
toProtocol: rawLog.newOpportunity.replace(/\s*\(.*?\)/g, "").trim(),
|
|
234
|
+
tokenSymbol: matched?.token_symbol ?? "",
|
|
235
|
+
amount: matched ? String(hexToDecimal(matched.amount || "0x")) : "",
|
|
236
|
+
status: "success"
|
|
237
|
+
}
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
const rawAmount = entry?.positions?.[0]?.amount;
|
|
241
|
+
const hasAmount = typeof rawAmount === "string" && rawAmount !== "" && rawAmount !== "0x" && rawAmount !== "0x0" && rawAmount !== "0";
|
|
242
|
+
return {
|
|
243
|
+
agent: "zyfai",
|
|
244
|
+
action: (entry.action ? actionMap[entry.action] : void 0) ?? entry.action,
|
|
245
|
+
date: entry.date || "",
|
|
246
|
+
newApy: newApy === null ? null : String(newApy),
|
|
247
|
+
oldApy: oldApy === null ? null : String(oldApy),
|
|
248
|
+
transactions: [
|
|
249
|
+
{
|
|
250
|
+
txHashes: entry.transactionHash ? [entry.transactionHash] : [],
|
|
251
|
+
chainId: entry.chainId,
|
|
252
|
+
tokenSymbol: entry?.positions?.[0]?.token_symbol,
|
|
253
|
+
amount: hasAmount ? String(hexToDecimal(rawAmount)) : void 0
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
rebalanceLog
|
|
257
|
+
};
|
|
258
|
+
});
|
|
262
259
|
}
|
|
263
260
|
function mapAgentStatus(raw) {
|
|
264
261
|
return {
|
|
@@ -303,6 +300,33 @@ function mapApyByStrategy(raw) {
|
|
|
303
300
|
};
|
|
304
301
|
}
|
|
305
302
|
|
|
303
|
+
// src/agents/zyfai/zyfai.history-cursor.ts
|
|
304
|
+
var InvalidHistoryCursorError = class extends Error {
|
|
305
|
+
code = "invalid_cursor";
|
|
306
|
+
constructor(message) {
|
|
307
|
+
super(message);
|
|
308
|
+
this.name = "InvalidHistoryCursorError";
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
function encodeHistoryCursor(payload) {
|
|
312
|
+
return Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
|
|
313
|
+
}
|
|
314
|
+
function decodeHistoryCursor(token) {
|
|
315
|
+
if (!token)
|
|
316
|
+
throw new InvalidHistoryCursorError("Cursor is empty.");
|
|
317
|
+
let parsed;
|
|
318
|
+
try {
|
|
319
|
+
const json = Buffer.from(token, "base64").toString("utf8");
|
|
320
|
+
parsed = JSON.parse(json);
|
|
321
|
+
} catch {
|
|
322
|
+
throw new InvalidHistoryCursorError("Cursor is not valid base64 JSON.");
|
|
323
|
+
}
|
|
324
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.toDate !== "string" || parsed.toDate.length === 0 || Number.isNaN(Date.parse(parsed.toDate)) || typeof parsed.rawOffset !== "number" || !Number.isFinite(parsed.rawOffset) || parsed.rawOffset < 0 || !Number.isInteger(parsed.rawOffset)) {
|
|
325
|
+
throw new InvalidHistoryCursorError("Cursor payload has wrong shape.");
|
|
326
|
+
}
|
|
327
|
+
return parsed;
|
|
328
|
+
}
|
|
329
|
+
|
|
306
330
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
307
331
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
308
332
|
var storage = () => {
|
|
@@ -617,8 +641,38 @@ var ZyfaiAgent = class {
|
|
|
617
641
|
}
|
|
618
642
|
async getHistory(state, chainId, options) {
|
|
619
643
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
620
|
-
const
|
|
621
|
-
|
|
644
|
+
const limit = options?.limit ?? 10;
|
|
645
|
+
const cursor = options?.cursor ? decodeHistoryCursor(options.cursor) : null;
|
|
646
|
+
const toDate = cursor?.toDate ?? options?.toDate ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
647
|
+
let offset = cursor?.rawOffset ?? 0;
|
|
648
|
+
const MAX_BACKEND_CALLS = 5;
|
|
649
|
+
const MIN_BACKEND_PAGE_SIZE = 20;
|
|
650
|
+
const backendPageSize = Math.max(limit, MIN_BACKEND_PAGE_SIZE);
|
|
651
|
+
const matched = [];
|
|
652
|
+
let backendExhausted = false;
|
|
653
|
+
for (let i = 0; i < MAX_BACKEND_CALLS && matched.length < limit; i++) {
|
|
654
|
+
const raw = await this.sdk.getHistory(smartWallet, validChainId, {
|
|
655
|
+
limit: backendPageSize,
|
|
656
|
+
offset,
|
|
657
|
+
fromDate: options?.fromDate,
|
|
658
|
+
toDate
|
|
659
|
+
});
|
|
660
|
+
matched.push(...raw.data.filter((e) => e.chainId === validChainId));
|
|
661
|
+
offset += raw.data.length;
|
|
662
|
+
if (raw.data.length < backendPageSize) {
|
|
663
|
+
backendExhausted = true;
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const overshoot = Math.max(0, matched.length - limit);
|
|
668
|
+
const pageData = matched.slice(0, limit);
|
|
669
|
+
const hasMore = !backendExhausted || overshoot > 0;
|
|
670
|
+
const nextCursor = hasMore ? encodeHistoryCursor({ toDate, rawOffset: offset - overshoot }) : void 0;
|
|
671
|
+
return {
|
|
672
|
+
data: mapEntries(pageData, validChainId),
|
|
673
|
+
hasMore,
|
|
674
|
+
nextCursor
|
|
675
|
+
};
|
|
622
676
|
}
|
|
623
677
|
// --- IAgent: Agent control ---
|
|
624
678
|
async pause(state, chainId) {
|
|
@@ -810,6 +864,26 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
810
864
|
}
|
|
811
865
|
|
|
812
866
|
// src/client.ts
|
|
867
|
+
function encodeMultiAgentCursor(map) {
|
|
868
|
+
return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
|
|
869
|
+
}
|
|
870
|
+
function decodeMultiAgentCursor(token) {
|
|
871
|
+
let parsed;
|
|
872
|
+
try {
|
|
873
|
+
const json = Buffer.from(token, "base64").toString("utf8");
|
|
874
|
+
parsed = JSON.parse(json);
|
|
875
|
+
} catch {
|
|
876
|
+
throw new InvalidHistoryCursorError(
|
|
877
|
+
"Multi-agent cursor is not valid base64 JSON."
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
if (!parsed || typeof parsed !== "object" || !Object.values(parsed).every((v) => typeof v === "string")) {
|
|
881
|
+
throw new InvalidHistoryCursorError(
|
|
882
|
+
"Multi-agent cursor payload has wrong shape."
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
return parsed;
|
|
886
|
+
}
|
|
813
887
|
var OwneySDK = class {
|
|
814
888
|
agents = /* @__PURE__ */ new Map();
|
|
815
889
|
activeAgents = /* @__PURE__ */ new Set();
|
|
@@ -1479,10 +1553,20 @@ var OwneySDK = class {
|
|
|
1479
1553
|
}
|
|
1480
1554
|
/**
|
|
1481
1555
|
* Get transaction history for a specific agent, or all agents.
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1485
|
-
*
|
|
1556
|
+
*
|
|
1557
|
+
* Pagination uses an opaque cursor (`filters.cursor`). The first call without
|
|
1558
|
+
* a cursor anchors a snapshot at "now"; subsequent pages within that snapshot
|
|
1559
|
+
* are stable. Each cursorless call captures a NEW snapshot, so do not mix
|
|
1560
|
+
* cursors issued by different first-page calls — refreshes that need to
|
|
1561
|
+
* preserve the user's scroll position should keep using cursors from the
|
|
1562
|
+
* original snapshot.
|
|
1563
|
+
*
|
|
1564
|
+
* @param params.agentId - Optional. Agent to query. Omit for all active agents.
|
|
1565
|
+
* @param params.filters - Optional. Pagination + date filters.
|
|
1566
|
+
* - `limit`: max entries per page (default 10)
|
|
1567
|
+
* - `cursor`: opaque cursor returned by a previous call
|
|
1568
|
+
* - `fromDate` / `toDate`: ISO 8601 date strings
|
|
1569
|
+
* @returns {OwneyAgentHistory} `data` (up to `limit` entries), `hasMore`, `nextCursor`.
|
|
1486
1570
|
*/
|
|
1487
1571
|
async getHistory(params) {
|
|
1488
1572
|
const state = this.requireState();
|
|
@@ -1491,21 +1575,40 @@ var OwneySDK = class {
|
|
|
1491
1575
|
if (agentId) {
|
|
1492
1576
|
return this.getAgent(agentId).getHistory(state, chainId, filters);
|
|
1493
1577
|
}
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
)
|
|
1578
|
+
const activeAgents = [...this.getActiveAgents().values()];
|
|
1579
|
+
const cursorMap = filters?.cursor ? decodeMultiAgentCursor(filters.cursor) : {};
|
|
1580
|
+
const perAgent = await Promise.all(
|
|
1581
|
+
activeAgents.map(async (agent) => {
|
|
1582
|
+
const agentCursor = cursorMap[agent.id];
|
|
1583
|
+
if (filters?.cursor && agentCursor === void 0) {
|
|
1584
|
+
return { agentId: agent.id, page: null };
|
|
1585
|
+
}
|
|
1586
|
+
const page = await agent.getHistory(state, chainId, {
|
|
1587
|
+
...filters,
|
|
1588
|
+
cursor: agentCursor
|
|
1589
|
+
});
|
|
1590
|
+
return { agentId: agent.id, page };
|
|
1591
|
+
})
|
|
1498
1592
|
);
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1593
|
+
const merged = [];
|
|
1594
|
+
const nextCursorMap = {};
|
|
1595
|
+
let hasMore = false;
|
|
1596
|
+
for (const { agentId: id, page } of perAgent) {
|
|
1597
|
+
if (!page)
|
|
1598
|
+
continue;
|
|
1599
|
+
merged.push(...page.data);
|
|
1600
|
+
if (page.hasMore && page.nextCursor) {
|
|
1601
|
+
nextCursorMap[id] = page.nextCursor;
|
|
1602
|
+
hasMore = true;
|
|
1603
|
+
}
|
|
1502
1604
|
}
|
|
1503
|
-
|
|
1605
|
+
merged.sort(
|
|
1504
1606
|
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
|
|
1505
1607
|
);
|
|
1506
1608
|
return {
|
|
1507
|
-
|
|
1508
|
-
|
|
1609
|
+
data: merged,
|
|
1610
|
+
hasMore,
|
|
1611
|
+
nextCursor: hasMore ? encodeMultiAgentCursor(nextCursorMap) : void 0
|
|
1509
1612
|
};
|
|
1510
1613
|
}
|
|
1511
1614
|
// --- Agent control ---
|
|
@@ -1659,6 +1762,7 @@ var OwneySDK = class {
|
|
|
1659
1762
|
export {
|
|
1660
1763
|
AgentChainIncompatibleError,
|
|
1661
1764
|
AgentNotFoundError,
|
|
1765
|
+
InvalidHistoryCursorError,
|
|
1662
1766
|
NotConnectedError,
|
|
1663
1767
|
OwneyError,
|
|
1664
1768
|
OwneySDK
|