@owney/sdk 0.7.22-beta.0 → 0.7.22-beta.2
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-W3FYRJLJ.js → chunk-5W56YOBO.js} +85 -35
- package/dist/{chunk-5LU2SHO7.js → chunk-AURO3C3R.js} +18 -10
- package/dist/index.cjs +179 -69
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +27 -2
- package/dist/{surfliquid.agent-XDJ672GM.js → surfliquid.agent-E54CPWXF.js} +25 -5
- package/dist/{surfliquid.smart-account-DWV5B3D5.js → surfliquid.smart-account-O6YPCQT3.js} +16 -4
- package/package.json +1 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./chunk-5LU2SHO7.js";
|
|
2
|
+
buildPermitTypedData
|
|
3
|
+
} from "./chunk-AURO3C3R.js";
|
|
5
4
|
|
|
6
5
|
// src/agents/surfliquid/surfliquid.constants.ts
|
|
7
6
|
var SURFLIQUID_CHAIN_ID = 8453;
|
|
8
7
|
var SURFLIQUID_CHAIN_NAME = "BASE";
|
|
9
8
|
var SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
9
|
+
var SURFLIQUID_PERMIT_CAP = 10000000000n;
|
|
10
|
+
var SURFLIQUID_PERMIT_TTL_SECONDS = 3600n;
|
|
10
11
|
var SURFLIQUID_MIN_DEPOSIT = "0";
|
|
11
12
|
var SURFLIQUID_SUPPORTED_ASSETS = [
|
|
12
13
|
{
|
|
@@ -49,10 +50,16 @@ var SURFLIQUID_VAULT_ABI = parseAbi([
|
|
|
49
50
|
var USDC_ABI = parseAbi([
|
|
50
51
|
"function approve(address spender, uint256 amount)",
|
|
51
52
|
"function transfer(address to, uint256 amount)",
|
|
53
|
+
"function transferFrom(address from, address to, uint256 value)",
|
|
52
54
|
"function balanceOf(address account) view returns (uint256)",
|
|
53
|
-
"function
|
|
55
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
56
|
+
"function nonces(address owner) view returns (uint256)",
|
|
57
|
+
"function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)"
|
|
54
58
|
]);
|
|
55
59
|
|
|
60
|
+
// src/agents/surfliquid/surfliquid.sponsorship.ts
|
|
61
|
+
import { parseSignature } from "viem";
|
|
62
|
+
|
|
56
63
|
// src/agents/surfliquid/surfliquid.calls.ts
|
|
57
64
|
import { encodeFunctionData } from "viem";
|
|
58
65
|
var call = (to, abi, functionName, args) => ({
|
|
@@ -60,12 +67,12 @@ var call = (to, abi, functionName, args) => ({
|
|
|
60
67
|
data: encodeFunctionData({ abi, functionName, args })
|
|
61
68
|
});
|
|
62
69
|
function buildDepositCalls(input) {
|
|
63
|
-
const { smartAccount, vault, amount,
|
|
64
|
-
if (
|
|
65
|
-
throw new Error("
|
|
70
|
+
const { smartAccount, owner, vault, amount, permit, deploySalt } = input;
|
|
71
|
+
if (permit && permit.owner.toLowerCase() !== owner.toLowerCase()) {
|
|
72
|
+
throw new Error("Permit must be signed by the smart account's owner");
|
|
66
73
|
}
|
|
67
|
-
if (
|
|
68
|
-
throw new Error("
|
|
74
|
+
if (permit && permit.value < amount) {
|
|
75
|
+
throw new Error("Permit allowance is worth less than the deposit");
|
|
69
76
|
}
|
|
70
77
|
if (!input.hasInitialDeposit && !input.morphoVault) {
|
|
71
78
|
throw new Error("A first deposit needs a target morpho vault");
|
|
@@ -79,16 +86,21 @@ function buildDepositCalls(input) {
|
|
|
79
86
|
])
|
|
80
87
|
);
|
|
81
88
|
}
|
|
89
|
+
if (permit) {
|
|
90
|
+
calls.push(
|
|
91
|
+
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "permit", [
|
|
92
|
+
permit.owner,
|
|
93
|
+
smartAccount,
|
|
94
|
+
permit.value,
|
|
95
|
+
permit.deadline,
|
|
96
|
+
permit.v,
|
|
97
|
+
permit.r,
|
|
98
|
+
permit.s
|
|
99
|
+
])
|
|
100
|
+
);
|
|
101
|
+
}
|
|
82
102
|
calls.push(
|
|
83
|
-
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "
|
|
84
|
-
authorization.from,
|
|
85
|
-
authorization.to,
|
|
86
|
-
authorization.value,
|
|
87
|
-
authorization.validAfter,
|
|
88
|
-
authorization.validBefore,
|
|
89
|
-
authorization.nonce,
|
|
90
|
-
authorization.signature
|
|
91
|
-
]),
|
|
103
|
+
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "transferFrom", [owner, smartAccount, amount]),
|
|
92
104
|
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "approve", [vault, amount]),
|
|
93
105
|
input.hasInitialDeposit ? call(vault, SURFLIQUID_VAULT_ABI, "userDeposit", [SURFLIQUID_USDC_ADDRESS, amount]) : call(vault, SURFLIQUID_VAULT_ABI, "initialDeposit", [
|
|
94
106
|
SURFLIQUID_USDC_ADDRESS,
|
|
@@ -111,7 +123,6 @@ function buildSweepCalls(input) {
|
|
|
111
123
|
}
|
|
112
124
|
|
|
113
125
|
// src/agents/surfliquid/surfliquid.sponsorship.ts
|
|
114
|
-
var AUTHORIZATION_TTL_SECONDS = 3600n;
|
|
115
126
|
var SubmittedError = class extends Error {
|
|
116
127
|
constructor(message, userOpHash) {
|
|
117
128
|
super(message);
|
|
@@ -160,22 +171,23 @@ async function pickMorphoVault(api) {
|
|
|
160
171
|
}
|
|
161
172
|
return candidate.vaultAddress;
|
|
162
173
|
}
|
|
163
|
-
async function
|
|
164
|
-
const {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
174
|
+
async function permitIfShort(input) {
|
|
175
|
+
const { chain, wallet, amount } = input;
|
|
176
|
+
const allowance = await chain.readAllowance(wallet.ownerAddress, wallet.smartAccountAddress);
|
|
177
|
+
if (allowance >= amount) return void 0;
|
|
178
|
+
const [{ tokenName, tokenVersion }, nonce] = await Promise.all([
|
|
179
|
+
chain.readTokenMeta(),
|
|
180
|
+
chain.readPermitNonce(wallet.ownerAddress)
|
|
181
|
+
]);
|
|
169
182
|
const message = {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
value: amount,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
nonce: randomAuthNonce()
|
|
183
|
+
owner: wallet.ownerAddress,
|
|
184
|
+
spender: wallet.smartAccountAddress,
|
|
185
|
+
value: amount > SURFLIQUID_PERMIT_CAP ? amount : SURFLIQUID_PERMIT_CAP,
|
|
186
|
+
nonce,
|
|
187
|
+
deadline: BigInt(Math.floor(Date.now() / 1e3)) + SURFLIQUID_PERMIT_TTL_SECONDS
|
|
176
188
|
};
|
|
177
|
-
const signature = await wallet.
|
|
178
|
-
|
|
189
|
+
const signature = await wallet.signPermit(
|
|
190
|
+
buildPermitTypedData({
|
|
179
191
|
token: SURFLIQUID_USDC_ADDRESS,
|
|
180
192
|
chainId: SURFLIQUID_CHAIN_ID,
|
|
181
193
|
tokenName,
|
|
@@ -183,12 +195,40 @@ async function depositSponsored(input) {
|
|
|
183
195
|
message
|
|
184
196
|
})
|
|
185
197
|
);
|
|
198
|
+
const { r, s, v, yParity } = parseSignature(signature);
|
|
199
|
+
return {
|
|
200
|
+
owner: message.owner,
|
|
201
|
+
value: message.value,
|
|
202
|
+
deadline: message.deadline,
|
|
203
|
+
v: Number(v ?? BigInt(yParity + 27)),
|
|
204
|
+
r,
|
|
205
|
+
s
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
async function readStuckBalance(input) {
|
|
209
|
+
return input.chain.usdcBalanceOf(input.wallet.smartAccountAddress);
|
|
210
|
+
}
|
|
211
|
+
async function sweepStuckBalance(input) {
|
|
212
|
+
const stranded = await readStuckBalance(input);
|
|
213
|
+
if (stranded === 0n) return { amount: 0n };
|
|
214
|
+
const txHash = await input.wallet.sendCalls(
|
|
215
|
+
buildSweepCalls({ owner: input.wallet.ownerAddress, amount: stranded })
|
|
216
|
+
);
|
|
217
|
+
return { txHash, amount: stranded };
|
|
218
|
+
}
|
|
219
|
+
async function depositSponsored(input) {
|
|
220
|
+
const { api, chain, wallet, amount } = input;
|
|
221
|
+
const { vault, deploySalt, registerAfterDeposit } = await resolveVault(input);
|
|
222
|
+
const hasInitialDeposit = deploySalt ? false : await chain.hasInitialDeposit(vault, SURFLIQUID_USDC_ADDRESS);
|
|
223
|
+
const morphoVault = hasInitialDeposit ? void 0 : await pickMorphoVault(api);
|
|
224
|
+
const permit = await permitIfShort({ chain, wallet, amount });
|
|
186
225
|
const txHash = await wallet.sendCalls(
|
|
187
226
|
buildDepositCalls({
|
|
188
227
|
smartAccount: wallet.smartAccountAddress,
|
|
228
|
+
owner: wallet.ownerAddress,
|
|
189
229
|
vault,
|
|
190
230
|
amount,
|
|
191
|
-
|
|
231
|
+
permit,
|
|
192
232
|
hasInitialDeposit,
|
|
193
233
|
morphoVault,
|
|
194
234
|
deploySalt
|
|
@@ -222,7 +262,15 @@ async function withdrawSponsored(input) {
|
|
|
222
262
|
if (owner.toLowerCase() !== wallet.smartAccountAddress.toLowerCase()) {
|
|
223
263
|
throw new VaultNotSponsorableError(`SurfLiquid vault ${vault} is not owned by the smart account`);
|
|
224
264
|
}
|
|
225
|
-
|
|
265
|
+
let withdrawHash;
|
|
266
|
+
try {
|
|
267
|
+
withdrawHash = await wallet.sendCalls(buildWithdrawCalls({ vault, amount }));
|
|
268
|
+
} catch (redeemError) {
|
|
269
|
+
const stranded = await chain.usdcBalanceOf(wallet.smartAccountAddress);
|
|
270
|
+
if (stranded === 0n) throw redeemError;
|
|
271
|
+
const sweepHash = await wallet.sendCalls(buildSweepCalls({ owner: wallet.ownerAddress, amount: stranded }));
|
|
272
|
+
return { txHash: sweepHash, amount: stranded.toString() };
|
|
273
|
+
}
|
|
226
274
|
try {
|
|
227
275
|
const proceeds = await chain.usdcBalanceOf(wallet.smartAccountAddress);
|
|
228
276
|
if (proceeds === 0n) return { txHash: withdrawHash, amount: "0" };
|
|
@@ -249,6 +297,8 @@ export {
|
|
|
249
297
|
USDC_ABI,
|
|
250
298
|
SubmittedError,
|
|
251
299
|
VaultNotSponsorableError,
|
|
300
|
+
readStuckBalance,
|
|
301
|
+
sweepStuckBalance,
|
|
252
302
|
depositSponsored,
|
|
253
303
|
withdrawSponsored
|
|
254
304
|
};
|
|
@@ -21,14 +21,6 @@ function buildTransferWithAuthorizationTypedData(input) {
|
|
|
21
21
|
message: input.message
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
function buildReceiveWithAuthorizationTypedData(input) {
|
|
25
|
-
const transfer = buildTransferWithAuthorizationTypedData(input);
|
|
26
|
-
return {
|
|
27
|
-
...transfer,
|
|
28
|
-
types: { ReceiveWithAuthorization: transfer.types.TransferWithAuthorization },
|
|
29
|
-
primaryType: "ReceiveWithAuthorization"
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
24
|
async function readTokenMeta(publicClient, token) {
|
|
33
25
|
const [tokenName, tokenVersion] = await Promise.all([
|
|
34
26
|
publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "name" }),
|
|
@@ -41,10 +33,26 @@ function randomAuthNonce() {
|
|
|
41
33
|
globalThis.crypto.getRandomValues(bytes);
|
|
42
34
|
return bytesToHex(bytes);
|
|
43
35
|
}
|
|
36
|
+
function buildPermitTypedData(input) {
|
|
37
|
+
return {
|
|
38
|
+
domain: { name: input.tokenName, version: input.tokenVersion, chainId: input.chainId, verifyingContract: input.token },
|
|
39
|
+
types: {
|
|
40
|
+
Permit: [
|
|
41
|
+
{ name: "owner", type: "address" },
|
|
42
|
+
{ name: "spender", type: "address" },
|
|
43
|
+
{ name: "value", type: "uint256" },
|
|
44
|
+
{ name: "nonce", type: "uint256" },
|
|
45
|
+
{ name: "deadline", type: "uint256" }
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
primaryType: "Permit",
|
|
49
|
+
message: input.message
|
|
50
|
+
};
|
|
51
|
+
}
|
|
44
52
|
|
|
45
53
|
export {
|
|
46
54
|
buildTransferWithAuthorizationTypedData,
|
|
47
|
-
buildReceiveWithAuthorizationTypedData,
|
|
48
55
|
readTokenMeta,
|
|
49
|
-
randomAuthNonce
|
|
56
|
+
randomAuthNonce,
|
|
57
|
+
buildPermitTypedData
|
|
50
58
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -193,14 +193,6 @@ function buildTransferWithAuthorizationTypedData(input) {
|
|
|
193
193
|
message: input.message
|
|
194
194
|
};
|
|
195
195
|
}
|
|
196
|
-
function buildReceiveWithAuthorizationTypedData(input) {
|
|
197
|
-
const transfer = buildTransferWithAuthorizationTypedData(input);
|
|
198
|
-
return {
|
|
199
|
-
...transfer,
|
|
200
|
-
types: { ReceiveWithAuthorization: transfer.types.TransferWithAuthorization },
|
|
201
|
-
primaryType: "ReceiveWithAuthorization"
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
196
|
async function readTokenMeta(publicClient, token) {
|
|
205
197
|
const [tokenName, tokenVersion] = await Promise.all([
|
|
206
198
|
publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "name" }),
|
|
@@ -213,6 +205,22 @@ function randomAuthNonce() {
|
|
|
213
205
|
globalThis.crypto.getRandomValues(bytes);
|
|
214
206
|
return (0, import_viem3.bytesToHex)(bytes);
|
|
215
207
|
}
|
|
208
|
+
function buildPermitTypedData(input) {
|
|
209
|
+
return {
|
|
210
|
+
domain: { name: input.tokenName, version: input.tokenVersion, chainId: input.chainId, verifyingContract: input.token },
|
|
211
|
+
types: {
|
|
212
|
+
Permit: [
|
|
213
|
+
{ name: "owner", type: "address" },
|
|
214
|
+
{ name: "spender", type: "address" },
|
|
215
|
+
{ name: "value", type: "uint256" },
|
|
216
|
+
{ name: "nonce", type: "uint256" },
|
|
217
|
+
{ name: "deadline", type: "uint256" }
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
primaryType: "Permit",
|
|
221
|
+
message: input.message
|
|
222
|
+
};
|
|
223
|
+
}
|
|
216
224
|
var import_viem3, ERC20_META_ABI;
|
|
217
225
|
var init_transfer_auth = __esm({
|
|
218
226
|
"src/lib/transfer-auth.ts"() {
|
|
@@ -226,13 +234,15 @@ var init_transfer_auth = __esm({
|
|
|
226
234
|
});
|
|
227
235
|
|
|
228
236
|
// src/agents/surfliquid/surfliquid.constants.ts
|
|
229
|
-
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
237
|
+
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_PERMIT_CAP, SURFLIQUID_PERMIT_TTL_SECONDS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
230
238
|
var init_surfliquid_constants = __esm({
|
|
231
239
|
"src/agents/surfliquid/surfliquid.constants.ts"() {
|
|
232
240
|
"use strict";
|
|
233
241
|
SURFLIQUID_CHAIN_ID = 8453;
|
|
234
242
|
SURFLIQUID_CHAIN_NAME = "BASE";
|
|
235
243
|
SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
244
|
+
SURFLIQUID_PERMIT_CAP = 10000000000n;
|
|
245
|
+
SURFLIQUID_PERMIT_TTL_SECONDS = 3600n;
|
|
236
246
|
SURFLIQUID_MIN_DEPOSIT = "0";
|
|
237
247
|
SURFLIQUID_SUPPORTED_ASSETS = [
|
|
238
248
|
{
|
|
@@ -645,20 +655,23 @@ var init_surfliquid_contracts = __esm({
|
|
|
645
655
|
USDC_ABI = (0, import_viem6.parseAbi)([
|
|
646
656
|
"function approve(address spender, uint256 amount)",
|
|
647
657
|
"function transfer(address to, uint256 amount)",
|
|
658
|
+
"function transferFrom(address from, address to, uint256 value)",
|
|
648
659
|
"function balanceOf(address account) view returns (uint256)",
|
|
649
|
-
"function
|
|
660
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
661
|
+
"function nonces(address owner) view returns (uint256)",
|
|
662
|
+
"function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)"
|
|
650
663
|
]);
|
|
651
664
|
}
|
|
652
665
|
});
|
|
653
666
|
|
|
654
667
|
// src/agents/surfliquid/surfliquid.calls.ts
|
|
655
668
|
function buildDepositCalls(input) {
|
|
656
|
-
const { smartAccount, vault, amount,
|
|
657
|
-
if (
|
|
658
|
-
throw new Error("
|
|
669
|
+
const { smartAccount, owner, vault, amount, permit, deploySalt } = input;
|
|
670
|
+
if (permit && permit.owner.toLowerCase() !== owner.toLowerCase()) {
|
|
671
|
+
throw new Error("Permit must be signed by the smart account's owner");
|
|
659
672
|
}
|
|
660
|
-
if (
|
|
661
|
-
throw new Error("
|
|
673
|
+
if (permit && permit.value < amount) {
|
|
674
|
+
throw new Error("Permit allowance is worth less than the deposit");
|
|
662
675
|
}
|
|
663
676
|
if (!input.hasInitialDeposit && !input.morphoVault) {
|
|
664
677
|
throw new Error("A first deposit needs a target morpho vault");
|
|
@@ -672,16 +685,21 @@ function buildDepositCalls(input) {
|
|
|
672
685
|
])
|
|
673
686
|
);
|
|
674
687
|
}
|
|
688
|
+
if (permit) {
|
|
689
|
+
calls.push(
|
|
690
|
+
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "permit", [
|
|
691
|
+
permit.owner,
|
|
692
|
+
smartAccount,
|
|
693
|
+
permit.value,
|
|
694
|
+
permit.deadline,
|
|
695
|
+
permit.v,
|
|
696
|
+
permit.r,
|
|
697
|
+
permit.s
|
|
698
|
+
])
|
|
699
|
+
);
|
|
700
|
+
}
|
|
675
701
|
calls.push(
|
|
676
|
-
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "
|
|
677
|
-
authorization.from,
|
|
678
|
-
authorization.to,
|
|
679
|
-
authorization.value,
|
|
680
|
-
authorization.validAfter,
|
|
681
|
-
authorization.validBefore,
|
|
682
|
-
authorization.nonce,
|
|
683
|
-
authorization.signature
|
|
684
|
-
]),
|
|
702
|
+
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "transferFrom", [owner, smartAccount, amount]),
|
|
685
703
|
call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "approve", [vault, amount]),
|
|
686
704
|
input.hasInitialDeposit ? call(vault, SURFLIQUID_VAULT_ABI, "userDeposit", [SURFLIQUID_USDC_ADDRESS, amount]) : call(vault, SURFLIQUID_VAULT_ABI, "initialDeposit", [
|
|
687
705
|
SURFLIQUID_USDC_ADDRESS,
|
|
@@ -751,22 +769,23 @@ async function pickMorphoVault(api) {
|
|
|
751
769
|
}
|
|
752
770
|
return candidate.vaultAddress;
|
|
753
771
|
}
|
|
754
|
-
async function
|
|
755
|
-
const {
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
const
|
|
759
|
-
|
|
772
|
+
async function permitIfShort(input) {
|
|
773
|
+
const { chain, wallet, amount } = input;
|
|
774
|
+
const allowance = await chain.readAllowance(wallet.ownerAddress, wallet.smartAccountAddress);
|
|
775
|
+
if (allowance >= amount) return void 0;
|
|
776
|
+
const [{ tokenName, tokenVersion }, nonce] = await Promise.all([
|
|
777
|
+
chain.readTokenMeta(),
|
|
778
|
+
chain.readPermitNonce(wallet.ownerAddress)
|
|
779
|
+
]);
|
|
760
780
|
const message = {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
value: amount,
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
nonce: randomAuthNonce()
|
|
781
|
+
owner: wallet.ownerAddress,
|
|
782
|
+
spender: wallet.smartAccountAddress,
|
|
783
|
+
value: amount > SURFLIQUID_PERMIT_CAP ? amount : SURFLIQUID_PERMIT_CAP,
|
|
784
|
+
nonce,
|
|
785
|
+
deadline: BigInt(Math.floor(Date.now() / 1e3)) + SURFLIQUID_PERMIT_TTL_SECONDS
|
|
767
786
|
};
|
|
768
|
-
const signature = await wallet.
|
|
769
|
-
|
|
787
|
+
const signature = await wallet.signPermit(
|
|
788
|
+
buildPermitTypedData({
|
|
770
789
|
token: SURFLIQUID_USDC_ADDRESS,
|
|
771
790
|
chainId: SURFLIQUID_CHAIN_ID,
|
|
772
791
|
tokenName,
|
|
@@ -774,12 +793,40 @@ async function depositSponsored(input) {
|
|
|
774
793
|
message
|
|
775
794
|
})
|
|
776
795
|
);
|
|
796
|
+
const { r, s, v, yParity } = (0, import_viem8.parseSignature)(signature);
|
|
797
|
+
return {
|
|
798
|
+
owner: message.owner,
|
|
799
|
+
value: message.value,
|
|
800
|
+
deadline: message.deadline,
|
|
801
|
+
v: Number(v ?? BigInt(yParity + 27)),
|
|
802
|
+
r,
|
|
803
|
+
s
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
async function readStuckBalance(input) {
|
|
807
|
+
return input.chain.usdcBalanceOf(input.wallet.smartAccountAddress);
|
|
808
|
+
}
|
|
809
|
+
async function sweepStuckBalance(input) {
|
|
810
|
+
const stranded = await readStuckBalance(input);
|
|
811
|
+
if (stranded === 0n) return { amount: 0n };
|
|
812
|
+
const txHash = await input.wallet.sendCalls(
|
|
813
|
+
buildSweepCalls({ owner: input.wallet.ownerAddress, amount: stranded })
|
|
814
|
+
);
|
|
815
|
+
return { txHash, amount: stranded };
|
|
816
|
+
}
|
|
817
|
+
async function depositSponsored(input) {
|
|
818
|
+
const { api, chain, wallet, amount } = input;
|
|
819
|
+
const { vault, deploySalt, registerAfterDeposit } = await resolveVault(input);
|
|
820
|
+
const hasInitialDeposit = deploySalt ? false : await chain.hasInitialDeposit(vault, SURFLIQUID_USDC_ADDRESS);
|
|
821
|
+
const morphoVault = hasInitialDeposit ? void 0 : await pickMorphoVault(api);
|
|
822
|
+
const permit = await permitIfShort({ chain, wallet, amount });
|
|
777
823
|
const txHash = await wallet.sendCalls(
|
|
778
824
|
buildDepositCalls({
|
|
779
825
|
smartAccount: wallet.smartAccountAddress,
|
|
826
|
+
owner: wallet.ownerAddress,
|
|
780
827
|
vault,
|
|
781
828
|
amount,
|
|
782
|
-
|
|
829
|
+
permit,
|
|
783
830
|
hasInitialDeposit,
|
|
784
831
|
morphoVault,
|
|
785
832
|
deploySalt
|
|
@@ -813,7 +860,15 @@ async function withdrawSponsored(input) {
|
|
|
813
860
|
if (owner.toLowerCase() !== wallet.smartAccountAddress.toLowerCase()) {
|
|
814
861
|
throw new VaultNotSponsorableError(`SurfLiquid vault ${vault} is not owned by the smart account`);
|
|
815
862
|
}
|
|
816
|
-
|
|
863
|
+
let withdrawHash;
|
|
864
|
+
try {
|
|
865
|
+
withdrawHash = await wallet.sendCalls(buildWithdrawCalls({ vault, amount }));
|
|
866
|
+
} catch (redeemError) {
|
|
867
|
+
const stranded = await chain.usdcBalanceOf(wallet.smartAccountAddress);
|
|
868
|
+
if (stranded === 0n) throw redeemError;
|
|
869
|
+
const sweepHash = await wallet.sendCalls(buildSweepCalls({ owner: wallet.ownerAddress, amount: stranded }));
|
|
870
|
+
return { txHash: sweepHash, amount: stranded.toString() };
|
|
871
|
+
}
|
|
817
872
|
try {
|
|
818
873
|
const proceeds = await chain.usdcBalanceOf(wallet.smartAccountAddress);
|
|
819
874
|
if (proceeds === 0n) return { txHash: withdrawHash, amount: "0" };
|
|
@@ -827,14 +882,14 @@ async function withdrawSponsored(input) {
|
|
|
827
882
|
);
|
|
828
883
|
}
|
|
829
884
|
}
|
|
830
|
-
var
|
|
885
|
+
var import_viem8, SubmittedError, VaultNotSponsorableError;
|
|
831
886
|
var init_surfliquid_sponsorship = __esm({
|
|
832
887
|
"src/agents/surfliquid/surfliquid.sponsorship.ts"() {
|
|
833
888
|
"use strict";
|
|
889
|
+
import_viem8 = require("viem");
|
|
834
890
|
init_transfer_auth();
|
|
835
891
|
init_surfliquid_constants();
|
|
836
892
|
init_surfliquid_calls();
|
|
837
|
-
AUTHORIZATION_TTL_SECONDS = 3600n;
|
|
838
893
|
SubmittedError = class extends Error {
|
|
839
894
|
constructor(message, userOpHash) {
|
|
840
895
|
super(message);
|
|
@@ -946,7 +1001,7 @@ __export(surfliquid_smart_account_exports, {
|
|
|
946
1001
|
pinAccount: () => pinAccount
|
|
947
1002
|
});
|
|
948
1003
|
function publicClientFor(rpcUrl) {
|
|
949
|
-
return (0,
|
|
1004
|
+
return (0, import_viem9.createPublicClient)({ chain: import_chains2.base, transport: (0, import_viem9.http)(rpcUrl) });
|
|
950
1005
|
}
|
|
951
1006
|
function createSponsoredChain(rpcUrl) {
|
|
952
1007
|
const client = publicClientFor(rpcUrl);
|
|
@@ -976,7 +1031,19 @@ function createSponsoredChain(rpcUrl) {
|
|
|
976
1031
|
}),
|
|
977
1032
|
// Cast: viem's OP-stack tx union does not match the generic PublicClient
|
|
978
1033
|
// the helper is typed against, though every method it uses is present.
|
|
979
|
-
readTokenMeta: () => readTokenMeta(client, SURFLIQUID_USDC_ADDRESS)
|
|
1034
|
+
readTokenMeta: () => readTokenMeta(client, SURFLIQUID_USDC_ADDRESS),
|
|
1035
|
+
readAllowance: (owner, spender) => client.readContract({
|
|
1036
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
1037
|
+
abi: USDC_ABI,
|
|
1038
|
+
functionName: "allowance",
|
|
1039
|
+
args: [owner, spender]
|
|
1040
|
+
}),
|
|
1041
|
+
readPermitNonce: (owner) => client.readContract({
|
|
1042
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
1043
|
+
abi: USDC_ABI,
|
|
1044
|
+
functionName: "nonces",
|
|
1045
|
+
args: [owner]
|
|
1046
|
+
})
|
|
980
1047
|
};
|
|
981
1048
|
}
|
|
982
1049
|
function pinAccount(provider, address) {
|
|
@@ -992,7 +1059,7 @@ async function createSponsoredWallet(input) {
|
|
|
992
1059
|
owner: pinAccount(input.provider, input.ownerAddress),
|
|
993
1060
|
entryPoint
|
|
994
1061
|
});
|
|
995
|
-
const bundlerTransport = (0,
|
|
1062
|
+
const bundlerTransport = (0, import_viem9.http)(sponsorProxyUrl(input.routingApiBaseUrl), {
|
|
996
1063
|
fetchOptions: { headers: { "x-owney-api-key": input.apiKey } }
|
|
997
1064
|
});
|
|
998
1065
|
const pimlico = (0, import_pimlico.createPimlicoClient)({ transport: bundlerTransport, entryPoint });
|
|
@@ -1005,16 +1072,16 @@ async function createSponsoredWallet(input) {
|
|
|
1005
1072
|
estimateFeesPerGas: async () => (await pimlico.getUserOperationGasPrice()).fast
|
|
1006
1073
|
}
|
|
1007
1074
|
});
|
|
1008
|
-
const walletClient = (0,
|
|
1075
|
+
const walletClient = (0, import_viem9.createWalletClient)({
|
|
1009
1076
|
account: input.ownerAddress,
|
|
1010
1077
|
chain: import_chains2.base,
|
|
1011
|
-
transport: (0,
|
|
1078
|
+
transport: (0, import_viem9.custom)(input.provider)
|
|
1012
1079
|
});
|
|
1013
1080
|
return {
|
|
1014
1081
|
smartAccountAddress: account.address,
|
|
1015
1082
|
ownerAddress: input.ownerAddress,
|
|
1016
1083
|
// The EOA signs, not the smart account: USDC verifies ECDSA from the token holder.
|
|
1017
|
-
|
|
1084
|
+
signPermit: (typedData) => walletClient.signTypedData({
|
|
1018
1085
|
account: input.ownerAddress,
|
|
1019
1086
|
domain: typedData.domain,
|
|
1020
1087
|
types: typedData.types,
|
|
@@ -1037,14 +1104,14 @@ async function createSponsoredWallet(input) {
|
|
|
1037
1104
|
}
|
|
1038
1105
|
};
|
|
1039
1106
|
}
|
|
1040
|
-
var import_permissionless, import_accounts, import_pimlico,
|
|
1107
|
+
var import_permissionless, import_accounts, import_pimlico, import_viem9, import_account_abstraction, import_chains2, sponsorProxyUrl;
|
|
1041
1108
|
var init_surfliquid_smart_account = __esm({
|
|
1042
1109
|
"src/agents/surfliquid/surfliquid.smart-account.ts"() {
|
|
1043
1110
|
"use strict";
|
|
1044
1111
|
import_permissionless = require("permissionless");
|
|
1045
1112
|
import_accounts = require("permissionless/accounts");
|
|
1046
1113
|
import_pimlico = require("permissionless/clients/pimlico");
|
|
1047
|
-
|
|
1114
|
+
import_viem9 = require("viem");
|
|
1048
1115
|
import_account_abstraction = require("viem/account-abstraction");
|
|
1049
1116
|
import_chains2 = require("viem/chains");
|
|
1050
1117
|
init_transfer_auth();
|
|
@@ -1075,11 +1142,11 @@ function toOwneyError(error) {
|
|
|
1075
1142
|
}
|
|
1076
1143
|
return new OwneyError("SPONSORSHIP_UNAVAILABLE", message, void 0, AGENT_ID2);
|
|
1077
1144
|
}
|
|
1078
|
-
var
|
|
1145
|
+
var import_viem10, import_chains3, AGENT_ID2, WALLET_REJECTED_CODE, DISCOVERY_WALLET2, HISTORY_DEFAULT_LIMIT, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
1079
1146
|
var init_surfliquid_agent = __esm({
|
|
1080
1147
|
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
1081
1148
|
"use strict";
|
|
1082
|
-
|
|
1149
|
+
import_viem10 = require("viem");
|
|
1083
1150
|
import_chains3 = require("viem/chains");
|
|
1084
1151
|
init_errors();
|
|
1085
1152
|
init_surfliquid_constants();
|
|
@@ -1133,10 +1200,10 @@ var init_surfliquid_agent = __esm({
|
|
|
1133
1200
|
if (this.connectPromise) return this.connectPromise;
|
|
1134
1201
|
this.connectPromise = (async () => {
|
|
1135
1202
|
const message = await broker.nonce();
|
|
1136
|
-
const walletClient = (0,
|
|
1203
|
+
const walletClient = (0, import_viem10.createWalletClient)({
|
|
1137
1204
|
account: state.walletAddress,
|
|
1138
1205
|
chain: import_chains3.base,
|
|
1139
|
-
transport: (0,
|
|
1206
|
+
transport: (0, import_viem10.custom)(state.provider)
|
|
1140
1207
|
});
|
|
1141
1208
|
const signature = await walletClient.signMessage({ account: state.walletAddress, message });
|
|
1142
1209
|
await broker.login(message, signature);
|
|
@@ -1218,6 +1285,24 @@ var init_surfliquid_agent = __esm({
|
|
|
1218
1285
|
throw toOwneyError(error);
|
|
1219
1286
|
}
|
|
1220
1287
|
}
|
|
1288
|
+
/** Funds a prior withdrawal's sweep left in the smart account (never reached the EOA). No session needed — pure read. */
|
|
1289
|
+
async getStuckBalance(state) {
|
|
1290
|
+
const wallet = await this.sponsoredWallet(state);
|
|
1291
|
+
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1292
|
+
const amount = await readStuckBalance({ chain: createSponsoredChain2(this.config.rpcUrl), wallet });
|
|
1293
|
+
return { amount: amount.toString(), smartAccountAddress: wallet.smartAccountAddress };
|
|
1294
|
+
}
|
|
1295
|
+
/** Sweep the stranded balance to the owner's EOA — one sponsored userOp, one signature. */
|
|
1296
|
+
async recoverStuckBalance(state) {
|
|
1297
|
+
const wallet = await this.sponsoredWallet(state);
|
|
1298
|
+
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1299
|
+
try {
|
|
1300
|
+
const { txHash, amount } = await sweepStuckBalance({ chain: createSponsoredChain2(this.config.rpcUrl), wallet });
|
|
1301
|
+
return { txHash, type: "full", amount: amount.toString() };
|
|
1302
|
+
} catch (error) {
|
|
1303
|
+
throw toOwneyError(error);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1221
1306
|
// --- IAgent: portfolio reads ---
|
|
1222
1307
|
async vault(state) {
|
|
1223
1308
|
const broker = await this.connect(state);
|
|
@@ -3481,7 +3566,7 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
3481
3566
|
}
|
|
3482
3567
|
|
|
3483
3568
|
// src/client.ts
|
|
3484
|
-
var
|
|
3569
|
+
var import_viem11 = require("viem");
|
|
3485
3570
|
var import_chains4 = require("viem/chains");
|
|
3486
3571
|
|
|
3487
3572
|
// src/lib/sponsored-deposit.ts
|
|
@@ -4160,14 +4245,14 @@ var OwneySDK = class {
|
|
|
4160
4245
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4161
4246
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4162
4247
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4163
|
-
getPublicClient: (cid) => (0,
|
|
4248
|
+
getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
|
|
4164
4249
|
chain: VIEM_CHAIN2[cid],
|
|
4165
|
-
transport: (0,
|
|
4250
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4166
4251
|
}),
|
|
4167
|
-
getWalletClient: (cid) => (0,
|
|
4252
|
+
getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
|
|
4168
4253
|
account: owner,
|
|
4169
4254
|
chain: VIEM_CHAIN2[cid],
|
|
4170
|
-
transport: (0,
|
|
4255
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4171
4256
|
})
|
|
4172
4257
|
});
|
|
4173
4258
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -4213,14 +4298,14 @@ var OwneySDK = class {
|
|
|
4213
4298
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4214
4299
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4215
4300
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4216
|
-
getPublicClient: (cid) => (0,
|
|
4301
|
+
getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
|
|
4217
4302
|
chain: VIEM_CHAIN2[cid],
|
|
4218
|
-
transport: (0,
|
|
4303
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4219
4304
|
}),
|
|
4220
|
-
getWalletClient: (cid) => (0,
|
|
4305
|
+
getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
|
|
4221
4306
|
account: owner,
|
|
4222
4307
|
chain: VIEM_CHAIN2[cid],
|
|
4223
|
-
transport: (0,
|
|
4308
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4224
4309
|
})
|
|
4225
4310
|
});
|
|
4226
4311
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -4979,6 +5064,31 @@ var OwneySDK = class {
|
|
|
4979
5064
|
}
|
|
4980
5065
|
return { agentResult: results, totalWithdrawn: withdrawn.toString() };
|
|
4981
5066
|
}
|
|
5067
|
+
/**
|
|
5068
|
+
* Funds a prior withdrawal left stranded in the agent's smart account (the
|
|
5069
|
+
* payout leg never reached the owner's EOA). Read-only — check once after
|
|
5070
|
+
* connect. Agents without a smart account model report "0".
|
|
5071
|
+
*/
|
|
5072
|
+
async getStuckBalance(agentId) {
|
|
5073
|
+
const state = this.requireState();
|
|
5074
|
+
const chainId = this.requireChainId();
|
|
5075
|
+
const agent = this.getAgent(agentId);
|
|
5076
|
+
if (!agent.getStuckBalance) return { amount: "0", smartAccountAddress: "" };
|
|
5077
|
+
return agent.getStuckBalance(state, chainId);
|
|
5078
|
+
}
|
|
5079
|
+
/** Sweep that stranded balance to the owner's EOA — one signature. No-op ("0") when nothing is stuck. */
|
|
5080
|
+
async recoverStuckBalance(agentId) {
|
|
5081
|
+
const state = this.requireState();
|
|
5082
|
+
const chainId = this.requireChainId();
|
|
5083
|
+
const agent = this.getAgent(agentId);
|
|
5084
|
+
if (!agent.recoverStuckBalance) return { type: "full", amount: "0" };
|
|
5085
|
+
return withFailureReporting(
|
|
5086
|
+
this.apiKey,
|
|
5087
|
+
agent.id,
|
|
5088
|
+
() => agent.recoverStuckBalance(state, chainId),
|
|
5089
|
+
this.routingApiBaseUrl
|
|
5090
|
+
);
|
|
5091
|
+
}
|
|
4982
5092
|
// --- Portfolio reads ---
|
|
4983
5093
|
/**
|
|
4984
5094
|
* Get the user's balances for a specific agent, or aggregated across all agents.
|
|
@@ -5314,10 +5424,10 @@ var OwneySDK = class {
|
|
|
5314
5424
|
);
|
|
5315
5425
|
}
|
|
5316
5426
|
const provider = this.requireConnectedProvider();
|
|
5317
|
-
const wallet = (0,
|
|
5427
|
+
const wallet = (0, import_viem11.createWalletClient)({
|
|
5318
5428
|
account: state.walletAddress,
|
|
5319
5429
|
chain: VIEM_CHAIN2[chainId],
|
|
5320
|
-
transport: (0,
|
|
5430
|
+
transport: (0, import_viem11.custom)(provider)
|
|
5321
5431
|
});
|
|
5322
5432
|
const hash = await wallet.writeContract({
|
|
5323
5433
|
address: token,
|
|
@@ -5327,9 +5437,9 @@ var OwneySDK = class {
|
|
|
5327
5437
|
account: state.walletAddress,
|
|
5328
5438
|
chain: VIEM_CHAIN2[chainId]
|
|
5329
5439
|
});
|
|
5330
|
-
const publicClient = (0,
|
|
5440
|
+
const publicClient = (0, import_viem11.createPublicClient)({
|
|
5331
5441
|
chain: VIEM_CHAIN2[chainId],
|
|
5332
|
-
transport: (0,
|
|
5442
|
+
transport: (0, import_viem11.custom)(provider)
|
|
5333
5443
|
});
|
|
5334
5444
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
5335
5445
|
hash,
|
|
@@ -5445,7 +5555,7 @@ init_errors();
|
|
|
5445
5555
|
init_debug();
|
|
5446
5556
|
|
|
5447
5557
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
5448
|
-
var
|
|
5558
|
+
var import_viem12 = require("viem");
|
|
5449
5559
|
var import_siwe = require("siwe");
|
|
5450
5560
|
var import_sdk2 = require("@zyfai/sdk");
|
|
5451
5561
|
|
|
@@ -5572,7 +5682,7 @@ function buildSIWXConfig(deps) {
|
|
|
5572
5682
|
issuedAt,
|
|
5573
5683
|
toString() {
|
|
5574
5684
|
return new import_siwe.SiweMessage({
|
|
5575
|
-
address: (0,
|
|
5685
|
+
address: (0, import_viem12.getAddress)(accountAddress),
|
|
5576
5686
|
chainId: numericChainId(chainId),
|
|
5577
5687
|
domain,
|
|
5578
5688
|
uri,
|
package/dist/index.d.cts
CHANGED
|
@@ -195,6 +195,13 @@ interface AgentWithdrawResult {
|
|
|
195
195
|
/** Smallest-unit amount, or a provider sentinel such as "all" for a full request. */
|
|
196
196
|
amount: string;
|
|
197
197
|
}
|
|
198
|
+
/** Funds a prior withdrawal left in the agent's smart account, awaiting recovery to the owner's EOA. */
|
|
199
|
+
interface AgentStuckBalance {
|
|
200
|
+
/** Smallest-unit amount stuck in the smart account; "0" when nothing is stuck. */
|
|
201
|
+
amount: string;
|
|
202
|
+
/** The smart account holding the funds (for display / on-chain verification). */
|
|
203
|
+
smartAccountAddress: string;
|
|
204
|
+
}
|
|
198
205
|
interface OwneyWithdrawResult {
|
|
199
206
|
agentResult: Record<AgentId, AgentWithdrawResult>;
|
|
200
207
|
/**
|
|
@@ -446,6 +453,14 @@ interface IAgent {
|
|
|
446
453
|
* a write occurred (`false` = already enabled / not supported).
|
|
447
454
|
*/
|
|
448
455
|
ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
|
|
456
|
+
/**
|
|
457
|
+
* Read funds a prior withdrawal left stranded in the agent's smart account
|
|
458
|
+
* (the payout leg never reached the owner's EOA). Optional capability — only
|
|
459
|
+
* agents with a per-user smart account model this. Checked once after connect.
|
|
460
|
+
*/
|
|
461
|
+
getStuckBalance?(state: ConnectionState, chainId: number): Promise<AgentStuckBalance>;
|
|
462
|
+
/** Sweep that stranded balance to the owner's EOA. No-op (amount "0") when nothing is stuck. */
|
|
463
|
+
recoverStuckBalance?(state: ConnectionState, chainId: number): Promise<AgentWithdrawResult>;
|
|
449
464
|
getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
|
|
450
465
|
}
|
|
451
466
|
/**
|
|
@@ -656,6 +671,14 @@ declare class OwneySDK {
|
|
|
656
671
|
* @returns {AgentWithdrawResult} for a single agent, or {OwneyWithdrawResult} with per-agent results
|
|
657
672
|
*/
|
|
658
673
|
withdraw(options: WithdrawOptions): Promise<OwneyWithdrawResult | AgentWithdrawResult>;
|
|
674
|
+
/**
|
|
675
|
+
* Funds a prior withdrawal left stranded in the agent's smart account (the
|
|
676
|
+
* payout leg never reached the owner's EOA). Read-only — check once after
|
|
677
|
+
* connect. Agents without a smart account model report "0".
|
|
678
|
+
*/
|
|
679
|
+
getStuckBalance(agentId: AgentId): Promise<AgentStuckBalance>;
|
|
680
|
+
/** Sweep that stranded balance to the owner's EOA — one signature. No-op ("0") when nothing is stuck. */
|
|
681
|
+
recoverStuckBalance(agentId: AgentId): Promise<AgentWithdrawResult>;
|
|
659
682
|
/**
|
|
660
683
|
* Get the user's balances for a specific agent, or aggregated across all agents.
|
|
661
684
|
* @param agentId - Optional. Agent to query. Omit for aggregated balances.
|
|
@@ -812,4 +835,4 @@ type OwneySIWXConfig = {
|
|
|
812
835
|
*/
|
|
813
836
|
declare function createOwneySIWX(config: OwneySIWXConfig): SIWXConfig;
|
|
814
837
|
|
|
815
|
-
export { type AccountAgentApy, type AccountApyOptions, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type RebalanceLog, type WithdrawOptions, createOwneySIWX, setOwneyDebug };
|
|
838
|
+
export { type AccountAgentApy, type AccountApyOptions, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentStuckBalance, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type RebalanceLog, type WithdrawOptions, createOwneySIWX, setOwneyDebug };
|
package/dist/index.d.ts
CHANGED
|
@@ -195,6 +195,13 @@ interface AgentWithdrawResult {
|
|
|
195
195
|
/** Smallest-unit amount, or a provider sentinel such as "all" for a full request. */
|
|
196
196
|
amount: string;
|
|
197
197
|
}
|
|
198
|
+
/** Funds a prior withdrawal left in the agent's smart account, awaiting recovery to the owner's EOA. */
|
|
199
|
+
interface AgentStuckBalance {
|
|
200
|
+
/** Smallest-unit amount stuck in the smart account; "0" when nothing is stuck. */
|
|
201
|
+
amount: string;
|
|
202
|
+
/** The smart account holding the funds (for display / on-chain verification). */
|
|
203
|
+
smartAccountAddress: string;
|
|
204
|
+
}
|
|
198
205
|
interface OwneyWithdrawResult {
|
|
199
206
|
agentResult: Record<AgentId, AgentWithdrawResult>;
|
|
200
207
|
/**
|
|
@@ -446,6 +453,14 @@ interface IAgent {
|
|
|
446
453
|
* a write occurred (`false` = already enabled / not supported).
|
|
447
454
|
*/
|
|
448
455
|
ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
|
|
456
|
+
/**
|
|
457
|
+
* Read funds a prior withdrawal left stranded in the agent's smart account
|
|
458
|
+
* (the payout leg never reached the owner's EOA). Optional capability — only
|
|
459
|
+
* agents with a per-user smart account model this. Checked once after connect.
|
|
460
|
+
*/
|
|
461
|
+
getStuckBalance?(state: ConnectionState, chainId: number): Promise<AgentStuckBalance>;
|
|
462
|
+
/** Sweep that stranded balance to the owner's EOA. No-op (amount "0") when nothing is stuck. */
|
|
463
|
+
recoverStuckBalance?(state: ConnectionState, chainId: number): Promise<AgentWithdrawResult>;
|
|
449
464
|
getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
|
|
450
465
|
}
|
|
451
466
|
/**
|
|
@@ -656,6 +671,14 @@ declare class OwneySDK {
|
|
|
656
671
|
* @returns {AgentWithdrawResult} for a single agent, or {OwneyWithdrawResult} with per-agent results
|
|
657
672
|
*/
|
|
658
673
|
withdraw(options: WithdrawOptions): Promise<OwneyWithdrawResult | AgentWithdrawResult>;
|
|
674
|
+
/**
|
|
675
|
+
* Funds a prior withdrawal left stranded in the agent's smart account (the
|
|
676
|
+
* payout leg never reached the owner's EOA). Read-only — check once after
|
|
677
|
+
* connect. Agents without a smart account model report "0".
|
|
678
|
+
*/
|
|
679
|
+
getStuckBalance(agentId: AgentId): Promise<AgentStuckBalance>;
|
|
680
|
+
/** Sweep that stranded balance to the owner's EOA — one signature. No-op ("0") when nothing is stuck. */
|
|
681
|
+
recoverStuckBalance(agentId: AgentId): Promise<AgentWithdrawResult>;
|
|
659
682
|
/**
|
|
660
683
|
* Get the user's balances for a specific agent, or aggregated across all agents.
|
|
661
684
|
* @param agentId - Optional. Agent to query. Omit for aggregated balances.
|
|
@@ -812,4 +835,4 @@ type OwneySIWXConfig = {
|
|
|
812
835
|
*/
|
|
813
836
|
declare function createOwneySIWX(config: OwneySIWXConfig): SIWXConfig;
|
|
814
837
|
|
|
815
|
-
export { type AccountAgentApy, type AccountApyOptions, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type RebalanceLog, type WithdrawOptions, createOwneySIWX, setOwneyDebug };
|
|
838
|
+
export { type AccountAgentApy, type AccountApyOptions, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentStuckBalance, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type RebalanceLog, type WithdrawOptions, createOwneySIWX, setOwneyDebug };
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
buildTransferWithAuthorizationTypedData,
|
|
13
13
|
randomAuthNonce,
|
|
14
14
|
readTokenMeta
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-AURO3C3R.js";
|
|
16
16
|
|
|
17
17
|
// src/lib/rate-limit.ts
|
|
18
18
|
function rateLimitDelay(error, now = Date.now()) {
|
|
@@ -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-E54CPWXF.js");
|
|
3040
3040
|
return new SurfLiquidAgent({
|
|
3041
3041
|
apiKey: this.apiKey,
|
|
3042
3042
|
routingApiBaseUrl: this.routingApiBaseUrl
|
|
@@ -3691,6 +3691,31 @@ var OwneySDK = class {
|
|
|
3691
3691
|
}
|
|
3692
3692
|
return { agentResult: results, totalWithdrawn: withdrawn.toString() };
|
|
3693
3693
|
}
|
|
3694
|
+
/**
|
|
3695
|
+
* Funds a prior withdrawal left stranded in the agent's smart account (the
|
|
3696
|
+
* payout leg never reached the owner's EOA). Read-only — check once after
|
|
3697
|
+
* connect. Agents without a smart account model report "0".
|
|
3698
|
+
*/
|
|
3699
|
+
async getStuckBalance(agentId) {
|
|
3700
|
+
const state = this.requireState();
|
|
3701
|
+
const chainId = this.requireChainId();
|
|
3702
|
+
const agent = this.getAgent(agentId);
|
|
3703
|
+
if (!agent.getStuckBalance) return { amount: "0", smartAccountAddress: "" };
|
|
3704
|
+
return agent.getStuckBalance(state, chainId);
|
|
3705
|
+
}
|
|
3706
|
+
/** Sweep that stranded balance to the owner's EOA — one signature. No-op ("0") when nothing is stuck. */
|
|
3707
|
+
async recoverStuckBalance(agentId) {
|
|
3708
|
+
const state = this.requireState();
|
|
3709
|
+
const chainId = this.requireChainId();
|
|
3710
|
+
const agent = this.getAgent(agentId);
|
|
3711
|
+
if (!agent.recoverStuckBalance) return { type: "full", amount: "0" };
|
|
3712
|
+
return withFailureReporting(
|
|
3713
|
+
this.apiKey,
|
|
3714
|
+
agent.id,
|
|
3715
|
+
() => agent.recoverStuckBalance(state, chainId),
|
|
3716
|
+
this.routingApiBaseUrl
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3694
3719
|
// --- Portfolio reads ---
|
|
3695
3720
|
/**
|
|
3696
3721
|
* Get the user's balances for a specific agent, or aggregated across all agents.
|
|
@@ -10,9 +10,11 @@ import {
|
|
|
10
10
|
SubmittedError,
|
|
11
11
|
VaultNotSponsorableError,
|
|
12
12
|
depositSponsored,
|
|
13
|
+
readStuckBalance,
|
|
14
|
+
sweepStuckBalance,
|
|
13
15
|
withdrawSponsored
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-5W56YOBO.js";
|
|
17
|
+
import "./chunk-AURO3C3R.js";
|
|
16
18
|
|
|
17
19
|
// src/agents/surfliquid/surfliquid.agent.ts
|
|
18
20
|
import { createWalletClient, custom } from "viem";
|
|
@@ -533,7 +535,7 @@ var SurfLiquidAgent = class {
|
|
|
533
535
|
}
|
|
534
536
|
}
|
|
535
537
|
async sponsoredWallet(state) {
|
|
536
|
-
const { createSponsoredWallet } = await import("./surfliquid.smart-account-
|
|
538
|
+
const { createSponsoredWallet } = await import("./surfliquid.smart-account-O6YPCQT3.js");
|
|
537
539
|
return createSponsoredWallet({
|
|
538
540
|
provider: state.provider,
|
|
539
541
|
ownerAddress: state.walletAddress,
|
|
@@ -555,7 +557,7 @@ var SurfLiquidAgent = class {
|
|
|
555
557
|
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
556
558
|
const broker = await this.connect(state);
|
|
557
559
|
const wallet = await this.sponsoredWallet(state);
|
|
558
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
560
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
|
|
559
561
|
try {
|
|
560
562
|
const { txHash, vault } = await this.withSession(
|
|
561
563
|
state,
|
|
@@ -570,7 +572,7 @@ var SurfLiquidAgent = class {
|
|
|
570
572
|
async withdraw(state, _chainId, _token, amount) {
|
|
571
573
|
const broker = await this.connect(state);
|
|
572
574
|
const wallet = await this.sponsoredWallet(state);
|
|
573
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
575
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
|
|
574
576
|
try {
|
|
575
577
|
const result = await this.withSession(
|
|
576
578
|
state,
|
|
@@ -587,6 +589,24 @@ var SurfLiquidAgent = class {
|
|
|
587
589
|
throw toOwneyError(error);
|
|
588
590
|
}
|
|
589
591
|
}
|
|
592
|
+
/** Funds a prior withdrawal's sweep left in the smart account (never reached the EOA). No session needed — pure read. */
|
|
593
|
+
async getStuckBalance(state) {
|
|
594
|
+
const wallet = await this.sponsoredWallet(state);
|
|
595
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
|
|
596
|
+
const amount = await readStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
597
|
+
return { amount: amount.toString(), smartAccountAddress: wallet.smartAccountAddress };
|
|
598
|
+
}
|
|
599
|
+
/** Sweep the stranded balance to the owner's EOA — one sponsored userOp, one signature. */
|
|
600
|
+
async recoverStuckBalance(state) {
|
|
601
|
+
const wallet = await this.sponsoredWallet(state);
|
|
602
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-O6YPCQT3.js");
|
|
603
|
+
try {
|
|
604
|
+
const { txHash, amount } = await sweepStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
605
|
+
return { txHash, type: "full", amount: amount.toString() };
|
|
606
|
+
} catch (error) {
|
|
607
|
+
throw toOwneyError(error);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
590
610
|
// --- IAgent: portfolio reads ---
|
|
591
611
|
async vault(state) {
|
|
592
612
|
const broker = await this.connect(state);
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
SURFLIQUID_VAULT_ABI,
|
|
7
7
|
SubmittedError,
|
|
8
8
|
USDC_ABI
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5W56YOBO.js";
|
|
10
10
|
import {
|
|
11
11
|
readTokenMeta
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AURO3C3R.js";
|
|
13
13
|
|
|
14
14
|
// src/agents/surfliquid/surfliquid.smart-account.ts
|
|
15
15
|
import { createSmartAccountClient } from "permissionless";
|
|
@@ -55,7 +55,19 @@ function createSponsoredChain(rpcUrl) {
|
|
|
55
55
|
}),
|
|
56
56
|
// Cast: viem's OP-stack tx union does not match the generic PublicClient
|
|
57
57
|
// the helper is typed against, though every method it uses is present.
|
|
58
|
-
readTokenMeta: () => readTokenMeta(client, SURFLIQUID_USDC_ADDRESS)
|
|
58
|
+
readTokenMeta: () => readTokenMeta(client, SURFLIQUID_USDC_ADDRESS),
|
|
59
|
+
readAllowance: (owner, spender) => client.readContract({
|
|
60
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
61
|
+
abi: USDC_ABI,
|
|
62
|
+
functionName: "allowance",
|
|
63
|
+
args: [owner, spender]
|
|
64
|
+
}),
|
|
65
|
+
readPermitNonce: (owner) => client.readContract({
|
|
66
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
67
|
+
abi: USDC_ABI,
|
|
68
|
+
functionName: "nonces",
|
|
69
|
+
args: [owner]
|
|
70
|
+
})
|
|
59
71
|
};
|
|
60
72
|
}
|
|
61
73
|
function pinAccount(provider, address) {
|
|
@@ -93,7 +105,7 @@ async function createSponsoredWallet(input) {
|
|
|
93
105
|
smartAccountAddress: account.address,
|
|
94
106
|
ownerAddress: input.ownerAddress,
|
|
95
107
|
// The EOA signs, not the smart account: USDC verifies ECDSA from the token holder.
|
|
96
|
-
|
|
108
|
+
signPermit: (typedData) => walletClient.signTypedData({
|
|
97
109
|
account: input.ownerAddress,
|
|
98
110
|
domain: typedData.domain,
|
|
99
111
|
types: typedData.types,
|