@owney/sdk 0.7.21-beta.4 → 0.7.21-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/index.cjs +521 -393
- package/dist/index.d.cts +17 -22
- package/dist/index.d.ts +17 -22
- package/dist/index.js +509 -377
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,26 @@ __export(index_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(index_exports);
|
|
34
34
|
|
|
35
|
+
// src/lib/deposit-batch-callback.ts
|
|
36
|
+
var batchCallbacks = /* @__PURE__ */ new WeakMap();
|
|
37
|
+
var getDepositBatchTransfer = (callback) => callback ? batchCallbacks.get(callback) : void 0;
|
|
38
|
+
function toBatchTransfer(to, amount, verification) {
|
|
39
|
+
return {
|
|
40
|
+
to,
|
|
41
|
+
amount,
|
|
42
|
+
...verification ? {
|
|
43
|
+
yieldseeker: {
|
|
44
|
+
signature: verification.signature,
|
|
45
|
+
userId: verification.userId,
|
|
46
|
+
agentId: verification.yieldseekerAgentId
|
|
47
|
+
}
|
|
48
|
+
} : {}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function registerDepositBatch(callback, transfer) {
|
|
52
|
+
batchCallbacks.set(callback, transfer);
|
|
53
|
+
}
|
|
54
|
+
|
|
35
55
|
// src/errors.ts
|
|
36
56
|
var OwneyError = class extends Error {
|
|
37
57
|
code;
|
|
@@ -2098,39 +2118,6 @@ async function ensureWalletOnChain(pub, wallet, expected) {
|
|
|
2098
2118
|
|
|
2099
2119
|
// src/lib/transfer-auth.ts
|
|
2100
2120
|
var import_viem2 = require("viem");
|
|
2101
|
-
var ERC20_META_ABI = [
|
|
2102
|
-
{ type: "function", name: "name", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] },
|
|
2103
|
-
{ type: "function", name: "version", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] }
|
|
2104
|
-
];
|
|
2105
|
-
function buildTransferWithAuthorizationTypedData(input) {
|
|
2106
|
-
return {
|
|
2107
|
-
domain: { name: input.tokenName, version: input.tokenVersion, chainId: input.chainId, verifyingContract: input.token },
|
|
2108
|
-
types: {
|
|
2109
|
-
TransferWithAuthorization: [
|
|
2110
|
-
{ name: "from", type: "address" },
|
|
2111
|
-
{ name: "to", type: "address" },
|
|
2112
|
-
{ name: "value", type: "uint256" },
|
|
2113
|
-
{ name: "validAfter", type: "uint256" },
|
|
2114
|
-
{ name: "validBefore", type: "uint256" },
|
|
2115
|
-
{ name: "nonce", type: "bytes32" }
|
|
2116
|
-
]
|
|
2117
|
-
},
|
|
2118
|
-
primaryType: "TransferWithAuthorization",
|
|
2119
|
-
message: input.message
|
|
2120
|
-
};
|
|
2121
|
-
}
|
|
2122
|
-
async function readTokenMeta(publicClient, token) {
|
|
2123
|
-
const [tokenName, tokenVersion] = await Promise.all([
|
|
2124
|
-
publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "name" }),
|
|
2125
|
-
publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "version" }).catch(() => "2")
|
|
2126
|
-
]);
|
|
2127
|
-
return { tokenName, tokenVersion };
|
|
2128
|
-
}
|
|
2129
|
-
function randomAuthNonce() {
|
|
2130
|
-
const bytes = new Uint8Array(32);
|
|
2131
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
2132
|
-
return (0, import_viem2.bytesToHex)(bytes);
|
|
2133
|
-
}
|
|
2134
2121
|
|
|
2135
2122
|
// src/lib/sponsor-client.ts
|
|
2136
2123
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
@@ -2173,65 +2160,21 @@ async function postPaymasterIntent(input) {
|
|
|
2173
2160
|
}
|
|
2174
2161
|
return parsed.data;
|
|
2175
2162
|
}
|
|
2176
|
-
async function
|
|
2163
|
+
async function getSponsorRelayerAddress(input) {
|
|
2177
2164
|
const base5 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
2178
2165
|
let res;
|
|
2179
2166
|
try {
|
|
2180
|
-
res = await fetch(
|
|
2181
|
-
|
|
2182
|
-
headers: {
|
|
2183
|
-
"content-type": "application/json",
|
|
2184
|
-
"x-owney-api-key": input.apiKey,
|
|
2185
|
-
...input.yieldseekerSignature ? { Authorization: `Signature ${input.yieldseekerSignature}` } : {}
|
|
2186
|
-
},
|
|
2187
|
-
body: JSON.stringify(input.body)
|
|
2188
|
-
});
|
|
2189
|
-
} catch (networkError) {
|
|
2190
|
-
throw new OwneyError(
|
|
2191
|
-
"SPONSOR_REQUEST_FAILED",
|
|
2192
|
-
`Sponsor API network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
2193
|
-
{ cause: String(networkError) }
|
|
2194
|
-
);
|
|
2195
|
-
}
|
|
2196
|
-
const text = await res.text();
|
|
2197
|
-
let parsed = null;
|
|
2198
|
-
try {
|
|
2199
|
-
parsed = JSON.parse(text);
|
|
2200
|
-
} catch {
|
|
2201
|
-
}
|
|
2202
|
-
if (!res.ok || !parsed?.success || !parsed.data) {
|
|
2203
|
-
throw new OwneyError(
|
|
2204
|
-
"SPONSOR_REQUEST_FAILED",
|
|
2205
|
-
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
2167
|
+
res = await fetch(
|
|
2168
|
+
`${base5}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
2206
2169
|
{
|
|
2207
|
-
|
|
2208
|
-
responseBody: text.slice(0, 500),
|
|
2209
|
-
// 503 SPONSOR_UNAVAILABLE = relayer out of gas; the tx was rejected
|
|
2210
|
-
// before broadcast, so it is safe to fall back to a user-paid deposit.
|
|
2211
|
-
safeToFallback: res.status === 503
|
|
2170
|
+
headers: { "x-owney-api-key": input.apiKey }
|
|
2212
2171
|
}
|
|
2213
2172
|
);
|
|
2214
|
-
}
|
|
2215
|
-
return parsed.data;
|
|
2216
|
-
}
|
|
2217
|
-
async function postSponsorPermit2Transfer(input) {
|
|
2218
|
-
const base5 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
2219
|
-
let res;
|
|
2220
|
-
try {
|
|
2221
|
-
res = await fetch(`${base5}/api/v1/sponsor/permit2-transfer`, {
|
|
2222
|
-
method: "POST",
|
|
2223
|
-
headers: {
|
|
2224
|
-
"content-type": "application/json",
|
|
2225
|
-
"x-owney-api-key": input.apiKey,
|
|
2226
|
-
...input.yieldseekerSignature ? { Authorization: `Signature ${input.yieldseekerSignature}` } : {}
|
|
2227
|
-
},
|
|
2228
|
-
body: JSON.stringify(input.body)
|
|
2229
|
-
});
|
|
2230
2173
|
} catch (networkError) {
|
|
2231
2174
|
throw new OwneyError(
|
|
2232
2175
|
"SPONSOR_REQUEST_FAILED",
|
|
2233
2176
|
`Sponsor API network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
2234
|
-
{ cause: String(networkError), safeToFallback:
|
|
2177
|
+
{ cause: String(networkError), safeToFallback: true }
|
|
2235
2178
|
);
|
|
2236
2179
|
}
|
|
2237
2180
|
const text = await res.text();
|
|
@@ -2240,60 +2183,64 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
2240
2183
|
parsed = JSON.parse(text);
|
|
2241
2184
|
} catch {
|
|
2242
2185
|
}
|
|
2243
|
-
if (!res.ok || !parsed?.success || !parsed.data) {
|
|
2186
|
+
if (!res.ok || !parsed?.success || !parsed.data?.relayer) {
|
|
2244
2187
|
throw new OwneyError(
|
|
2245
2188
|
"SPONSOR_REQUEST_FAILED",
|
|
2246
2189
|
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
2247
2190
|
{
|
|
2248
2191
|
statusCode: res.status,
|
|
2249
2192
|
responseBody: text.slice(0, 500),
|
|
2250
|
-
safeToFallback:
|
|
2193
|
+
safeToFallback: true
|
|
2251
2194
|
}
|
|
2252
2195
|
);
|
|
2253
2196
|
}
|
|
2254
|
-
return parsed.data;
|
|
2197
|
+
return parsed.data.relayer;
|
|
2255
2198
|
}
|
|
2256
|
-
async function
|
|
2257
|
-
const base5 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
2199
|
+
async function postSponsorBatchTransfer(input) {
|
|
2258
2200
|
let res;
|
|
2259
2201
|
try {
|
|
2260
2202
|
res = await fetch(
|
|
2261
|
-
`${
|
|
2203
|
+
`${input.baseUrl ?? ROUTING_API_BASE_URL}/api/v1/sponsor/permit2-batch`,
|
|
2262
2204
|
{
|
|
2263
|
-
|
|
2205
|
+
method: "POST",
|
|
2206
|
+
headers: {
|
|
2207
|
+
"content-type": "application/json",
|
|
2208
|
+
"x-owney-api-key": input.apiKey
|
|
2209
|
+
},
|
|
2210
|
+
body: JSON.stringify(input.body)
|
|
2264
2211
|
}
|
|
2265
2212
|
);
|
|
2266
|
-
} catch
|
|
2213
|
+
} catch {
|
|
2267
2214
|
throw new OwneyError(
|
|
2268
2215
|
"SPONSOR_REQUEST_FAILED",
|
|
2269
|
-
|
|
2270
|
-
{
|
|
2216
|
+
"Deposit status is unknown. Retry the same amount to check it.",
|
|
2217
|
+
{ safeToFallback: false }
|
|
2271
2218
|
);
|
|
2272
2219
|
}
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
try {
|
|
2276
|
-
parsed = JSON.parse(text);
|
|
2277
|
-
} catch {
|
|
2278
|
-
}
|
|
2279
|
-
if (!res.ok || !parsed?.success || !parsed.data?.relayer) {
|
|
2220
|
+
const parsed = await res.json().catch(() => null);
|
|
2221
|
+
if (!res.ok || !parsed?.success || !/^0x[0-9a-fA-F]{64}$/.test(parsed.data?.txHash ?? "")) {
|
|
2280
2222
|
throw new OwneyError(
|
|
2281
2223
|
"SPONSOR_REQUEST_FAILED",
|
|
2282
|
-
|
|
2224
|
+
"Deposit could not be confirmed. Retry the same amount to check its status.",
|
|
2283
2225
|
{
|
|
2284
2226
|
statusCode: res.status,
|
|
2285
|
-
|
|
2286
|
-
|
|
2227
|
+
safeToFallback: false,
|
|
2228
|
+
notSubmitted: parsed?.notSubmitted === true || parsed?.error?.notSubmitted === true || parsed?.error?.details?.notSubmitted === true
|
|
2287
2229
|
}
|
|
2288
2230
|
);
|
|
2289
2231
|
}
|
|
2290
|
-
return parsed.data
|
|
2232
|
+
return parsed.data;
|
|
2291
2233
|
}
|
|
2292
2234
|
|
|
2293
2235
|
// src/lib/permit2.ts
|
|
2294
2236
|
var import_viem3 = require("viem");
|
|
2295
2237
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2296
|
-
|
|
2238
|
+
function permit2ApprovalAmount(requiredAmount) {
|
|
2239
|
+
if (requiredAmount <= 0n) {
|
|
2240
|
+
throw new Error("Permit2 approval requires a positive deposit amount");
|
|
2241
|
+
}
|
|
2242
|
+
return requiredAmount;
|
|
2243
|
+
}
|
|
2297
2244
|
var ERC20_ALLOWANCE_ABI = [
|
|
2298
2245
|
{
|
|
2299
2246
|
type: "function",
|
|
@@ -2323,29 +2270,6 @@ var ERC20_ALLOWANCE_ABI = [
|
|
|
2323
2270
|
outputs: [{ name: "", type: "uint256" }]
|
|
2324
2271
|
}
|
|
2325
2272
|
];
|
|
2326
|
-
function buildPermitTransferFromTypedData(input) {
|
|
2327
|
-
return {
|
|
2328
|
-
domain: {
|
|
2329
|
-
name: "Permit2",
|
|
2330
|
-
chainId: input.chainId,
|
|
2331
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
2332
|
-
},
|
|
2333
|
-
types: {
|
|
2334
|
-
PermitTransferFrom: [
|
|
2335
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
2336
|
-
{ name: "spender", type: "address" },
|
|
2337
|
-
{ name: "nonce", type: "uint256" },
|
|
2338
|
-
{ name: "deadline", type: "uint256" }
|
|
2339
|
-
],
|
|
2340
|
-
TokenPermissions: [
|
|
2341
|
-
{ name: "token", type: "address" },
|
|
2342
|
-
{ name: "amount", type: "uint256" }
|
|
2343
|
-
]
|
|
2344
|
-
},
|
|
2345
|
-
primaryType: "PermitTransferFrom",
|
|
2346
|
-
message: input.message
|
|
2347
|
-
};
|
|
2348
|
-
}
|
|
2349
2273
|
function randomPermit2Nonce() {
|
|
2350
2274
|
const bytes = new Uint8Array(32);
|
|
2351
2275
|
globalThis.crypto.getRandomValues(bytes);
|
|
@@ -2388,88 +2312,6 @@ function makeVerificationAwareDepositCallback(implementation) {
|
|
|
2388
2312
|
});
|
|
2389
2313
|
return callback;
|
|
2390
2314
|
}
|
|
2391
|
-
function makeSponsoredDepositCallback(deps) {
|
|
2392
|
-
const post = deps.httpPost ?? postSponsorTransferAuth;
|
|
2393
|
-
return makeVerificationAwareDepositCallback(
|
|
2394
|
-
async (smartWallet, chainId, amount, verification) => {
|
|
2395
|
-
const cid = chainId;
|
|
2396
|
-
const token = deps.tokenAddressByChain[cid];
|
|
2397
|
-
if (!token) {
|
|
2398
|
-
throw new OwneyError(
|
|
2399
|
-
"CHAIN_UNSUPPORTED",
|
|
2400
|
-
`No sponsored token configured for chain ${chainId}`
|
|
2401
|
-
);
|
|
2402
|
-
}
|
|
2403
|
-
const pub = deps.getPublicClient(cid);
|
|
2404
|
-
const wallet = deps.getWalletClient(cid);
|
|
2405
|
-
await ensureWalletOnChain(pub, wallet, cid);
|
|
2406
|
-
try {
|
|
2407
|
-
const balance = await readErc20Balance(pub, token, deps.ownerAddress);
|
|
2408
|
-
if (balance < BigInt(amount)) {
|
|
2409
|
-
throw new OwneyError(
|
|
2410
|
-
"DEPOSIT_INSUFFICIENT_BALANCE",
|
|
2411
|
-
"Insufficient balance for this deposit.",
|
|
2412
|
-
{ token, chainId: cid, balance: balance.toString(), amount }
|
|
2413
|
-
);
|
|
2414
|
-
}
|
|
2415
|
-
} catch (err) {
|
|
2416
|
-
if (err instanceof OwneyError) throw err;
|
|
2417
|
-
console.warn(
|
|
2418
|
-
"[owney-sdk] Deposit balance pre-check failed (non-fatal):",
|
|
2419
|
-
err instanceof Error ? err.message : String(err)
|
|
2420
|
-
);
|
|
2421
|
-
}
|
|
2422
|
-
const { tokenName, tokenVersion } = await readTokenMeta(pub, token);
|
|
2423
|
-
const validAfter = 0n;
|
|
2424
|
-
const validBefore = BigInt(
|
|
2425
|
-
Math.floor(Date.now() / 1e3) + AUTH_WINDOW_SECONDS
|
|
2426
|
-
);
|
|
2427
|
-
const nonce = randomAuthNonce();
|
|
2428
|
-
const typedData = buildTransferWithAuthorizationTypedData({
|
|
2429
|
-
token,
|
|
2430
|
-
chainId: cid,
|
|
2431
|
-
tokenName,
|
|
2432
|
-
tokenVersion,
|
|
2433
|
-
message: {
|
|
2434
|
-
from: deps.ownerAddress,
|
|
2435
|
-
to: smartWallet,
|
|
2436
|
-
value: BigInt(amount),
|
|
2437
|
-
validAfter,
|
|
2438
|
-
validBefore,
|
|
2439
|
-
nonce
|
|
2440
|
-
}
|
|
2441
|
-
});
|
|
2442
|
-
const authSignature = await wallet.signTypedData({
|
|
2443
|
-
account: deps.ownerAddress,
|
|
2444
|
-
...typedData
|
|
2445
|
-
});
|
|
2446
|
-
deps.onApproved?.();
|
|
2447
|
-
const result = await post({
|
|
2448
|
-
baseUrl: deps.baseUrl,
|
|
2449
|
-
apiKey: deps.apiKey,
|
|
2450
|
-
...verification?.agentId === "yieldseeker" ? { yieldseekerSignature: verification.signature } : {},
|
|
2451
|
-
body: {
|
|
2452
|
-
chainId: cid,
|
|
2453
|
-
token,
|
|
2454
|
-
from: deps.ownerAddress,
|
|
2455
|
-
to: smartWallet,
|
|
2456
|
-
value: amount,
|
|
2457
|
-
validAfter: validAfter.toString(),
|
|
2458
|
-
validBefore: validBefore.toString(),
|
|
2459
|
-
nonce,
|
|
2460
|
-
authSignature,
|
|
2461
|
-
tokenName,
|
|
2462
|
-
tokenVersion,
|
|
2463
|
-
...verification?.agentId === "yieldseeker" ? {
|
|
2464
|
-
yieldseekerUserId: verification.userId,
|
|
2465
|
-
yieldseekerAgentId: verification.yieldseekerAgentId
|
|
2466
|
-
} : {}
|
|
2467
|
-
}
|
|
2468
|
-
});
|
|
2469
|
-
return result.txHash;
|
|
2470
|
-
}
|
|
2471
|
-
);
|
|
2472
|
-
}
|
|
2473
2315
|
|
|
2474
2316
|
// src/agents/yieldseeker/yieldseeker.auth.ts
|
|
2475
2317
|
var import_siwe = require("siwe");
|
|
@@ -3148,7 +2990,7 @@ function depositDestination(context, movement) {
|
|
|
3148
2990
|
if (receipt && minted) return { protocol: "Vault", pool: receipt.name || receipt.symbol, tokenSymbol: context.asset };
|
|
3149
2991
|
return void 0;
|
|
3150
2992
|
}
|
|
3151
|
-
function movementEntry(movement, wallet, agent, asset, ownerAddress, destination) {
|
|
2993
|
+
function movementEntry(movement, wallet, agent, asset, ownerAddress, vaultAddresses, destination) {
|
|
3152
2994
|
const from = movement.fromAddress.toLowerCase();
|
|
3153
2995
|
const to = movement.toAddress.toLowerCase();
|
|
3154
2996
|
const owner = ownerAddress.toLowerCase();
|
|
@@ -3158,7 +3000,7 @@ function movementEntry(movement, wallet, agent, asset, ownerAddress, destination
|
|
|
3158
3000
|
return void 0;
|
|
3159
3001
|
}
|
|
3160
3002
|
let action;
|
|
3161
|
-
if (
|
|
3003
|
+
if (to === agentWallet && !vaultAddresses.has(from)) {
|
|
3162
3004
|
action = "Top up";
|
|
3163
3005
|
} else if (from === agentWallet && to === owner) {
|
|
3164
3006
|
action = "Withdraw";
|
|
@@ -3208,6 +3050,7 @@ function mapYieldseekerHistory(contexts, options) {
|
|
|
3208
3050
|
context.agent,
|
|
3209
3051
|
context.asset,
|
|
3210
3052
|
options.ownerAddress,
|
|
3053
|
+
options.vaultAddresses,
|
|
3211
3054
|
depositDestination(context, movement)
|
|
3212
3055
|
)
|
|
3213
3056
|
),
|
|
@@ -3288,6 +3131,7 @@ var OWNEY_AGENT_NAME = "owney";
|
|
|
3288
3131
|
var YIELDSEEKER_USERNAME_PREFIX = "owney_";
|
|
3289
3132
|
var YIELDSEEKER_USERNAME_RANDOM_LENGTH = 14;
|
|
3290
3133
|
var YIELDSEEKER_USERNAME_CREATE_ATTEMPTS = 3;
|
|
3134
|
+
var YIELDSEEKER_YIELD_OPTIONS_CACHE_MS = 6e4;
|
|
3291
3135
|
function generateYieldseekerUsername() {
|
|
3292
3136
|
const suffix = globalThis.crypto.randomUUID().replaceAll("-", "").slice(0, YIELDSEEKER_USERNAME_RANDOM_LENGTH).toLowerCase();
|
|
3293
3137
|
return `${YIELDSEEKER_USERNAME_PREFIX}${suffix}`;
|
|
@@ -3349,6 +3193,8 @@ var YieldseekerAgent = class {
|
|
|
3349
3193
|
agentContexts = /* @__PURE__ */ new Map();
|
|
3350
3194
|
users = /* @__PURE__ */ new Map();
|
|
3351
3195
|
pendingAgents = /* @__PURE__ */ new Map();
|
|
3196
|
+
yieldOptions = /* @__PURE__ */ new Map();
|
|
3197
|
+
pendingYieldOptions = /* @__PURE__ */ new Map();
|
|
3352
3198
|
constructor(owneyApiKey, options = {}) {
|
|
3353
3199
|
this.api = new YieldseekerApiClient(
|
|
3354
3200
|
owneyApiKey,
|
|
@@ -3415,7 +3261,6 @@ var YieldseekerAgent = class {
|
|
|
3415
3261
|
chainId
|
|
3416
3262
|
});
|
|
3417
3263
|
}
|
|
3418
|
-
await this.deployAfterFunding(state, chainId, context);
|
|
3419
3264
|
} finally {
|
|
3420
3265
|
await this.refreshSnapshotAfterMovement(
|
|
3421
3266
|
state,
|
|
@@ -3567,9 +3412,20 @@ var YieldseekerAgent = class {
|
|
|
3567
3412
|
historic: true,
|
|
3568
3413
|
actions: true
|
|
3569
3414
|
});
|
|
3415
|
+
const catalog = await Promise.all(
|
|
3416
|
+
[...new Set(contexts.map((context) => context.asset))].map(
|
|
3417
|
+
(contextAsset) => this.loadYieldOptions(contextAsset)
|
|
3418
|
+
)
|
|
3419
|
+
);
|
|
3420
|
+
const vaultAddresses = new Set(
|
|
3421
|
+
catalog.flat().filter(
|
|
3422
|
+
(yieldOption) => yieldOption.chainId === chainId && (0, import_viem6.isAddress)(yieldOption.address)
|
|
3423
|
+
).map((yieldOption) => yieldOption.address.toLowerCase())
|
|
3424
|
+
);
|
|
3570
3425
|
return mapYieldseekerHistory(contexts, {
|
|
3571
3426
|
limit: options?.limit ?? 10,
|
|
3572
3427
|
ownerAddress: state.walletAddress,
|
|
3428
|
+
vaultAddresses,
|
|
3573
3429
|
...options?.fromDate ? { fromDate: options.fromDate } : {},
|
|
3574
3430
|
...options?.toDate ? { toDate: options.toDate } : {}
|
|
3575
3431
|
});
|
|
@@ -3588,18 +3444,32 @@ var YieldseekerAgent = class {
|
|
|
3588
3444
|
const assets = requested ? [requested] : ["USDC", "WETH"];
|
|
3589
3445
|
const values = await Promise.all(
|
|
3590
3446
|
assets.map(async (asset) => {
|
|
3591
|
-
|
|
3592
|
-
const response = await this.api.request(
|
|
3593
|
-
`/chains/8453/assets/${metadata.address}/yield-options`
|
|
3594
|
-
);
|
|
3595
|
-
if (!Array.isArray(response?.yieldOptions)) {
|
|
3596
|
-
throw this.invalidResponse("yield options");
|
|
3597
|
-
}
|
|
3598
|
-
return { asset, yieldOptions: response.yieldOptions };
|
|
3447
|
+
return { asset, yieldOptions: await this.loadYieldOptions(asset) };
|
|
3599
3448
|
})
|
|
3600
3449
|
);
|
|
3601
3450
|
return mapYieldseekerAgentApy(values, days);
|
|
3602
3451
|
}
|
|
3452
|
+
async loadYieldOptions(asset) {
|
|
3453
|
+
const cached = this.yieldOptions.get(asset);
|
|
3454
|
+
if (cached && cached.expiresAt > Date.now()) return cached.value;
|
|
3455
|
+
const pending = this.pendingYieldOptions.get(asset);
|
|
3456
|
+
if (pending) return pending;
|
|
3457
|
+
const metadata = YIELDSEEKER_ASSET_METADATA[asset];
|
|
3458
|
+
const request = this.api.request(
|
|
3459
|
+
`/chains/8453/assets/${metadata.address}/yield-options`
|
|
3460
|
+
).then((response) => {
|
|
3461
|
+
if (!Array.isArray(response?.yieldOptions)) {
|
|
3462
|
+
throw this.invalidResponse("yield options");
|
|
3463
|
+
}
|
|
3464
|
+
this.yieldOptions.set(asset, {
|
|
3465
|
+
expiresAt: Date.now() + YIELDSEEKER_YIELD_OPTIONS_CACHE_MS,
|
|
3466
|
+
value: response.yieldOptions
|
|
3467
|
+
});
|
|
3468
|
+
return response.yieldOptions;
|
|
3469
|
+
}).finally(() => this.pendingYieldOptions.delete(asset));
|
|
3470
|
+
this.pendingYieldOptions.set(asset, request);
|
|
3471
|
+
return request;
|
|
3472
|
+
}
|
|
3603
3473
|
userKey(state, chainId) {
|
|
3604
3474
|
return `${state.walletAddress.toLowerCase()}:${chainId}`;
|
|
3605
3475
|
}
|
|
@@ -3678,8 +3548,9 @@ var YieldseekerAgent = class {
|
|
|
3678
3548
|
const pending = this.pendingAgents.get(key2);
|
|
3679
3549
|
if (pending) return pending;
|
|
3680
3550
|
const request = this.resolveAgent(state, chainId, asset, true).then(
|
|
3681
|
-
(context) => {
|
|
3551
|
+
async (context) => {
|
|
3682
3552
|
if (!context) throw this.invalidResponse("agent creation");
|
|
3553
|
+
await this.deployAgent(state, chainId, context);
|
|
3683
3554
|
this.agentContexts.set(key2, context);
|
|
3684
3555
|
return context;
|
|
3685
3556
|
}
|
|
@@ -3824,24 +3695,21 @@ var YieldseekerAgent = class {
|
|
|
3824
3695
|
...actions?.actions ? { actions: actions.actions } : {}
|
|
3825
3696
|
};
|
|
3826
3697
|
}
|
|
3827
|
-
async
|
|
3698
|
+
async deployAgent(state, chainId, context) {
|
|
3828
3699
|
if (context.wallet.initializedDate != null) return;
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
console.warn(
|
|
3841
|
-
"[owney-sdk] Yieldseeker deposit is funded but not deployable yet:",
|
|
3842
|
-
error
|
|
3843
|
-
);
|
|
3700
|
+
const walletAddress = context.wallet.walletAddress.toLowerCase();
|
|
3701
|
+
const deployed = await this.walletRequest(
|
|
3702
|
+
state,
|
|
3703
|
+
chainId,
|
|
3704
|
+
this.agentPath(context, "deploy"),
|
|
3705
|
+
{ method: "POST", body: {} }
|
|
3706
|
+
);
|
|
3707
|
+
if (!deployed?.agentWallet || !(0, import_viem6.isAddress)(deployed.agentWallet.walletAddress) || deployed.agentWallet.walletAddress.toLowerCase() !== walletAddress) {
|
|
3708
|
+
throw this.invalidResponse("agent deployment", {
|
|
3709
|
+
reason: "Deploy did not return the expected Agent Wallet."
|
|
3710
|
+
});
|
|
3844
3711
|
}
|
|
3712
|
+
context.wallet = deployed.agentWallet;
|
|
3845
3713
|
}
|
|
3846
3714
|
async refreshSnapshotAfterMovement(state, chainId, context, movement) {
|
|
3847
3715
|
try {
|
|
@@ -4325,105 +4193,305 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
4325
4193
|
}
|
|
4326
4194
|
|
|
4327
4195
|
// src/client.ts
|
|
4328
|
-
var
|
|
4196
|
+
var import_viem11 = require("viem");
|
|
4329
4197
|
var import_chains4 = require("viem/chains");
|
|
4330
4198
|
|
|
4331
|
-
// src/lib/sponsored-
|
|
4332
|
-
var
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4199
|
+
// src/lib/sponsored-token-batch.ts
|
|
4200
|
+
var import_viem9 = require("viem");
|
|
4201
|
+
|
|
4202
|
+
// src/lib/permit2-batch.ts
|
|
4203
|
+
var import_viem8 = require("viem");
|
|
4204
|
+
var BATCH_PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
4205
|
+
var PERMIT_BATCH_TYPES = {
|
|
4206
|
+
PermitBatchWitnessTransferFrom: [
|
|
4207
|
+
{ name: "permitted", type: "TokenPermissions[]" },
|
|
4208
|
+
{ name: "spender", type: "address" },
|
|
4209
|
+
{ name: "nonce", type: "uint256" },
|
|
4210
|
+
{ name: "deadline", type: "uint256" },
|
|
4211
|
+
{ name: "witness", type: "Deposit" }
|
|
4212
|
+
],
|
|
4213
|
+
Deposit: [{ name: "recipients", type: "address[]" }],
|
|
4214
|
+
TokenPermissions: [
|
|
4215
|
+
{ name: "token", type: "address" },
|
|
4216
|
+
{ name: "amount", type: "uint256" }
|
|
4217
|
+
]
|
|
4218
|
+
};
|
|
4219
|
+
var PERMIT2_BATCH_ABI = (0, import_viem8.parseAbi)([
|
|
4220
|
+
"struct TokenPermissions { address token; uint256 amount; }",
|
|
4221
|
+
"struct PermitBatchTransferFrom { TokenPermissions[] permitted; uint256 nonce; uint256 deadline; }",
|
|
4222
|
+
"struct SignatureTransferDetails { address to; uint256 requestedAmount; }",
|
|
4223
|
+
"function permitWitnessTransferFrom(PermitBatchTransferFrom permit,SignatureTransferDetails[] transferDetails,address owner,bytes32 witness,string witnessTypeString,bytes signature)",
|
|
4224
|
+
"function nonceBitmap(address owner,uint256 wordPos) view returns (uint256)"
|
|
4225
|
+
]);
|
|
4226
|
+
function batchPermit(b) {
|
|
4227
|
+
return {
|
|
4228
|
+
permitted: b.transfers.map((t) => ({
|
|
4229
|
+
token: b.token,
|
|
4230
|
+
amount: BigInt(t.amount)
|
|
4231
|
+
})),
|
|
4232
|
+
nonce: BigInt(b.nonce),
|
|
4233
|
+
deadline: BigInt(b.deadline)
|
|
4234
|
+
};
|
|
4235
|
+
}
|
|
4236
|
+
function batchTypedData(b, spender) {
|
|
4237
|
+
return {
|
|
4238
|
+
domain: {
|
|
4239
|
+
name: "Permit2",
|
|
4240
|
+
chainId: b.chainId,
|
|
4241
|
+
verifyingContract: BATCH_PERMIT2_ADDRESS
|
|
4242
|
+
},
|
|
4243
|
+
types: PERMIT_BATCH_TYPES,
|
|
4244
|
+
primaryType: "PermitBatchWitnessTransferFrom",
|
|
4245
|
+
message: {
|
|
4246
|
+
...batchPermit(b),
|
|
4247
|
+
spender,
|
|
4248
|
+
witness: { recipients: b.transfers.map((t) => t.to) }
|
|
4249
|
+
}
|
|
4250
|
+
};
|
|
4251
|
+
}
|
|
4252
|
+
|
|
4253
|
+
// src/lib/sponsored-token-batch.ts
|
|
4254
|
+
var memory = /* @__PURE__ */ new Map();
|
|
4255
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
4256
|
+
var planOf = (transfers) => JSON.stringify(
|
|
4257
|
+
transfers.map((t) => ({
|
|
4258
|
+
to: t.to.toLowerCase(),
|
|
4259
|
+
amount: BigInt(t.amount).toString()
|
|
4260
|
+
}))
|
|
4261
|
+
);
|
|
4262
|
+
function read(key2) {
|
|
4263
|
+
return typeof window === "undefined" ? memory.get(key2) : window.localStorage.getItem(key2);
|
|
4264
|
+
}
|
|
4265
|
+
function save(key2, body) {
|
|
4266
|
+
const value = JSON.stringify({
|
|
4267
|
+
...body,
|
|
4268
|
+
transfers: body.transfers.map(({ to, amount }) => ({ to, amount }))
|
|
4269
|
+
});
|
|
4270
|
+
if (typeof window === "undefined") memory.set(key2, value);
|
|
4271
|
+
else window.localStorage.setItem(key2, value);
|
|
4272
|
+
}
|
|
4273
|
+
function clear(key2) {
|
|
4274
|
+
if (typeof window === "undefined") memory.delete(key2);
|
|
4275
|
+
else window.localStorage.removeItem(key2);
|
|
4276
|
+
}
|
|
4277
|
+
function sponsorTokenBatch(i) {
|
|
4278
|
+
const key2 = `owney.token-batch.v1:${(0, import_viem9.keccak256)((0, import_viem9.toBytes)(i.apiKey))}:${i.baseUrl ?? "default"}:${i.chainId}:${i.owner.toLowerCase()}:${i.token.toLowerCase()}`;
|
|
4279
|
+
const plan = planOf(i.transfers);
|
|
4280
|
+
const active = inflight.get(key2);
|
|
4281
|
+
if (active) {
|
|
4282
|
+
if (active.plan !== plan)
|
|
4283
|
+
return Promise.reject(
|
|
4284
|
+
new Error(
|
|
4285
|
+
"A token deposit is already in progress. Wait for its result before depositing again."
|
|
4286
|
+
)
|
|
4370
4287
|
);
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4288
|
+
return active.promise;
|
|
4289
|
+
}
|
|
4290
|
+
const promise = execute(i, key2, plan).finally(() => inflight.delete(key2));
|
|
4291
|
+
inflight.set(key2, { plan, promise });
|
|
4292
|
+
return promise;
|
|
4293
|
+
}
|
|
4294
|
+
async function execute(i, key2, plan) {
|
|
4295
|
+
if (!i.transfers.length || i.transfers.length > 16 || i.transfers.some(
|
|
4296
|
+
(t) => BigInt(t.amount) <= 0n || BigInt(t.amount) >= 1n << 256n
|
|
4297
|
+
) || new Set(i.transfers.map((t) => t.to.toLowerCase())).size !== i.transfers.length)
|
|
4298
|
+
throw new Error("Invalid token deposit shares.");
|
|
4299
|
+
const send = async (initial) => {
|
|
4300
|
+
let body = initial;
|
|
4301
|
+
save(key2, body);
|
|
4302
|
+
try {
|
|
4303
|
+
if (!body.serializedTransaction) {
|
|
4304
|
+
const prepared = await postSponsorBatchTransfer({
|
|
4305
|
+
apiKey: i.apiKey,
|
|
4306
|
+
baseUrl: i.baseUrl,
|
|
4307
|
+
body
|
|
4308
|
+
});
|
|
4309
|
+
if (!prepared.serializedTransaction || (0, import_viem9.keccak256)(prepared.serializedTransaction) !== prepared.txHash)
|
|
4310
|
+
throw new Error(
|
|
4311
|
+
"Sponsorship API did not return a valid prepared transaction."
|
|
4312
|
+
);
|
|
4313
|
+
body = {
|
|
4314
|
+
...body,
|
|
4315
|
+
serializedTransaction: prepared.serializedTransaction
|
|
4316
|
+
};
|
|
4317
|
+
save(key2, body);
|
|
4377
4318
|
}
|
|
4378
|
-
const
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
});
|
|
4383
|
-
const nonce = randomPermit2Nonce();
|
|
4384
|
-
const deadline = BigInt(
|
|
4385
|
-
Math.floor(Date.now() / 1e3) + PERMIT_WINDOW_SECONDS
|
|
4386
|
-
);
|
|
4387
|
-
const typedData = buildPermitTransferFromTypedData({
|
|
4388
|
-
chainId: cid,
|
|
4389
|
-
message: {
|
|
4390
|
-
permitted: { token, amount: amountWei },
|
|
4391
|
-
spender: relayer,
|
|
4392
|
-
nonce,
|
|
4393
|
-
deadline
|
|
4394
|
-
}
|
|
4395
|
-
});
|
|
4396
|
-
const signature = await wallet.signTypedData({
|
|
4397
|
-
account: deps.ownerAddress,
|
|
4398
|
-
...typedData
|
|
4399
|
-
});
|
|
4400
|
-
deps.onApproved?.();
|
|
4401
|
-
const result = await post({
|
|
4402
|
-
baseUrl: deps.baseUrl,
|
|
4403
|
-
apiKey: deps.apiKey,
|
|
4404
|
-
...verification?.agentId === "yieldseeker" ? { yieldseekerSignature: verification.signature } : {},
|
|
4405
|
-
body: {
|
|
4406
|
-
chainId: cid,
|
|
4407
|
-
token,
|
|
4408
|
-
from: deps.ownerAddress,
|
|
4409
|
-
to: smartWallet,
|
|
4410
|
-
amount,
|
|
4411
|
-
nonce: nonce.toString(),
|
|
4412
|
-
deadline: deadline.toString(),
|
|
4413
|
-
signature,
|
|
4414
|
-
...verification?.agentId === "yieldseeker" ? {
|
|
4415
|
-
yieldseekerUserId: verification.userId,
|
|
4416
|
-
yieldseekerAgentId: verification.yieldseekerAgentId
|
|
4417
|
-
} : {}
|
|
4418
|
-
}
|
|
4319
|
+
const result = await postSponsorBatchTransfer({
|
|
4320
|
+
apiKey: i.apiKey,
|
|
4321
|
+
baseUrl: i.baseUrl,
|
|
4322
|
+
body
|
|
4419
4323
|
});
|
|
4324
|
+
if (result.txHash !== (0, import_viem9.keccak256)(body.serializedTransaction))
|
|
4325
|
+
throw new Error(
|
|
4326
|
+
"Sponsorship receipt does not match the pending transaction."
|
|
4327
|
+
);
|
|
4328
|
+
clear(key2);
|
|
4420
4329
|
return result.txHash;
|
|
4330
|
+
} catch (error) {
|
|
4331
|
+
if (!body.serializedTransaction || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
4332
|
+
clear(key2);
|
|
4333
|
+
throw error;
|
|
4421
4334
|
}
|
|
4335
|
+
};
|
|
4336
|
+
const saved = read(key2);
|
|
4337
|
+
if (saved) {
|
|
4338
|
+
const previous = JSON.parse(saved);
|
|
4339
|
+
if (previous.chainId !== i.chainId || !(0, import_viem9.isAddressEqual)(previous.from, i.owner) || !(0, import_viem9.isAddressEqual)(previous.token, i.token) || planOf(previous.transfers) !== plan)
|
|
4340
|
+
throw new Error(
|
|
4341
|
+
"Retry the previous token deposit and agent split first to reconcile its status."
|
|
4342
|
+
);
|
|
4343
|
+
i.onApproved?.();
|
|
4344
|
+
return send({ ...previous, transfers: i.transfers });
|
|
4345
|
+
}
|
|
4346
|
+
const total = i.transfers.reduce((sum, t) => sum + BigInt(t.amount), 0n);
|
|
4347
|
+
const [balance, allowance] = await Promise.all([
|
|
4348
|
+
readErc20Balance(i.pub, i.token, i.owner),
|
|
4349
|
+
readPermit2Allowance(i.pub, i.token, i.owner)
|
|
4350
|
+
]);
|
|
4351
|
+
if (balance < total)
|
|
4352
|
+
throw new OwneyError(
|
|
4353
|
+
"DEPOSIT_INSUFFICIENT_BALANCE",
|
|
4354
|
+
"Insufficient token balance for this deposit."
|
|
4355
|
+
);
|
|
4356
|
+
if (allowance < total)
|
|
4357
|
+
throw new OwneyError(
|
|
4358
|
+
"PERMIT2_APPROVAL_REQUIRED",
|
|
4359
|
+
"token deposits need a one-time Permit2 approval."
|
|
4360
|
+
);
|
|
4361
|
+
const relayer = await getSponsorRelayerAddress({
|
|
4362
|
+
apiKey: i.apiKey,
|
|
4363
|
+
baseUrl: i.baseUrl,
|
|
4364
|
+
chainId: i.chainId
|
|
4365
|
+
});
|
|
4366
|
+
const now = (await i.pub.getBlock()).timestamp;
|
|
4367
|
+
const unsigned = {
|
|
4368
|
+
chainId: i.chainId,
|
|
4369
|
+
token: i.token,
|
|
4370
|
+
from: i.owner,
|
|
4371
|
+
transfers: i.transfers,
|
|
4372
|
+
nonce: randomPermit2Nonce().toString(),
|
|
4373
|
+
deadline: (now + 900n).toString()
|
|
4374
|
+
};
|
|
4375
|
+
const signature = await i.wallet.signTypedData({
|
|
4376
|
+
account: i.owner,
|
|
4377
|
+
...batchTypedData(unsigned, relayer)
|
|
4378
|
+
});
|
|
4379
|
+
i.onApproved?.();
|
|
4380
|
+
return send({ ...unsigned, signature });
|
|
4381
|
+
}
|
|
4382
|
+
|
|
4383
|
+
// src/lib/sponsored-token-deposit.ts
|
|
4384
|
+
function makeSponsoredTokenCallback(deps) {
|
|
4385
|
+
const batch = async (chainId, transfers) => {
|
|
4386
|
+
if (chainId !== 8453 && chainId !== 42161 && chainId !== 1)
|
|
4387
|
+
throw new OwneyError(
|
|
4388
|
+
"CHAIN_UNSUPPORTED",
|
|
4389
|
+
`No sponsored token configured for chain ${chainId}`
|
|
4390
|
+
);
|
|
4391
|
+
const token = deps.tokenAddressByChain[chainId];
|
|
4392
|
+
if (!token)
|
|
4393
|
+
throw new OwneyError(
|
|
4394
|
+
"CHAIN_UNSUPPORTED",
|
|
4395
|
+
`No sponsored token configured for chain ${chainId}`
|
|
4396
|
+
);
|
|
4397
|
+
const pub = deps.getPublicClient(chainId), wallet = deps.getWalletClient(chainId);
|
|
4398
|
+
await ensureWalletOnChain(pub, wallet, chainId);
|
|
4399
|
+
return sponsorTokenBatch({
|
|
4400
|
+
apiKey: deps.apiKey,
|
|
4401
|
+
baseUrl: deps.baseUrl,
|
|
4402
|
+
owner: deps.ownerAddress,
|
|
4403
|
+
token,
|
|
4404
|
+
chainId,
|
|
4405
|
+
transfers,
|
|
4406
|
+
pub,
|
|
4407
|
+
wallet,
|
|
4408
|
+
onApproved: deps.onApproved
|
|
4409
|
+
});
|
|
4410
|
+
};
|
|
4411
|
+
const callback = makeVerificationAwareDepositCallback(
|
|
4412
|
+
(to, chainId, amount, verification) => batch(chainId, [toBatchTransfer(to, amount, verification)])
|
|
4422
4413
|
);
|
|
4414
|
+
registerDepositBatch(callback, batch);
|
|
4415
|
+
return callback;
|
|
4416
|
+
}
|
|
4417
|
+
|
|
4418
|
+
// src/lib/agent-deposit-batch.ts
|
|
4419
|
+
function deferred() {
|
|
4420
|
+
let resolve, reject;
|
|
4421
|
+
const promise = new Promise((yes, no) => {
|
|
4422
|
+
resolve = yes;
|
|
4423
|
+
reject = no;
|
|
4424
|
+
});
|
|
4425
|
+
void promise.catch(() => {
|
|
4426
|
+
});
|
|
4427
|
+
return { promise, resolve, reject };
|
|
4428
|
+
}
|
|
4429
|
+
async function runAgentDepositBatch(chainId, legs, transfer) {
|
|
4430
|
+
const funding = deferred();
|
|
4431
|
+
const tasks = [];
|
|
4432
|
+
const transfers = [];
|
|
4433
|
+
try {
|
|
4434
|
+
for (const leg of legs) {
|
|
4435
|
+
const ready = deferred();
|
|
4436
|
+
let entered = false;
|
|
4437
|
+
const callback = makeVerificationAwareDepositCallback(
|
|
4438
|
+
(to, cid, amount, verification) => {
|
|
4439
|
+
if (entered || cid !== chainId || BigInt(amount) !== BigInt(leg.amount)) {
|
|
4440
|
+
const error = new Error(
|
|
4441
|
+
"Agent changed its prepared deposit share."
|
|
4442
|
+
);
|
|
4443
|
+
ready.reject(error);
|
|
4444
|
+
throw error;
|
|
4445
|
+
}
|
|
4446
|
+
entered = true;
|
|
4447
|
+
ready.resolve(toBatchTransfer(to, amount, verification));
|
|
4448
|
+
return funding.promise;
|
|
4449
|
+
}
|
|
4450
|
+
);
|
|
4451
|
+
const task = Promise.resolve().then(() => leg.run(callback));
|
|
4452
|
+
tasks.push(task);
|
|
4453
|
+
void task.then(
|
|
4454
|
+
() => {
|
|
4455
|
+
if (!entered)
|
|
4456
|
+
ready.reject(
|
|
4457
|
+
new Error("Agent did not prepare a deposit transfer.")
|
|
4458
|
+
);
|
|
4459
|
+
},
|
|
4460
|
+
(error) => ready.reject(error)
|
|
4461
|
+
);
|
|
4462
|
+
transfers.push(await ready.promise);
|
|
4463
|
+
}
|
|
4464
|
+
const txHash = await transfer(chainId, transfers);
|
|
4465
|
+
funding.resolve(txHash);
|
|
4466
|
+
const settled = await Promise.allSettled(tasks);
|
|
4467
|
+
const agentResults = {};
|
|
4468
|
+
const failures = [];
|
|
4469
|
+
for (const [index, result] of settled.entries()) {
|
|
4470
|
+
if (result.status === "fulfilled")
|
|
4471
|
+
agentResults[legs[index].id] = result.value;
|
|
4472
|
+
else failures.push(legs[index].id);
|
|
4473
|
+
}
|
|
4474
|
+
if (failures.length)
|
|
4475
|
+
throw new OwneyError(
|
|
4476
|
+
"DEPOSIT_PARTIAL_FAILURE",
|
|
4477
|
+
"The deposit was sent to all agents, but some agent updates could not be confirmed. Check activity before depositing again.",
|
|
4478
|
+
{
|
|
4479
|
+
txHash,
|
|
4480
|
+
fundsSubmitted: true,
|
|
4481
|
+
agentResults,
|
|
4482
|
+
failedAgentIds: failures
|
|
4483
|
+
}
|
|
4484
|
+
);
|
|
4485
|
+
return { agentResults };
|
|
4486
|
+
} catch (error) {
|
|
4487
|
+
funding.reject(error);
|
|
4488
|
+
await Promise.allSettled(tasks);
|
|
4489
|
+
throw error;
|
|
4490
|
+
}
|
|
4423
4491
|
}
|
|
4424
4492
|
|
|
4425
4493
|
// src/lib/sponsored-calls-deposit.ts
|
|
4426
|
-
var
|
|
4494
|
+
var import_viem10 = require("viem");
|
|
4427
4495
|
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
4428
4496
|
var DEFAULT_MAX_POLLS = 30;
|
|
4429
4497
|
async function paymasterSupported(provider, owner, chainId) {
|
|
@@ -4431,7 +4499,7 @@ async function paymasterSupported(provider, owner, chainId) {
|
|
|
4431
4499
|
method: "wallet_getCapabilities",
|
|
4432
4500
|
params: [owner]
|
|
4433
4501
|
});
|
|
4434
|
-
const forChain = caps?.[(0,
|
|
4502
|
+
const forChain = caps?.[(0, import_viem10.toHex)(chainId)] ?? caps?.[String(chainId)];
|
|
4435
4503
|
return Boolean(forChain?.paymasterService?.supported);
|
|
4436
4504
|
}
|
|
4437
4505
|
function makeSponsoredCallsCallback(deps) {
|
|
@@ -4449,7 +4517,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4449
4517
|
}
|
|
4450
4518
|
return new URL(configured, origin).toString();
|
|
4451
4519
|
};
|
|
4452
|
-
|
|
4520
|
+
const batch = async (chainId, transfers) => {
|
|
4453
4521
|
const cid = chainId;
|
|
4454
4522
|
const token = deps.tokenAddressByChain[cid];
|
|
4455
4523
|
if (!token) {
|
|
@@ -4465,19 +4533,24 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4465
4533
|
{ chainId }
|
|
4466
4534
|
);
|
|
4467
4535
|
}
|
|
4468
|
-
const
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4536
|
+
const calls = transfers.map((transfer) => ({
|
|
4537
|
+
to: token,
|
|
4538
|
+
value: "0x0",
|
|
4539
|
+
data: (0, import_viem10.encodeFunctionData)({
|
|
4540
|
+
abi: import_viem10.erc20Abi,
|
|
4541
|
+
functionName: "transfer",
|
|
4542
|
+
args: [transfer.to, BigInt(transfer.amount)]
|
|
4543
|
+
})
|
|
4544
|
+
}));
|
|
4473
4545
|
let paymasterUrl = absolutePaymasterUrl();
|
|
4474
|
-
|
|
4475
|
-
|
|
4546
|
+
for (const transfer of transfers) {
|
|
4547
|
+
const verification = transfer.yieldseeker;
|
|
4548
|
+
if (!verification) continue;
|
|
4549
|
+
if (chainId !== 8453)
|
|
4476
4550
|
throw new OwneyError(
|
|
4477
4551
|
"CHAIN_UNSUPPORTED",
|
|
4478
|
-
`Yieldseeker
|
|
4552
|
+
`Yieldseeker sponsorship is not available on chain ${chainId}.`
|
|
4479
4553
|
);
|
|
4480
|
-
}
|
|
4481
4554
|
const { intent } = await postPaymasterIntent({
|
|
4482
4555
|
baseUrl: deps.routingApiBaseUrl,
|
|
4483
4556
|
apiKey: deps.apiKey,
|
|
@@ -4486,14 +4559,14 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4486
4559
|
chainId,
|
|
4487
4560
|
token,
|
|
4488
4561
|
from: deps.ownerAddress,
|
|
4489
|
-
to:
|
|
4490
|
-
amount,
|
|
4562
|
+
to: transfer.to,
|
|
4563
|
+
amount: transfer.amount,
|
|
4491
4564
|
yieldseekerUserId: verification.userId,
|
|
4492
|
-
yieldseekerAgentId: verification.
|
|
4565
|
+
yieldseekerAgentId: verification.agentId
|
|
4493
4566
|
}
|
|
4494
4567
|
});
|
|
4495
4568
|
const url = new URL(paymasterUrl);
|
|
4496
|
-
url.searchParams.
|
|
4569
|
+
url.searchParams.append("owneyIntent", intent);
|
|
4497
4570
|
paymasterUrl = url.toString();
|
|
4498
4571
|
}
|
|
4499
4572
|
const sendResult = await deps.provider.request({
|
|
@@ -4502,9 +4575,9 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4502
4575
|
{
|
|
4503
4576
|
version: "2.0.0",
|
|
4504
4577
|
from: deps.ownerAddress,
|
|
4505
|
-
chainId: (0,
|
|
4506
|
-
atomicRequired:
|
|
4507
|
-
calls
|
|
4578
|
+
chainId: (0, import_viem10.toHex)(chainId),
|
|
4579
|
+
atomicRequired: transfers.length > 1,
|
|
4580
|
+
calls,
|
|
4508
4581
|
capabilities: {
|
|
4509
4582
|
paymasterService: { url: paymasterUrl }
|
|
4510
4583
|
}
|
|
@@ -4526,7 +4599,24 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4526
4599
|
params: [callsId]
|
|
4527
4600
|
});
|
|
4528
4601
|
const txHash = status?.receipts?.[0]?.transactionHash;
|
|
4529
|
-
if (
|
|
4602
|
+
if (status?.receipts?.some((receipt) => receipt.status === "0x0") || typeof status?.status === "number" && status.status >= 400) {
|
|
4603
|
+
throw new OwneyError(
|
|
4604
|
+
"SPONSOR_REQUEST_FAILED",
|
|
4605
|
+
"The sponsored deposit did not complete successfully.",
|
|
4606
|
+
{ chainId, callsId, safeToFallback: false }
|
|
4607
|
+
);
|
|
4608
|
+
}
|
|
4609
|
+
if (txHash && (transfers.length === 1 || status?.status === 200 || status?.status === "CONFIRMED")) {
|
|
4610
|
+
if (status?.receipts?.some(
|
|
4611
|
+
(receipt) => receipt.transactionHash !== txHash
|
|
4612
|
+
))
|
|
4613
|
+
throw new OwneyError(
|
|
4614
|
+
"SPONSORED_CALLS_NO_RECEIPT",
|
|
4615
|
+
"The wallet returned multiple transactions for an atomic deposit. Check activity before trying again.",
|
|
4616
|
+
{ chainId, callsId }
|
|
4617
|
+
);
|
|
4618
|
+
return txHash;
|
|
4619
|
+
}
|
|
4530
4620
|
if (pollIntervalMs > 0) {
|
|
4531
4621
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
4532
4622
|
}
|
|
@@ -4536,7 +4626,12 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
4536
4626
|
`No receipt for calls ${callsId} after ${maxPolls} polls; the deposit may still settle.`,
|
|
4537
4627
|
{ chainId, callsId }
|
|
4538
4628
|
);
|
|
4539
|
-
}
|
|
4629
|
+
};
|
|
4630
|
+
const callback = makeVerificationAwareDepositCallback(
|
|
4631
|
+
(to, chainId, amount, verification) => batch(chainId, [toBatchTransfer(to, amount, verification)])
|
|
4632
|
+
);
|
|
4633
|
+
registerDepositBatch(callback, batch);
|
|
4634
|
+
return callback;
|
|
4540
4635
|
}
|
|
4541
4636
|
|
|
4542
4637
|
// src/client.ts
|
|
@@ -4575,6 +4670,11 @@ var SPONSORED_WETH_BY_CHAIN = {
|
|
|
4575
4670
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
4576
4671
|
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
4577
4672
|
};
|
|
4673
|
+
var SPONSORED_TOKENS_BY_ASSET = { USDC: SPONSORED_USDC_BY_CHAIN, WETH: SPONSORED_WETH_BY_CHAIN };
|
|
4674
|
+
function sponsoredTokensFor(asset) {
|
|
4675
|
+
if (!Object.prototype.hasOwnProperty.call(SPONSORED_TOKENS_BY_ASSET, asset)) throw new OwneyError("ASSET_UNSUPPORTED", `No sponsored token configured for ${asset}`);
|
|
4676
|
+
return SPONSORED_TOKENS_BY_ASSET[asset];
|
|
4677
|
+
}
|
|
4578
4678
|
function shouldFallbackToUserPaid(error, asset, appCallback) {
|
|
4579
4679
|
return (asset === "WETH" || asset === "USDC") && appCallback === void 0 && error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED" && error.details?.safeToFallback === true;
|
|
4580
4680
|
}
|
|
@@ -4709,18 +4809,13 @@ var OwneySDK = class {
|
|
|
4709
4809
|
}
|
|
4710
4810
|
return this.state.provider;
|
|
4711
4811
|
}
|
|
4712
|
-
/**
|
|
4713
|
-
* Lazily builds (and caches) the default EIP-3009 sponsored deposit callback
|
|
4714
|
-
* used when the caller omits `depositCallback`. Wraps the connected EIP-1193
|
|
4715
|
-
* provider with viem `custom(provider)` to read token meta and sign the
|
|
4716
|
-
* `TransferWithAuthorization`, then POSTs to the sponsor API.
|
|
4717
|
-
*/
|
|
4812
|
+
/** Builds the default USDC batch callback for the connected wallet. */
|
|
4718
4813
|
getDefaultSponsoredCallback(onApproved) {
|
|
4719
4814
|
if (!onApproved && this.cachedSponsoredCallback)
|
|
4720
4815
|
return this.cachedSponsoredCallback;
|
|
4721
4816
|
const provider = this.requireConnectedProvider();
|
|
4722
4817
|
const owner = this.state.walletAddress;
|
|
4723
|
-
const callback =
|
|
4818
|
+
const callback = makeSponsoredTokenCallback({
|
|
4724
4819
|
apiKey: this.apiKey,
|
|
4725
4820
|
baseUrl: this.routingApiBaseUrl,
|
|
4726
4821
|
ownerAddress: owner,
|
|
@@ -4729,25 +4824,20 @@ var OwneySDK = class {
|
|
|
4729
4824
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4730
4825
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4731
4826
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4732
|
-
getPublicClient: (cid) => (0,
|
|
4827
|
+
getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
|
|
4733
4828
|
chain: VIEM_CHAIN2[cid],
|
|
4734
|
-
transport: (0,
|
|
4829
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4735
4830
|
}),
|
|
4736
|
-
getWalletClient: (cid) => (0,
|
|
4831
|
+
getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
|
|
4737
4832
|
account: owner,
|
|
4738
4833
|
chain: VIEM_CHAIN2[cid],
|
|
4739
|
-
transport: (0,
|
|
4834
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4740
4835
|
})
|
|
4741
4836
|
});
|
|
4742
4837
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
4743
4838
|
return callback;
|
|
4744
4839
|
}
|
|
4745
|
-
/**
|
|
4746
|
-
* Lazily builds (and caches) the default Permit2 sponsored WETH deposit
|
|
4747
|
-
* callback used when the caller omits `depositCallback` for a WETH
|
|
4748
|
-
* deposit. Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
|
|
4749
|
-
* `PermitTransferFrom` instead of an EIP-3009 authorization.
|
|
4750
|
-
*/
|
|
4840
|
+
/** Builds the wallet-native sponsored calls callback for compatible paymasters. */
|
|
4751
4841
|
getDefaultSponsoredCallsCallback(asset, onApproved) {
|
|
4752
4842
|
const cached = this.cachedSponsoredCallsCallbacks.get(asset);
|
|
4753
4843
|
if (!onApproved && cached) return cached;
|
|
@@ -4759,7 +4849,7 @@ var OwneySDK = class {
|
|
|
4759
4849
|
ownerAddress: this.state.walletAddress,
|
|
4760
4850
|
paymasterServiceUrl: this.paymasterServiceUrl,
|
|
4761
4851
|
onApproved,
|
|
4762
|
-
tokenAddressByChain: asset
|
|
4852
|
+
tokenAddressByChain: sponsoredTokensFor(asset)
|
|
4763
4853
|
});
|
|
4764
4854
|
if (!onApproved) this.cachedSponsoredCallsCallbacks.set(asset, callback);
|
|
4765
4855
|
return callback;
|
|
@@ -4768,14 +4858,14 @@ var OwneySDK = class {
|
|
|
4768
4858
|
* Lazily builds (and caches) the default Permit2 sponsored WETH deposit
|
|
4769
4859
|
* callback used when the caller omits `depositCallback` for a WETH deposit.
|
|
4770
4860
|
* Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
|
|
4771
|
-
*
|
|
4861
|
+
* single-use batch authorization instead of an EIP-3009 authorization.
|
|
4772
4862
|
*/
|
|
4773
4863
|
getDefaultWethSponsoredCallback(onApproved) {
|
|
4774
4864
|
if (!onApproved && this.cachedWethSponsoredCallback)
|
|
4775
4865
|
return this.cachedWethSponsoredCallback;
|
|
4776
4866
|
const provider = this.requireConnectedProvider();
|
|
4777
4867
|
const owner = this.state.walletAddress;
|
|
4778
|
-
const callback =
|
|
4868
|
+
const callback = makeSponsoredTokenCallback({
|
|
4779
4869
|
apiKey: this.apiKey,
|
|
4780
4870
|
baseUrl: this.routingApiBaseUrl,
|
|
4781
4871
|
ownerAddress: owner,
|
|
@@ -4784,14 +4874,14 @@ var OwneySDK = class {
|
|
|
4784
4874
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
4785
4875
|
// PublicClient/WalletClient param types — structurally identical at
|
|
4786
4876
|
// runtime, but the two share a name TS treats as unrelated.
|
|
4787
|
-
getPublicClient: (cid) => (0,
|
|
4877
|
+
getPublicClient: (cid) => (0, import_viem11.createPublicClient)({
|
|
4788
4878
|
chain: VIEM_CHAIN2[cid],
|
|
4789
|
-
transport: (0,
|
|
4879
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4790
4880
|
}),
|
|
4791
|
-
getWalletClient: (cid) => (0,
|
|
4881
|
+
getWalletClient: (cid) => (0, import_viem11.createWalletClient)({
|
|
4792
4882
|
account: owner,
|
|
4793
4883
|
chain: VIEM_CHAIN2[cid],
|
|
4794
|
-
transport: (0,
|
|
4884
|
+
transport: (0, import_viem11.custom)(provider)
|
|
4795
4885
|
})
|
|
4796
4886
|
});
|
|
4797
4887
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -5081,7 +5171,8 @@ var OwneySDK = class {
|
|
|
5081
5171
|
* @param options.asset - Asset symbol to deposit (e.g. "USDC")
|
|
5082
5172
|
* @param options.depositCallback - Callback that performs the token transfer and returns a tx hash.
|
|
5083
5173
|
* When agentId is omitted, this callback is invoked once per eligible agent with that agent's
|
|
5084
|
-
* split amount and smart wallet address
|
|
5174
|
+
* split amount and smart wallet address. Default sponsored deposits batch
|
|
5175
|
+
* all shares into one signature; custom callbacks still run once per agent.
|
|
5085
5176
|
* @param options.agentId - Optional explicit target. Otherwise split equally,
|
|
5086
5177
|
* or fund remaining agents when a recovery deposit cannot meet every minimum.
|
|
5087
5178
|
* @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
|
|
@@ -5166,6 +5257,39 @@ var OwneySDK = class {
|
|
|
5166
5257
|
}
|
|
5167
5258
|
);
|
|
5168
5259
|
}
|
|
5260
|
+
const batchTransfer = getDepositBatchTransfer(effectiveCallback);
|
|
5261
|
+
if (!depositCallback && batchTransfer) {
|
|
5262
|
+
return runAgentDepositBatch(
|
|
5263
|
+
chainId,
|
|
5264
|
+
agentAmounts.map(({ agent, amount: amount2 }) => ({
|
|
5265
|
+
id: agent.id,
|
|
5266
|
+
amount: amount2,
|
|
5267
|
+
run: (callback) => withFailureReporting(
|
|
5268
|
+
this.apiKey,
|
|
5269
|
+
agent.id,
|
|
5270
|
+
() => agent.deposit(state, chainId, amount2, asset, callback),
|
|
5271
|
+
this.routingApiBaseUrl
|
|
5272
|
+
)
|
|
5273
|
+
})),
|
|
5274
|
+
async (cid, transfers) => {
|
|
5275
|
+
try {
|
|
5276
|
+
return await batchTransfer(cid, transfers);
|
|
5277
|
+
} catch (error) {
|
|
5278
|
+
if (!(error instanceof OwneyError) || error.code !== "PERMIT2_APPROVAL_REQUIRED")
|
|
5279
|
+
throw error;
|
|
5280
|
+
const requiredAmount = transfers.reduce(
|
|
5281
|
+
(sum, transfer) => sum + BigInt(transfer.amount),
|
|
5282
|
+
0n
|
|
5283
|
+
);
|
|
5284
|
+
await this.approvePermit2(
|
|
5285
|
+
asset,
|
|
5286
|
+
requiredAmount
|
|
5287
|
+
);
|
|
5288
|
+
return batchTransfer(cid, transfers);
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
);
|
|
5292
|
+
}
|
|
5169
5293
|
const agentResults = {};
|
|
5170
5294
|
for (const [
|
|
5171
5295
|
index,
|
|
@@ -5205,7 +5329,7 @@ var OwneySDK = class {
|
|
|
5205
5329
|
*
|
|
5206
5330
|
* 1. Missing Permit2 allowance: when the app did not supply its own
|
|
5207
5331
|
* callback and the attempt fails with `PERMIT2_APPROVAL_REQUIRED` on a
|
|
5208
|
-
*
|
|
5332
|
+
* token deposit, this is the wallet's first Permit2 deposit for that token. We send
|
|
5209
5333
|
* the one-time (user-paid) Permit2 approval via `approvePermit2()` and
|
|
5210
5334
|
* retry the SAME sponsored attempt once. Bounded to one approval attempt
|
|
5211
5335
|
* per call so a wallet/agent that keeps reporting the allowance as
|
|
@@ -5242,12 +5366,15 @@ var OwneySDK = class {
|
|
|
5242
5366
|
try {
|
|
5243
5367
|
return await attempt(effectiveCallback);
|
|
5244
5368
|
} catch (error) {
|
|
5245
|
-
if (!approvalAttempted && appCallback === void 0 && asset === "WETH" && error instanceof OwneyError && error.code === "PERMIT2_APPROVAL_REQUIRED") {
|
|
5369
|
+
if (!approvalAttempted && appCallback === void 0 && (asset === "WETH" || asset === "USDC") && error instanceof OwneyError && error.code === "PERMIT2_APPROVAL_REQUIRED") {
|
|
5246
5370
|
approvalAttempted = true;
|
|
5247
5371
|
console.warn(
|
|
5248
|
-
"[owney-sdk] First
|
|
5372
|
+
"[owney-sdk] First token deposit: sending one-time Permit2 approval..."
|
|
5373
|
+
);
|
|
5374
|
+
await this.approvePermit2(
|
|
5375
|
+
asset,
|
|
5376
|
+
BigInt(amount)
|
|
5249
5377
|
);
|
|
5250
|
-
await this.approvePermit2();
|
|
5251
5378
|
continue;
|
|
5252
5379
|
}
|
|
5253
5380
|
if (!shouldFallbackToUserPaid(error, asset, appCallback)) throw error;
|
|
@@ -5900,43 +6027,44 @@ var OwneySDK = class {
|
|
|
5900
6027
|
return pending;
|
|
5901
6028
|
}
|
|
5902
6029
|
/**
|
|
5903
|
-
*
|
|
5904
|
-
*
|
|
5905
|
-
*
|
|
5906
|
-
*
|
|
5907
|
-
*
|
|
6030
|
+
* User-paid approval of Permit2 on the selected token for the active chain.
|
|
6031
|
+
* Approves exactly the pending deposit amount. Another approval is required
|
|
6032
|
+
* for a later deposit once this allowance has been consumed. Resolves after
|
|
6033
|
+
* one confirmation so the subsequent deposit attempt sees the new allowance.
|
|
6034
|
+
*
|
|
6035
|
+
* @param requiredAmount Raw base-unit amount the pending deposit must cover.
|
|
5908
6036
|
* @returns the approval transaction hash.
|
|
5909
6037
|
*/
|
|
5910
|
-
async approvePermit2(asset = "WETH") {
|
|
5911
|
-
void asset;
|
|
6038
|
+
async approvePermit2(asset = "WETH", requiredAmount = 0n) {
|
|
5912
6039
|
const state = this.requireState();
|
|
5913
6040
|
const chainId = this.requireChainId();
|
|
5914
|
-
this.
|
|
5915
|
-
const token =
|
|
6041
|
+
this.getEligibleAgents(chainId, asset, { excludeDisabled: true });
|
|
6042
|
+
const token = sponsoredTokensFor(asset)[chainId];
|
|
5916
6043
|
if (!token) {
|
|
5917
6044
|
throw new OwneyError(
|
|
5918
6045
|
"CHAIN_UNSUPPORTED",
|
|
5919
|
-
`No sponsored
|
|
6046
|
+
`No sponsored token on chain ${chainId}`
|
|
5920
6047
|
);
|
|
5921
6048
|
}
|
|
5922
6049
|
const provider = this.requireConnectedProvider();
|
|
5923
|
-
const
|
|
6050
|
+
const publicClient = (0, import_viem11.createPublicClient)({
|
|
6051
|
+
chain: VIEM_CHAIN2[chainId],
|
|
6052
|
+
transport: (0, import_viem11.custom)(provider)
|
|
6053
|
+
});
|
|
6054
|
+
const approvalAmount = permit2ApprovalAmount(requiredAmount);
|
|
6055
|
+
const wallet = (0, import_viem11.createWalletClient)({
|
|
5924
6056
|
account: state.walletAddress,
|
|
5925
6057
|
chain: VIEM_CHAIN2[chainId],
|
|
5926
|
-
transport: (0,
|
|
6058
|
+
transport: (0, import_viem11.custom)(provider)
|
|
5927
6059
|
});
|
|
5928
6060
|
const hash = await wallet.writeContract({
|
|
5929
6061
|
address: token,
|
|
5930
6062
|
abi: ERC20_ALLOWANCE_ABI,
|
|
5931
6063
|
functionName: "approve",
|
|
5932
|
-
args: [PERMIT2_ADDRESS,
|
|
6064
|
+
args: [PERMIT2_ADDRESS, approvalAmount],
|
|
5933
6065
|
account: state.walletAddress,
|
|
5934
6066
|
chain: VIEM_CHAIN2[chainId]
|
|
5935
6067
|
});
|
|
5936
|
-
const publicClient = (0, import_viem9.createPublicClient)({
|
|
5937
|
-
chain: VIEM_CHAIN2[chainId],
|
|
5938
|
-
transport: (0, import_viem9.custom)(provider)
|
|
5939
|
-
});
|
|
5940
6068
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
5941
6069
|
hash,
|
|
5942
6070
|
confirmations: 1
|
|
@@ -6049,7 +6177,7 @@ var OwneySDK = class {
|
|
|
6049
6177
|
};
|
|
6050
6178
|
|
|
6051
6179
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
6052
|
-
var
|
|
6180
|
+
var import_viem12 = require("viem");
|
|
6053
6181
|
var import_siwe2 = require("siwe");
|
|
6054
6182
|
var import_sdk2 = require("@zyfai/sdk");
|
|
6055
6183
|
|
|
@@ -6176,7 +6304,7 @@ function buildSIWXConfig(deps) {
|
|
|
6176
6304
|
issuedAt,
|
|
6177
6305
|
toString() {
|
|
6178
6306
|
return new import_siwe2.SiweMessage({
|
|
6179
|
-
address: (0,
|
|
6307
|
+
address: (0, import_viem12.getAddress)(accountAddress),
|
|
6180
6308
|
chainId: numericChainId(chainId),
|
|
6181
6309
|
domain,
|
|
6182
6310
|
uri,
|