@owney/sdk 0.7.0-beta.1 → 0.7.1

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 CHANGED
@@ -9,9 +9,9 @@ var __export = (target, all) => {
9
9
  };
10
10
  var __copyProps = (to, from, except, desc) => {
11
11
  if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ for (let key2 of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key2) && key2 !== except)
14
+ __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
15
15
  }
16
16
  return to;
17
17
  };
@@ -26,7 +26,8 @@ __export(index_exports, {
26
26
  NotConnectedError: () => NotConnectedError,
27
27
  OwneyError: () => OwneyError,
28
28
  OwneySDK: () => OwneySDK,
29
- createOwneySIWX: () => createOwneySIWX
29
+ createOwneySIWX: () => createOwneySIWX,
30
+ setOwneyDebug: () => setOwneyDebug
30
31
  });
31
32
  module.exports = __toCommonJS(index_exports);
32
33
 
@@ -412,7 +413,9 @@ function mapUserProfile(raw, userAddress) {
412
413
  chains: raw.chains || [],
413
414
  strategy: raw.strategy,
414
415
  hasActiveSessionKey: raw.hasActiveSessionKey || false,
415
- protocols: raw.protocols || []
416
+ protocols: raw.protocols || [],
417
+ splitting: raw.splitting,
418
+ minSplits: raw.minSplits
416
419
  };
417
420
  }
418
421
  function mapApyByStrategy(raw) {
@@ -559,23 +562,23 @@ var readLegacySession = (store, address) => {
559
562
  const legacyKeys = [];
560
563
  try {
561
564
  for (let i = 0; i < store.length; i++) {
562
- const key = store.key(i);
563
- if (key?.startsWith(prefix)) legacyKeys.push(key);
565
+ const key2 = store.key(i);
566
+ if (key2?.startsWith(prefix)) legacyKeys.push(key2);
564
567
  }
565
568
  } catch {
566
569
  return null;
567
570
  }
568
571
  let adopted = null;
569
- for (const key of legacyKeys) {
572
+ for (const key2 of legacyKeys) {
570
573
  if (!adopted) {
571
574
  try {
572
- const parsed = JSON.parse(store.getItem(key) ?? "");
575
+ const parsed = JSON.parse(store.getItem(key2) ?? "");
573
576
  if (isFreshSession(parsed)) adopted = parsed;
574
577
  } catch {
575
578
  }
576
579
  }
577
580
  try {
578
- store.removeItem(key);
581
+ store.removeItem(key2);
579
582
  } catch {
580
583
  }
581
584
  }
@@ -583,11 +586,11 @@ var readLegacySession = (store, address) => {
583
586
  };
584
587
  var readSession = (address, _chainId) => {
585
588
  if (typeof window === "undefined") return null;
586
- const key = buildKey(address);
589
+ const key2 = buildKey(address);
587
590
  const store = storage();
588
591
  let raw = null;
589
592
  try {
590
- raw = store?.getItem(key) ?? null;
593
+ raw = store?.getItem(key2) ?? null;
591
594
  } catch {
592
595
  raw = null;
593
596
  }
@@ -597,9 +600,9 @@ var readSession = (address, _chainId) => {
597
600
  if (isFreshSession(parsed)) return parsed;
598
601
  } catch {
599
602
  }
600
- memorySessions.delete(key);
603
+ memorySessions.delete(key2);
601
604
  try {
602
- store?.removeItem(key);
605
+ store?.removeItem(key2);
603
606
  } catch {
604
607
  }
605
608
  return null;
@@ -609,27 +612,27 @@ var readSession = (address, _chainId) => {
609
612
  writeSession(address, _chainId, legacy);
610
613
  return legacy;
611
614
  }
612
- const cached = memorySessions.get(key);
615
+ const cached = memorySessions.get(key2);
613
616
  if (isFreshSession(cached)) return cached;
614
- if (cached) memorySessions.delete(key);
617
+ if (cached) memorySessions.delete(key2);
615
618
  return null;
616
619
  };
617
620
  var writeSession = (address, _chainId, session) => {
618
621
  if (typeof window === "undefined") return;
619
- const key = buildKey(address);
620
- memorySessions.set(key, session);
622
+ const key2 = buildKey(address);
623
+ memorySessions.set(key2, session);
621
624
  const store = storage();
622
625
  try {
623
- store?.setItem(key, JSON.stringify(session));
626
+ store?.setItem(key2, JSON.stringify(session));
624
627
  } catch {
625
628
  }
626
629
  };
627
630
  var clearSession = (address, _chainId) => {
628
- const key = buildKey(address);
629
- memorySessions.delete(key);
631
+ const key2 = buildKey(address);
632
+ memorySessions.delete(key2);
630
633
  const store = storage();
631
634
  try {
632
- store?.removeItem(key);
635
+ store?.removeItem(key2);
633
636
  } catch {
634
637
  }
635
638
  readLegacySession(store, address);
@@ -660,6 +663,149 @@ function buildProtocolMergeUpdate(available, current, asset) {
660
663
  };
661
664
  }
662
665
 
666
+ // src/agents/zyfai/splitting.ts
667
+ var MAX_MIN_SPLITS = 4;
668
+ var MIN_FORCE_SPLITS = 2;
669
+ var AUTOMATIC_MIN_SPLITS = 1;
670
+ function toZyfaiSplitting(policy) {
671
+ switch (policy.splittingMode) {
672
+ case "none":
673
+ return { splitting: false };
674
+ case "automatic":
675
+ return { splitting: true, minSplits: AUTOMATIC_MIN_SPLITS };
676
+ case "force":
677
+ return {
678
+ splitting: true,
679
+ minSplits: clampForceSplits(policy.minSplits)
680
+ };
681
+ }
682
+ }
683
+ function clampForceSplits(minSplits) {
684
+ if (typeof minSplits !== "number" || !Number.isFinite(minSplits)) {
685
+ return MIN_FORCE_SPLITS;
686
+ }
687
+ const rounded = Math.round(minSplits);
688
+ if (rounded < MIN_FORCE_SPLITS) return MIN_FORCE_SPLITS;
689
+ if (rounded > MAX_MIN_SPLITS) return MAX_MIN_SPLITS;
690
+ return rounded;
691
+ }
692
+ function splittingNeedsUpdate(current, desired) {
693
+ if (!current) return true;
694
+ if (current.splitting !== desired.splitting) return true;
695
+ if (desired.minSplits === void 0) return false;
696
+ return current.minSplits !== desired.minSplits;
697
+ }
698
+
699
+ // src/agents/zyfai/pool-policy.ts
700
+ function toZyfaiCustomizations(policy, availableByProtocol, chainsByProtocol) {
701
+ const selectionByKey = /* @__PURE__ */ new Map();
702
+ for (const selection of policy.selections) {
703
+ selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
704
+ }
705
+ const customizations = [];
706
+ for (const [protocolId, chainIds] of Object.entries(chainsByProtocol)) {
707
+ const available = availableByProtocol.get(protocolId);
708
+ if (available === void 0) {
709
+ continue;
710
+ }
711
+ const availableSet = new Set(available);
712
+ for (const chainId of chainIds) {
713
+ const stored = selectionByKey.get(key(protocolId, chainId));
714
+ if (stored === void 0) {
715
+ customizations.push({
716
+ protocolId,
717
+ chainId,
718
+ pools: [],
719
+ autoselect: true
720
+ });
721
+ continue;
722
+ }
723
+ const pools = stored.pools.filter((pool) => availableSet.has(pool));
724
+ customizations.push({
725
+ protocolId,
726
+ chainId,
727
+ pools,
728
+ autoselect: false
729
+ });
730
+ }
731
+ }
732
+ return customizations;
733
+ }
734
+ function deriveProtocols(policy, universe, chainsByProtocol) {
735
+ if (policy.selections.length === 0) {
736
+ return null;
737
+ }
738
+ const selectionByKey = /* @__PURE__ */ new Map();
739
+ for (const selection of policy.selections) {
740
+ selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
741
+ }
742
+ return universe.filter((protocolId) => {
743
+ const chainIds = chainsByProtocol[protocolId];
744
+ if (chainIds === void 0 || chainIds.length === 0) {
745
+ return true;
746
+ }
747
+ const fullyDisabled = chainIds.every((chainId) => {
748
+ const stored = selectionByKey.get(key(protocolId, chainId));
749
+ return stored !== void 0 && stored.pools.length === 0;
750
+ });
751
+ return !fullyDisabled;
752
+ });
753
+ }
754
+ function key(protocolId, chainId) {
755
+ return `${protocolId}:${chainId}`;
756
+ }
757
+ function buildChainsByProtocol(protocols, dashboardChainIds) {
758
+ const allowed = new Set(dashboardChainIds);
759
+ const result = {};
760
+ for (const protocol of protocols) {
761
+ result[protocol.id] = (protocol.chains ?? []).filter(
762
+ (chainId) => allowed.has(chainId)
763
+ );
764
+ }
765
+ return result;
766
+ }
767
+ function flattenAvailablePools(raw) {
768
+ const byChain = raw ?? {};
769
+ const names = [];
770
+ for (const byToken of Object.values(byChain ?? {})) {
771
+ for (const entry of Object.values(byToken ?? {})) {
772
+ for (const pool of entry?.pools ?? []) {
773
+ if (pool?.name) names.push(pool.name);
774
+ }
775
+ }
776
+ }
777
+ return names;
778
+ }
779
+ function protocolListsEqual(a, b) {
780
+ const left = [...a ?? []].sort();
781
+ const right = [...b ?? []].sort();
782
+ if (left.length !== right.length) return false;
783
+ return left.every((value, index) => value === right[index]);
784
+ }
785
+ function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect) {
786
+ if (!current) return true;
787
+ if (current.autoSelectProtocols !== desiredAutoSelect) return true;
788
+ if (desiredProtocols === null) return false;
789
+ return !protocolListsEqual(current.protocols, desiredProtocols);
790
+ }
791
+
792
+ // src/lib/debug.ts
793
+ var configuredDebug = false;
794
+ function setOwneyDebug(enabled) {
795
+ configuredDebug = enabled;
796
+ }
797
+ function isOwneyDebug() {
798
+ return globalThis.__OWNEY_DEBUG__ === true || configuredDebug;
799
+ }
800
+ function debugLog(scope, message, data) {
801
+ if (!isOwneyDebug()) return;
802
+ if (data === void 0) {
803
+ console.log(`[${scope}] ${message}`);
804
+ } else {
805
+ console.log(`[${scope}] ${message}`, data);
806
+ }
807
+ }
808
+
663
809
  // src/agents/zyfai/zyfai.agent.ts
664
810
  var DEFAULT_ZYFAI_RPC_URLS = {
665
811
  8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
@@ -672,6 +818,8 @@ var WETH_ADDRESS_BY_CHAIN = {
672
818
  1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
673
819
  };
674
820
  var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
821
+ var SPLITTING_ASSETS = ["USDC", "WETH"];
822
+ var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
675
823
  var ZyfaiAgent = class {
676
824
  id = "zyfai";
677
825
  supportedChainIds = [8453, 42161, 1];
@@ -982,6 +1130,176 @@ var ZyfaiAgent = class {
982
1130
  throw error;
983
1131
  }
984
1132
  }
1133
+ /**
1134
+ * Apply the org's capital splitting policy to this user's Zyfai profile.
1135
+ *
1136
+ * Per ASSET, not per chain: Zyfai stores splitting under
1137
+ * `assetTypeSettings[asset]`, so one call would only configure USDC and leave a
1138
+ * WETH holder's real setting untouched.
1139
+ *
1140
+ * Non-fatal throughout. This is a side effect of connecting, so a Zyfai hiccup
1141
+ * must leave the user connected with their profile unchanged, never fail
1142
+ * activation.
1143
+ */
1144
+ async applyOrgPolicy(_state, _chainId, policy) {
1145
+ debugLog("zyfai:splitting", "applying org policy", {
1146
+ policy,
1147
+ // Per asset because Zyfai stores splitting under assetTypeSettings[asset].
1148
+ assets: SPLITTING_ASSETS
1149
+ });
1150
+ await Promise.all(
1151
+ SPLITTING_ASSETS.map((asset) => this.applySplitting(asset, policy))
1152
+ );
1153
+ if (policy.poolPolicy) {
1154
+ await this.applyPoolPolicy(policy.poolPolicy);
1155
+ }
1156
+ }
1157
+ async applySplitting(asset, policy) {
1158
+ try {
1159
+ const desired = toZyfaiSplitting(policy);
1160
+ const current = await this.sdk.getUserDetails(asset);
1161
+ const currentSplitting = {
1162
+ splitting: current?.splitting,
1163
+ minSplits: current?.minSplits
1164
+ };
1165
+ const needsUpdate = splittingNeedsUpdate(current, desired);
1166
+ debugLog("zyfai:splitting", `${asset}: comparing`, {
1167
+ mode: policy.splittingMode,
1168
+ current: currentSplitting,
1169
+ desired,
1170
+ // Spelled out because the "why" is the non-obvious part: minSplits is
1171
+ // what separates automatic (1) from force (2-4), not `splitting`.
1172
+ decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
1173
+ });
1174
+ if (!needsUpdate) return;
1175
+ const result = await this.sdk.updateUserProfile({ asset, ...desired });
1176
+ debugLog("zyfai:splitting", `${asset}: wrote updateUserProfile`, {
1177
+ sent: { asset, ...desired },
1178
+ // updateUserProfile re-reads the profile after PATCHing, so this is
1179
+ // Zyfai's own view of the result rather than an echo of what we sent.
1180
+ zyfaiNowReports: {
1181
+ splitting: result?.splitting,
1182
+ minSplits: result?.minSplits
1183
+ }
1184
+ });
1185
+ } catch (error) {
1186
+ console.warn(
1187
+ `[zyfai] applyOrgPolicy(${asset}) failed (non-fatal):`,
1188
+ error instanceof Error ? error.message : String(error)
1189
+ );
1190
+ }
1191
+ }
1192
+ /**
1193
+ * Apply the org's protocol/pool policy to this user's Zyfai profile.
1194
+ *
1195
+ * Two Zyfai writes, in a strict order:
1196
+ * 1. `updateUserProfile({ protocols, autoSelectProtocols })` per asset —
1197
+ * the explicit allow-list. Chain-agnostic, mirrors `applySplitting`.
1198
+ * 2. `customizeBatch(...)` once — per (protocol, chain), asset-agnostic
1199
+ * pool narrowing.
1200
+ *
1201
+ * Order matters: constraining a protocol's pools (step 2) while that
1202
+ * protocol is not yet in the allow-list (step 1 not yet applied) lands the
1203
+ * constraint on something the rebalance engine isn't considering.
1204
+ *
1205
+ * Wrapped so a failure anywhere is non-fatal — this runs as a side effect of
1206
+ * connecting, so a Zyfai hiccup must leave the user connected with their
1207
+ * profile unchanged, never fail activation.
1208
+ */
1209
+ async applyPoolPolicy(policy) {
1210
+ try {
1211
+ const { protocols: universe } = await this.sdk.getAvailableProtocols(
1212
+ this.supportedChainIds[0]
1213
+ );
1214
+ const universeIds = universe.map((p) => p.id);
1215
+ const chainsByProtocol = buildChainsByProtocol(
1216
+ universe,
1217
+ POOL_POLICY_CHAIN_IDS
1218
+ );
1219
+ debugLog("zyfai:pools", "protocol universe", {
1220
+ universeIds,
1221
+ chainsByProtocol
1222
+ });
1223
+ let strategy;
1224
+ const desiredProtocols = deriveProtocols(
1225
+ policy,
1226
+ universeIds,
1227
+ chainsByProtocol
1228
+ );
1229
+ const desiredAutoSelect = policy.autoApproveProtocols;
1230
+ for (const asset of SPLITTING_ASSETS) {
1231
+ const current = await this.sdk.getUserDetails(asset);
1232
+ if (strategy === void 0 && (current.strategy === "conservative" || current.strategy === "aggressive")) {
1233
+ strategy = current.strategy;
1234
+ }
1235
+ const needsUpdate = protocolsPolicyNeedsUpdate(
1236
+ current,
1237
+ desiredProtocols,
1238
+ desiredAutoSelect
1239
+ );
1240
+ debugLog("zyfai:pools", `${asset}: comparing protocols`, {
1241
+ current: {
1242
+ protocols: current.protocols,
1243
+ autoSelectProtocols: current.autoSelectProtocols
1244
+ },
1245
+ desired: {
1246
+ protocols: desiredProtocols,
1247
+ autoSelectProtocols: desiredAutoSelect
1248
+ },
1249
+ decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
1250
+ });
1251
+ if (!needsUpdate) continue;
1252
+ const update = {
1253
+ asset,
1254
+ autoSelectProtocols: desiredAutoSelect
1255
+ };
1256
+ if (desiredProtocols !== null) update.protocols = desiredProtocols;
1257
+ await this.sdk.updateUserProfile(update);
1258
+ debugLog("zyfai:pools", `${asset}: wrote protocols update`, update);
1259
+ }
1260
+ const poolResults = await Promise.all(
1261
+ universe.map(async (protocol) => {
1262
+ try {
1263
+ const raw = await this.sdk.getAvailablePools(protocol.id, strategy);
1264
+ return [protocol.id, flattenAvailablePools(raw)];
1265
+ } catch (error) {
1266
+ console.warn(
1267
+ `[zyfai] applyPoolPolicy: getAvailablePools(${protocol.id}) failed, skipping this protocol (non-fatal):`,
1268
+ error instanceof Error ? error.message : String(error)
1269
+ );
1270
+ return null;
1271
+ }
1272
+ })
1273
+ );
1274
+ const availableByProtocol = /* @__PURE__ */ new Map();
1275
+ for (const result of poolResults) {
1276
+ if (result) availableByProtocol.set(result[0], result[1]);
1277
+ }
1278
+ const customizations = toZyfaiCustomizations(
1279
+ policy,
1280
+ availableByProtocol,
1281
+ chainsByProtocol
1282
+ );
1283
+ debugLog("zyfai:pools", "derived customizeBatch payload", {
1284
+ strategy,
1285
+ availableProtocolCount: availableByProtocol.size,
1286
+ customizations
1287
+ });
1288
+ if (customizations.length === 0) {
1289
+ debugLog("zyfai:pools", "skipping customizeBatch \u2014 nothing to send");
1290
+ return;
1291
+ }
1292
+ await this.sdk.customizeBatch(customizations);
1293
+ debugLog("zyfai:pools", "wrote customizeBatch", {
1294
+ count: customizations.length
1295
+ });
1296
+ } catch (error) {
1297
+ console.warn(
1298
+ "[zyfai] applyPoolPolicy failed (non-fatal):",
1299
+ error instanceof Error ? error.message : String(error)
1300
+ );
1301
+ }
1302
+ }
985
1303
  async deposit(state, chainId, amount, asset, depositCallback) {
986
1304
  try {
987
1305
  const validChainId = isValidChainId(chainId);
@@ -1102,6 +1420,16 @@ var ZyfaiAgent = class {
1102
1420
  async getUserProfile(state, chainId) {
1103
1421
  await this.connectAuth(state, chainId);
1104
1422
  const raw = await this.sdk.getUserDetails();
1423
+ debugLog("zyfai:profile", "getUserProfile \u2014 Zyfai reports", {
1424
+ asset: "USDC (default \u2014 no asset passed)",
1425
+ splitting: raw.splitting,
1426
+ minSplits: raw.minSplits,
1427
+ strategy: raw.strategy,
1428
+ chains: raw.chains,
1429
+ protocolCount: raw.protocols?.length,
1430
+ hasActiveSessionKey: raw.hasActiveSessionKey,
1431
+ smartWallet: raw.smartWallet
1432
+ });
1105
1433
  return mapUserProfile(raw, this.connectedAddress);
1106
1434
  }
1107
1435
  async ensureAutoSelectProtocols(state, chainId, asset) {
@@ -1134,6 +1462,40 @@ var ZyfaiAgent = class {
1134
1462
 
1135
1463
  // src/lib/routing-api.ts
1136
1464
  var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
1465
+ async function fetchOrgAgentConfig(apiKey) {
1466
+ const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
1467
+ try {
1468
+ const res = await fetch(url, {
1469
+ method: "GET",
1470
+ headers: {
1471
+ "Content-Type": "application/json",
1472
+ "x-owney-api-key": `${apiKey}`
1473
+ }
1474
+ });
1475
+ if (!res.ok) {
1476
+ if (res.status !== 404) {
1477
+ console.warn(
1478
+ `[owney-sdk] Could not read org agent config (${res.status}); leaving user profiles unchanged.`
1479
+ );
1480
+ }
1481
+ return null;
1482
+ }
1483
+ const json = await res.json();
1484
+ const policy = json.success ? json.data ?? null : null;
1485
+ debugLog(
1486
+ "owney-sdk",
1487
+ policy ? "org agent config: loaded" : "org agent config: none set by this partner \u2014 user profiles will be left as they are",
1488
+ policy ?? void 0
1489
+ );
1490
+ return policy;
1491
+ } catch (error) {
1492
+ console.warn(
1493
+ "[owney-sdk] Could not read org agent config (non-fatal):",
1494
+ error instanceof Error ? error.message : String(error)
1495
+ );
1496
+ return null;
1497
+ }
1498
+ }
1137
1499
  async function fetchAgentKeys(apiKey) {
1138
1500
  const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
1139
1501
  const res = await fetch(url, {
@@ -1747,6 +2109,12 @@ var OwneySDK = class {
1747
2109
  disabledAgents = /* @__PURE__ */ new Set();
1748
2110
  state = null;
1749
2111
  apiKey;
2112
+ // The org's agent policy, fetched once per client. Applied to each agent on
2113
+ // activation (ROUT-229). `undefined` means "not fetched yet", `null` means
2114
+ // "fetched, and the partner has no policy" — which is a real answer meaning
2115
+ // leave every user's agent profile alone.
2116
+ orgAgentConfig;
2117
+ orgAgentConfigPromise = null;
1750
2118
  zyfaiRpcUrls;
1751
2119
  routingApiBaseUrl;
1752
2120
  referralSource;
@@ -1755,6 +2123,7 @@ var OwneySDK = class {
1755
2123
  initializingAgentsPromise = null;
1756
2124
  constructor(config) {
1757
2125
  this.apiKey = config.apiKey;
2126
+ if (config.debug) setOwneyDebug(true);
1758
2127
  this.zyfaiRpcUrls = config.zyfaiRpcUrls;
1759
2128
  this.routingApiBaseUrl = config.routingApiBaseUrl;
1760
2129
  this.referralSource = config.referralSource;
@@ -1916,14 +2285,57 @@ var OwneySDK = class {
1916
2285
  }
1917
2286
  return active;
1918
2287
  }
2288
+ /**
2289
+ * Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
2290
+ * throws — it degrades to null — so this cannot break activation.
2291
+ */
2292
+ async getOrgAgentConfig() {
2293
+ if (this.orgAgentConfig !== void 0) return this.orgAgentConfig;
2294
+ if (!this.orgAgentConfigPromise) {
2295
+ this.orgAgentConfigPromise = fetchOrgAgentConfig(this.apiKey).then(
2296
+ (config) => {
2297
+ this.orgAgentConfig = config;
2298
+ return config;
2299
+ }
2300
+ );
2301
+ }
2302
+ return this.orgAgentConfigPromise;
2303
+ }
2304
+ /**
2305
+ * Apply the org policy to one agent, after it has activated.
2306
+ *
2307
+ * Sequenced after activation rather than alongside it because applying the
2308
+ * policy needs the authenticated session activation establishes. Every failure
2309
+ * mode is swallowed: a partner's splitting preference is not worth failing a
2310
+ * user's connect over.
2311
+ */
2312
+ async applyOrgPolicyTo(agent, state, chainId) {
2313
+ if (!agent.applyOrgPolicy) {
2314
+ debugLog(
2315
+ "owney-sdk",
2316
+ `${agent.id}: no applyOrgPolicy \u2014 agent has no org-level knobs, skipping`
2317
+ );
2318
+ return;
2319
+ }
2320
+ try {
2321
+ const policy = await this.getOrgAgentConfig();
2322
+ if (!policy) return;
2323
+ await agent.applyOrgPolicy(state, chainId, policy);
2324
+ } catch (error) {
2325
+ console.warn(
2326
+ `[owney-sdk] applyOrgPolicy(${agent.id}) failed (non-fatal):`,
2327
+ error instanceof Error ? error.message : String(error)
2328
+ );
2329
+ }
2330
+ }
1919
2331
  async ensureAgentsInitialized() {
1920
2332
  if (this.agents.size > 0) return;
1921
2333
  if (!this.initializingAgentsPromise) {
1922
2334
  this.initializingAgentsPromise = (async () => {
1923
2335
  const agentKeys = await fetchAgentKeys(this.apiKey);
1924
2336
  this.disabledAgents.clear();
1925
- for (const { key, agent_type, is_enabled } of agentKeys) {
1926
- const agent = this.createAgent(agent_type, key);
2337
+ for (const { key: key2, agent_type, is_enabled } of agentKeys) {
2338
+ const agent = this.createAgent(agent_type, key2);
1927
2339
  if (!agent) continue;
1928
2340
  this.agents.set(agent_type, agent);
1929
2341
  if (is_enabled === false) {
@@ -1944,9 +2356,9 @@ var OwneySDK = class {
1944
2356
  this.initializingAgentsPromise = null;
1945
2357
  }
1946
2358
  }
1947
- createAgent(agentId, key) {
2359
+ createAgent(agentId, key2) {
1948
2360
  if (agentId === "zyfai") {
1949
- return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
2361
+ return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
1950
2362
  }
1951
2363
  return null;
1952
2364
  }
@@ -2000,6 +2412,7 @@ var OwneySDK = class {
2000
2412
  Promise.all(
2001
2413
  agents.map(async (agent) => {
2002
2414
  await agent.activateAgent(state, chainId);
2415
+ await this.applyOrgPolicyTo(agent, state, chainId);
2003
2416
  })
2004
2417
  ).catch((error) => {
2005
2418
  console.error("activateAgent background init failed:", error);
@@ -2027,6 +2440,7 @@ var OwneySDK = class {
2027
2440
  Promise.all(
2028
2441
  enabledCompatible.map(async (agent) => {
2029
2442
  await agent.activateAgent(state, chainId);
2443
+ await this.applyOrgPolicyTo(agent, state, chainId);
2030
2444
  })
2031
2445
  ).catch((error) => {
2032
2446
  console.error("activateAgent background init failed:", error);
@@ -2841,22 +3255,22 @@ var readLegacySiwxSession = (store, address) => {
2841
3255
  const legacyKeys = [];
2842
3256
  try {
2843
3257
  for (let i = 0; i < store.length; i++) {
2844
- const key = store.key(i);
2845
- if (key?.startsWith(prefix)) legacyKeys.push(key);
3258
+ const key2 = store.key(i);
3259
+ if (key2?.startsWith(prefix)) legacyKeys.push(key2);
2846
3260
  }
2847
3261
  } catch {
2848
3262
  return null;
2849
3263
  }
2850
3264
  let adopted = null;
2851
- for (const key of legacyKeys) {
3265
+ for (const key2 of legacyKeys) {
2852
3266
  if (!adopted) {
2853
3267
  try {
2854
- adopted = JSON.parse(store.getItem(key) ?? "");
3268
+ adopted = JSON.parse(store.getItem(key2) ?? "");
2855
3269
  } catch {
2856
3270
  }
2857
3271
  }
2858
3272
  try {
2859
- store.removeItem(key);
3273
+ store.removeItem(key2);
2860
3274
  } catch {
2861
3275
  }
2862
3276
  }
@@ -2864,11 +3278,11 @@ var readLegacySiwxSession = (store, address) => {
2864
3278
  };
2865
3279
  var readSiwxSession = (address, chainId) => {
2866
3280
  if (typeof window === "undefined") return null;
2867
- const key = buildKey2(address);
3281
+ const key2 = buildKey2(address);
2868
3282
  const store = storage2();
2869
3283
  let raw = null;
2870
3284
  try {
2871
- raw = store?.getItem(key) ?? null;
3285
+ raw = store?.getItem(key2) ?? null;
2872
3286
  } catch {
2873
3287
  raw = null;
2874
3288
  }
@@ -2876,9 +3290,9 @@ var readSiwxSession = (address, chainId) => {
2876
3290
  try {
2877
3291
  return JSON.parse(raw);
2878
3292
  } catch {
2879
- memorySiwxSessions.delete(key);
3293
+ memorySiwxSessions.delete(key2);
2880
3294
  try {
2881
- store?.removeItem(key);
3295
+ store?.removeItem(key2);
2882
3296
  } catch {
2883
3297
  }
2884
3298
  return null;
@@ -2889,24 +3303,24 @@ var readSiwxSession = (address, chainId) => {
2889
3303
  writeSiwxSession(address, chainId, legacy);
2890
3304
  return legacy;
2891
3305
  }
2892
- return memorySiwxSessions.get(key) ?? null;
3306
+ return memorySiwxSessions.get(key2) ?? null;
2893
3307
  };
2894
3308
  var writeSiwxSession = (address, _chainId, session) => {
2895
3309
  if (typeof window === "undefined") return;
2896
- const key = buildKey2(address);
2897
- memorySiwxSessions.set(key, session);
3310
+ const key2 = buildKey2(address);
3311
+ memorySiwxSessions.set(key2, session);
2898
3312
  const store = storage2();
2899
3313
  try {
2900
- store?.setItem(key, JSON.stringify(session));
3314
+ store?.setItem(key2, JSON.stringify(session));
2901
3315
  } catch {
2902
3316
  }
2903
3317
  };
2904
3318
  var clearSiwxSession = (address, _chainId) => {
2905
- const key = buildKey2(address);
2906
- memorySiwxSessions.delete(key);
3319
+ const key2 = buildKey2(address);
3320
+ memorySiwxSessions.delete(key2);
2907
3321
  const store = storage2();
2908
3322
  try {
2909
- store?.removeItem(key);
3323
+ store?.removeItem(key2);
2910
3324
  } catch {
2911
3325
  }
2912
3326
  readLegacySiwxSession(store, address);
@@ -3036,5 +3450,6 @@ function createOwneySIWX(config) {
3036
3450
  NotConnectedError,
3037
3451
  OwneyError,
3038
3452
  OwneySDK,
3039
- createOwneySIWX
3453
+ createOwneySIWX,
3454
+ setOwneyDebug
3040
3455
  });