@owney/sdk 0.7.25-beta.1 → 0.7.25-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2313,11 +2313,12 @@ async function postSponsorBatchTransfer(input) {
2313
2313
  // src/lib/permit2.ts
2314
2314
  var import_viem3 = require("viem");
2315
2315
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
2316
+ var MAX_UINT256 = 2n ** 256n - 1n;
2316
2317
  function permit2ApprovalAmount(requiredAmount) {
2317
2318
  if (requiredAmount <= 0n) {
2318
2319
  throw new Error("Permit2 approval requires a positive deposit amount");
2319
2320
  }
2320
- return requiredAmount;
2321
+ return MAX_UINT256;
2321
2322
  }
2322
2323
  var ERC20_ALLOWANCE_ABI = [
2323
2324
  {
@@ -2353,12 +2354,13 @@ function randomPermit2Nonce() {
2353
2354
  globalThis.crypto.getRandomValues(bytes);
2354
2355
  return BigInt((0, import_viem3.bytesToHex)(bytes));
2355
2356
  }
2356
- async function readPermit2Allowance(publicClient, token, owner) {
2357
+ async function readPermit2Allowance(publicClient, token, owner, blockNumber) {
2357
2358
  return publicClient.readContract({
2358
2359
  address: token,
2359
2360
  abi: ERC20_ALLOWANCE_ABI,
2360
2361
  functionName: "allowance",
2361
- args: [owner, PERMIT2_ADDRESS]
2362
+ args: [owner, PERMIT2_ADDRESS],
2363
+ ...blockNumber === void 0 ? {} : { blockNumber }
2362
2364
  });
2363
2365
  }
2364
2366
  async function readErc20Balance(publicClient, token, owner) {
@@ -4713,6 +4715,8 @@ function makeSponsoredCallsCallback(deps) {
4713
4715
  }
4714
4716
 
4715
4717
  // src/client.ts
4718
+ var PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS = 6;
4719
+ var PERMIT2_ALLOWANCE_VERIFY_DELAY_MS = 250;
4716
4720
  function encodeMultiAgentCursor(map) {
4717
4721
  return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
4718
4722
  }
@@ -5361,7 +5365,8 @@ var OwneySDK = class {
5361
5365
  );
5362
5366
  await this.approvePermit2(
5363
5367
  asset,
5364
- requiredAmount
5368
+ requiredAmount,
5369
+ cid
5365
5370
  );
5366
5371
  return batchTransfer(cid, transfers);
5367
5372
  }
@@ -5451,7 +5456,8 @@ var OwneySDK = class {
5451
5456
  );
5452
5457
  await this.approvePermit2(
5453
5458
  asset,
5454
- BigInt(amount)
5459
+ BigInt(amount),
5460
+ chainId
5455
5461
  );
5456
5462
  continue;
5457
5463
  }
@@ -6172,16 +6178,18 @@ var OwneySDK = class {
6172
6178
  }
6173
6179
  /**
6174
6180
  * User-paid approval of Permit2 on the selected token for the active chain.
6175
- * Approves exactly the pending deposit amount. Another approval is required
6176
- * for a later deposit once this allowance has been consumed. Resolves after
6177
- * one confirmation so the subsequent deposit attempt sees the new allowance.
6181
+ * Grants the maximum ERC20 allowance so later deposits do not require another
6182
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
6183
+ * sees the new allowance. Deposit retries pass their captured chain id so a
6184
+ * concurrent activation cannot redirect the approval to another network.
6178
6185
  *
6179
6186
  * @param requiredAmount Raw base-unit amount the pending deposit must cover.
6187
+ * @param expectedChainId Chain captured by the deposit that requested approval.
6180
6188
  * @returns the approval transaction hash.
6181
6189
  */
6182
- async approvePermit2(asset = "WETH", requiredAmount = 0n) {
6190
+ async approvePermit2(asset = "WETH", requiredAmount = 0n, expectedChainId) {
6183
6191
  const state = this.requireState();
6184
- const chainId = this.requireChainId();
6192
+ const chainId = expectedChainId ?? this.requireChainId();
6185
6193
  this.getEligibleAgents(chainId, asset, { excludeDisabled: true });
6186
6194
  const token = sponsoredTokensFor(asset)[chainId];
6187
6195
  if (!token) {
@@ -6201,6 +6209,7 @@ var OwneySDK = class {
6201
6209
  chain: VIEM_CHAIN2[chainId],
6202
6210
  transport: (0, import_viem11.custom)(provider)
6203
6211
  });
6212
+ await ensureWalletOnChain(publicClient, wallet, chainId);
6204
6213
  const hash = await wallet.writeContract({
6205
6214
  address: token,
6206
6215
  abi: ERC20_ALLOWANCE_ABI,
@@ -6216,7 +6225,42 @@ var OwneySDK = class {
6216
6225
  if (receipt.status !== "success") {
6217
6226
  throw new Error(`Permit2 approval reverted (tx ${hash})`);
6218
6227
  }
6219
- return hash;
6228
+ let observedAllowance = 0n;
6229
+ let verificationError;
6230
+ for (let attempt = 0; attempt < PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS; attempt += 1) {
6231
+ try {
6232
+ observedAllowance = await readPermit2Allowance(
6233
+ publicClient,
6234
+ token,
6235
+ state.walletAddress,
6236
+ attempt === 0 ? receipt.blockNumber : void 0
6237
+ );
6238
+ verificationError = void 0;
6239
+ if (observedAllowance >= requiredAmount) return hash;
6240
+ } catch (error) {
6241
+ verificationError = error;
6242
+ }
6243
+ if (attempt + 1 < PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS) {
6244
+ await new Promise(
6245
+ (resolve) => setTimeout(resolve, PERMIT2_ALLOWANCE_VERIFY_DELAY_MS)
6246
+ );
6247
+ }
6248
+ }
6249
+ throw new OwneyError(
6250
+ "PERMIT2_APPROVAL_REQUIRED",
6251
+ "Permit2 approval was confirmed, but the required token allowance was not observable.",
6252
+ {
6253
+ approvalConfirmed: true,
6254
+ approvalTxHash: hash,
6255
+ owner: state.walletAddress,
6256
+ token,
6257
+ spender: PERMIT2_ADDRESS,
6258
+ chainId,
6259
+ requiredAmount: requiredAmount.toString(),
6260
+ observedAllowance: observedAllowance.toString(),
6261
+ ...verificationError instanceof Error ? { verificationError: verificationError.message } : {}
6262
+ }
6263
+ );
6220
6264
  }
6221
6265
  // --- Discovery (no wallet required) ---
6222
6266
  /**
package/dist/index.d.cts CHANGED
@@ -793,14 +793,16 @@ declare class OwneySDK {
793
793
  ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
794
794
  /**
795
795
  * User-paid approval of Permit2 on the selected token for the active chain.
796
- * Approves exactly the pending deposit amount. Another approval is required
797
- * for a later deposit once this allowance has been consumed. Resolves after
798
- * one confirmation so the subsequent deposit attempt sees the new allowance.
796
+ * Grants the maximum ERC20 allowance so later deposits do not require another
797
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
798
+ * sees the new allowance. Deposit retries pass their captured chain id so a
799
+ * concurrent activation cannot redirect the approval to another network.
799
800
  *
800
801
  * @param requiredAmount Raw base-unit amount the pending deposit must cover.
802
+ * @param expectedChainId Chain captured by the deposit that requested approval.
801
803
  * @returns the approval transaction hash.
802
804
  */
803
- approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint): Promise<`0x${string}`>;
805
+ approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint, expectedChainId?: OwneySupportedChainId): Promise<`0x${string}`>;
804
806
  /**
805
807
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
806
808
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
package/dist/index.d.ts CHANGED
@@ -793,14 +793,16 @@ declare class OwneySDK {
793
793
  ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
794
794
  /**
795
795
  * User-paid approval of Permit2 on the selected token for the active chain.
796
- * Approves exactly the pending deposit amount. Another approval is required
797
- * for a later deposit once this allowance has been consumed. Resolves after
798
- * one confirmation so the subsequent deposit attempt sees the new allowance.
796
+ * Grants the maximum ERC20 allowance so later deposits do not require another
797
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
798
+ * sees the new allowance. Deposit retries pass their captured chain id so a
799
+ * concurrent activation cannot redirect the approval to another network.
799
800
  *
800
801
  * @param requiredAmount Raw base-unit amount the pending deposit must cover.
802
+ * @param expectedChainId Chain captured by the deposit that requested approval.
801
803
  * @returns the approval transaction hash.
802
804
  */
803
- approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint): Promise<`0x${string}`>;
805
+ approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint, expectedChainId?: OwneySupportedChainId): Promise<`0x${string}`>;
804
806
  /**
805
807
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
806
808
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
package/dist/index.js CHANGED
@@ -2287,11 +2287,12 @@ async function postSponsorBatchTransfer(input) {
2287
2287
  // src/lib/permit2.ts
2288
2288
  import { bytesToHex as bytesToHex2 } from "viem";
2289
2289
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
2290
+ var MAX_UINT256 = 2n ** 256n - 1n;
2290
2291
  function permit2ApprovalAmount(requiredAmount) {
2291
2292
  if (requiredAmount <= 0n) {
2292
2293
  throw new Error("Permit2 approval requires a positive deposit amount");
2293
2294
  }
2294
- return requiredAmount;
2295
+ return MAX_UINT256;
2295
2296
  }
2296
2297
  var ERC20_ALLOWANCE_ABI = [
2297
2298
  {
@@ -2327,12 +2328,13 @@ function randomPermit2Nonce() {
2327
2328
  globalThis.crypto.getRandomValues(bytes);
2328
2329
  return BigInt(bytesToHex2(bytes));
2329
2330
  }
2330
- async function readPermit2Allowance(publicClient, token, owner) {
2331
+ async function readPermit2Allowance(publicClient, token, owner, blockNumber) {
2331
2332
  return publicClient.readContract({
2332
2333
  address: token,
2333
2334
  abi: ERC20_ALLOWANCE_ABI,
2334
2335
  functionName: "allowance",
2335
- args: [owner, PERMIT2_ADDRESS]
2336
+ args: [owner, PERMIT2_ADDRESS],
2337
+ ...blockNumber === void 0 ? {} : { blockNumber }
2336
2338
  });
2337
2339
  }
2338
2340
  async function readErc20Balance(publicClient, token, owner) {
@@ -4700,6 +4702,8 @@ function makeSponsoredCallsCallback(deps) {
4700
4702
  }
4701
4703
 
4702
4704
  // src/client.ts
4705
+ var PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS = 6;
4706
+ var PERMIT2_ALLOWANCE_VERIFY_DELAY_MS = 250;
4703
4707
  function encodeMultiAgentCursor(map) {
4704
4708
  return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
4705
4709
  }
@@ -5348,7 +5352,8 @@ var OwneySDK = class {
5348
5352
  );
5349
5353
  await this.approvePermit2(
5350
5354
  asset,
5351
- requiredAmount
5355
+ requiredAmount,
5356
+ cid
5352
5357
  );
5353
5358
  return batchTransfer(cid, transfers);
5354
5359
  }
@@ -5438,7 +5443,8 @@ var OwneySDK = class {
5438
5443
  );
5439
5444
  await this.approvePermit2(
5440
5445
  asset,
5441
- BigInt(amount)
5446
+ BigInt(amount),
5447
+ chainId
5442
5448
  );
5443
5449
  continue;
5444
5450
  }
@@ -6159,16 +6165,18 @@ var OwneySDK = class {
6159
6165
  }
6160
6166
  /**
6161
6167
  * User-paid approval of Permit2 on the selected token for the active chain.
6162
- * Approves exactly the pending deposit amount. Another approval is required
6163
- * for a later deposit once this allowance has been consumed. Resolves after
6164
- * one confirmation so the subsequent deposit attempt sees the new allowance.
6168
+ * Grants the maximum ERC20 allowance so later deposits do not require another
6169
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
6170
+ * sees the new allowance. Deposit retries pass their captured chain id so a
6171
+ * concurrent activation cannot redirect the approval to another network.
6165
6172
  *
6166
6173
  * @param requiredAmount Raw base-unit amount the pending deposit must cover.
6174
+ * @param expectedChainId Chain captured by the deposit that requested approval.
6167
6175
  * @returns the approval transaction hash.
6168
6176
  */
6169
- async approvePermit2(asset = "WETH", requiredAmount = 0n) {
6177
+ async approvePermit2(asset = "WETH", requiredAmount = 0n, expectedChainId) {
6170
6178
  const state = this.requireState();
6171
- const chainId = this.requireChainId();
6179
+ const chainId = expectedChainId ?? this.requireChainId();
6172
6180
  this.getEligibleAgents(chainId, asset, { excludeDisabled: true });
6173
6181
  const token = sponsoredTokensFor(asset)[chainId];
6174
6182
  if (!token) {
@@ -6188,6 +6196,7 @@ var OwneySDK = class {
6188
6196
  chain: VIEM_CHAIN2[chainId],
6189
6197
  transport: custom3(provider)
6190
6198
  });
6199
+ await ensureWalletOnChain(publicClient, wallet, chainId);
6191
6200
  const hash = await wallet.writeContract({
6192
6201
  address: token,
6193
6202
  abi: ERC20_ALLOWANCE_ABI,
@@ -6203,7 +6212,42 @@ var OwneySDK = class {
6203
6212
  if (receipt.status !== "success") {
6204
6213
  throw new Error(`Permit2 approval reverted (tx ${hash})`);
6205
6214
  }
6206
- return hash;
6215
+ let observedAllowance = 0n;
6216
+ let verificationError;
6217
+ for (let attempt = 0; attempt < PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS; attempt += 1) {
6218
+ try {
6219
+ observedAllowance = await readPermit2Allowance(
6220
+ publicClient,
6221
+ token,
6222
+ state.walletAddress,
6223
+ attempt === 0 ? receipt.blockNumber : void 0
6224
+ );
6225
+ verificationError = void 0;
6226
+ if (observedAllowance >= requiredAmount) return hash;
6227
+ } catch (error) {
6228
+ verificationError = error;
6229
+ }
6230
+ if (attempt + 1 < PERMIT2_ALLOWANCE_VERIFY_ATTEMPTS) {
6231
+ await new Promise(
6232
+ (resolve) => setTimeout(resolve, PERMIT2_ALLOWANCE_VERIFY_DELAY_MS)
6233
+ );
6234
+ }
6235
+ }
6236
+ throw new OwneyError(
6237
+ "PERMIT2_APPROVAL_REQUIRED",
6238
+ "Permit2 approval was confirmed, but the required token allowance was not observable.",
6239
+ {
6240
+ approvalConfirmed: true,
6241
+ approvalTxHash: hash,
6242
+ owner: state.walletAddress,
6243
+ token,
6244
+ spender: PERMIT2_ADDRESS,
6245
+ chainId,
6246
+ requiredAmount: requiredAmount.toString(),
6247
+ observedAllowance: observedAllowance.toString(),
6248
+ ...verificationError instanceof Error ? { verificationError: verificationError.message } : {}
6249
+ }
6250
+ );
6207
6251
  }
6208
6252
  // --- Discovery (no wallet required) ---
6209
6253
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.25-beta.1",
3
+ "version": "0.7.25-beta.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",