@owney/sdk 0.7.22-beta.3 → 0.7.22-beta.5
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/{chunk-5W56YOBO.js → chunk-T5YJVIQG.js} +2 -2
- package/dist/index.cjs +104 -53
- package/dist/index.js +1 -1
- package/dist/{surfliquid.agent-BFBNEQQI.js → surfliquid.agent-YC4VDPPF.js} +63 -29
- package/dist/{surfliquid.smart-account-O6YPCQT3.js → surfliquid.smart-account-YV3PLZ72.js} +21 -6
- package/package.json +1 -1
|
@@ -138,7 +138,7 @@ var VaultNotSponsorableError = class extends Error {
|
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
async function resolveVault(ctx) {
|
|
141
|
-
const registered = await ctx.api.getVault(ctx.wallet.
|
|
141
|
+
const registered = await ctx.api.getVault(ctx.wallet.smartAccountAddress);
|
|
142
142
|
const smartAccount = ctx.wallet.smartAccountAddress;
|
|
143
143
|
if (!registered.userVaultAddress) {
|
|
144
144
|
const salt2 = registered.deploymentSalt ?? (await ctx.api.prepare(SURFLIQUID_CHAIN_ID)).salt;
|
|
@@ -253,7 +253,7 @@ async function depositSponsored(input) {
|
|
|
253
253
|
}
|
|
254
254
|
async function withdrawSponsored(input) {
|
|
255
255
|
const { api, chain, wallet, amount } = input;
|
|
256
|
-
const registered = await api.getVault(wallet.
|
|
256
|
+
const registered = await api.getVault(wallet.smartAccountAddress);
|
|
257
257
|
if (!registered.userVaultAddress) {
|
|
258
258
|
throw new Error("SurfLiquid has no vault registered for this wallet");
|
|
259
259
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -388,7 +388,7 @@ function normalizeSupportedAssets(json, chainId) {
|
|
|
388
388
|
function createSurfBroker(options) {
|
|
389
389
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
390
390
|
const now = options.now ?? Date.now;
|
|
391
|
-
const
|
|
391
|
+
const base4 = `${options.routingApiBaseUrl.replace(/\/$/, "")}/api/v1/surf`;
|
|
392
392
|
const wallet = options.walletAddress;
|
|
393
393
|
let session = readSurfSession(options.apiKey, wallet);
|
|
394
394
|
const vaultMemo = /* @__PURE__ */ new Map();
|
|
@@ -407,7 +407,7 @@ function createSurfBroker(options) {
|
|
|
407
407
|
if (options.origin) headers["origin"] = options.origin;
|
|
408
408
|
let response;
|
|
409
409
|
try {
|
|
410
|
-
response = await fetchImpl(`${
|
|
410
|
+
response = await fetchImpl(`${base4}${path}`, {
|
|
411
411
|
method,
|
|
412
412
|
headers,
|
|
413
413
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -501,7 +501,7 @@ function createSurfBroker(options) {
|
|
|
501
501
|
)
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
|
-
var SURF_SESSION_HEADER, SURF_BROKER_TIMEOUT_MS, VAULT_MEMO_TTL_MS, AGENT_ID, DISCOVERY_WALLET, SurfSessionExpiredError, asRecord, unavailable;
|
|
504
|
+
var SURF_SESSION_HEADER, SURF_BROKER_TIMEOUT_MS, VAULT_MEMO_TTL_MS, AGENT_ID, DISCOVERY_WALLET, SurfSessionExpiredError, asRecord, unavailable, emptyVaultInfo;
|
|
505
505
|
var init_surfliquid_broker = __esm({
|
|
506
506
|
"src/agents/surfliquid/surfliquid.broker.ts"() {
|
|
507
507
|
"use strict";
|
|
@@ -520,6 +520,7 @@ var init_surfliquid_broker = __esm({
|
|
|
520
520
|
};
|
|
521
521
|
asRecord = (value) => value && typeof value === "object" ? value : {};
|
|
522
522
|
unavailable = (message, details) => new OwneyError("SURF_UNAVAILABLE", message, details, AGENT_ID);
|
|
523
|
+
emptyVaultInfo = () => normalizeVault(void 0);
|
|
523
524
|
}
|
|
524
525
|
});
|
|
525
526
|
|
|
@@ -527,7 +528,7 @@ var init_surfliquid_broker = __esm({
|
|
|
527
528
|
function mapMessage(message) {
|
|
528
529
|
const action = SURFLIQUID_ACTION_MAP[message.transactionType];
|
|
529
530
|
if (!action) return [];
|
|
530
|
-
const
|
|
531
|
+
const base4 = {
|
|
531
532
|
agent: "surfliquid",
|
|
532
533
|
action,
|
|
533
534
|
date: message.timestamp,
|
|
@@ -545,9 +546,9 @@ function mapMessage(message) {
|
|
|
545
546
|
};
|
|
546
547
|
if (DEPOSIT_TRANSACTION_TYPES.has(message.transactionType) && message.toVault?.name && message.amount != null) {
|
|
547
548
|
return [
|
|
548
|
-
|
|
549
|
+
base4,
|
|
549
550
|
{
|
|
550
|
-
...
|
|
551
|
+
...base4,
|
|
551
552
|
action: "Deposit",
|
|
552
553
|
positions: [
|
|
553
554
|
{
|
|
@@ -560,10 +561,20 @@ function mapMessage(message) {
|
|
|
560
561
|
}
|
|
561
562
|
];
|
|
562
563
|
}
|
|
563
|
-
return [
|
|
564
|
+
return [base4];
|
|
565
|
+
}
|
|
566
|
+
function dedupeMessages(messages) {
|
|
567
|
+
const seen = /* @__PURE__ */ new Set();
|
|
568
|
+
return messages.filter((message) => {
|
|
569
|
+
if (!message.txHash) return true;
|
|
570
|
+
const key2 = `${message.transactionType}:${message.txHash}`;
|
|
571
|
+
if (seen.has(key2)) return false;
|
|
572
|
+
seen.add(key2);
|
|
573
|
+
return true;
|
|
574
|
+
});
|
|
564
575
|
}
|
|
565
576
|
function mapHistory(result, _chainId) {
|
|
566
|
-
const data = result.messages.flatMap(mapMessage);
|
|
577
|
+
const data = dedupeMessages(result.messages).flatMap(mapMessage);
|
|
567
578
|
const hasMore = result.page < result.pages;
|
|
568
579
|
return {
|
|
569
580
|
data,
|
|
@@ -760,7 +771,7 @@ var init_surfliquid_calls = __esm({
|
|
|
760
771
|
|
|
761
772
|
// src/agents/surfliquid/surfliquid.sponsorship.ts
|
|
762
773
|
async function resolveVault(ctx) {
|
|
763
|
-
const registered = await ctx.api.getVault(ctx.wallet.
|
|
774
|
+
const registered = await ctx.api.getVault(ctx.wallet.smartAccountAddress);
|
|
764
775
|
const smartAccount = ctx.wallet.smartAccountAddress;
|
|
765
776
|
if (!registered.userVaultAddress) {
|
|
766
777
|
const salt2 = registered.deploymentSalt ?? (await ctx.api.prepare(SURFLIQUID_CHAIN_ID)).salt;
|
|
@@ -875,7 +886,7 @@ async function depositSponsored(input) {
|
|
|
875
886
|
}
|
|
876
887
|
async function withdrawSponsored(input) {
|
|
877
888
|
const { api, chain, wallet, amount } = input;
|
|
878
|
-
const registered = await api.getVault(wallet.
|
|
889
|
+
const registered = await api.getVault(wallet.smartAccountAddress);
|
|
879
890
|
if (!registered.userVaultAddress) {
|
|
880
891
|
throw new Error("SurfLiquid has no vault registered for this wallet");
|
|
881
892
|
}
|
|
@@ -1077,10 +1088,11 @@ function pinAccount(provider, address) {
|
|
|
1077
1088
|
};
|
|
1078
1089
|
}
|
|
1079
1090
|
async function createSponsoredWallet(input) {
|
|
1080
|
-
const entryPoint = { address: import_account_abstraction.
|
|
1081
|
-
const account = await (0, import_accounts.
|
|
1091
|
+
const entryPoint = { address: import_account_abstraction.entryPoint07Address, version: "0.7" };
|
|
1092
|
+
const account = await (0, import_accounts.toSafeSmartAccount)({
|
|
1082
1093
|
client: publicClientFor(input.rpcUrl),
|
|
1083
|
-
|
|
1094
|
+
owners: [pinAccount(input.provider, input.ownerAddress)],
|
|
1095
|
+
version: "1.4.1",
|
|
1084
1096
|
entryPoint
|
|
1085
1097
|
});
|
|
1086
1098
|
const bundlerTransport = (0, import_viem9.http)(sponsorProxyUrl(input.routingApiBaseUrl), {
|
|
@@ -1112,6 +1124,20 @@ async function createSponsoredWallet(input) {
|
|
|
1112
1124
|
primaryType: typedData.primaryType,
|
|
1113
1125
|
message: typedData.message
|
|
1114
1126
|
}),
|
|
1127
|
+
// The smart account signs (ERC-1271), not the EOA: SurfLiquid's SIWE session must
|
|
1128
|
+
// be the vault owner, which is the smart account. Safe wraps this as a SafeMessage
|
|
1129
|
+
// EIP-712 signature the deployed account verifies via isValidSignature.
|
|
1130
|
+
signMessage: (message) => account.signMessage({ message }),
|
|
1131
|
+
// Deploy-on-connect: the account is counterfactual until its first userOp, but SIWE
|
|
1132
|
+
// (isValidSignature) needs on-chain code. A no-op self-call carries the factory
|
|
1133
|
+
// initCode and deploys it. Idempotency is the caller's (it checks isDeployed first).
|
|
1134
|
+
deployAccount: async () => {
|
|
1135
|
+
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
1136
|
+
calls: [{ to: account.address, value: 0n, data: "0x" }]
|
|
1137
|
+
});
|
|
1138
|
+
const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash: userOpHash });
|
|
1139
|
+
return receipt.receipt.transactionHash;
|
|
1140
|
+
},
|
|
1115
1141
|
sendCalls: async (calls) => {
|
|
1116
1142
|
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
1117
1143
|
calls: calls.map((c) => ({ to: c.to, data: c.data, value: 0n }))
|
|
@@ -1166,12 +1192,10 @@ function toOwneyError(error) {
|
|
|
1166
1192
|
}
|
|
1167
1193
|
return new OwneyError("SPONSORSHIP_UNAVAILABLE", message, void 0, AGENT_ID2);
|
|
1168
1194
|
}
|
|
1169
|
-
var
|
|
1195
|
+
var AGENT_ID2, WALLET_REJECTED_CODE, DISCOVERY_WALLET2, HISTORY_DEFAULT_LIMIT, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
1170
1196
|
var init_surfliquid_agent = __esm({
|
|
1171
1197
|
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
1172
1198
|
"use strict";
|
|
1173
|
-
import_viem10 = require("viem");
|
|
1174
|
-
import_chains3 = require("viem/chains");
|
|
1175
1199
|
init_errors();
|
|
1176
1200
|
init_surfliquid_constants();
|
|
1177
1201
|
init_surfliquid_broker();
|
|
@@ -1198,6 +1222,9 @@ var init_surfliquid_agent = __esm({
|
|
|
1198
1222
|
supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
|
|
1199
1223
|
broker = null;
|
|
1200
1224
|
brokerWallet = null;
|
|
1225
|
+
// The SurfLiquid session and every keyed read run on the smart account (the vault
|
|
1226
|
+
// owner), not the EOA — set by connect(), consumed by the reads below.
|
|
1227
|
+
smartAccountAddress = null;
|
|
1201
1228
|
// Dedicated instance for the anonymous "0x" asset probe — never shares a slot
|
|
1202
1229
|
// with the user's broker, so discovery can never evict or overwrite a session.
|
|
1203
1230
|
discoveryBroker = null;
|
|
@@ -1219,17 +1246,22 @@ var init_surfliquid_agent = __esm({
|
|
|
1219
1246
|
return this.broker;
|
|
1220
1247
|
}
|
|
1221
1248
|
async connect(state, shouldForce = false) {
|
|
1222
|
-
|
|
1223
|
-
|
|
1249
|
+
if (!shouldForce && this.broker && this.smartAccountAddress && this.broker.hasSession()) {
|
|
1250
|
+
return this.broker;
|
|
1251
|
+
}
|
|
1224
1252
|
if (this.connectPromise) return this.connectPromise;
|
|
1225
1253
|
this.connectPromise = (async () => {
|
|
1254
|
+
const wallet = await this.sponsoredWallet(state);
|
|
1255
|
+
const smartAccountAddress = wallet.smartAccountAddress;
|
|
1256
|
+
this.smartAccountAddress = smartAccountAddress;
|
|
1257
|
+
const broker = this.brokerFor(smartAccountAddress);
|
|
1258
|
+
if (!shouldForce && broker.hasSession()) return broker;
|
|
1259
|
+
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1260
|
+
if (!await createSponsoredChain2(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
|
|
1261
|
+
await wallet.deployAccount();
|
|
1262
|
+
}
|
|
1226
1263
|
const message = await broker.nonce();
|
|
1227
|
-
const
|
|
1228
|
-
account: state.walletAddress,
|
|
1229
|
-
chain: import_chains3.base,
|
|
1230
|
-
transport: (0, import_viem10.custom)(state.provider)
|
|
1231
|
-
});
|
|
1232
|
-
const signature = await walletClient.signMessage({ account: state.walletAddress, message });
|
|
1264
|
+
const signature = await wallet.signMessage(message);
|
|
1233
1265
|
await broker.login(message, signature);
|
|
1234
1266
|
return broker;
|
|
1235
1267
|
})();
|
|
@@ -1239,6 +1271,10 @@ var init_surfliquid_agent = __esm({
|
|
|
1239
1271
|
this.connectPromise = null;
|
|
1240
1272
|
}
|
|
1241
1273
|
}
|
|
1274
|
+
/** The SurfLiquid-facing wallet address: the smart account once connected, else the EOA. */
|
|
1275
|
+
surfWallet(state) {
|
|
1276
|
+
return this.smartAccountAddress ?? state.walletAddress;
|
|
1277
|
+
}
|
|
1242
1278
|
/** A 401 can only surface before any signature (SurfLiquid is never called between sign and submit). */
|
|
1243
1279
|
async withSession(state, run) {
|
|
1244
1280
|
try {
|
|
@@ -1269,9 +1305,22 @@ var init_surfliquid_agent = __esm({
|
|
|
1269
1305
|
this.broker?.clearSession();
|
|
1270
1306
|
this.broker = null;
|
|
1271
1307
|
this.brokerWallet = null;
|
|
1308
|
+
this.smartAccountAddress = null;
|
|
1272
1309
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1310
|
+
// The SDK orchestrator already marks the agent active and sets the chain. SurfLiquid
|
|
1311
|
+
// establishes its session lazily — on the first read of a deployed account, or on
|
|
1312
|
+
// deposit — so merely connecting a wallet never prompts for a signature.
|
|
1313
|
+
async activateAgent(_state, _chainId) {
|
|
1314
|
+
}
|
|
1315
|
+
/** A counterfactual account owns no vault and can't be a SIWE signer yet — reads answer empty. */
|
|
1316
|
+
async isSmartAccountDeployed(state) {
|
|
1317
|
+
if (this.broker?.hasSession()) return true;
|
|
1318
|
+
const wallet = await this.sponsoredWallet(state);
|
|
1319
|
+
this.smartAccountAddress = wallet.smartAccountAddress;
|
|
1320
|
+
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1321
|
+
return createSponsoredChain2(this.config.rpcUrl).isDeployed(
|
|
1322
|
+
wallet.smartAccountAddress
|
|
1323
|
+
);
|
|
1275
1324
|
}
|
|
1276
1325
|
// --- IAgent: funds (gasless only) ---
|
|
1277
1326
|
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
@@ -1329,8 +1378,9 @@ var init_surfliquid_agent = __esm({
|
|
|
1329
1378
|
}
|
|
1330
1379
|
// --- IAgent: portfolio reads ---
|
|
1331
1380
|
async vault(state) {
|
|
1381
|
+
if (!await this.isSmartAccountDeployed(state)) return emptyVaultInfo();
|
|
1332
1382
|
const broker = await this.connect(state);
|
|
1333
|
-
return this.withSession(state, () => broker.getVault(state
|
|
1383
|
+
return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
|
|
1334
1384
|
}
|
|
1335
1385
|
async getBalances(state, chainId) {
|
|
1336
1386
|
const vault = await this.vault(state);
|
|
@@ -1346,12 +1396,13 @@ var init_surfliquid_agent = __esm({
|
|
|
1346
1396
|
return mapAccountApy(await this.vault(state), days);
|
|
1347
1397
|
}
|
|
1348
1398
|
async getHistory(state, chainId, options) {
|
|
1399
|
+
if (!await this.isSmartAccountDeployed(state)) return { data: [], hasMore: false };
|
|
1349
1400
|
const broker = await this.connect(state);
|
|
1350
1401
|
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
1351
1402
|
const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
|
|
1352
1403
|
const result = await this.withSession(
|
|
1353
1404
|
state,
|
|
1354
|
-
() => broker.getAgentMessages(state
|
|
1405
|
+
() => broker.getAgentMessages(this.surfWallet(state), page, limit, options?.fromDate, options?.toDate)
|
|
1355
1406
|
);
|
|
1356
1407
|
return mapHistory(result, chainId);
|
|
1357
1408
|
}
|
|
@@ -3590,8 +3641,8 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
3590
3641
|
}
|
|
3591
3642
|
|
|
3592
3643
|
// src/client.ts
|
|
3593
|
-
var
|
|
3594
|
-
var
|
|
3644
|
+
var import_viem10 = require("viem");
|
|
3645
|
+
var import_chains3 = require("viem/chains");
|
|
3595
3646
|
|
|
3596
3647
|
// src/lib/sponsored-deposit.ts
|
|
3597
3648
|
init_errors();
|
|
@@ -3601,10 +3652,10 @@ init_transfer_auth();
|
|
|
3601
3652
|
init_errors();
|
|
3602
3653
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
3603
3654
|
async function postSponsorTransferAuth(input) {
|
|
3604
|
-
const
|
|
3655
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
3605
3656
|
let res;
|
|
3606
3657
|
try {
|
|
3607
|
-
res = await fetch(`${
|
|
3658
|
+
res = await fetch(`${base4}/api/v1/sponsor/erc20-transfer-auth`, {
|
|
3608
3659
|
method: "POST",
|
|
3609
3660
|
headers: {
|
|
3610
3661
|
"content-type": "application/json",
|
|
@@ -3641,10 +3692,10 @@ async function postSponsorTransferAuth(input) {
|
|
|
3641
3692
|
return parsed.data;
|
|
3642
3693
|
}
|
|
3643
3694
|
async function postSponsorPermit2Transfer(input) {
|
|
3644
|
-
const
|
|
3695
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
3645
3696
|
let res;
|
|
3646
3697
|
try {
|
|
3647
|
-
res = await fetch(`${
|
|
3698
|
+
res = await fetch(`${base4}/api/v1/sponsor/permit2-transfer`, {
|
|
3648
3699
|
method: "POST",
|
|
3649
3700
|
headers: {
|
|
3650
3701
|
"content-type": "application/json",
|
|
@@ -3679,11 +3730,11 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
3679
3730
|
return parsed.data;
|
|
3680
3731
|
}
|
|
3681
3732
|
async function getSponsorRelayerAddress(input) {
|
|
3682
|
-
const
|
|
3733
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
3683
3734
|
let res;
|
|
3684
3735
|
try {
|
|
3685
3736
|
res = await fetch(
|
|
3686
|
-
`${
|
|
3737
|
+
`${base4}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
3687
3738
|
{
|
|
3688
3739
|
headers: { "x-owney-api-key": input.apiKey }
|
|
3689
3740
|
}
|
|
@@ -4110,9 +4161,9 @@ var SPONSORED_USDC_BY_CHAIN = {
|
|
|
4110
4161
|
1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
4111
4162
|
};
|
|
4112
4163
|
var VIEM_CHAIN2 = {
|
|
4113
|
-
8453:
|
|
4114
|
-
42161:
|
|
4115
|
-
1:
|
|
4164
|
+
8453: import_chains3.base,
|
|
4165
|
+
42161: import_chains3.arbitrum,
|
|
4166
|
+
1: import_chains3.mainnet
|
|
4116
4167
|
};
|
|
4117
4168
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
4118
4169
|
8453: "0x4200000000000000000000000000000000000006",
|
|
@@ -4269,14 +4320,14 @@ var OwneySDK = class {
|
|
|
4269
4320
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4270
4321
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4271
4322
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4272
|
-
getPublicClient: (cid) => (0,
|
|
4323
|
+
getPublicClient: (cid) => (0, import_viem10.createPublicClient)({
|
|
4273
4324
|
chain: VIEM_CHAIN2[cid],
|
|
4274
|
-
transport: (0,
|
|
4325
|
+
transport: (0, import_viem10.custom)(provider)
|
|
4275
4326
|
}),
|
|
4276
|
-
getWalletClient: (cid) => (0,
|
|
4327
|
+
getWalletClient: (cid) => (0, import_viem10.createWalletClient)({
|
|
4277
4328
|
account: owner,
|
|
4278
4329
|
chain: VIEM_CHAIN2[cid],
|
|
4279
|
-
transport: (0,
|
|
4330
|
+
transport: (0, import_viem10.custom)(provider)
|
|
4280
4331
|
})
|
|
4281
4332
|
});
|
|
4282
4333
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -4322,14 +4373,14 @@ var OwneySDK = class {
|
|
|
4322
4373
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4323
4374
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4324
4375
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4325
|
-
getPublicClient: (cid) => (0,
|
|
4376
|
+
getPublicClient: (cid) => (0, import_viem10.createPublicClient)({
|
|
4326
4377
|
chain: VIEM_CHAIN2[cid],
|
|
4327
|
-
transport: (0,
|
|
4378
|
+
transport: (0, import_viem10.custom)(provider)
|
|
4328
4379
|
}),
|
|
4329
|
-
getWalletClient: (cid) => (0,
|
|
4380
|
+
getWalletClient: (cid) => (0, import_viem10.createWalletClient)({
|
|
4330
4381
|
account: owner,
|
|
4331
4382
|
chain: VIEM_CHAIN2[cid],
|
|
4332
|
-
transport: (0,
|
|
4383
|
+
transport: (0, import_viem10.custom)(provider)
|
|
4333
4384
|
})
|
|
4334
4385
|
});
|
|
4335
4386
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -5448,10 +5499,10 @@ var OwneySDK = class {
|
|
|
5448
5499
|
);
|
|
5449
5500
|
}
|
|
5450
5501
|
const provider = this.requireConnectedProvider();
|
|
5451
|
-
const wallet = (0,
|
|
5502
|
+
const wallet = (0, import_viem10.createWalletClient)({
|
|
5452
5503
|
account: state.walletAddress,
|
|
5453
5504
|
chain: VIEM_CHAIN2[chainId],
|
|
5454
|
-
transport: (0,
|
|
5505
|
+
transport: (0, import_viem10.custom)(provider)
|
|
5455
5506
|
});
|
|
5456
5507
|
const hash = await wallet.writeContract({
|
|
5457
5508
|
address: token,
|
|
@@ -5461,9 +5512,9 @@ var OwneySDK = class {
|
|
|
5461
5512
|
account: state.walletAddress,
|
|
5462
5513
|
chain: VIEM_CHAIN2[chainId]
|
|
5463
5514
|
});
|
|
5464
|
-
const publicClient = (0,
|
|
5515
|
+
const publicClient = (0, import_viem10.createPublicClient)({
|
|
5465
5516
|
chain: VIEM_CHAIN2[chainId],
|
|
5466
|
-
transport: (0,
|
|
5517
|
+
transport: (0, import_viem10.custom)(provider)
|
|
5467
5518
|
});
|
|
5468
5519
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
5469
5520
|
hash,
|
|
@@ -5579,7 +5630,7 @@ init_errors();
|
|
|
5579
5630
|
init_debug();
|
|
5580
5631
|
|
|
5581
5632
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
5582
|
-
var
|
|
5633
|
+
var import_viem11 = require("viem");
|
|
5583
5634
|
var import_siwe = require("siwe");
|
|
5584
5635
|
var import_sdk2 = require("@zyfai/sdk");
|
|
5585
5636
|
|
|
@@ -5706,7 +5757,7 @@ function buildSIWXConfig(deps) {
|
|
|
5706
5757
|
issuedAt,
|
|
5707
5758
|
toString() {
|
|
5708
5759
|
return new import_siwe.SiweMessage({
|
|
5709
|
-
address: (0,
|
|
5760
|
+
address: (0, import_viem11.getAddress)(accountAddress),
|
|
5710
5761
|
chainId: numericChainId(chainId),
|
|
5711
5762
|
domain,
|
|
5712
5763
|
uri,
|
package/dist/index.js
CHANGED
|
@@ -3036,7 +3036,7 @@ var OwneySDK = class {
|
|
|
3036
3036
|
}
|
|
3037
3037
|
if (agentId === "surfliquid") {
|
|
3038
3038
|
if (!key2) return null;
|
|
3039
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-
|
|
3039
|
+
const { SurfLiquidAgent } = await import("./surfliquid.agent-YC4VDPPF.js");
|
|
3040
3040
|
return new SurfLiquidAgent({
|
|
3041
3041
|
apiKey: this.apiKey,
|
|
3042
3042
|
routingApiBaseUrl: this.routingApiBaseUrl
|
|
@@ -13,13 +13,9 @@ import {
|
|
|
13
13
|
readStuckBalance,
|
|
14
14
|
sweepStuckBalance,
|
|
15
15
|
withdrawSponsored
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-T5YJVIQG.js";
|
|
17
17
|
import "./chunk-AURO3C3R.js";
|
|
18
18
|
|
|
19
|
-
// src/agents/surfliquid/surfliquid.agent.ts
|
|
20
|
-
import { createWalletClient, custom } from "viem";
|
|
21
|
-
import { base } from "viem/chains";
|
|
22
|
-
|
|
23
19
|
// src/agents/surfliquid/surfliquid.session-store.ts
|
|
24
20
|
var KEY_PREFIX = "owney.surfliquid.session";
|
|
25
21
|
var EXPIRY_SKEW_MS = 3e4;
|
|
@@ -100,6 +96,7 @@ function parseJson(text) {
|
|
|
100
96
|
return void 0;
|
|
101
97
|
}
|
|
102
98
|
}
|
|
99
|
+
var emptyVaultInfo = () => normalizeVault(void 0);
|
|
103
100
|
function normalizeVault(json) {
|
|
104
101
|
const root = asRecord(json);
|
|
105
102
|
const data = asRecord(root.data);
|
|
@@ -146,7 +143,7 @@ function normalizeSupportedAssets(json, chainId) {
|
|
|
146
143
|
function createSurfBroker(options) {
|
|
147
144
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
148
145
|
const now = options.now ?? Date.now;
|
|
149
|
-
const
|
|
146
|
+
const base = `${options.routingApiBaseUrl.replace(/\/$/, "")}/api/v1/surf`;
|
|
150
147
|
const wallet = options.walletAddress;
|
|
151
148
|
let session = readSurfSession(options.apiKey, wallet);
|
|
152
149
|
const vaultMemo = /* @__PURE__ */ new Map();
|
|
@@ -165,7 +162,7 @@ function createSurfBroker(options) {
|
|
|
165
162
|
if (options.origin) headers["origin"] = options.origin;
|
|
166
163
|
let response;
|
|
167
164
|
try {
|
|
168
|
-
response = await fetchImpl(`${
|
|
165
|
+
response = await fetchImpl(`${base}${path}`, {
|
|
169
166
|
method,
|
|
170
167
|
headers,
|
|
171
168
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
@@ -270,7 +267,7 @@ var DEPOSIT_TRANSACTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
270
267
|
function mapMessage(message) {
|
|
271
268
|
const action = SURFLIQUID_ACTION_MAP[message.transactionType];
|
|
272
269
|
if (!action) return [];
|
|
273
|
-
const
|
|
270
|
+
const base = {
|
|
274
271
|
agent: "surfliquid",
|
|
275
272
|
action,
|
|
276
273
|
date: message.timestamp,
|
|
@@ -288,9 +285,9 @@ function mapMessage(message) {
|
|
|
288
285
|
};
|
|
289
286
|
if (DEPOSIT_TRANSACTION_TYPES.has(message.transactionType) && message.toVault?.name && message.amount != null) {
|
|
290
287
|
return [
|
|
291
|
-
|
|
288
|
+
base,
|
|
292
289
|
{
|
|
293
|
-
...
|
|
290
|
+
...base,
|
|
294
291
|
action: "Deposit",
|
|
295
292
|
positions: [
|
|
296
293
|
{
|
|
@@ -303,10 +300,20 @@ function mapMessage(message) {
|
|
|
303
300
|
}
|
|
304
301
|
];
|
|
305
302
|
}
|
|
306
|
-
return [
|
|
303
|
+
return [base];
|
|
304
|
+
}
|
|
305
|
+
function dedupeMessages(messages) {
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
307
|
+
return messages.filter((message) => {
|
|
308
|
+
if (!message.txHash) return true;
|
|
309
|
+
const key = `${message.transactionType}:${message.txHash}`;
|
|
310
|
+
if (seen.has(key)) return false;
|
|
311
|
+
seen.add(key);
|
|
312
|
+
return true;
|
|
313
|
+
});
|
|
307
314
|
}
|
|
308
315
|
function mapHistory(result, _chainId) {
|
|
309
|
-
const data = result.messages.flatMap(mapMessage);
|
|
316
|
+
const data = dedupeMessages(result.messages).flatMap(mapMessage);
|
|
310
317
|
const hasMore = result.page < result.pages;
|
|
311
318
|
return {
|
|
312
319
|
data,
|
|
@@ -502,6 +509,9 @@ var SurfLiquidAgent = class {
|
|
|
502
509
|
supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
|
|
503
510
|
broker = null;
|
|
504
511
|
brokerWallet = null;
|
|
512
|
+
// The SurfLiquid session and every keyed read run on the smart account (the vault
|
|
513
|
+
// owner), not the EOA — set by connect(), consumed by the reads below.
|
|
514
|
+
smartAccountAddress = null;
|
|
505
515
|
// Dedicated instance for the anonymous "0x" asset probe — never shares a slot
|
|
506
516
|
// with the user's broker, so discovery can never evict or overwrite a session.
|
|
507
517
|
discoveryBroker = null;
|
|
@@ -523,17 +533,22 @@ var SurfLiquidAgent = class {
|
|
|
523
533
|
return this.broker;
|
|
524
534
|
}
|
|
525
535
|
async connect(state, shouldForce = false) {
|
|
526
|
-
|
|
527
|
-
|
|
536
|
+
if (!shouldForce && this.broker && this.smartAccountAddress && this.broker.hasSession()) {
|
|
537
|
+
return this.broker;
|
|
538
|
+
}
|
|
528
539
|
if (this.connectPromise) return this.connectPromise;
|
|
529
540
|
this.connectPromise = (async () => {
|
|
541
|
+
const wallet = await this.sponsoredWallet(state);
|
|
542
|
+
const smartAccountAddress = wallet.smartAccountAddress;
|
|
543
|
+
this.smartAccountAddress = smartAccountAddress;
|
|
544
|
+
const broker = this.brokerFor(smartAccountAddress);
|
|
545
|
+
if (!shouldForce && broker.hasSession()) return broker;
|
|
546
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
547
|
+
if (!await createSponsoredChain(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
|
|
548
|
+
await wallet.deployAccount();
|
|
549
|
+
}
|
|
530
550
|
const message = await broker.nonce();
|
|
531
|
-
const
|
|
532
|
-
account: state.walletAddress,
|
|
533
|
-
chain: base,
|
|
534
|
-
transport: custom(state.provider)
|
|
535
|
-
});
|
|
536
|
-
const signature = await walletClient.signMessage({ account: state.walletAddress, message });
|
|
551
|
+
const signature = await wallet.signMessage(message);
|
|
537
552
|
await broker.login(message, signature);
|
|
538
553
|
return broker;
|
|
539
554
|
})();
|
|
@@ -543,6 +558,10 @@ var SurfLiquidAgent = class {
|
|
|
543
558
|
this.connectPromise = null;
|
|
544
559
|
}
|
|
545
560
|
}
|
|
561
|
+
/** The SurfLiquid-facing wallet address: the smart account once connected, else the EOA. */
|
|
562
|
+
surfWallet(state) {
|
|
563
|
+
return this.smartAccountAddress ?? state.walletAddress;
|
|
564
|
+
}
|
|
546
565
|
/** A 401 can only surface before any signature (SurfLiquid is never called between sign and submit). */
|
|
547
566
|
async withSession(state, run) {
|
|
548
567
|
try {
|
|
@@ -559,7 +578,7 @@ var SurfLiquidAgent = class {
|
|
|
559
578
|
}
|
|
560
579
|
}
|
|
561
580
|
async sponsoredWallet(state) {
|
|
562
|
-
const { createSponsoredWallet } = await import("./surfliquid.smart-account-
|
|
581
|
+
const { createSponsoredWallet } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
563
582
|
return createSponsoredWallet({
|
|
564
583
|
provider: state.provider,
|
|
565
584
|
ownerAddress: state.walletAddress,
|
|
@@ -573,15 +592,28 @@ var SurfLiquidAgent = class {
|
|
|
573
592
|
this.broker?.clearSession();
|
|
574
593
|
this.broker = null;
|
|
575
594
|
this.brokerWallet = null;
|
|
595
|
+
this.smartAccountAddress = null;
|
|
596
|
+
}
|
|
597
|
+
// The SDK orchestrator already marks the agent active and sets the chain. SurfLiquid
|
|
598
|
+
// establishes its session lazily — on the first read of a deployed account, or on
|
|
599
|
+
// deposit — so merely connecting a wallet never prompts for a signature.
|
|
600
|
+
async activateAgent(_state, _chainId) {
|
|
576
601
|
}
|
|
577
|
-
|
|
578
|
-
|
|
602
|
+
/** A counterfactual account owns no vault and can't be a SIWE signer yet — reads answer empty. */
|
|
603
|
+
async isSmartAccountDeployed(state) {
|
|
604
|
+
if (this.broker?.hasSession()) return true;
|
|
605
|
+
const wallet = await this.sponsoredWallet(state);
|
|
606
|
+
this.smartAccountAddress = wallet.smartAccountAddress;
|
|
607
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
608
|
+
return createSponsoredChain(this.config.rpcUrl).isDeployed(
|
|
609
|
+
wallet.smartAccountAddress
|
|
610
|
+
);
|
|
579
611
|
}
|
|
580
612
|
// --- IAgent: funds (gasless only) ---
|
|
581
613
|
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
582
614
|
const broker = await this.connect(state);
|
|
583
615
|
const wallet = await this.sponsoredWallet(state);
|
|
584
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
616
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
585
617
|
try {
|
|
586
618
|
const { txHash, vault } = await this.withSession(
|
|
587
619
|
state,
|
|
@@ -596,7 +628,7 @@ var SurfLiquidAgent = class {
|
|
|
596
628
|
async withdraw(state, _chainId, _token, amount) {
|
|
597
629
|
const broker = await this.connect(state);
|
|
598
630
|
const wallet = await this.sponsoredWallet(state);
|
|
599
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
631
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
600
632
|
try {
|
|
601
633
|
const result = await this.withSession(
|
|
602
634
|
state,
|
|
@@ -616,14 +648,14 @@ var SurfLiquidAgent = class {
|
|
|
616
648
|
/** Funds a prior withdrawal's sweep left in the smart account (never reached the EOA). No session needed — pure read. */
|
|
617
649
|
async getStuckBalance(state) {
|
|
618
650
|
const wallet = await this.sponsoredWallet(state);
|
|
619
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
651
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
620
652
|
const amount = await readStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
621
653
|
return { amount: amount.toString(), smartAccountAddress: wallet.smartAccountAddress };
|
|
622
654
|
}
|
|
623
655
|
/** Sweep the stranded balance to the owner's EOA — one sponsored userOp, one signature. */
|
|
624
656
|
async recoverStuckBalance(state) {
|
|
625
657
|
const wallet = await this.sponsoredWallet(state);
|
|
626
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
658
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
627
659
|
try {
|
|
628
660
|
const { txHash, amount } = await sweepStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
629
661
|
return { txHash, type: "full", amount: amount.toString() };
|
|
@@ -633,8 +665,9 @@ var SurfLiquidAgent = class {
|
|
|
633
665
|
}
|
|
634
666
|
// --- IAgent: portfolio reads ---
|
|
635
667
|
async vault(state) {
|
|
668
|
+
if (!await this.isSmartAccountDeployed(state)) return emptyVaultInfo();
|
|
636
669
|
const broker = await this.connect(state);
|
|
637
|
-
return this.withSession(state, () => broker.getVault(state
|
|
670
|
+
return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
|
|
638
671
|
}
|
|
639
672
|
async getBalances(state, chainId) {
|
|
640
673
|
const vault = await this.vault(state);
|
|
@@ -650,12 +683,13 @@ var SurfLiquidAgent = class {
|
|
|
650
683
|
return mapAccountApy(await this.vault(state), days);
|
|
651
684
|
}
|
|
652
685
|
async getHistory(state, chainId, options) {
|
|
686
|
+
if (!await this.isSmartAccountDeployed(state)) return { data: [], hasMore: false };
|
|
653
687
|
const broker = await this.connect(state);
|
|
654
688
|
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
655
689
|
const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
|
|
656
690
|
const result = await this.withSession(
|
|
657
691
|
state,
|
|
658
|
-
() => broker.getAgentMessages(state
|
|
692
|
+
() => broker.getAgentMessages(this.surfWallet(state), page, limit, options?.fromDate, options?.toDate)
|
|
659
693
|
);
|
|
660
694
|
return mapHistory(result, chainId);
|
|
661
695
|
}
|
|
@@ -6,14 +6,14 @@ import {
|
|
|
6
6
|
SURFLIQUID_VAULT_ABI,
|
|
7
7
|
SubmittedError,
|
|
8
8
|
USDC_ABI
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-T5YJVIQG.js";
|
|
10
10
|
import {
|
|
11
11
|
readTokenMeta
|
|
12
12
|
} from "./chunk-AURO3C3R.js";
|
|
13
13
|
|
|
14
14
|
// src/agents/surfliquid/surfliquid.smart-account.ts
|
|
15
15
|
import { createSmartAccountClient } from "permissionless";
|
|
16
|
-
import {
|
|
16
|
+
import { toSafeSmartAccount } from "permissionless/accounts";
|
|
17
17
|
import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
18
18
|
import {
|
|
19
19
|
createPublicClient,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
custom,
|
|
22
22
|
http
|
|
23
23
|
} from "viem";
|
|
24
|
-
import {
|
|
24
|
+
import { entryPoint07Address } from "viem/account-abstraction";
|
|
25
25
|
import { base } from "viem/chains";
|
|
26
26
|
var sponsorProxyUrl = (routingApiBaseUrl) => `${routingApiBaseUrl.replace(/\/$/, "")}/api/v1/sponsor/pimlico-rpc/${SURFLIQUID_CHAIN_ID}`;
|
|
27
27
|
function publicClientFor(rpcUrl) {
|
|
@@ -77,10 +77,11 @@ function pinAccount(provider, address) {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
async function createSponsoredWallet(input) {
|
|
80
|
-
const entryPoint = { address:
|
|
81
|
-
const account = await
|
|
80
|
+
const entryPoint = { address: entryPoint07Address, version: "0.7" };
|
|
81
|
+
const account = await toSafeSmartAccount({
|
|
82
82
|
client: publicClientFor(input.rpcUrl),
|
|
83
|
-
|
|
83
|
+
owners: [pinAccount(input.provider, input.ownerAddress)],
|
|
84
|
+
version: "1.4.1",
|
|
84
85
|
entryPoint
|
|
85
86
|
});
|
|
86
87
|
const bundlerTransport = http(sponsorProxyUrl(input.routingApiBaseUrl), {
|
|
@@ -112,6 +113,20 @@ async function createSponsoredWallet(input) {
|
|
|
112
113
|
primaryType: typedData.primaryType,
|
|
113
114
|
message: typedData.message
|
|
114
115
|
}),
|
|
116
|
+
// The smart account signs (ERC-1271), not the EOA: SurfLiquid's SIWE session must
|
|
117
|
+
// be the vault owner, which is the smart account. Safe wraps this as a SafeMessage
|
|
118
|
+
// EIP-712 signature the deployed account verifies via isValidSignature.
|
|
119
|
+
signMessage: (message) => account.signMessage({ message }),
|
|
120
|
+
// Deploy-on-connect: the account is counterfactual until its first userOp, but SIWE
|
|
121
|
+
// (isValidSignature) needs on-chain code. A no-op self-call carries the factory
|
|
122
|
+
// initCode and deploys it. Idempotency is the caller's (it checks isDeployed first).
|
|
123
|
+
deployAccount: async () => {
|
|
124
|
+
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
125
|
+
calls: [{ to: account.address, value: 0n, data: "0x" }]
|
|
126
|
+
});
|
|
127
|
+
const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash: userOpHash });
|
|
128
|
+
return receipt.receipt.transactionHash;
|
|
129
|
+
},
|
|
115
130
|
sendCalls: async (calls) => {
|
|
116
131
|
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
117
132
|
calls: calls.map((c) => ({ to: c.to, data: c.data, value: 0n }))
|