@owney/sdk 0.2.6 → 0.2.7
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/dist/index.cjs +166 -81
- package/dist/index.d.cts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +165 -81
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(src_exports, {
|
|
|
23
23
|
AgentChainIncompatibleError: () => AgentChainIncompatibleError,
|
|
24
24
|
AgentNotFoundError: () => AgentNotFoundError,
|
|
25
25
|
NotConnectedError: () => NotConnectedError,
|
|
26
|
+
OwneyError: () => OwneyError,
|
|
26
27
|
OwneySDK: () => OwneySDK
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -55,11 +56,58 @@ var SupportedAssets = [
|
|
|
55
56
|
}
|
|
56
57
|
];
|
|
57
58
|
|
|
59
|
+
// src/errors.ts
|
|
60
|
+
var OwneyError = class extends Error {
|
|
61
|
+
code;
|
|
62
|
+
details;
|
|
63
|
+
constructor(code, message, details) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.name = "OwneyError";
|
|
66
|
+
this.code = code;
|
|
67
|
+
this.details = details;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
71
|
+
constructor(agentId, available) {
|
|
72
|
+
super(
|
|
73
|
+
"AGENT_NOT_FOUND",
|
|
74
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
75
|
+
{ agentId, available }
|
|
76
|
+
);
|
|
77
|
+
this.name = "AgentNotFoundError";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var NotConnectedError = class extends OwneyError {
|
|
81
|
+
constructor() {
|
|
82
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
83
|
+
this.name = "NotConnectedError";
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
87
|
+
incompatibleAgents;
|
|
88
|
+
connectedChainId;
|
|
89
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
90
|
+
const details = incompatibleAgents.map(
|
|
91
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
92
|
+
).join("; ");
|
|
93
|
+
super(
|
|
94
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
95
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
96
|
+
{ incompatibleAgents, connectedChainId }
|
|
97
|
+
);
|
|
98
|
+
this.name = "AgentChainIncompatibleError";
|
|
99
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
100
|
+
this.connectedChainId = connectedChainId;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
58
104
|
// src/lib/utils.ts
|
|
59
105
|
var isValidChainId = (chainId) => {
|
|
60
106
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
61
|
-
throw new
|
|
62
|
-
|
|
107
|
+
throw new OwneyError(
|
|
108
|
+
"CHAIN_UNSUPPORTED",
|
|
109
|
+
`Unsupported chain ID: ${chainId}. Supported chains: ${SUPPORTED_CHAIN_IDS.join(", ")}`,
|
|
110
|
+
{ chainId, supportedChainIds: [...SUPPORTED_CHAIN_IDS] }
|
|
63
111
|
);
|
|
64
112
|
}
|
|
65
113
|
return chainId;
|
|
@@ -74,6 +122,15 @@ function hexToDecimal(hex, decimals = 6) {
|
|
|
74
122
|
const remainder = parsed % divisor;
|
|
75
123
|
return Number(whole) + Number(remainder) / Number(divisor);
|
|
76
124
|
}
|
|
125
|
+
function normalizeDecimalPlace(value, decimals = 6) {
|
|
126
|
+
const parsed = BigInt(value);
|
|
127
|
+
if (decimals <= 0)
|
|
128
|
+
return Number(parsed);
|
|
129
|
+
const divisor = BigInt(10 ** decimals);
|
|
130
|
+
const whole = parsed / divisor;
|
|
131
|
+
const remainder = parsed % divisor;
|
|
132
|
+
return Number(whole) + Number(remainder) / Number(divisor);
|
|
133
|
+
}
|
|
77
134
|
var DayFilterMapping = {
|
|
78
135
|
"30D": 30,
|
|
79
136
|
"14D": 14,
|
|
@@ -103,7 +160,7 @@ var CHAIN_NAME_TO_ID = {
|
|
|
103
160
|
BASE: 8453,
|
|
104
161
|
ARBITRUM: 42161
|
|
105
162
|
};
|
|
106
|
-
function mapBalances(raw, chainId) {
|
|
163
|
+
function mapBalances(raw, chainId, smartWallet) {
|
|
107
164
|
const portfolio = raw.portfolio;
|
|
108
165
|
const tokenMap = /* @__PURE__ */ new Map();
|
|
109
166
|
for (const p of portfolio.positions || []) {
|
|
@@ -114,18 +171,7 @@ function mapBalances(raw, chainId) {
|
|
|
114
171
|
tokenMap.set(key, {
|
|
115
172
|
symbol,
|
|
116
173
|
chainId: positionChainId,
|
|
117
|
-
amount: (current?.amount ?? 0) +
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
for (const s of portfolio.staleBalances || []) {
|
|
121
|
-
const symbol = s.tokenSymbol || "USDC";
|
|
122
|
-
const staleChainId = s.chainId ?? chainId;
|
|
123
|
-
const key = `${symbol}:${staleChainId}`;
|
|
124
|
-
const current = tokenMap.get(key);
|
|
125
|
-
tokenMap.set(key, {
|
|
126
|
-
symbol,
|
|
127
|
-
chainId: staleChainId,
|
|
128
|
-
amount: (current?.amount ?? 0) + hexToDecimal(s.balance || "0")
|
|
174
|
+
amount: (current?.amount ?? 0) + normalizeDecimalPlace(p.underlyingAmount || "0")
|
|
129
175
|
});
|
|
130
176
|
}
|
|
131
177
|
let totalBalance = 0;
|
|
@@ -140,7 +186,7 @@ function mapBalances(raw, chainId) {
|
|
|
140
186
|
});
|
|
141
187
|
}
|
|
142
188
|
return {
|
|
143
|
-
smartWallet
|
|
189
|
+
smartWallet,
|
|
144
190
|
totalBalance: String(totalBalance),
|
|
145
191
|
tokens
|
|
146
192
|
};
|
|
@@ -292,7 +338,10 @@ var ZyfaiAgent = class {
|
|
|
292
338
|
// --- Private helpers ---
|
|
293
339
|
getAddress() {
|
|
294
340
|
if (!this.connectedAddress) {
|
|
295
|
-
throw new
|
|
341
|
+
throw new OwneyError(
|
|
342
|
+
"NOT_CONNECTED",
|
|
343
|
+
"Wallet not connected. Call sdk.connect() first."
|
|
344
|
+
);
|
|
296
345
|
}
|
|
297
346
|
return this.connectedAddress;
|
|
298
347
|
}
|
|
@@ -444,15 +493,14 @@ var ZyfaiAgent = class {
|
|
|
444
493
|
// --- IAgent: Portfolio reads ---
|
|
445
494
|
async getBalances(state, chainId) {
|
|
446
495
|
const startedAt = Date.now();
|
|
447
|
-
await this.
|
|
448
|
-
const
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
logTiming("getBalances getPositions", positionsStart, {
|
|
496
|
+
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
497
|
+
const portfolioStart = Date.now();
|
|
498
|
+
const raw = await this.sdk.getPortfolio(this.getAddress());
|
|
499
|
+
logTiming("getBalances getPortfolio", portfolioStart, {
|
|
452
500
|
chainId: validChainId
|
|
453
501
|
});
|
|
454
502
|
logTiming("getBalances success", startedAt, { chainId: validChainId });
|
|
455
|
-
return mapBalances(raw, validChainId);
|
|
503
|
+
return mapBalances(raw, validChainId, smartWallet);
|
|
456
504
|
}
|
|
457
505
|
async getEarnings(state, chainId) {
|
|
458
506
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
@@ -764,7 +812,11 @@ var SailAgent = class {
|
|
|
764
812
|
});
|
|
765
813
|
} catch (error) {
|
|
766
814
|
if (error instanceof Error && error.name === "AbortError" && timeoutMs) {
|
|
767
|
-
throw new
|
|
815
|
+
throw new OwneyError(
|
|
816
|
+
"API_SAIL_TIMEOUT",
|
|
817
|
+
`Sail API timeout ${timeoutMs}ms: ${method} ${path}`,
|
|
818
|
+
{ timeoutMs, method, path }
|
|
819
|
+
);
|
|
768
820
|
}
|
|
769
821
|
throw error;
|
|
770
822
|
} finally {
|
|
@@ -773,7 +825,11 @@ var SailAgent = class {
|
|
|
773
825
|
}
|
|
774
826
|
if (!res.ok) {
|
|
775
827
|
const text = await res.text().catch(() => "");
|
|
776
|
-
throw new
|
|
828
|
+
throw new OwneyError(
|
|
829
|
+
"API_SAIL_ERROR",
|
|
830
|
+
`Sail API error ${res.status}: ${text}`,
|
|
831
|
+
{ statusCode: res.status, method, path, responseBody: text }
|
|
832
|
+
);
|
|
777
833
|
}
|
|
778
834
|
return res.json();
|
|
779
835
|
}
|
|
@@ -814,7 +870,10 @@ var SailAgent = class {
|
|
|
814
870
|
return;
|
|
815
871
|
}
|
|
816
872
|
if (!state.walletAddress) {
|
|
817
|
-
throw new
|
|
873
|
+
throw new OwneyError(
|
|
874
|
+
"WALLET_ADDRESS_REQUIRED",
|
|
875
|
+
"Wallet address is required. Call sdk.connect(provider) first."
|
|
876
|
+
);
|
|
818
877
|
}
|
|
819
878
|
this.connectPromise = (async () => {
|
|
820
879
|
const { sessionId, signature, message } = await this.signSiwe(
|
|
@@ -850,7 +909,10 @@ var SailAgent = class {
|
|
|
850
909
|
await this.connectFull(state, chainId);
|
|
851
910
|
const validChainId = isValidChainId(chainId);
|
|
852
911
|
if (!this.smartWalletAddress) {
|
|
853
|
-
throw new
|
|
912
|
+
throw new OwneyError(
|
|
913
|
+
"NOT_CONNECTED",
|
|
914
|
+
"Wallet not connected. Call sdk.connect() first."
|
|
915
|
+
);
|
|
854
916
|
}
|
|
855
917
|
logTiming2("resolveSmartWallet ready", startedAt, { chainId: validChainId });
|
|
856
918
|
return {
|
|
@@ -877,7 +939,8 @@ var SailAgent = class {
|
|
|
877
939
|
}
|
|
878
940
|
async deposit(state, chainId, amount, depositCallback) {
|
|
879
941
|
if (!depositCallback) {
|
|
880
|
-
throw new
|
|
942
|
+
throw new OwneyError(
|
|
943
|
+
"DEPOSIT_CALLBACK_REQUIRED",
|
|
881
944
|
"depositCallback is required for Sail. Provide a callback that transfers tokens and returns the transaction hash."
|
|
882
945
|
);
|
|
883
946
|
}
|
|
@@ -886,12 +949,16 @@ var SailAgent = class {
|
|
|
886
949
|
const depositInfo = await this.getDepositInfo();
|
|
887
950
|
const resolvedTokenAddress = depositInfo.permittedTokens[0]?.address;
|
|
888
951
|
if (!resolvedTokenAddress) {
|
|
889
|
-
throw new
|
|
952
|
+
throw new OwneyError(
|
|
953
|
+
"DEPOSIT_NO_PERMITTED_TOKENS",
|
|
954
|
+
"No permitted tokens available for deposit."
|
|
955
|
+
);
|
|
890
956
|
}
|
|
891
957
|
await this.executePreHooks(resolvedTokenAddress, amount, chainId);
|
|
892
958
|
const txHash = await depositCallback(smartWallet, chainId, amount);
|
|
893
959
|
if (!txHash) {
|
|
894
|
-
throw new
|
|
960
|
+
throw new OwneyError(
|
|
961
|
+
"DEPOSIT_CALLBACK_INVALID",
|
|
895
962
|
"depositCallback must return a transaction hash (txHash) for Sail deposits."
|
|
896
963
|
);
|
|
897
964
|
}
|
|
@@ -945,7 +1012,10 @@ var SailAgent = class {
|
|
|
945
1012
|
const withdrawInfo = await this.getWithdrawInfo();
|
|
946
1013
|
const tokenAddress = withdrawInfo.permittedTokens[0]?.address;
|
|
947
1014
|
if (!tokenAddress) {
|
|
948
|
-
throw new
|
|
1015
|
+
throw new OwneyError(
|
|
1016
|
+
"WITHDRAW_NO_PERMITTED_TOKENS",
|
|
1017
|
+
"No permitted tokens available for withdrawal."
|
|
1018
|
+
);
|
|
949
1019
|
}
|
|
950
1020
|
const resolvedAmount = amount ?? withdrawInfo.currentBalance;
|
|
951
1021
|
const { signature: adminWalletSignature, message: adminWalletPayload } = await this.signSiwe(state, chainId);
|
|
@@ -978,7 +1048,7 @@ var SailAgent = class {
|
|
|
978
1048
|
logTiming2("getBalances success", startedAt, { chainId });
|
|
979
1049
|
return mapPortfolioBalances(raw, smartWallet);
|
|
980
1050
|
} catch (error) {
|
|
981
|
-
if (error instanceof
|
|
1051
|
+
if (error instanceof OwneyError && error.code === "API_SAIL_TIMEOUT") {
|
|
982
1052
|
console.warn(
|
|
983
1053
|
"Sail portfolio request timed out; using empty snapshot.",
|
|
984
1054
|
{
|
|
@@ -1062,8 +1132,10 @@ var SailAgent = class {
|
|
|
1062
1132
|
}
|
|
1063
1133
|
const dayCount = DayFilterMapping[days];
|
|
1064
1134
|
if (dayCount === void 0) {
|
|
1065
|
-
throw new
|
|
1066
|
-
|
|
1135
|
+
throw new OwneyError(
|
|
1136
|
+
"VALIDATION_INVALID_DAYS",
|
|
1137
|
+
`Invalid days value: "${days}". Expected one of: "7D", "14D", "30D".`,
|
|
1138
|
+
{ days }
|
|
1067
1139
|
);
|
|
1068
1140
|
}
|
|
1069
1141
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1140,37 +1212,6 @@ var SailAgent = class {
|
|
|
1140
1212
|
}
|
|
1141
1213
|
};
|
|
1142
1214
|
|
|
1143
|
-
// src/errors.ts
|
|
1144
|
-
var AgentNotFoundError = class extends Error {
|
|
1145
|
-
constructor(agentId, available) {
|
|
1146
|
-
super(
|
|
1147
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`
|
|
1148
|
-
);
|
|
1149
|
-
this.name = "AgentNotFoundError";
|
|
1150
|
-
}
|
|
1151
|
-
};
|
|
1152
|
-
var NotConnectedError = class extends Error {
|
|
1153
|
-
constructor() {
|
|
1154
|
-
super("Not connected. Call sdk.connect(provider) first.");
|
|
1155
|
-
this.name = "NotConnectedError";
|
|
1156
|
-
}
|
|
1157
|
-
};
|
|
1158
|
-
var AgentChainIncompatibleError = class extends Error {
|
|
1159
|
-
incompatibleAgents;
|
|
1160
|
-
connectedChainId;
|
|
1161
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
1162
|
-
const details = incompatibleAgents.map(
|
|
1163
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
1164
|
-
).join("; ");
|
|
1165
|
-
super(
|
|
1166
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`
|
|
1167
|
-
);
|
|
1168
|
-
this.name = "AgentChainIncompatibleError";
|
|
1169
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
1170
|
-
this.connectedChainId = connectedChainId;
|
|
1171
|
-
}
|
|
1172
|
-
};
|
|
1173
|
-
|
|
1174
1215
|
// src/lib/routing-api.ts
|
|
1175
1216
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1176
1217
|
async function fetchAgentKeys(apiKey) {
|
|
@@ -1184,11 +1225,19 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1184
1225
|
});
|
|
1185
1226
|
if (!res.ok) {
|
|
1186
1227
|
const text = await res.text().catch(() => "");
|
|
1187
|
-
throw new
|
|
1228
|
+
throw new OwneyError(
|
|
1229
|
+
"API_ROUTING_ERROR",
|
|
1230
|
+
`Routing API error ${res.status}: ${text}`,
|
|
1231
|
+
{ statusCode: res.status, responseBody: text }
|
|
1232
|
+
);
|
|
1188
1233
|
}
|
|
1189
1234
|
const json = await res.json();
|
|
1190
1235
|
if (!json.success) {
|
|
1191
|
-
throw new
|
|
1236
|
+
throw new OwneyError(
|
|
1237
|
+
"API_ROUTING_FAILED",
|
|
1238
|
+
`Routing API request failed: ${json.message}`,
|
|
1239
|
+
{ message: json.message }
|
|
1240
|
+
);
|
|
1192
1241
|
}
|
|
1193
1242
|
return json.data;
|
|
1194
1243
|
}
|
|
@@ -1228,7 +1277,8 @@ var OwneySDK = class {
|
|
|
1228
1277
|
});
|
|
1229
1278
|
const walletAddress = accounts[0];
|
|
1230
1279
|
if (!walletAddress) {
|
|
1231
|
-
throw new
|
|
1280
|
+
throw new OwneyError(
|
|
1281
|
+
"WALLET_NO_ACCOUNTS",
|
|
1232
1282
|
"No accounts found. Ensure the wallet is unlocked and connected."
|
|
1233
1283
|
);
|
|
1234
1284
|
}
|
|
@@ -1267,7 +1317,8 @@ var OwneySDK = class {
|
|
|
1267
1317
|
requireChainId() {
|
|
1268
1318
|
const chainId = this.state?.chainId ?? null;
|
|
1269
1319
|
if (chainId === null) {
|
|
1270
|
-
throw new
|
|
1320
|
+
throw new OwneyError(
|
|
1321
|
+
"NO_ACTIVE_CHAIN",
|
|
1271
1322
|
"No active chain. Call sdk.activateAgent(chainId) first."
|
|
1272
1323
|
);
|
|
1273
1324
|
}
|
|
@@ -1303,7 +1354,8 @@ var OwneySDK = class {
|
|
|
1303
1354
|
this.agents.set(agent_type, agent);
|
|
1304
1355
|
}
|
|
1305
1356
|
if (this.agents.size === 0) {
|
|
1306
|
-
throw new
|
|
1357
|
+
throw new OwneyError(
|
|
1358
|
+
"API_NO_AGENTS",
|
|
1307
1359
|
"No supported agents returned by the routing API. Check your API key and routing configuration."
|
|
1308
1360
|
);
|
|
1309
1361
|
}
|
|
@@ -1332,7 +1384,8 @@ var OwneySDK = class {
|
|
|
1332
1384
|
await this.ensureAgentsInitialized();
|
|
1333
1385
|
if (agentId !== void 0) {
|
|
1334
1386
|
if (agentId.length === 0) {
|
|
1335
|
-
throw new
|
|
1387
|
+
throw new OwneyError(
|
|
1388
|
+
"AGENT_EMPTY_LIST",
|
|
1336
1389
|
"agentId array must not be empty. Omit the argument to activate all compatible agents."
|
|
1337
1390
|
);
|
|
1338
1391
|
}
|
|
@@ -1374,7 +1427,11 @@ var OwneySDK = class {
|
|
|
1374
1427
|
(agent) => agent.supportedChainIds.includes(chainId)
|
|
1375
1428
|
);
|
|
1376
1429
|
if (compatible.length === 0) {
|
|
1377
|
-
throw new
|
|
1430
|
+
throw new OwneyError(
|
|
1431
|
+
"CHAIN_NO_COMPATIBLE_AGENTS",
|
|
1432
|
+
`No agents support chain ${chainId}.`,
|
|
1433
|
+
{ chainId }
|
|
1434
|
+
);
|
|
1378
1435
|
}
|
|
1379
1436
|
this.activeAgents.clear();
|
|
1380
1437
|
for (const agent of compatible) {
|
|
@@ -1422,8 +1479,10 @@ var OwneySDK = class {
|
|
|
1422
1479
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
1423
1480
|
const totalAmount = BigInt(amount);
|
|
1424
1481
|
if (totalAmount < BigInt(eligibleAgents.length)) {
|
|
1425
|
-
throw new
|
|
1426
|
-
|
|
1482
|
+
throw new OwneyError(
|
|
1483
|
+
"DEPOSIT_AMOUNT_TOO_SMALL",
|
|
1484
|
+
`Amount "${amount}" is too small to split across ${eligibleAgents.length} agents.`,
|
|
1485
|
+
{ amount, agentCount: eligibleAgents.length }
|
|
1427
1486
|
);
|
|
1428
1487
|
}
|
|
1429
1488
|
const perAgent = totalAmount / BigInt(eligibleAgents.length);
|
|
@@ -1446,8 +1505,10 @@ var OwneySDK = class {
|
|
|
1446
1505
|
(sa) => sa.chainId === chainId
|
|
1447
1506
|
);
|
|
1448
1507
|
if (!chainAssets || !chainAssets.assets.includes(asset)) {
|
|
1449
|
-
throw new
|
|
1450
|
-
|
|
1508
|
+
throw new OwneyError(
|
|
1509
|
+
"ASSET_UNSUPPORTED",
|
|
1510
|
+
`Agent "${agent.id}" does not support asset "${asset}" on chain ${chainId}.`,
|
|
1511
|
+
{ agentId: agent.id, asset, chainId }
|
|
1451
1512
|
);
|
|
1452
1513
|
}
|
|
1453
1514
|
}
|
|
@@ -1459,8 +1520,10 @@ var OwneySDK = class {
|
|
|
1459
1520
|
return chainAssets && chainAssets.assets.includes(asset);
|
|
1460
1521
|
});
|
|
1461
1522
|
if (eligible.length === 0) {
|
|
1462
|
-
throw new
|
|
1463
|
-
|
|
1523
|
+
throw new OwneyError(
|
|
1524
|
+
"ASSET_NO_COMPATIBLE_AGENTS",
|
|
1525
|
+
`No agents support asset "${asset}" on chain ${chainId}.`,
|
|
1526
|
+
{ asset, chainId }
|
|
1464
1527
|
);
|
|
1465
1528
|
}
|
|
1466
1529
|
return eligible;
|
|
@@ -1485,10 +1548,25 @@ var OwneySDK = class {
|
|
|
1485
1548
|
return agent.withdraw(state, chainId, amount);
|
|
1486
1549
|
}
|
|
1487
1550
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
1551
|
+
if (!amount) {
|
|
1552
|
+
const results2 = {};
|
|
1553
|
+
for (const agent of eligibleAgents) {
|
|
1554
|
+
results2[agent.id] = await agent.withdraw(state, chainId);
|
|
1555
|
+
}
|
|
1556
|
+
return { agentResult: results2 };
|
|
1557
|
+
}
|
|
1488
1558
|
const results = {};
|
|
1559
|
+
let lastError;
|
|
1489
1560
|
for (const agent of eligibleAgents) {
|
|
1490
|
-
|
|
1561
|
+
try {
|
|
1562
|
+
results[agent.id] = await agent.withdraw(state, chainId, amount);
|
|
1563
|
+
return { agentResult: results };
|
|
1564
|
+
} catch (err) {
|
|
1565
|
+
lastError = err;
|
|
1566
|
+
}
|
|
1491
1567
|
}
|
|
1568
|
+
if (lastError)
|
|
1569
|
+
throw lastError;
|
|
1492
1570
|
return {
|
|
1493
1571
|
agentResult: results
|
|
1494
1572
|
};
|
|
@@ -1534,7 +1612,10 @@ var OwneySDK = class {
|
|
|
1534
1612
|
console.error("getBalances agent failed:", settledResult.reason);
|
|
1535
1613
|
}
|
|
1536
1614
|
if (successCount === 0) {
|
|
1537
|
-
throw new
|
|
1615
|
+
throw new OwneyError(
|
|
1616
|
+
"BALANCE_ALL_FAILED",
|
|
1617
|
+
"Failed to fetch balances for all active agents."
|
|
1618
|
+
);
|
|
1538
1619
|
}
|
|
1539
1620
|
logTiming3("getBalances aggregate", startedAt, {
|
|
1540
1621
|
chainId,
|
|
@@ -1776,7 +1857,10 @@ var OwneySDK = class {
|
|
|
1776
1857
|
}
|
|
1777
1858
|
}
|
|
1778
1859
|
if (successCount === 0) {
|
|
1779
|
-
throw new
|
|
1860
|
+
throw new OwneyError(
|
|
1861
|
+
"ALLOCATION_ALL_FAILED",
|
|
1862
|
+
"Failed to fetch allocation: all agents failed."
|
|
1863
|
+
);
|
|
1780
1864
|
}
|
|
1781
1865
|
const allocation = {};
|
|
1782
1866
|
if (totalBalance === 0) {
|
|
@@ -1805,5 +1889,6 @@ var OwneySDK = class {
|
|
|
1805
1889
|
AgentChainIncompatibleError,
|
|
1806
1890
|
AgentNotFoundError,
|
|
1807
1891
|
NotConnectedError,
|
|
1892
|
+
OwneyError,
|
|
1808
1893
|
OwneySDK
|
|
1809
1894
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -334,13 +334,19 @@ declare class OwneySDK {
|
|
|
334
334
|
getAgentAllocation(): Promise<OwneyAgentAllocation>;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
|
|
337
|
+
type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_TOO_SMALL" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
|
|
338
|
+
declare class OwneyError extends Error {
|
|
339
|
+
readonly code: OwneyErrorCode;
|
|
340
|
+
readonly details?: Record<string, unknown>;
|
|
341
|
+
constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>);
|
|
342
|
+
}
|
|
343
|
+
declare class AgentNotFoundError extends OwneyError {
|
|
338
344
|
constructor(agentId: string, available: string[]);
|
|
339
345
|
}
|
|
340
|
-
declare class NotConnectedError extends
|
|
346
|
+
declare class NotConnectedError extends OwneyError {
|
|
341
347
|
constructor();
|
|
342
348
|
}
|
|
343
|
-
declare class AgentChainIncompatibleError extends
|
|
349
|
+
declare class AgentChainIncompatibleError extends OwneyError {
|
|
344
350
|
readonly incompatibleAgents: Array<{
|
|
345
351
|
agentId: string;
|
|
346
352
|
supportedChainIds: readonly number[];
|
|
@@ -352,4 +358,4 @@ declare class AgentChainIncompatibleError extends Error {
|
|
|
352
358
|
}>, connectedChainId: number);
|
|
353
359
|
}
|
|
354
360
|
|
|
355
|
-
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
|
361
|
+
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -334,13 +334,19 @@ declare class OwneySDK {
|
|
|
334
334
|
getAgentAllocation(): Promise<OwneyAgentAllocation>;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
|
|
337
|
+
type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_TOO_SMALL" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
|
|
338
|
+
declare class OwneyError extends Error {
|
|
339
|
+
readonly code: OwneyErrorCode;
|
|
340
|
+
readonly details?: Record<string, unknown>;
|
|
341
|
+
constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>);
|
|
342
|
+
}
|
|
343
|
+
declare class AgentNotFoundError extends OwneyError {
|
|
338
344
|
constructor(agentId: string, available: string[]);
|
|
339
345
|
}
|
|
340
|
-
declare class NotConnectedError extends
|
|
346
|
+
declare class NotConnectedError extends OwneyError {
|
|
341
347
|
constructor();
|
|
342
348
|
}
|
|
343
|
-
declare class AgentChainIncompatibleError extends
|
|
349
|
+
declare class AgentChainIncompatibleError extends OwneyError {
|
|
344
350
|
readonly incompatibleAgents: Array<{
|
|
345
351
|
agentId: string;
|
|
346
352
|
supportedChainIds: readonly number[];
|
|
@@ -352,4 +358,4 @@ declare class AgentChainIncompatibleError extends Error {
|
|
|
352
358
|
}>, connectedChainId: number);
|
|
353
359
|
}
|
|
354
360
|
|
|
355
|
-
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
|
361
|
+
export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
|
package/dist/index.js
CHANGED
|
@@ -26,11 +26,58 @@ var SupportedAssets = [
|
|
|
26
26
|
}
|
|
27
27
|
];
|
|
28
28
|
|
|
29
|
+
// src/errors.ts
|
|
30
|
+
var OwneyError = class extends Error {
|
|
31
|
+
code;
|
|
32
|
+
details;
|
|
33
|
+
constructor(code, message, details) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = "OwneyError";
|
|
36
|
+
this.code = code;
|
|
37
|
+
this.details = details;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
41
|
+
constructor(agentId, available) {
|
|
42
|
+
super(
|
|
43
|
+
"AGENT_NOT_FOUND",
|
|
44
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
45
|
+
{ agentId, available }
|
|
46
|
+
);
|
|
47
|
+
this.name = "AgentNotFoundError";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var NotConnectedError = class extends OwneyError {
|
|
51
|
+
constructor() {
|
|
52
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
53
|
+
this.name = "NotConnectedError";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
57
|
+
incompatibleAgents;
|
|
58
|
+
connectedChainId;
|
|
59
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
60
|
+
const details = incompatibleAgents.map(
|
|
61
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
62
|
+
).join("; ");
|
|
63
|
+
super(
|
|
64
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
65
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
66
|
+
{ incompatibleAgents, connectedChainId }
|
|
67
|
+
);
|
|
68
|
+
this.name = "AgentChainIncompatibleError";
|
|
69
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
70
|
+
this.connectedChainId = connectedChainId;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
29
74
|
// src/lib/utils.ts
|
|
30
75
|
var isValidChainId = (chainId) => {
|
|
31
76
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
32
|
-
throw new
|
|
33
|
-
|
|
77
|
+
throw new OwneyError(
|
|
78
|
+
"CHAIN_UNSUPPORTED",
|
|
79
|
+
`Unsupported chain ID: ${chainId}. Supported chains: ${SUPPORTED_CHAIN_IDS.join(", ")}`,
|
|
80
|
+
{ chainId, supportedChainIds: [...SUPPORTED_CHAIN_IDS] }
|
|
34
81
|
);
|
|
35
82
|
}
|
|
36
83
|
return chainId;
|
|
@@ -45,6 +92,15 @@ function hexToDecimal(hex, decimals = 6) {
|
|
|
45
92
|
const remainder = parsed % divisor;
|
|
46
93
|
return Number(whole) + Number(remainder) / Number(divisor);
|
|
47
94
|
}
|
|
95
|
+
function normalizeDecimalPlace(value, decimals = 6) {
|
|
96
|
+
const parsed = BigInt(value);
|
|
97
|
+
if (decimals <= 0)
|
|
98
|
+
return Number(parsed);
|
|
99
|
+
const divisor = BigInt(10 ** decimals);
|
|
100
|
+
const whole = parsed / divisor;
|
|
101
|
+
const remainder = parsed % divisor;
|
|
102
|
+
return Number(whole) + Number(remainder) / Number(divisor);
|
|
103
|
+
}
|
|
48
104
|
var DayFilterMapping = {
|
|
49
105
|
"30D": 30,
|
|
50
106
|
"14D": 14,
|
|
@@ -74,7 +130,7 @@ var CHAIN_NAME_TO_ID = {
|
|
|
74
130
|
BASE: 8453,
|
|
75
131
|
ARBITRUM: 42161
|
|
76
132
|
};
|
|
77
|
-
function mapBalances(raw, chainId) {
|
|
133
|
+
function mapBalances(raw, chainId, smartWallet) {
|
|
78
134
|
const portfolio = raw.portfolio;
|
|
79
135
|
const tokenMap = /* @__PURE__ */ new Map();
|
|
80
136
|
for (const p of portfolio.positions || []) {
|
|
@@ -85,18 +141,7 @@ function mapBalances(raw, chainId) {
|
|
|
85
141
|
tokenMap.set(key, {
|
|
86
142
|
symbol,
|
|
87
143
|
chainId: positionChainId,
|
|
88
|
-
amount: (current?.amount ?? 0) +
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
for (const s of portfolio.staleBalances || []) {
|
|
92
|
-
const symbol = s.tokenSymbol || "USDC";
|
|
93
|
-
const staleChainId = s.chainId ?? chainId;
|
|
94
|
-
const key = `${symbol}:${staleChainId}`;
|
|
95
|
-
const current = tokenMap.get(key);
|
|
96
|
-
tokenMap.set(key, {
|
|
97
|
-
symbol,
|
|
98
|
-
chainId: staleChainId,
|
|
99
|
-
amount: (current?.amount ?? 0) + hexToDecimal(s.balance || "0")
|
|
144
|
+
amount: (current?.amount ?? 0) + normalizeDecimalPlace(p.underlyingAmount || "0")
|
|
100
145
|
});
|
|
101
146
|
}
|
|
102
147
|
let totalBalance = 0;
|
|
@@ -111,7 +156,7 @@ function mapBalances(raw, chainId) {
|
|
|
111
156
|
});
|
|
112
157
|
}
|
|
113
158
|
return {
|
|
114
|
-
smartWallet
|
|
159
|
+
smartWallet,
|
|
115
160
|
totalBalance: String(totalBalance),
|
|
116
161
|
tokens
|
|
117
162
|
};
|
|
@@ -263,7 +308,10 @@ var ZyfaiAgent = class {
|
|
|
263
308
|
// --- Private helpers ---
|
|
264
309
|
getAddress() {
|
|
265
310
|
if (!this.connectedAddress) {
|
|
266
|
-
throw new
|
|
311
|
+
throw new OwneyError(
|
|
312
|
+
"NOT_CONNECTED",
|
|
313
|
+
"Wallet not connected. Call sdk.connect() first."
|
|
314
|
+
);
|
|
267
315
|
}
|
|
268
316
|
return this.connectedAddress;
|
|
269
317
|
}
|
|
@@ -415,15 +463,14 @@ var ZyfaiAgent = class {
|
|
|
415
463
|
// --- IAgent: Portfolio reads ---
|
|
416
464
|
async getBalances(state, chainId) {
|
|
417
465
|
const startedAt = Date.now();
|
|
418
|
-
await this.
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
logTiming("getBalances getPositions", positionsStart, {
|
|
466
|
+
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
467
|
+
const portfolioStart = Date.now();
|
|
468
|
+
const raw = await this.sdk.getPortfolio(this.getAddress());
|
|
469
|
+
logTiming("getBalances getPortfolio", portfolioStart, {
|
|
423
470
|
chainId: validChainId
|
|
424
471
|
});
|
|
425
472
|
logTiming("getBalances success", startedAt, { chainId: validChainId });
|
|
426
|
-
return mapBalances(raw, validChainId);
|
|
473
|
+
return mapBalances(raw, validChainId, smartWallet);
|
|
427
474
|
}
|
|
428
475
|
async getEarnings(state, chainId) {
|
|
429
476
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
@@ -735,7 +782,11 @@ var SailAgent = class {
|
|
|
735
782
|
});
|
|
736
783
|
} catch (error) {
|
|
737
784
|
if (error instanceof Error && error.name === "AbortError" && timeoutMs) {
|
|
738
|
-
throw new
|
|
785
|
+
throw new OwneyError(
|
|
786
|
+
"API_SAIL_TIMEOUT",
|
|
787
|
+
`Sail API timeout ${timeoutMs}ms: ${method} ${path}`,
|
|
788
|
+
{ timeoutMs, method, path }
|
|
789
|
+
);
|
|
739
790
|
}
|
|
740
791
|
throw error;
|
|
741
792
|
} finally {
|
|
@@ -744,7 +795,11 @@ var SailAgent = class {
|
|
|
744
795
|
}
|
|
745
796
|
if (!res.ok) {
|
|
746
797
|
const text = await res.text().catch(() => "");
|
|
747
|
-
throw new
|
|
798
|
+
throw new OwneyError(
|
|
799
|
+
"API_SAIL_ERROR",
|
|
800
|
+
`Sail API error ${res.status}: ${text}`,
|
|
801
|
+
{ statusCode: res.status, method, path, responseBody: text }
|
|
802
|
+
);
|
|
748
803
|
}
|
|
749
804
|
return res.json();
|
|
750
805
|
}
|
|
@@ -785,7 +840,10 @@ var SailAgent = class {
|
|
|
785
840
|
return;
|
|
786
841
|
}
|
|
787
842
|
if (!state.walletAddress) {
|
|
788
|
-
throw new
|
|
843
|
+
throw new OwneyError(
|
|
844
|
+
"WALLET_ADDRESS_REQUIRED",
|
|
845
|
+
"Wallet address is required. Call sdk.connect(provider) first."
|
|
846
|
+
);
|
|
789
847
|
}
|
|
790
848
|
this.connectPromise = (async () => {
|
|
791
849
|
const { sessionId, signature, message } = await this.signSiwe(
|
|
@@ -821,7 +879,10 @@ var SailAgent = class {
|
|
|
821
879
|
await this.connectFull(state, chainId);
|
|
822
880
|
const validChainId = isValidChainId(chainId);
|
|
823
881
|
if (!this.smartWalletAddress) {
|
|
824
|
-
throw new
|
|
882
|
+
throw new OwneyError(
|
|
883
|
+
"NOT_CONNECTED",
|
|
884
|
+
"Wallet not connected. Call sdk.connect() first."
|
|
885
|
+
);
|
|
825
886
|
}
|
|
826
887
|
logTiming2("resolveSmartWallet ready", startedAt, { chainId: validChainId });
|
|
827
888
|
return {
|
|
@@ -848,7 +909,8 @@ var SailAgent = class {
|
|
|
848
909
|
}
|
|
849
910
|
async deposit(state, chainId, amount, depositCallback) {
|
|
850
911
|
if (!depositCallback) {
|
|
851
|
-
throw new
|
|
912
|
+
throw new OwneyError(
|
|
913
|
+
"DEPOSIT_CALLBACK_REQUIRED",
|
|
852
914
|
"depositCallback is required for Sail. Provide a callback that transfers tokens and returns the transaction hash."
|
|
853
915
|
);
|
|
854
916
|
}
|
|
@@ -857,12 +919,16 @@ var SailAgent = class {
|
|
|
857
919
|
const depositInfo = await this.getDepositInfo();
|
|
858
920
|
const resolvedTokenAddress = depositInfo.permittedTokens[0]?.address;
|
|
859
921
|
if (!resolvedTokenAddress) {
|
|
860
|
-
throw new
|
|
922
|
+
throw new OwneyError(
|
|
923
|
+
"DEPOSIT_NO_PERMITTED_TOKENS",
|
|
924
|
+
"No permitted tokens available for deposit."
|
|
925
|
+
);
|
|
861
926
|
}
|
|
862
927
|
await this.executePreHooks(resolvedTokenAddress, amount, chainId);
|
|
863
928
|
const txHash = await depositCallback(smartWallet, chainId, amount);
|
|
864
929
|
if (!txHash) {
|
|
865
|
-
throw new
|
|
930
|
+
throw new OwneyError(
|
|
931
|
+
"DEPOSIT_CALLBACK_INVALID",
|
|
866
932
|
"depositCallback must return a transaction hash (txHash) for Sail deposits."
|
|
867
933
|
);
|
|
868
934
|
}
|
|
@@ -916,7 +982,10 @@ var SailAgent = class {
|
|
|
916
982
|
const withdrawInfo = await this.getWithdrawInfo();
|
|
917
983
|
const tokenAddress = withdrawInfo.permittedTokens[0]?.address;
|
|
918
984
|
if (!tokenAddress) {
|
|
919
|
-
throw new
|
|
985
|
+
throw new OwneyError(
|
|
986
|
+
"WITHDRAW_NO_PERMITTED_TOKENS",
|
|
987
|
+
"No permitted tokens available for withdrawal."
|
|
988
|
+
);
|
|
920
989
|
}
|
|
921
990
|
const resolvedAmount = amount ?? withdrawInfo.currentBalance;
|
|
922
991
|
const { signature: adminWalletSignature, message: adminWalletPayload } = await this.signSiwe(state, chainId);
|
|
@@ -949,7 +1018,7 @@ var SailAgent = class {
|
|
|
949
1018
|
logTiming2("getBalances success", startedAt, { chainId });
|
|
950
1019
|
return mapPortfolioBalances(raw, smartWallet);
|
|
951
1020
|
} catch (error) {
|
|
952
|
-
if (error instanceof
|
|
1021
|
+
if (error instanceof OwneyError && error.code === "API_SAIL_TIMEOUT") {
|
|
953
1022
|
console.warn(
|
|
954
1023
|
"Sail portfolio request timed out; using empty snapshot.",
|
|
955
1024
|
{
|
|
@@ -1033,8 +1102,10 @@ var SailAgent = class {
|
|
|
1033
1102
|
}
|
|
1034
1103
|
const dayCount = DayFilterMapping[days];
|
|
1035
1104
|
if (dayCount === void 0) {
|
|
1036
|
-
throw new
|
|
1037
|
-
|
|
1105
|
+
throw new OwneyError(
|
|
1106
|
+
"VALIDATION_INVALID_DAYS",
|
|
1107
|
+
`Invalid days value: "${days}". Expected one of: "7D", "14D", "30D".`,
|
|
1108
|
+
{ days }
|
|
1038
1109
|
);
|
|
1039
1110
|
}
|
|
1040
1111
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1111,37 +1182,6 @@ var SailAgent = class {
|
|
|
1111
1182
|
}
|
|
1112
1183
|
};
|
|
1113
1184
|
|
|
1114
|
-
// src/errors.ts
|
|
1115
|
-
var AgentNotFoundError = class extends Error {
|
|
1116
|
-
constructor(agentId, available) {
|
|
1117
|
-
super(
|
|
1118
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`
|
|
1119
|
-
);
|
|
1120
|
-
this.name = "AgentNotFoundError";
|
|
1121
|
-
}
|
|
1122
|
-
};
|
|
1123
|
-
var NotConnectedError = class extends Error {
|
|
1124
|
-
constructor() {
|
|
1125
|
-
super("Not connected. Call sdk.connect(provider) first.");
|
|
1126
|
-
this.name = "NotConnectedError";
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1129
|
-
var AgentChainIncompatibleError = class extends Error {
|
|
1130
|
-
incompatibleAgents;
|
|
1131
|
-
connectedChainId;
|
|
1132
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
1133
|
-
const details = incompatibleAgents.map(
|
|
1134
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
1135
|
-
).join("; ");
|
|
1136
|
-
super(
|
|
1137
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`
|
|
1138
|
-
);
|
|
1139
|
-
this.name = "AgentChainIncompatibleError";
|
|
1140
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
1141
|
-
this.connectedChainId = connectedChainId;
|
|
1142
|
-
}
|
|
1143
|
-
};
|
|
1144
|
-
|
|
1145
1185
|
// src/lib/routing-api.ts
|
|
1146
1186
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1147
1187
|
async function fetchAgentKeys(apiKey) {
|
|
@@ -1155,11 +1195,19 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1155
1195
|
});
|
|
1156
1196
|
if (!res.ok) {
|
|
1157
1197
|
const text = await res.text().catch(() => "");
|
|
1158
|
-
throw new
|
|
1198
|
+
throw new OwneyError(
|
|
1199
|
+
"API_ROUTING_ERROR",
|
|
1200
|
+
`Routing API error ${res.status}: ${text}`,
|
|
1201
|
+
{ statusCode: res.status, responseBody: text }
|
|
1202
|
+
);
|
|
1159
1203
|
}
|
|
1160
1204
|
const json = await res.json();
|
|
1161
1205
|
if (!json.success) {
|
|
1162
|
-
throw new
|
|
1206
|
+
throw new OwneyError(
|
|
1207
|
+
"API_ROUTING_FAILED",
|
|
1208
|
+
`Routing API request failed: ${json.message}`,
|
|
1209
|
+
{ message: json.message }
|
|
1210
|
+
);
|
|
1163
1211
|
}
|
|
1164
1212
|
return json.data;
|
|
1165
1213
|
}
|
|
@@ -1199,7 +1247,8 @@ var OwneySDK = class {
|
|
|
1199
1247
|
});
|
|
1200
1248
|
const walletAddress = accounts[0];
|
|
1201
1249
|
if (!walletAddress) {
|
|
1202
|
-
throw new
|
|
1250
|
+
throw new OwneyError(
|
|
1251
|
+
"WALLET_NO_ACCOUNTS",
|
|
1203
1252
|
"No accounts found. Ensure the wallet is unlocked and connected."
|
|
1204
1253
|
);
|
|
1205
1254
|
}
|
|
@@ -1238,7 +1287,8 @@ var OwneySDK = class {
|
|
|
1238
1287
|
requireChainId() {
|
|
1239
1288
|
const chainId = this.state?.chainId ?? null;
|
|
1240
1289
|
if (chainId === null) {
|
|
1241
|
-
throw new
|
|
1290
|
+
throw new OwneyError(
|
|
1291
|
+
"NO_ACTIVE_CHAIN",
|
|
1242
1292
|
"No active chain. Call sdk.activateAgent(chainId) first."
|
|
1243
1293
|
);
|
|
1244
1294
|
}
|
|
@@ -1274,7 +1324,8 @@ var OwneySDK = class {
|
|
|
1274
1324
|
this.agents.set(agent_type, agent);
|
|
1275
1325
|
}
|
|
1276
1326
|
if (this.agents.size === 0) {
|
|
1277
|
-
throw new
|
|
1327
|
+
throw new OwneyError(
|
|
1328
|
+
"API_NO_AGENTS",
|
|
1278
1329
|
"No supported agents returned by the routing API. Check your API key and routing configuration."
|
|
1279
1330
|
);
|
|
1280
1331
|
}
|
|
@@ -1303,7 +1354,8 @@ var OwneySDK = class {
|
|
|
1303
1354
|
await this.ensureAgentsInitialized();
|
|
1304
1355
|
if (agentId !== void 0) {
|
|
1305
1356
|
if (agentId.length === 0) {
|
|
1306
|
-
throw new
|
|
1357
|
+
throw new OwneyError(
|
|
1358
|
+
"AGENT_EMPTY_LIST",
|
|
1307
1359
|
"agentId array must not be empty. Omit the argument to activate all compatible agents."
|
|
1308
1360
|
);
|
|
1309
1361
|
}
|
|
@@ -1345,7 +1397,11 @@ var OwneySDK = class {
|
|
|
1345
1397
|
(agent) => agent.supportedChainIds.includes(chainId)
|
|
1346
1398
|
);
|
|
1347
1399
|
if (compatible.length === 0) {
|
|
1348
|
-
throw new
|
|
1400
|
+
throw new OwneyError(
|
|
1401
|
+
"CHAIN_NO_COMPATIBLE_AGENTS",
|
|
1402
|
+
`No agents support chain ${chainId}.`,
|
|
1403
|
+
{ chainId }
|
|
1404
|
+
);
|
|
1349
1405
|
}
|
|
1350
1406
|
this.activeAgents.clear();
|
|
1351
1407
|
for (const agent of compatible) {
|
|
@@ -1393,8 +1449,10 @@ var OwneySDK = class {
|
|
|
1393
1449
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
1394
1450
|
const totalAmount = BigInt(amount);
|
|
1395
1451
|
if (totalAmount < BigInt(eligibleAgents.length)) {
|
|
1396
|
-
throw new
|
|
1397
|
-
|
|
1452
|
+
throw new OwneyError(
|
|
1453
|
+
"DEPOSIT_AMOUNT_TOO_SMALL",
|
|
1454
|
+
`Amount "${amount}" is too small to split across ${eligibleAgents.length} agents.`,
|
|
1455
|
+
{ amount, agentCount: eligibleAgents.length }
|
|
1398
1456
|
);
|
|
1399
1457
|
}
|
|
1400
1458
|
const perAgent = totalAmount / BigInt(eligibleAgents.length);
|
|
@@ -1417,8 +1475,10 @@ var OwneySDK = class {
|
|
|
1417
1475
|
(sa) => sa.chainId === chainId
|
|
1418
1476
|
);
|
|
1419
1477
|
if (!chainAssets || !chainAssets.assets.includes(asset)) {
|
|
1420
|
-
throw new
|
|
1421
|
-
|
|
1478
|
+
throw new OwneyError(
|
|
1479
|
+
"ASSET_UNSUPPORTED",
|
|
1480
|
+
`Agent "${agent.id}" does not support asset "${asset}" on chain ${chainId}.`,
|
|
1481
|
+
{ agentId: agent.id, asset, chainId }
|
|
1422
1482
|
);
|
|
1423
1483
|
}
|
|
1424
1484
|
}
|
|
@@ -1430,8 +1490,10 @@ var OwneySDK = class {
|
|
|
1430
1490
|
return chainAssets && chainAssets.assets.includes(asset);
|
|
1431
1491
|
});
|
|
1432
1492
|
if (eligible.length === 0) {
|
|
1433
|
-
throw new
|
|
1434
|
-
|
|
1493
|
+
throw new OwneyError(
|
|
1494
|
+
"ASSET_NO_COMPATIBLE_AGENTS",
|
|
1495
|
+
`No agents support asset "${asset}" on chain ${chainId}.`,
|
|
1496
|
+
{ asset, chainId }
|
|
1435
1497
|
);
|
|
1436
1498
|
}
|
|
1437
1499
|
return eligible;
|
|
@@ -1456,10 +1518,25 @@ var OwneySDK = class {
|
|
|
1456
1518
|
return agent.withdraw(state, chainId, amount);
|
|
1457
1519
|
}
|
|
1458
1520
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
1521
|
+
if (!amount) {
|
|
1522
|
+
const results2 = {};
|
|
1523
|
+
for (const agent of eligibleAgents) {
|
|
1524
|
+
results2[agent.id] = await agent.withdraw(state, chainId);
|
|
1525
|
+
}
|
|
1526
|
+
return { agentResult: results2 };
|
|
1527
|
+
}
|
|
1459
1528
|
const results = {};
|
|
1529
|
+
let lastError;
|
|
1460
1530
|
for (const agent of eligibleAgents) {
|
|
1461
|
-
|
|
1531
|
+
try {
|
|
1532
|
+
results[agent.id] = await agent.withdraw(state, chainId, amount);
|
|
1533
|
+
return { agentResult: results };
|
|
1534
|
+
} catch (err) {
|
|
1535
|
+
lastError = err;
|
|
1536
|
+
}
|
|
1462
1537
|
}
|
|
1538
|
+
if (lastError)
|
|
1539
|
+
throw lastError;
|
|
1463
1540
|
return {
|
|
1464
1541
|
agentResult: results
|
|
1465
1542
|
};
|
|
@@ -1505,7 +1582,10 @@ var OwneySDK = class {
|
|
|
1505
1582
|
console.error("getBalances agent failed:", settledResult.reason);
|
|
1506
1583
|
}
|
|
1507
1584
|
if (successCount === 0) {
|
|
1508
|
-
throw new
|
|
1585
|
+
throw new OwneyError(
|
|
1586
|
+
"BALANCE_ALL_FAILED",
|
|
1587
|
+
"Failed to fetch balances for all active agents."
|
|
1588
|
+
);
|
|
1509
1589
|
}
|
|
1510
1590
|
logTiming3("getBalances aggregate", startedAt, {
|
|
1511
1591
|
chainId,
|
|
@@ -1747,7 +1827,10 @@ var OwneySDK = class {
|
|
|
1747
1827
|
}
|
|
1748
1828
|
}
|
|
1749
1829
|
if (successCount === 0) {
|
|
1750
|
-
throw new
|
|
1830
|
+
throw new OwneyError(
|
|
1831
|
+
"ALLOCATION_ALL_FAILED",
|
|
1832
|
+
"Failed to fetch allocation: all agents failed."
|
|
1833
|
+
);
|
|
1751
1834
|
}
|
|
1752
1835
|
const allocation = {};
|
|
1753
1836
|
if (totalBalance === 0) {
|
|
@@ -1775,5 +1858,6 @@ export {
|
|
|
1775
1858
|
AgentChainIncompatibleError,
|
|
1776
1859
|
AgentNotFoundError,
|
|
1777
1860
|
NotConnectedError,
|
|
1861
|
+
OwneyError,
|
|
1778
1862
|
OwneySDK
|
|
1779
1863
|
};
|