diff --git a/package-lock.json b/package-lock.json
index 2490240e2357b965720c48b4eaf5527fbc81eeb2..9cd2692d7290ab8d07921914adbce87e59ec7deb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "cesium",
-  "version": "2.0.0-alpha42",
+  "version": "2.0.0-alpha43",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cesium",
-      "version": "2.0.0-alpha42",
+      "version": "2.0.0-alpha43",
       "license": "AGPL-3.0",
       "dependencies": {
         "@angular/animations": "^18.2.13",
@@ -55,8 +55,10 @@
         "apollo3-cache-persist": "~0.14.1",
         "bs58": "^5.0.0",
         "chart.js": "^4.4.7",
+        "discourse2": "^1.1.25",
         "graphql-tag": "~2.12.6",
         "graphql-ws": "~5.16.0",
+        "ionic-cache": "^6.0.3",
         "ionicons": "~7.4.0",
         "jdenticon": "^3.3.0",
         "localforage": "~1.10.0",
@@ -12408,6 +12410,14 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
+    "node_modules/ajv-errors": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz",
+      "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==",
+      "peerDependencies": {
+        "ajv": "^8.0.1"
+      }
+    },
     "node_modules/ajv-formats": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
@@ -16191,6 +16201,17 @@
         "node": ">=8"
       }
     },
+    "node_modules/discourse2": {
+      "version": "1.1.26",
+      "resolved": "https://registry.npmjs.org/discourse2/-/discourse2-1.1.26.tgz",
+      "integrity": "sha512-unXK6XyFnLmdcMJI8GyU4NS/uoQdvHJTJTzWMqZrnuTkAcfwfnZLpxHVp7Nm7BnKvXzltuuv3cgGUS3WfSIjgg==",
+      "dependencies": {
+        "ajv": "^8.17.1",
+        "ajv-errors": "^3.0.0",
+        "ajv-formats": "^3.0.1",
+        "openapi-types": "^12.1.3"
+      }
+    },
     "node_modules/dns-packet": {
       "version": "5.6.1",
       "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -19670,6 +19691,19 @@
         "loose-envify": "^1.0.0"
       }
     },
+    "node_modules/ionic-cache": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/ionic-cache/-/ionic-cache-6.0.3.tgz",
+      "integrity": "sha512-jlnFC5aVW6bslP8m4a4U287kwpfY5ZzKD0EhO6ko+coYwIsC2VXgcTDPheH7F5ydgW5ioyCq6Z2gkSPYDDe21w==",
+      "dependencies": {
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": ">=9.0.0",
+        "@angular/core": ">=9.0.0",
+        "@ionic/storage-angular": ">=3"
+      }
+    },
     "node_modules/ionicons": {
       "version": "7.4.0",
       "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz",
@@ -24672,6 +24706,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/openapi-types": {
+      "version": "12.1.3",
+      "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
+      "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="
+    },
     "node_modules/optimism": {
       "version": "0.18.1",
       "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz",
diff --git a/package.json b/package.json
index b74db9accbffa4ec41ddce72a1e70f280dd73720..42a6fb1ecb8909087f856529e4ae1e80a6bd94d0 100644
--- a/package.json
+++ b/package.json
@@ -83,12 +83,12 @@
     "src/**/*.{css,json,md,scss}": "prettier --write"
   },
   "peerDependencies": {
+    "@angular/cdk": "^18.2.13",
+    "@angular/common": "^18.2.13",
     "@apollo/client": "~3.12.11",
     "localforage": "~1.10.0",
     "rxjs": "~7.8.1",
-    "zone.js": "~0.14.10",
-    "@angular/common": "^18.2.13",
-    "@angular/cdk": "^18.2.13"
+    "zone.js": "~0.14.10"
   },
   "dependencies": {
     "@angular/animations": "^18.2.13",
@@ -137,8 +137,10 @@
     "apollo3-cache-persist": "~0.14.1",
     "bs58": "^5.0.0",
     "chart.js": "^4.4.7",
+    "discourse2": "^1.1.25",
     "graphql-tag": "~2.12.6",
     "graphql-ws": "~5.16.0",
+    "ionic-cache": "^6.0.3",
     "ionicons": "~7.4.0",
     "jdenticon": "^3.3.0",
     "localforage": "~1.10.0",
diff --git a/src/app/account/accounts.service.ts b/src/app/account/accounts.service.ts
index 81a7f1fcb128f33f99d4511cfbaac97a28338c18..9e1ef7e8bf15db57d089e2d8cbe6c0efb72a5b40 100644
--- a/src/app/account/accounts.service.ts
+++ b/src/app/account/accounts.service.ts
@@ -35,6 +35,9 @@ import { ExtrinsicError, ExtrinsicUtils } from '@app/shared/substrate/extrinsic.
 import { IdentityStatusEnum } from '@app/network/indexer/indexer-types.generated';
 import { PodService } from '@app/network/pod/pod.service';
 import { FetchPolicy } from '@apollo/client';
+import { TranslateService } from '@ngx-translate/core';
+import { WotService } from '@app/wot/wot.service';
+import { CertificationSearchFilter } from '@app/certification/history/cert-history.model';
 
 // kind of certify action
 enum CertType {
@@ -56,6 +59,7 @@ export interface LoadAccountDataOptions {
   withProfile?: boolean;
   fetchPolicy?: FetchPolicy;
 }
+
 export interface WatchAccountDataOptions extends LoadAccountDataOptions {}
 
 export interface AccountsState {
@@ -85,8 +89,10 @@ export class AccountsService extends RxStartableService<AccountsState> {
   constructor(
     protected network: NetworkService,
     protected indexer: IndexerService,
+    protected wot: WotService,
     protected pod: PodService,
     protected settings: SettingsService,
+    protected translate: TranslateService,
     @Inject(APP_STORAGE) protected storage: IStorage,
     @Inject(APP_AUTH_CONTROLLER) protected authController: IAuthController
   ) {
@@ -222,6 +228,7 @@ export class AccountsService extends RxStartableService<AccountsState> {
       default: true,
       ...data.meta,
       self: true,
+      isMember: true,
     };
 
     const { pair, account } = await this.createAccount(data);
@@ -502,7 +509,13 @@ export class AccountsService extends RxStartableService<AccountsState> {
       return this.accounts$.pipe(
         map((accounts) => accounts?.find((a) => a.address === address)),
         tap((account) => account || stopWatching.next()),
-        mergeMap(async (account) => this.loadData(account, { ...opts, withMembership: false, fetchPolicy: 'cache-first' })),
+        mergeMap(async (account) =>
+          this.loadData(account, {
+            ...opts,
+            withMembership: false,
+            fetchPolicy: 'cache-first',
+          })
+        ),
         takeUntil(stopWatching)
       );
     }
@@ -514,7 +527,13 @@ export class AccountsService extends RxStartableService<AccountsState> {
 
     return this.indexer.wotSearch({ address }, { first: 1, fetchPolicy: 'cache-first' }).pipe(
       map(({ data }) => firstArrayValue(data) || { address, meta: { name: formatAddress(address) } }),
-      mergeMap(async (account) => this.loadData(account, { ...opts, withMembership: false, fetchPolicy: 'cache-first' }))
+      mergeMap(async (account) =>
+        this.loadData(account, {
+          ...opts,
+          withMembership: false,
+          fetchPolicy: 'cache-first',
+        })
+      )
     );
   }
 
@@ -523,9 +542,10 @@ export class AccountsService extends RxStartableService<AccountsState> {
    * @param from
    * @param to
    * @param amount the TX amount, using decimals
+   * @param comment
    * @param fee the TX fee, using decimals
    */
-  async transfer(from: Partial<Account>, to: Partial<Account>, amount: number, fee?: number): Promise<string> {
+  async transfer(from: Partial<Account>, to: Partial<Account>, amount: number, comment?: string, fee?: number): Promise<string> {
     if (!from || !to) throw new Error("Missing argument 'from' or 'to' !");
     const currency = this.network.currency;
 
@@ -578,31 +598,59 @@ export class AccountsService extends RxStartableService<AccountsState> {
     }
 
     try {
+      let txHash;
       // Sign and send a transfer from Alice to Bob
-      const txHash = await this.api.tx.balances.transferKeepAlive(to.address, amount).signAndSend(issuerPair, async ({ status, events }) => {
-        if (status.isInBlock) {
-          console.info(`${this._logPrefix}Extrinsic status`, status.toHuman());
-          console.info(`${this._logPrefix}Completed at block hash #${status.hash.toHuman()}`);
-
-          if (this._debug) console.debug(`${this._logPrefix}Block events:`, JSON.stringify(events));
+      if (isNotNilOrBlank(comment)) {
+        const txTransfer = this.api.tx.balances.transferKeepAlive(to.address, amount);
+        const txComment = this.api.tx.system.remarkWithEvent(comment ?? '');
+        txHash = this.api.tx.utility.batch([txTransfer, txComment]).signAndSend(issuerPair, async ({ status, events }) => {
+          if (status.isInBlock) {
+            console.info(`${this._logPrefix}Extrinsic status`, status.toHuman());
+            console.info(`${this._logPrefix}Completed at block hash #${status.hash.toHuman()}`);
+
+            if (this._debug) console.debug(`${this._logPrefix}Block events:`, JSON.stringify(events));
+
+            // List of outdated accounts
+            const outdatedAccounts = [issuerAccount];
+
+            // Add receiver to outdated account
+            if (await this.isAvailable(to.address)) {
+              const toAccount = await this.getByAddress(to.address);
+              outdatedAccounts.push(toAccount);
+            }
+
+            await sleep(200); // Wait 200ms
+
+            await this.refreshData(outdatedAccounts, { reload: true });
+          } else {
+            console.info(`${this._logPrefix}Current status: `, status.toHuman());
+          }
+        });
+      } else {
+        txHash = this.api.tx.balances.transferKeepAlive(to.address, amount).signAndSend(issuerPair, async ({ status, events }) => {
+          if (status.isInBlock) {
+            console.info(`${this._logPrefix}Extrinsic status`, status.toHuman());
+            console.info(`${this._logPrefix}Completed at block hash #${status.hash.toHuman()}`);
 
-          // List of outdated accounts
-          const outdatedAccounts = [issuerAccount];
+            if (this._debug) console.debug(`${this._logPrefix}Block events:`, JSON.stringify(events));
 
-          // Add receiver to outdated account
-          if (await this.isAvailable(to.address)) {
-            const toAccount = await this.getByAddress(to.address);
-            outdatedAccounts.push(toAccount);
-          }
+            // List of outdated accounts
+            const outdatedAccounts = [issuerAccount];
 
-          await sleep(200); // Wait 200ms
+            // Add receiver to outdated account
+            if (await this.isAvailable(to.address)) {
+              const toAccount = await this.getByAddress(to.address);
+              outdatedAccounts.push(toAccount);
+            }
 
-          await this.refreshData(outdatedAccounts, { reload: true });
-        } else {
-          console.info(`${this._logPrefix}Current status: `, status.toHuman());
-        }
-      });
+            await sleep(200); // Wait 200ms
 
+            await this.refreshData(outdatedAccounts, { reload: true });
+          } else {
+            console.info(`${this._logPrefix}Current status: `, status.toHuman());
+          }
+        });
+      }
       // Show the hash
       console.info(`${this._logPrefix}Finalized hash ${txHash}`);
 
@@ -617,8 +665,16 @@ export class AccountsService extends RxStartableService<AccountsState> {
    *
    * @param from
    * @param to
+   * @param opts
    */
-  async cert(from: Partial<Account>, to: Partial<Account>, opts = { allowCreation: true, confirmBeforeCreation: true }): Promise<string> {
+  async cert(
+    from: Account,
+    to: Account,
+    opts = {
+      allowCreation: true,
+      confirmBeforeCreation: true,
+    }
+  ): Promise<string> {
     if (!from || !to) throw new Error("Missing argument 'from' or 'to' !");
 
     // Check currency
@@ -670,17 +726,35 @@ export class AccountsService extends RxStartableService<AccountsState> {
         case IdentityStatusEnum.Unconfirmed:
           console.log('can not certify unconfirmed identity');
           break;
-        case IdentityStatusEnum.Unvalidated:
-          // TODO special case for last certification: request distance evaluation
+        case IdentityStatusEnum.Unvalidated: {
+          // special case for last certification: request distance evaluation
+          const toAccount = <Account>{ address: to.address, meta: to.meta, data: to.data, publicKey: to.publicKey };
+          const toAccountRefereePercent = await this.wot.getRefereePercentByAccount(toAccount);
+          if (toAccountRefereePercent > this.network.currency.params.minAccessibleReferees / 1000000000) {
+            certType = CertType.IdentityCreation;
+          } else {
+            certType = CertType.CertCreation;
+          }
           break;
-        case IdentityStatusEnum.Notmember:
-          // TODO prevent certifying if lost membership for membership non renewal
+        }
+        case IdentityStatusEnum.Notmember: {
+          // prevent certifying if lost membership for membership non renewal
+          const toAccountRefereePercent = await this.wot.getRefereePercentByAccount(to);
+          if (toAccountRefereePercent > this.network.currency.params.minAccessibleReferees / 1000000000) {
+            certType = CertType.CertRenewal;
+          }
           break;
-        default:
-          // ok to certify
-          // TODO check if certification already exists (renewal)
-          certType = CertType.CertCreation;
+        }
+        default: {
+          // check if certification already exists (renewal)
+          const isRenewal = await this.isCertValid({ receiver: to.address, issuer: from.address });
+          if (isRenewal) {
+            certType = CertType.CertRenewal;
+          } else {
+            certType = CertType.CertCreation;
+          }
           break;
+        }
       }
     }
 
@@ -689,9 +763,12 @@ export class AccountsService extends RxStartableService<AccountsState> {
     try {
       let tx = null;
       switch (certType) {
-        case CertType.IdentityCreation:
-          tx = this.api.tx.identity.createIdentity(to.address);
+        case CertType.IdentityCreation: {
+          const txCertify = this.api.tx.identity.addCert(to.meta.index);
+          const txIdentity = this.api.tx.identity.createIdentity(to.address);
+          tx = this.api.tx.utility.batch([txCertify, txIdentity]);
           break;
+        }
         case CertType.CertCreation:
           tx = this.api.tx.certification.addCert(to.meta.index);
           break;
@@ -759,7 +836,7 @@ export class AccountsService extends RxStartableService<AccountsState> {
       const derivationPath = i === -1 ? '' : `//${i}`;
       const address = this.generateAddress(`${mnemonic}${derivationPath}`);
       const shortAddress = formatAddress(address);
-      derivationAccounts.push({ derivation: derivationPath, address, meta: { name: shortAddress} });
+      derivationAccounts.push({ derivation: derivationPath, address, meta: { name: shortAddress } });
     }
     // Load balances data (e.g. balance)
     await Promise.all(derivationAccounts.map((account) => this.loadData(account, { withBalance: true })));
@@ -768,6 +845,31 @@ export class AccountsService extends RxStartableService<AccountsState> {
     return derivationAccounts.filter((account) => AccountUtils.getBalance(account) > 0);
   }
 
+  async isCertValid(filter: CertificationSearchFilter) {
+    const certs = await firstValueFrom(this.indexer.certsSearch({ receiver: filter.receiver }));
+    return isNotEmptyArray(certs.data.filter((cert) => cert.account.address === filter.issuer));
+  }
+
+  async claimUds(account: Account) {
+    const issuerPair = keyring.getPair(account.address);
+    if (issuerPair.isLocked) {
+      console.debug(`[account-service] Unlocking address ${account.address} ...`);
+      const isAuth = await this.auth();
+      if (!isAuth) throw new Error('ERROR.AUTH_REQUIRED');
+      issuerPair.unlock(this._password);
+    }
+
+    try {
+      const tx = this.api.tx.universalDividend.claimUds();
+      const { status } = await ExtrinsicUtils.submit(tx, issuerPair);
+      console.info(`${this._logPrefix}Extrinsic status`, status.toHuman());
+      return status.toHuman();
+    } catch (err) {
+      console.error(err);
+      throw new Error('ERROR.CLAIM_UD_FAILED');
+    }
+  }
+
   /**
    * Load account data (balance, tx history, etc.).
    * This load can be skipped, when data already loaded (See options)
diff --git a/src/app/account/auth/auth.modal.ts b/src/app/account/auth/auth.modal.ts
index 3117b1bdcfa062d5caf41e8f2ab5cf16ded3d719..7b7eafdab23742f59c0cc6e21441ac098c781ef2 100644
--- a/src/app/account/auth/auth.modal.ts
+++ b/src/app/account/auth/auth.modal.ts
@@ -81,41 +81,43 @@ export class AuthModal implements OnInit, AuthModalOptions {
       // Disable the form
       this.form.disable();
 
-      if (data.v2.mnemonic.includes('//')) {
-        const account = await this.accountService.addAccount(data);
-        return this.modalCtrl.dismiss(account, <AuthModalRole>'VALIDATE');
-      }
+      if (this.loginMethod === 'v2') {
+        if (data.v2.mnemonic.includes('//')) {
+          const account = await this.accountService.addAccount(data);
+          return this.modalCtrl.dismiss(account, <AuthModalRole>'VALIDATE');
+        }
 
-      // Scan for derivations
-      const derivations = await this.accountService.scanDerivations(data.v2.mnemonic);
+        // Scan for derivations
+        const derivations = await this.accountService.scanDerivations(data.v2.mnemonic);
 
-      // Only one derivation: use it
-      let selectedDerivationAccount: DerivationAccount;
-      if (derivations?.length === 1) {
-        selectedDerivationAccount = derivations[0];
-      }
+        // Only one derivation: use it
+        let selectedDerivationAccount: DerivationAccount;
+        if (derivations?.length === 1) {
+          selectedDerivationAccount = derivations[0];
+        }
 
-      // Many derivation: let the user choose
-      else if (derivations?.length > 1) {
-        const modal = await this.modalCtrl.create({
-          component: DerivationSelectionComponent,
-          componentProps: {
-            mnemonic: data.v2.mnemonic,
-            derivations,
-          },
-        });
-
-        await modal.present();
-        const res = await modal.onDidDismiss();
-        if (AccountUtils.isDerivationAccount(res?.data)) {
-          selectedDerivationAccount = res.data;
+        // Many derivation: let the user choose
+        else if (derivations?.length > 1) {
+          const modal = await this.modalCtrl.create({
+            component: DerivationSelectionComponent,
+            componentProps: {
+              mnemonic: data.v2.mnemonic,
+              derivations,
+            },
+          });
+
+          await modal.present();
+          const res = await modal.onDidDismiss();
+          if (AccountUtils.isDerivationAccount(res?.data)) {
+            selectedDerivationAccount = res.data;
+          }
         }
-      }
 
-      // Update mnemonic, to use the derivation
-      if (selectedDerivationAccount) {
-        console.info(`[auth] Will use derivation: ${selectedDerivationAccount?.derivation}`);
-        data.v2.mnemonic += selectedDerivationAccount?.derivation;
+        // Update mnemonic, to use the derivation
+        if (selectedDerivationAccount) {
+          console.info(`[auth] Will use derivation: ${selectedDerivationAccount?.derivation}`);
+          data.v2.mnemonic += selectedDerivationAccount?.derivation;
+        }
       }
 
       const account = await this.accountService.addAccount(data);
diff --git a/src/app/account/wallet/wallet.page.html b/src/app/account/wallet/wallet.page.html
index 0238549e084dc6564913930c3994e55ae45305d5..cdb23b72a6cdc45f5f8202f8109f327d7f8cea7f 100644
--- a/src/app/account/wallet/wallet.page.html
+++ b/src/app/account/wallet/wallet.page.html
@@ -17,12 +17,12 @@
 </ion-header>
 
 <!-- options menu -->
-<ion-popover #optionsPopover trigger="options-menu-trigger" triggerAction="click">
+<ion-popover #optionsPopover [dismissOnSelect]="true" trigger="options-menu-trigger" triggerAction="click">
   <ng-template>
     <ion-content class="ion-no-padding">
       <ion-list-header translate>COMMON.POPOVER_ACTIONS_TITLE</ion-list-header>
       <ion-list>
-        <ion-item (click)="addNewWallet($event)" tappable>
+        <ion-item (click)="addNewWallet()" tappable>
           <ion-label translate>ACCOUNT.WALLET_LIST.BTN_NEW_DOTS</ion-label>
         </ion-item>
       </ion-list>
@@ -75,9 +75,9 @@
         </ion-button>
 
         <!-- Confirm identity -->
-        @if (account.meta?.status === IdentityStatusEnum.Unconfirmed) {
+        @if (account.meta?.status === IdentityStatusEnum.Unconfirmed && distanceRuleValid()) {
           <ion-button (click)="confirmIdentity()" [disabled]="loading" color="tertiary">
-            <!--            <ion-icon slot="start" name="checkmark-circle-outline"></ion-icon>-->
+            <ion-icon slot="start" name="checkmark-circle"></ion-icon>
             <ion-label translate>ACCOUNT.BTN_CONFIRM_MEMBERSHIP</ion-label>
           </ion-button>
         }
@@ -178,6 +178,18 @@
             <ion-label translate>WOT.GIVEN_CERTIFICATIONS.SENT</ion-label>
             <ion-badge color="success" slot="end">{{ givenCertCount$ | push }}</ion-badge>
           </ion-item>
+
+          <!-- Distance rule -->
+          <ion-item [disabled]="disableDistanceRule()">
+            <ion-icon aria-hidden="true" slot="start" name="logo-steam"></ion-icon>
+            <ion-label translate>
+              HELP.GLOSSARY.DISTANCE_RULE
+              <ion-icon [color]="'tertiary'" name="help-circle-outline" (click)="showModalDistanceRuleDefinition()" tappable></ion-icon>
+            </ion-label>
+            <ion-badge title="{{ titleDistanceRule() }}" color="{{ distanceRuleValid() ? 'success' : 'danger' }}">
+              {{ refereePercent$ | async | percent: '1.1' }}
+            </ion-badge>
+          </ion-item>
         }
 
         <!-- TX history -->
diff --git a/src/app/account/wallet/wallet.page.ts b/src/app/account/wallet/wallet.page.ts
index ca08ac231e1b41141827c8e43c0c41645087a54b..0c2dafb972f758469b5246cff5b47ad10dfd63cb 100644
--- a/src/app/account/wallet/wallet.page.ts
+++ b/src/app/account/wallet/wallet.page.ts
@@ -10,7 +10,7 @@ import { ActivatedRoute, Router } from '@angular/router';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
 import { distinctUntilChanged, filter, mergeMap, switchMap } from 'rxjs/operators';
 import { AccountsService } from '@app/account/accounts.service';
-import { map, merge, Observable } from 'rxjs';
+import { from, map, merge, Observable } from 'rxjs';
 import { RxState } from '@rx-angular/state';
 import { APP_TRANSFER_CONTROLLER, ITransferController, TransferFormOptions } from '@app/transfer/transfer.model';
 import { TranslateModule } from '@ngx-translate/core';
@@ -21,16 +21,22 @@ import { IdentityStatusEnum } from '@app/network/indexer/indexer-types.generated
 import { AppIdentityConfirmModule } from '@app/account/confirm/identity-confirm.module';
 import { IdentityConfirmModal } from '@app/account/confirm/identity-confirm.modal';
 import { fadeInOutAnimation, slideUpDownAnimation } from '@app/shared/animations';
+import { Currency } from '@app/currency/currency.model';
+import { DistanceInformation, WotService } from '@app/wot/wot.service';
+import { HelpPage } from '@app/home/help/help.page';
 
 export interface WalletState extends AppPageState {
   accounts: Account[];
   account: Account;
   address: string;
-  currency: string;
+  currencySymbol: string;
+  currency: Currency;
   balance: number;
   receivedCertCount: number;
   givenCertCount: number;
   status: IdentityStatusEnum;
+  refereePercent: number;
+  distanceInformation: DistanceInformation;
 }
 
 @Component({
@@ -56,13 +62,17 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
   @RxStateProperty() accounts: Account[];
   @RxStateProperty() account: Account;
   @RxStateProperty() address: string;
-  @RxStateProperty() currency: string;
+  @RxStateProperty() currencySymbol: string;
+  @RxStateProperty() currency: Currency;
+  @RxStateProperty() refereePercent: number;
+  @RxStateProperty() distanceInformation: DistanceInformation;
 
   @RxStateSelect() account$: Observable<Account>;
   @RxStateSelect() accounts$: Observable<Account[]>;
   @RxStateSelect() receivedCertCount$: Observable<number>;
   @RxStateSelect() givenCertCount$: Observable<number>;
   @RxStateSelect() status$: Observable<IdentityStatusEnum>;
+  @RxStateSelect() refereePercent$: Observable<number>;
 
   get balance(): number {
     if (!this.account?.data) return undefined;
@@ -89,6 +99,7 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
     protected route: ActivatedRoute,
     protected networkService: NetworkService,
     protected accountService: AccountsService,
+    protected wotService: WotService,
     protected modalCtrl: ModalController,
     @Inject(APP_TRANSFER_CONTROLLER) protected transferController: ITransferController
   ) {
@@ -171,6 +182,15 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
         filter(isNotNil)
       )
     );
+
+    this._state.connect(
+      'refereePercent',
+      this._state.select('account').pipe(switchMap((account) => from(this.wotService.getRefereePercentByAccount(account))))
+    );
+    this._state.connect(
+      'distanceInformation',
+      this._state.select('account').pipe(switchMap((account) => from(this.wotService.getDistanceInformation(account))))
+    );
   }
 
   async ngOnInit() {
@@ -184,7 +204,8 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
     return <WalletState>{
       account: null,
       address: this.activatedRoute.snapshot.paramMap.get('address'),
-      currency: this.networkService.currencySymbol,
+      currencySymbol: this.networkService.currencySymbol, // TODO: delete to use instead currency.currencySymbol?
+      currency: this.networkService.currency,
     };
   }
 
@@ -207,16 +228,11 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
     return this.qrCodeModal.present();
   }
 
-  async addNewWallet(event?: Event): Promise<Account> {
-    event?.preventDefault();
-    event?.stopPropagation();
-    this.optionsPopover?.dismiss();
-
+  async addNewWallet(): Promise<Account> {
     const data = await this.accountService.createNew();
     if (!data) return null;
 
     this.account = data;
-
     return data;
   }
 
@@ -229,8 +245,18 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
   }
 
   async confirmIdentity(): Promise<void> {
-    console.info(`${this._logPrefix}Opening identity confirm modal...`);
+    if (!this.distanceRuleValid()) {
+      console.info(`${this._logPrefix}Distance rule not valid`);
+      await this.showToast({
+        id: 'distance-rule-not-valid',
+        message: 'ACCOUNT.MEMBER_CONVERT_FAILED',
+        swipeGesture: 'vertical',
+        color: 'danger',
+      });
+      return;
+    }
 
+    console.info(`${this._logPrefix}Opening identity confirm modal...`);
     const modal = await this.modalCtrl.create({
       component: IdentityConfirmModal,
       presentingElement: this._presentingElement,
@@ -255,10 +281,44 @@ export class WalletPage extends AppPage<WalletState> implements OnInit {
       await this.accountService.confirm(this.account, data.pseudo);
 
       // Show toast
-      await this.showToast({ id: 'confirm-identity', message: 'INFO.CONFIRM_IDENTITY_DONE', swipeGesture: 'vertical', color: 'secondary' });
+      await this.showToast({
+        id: 'confirm-identity',
+        message: 'INFO.CONFIRM_IDENTITY_DONE',
+        swipeGesture: 'vertical',
+        color: 'secondary',
+      });
     } catch (err) {
       this.showErrorToast(err, { id: 'confirm-identity' });
       this.markAsLoaded();
     }
   }
+
+  distanceRuleValid(): boolean {
+    return this.refereePercent > this.networkService.currency.params.minAccessibleReferees / 1000000000;
+  }
+
+  disableDistanceRule(): boolean {
+    return isNil(this.refereePercent);
+  }
+
+  titleDistanceRule() {
+    return this.translate.instant('ACCOUNT.TITLE_DISTANCE_RULES', {
+      refereesReached: this.distanceInformation?.refereesReached,
+      refereesCount: this.distanceInformation?.refereesCount,
+      height: this.distanceInformation?.height,
+    });
+  }
+
+  async showModalDistanceRuleDefinition() {
+    const modal = await this.modalCtrl.create({
+      id: 'help-modal',
+      component: HelpPage,
+      componentProps: <HelpPage>{
+        highlightedDefinition: 'GLOSSARY_DISTANCE_RULE',
+      },
+      presentingElement: this._presentingElement,
+      canDismiss: true,
+    });
+    await modal.present();
+  }
 }
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 3840930e009ce246137ef43dddbdddd0fcfb37c6..5b89b2302dc972493e8374a37893541fe4e575bf 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -44,6 +44,10 @@ const routes: Routes = [
     path: 'settings',
     loadChildren: () => import('./settings/settings-routing.module').then((m) => m.AppSettingsRoutingModule),
   },
+  {
+    path: 'help',
+    loadChildren: () => import('./home/help/help-routing.module').then((m) => m.HelpPageRoutingModule),
+  },
 
   // -- DEV only
   {
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 0ba8858afdbfdffceaa9da7a91ce1b117d86ac74..034a1ff69efbe215a16f01e80e27017928f69c8e 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -3,7 +3,20 @@
     <ion-menu contentId="main-content" type="overlay">
       <ion-content [class.dark]="settings.darkMode$ | async">
         <ion-list id="main-menu-list">
-          <ion-list-header class="title" [innerHTML]="'COMMON.APP_NAME' | translate"></ion-list-header>
+          <div style="display: inline-block">
+            <ion-list-header style="overflow: visible">
+              @if (isDemo()) {
+                <a>
+                  <ion-badge color="danger" (click)="openHelpModal('DEMO_MODE_HELP')" tappable translate>MODE.DEMO.BADGE</ion-badge>
+                </a>
+              } @else if (isDev()) {
+                <a>
+                  <ion-badge color="success" (click)="openHelpModal('READONLY_MODE_HELP')" tappable translate>MODE.READONLY.BADGE</ion-badge>
+                </a>
+              }
+              <ion-label [innerHTML]="'COMMON.APP_NAME' | translate"></ion-label>
+            </ion-list-header>
+          </div>
 
           <ion-note></ion-note>
 
@@ -12,6 +25,13 @@
           }
         </ion-list>
       </ion-content>
+      <ion-footer>
+        <ion-item color="light" class="ion-tappable ion-focusable">
+          <ion-icon color="medium" slot="start" name="help-circle-outline" routerDirection="root" [routerLink]="'/help'" tappable></ion-icon>
+          <ion-label color="medium" [translateParams]="{ version: getVersion() }" translate>COMMON.APP_VERSION</ion-label>
+          <ion-label color="medium" slot="end" (click)="openAboutModal()" tappable translate>HOME.BTN_ABOUT</ion-label>
+        </ion-item>
+      </ion-footer>
     </ion-menu>
     <ion-router-outlet id="main-content"></ion-router-outlet>
   </ion-split-pane>
diff --git a/src/app/app.component.scss b/src/app/app.component.scss
index b54b539ccf84ad1876df77f187244b11b012d94e..290ea63cf74b31948fff6386c8a889ce3d9110cd 100644
--- a/src/app/app.component.scss
+++ b/src/app/app.component.scss
@@ -4,6 +4,12 @@
 ion-menu {
   --side-min-width: #{$app-menu-width};
   --side-max-width: #{$app-menu-width};
+
+}
+
+ion-menu ion-footer {
+  background-image: linear-gradient(180deg, #b2b2b2, #b2b2b2 50%, transparent 50%);
+  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .26);
 }
 
 ion-menu ion-content {
@@ -16,15 +22,37 @@ ion-menu ion-content {
     flex-direction: column;
     justify-content: flex-start;
 
+    ion-list-header {
+      ion-badge {
+        font-size: 12px;
+        left: 1px;
+        transform-origin: 26px 5px;
+        transform: rotate(-10deg);
+
+      }
+      ion-badge:hover {
+        font-size: 14px;
+        right: 1px;
+        transform-origin: 26px 5px;
+        transform: rotate(-10deg);
+      }
+      ion-label {
+        padding-left: 10px;
+      }
+    }
+
     ion-item-divider {
       background: transparent;
     }
+
     .flex-spacer {
       flex: 1 1 auto;
       display: flex;
       flex-direction: column;
       justify-content: flex-end;
     }
+
+
   }
 
   &.dark {
@@ -33,11 +61,10 @@ ion-menu ion-content {
 
     ion-list-header.title {
       color: yellow;
-      text-shadow:
-        0 0 10px var(--background-color),
-        0 0 20px var(--background-color),
-        0 0 30px var(--background-color),
-        0 0 40px var(--background-color);
+      text-shadow: 0 0 10px var(--background-color),
+      0 0 20px var(--background-color),
+      0 0 30px var(--background-color),
+      0 0 40px var(--background-color);
       overflow: visible;
     }
   }
@@ -115,6 +142,7 @@ ion-menu.md ion-item.selected ion-icon {
 ion-menu.md ion-item ion-icon {
   color: #616e7e;
 }
+
 ion-menu ion-item {
   user-select: none;
 }
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 3dfd6e035adb74e770aa32bf55f9e35fa2dbf1b7..5f52358a41dc845180b748d592c9c8fd4e0509cb 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -9,9 +9,12 @@ import { PredefinedColors } from '@app/shared/colors/colors.utils';
 import { fadeInAnimation } from '@app/shared/animations';
 import { SettingsService } from '@app/settings/settings.service';
 import { TranslateService } from '@ngx-translate/core';
-import { AlertController } from '@ionic/angular';
-import { WotController } from './wot/wot.controller';
+import { AlertController, ModalController } from '@ionic/angular';
 import { Observable } from 'rxjs';
+import { environment } from '@environments/environment';
+import { AboutModal } from '@app/home/about/about.modal';
+import { HelpPage } from '@app/home/help/help.page';
+import { isDemo, isDev } from '@app/shared/environment/environment.utils';
 
 export interface IMenuItem {
   title: string;
@@ -80,10 +83,10 @@ export class AppComponent {
     protected settings: SettingsService,
     private accountService: AccountsService,
     private transferController: TransferController,
-    private wotController: WotController,
     private translate: TranslateService,
     private alertController: AlertController,
-    private router: Router
+    private router: Router,
+    private modalCtrl: ModalController
   ) {
     this.start();
   }
@@ -148,4 +151,31 @@ export class AppComponent {
       // Continue
     }
   }
+
+  getVersion() {
+    return environment.version;
+  }
+
+  async openAboutModal() {
+    const modal = await this.modalCtrl.create({
+      id: 'about-modal',
+      component: AboutModal,
+      canDismiss: true,
+    });
+    await modal.present();
+  }
+  async openHelpModal(definition: string) {
+    const modal = await this.modalCtrl.create({
+      id: 'help-modal',
+      component: HelpPage,
+      componentProps: {
+        highlightedDefinition: definition,
+      },
+      canDismiss: true,
+    });
+    await modal.present();
+  }
+  protected readonly environment = environment;
+  protected readonly isDemo = isDemo;
+  protected readonly isDev = isDev;
 }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index b8a3e69d691e5a2d7d261b1576b3d8ae4aeebcbc..73967b6bf8c5369d7fd3cfeaf8392c7b5685ce6b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -29,6 +29,8 @@ import { AppWotModule } from './wot/wot.module';
 import { APP_FORM_ERROR_I18N_KEYS } from '@app/shared/form/form-error-translator.service';
 import { IdentityConfirmValidators } from '@app/account/confirm/identity-confirm.validator';
 import { CodeInputModule } from 'angular-code-input';
+import { HelpModule } from '@app/home/help/help.module';
+import { AboutModule } from '@app/home/about/about.module';
 
 export function createTranslateLoader(http: HttpClient) {
   if (environment.production) {
@@ -38,86 +40,97 @@ export function createTranslateLoader(http: HttpClient) {
   return new TranslateHttpLoader(http, './assets/i18n/', `.json`);
 }
 
-@NgModule({ declarations: [AppComponent],
-    bootstrap: [AppComponent], imports: [BrowserModule,
-        BrowserAnimationsModule,
-        IonicModule.forRoot(),
-        IonicStorageModule.forRoot({
-            name: environment.name || 'cesium2',
-            ...environment.storage,
-        }),
-        TranslateModule.forRoot({
-            defaultLanguage: environment.defaultLocale,
-            loader: {
-                provide: TranslateLoader,
-                useFactory: createTranslateLoader,
-                deps: [HttpClient],
-            },
-        }),
-        CodeInputModule.forRoot({
-            codeLength: 6,
-            isCharsCode: true,
-            code: 'abcdef',
-        }),
-        AppRoutingModule,
-        AppSharedModule,
-        AppWotModule.forRoot(),
-        AppAccountModule.forRoot(),
-        AppTransferModule.forRoot()], providers: [
-        PlatformService,
-        StorageService,
-        AccountsService,
-        { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
-        {
-            provide: APP_GRAPHQL_TYPE_POLICIES,
-            useValue: {
-                ...INDEXER_GRAPHQL_TYPE_POLICIES,
-                ...POD_GRAPHQL_TYPE_POLICIES,
-            },
+@NgModule({
+  declarations: [AppComponent],
+  bootstrap: [AppComponent],
+  imports: [
+    BrowserModule,
+    BrowserAnimationsModule,
+    IonicModule.forRoot({
+      innerHTMLTemplatesEnabled: true,
+    }),
+    IonicStorageModule.forRoot({
+      name: environment.name || 'cesium2',
+      ...environment.storage,
+    }),
+    TranslateModule.forRoot({
+      defaultLanguage: environment.defaultLocale,
+      loader: {
+        provide: TranslateLoader,
+        useFactory: createTranslateLoader,
+        deps: [HttpClient],
+      },
+    }),
+    HelpModule,
+    AboutModule,
+    CodeInputModule.forRoot({
+      codeLength: 6,
+      isCharsCode: true,
+      code: 'abcdef',
+    }),
+    HelpModule,
+    AppRoutingModule,
+    AppSharedModule,
+    AppWotModule.forRoot(),
+    AppAccountModule.forRoot(),
+    AppTransferModule.forRoot(),
+  ],
+  providers: [
+    PlatformService,
+    StorageService,
+    AccountsService,
+    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
+    {
+      provide: APP_GRAPHQL_TYPE_POLICIES,
+      useValue: {
+        ...INDEXER_GRAPHQL_TYPE_POLICIES,
+        ...POD_GRAPHQL_TYPE_POLICIES,
+      },
+    },
+    { provide: APP_STORAGE, useExisting: StorageService },
+    { provide: APP_BASE_HREF, useValue: environment.baseUrl || '/' },
+    {
+      provide: APP_LOCALES,
+      useValue: [
+        { key: 'en', value: 'English', country: 'us' },
+        { key: 'en-GB', value: 'English (UK)', country: 'gb' },
+        { key: 'eo-EO', value: 'Esperanto', country: 'eo' },
+        { key: 'fr', value: 'Français', country: 'fr' },
+        { key: 'nl-NL', value: 'Nederlands', country: 'nl' },
+        { key: 'es-ES', value: 'Spanish', country: 'es' },
+        { key: 'ca', value: 'Català', country: 'ca' },
+        { key: 'it-IT', value: 'Italiano', country: 'it' },
+      ],
+    },
+    // Custom identicon style
+    // https://jdenticon.com/icon-designer.html?config=4451860010ff320028501e5a
+    {
+      provide: JDENTICON_CONFIG,
+      useValue: {
+        lightness: {
+          color: [0.26, 0.8],
+          grayscale: [0.3, 0.9],
         },
-        { provide: APP_STORAGE, useExisting: StorageService },
-        { provide: APP_BASE_HREF, useValue: environment.baseUrl || '/' },
-        {
-            provide: APP_LOCALES,
-            useValue: [
-                { key: 'en', value: 'English', country: 'us' },
-                { key: 'en-GB', value: 'English (UK)', country: 'gb' },
-                { key: 'eo-EO', value: 'Esperanto', country: 'eo' },
-                { key: 'fr', value: 'Français', country: 'fr' },
-                { key: 'nl-NL', value: 'Nederlands', country: 'nl' },
-                { key: 'es-ES', value: 'Spanish', country: 'es' },
-                { key: 'ca', value: 'Català', country: 'ca' },
-                { key: 'it-IT', value: 'Italiano', country: 'it' },
-            ],
-        },
-        // Custom identicon style
-        // https://jdenticon.com/icon-designer.html?config=4451860010ff320028501e5a
-        {
-            provide: JDENTICON_CONFIG,
-            useValue: {
-                lightness: {
-                    color: [0.26, 0.8],
-                    grayscale: [0.3, 0.9],
-                },
-                saturation: {
-                    color: 0.5,
-                    grayscale: 0.46,
-                },
-                backColor: '#0000',
-            },
-        },
-        // Custom error i18nk keys
-        {
-            provide: APP_FORM_ERROR_I18N_KEYS,
-            useValue: {
-                ...IdentityConfirmValidators.I18N_ERROR_KEYS,
-            },
+        saturation: {
+          color: 0.5,
+          grayscale: 0.46,
         },
+        backColor: '#0000',
+      },
+    },
+    // Custom error i18nk keys
+    {
+      provide: APP_FORM_ERROR_I18N_KEYS,
+      useValue: {
+        ...IdentityConfirmValidators.I18N_ERROR_KEYS,
+      },
+    },
 
-      // Http client
-      provideHttpClient(withInterceptorsFromDi()),
+    // Http client
+    provideHttpClient(withInterceptorsFromDi()),
 
-      // Zone less (experimental)
-      provideExperimentalZonelessChangeDetection(),
-    ] })
+    // Zone less (experimental)
+    provideExperimentalZonelessChangeDetection(),
+  ],
+})
 export class AppModule {}
diff --git a/src/app/currency/currency.model.ts b/src/app/currency/currency.model.ts
index e65a6534c84e45c3b130029927a593741bb6b510..f1b931939f58d5ff70debf1e1b3b937fdd01535a 100644
--- a/src/app/currency/currency.model.ts
+++ b/src/app/currency/currency.model.ts
@@ -16,4 +16,7 @@ export interface Currency {
   };
   decimals: number;
   minBlockHeight?: number;
+  params: {
+    minAccessibleReferees: number;
+  };
 }
diff --git a/src/app/currency/currency.page.html b/src/app/currency/currency.page.html
index 17b4c2441e24f3e6c0c5ce77e598cb3d8da88e5f..94b83521c9c300eda4fda49e1b4099bdfafeb387 100644
--- a/src/app/currency/currency.page.html
+++ b/src/app/currency/currency.page.html
@@ -14,11 +14,33 @@
     </ion-toolbar>
   </ion-header>
 
-  <div id="container">
+  <div id="container" *rxIf="loaded$; else listSkeleton">
     <ion-grid class="ion-no-padding">
+      <ion-row>
+        <ion-col size="2" size-sm="0" size-md="0" size-lg="2"></ion-col>
+        <ion-col size="8" size-sm="12" size-md="12" size-lg="8" size-xs="12">
+          <ion-card>
+            <ion-card-content>
+              <ion-label
+                [innerHTML]="
+                  'CURRENCY.VIEW.CURRENCY_SHORT_DESCRIPTION'
+                    | translate
+                      : {
+                          currency: params.currencyName,
+                          firstBlockTime: firstBlockTime$ | async | dateFromNow,
+                          N: params.members,
+                          dt: params.udCreationPeriodMs | duration: 'ms'
+                        }
+                "
+              ></ion-label>
+            </ion-card-content>
+          </ion-card>
+        </ion-col>
+        <ion-col size="2" size-sm="0" size-md="0" size-lg="2"></ion-col>
+      </ion-row>
       <ion-row>
         <ion-col size="12" size-sm="6">
-          <ion-list *rxIf="loaded$; else listSkeleton" lines="none">
+          <ion-list lines="none">
             <ion-item-divider translate>CURRENCY.VIEW.TITLE</ion-item-divider>
 
             <ion-item>
diff --git a/src/app/currency/currency.page.ts b/src/app/currency/currency.page.ts
index e17deda9cc65ace591a18f17a8a964e75f6d7a15..42392ab8650722a66621590e011bb082c00afcf5 100644
--- a/src/app/currency/currency.page.ts
+++ b/src/app/currency/currency.page.ts
@@ -7,15 +7,17 @@ import { RxState } from '@rx-angular/state';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
 import { SettingsService } from '@app/settings/settings.service';
 import { CurrencyDisplayUnit } from '@app/settings/settings.model';
-import { map, switchMap } from 'rxjs/operators';
 import { isNotEmptyArray, toBoolean, toNumber } from '@app/shared/functions';
 import { CurrencyHistory } from '@app/currency/currency-history.model';
 import { ChartDataset, ChartOptions } from 'chart.js';
-import { Observable } from 'rxjs';
+import { Observable, switchMap } from 'rxjs';
 import { IndexerService } from '@app/network/indexer/indexer.service';
 import { Currency } from '@app/currency/currency.model';
-import moment from 'moment';
+import moment, { Moment } from 'moment';
 import { Color } from '@app/shared/colors/graph-colors';
+import { ModalController } from '@ionic/angular';
+import { Promise } from '@rx-angular/cdk/zone-less/browser';
+import { map } from 'rxjs/operators';
 
 export interface CurrencyParameters {
   currencyName: string;
@@ -61,6 +63,7 @@ export interface CurrencyPageState extends AppPageState {
   isLogarithmic: boolean;
   chartReady: boolean;
   membersVariation: number;
+  firstBlockTime: Moment;
 }
 
 @Component({
@@ -76,6 +79,7 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
   @RxStateSelect() protected chartLabels$: Observable<string[]>;
   @RxStateSelect() protected chartReady$: Observable<string[]>;
   @RxStateSelect() protected membersVariation$: Observable<number>;
+  @RxStateSelect() protected firstBlockTime$: Observable<Moment>;
 
   @RxStateProperty() protected params: CurrencyParameters;
   @RxStateProperty() protected wotParams: WotParameters;
@@ -87,6 +91,7 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
   @RxStateProperty() protected chartLoaded: boolean;
   @RxStateProperty() protected chartReady: boolean;
   @RxStateProperty() protected membersVariation: number;
+  @RxStateProperty() protected firstBlockTime: Moment;
 
   @Input() @RxStateProperty() showAllRulesCurrency: boolean;
   @Input() @RxStateProperty() showAllRulesWot: boolean;
@@ -154,6 +159,7 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
     protected indexer: IndexerService,
     protected settings: SettingsService,
     protected cd: ChangeDetectorRef,
+    protected modalCtrl: ModalController,
     private sanitizer: DomSanitizer
   ) {
     super({ name: 'currency-service' });
@@ -178,6 +184,7 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
     );
     this._state.connect('membersVariation', this._state.select('currencyHistory').pipe(map((value) => this.getMembersVariation(value))));
     this._state.connect('chartLabels', this._state.select('currencyHistory').pipe(map((value) => this.prepareLineChartLabel(value))));
+    this._state.connect('firstBlockTime', this._state.select('currencyHistory').pipe(map((value) => this.getFirstBlockValue(value))));
     this._state.connect(
       'chartReady',
       this._state
@@ -262,6 +269,7 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
       sentries,
       xPercent,
     };
+
     return { currency, paramsByUnit, showAllRulesCurrency, showAllRulesWot, useRelativeUnit, wotParams };
   }
 
@@ -375,4 +383,8 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
     const membersCountPast = histories[histories.length - 2];
     return membersCountCurrent.membersCount - membersCountPast.membersCount;
   }
+
+  private getFirstBlockValue(histories: CurrencyHistory[]): Moment {
+    return moment(histories[0].timestamp);
+  }
 }
diff --git a/src/app/currency/currency.service.ts b/src/app/currency/currency.service.ts
deleted file mode 100644
index e41923b0f749ffcfdecffe72a5aad45de52da6a5..0000000000000000000000000000000000000000
--- a/src/app/currency/currency.service.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Injectable } from '@angular/core';
-import { SettingsService } from '@app/settings/settings.service';
-import { StartableService } from '@app/shared/services/startable-service.class';
-import { Promise } from '@rx-angular/cdk/zone-less/browser';
-import { IndexerService } from '@app/network/indexer/indexer.service';
-
-@Injectable({ providedIn: 'root' })
-export class CurrencyService extends StartableService {
-  constructor(
-    private indexer: IndexerService,
-    private settings: SettingsService
-  ) {
-    super(settings);
-  }
-
-  protected ngOnStart(): Promise<void> {
-    return Promise.resolve(undefined);
-  }
-}
diff --git a/src/app/home/about/about.modal.css b/src/app/home/about/about.modal.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/home/about/about.modal.html b/src/app/home/about/about.modal.html
new file mode 100644
index 0000000000000000000000000000000000000000..4acaa1eb98f4a443d2f52000bf62f5656d8e6f23
--- /dev/null
+++ b/src/app/home/about/about.modal.html
@@ -0,0 +1,111 @@
+<ion-header [translucent]="true" *ngIf="showToolbar">
+  <ion-toolbar color="primary">
+    <ion-buttons slot="start">
+      <ion-menu-button *ngIf="!canGoBack"></ion-menu-button>
+      <ion-back-button></ion-back-button>
+    </ion-buttons>
+    <ion-title translate>ABOUT.TITLE</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <ion-header collapse="condense">
+    <ion-toolbar>
+      <ion-title size="large" translate>ABOUT.TITLE</ion-title>
+    </ion-toolbar>
+  </ion-header>
+
+  <ion-list lines="none">
+    <ion-item class="item-icon-left item-text-wrap">
+      <ion-icon slot="start"></ion-icon>
+      <ion-label>
+        {{ 'COMMON.APP_NAME' | translate }}&nbsp;
+        <b>{{ 'COMMON.APP_VERSION' | translate: { version: environment.version } }}</b>
+        -
+        <a href="{{ environment.officialUrl }}" target="_system">{{ environment.officialUrl }}</a>
+      </ion-label>
+      <ion-label [innerHTML]="'ABOUT.LICENSE' | translate"></ion-label>
+    </ion-item>
+
+    @if (isUpdateAvailable()) {
+      <ion-item>
+        <ion-icon slot="start" color="danger" name="alert-circle-outline"></ion-icon>
+        <ion-label
+          [innerHTML]="'ABOUT.LATEST_RELEASE' | translate: { appName: 'COMMON.APP_NAME' | translate, version: environment.version }"
+        ></ion-label>
+      </ion-item>
+    }
+
+    <ion-item>
+      <ion-icon slot="start" name="laptop-outline"></ion-icon>
+      <ion-label translate>ABOUT.OFFICIAL_WEB_SITE</ion-label>
+      <ion-label>
+        <a href="{{ environment.sourceUrl }}" target="_system" translate>{{ environment.sourceUrl }}</a>
+      </ion-label>
+    </ion-item>
+
+    <ion-item>
+      <ion-icon slot="start" name="chatbubbles"></ion-icon>
+      <ion-label translate>ABOUT.FORUM</ion-label>
+      <ion-label>
+        <a href="{{ environment.forumUrl }}" target="_system">{{ environment.forumUrl }}</a>
+      </ion-label>
+    </ion-item>
+
+    <ion-item>
+      <ion-icon slot="start" name="bug"></ion-icon>
+      <ion-label translate>ABOUT.PLEASE_REPORT_ISSUE</ion-label>
+      <ion-label>
+        <a href="{{ environment.reportIssueUrl }}" target="_system" translate>ABOUT.REPORT_ISSUE</a>
+      </ion-label>
+    </ion-item>
+
+    <ion-item>
+      <ion-icon slot="start" name="git-network"></ion-icon>
+      <ion-label translate>ABOUT.CODE</ion-label>
+      <ion-label>
+        <a href="{{ environment.sourceUrl }}" target="_system" translate>{{ environment.sourceUrl }}</a>
+      </ion-label>
+    </ion-item>
+    <ion-item>
+      <ion-icon slot="start" name="people"></ion-icon>
+      <ion-label translate>ABOUT.DEVELOPERS</ion-label>
+      <ion-label>
+        <a href="https://github.com/blavenie" target="_system">Benoit Lavenier</a>
+        ,
+        <a href="https://github.com/bpresles" target="_system">bpresles</a>
+        ,
+        <a href="https://github.com/c-geek" target="_system">cgeek</a>
+        ,
+        <a href="https://github.com/devingfx" target="_system">DiG</a>
+        ,
+        <a href="https://git.duniter.org/ji_emme" target="_system">Ji_emme</a>
+        ,
+        <a href="https://git.duniter.org/matograine" target="_system">matograine</a>
+        ,
+        <a href="https://github.com/duniter/cesium/graphs/contributors" target="_system" title="{{ 'HOME.SHOW_ALL_FEED' | translate }}">...</a>
+      </ion-label>
+    </ion-item>
+  </ion-list>
+</ion-content>
+@if (!mobile) {
+  <ion-footer>
+    <ion-toolbar>
+      <ion-row class="ion-no-padding" nowrap>
+        <ion-col size="4"></ion-col>
+        <!-- buttons -->
+        <ion-col size="8">
+          <ion-button color="light" (click)="goToHelpPage()" tappable>
+            <ion-icon slot="start" name="help-circle-outline"></ion-icon>
+            <ion-label translate>HOME.BTN_HELP</ion-label>
+          </ion-button>
+
+          <ion-button (click)="cancel()">
+            <ion-label translate>COMMON.BTN_CLOSE</ion-label>
+          </ion-button>
+        </ion-col>
+        <ion-col size="4"></ion-col>
+      </ion-row>
+    </ion-toolbar>
+  </ion-footer>
+}
diff --git a/src/app/home/about/about.modal.spec.ts b/src/app/home/about/about.modal.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1523334ee1b58d960ba4f352e12fa8855ff388f1
--- /dev/null
+++ b/src/app/home/about/about.modal.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { AboutModal } from './about.modal';
+
+describe('AboutModalComponent', () => {
+  let component: AboutModal;
+  let fixture: ComponentFixture<AboutModal>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [AboutModal],
+      imports: [IonicModule.forRoot()],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AboutModal);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/home/about/about.modal.ts b/src/app/home/about/about.modal.ts
new file mode 100644
index 0000000000000000000000000000000000000000..19a937591de9218e03cea51376b7cb87ddb3d48a
--- /dev/null
+++ b/src/app/home/about/about.modal.ts
@@ -0,0 +1,51 @@
+import { Component, Input } from '@angular/core';
+import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
+import { RxState } from '@rx-angular/state';
+import { Promise } from '@rx-angular/cdk/zone-less/browser';
+import { TranslateService } from '@ngx-translate/core';
+import { environment } from '@environments/environment';
+import { ModalController } from '@ionic/angular';
+import { Router } from '@angular/router';
+
+export interface AboutModalState extends AppPageState {}
+
+@Component({
+  selector: 'app-about',
+  templateUrl: './about.modal.html',
+  styleUrls: ['./about.modal.css'],
+  providers: [RxState],
+})
+export class AboutModal extends AppPage<AboutModalState> {
+  protected readonly environment = environment;
+
+  @Input() showToolbar = true;
+  version: string;
+
+  constructor(
+    protected translate: TranslateService,
+    protected viewCtrl: ModalController,
+    protected router: Router
+  ) {
+    super({ name: 'about-modal' });
+    this.version = environment.version;
+  }
+
+  protected ngOnLoad(): Promise<Partial<AboutModalState>> {
+    return Promise.resolve(undefined);
+  }
+
+  cancel() {
+    this.viewCtrl.dismiss();
+  }
+
+  goToHelpPage() {
+    this.viewCtrl.dismiss();
+    this.router.navigateByUrl('/help', {
+      replaceUrl: true,
+    });
+  }
+
+  isUpdateAvailable() {
+    return this.environment.version !== this.version; //TODO: need more information about the current version and remote version
+  }
+}
diff --git a/src/app/home/about/about.module.ts b/src/app/home/about/about.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ca6aa6aaa63ff69224a2b06f37c85e7a3adfba3f
--- /dev/null
+++ b/src/app/home/about/about.module.ts
@@ -0,0 +1,14 @@
+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 { AboutModal } from '@app/home/about/about.modal';
+
+@NgModule({
+  imports: [AppSharedModule, TranslateModule.forChild(), HomePageRoutingModule, AppAuthModule, AppRegisterModule, AppTransferModule],
+  declarations: [AboutModal],
+})
+export class AboutModule {}
diff --git a/src/app/home/feed/feed.component.html b/src/app/home/feed/feed.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..c46963b79c798a6d834f2889c736f613e587a100
--- /dev/null
+++ b/src/app/home/feed/feed.component.html
@@ -0,0 +1,56 @@
+@if ((topics | isNotEmptyArray) && topics.length > 0) {
+  <div class="feed ion-padding-horizontal ion-no-padding ion-padding-top">
+    <ion-item color="transparent" lines="none">
+      <ion-icon color="light" slot="start" name="megaphone"></ion-icon>
+      <ion-label color="light">
+        <b translate>HOME.NEWS</b>
+        <ion-button fill="clear" (click)="redirectToForumHome()" translate>
+          HOME.SHOW_ALL_FEED
+          <ion-icon slot="end" color="medium" name="chevron-forward-outline"></ion-icon>
+        </ion-button>
+      </ion-label>
+    </ion-item>
+    @for (topic of topics; track topic) {
+      <ion-card>
+        <ion-card-header>
+          <ion-card-subtitle style="vertical-align: middle">
+            <ion-chip>
+              <ion-avatar>
+                <img [alt]="topic?.authorAvatar" [src]="topic?.feedItem.authorAvatar" />
+              </ion-avatar>
+              <ion-label color="medium">{{ topic?.feedItem.author }}</ion-label>
+            </ion-chip>
+            <ion-note class="ion-float-end">
+              <small>{{ topic?.feedItem.date_published | dateFromNow }}</small>
+            </ion-note>
+          </ion-card-subtitle>
+          <ion-card-title (click)="redirectToForum(topic.feedUrl)" tappable>{{ topic?.fancyTitle }}</ion-card-title>
+          @if (topic?.tags | isNotEmptyArray) {
+            <div style="display: inline">
+              @for (tag of topic.tags; track tag) {
+                <ion-chip>
+                  <ion-label color="medium">#{{ tag }}</ion-label>
+                </ion-chip>
+              }
+            </div>
+          }
+        </ion-card-header>
+
+        <ion-card-content>
+          <ion-text [innerHTML]="topic?.feedItem.content_html"></ion-text>
+        </ion-card-content>
+        @if (!topic?.feedItem.truncated) {
+          <ion-button (click)="redirectToForum(topic.feedUrl)" class="ion-float-end" fill="clear" translate>
+            COMMON.BTN_SHOW
+            <ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
+          </ion-button>
+        } @else {
+          <ion-button (click)="redirectToForum(topic.feedUrl)" class="ion-float-end" fill="clear" translate>
+            HOME.READ_MORE
+            <ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
+          </ion-button>
+        }
+      </ion-card>
+    }
+  </div>
+}
diff --git a/src/app/home/feed/feed.component.scss b/src/app/home/feed/feed.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2b087e3d36c87194376996312c521b8d8c43ca9d
--- /dev/null
+++ b/src/app/home/feed/feed.component.scss
@@ -0,0 +1,40 @@
+
+.feed {
+  ion-item {
+    --color: var(--ion-color-dark-contrast);
+    ion-icon[slot=start] {
+      -webkit-margin-end: 8px;
+      margin-inline-end: 8px;
+    }
+  }
+
+
+  ion-card {
+    --ion-card-background: rgba(var(--ion-text-color-rgb), 0.3);
+    --ion-card-color: var(--ion-color-dark-contrast);
+
+    ion-card-header {
+      ion-card-title {
+        --color: var(--ion-color-dark-contrast);
+      }
+      ion-chip {
+        --background: transparent;
+        --border-color: transparent;
+        --border-width: 0;
+
+        ion-avatar {
+          border: 1px solid var(--ion-color-medium);
+        }
+      }
+    }
+  }
+
+  ion-button {
+    text-transform: unset;
+    color: var(--ion-color-step-400);
+  }
+
+  a:hover {
+    color: var(--ion-color-medium);
+  }
+}
diff --git a/src/app/home/feed/feed.component.spec.ts b/src/app/home/feed/feed.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..204301f3aea8a384170357962f51e2ee48f9b31f
--- /dev/null
+++ b/src/app/home/feed/feed.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { FeedComponent } from './feed.component';
+
+describe('AboutModalComponent', () => {
+  let component: FeedComponent;
+  let fixture: ComponentFixture<FeedComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [FeedComponent],
+      imports: [IonicModule.forRoot()],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(FeedComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/home/feed/feed.component.ts b/src/app/home/feed/feed.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c3303c16c82a7907e32cf8e99119d0589bd84ae0
--- /dev/null
+++ b/src/app/home/feed/feed.component.ts
@@ -0,0 +1,55 @@
+import { Component, Input } from '@angular/core';
+import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
+import { RxState } from '@rx-angular/state';
+import { Promise } from '@rx-angular/cdk/zone-less/browser';
+import { TranslateService } from '@ngx-translate/core';
+import { environment } from '@environments/environment';
+import { Router } from '@angular/router';
+import { NetworkService } from '@app/network/network.service';
+import { JsonTopic } from '@app/home/feed/feed.model';
+import { SettingsService } from '@app/settings/settings.service';
+import { isNotNil } from '@app/shared/functions';
+
+export interface FeedState extends AppPageState {
+  topics: JsonTopic[];
+}
+
+@Component({
+  selector: 'app-feeds',
+  templateUrl: './feed.component.html',
+  styleUrls: ['./feed.component.scss'],
+  providers: [RxState],
+})
+export class FeedComponent extends AppPage<FeedState> {
+  @Input() showToolbar = true;
+
+  topics: JsonTopic[];
+  version: string;
+
+  constructor(
+    protected translate: TranslateService,
+    protected settings: SettingsService,
+    protected networkService: NetworkService,
+    protected router: Router
+  ) {
+    super({ name: 'about-modal' });
+  }
+
+  protected async ngOnLoad(): Promise<FeedState> {
+    await Promise.all([this.settings.ready(), this.networkService.ready()]);
+    const feedUrl = environment.feed.jsonFeed.get(this.settings.locale);
+    this.topics = await this.networkService.loadJsonFeed(feedUrl);
+    this.topics = this.topics.filter(isNotNil).map((value) => value);
+    return <FeedState>{ topics: this.topics };
+  }
+
+  redirectToForum(url: string) {
+    window.open(url.replace(/\.json$/, ''), '_blank');
+  }
+
+  redirectToForumHome() {
+    window.open(environment.forumUrl, '_blank');
+  }
+
+  protected readonly environment = environment;
+}
diff --git a/src/app/home/feed/feed.model.ts b/src/app/home/feed/feed.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ba6cfc1e968b275e7426ffe3d98ba43000d029e9
--- /dev/null
+++ b/src/app/home/feed/feed.model.ts
@@ -0,0 +1,88 @@
+import { Moment } from 'moment';
+
+export class JsonFeedItem {
+  constructor(author: string, authorAvatar: string, content_html: string, date_published: string, truncated: boolean) {
+    this.author = author;
+    this.authorAvatar = authorAvatar;
+    this.content_html = content_html;
+    this.date_published = date_published;
+    this.truncated = truncated;
+  }
+  author: string;
+  authorAvatar: string;
+  content_html: string;
+  date_published: string;
+  truncated: boolean;
+}
+
+export class JsonTopic {
+  constructor(
+    archived: boolean,
+    createdAt: Moment,
+    updatedAt: Moment,
+    author: string,
+    authorAvatar: string,
+    fancyTitle: string,
+    tags: unknown[],
+    feedItem: JsonFeedItem,
+    feedUrl: string
+  ) {
+    this.archived = archived;
+    this.createdAt = createdAt;
+    this.updatedAt = updatedAt;
+    this.author = author;
+    this.authorAvatar = authorAvatar;
+    this.fancyTitle = fancyTitle;
+    this.tags = tags;
+    this.feedItem = feedItem;
+    this.feedUrl = feedUrl;
+  }
+  feedItem: JsonFeedItem;
+  archived: boolean;
+  createdAt: Moment;
+  updatedAt: Moment;
+  author: string;
+  authorAvatar: string;
+  fancyTitle: string;
+  tags: unknown[];
+  feedUrl: string;
+}
+
+export interface Topic {
+  id: number;
+  title: string;
+  fancy_title: string;
+  slug: string;
+  posts_count: number;
+  reply_count: number;
+  highest_post_number: number;
+  image_url: string | null;
+  created_at: string;
+  last_posted_at: string;
+  bumped: boolean;
+  bumped_at: string;
+  archetype: string;
+  unseen: boolean;
+  pinned: boolean;
+  unpinned: string | null;
+  excerpt: string;
+  visible: boolean;
+  closed: boolean;
+  archived: boolean;
+  bookmarked: string | null;
+  liked: string | null;
+  views: number;
+  like_count: number;
+  has_summary: boolean;
+  last_poster_username: string;
+  category_id: number;
+  pinned_globally: boolean;
+  featured_link: string | null;
+  tags: string[];
+  posters: {
+    extras: string;
+    description: string;
+    user_id: number;
+    primary_group_id: number | null;
+  }[];
+}
diff --git a/src/app/home/feed/feed.module.ts b/src/app/home/feed/feed.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5c4fa3fd2ea09800035af0a3a2929bdf143f5343
--- /dev/null
+++ b/src/app/home/feed/feed.module.ts
@@ -0,0 +1,24 @@
+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,
+  ],
+  declarations: [FeedComponent],
+  exports: [FeedComponent],
+})
+export class FeedModule {}
diff --git a/src/app/home/help/help-routing.module.ts b/src/app/home/help/help-routing.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c1de2427694a044b7f01bd5bdd0ce4cffb2415e0
--- /dev/null
+++ b/src/app/home/help/help-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { HelpPage } from '@app/home/help/help.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    pathMatch: 'full',
+    component: HelpPage,
+  },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class HelpPageRoutingModule {}
diff --git a/src/app/home/help/help.module.ts b/src/app/home/help/help.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aaba39986d6800d42f1a92c7b02cb50dc44f8778
--- /dev/null
+++ b/src/app/home/help/help.module.ts
@@ -0,0 +1,12 @@
+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 { HelpPage } from '@app/home/help/help.page';
+
+@NgModule({
+  imports: [AppSharedModule, TranslateModule, HomePageRoutingModule],
+  declarations: [HelpPage],
+})
+export class HelpModule {}
diff --git a/src/app/home/help/help.page.html b/src/app/home/help/help.page.html
new file mode 100644
index 0000000000000000000000000000000000000000..1c7dd5e8778486153efeaa3e35d40e7c18d78527
--- /dev/null
+++ b/src/app/home/help/help.page.html
@@ -0,0 +1,197 @@
+<ion-header [translucent]="true">
+  <ion-toolbar color="primary">
+    <ion-buttons slot="start">
+      <ion-menu-button *ngIf="!canGoBack"></ion-menu-button>
+      <ion-back-button></ion-back-button>
+    </ion-buttons>
+    <ion-title translate>HELP.TITLE</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <ion-header collapse="condense">
+    <ion-toolbar>
+      <ion-title size="large" translate>HELP.TITLE</ion-title>
+    </ion-toolbar>
+  </ion-header>
+
+  <ion-list>
+    @if (isDemo()) {
+      <ion-item id="DEMO_MODE_HELP" lines="none">
+        <ion-grid class="highlight">
+          <ion-row>
+            <ion-col size="4" size-lg="4" size-sm="12">
+              <ion-label translate>MODE.DEMO.MODE</ion-label>
+            </ion-col>
+            <ion-col size="8" size-lg="8" size-sm="12">
+              <ion-label color="dark" [innerHTML]="'MODE.DEMO.MODE_HELP' | translate"></ion-label>
+            </ion-col>
+          </ion-row>
+        </ion-grid>
+      </ion-item>
+    }
+    @if (isReadonly()) {
+      <ion-item id="READONLY_MODE_HELP" lines="none">
+        <ion-grid class="highlight">
+          <ion-row>
+            <ion-col size="4" size-lg="4" size-sm="12">
+              <ion-label translate>MODE.READONLY.MODE</ion-label>
+            </ion-col>
+            <ion-col size="8" size-lg="8" size-sm="12">
+              <ion-label color="dark" [innerHTML]="'MODE.READONLY.MODE_HELP' | translate"></ion-label>
+            </ion-col>
+          </ion-row>
+        </ion-grid>
+      </ion-item>
+    }
+    <ion-item-divider translate>HELP.JOIN.SECTION</ion-item-divider>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>LOGIN.SALT</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.JOIN.SALT' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>LOGIN.PASSWORD</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.JOIN.PASSWORD' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>WOT.PSEUDO</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.JOIN.PSEUDO' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+
+    <ion-item-divider translate>HELP.LOGIN.SECTION</ion-item-divider>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>HELP.LOGIN.PUBKEY</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.LOGIN.PUBKEY_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>HELP.LOGIN.METHOD</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.LOGIN.METHOD_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+
+    <ion-item-divider translate>HELP.GLOSSARY.SECTION</ion-item-divider>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>COMMON.PUBKEY</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.PUBKEY_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label [innerHTML]="'HELP.GLOSSARY.BLOCKCHAIN' | translate"></ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.BLOCKCHAIN_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>COMMON.UNIVERSAL_DIVIDEND</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.UNIVERSAL_DIVIDEND_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>HELP.GLOSSARY.MEMBER</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.MEMBER_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>HELP.GLOSSARY.WOT</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.WOT_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item lines="none">
+      <ion-grid>
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12">
+            <ion-label translate>HELP.GLOSSARY.CURRENCY_RULES</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.CURRENCY_RULES_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+    <ion-item id="GLOSSARY_DISTANCE_RULE" lines="none">
+      <ion-grid [ngClass]="{ highlight: isDefinitionGlossaryDistanceRule() }">
+        <ion-row>
+          <ion-col size="4" size-lg="4" size-sm="12" [ngClass]="{ 'text-bold': isDefinitionGlossaryDistanceRule() }">
+            <ion-label translate>HELP.GLOSSARY.DISTANCE_RULE</ion-label>
+          </ion-col>
+          <ion-col size="8" size-lg="8" size-sm="12">
+            <ion-label color="dark" [innerHTML]="'HELP.GLOSSARY.DISTANCE_RULE_DEF' | translate"></ion-label>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </ion-item>
+  </ion-list>
+</ion-content>
diff --git a/src/app/home/help/help.page.scss b/src/app/home/help/help.page.scss
new file mode 100644
index 0000000000000000000000000000000000000000..aa9ad85da71a8dd719a93547e5c032d8a73de0fd
--- /dev/null
+++ b/src/app/home/help/help.page.scss
@@ -0,0 +1,11 @@
+@import 'ionic.globals';
+@import 'cesium.globals';
+
+ion-item-divider {
+  font-size: 24px;
+  color: $font-family-base;
+}
+
+.highlight {
+  background-color: #ffe0b2;
+}
diff --git a/src/app/home/help/help.page.spec.ts b/src/app/home/help/help.page.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/home/help/help.page.ts b/src/app/home/help/help.page.ts
new file mode 100644
index 0000000000000000000000000000000000000000..15d477f54870e5e55b8115ad83465942d76f09ca
--- /dev/null
+++ b/src/app/home/help/help.page.ts
@@ -0,0 +1,78 @@
+import { Component, inject, Inject, Input, OnInit, ViewChild } from '@angular/core';
+import { APP_LOCALES, LocaleConfig, Settings } from '@app/settings/settings.model';
+import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
+import { NetworkService } from '@app/network/network.service';
+import { fadeInAnimation } from '@app/shared/animations';
+import { Router } from '@angular/router';
+import { RxStateProperty } from '@app/shared/decorator/state.decorator';
+import { RxState } from '@rx-angular/state';
+import { TranslateService } from '@ngx-translate/core';
+import { IonContent } from '@ionic/angular';
+import { isNotNilOrBlank } from '@app/shared/functions';
+
+export interface HelpPageState extends AppPageState, Settings {}
+
+export declare type HighlightedDefinition = 'GLOSSARY_DISTANCE_RULE' | 'DEMO_MODE_HELP' | 'READONLY_MODE_HELP' | '';
+
+@Component({
+  selector: 'app-help',
+  templateUrl: './help.page.html',
+  styleUrls: ['./help.page.scss'],
+  animations: [fadeInAnimation],
+  providers: [RxState],
+})
+export class HelpPage extends AppPage<HelpPageState> implements OnInit {
+  @ViewChild(IonContent, { static: true }) content: IonContent;
+  @RxStateProperty() locale: string;
+
+  @Input() highlightedDefinition: HighlightedDefinition;
+
+  protected translate = inject(TranslateService);
+
+  constructor(
+    protected networkService: NetworkService,
+    protected router: Router,
+    @Inject(APP_LOCALES) public locales: LocaleConfig[]
+  ) {
+    super({ name: 'help' });
+  }
+
+  protected async ngOnLoad() {
+    await Promise.all([this.networkService.ready()]);
+
+    if (isNotNilOrBlank(this.highlightedDefinition)) {
+      this.scrollToDefinition(this.highlightedDefinition);
+    }
+    return {
+      ...this.settings.clone(),
+    };
+  }
+
+  isDefinitionGlossaryDistanceRule() {
+    return this.highlightedDefinition === 'GLOSSARY_DISTANCE_RULE';
+  }
+
+  isDemo() {
+    return this.highlightedDefinition === 'DEMO_MODE_HELP';
+  }
+
+  isReadonly() {
+    return this.highlightedDefinition === 'READONLY_MODE_HELP';
+  }
+
+  async scrollToDefinition(definitionId: string) {
+    const targetElement = document.getElementById(definitionId);
+    if (targetElement) {
+      const scrollElement = await this.content.getScrollElement();
+      const yOffset = targetElement.getBoundingClientRect().top - scrollElement.getBoundingClientRect().top;
+      this.content
+        .scrollToPoint(0, yOffset, 500)
+        .then(() => {
+          console.log(`${this._logPrefix}Scrolled to ${definitionId}`);
+        })
+        .catch((err) => {
+          console.error(`${this._logPrefix}Scroll error:`, err);
+        });
+    }
+  }
+}
diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts
index 7dd5a1b3728d6adb055e50c56336502dc8e9d43b..e83c53af3f4a5759b5b68759cb24c9506fc262c6 100644
--- a/src/app/home/home.module.ts
+++ b/src/app/home/home.module.ts
@@ -7,9 +7,10 @@ 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 { FeedModule } from '@app/home/feed/feed.module';
 
 @NgModule({
-  imports: [AppSharedModule, TranslateModule.forChild(), HomePageRoutingModule, AppAuthModule, AppRegisterModule, AppTransferModule],
+  imports: [AppSharedModule, TranslateModule.forChild(), HomePageRoutingModule, AppAuthModule, AppRegisterModule, AppTransferModule, FeedModule],
   declarations: [HomePage],
 })
 export class HomeModule {}
diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html
index 6b532d86628ebedb97726724ad27dd3a4fc0fc91..0307edc85eaaa25abc02f55958d217d67b3f7492 100644
--- a/src/app/home/home.page.html
+++ b/src/app/home/home.page.html
@@ -1,4 +1,4 @@
-<ion-header [translucent]="true" *ngIf="mobile">
+<ion-header [translucent]="true">
   <ion-toolbar color="primary">
     <ion-buttons slot="start">
       <ion-menu-button></ion-menu-button>
@@ -11,77 +11,112 @@
 </ion-header>
 
 <ion-content [fullscreen]="true" class="circle-bg-dark">
+  <app-error-item [message]="error$ | async" [backgroundColor]="'danger'"></app-error-item>
+
+  @if (isDev() || isDemo()) {
+    <div class="ribbon">
+      @if (isDemo()) {
+        <ion-badge color="danger" (click)="openHelpModal('DEMO_MODE_HELP')" translate>MODE.DEMO.BADGE</ion-badge>
+      }
+      @if (isDev()) {
+        <ion-badge color="success" (click)="openHelpModal('READONLY_MODE_HELP')" translate>MODE.READONLY.BADGE</ion-badge>
+      }
+      <a [href]="environment.sourceUrl" target="_blank" title="{{ 'HOME.FORK_ME' | translate }}">
+        <ion-badge color="secondary" translate>HOME.FREE_SOFTWARE</ion-badge>
+      </a>
+      <a href="https://git.duniter.org/clients/cesium-grp/cesium/-/raw/master/LICENSE" target="_blank" title="{{ 'HOME.SHOW_LICENSE' | translate }}">
+        <ion-badge color="light">AGPL-3.0</ion-badge>
+      </a>
+    </div>
+  }
+
   <!-- Desktop: translucent top toolbar -->
-  <div *ngIf="!mobile">
-    <ion-toolbar color="transparent">
-      <ion-buttons slot="start">
-        <ion-menu-toggle>
-          <ion-button color="light" fill="clear">
-            <ion-icon slot="icon-only" name="menu"></ion-icon>
-          </ion-button>
-        </ion-menu-toggle>
-      </ion-buttons>
+  <!--  <div *ngIf="!mobile">-->
+  <!--    <ion-toolbar color="transparent">-->
+  <!--      <ion-buttons slot="start">-->
+  <!--        <ion-menu-toggle>-->
+  <!--          <ion-button color="light" fill="clear">-->
+  <!--            <ion-icon slot="icon-only" name="menu"></ion-icon>-->
+  <!--          </ion-button>-->
+  <!--        </ion-menu-toggle>-->
+  <!--      </ion-buttons>-->
 
-      <ion-buttons slot="end">
-        <ng-container *ngTemplateOutlet="darkModeButton; context: { $implicit: 'light' }"></ng-container>
-        <ng-container *ngTemplateOutlet="localeButton; context: { $implicit: 'light' }"></ng-container>
-      </ion-buttons>
-    </ion-toolbar>
-  </div>
+  <!--      <ion-buttons slot="end">-->
+  <!--        <ng-container *ngTemplateOutlet="darkModeButton; context: { $implicit: 'light' }"></ng-container>-->
+  <!--        <ng-container *ngTemplateOutlet="localeButton; context: { $implicit: 'light' }"></ng-container>-->
+  <!--      </ion-buttons>-->
+  <!--    </ion-toolbar>-->
+  <!--  </div>-->
+  <ion-row class="ion-no-padding">
+    <ion-col size="0" [sizeXl]="hasFeeds() ? 3 : 0"></ion-col>
+    <ion-col>
+      <ion-card class="main welcome ion-padding ion-text-center ion-align-self-center">
+        <ion-card-header>
+          <div class="logo"></div>
+          <ion-card-subtitle [innerHTML]="'HOME.WELCOME' | translate"></ion-card-subtitle>
+          <ion-card-title class="ion-text-center">
+            <ion-spinner *rxIf="loading$; else message"></ion-spinner>
+            <ng-template #message>
+              {{ 'HOME.MESSAGE' | translate: { currency: currency$ | async } }}
+            </ng-template>
+          </ion-card-title>
+        </ion-card-header>
+        <ion-card-content *rxIf="loaded$" @fadeInAnimation>
+          <ng-container *ngIf="isLogin; else noAccount">
+            <!-- my account -->
+            <ion-button expand="block" [routerLink]="'/wallet'">
+              <ion-icon name="person" slot="start"></ion-icon>
+              <ion-label translate>MENU.ACCOUNT</ion-label>
+            </ion-button>
 
-  <div id="container">
-    <ion-card class="main welcome ion-padding ion-text-center ion-align-self-center">
-      <ion-card-header>
-        <div class="logo"></div>
-        <ion-card-subtitle [innerHTML]="'HOME.WELCOME' | translate"></ion-card-subtitle>
-        <ion-card-title class="ion-text-center">
-          <ion-spinner *rxIf="loading$; else message"></ion-spinner>
-          <ng-template #message>
-            {{ 'HOME.MESSAGE' | translate: { currency: currency$ | async } }}
-          </ng-template>
-        </ion-card-title>
-      </ion-card-header>
-      <ion-card-content *rxIf="loaded$" @fadeInAnimation>
-        <ng-container *ngIf="isLogin; else noAccount">
-          <!-- my account -->
-          <ion-button expand="block" [routerLink]="'/wallet'">
-            <ion-icon name="person" slot="start"></ion-icon>
-            <ion-label translate>MENU.ACCOUNT</ion-label>
-          </ion-button>
+            <!-- transfer -->
+            <ion-button expand="block" (click)="transfer()">
+              <ion-icon name="paper-plane" slot="start"></ion-icon>
+              <ion-label translate>COMMON.BTN_SEND_MONEY</ion-label>
+            </ion-button>
 
-          <!-- transfer -->
-          <ion-button expand="block" (click)="transfer()">
-            <ion-icon name="paper-plane" slot="start"></ion-icon>
-            <ion-label translate>COMMON.BTN_SEND_MONEY</ion-label>
-          </ion-button>
+            <!-- disconnect button -->
+            <p [class.cdk-visually-hidden]="mobile" *rxIf="defaultAccount$; let defaultAccount">
+              <ion-text [innerHTML]="'HOME.NOT_YOUR_ACCOUNT_QUESTION' | translate: { pubkey: (defaultAccount | accountName) }"></ion-text>
+              <br />
+              <ion-text>
+                <a href="#" (click)="logout($event)">
+                  <span translate>HOME.BTN_CHANGE_ACCOUNT</span>
+                </a>
+              </ion-text>
+            </p>
 
-          <!-- disconnect button -->
-          <p [class.cdk-visually-hidden]="mobile" *rxIf="defaultAccount$; let defaultAccount">
-            <ion-text [innerHTML]="'HOME.NOT_YOUR_ACCOUNT_QUESTION' | translate: { pubkey: (defaultAccount | accountName) }"></ion-text>
-            <br />
-            <ion-text>
-              <a href="#" (click)="logout($event)">
-                <span translate>HOME.BTN_CHANGE_ACCOUNT</span>
-              </a>
-            </ion-text>
-          </p>
-        </ng-container>
+            @if (isDemo()) {
+              <p>
+                <ion-icon name="help-circle" slot="start"></ion-icon>
+                <ion-label [innerHTML]="'MODE.DEMO.MODE_HELP' | translate"></ion-label>
+              </p>
+              <p>
+                <a (click)="openHelpModal('DEMO_MODE_HELP')" tappable translate>HOME.READ_MORE</a>
+              </p>
+            }
+          </ng-container>
 
-        <ng-template #noAccount>
-          <!-- register -->
-          <ion-button expand="block" (click)="register($event)">
-            <ion-label translate>LOGIN.CREATE_FREE_ACCOUNT</ion-label>
-          </ion-button>
+          <ng-template #noAccount>
+            <!-- register -->
+            <ion-button expand="block" (click)="register($event)">
+              <ion-label translate>LOGIN.CREATE_FREE_ACCOUNT</ion-label>
+            </ion-button>
 
-          <!-- login -->
-          <p class="ion-padding-top" translate>LOGIN.HAVE_ACCOUNT_QUESTION</p>
-          <ion-button expand="block" (click)="login($event)">
-            <ion-label translate>COMMON.BTN_LOGIN</ion-label>
-          </ion-button>
-        </ng-template>
-      </ion-card-content>
-    </ion-card>
-  </div>
+            <!-- login -->
+            <p class="ion-padding-top" translate>LOGIN.HAVE_ACCOUNT_QUESTION</p>
+            <ion-button expand="block" (click)="login($event)">
+              <ion-label translate>COMMON.BTN_LOGIN</ion-label>
+            </ion-button>
+          </ng-template>
+        </ion-card-content>
+      </ion-card>
+    </ion-col>
+    <ion-col size="0" [sizeXl]="hasFeeds() ? 1 : 0"></ion-col>
+    <ion-col [size]="hasFeeds() ? 12 : 0" [sizeXl]="hasFeeds() ? 4 : 0">
+      <app-feeds #feeds></app-feeds>
+    </ion-col>
+  </ion-row>
 </ion-content>
 
 <ng-template #localeButton let-buttonColor>
@@ -106,9 +141,7 @@
 </ng-template>
 
 <ng-template #darkModeButton let-buttonColor>
-  <ion-button (click)="toggleDarkMode()"
-              [color]="buttonColor"
-              [title]="'SETTINGS.BTN_DARK_MODE' | translate">
+  <ion-button (click)="toggleDarkMode()" [color]="buttonColor" [title]="'SETTINGS.BTN_DARK_MODE' | translate">
     <ion-icon slot="icon-only" [name]="settings.darkMode ? 'sunny' : 'moon'"></ion-icon>
   </ion-button>
 </ng-template>
diff --git a/src/app/home/home.page.scss b/src/app/home/home.page.scss
index 475104bbfbf3ab04bfd9d4eb00f1a6c8efa653b6..c371df05f688ae12a9017e560f5b23811e8ead5d 100644
--- a/src/app/home/home.page.scss
+++ b/src/app/home/home.page.scss
@@ -11,6 +11,7 @@ h5 {
 .ion-text-center {
   text-align: center;
 }
+
 ion-content {
   --background: transparent;
   --ion-toolbar-background: transparent;
@@ -26,6 +27,7 @@ ion-content {
 
   ion-card {
     z-index: 9;
+
     ion-card-header {
       display: block;
 
@@ -98,3 +100,34 @@ ion-content {
     background-size: 1024px 1024px;
   }
 }
+
+.ribbon {
+  position: absolute;
+  top: 70px;
+  right: -100px;
+  z-index: 500;
+  transform: rotate(45deg);
+  width: 300px;
+  text-decoration: none;
+  box-shadow: 0 0 5px #000;
+  a {
+    text-decoration: none;
+  }
+  ion-badge:first-child {
+    opacity: 1 !important;
+  }
+
+  ion-badge {
+    display: block;
+    width: 100%;
+    line-height: 16px;
+    opacity: 0.9;
+  }
+
+  ion-badge:hover {
+    opacity: 1;
+    font-size: 16px;
+  }
+}
+
+
diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts
index 8fb25a686176bf6e7695aa9ea91344053b1eef7b..b79f499fbbd37c056cd06bb90210a344048ff276 100644
--- a/src/app/home/home.page.ts
+++ b/src/app/home/home.page.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit, ViewChild } from '@angular/core';
 import { APP_LOCALES, LocaleConfig, Settings } from '@app/settings/settings.model';
 import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
 import { NetworkService } from '@app/network/network.service';
@@ -13,7 +13,13 @@ import { Observable } from 'rxjs';
 import { Currency } from '@app/currency/currency.model';
 import { RxState } from '@rx-angular/state';
 import { setTimeout } from '@rx-angular/cdk/zone-less/browser';
-import { AlertController } from '@ionic/angular';
+import { AlertController, ModalController } from '@ionic/angular';
+import { FeedComponent } from '@app/home/feed/feed.component';
+import { isNotEmptyArray } from '@app/shared/functions';
+import { environment } from '@environments/environment';
+import { HelpPage } from '@app/home/help/help.page';
+import { isDemo, isDev } from '@app/shared/environment/environment.utils';
+import moment from 'moment';
 
 export interface HomePageState extends AppPageState, Settings {
   defaultAccount: Account;
@@ -28,6 +34,8 @@ export interface HomePageState extends AppPageState, Settings {
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
 export class HomePage extends AppPage<HomePageState> implements OnInit {
+  @ViewChild('feeds') feeds: FeedComponent;
+
   @RxStateProperty() defaultAccount: Account;
   @RxStateProperty() locale: string;
 
@@ -45,6 +53,7 @@ export class HomePage extends AppPage<HomePageState> implements OnInit {
     protected authController: AuthController,
     protected transferController: TransferController,
     protected router: Router,
+    protected modalCtrl: ModalController,
     private cd: ChangeDetectorRef,
     @Inject(APP_LOCALES) public locales: LocaleConfig[]
   ) {
@@ -78,6 +87,18 @@ export class HomePage extends AppPage<HomePageState> implements OnInit {
       //auth: true,
     });
     if (data?.address) {
+      if (data.meta?.isMember) {
+        const redeemPeriod = this.settings.selectedRedeemPeriod;
+        const now = moment();
+
+        const lastRedeem = this.settings.lastRedeemDate.startOf('day');
+
+        if (lastRedeem.add(1, redeemPeriod).isBefore(now)) {
+          await this.accountService.claimUds(data);
+          this.settings.patchValue({ lastRedeemDate: now });
+        }
+      }
+
       this.defaultAccount = data;
       setTimeout(() => this.router.navigate(['/wallet', data.address]));
     }
@@ -125,6 +146,27 @@ export class HomePage extends AppPage<HomePageState> implements OnInit {
   }
 
   toggleDarkMode() {
-      this.settings.patchValue({ darkMode: !this.settings.darkMode});
+    this.settings.patchValue({ darkMode: !this.settings.darkMode });
+  }
+
+  hasFeeds() {
+    return isNotEmptyArray(this.feeds?.topics);
+  }
+
+  async openHelpModal(definition: string) {
+    const modal = await this.modalCtrl.create({
+      id: 'help-modal',
+      component: HelpPage,
+      componentProps: {
+        highlightedDefinition: definition,
+      },
+      presentingElement: this._presentingElement,
+      canDismiss: true,
+    });
+    await modal.present();
   }
+  protected readonly environment = environment;
+  protected readonly open = open;
+  protected readonly isDemo = isDemo;
+  protected readonly isDev = isDev;
 }
diff --git a/src/app/network/indexer/indexer-certification.gql b/src/app/network/indexer/indexer-certification.gql
index 98a04d2e805dc6c1faed64520a9541ca97f6084b..4f298e63f6871b1a3f764dd5ea52b3f1dfaf2690 100644
--- a/src/app/network/indexer/indexer-certification.gql
+++ b/src/app/network/indexer/indexer-certification.gql
@@ -1,4 +1,3 @@
-
 fragment LightCert on Cert {
   __typename
   id
diff --git a/src/app/network/indexer/indexer-helpers.generated.ts b/src/app/network/indexer/indexer-helpers.generated.ts
index 51973f2fd2edccf6ab313a559274172f06f02466..819f9b354a07fc0ea4a3a070e8892e3e23f049d3 100644
--- a/src/app/network/indexer/indexer-helpers.generated.ts
+++ b/src/app/network/indexer/indexer-helpers.generated.ts
@@ -1,10 +1,20 @@
 import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';
-export type AccountKeySpecifier = ('id' | 'identity' | 'linkedIdentity' | 'linkedIdentityId' | 'transfersIssued' | 'transfersIssuedAggregate' | 'transfersIssued_connection' | 'transfersReceived' | 'transfersReceivedAggregate' | 'transfersReceived_connection' | 'wasIdentity' | 'wasIdentityAggregate' | 'wasIdentity_connection' | AccountKeySpecifier)[];
+export type AccountKeySpecifier = ('balance' | 'commentsIssued' | 'commentsIssuedAggregate' | 'commentsIssued_connection' | 'createdOn' | 'id' | 'identity' | 'isActive' | 'linkedIdentity' | 'linkedIdentityId' | 'removedIdentities' | 'removedIdentitiesAggregate' | 'removedIdentities_connection' | 'totalBalance' | 'transfersIssued' | 'transfersIssuedAggregate' | 'transfersIssued_connection' | 'transfersReceived' | 'transfersReceivedAggregate' | 'transfersReceived_connection' | 'wasIdentity' | 'wasIdentityAggregate' | 'wasIdentity_connection' | AccountKeySpecifier)[];
 export type AccountFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentsIssued?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentsIssuedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentsIssued_connection?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
 	identity?: FieldPolicy<any> | FieldReadFunction<any>,
+	isActive?: FieldPolicy<any> | FieldReadFunction<any>,
 	linkedIdentity?: FieldPolicy<any> | FieldReadFunction<any>,
 	linkedIdentityId?: FieldPolicy<any> | FieldReadFunction<any>,
+	removedIdentities?: FieldPolicy<any> | FieldReadFunction<any>,
+	removedIdentitiesAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	removedIdentities_connection?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>,
 	transfersIssued?: FieldPolicy<any> | FieldReadFunction<any>,
 	transfersIssuedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
 	transfersIssued_connection?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -20,11 +30,25 @@ export type AccountAggregateFieldPolicy = {
 	aggregate?: FieldPolicy<any> | FieldReadFunction<any>,
 	nodes?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type AccountAggregateFieldsKeySpecifier = ('count' | 'max' | 'min' | AccountAggregateFieldsKeySpecifier)[];
+export type AccountAggregateFieldsKeySpecifier = ('avg' | 'count' | 'max' | 'min' | 'stddev' | 'stddevPop' | 'stddevSamp' | 'sum' | 'varPop' | 'varSamp' | 'variance' | AccountAggregateFieldsKeySpecifier)[];
 export type AccountAggregateFieldsFieldPolicy = {
+	avg?: FieldPolicy<any> | FieldReadFunction<any>,
 	count?: FieldPolicy<any> | FieldReadFunction<any>,
 	max?: FieldPolicy<any> | FieldReadFunction<any>,
-	min?: FieldPolicy<any> | FieldReadFunction<any>
+	min?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddev?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	sum?: FieldPolicy<any> | FieldReadFunction<any>,
+	varPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	varSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	variance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountAvgFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountAvgFieldsKeySpecifier)[];
+export type AccountAvgFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
 };
 export type AccountConnectionKeySpecifier = ('edges' | 'pageInfo' | AccountConnectionKeySpecifier)[];
 export type AccountConnectionFieldPolicy = {
@@ -36,15 +60,63 @@ export type AccountEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type AccountMaxFieldsKeySpecifier = ('id' | 'linkedIdentityId' | AccountMaxFieldsKeySpecifier)[];
+export type AccountMaxFieldsKeySpecifier = ('balance' | 'createdOn' | 'id' | 'linkedIdentityId' | 'totalBalance' | AccountMaxFieldsKeySpecifier)[];
 export type AccountMaxFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
-	linkedIdentityId?: FieldPolicy<any> | FieldReadFunction<any>
+	linkedIdentityId?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type AccountMinFieldsKeySpecifier = ('id' | 'linkedIdentityId' | AccountMinFieldsKeySpecifier)[];
+export type AccountMinFieldsKeySpecifier = ('balance' | 'createdOn' | 'id' | 'linkedIdentityId' | 'totalBalance' | AccountMinFieldsKeySpecifier)[];
 export type AccountMinFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
-	linkedIdentityId?: FieldPolicy<any> | FieldReadFunction<any>
+	linkedIdentityId?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountStddevFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountStddevFieldsKeySpecifier)[];
+export type AccountStddevFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountStddevPopFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountStddevPopFieldsKeySpecifier)[];
+export type AccountStddevPopFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountStddevSampFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountStddevSampFieldsKeySpecifier)[];
+export type AccountStddevSampFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountSumFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountSumFieldsKeySpecifier)[];
+export type AccountSumFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountVarPopFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountVarPopFieldsKeySpecifier)[];
+export type AccountVarPopFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountVarSampFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountVarSampFieldsKeySpecifier)[];
+export type AccountVarSampFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type AccountVarianceFieldsKeySpecifier = ('balance' | 'createdOn' | 'totalBalance' | AccountVarianceFieldsKeySpecifier)[];
+export type AccountVarianceFieldsFieldPolicy = {
+	balance?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	totalBalance?: FieldPolicy<any> | FieldReadFunction<any>
 };
 export type BlockKeySpecifier = ('calls' | 'callsAggregate' | 'callsCount' | 'calls_connection' | 'events' | 'eventsAggregate' | 'eventsCount' | 'events_connection' | 'extrinsics' | 'extrinsicsAggregate' | 'extrinsicsCount' | 'extrinsics_connection' | 'extrinsicsicRoot' | 'hash' | 'height' | 'id' | 'implName' | 'implVersion' | 'parentHash' | 'specName' | 'specVersion' | 'stateRoot' | 'timestamp' | 'validator' | BlockKeySpecifier)[];
 export type BlockFieldPolicy = {
@@ -668,10 +740,12 @@ export type ExtrinsicVarianceFieldsFieldPolicy = {
 	tip?: FieldPolicy<any> | FieldReadFunction<any>,
 	version?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type IdentityKeySpecifier = ('account' | 'accountId' | 'certIssued' | 'certIssuedAggregate' | 'certIssued_connection' | 'certReceived' | 'certReceivedAggregate' | 'certReceived_connection' | 'createdIn' | 'createdInId' | 'createdOn' | 'expireOn' | 'id' | 'index' | 'isMember' | 'lastChangeOn' | 'linkedAccount' | 'linkedAccountAggregate' | 'linkedAccount_connection' | 'membershipHistory' | 'membershipHistoryAggregate' | 'membershipHistory_connection' | 'name' | 'ownerKeyChange' | 'ownerKeyChangeAggregate' | 'ownerKeyChange_connection' | 'smithCertIssued' | 'smithCertIssuedAggregate' | 'smithCertIssued_connection' | 'smithCertReceived' | 'smithCertReceivedAggregate' | 'smithCertReceived_connection' | 'smithStatus' | 'status' | 'udHistory' | IdentityKeySpecifier)[];
+export type IdentityKeySpecifier = ('account' | 'accountId' | 'accountRemoved' | 'accountRemovedId' | 'certIssued' | 'certIssuedAggregate' | 'certIssued_connection' | 'certReceived' | 'certReceivedAggregate' | 'certReceived_connection' | 'createdIn' | 'createdInId' | 'createdOn' | 'expireOn' | 'firstEligibleUd' | 'id' | 'index' | 'isMember' | 'lastChangeOn' | 'linkedAccount' | 'linkedAccountAggregate' | 'linkedAccount_connection' | 'membershipHistory' | 'membershipHistoryAggregate' | 'membershipHistory_connection' | 'name' | 'ownerKeyChange' | 'ownerKeyChangeAggregate' | 'ownerKeyChange_connection' | 'smith' | 'status' | 'udHistory' | IdentityKeySpecifier)[];
 export type IdentityFieldPolicy = {
 	account?: FieldPolicy<any> | FieldReadFunction<any>,
 	accountId?: FieldPolicy<any> | FieldReadFunction<any>,
+	accountRemoved?: FieldPolicy<any> | FieldReadFunction<any>,
+	accountRemovedId?: FieldPolicy<any> | FieldReadFunction<any>,
 	certIssued?: FieldPolicy<any> | FieldReadFunction<any>,
 	certIssuedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
 	certIssued_connection?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -682,6 +756,7 @@ export type IdentityFieldPolicy = {
 	createdInId?: FieldPolicy<any> | FieldReadFunction<any>,
 	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
 	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
 	index?: FieldPolicy<any> | FieldReadFunction<any>,
 	isMember?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -696,16 +771,37 @@ export type IdentityFieldPolicy = {
 	ownerKeyChange?: FieldPolicy<any> | FieldReadFunction<any>,
 	ownerKeyChangeAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
 	ownerKeyChange_connection?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertIssued?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertIssuedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertIssued_connection?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertReceived?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertReceivedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithCertReceived_connection?: FieldPolicy<any> | FieldReadFunction<any>,
-	smithStatus?: FieldPolicy<any> | FieldReadFunction<any>,
+	smith?: FieldPolicy<any> | FieldReadFunction<any>,
 	status?: FieldPolicy<any> | FieldReadFunction<any>,
 	udHistory?: FieldPolicy<any> | FieldReadFunction<any>
 };
+export type IdentityAggregateKeySpecifier = ('aggregate' | 'nodes' | IdentityAggregateKeySpecifier)[];
+export type IdentityAggregateFieldPolicy = {
+	aggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	nodes?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityAggregateFieldsKeySpecifier = ('avg' | 'count' | 'max' | 'min' | 'stddev' | 'stddevPop' | 'stddevSamp' | 'sum' | 'varPop' | 'varSamp' | 'variance' | IdentityAggregateFieldsKeySpecifier)[];
+export type IdentityAggregateFieldsFieldPolicy = {
+	avg?: FieldPolicy<any> | FieldReadFunction<any>,
+	count?: FieldPolicy<any> | FieldReadFunction<any>,
+	max?: FieldPolicy<any> | FieldReadFunction<any>,
+	min?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddev?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	sum?: FieldPolicy<any> | FieldReadFunction<any>,
+	varPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	varSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	variance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityAvgFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityAvgFieldsKeySpecifier)[];
+export type IdentityAvgFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
 export type IdentityConnectionKeySpecifier = ('edges' | 'pageInfo' | IdentityConnectionKeySpecifier)[];
 export type IdentityConnectionFieldPolicy = {
 	edges?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -716,6 +812,88 @@ export type IdentityEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
+export type IdentityMaxFieldsKeySpecifier = ('accountId' | 'accountRemovedId' | 'createdInId' | 'createdOn' | 'expireOn' | 'firstEligibleUd' | 'id' | 'index' | 'lastChangeOn' | 'name' | IdentityMaxFieldsKeySpecifier)[];
+export type IdentityMaxFieldsFieldPolicy = {
+	accountId?: FieldPolicy<any> | FieldReadFunction<any>,
+	accountRemovedId?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdInId?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	name?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityMinFieldsKeySpecifier = ('accountId' | 'accountRemovedId' | 'createdInId' | 'createdOn' | 'expireOn' | 'firstEligibleUd' | 'id' | 'index' | 'lastChangeOn' | 'name' | IdentityMinFieldsKeySpecifier)[];
+export type IdentityMinFieldsFieldPolicy = {
+	accountId?: FieldPolicy<any> | FieldReadFunction<any>,
+	accountRemovedId?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdInId?: FieldPolicy<any> | FieldReadFunction<any>,
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	name?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityStddevFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityStddevFieldsKeySpecifier)[];
+export type IdentityStddevFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityStddevPopFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityStddevPopFieldsKeySpecifier)[];
+export type IdentityStddevPopFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityStddevSampFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityStddevSampFieldsKeySpecifier)[];
+export type IdentityStddevSampFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentitySumFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentitySumFieldsKeySpecifier)[];
+export type IdentitySumFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityVarPopFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityVarPopFieldsKeySpecifier)[];
+export type IdentityVarPopFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityVarSampFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityVarSampFieldsKeySpecifier)[];
+export type IdentityVarSampFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type IdentityVarianceFieldsKeySpecifier = ('createdOn' | 'expireOn' | 'firstEligibleUd' | 'index' | 'lastChangeOn' | IdentityVarianceFieldsKeySpecifier)[];
+export type IdentityVarianceFieldsFieldPolicy = {
+	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	expireOn?: FieldPolicy<any> | FieldReadFunction<any>,
+	firstEligibleUd?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChangeOn?: FieldPolicy<any> | FieldReadFunction<any>
+};
 export type ItemsCounterKeySpecifier = ('id' | 'level' | 'total' | 'type' | ItemsCounterKeySpecifier)[];
 export type ItemsCounterFieldPolicy = {
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -829,6 +1007,44 @@ export type PageInfoFieldPolicy = {
 	hasPreviousPage?: FieldPolicy<any> | FieldReadFunction<any>,
 	startCursor?: FieldPolicy<any> | FieldReadFunction<any>
 };
+export type PopulationHistoryKeySpecifier = ('activeAccountCount' | 'blockNumber' | 'id' | 'memberCount' | 'smithCount' | PopulationHistoryKeySpecifier)[];
+export type PopulationHistoryFieldPolicy = {
+	activeAccountCount?: FieldPolicy<any> | FieldReadFunction<any>,
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	memberCount?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCount?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type PopulationHistoryConnectionKeySpecifier = ('edges' | 'pageInfo' | PopulationHistoryConnectionKeySpecifier)[];
+export type PopulationHistoryConnectionFieldPolicy = {
+	edges?: FieldPolicy<any> | FieldReadFunction<any>,
+	pageInfo?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type PopulationHistoryEdgeKeySpecifier = ('cursor' | 'node' | PopulationHistoryEdgeKeySpecifier)[];
+export type PopulationHistoryEdgeFieldPolicy = {
+	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
+	node?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithKeySpecifier = ('forged' | 'id' | 'identity' | 'identityId' | 'index' | 'lastChanged' | 'lastForged' | 'smithCertIssued' | 'smithCertIssuedAggregate' | 'smithCertIssued_connection' | 'smithCertReceived' | 'smithCertReceivedAggregate' | 'smithCertReceived_connection' | 'smithHistory' | 'smithHistoryAggregate' | 'smithHistory_connection' | 'smithStatus' | SmithKeySpecifier)[];
+export type SmithFieldPolicy = {
+	forged?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	identity?: FieldPolicy<any> | FieldReadFunction<any>,
+	identityId?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastChanged?: FieldPolicy<any> | FieldReadFunction<any>,
+	lastForged?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertIssued?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertIssuedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertIssued_connection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertReceived?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertReceivedAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithCertReceived_connection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithHistory?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithHistoryAggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithHistory_connection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithStatus?: FieldPolicy<any> | FieldReadFunction<any>
+};
 export type SmithCertKeySpecifier = ('createdOn' | 'id' | 'issuer' | 'issuerId' | 'receiver' | 'receiverId' | SmithCertKeySpecifier)[];
 export type SmithCertFieldPolicy = {
 	createdOn?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -913,11 +1129,109 @@ export type SmithCertVarianceFieldsKeySpecifier = ('createdOn' | SmithCertVarian
 export type SmithCertVarianceFieldsFieldPolicy = {
 	createdOn?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type TransferKeySpecifier = ('amount' | 'blockNumber' | 'comment' | 'from' | 'fromId' | 'id' | 'timestamp' | 'to' | 'toId' | TransferKeySpecifier)[];
+export type SmithConnectionKeySpecifier = ('edges' | 'pageInfo' | SmithConnectionKeySpecifier)[];
+export type SmithConnectionFieldPolicy = {
+	edges?: FieldPolicy<any> | FieldReadFunction<any>,
+	pageInfo?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEdgeKeySpecifier = ('cursor' | 'node' | SmithEdgeKeySpecifier)[];
+export type SmithEdgeFieldPolicy = {
+	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
+	node?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventKeySpecifier = ('blockNumber' | 'event' | 'eventId' | 'eventType' | 'id' | 'smith' | 'smithId' | SmithEventKeySpecifier)[];
+export type SmithEventFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	event?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventType?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	smith?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithId?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventAggregateKeySpecifier = ('aggregate' | 'nodes' | SmithEventAggregateKeySpecifier)[];
+export type SmithEventAggregateFieldPolicy = {
+	aggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	nodes?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventAggregateFieldsKeySpecifier = ('avg' | 'count' | 'max' | 'min' | 'stddev' | 'stddevPop' | 'stddevSamp' | 'sum' | 'varPop' | 'varSamp' | 'variance' | SmithEventAggregateFieldsKeySpecifier)[];
+export type SmithEventAggregateFieldsFieldPolicy = {
+	avg?: FieldPolicy<any> | FieldReadFunction<any>,
+	count?: FieldPolicy<any> | FieldReadFunction<any>,
+	max?: FieldPolicy<any> | FieldReadFunction<any>,
+	min?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddev?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	sum?: FieldPolicy<any> | FieldReadFunction<any>,
+	varPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	varSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	variance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventAvgFieldsKeySpecifier = ('blockNumber' | SmithEventAvgFieldsKeySpecifier)[];
+export type SmithEventAvgFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventConnectionKeySpecifier = ('edges' | 'pageInfo' | SmithEventConnectionKeySpecifier)[];
+export type SmithEventConnectionFieldPolicy = {
+	edges?: FieldPolicy<any> | FieldReadFunction<any>,
+	pageInfo?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventEdgeKeySpecifier = ('cursor' | 'node' | SmithEventEdgeKeySpecifier)[];
+export type SmithEventEdgeFieldPolicy = {
+	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
+	node?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventMaxFieldsKeySpecifier = ('blockNumber' | 'eventId' | 'id' | 'smithId' | SmithEventMaxFieldsKeySpecifier)[];
+export type SmithEventMaxFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithId?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventMinFieldsKeySpecifier = ('blockNumber' | 'eventId' | 'id' | 'smithId' | SmithEventMinFieldsKeySpecifier)[];
+export type SmithEventMinFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithId?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventStddevFieldsKeySpecifier = ('blockNumber' | SmithEventStddevFieldsKeySpecifier)[];
+export type SmithEventStddevFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventStddevPopFieldsKeySpecifier = ('blockNumber' | SmithEventStddevPopFieldsKeySpecifier)[];
+export type SmithEventStddevPopFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventStddevSampFieldsKeySpecifier = ('blockNumber' | SmithEventStddevSampFieldsKeySpecifier)[];
+export type SmithEventStddevSampFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventSumFieldsKeySpecifier = ('blockNumber' | SmithEventSumFieldsKeySpecifier)[];
+export type SmithEventSumFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventVarPopFieldsKeySpecifier = ('blockNumber' | SmithEventVarPopFieldsKeySpecifier)[];
+export type SmithEventVarPopFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventVarSampFieldsKeySpecifier = ('blockNumber' | SmithEventVarSampFieldsKeySpecifier)[];
+export type SmithEventVarSampFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type SmithEventVarianceFieldsKeySpecifier = ('blockNumber' | SmithEventVarianceFieldsKeySpecifier)[];
+export type SmithEventVarianceFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TransferKeySpecifier = ('amount' | 'blockNumber' | 'comment' | 'commentId' | 'event' | 'eventId' | 'from' | 'fromId' | 'id' | 'timestamp' | 'to' | 'toId' | TransferKeySpecifier)[];
 export type TransferFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
 	comment?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentId?: FieldPolicy<any> | FieldReadFunction<any>,
+	event?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
 	from?: FieldPolicy<any> | FieldReadFunction<any>,
 	fromId?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -959,21 +1273,23 @@ export type TransferEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type TransferMaxFieldsKeySpecifier = ('amount' | 'blockNumber' | 'comment' | 'fromId' | 'id' | 'timestamp' | 'toId' | TransferMaxFieldsKeySpecifier)[];
+export type TransferMaxFieldsKeySpecifier = ('amount' | 'blockNumber' | 'commentId' | 'eventId' | 'fromId' | 'id' | 'timestamp' | 'toId' | TransferMaxFieldsKeySpecifier)[];
 export type TransferMaxFieldsFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
-	comment?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentId?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
 	fromId?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
 	timestamp?: FieldPolicy<any> | FieldReadFunction<any>,
 	toId?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type TransferMinFieldsKeySpecifier = ('amount' | 'blockNumber' | 'comment' | 'fromId' | 'id' | 'timestamp' | 'toId' | TransferMinFieldsKeySpecifier)[];
+export type TransferMinFieldsKeySpecifier = ('amount' | 'blockNumber' | 'commentId' | 'eventId' | 'fromId' | 'id' | 'timestamp' | 'toId' | TransferMinFieldsKeySpecifier)[];
 export type TransferMinFieldsFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
-	comment?: FieldPolicy<any> | FieldReadFunction<any>,
+	commentId?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
 	fromId?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
 	timestamp?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1014,6 +1330,98 @@ export type TransferVarianceFieldsFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
 };
+export type TxCommentKeySpecifier = ('author' | 'authorId' | 'blockNumber' | 'event' | 'eventId' | 'hash' | 'id' | 'remark' | 'remarkBytes' | 'type' | TxCommentKeySpecifier)[];
+export type TxCommentFieldPolicy = {
+	author?: FieldPolicy<any> | FieldReadFunction<any>,
+	authorId?: FieldPolicy<any> | FieldReadFunction<any>,
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	event?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	hash?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	remark?: FieldPolicy<any> | FieldReadFunction<any>,
+	remarkBytes?: FieldPolicy<any> | FieldReadFunction<any>,
+	type?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentAggregateKeySpecifier = ('aggregate' | 'nodes' | TxCommentAggregateKeySpecifier)[];
+export type TxCommentAggregateFieldPolicy = {
+	aggregate?: FieldPolicy<any> | FieldReadFunction<any>,
+	nodes?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentAggregateFieldsKeySpecifier = ('avg' | 'count' | 'max' | 'min' | 'stddev' | 'stddevPop' | 'stddevSamp' | 'sum' | 'varPop' | 'varSamp' | 'variance' | TxCommentAggregateFieldsKeySpecifier)[];
+export type TxCommentAggregateFieldsFieldPolicy = {
+	avg?: FieldPolicy<any> | FieldReadFunction<any>,
+	count?: FieldPolicy<any> | FieldReadFunction<any>,
+	max?: FieldPolicy<any> | FieldReadFunction<any>,
+	min?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddev?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	stddevSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	sum?: FieldPolicy<any> | FieldReadFunction<any>,
+	varPop?: FieldPolicy<any> | FieldReadFunction<any>,
+	varSamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	variance?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentAvgFieldsKeySpecifier = ('blockNumber' | TxCommentAvgFieldsKeySpecifier)[];
+export type TxCommentAvgFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentConnectionKeySpecifier = ('edges' | 'pageInfo' | TxCommentConnectionKeySpecifier)[];
+export type TxCommentConnectionFieldPolicy = {
+	edges?: FieldPolicy<any> | FieldReadFunction<any>,
+	pageInfo?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentEdgeKeySpecifier = ('cursor' | 'node' | TxCommentEdgeKeySpecifier)[];
+export type TxCommentEdgeFieldPolicy = {
+	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
+	node?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentMaxFieldsKeySpecifier = ('authorId' | 'blockNumber' | 'eventId' | 'hash' | 'id' | 'remark' | TxCommentMaxFieldsKeySpecifier)[];
+export type TxCommentMaxFieldsFieldPolicy = {
+	authorId?: FieldPolicy<any> | FieldReadFunction<any>,
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	hash?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	remark?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentMinFieldsKeySpecifier = ('authorId' | 'blockNumber' | 'eventId' | 'hash' | 'id' | 'remark' | TxCommentMinFieldsKeySpecifier)[];
+export type TxCommentMinFieldsFieldPolicy = {
+	authorId?: FieldPolicy<any> | FieldReadFunction<any>,
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
+	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
+	hash?: FieldPolicy<any> | FieldReadFunction<any>,
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	remark?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentStddevFieldsKeySpecifier = ('blockNumber' | TxCommentStddevFieldsKeySpecifier)[];
+export type TxCommentStddevFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentStddevPopFieldsKeySpecifier = ('blockNumber' | TxCommentStddevPopFieldsKeySpecifier)[];
+export type TxCommentStddevPopFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentStddevSampFieldsKeySpecifier = ('blockNumber' | TxCommentStddevSampFieldsKeySpecifier)[];
+export type TxCommentStddevSampFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentSumFieldsKeySpecifier = ('blockNumber' | TxCommentSumFieldsKeySpecifier)[];
+export type TxCommentSumFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentVarPopFieldsKeySpecifier = ('blockNumber' | TxCommentVarPopFieldsKeySpecifier)[];
+export type TxCommentVarPopFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentVarSampFieldsKeySpecifier = ('blockNumber' | TxCommentVarSampFieldsKeySpecifier)[];
+export type TxCommentVarSampFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type TxCommentVarianceFieldsKeySpecifier = ('blockNumber' | TxCommentVarianceFieldsKeySpecifier)[];
+export type TxCommentVarianceFieldsFieldPolicy = {
+	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>
+};
 export type UdHistoryKeySpecifier = ('amount' | 'blockNumber' | 'id' | 'identity' | 'identityId' | 'timestamp' | UdHistoryKeySpecifier)[];
 export type UdHistoryFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1033,7 +1441,7 @@ export type UdHistoryEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type UdReevalKeySpecifier = ('blockNumber' | 'event' | 'eventId' | 'id' | 'membersCount' | 'monetaryMass' | 'newUdAmount' | 'timestamp' | UdReevalKeySpecifier)[];
+export type UdReevalKeySpecifier = ('blockNumber' | 'event' | 'eventId' | 'id' | 'membersCount' | 'monetaryMass' | 'newUdAmount' | 'timestamp' | 'udIndex' | UdReevalKeySpecifier)[];
 export type UdReevalFieldPolicy = {
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
 	event?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1042,7 +1450,8 @@ export type UdReevalFieldPolicy = {
 	membersCount?: FieldPolicy<any> | FieldReadFunction<any>,
 	monetaryMass?: FieldPolicy<any> | FieldReadFunction<any>,
 	newUdAmount?: FieldPolicy<any> | FieldReadFunction<any>,
-	timestamp?: FieldPolicy<any> | FieldReadFunction<any>
+	timestamp?: FieldPolicy<any> | FieldReadFunction<any>,
+	udIndex?: FieldPolicy<any> | FieldReadFunction<any>
 };
 export type UdReevalConnectionKeySpecifier = ('edges' | 'pageInfo' | UdReevalConnectionKeySpecifier)[];
 export type UdReevalConnectionFieldPolicy = {
@@ -1054,13 +1463,14 @@ export type UdReevalEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type UniversalDividendKeySpecifier = ('amount' | 'blockNumber' | 'event' | 'eventId' | 'id' | 'membersCount' | 'monetaryMass' | 'timestamp' | UniversalDividendKeySpecifier)[];
+export type UniversalDividendKeySpecifier = ('amount' | 'blockNumber' | 'event' | 'eventId' | 'id' | 'index' | 'membersCount' | 'monetaryMass' | 'timestamp' | UniversalDividendKeySpecifier)[];
 export type UniversalDividendFieldPolicy = {
 	amount?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockNumber?: FieldPolicy<any> | FieldReadFunction<any>,
 	event?: FieldPolicy<any> | FieldReadFunction<any>,
 	eventId?: FieldPolicy<any> | FieldReadFunction<any>,
 	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>,
 	membersCount?: FieldPolicy<any> | FieldReadFunction<any>,
 	monetaryMass?: FieldPolicy<any> | FieldReadFunction<any>,
 	timestamp?: FieldPolicy<any> | FieldReadFunction<any>
@@ -1075,7 +1485,22 @@ export type UniversalDividendEdgeFieldPolicy = {
 	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type query_rootKeySpecifier = ('accountConnection' | 'blockConnection' | 'callConnection' | 'certConnection' | 'certEventConnection' | 'changeOwnerKeyConnection' | 'eventConnection' | 'extrinsicConnection' | 'getUdHistory_connection' | 'identityConnection' | 'itemsCounterConnection' | 'membershipEventConnection' | 'node' | 'smithCertConnection' | 'transferConnection' | 'udHistoryConnection' | 'udReevalConnection' | 'universalDividendConnection' | query_rootKeySpecifier)[];
+export type ValidatorKeySpecifier = ('id' | 'index' | ValidatorKeySpecifier)[];
+export type ValidatorFieldPolicy = {
+	id?: FieldPolicy<any> | FieldReadFunction<any>,
+	index?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type ValidatorConnectionKeySpecifier = ('edges' | 'pageInfo' | ValidatorConnectionKeySpecifier)[];
+export type ValidatorConnectionFieldPolicy = {
+	edges?: FieldPolicy<any> | FieldReadFunction<any>,
+	pageInfo?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type ValidatorEdgeKeySpecifier = ('cursor' | 'node' | ValidatorEdgeKeySpecifier)[];
+export type ValidatorEdgeFieldPolicy = {
+	cursor?: FieldPolicy<any> | FieldReadFunction<any>,
+	node?: FieldPolicy<any> | FieldReadFunction<any>
+};
+export type query_rootKeySpecifier = ('accountConnection' | 'blockConnection' | 'callConnection' | 'certConnection' | 'certEventConnection' | 'changeOwnerKeyConnection' | 'eventConnection' | 'extrinsicConnection' | 'getUdHistory_connection' | 'identityConnection' | 'itemsCounterConnection' | 'membershipEventConnection' | 'node' | 'populationHistoryConnection' | 'smithCertConnection' | 'smithConnection' | 'smithEventConnection' | 'transferConnection' | 'txCommentConnection' | 'udHistoryConnection' | 'udReevalConnection' | 'universalDividendConnection' | 'validatorConnection' | query_rootKeySpecifier)[];
 export type query_rootFieldPolicy = {
 	accountConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockConnection?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1090,13 +1515,18 @@ export type query_rootFieldPolicy = {
 	itemsCounterConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	membershipEventConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>,
+	populationHistoryConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	smithCertConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithEventConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	transferConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	txCommentConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	udHistoryConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	udReevalConnection?: FieldPolicy<any> | FieldReadFunction<any>,
-	universalDividendConnection?: FieldPolicy<any> | FieldReadFunction<any>
+	universalDividendConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	validatorConnection?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type subscription_rootKeySpecifier = ('accountConnection' | 'blockConnection' | 'callConnection' | 'certConnection' | 'certEventConnection' | 'changeOwnerKeyConnection' | 'eventConnection' | 'extrinsicConnection' | 'getUdHistory_connection' | 'identityConnection' | 'itemsCounterConnection' | 'membershipEventConnection' | 'node' | 'smithCertConnection' | 'transferConnection' | 'udHistoryConnection' | 'udReevalConnection' | 'universalDividendConnection' | subscription_rootKeySpecifier)[];
+export type subscription_rootKeySpecifier = ('accountConnection' | 'blockConnection' | 'callConnection' | 'certConnection' | 'certEventConnection' | 'changeOwnerKeyConnection' | 'eventConnection' | 'extrinsicConnection' | 'getUdHistory_connection' | 'identityConnection' | 'itemsCounterConnection' | 'membershipEventConnection' | 'node' | 'populationHistoryConnection' | 'smithCertConnection' | 'smithConnection' | 'smithEventConnection' | 'transferConnection' | 'txCommentConnection' | 'udHistoryConnection' | 'udReevalConnection' | 'universalDividendConnection' | 'validatorConnection' | subscription_rootKeySpecifier)[];
 export type subscription_rootFieldPolicy = {
 	accountConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	blockConnection?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1111,11 +1541,16 @@ export type subscription_rootFieldPolicy = {
 	itemsCounterConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	membershipEventConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	node?: FieldPolicy<any> | FieldReadFunction<any>,
+	populationHistoryConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	smithCertConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	smithEventConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	transferConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	txCommentConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	udHistoryConnection?: FieldPolicy<any> | FieldReadFunction<any>,
 	udReevalConnection?: FieldPolicy<any> | FieldReadFunction<any>,
-	universalDividendConnection?: FieldPolicy<any> | FieldReadFunction<any>
+	universalDividendConnection?: FieldPolicy<any> | FieldReadFunction<any>,
+	validatorConnection?: FieldPolicy<any> | FieldReadFunction<any>
 };
 export type StrictTypedTypePolicies = {
 	Account?: Omit<TypePolicy, "fields" | "keyFields"> & {
@@ -1130,6 +1565,10 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | AccountAggregateFieldsKeySpecifier | (() => undefined | AccountAggregateFieldsKeySpecifier),
 		fields?: AccountAggregateFieldsFieldPolicy,
 	},
+	AccountAvgFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountAvgFieldsKeySpecifier | (() => undefined | AccountAvgFieldsKeySpecifier),
+		fields?: AccountAvgFieldsFieldPolicy,
+	},
 	AccountConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | AccountConnectionKeySpecifier | (() => undefined | AccountConnectionKeySpecifier),
 		fields?: AccountConnectionFieldPolicy,
@@ -1146,6 +1585,34 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | AccountMinFieldsKeySpecifier | (() => undefined | AccountMinFieldsKeySpecifier),
 		fields?: AccountMinFieldsFieldPolicy,
 	},
+	AccountStddevFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountStddevFieldsKeySpecifier | (() => undefined | AccountStddevFieldsKeySpecifier),
+		fields?: AccountStddevFieldsFieldPolicy,
+	},
+	AccountStddevPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountStddevPopFieldsKeySpecifier | (() => undefined | AccountStddevPopFieldsKeySpecifier),
+		fields?: AccountStddevPopFieldsFieldPolicy,
+	},
+	AccountStddevSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountStddevSampFieldsKeySpecifier | (() => undefined | AccountStddevSampFieldsKeySpecifier),
+		fields?: AccountStddevSampFieldsFieldPolicy,
+	},
+	AccountSumFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountSumFieldsKeySpecifier | (() => undefined | AccountSumFieldsKeySpecifier),
+		fields?: AccountSumFieldsFieldPolicy,
+	},
+	AccountVarPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountVarPopFieldsKeySpecifier | (() => undefined | AccountVarPopFieldsKeySpecifier),
+		fields?: AccountVarPopFieldsFieldPolicy,
+	},
+	AccountVarSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountVarSampFieldsKeySpecifier | (() => undefined | AccountVarSampFieldsKeySpecifier),
+		fields?: AccountVarSampFieldsFieldPolicy,
+	},
+	AccountVarianceFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | AccountVarianceFieldsKeySpecifier | (() => undefined | AccountVarianceFieldsKeySpecifier),
+		fields?: AccountVarianceFieldsFieldPolicy,
+	},
 	Block?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | BlockKeySpecifier | (() => undefined | BlockKeySpecifier),
 		fields?: BlockFieldPolicy,
@@ -1490,6 +1957,18 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | IdentityKeySpecifier | (() => undefined | IdentityKeySpecifier),
 		fields?: IdentityFieldPolicy,
 	},
+	IdentityAggregate?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityAggregateKeySpecifier | (() => undefined | IdentityAggregateKeySpecifier),
+		fields?: IdentityAggregateFieldPolicy,
+	},
+	IdentityAggregateFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityAggregateFieldsKeySpecifier | (() => undefined | IdentityAggregateFieldsKeySpecifier),
+		fields?: IdentityAggregateFieldsFieldPolicy,
+	},
+	IdentityAvgFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityAvgFieldsKeySpecifier | (() => undefined | IdentityAvgFieldsKeySpecifier),
+		fields?: IdentityAvgFieldsFieldPolicy,
+	},
 	IdentityConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | IdentityConnectionKeySpecifier | (() => undefined | IdentityConnectionKeySpecifier),
 		fields?: IdentityConnectionFieldPolicy,
@@ -1498,6 +1977,42 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | IdentityEdgeKeySpecifier | (() => undefined | IdentityEdgeKeySpecifier),
 		fields?: IdentityEdgeFieldPolicy,
 	},
+	IdentityMaxFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityMaxFieldsKeySpecifier | (() => undefined | IdentityMaxFieldsKeySpecifier),
+		fields?: IdentityMaxFieldsFieldPolicy,
+	},
+	IdentityMinFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityMinFieldsKeySpecifier | (() => undefined | IdentityMinFieldsKeySpecifier),
+		fields?: IdentityMinFieldsFieldPolicy,
+	},
+	IdentityStddevFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityStddevFieldsKeySpecifier | (() => undefined | IdentityStddevFieldsKeySpecifier),
+		fields?: IdentityStddevFieldsFieldPolicy,
+	},
+	IdentityStddevPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityStddevPopFieldsKeySpecifier | (() => undefined | IdentityStddevPopFieldsKeySpecifier),
+		fields?: IdentityStddevPopFieldsFieldPolicy,
+	},
+	IdentityStddevSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityStddevSampFieldsKeySpecifier | (() => undefined | IdentityStddevSampFieldsKeySpecifier),
+		fields?: IdentityStddevSampFieldsFieldPolicy,
+	},
+	IdentitySumFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentitySumFieldsKeySpecifier | (() => undefined | IdentitySumFieldsKeySpecifier),
+		fields?: IdentitySumFieldsFieldPolicy,
+	},
+	IdentityVarPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityVarPopFieldsKeySpecifier | (() => undefined | IdentityVarPopFieldsKeySpecifier),
+		fields?: IdentityVarPopFieldsFieldPolicy,
+	},
+	IdentityVarSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityVarSampFieldsKeySpecifier | (() => undefined | IdentityVarSampFieldsKeySpecifier),
+		fields?: IdentityVarSampFieldsFieldPolicy,
+	},
+	IdentityVarianceFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | IdentityVarianceFieldsKeySpecifier | (() => undefined | IdentityVarianceFieldsKeySpecifier),
+		fields?: IdentityVarianceFieldsFieldPolicy,
+	},
 	ItemsCounter?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | ItemsCounterKeySpecifier | (() => undefined | ItemsCounterKeySpecifier),
 		fields?: ItemsCounterFieldPolicy,
@@ -1578,6 +2093,22 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | PageInfoKeySpecifier | (() => undefined | PageInfoKeySpecifier),
 		fields?: PageInfoFieldPolicy,
 	},
+	PopulationHistory?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | PopulationHistoryKeySpecifier | (() => undefined | PopulationHistoryKeySpecifier),
+		fields?: PopulationHistoryFieldPolicy,
+	},
+	PopulationHistoryConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | PopulationHistoryConnectionKeySpecifier | (() => undefined | PopulationHistoryConnectionKeySpecifier),
+		fields?: PopulationHistoryConnectionFieldPolicy,
+	},
+	PopulationHistoryEdge?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | PopulationHistoryEdgeKeySpecifier | (() => undefined | PopulationHistoryEdgeKeySpecifier),
+		fields?: PopulationHistoryEdgeFieldPolicy,
+	},
+	Smith?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithKeySpecifier | (() => undefined | SmithKeySpecifier),
+		fields?: SmithFieldPolicy,
+	},
 	SmithCert?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | SmithCertKeySpecifier | (() => undefined | SmithCertKeySpecifier),
 		fields?: SmithCertFieldPolicy,
@@ -1638,6 +2169,74 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | SmithCertVarianceFieldsKeySpecifier | (() => undefined | SmithCertVarianceFieldsKeySpecifier),
 		fields?: SmithCertVarianceFieldsFieldPolicy,
 	},
+	SmithConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithConnectionKeySpecifier | (() => undefined | SmithConnectionKeySpecifier),
+		fields?: SmithConnectionFieldPolicy,
+	},
+	SmithEdge?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEdgeKeySpecifier | (() => undefined | SmithEdgeKeySpecifier),
+		fields?: SmithEdgeFieldPolicy,
+	},
+	SmithEvent?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventKeySpecifier | (() => undefined | SmithEventKeySpecifier),
+		fields?: SmithEventFieldPolicy,
+	},
+	SmithEventAggregate?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventAggregateKeySpecifier | (() => undefined | SmithEventAggregateKeySpecifier),
+		fields?: SmithEventAggregateFieldPolicy,
+	},
+	SmithEventAggregateFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventAggregateFieldsKeySpecifier | (() => undefined | SmithEventAggregateFieldsKeySpecifier),
+		fields?: SmithEventAggregateFieldsFieldPolicy,
+	},
+	SmithEventAvgFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventAvgFieldsKeySpecifier | (() => undefined | SmithEventAvgFieldsKeySpecifier),
+		fields?: SmithEventAvgFieldsFieldPolicy,
+	},
+	SmithEventConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventConnectionKeySpecifier | (() => undefined | SmithEventConnectionKeySpecifier),
+		fields?: SmithEventConnectionFieldPolicy,
+	},
+	SmithEventEdge?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventEdgeKeySpecifier | (() => undefined | SmithEventEdgeKeySpecifier),
+		fields?: SmithEventEdgeFieldPolicy,
+	},
+	SmithEventMaxFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventMaxFieldsKeySpecifier | (() => undefined | SmithEventMaxFieldsKeySpecifier),
+		fields?: SmithEventMaxFieldsFieldPolicy,
+	},
+	SmithEventMinFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventMinFieldsKeySpecifier | (() => undefined | SmithEventMinFieldsKeySpecifier),
+		fields?: SmithEventMinFieldsFieldPolicy,
+	},
+	SmithEventStddevFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventStddevFieldsKeySpecifier | (() => undefined | SmithEventStddevFieldsKeySpecifier),
+		fields?: SmithEventStddevFieldsFieldPolicy,
+	},
+	SmithEventStddevPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventStddevPopFieldsKeySpecifier | (() => undefined | SmithEventStddevPopFieldsKeySpecifier),
+		fields?: SmithEventStddevPopFieldsFieldPolicy,
+	},
+	SmithEventStddevSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventStddevSampFieldsKeySpecifier | (() => undefined | SmithEventStddevSampFieldsKeySpecifier),
+		fields?: SmithEventStddevSampFieldsFieldPolicy,
+	},
+	SmithEventSumFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventSumFieldsKeySpecifier | (() => undefined | SmithEventSumFieldsKeySpecifier),
+		fields?: SmithEventSumFieldsFieldPolicy,
+	},
+	SmithEventVarPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventVarPopFieldsKeySpecifier | (() => undefined | SmithEventVarPopFieldsKeySpecifier),
+		fields?: SmithEventVarPopFieldsFieldPolicy,
+	},
+	SmithEventVarSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventVarSampFieldsKeySpecifier | (() => undefined | SmithEventVarSampFieldsKeySpecifier),
+		fields?: SmithEventVarSampFieldsFieldPolicy,
+	},
+	SmithEventVarianceFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | SmithEventVarianceFieldsKeySpecifier | (() => undefined | SmithEventVarianceFieldsKeySpecifier),
+		fields?: SmithEventVarianceFieldsFieldPolicy,
+	},
 	Transfer?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | TransferKeySpecifier | (() => undefined | TransferKeySpecifier),
 		fields?: TransferFieldPolicy,
@@ -1698,6 +2297,66 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | TransferVarianceFieldsKeySpecifier | (() => undefined | TransferVarianceFieldsKeySpecifier),
 		fields?: TransferVarianceFieldsFieldPolicy,
 	},
+	TxComment?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentKeySpecifier | (() => undefined | TxCommentKeySpecifier),
+		fields?: TxCommentFieldPolicy,
+	},
+	TxCommentAggregate?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentAggregateKeySpecifier | (() => undefined | TxCommentAggregateKeySpecifier),
+		fields?: TxCommentAggregateFieldPolicy,
+	},
+	TxCommentAggregateFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentAggregateFieldsKeySpecifier | (() => undefined | TxCommentAggregateFieldsKeySpecifier),
+		fields?: TxCommentAggregateFieldsFieldPolicy,
+	},
+	TxCommentAvgFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentAvgFieldsKeySpecifier | (() => undefined | TxCommentAvgFieldsKeySpecifier),
+		fields?: TxCommentAvgFieldsFieldPolicy,
+	},
+	TxCommentConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentConnectionKeySpecifier | (() => undefined | TxCommentConnectionKeySpecifier),
+		fields?: TxCommentConnectionFieldPolicy,
+	},
+	TxCommentEdge?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentEdgeKeySpecifier | (() => undefined | TxCommentEdgeKeySpecifier),
+		fields?: TxCommentEdgeFieldPolicy,
+	},
+	TxCommentMaxFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentMaxFieldsKeySpecifier | (() => undefined | TxCommentMaxFieldsKeySpecifier),
+		fields?: TxCommentMaxFieldsFieldPolicy,
+	},
+	TxCommentMinFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentMinFieldsKeySpecifier | (() => undefined | TxCommentMinFieldsKeySpecifier),
+		fields?: TxCommentMinFieldsFieldPolicy,
+	},
+	TxCommentStddevFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentStddevFieldsKeySpecifier | (() => undefined | TxCommentStddevFieldsKeySpecifier),
+		fields?: TxCommentStddevFieldsFieldPolicy,
+	},
+	TxCommentStddevPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentStddevPopFieldsKeySpecifier | (() => undefined | TxCommentStddevPopFieldsKeySpecifier),
+		fields?: TxCommentStddevPopFieldsFieldPolicy,
+	},
+	TxCommentStddevSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentStddevSampFieldsKeySpecifier | (() => undefined | TxCommentStddevSampFieldsKeySpecifier),
+		fields?: TxCommentStddevSampFieldsFieldPolicy,
+	},
+	TxCommentSumFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentSumFieldsKeySpecifier | (() => undefined | TxCommentSumFieldsKeySpecifier),
+		fields?: TxCommentSumFieldsFieldPolicy,
+	},
+	TxCommentVarPopFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentVarPopFieldsKeySpecifier | (() => undefined | TxCommentVarPopFieldsKeySpecifier),
+		fields?: TxCommentVarPopFieldsFieldPolicy,
+	},
+	TxCommentVarSampFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentVarSampFieldsKeySpecifier | (() => undefined | TxCommentVarSampFieldsKeySpecifier),
+		fields?: TxCommentVarSampFieldsFieldPolicy,
+	},
+	TxCommentVarianceFields?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | TxCommentVarianceFieldsKeySpecifier | (() => undefined | TxCommentVarianceFieldsKeySpecifier),
+		fields?: TxCommentVarianceFieldsFieldPolicy,
+	},
 	UdHistory?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | UdHistoryKeySpecifier | (() => undefined | UdHistoryKeySpecifier),
 		fields?: UdHistoryFieldPolicy,
@@ -1734,6 +2393,18 @@ export type StrictTypedTypePolicies = {
 		keyFields?: false | UniversalDividendEdgeKeySpecifier | (() => undefined | UniversalDividendEdgeKeySpecifier),
 		fields?: UniversalDividendEdgeFieldPolicy,
 	},
+	Validator?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | ValidatorKeySpecifier | (() => undefined | ValidatorKeySpecifier),
+		fields?: ValidatorFieldPolicy,
+	},
+	ValidatorConnection?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | ValidatorConnectionKeySpecifier | (() => undefined | ValidatorConnectionKeySpecifier),
+		fields?: ValidatorConnectionFieldPolicy,
+	},
+	ValidatorEdge?: Omit<TypePolicy, "fields" | "keyFields"> & {
+		keyFields?: false | ValidatorEdgeKeySpecifier | (() => undefined | ValidatorEdgeKeySpecifier),
+		fields?: ValidatorEdgeFieldPolicy,
+	},
 	query_root?: Omit<TypePolicy, "fields" | "keyFields"> & {
 		keyFields?: false | query_rootKeySpecifier | (() => undefined | query_rootKeySpecifier),
 		fields?: query_rootFieldPolicy,
diff --git a/src/app/network/indexer/indexer-schema.graphql b/src/app/network/indexer/indexer-schema.graphql
index 178ec39310b03e455d45814c4b2fe0ff245f46ee..b2f59d91ba99307bc6858a85e56d1405eb030bec 100644
--- a/src/app/network/indexer/indexer-schema.graphql
+++ b/src/app/network/indexer/indexer-schema.graphql
@@ -21,13 +21,96 @@ interface Node {
 
 "columns and relationships of \"account\""
 type Account implements Node {
+  balance: numeric!
+  "An array relationship"
+  commentsIssued(
+    "distinct select on columns"
+    distinctOn: [TxCommentSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [TxCommentOrderBy!],
+    "filter the rows returned"
+    where: TxCommentBoolExp
+  ): [TxComment!]!
+  "An aggregate relationship"
+  commentsIssuedAggregate(
+    "distinct select on columns"
+    distinctOn: [TxCommentSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [TxCommentOrderBy!],
+    "filter the rows returned"
+    where: TxCommentBoolExp
+  ): TxCommentAggregate!
+  "An array relationship connection"
+  commentsIssued_connection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [TxCommentSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [TxCommentOrderBy!],
+    "filter the rows returned"
+    where: TxCommentBoolExp
+  ): TxCommentConnection!
+  createdOn: Int!
   id: ID!
   "An object relationship"
   identity: Identity
+  isActive: Boolean!
   "An object relationship"
   linkedIdentity: Identity
   linkedIdentityId: String
   "An array relationship"
+  removedIdentities(
+    "distinct select on columns"
+    distinctOn: [IdentitySelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [IdentityOrderBy!],
+    "filter the rows returned"
+    where: IdentityBoolExp
+  ): [Identity!]!
+  "An aggregate relationship"
+  removedIdentitiesAggregate(
+    "distinct select on columns"
+    distinctOn: [IdentitySelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [IdentityOrderBy!],
+    "filter the rows returned"
+    where: IdentityBoolExp
+  ): IdentityAggregate!
+  "An array relationship connection"
+  removedIdentities_connection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [IdentitySelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [IdentityOrderBy!],
+    "filter the rows returned"
+    where: IdentityBoolExp
+  ): IdentityConnection!
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+  "An array relationship"
   transfersIssued(
     "distinct select on columns"
     distinctOn: [TransferSelectColumn!],
@@ -154,9 +237,25 @@ type AccountAggregate {
 
 "aggregate fields of \"account\""
 type AccountAggregateFields {
+  avg: AccountAvgFields
   count(columns: [AccountSelectColumn!], distinct: Boolean): Int!
   max: AccountMaxFields
   min: AccountMinFields
+  stddev: AccountStddevFields
+  stddevPop: AccountStddevPopFields
+  stddevSamp: AccountStddevSampFields
+  sum: AccountSumFields
+  varPop: AccountVarPopFields
+  varSamp: AccountVarSampFields
+  variance: AccountVarianceFields
+}
+
+"aggregate avg on columns"
+type AccountAvgFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
 }
 
 "A Relay connection object on \"account\""
@@ -172,14 +271,78 @@ type AccountEdge {
 
 "aggregate max on columns"
 type AccountMaxFields {
+  balance: numeric
+  createdOn: Int
   id: String
   linkedIdentityId: String
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
 }
 
 "aggregate min on columns"
 type AccountMinFields {
+  balance: numeric
+  createdOn: Int
   id: String
   linkedIdentityId: String
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate stddev on columns"
+type AccountStddevFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate stddevPop on columns"
+type AccountStddevPopFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate stddevSamp on columns"
+type AccountStddevSampFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate sum on columns"
+type AccountSumFields {
+  balance: numeric
+  createdOn: Int
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate varPop on columns"
+type AccountVarPopFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate varSamp on columns"
+type AccountVarSampFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
+}
+
+"aggregate variance on columns"
+type AccountVarianceFields {
+  balance: Float
+  createdOn: Float
+  "\"Get total balance including unclaimed UDs\""
+  totalBalance: numeric
 }
 
 "columns and relationships of \"block\""
@@ -1207,6 +1370,9 @@ type Identity implements Node {
   "An object relationship"
   account: Account
   accountId: String
+  "An object relationship"
+  accountRemoved: Account
+  accountRemovedId: String
   "An array relationship"
   certIssued(
     "distinct select on columns"
@@ -1290,6 +1456,7 @@ type Identity implements Node {
   createdInId: String
   createdOn: Int!
   expireOn: Int!
+  firstEligibleUd: Int
   id: ID!
   index: Int!
   isMember: Boolean!
@@ -1412,85 +1579,8 @@ type Identity implements Node {
     "filter the rows returned"
     where: ChangeOwnerKeyBoolExp
   ): ChangeOwnerKeyConnection!
-  "An array relationship"
-  smithCertIssued(
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    "limit the number of rows returned"
-    limit: Int,
-    "skip the first n rows. Use only with order_by"
-    offset: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): [SmithCert!]!
-  "An aggregate relationship"
-  smithCertIssuedAggregate(
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    "limit the number of rows returned"
-    limit: Int,
-    "skip the first n rows. Use only with order_by"
-    offset: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): SmithCertAggregate!
-  "An array relationship connection"
-  smithCertIssued_connection(
-    after: String,
-    before: String,
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    first: Int,
-    last: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): SmithCertConnection!
-  "An array relationship"
-  smithCertReceived(
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    "limit the number of rows returned"
-    limit: Int,
-    "skip the first n rows. Use only with order_by"
-    offset: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): [SmithCert!]!
-  "An aggregate relationship"
-  smithCertReceivedAggregate(
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    "limit the number of rows returned"
-    limit: Int,
-    "skip the first n rows. Use only with order_by"
-    offset: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): SmithCertAggregate!
-  "An array relationship connection"
-  smithCertReceived_connection(
-    after: String,
-    before: String,
-    "distinct select on columns"
-    distinctOn: [SmithCertSelectColumn!],
-    first: Int,
-    last: Int,
-    "sort the rows by one or more columns"
-    orderBy: [SmithCertOrderBy!],
-    "filter the rows returned"
-    where: SmithCertBoolExp
-  ): SmithCertConnection!
-  smithStatus: SmithStatusEnum
+  "An object relationship"
+  smith: Smith
   status: IdentityStatusEnum
   "\"Get UD History by Identity\""
   udHistory(
@@ -1507,6 +1597,36 @@ type Identity implements Node {
   ): [UdHistory!]
 }
 
+"aggregated selection of \"identity\""
+type IdentityAggregate {
+  aggregate: IdentityAggregateFields
+  nodes: [Identity!]!
+}
+
+"aggregate fields of \"identity\""
+type IdentityAggregateFields {
+  avg: IdentityAvgFields
+  count(columns: [IdentitySelectColumn!], distinct: Boolean): Int!
+  max: IdentityMaxFields
+  min: IdentityMinFields
+  stddev: IdentityStddevFields
+  stddevPop: IdentityStddevPopFields
+  stddevSamp: IdentityStddevSampFields
+  sum: IdentitySumFields
+  varPop: IdentityVarPopFields
+  varSamp: IdentityVarSampFields
+  variance: IdentityVarianceFields
+}
+
+"aggregate avg on columns"
+type IdentityAvgFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
 "A Relay connection object on \"identity\""
 type IdentityConnection {
   edges: [IdentityEdge!]!
@@ -1518,6 +1638,97 @@ type IdentityEdge {
   node: Identity!
 }
 
+"aggregate max on columns"
+type IdentityMaxFields {
+  accountId: String
+  accountRemovedId: String
+  createdInId: String
+  createdOn: Int
+  expireOn: Int
+  firstEligibleUd: Int
+  id: String
+  index: Int
+  lastChangeOn: Int
+  name: String
+}
+
+"aggregate min on columns"
+type IdentityMinFields {
+  accountId: String
+  accountRemovedId: String
+  createdInId: String
+  createdOn: Int
+  expireOn: Int
+  firstEligibleUd: Int
+  id: String
+  index: Int
+  lastChangeOn: Int
+  name: String
+}
+
+"aggregate stddev on columns"
+type IdentityStddevFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
+"aggregate stddevPop on columns"
+type IdentityStddevPopFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
+"aggregate stddevSamp on columns"
+type IdentityStddevSampFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
+"aggregate sum on columns"
+type IdentitySumFields {
+  createdOn: Int
+  expireOn: Int
+  firstEligibleUd: Int
+  index: Int
+  lastChangeOn: Int
+}
+
+"aggregate varPop on columns"
+type IdentityVarPopFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
+"aggregate varSamp on columns"
+type IdentityVarSampFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
+"aggregate variance on columns"
+type IdentityVarianceFields {
+  createdOn: Float
+  expireOn: Float
+  firstEligibleUd: Float
+  index: Float
+  lastChangeOn: Float
+}
+
 "columns and relationships of \"items_counter\""
 type ItemsCounter implements Node {
   id: ID!
@@ -1645,15 +1856,165 @@ type PageInfo {
   startCursor: String!
 }
 
-"columns and relationships of \"smith_cert\""
-type SmithCert implements Node {
-  createdOn: Int!
+"columns and relationships of \"population_history\""
+type PopulationHistory implements Node {
+  activeAccountCount: Int!
+  blockNumber: Int!
   id: ID!
-  "An object relationship"
-  issuer: Identity
-  issuerId: String
-  "An object relationship"
-  receiver: Identity
+  memberCount: Int!
+  smithCount: Int!
+}
+
+"A Relay connection object on \"population_history\""
+type PopulationHistoryConnection {
+  edges: [PopulationHistoryEdge!]!
+  pageInfo: PageInfo!
+}
+
+type PopulationHistoryEdge {
+  cursor: String!
+  node: PopulationHistory!
+}
+
+"columns and relationships of \"smith\""
+type Smith implements Node {
+  forged: Int!
+  id: ID!
+  "An object relationship"
+  identity: Identity
+  identityId: String
+  index: Int!
+  lastChanged: Int
+  lastForged: Int
+  "An array relationship"
+  smithCertIssued(
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): [SmithCert!]!
+  "An aggregate relationship"
+  smithCertIssuedAggregate(
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): SmithCertAggregate!
+  "An array relationship connection"
+  smithCertIssued_connection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): SmithCertConnection!
+  "An array relationship"
+  smithCertReceived(
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): [SmithCert!]!
+  "An aggregate relationship"
+  smithCertReceivedAggregate(
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): SmithCertAggregate!
+  "An array relationship connection"
+  smithCertReceived_connection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithCertSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithCertOrderBy!],
+    "filter the rows returned"
+    where: SmithCertBoolExp
+  ): SmithCertConnection!
+  "An array relationship"
+  smithHistory(
+    "distinct select on columns"
+    distinctOn: [SmithEventSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithEventOrderBy!],
+    "filter the rows returned"
+    where: SmithEventBoolExp
+  ): [SmithEvent!]!
+  "An aggregate relationship"
+  smithHistoryAggregate(
+    "distinct select on columns"
+    distinctOn: [SmithEventSelectColumn!],
+    "limit the number of rows returned"
+    limit: Int,
+    "skip the first n rows. Use only with order_by"
+    offset: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithEventOrderBy!],
+    "filter the rows returned"
+    where: SmithEventBoolExp
+  ): SmithEventAggregate!
+  "An array relationship connection"
+  smithHistory_connection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithEventSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithEventOrderBy!],
+    "filter the rows returned"
+    where: SmithEventBoolExp
+  ): SmithEventConnection!
+  smithStatus: SmithStatusEnum
+}
+
+"columns and relationships of \"smith_cert\""
+type SmithCert implements Node {
+  createdOn: Int!
+  id: ID!
+  "An object relationship"
+  issuer: Smith
+  issuerId: String
+  "An object relationship"
+  receiver: Smith
   receiverId: String
 }
 
@@ -1745,11 +2106,128 @@ type SmithCertVarianceFields {
   createdOn: Float
 }
 
+"A Relay connection object on \"smith\""
+type SmithConnection {
+  edges: [SmithEdge!]!
+  pageInfo: PageInfo!
+}
+
+type SmithEdge {
+  cursor: String!
+  node: Smith!
+}
+
+"columns and relationships of \"smith_event\""
+type SmithEvent implements Node {
+  blockNumber: Int!
+  "An object relationship"
+  event: Event
+  eventId: String
+  eventType: SmithEventTypeEnum
+  id: ID!
+  "An object relationship"
+  smith: Smith
+  smithId: String
+}
+
+"aggregated selection of \"smith_event\""
+type SmithEventAggregate {
+  aggregate: SmithEventAggregateFields
+  nodes: [SmithEvent!]!
+}
+
+"aggregate fields of \"smith_event\""
+type SmithEventAggregateFields {
+  avg: SmithEventAvgFields
+  count(columns: [SmithEventSelectColumn!], distinct: Boolean): Int!
+  max: SmithEventMaxFields
+  min: SmithEventMinFields
+  stddev: SmithEventStddevFields
+  stddevPop: SmithEventStddevPopFields
+  stddevSamp: SmithEventStddevSampFields
+  sum: SmithEventSumFields
+  varPop: SmithEventVarPopFields
+  varSamp: SmithEventVarSampFields
+  variance: SmithEventVarianceFields
+}
+
+"aggregate avg on columns"
+type SmithEventAvgFields {
+  blockNumber: Float
+}
+
+"A Relay connection object on \"smith_event\""
+type SmithEventConnection {
+  edges: [SmithEventEdge!]!
+  pageInfo: PageInfo!
+}
+
+type SmithEventEdge {
+  cursor: String!
+  node: SmithEvent!
+}
+
+"aggregate max on columns"
+type SmithEventMaxFields {
+  blockNumber: Int
+  eventId: String
+  id: String
+  smithId: String
+}
+
+"aggregate min on columns"
+type SmithEventMinFields {
+  blockNumber: Int
+  eventId: String
+  id: String
+  smithId: String
+}
+
+"aggregate stddev on columns"
+type SmithEventStddevFields {
+  blockNumber: Float
+}
+
+"aggregate stddevPop on columns"
+type SmithEventStddevPopFields {
+  blockNumber: Float
+}
+
+"aggregate stddevSamp on columns"
+type SmithEventStddevSampFields {
+  blockNumber: Float
+}
+
+"aggregate sum on columns"
+type SmithEventSumFields {
+  blockNumber: Int
+}
+
+"aggregate varPop on columns"
+type SmithEventVarPopFields {
+  blockNumber: Float
+}
+
+"aggregate varSamp on columns"
+type SmithEventVarSampFields {
+  blockNumber: Float
+}
+
+"aggregate variance on columns"
+type SmithEventVarianceFields {
+  blockNumber: Float
+}
+
 "columns and relationships of \"transfer\""
 type Transfer implements Node {
   amount: numeric!
   blockNumber: Int!
-  comment: String
+  "An object relationship"
+  comment: TxComment
+  commentId: String
+  "An object relationship"
+  event: Event
+  eventId: String
   "An object relationship"
   from: Account
   fromId: String
@@ -1802,7 +2280,8 @@ type TransferEdge {
 type TransferMaxFields {
   amount: numeric
   blockNumber: Int
-  comment: String
+  commentId: String
+  eventId: String
   fromId: String
   id: String
   timestamp: timestamptz
@@ -1813,7 +2292,8 @@ type TransferMaxFields {
 type TransferMinFields {
   amount: numeric
   blockNumber: Int
-  comment: String
+  commentId: String
+  eventId: String
   fromId: String
   id: String
   timestamp: timestamptz
@@ -1862,9 +2342,117 @@ type TransferVarianceFields {
   blockNumber: Float
 }
 
+"columns and relationships of \"tx_comment\""
+type TxComment implements Node {
+  "An object relationship"
+  author: Account
+  authorId: String
+  blockNumber: Int!
+  "An object relationship"
+  event: Event
+  eventId: String
+  hash: String!
+  id: ID!
+  remark: String!
+  remarkBytes: bytea!
+  type: CommentTypeEnum
+}
+
+"aggregated selection of \"tx_comment\""
+type TxCommentAggregate {
+  aggregate: TxCommentAggregateFields
+  nodes: [TxComment!]!
+}
+
+"aggregate fields of \"tx_comment\""
+type TxCommentAggregateFields {
+  avg: TxCommentAvgFields
+  count(columns: [TxCommentSelectColumn!], distinct: Boolean): Int!
+  max: TxCommentMaxFields
+  min: TxCommentMinFields
+  stddev: TxCommentStddevFields
+  stddevPop: TxCommentStddevPopFields
+  stddevSamp: TxCommentStddevSampFields
+  sum: TxCommentSumFields
+  varPop: TxCommentVarPopFields
+  varSamp: TxCommentVarSampFields
+  variance: TxCommentVarianceFields
+}
+
+"aggregate avg on columns"
+type TxCommentAvgFields {
+  blockNumber: Float
+}
+
+"A Relay connection object on \"tx_comment\""
+type TxCommentConnection {
+  edges: [TxCommentEdge!]!
+  pageInfo: PageInfo!
+}
+
+type TxCommentEdge {
+  cursor: String!
+  node: TxComment!
+}
+
+"aggregate max on columns"
+type TxCommentMaxFields {
+  authorId: String
+  blockNumber: Int
+  eventId: String
+  hash: String
+  id: String
+  remark: String
+}
+
+"aggregate min on columns"
+type TxCommentMinFields {
+  authorId: String
+  blockNumber: Int
+  eventId: String
+  hash: String
+  id: String
+  remark: String
+}
+
+"aggregate stddev on columns"
+type TxCommentStddevFields {
+  blockNumber: Float
+}
+
+"aggregate stddevPop on columns"
+type TxCommentStddevPopFields {
+  blockNumber: Float
+}
+
+"aggregate stddevSamp on columns"
+type TxCommentStddevSampFields {
+  blockNumber: Float
+}
+
+"aggregate sum on columns"
+type TxCommentSumFields {
+  blockNumber: Int
+}
+
+"aggregate varPop on columns"
+type TxCommentVarPopFields {
+  blockNumber: Float
+}
+
+"aggregate varSamp on columns"
+type TxCommentVarSampFields {
+  blockNumber: Float
+}
+
+"aggregate variance on columns"
+type TxCommentVarianceFields {
+  blockNumber: Float
+}
+
 "columns and relationships of \"ud_history\""
 type UdHistory implements Node {
-  amount: Int!
+  amount: numeric!
   blockNumber: Int!
   id: ID!
   "An object relationship"
@@ -1893,8 +2481,9 @@ type UdReeval implements Node {
   id: ID!
   membersCount: Int!
   monetaryMass: numeric!
-  newUdAmount: Int!
+  newUdAmount: numeric!
   timestamp: timestamptz!
+  udIndex: Int!
 }
 
 "A Relay connection object on \"ud_reeval\""
@@ -1910,12 +2499,13 @@ type UdReevalEdge {
 
 "columns and relationships of \"universal_dividend\""
 type UniversalDividend implements Node {
-  amount: Int!
+  amount: numeric!
   blockNumber: Int!
   "An object relationship"
   event: Event
   eventId: String
   id: ID!
+  index: Int!
   membersCount: Int!
   monetaryMass: numeric!
   timestamp: timestamptz!
@@ -1932,6 +2522,23 @@ type UniversalDividendEdge {
   node: UniversalDividend!
 }
 
+"columns and relationships of \"validator\""
+type Validator implements Node {
+  id: ID!
+  index: Int!
+}
+
+"A Relay connection object on \"validator\""
+type ValidatorConnection {
+  edges: [ValidatorEdge!]!
+  pageInfo: PageInfo!
+}
+
+type ValidatorEdge {
+  cursor: String!
+  node: Validator!
+}
+
 type query_root {
   "fetch data from the table: \"account\""
   accountConnection(
@@ -2095,6 +2702,19 @@ type query_root {
     "A globally unique id"
     id: ID!
   ): Node
+  "fetch data from the table: \"population_history\""
+  populationHistoryConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [PopulationHistorySelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [PopulationHistoryOrderBy!],
+    "filter the rows returned"
+    where: PopulationHistoryBoolExp
+  ): PopulationHistoryConnection!
   "fetch data from the table: \"smith_cert\""
   smithCertConnection(
     after: String,
@@ -2108,6 +2728,32 @@ type query_root {
     "filter the rows returned"
     where: SmithCertBoolExp
   ): SmithCertConnection!
+  "fetch data from the table: \"smith\""
+  smithConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithOrderBy!],
+    "filter the rows returned"
+    where: SmithBoolExp
+  ): SmithConnection!
+  "fetch data from the table: \"smith_event\""
+  smithEventConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithEventSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithEventOrderBy!],
+    "filter the rows returned"
+    where: SmithEventBoolExp
+  ): SmithEventConnection!
   "fetch data from the table: \"transfer\""
   transferConnection(
     after: String,
@@ -2121,6 +2767,19 @@ type query_root {
     "filter the rows returned"
     where: TransferBoolExp
   ): TransferConnection!
+  "fetch data from the table: \"tx_comment\""
+  txCommentConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [TxCommentSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [TxCommentOrderBy!],
+    "filter the rows returned"
+    where: TxCommentBoolExp
+  ): TxCommentConnection!
   "fetch data from the table: \"ud_history\""
   udHistoryConnection(
     after: String,
@@ -2160,6 +2819,19 @@ type query_root {
     "filter the rows returned"
     where: UniversalDividendBoolExp
   ): UniversalDividendConnection!
+  "fetch data from the table: \"validator\""
+  validatorConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [ValidatorSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [ValidatorOrderBy!],
+    "filter the rows returned"
+    where: ValidatorBoolExp
+  ): ValidatorConnection!
 }
 
 type subscription_root {
@@ -2325,6 +2997,19 @@ type subscription_root {
     "A globally unique id"
     id: ID!
   ): Node
+  "fetch data from the table: \"population_history\""
+  populationHistoryConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [PopulationHistorySelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [PopulationHistoryOrderBy!],
+    "filter the rows returned"
+    where: PopulationHistoryBoolExp
+  ): PopulationHistoryConnection!
   "fetch data from the table: \"smith_cert\""
   smithCertConnection(
     after: String,
@@ -2338,6 +3023,32 @@ type subscription_root {
     "filter the rows returned"
     where: SmithCertBoolExp
   ): SmithCertConnection!
+  "fetch data from the table: \"smith\""
+  smithConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithOrderBy!],
+    "filter the rows returned"
+    where: SmithBoolExp
+  ): SmithConnection!
+  "fetch data from the table: \"smith_event\""
+  smithEventConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [SmithEventSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [SmithEventOrderBy!],
+    "filter the rows returned"
+    where: SmithEventBoolExp
+  ): SmithEventConnection!
   "fetch data from the table: \"transfer\""
   transferConnection(
     after: String,
@@ -2351,6 +3062,19 @@ type subscription_root {
     "filter the rows returned"
     where: TransferBoolExp
   ): TransferConnection!
+  "fetch data from the table: \"tx_comment\""
+  txCommentConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [TxCommentSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [TxCommentOrderBy!],
+    "filter the rows returned"
+    where: TxCommentBoolExp
+  ): TxCommentConnection!
   "fetch data from the table: \"ud_history\""
   udHistoryConnection(
     after: String,
@@ -2390,16 +3114,47 @@ type subscription_root {
     "filter the rows returned"
     where: UniversalDividendBoolExp
   ): UniversalDividendConnection!
+  "fetch data from the table: \"validator\""
+  validatorConnection(
+    after: String,
+    before: String,
+    "distinct select on columns"
+    distinctOn: [ValidatorSelectColumn!],
+    first: Int,
+    last: Int,
+    "sort the rows by one or more columns"
+    orderBy: [ValidatorOrderBy!],
+    "filter the rows returned"
+    where: ValidatorBoolExp
+  ): ValidatorConnection!
 }
 
 "select columns of table \"account\""
 enum AccountSelectColumn {
+  "column name"
+  balance
+  "column name"
+  createdOn
   "column name"
   id
   "column name"
+  isActive
+  "column name"
   linkedIdentityId
 }
 
+"select \"accountAggregateBoolExpBool_andArgumentsColumns\" columns of table \"account\""
+enum AccountSelectColumnAccountAggregateBoolExpBool_andArgumentsColumns {
+  "column name"
+  isActive
+}
+
+"select \"accountAggregateBoolExpBool_orArgumentsColumns\" columns of table \"account\""
+enum AccountSelectColumnAccountAggregateBoolExpBool_orArgumentsColumns {
+  "column name"
+  isActive
+}
+
 "select columns of table \"block\""
 enum BlockSelectColumn {
   "column name"
@@ -2534,6 +3289,13 @@ enum ChangeOwnerKeySelectColumn {
   previousId
 }
 
+enum CommentTypeEnum {
+  ASCII
+  CID
+  RAW
+  UNICODE
+}
+
 enum CounterLevelEnum {
   GLOBAL
   ITEM
@@ -2613,12 +3375,16 @@ enum IdentitySelectColumn {
   "column name"
   accountId
   "column name"
+  accountRemovedId
+  "column name"
   createdInId
   "column name"
   createdOn
   "column name"
   expireOn
   "column name"
+  firstEligibleUd
+  "column name"
   id
   "column name"
   index
@@ -2629,11 +3395,21 @@ enum IdentitySelectColumn {
   "column name"
   name
   "column name"
-  smithStatus
-  "column name"
   status
 }
 
+"select \"identityAggregateBoolExpBool_andArgumentsColumns\" columns of table \"identity\""
+enum IdentitySelectColumnIdentityAggregateBoolExpBool_andArgumentsColumns {
+  "column name"
+  isMember
+}
+
+"select \"identityAggregateBoolExpBool_orArgumentsColumns\" columns of table \"identity\""
+enum IdentitySelectColumnIdentityAggregateBoolExpBool_orArgumentsColumns {
+  "column name"
+  isMember
+}
+
 enum IdentityStatusEnum {
   MEMBER
   NOTMEMBER
@@ -2691,6 +3467,20 @@ enum OrderBy {
   DESC_NULLS_LAST
 }
 
+"select columns of table \"population_history\""
+enum PopulationHistorySelectColumn {
+  "column name"
+  activeAccountCount
+  "column name"
+  blockNumber
+  "column name"
+  id
+  "column name"
+  memberCount
+  "column name"
+  smithCount
+}
+
 "select columns of table \"smith_cert\""
 enum SmithCertSelectColumn {
   "column name"
@@ -2703,6 +3493,45 @@ enum SmithCertSelectColumn {
   receiverId
 }
 
+"select columns of table \"smith_event\""
+enum SmithEventSelectColumn {
+  "column name"
+  blockNumber
+  "column name"
+  eventId
+  "column name"
+  eventType
+  "column name"
+  id
+  "column name"
+  smithId
+}
+
+enum SmithEventTypeEnum {
+  ACCEPTED
+  EXCLUDED
+  INVITED
+  PROMOTED
+}
+
+"select columns of table \"smith\""
+enum SmithSelectColumn {
+  "column name"
+  forged
+  "column name"
+  id
+  "column name"
+  identityId
+  "column name"
+  index
+  "column name"
+  lastChanged
+  "column name"
+  lastForged
+  "column name"
+  smithStatus
+}
+
 enum SmithStatusEnum {
   EXCLUDED
   INVITED
@@ -2717,7 +3546,9 @@ enum TransferSelectColumn {
   "column name"
   blockNumber
   "column name"
-  comment
+  commentId
+  "column name"
+  eventId
   "column name"
   fromId
   "column name"
@@ -2728,6 +3559,26 @@ enum TransferSelectColumn {
   toId
 }
 
+"select columns of table \"tx_comment\""
+enum TxCommentSelectColumn {
+  "column name"
+  authorId
+  "column name"
+  blockNumber
+  "column name"
+  eventId
+  "column name"
+  hash
+  "column name"
+  id
+  "column name"
+  remark
+  "column name"
+  remarkBytes
+  "column name"
+  type
+}
+
 "select columns of table \"ud_history\""
 enum UdHistorySelectColumn {
   "column name"
@@ -2758,6 +3609,8 @@ enum UdReevalSelectColumn {
   newUdAmount
   "column name"
   timestamp
+  "column name"
+  udIndex
 }
 
 "select columns of table \"universal_dividend\""
@@ -2771,6 +3624,8 @@ enum UniversalDividendSelectColumn {
   "column name"
   id
   "column name"
+  index
+  "column name"
   membersCount
   "column name"
   monetaryMass
@@ -2778,6 +3633,14 @@ enum UniversalDividendSelectColumn {
   timestamp
 }
 
+"select columns of table \"validator\""
+enum ValidatorSelectColumn {
+  "column name"
+  id
+  "column name"
+  index
+}
+
 scalar bytea
 
 scalar identity_scalar
@@ -2789,14 +3652,30 @@ scalar numeric
 scalar timestamptz
 
 input AccountAggregateBoolExp {
+  bool_and: accountAggregateBoolExpBool_and
+  bool_or: accountAggregateBoolExpBool_or
   count: accountAggregateBoolExpCount
 }
 
 "order by aggregate values of table \"account\""
 input AccountAggregateOrderBy {
+  avg: AccountAvgOrderBy
   count: OrderBy
   max: AccountMaxOrderBy
   min: AccountMinOrderBy
+  stddev: AccountStddevOrderBy
+  stddevPop: AccountStddevPopOrderBy
+  stddevSamp: AccountStddevSampOrderBy
+  sum: AccountSumOrderBy
+  varPop: AccountVarPopOrderBy
+  varSamp: AccountVarSampOrderBy
+  variance: AccountVarianceOrderBy
+}
+
+"order by avg() on columns of table \"account\""
+input AccountAvgOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
 }
 
 "Boolean expression to filter rows from the table \"account\". All fields are combined with a logical 'AND'."
@@ -2804,10 +3683,18 @@ input AccountBoolExp {
   _and: [AccountBoolExp!]
   _not: AccountBoolExp
   _or: [AccountBoolExp!]
+  balance: NumericComparisonExp
+  commentsIssued: TxCommentBoolExp
+  commentsIssuedAggregate: TxCommentAggregateBoolExp
+  createdOn: IntComparisonExp
   id: StringComparisonExp
   identity: IdentityBoolExp
+  isActive: BooleanComparisonExp
   linkedIdentity: IdentityBoolExp
   linkedIdentityId: StringComparisonExp
+  removedIdentities: IdentityBoolExp
+  removedIdentitiesAggregate: IdentityAggregateBoolExp
+  totalBalance: NumericComparisonExp
   transfersIssued: TransferBoolExp
   transfersIssuedAggregate: TransferAggregateBoolExp
   transfersReceived: TransferBoolExp
@@ -2818,27 +3705,79 @@ input AccountBoolExp {
 
 "order by max() on columns of table \"account\""
 input AccountMaxOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
   id: OrderBy
   linkedIdentityId: OrderBy
 }
 
 "order by min() on columns of table \"account\""
 input AccountMinOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
   id: OrderBy
   linkedIdentityId: OrderBy
 }
 
 "Ordering options when selecting data from \"account\"."
 input AccountOrderBy {
+  balance: OrderBy
+  commentsIssuedAggregate: TxCommentAggregateOrderBy
+  createdOn: OrderBy
   id: OrderBy
   identity: IdentityOrderBy
+  isActive: OrderBy
   linkedIdentity: IdentityOrderBy
   linkedIdentityId: OrderBy
+  removedIdentitiesAggregate: IdentityAggregateOrderBy
+  totalBalance: OrderBy
   transfersIssuedAggregate: TransferAggregateOrderBy
   transfersReceivedAggregate: TransferAggregateOrderBy
   wasIdentityAggregate: ChangeOwnerKeyAggregateOrderBy
 }
 
+"order by stddev() on columns of table \"account\""
+input AccountStddevOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by stddevPop() on columns of table \"account\""
+input AccountStddevPopOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by stddevSamp() on columns of table \"account\""
+input AccountStddevSampOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by sum() on columns of table \"account\""
+input AccountSumOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by varPop() on columns of table \"account\""
+input AccountVarPopOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by varSamp() on columns of table \"account\""
+input AccountVarSampOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
+"order by variance() on columns of table \"account\""
+input AccountVarianceOrderBy {
+  balance: OrderBy
+  createdOn: OrderBy
+}
+
 "Boolean expression to filter rows from the table \"block\". All fields are combined with a logical 'AND'."
 input BlockBoolExp {
   _and: [BlockBoolExp!]
@@ -3342,6 +4281,15 @@ input ChangeOwnerKeyVarianceOrderBy {
   blockNumber: OrderBy
 }
 
+"Boolean expression to compare columns of type \"CommentTypeEnum\". All fields are combined with logical 'AND'."
+input CommentTypeEnumComparisonExp {
+  _eq: CommentTypeEnum
+  _in: [CommentTypeEnum!]
+  _isNull: Boolean
+  _neq: CommentTypeEnum
+  _nin: [CommentTypeEnum!]
+}
+
 "Boolean expression to compare columns of type \"CounterLevelEnum\". All fields are combined with logical 'AND'."
 input CounterLevelEnumComparisonExp {
   _eq: CounterLevelEnum
@@ -3632,6 +4580,36 @@ input ExtrinsicVarianceOrderBy {
   version: OrderBy
 }
 
+input IdentityAggregateBoolExp {
+  bool_and: identityAggregateBoolExpBool_and
+  bool_or: identityAggregateBoolExpBool_or
+  count: identityAggregateBoolExpCount
+}
+
+"order by aggregate values of table \"identity\""
+input IdentityAggregateOrderBy {
+  avg: IdentityAvgOrderBy
+  count: OrderBy
+  max: IdentityMaxOrderBy
+  min: IdentityMinOrderBy
+  stddev: IdentityStddevOrderBy
+  stddevPop: IdentityStddevPopOrderBy
+  stddevSamp: IdentityStddevSampOrderBy
+  sum: IdentitySumOrderBy
+  varPop: IdentityVarPopOrderBy
+  varSamp: IdentityVarSampOrderBy
+  variance: IdentityVarianceOrderBy
+}
+
+"order by avg() on columns of table \"identity\""
+input IdentityAvgOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
 "Boolean expression to filter rows from the table \"identity\". All fields are combined with a logical 'AND'."
 input IdentityBoolExp {
   _and: [IdentityBoolExp!]
@@ -3639,6 +4617,8 @@ input IdentityBoolExp {
   _or: [IdentityBoolExp!]
   account: AccountBoolExp
   accountId: StringComparisonExp
+  accountRemoved: AccountBoolExp
+  accountRemovedId: StringComparisonExp
   certIssued: CertBoolExp
   certIssuedAggregate: CertAggregateBoolExp
   certReceived: CertBoolExp
@@ -3647,6 +4627,7 @@ input IdentityBoolExp {
   createdInId: StringComparisonExp
   createdOn: IntComparisonExp
   expireOn: IntComparisonExp
+  firstEligibleUd: IntComparisonExp
   id: StringComparisonExp
   index: IntComparisonExp
   isMember: BooleanComparisonExp
@@ -3658,25 +4639,52 @@ input IdentityBoolExp {
   name: StringComparisonExp
   ownerKeyChange: ChangeOwnerKeyBoolExp
   ownerKeyChangeAggregate: ChangeOwnerKeyAggregateBoolExp
-  smithCertIssued: SmithCertBoolExp
-  smithCertIssuedAggregate: SmithCertAggregateBoolExp
-  smithCertReceived: SmithCertBoolExp
-  smithCertReceivedAggregate: SmithCertAggregateBoolExp
-  smithStatus: SmithStatusEnumComparisonExp
+  smith: SmithBoolExp
   status: IdentityStatusEnumComparisonExp
   udHistory: UdHistoryBoolExp
 }
 
+"order by max() on columns of table \"identity\""
+input IdentityMaxOrderBy {
+  accountId: OrderBy
+  accountRemovedId: OrderBy
+  createdInId: OrderBy
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  id: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+  name: OrderBy
+}
+
+"order by min() on columns of table \"identity\""
+input IdentityMinOrderBy {
+  accountId: OrderBy
+  accountRemovedId: OrderBy
+  createdInId: OrderBy
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  id: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+  name: OrderBy
+}
+
 "Ordering options when selecting data from \"identity\"."
 input IdentityOrderBy {
   account: AccountOrderBy
   accountId: OrderBy
+  accountRemoved: AccountOrderBy
+  accountRemovedId: OrderBy
   certIssuedAggregate: CertAggregateOrderBy
   certReceivedAggregate: CertAggregateOrderBy
   createdIn: EventOrderBy
   createdInId: OrderBy
   createdOn: OrderBy
   expireOn: OrderBy
+  firstEligibleUd: OrderBy
   id: OrderBy
   index: OrderBy
   isMember: OrderBy
@@ -3685,9 +4693,7 @@ input IdentityOrderBy {
   membershipHistoryAggregate: MembershipEventAggregateOrderBy
   name: OrderBy
   ownerKeyChangeAggregate: ChangeOwnerKeyAggregateOrderBy
-  smithCertIssuedAggregate: SmithCertAggregateOrderBy
-  smithCertReceivedAggregate: SmithCertAggregateOrderBy
-  smithStatus: OrderBy
+  smith: SmithOrderBy
   status: OrderBy
   udHistoryAggregate: UdHistoryAggregateOrderBy
 }
@@ -3701,6 +4707,69 @@ input IdentityStatusEnumComparisonExp {
   _nin: [IdentityStatusEnum!]
 }
 
+"order by stddev() on columns of table \"identity\""
+input IdentityStddevOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by stddevPop() on columns of table \"identity\""
+input IdentityStddevPopOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by stddevSamp() on columns of table \"identity\""
+input IdentityStddevSampOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by sum() on columns of table \"identity\""
+input IdentitySumOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by varPop() on columns of table \"identity\""
+input IdentityVarPopOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by varSamp() on columns of table \"identity\""
+input IdentityVarSampOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
+"order by variance() on columns of table \"identity\""
+input IdentityVarianceOrderBy {
+  createdOn: OrderBy
+  expireOn: OrderBy
+  firstEligibleUd: OrderBy
+  index: OrderBy
+  lastChangeOn: OrderBy
+}
+
 "Boolean expression to compare columns of type \"Int\". All fields are combined with logical 'AND'."
 input IntArrayComparisonExp {
   "is the array contained in the given array value"
@@ -3900,6 +4969,48 @@ input NumericComparisonExp {
   _nin: [numeric!]
 }
 
+"Boolean expression to filter rows from the table \"population_history\". All fields are combined with a logical 'AND'."
+input PopulationHistoryBoolExp {
+  _and: [PopulationHistoryBoolExp!]
+  _not: PopulationHistoryBoolExp
+  _or: [PopulationHistoryBoolExp!]
+  activeAccountCount: IntComparisonExp
+  blockNumber: IntComparisonExp
+  id: StringComparisonExp
+  memberCount: IntComparisonExp
+  smithCount: IntComparisonExp
+}
+
+"Ordering options when selecting data from \"population_history\"."
+input PopulationHistoryOrderBy {
+  activeAccountCount: OrderBy
+  blockNumber: OrderBy
+  id: OrderBy
+  memberCount: OrderBy
+  smithCount: OrderBy
+}
+
+"Boolean expression to filter rows from the table \"smith\". All fields are combined with a logical 'AND'."
+input SmithBoolExp {
+  _and: [SmithBoolExp!]
+  _not: SmithBoolExp
+  _or: [SmithBoolExp!]
+  forged: IntComparisonExp
+  id: StringComparisonExp
+  identity: IdentityBoolExp
+  identityId: StringComparisonExp
+  index: IntComparisonExp
+  lastChanged: IntComparisonExp
+  lastForged: IntComparisonExp
+  smithCertIssued: SmithCertBoolExp
+  smithCertIssuedAggregate: SmithCertAggregateBoolExp
+  smithCertReceived: SmithCertBoolExp
+  smithCertReceivedAggregate: SmithCertAggregateBoolExp
+  smithHistory: SmithEventBoolExp
+  smithHistoryAggregate: SmithEventAggregateBoolExp
+  smithStatus: SmithStatusEnumComparisonExp
+}
+
 input SmithCertAggregateBoolExp {
   count: smithCertAggregateBoolExpCount
 }
@@ -3931,9 +5042,9 @@ input SmithCertBoolExp {
   _or: [SmithCertBoolExp!]
   createdOn: IntComparisonExp
   id: StringComparisonExp
-  issuer: IdentityBoolExp
+  issuer: SmithBoolExp
   issuerId: StringComparisonExp
-  receiver: IdentityBoolExp
+  receiver: SmithBoolExp
   receiverId: StringComparisonExp
 }
 
@@ -3957,9 +5068,9 @@ input SmithCertMinOrderBy {
 input SmithCertOrderBy {
   createdOn: OrderBy
   id: OrderBy
-  issuer: IdentityOrderBy
+  issuer: SmithOrderBy
   issuerId: OrderBy
-  receiver: IdentityOrderBy
+  receiver: SmithOrderBy
   receiverId: OrderBy
 }
 
@@ -3998,6 +5109,130 @@ input SmithCertVarianceOrderBy {
   createdOn: OrderBy
 }
 
+input SmithEventAggregateBoolExp {
+  count: smithEventAggregateBoolExpCount
+}
+
+"order by aggregate values of table \"smith_event\""
+input SmithEventAggregateOrderBy {
+  avg: SmithEventAvgOrderBy
+  count: OrderBy
+  max: SmithEventMaxOrderBy
+  min: SmithEventMinOrderBy
+  stddev: SmithEventStddevOrderBy
+  stddevPop: SmithEventStddevPopOrderBy
+  stddevSamp: SmithEventStddevSampOrderBy
+  sum: SmithEventSumOrderBy
+  varPop: SmithEventVarPopOrderBy
+  varSamp: SmithEventVarSampOrderBy
+  variance: SmithEventVarianceOrderBy
+}
+
+"order by avg() on columns of table \"smith_event\""
+input SmithEventAvgOrderBy {
+  blockNumber: OrderBy
+}
+
+"Boolean expression to filter rows from the table \"smith_event\". All fields are combined with a logical 'AND'."
+input SmithEventBoolExp {
+  _and: [SmithEventBoolExp!]
+  _not: SmithEventBoolExp
+  _or: [SmithEventBoolExp!]
+  blockNumber: IntComparisonExp
+  event: EventBoolExp
+  eventId: StringComparisonExp
+  eventType: SmithEventTypeEnumComparisonExp
+  id: StringComparisonExp
+  smith: SmithBoolExp
+  smithId: StringComparisonExp
+}
+
+"order by max() on columns of table \"smith_event\""
+input SmithEventMaxOrderBy {
+  blockNumber: OrderBy
+  eventId: OrderBy
+  id: OrderBy
+  smithId: OrderBy
+}
+
+"order by min() on columns of table \"smith_event\""
+input SmithEventMinOrderBy {
+  blockNumber: OrderBy
+  eventId: OrderBy
+  id: OrderBy
+  smithId: OrderBy
+}
+
+"Ordering options when selecting data from \"smith_event\"."
+input SmithEventOrderBy {
+  blockNumber: OrderBy
+  event: EventOrderBy
+  eventId: OrderBy
+  eventType: OrderBy
+  id: OrderBy
+  smith: SmithOrderBy
+  smithId: OrderBy
+}
+
+"order by stddev() on columns of table \"smith_event\""
+input SmithEventStddevOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by stddevPop() on columns of table \"smith_event\""
+input SmithEventStddevPopOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by stddevSamp() on columns of table \"smith_event\""
+input SmithEventStddevSampOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by sum() on columns of table \"smith_event\""
+input SmithEventSumOrderBy {
+  blockNumber: OrderBy
+}
+
+"Boolean expression to compare columns of type \"SmithEventTypeEnum\". All fields are combined with logical 'AND'."
+input SmithEventTypeEnumComparisonExp {
+  _eq: SmithEventTypeEnum
+  _in: [SmithEventTypeEnum!]
+  _isNull: Boolean
+  _neq: SmithEventTypeEnum
+  _nin: [SmithEventTypeEnum!]
+}
+
+"order by varPop() on columns of table \"smith_event\""
+input SmithEventVarPopOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by varSamp() on columns of table \"smith_event\""
+input SmithEventVarSampOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by variance() on columns of table \"smith_event\""
+input SmithEventVarianceOrderBy {
+  blockNumber: OrderBy
+}
+
+"Ordering options when selecting data from \"smith\"."
+input SmithOrderBy {
+  forged: OrderBy
+  id: OrderBy
+  identity: IdentityOrderBy
+  identityId: OrderBy
+  index: OrderBy
+  lastChanged: OrderBy
+  lastForged: OrderBy
+  smithCertIssuedAggregate: SmithCertAggregateOrderBy
+  smithCertReceivedAggregate: SmithCertAggregateOrderBy
+  smithHistoryAggregate: SmithEventAggregateOrderBy
+  smithStatus: OrderBy
+}
+
 "Boolean expression to compare columns of type \"SmithStatusEnum\". All fields are combined with logical 'AND'."
 input SmithStatusEnumComparisonExp {
   _eq: SmithStatusEnum
@@ -4102,7 +5337,10 @@ input TransferBoolExp {
   _or: [TransferBoolExp!]
   amount: NumericComparisonExp
   blockNumber: IntComparisonExp
-  comment: StringComparisonExp
+  comment: TxCommentBoolExp
+  commentId: StringComparisonExp
+  event: EventBoolExp
+  eventId: StringComparisonExp
   from: AccountBoolExp
   fromId: StringComparisonExp
   id: StringComparisonExp
@@ -4115,7 +5353,8 @@ input TransferBoolExp {
 input TransferMaxOrderBy {
   amount: OrderBy
   blockNumber: OrderBy
-  comment: OrderBy
+  commentId: OrderBy
+  eventId: OrderBy
   fromId: OrderBy
   id: OrderBy
   timestamp: OrderBy
@@ -4126,7 +5365,8 @@ input TransferMaxOrderBy {
 input TransferMinOrderBy {
   amount: OrderBy
   blockNumber: OrderBy
-  comment: OrderBy
+  commentId: OrderBy
+  eventId: OrderBy
   fromId: OrderBy
   id: OrderBy
   timestamp: OrderBy
@@ -4137,7 +5377,10 @@ input TransferMinOrderBy {
 input TransferOrderBy {
   amount: OrderBy
   blockNumber: OrderBy
-  comment: OrderBy
+  comment: TxCommentOrderBy
+  commentId: OrderBy
+  event: EventOrderBy
+  eventId: OrderBy
   from: AccountOrderBy
   fromId: OrderBy
   id: OrderBy
@@ -4188,6 +5431,116 @@ input TransferVarianceOrderBy {
   blockNumber: OrderBy
 }
 
+input TxCommentAggregateBoolExp {
+  count: txCommentAggregateBoolExpCount
+}
+
+"order by aggregate values of table \"tx_comment\""
+input TxCommentAggregateOrderBy {
+  avg: TxCommentAvgOrderBy
+  count: OrderBy
+  max: TxCommentMaxOrderBy
+  min: TxCommentMinOrderBy
+  stddev: TxCommentStddevOrderBy
+  stddevPop: TxCommentStddevPopOrderBy
+  stddevSamp: TxCommentStddevSampOrderBy
+  sum: TxCommentSumOrderBy
+  varPop: TxCommentVarPopOrderBy
+  varSamp: TxCommentVarSampOrderBy
+  variance: TxCommentVarianceOrderBy
+}
+
+"order by avg() on columns of table \"tx_comment\""
+input TxCommentAvgOrderBy {
+  blockNumber: OrderBy
+}
+
+"Boolean expression to filter rows from the table \"tx_comment\". All fields are combined with a logical 'AND'."
+input TxCommentBoolExp {
+  _and: [TxCommentBoolExp!]
+  _not: TxCommentBoolExp
+  _or: [TxCommentBoolExp!]
+  author: AccountBoolExp
+  authorId: StringComparisonExp
+  blockNumber: IntComparisonExp
+  event: EventBoolExp
+  eventId: StringComparisonExp
+  hash: StringComparisonExp
+  id: StringComparisonExp
+  remark: StringComparisonExp
+  remarkBytes: ByteaComparisonExp
+  type: CommentTypeEnumComparisonExp
+}
+
+"order by max() on columns of table \"tx_comment\""
+input TxCommentMaxOrderBy {
+  authorId: OrderBy
+  blockNumber: OrderBy
+  eventId: OrderBy
+  hash: OrderBy
+  id: OrderBy
+  remark: OrderBy
+}
+
+"order by min() on columns of table \"tx_comment\""
+input TxCommentMinOrderBy {
+  authorId: OrderBy
+  blockNumber: OrderBy
+  eventId: OrderBy
+  hash: OrderBy
+  id: OrderBy
+  remark: OrderBy
+}
+
+"Ordering options when selecting data from \"tx_comment\"."
+input TxCommentOrderBy {
+  author: AccountOrderBy
+  authorId: OrderBy
+  blockNumber: OrderBy
+  event: EventOrderBy
+  eventId: OrderBy
+  hash: OrderBy
+  id: OrderBy
+  remark: OrderBy
+  remarkBytes: OrderBy
+  type: OrderBy
+}
+
+"order by stddev() on columns of table \"tx_comment\""
+input TxCommentStddevOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by stddevPop() on columns of table \"tx_comment\""
+input TxCommentStddevPopOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by stddevSamp() on columns of table \"tx_comment\""
+input TxCommentStddevSampOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by sum() on columns of table \"tx_comment\""
+input TxCommentSumOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by varPop() on columns of table \"tx_comment\""
+input TxCommentVarPopOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by varSamp() on columns of table \"tx_comment\""
+input TxCommentVarSampOrderBy {
+  blockNumber: OrderBy
+}
+
+"order by variance() on columns of table \"tx_comment\""
+input TxCommentVarianceOrderBy {
+  blockNumber: OrderBy
+}
+
 "order by aggregate values of table \"ud_history\""
 input UdHistoryAggregateOrderBy {
   avg: UdHistoryAvgOrderBy
@@ -4214,7 +5567,7 @@ input UdHistoryBoolExp {
   _and: [UdHistoryBoolExp!]
   _not: UdHistoryBoolExp
   _or: [UdHistoryBoolExp!]
-  amount: IntComparisonExp
+  amount: NumericComparisonExp
   blockNumber: IntComparisonExp
   id: StringComparisonExp
   identity: IdentityBoolExp
@@ -4303,8 +5656,9 @@ input UdReevalBoolExp {
   id: StringComparisonExp
   membersCount: IntComparisonExp
   monetaryMass: NumericComparisonExp
-  newUdAmount: IntComparisonExp
+  newUdAmount: NumericComparisonExp
   timestamp: TimestamptzComparisonExp
+  udIndex: IntComparisonExp
 }
 
 "Ordering options when selecting data from \"ud_reeval\"."
@@ -4317,6 +5671,7 @@ input UdReevalOrderBy {
   monetaryMass: OrderBy
   newUdAmount: OrderBy
   timestamp: OrderBy
+  udIndex: OrderBy
 }
 
 "Boolean expression to filter rows from the table \"universal_dividend\". All fields are combined with a logical 'AND'."
@@ -4324,11 +5679,12 @@ input UniversalDividendBoolExp {
   _and: [UniversalDividendBoolExp!]
   _not: UniversalDividendBoolExp
   _or: [UniversalDividendBoolExp!]
-  amount: IntComparisonExp
+  amount: NumericComparisonExp
   blockNumber: IntComparisonExp
   event: EventBoolExp
   eventId: StringComparisonExp
   id: StringComparisonExp
+  index: IntComparisonExp
   membersCount: IntComparisonExp
   monetaryMass: NumericComparisonExp
   timestamp: TimestamptzComparisonExp
@@ -4341,11 +5697,41 @@ input UniversalDividendOrderBy {
   event: EventOrderBy
   eventId: OrderBy
   id: OrderBy
+  index: OrderBy
   membersCount: OrderBy
   monetaryMass: OrderBy
   timestamp: OrderBy
 }
 
+"Boolean expression to filter rows from the table \"validator\". All fields are combined with a logical 'AND'."
+input ValidatorBoolExp {
+  _and: [ValidatorBoolExp!]
+  _not: ValidatorBoolExp
+  _or: [ValidatorBoolExp!]
+  id: StringComparisonExp
+  index: IntComparisonExp
+}
+
+"Ordering options when selecting data from \"validator\"."
+input ValidatorOrderBy {
+  id: OrderBy
+  index: OrderBy
+}
+
+input accountAggregateBoolExpBool_and {
+  arguments: AccountSelectColumnAccountAggregateBoolExpBool_andArgumentsColumns!
+  distinct: Boolean
+  filter: AccountBoolExp
+  predicate: BooleanComparisonExp!
+}
+
+input accountAggregateBoolExpBool_or {
+  arguments: AccountSelectColumnAccountAggregateBoolExpBool_orArgumentsColumns!
+  distinct: Boolean
+  filter: AccountBoolExp
+  predicate: BooleanComparisonExp!
+}
+
 input accountAggregateBoolExpCount {
   arguments: [AccountSelectColumn!]
   distinct: Boolean
@@ -4441,6 +5827,27 @@ input getUdHistoryArgs {
   identity_row: identity_scalar
 }
 
+input identityAggregateBoolExpBool_and {
+  arguments: IdentitySelectColumnIdentityAggregateBoolExpBool_andArgumentsColumns!
+  distinct: Boolean
+  filter: IdentityBoolExp
+  predicate: BooleanComparisonExp!
+}
+
+input identityAggregateBoolExpBool_or {
+  arguments: IdentitySelectColumnIdentityAggregateBoolExpBool_orArgumentsColumns!
+  distinct: Boolean
+  filter: IdentityBoolExp
+  predicate: BooleanComparisonExp!
+}
+
+input identityAggregateBoolExpCount {
+  arguments: [IdentitySelectColumn!]
+  distinct: Boolean
+  filter: IdentityBoolExp
+  predicate: IntComparisonExp!
+}
+
 input membershipEventAggregateBoolExpCount {
   arguments: [MembershipEventSelectColumn!]
   distinct: Boolean
@@ -4455,9 +5862,23 @@ input smithCertAggregateBoolExpCount {
   predicate: IntComparisonExp!
 }
 
+input smithEventAggregateBoolExpCount {
+  arguments: [SmithEventSelectColumn!]
+  distinct: Boolean
+  filter: SmithEventBoolExp
+  predicate: IntComparisonExp!
+}
+
 input transferAggregateBoolExpCount {
   arguments: [TransferSelectColumn!]
   distinct: Boolean
   filter: TransferBoolExp
   predicate: IntComparisonExp!
 }
+
+input txCommentAggregateBoolExpCount {
+  arguments: [TxCommentSelectColumn!]
+  distinct: Boolean
+  filter: TxCommentBoolExp
+  predicate: IntComparisonExp!
+}
diff --git a/src/app/network/indexer/indexer-types.generated.ts b/src/app/network/indexer/indexer-types.generated.ts
index d6dae77458386c2e9a4d8769294ff44b7cea5673..7b48abfda0326c2b35a21bffd7853a437623d6e7 100644
--- a/src/app/network/indexer/indexer-types.generated.ts
+++ b/src/app/network/indexer/indexer-types.generated.ts
@@ -28,13 +28,30 @@ export type Scalars = {
 /** columns and relationships of "account" */
 export type Account = Node & {
   __typename?: 'Account';
+  balance: Scalars['numeric']['output'];
+  /** An array relationship */
+  commentsIssued: Array<TxComment>;
+  /** An aggregate relationship */
+  commentsIssuedAggregate: TxCommentAggregate;
+  /** An array relationship connection */
+  commentsIssued_connection: TxCommentConnection;
+  createdOn: Scalars['Int']['output'];
   id: Scalars['ID']['output'];
   /** An object relationship */
   identity?: Maybe<Identity>;
+  isActive: Scalars['Boolean']['output'];
   /** An object relationship */
   linkedIdentity?: Maybe<Identity>;
   linkedIdentityId?: Maybe<Scalars['String']['output']>;
   /** An array relationship */
+  removedIdentities: Array<Identity>;
+  /** An aggregate relationship */
+  removedIdentitiesAggregate: IdentityAggregate;
+  /** An array relationship connection */
+  removedIdentities_connection: IdentityConnection;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+  /** An array relationship */
   transfersIssued: Array<Transfer>;
   /** An aggregate relationship */
   transfersIssuedAggregate: TransferAggregate;
@@ -55,6 +72,70 @@ export type Account = Node & {
 };
 
 
+/** columns and relationships of "account" */
+export type AccountCommentsIssuedArgs = {
+  distinctOn?: InputMaybe<Array<TxCommentSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<TxCommentOrderBy>>;
+  where?: InputMaybe<TxCommentBoolExp>;
+};
+
+
+/** columns and relationships of "account" */
+export type AccountCommentsIssuedAggregateArgs = {
+  distinctOn?: InputMaybe<Array<TxCommentSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<TxCommentOrderBy>>;
+  where?: InputMaybe<TxCommentBoolExp>;
+};
+
+
+/** columns and relationships of "account" */
+export type AccountCommentsIssued_ConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<TxCommentSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<TxCommentOrderBy>>;
+  where?: InputMaybe<TxCommentBoolExp>;
+};
+
+
+/** columns and relationships of "account" */
+export type AccountRemovedIdentitiesArgs = {
+  distinctOn?: InputMaybe<Array<IdentitySelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<IdentityOrderBy>>;
+  where?: InputMaybe<IdentityBoolExp>;
+};
+
+
+/** columns and relationships of "account" */
+export type AccountRemovedIdentitiesAggregateArgs = {
+  distinctOn?: InputMaybe<Array<IdentitySelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<IdentityOrderBy>>;
+  where?: InputMaybe<IdentityBoolExp>;
+};
+
+
+/** columns and relationships of "account" */
+export type AccountRemovedIdentities_ConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<IdentitySelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<IdentityOrderBy>>;
+  where?: InputMaybe<IdentityBoolExp>;
+};
+
+
 /** columns and relationships of "account" */
 export type AccountTransfersIssuedArgs = {
   distinctOn?: InputMaybe<Array<TransferSelectColumn>>;
@@ -158,15 +239,25 @@ export type AccountAggregate = {
 };
 
 export type AccountAggregateBoolExp = {
+  bool_and?: InputMaybe<AccountAggregateBoolExpBool_And>;
+  bool_or?: InputMaybe<AccountAggregateBoolExpBool_Or>;
   count?: InputMaybe<AccountAggregateBoolExpCount>;
 };
 
 /** aggregate fields of "account" */
 export type AccountAggregateFields = {
   __typename?: 'AccountAggregateFields';
+  avg?: Maybe<AccountAvgFields>;
   count: Scalars['Int']['output'];
   max?: Maybe<AccountMaxFields>;
   min?: Maybe<AccountMinFields>;
+  stddev?: Maybe<AccountStddevFields>;
+  stddevPop?: Maybe<AccountStddevPopFields>;
+  stddevSamp?: Maybe<AccountStddevSampFields>;
+  sum?: Maybe<AccountSumFields>;
+  varPop?: Maybe<AccountVarPopFields>;
+  varSamp?: Maybe<AccountVarSampFields>;
+  variance?: Maybe<AccountVarianceFields>;
 };
 
 
@@ -178,9 +269,32 @@ export type AccountAggregateFieldsCountArgs = {
 
 /** order by aggregate values of table "account" */
 export type AccountAggregateOrderBy = {
+  avg?: InputMaybe<AccountAvgOrderBy>;
   count?: InputMaybe<OrderBy>;
   max?: InputMaybe<AccountMaxOrderBy>;
   min?: InputMaybe<AccountMinOrderBy>;
+  stddev?: InputMaybe<AccountStddevOrderBy>;
+  stddevPop?: InputMaybe<AccountStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<AccountStddevSampOrderBy>;
+  sum?: InputMaybe<AccountSumOrderBy>;
+  varPop?: InputMaybe<AccountVarPopOrderBy>;
+  varSamp?: InputMaybe<AccountVarSampOrderBy>;
+  variance?: InputMaybe<AccountVarianceOrderBy>;
+};
+
+/** aggregate avg on columns */
+export type AccountAvgFields = {
+  __typename?: 'AccountAvgFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by avg() on columns of table "account" */
+export type AccountAvgOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
 };
 
 /** Boolean expression to filter rows from the table "account". All fields are combined with a logical 'AND'. */
@@ -188,10 +302,18 @@ export type AccountBoolExp = {
   _and?: InputMaybe<Array<AccountBoolExp>>;
   _not?: InputMaybe<AccountBoolExp>;
   _or?: InputMaybe<Array<AccountBoolExp>>;
+  balance?: InputMaybe<NumericComparisonExp>;
+  commentsIssued?: InputMaybe<TxCommentBoolExp>;
+  commentsIssuedAggregate?: InputMaybe<TxCommentAggregateBoolExp>;
+  createdOn?: InputMaybe<IntComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
   identity?: InputMaybe<IdentityBoolExp>;
+  isActive?: InputMaybe<BooleanComparisonExp>;
   linkedIdentity?: InputMaybe<IdentityBoolExp>;
   linkedIdentityId?: InputMaybe<StringComparisonExp>;
+  removedIdentities?: InputMaybe<IdentityBoolExp>;
+  removedIdentitiesAggregate?: InputMaybe<IdentityAggregateBoolExp>;
+  totalBalance?: InputMaybe<NumericComparisonExp>;
   transfersIssued?: InputMaybe<TransferBoolExp>;
   transfersIssuedAggregate?: InputMaybe<TransferAggregateBoolExp>;
   transfersReceived?: InputMaybe<TransferBoolExp>;
@@ -216,12 +338,18 @@ export type AccountEdge = {
 /** aggregate max on columns */
 export type AccountMaxFields = {
   __typename?: 'AccountMaxFields';
+  balance?: Maybe<Scalars['numeric']['output']>;
+  createdOn?: Maybe<Scalars['Int']['output']>;
   id?: Maybe<Scalars['String']['output']>;
   linkedIdentityId?: Maybe<Scalars['String']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
 };
 
 /** order by max() on columns of table "account" */
 export type AccountMaxOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
   linkedIdentityId?: InputMaybe<OrderBy>;
 };
@@ -229,22 +357,34 @@ export type AccountMaxOrderBy = {
 /** aggregate min on columns */
 export type AccountMinFields = {
   __typename?: 'AccountMinFields';
+  balance?: Maybe<Scalars['numeric']['output']>;
+  createdOn?: Maybe<Scalars['Int']['output']>;
   id?: Maybe<Scalars['String']['output']>;
   linkedIdentityId?: Maybe<Scalars['String']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
 };
 
 /** order by min() on columns of table "account" */
 export type AccountMinOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
   linkedIdentityId?: InputMaybe<OrderBy>;
 };
 
 /** Ordering options when selecting data from "account". */
 export type AccountOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  commentsIssuedAggregate?: InputMaybe<TxCommentAggregateOrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
   identity?: InputMaybe<IdentityOrderBy>;
+  isActive?: InputMaybe<OrderBy>;
   linkedIdentity?: InputMaybe<IdentityOrderBy>;
   linkedIdentityId?: InputMaybe<OrderBy>;
+  removedIdentitiesAggregate?: InputMaybe<IdentityAggregateOrderBy>;
+  totalBalance?: InputMaybe<OrderBy>;
   transfersIssuedAggregate?: InputMaybe<TransferAggregateOrderBy>;
   transfersReceivedAggregate?: InputMaybe<TransferAggregateOrderBy>;
   wasIdentityAggregate?: InputMaybe<ChangeOwnerKeyAggregateOrderBy>;
@@ -252,12 +392,135 @@ export type AccountOrderBy = {
 
 /** select columns of table "account" */
 export enum AccountSelectColumn {
+  /** column name */
+  Balance = 'balance',
+  /** column name */
+  CreatedOn = 'createdOn',
   /** column name */
   Id = 'id',
   /** column name */
+  IsActive = 'isActive',
+  /** column name */
   LinkedIdentityId = 'linkedIdentityId'
 }
 
+/** select "accountAggregateBoolExpBool_andArgumentsColumns" columns of table "account" */
+export enum AccountSelectColumnAccountAggregateBoolExpBool_AndArgumentsColumns {
+  /** column name */
+  IsActive = 'isActive'
+}
+
+/** select "accountAggregateBoolExpBool_orArgumentsColumns" columns of table "account" */
+export enum AccountSelectColumnAccountAggregateBoolExpBool_OrArgumentsColumns {
+  /** column name */
+  IsActive = 'isActive'
+}
+
+/** aggregate stddev on columns */
+export type AccountStddevFields = {
+  __typename?: 'AccountStddevFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by stddev() on columns of table "account" */
+export type AccountStddevOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevPop on columns */
+export type AccountStddevPopFields = {
+  __typename?: 'AccountStddevPopFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by stddevPop() on columns of table "account" */
+export type AccountStddevPopOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevSamp on columns */
+export type AccountStddevSampFields = {
+  __typename?: 'AccountStddevSampFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by stddevSamp() on columns of table "account" */
+export type AccountStddevSampOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate sum on columns */
+export type AccountSumFields = {
+  __typename?: 'AccountSumFields';
+  balance?: Maybe<Scalars['numeric']['output']>;
+  createdOn?: Maybe<Scalars['Int']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by sum() on columns of table "account" */
+export type AccountSumOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varPop on columns */
+export type AccountVarPopFields = {
+  __typename?: 'AccountVarPopFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by varPop() on columns of table "account" */
+export type AccountVarPopOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varSamp on columns */
+export type AccountVarSampFields = {
+  __typename?: 'AccountVarSampFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by varSamp() on columns of table "account" */
+export type AccountVarSampOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate variance on columns */
+export type AccountVarianceFields = {
+  __typename?: 'AccountVarianceFields';
+  balance?: Maybe<Scalars['Float']['output']>;
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  /** "Get total balance including unclaimed UDs" */
+  totalBalance?: Maybe<Scalars['numeric']['output']>;
+};
+
+/** order by variance() on columns of table "account" */
+export type AccountVarianceOrderBy = {
+  balance?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+};
+
 /** columns and relationships of "block" */
 export type Block = Node & {
   __typename?: 'Block';
@@ -1656,6 +1919,22 @@ export type ChangeOwnerKeyVarianceOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
+export enum CommentTypeEnum {
+  Ascii = 'ASCII',
+  Cid = 'CID',
+  Raw = 'RAW',
+  Unicode = 'UNICODE'
+}
+
+/** Boolean expression to compare columns of type "CommentTypeEnum". All fields are combined with logical 'AND'. */
+export type CommentTypeEnumComparisonExp = {
+  _eq?: InputMaybe<CommentTypeEnum>;
+  _in?: InputMaybe<Array<CommentTypeEnum>>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  _neq?: InputMaybe<CommentTypeEnum>;
+  _nin?: InputMaybe<Array<CommentTypeEnum>>;
+};
+
 export enum CounterLevelEnum {
   Global = 'GLOBAL',
   Item = 'ITEM',
@@ -2419,6 +2698,9 @@ export type Identity = Node & {
   /** An object relationship */
   account?: Maybe<Account>;
   accountId?: Maybe<Scalars['String']['output']>;
+  /** An object relationship */
+  accountRemoved?: Maybe<Account>;
+  accountRemovedId?: Maybe<Scalars['String']['output']>;
   /** An array relationship */
   certIssued: Array<Cert>;
   /** An aggregate relationship */
@@ -2436,6 +2718,7 @@ export type Identity = Node & {
   createdInId?: Maybe<Scalars['String']['output']>;
   createdOn: Scalars['Int']['output'];
   expireOn: Scalars['Int']['output'];
+  firstEligibleUd?: Maybe<Scalars['Int']['output']>;
   id: Scalars['ID']['output'];
   index: Scalars['Int']['output'];
   isMember: Scalars['Boolean']['output'];
@@ -2459,19 +2742,8 @@ export type Identity = Node & {
   ownerKeyChangeAggregate: ChangeOwnerKeyAggregate;
   /** An array relationship connection */
   ownerKeyChange_connection: ChangeOwnerKeyConnection;
-  /** An array relationship */
-  smithCertIssued: Array<SmithCert>;
-  /** An aggregate relationship */
-  smithCertIssuedAggregate: SmithCertAggregate;
-  /** An array relationship connection */
-  smithCertIssued_connection: SmithCertConnection;
-  /** An array relationship */
-  smithCertReceived: Array<SmithCert>;
-  /** An aggregate relationship */
-  smithCertReceivedAggregate: SmithCertAggregate;
-  /** An array relationship connection */
-  smithCertReceived_connection: SmithCertConnection;
-  smithStatus?: Maybe<SmithStatusEnum>;
+  /** An object relationship */
+  smith?: Maybe<Smith>;
   status?: Maybe<IdentityStatusEnum>;
   /** "Get UD History by Identity" */
   udHistory?: Maybe<Array<UdHistory>>;
@@ -2639,76 +2911,82 @@ export type IdentityOwnerKeyChange_ConnectionArgs = {
 
 
 /** columns and relationships of "identity" */
-export type IdentitySmithCertIssuedArgs = {
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+export type IdentityUdHistoryArgs = {
+  distinctOn?: InputMaybe<Array<UdHistorySelectColumn>>;
   limit?: InputMaybe<Scalars['Int']['input']>;
   offset?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+  orderBy?: InputMaybe<Array<UdHistoryOrderBy>>;
+  where?: InputMaybe<UdHistoryBoolExp>;
 };
 
-
-/** columns and relationships of "identity" */
-export type IdentitySmithCertIssuedAggregateArgs = {
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
-  limit?: InputMaybe<Scalars['Int']['input']>;
-  offset?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+/** aggregated selection of "identity" */
+export type IdentityAggregate = {
+  __typename?: 'IdentityAggregate';
+  aggregate?: Maybe<IdentityAggregateFields>;
+  nodes: Array<Identity>;
 };
 
-
-/** columns and relationships of "identity" */
-export type IdentitySmithCertIssued_ConnectionArgs = {
-  after?: InputMaybe<Scalars['String']['input']>;
-  before?: InputMaybe<Scalars['String']['input']>;
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
-  first?: InputMaybe<Scalars['Int']['input']>;
-  last?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+export type IdentityAggregateBoolExp = {
+  bool_and?: InputMaybe<IdentityAggregateBoolExpBool_And>;
+  bool_or?: InputMaybe<IdentityAggregateBoolExpBool_Or>;
+  count?: InputMaybe<IdentityAggregateBoolExpCount>;
 };
 
-
-/** columns and relationships of "identity" */
-export type IdentitySmithCertReceivedArgs = {
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
-  limit?: InputMaybe<Scalars['Int']['input']>;
-  offset?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+/** aggregate fields of "identity" */
+export type IdentityAggregateFields = {
+  __typename?: 'IdentityAggregateFields';
+  avg?: Maybe<IdentityAvgFields>;
+  count: Scalars['Int']['output'];
+  max?: Maybe<IdentityMaxFields>;
+  min?: Maybe<IdentityMinFields>;
+  stddev?: Maybe<IdentityStddevFields>;
+  stddevPop?: Maybe<IdentityStddevPopFields>;
+  stddevSamp?: Maybe<IdentityStddevSampFields>;
+  sum?: Maybe<IdentitySumFields>;
+  varPop?: Maybe<IdentityVarPopFields>;
+  varSamp?: Maybe<IdentityVarSampFields>;
+  variance?: Maybe<IdentityVarianceFields>;
 };
 
 
-/** columns and relationships of "identity" */
-export type IdentitySmithCertReceivedAggregateArgs = {
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
-  limit?: InputMaybe<Scalars['Int']['input']>;
-  offset?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+/** aggregate fields of "identity" */
+export type IdentityAggregateFieldsCountArgs = {
+  columns?: InputMaybe<Array<IdentitySelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
 };
 
-
-/** columns and relationships of "identity" */
-export type IdentitySmithCertReceived_ConnectionArgs = {
-  after?: InputMaybe<Scalars['String']['input']>;
-  before?: InputMaybe<Scalars['String']['input']>;
-  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
-  first?: InputMaybe<Scalars['Int']['input']>;
-  last?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
-  where?: InputMaybe<SmithCertBoolExp>;
+/** order by aggregate values of table "identity" */
+export type IdentityAggregateOrderBy = {
+  avg?: InputMaybe<IdentityAvgOrderBy>;
+  count?: InputMaybe<OrderBy>;
+  max?: InputMaybe<IdentityMaxOrderBy>;
+  min?: InputMaybe<IdentityMinOrderBy>;
+  stddev?: InputMaybe<IdentityStddevOrderBy>;
+  stddevPop?: InputMaybe<IdentityStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<IdentityStddevSampOrderBy>;
+  sum?: InputMaybe<IdentitySumOrderBy>;
+  varPop?: InputMaybe<IdentityVarPopOrderBy>;
+  varSamp?: InputMaybe<IdentityVarSampOrderBy>;
+  variance?: InputMaybe<IdentityVarianceOrderBy>;
 };
 
+/** aggregate avg on columns */
+export type IdentityAvgFields = {
+  __typename?: 'IdentityAvgFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
 
-/** columns and relationships of "identity" */
-export type IdentityUdHistoryArgs = {
-  distinctOn?: InputMaybe<Array<UdHistorySelectColumn>>;
-  limit?: InputMaybe<Scalars['Int']['input']>;
-  offset?: InputMaybe<Scalars['Int']['input']>;
-  orderBy?: InputMaybe<Array<UdHistoryOrderBy>>;
-  where?: InputMaybe<UdHistoryBoolExp>;
+/** order by avg() on columns of table "identity" */
+export type IdentityAvgOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
 };
 
 /** Boolean expression to filter rows from the table "identity". All fields are combined with a logical 'AND'. */
@@ -2718,6 +2996,8 @@ export type IdentityBoolExp = {
   _or?: InputMaybe<Array<IdentityBoolExp>>;
   account?: InputMaybe<AccountBoolExp>;
   accountId?: InputMaybe<StringComparisonExp>;
+  accountRemoved?: InputMaybe<AccountBoolExp>;
+  accountRemovedId?: InputMaybe<StringComparisonExp>;
   certIssued?: InputMaybe<CertBoolExp>;
   certIssuedAggregate?: InputMaybe<CertAggregateBoolExp>;
   certReceived?: InputMaybe<CertBoolExp>;
@@ -2726,6 +3006,7 @@ export type IdentityBoolExp = {
   createdInId?: InputMaybe<StringComparisonExp>;
   createdOn?: InputMaybe<IntComparisonExp>;
   expireOn?: InputMaybe<IntComparisonExp>;
+  firstEligibleUd?: InputMaybe<IntComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
   index?: InputMaybe<IntComparisonExp>;
   isMember?: InputMaybe<BooleanComparisonExp>;
@@ -2737,11 +3018,7 @@ export type IdentityBoolExp = {
   name?: InputMaybe<StringComparisonExp>;
   ownerKeyChange?: InputMaybe<ChangeOwnerKeyBoolExp>;
   ownerKeyChangeAggregate?: InputMaybe<ChangeOwnerKeyAggregateBoolExp>;
-  smithCertIssued?: InputMaybe<SmithCertBoolExp>;
-  smithCertIssuedAggregate?: InputMaybe<SmithCertAggregateBoolExp>;
-  smithCertReceived?: InputMaybe<SmithCertBoolExp>;
-  smithCertReceivedAggregate?: InputMaybe<SmithCertAggregateBoolExp>;
-  smithStatus?: InputMaybe<SmithStatusEnumComparisonExp>;
+  smith?: InputMaybe<SmithBoolExp>;
   status?: InputMaybe<IdentityStatusEnumComparisonExp>;
   udHistory?: InputMaybe<UdHistoryBoolExp>;
 };
@@ -2759,42 +3036,105 @@ export type IdentityEdge = {
   node: Identity;
 };
 
-/** Ordering options when selecting data from "identity". */
-export type IdentityOrderBy = {
-  account?: InputMaybe<AccountOrderBy>;
+/** aggregate max on columns */
+export type IdentityMaxFields = {
+  __typename?: 'IdentityMaxFields';
+  accountId?: Maybe<Scalars['String']['output']>;
+  accountRemovedId?: Maybe<Scalars['String']['output']>;
+  createdInId?: Maybe<Scalars['String']['output']>;
+  createdOn?: Maybe<Scalars['Int']['output']>;
+  expireOn?: Maybe<Scalars['Int']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Int']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  index?: Maybe<Scalars['Int']['output']>;
+  lastChangeOn?: Maybe<Scalars['Int']['output']>;
+  name?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by max() on columns of table "identity" */
+export type IdentityMaxOrderBy = {
   accountId?: InputMaybe<OrderBy>;
-  certIssuedAggregate?: InputMaybe<CertAggregateOrderBy>;
-  certReceivedAggregate?: InputMaybe<CertAggregateOrderBy>;
-  createdIn?: InputMaybe<EventOrderBy>;
+  accountRemovedId?: InputMaybe<OrderBy>;
   createdInId?: InputMaybe<OrderBy>;
   createdOn?: InputMaybe<OrderBy>;
   expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
   index?: InputMaybe<OrderBy>;
-  isMember?: InputMaybe<OrderBy>;
   lastChangeOn?: InputMaybe<OrderBy>;
-  linkedAccountAggregate?: InputMaybe<AccountAggregateOrderBy>;
-  membershipHistoryAggregate?: InputMaybe<MembershipEventAggregateOrderBy>;
   name?: InputMaybe<OrderBy>;
-  ownerKeyChangeAggregate?: InputMaybe<ChangeOwnerKeyAggregateOrderBy>;
-  smithCertIssuedAggregate?: InputMaybe<SmithCertAggregateOrderBy>;
-  smithCertReceivedAggregate?: InputMaybe<SmithCertAggregateOrderBy>;
-  smithStatus?: InputMaybe<OrderBy>;
-  status?: InputMaybe<OrderBy>;
-  udHistoryAggregate?: InputMaybe<UdHistoryAggregateOrderBy>;
 };
 
-/** select columns of table "identity" */
-export enum IdentitySelectColumn {
-  /** column name */
-  AccountId = 'accountId',
-  /** column name */
-  CreatedInId = 'createdInId',
-  /** column name */
-  CreatedOn = 'createdOn',
+/** aggregate min on columns */
+export type IdentityMinFields = {
+  __typename?: 'IdentityMinFields';
+  accountId?: Maybe<Scalars['String']['output']>;
+  accountRemovedId?: Maybe<Scalars['String']['output']>;
+  createdInId?: Maybe<Scalars['String']['output']>;
+  createdOn?: Maybe<Scalars['Int']['output']>;
+  expireOn?: Maybe<Scalars['Int']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Int']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  index?: Maybe<Scalars['Int']['output']>;
+  lastChangeOn?: Maybe<Scalars['Int']['output']>;
+  name?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by min() on columns of table "identity" */
+export type IdentityMinOrderBy = {
+  accountId?: InputMaybe<OrderBy>;
+  accountRemovedId?: InputMaybe<OrderBy>;
+  createdInId?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+  name?: InputMaybe<OrderBy>;
+};
+
+/** Ordering options when selecting data from "identity". */
+export type IdentityOrderBy = {
+  account?: InputMaybe<AccountOrderBy>;
+  accountId?: InputMaybe<OrderBy>;
+  accountRemoved?: InputMaybe<AccountOrderBy>;
+  accountRemovedId?: InputMaybe<OrderBy>;
+  certIssuedAggregate?: InputMaybe<CertAggregateOrderBy>;
+  certReceivedAggregate?: InputMaybe<CertAggregateOrderBy>;
+  createdIn?: InputMaybe<EventOrderBy>;
+  createdInId?: InputMaybe<OrderBy>;
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  isMember?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+  linkedAccountAggregate?: InputMaybe<AccountAggregateOrderBy>;
+  membershipHistoryAggregate?: InputMaybe<MembershipEventAggregateOrderBy>;
+  name?: InputMaybe<OrderBy>;
+  ownerKeyChangeAggregate?: InputMaybe<ChangeOwnerKeyAggregateOrderBy>;
+  smith?: InputMaybe<SmithOrderBy>;
+  status?: InputMaybe<OrderBy>;
+  udHistoryAggregate?: InputMaybe<UdHistoryAggregateOrderBy>;
+};
+
+/** select columns of table "identity" */
+export enum IdentitySelectColumn {
+  /** column name */
+  AccountId = 'accountId',
+  /** column name */
+  AccountRemovedId = 'accountRemovedId',
+  /** column name */
+  CreatedInId = 'createdInId',
+  /** column name */
+  CreatedOn = 'createdOn',
   /** column name */
   ExpireOn = 'expireOn',
   /** column name */
+  FirstEligibleUd = 'firstEligibleUd',
+  /** column name */
   Id = 'id',
   /** column name */
   Index = 'index',
@@ -2805,11 +3145,21 @@ export enum IdentitySelectColumn {
   /** column name */
   Name = 'name',
   /** column name */
-  SmithStatus = 'smithStatus',
-  /** column name */
   Status = 'status'
 }
 
+/** select "identityAggregateBoolExpBool_andArgumentsColumns" columns of table "identity" */
+export enum IdentitySelectColumnIdentityAggregateBoolExpBool_AndArgumentsColumns {
+  /** column name */
+  IsMember = 'isMember'
+}
+
+/** select "identityAggregateBoolExpBool_orArgumentsColumns" columns of table "identity" */
+export enum IdentitySelectColumnIdentityAggregateBoolExpBool_OrArgumentsColumns {
+  /** column name */
+  IsMember = 'isMember'
+}
+
 export enum IdentityStatusEnum {
   Member = 'MEMBER',
   Notmember = 'NOTMEMBER',
@@ -2828,6 +3178,139 @@ export type IdentityStatusEnumComparisonExp = {
   _nin?: InputMaybe<Array<IdentityStatusEnum>>;
 };
 
+/** aggregate stddev on columns */
+export type IdentityStddevFields = {
+  __typename?: 'IdentityStddevFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddev() on columns of table "identity" */
+export type IdentityStddevOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevPop on columns */
+export type IdentityStddevPopFields = {
+  __typename?: 'IdentityStddevPopFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevPop() on columns of table "identity" */
+export type IdentityStddevPopOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevSamp on columns */
+export type IdentityStddevSampFields = {
+  __typename?: 'IdentityStddevSampFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevSamp() on columns of table "identity" */
+export type IdentityStddevSampOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate sum on columns */
+export type IdentitySumFields = {
+  __typename?: 'IdentitySumFields';
+  createdOn?: Maybe<Scalars['Int']['output']>;
+  expireOn?: Maybe<Scalars['Int']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Int']['output']>;
+  index?: Maybe<Scalars['Int']['output']>;
+  lastChangeOn?: Maybe<Scalars['Int']['output']>;
+};
+
+/** order by sum() on columns of table "identity" */
+export type IdentitySumOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varPop on columns */
+export type IdentityVarPopFields = {
+  __typename?: 'IdentityVarPopFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varPop() on columns of table "identity" */
+export type IdentityVarPopOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varSamp on columns */
+export type IdentityVarSampFields = {
+  __typename?: 'IdentityVarSampFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varSamp() on columns of table "identity" */
+export type IdentityVarSampOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
+/** aggregate variance on columns */
+export type IdentityVarianceFields = {
+  __typename?: 'IdentityVarianceFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+  expireOn?: Maybe<Scalars['Float']['output']>;
+  firstEligibleUd?: Maybe<Scalars['Float']['output']>;
+  index?: Maybe<Scalars['Float']['output']>;
+  lastChangeOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by variance() on columns of table "identity" */
+export type IdentityVarianceOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
+  expireOn?: InputMaybe<OrderBy>;
+  firstEligibleUd?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChangeOn?: InputMaybe<OrderBy>;
+};
+
 /** Boolean expression to compare columns of type "Int". All fields are combined with logical 'AND'. */
 export type IntArrayComparisonExp = {
   /** is the array contained in the given array value */
@@ -3234,77 +3717,284 @@ export type PageInfo = {
   startCursor: Scalars['String']['output'];
 };
 
-/** columns and relationships of "smith_cert" */
-export type SmithCert = Node & {
-  __typename?: 'SmithCert';
-  createdOn: Scalars['Int']['output'];
+/** columns and relationships of "population_history" */
+export type PopulationHistory = Node & {
+  __typename?: 'PopulationHistory';
+  activeAccountCount: Scalars['Int']['output'];
+  blockNumber: Scalars['Int']['output'];
   id: Scalars['ID']['output'];
-  /** An object relationship */
-  issuer?: Maybe<Identity>;
-  issuerId?: Maybe<Scalars['String']['output']>;
-  /** An object relationship */
-  receiver?: Maybe<Identity>;
-  receiverId?: Maybe<Scalars['String']['output']>;
+  memberCount: Scalars['Int']['output'];
+  smithCount: Scalars['Int']['output'];
 };
 
-/** aggregated selection of "smith_cert" */
-export type SmithCertAggregate = {
-  __typename?: 'SmithCertAggregate';
-  aggregate?: Maybe<SmithCertAggregateFields>;
-  nodes: Array<SmithCert>;
+/** Boolean expression to filter rows from the table "population_history". All fields are combined with a logical 'AND'. */
+export type PopulationHistoryBoolExp = {
+  _and?: InputMaybe<Array<PopulationHistoryBoolExp>>;
+  _not?: InputMaybe<PopulationHistoryBoolExp>;
+  _or?: InputMaybe<Array<PopulationHistoryBoolExp>>;
+  activeAccountCount?: InputMaybe<IntComparisonExp>;
+  blockNumber?: InputMaybe<IntComparisonExp>;
+  id?: InputMaybe<StringComparisonExp>;
+  memberCount?: InputMaybe<IntComparisonExp>;
+  smithCount?: InputMaybe<IntComparisonExp>;
 };
 
-export type SmithCertAggregateBoolExp = {
-  count?: InputMaybe<SmithCertAggregateBoolExpCount>;
+/** A Relay connection object on "population_history" */
+export type PopulationHistoryConnection = {
+  __typename?: 'PopulationHistoryConnection';
+  edges: Array<PopulationHistoryEdge>;
+  pageInfo: PageInfo;
 };
 
-/** aggregate fields of "smith_cert" */
-export type SmithCertAggregateFields = {
-  __typename?: 'SmithCertAggregateFields';
-  avg?: Maybe<SmithCertAvgFields>;
-  count: Scalars['Int']['output'];
-  max?: Maybe<SmithCertMaxFields>;
-  min?: Maybe<SmithCertMinFields>;
-  stddev?: Maybe<SmithCertStddevFields>;
-  stddevPop?: Maybe<SmithCertStddevPopFields>;
-  stddevSamp?: Maybe<SmithCertStddevSampFields>;
-  sum?: Maybe<SmithCertSumFields>;
-  varPop?: Maybe<SmithCertVarPopFields>;
-  varSamp?: Maybe<SmithCertVarSampFields>;
-  variance?: Maybe<SmithCertVarianceFields>;
+export type PopulationHistoryEdge = {
+  __typename?: 'PopulationHistoryEdge';
+  cursor: Scalars['String']['output'];
+  node: PopulationHistory;
 };
 
+/** Ordering options when selecting data from "population_history". */
+export type PopulationHistoryOrderBy = {
+  activeAccountCount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  memberCount?: InputMaybe<OrderBy>;
+  smithCount?: InputMaybe<OrderBy>;
+};
 
-/** aggregate fields of "smith_cert" */
-export type SmithCertAggregateFieldsCountArgs = {
-  columns?: InputMaybe<Array<SmithCertSelectColumn>>;
-  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+/** select columns of table "population_history" */
+export enum PopulationHistorySelectColumn {
+  /** column name */
+  ActiveAccountCount = 'activeAccountCount',
+  /** column name */
+  BlockNumber = 'blockNumber',
+  /** column name */
+  Id = 'id',
+  /** column name */
+  MemberCount = 'memberCount',
+  /** column name */
+  SmithCount = 'smithCount'
+}
+
+/** columns and relationships of "smith" */
+export type Smith = Node & {
+  __typename?: 'Smith';
+  forged: Scalars['Int']['output'];
+  id: Scalars['ID']['output'];
+  /** An object relationship */
+  identity?: Maybe<Identity>;
+  identityId?: Maybe<Scalars['String']['output']>;
+  index: Scalars['Int']['output'];
+  lastChanged?: Maybe<Scalars['Int']['output']>;
+  lastForged?: Maybe<Scalars['Int']['output']>;
+  /** An array relationship */
+  smithCertIssued: Array<SmithCert>;
+  /** An aggregate relationship */
+  smithCertIssuedAggregate: SmithCertAggregate;
+  /** An array relationship connection */
+  smithCertIssued_connection: SmithCertConnection;
+  /** An array relationship */
+  smithCertReceived: Array<SmithCert>;
+  /** An aggregate relationship */
+  smithCertReceivedAggregate: SmithCertAggregate;
+  /** An array relationship connection */
+  smithCertReceived_connection: SmithCertConnection;
+  /** An array relationship */
+  smithHistory: Array<SmithEvent>;
+  /** An aggregate relationship */
+  smithHistoryAggregate: SmithEventAggregate;
+  /** An array relationship connection */
+  smithHistory_connection: SmithEventConnection;
+  smithStatus?: Maybe<SmithStatusEnum>;
 };
 
-/** order by aggregate values of table "smith_cert" */
-export type SmithCertAggregateOrderBy = {
-  avg?: InputMaybe<SmithCertAvgOrderBy>;
-  count?: InputMaybe<OrderBy>;
-  max?: InputMaybe<SmithCertMaxOrderBy>;
-  min?: InputMaybe<SmithCertMinOrderBy>;
-  stddev?: InputMaybe<SmithCertStddevOrderBy>;
-  stddevPop?: InputMaybe<SmithCertStddevPopOrderBy>;
-  stddevSamp?: InputMaybe<SmithCertStddevSampOrderBy>;
-  sum?: InputMaybe<SmithCertSumOrderBy>;
-  varPop?: InputMaybe<SmithCertVarPopOrderBy>;
-  varSamp?: InputMaybe<SmithCertVarSampOrderBy>;
-  variance?: InputMaybe<SmithCertVarianceOrderBy>;
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertIssuedArgs = {
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
 };
 
-/** aggregate avg on columns */
-export type SmithCertAvgFields = {
-  __typename?: 'SmithCertAvgFields';
-  createdOn?: Maybe<Scalars['Float']['output']>;
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertIssuedAggregateArgs = {
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
 };
 
-/** order by avg() on columns of table "smith_cert" */
-export type SmithCertAvgOrderBy = {
-  createdOn?: InputMaybe<OrderBy>;
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertIssued_ConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertReceivedArgs = {
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertReceivedAggregateArgs = {
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithCertReceived_ConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithCertSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithCertOrderBy>>;
+  where?: InputMaybe<SmithCertBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithHistoryArgs = {
+  distinctOn?: InputMaybe<Array<SmithEventSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithEventOrderBy>>;
+  where?: InputMaybe<SmithEventBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithHistoryAggregateArgs = {
+  distinctOn?: InputMaybe<Array<SmithEventSelectColumn>>;
+  limit?: InputMaybe<Scalars['Int']['input']>;
+  offset?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithEventOrderBy>>;
+  where?: InputMaybe<SmithEventBoolExp>;
+};
+
+
+/** columns and relationships of "smith" */
+export type SmithSmithHistory_ConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithEventSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithEventOrderBy>>;
+  where?: InputMaybe<SmithEventBoolExp>;
+};
+
+/** Boolean expression to filter rows from the table "smith". All fields are combined with a logical 'AND'. */
+export type SmithBoolExp = {
+  _and?: InputMaybe<Array<SmithBoolExp>>;
+  _not?: InputMaybe<SmithBoolExp>;
+  _or?: InputMaybe<Array<SmithBoolExp>>;
+  forged?: InputMaybe<IntComparisonExp>;
+  id?: InputMaybe<StringComparisonExp>;
+  identity?: InputMaybe<IdentityBoolExp>;
+  identityId?: InputMaybe<StringComparisonExp>;
+  index?: InputMaybe<IntComparisonExp>;
+  lastChanged?: InputMaybe<IntComparisonExp>;
+  lastForged?: InputMaybe<IntComparisonExp>;
+  smithCertIssued?: InputMaybe<SmithCertBoolExp>;
+  smithCertIssuedAggregate?: InputMaybe<SmithCertAggregateBoolExp>;
+  smithCertReceived?: InputMaybe<SmithCertBoolExp>;
+  smithCertReceivedAggregate?: InputMaybe<SmithCertAggregateBoolExp>;
+  smithHistory?: InputMaybe<SmithEventBoolExp>;
+  smithHistoryAggregate?: InputMaybe<SmithEventAggregateBoolExp>;
+  smithStatus?: InputMaybe<SmithStatusEnumComparisonExp>;
+};
+
+/** columns and relationships of "smith_cert" */
+export type SmithCert = Node & {
+  __typename?: 'SmithCert';
+  createdOn: Scalars['Int']['output'];
+  id: Scalars['ID']['output'];
+  /** An object relationship */
+  issuer?: Maybe<Smith>;
+  issuerId?: Maybe<Scalars['String']['output']>;
+  /** An object relationship */
+  receiver?: Maybe<Smith>;
+  receiverId?: Maybe<Scalars['String']['output']>;
+};
+
+/** aggregated selection of "smith_cert" */
+export type SmithCertAggregate = {
+  __typename?: 'SmithCertAggregate';
+  aggregate?: Maybe<SmithCertAggregateFields>;
+  nodes: Array<SmithCert>;
+};
+
+export type SmithCertAggregateBoolExp = {
+  count?: InputMaybe<SmithCertAggregateBoolExpCount>;
+};
+
+/** aggregate fields of "smith_cert" */
+export type SmithCertAggregateFields = {
+  __typename?: 'SmithCertAggregateFields';
+  avg?: Maybe<SmithCertAvgFields>;
+  count: Scalars['Int']['output'];
+  max?: Maybe<SmithCertMaxFields>;
+  min?: Maybe<SmithCertMinFields>;
+  stddev?: Maybe<SmithCertStddevFields>;
+  stddevPop?: Maybe<SmithCertStddevPopFields>;
+  stddevSamp?: Maybe<SmithCertStddevSampFields>;
+  sum?: Maybe<SmithCertSumFields>;
+  varPop?: Maybe<SmithCertVarPopFields>;
+  varSamp?: Maybe<SmithCertVarSampFields>;
+  variance?: Maybe<SmithCertVarianceFields>;
+};
+
+
+/** aggregate fields of "smith_cert" */
+export type SmithCertAggregateFieldsCountArgs = {
+  columns?: InputMaybe<Array<SmithCertSelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+};
+
+/** order by aggregate values of table "smith_cert" */
+export type SmithCertAggregateOrderBy = {
+  avg?: InputMaybe<SmithCertAvgOrderBy>;
+  count?: InputMaybe<OrderBy>;
+  max?: InputMaybe<SmithCertMaxOrderBy>;
+  min?: InputMaybe<SmithCertMinOrderBy>;
+  stddev?: InputMaybe<SmithCertStddevOrderBy>;
+  stddevPop?: InputMaybe<SmithCertStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<SmithCertStddevSampOrderBy>;
+  sum?: InputMaybe<SmithCertSumOrderBy>;
+  varPop?: InputMaybe<SmithCertVarPopOrderBy>;
+  varSamp?: InputMaybe<SmithCertVarSampOrderBy>;
+  variance?: InputMaybe<SmithCertVarianceOrderBy>;
+};
+
+/** aggregate avg on columns */
+export type SmithCertAvgFields = {
+  __typename?: 'SmithCertAvgFields';
+  createdOn?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by avg() on columns of table "smith_cert" */
+export type SmithCertAvgOrderBy = {
+  createdOn?: InputMaybe<OrderBy>;
 };
 
 /** Boolean expression to filter rows from the table "smith_cert". All fields are combined with a logical 'AND'. */
@@ -3314,9 +4004,9 @@ export type SmithCertBoolExp = {
   _or?: InputMaybe<Array<SmithCertBoolExp>>;
   createdOn?: InputMaybe<IntComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
-  issuer?: InputMaybe<IdentityBoolExp>;
+  issuer?: InputMaybe<SmithBoolExp>;
   issuerId?: InputMaybe<StringComparisonExp>;
-  receiver?: InputMaybe<IdentityBoolExp>;
+  receiver?: InputMaybe<SmithBoolExp>;
   receiverId?: InputMaybe<StringComparisonExp>;
 };
 
@@ -3371,9 +4061,9 @@ export type SmithCertMinOrderBy = {
 export type SmithCertOrderBy = {
   createdOn?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
-  issuer?: InputMaybe<IdentityOrderBy>;
+  issuer?: InputMaybe<SmithOrderBy>;
   issuerId?: InputMaybe<OrderBy>;
-  receiver?: InputMaybe<IdentityOrderBy>;
+  receiver?: InputMaybe<SmithOrderBy>;
   receiverId?: InputMaybe<OrderBy>;
 };
 
@@ -3466,364 +4156,940 @@ export type SmithCertVarianceOrderBy = {
   createdOn?: InputMaybe<OrderBy>;
 };
 
-export enum SmithStatusEnum {
-  Excluded = 'EXCLUDED',
-  Invited = 'INVITED',
-  Pending = 'PENDING',
-  Smith = 'SMITH'
-}
-
-/** Boolean expression to compare columns of type "SmithStatusEnum". All fields are combined with logical 'AND'. */
-export type SmithStatusEnumComparisonExp = {
-  _eq?: InputMaybe<SmithStatusEnum>;
-  _in?: InputMaybe<Array<SmithStatusEnum>>;
-  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
-  _neq?: InputMaybe<SmithStatusEnum>;
-  _nin?: InputMaybe<Array<SmithStatusEnum>>;
-};
-
-/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */
-export type StringArrayComparisonExp = {
-  /** is the array contained in the given array value */
-  _containedIn?: InputMaybe<Array<Scalars['String']['input']>>;
-  /** does the array contain the given value */
-  _contains?: InputMaybe<Array<Scalars['String']['input']>>;
-  _eq?: InputMaybe<Array<Scalars['String']['input']>>;
-  _gt?: InputMaybe<Array<Scalars['String']['input']>>;
-  _gte?: InputMaybe<Array<Scalars['String']['input']>>;
-  _in?: InputMaybe<Array<Array<Scalars['String']['input']>>>;
-  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
-  _lt?: InputMaybe<Array<Scalars['String']['input']>>;
-  _lte?: InputMaybe<Array<Scalars['String']['input']>>;
-  _neq?: InputMaybe<Array<Scalars['String']['input']>>;
-  _nin?: InputMaybe<Array<Array<Scalars['String']['input']>>>;
-};
-
-/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */
-export type StringComparisonExp = {
-  _eq?: InputMaybe<Scalars['String']['input']>;
-  _gt?: InputMaybe<Scalars['String']['input']>;
-  _gte?: InputMaybe<Scalars['String']['input']>;
-  /** does the column match the given case-insensitive pattern */
-  _ilike?: InputMaybe<Scalars['String']['input']>;
-  _in?: InputMaybe<Array<Scalars['String']['input']>>;
-  /** does the column match the given POSIX regular expression, case insensitive */
-  _iregex?: InputMaybe<Scalars['String']['input']>;
-  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
-  /** does the column match the given pattern */
-  _like?: InputMaybe<Scalars['String']['input']>;
-  _lt?: InputMaybe<Scalars['String']['input']>;
-  _lte?: InputMaybe<Scalars['String']['input']>;
-  _neq?: InputMaybe<Scalars['String']['input']>;
-  /** does the column NOT match the given case-insensitive pattern */
-  _nilike?: InputMaybe<Scalars['String']['input']>;
-  _nin?: InputMaybe<Array<Scalars['String']['input']>>;
-  /** does the column NOT match the given POSIX regular expression, case insensitive */
-  _niregex?: InputMaybe<Scalars['String']['input']>;
-  /** does the column NOT match the given pattern */
-  _nlike?: InputMaybe<Scalars['String']['input']>;
-  /** does the column NOT match the given POSIX regular expression, case sensitive */
-  _nregex?: InputMaybe<Scalars['String']['input']>;
-  /** does the column NOT match the given SQL regular expression */
-  _nsimilar?: InputMaybe<Scalars['String']['input']>;
-  /** does the column match the given POSIX regular expression, case sensitive */
-  _regex?: InputMaybe<Scalars['String']['input']>;
-  /** does the column match the given SQL regular expression */
-  _similar?: InputMaybe<Scalars['String']['input']>;
+/** A Relay connection object on "smith" */
+export type SmithConnection = {
+  __typename?: 'SmithConnection';
+  edges: Array<SmithEdge>;
+  pageInfo: PageInfo;
 };
 
-/** Boolean expression to compare columns of type "timestamptz". All fields are combined with logical 'AND'. */
-export type TimestamptzComparisonExp = {
-  _eq?: InputMaybe<Scalars['timestamptz']['input']>;
-  _gt?: InputMaybe<Scalars['timestamptz']['input']>;
-  _gte?: InputMaybe<Scalars['timestamptz']['input']>;
-  _in?: InputMaybe<Array<Scalars['timestamptz']['input']>>;
-  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
-  _lt?: InputMaybe<Scalars['timestamptz']['input']>;
-  _lte?: InputMaybe<Scalars['timestamptz']['input']>;
-  _neq?: InputMaybe<Scalars['timestamptz']['input']>;
-  _nin?: InputMaybe<Array<Scalars['timestamptz']['input']>>;
+export type SmithEdge = {
+  __typename?: 'SmithEdge';
+  cursor: Scalars['String']['output'];
+  node: Smith;
 };
 
-/** columns and relationships of "transfer" */
-export type Transfer = Node & {
-  __typename?: 'Transfer';
-  amount: Scalars['numeric']['output'];
+/** columns and relationships of "smith_event" */
+export type SmithEvent = Node & {
+  __typename?: 'SmithEvent';
   blockNumber: Scalars['Int']['output'];
-  comment?: Maybe<Scalars['String']['output']>;
   /** An object relationship */
-  from?: Maybe<Account>;
-  fromId?: Maybe<Scalars['String']['output']>;
+  event?: Maybe<Event>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  eventType?: Maybe<SmithEventTypeEnum>;
   id: Scalars['ID']['output'];
-  timestamp: Scalars['timestamptz']['output'];
   /** An object relationship */
-  to?: Maybe<Account>;
-  toId?: Maybe<Scalars['String']['output']>;
+  smith?: Maybe<Smith>;
+  smithId?: Maybe<Scalars['String']['output']>;
 };
 
-/** aggregated selection of "transfer" */
-export type TransferAggregate = {
-  __typename?: 'TransferAggregate';
-  aggregate?: Maybe<TransferAggregateFields>;
-  nodes: Array<Transfer>;
+/** aggregated selection of "smith_event" */
+export type SmithEventAggregate = {
+  __typename?: 'SmithEventAggregate';
+  aggregate?: Maybe<SmithEventAggregateFields>;
+  nodes: Array<SmithEvent>;
 };
 
-export type TransferAggregateBoolExp = {
-  count?: InputMaybe<TransferAggregateBoolExpCount>;
+export type SmithEventAggregateBoolExp = {
+  count?: InputMaybe<SmithEventAggregateBoolExpCount>;
 };
 
-/** aggregate fields of "transfer" */
-export type TransferAggregateFields = {
-  __typename?: 'TransferAggregateFields';
-  avg?: Maybe<TransferAvgFields>;
+/** aggregate fields of "smith_event" */
+export type SmithEventAggregateFields = {
+  __typename?: 'SmithEventAggregateFields';
+  avg?: Maybe<SmithEventAvgFields>;
   count: Scalars['Int']['output'];
-  max?: Maybe<TransferMaxFields>;
-  min?: Maybe<TransferMinFields>;
-  stddev?: Maybe<TransferStddevFields>;
-  stddevPop?: Maybe<TransferStddevPopFields>;
-  stddevSamp?: Maybe<TransferStddevSampFields>;
-  sum?: Maybe<TransferSumFields>;
-  varPop?: Maybe<TransferVarPopFields>;
-  varSamp?: Maybe<TransferVarSampFields>;
-  variance?: Maybe<TransferVarianceFields>;
+  max?: Maybe<SmithEventMaxFields>;
+  min?: Maybe<SmithEventMinFields>;
+  stddev?: Maybe<SmithEventStddevFields>;
+  stddevPop?: Maybe<SmithEventStddevPopFields>;
+  stddevSamp?: Maybe<SmithEventStddevSampFields>;
+  sum?: Maybe<SmithEventSumFields>;
+  varPop?: Maybe<SmithEventVarPopFields>;
+  varSamp?: Maybe<SmithEventVarSampFields>;
+  variance?: Maybe<SmithEventVarianceFields>;
 };
 
 
-/** aggregate fields of "transfer" */
-export type TransferAggregateFieldsCountArgs = {
-  columns?: InputMaybe<Array<TransferSelectColumn>>;
+/** aggregate fields of "smith_event" */
+export type SmithEventAggregateFieldsCountArgs = {
+  columns?: InputMaybe<Array<SmithEventSelectColumn>>;
   distinct?: InputMaybe<Scalars['Boolean']['input']>;
 };
 
-/** order by aggregate values of table "transfer" */
-export type TransferAggregateOrderBy = {
-  avg?: InputMaybe<TransferAvgOrderBy>;
+/** order by aggregate values of table "smith_event" */
+export type SmithEventAggregateOrderBy = {
+  avg?: InputMaybe<SmithEventAvgOrderBy>;
   count?: InputMaybe<OrderBy>;
-  max?: InputMaybe<TransferMaxOrderBy>;
-  min?: InputMaybe<TransferMinOrderBy>;
-  stddev?: InputMaybe<TransferStddevOrderBy>;
-  stddevPop?: InputMaybe<TransferStddevPopOrderBy>;
-  stddevSamp?: InputMaybe<TransferStddevSampOrderBy>;
-  sum?: InputMaybe<TransferSumOrderBy>;
-  varPop?: InputMaybe<TransferVarPopOrderBy>;
-  varSamp?: InputMaybe<TransferVarSampOrderBy>;
-  variance?: InputMaybe<TransferVarianceOrderBy>;
+  max?: InputMaybe<SmithEventMaxOrderBy>;
+  min?: InputMaybe<SmithEventMinOrderBy>;
+  stddev?: InputMaybe<SmithEventStddevOrderBy>;
+  stddevPop?: InputMaybe<SmithEventStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<SmithEventStddevSampOrderBy>;
+  sum?: InputMaybe<SmithEventSumOrderBy>;
+  varPop?: InputMaybe<SmithEventVarPopOrderBy>;
+  varSamp?: InputMaybe<SmithEventVarSampOrderBy>;
+  variance?: InputMaybe<SmithEventVarianceOrderBy>;
+};
+
+/** aggregate avg on columns */
+export type SmithEventAvgFields = {
+  __typename?: 'SmithEventAvgFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by avg() on columns of table "smith_event" */
+export type SmithEventAvgOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** Boolean expression to filter rows from the table "smith_event". All fields are combined with a logical 'AND'. */
+export type SmithEventBoolExp = {
+  _and?: InputMaybe<Array<SmithEventBoolExp>>;
+  _not?: InputMaybe<SmithEventBoolExp>;
+  _or?: InputMaybe<Array<SmithEventBoolExp>>;
+  blockNumber?: InputMaybe<IntComparisonExp>;
+  event?: InputMaybe<EventBoolExp>;
+  eventId?: InputMaybe<StringComparisonExp>;
+  eventType?: InputMaybe<SmithEventTypeEnumComparisonExp>;
+  id?: InputMaybe<StringComparisonExp>;
+  smith?: InputMaybe<SmithBoolExp>;
+  smithId?: InputMaybe<StringComparisonExp>;
+};
+
+/** A Relay connection object on "smith_event" */
+export type SmithEventConnection = {
+  __typename?: 'SmithEventConnection';
+  edges: Array<SmithEventEdge>;
+  pageInfo: PageInfo;
+};
+
+export type SmithEventEdge = {
+  __typename?: 'SmithEventEdge';
+  cursor: Scalars['String']['output'];
+  node: SmithEvent;
+};
+
+/** aggregate max on columns */
+export type SmithEventMaxFields = {
+  __typename?: 'SmithEventMaxFields';
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  smithId?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by max() on columns of table "smith_event" */
+export type SmithEventMaxOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  smithId?: InputMaybe<OrderBy>;
+};
+
+/** aggregate min on columns */
+export type SmithEventMinFields = {
+  __typename?: 'SmithEventMinFields';
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  smithId?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by min() on columns of table "smith_event" */
+export type SmithEventMinOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  smithId?: InputMaybe<OrderBy>;
+};
+
+/** Ordering options when selecting data from "smith_event". */
+export type SmithEventOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+  event?: InputMaybe<EventOrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  eventType?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  smith?: InputMaybe<SmithOrderBy>;
+  smithId?: InputMaybe<OrderBy>;
+};
+
+/** select columns of table "smith_event" */
+export enum SmithEventSelectColumn {
+  /** column name */
+  BlockNumber = 'blockNumber',
+  /** column name */
+  EventId = 'eventId',
+  /** column name */
+  EventType = 'eventType',
+  /** column name */
+  Id = 'id',
+  /** column name */
+  SmithId = 'smithId'
+}
+
+/** aggregate stddev on columns */
+export type SmithEventStddevFields = {
+  __typename?: 'SmithEventStddevFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddev() on columns of table "smith_event" */
+export type SmithEventStddevOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevPop on columns */
+export type SmithEventStddevPopFields = {
+  __typename?: 'SmithEventStddevPopFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevPop() on columns of table "smith_event" */
+export type SmithEventStddevPopOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevSamp on columns */
+export type SmithEventStddevSampFields = {
+  __typename?: 'SmithEventStddevSampFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevSamp() on columns of table "smith_event" */
+export type SmithEventStddevSampOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate sum on columns */
+export type SmithEventSumFields = {
+  __typename?: 'SmithEventSumFields';
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+};
+
+/** order by sum() on columns of table "smith_event" */
+export type SmithEventSumOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+export enum SmithEventTypeEnum {
+  Accepted = 'ACCEPTED',
+  Excluded = 'EXCLUDED',
+  Invited = 'INVITED',
+  Promoted = 'PROMOTED'
+}
+
+/** Boolean expression to compare columns of type "SmithEventTypeEnum". All fields are combined with logical 'AND'. */
+export type SmithEventTypeEnumComparisonExp = {
+  _eq?: InputMaybe<SmithEventTypeEnum>;
+  _in?: InputMaybe<Array<SmithEventTypeEnum>>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  _neq?: InputMaybe<SmithEventTypeEnum>;
+  _nin?: InputMaybe<Array<SmithEventTypeEnum>>;
+};
+
+/** aggregate varPop on columns */
+export type SmithEventVarPopFields = {
+  __typename?: 'SmithEventVarPopFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varPop() on columns of table "smith_event" */
+export type SmithEventVarPopOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varSamp on columns */
+export type SmithEventVarSampFields = {
+  __typename?: 'SmithEventVarSampFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varSamp() on columns of table "smith_event" */
+export type SmithEventVarSampOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate variance on columns */
+export type SmithEventVarianceFields = {
+  __typename?: 'SmithEventVarianceFields';
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by variance() on columns of table "smith_event" */
+export type SmithEventVarianceOrderBy = {
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** Ordering options when selecting data from "smith". */
+export type SmithOrderBy = {
+  forged?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  identity?: InputMaybe<IdentityOrderBy>;
+  identityId?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+  lastChanged?: InputMaybe<OrderBy>;
+  lastForged?: InputMaybe<OrderBy>;
+  smithCertIssuedAggregate?: InputMaybe<SmithCertAggregateOrderBy>;
+  smithCertReceivedAggregate?: InputMaybe<SmithCertAggregateOrderBy>;
+  smithHistoryAggregate?: InputMaybe<SmithEventAggregateOrderBy>;
+  smithStatus?: InputMaybe<OrderBy>;
+};
+
+/** select columns of table "smith" */
+export enum SmithSelectColumn {
+  /** column name */
+  Forged = 'forged',
+  /** column name */
+  Id = 'id',
+  /** column name */
+  IdentityId = 'identityId',
+  /** column name */
+  Index = 'index',
+  /** column name */
+  LastChanged = 'lastChanged',
+  /** column name */
+  LastForged = 'lastForged',
+  /** column name */
+  SmithStatus = 'smithStatus'
+}
+
+export enum SmithStatusEnum {
+  Excluded = 'EXCLUDED',
+  Invited = 'INVITED',
+  Pending = 'PENDING',
+  Smith = 'SMITH'
+}
+
+/** Boolean expression to compare columns of type "SmithStatusEnum". All fields are combined with logical 'AND'. */
+export type SmithStatusEnumComparisonExp = {
+  _eq?: InputMaybe<SmithStatusEnum>;
+  _in?: InputMaybe<Array<SmithStatusEnum>>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  _neq?: InputMaybe<SmithStatusEnum>;
+  _nin?: InputMaybe<Array<SmithStatusEnum>>;
+};
+
+/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */
+export type StringArrayComparisonExp = {
+  /** is the array contained in the given array value */
+  _containedIn?: InputMaybe<Array<Scalars['String']['input']>>;
+  /** does the array contain the given value */
+  _contains?: InputMaybe<Array<Scalars['String']['input']>>;
+  _eq?: InputMaybe<Array<Scalars['String']['input']>>;
+  _gt?: InputMaybe<Array<Scalars['String']['input']>>;
+  _gte?: InputMaybe<Array<Scalars['String']['input']>>;
+  _in?: InputMaybe<Array<Array<Scalars['String']['input']>>>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  _lt?: InputMaybe<Array<Scalars['String']['input']>>;
+  _lte?: InputMaybe<Array<Scalars['String']['input']>>;
+  _neq?: InputMaybe<Array<Scalars['String']['input']>>;
+  _nin?: InputMaybe<Array<Array<Scalars['String']['input']>>>;
+};
+
+/** Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'. */
+export type StringComparisonExp = {
+  _eq?: InputMaybe<Scalars['String']['input']>;
+  _gt?: InputMaybe<Scalars['String']['input']>;
+  _gte?: InputMaybe<Scalars['String']['input']>;
+  /** does the column match the given case-insensitive pattern */
+  _ilike?: InputMaybe<Scalars['String']['input']>;
+  _in?: InputMaybe<Array<Scalars['String']['input']>>;
+  /** does the column match the given POSIX regular expression, case insensitive */
+  _iregex?: InputMaybe<Scalars['String']['input']>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  /** does the column match the given pattern */
+  _like?: InputMaybe<Scalars['String']['input']>;
+  _lt?: InputMaybe<Scalars['String']['input']>;
+  _lte?: InputMaybe<Scalars['String']['input']>;
+  _neq?: InputMaybe<Scalars['String']['input']>;
+  /** does the column NOT match the given case-insensitive pattern */
+  _nilike?: InputMaybe<Scalars['String']['input']>;
+  _nin?: InputMaybe<Array<Scalars['String']['input']>>;
+  /** does the column NOT match the given POSIX regular expression, case insensitive */
+  _niregex?: InputMaybe<Scalars['String']['input']>;
+  /** does the column NOT match the given pattern */
+  _nlike?: InputMaybe<Scalars['String']['input']>;
+  /** does the column NOT match the given POSIX regular expression, case sensitive */
+  _nregex?: InputMaybe<Scalars['String']['input']>;
+  /** does the column NOT match the given SQL regular expression */
+  _nsimilar?: InputMaybe<Scalars['String']['input']>;
+  /** does the column match the given POSIX regular expression, case sensitive */
+  _regex?: InputMaybe<Scalars['String']['input']>;
+  /** does the column match the given SQL regular expression */
+  _similar?: InputMaybe<Scalars['String']['input']>;
+};
+
+/** Boolean expression to compare columns of type "timestamptz". All fields are combined with logical 'AND'. */
+export type TimestamptzComparisonExp = {
+  _eq?: InputMaybe<Scalars['timestamptz']['input']>;
+  _gt?: InputMaybe<Scalars['timestamptz']['input']>;
+  _gte?: InputMaybe<Scalars['timestamptz']['input']>;
+  _in?: InputMaybe<Array<Scalars['timestamptz']['input']>>;
+  _isNull?: InputMaybe<Scalars['Boolean']['input']>;
+  _lt?: InputMaybe<Scalars['timestamptz']['input']>;
+  _lte?: InputMaybe<Scalars['timestamptz']['input']>;
+  _neq?: InputMaybe<Scalars['timestamptz']['input']>;
+  _nin?: InputMaybe<Array<Scalars['timestamptz']['input']>>;
+};
+
+/** columns and relationships of "transfer" */
+export type Transfer = Node & {
+  __typename?: 'Transfer';
+  amount: Scalars['numeric']['output'];
+  blockNumber: Scalars['Int']['output'];
+  /** An object relationship */
+  comment?: Maybe<TxComment>;
+  commentId?: Maybe<Scalars['String']['output']>;
+  /** An object relationship */
+  event?: Maybe<Event>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  /** An object relationship */
+  from?: Maybe<Account>;
+  fromId?: Maybe<Scalars['String']['output']>;
+  id: Scalars['ID']['output'];
+  timestamp: Scalars['timestamptz']['output'];
+  /** An object relationship */
+  to?: Maybe<Account>;
+  toId?: Maybe<Scalars['String']['output']>;
+};
+
+/** aggregated selection of "transfer" */
+export type TransferAggregate = {
+  __typename?: 'TransferAggregate';
+  aggregate?: Maybe<TransferAggregateFields>;
+  nodes: Array<Transfer>;
+};
+
+export type TransferAggregateBoolExp = {
+  count?: InputMaybe<TransferAggregateBoolExpCount>;
+};
+
+/** aggregate fields of "transfer" */
+export type TransferAggregateFields = {
+  __typename?: 'TransferAggregateFields';
+  avg?: Maybe<TransferAvgFields>;
+  count: Scalars['Int']['output'];
+  max?: Maybe<TransferMaxFields>;
+  min?: Maybe<TransferMinFields>;
+  stddev?: Maybe<TransferStddevFields>;
+  stddevPop?: Maybe<TransferStddevPopFields>;
+  stddevSamp?: Maybe<TransferStddevSampFields>;
+  sum?: Maybe<TransferSumFields>;
+  varPop?: Maybe<TransferVarPopFields>;
+  varSamp?: Maybe<TransferVarSampFields>;
+  variance?: Maybe<TransferVarianceFields>;
+};
+
+
+/** aggregate fields of "transfer" */
+export type TransferAggregateFieldsCountArgs = {
+  columns?: InputMaybe<Array<TransferSelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+};
+
+/** order by aggregate values of table "transfer" */
+export type TransferAggregateOrderBy = {
+  avg?: InputMaybe<TransferAvgOrderBy>;
+  count?: InputMaybe<OrderBy>;
+  max?: InputMaybe<TransferMaxOrderBy>;
+  min?: InputMaybe<TransferMinOrderBy>;
+  stddev?: InputMaybe<TransferStddevOrderBy>;
+  stddevPop?: InputMaybe<TransferStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<TransferStddevSampOrderBy>;
+  sum?: InputMaybe<TransferSumOrderBy>;
+  varPop?: InputMaybe<TransferVarPopOrderBy>;
+  varSamp?: InputMaybe<TransferVarSampOrderBy>;
+  variance?: InputMaybe<TransferVarianceOrderBy>;
+};
+
+/** aggregate avg on columns */
+export type TransferAvgFields = {
+  __typename?: 'TransferAvgFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by avg() on columns of table "transfer" */
+export type TransferAvgOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** Boolean expression to filter rows from the table "transfer". All fields are combined with a logical 'AND'. */
+export type TransferBoolExp = {
+  _and?: InputMaybe<Array<TransferBoolExp>>;
+  _not?: InputMaybe<TransferBoolExp>;
+  _or?: InputMaybe<Array<TransferBoolExp>>;
+  amount?: InputMaybe<NumericComparisonExp>;
+  blockNumber?: InputMaybe<IntComparisonExp>;
+  comment?: InputMaybe<TxCommentBoolExp>;
+  commentId?: InputMaybe<StringComparisonExp>;
+  event?: InputMaybe<EventBoolExp>;
+  eventId?: InputMaybe<StringComparisonExp>;
+  from?: InputMaybe<AccountBoolExp>;
+  fromId?: InputMaybe<StringComparisonExp>;
+  id?: InputMaybe<StringComparisonExp>;
+  timestamp?: InputMaybe<TimestamptzComparisonExp>;
+  to?: InputMaybe<AccountBoolExp>;
+  toId?: InputMaybe<StringComparisonExp>;
+};
+
+/** A Relay connection object on "transfer" */
+export type TransferConnection = {
+  __typename?: 'TransferConnection';
+  edges: Array<TransferEdge>;
+  pageInfo: PageInfo;
+};
+
+export type TransferEdge = {
+  __typename?: 'TransferEdge';
+  cursor: Scalars['String']['output'];
+  node: Transfer;
+};
+
+/** aggregate max on columns */
+export type TransferMaxFields = {
+  __typename?: 'TransferMaxFields';
+  amount?: Maybe<Scalars['numeric']['output']>;
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+  commentId?: Maybe<Scalars['String']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  fromId?: Maybe<Scalars['String']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  timestamp?: Maybe<Scalars['timestamptz']['output']>;
+  toId?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by max() on columns of table "transfer" */
+export type TransferMaxOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+  commentId?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  fromId?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  timestamp?: InputMaybe<OrderBy>;
+  toId?: InputMaybe<OrderBy>;
+};
+
+/** aggregate min on columns */
+export type TransferMinFields = {
+  __typename?: 'TransferMinFields';
+  amount?: Maybe<Scalars['numeric']['output']>;
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+  commentId?: Maybe<Scalars['String']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  fromId?: Maybe<Scalars['String']['output']>;
+  id?: Maybe<Scalars['String']['output']>;
+  timestamp?: Maybe<Scalars['timestamptz']['output']>;
+  toId?: Maybe<Scalars['String']['output']>;
+};
+
+/** order by min() on columns of table "transfer" */
+export type TransferMinOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+  commentId?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  fromId?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  timestamp?: InputMaybe<OrderBy>;
+  toId?: InputMaybe<OrderBy>;
+};
+
+/** Ordering options when selecting data from "transfer". */
+export type TransferOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+  comment?: InputMaybe<TxCommentOrderBy>;
+  commentId?: InputMaybe<OrderBy>;
+  event?: InputMaybe<EventOrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  from?: InputMaybe<AccountOrderBy>;
+  fromId?: InputMaybe<OrderBy>;
+  id?: InputMaybe<OrderBy>;
+  timestamp?: InputMaybe<OrderBy>;
+  to?: InputMaybe<AccountOrderBy>;
+  toId?: InputMaybe<OrderBy>;
+};
+
+/** select columns of table "transfer" */
+export enum TransferSelectColumn {
+  /** column name */
+  Amount = 'amount',
+  /** column name */
+  BlockNumber = 'blockNumber',
+  /** column name */
+  CommentId = 'commentId',
+  /** column name */
+  EventId = 'eventId',
+  /** column name */
+  FromId = 'fromId',
+  /** column name */
+  Id = 'id',
+  /** column name */
+  Timestamp = 'timestamp',
+  /** column name */
+  ToId = 'toId'
+}
+
+/** aggregate stddev on columns */
+export type TransferStddevFields = {
+  __typename?: 'TransferStddevFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddev() on columns of table "transfer" */
+export type TransferStddevOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevPop on columns */
+export type TransferStddevPopFields = {
+  __typename?: 'TransferStddevPopFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevPop() on columns of table "transfer" */
+export type TransferStddevPopOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate stddevSamp on columns */
+export type TransferStddevSampFields = {
+  __typename?: 'TransferStddevSampFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by stddevSamp() on columns of table "transfer" */
+export type TransferStddevSampOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate sum on columns */
+export type TransferSumFields = {
+  __typename?: 'TransferSumFields';
+  amount?: Maybe<Scalars['numeric']['output']>;
+  blockNumber?: Maybe<Scalars['Int']['output']>;
+};
+
+/** order by sum() on columns of table "transfer" */
+export type TransferSumOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varPop on columns */
+export type TransferVarPopFields = {
+  __typename?: 'TransferVarPopFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varPop() on columns of table "transfer" */
+export type TransferVarPopOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate varSamp on columns */
+export type TransferVarSampFields = {
+  __typename?: 'TransferVarSampFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by varSamp() on columns of table "transfer" */
+export type TransferVarSampOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** aggregate variance on columns */
+export type TransferVarianceFields = {
+  __typename?: 'TransferVarianceFields';
+  amount?: Maybe<Scalars['Float']['output']>;
+  blockNumber?: Maybe<Scalars['Float']['output']>;
+};
+
+/** order by variance() on columns of table "transfer" */
+export type TransferVarianceOrderBy = {
+  amount?: InputMaybe<OrderBy>;
+  blockNumber?: InputMaybe<OrderBy>;
+};
+
+/** columns and relationships of "tx_comment" */
+export type TxComment = Node & {
+  __typename?: 'TxComment';
+  /** An object relationship */
+  author?: Maybe<Account>;
+  authorId?: Maybe<Scalars['String']['output']>;
+  blockNumber: Scalars['Int']['output'];
+  /** An object relationship */
+  event?: Maybe<Event>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  hash: Scalars['String']['output'];
+  id: Scalars['ID']['output'];
+  remark: Scalars['String']['output'];
+  remarkBytes: Scalars['bytea']['output'];
+  type?: Maybe<CommentTypeEnum>;
+};
+
+/** aggregated selection of "tx_comment" */
+export type TxCommentAggregate = {
+  __typename?: 'TxCommentAggregate';
+  aggregate?: Maybe<TxCommentAggregateFields>;
+  nodes: Array<TxComment>;
+};
+
+export type TxCommentAggregateBoolExp = {
+  count?: InputMaybe<TxCommentAggregateBoolExpCount>;
+};
+
+/** aggregate fields of "tx_comment" */
+export type TxCommentAggregateFields = {
+  __typename?: 'TxCommentAggregateFields';
+  avg?: Maybe<TxCommentAvgFields>;
+  count: Scalars['Int']['output'];
+  max?: Maybe<TxCommentMaxFields>;
+  min?: Maybe<TxCommentMinFields>;
+  stddev?: Maybe<TxCommentStddevFields>;
+  stddevPop?: Maybe<TxCommentStddevPopFields>;
+  stddevSamp?: Maybe<TxCommentStddevSampFields>;
+  sum?: Maybe<TxCommentSumFields>;
+  varPop?: Maybe<TxCommentVarPopFields>;
+  varSamp?: Maybe<TxCommentVarSampFields>;
+  variance?: Maybe<TxCommentVarianceFields>;
+};
+
+
+/** aggregate fields of "tx_comment" */
+export type TxCommentAggregateFieldsCountArgs = {
+  columns?: InputMaybe<Array<TxCommentSelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+};
+
+/** order by aggregate values of table "tx_comment" */
+export type TxCommentAggregateOrderBy = {
+  avg?: InputMaybe<TxCommentAvgOrderBy>;
+  count?: InputMaybe<OrderBy>;
+  max?: InputMaybe<TxCommentMaxOrderBy>;
+  min?: InputMaybe<TxCommentMinOrderBy>;
+  stddev?: InputMaybe<TxCommentStddevOrderBy>;
+  stddevPop?: InputMaybe<TxCommentStddevPopOrderBy>;
+  stddevSamp?: InputMaybe<TxCommentStddevSampOrderBy>;
+  sum?: InputMaybe<TxCommentSumOrderBy>;
+  varPop?: InputMaybe<TxCommentVarPopOrderBy>;
+  varSamp?: InputMaybe<TxCommentVarSampOrderBy>;
+  variance?: InputMaybe<TxCommentVarianceOrderBy>;
 };
 
 /** aggregate avg on columns */
-export type TransferAvgFields = {
-  __typename?: 'TransferAvgFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentAvgFields = {
+  __typename?: 'TxCommentAvgFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by avg() on columns of table "transfer" */
-export type TransferAvgOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by avg() on columns of table "tx_comment" */
+export type TxCommentAvgOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
-/** Boolean expression to filter rows from the table "transfer". All fields are combined with a logical 'AND'. */
-export type TransferBoolExp = {
-  _and?: InputMaybe<Array<TransferBoolExp>>;
-  _not?: InputMaybe<TransferBoolExp>;
-  _or?: InputMaybe<Array<TransferBoolExp>>;
-  amount?: InputMaybe<NumericComparisonExp>;
+/** Boolean expression to filter rows from the table "tx_comment". All fields are combined with a logical 'AND'. */
+export type TxCommentBoolExp = {
+  _and?: InputMaybe<Array<TxCommentBoolExp>>;
+  _not?: InputMaybe<TxCommentBoolExp>;
+  _or?: InputMaybe<Array<TxCommentBoolExp>>;
+  author?: InputMaybe<AccountBoolExp>;
+  authorId?: InputMaybe<StringComparisonExp>;
   blockNumber?: InputMaybe<IntComparisonExp>;
-  comment?: InputMaybe<StringComparisonExp>;
-  from?: InputMaybe<AccountBoolExp>;
-  fromId?: InputMaybe<StringComparisonExp>;
+  event?: InputMaybe<EventBoolExp>;
+  eventId?: InputMaybe<StringComparisonExp>;
+  hash?: InputMaybe<StringComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
-  timestamp?: InputMaybe<TimestamptzComparisonExp>;
-  to?: InputMaybe<AccountBoolExp>;
-  toId?: InputMaybe<StringComparisonExp>;
+  remark?: InputMaybe<StringComparisonExp>;
+  remarkBytes?: InputMaybe<ByteaComparisonExp>;
+  type?: InputMaybe<CommentTypeEnumComparisonExp>;
 };
 
-/** A Relay connection object on "transfer" */
-export type TransferConnection = {
-  __typename?: 'TransferConnection';
-  edges: Array<TransferEdge>;
+/** A Relay connection object on "tx_comment" */
+export type TxCommentConnection = {
+  __typename?: 'TxCommentConnection';
+  edges: Array<TxCommentEdge>;
   pageInfo: PageInfo;
 };
 
-export type TransferEdge = {
-  __typename?: 'TransferEdge';
+export type TxCommentEdge = {
+  __typename?: 'TxCommentEdge';
   cursor: Scalars['String']['output'];
-  node: Transfer;
+  node: TxComment;
 };
 
 /** aggregate max on columns */
-export type TransferMaxFields = {
-  __typename?: 'TransferMaxFields';
-  amount?: Maybe<Scalars['numeric']['output']>;
+export type TxCommentMaxFields = {
+  __typename?: 'TxCommentMaxFields';
+  authorId?: Maybe<Scalars['String']['output']>;
   blockNumber?: Maybe<Scalars['Int']['output']>;
-  comment?: Maybe<Scalars['String']['output']>;
-  fromId?: Maybe<Scalars['String']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  hash?: Maybe<Scalars['String']['output']>;
   id?: Maybe<Scalars['String']['output']>;
-  timestamp?: Maybe<Scalars['timestamptz']['output']>;
-  toId?: Maybe<Scalars['String']['output']>;
+  remark?: Maybe<Scalars['String']['output']>;
 };
 
-/** order by max() on columns of table "transfer" */
-export type TransferMaxOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by max() on columns of table "tx_comment" */
+export type TxCommentMaxOrderBy = {
+  authorId?: InputMaybe<OrderBy>;
   blockNumber?: InputMaybe<OrderBy>;
-  comment?: InputMaybe<OrderBy>;
-  fromId?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  hash?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
-  timestamp?: InputMaybe<OrderBy>;
-  toId?: InputMaybe<OrderBy>;
+  remark?: InputMaybe<OrderBy>;
 };
 
 /** aggregate min on columns */
-export type TransferMinFields = {
-  __typename?: 'TransferMinFields';
-  amount?: Maybe<Scalars['numeric']['output']>;
+export type TxCommentMinFields = {
+  __typename?: 'TxCommentMinFields';
+  authorId?: Maybe<Scalars['String']['output']>;
   blockNumber?: Maybe<Scalars['Int']['output']>;
-  comment?: Maybe<Scalars['String']['output']>;
-  fromId?: Maybe<Scalars['String']['output']>;
+  eventId?: Maybe<Scalars['String']['output']>;
+  hash?: Maybe<Scalars['String']['output']>;
   id?: Maybe<Scalars['String']['output']>;
-  timestamp?: Maybe<Scalars['timestamptz']['output']>;
-  toId?: Maybe<Scalars['String']['output']>;
+  remark?: Maybe<Scalars['String']['output']>;
 };
 
-/** order by min() on columns of table "transfer" */
-export type TransferMinOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by min() on columns of table "tx_comment" */
+export type TxCommentMinOrderBy = {
+  authorId?: InputMaybe<OrderBy>;
   blockNumber?: InputMaybe<OrderBy>;
-  comment?: InputMaybe<OrderBy>;
-  fromId?: InputMaybe<OrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  hash?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
-  timestamp?: InputMaybe<OrderBy>;
-  toId?: InputMaybe<OrderBy>;
+  remark?: InputMaybe<OrderBy>;
 };
 
-/** Ordering options when selecting data from "transfer". */
-export type TransferOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** Ordering options when selecting data from "tx_comment". */
+export type TxCommentOrderBy = {
+  author?: InputMaybe<AccountOrderBy>;
+  authorId?: InputMaybe<OrderBy>;
   blockNumber?: InputMaybe<OrderBy>;
-  comment?: InputMaybe<OrderBy>;
-  from?: InputMaybe<AccountOrderBy>;
-  fromId?: InputMaybe<OrderBy>;
+  event?: InputMaybe<EventOrderBy>;
+  eventId?: InputMaybe<OrderBy>;
+  hash?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
-  timestamp?: InputMaybe<OrderBy>;
-  to?: InputMaybe<AccountOrderBy>;
-  toId?: InputMaybe<OrderBy>;
+  remark?: InputMaybe<OrderBy>;
+  remarkBytes?: InputMaybe<OrderBy>;
+  type?: InputMaybe<OrderBy>;
 };
 
-/** select columns of table "transfer" */
-export enum TransferSelectColumn {
+/** select columns of table "tx_comment" */
+export enum TxCommentSelectColumn {
   /** column name */
-  Amount = 'amount',
+  AuthorId = 'authorId',
   /** column name */
   BlockNumber = 'blockNumber',
   /** column name */
-  Comment = 'comment',
+  EventId = 'eventId',
   /** column name */
-  FromId = 'fromId',
+  Hash = 'hash',
   /** column name */
   Id = 'id',
   /** column name */
-  Timestamp = 'timestamp',
+  Remark = 'remark',
   /** column name */
-  ToId = 'toId'
+  RemarkBytes = 'remarkBytes',
+  /** column name */
+  Type = 'type'
 }
 
 /** aggregate stddev on columns */
-export type TransferStddevFields = {
-  __typename?: 'TransferStddevFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentStddevFields = {
+  __typename?: 'TxCommentStddevFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by stddev() on columns of table "transfer" */
-export type TransferStddevOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by stddev() on columns of table "tx_comment" */
+export type TxCommentStddevOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate stddevPop on columns */
-export type TransferStddevPopFields = {
-  __typename?: 'TransferStddevPopFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentStddevPopFields = {
+  __typename?: 'TxCommentStddevPopFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by stddevPop() on columns of table "transfer" */
-export type TransferStddevPopOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by stddevPop() on columns of table "tx_comment" */
+export type TxCommentStddevPopOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate stddevSamp on columns */
-export type TransferStddevSampFields = {
-  __typename?: 'TransferStddevSampFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentStddevSampFields = {
+  __typename?: 'TxCommentStddevSampFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by stddevSamp() on columns of table "transfer" */
-export type TransferStddevSampOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by stddevSamp() on columns of table "tx_comment" */
+export type TxCommentStddevSampOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate sum on columns */
-export type TransferSumFields = {
-  __typename?: 'TransferSumFields';
-  amount?: Maybe<Scalars['numeric']['output']>;
+export type TxCommentSumFields = {
+  __typename?: 'TxCommentSumFields';
   blockNumber?: Maybe<Scalars['Int']['output']>;
 };
 
-/** order by sum() on columns of table "transfer" */
-export type TransferSumOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by sum() on columns of table "tx_comment" */
+export type TxCommentSumOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate varPop on columns */
-export type TransferVarPopFields = {
-  __typename?: 'TransferVarPopFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentVarPopFields = {
+  __typename?: 'TxCommentVarPopFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by varPop() on columns of table "transfer" */
-export type TransferVarPopOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by varPop() on columns of table "tx_comment" */
+export type TxCommentVarPopOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate varSamp on columns */
-export type TransferVarSampFields = {
-  __typename?: 'TransferVarSampFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentVarSampFields = {
+  __typename?: 'TxCommentVarSampFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by varSamp() on columns of table "transfer" */
-export type TransferVarSampOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by varSamp() on columns of table "tx_comment" */
+export type TxCommentVarSampOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** aggregate variance on columns */
-export type TransferVarianceFields = {
-  __typename?: 'TransferVarianceFields';
-  amount?: Maybe<Scalars['Float']['output']>;
+export type TxCommentVarianceFields = {
+  __typename?: 'TxCommentVarianceFields';
   blockNumber?: Maybe<Scalars['Float']['output']>;
 };
 
-/** order by variance() on columns of table "transfer" */
-export type TransferVarianceOrderBy = {
-  amount?: InputMaybe<OrderBy>;
+/** order by variance() on columns of table "tx_comment" */
+export type TxCommentVarianceOrderBy = {
   blockNumber?: InputMaybe<OrderBy>;
 };
 
 /** columns and relationships of "ud_history" */
 export type UdHistory = Node & {
   __typename?: 'UdHistory';
-  amount: Scalars['Int']['output'];
+  amount: Scalars['numeric']['output'];
   blockNumber: Scalars['Int']['output'];
   id: Scalars['ID']['output'];
   /** An object relationship */
@@ -3858,7 +5124,7 @@ export type UdHistoryBoolExp = {
   _and?: InputMaybe<Array<UdHistoryBoolExp>>;
   _not?: InputMaybe<UdHistoryBoolExp>;
   _or?: InputMaybe<Array<UdHistoryBoolExp>>;
-  amount?: InputMaybe<IntComparisonExp>;
+  amount?: InputMaybe<NumericComparisonExp>;
   blockNumber?: InputMaybe<IntComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
   identity?: InputMaybe<IdentityBoolExp>;
@@ -3973,8 +5239,9 @@ export type UdReeval = Node & {
   id: Scalars['ID']['output'];
   membersCount: Scalars['Int']['output'];
   monetaryMass: Scalars['numeric']['output'];
-  newUdAmount: Scalars['Int']['output'];
+  newUdAmount: Scalars['numeric']['output'];
   timestamp: Scalars['timestamptz']['output'];
+  udIndex: Scalars['Int']['output'];
 };
 
 /** Boolean expression to filter rows from the table "ud_reeval". All fields are combined with a logical 'AND'. */
@@ -3988,8 +5255,9 @@ export type UdReevalBoolExp = {
   id?: InputMaybe<StringComparisonExp>;
   membersCount?: InputMaybe<IntComparisonExp>;
   monetaryMass?: InputMaybe<NumericComparisonExp>;
-  newUdAmount?: InputMaybe<IntComparisonExp>;
+  newUdAmount?: InputMaybe<NumericComparisonExp>;
   timestamp?: InputMaybe<TimestamptzComparisonExp>;
+  udIndex?: InputMaybe<IntComparisonExp>;
 };
 
 /** A Relay connection object on "ud_reeval" */
@@ -4015,6 +5283,7 @@ export type UdReevalOrderBy = {
   monetaryMass?: InputMaybe<OrderBy>;
   newUdAmount?: InputMaybe<OrderBy>;
   timestamp?: InputMaybe<OrderBy>;
+  udIndex?: InputMaybe<OrderBy>;
 };
 
 /** select columns of table "ud_reeval" */
@@ -4032,18 +5301,21 @@ export enum UdReevalSelectColumn {
   /** column name */
   NewUdAmount = 'newUdAmount',
   /** column name */
-  Timestamp = 'timestamp'
+  Timestamp = 'timestamp',
+  /** column name */
+  UdIndex = 'udIndex'
 }
 
 /** columns and relationships of "universal_dividend" */
 export type UniversalDividend = Node & {
   __typename?: 'UniversalDividend';
-  amount: Scalars['Int']['output'];
+  amount: Scalars['numeric']['output'];
   blockNumber: Scalars['Int']['output'];
   /** An object relationship */
   event?: Maybe<Event>;
   eventId?: Maybe<Scalars['String']['output']>;
   id: Scalars['ID']['output'];
+  index: Scalars['Int']['output'];
   membersCount: Scalars['Int']['output'];
   monetaryMass: Scalars['numeric']['output'];
   timestamp: Scalars['timestamptz']['output'];
@@ -4054,11 +5326,12 @@ export type UniversalDividendBoolExp = {
   _and?: InputMaybe<Array<UniversalDividendBoolExp>>;
   _not?: InputMaybe<UniversalDividendBoolExp>;
   _or?: InputMaybe<Array<UniversalDividendBoolExp>>;
-  amount?: InputMaybe<IntComparisonExp>;
+  amount?: InputMaybe<NumericComparisonExp>;
   blockNumber?: InputMaybe<IntComparisonExp>;
   event?: InputMaybe<EventBoolExp>;
   eventId?: InputMaybe<StringComparisonExp>;
   id?: InputMaybe<StringComparisonExp>;
+  index?: InputMaybe<IntComparisonExp>;
   membersCount?: InputMaybe<IntComparisonExp>;
   monetaryMass?: InputMaybe<NumericComparisonExp>;
   timestamp?: InputMaybe<TimestamptzComparisonExp>;
@@ -4084,6 +5357,7 @@ export type UniversalDividendOrderBy = {
   event?: InputMaybe<EventOrderBy>;
   eventId?: InputMaybe<OrderBy>;
   id?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
   membersCount?: InputMaybe<OrderBy>;
   monetaryMass?: InputMaybe<OrderBy>;
   timestamp?: InputMaybe<OrderBy>;
@@ -4100,6 +5374,8 @@ export enum UniversalDividendSelectColumn {
   /** column name */
   Id = 'id',
   /** column name */
+  Index = 'index',
+  /** column name */
   MembersCount = 'membersCount',
   /** column name */
   MonetaryMass = 'monetaryMass',
@@ -4107,6 +5383,63 @@ export enum UniversalDividendSelectColumn {
   Timestamp = 'timestamp'
 }
 
+/** columns and relationships of "validator" */
+export type Validator = Node & {
+  __typename?: 'Validator';
+  id: Scalars['ID']['output'];
+  index: Scalars['Int']['output'];
+};
+
+/** Boolean expression to filter rows from the table "validator". All fields are combined with a logical 'AND'. */
+export type ValidatorBoolExp = {
+  _and?: InputMaybe<Array<ValidatorBoolExp>>;
+  _not?: InputMaybe<ValidatorBoolExp>;
+  _or?: InputMaybe<Array<ValidatorBoolExp>>;
+  id?: InputMaybe<StringComparisonExp>;
+  index?: InputMaybe<IntComparisonExp>;
+};
+
+/** A Relay connection object on "validator" */
+export type ValidatorConnection = {
+  __typename?: 'ValidatorConnection';
+  edges: Array<ValidatorEdge>;
+  pageInfo: PageInfo;
+};
+
+export type ValidatorEdge = {
+  __typename?: 'ValidatorEdge';
+  cursor: Scalars['String']['output'];
+  node: Validator;
+};
+
+/** Ordering options when selecting data from "validator". */
+export type ValidatorOrderBy = {
+  id?: InputMaybe<OrderBy>;
+  index?: InputMaybe<OrderBy>;
+};
+
+/** select columns of table "validator" */
+export enum ValidatorSelectColumn {
+  /** column name */
+  Id = 'id',
+  /** column name */
+  Index = 'index'
+}
+
+export type AccountAggregateBoolExpBool_And = {
+  arguments: AccountSelectColumnAccountAggregateBoolExpBool_AndArgumentsColumns;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<AccountBoolExp>;
+  predicate: BooleanComparisonExp;
+};
+
+export type AccountAggregateBoolExpBool_Or = {
+  arguments: AccountSelectColumnAccountAggregateBoolExpBool_OrArgumentsColumns;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<AccountBoolExp>;
+  predicate: BooleanComparisonExp;
+};
+
 export type AccountAggregateBoolExpCount = {
   arguments?: InputMaybe<Array<AccountSelectColumn>>;
   distinct?: InputMaybe<Scalars['Boolean']['input']>;
@@ -4202,6 +5535,27 @@ export type GetUdHistoryArgs = {
   identity_row?: InputMaybe<Scalars['identity_scalar']['input']>;
 };
 
+export type IdentityAggregateBoolExpBool_And = {
+  arguments: IdentitySelectColumnIdentityAggregateBoolExpBool_AndArgumentsColumns;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<IdentityBoolExp>;
+  predicate: BooleanComparisonExp;
+};
+
+export type IdentityAggregateBoolExpBool_Or = {
+  arguments: IdentitySelectColumnIdentityAggregateBoolExpBool_OrArgumentsColumns;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<IdentityBoolExp>;
+  predicate: BooleanComparisonExp;
+};
+
+export type IdentityAggregateBoolExpCount = {
+  arguments?: InputMaybe<Array<IdentitySelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<IdentityBoolExp>;
+  predicate: IntComparisonExp;
+};
+
 export type MembershipEventAggregateBoolExpCount = {
   arguments?: InputMaybe<Array<MembershipEventSelectColumn>>;
   distinct?: InputMaybe<Scalars['Boolean']['input']>;
@@ -4236,16 +5590,26 @@ export type Query_Root = {
   /** fetch data from the table: "membership_event" */
   membershipEventConnection: MembershipEventConnection;
   node?: Maybe<Node>;
+  /** fetch data from the table: "population_history" */
+  populationHistoryConnection: PopulationHistoryConnection;
   /** fetch data from the table: "smith_cert" */
   smithCertConnection: SmithCertConnection;
+  /** fetch data from the table: "smith" */
+  smithConnection: SmithConnection;
+  /** fetch data from the table: "smith_event" */
+  smithEventConnection: SmithEventConnection;
   /** fetch data from the table: "transfer" */
   transferConnection: TransferConnection;
+  /** fetch data from the table: "tx_comment" */
+  txCommentConnection: TxCommentConnection;
   /** fetch data from the table: "ud_history" */
   udHistoryConnection: UdHistoryConnection;
   /** fetch data from the table: "ud_reeval" */
   udReevalConnection: UdReevalConnection;
   /** fetch data from the table: "universal_dividend" */
   universalDividendConnection: UniversalDividendConnection;
+  /** fetch data from the table: "validator" */
+  validatorConnection: ValidatorConnection;
 };
 
 
@@ -4387,6 +5751,17 @@ export type Query_RootNodeArgs = {
 };
 
 
+export type Query_RootPopulationHistoryConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<PopulationHistorySelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<PopulationHistoryOrderBy>>;
+  where?: InputMaybe<PopulationHistoryBoolExp>;
+};
+
+
 export type Query_RootSmithCertConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4398,6 +5773,28 @@ export type Query_RootSmithCertConnectionArgs = {
 };
 
 
+export type Query_RootSmithConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithOrderBy>>;
+  where?: InputMaybe<SmithBoolExp>;
+};
+
+
+export type Query_RootSmithEventConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithEventSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithEventOrderBy>>;
+  where?: InputMaybe<SmithEventBoolExp>;
+};
+
+
 export type Query_RootTransferConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4409,6 +5806,17 @@ export type Query_RootTransferConnectionArgs = {
 };
 
 
+export type Query_RootTxCommentConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<TxCommentSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<TxCommentOrderBy>>;
+  where?: InputMaybe<TxCommentBoolExp>;
+};
+
+
 export type Query_RootUdHistoryConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4441,6 +5849,17 @@ export type Query_RootUniversalDividendConnectionArgs = {
   where?: InputMaybe<UniversalDividendBoolExp>;
 };
 
+
+export type Query_RootValidatorConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<ValidatorSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<ValidatorOrderBy>>;
+  where?: InputMaybe<ValidatorBoolExp>;
+};
+
 export type SmithCertAggregateBoolExpCount = {
   arguments?: InputMaybe<Array<SmithCertSelectColumn>>;
   distinct?: InputMaybe<Scalars['Boolean']['input']>;
@@ -4448,6 +5867,13 @@ export type SmithCertAggregateBoolExpCount = {
   predicate: IntComparisonExp;
 };
 
+export type SmithEventAggregateBoolExpCount = {
+  arguments?: InputMaybe<Array<SmithEventSelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<SmithEventBoolExp>;
+  predicate: IntComparisonExp;
+};
+
 export type Subscription_Root = {
   __typename?: 'subscription_root';
   /** fetch data from the table: "account" */
@@ -4475,16 +5901,26 @@ export type Subscription_Root = {
   /** fetch data from the table: "membership_event" */
   membershipEventConnection: MembershipEventConnection;
   node?: Maybe<Node>;
+  /** fetch data from the table: "population_history" */
+  populationHistoryConnection: PopulationHistoryConnection;
   /** fetch data from the table: "smith_cert" */
   smithCertConnection: SmithCertConnection;
+  /** fetch data from the table: "smith" */
+  smithConnection: SmithConnection;
+  /** fetch data from the table: "smith_event" */
+  smithEventConnection: SmithEventConnection;
   /** fetch data from the table: "transfer" */
   transferConnection: TransferConnection;
+  /** fetch data from the table: "tx_comment" */
+  txCommentConnection: TxCommentConnection;
   /** fetch data from the table: "ud_history" */
   udHistoryConnection: UdHistoryConnection;
   /** fetch data from the table: "ud_reeval" */
   udReevalConnection: UdReevalConnection;
   /** fetch data from the table: "universal_dividend" */
   universalDividendConnection: UniversalDividendConnection;
+  /** fetch data from the table: "validator" */
+  validatorConnection: ValidatorConnection;
 };
 
 
@@ -4626,6 +6062,17 @@ export type Subscription_RootNodeArgs = {
 };
 
 
+export type Subscription_RootPopulationHistoryConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<PopulationHistorySelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<PopulationHistoryOrderBy>>;
+  where?: InputMaybe<PopulationHistoryBoolExp>;
+};
+
+
 export type Subscription_RootSmithCertConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4637,6 +6084,28 @@ export type Subscription_RootSmithCertConnectionArgs = {
 };
 
 
+export type Subscription_RootSmithConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithOrderBy>>;
+  where?: InputMaybe<SmithBoolExp>;
+};
+
+
+export type Subscription_RootSmithEventConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<SmithEventSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<SmithEventOrderBy>>;
+  where?: InputMaybe<SmithEventBoolExp>;
+};
+
+
 export type Subscription_RootTransferConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4648,6 +6117,17 @@ export type Subscription_RootTransferConnectionArgs = {
 };
 
 
+export type Subscription_RootTxCommentConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<TxCommentSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<TxCommentOrderBy>>;
+  where?: InputMaybe<TxCommentBoolExp>;
+};
+
+
 export type Subscription_RootUdHistoryConnectionArgs = {
   after?: InputMaybe<Scalars['String']['input']>;
   before?: InputMaybe<Scalars['String']['input']>;
@@ -4680,6 +6160,17 @@ export type Subscription_RootUniversalDividendConnectionArgs = {
   where?: InputMaybe<UniversalDividendBoolExp>;
 };
 
+
+export type Subscription_RootValidatorConnectionArgs = {
+  after?: InputMaybe<Scalars['String']['input']>;
+  before?: InputMaybe<Scalars['String']['input']>;
+  distinctOn?: InputMaybe<Array<ValidatorSelectColumn>>;
+  first?: InputMaybe<Scalars['Int']['input']>;
+  last?: InputMaybe<Scalars['Int']['input']>;
+  orderBy?: InputMaybe<Array<ValidatorOrderBy>>;
+  where?: InputMaybe<ValidatorBoolExp>;
+};
+
 export type TransferAggregateBoolExpCount = {
   arguments?: InputMaybe<Array<TransferSelectColumn>>;
   distinct?: InputMaybe<Scalars['Boolean']['input']>;
@@ -4687,6 +6178,13 @@ export type TransferAggregateBoolExpCount = {
   predicate: IntComparisonExp;
 };
 
+export type TxCommentAggregateBoolExpCount = {
+  arguments?: InputMaybe<Array<TxCommentSelectColumn>>;
+  distinct?: InputMaybe<Scalars['Boolean']['input']>;
+  filter?: InputMaybe<TxCommentBoolExp>;
+  predicate: IntComparisonExp;
+};
+
 export type LightIdentityFragment = { __typename?: 'Identity', id: string, index: number, name: string, accountId?: string | null, status?: IdentityStatusEnum | null, isMember: boolean, createdOn: number, membershipHistory: Array<{ __typename: 'MembershipEvent', id: string, eventType?: EventTypeEnum | null }> };
 
 export type LightAccountFragment = { __typename?: 'Account', id: string, identity?: { __typename?: 'Identity', id: string, index: number, name: string, accountId?: string | null, status?: IdentityStatusEnum | null, isMember: boolean, createdOn: number, membershipHistory: Array<{ __typename: 'MembershipEvent', id: string, eventType?: EventTypeEnum | null }> } | null };
@@ -5384,11 +6882,16 @@ export const WotSearchByUidDocument = gql`
       "Identity",
       "ItemsCounter",
       "MembershipEvent",
+      "PopulationHistory",
+      "Smith",
       "SmithCert",
+      "SmithEvent",
       "Transfer",
+      "TxComment",
       "UdHistory",
       "UdReeval",
-      "UniversalDividend"
+      "UniversalDividend",
+      "Validator"
     ]
   }
 };
diff --git a/src/app/network/indexer/indexer.service.ts b/src/app/network/indexer/indexer.service.ts
index 7ea83d4fe535bdb4294c04f81e451bb3d2b86a37..7d4a989a9b541eb4e38b0e2a2abc91a80119a53d 100644
--- a/src/app/network/indexer/indexer.service.ts
+++ b/src/app/network/indexer/indexer.service.ts
@@ -23,8 +23,7 @@ import {
   TransferFragment,
   UniversalDividendConnection,
 } from './indexer-types.generated';
-import { firstValueFrom, mergeMap, Observable } from 'rxjs';
-import { filter, map } from 'rxjs/operators';
+import { filter, firstValueFrom, map, mergeMap, Observable } from 'rxjs';
 import { Transfer, TransferConverter, TransferSearchFilter } from '@app/transfer/transfer.model';
 import { WotSearchFilter } from '@app/wot/wot.model';
 import { Block, BlockConverter, BlockSearchFilter } from '@app/block/block.model';
@@ -339,17 +338,28 @@ export class IndexerService extends GraphqlService<IndexerState> {
     // Wait settings and storage
     const [settings, currency] = await Promise.all([this.settings.ready(), firstNotNilPromise(this.currency$)]);
 
+    let isPeerAlive: boolean;
     let peer = Peers.fromUri(settings.indexer);
-    if (!peer) {
-      const peers = await this.filterAlivePeers(settings.preferredIndexers);
-      if (!peers.length) {
+
+    if (isNil(peer)) {
+      isPeerAlive = false;
+    } else {
+      isPeerAlive = await this.isPeerAlive(peer);
+    }
+
+    if (!peer || !isPeerAlive) {
+      const preferredFiltered = settings.preferredIndexers.filter((preferred) => preferred !== settings.indexer);
+      if (preferredFiltered.length === 0) throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
+
+      const peers = await this.filterAlivePeers(preferredFiltered);
+      if (peers.length === 0) {
         throw { message: 'ERROR.CHECK_NETWORK_CONNECTION' };
       }
       peer = arrayRandomPick(peers);
     }
 
     const client = await super.createClient(peer, 'indexer');
-
+    settings.indexer = Peers.getHttpUri(peer);
     return {
       peer,
       client,
diff --git a/src/app/network/ipfs/ipfs.service.ts b/src/app/network/ipfs/ipfs.service.ts
index dbcfb3b1993f75fec4a0683bf6df51d6c1515cb1..832b3ca1d853a65cc0df0f6f6b8971d8bfca69f6 100644
--- a/src/app/network/ipfs/ipfs.service.ts
+++ b/src/app/network/ipfs/ipfs.service.ts
@@ -7,6 +7,7 @@ import { StorageService } from '@app/shared/services/storage/storage.service';
 import { Observable } from 'rxjs';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
 import { RxStartableService } from '@app/shared/services/rx-startable-service.class';
+import { HttpClient } from '@angular/common/http';
 
 export interface IpfsState {
   peer: Peer;
@@ -22,7 +23,8 @@ export class IpfsService extends RxStartableService<IpfsState> {
 
   constructor(
     storage: StorageService,
-    private settings: SettingsService
+    private settings: SettingsService,
+    private httpClient: HttpClient
   ) {
     super(storage, {
       name: 'ipfs-service',
@@ -41,14 +43,18 @@ export class IpfsService extends RxStartableService<IpfsState> {
     const settings = await this.settings.ready();
 
     let peer = Peers.fromUri(settings.ipfsGateway);
-    if (!peer) {
-      const peers = await this.filterAlivePeers(settings.preferredIpfsGateways || []);
+    const isPeerAlive = await this.isPeerAlive(peer);
+
+    if (!peer || !isPeerAlive) {
+      const preferredFiltered = settings.preferredIpfsGateways.filter((preferred) => preferred !== settings.ipfsGateway);
+      if (preferredFiltered.length === 0) throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
+
+      const peers = await this.filterAlivePeers(settings.preferredPods);
       if (!peers.length) {
-        throw { message: 'ERROR.CHECK_NETWORK_CONNECTION' };
+        throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
       }
       peer = arrayRandomPick(peers);
     }
-
     const gatewayBaseUrl = Peers.getHttpUri(peer) + '/ipfs/';
 
     return {
@@ -58,29 +64,21 @@ export class IpfsService extends RxStartableService<IpfsState> {
     };
   }
 
-  protected async filterAlivePeers(
-    peers: string[],
-    opts?: {
-      timeout?: number;
-    }
-  ): Promise<Peer[]> {
+  protected async filterAlivePeers(peers: string[]): Promise<Peer[]> {
     return (
-      await Promise.all(
-        peers.map((peer) => Peers.fromUri(peer)).map((peer) => this.isPeerAlive(peer, opts).then((alive) => (alive ? peer : undefined)))
-      )
+      await Promise.all(peers.map((peer) => Peers.fromUri(peer)).map((peer) => this.isPeerAlive(peer).then((alive) => (alive ? peer : undefined))))
     ).filter(isNotNil);
   }
 
-  protected async isPeerAlive(
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    peer: Peer,
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    opts?: {
-      timeout?: number;
+  protected async isPeerAlive(peer: Peer): Promise<boolean> {
+    const url = Peers.getHttpUri(peer) + '/api/v0/version';
+
+    try {
+      await this.httpClient.get(url, {}).toPromise();
+      return true;
+    } catch (err) {
+      console.error(`${this._logPrefix}Le pair IPFS n'est pas accessible:`, peer, err);
+      return false;
     }
-  ): Promise<boolean> {
-    // TODO
-    console.log(`${this._logPrefix}TODO: implement ${this.constructor.name}.isPeerAlive()`, peer);
-    return Promise.resolve(true);
   }
 }
diff --git a/src/app/network/network.service.ts b/src/app/network/network.service.ts
index a2fcb75c5c2ce6c2cb18b1fd1151faa1a40531f1..9ec61953c6a724758617372bc89d82d615cf5a3c 100644
--- a/src/app/network/network.service.ts
+++ b/src/app/network/network.service.ts
@@ -6,13 +6,19 @@ 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 { EMPTY, firstValueFrom, mergeMap, Observable, of, race, tap } from 'rxjs';
-import { catchError, filter, map, timeout } from 'rxjs/operators';
-import { arrayRandomPick, isNotNilOrBlank, toNumber } from '@app/shared/functions';
+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 { IndexerService } from './indexer/indexer.service';
 import { fromDateISOString } from '@app/shared/dates';
 import { ContextService } from '@app/shared/services/storage/context.service';
 import { PodService } from '@app/network/pod/pod.service';
+import { HttpClient } from '@angular/common/http';
+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';
 
 export interface NetworkState {
   peer: Peer;
@@ -22,6 +28,13 @@ export interface NetworkState {
   api: ApiPromise;
 }
 
+export interface DistancePrecomputionData {
+  height: number;
+  referees_count: number;
+  min_certs_for_referee: number;
+  results: Map<number, number>;
+}
+
 @Injectable({ providedIn: 'root' })
 export class NetworkService extends RxStartableService<NetworkState> {
   indexer = inject(IndexerService);
@@ -39,7 +52,8 @@ export class NetworkService extends RxStartableService<NetworkState> {
 
   constructor(
     private settings: SettingsService,
-    private context: ContextService
+    private context: ContextService,
+    private http: HttpClient
   ) {
     super(settings, {
       name: 'network-service',
@@ -74,18 +88,30 @@ export class NetworkService extends RxStartableService<NetworkState> {
   protected async ngOnStart(): Promise<NetworkState> {
     const settings = await this.settings.ready();
 
+    let isPeerAlive: boolean;
     let peer = Peers.fromUri(settings.peer);
-    if (!peer) {
+
+    if (isNil(peer)) {
+      isPeerAlive = false;
+    } else {
+      isPeerAlive = await this.isPeerAlive(peer);
+    }
+
+    if (!peer || !isPeerAlive) {
+      const preferredFiltered = settings.preferredPeers.filter((preferred) => preferred !== settings.peer);
+      if (preferredFiltered.length === 0) throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
+
       const peers = await this.filterAlivePeers(settings.preferredPeers);
       if (!peers.length) {
-        throw { message: 'ERROR.CHECK_NETWORK_CONNECTION' };
+        throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
       }
       peer = arrayRandomPick(peers);
     }
-
     const wsUri = Peers.getWsUri(peer);
     console.info(`${this._logPrefix}Connecting to peer {${wsUri}}...`);
 
+    settings.peer = wsUri;
+
     // Extract all types from definitions - fast and dirty approach, flatted on 'types'
     // const types = Object.values(definitions).reduce((res: any, { types }): object => {
     //   return { ...res, ...types };
@@ -139,7 +165,9 @@ export class NetworkService extends RxStartableService<NetworkState> {
       ...WELL_KNOWN_CURRENCIES.GDEV.fees, // TODO use G1 defaults
       ...(currency.fees || {}),
     };
-
+    currency.params = {
+      minAccessibleReferees: toNumber(api.consts.distance.minAccessibleReferees),
+    };
     // Read the genesys block hash
     console.debug(`${this._logPrefix}Chain genesis: ${currency.genesis}`);
 
@@ -152,7 +180,9 @@ export class NetworkService extends RxStartableService<NetworkState> {
     // Configure and start indexer and pod
     this.indexer.currency = currency;
     this.pod.currency = currency;
-    await Promise.all([this.indexer.start(), this.pod.start()]);
+    await Promise.all([this.indexer.start(), this.pod.start()]).catch((err) =>
+      console.error(`${this._logPrefix}Error starting indexer or pod:`, err)
+    );
 
     return {
       api,
@@ -170,23 +200,19 @@ export class NetworkService extends RxStartableService<NetworkState> {
   }
 
   protected async filterAlivePeers(peers: string[]): Promise<Peer[]> {
-    const peerObjects = peers.map((peer) => Peers.fromUri(peer));
-
-    try {
-      // Try to get the first responding peer
-      const firstPeer = await firstValueFrom(race(peerObjects.map((peer) => this.isPeerAlive(peer))));
-      return [firstPeer];
-    } catch {
-      // If no quick response, check all peers
-      console.warn(`${this._logPrefix}No quick response, checking all peers...`);
-      const results = await Promise.all(peerObjects.map((peer) => firstValueFrom(this.isPeerAlive(peer).pipe(catchError(() => of(undefined))))));
-      return results.filter((peer): peer is Peer => !!peer);
-    }
+    return (
+      await Promise.all(peers.map((peer) => Peers.fromUri(peer)).map((peer) => this.isPeerAlive(peer).then((alive) => (alive ? peer : undefined))))
+    ).filter(isNotNil);
   }
-
-  protected isPeerAlive(peer: Peer): Observable<Peer> {
+  protected async isPeerAlive(peer: Peer): Promise<boolean> {
     const timeoutDuration = 4000;
-    return new Observable<Peer>((subscriber) => {
+
+    return new Promise<boolean>((resolve) => {
+      const timeoutId = setTimeout(() => {
+        ws.close();
+        resolve(false);
+      }, timeoutDuration);
+
       const wsUri = Peers.getWsUri(peer);
       const ws = new WebSocket(wsUri);
 
@@ -201,22 +227,169 @@ export class NetworkService extends RxStartableService<NetworkState> {
       };
 
       ws.onmessage = () => {
-        subscriber.next(peer);
-        subscriber.complete();
+        clearTimeout(timeoutId);
         ws.close();
+        resolve(true);
       };
 
       ws.onerror = () => {
-        subscriber.error(new Error('Connection error'));
+        clearTimeout(timeoutId);
         ws.close();
+        resolve(false);
       };
+    });
+  }
 
-      return () => {
-        ws.close();
-      };
-    }).pipe(
-      timeout(timeoutDuration),
-      catchError(() => EMPTY) // Return an empty Observable on error
+  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 getDistancePrecomputionData(urls: string[]) {
+    const source = timer(0, 5 * 60 * 1000);
+    return firstValueFrom(source.pipe(map(() => this.race(urls))));
+  }
+
+  async loadJsonFeed(urls: string[]): Promise<JsonTopic[]> {
+    const topicsPromises = urls.map(async (url) => {
+      let topics: JsonTopic[] = [];
+      try {
+        if (this.isDiscourseCategory(url)) {
+          console.log(`${this._logPrefix}Une catégorie a été détectée dans l'url: ${url}`);
+          topics = await this.getTopicsByCategory(url);
+        } else {
+          topics = await this.getPostByUrl(url);
+        }
+        return topics;
+      } catch (err) {
+        console.error(`${this._logPrefix}`, err);
+      }
+    });
+    const allTopics = await Promise.all(topicsPromises);
+    // Aplatir le tableau en 1 dimension, car chaque URL retourne un tableau de topics
+    return allTopics.flat();
+  }
+
+  protected async getPostByUrl(url: string): Promise<JsonTopic[]> {
+    const maxAgeInMonths = environment.feed.maxAgeInMonths;
+    const minDate = maxAgeInMonths > 0 ? moment().subtract(maxAgeInMonths, 'month').startOf('day').utc() : undefined;
+    const topicId = this.extractTopicIdFromUrl(url);
+    if (!topicId) {
+      console.error(`${this._logPrefix}Invalid URL`);
+      return undefined;
+    }
+    const discourse = new DiscourseAPI(environment.forumUrl);
+    const topic = await discourse.getTopic({ id: topicId.toString() });
+    const posts = topic.post_stream.posts;
+    if (posts.length === 0) {
+      console.error(`${this._logPrefix}Aucun post trouvé dans ce topic.`);
+      return undefined;
+    }
+    const lastPost = posts[posts.length - 1];
+    if (moment(lastPost.created_at).isBefore(minDate)) {
+      console.log(`${this._logPrefix}Le post ne réponds pas la régle de date`);
+      return undefined;
+    }
+    return [this.formatTopics(lastPost, topic, url)];
+  }
+
+  private async getTopicsByCategory(url: string) {
+    console.log(`${this._logPrefix}Une catégorie a été détectée dans l'url: ${url}`);
+
+    const categoryId = this.extractCategoryIdFromUrl(url);
+    const categorySlug = this.extractCategorySlugFromUrl(url);
+    const discourse = new DiscourseAPI(environment.forumUrl);
+    const category = await discourse.listCategoryTopics({ id: categoryId, slug: categorySlug });
+
+    const topics = category.topic_list.topics.filter(
+      (topic: Topic) =>
+        topic.pinned &&
+        topic.visible &&
+        !topic.tags.includes('about-category') &&
+        this.getLanguageFromTitle(topic.fancy_title) != this.settings.locale
     );
+    return Promise.all(
+      topics.map(async (t) => {
+        const topic = await discourse.getTopic({ id: t.id.toString() });
+        const posts = topic.post_stream.posts;
+        if (posts.length === 0) {
+          console.error(`${this._logPrefix}Aucun post trouvé dans ce topic.`);
+          return undefined;
+        }
+        return this.formatTopics(posts[0], topic, url);
+      })
+    );
+  }
+
+  protected formatTopics(post, topic, url: string) {
+    const feedItem = this.prepareFeedItem(post, topic);
+    return <JsonTopic>{
+      fancyTitle: this.cleanTitle(topic.fancy_title),
+      archived: topic.archived,
+      author: topic.details.created_by.name,
+      authorAvatar: environment.forumUrl + topic.details.created_by.avatar_template.replace('{size}', '48'),
+      tags: topic.tags,
+      createdAt: moment(topic.created_at),
+      updatedAt: moment(topic.last_posted_at),
+      feedItem: feedItem,
+      feedUrl: url,
+    };
+  }
+
+  protected isDiscourseCategory(url: string) {
+    return url.match(/\/c\//);
+  }
+
+  protected prepareFeedItem(post, topic): JsonFeedItem {
+    const maxContentLength = environment.feed.maxContentLength;
+    if (maxContentLength > 0 && post.cooked && post.cooked.length > maxContentLength) {
+      const endIndex = Math.max(post.cooked.lastIndexOf(' ', maxContentLength), post.cooked.lastIndexOf('<', maxContentLength));
+      post.cooked = post.cooked.substring(0, endIndex) + ' (...)';
+      post.truncated = true;
+    }
+    post.name = post.name ?? topic.details.last_poster.name;
+    return <JsonFeedItem>{
+      author: post.name,
+      authorAvatar:
+        environment.forumUrl + (post.avatar_template.replace('{size}', '48') ?? topic.details.last_poster.avatar_template.replace('{size}', '48')),
+      content_html: post.cooked,
+      date_published: post.created_at,
+      truncated: post.truncated,
+    };
+  }
+
+  protected extractCategoryIdFromUrl(url: string) {
+    const idMatch = url.match(/\/(\d+)$/);
+    return idMatch ? parseInt(idMatch[1], 10) : null;
+  }
+
+  protected extractCategorySlugFromUrl(url: string) {
+    const match = url.match(/\/c\/([\w/-]+)\/\d+$/);
+    return match ? match[1] : null;
+  }
+
+  protected extractTopicIdFromUrl(url: string) {
+    const idMatch = url.match(/\/(\d+)(?:$|\/)/);
+    return idMatch ? parseInt(idMatch[1], 10) : null;
+  }
+
+  protected getLanguageFromTitle(title: string) {
+    if (!title) return '';
+
+    const matches = title.match('\\s\\(([a-z]{2}(?:-[A-Z]{2})?)\\)$');
+    return matches && matches[1];
+  }
+
+  protected cleanTitle(title: string) {
+    if (!title) return undefined;
+    return title.replace(/\s\([a-z]{2}(:?-[A-Z]{2})?\)$/, '');
   }
 }
diff --git a/src/app/network/pod/pod.service.ts b/src/app/network/pod/pod.service.ts
index 08903cfa9d4af10c20ac20b5ed2e7c2d9ac4e792..db661859e924d711a75ae532e47f7cb28e0ae715 100644
--- a/src/app/network/pod/pod.service.ts
+++ b/src/app/network/pod/pod.service.ts
@@ -12,8 +12,7 @@ import {
 } from '@app/shared/services/network/graphql/graphql.service';
 import { DocumentNode } from 'graphql/index';
 import { StorageService } from '@app/shared/services/storage/storage.service';
-import { firstValueFrom, Observable, of } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { firstValueFrom, map, Observable, of } from 'rxjs';
 import { Currency } from '@app/currency/currency.model';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
 import { firstNotNilPromise } from '@app/shared/observables';
@@ -37,6 +36,8 @@ export class PodService extends GraphqlService<PodState> {
   @RxStateSelect() minBlockHeight$: Observable<number>;
   @RxStateProperty() minBlockHeight: number;
 
+  errors: Error;
+
   constructor(
     storage: StorageService,
     private settings: SettingsService,
@@ -55,111 +56,127 @@ export class PodService extends GraphqlService<PodState> {
     filter: WotSearchFilter,
     options: { after?: string; first?: number; fetchPolicy?: FetchPolicy; total?: number; withTotal?: boolean }
   ): Observable<LoadResult<Account>> {
+    if (this.errors) return of(<LoadResult<Account>>{});
     console.debug(`${this._logPrefix}Searching profiles by filter...`, filter);
-
     const now = Date.now();
     const offset = toNumber(+options?.after, 0);
     const limit = toNumber(+options?.first, this.fetchSize);
     const withTotal = offset === 0 && options?.withTotal !== false;
     let data$: Observable<LoadResult<ProfileFragment>>;
+    try {
+      // Load by unique address
+      if (isNotNilOrBlank(filter.address)) {
+        data$ = this.graphqlService
+          .profileByAddress(
+            {
+              address: filter.address,
+            },
+            options
+          )
+          .pipe(
+            map(({ data }) => {
+              return {
+                data: [data.profiles_by_pk],
+                total: isNil(data.profiles_by_pk) ? 0 : 1,
+              };
+            })
+          );
+      }
 
-    // Load by unique address
-    if (isNotNilOrBlank(filter.address)) {
-      data$ = this.graphqlService
-        .profileByAddress(
-          {
-            address: filter.address,
-          },
-          options
-        )
-        .pipe(
-          map(({ data }) => {
-            return {
-              data: [data.profiles_by_pk],
-              total: isNil(data.profiles_by_pk) ? 0 : 1,
-            };
+      // Load by adresses
+      else if (isNotEmptyArray(filter.addresses)) {
+        data$ = this.graphqlService
+          .profileSearchByAddresses(
+            {
+              addresses: filter.addresses,
+            },
+            options
+          )
+          .pipe(
+            map(({ data }) => {
+              return {
+                data: data.profiles as ProfileFragment[],
+              };
+            })
+          );
+      } else if (isNotNilOrBlank(filter.searchText)) {
+        data$ = this.graphqlService
+          .profileSearchByText({
+            offset,
+            limit,
+            searchText: `%${filter.searchText}%`,
+            orderBy: [{ time: Order_By.Asc }, { title: Order_By.Asc }],
+            withTotal,
           })
-        );
-    }
+          .pipe(
+            map(({ data }) => {
+              return {
+                data: data.profiles as ProfileFragment[],
+                total: data.profiles_aggregate?.aggregate.count,
+              };
+            })
+          );
+      } else {
+        return of(<LoadResult<Account>>{});
+      }
 
-    // Load by adresses
-    else if (isNotEmptyArray(filter.addresses)) {
-      data$ = this.graphqlService
-        .profileSearchByAddresses(
-          {
-            addresses: filter.addresses,
-          },
-          options
-        )
-        .pipe(
-          map(({ data }) => {
-            return {
-              data: data.profiles as ProfileFragment[],
+      return data$.pipe(
+        map((res) => {
+          const data = AccountConverter.profileToAccounts(res.data, { ipfsGateway: this.ipfsService.gatewayBaseUrl });
+
+          const duration = Date.now() - now;
+          if (duration > 10) {
+            console.info(`${this._logPrefix}${data.length} profiles loaded in ${duration}ms`);
+          }
+
+          const total = toNumber(res?.total, options?.total);
+          const result: LoadResult<Account> = { data, total };
+          const nextOffset = offset + limit;
+          if (isNotNil(total) && nextOffset < total) {
+            result.fetchMore = (first) => {
+              console.debug(`${this._logPrefix}Fetching more profiles - offset: ${nextOffset}`);
+              return firstValueFrom(
+                this.profileSearch(filter, { ...options, after: nextOffset.toString(), first: toNumber(first, options.first), total })
+              );
             };
-          })
-        );
-    } else if (isNotNilOrBlank(filter.searchText)) {
-      data$ = this.graphqlService
-        .profileSearchByText({
-          offset,
-          limit,
-          searchText: `%${filter.searchText}%`,
-          orderBy: [{ time: Order_By.Asc }, { title: Order_By.Asc }],
-          withTotal,
+          }
+          return result;
         })
-        .pipe(
-          map(({ data }) => {
-            return {
-              data: data.profiles as ProfileFragment[],
-              total: data.profiles_aggregate?.aggregate.count,
-            };
-          })
-        );
-    } else {
+      );
+    } catch (e) {
       return of(<LoadResult<Account>>{});
     }
-
-    return data$.pipe(
-      map((res) => {
-        const data = AccountConverter.profileToAccounts(res.data, { ipfsGateway: this.ipfsService.gatewayBaseUrl });
-
-        const duration = Date.now() - now;
-        if (duration > 10) {
-          console.info(`${this._logPrefix}${data.length} profiles loaded in ${duration}ms`);
-        }
-
-        const total = toNumber(res?.total, options?.total);
-        const result: LoadResult<Account> = { data, total };
-        const nextOffset = offset + limit;
-        if (isNotNil(total) && nextOffset < total) {
-          result.fetchMore = (first) => {
-            console.debug(`${this._logPrefix}Fetching more profiles - offset: ${nextOffset}`);
-            return firstValueFrom(
-              this.profileSearch(filter, { ...options, after: nextOffset.toString(), first: toNumber(first, options.first), total })
-            );
-          };
-        }
-        return result;
-      })
-    );
   }
 
   protected async ngOnStart(): Promise<PodState> {
-    if (!this.ipfsService.started) this.ipfsService.start();
+    if (!this.ipfsService.started) await this.ipfsService.start();
 
     // Wait settings and ipfs service
     const [settings, currency] = await Promise.all([this.settings.ready(), firstNotNilPromise(this.currency$)]);
 
+    let isPeerAlive: boolean;
     let peer = Peers.fromUri(settings.pod);
-    if (!peer) {
+
+    if (isNil(peer)) {
+      isPeerAlive = false;
+    } else {
+      isPeerAlive = await this.isPeerAlive(peer);
+    }
+
+    if (!peer || !isPeerAlive) {
+      const preferredFiltered = settings.preferredPods.filter((preferred) => preferred !== settings.pod);
+      if (preferredFiltered.length === 0) throw new Error('ERROR.CHECK_NETWORK_CONNECTION');
+
       const peers = await this.filterAlivePeers(settings.preferredPods);
       if (!peers.length) {
-        throw { message: 'ERROR.CHECK_NETWORK_CONNECTION' };
+        this.errors = new Error('ERROR.CHECK_NETWORK_CONNECTION');
+        throw this.errors;
       }
       peer = arrayRandomPick(peers);
     }
 
     const client = await super.createClient(peer, 'pod');
+    settings.pod = Peers.getHttpUri(peer);
 
     return {
       peer,
diff --git a/src/app/settings/settings.model.ts b/src/app/settings/settings.model.ts
index 157a7a6a84d2406d206c0e3cf3100340f82f01ef..77f0a95827488c1479fbb0858825fc0233b22658 100644
--- a/src/app/settings/settings.model.ts
+++ b/src/app/settings/settings.model.ts
@@ -1,5 +1,7 @@
 import { PropertiesMap, Property } from '../shared/types';
 import { InjectionToken } from '@angular/core';
+import moment, { Moment } from 'moment';
+import DurationConstructor = moment.unitOfTime.DurationConstructor;
 
 export declare interface LocaleConfig extends Property {
   country?: string;
@@ -9,6 +11,11 @@ export const APP_LOCALES = new InjectionToken<LocaleConfig[]>('locales');
 
 export type CurrencyDisplayUnit = 'base' | 'du';
 
+export interface PeriodOption {
+  key: DurationConstructor;
+  i18nKey: string;
+}
+
 export interface Settings {
   peer: string;
   currency?: string;
@@ -19,6 +26,8 @@ export interface Settings {
   preferredPods?: string[];
   ipfsGateway: string;
   preferredIpfsGateways?: string[];
+  distanceFileUrl?: string;
+  preferredDistanteFileUrls?: string[];
   pages?: any; // Any pages settings
   locale?: string;
   mobile?: boolean;
@@ -27,4 +36,6 @@ export interface Settings {
   unAuthDelayMs?: number;
   darkMode: boolean;
   displayUnit: CurrencyDisplayUnit;
+  selectedRedeemPeriod?: DurationConstructor;
+  lastRedeemDate: Moment;
 }
diff --git a/src/app/settings/settings.page.html b/src/app/settings/settings.page.html
index 1f3f12b4de7ec3d6eceefa33073642a11628fa2f..72fbe614d20bde4a23941df11a5b352fba290277 100644
--- a/src/app/settings/settings.page.html
+++ b/src/app/settings/settings.page.html
@@ -38,6 +38,17 @@
         </ion-select>
       </ion-item>
 
+      <ion-item-divider translate>MENU.ACCOUNT</ion-item-divider>
+      <ion-item>
+        <ion-icon slot="start" name="timer-outline"></ion-icon>
+        <ion-label translate>SETTINGS.DURATION_BETWEEN_UD_CLAIM</ion-label>
+        <ion-select [interface]="mobile ? 'action-sheet' : 'popover'" [(ngModel)]="selectedRedeemPeriod">
+          @for (period of redeemPeriodOptions; track period.key) {
+            <ion-select-option [value]="period.key" translate>{{ period.i18nKey }}</ion-select-option>
+          }
+        </ion-select>
+      </ion-item>
+
       <ion-item>
         <ion-toggle [(ngModel)]="useRelativeUnit" justify="end">
           <ion-label color="medium" translate>COMMON.BTN_RELATIVE_UNIT</ion-label>
@@ -185,6 +196,12 @@
     </ion-toolbar>
   </ion-header>
   <ion-content>
+    <ion-item>
+      <ion-input [(ngModel)]="customPeer" (keydown.enter)="onPeerSubmit(property) && modal.dismiss()" labelPlacement="floating">
+        <div slot="label" translate>PEER.CUSTOM_PEER</div>
+      </ion-input>
+      <ion-icon name="enter-outline" slot="end" (click)="onPeerSubmit(property) && modal.dismiss()" tappable></ion-icon>
+    </ion-item>
     <ion-list>
       <ion-item
         *rxFor="let peer of peers$"
diff --git a/src/app/settings/settings.page.ts b/src/app/settings/settings.page.ts
index dc8ac6326b1bd1932c217011a2367d016bc2086e..c30c63211637c073f8e422d4ce9dda7ad750ed90 100644
--- a/src/app/settings/settings.page.ts
+++ b/src/app/settings/settings.page.ts
@@ -1,5 +1,5 @@
-import { Component, Inject, OnInit, ViewChild } from '@angular/core';
-import { APP_LOCALES, LocaleConfig, Settings } from '@app/settings/settings.model';
+import { Component, Inject, Input, OnInit, ViewChild } from '@angular/core';
+import { APP_LOCALES, LocaleConfig, PeriodOption, Settings } from '@app/settings/settings.model';
 import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
 import { RxState } from '@rx-angular/state';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
@@ -7,10 +7,13 @@ import { Observable, skip } from 'rxjs';
 import { IonModal } from '@ionic/angular';
 import { NetworkService } from '@app/network/network.service';
 import { map } from 'rxjs/operators';
+import moment from 'moment';
+import DurationConstructor = moment.unitOfTime.DurationConstructor;
 
 export interface SettingsPageState extends Settings, AppPageState {
   useRelativeUnit: boolean;
   dirty: boolean;
+  newPeer: string;
 }
 
 @Component({
@@ -51,6 +54,22 @@ export class SettingsPage extends AppPage<SettingsPageState> implements OnInit {
       value: 9999 * 60_000,
     },
   ];
+
+  redeemPeriodOptions: PeriodOption[] = [
+    {
+      key: 'day',
+      i18nKey: 'SETTINGS.REDEEM_UD_PERIOD_OPTION.DAILY',
+    },
+    {
+      key: 'week',
+      i18nKey: 'SETTINGS.REDEEM_UD_PERIOD_OPTION.WEEKLY',
+    },
+    {
+      key: 'month',
+      i18nKey: 'SETTINGS.REDEEM_UD_PERIOD_OPTION.MONTHLY',
+    },
+  ];
+
   @RxStateSelect() preferredPeers$: Observable<string[]>;
   @RxStateSelect() peer$: Observable<string>;
   @RxStateSelect() preferredIndexers$: Observable<string[]>;
@@ -60,6 +79,8 @@ export class SettingsPage extends AppPage<SettingsPageState> implements OnInit {
   @RxStateSelect() preferredIpfsGateways$: Observable<string[]>;
   @RxStateSelect() ipfsGateway$: Observable<string>;
   @RxStateSelect() dirty$: Observable<boolean>;
+  @RxStateSelect() newPeer$: Observable<string>;
+  @RxStateSelect() durationRedeemUd$: Observable<number>;
 
   @RxStateProperty() darkMode: boolean;
   @RxStateProperty() locale: string;
@@ -70,6 +91,8 @@ export class SettingsPage extends AppPage<SettingsPageState> implements OnInit {
   @RxStateProperty() ipfsGateway: string;
   @RxStateProperty() unAuthDelayMs: number;
   @RxStateProperty() dirty: boolean;
+  @Input() @RxStateProperty() customPeer: string;
+  @Input() @RxStateProperty() selectedRedeemPeriod: DurationConstructor = 'week';
 
   @ViewChild('selectPeerModal') selectPeerModal: IonModal;
   @ViewChild('selectIndexerModal') selectIndexerModal: IonModal;
@@ -88,7 +111,9 @@ export class SettingsPage extends AppPage<SettingsPageState> implements OnInit {
 
     // Detect changes
     this._state.hold(
-      this._state.select(['locale', 'peer', 'indexer', 'pod', 'ipfsGateway', 'unAuthDelayMs', 'displayUnit'], (s) => s).pipe(skip(1)),
+      this._state
+        .select(['locale', 'peer', 'indexer', 'pod', 'ipfsGateway', 'unAuthDelayMs', 'displayUnit', 'selectedRedeemPeriod'], (s) => s)
+        .pipe(skip(1)),
       () => {
         if (this.mobile) {
           this.save();
@@ -122,6 +147,10 @@ export class SettingsPage extends AppPage<SettingsPageState> implements OnInit {
     return true;
   }
 
+  onPeerSubmit(property: keyof Settings) {
+    return this.setStateValue(this.customPeer, property);
+  }
+
   markAsDirty() {
     this.dirty = true;
   }
diff --git a/src/app/settings/settings.service.ts b/src/app/settings/settings.service.ts
index caced262851f9a5a5168f94f42ef9979d5c16011..094eba61eea1ed873eb35e51941b14bb43f995cf 100644
--- a/src/app/settings/settings.service.ts
+++ b/src/app/settings/settings.service.ts
@@ -26,6 +26,14 @@ export class SettingsService extends RxStartableService<SettingsState> {
     return this.get('mobile');
   }
 
+  get selectedRedeemPeriod() {
+    return this.get('selectedRedeemPeriod');
+  }
+
+  get lastRedeemDate() {
+    return this.get('lastRedeemDate');
+  }
+
   @RxStateSelect() locale$: Observable<string>;
   @RxStateSelect() darkMode$: Observable<boolean>;
   @RxStateSelect() peer$: Observable<string>;
@@ -77,13 +85,18 @@ export class SettingsService extends RxStartableService<SettingsState> {
 
   clone(): Settings {
     const data = this.get();
+    // const conf = await this.storage.get(SETTINGS_STORAGE_KEY);
+
+    // console.log('TODO storage', conf);
     return <Settings>{
       locale: environment.defaultLocale,
-      peer: environment.dev?.peer || environment.defaultPeers?.[0],
-      indexer: environment.dev?.indexer || environment.defaultIndexers?.[0],
-      pod: environment.dev?.pod || environment.defaultPods?.[0],
-      ipfsGateway: environment.dev?.ipfsGateway || environment.defaultIfpsGateways?.[0],
+      peer: environment.dev?.peer ?? environment.defaultPeers?.[0],
+      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 || [])]),
       preferredPeers: arrayDistinct([...environment.defaultPeers, ...(data?.preferredPeers || [])]),
       preferredIndexers: arrayDistinct([...environment.defaultIndexers, ...(data?.preferredIndexers || [])]),
       preferredPods: arrayDistinct([...environment.defaultPods, ...(data?.preferredPods || [])]),
@@ -104,6 +117,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 || [])]),
     };
   }
 
@@ -126,7 +140,7 @@ export class SettingsService extends RxStartableService<SettingsState> {
   private getNumberFormatOptions(locale: string): Intl.NumberFormatOptions {
     const defaultOptions: Intl.NumberFormatOptions = { useGrouping: true, maximumFractionDigits: 3 };
     switch (locale) {
-      case 'fr-FR':
+      case 'fr':
         return <Intl.NumberFormatOptions>{ ...defaultOptions };
       case 'en-US':
       case 'en-GB':
diff --git a/src/app/shared/animations.ts b/src/app/shared/animations.ts
index 591fe731060a6a53fcc27e4b40b98bb4c628d196..ea7ff2f42975b9ef91218007e9289633c0db2cdf 100644
--- a/src/app/shared/animations.ts
+++ b/src/app/shared/animations.ts
@@ -96,6 +96,46 @@ export const slideInOutAnimation =
     ]),
   ]);
 
+export const slideDownAnimation =
+  // trigger name for attaching this animation to an element using the [@triggerName] syntax
+  trigger('slideDownAnimation', [
+    // end state styles for route container (host)
+    state(
+      '*',
+      style({
+        transform: 'translateY(0)',
+        opacity: 1,
+      })
+    ),
+
+    // route 'enter' transition
+    transition(':enter', [
+      // styles at start of transition
+      style({
+        transform: 'translateY(-400%)',
+        opacity: 0,
+      }),
+
+      // animation and styles at end of transition
+      animate(
+        '.3s ease-in-out',
+        style({
+          transform: 'translateY(0)',
+          opacity: 1,
+        })
+      ),
+    ]),
+
+    // route 'leave' transition
+    transition(':leave', [
+      // animation and styles at end of transition
+      style({
+        transform: 'translateY(-400%)',
+        opacity: 0,
+      }),
+    ]),
+  ]);
+
 export const slideUpDownAnimation =
   // trigger name for attaching this animation to an element using the [@triggerName] syntax
   trigger('slideUpDownAnimation', [
diff --git a/src/app/shared/colors.utils.ts b/src/app/shared/colors.utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c9c92db8208a324161776260d7d316e946f00c84
--- /dev/null
+++ b/src/app/shared/colors.utils.ts
@@ -0,0 +1,3 @@
+import { PredefinedColors } from '@ionic/core';
+
+export declare type AppColors = PredefinedColors | 'secondary100' | 'warning900' | 'danger100' | 'danger900' | 'transparent';
diff --git a/src/app/shared/environment/environment.utils.ts b/src/app/shared/environment/environment.utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4be7ca19df42b64a4d89dd4782655a29b727349c
--- /dev/null
+++ b/src/app/shared/environment/environment.utils.ts
@@ -0,0 +1,8 @@
+import { environment } from '@environments/environment';
+
+export function isDemo() {
+  return environment?.mode === 'demo' && environment.production === true;
+}
+export function isDev() {
+  return environment?.mode === 'dev' && environment.production === false;
+}
diff --git a/src/app/shared/error/error-item.component.html b/src/app/shared/error/error-item.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..fb5249f676cdd2419a3dcbb33e70e097ca9480c6
--- /dev/null
+++ b/src/app/shared/error/error-item.component.html
@@ -0,0 +1,7 @@
+<!-- error -->
+@if (message) {
+  <ion-item lines="none" [color]="backgroundColor" class="{{ size }} {{ classList }}" [@slideDownAnimation]="animated">
+    <ion-icon [color]="color" slot="start" [name]="icon"></ion-icon>
+    <ion-label [color]="color" [innerHTML]="message | translate"></ion-label>
+  </ion-item>
+}
diff --git a/src/app/shared/error/error-item.component.scss b/src/app/shared/error/error-item.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c5e6d7122bb1f35073a3f8bbbc3ccf869a0bcfa3
--- /dev/null
+++ b/src/app/shared/error/error-item.component.scss
@@ -0,0 +1,29 @@
+// Small
+ion-item.small {
+  ion-icon[slot='start'] {
+    height: 18px;
+    width: 18px;
+    font-size: 18px;
+    margin-inline-end: 8px;
+  }
+  ion-label {
+    font-size: 0.9rem;
+  }
+}
+
+// Medium
+ion-item.medium {
+  ion-icon[slot='start'] {
+    margin-inline-end: 10px;
+  }
+}
+
+// Large
+ion-item.large {
+  ion-icon[slot='start'] {
+    margin-inline-end: 10px;
+  }
+  ion-label {
+    font-size: 1.1rem;
+  }
+}
diff --git a/src/app/shared/error/error-item.component.ts b/src/app/shared/error/error-item.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cd05bd131fc7ca4bbb141a493e668927cb89edc9
--- /dev/null
+++ b/src/app/shared/error/error-item.component.ts
@@ -0,0 +1,38 @@
+import { booleanAttribute, ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
+import { IonicModule } from '@ionic/angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { SharedPipesModule } from '@app/shared/pipes/pipes.module';
+import { AppColors } from '@app/shared/colors.utils';
+import { slideDownAnimation } from '@app/shared/animations';
+
+@Component({
+  selector: 'app-error-item',
+  templateUrl: './error-item.component.html',
+  styleUrls: ['./error-item.component.scss'],
+  animations: [slideDownAnimation],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+  standalone: true,
+  imports: [IonicModule, TranslateModule, SharedPipesModule],
+})
+export class AppErrorItem implements OnInit {
+  protected defaultColor: AppColors;
+
+  @Input() message: string;
+  @Input() icon = 'alert-circle';
+  @Input() backgroundColor: AppColors = 'transparent';
+  @Input() color: AppColors;
+  @Input({ transform: booleanAttribute }) animated = true;
+  // eslint-disable-next-line @angular-eslint/no-input-rename
+  @Input('class') classList: string;
+  @Input() size: 'small' | 'medium' | 'large' = 'medium';
+  constructor() {
+    this.defaultColor = 'danger';
+  }
+
+  ngOnInit() {
+    this.backgroundColor = this.backgroundColor ?? 'transparent';
+    if ((!this.backgroundColor || this.backgroundColor === 'transparent') && !this.color) {
+      this.color = this.defaultColor || 'danger';
+    }
+  }
+}
diff --git a/src/app/shared/error/warning-item.component.ts b/src/app/shared/error/warning-item.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df2eaf609bc9bddfd2b9a4163670507e074574a8
--- /dev/null
+++ b/src/app/shared/error/warning-item.component.ts
@@ -0,0 +1,27 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+import { IonicModule } from '@ionic/angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AppErrorItem } from '@app/shared/error/error-item.component';
+
+@Component({
+  selector: 'app-warning-item',
+  templateUrl: './error-item.component.html',
+  styleUrls: ['./error-item.component.scss'],
+  // animations: [slideDownAnimation],
+  changeDetection: ChangeDetectionStrategy.OnPush,
+  standalone: true,
+  imports: [IonicModule, TranslateModule],
+})
+export class AppWarningItem extends AppErrorItem {
+  // eslint-disable-next-line @angular-eslint/no-input-rename
+  @Input('class') classList: string;
+  constructor() {
+    super();
+    this.icon = 'warning';
+    this.defaultColor = 'tertiary';
+  }
+
+  ngOnInit() {
+    super.ngOnInit();
+  }
+}
diff --git a/src/app/shared/services/network/graphql/graphql.service.ts b/src/app/shared/services/network/graphql/graphql.service.ts
index d61df3580500920c937f2b207d20f27bba7a80b8..b89d22f2325a79177158d192674fa447b0caa740 100644
--- a/src/app/shared/services/network/graphql/graphql.service.ts
+++ b/src/app/shared/services/network/graphql/graphql.service.ts
@@ -7,10 +7,11 @@ import {
   ApolloQueryResult,
   FetchPolicy,
   InMemoryCache,
-  MutationUpdaterFn, MutationUpdaterFunction,
+  MutationUpdaterFunction,
   NetworkStatus,
   OperationVariables,
-  TypePolicies, Unmasked,
+  TypePolicies,
+  Unmasked,
   WatchQueryFetchPolicy,
 } from '@apollo/client/core';
 import { ErrorCodes, ServerErrorCodes } from '../network.errors';
@@ -25,7 +26,8 @@ import TrackerLink, {
   isMutationOperation,
   isSubscriptionOperation,
   restoreTrackedQueries,
-  StorageServiceWrapper, TrackableMutationContext,
+  StorageServiceWrapper,
+  TrackableMutationContext,
 } from './graphql.utils';
 import { RetryLink } from '@apollo/client/link/retry';
 import queueLinkImported from 'apollo-link-queue';
@@ -35,7 +37,7 @@ import { Platform } from '@ionic/angular';
 import { EntityUtils } from '../../entity.model';
 import { isNil, isNotEmptyArray, isNotNil, toNumber } from '../../../functions';
 import { Resolvers } from '@apollo/client/core/types';
-import { HttpHeaders } from '@angular/common/http';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { HttpLink, Options } from 'apollo-angular/http';
 import { persistCache, PersistentStorage } from 'apollo3-cache-persist';
 import { ErrorPolicy, MutationBaseOptions } from '@apollo/client/core/watchQueryOptions';
@@ -65,10 +67,11 @@ export interface WatchQueryOptions<V> {
   fetchPolicy?: WatchQueryFetchPolicy;
 }
 
-export interface MutateQueryOptions<TData,
+export interface MutateQueryOptions<
+  TData,
   TVariables = OperationVariables,
   TContext = TrackableMutationContext,
-  TCache extends ApolloCache<any> = ApolloCache<any>
+  TCache extends ApolloCache<any> = ApolloCache<any>,
 > extends MutationBaseOptions<TData, TVariables, TContext, TCache> {
   mutation: any;
   variables?: TVariables;
@@ -107,6 +110,7 @@ export abstract class GraphqlService<
 
   private platform = inject(Platform);
   private httpLink = inject(HttpLink);
+  private httpClient = inject(HttpClient);
   private httpParams: Options;
   private wsParams: ClientOptions<ConnectionParams>;
   private connectionParams: ConnectionParams = {};
@@ -129,14 +133,6 @@ export abstract class GraphqlService<
     return this.client?.cache;
   }
 
-  get fetchPolicy(): FetchPolicy {
-    return this.offline ? 'cache-only' : this.defaultFetchPolicy;
-  }
-
-  get watchFetchPolicy(): WatchQueryFetchPolicy {
-    return this.offline ? 'cache-only' : this.defaultWatchFetchPolicy;
-  }
-
   protected constructor(
     private storage: StorageService,
     private typePolicies?: TypePolicies,
@@ -166,6 +162,14 @@ export abstract class GraphqlService<
     //   .subscribe(() => this.network.setForceOffline(true, { showToast: true }));
   }
 
+  get fetchPolicy(): FetchPolicy {
+    return this.offline ? 'cache-only' : this.defaultFetchPolicy;
+  }
+
+  get watchFetchPolicy(): WatchQueryFetchPolicy {
+    return this.offline ? 'cache-only' : this.defaultWatchFetchPolicy;
+  }
+
   /**
    * Allow to add a field resolver
    *  (see doc: https://www.apollographql.com/docs/react/data/local-state/#handling-client-fields-with-resolvers)
@@ -231,7 +235,7 @@ export abstract class GraphqlService<
         opts.optimisticResponse = (await optimisticResponseFn(opts.context)) as Unmasked<NoInfer<T>>;
         if (this._debug) console.debug('[graphql] [offline] Using an optimistic response: ', opts.optimisticResponse);
       } else {
-        opts.optimisticResponse = opts.offlineResponse  as Unmasked<NoInfer<T>>;
+        opts.optimisticResponse = opts.offlineResponse as Unmasked<NoInfer<T>>;
       }
       if (opts.forceOffline) {
         const res = { data: opts.optimisticResponse as Unmasked<NoInfer<T>> };
@@ -931,29 +935,36 @@ export abstract class GraphqlService<
     return undefined;
   }
 
-  protected async filterAlivePeers(
-    peers: string[],
-    opts?: {
-      timeout?: number;
-    }
-  ): Promise<Peer[]> {
+  protected async filterAlivePeers(peers: string[]): Promise<Peer[]> {
     return (
-      await Promise.all(
-        peers.map((peer) => Peers.fromUri(peer)).map((peer) => this.isPeerAlive(peer, opts).then((alive) => (alive ? peer : undefined)))
-      )
+      await Promise.all(peers.map((peer) => Peers.fromUri(peer)).map((peer) => this.isPeerAlive(peer).then((alive) => (alive ? peer : undefined))))
     ).filter(isNotNil);
   }
 
-  protected async isPeerAlive(
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    peer: Peer,
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    opts?: {
-      timeout?: number;
+  protected async isPeerAlive(peer: Peer): Promise<boolean> {
+    const query = `
+      query {
+        __schema {
+          types {
+            name
+          }
+        }
+      }
+    `;
+
+    try {
+      return await firstValueFrom(
+        this.httpClient.post(Peers.getHttpUri(peer), { query }).pipe(
+          map(() => true),
+          catchError((err) => {
+            console.error(`an error occurred during the verification :`, err);
+            throw new Error(`Unable to verify server status: ${err}`);
+          })
+        )
+      );
+    } catch (error) {
+      if (this._debug) console.debug(`${this._logPrefix}server not available.`, error);
+      return false;
     }
-  ): Promise<boolean> {
-    // TODO
-    console.log(`${this._logPrefix}TODO: implement ${this.constructor.name}.isPeerAlive()`, peer);
-    return Promise.resolve(true);
   }
 }
diff --git a/src/app/shared/services/rx-startable-service.class.ts b/src/app/shared/services/rx-startable-service.class.ts
index 1d5f8f77adb93a4e3e10b280632799b4b801ca3e..a9fe21b1c39cde9f95ac0e26693cb93204e73db5 100644
--- a/src/app/shared/services/rx-startable-service.class.ts
+++ b/src/app/shared/services/rx-startable-service.class.ts
@@ -56,10 +56,10 @@ export abstract class RxStartableService<T extends object = Object, O extends Rx
         return data;
       })
       .catch((err) => {
-        console.error('Failed to start a service: ' + ((err && err.message) || err), err);
+        console.error(`${this._logPrefix}Failed to start a service: ` + ((err && err.message) || err), err);
         this._started = false;
         this._startPromise = null;
-        return null;
+        throw err;
       });
     return this._startPromise;
   }
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index d1fe679046fd71b9c41571759d462bd2d9fda2bc..925813ec720ad85bbe2df36b8e3063b00d3ff7c4 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -16,6 +16,8 @@ import { SwiperDirective } from '@app/shared/swiper/app-swiper.directive';
 import { AppSkeletonListComponent } from '@app/shared/loading/skeleton.list/skeleton.list.component';
 import { AppGraphQLModule } from '@app/shared/services/network/graphql/graphql.module';
 import { RouterModule } from '@angular/router';
+import { AppErrorItem } from '@app/shared/error/error-item.component';
+import { AppWarningItem } from '@app/shared/error/warning-item.component';
 
 @NgModule({
   imports: [
@@ -40,6 +42,10 @@ import { RouterModule } from '@angular/router';
     SwiperDirective,
     AppGraphQLModule,
     AppSkeletonListComponent,
+
+    // Standalone components
+    AppErrorItem,
+    AppWarningItem,
   ],
   exports: [
     CommonModule,
@@ -63,6 +69,10 @@ import { RouterModule } from '@angular/router';
     SwiperDirective,
     AppGraphQLModule,
     AppSkeletonListComponent,
+
+    // Standalone components
+    AppErrorItem,
+    AppWarningItem,
   ],
 })
 export class AppSharedModule {}
diff --git a/src/app/transfer/send/transfer.page.html b/src/app/transfer/send/transfer.page.html
index 18f614c83cf015bd5b659aebc1ac201093c2336e..3384f5c85ff4ebf8ca341cb3bd59df031eb0cfd4 100644
--- a/src/app/transfer/send/transfer.page.html
+++ b/src/app/transfer/send/transfer.page.html
@@ -2,7 +2,9 @@
   <ion-toolbar [color]="toolbarColor">
     <ion-buttons slot="start" *ngIf="mobile">
       @if (_isModal) {
-        <ion-button (click)="cancel()"><ion-icon name="arrow-back"></ion-icon></ion-button>
+        <ion-button (click)="cancel()">
+          <ion-icon name="arrow-back"></ion-icon>
+        </ion-button>
       } @else {
         <ion-menu-button *ngIf="showMenuButton"></ion-menu-button>
         <ion-back-button></ion-back-button>
@@ -14,7 +16,7 @@
 
     <ion-buttons slot="end" *ngIf="mobile">
       <!-- Send-->
-      <ion-button (click)="doSubmit()" [disabled]="loading || invalid">
+      <ion-button (click)="doSubmit()" [disabled]="loading || invalid || isDemo()">
         <ion-icon name="send"></ion-icon>
       </ion-button>
     </ion-buttons>
@@ -97,16 +99,15 @@
     </ion-item>
 
     <ion-item lines="none">
-      <!--        <ion-toggle [(ngModel)]="showComment">-->
-      <!--        </ion-toggle>-->
-      <!--        <ion-label class="ion-text-start" color="medium" translate>TRANSFER.BTN_ADD_COMMENT</ion-label>-->
+      <ion-toggle [(ngModel)]="showComment"></ion-toggle>
+      <ion-label class="ion-text-start" color="medium" translate>TRANSFER.BTN_ADD_COMMENT</ion-label>
       <ion-badge slot="end" *ngIf="amount && fee" color="medium">
         {{ 'TRANSFER.FEE' | translate: { fee: fee, currency: currency.symbol } }}
       </ion-badge>
     </ion-item>
 
     <ion-item *ngIf="showComment">
-      <ion-textarea [placeholder]="'TRANSFER.COMMENT_HELP' | translate" rows="5"></ion-textarea>
+      <ion-textarea [(ngModel)]="comment" [placeholder]="'TRANSFER.COMMENT_HELP' | translate" rows="5"></ion-textarea>
     </ion-item>
   </ion-list>
 
@@ -120,7 +121,7 @@
     <ion-label translate>COMMON.BTN_CANCEL</ion-label>
   </ion-button>
 
-  <ion-button (click)="doSubmit()" [disabled]="loading || invalid" color="tertiary">
+  <ion-button (click)="doSubmit()" [disabled]="loading || invalid || isDemo()" color="tertiary">
     <ion-icon slot="start" name="paper-plane"></ion-icon>
     <ion-label translate>COMMON.BTN_SEND</ion-label>
   </ion-button>
diff --git a/src/app/transfer/send/transfer.page.ts b/src/app/transfer/send/transfer.page.ts
index 7a5711a3ab127562aba2d58bd54ddf670ea68ec3..202e73c2f97eb87efdec683f40b91be3f04ef5c9 100644
--- a/src/app/transfer/send/transfer.page.ts
+++ b/src/app/transfer/send/transfer.page.ts
@@ -16,6 +16,8 @@ import { WotController } from '@app/wot/wot.controller';
 import { TransferFormOptions } from '@app/transfer/transfer.model';
 import { PredefinedColors } from '@ionic/core';
 import { Capacitor } from '@capacitor/core';
+import { environment } from '@environments/environment';
+import { isDemo } from '@app/shared/environment/environment.utils';
 
 export interface TransferPageState extends AppPageState {
   currency: Currency;
@@ -24,6 +26,7 @@ export interface TransferPageState extends AppPageState {
   account: Account;
   recipient: Partial<Account>;
   submitted: boolean;
+  comment: string;
 }
 
 export interface TransferPageInputs extends TransferFormOptions {
@@ -56,12 +59,14 @@ export class TransferPage extends AppPage<TransferPageState> implements Transfer
   @RxStateSelect() protected account$: Observable<Account>;
   @RxStateSelect() protected recipient$: Observable<Partial<Account>>;
   @RxStateSelect() protected submitted$: Observable<boolean>;
+  @RxStateSelect() protected comment$: Observable<string>;
 
   @Input() @RxStateProperty() currency: Currency;
   @Input() @RxStateProperty() fee: number;
   @Input() @RxStateProperty() account: Account;
   @Input() @RxStateProperty() recipient: Partial<Account>;
   @Input() @RxStateProperty() amount: number;
+  @Input() @RxStateProperty() comment: string;
 
   @Input() showComment: boolean;
   @Input() dismissOnSubmit: boolean = false; // True is modal
@@ -115,8 +120,6 @@ export class TransferPage extends AppPage<TransferPageState> implements Transfer
         .pipe(
           tap((accounts) => console.debug(this._logPrefix + 'Accounts loaded:', accounts)),
           mergeMap(async (accounts) => {
-
-
             // Load recipient
             const toAddress = this.recipient?.address || this.activatedRoute.snapshot.paramMap.get('to');
             if (isNotNilOrBlank(toAddress)) {
@@ -127,26 +130,31 @@ export class TransferPage extends AppPage<TransferPageState> implements Transfer
         )
     );
 
-    this._state.connect('account', this.accounts$.pipe(
-      switchMap(accounts => merge(
-        this.account$.pipe(map(account => ({accounts, fromAddress: account?.address}))),
-        this.activatedRoute.paramMap.pipe(
-          map(paramMap => ({accounts, fromAddress: paramMap.get('from')})),
-          filter(({fromAddress}) => isNotNilOrBlank(fromAddress))
-        )
-      )),
-      mergeMap(async ({accounts, fromAddress}) => {
-        // Load account
-        if (isNotNilOrBlank(fromAddress)) {
-          return this.accountService.getByAddress(fromAddress);
-        }
-        // Get default
-        else if (isNotEmptyArray(accounts)) {
-          return this.accountService.getDefault();
-        }
-        return undefined;
-      })
-    ));
+    this._state.connect(
+      'account',
+      this.accounts$.pipe(
+        switchMap((accounts) =>
+          merge(
+            this.account$.pipe(map((account) => ({ accounts, fromAddress: account?.address }))),
+            this.activatedRoute.paramMap.pipe(
+              map((paramMap) => ({ accounts, fromAddress: paramMap.get('from') })),
+              filter(({ fromAddress }) => isNotNilOrBlank(fromAddress))
+            )
+          )
+        ),
+        mergeMap(async ({ accounts, fromAddress }) => {
+          // Load account
+          if (isNotNilOrBlank(fromAddress)) {
+            return this.accountService.getByAddress(fromAddress);
+          }
+          // Get default
+          else if (isNotEmptyArray(accounts)) {
+            return this.accountService.getDefault();
+          }
+          return undefined;
+        })
+      )
+    );
 
     this._state.connect('currency', this.networkService.currency$);
 
@@ -230,7 +238,7 @@ export class TransferPage extends AppPage<TransferPageState> implements Transfer
     this.resetError();
 
     try {
-      const hash = await this.accountService.transfer(this.account, this.recipient, this.amount);
+      const hash = await this.accountService.transfer(this.account, this.recipient, this.amount, this.comment);
 
       if (this.showToastOnSubmit) {
         await this.showToast({ message: 'INFO.TRANSFER_SENT' });
@@ -346,4 +354,7 @@ export class TransferPage extends AppPage<TransferPageState> implements Transfer
       if (opts.emitEvent !== false) this.markForCheck();
     }
   }
+
+  protected readonly environment = environment;
+  protected readonly isDemo = isDemo;
 }
diff --git a/src/app/wot/wot-details.page.html b/src/app/wot/wot-details.page.html
index 688edc77bc26bb0ddbdf95ec6c38f5a5c2b92c4b..da9c01e57429f97f02bdead7a922d8a8f1cbe2f4 100644
--- a/src/app/wot/wot-details.page.html
+++ b/src/app/wot/wot-details.page.html
@@ -47,9 +47,13 @@
     </ion-button>
 
     <!-- certify -->
-    <ion-button (click)="certifyTo()" [disabled]="loading">
+    <ion-button (click)="certifyTo()" [disabled]="loading || (canCertify$ | async)">
       <ion-icon slot="start" name="ribbon"></ion-icon>
-      <ion-label translate>WOT.BTN_CERTIFY</ion-label>
+      @if (!isRenewal) {
+        <ion-label translate>WOT.BTN_CERTIFY</ion-label>
+      } @else {
+        <ion-label translate>WOT.BTN_RENEWAL_CERTIFY</ion-label>
+      }
     </ion-button>
   </div>
 
@@ -99,7 +103,9 @@
           } @else {
             <ion-label>
               <h3 translate>COMMON.UID</h3>
-              <p>{{ 'WOT.REGISTERED_SINCE' | translate }}</p>
+              @if (account.meta?.isMember) {
+                <p>{{ 'WOT.REGISTERED_SINCE' | translate }} {{ account.meta.createdOn | date: 'dd/MM/YYYY' }}</p>
+              }
             </ion-label>
 
             <ion-buttons slot="end" class="vertical-alignment">
@@ -113,6 +119,17 @@
           }
         </ion-item>
 
+        <!-- Distance rule -->
+        <ion-item [disabled]="disableDistanceRule()">
+          <ion-icon aria-hidden="true" slot="start" name="logo-steam"></ion-icon>
+          <ion-label translate>
+            HELP.GLOSSARY.DISTANCE_RULE
+            <ion-icon [color]="'tertiary'" name="help-circle-outline" class="tappable" (click)="showModalDistanceRuleDefinition()"></ion-icon>
+          </ion-label>
+          <ion-badge title="{{ titleDistanceRule() }}" color="{{ distanceRuleValid() ? 'success' : 'danger' }}">
+            {{ refereePercent$ | async | percent: '1.1' }}
+          </ion-badge>
+        </ion-item>
         <!-- Received cert count -->
         <ion-item detail [routerLink]="['/wot', 'cert', account.address, account.meta?.uid || '', 'received']" routerDirection="forward">
           <ion-icon aria-hidden="true" slot="start" name="ribbon"></ion-icon>
diff --git a/src/app/wot/wot-details.page.ts b/src/app/wot/wot-details.page.ts
index f70530e9faa37520aa14486be5b55e59ff8fdd5f..5f5f2c22ca87889e5e3c7a112829443263de0c5a 100644
--- a/src/app/wot/wot-details.page.ts
+++ b/src/app/wot/wot-details.page.ts
@@ -9,16 +9,34 @@ import { firstValueFrom, mergeMap, Observable, switchMap } from 'rxjs';
 import { RxState } from '@rx-angular/state';
 import { APP_TRANSFER_CONTROLLER, ITransferController } from '@app/transfer/transfer.model';
 import { filter, map } from 'rxjs/operators';
-import { firstArrayValue, isNotNilOrBlank } from '@app/shared/functions';
+import { firstArrayValue, isNil, isNotEmptyArray, isNotNilOrBlank } from '@app/shared/functions';
 import { IndexerService } from '@app/network/indexer/indexer.service';
 import { address2PubkeyV1, pubkeyV1Checksum } from '@app/shared/currencies';
 import { IdentityStatusEnum } from '@app/network/indexer/indexer-types.generated';
+import { DistanceInformation, WotService } from '@app/wot/wot.service';
+import { NetworkService } from '@app/network/network.service';
+import { HelpPage } from '@app/home/help/help.page';
+import { AlertController, ModalController } from '@ionic/angular';
 
 export interface WotDetailsPageState extends AppPageState {
   address: string;
   account: Account;
   receivedCertCount: number;
   givenCertCount: number;
+  refereePercent: number;
+  distanceInformation: DistanceInformation;
+  accounts: Account[];
+  isRenewal: boolean;
+  canCertify: boolean;
+}
+interface CertificationVerificationStep {
+  labelKey: string;
+  expectedResponse: 'confirm' | 'cancel';
+  order: number;
+}
+interface ModalSequenceConfig {
+  title: string;
+  steps: CertificationVerificationStep[];
 }
 
 @Component({
@@ -33,16 +51,81 @@ export class WotDetailsPage extends AppPage<WotDetailsPageState> implements OnIn
   @RxStateSelect() account$: Observable<Account>;
   @RxStateSelect() receivedCertCount$: Observable<number>;
   @RxStateSelect() givenCertCount$: Observable<number>;
+  @RxStateSelect() refereePercent$: Observable<number>;
+  @RxStateSelect() accounts$: Observable<Account[]>;
+  @RxStateSelect() isRenewal$: Observable<boolean>;
+  @RxStateSelect() canCertify$: Observable<boolean>;
 
   @Input() showToolbar = true;
   @Input() showBalance = false;
   @Input() showToastOnCertify = true;
   @Input() @RxStateProperty() address: string;
   @Input() @RxStateProperty() account: Account;
+  @RxStateProperty() refereePercent: number;
+  @RxStateProperty() distanceInformation: DistanceInformation;
+  @RxStateProperty() accounts: Account[];
+  @RxStateProperty() isRenewal: boolean;
+  @RxStateProperty() canCertify: boolean;
+
+  private readonly certificationSteps: CertificationVerificationStep[] = [
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.WELL_KNOWN',
+      order: 0,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.REVOCATION',
+      order: 1,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.CONTACT',
+      order: 2,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.DOUBLE_IDENTITY',
+      order: 3,
+      expectedResponse: 'cancel',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.MASTER_ACCOUNT',
+      order: 4,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.LICENSE',
+      order: 5,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.CREDENTIALS',
+      order: 6,
+      expectedResponse: 'confirm',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.QUESTIONS.PUBLIC_KEY_DIFFERENT',
+      order: 7,
+      expectedResponse: 'cancel',
+    },
+    {
+      labelKey: 'ACCOUNT.CERTIFICATION_MODAL.SHORT_LICENSE_REMINDER',
+      order: 8,
+      expectedResponse: 'confirm',
+    },
+  ];
+  private readonly certificationModalConfig: ModalSequenceConfig = {
+    title: 'ACCOUNT.CERTIFICATION_MODAL.CHECKLIST_TITLE',
+    steps: this.certificationSteps,
+  };
 
   constructor(
     private accountsService: AccountsService,
     private indexerService: IndexerService,
+    private networkService: NetworkService,
+    private alertCtrl: AlertController,
+    private wotService: WotService,
+    private modalCtrl: ModalController,
     @Inject(APP_TRANSFER_CONTROLLER) private transferController: ITransferController
   ) {
     super({ name: 'wot-details-page' });
@@ -94,6 +177,8 @@ export class WotDetailsPage extends AppPage<WotDetailsPageState> implements OnIn
         map(({ total }) => total)
       )
     );
+
+    this._state.connect('accounts', this.accountsService.watchAll());
   }
 
   ngOnInit() {
@@ -102,7 +187,13 @@ export class WotDetailsPage extends AppPage<WotDetailsPageState> implements OnIn
 
   protected async ngOnLoad(): Promise<WotDetailsPageState> {
     const account = await firstValueFrom(this.account$);
-    return <WotDetailsPageState>{ account };
+    const accounts = await firstValueFrom(this.accounts$);
+
+    const refereePercent = await this.wotService.getRefereePercentByAccount(account);
+    const distanceInformation = await this.wotService.getDistanceInformation(account);
+    const canCertify = await this.enableCertify();
+    const isRenewal = await this.isRenewalCertification(accounts);
+    return <WotDetailsPageState>{ account, accounts, refereePercent, distanceInformation, canCertify, isRenewal };
   }
 
   async copyPubkey(event: UIEvent, pubkey?: string) {
@@ -138,17 +229,36 @@ export class WotDetailsPage extends AppPage<WotDetailsPageState> implements OnIn
 
   async certifyTo() {
     const issuer = await this.accountsService.selectAccount({ isMember: true });
-    if (!issuer) return; // Skip
+    if (!issuer) {
+      await this.showToast({
+        id: 'cert',
+        message: 'INFO.CERTIFICATION_PENDING',
+        duration: -1,
+      });
+      return; // Skip}
+    }
+    const verification = await this.showModalVerification();
+    if (!verification) return; // Skip
 
     this.markAsLoading();
     this.resetError();
 
     try {
-      if (this.showToastOnCertify) await this.showToast({ id: 'cert', message: 'INFO.CERTIFICATION_PENDING', duration: -1 });
+      if (this.showToastOnCertify)
+        await this.showToast({
+          id: 'cert',
+          message: 'INFO.CERTIFICATION_PENDING',
+          duration: -1,
+        });
       const certHash = await this.accountsService.cert(issuer, this.account);
 
       if (this.showToastOnCertify)
-        await this.showToast({ id: 'cert', message: 'INFO.CERTIFICATION_DONE', swipeGesture: 'vertical', color: 'secondary' });
+        await this.showToast({
+          id: 'cert',
+          message: 'INFO.CERTIFICATION_DONE',
+          swipeGesture: 'vertical',
+          color: 'secondary',
+        });
 
       return certHash;
     } catch (err) {
@@ -157,5 +267,99 @@ export class WotDetailsPage extends AppPage<WotDetailsPageState> implements OnIn
     }
   }
 
+  distanceRuleValid(): boolean {
+    return this.refereePercent > this.networkService.currency.params.minAccessibleReferees / 1000000000;
+  }
+
+  disableDistanceRule(): boolean {
+    return isNil(this.refereePercent);
+  }
+
+  titleDistanceRule() {
+    return this.translate.instant('ACCOUNT.TITLE_DISTANCE_RULES', {
+      refereesReached: this.distanceInformation?.refereesReached,
+      refereesCount: this.distanceInformation?.refereesCount,
+      height: this.distanceInformation?.height,
+    });
+  }
+
+  async showModalDistanceRuleDefinition() {
+    const modal = await this.modalCtrl.create({
+      id: 'help-modal',
+      component: HelpPage,
+      componentProps: <HelpPage>{
+        highlightedDefinition: 'GLOSSARY_DISTANCE_RULE',
+      },
+      presentingElement: this._presentingElement,
+      canDismiss: true,
+    });
+    await modal.present();
+  }
+
+  private async showModalVerification(): Promise<boolean> {
+    let confirm = true;
+    console.log(`${this._logPrefix}prepare verification modal`);
+
+    for (const step of this.certificationModalConfig.steps) {
+      const alert = await this.alertCtrl.create({
+        header: this.translate.instant(this.certificationModalConfig.title),
+        message: this.translate.instant(step.labelKey),
+        buttons: [
+          {
+            text: this.translate.instant('COMMON.BTN_NO'),
+            role: 'cancel',
+            cssClass: 'secondary',
+          },
+          {
+            text: this.translate.instant('COMMON.BTN_YES'),
+            role: 'confirm',
+            cssClass: 'primary',
+          },
+        ],
+      });
+      await alert.present();
+      const { role } = await alert.onDidDismiss();
+
+      if (role !== step.expectedResponse) {
+        confirm = false;
+        const warning = await this.alertCtrl.create({
+          header: this.translate.instant(this.certificationModalConfig.title),
+          message: this.translate.instant('ACCOUNT.CERTIFICATION_MODAL.CHECKLIST_CONDITIONS_NOT_MET'),
+          buttons: [
+            {
+              text: this.translate.instant('COMMON.BTN_NO'),
+              role: 'cancel',
+              cssClass: 'secondary',
+            },
+            {
+              text: this.translate.instant('COMMON.BTN_YES'),
+              role: 'confirm',
+              cssClass: 'primary',
+            },
+          ],
+        });
+        await warning.present();
+        break;
+      }
+    }
+
+    return confirm;
+  }
+
+  protected async enableCertify() {
+    const accounts = this.accounts.filter((account) => account.meta.isMember === true);
+    return !isNotEmptyArray(accounts);
+  }
+
+  private async isRenewalCertification(accounts: Account[]) {
+    return (
+      this.canCertify &&
+      (await this.accountsService.isCertValid({
+        receiver: this.account?.address,
+        issuer: accounts[0]?.address,
+      }))
+    );
+  }
+
   protected readonly IdentityStatusEnum = IdentityStatusEnum;
 }
diff --git a/src/app/wot/wot.service.ts b/src/app/wot/wot.service.ts
index 33cf2846b18f30893054112c24830332db4399b3..1230ce35c064ecd31f2f46c47357bab7cdc6fbc2 100644
--- a/src/app/wot/wot.service.ts
+++ b/src/app/wot/wot.service.ts
@@ -10,21 +10,39 @@ 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 { SettingsService } from '@app/settings/settings.service';
+
+export interface DistanceInformation {
+  refereesReached: number;
+  refereesCount: number;
+  minCertsForReferee: number;
+  height: number;
+}
 
 @Injectable({ providedIn: 'root' })
 export class WotService extends StartableService {
   constructor(
     private indexer: IndexerService,
-    private pod: PodService
+    private pod: PodService,
+    private network: NetworkService,
+    private settings: SettingsService
   ) {
     super();
   }
 
   protected async ngOnStart(): Promise<void> {
-    await Promise.all([this.indexer.ready(), this.pod.ready()]);
+    await Promise.all([this.indexer.ready(), this.pod.ready(), this.network.ready()]);
   }
 
-  wotSearch(filter: WotSearchFilter, options: { after?: string; first?: number; fetchPolicy?: FetchPolicy }): Observable<LoadResult<Account>> {
+  wotSearch(
+    filter: WotSearchFilter,
+    options: {
+      after?: string;
+      first?: number;
+      fetchPolicy?: FetchPolicy;
+    }
+  ): Observable<LoadResult<Account>> {
     const search1$ = this.indexer.wotSearch(filter, options).pipe(toArray());
     const search2$ = this.pod.profileSearch(filter, options).pipe(toArray());
 
@@ -62,4 +80,38 @@ export class WotService extends StartableService {
 
     return result;
   }
+
+  async getRefereePercentByAccount(account: Account): Promise<number> {
+    const distanceData: DistancePrecomputionData = await this.getDistanceData();
+    if (!distanceData) {
+      return null;
+    }
+
+    const accountIndex = account?.meta.index;
+    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 accountIndex = account?.meta.index;
+    const refereesReached = distanceData?.results[accountIndex];
+    const refereesCount = distanceData?.referees_count;
+    const minCertsForReferee = distanceData?.min_certs_for_referee;
+    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/assets/feed/1.1/feed-en-GB.json b/src/assets/feed/1.1/feed-en-GB.json
new file mode 100644
index 0000000000000000000000000000000000000000..9509fc7f8c5df8948d2deacaa1726837feac72bc
--- /dev/null
+++ b/src/assets/feed/1.1/feed-en-GB.json
@@ -0,0 +1,9 @@
+{
+  "version": "https://jsonfeed.org/version/1.1",
+  "title": "News",
+  "user_comment": "Ce fichier redirige vers le forum Duniter (via 'next_url')",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-en-GB.json",
+
+  "home_page_url": "https://forum.duniter.org/t/new-version-of-cesium-en/11460",
+  "next_url": "https://forum.duniter.org/t/new-version-of-cesium-en/11460.json"
+}
diff --git a/src/assets/feed/1.1/feed-en.json b/src/assets/feed/1.1/feed-en.json
new file mode 100644
index 0000000000000000000000000000000000000000..4c3547cf76503f80aa580cfbfac43d7cf614365a
--- /dev/null
+++ b/src/assets/feed/1.1/feed-en.json
@@ -0,0 +1,9 @@
+{
+  "version": "https://jsonfeed.org/version/1.1",
+  "title": "News",
+  "user_comment": "Ce fichier redirige vers le forum Duniter (via 'next_url')",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-en.json",
+
+  "home_page_url": "https://forum.duniter.org/t/new-version-of-cesium-en/11460",
+  "next_url": "https://forum.duniter.org/t/new-version-of-cesium-en/11460.json"
+}
diff --git a/src/assets/feed/1.1/feed-es-ES.json b/src/assets/feed/1.1/feed-es-ES.json
new file mode 100644
index 0000000000000000000000000000000000000000..a4b16bdde3ba824c7aac92e454c83923f26e0844
--- /dev/null
+++ b/src/assets/feed/1.1/feed-es-ES.json
@@ -0,0 +1,9 @@
+{
+  "version": "https://jsonfeed.org/version/1.1",
+  "title": "Noticias",
+  "user_comment": "Ce fichier redirige vers le forum Duniter (via 'next_url')",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-es-ES.json",
+
+  "home_page_url": "https://forum.duniter.org/t/nueva-version-de-cesium-es/11459",
+  "next_url": "https://forum.duniter.org/t/nueva-version-de-cesium-es/11459.json"
+}
diff --git a/src/assets/feed/1.1/feed-fr-FR.json b/src/assets/feed/1.1/feed-fr-FR.json
new file mode 100644
index 0000000000000000000000000000000000000000..edaa05d981645c94292b88dfc33c354cabe23cae
--- /dev/null
+++ b/src/assets/feed/1.1/feed-fr-FR.json
@@ -0,0 +1,9 @@
+{
+  "version": "https://jsonfeed.org/version/1.1",
+  "title": "Actualités",
+  "user_comment": "Ce fichier redirige vers le forum Duniter (via 'next_url')",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-fr-FR.json",
+
+  "home_page_url": "https://forum.duniter.org/t/gchange-v2-moderation-ou-et-federation/12910/3",
+  "next_url": "https://forum.duniter.org/t/gchange-v2-moderation-ou-et-federation/12910/3.json"
+}
diff --git a/src/assets/feed/1.1/feed-fr.json b/src/assets/feed/1.1/feed-fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..4ba478df592192c473dbe04f8a54ee59aa059f73
--- /dev/null
+++ b/src/assets/feed/1.1/feed-fr.json
@@ -0,0 +1,9 @@
+{
+  "version": "https://jsonfeed.org/version/1.1",
+  "title": "Actualités",
+  "user_comment": "Ce fichier redirige vers le forum Duniter (via 'next_url')",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-fr-FR.json",
+
+  "home_page_url": "https://forum.duniter.org/t/nouvelle-version-de-cesium-fr/11458/2",
+  "next_url": "https://forum.duniter.org/t/nouvelle-version-de-cesium-fr/11458/2.json"
+}
diff --git a/src/assets/feed/feed-en.json b/src/assets/feed/feed-en.json
new file mode 100644
index 0000000000000000000000000000000000000000..56886b9934dbb0577e5f840ba326c6a7605cb57e
--- /dev/null
+++ b/src/assets/feed/feed-en.json
@@ -0,0 +1,27 @@
+{
+  "version": "https://jsonfeed.org/version/1",
+  "title": "News",
+  "user_comment": "Ce fichier est nécessaire pour les versions avant la 1.7.7",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-en.json",
+
+  "home_page_url": "https://forum.duniter.org/t/nouvelle-version-de-cesium-fr/11458/2",
+  "author": {
+    "name": "Benoit Lavenier",
+    "url": "@BenoitLavenier",
+    "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+  },
+  "items": [
+    {
+      "title": "New version of Cesium",
+      "author": {
+        "name": "Benoit Lavenier",
+        "url": "@BenoitLavenier",
+        "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+      },
+      "date_published": "2023-08-14T19:30:00+02:00",
+      "id": "https://forum.duniter.org/t/new-version-of-cesium-en/11460",
+      "url": "https://forum.duniter.org/t/new-version-of-cesium-en/11460",
+      "content_html": "<p>A new release version of Cesium <a href=\"https://cesium.app\">is available</a>!</p><blockquote><p>The cesium.app website is currently being updated... The same goes for the Play Store, App Store, etc.\nPlease be patient! :slight_smile:</p></blockquote><p>In recent months, many of you have encountered multiple difficulties: transactions disappearing or being completely lost, “timeout” error, desynchronized node, etc.</p><p>We are well aware of these issues. They are related to several factors:</p><ul><li>on the one hand, to the new version 1.7 of Cesium, which introduces automatic node selection for Duniter, by random drawing among synchronized nodes;</li><li>on the other hand, to the state of the Duniter nodes network, some nodes have been found to be misconfigured to work with Cesium, or using unstable versions of Duniter.</li></ul><h2><a name=\"new-features-1\" class=\"anchor\" href=\"#new-features-1\"></a>New Features</h2><h3><a name=\"at-start-up-2\" class=\"anchor\" href=\"#at-start-up-2\"></a>At Start-Up</h3><p>Node selection at startup has been reviewed to select only those compatible with Cesium’s features. This should fix the previously explained problems.</p><h3><a name=\"my-operations-3\" class=\"anchor\" href=\"#my-operations-3\"></a>My Operations</h3><p>In “My Operations,” long comments are now more visible, whether on a phone:<br><img src=\"https://forum.duniter.org/uploads/default/original/2X/4/4fa5d83286441e6689d93b6d636a46771fcb543d.png\" alt=\"image\" data-base62-sha1=\"bmB2vlwdnBe1zK86r7RGiQpJesl\" width=\"594\" height=\"357\"></p><p>…or in a web browser:</p><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png\" data-download-href=\"https://forum.duniter.org/uploads/default/7d081473f9398e237425c96c8b9d55ef81e5662e\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png\" alt=\"image\" data-base62-sha1=\"hQ4ZGoEbNyaKoAMxEGc1d0Ksby6\" width=\"690\" height=\"192\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 2x\" data-dominant-color=\"F2F6F8\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">819×229 36.5 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Other small improvements on this page:</p><ul><li>Refreshing the list no longer causes flickering of existing operations. Only new operations are animated;</li><li>loading older operations (at the bottom of the page) is now done directly by scrolling down. No need to click on “Show More” or “Show All”! Beyond 6 months of history, these buttons appear to limit the number of network requests.<br><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png\" data-download-href=\"https://forum.duniter.org/uploads/default/8617ad8aa899debbc16bd92f38f1eefe68ed4699\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png\" alt=\"image\" data-base62-sha1=\"j8eI3VQg2QseXemuowxFVl8qFlf\" width=\"690\" height=\"211\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png, https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_1035x316.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png 2x\" data-dominant-color=\"F7F9FA\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">1094×335 36.1 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></li></ul><h3><a name=\"networks-in-expert-mode-4\" class=\"anchor\" href=\"#networks-in-expert-mode-4\"></a>Networks (in expert mode)</h3><p>The network view now allows you to see the status of the waiting queues (or pools) containing pending documents (transactions and membership requests).</p><blockquote><p>Only if you have activated “expert mode” in the settings,<br>and for nodes that have activated the BMA API</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f475de5c8c5f2e8efa21e33a387c3262a33eded5\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png\" alt=\"image\" data-base62-sha1=\"ySB2aVf3V1kcQ5aWwasCVNCX9kN\" width=\"690\" height=\"258\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 2x\" data-dominant-color=\"F3F7F4\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">781×293 36.4 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Another small novelty: you can now see if a node (BMA) properly archives the history of transactions. The symbol <strong><img src=\"https://forum.duniter.org/images/emoji/twitter/credit_card.png?v=12\" title=\":credit_card:\" class=\"emoji\" alt=\":credit_card:\" loading=\"lazy\" width=\"20\" height=\"20\"> <code>TX</code></strong> now appears in the <code>API</code> column.</p><blockquote><p>Only visible in expert mode, by <strong>expanding the display</strong> of rows</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f6c5abe0063f927df3b6a1814f3265d611c4ac4c\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png\" alt=\"image\" data-base62-sha1=\"zd2XW5qedxuZ7gjgSiRiYV6K2D2\" width=\"690\" height=\"40\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 2x\" data-dominant-color=\"EFF3F1\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">787×46 8.14 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><h3><a name=\"other-fixes-5\" class=\"anchor\" href=\"#other-fixes-5\"></a>Other Fixes</h3><ul><li>Android / iOS: file downloading works! For the revocation file in particular, but also for the list of operations, the saving of identifiers, etc.<blockquote><p>You will find the downloaded file in the “Downloads” directory (on Android) or “Documents” (on iOS);</p></blockquote></li><li>My Operations: the list of UDs is now correctly displayed (without going through the Duniter nodes to bypass a limitation, but through the Cesium+ pod if activated);</li><li>Notifications: the number of messages or notifications is now correct when you log in for the first time on an account.</li></ul><br/><br/>(...)"
+    }
+  ]
+}
diff --git a/src/assets/feed/feed-es.json b/src/assets/feed/feed-es.json
new file mode 100644
index 0000000000000000000000000000000000000000..96302df9ae049451f097f0c96ac2220a65f183ff
--- /dev/null
+++ b/src/assets/feed/feed-es.json
@@ -0,0 +1,27 @@
+{
+  "version": "https://jsonfeed.org/version/1",
+  "title": "News",
+  "user_comment": "Ce fichier est nécessaire pour les versions avant la 1.7.7",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-es.json",
+
+  "home_page_url": "https://forum.duniter.org/t/nueva-version-de-cesium-es/11459/3",
+  "author": {
+    "name": "Benoit Lavenier",
+    "url": "@BenoitLavenier",
+    "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+  },
+  "items": [
+    {
+      "title": "Nueva versión de Cesium",
+      "author": {
+        "name": "Benoit Lavenier",
+        "url": "@BenoitLavenier",
+        "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+      },
+      "date_published": "2023-08-14T19:30:00+02:00",
+      "id": "https://forum.duniter.org/t/nueva-version-de-cesium-es/11459",
+      "url": "https://forum.duniter.org/t/nueva-version-de-cesium-es/11459",
+      "content_html": "<p>¡Una nueva versión de Cesium <a href=\"https://cesium.app\">está disponible</a>!</p><blockquote><p>El sitio cesium.app está siendo actualizado... Lo mismo para Play Store, App Store, etc.\n¡Tengan paciencia!</p></blockquote><p>En los últimos meses, muchos de ustedes han encontrado múltiples dificultades: transacciones que desaparecen o se pierden completamente, error de “tiempo de espera excedido”, nodo desincronizado, etc.</p><p>Somos muy conscientes de estos problemas. Están relacionados con varios factores:</p><ul><li>por un lado, a la nueva versión 1.7 de Cesium, que introduce la selección automática del nodo Duniter, mediante sorteo entre los nodos sincronizados;</li><li>por otro lado, al estado de la red de nodos Duniter, algunos de los cuales se han revelado mal configurados para funcionar con Cesium, o utilizando versiones inestables de Duniter.</li></ul><h2><a name=\"novedades-1\" class=\"anchor\" href=\"#novedades-1\"></a>Novedades</h2><h3><a name=\"al-inicio-2\" class=\"anchor\" href=\"#al-inicio-2\"></a>Al inicio</h3><p>La selección de nodos al inicio ha sido revisada, para seleccionar solo aquellos compatibles con las funcionalidades de Cesium. Esto debería corregir los problemas explicados anteriormente.</p><h3><a name=\"mis-operaciones-3\" class=\"anchor\" href=\"#mis-operaciones-3\"></a>Mis operaciones</h3><p>En “Mis operaciones”, los comentarios largos son ahora más visibles, ya sea en un teléfono:<br><img src=\"https://forum.duniter.org/uploads/default/original/2X/4/4fa5d83286441e6689d93b6d636a46771fcb543d.png\" alt=\"image\" data-base62-sha1=\"bmB2vlwdnBe1zK86r7RGiQpJesl\" width=\"594\" height=\"357\"></p><p>…o en un navegador web:</p><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png\" data-download-href=\"https://forum.duniter.org/uploads/default/7d081473f9398e237425c96c8b9d55ef81e5662e\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png\" alt=\"image\" data-base62-sha1=\"hQ4ZGoEbNyaKoAMxEGc1d0Ksby6\" width=\"690\" height=\"192\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 2x\" data-dominant-color=\"F2F6F8\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">819×229 36.5 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Otras pequeñas mejoras en esta página:</p><ul><li>El hecho de refrescar la lista ya no provoca el parpadeo de las operaciones existentes. Solo las nuevas operaciones están animadas;</li><li>la carga de las operaciones más antiguas (en la parte inferior de la página) se hace directamente desplazándose hacia abajo. ¡No es necesario hacer clic en “Mostrar más” o “Mostrar todo”! Más allá de 6 meses de historial, estos botones aparecen para limitar el número de solicitudes a la red.<br><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png\" data-download-href=\"https://forum.duniter.org/uploads/default/8617ad8aa899debbc16bd92f38f1eefe68ed4699\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png\" alt=\"image\" data-base62-sha1=\"j8eI3VQg2QseXemuowxFVl8qFlf\" width=\"690\" height=\"211\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png, https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_1035x316.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png 2x\" data-dominant-color=\"F7F9FA\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">1094×335 36.1 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></li></ul><h3><a name=\"redes-en-modo-experto-4\" class=\"anchor\" href=\"#redes-en-modo-experto-4\"></a>Redes (en modo experto)</h3><p>La vista de red permite ahora ver el estado de las colas de espera (o piscinas) que contienen los documentos pendientes (transacciones y solicitudes de membresía).</p><blockquote><p>Solo si ha activado el “modo experto” en la configuración,<br>y para los nodos que han activado la API BMA</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f475de5c8c5f2e8efa21e33a387c3262a33eded5\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png\" alt=\"image\" data-base62-sha1=\"ySB2aVf3V1kcQ5aWwasCVNCX9kN\" width=\"690\" height=\"258\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 2x\" data-dominant-color=\"F3F7F4\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">781×293 36.4 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Otra pequeña novedad: ahora puede ver si un nodo (BMA) archiva correctamente el historial de transacciones. El símbolo <strong><img src=\"https://forum.duniter.org/images/emoji/twitter/credit_card.png?v=12\" title=\":credit_card:\" class=\"emoji\" alt=\":credit_card:\" loading=\"lazy\" width=\"20\" height=\"20\"> <code>TX</code></strong> aparece ahora en la columna <code>API</code>.</p><blockquote><p>Solo visible en modo experto, al <strong>expandir la visualización</strong> de las filas</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f6c5abe0063f927df3b6a1814f3265d611c4ac4c\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png\" alt=\"image\" data-base62-sha1=\"zd2XW5qedxuZ7gjgSiRiYV6K2D2\" width=\"690\" height=\"40\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 2x\" data-dominant-color=\"EFF3F1\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">787×46 8.14 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><h3><a name=\"otras-correcciones-5\" class=\"anchor\" href=\"#otras-correcciones-5\"></a>Otras correcciones</h3><ul><li>Android / iOS: ¡la descarga de archivos funciona! Para el archivo de revocación en particular, pero también para la lista de operaciones, la salvaguardia de identificadores, etc.<blockquote><p>Encontrarás el archivo descargado en el directorio “Descargas” (en Android) o “Documentos” (en iOS);</p></blockquote></li><li>Mis operaciones: la lista de UDs se muestra ahora correctamente (sin pasar por los nodos Duniter para eludir una limitación, pero a través del pod Cesium+ si está activado);</li><li>Notificaciones: el número de mensajes o notificaciones es ahora correcto cuando inicia sesión por primera vez en una cuenta.</li></ul><br/><br/>(...)"
+    }
+  ]
+}
diff --git a/src/assets/feed/feed-fr.json b/src/assets/feed/feed-fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..a4196df900223e9e91b7eaae768e3a20ad962862
--- /dev/null
+++ b/src/assets/feed/feed-fr.json
@@ -0,0 +1,26 @@
+{
+  "version": "https://jsonfeed.org/version/1",
+  "title": "Actualités",
+  "user_comment": "Ce fichier est nécessaire pour les versions avant la 1.7.7",
+  "feed_url": "https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-ff.json",
+  "home_page_url": "https://forum.duniter.org/t/nouvelle-version-de-cesium-fr/11458/2",
+  "author": {
+    "name": "Benoit Lavenier",
+    "url": "@BenoitLavenier",
+    "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+  },
+  "items": [
+    {
+      "title": "Nouvelle version de Cesium",
+      "author": {
+        "name": "Benoit Lavenier",
+        "url": "@BenoitLavenier",
+        "avatar": "https://forum.duniter.org//user_avatar/forum.duniter.org/kimamila/48/185_2.png"
+      },
+      "date_published": "2024-01-14T19:30:00+02:00",
+      "id": "https://forum.duniter.org/t/nouvelle-version-de-cesium/11458",
+      "url": "https://forum.duniter.org/t/nouvelle-version-de-cesium/11458",
+      "content_html": "<p>Une nouvelle version de Cesium <a href=\"https://cesium.app\">est disponible</a> !</p><blockquote><p>La mise jour du site et des Play Store est en cours.\nSoyez patient !</p></blockquote><p>Ces derniers mois, beaucoup d’entre vous ont rencontré des difficultés multiples : transactions qui disparaissent ou sont carrément perdues, erreur “délai d’attente dépassé”, nœud désynchronisé, etc.</p><p>Nous sommes bien conscients de ces problèmes. Ils sont liés à plusieurs facteurs :</p><ul><li>d’une part, à la nouvelle version 1.7 de Cesium, qui introduit la sélection automatique du nœud Duniter, par tirage au sort parmi les nœuds synchronisés ;</li><li>d’autre part, à l’état du réseau des nœuds Duniter, dont certains nœuds se sont révélés mal configurés pour fonctionner avec Cesium, ou utilisant des versions de Duniter non stables.</li></ul><h2><a name=\"nouveauts-1\" class=\"anchor\" href=\"#nouveauts-1\"></a>Nouveautés</h2><h3><a name=\"au-dmarrage-2\" class=\"anchor\" href=\"#au-dmarrage-2\"></a>Au démarrage</h3><p>La sélection des nœuds au démarrage a été revue, pour ne sélectionner que ceux compatibles avec les fonctionnalités de Cesium. Ceci devrait corriger les problèmes précédemment expliqués.</p><h3><a name=\"mes-oprations-3\" class=\"anchor\" href=\"#mes-oprations-3\"></a>Mes opérations</h3><p>Dans “Mes opérations”, les longs commentaires sont mieux visibles, que ce soit sur téléphone :<br><img src=\"https://forum.duniter.org/uploads/default/original/2X/4/4fa5d83286441e6689d93b6d636a46771fcb543d.png\" alt=\"image\" data-base62-sha1=\"bmB2vlwdnBe1zK86r7RGiQpJesl\" width=\"594\" height=\"357\"></p><p>…ou dans un navigateur web :</p><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png\" data-download-href=\"https://forum.duniter.org/uploads/default/7d081473f9398e237425c96c8b9d55ef81e5662e\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png\" alt=\"image\" data-base62-sha1=\"hQ4ZGoEbNyaKoAMxEGc1d0Ksby6\" width=\"690\" height=\"192\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e_2_690x192.png, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/7/7d081473f9398e237425c96c8b9d55ef81e5662e.png 2x\" data-dominant-color=\"F2F6F8\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">819×229 36.5 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Autres petites améliorations sur cette page :</p><ul><li>Le fait de rafraîchir la liste ne provoque plus de clignotement des opérations déjà existantes. Seules les nouvelles opérations sont animées ;</li><li>le chargement des opérations plus anciennes (en bas de page) se fait directement par défilement vers le bas. Plus besoin de cliquer sur “Afficher plus” ou “Afficher tout” ! Au-delà de 6 mois d’historique, ces boutons apparaissent, pour limiter le nombre de requêtes au réseau.<br><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png\" data-download-href=\"https://forum.duniter.org/uploads/default/8617ad8aa899debbc16bd92f38f1eefe68ed4699\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png\" alt=\"image\" data-base62-sha1=\"j8eI3VQg2QseXemuowxFVl8qFlf\" width=\"690\" height=\"211\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_690x211.png, https://forum.duniter.org/uploads/default/optimized/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699_2_1035x316.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/8/8617ad8aa899debbc16bd92f38f1eefe68ed4699.png 2x\" data-dominant-color=\"F7F9FA\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">1094×335 36.1 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></li></ul><h3><a name=\"rseaux-en-mode-expert-4\" class=\"anchor\" href=\"#rseaux-en-mode-expert-4\"></a>Réseaux (en mode expert)</h3><p>La vue réseau permet maintenant de voir l’état des files d’attente (ou piscines) contenant les documents en attente (transactions et demandes d’adhésion).</p><blockquote><p>Uniquement si vous avez activé le “mode expert” dans les paramètres,<br>et pour les nœuds ayant activé l’API BMA</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f475de5c8c5f2e8efa21e33a387c3262a33eded5\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png\" alt=\"image\" data-base62-sha1=\"ySB2aVf3V1kcQ5aWwasCVNCX9kN\" width=\"690\" height=\"258\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5_2_690x258.png, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f475de5c8c5f2e8efa21e33a387c3262a33eded5.png 2x\" data-dominant-color=\"F3F7F4\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">781×293 36.4 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><p>Autre petite nouveauté : vous pouvez voir si un nœud (BMA) archive bien l’historique des transactions. Le symbole <strong><img src=\"https://forum.duniter.org/images/emoji/twitter/credit_card.png?v=12\" title=\":credit_card:\" class=\"emoji\" alt=\":credit_card:\" loading=\"lazy\" width=\"20\" height=\"20\"> <code>TX</code></strong> s’affiche maintenant, dans la colonne <code>API</code>.</p><blockquote><p>Visible uniquement en mode expert, en <strong>décompactant l’affichage</strong> des lignes</p></blockquote><p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png\" data-download-href=\"https://forum.duniter.org/uploads/default/f6c5abe0063f927df3b6a1814f3265d611c4ac4c\" title=\"image\"><img src=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png\" alt=\"image\" data-base62-sha1=\"zd2XW5qedxuZ7gjgSiRiYV6K2D2\" width=\"690\" height=\"40\" srcset=\"https://forum.duniter.org/uploads/default/optimized/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c_2_690x40.png, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 1.5x, https://forum.duniter.org/uploads/default/original/2X/f/f6c5abe0063f927df3b6a1814f3265d611c4ac4c.png 2x\" data-dominant-color=\"EFF3F1\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use href=\"#far-image\"></use></svg><span class=\"filename\">image</span><span class=\"informations\">787×46 8.14 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use href=\"#discourse-expand\"></use></svg></div></a></div></p><h3><a name=\"autres-correctifs-5\" class=\"anchor\" href=\"#autres-correctifs-5\"></a>Autres correctifs</h3><ul><li>Android / iOS : le téléchargement de fichier fonctionne ! Pour le fichier de révocation notamment, mais aussi pour la liste des opérations, la sauvegarde des identifiants, etc.<blockquote><p>Vous trouverez le fichier téléchargé dans le répertoire “Téléchargements” (sous Android) ou “Documents” (sous iOS) ;</p></blockquote></li><li>Mes opérations : la liste des DU s’affiche maintenant correctement (sans passer par les nœuds Duniter pour contourner une limitation, mais par le pod Cesium+ s’il est activé) ;</li><li>Notifications : le nombre de messages ou de notifications est maintenant correct lorsque vous vous connectez pour la première fois sur un compte.</li></ul><br/> (...)"
+    }
+  ]
+}
diff --git a/src/assets/i18n/ca.json b/src/assets/i18n/ca.json
index 8ff034abebd1045c00300cca2166bcaab1bf717a..db0eaeff0a98e86854ea449796c4b79320506020 100644
--- a/src/assets/i18n/ca.json
+++ b/src/assets/i18n/ca.json
@@ -135,7 +135,8 @@
     "CONNECTION_ERROR": "Node <b>{{server}}</b> inabastable o adreça invàlida.<br/><br/>Comproveu bé la vostra connexió a Internet, o el node Duniter <a class=\"positive\" ng-click=\"doQuickFix('settings')\">als ajustos</a>.",
     "SHOW_ALL_FEED": "Veure-ho tot",
     "READ_MORE": "Llegiu més",
-    "FEED_SOURCE": "Font"
+    "FEED_SOURCE": "Font",
+    "NEWS": "Notícies"
   },
   "SETTINGS": {
     "TITLE": "Ajustos",
@@ -174,6 +175,11 @@
       "HOUR": "Després de {{value}}h d'inactivitat",
       "ALWAYS": "Al final de la sessió"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Cada dia",
+      "WEEKLY": "Cada setmana",
+      "MONTHLY": "Cada mes"
+    },
     "KEYRING_FILE": "Arxiu de claus",
     "KEYRING_FILE_HELP": "Us permet <b>connectar-vos</b> automàticament a cada inici <br/>i fins i tot <b>autenticar-vos</b> (només si \"Caducitat de l'autenticació\" està configurada en mode: \"al final de la sessió\").",
     "REMEMBER_ME": "Recordar-me",
@@ -328,6 +334,7 @@
     "MIRROR": "mirall",
     "MIRRORS": "Miralls",
     "MIRROR_PEERS": "Nodes mirall",
+    "CUSTOM_PEER": "Introduïu un node",
     "PEER_LIST": "Llista de nodes",
     "MEMBERS": "Membre",
     "MEMBER_PEERS": "Nodes membre",
@@ -374,6 +381,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Es tracta d'un moneder simple, sense solicitud d'inscripció en espera",
     "TECHNICAL_DIVIDER": "Informacions tècniques",
     "BTN_CERTIFY": "Certificar",
+    "BTN_RENEWAL_CERTIFY": "Renovar",
     "BTN_YES_CERTIFY": "Sí, certificar",
     "BTN_SELECT_AND_CERTIFY": "Nova certificació",
     "ACCOUNT_OPERATIONS": "Transaccions del compte",
@@ -524,6 +532,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Cancelar la membresía…",
     "BTN_SECURITY_DOTS": "Cuenta i seguridad…",
     "BTN_SHOW_DETAILS": "Publicar la información técnica",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} al bloc {{height}}",
+    "MEMBER_CONVERT_FAILED": "Error en la sol·licitud, no compleixes totes les normes de la xarxa de confiança.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Importe blocado",
       "DESCRIPTION": "Aquí están las condiciones para desblocar este importe:",
@@ -671,6 +681,23 @@
       "TIME": "Fecha",
       "AMOUNT": "Cantidad",
       "COMMENT": "Comentario"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Llista de verificacions abans de la certificació",
+      "INFOS": "La seguretat de la moneda Ğ1 recau sobre cada membre. Abans de certificar la identitat d'aquesta persona, cal que realitzis algunes verificacions. Si us plau, respon a les següents preguntes:",
+      "BTN_ALL_CHECK": "Certificar",
+      "CHECKLIST_CONDITIONS_NOT_MET": "La certificació no s'ha enviat. Les verificacions semblen insuficients. Si us plau, verifica de nou cada punt amb la persona a certificar.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>Coneixes bé</b> la persona que vols certificar, i coneixes altres persones que també la coneixen bé?",
+        "REVOCATION": "Ha descarregat el seu <b>document de revocació</b> i sap on trobar-lo?",
+        "CONTACT": "Has <b>contactat</b> amb aquesta persona per diversos mitjans i t'ha respost?",
+        "DOUBLE_IDENTITY": "La persona ha de tenir <b>una sola identitat de membre activa</b>. En té alguna <b>altra</b>?",
+        "MASTER_ACCOUNT": "Domina el seu compte i ja ha <b>enviat diners des del seu compte</b> com a mínim una vegada?",
+        "LICENSE": "Ha <b>entès la llicència</b> i accepta complir-la per a la certificació d'altres membres?",
+        "CREDENTIALS": "L'identificador i la contrasenya del seu compte són <b>suficientment llargs i complexos</b>? Ha entès que tant la contrasenya com la frase secreta han de romandre secret? Està segur que en recordarà o que podrà trobar-los?",
+        "PUBLIC_KEY_DIFFERENT": "La <b>clau pública</b> indicada ha de ser <b>idèntica</b> a la que aquesta persona t'ha donat. Les claus són <b>diferents</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "Pots recordar a la persona certificada els paràmetres de les certificacions:<br/><br/><ul><li> - Cada membre pot emetre com a màxim 100 certificacions vàlides.</li><li> - Les certificacions es registren amb un interval de 5 dies.</li><li> - Una nova identitat de membre ha de reunir com a mínim 5 certificacions en menys de dos mesos.</li><li> - Un membre ha de renovar la seva afiliació cada any.</li><li> - Les certificacions són vàlides durant dos anys.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -737,6 +764,7 @@
     "GET_CURRENCY_PARAMETER": "Error en la recuperación de les regles de moneda.",
     "GET_CURRENCY_FAILED": "Carga de la moneda imposible. Si us plau, intente más tarde.",
     "SEND_TX_FAILED": "Error en la transferencia.",
+    "CLAIM_UD_FAILED": "S'ha produït un error en reclamar el dividend universal.",
     "ALL_SOURCES_USED": "Si us plau, espera el càlcul del bloc siguiente (Todas sus fuentes de moneda fueron utilizada).",
     "NOT_ENOUGH_SOURCES": "No lo bastante cambio para mandar este importe en una sola transacció.<br/>Importe máximo: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Error en la creación de la compte membre.",
diff --git a/src/assets/i18n/en-GB.json b/src/assets/i18n/en-GB.json
index 898c2a5ea9b09a0094c350a6a42a408a19858d67..47b2a8275bde18d76dd99ba41210db0a542aa31c 100644
--- a/src/assets/i18n/en-GB.json
+++ b/src/assets/i18n/en-GB.json
@@ -134,7 +134,8 @@
     "CONNECTION_ERROR": "Peer <b>{{server}}</b> unreachable or invalid address.<br/><br/>Check your Internet connection, or change node <a class=\"positive\" ng-click=\"doQuickFix('settings')\">in the settings</a>.",
     "SHOW_ALL_FEED": "Show all",
     "READ_MORE": "Read more",
-    "FEED_SOURCE": "Source"
+    "FEED_SOURCE": "Source",
+    "NEWS": "News"
   },
   "SETTINGS": {
     "TITLE": "Settings",
@@ -171,6 +172,11 @@
       "HOUR": "After {{value}}h of inactivity",
       "ALWAYS": "At the end of the session"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Every day",
+      "WEEKLY": "Every week",
+      "MONTHLY": "Every month"
+    },
     "KEYRING_FILE": "Keyring file",
     "KEYRING_FILE_HELP": "Allow auto-connect at startup, or to authenticate (only if \"Expiration of authentication\" is \"at the end of the session\"",
     "REMEMBER_ME": "Remember me ?",
@@ -322,6 +328,7 @@
     "MIRROR": "mirror",
     "MIRRORS": "Mirrors",
     "MIRROR_PEERS": "Mirror peers",
+    "CUSTOM_PEER": "Enter a peer",
     "PEER_LIST": "Peer's list",
     "MEMBERS": "Members",
     "MEMBER_PEERS": "Member peers",
@@ -368,6 +375,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "This is a simple wallet, with no pending membership application.",
     "TECHNICAL_DIVIDER": "Technical data",
     "BTN_CERTIFY": "Certify",
+    "BTN_RENEWAL_CERTIFY": "Renew",
     "BTN_YES_CERTIFY": "Yes, certify",
     "BTN_SELECT_AND_CERTIFY": "New certification",
     "ACCOUNT_OPERATIONS": "Account operations",
@@ -512,6 +520,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Revoke membership...",
     "BTN_SECURITY_DOTS": "Sign-in and security...",
     "BTN_SHOW_DETAILS": "Display technical data",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} au bloc {{height}}",
+    "MEMBER_CONVERT_FAILED": "Request failed, you do not meet all the rules of the web of trust.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Locked amount",
       "DESCRIPTION": "Here are the conditions for unlocking this amount:",
@@ -659,6 +669,23 @@
       "TIME": "Date",
       "AMOUNT": "Amount",
       "COMMENT": "Comment"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Certification check list",
+      "INFOS": "Each member is responsible for the security of Äž1 currency. Before certifying this person's identity, you should have performed few checks. Please answer following questions:",
+      "BTN_ALL_CHECK": "Certify",
+      "CHECKLIST_CONDITIONS_NOT_MET": "The certification has not been sent. All answers are not right. Please recheck each point with the person to be certified.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "Do you know <b>well</b> the person you are about to certify? Do you know other people who also know this person well?",
+        "REVOCATION": "Has this person downloaded their <b>revocation document</b> and do they know where to find it?",
+        "CONTACT": "Have you <b>had contact</b> with this person by many means, and did they answer?",
+        "DOUBLE_IDENTITY": "The person should own <b>only one active member identity</b>. Do you think they own another one?",
+        "MASTER_ACCOUNT": "Does this person own their accounts secrets? Have they already <b>sent money from their account</b> at least once?",
+        "LICENSE": "Has this person <b>understood the Duniter license</b>? Do they agree to comply with it for future certifications?",
+        "CREDENTIALS": "Was the account created with <b>long and complex secret identifier and password</b> (ex. passphrases)? Did the person understand that both secret identifier and password must remain secret ? Are they <b>sure to remember them</b> or to be able to find them?",
+        "PUBLIC_KEY_DIFFERENT": "The <b>public key</b> that is shown must be <b>identical</b> to the one the person gave you. The public keys are they <b>different</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "You may remind the person to certify different certification parameters:<br/><br/><ul><li> - Each member can certify 100 other identities at most.</li><li> - The certifications are saved with a 5 days interval.</li><li> - A new identity must gather at least 5 certifications in less than 2 months.</li><li>- A member must renew its membership at least once a year.</li><li> - Certifications have a lifespan of two years.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -716,6 +743,7 @@
     "GET_CURRENCY_PARAMETER": "Could not get currency parameters.",
     "GET_CURRENCY_FAILED": "Could not load currency. Please retry later.",
     "SEND_TX_FAILED": "Could not send transaction.",
+    "CLAIM_UD_FAILED": "An error occurred while claiming your Universal Dividend.",
     "ALL_SOURCES_USED": "Please wait the next block computation (All transaction sources has been used).",
     "NOT_ENOUGH_SOURCES": "Not enough changes to send this amount in one time.<br/>Maximum amount: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Error while creating your member account.",
@@ -842,7 +870,7 @@
       "INSTALL_HELP": "For <b>security reasons</b> we recommend <b>installing</b> your copy of the software.<br/> Visit the site <a href='https://cesium.app'>www.cesium.app</a> for help."
     },
     "READONLY": {
-      "BADGE": "Monit",
+      "BADGE": "Dev mode",
       "MODE": "Monitoring mode",
       "MODE_HELP": "Cesium works in <b>monitoring mode</b>: only currency monitoring features are available.",
       "INSTALL_HELP": "If you want to <b>create a wallet account</b> to send or received money, we recommend <b>installing</b> your copy of the software.<br/> Visit the site <a href='https://cesium.app'>www.cesium.app</a> for help."
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 7ba358e787d91144578f0d56d670719c0590ec71..9fb124558c13d617982941c36d3f06664d40307c 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -135,7 +135,8 @@
     "CONNECTION_ERROR": "Peer <b>{{server}}</b> unreachable or invalid address.<br/><br/>Check your Internet connection, or change node <a class=\"positive\" ng-click=\"doQuickFix('settings')\">in the settings</a>.",
     "SHOW_ALL_FEED": "Show all",
     "READ_MORE": "Read more",
-    "FEED_SOURCE": "Source"
+    "FEED_SOURCE": "Source",
+    "NEWS": "News"
   },
   "SETTINGS": {
     "TITLE": "Settings",
@@ -172,6 +173,11 @@
       "HOUR": "After {{value}}h of inactivity",
       "ALWAYS": "At the end of the session"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Every day",
+      "WEEKLY": "Every week",
+      "MONTHLY": "Every month"
+    },
     "KEYRING_FILE": "Keyring file",
     "KEYRING_FILE_HELP": "Allow auto-connect at startup, or to authenticate (only if \"Expiration of authentication\" is \"at the end of the session\"",
     "REMEMBER_ME": "Remember me ?",
@@ -323,6 +329,7 @@
     "MIRROR": "mirror",
     "MIRRORS": "Mirrors",
     "MIRROR_PEERS": "Mirror peers",
+    "CUSTOM_PEER": "Enter a peer",
     "PEER_LIST": "Peer's list",
     "MEMBERS": "Members",
     "MEMBER_PEERS": "Member peers",
@@ -370,6 +377,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "This is a simple wallet, with no pending membership application.",
     "TECHNICAL_DIVIDER": "Technical data",
     "BTN_CERTIFY": "Certify",
+    "BTN_RENEWAL_CERTIFY": "Renew",
     "BTN_YES_CERTIFY": "Yes, certify",
     "BTN_SELECT_AND_CERTIFY": "New certification",
     "ACCOUNT_OPERATIONS": "Account operations",
@@ -531,6 +539,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Revoke membership...",
     "BTN_SECURITY_DOTS": "Sign-in and security...",
     "BTN_SHOW_DETAILS": "Display technical data",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} au bloc {{height}}",
+    "MEMBER_CONVERT_FAILED": "Request failed, you do not meet all the rules of the web of trust.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Locked amount",
       "DESCRIPTION": "Here are the conditions for unlocking this amount:",
@@ -679,6 +689,23 @@
       "TIME": "Date",
       "AMOUNT": "Amount",
       "COMMENT": "Comment"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Certification check list",
+      "INFOS": "Each member is responsible for the security of Äž1 currency. Before certifying this person's identity, you should have performed few checks. Please answer following questions:",
+      "BTN_ALL_CHECK": "Certify",
+      "CHECKLIST_CONDITIONS_NOT_MET": "The certification has not been sent. All answers are not right. Please recheck each point with the person to be certified.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "Do you know <b>well</b> the person you are about to certify? Do you know other people who also know this person well?",
+        "REVOCATION": "Has this person downloaded their <b>revocation document</b> and do they know where to find it?",
+        "CONTACT": "Have you <b>had contact</b> with this person by many means, and did they answer?",
+        "DOUBLE_IDENTITY": "The person should own <b>only one active member identity</b>. Do you think they own another one?",
+        "MASTER_ACCOUNT": "Does this person own their accounts secrets? Have they already <b>sent money from their account</b> at least once?",
+        "LICENSE": "Has this person <b>understood the Duniter license</b>? Do they agree to comply with it for future certifications?",
+        "CREDENTIALS": "Was the account created with <b>long and complex secret identifier and password</b> (ex. passphrases)? Did the person understand that both secret identifier and password must remain secret ? Are they <b>sure to remember them</b> or to be able to find them?",
+        "PUBLIC_KEY_DIFFERENT": "The <b>public key</b> that is shown must be <b>identical</b> to the one the person gave you. The public keys are they <b>different</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "You may remind the person to certify different certification parameters:<br/><br/><ul><li> - Each member can certify 100 other identities at most.</li><li> - The certifications are saved with a 5 days interval.</li><li> - A new identity must gather at least 5 certifications in less than 2 months.</li><li>- A member must renew its membership at least once a year.</li><li> - Certifications have a lifespan of two years.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -740,6 +767,7 @@
     "GET_CURRENCY_PARAMETER": "Could not get currency parameters.",
     "GET_CURRENCY_FAILED": "Could not load currency. Please retry later.",
     "SEND_TX_FAILED": "Could not send transaction.",
+    "CLAIM_UD_FAILED": "An error occurred while claiming your Universal Dividend.",
     "ALL_SOURCES_USED": "Please wait the next block computation (All transaction sources has been used).",
     "NOT_ENOUGH_SOURCES": "Not enough changes to send this amount in one time.<br/>Maximum amount: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Error while creating your member account.",
@@ -868,7 +896,7 @@
       "INSTALL_HELP": "For <b>security reasons</b> we recommend <b>installing</b> your copy of the software.<br/> Visit the site <a href='https://cesium.app'>www.cesium.app</a> for help."
     },
     "READONLY": {
-      "BADGE": "Monit",
+      "BADGE": "Dev mode",
       "MODE": "Monitoring mode",
       "MODE_HELP": "Cesium works in <b>monitoring mode</b>: only currency monitoring features are available.",
       "INSTALL_HELP": "If you want to <b>create a wallet account</b> to send or received money, we recommend <b>installing</b> your copy of the software.<br/> Visit the site <a href='https://cesium.app'>www.cesium.app</a> for help."
diff --git a/src/assets/i18n/eo-EO.json b/src/assets/i18n/eo-EO.json
index 931fbd430c497c46c6437ba140165d6a332972d1..39c1d4572170a7a64130577026c1dea8d1ea1ebd 100644
--- a/src/assets/i18n/eo-EO.json
+++ b/src/assets/i18n/eo-EO.json
@@ -134,7 +134,8 @@
     "CONNECTION_ERROR": "Nodo <b>{{server}}</b> neatingebla aŭ adreso nevalida.<br/><br/>Kontrolu vian retkonekton, aŭ elektu alian nodon <a class=\"positive\" ng-click=\"doQuickFix('settings')\">ĉe la parametroj</a>.",
     "SHOW_ALL_FEED": "Vidi ĉion",
     "READ_MORE": "Legi la sekvon",
-    "FEED_SOURCE": "Fonto"
+    "FEED_SOURCE": "Fonto",
+    "NEWS": "Novaĵoj"
   },
   "SETTINGS": {
     "TITLE": "Parametroj",
@@ -170,6 +171,11 @@
       "HOUR": "Post {{value}}h de neatktiveco",
       "ALWAYS": "Fine de la seanco"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Ĉiutage",
+      "WEEKLY": "Ĉiusemajne",
+      "MONTHLY": "Ĉiumonate"
+    },
     "KEYRING_FILE": "Dosiero pri ŝlosilaro",
     "KEYRING_FILE_HELP": "Ebligas <b>konektiĝi</b> aŭtomate por ĉiu ekuzo<br/>kaj eĉ <b>aŭtentiĝi</b> (nur se \"Finiĝo de la aŭtentiĝo\" estas agordita kiel \"fine de la seanco\").",
     "REMEMBER_ME": "Memori min?",
@@ -321,6 +327,7 @@
     "MIRROR": "spegulo",
     "MIRRORS": "Speguloj",
     "MIRROR_PEERS": "Spegul-nodoj",
+    "CUSTOM_PEER": "Enigu nodon",
     "PEER_LIST": "Listo de la nodoj",
     "MEMBERS": "Membroj",
     "MEMBER_PEERS": "Membro-nodoj",
@@ -367,6 +374,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Temas pri simpla monujo, sen aliĝ-peto atendanta.",
     "TECHNICAL_DIVIDER": "Teknikaj informoj",
     "BTN_CERTIFY": "Atesti",
+    "BTN_RENEWAL_CERTIFY": "Renew",
     "BTN_YES_CERTIFY": "Jes, atesti",
     "BTN_SELECT_AND_CERTIFY": "Nova atestaĵo",
     "ACCOUNT_OPERATIONS": "Spezoj en la konto",
@@ -511,6 +519,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Ĉesigi la aliĝon...",
     "BTN_SECURITY_DOTS": "Konto kaj sekureco...",
     "BTN_SHOW_DETAILS": "Afiŝi la teknikajn informojn",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} ĉe la bloko {{height}}",
+    "MEMBER_CONVERT_FAILED": "Petado malsukcesis, vi ne plenumas ĉiujn regulojn de la reto de fido.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Sumo blokita",
       "DESCRIPTION": "Jen la kondiĉoj de malblokado de tiu sumo:",
@@ -658,6 +668,23 @@
       "TIME": "Dato",
       "AMOUNT": "Sumo",
       "COMMENT": "Komento"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Kontrolisto antaÅ­ atesto",
+      "INFOS": "La sekureco de la monero Ğ1 dependas de ĉiu membro. Antaŭ atesti la identon de tiu ĉi persono, vi devus fari kelkajn kontroladetojn. Bonvolu respondi la jenajn demandojn:",
+      "BTN_ALL_CHECK": "Atesti",
+      "CHECKLIST_CONDITIONS_NOT_MET": "La atesto ne estis sendita. La kontrolado ŝajnas nesufiĉa. Bonvolu rekontroli ĉiun punkton kun la persono, kiun vi volas atesti.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>Ĉu vi bone konas</b> la personon, kiun vi volas atesti, kaj ĉu vi konas aliajn homojn, kiuj ankaŭ bone konas tiun personon?",
+        "REVOCATION": "Ĉu tiu ĉi persono elŝutis sian <b>malkonfirmadon dokumenton</b> kaj ĉu ŝi scias, kie trovi ĝin?",
+        "CONTACT": "Ĉu vi <b>kontaktis</b> kun tiu ĉi persono per diversaj metodoj, kaj ĉu ŝi respondis?",
+        "DOUBLE_IDENTITY": "La persono devus havi <b>nur unu aktivan membro-identon</b>. Ĉu vi pensas, ke ŝi posedas alian?",
+        "MASTER_ACCOUNT": "Ĉu tiu ĉi persono posedas siajn kontosekretojn? Ĉu ŝi jam <b>sendis monon de sia konto</b> almenaŭ unufoje?",
+        "LICENSE": "Ĉu tiu ĉi persono <b>komprenis la permesilon</b> de Duniter, kaj ĉu ŝi konsentas konformiĝi al ĝi por estontaj atestoj?",
+        "CREDENTIALS": "Ĉu la konto estis kreita kun <b>longa kaj kompleksa identigilo/pasvorto</b> (ekz. pasfrazoj)? Ĉu la persono komprenis, ke ambaŭ la identigilo kaj la pasvorto devas resti sekretaj? Ĉu ŝi estas <b>certa, ke ŝi memoros ilin</b> aŭ povos retrovi ilin?",
+        "PUBLIC_KEY_DIFFERENT": "La montrata <b>publika ŝlosilo</b> devas esti <b>identa</b> al tiu, kiun la persono donis al vi. Ĉu la publika ŝlosiloj estas <b>malsamaj</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "Vi povas rememorigi al la atestota persono diversajn parametrojn pri atestoj:<br/><br/><ul><li> - Ĉiu membro povas atesti maksimume 100 aliajn identecojn.</li><li> - La atestoj estas konservataj kun intervolo de 5 tagoj.</li><li> - Nova membro devas kolekti minimume 5 atestojn en malpli ol 2 monatoj.</li><li> - Membro devas renovigi sian membrecon minimume unufoje jare.</li><li> - Atestoj estas validaj dum du jaroj.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -715,6 +742,7 @@
     "GET_CURRENCY_PARAMETER": "Malsukceso por ricevi la regulojn de la mono.",
     "GET_CURRENCY_FAILED": "Ne eblis ŝarĝi la monon. Bonvolu reprovi pli poste.",
     "SEND_TX_FAILED": "Elspezado malsukcesa.",
+    "CLAIM_UD_FAILED": "Eraro okazis dum la postulo de via Universala Dividendo.",
     "ALL_SOURCES_USED": "Bonvolu atendi la kalkulon de la venonta bloko (ĉiuj viaj monfontoj estis uzitaj).",
     "NOT_ENOUGH_SOURCES": "Ne sufiĉe da mono por sendi tiun ĉi sumon per ununura spezo.<br/>Maksimuma sumo: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Malsukceso por krei la membro-konton.",
diff --git a/src/assets/i18n/es-ES.json b/src/assets/i18n/es-ES.json
index 85833486751c2201993524be19eab6cd05f51478..a63293ee653804ff20856c21100098d34e63964e 100644
--- a/src/assets/i18n/es-ES.json
+++ b/src/assets/i18n/es-ES.json
@@ -128,7 +128,9 @@
     "REPORT_ISSUE": "Reportar anomalía",
     "NOT_YOUR_ACCOUNT_QUESTION": "¿No es suya la cuenta <b><i class=\"ion-key\"></i> {{pubkey|formatPubkey}}</b>?",
     "BTN_CHANGE_ACCOUNT": "Desconectar esta cuenta",
-    "CONNECTION_ERROR": "Nodo <b>{{server}}</b> inalcanzable o dirección inválida.<br/><br/>Compruebe su conexión a Internet, o nodo Duniter <a class=\"positive\" ng-click=\"doQuickFix('settings')\">en los ajustes</a>."
+    "CONNECTION_ERROR": "Nodo <b>{{server}}</b> inalcanzable o dirección inválida.<br/><br/>Compruebe su conexión a Internet, o nodo Duniter <a class=\"positive\" ng-click=\"doQuickFix('settings')\">en los ajustes</a>.",
+    "NEWS": "Notícies"
+
   },
   "SETTINGS": {
     "TITLE": "Ajustes",
@@ -163,6 +165,11 @@
       "HOUR": "Después de {{value}}h de inactividad",
       "ALWAYS": "Al finalizar la sesión"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Todos los días",
+      "WEEKLY": "Todas las semanas",
+      "MONTHLY": "Todos los meses"
+    },
     "KEYRING_FILE": "Archivo de llaves",
     "KEYRING_FILE_HELP": "Le permite <b>conectarse</b> automáticamente en cada inicio <br/>e incluso de <b>autenticarse</b> (solo si \"Caducidad de la autenticación\" está configurada en modo: \"al finalizar la sesión\").",
     "REMEMBER_ME": "Recordarme",
@@ -315,6 +322,7 @@
     "MIRROR": "espejo",
     "MIRRORS": "Espejo",
     "MIRROR_PEERS": "Nodos espejo",
+    "CUSTOM_PEER": "Ingresar un nodo",
     "PEER_LIST": "Lista de nodos",
     "MEMBERS": "Miembro",
     "MEMBER_PEERS": "Nodos miembro",
@@ -361,6 +369,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Se trata de un monedero simple, sin solicitud de membresía en espera",
     "TECHNICAL_DIVIDER": "Informaciones técnicas",
     "BTN_CERTIFY": "Certificar",
+    "BTN_RENEWAL_CERTIFY": "Renovar",
     "BTN_YES_CERTIFY": "Sí, certificar",
     "BTN_SELECT_AND_CERTIFY": "Nueva certificación",
     "ACCOUNT_OPERATIONS": "Transacciones de la cuenta",
@@ -603,6 +612,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Cancelar la membresía…",
     "BTN_SECURITY_DOTS": "Cuenta y seguridad…",
     "BTN_SHOW_DETAILS": "Publicar la información técnica",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} en el bloque {{height}}",
+    "MEMBER_CONVERT_FAILED": "Fallo en la solicitud, no cumples con todas las reglas de la red de confianza.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Importe bloqueado",
       "DESCRIPTION": "Aquí están las condiciones para desbloquear este importe:",
@@ -750,6 +761,23 @@
       "TIME": "Fecha",
       "AMOUNT": "Cantidad",
       "COMMENT": "Comentario"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Lista de verificación antes de certificar",
+      "INFOS": "La seguridad de la moneda Äž1 depende de cada miembro. Antes de certificar la identidad de este ser humano, debes realizar algunas verificaciones. Por favor, responde a las siguientes preguntas:",
+      "BTN_ALL_CHECK": "Certificar",
+      "CHECKLIST_CONDITIONS_NOT_MET": "La certificación no se ha enviado. Las verificaciones parecen insuficientes. Por favor, verifica nuevamente cada punto con la persona a certificar.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>¿Conoces bien</b> al ser humano que vas a certificar y conoces a otras personas que también lo conocen bien?",
+        "REVOCATION": "¿Ha descargado su <b>documento de revocación</b> y sabe dónde encontrarlo?",
+        "CONTACT": "¿Has <b>contactado</b> a esta persona por varios medios y te ha respondido?",
+        "DOUBLE_IDENTITY": "La persona debe tener <b>una sola identidad de miembro activa</b>. ¿Tiene alguna <b>otra</b>?",
+        "MASTER_ACCOUNT": "¿Controla bien su cuenta y ha realizado al menos <b>una transferencia</b> desde su cuenta?",
+        "LICENSE": "¿Ha <b>entendido la licencia</b> y está dispuesta a cumplirla para certificar a otros miembros?",
+        "CREDENTIALS": "¿Las credenciales de su cuenta, como el identificador y la contraseña, son suficientemente <b>largas y complejas</b>? ¿Ha comprendido que tanto la frase secreta como la contraseña deben mantenerse en secreto? ¿Está segura de recordarlos o de poder encontrarlos?",
+        "PUBLIC_KEY_DIFFERENT": "La <b>clave pública</b> indicada debe ser <b>idéntica</b> a la que esta persona te ha proporcionado. ¿Son <b>diferentes</b> las claves?"
+      },
+      "SHORT_LICENSE_REMINDER": "Puedes recordarle a la persona certificada los parámetros de las certificaciones:<br/><br/><ul><li> - Cada miembro puede emitir un máximo de 100 certificaciones válidas.</li><li> - Las certificaciones se registran con un intervalo de 5 días.</li><li> - Una nueva identidad de miembro debe reunir al menos 5 certificaciones en menos de dos meses.</li><li> - Un miembro debe renovar su membresía cada año.</li><li> - Las certificaciones son válidas durante dos años.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -816,6 +844,7 @@
     "GET_CURRENCY_PARAMETER": "Error en la recuperación de las reglas de moneda.",
     "GET_CURRENCY_FAILED": "Carga de la moneda imposible. Por favor, intente más tarde.",
     "SEND_TX_FAILED": "Error en la transferencia.",
+    "CLAIM_UD_FAILED": "Se produjo un error al reclamar su Dividendo Universal.",
     "ALL_SOURCES_USED": "Por favor, espera el cálculo del bloque siguiente (Todas sus fuentes de moneda fueron utilizada).",
     "NOT_ENOUGH_SOURCES": "No lo bastante cambio para mandar este importe en una sola transacción.<br/>Importe máximo: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Error en la creación de la cuenta miembro.",
diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json
index e89f33cd2657371df870250fa164c579c0f104c7..8dcf339e7a9275094c213e35acfeaaccbd652f0b 100644
--- a/src/assets/i18n/fr.json
+++ b/src/assets/i18n/fr.json
@@ -107,7 +107,7 @@
   "ABOUT": {
     "TITLE": "À propos",
     "LICENSE": "Application <b>libre</b> (Licence GNU AGPLv3).",
-    "LATEST_RELEASE": "Il existe une <b>version plus récente</b> de {{'COMMON.APP_NAME'|translate}} (<b>v{{version}}</b>)",
+    "LATEST_RELEASE": "Il existe une <b>version plus récente</b> de {{appName}} (<b>v{{version}}</b>)",
     "PLEASE_UPDATE": "Veuillez mettre à jour {{'COMMON.APP_NAME'|translate}} (dernière version : <b>v{{version}}</b>)",
     "CODE": "Code source :",
     "OFFICIAL_WEB_SITE": "Site web officiel :",
@@ -136,7 +136,8 @@
     "CONNECTION_ERROR": "Nœud <b>{{server}}</b> injoignable ou adresse invalide.<br/><br/>Vérifiez votre connexion Internet, ou changer de nœud <a class=\"positive\" ng-click=\"doQuickFix('settings')\">dans les paramètres</a>.",
     "SHOW_ALL_FEED": "Voir tout",
     "READ_MORE": "Lire la suite",
-    "FEED_SOURCE": "Source"
+    "FEED_SOURCE": "Source",
+    "NEWS": "Actualités"
   },
   "SETTINGS": {
     "TITLE": "Paramètres",
@@ -177,6 +178,11 @@
       "HOUR": "Après {{value}}h d'inactivité",
       "ALWAYS": "A la fin de la session"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Tous les jours",
+      "WEEKLY": "Toutes les semaines",
+      "MONTHLY": "Tous les mois"
+    },
     "KEYRING_FILE": "Fichier de trousseau",
     "KEYRING_FILE_HELP": "Permet de vous <b>connecter</b> automatiquement à chaque lancement<br/>et même de vous <b>authentifier</b> (seulement si \"Expiration de l'authentification\" est configurée \"à la fin de la session\").",
     "REMEMBER_ME": "Se souvenir de moi ?",
@@ -199,7 +205,8 @@
       "USE_SSL": "Sécurisé ?",
       "USE_SSL_HELP": "(Chiffrement SSL)",
       "BTN_SHOW_LIST": "Liste des noeuds"
-    }
+    },
+    "DURATION_BETWEEN_UD_CLAIM": "Période entre chaque récupération du dividende universel"
   },
   "BLOCKCHAIN": {
     "HASH": "Hash : {{hash}}",
@@ -259,7 +266,7 @@
       "TAB_WOT": "Toile de confiance",
       "TAB_NETWORK": "Réseau",
       "TAB_BLOCKS": "Blocs",
-      "CURRENCY_SHORT_DESCRIPTION": "{{currency}} est une <b>monnaie libre</b>, démarrée {{firstBlockTime|formatFromNow}}. Elle compte actuellement <b>{{N}} membres</b>, qui produisent et perçoivent un <a ng-click=\"showHelpModal('ud')\">Dividende Universel</a> (DU), chaque {{dt|formatPeriod}}.",
+      "CURRENCY_SHORT_DESCRIPTION": "{{currency}} est une <b>monnaie libre</b>, démarrée {{firstBlockTime}}. Elle compte actuellement <b>{{N}} membres</b>, qui produisent et perçoivent un <a class='open-modal' (click)='onDividendeClick()' style='cursor: pointer;'>Dividende Universel</a> (DU), chaque {{dt}}.",
       "NETWORK_RULES_DIVIDER": "Règles du réseau",
       "CURRENCY_NAME": "Nom de la monnaie",
       "MEMBERS": "Nombre de membres",
@@ -331,6 +338,7 @@
     "MIRROR": "miroir",
     "MIRRORS": "Miroirs",
     "MIRROR_PEERS": "Nœuds miroirs",
+    "CUSTOM_PEER": "Saisir un nœud",
     "PEER_LIST": "Liste des nœuds",
     "MEMBERS": "Membres",
     "MEMBER_PEERS": "Nœuds membres",
@@ -378,6 +386,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Il s'agit d'un simple portefeuille, sans demande d'adhésion en attente.",
     "TECHNICAL_DIVIDER": "Informations techniques",
     "BTN_CERTIFY": "Certifier",
+    "BTN_RENEWAL_CERTIFY": "Renouveler",
     "BTN_YES_CERTIFY": "Oui, certifier",
     "BTN_SELECT_AND_CERTIFY": "Nouvelle certification",
     "ACCOUNT_OPERATIONS": "Opérations sur le compte",
@@ -543,6 +552,9 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Arrêter l'adhésion...",
     "BTN_SECURITY_DOTS": "Compte et sécurité...",
     "BTN_SHOW_DETAILS": "Afficher les infos techniques",
+    "BTN_CLAIMS_UD": "Réclamer son dividende universel",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} au bloc {{height}}",
+    "MEMBER_CONVERT_FAILED": "Echec de la demande, vous ne respectez pas toutes les régles de la toile de confiance.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Montant verrouillé",
       "DESCRIPTION": "Voici les conditions de déverrouillage de ce montant :",
@@ -696,6 +708,22 @@
       "TIME": "Date",
       "AMOUNT": "Montant",
       "COMMENT": "Commentaire"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Vérifications avant certification",
+      "INFOS": "La sécurité de la monnaie Ğ1 repose sur chaque membre. Avant de certifier l'identité de cette personne, vous devez avoir fait quelques vérifications à son propos. Veuillez répondre aux questions suivantes :",
+      "CHECKLIST_CONDITIONS_NOT_MET": "La certification n'a pas été envoyée. Les vérifications semblent insuffisantes. Veuillez vérifier de nouveau chaque point auprès de la personne à certifier.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>Connaissez-vous bien</b> la personne que vous certifiez, et connaissez-vous des gens qui la connaissent bien également ?",
+        "REVOCATION": "A-t-elle téléchargé son <b>document de révocation</b> et sait-elle où le retrouver ?",
+        "CONTACT": "Avez-vous <b>contacté</b> cette personne par plusieurs moyens et vous a-t-elle répondu ?",
+        "DOUBLE_IDENTITY": "La personne doit posséder <b>une seule identité membre active</b>. En possède-t-elle une <b>autre</b> ?",
+        "MASTER_ACCOUNT": "Maîtrise-t-elle son compte et a-t-elle déjà <b>effectué au moins un virement</b> depuis son compte ?",
+        "LICENSE": "A-t-elle <b>compris la licence</b> et accepte-t-elle de s'y conformer pour la certification d'autres membres ?",
+        "CREDENTIALS": "L’identifiant secret et le mot de passe de son compte sont-ils <b>longs et complexes</b> (phrases de passe) ? A-t-elle compris que l’identifiant doit également rester secret ? Est-elle <b>certaine de s’en souvenir</b> ou de pouvoir les retrouver ?",
+        "PUBLIC_KEY_DIFFERENT": "La <b>clef publique</b> indiquée doit être <b>identique</b> à celle que vous a communiqué cette personne. Les clefs sont-elles <b>différentes</b> ?"
+      },
+      "SHORT_LICENSE_REMINDER": "Vous pouvez rappeler à la personne certifiée les paramètres des certifications :<br/><br/><ul><li> - Chaque membre peut avoir émis 100 certifications valides au maximum.</li><li> - Les certifications sont enregistrées à un intervalle de 5 jours.</li><li> - Une nouvelle identité membre doit réunir au minimum 5 certifications en moins de deux mois.</li><li> - Un membre doit renouveler son adhésion chaque année.</li><li> - Les certifications sont valides durant deux ans.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -772,6 +800,7 @@
     "GET_CURRENCY_PARAMETER": "Échec de la récupération des règles de la monnaie.",
     "GET_CURRENCY_FAILED": "Chargement de la monnaie impossible. Veuillez réessayer plus tard.",
     "SEND_TX_FAILED": "Échec du virement.",
+    "CLAIM_UD_FAILED": "Une erreur est survenue au moment de réclamer votre dividende universel.",
     "ALL_SOURCES_USED": "Veuillez attendre le calcul du prochain bloc (toutes vos sources de monnaie ont été utilisées).",
     "NOT_ENOUGH_SOURCES": "Pas assez de change pour envoyer ce montant en une seule transaction.<br/>Montant maximum : {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Échec de la création du compte membre.",
@@ -902,7 +931,7 @@
       "INSTALL_HELP": "Pour des <b>raisons de sécurité</b> nous vous recommandons <b>d'installer</b> votre copie de l'application Cesium. Visitez le site <a href='https://cesium.app'>www.cesium.app</a> pour obtenir de l'aide."
     },
     "READONLY": {
-      "BADGE": "Monit",
+      "BADGE": "Dev mode",
       "MODE": "Mode monitoring",
       "MODE_HELP": "Cesium fonctionne en <b>mode monitoring</b> : ne sont disponibles que les fonctionnalités de supervision de la monnaie.",
       "INSTALL_HELP": "Si vous souhaitez <b>créer un compte portefeuille</b> pour envoyer ou recevoir de la monnaie, nous vous recommandons <b>d'installer votre copie</b> de l'application Cesium. Visitez le site <a href='https://cesium.app'>www.cesium.app</a> pour obtenir de l'aide."
diff --git a/src/assets/i18n/it-IT.json b/src/assets/i18n/it-IT.json
index 9be3d6e706f23f437cdc6cdfe23c188267466a5a..f534666d71fbc99323d27a3fd33366213ec69728 100644
--- a/src/assets/i18n/it-IT.json
+++ b/src/assets/i18n/it-IT.json
@@ -131,7 +131,8 @@
     "CONNECTION_ERROR": "Nodo <b>{{server}}</b> irraggiungibile o indirizzo non valido. <br/><br/> Verifica tua connessione or cambia nodo. <a class=\"positive\" ng-click=\"doQuickFix('settings')\">nell impostazioni. </a>.",
     "SHOW_ALL_FEED": "Mostra tutto",
     "READ_MORE": "Leggi di più",
-    "FEED_SOURCE": "Fonte"
+    "FEED_SOURCE": "Fonte",
+    "NEWS": "Notizie"
   },
   "SETTINGS": {
     "TITLE": "Impostazioni",
@@ -160,6 +161,11 @@
       "HOUR": "Dopo {{value}}h d'inattività",
       "ALWAYS": "Alla fine della sessione"
     },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Ogni giorno",
+      "WEEKLY": "Ogni settimana",
+      "MONTHLY": "Ogni mese"
+    },
     "REMEMBER_ME": "Ricordarsi di me?",
     "REMEMBER_ME_HELP": "Rimanere identificato da una sessione all'altra, conservando la chiave localmente.",
     "PLUGINS_SETTINGS": "Estensioni",
@@ -302,6 +308,7 @@
     "MIRROR": "Specchio",
     "MIRRORS": "Specchi",
     "MIRROR_PEERS": "Nodi specchio",
+    "CUSTOM_PEER": "Inserisci un nodo",
     "PEER_LIST": "Lista dei nodi",
     "MEMBERS": "Membri",
     "MEMBER_PEERS": "Nodi membri",
@@ -348,6 +355,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Questo è un portafoglio semplice, senza richiesta di certificazione emessa.",
     "TECHNICAL_DIVIDER": "Dati tecnici",
     "BTN_CERTIFY": "Certificare",
+    "BTN_RENEWAL_CERTIFY": "Rinnova",
     "BTN_YES_CERTIFY": "Si, certificare",
     "BTN_SELECT_AND_CERTIFY": "Nuova certificazione",
     "ACCOUNT_OPERATIONS": "Operazioni sul conto",
@@ -489,6 +497,8 @@
     "BTN_MEMBERSHIP_OUT_DOTS": "Revocare adesione...",
     "BTN_SECURITY_DOTS": "Login e securità...",
     "BTN_SHOW_DETAILS": "Visualizza dati tecnici",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} al blocco {{height}}",
+    "MEMBER_CONVERT_FAILED": "Richiesta fallita, non rispetti tutte le regole della rete di fiducia.",
     "LOCKED_OUTPUTS_POPOVER": {
       "TITLE": "Importo bloccato",
       "DESCRIPTION": "Ecco le condizioni per sbloccare questo importo:",
@@ -601,6 +611,23 @@
       "TIME": "Data",
       "AMOUNT": "Importo",
       "COMMENT": "Commento"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Lista di controllo prima della certificazione",
+      "INFOS": "La sicurezza della valuta Ğ1 dipende da ogni membro. Prima di certificare l'identità di questa persona, è necessario effettuare alcuni controlli. Si prega di rispondere alle seguenti domande:",
+      "BTN_ALL_CHECK": "Certifica",
+      "CHECKLIST_CONDITIONS_NOT_MET": "La certificazione non è stata inviata. I controlli sembrano insufficienti. Si prega di verificare nuovamente ogni punto con la persona che si desidera certificare.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>Conosci bene</b> la persona che stai per certificare e conosci altre persone che la conoscono bene?",
+        "REVOCATION": "Ha scaricato il suo <b>documento di revoca</b> e sa dove trovarlo?",
+        "CONTACT": "Hai <b>contattato</b> questa persona in vari modi e ti ha risposto?",
+        "DOUBLE_IDENTITY": "La persona dovrebbe possedere <b>solo un'identità di membro attiva</b>. Ne possiede un'altra?",
+        "MASTER_ACCOUNT": "Ha il controllo del suo account e ha già <b>effettuato almeno un trasferimento</b> dal suo account?",
+        "LICENSE": "Ha <b>compreso la licenza</b> di Duniter e accetta di conformarsi ad essa per le future certificazioni?",
+        "CREDENTIALS": "L'account è stato creato con un <b>ID/password lungo e complesso</b> (frasi segrete)? La persona ha compreso che sia l'ID che la password devono rimanere segreti? È sicura di ricordarli o di poterli recuperare?",
+        "PUBLIC_KEY_DIFFERENT": "La <b>chiave pubblica</b> mostrata deve essere <b>identica</b> a quella che la persona ti ha comunicato. Le chiavi pubbliche sono <b>diverse</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "Puoi ricordare alla persona da certificare i parametri delle certificazioni:<br/><br/><ul><li> - Ogni membro può certificare al massimo 100 identità.</li><li> - Le certificazioni vengono registrate con un intervallo di 5 giorni.</li><li> - Una nuova identità deve raccogliere almeno 5 certificazioni in meno di 2 mesi.</li><li> - Un membro deve rinnovare la sua adesione almeno una volta all'anno.</li><li> - Le certificazioni sono valide per due anni.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -653,6 +680,7 @@
     "GET_CURRENCY_PARAMETER": "Impossibile ricuperare i parametri della moneta.",
     "GET_CURRENCY_FAILED": "Impossibile caricare la moneta. Riprovare più tardi.",
     "SEND_TX_FAILED": "Impossibile eseguire la transazione.",
+    "CLAIM_UD_FAILED": "Si è verificato un errore durante la richiesta del Dividendo Universale.",
     "ALL_SOURCES_USED": "Per favore aspetta il calcolo del prossimo blocco (Tutte le tue fonti di moneta sono state utilizzate).",
     "NOT_ENOUGH_SOURCES": "Non hai abbastanza cambio per inviare questo importo in una sola transazione.<br/>Importo massimo: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Errore nella creazione del tuo conto membro.",
@@ -764,7 +792,7 @@
       "INSTALL_HELP": "Per <b>motivi di sicurezza</b> ti consigliamo di <b>installare</b> la tua copia del software.<br/>Visita il sito <a href='https://cesium.app'>www.cesium.app</a> per assistenza."
     },
     "READONLY": {
-      "BADGE": "Monit",
+      "BADGE": "Dev mode",
       "MODE": "Modalità di monitoraggio",
       "MODE_HELP": "Il Cesium funziona in <b>modalità monitoraggio</b>: sono disponibili solo le funzionalità di monitoraggio della valuta.",
       "INSTALL_HELP": "Se desidera <b>creare un account di portafoglio</b> per inviare o ricevere valuta, ti consigliamo di <b>installare</b> la tua copia del software.<br/>Visita il sito <a href='https://cesium.app'>www.cesium.app</a> per assistenza."
diff --git a/src/assets/i18n/nl-NL.json b/src/assets/i18n/nl-NL.json
index 5c707d903c5373fdfdd423eb0cf1ef77cb67173d..861bee0aedb01ba68abb4ef41b34d676d40ad7f9 100644
--- a/src/assets/i18n/nl-NL.json
+++ b/src/assets/i18n/nl-NL.json
@@ -113,7 +113,8 @@
     "REPORT_ISSUE": "Meld een probleem",
     "NOT_YOUR_ACCOUNT_QUESTION": "Is rekening <b><i class=\"ion-key\"></i> {{pubkey|formatPubkey}}</b> niet van jou?",
     "BTN_CHANGE_ACCOUNT": "Dze rekening ontkoppelen",
-    "CONNECTION_ERROR": "Node <b>{{server}}</b> onbereikbaar of ongeldig adres.<br/><br/>Controleer de internetverbinding, of schakel knooppunt <a class=\"positive\" ng-click=\"doQuickFix('settings')\">in parameters</a>."
+    "CONNECTION_ERROR": "Node <b>{{server}}</b> onbereikbaar of ongeldig adres.<br/><br/>Controleer de internetverbinding, of schakel knooppunt <a class=\"positive\" ng-click=\"doQuickFix('settings')\">in parameters</a>.",
+    "NEWS": "Nieuws"
   },
   "SETTINGS": {
     "TITLE": "Instellingen",
@@ -140,6 +141,19 @@
       "USE_SSL": "Secure?",
       "USE_SSL_HELP": "(SSL-encryptie)",
       "BTN_SHOW_LIST": "Lijst van knooppunten"
+    },
+    "KEEP_AUTH_OPTION": {
+      "NEVER": "Na elke handeling",
+      "SECONDS": "Na {{value}}s inactiviteit",
+      "MINUTE": "Na {{value}}min inactiviteit",
+      "MINUTES": "Na {{value}}min inactiviteit",
+      "HOUR": "Na {{value}}u inactiviteit",
+      "ALWAYS": "Aan het einde van de sessie"
+    },
+    "REDEEM_UD_PERIOD_OPTION": {
+      "DAILY": "Elke dag",
+      "WEEKLY": "Elke week",
+      "MONTHLY": "Elke maand"
     }
   },
   "BLOCKCHAIN": {
@@ -242,6 +256,7 @@
     "PEERS": "Knopen",
     "SIGNED_ON_BLOCK": "Getekend op blok",
     "MIRROR": "spiegel",
+    "CUSTOM_PEER": "Voer een peer in",
     "CURRENT_BLOCK": "Blok #",
     "VIEW": {
       "TITLE": "Knoop",
@@ -276,6 +291,7 @@
     "NOT_MEMBER_ACCOUNT_HELP": "Dit is een eenvoudige rekening, zonder dat er een aanvraag voor lidmaatschap in de wacht wordt gezet.",
     "TECHNICAL_DIVIDER": "Technische informatie",
     "BTN_CERTIFY": "Certificeren",
+    "BTN_RENEWAL_CERTIFY": "Vernieuw",
     "BTN_YES_CERTIFY": "Ja, Certificeren",
     "BTN_SELECT_AND_CERTIFY": "Nieuwe certificatie",
     "ACCOUNT_OPERATIONS": "Operaties op de rekening",
@@ -362,6 +378,8 @@
     "BTN_SECURITY_DOTS": "Rekening en veiligheid...",
     "BTN_SHOW_DETAILS": "Tonen technische informatie",
     "BTN_REVOKE": "Deze identiteit<span class='hidden-xs hidden-sm'> definitief</span> opzeggen...",
+    "TITLE_DISTANCE_RULES": "{{refereesReached}} / {{refereesCount}} bij blok {{height}}",
+    "MEMBER_CONVERT_FAILED": "Verzoek mislukt, u voldoet niet aan alle regels van het vertrouwensnetwerk.",
     "NEW": {
       "TITLE": "Registratie",
       "SLIDE_1_TITLE": "Selecteer een valuta:",
@@ -399,6 +417,23 @@
       "TIME": "Datum",
       "AMOUNT": "Bedrag",
       "COMMENT": "Commentaar"
+    },
+    "CERTIFICATION_MODAL": {
+      "CHECKLIST_TITLE": "Controles vóór certificering",
+      "INFOS": "De veiligheid van de munteenheid Äž1 is gebaseerd op elk lid. Voordat je de identiteit van deze persoon certificeert, moet je enkele controles over haar hebben uitgevoerd. Beantwoord de volgende vragen:",
+      "BTN_ALL_CHECK": "Certificeren",
+      "CHECKLIST_CONDITIONS_NOT_MET": "De certificering is niet verzonden. De controles lijken onvoldoende. Controleer elk punt opnieuw bij de persoon die moet worden gecertificeerd.",
+      "QUESTIONS": {
+        "WELL_KNOWN": "<b>Ken je</b> de persoon die je certificeert goed, en ken je ook mensen die haar goed kennen?",
+        "REVOCATION": "Heeft ze haar <b>herroepingsdocument</b> gedownload en weet ze waar ze het kan vinden?",
+        "CONTACT": "Heb je deze persoon op verschillende manieren <b>gecontacteerd</b> en heeft ze je geantwoord?",
+        "DOUBLE_IDENTITY": "De persoon moet <b>één actieve lididentiteit</b> hebben. Heeft ze er <b>een andere</b>?",
+        "MASTER_ACCOUNT": "Heeft ze controle over haar rekening, en heeft ze al <b>minstens één overboeking</b> gedaan vanaf haar rekening?",
+        "LICENSE": "Heeft ze de <b>licentie begrepen</b>, en gaat ze akkoord met de naleving ervan voor de certificering van andere leden?",
+        "CREDENTIALS": "Zijn de geheime identificatie en het wachtwoord van haar rekening <b>lang en complex</b> (wachtwoordzinnen)? Heeft ze begrepen dat de identificatie ook geheim moet blijven? Is ze er <b>zeker van dat ze deze zal onthouden</b> of terugvinden?",
+        "PUBLIC_KEY_DIFFERENT": "De <b>openbare sleutel</b> moet <b>identiek</b> zijn aan die welke deze persoon je heeft meegedeeld. Zijn de sleutels <b>verschillend</b>?"
+      },
+      "SHORT_LICENSE_REMINDER": "Je kunt de persoon eraan herinneren verschillende certificeringsparameters te certificeren:<br/><br/><ul><li> - Elk lid kan maximaal 100 andere identiteiten certificeren.</li><li> - De certificeringen worden met een interval van 5 dagen opgeslagen.</li><li> - Een nieuwe identiteit moet in minder dan 2 maanden minstens 5 certificeringen verzamelen.</li><li> - Een lid moet minstens eenmaal per jaar zijn lidmaatschap vernieuwen.</li><li> - Certificeringen hebben een levensduur van twee jaar.</li></ul>"
     }
   },
   "TRANSFER": {
@@ -445,6 +480,7 @@
     "GET_CURRENCY_PARAMETER": "Could not get currency parameters.",
     "GET_CURRENCY_FAILED": "Could not load currency.",
     "SEND_TX_FAILED": "Could not send transaction.",
+    "CLAIM_UD_FAILED": "Er is een fout opgetreden bij het claimen van uw Universeel Dividend.",
     "ALL_SOURCES_USED": "Please wait the next block computation (All transaction sources has been used).",
     "NOT_ENOUGH_SOURCES": "Not enough changes to send this amount in one time.<br/>Maximum amount: {{amount}} {{unit}}<sub>{{subUnit}}</sub>.",
     "ACCOUNT_CREATION_FAILED": "Error while creating your member account.",
diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts
index bf0a8c400c656a12aeba6b12e837be3b60050f09..7e94192b60750a28d2782c958deaa2c893632ebc 100644
--- a/src/environments/environment.class.ts
+++ b/src/environments/environment.class.ts
@@ -7,16 +7,30 @@ export interface Environment {
   name: string;
   version?: string;
   production: boolean;
+  mode?: string;
 
   // Default values
   baseUrl?: string;
   useHash?: boolean;
   defaultLocale: string;
 
+  sourceUrl?: string;
+  reportIssueUrl?: string;
+  forumUrl?: string;
+  officialUrl?: string;
+
   defaultPeers: string[];
   defaultIndexers: string[];
   defaultPods: string[];
   defaultIfpsGateways: string[];
+  defaultDistanteFileUrl: string[];
+
+  feed?: {
+    jsonFeed: Map<string, string[]>;
+    maxContentLength: number;
+    maxAgeInMonths: number;
+    maxCount: number;
+  };
 
   // GraphQL
   graphql: {
@@ -41,6 +55,7 @@ export interface Environment {
     indexer?: string;
     pod?: string;
     ipfsGateway?: string;
+    distanceFileUrl?: string;
 
     // Load polkadot default account (alice, etc.)
     testingAccounts?: boolean;
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index 744751cc6b9eb3565228e353126bf9b241e212cb..1cbbe7fd61f4f8767ed488626e94fec8773ac8f3 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -12,6 +12,12 @@ export const environment = <Environment>{
   useHash: false,
   defaultLocale: 'fr',
 
+  // 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://git.duniter.org/',
+
   graphql: {
     fetchPolicy: 'cache-first',
     watchFetchPolicy: 'cache-and-network',
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index be0ed973300aec30d99c9a3ce57329f7269493b0..77f12849b6ca92d883b936b354260706d275e14a 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -4,15 +4,21 @@
 
 import { Environment } from './environment.class';
 import { StorageDrivers } from '@app/shared/services/storage/storage.utils';
-
 import { AuthData } from '@app/account/auth/auth.model';
 
 export const environment = <Environment>{
   production: false,
-
+  version: '2.0.1',
   name: 'Cesium&sup2;',
-
+  mode: 'dev',
   defaultLocale: 'fr',
+  forumInformationUrl: 'https://forum.duniter.org/t/gchange-v2-moderation-ou-et-federation/12910/2',
+
+  // About
+  sourceUrl: 'https://git.duniter.org/clients/cesium-grp/cesium',
+  reportIssueUrl: 'https://git.duniter.org/clients/cesium-grp/cesium/-/issues/new',
+  forumUrl: 'https://forum.duniter.org/',
+  officialUrl: 'https://www.cesium.app',
 
   graphql: {
     fetchPolicy: 'cache-first',
@@ -31,6 +37,25 @@ export const environment = <Environment>{
     ss58Format: 42, // dev
   },
 
+  feed: {
+    jsonFeed: new Map<string, string[]>([
+      ['en', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-en.json']],
+      ['en-GB', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-en-GB.json']],
+      ['eo-EO', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-eo-EO.json']],
+      // ['fr', ['https://forum.duniter.org/t/nouvelle-version-1-7-9-de-cesium/11458/2.json']],
+      // ['fr', ['https://forum.duniter.org/c/clients/cesium/22']],
+      ['fr', ['https://forum.duniter.org/c/clients/cesium/22', 'https://forum.duniter.org/t/nouvelle-version-1-7-9-de-cesium/11458/2.json']],
+      ['nl-Nl', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-nl-NL.json']],
+      ['es-ES', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-es-ES.json']],
+      ['ca', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-ca.json']],
+      ['it-IT', ['https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-it-IT.json']],
+    ]),
+    maxContentLength: 1300,
+    // maxAgeInMonths: 1,
+    maxAgeInMonths: 120,
+    maxCount: 3,
+  },
+
   dev: {
     //peer: 'ws://127.0.0.1:9944',
     peer: 'wss://gdev.coinduf.eu/ws',
@@ -53,12 +78,15 @@ 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: [
@@ -66,8 +94,8 @@ export const environment = <Environment>{
     //'http://localhost:8080/v1/graphql',
     /* GDev endpoints */
     'https://squid.gdev.coinduf.eu/v1beta1/relay',
-    //'https://gdev-squid.axiom-team.fr/graphql'
-    // 'https://gdev-squid.axiom-team.fr/v1beta1/relay',
+    // 'https://gdev-squid.axiom-team.fr/graphql',
+    'https://gdev-squid.axiom-team.fr/v1beta1/relay',
   ],
 
   defaultPods: [
@@ -75,6 +103,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: [
@@ -83,4 +112,9 @@ export const environment = <Environment>{
     /* GDev endpoints */
     'https://pagu.re',
   ],
+
+  defaultDistanteFileUrl: [
+    /* Distance file Urls */
+    'https://files.coinduf.eu/distance_precompute/latest_distance.json',
+  ],
 };
diff --git a/src/theme/_cesium.scss b/src/theme/_cesium.scss
index 3f430b3a6955ae8135fc78f374ebd58bd87b0d85..eec5a90d970cbdd9ae1b1051eb04b74b04268c9d 100644
--- a/src/theme/_cesium.scss
+++ b/src/theme/_cesium.scss
@@ -132,3 +132,7 @@ ion-icon.icon-secondary {
   left: 8px;
   top: -2px;
 }
+
+ion-icon.tappable {
+  cursor: pointer;
+}
diff --git a/src/theme/_ionic.globals.scss b/src/theme/_ionic.globals.scss
index 86978cab0850b52af5da205597fbd1d55338d57b..664c0e4f137bf79e769cb468501dc4ca42d410fe 100644
--- a/src/theme/_ionic.globals.scss
+++ b/src/theme/_ionic.globals.scss
@@ -63,7 +63,7 @@ $dark-disabled-text: rgba(black, 0.38);
 $light-primary-text: white;
 $light-secondary-text: rgba(white, 0.7);
 $light-disabled-text: rgba(white, 0.5);
-$text-color: $dark-primary-text;
+$text-color: rgba(black, 1);
 
 // Default General Colors
 // --------------------------------------------------
diff --git a/src/theme/_mixins.scss b/src/theme/_mixins.scss
index 45f54fc1f4efa376275ef262b07875eaf728a491..6122f6a3c7386912f2b26770c224573d1c1c8a04 100644
--- a/src/theme/_mixins.scss
+++ b/src/theme/_mixins.scss
@@ -74,6 +74,8 @@
 
 @mixin css-variables-to-root() {
   --ion-background-color: #{$background-color};
+  --ion-text-color:  #{$text-color};
+  --ion-text-color-rgb:  #{color-to-rgb-list($text-color)};
   --ion-toolbar-background: var(--ion-background-color);
   --ion-item-background: #{$ion-item-background-color};