Humanity score integration (#2354)

* Humanity score integration

* isLoading fix
This commit is contained in:
Igor Stuev
2024-11-04 18:53:42 +01:00
committed by GitHub
parent 9d8520c645
commit f834a4f59c
9 changed files with 129 additions and 2 deletions
+1
View File
@@ -37,3 +37,4 @@ export { default as addressProfileAPI } from './addressProfileAPI';
export { default as validators } from './validators';
export { default as verifiedTokens } from './verifiedTokens';
export { default as web3Wallet } from './web3Wallet';
export { default as xStarScore } from './xStarScore';
+23
View File
@@ -0,0 +1,23 @@
import type { Feature } from './types';
import { getEnvValue } from '../utils';
const title = 'Xname score';
const url = getEnvValue('NEXT_PUBLIC_XNAME_SCORE_URL');
const config: Feature<{ url: string }> = (() => {
if (url) {
return Object.freeze({
title,
url,
isEnabled: true,
});
}
return Object.freeze({
title,
isEnabled: false,
});
})();
export default config;
+1
View File
@@ -62,3 +62,4 @@ NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=noves
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST=https://points.k8s-dev.blockscout.com
NEXT_PUBLIC_XSTAR_SCORE_URL='https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address'
+1
View File
@@ -837,6 +837,7 @@ const schema = yup
return isUndefined || valueSchema.isValidSync(data);
}),
NEXT_PUBLIC_REWARDS_SERVICE_API_HOST: yup.string().test(urlTest),
NEXT_PUBLIC_XSTAR_SCORE_URL: yup.string().test(urlTest),
// 6. External services envs
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: yup.string(),
+11
View File
@@ -55,6 +55,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
- [Bridged tokens](ENVS.md#bridged-tokens)
- [Safe{Core} address tags](ENVS.md#safecore-address-tags)
- [Address profile API](ENVS.md#address-profile-api)
- [Address XStar XHS score](ENVS.md#address-xstar-xhs-score)
- [SUAVE chain](ENVS.md#suave-chain)
- [MetaSuites extension](ENVS.md#metasuites-extension)
- [Validators list](ENVS.md#validators-list)
@@ -680,6 +681,16 @@ This feature allows the integration of an external API to fetch user info for ad
&nbsp;
### Address XStar XHS score
This feature allows the integration of an XStar API to fetch XHS score for addresses. When configured, if the API returns a score, a public tag with that score will be displayed in the address page header.
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_XSTAR_SCORE_URL | `string` | XStar XHS score documentation URL for the address tag. Enables the XStar score feature. | - | - | `https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm` | v1.36.0+ |
&nbsp;
### SUAVE chain
For blockchains that implement SUAVE architecture additional fields will be shown on the transaction page ("Allowed peekers", "Kettle"). Users also will be able to see the list of all transactions for a particular Kettle in the separate view.
+6
View File
@@ -38,6 +38,7 @@ import type {
AddressMudRecordsSorting,
AddressMudRecord,
AddressEpochRewardsResponse,
AddressXStarResponse,
} from 'types/api/address';
import type { AddressesResponse, AddressesMetadataSearchResult, AddressesMetadataSearchFilters } from 'types/api/addresses';
import type { AddressMetadataInfo, PublicTagTypesResponse } from 'types/api/addressMetadata';
@@ -595,6 +596,10 @@ export const RESOURCES = {
pathParams: [ 'hash' as const ],
filterFields: [],
},
address_xstar_score: {
path: '/api/v2/proxy/xname/address/:hash',
pathParams: [ 'hash' as const ],
},
// CONTRACT
contract: {
@@ -1304,6 +1309,7 @@ Q extends 'rewards_user_daily_check' ? RewardsUserDailyCheckResponse :
Q extends 'rewards_user_daily_claim' ? RewardsUserDailyClaimResponse :
Q extends 'rewards_user_referrals' ? RewardsUserReferralsResponse :
Q extends 'token_transfers_all' ? TokenTransferResponse :
Q extends 'address_xstar_score' ? AddressXStarResponse :
never;
/* eslint-enable @typescript-eslint/indent */
+51
View File
@@ -0,0 +1,51 @@
import React from 'react';
import * as v from 'valibot';
import config from 'configs/app';
import buildUrl from 'lib/api/buildUrl';
import useApiQuery from 'lib/api/useApiQuery';
interface Params {
hash: string;
}
const RESOURCE_NAME = 'address_xstar_score';
const ERROR_NAME = 'Invalid response schema';
export default function useFetchXStarScore({ hash }: Params) {
const query = useApiQuery(RESOURCE_NAME, {
pathParams: { hash },
queryOptions: {
select: (response) => {
const parsedResponse = v.safeParse(v.object({ data: v.string() }), response);
if (!parsedResponse.success) {
throw Error(ERROR_NAME);
}
return parsedResponse.output;
},
enabled: Boolean(hash) && config.features.xStarScore.isEnabled,
placeholderData: {
data: 'Base' as const,
},
retry: 0,
},
});
const errorMessage = query.error && 'message' in query.error ? query.error.message : undefined;
React.useEffect(() => {
if (errorMessage === ERROR_NAME) {
fetch('/node-api/monitoring/invalid-api-schema', {
method: 'POST',
body: JSON.stringify({
resource: RESOURCE_NAME,
url: buildUrl(RESOURCE_NAME, { hash }, undefined, true),
}),
});
}
}, [ errorMessage, hash ]);
return query;
}
+4
View File
@@ -270,3 +270,7 @@ export type AddressEpochRewardsItem = {
epoch_number: number;
associated_account: AddressParam;
}
export type AddressXStarResponse = {
data: string | null;
}
+31 -2
View File
@@ -16,6 +16,7 @@ import getNetworkValidationActionText from 'lib/networks/getNetworkValidationAct
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import useFetchXStarScore from 'lib/xStarScore/useFetchXStarScore';
import { ADDRESS_TABS_COUNTERS } from 'stubs/address';
import { USER_OPS_ACCOUNT } from 'stubs/userOps';
import AddressAccountHistory from 'ui/address/AddressAccountHistory';
@@ -58,6 +59,7 @@ const TOKEN_TABS = [ 'tokens_erc20', 'tokens_nfts', 'tokens_nfts_collection', 't
const txInterpretation = config.features.txInterpretation;
const addressProfileAPIFeature = config.features.addressProfileAPI;
const xScoreFeature = config.features.xStarScore;
const AddressPageContent = () => {
const router = useRouter();
@@ -139,6 +141,8 @@ const AddressPageContent = () => {
const isSafeAddress = useIsSafeAddress(!addressQuery.isPlaceholderData && addressQuery.data?.is_contract ? hash : undefined);
const safeIconColor = useColorModeValue('black', 'white');
const xStarQuery = useFetchXStarScore({ hash });
const contractTabs = useContractTabs(
addressQuery.data,
config.features.mudFramework.isEnabled ? (mudTablesCountQuery.isPlaceholderData || addressQuery.isPlaceholderData) : addressQuery.isPlaceholderData,
@@ -295,8 +299,32 @@ const AddressPageContent = () => {
undefined,
...formatUserTags(addressQuery.data),
...(addressMetadataQuery.data?.addresses?.[hash.toLowerCase()]?.tags.filter(tag => tag.tagType !== 'note') || []),
!addressQuery.data?.is_contract && xScoreFeature.isEnabled && xStarQuery.data?.data ?
{
slug: 'xstar',
name: `XHS ${ xStarQuery.data.data } level`,
tagType: 'custom' as const,
ordinal: 12,
meta: {
tagUrl: xScoreFeature.url,
tooltipTitle: 'XStar humanity levels',
tooltipDescription:
'XStar looks for off-chain information about an address and interpret it as a XHS score. Different score means different humanity levels.',
tooltipUrl: xScoreFeature.url,
},
} :
undefined,
].filter(Boolean).sort(sortEntityTags);
}, [ addressMetadataQuery.data, addressQuery.data, hash, isSafeAddress, userOpsAccountQuery.data, mudTablesCountQuery.data, usernameApiTag ]);
}, [
addressMetadataQuery.data,
addressQuery.data,
hash,
isSafeAddress,
userOpsAccountQuery.data,
mudTablesCountQuery.data,
usernameApiTag,
xStarQuery.data?.data,
]);
const titleContentAfter = (
<EntityTags
@@ -305,7 +333,8 @@ const AddressPageContent = () => {
isLoading ||
(config.features.userOps.isEnabled && userOpsAccountQuery.isPlaceholderData) ||
(config.features.addressMetadata.isEnabled && addressMetadataQuery.isPending) ||
(addressProfileAPIFeature.isEnabled && userPropfileApiQuery.isPending)
(addressProfileAPIFeature.isEnabled && userPropfileApiQuery.isPending) ||
(xScoreFeature.isEnabled && xStarQuery.isPlaceholderData)
}
/>
);