@owney/sdk 0.6.9-beta.0 → 0.6.9-beta.2
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 +300 -608
- package/dist/index.d.cts +74 -20
- package/dist/index.d.ts +74 -20
- package/dist/index.js +283 -102
- package/package.json +1 -3
- package/dist/chunk-GMNQBWUB.js +0 -55
- package/dist/surfliquid.agent-OMOYXWLP.js +0 -385
package/dist/index.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AgentChainIncompatibleError,
|
|
3
|
-
AgentNotFoundError,
|
|
4
|
-
NotConnectedError,
|
|
5
|
-
OwneyError
|
|
6
|
-
} from "./chunk-GMNQBWUB.js";
|
|
7
|
-
|
|
8
1
|
// src/agents/zyfai/zyfai.agent.ts
|
|
9
2
|
import { ZyfaiSDK } from "@zyfai/sdk";
|
|
10
3
|
import { createPublicClient, http } from "viem";
|
|
@@ -63,6 +56,55 @@ var SupportedAssets = [
|
|
|
63
56
|
}
|
|
64
57
|
];
|
|
65
58
|
|
|
59
|
+
// src/errors.ts
|
|
60
|
+
var OwneyError = class extends Error {
|
|
61
|
+
code;
|
|
62
|
+
details;
|
|
63
|
+
agentId;
|
|
64
|
+
constructor(code, message, details, agentId) {
|
|
65
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
66
|
+
super(`${prefix} ${message}`);
|
|
67
|
+
this.name = "OwneyError";
|
|
68
|
+
this.code = code;
|
|
69
|
+
this.details = details;
|
|
70
|
+
this.agentId = agentId;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
74
|
+
constructor(agentId, available) {
|
|
75
|
+
super(
|
|
76
|
+
"AGENT_NOT_FOUND",
|
|
77
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
78
|
+
{ agentId, available },
|
|
79
|
+
agentId
|
|
80
|
+
);
|
|
81
|
+
this.name = "AgentNotFoundError";
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var NotConnectedError = class extends OwneyError {
|
|
85
|
+
constructor() {
|
|
86
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
87
|
+
this.name = "NotConnectedError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
91
|
+
incompatibleAgents;
|
|
92
|
+
connectedChainId;
|
|
93
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
94
|
+
const details = incompatibleAgents.map(
|
|
95
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
96
|
+
).join("; ");
|
|
97
|
+
super(
|
|
98
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
99
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
100
|
+
{ incompatibleAgents, connectedChainId }
|
|
101
|
+
);
|
|
102
|
+
this.name = "AgentChainIncompatibleError";
|
|
103
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
104
|
+
this.connectedChainId = connectedChainId;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
66
108
|
// src/lib/utils.ts
|
|
67
109
|
var isValidChainId = (chainId) => {
|
|
68
110
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
@@ -137,46 +179,46 @@ function resolveChainId(chain) {
|
|
|
137
179
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
138
180
|
const portfolio = raw.portfolio;
|
|
139
181
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
140
|
-
const rawPositions = portfolio.positions ?? [];
|
|
141
|
-
const detailByKey = /* @__PURE__ */ new Map();
|
|
142
|
-
for (const p of rawPositions) {
|
|
143
|
-
const cid = resolveChainId(p.chain ?? "");
|
|
144
|
-
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
145
|
-
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
146
|
-
}
|
|
147
182
|
let totalBalance = 0;
|
|
148
183
|
const tokens = [];
|
|
149
|
-
const positions = [];
|
|
150
184
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
151
185
|
const positionChainId = Number(chainIdKey);
|
|
152
|
-
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
153
186
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
154
187
|
tokensBySymbol ?? {}
|
|
155
188
|
)) {
|
|
156
|
-
const amount = hexToDecimal(balance || "0",
|
|
189
|
+
const amount = hexToDecimal(balance || "0", decimals);
|
|
157
190
|
totalBalance += amount;
|
|
158
191
|
tokens.push({
|
|
159
|
-
chain:
|
|
192
|
+
chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
|
|
160
193
|
chainId: positionChainId,
|
|
161
194
|
asset: symbol,
|
|
162
195
|
amount: String(amount)
|
|
163
196
|
});
|
|
164
|
-
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
165
|
-
positions.push({
|
|
166
|
-
chain: chainName,
|
|
167
|
-
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
168
|
-
protocolId: detail?.protocol_id,
|
|
169
|
-
pool: detail?.pool,
|
|
170
|
-
asset: symbol,
|
|
171
|
-
amount: String(amount),
|
|
172
|
-
apy: detail?.pool_apy,
|
|
173
|
-
tvl: detail?.pool_tvl,
|
|
174
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
175
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
176
|
-
liquidity: detail?.liquidity
|
|
177
|
-
});
|
|
178
197
|
}
|
|
179
198
|
}
|
|
199
|
+
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
200
|
+
chain: p.chain ?? "",
|
|
201
|
+
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
202
|
+
protocolId: p.protocol_id,
|
|
203
|
+
pool: p.pool,
|
|
204
|
+
asset: p.token_symbol ?? "",
|
|
205
|
+
// Position amount is hex-encoded base units (like the token balances
|
|
206
|
+
// above). `PositionSlot` doesn't type a `decimals` field, but runtime
|
|
207
|
+
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
208
|
+
// when present, otherwise fall back to the per-symbol lookup so
|
|
209
|
+
// non-6-decimal assets like WETH don't render 1e12 too large.
|
|
210
|
+
amount: String(
|
|
211
|
+
hexToDecimal(
|
|
212
|
+
p.amount || "0",
|
|
213
|
+
tokenDecimals(p.token_symbol, p.decimals)
|
|
214
|
+
)
|
|
215
|
+
),
|
|
216
|
+
apy: p.pool_apy,
|
|
217
|
+
tvl: p.pool_tvl,
|
|
218
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
219
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
220
|
+
liquidity: p.liquidity
|
|
221
|
+
}));
|
|
180
222
|
return {
|
|
181
223
|
smartWallet,
|
|
182
224
|
totalBalance: String(totalBalance),
|
|
@@ -586,6 +628,56 @@ function buildProtocolMergeUpdate(available, current, asset) {
|
|
|
586
628
|
};
|
|
587
629
|
}
|
|
588
630
|
|
|
631
|
+
// src/agents/zyfai/splitting.ts
|
|
632
|
+
var MAX_MIN_SPLITS = 4;
|
|
633
|
+
var MIN_FORCE_SPLITS = 2;
|
|
634
|
+
var AUTOMATIC_MIN_SPLITS = 1;
|
|
635
|
+
function toZyfaiSplitting(policy) {
|
|
636
|
+
switch (policy.splittingMode) {
|
|
637
|
+
case "none":
|
|
638
|
+
return { splitting: false };
|
|
639
|
+
case "automatic":
|
|
640
|
+
return { splitting: true, minSplits: AUTOMATIC_MIN_SPLITS };
|
|
641
|
+
case "force":
|
|
642
|
+
return {
|
|
643
|
+
splitting: true,
|
|
644
|
+
minSplits: clampForceSplits(policy.minSplits)
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function clampForceSplits(minSplits) {
|
|
649
|
+
if (typeof minSplits !== "number" || !Number.isFinite(minSplits)) {
|
|
650
|
+
return MIN_FORCE_SPLITS;
|
|
651
|
+
}
|
|
652
|
+
const rounded = Math.round(minSplits);
|
|
653
|
+
if (rounded < MIN_FORCE_SPLITS) return MIN_FORCE_SPLITS;
|
|
654
|
+
if (rounded > MAX_MIN_SPLITS) return MAX_MIN_SPLITS;
|
|
655
|
+
return rounded;
|
|
656
|
+
}
|
|
657
|
+
function splittingNeedsUpdate(current, desired) {
|
|
658
|
+
if (!current) return true;
|
|
659
|
+
if (current.splitting !== desired.splitting) return true;
|
|
660
|
+
if (desired.minSplits === void 0) return false;
|
|
661
|
+
return current.minSplits !== desired.minSplits;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// src/lib/debug.ts
|
|
665
|
+
var configuredDebug = false;
|
|
666
|
+
function setOwneyDebug(enabled) {
|
|
667
|
+
configuredDebug = enabled;
|
|
668
|
+
}
|
|
669
|
+
function isOwneyDebug() {
|
|
670
|
+
return globalThis.__OWNEY_DEBUG__ === true || configuredDebug;
|
|
671
|
+
}
|
|
672
|
+
function debugLog(scope, message, data) {
|
|
673
|
+
if (!isOwneyDebug()) return;
|
|
674
|
+
if (data === void 0) {
|
|
675
|
+
console.log(`[${scope}] ${message}`);
|
|
676
|
+
} else {
|
|
677
|
+
console.log(`[${scope}] ${message}`, data);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
589
681
|
// src/agents/zyfai/zyfai.agent.ts
|
|
590
682
|
var DEFAULT_ZYFAI_RPC_URLS = {
|
|
591
683
|
8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
@@ -598,6 +690,7 @@ var WETH_ADDRESS_BY_CHAIN = {
|
|
|
598
690
|
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
599
691
|
};
|
|
600
692
|
var VIEM_CHAIN = { 8453: base, 42161: arbitrum, 1: mainnet };
|
|
693
|
+
var SPLITTING_ASSETS = ["USDC", "WETH"];
|
|
601
694
|
function isAlreadyActiveSessionKeyError(error) {
|
|
602
695
|
const message = error instanceof Error ? error.message : String(error);
|
|
603
696
|
return /already has an active session key/i.test(message);
|
|
@@ -962,6 +1055,62 @@ var ZyfaiAgent = class {
|
|
|
962
1055
|
throw error;
|
|
963
1056
|
}
|
|
964
1057
|
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Apply the org's capital splitting policy to this user's Zyfai profile.
|
|
1060
|
+
*
|
|
1061
|
+
* Per ASSET, not per chain: Zyfai stores splitting under
|
|
1062
|
+
* `assetTypeSettings[asset]`, so one call would only configure USDC and leave a
|
|
1063
|
+
* WETH holder's real setting untouched.
|
|
1064
|
+
*
|
|
1065
|
+
* Non-fatal throughout. This is a side effect of connecting, so a Zyfai hiccup
|
|
1066
|
+
* must leave the user connected with their profile unchanged, never fail
|
|
1067
|
+
* activation.
|
|
1068
|
+
*/
|
|
1069
|
+
async applyOrgPolicy(_state, _chainId, policy) {
|
|
1070
|
+
debugLog("zyfai:splitting", "applying org policy", {
|
|
1071
|
+
policy,
|
|
1072
|
+
// Per asset because Zyfai stores splitting under assetTypeSettings[asset].
|
|
1073
|
+
assets: SPLITTING_ASSETS
|
|
1074
|
+
});
|
|
1075
|
+
await Promise.all(
|
|
1076
|
+
SPLITTING_ASSETS.map((asset) => this.applySplitting(asset, policy))
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
async applySplitting(asset, policy) {
|
|
1080
|
+
try {
|
|
1081
|
+
const desired = toZyfaiSplitting(policy);
|
|
1082
|
+
const current = await this.sdk.getUserDetails(asset);
|
|
1083
|
+
const currentSplitting = {
|
|
1084
|
+
splitting: current?.splitting,
|
|
1085
|
+
minSplits: current?.minSplits
|
|
1086
|
+
};
|
|
1087
|
+
const needsUpdate = splittingNeedsUpdate(current, desired);
|
|
1088
|
+
debugLog("zyfai:splitting", `${asset}: comparing`, {
|
|
1089
|
+
mode: policy.splittingMode,
|
|
1090
|
+
current: currentSplitting,
|
|
1091
|
+
desired,
|
|
1092
|
+
// Spelled out because the "why" is the non-obvious part: minSplits is
|
|
1093
|
+
// what separates automatic (1) from force (2-4), not `splitting`.
|
|
1094
|
+
decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
|
|
1095
|
+
});
|
|
1096
|
+
if (!needsUpdate) return;
|
|
1097
|
+
const result = await this.sdk.updateUserProfile({ asset, ...desired });
|
|
1098
|
+
debugLog("zyfai:splitting", `${asset}: wrote updateUserProfile`, {
|
|
1099
|
+
sent: { asset, ...desired },
|
|
1100
|
+
// updateUserProfile re-reads the profile after PATCHing, so this is
|
|
1101
|
+
// Zyfai's own view of the result rather than an echo of what we sent.
|
|
1102
|
+
zyfaiNowReports: {
|
|
1103
|
+
splitting: result?.splitting,
|
|
1104
|
+
minSplits: result?.minSplits
|
|
1105
|
+
}
|
|
1106
|
+
});
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
console.warn(
|
|
1109
|
+
`[zyfai] applyOrgPolicy(${asset}) failed (non-fatal):`,
|
|
1110
|
+
error instanceof Error ? error.message : String(error)
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
965
1114
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
|
966
1115
|
try {
|
|
967
1116
|
await this.connectFull(state, chainId);
|
|
@@ -1115,6 +1264,40 @@ var ZyfaiAgent = class {
|
|
|
1115
1264
|
|
|
1116
1265
|
// src/lib/routing-api.ts
|
|
1117
1266
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1267
|
+
async function fetchOrgAgentConfig(apiKey) {
|
|
1268
|
+
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
|
|
1269
|
+
try {
|
|
1270
|
+
const res = await fetch(url, {
|
|
1271
|
+
method: "GET",
|
|
1272
|
+
headers: {
|
|
1273
|
+
"Content-Type": "application/json",
|
|
1274
|
+
"x-owney-api-key": `${apiKey}`
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
if (!res.ok) {
|
|
1278
|
+
if (res.status !== 404) {
|
|
1279
|
+
console.warn(
|
|
1280
|
+
`[owney-sdk] Could not read org agent config (${res.status}); leaving user profiles unchanged.`
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
return null;
|
|
1284
|
+
}
|
|
1285
|
+
const json = await res.json();
|
|
1286
|
+
const policy = json.success ? json.data ?? null : null;
|
|
1287
|
+
debugLog(
|
|
1288
|
+
"owney-sdk",
|
|
1289
|
+
policy ? "org agent config: loaded" : "org agent config: none set by this partner \u2014 user profiles will be left as they are",
|
|
1290
|
+
policy ?? void 0
|
|
1291
|
+
);
|
|
1292
|
+
return policy;
|
|
1293
|
+
} catch (error) {
|
|
1294
|
+
console.warn(
|
|
1295
|
+
"[owney-sdk] Could not read org agent config (non-fatal):",
|
|
1296
|
+
error instanceof Error ? error.message : String(error)
|
|
1297
|
+
);
|
|
1298
|
+
return null;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1118
1301
|
async function fetchAgentKeys(apiKey) {
|
|
1119
1302
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
1120
1303
|
const res = await fetch(url, {
|
|
@@ -1713,7 +1896,6 @@ var VIEM_CHAIN2 = {
|
|
|
1713
1896
|
42161: arbitrum2,
|
|
1714
1897
|
1: mainnet2
|
|
1715
1898
|
};
|
|
1716
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
1717
1899
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
1718
1900
|
8453: "0x4200000000000000000000000000000000000006",
|
|
1719
1901
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -1733,6 +1915,12 @@ var OwneySDK = class {
|
|
|
1733
1915
|
disabledAgents = /* @__PURE__ */ new Set();
|
|
1734
1916
|
state = null;
|
|
1735
1917
|
apiKey;
|
|
1918
|
+
// The org's agent policy, fetched once per client. Applied to each agent on
|
|
1919
|
+
// activation (ROUT-229). `undefined` means "not fetched yet", `null` means
|
|
1920
|
+
// "fetched, and the partner has no policy" — which is a real answer meaning
|
|
1921
|
+
// leave every user's agent profile alone.
|
|
1922
|
+
orgAgentConfig;
|
|
1923
|
+
orgAgentConfigPromise = null;
|
|
1736
1924
|
zyfaiRpcUrls;
|
|
1737
1925
|
routingApiBaseUrl;
|
|
1738
1926
|
referralSource;
|
|
@@ -1741,6 +1929,7 @@ var OwneySDK = class {
|
|
|
1741
1929
|
initializingAgentsPromise = null;
|
|
1742
1930
|
constructor(config) {
|
|
1743
1931
|
this.apiKey = config.apiKey;
|
|
1932
|
+
if (config.debug) setOwneyDebug(true);
|
|
1744
1933
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
1745
1934
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
1746
1935
|
this.referralSource = config.referralSource;
|
|
@@ -1902,14 +2091,57 @@ var OwneySDK = class {
|
|
|
1902
2091
|
}
|
|
1903
2092
|
return active;
|
|
1904
2093
|
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
|
|
2096
|
+
* throws — it degrades to null — so this cannot break activation.
|
|
2097
|
+
*/
|
|
2098
|
+
async getOrgAgentConfig() {
|
|
2099
|
+
if (this.orgAgentConfig !== void 0) return this.orgAgentConfig;
|
|
2100
|
+
if (!this.orgAgentConfigPromise) {
|
|
2101
|
+
this.orgAgentConfigPromise = fetchOrgAgentConfig(this.apiKey).then(
|
|
2102
|
+
(config) => {
|
|
2103
|
+
this.orgAgentConfig = config;
|
|
2104
|
+
return config;
|
|
2105
|
+
}
|
|
2106
|
+
);
|
|
2107
|
+
}
|
|
2108
|
+
return this.orgAgentConfigPromise;
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Apply the org policy to one agent, after it has activated.
|
|
2112
|
+
*
|
|
2113
|
+
* Sequenced after activation rather than alongside it because applying the
|
|
2114
|
+
* policy needs the authenticated session activation establishes. Every failure
|
|
2115
|
+
* mode is swallowed: a partner's splitting preference is not worth failing a
|
|
2116
|
+
* user's connect over.
|
|
2117
|
+
*/
|
|
2118
|
+
async applyOrgPolicyTo(agent, state, chainId) {
|
|
2119
|
+
if (!agent.applyOrgPolicy) {
|
|
2120
|
+
debugLog(
|
|
2121
|
+
"owney-sdk",
|
|
2122
|
+
`${agent.id}: no applyOrgPolicy \u2014 agent has no org-level knobs, skipping`
|
|
2123
|
+
);
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
2126
|
+
try {
|
|
2127
|
+
const policy = await this.getOrgAgentConfig();
|
|
2128
|
+
if (!policy) return;
|
|
2129
|
+
await agent.applyOrgPolicy(state, chainId, policy);
|
|
2130
|
+
} catch (error) {
|
|
2131
|
+
console.warn(
|
|
2132
|
+
`[owney-sdk] applyOrgPolicy(${agent.id}) failed (non-fatal):`,
|
|
2133
|
+
error instanceof Error ? error.message : String(error)
|
|
2134
|
+
);
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
1905
2137
|
async ensureAgentsInitialized() {
|
|
1906
2138
|
if (this.agents.size > 0) return;
|
|
1907
2139
|
if (!this.initializingAgentsPromise) {
|
|
1908
2140
|
this.initializingAgentsPromise = (async () => {
|
|
1909
2141
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
1910
2142
|
this.disabledAgents.clear();
|
|
1911
|
-
for (const { key, agent_type,
|
|
1912
|
-
const agent =
|
|
2143
|
+
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
2144
|
+
const agent = this.createAgent(agent_type, key);
|
|
1913
2145
|
if (!agent) continue;
|
|
1914
2146
|
this.agents.set(agent_type, agent);
|
|
1915
2147
|
if (is_enabled === false) {
|
|
@@ -1930,15 +2162,10 @@ var OwneySDK = class {
|
|
|
1930
2162
|
this.initializingAgentsPromise = null;
|
|
1931
2163
|
}
|
|
1932
2164
|
}
|
|
1933
|
-
|
|
2165
|
+
createAgent(agentId, key) {
|
|
1934
2166
|
if (agentId === "zyfai") {
|
|
1935
2167
|
return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
|
|
1936
2168
|
}
|
|
1937
|
-
if (agentId === "surfliquid") {
|
|
1938
|
-
if (!projectName) return null;
|
|
1939
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-OMOYXWLP.js");
|
|
1940
|
-
return new SurfLiquidAgent({ projectName, appId: key });
|
|
1941
|
-
}
|
|
1942
2169
|
return null;
|
|
1943
2170
|
}
|
|
1944
2171
|
// --- Account lifecycle ---
|
|
@@ -1991,6 +2218,7 @@ var OwneySDK = class {
|
|
|
1991
2218
|
Promise.all(
|
|
1992
2219
|
agents.map(async (agent) => {
|
|
1993
2220
|
await agent.activateAgent(state, chainId);
|
|
2221
|
+
await this.applyOrgPolicyTo(agent, state, chainId);
|
|
1994
2222
|
})
|
|
1995
2223
|
).catch((error) => {
|
|
1996
2224
|
console.error("activateAgent background init failed:", error);
|
|
@@ -2018,6 +2246,7 @@ var OwneySDK = class {
|
|
|
2018
2246
|
Promise.all(
|
|
2019
2247
|
enabledCompatible.map(async (agent) => {
|
|
2020
2248
|
await agent.activateAgent(state, chainId);
|
|
2249
|
+
await this.applyOrgPolicyTo(agent, state, chainId);
|
|
2021
2250
|
})
|
|
2022
2251
|
).catch((error) => {
|
|
2023
2252
|
console.error("activateAgent background init failed:", error);
|
|
@@ -2091,30 +2320,18 @@ var OwneySDK = class {
|
|
|
2091
2320
|
);
|
|
2092
2321
|
}
|
|
2093
2322
|
const agentResults = {};
|
|
2094
|
-
const agentErrors = {};
|
|
2095
2323
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
depositCallback
|
|
2105
|
-
);
|
|
2106
|
-
} catch (error) {
|
|
2107
|
-
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
2108
|
-
}
|
|
2109
|
-
}
|
|
2110
|
-
if (Object.keys(agentResults).length === 0) {
|
|
2111
|
-
throw new OwneyError(
|
|
2112
|
-
"DEPOSIT_ALL_FAILED",
|
|
2113
|
-
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
2114
|
-
{ agentErrors }
|
|
2324
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2325
|
+
agent,
|
|
2326
|
+
state,
|
|
2327
|
+
chainId,
|
|
2328
|
+
agentAmount,
|
|
2329
|
+
asset,
|
|
2330
|
+
effectiveCallback,
|
|
2331
|
+
depositCallback
|
|
2115
2332
|
);
|
|
2116
2333
|
}
|
|
2117
|
-
return
|
|
2334
|
+
return { agentResults };
|
|
2118
2335
|
}
|
|
2119
2336
|
/**
|
|
2120
2337
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2271,34 +2488,6 @@ var OwneySDK = class {
|
|
|
2271
2488
|
}
|
|
2272
2489
|
return eligible;
|
|
2273
2490
|
}
|
|
2274
|
-
/**
|
|
2275
|
-
* Agent ids the routing API provisioned for this org that support the given
|
|
2276
|
-
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
2277
|
-
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
2278
|
-
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
2279
|
-
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
2280
|
-
*
|
|
2281
|
-
* This is the source of truth for agent availability: an agent appears here
|
|
2282
|
-
* iff the routing API returned its key. No per-app feature flags.
|
|
2283
|
-
*/
|
|
2284
|
-
async getEligibleAgentIds(chainId, asset) {
|
|
2285
|
-
try {
|
|
2286
|
-
await this.ensureAgentsInitialized();
|
|
2287
|
-
} catch (error) {
|
|
2288
|
-
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
2289
|
-
return [];
|
|
2290
|
-
}
|
|
2291
|
-
throw error;
|
|
2292
|
-
}
|
|
2293
|
-
return [...this.agents.values()].filter((agent) => {
|
|
2294
|
-
const chainAssets = agent.supportedAssets.find(
|
|
2295
|
-
(sa) => sa.chainId === chainId
|
|
2296
|
-
);
|
|
2297
|
-
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
2298
|
-
}).map((agent) => agent.id).sort(
|
|
2299
|
-
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
2300
|
-
);
|
|
2301
|
-
}
|
|
2302
2491
|
// --- Fund operations ---
|
|
2303
2492
|
/**
|
|
2304
2493
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2334,17 +2523,9 @@ var OwneySDK = class {
|
|
|
2334
2523
|
}
|
|
2335
2524
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2336
2525
|
if (!amount) {
|
|
2337
|
-
const aggregated2 = await this.getBalances();
|
|
2338
|
-
const funded = projectAgentBalancesForAsset(
|
|
2339
|
-
eligibleAgents,
|
|
2340
|
-
aggregated2.agentBalances,
|
|
2341
|
-
chainId,
|
|
2342
|
-
asset,
|
|
2343
|
-
assetInfo.decimals
|
|
2344
|
-
).filter((b) => b.balance > 0n);
|
|
2345
2526
|
const results2 = {};
|
|
2346
2527
|
const agentErrors2 = {};
|
|
2347
|
-
for (const
|
|
2528
|
+
for (const agent of eligibleAgents) {
|
|
2348
2529
|
try {
|
|
2349
2530
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2350
2531
|
} catch (err) {
|
|
@@ -2361,10 +2542,9 @@ var OwneySDK = class {
|
|
|
2361
2542
|
{ asset, agentErrors: agentErrors2 }
|
|
2362
2543
|
);
|
|
2363
2544
|
}
|
|
2364
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2365
2545
|
return {
|
|
2366
2546
|
agentResult: results2,
|
|
2367
|
-
totalWithdrawn:
|
|
2547
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
2368
2548
|
};
|
|
2369
2549
|
}
|
|
2370
2550
|
const requested = BigInt(amount);
|
|
@@ -3075,5 +3255,6 @@ export {
|
|
|
3075
3255
|
NotConnectedError,
|
|
3076
3256
|
OwneyError,
|
|
3077
3257
|
OwneySDK,
|
|
3078
|
-
createOwneySIWX
|
|
3258
|
+
createOwneySIWX,
|
|
3259
|
+
setOwneyDebug
|
|
3079
3260
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owney/sdk",
|
|
3
|
-
"version": "0.6.9-beta.
|
|
3
|
+
"version": "0.6.9-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -23,9 +23,7 @@
|
|
|
23
23
|
"test:watch": "vitest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@surf_liquid/core-sdk": "^0.4.0",
|
|
27
26
|
"@zyfai/sdk": "^0.2.41",
|
|
28
|
-
"ethers": "^6.17.0",
|
|
29
27
|
"siwe": "^3.0.0",
|
|
30
28
|
"viem": "^2.48.1"
|
|
31
29
|
},
|
package/dist/chunk-GMNQBWUB.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// src/errors.ts
|
|
2
|
-
var OwneyError = class extends Error {
|
|
3
|
-
code;
|
|
4
|
-
details;
|
|
5
|
-
agentId;
|
|
6
|
-
constructor(code, message, details, agentId) {
|
|
7
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
8
|
-
super(`${prefix} ${message}`);
|
|
9
|
-
this.name = "OwneyError";
|
|
10
|
-
this.code = code;
|
|
11
|
-
this.details = details;
|
|
12
|
-
this.agentId = agentId;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
16
|
-
constructor(agentId, available) {
|
|
17
|
-
super(
|
|
18
|
-
"AGENT_NOT_FOUND",
|
|
19
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
20
|
-
{ agentId, available },
|
|
21
|
-
agentId
|
|
22
|
-
);
|
|
23
|
-
this.name = "AgentNotFoundError";
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var NotConnectedError = class extends OwneyError {
|
|
27
|
-
constructor() {
|
|
28
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
29
|
-
this.name = "NotConnectedError";
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
33
|
-
incompatibleAgents;
|
|
34
|
-
connectedChainId;
|
|
35
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
36
|
-
const details = incompatibleAgents.map(
|
|
37
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
38
|
-
).join("; ");
|
|
39
|
-
super(
|
|
40
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
41
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
42
|
-
{ incompatibleAgents, connectedChainId }
|
|
43
|
-
);
|
|
44
|
-
this.name = "AgentChainIncompatibleError";
|
|
45
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
46
|
-
this.connectedChainId = connectedChainId;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
OwneyError,
|
|
52
|
-
AgentNotFoundError,
|
|
53
|
-
NotConnectedError,
|
|
54
|
-
AgentChainIncompatibleError
|
|
55
|
-
};
|