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 }} + <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²', - + 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};