@owney/sdk 0.2.10 → 0.2.12

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
@@ -128,15 +128,6 @@ function hexToDecimal(hex, decimals = 6) {
128
128
  const remainder = parsed % divisor;
129
129
  return Number(whole) + Number(remainder) / Number(divisor);
130
130
  }
131
- function normalizeDecimalPlace(value, decimals = 6) {
132
- const parsed = BigInt(value);
133
- if (decimals <= 0)
134
- return Number(parsed);
135
- const divisor = BigInt(10 ** decimals);
136
- const whole = parsed / divisor;
137
- const remainder = parsed % divisor;
138
- return Number(whole) + Number(remainder) / Number(divisor);
139
- }
140
131
  var DayFilterMapping = {
141
132
  "30D": 30,
142
133
  "14D": 14,
@@ -162,34 +153,25 @@ var CHAIN_ID_TO_NAME = {
162
153
  8453: "BASE",
163
154
  42161: "ARBITRUM"
164
155
  };
165
- var CHAIN_NAME_TO_ID = {
166
- BASE: 8453,
167
- ARBITRUM: 42161
168
- };
169
- function mapBalances(raw, chainId, smartWallet) {
156
+ function mapBalances(raw, _chainId, smartWallet) {
170
157
  const portfolio = raw.portfolio;
171
- const tokenMap = /* @__PURE__ */ new Map();
172
- for (const p of portfolio.positions || []) {
173
- const symbol = p.token_symbol || "USDC";
174
- const positionChainId = (p.chain ? CHAIN_NAME_TO_ID[p.chain.toUpperCase()] : void 0) ?? chainId;
175
- const key = `${symbol}:${positionChainId}`;
176
- const current = tokenMap.get(key);
177
- tokenMap.set(key, {
178
- symbol,
179
- chainId: positionChainId,
180
- amount: (current?.amount ?? 0) + normalizeDecimalPlace(p.underlyingAmount || "0")
181
- });
182
- }
158
+ const portfolioByChain = portfolio.portfolioByChain ?? {};
183
159
  let totalBalance = 0;
184
160
  const tokens = [];
185
- for (const [, entry] of tokenMap) {
186
- totalBalance += entry.amount;
187
- tokens.push({
188
- chain: CHAIN_ID_TO_NAME[entry.chainId] ?? "BASE",
189
- chainId: entry.chainId,
190
- asset: entry.symbol,
191
- amount: String(entry.amount)
192
- });
161
+ for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
162
+ const positionChainId = Number(chainIdKey);
163
+ for (const [symbol, { balance, decimals }] of Object.entries(
164
+ tokensBySymbol ?? {}
165
+ )) {
166
+ const amount = hexToDecimal(balance || "0", decimals);
167
+ totalBalance += amount;
168
+ tokens.push({
169
+ chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
170
+ chainId: positionChainId,
171
+ asset: symbol,
172
+ amount: String(amount)
173
+ });
174
+ }
193
175
  }
194
176
  return {
195
177
  smartWallet,
@@ -215,7 +197,7 @@ function mapApyHistory(raw) {
215
197
  weightedApyAfterFee: raw.weightedApyAfterFee ? sumTokenValues(raw.weightedApyAfterFee) : void 0
216
198
  };
217
199
  }
218
- function mapHistory(raw) {
200
+ function mapHistory(raw, chainId) {
219
201
  const actionMap = {
220
202
  "Deposit to protocol": "Deposit",
221
203
  "Top up wallet": "Top up",
@@ -224,7 +206,7 @@ function mapHistory(raw) {
224
206
  };
225
207
  return {
226
208
  total: raw.total,
227
- data: raw.data.map((entry) => {
209
+ data: raw.data.filter((d) => d.chainId === chainId).map((entry) => {
228
210
  const rawLog = entry.rebalanceLog;
229
211
  const positions = entry.positions ?? [];
230
212
  let rebalanceLog = [];
@@ -257,7 +239,9 @@ function mapHistory(raw) {
257
239
  txHashes: entry.transactionHash ? [entry.transactionHash] : [],
258
240
  chainId: entry.chainId,
259
241
  tokenSymbol: entry?.positions?.[0]?.token_symbol,
260
- amount: String(hexToDecimal(entry?.positions?.[0]?.amount || "0x"))
242
+ amount: String(
243
+ hexToDecimal(entry?.positions?.[0]?.amount || "0x")
244
+ )
261
245
  }
262
246
  ],
263
247
  rebalanceLog
@@ -483,7 +467,7 @@ var ZyfaiAgent = class {
483
467
  async getHistory(state, chainId, options) {
484
468
  const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
485
469
  const raw = await this.sdk.getHistory(smartWallet, validChainId, options);
486
- return mapHistory(raw);
470
+ return mapHistory(raw, validChainId);
487
471
  }
488
472
  // --- IAgent: Agent control ---
489
473
  async pause(state, chainId) {
@@ -514,691 +498,6 @@ var ZyfaiAgent = class {
514
498
  }
515
499
  };
516
500
 
517
- // src/agents/sail/sail.mapper.ts
518
- function mapDeposit2(raw) {
519
- return {
520
- txHash: raw.txHash,
521
- smartWallet: raw.smartWallet,
522
- amount: raw.amount
523
- };
524
- }
525
- function mapWithdraw2(raw) {
526
- return {
527
- txHash: raw.txHash,
528
- type: raw.type,
529
- amount: raw.amount
530
- };
531
- }
532
- function mapPortfolioBalances(raw, smartWallet) {
533
- let total = 0;
534
- const tokens = [];
535
- for (const item of raw.tokens) {
536
- total += item.balanceFormatted;
537
- tokens.push({
538
- chain: SUPPORTED_CHAINS[item.chain],
539
- chainId: item.chain,
540
- asset: item.symbol === "USD\u20AE0" ? "USDT" : item.symbol,
541
- amount: item.balance
542
- });
543
- }
544
- return {
545
- smartWallet,
546
- totalBalance: String(total),
547
- tokens
548
- };
549
- }
550
- function mapEarnings2(raw, smartWallet) {
551
- return {
552
- smartWallet,
553
- lifetimeEarnings: raw.result
554
- };
555
- }
556
- function mapApyHistory2(raw, walletAddress) {
557
- const apyPerAsset = remapApyPerAssetToSymbols(raw.result.apy_per_asset);
558
- return {
559
- walletAddress,
560
- weightedApyAfterFee: raw.result.apy,
561
- weightedApyAfterFeeDetails: apyPerAsset ? { apyPerAsset } : void 0
562
- };
563
- }
564
- function mapSailTransaction(tx) {
565
- switch (tx.type) {
566
- case "deposit":
567
- case "redeem":
568
- return {
569
- txHashes: tx.tx_hashes,
570
- chainId: tx.chain_id,
571
- tokenSymbol: tx.asset,
572
- amount: String(tx.amount)
573
- };
574
- case "swap":
575
- return {
576
- txHashes: tx.tx_hashes,
577
- chainId: tx.chain_id,
578
- tokenSymbol: tx.from_asset,
579
- amount: String(tx.amount)
580
- };
581
- case "bridge":
582
- return {
583
- txHashes: tx.tx_hashes,
584
- chainId: Number(tx.from_chain_id),
585
- tokenSymbol: tx.asset,
586
- amount: String(tx.amount)
587
- };
588
- }
589
- }
590
- function buildRebalanceLogs(transactions, failedTransactions) {
591
- const redeems = transactions.filter(
592
- (tx) => tx.type === "redeem"
593
- );
594
- const deposits = transactions.filter(
595
- (tx) => tx.type === "deposit"
596
- );
597
- const failedRedeems = failedTransactions.filter(
598
- (tx) => tx.type === "redeem"
599
- );
600
- const failedDeposits = failedTransactions.filter(
601
- (tx) => tx.type === "deposit"
602
- );
603
- const logs = [];
604
- const matchedDeposits = /* @__PURE__ */ new Set();
605
- const matchedRedeems = /* @__PURE__ */ new Set();
606
- for (let r = 0; r < redeems.length; r++) {
607
- const idx = deposits.findIndex(
608
- (d, i) => !matchedDeposits.has(i) && d.amount === redeems[r].amount
609
- );
610
- if (idx !== -1) {
611
- matchedDeposits.add(idx);
612
- matchedRedeems.add(r);
613
- logs.push({
614
- fromProtocol: redeems[r].protocol_name,
615
- toProtocol: deposits[idx].protocol_name,
616
- tokenSymbol: redeems[r].asset,
617
- amount: String(redeems[r].amount),
618
- status: "success"
619
- });
620
- }
621
- }
622
- for (let i = 0; i < deposits.length; i++) {
623
- if (matchedDeposits.has(i))
624
- continue;
625
- const failedRedeem = failedRedeems.find(
626
- (fr) => fr.amount === deposits[i].amount
627
- );
628
- logs.push({
629
- fromProtocol: failedRedeem ? failedRedeem.protocol_name : "Wallet",
630
- toProtocol: deposits[i].protocol_name,
631
- tokenSymbol: deposits[i].asset,
632
- amount: String(deposits[i].amount),
633
- status: failedRedeem ? "failed" : "success"
634
- });
635
- }
636
- for (let i = 0; i < redeems.length; i++) {
637
- if (matchedRedeems.has(i))
638
- continue;
639
- const failedDeposit = failedDeposits.find(
640
- (fd) => fd.amount === redeems[i].amount
641
- );
642
- logs.push({
643
- fromProtocol: redeems[i].protocol_name,
644
- toProtocol: failedDeposit ? failedDeposit.protocol_name : "Wallet",
645
- tokenSymbol: redeems[i].asset,
646
- amount: String(redeems[i].amount),
647
- status: failedDeposit ? "failed" : "success"
648
- });
649
- }
650
- return logs;
651
- }
652
- function mapHistory2(raw) {
653
- const actionMap = {
654
- execution: "Rebalance",
655
- deposit: "Top up",
656
- withdraw: "Withdraw",
657
- rewards: "Earned"
658
- };
659
- const filtered = raw.result.items.filter(
660
- (i) => !(i.type === "execution" && (i.status === "failed" || !i.transactions.length))
661
- );
662
- return {
663
- total: filtered.length,
664
- data: filtered.map((entry) => ({
665
- agent: "sail",
666
- action: actionMap[entry.type] ?? entry.type,
667
- date: entry.time,
668
- newApy: String(entry.new_apy),
669
- oldApy: String(entry.previous_apy),
670
- transactions: (entry.transactions ?? []).map(mapSailTransaction),
671
- rebalanceLog: buildRebalanceLogs(
672
- entry.transactions ?? [],
673
- entry.failed_transactions ?? []
674
- )
675
- }))
676
- };
677
- }
678
- function mapAgentStatus2(raw) {
679
- return {
680
- success: raw.success,
681
- strategy: raw.strategy,
682
- protocols: raw.protocols
683
- };
684
- }
685
- function mapUserProfile2(raw) {
686
- return {
687
- address: raw.result.smart_account,
688
- smartWallet: raw.result.smart_account,
689
- chains: [],
690
- hasActiveSessionKey: false,
691
- protocols: []
692
- };
693
- }
694
- function mapApyByStrategy2(raw) {
695
- const apyPerAsset = remapApyPerAssetToSymbols(raw.result.apy_per_asset);
696
- return {
697
- averageApy: raw.result.apy,
698
- detailedApys: apyPerAsset ? { apyPerAsset } : void 0
699
- };
700
- }
701
- function remapApyPerAssetToSymbols(raw) {
702
- if (!raw)
703
- return void 0;
704
- const remapped = {};
705
- for (const asset of SupportedAssets) {
706
- const chainKey = asset.chainId;
707
- const apyByAddress = raw[String(chainKey)];
708
- if (!apyByAddress)
709
- continue;
710
- const apy = apyByAddress[asset.address] ?? apyByAddress[asset.address.toLowerCase()];
711
- if (apy === void 0)
712
- continue;
713
- const bucket = remapped[chainKey] ?? {};
714
- bucket[asset.symbol] = apy;
715
- remapped[chainKey] = bucket;
716
- }
717
- return Object.keys(remapped).length > 0 ? remapped : void 0;
718
- }
719
-
720
- // src/agents/sail/sail.agent.ts
721
- var import_viem = require("viem");
722
- var SAIL_API_BASE = "https://app.sail.money";
723
- var PROJECT_ID = "sail";
724
- var PAGE_ID = "home";
725
- var SAIL_PORTFOLIO_TIMEOUT_MS = 8e3;
726
- var SailAgent = class {
727
- id = "sail";
728
- minDepositAmount = "4800000000";
729
- supportedChainIds = [8453, 42161];
730
- supportedAssets = [
731
- {
732
- chainId: 8453,
733
- chain: "BASE",
734
- assets: ["USDC"]
735
- },
736
- {
737
- chainId: 42161,
738
- chain: "ARBITRUM",
739
- assets: ["USDC", "USDT"]
740
- }
741
- ];
742
- apiKey;
743
- authToken = null;
744
- accountToken = null;
745
- connectedAddress = null;
746
- smartWalletAddress = null;
747
- connectedChainId = null;
748
- connectPromise = null;
749
- constructor(apiKey) {
750
- this.apiKey = apiKey;
751
- }
752
- // --- Private helpers ---
753
- async request(method, path, body, timeoutMs) {
754
- const headers = {
755
- "Content-Type": "application/json",
756
- "X-Business-API-Key": this.apiKey
757
- };
758
- if (this.authToken) {
759
- headers["Authorization"] = `Bearer ${this.authToken}`;
760
- }
761
- if (this.accountToken) {
762
- headers["X-Account-Token"] = this.accountToken;
763
- }
764
- const controller = new AbortController();
765
- const timeoutId = typeof timeoutMs === "number" && timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
766
- let res;
767
- try {
768
- res = await fetch(`${SAIL_API_BASE}${path}`, {
769
- method,
770
- headers,
771
- body: body ? JSON.stringify(body) : void 0,
772
- signal: controller.signal
773
- });
774
- } catch (error) {
775
- if (error instanceof Error && error.name === "AbortError" && timeoutMs) {
776
- throw new OwneyError(
777
- "API_SAIL_TIMEOUT",
778
- `Sail API timeout ${timeoutMs}ms: ${method} ${path}`,
779
- { timeoutMs, method, path },
780
- this.id
781
- );
782
- }
783
- throw error;
784
- } finally {
785
- if (timeoutId)
786
- clearTimeout(timeoutId);
787
- }
788
- if (!res.ok) {
789
- const text = await res.text().catch(() => "");
790
- throw new OwneyError(
791
- "API_SAIL_ERROR",
792
- `Sail API error ${res.status}: ${text}`,
793
- { statusCode: res.status, method, path, responseBody: text },
794
- this.id
795
- );
796
- }
797
- return res.json();
798
- }
799
- /** Initiate SIWE and sign with the user's wallet. */
800
- async signSiwe(state, chainId) {
801
- const initiate = await this.request(
802
- "POST",
803
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/auth/initiate`,
804
- {
805
- method: "siwe",
806
- address: state.walletAddress,
807
- chainId,
808
- identityMode: "byWallet"
809
- }
810
- );
811
- const signature = await state.provider.request({
812
- method: "personal_sign",
813
- params: [initiate.message, state.walletAddress]
814
- });
815
- return {
816
- sessionId: initiate.sessionId,
817
- message: initiate.message,
818
- signature
819
- };
820
- }
821
- /** Full connect: auth handles smart account creation via SIWE flow. */
822
- async connectFull(state, chainId) {
823
- if (this.connectedAddress && this.connectedChainId === chainId) {
824
- return;
825
- }
826
- if (this.connectPromise) {
827
- await this.connectPromise;
828
- return;
829
- }
830
- if (!state.walletAddress) {
831
- throw new OwneyError(
832
- "WALLET_ADDRESS_REQUIRED",
833
- "Wallet address is required. Call sdk.connect(provider) first.",
834
- void 0,
835
- this.id
836
- );
837
- }
838
- this.connectPromise = (async () => {
839
- const { sessionId, signature, message } = await this.signSiwe(
840
- state,
841
- chainId
842
- );
843
- const complete = await this.request(
844
- "POST",
845
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/auth/complete`,
846
- {
847
- method: "custom",
848
- sessionId,
849
- signature,
850
- walletAddress: state.walletAddress,
851
- identityMode: "byWallet"
852
- }
853
- );
854
- this.authToken = complete.token;
855
- this.accountToken = complete.accountToken;
856
- this.connectedAddress = state.walletAddress;
857
- this.smartWalletAddress = complete.walletAddress;
858
- this.connectedChainId = chainId;
859
- })();
860
- try {
861
- await this.connectPromise;
862
- } finally {
863
- this.connectPromise = null;
864
- }
865
- }
866
- async resolveSmartWallet(state, chainId) {
867
- await this.connectFull(state, chainId);
868
- const validChainId = isValidChainId(chainId);
869
- if (!this.smartWalletAddress) {
870
- throw new OwneyError(
871
- "NOT_CONNECTED",
872
- "Wallet not connected. Call sdk.connect() first.",
873
- void 0,
874
- this.id
875
- );
876
- }
877
- return {
878
- smartWallet: this.smartWalletAddress,
879
- chainId: validChainId
880
- };
881
- }
882
- // --- IAgent: Connection lifecycle ---
883
- async disconnect() {
884
- this.authToken = null;
885
- this.accountToken = null;
886
- this.connectedAddress = null;
887
- this.smartWalletAddress = null;
888
- this.connectedChainId = null;
889
- }
890
- // --- IAgent: Account lifecycle ---
891
- async activateAgent(state, chainId) {
892
- try {
893
- await this.connectFull(state, chainId);
894
- } catch (error) {
895
- await this.disconnect();
896
- throw error;
897
- }
898
- }
899
- async deposit(state, chainId, amount, depositCallback) {
900
- if (!depositCallback) {
901
- throw new OwneyError(
902
- "DEPOSIT_CALLBACK_REQUIRED",
903
- "depositCallback is required for Sail. Provide a callback that transfers tokens and returns the transaction hash.",
904
- void 0,
905
- this.id
906
- );
907
- }
908
- try {
909
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
910
- const depositInfo = await this.getDepositInfo();
911
- const resolvedTokenAddress = depositInfo.permittedTokens[0]?.address;
912
- if (!resolvedTokenAddress) {
913
- throw new OwneyError(
914
- "DEPOSIT_NO_PERMITTED_TOKENS",
915
- "No permitted tokens available for deposit.",
916
- void 0,
917
- this.id
918
- );
919
- }
920
- await this.executePreHooks(resolvedTokenAddress, amount, chainId);
921
- const txHash = await depositCallback(smartWallet, chainId, amount);
922
- if (!txHash) {
923
- throw new OwneyError(
924
- "DEPOSIT_CALLBACK_INVALID",
925
- "depositCallback must return a transaction hash (txHash) for Sail deposits.",
926
- void 0,
927
- this.id
928
- );
929
- }
930
- const postResult = await this.executePostHooks(
931
- resolvedTokenAddress,
932
- amount,
933
- chainId,
934
- txHash
935
- );
936
- return mapDeposit2({
937
- txHash: postResult.transactionHash,
938
- smartWallet,
939
- amount
940
- });
941
- } catch (error) {
942
- await this.disconnect();
943
- throw error;
944
- }
945
- }
946
- // --- Private deposit flow helpers ---
947
- async getDepositInfo() {
948
- return this.request(
949
- "GET",
950
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/deposit-info`
951
- );
952
- }
953
- async executePreHooks(tokenAddress, amount, chainId) {
954
- return this.request(
955
- "POST",
956
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/deposit/pre-hooks`,
957
- { tokenAddress, amount, chainId }
958
- );
959
- }
960
- async executePostHooks(tokenAddress, amount, chainId, txHash) {
961
- return this.request(
962
- "POST",
963
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/deposit/post-hooks`,
964
- { tokenAddress, amount, chainId, txHash }
965
- );
966
- }
967
- // --- Private withdraw flow helpers ---
968
- async getWithdrawInfo() {
969
- return this.request(
970
- "GET",
971
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/withdraw-info`
972
- );
973
- }
974
- // --- IAgent: Fund operations ---
975
- async withdraw(state, chainId, token, amount) {
976
- await this.connectFull(state, chainId);
977
- const withdrawInfo = await this.getWithdrawInfo();
978
- const selectedTokenAddress = SupportedAssets.find(
979
- (a) => a.symbol === token && a.chainId === chainId
980
- );
981
- if (!selectedTokenAddress) {
982
- throw new OwneyError(
983
- "WITHDRAW_NO_PERMITTED_TOKENS",
984
- "Unsupported asset.",
985
- void 0,
986
- this.id
987
- );
988
- }
989
- const tokenAddress = withdrawInfo.permittedTokens.find(
990
- (t) => t.address === selectedTokenAddress.address
991
- )?.address;
992
- if (!tokenAddress) {
993
- throw new OwneyError(
994
- "WITHDRAW_NO_PERMITTED_TOKENS",
995
- "No permitted tokens available for withdrawal.",
996
- void 0,
997
- this.id
998
- );
999
- }
1000
- const resolvedAmount = amount ?? withdrawInfo.currentBalance;
1001
- const { signature: adminWalletSignature, message: adminWalletPayload } = await this.signSiwe(state, chainId);
1002
- const payload = {
1003
- amount: String(resolvedAmount),
1004
- tokenAddress,
1005
- chainId,
1006
- adminWalletSignature,
1007
- adminWalletPayload
1008
- };
1009
- const raw = await this.request(
1010
- "POST",
1011
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/withdraw`,
1012
- payload
1013
- );
1014
- return mapWithdraw2({
1015
- txHash: raw.transactionHash,
1016
- type: amount ? "partial" : "full",
1017
- amount: (0, import_viem.parseUnits)(
1018
- resolvedAmount,
1019
- selectedTokenAddress.decimals
1020
- ).toString()
1021
- });
1022
- }
1023
- // --- IAgent: Portfolio reads ---
1024
- async getBalances(state, chainId) {
1025
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1026
- try {
1027
- const raw = await this.getPortfolio();
1028
- return mapPortfolioBalances(raw, smartWallet);
1029
- } catch (error) {
1030
- if (error instanceof OwneyError && error.code === "API_SAIL_TIMEOUT") {
1031
- console.warn(
1032
- "Sail portfolio request timed out; using empty snapshot.",
1033
- {
1034
- chainId
1035
- }
1036
- );
1037
- return mapPortfolioBalances(
1038
- { message: "timeout", tokens: [] },
1039
- smartWallet
1040
- );
1041
- }
1042
- throw error;
1043
- }
1044
- }
1045
- async getEarnings(state, chainId) {
1046
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1047
- const raw = await this.getMetricsEarnings(state, chainId);
1048
- return mapEarnings2(raw, smartWallet);
1049
- }
1050
- async getAccountApy(state, chainId, days) {
1051
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1052
- const raw = await this.getMetricsYield(days, state, chainId);
1053
- return mapApyHistory2(raw, smartWallet);
1054
- }
1055
- async getHistory(state, chainId, options) {
1056
- const raw = await this.getMetricsHistory(state, chainId, options);
1057
- return mapHistory2(raw);
1058
- }
1059
- // -- Sail-specific: Metrics ---
1060
- async getMetricsPortfolio(state, chainId) {
1061
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1062
- return this.request(
1063
- "GET",
1064
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/portfolio?${smartWallet ? `smart_account=${smartWallet}` : ""}`,
1065
- void 0,
1066
- SAIL_PORTFOLIO_TIMEOUT_MS
1067
- );
1068
- }
1069
- async getPortfolio() {
1070
- return this.request(
1071
- "GET",
1072
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/portfolio/tokens`,
1073
- void 0,
1074
- SAIL_PORTFOLIO_TIMEOUT_MS
1075
- );
1076
- }
1077
- async getMetricsEarnings(state, chainId) {
1078
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1079
- return this.request(
1080
- "GET",
1081
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/earnings?smart_account=${smartWallet}`
1082
- );
1083
- }
1084
- async getMetricsBalance(state, chainId, currency = "usd") {
1085
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1086
- return this.request(
1087
- "GET",
1088
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/balance?smart_account=${smartWallet}&currency=${currency}&limit=1000`
1089
- );
1090
- }
1091
- async getMetricsHistory(state, chainId, filters) {
1092
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1093
- const params = new URLSearchParams();
1094
- params.set("smart_account", smartWallet);
1095
- if (filters?.fromDate) {
1096
- params.set("start_date", filters.fromDate);
1097
- }
1098
- if (filters?.toDate) {
1099
- params.set("end_date", filters.toDate);
1100
- }
1101
- return this.request(
1102
- "GET",
1103
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/history?${params.toString()}`
1104
- );
1105
- }
1106
- async getMetricsUser(state, chainId, currency) {
1107
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1108
- return this.request(
1109
- "GET",
1110
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/user-metrics?smart_account=${smartWallet}&currency=${currency}`
1111
- );
1112
- }
1113
- async getMetricsYield(days, state, chainId) {
1114
- let walletAddress = "";
1115
- if (state && chainId) {
1116
- const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1117
- walletAddress = smartWallet;
1118
- }
1119
- const dayCount = DayFilterMapping[days];
1120
- if (dayCount === void 0) {
1121
- throw new OwneyError(
1122
- "VALIDATION_INVALID_DAYS",
1123
- `Invalid days value: "${days}". Expected one of: "7D", "14D", "30D".`,
1124
- { days },
1125
- this.id
1126
- );
1127
- }
1128
- const now = /* @__PURE__ */ new Date();
1129
- const end = now.toISOString().split("T")[0];
1130
- const start = new Date(now.getTime() - dayCount * 864e5).toISOString().split("T")[0];
1131
- return this.request(
1132
- "GET",
1133
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/yield?start=${start}&end=${end}${walletAddress ? `&smart_account=${walletAddress}` : ""}`
1134
- );
1135
- }
1136
- // --- Sail-specific: Automation jobs ---
1137
- async getAutomationStatus(state, chainId) {
1138
- await this.connectFull(state, chainId);
1139
- return this.request(
1140
- "GET",
1141
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/automation/status`
1142
- );
1143
- }
1144
- async startAutomation(state, chainId, graphId, prompt, options) {
1145
- await this.connectFull(state, chainId);
1146
- return this.request(
1147
- "POST",
1148
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/automation/start`,
1149
- {
1150
- graphId,
1151
- prompt,
1152
- paramValues: options?.paramValues ?? {},
1153
- iterations: options?.iterations ?? 1,
1154
- branchId: options?.branchId
1155
- }
1156
- );
1157
- }
1158
- async pauseAutomation(state, chainId) {
1159
- await this.connectFull(state, chainId);
1160
- return this.request(
1161
- "POST",
1162
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/automation/pause`
1163
- );
1164
- }
1165
- async resumeAutomation(state, chainId) {
1166
- await this.connectFull(state, chainId);
1167
- return this.request(
1168
- "POST",
1169
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/automation/resume`
1170
- );
1171
- }
1172
- async stopAutomation(state, chainId) {
1173
- await this.connectFull(state, chainId);
1174
- return this.request(
1175
- "POST",
1176
- `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/automation/stop`
1177
- );
1178
- }
1179
- // --- IAgent: Agent control ---
1180
- async pause(state, chainId) {
1181
- await this.connectFull(state, chainId);
1182
- await this.pauseAutomation(state, chainId);
1183
- return mapAgentStatus2({ success: true });
1184
- }
1185
- async resume(state, chainId) {
1186
- await this.connectFull(state, chainId);
1187
- await this.resumeAutomation(state, chainId);
1188
- return mapAgentStatus2({ success: true });
1189
- }
1190
- async getUserProfile(state, chainId) {
1191
- await this.connectFull(state, chainId);
1192
- const raw = await this.getMetricsUser(state, chainId, "usd");
1193
- return mapUserProfile2(raw);
1194
- }
1195
- // --- IAgent: Discovery (no wallet required) ---
1196
- async getAgentApy(days, _options) {
1197
- const raw = await this.getMetricsYield(days);
1198
- return mapApyByStrategy2(raw);
1199
- }
1200
- };
1201
-
1202
501
  // src/lib/routing-api.ts
1203
502
  var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
1204
503
  async function fetchAgentKeys(apiKey) {
@@ -1287,7 +586,7 @@ function sumWithdrawnAmount(results) {
1287
586
  }
1288
587
 
1289
588
  // src/client.ts
1290
- var import_viem2 = require("viem");
589
+ var import_viem = require("viem");
1291
590
  var OwneySDK = class {
1292
591
  agents = /* @__PURE__ */ new Map();
1293
592
  activeAgents = /* @__PURE__ */ new Set();
@@ -1404,9 +703,6 @@ var OwneySDK = class {
1404
703
  if (agentId === "zyfai") {
1405
704
  return new ZyfaiAgent(key, this.zyfaiRpcUrls);
1406
705
  }
1407
- if (agentId === "sail") {
1408
- return new SailAgent(key);
1409
- }
1410
706
  return null;
1411
707
  }
1412
708
  // --- Account lifecycle ---
@@ -1630,7 +926,7 @@ var OwneySDK = class {
1630
926
  );
1631
927
  if (!tokenBalance)
1632
928
  return { agent, balance: 0n };
1633
- const balance = (0, import_viem2.parseUnits)(tokenBalance.amount, assetInfo.decimals);
929
+ const balance = (0, import_viem.parseUnits)(tokenBalance.amount, assetInfo.decimals);
1634
930
  return { agent, balance };
1635
931
  });
1636
932
  const totalAvailable = balances.reduce((sum, x) => sum + x.balance, 0n);
@@ -1657,7 +953,7 @@ var OwneySDK = class {
1657
953
  state,
1658
954
  chainId,
1659
955
  token,
1660
- p.agent.id === "sail" ? (0, import_viem2.formatUnits)(p.planned, assetInfo.decimals) : p.planned.toString()
956
+ p.planned.toString()
1661
957
  );
1662
958
  } catch (err) {
1663
959
  console.error(`withdraw failed for agent "${p.agent.id}":`, err);
@@ -1919,7 +1215,7 @@ var OwneySDK = class {
1919
1215
  * @param options.days - Lookback period: "7D", "14D", or "30D"
1920
1216
  * @param options.tokenSymbol - Optional asset symbol ("USDC" / "WETH") to
1921
1217
  * scope the APY to a specific asset+chain. Agents whose backends do not
1922
- * support per-asset APY (currently Sail) ignore this.
1218
+ * support per-asset APY ignore this.
1923
1219
  * @param options.chainId - Optional chain id for per-asset APY lookups.
1924
1220
  * Typically paired with `tokenSymbol`.
1925
1221
  * @returns {AgentApy} for a single agent, or {OwneyAgentApy} with per-agent APY