@defisaver/ethena-sdk 0.0.4 → 0.0.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.
Files changed (76) hide show
  1. package/cjs/config/contracts.d.ts +181 -0
  2. package/cjs/config/contracts.js +72 -0
  3. package/cjs/constants/index.d.ts +7 -0
  4. package/cjs/constants/index.js +10 -0
  5. package/cjs/contracts.d.ts +696 -0
  6. package/cjs/contracts.js +80 -0
  7. package/cjs/exchange/index.d.ts +10 -0
  8. package/cjs/exchange/index.js +185 -0
  9. package/cjs/execution/index.d.ts +2 -0
  10. package/cjs/execution/index.js +15 -0
  11. package/cjs/execution/morpho.d.ts +2 -0
  12. package/cjs/execution/morpho.js +56 -0
  13. package/cjs/index.d.ts +5 -1
  14. package/cjs/index.js +9 -1
  15. package/cjs/positionData/index.d.ts +1 -1
  16. package/cjs/positionData/index.js +2 -2
  17. package/cjs/positionData/morpho.d.ts +1 -1
  18. package/cjs/positionData/morpho.js +15 -7
  19. package/cjs/safe/index.d.ts +6 -0
  20. package/cjs/safe/index.js +80 -0
  21. package/cjs/services/viem.d.ts +31 -31
  22. package/cjs/types/common.d.ts +10 -0
  23. package/cjs/types/exchange.d.ts +19 -0
  24. package/cjs/types/exchange.js +12 -0
  25. package/cjs/types/execution.d.ts +9 -0
  26. package/cjs/types/execution.js +8 -0
  27. package/cjs/types/index.d.ts +3 -0
  28. package/cjs/types/index.js +3 -0
  29. package/cjs/types/safe.d.ts +5 -0
  30. package/cjs/types/safe.js +2 -0
  31. package/esm/config/contracts.d.ts +181 -0
  32. package/esm/config/contracts.js +69 -0
  33. package/esm/constants/index.d.ts +7 -0
  34. package/esm/constants/index.js +7 -0
  35. package/esm/contracts.d.ts +696 -0
  36. package/esm/contracts.js +37 -0
  37. package/esm/exchange/index.d.ts +10 -0
  38. package/esm/exchange/index.js +176 -0
  39. package/esm/execution/index.d.ts +2 -0
  40. package/esm/execution/index.js +11 -0
  41. package/esm/execution/morpho.d.ts +2 -0
  42. package/esm/execution/morpho.js +52 -0
  43. package/esm/index.d.ts +5 -1
  44. package/esm/index.js +5 -1
  45. package/esm/positionData/index.d.ts +1 -1
  46. package/esm/positionData/index.js +2 -2
  47. package/esm/positionData/morpho.d.ts +1 -1
  48. package/esm/positionData/morpho.js +16 -8
  49. package/esm/safe/index.d.ts +6 -0
  50. package/esm/safe/index.js +75 -0
  51. package/esm/services/viem.d.ts +31 -31
  52. package/esm/types/common.d.ts +10 -0
  53. package/esm/types/exchange.d.ts +19 -0
  54. package/esm/types/exchange.js +9 -0
  55. package/esm/types/execution.d.ts +9 -0
  56. package/esm/types/execution.js +5 -0
  57. package/esm/types/index.d.ts +3 -0
  58. package/esm/types/index.js +3 -0
  59. package/esm/types/safe.d.ts +5 -0
  60. package/esm/types/safe.js +1 -0
  61. package/package.json +3 -1
  62. package/src/config/contracts.ts +72 -0
  63. package/src/constants/index.ts +7 -0
  64. package/src/contracts.ts +57 -0
  65. package/src/exchange/index.ts +195 -0
  66. package/src/execution/index.ts +12 -0
  67. package/src/execution/morpho.ts +47 -0
  68. package/src/index.ts +8 -0
  69. package/src/positionData/index.ts +2 -2
  70. package/src/positionData/morpho.ts +17 -8
  71. package/src/safe/index.ts +99 -0
  72. package/src/types/common.ts +11 -0
  73. package/src/types/exchange.ts +21 -0
  74. package/src/types/execution.ts +11 -0
  75. package/src/types/index.ts +4 -1
  76. package/src/types/safe.ts +5 -0
@@ -826,12 +826,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
826
826
  withdrawals?: import("viem").Withdrawal[] | undefined | undefined;
827
827
  withdrawalsRoot?: `0x${string}` | undefined;
828
828
  transactions: includeTransactions extends true ? ({
829
- type: "legacy";
830
829
  to: import("viem").Address | null;
830
+ value: bigint;
831
+ nonce: number;
832
+ type: "legacy";
831
833
  from: import("viem").Address;
832
834
  gas: bigint;
833
- nonce: number;
834
- value: bigint;
835
835
  maxFeePerBlobGas?: undefined | undefined;
836
836
  gasPrice: bigint;
837
837
  maxFeePerGas?: undefined | undefined;
@@ -851,12 +851,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
851
851
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_1 ? T_1 extends (blockTag extends "pending" ? true : false) ? T_1 extends true ? null : `0x${string}` : never : never;
852
852
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_2 ? T_2 extends (blockTag extends "pending" ? true : false) ? T_2 extends true ? null : number : never : never;
853
853
  } | {
854
- type: "eip2930";
855
854
  to: import("viem").Address | null;
855
+ value: bigint;
856
+ nonce: number;
857
+ type: "eip2930";
856
858
  from: import("viem").Address;
857
859
  gas: bigint;
858
- nonce: number;
859
- value: bigint;
860
860
  maxFeePerBlobGas?: undefined | undefined;
861
861
  gasPrice: bigint;
862
862
  maxFeePerGas?: undefined | undefined;
@@ -876,12 +876,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
876
876
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_4 ? T_4 extends (blockTag extends "pending" ? true : false) ? T_4 extends true ? null : `0x${string}` : never : never;
877
877
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_5 ? T_5 extends (blockTag extends "pending" ? true : false) ? T_5 extends true ? null : number : never : never;
878
878
  } | {
879
- type: "eip1559";
880
879
  to: import("viem").Address | null;
880
+ value: bigint;
881
+ nonce: number;
882
+ type: "eip1559";
881
883
  from: import("viem").Address;
882
884
  gas: bigint;
883
- nonce: number;
884
- value: bigint;
885
885
  maxFeePerBlobGas?: undefined | undefined;
886
886
  gasPrice?: undefined | undefined;
887
887
  maxFeePerGas: bigint;
@@ -901,12 +901,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
901
901
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_7 ? T_7 extends (blockTag extends "pending" ? true : false) ? T_7 extends true ? null : `0x${string}` : never : never;
902
902
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_8 ? T_8 extends (blockTag extends "pending" ? true : false) ? T_8 extends true ? null : number : never : never;
903
903
  } | {
904
- type: "eip4844";
905
904
  to: import("viem").Address | null;
905
+ value: bigint;
906
+ nonce: number;
907
+ type: "eip4844";
906
908
  from: import("viem").Address;
907
909
  gas: bigint;
908
- nonce: number;
909
- value: bigint;
910
910
  maxFeePerBlobGas: bigint;
911
911
  gasPrice?: undefined | undefined;
912
912
  maxFeePerGas: bigint;
@@ -926,12 +926,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
926
926
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_10 ? T_10 extends (blockTag extends "pending" ? true : false) ? T_10 extends true ? null : `0x${string}` : never : never;
927
927
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_11 ? T_11 extends (blockTag extends "pending" ? true : false) ? T_11 extends true ? null : number : never : never;
928
928
  } | {
929
- type: "eip7702";
930
929
  to: import("viem").Address | null;
930
+ value: bigint;
931
+ nonce: number;
932
+ type: "eip7702";
931
933
  from: import("viem").Address;
932
934
  gas: bigint;
933
- nonce: number;
934
- value: bigint;
935
935
  maxFeePerBlobGas?: undefined | undefined;
936
936
  gasPrice?: undefined | undefined;
937
937
  maxFeePerGas: bigint;
@@ -976,12 +976,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
976
976
  } | undefined) => Promise<import("viem").EstimateMaxPriorityFeePerGasReturnType>;
977
977
  getStorageAt: (args: import("viem").GetStorageAtParameters) => Promise<import("viem").GetStorageAtReturnType>;
978
978
  getTransaction: <blockTag extends import("viem").BlockTag = "latest">(args: import("viem").GetTransactionParameters<blockTag>) => Promise<{
979
- type: "legacy";
980
979
  to: import("viem").Address | null;
980
+ value: bigint;
981
+ nonce: number;
982
+ type: "legacy";
981
983
  from: import("viem").Address;
982
984
  gas: bigint;
983
- nonce: number;
984
- value: bigint;
985
985
  maxFeePerBlobGas?: undefined | undefined;
986
986
  gasPrice: bigint;
987
987
  maxFeePerGas?: undefined | undefined;
@@ -1001,12 +1001,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
1001
1001
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_1 ? T_1 extends (blockTag extends "pending" ? true : false) ? T_1 extends true ? null : `0x${string}` : never : never;
1002
1002
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_2 ? T_2 extends (blockTag extends "pending" ? true : false) ? T_2 extends true ? null : number : never : never;
1003
1003
  } | {
1004
- type: "eip2930";
1005
1004
  to: import("viem").Address | null;
1005
+ value: bigint;
1006
+ nonce: number;
1007
+ type: "eip2930";
1006
1008
  from: import("viem").Address;
1007
1009
  gas: bigint;
1008
- nonce: number;
1009
- value: bigint;
1010
1010
  maxFeePerBlobGas?: undefined | undefined;
1011
1011
  gasPrice: bigint;
1012
1012
  maxFeePerGas?: undefined | undefined;
@@ -1026,12 +1026,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
1026
1026
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_4 ? T_4 extends (blockTag extends "pending" ? true : false) ? T_4 extends true ? null : `0x${string}` : never : never;
1027
1027
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_5 ? T_5 extends (blockTag extends "pending" ? true : false) ? T_5 extends true ? null : number : never : never;
1028
1028
  } | {
1029
- type: "eip1559";
1030
1029
  to: import("viem").Address | null;
1030
+ value: bigint;
1031
+ nonce: number;
1032
+ type: "eip1559";
1031
1033
  from: import("viem").Address;
1032
1034
  gas: bigint;
1033
- nonce: number;
1034
- value: bigint;
1035
1035
  maxFeePerBlobGas?: undefined | undefined;
1036
1036
  gasPrice?: undefined | undefined;
1037
1037
  maxFeePerGas: bigint;
@@ -1051,12 +1051,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
1051
1051
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_7 ? T_7 extends (blockTag extends "pending" ? true : false) ? T_7 extends true ? null : `0x${string}` : never : never;
1052
1052
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_8 ? T_8 extends (blockTag extends "pending" ? true : false) ? T_8 extends true ? null : number : never : never;
1053
1053
  } | {
1054
- type: "eip4844";
1055
1054
  to: import("viem").Address | null;
1055
+ value: bigint;
1056
+ nonce: number;
1057
+ type: "eip4844";
1056
1058
  from: import("viem").Address;
1057
1059
  gas: bigint;
1058
- nonce: number;
1059
- value: bigint;
1060
1060
  maxFeePerBlobGas: bigint;
1061
1061
  gasPrice?: undefined | undefined;
1062
1062
  maxFeePerGas: bigint;
@@ -1076,12 +1076,12 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
1076
1076
  blockHash: (blockTag extends "pending" ? true : false) extends infer T_10 ? T_10 extends (blockTag extends "pending" ? true : false) ? T_10 extends true ? null : `0x${string}` : never : never;
1077
1077
  transactionIndex: (blockTag extends "pending" ? true : false) extends infer T_11 ? T_11 extends (blockTag extends "pending" ? true : false) ? T_11 extends true ? null : number : never : never;
1078
1078
  } | {
1079
- type: "eip7702";
1080
1079
  to: import("viem").Address | null;
1080
+ value: bigint;
1081
+ nonce: number;
1082
+ type: "eip7702";
1081
1083
  from: import("viem").Address;
1082
1084
  gas: bigint;
1083
- nonce: number;
1084
- value: bigint;
1085
1085
  maxFeePerBlobGas?: undefined | undefined;
1086
1086
  gasPrice?: undefined | undefined;
1087
1087
  maxFeePerGas: bigint;
@@ -4357,7 +4357,7 @@ export declare const getViemProvider: (rpcUrl: string, network: NetworkNumber, o
4357
4357
  authorizationList: import("viem").TransactionSerializableEIP7702["authorizationList"];
4358
4358
  } ? "eip7702" : never) | (request["type"] extends string | undefined ? Extract<request["type"], string> : never)>) ? T_12 extends "eip7702" ? import("viem").TransactionRequestEIP7702 : never : never : never)>> & {
4359
4359
  chainId?: number | undefined;
4360
- }, (request["parameters"] extends readonly import("viem").PrepareTransactionRequestParameterType[] ? request["parameters"][number] : "type" | "gas" | "nonce" | "blobVersionedHashes" | "fees" | "chainId") extends infer T_13 ? T_13 extends (request["parameters"] extends readonly import("viem").PrepareTransactionRequestParameterType[] ? request["parameters"][number] : "type" | "gas" | "nonce" | "blobVersionedHashes" | "fees" | "chainId") ? T_13 extends "fees" ? "gasPrice" | "maxFeePerGas" | "maxPriorityFeePerGas" : T_13 : never : never> & (unknown extends request["kzg"] ? {} : Pick<request, "kzg">) extends infer T ? { [K in keyof T]: T[K]; } : never>;
4360
+ }, (request["parameters"] extends readonly import("viem").PrepareTransactionRequestParameterType[] ? request["parameters"][number] : "nonce" | "type" | "gas" | "blobVersionedHashes" | "fees" | "chainId") extends infer T_13 ? T_13 extends (request["parameters"] extends readonly import("viem").PrepareTransactionRequestParameterType[] ? request["parameters"][number] : "nonce" | "type" | "gas" | "blobVersionedHashes" | "fees" | "chainId") ? T_13 extends "fees" ? "gasPrice" | "maxFeePerGas" | "maxPriorityFeePerGas" : T_13 : never : never> & (unknown extends request["kzg"] ? {} : Pick<request, "kzg">) extends infer T ? { [K in keyof T]: T[K]; } : never>;
4361
4361
  readContract: <const abi extends import("viem").Abi | readonly unknown[], functionName extends import("viem").ContractFunctionName<abi, "pure" | "view">, const args extends import("viem").ContractFunctionArgs<abi, "pure" | "view", functionName>>(args: import("viem").ReadContractParameters<abi, functionName, args>) => Promise<import("viem").ReadContractReturnType<abi, functionName, args>>;
4362
4362
  sendRawTransaction: (args: import("viem").SendRawTransactionParameters) => Promise<import("viem").SendRawTransactionReturnType>;
4363
4363
  simulate: <const calls extends readonly unknown[]>(args: import("viem").SimulateBlocksParameters<calls>) => Promise<import("viem").SimulateBlocksReturnType<calls>>;
@@ -1,5 +1,6 @@
1
1
  import { IncentiveData, MMUsedAssets, MorphoBlueAggregatedPositionData, NetworkNumber } from '@defisaver/positions-sdk';
2
2
  import { SupportedMarkets } from './markets';
3
+ import { OffchainExchanges } from './exchange';
3
4
  export interface AssetData {
4
5
  symbol: string;
5
6
  address: string;
@@ -18,7 +19,16 @@ export interface MarketData {
18
19
  lltv: string;
19
20
  rate: string;
20
21
  }
22
+ export interface ExchangeInfo {
23
+ price: string;
24
+ source: OffchainExchanges | 'None';
25
+ sellAsset: string;
26
+ sellAmount: string;
27
+ buyAsset: string;
28
+ buyAmount: string;
29
+ }
21
30
  export interface PositionData extends MorphoBlueAggregatedPositionData {
22
31
  usedAssets: MMUsedAssets;
32
+ exchangeInfo: ExchangeInfo;
23
33
  }
24
34
  export { NetworkNumber, MMUsedAssets, IncentiveData, };
@@ -0,0 +1,19 @@
1
+ export declare enum OffchainExchanges {
2
+ ZeroX = "0x",
3
+ Paraswap = "Paraswap",
4
+ Kyberswap = "Kyberswap",
5
+ OneInch = "1Inch",
6
+ Bebop = "Bebop"
7
+ }
8
+ export interface PriceData {
9
+ price: string;
10
+ priceWithFee: string;
11
+ source: OffchainExchanges | 'None';
12
+ wrapper: string;
13
+ to: string;
14
+ allowanceTarget: string;
15
+ protocolFee: string;
16
+ data: string;
17
+ value: string;
18
+ gas: string;
19
+ }
@@ -0,0 +1,9 @@
1
+ export var OffchainExchanges;
2
+ (function (OffchainExchanges) {
3
+ OffchainExchanges["ZeroX"] = "0x";
4
+ OffchainExchanges["Paraswap"] = "Paraswap";
5
+ OffchainExchanges["Kyberswap"] = "Kyberswap";
6
+ OffchainExchanges["OneInch"] = "1Inch";
7
+ // Odos = 'Odos',
8
+ OffchainExchanges["Bebop"] = "Bebop";
9
+ })(OffchainExchanges || (OffchainExchanges = {}));
@@ -0,0 +1,9 @@
1
+ import { NetworkNumber } from '@defisaver/positions-sdk';
2
+ export declare enum RequestType {
3
+ Signature = "Signature",
4
+ EthCall = "EthCall"
5
+ }
6
+ export interface Request {
7
+ type: RequestType;
8
+ getParams: (rpcUrl: string, network: NetworkNumber, userAddress: string) => Promise<any>;
9
+ }
@@ -0,0 +1,5 @@
1
+ export var RequestType;
2
+ (function (RequestType) {
3
+ RequestType["Signature"] = "Signature";
4
+ RequestType["EthCall"] = "EthCall";
5
+ })(RequestType || (RequestType = {}));
@@ -1,2 +1,5 @@
1
1
  export * from './common';
2
2
  export * from './markets';
3
+ export * from './exchange';
4
+ export * from './safe';
5
+ export * from './execution';
@@ -1,2 +1,5 @@
1
1
  export * from './common';
2
2
  export * from './markets';
3
+ export * from './exchange';
4
+ export * from './safe';
5
+ export * from './execution';
@@ -0,0 +1,5 @@
1
+ export type Wallet = {
2
+ address: string;
3
+ type: string;
4
+ owners?: string[];
5
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/ethena-sdk",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "SDK for ethena lev create",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -26,7 +26,9 @@
26
26
  "homepage": "https://github.com/defisaver/ethena-sdk#readme",
27
27
  "dependencies": {
28
28
  "@defisaver/positions-sdk": "^2.1.57",
29
+ "@defisaver/sdk": "^1.3.18",
29
30
  "@defisaver/tokens": "^1.7.22",
31
+ "bn.js": "^5.1.3",
30
32
  "decimal.js": "^10.6.0",
31
33
  "viem": "^2.37.9"
32
34
  },
@@ -0,0 +1,72 @@
1
+ export const Safe130 = {
2
+ abi: [{
3
+ inputs: [{ internalType: 'address[]', name: '_owners', type: 'address[]' }, { internalType: 'uint256', name: '_threshold', type: 'uint256' }, { internalType: 'address', name: 'to', type: 'address' }, { internalType: 'bytes', name: 'data', type: 'bytes' }, { internalType: 'address', name: 'fallbackHandler', type: 'address' }, { internalType: 'address', name: 'paymentToken', type: 'address' }, { internalType: 'uint256', name: 'payment', type: 'uint256' }, { internalType: 'address payable', name: 'paymentReceiver', type: 'address' }], name: 'setup', outputs: [], stateMutability: 'pure', type: 'function',
4
+ }],
5
+ networks: {
6
+ 1: {
7
+ address: '0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552',
8
+ },
9
+ 10: {
10
+ address: '0xfb1bffC9d739B8D520DaF37dF666da4C687191EA',
11
+ },
12
+ 8453: {
13
+ address: '0xfb1bffC9d739B8D520DaF37dF666da4C687191EA',
14
+ },
15
+ 42161: {
16
+ address: '0x3E5c63644E683549055b9Be8653de26E0B4CD36E',
17
+ },
18
+ },
19
+ } as const;
20
+
21
+ export const SafeFallbackHandler130 = {
22
+ abi: [{ inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, {
23
+ inputs: [{ internalType: 'address', name: 'to', type: 'address' }, { internalType: 'uint256', name: 'value', type: 'uint256' }, { internalType: 'bytes', name: 'data', type: 'bytes' }, { internalType: 'enum Enum.Operation', name: 'operation', type: 'uint8' }], name: 'simulate', outputs: [{ internalType: 'uint256', name: 'estimate', type: 'uint256' }, { internalType: 'bool', name: 'success', type: 'bool' }, { internalType: 'bytes', name: 'returnData', type: 'bytes' }], stateMutability: 'nonpayable', type: 'function',
24
+ }],
25
+ networks: {
26
+ 1: {
27
+ address: '0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4',
28
+ },
29
+ 10: {
30
+ address: '0x017062a1dE2FE6b99BE3d9d37841FeD19F573804',
31
+ },
32
+ 8453: {
33
+ address: '0x017062a1dE2FE6b99BE3d9d37841FeD19F573804',
34
+ },
35
+ 42161: {
36
+ address: '0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4',
37
+ },
38
+ },
39
+ } as const;
40
+
41
+ export const SafeProxyFactory130 = {
42
+ abi: [{
43
+ inputs: [{ internalType: 'address', name: '_singleton', type: 'address' }, { internalType: 'bytes', name: 'initializer', type: 'bytes' }, { internalType: 'uint256', name: 'saltNonce', type: 'uint256' }], name: 'createProxyWithNonce', outputs: [{ internalType: 'contract GnosisSafeProxy', name: 'proxy', type: 'address' }], stateMutability: 'nonpayable', type: 'function',
44
+ }, {
45
+ inputs: [], name: 'proxyCreationCode', outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], stateMutability: 'pure', type: 'function',
46
+ }],
47
+ networks: {
48
+ 1: {
49
+ address: '0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2',
50
+ },
51
+ 10: {
52
+ address: '0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC',
53
+ },
54
+ 8453: {
55
+ address: '0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC',
56
+ },
57
+ 42161: {
58
+ address: '0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2',
59
+ },
60
+ },
61
+ } as const;
62
+
63
+ export const MorphoManager = {
64
+ abi: [{
65
+ inputs: [{ internalType: 'address', name: '', type: 'address' }], name: 'nonce', outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], stateMutability: 'view', type: 'function',
66
+ }],
67
+ networks: {
68
+ 1: {
69
+ address: '0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb',
70
+ },
71
+ },
72
+ } as const;
@@ -0,0 +1,7 @@
1
+ export const STABLE_PAIR_FEE_DIVIDER = '10000';
2
+ export const DFS_API_URL = 'https://fe.defisaver.com';
3
+ export const SAFE_API_URL = 'https://fe.defisaver.com';
4
+ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
5
+ export const SLIPPAGE_PERCENT = 0.05;
6
+ export const SAFE_REFUND_RECEIVER = '0x25aa0f9a42eE4Ea2Dc7f3c9fF02F558dcb0445a3';
7
+ export const SALT_PREFIX = '44654669205361766572'; // 'DeFi Saver' in hex
@@ -0,0 +1,57 @@
1
+ import { getContract, Client } from 'viem';
2
+ import { EthAddress, HexString, NetworkNumber } from '@defisaver/positions-sdk';
3
+ import * as configRaw from './config/contracts';
4
+
5
+ export type ConfigKey = keyof typeof configRaw;
6
+
7
+ declare type ContractConfig = {
8
+ abi: any[],
9
+ networks: Partial<Record<NetworkNumber, Network>>,
10
+ };
11
+ declare type Network = {
12
+ createdBlock?: number,
13
+ address: string,
14
+ oldVersions?: Record<string, { address: EthAddress, abi: any[] }>,
15
+ };
16
+ // @ts-ignore
17
+ const contractConfig:Record<ConfigKey, ContractConfig> = configRaw;
18
+
19
+ export const getConfigContractAddress = (name: ConfigKey, network: NetworkNumber): HexString => {
20
+ const networkData = contractConfig[name].networks[network];
21
+ const latestAddress = networkData?.address || '';
22
+ return latestAddress as HexString;
23
+ };
24
+
25
+ export const getConfigContractAbi = <TKey extends ConfigKey>(name: TKey): typeof configRaw[TKey]['abi'] => {
26
+ const latestAbi = contractConfig[name].abi;
27
+ return latestAbi as unknown as typeof configRaw[TKey]['abi'];
28
+ };
29
+
30
+ export const createContractFromConfigFunc = <TKey extends ConfigKey>(name: TKey, _address?: HexString) => (client: Client, network: NetworkNumber) => {
31
+ const address = (_address || getConfigContractAddress(name, network));
32
+ const abi = getConfigContractAbi(name) as typeof configRaw[TKey]['abi'];
33
+ return getContract({
34
+ address,
35
+ abi,
36
+ client,
37
+ });
38
+ };
39
+
40
+ export const Safe130Contract = createContractFromConfigFunc('Safe130');
41
+ export const SafeFactoryContract = createContractFromConfigFunc('SafeProxyFactory130');
42
+ export const MorphoManagerContract = createContractFromConfigFunc('MorphoManager');
43
+
44
+ export const getSafeWalletContract = (client: Client, address: HexString) => {
45
+ const abi = getConfigContractAbi('Safe130') as typeof configRaw['Safe130']['abi'];
46
+ return getContract({
47
+ address,
48
+ abi,
49
+ client,
50
+ });
51
+ };
52
+
53
+ export const getSafeWalletSingletonAddress = (network?: NetworkNumber) => getConfigContractAddress('Safe130', network || NetworkNumber.Eth);
54
+
55
+ export const getSafeFactoryAddress = (network?: NetworkNumber) => getConfigContractAddress('SafeProxyFactory130', network || NetworkNumber.Eth);
56
+
57
+ export const getSafeFallbackHandlerAddress = (network?: NetworkNumber) => getConfigContractAddress('SafeFallbackHandler130', network || NetworkNumber.Eth);
@@ -0,0 +1,195 @@
1
+ import Dec from 'decimal.js';
2
+ import BN from 'bn.js';
3
+ import { NetworkNumber } from '@defisaver/positions-sdk';
4
+ import { assetAmountInWei, getAssetInfo } from '@defisaver/tokens';
5
+ import { OffchainExchanges, PriceData } from '../types';
6
+ import {
7
+ DFS_API_URL, SLIPPAGE_PERCENT, STABLE_PAIR_FEE_DIVIDER, ZERO_ADDRESS,
8
+ } from '../constants';
9
+
10
+ const getOffchainEmptyData = (source: OffchainExchanges | 'None' = 'None'): PriceData => ({
11
+ wrapper: ZERO_ADDRESS,
12
+ to: ZERO_ADDRESS,
13
+ allowanceTarget: ZERO_ADDRESS,
14
+ price: '0',
15
+ priceWithFee: '0',
16
+ protocolFee: '0',
17
+ data: '0x00',
18
+ value: '0',
19
+ gas: '0',
20
+ source,
21
+ });
22
+
23
+ const parsePriceWithDecimals = (price: string, fromDecimals: number, toDecimals: number) => new Dec(price)
24
+ .div(10 ** toDecimals)
25
+ .div(10 ** (18 - fromDecimals))
26
+ .toString();
27
+
28
+ const formatPriceWithDecimalForContract = (price: string, fromDecimals: number, toDecimals: number) => new Dec(price)
29
+ .mul(10 ** toDecimals)
30
+ .mul(10 ** (18 - fromDecimals))
31
+ .floor()
32
+ .toString();
33
+
34
+ const includeFeeInPrice = (price: string, from: string, to: string, fee: string) => {
35
+ if (from === to) return price;
36
+ return new Dec(price).mul(new Dec(1).sub(fee)).toString();
37
+ };
38
+
39
+ const excludeFeeFromPrice = (price: string, from: string, to: string, fee: string) => {
40
+ if (from === to) return price;
41
+ return new Dec(price).mul(new Dec(1).add(fee)).toString();
42
+ };
43
+
44
+ const parseOffchainPrice = (
45
+ fromTokenSymbol: string,
46
+ fromTokenDecimals: number,
47
+ toTokenSymbol: string,
48
+ toTokenDecimals: number,
49
+ amount: string,
50
+ feeDecimal: string,
51
+ ): string => {
52
+ const _price = parsePriceWithDecimals(amount, fromTokenDecimals, toTokenDecimals);
53
+ return includeFeeInPrice(_price, fromTokenSymbol, toTokenSymbol, feeDecimal);
54
+ };
55
+
56
+ const getFeeDecimal = () => new Dec(1).div(STABLE_PAIR_FEE_DIVIDER).toString();
57
+
58
+ export const numStringToBytes = (num: number) => {
59
+ const bn = new BN(num.toString()).toTwos(256);
60
+ return bn.toString(16);
61
+ };
62
+
63
+ const getPriceFromServer = async (fromAsset: string, toAsset: string, amount: string, userAddress: string, network: NetworkNumber = NetworkNumber.Eth, infoOnly: boolean = true) => {
64
+ const fromAssetData = getAssetInfo(fromAsset, network);
65
+ const toAssetData = getAssetInfo(toAsset, network);
66
+ const feeDecimal = getFeeDecimal();
67
+ const excludedSources = ['Balancer_V2', 'Beethovenx'];
68
+
69
+ const allSources = Object.values(OffchainExchanges);
70
+
71
+ try {
72
+ const res = await fetch(`${DFS_API_URL}/api/exchange/get-best-price`, {
73
+ method: 'POST',
74
+ headers: {
75
+ 'Content-Type': 'application/json',
76
+ },
77
+ body: JSON.stringify({
78
+ fromAsset: fromAssetData.address,
79
+ fromAssetDecimals: fromAssetData.decimals,
80
+ fromAssetSymbol: fromAssetData.symbol,
81
+ toAsset: toAssetData.address,
82
+ toAssetDecimals: toAssetData.decimals,
83
+ toAssetSymbol: toAssetData.symbol,
84
+ sources: [...allSources.map(s => s.toLowerCase())],
85
+ chainId: network,
86
+ amount,
87
+ excludedSources,
88
+ infoOnly,
89
+ takerAddress: userAddress,
90
+ account: userAddress,
91
+ noFee: false,
92
+ feeDecimal,
93
+ // temporary fix for paraswap until old exchange service is removed
94
+ shouldFormatParaswapPrice: true,
95
+ }),
96
+ });
97
+
98
+ if (!res.ok) throw new Error(await res.text());
99
+ const data = (await res.json());
100
+
101
+ const formattedData: PriceData[] = data.map((d: any, i: number) => {
102
+ const source = allSources[i];
103
+ if (typeof d === 'string') return getOffchainEmptyData(source);
104
+ return {
105
+ wrapper: d.wrapper || ZERO_ADDRESS,
106
+ to: d.to || ZERO_ADDRESS,
107
+ allowanceTarget: d.allowanceTarget || ZERO_ADDRESS,
108
+ protocolFee: d.protocolFee || '0',
109
+ data: d.data || '0x00',
110
+ value: d.value || '0',
111
+ gas: d.gas || '0',
112
+ source: allSources[i],
113
+ price: d.price,
114
+ priceWithFee: +(d.price || '0') > 0
115
+ ? parseOffchainPrice(fromAssetData.symbol, fromAssetData.decimals, toAssetData.symbol, toAssetData.decimals, d.price, feeDecimal)
116
+ : '0',
117
+ };
118
+ }).filter((d: PriceData) => d.wrapper !== ZERO_ADDRESS && d.price !== '0').sort((a: PriceData, b: PriceData) => (new Dec(a.price).gt(b.price) ? -1 : 1));
119
+
120
+ return formattedData;
121
+ } catch {
122
+ return allSources.map(source => getOffchainEmptyData(source));
123
+ }
124
+ };
125
+
126
+ export const getBestPrice = async (fromAsset: string, toAsset: string, amount: string, userAddress: string, network: NetworkNumber = NetworkNumber.Eth): Promise<PriceData> => {
127
+ try {
128
+ const formattedData: PriceData[] = await getPriceFromServer(fromAsset, toAsset, amount, userAddress, network);
129
+
130
+ return formattedData[0] || getOffchainEmptyData();
131
+ } catch (e) {
132
+ console.error('Error fetching best price:', e);
133
+ return getOffchainEmptyData();
134
+ }
135
+ };
136
+
137
+ export const getExchangeOrder = async (fromAsset: string, toAsset: string, amount: string, userAddress: string, minPrice: string, network: NetworkNumber = NetworkNumber.Eth) => {
138
+ const fromAssetData = getAssetInfo(fromAsset, network);
139
+ const toAssetData = getAssetInfo(toAsset, network);
140
+ const feeDecimal = getFeeDecimal();
141
+
142
+ const offchainQuotes: PriceData[] = await getPriceFromServer(fromAsset, toAsset, amount, userAddress, network, false);
143
+
144
+ const formattedOffchainQuotes = offchainQuotes.map((quote) => ({
145
+ source: quote.source,
146
+ price: quote.priceWithFee,
147
+ wrapper: quote.wrapper,
148
+ wrapperData: quote.data,
149
+ offchainData: quote,
150
+ }));
151
+
152
+ const bestQuote = formattedOffchainQuotes[0];
153
+ const { offchainData, source, price } = bestQuote;
154
+
155
+ const minPriceFormatted = new Dec(excludeFeeFromPrice(minPrice, fromAssetData.address, toAssetData.address, feeDecimal))
156
+ .mul(100 - SLIPPAGE_PERCENT)
157
+ .div(100)
158
+ .toString();
159
+ const minPriceForContract = formatPriceWithDecimalForContract(minPriceFormatted, fromAssetData.decimals, toAssetData.decimals);
160
+
161
+ const offchainDataArray = [
162
+ offchainData.wrapper,
163
+ offchainData.to,
164
+ offchainData.allowanceTarget,
165
+ offchainData.price,
166
+ offchainData.protocolFee,
167
+ offchainData.data,
168
+ ];
169
+
170
+ const value = offchainData.protocolFee;
171
+
172
+ const wrapper = ZERO_ADDRESS;
173
+ const wrapperData = `0x${numStringToBytes(Math.floor(Date.now() / 1000))}`;
174
+ const amountWei = assetAmountInWei(amount, fromAsset).toString();
175
+
176
+ if (offchainData.data === '0x00') throw new Error('Offchain data is empty');
177
+
178
+ return {
179
+ orderData: [
180
+ fromAssetData.address,
181
+ toAssetData.address,
182
+ amountWei,
183
+ '0',
184
+ minPriceForContract,
185
+ STABLE_PAIR_FEE_DIVIDER,
186
+ '0x0000000000000000000000000000000000000000', // set by contract
187
+ wrapper,
188
+ wrapperData,
189
+ offchainDataArray,
190
+ ],
191
+ value,
192
+ source,
193
+ price,
194
+ };
195
+ };
@@ -0,0 +1,12 @@
1
+ import { SupportedMarkets } from '../types';
2
+ import { getMorphoRequests } from './morpho';
3
+
4
+ export const getRequests = (market: SupportedMarkets) => {
5
+ switch (market) {
6
+ case SupportedMarkets.MorphoBlueSUSDeUSDtb_915: {
7
+ return getMorphoRequests();
8
+ }
9
+ default:
10
+ throw new Error(`Unsupported market: ${market}`);
11
+ }
12
+ };