feat: massalabs network#741
Conversation
|
💼 Build Files |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (3)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds end-to-end Massa support: new Massa signer package and massa-web3 dependency, MassaProvider and API, MassaNetwork configs, UI routes/components (send/verify/token management), types, keyring/signers wiring, activity handlers, crypto utilities, tests, and multiple dependency/tooling updates. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant SendUI as "SendTransaction (Massa UI)"
participant KeyRing as "KeyRing / MassaSigner"
participant BG as "Background (MassaProvider)"
participant API as "MassaAPI"
participant Node as "Massa Node (RPC)"
User->>SendUI: confirm transaction
SendUI->>API: api().getMinimalFee() / getAllTokenInfo()
SendUI->>KeyRing: request signature (MassaTransactionSigner)
KeyRing-->>SendUI: signed payload
SendUI->>BG: background request to submit signed operation
BG->>API: submit operation (sendOperations / RPC)
API->>Node: RPC submit
Node-->>API: operationId / status
API-->>BG: result
BG-->>SendUI: response / notification
SendUI->>User: display operationId / activity
sequenceDiagram
autonumber
participant Dapp as "dApp"
participant BG as "Background"
participant Prov as "MassaProvider"
participant API as "MassaAPI"
Dapp->>BG: JSON-RPC massa_getBalance(address)
BG->>Prov: middleware chain -> massa_getBalance
Prov->>API: api().getBalance(address)
API-->>Prov: balance
Prov-->>BG: result
BG-->>Dapp: balance response
Dapp->>BG: JSON-RPC massa_setNetwork(target)
BG->>Prov: middleware chain -> massa_setNetwork
Prov->>Prov: setRequestProvider(newNetwork)
Prov-->>BG: { success: true, network }
BG-->>Dapp: response
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Pre-merge checks (3 passed)✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 21
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/extension/src/types/provider.ts (1)
141-152: Add Massa to Provider type unions and exportsYou added enums and MassaRawInfo, but Provider (the union) and the named exports don’t include the Massa injected provider. This will hinder typing for consumers and any cross-network abstractions expecting Provider to cover all supported networks.
Apply these changes (outside the modified lines):
@@ -import type { InjectedProvider as KadenaProvider } from '@/providers/kadena/types'; +import type { InjectedProvider as KadenaProvider } from '@/providers/kadena/types'; import type { InjectedProvider as SolanaProvider } from '@/providers/solana/types'; +import type { InjectedProvider as MassaProvider } from '@/providers/massa/types'; @@ export { EthereumProvider, PolkadotProvider, BitcoinProvider, KadenaProvider, SolanaProvider, + MassaProvider, }; @@ export type Provider = | EthereumProvider | PolkadotProvider | BitcoinProvider | KadenaProvider - | SolanaProvider; + | SolanaProvider + | MassaProvider;If Massa currently doesn’t expose an InjectedProvider type, define and export it from '@/providers/massa/types' for consistency with other providers.
packages/extension/src/ui/action/views/network-activity/index.vue (1)
235-238: Unconditional clearInterval can stop polling for still-pending activities (affects Massa, Polkadot, etc.)If an activity is still pending (e.g., Polkadot subInfo.pending), the interval is cleared anyway. Gate the clear with terminal statuses only.
Apply this diff:
- // If we're this far in then the transaction has reached a terminal status - // No longer need to check this activity - clearInterval(timer); + // Stop polling only when a terminal status is reached + if ( + activity.status === ActivityStatus.success || + activity.status === ActivityStatus.failed || + activity.status === ActivityStatus.dropped + ) { + clearInterval(timer); + }
🧹 Nitpick comments (43)
packages/signers/massa/tsconfig.json (1)
3-17: Set rootDir to stabilize emit paths and avoid mis-inferenceWithout rootDir, tsc infers it from all included files. Explicitly setting "rootDir": "src" prevents accidental inclusion of tests or editor folders from affecting emit structure.
Apply this diff:
"compilerOptions": { "lib": ["ESNext", "dom"], "moduleResolution": "node", "noUnusedLocals": true, "noUnusedParameters": true, "removeComments": true, "sourceMap": true, "target": "es2015", "module": "commonjs", "outDir": "dist", + "rootDir": "src", "resolveJsonModule": true, "esModuleInterop": true, "declaration": true, "downlevelIteration": true },packages/types/package.json (1)
27-27: Remove unused@massalabs/massa-web3devDependency from the types packageNo imports of
@massalabs/massa-web3were found underpackages/types/src, and keeping a caret‐range here duplicates the extension’s pinned version and risks skew down the line.• packages/types/package.json (lines 26–28):
- "devDependencies": { - "@massalabs/massa-web3": "^5.2.1-dev", - "@types/node": "^22.16.5", + "devDependencies": { + "@types/node": "^22.16.5",packages/extension/src/libs/tokens-state/types.ts (1)
24-27: Massa token address type is fine; consider runtime validation and clearer token standard namingThe template literal type for AS-prefixed addresses is helpful, but it’s not sufficient for correctness (doesn’t validate base58 length/charset). Ensure add-token flows perform runtime validation for Massa contract addresses using a trusted utility (e.g., from massa-web3) before persisting state.
Additionally, since these are MRC20 contracts, consider introducing TokenType.MRC20 and/or renaming to CustomMrc20Token for clarity. Not blocking, but it will future-proof conditional logic that diverges from ERC20.
I can add a lightweight validator in the add-token path and, if desired, refactor TokenType to include MRC20 while preserving backward compatibility. Want me to draft that patch?
packages/extension/src/types/activity.ts (1)
9-9: Use a type-only import to avoid bundling massa-web3 at runtimePrevents unnecessary runtime dependency inclusion by the bundler.
-import { OperationStatus } from '@massalabs/massa-web3'; +import type { OperationStatus } from '@massalabs/massa-web3';packages/extension/src/providers/massa/methods/massa_getNetwork.ts (1)
12-19: Avoid defaulting to mainnet on errors; return the actual error or current networkDefaulting to NetworkNames.Massa can misreport the active network (e.g., Buildnet). Prefer returning the actual current network or surfacing the error.
- if (payload.method !== 'massa_getNetwork') return next(); - else { - try { - res(null, this.network.name); - } catch (error) { - res(null, NetworkNames.Massa); - } - } + if (payload.method !== 'massa_getNetwork') return next(); + try { + return res(null, this.network.name); + } catch (error) { + return res(error as any); + }packages/extension/src/providers/massa/libs/activity-handlers/massa.ts (1)
10-21: Local-activity passthrough is fine; consider deterministic orderingReturning persisted activities is a good first step. Consider sorting by timestamp desc to keep UI stable across loads.
Example:
return activities.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));packages/extension/src/providers/massa/ui/send-transaction/components/send-token-select.vue (4)
2-2: Prefer button semantics for clickability (accessibility).Using an anchor purely for click handling is suboptimal for a11y. Use a button or add role and keyboard handlers.
Apply:
- <a class="send-token-select" @click="emit('update:toggleTokenSelect')"> + <button type="button" class="send-token-select" @click="emit('update:toggleTokenSelect')"> ... - </a> + </button>
4-5: Guard against undefined token.icon to avoid broken image requests.When token.icon is undefined, the browser will attempt to load "undefined". Add a conditional and a fallback.
- <img :src="token.icon" alt="" /> + <img v-if="token.icon" :src="token.icon" :alt="token.symbol || token.name || 'token icon'" /> + <div v-else class="send-token-select__image--placeholder" aria-hidden="true"></div>
49-57: Duplicate CSS property.box-sizing is set twice; remove the duplicate.
box-sizing: border-box; - border: 1px solid @gray02; - box-sizing: border-box; + border: 1px solid @gray02;
26-28: Event name suggests v-model usage but is used as a plain toggle.update:toggleTokenSelect reads like a v-model event. Consider renaming to toggle:tokenSelect or toggleTokenSelect for clarity and consistency.
packages/extension/src/providers/massa/types/index.ts (1)
9-15: Make chainId required to avoid non-null assertions downstream.chainId is used with a non-null assertion in signing (OperationManager.canonicalize). Making it required at the type level prevents runtime surprises.
-export interface MassaNetworkOptions extends BaseNetworkOptions { - chainId?: (typeof CHAIN_ID)[keyof typeof CHAIN_ID]; +export interface MassaNetworkOptions extends BaseNetworkOptions { + chainId: (typeof CHAIN_ID)[keyof typeof CHAIN_ID];If some networks legitimately lack chainId, add a guard at the call site instead.
packages/signers/massa/src/libs/ed25519.ts (2)
50-61: Path handling silently hardens all segments; either enforce apostrophes or reflect them.Ed25519 derivation only supports hardened steps. Your current implementation adds HARDENED_OFFSET to all segments regardless of apostrophes, which can surprise callers. Prefer one of:
- Enforce that all segments are hardened (contain a trailing apostrophe) and reject otherwise, or
- Keep current behavior but document it and tighten validation.
Option A (enforce hardened segments):
-const isValidPath = (path: string): boolean => { - if (!/^m(\/[0-9]+('?))*$/.test(path)) { +const isValidPath = (path: string): boolean => { + if (!/^m(\/[0-9]+'?)*$/.test(path)) { return false; } - return !path - .split("/") - .slice(1) - .map(replaceDerive) - .some(isNaN as any); + const segments = path.split("/").slice(1); + // Require apostrophes on all segments when present + if (segments.length && segments.some(s => !s.endsWith("'"))) return false; + return !segments.map(replaceDerive).some(isNaN as any); }Option B (document behavior): add a brief comment to derivePath stating all segments are treated as hardened irrespective of apostrophes.
41-48: Public key derivation is correct; defaulting to a 0x00 prefix is unconventional.Many consumers expect a 32-byte ed25519 public key. Default withZeroByte = true alters length to 33 bytes. If this is for compatibility with downstream tooling, all good; otherwise consider defaulting to false.
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue (2)
47-51: Use Clipboard API instead of deprecated execCommand('paste').document.execCommand('paste') is deprecated and requires special permissions. Prefer navigator.clipboard with fallback.
-const pasteFromClipboard = () => { - addressInput.value?.focus(); - document.execCommand('paste'); -}; +const pasteFromClipboard = async () => { + try { + addressInput.value?.focus(); + if (navigator.clipboard?.readText) { + const text = await navigator.clipboard.readText(); + emit('update:inputAddress', text); + } else { + console.warn('Clipboard API not available'); + } + } catch (e) { + console.error('Clipboard read failed:', e); + } +};
27-28: Replace inline color logic with a CSS class for consistency with theming.Inline styles bypass theme tokens and can hurt readability. Toggle a class instead.
- :style="{ - color: massaAddress && !isValidMassaAddress ? 'red' : 'black', - }" + :class="{ 'send-address-input__address--invalid': massaAddress && !isValidMassaAddress }"Add style:
.send-address-input__address--invalid { color: @error; // or appropriate theme token }packages/extension/src/providers/massa/ui/libs/signer.ts (3)
96-107: Harden JSON parsing and result handling from messenger.If result isn’t JSON or is empty, JSON.parse will throw. Use a safe parse and normalize the signature.
- const signature = JSON.parse(res.result as string) || ''; + let signature = ''; + try { + signature = JSON.parse(res.result as string) || ''; + } catch { + signature = (res.result as string) || ''; + }
17-32: Type network as MassaNetworkOptions to remove casts.You’re casting network later; make it explicit in the options interface to improve safety.
export interface MassaTransactionOptions { account: EnkryptAccount; - network: BaseNetwork; + network: BaseNetwork & MassaNetworkOptions;
68-75: Validate hex payload for smart contract calls.hexToBuffer('') or non-hex strings may throw. Add a simple guard or normalize 0x prefix.
- parameter: hexToBuffer(payload.data ?? ''), + parameter: payload.data ? hexToBuffer(payload.data) : Buffer.alloc(0),packages/keyring/src/utils.ts (1)
17-19: Add unit tests for ed25519mas path parsingThe new
SignerType.ed25519masbranch inpathParserhas no existing test coverage—let’s add tests to guard against regressions. For example, verify that given abasePathof"m/44'/632'"and indexes0,1,2, etc., the outputs are:
- index 0 →
"m/44'/632'/0'/0'"- index 1 →
"m/44'/632'/1'/0'"- index 2 →
"m/44'/632'/2'/0'"Please add corresponding unit tests in the
packages/keyring/src/utils.test.ts(or similar) targeting:
- The
ed25519mascase inpathParser(basePath, index, type)- Edge conditions (e.g., negative indexes, very large indexes) if applicable
packages/extension/src/providers/massa/libs/activity-handlers/index.ts (1)
1-3: Minor: simplify re-export to a one-liner.Functionally equivalent and a bit tidier.
Apply this diff:
-import MassaActivity from './massa'; - -export { MassaActivity }; +export { default as MassaActivity } from './massa';packages/extension/src/providers/massa/methods/index.ts (1)
7-19: Tiny polish: avoid unused param warning and name the placeholder middleware.
- Rename the unused
providerparam to_providerto satisfy linters.- Give the placeholder middleware a name for easier debugging in stacks.
Apply this diff:
-export default ( - provider: BackgroundProviderInterface, -): MiddlewareFunction[] => { +export default ( + _provider: BackgroundProviderInterface, +): MiddlewareFunction[] => { return [ massa_getBalance, massa_getNetwork, massa_setNetwork, - async (request, response, next) => { - // Add any additional Massa-specific middleware logic here - return next(); - }, + async function massaExtraMiddleware(request, response, next) { + // Add any additional Massa-specific middleware logic here + return next(); + }, ]; };packages/extension/src/providers/massa/networks/mainnet.ts (1)
5-14: Optional: Set an explicit CoinGecko platform only if supportedgetAllTokenInfo in massa-base uses this.coingeckoPlatform for custom token market data. If createMassaNetworkOptions doesn’t set it (or CoinGecko doesn’t recognize Massa as a platform by contract), custom tokens’ market data calls may fail. If unsupported, it's fine to skip; otherwise, consider passing a valid coingeckoPlatform here.
packages/extension/src/ui/action/App.vue (1)
201-226: Add Massa buy link via network options for consistency (optional)Hardcoding the Massa buy URL works, but other networks pull from network.options.buyLink. Using options keeps this centralized and easier to change.
Apply this diff to prefer a network-provided link while keeping your fallback:
case NetworkNames.SyscoinNEVMTest: case NetworkNames.RolluxTest: return (currentNetwork.value as EvmNetwork).options.buyLink; - case NetworkNames.Massa: - return 'https://www.massa.net/get-mas'; + case NetworkNames.Massa: + return (currentNetwork.value as any).options?.buyLink ?? 'https://www.massa.net/get-mas';packages/signers/massa/tests/sign.test.ts (2)
28-38: Sign/verify happy path looks solidUsing blake2 for a msg hash is fine for this unit test and validates the signer API.
Add a negative test where the message hash differs (same signature, different msgHash) to ensure verify rejects altered payloads, complementing the “all zeros” signature case.
16-26: Confirmed: SLIP-0044 coin type 632 and “AU” prefixBoth assumptions are correct:
- SLIP-0044 assigns Massa coin type 632.
- Externally owned Massa addresses are serialized with the “AU” prefix.
• Optional improvement: add a canonical test vector (mnemonic + derivation path → full expected address) and assert the exact address to catch any future regressions, rather than only checking the prefix.
packages/signers/massa/package.json (3)
8-15: Add an explicit exports map and mark package as side-effect freeImproves Node/bundler interop (Esm/Cjs) and enables tree-shaking. Using publishConfig to override fields on publish is good; extend it to include exports. Also mark as sideEffects: false.
Apply this diff:
"module": "src/index.ts", "publishConfig": { "main": "dist/index.cjs", "module": "dist/index.js", - "types": "dist/index.d.ts" + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + } + } }, + "sideEffects": false,Also applies to: 24-31
17-20: Ensure artifacts are built before publishWithout a prepublish step, you risk publishing an empty dist. Add prepublishOnly (or prepare) to guarantee builds on publish.
"scripts": { "build": "tsup src/index.ts --format esm,cjs --dts --clean", "lint": "prettier --write .", - "test": "vitest run" + "test": "vitest run", + "prepublishOnly": "pnpm run build" },
21-23: Modernize Node engine, pin massa-web3 prerelease, remove unused types, and correct repository URL
- Removed unused
@types/hdkey(no references found inpackages/signers/massa).- Confirmed
@massalabs/massa-web3is imported insrc/index.ts; changed from caret-pinned prerelease to an exact5.2.1-dev.- Recommended bumping the Node engine from
>=14.15.0to>=18for alignment with current LTS and ESM ecosystem (TS 5.8.3/ESLint 9.27.0 support ≥14; please verify no regressions).- Updated
repositorymetadata to point at the root Git URL and added thedirectoryfield.Relevant file: packages/signers/massa/package.json
Proposed diff:
"engines": { - "node": ">=14.15.0" + "node": ">=18" }, "dependencies": { - "@massalabs/massa-web3": "^5.2.1-dev", + "@massalabs/massa-web3": "5.2.1-dev", }, "devDependencies": { - "@types/hdkey": "^2.1.0", }, "repository": { "type": "git", - "url": "git+https://github.com/enkryptcom/enKrypt/tree/main/packages/signers/massa" + "url": "git+https://github.com/enkryptcom/enKrypt.git", + "directory": "packages/signers/massa" }packages/extension/src/providers/massa/methods/massa_getBalance.ts (2)
3-3: Remove unused importAddress is not used in this middleware.
-import { Address } from '@massalabs/massa-web3';
17-21: Stricter input validation for address parameterEnsure the param is a string before validation to avoid accidental truthy non-strings.
- const address = payload.params?.[0]; + const address = payload.params?.[0]; const network = this.network as MassaNetwork; - if (!address || !network.isValidAddress(address)) { + if (typeof address !== 'string' || !network.isValidAddress(address)) { res(getCustomError('Please enter a valid Massa address')); return; }packages/extension/src/providers/massa/methods/massa_setNetwork.ts (1)
16-37: Simplify network lookup and handle case-insensitive names (optional)You can lookup directly and avoid building a keys array; also optionally accept case-insensitive names.
- const networkName = payload.params?.[0]; - - if (!networkName) { + const networkName = payload.params?.[0]; + if (!networkName || typeof networkName !== 'string') { res(getCustomError('Network name is required')); return; } - - // Check if the network exists - const availableNetworks = Object.keys(massaNetworks); - - if (!availableNetworks.includes(networkName)) { - res( - getCustomError( - `Invalid network name. Available networks: ${availableNetworks.join(', ')}`, - ), - ); - return; - } - - // Get the network object - const network = massaNetworks[networkName as keyof typeof massaNetworks]; + const key = (networkName in massaNetworks) + ? (networkName as keyof typeof massaNetworks) + : (Object.keys(massaNetworks).find(k => k.toLowerCase() === networkName.toLowerCase()) as keyof typeof massaNetworks | undefined); + const network = key ? massaNetworks[key] : undefined; + if (!network) { + res(getCustomError(`Invalid network name. Available networks: ${Object.keys(massaNetworks).join(', ')}`)); + return; + }packages/extension/src/ui/action/views/network-assets/index.vue (2)
62-69: Guard against undefined address when opening “Add custom token” modalThe address prop uses a non-null assertion. If the button is triggered before accountInfo is populated, this can pass undefined at runtime. Guard in v-if and drop the non-null assertion.
Apply this diff:
- <custom-evm-token v-if="showAddCustomTokens && isEvmNetwork" :address="props.accountInfo.selectedAccount?.address!" + <custom-evm-token v-if="showAddCustomTokens && isEvmNetwork && !!props.accountInfo.selectedAccount?.address" :address="props.accountInfo.selectedAccount?.address" :network="(props.network as EvmNetwork)" @update:token-added="addCustomAsset" @update:close="toggleShowAddCustomTokens"></custom-evm-token> @@ - <custom-massa-token v-if="showAddCustomTokens && isMassaNetwork" :address="props.accountInfo.selectedAccount?.address!" - :network="props.network" @update:token-added="addCustomAsset" + <custom-massa-token v-if="showAddCustomTokens && isMassaNetwork && !!props.accountInfo.selectedAccount?.address" :address="props.accountInfo.selectedAccount?.address" + :network="props.network" @update:token-added="addCustomAsset" @update:close="toggleShowAddCustomTokens"></custom-massa-token>
155-162: Solid, explicit network gating for UI branchesThe computed checks for EVM and Massa via ProviderName are straightforward and readable. Consider centralizing provider-type checks in a small helper if you find similar patterns repeated across views, but no change is required here.
packages/extension/src/types/base-network.ts (1)
11-11: Unify import path style for MassaAPIAll other provider APIs use the
@alias. Recommend switching to@/providers/massa/libs/apifor consistency.-import MassaAPI from '../providers/massa/libs/api'; +import MassaAPI from '@/providers/massa/libs/api';packages/extension/src/providers/massa/libs/api.ts (3)
27-31: Harden balance lookup with error handlingIf the node is unreachable or responds unexpectedly, this can throw and bubble up into UI. Consider catching errors and returning '0' (consistent with other getters’ defensive behavior).
async getBalance(address: string): Promise<string> { - const [account] = await this.provider.balanceOf([address], false); - if (!account) return '0'; - return account.balance.toString(); + try { + const [account] = await this.provider.balanceOf([address], false); + if (!account) return '0'; + return account.balance.toString(); + } catch (_e) { + return '0'; + } }
33-37: Wrap token balance lookup to avoid leaking provider errorsSame rationale as native balance; fallback to '0' if the contract call fails or the contract address is invalid.
async getBalanceMRC20(address: string, contract: string): Promise<string> { - const mrc20 = new MRC20(this.provider, contract); - const balance = await mrc20.balanceOf(address); - return balance.toString(); + try { + const mrc20 = new MRC20(this.provider, contract); + const balance = await mrc20.balanceOf(address); + return balance.toString(); + } catch (_e) { + return '0'; + } }
39-47: Reasonable default minimal fee on failureGraceful fallback to a sensible minimal fee is good; consider exposing the fallback as a constant to centralize fee policy later.
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue (2)
15-21: Render error paragraph only when there’s an errorCurrently an empty red line shows when there’s no error. Gate it on
errorMsg.- <p + <p + v-if="errorMsg" class="verify-transaction__description" style="color: red" :class="{ popup: isPopup }" > {{ errorMsg }} </p>
167-174: Avoid relying on symbol to detect native transfersSymbols can be user-facing and change; prefer an explicit flag on the token (e.g.,
isNative) or a branch on provider/network metadata.packages/extension/src/providers/massa/networks/massa-base.ts (1)
71-79: Unify sparkline encoding across native and token assets (consistency)Native MAS uses JSON.stringify of the last 25 points; custom tokens use Sparkline.dataValues. Consider standardizing to one format to keep the UI consumer logic simple.
If Sparkline is the standard across the app, you can do:
- // Convert sparkline data to string format expected by UI - sparklineData = JSON.stringify( - marketInfo.sparkline_in_24h.price.slice(-25), - ); // Last 25 points + sparklineData = new Sparkline( + marketInfo.sparkline_in_24h.price, + 25, + ).dataValues;packages/extension/src/ui/action/views/network-assets/components/custom-massa-token.vue (2)
19-24: Avoid marking the field invalid when it’s emptyCurrently the field shows invalid state on empty value. Make it invalid only when non-empty and failing validation.
- :class="{ invalid: !isValidAddress }" + :class="{ invalid: contractAddress && !isValidAddress }"
255-257: Debounce contract lookups to reduce RPC chatter (optional)fetchTokenInfo runs on every keystroke. Debounce to prevent unnecessary RPC calls.
You can replace the watcher with a debounced one (no extra deps):
// outside: let timer: number | undefined; let timer: number | undefined; watch(contractAddress, () => { if (timer) window.clearTimeout(timer); timer = window.setTimeout(fetchTokenInfo, 300); });packages/extension/src/providers/massa/index.ts (1)
78-81: More robust error serialization (optional)Ensure a meaningful message even when e is not a standard Error.
- return { - error: JSON.stringify(e.message), - }; + return { + error: JSON.stringify(e?.message || String(e)), + };
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (51)
packages/extension/package.json(1 hunks)packages/extension/src/libs/background/index.ts(1 hunks)packages/extension/src/libs/background/types.ts(3 hunks)packages/extension/src/libs/tokens-state/index.ts(2 hunks)packages/extension/src/libs/tokens-state/types.ts(1 hunks)packages/extension/src/libs/utils/initialize-wallet.ts(3 hunks)packages/extension/src/libs/utils/networks.ts(4 hunks)packages/extension/src/providers/index.ts(2 hunks)packages/extension/src/providers/massa/index.ts(1 hunks)packages/extension/src/providers/massa/libs/activity-handlers/index.ts(1 hunks)packages/extension/src/providers/massa/libs/activity-handlers/massa.ts(1 hunks)packages/extension/src/providers/massa/libs/api.ts(1 hunks)packages/extension/src/providers/massa/methods/index.ts(1 hunks)packages/extension/src/providers/massa/methods/massa_getBalance.ts(1 hunks)packages/extension/src/providers/massa/methods/massa_getNetwork.ts(1 hunks)packages/extension/src/providers/massa/methods/massa_setNetwork.ts(1 hunks)packages/extension/src/providers/massa/networks/buildnet.ts(1 hunks)packages/extension/src/providers/massa/networks/index.ts(1 hunks)packages/extension/src/providers/massa/networks/mainnet.ts(1 hunks)packages/extension/src/providers/massa/networks/massa-base.ts(1 hunks)packages/extension/src/providers/massa/types/index.ts(1 hunks)packages/extension/src/providers/massa/ui/index.ts(1 hunks)packages/extension/src/providers/massa/ui/libs/signer.ts(1 hunks)packages/extension/src/providers/massa/ui/routes/index.ts(1 hunks)packages/extension/src/providers/massa/ui/routes/names.ts(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/components/send-token-select.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue(1 hunks)packages/extension/src/types/activity.ts(4 hunks)packages/extension/src/types/base-network.ts(3 hunks)packages/extension/src/types/provider.ts(4 hunks)packages/extension/src/ui/action/App.vue(2 hunks)packages/extension/src/ui/action/views/network-activity/index.vue(3 hunks)packages/extension/src/ui/action/views/network-assets/components/custom-massa-token.vue(1 hunks)packages/extension/src/ui/action/views/network-assets/index.vue(3 hunks)packages/extension/src/ui/action/views/send-transaction/index.vue(2 hunks)packages/extension/src/ui/action/views/verify-transaction/index.vue(2 hunks)packages/extension/src/ui/provider-pages/routes.ts(2 hunks)packages/keyring/package.json(1 hunks)packages/keyring/src/index.ts(2 hunks)packages/keyring/src/utils.ts(1 hunks)packages/signers/massa/package.json(1 hunks)packages/signers/massa/src/index.ts(1 hunks)packages/signers/massa/src/libs/ed25519.ts(1 hunks)packages/signers/massa/tests/sign.test.ts(1 hunks)packages/signers/massa/tsconfig.json(1 hunks)packages/signers/massa/tsconfig.paths.json(1 hunks)packages/types/package.json(1 hunks)packages/types/src/index.ts(1 hunks)packages/types/src/networks.ts(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (23)
packages/extension/src/providers/massa/methods/index.ts (1)
packages/extension/src/providers/massa/index.ts (1)
request(70-83)
packages/extension/src/providers/index.ts (1)
packages/extension/src/providers/massa/index.ts (1)
MassaProvider(18-92)
packages/extension/src/providers/massa/methods/massa_getNetwork.ts (2)
packages/extension/src/providers/massa/index.ts (1)
MassaProvider(18-92)packages/extension/src/types/provider.ts (1)
ProviderRPCRequest(185-187)
packages/signers/massa/tests/sign.test.ts (2)
packages/utils/src/index.ts (1)
bufferToHex(38-38)packages/signers/massa/src/index.ts (1)
MassaSigner(17-65)
packages/extension/src/providers/massa/networks/mainnet.ts (1)
packages/extension/src/providers/massa/networks/massa-base.ts (1)
MassaNetwork(26-250)
packages/extension/src/providers/massa/methods/massa_getBalance.ts (5)
packages/extension/src/providers/massa/index.ts (1)
MassaProvider(18-92)packages/extension/src/types/provider.ts (1)
ProviderRPCRequest(185-187)packages/extension/src/providers/massa/networks/massa-base.ts (1)
MassaNetwork(26-250)packages/extension/src/libs/error/index.ts (1)
getCustomError(27-33)packages/extension/src/providers/massa/libs/api.ts (1)
api(21-23)
packages/signers/massa/src/libs/ed25519.ts (2)
packages/signers/massa/src/index.ts (1)
sign(60-64)packages/keyring/src/index.ts (1)
sign(201-227)
packages/extension/src/types/base-network.ts (1)
packages/extension/src/providers/massa/libs/api.ts (1)
MassaAPI(9-60)
packages/extension/src/providers/massa/networks/buildnet.ts (1)
packages/extension/src/providers/massa/networks/massa-base.ts (1)
MassaNetwork(26-250)
packages/keyring/src/utils.ts (1)
packages/keyring/src/index.ts (1)
basePath(106-111)
packages/extension/src/libs/background/types.ts (1)
packages/extension/src/providers/massa/index.ts (1)
MassaProvider(18-92)
packages/extension/src/providers/massa/ui/index.ts (1)
packages/extension/src/types/provider.ts (1)
UIExportOptions(189-192)
packages/extension/src/providers/massa/index.ts (2)
packages/types/src/index.ts (1)
MiddlewareFunction(194-194)packages/extension/src/types/provider.ts (1)
ProviderRPCRequest(185-187)
packages/extension/src/providers/massa/types/index.ts (1)
packages/extension/src/types/base-network.ts (1)
BaseNetworkOptions(17-45)
packages/extension/src/providers/massa/methods/massa_setNetwork.ts (4)
packages/types/src/index.ts (1)
MiddlewareFunction(194-194)packages/extension/src/providers/massa/index.ts (1)
MassaProvider(18-92)packages/extension/src/types/provider.ts (1)
ProviderRPCRequest(185-187)packages/extension/src/libs/error/index.ts (1)
getCustomError(27-33)
packages/extension/src/providers/massa/networks/massa-base.ts (3)
packages/extension/src/providers/massa/types/index.ts (1)
MassaNetworkOptions(9-15)packages/extension/src/providers/massa/libs/api.ts (2)
api(21-23)MassaAPI(9-60)packages/extension/src/libs/tokens-state/types.ts (1)
CustomMassaToken(24-26)
packages/extension/src/providers/massa/ui/libs/signer.ts (3)
packages/utils/src/index.ts (2)
hexToBuffer(39-39)bufferToHex(38-38)packages/extension/src/providers/massa/types/index.ts (1)
MassaNetworkOptions(9-15)packages/extension/src/libs/backup-state/index.ts (1)
msgHash(36-51)
packages/keyring/src/index.ts (1)
packages/signers/massa/src/index.ts (1)
MassaSigner(17-65)
packages/extension/src/libs/utils/initialize-wallet.ts (2)
packages/extension/src/libs/utils/accounts.ts (1)
getAccountsByNetworkName(14-44)packages/extension/src/providers/massa/types/index.ts (1)
MassaNetworks(7-7)
packages/extension/src/libs/utils/networks.ts (3)
packages/extension/src/providers/bitcoin/types/index.ts (1)
BitcoinNetworks(5-9)packages/extension/src/providers/kadena/types/index.ts (1)
KadenaNetworks(4-7)packages/extension/src/providers/massa/types/index.ts (1)
MassaNetworks(7-7)
packages/extension/src/types/provider.ts (1)
packages/extension/src/types/activity.ts (1)
MassaRawInfo(150-150)
packages/signers/massa/src/index.ts (3)
packages/types/src/index.ts (3)
SignerInterface(187-187)MnemonicWithExtraWord(205-205)KeyPair(191-191)packages/utils/src/index.ts (2)
bufferToHex(38-38)hexToBuffer(39-39)packages/signers/massa/src/libs/ed25519.ts (1)
derivePath(81-81)
packages/extension/src/libs/tokens-state/index.ts (1)
packages/extension/src/libs/tokens-state/types.ts (1)
CustomMassaToken(24-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: buildAll
- GitHub Check: test
🔇 Additional comments (61)
packages/signers/massa/tsconfig.paths.json (1)
2-7: LGTM: simple, scoped alias for local sourcesThe @src/* → src/* mapping is clean and avoids deep relative paths. No issues spotted.
packages/signers/massa/tsconfig.json (1)
1-29:⚠️ Missing TypeScript Dependency Prevents Local Type-CheckingThe
tsconfig.jsoninpackages/signers/massais well-configured, butnpx tsc -p packages/signers/massa/tsconfig.json --noEmitfailed because the TypeScript compiler isn’t installed. To enable the final type-coverage check:• In packages/signers/massa/package.json, add TypeScript as a devDependency:
npm install --save-dev typescript• Re-run the check:
npx tsc -p packages/signers/massa/tsconfig.json --noEmitEnsure no type errors remain.
packages/keyring/package.json (1)
28-28: LGTM: correct workspace dependency for Massa signerAdding "@enkryptcom/signer-massa" as a workspace dep is the right move to wire the new signer into keyring.
packages/types/src/index.ts (1)
53-54: ed25519mas coverage verified
All occurrences of the new SignerType.ed25519mas have been wired through the codebase—no unsupported “not supported” paths remain:• packages/types/src/index.ts – enum entry added
• packages/extension/src/providers/massa/networks/massa-base.ts – network’s signerType mapping
• packages/keyring/src/index.ts – signer dispatch tableNo switch-on-SignerType statements (e.g. in PolkadotSigner) need ed25519mas support, and no other mappings omit it.
packages/types/src/networks.ts (2)
115-116: All downstream Massa network mappings verified
All occurrences of NetworkNames.Massa and NetworkNames.MassaBuildnet are present and correctly wired—no missing references.• providers/massa/networks/index.ts: both Massa and MassaBuildnet entries mapped
• src/libs/utils/networks.ts: DEFAULT_MASSA_NETWORK_NAME and network list include Massa
• initialize-wallet.ts: handles NetworkNames.Massa
• UI (App.vue): case for NetworkNames.Massa with correct buyLink
• providers/index.ts & background types: ProviderName.massa and MassaProvider imported
186-186: Verify CoinGecko platform slug "massa" and add fallback
- File: packages/types/src/networks.ts, line 186 (
Massa = "massa",)- Query CoinGecko’s
/asset_platformsendpoint (e.g. via pycoingecko or a direct HTTP call) to confirm that"massa"appears in the returned list.- In your price-fetcher logic, guard against unrecognized platform slugs and provide a safe fallback (e.g. default network, skip pricing, or surface a clear error).
packages/extension/src/types/activity.ts (3)
95-96: Typedef alias reads well
MassaRawInfo = OperationStatuskeeps types lean and matches how other chains are modeled.
151-151: Export looks goodPublicly exposing MassaRawInfo is consistent with the rest of the file.
134-136: Confirmed handling of MassaRawInfo in all UI branchesVerified that every conditional in
packages/extension/src/ui/action/views/network-activity/index.vue
now includes the Massa case (lines 228–233), settingactivity.rawInfo = massaInfoand updating status. The union in
packages/extension/src/types/activity.ts
already includesMassaRawInfo. No missing branches or serializers found. Approving changes.packages/extension/src/libs/tokens-state/index.ts (1)
9-10: Importing CustomMassaToken is fineNo issues with the widened types import.
packages/extension/src/providers/massa/methods/massa_getNetwork.ts (1)
1-5: Middleware scaffolding and types are correctShape matches the provider’s middleware pattern and uses the MassaProvider context correctly.
packages/extension/src/providers/massa/ui/send-transaction/components/send-token-select.vue (1)
39-43: Confirm default decimals = 9 is correct for all Massa assets displayed here.Hardcoding 9 as fallback may misrepresent balances for non-native assets. If this component can be used for tokens with different decimals, consider making decimals required or passing network/token defaults explicitly.
Would you like me to update this to prefer token.decimals and otherwise fall back to a provided network.decimals prop?
packages/extension/src/providers/massa/types/index.ts (3)
7-7: Re-exporting MassaNetworks looks good.
17-22: Fee info shape is pragmatic.String-based values for fiat/native amounts are suitable for UI. No issues.
24-31: VerifyTransactionParams aligns with the UI flow.Looks consistent with the verify screen’s needs.
packages/signers/massa/src/libs/ed25519.ts (2)
26-39: CKDPriv implementation matches SLIP-0010 hardened derivation.
1-3: Ensure Node crypto is available in all targets.createHmac from "crypto" may not be polyfilled in browser builds (many bundlers dropped auto-polyfills). Confirm the build for the extension bundles a crypto shim or this runs only in Node-like contexts.
If needed, I can provide a minimal refactor to use a HMAC-SHA512 implementation that works in browsers (e.g., SubtleCrypto + a fallback).
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue (1)
106-113: Confirm identicon() supports placeholder input.Passing a 64-char zero string to identicon() may not be accepted by all implementations. If it expects a valid address, consider a local placeholder asset instead.
I can wire a lightweight SVG placeholder if needed.
packages/extension/src/providers/index.ts (1)
6-6: Massa provider is correctly wired into the providers mapImport and map entry look consistent with existing providers. The default export pattern remains unchanged and should integrate seamlessly with BackgroundHandler via Providers.
Also applies to: 15-15
packages/extension/src/ui/action/views/send-transaction/index.vue (1)
15-15: Cannot locate Massa send-transaction component for prop inspectionI wasn’t able to find
send-transaction/index.vueunderpackages/extension/src/providers/massa/ui. Please verify:
- The component exists at
packages/extension/src/providers/massa/ui/send-transaction/index.vue- It defines the
accountInfoandnetworkprops (viadefinePropsorprops)- Its API matches other providers’ send-transaction components (e.g. Ethereum, Solana)
packages/extension/src/ui/provider-pages/routes.ts (1)
9-9: Massa UI routes export verified
- packages/extension/src/providers/massa/ui/index.ts default export includes a
routesproperty viagetRoutes(ProviderName.massa).- packages/extension/src/providers/massa/ui/routes/index.ts exports a function that returns a
RouteRecordRaw[].This matches the pattern of other providers—no further changes required.
packages/extension/src/libs/background/types.ts (3)
6-6: Massa provider wired into background typings. LGTM.The import looks correct and aligns with the provider’s default export.
8-17: TabProviderType updated to include Massa instances.Union extension is consistent with existing providers; no issues spotted.
19-27: ProviderType includes Massa constructor.Assuming MassaProvider is a class (constructor) default export (as in providers/massa/index.ts), this is correct. If the export ever changes to a factory or plain object, this would need to be revisited.
Please confirm that providers/index.ts (or equivalent registry) maps ProviderName.massa to MassaProvider so these types reflect actual runtime registration.
packages/extension/src/libs/utils/initialize-wallet.ts (2)
27-29: Account discovery for Massa integrated correctly.Fetching and filtering Massa accounts mirrors the pattern used for other networks.
7-7: Import path looks right; ensure it aligns with the networks export.No action needed if the default export from
@/providers/massa/networksmatches the usage above.packages/extension/src/providers/massa/ui/index.ts (1)
1-9: UI export for Massa is correct.providerName and routes wiring align with the established UIExportOptions pattern.
packages/extension/src/providers/massa/networks/mainnet.ts (2)
8-9: Explorer templates look correct for Massa mainnetoperation hash and address templates use the expected placeholders [[txHash]]/[[address]]. Looks consistent with BaseNetwork conventions.
5-14: Types are correct for MassaNetworkOptionsThe
createMassaNetworkOptionshelper expectschainIdto be a bigint andnodeto be a string.
CHAIN_ID.Mainnetis typed asbigint.PublicApiUrl.Mainnetis astring.No mismatches found—no changes required.
packages/extension/src/providers/massa/networks/index.ts (1)
5-8: LGTM: Network map wiring is correctMassa mainnet/buildnet are correctly exposed under NetworkNames.Massa and NetworkNames.MassaBuildnet.
packages/extension/src/types/provider.ts (3)
26-27: MassaRawInfo union addition is goodIncluding MassaRawInfo in activity raw info unions keeps network activity UI/types coherent.
36-37: New provider name addedProviderName.massa addition aligns with new network.
73-74: New provider type addedProviderType.massa addition is consistent with existing patterns.
packages/extension/src/providers/massa/networks/buildnet.ts (2)
8-11: Explorer templates for Buildnet look finemassexplo.com with network=buildnet parameters should work for test network activity/address deep links.
5-15: Confirm Buildnet network option typesPlease verify in packages/extension/src/providers/massa/networks/buildnet.ts (lines 5–15) that:
node: PublicApiUrl.Buildnetis a stringchainId: CHAIN_ID.Buildnetis a bigintIf either value’s type doesn’t match the
createMassaNetworkOptionssignature, cast or convert it (e.g.BigInt(...)or.toString()) before passing intocreateMassaNetworkOptions.packages/extension/src/libs/utils/networks.ts (6)
16-18: Wiring Massa into network registries is correctDefault import of MassaNetworks and mainnet anchor follows existing patterns used for other providers.
20-27: Provider map extended with MassaAdding [ProviderName.massa]: MassaNetworks completes provider → networks mapping.
36-42: Include Massa networks in getAllNetworksThe concatenation order is fine; Massa networks will now be discoverable in generic listings.
75-83: Default network name/object for Massa addedDefaults mirror other providers. No issues spotted.
84-95: POPULAR_NAMES updatedAdding NetworkNames.Massa is reasonable to surface it in UI quick picks.
96-113: Export surface updatedDEFAULT_MASSA_NETWORK and DEFAULT_MASSA_NETWORK_NAME exported alongside others — consistent and helpful for consumers.
packages/keyring/src/index.ts (1)
22-22: Verification Complete: Massa signer wiring is correctly implementedAll end-to-end checks passed:
- SignerType enum includes
ed25519mas(packages/types/src/index.ts:53).pathParserhandlesSignerType.ed25519maswith the correct hardened path (packages/keyring/src/utils.ts:17–19).@enkryptcom/signer-massais declared in keyring’s package.json (packages/keyring/package.json:28).- Registration in
KeyRingmapsSignerType.ed25519mastonew MassaSigner()(packages/keyring/src/index.ts:55–56).packages/extension/src/ui/action/App.vue (1)
320-338: Preserve previously selected address if still valid — good improvementUsing DomainState.getSelectedAddress and falling back to the first active account is the right UX.
Edge case to double-check: networks where activeAccounts is empty. If this can happen, guard selectedAccount access elsewhere (e.g., places using selectedAccount!.address) to avoid runtime errors.
packages/extension/src/ui/action/views/verify-transaction/index.vue (1)
11-11: Massa verify flow is correctly registeredImport and mapping under ProviderName.massa are consistent with other providers.
Also applies to: 23-24
packages/extension/src/providers/massa/ui/routes/names.ts (1)
3-14: LGTM: minimal and consistent route wiringsend and verify routes follow the existing provider pattern with lazy-loaded components and provider-scoped names. Looks good.
packages/extension/src/ui/action/views/network-activity/index.vue (1)
71-73: Incorrect comparison concern—ignoreAfter checking the code:
type MassaRawInfo = OperationStatus;getTransactionStatusfor Massa returns anOperationStatus(not an object).- In
index.vue,info as MassaRawInfois itself the enum value, so comparinginfo === OperationStatus.Xis correct.Feel free to disregard the original comment.
Likely an incorrect or invalid review comment.
packages/extension/src/providers/massa/methods/massa_getBalance.ts (1)
24-30: LGTM: error-handled, delegated RPC with network-validated addressThe middleware pattern is consistent with others: guards method, validates input, delegates to network API, and wraps errors in a provider-friendly format.
packages/extension/src/providers/massa/methods/massa_setNetwork.ts (1)
39-45: LGTM: provider swap with requestProvider handoff is correctSwitching networks via setRequestProvider aligns with the provider’s design and returns a concise result object.
packages/extension/src/types/base-network.ts (1)
37-44: Type unions updated correctly to include MassaAPIVerified across the codebase that
BaseNetwork.apinow includesPromise<MassaAPI>.- The only explicit cast to
MassaAPIis incustom-massa-token.vue(line 165).- All other
await network.api()calls remain narrowed to their respective API types (EvmAPI, SubstrateAPI, BitcoinAPI, KadenaAPI, SolanaAPI).If you intend to support Massa in any conditional/switch over
networkType, be sure to:
- Add a
NetworkType.Massabranch (e.g., inswap/libs/send-transactions.tsaround lines 80–87, 174–181, 483–487).- Narrow the resulting API to
MassaAPIbefore invoking its methods.No other changes are required at this time.
packages/signers/massa/src/index.ts (3)
29-37: Private key construction matches Massa formatPrefixing 32-byte ed25519 seed with version byte (0) to produce a 33-byte Massa PrivateKey is correct; deriving PublicKey and Address from it is also correct.
60-64: sign() returns encoded signature string as expectedReturning the string form aligns with Massa web3 types and pairs with the verify() fix above.
22-27: Validate derivation path input & confirm seed formatIn packages/signers/massa/src/index.ts (lines 22–27):
- Ensure
derivationPathis never empty. Either:
• throw a clear error if it’s missing, e.g.• or apply a project-wide default (for example,if (!derivationPath) { throw new Error('Invalid derivationPath: must not be empty'); }"m/44'/1022'/0'/0'/0'").- Confirm the imported
derivePathimplementation (likely fromed25519-hd-keyor similar) accepts a hex seed string with a0xprefix. If it does not, strip the prefix before calling it:const normalizedSeed = seed.startsWith('0x') ? seed.slice(2) : seed; const keys = derivePath(derivationPath, normalizedSeed);Please verify both points are covered before merging.
packages/extension/src/providers/massa/libs/api.ts (2)
13-19: Provider initialization is straightforwardConstructing the JSON-RPC provider from RPC URL is idiomatic for massa-web3. No issues here.
49-59: Transaction and node status methods LGTMReturning null on failure for operation status and direct node status passthrough both look fine.
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue (5)
183-192: Confirm unit handling for amount in native MAS transfers
amount: txData.toToken.amountimplies base units. Ensure upstream always provides base units here. If not guaranteed, use a conversion similar to fee:toBase(displayValue, decimals).
203-215: MRC20 coins for balance creation: good UX considerationUsing
StorageCost.MRC20BalanceCreationCostto pre-fund storage for recipients without balances is a nice touch. Ensure this returns"0"for recipients who already hold the token to avoid overpaying.If you want, I can add a small unit to stub provider responses and assert the payload’s
coinsvalue varies (0 vs non-0) based on prior balance.
224-231: Sending operation payload looks correctPassing serialized operation bytes, base58 public key, and encoded signature matches massa-web3 expectations. Combined with the verify fix in the signer, this should interoperate cleanly.
260-276: Storing activity for both parties is a good touchDual activity entries (sender and receiver) improve UX. Ensure background indexer updates the pending status to final when operation is included.
137-139: Ensure Buffer polyfill availabilityIt looks like
Buffer.from(..., 'base64')is used here without any explicitimport { Buffer } from 'buffer'in the extension code, so you’re relying on a global Buffer. Please verify that your bundler or extension build config injects a Buffer polyfill in all contexts—otherwise these base64-to-UTF8 decodes will break in environments whereBufferisn’t defined.As an alternative, you can use native browser APIs for a zero-polyfill solution:
const binary = atob(route.query.txData as string); const uint8 = Uint8Array.from(binary, c => c.charCodeAt(0)); const decoded = new TextDecoder().decode(uint8); const txData: VerifyTransactionParams = JSON.parse(decoded);Locations to review:
- packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue (lines 137–139)
- Similar
Buffer.from(..., 'base64')calls in other providers (kadena, polkadot, ethereum, solana, bitcoin) and swap/decode librariespackages/extension/src/providers/massa/index.ts (1)
30-46: Could you show the surrounding context of the Massa provider’s constructor (e.g. the first ~100 lines ofpackages/extension/src/providers/massa/index.ts)? I want to confirm how and whennetwork.nodegets applied there before suggesting any changes.packages/extension/src/providers/massa/ui/send-transaction/index.vue (1)
250-268: Balance/fee math relies on unit consistency (re-verify after the above fix)After normalizing accountBalance to human units, hasEnoughBalance correctly converts to base with toBase. This will fix false positives/negatives on insufficient balance.
You don’t need code changes here beyond the previous comment, but please re-test:
- MAS send: amount + fee <= balance
- Token send: amount <= token balance and MAS balance >= fee
fix massa signature verify
devop: massa: migrate crypto to local
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (27)
packages/extension/configs/vitest.config.mts (1)
23-24: Consider broadening test globs (optional).
If you add UI tests, patterns like .tsx/.mts won’t match. Consider including them to avoid silent skips.Apply if needed:
- include: ['src/**/*.{test,spec}.ts', 'tests/**/*.{test,spec}.ts'], + include: [ + 'src/**/*.{test,spec}.{ts,tsx,mts}', + 'tests/**/*.{test,spec}.{ts,tsx,mts}' + ],packages/signers/massa/package.json (5)
8-12: Provide proper conditional exports for ESM/CJS and typesRelying on non-standard "module" risks resolver quirks. Add exports (applies only on publish via publishConfig).
Apply:
"publishConfig": { "main": "dist/index.cjs", "module": "dist/index.js", - "types": "dist/index.d.ts" + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + } + } },
16-20: Ensure build artifacts exist before publishWithout a prepublish step, publishing could ship an empty dist if CI didn’t build.
Apply:
"scripts": { "build": "tsup src/index.ts --format esm,cjs --dts --clean", "lint": "prettier --write .", - "test": "vitest run" + "test": "vitest run", + "prepublishOnly": "npm run build" },
5-7: Dev vs publish entrypoints: consider adding root types and sideEffectsMain/module pointing to TS source is fine in-workspace, but add root "types" for editor DX and declare sideEffects for better treeshaking.
Apply:
"type": "module", "main": "src/index.ts", "module": "src/index.ts", + "types": "src/index.ts", @@ "files": [ "dist" ], + "sideEffects": false,Also applies to: 13-15
55-58: Fix repository URL and set monorepo directoryNPM expects the git remote URL; include "directory" for correct links.
Apply:
"repository": { "type": "git", - "url": "git+https://github.com/enkryptcom/enKrypt/tree/main/packages/signers/massa" + "url": "git+https://github.com/enkryptcom/enKrypt.git", + "directory": "packages/signers/massa" },
34-38: Node types vs engines: consider aligningUsing @types/node@22 with engines ≥18 is okay but can cause minor lib mismatch. Either bump engines to ≥20 or downgrade types to match the supported baseline.
Would you prefer engines ">=20.11.0" to match Node 20 LTS used in many repos?
Also applies to: 21-23
packages/signers/massa/src/crypto/interfaces/sealer.ts (1)
3-6: Tighten Sealer types; avoid any and align with implementation.
PasswordSealreturns/consumesUint8Array. The interface should reflect that for type safety.export default interface Sealer { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - seal(data: Uint8Array): Promise<any> - // eslint-disable-next-line @typescript-eslint/no-explicit-any - unseal(data: any): Promise<Uint8Array> + seal(data: Uint8Array): Promise<Uint8Array> + unseal(data: Uint8Array): Promise<Uint8Array> }packages/signers/massa/src/crypto/passwordSeal.ts (1)
51-51: Typo: PBKDF2 acronym.Fix docstrings “PKDF2” → “PBKDF2”.
- * Seals data using password-based PKDF2 AES-256-GCM encryption. + * Seals data using password-based PBKDF2 AES-256-GCM encryption. - * Unseals data using password-based PKDF2 AES-256-GCM decryption. + * Unseals data using password-based PBKDF2 AES-256-GCM decryption.Also applies to: 64-64
packages/signers/massa/src/crypto/cross-browser.ts (1)
1-218: Optional: add minimal runtime guards for browser crypto availability.You already throw on missing Web Crypto in PBKDF2; mirroring that in AES paths would make failures clearer.
packages/signers/massa/src/crypto/interfaces/signer.ts (1)
2-11: Clarify hashing responsibility in the contract.Specify whether sign/verify expect raw message bytes or a pre-hashed digest (e.g., Blake3). This avoids double-hashing or interop breaks across providers.
packages/signers/massa/src/libs/ed25519.ts (1)
53-69: Confirm hardened-only semantics.derivePath adds HARDENED_OFFSET unconditionally, so even m/0/1 becomes hardened-hardened. If you want apostrophes to matter, either reject non-hardened segments for ed25519 or only add offset when a segment ends with "'".
Optional change (reject non-hardened):
- const segments = path - .split("/") - .slice(1) - .map(replaceDerive) - .map((el) => parseInt(el, 10)); - - return segments.reduce( - (parentKeys, segment) => CKDPriv(parentKeys, segment + offset), - { key, chainCode }, - ); + const raw = path.split("/").slice(1) + if (raw.some((s) => !s.endsWith("'"))) { + throw new Error("Non-hardened derivation is not supported for ed25519") + } + const segments = raw.map((s) => parseInt(replaceDerive(s), 10)) + return segments.reduce((p, seg) => CKDPriv(p, seg + offset), { key, chainCode })packages/signers/massa/src/crypto/interfaces/serializer.ts (1)
2-5: Document encoding to prevent ambiguity.String format (base58/base64/hex) should be explicit to avoid mismatches across components.
-export default interface Serializer { +/** + * Serializer for binary <-> string. The string encoding MUST be fixed and documented + * (e.g., base58, base64, hex) for cross-component compatibility. + */ +export default interface Serializer {packages/signers/massa/src/crypto/base58.ts (2)
1-1: Avoid relying on esModuleInterop for CJS dependency.Safer import style for bs58check across TS configs.
-import bs58check from 'bs58check' +import * as bs58check from 'bs58check'
14-16: Type narrowing for decode result (minor).Make the Uint8Array return explicit without extra allocs.
- deserialize(data: string): Uint8Array { - return bs58check.decode(data) - } + deserialize(data: string): Uint8Array { + return bs58check.decode(data) as unknown as Uint8Array + }packages/signers/massa/src/crypto/ed25519.ts (1)
16-23: Validate private key length to fail fast on misuse.Accept common 32- or 64-byte inputs; throw otherwise.
async getPublicKey(privateKey: Uint8Array): Promise<Uint8Array> { - return ed.getPublicKey(privateKey); + if (privateKey.length !== 32 && privateKey.length !== 64) { + throw new Error("Ed25519 privateKey must be 32 or 64 bytes"); + } + return ed.getPublicKey(privateKey); } @@ async sign(privateKey: Uint8Array, data: Uint8Array): Promise<Uint8Array> { - return ed.sign(data, privateKey); + if (privateKey.length !== 32 && privateKey.length !== 64) { + throw new Error("Ed25519 privateKey must be 32 or 64 bytes"); + } + return ed.sign(data, privateKey); }packages/signers/massa/src/crypto/varintVersioner.ts (2)
17-20: Avoid spread copies when concatenating Uint8Arrays.Use set() to reduce allocations.
attach(version: Version, data: Uint8Array): Uint8Array { - const versionArray = varint.encode(version); - return new Uint8Array([...versionArray, ...data]); + const prefix = varint.encode(version); + const out = new Uint8Array(prefix.length + data.length); + out.set(prefix, 0); + out.set(data, prefix.length); + return out; }
31-33: Optional: Guard unsupported versions and use explicit consumed‐bytes inextractWe’ve confirmed that every caller in
packages/signers/massa/srcusesversioner.attachto prefix data with a varint-encoded version andversioner.extractto decode it (e.g. inlibs/signature.ts,libs/address.ts,libs/keys.ts), so switching to an explicitconsumedvariable won’t break any single-byte expectations. To make future invalid or unrecognized versions fail fast and to clarify the byte‐offset calculation, consider this refactor inpackages/signers/massa/src/crypto/varintVersioner.ts:--- a/packages/signers/massa/src/crypto/varintVersioner.ts +++ b/packages/signers/massa/src/crypto/varintVersioner.ts @@ -30,4 +30,10 @@ extract(data: Uint8Array): { version: Version; data: Uint8Array } { - const version = varint.decode(data); - return { data: data.slice(varint.decode.bytes), version }; + const version = varint.decode(data); + const consumed = (varint.decode as any).bytes as number; + if (version !== Version.V0 && version !== Version.V1) { + throw new Error(`Unsupported version: ${version}`); + } + return { data: data.slice(consumed), version }; }• File needing update:
•packages/signers/massa/src/crypto/varintVersioner.ts– inside theextractmethod.This change is purely optional but improves safety and readability.
packages/signers/massa/src/libs/signature.ts (4)
71-75: Fix wrong variable used in version-mismatch error message.The thrown message reports the detected
versioninstead of the extracted one, making debugging confusing.- throw new Error( - `invalid version: ${version}. ${signature.version} was expected.`, - ); + throw new Error( + `invalid version: ${extractedVersion}. ${version} was expected.`, + );- throw new Error( - `invalid version: ${version}. ${signature.version} was expected.`, - ); + throw new Error( + `invalid version: ${extractedVersion}. ${version} was expected.`, + );Also applies to: 97-101
76-78: Harden catch typing for TS “unknown” catch variables.Avoid assuming
eisError.- } catch (e) { - throw new Error(`invalid signature string: ${e.message}`); - } + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new Error(`invalid signature string: ${msg}`); + }
28-31: Mark ctor deps as readonly.They’re never reassigned;
readonlyimproves safety and intent.- public serializer: Serializer, - public versioner: Versioner, - public version: Version, + public readonly serializer: Serializer, + public readonly versioner: Versioner, + public readonly version: Version,
16-16: Typo in comment (“versionner”).Minor docs nit.
- // This should be done without serializer and versionner as they are potentially not known at this point + // This should be done without serializer and versioner as they are potentially not known at this pointpackages/signers/massa/src/libs/address.ts (4)
161-167: Confirm address preimage (hashing versioned vs raw public key).You hash
publicKey.toBytes()(versioned). Many schemes hash the raw public key bytes. If Massa expects raw pubkey, the derived address will differ from reference implementations.Proposed change if raw pubkey is required:
- const rawBytes = publicKey.hasher.hash(publicKey.toBytes()); - address.bytes = Uint8Array.from([ - AddressType.EOA, - ...address.versioner.attach(Version.V0, rawBytes), - ]); + const { data: rawPublicKey } = address.versioner.extract(publicKey.toBytes()); + const digest = publicKey.hasher.hash(rawPublicKey); + address.bytes = Uint8Array.from([ + AddressType.EOA, + ...address.versioner.attach(Version.V0, digest), + ]);If you want, I can cross-check against Massa’s spec and reference SDKs and adjust accordingly.
119-123: Fix wrong variable used in version-mismatch error message.- throw new Error( - `invalid version: ${version}. ${address.version} was expected.`, - ); + throw new Error( + `invalid version: ${extractedVersion}. ${version} was expected.`, + );- throw new Error( - `invalid version: ${version}. ${address.version} was expected.`, - ); + throw new Error( + `invalid version: ${extractedVersion}. ${version} was expected.`, + );Also applies to: 188-191
37-38: Docstring return description is incorrect.Function returns a prefix, not a version.
- * @returns the address version. + * @returns The address prefix.
142-147: Return type and error grammar in getType().Tighten typing and fix message grammar.
- private getType(): number { + private getType(): AddressType { if (!this.bytes) { - throw new Error("address bytes is not initialized"); + throw new Error("address bytes are not initialized"); } - return varint.decode(this.bytes); + return varint.decode(this.bytes) as AddressType; }packages/signers/massa/src/libs/keys.ts (2)
341-345: Fix typo in verify() docs.- * This function very a byte-encoded message. The message is first hashed and then verified. + * This function verifies a byte-encoded message. The message is first hashed and then verified.
50-55: Mark ctor deps as readonly.Consistency with Signature/Address suggestion; prevents accidental reassignment.
- public hasher: Hasher, - public signer: Signer, - public serializer: Serializer, - public versioner: Versioner, - public version: Version, + public readonly hasher: Hasher, + public readonly signer: Signer, + public readonly serializer: Serializer, + public readonly versioner: Versioner, + public readonly version: Version,Also applies to: 231-237
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (27)
packages/extension/configs/vitest.config.mts(1 hunks)packages/extension/src/libs/utils/initialize-wallet.ts(3 hunks)packages/extension/src/providers/massa/index.ts(1 hunks)packages/extension/src/providers/massa/libs/activity-handlers/massa.ts(1 hunks)packages/extension/src/providers/massa/libs/api.ts(1 hunks)packages/extension/src/providers/massa/methods/index.ts(1 hunks)packages/extension/src/providers/massa/methods/massa_getBalance.ts(1 hunks)packages/extension/src/providers/massa/methods/massa_getNetwork.ts(1 hunks)packages/extension/src/providers/massa/networks/massa-base.ts(1 hunks)packages/signers/massa/package.json(1 hunks)packages/signers/massa/src/crypto/base58.ts(1 hunks)packages/signers/massa/src/crypto/blake3.ts(1 hunks)packages/signers/massa/src/crypto/cross-browser.ts(1 hunks)packages/signers/massa/src/crypto/ed25519.ts(1 hunks)packages/signers/massa/src/crypto/interfaces/hasher.ts(1 hunks)packages/signers/massa/src/crypto/interfaces/sealer.ts(1 hunks)packages/signers/massa/src/crypto/interfaces/serializer.ts(1 hunks)packages/signers/massa/src/crypto/interfaces/signer.ts(1 hunks)packages/signers/massa/src/crypto/interfaces/versioner.ts(1 hunks)packages/signers/massa/src/crypto/passwordSeal.ts(1 hunks)packages/signers/massa/src/crypto/varintVersioner.ts(1 hunks)packages/signers/massa/src/index.ts(1 hunks)packages/signers/massa/src/libs/address.ts(1 hunks)packages/signers/massa/src/libs/ed25519.ts(1 hunks)packages/signers/massa/src/libs/index.ts(1 hunks)packages/signers/massa/src/libs/keys.ts(1 hunks)packages/signers/massa/src/libs/signature.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- packages/extension/src/providers/massa/methods/massa_getNetwork.ts
- packages/extension/src/providers/massa/methods/massa_getBalance.ts
- packages/extension/src/providers/massa/networks/massa-base.ts
- packages/extension/src/providers/massa/libs/activity-handlers/massa.ts
- packages/signers/massa/src/index.ts
- packages/extension/src/providers/massa/methods/index.ts
- packages/extension/src/providers/massa/index.ts
- packages/extension/src/libs/utils/initialize-wallet.ts
- packages/extension/src/providers/massa/libs/api.ts
🧰 Additional context used
🧬 Code graph analysis (9)
packages/signers/massa/src/crypto/base58.ts (1)
packages/signers/massa/src/crypto/interfaces/serializer.ts (1)
Serializer(2-5)
packages/signers/massa/src/crypto/ed25519.ts (1)
packages/signers/massa/src/crypto/interfaces/signer.ts (1)
Signer(2-11)
packages/signers/massa/src/crypto/blake3.ts (1)
packages/signers/massa/src/crypto/interfaces/hasher.ts (1)
Hasher(2-4)
packages/signers/massa/src/crypto/cross-browser.ts (1)
packages/keyring/src/index.ts (1)
password(113-133)
packages/signers/massa/src/crypto/passwordSeal.ts (2)
packages/signers/massa/src/crypto/cross-browser.ts (4)
PBKDF2Options(84-88)pbkdf2(99-109)aesGCMEncrypt(123-159)aesGCMDecrypt(176-217)packages/signers/massa/src/crypto/interfaces/sealer.ts (1)
Sealer(2-7)
packages/signers/massa/src/crypto/varintVersioner.ts (1)
packages/signers/massa/src/crypto/interfaces/versioner.ts (1)
Versioner(2-5)
packages/signers/massa/src/libs/address.ts (5)
packages/signers/massa/src/crypto/interfaces/serializer.ts (1)
Serializer(2-5)packages/signers/massa/src/crypto/interfaces/versioner.ts (1)
Versioner(2-5)packages/signers/massa/src/crypto/base58.ts (1)
Base58(7-17)packages/signers/massa/src/crypto/varintVersioner.ts (1)
VarintVersioner(7-34)packages/signers/massa/src/libs/keys.ts (1)
PublicKey(225-384)
packages/signers/massa/src/libs/keys.ts (10)
packages/signers/massa/src/crypto/interfaces/hasher.ts (1)
Hasher(2-4)packages/signers/massa/src/crypto/interfaces/signer.ts (1)
Signer(2-11)packages/signers/massa/src/crypto/interfaces/serializer.ts (1)
Serializer(2-5)packages/signers/massa/src/crypto/interfaces/versioner.ts (1)
Versioner(2-5)packages/signers/massa/src/crypto/blake3.ts (1)
Blake3(7-12)packages/signers/massa/src/crypto/ed25519.ts (1)
Ed25519(9-33)packages/signers/massa/src/crypto/base58.ts (1)
Base58(7-17)packages/signers/massa/src/crypto/varintVersioner.ts (1)
VarintVersioner(7-34)packages/signers/massa/src/libs/signature.ts (1)
Signature(23-122)packages/signers/massa/src/libs/address.ts (1)
Address(65-254)
packages/signers/massa/src/libs/signature.ts (4)
packages/signers/massa/src/crypto/interfaces/serializer.ts (1)
Serializer(2-5)packages/signers/massa/src/crypto/interfaces/versioner.ts (1)
Versioner(2-5)packages/signers/massa/src/crypto/base58.ts (1)
Base58(7-17)packages/signers/massa/src/crypto/varintVersioner.ts (1)
VarintVersioner(7-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (6)
packages/extension/configs/vitest.config.mts (1)
25-35: CI Node versions are sufficiently modern forimport.meta.resolve
- In
.github/workflows/test-swap.ymlandtest-all.yml, theactions/setup-node@v4step pinsnode-version: "22.10.0".- Other workflows (e.g. release/build-all) rely on the GitHub runner’s default Node.js (currently v20.x), which also supports
import.meta.resolve.- All
package.jsonfiles declare"node": ">=14.15.0", and sinceimport.meta.resolveis stable in Node.js v16+, your CI configuration exceeds that requirement.No further changes are required to avoid runtime errors in CI. You may optionally tighten your
engines.nodefield to>=16.0.0for local-development consistency, but it isn’t strictly necessary given your current CI setup.packages/signers/massa/package.json (1)
21-23: Align Node engine with tooling requirementsTooling here (eslint@9, vitest@3, tsup@8, typescript-eslint@8) requires Node ≥18. Engines set to 14 will break CI/local installs.
Apply:
- "engines": { - "node": ">=14.15.0" - }, + "engines": { + "node": ">=18.18.0" + },Likely an incorrect or invalid review comment.
packages/signers/massa/src/crypto/cross-browser.ts (2)
123-159: LGTM on AES-GCM implementation details and tag handling.Node/browser parity is clear; validations are good. With the Uint8Array changes above, this will be robust across environments.
Also applies to: 176-217
1-6: Doc nit: module comments are helpful and accurate.No changes needed.
packages/signers/massa/src/libs/index.ts (1)
1-4: libs/index.ts correctly exports only derivePath; no default Ed25519 to forwardThe file
packages/signers/massa/src/libs/ed25519.tsonly defines and exports thederivePathfunction—there is noexport default class Ed25519in this module. TheEd25519signer implementation lives inpackages/signers/massa/src/crypto/ed25519.ts.• If you intended to expose the
Ed25519Signer class from this barrel, add:export { default as Ed25519 } from "../crypto/ed25519";• Otherwise, the current barrel is correct in re-exporting the HD derivation utility (
derivePath) only.Likely an incorrect or invalid review comment.
packages/signers/massa/src/crypto/interfaces/versioner.ts (1)
2-10: LGTM — clear, minimal contract for versioned payloads.Interface and enum are straightforward and align with intended consumers.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (3)
package.json(1 hunks)packages/extension/package.json(1 hunks)packages/extension/src/providers/massa/networks/mainnet.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/extension/package.json
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension/src/providers/massa/networks/mainnet.ts (1)
packages/extension/src/providers/massa/networks/massa-base.ts (2)
createMassaNetworkOptions(249-285)MassaNetwork(22-246)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (6)
package.json (2)
42-43: Unable to verify automatically—novite.config.*files referencevite-plugin-node-polyfillsor the script tooling failed. Please confirm that any workspace importing this plugin in its Vite config has it listed in its own package.json.
43-43: No changes required: vite-plugin-node-polyfills@0.24.0 is confirmed compatible with Vite 5.x and Node 18/20.packages/extension/src/providers/massa/networks/mainnet.ts (4)
16-18: LGTM: network instantiation and export.Instantiation and default export are clean and consistent with the pattern.
13-14: Confirmed CoinGecko ID: ‘massa’ is the correct CoinGecko asset ID for Massa (MAS); no changes needed.
12-12: No action required—chainId type is correct.
CHAIN_ID.Mainnetis already abigint, matching the expected type increateMassaNetworkOptions.
8-9: Confirmed explorer URL patterns. The existing URLs (https://explorer.massa.net/mainnet/operation/[[txHash]] and https://explorer.massa.net/mainnet/address/[[address]]) match the live explorer; no changes needed.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (2)
72-86: Resolved: native symbol now correct
send-alertusesselectedAsset?.symbol || network.currencyNameinstead ofnetwork.name. Good catch.
376-386: Balance units bug (base vs human) and mutating a computed
api.getBalancereturns base units, but elsewhereaccountBalanceis treated as human-readable. Also, writing toaccount.value.balancemutates a computed result.Minimal fix (convert to human units):
- const balance = await api.getBalance(addressFrom.value); - // Update the account object with the new balance - if (account.value) { - account.value.balance = balance; - } + const balanceBase = await api.getBalance(addressFrom.value); + const balance = fromBase(balanceBase, 9); // MAS has 9 decimals + // Update the account object with the human-readable balance + if (account.value) { + account.value.balance = balance; + }Optional refactor (avoid mutating a computed): introduce a local ref and derive
accountBalancefrom it.// declare near other refs const accountBalanceRef = ref<string>('0'); // replace the computed at lines 200-203: const accountBalance = computed(() => accountBalanceRef.value); // and set it here instead of mutating `account.value`: accountBalanceRef.value = balance;
🧹 Nitpick comments (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (4)
281-283: Avoid magic number for MAS decimalsUse the selected token’s decimals for consistency.
- return fromBase(insufficientBase.toString(), 9); + return fromBase( + insufficientBase.toString(), + selectedAsset.value.decimals + );
89-89: Dynamic fee labelAvoid hard-coding “MAS” so testnets or future networks display the right symbol.
- <label>Fee (MAS)</label> + <label>Fee ({{ network.currencyName }})</label>
144-153: Make required props explicitUsing
{}defaults on typed objects can mask errors. Mark as required.network: { - type: Object as PropType<BaseNetwork>, - default: () => ({}), + type: Object as PropType<BaseNetwork>, + required: true, }, accountInfo: { - type: Object as PropType<AccountsHeaderData>, - default: () => ({}), + type: Object as PropType<AccountsHeaderData>, + required: true, },
505-508: Remove dead handler or implement toggle
toggleSelectoris a no-op; either wire it to open token selector or remove the listener fromsend-header.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/extension/package.json(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)packages/signers/massa/src/crypto/ed25519.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/signers/massa/src/crypto/ed25519.ts
- packages/extension/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: buildAll
🔇 Additional comments (3)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (3)
537-537: Verify toTokenAddress for MASFor native MAS transfers,
contractmay be empty/undefined. Ensure the verify flow and signer handle native transfers without a contract address.
553-557: Buffer API is already polyfilled via Vite config
The Vite setup in packages/extension/vite.config.ts usesnodePolyfills({ include: ['buffer', …] }), soBuffer.from(...).toString('base64')and its reverse on the verify screen will work without importingBufferor switching tobtoa.
248-261: Ensureapi.getBalancereturns raw base units
InupdateAccountBalance,account.value.balance = balanceassigns whateverMassaAPI.getBalancereturns. IngetAllTokenInfo,api.getBalanceyields a base‐unit string (e.g. raw integer amount) which is then converted to human units viafromBase(balance, decimals)before use(). Ifapi.getBalanceindeed returns base units, then elsewhere usingaccountBalance.valuedirectly (e.g.parseFloat(accountBalance)) treats it as human units—causing incorrect fee checks.
- Confirm in
packages/extension/src/providers/massa/libs/api.tsthatgetBalancereturns a raw string/BigInt in base units; if it already formats to human units, update comment here.- If it returns base units, wrap
balanceinfromBase(balance, 9)before assigning toaccount.value.balance, or adjust all downstream uses to convert from base units.
| onMounted(async () => { | ||
| const currentAccount = account.value; | ||
| if (currentAccount?.address && !addressFrom.value) { | ||
| addressFrom.value = currentAccount.address; | ||
| } else { | ||
| const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); | ||
| addressFrom.value = accounts[0].address; | ||
| } | ||
|
|
There was a problem hiding this comment.
Guard against empty keyring accounts
accounts[0] can be undefined and crash subsequent logic.
Apply:
- const accounts = await keyRing.getAccounts([SignerType.ed25519mas]);
- addressFrom.value = accounts[0].address;
+ const accounts = await keyRing.getAccounts([SignerType.ed25519mas]);
+ addressFrom.value = accounts?.[0]?.address || '';Optionally, early-return or show an error if no accounts are found.
📝 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.
| onMounted(async () => { | |
| const currentAccount = account.value; | |
| if (currentAccount?.address && !addressFrom.value) { | |
| addressFrom.value = currentAccount.address; | |
| } else { | |
| const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); | |
| addressFrom.value = accounts[0].address; | |
| } | |
| onMounted(async () => { | |
| const currentAccount = account.value; | |
| if (currentAccount?.address && !addressFrom.value) { | |
| addressFrom.value = currentAccount.address; | |
| } else { | |
| const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); | |
| addressFrom.value = accounts?.[0]?.address || ''; | |
| } | |
| // …rest of the mounted logic… | |
| }); |
🤖 Prompt for AI Agents
In packages/extension/src/providers/massa/ui/send-transaction/index.vue around
lines 352–360, the code assumes accounts[0] exists which can be undefined and
crash; after awaiting keyRing.getAccounts([...]) check that accounts is non-null
and accounts.length > 0, and if empty either set a user-visible
error/notification and return early (or set a sensible fallback), otherwise
safely use accounts[0].address; ensure you don’t dereference accounts[0] before
this check and keep the existing addressFrom assignment inside the validated
branch.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (4)
332-369: Validate fee decimals and enforce minimal fee in isInputsValidWithout this, users can submit with invalid precision or below-network fee; downstream toBase() may also throw on bad input.
const isInputsValid = computed<boolean>(() => { // First check if address is provided if (!addressTo.value || addressTo.value.trim() === '') { return false; } @@ // Check if a token is selected if (!selectedAsset.value) { return false; } @@ // Check if amount is greater than 0 if (amountNum <= 0) { return false; } - - const result = hasEnoughBalance.value; - return result; + + // Validate fee precision and minimal fee + if (!isValidDecimals(fee.value, 9)) return false; + try { + const feeBase = BigInt(toBase(fee.value || '0', 9)); + const minBase = BigInt(toBase(minimalFee.value || '0', 9)); + if (feeBase < minBase) return false; + } catch { + return false; + } + + return hasEnoughBalance.value; });
381-383: Guard against empty keyring results to avoid runtime crashgetAccounts() can return an empty array. Accessing accounts[0].address will throw.
- const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); - addressFrom.value = accounts[0].address; + const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); + addressFrom.value = accounts?.[0]?.address || ''; + if (!addressFrom.value) { + // No Massa accounts; keep UI inert + return; + }
404-409: Balance units mismatch: convert base→human before storingElsewhere balance is treated as human-readable and re-converted with toBase (e.g., Line 259). Writing base units here breaks fee/balance checks.
- const balance = await api.getBalance(addressFrom.value); - // Update the account object with the new balance - if (account.value) { - account.value.balance = balance; - } + const balanceBase = await api.getBalance(addressFrom.value); + const balance = fromBase(balanceBase, 9); // MAS has 9 decimals + // Update the account object with the human-readable balance + if (account.value) { + account.value.balance = balance; + }
560-561: Fix typo: price uses non-existent fieldvaluefThis serializes undefined and breaks USD pricing on verify.
- price: selectedAsset.value.valuef || '0', + price: selectedAsset.value.value || '0',
🧹 Nitpick comments (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (4)
433-441: Type the augmented assets instead of using any[]Define a narrowed type that extends AssetsType with price to improve safety across AssetsSelectList usage.
-const accountAssets = ref<any[]>([]); +type AssetWithPrice = AssetsType & { price: string }; +const accountAssets = ref<AssetWithPrice[]>([]); @@ - const tokensWithPrice = tokenInfos.map((token: AssetsType) => ({ + const tokensWithPrice: AssetWithPrice[] = tokenInfos.map((token: AssetsType) => ({ ...token, price: token.value, // Use value field as price for USD display }));
135-137: Decouple from Solana provider componentImporting SendAlert from the Solana path couples Massa UI to another provider. Move/alias this alert in common or the Massa folder for locality.
506-517: Max for MAS should clamp at zero with explicit guardBigInt subtraction can be negative; you already check >0n, but make the clamp explicit to avoid accidental negative conversions if logic changes.
- const maxAmountBase = balanceNum - feeNum; - if (maxAmountBase > 0n) { + const maxAmountBase = balanceNum > feeNum ? balanceNum - feeNum : 0n; + if (maxAmountBase > 0n) { amount.value = fromBase( maxAmountBase.toString(), selectedAsset.value.decimals, );
239-245: Round fiat values consistentlyConsider using toFixed(2, BigNumber.ROUND_DOWN) or a shared formatter to avoid rounding up fees/amounts unexpectedly.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (3)
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)packages/extension/vite.config.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (4)
packages/extension/vite.config.ts (1)
56-60: Make BUILD_TIME locale-agnostic and reproducibletoLocaleString()+replace(/\D/g, '') depends on the build machine’s locale and can yield ambiguous or empty values. Switch to a stable UTC format with an optional env override:
- : JSON.stringify(new Date().toLocaleString().replace(/\D/g, '')), + : JSON.stringify(process.env.BUILD_TIME ?? new Date().toISOString().slice(0, 19).replace(/[-:T]/g, '')),Also confirm whether the static
'FF-build'for Firefox builds is intentional; otherwise align it to use the same timestamp logic.packages/extension/src/providers/massa/ui/send-transaction/index.vue (3)
72-76: Good fix on native symbolPassing selectedAsset?.symbol || network.currencyName to the balance alert is correct and resolves the earlier mismatch.
562-562: Native MAS may not have a contract addressIf MAS is native, selectedAsset.contract could be empty/undefined. Ensure the verify flow treats this field as optional or conditionally omit it.
Would you like me to patch this to set toTokenAddress only for non-MAS tokens?
579-581: No changes required—Buffer is polyfilled in the extension build
Rollup’s inject plugin already provides a browser‐safe Buffer (see packages/extension/configs/rollup.config.base.ts:36–37), so usingBuffer.from(...).toString('base64')here is safe.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue (2)
127-130: Always emit toggle state on both focus and blur.Consumers won’t know when to hide contacts otherwise.
const changeFocus = (val: FocusEvent) => { isFocus.value = val.type === 'focus'; - if (isFocus.value) emit('toggle:showContacts', isFocus.value); + emit('toggle:showContacts', isFocus.value); };
79-82: Guard against undefined validator to prevent runtime crash.
props.networkdefaults to{}andisValidAddressmay be undefined, which will throw on non-empty input.Apply:
-const isValidMassaAddress = computed(() => { - if (!massaAddress.value || massaAddress.value.trim() === '') return false; - return props.network.isValidAddress(massaAddress.value); -}); +const isValidMassaAddress = computed(() => { + const val = massaAddress.value?.trim() ?? ''; + if (!val) return false; + return props.network?.isValidAddress?.(val) ?? false; +});
🧹 Nitpick comments (5)
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue (5)
46-51: Use Clipboard API (with fallback) and declareemitbefore use.
document.execCommand('paste')is deprecated and often blocked. Prefernavigator.clipboard.readText()with a safe fallback. This also requires movingdefineEmitsabove the function.-const pasteFromClipboard = () => { - addressInput.value?.focus(); - document.execCommand('paste'); -}; -defineExpose({ addressInput, pasteFromClipboard }); +const emit = defineEmits<{ + (e: 'update:inputAddress', address: string): void; + (e: 'toggle:showContacts', show: boolean): void; +}>(); + +const pasteFromClipboard = async () => { + try { + addressInput.value?.focus(); + const text = await navigator.clipboard.readText(); + emit('update:inputAddress', text.trim()); + } catch { + // Fallback for environments without Clipboard API/permissions + addressInput.value?.focus(); + document.execCommand?.('paste'); + } +}; +defineExpose({ addressInput, pasteFromClipboard });-const emit = defineEmits<{ - (e: 'update:inputAddress', address: string): void; - (e: 'toggle:showContacts', show: boolean): void; -}>(); +// moved above to use in pasteFromClipboardAlso applies to: 70-73
93-103: Avoid side-effects inside a computed getter.Setting reactive state (
identiconError) from within a computed can cause re-computation loops and is an anti-pattern. Just returnnullon error; rely on@errorhandler for load failures.- try { - if (props.network && props.network.identicon) { - return props.network.identicon(massaAddress.value); - } - } catch (error) { - console.error('Error generating identicon:', error); - // Set error state outside of computed property - nextTick(() => { - identiconError.value = true; - }); - } + try { + return props.network?.identicon?.(massaAddress.value) ?? null; + } catch (error) { + console.error('Error generating identicon:', error); + return null; + }
20-31: Minor a11y: reflect validity and disable noisy browser heuristics.Expose validity and turn off autocorrect for addresses.
<input ref="addressInput" v-model="address" type="text" :disabled="disableDirectInput" placeholder="Enter Massa address" + :aria-invalid="!!(massaAddress && !isValidMassaAddress)" + autocomplete="off" + autocapitalize="none" + spellcheck="false" :style="{ color: massaAddress && !isValidMassaAddress ? 'red' : 'black', }" @focus="changeFocus" @blur="changeFocus" />
59-63: Type-safe default fornetworkor make it required.Defaulting to
{}violates the contract and forces defensive checks. Prefernulldefault (with optional chaining) orrequired: true.- network: { - type: Object as PropType<MassaNetwork>, - default: () => ({}), - }, + network: { + type: Object as PropType<MassaNetwork | null>, + default: null, + },
145-147: Duplicate CSS declaration.
box-sizing: border-box;is set twice; keep one.box-sizing: border-box; - border: 1px solid @gray02; - box-sizing: border-box; + border: 1px solid @gray02;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/extension/src/providers/common/ui/send-transaction/send-input-amount.vue(2 hunks)packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/extension/src/providers/common/ui/send-transaction/send-input-amount.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/extension/src/providers/massa/ui/send-transaction/index.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
packages/extension/src/providers/massa/ui/send-transaction/components/send-address-input.vue
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue (4)
173-174: Confirm hardcoded MAS decimals
toBase(txData.txFee.nativeValue, 9)assumes 9 decimals. If MAS decimals are centralized elsewhere, derive from network/token metadata to avoid drift.
15-21: Replace inline error color with themed classInline
style="color: red"bypasses theming. Use a BEM modifier and theme variable (e.g.,--errorcolor) for consistency/accessibility.
258-276: Activity type for token transfersIf
ActivityTypedifferentiates native vs token transfers, consider using a token-specific type for MRC20 to improve UX/filters.
318-324: Micro: avoid DOM reads on render for scroll check
isHasScroll()readsclassListeach render. Consider caching via a computed or an event from the scrollbar to toggle the border class.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (1)
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue (1)
209-215: Verify Massa call payload field names and sendOperation return shape
- Ensure
OperationType.CallSmartContractFunctionexpects{ to, func, data, coins }as named; some APIs usetargetAddress,targetFunction,parameter.- Confirm
massaClient.sendOperationreturns a single operation ID (string). If it returns an array, assign the first element and store consistently inoperationIdRef.Also applies to: 224-230
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue
Show resolved
Hide resolved
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue
Show resolved
Hide resolved
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue
Show resolved
Hide resolved
packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/extension/src/ui/action/views/network-activity/index.vue (1)
222-245: Do not fail non-terminal Massa states; map only terminal states and keep polling otherwiseAnything not “success” is currently marked failed, and
PendingInclusionis the only non-terminal you skip. Massa distinguishes terminal vs non-terminal states; treat only terminal success/failure as final, keep polling for the rest.Apply:
- } else if (props.network.provider === ProviderName.massa) { - if (!info) return; - const massaInfo = info as MassaRawInfo; - if (isActivityUpdating || massaInfo === OperationStatus.PendingInclusion) - return; - - let status = ActivityStatus.failed; - // if the transaction is not found, and it's been less than 1 minute, wait for it to be processed - if ( - massaInfo === OperationStatus.NotFound && - Date.now() < activity.timestamp + 60_000 - ) { - return; - } else if ( - massaInfo === OperationStatus.Success || - massaInfo === OperationStatus.SpeculativeSuccess - ) { - status = ActivityStatus.success; - } - - activity.status = status; - activity.rawInfo = massaInfo; - updateActivitySync(activity).then(() => updateVisibleActivity(activity)); + } else if (props.network.provider === ProviderName.massa) { + if (!info || isActivityUpdating) return; + const status = info as unknown as OperationStatus; + + // Non-terminal: keep polling + if ( + status === OperationStatus.INCLUDED_PENDING || + status === OperationStatus.AWAITING_INCLUSION + ) { + return; + } + + // Grace period for NOT_FOUND (node lag) + if ( + status === OperationStatus.NOT_FOUND && + Date.now() < activity.timestamp + 60_000 + ) { + return; + } + + // Terminal mapping + activity.status = + status === OperationStatus.FINAL + ? ActivityStatus.success + : ActivityStatus.failed; // e.g., INCONSISTENT or late NOT_FOUND + activity.rawInfo = info as MassaRawInfo; + updateActivitySync(activity).then(() => updateVisibleActivity(activity)); }Rationale:
FINALis terminal success;INCONSISTENT/lateNOT_FOUNDare terminal failures;INCLUDED_PENDING/AWAITING_INCLUSIONare non-terminal and must not stop the poller. Keep the globalclearIntervalreliant on reaching this block only after a terminal state. (npmjs.com, docs.massa.net)
🧹 Nitpick comments (1)
packages/extension/src/ui/action/views/network-activity/index.vue (1)
71-72: Clarify MassaRawInfo shape vs valueYou use
massaInfoas a bare enum value (compared directly toOperationStatus.*) but assign it toactivity.rawInfotyped asMassaRawInfo. EnsureMassaRawInfois actually the enum (or wrap it as{ status: OperationStatus }) to avoid type drift at persistence/serialization boundaries.
Would you like me to align the activity type and storage schema?
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue(1 hunks)packages/extension/src/ui/action/views/network-activity/index.vue(3 hunks)packages/extension/src/ui/action/views/network-assets/components/custom-massa-token.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/extension/src/providers/massa/ui/send-transaction/index.vue
- packages/extension/src/ui/action/views/network-assets/components/custom-massa-token.vue
- packages/extension/src/providers/massa/ui/send-transaction/verify-transaction/index.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (4)
549-550: Fix typo: toToken.price uses non-existent fieldvaluefThis serializes
undefinedand breaks fiat display on verify.- price: selectedAsset.value.valuef || '0', + price: selectedAsset.value.value || '0',Run to confirm there are no other
valueftypos:#!/bin/bash rg -n "valuef" -S
87-94: Bind fee placeholder/min correctly (mustache doesn't work in Vue templates)Current attributes won’t reflect
minimalFeeand won’t enforce min.- <input - v-model="fee" - type="number" - placeholder="{{ minimalFee }}" - class="fee-input" - step="0.000000001" - min="{{ minimalFee }}" - /> + <input + v-model="fee" + type="number" + :placeholder="minimalFee" + class="fee-input" + step="0.000000001" + :min="minimalFee" + inputmode="decimal" + />
383-391: Keepaccount.balancein human units (9 decimals), not base unitsElsewhere you treat
account.balanceas human-readable and convert viatoBase. Assigning base units here breaks fee/balance checks.- const api = (await network.value.api()) as MassaAPI; - const balance = await api.getBalance(addressFrom.value); - // Update the account object with the new balance - if (account.value) { - account.value.balance = balance; - } + const api = (await network.value.api()) as MassaAPI; + const balanceBase = await api.getBalance(addressFrom.value); + const balance = fromBase(balanceBase, 9); // MAS has 9 decimals + if (account.value) { + account.value.balance = balance; + }
358-366: Guard against empty keyring accounts to avoid crash
accounts[0]may be undefined.- } else { - const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); - addressFrom.value = accounts[0].address; - } + } else { + const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); + addressFrom.value = accounts?.[0]?.address || ''; + }
🧹 Nitpick comments (3)
packages/extension/src/ui/action/components/app-menu/index.vue (1)
352-361: Sorting by name_long is sensible. Consider immutability, fallback, and case-insensitive compare.
- Don’t mutate the input array; return a sorted copy to avoid side effects.
- Gracefully fallback to
nameifname_longis ever missing.- Use case-insensitive comparison for a more consistent UX.
const sortNetworks = (networks: BaseNetwork[], sortBy: NetworkSort) => { - return networks.sort((a, b) => { + return [...networks].sort((a, b) => { if (sortBy.name === NetworkSortOption.Name) { - return sortBy.direction === NetworkSortDirection.Asc - ? a.name_long.localeCompare(b.name_long) - : b.name_long.localeCompare(a.name_long); + const aName = a.name_long ?? a.name; + const bName = b.name_long ?? b.name; + return sortBy.direction === NetworkSortDirection.Asc + ? aName.localeCompare(bName, undefined, { sensitivity: 'base' }) + : bName.localeCompare(aName, undefined, { sensitivity: 'base' }); } return 0; }); };packages/extension/src/providers/massa/ui/send-transaction/index.vue (2)
172-198: Avoid mutating a computed ref (account)You mutate
account.value.balancethoughaccountis derived from props. Prefer a writablerefsynced from props to prevent surprising overrides when props change.
- Create
const accountRef = ref({...})on mount andwatchprops.accountInfoto resync fields; replace usages ofaccountwithaccountRef.- Keep API refreshes writing to
accountRef.value.balance.Also applies to: 383-391
120-141: Decouple Solana-specific path forSendAlertImporting from
solanapath in a Massa view creates cross-provider coupling.
- Move
send-alert.vueto a shared location (e.g.,@/providers/common/ui/send-transaction/components/) and import from there, or re-export under a common alias.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)packages/extension/src/ui/action/components/app-menu/index.vue(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (1)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (1)
541-561:toTokenAddresscorrectly optional for native MAS
VerifyTransactionParamsdeclarestoTokenAddress?, and insendActionthe branchtxData.toToken.symbol === 'MAS'skips any check ontoTokenAddress, so native MAS transfers proceed without it.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (5)
386-391: Fix unit mismatch: keep account.balance in human-readable MASapi.getBalance returns base units. You later call toBase(accountBalance, 9), double-converting and breaking balance/fee math.
- const balance = await api.getBalance(addressFrom.value); - // Update the account object with the new balance - if (account.value) { - account.value.balance = balance; - } + const balanceBase = await api.getBalance(addressFrom.value); + const balance = fromBase(balanceBase, 9); // MAS has 9 decimals + // Update the account object with the human-readable balance + if (account.value) { + account.value.balance = balance; + }
363-365: Guard against empty keyring accounts to avoid crashaccounts[0] can be undefined. Add a safe check and early return/UI notice.
- const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); - addressFrom.value = accounts[0].address; + const accounts = await keyRing.getAccounts([SignerType.ed25519mas]); + addressFrom.value = accounts?.[0]?.address || ''; + if (!addressFrom.value) { + // Optionally show a user-facing error or disable form + return; + }
90-94: Bind fee placeholder/min with Vue bindings (mustache here doesn’t work)Current markup shows literal “{{ minimalFee }}” and doesn’t enforce min.
- <input - v-model="fee" - type="number" - placeholder="{{ minimalFee }}" - class="fee-input" - step="0.000000001" - min="{{ minimalFee }}" - /> + <input + v-model="fee" + type="number" + :placeholder="minimalFee" + class="fee-input" + step="0.000000001" + :min="minimalFee" + />
162-166: Enforce minimal fee and validate fee before balance mathFee is neither validated nor checked against minimalFee; toBase(fee) can throw and allow under-min fees.
@@ -const fee = ref<string>('0.01'); -const minimalFee = ref<string>('0.01'); +const fee = ref<string>('0.01'); +const minimalFee = ref<string>('0.01'); +const isFeeValid = computed(() => { + if (!isValidDecimals(fee.value, 9) || !isNumericPositive(fee.value)) return false; + try { + return BigInt(toBase(fee.value, 9)) >= BigInt(toBase(minimalFee.value, 9)); + } catch { + return false; + } +}); @@ - const amount = BigInt(toBase(sendAmount.value, selectedAsset.value.decimals)); + const amount = BigInt(toBase(sendAmount.value, selectedAsset.value.decimals)); const tokenBalance = BigInt(selectedAsset.value.balance || '0'); - const masBalance = BigInt(toBase(accountBalance.value, 9)); - const feeRaw = BigInt(toBase(fee.value, 9)); + if (!isFeeValid.value) return false; + const masBalance = BigInt(toBase(accountBalance.value, 9)); + const feeRaw = BigInt(toBase(fee.value, 9)); @@ if (selectedAsset.value && !hasValidDecimals.value) { return `Too many decimals.`; } + if (!isFeeValid.value) { + return `Fee is invalid or below network minimum (${minimalFee.value} MAS).`; + } return ''; @@ if (amountBN.lte(0)) { return false; } - - return hasEnoughBalance.value; + if (!isFeeValid.value) { + return false; + } + return hasEnoughBalance.value;Also applies to: 244-264, 284-308, 310-351
549-550: Fix typo: use token.value, not valuefvaluef doesn’t exist; breaks USD pricing on verify.
- price: selectedAsset.value.valuef || '0', + price: selectedAsset.value.value || '0',
🧹 Nitpick comments (4)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (4)
486-517: Handle invalid fee in setMaxValue to avoid toBase throwingIf fee is invalid/below min, set max to 0 or skip subtract; otherwise toBase(fee, 9) can throw.
- const feeBase = toBase(fee.value, 9); // Fee is always in MAS + const feeBase = isFeeValid?.value ? toBase(fee.value, 9) : '0';
45-46: Optional: null-safe template ref callProtect against rare timing issues with the template ref.
- @update:paste-from-clipboard="addressInputTo.pasteFromClipboard()" + @update:paste-from-clipboard="addressInputTo?.pasteFromClipboard?.()"
131-131: Consider de-coupling SendAlert from Solana pathImporting from a Solana provider path in Massa UI is brittle; move/alias to a common location if available.
208-211: Type the assets listUse a typed array to avoid any[] and align with AssetsSelectList expectations.
-const accountAssets = ref<any[]>([]); +const accountAssets = ref<(AssetsType & { price?: string })[]>([]);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/extension/src/providers/massa/ui/send-transaction/index.vue(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (2)
packages/extension/src/providers/massa/ui/send-transaction/index.vue (2)
555-559: LGTM: correct native currency symbolUsing network.value.currencyName here resolves the earlier nativeSymbol issue.
244-255: Confirm unit ofactiveBalances
ThehasEnoughBalancecheck usestoBase(accountBalance.value, 9), which assumesaccountBalance(fromprops.accountInfo.activeBalances) is a human-readable MAS decimal. Verify thatactiveBalancesindeed supplies decimal MAS strings; if it already returns base-unit values, drop the extratoBaseconversion.
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
Dockerfile (1)
1-7: Harden and slim image; ensure Yarn works under Node 22.
- Combine apt steps, use
--no-install-recommends, and clean apt lists to cut image size.- Enable Corepack before
yarn -vto avoid failures if Yarn isn’t activated.- Optional: install
python3for native module builds commonly required in Node toolchains.-FROM node:22.18-bookworm -RUN apt-get update -RUN apt-get install build-essential zip -y +FROM node:22.18-bookworm +RUN set -eux; \ + apt-get update; \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential zip python3 ca-certificates git \ + ; \ + rm -rf /var/lib/apt/lists/* ENV HOME /home ENV NODE_OPTIONS --max-old-space-size=8192 -RUN node -v && npm -v && yarn -v +RUN corepack enable && node -v && npm -v && yarn -v WORKDIR /homepackages/storage/package.json (1)
30-45: Avoid duplicate TypeScript-ESLint installs; keep the meta package only.
Installing bothtypescript-eslintand the individual@typescript-eslint/*packages is redundant and can cause version skew."devDependencies": { - "@types/node": "^22.18.1", - "@typescript-eslint/eslint-plugin": "^8.43.0", - "@typescript-eslint/parser": "^8.43.0", + "@types/node": "^22.18.1", "eslint": "^9.35.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-module-resolver": "^1.5.0", "prettier": "^3.6.2", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", "tsup": "^8.5.0", "typescript": "^5.9.2", "typescript-eslint": "8.43.0", "vitest": "^3.2.4" },packages/signers/polkadot/src/index.ts (2)
115-123: Assertions never validate signatures (async verify is not awaited)this.verify(...) returns a Promise, so assert(...) always sees a truthy value and never actually checks validity. Use signatureVerify synchronously.
Apply this diff in all three cases:
- assert( - this.verify( - bufferToHex(msgHashBuffer), - bufferToHex(sig), - bufferToHex(pair.publicKey), - ), - Errors.SigningErrors.UnableToVerify, - ); + assert( + signatureVerify( + msgHashBuffer, + sig, + pair.publicKey, + ).isValid, + Errors.SigningErrors.UnableToVerify, + );Also applies to: 126-134, 137-145
49-55: Remove invalid fifth argument from mnemonicToMiniSecret
In packages/signers/polkadot/src/index.ts (around line 49),mnemonicToMiniSecretonly accepts four parameters (mnemonic, password?, wordlist?, onlyJs?). Passing2048causes TS errors—revert to the 4-arg call.packages/name-resolution/package.json (1)
21-23: Engines mismatch: bump Node to ≥18.18 to align with ESLint 9 and TS toolchain.ESLint 9 requires Node 18.18+; keeping
"engines.node": ">=14.15.0"will break local linting/CI for this package. typescript-eslint v8 explicitly targets ESLint 9, which you’ve added. Recommend raising the engine floor here (and at the repo root if enforced). (eslint.org, typescripteslint.com)Apply:
"engines": { - "node": ">=14.15.0" + "node": ">=18.18.0" }Also applies to: 25-28, 38-41
♻️ Duplicate comments (1)
packages/extension/configs/vitest.config.mts (1)
20-28: Make resolver cross-platform and robust (use fileURLToPath + try/catch).Regex‑stripping "file://" is brittle (breaks on Windows, UNC paths, and encoded chars). Convert file URLs properly and fall back to default resolution on errors. This mirrors a prior review—resurfacing because the issue persists.
Apply within this hunk:
{ find: /^(vite-plugin-node-polyfills\/shims\/.+)/, replacement: '$1', - customResolver(source) { - return import.meta.resolve(source).replace(/^file:\/\//, ''); - }, + customResolver(source: string): string | undefined { + try { + const resolved = import.meta.resolve(source); + if (resolved.startsWith('file://')) { + return fileURLToPath(new URL(resolved)); + } + // Defer to Vite when it's not a file URL + return undefined; + } catch { + // Defer to normal alias replacement / Vite resolution + return undefined; + } + }, },Also add this import at the top of the file:
import { fileURLToPath } from 'node:url';
🧹 Nitpick comments (21)
packages/signers/polkadot/package.json (1)
47-48: Unify typescript-eslint versioning to avoid drift.
parserandeslint-pluginuse caret buttypescript-eslintis pinned. Prefer consistent spec to keep the trio in lockstep.Option A (caret everywhere):
- "typescript-eslint": "8.43.0", + "typescript-eslint": "^8.43.0",Option B (pin all three to exact versions) for stricter reproducibility:
- "@typescript-eslint/eslint-plugin": "^8.43.0", - "@typescript-eslint/parser": "^8.43.0", + "@typescript-eslint/eslint-plugin": "8.43.0", + "@typescript-eslint/parser": "8.43.0",.github/workflows/test-all.yml (1)
10-16: Improve Yarn availability and cache hit rate.
- Add Corepack to guarantee
yarnunder Node 22.- Cache all workspace locks for better cache hits.
- uses: actions/setup-node@v4 with: node-version: "22.18.0" cache: "yarn" + cache-dependency-path: | + yarn.lock + **/yarn.lock + - run: corepack enable - run: yarn installDockerfile (2)
4-5: Double-check 8 GB heap cap is intended for CI/build.
On smaller runners this can backfire; consider making it configurable via build arg.-ENV NODE_OPTIONS --max-old-space-size=8192 +ARG NODE_MAX_OLD_SPACE=8192 +ENV NODE_OPTIONS="--max-old-space-size=${NODE_MAX_OLD_SPACE}"
1-7: Optional: run as non-root for safer builds.
Create a user and switch to it unless root is required later.RUN corepack enable && node -v && npm -v && yarn -v -WORKDIR /home +RUN useradd -m -d /home nodeuser +USER nodeuser +WORKDIR /homepackages/storage/package.json (2)
21-23: Update engines.node to match repo toolchain.
Repo CI/Docker use Node 22.18.x; raise the floor to reduce surprises."engines": { - "node": ">=14.15.0" + "node": ">=20.0.0" },
16-20: Add a type-check script for CI clarity.
Separate type-check from build for faster feedback."scripts": { "build": "tsup src/index.ts --format esm,cjs --dts --clean", "lint": "prettier --write .", - "test": "vitest run" + "test": "vitest run", + "type-check": "tsc -p tsconfig.json --noEmit" },packages/signers/ethereum/package.json (2)
36-37: Avoid duplicating typescript-eslint stacks. Pick meta or plugin+parser.You have both @typescript-eslint/{parser,eslint-plugin} and the meta package “typescript-eslint”. Use one approach to reduce install time and peer-dep churn.
Option to keep meta only (remove plugin+parser here):
- "@typescript-eslint/eslint-plugin": "^8.43.0", - "@typescript-eslint/parser": "^8.43.0",Refs: v8 supports ESLint 9 and documents recommended setups. (tseslint.com, typescript-eslint.io)
48-49: If keeping plugin+parser, drop the meta package.This avoids redundant deps while remaining ESLint 9 compatible.
"typescript": "^5.9.2", - "typescript-eslint": "8.43.0", + // (optional) keep only @typescript-eslint/{parser,eslint-plugin} or switch to meta package; don't use bothRefs: Supported ranges for ESLint/Node/TS. (tseslint.com)
packages/hw-wallets/package.json (1)
25-25: @types/node v24 with Node 14 engines is inconsistent.Node 14 is EOL and far below the API surface modeled by @types/node 24.x. Once engines.node is raised (see above), this mismatch is resolved. Keep @types/node aligned with the Node version you run in CI/dev.
packages/name-resolution/package.json (2)
25-28: Add an ESLint script (you only run Prettier today).You’ve added ESLint deps but the script runs Prettier only. Add an eslint script and consider separating format vs. lint.
Outside this hunk, update scripts:
"scripts": { - "build": "tsup src/index.ts --format esm,cjs --dts", - "lint": "prettier --write .", + "build": "tsup src/index.ts --format esm,cjs --dts", + "lint": "eslint .", + "format": "prettier --write .", "test": "vitest run" },
51-52: Dependency bumps: request quick smoke tests against ENS/SNS flows.@bonfida/spl-name-service 3.0.16 and @ensdomains/address-encoder ^1.1.4 look fine, but please rerun ENS/Solana name encode/decode tests to catch subtle codec changes. If consumers are sensitive, consider pinning exacts until validated across the monorepo.
packages/signers/bitcoin/package.json (1)
48-49: Version pinning inconsistency and TS/Node types alignment.
- Parser/plugin use caret (^8.43.0) while "typescript-eslint" meta package is pinned to 8.43.0. Align to caret for consistent patch/minor updates, or pin all three—pick one strategy.
- @types/node is at ^24.x while engines will be ≥18.18 after the change; consider matching your supported runtime (e.g., ^20 or ^22) to avoid accidentally using APIs not present in Node 18.
Apply this minimal diff for consistency:
- "typescript-eslint": "8.43.0", + "typescript-eslint": "^8.43.0",packages/name-resolution/src/index.ts (3)
31-46: Harden reverse resolution against single-resolver failuresOne resolver rejecting will reject the whole call. Use
allSettledto ignore failures and return the first fulfilled non-null.- return this.initDone.then(() => - Promise.all([ - this.ens.resolveReverseName(address), - // this.sid.resolveReverseName(address), - this.rns.resolveReverseName(address), - this.ud.resolveReverseName(address), - ]).then((results) => { - // eslint-disable-next-line no-restricted-syntax - for (const name of results) { - if (name !== null) return name; - } - return null; - }), - ); + return this.initDone.then(() => + Promise.allSettled([ + this.ens.resolveReverseName(address), + this.rns.resolveReverseName(address), + this.ud.resolveReverseName(address), + ]).then((results) => { + for (const r of results) { + if (r.status === "fulfilled" && r.value !== null) return r.value; + } + return null; + }), + );
48-53: Mark _paymentIdChain as deprecated/ignoredThe param remains public but unused. Add a brief JSDoc to avoid confusion.
public async resolveAddress( + /** + * @deprecated Ignored while SID resolution is disabled. + */ name: string, coin: CoinType = "ETH", _paymentIdChain?: string, ): Promise<string | null> {
35-35: Delete commented-out SID callsThey’re noise now; removing avoids drift.
- // this.sid.resolveReverseName(address), @@ - // if (this.sid.isSupportedName(name)) - // return this.sid.resolveAddress(name, paymentIdChain);Also applies to: 58-59
packages/name-resolution/tests/resolver.test.ts (2)
23-25: Remove stale commented assertionKeep the test concise; the new expectation is null.
- // expect(address).to.be.eq("0xb5932a6B7d50A966AEC6C74C97385412Fb497540"); expect(address).to.be.eq(null);
11-17: Drop unused SID config in testsSID is disabled; this config is unused and can mislead.
ens: { node: "https://nodes.mewapi.io/rpc/eth", }, - sid: { - node: { - bnb: "https://nodes.mewapi.io/rpc/bsc", - arb: "https://nodes.mewapi.io/rpc/arb", - }, - },ens: { node: "https://nodes.mewapi.io/rpc/eth", }, - sid: { - node: { - bnb: "https://nodes.mewapi.io/rpc/bsc", - arb: "https://nodes.mewapi.io/rpc/arb", - }, - },Also applies to: 32-38
packages/extension/src/providers/ethereum/networks/zksepolia.ts (2)
6-19: Rename vars to zksepolia for clarityNames still say goerli. Keeps code grep-friendly and avoids confusion.
-const zkgoerliOptions: EvmNetworkOptions = { +const zksepoliaOptions: EvmNetworkOptions = {
21-23: Follow-through rename on instance and export-const zkgoerli = new EvmNetwork(zkgoerliOptions); - -export default zkgoerli; +const zksepolia = new EvmNetwork(zksepoliaOptions); +export default zksepolia;packages/utils/package.json (1)
27-27: Align @polkadot/util-crypto versions across the monorepo – update packages/signers/massa/package.json (line 35) from ^13.5.1 to ^13.5.6 to match the other packages.packages/extension/src/providers/ethereum/networks/index.ts (1)
144-146: Export key naming: prefercotiTestnet(withoutNode) for consistencyMost keys are network names without the
Nodesuffix. Consider aligning this export to avoid surprise for consumers.- cotiTestnetNode: cotiTestnetNode, + cotiTestnet: cotiTestnetNode,
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (43)
.github/workflows/test-all.yml(1 hunks).github/workflows/test-swap.yml(1 hunks).nvmrc(1 hunks)Dockerfile(1 hunks)package.json(1 hunks)packages/extension-bridge/package.json(2 hunks)packages/extension/configs/vitest.config.mts(1 hunks)packages/extension/package.json(6 hunks)packages/extension/src/providers/common/libs/new-features.ts(1 hunks)packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts(1 hunks)packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts(1 hunks)packages/extension/src/providers/ethereum/networks/cagaAnkara.ts(0 hunks)packages/extension/src/providers/ethereum/networks/coti-devnet.ts(0 hunks)packages/extension/src/providers/ethereum/networks/coti-testnet.ts(1 hunks)packages/extension/src/providers/ethereum/networks/form-testnet.ts(0 hunks)packages/extension/src/providers/ethereum/networks/form.ts(0 hunks)packages/extension/src/providers/ethereum/networks/index.ts(6 hunks)packages/extension/src/providers/ethereum/networks/skale/chaos.ts(0 hunks)packages/extension/src/providers/ethereum/networks/skale/index.ts(0 hunks)packages/extension/src/providers/ethereum/networks/tac.ts(1 hunks)packages/extension/src/providers/ethereum/networks/zkgoerli.ts(0 hunks)packages/extension/src/providers/ethereum/networks/zksepolia.ts(1 hunks)packages/extension/src/providers/polkadot/networks/index.ts(0 hunks)packages/extension/src/providers/polkadot/networks/unique/opal.ts(0 hunks)packages/hw-wallets/package.json(3 hunks)packages/keyring/package.json(2 hunks)packages/name-resolution/package.json(3 hunks)packages/name-resolution/src/index.ts(2 hunks)packages/name-resolution/tests/resolver.test.ts(1 hunks)packages/name-resolution/tests/sid.test.ts(1 hunks)packages/request/package.json(2 hunks)packages/signers/bitcoin/package.json(2 hunks)packages/signers/ethereum/package.json(2 hunks)packages/signers/kadena/package.json(2 hunks)packages/signers/polkadot/package.json(2 hunks)packages/signers/polkadot/src/index.ts(1 hunks)packages/storage/package.json(2 hunks)packages/swap/package.json(2 hunks)packages/swap/src/common/estimateGasList.ts(0 hunks)packages/swap/src/index.ts(1 hunks)packages/types/package.json(2 hunks)packages/types/src/networks.ts(4 hunks)packages/utils/package.json(2 hunks)
💤 Files with no reviewable changes (10)
- packages/extension/src/providers/ethereum/networks/coti-devnet.ts
- packages/extension/src/providers/polkadot/networks/unique/opal.ts
- packages/swap/src/common/estimateGasList.ts
- packages/extension/src/providers/ethereum/networks/cagaAnkara.ts
- packages/extension/src/providers/ethereum/networks/form.ts
- packages/extension/src/providers/polkadot/networks/index.ts
- packages/extension/src/providers/ethereum/networks/skale/chaos.ts
- packages/extension/src/providers/ethereum/networks/form-testnet.ts
- packages/extension/src/providers/ethereum/networks/zkgoerli.ts
- packages/extension/src/providers/ethereum/networks/skale/index.ts
✅ Files skipped from review due to trivial changes (3)
- packages/name-resolution/tests/sid.test.ts
- .github/workflows/test-swap.yml
- .nvmrc
🚧 Files skipped from review as they are similar to previous changes (2)
- package.json
- packages/keyring/package.json
🧰 Additional context used
🧬 Code graph analysis (3)
packages/extension/src/providers/ethereum/networks/coti-testnet.ts (1)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)
packages/extension/src/providers/ethereum/networks/zksepolia.ts (1)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)
packages/extension/src/providers/ethereum/networks/tac.ts (2)
packages/extension/src/providers/ethereum/types/evm-network.ts (2)
EvmNetworkOptions(22-53)EvmNetwork(55-286)packages/extension/src/providers/ethereum/libs/activity-handlers/index.ts (1)
EtherscanActivity(10-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: buildAll
- GitHub Check: test
- GitHub Check: test
🔇 Additional comments (18)
packages/swap/package.json (2)
27-28: Solana libs: patch bumps look goodPatch updates for @solana/spl-token and @solana/web3.js are low risk and align with the broader dependency refresh. No further action from me here.
34-34: rango-sdk-basic bump: verify no breaking metadata or enum changes
Imports in packages/swap/src/providers/rango/index.ts. Confirm v0.1.71 didn’t alter RangoTransactionType or RoutingResultType values or supportedNetworkByRangoBlockchain mappings. Sanity-check swap flows on EVM and Solana and run existing Rango provider tests..github/workflows/test-all.yml (1)
12-12: Include hidden files in ripgrep search
Your rg invocation skipped the.githubfolder by default; rerun with-u(or--hidden) so all workflows are checked, e.g.:rg -u -nP '(node-version|setup-node)' -g '.github/workflows/**/*.yml'packages/hw-wallets/package.json (2)
28-29: Verify ESLint v9 compatibility with Airbnb base config
Ensureeslint-config-airbnb-base@^15.0.0’s peerDependencies support ESLint 9 and that your.eslintrc*inpackages/hw-wallets(and similar packages) correctly extends it via the compatibility layer or flat config per the ESLint 9 migration guide.
55-60: Patch bumps verified; no unmet peers or duplicate transports detected. Manual testing of WebUSB flows in Chromium-based browsers is still required.packages/extension/configs/vitest.config.mts (1)
18-19: Test globs look good.Patterns cover src and tests folders for .test/.spec TS files; no concerns.
packages/name-resolution/package.json (1)
25-28: Verify ESLint 9 compatibility with current plugins/config
- Current stack in packages/name-resolution:
- ESLint ^9.35.0
- eslint-config-airbnb-base ^15.0.0
- eslint-plugin-import ^2.32.0
- eslint-plugin-module-resolver ^1.5.0
- Ensure each package’s peerDependencies permit
eslint@^9(e.g.npm view eslint-plugin-import@2.32.0 peerDependencies); upgrade or replace any that don’t.- Legacy
.eslintrc.jsonremains supported in ESLint 9; migrating to Flat Config is optional.packages/name-resolution/src/index.ts (1)
5-5: Remove SIDResolver import and wiring in NameResolverIn packages/name-resolution/src/index.ts:
- Delete
import SIDResolver from "./sid";- Remove the
sid: SIDResolver;class property- Drop
this.sid = new SIDResolver(options.sid);from the constructor- Remove the commented
// this.sid.init(),line in theinitDonearraypackages/extension-bridge/package.json (1)
47-65: [Waiting for script results]packages/signers/kadena/package.json (1)
31-37: Dev deps bump LGTMNo runtime/API surface changes; safe to merge.
Also applies to: 46-48
packages/types/package.json (1)
27-43: No action needed:@massalabs/massa-web3is only in devDependencies
Verified no imports of@massalabs/massa-web3in the publishedpackages/types/srcsurface—keeping it as a devDependency is safe.packages/extension/src/providers/ethereum/networks/zksepolia.ts (1)
12-17: Resolve: Chain ID and WebSocket endpoint are correct
Chain ID 0x12c (300) and wss://sepolia.era.zksync.dev/ws match the official zkSync Era Sepolia documentation.packages/request/package.json (1)
34-49: Tooling bumps LGTMNo functional/runtime impact here.
packages/types/src/networks.ts (1)
182-183: CoinGecko slug “massa” is valid
Confirmed that CoinGecko recognizes the smart-contract platform with API id “massa”, so no changes are needed.packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts (1)
71-71: No changes needed for TAC explorer URL
TAC’s explorer is a custom Blockscout instance exposing the standard/apiendpoints, so activity fetching withEtherscanActivitywill work as is.packages/extension/package.json (1)
26-68: Verify major-version upgrades (Vite 7, ECharts 6, Vue 3.5, TS 5.9)
- CRX plugin (packages/extension/vite.config.ts:81) – confirm vite-plugin-crx options remain compatible under Vite 7.
- ECharts imports – code scan didn’t find direct
import 'echarts'or renderer usage; ensure vue-echarts@7.0.3 integration still works with echarts@6.- Vite config APIs –
optimizeDeps,build.rollupOptions, andpluginsremain valid in Vite 7 (config at lines 95–117).- TypeScript setup – verify tsconfig and any plugins handle TS 5.9 without regressions.
packages/extension/src/providers/common/libs/new-features.ts (1)
3-3: LGTM: TAC flagged as newThis matches the TAC additions elsewhere.
packages/extension/src/providers/ethereum/networks/tac.ts (1)
11-19: TAC network configuration verified
- chainID 0xEF (239) matches the official EVM chain ID
- RPC: primary https://rpc.tac.build (official) with fallback https://rpc.ankr.com/tac
- Explorer endpoints
/tx/[[txHash]]and/address/[[address]]align with the Blockscout instance (API docs at /explorer.tac.build/api_docs)- CoinGecko ID
tacexists for the main currency
| [NetworkNames.Sanko]: { | ||
| tbName: 'sanko', | ||
| tbName: '', | ||
| cgPlatform: CoingeckoPlatform.Sanko, | ||
| bsEndpoint: true, | ||
| }, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Sanko → Blockscout: drop unused tbName and confirm Blockscout mapping exists
Switching to bsEndpoint: true is good. Since MEW tbName is no longer used, remove the empty tbName to avoid accidental future use.
[NetworkNames.Sanko]: {
- tbName: '',
cgPlatform: CoingeckoPlatform.Sanko,
bsEndpoint: true,
},Run to confirm Sanko is supported in the Blockscout handler:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=$(fd -a 'blockscout.ts' packages/extension/src/providers/ethereum | head -n1)
echo "Blockscout file: $FILE"
rg -nC2 -e 'Sanko|sanko' "$FILE" || { echo "No Sanko mapping found in $FILE"; exit 1; }Length of output: 234
Add missing Blockscout mapping for Sanko and remove unused tbName
- In
packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts, drop the emptytbName: ''under theNetworkNames.Sankoentry. - In
packages/extension/src/providers/ethereum/libs/assets-handlers/blockscout.ts, add aNetworkNames.Sankomapping so thatbsEndpoint: trueresolves correctly (e.g. map to the appropriate “sanko” identifier).
🤖 Prompt for AI Agents
In
packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts
around lines 145-149, remove the unused empty property tbName: '' from the
NetworkNames.Sanko entry so the object only contains cgPlatform and bsEndpoint;
then in
packages/extension/src/providers/ethereum/libs/assets-handlers/blockscout.ts add
a mapping for NetworkNames.Sanko pointing to the correct Blockscout identifier
(e.g. "sanko" or the project's expected string) so bsEndpoint: true can resolve
correctly — update the exported mapping object, ensure imports/constants align,
and run type checks.
| import zkSepoliaNode from './zksepolia'; | ||
| import vicNode from './vic'; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Renames/removals: verify downstream references
You renamed zkGoerli→zkSepolia and replaced COTI devnet with testnet. Ensure no remaining imports/usages expect the old keys or removed networks.
Also applies to: 98-99
🏁 Script executed:
#!/bin/bash
# Find stale references to renamed/removed networks
rg -nP -C2 '\b(zkGoerli|cotiDevnet|skaleChaos|formTestnet|form|cagaAnkara)\b' -- \
packages apps configs src || trueLength of output: 6587
Rename remaining cotiDevnet references – packages/extension/src/providers/ethereum/networks/coti.ts lines 23–25 still define/export cotiDevnet; update the identifier and export to cotiTestnet to reflect the COTI testnet replacement. No stale zkGoerli references found.
🤖 Prompt for AI Agents
In packages/extension/src/providers/ethereum/networks/coti.ts around lines 23 to
25, the exported identifier is still named cotiDevnet; rename the identifier and
its export to cotiTestnet (and update any internal variable names) so the module
reflects the COTI testnet replacement, then update any imports/exports that
reference cotiDevnet (including
packages/extension/src/providers/ethereum/networks/index.ts) to use cotiTestnet.
| "@types/node": "^22.18.1", | ||
| "@typescript-eslint/eslint-plugin": "^8.43.0", | ||
| "@typescript-eslint/parser": "^8.43.0", | ||
| "eslint": "^9.35.0", |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Tooling bumped to ESLint 9 / @typescript-eslint 8 / TS 5.9 — engines.node is now too low
ESLint 9 and @typescript-eslint v8 require Node ≥18 (typically ≥18.18). tsup 8 also targets modern Node. Current engines.node (>=14.15.0) is misleading and will fail local/CI installs using engines-strict.
Update engines.node here (and align at repo root if needed):
- "engines": {
- "node": ">=14.15.0"
- },
+ "engines": {
+ "node": ">=18.18.0"
+ },Quick audit across the monorepo:
Also applies to: 55-56
🏁 Script executed:
#!/bin/bash
# List all declared Node engine constraints to spot inconsistencies
fd -H --full-path 'package.json' | while read -r f; do
nodeVal=$(jq -r '.engines.node // empty' "$f" 2>/dev/null)
if [ -n "$nodeVal" ]; then
echo "$f -> engines.node: $nodeVal"
fi
doneLength of output: 783
Bump engines.node to ≥18.18.0 across all package.json files
ESLint v9.x drops support for Node.js < 18.18.0 (requires ≥ 18.18.0) (eslint.org) and tsup v8 targets Node.js ≥ 18 (app.unpkg.com); every package currently declares >=14.15.0—update them (and the root) to >=18.18.0.
🤖 Prompt for AI Agents
In packages/swap/package.json around lines 42-45, the package.json currently
declares Node engine ">=14.15.0" while newer tool versions require Node
>=18.18.0; update the "engines.node" entry in this file to ">=18.18.0" (and
mirror the same change across all other package.json files including the
repository root) so ESLint/tsup and related tooling run on the supported Node
version; no other changes required beyond updating the engine specification and
committing the modified package.json files.
Summary by CodeRabbit
New Features
Tests
Chores