Skip to content

Commit

Permalink
Merge pull request #560 from enkryptcom/feat/delete-custom-tokens
Browse files Browse the repository at this point in the history
Feat/delete custom tokens
  • Loading branch information
gamalielhere authored Nov 26, 2024
2 parents 0a9c1db + 7e6b3b0 commit 89fb017
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 7 deletions.
40 changes: 39 additions & 1 deletion packages/extension/src/libs/tokens-state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class TokensState {
if (
t.type === TokenType.ERC20 &&
(t as CustomErc20Token).address.toLowerCase() ===
token.address.toLowerCase()
token.address.toLowerCase()
) {
return false;
}
Expand All @@ -54,6 +54,44 @@ export class TokensState {
return true;
}

/**
* Remove a custom ERC20 token from a given network.
* Returns `true` if the token was removed and false otherwise.
* @param {NetworkNames} chainName - The name of the network the token is being removed from.
* @param {string} address - The address of the token being removed.
*/
async removeErc20Token(
chainName: NetworkNames,
address: string,
): Promise<boolean> {
const state: IState | null = await this.storage.get(StorageKeys.customTokens);

if (state && state[chainName]) {
const tokens = state[chainName];

for (let i = 0; i < tokens!.length; i++) {
const token = tokens![i];

if (
token.type === TokenType.ERC20 &&
(token as CustomErc20Token).address.toLowerCase() ===
address.toLowerCase()
) {
tokens!.splice(i, 1);

if (tokens!.length === 0) {
delete state[chainName];
}

await this.storage.set(StorageKeys.customTokens, state);
return true;
}
}
}

return false;
}

async getTokensByNetwork(chainName: NetworkNames): Promise<CustomToken[]> {
const state: IState | null = await this.storage.get(
StorageKeys.customTokens,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class EvmNetwork extends BaseNetwork {
decimals: this.decimals,
sparkline: nativeMarketData
? new Sparkline(nativeMarketData.sparkline_in_24h.price, 25)
.dataValues
.dataValues
: '',
priceChangePercentage:
nativeMarketData?.price_change_percentage_24h_in_currency ?? 0,
Expand Down Expand Up @@ -197,7 +197,6 @@ export class EvmNetwork extends BaseNetwork {

assets = [nativeAsset, ...assetInfos];
}

const customTokens = await tokensState
.getTokensByNetwork(this.name)
.then(tokens => {
Expand All @@ -211,7 +210,7 @@ export class EvmNetwork extends BaseNetwork {
a.contract &&
(token as CustomErc20Token).address &&
a.contract.toLowerCase() ===
(token as CustomErc20Token).address.toLowerCase()
(token as CustomErc20Token).address.toLowerCase()
) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,24 @@
</h4>
<p>${{ token.balanceUSDf }}</p>
</div>
<div class="asset-detail-view__token-divider" v-if="isCustomToken" />
<div class="asset-detail-view__action" v-if="isCustomToken">
<base-button
title="Delete custom token"
:red="true"
:click="removeToken"
/>
<span class="label"
>*Deleting custom token deletes it for the whole network.</span
>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { PropType, ref } from 'vue';
import BaseButton from '@action/components/base-button/index.vue';
import CloseIcon from '@action/icons/common/close-icon.vue';
import SparklineUp from '@action/icons/asset/sparkline-up.vue';
import SparklineDown from '@action/icons/asset/sparkline-down.vue';
Expand All @@ -68,12 +80,19 @@ import { SVGRenderer } from 'echarts/renderers';
import { LineChart } from 'echarts/charts';
import { TooltipComponent, GridComponent } from 'echarts/components';
import VChart from 'vue-echarts';
const props = defineProps({
token: {
type: Object as PropType<AssetsType>,
default: () => ({}),
},
isCustomToken: {
type: Boolean,
default: false,
},
removeToken: {
type: Function,
default: () => {},
},
});
use([SVGRenderer, LineChart, TooltipComponent, GridComponent]);
const option = ref({
Expand Down Expand Up @@ -307,6 +326,11 @@ const close = () => {
&__action {
margin: 0 0 -12px -12px;
width: calc(~'100% + 24px');
text-align: center;
.label {
color: @secondaryLabel;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,17 @@
<asset-detail-view
v-if="isDetail"
:token="token"
:network="network"
:is-custom-token="isCustomToken"
:remove-token="removeToken"
@close:popup="toggleDetail"
/>
</template>

<script setup lang="ts">
import { PropType, ref } from 'vue';
import { PropType, ref, computed, onMounted } from 'vue';
import { CustomErc20Token } from '@/libs/tokens-state/types.ts';
import { BaseNetwork } from '@/types/base-network';
import SparklineUp from '@action/icons/asset/sparkline-up.vue';
import SparklineDown from '@action/icons/asset/sparkline-down.vue';
import AssetDetailView from '@action/views/asset-detail-view/index.vue';
Expand All @@ -66,6 +71,7 @@ import { use } from 'echarts/core';
import { SVGRenderer } from 'echarts/renderers';
import { LineChart } from 'echarts/charts';
import { TooltipComponent, GridComponent } from 'echarts/components';
import { TokensState } from '@/libs/tokens-state';
import VChart from 'vue-echarts';
const isDetail = ref(false);
Expand All @@ -75,6 +81,10 @@ const props = defineProps({
type: Object as PropType<AssetsType>,
default: () => ({}),
},
network: {
type: Object as PropType<BaseNetwork>,
default: () => ({}),
},
});
use([SVGRenderer, LineChart, TooltipComponent, GridComponent]);
Expand Down Expand Up @@ -120,6 +130,48 @@ const option = ref({
],
});
const customTokens = ref<CustomErc20Token[]>([]);
const tokenState = new TokensState();
const fetchCustomTokens = async () => {
try {
return await tokenState.getTokensByNetwork(props.network.name).then(res => {
customTokens.value = res.filter(
(token): token is CustomErc20Token => 'address' in token,
);
});
} catch {
customTokens.value = [];
}
};
onMounted(async () => {
await fetchCustomTokens();
});
const isCustomToken = computed(() => {
if (!props.token.contract) return false;
return customTokens.value.some(
token =>
token.address.toLowerCase() === props.token.contract?.toLowerCase(),
);
});
const emit = defineEmits<{
(e: 'update:tokens'): void;
}>();
const removeToken = () => {
if (props.token.contract) {
tokenState
.removeErc20Token(props.network.name, props.token.contract)
.then(() => {
isDetail.value = !isDetail.value;
emit('update:tokens');
});
}
};
const toggleDetail = () => {
isDetail.value = !isDetail.value;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
v-for="(item, index) in assets"
:key="index"
:token="item"
:network="network"
@update:tokens="updateAssets"
></network-assets-item>
<div
v-show="network.customTokens && assets.length !== 0"
Expand Down Expand Up @@ -145,7 +147,8 @@ const addCustomAsset = (asset: AssetsType) => {
});
if (!existingAsset) {
assets.value = [...assets.value, asset];
// refetches assets to update the custom token
updateAssets();
}
};
</script>
Expand Down

0 comments on commit 89fb017

Please sign in to comment.