@owney/sdk 0.7.28-beta.8 → 0.7.28

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 CHANGED
@@ -134,6 +134,13 @@ Deposit funds into a specific agent, or split equally across all agents if `agen
134
134
  | `options.depositCallback` | `DepositCallback` | Callback that performs the token transfer and returns a tx hash |
135
135
  | `options.agentId` | `AgentId` (optional) | Target agent. Omit to split equally across all agents. |
136
136
 
137
+ Zyfai's native transfer path uses `sendDeposit()`. It returns after the token
138
+ transfer confirms and the deposit is registered, while balance credit may still
139
+ be queued. Balance reads reflect subsequent credit and allocation; the deposit
140
+ call does not wait for `waitForDepositCredit()`.
141
+ A successful deposit result confirms the transfer; it does not guarantee that
142
+ the funds are already credited or earning yield.
143
+
137
144
  Returns: `OwneyDepositResult` (single agent) or `OwneyMultiDepositResult` (all agents)
138
145
 
139
146
  ```typescript
package/dist/index.cjs CHANGED
@@ -1444,7 +1444,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
1444
1444
  * chain/account switch fires the provider's `accountsChanged` →
1445
1445
  * `disconnectAccount` (nulls walletClient + authenticatedUserId) while our
1446
1446
  * own `connectAuth` guard still believes this chain is connected and
1447
- * early-returns. Without this, authenticated calls (depositFunds,
1447
+ * early-returns. Without this, authenticated calls (sendDeposit,
1448
1448
  * withdrawFunds) fail with "No account connected".
1449
1449
  */
1450
1450
  async ensureConnected(state, chainId) {
@@ -2927,9 +2927,24 @@ async function wrapNative(deps, options) {
2927
2927
  message: error instanceof Error ? error.message : String(error)
2928
2928
  });
2929
2929
  }
2930
+ let approvalPending = true;
2931
+ if (options.spender && deps.readAllowance) {
2932
+ try {
2933
+ const allowance = await deps.readAllowance(wrapper, options.spender);
2934
+ approvalPending = allowance < requested;
2935
+ } catch (error) {
2936
+ debugLog(
2937
+ "owney-sdk",
2938
+ "wrap: allowance read failed, assuming an approve",
2939
+ {
2940
+ message: error instanceof Error ? error.message : String(error)
2941
+ }
2942
+ );
2943
+ }
2944
+ }
2930
2945
  const measured = await deps.getMaxFeePerGas();
2931
2946
  const gasPrice = measured > MIN_WALLET_GAS_PRICE ? measured : MIN_WALLET_GAS_PRICE;
2932
- const reserve = (wrapGas + APPROVE_GAS) * gasPrice * GAS_SAFETY;
2947
+ const reserve = (wrapGas + (approvalPending ? APPROVE_GAS : 0n)) * gasPrice * GAS_SAFETY;
2933
2948
  const spendable = balance > reserve ? balance - reserve : 0n;
2934
2949
  const wrapped = requested < spendable ? requested : spendable;
2935
2950
  debugLog("owney-sdk", "wrap: sizing", {
@@ -2937,6 +2952,7 @@ async function wrapNative(deps, options) {
2937
2952
  requested: requested.toString(),
2938
2953
  measuredGasPrice: measured.toString(),
2939
2954
  reservedAtGasPrice: gasPrice.toString(),
2955
+ approvalPending,
2940
2956
  reserve: reserve.toString(),
2941
2957
  wrapped: wrapped.toString()
2942
2958
  });
@@ -3582,7 +3598,7 @@ async function runSameChainFusion(deps, options, walletAddress) {
3582
3598
  const isNativeSource = quote.src.address.toLowerCase().startsWith("0xeeee");
3583
3599
  const amount = isNativeSource ? BigInt(quote.src.amount) : await affordableAmount(deps, BigInt(quote.src.amount));
3584
3600
  const permit = await authoriseSpend(deps, options, amount, isNativeSource);
3585
- onStage?.("quoting");
3601
+ onStage?.("building");
3586
3602
  debugLog("owney-sdk", "swap: building same-chain fusion order");
3587
3603
  const built = await deps.api.buildOrder({
3588
3604
  from: {
@@ -3664,7 +3680,7 @@ async function runFusion(deps, options, walletAddress) {
3664
3680
  const amount = await affordableAmount(deps, BigInt(quote.src.amount));
3665
3681
  const permit = await authoriseSpend(deps, options, amount, false);
3666
3682
  const { secrets, secretHashes } = mintSecrets(quote.secretsCount ?? 1);
3667
- onStage?.("quoting");
3683
+ onStage?.("building");
3668
3684
  debugLog("owney-sdk", "swap: building fusion order", {
3669
3685
  secrets: secretHashes.length
3670
3686
  });
@@ -5572,13 +5588,25 @@ var OwneySDK = class {
5572
5588
  }
5573
5589
  return hash;
5574
5590
  },
5575
- ensureChain: (id) => this.ensureSwapChain(id)
5591
+ ensureChain: (id) => this.ensureSwapChain(id),
5592
+ // Read through the same public client as every other sizing input, so
5593
+ // a wallet sitting on the wrong chain cannot answer for this one.
5594
+ readAllowance: (token, spender) => publicClient.readContract({
5595
+ address: token,
5596
+ abi: ERC20_ALLOWANCE_ABI,
5597
+ functionName: "allowance",
5598
+ args: [walletAddress, spender]
5599
+ })
5576
5600
  },
5577
5601
  {
5578
5602
  chainId,
5579
5603
  wrapper: wrapper.address,
5580
5604
  nativeSymbol: quote.src.symbol,
5581
5605
  requested: BigInt(quote.src.amount),
5606
+ // Lets the reserve skip the approve's gas when one is already in
5607
+ // place. Absent on a quote that names no spender, which keeps the
5608
+ // full reserve (ROUT-242, comment 16234).
5609
+ ...quote.spender ? { spender: quote.spender } : {},
5582
5610
  onSubmitted: () => onStage?.("wrapped")
5583
5611
  }
5584
5612
  );
package/dist/index.d.cts CHANGED
@@ -220,7 +220,7 @@ type SwapOrderStatus = "pending" | "executed" | "expired" | "cancelled" | "refun
220
220
  * of the flow and the one place a user would otherwise think nothing is
221
221
  * happening.
222
222
  */
223
- type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
223
+ type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "building" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
224
224
  /**
225
225
  * Which way the funds travel, which decides what each side may be.
226
226
  *
package/dist/index.d.ts CHANGED
@@ -220,7 +220,7 @@ type SwapOrderStatus = "pending" | "executed" | "expired" | "cancelled" | "refun
220
220
  * of the flow and the one place a user would otherwise think nothing is
221
221
  * happening.
222
222
  */
223
- type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
223
+ type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "building" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
224
224
  /**
225
225
  * Which way the funds travel, which decides what each side may be.
226
226
  *
package/dist/index.js CHANGED
@@ -1404,7 +1404,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
1404
1404
  * chain/account switch fires the provider's `accountsChanged` →
1405
1405
  * `disconnectAccount` (nulls walletClient + authenticatedUserId) while our
1406
1406
  * own `connectAuth` guard still believes this chain is connected and
1407
- * early-returns. Without this, authenticated calls (depositFunds,
1407
+ * early-returns. Without this, authenticated calls (sendDeposit,
1408
1408
  * withdrawFunds) fail with "No account connected".
1409
1409
  */
1410
1410
  async ensureConnected(state, chainId) {
@@ -2887,9 +2887,24 @@ async function wrapNative(deps, options) {
2887
2887
  message: error instanceof Error ? error.message : String(error)
2888
2888
  });
2889
2889
  }
2890
+ let approvalPending = true;
2891
+ if (options.spender && deps.readAllowance) {
2892
+ try {
2893
+ const allowance = await deps.readAllowance(wrapper, options.spender);
2894
+ approvalPending = allowance < requested;
2895
+ } catch (error) {
2896
+ debugLog(
2897
+ "owney-sdk",
2898
+ "wrap: allowance read failed, assuming an approve",
2899
+ {
2900
+ message: error instanceof Error ? error.message : String(error)
2901
+ }
2902
+ );
2903
+ }
2904
+ }
2890
2905
  const measured = await deps.getMaxFeePerGas();
2891
2906
  const gasPrice = measured > MIN_WALLET_GAS_PRICE ? measured : MIN_WALLET_GAS_PRICE;
2892
- const reserve = (wrapGas + APPROVE_GAS) * gasPrice * GAS_SAFETY;
2907
+ const reserve = (wrapGas + (approvalPending ? APPROVE_GAS : 0n)) * gasPrice * GAS_SAFETY;
2893
2908
  const spendable = balance > reserve ? balance - reserve : 0n;
2894
2909
  const wrapped = requested < spendable ? requested : spendable;
2895
2910
  debugLog("owney-sdk", "wrap: sizing", {
@@ -2897,6 +2912,7 @@ async function wrapNative(deps, options) {
2897
2912
  requested: requested.toString(),
2898
2913
  measuredGasPrice: measured.toString(),
2899
2914
  reservedAtGasPrice: gasPrice.toString(),
2915
+ approvalPending,
2900
2916
  reserve: reserve.toString(),
2901
2917
  wrapped: wrapped.toString()
2902
2918
  });
@@ -3552,7 +3568,7 @@ async function runSameChainFusion(deps, options, walletAddress) {
3552
3568
  const isNativeSource = quote.src.address.toLowerCase().startsWith("0xeeee");
3553
3569
  const amount = isNativeSource ? BigInt(quote.src.amount) : await affordableAmount(deps, BigInt(quote.src.amount));
3554
3570
  const permit = await authoriseSpend(deps, options, amount, isNativeSource);
3555
- onStage?.("quoting");
3571
+ onStage?.("building");
3556
3572
  debugLog("owney-sdk", "swap: building same-chain fusion order");
3557
3573
  const built = await deps.api.buildOrder({
3558
3574
  from: {
@@ -3634,7 +3650,7 @@ async function runFusion(deps, options, walletAddress) {
3634
3650
  const amount = await affordableAmount(deps, BigInt(quote.src.amount));
3635
3651
  const permit = await authoriseSpend(deps, options, amount, false);
3636
3652
  const { secrets, secretHashes } = mintSecrets(quote.secretsCount ?? 1);
3637
- onStage?.("quoting");
3653
+ onStage?.("building");
3638
3654
  debugLog("owney-sdk", "swap: building fusion order", {
3639
3655
  secrets: secretHashes.length
3640
3656
  });
@@ -5553,13 +5569,25 @@ var OwneySDK = class {
5553
5569
  }
5554
5570
  return hash;
5555
5571
  },
5556
- ensureChain: (id) => this.ensureSwapChain(id)
5572
+ ensureChain: (id) => this.ensureSwapChain(id),
5573
+ // Read through the same public client as every other sizing input, so
5574
+ // a wallet sitting on the wrong chain cannot answer for this one.
5575
+ readAllowance: (token, spender) => publicClient.readContract({
5576
+ address: token,
5577
+ abi: ERC20_ALLOWANCE_ABI,
5578
+ functionName: "allowance",
5579
+ args: [walletAddress, spender]
5580
+ })
5557
5581
  },
5558
5582
  {
5559
5583
  chainId,
5560
5584
  wrapper: wrapper.address,
5561
5585
  nativeSymbol: quote.src.symbol,
5562
5586
  requested: BigInt(quote.src.amount),
5587
+ // Lets the reserve skip the approve's gas when one is already in
5588
+ // place. Absent on a quote that names no spender, which keeps the
5589
+ // full reserve (ROUT-242, comment 16234).
5590
+ ...quote.spender ? { spender: quote.spender } : {},
5563
5591
  onSubmitted: () => onStage?.("wrapped")
5564
5592
  }
5565
5593
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.28-beta.8",
3
+ "version": "0.7.28",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",