@0xmonaco/core 1.0.43 → 1.0.45

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.
@@ -23,7 +23,7 @@
23
23
  * console.log(`Deposit transaction: ${result.hash}`);
24
24
  * ```
25
25
  */
26
- import type { ApplicationsAPI, Balance, DepositTarget, ProfileAPI, TransactionResult, VaultAPI, WithdrawalRetryOptions, WithdrawalSource, WithdrawResult } from "@0xmonaco/types";
26
+ import type { ApplicationsAPI, Balance, DepositOptions, DepositTarget, ProfileAPI, TransactionResult, VaultAPI, WithdrawalRetryOptions, WithdrawalSource, WithdrawResult } from "@0xmonaco/types";
27
27
  import { type Address, type Chain, type PublicClient, type WalletClient } from "viem";
28
28
  import { BaseAPI } from "../base";
29
29
  /**
@@ -139,8 +139,11 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
139
139
  * standard ERC20 assets. The wrapped-native asset (e.g. WSEI, flagged
140
140
  * `wrappedNative` in the balances API) is deposited in native coin via the
141
141
  * payable `depositNative` — the vault wraps it into the ERC20 on entry — so
142
- * no approval is needed and `amount` is sent as msg.value. Withdrawals of the
143
- * wrapped-native asset pay out native coin (the vault unwraps).
142
+ * no approval is needed and `amount` is sent as msg.value. A wallet holding
143
+ * the wrapped ERC20 itself can pass `options.asErc20` to deposit it through
144
+ * the standard `approve()` + `depositERC20` path instead. Either way,
145
+ * withdrawals of the wrapped-native asset pay out native coin (the vault
146
+ * unwraps).
144
147
  *
145
148
  * @param assetId - The asset identifier (UUID) to deposit
146
149
  * @param amount - The amount of tokens to deposit (as bigint)
@@ -149,6 +152,9 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
149
152
  * wallet; `"margin"` routes the deposit into the parent margin account's
150
153
  * collateral (auto-creating the account if needed). Margin deposits that
151
154
  * cannot be routed safely fall back to spot.
155
+ * @param options - Deposit options; `asErc20` deposits the wrapped-native
156
+ * asset as its ERC20 via `depositERC20` (requires approval) instead of in
157
+ * native coin. No effect on other assets.
152
158
  * @returns Promise resolving to TransactionResult with transaction details
153
159
  * @throws {ContractError} When deposit fails or approval is insufficient
154
160
  * @throws {APIError} When the asset is not found or the assetId is invalid
@@ -182,7 +188,7 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
182
188
  * const receipt = await sdk.waitForTransaction(result.hash);
183
189
  * ```
184
190
  */
185
- deposit(assetId: string, amount: bigint, autoWait?: boolean, target?: DepositTarget): Promise<TransactionResult>;
191
+ deposit(assetId: string, amount: bigint, autoWait?: boolean, target?: DepositTarget, options?: DepositOptions): Promise<TransactionResult>;
186
192
  /**
187
193
  * Polls `GET /api/v1/withdrawals/{index}` until the gateway can serve the
188
194
  * `executeWithdrawal` calldata, then returns it with the vault address.
@@ -325,13 +331,17 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
325
331
  * Compares the current allowance with the requested amount to determine if
326
332
  * the user needs to approve more tokens before performing operations.
327
333
  *
328
- * The wrapped-native asset (e.g. WSEI) never needs approval: its deposits
329
- * are made in native coin via the payable `depositNative` (the vault wraps
330
- * on entry), so no ERC20 allowance is consumed and this method returns
331
- * `false` without reading the chain.
334
+ * The wrapped-native asset (e.g. WSEI) does not need approval by default:
335
+ * its deposits are made in native coin via the payable `depositNative` (the
336
+ * vault wraps on entry), so no ERC20 allowance is consumed and this method
337
+ * returns `false` without reading the chain. An `options.asErc20` deposit of
338
+ * that asset goes through `depositERC20` and consumes a real allowance, so
339
+ * pass the same options here to check it.
332
340
  *
333
341
  * @param assetId - The asset identifier (UUID) to check for
334
342
  * @param amount - The amount to check approval for (as bigint)
343
+ * @param options - Deposit options the approval is for; with `asErc20` the
344
+ * wrapped-native asset's real ERC20 allowance is read.
335
345
  * @returns Promise resolving to true if approval is needed, false otherwise
336
346
  * @throws {ContractError} When approval check fails or asset not found
337
347
  *
@@ -348,6 +358,6 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
348
358
  * }
349
359
  * ```
350
360
  */
351
- needsApproval(assetId: string, amount: bigint): Promise<boolean>;
361
+ needsApproval(assetId: string, amount: bigint, options?: DepositOptions): Promise<boolean>;
352
362
  private waitForTransaction;
353
363
  }
@@ -228,8 +228,11 @@ export class VaultAPIImpl extends BaseAPI {
228
228
  * standard ERC20 assets. The wrapped-native asset (e.g. WSEI, flagged
229
229
  * `wrappedNative` in the balances API) is deposited in native coin via the
230
230
  * payable `depositNative` — the vault wraps it into the ERC20 on entry — so
231
- * no approval is needed and `amount` is sent as msg.value. Withdrawals of the
232
- * wrapped-native asset pay out native coin (the vault unwraps).
231
+ * no approval is needed and `amount` is sent as msg.value. A wallet holding
232
+ * the wrapped ERC20 itself can pass `options.asErc20` to deposit it through
233
+ * the standard `approve()` + `depositERC20` path instead. Either way,
234
+ * withdrawals of the wrapped-native asset pay out native coin (the vault
235
+ * unwraps).
233
236
  *
234
237
  * @param assetId - The asset identifier (UUID) to deposit
235
238
  * @param amount - The amount of tokens to deposit (as bigint)
@@ -238,6 +241,9 @@ export class VaultAPIImpl extends BaseAPI {
238
241
  * wallet; `"margin"` routes the deposit into the parent margin account's
239
242
  * collateral (auto-creating the account if needed). Margin deposits that
240
243
  * cannot be routed safely fall back to spot.
244
+ * @param options - Deposit options; `asErc20` deposits the wrapped-native
245
+ * asset as its ERC20 via `depositERC20` (requires approval) instead of in
246
+ * native coin. No effect on other assets.
241
247
  * @returns Promise resolving to TransactionResult with transaction details
242
248
  * @throws {ContractError} When deposit fails or approval is insufficient
243
249
  * @throws {APIError} When the asset is not found or the assetId is invalid
@@ -271,21 +277,25 @@ export class VaultAPIImpl extends BaseAPI {
271
277
  * const receipt = await sdk.waitForTransaction(result.hash);
272
278
  * ```
273
279
  */
274
- async deposit(assetId, amount, autoWait = true, target = "spot") {
280
+ async deposit(assetId, amount, autoWait = true, target = "spot", options = {}) {
275
281
  if (!this.walletClient) {
276
282
  throw new InvalidConfigError("Wallet client not set. Connect a wallet first.", "walletClient");
277
283
  }
278
284
  // Validate inputs
279
- validate(DepositSchema, { assetId, amount, autoWait, target });
285
+ validate(DepositSchema, { assetId, amount, autoWait, target, options });
280
286
  const vaultAddress = await this.getVaultAddress();
281
287
  const clientId = await this.getClientId();
282
288
  // The on-chain applicationData carries the client id plus, for margin
283
289
  // deposits, the routing hint the indexer decodes.
284
290
  const applicationData = encodeDepositApplicationData(clientId, target);
285
291
  const { tokenAddress, isWrappedNative } = await this.resolveAsset(assetId);
286
- if (!isWrappedNative) {
292
+ // The wrapped-native asset normally deposits in native coin, but asErc20
293
+ // opts into the standard ERC20 path for wallets holding the wrapped ERC20
294
+ // itself (the vault accepts it like any enabled token).
295
+ const useNativePath = isWrappedNative && options.asErc20 !== true;
296
+ if (!useNativePath) {
287
297
  // Check if approval is needed before proceeding
288
- const needsApproval = await this.needsApproval(assetId, amount);
298
+ const needsApproval = await this.needsApproval(assetId, amount, options);
289
299
  if (needsApproval) {
290
300
  throw new ContractError(`Approval required before deposit. Please invoke approve() first for asset ${assetId} (token address: ${tokenAddress}).`, {
291
301
  revertReason: "APPROVAL_REQUIRED",
@@ -298,9 +308,10 @@ export class VaultAPIImpl extends BaseAPI {
298
308
  }
299
309
  // For the wrapped-native asset (e.g. WSEI), use depositNative (payable) — the
300
310
  // vault wraps the native coin into the ERC20 on entry, so no allowance is
301
- // involved. All other ERC20 tokens go through approve + depositERC20.
311
+ // involved. All other ERC20 tokens (and asErc20 wrapped-native deposits) go
312
+ // through approve + depositERC20.
302
313
  let hash;
303
- if (isWrappedNative) {
314
+ if (useNativePath) {
304
315
  hash = await this.walletClient.writeContract({
305
316
  address: vaultAddress,
306
317
  abi: CONTRACT_ABIS.vault,
@@ -616,13 +627,17 @@ export class VaultAPIImpl extends BaseAPI {
616
627
  * Compares the current allowance with the requested amount to determine if
617
628
  * the user needs to approve more tokens before performing operations.
618
629
  *
619
- * The wrapped-native asset (e.g. WSEI) never needs approval: its deposits
620
- * are made in native coin via the payable `depositNative` (the vault wraps
621
- * on entry), so no ERC20 allowance is consumed and this method returns
622
- * `false` without reading the chain.
630
+ * The wrapped-native asset (e.g. WSEI) does not need approval by default:
631
+ * its deposits are made in native coin via the payable `depositNative` (the
632
+ * vault wraps on entry), so no ERC20 allowance is consumed and this method
633
+ * returns `false` without reading the chain. An `options.asErc20` deposit of
634
+ * that asset goes through `depositERC20` and consumes a real allowance, so
635
+ * pass the same options here to check it.
623
636
  *
624
637
  * @param assetId - The asset identifier (UUID) to check for
625
638
  * @param amount - The amount to check approval for (as bigint)
639
+ * @param options - Deposit options the approval is for; with `asErc20` the
640
+ * wrapped-native asset's real ERC20 allowance is read.
626
641
  * @returns Promise resolving to true if approval is needed, false otherwise
627
642
  * @throws {ContractError} When approval check fails or asset not found
628
643
  *
@@ -639,11 +654,12 @@ export class VaultAPIImpl extends BaseAPI {
639
654
  * }
640
655
  * ```
641
656
  */
642
- async needsApproval(assetId, amount) {
657
+ async needsApproval(assetId, amount, options = {}) {
643
658
  const { isWrappedNative } = await this.resolveAsset(assetId);
644
- if (isWrappedNative) {
659
+ if (isWrappedNative && options.asErc20 !== true) {
645
660
  // Wrapped-native deposits route to the payable depositNative — no ERC20
646
- // allowance is consumed, so approval is never needed.
661
+ // allowance is consumed, so approval is never needed. asErc20 deposits
662
+ // go through depositERC20 and fall through to the real allowance read.
647
663
  return false;
648
664
  }
649
665
  const allowance = await this.getAllowance(assetId);
package/package.json CHANGED
@@ -1,12 +1,8 @@
1
1
  {
2
2
  "name": "@0xmonaco/core",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "type": "module",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/Monaco-Research/monaco-sdk.git",
8
- "directory": "packages/core"
9
- },
5
+ "homepage": "https://docs.0xmonaco.com/sdk/typescript",
10
6
  "main": "./dist/index.js",
11
7
  "module": "./dist/index.js",
12
8
  "types": "./dist/index.d.ts",
@@ -23,8 +19,8 @@
23
19
  "viem": "^2.45.2"
24
20
  },
25
21
  "dependencies": {
26
- "@0xmonaco/contracts": "1.0.43",
27
- "@0xmonaco/types": "1.0.43",
22
+ "@0xmonaco/contracts": "1.0.45",
23
+ "@0xmonaco/types": "1.0.45",
28
24
  "@noble/curves": "^1.9.1",
29
25
  "@noble/hashes": "^1.8.0",
30
26
  "http-status-codes": "^2.3.0"