diff --git a/package-lock.json b/package-lock.json
index 9cd2692d7290ab8d07921914adbce87e59ec7deb..0207babf78d91f7381ae832cb146824968f45f86 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "cesium",
-  "version": "2.0.0-alpha43",
+  "version": "2.0.0-alpha45",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cesium",
-      "version": "2.0.0-alpha43",
+      "version": "2.0.0-alpha45",
       "license": "AGPL-3.0",
       "dependencies": {
         "@angular/animations": "^18.2.13",
@@ -131,8 +131,8 @@
         "typescript": "~5.4.5"
       },
       "engines": {
-        "node": ">= 18.18.2",
-        "npm": ">= 9.9.1",
+        "node": ">= 20.17.2",
+        "npm": ">= 10.7.0",
         "yarn": ">= 1.22.19"
       },
       "peerDependencies": {
diff --git a/package.json b/package.json
index 51a8005373ac2f71178782ee057d942999f6cf95..5ee1393694f904a745508cfac79c17baf8f15ff0 100644
--- a/package.json
+++ b/package.json
@@ -213,8 +213,8 @@
     "typescript": "~5.4.5"
   },
   "engines": {
-    "node": ">= 18.18.2",
-    "npm": ">= 9.9.1",
+    "node": ">= 20.17.0",
+    "npm": ">= 10.7.0",
     "yarn": ">= 1.22.19"
   }
 }
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 034a1ff69efbe215a16f01e80e27017928f69c8e..66291e14b1af895427bd7267c48398354be0fa47 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -41,7 +41,9 @@
   @if (item.divider) {
     <!-- divider -->
     <ion-item-divider class="{{ item.cssClass }} {{ item.color }}" @fadeInAnimation>
-      <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+      @if (item.icon) {
+        <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+      }
       @if (item.cssClass !== 'flex-spacer') {
         <ion-label [color]="item.color">{{ item.title | translate }}</ion-label>
       }
@@ -58,7 +60,9 @@
           detail="false"
           routerLinkActive="selected"
         >
-          <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+          @if (item.icon) {
+            <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+          }
           <ion-label [color]="item.color">{{ item.title | translate }}</ion-label>
         </ion-item>
       } @else if (item.handle && (!item.visible || item.visible())) {
@@ -73,7 +77,9 @@
           tappable
           @fadeInAnimation
         >
-          <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+          @if (item.icon) {
+            <ion-icon slot="start" [color]="item.color" [ios]="item.icon + '-outline'" [md]="item.icon + '-sharp'"></ion-icon>
+          }
           <ion-label [color]="item.color">{{ item.title | translate }}</ion-label>
         </ion-item>
       }
diff --git a/src/app/home/feed/feed.component.ts b/src/app/home/feed/feed.component.ts
index 83776f320afbd68b0693d46a44a43018777bef9e..aff86675b2ebc34a2c147810347feae7b7588659 100644
--- a/src/app/home/feed/feed.component.ts
+++ b/src/app/home/feed/feed.component.ts
@@ -37,9 +37,8 @@ export class FeedComponent extends AppPage<FeedState> {
 
   protected async ngOnLoad(): Promise<FeedState> {
     await Promise.all([this.settings.ready(), this.networkService.ready()]);
-    console.log(await this.settings);
-    const feedUrl = environment.feed.jsonFeed.get(this.settings.locale);
-    this.topics = await this.networkService.loadJsonFeed(feedUrl);
+    const feedUrls = environment.feed?.jsonFeed[this.settings.locale];
+    this.topics = await this.networkService.loadJsonFeedUrls(feedUrls);
     this.topics = this.topics.filter(isNotNil).map((value) => value);
     return <FeedState>{ topics: this.topics };
   }
diff --git a/src/app/home/feed/feed.module.ts b/src/app/home/feed/feed.module.ts
index 5c4fa3fd2ea09800035af0a3a2929bdf143f5343..f0c386d8ecd3f4d539149c56fb55de5ff2b539d2 100644
--- a/src/app/home/feed/feed.module.ts
+++ b/src/app/home/feed/feed.module.ts
@@ -1,24 +1,11 @@
 import { NgModule } from '@angular/core';
 import { AppSharedModule } from '@app/shared/shared.module';
 import { TranslateModule } from '@ngx-translate/core';
-import { HomePageRoutingModule } from '@app/home/home-routing.module';
-import { AppAuthModule } from '@app/account/auth/auth.module';
-import { AppRegisterModule } from '@app/account/register/register.module';
-import { AppTransferModule } from '@app/transfer/send/transfer.module';
 import { FeedComponent } from '@app/home/feed/feed.component';
-import { NgOptimizedImage } from '@angular/common';
 
 @NgModule({
-  imports: [
-    AppSharedModule,
-    TranslateModule.forChild(),
-    HomePageRoutingModule,
-    AppAuthModule,
-    AppRegisterModule,
-    AppTransferModule,
-    NgOptimizedImage,
-  ],
+  imports: [AppSharedModule, TranslateModule.forChild()],
   declarations: [FeedComponent],
-  exports: [FeedComponent],
+  exports: [FeedComponent, TranslateModule],
 })
 export class FeedModule {}
diff --git a/src/app/network/network.service.ts b/src/app/network/network.service.ts
index dbc8f9f635fef3c4ee949542997989359c8f7166..1c668c72ecceea24b927b9432a7800f0f308792a 100644
--- a/src/app/network/network.service.ts
+++ b/src/app/network/network.service.ts
@@ -6,9 +6,9 @@ import { abbreviate, WELL_KNOWN_CURRENCIES } from '@app/shared/currencies';
 import { Currency } from '../currency/currency.model';
 import { RxStartableService } from '@app/shared/services/rx-startable-service.class';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
-import { firstValueFrom, mergeMap, Observable, tap, timer } from 'rxjs';
-import { filter, map } from 'rxjs/operators';
-import { arrayRandomPick, isNil, isNotNil, isNotNilOrBlank, toNumber } from '@app/shared/functions';
+import { EMPTY, firstValueFrom, mergeMap, Observable, race, tap } from 'rxjs';
+import { catchError, filter, map } from 'rxjs/operators';
+import { arrayRandomPick, isEmptyArray, isNil, isNotNil, isNotNilOrBlank, toNumber } from '@app/shared/functions';
 import { IndexerService } from './indexer/indexer.service';
 import { fromDateISOString } from '@app/shared/dates';
 import { ContextService } from '@app/shared/services/storage/context.service';
@@ -18,7 +18,8 @@ import { environment } from '@environments/environment';
 import moment from 'moment';
 import DiscourseAPI from 'discourse2';
 import { JsonFeedItem, JsonTopic, Topic } from '@app/home/feed/feed.model';
-import { Promise } from '@rx-angular/cdk/zone-less/browser';
+
+import { Promise, setTimeout } from '@rx-angular/cdk/zone-less/browser';
 
 export interface NetworkState {
   peer: Peer;
@@ -242,25 +243,26 @@ export class NetworkService extends RxStartableService<NetworkState> {
     });
   }
 
-  async race(urls: string[]): Promise<any> {
-    return Promise.race(
-      urls.map(async (url) => {
-        try {
-          return await firstValueFrom(this.http.get(url));
-        } catch (error) {
-          console.error(`${this._logPrefix}Erreur lors de la récupération de ${url}:`, error);
-          return undefined;
-        }
-      })
-    );
+  async race<T>(urls: string[]): Promise<T> {
+    try {
+      const requests = (urls || []).map((url) => this.http.get<T>(url).pipe(catchError(() => EMPTY)));
+      return await firstValueFrom(race<T[]>(...requests));
+    } catch (err) {
+      return null;
+    }
   }
 
-  async getDistancePrecomputionData(urls: string[]) {
-    const source = timer(0, 5 * 60 * 1000);
-    return firstValueFrom(source.pipe(map(() => this.race(urls))));
+  async getDistancePrecomputionData(): Promise<DistancePrecomputionData> {
+    const distanceFileUrls = this.settings.data.preferredDistanceFileUrls;
+    if (isEmptyArray(distanceFileUrls)) {
+      console.warn(`${this._logPrefix}No precomputed distance file URLs found, in settings and environment!`);
+      return Promise.resolve(null);
+    }
+    console.debug(`${this._logPrefix}Fetching precomputed distance data...`, distanceFileUrls);
+    return this.race<DistancePrecomputionData>(distanceFileUrls);
   }
 
-  async loadJsonFeed(urls: string[]): Promise<JsonTopic[]> {
+  async loadJsonFeedUrls(urls: string[]): Promise<JsonTopic[]> {
     const topicsPromises = urls.map(async (url) => {
       let topics: JsonTopic[] = [];
       try {
diff --git a/src/app/settings/settings.model.ts b/src/app/settings/settings.model.ts
index 17fcc3b46bc2ceaa3305ef820a6bd1e93cc89750..52dd0d692f83c8d4a93106bcf4724f3f306bc301 100644
--- a/src/app/settings/settings.model.ts
+++ b/src/app/settings/settings.model.ts
@@ -27,7 +27,7 @@ export interface Settings {
   ipfsGateway: string;
   preferredIpfsGateways?: string[];
   distanceFileUrl?: string;
-  preferredDistanteFileUrls?: string[];
+  preferredDistanceFileUrls?: string[];
   pages?: any; // Any pages settings
   locale?: string;
   mobile?: boolean;
diff --git a/src/app/settings/settings.service.ts b/src/app/settings/settings.service.ts
index 576eacc97f6e5db4fe0578d07803618fa25b2154..453c4391f05cf48a263474695dad115de85780d9 100644
--- a/src/app/settings/settings.service.ts
+++ b/src/app/settings/settings.service.ts
@@ -91,9 +91,8 @@ export class SettingsService extends RxStartableService<SettingsState> {
       indexer: environment.dev?.indexer ?? environment.defaultIndexers?.[0],
       pod: environment.dev?.pod ?? environment.defaultPods?.[0],
       ipfsGateway: environment.dev?.ipfsGateway ?? environment.defaultIfpsGateways?.[0],
-      distanceFileUrl: environment.dev?.distanceFileUrl ?? environment.defaultDistanteFileUrl?.[0],
       ...this.get(),
-      preferredDistanteFileUrls: arrayDistinct([...environment.defaultDistanteFileUrl, ...(data?.preferredDistanteFileUrls || [])]),
+      preferredDistanceFileUrls: arrayDistinct([...environment.defaultDistanceFileUrls, ...(data?.preferredDistanceFileUrls || [])]),
       preferredPeers: arrayDistinct([...environment.defaultPeers, ...(data?.preferredPeers || [])]),
       preferredIndexers: arrayDistinct([...environment.defaultIndexers, ...(data?.preferredIndexers || [])]),
       preferredPods: arrayDistinct([...environment.defaultPods, ...(data?.preferredPods || [])]),
@@ -114,7 +113,7 @@ export class SettingsService extends RxStartableService<SettingsState> {
       preferredIndexers: arrayDistinct([...environment.defaultIndexers, ...(data?.preferredIndexers || [])]),
       preferredPods: arrayDistinct([...environment.defaultPods, ...(data?.preferredPods || [])]),
       preferredIpfsGateways: arrayDistinct([...environment.defaultIfpsGateways, ...(data?.preferredIpfsGateways || [])]),
-      preferredDistanteFileUrls: arrayDistinct([...environment.defaultDistanteFileUrl, ...(data?.preferredDistanceFileUrls || [])]),
+      preferredDistanceFileUrls: arrayDistinct([...environment.defaultDistanceFileUrls, ...(data?.preferredDistanceFileUrls || [])]),
     };
   }
 
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index 47697e36bdcdc34e63bd756cb29ed0630ab2f0f2..4f68ad7d1be9b434a24354b64025703eec1fdc4e 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -1,5 +1,5 @@
 import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
+import { CommonModule, NgOptimizedImage } from '@angular/common';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 
 import { IonicModule } from '@ionic/angular';
@@ -30,6 +30,7 @@ import { SharedDirectivesModule } from '@app/shared/directives/directives.module
     TranslateModule,
     QrCodeModule,
     MaskitoModule,
+    NgOptimizedImage,
 
     // RxState template
     RxPush,
@@ -58,6 +59,7 @@ import { SharedDirectivesModule } from '@app/shared/directives/directives.module
     TranslateModule,
     QrCodeModule,
     MaskitoModule,
+    NgOptimizedImage,
 
     // RxState template
     RxPush,
diff --git a/src/app/wot/wot.service.ts b/src/app/wot/wot.service.ts
index 1230ce35c064ecd31f2f46c47357bab7cdc6fbc2..e06e07f1f9fb32148fba598490fa814c84627ff4 100644
--- a/src/app/wot/wot.service.ts
+++ b/src/app/wot/wot.service.ts
@@ -10,7 +10,7 @@ import { LoadResult } from '@app/shared/services/service.model';
 import { Account, AccountUtils } from '@app/account/account.model';
 import { map } from 'rxjs/operators';
 import { isNotEmptyArray, isNotNil } from '@app/shared/functions';
-import { DistancePrecomputionData, NetworkService } from '@app/network/network.service';
+import { NetworkService } from '@app/network/network.service';
 import { SettingsService } from '@app/settings/settings.service';
 
 export interface DistanceInformation {
@@ -82,24 +82,19 @@ export class WotService extends StartableService {
   }
 
   async getRefereePercentByAccount(account: Account): Promise<number> {
-    const distanceData: DistancePrecomputionData = await this.getDistanceData();
-    if (!distanceData) {
-      return null;
-    }
+    const distanceData = await this.network.getDistancePrecomputionData();
+    if (!distanceData) return null; // SKip if no data
 
     const accountIndex = account?.meta.index;
-    const refereesReached = distanceData?.results[accountIndex];
-    const refereesCount = distanceData?.referees_count;
+    const refereesReached = distanceData.results[accountIndex];
+    const refereesCount = distanceData.referees_count;
 
     return refereesReached / refereesCount;
   }
 
   async getDistanceInformation(account: Account): Promise<DistanceInformation> {
-    const distanceData: DistancePrecomputionData = await this.getDistanceData();
-
-    if (!distanceData) {
-      return null;
-    }
+    const distanceData = await this.network.getDistancePrecomputionData();
+    if (!distanceData) return null; // Skip if no data
 
     const accountIndex = account?.meta.index;
     const refereesReached = distanceData?.results[accountIndex];
@@ -108,10 +103,4 @@ export class WotService extends StartableService {
     const height = distanceData?.height;
     return <DistanceInformation>{ refereesReached, refereesCount, height, minCertsForReferee };
   }
-
-  protected async getDistanceData() {
-    const distanceFileUrls = this.settings.data.preferredDistanteFileUrls;
-    const distanceData: DistancePrecomputionData = await this.network.getDistancePrecomputionData(distanceFileUrls);
-    return distanceData;
-  }
 }
diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts
index 7e94192b60750a28d2782c958deaa2c893632ebc..236cb6ab9e1a2e52bf35063758d47340133c3d69 100644
--- a/src/environments/environment.class.ts
+++ b/src/environments/environment.class.ts
@@ -23,10 +23,10 @@ export interface Environment {
   defaultIndexers: string[];
   defaultPods: string[];
   defaultIfpsGateways: string[];
-  defaultDistanteFileUrl: string[];
+  defaultDistanceFileUrls: string[];
 
   feed?: {
-    jsonFeed: Map<string, string[]>;
+    jsonFeed: { [key: string]: string[] };
     maxContentLength: number;
     maxAgeInMonths: number;
     maxCount: number;
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index b8a906d4b00bf5e6c9108517c562d9f21f4686b6..bc83030654ffdba4542109f5ee2b2af6489994c1 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -30,8 +30,15 @@ export const environment = <Environment>{
     name: 'cesium2',
     driverOrder: [StorageDrivers.IndexedDB, StorageDrivers.WebSQL, StorageDrivers.LocalStorage],
   },
+
+  keyring: {
+    ss58Format: 42, // dev
+  },
+
   feed: {
-    jsonFeed: new Map<string, string[]>([['fr', ['https://forum.monnaie-libre.fr/t/actu-generale-la-1-bouge/31318.json']]]),
+    jsonFeed: {
+      fr: ['https://forum.monnaie-libre.fr/t/actu-generale-la-1-bouge/31318.json'],
+    },
     maxContentLength: 1300,
     maxAgeInMonths: 3,
     maxCount: 1,
@@ -40,21 +47,24 @@ export const environment = <Environment>{
     /* Local endpoint */
     //'ws://127.0.0.1:9944',
     /* GDev endpoints */
+    // 'wss://vit.fdn.org/ws',
+    //'wss://1000i100.fr/ws',
     'wss://gdev.coinduf.eu/ws',
-    'wss://vit.fdn.org/ws',
     'wss://gdev.pini.fr/ws',
     'wss://gdev.cgeek.fr/ws',
     'wss://gdev.p2p.legal/ws',
-    //'wss://1000i100.fr/ws',
+    'wss://archive-rpc.gdev.brussels.ovh/ws',
+    'wss://archive-rpc.gdev.de.brussels.ovh/ws',
+    'wss://gdev.p2p.legal/ws',
   ],
 
   defaultIndexers: [
     /* Local endpoint */
     //'http://localhost:8080/v1/graphql',
     /* GDev endpoints */
-    'https://gdev-squid.axiom-team.fr/v1beta1/relay',
     'https://squid.gdev.coinduf.eu/v1beta1/relay',
-    //'https://gdev-squid.axiom-team.fr/graphql'
+    // 'https://gdev-squid.axiom-team.fr/graphql',
+    'https://gdev-squid.axiom-team.fr/v1beta1/relay',
   ],
 
   defaultPods: [
@@ -62,6 +72,7 @@ export const environment = <Environment>{
     // 'http://localhost:8081/v1/graphql'
     /* GDev endpoints */
     'https://datapod.coinduf.eu/v1/graphql',
+    'https://datapod.gyroi.de:443/v1/graphql',
   ],
 
   defaultIfpsGateways: [
@@ -70,4 +81,9 @@ export const environment = <Environment>{
     /* GDev endpoints */
     'https://pagu.re',
   ],
+
+  defaultDistanceFileUrls: [
+    /* Distance file Urls */
+    'https://files.coinduf.eu/distance_precompute/latest_distance.json',
+  ],
 };
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index a08e292f4037bbe08546c2bc0b3cb244e0006382..f7b7ae635ff5e4dba985498874e85672132a2d60 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -15,10 +15,10 @@ export const environment = <Environment>{
   forumInformationUrl: 'https://forum.duniter.org/t/gchange-v2-moderation-ou-et-federation/12910/2',
 
   // About
+  officialUrl: 'https://www.cesium.app',
   sourceUrl: 'https://git.duniter.org/clients/cesium-grp/cesium',
   reportIssueUrl: 'https://git.duniter.org/clients/cesium-grp/cesium/-/issues/new',
   forumUrl: 'https://forum.monnaie-libre.fr',
-  officialUrl: 'https://www.cesium.app',
 
   graphql: {
     fetchPolicy: 'cache-first',
@@ -38,7 +38,9 @@ export const environment = <Environment>{
   },
 
   feed: {
-    jsonFeed: new Map<string, string[]>([['fr', ['https://forum.monnaie-libre.fr/t/actu-generale-la-1-bouge/31318.json']]]),
+    jsonFeed: {
+      fr: ['https://forum.monnaie-libre.fr/t/actu-generale-la-1-bouge/31318.json'],
+    },
     maxContentLength: 1300,
     maxAgeInMonths: 3,
     maxCount: 1,
@@ -101,7 +103,7 @@ export const environment = <Environment>{
     'https://pagu.re',
   ],
 
-  defaultDistanteFileUrl: [
+  defaultDistanceFileUrls: [
     /* Distance file Urls */
     'https://files.coinduf.eu/distance_precompute/latest_distance.json',
   ],