Feat/add support for hyperliquid transactions#1
Conversation
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
queue-manager/rango-preset/src/actions/scheduleNextStep.ts (1)
43-53:⚠️ Potential issue | 🟠 MajorRoute resumed Hyperliquid steps to Hyperliquid status checker.
When
currentStep.executedTransactionIdexists, Line 52 always schedulesCHECK_TRANSACTION_STATUS. For Hyperliquid, this should scheduleCHECK_HYPERLIQUID_TRANSACTION_STATUS; otherwise resumed swaps can poll the wrong action path.Suggested fix
- if (currentStep?.executedTransactionId) { - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); + if (currentStep?.executedTransactionId) { + if (currentStep.fromBlockchain === TransactionType.HYPERLIQUID) { + schedule(SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS); + } else { + schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); + } return next(); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@queue-manager/rango-preset/src/actions/scheduleNextStep.ts` around lines 43 - 53, When resuming a step that already has currentStep.executedTransactionId we always schedule SwapActionTypes.CHECK_TRANSACTION_STATUS but must route Hyperliquid transactions to the Hyperliquid status checker; update the branch that handles currentStep.executedTransactionId to check currentStep.fromBlockchain (compare to TransactionType.HYPERLIQUID) and call schedule(SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS) for Hyperliquid, otherwise schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS) so resumed Hyperliquid swaps poll the correct action.
🧹 Nitpick comments (6)
wallets/shared/src/rango.ts (1)
176-176: Add a short rationale comment for this mapping.Line 176 is easy to misinterpret. A one-line note explaining why Hyperliquid signing is intentionally mapped to
Networks.ARBITRUMwould reduce future regressions.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@wallets/shared/src/rango.ts` at line 176, Add a one-line rationale comment above the HYPERLIQUID_SIGN_NETWORK constant explaining why Hyperliquid signing maps to Networks.ARBITRUM (e.g., that Hyperliquid uses Arbitrum-compatible signing or that the Hyperliquid chain is signed using Arbitrum keys) so future readers understand this intentional mapping; update the comment near the HYPERLIQUID_SIGN_NETWORK export to mention the compatibility/intent and any relevant reference (Hyperliquid signing behavior) to prevent accidental change.queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/types.ts (1)
1-5: Tighten typed-data typing to prevent invalid EIP-712 payloads.The current type uses
unknownand looseRecord<string, unknown>patterns, which removes compile-time checks for signing inputs. The proposed refactor below is incomplete—it should useTypedDataDomainfor the domain field (notRecord<string, unknown>) andRecord<string, any>for value, matching ethers v6's actual requirements.Corrected type-tightening
+import type { TypedDataDomain, TypedDataField } from 'ethers'; + +type TypedDataField = { + name: string; + type: string; +}; + export type EthersV6CompatibleTypedData = { - domain: unknown; - types: Record<string, unknown>; - value: Record<string, unknown>; + domain: TypedDataDomain; + types: Record<string, Array<TypedDataField>>; + value: Record<string, any>; };Alternatively, consider reusing the existing
TypedDatatype fromsigners/signer-evm/src/types.ts, which already has the correct shape.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/types.ts` around lines 1 - 5, Update the EthersV6CompatibleTypedData type to tighten EIP-712 typing: replace the loose domain and value shapes by using TypedDataDomain for the domain field and use Record<string, any> for value (or simply reuse the existing TypedData type if available), keeping types as the appropriate record; modify the EthersV6CompatibleTypedData declaration to import and reference TypedDataDomain (or TypedData) and change value to Record<string, any> so signing inputs align with ethers v6 requirements.queue-manager/rango-preset/src/helpers.ts (1)
791-791: Prefer network-based wallet lookup over transaction-type lookup.Using
step.hyperliquidTransaction?.typeas the wallet-map key is brittle. For consistency with other branches, key this via the step network (fromBlockchain) when Hyperliquid tx exists.Refactor sketch
- swap.wallets[step.hyperliquidTransaction?.type || ''] || + (step.hyperliquidTransaction + ? swap.wallets[step.fromBlockchain] + : null) ||🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@queue-manager/rango-preset/src/helpers.ts` at line 791, The lookup currently uses swap.wallets[step.hyperliquidTransaction?.type || ''] which is brittle; change the key to use the network field when a Hyperliquid transaction exists (e.g. step.hyperliquidTransaction?.fromBlockchain) and fall back to the normal step.fromBlockchain or existing fallback used elsewhere; update the expression that references swap.wallets to use step.hyperliquidTransaction?.fromBlockchain || step.fromBlockchain (or the same fallback string used in other branches) so the wallet lookup is network-based instead of transaction-type-based.queue-manager/rango-preset/src/queueDef.ts (1)
35-38: Please add a queue-definition test for the two new action registrations.These keys are orchestration-critical; a focused assertion around
swapQueueDef.actionshelps prevent silent regressions.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@queue-manager/rango-preset/src/queueDef.ts` around lines 35 - 38, Add a unit test that asserts the queue definition registers the two new actions: verify swapQueueDef.actions has keys SwapActionTypes.EXECUTE_HYPERLIQUID_TRANSACTION and SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS and that their values are the expected handlers (executeHyperliquidTransaction and checkHyperliquidTransactionStatus respectively); import swapQueueDef, SwapActionTypes, executeHyperliquidTransaction, and checkHyperliquidTransactionStatus from the module under test and use focused assertions (e.g., hasOwnProperty/has/key and strict equality against the handler functions) so this test will fail if those registrations are removed or renamed.wallets/provider-safepal/src/constants.ts (1)
34-37: Consider centralizing EVM+Hyperliquid chain composition.This merge logic is now repeated across multiple provider constants. A shared helper would reduce drift risk if chain-grouping rules change later.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@wallets/provider-safepal/src/constants.ts` around lines 34 - 37, Multiple provider constants duplicate the same merge logic for EVM + Hyperliquid chains; extract that logic into a single helper (e.g., composeEvmAndHyperliquid or getEvmHyperliquidChains) and replace occurrences of the inline array in getSupportedChains with a call to that helper. The helper should accept the same parameter (allBlockchains: BlockchainMeta[]) and internally call evmBlockchains(allBlockchains) and hyperliquidBlockchain(allBlockchains) to return the combined array; update every provider constant that currently uses getSupportedChains: (allBlockchains) => [...evmBlockchains(allBlockchains), ...hyperliquidBlockchain(allBlockchains)] to instead call the new helper.queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts (1)
83-85: Consider bounded retry/backoff for long-lived transaction pollingCurrent fixed-interval retry is okay for happy path, but adding a cap/backoff here improves resilience under explorer incidents.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts` around lines 83 - 85, The current fixed-interval retry in checkHyperliquidTransactionStatus (using delay(INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS); retry(); return;) should be replaced with a bounded backoff: add a retry counter (e.g., attempts or retryCount) and a MAX_RETRIES constant, compute an increasing delay (exponential backoff with optional jitter using INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS as the base) and call retry() only while attempts < MAX_RETRIES; when max is reached, stop polling and surface/return a failure (or emit a timeout/error) so the caller can handle it. Ensure the new logic updates the retry counter on each loop and uses INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS as the backoff base.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts`:
- Around line 74-79: The warning call in checkHyperliquidTransactionStatus is
logging the full swap object (pendingSwap: swap) which may contain PII; instead,
modify the warn(...) tags to avoid including the entire swap payload—replace
pendingSwap: swap with a minimal identifier such as pendingSwapId: swap.id (or
pendingSwapNonce: swap.nonce) and remove or redact any direct user identifiers
(e.g., walletAddress) in the tags; update the warn(...) invocation so it only
emits non-sensitive fields and keep the same tag keys for traceability.
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.ts`:
- Around line 39-43: The find predicate that computes currentUserDetailsItem
assumes every entry in userDetailsJson.txs has an action and directly accesses
item.action.type/time, which can throw; update the predicate in the function
that uses currentUserDetailsItem to first guard that item and item.action are
present (e.g., check item && item.action or use optional chaining) before
comparing action.type and action.time against 'withdraw3'|'usdSend' and nonce,
and if missing return a typed error/result instead of letting polling crash so
callers can handle malformed explorer items.
- Around line 17-23: The fetch call that assigns userDetailsResponse should use
a timeout via an AbortController (or equivalent) and must check the HTTP status
before parsing: wrap the POST to HYPERLIQUID_EXPLORER_API_URL in a request that
aborts after a configured timeout, call response.ok (or check status) and
throw/return a clear error for non-2xx responses instead of assuming parse
errors, and ensure the calling code (e.g., whichever function in utils.ts that
awaits userDetailsResponse) handles abort/timeouts and non-2xx errors distinctly
so polling won't hang or misclassify failures.
In
`@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.ts`:
- Around line 153-165: The code calls handleErr when
initiateWithdrawalResponse.val.status !== 'ok' but then continues to call
onSuccessfulFinish(), advancing the queue on failure; modify the control flow in
executeHyperliquidTransaction so that after creating and invoking handleErr for
the failed initiation (reference initiateWithdrawalResponse and handleErr) the
function returns or otherwise stops execution (do not call onSuccessfulFinish)
to prevent advancing the queue on error; ensure any necessary cleanup or error
propagation still occurs before the early return.
In
`@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/utils.ts`:
- Around line 89-107: The API call in initiateWithdrawalResponse (to
HYPERLIQUID_EXCHANGE_API_URL) needs a timeout and proper HTTP-status/error
handling: wrap the fetch with an AbortController to enforce a short timeout
(e.g., 3–10s) and abort if exceeded, check initiateWithdrawalResponse.ok after
fetch and if false read the error body (or use status/statusText) and return an
Err result instead of Ok, and wrap the JSON parsing of
initiateWithdrawalResponseJson in a try/catch to handle invalid/non-JSON
responses and return an Err with useful context (including HTTP status or abort
error) — ensure callers still get Ok(...) only for successful 2xx responses.
In `@queue-manager/rango-preset/src/shared.ts`:
- Line 256: The wallet lookup is using the transaction type
(step.hyperliquidTransaction?.type) which is wrong and causes WalletMissing;
change the key to the Hyperliquid network identifier on the transaction (e.g.,
step.hyperliquidTransaction?.network or the appropriate network/chain field on
hyperliquidTransaction) when indexing swap.wallets so swap.wallets[networkKey ||
''] is used instead of swap.wallets[step.hyperliquidTransaction?.type || ''];
update any null/undefined fallback handling to preserve previous behavior and
ensure WalletMissing no longer occurs for valid Hyperliquid steps.
---
Outside diff comments:
In `@queue-manager/rango-preset/src/actions/scheduleNextStep.ts`:
- Around line 43-53: When resuming a step that already has
currentStep.executedTransactionId we always schedule
SwapActionTypes.CHECK_TRANSACTION_STATUS but must route Hyperliquid transactions
to the Hyperliquid status checker; update the branch that handles
currentStep.executedTransactionId to check currentStep.fromBlockchain (compare
to TransactionType.HYPERLIQUID) and call
schedule(SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS) for Hyperliquid,
otherwise schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS) so resumed
Hyperliquid swaps poll the correct action.
---
Nitpick comments:
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts`:
- Around line 83-85: The current fixed-interval retry in
checkHyperliquidTransactionStatus (using
delay(INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS); retry(); return;)
should be replaced with a bounded backoff: add a retry counter (e.g., attempts
or retryCount) and a MAX_RETRIES constant, compute an increasing delay
(exponential backoff with optional jitter using
INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS as the base) and call retry()
only while attempts < MAX_RETRIES; when max is reached, stop polling and
surface/return a failure (or emit a timeout/error) so the caller can handle it.
Ensure the new logic updates the retry counter on each loop and uses
INTERVAL_FOR_CHECK_HYPERLIQUID_TRANSACTION_STATUS as the backoff base.
In
`@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/types.ts`:
- Around line 1-5: Update the EthersV6CompatibleTypedData type to tighten
EIP-712 typing: replace the loose domain and value shapes by using
TypedDataDomain for the domain field and use Record<string, any> for value (or
simply reuse the existing TypedData type if available), keeping types as the
appropriate record; modify the EthersV6CompatibleTypedData declaration to import
and reference TypedDataDomain (or TypedData) and change value to Record<string,
any> so signing inputs align with ethers v6 requirements.
In `@queue-manager/rango-preset/src/helpers.ts`:
- Line 791: The lookup currently uses
swap.wallets[step.hyperliquidTransaction?.type || ''] which is brittle; change
the key to use the network field when a Hyperliquid transaction exists (e.g.
step.hyperliquidTransaction?.fromBlockchain) and fall back to the normal
step.fromBlockchain or existing fallback used elsewhere; update the expression
that references swap.wallets to use step.hyperliquidTransaction?.fromBlockchain
|| step.fromBlockchain (or the same fallback string used in other branches) so
the wallet lookup is network-based instead of transaction-type-based.
In `@queue-manager/rango-preset/src/queueDef.ts`:
- Around line 35-38: Add a unit test that asserts the queue definition registers
the two new actions: verify swapQueueDef.actions has keys
SwapActionTypes.EXECUTE_HYPERLIQUID_TRANSACTION and
SwapActionTypes.CHECK_HYPERLIQUID_TRANSACTION_STATUS and that their values are
the expected handlers (executeHyperliquidTransaction and
checkHyperliquidTransactionStatus respectively); import swapQueueDef,
SwapActionTypes, executeHyperliquidTransaction, and
checkHyperliquidTransactionStatus from the module under test and use focused
assertions (e.g., hasOwnProperty/has/key and strict equality against the handler
functions) so this test will fail if those registrations are removed or renamed.
In `@wallets/provider-safepal/src/constants.ts`:
- Around line 34-37: Multiple provider constants duplicate the same merge logic
for EVM + Hyperliquid chains; extract that logic into a single helper (e.g.,
composeEvmAndHyperliquid or getEvmHyperliquidChains) and replace occurrences of
the inline array in getSupportedChains with a call to that helper. The helper
should accept the same parameter (allBlockchains: BlockchainMeta[]) and
internally call evmBlockchains(allBlockchains) and
hyperliquidBlockchain(allBlockchains) to return the combined array; update every
provider constant that currently uses getSupportedChains: (allBlockchains) =>
[...evmBlockchains(allBlockchains), ...hyperliquidBlockchain(allBlockchains)] to
instead call the new helper.
In `@wallets/shared/src/rango.ts`:
- Line 176: Add a one-line rationale comment above the HYPERLIQUID_SIGN_NETWORK
constant explaining why Hyperliquid signing maps to Networks.ARBITRUM (e.g.,
that Hyperliquid uses Arbitrum-compatible signing or that the Hyperliquid chain
is signed using Arbitrum keys) so future readers understand this intentional
mapping; update the comment near the HYPERLIQUID_SIGN_NETWORK export to mention
the compatibility/intent and any relevant reference (Hyperliquid signing
behavior) to prevent accidental change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: aafe4bc7-5e95-48e3-868f-0c6af53530c8
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (82)
queue-manager/queue-manager-demo/package.jsonqueue-manager/rango-preset/package.jsonqueue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.tsqueue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/constants.tsqueue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/index.tsqueue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/types.tsqueue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.tsqueue-manager/rango-preset/src/actions/executeHyperliquidTransaction/constants.tsqueue-manager/rango-preset/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.tsqueue-manager/rango-preset/src/actions/executeHyperliquidTransaction/index.tsqueue-manager/rango-preset/src/actions/executeHyperliquidTransaction/types.tsqueue-manager/rango-preset/src/actions/executeHyperliquidTransaction/utils.tsqueue-manager/rango-preset/src/actions/scheduleNextStep.tsqueue-manager/rango-preset/src/helpers.tsqueue-manager/rango-preset/src/queueDef.tsqueue-manager/rango-preset/src/shared.tsqueue-manager/rango-preset/src/types.tssigners/signer-cosmos/package.jsonsigners/signer-evm/package.jsonsigners/signer-evm/src/signer.tssigners/signer-evm/src/types.tssigners/signer-solana/package.jsonsigners/signer-starknet/package.jsonsigners/signer-sui/package.jsonsigners/signer-ton/package.jsonsigners/signer-tron/package.jsonwallets/core/package.jsonwallets/core/src/legacy/types.tswallets/provider-binance/package.jsonwallets/provider-bitget/package.jsonwallets/provider-bitget/src/constants.tswallets/provider-braavos/package.jsonwallets/provider-brave/package.jsonwallets/provider-brave/src/constants.tswallets/provider-coin98/package.jsonwallets/provider-coin98/src/constants.tswallets/provider-coinbase/package.jsonwallets/provider-coinbase/src/constants.tswallets/provider-cosmostation/package.jsonwallets/provider-cosmostation/src/constants.tswallets/provider-default/package.jsonwallets/provider-enkrypt/package.jsonwallets/provider-enkrypt/src/constants.tswallets/provider-exodus/package.jsonwallets/provider-keplr/package.jsonwallets/provider-leap-cosmos/package.jsonwallets/provider-ledger/package.jsonwallets/provider-math-wallet/package.jsonwallets/provider-math-wallet/src/constants.tswallets/provider-metamask/package.jsonwallets/provider-metamask/src/constants.tswallets/provider-okx/package.jsonwallets/provider-phantom/package.jsonwallets/provider-rabby/package.jsonwallets/provider-rabby/src/constants.tswallets/provider-ready/package.jsonwallets/provider-safe/package.jsonwallets/provider-safepal/package.jsonwallets/provider-safepal/src/constants.tswallets/provider-slush/package.jsonwallets/provider-solflare/package.jsonwallets/provider-taho/package.jsonwallets/provider-tokenpocket/package.jsonwallets/provider-tokenpocket/src/constants.tswallets/provider-tomo/package.jsonwallets/provider-tomo/src/constants.tswallets/provider-tonconnect/package.jsonwallets/provider-trezor/package.jsonwallets/provider-tron-link/package.jsonwallets/provider-trustwallet/package.jsonwallets/provider-trustwallet/src/constants.tswallets/provider-unisat/package.jsonwallets/provider-walletconnect-2/package.jsonwallets/provider-xdefi/package.jsonwallets/provider-xverse/package.jsonwallets/react/package.jsonwallets/shared/package.jsonwallets/shared/src/rango.tswidget/embedded/package.jsonwidget/embedded/src/utils/wallets.tswidget/playground/package.jsonwidget/ui/package.json
| warn(new Error('check Hyperliquid transaction status Error'), { | ||
| tags: { | ||
| type: 'request-error', | ||
| requestBody: { type: 'userDetails', user: walletAddress, nonce }, | ||
| pendingSwap: swap, | ||
| }, |
There was a problem hiding this comment.
Avoid logging full swap payload in warning tags
Line 78 logs pendingSwap: swap, which can expose user identifiers and transaction metadata in logs.
Proposed fix
warn(new Error('check Hyperliquid transaction status Error'), {
tags: {
type: 'request-error',
- requestBody: { type: 'userDetails', user: walletAddress, nonce },
- pendingSwap: swap,
+ requestType: 'userDetails',
+ nonce,
+ walletAddressSuffix: walletAddress.slice(-6),
},
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/checkHyperliquidTransactionStatus.ts`
around lines 74 - 79, The warning call in checkHyperliquidTransactionStatus is
logging the full swap object (pendingSwap: swap) which may contain PII; instead,
modify the warn(...) tags to avoid including the entire swap payload—replace
pendingSwap: swap with a minimal identifier such as pendingSwapId: swap.id (or
pendingSwapNonce: swap.nonce) and remove or redact any direct user identifiers
(e.g., walletAddress) in the tags; update the warn(...) invocation so it only
emits non-sensitive fields and keep the same tag keys for traceability.
| userDetailsResponse = await fetch(HYPERLIQUID_EXPLORER_API_URL, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ type: 'userDetails', user: walletAddress }), | ||
| }); |
There was a problem hiding this comment.
Add timeout and HTTP status handling to explorer request
Line 17 awaits fetch without timeout, and non-2xx responses are treated like parse issues. This can hang polling or blur failure classification.
Proposed fix
let userDetailsResponse: Response;
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort(), 10_000);
try {
userDetailsResponse = await fetch(HYPERLIQUID_EXPLORER_API_URL, {
method: 'POST',
+ signal: controller.signal,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ type: 'userDetails', user: walletAddress }),
});
+ if (!userDetailsResponse.ok) {
+ return new Err(GetHyperliquidTransactionHashError.FETCH_ERROR);
+ }
} catch {
return new Err(GetHyperliquidTransactionHashError.FETCH_ERROR);
+ } finally {
+ clearTimeout(timeoutId);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.ts`
around lines 17 - 23, The fetch call that assigns userDetailsResponse should use
a timeout via an AbortController (or equivalent) and must check the HTTP status
before parsing: wrap the POST to HYPERLIQUID_EXPLORER_API_URL in a request that
aborts after a configured timeout, call response.ok (or check status) and
throw/return a clear error for non-2xx responses instead of assuming parse
errors, and ensure the calling code (e.g., whichever function in utils.ts that
awaits userDetailsResponse) handles abort/timeouts and non-2xx errors distinctly
so polling won't hang or misclassify failures.
| const currentUserDetailsItem = userDetailsJson.txs.find( | ||
| (item) => | ||
| (item.action.type === 'withdraw3' || item.action.type === 'usdSend') && | ||
| item.action.time === nonce | ||
| ); |
There was a problem hiding this comment.
Guard malformed explorer items before nested property access
Line 41/42 can throw at runtime if any txs entry is missing action. This crashes polling instead of returning a typed error.
Proposed fix
- const currentUserDetailsItem = userDetailsJson.txs.find(
- (item) =>
- (item.action.type === 'withdraw3' || item.action.type === 'usdSend') &&
- item.action.time === nonce
- );
+ const currentUserDetailsItem = userDetailsJson.txs.find((item) => {
+ const action = item?.action;
+ return (
+ (action?.type === 'withdraw3' || action?.type === 'usdSend') &&
+ action?.time === nonce &&
+ typeof item?.hash === 'string'
+ );
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const currentUserDetailsItem = userDetailsJson.txs.find( | |
| (item) => | |
| (item.action.type === 'withdraw3' || item.action.type === 'usdSend') && | |
| item.action.time === nonce | |
| ); | |
| const currentUserDetailsItem = userDetailsJson.txs.find((item) => { | |
| const action = item?.action; | |
| return ( | |
| (action?.type === 'withdraw3' || action?.type === 'usdSend') && | |
| action?.time === nonce && | |
| typeof item?.hash === 'string' | |
| ); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.ts`
around lines 39 - 43, The find predicate that computes currentUserDetailsItem
assumes every entry in userDetailsJson.txs has an action and directly accesses
item.action.type/time, which can throw; update the predicate in the function
that uses currentUserDetailsItem to first guard that item and item.action are
present (e.g., check item && item.action or use optional chaining) before
comparing action.type and action.time against 'withdraw3'|'usdSend' and nonce,
and if missing return a typed error/result instead of letting polling crash so
callers can handle malformed explorer items.
| if (initiateWithdrawalResponse.val.status !== 'ok') { | ||
| handleErr( | ||
| new Err({ | ||
| nextStatus: 'failed', | ||
| nextStepStatus: 'failed', | ||
| message: 'Unexpected Error: Failed to initiate withdrawal.', | ||
| details: undefined, | ||
| errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', | ||
| }) | ||
| ); | ||
| } | ||
|
|
||
| onSuccessfulFinish(); |
There was a problem hiding this comment.
Stop flow after failed withdrawal initiation status
Line 153-163 marks an error, but execution still reaches Line 165 (onSuccessfulFinish()), advancing the queue on failure.
Proposed fix
if (initiateWithdrawalResponse.val.status !== 'ok') {
handleErr(
new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: 'Unexpected Error: Failed to initiate withdrawal.',
details: undefined,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
})
);
+ return;
}
onSuccessfulFinish();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (initiateWithdrawalResponse.val.status !== 'ok') { | |
| handleErr( | |
| new Err({ | |
| nextStatus: 'failed', | |
| nextStepStatus: 'failed', | |
| message: 'Unexpected Error: Failed to initiate withdrawal.', | |
| details: undefined, | |
| errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', | |
| }) | |
| ); | |
| } | |
| onSuccessfulFinish(); | |
| if (initiateWithdrawalResponse.val.status !== 'ok') { | |
| handleErr( | |
| new Err({ | |
| nextStatus: 'failed', | |
| nextStepStatus: 'failed', | |
| message: 'Unexpected Error: Failed to initiate withdrawal.', | |
| details: undefined, | |
| errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', | |
| }) | |
| ); | |
| return; | |
| } | |
| onSuccessfulFinish(); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.ts`
around lines 153 - 165, The code calls handleErr when
initiateWithdrawalResponse.val.status !== 'ok' but then continues to call
onSuccessfulFinish(), advancing the queue on failure; modify the control flow in
executeHyperliquidTransaction so that after creating and invoking handleErr for
the failed initiation (reference initiateWithdrawalResponse and handleErr) the
function returns or otherwise stops execution (do not call onSuccessfulFinish)
to prevent advancing the queue on error; ensure any necessary cleanup or error
propagation still occurs before the early return.
| const initiateWithdrawalResponse = await fetch( | ||
| HYPERLIQUID_EXCHANGE_API_URL, | ||
| { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ | ||
| action, | ||
| signature, | ||
| nonce, | ||
| }), | ||
| } | ||
| ); | ||
|
|
||
| const initiateWithdrawalResponseJson = | ||
| await initiateWithdrawalResponse.json(); | ||
|
|
||
| return Ok(initiateWithdrawalResponseJson); |
There was a problem hiding this comment.
Harden withdrawal API call with timeout and HTTP status check
Line 89 call has no timeout and treats any parseable JSON as success. This weakens failure handling for exchange API outages/error responses.
Proposed fix
export async function initiateWithdrawalRequest(
action: HyperliquidTransaction['action'],
signature: Signature,
nonce: HyperliquidTransaction['nonce']
): Promise<Result<{ status: string }, NextTransactionStateError>> {
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort(), 10_000);
try {
const initiateWithdrawalResponse = await fetch(
HYPERLIQUID_EXCHANGE_API_URL,
{
method: 'POST',
+ signal: controller.signal,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
action,
signature,
nonce,
}),
}
);
+ if (!initiateWithdrawalResponse.ok) {
+ return new Err({
+ nextStatus: 'failed',
+ nextStepStatus: 'failed',
+ message: 'Unexpected Error: Failed to initiate withdrawal.',
+ details: undefined,
+ errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
+ });
+ }
const initiateWithdrawalResponseJson =
await initiateWithdrawalResponse.json();
return Ok(initiateWithdrawalResponseJson);
} catch {
return new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: 'Unexpected Error: Failed to initiate withdrawal.',
details: undefined,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
});
+ } finally {
+ clearTimeout(timeoutId);
}
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/utils.ts`
around lines 89 - 107, The API call in initiateWithdrawalResponse (to
HYPERLIQUID_EXCHANGE_API_URL) needs a timeout and proper HTTP-status/error
handling: wrap the fetch with an AbortController to enforce a short timeout
(e.g., 3–10s) and abort if exceeded, check initiateWithdrawalResponse.ok after
fetch and if false read the error body (or use status/statusText) and return an
Err result instead of Ok, and wrap the JSON parsing of
initiateWithdrawalResponseJson in a try/catch to handle invalid/non-JSON
responses and return an Err with useful context (including HTTP status or abort
error) — ensure callers still get Ok(...) only for successful 2xx responses.
| swap.wallets[step.suiTransaction?.blockChain || ''] || | ||
| swap.wallets[step.xrplTransaction?.blockChain || ''] || | ||
| swap.wallets[step.stellarTransaction?.blockChain || ''] || | ||
| swap.wallets[step.hyperliquidTransaction?.type || ''] || |
There was a problem hiding this comment.
Use Hyperliquid network key (not tx type) for wallet lookup.
On Line 256, wallet resolution uses step.hyperliquidTransaction?.type as the key into swap.wallets. That key is transaction type metadata, not the blockchain/network key, so valid Hyperliquid steps can fail with WalletMissing.
💡 Proposed fix
- swap.wallets[step.hyperliquidTransaction?.type || ''] ||
+ (step.hyperliquidTransaction
+ ? swap.wallets[HYPERLIQUID_SIGN_NETWORK]
+ : null) ||📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| swap.wallets[step.hyperliquidTransaction?.type || ''] || | |
| (step.hyperliquidTransaction | |
| ? swap.wallets[HYPERLIQUID_SIGN_NETWORK] | |
| : null) || |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@queue-manager/rango-preset/src/shared.ts` at line 256, The wallet lookup is
using the transaction type (step.hyperliquidTransaction?.type) which is wrong
and causes WalletMissing; change the key to the Hyperliquid network identifier
on the transaction (e.g., step.hyperliquidTransaction?.network or the
appropriate network/chain field on hyperliquidTransaction) when indexing
swap.wallets so swap.wallets[networkKey || ''] is used instead of
swap.wallets[step.hyperliquidTransaction?.type || '']; update any null/undefined
fallback handling to preserve previous behavior and ensure WalletMissing no
longer occurs for valid Hyperliquid steps.
|
@kody start-review |
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
| swap.wallets[step.tonTransaction?.blockChain || ''] || | ||
| swap.wallets[step.suiTransaction?.blockChain || ''] || | ||
| swap.wallets[step.xrplTransaction?.blockChain || ''] || | ||
| swap.wallets[step.hyperliquidTransaction?.type || ''] || |
There was a problem hiding this comment.
Incorrect property used for Hyperliquid wallet lookup in multiple files. The code incorrectly uses hyperliquidTransaction.type instead of hyperliquidTransaction.blockChain to look up wallets in swap.wallets. Since the wallets map is keyed by blockchain names, this causes wallet lookups to fail for Hyperliquid transactions.
This issue appears in multiple locations:
- queue-manager/rango-preset/src/helpers.ts: Lines 791-791
- queue-manager/rango-preset/src/shared.ts: Lines 256-256
Replace all instances ofhyperliquidTransaction?.typewithhyperliquidTransaction?.blockChainfor wallet lookups to ensure consistent behavior with other transaction types.
swap.wallets[step.hyperliquidTransaction?.blockChain || ''] ||Prompt for LLM
File queue-manager/rango-preset/src/helpers.ts:
Line 791:
In the file `queue-manager/rango-preset/src/helpers.ts`, I've identified a bug in the `isTxAlreadyCreated` function. When checking for a wallet for a `hyperliquidTransaction`, the code uses `step.hyperliquidTransaction.type` as the key for the `swap.wallets` map. This is incorrect because the `wallets` map is keyed by blockchain names (like 'ARBITRUM'), whereas `.type` refers to the transaction's type (like 'HYPERLIQUID'). All other transaction types in this function correctly use the `.blockChain` property for this lookup. This will cause the wallet lookup to fail for Hyperliquid transactions. Please provide a fix that uses the correct property, `blockChain`, for the lookup, consistent with the other transaction types.
Suggested Code:
swap.wallets[step.hyperliquidTransaction?.blockChain || ''] ||
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| let userDetailsJson: UserDetailsResponse; | ||
| try { | ||
| userDetailsJson = await userDetailsResponse.json(); | ||
|
|
||
| if (!Array.isArray(userDetailsJson.txs)) { | ||
| return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR); | ||
| } | ||
| } catch { | ||
| return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR); | ||
| } |
There was a problem hiding this comment.
Avoid unsafe any assignment by validating the API response structure before casting to UserDetailsResponse.
This issue appears in multiple locations:
- queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.ts: Lines 28-37
- queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/utils.ts: Lines 63-70
- signers/signer-evm/src/signer.ts: Lines 163-164
Please fix this Kody Rule violation in all listed locations.
let userDetailsJson: UserDetailsResponse;
try {
const data: unknown = await userDetailsResponse.json();
if (
!data ||
typeof data !== 'object' ||
!('txs' in data) ||
!Array.isArray((data as { txs: unknown }).txs)
) {
return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR);
}
userDetailsJson = data as UserDetailsResponse;
} catch {
return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR);
}Prompt for LLM
File queue-manager/rango-preset/src/actions/checkHyperliquidTransactionStatus/utils.ts:
Line 28 to 37:
I have a piece of TypeScript code that fetches data from an API. It currently assigns the result of `response.json()`, which is of type `any`, directly to a variable that has a specific interface type. This approach is not type-safe and could lead to runtime errors if the API response structure changes.
My project follows a strict rule that disallows the use of the `any` type to maintain type safety. All external data, such as API responses, must be properly validated before being used with a specific type.
Please refactor the code to handle this safely. The solution should first treat the JSON response as `unknown`, then perform runtime checks to validate its structure (e.g., ensure it's an object and contains the expected `txs` array). Only after successful validation should the data be cast to the `UserDetailsResponse` type.
Suggested Code:
let userDetailsJson: UserDetailsResponse;
try {
const data: unknown = await userDetailsResponse.json();
if (
!data ||
typeof data !== 'object' ||
!('txs' in data) ||
!Array.isArray((data as { txs: unknown }).txs)
) {
return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR);
}
userDetailsJson = data as UserDetailsResponse;
} catch {
return new Err(GetHyperliquidTransactionHashError.RESPONSE_PARSING_ERROR);
}
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| if (initiateWithdrawalResponse.val.status !== 'ok') { | ||
| handleErr( | ||
| new Err({ | ||
| nextStatus: 'failed', | ||
| nextStepStatus: 'failed', | ||
| message: 'Unexpected Error: Failed to initiate withdrawal.', | ||
| details: undefined, | ||
| errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', | ||
| }) | ||
| ); | ||
| } | ||
|
|
||
| onSuccessfulFinish(); |
There was a problem hiding this comment.
Logic error causes inconsistent state on failed withdrawal. When initiateWithdrawalRequest returns a non-'ok' status, the code calls handleErr to mark the transaction as failed but then proceeds to call onSuccessfulFinish. This incorrectly advances the queue to the next step for a failed transaction, leading to state corruption. A return statement is missing after handling the error.
if (initiateWithdrawalResponse.val.status !== 'ok') {
handleErr(
new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: 'Unexpected Error: Failed to initiate withdrawal.',
details: undefined,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
})
);
return;
}
onSuccessfulFinish();Prompt for LLM
File queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.ts:
Line 153 to 165:
I have a TypeScript function that handles Hyperliquid transactions within a queue manager. There's a logic error in the error handling. When a withdrawal initiation request succeeds but returns a non-'ok' status, the code correctly calls an error handler (`handleErr`). However, it fails to stop execution and proceeds to call the success handler (`onSuccessfulFinish`). This results in the transaction being marked as failed while also advancing the queue to the next step, causing an inconsistent state. Explain why this is a problem and how to fix it by adding a `return` statement.
Suggested Code:
if (initiateWithdrawalResponse.val.status !== 'ok') {
handleErr(
new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: 'Unexpected Error: Failed to initiate withdrawal.',
details: undefined,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
})
);
return;
}
onSuccessfulFinish();
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| const initiateWithdrawalResponseJson = | ||
| await initiateWithdrawalResponse.json(); | ||
|
|
||
| return Ok(initiateWithdrawalResponseJson); |
There was a problem hiding this comment.
The initiateWithdrawalRequest function does not handle non-successful HTTP responses from the fetch call. If the API returns an error status code (e.g., 4xx or 5xx), the code incorrectly treats the failed request as a success. Additionally, the response JSON is implicitly typed as any, which violates the strict typing rule. The improved code adds proper error handling for failed requests and explicitly types both the error details (unknown) and the successful response to ensure type safety.
if (!initiateWithdrawalResponse.ok) {
let errorDetails: unknown;
try {
errorDetails = await initiateWithdrawalResponse.json();
} catch (e) {
errorDetails = initiateWithdrawalResponse.statusText;
}
return new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: `Failed to initiate withdrawal: ${initiateWithdrawalResponse.status}`,
details: errorDetails,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
});
}
const initiateWithdrawalResponseJson = await initiateWithdrawalResponse.json() as { status: string };
return Ok(initiateWithdrawalResponseJson);Prompt for LLM
File queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/utils.ts:
Line 104 to 107:
I have a function `initiateWithdrawalRequest` in my TypeScript code that makes a `fetch` call. It has two issues. First, it doesn't handle non-successful HTTP responses (like 4xx or 5xx errors) and treats them as successes. Second, it violates our strict typing rules by implicitly using the `any` type for the JSON response. Our rules state that the `any` type must not be used to ensure type safety.
Please modify the function to:
1. Check the `ok` property of the response. If it's not ok, return an `Err` result with error details.
2. For the error details, use the `unknown` type instead of an implicit `any`.
3. For the successful response, ensure the parsed JSON is explicitly typed as `{ status: string }` to match the function's return signature and avoid the `any` type.
Suggested Code:
if (!initiateWithdrawalResponse.ok) {
let errorDetails: unknown;
try {
errorDetails = await initiateWithdrawalResponse.json();
} catch (e) {
errorDetails = initiateWithdrawalResponse.statusText;
}
return new Err({
nextStatus: 'failed',
nextStepStatus: 'failed',
message: `Failed to initiate withdrawal: ${initiateWithdrawalResponse.status}`,
details: errorDetails,
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
});
}
const initiateWithdrawalResponseJson = await initiateWithdrawalResponse.json() as { status: string };
return Ok(initiateWithdrawalResponseJson);
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| async signTypedData(typedData: TypedData): Promise<string> { | ||
| try { | ||
| const signer = await this.provider.getSigner(); | ||
| const signature = await signer.signTypedData( | ||
| typedData.domain, | ||
| typedData.types, | ||
| typedData.value | ||
| ); | ||
|
|
||
| return signature; | ||
| } catch (error) { | ||
| throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); | ||
| } | ||
| } |
There was a problem hiding this comment.
Missing signer validation in the signTypedData method. The method's signature is inconsistent with its usage, which passes the wallet address and chain ID as additional arguments. These arguments are ignored, and unlike signAndSendTx in the same class, the method fails to validate that the active signer's address and chain ID match the required ones. This omission can lead to generating invalid signatures if the user's wallet is on the wrong network or has the wrong account selected. The proposed fix adds this validation and also improves type safety in the catch block by explicitly typing the error as unknown to avoid using an implicit any type.
async signTypedData(
typedData: TypedData,
address: string,
chainId: string | null
): Promise<string> {
try {
const signer = await this.provider.getSigner();
const signerChainId = (await this.provider.getNetwork()).chainId;
const signerAddress = await signer.getAddress();
if (
!!chainId &&
!!signerChainId &&
signerChainId.toString() !== Number(chainId).toString()
) {
throw new SignerError(
SignerErrorCode.UNEXPECTED_BEHAVIOUR,
undefined,
`Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.`
);
}
if (address.toLowerCase() !== signerAddress.toLowerCase()) {
throw new SignerError(
SignerErrorCode.UNEXPECTED_BEHAVIOUR,
undefined,
`Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.`
);
}
const signature = await signer.signTypedData(
typedData.domain,
typedData.types,
typedData.value
);
return signature;
} catch (error: unknown) {
if (error instanceof SignerError) {
throw error;
}
throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error);
}
}Prompt for LLM
File signers/signer-evm/src/signer.ts:
Line 101 to 114:
The provided code introduces a new `signTypedData` method to an EVM signer class. However, its signature and implementation are incorrect. A consumer of this method calls it with three arguments: the typed data object, the expected signer address, and the expected chain ID. The new method only accepts the first argument, ignoring the address and chain ID. Furthermore, another method in the same class, `signAndSendTx`, correctly uses the address and chain ID to validate the signer's state before performing an action. The new `signTypedData` method omits this critical validation.
Refactor the `signTypedData` method to accept all three arguments and include the validation logic for the address and chain ID, mirroring the pattern in `signAndSendTx`, to prevent signing with an incorrect wallet configuration.
Additionally, please ensure the implementation adheres to our strict typing rules. Specifically, the use of the `any` type is disallowed. This means that any error handling, such as in a `try...catch` block, must explicitly type the error as `unknown` (e.g., `catch (error: unknown)`), not leave it as an implicit `any`.
Suggested Code:
async signTypedData(
typedData: TypedData,
address: string,
chainId: string | null
): Promise<string> {
try {
const signer = await this.provider.getSigner();
const signerChainId = (await this.provider.getNetwork()).chainId;
const signerAddress = await signer.getAddress();
if (
!!chainId &&
!!signerChainId &&
signerChainId.toString() !== Number(chainId).toString()
) {
throw new SignerError(
SignerErrorCode.UNEXPECTED_BEHAVIOUR,
undefined,
`Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.`
);
}
if (address.toLowerCase() !== signerAddress.toLowerCase()) {
throw new SignerError(
SignerErrorCode.UNEXPECTED_BEHAVIOUR,
undefined,
`Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.`
);
}
const signature = await signer.signTypedData(
typedData.domain,
typedData.types,
typedData.value
);
return signature;
} catch (error: unknown) {
if (error instanceof SignerError) {
throw error;
}
throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error);
}
}
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| getSupportedChains: (allBlockchains: BlockchainMeta[]) => [ | ||
| ...evmBlockchains(allBlockchains), | ||
| ...hyperliquidBlockchain(allBlockchains), | ||
| ], |
There was a problem hiding this comment.
Duplicate blockchain entry. The function concatenates the results of evmBlockchains and hyperliquidBlockchain. As Hyperliquid is an EVM-compatible chain, it is likely included in the list returned by evmBlockchains. This implementation will create a duplicate Hyperliquid entry in the supported chains list, which can cause downstream logic failures or UI bugs.
getSupportedChains: (allBlockchains: BlockchainMeta[]) => {
const chains = [
...evmBlockchains(allBlockchains),
...hyperliquidBlockchain(allBlockchains),
];
// Assuming `chain.name` is the unique identifier for a blockchain.
return [
...new Map(chains.map((chain) => [chain.name, chain])).values(),
];
},Prompt for LLM
File wallets/provider-rabby/src/constants.ts:
Line 34 to 37:
I have this TypeScript code that is supposed to return a list of supported blockchain networks for a crypto wallet. It combines a list of all EVM chains with the Hyperliquid chain. The problem is that Hyperliquid is an EVM-compatible chain, so it's likely already included in the list from `evmBlockchains()`. The current code just concatenates the two lists using the spread operator, which will result in a duplicate Hyperliquid entry in the final array. This can cause bugs in the UI or other parts of the application. How can I modify this code to combine the two lists while ensuring the final list contains only unique blockchains? Assume each blockchain object in the array has a unique `name` property that can be used for deduplication.
Suggested Code:
getSupportedChains: (allBlockchains: BlockchainMeta[]) => {
const chains = [
...evmBlockchains(allBlockchains),
...hyperliquidBlockchain(allBlockchains),
];
// Assuming `chain.name` is the unique identifier for a blockchain.
return [
...new Map(chains.map((chain) => [chain.name, chain])).values(),
];
},
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
There was a problem hiding this comment.
type of hyperliquid chain in meta is "Hyperliquid" so it will not be returned in the evmBlockchains so I need to do the concatenatrion @kody
Review Summary by QodoAdd comprehensive Hyperliquid transaction support to Rango client
WalkthroughsDescription• Add Hyperliquid transaction execution and status checking actions • Integrate Hyperliquid support into queue manager workflow • Enable EVM signer to support typed data signing for Hyperliquid • Add Hyperliquid blockchain support across multiple wallet providers • Automatically provision Hyperliquid accounts for EVM wallets Diagramflowchart LR
A["Hyperliquid Transaction"] --> B["Execute Hyperliquid Transaction"]
B --> C["Sign Typed Data"]
C --> D["Submit to Exchange API"]
D --> E["Check Transaction Status"]
E --> F["Poll Explorer API"]
F --> G["Transaction Hash"]
H["EVM Wallets"] --> I["Support Hyperliquid"]
I --> J["Auto-provision Accounts"]
File Changes1. queue-manager/rango-preset/src/actions/executeHyperliquidTransaction/executeHyperliquidTransaction.ts
|
This pull request introduces comprehensive support for Hyperliquid transactions within the Rango client.
Key changes include:
signTypedData, which is essential for signing Hyperliquid transactions.These changes enable users to seamlessly perform and track Hyperliquid transactions through the Rango client.