@stableflow/hyperliquid 3.0.0-beta-02a59f37a0-20260515
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 +37 -0
- package/dist/index.d.mts +75 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +177 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @stableflow/hyperliquid
|
|
2
|
+
|
|
3
|
+
Hyperliquid deposit helpers for the StableFlow SDK: quote via OneClick, transfer on source chain, permit + deposit to Hyperliquid, and status polling.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @stableflow/hyperliquid @stableflow/core @stableflow/bridges
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install wallet adapters for the source chain (e.g. `@stableflow/wallet-evm`, `@stableflow/wallet-solana`) and an EVM wallet on Arbitrum for USDC permit signing.
|
|
12
|
+
|
|
13
|
+
## Main exports
|
|
14
|
+
|
|
15
|
+
| Export | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| `Hyperliquid` | Service instance: `quote`, `transfer`, `deposit`, `getStatus` |
|
|
18
|
+
| `HyperliquidFromTokens` | Supported source tokens |
|
|
19
|
+
| `HyperliuquidToToken` | Destination token (USDC on Arbitrum) — note typo in export name |
|
|
20
|
+
| `HyperliuquidMinAmount` | Minimum `amountWei` for quotes — note typo in export name |
|
|
21
|
+
|
|
22
|
+
Types: `HyperliquidQuoteParams`, `HyperliquidTransferParams`, `HyperliquidDepositParams`, `HyperliquidGetStatusParams`, …
|
|
23
|
+
|
|
24
|
+
## Flow
|
|
25
|
+
|
|
26
|
+
1. `Hyperliquid.quote({ dry: true, ... })` — fast estimate (default `dry: true`)
|
|
27
|
+
2. `Hyperliquid.quote({ dry: false, ... })` — obtain deposit address before transfer
|
|
28
|
+
3. `Hyperliquid.transfer({ wallet, quote })` — source-chain deposit tx
|
|
29
|
+
4. `Hyperliquid.deposit({ evmWallet, evmWalletAddress, quote, txhash })` — Arbitrum USDC permit + API deposit
|
|
30
|
+
5. `Hyperliquid.getStatus({ depositId })` — poll deposit status
|
|
31
|
+
|
|
32
|
+
See [Developer Guide](../../DEVELOPER_GUIDE.md#hyperliquid) for details.
|
|
33
|
+
|
|
34
|
+
## See also
|
|
35
|
+
|
|
36
|
+
- [@stableflow/bridges](../bridges/README.md)
|
|
37
|
+
- [@stableflow/core](../core/README.md)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { WalletConfig, TokenConfig } from '@stableflow/core';
|
|
2
|
+
|
|
3
|
+
declare class HyperliquidService {
|
|
4
|
+
quote(params: HyperliquidQuoteParams): Promise<{
|
|
5
|
+
quote: any;
|
|
6
|
+
error: string | null;
|
|
7
|
+
}>;
|
|
8
|
+
transfer(params: HyperliquidTransferParams): Promise<string>;
|
|
9
|
+
deposit(params: HyperliquidDepositParams): Promise<HyperliquidDepositResponse>;
|
|
10
|
+
getStatus(params: HyperliquidGetStatusParams): Promise<HyperliquidDepositStatusResponse>;
|
|
11
|
+
protected generatePermit(params: HyperliquidGeneratePermitParams): Promise<{
|
|
12
|
+
amount: string;
|
|
13
|
+
deadline: number;
|
|
14
|
+
owner: string;
|
|
15
|
+
r: string;
|
|
16
|
+
s: string;
|
|
17
|
+
spender: string;
|
|
18
|
+
token: string;
|
|
19
|
+
v: 27 | 28;
|
|
20
|
+
nonce: number;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
declare const Hyperliquid: HyperliquidService;
|
|
24
|
+
declare const HyperliquidFromTokens: TokenConfig[];
|
|
25
|
+
declare const HyperliuquidToToken: TokenConfig;
|
|
26
|
+
declare const HyperliuquidMinAmount: string;
|
|
27
|
+
interface HyperliquidQuoteParams {
|
|
28
|
+
slippageTolerance: number;
|
|
29
|
+
refundTo: string;
|
|
30
|
+
recipient: string;
|
|
31
|
+
wallet: WalletConfig;
|
|
32
|
+
fromToken: TokenConfig;
|
|
33
|
+
prices: Record<string, string>;
|
|
34
|
+
amountWei: string;
|
|
35
|
+
dry?: boolean;
|
|
36
|
+
oneclickParams?: {
|
|
37
|
+
appFees?: {
|
|
38
|
+
recipient: string;
|
|
39
|
+
fee: number;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface HyperliquidTransferParams {
|
|
44
|
+
wallet: WalletConfig;
|
|
45
|
+
evmWallet: WalletConfig;
|
|
46
|
+
evmWalletAddress: string;
|
|
47
|
+
quote: any;
|
|
48
|
+
}
|
|
49
|
+
interface HyperliquidGeneratePermitParams {
|
|
50
|
+
address: string;
|
|
51
|
+
evmWallet: WalletConfig;
|
|
52
|
+
amountWei: string;
|
|
53
|
+
}
|
|
54
|
+
interface HyperliquidDepositParams extends HyperliquidTransferParams {
|
|
55
|
+
txhash: string;
|
|
56
|
+
}
|
|
57
|
+
interface HyperliquidGetStatusParams {
|
|
58
|
+
depositId: string;
|
|
59
|
+
}
|
|
60
|
+
interface HyperliquidResponse<T> {
|
|
61
|
+
code: number;
|
|
62
|
+
data: T;
|
|
63
|
+
}
|
|
64
|
+
interface HyperliquidDepositResponseData {
|
|
65
|
+
depositId: number;
|
|
66
|
+
}
|
|
67
|
+
type HyperliquidDepositResponse = HyperliquidResponse<HyperliquidDepositResponseData>;
|
|
68
|
+
type HyperliquidDepositStatus = "PROCESSING" | "SUCCESS" | "REFUNDED" | "FAILED";
|
|
69
|
+
interface HyperliquidDepositStatusResponseData {
|
|
70
|
+
status: HyperliquidDepositStatus;
|
|
71
|
+
txHash: string;
|
|
72
|
+
}
|
|
73
|
+
type HyperliquidDepositStatusResponse = HyperliquidResponse<HyperliquidDepositStatusResponseData>;
|
|
74
|
+
|
|
75
|
+
export { Hyperliquid, type HyperliquidDepositParams, type HyperliquidDepositResponse, type HyperliquidDepositResponseData, type HyperliquidDepositStatus, type HyperliquidDepositStatusResponse, type HyperliquidDepositStatusResponseData, HyperliquidFromTokens, type HyperliquidGeneratePermitParams, type HyperliquidGetStatusParams, type HyperliquidQuoteParams, type HyperliquidResponse, type HyperliquidTransferParams, HyperliuquidMinAmount, HyperliuquidToToken };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { WalletConfig, TokenConfig } from '@stableflow/core';
|
|
2
|
+
|
|
3
|
+
declare class HyperliquidService {
|
|
4
|
+
quote(params: HyperliquidQuoteParams): Promise<{
|
|
5
|
+
quote: any;
|
|
6
|
+
error: string | null;
|
|
7
|
+
}>;
|
|
8
|
+
transfer(params: HyperliquidTransferParams): Promise<string>;
|
|
9
|
+
deposit(params: HyperliquidDepositParams): Promise<HyperliquidDepositResponse>;
|
|
10
|
+
getStatus(params: HyperliquidGetStatusParams): Promise<HyperliquidDepositStatusResponse>;
|
|
11
|
+
protected generatePermit(params: HyperliquidGeneratePermitParams): Promise<{
|
|
12
|
+
amount: string;
|
|
13
|
+
deadline: number;
|
|
14
|
+
owner: string;
|
|
15
|
+
r: string;
|
|
16
|
+
s: string;
|
|
17
|
+
spender: string;
|
|
18
|
+
token: string;
|
|
19
|
+
v: 27 | 28;
|
|
20
|
+
nonce: number;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
declare const Hyperliquid: HyperliquidService;
|
|
24
|
+
declare const HyperliquidFromTokens: TokenConfig[];
|
|
25
|
+
declare const HyperliuquidToToken: TokenConfig;
|
|
26
|
+
declare const HyperliuquidMinAmount: string;
|
|
27
|
+
interface HyperliquidQuoteParams {
|
|
28
|
+
slippageTolerance: number;
|
|
29
|
+
refundTo: string;
|
|
30
|
+
recipient: string;
|
|
31
|
+
wallet: WalletConfig;
|
|
32
|
+
fromToken: TokenConfig;
|
|
33
|
+
prices: Record<string, string>;
|
|
34
|
+
amountWei: string;
|
|
35
|
+
dry?: boolean;
|
|
36
|
+
oneclickParams?: {
|
|
37
|
+
appFees?: {
|
|
38
|
+
recipient: string;
|
|
39
|
+
fee: number;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface HyperliquidTransferParams {
|
|
44
|
+
wallet: WalletConfig;
|
|
45
|
+
evmWallet: WalletConfig;
|
|
46
|
+
evmWalletAddress: string;
|
|
47
|
+
quote: any;
|
|
48
|
+
}
|
|
49
|
+
interface HyperliquidGeneratePermitParams {
|
|
50
|
+
address: string;
|
|
51
|
+
evmWallet: WalletConfig;
|
|
52
|
+
amountWei: string;
|
|
53
|
+
}
|
|
54
|
+
interface HyperliquidDepositParams extends HyperliquidTransferParams {
|
|
55
|
+
txhash: string;
|
|
56
|
+
}
|
|
57
|
+
interface HyperliquidGetStatusParams {
|
|
58
|
+
depositId: string;
|
|
59
|
+
}
|
|
60
|
+
interface HyperliquidResponse<T> {
|
|
61
|
+
code: number;
|
|
62
|
+
data: T;
|
|
63
|
+
}
|
|
64
|
+
interface HyperliquidDepositResponseData {
|
|
65
|
+
depositId: number;
|
|
66
|
+
}
|
|
67
|
+
type HyperliquidDepositResponse = HyperliquidResponse<HyperliquidDepositResponseData>;
|
|
68
|
+
type HyperliquidDepositStatus = "PROCESSING" | "SUCCESS" | "REFUNDED" | "FAILED";
|
|
69
|
+
interface HyperliquidDepositStatusResponseData {
|
|
70
|
+
status: HyperliquidDepositStatus;
|
|
71
|
+
txHash: string;
|
|
72
|
+
}
|
|
73
|
+
type HyperliquidDepositStatusResponse = HyperliquidResponse<HyperliquidDepositStatusResponseData>;
|
|
74
|
+
|
|
75
|
+
export { Hyperliquid, type HyperliquidDepositParams, type HyperliquidDepositResponse, type HyperliquidDepositResponseData, type HyperliquidDepositStatus, type HyperliquidDepositStatusResponse, type HyperliquidDepositStatusResponseData, HyperliquidFromTokens, type HyperliquidGeneratePermitParams, type HyperliquidGetStatusParams, type HyperliquidQuoteParams, type HyperliquidResponse, type HyperliquidTransferParams, HyperliuquidMinAmount, HyperliuquidToToken };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ethers = require('ethers');
|
|
4
|
+
var core = require('@stableflow/core');
|
|
5
|
+
var bridges = require('@stableflow/bridges');
|
|
6
|
+
var Big = require('big.js');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var Big__default = /*#__PURE__*/_interopDefault(Big);
|
|
11
|
+
|
|
12
|
+
// src/index.ts
|
|
13
|
+
var SPENDER = "0x2df1c51e09aecf9cacb7bc98cb1742757f163df7";
|
|
14
|
+
var DESTINATION_TOKEN = core.usdcChains["arb"];
|
|
15
|
+
var MIN_AMOUNT = Big__default.default(5).times(10 ** DESTINATION_TOKEN.decimals).toFixed(0);
|
|
16
|
+
var HyperliquidService = class {
|
|
17
|
+
async quote(params) {
|
|
18
|
+
const result = { quote: null, error: null };
|
|
19
|
+
if (Big__default.default(params.amountWei || 0).lt(MIN_AMOUNT)) {
|
|
20
|
+
result.error = `Amount is too low, at least ${MIN_AMOUNT}`;
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
const quoteParams = {
|
|
24
|
+
...params,
|
|
25
|
+
dry: params.dry ?? true,
|
|
26
|
+
slippageTolerance: params.slippageTolerance * 100,
|
|
27
|
+
originAsset: params.fromToken.assetId,
|
|
28
|
+
toToken: DESTINATION_TOKEN,
|
|
29
|
+
destinationAsset: DESTINATION_TOKEN.assetId,
|
|
30
|
+
amount: params.amountWei,
|
|
31
|
+
refundType: "ORIGIN_CHAIN",
|
|
32
|
+
appFees: params.oneclickParams?.appFees,
|
|
33
|
+
swapType: "EXACT_OUTPUT",
|
|
34
|
+
isProxy: false
|
|
35
|
+
};
|
|
36
|
+
try {
|
|
37
|
+
const quoteRes = await bridges.ServiceMap[core.Service.OneClick].quote(quoteParams);
|
|
38
|
+
result.quote = quoteRes;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
const _err = core.formatQuoteError(error, { service: core.Service.OneClick, fromToken: params.fromToken });
|
|
41
|
+
result.error = _err.error;
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
async transfer(params) {
|
|
46
|
+
const {
|
|
47
|
+
quote,
|
|
48
|
+
wallet
|
|
49
|
+
} = params;
|
|
50
|
+
const sendParams = {
|
|
51
|
+
wallet,
|
|
52
|
+
sendParam: quote?.sendParam,
|
|
53
|
+
fromToken: quote?.quoteParam.fromToken,
|
|
54
|
+
depositAddress: quote?.quote?.depositAddress,
|
|
55
|
+
amountWei: quote?.quote?.amountIn
|
|
56
|
+
};
|
|
57
|
+
const txhash = await bridges.ServiceMap[core.Service.OneClick].send(sendParams);
|
|
58
|
+
return txhash;
|
|
59
|
+
}
|
|
60
|
+
async deposit(params) {
|
|
61
|
+
const {
|
|
62
|
+
evmWallet,
|
|
63
|
+
evmWalletAddress,
|
|
64
|
+
quote,
|
|
65
|
+
txhash
|
|
66
|
+
} = params;
|
|
67
|
+
const permitParams = await this.generatePermit({
|
|
68
|
+
address: evmWalletAddress,
|
|
69
|
+
evmWallet,
|
|
70
|
+
amountWei: quote?.quote?.amountOut
|
|
71
|
+
});
|
|
72
|
+
const depositParams = {
|
|
73
|
+
deposit_address: quote?.quote?.depositAddress,
|
|
74
|
+
from_addr: quote?.quoteParam?.refundTo,
|
|
75
|
+
from_amount: quote?.quote?.amountIn,
|
|
76
|
+
from_chain: quote?.quoteParam?.fromToken?.blockchain,
|
|
77
|
+
from_hash: txhash,
|
|
78
|
+
from_token: quote?.quoteParam?.fromToken?.contractAddress,
|
|
79
|
+
sender: quote?.quoteParam?.recipient,
|
|
80
|
+
to_amount: quote?.quote?.amountOut,
|
|
81
|
+
to_chain: quote?.quoteParam?.toToken?.blockchain,
|
|
82
|
+
to_token: quote?.quoteParam?.toToken?.contractAddress,
|
|
83
|
+
type: core.Service.OneClick,
|
|
84
|
+
permit: permitParams
|
|
85
|
+
};
|
|
86
|
+
const depositRes = await core.request(core.OpenAPI, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
url: "/v0/deposit",
|
|
89
|
+
body: depositParams,
|
|
90
|
+
mediaType: "application/json",
|
|
91
|
+
errors: {
|
|
92
|
+
400: `Bad Request - Invalid input data`,
|
|
93
|
+
401: `Unauthorized - JWT token is invalid`
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return depositRes;
|
|
97
|
+
}
|
|
98
|
+
async getStatus(params) {
|
|
99
|
+
return core.request(core.OpenAPI, {
|
|
100
|
+
method: "GET",
|
|
101
|
+
url: "/v0/deposit",
|
|
102
|
+
query: {
|
|
103
|
+
depositId: params.depositId
|
|
104
|
+
},
|
|
105
|
+
mediaType: "application/json",
|
|
106
|
+
errors: {
|
|
107
|
+
400: `Bad Request - Invalid input data`,
|
|
108
|
+
401: `Unauthorized - JWT token is invalid`
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async generatePermit(params) {
|
|
113
|
+
const {
|
|
114
|
+
address,
|
|
115
|
+
evmWallet,
|
|
116
|
+
amountWei
|
|
117
|
+
} = params;
|
|
118
|
+
const tokenAddress = DESTINATION_TOKEN.contractAddress;
|
|
119
|
+
const name = DESTINATION_TOKEN.name;
|
|
120
|
+
const chainId = DESTINATION_TOKEN.chainId;
|
|
121
|
+
const provider = new ethers.ethers.JsonRpcProvider(core.getChainRpcUrl("arb").rpcUrl);
|
|
122
|
+
const erc20 = new ethers.ethers.Contract(
|
|
123
|
+
tokenAddress,
|
|
124
|
+
[
|
|
125
|
+
"function name() view returns (string)",
|
|
126
|
+
"function nonces(address) view returns (uint256)",
|
|
127
|
+
"function decimals() view returns (uint8)"
|
|
128
|
+
],
|
|
129
|
+
provider
|
|
130
|
+
);
|
|
131
|
+
const deadline = Math.floor(Date.now() / 1e3) + 86400;
|
|
132
|
+
const nonce = await erc20.nonces(address);
|
|
133
|
+
const value = amountWei;
|
|
134
|
+
const domain = {
|
|
135
|
+
name,
|
|
136
|
+
version: "2",
|
|
137
|
+
chainId: Number(chainId),
|
|
138
|
+
verifyingContract: tokenAddress
|
|
139
|
+
};
|
|
140
|
+
const types = {
|
|
141
|
+
Permit: [
|
|
142
|
+
{ name: "owner", type: "address" },
|
|
143
|
+
{ name: "spender", type: "address" },
|
|
144
|
+
{ name: "value", type: "uint256" },
|
|
145
|
+
{ name: "nonce", type: "uint256" },
|
|
146
|
+
{ name: "deadline", type: "uint256" }
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
const values = {
|
|
150
|
+
owner: address,
|
|
151
|
+
spender: SPENDER,
|
|
152
|
+
value,
|
|
153
|
+
nonce: nonce.toString(),
|
|
154
|
+
deadline
|
|
155
|
+
};
|
|
156
|
+
const signature = await evmWallet.signTypedData({
|
|
157
|
+
domain,
|
|
158
|
+
types,
|
|
159
|
+
values
|
|
160
|
+
});
|
|
161
|
+
const { v, r, s } = ethers.ethers.Signature.from(signature);
|
|
162
|
+
const permitParams = {
|
|
163
|
+
amount: value,
|
|
164
|
+
deadline,
|
|
165
|
+
owner: address,
|
|
166
|
+
r,
|
|
167
|
+
s,
|
|
168
|
+
spender: SPENDER,
|
|
169
|
+
token: tokenAddress,
|
|
170
|
+
v,
|
|
171
|
+
nonce: Number(nonce)
|
|
172
|
+
};
|
|
173
|
+
return permitParams;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
var Hyperliquid = new HyperliquidService();
|
|
177
|
+
var HyperliquidFromTokens = core.tokens.filter((token) => !(token.chainName === "Arbitrum" && token.symbol === "USDC"));
|
|
178
|
+
var HyperliuquidToToken = DESTINATION_TOKEN;
|
|
179
|
+
var HyperliuquidMinAmount = MIN_AMOUNT;
|
|
180
|
+
|
|
181
|
+
exports.Hyperliquid = Hyperliquid;
|
|
182
|
+
exports.HyperliquidFromTokens = HyperliquidFromTokens;
|
|
183
|
+
exports.HyperliuquidMinAmount = HyperliuquidMinAmount;
|
|
184
|
+
exports.HyperliuquidToToken = HyperliuquidToToken;
|
|
185
|
+
//# sourceMappingURL=index.js.map
|
|
186
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["usdcChains","Big","ServiceMap","Service","formatQuoteError","__request","OpenAPI","ethers","getChainRpcUrl","tokens"],"mappings":"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","file":"index.js","sourcesContent":["import { ethers } from 'ethers';\nimport {\n request as __request,\n usdcChains,\n getChainRpcUrl,\n Service,\n formatQuoteError,\n tokens,\n OpenAPI,\n} from '@stableflow/core';\nimport { ServiceMap } from '@stableflow/bridges';\nimport type { WalletConfig, TokenConfig } from '@stableflow/core';\nimport Big from 'big.js';\n\nconst SPENDER = \"0x2df1c51e09aecf9cacb7bc98cb1742757f163df7\";\nconst DESTINATION_TOKEN = usdcChains[\"arb\"];\nconst MIN_AMOUNT = Big(5).times(10 ** DESTINATION_TOKEN.decimals).toFixed(0);\n\nclass HyperliquidService {\n public async quote(params: HyperliquidQuoteParams): Promise<{ quote: any; error: string | null; }> {\n\n const result: { quote: any; error: string | null; } = { quote: null, error: null };\n\n if (Big(params.amountWei || 0).lt(MIN_AMOUNT)) {\n result.error = `Amount is too low, at least ${MIN_AMOUNT}`;\n return result;\n }\n\n const quoteParams = {\n ...params,\n dry: params.dry ?? true,\n slippageTolerance: params.slippageTolerance * 100,\n originAsset: params.fromToken.assetId,\n toToken: DESTINATION_TOKEN,\n destinationAsset: DESTINATION_TOKEN.assetId,\n amount: params.amountWei,\n refundType: \"ORIGIN_CHAIN\",\n appFees: params.oneclickParams?.appFees,\n swapType: \"EXACT_OUTPUT\",\n isProxy: false,\n };\n\n try {\n const quoteRes = await ServiceMap[Service.OneClick].quote(quoteParams);\n result.quote = quoteRes;\n } catch (error) {\n const _err = formatQuoteError(error, { service: Service.OneClick, fromToken: params.fromToken });\n result.error = _err.error;\n }\n\n return result;\n }\n\n public async transfer(params: HyperliquidTransferParams): Promise<string> {\n const {\n quote,\n wallet,\n } = params;\n\n const sendParams = {\n wallet,\n sendParam: quote?.sendParam,\n fromToken: quote?.quoteParam.fromToken,\n depositAddress: quote?.quote?.depositAddress,\n amountWei: quote?.quote?.amountIn,\n };\n\n const txhash = await ServiceMap[Service.OneClick].send(sendParams);\n\n return txhash;\n }\n\n public async deposit(params: HyperliquidDepositParams): Promise<HyperliquidDepositResponse> {\n const {\n evmWallet,\n evmWalletAddress,\n quote,\n txhash,\n } = params;\n\n const permitParams = await this.generatePermit({\n address: evmWalletAddress,\n evmWallet,\n amountWei: quote?.quote?.amountOut,\n });\n\n const depositParams = {\n deposit_address: quote?.quote?.depositAddress,\n from_addr: quote?.quoteParam?.refundTo,\n from_amount: quote?.quote?.amountIn,\n from_chain: quote?.quoteParam?.fromToken?.blockchain,\n from_hash: txhash,\n from_token: quote?.quoteParam?.fromToken?.contractAddress,\n sender: quote?.quoteParam?.recipient,\n to_amount: quote?.quote?.amountOut,\n to_chain: quote?.quoteParam?.toToken?.blockchain,\n to_token: quote?.quoteParam?.toToken?.contractAddress,\n type: Service.OneClick,\n\n permit: permitParams,\n };\n\n const depositRes = await __request(OpenAPI, {\n method: \"POST\",\n url: \"/v0/deposit\",\n body: depositParams,\n mediaType: \"application/json\",\n errors: {\n 400: `Bad Request - Invalid input data`,\n 401: `Unauthorized - JWT token is invalid`,\n },\n });\n\n return depositRes as HyperliquidDepositResponse;\n }\n\n public async getStatus(params: HyperliquidGetStatusParams): Promise<HyperliquidDepositStatusResponse> {\n return __request(OpenAPI, {\n method: \"GET\",\n url: \"/v0/deposit\",\n query: {\n depositId: params.depositId,\n },\n mediaType: \"application/json\",\n errors: {\n 400: `Bad Request - Invalid input data`,\n 401: `Unauthorized - JWT token is invalid`,\n },\n });\n }\n\n protected async generatePermit(params: HyperliquidGeneratePermitParams) {\n const {\n address,\n evmWallet,\n amountWei,\n } = params;\n\n const tokenAddress = DESTINATION_TOKEN.contractAddress;\n const name = DESTINATION_TOKEN.name;\n const chainId = DESTINATION_TOKEN.chainId;\n\n const provider = new ethers.JsonRpcProvider(getChainRpcUrl(\"arb\").rpcUrl);\n const erc20 = new ethers.Contract(\n tokenAddress,\n [\n \"function name() view returns (string)\",\n \"function nonces(address) view returns (uint256)\",\n \"function decimals() view returns (uint8)\"\n ],\n provider\n );\n\n const deadline = Math.floor(Date.now() / 1000) + 86400;\n const nonce = await erc20.nonces(address);\n const value = amountWei;\n\n const domain = {\n name,\n version: \"2\",\n chainId: Number(chainId),\n verifyingContract: tokenAddress\n };\n\n const types = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" }\n ]\n };\n\n const values = {\n owner: address,\n spender: SPENDER,\n value,\n nonce: nonce.toString(),\n deadline\n };\n\n const signature = await (evmWallet as any).signTypedData({\n domain,\n types,\n values\n });\n\n const { v, r, s } = ethers.Signature.from(signature);\n\n const permitParams = {\n amount: value,\n deadline,\n owner: address,\n r,\n s,\n spender: SPENDER,\n token: tokenAddress,\n v,\n nonce: Number(nonce),\n };\n\n return permitParams;\n }\n}\n\nexport const Hyperliquid = new HyperliquidService();\n\nexport const HyperliquidFromTokens = tokens.filter((token) => !(token.chainName === \"Arbitrum\" && token.symbol === \"USDC\"));\nexport const HyperliuquidToToken = DESTINATION_TOKEN;\nexport const HyperliuquidMinAmount = MIN_AMOUNT;\n\nexport interface HyperliquidQuoteParams {\n slippageTolerance: number;\n refundTo: string;\n recipient: string;\n wallet: WalletConfig;\n fromToken: TokenConfig;\n prices: Record<string, string>;\n amountWei: string;\n // Whether to generate deposit address\n // false will generate a deposit address\n dry?: boolean;\n oneclickParams?: {\n appFees?: { recipient: string; fee: number; }[];\n };\n}\n\nexport interface HyperliquidTransferParams {\n // bridge wallet\n wallet: WalletConfig;\n // deposit wallet (evm wallet)\n evmWallet: WalletConfig;\n // deposit wallet address\n evmWalletAddress: string;\n // quote result with deposit address\n quote: any;\n}\n\nexport interface HyperliquidGeneratePermitParams {\n address: string;\n evmWallet: WalletConfig;\n amountWei: string;\n}\n\nexport interface HyperliquidDepositParams extends HyperliquidTransferParams {\n txhash: string;\n}\n\nexport interface HyperliquidGetStatusParams {\n depositId: string;\n}\n\nexport interface HyperliquidResponse<T> {\n code: number;\n data: T;\n}\n\nexport interface HyperliquidDepositResponseData {\n depositId: number;\n}\n\nexport type HyperliquidDepositResponse = HyperliquidResponse<HyperliquidDepositResponseData>;\n\nexport type HyperliquidDepositStatus = \"PROCESSING\" | \"SUCCESS\" | \"REFUNDED\" | \"FAILED\";\n\nexport interface HyperliquidDepositStatusResponseData {\n status: HyperliquidDepositStatus;\n txHash: string;\n}\n\nexport type HyperliquidDepositStatusResponse = HyperliquidResponse<HyperliquidDepositStatusResponseData>;\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { usdcChains, tokens, Service, formatQuoteError, request, OpenAPI, getChainRpcUrl } from '@stableflow/core';
|
|
3
|
+
import { ServiceMap } from '@stableflow/bridges';
|
|
4
|
+
import Big from 'big.js';
|
|
5
|
+
|
|
6
|
+
// src/index.ts
|
|
7
|
+
var SPENDER = "0x2df1c51e09aecf9cacb7bc98cb1742757f163df7";
|
|
8
|
+
var DESTINATION_TOKEN = usdcChains["arb"];
|
|
9
|
+
var MIN_AMOUNT = Big(5).times(10 ** DESTINATION_TOKEN.decimals).toFixed(0);
|
|
10
|
+
var HyperliquidService = class {
|
|
11
|
+
async quote(params) {
|
|
12
|
+
const result = { quote: null, error: null };
|
|
13
|
+
if (Big(params.amountWei || 0).lt(MIN_AMOUNT)) {
|
|
14
|
+
result.error = `Amount is too low, at least ${MIN_AMOUNT}`;
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
const quoteParams = {
|
|
18
|
+
...params,
|
|
19
|
+
dry: params.dry ?? true,
|
|
20
|
+
slippageTolerance: params.slippageTolerance * 100,
|
|
21
|
+
originAsset: params.fromToken.assetId,
|
|
22
|
+
toToken: DESTINATION_TOKEN,
|
|
23
|
+
destinationAsset: DESTINATION_TOKEN.assetId,
|
|
24
|
+
amount: params.amountWei,
|
|
25
|
+
refundType: "ORIGIN_CHAIN",
|
|
26
|
+
appFees: params.oneclickParams?.appFees,
|
|
27
|
+
swapType: "EXACT_OUTPUT",
|
|
28
|
+
isProxy: false
|
|
29
|
+
};
|
|
30
|
+
try {
|
|
31
|
+
const quoteRes = await ServiceMap[Service.OneClick].quote(quoteParams);
|
|
32
|
+
result.quote = quoteRes;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const _err = formatQuoteError(error, { service: Service.OneClick, fromToken: params.fromToken });
|
|
35
|
+
result.error = _err.error;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
async transfer(params) {
|
|
40
|
+
const {
|
|
41
|
+
quote,
|
|
42
|
+
wallet
|
|
43
|
+
} = params;
|
|
44
|
+
const sendParams = {
|
|
45
|
+
wallet,
|
|
46
|
+
sendParam: quote?.sendParam,
|
|
47
|
+
fromToken: quote?.quoteParam.fromToken,
|
|
48
|
+
depositAddress: quote?.quote?.depositAddress,
|
|
49
|
+
amountWei: quote?.quote?.amountIn
|
|
50
|
+
};
|
|
51
|
+
const txhash = await ServiceMap[Service.OneClick].send(sendParams);
|
|
52
|
+
return txhash;
|
|
53
|
+
}
|
|
54
|
+
async deposit(params) {
|
|
55
|
+
const {
|
|
56
|
+
evmWallet,
|
|
57
|
+
evmWalletAddress,
|
|
58
|
+
quote,
|
|
59
|
+
txhash
|
|
60
|
+
} = params;
|
|
61
|
+
const permitParams = await this.generatePermit({
|
|
62
|
+
address: evmWalletAddress,
|
|
63
|
+
evmWallet,
|
|
64
|
+
amountWei: quote?.quote?.amountOut
|
|
65
|
+
});
|
|
66
|
+
const depositParams = {
|
|
67
|
+
deposit_address: quote?.quote?.depositAddress,
|
|
68
|
+
from_addr: quote?.quoteParam?.refundTo,
|
|
69
|
+
from_amount: quote?.quote?.amountIn,
|
|
70
|
+
from_chain: quote?.quoteParam?.fromToken?.blockchain,
|
|
71
|
+
from_hash: txhash,
|
|
72
|
+
from_token: quote?.quoteParam?.fromToken?.contractAddress,
|
|
73
|
+
sender: quote?.quoteParam?.recipient,
|
|
74
|
+
to_amount: quote?.quote?.amountOut,
|
|
75
|
+
to_chain: quote?.quoteParam?.toToken?.blockchain,
|
|
76
|
+
to_token: quote?.quoteParam?.toToken?.contractAddress,
|
|
77
|
+
type: Service.OneClick,
|
|
78
|
+
permit: permitParams
|
|
79
|
+
};
|
|
80
|
+
const depositRes = await request(OpenAPI, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
url: "/v0/deposit",
|
|
83
|
+
body: depositParams,
|
|
84
|
+
mediaType: "application/json",
|
|
85
|
+
errors: {
|
|
86
|
+
400: `Bad Request - Invalid input data`,
|
|
87
|
+
401: `Unauthorized - JWT token is invalid`
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return depositRes;
|
|
91
|
+
}
|
|
92
|
+
async getStatus(params) {
|
|
93
|
+
return request(OpenAPI, {
|
|
94
|
+
method: "GET",
|
|
95
|
+
url: "/v0/deposit",
|
|
96
|
+
query: {
|
|
97
|
+
depositId: params.depositId
|
|
98
|
+
},
|
|
99
|
+
mediaType: "application/json",
|
|
100
|
+
errors: {
|
|
101
|
+
400: `Bad Request - Invalid input data`,
|
|
102
|
+
401: `Unauthorized - JWT token is invalid`
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async generatePermit(params) {
|
|
107
|
+
const {
|
|
108
|
+
address,
|
|
109
|
+
evmWallet,
|
|
110
|
+
amountWei
|
|
111
|
+
} = params;
|
|
112
|
+
const tokenAddress = DESTINATION_TOKEN.contractAddress;
|
|
113
|
+
const name = DESTINATION_TOKEN.name;
|
|
114
|
+
const chainId = DESTINATION_TOKEN.chainId;
|
|
115
|
+
const provider = new ethers.JsonRpcProvider(getChainRpcUrl("arb").rpcUrl);
|
|
116
|
+
const erc20 = new ethers.Contract(
|
|
117
|
+
tokenAddress,
|
|
118
|
+
[
|
|
119
|
+
"function name() view returns (string)",
|
|
120
|
+
"function nonces(address) view returns (uint256)",
|
|
121
|
+
"function decimals() view returns (uint8)"
|
|
122
|
+
],
|
|
123
|
+
provider
|
|
124
|
+
);
|
|
125
|
+
const deadline = Math.floor(Date.now() / 1e3) + 86400;
|
|
126
|
+
const nonce = await erc20.nonces(address);
|
|
127
|
+
const value = amountWei;
|
|
128
|
+
const domain = {
|
|
129
|
+
name,
|
|
130
|
+
version: "2",
|
|
131
|
+
chainId: Number(chainId),
|
|
132
|
+
verifyingContract: tokenAddress
|
|
133
|
+
};
|
|
134
|
+
const types = {
|
|
135
|
+
Permit: [
|
|
136
|
+
{ name: "owner", type: "address" },
|
|
137
|
+
{ name: "spender", type: "address" },
|
|
138
|
+
{ name: "value", type: "uint256" },
|
|
139
|
+
{ name: "nonce", type: "uint256" },
|
|
140
|
+
{ name: "deadline", type: "uint256" }
|
|
141
|
+
]
|
|
142
|
+
};
|
|
143
|
+
const values = {
|
|
144
|
+
owner: address,
|
|
145
|
+
spender: SPENDER,
|
|
146
|
+
value,
|
|
147
|
+
nonce: nonce.toString(),
|
|
148
|
+
deadline
|
|
149
|
+
};
|
|
150
|
+
const signature = await evmWallet.signTypedData({
|
|
151
|
+
domain,
|
|
152
|
+
types,
|
|
153
|
+
values
|
|
154
|
+
});
|
|
155
|
+
const { v, r, s } = ethers.Signature.from(signature);
|
|
156
|
+
const permitParams = {
|
|
157
|
+
amount: value,
|
|
158
|
+
deadline,
|
|
159
|
+
owner: address,
|
|
160
|
+
r,
|
|
161
|
+
s,
|
|
162
|
+
spender: SPENDER,
|
|
163
|
+
token: tokenAddress,
|
|
164
|
+
v,
|
|
165
|
+
nonce: Number(nonce)
|
|
166
|
+
};
|
|
167
|
+
return permitParams;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
var Hyperliquid = new HyperliquidService();
|
|
171
|
+
var HyperliquidFromTokens = tokens.filter((token) => !(token.chainName === "Arbitrum" && token.symbol === "USDC"));
|
|
172
|
+
var HyperliuquidToToken = DESTINATION_TOKEN;
|
|
173
|
+
var HyperliuquidMinAmount = MIN_AMOUNT;
|
|
174
|
+
|
|
175
|
+
export { Hyperliquid, HyperliquidFromTokens, HyperliuquidMinAmount, HyperliuquidToToken };
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
177
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["__request"],"mappings":"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","file":"index.mjs","sourcesContent":["import { ethers } from 'ethers';\nimport {\n request as __request,\n usdcChains,\n getChainRpcUrl,\n Service,\n formatQuoteError,\n tokens,\n OpenAPI,\n} from '@stableflow/core';\nimport { ServiceMap } from '@stableflow/bridges';\nimport type { WalletConfig, TokenConfig } from '@stableflow/core';\nimport Big from 'big.js';\n\nconst SPENDER = \"0x2df1c51e09aecf9cacb7bc98cb1742757f163df7\";\nconst DESTINATION_TOKEN = usdcChains[\"arb\"];\nconst MIN_AMOUNT = Big(5).times(10 ** DESTINATION_TOKEN.decimals).toFixed(0);\n\nclass HyperliquidService {\n public async quote(params: HyperliquidQuoteParams): Promise<{ quote: any; error: string | null; }> {\n\n const result: { quote: any; error: string | null; } = { quote: null, error: null };\n\n if (Big(params.amountWei || 0).lt(MIN_AMOUNT)) {\n result.error = `Amount is too low, at least ${MIN_AMOUNT}`;\n return result;\n }\n\n const quoteParams = {\n ...params,\n dry: params.dry ?? true,\n slippageTolerance: params.slippageTolerance * 100,\n originAsset: params.fromToken.assetId,\n toToken: DESTINATION_TOKEN,\n destinationAsset: DESTINATION_TOKEN.assetId,\n amount: params.amountWei,\n refundType: \"ORIGIN_CHAIN\",\n appFees: params.oneclickParams?.appFees,\n swapType: \"EXACT_OUTPUT\",\n isProxy: false,\n };\n\n try {\n const quoteRes = await ServiceMap[Service.OneClick].quote(quoteParams);\n result.quote = quoteRes;\n } catch (error) {\n const _err = formatQuoteError(error, { service: Service.OneClick, fromToken: params.fromToken });\n result.error = _err.error;\n }\n\n return result;\n }\n\n public async transfer(params: HyperliquidTransferParams): Promise<string> {\n const {\n quote,\n wallet,\n } = params;\n\n const sendParams = {\n wallet,\n sendParam: quote?.sendParam,\n fromToken: quote?.quoteParam.fromToken,\n depositAddress: quote?.quote?.depositAddress,\n amountWei: quote?.quote?.amountIn,\n };\n\n const txhash = await ServiceMap[Service.OneClick].send(sendParams);\n\n return txhash;\n }\n\n public async deposit(params: HyperliquidDepositParams): Promise<HyperliquidDepositResponse> {\n const {\n evmWallet,\n evmWalletAddress,\n quote,\n txhash,\n } = params;\n\n const permitParams = await this.generatePermit({\n address: evmWalletAddress,\n evmWallet,\n amountWei: quote?.quote?.amountOut,\n });\n\n const depositParams = {\n deposit_address: quote?.quote?.depositAddress,\n from_addr: quote?.quoteParam?.refundTo,\n from_amount: quote?.quote?.amountIn,\n from_chain: quote?.quoteParam?.fromToken?.blockchain,\n from_hash: txhash,\n from_token: quote?.quoteParam?.fromToken?.contractAddress,\n sender: quote?.quoteParam?.recipient,\n to_amount: quote?.quote?.amountOut,\n to_chain: quote?.quoteParam?.toToken?.blockchain,\n to_token: quote?.quoteParam?.toToken?.contractAddress,\n type: Service.OneClick,\n\n permit: permitParams,\n };\n\n const depositRes = await __request(OpenAPI, {\n method: \"POST\",\n url: \"/v0/deposit\",\n body: depositParams,\n mediaType: \"application/json\",\n errors: {\n 400: `Bad Request - Invalid input data`,\n 401: `Unauthorized - JWT token is invalid`,\n },\n });\n\n return depositRes as HyperliquidDepositResponse;\n }\n\n public async getStatus(params: HyperliquidGetStatusParams): Promise<HyperliquidDepositStatusResponse> {\n return __request(OpenAPI, {\n method: \"GET\",\n url: \"/v0/deposit\",\n query: {\n depositId: params.depositId,\n },\n mediaType: \"application/json\",\n errors: {\n 400: `Bad Request - Invalid input data`,\n 401: `Unauthorized - JWT token is invalid`,\n },\n });\n }\n\n protected async generatePermit(params: HyperliquidGeneratePermitParams) {\n const {\n address,\n evmWallet,\n amountWei,\n } = params;\n\n const tokenAddress = DESTINATION_TOKEN.contractAddress;\n const name = DESTINATION_TOKEN.name;\n const chainId = DESTINATION_TOKEN.chainId;\n\n const provider = new ethers.JsonRpcProvider(getChainRpcUrl(\"arb\").rpcUrl);\n const erc20 = new ethers.Contract(\n tokenAddress,\n [\n \"function name() view returns (string)\",\n \"function nonces(address) view returns (uint256)\",\n \"function decimals() view returns (uint8)\"\n ],\n provider\n );\n\n const deadline = Math.floor(Date.now() / 1000) + 86400;\n const nonce = await erc20.nonces(address);\n const value = amountWei;\n\n const domain = {\n name,\n version: \"2\",\n chainId: Number(chainId),\n verifyingContract: tokenAddress\n };\n\n const types = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" }\n ]\n };\n\n const values = {\n owner: address,\n spender: SPENDER,\n value,\n nonce: nonce.toString(),\n deadline\n };\n\n const signature = await (evmWallet as any).signTypedData({\n domain,\n types,\n values\n });\n\n const { v, r, s } = ethers.Signature.from(signature);\n\n const permitParams = {\n amount: value,\n deadline,\n owner: address,\n r,\n s,\n spender: SPENDER,\n token: tokenAddress,\n v,\n nonce: Number(nonce),\n };\n\n return permitParams;\n }\n}\n\nexport const Hyperliquid = new HyperliquidService();\n\nexport const HyperliquidFromTokens = tokens.filter((token) => !(token.chainName === \"Arbitrum\" && token.symbol === \"USDC\"));\nexport const HyperliuquidToToken = DESTINATION_TOKEN;\nexport const HyperliuquidMinAmount = MIN_AMOUNT;\n\nexport interface HyperliquidQuoteParams {\n slippageTolerance: number;\n refundTo: string;\n recipient: string;\n wallet: WalletConfig;\n fromToken: TokenConfig;\n prices: Record<string, string>;\n amountWei: string;\n // Whether to generate deposit address\n // false will generate a deposit address\n dry?: boolean;\n oneclickParams?: {\n appFees?: { recipient: string; fee: number; }[];\n };\n}\n\nexport interface HyperliquidTransferParams {\n // bridge wallet\n wallet: WalletConfig;\n // deposit wallet (evm wallet)\n evmWallet: WalletConfig;\n // deposit wallet address\n evmWalletAddress: string;\n // quote result with deposit address\n quote: any;\n}\n\nexport interface HyperliquidGeneratePermitParams {\n address: string;\n evmWallet: WalletConfig;\n amountWei: string;\n}\n\nexport interface HyperliquidDepositParams extends HyperliquidTransferParams {\n txhash: string;\n}\n\nexport interface HyperliquidGetStatusParams {\n depositId: string;\n}\n\nexport interface HyperliquidResponse<T> {\n code: number;\n data: T;\n}\n\nexport interface HyperliquidDepositResponseData {\n depositId: number;\n}\n\nexport type HyperliquidDepositResponse = HyperliquidResponse<HyperliquidDepositResponseData>;\n\nexport type HyperliquidDepositStatus = \"PROCESSING\" | \"SUCCESS\" | \"REFUNDED\" | \"FAILED\";\n\nexport interface HyperliquidDepositStatusResponseData {\n status: HyperliquidDepositStatus;\n txHash: string;\n}\n\nexport type HyperliquidDepositStatusResponse = HyperliquidResponse<HyperliquidDepositStatusResponseData>;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stableflow/hyperliquid",
|
|
3
|
+
"version": "3.0.0-beta-02a59f37a0-20260515",
|
|
4
|
+
"description": "Hyperliquid helpers for StableFlow SDK",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/stableflow-ai/stableflow-sdk.git",
|
|
9
|
+
"directory": "packages/hyperliquid"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"module": "./dist/index.mjs",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"big.js": "^7.0.1",
|
|
26
|
+
"ethers": "^6.16.0",
|
|
27
|
+
"@stableflow/bridges": "3.0.0-beta-02a59f37a0-20260515",
|
|
28
|
+
"@stableflow/core": "3.0.0-beta-02a59f37a0-20260515"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/big.js": "^6.2.2",
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"clean": "rm -rf dist"
|
|
38
|
+
}
|
|
39
|
+
}
|