Skip to content

Commit 89fb017

Browse files
authored
Merge pull request #560 from enkryptcom/feat/delete-custom-tokens
Feat/delete custom tokens
2 parents 0a9c1db + 7e6b3b0 commit 89fb017

5 files changed

Lines changed: 123 additions & 7 deletions

File tree

packages/extension/src/libs/tokens-state/index.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class TokensState {
3535
if (
3636
t.type === TokenType.ERC20 &&
3737
(t as CustomErc20Token).address.toLowerCase() ===
38-
token.address.toLowerCase()
38+
token.address.toLowerCase()
3939
) {
4040
return false;
4141
}
@@ -54,6 +54,44 @@ export class TokensState {
5454
return true;
5555
}
5656

57+
/**
58+
* Remove a custom ERC20 token from a given network.
59+
* Returns `true` if the token was removed and false otherwise.
60+
* @param {NetworkNames} chainName - The name of the network the token is being removed from.
61+
* @param {string} address - The address of the token being removed.
62+
*/
63+
async removeErc20Token(
64+
chainName: NetworkNames,
65+
address: string,
66+
): Promise<boolean> {
67+
const state: IState | null = await this.storage.get(StorageKeys.customTokens);
68+
69+
if (state && state[chainName]) {
70+
const tokens = state[chainName];
71+
72+
for (let i = 0; i < tokens!.length; i++) {
73+
const token = tokens![i];
74+
75+
if (
76+
token.type === TokenType.ERC20 &&
77+
(token as CustomErc20Token).address.toLowerCase() ===
78+
address.toLowerCase()
79+
) {
80+
tokens!.splice(i, 1);
81+
82+
if (tokens!.length === 0) {
83+
delete state[chainName];
84+
}
85+
86+
await this.storage.set(StorageKeys.customTokens, state);
87+
return true;
88+
}
89+
}
90+
}
91+
92+
return false;
93+
}
94+
5795
async getTokensByNetwork(chainName: NetworkNames): Promise<CustomToken[]> {
5896
const state: IState | null = await this.storage.get(
5997
StorageKeys.customTokens,

packages/extension/src/providers/ethereum/types/evm-network.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export class EvmNetwork extends BaseNetwork {
157157
decimals: this.decimals,
158158
sparkline: nativeMarketData
159159
? new Sparkline(nativeMarketData.sparkline_in_24h.price, 25)
160-
.dataValues
160+
.dataValues
161161
: '',
162162
priceChangePercentage:
163163
nativeMarketData?.price_change_percentage_24h_in_currency ?? 0,
@@ -197,7 +197,6 @@ export class EvmNetwork extends BaseNetwork {
197197

198198
assets = [nativeAsset, ...assetInfos];
199199
}
200-
201200
const customTokens = await tokensState
202201
.getTokensByNetwork(this.name)
203202
.then(tokens => {
@@ -211,7 +210,7 @@ export class EvmNetwork extends BaseNetwork {
211210
a.contract &&
212211
(token as CustomErc20Token).address &&
213212
a.contract.toLowerCase() ===
214-
(token as CustomErc20Token).address.toLowerCase()
213+
(token as CustomErc20Token).address.toLowerCase()
215214
) {
216215
return false;
217216
}

packages/extension/src/ui/action/views/asset-detail-view/index.vue

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,24 @@
5252
</h4>
5353
<p>${{ token.balanceUSDf }}</p>
5454
</div>
55+
<div class="asset-detail-view__token-divider" v-if="isCustomToken" />
56+
<div class="asset-detail-view__action" v-if="isCustomToken">
57+
<base-button
58+
title="Delete custom token"
59+
:red="true"
60+
:click="removeToken"
61+
/>
62+
<span class="label"
63+
>*Deleting custom token deletes it for the whole network.</span
64+
>
65+
</div>
5566
</div>
5667
</div>
5768
</template>
5869

5970
<script setup lang="ts">
6071
import { PropType, ref } from 'vue';
72+
import BaseButton from '@action/components/base-button/index.vue';
6173
import CloseIcon from '@action/icons/common/close-icon.vue';
6274
import SparklineUp from '@action/icons/asset/sparkline-up.vue';
6375
import SparklineDown from '@action/icons/asset/sparkline-down.vue';
@@ -68,12 +80,19 @@ import { SVGRenderer } from 'echarts/renderers';
6880
import { LineChart } from 'echarts/charts';
6981
import { TooltipComponent, GridComponent } from 'echarts/components';
7082
import VChart from 'vue-echarts';
71-
7283
const props = defineProps({
7384
token: {
7485
type: Object as PropType<AssetsType>,
7586
default: () => ({}),
7687
},
88+
isCustomToken: {
89+
type: Boolean,
90+
default: false,
91+
},
92+
removeToken: {
93+
type: Function,
94+
default: () => {},
95+
},
7796
});
7897
use([SVGRenderer, LineChart, TooltipComponent, GridComponent]);
7998
const option = ref({
@@ -307,6 +326,11 @@ const close = () => {
307326
&__action {
308327
margin: 0 0 -12px -12px;
309328
width: calc(~'100% + 24px');
329+
text-align: center;
330+
331+
.label {
332+
color: @secondaryLabel;
333+
}
310334
}
311335
}
312336
</style>

packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,17 @@
5151
<asset-detail-view
5252
v-if="isDetail"
5353
:token="token"
54+
:network="network"
55+
:is-custom-token="isCustomToken"
56+
:remove-token="removeToken"
5457
@close:popup="toggleDetail"
5558
/>
5659
</template>
5760

5861
<script setup lang="ts">
59-
import { PropType, ref } from 'vue';
62+
import { PropType, ref, computed, onMounted } from 'vue';
63+
import { CustomErc20Token } from '@/libs/tokens-state/types.ts';
64+
import { BaseNetwork } from '@/types/base-network';
6065
import SparklineUp from '@action/icons/asset/sparkline-up.vue';
6166
import SparklineDown from '@action/icons/asset/sparkline-down.vue';
6267
import AssetDetailView from '@action/views/asset-detail-view/index.vue';
@@ -66,6 +71,7 @@ import { use } from 'echarts/core';
6671
import { SVGRenderer } from 'echarts/renderers';
6772
import { LineChart } from 'echarts/charts';
6873
import { TooltipComponent, GridComponent } from 'echarts/components';
74+
import { TokensState } from '@/libs/tokens-state';
6975
import VChart from 'vue-echarts';
7076
7177
const isDetail = ref(false);
@@ -75,6 +81,10 @@ const props = defineProps({
7581
type: Object as PropType<AssetsType>,
7682
default: () => ({}),
7783
},
84+
network: {
85+
type: Object as PropType<BaseNetwork>,
86+
default: () => ({}),
87+
},
7888
});
7989
use([SVGRenderer, LineChart, TooltipComponent, GridComponent]);
8090
@@ -120,6 +130,48 @@ const option = ref({
120130
],
121131
});
122132
133+
const customTokens = ref<CustomErc20Token[]>([]);
134+
135+
const tokenState = new TokensState();
136+
const fetchCustomTokens = async () => {
137+
try {
138+
return await tokenState.getTokensByNetwork(props.network.name).then(res => {
139+
customTokens.value = res.filter(
140+
(token): token is CustomErc20Token => 'address' in token,
141+
);
142+
});
143+
} catch {
144+
customTokens.value = [];
145+
}
146+
};
147+
148+
onMounted(async () => {
149+
await fetchCustomTokens();
150+
});
151+
152+
const isCustomToken = computed(() => {
153+
if (!props.token.contract) return false;
154+
return customTokens.value.some(
155+
token =>
156+
token.address.toLowerCase() === props.token.contract?.toLowerCase(),
157+
);
158+
});
159+
160+
const emit = defineEmits<{
161+
(e: 'update:tokens'): void;
162+
}>();
163+
164+
const removeToken = () => {
165+
if (props.token.contract) {
166+
tokenState
167+
.removeErc20Token(props.network.name, props.token.contract)
168+
.then(() => {
169+
isDetail.value = !isDetail.value;
170+
emit('update:tokens');
171+
});
172+
}
173+
};
174+
123175
const toggleDetail = () => {
124176
isDetail.value = !isDetail.value;
125177
};

packages/extension/src/ui/action/views/network-assets/index.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
v-for="(item, index) in assets"
1919
:key="index"
2020
:token="item"
21+
:network="network"
22+
@update:tokens="updateAssets"
2123
></network-assets-item>
2224
<div
2325
v-show="network.customTokens && assets.length !== 0"
@@ -145,7 +147,8 @@ const addCustomAsset = (asset: AssetsType) => {
145147
});
146148
147149
if (!existingAsset) {
148-
assets.value = [...assets.value, asset];
150+
// refetches assets to update the custom token
151+
updateAssets();
149152
}
150153
};
151154
</script>

0 commit comments

Comments
 (0)