@owney/sdk 0.6.9-beta.6 → 0.6.9-beta.7
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-PWIKIQOX.js +140 -0
- package/dist/index.cjs +157 -90
- package/dist/index.js +10 -81
- package/dist/{surfliquid.agent-OMOYXWLP.js → surfliquid.agent-JOJJ3C5Y.js} +65 -2
- package/package.json +1 -1
- package/dist/chunk-GMNQBWUB.js +0 -55
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var OwneyError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
details;
|
|
5
|
+
agentId;
|
|
6
|
+
constructor(code, message, details, agentId) {
|
|
7
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
8
|
+
super(`${prefix} ${message}`);
|
|
9
|
+
this.name = "OwneyError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.details = details;
|
|
12
|
+
this.agentId = agentId;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
16
|
+
constructor(agentId, available) {
|
|
17
|
+
super(
|
|
18
|
+
"AGENT_NOT_FOUND",
|
|
19
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
20
|
+
{ agentId, available },
|
|
21
|
+
agentId
|
|
22
|
+
);
|
|
23
|
+
this.name = "AgentNotFoundError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var NotConnectedError = class extends OwneyError {
|
|
27
|
+
constructor() {
|
|
28
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
29
|
+
this.name = "NotConnectedError";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
33
|
+
incompatibleAgents;
|
|
34
|
+
connectedChainId;
|
|
35
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
36
|
+
const details = incompatibleAgents.map(
|
|
37
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
38
|
+
).join("; ");
|
|
39
|
+
super(
|
|
40
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
41
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
42
|
+
{ incompatibleAgents, connectedChainId }
|
|
43
|
+
);
|
|
44
|
+
this.name = "AgentChainIncompatibleError";
|
|
45
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
46
|
+
this.connectedChainId = connectedChainId;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/lib/permit2.ts
|
|
51
|
+
import { bytesToHex } from "viem";
|
|
52
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
53
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
54
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
55
|
+
{
|
|
56
|
+
type: "function",
|
|
57
|
+
name: "allowance",
|
|
58
|
+
stateMutability: "view",
|
|
59
|
+
inputs: [
|
|
60
|
+
{ name: "owner", type: "address" },
|
|
61
|
+
{ name: "spender", type: "address" }
|
|
62
|
+
],
|
|
63
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: "function",
|
|
67
|
+
name: "approve",
|
|
68
|
+
stateMutability: "nonpayable",
|
|
69
|
+
inputs: [
|
|
70
|
+
{ name: "spender", type: "address" },
|
|
71
|
+
{ name: "amount", type: "uint256" }
|
|
72
|
+
],
|
|
73
|
+
outputs: [{ name: "", type: "bool" }]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: "function",
|
|
77
|
+
name: "balanceOf",
|
|
78
|
+
stateMutability: "view",
|
|
79
|
+
inputs: [{ name: "account", type: "address" }],
|
|
80
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
function buildPermitTransferFromTypedData(input) {
|
|
84
|
+
return {
|
|
85
|
+
domain: {
|
|
86
|
+
name: "Permit2",
|
|
87
|
+
chainId: input.chainId,
|
|
88
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
89
|
+
},
|
|
90
|
+
types: {
|
|
91
|
+
PermitTransferFrom: [
|
|
92
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
93
|
+
{ name: "spender", type: "address" },
|
|
94
|
+
{ name: "nonce", type: "uint256" },
|
|
95
|
+
{ name: "deadline", type: "uint256" }
|
|
96
|
+
],
|
|
97
|
+
TokenPermissions: [
|
|
98
|
+
{ name: "token", type: "address" },
|
|
99
|
+
{ name: "amount", type: "uint256" }
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
primaryType: "PermitTransferFrom",
|
|
103
|
+
message: input.message
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function randomPermit2Nonce() {
|
|
107
|
+
const bytes = new Uint8Array(32);
|
|
108
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
109
|
+
return BigInt(bytesToHex(bytes));
|
|
110
|
+
}
|
|
111
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
112
|
+
return publicClient.readContract({
|
|
113
|
+
address: token,
|
|
114
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
115
|
+
functionName: "allowance",
|
|
116
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
120
|
+
return publicClient.readContract({
|
|
121
|
+
address: token,
|
|
122
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
123
|
+
functionName: "balanceOf",
|
|
124
|
+
args: [owner]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
OwneyError,
|
|
130
|
+
AgentNotFoundError,
|
|
131
|
+
NotConnectedError,
|
|
132
|
+
AgentChainIncompatibleError,
|
|
133
|
+
PERMIT2_ADDRESS,
|
|
134
|
+
MAX_UINT256,
|
|
135
|
+
ERC20_ALLOWANCE_ABI,
|
|
136
|
+
buildPermitTransferFromTypedData,
|
|
137
|
+
randomPermit2Nonce,
|
|
138
|
+
readPermit2Allowance,
|
|
139
|
+
readErc20Balance
|
|
140
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -80,8 +80,92 @@ var init_errors = __esm({
|
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
// src/lib/permit2.ts
|
|
84
|
+
function buildPermitTransferFromTypedData(input) {
|
|
85
|
+
return {
|
|
86
|
+
domain: {
|
|
87
|
+
name: "Permit2",
|
|
88
|
+
chainId: input.chainId,
|
|
89
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
90
|
+
},
|
|
91
|
+
types: {
|
|
92
|
+
PermitTransferFrom: [
|
|
93
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
94
|
+
{ name: "spender", type: "address" },
|
|
95
|
+
{ name: "nonce", type: "uint256" },
|
|
96
|
+
{ name: "deadline", type: "uint256" }
|
|
97
|
+
],
|
|
98
|
+
TokenPermissions: [
|
|
99
|
+
{ name: "token", type: "address" },
|
|
100
|
+
{ name: "amount", type: "uint256" }
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
primaryType: "PermitTransferFrom",
|
|
104
|
+
message: input.message
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function randomPermit2Nonce() {
|
|
108
|
+
const bytes = new Uint8Array(32);
|
|
109
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
110
|
+
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
111
|
+
}
|
|
112
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
113
|
+
return publicClient.readContract({
|
|
114
|
+
address: token,
|
|
115
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
116
|
+
functionName: "allowance",
|
|
117
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
121
|
+
return publicClient.readContract({
|
|
122
|
+
address: token,
|
|
123
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
124
|
+
functionName: "balanceOf",
|
|
125
|
+
args: [owner]
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
var import_viem4, PERMIT2_ADDRESS, MAX_UINT256, ERC20_ALLOWANCE_ABI;
|
|
129
|
+
var init_permit2 = __esm({
|
|
130
|
+
"src/lib/permit2.ts"() {
|
|
131
|
+
"use strict";
|
|
132
|
+
import_viem4 = require("viem");
|
|
133
|
+
PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
134
|
+
MAX_UINT256 = 2n ** 256n - 1n;
|
|
135
|
+
ERC20_ALLOWANCE_ABI = [
|
|
136
|
+
{
|
|
137
|
+
type: "function",
|
|
138
|
+
name: "allowance",
|
|
139
|
+
stateMutability: "view",
|
|
140
|
+
inputs: [
|
|
141
|
+
{ name: "owner", type: "address" },
|
|
142
|
+
{ name: "spender", type: "address" }
|
|
143
|
+
],
|
|
144
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
type: "function",
|
|
148
|
+
name: "approve",
|
|
149
|
+
stateMutability: "nonpayable",
|
|
150
|
+
inputs: [
|
|
151
|
+
{ name: "spender", type: "address" },
|
|
152
|
+
{ name: "amount", type: "uint256" }
|
|
153
|
+
],
|
|
154
|
+
outputs: [{ name: "", type: "bool" }]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
type: "function",
|
|
158
|
+
name: "balanceOf",
|
|
159
|
+
stateMutability: "view",
|
|
160
|
+
inputs: [{ name: "account", type: "address" }],
|
|
161
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
162
|
+
}
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
83
167
|
// src/agents/surfliquid/surfliquid.constants.ts
|
|
84
|
-
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_USDC_DECIMALS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
168
|
+
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_USDC_DECIMALS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_APPROVAL_TARGET, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
85
169
|
var init_surfliquid_constants = __esm({
|
|
86
170
|
"src/agents/surfliquid/surfliquid.constants.ts"() {
|
|
87
171
|
"use strict";
|
|
@@ -90,6 +174,7 @@ var init_surfliquid_constants = __esm({
|
|
|
90
174
|
SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
91
175
|
SURFLIQUID_USDC_DECIMALS = 6;
|
|
92
176
|
SURFLIQUID_MIN_DEPOSIT = "0";
|
|
177
|
+
SURFLIQUID_APPROVAL_TARGET = 100000000000n;
|
|
93
178
|
SURFLIQUID_SUPPORTED_ASSETS = [
|
|
94
179
|
{
|
|
95
180
|
chainId: SURFLIQUID_CHAIN_ID,
|
|
@@ -314,14 +399,16 @@ var surfliquid_agent_exports = {};
|
|
|
314
399
|
__export(surfliquid_agent_exports, {
|
|
315
400
|
SurfLiquidAgent: () => SurfLiquidAgent
|
|
316
401
|
});
|
|
317
|
-
var import_core_sdk2, import_viem5, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
402
|
+
var import_core_sdk2, import_viem5, import_chains2, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
318
403
|
var init_surfliquid_agent = __esm({
|
|
319
404
|
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
320
405
|
"use strict";
|
|
321
406
|
import_core_sdk2 = require("@surf_liquid/core-sdk");
|
|
322
407
|
import_viem5 = require("viem");
|
|
408
|
+
import_chains2 = require("viem/chains");
|
|
323
409
|
init_errors();
|
|
324
410
|
init_surfliquid_constants();
|
|
411
|
+
init_permit2();
|
|
325
412
|
init_surfliquid_mapper();
|
|
326
413
|
init_surfliquid_wallet_adapter();
|
|
327
414
|
init_surfliquid_morpho();
|
|
@@ -397,6 +484,60 @@ var init_surfliquid_agent = __esm({
|
|
|
397
484
|
const { vaultAddress } = await surf.deployVault();
|
|
398
485
|
return vaultAddress;
|
|
399
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Grants the user's vault a standing USDC allowance so SurfLiquid's
|
|
489
|
+
* `autoApprove` has nothing to do — see {@link SURFLIQUID_APPROVAL_TARGET}
|
|
490
|
+
* for why one prompt per deposit is worth removing.
|
|
491
|
+
*
|
|
492
|
+
* Fails OPEN on a read error: if the allowance can't be checked we simply
|
|
493
|
+
* return and let SurfLiquid's own per-deposit approve run, because a flaky
|
|
494
|
+
* RPC must never block a deposit. A failed or rejected APPROVE does
|
|
495
|
+
* propagate — the user declined a transaction, and letting SurfLiquid
|
|
496
|
+
* immediately ask again for a smaller one is exactly the double prompt this
|
|
497
|
+
* removes.
|
|
498
|
+
*/
|
|
499
|
+
async ensureVaultAllowance(state, vaultAddress, amount) {
|
|
500
|
+
const spender = vaultAddress;
|
|
501
|
+
const transport = (0, import_viem5.custom)(state.provider);
|
|
502
|
+
const publicClient = (0, import_viem5.createPublicClient)({ chain: import_chains2.base, transport });
|
|
503
|
+
let allowance;
|
|
504
|
+
try {
|
|
505
|
+
allowance = await publicClient.readContract({
|
|
506
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
507
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
508
|
+
functionName: "allowance",
|
|
509
|
+
args: [state.walletAddress, spender]
|
|
510
|
+
});
|
|
511
|
+
} catch (error) {
|
|
512
|
+
console.warn(
|
|
513
|
+
"[owney-sdk] SurfLiquid allowance pre-check failed; deferring to its per-deposit approve:",
|
|
514
|
+
error instanceof Error ? error.message : String(error)
|
|
515
|
+
);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (allowance >= amount) return;
|
|
519
|
+
const target = amount > SURFLIQUID_APPROVAL_TARGET ? amount : SURFLIQUID_APPROVAL_TARGET;
|
|
520
|
+
const wallet = (0, import_viem5.createWalletClient)({
|
|
521
|
+
account: state.walletAddress,
|
|
522
|
+
chain: import_chains2.base,
|
|
523
|
+
transport
|
|
524
|
+
});
|
|
525
|
+
const hash = await wallet.writeContract({
|
|
526
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
527
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
528
|
+
functionName: "approve",
|
|
529
|
+
args: [spender, target],
|
|
530
|
+
account: state.walletAddress,
|
|
531
|
+
chain: import_chains2.base
|
|
532
|
+
});
|
|
533
|
+
const receipt = await publicClient.waitForTransactionReceipt({
|
|
534
|
+
hash,
|
|
535
|
+
confirmations: 1
|
|
536
|
+
});
|
|
537
|
+
if (receipt.status !== "success") {
|
|
538
|
+
throw new Error(`SurfLiquid USDC approval reverted (tx ${hash})`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
400
541
|
// --- IAgent: lifecycle ---
|
|
401
542
|
async disconnect() {
|
|
402
543
|
if (this.surf) {
|
|
@@ -415,6 +556,7 @@ var init_surfliquid_agent = __esm({
|
|
|
415
556
|
surf,
|
|
416
557
|
state.walletAddress
|
|
417
558
|
);
|
|
559
|
+
await this.ensureVaultAllowance(state, smartWallet, BigInt(amount));
|
|
418
560
|
const tx = await surf.deposit({
|
|
419
561
|
asset: SURFLIQUID_USDC_ADDRESS,
|
|
420
562
|
amount: human
|
|
@@ -2170,7 +2312,7 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
2170
2312
|
|
|
2171
2313
|
// src/client.ts
|
|
2172
2314
|
var import_viem6 = require("viem");
|
|
2173
|
-
var
|
|
2315
|
+
var import_chains3 = require("viem/chains");
|
|
2174
2316
|
|
|
2175
2317
|
// src/lib/sponsored-deposit.ts
|
|
2176
2318
|
init_errors();
|
|
@@ -2215,10 +2357,10 @@ function randomAuthNonce() {
|
|
|
2215
2357
|
init_errors();
|
|
2216
2358
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2217
2359
|
async function postSponsorTransferAuth(input) {
|
|
2218
|
-
const
|
|
2360
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2219
2361
|
let res;
|
|
2220
2362
|
try {
|
|
2221
|
-
res = await fetch(`${
|
|
2363
|
+
res = await fetch(`${base4}/api/v1/sponsor/erc20-transfer-auth`, {
|
|
2222
2364
|
method: "POST",
|
|
2223
2365
|
headers: {
|
|
2224
2366
|
"content-type": "application/json",
|
|
@@ -2255,10 +2397,10 @@ async function postSponsorTransferAuth(input) {
|
|
|
2255
2397
|
return parsed.data;
|
|
2256
2398
|
}
|
|
2257
2399
|
async function postSponsorPermit2Transfer(input) {
|
|
2258
|
-
const
|
|
2400
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2259
2401
|
let res;
|
|
2260
2402
|
try {
|
|
2261
|
-
res = await fetch(`${
|
|
2403
|
+
res = await fetch(`${base4}/api/v1/sponsor/permit2-transfer`, {
|
|
2262
2404
|
method: "POST",
|
|
2263
2405
|
headers: {
|
|
2264
2406
|
"content-type": "application/json",
|
|
@@ -2293,11 +2435,11 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
2293
2435
|
return parsed.data;
|
|
2294
2436
|
}
|
|
2295
2437
|
async function getSponsorRelayerAddress(input) {
|
|
2296
|
-
const
|
|
2438
|
+
const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2297
2439
|
let res;
|
|
2298
2440
|
try {
|
|
2299
2441
|
res = await fetch(
|
|
2300
|
-
`${
|
|
2442
|
+
`${base4}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
2301
2443
|
{
|
|
2302
2444
|
headers: { "x-owney-api-key": input.apiKey }
|
|
2303
2445
|
}
|
|
@@ -2329,85 +2471,8 @@ async function getSponsorRelayerAddress(input) {
|
|
|
2329
2471
|
return parsed.data.relayer;
|
|
2330
2472
|
}
|
|
2331
2473
|
|
|
2332
|
-
// src/lib/permit2.ts
|
|
2333
|
-
var import_viem4 = require("viem");
|
|
2334
|
-
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2335
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2336
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
2337
|
-
{
|
|
2338
|
-
type: "function",
|
|
2339
|
-
name: "allowance",
|
|
2340
|
-
stateMutability: "view",
|
|
2341
|
-
inputs: [
|
|
2342
|
-
{ name: "owner", type: "address" },
|
|
2343
|
-
{ name: "spender", type: "address" }
|
|
2344
|
-
],
|
|
2345
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
2346
|
-
},
|
|
2347
|
-
{
|
|
2348
|
-
type: "function",
|
|
2349
|
-
name: "approve",
|
|
2350
|
-
stateMutability: "nonpayable",
|
|
2351
|
-
inputs: [
|
|
2352
|
-
{ name: "spender", type: "address" },
|
|
2353
|
-
{ name: "amount", type: "uint256" }
|
|
2354
|
-
],
|
|
2355
|
-
outputs: [{ name: "", type: "bool" }]
|
|
2356
|
-
},
|
|
2357
|
-
{
|
|
2358
|
-
type: "function",
|
|
2359
|
-
name: "balanceOf",
|
|
2360
|
-
stateMutability: "view",
|
|
2361
|
-
inputs: [{ name: "account", type: "address" }],
|
|
2362
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
2363
|
-
}
|
|
2364
|
-
];
|
|
2365
|
-
function buildPermitTransferFromTypedData(input) {
|
|
2366
|
-
return {
|
|
2367
|
-
domain: {
|
|
2368
|
-
name: "Permit2",
|
|
2369
|
-
chainId: input.chainId,
|
|
2370
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
2371
|
-
},
|
|
2372
|
-
types: {
|
|
2373
|
-
PermitTransferFrom: [
|
|
2374
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
2375
|
-
{ name: "spender", type: "address" },
|
|
2376
|
-
{ name: "nonce", type: "uint256" },
|
|
2377
|
-
{ name: "deadline", type: "uint256" }
|
|
2378
|
-
],
|
|
2379
|
-
TokenPermissions: [
|
|
2380
|
-
{ name: "token", type: "address" },
|
|
2381
|
-
{ name: "amount", type: "uint256" }
|
|
2382
|
-
]
|
|
2383
|
-
},
|
|
2384
|
-
primaryType: "PermitTransferFrom",
|
|
2385
|
-
message: input.message
|
|
2386
|
-
};
|
|
2387
|
-
}
|
|
2388
|
-
function randomPermit2Nonce() {
|
|
2389
|
-
const bytes = new Uint8Array(32);
|
|
2390
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
2391
|
-
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
2392
|
-
}
|
|
2393
|
-
async function readPermit2Allowance(publicClient, token, owner) {
|
|
2394
|
-
return publicClient.readContract({
|
|
2395
|
-
address: token,
|
|
2396
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
2397
|
-
functionName: "allowance",
|
|
2398
|
-
args: [owner, PERMIT2_ADDRESS]
|
|
2399
|
-
});
|
|
2400
|
-
}
|
|
2401
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
2402
|
-
return publicClient.readContract({
|
|
2403
|
-
address: token,
|
|
2404
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
2405
|
-
functionName: "balanceOf",
|
|
2406
|
-
args: [owner]
|
|
2407
|
-
});
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
2474
|
// src/lib/sponsored-deposit.ts
|
|
2475
|
+
init_permit2();
|
|
2411
2476
|
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
2412
2477
|
function makeSponsoredDepositCallback(deps) {
|
|
2413
2478
|
const post = deps.httpPost ?? postSponsorTransferAuth;
|
|
@@ -2482,6 +2547,7 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
2482
2547
|
|
|
2483
2548
|
// src/lib/sponsored-weth-deposit.ts
|
|
2484
2549
|
init_errors();
|
|
2550
|
+
init_permit2();
|
|
2485
2551
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
2486
2552
|
function makeSponsoredWethCallback(deps) {
|
|
2487
2553
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -2560,6 +2626,7 @@ function makeSponsoredWethCallback(deps) {
|
|
|
2560
2626
|
}
|
|
2561
2627
|
|
|
2562
2628
|
// src/client.ts
|
|
2629
|
+
init_permit2();
|
|
2563
2630
|
function encodeMultiAgentCursor(map) {
|
|
2564
2631
|
return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
|
|
2565
2632
|
}
|
|
@@ -2586,9 +2653,9 @@ var SPONSORED_USDC_BY_CHAIN = {
|
|
|
2586
2653
|
1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
2587
2654
|
};
|
|
2588
2655
|
var VIEM_CHAIN2 = {
|
|
2589
|
-
8453:
|
|
2590
|
-
42161:
|
|
2591
|
-
1:
|
|
2656
|
+
8453: import_chains3.base,
|
|
2657
|
+
42161: import_chains3.arbitrum,
|
|
2658
|
+
1: import_chains3.mainnet
|
|
2592
2659
|
};
|
|
2593
2660
|
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2594
2661
|
var SPONSORED_WETH_BY_CHAIN = {
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentChainIncompatibleError,
|
|
3
3
|
AgentNotFoundError,
|
|
4
|
+
ERC20_ALLOWANCE_ABI,
|
|
5
|
+
MAX_UINT256,
|
|
4
6
|
NotConnectedError,
|
|
5
|
-
OwneyError
|
|
6
|
-
|
|
7
|
+
OwneyError,
|
|
8
|
+
PERMIT2_ADDRESS,
|
|
9
|
+
buildPermitTransferFromTypedData,
|
|
10
|
+
randomPermit2Nonce,
|
|
11
|
+
readErc20Balance,
|
|
12
|
+
readPermit2Allowance
|
|
13
|
+
} from "./chunk-PWIKIQOX.js";
|
|
7
14
|
|
|
8
15
|
// src/agents/zyfai/zyfai.agent.ts
|
|
9
16
|
import { ZyfaiSDK } from "@zyfai/sdk";
|
|
@@ -1814,84 +1821,6 @@ async function getSponsorRelayerAddress(input) {
|
|
|
1814
1821
|
return parsed.data.relayer;
|
|
1815
1822
|
}
|
|
1816
1823
|
|
|
1817
|
-
// src/lib/permit2.ts
|
|
1818
|
-
import { bytesToHex as bytesToHex2 } from "viem";
|
|
1819
|
-
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
1820
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
1821
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
1822
|
-
{
|
|
1823
|
-
type: "function",
|
|
1824
|
-
name: "allowance",
|
|
1825
|
-
stateMutability: "view",
|
|
1826
|
-
inputs: [
|
|
1827
|
-
{ name: "owner", type: "address" },
|
|
1828
|
-
{ name: "spender", type: "address" }
|
|
1829
|
-
],
|
|
1830
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
1831
|
-
},
|
|
1832
|
-
{
|
|
1833
|
-
type: "function",
|
|
1834
|
-
name: "approve",
|
|
1835
|
-
stateMutability: "nonpayable",
|
|
1836
|
-
inputs: [
|
|
1837
|
-
{ name: "spender", type: "address" },
|
|
1838
|
-
{ name: "amount", type: "uint256" }
|
|
1839
|
-
],
|
|
1840
|
-
outputs: [{ name: "", type: "bool" }]
|
|
1841
|
-
},
|
|
1842
|
-
{
|
|
1843
|
-
type: "function",
|
|
1844
|
-
name: "balanceOf",
|
|
1845
|
-
stateMutability: "view",
|
|
1846
|
-
inputs: [{ name: "account", type: "address" }],
|
|
1847
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
1848
|
-
}
|
|
1849
|
-
];
|
|
1850
|
-
function buildPermitTransferFromTypedData(input) {
|
|
1851
|
-
return {
|
|
1852
|
-
domain: {
|
|
1853
|
-
name: "Permit2",
|
|
1854
|
-
chainId: input.chainId,
|
|
1855
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
1856
|
-
},
|
|
1857
|
-
types: {
|
|
1858
|
-
PermitTransferFrom: [
|
|
1859
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
1860
|
-
{ name: "spender", type: "address" },
|
|
1861
|
-
{ name: "nonce", type: "uint256" },
|
|
1862
|
-
{ name: "deadline", type: "uint256" }
|
|
1863
|
-
],
|
|
1864
|
-
TokenPermissions: [
|
|
1865
|
-
{ name: "token", type: "address" },
|
|
1866
|
-
{ name: "amount", type: "uint256" }
|
|
1867
|
-
]
|
|
1868
|
-
},
|
|
1869
|
-
primaryType: "PermitTransferFrom",
|
|
1870
|
-
message: input.message
|
|
1871
|
-
};
|
|
1872
|
-
}
|
|
1873
|
-
function randomPermit2Nonce() {
|
|
1874
|
-
const bytes = new Uint8Array(32);
|
|
1875
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
1876
|
-
return BigInt(bytesToHex2(bytes));
|
|
1877
|
-
}
|
|
1878
|
-
async function readPermit2Allowance(publicClient, token, owner) {
|
|
1879
|
-
return publicClient.readContract({
|
|
1880
|
-
address: token,
|
|
1881
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
1882
|
-
functionName: "allowance",
|
|
1883
|
-
args: [owner, PERMIT2_ADDRESS]
|
|
1884
|
-
});
|
|
1885
|
-
}
|
|
1886
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
1887
|
-
return publicClient.readContract({
|
|
1888
|
-
address: token,
|
|
1889
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
1890
|
-
functionName: "balanceOf",
|
|
1891
|
-
args: [owner]
|
|
1892
|
-
});
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
1824
|
// src/lib/sponsored-deposit.ts
|
|
1896
1825
|
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
1897
1826
|
function makeSponsoredDepositCallback(deps) {
|
|
@@ -2349,7 +2278,7 @@ var OwneySDK = class {
|
|
|
2349
2278
|
}
|
|
2350
2279
|
if (agentId === "surfliquid") {
|
|
2351
2280
|
if (!projectName) return null;
|
|
2352
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-
|
|
2281
|
+
const { SurfLiquidAgent } = await import("./surfliquid.agent-JOJJ3C5Y.js");
|
|
2353
2282
|
return new SurfLiquidAgent({
|
|
2354
2283
|
projectName,
|
|
2355
2284
|
appId: key2,
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ERC20_ALLOWANCE_ABI,
|
|
2
3
|
OwneyError
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PWIKIQOX.js";
|
|
4
5
|
|
|
5
6
|
// src/agents/surfliquid/surfliquid.agent.ts
|
|
6
7
|
import { SurfClient } from "@surf_liquid/core-sdk";
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createPublicClient,
|
|
10
|
+
createWalletClient,
|
|
11
|
+
custom,
|
|
12
|
+
formatUnits
|
|
13
|
+
} from "viem";
|
|
14
|
+
import { base } from "viem/chains";
|
|
8
15
|
|
|
9
16
|
// src/agents/surfliquid/surfliquid.constants.ts
|
|
10
17
|
var SURFLIQUID_CHAIN_ID = 8453;
|
|
@@ -12,6 +19,7 @@ var SURFLIQUID_CHAIN_NAME = "BASE";
|
|
|
12
19
|
var SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
13
20
|
var SURFLIQUID_USDC_DECIMALS = 6;
|
|
14
21
|
var SURFLIQUID_MIN_DEPOSIT = "0";
|
|
22
|
+
var SURFLIQUID_APPROVAL_TARGET = 100000000000n;
|
|
15
23
|
var SURFLIQUID_SUPPORTED_ASSETS = [
|
|
16
24
|
{
|
|
17
25
|
chainId: SURFLIQUID_CHAIN_ID,
|
|
@@ -283,6 +291,60 @@ var SurfLiquidAgent = class {
|
|
|
283
291
|
const { vaultAddress } = await surf.deployVault();
|
|
284
292
|
return vaultAddress;
|
|
285
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Grants the user's vault a standing USDC allowance so SurfLiquid's
|
|
296
|
+
* `autoApprove` has nothing to do — see {@link SURFLIQUID_APPROVAL_TARGET}
|
|
297
|
+
* for why one prompt per deposit is worth removing.
|
|
298
|
+
*
|
|
299
|
+
* Fails OPEN on a read error: if the allowance can't be checked we simply
|
|
300
|
+
* return and let SurfLiquid's own per-deposit approve run, because a flaky
|
|
301
|
+
* RPC must never block a deposit. A failed or rejected APPROVE does
|
|
302
|
+
* propagate — the user declined a transaction, and letting SurfLiquid
|
|
303
|
+
* immediately ask again for a smaller one is exactly the double prompt this
|
|
304
|
+
* removes.
|
|
305
|
+
*/
|
|
306
|
+
async ensureVaultAllowance(state, vaultAddress, amount) {
|
|
307
|
+
const spender = vaultAddress;
|
|
308
|
+
const transport = custom(state.provider);
|
|
309
|
+
const publicClient = createPublicClient({ chain: base, transport });
|
|
310
|
+
let allowance;
|
|
311
|
+
try {
|
|
312
|
+
allowance = await publicClient.readContract({
|
|
313
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
314
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
315
|
+
functionName: "allowance",
|
|
316
|
+
args: [state.walletAddress, spender]
|
|
317
|
+
});
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.warn(
|
|
320
|
+
"[owney-sdk] SurfLiquid allowance pre-check failed; deferring to its per-deposit approve:",
|
|
321
|
+
error instanceof Error ? error.message : String(error)
|
|
322
|
+
);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (allowance >= amount) return;
|
|
326
|
+
const target = amount > SURFLIQUID_APPROVAL_TARGET ? amount : SURFLIQUID_APPROVAL_TARGET;
|
|
327
|
+
const wallet = createWalletClient({
|
|
328
|
+
account: state.walletAddress,
|
|
329
|
+
chain: base,
|
|
330
|
+
transport
|
|
331
|
+
});
|
|
332
|
+
const hash = await wallet.writeContract({
|
|
333
|
+
address: SURFLIQUID_USDC_ADDRESS,
|
|
334
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
335
|
+
functionName: "approve",
|
|
336
|
+
args: [spender, target],
|
|
337
|
+
account: state.walletAddress,
|
|
338
|
+
chain: base
|
|
339
|
+
});
|
|
340
|
+
const receipt = await publicClient.waitForTransactionReceipt({
|
|
341
|
+
hash,
|
|
342
|
+
confirmations: 1
|
|
343
|
+
});
|
|
344
|
+
if (receipt.status !== "success") {
|
|
345
|
+
throw new Error(`SurfLiquid USDC approval reverted (tx ${hash})`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
286
348
|
// --- IAgent: lifecycle ---
|
|
287
349
|
async disconnect() {
|
|
288
350
|
if (this.surf) {
|
|
@@ -301,6 +363,7 @@ var SurfLiquidAgent = class {
|
|
|
301
363
|
surf,
|
|
302
364
|
state.walletAddress
|
|
303
365
|
);
|
|
366
|
+
await this.ensureVaultAllowance(state, smartWallet, BigInt(amount));
|
|
304
367
|
const tx = await surf.deposit({
|
|
305
368
|
asset: SURFLIQUID_USDC_ADDRESS,
|
|
306
369
|
amount: human
|
package/package.json
CHANGED
package/dist/chunk-GMNQBWUB.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// src/errors.ts
|
|
2
|
-
var OwneyError = class extends Error {
|
|
3
|
-
code;
|
|
4
|
-
details;
|
|
5
|
-
agentId;
|
|
6
|
-
constructor(code, message, details, agentId) {
|
|
7
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
8
|
-
super(`${prefix} ${message}`);
|
|
9
|
-
this.name = "OwneyError";
|
|
10
|
-
this.code = code;
|
|
11
|
-
this.details = details;
|
|
12
|
-
this.agentId = agentId;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
16
|
-
constructor(agentId, available) {
|
|
17
|
-
super(
|
|
18
|
-
"AGENT_NOT_FOUND",
|
|
19
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
20
|
-
{ agentId, available },
|
|
21
|
-
agentId
|
|
22
|
-
);
|
|
23
|
-
this.name = "AgentNotFoundError";
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var NotConnectedError = class extends OwneyError {
|
|
27
|
-
constructor() {
|
|
28
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
29
|
-
this.name = "NotConnectedError";
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
33
|
-
incompatibleAgents;
|
|
34
|
-
connectedChainId;
|
|
35
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
36
|
-
const details = incompatibleAgents.map(
|
|
37
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
38
|
-
).join("; ");
|
|
39
|
-
super(
|
|
40
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
41
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
42
|
-
{ incompatibleAgents, connectedChainId }
|
|
43
|
-
);
|
|
44
|
-
this.name = "AgentChainIncompatibleError";
|
|
45
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
46
|
-
this.connectedChainId = connectedChainId;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
OwneyError,
|
|
52
|
-
AgentNotFoundError,
|
|
53
|
-
NotConnectedError,
|
|
54
|
-
AgentChainIncompatibleError
|
|
55
|
-
};
|