@owney/sdk 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -5
- package/dist/index.cjs +4 -692
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -692
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -514,691 +514,6 @@ var ZyfaiAgent = class {
|
|
|
514
514
|
}
|
|
515
515
|
};
|
|
516
516
|
|
|
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}¤cy=${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}¤cy=${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
517
|
// src/lib/routing-api.ts
|
|
1203
518
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1204
519
|
async function fetchAgentKeys(apiKey) {
|
|
@@ -1287,7 +602,7 @@ function sumWithdrawnAmount(results) {
|
|
|
1287
602
|
}
|
|
1288
603
|
|
|
1289
604
|
// src/client.ts
|
|
1290
|
-
var
|
|
605
|
+
var import_viem = require("viem");
|
|
1291
606
|
var OwneySDK = class {
|
|
1292
607
|
agents = /* @__PURE__ */ new Map();
|
|
1293
608
|
activeAgents = /* @__PURE__ */ new Set();
|
|
@@ -1404,9 +719,6 @@ var OwneySDK = class {
|
|
|
1404
719
|
if (agentId === "zyfai") {
|
|
1405
720
|
return new ZyfaiAgent(key, this.zyfaiRpcUrls);
|
|
1406
721
|
}
|
|
1407
|
-
if (agentId === "sail") {
|
|
1408
|
-
return new SailAgent(key);
|
|
1409
|
-
}
|
|
1410
722
|
return null;
|
|
1411
723
|
}
|
|
1412
724
|
// --- Account lifecycle ---
|
|
@@ -1630,7 +942,7 @@ var OwneySDK = class {
|
|
|
1630
942
|
);
|
|
1631
943
|
if (!tokenBalance)
|
|
1632
944
|
return { agent, balance: 0n };
|
|
1633
|
-
const balance = (0,
|
|
945
|
+
const balance = (0, import_viem.parseUnits)(tokenBalance.amount, assetInfo.decimals);
|
|
1634
946
|
return { agent, balance };
|
|
1635
947
|
});
|
|
1636
948
|
const totalAvailable = balances.reduce((sum, x) => sum + x.balance, 0n);
|
|
@@ -1657,7 +969,7 @@ var OwneySDK = class {
|
|
|
1657
969
|
state,
|
|
1658
970
|
chainId,
|
|
1659
971
|
token,
|
|
1660
|
-
p.
|
|
972
|
+
p.planned.toString()
|
|
1661
973
|
);
|
|
1662
974
|
} catch (err) {
|
|
1663
975
|
console.error(`withdraw failed for agent "${p.agent.id}":`, err);
|
|
@@ -1919,7 +1231,7 @@ var OwneySDK = class {
|
|
|
1919
1231
|
* @param options.days - Lookback period: "7D", "14D", or "30D"
|
|
1920
1232
|
* @param options.tokenSymbol - Optional asset symbol ("USDC" / "WETH") to
|
|
1921
1233
|
* scope the APY to a specific asset+chain. Agents whose backends do not
|
|
1922
|
-
* support per-asset APY
|
|
1234
|
+
* support per-asset APY ignore this.
|
|
1923
1235
|
* @param options.chainId - Optional chain id for per-asset APY lookups.
|
|
1924
1236
|
* Typically paired with `tokenSymbol`.
|
|
1925
1237
|
* @returns {AgentApy} for a single agent, or {OwneyAgentApy} with per-agent APY
|