@morpho-org/consumer-sdk 0.2.0 → 0.4.0
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 +178 -44
- package/lib/actions/index.d.ts +1 -0
- package/lib/actions/index.js +1 -0
- package/lib/actions/requirements/getRequirements.js +3 -0
- package/lib/actions/requirements/getRequirementsAction.d.ts +2 -2
- package/lib/actions/requirements/getRequirementsAction.js +7 -7
- package/lib/actions/vaultV1/deposit.d.ts +41 -0
- package/lib/actions/vaultV1/deposit.js +116 -0
- package/lib/actions/vaultV1/index.d.ts +3 -0
- package/lib/actions/vaultV1/index.js +19 -0
- package/lib/actions/vaultV1/redeem.d.ts +29 -0
- package/lib/actions/vaultV1/redeem.js +48 -0
- package/lib/actions/vaultV1/withdraw.d.ts +29 -0
- package/lib/actions/vaultV1/withdraw.js +48 -0
- package/lib/actions/vaultV2/deposit.d.ts +20 -25
- package/lib/actions/vaultV2/deposit.js +78 -40
- package/lib/actions/vaultV2/forceRedeem.d.ts +48 -0
- package/lib/actions/vaultV2/forceRedeem.js +85 -0
- package/lib/actions/vaultV2/forceWithdraw.d.ts +40 -0
- package/lib/actions/vaultV2/forceWithdraw.js +81 -0
- package/lib/actions/vaultV2/index.d.ts +2 -0
- package/lib/actions/vaultV2/index.js +2 -0
- package/lib/actions/vaultV2/redeem.js +2 -2
- package/lib/actions/vaultV2/withdraw.d.ts +3 -3
- package/lib/actions/vaultV2/withdraw.js +6 -6
- package/lib/client/morphoClient.d.ts +2 -1
- package/lib/client/morphoClient.js +3 -0
- package/lib/client/morphoViemExtension.d.ts +12 -9
- package/lib/client/morphoViemExtension.js +12 -9
- package/lib/entities/index.d.ts +1 -0
- package/lib/entities/index.js +1 -0
- package/lib/entities/vaultV1/index.d.ts +1 -0
- package/lib/entities/vaultV1/index.js +17 -0
- package/lib/entities/vaultV1/vaultV1.d.ts +95 -0
- package/lib/entities/vaultV1/vaultV1.js +125 -0
- package/lib/entities/vaultV2/vaultV2.d.ts +94 -18
- package/lib/entities/vaultV2/vaultV2.js +76 -15
- package/lib/helpers/encodeDeallocation.d.ts +10 -0
- package/lib/helpers/encodeDeallocation.js +37 -0
- package/lib/types/action.d.ts +59 -3
- package/lib/types/client.d.ts +2 -1
- package/lib/types/deallocation.d.ts +15 -0
- package/lib/types/deallocation.js +2 -0
- package/lib/types/error.d.ts +28 -4
- package/lib/types/error.js +59 -11
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/package.json +2 -2
|
@@ -3,18 +3,18 @@ import type { Metadata } from "../types";
|
|
|
3
3
|
import { MorphoClient } from "./morphoClient";
|
|
4
4
|
/**
|
|
5
5
|
* Morpho extension for viem clients.
|
|
6
|
-
* Adds `morpho` namespace
|
|
6
|
+
* Adds `morpho` namespace with `vaultV1` and `vaultV2` accessors.
|
|
7
7
|
*
|
|
8
|
-
* @param metadata - (Optional) Metadata
|
|
9
|
-
* @param supportSignature - (Optional)
|
|
10
|
-
* @param supportDeployless - (Optional)
|
|
11
|
-
* @returns Extension function that adds morpho namespace to viem clients
|
|
8
|
+
* @param metadata - (Optional) Metadata appended to all transactions for analytics.
|
|
9
|
+
* @param supportSignature - (Optional) Enable off-chain permit/permit2 approvals.
|
|
10
|
+
* @param supportDeployless - (Optional) Enable deployless reads for on-chain data fetching.
|
|
11
|
+
* @returns Extension function that adds morpho namespace to viem clients.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```ts
|
|
15
15
|
* import { createWalletClient, http } from 'viem';
|
|
16
16
|
* import { mainnet } from 'viem/chains';
|
|
17
|
-
* import {
|
|
17
|
+
* import { morphoViemExtension } from '@morpho-org/consumer-sdk';
|
|
18
18
|
*
|
|
19
19
|
* const client = createWalletClient({
|
|
20
20
|
* chain: mainnet,
|
|
@@ -22,9 +22,12 @@ import { MorphoClient } from "./morphoClient";
|
|
|
22
22
|
* account: '0x...',
|
|
23
23
|
* }).extend(morphoViemExtension());
|
|
24
24
|
*
|
|
25
|
-
* //
|
|
26
|
-
* const
|
|
27
|
-
* const
|
|
25
|
+
* // VaultV1 (MetaMorpho)
|
|
26
|
+
* const vaultV1 = client.morpho.vaultV1('0x...', 1);
|
|
27
|
+
* const depositV1 = await vaultV1.deposit({ amount: 1000000000000000000n, userAddress: '0x...' });
|
|
28
|
+
*
|
|
29
|
+
* // VaultV2
|
|
30
|
+
* const vaultV2 = client.morpho.vaultV2('0x...', 1);
|
|
28
31
|
* ```
|
|
29
32
|
*/
|
|
30
33
|
export declare function morphoViemExtension(_options?: {
|
|
@@ -4,18 +4,18 @@ exports.morphoViemExtension = morphoViemExtension;
|
|
|
4
4
|
const morphoClient_1 = require("./morphoClient");
|
|
5
5
|
/**
|
|
6
6
|
* Morpho extension for viem clients.
|
|
7
|
-
* Adds `morpho` namespace
|
|
7
|
+
* Adds `morpho` namespace with `vaultV1` and `vaultV2` accessors.
|
|
8
8
|
*
|
|
9
|
-
* @param metadata - (Optional) Metadata
|
|
10
|
-
* @param supportSignature - (Optional)
|
|
11
|
-
* @param supportDeployless - (Optional)
|
|
12
|
-
* @returns Extension function that adds morpho namespace to viem clients
|
|
9
|
+
* @param metadata - (Optional) Metadata appended to all transactions for analytics.
|
|
10
|
+
* @param supportSignature - (Optional) Enable off-chain permit/permit2 approvals.
|
|
11
|
+
* @param supportDeployless - (Optional) Enable deployless reads for on-chain data fetching.
|
|
12
|
+
* @returns Extension function that adds morpho namespace to viem clients.
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
16
|
* import { createWalletClient, http } from 'viem';
|
|
17
17
|
* import { mainnet } from 'viem/chains';
|
|
18
|
-
* import {
|
|
18
|
+
* import { morphoViemExtension } from '@morpho-org/consumer-sdk';
|
|
19
19
|
*
|
|
20
20
|
* const client = createWalletClient({
|
|
21
21
|
* chain: mainnet,
|
|
@@ -23,9 +23,12 @@ const morphoClient_1 = require("./morphoClient");
|
|
|
23
23
|
* account: '0x...',
|
|
24
24
|
* }).extend(morphoViemExtension());
|
|
25
25
|
*
|
|
26
|
-
* //
|
|
27
|
-
* const
|
|
28
|
-
* const
|
|
26
|
+
* // VaultV1 (MetaMorpho)
|
|
27
|
+
* const vaultV1 = client.morpho.vaultV1('0x...', 1);
|
|
28
|
+
* const depositV1 = await vaultV1.deposit({ amount: 1000000000000000000n, userAddress: '0x...' });
|
|
29
|
+
*
|
|
30
|
+
* // VaultV2
|
|
31
|
+
* const vaultV2 = client.morpho.vaultV2('0x...', 1);
|
|
29
32
|
* ```
|
|
30
33
|
*/
|
|
31
34
|
function morphoViemExtension(_options) {
|
package/lib/entities/index.d.ts
CHANGED
package/lib/entities/index.js
CHANGED
|
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./vaultV1"), exports);
|
|
17
18
|
__exportStar(require("./vaultV2"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./vaultV1";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./vaultV1"), exports);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type AccrualVault } from "@morpho-org/blue-sdk";
|
|
2
|
+
import { fetchAccrualVault } from "@morpho-org/blue-sdk-viem";
|
|
3
|
+
import { type Address } from "viem";
|
|
4
|
+
import { type DepositAmountArgs, type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV1DepositAction, type VaultV1RedeemAction, type VaultV1WithdrawAction } from "../../types";
|
|
5
|
+
import type { FetchParameters } from "../../types/data";
|
|
6
|
+
export interface VaultV1Actions {
|
|
7
|
+
/**
|
|
8
|
+
* Fetches the latest vault data with accrued interest.
|
|
9
|
+
*
|
|
10
|
+
* @param {FetchParameters} [parameters] - Optional fetch parameters (block number, state overrides, etc.).
|
|
11
|
+
* @returns {Promise<Awaited<ReturnType<typeof fetchAccrualVault>>>} The latest accrued vault data.
|
|
12
|
+
*/
|
|
13
|
+
getData: (parameters?: FetchParameters) => Promise<Awaited<ReturnType<typeof fetchAccrualVault>>>;
|
|
14
|
+
/**
|
|
15
|
+
* Prepares a deposit into a VaultV1 (MetaMorpho) contract.
|
|
16
|
+
*
|
|
17
|
+
* Uses pre-fetched accrual vault data to compute `maxSharePrice` with slippage tolerance,
|
|
18
|
+
* then returns `buildTx` and `getRequirements` for lazy evaluation.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} params - The deposit parameters.
|
|
21
|
+
* @param {bigint} params.amount - Amount of assets to deposit.
|
|
22
|
+
* @param {Address} params.userAddress - User address initiating the deposit.
|
|
23
|
+
* @param {AccrualVault} params.accrualVault - Pre-fetched vault data with asset address and share conversion.
|
|
24
|
+
* @param {bigint} [params.slippageTolerance=DEFAULT_SLIPPAGE_TOLERANCE] - Slippage tolerance (default 0.03%, max 10%).
|
|
25
|
+
* @param {bigint} [params.nativeAmount] - Amount of native ETH to wrap into WETH. Vault asset must be wNative.
|
|
26
|
+
* @returns {Object} Object with `buildTx` and `getRequirements`.
|
|
27
|
+
*/
|
|
28
|
+
deposit: (params: {
|
|
29
|
+
userAddress: Address;
|
|
30
|
+
accrualVault: AccrualVault;
|
|
31
|
+
slippageTolerance?: bigint;
|
|
32
|
+
} & DepositAmountArgs) => {
|
|
33
|
+
buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV1DepositAction>>;
|
|
34
|
+
getRequirements: (params?: {
|
|
35
|
+
useSimplePermit?: boolean;
|
|
36
|
+
}) => Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Prepares a withdraw from a VaultV1 (MetaMorpho) contract.
|
|
40
|
+
*
|
|
41
|
+
* @param {Object} params - The withdraw parameters.
|
|
42
|
+
* @param {bigint} params.amount - Amount of assets to withdraw.
|
|
43
|
+
* @param {Address} params.userAddress - User address initiating the withdraw.
|
|
44
|
+
* @returns {Object} Object with `buildTx`.
|
|
45
|
+
*/
|
|
46
|
+
withdraw: (params: {
|
|
47
|
+
amount: bigint;
|
|
48
|
+
userAddress: Address;
|
|
49
|
+
}) => {
|
|
50
|
+
buildTx: () => Readonly<Transaction<VaultV1WithdrawAction>>;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Prepares a redeem from a VaultV1 (MetaMorpho) contract.
|
|
54
|
+
*
|
|
55
|
+
* @param {Object} params - The redeem parameters.
|
|
56
|
+
* @param {bigint} params.shares - Amount of shares to redeem.
|
|
57
|
+
* @param {Address} params.userAddress - User address initiating the redeem.
|
|
58
|
+
* @returns {Object} Object with `buildTx`.
|
|
59
|
+
*/
|
|
60
|
+
redeem: (params: {
|
|
61
|
+
shares: bigint;
|
|
62
|
+
userAddress: Address;
|
|
63
|
+
}) => {
|
|
64
|
+
buildTx: () => Readonly<Transaction<VaultV1RedeemAction>>;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export declare class MorphoVaultV1 implements VaultV1Actions {
|
|
68
|
+
private readonly client;
|
|
69
|
+
private readonly vault;
|
|
70
|
+
private readonly chainId;
|
|
71
|
+
constructor(client: MorphoClientType, vault: Address, chainId: number);
|
|
72
|
+
getData(parameters?: FetchParameters): Promise<AccrualVault>;
|
|
73
|
+
deposit({ amount, userAddress, accrualVault, slippageTolerance, nativeAmount, }: {
|
|
74
|
+
userAddress: Address;
|
|
75
|
+
accrualVault: AccrualVault;
|
|
76
|
+
slippageTolerance?: bigint;
|
|
77
|
+
} & DepositAmountArgs): {
|
|
78
|
+
getRequirements: (params?: {
|
|
79
|
+
useSimplePermit?: boolean;
|
|
80
|
+
}) => Promise<(Requirement | Readonly<Transaction<ERC20ApprovalAction>>)[]>;
|
|
81
|
+
buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV1DepositAction>>;
|
|
82
|
+
};
|
|
83
|
+
withdraw({ amount, userAddress }: {
|
|
84
|
+
amount: bigint;
|
|
85
|
+
userAddress: Address;
|
|
86
|
+
}): {
|
|
87
|
+
buildTx: () => Readonly<Transaction<VaultV1WithdrawAction>>;
|
|
88
|
+
};
|
|
89
|
+
redeem({ shares, userAddress }: {
|
|
90
|
+
shares: bigint;
|
|
91
|
+
userAddress: Address;
|
|
92
|
+
}): {
|
|
93
|
+
buildTx: () => Readonly<Transaction<VaultV1RedeemAction>>;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MorphoVaultV1 = void 0;
|
|
4
|
+
const blue_sdk_1 = require("@morpho-org/blue-sdk");
|
|
5
|
+
const blue_sdk_viem_1 = require("@morpho-org/blue-sdk-viem");
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const actions_1 = require("../../actions");
|
|
8
|
+
const constant_1 = require("../../helpers/constant");
|
|
9
|
+
const types_1 = require("../../types");
|
|
10
|
+
class MorphoVaultV1 {
|
|
11
|
+
client;
|
|
12
|
+
vault;
|
|
13
|
+
chainId;
|
|
14
|
+
constructor(client, vault, chainId) {
|
|
15
|
+
this.client = client;
|
|
16
|
+
this.vault = vault;
|
|
17
|
+
this.chainId = chainId;
|
|
18
|
+
}
|
|
19
|
+
async getData(parameters) {
|
|
20
|
+
return (0, blue_sdk_viem_1.fetchAccrualVault)(this.vault, this.client.viemClient, {
|
|
21
|
+
...parameters,
|
|
22
|
+
chainId: this.chainId,
|
|
23
|
+
deployless: this.client.options.supportDeployless,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
deposit({ amount = 0n, userAddress, accrualVault, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, nativeAmount, }) {
|
|
27
|
+
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
28
|
+
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
29
|
+
}
|
|
30
|
+
if (!(0, viem_1.isAddressEqual)(accrualVault.address, this.vault)) {
|
|
31
|
+
throw new types_1.VaultAddressMismatchError(this.vault, accrualVault.address);
|
|
32
|
+
}
|
|
33
|
+
if (amount < 0n) {
|
|
34
|
+
throw new types_1.NonPositiveAssetAmountError(this.vault);
|
|
35
|
+
}
|
|
36
|
+
if (nativeAmount && nativeAmount < 0n) {
|
|
37
|
+
throw new types_1.NegativeNativeAmountError(nativeAmount);
|
|
38
|
+
}
|
|
39
|
+
let wNative;
|
|
40
|
+
if (nativeAmount) {
|
|
41
|
+
({ wNative } = (0, blue_sdk_1.getChainAddresses)(this.chainId));
|
|
42
|
+
if (!wNative) {
|
|
43
|
+
throw new types_1.ChainWNativeMissingError(this.chainId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (slippageTolerance < 0n) {
|
|
47
|
+
throw new types_1.NegativeSlippageToleranceError(slippageTolerance);
|
|
48
|
+
}
|
|
49
|
+
if (slippageTolerance > constant_1.MAX_SLIPPAGE_TOLERANCE) {
|
|
50
|
+
throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
|
|
51
|
+
}
|
|
52
|
+
if (nativeAmount && wNative) {
|
|
53
|
+
if (!(0, viem_1.isAddressEqual)(accrualVault.asset, wNative)) {
|
|
54
|
+
throw new types_1.NativeAmountOnNonWNativeVaultError(accrualVault.asset, wNative);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const totalAssets = amount + (nativeAmount ?? 0n);
|
|
58
|
+
const shares = accrualVault.toShares(totalAssets);
|
|
59
|
+
if (shares <= 0n) {
|
|
60
|
+
throw new types_1.NonPositiveSharesAmountError(this.vault);
|
|
61
|
+
}
|
|
62
|
+
const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(totalAssets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares), blue_sdk_1.MathLib.RAY * 100n);
|
|
63
|
+
return {
|
|
64
|
+
getRequirements: async (params) => await (0, actions_1.getRequirements)(this.client.viemClient, {
|
|
65
|
+
address: accrualVault.asset,
|
|
66
|
+
chainId: this.chainId,
|
|
67
|
+
supportSignature: this.client.options.supportSignature,
|
|
68
|
+
supportDeployless: this.client.options.supportDeployless,
|
|
69
|
+
useSimplePermit: params?.useSimplePermit,
|
|
70
|
+
args: {
|
|
71
|
+
amount,
|
|
72
|
+
from: userAddress,
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
buildTx: (requirementSignature) => (0, actions_1.vaultV1Deposit)({
|
|
76
|
+
vault: {
|
|
77
|
+
chainId: this.chainId,
|
|
78
|
+
address: this.vault,
|
|
79
|
+
asset: accrualVault.asset,
|
|
80
|
+
},
|
|
81
|
+
args: {
|
|
82
|
+
amount,
|
|
83
|
+
maxSharePrice,
|
|
84
|
+
recipient: userAddress,
|
|
85
|
+
requirementSignature,
|
|
86
|
+
nativeAmount,
|
|
87
|
+
},
|
|
88
|
+
metadata: this.client.options.metadata,
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
withdraw({ amount, userAddress }) {
|
|
93
|
+
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
94
|
+
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
buildTx: () => (0, actions_1.vaultV1Withdraw)({
|
|
98
|
+
vault: { address: this.vault },
|
|
99
|
+
args: {
|
|
100
|
+
amount,
|
|
101
|
+
recipient: userAddress,
|
|
102
|
+
onBehalf: userAddress,
|
|
103
|
+
},
|
|
104
|
+
metadata: this.client.options.metadata,
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
redeem({ shares, userAddress }) {
|
|
109
|
+
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
110
|
+
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
buildTx: () => (0, actions_1.vaultV1Redeem)({
|
|
114
|
+
vault: { address: this.vault },
|
|
115
|
+
args: {
|
|
116
|
+
shares,
|
|
117
|
+
recipient: userAddress,
|
|
118
|
+
onBehalf: userAddress,
|
|
119
|
+
},
|
|
120
|
+
metadata: this.client.options.metadata,
|
|
121
|
+
}),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.MorphoVaultV1 = MorphoVaultV1;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type AccrualVaultV2 } from "@morpho-org/blue-sdk";
|
|
1
2
|
import { fetchAccrualVaultV2 } from "@morpho-org/blue-sdk-viem";
|
|
2
|
-
import type
|
|
3
|
-
import { type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV2DepositAction, type VaultV2RedeemAction, type VaultV2WithdrawAction } from "../../types";
|
|
3
|
+
import { type Address } from "viem";
|
|
4
|
+
import { type Deallocation, type DepositAmountArgs, type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV2DepositAction, type VaultV2ForceRedeemAction, type VaultV2ForceWithdrawAction, type VaultV2RedeemAction, type VaultV2WithdrawAction } from "../../types";
|
|
4
5
|
import type { FetchParameters } from "../../types/data";
|
|
5
6
|
export interface VaultV2Actions {
|
|
6
7
|
/**
|
|
@@ -16,41 +17,43 @@ export interface VaultV2Actions {
|
|
|
16
17
|
* Prepares a deposit transaction for the VaultV2 contract.
|
|
17
18
|
*
|
|
18
19
|
* This function constructs the transaction data required to deposit a specified amount of assets into the vault.
|
|
19
|
-
*
|
|
20
|
+
* Uses pre-fetched accrual vault data for accurate calculations of slippage and asset address,
|
|
20
21
|
* then returns the prepared deposit transaction and a function for retrieving all required approval transactions.
|
|
21
22
|
* Bundler Integration: This flow uses the bundler to atomically execute the user's asset transfer and vault deposit in a single transaction for slippage protection.
|
|
22
23
|
*
|
|
23
24
|
* @param {Object} params - The deposit parameters.
|
|
24
|
-
* @param {bigint} params.
|
|
25
|
-
* @param {Address}
|
|
25
|
+
* @param {bigint} [params.amount=0n] - Amount of ERC-20 assets to deposit. At least one of amount or nativeAmount must be provided.
|
|
26
|
+
* @param {Address} params.userAddress - User address initiating the deposit.
|
|
27
|
+
* @param {AccrualVaultV2} params.accrualVault - Pre-fetched vault data with asset address and share conversion.
|
|
26
28
|
* @param {bigint} [params.slippageTolerance=DEFAULT_SLIPPAGE_TOLERANCE] - Optional slippage tolerance value. Default is 0.03%. Slippage tolerance must be less than 10%.
|
|
29
|
+
* @param {bigint} [params.nativeAmount] - Amount of native token to wrap into wNative. Vault asset must be wNative.
|
|
27
30
|
* @returns {Object} The result object.
|
|
28
31
|
* @returns {Readonly<Transaction<VaultV2DepositAction>>} returns.tx The prepared deposit transaction.
|
|
29
|
-
* @returns {Promise<Readonly<Transaction<ERC20ApprovalAction
|
|
32
|
+
* @returns {Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>} returns.getRequirements The function for retrieving all required approval transactions.
|
|
30
33
|
*/
|
|
31
34
|
deposit: (params: {
|
|
32
|
-
assets: bigint;
|
|
33
35
|
userAddress: Address;
|
|
36
|
+
accrualVault: AccrualVaultV2;
|
|
34
37
|
slippageTolerance?: bigint;
|
|
35
|
-
}) =>
|
|
38
|
+
} & DepositAmountArgs) => {
|
|
36
39
|
buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV2DepositAction>>;
|
|
37
40
|
getRequirements: (params?: {
|
|
38
41
|
useSimplePermit?: boolean;
|
|
39
42
|
}) => Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>;
|
|
40
|
-
}
|
|
43
|
+
};
|
|
41
44
|
/**
|
|
42
45
|
* Prepares a withdraw transaction for the VaultV2 contract.
|
|
43
46
|
*
|
|
44
47
|
* This function constructs the transaction data required to withdraw a specified amount of assets from the vault.
|
|
45
48
|
*
|
|
46
49
|
* @param {Object} params - The withdraw parameters.
|
|
47
|
-
* @param {bigint} params.
|
|
50
|
+
* @param {bigint} params.amount - The amount of assets to withdraw.
|
|
48
51
|
* @param {Address} params.userAddress - User address initiating the withdraw.
|
|
49
52
|
* @returns {Object} The result object.
|
|
50
53
|
* @returns {Readonly<Transaction<VaultV2WithdrawAction>>} returns.tx The prepared withdraw transaction.
|
|
51
54
|
*/
|
|
52
55
|
withdraw: (params: {
|
|
53
|
-
|
|
56
|
+
amount: bigint;
|
|
54
57
|
userAddress: Address;
|
|
55
58
|
}) => {
|
|
56
59
|
buildTx: () => Readonly<Transaction<VaultV2WithdrawAction>>;
|
|
@@ -72,25 +75,80 @@ export interface VaultV2Actions {
|
|
|
72
75
|
}) => {
|
|
73
76
|
buildTx: () => Readonly<Transaction<VaultV2RedeemAction>>;
|
|
74
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* Prepares a force withdraw transaction for the VaultV2 contract using the vault's native multicall.
|
|
80
|
+
*
|
|
81
|
+
* This function encodes one or more on-chain forceDeallocate calls followed by a single withdraw,
|
|
82
|
+
* executed atomically via VaultV2's multicall. This allows a user to free liquidity from multiple
|
|
83
|
+
* illiquid markets and withdraw the resulting assets in one transaction.
|
|
84
|
+
*
|
|
85
|
+
* @param {Object} params - The force withdraw parameters.
|
|
86
|
+
* @param {readonly Deallocation[]} params.deallocations - The typed list of deallocations to perform.
|
|
87
|
+
* @param {Object} params.withdraw - The withdraw parameters applied after deallocations.
|
|
88
|
+
* @param {bigint} params.withdraw.amount - The amount of assets to withdraw.
|
|
89
|
+
* @param {Address} params.userAddress - User address (penalty source and withdraw recipient).
|
|
90
|
+
* @returns {Object} The result object.
|
|
91
|
+
* @returns {Readonly<Transaction<VaultV2ForceWithdrawAction>>} returns.buildTx The prepared multicall transaction.
|
|
92
|
+
*/
|
|
93
|
+
forceWithdraw: (params: {
|
|
94
|
+
deallocations: readonly Deallocation[];
|
|
95
|
+
withdraw: {
|
|
96
|
+
amount: bigint;
|
|
97
|
+
};
|
|
98
|
+
userAddress: Address;
|
|
99
|
+
}) => {
|
|
100
|
+
buildTx: () => Readonly<Transaction<VaultV2ForceWithdrawAction>>;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Prepares a force redeem transaction for the VaultV2 contract using the vault's native multicall.
|
|
104
|
+
*
|
|
105
|
+
* This function encodes one or more on-chain forceDeallocate calls followed by a single redeem,
|
|
106
|
+
* executed atomically via VaultV2's multicall. This allows a user to free liquidity from multiple
|
|
107
|
+
* illiquid markets and redeem all their shares in one transaction.
|
|
108
|
+
*
|
|
109
|
+
* This is the share-based counterpart to forceWithdraw, useful for maximum withdrawal scenarios
|
|
110
|
+
* where specifying an exact asset amount is impractical.
|
|
111
|
+
*
|
|
112
|
+
* The total assets passed to forceDeallocate calls must be greater than or equal to the
|
|
113
|
+
* asset-equivalent of the redeemed shares. The caller should apply a buffer on the deallocated
|
|
114
|
+
* amounts to account for share-price drift between submission and execution.
|
|
115
|
+
*
|
|
116
|
+
* @param {Object} params - The force redeem parameters.
|
|
117
|
+
* @param {readonly Deallocation[]} params.deallocations - The typed list of deallocations to perform.
|
|
118
|
+
* @param {Object} params.redeem - The redeem parameters applied after deallocations.
|
|
119
|
+
* @param {bigint} params.redeem.shares - The amount of shares to redeem.
|
|
120
|
+
* @param {Address} params.userAddress - User address (penalty source and redeem recipient).
|
|
121
|
+
* @returns {Object} The result object.
|
|
122
|
+
* @returns {Readonly<Transaction<VaultV2ForceRedeemAction>>} returns.buildTx The prepared multicall transaction.
|
|
123
|
+
*/
|
|
124
|
+
forceRedeem: (params: {
|
|
125
|
+
deallocations: readonly Deallocation[];
|
|
126
|
+
redeem: {
|
|
127
|
+
shares: bigint;
|
|
128
|
+
};
|
|
129
|
+
userAddress: Address;
|
|
130
|
+
}) => {
|
|
131
|
+
buildTx: () => Readonly<Transaction<VaultV2ForceRedeemAction>>;
|
|
132
|
+
};
|
|
75
133
|
}
|
|
76
134
|
export declare class MorphoVaultV2 implements VaultV2Actions {
|
|
77
135
|
private readonly client;
|
|
78
136
|
private readonly vault;
|
|
79
137
|
private readonly chainId;
|
|
80
138
|
constructor(client: MorphoClientType, vault: Address, chainId: number);
|
|
81
|
-
getData(parameters?: FetchParameters): Promise<
|
|
82
|
-
deposit({
|
|
83
|
-
assets: bigint;
|
|
139
|
+
getData(parameters?: FetchParameters): Promise<AccrualVaultV2>;
|
|
140
|
+
deposit({ amount, userAddress, accrualVault, slippageTolerance, nativeAmount, }: {
|
|
84
141
|
userAddress: Address;
|
|
142
|
+
accrualVault: AccrualVaultV2;
|
|
85
143
|
slippageTolerance?: bigint;
|
|
86
|
-
}):
|
|
144
|
+
} & DepositAmountArgs): {
|
|
87
145
|
getRequirements: (params?: {
|
|
88
146
|
useSimplePermit?: boolean;
|
|
89
147
|
}) => Promise<(Requirement | Readonly<Transaction<ERC20ApprovalAction>>)[]>;
|
|
90
148
|
buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV2DepositAction>>;
|
|
91
|
-
}
|
|
92
|
-
withdraw({
|
|
93
|
-
|
|
149
|
+
};
|
|
150
|
+
withdraw({ amount, userAddress }: {
|
|
151
|
+
amount: bigint;
|
|
94
152
|
userAddress: Address;
|
|
95
153
|
}): {
|
|
96
154
|
buildTx: () => Readonly<Transaction<VaultV2WithdrawAction>>;
|
|
@@ -101,4 +159,22 @@ export declare class MorphoVaultV2 implements VaultV2Actions {
|
|
|
101
159
|
}): {
|
|
102
160
|
buildTx: () => Readonly<Transaction<VaultV2RedeemAction>>;
|
|
103
161
|
};
|
|
162
|
+
forceWithdraw({ deallocations, withdraw, userAddress, }: {
|
|
163
|
+
deallocations: readonly Deallocation[];
|
|
164
|
+
withdraw: {
|
|
165
|
+
amount: bigint;
|
|
166
|
+
};
|
|
167
|
+
userAddress: Address;
|
|
168
|
+
}): {
|
|
169
|
+
buildTx: () => Readonly<Transaction<VaultV2ForceWithdrawAction>>;
|
|
170
|
+
};
|
|
171
|
+
forceRedeem({ deallocations, redeem, userAddress, }: {
|
|
172
|
+
deallocations: readonly Deallocation[];
|
|
173
|
+
redeem: {
|
|
174
|
+
shares: bigint;
|
|
175
|
+
};
|
|
176
|
+
userAddress: Address;
|
|
177
|
+
}): {
|
|
178
|
+
buildTx: () => Readonly<Transaction<VaultV2ForceRedeemAction>>;
|
|
179
|
+
};
|
|
104
180
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MorphoVaultV2 = void 0;
|
|
4
4
|
const blue_sdk_1 = require("@morpho-org/blue-sdk");
|
|
5
5
|
const blue_sdk_viem_1 = require("@morpho-org/blue-sdk-viem");
|
|
6
|
+
const viem_1 = require("viem");
|
|
6
7
|
const actions_1 = require("../../actions");
|
|
7
8
|
const constant_1 = require("../../helpers/constant");
|
|
8
9
|
const types_1 = require("../../types");
|
|
@@ -22,31 +23,52 @@ class MorphoVaultV2 {
|
|
|
22
23
|
deployless: this.client.options.supportDeployless,
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
deposit({ amount = 0n, userAddress, accrualVault, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, nativeAmount, }) {
|
|
26
27
|
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
27
28
|
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
if (!(0, viem_1.isAddressEqual)(accrualVault.address, this.vault)) {
|
|
31
|
+
throw new types_1.VaultAddressMismatchError(this.vault, accrualVault.address);
|
|
32
|
+
}
|
|
33
|
+
if (amount < 0n) {
|
|
34
|
+
throw new types_1.NonPositiveAssetAmountError(this.vault);
|
|
35
|
+
}
|
|
36
|
+
if (nativeAmount && nativeAmount < 0n) {
|
|
37
|
+
throw new types_1.NegativeNativeAmountError(nativeAmount);
|
|
38
|
+
}
|
|
39
|
+
let wNative;
|
|
40
|
+
if (nativeAmount) {
|
|
41
|
+
({ wNative } = (0, blue_sdk_1.getChainAddresses)(this.chainId));
|
|
42
|
+
if (!wNative) {
|
|
43
|
+
throw new types_1.ChainWNativeMissingError(this.chainId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (slippageTolerance < 0n) {
|
|
47
|
+
throw new types_1.NegativeSlippageToleranceError(slippageTolerance);
|
|
48
|
+
}
|
|
33
49
|
if (slippageTolerance > constant_1.MAX_SLIPPAGE_TOLERANCE) {
|
|
34
50
|
throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
|
|
35
51
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
if (nativeAmount && wNative) {
|
|
53
|
+
if (!(0, viem_1.isAddressEqual)(accrualVault.asset, wNative)) {
|
|
54
|
+
throw new types_1.NativeAmountOnNonWNativeVaultError(accrualVault.asset, wNative);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const totalAssets = amount + (nativeAmount ?? 0n);
|
|
58
|
+
const shares = accrualVault.toShares(totalAssets);
|
|
59
|
+
if (shares <= 0n) {
|
|
60
|
+
throw new types_1.NonPositiveSharesAmountError(this.vault);
|
|
39
61
|
}
|
|
40
|
-
const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(
|
|
62
|
+
const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(totalAssets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares), blue_sdk_1.MathLib.RAY * 100n);
|
|
41
63
|
return {
|
|
42
64
|
getRequirements: async (params) => await (0, actions_1.getRequirements)(this.client.viemClient, {
|
|
43
|
-
address:
|
|
65
|
+
address: accrualVault.asset,
|
|
44
66
|
chainId: this.chainId,
|
|
45
67
|
supportSignature: this.client.options.supportSignature,
|
|
46
68
|
supportDeployless: this.client.options.supportDeployless,
|
|
47
69
|
useSimplePermit: params?.useSimplePermit,
|
|
48
70
|
args: {
|
|
49
|
-
amount
|
|
71
|
+
amount,
|
|
50
72
|
from: userAddress,
|
|
51
73
|
},
|
|
52
74
|
}),
|
|
@@ -54,19 +76,20 @@ class MorphoVaultV2 {
|
|
|
54
76
|
vault: {
|
|
55
77
|
chainId: this.chainId,
|
|
56
78
|
address: this.vault,
|
|
57
|
-
asset:
|
|
79
|
+
asset: accrualVault.asset,
|
|
58
80
|
},
|
|
59
81
|
args: {
|
|
60
|
-
|
|
82
|
+
amount,
|
|
61
83
|
maxSharePrice,
|
|
62
84
|
recipient: userAddress,
|
|
63
85
|
requirementSignature,
|
|
86
|
+
nativeAmount,
|
|
64
87
|
},
|
|
65
88
|
metadata: this.client.options.metadata,
|
|
66
89
|
}),
|
|
67
90
|
};
|
|
68
91
|
}
|
|
69
|
-
withdraw({
|
|
92
|
+
withdraw({ amount, userAddress }) {
|
|
70
93
|
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
71
94
|
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
72
95
|
}
|
|
@@ -74,7 +97,7 @@ class MorphoVaultV2 {
|
|
|
74
97
|
buildTx: () => (0, actions_1.vaultV2Withdraw)({
|
|
75
98
|
vault: { address: this.vault },
|
|
76
99
|
args: {
|
|
77
|
-
|
|
100
|
+
amount,
|
|
78
101
|
recipient: userAddress,
|
|
79
102
|
onBehalf: userAddress,
|
|
80
103
|
},
|
|
@@ -98,5 +121,43 @@ class MorphoVaultV2 {
|
|
|
98
121
|
}),
|
|
99
122
|
};
|
|
100
123
|
}
|
|
124
|
+
forceWithdraw({ deallocations, withdraw, userAddress, }) {
|
|
125
|
+
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
126
|
+
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
buildTx: () => (0, actions_1.vaultV2ForceWithdraw)({
|
|
130
|
+
vault: { address: this.vault },
|
|
131
|
+
args: {
|
|
132
|
+
deallocations,
|
|
133
|
+
withdraw: {
|
|
134
|
+
amount: withdraw.amount,
|
|
135
|
+
recipient: userAddress,
|
|
136
|
+
},
|
|
137
|
+
onBehalf: userAddress,
|
|
138
|
+
},
|
|
139
|
+
metadata: this.client.options.metadata,
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
forceRedeem({ deallocations, redeem, userAddress, }) {
|
|
144
|
+
if (this.client.viemClient.chain?.id !== this.chainId) {
|
|
145
|
+
throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
buildTx: () => (0, actions_1.vaultV2ForceRedeem)({
|
|
149
|
+
vault: { address: this.vault },
|
|
150
|
+
args: {
|
|
151
|
+
deallocations,
|
|
152
|
+
redeem: {
|
|
153
|
+
shares: redeem.shares,
|
|
154
|
+
recipient: userAddress,
|
|
155
|
+
},
|
|
156
|
+
onBehalf: userAddress,
|
|
157
|
+
},
|
|
158
|
+
metadata: this.client.options.metadata,
|
|
159
|
+
}),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
101
162
|
}
|
|
102
163
|
exports.MorphoVaultV2 = MorphoVaultV2;
|