Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/extension/blocked.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="">

<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>Enkrypt Extension - Everything in the blockchain made easy</title>
</head>

<body>
<noscript>
<strong>We're sorry but Enkrypt doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/ui/blocked/main.ts"></script>
</body>

</html>
12 changes: 5 additions & 7 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@
"private": true,
"type": "module",
"scripts": {
"dev": "yarn prebuild && cross-env BROWSER='chrome' vite",
"dev": "cross-env BROWSER='chrome' vite",
"build2": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --fix && yarn format",
"format": "prettier --write src/",
"zip": "cd dist; zip -r release.zip *;",
"prebuild": "yarn kadena:prebuild",
"build:chrome": "yarn prebuild && cross-env BROWSER='chrome' MINIFY='true' vite build",
"build:firefox": "yarn prebuild && cross-env BROWSER='firefox' MINIFY='true' vite build && node configs/get-system-info.js",
"build:opera": "yarn prebuild && cross-env BROWSER='opera' MINIFY='true' vite build",
"kadena:prebuild": "pactjs contract-generate --contract=coin --api https://api.chainweb.com/chainweb/0.0/mainnet01/chain/1/pact",
"build:chrome": "cross-env BROWSER='chrome' MINIFY='true' vite build",
"build:firefox": "cross-env BROWSER='firefox' MINIFY='true' vite build && node configs/get-system-info.js",
"build:opera": "cross-env BROWSER='opera' MINIFY='true' vite build",
"test": "vitest run -c ./configs/vitest.config.mts",
"watch": "yarn dev",
"watch:chrome": "yarn dev",
"watch:firefox": "yarn prebuild && cross-env BROWSER='firefox' vite"
"watch:firefox": "cross-env BROWSER='firefox' vite"
},
"dependencies": {
"@amplitude/analytics-browser": "^2.25.0",
Expand Down
20 changes: 20 additions & 0 deletions packages/extension/src/libs/utils/providersDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ProviderName, ProviderNameProper } from "@enkryptcom/swap/src/types"

import changellyLogo from '@/ui/action/assets/swap/changelly-logo.png'
import oneInch from '@/ui/action/assets/swap/1inch-logo.png'
import paraswap from '@/ui/action/assets/swap/paraswap-logo.png'
import zerox from '@/ui/action/assets/swap/0x-logo.png'
import rango from '@/ui/action/assets/swap/rango-logo.png'
import jupiter from '@/ui/action/assets/swap/jupiter-logo.png'
import okx from '@/ui/action/assets/swap/okx-logo.png'

export default {
[ProviderName.changelly]: { name: ProviderNameProper.changelly, logo: changellyLogo },
[ProviderName.oneInch]: { name: ProviderNameProper.oneInch, logo: oneInch },
[ProviderName.oneInchFusion]: { name: ProviderNameProper.oneInchFusion, logo: oneInch },
[ProviderName.paraswap]: { name: ProviderNameProper.paraswap, logo: paraswap },
[ProviderName.zerox]: { name: ProviderNameProper.zerox, logo: zerox },
[ProviderName.rango]: { name: ProviderNameProper.rango, logo: rango },
[ProviderName.jupiter]: { name: ProviderNameProper.jupiter, logo: jupiter },
[ProviderName.okx]: { name: ProviderNameProper.okx, logo: okx }
}
Comment on lines +11 to +20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add type annotation for better type safety.

The exported object lacks a type annotation, which reduces type safety when accessing provider details elsewhere in the codebase. This makes it easier for runtime errors to occur when accessing non-existent properties.

Add a typed interface and annotation:

+interface ProviderDetails {
+  name: string;
+  logo: string;
+}
+
+const providersDetails: Record<ProviderName, ProviderDetails> = {
-export default {
   [ProviderName.changelly]: { name: ProviderNameProper.changelly, logo: changellyLogo },
   [ProviderName.oneInch]: { name: ProviderNameProper.oneInch, logo: oneInch },
   [ProviderName.oneInchFusion]: { name: ProviderNameProper.oneInchFusion, logo: oneInch },
   [ProviderName.paraswap]: { name: ProviderNameProper.paraswap, logo: paraswap },
   [ProviderName.zerox]: { name: ProviderNameProper.zerox, logo: zerox },
   [ProviderName.rango]: { name: ProviderNameProper.rango, logo: rango },
   [ProviderName.jupiter]: { name: ProviderNameProper.jupiter, logo: jupiter },
   [ProviderName.okx]: { name: ProviderNameProper.okx, logo: okx }
-}
+};
+
+export default providersDetails;

This provides compile-time checking that all ProviderName enum values are present in the mapping.

🤖 Prompt for AI Agents
In packages/extension/src/libs/utils/providersDetails.ts around lines 11-20, the
exported providers object has no type annotation; add a strong type by defining
a ProviderDetail interface (e.g. { name: string; logo: string |
StaticImageImport } or the correct logo type) and then type the export as
Record<ProviderName, ProviderDetail> (or an equivalent mapped type), import the
ProviderName/ProviderNameProper types as needed, and change the default export
declaration to use that type so the compiler enforces that every ProviderName
key is present and values have the correct shape.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions packages/extension/src/ui/action/icons/actions/mnemonic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#444"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="6" y="3" width="12" height="18" rx="2" ry="2" />
<path d="M9 3.5V2.8C9 2.36 9.36 2 9.8 2h4.4c.44 0 .8.36.8.8v.7" />
<rect x="9" y="3" width="6" height="2.8" rx="0.6" ry="0.6" fill="#fff" />
<path d="M9 9h6M9 13h4M9 17h3" stroke="#888" />
</svg>
</template>
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
<template>
<a class="best-offer-list-item" @click="select">
<div>
<img
v-if="providersDetails[props.provider]"
:src="providersDetails[props.provider].logo"
/>
Comment on lines +4 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Image element should be accessible with alt text.

The provider logo image lacks an alt attribute, which is important for accessibility and should describe the image content.

Add an alt attribute:

       <img
         v-if="providersDetails[props.provider]"
         :src="providersDetails[props.provider].logo"
+        :alt="`${providersDetails[props.provider].name} logo`"
       />
🤖 Prompt for AI Agents
In
packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list-item.vue
around lines 4-7, the <img> lacks an alt attribute; add a bound alt so the image
is accessible by using the provider's name when available or an empty string if
decorative (for example bind :alt="providersDetails[props.provider]?.name ||
''"), keeping the existing v-if check and src binding intact.

</div>
<div class="best-offer-list-item__info">
<p>Offer {{ swapNumber }}</p>
<p>
{{
props.provider
? providersDetails[props.provider].name
: 'Unknown Provider'
}}
</p>
Comment on lines +10 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential runtime error when accessing provider details.

The code checks props.provider existence but doesn't verify that providersDetails[props.provider] exists before accessing .name. If a provider key exists in ProviderName but is missing from providersDetails, this will throw a runtime error.

Apply defensive coding to handle missing provider details:

       <p>
         {{
           props.provider
-            ? providersDetails[props.provider].name
+            ? providersDetails[props.provider]?.name || 'Unknown Provider'
             : 'Unknown Provider'
         }}
       </p>

Alternatively, consolidate the logic:

-      <p>
-        {{
-          props.provider
-            ? providersDetails[props.provider].name
-            : 'Unknown Provider'
-        }}
-      </p>
+      <p>
+        {{ providersDetails[props.provider]?.name || 'Unknown Provider' }}
+      </p>
📝 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.

Suggested change
<p>
{{
props.provider
? providersDetails[props.provider].name
: 'Unknown Provider'
}}
</p>
<p>
{{
props.provider
? providersDetails[props.provider]?.name || 'Unknown Provider'
: 'Unknown Provider'
}}
</p>
Suggested change
<p>
{{
props.provider
? providersDetails[props.provider].name
: 'Unknown Provider'
}}
</p>
<p>
{{ providersDetails[props.provider]?.name || 'Unknown Provider' }}
</p>
🤖 Prompt for AI Agents
In
packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list-item.vue
around lines 10–16, the template accesses providersDetails[props.provider].name
without ensuring providersDetails[props.provider] exists, which can throw at
runtime; update the rendering to guard the lookup (e.g., use optional chaining
or an explicit check) and fall back to 'Unknown Provider' when
providersDetails[props.provider] is undefined or name is missing, or consolidate
into a single evaluated value like providerName =
providersDetails[props.provider]?.name ?? 'Unknown Provider' and render that.

<h5>{{ amount }}</h5>
</div>

Expand All @@ -19,14 +31,23 @@
import DoneIcon from '@action/icons/common/done_icon.vue';
import LottieStatusJson from '@action/assets/animation/status.json';
import { Vue3Lottie } from 'vue3-lottie';
import { ProviderName } from '@enkryptcom/swap/src/types';
import providersDetails from '@/libs/utils/providersDetails';
import { PropType } from 'vue';

defineProps({
const props = defineProps({
select: {
type: Function as () => void,
type: Function as PropType<() => void>,
default: () => {
return null;
},
},
provider: {
type: String as PropType<ProviderName>,
default: () => {
return '';
},
},
swapNumber: {
type: Number,
default: () => {
Expand Down Expand Up @@ -60,7 +81,7 @@ defineProps({
.best-offer-list-item {
height: 56px;
width: 100%;
padding: 8px 12px;
padding: 8px 4px;
box-sizing: border-box;
display: flex;
justify-content: flex-start;
Expand All @@ -77,8 +98,7 @@ defineProps({
}

img {
width: 32px;
height: 32px;
width: 20px;
margin-right: 8px;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
v-for="(trade, index) in trades"
:key="trade.provider"
:swap-number="index + 1"
:provider="trade.provider"
:amount="`~${getReadable(index)}`"
:select="() => select(trade)"
:is-checked="trade.provider === pickedTrade.provider"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<template>
<div class="swap-best-offer-block">
<h3>Best offer including network fee</h3>
<h3>
Best offer including network fee powered by
<img :src="providersDetails[props.pickedTrade.provider].logo" />
{{ providersDetails[props.pickedTrade.provider].name }}
</h3>
Comment on lines +3 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add defensive checks for provider details access.

The code directly accesses providersDetails[props.pickedTrade.provider] without verifying that the provider exists in the mapping. This could cause runtime errors if an unexpected provider value is encountered or if the mapping is incomplete.

Add defensive checks or fallbacks:

 <h3>
   Best offer including network fee powered by
-  <img :src="providersDetails[props.pickedTrade.provider].logo" />
-  {{ providersDetails[props.pickedTrade.provider].name }}
+  <img :src="providersDetails[props.pickedTrade.provider]?.logo" />
+  {{ providersDetails[props.pickedTrade.provider]?.name || props.pickedTrade.provider }}
 </h3>

And similarly for lines 50-54:

 <p>
   Provider:
   <img
     height="15px"
-    :src="providersDetails[props.pickedTrade.provider].logo"
+    :src="providersDetails[props.pickedTrade.provider]?.logo"
   />
-  {{ providersDetails[props.pickedTrade.provider].name }}
+  {{ providersDetails[props.pickedTrade.provider]?.name || props.pickedTrade.provider }}
 </p>

Also applies to: 48-55

🤖 Prompt for AI Agents
In
packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/index.vue
around lines 3-7 and 48-55, the template directly indexes
providersDetails[props.pickedTrade.provider] which can throw if the provider key
is missing; change this to resolve providerDetail safely (e.g., create a
computed getter that reads providersDetails[props.pickedTrade.provider] with a
fallback empty object or default { logo: defaultLogo, name: 'Unknown provider'
}) and use that computed value in the template (or use optional chaining and
nullish coalescing) so the img src and displayed name always have safe fallbacks
and runtime errors are prevented.

<div class="swap-best-offer-block__for">
for<img :src="fromToken.logoURI" />
<p>
Expand Down Expand Up @@ -41,6 +45,14 @@
/>
</div>
<div class="swap-best-offer-block__info">
<p>
Provider:
<img
height="15px"
:src="providersDetails[props.pickedTrade.provider].logo"
/>
{{ providersDetails[props.pickedTrade.provider].name }}
</p>
<p>
Rate: 1 {{ fromToken.symbol.toUpperCase() }} ≈
{{ $filters.formatFloatingPointValue(ratio).value }}
Expand Down Expand Up @@ -89,6 +101,7 @@ import {
SwapToken,
} from '@enkryptcom/swap';
import { imageLoadError } from '@/ui/action/utils/misc';
import providersDetails from '@/libs/utils/providersDetails';

interface SwapBestOfferProps {
trades: ProviderSwapResponse[];
Expand Down Expand Up @@ -178,6 +191,11 @@ const toggleOffers = () => {
letter-spacing: 0.15px;
color: @primaryLabel;
margin: 0 0 8px 0;

img {
margin-left: 2px;
width: 20px;
}
}

&__for {
Expand Down
122 changes: 122 additions & 0 deletions packages/extension/src/ui/blocked/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<template>
<div class="blocked__container">
<logo class="blocked__logo" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Missing import for logo component.

The template uses <logo> at line 3, but there is no corresponding import in the script section (line 10 is empty). This will cause a runtime error when the component tries to render.

Add the logo import to the script section:

-<script setup lang="ts"></script>
+<script setup lang="ts">
+import Logo from '@action/icons/common/logo.vue';
+</script>

Note: Verify the correct path for the logo component in your codebase.

📝 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.

Suggested change
<logo class="blocked__logo" />
<template>
<div class="blocked__container">
<logo class="blocked__logo" />
<router-view />
</div>
</template>
<script setup lang="ts">
import Logo from '@action/icons/common/logo.vue';
</script>
<style lang="less" scoped>
/* styles remain unchanged */
</style>
🤖 Prompt for AI Agents
In packages/extension/src/ui/blocked/App.vue around line 3 (template) and the
empty script area at line 10, the <logo> component is used but not
imported/registered; add an import for the Logo component using the correct
relative path and register it in the component's export (either via the
components object in the default export or via setup registration for
composition API) so the <logo> tag resolves at runtime.

<div class="blocked__wrap">
<router-view />
</div>
</div>
</template>

<script setup lang="ts"></script>

<style lang="less">
@import '@action/styles/theme.less';
@import (css)
url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap');

body {
width: 100vw;
height: 100vh;
margin: 0;
overflow: hidden;
font-size: 0;
font-family: 'Roboto', sans-serif;
overflow-y: auto;
}

.blocked {
&__logo {
position: absolute;
left: 32px;
top: 24px;
}

&__back {
position: absolute;
top: 8px;
left: 8px;
border-radius: 8px;
cursor: pointer;
padding: 8px;
transition: background 300ms ease-in-out;

&:hover {
background: @black007;
}
}

&__container {
background-color: @lightBg;
width: 100vw;
height: 100vh;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
min-height: 700px;
}

&__wrap {
width: 460px;
height: 650px;
background: @white;
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.16);
border-radius: 12px;
padding: 40px;
box-sizing: border-box;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
overflow: hidden;

&--ready {
background: transparent;
box-shadow: none;
}

&--auto-height {
height: auto;
max-height: 600px;
}
}

&__info {
position: absolute;
right: 8px;
top: 8px;
background: @tip;
border: 1px solid rgba(0, 0, 0, 0.1);
width: 301px;
height: 96px;
border-radius: 10px;
padding: 12px 20px;
box-sizing: border-box;

h4 {
font-style: normal;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: @primaryLabel;
margin: 0;
}

p {
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: @black07;
margin: 0;
}
}

&__online {
width: 16px;
height: 16px;
}
}
</style>
Loading
Loading