@rango-dev/queue-manager-rango-preset 0.62.1-next.4 → 0.63.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/dist/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.d.ts +4 -0
- package/dist/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.d.ts.map +1 -0
- package/dist/actions/checkHyperliquidTransactionStatus/constants.d.ts +8 -0
- package/dist/actions/checkHyperliquidTransactionStatus/constants.d.ts.map +1 -0
- package/dist/actions/checkHyperliquidTransactionStatus/index.d.ts +2 -0
- package/dist/actions/checkHyperliquidTransactionStatus/index.d.ts.map +1 -0
- package/dist/actions/checkHyperliquidTransactionStatus/types.d.ts +20 -0
- package/dist/actions/checkHyperliquidTransactionStatus/types.d.ts.map +1 -0
- package/dist/actions/checkHyperliquidTransactionStatus/utils.d.ts +4 -0
- package/dist/actions/checkHyperliquidTransactionStatus/utils.d.ts.map +1 -0
- package/dist/actions/checkPrerequisites/checkPrerequisites.d.ts.map +1 -1
- package/dist/actions/common/checkEnvironmentBeforeExecuteTransaction.d.ts.map +1 -1
- package/dist/actions/executeHyperliquidTransaction/constants.d.ts +2 -0
- package/dist/actions/executeHyperliquidTransaction/constants.d.ts.map +1 -0
- package/dist/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.d.ts +5 -0
- package/dist/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.d.ts.map +1 -0
- package/dist/actions/executeHyperliquidTransaction/index.d.ts +3 -0
- package/dist/actions/executeHyperliquidTransaction/index.d.ts.map +1 -0
- package/dist/actions/executeHyperliquidTransaction/types.d.ts +6 -0
- package/dist/actions/executeHyperliquidTransaction/types.d.ts.map +1 -0
- package/dist/actions/executeHyperliquidTransaction/utils.d.ts +21 -0
- package/dist/actions/executeHyperliquidTransaction/utils.d.ts.map +1 -0
- package/dist/helpers.d.ts +10 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/queue-manager-rango-preset.build.json +1 -1
- package/dist/queueDef.d.ts.map +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts +94 -0
- package/src/actions/checkHyperliquidTransactionStatus/constants.ts +10 -0
- package/src/actions/checkHyperliquidTransactionStatus/index.ts +1 -0
- package/src/actions/checkHyperliquidTransactionStatus/types.ts +20 -0
- package/src/actions/checkHyperliquidTransactionStatus/utils.ts +50 -0
- package/src/actions/checkPrerequisites/checkPrerequisites.ts +2 -0
- package/src/actions/common/checkEnvironmentBeforeExecuteTransaction.ts +2 -1
- package/src/actions/executeHyperliquidTransaction/constants.ts +2 -0
- package/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.ts +167 -0
- package/src/actions/executeHyperliquidTransaction/index.ts +2 -0
- package/src/actions/executeHyperliquidTransaction/types.ts +5 -0
- package/src/actions/executeHyperliquidTransaction/utils.ts +155 -0
- package/src/helpers.ts +51 -9
- package/src/queueDef.ts +6 -0
- package/src/shared.ts +8 -1
- package/src/types.ts +2 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { SwapQueueContext, SwapStorage } from '../../types';
|
|
2
|
+
import type { NextTransactionStateError } from '../common/produceNextStateForTransaction';
|
|
3
|
+
import type { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
4
|
+
import type { EvmTransaction } from 'rango-sdk';
|
|
5
|
+
|
|
6
|
+
import { type GenericSigner, TransactionType } from 'rango-types';
|
|
7
|
+
import { Err } from 'ts-results';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getCurrentStep,
|
|
11
|
+
getCurrentStepTx,
|
|
12
|
+
handleRejectedSign,
|
|
13
|
+
} from '../../helpers';
|
|
14
|
+
import { getCurrentAddressOf, getRelatedWallet } from '../../shared';
|
|
15
|
+
import { SwapActionTypes } from '../../types';
|
|
16
|
+
import { checkEnvironmentBeforeExecuteTransaction } from '../common/checkEnvironmentBeforeExecuteTransaction';
|
|
17
|
+
import {
|
|
18
|
+
onNextStateError,
|
|
19
|
+
onNextStateOk,
|
|
20
|
+
produceNextStateForTransaction,
|
|
21
|
+
} from '../common/produceNextStateForTransaction';
|
|
22
|
+
import { requestBlockQueue } from '../common/utils';
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
ensureHyperliquidTransactionIsValid,
|
|
26
|
+
getEthersV6CompatibleTypedDataFromMessage,
|
|
27
|
+
initiateWithdrawalRequest,
|
|
28
|
+
splitSignature,
|
|
29
|
+
} from './utils';
|
|
30
|
+
|
|
31
|
+
export async function executeHyperliquidTransaction(
|
|
32
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
33
|
+
): Promise<void> {
|
|
34
|
+
const checkResult = await checkEnvironmentBeforeExecuteTransaction(actions);
|
|
35
|
+
if (checkResult.err) {
|
|
36
|
+
requestBlockQueue(actions, checkResult.val);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { failed, getStorage, context, schedule, next } = actions;
|
|
41
|
+
const { getSigners } = context;
|
|
42
|
+
|
|
43
|
+
const swap = getStorage().swapDetails;
|
|
44
|
+
const currentStep = getCurrentStep(swap)!;
|
|
45
|
+
|
|
46
|
+
const onFinish = () => {
|
|
47
|
+
if (actions.context.resetClaimedBy) {
|
|
48
|
+
actions.context.resetClaimedBy();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const onSuccessfulFinish = () => {
|
|
53
|
+
schedule(SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS);
|
|
54
|
+
next();
|
|
55
|
+
onFinish();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const handleErr = (err: Err<NextTransactionStateError>) => {
|
|
59
|
+
onNextStateError(actions, err.val);
|
|
60
|
+
failed();
|
|
61
|
+
onFinish();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Checking the current transaction state to determine the next step.
|
|
66
|
+
* It will either be Err, indicating process should stop, or Ok, indicating process should continu.
|
|
67
|
+
*/
|
|
68
|
+
const nextStateResult = produceNextStateForTransaction(actions);
|
|
69
|
+
|
|
70
|
+
if (nextStateResult.err) {
|
|
71
|
+
handleErr(nextStateResult);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// On sucess, we should update Swap object and also call notifier
|
|
76
|
+
onNextStateOk(actions, nextStateResult.val);
|
|
77
|
+
|
|
78
|
+
// when we are producing next step, it will check to tx shouldn't be null. So ! here is safe.
|
|
79
|
+
const currentTransactionFromStorage = getCurrentStepTx(currentStep)!;
|
|
80
|
+
const hyperliquidTransactionResult = ensureHyperliquidTransactionIsValid(
|
|
81
|
+
currentTransactionFromStorage
|
|
82
|
+
);
|
|
83
|
+
if (hyperliquidTransactionResult.err) {
|
|
84
|
+
handleErr(hyperliquidTransactionResult);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const hyperliquidTransaction = hyperliquidTransactionResult.val;
|
|
88
|
+
|
|
89
|
+
const sourceWallet = getRelatedWallet(swap, currentStep);
|
|
90
|
+
const walletAddress = getCurrentAddressOf(swap, currentStep);
|
|
91
|
+
|
|
92
|
+
let signer: GenericSigner<EvmTransaction>;
|
|
93
|
+
try {
|
|
94
|
+
const walletSigners = await getSigners(sourceWallet.walletType);
|
|
95
|
+
signer = walletSigners.getSigner(TransactionType.EVM); // We need EVM signer for Hyperliquid transactions
|
|
96
|
+
} catch (error) {
|
|
97
|
+
handleRejectedSign(actions)(error);
|
|
98
|
+
onFinish();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!signer?.signTypedData) {
|
|
103
|
+
handleErr(
|
|
104
|
+
new Err({
|
|
105
|
+
nextStatus: 'failed',
|
|
106
|
+
nextStepStatus: 'failed',
|
|
107
|
+
message: 'Unexpected Error: Signer does not support signTypedData.',
|
|
108
|
+
details: undefined,
|
|
109
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const typedData = getEthersV6CompatibleTypedDataFromMessage(
|
|
116
|
+
hyperliquidTransaction.message
|
|
117
|
+
);
|
|
118
|
+
if (typedData.err) {
|
|
119
|
+
handleErr(typedData);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let signature: `0x${string}`;
|
|
124
|
+
try {
|
|
125
|
+
signature = (await signer.signTypedData(
|
|
126
|
+
typedData.val,
|
|
127
|
+
walletAddress,
|
|
128
|
+
hyperliquidTransaction.action.signatureChainId
|
|
129
|
+
)) as `0x${string}`;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
handleRejectedSign(actions)(error);
|
|
132
|
+
onFinish();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const splitSignatureResult = splitSignature(signature);
|
|
137
|
+
if (splitSignatureResult.err) {
|
|
138
|
+
handleErr(splitSignatureResult);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const splittedSignature = splitSignatureResult.val;
|
|
142
|
+
|
|
143
|
+
const initiateWithdrawalResponse = await initiateWithdrawalRequest(
|
|
144
|
+
hyperliquidTransaction.action,
|
|
145
|
+
splittedSignature,
|
|
146
|
+
hyperliquidTransaction.nonce
|
|
147
|
+
);
|
|
148
|
+
if (initiateWithdrawalResponse.err) {
|
|
149
|
+
handleErr(initiateWithdrawalResponse);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (initiateWithdrawalResponse.val.status !== 'ok') {
|
|
154
|
+
handleErr(
|
|
155
|
+
new Err({
|
|
156
|
+
nextStatus: 'failed',
|
|
157
|
+
nextStepStatus: 'failed',
|
|
158
|
+
message: 'Unexpected Error: Failed to initiate withdrawal.',
|
|
159
|
+
details: undefined,
|
|
160
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
onSuccessfulFinish();
|
|
167
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
|
2
|
+
import type { EthersV6CompatibleTypedData } from './types';
|
|
3
|
+
import type { NextTransactionStateError } from '../common/produceNextStateForTransaction';
|
|
4
|
+
import type { HyperliquidTransaction, Transaction } from 'rango-sdk';
|
|
5
|
+
import type { Result } from 'ts-results';
|
|
6
|
+
|
|
7
|
+
import { mainAPI } from 'rango-types';
|
|
8
|
+
import { Err, Ok } from 'ts-results';
|
|
9
|
+
|
|
10
|
+
import { HYPERLIQUID_EXCHANGE_API_URL } from './constants';
|
|
11
|
+
|
|
12
|
+
export function ensureHyperliquidTransactionIsValid(
|
|
13
|
+
tx: Transaction | null
|
|
14
|
+
): Result<HyperliquidTransaction, NextTransactionStateError> {
|
|
15
|
+
if (!tx) {
|
|
16
|
+
return new Err({
|
|
17
|
+
nextStatus: 'failed',
|
|
18
|
+
nextStepStatus: 'failed',
|
|
19
|
+
message: 'Unexpected Error: tx is null!',
|
|
20
|
+
details: undefined,
|
|
21
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!mainAPI.isHyperliquidTransaction(tx)) {
|
|
26
|
+
return new Err({
|
|
27
|
+
nextStatus: 'failed',
|
|
28
|
+
nextStepStatus: 'failed',
|
|
29
|
+
message:
|
|
30
|
+
"Unexpected Error: Expected Hyperliquid transaction but it doesn't match with the structure.",
|
|
31
|
+
details: undefined,
|
|
32
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (tx.action.type !== 'withdraw3' && tx.action.type !== 'usdSend') {
|
|
37
|
+
return new Err({
|
|
38
|
+
nextStatus: 'failed',
|
|
39
|
+
nextStepStatus: 'failed',
|
|
40
|
+
message: 'Unexpected Error: Transaction action is not supported.',
|
|
41
|
+
details: undefined,
|
|
42
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!tx.message) {
|
|
47
|
+
return new Err({
|
|
48
|
+
nextStatus: 'failed',
|
|
49
|
+
nextStepStatus: 'failed',
|
|
50
|
+
message: 'Unexpected Error: Transaction message does not exist.',
|
|
51
|
+
details: undefined,
|
|
52
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return Ok(tx);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getEthersV6CompatibleTypedDataFromMessage(
|
|
60
|
+
message: string
|
|
61
|
+
): Result<EthersV6CompatibleTypedData, NextTransactionStateError> {
|
|
62
|
+
try {
|
|
63
|
+
const typedData = JSON.parse(message);
|
|
64
|
+
const ethersV6CompatibleTypedData = {
|
|
65
|
+
domain: typedData.domain,
|
|
66
|
+
types: {
|
|
67
|
+
[typedData.primaryType]: typedData.types[typedData.primaryType],
|
|
68
|
+
},
|
|
69
|
+
value: typedData.message,
|
|
70
|
+
};
|
|
71
|
+
return Ok(ethersV6CompatibleTypedData);
|
|
72
|
+
} catch {
|
|
73
|
+
return new Err({
|
|
74
|
+
nextStatus: 'failed',
|
|
75
|
+
nextStepStatus: 'failed',
|
|
76
|
+
message: 'Unexpected Error: Could not infer typed data from message.',
|
|
77
|
+
details: undefined,
|
|
78
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function initiateWithdrawalRequest(
|
|
84
|
+
action: HyperliquidTransaction['action'],
|
|
85
|
+
signature: Signature,
|
|
86
|
+
nonce: HyperliquidTransaction['nonce']
|
|
87
|
+
): Promise<Result<{ status: string }, NextTransactionStateError>> {
|
|
88
|
+
try {
|
|
89
|
+
const initiateWithdrawalResponse = await fetch(
|
|
90
|
+
HYPERLIQUID_EXCHANGE_API_URL,
|
|
91
|
+
{
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: {
|
|
94
|
+
'Content-Type': 'application/json',
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify({
|
|
97
|
+
action,
|
|
98
|
+
signature,
|
|
99
|
+
nonce,
|
|
100
|
+
}),
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const initiateWithdrawalResponseJson =
|
|
105
|
+
await initiateWithdrawalResponse.json();
|
|
106
|
+
|
|
107
|
+
return Ok(initiateWithdrawalResponseJson);
|
|
108
|
+
} catch {
|
|
109
|
+
return new Err({
|
|
110
|
+
nextStatus: 'failed',
|
|
111
|
+
nextStepStatus: 'failed',
|
|
112
|
+
message: 'Unexpected Error: Failed to initiate withdrawal.',
|
|
113
|
+
details: undefined,
|
|
114
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface Signature {
|
|
120
|
+
/** First 32-byte component of ECDSA signature. */
|
|
121
|
+
r: string;
|
|
122
|
+
/** Second 32-byte component of ECDSA signature. */
|
|
123
|
+
s: string;
|
|
124
|
+
/** Recovery identifier. */
|
|
125
|
+
v: 27 | 28;
|
|
126
|
+
}
|
|
127
|
+
export function splitSignature( // validate and decode a 65-byte 0x… signature into { r, s, v } with v normalized to 27/28 for the Hyperliquid withdrawal request
|
|
128
|
+
signature: `0x${string}`
|
|
129
|
+
): Result<Signature, NextTransactionStateError> {
|
|
130
|
+
if (signature.length !== 132) {
|
|
131
|
+
return new Err({
|
|
132
|
+
nextStatus: 'failed',
|
|
133
|
+
nextStepStatus: 'failed',
|
|
134
|
+
message: `Expected 65-byte signature (132 hex chars), got ${signature.length}`,
|
|
135
|
+
details: undefined,
|
|
136
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const r = `0x${signature.slice(2, 66)}`;
|
|
140
|
+
const s = `0x${signature.slice(66, 130)}`;
|
|
141
|
+
let v = parseInt(signature.slice(130, 132), 16);
|
|
142
|
+
if (v === 0 || v === 1) {
|
|
143
|
+
v += 27;
|
|
144
|
+
}
|
|
145
|
+
if (v !== 27 && v !== 28) {
|
|
146
|
+
return new Err({
|
|
147
|
+
nextStatus: 'failed',
|
|
148
|
+
nextStepStatus: 'failed',
|
|
149
|
+
message: `Invalid signature recovery value: ${v}, expected 27 or 28`,
|
|
150
|
+
details: undefined,
|
|
151
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return Ok({ r, s, v });
|
|
155
|
+
}
|
package/src/helpers.ts
CHANGED
|
@@ -49,6 +49,7 @@ import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/walle
|
|
|
49
49
|
import {
|
|
50
50
|
getBlockChainNameFromId,
|
|
51
51
|
getEvmProvider,
|
|
52
|
+
HYPERLIQUID_SIGN_NETWORK,
|
|
52
53
|
} from '@rango-dev/wallets-shared';
|
|
53
54
|
import BigNumber from 'bignumber.js';
|
|
54
55
|
import {
|
|
@@ -178,6 +179,7 @@ export const getCurrentStepTx = (
|
|
|
178
179
|
tonTransaction,
|
|
179
180
|
suiTransaction,
|
|
180
181
|
xrplTransaction,
|
|
182
|
+
hyperliquidTransaction,
|
|
181
183
|
} = currentStep;
|
|
182
184
|
return (
|
|
183
185
|
evmTransaction ||
|
|
@@ -191,7 +193,8 @@ export const getCurrentStepTx = (
|
|
|
191
193
|
tronTransaction ||
|
|
192
194
|
tonTransaction ||
|
|
193
195
|
suiTransaction ||
|
|
194
|
-
xrplTransaction
|
|
196
|
+
xrplTransaction ||
|
|
197
|
+
hyperliquidTransaction
|
|
195
198
|
);
|
|
196
199
|
};
|
|
197
200
|
|
|
@@ -217,6 +220,7 @@ export const setCurrentStepTx = (
|
|
|
217
220
|
currentStep.suiTransaction = null;
|
|
218
221
|
currentStep.xrplTransaction = null;
|
|
219
222
|
currentStep.stellarTransaction = null;
|
|
223
|
+
currentStep.hyperliquidTransaction = null;
|
|
220
224
|
|
|
221
225
|
const txType = transaction.type;
|
|
222
226
|
switch (txType) {
|
|
@@ -713,6 +717,24 @@ export async function getProviderChainId(
|
|
|
713
717
|
* For running a swap safely, we need to make sure about the state of wallet
|
|
714
718
|
* which means the netowrk/chain of wallet should be exactly on what a transaction needs.
|
|
715
719
|
*/
|
|
720
|
+
/**
|
|
721
|
+
* The EVM chain a wallet must be actively connected to in order to sign the current step.
|
|
722
|
+
*
|
|
723
|
+
* For Hyperliquid the wallet is stored under the "HYPERLIQUID" key, but the action is an
|
|
724
|
+
* EIP-712 message signed with the Arbitrum domain chainId. Many wallets reject
|
|
725
|
+
* `eth_signTypedData_v4` unless their active chain matches that chainId, so the wallet
|
|
726
|
+
* must actually be on Arbitrum (HYPERLIQUID_SIGN_NETWORK) before signing — even though
|
|
727
|
+
* the step's network/storage key is "HYPERLIQUID".
|
|
728
|
+
*/
|
|
729
|
+
export function getRequiredSignNetwork(
|
|
730
|
+
step: PendingSwapStep,
|
|
731
|
+
fallbackNetwork: string
|
|
732
|
+
): string {
|
|
733
|
+
return step.hyperliquidTransaction
|
|
734
|
+
? HYPERLIQUID_SIGN_NETWORK
|
|
735
|
+
: fallbackNetwork;
|
|
736
|
+
}
|
|
737
|
+
|
|
716
738
|
export async function isNetworkMatchedForTransaction(
|
|
717
739
|
swap: PendingSwap,
|
|
718
740
|
step: PendingSwapStep,
|
|
@@ -729,13 +751,17 @@ export async function isNetworkMatchedForTransaction(
|
|
|
729
751
|
return false;
|
|
730
752
|
}
|
|
731
753
|
|
|
754
|
+
// The EVM chain the wallet must actually be on to sign (Arbitrum for Hyperliquid).
|
|
755
|
+
const requiredNetwork = getRequiredSignNetwork(step, fromNamespace.network);
|
|
756
|
+
|
|
732
757
|
if (
|
|
733
758
|
meta.evmBasedChains.find(
|
|
734
|
-
(evmBlochain) => evmBlochain.name ===
|
|
759
|
+
(evmBlochain) => evmBlochain.name === requiredNetwork
|
|
735
760
|
)
|
|
736
761
|
) {
|
|
737
762
|
try {
|
|
738
|
-
|
|
763
|
+
// Resolve via the step-aware key so the Hyperliquid wallet (keyed "HYPERLIQUID") is found.
|
|
764
|
+
const sourceWallet = getRelatedWalletOrNull(swap, step);
|
|
739
765
|
if (sourceWallet) {
|
|
740
766
|
const chainId = await getProviderChainId(
|
|
741
767
|
providers,
|
|
@@ -751,13 +777,13 @@ export async function isNetworkMatchedForTransaction(
|
|
|
751
777
|
);
|
|
752
778
|
if (
|
|
753
779
|
blockChain &&
|
|
754
|
-
blockChain.toLowerCase() ===
|
|
780
|
+
blockChain.toLowerCase() === requiredNetwork.toLowerCase()
|
|
755
781
|
) {
|
|
756
782
|
return true;
|
|
757
783
|
}
|
|
758
784
|
if (
|
|
759
785
|
blockChain &&
|
|
760
|
-
blockChain.toLowerCase() !==
|
|
786
|
+
blockChain.toLowerCase() !== requiredNetwork.toLowerCase()
|
|
761
787
|
) {
|
|
762
788
|
return false;
|
|
763
789
|
}
|
|
@@ -787,6 +813,7 @@ export const isTxAlreadyCreated = (
|
|
|
787
813
|
swap.wallets[step.suiTransaction?.blockChain || ''] ||
|
|
788
814
|
swap.wallets[step.stellarTransaction?.blockChain || ''] ||
|
|
789
815
|
swap.wallets[step.xrplTransaction?.blockChain || ''] ||
|
|
816
|
+
swap.wallets[step.hyperliquidTransaction?.type || ''] ||
|
|
790
817
|
step.transferTransaction?.fromWalletAddress ||
|
|
791
818
|
null;
|
|
792
819
|
|
|
@@ -913,10 +940,14 @@ export function onBlockForChangeNetwork(
|
|
|
913
940
|
setStorage: queue.setStorage.bind(queue),
|
|
914
941
|
});
|
|
915
942
|
|
|
916
|
-
const
|
|
943
|
+
const namespaceNetwork = getCurrentNamespaceOfOrNull(
|
|
917
944
|
swap,
|
|
918
945
|
currentStep
|
|
919
946
|
)?.network;
|
|
947
|
+
// For Hyperliquid the wallet must be switched to Arbitrum, not "HYPERLIQUID".
|
|
948
|
+
const requiredNetwork = currentStep.hyperliquidTransaction
|
|
949
|
+
? HYPERLIQUID_SIGN_NETWORK
|
|
950
|
+
: namespaceNetwork;
|
|
920
951
|
|
|
921
952
|
const requiredWallet = getRequiredWallet(swap).type;
|
|
922
953
|
|
|
@@ -939,9 +970,20 @@ export function onBlockForChangeNetwork(
|
|
|
939
970
|
|
|
940
971
|
// Try to auto switch
|
|
941
972
|
const { type, namespace } = getRequiredWallet(swap);
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
973
|
+
/*
|
|
974
|
+
* For Hyperliquid we must switch the wallet to the signing chain (Arbitrum) rather than
|
|
975
|
+
* the step's "HYPERLIQUID" network, otherwise the wallet rejects signing the
|
|
976
|
+
* Arbitrum-domain EIP-712 message ("chainId should be same as current chainId").
|
|
977
|
+
*/
|
|
978
|
+
const switchNamespace =
|
|
979
|
+
currentStep.hyperliquidTransaction && namespace
|
|
980
|
+
? { ...namespace, network: HYPERLIQUID_SIGN_NETWORK }
|
|
981
|
+
: namespace;
|
|
982
|
+
if (!!type && !!switchNamespace?.network) {
|
|
983
|
+
if (
|
|
984
|
+
context.canSwitchNetworkTo(type, switchNamespace.network, switchNamespace)
|
|
985
|
+
) {
|
|
986
|
+
const result = context.switchNetwork(type, switchNamespace);
|
|
945
987
|
if (result) {
|
|
946
988
|
result
|
|
947
989
|
.then(() => {
|
package/src/queueDef.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { SwapQueueDef } from './types';
|
|
2
2
|
|
|
3
|
+
import { checkHyperliquidTransactionStatus } from './actions/checkHyperliquidTransactionStatus';
|
|
3
4
|
import { checkPrerequisites } from './actions/checkPrerequisites';
|
|
4
5
|
import { checkStatus } from './actions/checkStatus';
|
|
5
6
|
import { checkStellarTrustline } from './actions/checkStellarTrustline';
|
|
6
7
|
import { checkXrplTrustline } from './actions/checkXrplTrustline';
|
|
7
8
|
import { checkXrplTrustLineTransactionStatus } from './actions/checkXrplTrustlineTransactionStatus';
|
|
8
9
|
import { createTransaction } from './actions/createTransaction';
|
|
10
|
+
import { executeHyperliquidTransaction } from './actions/executeHyperliquidTransaction';
|
|
9
11
|
import { executeStellarTransaction } from './actions/executeStellarTransaction';
|
|
10
12
|
import { executeTransaction } from './actions/executeTransaction';
|
|
11
13
|
import { executeXrplTransaction } from './actions/executeXrplTransaction';
|
|
@@ -39,6 +41,10 @@ export const swapQueueDef: SwapQueueDef = {
|
|
|
39
41
|
[SwapActionTypes.EXECUTE_TRANSACTION]: executeTransaction,
|
|
40
42
|
[SwapActionTypes.EXECUTE_XRPL_TRANSACTION]: executeXrplTransaction,
|
|
41
43
|
[SwapActionTypes.EXECUTE_STELLAR_TRANSACTION]: executeStellarTransaction,
|
|
44
|
+
[SwapActionTypes.EXECUTE_HYPERLIQUID_TRANSACTION]:
|
|
45
|
+
executeHyperliquidTransaction,
|
|
46
|
+
[SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS]:
|
|
47
|
+
checkHyperliquidTransactionStatus,
|
|
42
48
|
[SwapActionTypes.CHECK_TRANSACTION_STATUS]: checkStatus,
|
|
43
49
|
},
|
|
44
50
|
run: [SwapActionTypes.START],
|
package/src/shared.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { NamespaceInputForConnect } from '@rango-dev/wallets-core/dist/legacy/types';
|
|
2
1
|
import type { Network, WalletType } from '@rango-dev/wallets-shared';
|
|
3
2
|
import type {
|
|
4
3
|
BlockchainMeta,
|
|
@@ -15,6 +14,7 @@ import type {
|
|
|
15
14
|
WalletTypeAndAddress,
|
|
16
15
|
} from 'rango-types';
|
|
17
16
|
|
|
17
|
+
import { type NamespaceInputForConnect } from '@rango-dev/wallets-core/dist/legacy/types';
|
|
18
18
|
import BigNumber from 'bignumber.js';
|
|
19
19
|
|
|
20
20
|
import { numberToString } from './numbers';
|
|
@@ -119,6 +119,7 @@ export const getCurrentNamespaceOf = (
|
|
|
119
119
|
const suiNetwork = step.suiTransaction?.blockChain;
|
|
120
120
|
const xrplNetwork = step.xrplTransaction?.blockChain;
|
|
121
121
|
const stellarNetwork = step.stellarTransaction?.blockChain;
|
|
122
|
+
const hyperliquidNetwork = step.hyperliquidTransaction?.blockChain;
|
|
122
123
|
|
|
123
124
|
if (evmNetwork) {
|
|
124
125
|
return {
|
|
@@ -160,6 +161,11 @@ export const getCurrentNamespaceOf = (
|
|
|
160
161
|
namespace: 'Stellar',
|
|
161
162
|
network: stellarNetwork,
|
|
162
163
|
};
|
|
164
|
+
} else if (hyperliquidNetwork) {
|
|
165
|
+
return {
|
|
166
|
+
namespace: 'EVM',
|
|
167
|
+
network: hyperliquidNetwork,
|
|
168
|
+
};
|
|
163
169
|
} else if (!!step.transferTransaction) {
|
|
164
170
|
const transferAddress = step.transferTransaction.fromWalletAddress;
|
|
165
171
|
if (!transferAddress) {
|
|
@@ -239,6 +245,7 @@ export const getCurrentWalletTypeAndAddress = (
|
|
|
239
245
|
swap.wallets[step.suiTransaction?.blockChain || ''] ||
|
|
240
246
|
swap.wallets[step.xrplTransaction?.blockChain || ''] ||
|
|
241
247
|
swap.wallets[step.stellarTransaction?.blockChain || ''] ||
|
|
248
|
+
swap.wallets[step.hyperliquidTransaction?.type || ''] ||
|
|
242
249
|
(step.transferTransaction?.fromWalletAddress
|
|
243
250
|
? {
|
|
244
251
|
address: step.transferTransaction.fromWalletAddress,
|
package/src/types.ts
CHANGED
|
@@ -52,7 +52,9 @@ export enum SwapActionTypes {
|
|
|
52
52
|
EXECUTE_TRANSACTION = 'EXECUTE_TRANSACTION',
|
|
53
53
|
EXECUTE_XRPL_TRANSACTION = 'EXECUTE_XRPL_TRANSACTION',
|
|
54
54
|
EXECUTE_STELLAR_TRANSACTION = 'EXECUTE_STELLAR_TRANSACTION',
|
|
55
|
+
EXECUTE_HYPERLIQUID_TRANSACTION = 'EXECUTE_HYPERLIQUID_TRANSACTION',
|
|
55
56
|
|
|
57
|
+
CHECK_HYPERLIQUID_TRANSACTION_STATUS = 'CHECK_HYPERLIQUID_TRANSACTION_STATUS',
|
|
56
58
|
CHECK_TRANSACTION_STATUS = 'CHECK_TRANSACTION_STATUS',
|
|
57
59
|
}
|
|
58
60
|
|