@owney/sdk 0.7.22-beta.3 → 0.7.22-beta.4

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.
@@ -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.ownerAddress);
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.ownerAddress);
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 base5 = `${options.routingApiBaseUrl.replace(/\/$/, "")}/api/v1/surf`;
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(`${base5}${path}`, {
410
+ response = await fetchImpl(`${base4}${path}`, {
411
411
  method,
412
412
  headers,
413
413
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -527,7 +527,7 @@ var init_surfliquid_broker = __esm({
527
527
  function mapMessage(message) {
528
528
  const action = SURFLIQUID_ACTION_MAP[message.transactionType];
529
529
  if (!action) return [];
530
- const base5 = {
530
+ const base4 = {
531
531
  agent: "surfliquid",
532
532
  action,
533
533
  date: message.timestamp,
@@ -545,9 +545,9 @@ function mapMessage(message) {
545
545
  };
546
546
  if (DEPOSIT_TRANSACTION_TYPES.has(message.transactionType) && message.toVault?.name && message.amount != null) {
547
547
  return [
548
- base5,
548
+ base4,
549
549
  {
550
- ...base5,
550
+ ...base4,
551
551
  action: "Deposit",
552
552
  positions: [
553
553
  {
@@ -560,7 +560,7 @@ function mapMessage(message) {
560
560
  }
561
561
  ];
562
562
  }
563
- return [base5];
563
+ return [base4];
564
564
  }
565
565
  function mapHistory(result, _chainId) {
566
566
  const data = result.messages.flatMap(mapMessage);
@@ -760,7 +760,7 @@ var init_surfliquid_calls = __esm({
760
760
 
761
761
  // src/agents/surfliquid/surfliquid.sponsorship.ts
762
762
  async function resolveVault(ctx) {
763
- const registered = await ctx.api.getVault(ctx.wallet.ownerAddress);
763
+ const registered = await ctx.api.getVault(ctx.wallet.smartAccountAddress);
764
764
  const smartAccount = ctx.wallet.smartAccountAddress;
765
765
  if (!registered.userVaultAddress) {
766
766
  const salt2 = registered.deploymentSalt ?? (await ctx.api.prepare(SURFLIQUID_CHAIN_ID)).salt;
@@ -875,7 +875,7 @@ async function depositSponsored(input) {
875
875
  }
876
876
  async function withdrawSponsored(input) {
877
877
  const { api, chain, wallet, amount } = input;
878
- const registered = await api.getVault(wallet.ownerAddress);
878
+ const registered = await api.getVault(wallet.smartAccountAddress);
879
879
  if (!registered.userVaultAddress) {
880
880
  throw new Error("SurfLiquid has no vault registered for this wallet");
881
881
  }
@@ -1077,10 +1077,11 @@ function pinAccount(provider, address) {
1077
1077
  };
1078
1078
  }
1079
1079
  async function createSponsoredWallet(input) {
1080
- const entryPoint = { address: import_account_abstraction.entryPoint08Address, version: "0.8" };
1081
- const account = await (0, import_accounts.toSimpleSmartAccount)({
1080
+ const entryPoint = { address: import_account_abstraction.entryPoint07Address, version: "0.7" };
1081
+ const account = await (0, import_accounts.toSafeSmartAccount)({
1082
1082
  client: publicClientFor(input.rpcUrl),
1083
- owner: pinAccount(input.provider, input.ownerAddress),
1083
+ owners: [pinAccount(input.provider, input.ownerAddress)],
1084
+ version: "1.4.1",
1084
1085
  entryPoint
1085
1086
  });
1086
1087
  const bundlerTransport = (0, import_viem9.http)(sponsorProxyUrl(input.routingApiBaseUrl), {
@@ -1112,6 +1113,20 @@ async function createSponsoredWallet(input) {
1112
1113
  primaryType: typedData.primaryType,
1113
1114
  message: typedData.message
1114
1115
  }),
1116
+ // The smart account signs (ERC-1271), not the EOA: SurfLiquid's SIWE session must
1117
+ // be the vault owner, which is the smart account. Safe wraps this as a SafeMessage
1118
+ // EIP-712 signature the deployed account verifies via isValidSignature.
1119
+ signMessage: (message) => account.signMessage({ message }),
1120
+ // Deploy-on-connect: the account is counterfactual until its first userOp, but SIWE
1121
+ // (isValidSignature) needs on-chain code. A no-op self-call carries the factory
1122
+ // initCode and deploys it. Idempotency is the caller's (it checks isDeployed first).
1123
+ deployAccount: async () => {
1124
+ const userOpHash = await smartAccountClient.sendUserOperation({
1125
+ calls: [{ to: account.address, value: 0n, data: "0x" }]
1126
+ });
1127
+ const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash: userOpHash });
1128
+ return receipt.receipt.transactionHash;
1129
+ },
1115
1130
  sendCalls: async (calls) => {
1116
1131
  const userOpHash = await smartAccountClient.sendUserOperation({
1117
1132
  calls: calls.map((c) => ({ to: c.to, data: c.data, value: 0n }))
@@ -1166,12 +1181,10 @@ function toOwneyError(error) {
1166
1181
  }
1167
1182
  return new OwneyError("SPONSORSHIP_UNAVAILABLE", message, void 0, AGENT_ID2);
1168
1183
  }
1169
- var import_viem10, import_chains3, AGENT_ID2, WALLET_REJECTED_CODE, DISCOVERY_WALLET2, HISTORY_DEFAULT_LIMIT, APY_WINDOW_KEY2, SurfLiquidAgent;
1184
+ var AGENT_ID2, WALLET_REJECTED_CODE, DISCOVERY_WALLET2, HISTORY_DEFAULT_LIMIT, APY_WINDOW_KEY2, SurfLiquidAgent;
1170
1185
  var init_surfliquid_agent = __esm({
1171
1186
  "src/agents/surfliquid/surfliquid.agent.ts"() {
1172
1187
  "use strict";
1173
- import_viem10 = require("viem");
1174
- import_chains3 = require("viem/chains");
1175
1188
  init_errors();
1176
1189
  init_surfliquid_constants();
1177
1190
  init_surfliquid_broker();
@@ -1198,6 +1211,9 @@ var init_surfliquid_agent = __esm({
1198
1211
  supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
1199
1212
  broker = null;
1200
1213
  brokerWallet = null;
1214
+ // The SurfLiquid session and every keyed read run on the smart account (the vault
1215
+ // owner), not the EOA — set by connect(), consumed by the reads below.
1216
+ smartAccountAddress = null;
1201
1217
  // Dedicated instance for the anonymous "0x" asset probe — never shares a slot
1202
1218
  // with the user's broker, so discovery can never evict or overwrite a session.
1203
1219
  discoveryBroker = null;
@@ -1219,17 +1235,22 @@ var init_surfliquid_agent = __esm({
1219
1235
  return this.broker;
1220
1236
  }
1221
1237
  async connect(state, shouldForce = false) {
1222
- const broker = this.brokerFor(state.walletAddress);
1223
- if (!shouldForce && broker.hasSession()) return broker;
1238
+ if (!shouldForce && this.broker && this.smartAccountAddress && this.broker.hasSession()) {
1239
+ return this.broker;
1240
+ }
1224
1241
  if (this.connectPromise) return this.connectPromise;
1225
1242
  this.connectPromise = (async () => {
1243
+ const wallet = await this.sponsoredWallet(state);
1244
+ const smartAccountAddress = wallet.smartAccountAddress;
1245
+ this.smartAccountAddress = smartAccountAddress;
1246
+ const broker = this.brokerFor(smartAccountAddress);
1247
+ if (!shouldForce && broker.hasSession()) return broker;
1248
+ const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
1249
+ if (!await createSponsoredChain2(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
1250
+ await wallet.deployAccount();
1251
+ }
1226
1252
  const message = await broker.nonce();
1227
- const walletClient = (0, import_viem10.createWalletClient)({
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 });
1253
+ const signature = await wallet.signMessage(message);
1233
1254
  await broker.login(message, signature);
1234
1255
  return broker;
1235
1256
  })();
@@ -1239,6 +1260,10 @@ var init_surfliquid_agent = __esm({
1239
1260
  this.connectPromise = null;
1240
1261
  }
1241
1262
  }
1263
+ /** The SurfLiquid-facing wallet address: the smart account once connected, else the EOA. */
1264
+ surfWallet(state) {
1265
+ return this.smartAccountAddress ?? state.walletAddress;
1266
+ }
1242
1267
  /** A 401 can only surface before any signature (SurfLiquid is never called between sign and submit). */
1243
1268
  async withSession(state, run) {
1244
1269
  try {
@@ -1269,6 +1294,7 @@ var init_surfliquid_agent = __esm({
1269
1294
  this.broker?.clearSession();
1270
1295
  this.broker = null;
1271
1296
  this.brokerWallet = null;
1297
+ this.smartAccountAddress = null;
1272
1298
  }
1273
1299
  async activateAgent(state, _chainId) {
1274
1300
  await this.connect(state);
@@ -1330,7 +1356,7 @@ var init_surfliquid_agent = __esm({
1330
1356
  // --- IAgent: portfolio reads ---
1331
1357
  async vault(state) {
1332
1358
  const broker = await this.connect(state);
1333
- return this.withSession(state, () => broker.getVault(state.walletAddress));
1359
+ return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
1334
1360
  }
1335
1361
  async getBalances(state, chainId) {
1336
1362
  const vault = await this.vault(state);
@@ -1351,7 +1377,7 @@ var init_surfliquid_agent = __esm({
1351
1377
  const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
1352
1378
  const result = await this.withSession(
1353
1379
  state,
1354
- () => broker.getAgentMessages(state.walletAddress, page, limit, options?.fromDate, options?.toDate)
1380
+ () => broker.getAgentMessages(this.surfWallet(state), page, limit, options?.fromDate, options?.toDate)
1355
1381
  );
1356
1382
  return mapHistory(result, chainId);
1357
1383
  }
@@ -3590,8 +3616,8 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
3590
3616
  }
3591
3617
 
3592
3618
  // src/client.ts
3593
- var import_viem11 = require("viem");
3594
- var import_chains4 = require("viem/chains");
3619
+ var import_viem10 = require("viem");
3620
+ var import_chains3 = require("viem/chains");
3595
3621
 
3596
3622
  // src/lib/sponsored-deposit.ts
3597
3623
  init_errors();
@@ -3601,10 +3627,10 @@ init_transfer_auth();
3601
3627
  init_errors();
3602
3628
  var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
3603
3629
  async function postSponsorTransferAuth(input) {
3604
- const base5 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3630
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3605
3631
  let res;
3606
3632
  try {
3607
- res = await fetch(`${base5}/api/v1/sponsor/erc20-transfer-auth`, {
3633
+ res = await fetch(`${base4}/api/v1/sponsor/erc20-transfer-auth`, {
3608
3634
  method: "POST",
3609
3635
  headers: {
3610
3636
  "content-type": "application/json",
@@ -3641,10 +3667,10 @@ async function postSponsorTransferAuth(input) {
3641
3667
  return parsed.data;
3642
3668
  }
3643
3669
  async function postSponsorPermit2Transfer(input) {
3644
- const base5 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3670
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3645
3671
  let res;
3646
3672
  try {
3647
- res = await fetch(`${base5}/api/v1/sponsor/permit2-transfer`, {
3673
+ res = await fetch(`${base4}/api/v1/sponsor/permit2-transfer`, {
3648
3674
  method: "POST",
3649
3675
  headers: {
3650
3676
  "content-type": "application/json",
@@ -3679,11 +3705,11 @@ async function postSponsorPermit2Transfer(input) {
3679
3705
  return parsed.data;
3680
3706
  }
3681
3707
  async function getSponsorRelayerAddress(input) {
3682
- const base5 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3708
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3683
3709
  let res;
3684
3710
  try {
3685
3711
  res = await fetch(
3686
- `${base5}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
3712
+ `${base4}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
3687
3713
  {
3688
3714
  headers: { "x-owney-api-key": input.apiKey }
3689
3715
  }
@@ -4110,9 +4136,9 @@ var SPONSORED_USDC_BY_CHAIN = {
4110
4136
  1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
4111
4137
  };
4112
4138
  var VIEM_CHAIN2 = {
4113
- 8453: import_chains4.base,
4114
- 42161: import_chains4.arbitrum,
4115
- 1: import_chains4.mainnet
4139
+ 8453: import_chains3.base,
4140
+ 42161: import_chains3.arbitrum,
4141
+ 1: import_chains3.mainnet
4116
4142
  };
4117
4143
  var SPONSORED_WETH_BY_CHAIN = {
4118
4144
  8453: "0x4200000000000000000000000000000000000006",
@@ -4269,14 +4295,14 @@ var OwneySDK = class {
4269
4295
  // Casts work around viem's chain-narrowed Client vs the generic
4270
4296
  // PublicClient/WalletClient param types — structurally identical at
4271
4297
  // runtime, but the two share a name TS treats as unrelated.
4272
- getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
4298
+ getPublicClient: (cid) => (0, import_viem10.createPublicClient)({
4273
4299
  chain: VIEM_CHAIN2[cid],
4274
- transport: (0, import_viem11.custom)(provider)
4300
+ transport: (0, import_viem10.custom)(provider)
4275
4301
  }),
4276
- getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
4302
+ getWalletClient: (cid) => (0, import_viem10.createWalletClient)({
4277
4303
  account: owner,
4278
4304
  chain: VIEM_CHAIN2[cid],
4279
- transport: (0, import_viem11.custom)(provider)
4305
+ transport: (0, import_viem10.custom)(provider)
4280
4306
  })
4281
4307
  });
4282
4308
  if (!onApproved) this.cachedSponsoredCallback = callback;
@@ -4322,14 +4348,14 @@ var OwneySDK = class {
4322
4348
  // Casts work around viem's chain-narrowed Client vs the generic
4323
4349
  // PublicClient/WalletClient param types — structurally identical at
4324
4350
  // runtime, but the two share a name TS treats as unrelated.
4325
- getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
4351
+ getPublicClient: (cid) => (0, import_viem10.createPublicClient)({
4326
4352
  chain: VIEM_CHAIN2[cid],
4327
- transport: (0, import_viem11.custom)(provider)
4353
+ transport: (0, import_viem10.custom)(provider)
4328
4354
  }),
4329
- getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
4355
+ getWalletClient: (cid) => (0, import_viem10.createWalletClient)({
4330
4356
  account: owner,
4331
4357
  chain: VIEM_CHAIN2[cid],
4332
- transport: (0, import_viem11.custom)(provider)
4358
+ transport: (0, import_viem10.custom)(provider)
4333
4359
  })
4334
4360
  });
4335
4361
  if (!onApproved) this.cachedWethSponsoredCallback = callback;
@@ -5448,10 +5474,10 @@ var OwneySDK = class {
5448
5474
  );
5449
5475
  }
5450
5476
  const provider = this.requireConnectedProvider();
5451
- const wallet = (0, import_viem11.createWalletClient)({
5477
+ const wallet = (0, import_viem10.createWalletClient)({
5452
5478
  account: state.walletAddress,
5453
5479
  chain: VIEM_CHAIN2[chainId],
5454
- transport: (0, import_viem11.custom)(provider)
5480
+ transport: (0, import_viem10.custom)(provider)
5455
5481
  });
5456
5482
  const hash = await wallet.writeContract({
5457
5483
  address: token,
@@ -5461,9 +5487,9 @@ var OwneySDK = class {
5461
5487
  account: state.walletAddress,
5462
5488
  chain: VIEM_CHAIN2[chainId]
5463
5489
  });
5464
- const publicClient = (0, import_viem11.createPublicClient)({
5490
+ const publicClient = (0, import_viem10.createPublicClient)({
5465
5491
  chain: VIEM_CHAIN2[chainId],
5466
- transport: (0, import_viem11.custom)(provider)
5492
+ transport: (0, import_viem10.custom)(provider)
5467
5493
  });
5468
5494
  const receipt = await publicClient.waitForTransactionReceipt({
5469
5495
  hash,
@@ -5579,7 +5605,7 @@ init_errors();
5579
5605
  init_debug();
5580
5606
 
5581
5607
  // src/agents/zyfai/zyfai.siwx.ts
5582
- var import_viem12 = require("viem");
5608
+ var import_viem11 = require("viem");
5583
5609
  var import_siwe = require("siwe");
5584
5610
  var import_sdk2 = require("@zyfai/sdk");
5585
5611
 
@@ -5706,7 +5732,7 @@ function buildSIWXConfig(deps) {
5706
5732
  issuedAt,
5707
5733
  toString() {
5708
5734
  return new import_siwe.SiweMessage({
5709
- address: (0, import_viem12.getAddress)(accountAddress),
5735
+ address: (0, import_viem11.getAddress)(accountAddress),
5710
5736
  chainId: numericChainId(chainId),
5711
5737
  domain,
5712
5738
  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-BFBNEQQI.js");
3039
+ const { SurfLiquidAgent } = await import("./surfliquid.agent-ZTIK54MW.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-5W56YOBO.js";
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;
@@ -146,7 +142,7 @@ function normalizeSupportedAssets(json, chainId) {
146
142
  function createSurfBroker(options) {
147
143
  const fetchImpl = options.fetchImpl ?? fetch;
148
144
  const now = options.now ?? Date.now;
149
- const base2 = `${options.routingApiBaseUrl.replace(/\/$/, "")}/api/v1/surf`;
145
+ const base = `${options.routingApiBaseUrl.replace(/\/$/, "")}/api/v1/surf`;
150
146
  const wallet = options.walletAddress;
151
147
  let session = readSurfSession(options.apiKey, wallet);
152
148
  const vaultMemo = /* @__PURE__ */ new Map();
@@ -165,7 +161,7 @@ function createSurfBroker(options) {
165
161
  if (options.origin) headers["origin"] = options.origin;
166
162
  let response;
167
163
  try {
168
- response = await fetchImpl(`${base2}${path}`, {
164
+ response = await fetchImpl(`${base}${path}`, {
169
165
  method,
170
166
  headers,
171
167
  body: body === void 0 ? void 0 : JSON.stringify(body),
@@ -270,7 +266,7 @@ var DEPOSIT_TRANSACTION_TYPES = /* @__PURE__ */ new Set([
270
266
  function mapMessage(message) {
271
267
  const action = SURFLIQUID_ACTION_MAP[message.transactionType];
272
268
  if (!action) return [];
273
- const base2 = {
269
+ const base = {
274
270
  agent: "surfliquid",
275
271
  action,
276
272
  date: message.timestamp,
@@ -288,9 +284,9 @@ function mapMessage(message) {
288
284
  };
289
285
  if (DEPOSIT_TRANSACTION_TYPES.has(message.transactionType) && message.toVault?.name && message.amount != null) {
290
286
  return [
291
- base2,
287
+ base,
292
288
  {
293
- ...base2,
289
+ ...base,
294
290
  action: "Deposit",
295
291
  positions: [
296
292
  {
@@ -303,7 +299,7 @@ function mapMessage(message) {
303
299
  }
304
300
  ];
305
301
  }
306
- return [base2];
302
+ return [base];
307
303
  }
308
304
  function mapHistory(result, _chainId) {
309
305
  const data = result.messages.flatMap(mapMessage);
@@ -502,6 +498,9 @@ var SurfLiquidAgent = class {
502
498
  supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
503
499
  broker = null;
504
500
  brokerWallet = null;
501
+ // The SurfLiquid session and every keyed read run on the smart account (the vault
502
+ // owner), not the EOA — set by connect(), consumed by the reads below.
503
+ smartAccountAddress = null;
505
504
  // Dedicated instance for the anonymous "0x" asset probe — never shares a slot
506
505
  // with the user's broker, so discovery can never evict or overwrite a session.
507
506
  discoveryBroker = null;
@@ -523,17 +522,22 @@ var SurfLiquidAgent = class {
523
522
  return this.broker;
524
523
  }
525
524
  async connect(state, shouldForce = false) {
526
- const broker = this.brokerFor(state.walletAddress);
527
- if (!shouldForce && broker.hasSession()) return broker;
525
+ if (!shouldForce && this.broker && this.smartAccountAddress && this.broker.hasSession()) {
526
+ return this.broker;
527
+ }
528
528
  if (this.connectPromise) return this.connectPromise;
529
529
  this.connectPromise = (async () => {
530
+ const wallet = await this.sponsoredWallet(state);
531
+ const smartAccountAddress = wallet.smartAccountAddress;
532
+ this.smartAccountAddress = smartAccountAddress;
533
+ const broker = this.brokerFor(smartAccountAddress);
534
+ if (!shouldForce && broker.hasSession()) return broker;
535
+ const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
536
+ if (!await createSponsoredChain(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
537
+ await wallet.deployAccount();
538
+ }
530
539
  const message = await broker.nonce();
531
- const walletClient = createWalletClient({
532
- account: state.walletAddress,
533
- chain: base,
534
- transport: custom(state.provider)
535
- });
536
- const signature = await walletClient.signMessage({ account: state.walletAddress, message });
540
+ const signature = await wallet.signMessage(message);
537
541
  await broker.login(message, signature);
538
542
  return broker;
539
543
  })();
@@ -543,6 +547,10 @@ var SurfLiquidAgent = class {
543
547
  this.connectPromise = null;
544
548
  }
545
549
  }
550
+ /** The SurfLiquid-facing wallet address: the smart account once connected, else the EOA. */
551
+ surfWallet(state) {
552
+ return this.smartAccountAddress ?? state.walletAddress;
553
+ }
546
554
  /** A 401 can only surface before any signature (SurfLiquid is never called between sign and submit). */
547
555
  async withSession(state, run) {
548
556
  try {
@@ -559,7 +567,7 @@ var SurfLiquidAgent = class {
559
567
  }
560
568
  }
561
569
  async sponsoredWallet(state) {
562
- const { createSponsoredWallet } = await import("./surfliquid.smart-account-O6YPCQT3.js");
570
+ const { createSponsoredWallet } = await import("./surfliquid.smart-account-YV3PLZ72.js");
563
571
  return createSponsoredWallet({
564
572
  provider: state.provider,
565
573
  ownerAddress: state.walletAddress,
@@ -573,6 +581,7 @@ var SurfLiquidAgent = class {
573
581
  this.broker?.clearSession();
574
582
  this.broker = null;
575
583
  this.brokerWallet = null;
584
+ this.smartAccountAddress = null;
576
585
  }
577
586
  async activateAgent(state, _chainId) {
578
587
  await this.connect(state);
@@ -581,7 +590,7 @@ var SurfLiquidAgent = class {
581
590
  async deposit(state, _chainId, amount, _asset, _depositCallback) {
582
591
  const broker = await this.connect(state);
583
592
  const wallet = await this.sponsoredWallet(state);
584
- const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
593
+ const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
585
594
  try {
586
595
  const { txHash, vault } = await this.withSession(
587
596
  state,
@@ -596,7 +605,7 @@ var SurfLiquidAgent = class {
596
605
  async withdraw(state, _chainId, _token, amount) {
597
606
  const broker = await this.connect(state);
598
607
  const wallet = await this.sponsoredWallet(state);
599
- const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
608
+ const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
600
609
  try {
601
610
  const result = await this.withSession(
602
611
  state,
@@ -616,14 +625,14 @@ var SurfLiquidAgent = class {
616
625
  /** Funds a prior withdrawal's sweep left in the smart account (never reached the EOA). No session needed — pure read. */
617
626
  async getStuckBalance(state) {
618
627
  const wallet = await this.sponsoredWallet(state);
619
- const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
628
+ const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
620
629
  const amount = await readStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
621
630
  return { amount: amount.toString(), smartAccountAddress: wallet.smartAccountAddress };
622
631
  }
623
632
  /** Sweep the stranded balance to the owner's EOA — one sponsored userOp, one signature. */
624
633
  async recoverStuckBalance(state) {
625
634
  const wallet = await this.sponsoredWallet(state);
626
- const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
635
+ const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
627
636
  try {
628
637
  const { txHash, amount } = await sweepStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
629
638
  return { txHash, type: "full", amount: amount.toString() };
@@ -634,7 +643,7 @@ var SurfLiquidAgent = class {
634
643
  // --- IAgent: portfolio reads ---
635
644
  async vault(state) {
636
645
  const broker = await this.connect(state);
637
- return this.withSession(state, () => broker.getVault(state.walletAddress));
646
+ return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
638
647
  }
639
648
  async getBalances(state, chainId) {
640
649
  const vault = await this.vault(state);
@@ -655,7 +664,7 @@ var SurfLiquidAgent = class {
655
664
  const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
656
665
  const result = await this.withSession(
657
666
  state,
658
- () => broker.getAgentMessages(state.walletAddress, page, limit, options?.fromDate, options?.toDate)
667
+ () => broker.getAgentMessages(this.surfWallet(state), page, limit, options?.fromDate, options?.toDate)
659
668
  );
660
669
  return mapHistory(result, chainId);
661
670
  }
@@ -6,14 +6,14 @@ import {
6
6
  SURFLIQUID_VAULT_ABI,
7
7
  SubmittedError,
8
8
  USDC_ABI
9
- } from "./chunk-5W56YOBO.js";
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 { toSimpleSmartAccount } from "permissionless/accounts";
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 { entryPoint08Address } from "viem/account-abstraction";
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: entryPoint08Address, version: "0.8" };
81
- const account = await toSimpleSmartAccount({
80
+ const entryPoint = { address: entryPoint07Address, version: "0.7" };
81
+ const account = await toSafeSmartAccount({
82
82
  client: publicClientFor(input.rpcUrl),
83
- owner: pinAccount(input.provider, input.ownerAddress),
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 }))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.22-beta.3",
3
+ "version": "0.7.22-beta.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",