Commit 011d3669 authored by tom's avatar tom

Merge branch 'main' of github.com:blockscout/frontend into chakra-v3

parents 2750d34d 07388c62
...@@ -21,6 +21,7 @@ on: ...@@ -21,6 +21,7 @@ on:
- eth_sepolia - eth_sepolia
- eth_goerli - eth_goerli
- filecoin - filecoin
- immutable
- neon_devnet - neon_devnet
- optimism - optimism
- optimism_celestia - optimism_celestia
......
...@@ -21,6 +21,7 @@ on: ...@@ -21,6 +21,7 @@ on:
- eth_sepolia - eth_sepolia
- eth_goerli - eth_goerli
- filecoin - filecoin
- immutable
- mekong - mekong
- neon_devnet - neon_devnet
- optimism - optimism
......
...@@ -50,5 +50,27 @@ jobs: ...@@ -50,5 +50,27 @@ jobs:
test: test:
name: Run tests name: Run tests
needs: deploy_e2e needs: deploy_e2e
uses: blockscout/blockscout-ci-cd/.github/workflows/e2e_new.yaml@master runs-on: ubuntu-latest
secrets: inherit permissions: write-all
\ No newline at end of file steps:
- name: Get Vault credentials
id: retrieve-vault-secrets
uses: hashicorp/vault-action@v2.4.1
with:
url: https://vault.k8s.blockscout.com
role: ci-dev
path: github-jwt
method: jwt
tlsSkipVerify: false
exportToken: true
secrets: |
ci/data/dev/github token | WORKFLOW_TRIGGER_TOKEN ;
- name: Trigger tests
uses: convictional/trigger-workflow-and-wait@v1.6.1
with:
owner: blockscout
repo: blockscout-ci-cd
github_token: ${{ env.WORKFLOW_TRIGGER_TOKEN }}
workflow_file_name: e2e_new.yaml
ref: master
wait_interval: 30
...@@ -366,6 +366,7 @@ ...@@ -366,6 +366,7 @@
"celo_alfajores", "celo_alfajores",
"garnet", "garnet",
"gnosis", "gnosis",
"immutable",
"eth", "eth",
"eth_goerli", "eth_goerli",
"eth_sepolia", "eth_sepolia",
...@@ -374,6 +375,7 @@ ...@@ -374,6 +375,7 @@
"neon_devnet", "neon_devnet",
"optimism", "optimism",
"optimism_celestia", "optimism_celestia",
"optimism_interop_0",
"optimism_sepolia", "optimism_sepolia",
"polygon", "polygon",
"rari_testnet", "rari_testnet",
......
...@@ -35,6 +35,7 @@ const config: Feature<{ ...@@ -35,6 +35,7 @@ const config: Feature<{
type: RollupType; type: RollupType;
homepage: { showLatestBlocks: boolean }; homepage: { showLatestBlocks: boolean };
outputRootsEnabled: boolean; outputRootsEnabled: boolean;
interopEnabled: boolean;
L2WithdrawalUrl: string | undefined; L2WithdrawalUrl: string | undefined;
parentChain: ParentChain; parentChain: ParentChain;
DA: { DA: {
...@@ -50,6 +51,7 @@ const config: Feature<{ ...@@ -50,6 +51,7 @@ const config: Feature<{
type, type,
L2WithdrawalUrl: type === 'optimistic' ? L2WithdrawalUrl : undefined, L2WithdrawalUrl: type === 'optimistic' ? L2WithdrawalUrl : undefined,
outputRootsEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED') === 'true', outputRootsEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED') === 'true',
interopEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_INTEROP_ENABLED') === 'true',
homepage: { homepage: {
showLatestBlocks: getEnvValue('NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS') === 'true', showLatestBlocks: getEnvValue('NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS') === 'true',
}, },
......
# Set of ENVs for Immutable network explorer
# https://explorer.immutable.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=immutable"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
# Instance ENVs
NEXT_PUBLIC_AD_BANNER_PROVIDER=none
NEXT_PUBLIC_AD_TEXT_PROVIDER=none
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=immutable-mainnet.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/immutable-mainnet.json
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/immutable.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x6166cece570f4731ccc94c2d17d854ce88496cd3b48e03b537959992ab6685c8
NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS=true
NEXT_PUBLIC_HELIA_VERIFIED_FETCH_ENABLED=false
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['no-repeat center/100% 100% url(https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-skins/immutable.jpg)'],'text_color':['rgba(19, 19, 19, 1)']}
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_LOGOUT_URL=https://blockscout-immutable.us.auth0.com/v2/logout
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/pools']
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=IMX
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=IMX
NEXT_PUBLIC_NETWORK_EXPLORERS=[{'title':'GeckoTerminal','logo':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/explorer-logos/geckoterminal.png','baseUrl':'https://www.geckoterminal.com/','paths':{'token':'/immutable-zkevm/pools'}}]
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/immutable-short.svg
NEXT_PUBLIC_NETWORK_ID=13371
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/immutable.svg
NEXT_PUBLIC_NETWORK_NAME=Immutable
NEXT_PUBLIC_NETWORK_RPC_URL=https://rpc.immutable.com/
NEXT_PUBLIC_NETWORK_SHORT_NAME=Immutable
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/immutable.png
NEXT_PUBLIC_STATS_API_HOST=https://stats-immutable-mainnet.k8s.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=["miner"]
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'Rarible','collection_url':'https://rarible.com/collection/immutablex/{hash}/items','instance_url':'https://rarible.com/token/immutablex/{hash}:{id}','logo_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/nft-marketplace-logos/rarible.png'}]
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
\ No newline at end of file
# Set of ENVs for OP Interop Alpha 0 network explorer
# https://optimism-interop-alpha-0.blockscout.com
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=optimism_interop_0"
# Local ENVs
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
# Instance ENVs
NEXT_PUBLIC_AD_BANNER_PROVIDER=none
NEXT_PUBLIC_AD_TEXT_PROVIDER=none
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=optimism-interop-alpha-0.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/optimism.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['linear-gradient(90deg, rgb(232, 52, 53) 0%, rgb(139, 28, 232) 100%)'],'text_color':['rgb(255, 255, 255)']}
NEXT_PUBLIC_INTEROP_ENABLED=true
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=Ether
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ETH
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/optimism.svg
NEXT_PUBLIC_NETWORK_ID=420120000
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/optimism.svg
NEXT_PUBLIC_NETWORK_NAME=OP Interop Alpha 0
NEXT_PUBLIC_NETWORK_RPC_URL=https://interop-alpha-0.optimism.io
NEXT_PUBLIC_NETWORK_SHORT_NAME=OP Interop Alpha 0
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://eth-sepolia.blockscout.com/
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://bridge.interop-alpha-0.optimism.io
NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED=false
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
NEXT_PUBLIC_STATS_API_HOST=https://stats-optimism-interop-devnet-0.k8s-prod-1.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket', 'metamask']
\ No newline at end of file
...@@ -346,6 +346,17 @@ const rollupSchema = yup ...@@ -346,6 +346,17 @@ const rollupSchema = yup
value => value === undefined, value => value === undefined,
), ),
}), }),
NEXT_PUBLIC_INTEROP_ENABLED: yup
.boolean()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: 'optimistic',
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_INTEROP_ENABLED can only be used if NEXT_PUBLIC_ROLLUP_TYPE is set to \'optimistic\' ',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME: yup NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME: yup
.string() .string()
.when('NEXT_PUBLIC_ROLLUP_TYPE', { .when('NEXT_PUBLIC_ROLLUP_TYPE', {
......
...@@ -5,3 +5,4 @@ NEXT_PUBLIC_FAULT_PROOF_ENABLED=true ...@@ -5,3 +5,4 @@ NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED=false NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED=false
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://explorer.duckchain.io'} NEXT_PUBLIC_ROLLUP_PARENT_CHAIN={'baseUrl':'https://explorer.duckchain.io'}
NEXT_PUBLIC_INTEROP_ENABLED=true
\ No newline at end of file
...@@ -114,6 +114,11 @@ module.exports = { ...@@ -114,6 +114,11 @@ module.exports = {
return null; return null;
} }
break; break;
case '/interop-messages':
if (process.env.NEXT_PUBLIC_INTEROP_ENABLED !== 'true') {
return null;
}
break;
case '/pools': case '/pools':
if (process.env.NEXT_PUBLIC_DEX_POOLS_ENABLED !== 'true') { if (process.env.NEXT_PUBLIC_DEX_POOLS_ENABLED !== 'true') {
return null; return null;
......
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
The app instance can be customized by passing the following variables to the Node.js environment at runtime. Some of these variables have been deprecated, and their full list can be found in the [file](./DEPRECATED_ENVS.md). The app instance can be customized by passing the following variables to the Node.js environment at runtime. Some of these variables have been deprecated, and their full list can be found in the [file](./DEPRECATED_ENVS.md).
**IMPORTANT NOTE!** For _production_ build purposes all json-like values should be single-quoted. If it contains a hash (`#`) or a dollar-sign (`$`) the whole value should be wrapped in single quotes as well (see `dotenv` [readme](https://github.com/bkeepers/dotenv#variable-substitution) for the reference) ## Read before you run the app
## Disclaimer about using variables ### Variables compulsoriness
Please note that in the tables below, the "Compulsoriness" column indicates whether the variable is required for starting up the application, except for the "App Features" section. All features are optional by definition; therefore, the "Compulsoriness" column indicates whether a certain variable is required or optional only within the context of that feature, not for the entire application.
Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will be exposed to the browser. So any user can obtain its values. Make sure that for all 3rd-party services keys (e.g., Sentri, Auth0, WalletConnect, etc.) in the services administration panel you have created a whitelist of allowed origins and have added your app domain into it. That will help you prevent using your key by unauthorized app, if someone gets its value. ### Disclaimer about using variables
Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will be exposed to the browser. So any user can obtain its values. Make sure that for all 3rd-party services keys (e.g., Auth0, WalletConnect, etc.) in the services administration panel you have created a whitelist of allowed origins and have added your app domain into it. That will help you prevent using your key by unauthorized app, if someone gets its value.
### Note about escaping variables values
All json-like values should be single-quoted. If it contains a hash (`#`) or a dollar-sign (`$`) the whole value should be wrapped in single quotes as well (see `dotenv` [readme](https://github.com/bkeepers/dotenv#variable-substitution) for the reference)
&nbsp; &nbsp;
...@@ -351,7 +356,7 @@ Settings for meta tags, OG tags and SEO ...@@ -351,7 +356,7 @@ Settings for meta tags, OG tags and SEO
## App features ## App features
*Note* The variables which are marked as required should be passed as described in order to enable the particular feature, but they are not required in the whole app context. *Note* The variables which are marked as required should be passed as described in order to enable the particular feature, but they are not required in the entire app context.
### My account ### My account
...@@ -461,6 +466,7 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi ...@@ -461,6 +466,7 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi
| NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL | `string` | URL for L2 -> L1 withdrawals (Optimistic stack only) | Required for `optimistic` rollups | - | `https://app.optimism.io/bridge/withdraw` | v1.24.0+ | | NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL | `string` | URL for L2 -> L1 withdrawals (Optimistic stack only) | Required for `optimistic` rollups | - | `https://app.optimism.io/bridge/withdraw` | v1.24.0+ |
| NEXT_PUBLIC_FAULT_PROOF_ENABLED | `boolean` | Set to `true` for chains with fault proof system enabled (Optimistic stack only) | - | - | `true` | v1.31.0+ | | NEXT_PUBLIC_FAULT_PROOF_ENABLED | `boolean` | Set to `true` for chains with fault proof system enabled (Optimistic stack only) | - | - | `true` | v1.31.0+ |
| NEXT_PUBLIC_HAS_MUD_FRAMEWORK | `boolean` | Set to `true` for instances that use MUD framework (Optimistic stack only) | - | - | `true` | v1.33.0+ | | NEXT_PUBLIC_HAS_MUD_FRAMEWORK | `boolean` | Set to `true` for instances that use MUD framework (Optimistic stack only) | - | - | `true` | v1.33.0+ |
| NEXT_PUBLIC_INTEROP_ENABLED | `boolean` | Enables "Interop messages" page (Optimistic stack only) | - | `false` | `true` | v1.39.0+ |
| NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS | `boolean` | Set to `true` to display "Latest blocks" widget instead of "Latest batches" on the home page | - | - | `true` | v1.36.0+ | | NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS | `boolean` | Set to `true` to display "Latest blocks" widget instead of "Latest batches" on the home page | - | - | `true` | v1.36.0+ |
| NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED | `boolean` | Enables "Output roots" page (Optimistic stack only) | - | `false` | `true` | v1.37.0+ | | NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED | `boolean` | Enables "Output roots" page (Optimistic stack only) | - | `false` | `true` | v1.37.0+ |
| NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME | `string` | Set to customize L1 transaction status labels in the UI (e.g., "Sent to <chain-name>"). This setting is applicable only for Arbitrum-based chains. **DEPRECATED** _Use `NEXT_PUBLIC_ROLLUP_PARENT_CHAIN` instead_ | - | - | `DuckChain` | v1.37.0+ | | NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME | `string` | Set to customize L1 transaction status labels in the UI (e.g., "Sent to <chain-name>"). This setting is applicable only for Arbitrum-based chains. **DEPRECATED** _Use `NEXT_PUBLIC_ROLLUP_PARENT_CHAIN` instead_ | - | - | `DuckChain` | v1.37.0+ |
......
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30">
<path fill="currentColor" fill-rule="evenodd" d="M8.455 6c.602 0 1.09.488 1.09 1.09v.864a6 6 0 0 0 10.91 0v-.863a1.091 1.091 0 0 1 2.181 0v.65a7.1 7.1 0 0 0 2.551 1.596 1.09 1.09 0 0 1-.738 2.053 9.3 9.3 0 0 1-1.813-.885v6.404h3.273a1.09 1.09 0 1 1 0 2.182h-3.273v3.273a1.09 1.09 0 0 1-2.181 0V19.09H9.545v3.273a1.09 1.09 0 1 1-2.181 0V19.09H4.09a1.09 1.09 0 1 1 0-2.182h3.273v-6.404a9.3 9.3 0 0 1-1.813.885 1.09 1.09 0 0 1-.738-2.053 7.1 7.1 0 0 0 2.55-1.596v-.65A1.094 1.094 0 0 1 8.456 6m7.636 10.91h4.363v-5.357a8.17 8.17 0 0 1-4.363 2.01zm-2.182-3.347v3.346H9.545v-5.356a8.18 8.18 0 0 0 4.364 2.01" clip-rule="evenodd"/>
</svg>
...@@ -82,6 +82,7 @@ import type { ...@@ -82,6 +82,7 @@ import type {
} from 'types/api/ens'; } from 'types/api/ens';
import type { IndexingStatus } from 'types/api/indexingStatus'; import type { IndexingStatus } from 'types/api/indexingStatus';
import type { InternalTransactionsResponse } from 'types/api/internalTransaction'; import type { InternalTransactionsResponse } from 'types/api/internalTransaction';
import type { InteropMessageListResponse } from 'types/api/interop';
import type { LogsResponseTx, LogsResponseAddress } from 'types/api/log'; import type { LogsResponseTx, LogsResponseAddress } from 'types/api/log';
import type { MudWorldsResponse } from 'types/api/mudWorlds'; import type { MudWorldsResponse } from 'types/api/mudWorlds';
import type { NovesAccountHistoryResponse, NovesDescribeTxsResponse, NovesResponseData } from 'types/api/noves'; import type { NovesAccountHistoryResponse, NovesDescribeTxsResponse, NovesResponseData } from 'types/api/noves';
...@@ -1243,6 +1244,15 @@ export const RESOURCES = { ...@@ -1243,6 +1244,15 @@ export const RESOURCES = {
block_countdown: { block_countdown: {
path: '/api', path: '/api',
}, },
// INTEROP
optimistic_l2_interop_messages: {
path: '/api/v2/optimism/interop/messages',
filterFields: [],
},
optimistic_l2_interop_messages_count: {
path: '/api/v2/optimism/interop/messages/count',
},
}; };
export type ResourceName = keyof typeof RESOURCES; export type ResourceName = keyof typeof RESOURCES;
...@@ -1296,7 +1306,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward ...@@ -1296,7 +1306,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward
'watchlist' | 'private_tags_address' | 'private_tags_tx' | 'watchlist' | 'private_tags_address' | 'private_tags_tx' |
'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators_stability' | 'validators_blackfort' | 'validators_zilliqa' | 'noves_address_history' | 'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators_stability' | 'validators_blackfort' | 'validators_zilliqa' | 'noves_address_history' |
'token_transfers_all' | 'scroll_l2_txn_batches' | 'scroll_l2_txn_batch_txs' | 'scroll_l2_txn_batch_blocks' | 'token_transfers_all' | 'scroll_l2_txn_batches' | 'scroll_l2_txn_batch_txs' | 'scroll_l2_txn_batch_blocks' |
'scroll_l2_deposits' | 'scroll_l2_withdrawals' | 'advanced_filter' | 'pools'; 'scroll_l2_deposits' | 'scroll_l2_withdrawals' | 'advanced_filter' | 'pools' | 'optimistic_l2_interop_messages';
export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>; export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>;
...@@ -1473,6 +1483,8 @@ Q extends 'optimistic_l2_output_roots_count' ? number : ...@@ -1473,6 +1483,8 @@ Q extends 'optimistic_l2_output_roots_count' ? number :
Q extends 'optimistic_l2_withdrawals_count' ? number : Q extends 'optimistic_l2_withdrawals_count' ? number :
Q extends 'optimistic_l2_deposits_count' ? number : Q extends 'optimistic_l2_deposits_count' ? number :
Q extends 'optimistic_l2_dispute_games_count' ? number : Q extends 'optimistic_l2_dispute_games_count' ? number :
Q extends 'optimistic_l2_interop_messages' ? InteropMessageListResponse :
Q extends 'optimistic_l2_interop_messages_count' ? number :
Q extends 'shibarium_withdrawals' ? ShibariumWithdrawalsResponse : Q extends 'shibarium_withdrawals' ? ShibariumWithdrawalsResponse :
Q extends 'shibarium_deposits' ? ShibariumDepositsResponse : Q extends 'shibarium_deposits' ? ShibariumDepositsResponse :
Q extends 'shibarium_withdrawals_count' ? number : Q extends 'shibarium_withdrawals_count' ? number :
......
...@@ -45,7 +45,7 @@ type TRewardsContext = { ...@@ -45,7 +45,7 @@ type TRewardsContext = {
openLoginModal: () => void; openLoginModal: () => void;
closeLoginModal: () => void; closeLoginModal: () => void;
saveApiToken: (token: string | undefined) => void; saveApiToken: (token: string | undefined) => void;
login: (refCode: string) => Promise<{ isNewUser?: boolean; invalidRefCodeError?: boolean }>; login: (refCode: string) => Promise<{ isNewUser: boolean; reward: string | null; invalidRefCodeError?: boolean }>;
claim: () => Promise<void>; claim: () => Promise<void>;
}; };
...@@ -70,7 +70,7 @@ const initialState = { ...@@ -70,7 +70,7 @@ const initialState = {
openLoginModal: () => {}, openLoginModal: () => {},
closeLoginModal: () => {}, closeLoginModal: () => {},
saveApiToken: () => {}, saveApiToken: () => {},
login: async() => ({}), login: async() => ({ isNewUser: false, reward: null }),
claim: async() => {}, claim: async() => {},
}; };
...@@ -211,10 +211,14 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -211,10 +211,14 @@ export function RewardsContextProvider({ children }: Props) {
apiFetch('rewards_nonce') as Promise<RewardsNonceResponse>, apiFetch('rewards_nonce') as Promise<RewardsNonceResponse>,
refCode ? refCode ?
apiFetch('rewards_check_ref_code', { pathParams: { code: refCode } }) as Promise<RewardsCheckRefCodeResponse> : apiFetch('rewards_check_ref_code', { pathParams: { code: refCode } }) as Promise<RewardsCheckRefCodeResponse> :
Promise.resolve({ valid: true }), Promise.resolve({ valid: true, reward: null }),
]); ]);
if (!checkCodeResponse.valid) { if (!checkCodeResponse.valid) {
return { invalidRefCodeError: true }; return {
invalidRefCodeError: true,
isNewUser: false,
reward: null,
};
} }
const message = getMessageToSign(address, nonceResponse.nonce, checkUserQuery.data?.exists, refCode); const message = getMessageToSign(address, nonceResponse.nonce, checkUserQuery.data?.exists, refCode);
const signature = await signMessageAsync({ message }); const signature = await signMessageAsync({ message });
...@@ -229,7 +233,10 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -229,7 +233,10 @@ export function RewardsContextProvider({ children }: Props) {
}, },
}) as RewardsLoginResponse; }) as RewardsLoginResponse;
saveApiToken(loginResponse.token); saveApiToken(loginResponse.token);
return { isNewUser: loginResponse.created }; return {
isNewUser: loginResponse.created,
reward: checkCodeResponse.reward,
};
} catch (_error) { } catch (_error) {
errorToast(_error); errorToast(_error);
throw _error; throw _error;
......
...@@ -115,6 +115,13 @@ export default function useNavItems(): ReturnType { ...@@ -115,6 +115,13 @@ export default function useNavItems(): ReturnType {
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
const rollupInteropMessages = rollupFeature.isEnabled && rollupFeature.interopEnabled ? {
text: 'Interop messages',
nextRoute: { pathname: '/interop-messages' as const },
icon: 'interop',
isActive: pathname === '/interop-messages',
} : null;
if (rollupFeature.isEnabled && ( if (rollupFeature.isEnabled && (
rollupFeature.type === 'optimistic' || rollupFeature.type === 'optimistic' ||
rollupFeature.type === 'arbitrum' || rollupFeature.type === 'arbitrum' ||
...@@ -127,7 +134,8 @@ export default function useNavItems(): ReturnType { ...@@ -127,7 +134,8 @@ export default function useNavItems(): ReturnType {
internalTxs, internalTxs,
rollupDeposits, rollupDeposits,
rollupWithdrawals, rollupWithdrawals,
], rollupInteropMessages,
].filter(Boolean),
[ [
blocks, blocks,
rollupTxnBatches, rollupTxnBatches,
......
...@@ -60,6 +60,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = { ...@@ -60,6 +60,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/advanced-filter': 'Root page', '/advanced-filter': 'Root page',
'/pools': 'Root page', '/pools': 'Root page',
'/pools/[hash]': 'Regular page', '/pools/[hash]': 'Regular page',
'/interop-messages': 'Root page',
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': 'Regular page', '/login': 'Regular page',
......
...@@ -63,6 +63,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = { ...@@ -63,6 +63,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/advanced-filter': DEFAULT_TEMPLATE, '/advanced-filter': DEFAULT_TEMPLATE,
'/pools': DEFAULT_TEMPLATE, '/pools': DEFAULT_TEMPLATE,
'/pools/[hash]': DEFAULT_TEMPLATE, '/pools/[hash]': DEFAULT_TEMPLATE,
'/interop-messages': DEFAULT_TEMPLATE,
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': DEFAULT_TEMPLATE, '/login': DEFAULT_TEMPLATE,
......
...@@ -60,6 +60,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = { ...@@ -60,6 +60,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/advanced-filter': '%network_name% advanced filter', '/advanced-filter': '%network_name% advanced filter',
'/pools': '%network_name% DEX pools', '/pools': '%network_name% DEX pools',
'/pools/[hash]': '%network_name% pool details', '/pools/[hash]': '%network_name% pool details',
'/interop-messages': '%network_name% interop messages',
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': '%network_name% login', '/login': '%network_name% login',
......
...@@ -58,6 +58,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = { ...@@ -58,6 +58,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/advanced-filter': 'Advanced filter', '/advanced-filter': 'Advanced filter',
'/pools': 'DEX pools', '/pools': 'DEX pools',
'/pools/[hash]': 'Pool details', '/pools/[hash]': 'Pool details',
'/interop-messages': 'Interop messages',
// service routes, added only to make typescript happy // service routes, added only to make typescript happy
'/login': 'Login', '/login': 'Login',
......
import type { ChainInfo, InteropMessage } from 'types/api/interop';
export const chain: ChainInfo = {
chain_id: 1,
chain_name: 'Ethereum',
chain_logo: 'https://example.com/logo.png',
instance_url: 'https://example.com',
};
export const interopMessageIn: InteropMessage = {
init_transaction_hash: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
nonce: 1,
payload: 'payload',
relay_transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
sender: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
status: 'Relayed',
target: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
timestamp: '2022-10-10T14:34:30.000000Z',
init_chain: chain,
};
export const interopMessageIn1: InteropMessage = {
init_transaction_hash: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
nonce: 1,
payload: 'payload',
relay_transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
sender: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
status: 'Sent',
target: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
timestamp: '2022-10-10T14:34:30.000000Z',
init_chain: null,
};
export const interopMessageOut: InteropMessage = {
init_transaction_hash: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
nonce: 1,
payload: 'payload',
relay_transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
sender: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
status: 'Relayed',
target: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
timestamp: '2022-10-10T14:34:30.000000Z',
relay_chain: chain,
};
export const interopMessageOut1: InteropMessage = {
init_transaction_hash: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
nonce: 1,
payload: 'payload',
relay_transaction_hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
sender: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
status: 'Failed',
target: '0x047A81aFB05D9B1f8844bf60fcA05DCCFbC584B9',
timestamp: '2022-10-10T14:34:30.000000Z',
relay_chain: null,
};
import type { TokenInfo } from 'types/api/token'; import type { TokenInfo } from 'types/api/token';
import type { TokenTransfer, TokenTransferResponse } from 'types/api/tokenTransfer'; import type { TokenTransfer, TokenTransferResponse } from 'types/api/tokenTransfer';
import * as tokenInstanceMock from './tokenInstance';
export const erc20: TokenTransfer = { export const erc20: TokenTransfer = {
from: { from: {
hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859', hash: '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859',
...@@ -86,6 +88,7 @@ export const erc721: TokenTransfer = { ...@@ -86,6 +88,7 @@ export const erc721: TokenTransfer = {
}, },
total: { total: {
token_id: '875879856', token_id: '875879856',
token_instance: tokenInstanceMock.base,
}, },
transaction_hash: '0xf13bc7afe5e02b494dd2f22078381d36a4800ef94a0ccc147431db56c301e6cc', transaction_hash: '0xf13bc7afe5e02b494dd2f22078381d36a4800ef94a0ccc147431db56c301e6cc',
type: 'token_transfer', type: 'token_transfer',
...@@ -135,6 +138,7 @@ export const erc1155A: TokenTransfer = { ...@@ -135,6 +138,7 @@ export const erc1155A: TokenTransfer = {
token_id: '123', token_id: '123',
value: '42', value: '42',
decimals: null, decimals: null,
token_instance: null,
}, },
transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746', transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746',
type: 'token_minting', type: 'token_minting',
...@@ -151,7 +155,7 @@ export const erc1155B: TokenTransfer = { ...@@ -151,7 +155,7 @@ export const erc1155B: TokenTransfer = {
name: 'SastanaNFT', name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
}, },
total: { token_id: '12345678', value: '100000000000000000000', decimals: null }, total: { token_id: '12345678', value: '100000000000000000000', decimals: null, token_instance: null },
}; };
export const erc1155C: TokenTransfer = { export const erc1155C: TokenTransfer = {
...@@ -161,7 +165,7 @@ export const erc1155C: TokenTransfer = { ...@@ -161,7 +165,7 @@ export const erc1155C: TokenTransfer = {
name: 'SastanaNFT', name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
}, },
total: { token_id: '483200961027732618117991942553110860267520', value: '200000000000000000000', decimals: null }, total: { token_id: '483200961027732618117991942553110860267520', value: '200000000000000000000', decimals: null, token_instance: null },
}; };
export const erc1155D: TokenTransfer = { export const erc1155D: TokenTransfer = {
...@@ -171,7 +175,7 @@ export const erc1155D: TokenTransfer = { ...@@ -171,7 +175,7 @@ export const erc1155D: TokenTransfer = {
name: 'SastanaNFT', name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
}, },
total: { token_id: '456', value: '42', decimals: null }, total: { token_id: '456', value: '42', decimals: null, token_instance: null },
}; };
export const erc404A: TokenTransfer = { export const erc404A: TokenTransfer = {
...@@ -213,6 +217,7 @@ export const erc404A: TokenTransfer = { ...@@ -213,6 +217,7 @@ export const erc404A: TokenTransfer = {
value: '42000000000000000000000000', value: '42000000000000000000000000',
decimals: '18', decimals: '18',
token_id: null, token_id: null,
token_instance: null,
}, },
transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746', transaction_hash: '0x05d6589367633c032d757a69c5fb16c0e33e3994b0d9d1483f82aeee1f05d746',
type: 'token_transfer', type: 'token_transfer',
...@@ -230,7 +235,7 @@ export const erc404B: TokenTransfer = { ...@@ -230,7 +235,7 @@ export const erc404B: TokenTransfer = {
name: 'SastanaNFT', name: 'SastanaNFT',
symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY', symbol: 'ipfs://QmUpFUfVKDCWeZQk5pvDFUxnpQP9N6eLSHhNUy49T1JVtY',
}, },
total: { token_id: '4625304364899952' }, total: { token_id: '4625304364899952', token_instance: null },
}; };
export const mixTokens: TokenTransferResponse = { export const mixTokens: TokenTransferResponse = {
......
...@@ -19,6 +19,7 @@ export const mintToken: TxStateChange = { ...@@ -19,6 +19,7 @@ export const mintToken: TxStateChange = {
direction: 'from', direction: 'from',
total: { total: {
token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065', token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065',
token_instance: null,
}, },
}, },
], ],
...@@ -57,6 +58,7 @@ export const receiveMintedToken: TxStateChange = { ...@@ -57,6 +58,7 @@ export const receiveMintedToken: TxStateChange = {
direction: 'to', direction: 'to',
total: { total: {
token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065', token_id: '15077554365819457090226168288698582604878106156134383525616269766016907608065',
token_instance: null,
}, },
}, },
], ],
......
...@@ -3,6 +3,7 @@ import type { Transaction } from 'types/api/transaction'; ...@@ -3,6 +3,7 @@ import type { Transaction } from 'types/api/transaction';
import * as addressMock from 'mocks/address/address'; import * as addressMock from 'mocks/address/address';
import { publicTag, privateTag, watchlistName } from 'mocks/address/tag'; import { publicTag, privateTag, watchlistName } from 'mocks/address/tag';
import * as interopMock from 'mocks/interop/interop';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import * as decodedInputDataMock from 'mocks/txs/decodedInputData'; import * as decodedInputDataMock from 'mocks/txs/decodedInputData';
...@@ -423,3 +424,29 @@ export const withRecipientContract = { ...@@ -423,3 +424,29 @@ export const withRecipientContract = {
...withRecipientEns, ...withRecipientEns,
to: addressMock.contract, to: addressMock.contract,
}; };
export const withInteropInMessage: Transaction = {
...base,
op_interop: {
init_chain: interopMock.chain,
nonce: 1,
payload: '0x',
init_transaction_hash: '0x01a8c328b0370068aaaef49c107f70901cd79adcda81e3599a88855532122e09',
sender: addressMock.hash,
status: 'Sent',
target: addressMock.hash,
},
};
export const withInteropOutMessage: Transaction = {
...base,
op_interop: {
relay_chain: interopMock.chain,
nonce: 1,
payload: '0xfa4b78b90000000000000000000000000000000000000000000000000000000005001bcfe835d1028984e9e6e7d016b77164eacbcc6cc061e9333c0b37982b504f7ea791000000000000000000000000a79b29ad7e0196c95b87f4663ded82fbf2e3add8',
relay_transaction_hash: '0x01a8c328b0370068aaaef49c107f70901cd79adcda81e3599a88855532122e09',
sender: addressMock.hash,
status: 'Sent',
target: addressMock.hash,
},
};
...@@ -380,6 +380,17 @@ export const mud: GetServerSideProps<Props> = async(context) => { ...@@ -380,6 +380,17 @@ export const mud: GetServerSideProps<Props> = async(context) => {
return base(context); return base(context);
}; };
export const interopMessages: GetServerSideProps<Props> = async(context) => {
const rollupFeature = config.features.rollup;
if (!rollupFeature.isEnabled || !rollupFeature.interopEnabled) {
return {
notFound: true,
};
}
return base(context);
};
export const pools: GetServerSideProps<Props> = async(context) => { export const pools: GetServerSideProps<Props> = async(context) => {
if (!config.features.pools.isEnabled) { if (!config.features.pools.isEnabled) {
return { return {
......
...@@ -47,6 +47,7 @@ declare module "nextjs-routes" { ...@@ -47,6 +47,7 @@ declare module "nextjs-routes" {
| StaticRoute<"/graphiql"> | StaticRoute<"/graphiql">
| StaticRoute<"/"> | StaticRoute<"/">
| StaticRoute<"/internal-txs"> | StaticRoute<"/internal-txs">
| StaticRoute<"/interop-messages">
| StaticRoute<"/login"> | StaticRoute<"/login">
| StaticRoute<"/mud-worlds"> | StaticRoute<"/mud-worlds">
| DynamicRoute<"/name-domains/[name]", { "name": string }> | DynamicRoute<"/name-domains/[name]", { "name": string }>
......
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageNextJs from 'nextjs/PageNextJs';
const InteropMessages = dynamic(() => import('ui/pages/InteropMessages'), { ssr: false });
const Page: NextPage = () => {
return (
<PageNextJs pathname="/interop-messages">
<InteropMessages/>
</PageNextJs>
);
};
export default Page;
export { interopMessages as getServerSideProps } from 'nextjs/getServerSideProps';
...@@ -97,4 +97,10 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = { ...@@ -97,4 +97,10 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
externalTxs: [ externalTxs: [
[ 'NEXT_PUBLIC_TX_EXTERNAL_TRANSACTIONS_CONFIG', '{"chain_name": "Solana", "chain_logo_url": "http://example.url", "explorer_url_template": "https://scan.io/tx/{hash}"}' ], [ 'NEXT_PUBLIC_TX_EXTERNAL_TRANSACTIONS_CONFIG', '{"chain_name": "Solana", "chain_logo_url": "http://example.url", "explorer_url_template": "https://scan.io/tx/{hash}"}' ],
], ],
interop: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'optimistic' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL', 'https://localhost:3102' ],
[ 'NEXT_PUBLIC_INTEROP_ENABLED', 'true' ],
],
}; };
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
| "integration/full" | "integration/full"
| "integration/partial" | "integration/partial"
| "internal_txns" | "internal_txns"
| "interop"
| "key" | "key"
| "lightning_navbar" | "lightning_navbar"
| "lightning" | "lightning"
......
<svg viewBox="0 0 184 79" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.83 78.287h31.624c11.672 0 21.144-9.357 21.144-20.914V26.1c0-11.557-9.472-20.914-21.144-20.914H24.831c-11.672 0-21.144 9.357-21.144 20.914v31.272c0 11.557 9.472 20.914 21.144 20.914Z" fill="#CFE3FF" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path d="M22.581 74.538h31.624c11.671 0 21.143-9.357 21.143-20.914V22.352c0-11.557-9.472-20.914-21.143-20.914H22.58c-11.672 0-21.143 9.357-21.143 20.914v31.272c0 11.557 9.471 20.914 21.143 20.914Z" fill="#fff" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path d="M31.138 32.901c.143 6.487 7.717 15.4 7.717 15.4s7.662-9.333 8.028-15.4c.397-6.561-7.454-13.299-8.083-13.827-.026-.022-.054-.021-.079.001-.588.538-7.73 7.21-7.583 13.826Z" fill="#FD95AF" stroke="#F27DA2" stroke-width="2.143"/>
<path d="M52.963 43.002c3.149-6.104.29-17.6.29-17.6s-9.824 2.533-13.206 7.95c-3.653 5.85-1.66 18.191-1.49 19.197.008.04.038.058.076.047.904-.266 11.13-3.39 14.33-9.594Z" fill="#FEE231" stroke="#CCAD18" stroke-width="2.143"/>
<path d="M24.53 42.601c3.065 6.146 14.082 10.733 14.082 10.733s3.07-12.101.703-18.023c-2.562-6.403-13.087-9.628-13.926-9.876-.033-.01-.06.004-.072.037-.3.806-3.914 10.857-.786 17.129Z" fill="#7ED5EE" stroke="#3DA6C5" stroke-width="2.143"/>
<path d="M25.596 51.18c4.098 4.855 13.141 4.615 14.703 4.535a.25.25 0 0 0 .24-.248c.043-1.535.114-10.26-3.59-14.397-4.381-4.895-15.692-5.938-16.688-6.02-.041-.004-.068.023-.064.064.09.942 1.142 11.023 5.4 16.067Z" fill="#68AE19" stroke="#005225" stroke-width="2.143"/>
<path d="M42.49 40.333c-4.238 4.387-4.51 14.055-4.526 15.274a.127.127 0 0 0 .124.13c1.175.032 10.265.126 14.606-4.155 4.68-4.614 5.97-15.572 6.075-16.538.004-.04-.021-.067-.062-.065-.955.04-11.618.593-16.217 5.354Z" fill="#68AE19" stroke="#005225" stroke-width="2.143"/>
<path d="M129.795 78.287h31.624c11.671 0 21.143-9.357 21.143-20.914V26.1c0-11.557-9.472-20.914-21.143-20.914h-31.624c-11.672 0-21.143 9.357-21.143 20.914v31.272c0 11.557 9.471 20.914 21.143 20.914Z" fill="#CFE3FF" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path d="M127.546 74.538h31.624c11.671 0 21.143-9.357 21.143-20.914V22.352c0-11.557-9.472-20.914-21.143-20.914h-31.624c-11.672 0-21.143 9.357-21.143 20.914v31.272c0 11.557 9.471 20.914 21.143 20.914Z" fill="#fff" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M137.981 51.029a4.626 4.626 0 0 1-4.411-3.228l-3.136-9.883h-1.927a4.629 4.629 0 0 1-4.412-3.228l-1.863-5.872h6.988l-3.686-5.553h34.921l-3.686 5.553h6.988l-1.863 5.872a4.628 4.628 0 0 1-4.411 3.228h-1.928l-3.135 9.883a4.629 4.629 0 0 1-4.412 3.228h-10.027Zm-2.368-15.81c0 1.49 1.113 2.7 2.486 2.7 1.373 0 2.486-1.21 2.486-2.7 0-1.49-1.113-2.7-2.486-2.7-1.373 0-2.486 1.21-2.486 2.7Zm14.764 0c0 1.49-1.113 2.7-2.486 2.7-1.374 0-2.487-1.21-2.487-2.7 0-1.49 1.113-2.7 2.487-2.7 1.373 0 2.486 1.21 2.486 2.7Z" fill="#004293"/>
<path d="M77.313 78.287h31.623c11.672 0 21.144-9.357 21.144-20.914V26.1c0-11.557-9.472-20.914-21.144-20.914H77.313c-11.672 0-21.144 9.357-21.144 20.914v31.272c0 11.557 9.472 20.914 21.144 20.914Z" fill="#CFE3FF" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path d="M75.064 74.538h31.623c11.672 0 21.144-9.357 21.144-20.914V22.352c0-11.557-9.472-20.914-21.144-20.914H75.064c-11.672 0-21.144 9.357-21.144 20.914v31.272c0 11.557 9.472 20.914 21.144 20.914Z" fill="#fff" stroke="#7E94CE" stroke-width="1.125" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M109.285 48.52h.013v2.028a5.795 5.795 0 0 1-5.795 5.796h-3.333v-.01H81.7a1.77 1.77 0 0 1-1.768-1.774v-1.486c.007-.066.011-.134.011-.202 0-1.043-.908-1.889-2.028-1.889-1.08 0-1.964.787-2.025 1.78l-.005.002v1.672a1.833 1.833 0 1 1-3.665 0v-7.123a2.324 2.324 0 0 1-.016-.238v-4.203c0-.98.792-1.774 1.769-1.774H85.56a1.687 1.687 0 1 1 0 3.374h-1.792c-1.032.014-1.865.917-1.865 2.029 0 1.12.846 2.028 1.889 2.028h.003c.123.033 9.006.045 15.868.05v-.009h.028a1.927 1.927 0 0 0 1.924-1.808l.004-.003v-4.316c0-.8.649-1.449 1.449-1.449h4.767c.8 0 1.449.65 1.449 1.45v6.075ZM97.713 26.796a2.65 2.65 0 0 0-.126.004c-1.258-.038-12.012-.044-15.724-.044l-.05-.001c-1.025 0-1.862.8-1.924 1.809l-.003.002v4.316c0 .8-.649 1.449-1.449 1.449H73.67a1.45 1.45 0 0 1-1.449-1.45v-6.085h-.016v-2.029a5.796 5.796 0 0 1 5.796-5.796h3.333v.033h18.469c.976 0 1.768.794 1.768 1.774v1.498a1.734 1.734 0 0 0 0 .36.777.777 0 0 0 .036.213c.195.854 1.009 1.493 1.984 1.493 1.077 0 1.957-.78 2.024-1.768l.003-.001v-.05l.001-.07v-.025l-.001-.043v-1.496a1.832 1.832 0 1 1 3.665 0v7.139c.011.094.016.173.016.234v4.203a1.77 1.77 0 0 1-1.769 1.773h-4.191c-.068 0-.135-.004-.202-.011h-7.195a1.687 1.687 0 1 1 0-3.374h1.771c1.043 0 1.889-.908 1.889-2.028s-.846-2.029-1.89-2.029Z" fill="#5353D3"/>
</svg>
<svg viewBox="0 0 181 86" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M135.242 8.795a13.983 13.983 0 0 1 13.995 0L167.98 19.63a13.982 13.982 0 0 1 6.985 12.106v21.697c0 4.992-2.662 9.606-6.985 12.105l-18.743 10.834a13.983 13.983 0 0 1-13.995 0l-18.743-10.834a13.984 13.984 0 0 1-6.985-12.106V31.735c0-4.993 2.663-9.607 6.985-12.106l18.743-10.834Z" fill="url(#a)"/>
<path d="M135.978 9.477a13.483 13.483 0 0 1 13.495 0l18.743 10.834a13.483 13.483 0 0 1 6.735 11.674V53.68c0 4.815-2.567 9.264-6.735 11.674l-18.743 10.834a13.483 13.483 0 0 1-13.495 0l-18.743-10.834a13.484 13.484 0 0 1-6.736-11.674V31.985c0-4.815 2.568-9.264 6.736-11.674l18.743-10.834Z" fill="url(#b)" stroke="#6BB171" stroke-width=".999"/>
<path d="M123.015 44.668a.295.295 0 0 0-.045-.158l-.859-1.388a.3.3 0 0 0-.314-.136l-6.966 1.387a.297.297 0 0 0-.198.14l-.741 1.227a.298.298 0 0 0-.004.303l.741 1.299a.3.3 0 0 0 .261.151h7.825a.3.3 0 0 0 .3-.3v-2.525Zm2.005 4.021a.294.294 0 0 0-.083.104l-.832 1.714a.3.3 0 0 0 .018.293l.831 1.298a.3.3 0 0 0 .253.138h11.904a.3.3 0 0 0 .3-.3V48.64a.304.304 0 0 0-.043-.156l-.879-1.447a.3.3 0 0 0-.333-.134l-4.165 1.09c1.316-1.105 2.438-2.234 3.362-3.387h.001c1.192-1.503 1.796-3.14 1.796-4.907 0-1.616-.505-2.953-1.533-3.981-1.024-1.04-2.529-1.536-4.458-1.536-1.131 0-2.172.222-3.117.67h-.001c-.268.13-.611.413-.965.747-.362.342-.763.763-1.151 1.197-.771.862-1.514 1.797-1.805 2.272-.06.097-.06.22.001.316l.784 1.257a.299.299 0 0 0 .254.141h3.913a.3.3 0 0 0 .3-.3c0-.787.16-1.346.438-1.716.288-.38.671-.569 1.183-.569.538 0 .892.16 1.12.437.242.292.382.722.382 1.326 0 .779-.28 1.598-.872 2.463a14.612 14.612 0 0 1-2.231 2.533l-.002.002c-.88.816-2.092 1.863-3.639 3.142a.254.254 0 0 0-.029.028l-.117.094a55.61 55.61 0 0 1-.585.467Zm15.193-12.003-.001.001c-1.088 1.632-1.615 3.84-1.615 6.593 0 2.785.527 5.008 1.615 6.64l.001.002c1.129 1.668 2.935 2.48 5.347 2.48 2.412 0 4.211-.812 5.324-2.48 1.105-1.633 1.64-3.857 1.64-6.642 0-2.753-.536-4.962-1.64-6.594-1.113-1.668-2.912-2.48-5.324-2.48s-4.218.812-5.347 2.48Zm7.227 3.03.001.002c.326.8.499 1.98.499 3.562 0 1.065-.063 1.939-.185 2.627-.118.651-.359 1.167-.711 1.56v.001c-.306.344-.781.54-1.484.54-.699 0-1.184-.195-1.507-.54-.336-.394-.569-.91-.687-1.561-.123-.688-.185-1.562-.185-2.627 0-1.582.173-2.762.499-3.562l.001-.002c.153-.382.379-.653.677-.833.301-.182.696-.283 1.202-.283.507 0 .902.101 1.203.283.297.18.524.451.677.833Zm8.802.304-.002.002c-.62.593-.911 1.422-.911 2.44 0 1.019.291 1.847.911 2.44l.002.002c.622.582 1.416.864 2.358.864.718 0 1.348-.164 1.877-.501l-3.74 5.347a.299.299 0 0 0-.003.34l.941 1.388a.3.3 0 0 0 .249.131h2.934c.11 0 .211-.06.264-.156l6.847-12.521a.3.3 0 0 0-.006-.299l-.793-1.316a.301.301 0 0 0-.414-.1l-2.142 1.315a.306.306 0 0 0-.089.084l-2.78 3.975c.072-.306.107-.638.107-.993 0-1.019-.291-1.847-.911-2.44-.61-.584-1.4-.866-2.341-.866-.942 0-1.736.282-2.358.864Zm11.185 8.612.005.006c.097.127.17.352.17.725s-.073.599-.17.725c-.093.121-.215.184-.402.184-.204 0-.318-.066-.395-.175-.091-.128-.159-.357-.159-.734 0-.386.068-.62.156-.747.092-.118.213-.18.398-.18.18 0 .302.063.397.196Zm-9.399-6.17c0-.383.068-.618.16-.749.077-.111.191-.178.394-.178.211 0 .329.069.409.18.093.131.162.364.162.747 0 .373-.073.599-.169.725-.093.121-.215.185-.402.185-.205 0-.319-.067-.395-.176-.091-.128-.159-.357-.159-.734Zm6.678 4.461c-.62.593-.911 1.421-.911 2.44s.291 1.847.911 2.44c.61.584 1.401.866 2.342.866.941 0 1.731-.282 2.341-.866.62-.593.911-1.421.911-2.44s-.291-1.847-.911-2.44c-.61-.584-1.4-.866-2.341-.866-.941 0-1.732.282-2.342.866Z" fill="#9EDF99" stroke="#6BB171" stroke-width=".6" stroke-linejoin="round"/>
<path d="M122.126 43.185a.3.3 0 0 0-.3-.3H114a.3.3 0 0 0-.3.3v2.526a.3.3 0 0 0 .3.3h7.826a.3.3 0 0 0 .3-.3v-2.526Zm2.005 4.022a.3.3 0 0 0-.114.235v3.012a.3.3 0 0 0 .3.3h11.905a.3.3 0 0 0 .3-.3v-3.296a.3.3 0 0 0-.3-.3h-5.54c1.499-1.217 2.761-2.461 3.782-3.734l.001-.001c1.192-1.502 1.796-3.14 1.796-4.906 0-1.616-.506-2.953-1.534-3.981-1.024-1.041-2.528-1.536-4.458-1.536-1.131 0-2.171.222-3.116.67h-.002c-.941.454-1.702 1.16-2.283 2.105l-.002.004c-.571.956-.864 2.133-.896 3.514a.301.301 0 0 0 .3.307h3.913a.3.3 0 0 0 .3-.3c0-.787.159-1.346.437-1.717.288-.38.672-.568 1.183-.568.538 0 .892.16 1.121.436.242.293.382.723.382 1.327 0 .779-.281 1.598-.873 2.463a14.613 14.613 0 0 1-2.231 2.533l-.002.001c-.879.817-2.091 1.864-3.639 3.143a.376.376 0 0 0-.029.027l-.116.095-.585.467Zm15.193-12.004-.001.002c-1.088 1.632-1.616 3.84-1.616 6.593 0 2.784.527 5.008 1.616 6.64l.001.002c1.128 1.668 2.934 2.48 5.347 2.48 2.412 0 4.211-.812 5.324-2.48 1.104-1.633 1.64-3.857 1.64-6.642 0-2.754-.536-4.962-1.64-6.594-1.113-1.669-2.912-2.48-5.324-2.48-2.413 0-4.219.812-5.347 2.48Zm7.226 3.03.001.003c.326.8.5 1.98.5 3.562 0 1.065-.063 1.939-.185 2.626-.119.652-.36 1.167-.711 1.562h-.001c-.305.344-.78.54-1.483.54-.699 0-1.185-.195-1.507-.54-.336-.394-.569-.91-.688-1.561-.122-.688-.185-1.562-.185-2.627 0-1.582.174-2.762.5-3.562v-.002c.153-.382.38-.653.677-.833.301-.182.696-.283 1.203-.283.507 0 .901.101 1.202.283.298.18.525.451.677.833Zm8.803.305-.002.002c-.62.593-.911 1.421-.911 2.44s.291 1.847.911 2.44l.002.002c.621.582 1.416.864 2.357.864.941 0 1.731-.282 2.342-.866.619-.593.91-1.421.91-2.44s-.291-1.847-.91-2.44c-.611-.584-1.401-.866-2.342-.866-.941 0-1.736.282-2.357.864Zm11.727-.224a.302.302 0 0 0-.264-.444h-2.934c-.11 0-.211.06-.264.156l-6.847 12.521a.3.3 0 0 0 .263.444h2.935a.3.3 0 0 0 .263-.156l6.848-12.521Zm-.542 8.835h-.001l.005.007c.097.126.17.352.17.725s-.073.598-.17.725c-.092.12-.214.184-.402.184-.204 0-.318-.066-.395-.175-.09-.128-.158-.357-.158-.734 0-.387.067-.62.155-.747.092-.118.214-.18.398-.18a.45.45 0 0 1 .398.195Zm-9.399-6.169c0-.383.068-.618.159-.75.078-.11.192-.177.394-.177.211 0 .33.068.409.18.093.131.163.364.163.747 0 .373-.073.598-.17.725-.092.121-.214.184-.402.184-.204 0-.318-.066-.395-.175-.09-.128-.158-.357-.158-.734Zm6.678 4.46c-.62.594-.911 1.422-.911 2.44 0 1.02.291 1.848.911 2.44.61.585 1.4.867 2.341.867.941 0 1.732-.282 2.342-.866.62-.593.911-1.421.911-2.44s-.291-1.847-.911-2.44c-.61-.584-1.401-.866-2.342-.866-.941 0-1.731.282-2.341.866Z" fill="#fff" stroke="#6BB171" stroke-width=".6" stroke-linejoin="round"/>
<path d="M60.254 4.092H17.878c-9.112 0-16.5 7.387-16.5 16.5v43.983c0 9.112 7.388 16.5 16.5 16.5h42.376c9.112 0 16.5-7.388 16.5-16.5V20.591c0-9.112-7.388-16.5-16.5-16.5Z" fill="url(#c)" stroke="#A7BFDA" stroke-width=".999"/>
<path d="M59.791 9.25H18.34c-6.903 0-12.499 5.597-12.499 12.5v41.666c0 6.903 5.596 12.5 12.5 12.5h41.45c6.903 0 12.5-5.597 12.5-12.5V21.75c0-6.903-5.597-12.5-12.5-12.5Z" stroke="#F8FBFF" stroke-width=".999"/>
<path d="M38.725 10.5h20.726c6.351 0 11.5 5.148 11.5 11.5v41.666c0 6.351-5.149 11.5-11.5 11.5H18c-6.352 0-11.5-5.149-11.5-11.5V22c0-6.352 5.148-11.5 11.5-11.5h20.725Z" fill="url(#d)" stroke="#B967AD" stroke-width=".999"/>
<path d="M28.513 54.808a.3.3 0 0 0 .247.13h4.288a.3.3 0 0 0 .247-.471l-4.172-6.02 4.063-6.106a.3.3 0 0 0 .007-.322l-1.02-1.682a.3.3 0 0 0-.4-.109l-3.111 1.683a.3.3 0 0 0-.116.112l-1.773 3.034-2.122-3.053a.3.3 0 0 0-.246-.13h-4.289a.3.3 0 0 0-.246.472l4.073 5.883-4.886 4.513a.3.3 0 0 0-.056.37l.967 1.676a.3.3 0 0 0 .26.15h4.132a.3.3 0 0 0 .26-.15l1.772-3.053 2.121 3.073Zm23.502-17.172a.3.3 0 0 0 .3-.3v-4.467a.3.3 0 0 0-.042-.154l-1.114-1.869a.3.3 0 0 0-.301-.143l-12.793 1.869a.3.3 0 0 0-.256.27l-.98 11.347a.3.3 0 0 0 .043.182l.98 1.608a.3.3 0 0 0 .256.144h4.914a.3.3 0 0 0 .29-.225c.122-.47.371-.838.75-1.113l.007-.005c.373-.289.86-.444 1.484-.444.856 0 1.46.24 1.864.678.409.442.636 1.103.636 2.03 0 .948-.218 1.671-.623 2.2-.387.503-.982.776-1.847.776-.743 0-1.29-.185-1.676-.52a2.45 2.45 0 0 1-.77-1.382.3.3 0 0 0-.294-.243H37.87a.3.3 0 0 0-.3.314c.062 1.32.424 2.494 1.091 3.516.67 1.024 1.617 1.823 2.833 2.4l.004.001c1.218.558 2.642.831 4.264.831 2.44 0 4.373-.693 5.754-2.115l.002-.002c1.375-1.438 2.048-3.365 2.048-5.746 0-1.289-.235-2.49-.709-3.602a6.226 6.226 0 0 0-2.28-2.75c-1.034-.718-2.329-1.066-3.862-1.066-.868 0-1.68.145-2.432.438a5.302 5.302 0 0 0-1.259.678v-3.136h8.991Z" fill="#FF96C6" stroke="#B967AD" stroke-width=".6" stroke-linejoin="round"/>
<path d="M27.397 52.947a.3.3 0 0 0 .247.13h4.288a.3.3 0 0 0 .246-.472l-4.172-6.019 4.064-6.106a.3.3 0 0 0-.25-.467h-4.132a.3.3 0 0 0-.259.15l-1.773 3.033-2.121-3.054a.3.3 0 0 0-.247-.129H19a.3.3 0 0 0-.247.471l4.107 5.933-4 6.197a.3.3 0 0 0 .252.462h4.132a.3.3 0 0 0 .259-.15l1.773-3.052 2.12 3.073Zm23.502-17.173a.3.3 0 0 0 .3-.3v-4.467a.3.3 0 0 0-.3-.3H36.992a.3.3 0 0 0-.3.3v12.954a.3.3 0 0 0 .3.3h4.914a.3.3 0 0 0 .29-.224c.122-.47.37-.838.75-1.114l.007-.005c.373-.288.86-.443 1.484-.443.856 0 1.46.24 1.864.677.408.443.635 1.104.635 2.03 0 .948-.218 1.672-.623 2.2-.386.504-.982.776-1.846.776-.743 0-1.29-.184-1.677-.52a2.45 2.45 0 0 1-.769-1.381.3.3 0 0 0-.294-.243h-4.973a.3.3 0 0 0-.3.314c.062 1.319.423 2.493 1.09 3.515.67 1.024 1.618 1.823 2.833 2.4l.004.002c1.219.558 2.643.831 4.264.831 2.44 0 4.374-.693 5.755-2.116l.001-.001c1.375-1.438 2.049-3.365 2.049-5.747 0-1.288-.236-2.49-.71-3.602a6.226 6.226 0 0 0-2.28-2.75c-1.034-.717-2.328-1.065-3.862-1.065-.868 0-1.68.145-2.431.437a5.301 5.301 0 0 0-1.26.679v-3.137H50.9Z" fill="#fff" stroke="#B967AD" stroke-width=".6" stroke-linejoin="round"/>
<path d="M163.376 4.092H121c-9.112 0-16.499 7.387-16.499 16.5v43.983c0 9.112 7.387 16.5 16.499 16.5h42.376c9.112 0 16.499-7.388 16.499-16.5V20.591c0-9.112-7.387-16.5-16.499-16.5Z" fill="url(#e)" stroke="#A7BFDA" stroke-width=".999"/>
<path d="M162.913 9.25h-41.451c-6.903 0-12.499 5.597-12.499 12.5v41.666c0 6.903 5.596 12.5 12.499 12.5h41.451c6.903 0 12.5-5.597 12.5-12.5V21.75c0-6.903-5.597-12.5-12.5-12.5Z" stroke="#F8FBFF" stroke-width=".999"/>
<path d="M141.847 10.5h20.726c6.351 0 11.5 5.148 11.5 11.5v41.666c0 6.351-5.149 11.5-11.5 11.5h-41.451c-6.352 0-11.501-5.149-11.501-11.5V22c0-6.352 5.149-11.5 11.501-11.5h20.725Z" fill="url(#f)" stroke="#6BB171" stroke-width=".999"/>
<path d="M123.015 44.667a.294.294 0 0 0-.045-.157l-.859-1.388a.3.3 0 0 0-.314-.136l-6.966 1.387a.297.297 0 0 0-.198.14l-.741 1.227a.298.298 0 0 0-.004.303l.741 1.299a.3.3 0 0 0 .261.151h7.825a.3.3 0 0 0 .3-.3v-2.526Zm2.005 4.022a.294.294 0 0 0-.083.104l-.832 1.714a.3.3 0 0 0 .018.292l.831 1.299a.3.3 0 0 0 .253.138h11.904a.3.3 0 0 0 .3-.3V48.64a.304.304 0 0 0-.043-.156l-.879-1.447a.3.3 0 0 0-.333-.134l-4.165 1.09c1.316-1.105 2.438-2.235 3.362-3.387l.001-.001c1.192-1.502 1.796-3.14 1.796-4.906 0-1.616-.505-2.953-1.533-3.981-1.024-1.041-2.529-1.536-4.458-1.536-1.131 0-2.172.222-3.117.67h-.001c-.268.13-.611.413-.965.747-.362.342-.763.763-1.151 1.197-.771.862-1.514 1.797-1.805 2.272-.06.097-.06.22.001.316l.784 1.257a.299.299 0 0 0 .254.14h3.913a.3.3 0 0 0 .3-.3c0-.786.16-1.345.438-1.716.288-.38.671-.568 1.183-.568.538 0 .892.16 1.12.436.242.293.382.723.382 1.327 0 .779-.28 1.598-.872 2.463a14.616 14.616 0 0 1-2.231 2.533l-.002.002c-.88.816-2.092 1.863-3.639 3.142a.245.245 0 0 0-.029.028l-.117.094c-.121.098-.316.254-.585.467Zm15.193-12.004-.001.002c-1.088 1.632-1.615 3.84-1.615 6.593 0 2.784.527 5.008 1.615 6.64l.001.002c1.129 1.668 2.935 2.48 5.347 2.48 2.412 0 4.211-.812 5.324-2.48 1.105-1.633 1.64-3.857 1.64-6.642 0-2.754-.536-4.962-1.64-6.594-1.113-1.669-2.912-2.48-5.324-2.48s-4.218.812-5.347 2.48Zm7.227 3.03.001.003c.326.8.499 1.98.499 3.562 0 1.065-.063 1.939-.185 2.626-.118.652-.359 1.167-.711 1.562-.306.344-.781.54-1.484.54-.699 0-1.184-.195-1.507-.54-.336-.394-.569-.91-.687-1.561-.123-.688-.185-1.562-.185-2.627 0-1.582.173-2.762.499-3.562l.001-.002c.153-.382.379-.653.677-.833.301-.182.696-.283 1.202-.283.507 0 .902.101 1.203.283.297.18.524.451.677.833Zm8.802.305-.002.002c-.62.593-.911 1.421-.911 2.44s.291 1.847.911 2.44l.002.002c.622.582 1.416.864 2.358.864.718 0 1.348-.164 1.877-.501l-3.74 5.347a.299.299 0 0 0-.003.34l.941 1.388a.3.3 0 0 0 .249.131h2.934c.11 0 .211-.06.264-.156l6.847-12.521a.3.3 0 0 0-.006-.299l-.793-1.316a.301.301 0 0 0-.414-.1l-2.142 1.315a.307.307 0 0 0-.089.084l-2.78 3.975c.072-.307.107-.638.107-.993 0-1.019-.291-1.847-.911-2.44-.61-.584-1.4-.866-2.341-.866-.942 0-1.736.282-2.358.864Zm11.185 8.611.005.007c.097.127.17.352.17.725s-.073.598-.17.725a.466.466 0 0 1-.402.184c-.204 0-.318-.066-.395-.175-.091-.128-.159-.357-.159-.734 0-.386.068-.62.156-.747.092-.118.213-.18.398-.18.18 0 .302.063.397.196Zm-9.399-6.169c0-.384.068-.618.16-.749.077-.112.191-.178.394-.178.211 0 .329.068.409.18.093.131.162.364.162.747 0 .373-.073.598-.169.725-.093.121-.215.184-.402.184-.205 0-.319-.066-.395-.175-.091-.128-.159-.357-.159-.734Zm6.678 4.46c-.62.594-.911 1.422-.911 2.44 0 1.02.291 1.848.911 2.44.61.585 1.401.867 2.342.867.941 0 1.731-.282 2.341-.866.62-.593.911-1.421.911-2.44s-.291-1.847-.911-2.44c-.61-.584-1.4-.866-2.341-.866-.941 0-1.732.282-2.342.866Z" fill="#9EDF99" stroke="#6BB171" stroke-width=".6" stroke-linejoin="round"/>
<path d="M122.126 43.185a.3.3 0 0 0-.3-.3H114a.3.3 0 0 0-.3.3v2.526a.3.3 0 0 0 .3.3h7.826a.3.3 0 0 0 .3-.3v-2.526Zm2.005 4.022a.3.3 0 0 0-.114.235v3.012a.3.3 0 0 0 .3.3h11.905a.3.3 0 0 0 .3-.3v-3.297a.3.3 0 0 0-.3-.3h-5.54c1.499-1.216 2.761-2.46 3.782-3.733l.001-.001c1.192-1.502 1.796-3.14 1.796-4.906 0-1.617-.506-2.953-1.534-3.982-1.024-1.04-2.528-1.535-4.458-1.535-1.131 0-2.171.222-3.116.67h-.002c-.941.454-1.702 1.16-2.283 2.105l-.002.004c-.571.956-.864 2.132-.896 3.514a.3.3 0 0 0 .3.307h3.913a.3.3 0 0 0 .3-.3c0-.787.159-1.346.437-1.717.288-.38.672-.568 1.183-.568.538 0 .892.16 1.121.436.242.293.382.723.382 1.327 0 .778-.281 1.598-.873 2.463a14.612 14.612 0 0 1-2.231 2.532l-.002.002c-.879.817-2.091 1.864-3.639 3.143a.377.377 0 0 0-.029.027l-.116.095-.585.467Zm15.193-12.004-.001.002c-1.088 1.632-1.616 3.84-1.616 6.593 0 2.784.527 5.008 1.616 6.64l.001.002c1.128 1.668 2.934 2.48 5.347 2.48 2.412 0 4.211-.812 5.324-2.48 1.104-1.633 1.64-3.858 1.64-6.642 0-2.754-.536-4.962-1.64-6.594-1.113-1.669-2.912-2.48-5.324-2.48-2.413 0-4.219.812-5.347 2.48Zm7.226 3.03.001.003c.326.8.5 1.98.5 3.562 0 1.065-.063 1.938-.185 2.626-.119.652-.36 1.167-.711 1.561h-.001c-.305.344-.78.54-1.483.54-.699 0-1.185-.194-1.507-.54-.336-.393-.569-.909-.688-1.56-.122-.688-.185-1.562-.185-2.627 0-1.582.174-2.762.5-3.563v-.001c.153-.382.38-.653.677-.833.301-.182.696-.283 1.203-.283.507 0 .901.101 1.202.283.298.18.525.451.677.833Zm8.803.305-.002.002c-.62.593-.911 1.421-.911 2.44s.291 1.847.911 2.44l.002.002c.621.582 1.416.864 2.357.864.941 0 1.731-.282 2.342-.866.619-.593.91-1.421.91-2.44s-.291-1.847-.91-2.44c-.611-.584-1.401-.866-2.342-.866-.941 0-1.736.282-2.357.864Zm11.727-.224a.302.302 0 0 0-.264-.444h-2.934c-.11 0-.211.06-.264.156l-6.847 12.52a.3.3 0 0 0 .263.445h2.935a.3.3 0 0 0 .263-.156l6.848-12.521Zm-.542 8.835h-.001l.005.007c.097.126.17.351.17.725 0 .373-.073.598-.17.725-.092.12-.214.184-.402.184-.204 0-.318-.066-.395-.175-.09-.128-.158-.357-.158-.734 0-.387.067-.62.155-.748.092-.118.214-.18.398-.18a.45.45 0 0 1 .398.196Zm-9.399-6.17c0-.383.068-.617.159-.748.078-.112.192-.178.394-.178.211 0 .33.068.409.18.093.131.163.364.163.747 0 .373-.073.598-.17.725-.092.12-.214.184-.402.184-.204 0-.318-.066-.395-.175-.09-.128-.158-.357-.158-.734Zm6.678 4.462c-.62.592-.911 1.421-.911 2.44s.291 1.847.911 2.44c.61.584 1.4.866 2.341.866.941 0 1.732-.282 2.342-.866.62-.593.911-1.421.911-2.44s-.291-1.848-.911-2.44c-.61-.584-1.401-.866-2.342-.866-.941 0-1.731.282-2.341.866Z" fill="#fff" stroke="#6BB171" stroke-width=".6" stroke-linejoin="round"/>
<path d="M95.99 3.608a14.19 14.19 0 0 0-14.202 0L58.353 17.154a14.19 14.19 0 0 0-7.089 12.286v27.12a14.19 14.19 0 0 0 7.089 12.286l23.435 13.546a14.19 14.19 0 0 0 14.203 0l23.435-13.546a14.191 14.191 0 0 0 7.088-12.286V29.44c0-5.067-2.702-9.75-7.088-12.286L95.991 3.608Z" fill="#ECF5FF" stroke="#A7BFDA" stroke-width=".86"/>
<path d="M88.89 2.133V43L53.534 22.564a13.75 13.75 0 0 1 5.033-5.037L82.003 3.98a13.751 13.751 0 0 1 6.886-1.847Z" fill="#F8FBFF"/>
<path d="M51.694 29.44v27.12c0 2.456.655 4.82 1.841 6.876L88.89 43 53.535 22.564a13.751 13.751 0 0 0-1.84 6.876Z" fill="url(#g)"/>
<path d="M126.084 56.571v-27.12c0-2.457-.655-4.82-1.841-6.876L88.889 43.011l35.354 20.436a13.753 13.753 0 0 0 1.841-6.876Z" fill="#E0EEFF"/>
<path d="M88.89 2.15v40.867l35.353-20.436a13.749 13.749 0 0 0-5.033-5.038L95.775 3.997A13.751 13.751 0 0 0 88.89 2.15Z" fill="url(#h)"/>
<path d="M58.565 68.472a13.751 13.751 0 0 1-5.03-5.036L88.89 43v40.867a13.75 13.75 0 0 1-6.884-1.847h-.002L58.568 68.473l-.003-.001Z" fill="url(#i)"/>
<path d="m95.775 82.02 23.435-13.547a13.749 13.749 0 0 0 5.033-5.037L88.889 43v40.867c2.378 0 4.756-.616 6.886-1.847Z" fill="#D1E5FE"/>
<path d="M82.864 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.04 12.04 0 0 1 6.015 10.424v23.946c0 4.3-2.293 8.272-6.015 10.424l-20.691 11.96a12.04 12.04 0 0 1-12.051 0l-20.692-11.96a12.04 12.04 0 0 1-6.014-10.424V31.027c0-4.3 2.292-8.272 6.014-10.424l20.692-11.96Z" fill="#A7BFDA"/>
<path d="M95.13 8.27a12.47 12.47 0 0 0-12.481 0L61.957 20.232a12.47 12.47 0 0 0-6.23 10.796v23.946a12.47 12.47 0 0 0 6.23 10.796l20.692 11.96a12.47 12.47 0 0 0 12.48 0l20.692-11.96a12.469 12.469 0 0 0 6.23-10.796V31.027c0-4.453-2.374-8.568-6.23-10.796L95.13 8.271Z" stroke="#F8FBFF" stroke-width=".86"/>
<path d="M83.08 9.015a11.61 11.61 0 0 1 11.62 0l20.691 11.96a11.61 11.61 0 0 1 5.8 10.052v23.946a11.61 11.61 0 0 1-5.8 10.051l-20.692 11.96a11.61 11.61 0 0 1-11.62 0l-20.691-11.96a11.61 11.61 0 0 1-5.8-10.051V31.027a11.61 11.61 0 0 1 5.8-10.051l20.691-11.96Z" stroke="#A7BFDA" stroke-width=".86"/>
<path d="M82.916 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.04 12.04 0 0 1 6.015 10.424v23.946c0 4.3-2.293 8.272-6.015 10.424l-20.692 11.96a12.04 12.04 0 0 1-12.05 0l-20.692-11.96a12.04 12.04 0 0 1-6.014-10.424V31.027c0-4.3 2.292-8.272 6.014-10.424l20.692-11.96Z" fill="#FFBA0D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M56.21 50.673v4.3c0 4.3 2.292 8.272 6.014 10.424l20.692 11.96a12.04 12.04 0 0 0 12.05 0l20.692-11.96a12.04 12.04 0 0 0 6.015-10.424v-4.3c0 4.3-2.293 8.272-6.015 10.424l-20.692 11.96a12.04 12.04 0 0 1-12.05 0l-20.692-11.96a12.04 12.04 0 0 1-6.014-10.424Z" fill="#E1910E"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M82.865 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.039 12.039 0 0 1 6.015 10.424v2.58c0-4.3-2.292-8.272-6.015-10.424l-20.691-11.96a12.04 12.04 0 0 0-12.05 0l-20.693 11.96a12.04 12.04 0 0 0-6.014 10.424v-2.58c0-4.3 2.292-8.272 6.014-10.424l20.692-11.96Z" fill="#FFD57C"/>
<path d="M83.13 9.015a11.61 11.61 0 0 1 11.621 0l20.692 11.96a11.61 11.61 0 0 1 5.8 10.052v23.946a11.61 11.61 0 0 1-5.8 10.051l-20.692 11.96a11.61 11.61 0 0 1-11.62 0l-20.692-11.96a11.61 11.61 0 0 1-5.8-10.051V31.027a11.61 11.61 0 0 1 5.8-10.051l20.692-11.96Z" stroke="#A05500" stroke-width=".86"/>
<g filter="url(#j)">
<path d="M92.115 50.74v-12.9l-1.72 1.72v9.46l1.72 1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M92.115 37.84h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M90.394 49.02v-9.46h-3.01v9.46h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m87.384 44.667 3.01 3.01v-5.053l-3.01-3.01v5.053Z" fill="#DABCFF"/>
<path d="M85.665 50.74h6.45l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M85.665 37.84v12.9l1.72-1.72v-9.46l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M85.665 37.84h6.45m-6.45 0v12.9m0-12.9 1.72 1.72m4.73-1.72v12.9m0-12.9-1.72 1.72m1.72 11.18h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-9.46m0 9.46h-3.01m0 0v-9.46m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g filter="url(#k)" stroke="#50119C" stroke-width=".86" stroke-linejoin="round">
<path d="M85.234 30.745v-6.45l-1.72 1.72v3.01l1.72 1.72Z" fill="#A964FD"/>
<path d="M85.235 24.295h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD"/>
<path d="M83.514 29.025v-3.01h-3.01v3.01h3.01Z" fill="#B77CFF"/>
<path d="M78.785 30.745h6.45l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA"/>
<path d="M78.785 24.295v6.45l1.72-1.72v-3.01l-1.72-1.72Z" fill="#7A2CDA"/>
<path d="M78.785 24.295h6.45m-6.45 0v6.45m0-6.45 1.72 1.72m4.73-1.72v6.45m0-6.45-1.72 1.72m1.72 4.73h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-3.01m0 3.01h-3.01m0 0v-3.01m0 0h3.01"/>
</g>
<g filter="url(#l)" stroke="#50119C" stroke-width=".86" stroke-linejoin="round">
<path d="M99.21 30.745v-6.45l-1.72 1.72v3.01l1.72 1.72Z" fill="#A964FD"/>
<path d="M99.21 24.295h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD"/>
<path d="M97.489 29.025v-3.01h-3.01v3.01h3.01Z" fill="#B77CFF"/>
<path d="M92.76 30.745h6.45l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA"/>
<path d="M92.76 24.295v6.45l1.72-1.72v-3.01l-1.72-1.72Z" fill="#7A2CDA"/>
<path d="M92.76 24.295h6.45m-6.45 0v6.45m0-6.45 1.72 1.72m4.73-1.72v6.45m0-6.45-1.72 1.72m1.72 4.73h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-3.01m0 3.01h-3.01m0 0v-3.01m0 0h3.01"/>
</g>
<g filter="url(#m)">
<path d="M78.784 57.405v-26.66l-1.72 1.72v23.22l1.72 1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M78.784 30.745h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M77.064 55.685v-23.22h-3.01v23.22h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m74.055 51.641 3.01 3.01v-3.307l-3.01-3.01v3.307Zm0-4.084 3.01 3.01v-1.463l-3.01-3.01v1.463Z" fill="#DABCFF"/>
<path d="M72.335 57.405h6.45l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M72.335 30.745v26.66l1.72-1.72v-23.22l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M72.335 30.745h6.45m-6.45 0v26.66m0-26.66 1.72 1.72m4.73-1.72v26.66m0-26.66-1.72 1.72m1.72 24.94h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-23.22m0 23.22h-3.01m0 0v-23.22m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g filter="url(#n)">
<path d="M105.659 57.405v-26.66l-1.72 1.72v23.22l1.72 1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M105.659 30.745h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M103.939 55.685v-23.22h-3.01v23.22h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m100.93 41.238 3.01 3.01V40.94l-3.01-3.01v3.308Zm0-4.085 3.01 3.01V38.7l-3.01-3.01v1.463Z" fill="#DABCFF"/>
<path d="M99.21 57.405h6.449l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M99.21 30.745v26.66l1.719-1.72v-23.22l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M99.21 30.745h6.449m-6.45 0v26.66m0-26.66 1.72 1.72m4.73-1.72v26.66m0-26.66-1.72 1.72m1.72 24.94h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-23.22m0 23.22h-3.01m0 0v-23.22m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g style="mix-blend-mode:color-burn">
<mask id="o" maskUnits="userSpaceOnUse" x="48.954" y="13.265" width="23" height="61" fill="#000">
<path fill="#fff" d="M48.954 13.265h23v61h-23z"/>
<path d="M66.283 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.137.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.093 9.093 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.098-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.868 50.868 0 0 0-.707 7.367c.079-.08.099-.2.138-.319.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.962-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.717-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.178.02-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097c.471-.32.942-.599 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.058-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.021-.858.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.101 4.493c-.157.12-.138.2-.06.36a55.346 55.346 0 0 0 3.004 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a92.016 92.016 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.787-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.451.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.375.118.2.216.4.354.62-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.886-3.434a9.274 9.274 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.217.798.374 1.177 0-.12.02-.16.02-.279.176-2.056.45-4.093.863-6.11.04-.2.02-.359-.216-.439a9.5 9.5 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.619.117.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.589-1.218-.589-2.456-.334-3.714.079-.46.197-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.579-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.392-1.258.844-1.717.53-.58 1.158-1.019 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z"/>
</mask>
<path d="M66.283 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.137.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.093 9.093 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.098-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.868 50.868 0 0 0-.707 7.367c.079-.08.099-.2.138-.319.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.962-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.717-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.178.02-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097c.471-.32.942-.599 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.058-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.021-.858.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.101 4.493c-.157.12-.138.2-.06.36a55.346 55.346 0 0 0 3.004 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a92.016 92.016 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.787-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.451.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.375.118.2.216.4.354.62-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.886-3.434a9.274 9.274 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.217.798.374 1.177 0-.12.02-.16.02-.279.176-2.056.45-4.093.863-6.11.04-.2.02-.359-.216-.439a9.5 9.5 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.619.117.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.589-1.218-.589-2.456-.334-3.714.079-.46.197-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.579-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.392-1.258.844-1.717.53-.58 1.158-1.019 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z" fill="#000" fill-opacity=".16"/>
<path d="M66.283 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.137.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.093 9.093 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.098-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.868 50.868 0 0 0-.707 7.367c.079-.08.099-.2.138-.319.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.962-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.717-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.178.02-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097c.471-.32.942-.599 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.058-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.021-.858.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.101 4.493c-.157.12-.138.2-.06.36a55.346 55.346 0 0 0 3.004 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a92.016 92.016 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.787-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.451.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.375.118.2.216.4.354.62-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.886-3.434a9.274 9.274 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.217.798.374 1.177 0-.12.02-.16.02-.279.176-2.056.45-4.093.863-6.11.04-.2.02-.359-.216-.439a9.5 9.5 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.619.117.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.589-1.218-.589-2.456-.334-3.714.079-.46.197-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.579-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.392-1.258.844-1.717.53-.58 1.158-1.019 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z" stroke="#000" stroke-opacity=".16" stroke-width="2.15" stroke-linejoin="round" mask="url(#o)"/>
</g>
<path d="M64.993 18.478c-.608 1.258-1.688 1.917-2.886 2.396-.137.08-.274.2-.333.32-.452 1.018-.884 2.076-1.316 3.074-.157.38-.275.739-.451 1.198.51-.659.962-1.218 1.413-1.757.825-.978 1.806-1.717 3.122-1.917 1.335-.22 2.67-.1 3.985.24.04.04.059.04.138.08-.334.499-.629 1.018-.943 1.477-.687.899-1.511 1.637-2.61 2.037a10.27 10.27 0 0 1-4.791.359c-.157-.06-.295-.08-.452-.12a46.477 46.477 0 0 0-1.865 7.128c.314-.46.59-.978.864-1.438.687-1.178 1.551-2.116 2.866-2.575a9.092 9.092 0 0 1 3.083-.52c.333 0 .687.04 1.099.04-.196.48-.334.9-.49 1.298-.511 1.099-1.14 2.057-2.16 2.696-1.218.818-2.592 1.218-4.025 1.357-.452.04-.942.08-1.413.12a50.868 50.868 0 0 0-.707 7.368c.078-.08.098-.2.137-.32.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.962-.44 1.983-.699 3.023-.858.177 0 .354-.04.55-.08v.24c-.04.219-.079.498-.137.778-.334 1.437-.884 2.815-2.101 3.753-1.276 1.059-2.768 1.718-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .589 7.527c.177-.819.314-1.598.471-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.138 0 .275-.08.491-.12-.02.719-.04 1.338-.118 1.957-.137 1.138-.451 2.176-1.178 3.035-1.236 1.437-2.729 2.535-4.515 3.154-.059 0-.118.04-.196.08.451 2.316 1.06 4.572 1.884 6.748.04-.399 0-.778.02-1.178.02-1.317.236-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.473-.858c.059.22.078.42.118.579.274 1.637.274 3.234-.55 4.712-.687 1.218-1.63 2.236-2.73 3.094-.411.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.828 6.07 0-.12 0-.2-.02-.28-.06-.54-.138-1.138-.197-1.677a5.277 5.277 0 0 1 .59-2.895c.569-1.038 1.335-1.937 2.238-2.716.333-.26.667-.539 1.02-.858.491 1.178.766 2.316.805 3.474 0 .659-.039 1.318-.294 1.956a11.52 11.52 0 0 1-3.102 4.493c-.157.12-.137.2-.059.36a55.327 55.327 0 0 0 3.004 4.471s-.197.4-1.512-.459c-.314-.459-.628-.898-.923-1.397a90.378 90.378 0 0 1-1.786-2.955c-.118-.26-.236-.34-.51-.26-1.728.4-3.476.4-5.184-.08-1.217-.32-2.198-1.098-3.003-2.036-.354-.42-.668-.939-1.001-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.375-.459 2.788-.698 4.221-.578 1.433.08 2.592.778 3.612 1.797.236.24.452.459.727.658-.02-.08-.059-.16-.098-.24a53.463 53.463 0 0 1-2.395-5.69c-.06-.199-.138-.239-.334-.239-1.708.12-3.377-.2-4.947-.898-1.218-.54-2.062-1.478-2.71-2.616-.314-.499-.55-1.078-.844-1.697.57 0 1.08-.08 1.59-.08.982-.04 1.964.04 2.925.3 1.316.399 2.238 1.218 3.024 2.296.196.24.353.479.51.718-.49-2.136-.981-4.292-1.472-6.428-.785-.2-1.63-.36-2.415-.62-1.217-.419-2.356-1.018-3.259-1.996-.785-.858-1.59-2.735-1.688-3.893h.039c1.688.02 3.318.34 4.79 1.278.903.539 1.473 1.437 1.944 2.376.118.2.216.399.353.618-.196-2.136-.275-4.252-.117-6.388-1.06-.32-2.023-.74-2.906-1.318-1.296-.859-2.415-1.877-2.886-3.434a9.27 9.27 0 0 1-.432-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.942.399 1.806.898 2.532 1.677.628.678.962 1.497 1.237 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279a53.12 53.12 0 0 1 .863-6.11c.04-.2.02-.359-.215-.439a9.502 9.502 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.825-3.474 0-.459.06-.898.118-1.437.59.32 1.159.559 1.65.858 1.099.64 2.06 1.418 2.689 2.536.49.858.608 1.837.687 2.815.04.3.04.619.118.898l.059-.24c.51-2.056 1.119-4.132 1.904-6.128.079-.2.079-.32-.098-.42-1.355-.978-2.376-2.216-3.122-3.753-.589-1.218-.589-2.456-.333-3.714.078-.46.196-.878.314-1.338l.039-.04c.864.54 1.669 1.159 2.356 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.099 1.218-.138 1.917.04-.08.059-.12.079-.2.432-.898.864-1.797 1.295-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.393-1.258.844-1.717.53-.58 1.158-1.019 1.826-1.398.353-.24.707-.4 1.08-.579.059 0 .098.04.157.04-.02.3-.079.579-.098.878-.04 1.099-.295 2.197-.786 3.155Z" fill="#FFD57C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M64.647 50.047c-1.26 3.726-2.24 5.921-4.306 8.904l-.622-1.43a2.854 2.854 0 0 1-.007.07c-.07-.187-.139-.373-.206-.56l-.071-.164-.045-.164a41.59 41.59 0 0 1-1.431-5.213l-.03-.105-.015-.112a29.85 29.85 0 0 1-.086-.431l.022-.012-.16-1.127-.039.18a40.27 40.27 0 0 1-.589-7.526c.046-.01.09-.017.132-.023l.063-1.312-.022.075a.551.551 0 0 1-.114.241c.059-2.495.294-4.951.707-7.367l.045-.004.277-1.196a8.15 8.15 0 0 1-.146.222 46.474 46.474 0 0 1 1.866-7.128l.139.033c.103.023.203.045.312.087 1.61.26 3.22.14 4.79-.36 1.1-.399 1.924-1.137 2.611-2.036.165-.24.324-.497.486-.759l.046-.074c-2.923 1.732-5.053 2.57-8.135 3.108l.42-1.075c-.172.215-.348.44-.532.677.073-.19.136-.362.196-.527.085-.233.163-.448.255-.671.177-.409.354-.827.532-1.25a113.8 113.8 0 0 1 .784-1.825.726.726 0 0 1 .203-.23h-.265a257.17 257.17 0 0 1-.802 1.685 63.337 63.337 0 0 0-1.866 4.691 56.278 56.278 0 0 0-1.118 3.937l-.059.24-.005-.019c-.785 3.807-1.117 7.949-1.337 10.7l-.044.557c-.046 1.659.036 3.31.188 4.973l-.09-.149c.089.786.204 1.612.341 2.453l.721 3.147.736 3.214a70.416 70.416 0 0 0-.073-.11c.216.752.44 1.46.671 2.1.095.025.146.086.188.227.344.968.717 1.932 1.117 2.883.45 1.022.864 1.935 1.253 2.756l.025.05.058.125c.365.765.71 1.447 1.044 2.06.042.047.078.11.115.192.245.429.497.855.753 1.278.324.501.64 1.022.933 1.515l.1.161c.24.408.494.775.75 1.146l.173.252c1.316.859 1.512.46 1.512.46a55.325 55.325 0 0 1-3.004-4.473c-.07-.143-.093-.222.015-.323l-1.016-1.815v.002c.02.08.02.16.02.28-1.1-1.937-2.023-3.974-2.827-6.07l.14-.09c.381-.247.749-.484 1.116-.769 1.1-.858 2.042-1.877 2.729-3.094.825-1.478.825-3.075.55-4.712a3.384 3.384 0 0 1-.044-.225 8.635 8.635 0 0 0-.028-.151Zm2.019 6.741c-.755 4.362-1.306 6.716-2.54 9.8a11.522 11.522 0 0 0 3.027-4.426c.255-.638.294-1.297.294-1.956-.038-1.14-.305-2.26-.781-3.418Zm-4.635 9.679c-3.288-.513-5.542-1.555-8.849-3.39.114.152.226.312.34.473.18.258.362.518.556.749.805.938 1.786 1.717 3.004 2.036 1.63.458 3.297.478 4.949.132Zm-3.407-8.086c-2.815-1.035-4.77-2.366-8.195-5.008l.12.26c.202.44.391.853.623 1.222.648 1.138 1.492 2.077 2.71 2.616 1.507.67 3.105.992 4.742.91Zm-2.106-8.512c-2.84-1.502-4.332-3.052-6.77-6.411a13.11 13.11 0 0 0-.166-.003h-.039c.098 1.158.903 3.035 1.688 3.893.903.978 2.042 1.577 3.26 1.997.533.176 1.093.306 1.644.434l.383.09Zm-.312-8.64c-2.329-1.938-3.622-3.769-5.678-7.464a16.117 16.117 0 0 1-.189-.07l-.01.027-.006.158c-.004.075-.007.123.005.171.02.858.177 1.717.432 2.536.471 1.557 1.59 2.575 2.886 3.434.787.515 1.635.904 2.56 1.209Zm1.045-8.499c-1.973-2.34-3.042-4.092-4.542-8.194l-.013.116c-.048.432-.09.805-.09 1.193-.02 1.258.137 2.416.824 3.474a9.499 9.499 0 0 0 3.821 3.411Zm2.6-7.899.012.001c-1.854-3.366-2.53-5.368-3.279-8.884l-.054.21c-.096.37-.188.722-.253 1.102-.255 1.258-.255 2.496.334 3.714.746 1.537 1.767 2.775 3.121 3.753a.318.318 0 0 1 .119.104ZM65.839 14.8c-.983 2.306-1.84 3.829-3.644 6.038 1.163-.476 2.205-1.133 2.798-2.36.491-.958.747-2.056.786-3.155.01-.15.03-.294.049-.439l.011-.084Zm-.102 14.161c-2.762 2.514-4.66 3.892-7.419 4.969.314-.026.627-.052.923-.079 1.433-.14 2.808-.539 4.025-1.357 1.02-.64 1.649-1.598 2.16-2.696.066-.168.128-.34.193-.517l.118-.32Zm-1.53 6.738c-2.631 3.117-4.301 4.833-6.995 6.633.067-.009.131-.014.193-.019l.167-.016c1.63-.36 3.122-1.018 4.398-2.077 1.217-.938 1.767-2.316 2.1-3.753.04-.186.07-.373.098-.541l.038-.227Zm-.38 7.236c-2.143 3.5-3.571 5.613-5.66 7.776 1.724-.627 3.169-1.705 4.372-3.103.727-.859 1.041-1.897 1.178-3.035.067-.526.091-1.051.11-1.638Z" fill="#E1910E"/>
<mask id="p" maskUnits="userSpaceOnUse" x="47.665" y="12.405" width="23" height="61" fill="#000">
<path fill="#fff" d="M47.665 12.405h23v61h-23z"/>
<path d="M64.994 18.478c-.609 1.258-1.689 1.917-2.886 2.396-.137.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.058.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.571.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.489 46.489 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.092 9.092 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.099-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.868 50.868 0 0 0-.707 7.368c.079-.08.098-.2.138-.32.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.961-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.718-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.314-1.598.471-2.376.256-1.098.786-2.077 1.63-2.815 1.06-.899 2.297-1.478 3.593-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.73 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.039-.399 0-.778.02-1.178.019-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.472-.858c.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.02-.858.492 1.178.767 2.316.806 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.102 4.493c-.157.12-.137.2-.058.36a55.327 55.327 0 0 0 3.003 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a90.378 90.378 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.1-.2l.119-.08c1.374-.459 2.788-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.618-.197-2.136-.275-4.252-.118-6.388-1.06-.32-2.022-.74-2.906-1.318-1.295-.859-2.414-1.877-2.886-3.434a9.27 9.27 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279.177-2.056.452-4.093.864-6.11.04-.2.02-.359-.216-.439a9.503 9.503 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.686 2.815.04.3.04.619.118.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.59-2.456-.334-3.714.079-.46.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.392-1.258.844-1.717.53-.58 1.158-1.019 1.825-1.398.354-.24.707-.4 1.08-.579.06 0 .098.04.157.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z"/>
</mask>
<path d="M64.994 18.478c-.609 1.258-1.689 1.917-2.886 2.396-.137.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.058.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.571.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.489 46.489 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.092 9.092 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.099-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.868 50.868 0 0 0-.707 7.368c.079-.08.098-.2.138-.32.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.961-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.718-4.398 2.077-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.314-1.598.471-2.376.256-1.098.786-2.077 1.63-2.815 1.06-.899 2.297-1.478 3.593-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.73 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.039-.399 0-.778.02-1.178.019-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.472-.858c.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.02-.858.492 1.178.767 2.316.806 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.102 4.493c-.157.12-.137.2-.058.36a55.327 55.327 0 0 0 3.003 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a90.378 90.378 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.1-.2l.119-.08c1.374-.459 2.788-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.618-.197-2.136-.275-4.252-.118-6.388-1.06-.32-2.022-.74-2.906-1.318-1.295-.859-2.414-1.877-2.886-3.434a9.27 9.27 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279.177-2.056.452-4.093.864-6.11.04-.2.02-.359-.216-.439a9.503 9.503 0 0 1-3.868-3.434c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.686 2.815.04.3.04.619.118.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.59-2.456-.334-3.714.079-.46.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.392-1.258.844-1.717.53-.58 1.158-1.019 1.825-1.398.354-.24.707-.4 1.08-.579.06 0 .098.04.157.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z" stroke="#A05500" stroke-width="2.15" stroke-linejoin="round" mask="url(#p)"/>
<g style="mix-blend-mode:color-burn">
<mask id="q" maskUnits="userSpaceOnUse" x="105.809" y="13.265" width="23" height="61" fill="#000">
<path fill="#fff" d="M105.809 13.265h23v61h-23z"/>
<path d="M111.48 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.452 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.068 58.068 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.138.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.612 2.037 1.57.499 3.18.619 4.79.359.157-.06.294-.08.451-.12a46.43 46.43 0 0 1 1.865 7.128c-.314-.46-.589-.978-.863-1.438-.688-1.178-1.551-2.116-2.867-2.575a9.088 9.088 0 0 0-3.082-.52c-.334 0-.687.04-1.099.04.196.48.333.9.49 1.298.511 1.098 1.139 2.057 2.16 2.696 1.217.818 2.591 1.218 4.025 1.357.451.04.942.08 1.413.12.412 2.416.648 4.872.707 7.367-.079-.08-.098-.2-.138-.319-.157-.46-.333-.938-.51-1.438-.55-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.549-.08v.24c.039.219.078.498.137.778.334 1.437.883 2.815 2.101 3.753 1.276 1.059 2.768 1.717 4.397 2.077.157.02.314.02.511.06a40.287 40.287 0 0 1-.589 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.019.719.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.516 3.154.059 0 .118.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.019-1.178-.02-1.317-.236-2.555-1.041-3.613a8.456 8.456 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.629 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.274 5.274 0 0 0-.589-2.895c-.569-1.038-1.335-1.937-2.238-2.716a18.02 18.02 0 0 1-1.021-.858c-.491 1.178-.765 2.316-.805 3.474 0 .659.04 1.318.295 1.956a11.509 11.509 0 0 0 3.102 4.493c.157.12.137.2.059.36a55.375 55.375 0 0 1-3.004 4.471s.196.4 1.512-.459c.314-.459.628-.898.922-1.397a90.923 90.923 0 0 0 1.787-2.955c.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.32 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.658.019-.08.059-.16.098-.24a53.462 53.462 0 0 0 2.395-5.69c.059-.199.137-.239.334-.239 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.062-1.478 2.709-2.616.315-.499.55-1.078.845-1.697-.57 0-1.08-.08-1.591-.08-.981-.04-1.963.04-2.925.3-1.315.399-2.238 1.218-3.023 2.296-.197.24-.354.479-.511.718.491-2.136.982-4.292 1.473-6.428.785-.2 1.629-.36 2.415-.62 1.217-.419 2.355-1.018 3.258-1.996.786-.858 1.591-2.735 1.689-3.893h-.039c-1.689.02-3.318.34-4.791 1.278-.903.539-1.472 1.437-1.943 2.375-.118.2-.216.4-.354.62.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.414-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.019-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.533 1.677-.628.678-.962 1.497-1.236 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.307 53.307 0 0 0-.864-6.11c-.039-.2-.019-.359.216-.439a9.506 9.506 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.099.64-2.061 1.418-2.689 2.536-.491.858-.609 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.511-2.056-1.119-4.132-1.904-6.128-.079-.2-.079-.32.098-.42 1.354-.978 2.375-2.216 3.121-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.196-.878-.314-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.512 4.093.039.579.098 1.218.138 1.917a.829.829 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.019-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.019.3.078.579.098.878.039 1.099.295 2.197.785 3.155Z"/>
</mask>
<path d="M111.48 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.452 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.068 58.068 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.138.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.612 2.037 1.57.499 3.18.619 4.79.359.157-.06.294-.08.451-.12a46.43 46.43 0 0 1 1.865 7.128c-.314-.46-.589-.978-.863-1.438-.688-1.178-1.551-2.116-2.867-2.575a9.088 9.088 0 0 0-3.082-.52c-.334 0-.687.04-1.099.04.196.48.333.9.49 1.298.511 1.098 1.139 2.057 2.16 2.696 1.217.818 2.591 1.218 4.025 1.357.451.04.942.08 1.413.12.412 2.416.648 4.872.707 7.367-.079-.08-.098-.2-.138-.319-.157-.46-.333-.938-.51-1.438-.55-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.549-.08v.24c.039.219.078.498.137.778.334 1.437.883 2.815 2.101 3.753 1.276 1.059 2.768 1.717 4.397 2.077.157.02.314.02.511.06a40.287 40.287 0 0 1-.589 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.019.719.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.516 3.154.059 0 .118.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.019-1.178-.02-1.317-.236-2.555-1.041-3.613a8.456 8.456 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.629 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.274 5.274 0 0 0-.589-2.895c-.569-1.038-1.335-1.937-2.238-2.716a18.02 18.02 0 0 1-1.021-.858c-.491 1.178-.765 2.316-.805 3.474 0 .659.04 1.318.295 1.956a11.509 11.509 0 0 0 3.102 4.493c.157.12.137.2.059.36a55.375 55.375 0 0 1-3.004 4.471s.196.4 1.512-.459c.314-.459.628-.898.922-1.397a90.923 90.923 0 0 0 1.787-2.955c.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.32 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.658.019-.08.059-.16.098-.24a53.462 53.462 0 0 0 2.395-5.69c.059-.199.137-.239.334-.239 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.062-1.478 2.709-2.616.315-.499.55-1.078.845-1.697-.57 0-1.08-.08-1.591-.08-.981-.04-1.963.04-2.925.3-1.315.399-2.238 1.218-3.023 2.296-.197.24-.354.479-.511.718.491-2.136.982-4.292 1.473-6.428.785-.2 1.629-.36 2.415-.62 1.217-.419 2.355-1.018 3.258-1.996.786-.858 1.591-2.735 1.689-3.893h-.039c-1.689.02-3.318.34-4.791 1.278-.903.539-1.472 1.437-1.943 2.375-.118.2-.216.4-.354.62.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.414-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.019-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.533 1.677-.628.678-.962 1.497-1.236 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.307 53.307 0 0 0-.864-6.11c-.039-.2-.019-.359.216-.439a9.506 9.506 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.099.64-2.061 1.418-2.689 2.536-.491.858-.609 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.511-2.056-1.119-4.132-1.904-6.128-.079-.2-.079-.32.098-.42 1.354-.978 2.375-2.216 3.121-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.196-.878-.314-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.512 4.093.039.579.098 1.218.138 1.917a.829.829 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.019-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.019.3.078.579.098.878.039 1.099.295 2.197.785 3.155Z" fill="#000" fill-opacity=".16"/>
<path d="M111.48 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.452 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.068 58.068 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.138.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.612 2.037 1.57.499 3.18.619 4.79.359.157-.06.294-.08.451-.12a46.43 46.43 0 0 1 1.865 7.128c-.314-.46-.589-.978-.863-1.438-.688-1.178-1.551-2.116-2.867-2.575a9.088 9.088 0 0 0-3.082-.52c-.334 0-.687.04-1.099.04.196.48.333.9.49 1.298.511 1.098 1.139 2.057 2.16 2.696 1.217.818 2.591 1.218 4.025 1.357.451.04.942.08 1.413.12.412 2.416.648 4.872.707 7.367-.079-.08-.098-.2-.138-.319-.157-.46-.333-.938-.51-1.438-.55-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.549-.08v.24c.039.219.078.498.137.778.334 1.437.883 2.815 2.101 3.753 1.276 1.059 2.768 1.717 4.397 2.077.157.02.314.02.511.06a40.287 40.287 0 0 1-.589 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.019.719.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.516 3.154.059 0 .118.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.019-1.178-.02-1.317-.236-2.555-1.041-3.613a8.456 8.456 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.629 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.274 5.274 0 0 0-.589-2.895c-.569-1.038-1.335-1.937-2.238-2.716a18.02 18.02 0 0 1-1.021-.858c-.491 1.178-.765 2.316-.805 3.474 0 .659.04 1.318.295 1.956a11.509 11.509 0 0 0 3.102 4.493c.157.12.137.2.059.36a55.375 55.375 0 0 1-3.004 4.471s.196.4 1.512-.459c.314-.459.628-.898.922-1.397a90.923 90.923 0 0 0 1.787-2.955c.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.32 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.658.019-.08.059-.16.098-.24a53.462 53.462 0 0 0 2.395-5.69c.059-.199.137-.239.334-.239 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.062-1.478 2.709-2.616.315-.499.55-1.078.845-1.697-.57 0-1.08-.08-1.591-.08-.981-.04-1.963.04-2.925.3-1.315.399-2.238 1.218-3.023 2.296-.197.24-.354.479-.511.718.491-2.136.982-4.292 1.473-6.428.785-.2 1.629-.36 2.415-.62 1.217-.419 2.355-1.018 3.258-1.996.786-.858 1.591-2.735 1.689-3.893h-.039c-1.689.02-3.318.34-4.791 1.278-.903.539-1.472 1.437-1.943 2.375-.118.2-.216.4-.354.62.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.414-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.019-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.533 1.677-.628.678-.962 1.497-1.236 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.307 53.307 0 0 0-.864-6.11c-.039-.2-.019-.359.216-.439a9.506 9.506 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.099.64-2.061 1.418-2.689 2.536-.491.858-.609 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.511-2.056-1.119-4.132-1.904-6.128-.079-.2-.079-.32.098-.42 1.354-.978 2.375-2.216 3.121-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.196-.878-.314-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.512 4.093.039.579.098 1.218.138 1.917a.829.829 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.019-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.019.3.078.579.098.878.039 1.099.295 2.197.785 3.155Z" stroke="#000" stroke-opacity=".16" stroke-width="2.15" stroke-linejoin="round" mask="url(#q)"/>
</g>
<path d="M112.771 18.478c.608 1.258 1.688 1.917 2.886 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a58.114 58.114 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.039.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.546 46.546 0 0 1 1.865 7.128c-.314-.46-.589-.978-.864-1.438-.687-1.178-1.551-2.116-2.866-2.575a9.092 9.092 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.491 1.298.51 1.099 1.139 2.057 2.159 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.647 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.511-1.438-.549-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.039.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.203 40.203 0 0 1-.589 7.527c-.176-.819-.314-1.598-.471-2.376-.255-1.098-.785-2.077-1.629-2.815-1.061-.899-2.297-1.478-3.593-1.957-.137 0-.275-.08-.491-.12.02.719.039 1.338.118 1.957.137 1.138.451 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.059 0 .118.04.197.08-.452 2.316-1.061 4.572-1.885 6.748-.039-.399 0-.778-.02-1.178-.019-1.317-.235-2.555-1.04-3.613a8.47 8.47 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.473-.858-.058.22-.078.42-.117.579-.275 1.637-.275 3.234.549 4.712.688 1.218 1.63 2.236 2.729 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.019-.28.059-.54.138-1.138.197-1.677a5.283 5.283 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.039 1.318.294 1.956a11.53 11.53 0 0 0 3.102 4.493c.157.12.138.2.059.36a55.357 55.357 0 0 1-3.004 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397.608-.979 1.217-1.957 1.786-2.955.118-.26.236-.34.511-.26 1.727.4 3.475.4 5.183-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.019-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.059-.16.098-.24a53.469 53.469 0 0 0 2.396-5.69c.059-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.569 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.491-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.118.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.159.7-.943.399-1.807.898-2.533 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.019-.16-.019-.279a53.305 53.305 0 0 0-.864-6.11c-.04-.2-.02-.359.216-.439a9.498 9.498 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.1.64-2.062 1.418-2.69 2.536-.491.858-.608 1.837-.687 2.815-.039.3-.039.619-.118.898a20.4 20.4 0 0 0-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.629 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.039-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.019-1.637-.197-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.707-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z" fill="#FFD57C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M113.118 50.048c1.261 3.725 2.24 5.92 4.306 8.903l.623-1.432a.86.86 0 0 0 .006.071c.071-.188.141-.376.209-.566l.068-.157.043-.157a41.54 41.54 0 0 0 1.435-5.228l.027-.097.015-.104c.03-.146.059-.292.087-.44a.407.407 0 0 0-.023-.011l.161-1.128.039.182c.432-2.496.628-4.992.589-7.527a2.003 2.003 0 0 0-.132-.023l-.064-1.314c.009.026.016.051.023.077a.551.551 0 0 0 .114.241 50.783 50.783 0 0 0-.707-7.367l-.045-.004-.278-1.197c.048.075.097.15.147.223a46.543 46.543 0 0 0-1.865-7.128l-.139.033c-.104.023-.204.045-.313.087-1.61.26-3.22.14-4.79-.36-1.1-.399-1.924-1.137-2.611-2.036a19.248 19.248 0 0 1-.532-.833c2.923 1.732 5.053 2.57 8.135 3.108l-.42-1.077c.171.216.348.44.532.679-.073-.19-.136-.363-.195-.527a16.808 16.808 0 0 0-.256-.671 147.49 147.49 0 0 1-.532-1.25 113.8 113.8 0 0 0-.784-1.825.707.707 0 0 0-.203-.23h.266c.264.562.529 1.118.794 1.67a63.425 63.425 0 0 1 1.881 4.729 56.425 56.425 0 0 1 1.11 3.914l.059.24.005-.018c.785 3.807 1.116 7.948 1.336 10.698l.046.568c.045 1.655-.037 3.303-.189 4.963l.089-.148a48.93 48.93 0 0 1-.342 2.46c-.24 1.043-.479 2.09-.719 3.139l-.736 3.214.072-.11c-.215.752-.44 1.46-.67 2.1-.095.025-.146.086-.188.227-.34.96-.71 1.916-1.107 2.86a111.02 111.02 0 0 1-1.277 2.809l-.011.02-.054.114c-.367.77-.713 1.456-1.049 2.073a.752.752 0 0 0-.114.19c-.242.425-.492.847-.746 1.266-.33.51-.653 1.042-.951 1.544l-.089.144a19.06 19.06 0 0 1-.75 1.146l-.173.252c-1.315.859-1.512.46-1.512.46a55.355 55.355 0 0 0 3.004-4.473c.07-.143.093-.222-.015-.323l1.016-1.816v.003c-.019.08-.019.16-.019.28 1.099-1.938 2.022-3.974 2.827-6.07l-.14-.09a15.39 15.39 0 0 1-1.117-.769c-1.099-.858-2.042-1.877-2.729-3.094-.824-1.478-.824-3.075-.549-4.712.016-.069.029-.144.044-.225l.027-.15Zm-2.019 6.74c.755 4.362 1.306 6.716 2.54 9.8a11.523 11.523 0 0 1-3.027-4.426c-.255-.639-.294-1.297-.294-1.956.038-1.14.305-2.26.781-3.417Zm4.635 9.679c3.288-.513 5.542-1.555 8.849-3.39-.114.151-.226.312-.339.473-.18.258-.363.518-.557.749-.805.938-1.786 1.717-3.004 2.036-1.631.458-3.297.478-4.949.132Zm3.407-8.086c2.815-1.036 4.77-2.366 8.195-5.008l-.12.26c-.202.44-.391.853-.623 1.222-.648 1.138-1.492 2.076-2.709 2.616-1.508.67-3.107.992-4.743.91Zm2.105-8.512c2.841-1.502 4.333-3.052 6.77-6.411a4.65 4.65 0 0 1 .167-.003h.039c-.098 1.158-.903 3.035-1.688 3.893-.903.978-2.042 1.577-3.259 1.996-.533.177-1.094.307-1.645.435l-.384.09Zm.312-8.64c2.329-1.938 3.623-3.769 5.679-7.464l.189-.07.011.028c.001.064.003.115.006.157.003.075.006.123-.006.17a9.296 9.296 0 0 1-.432 2.537c-.471 1.557-1.59 2.575-2.886 3.434a10.79 10.79 0 0 1-2.561 1.209Zm-1.045-8.498c1.973-2.34 3.043-4.093 4.543-8.196l.013.117c.049.431.091.805.091 1.193.019 1.258-.138 2.416-.825 3.474a9.494 9.494 0 0 1-3.822 3.412Zm-2.598-7.9-.013.001c1.854-3.366 2.529-5.368 3.279-8.885l.054.21c.097.37.188.723.253 1.103.256 1.258.256 2.496-.333 3.713-.746 1.538-1.767 2.776-3.122 3.754a.315.315 0 0 0-.118.104Zm-5.989-10.03c.983 2.305 1.839 3.828 3.643 6.037-1.162-.476-2.204-1.133-2.797-2.36-.491-.959-.746-2.057-.786-3.155-.009-.15-.029-.294-.049-.439l-.011-.083Zm.103 14.16c2.761 2.514 4.659 3.892 7.418 4.969l-.923-.079c-1.433-.14-2.807-.539-4.025-1.357-1.021-.64-1.649-1.598-2.159-2.696-.066-.168-.129-.34-.194-.517l-.117-.32Zm1.53 6.739c2.63 3.116 4.3 4.831 6.994 6.632a4.18 4.18 0 0 0-.193-.019 3.78 3.78 0 0 1-.167-.016c-1.63-.36-3.122-1.019-4.398-2.077-1.217-.938-1.767-2.316-2.101-3.753-.039-.187-.069-.373-.097-.541l-.038-.226Zm.38 7.236c2.142 3.5 3.57 5.612 5.658 7.775-1.723-.628-3.168-1.705-4.371-3.103-.727-.859-1.041-1.897-1.178-3.035a16.932 16.932 0 0 1-.109-1.637Z" fill="#E1910E"/>
<mask id="r" maskUnits="userSpaceOnUse" x="107.1" y="12.405" width="23" height="61" fill="#000">
<path fill="#fff" d="M107.1 12.405h23v61h-23z"/>
<path d="M112.771 18.478c.608 1.258 1.688 1.917 2.886 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a58.114 58.114 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.039.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.546 46.546 0 0 1 1.865 7.128c-.314-.46-.589-.978-.864-1.438-.687-1.178-1.551-2.116-2.866-2.575a9.092 9.092 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.491 1.298.51 1.099 1.139 2.057 2.159 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.647 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.511-1.438-.549-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.039.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.203 40.203 0 0 1-.589 7.527c-.176-.819-.314-1.598-.471-2.376-.255-1.098-.785-2.077-1.629-2.815-1.061-.899-2.297-1.478-3.593-1.957-.137 0-.275-.08-.491-.12.02.719.039 1.338.118 1.957.137 1.138.451 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.059 0 .118.04.197.08-.452 2.316-1.061 4.572-1.885 6.748-.039-.399 0-.778-.02-1.178-.019-1.317-.235-2.555-1.04-3.613a8.47 8.47 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.473-.858-.058.22-.078.42-.117.579-.275 1.637-.275 3.234.549 4.712.688 1.218 1.63 2.236 2.729 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.019-.28.059-.54.138-1.138.197-1.677a5.283 5.283 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.039 1.318.294 1.956a11.53 11.53 0 0 0 3.102 4.493c.157.12.138.2.059.36a55.357 55.357 0 0 1-3.004 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397.608-.979 1.217-1.957 1.786-2.955.118-.26.236-.34.511-.26 1.727.4 3.475.4 5.183-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.019-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.059-.16.098-.24a53.469 53.469 0 0 0 2.396-5.69c.059-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.569 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.491-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.118.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.159.7-.943.399-1.807.898-2.533 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.019-.16-.019-.279a53.305 53.305 0 0 0-.864-6.11c-.04-.2-.02-.359.216-.439a9.498 9.498 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.1.64-2.062 1.418-2.69 2.536-.491.858-.608 1.837-.687 2.815-.039.3-.039.619-.118.898a20.4 20.4 0 0 0-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.629 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.039-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.019-1.637-.197-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.707-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z"/>
</mask>
<path d="M112.771 18.478c.608 1.258 1.688 1.917 2.886 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a58.114 58.114 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.039.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.546 46.546 0 0 1 1.865 7.128c-.314-.46-.589-.978-.864-1.438-.687-1.178-1.551-2.116-2.866-2.575a9.092 9.092 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.491 1.298.51 1.099 1.139 2.057 2.159 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.647 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.511-1.438-.549-1.437-1.472-2.535-2.866-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.039.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.203 40.203 0 0 1-.589 7.527c-.176-.819-.314-1.598-.471-2.376-.255-1.098-.785-2.077-1.629-2.815-1.061-.899-2.297-1.478-3.593-1.957-.137 0-.275-.08-.491-.12.02.719.039 1.338.118 1.957.137 1.138.451 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.059 0 .118.04.197.08-.452 2.316-1.061 4.572-1.885 6.748-.039-.399 0-.778-.02-1.178-.019-1.317-.235-2.555-1.04-3.613a8.47 8.47 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.473-.858-.058.22-.078.42-.117.579-.275 1.637-.275 3.234.549 4.712.688 1.218 1.63 2.236 2.729 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.019-.28.059-.54.138-1.138.197-1.677a5.283 5.283 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.039 1.318.294 1.956a11.53 11.53 0 0 0 3.102 4.493c.157.12.138.2.059.36a55.357 55.357 0 0 1-3.004 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397.608-.979 1.217-1.957 1.786-2.955.118-.26.236-.34.511-.26 1.727.4 3.475.4 5.183-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.019-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.059-.16.098-.24a53.469 53.469 0 0 0 2.396-5.69c.059-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.569 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.491-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.118.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.297 9.297 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.159.7-.943.399-1.807.898-2.533 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.019-.16-.019-.279a53.305 53.305 0 0 0-.864-6.11c-.04-.2-.02-.359.216-.439a9.498 9.498 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.059-.898-.118-1.437-.589.32-1.158.559-1.649.858-1.1.64-2.062 1.418-2.69 2.536-.491.858-.608 1.837-.687 2.815-.039.3-.039.619-.118.898a20.4 20.4 0 0 0-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.629 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.039-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.039-.818.019-1.637-.197-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.707-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z" stroke="#A05500" stroke-width="2.15" stroke-linejoin="round" mask="url(#r)"/>
<defs>
<linearGradient id="a" x1="109.566" y1="40.326" x2="174.913" y2="40.326" gradientUnits="userSpaceOnUse">
<stop stop-color="#D5E8FF"/>
<stop offset="1" stop-color="#89BEFF"/>
</linearGradient>
<linearGradient id="b" x1="110" y1="5" x2="190.936" y2="56.174" gradientUnits="userSpaceOnUse">
<stop offset=".1" stop-color="#ACEEBD"/>
<stop offset=".9" stop-color="#E3F0B6"/>
</linearGradient>
<linearGradient id="c" x1="39.066" y1="-.409" x2="39.066" y2="85.575" gradientUnits="userSpaceOnUse">
<stop stop-color="#ECF5FF"/>
<stop offset="1" stop-color="#D1E5FE"/>
</linearGradient>
<linearGradient id="d" x1="6" y1="5" x2="86.936" y2="56.174" gradientUnits="userSpaceOnUse">
<stop offset=".1" stop-color="#FCC0FF"/>
<stop offset=".9" stop-color="#FFD5B3"/>
</linearGradient>
<linearGradient id="e" x1="142.188" y1="-.409" x2="142.188" y2="85.575" gradientUnits="userSpaceOnUse">
<stop stop-color="#ECF5FF"/>
<stop offset="1" stop-color="#D1E5FE"/>
</linearGradient>
<linearGradient id="f" x1="109.122" y1="10" x2="183.13" y2="63.92" gradientUnits="userSpaceOnUse">
<stop offset=".1" stop-color="#ACEEBD"/>
<stop offset=".9" stop-color="#E3F0B6"/>
</linearGradient>
<linearGradient id="g" x1="70.292" y1="22.564" x2="70.292" y2="63.436" gradientUnits="userSpaceOnUse">
<stop stop-color="#E0EEFF"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
<linearGradient id="h" x1="88.889" y1="4.193" x2="124.149" y2="4.193" gradientUnits="userSpaceOnUse">
<stop stop-color="#E0EEFF"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
<linearGradient id="i" x1="54.382" y1="63.425" x2="88.889" y2="63.425" gradientUnits="userSpaceOnUse">
<stop stop-color="#D1E5FE"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
<filter id="j" x="85.234" y="37.41" width="7.31" height="15.48" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2138_22191"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2138_22191" result="shape"/>
</filter>
<filter id="k" x="78.355" y="23.865" width="7.31" height="9.03" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2138_22191"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2138_22191" result="shape"/>
</filter>
<filter id="l" x="92.329" y="23.865" width="7.31" height="9.03" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2138_22191"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2138_22191" result="shape"/>
</filter>
<filter id="m" x="71.904" y="30.315" width="7.31" height="29.24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2138_22191"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2138_22191" result="shape"/>
</filter>
<filter id="n" x="98.779" y="30.315" width="7.31" height="29.24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2138_22191"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2138_22191" result="shape"/>
</filter>
</defs>
</svg>
import type { InteropMessage } from 'types/api/interop';
import { ADDRESS_HASH } from './addressParams';
import { TX_HASH } from './tx';
export const INTEROP_MESSAGE: InteropMessage = {
init_transaction_hash: TX_HASH,
nonce: 52,
payload: '0x4f0edcc90000000000000000000000007da521cbbe62e89cd75e0993c78b8c68c25f696b',
relay_chain: {
chain_id: 420120000,
chain_name: 'Optimism Testnet',
chain_logo: null,
instance_url: 'https://optimism-interop-alpha-0.blockscout.com/',
},
relay_transaction_hash: TX_HASH,
sender: ADDRESS_HASH,
status: 'Relayed',
target: ADDRESS_HASH,
timestamp: '2025-02-20T01:05:14.000000Z',
};
...@@ -110,6 +110,7 @@ export const TOKEN_TRANSFER_ERC_721: TokenTransfer = { ...@@ -110,6 +110,7 @@ export const TOKEN_TRANSFER_ERC_721: TokenTransfer = {
...TOKEN_TRANSFER_ERC_20, ...TOKEN_TRANSFER_ERC_20,
total: { total: {
token_id: '35870', token_id: '35870',
token_instance: null,
}, },
token: TOKEN_INFO_ERC_721, token: TOKEN_INFO_ERC_721,
}; };
...@@ -120,6 +121,7 @@ export const TOKEN_TRANSFER_ERC_1155: TokenTransfer = { ...@@ -120,6 +121,7 @@ export const TOKEN_TRANSFER_ERC_1155: TokenTransfer = {
token_id: '35870', token_id: '35870',
value: '123', value: '123',
decimals: '18', decimals: '18',
token_instance: null,
}, },
token: TOKEN_INFO_ERC_1155, token: TOKEN_INFO_ERC_1155,
}; };
...@@ -130,6 +132,7 @@ export const TOKEN_TRANSFER_ERC_404: TokenTransfer = { ...@@ -130,6 +132,7 @@ export const TOKEN_TRANSFER_ERC_404: TokenTransfer = {
token_id: '35870', token_id: '35870',
value: '123', value: '123',
decimals: '18', decimals: '18',
token_instance: null,
}, },
token: TOKEN_INFO_ERC_404, token: TOKEN_INFO_ERC_404,
}; };
......
...@@ -32,6 +32,7 @@ export const STATE_CHANGE_TOKEN: TxStateChange = { ...@@ -32,6 +32,7 @@ export const STATE_CHANGE_TOKEN: TxStateChange = {
direction: 'to', direction: 'to',
total: { total: {
token_id: '1621395', token_id: '1621395',
token_instance: null,
}, },
}, },
], ],
......
...@@ -4,56 +4,58 @@ import { scroller, Element } from 'react-scroll'; ...@@ -4,56 +4,58 @@ import { scroller, Element } from 'react-scroll';
import useUpdateEffect from 'lib/hooks/useUpdateEffect'; import useUpdateEffect from 'lib/hooks/useUpdateEffect';
import type { ButtonProps } from './button'; import type { LinkProps } from './link';
import { Button } from './button'; import { Link } from './link';
interface CollapsibleDetailsProps extends ButtonProps { interface CollapsibleDetailsProps extends LinkProps {
children: React.ReactNode; children: React.ReactNode;
id?: string; id?: string;
isExpanded?: boolean; isExpanded?: boolean;
text?: [string, string]; text?: [string, string];
noScroll?: boolean;
} }
const SCROLL_CONFIG = {
duration: 500,
smooth: true,
};
const CUT_ID = 'CollapsibleDetails';
export const CollapsibleDetails = (props: CollapsibleDetailsProps) => { export const CollapsibleDetails = (props: CollapsibleDetailsProps) => {
const CUT_ID = 'CollapsibleDetails';
const { children, id = CUT_ID, onClick, isExpanded: isExpandedProp = false, text: textProp, loading, ...rest } = props; const { children, id = CUT_ID, onClick, isExpanded: isExpandedProp = false, text: textProp, loading, noScroll, ...rest } = props;
const [ isExpanded, setIsExpanded ] = React.useState(isExpandedProp); const [ isExpanded, setIsExpanded ] = React.useState(isExpandedProp);
const handleClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => { const handleClick = React.useCallback((event: React.MouseEvent<HTMLAnchorElement>) => {
setIsExpanded((flag) => !flag); setIsExpanded((flag) => !flag);
scroller.scrollTo(id, { if (!noScroll) {
duration: 500, scroller.scrollTo(id, SCROLL_CONFIG);
smooth: true, }
});
onClick?.(event); onClick?.(event);
}, [ id, onClick ]); }, [ id, noScroll, onClick ]);
useUpdateEffect(() => { useUpdateEffect(() => {
setIsExpanded(isExpandedProp); setIsExpanded(isExpandedProp);
isExpandedProp && scroller.scrollTo(id, { isExpandedProp && !noScroll && scroller.scrollTo(id, SCROLL_CONFIG);
duration: 500, }, [ isExpandedProp, id, noScroll ]);
smooth: true,
});
}, [ isExpandedProp, id ]);
const text = isExpanded ? (textProp?.[1] ?? 'Hide details') : (textProp?.[0] ?? 'View details'); const text = isExpanded ? (textProp?.[1] ?? 'Hide details') : (textProp?.[0] ?? 'View details');
return ( return (
<> <>
<Button <Link
variant="link"
textStyle="sm" textStyle="sm"
textDecorationLine="underline" textDecorationLine="underline"
textDecorationStyle="dashed" textDecorationStyle="dashed"
w="fit-content" w="fit-content"
onClick={ handleClick } onClick={ handleClick }
loadingSkeleton={ loading } loading={ loading }
{ ...rest } { ...rest }
> >
<Element name={ id }>{ text }</Element> <Element name={ id }>{ text }</Element>
</Button> </Link>
{ isExpanded && children } { isExpanded && children }
</> </>
); );
...@@ -62,7 +64,7 @@ export const CollapsibleDetails = (props: CollapsibleDetailsProps) => { ...@@ -62,7 +64,7 @@ export const CollapsibleDetails = (props: CollapsibleDetailsProps) => {
interface CollapsibleListProps<T> extends FlexProps { interface CollapsibleListProps<T> extends FlexProps {
items: Array<T>; items: Array<T>;
renderItem: (item: T, index: number) => React.ReactNode; renderItem: (item: T, index: number) => React.ReactNode;
triggerProps?: ButtonProps; triggerProps?: LinkProps;
cutLength?: number; cutLength?: number;
} }
...@@ -81,8 +83,7 @@ export const CollapsibleList = <T,>(props: CollapsibleListProps<T>) => { ...@@ -81,8 +83,7 @@ export const CollapsibleList = <T,>(props: CollapsibleListProps<T>) => {
<Flex flexDir="column" w="100%" { ...rest }> <Flex flexDir="column" w="100%" { ...rest }>
{ items.slice(0, isExpanded ? undefined : cutLength).map(renderItem) } { items.slice(0, isExpanded ? undefined : cutLength).map(renderItem) }
{ items.length > cutLength && ( { items.length > cutLength && (
<Button <Link
variant="link"
textStyle="sm" textStyle="sm"
textDecorationLine="underline" textDecorationLine="underline"
textDecorationStyle="dashed" textDecorationStyle="dashed"
...@@ -92,7 +93,7 @@ export const CollapsibleList = <T,>(props: CollapsibleListProps<T>) => { ...@@ -92,7 +93,7 @@ export const CollapsibleList = <T,>(props: CollapsibleListProps<T>) => {
{ ...triggerProps } { ...triggerProps }
> >
{ isExpanded ? 'Hide' : 'Show all' } { isExpanded ? 'Hide' : 'Show all' }
</Button> </Link>
) } ) }
</Flex> </Flex>
); );
......
...@@ -11,13 +11,15 @@ const PRESETS = { ...@@ -11,13 +11,15 @@ const PRESETS = {
eth: 'https://eth.blockscout.com', eth: 'https://eth.blockscout.com',
eth_goerli: 'https://eth-goerli.blockscout.com', eth_goerli: 'https://eth-goerli.blockscout.com',
eth_sepolia: 'https://eth-sepolia.blockscout.com', eth_sepolia: 'https://eth-sepolia.blockscout.com',
garnet: 'https://explorer.garnetchain.com',
filecoin: 'https://filecoin.blockscout.com', filecoin: 'https://filecoin.blockscout.com',
garnet: 'https://explorer.garnetchain.com',
gnosis: 'https://gnosis.blockscout.com', gnosis: 'https://gnosis.blockscout.com',
immutable: 'https://explorer.immutable.com',
mekong: 'https://mekong.blockscout.com', mekong: 'https://mekong.blockscout.com',
neon_devnet: 'https://neon-devnet.blockscout.com', neon_devnet: 'https://neon-devnet.blockscout.com',
optimism: 'https://optimism.blockscout.com', optimism: 'https://optimism.blockscout.com',
optimism_celestia: 'https://opcelestia-raspberry.gelatoscout.com', optimism_celestia: 'https://opcelestia-raspberry.gelatoscout.com',
optimism_interop_0: 'https://optimism-interop-alpha-0.blockscout.com',
optimism_sepolia: 'https://optimism-sepolia.blockscout.com', optimism_sepolia: 'https://optimism-sepolia.blockscout.com',
polygon: 'https://polygon.blockscout.com', polygon: 'https://polygon.blockscout.com',
rari_testnet: 'https://rari-testnet.cloud.blockscout.com', rari_testnet: 'https://rari-testnet.cloud.blockscout.com',
......
export interface ChainInfo {
chain_id: number;
chain_name: string | null;
chain_logo: string | null;
instance_url: string;
}
export type MessageStatus = 'Sent' | 'Relayed' | 'Failed';
export interface InteropMessage {
init_transaction_hash: string;
init_chain?: ChainInfo | null;
nonce: number;
payload: string;
relay_chain?: ChainInfo | null;
relay_transaction_hash: string | null;
sender: string;
status: MessageStatus;
target: string;
timestamp: string;
}
export interface InteropMessageListResponse {
items: Array<InteropMessage>;
next_page_params?: {
init_transaction_hash: string;
items_count: number;
timestamp: number;
};
}
...@@ -12,6 +12,8 @@ export type RewardsConfigResponse = { ...@@ -12,6 +12,8 @@ export type RewardsConfigResponse = {
export type RewardsCheckRefCodeResponse = { export type RewardsCheckRefCodeResponse = {
valid: boolean; valid: boolean;
is_custom: boolean;
reward: string | null;
}; };
export type RewardsNonceResponse = { export type RewardsNonceResponse = {
......
...@@ -59,10 +59,12 @@ export interface TokenInstance { ...@@ -59,10 +59,12 @@ export interface TokenInstance {
holder_address_hash: string | null; holder_address_hash: string | null;
image_url: string | null; image_url: string | null;
animation_url: string | null; animation_url: string | null;
media_url?: string | null;
media_type?: string | null;
external_app_url: string | null; external_app_url: string | null;
metadata: Record<string, unknown> | null; metadata: Record<string, unknown> | null;
owner: AddressParam | null; owner: AddressParam | null;
thumbnails: Partial<Record<ThumbnailSize, string>> | null; thumbnails: ({ original: string } & Partial<Record<Exclude<ThumbnailSize, 'original'>, string>>) | null;
} }
export interface TokenInstanceMetadataSocketMessage { export interface TokenInstanceMetadataSocketMessage {
......
import type { AddressParam } from './addressParams'; import type { AddressParam } from './addressParams';
import type { TokenInfo, TokenType } from './token'; import type { TokenInfo, TokenInstance, TokenType } from './token';
export type Erc20TotalPayload = { export type Erc20TotalPayload = {
decimals: string | null; decimals: string | null;
...@@ -8,20 +8,24 @@ export type Erc20TotalPayload = { ...@@ -8,20 +8,24 @@ export type Erc20TotalPayload = {
export type Erc721TotalPayload = { export type Erc721TotalPayload = {
token_id: string | null; token_id: string | null;
token_instance: TokenInstance | null;
}; };
export type Erc1155TotalPayload = { export type Erc1155TotalPayload = {
decimals: string | null; decimals: string | null;
value: string; value: string;
token_id: string | null; token_id: string | null;
token_instance: TokenInstance | null;
}; };
export type Erc404TotalPayload = { export type Erc404TotalPayload = {
decimals: string; decimals: string;
value: string; value: string;
token_id: null; token_id: null;
token_instance: TokenInstance | null;
} | { } | {
token_id: string; token_id: string;
token_instance: TokenInstance | null;
}; };
export type TokenTransfer = ( export type TokenTransfer = (
......
...@@ -3,6 +3,7 @@ import type { ArbitrumBatchStatus, ArbitrumL2TxData } from './arbitrumL2'; ...@@ -3,6 +3,7 @@ import type { ArbitrumBatchStatus, ArbitrumL2TxData } from './arbitrumL2';
import type { BlockTransactionsResponse } from './block'; import type { BlockTransactionsResponse } from './block';
import type { DecodedInput } from './decodedInput'; import type { DecodedInput } from './decodedInput';
import type { Fee } from './fee'; import type { Fee } from './fee';
import type { ChainInfo, MessageStatus } from './interop';
import type { NovesTxTranslation } from './noves'; import type { NovesTxTranslation } from './noves';
import type { OptimisticL2WithdrawalStatus } from './optimisticL2'; import type { OptimisticL2WithdrawalStatus } from './optimisticL2';
import type { ScrollL2BlockStatus } from './scrollL2'; import type { ScrollL2BlockStatus } from './scrollL2';
...@@ -107,6 +108,8 @@ export type Transaction = { ...@@ -107,6 +108,8 @@ export type Transaction = {
scroll?: ScrollTransactionData; scroll?: ScrollTransactionData;
// EIP-7702 // EIP-7702
authorization_list?: Array<TxAuthorization>; authorization_list?: Array<TxAuthorization>;
// Interop
op_interop?: InteropTransactionInfo;
}; };
type ArbitrumTransactionData = { type ArbitrumTransactionData = {
...@@ -215,3 +218,15 @@ export interface TxAuthorization { ...@@ -215,3 +218,15 @@ export interface TxAuthorization {
chain_id: number; chain_id: number;
nonce: number; nonce: number;
} }
export interface InteropTransactionInfo {
nonce: number;
payload: string;
init_chain?: ChainInfo | null;
relay_chain?: ChainInfo | null;
init_transaction_hash?: string;
relay_transaction_hash?: string;
sender: string;
status: MessageStatus;
target: string;
}
...@@ -33,6 +33,7 @@ const NFTItem = ({ token, value, isLoading, withTokenLink, ...tokenInstance }: P ...@@ -33,6 +33,7 @@ const NFTItem = ({ token, value, isLoading, withTokenLink, ...tokenInstance }: P
<NftMedia <NftMedia
mb="18px" mb="18px"
data={ tokenInstance } data={ tokenInstance }
size="md"
isLoading={ isLoading } isLoading={ isLoading }
autoplayVideo={ false } autoplayVideo={ false }
/> />
......
import { chakra, Text, Flex } from '@chakra-ui/react';
import React from 'react';
import type { InteropMessage } from 'types/api/interop';
import { PopoverBody, PopoverCloseTriggerWrapper, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import AdditionalInfoButton from 'ui/shared/AdditionalInfoButton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
type Props = {
payload: InteropMessage['payload'];
isLoading?: boolean;
className?: string;
};
const InteropMessageAdditionalInfo = ({ payload, isLoading, className }: Props) => {
return (
<PopoverRoot positioning={{ placement: 'right-start' }}>
<PopoverTrigger>
<AdditionalInfoButton loading={ isLoading } className={ className }/>
</PopoverTrigger>
<PopoverContent w="330px">
<PopoverBody>
<Flex alignItems="center" justifyContent="space-between" mb={ 3 }>
<Text color="text.secondary" fontWeight="600">Message payload</Text>
<PopoverCloseTriggerWrapper>
<CopyToClipboard text={ payload }/>
</PopoverCloseTriggerWrapper>
</Flex>
<Text>
{ payload }
</Text>
</PopoverBody>
</PopoverContent>
</PopoverRoot>
);
};
export default React.memo(chakra(InteropMessageAdditionalInfo));
import React from 'react';
import type { ChainInfo } from 'types/api/interop';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import type { EntityProps } from 'ui/shared/entities/tx/TxEntity';
import TxEntityInterop from 'ui/shared/entities/tx/TxEntityInterop';
type Props = {
relay_transaction_hash?: string | null;
relay_chain?: ChainInfo | null;
truncation?: EntityProps['truncation'];
isLoading?: boolean;
};
const InteropMessageDestinationTx = (props: Props) => {
if (props.relay_chain !== undefined) {
return (
<TxEntityInterop
chain={ props.relay_chain }
hash={ props.relay_transaction_hash }
isLoading={ props.isLoading }
truncation={ props.truncation || 'constant' }
/>
);
}
if (!props.relay_transaction_hash) {
return 'N/A';
}
return (
<TxEntity
hash={ props.relay_transaction_hash }
isLoading={ props.isLoading }
noIcon
truncation={ props.truncation || 'constant' }
/>
);
};
export default InteropMessageDestinationTx;
import React from 'react';
import type { ChainInfo } from 'types/api/interop';
import type { EntityProps } from 'ui/shared/entities/tx/TxEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityInterop from 'ui/shared/entities/tx/TxEntityInterop';
type Props = {
init_transaction_hash?: string | null;
init_chain?: ChainInfo | null;
isLoading?: boolean;
truncation?: EntityProps['truncation'];
};
const InteropMessageSourceTx = (props: Props) => {
if (props.init_chain !== undefined) {
return (
<TxEntityInterop
chain={ props.init_chain }
hash={ props.init_transaction_hash }
isLoading={ props.isLoading }
truncation={ props.truncation || 'constant' }
/>
);
}
if (!props.init_transaction_hash) {
return 'N/A';
}
return (
<TxEntity
hash={ props.init_transaction_hash }
isLoading={ props.isLoading }
noIcon
truncation={ props.truncation || 'constant' }
/>
);
};
export default InteropMessageSourceTx;
import { Flex, HStack, Text, Grid } from '@chakra-ui/react';
import React from 'react';
import type { InteropMessage } from 'types/api/interop';
import AddressFromToIcon from 'ui/shared/address/AddressFromToIcon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressEntityInterop from 'ui/shared/entities/address/AddressEntityInterop';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import InteropMessageStatus from 'ui/shared/statusTag/InteropMessageStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import InteropMessageAdditionalInfo from './InteropMessageAdditionalInfo';
import InteropMessageDestinationTx from './InteropMessageDestinationTx';
import InteropMessageSourceTx from './InteropMessageSourceTx';
interface Props {
item: InteropMessage;
isLoading?: boolean;
}
const InteropMessagesListItem = ({ item, isLoading }: Props) => {
return (
<ListItemMobile rowGap={ 2 }>
<Flex alignItems="center" justifyContent="space-between" w="100%">
<InteropMessageStatus status={ item.status } isLoading={ isLoading }/>
<InteropMessageAdditionalInfo payload={ item.payload } isLoading={ isLoading }/>
</Flex>
<Flex alignItems="flex-start" flexDirection="column" gap={ 2 } w="100%">
<HStack w="100%">
<Text fontWeight={ 500 } flexGrow={ 1 }>#{ item.nonce }</Text>
<TimeAgoWithTooltip timestamp={ item.timestamp } isLoading={ isLoading } color="text.secondary"/>
</HStack>
<Grid templateColumns="120px 1fr" rowGap={ 2 }>
<Text as="span" color="text.secondary">Source tx</Text>
<InteropMessageSourceTx { ...item } isLoading={ isLoading }/>
<Text as="span" color="text.secondary">Destination tx</Text>
<InteropMessageDestinationTx { ...item } isLoading={ isLoading }/>
</Grid>
<Flex gap={ 2 } justifyContent="space-between" mt={ 2 }>
{ item.init_chain !== undefined ? (
<AddressEntityInterop
chain={ item.init_chain }
address={{ hash: item.sender }}
isLoading={ isLoading }
truncation="constant"
/>
) : (
<AddressEntity address={{ hash: item.sender }} isLoading={ isLoading } truncation="constant"/>
) }
<AddressFromToIcon
isLoading={ isLoading }
type={ item.init_chain !== undefined ? 'in' : 'out' }
/>
{ item.relay_chain !== undefined ? (
<AddressEntityInterop
chain={ item.relay_chain }
address={{ hash: item.target }}
isLoading={ isLoading }
truncation="constant"
/>
) : (
<AddressEntity address={{ hash: item.target }} isLoading={ isLoading } truncation="constant"/>
) }
</Flex>
</Flex>
</ListItemMobile>
);
};
export default React.memo(InteropMessagesListItem);
import React from 'react';
import type { InteropMessage } from 'types/api/interop';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import InteropMessagesTableItem from './InteropMessagesTableItem';
interface Props {
items?: Array<InteropMessage>;
top: number;
isLoading?: boolean;
}
const InteropMessagesTable = ({ items, top, isLoading }: Props) => {
return (
<TableRoot tableLayout="auto">
<TableHeaderSticky top={ top }>
<TableRow>
<TableColumnHeader/>
<TableColumnHeader>Message</TableColumnHeader>
<TableColumnHeader>Age</TableColumnHeader>
<TableColumnHeader>Status</TableColumnHeader>
<TableColumnHeader>Source tx</TableColumnHeader>
<TableColumnHeader>Destination tx</TableColumnHeader>
<TableColumnHeader>Sender</TableColumnHeader>
<TableColumnHeader>In/Out</TableColumnHeader>
<TableColumnHeader>Target</TableColumnHeader>
</TableRow>
</TableHeaderSticky>
<TableBody>
{ items?.map((item, index) => (
<InteropMessagesTableItem
key={ item.init_transaction_hash + '_' + index }
item={ item }
isLoading={ isLoading }
/>
)) }
</TableBody>
</TableRoot>
);
};
export default React.memo(InteropMessagesTable);
import React from 'react';
import type { InteropMessage } from 'types/api/interop';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import AddressFromToIcon from 'ui/shared/address/AddressFromToIcon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressEntityInterop from 'ui/shared/entities/address/AddressEntityInterop';
import InteropMessageStatus from 'ui/shared/statusTag/InteropMessageStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import InteropMessageAdditionalInfo from './InteropMessageAdditionalInfo';
import InteropMessageDestinationTx from './InteropMessageDestinationTx';
import InteropMessageSourceTx from './InteropMessageSourceTx';
interface Props {
item: InteropMessage;
isLoading?: boolean;
}
const InteropMessagesTableItem = ({ item, isLoading }: Props) => {
return (
<TableRow>
<TableCell>
<InteropMessageAdditionalInfo payload={ item.payload } isLoading={ isLoading }/>
</TableCell>
<TableCell>
<Skeleton loading={ isLoading } fontWeight="700">
{ item.nonce }
</Skeleton>
</TableCell>
<TableCell>
<TimeAgoWithTooltip timestamp={ item.timestamp } isLoading={ isLoading } color="text.secondary"/>
</TableCell>
<TableCell>
<InteropMessageStatus status={ item.status } isLoading={ isLoading }/>
</TableCell>
<TableCell>
<InteropMessageSourceTx { ...item } isLoading={ isLoading }/>
</TableCell>
<TableCell>
<InteropMessageDestinationTx { ...item } isLoading={ isLoading }/>
</TableCell>
<TableCell>
{ item.init_chain !== undefined ?
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.init_chain }/> :
<AddressEntity address={{ hash: item.target }} isLoading={ isLoading } truncation="constant"/>
}
</TableCell>
<TableCell>
<AddressFromToIcon
isLoading={ isLoading }
type={ item.init_chain !== undefined ? 'in' : 'out' }
/>
</TableCell>
<TableCell>
{ item.relay_chain !== undefined ?
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.relay_chain }/> :
<AddressEntity address={{ hash: item.target }} isLoading={ isLoading } truncation="constant"/>
}
</TableCell>
</TableRow>
);
};
export default React.memo(InteropMessagesTableItem);
import React from 'react';
import * as interopMessageMock from 'mocks/interop/interop';
import { test, expect } from 'playwright/lib';
import InteropMessages from './InteropMessages';
test('default view +@mobile', async({ render, mockTextAd, mockAssetResponse, mockApiResponse }) => {
await mockTextAd();
await mockAssetResponse(interopMessageMock.chain.chain_logo as string, './playwright/mocks/image_s.jpg');
await mockApiResponse('optimistic_l2_interop_messages', {
items: [
interopMessageMock.interopMessageIn,
interopMessageMock.interopMessageIn1,
interopMessageMock.interopMessageOut,
interopMessageMock.interopMessageOut1,
],
next_page_params: {
init_transaction_hash: '1',
items_count: 4,
timestamp: 1719456000,
},
});
await mockApiResponse('optimistic_l2_interop_messages_count', 4000000);
const component = await render(<InteropMessages/>);
await expect(component).toHaveScreenshot();
});
import { Box } from '@chakra-ui/react';
import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import { INTEROP_MESSAGE } from 'stubs/interop';
import { generateListStub } from 'stubs/utils';
import { Skeleton } from 'toolkit/chakra/skeleton';
import InteropMessagesListItem from 'ui/interopMessages/InteropMessagesListItem';
import InteropMessagesTable from 'ui/interopMessages/InteropMessagesTable';
import { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay';
import PageTitle from 'ui/shared/Page/PageTitle';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
const InteropMessages = () => {
const interopMessagesQuery = useQueryWithPages({
resourceName: 'optimistic_l2_interop_messages',
options: {
placeholderData: generateListStub<'optimistic_l2_interop_messages'>(INTEROP_MESSAGE, 50, { next_page_params: {
init_transaction_hash: '',
items_count: 50,
timestamp: 0,
} }),
},
});
const countQuery = useApiQuery('optimistic_l2_interop_messages_count', {
queryOptions: {
placeholderData: 1927029,
},
});
const text = (() => {
if (countQuery.isError) {
return null;
}
return (
<Skeleton loading={ countQuery.isPlaceholderData }>
A total of { countQuery.data?.toLocaleString() } messages found
</Skeleton>
);
})();
const actionBar = <StickyPaginationWithText text={ text } pagination={ interopMessagesQuery.pagination }/>;
const content = (
<>
<Box hideFrom="lg">
{ interopMessagesQuery.data?.items.map((item, index) => (
<InteropMessagesListItem
key={ item.init_transaction_hash + (interopMessagesQuery.isPlaceholderData ? index : '') }
item={ item }
isLoading={ interopMessagesQuery.isPlaceholderData }
/>
)) }
</Box>
<Box hideBelow="lg">
<InteropMessagesTable
items={ interopMessagesQuery.data?.items }
top={ interopMessagesQuery.pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }
isLoading={ interopMessagesQuery.isPlaceholderData }
/>
</Box>
</>
);
return (
<>
<PageTitle
title="Interop messages"
withTextAd
/>
<DataListDisplay
isError={ interopMessagesQuery.isError }
itemsNum={ interopMessagesQuery.data?.items.length }
emptyText="There are no interop messages."
actionBar={ actionBar }
>
{ content }
</DataListDisplay>
</>
);
};
export default InteropMessages;
...@@ -5,12 +5,12 @@ import config from 'configs/app'; ...@@ -5,12 +5,12 @@ import config from 'configs/app';
import { useRewardsContext } from 'lib/contexts/rewards'; import { useRewardsContext } from 'lib/contexts/rewards';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import { Alert } from 'toolkit/chakra/alert'; import { Alert } from 'toolkit/chakra/alert';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import DailyRewardClaimButton from 'ui/rewards/dashboard/DailyRewardClaimButton'; import DailyRewardClaimButton from 'ui/rewards/dashboard/DailyRewardClaimButton';
import RewardsDashboardCard from 'ui/rewards/dashboard/RewardsDashboardCard'; import RewardsDashboardCard from 'ui/rewards/dashboard/RewardsDashboardCard';
import RewardsDashboardCardValue from 'ui/rewards/dashboard/RewardsDashboardCardValue'; import RewardsDashboardCardValue from 'ui/rewards/dashboard/RewardsDashboardCardValue';
import RewardsDashboardInfoCard from 'ui/rewards/dashboard/RewardsDashboardInfoCard';
import RewardsReadOnlyInputWithCopy from 'ui/rewards/RewardsReadOnlyInputWithCopy'; import RewardsReadOnlyInputWithCopy from 'ui/rewards/RewardsReadOnlyInputWithCopy';
import AdBanner from 'ui/shared/ad/AdBanner'; import AdBanner from 'ui/shared/ad/AdBanner';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
...@@ -53,7 +53,7 @@ const RewardsDashboard = () => { ...@@ -53,7 +53,7 @@ const RewardsDashboard = () => {
<span> <span>
The Blockscout Merits Program is just getting started! Learn more about the details, The Blockscout Merits Program is just getting started! Learn more about the details,
features, and future plans in our{ ' ' } features, and future plans in our{ ' ' }
<Link external href="https://www.blog.blockscout.com/blockscout-merits-rewarding-block-explorer-skills"> <Link external href={ `https://merits.blockscout.com/?tab=users&utm_source=${ config.chain.id }&utm_medium=text-banner` }>
blog post blog post
</Link>. </Link>.
</span> </span>
...@@ -69,12 +69,6 @@ const RewardsDashboard = () => { ...@@ -69,12 +69,6 @@ const RewardsDashboard = () => {
description="Claim your daily Merits and any Merits received from referrals." description="Claim your daily Merits and any Merits received from referrals."
direction="column-reverse" direction="column-reverse"
contentAfter={ <DailyRewardClaimButton/> } contentAfter={ <DailyRewardClaimButton/> }
>
<RewardsDashboardCardValue
label="Total balance"
value={ balancesQuery.data?.total || 'N/A' }
isLoading={ balancesQuery.isPending }
withIcon
hint={ ( hint={ (
<> <>
Total number of Merits earned from all activities.{ ' ' } Total number of Merits earned from all activities.{ ' ' }
...@@ -83,6 +77,11 @@ const RewardsDashboard = () => { ...@@ -83,6 +77,11 @@ const RewardsDashboard = () => {
</Link> </Link>
</> </>
) } ) }
>
<RewardsDashboardCardValue
value={ balancesQuery.data?.total || 'N/A' }
isLoading={ balancesQuery.isPending }
withIcon
/> />
</RewardsDashboardCard> </RewardsDashboardCard>
<RewardsDashboardCard <RewardsDashboardCard
...@@ -91,7 +90,6 @@ const RewardsDashboard = () => { ...@@ -91,7 +90,6 @@ const RewardsDashboard = () => {
direction="column-reverse" direction="column-reverse"
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
label="Referrals"
value={ referralsQuery.data?.referrals ? value={ referralsQuery.data?.referrals ?
`${ referralsQuery.data?.referrals } user${ Number(referralsQuery.data?.referrals) === 1 ? '' : 's' }` : `${ referralsQuery.data?.referrals } user${ Number(referralsQuery.data?.referrals) === 1 ? '' : 's' }` :
'N/A' 'N/A'
...@@ -110,29 +108,26 @@ const RewardsDashboard = () => { ...@@ -110,29 +108,26 @@ const RewardsDashboard = () => {
</Link> </Link>
</> </>
) } ) }
hint={ (
<>
See the{ ' ' }
<Link external href="https://docs.blockscout.com/using-blockscout/merits/streak-rewards">docs</Link>{ ' ' }
to learn how your streak number affects daily rewards
</>
) }
direction="column-reverse" direction="column-reverse"
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
label="Streak"
value={ value={
dailyRewardQuery.data?.streak ? dailyRewardQuery.data?.streak ?
`${ dailyRewardQuery.data?.streak } day${ Number(dailyRewardQuery.data?.streak) === 1 ? '' : 's' }` : `${ dailyRewardQuery.data?.streak } day${ Number(dailyRewardQuery.data?.streak) === 1 ? '' : 's' }` :
'N/A' 'N/A'
} }
isLoading={ dailyRewardQuery.isPending } isLoading={ dailyRewardQuery.isPending }
hint={ (
<>
See the{ ' ' }
<Link external href="https://docs.blockscout.com/using-blockscout/merits/streak-rewards">
docs
</Link>{ ' ' }
to learn how your streak number affects daily rewards
</>
) }
/> />
</RewardsDashboardCard> </RewardsDashboardCard>
</Flex> </Flex>
<Flex gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}> <Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardCard <RewardsDashboardCard
title="Referral program" title="Referral program"
description={ ( description={ (
...@@ -169,46 +164,38 @@ const RewardsDashboard = () => { ...@@ -169,46 +164,38 @@ const RewardsDashboard = () => {
/> />
</Flex> </Flex>
</RewardsDashboardCard> </RewardsDashboardCard>
<RewardsDashboardCard <RewardsDashboardInfoCard
title="Badges" title="Badges"
description={ ( description={ `Collect limited and legendary badges by completing different Blockscout related tasks.
<Flex flexDir="column" gap={ 2 }> Go to the badges website to see what${ apos }s available and start your collection today.` }
<span> imageSrc="/static/merits/badges.svg"
Collect limited and legendary badges by completing different Blockscout related tasks. imageWidth="260px"
Go to the badges website to see what{ apos }s available and start your collection today. imageHeight="86px"
</span> linkText="View badges"
</Flex> linkHref={ `https://merits.blockscout.com/?tab=badges&utm_source=${ config.chain.id }&utm_medium=badges` }
) }
>
<Flex
flex={ 1 }
gap={ 4 }
pl={ 10 }
pr={ 7 }
py={{ base: 4, lg: 0 }}
flexDirection={{ base: 'column', lg: 'row' }}
justifyContent="space-between"
alignItems="center"
>
<Image
src="/static/badges.svg"
alt="Badges"
w="260px"
h="86px"
fallback={ <Skeleton loading w="260px" h="86px"/> }
/> />
<Link
external
href="https://merits.blockscout.com/?tab=badges&utm_source=blockscout&utm_medium=dashboard"
textStyle="md"
fontWeight="500"
>
View badges
</Link>
</Flex> </Flex>
</RewardsDashboardCard> <Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardInfoCard
title="Blockscout campaigns"
description="Join Blockscout activities to earn bonus Merits and exclusive rewards from our partners!"
imageSrc="/static/merits/campaigns.svg"
imageWidth="180px"
imageHeight="76px"
linkText="Check campaigns"
linkHref={ `https://merits.blockscout.com/?tab=campaigns&utm_source=${ config.chain.id }&utm_medium=campaigns` }
/>
<RewardsDashboardInfoCard
title="Use your Merits"
description="Spend your Merits to get exclusive discounts and offers across several web3 products!"
imageSrc="/static/merits/offers.svg"
imageWidth="180px"
imageHeight="86px"
linkText="Check offers"
linkHref={ `https://merits.blockscout.com/?tab=redeem&utm_source=${ config.chain.id }&utm_medium=redeem` }
/>
</Flex> </Flex>
<Flex gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}> <Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardCard <RewardsDashboardCard
title="Activity" title="Activity"
description="Earn Merits for your everyday Blockscout activities. You deserve to be rewarded for choosing open-source public goods!" description="Earn Merits for your everyday Blockscout activities. You deserve to be rewarded for choosing open-source public goods!"
......
...@@ -97,7 +97,16 @@ const TokenInstanceContent = () => { ...@@ -97,7 +97,16 @@ const TokenInstanceContent = () => {
{ {
id: 'token_transfers', id: 'token_transfers',
title: 'Token transfers', title: 'Token transfers',
component: <TokenTransfer transfersQuery={ transfersQuery } tokenId={ id } tokenQuery={ tokenQuery } shouldRender={ !isLoading } tabsHeight={ 80 }/>, component: (
<TokenTransfer
transfersQuery={ transfersQuery }
tokenId={ id }
tokenQuery={ tokenQuery }
tokenInstance={ tokenInstanceQuery.data }
shouldRender={ !isLoading }
tabsHeight={ 80 }
/>
),
}, },
shouldFetchHolders ? shouldFetchHolders ?
{ {
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import { mixTokens } from 'mocks/tokens/tokenTransfer'; import { mixTokens } from 'mocks/tokens/tokenTransfer';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import TokenTransfers from './TokenTransfers'; import TokenTransfers from './TokenTransfers';
test('base view +@mobile', async({ render, mockTextAd, mockApiResponse }) => { test('base view +@mobile', async({ render, mockTextAd, mockApiResponse, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
await mockTextAd(); await mockTextAd();
await mockApiResponse('token_transfers_all', mixTokens, { queryParams: { type: [] } }); await mockApiResponse('token_transfers_all', mixTokens, { queryParams: { type: [] } });
const component = await render(<Box pt={{ base: '106px', lg: 0 }}> <TokenTransfers/> </Box>); const component = await render(<Box pt={{ base: '106px', lg: 0 }}> <TokenTransfers/> </Box>);
......
...@@ -2,6 +2,7 @@ import { useRouter } from 'next/router'; ...@@ -2,6 +2,7 @@ import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types'; import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import type { EntityTag as TEntityTag } from 'ui/shared/EntityTags/types';
import config from 'configs/app'; import config from 'configs/app';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
...@@ -31,6 +32,7 @@ import TxUserOps from 'ui/tx/TxUserOps'; ...@@ -31,6 +32,7 @@ import TxUserOps from 'ui/tx/TxUserOps';
import useTxQuery from 'ui/tx/useTxQuery'; import useTxQuery from 'ui/tx/useTxQuery';
const txInterpretation = config.features.txInterpretation; const txInterpretation = config.features.txInterpretation;
const rollupFeature = config.features.rollup;
const TransactionPageContent = () => { const TransactionPageContent = () => {
const router = useRouter(); const router = useRouter();
...@@ -78,10 +80,21 @@ const TransactionPageContent = () => { ...@@ -78,10 +80,21 @@ const TransactionPageContent = () => {
const activeTab = useActiveTabFromQuery(tabs); const activeTab = useActiveTabFromQuery(tabs);
const txTags: Array<TEntityTag> = data?.transaction_tag ?
[ { slug: data.transaction_tag, name: data.transaction_tag, tagType: 'private_tag' as const, ordinal: 1 } ] : [];
if (rollupFeature.isEnabled && rollupFeature.interopEnabled && data?.op_interop) {
if (data.op_interop.init_chain !== undefined) {
txTags.push({ slug: 'relay_tx', name: 'Relay tx', tagType: 'custom' as const, ordinal: 0 });
}
if (data.op_interop.relay_chain !== undefined) {
txTags.push({ slug: 'init_tx', name: 'Source tx', tagType: 'custom' as const, ordinal: 0 });
}
}
const tags = ( const tags = (
<EntityTags <EntityTags
isLoading={ isPlaceholderData } isLoading={ isPlaceholderData }
tags={ data?.transaction_tag ? [ { slug: data.transaction_tag, name: data.transaction_tag, tagType: 'private_tag' as const, ordinal: 10 } ] : [] } tags={ txTags }
/> />
); );
......
...@@ -2,10 +2,12 @@ import { Flex, Text } from '@chakra-ui/react'; ...@@ -2,10 +2,12 @@ import { Flex, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Badge } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge';
import Hint from 'ui/shared/Hint';
type Props = { type Props = {
title?: string; title: string;
description: string | React.ReactNode; description: string | React.ReactNode;
hint?: string | React.ReactNode;
availableSoon?: boolean; availableSoon?: boolean;
blurFilter?: boolean; blurFilter?: boolean;
contentAfter?: React.ReactNode; contentAfter?: React.ReactNode;
...@@ -15,7 +17,7 @@ type Props = { ...@@ -15,7 +17,7 @@ type Props = {
}; };
const RewardsDashboardCard = ({ const RewardsDashboardCard = ({
title, description, availableSoon, contentAfter, title, description, hint, availableSoon, contentAfter,
direction = 'column', children, blurFilter, direction = 'column', children, blurFilter,
}: Props) => { }: Props) => {
return ( return (
...@@ -36,12 +38,11 @@ const RewardsDashboardCard = ({ ...@@ -36,12 +38,11 @@ const RewardsDashboardCard = ({
p={{ base: 1.5, md: 3 }} p={{ base: 1.5, md: 3 }}
w={{ base: 'full', md: direction === 'row' ? '340px' : 'full' }} w={{ base: 'full', md: direction === 'row' ? '340px' : 'full' }}
> >
{ title && (
<Flex alignItems="center" gap={ 2 }> <Flex alignItems="center" gap={ 2 }>
<Text fontSize={{ base: 'md', md: 'lg' }} fontWeight="500">{ title }</Text> <Text fontSize={{ base: 'md', md: 'lg' }} fontWeight="500">{ title }</Text>
{ hint && <Hint label={ hint }/> }
{ availableSoon && <Badge colorPalette="blue">Available soon</Badge> } { availableSoon && <Badge colorPalette="blue">Available soon</Badge> }
</Flex> </Flex>
) }
<Text as="div" fontSize="sm"> <Text as="div" fontSize="sm">
{ description } { description }
</Text> </Text>
......
...@@ -7,7 +7,7 @@ import Hint from 'ui/shared/Hint'; ...@@ -7,7 +7,7 @@ import Hint from 'ui/shared/Hint';
import MeritsIcon from '../MeritsIcon'; import MeritsIcon from '../MeritsIcon';
type Props = { type Props = {
label: string; label?: string;
value: number | string | undefined; value: number | string | undefined;
withIcon?: boolean; withIcon?: boolean;
hint?: string | React.ReactNode; hint?: string | React.ReactNode;
...@@ -16,6 +16,7 @@ type Props = { ...@@ -16,6 +16,7 @@ type Props = {
const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props) => ( const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props) => (
<Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }> <Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }>
{ label && (
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
{ hint && ( { hint && (
<Hint label={ hint }/> <Hint label={ hint }/>
...@@ -24,6 +25,7 @@ const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props ...@@ -24,6 +25,7 @@ const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props
{ label } { label }
</Text> </Text>
</Flex> </Flex>
) }
<Skeleton <Skeleton
loading={ isLoading } loading={ isLoading }
display="flex" display="flex"
......
import { Flex } from '@chakra-ui/react';
import React from 'react';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import RewardsDashboardCard from './RewardsDashboardCard';
type Props = {
title: string;
description: string | React.ReactNode;
imageSrc: string;
imageWidth: string;
imageHeight: string;
linkText: string;
linkHref: string;
};
const RewardsDashboardInfoCard = ({ title, description, imageSrc, imageWidth, imageHeight, linkText, linkHref }: Props) => (
<RewardsDashboardCard
title={ title }
description={ description }
>
<Flex
flex={ 1 }
gap={ 4 }
pl={ 10 }
pr={ 7 }
py={{ base: 4, lg: 0 }}
flexDirection={{ base: 'column', lg: 'row' }}
justifyContent="space-between"
alignItems="center"
>
<Image
src={ imageSrc }
alt={ title }
w={ imageWidth }
h={ imageHeight }
fallback={ <Skeleton loading w={ imageWidth } h={ imageHeight }/> }
/>
<Link
external
href={ linkHref }
fontSize="md"
fontWeight="500"
>
{ linkText }
</Link>
</Flex>
</RewardsDashboardCard>
);
export default RewardsDashboardInfoCard;
...@@ -26,6 +26,7 @@ const RewardsLoginModal = () => { ...@@ -26,6 +26,7 @@ const RewardsLoginModal = () => {
const [ isLoginStep, setIsLoginStep ] = React.useState(true); const [ isLoginStep, setIsLoginStep ] = React.useState(true);
const [ isReferral, setIsReferral ] = React.useState(false); const [ isReferral, setIsReferral ] = React.useState(false);
const [ customReferralReward, setCustomReferralReward ] = React.useState<string | null>(null);
const [ authModalInitialScreen, setAuthModalInitialScreen ] = React.useState<Screen>(); const [ authModalInitialScreen, setAuthModalInitialScreen ] = React.useState<Screen>();
const authModal = useDisclosure(); const authModal = useDisclosure();
...@@ -33,13 +34,13 @@ const RewardsLoginModal = () => { ...@@ -33,13 +34,13 @@ const RewardsLoginModal = () => {
if (!isLoginModalOpen) { if (!isLoginModalOpen) {
setIsLoginStep(true); setIsLoginStep(true);
setIsReferral(false); setIsReferral(false);
setCustomReferralReward(null);
} }
}, [ isLoginModalOpen, setIsLoginStep, setIsReferral ]); }, [ isLoginModalOpen ]);
const goNext = useCallback((isReferral: boolean) => { const goNext = useCallback((isReferral: boolean, reward: string | null) => {
if (isReferral) { setIsReferral(isReferral);
setIsReferral(true); setCustomReferralReward(reward);
}
setIsLoginStep(false); setIsLoginStep(false);
}, [ setIsLoginStep, setIsReferral ]); }, [ setIsLoginStep, setIsReferral ]);
...@@ -78,7 +79,7 @@ const RewardsLoginModal = () => { ...@@ -78,7 +79,7 @@ const RewardsLoginModal = () => {
<DialogBody> <DialogBody>
{ isLoginStep ? { isLoginStep ?
<LoginStepContent goNext={ goNext } openAuthModal={ handleAuthModalOpen } closeModal={ closeLoginModal }/> : <LoginStepContent goNext={ goNext } openAuthModal={ handleAuthModalOpen } closeModal={ closeLoginModal }/> :
<CongratsStepContent isReferral={ isReferral }/> <CongratsStepContent isReferral={ isReferral } customReferralReward={ customReferralReward }/>
} }
</DialogBody> </DialogBody>
</DialogContent> </DialogContent>
......
...@@ -13,14 +13,17 @@ import RewardsReadOnlyInputWithCopy from '../../RewardsReadOnlyInputWithCopy'; ...@@ -13,14 +13,17 @@ import RewardsReadOnlyInputWithCopy from '../../RewardsReadOnlyInputWithCopy';
type Props = { type Props = {
isReferral: boolean; isReferral: boolean;
customReferralReward: string | null;
}; };
const CongratsStepContent = ({ isReferral }: Props) => { const CongratsStepContent = ({ isReferral, customReferralReward }: Props) => {
const { referralsQuery, rewardsConfigQuery } = useRewardsContext(); const { referralsQuery, rewardsConfigQuery } = useRewardsContext();
const registrationReward = rewardsConfigQuery.data?.rewards.registration; const registrationReward = Number(rewardsConfigQuery.data?.rewards.registration);
const registrationWithReferralReward = rewardsConfigQuery.data?.rewards.registration_with_referral; const registrationWithReferralReward = customReferralReward ?
const referralReward = Number(registrationWithReferralReward) - Number(registrationReward); Number(customReferralReward) + registrationReward :
Number(rewardsConfigQuery.data?.rewards.registration_with_referral);
const referralReward = registrationWithReferralReward - registrationReward;
const refLink = referralsQuery.data?.link || 'N/A'; const refLink = referralsQuery.data?.link || 'N/A';
const shareText = `I joined the @blockscout Merits Program and got my first ${ registrationReward || 'N/A' } #Merits! Use this link for a sign-up bonus and start earning rewards with @blockscout block explorer.\n\n${ refLink }`; // eslint-disable-line max-len const shareText = `I joined the @blockscout Merits Program and got my first ${ registrationReward || 'N/A' } #Merits! Use this link for a sign-up bonus and start earning rewards with @blockscout block explorer.\n\n${ refLink }`; // eslint-disable-line max-len
...@@ -41,7 +44,7 @@ const CongratsStepContent = ({ isReferral }: Props) => { ...@@ -41,7 +44,7 @@ const CongratsStepContent = ({ isReferral }: Props) => {
<MeritsIcon boxSize={{ base: isReferral ? 8 : 12, md: 12 }} mr={{ base: isReferral ? 1 : 2, md: 2 }}/> <MeritsIcon boxSize={{ base: isReferral ? 8 : 12, md: 12 }} mr={{ base: isReferral ? 1 : 2, md: 2 }}/>
<Skeleton loading={ rewardsConfigQuery.isLoading }> <Skeleton loading={ rewardsConfigQuery.isLoading }>
<Text fontSize={{ base: isReferral ? '24px' : '30px', md: '30px' }} fontWeight="700" color={ textColor }> <Text fontSize={{ base: isReferral ? '24px' : '30px', md: '30px' }} fontWeight="700" color={ textColor }>
+{ rewardsConfigQuery.data?.rewards[ isReferral ? 'registration_with_referral' : 'registration' ] || 'N/A' } +{ (isReferral ? registrationWithReferralReward : registrationReward) || 'N/A' }
</Text> </Text>
</Skeleton> </Skeleton>
{ isReferral && ( { isReferral && (
......
...@@ -18,7 +18,7 @@ import { Switch } from 'toolkit/chakra/switch'; ...@@ -18,7 +18,7 @@ import { Switch } from 'toolkit/chakra/switch';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery'; import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
type Props = { type Props = {
goNext: (isReferral: boolean) => void; goNext: (isReferral: boolean, reward: string | null) => void;
closeModal: () => void; closeModal: () => void;
openAuthModal: (isAuth: boolean, trySharedLogin?: boolean) => void; openAuthModal: (isAuth: boolean, trySharedLogin?: boolean) => void;
}; };
...@@ -58,12 +58,12 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => { ...@@ -58,12 +58,12 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
try { try {
setRefCodeError(false); setRefCodeError(false);
setIsLoading(true); setIsLoading(true);
const { isNewUser, invalidRefCodeError } = await login(isSignUp && isRefCodeUsed ? refCode : ''); const { isNewUser, reward, invalidRefCodeError } = await login(isSignUp && isRefCodeUsed ? refCode : '');
if (invalidRefCodeError) { if (invalidRefCodeError) {
setRefCodeError(true); setRefCodeError(true);
} else { } else {
if (isNewUser) { if (isNewUser) {
goNext(isRefCodeUsed); goNext(isRefCodeUsed, reward);
} else { } else {
closeModal(); closeModal();
router.push({ pathname: '/account/merits' }, undefined, { shallow: true }); router.push({ pathname: '/account/merits' }, undefined, { shallow: true });
...@@ -71,14 +71,11 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => { ...@@ -71,14 +71,11 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
} }
} catch (error) {} } catch (error) {}
setIsLoading(false); setIsLoading(false);
}, [ login, goNext, setIsLoading, router, closeModal, refCode, setRefCodeError, isRefCodeUsed, isSignUp ]); }, [ login, goNext, router, closeModal, refCode, isRefCodeUsed, isSignUp ]);
React.useEffect(() => { React.useEffect(() => {
if (isSignUp && isRefCodeUsed && refCode.length > 0 && refCode.length !== 6) { const isInvalid = isSignUp && isRefCodeUsed && refCode.length > 0 && refCode.length !== 6 && refCode.length !== 12;
setRefCodeError(true); setRefCodeError(isInvalid);
} else {
setRefCodeError(false);
}
}, [ refCode, isRefCodeUsed, isSignUp ]); }, [ refCode, isRefCodeUsed, isSignUp ]);
const handleButtonClick = React.useCallback(() => { const handleButtonClick = React.useCallback(() => {
...@@ -118,7 +115,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => { ...@@ -118,7 +115,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
return ( return (
<> <>
<Image <Image
src="/static/merits_program.png" src="/static/merits/merits_program.png"
alt="Merits program" alt="Merits program"
mb={ 3 } mb={ 3 }
fallback={ <Skeleton loading w="full" h="120px" mb={ 3 }/> } fallback={ <Skeleton loading w="full" h="120px" mb={ 3 }/> }
...@@ -150,7 +147,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => { ...@@ -150,7 +147,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
mt={ 3 } mt={ 3 }
invalid={ refCodeError } invalid={ refCodeError }
helperText="The code should be in format XXXXXX" helperText="The code should be in format XXXXXX"
errorText={ refCodeError ? 'Incorrect code or format' : undefined } errorText={ refCodeError ? 'Incorrect code or format (6 or 12 characters)' : undefined }
> >
<Input <Input
value={ refCode } value={ refCode }
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import { test, expect, devices } from 'playwright/lib'; import { test, expect, devices } from 'playwright/lib';
...@@ -23,7 +24,8 @@ const data = [ ...@@ -23,7 +24,8 @@ const data = [
tokenTransferMock.erc1155D, tokenTransferMock.erc1155D,
]; ];
test('without tx info', async({ render }) => { test('without tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render( const component = await render(
<Box pt={{ base: '134px', lg: 6 }}> <Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferList <TokenTransferList
...@@ -36,7 +38,8 @@ test('without tx info', async({ render }) => { ...@@ -36,7 +38,8 @@ test('without tx info', async({ render }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with tx info', async({ render }) => { test('with tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render( const component = await render(
<Box pt={{ base: '134px', lg: 6 }}> <Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferList <TokenTransferList
......
...@@ -68,7 +68,7 @@ const TokenTransferListItem = ({ ...@@ -68,7 +68,7 @@ const TokenTransferListItem = ({
) } ) }
</Flex> </Flex>
{ total && 'token_id' in total && total.token_id !== null && token && ( { total && 'token_id' in total && total.token_id !== null && token && (
<NftEntity hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> <NftEntity hash={ token.address } id={ total.token_id } instance={ total.token_instance } isLoading={ isLoading }/>
) } ) }
{ showTxInfo && txHash && ( { showTxInfo && txHash && (
<Flex justifyContent="space-between" alignItems="center" lineHeight="24px" width="100%"> <Flex justifyContent="space-between" alignItems="center" lineHeight="24px" width="100%">
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import TokenTransferTable from './TokenTransferTable'; import TokenTransferTable from './TokenTransferTable';
test('without tx info', async({ render }) => { test('without tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render( const component = await render(
<Box pt={{ base: '134px', lg: 6 }}> <Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferTable <TokenTransferTable
...@@ -20,7 +22,8 @@ test('without tx info', async({ render }) => { ...@@ -20,7 +22,8 @@ test('without tx info', async({ render }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('with tx info', async({ render }) => { test('with tx info', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render( const component = await render(
<Box pt={{ base: '134px', lg: 6 }}> <Box pt={{ base: '134px', lg: 6 }}>
<TokenTransferTable <TokenTransferTable
......
...@@ -76,6 +76,7 @@ const TokenTransferTableItem = ({ ...@@ -76,6 +76,7 @@ const TokenTransferTableItem = ({
<NftEntity <NftEntity
hash={ token.address } hash={ token.address }
id={ total.token_id } id={ total.token_id }
instance={ total.token_instance }
isLoading={ isLoading } isLoading={ isLoading }
/> />
) } ) }
......
...@@ -44,6 +44,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props) ...@@ -44,6 +44,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props)
<TokenTransferSnippetNft <TokenTransferSnippetNft
token={ data.token } token={ data.token }
tokenId={ total.token_id } tokenId={ total.token_id }
instance={ total.token_instance }
value="1" value="1"
/> />
); );
...@@ -56,6 +57,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props) ...@@ -56,6 +57,7 @@ const TokenTransferSnippet = ({ data, isLoading, noAddressIcons = true }: Props)
key={ total.token_id } key={ total.token_id }
token={ data.token } token={ data.token }
tokenId={ total.token_id } tokenId={ total.token_id }
instance={ total.token_instance }
value={ total.value } value={ total.value }
/> />
); );
......
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenInfo } from 'types/api/token'; import type { TokenInfo, TokenInstance } from 'types/api/token';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
...@@ -10,9 +10,10 @@ interface Props { ...@@ -10,9 +10,10 @@ interface Props {
token: TokenInfo; token: TokenInfo;
value: string; value: string;
tokenId: string | null; tokenId: string | null;
instance?: TokenInstance | null;
} }
const NftTokenTransferSnippet = ({ value, token, tokenId }: Props) => { const NftTokenTransferSnippet = ({ value, token, tokenId, instance }: Props) => {
const num = value === '1' ? '' : value; const num = value === '1' ? '' : value;
const tokenIdContent = (() => { const tokenIdContent = (() => {
...@@ -28,6 +29,7 @@ const NftTokenTransferSnippet = ({ value, token, tokenId }: Props) => { ...@@ -28,6 +29,7 @@ const NftTokenTransferSnippet = ({ value, token, tokenId }: Props) => {
<NftEntity <NftEntity
hash={ token.address } hash={ token.address }
id={ tokenId } id={ tokenId }
instance={ instance }
fontWeight={ 600 } fontWeight={ 600 }
variant="content" variant="content"
maxW={{ base: '100%', lg: '150px' }} maxW={{ base: '100%', lg: '150px' }}
......
import React from 'react';
import * as addressMock from 'mocks/address/address';
import * as interopMock from 'mocks/interop/interop';
import { test, expect } from 'playwright/lib';
import AddressEntityInterop from './AddressEntityInterop';
test.use({ viewport: { width: 180, height: 140 } });
test('with chain icon', async({ render, mockAssetResponse }) => {
await mockAssetResponse('https://example.com/logo.png', './playwright/mocks/image_svg.svg');
const component = await render(
<AddressEntityInterop
address={ addressMock.withoutName }
chain={ interopMock.chain }
/>,
);
await expect(component).toHaveScreenshot();
});
test('with chain icon stub +@dark-mode', async({ render }) => {
const component = await render(
<AddressEntityInterop
address={ addressMock.withoutName }
chain={{ ...interopMock.chain, chain_logo: null }}
/>,
);
await expect(component).toHaveScreenshot();
});
import { Box, chakra, Flex } from '@chakra-ui/react';
import React from 'react';
import type { ChainInfo } from 'types/api/interop';
import { route } from 'nextjs-routes';
import { Image } from 'toolkit/chakra/image';
import { Tooltip } from 'toolkit/chakra/tooltip';
import IconSvg from 'ui/shared/IconSvg';
import { distributeEntityProps } from '../base/utils';
import * as AddressEntity from './AddressEntity';
interface Props extends AddressEntity.EntityProps {
chain: ChainInfo | null;
}
const IconStub = () => {
return (
<Flex
position="absolute"
bottom="-2px"
right="4px"
alignItems="center"
justifyContent="center"
borderRadius="base"
background={{ _light: 'gray.100', _dark: 'gray.700' }}
width="14px"
height="14px"
border="1px solid"
borderColor="global.body.bg"
>
<IconSvg
name="networks/icon-placeholder"
width="10px"
height="10px"
color="text.secondary"
/>
</Flex>
);
};
const AddressEntryInterop = (props: Props) => {
const partsProps = distributeEntityProps(props);
const href = props.chain?.instance_url ? props.chain.instance_url.replace(/\/$/, '') + route({
pathname: '/address/[hash]',
query: {
...props.query,
hash: props.address.hash,
},
}) : null;
const addressIcon = (
<Box position="relative">
<AddressEntity.Icon { ...partsProps.icon }/>
{ !props.isLoading && (
props.chain?.chain_logo ? (
<Image
position="absolute"
bottom="-3px"
right="4px"
src={ props.chain.chain_logo }
alt={ props.chain.chain_name || 'external chain logo' }
width="14px"
height="14px"
borderRadius="base"
/>
) : (
<IconStub/>
)
) }
</Box>
);
return (
<AddressEntity.Container>
{ props.chain && (
<Tooltip content={ `Address on ${ props.chain.chain_name ? props.chain.chain_name : 'external chain' } (chain id ${ props.chain.chain_id })` }>
{ addressIcon }
</Tooltip>
) }
{ !props.chain && addressIcon }
{ href ? (
<AddressEntity.Link { ...partsProps.link } href={ href } isExternal>
<AddressEntity.Content { ...partsProps.content }/>
</AddressEntity.Link>
) : (
<AddressEntity.Content { ...partsProps.content }/>
) }
<AddressEntity.Copy { ...partsProps.copy }/>
</AddressEntity.Container>
);
};
export default chakra(AddressEntryInterop);
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import * as EntityBase from 'ui/shared/entities/base/components'; import * as EntityBase from 'ui/shared/entities/base/components';
import NftMedia from 'ui/shared/nft/NftMedia';
import { distributeEntityProps } from '../base/utils'; import { distributeEntityProps, getIconProps } from '../base/utils';
const Container = EntityBase.Container; const Container = EntityBase.Container;
const Icon = (props: EntityBase.IconBaseProps) => { type IconProps = EntityBase.IconBaseProps & {
instance?: TokenInstance | null;
};
const ICON_MEDIA_TYPES = [ 'image' as const ];
const Icon = (props: IconProps) => {
if (props.noIcon) { if (props.noIcon) {
return null; return null;
} }
if (props.instance) {
const styles = getIconProps(props.variant ?? 'heading');
const fallback = (
<EntityBase.Icon
{ ...props }
variant={ props.variant ?? 'heading' }
name={ props.name ?? 'nft_shield' }
marginRight={ 0 }
/>
);
return (
<NftMedia
data={ props.instance }
isLoading={ props.isLoading }
boxSize={ styles.boxSize }
size="sm"
allowedTypes={ ICON_MEDIA_TYPES }
borderRadius="sm"
flexShrink={ 0 }
mr={ 2 }
fallback={ fallback }
/>
);
}
return ( return (
<EntityBase.Icon <EntityBase.Icon
{ ...props } { ...props }
...@@ -53,6 +88,7 @@ const Content = chakra((props: ContentProps) => { ...@@ -53,6 +88,7 @@ const Content = chakra((props: ContentProps) => {
export interface EntityProps extends EntityBase.EntityBaseProps { export interface EntityProps extends EntityBase.EntityBaseProps {
hash: string; hash: string;
id: string; id: string;
instance?: TokenInstance | null;
} }
const NftEntity = (props: EntityProps) => { const NftEntity = (props: EntityProps) => {
......
import React from 'react';
import * as interopMock from 'mocks/interop/interop';
import { test, expect } from 'playwright/lib';
import TxEntityInterop from './TxEntityInterop';
const hash = '0x376db52955d5bce114d0ccea2dcf22289b4eae1b86bcae5a59bb5fdbfef48899';
test.use({ viewport: { width: 180, height: 30 } });
test('with chain icon', async({ render, mockAssetResponse }) => {
await mockAssetResponse('https://example.com/logo.png', './playwright/mocks/image_svg.svg');
const component = await render(
<TxEntityInterop
hash={ hash }
chain={ interopMock.chain }
/>,
);
await expect(component).toHaveScreenshot();
});
test('with chain icon stub +@dark-mode', async({ render }) => {
const component = await render(
<TxEntityInterop
hash={ hash }
chain={{ ...interopMock.chain, chain_logo: null }}
/>,
);
await expect(component).toHaveScreenshot();
});
import { Box, chakra } from '@chakra-ui/react';
import React from 'react';
import type { ChainInfo } from 'types/api/interop';
import { route } from 'nextjs-routes';
import stripTrailingSlash from 'lib/stripTrailingSlash';
import { Image } from 'toolkit/chakra/image';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tooltip } from 'toolkit/chakra/tooltip';
import IconSvg from 'ui/shared/IconSvg';
import { distributeEntityProps } from '../base/utils';
import * as TxEntity from './TxEntity';
type Props = {
chain: ChainInfo | null;
hash?: string | null;
} & Omit<TxEntity.EntityProps, 'hash'>;
const IconStub = ({ isLoading }: { isLoading?: boolean }) => {
return (
<Skeleton
loading={ !isLoading }
display="flex"
minWidth="20px"
h="20px"
borderRadius="full"
background={{ _light: 'blackAlpha.100', _dark: 'whiteAlpha.100' }}
alignItems="center"
justifyContent="center"
mr={ 2 }
>
<IconSvg
name="networks/icon-placeholder"
width="16px"
height="16px"
color="text.secondary"
display="block"
/>
</Skeleton>
);
};
const TxEntityInterop = ({ chain, hash, ...props }: Props) => {
const partsProps = distributeEntityProps(props);
const href = (chain?.instance_url && hash) ? stripTrailingSlash(chain.instance_url) + route({
pathname: '/tx/[hash]',
query: {
...props.query,
hash: hash,
},
}) : null;
return (
<TxEntity.Container { ...partsProps.container }>
{ chain && (
<Tooltip content={ `${ chain.chain_name ? chain.chain_name : 'External chain' } (chain id ${ chain.chain_id })` }>
<Box>
{ chain.chain_logo ? (
<Image
src={ chain.chain_logo }
alt={ chain.chain_name || 'external chain logo' }
width="20px"
height="20px"
mr={ 2 }
borderRadius="base"
/>
) : (
<IconStub isLoading={ props.isLoading }/>
) }
</Box>
</Tooltip>
) }
{ !chain && (
<IconStub/>
) }
{ hash && (
<>
{ href ? (
<TxEntity.Link { ...partsProps.link } hash={ hash } href={ href } isExternal>
<TxEntity.Content { ...partsProps.content } hash={ hash }/>
</TxEntity.Link>
) : (
<TxEntity.Content { ...partsProps.content } hash={ hash }/>
) }
<TxEntity.Copy { ...partsProps.copy } hash={ hash }/>
</>
) }
{ !hash && (
'N/A'
) }
</TxEntity.Container>
);
};
export default chakra(TxEntityInterop);
...@@ -3,29 +3,55 @@ import React from 'react'; ...@@ -3,29 +3,55 @@ import React from 'react';
import { LinkOverlay } from 'toolkit/chakra/link'; import { LinkOverlay } from 'toolkit/chakra/link';
import { mediaStyleProps } from './utils'; import type { MediaElementProps } from './utils';
interface Props { interface Props extends MediaElementProps<'a'> {}
src: string;
onLoad: () => void; const NftHtml = ({ src, transport, onLoad, onError, onClick, ...rest }: Props) => {
onError: () => void; const ref = React.useRef<HTMLIFrameElement>(null);
onClick?: () => void;
} const [ isLoaded, setIsLoaded ] = React.useState(false);
const handleLoad = React.useCallback(() => {
setIsLoaded(true);
onLoad?.();
}, [ onLoad ]);
const loadViaHttp = React.useCallback(async() => {
if (!ref.current) {
return;
}
ref.current.src = src;
ref.current.onload = handleLoad;
onError && (ref.current.onerror = onError);
}, [ src, handleLoad, onError ]);
React.useEffect(() => {
switch (transport) {
case 'ipfs': {
// Currently we don't support IPFS video loading
onError?.();
break;
}
case 'http':
loadViaHttp();
break;
}
}, [ loadViaHttp, onError, transport ]);
const NftHtml = ({ src, onLoad, onError, onClick }: Props) => {
return ( return (
<LinkOverlay <LinkOverlay
onClick={ onClick } onClick={ onClick }
h="100%" h="100%"
{ ...mediaStyleProps } { ...rest }
> >
<chakra.iframe <chakra.iframe
src={ src } ref={ ref }
h="100%" h="100%"
w="100%" w="100%"
sandbox="allow-scripts" sandbox="allow-scripts"
onLoad={ onLoad } opacity={ isLoaded ? 1 : 0 }
onError={ onError }
/> />
</LinkOverlay> </LinkOverlay>
); );
......
import { chakra } from '@chakra-ui/react';
import React from 'react';
import NftMediaFullscreenModal from './NftMediaFullscreenModal';
interface Props {
src: string;
open: boolean;
onOpenChange: ({ open }: { open: boolean }) => void;
}
const NftHtmlFullscreen = ({ src, open, onOpenChange }: Props) => {
return (
<NftMediaFullscreenModal open={ open } onOpenChange={ onOpenChange }>
<chakra.iframe
w="90vw"
h="90vh"
src={ src }
sandbox="allow-scripts"
/>
</NftMediaFullscreenModal>
);
};
export default NftHtmlFullscreen;
...@@ -2,30 +2,66 @@ import React from 'react'; ...@@ -2,30 +2,66 @@ import React from 'react';
import { Image } from 'toolkit/chakra/image'; import { Image } from 'toolkit/chakra/image';
import { mediaStyleProps } from './utils'; import useLoadImageViaIpfs from './useLoadImageViaIpfs';
import type { MediaElementProps } from './utils';
interface Props { interface Props extends MediaElementProps<'img'> {}
src: string;
srcSet?: string; const NftImage = ({ src, srcSet, onLoad, onError, transport, onClick, ...rest }: Props) => {
onLoad: () => void; const ref = React.useRef<HTMLImageElement>(null);
onError: () => void; const [ isLoaded, setIsLoaded ] = React.useState(false);
onClick?: () => void;
} const handleLoad = React.useCallback(() => {
setIsLoaded(true);
onLoad?.();
}, [ onLoad ]);
const loadImageViaIpfs = useLoadImageViaIpfs();
const loadViaHttp = React.useCallback(async() => {
if (!ref.current) {
return;
}
ref.current.src = src;
srcSet && (ref.current.srcset = srcSet);
ref.current.onload = handleLoad;
onError && (ref.current.onerror = onError);
}, [ src, srcSet, handleLoad, onError ]);
const loadViaIpfs = React.useCallback(() => {
loadImageViaIpfs(src)
.then((src) => {
if (src && ref.current) {
ref.current.src = src;
handleLoad();
}
})
.catch(onError);
}, [ handleLoad, loadImageViaIpfs, onError, src ]);
React.useEffect(() => {
switch (transport) {
case 'ipfs':
loadViaIpfs();
break;
case 'http':
loadViaHttp();
break;
}
}, [ loadViaHttp, loadViaIpfs, transport ]);
const NftImage = ({ src, srcSet, onLoad, onError, onClick }: Props) => {
return ( return (
<Image <Image
ref={ ref }
w="100%" w="100%"
h="100%" h="100%"
src={ src } opacity={ isLoaded ? 1 : 0 }
srcSet={ srcSet }
alt="Token instance image" alt="Token instance image"
onError={ onError }
onLoad={ onLoad }
onClick={ onClick } onClick={ onClick }
{ ...mediaStyleProps } { ...rest }
/> />
); );
}; };
export default NftImage; export default React.memo(NftImage);
import React from 'react';
import { Image } from 'toolkit/chakra/image';
import NftMediaFullscreenModal from './NftMediaFullscreenModal';
interface Props {
src: string;
open: boolean;
onOpenChange: ({ open }: { open: boolean }) => void;
}
const NftImageFullscreen = ({ src, open, onOpenChange }: Props) => {
const imgRef = React.useRef<HTMLImageElement>(null);
const [ hasDimensions, setHasDimensions ] = React.useState<boolean>(true);
const checkWidth = React.useCallback(() => {
if (imgRef.current?.getBoundingClientRect().width === 0) {
setHasDimensions(false);
}
}, [ ]);
return (
<NftMediaFullscreenModal open={ open } onOpenChange={ onOpenChange }>
<Image
src={ src }
alt="Token instance image"
maxH="90vh"
maxW="90vw"
ref={ imgRef }
onLoad={ checkWidth }
{ ...(hasDimensions ? {} : { width: '90vw', height: '90vh' }) }
/>
</NftMediaFullscreenModal>
);
};
export default NftImageFullscreen;
...@@ -66,7 +66,7 @@ test.describe('image', () => { ...@@ -66,7 +66,7 @@ test.describe('image', () => {
} as TokenInstance; } as TokenInstance;
await render( await render(
<Box boxSize="250px"> <Box boxSize="250px">
<NftMedia data={ data }/> <NftMedia data={ data } size="md"/>
</Box>, </Box>,
); );
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
...@@ -84,7 +84,7 @@ test.describe('image', () => { ...@@ -84,7 +84,7 @@ test.describe('image', () => {
await mockAssetResponse(THUMBNAIL_URL, './playwright/mocks/image_md.jpg'); await mockAssetResponse(THUMBNAIL_URL, './playwright/mocks/image_md.jpg');
await render( await render(
<Box boxSize="250px"> <Box boxSize="250px">
<NftMedia data={ data }/> <NftMedia data={ data } size="md"/>
</Box>, </Box>,
); );
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
...@@ -95,7 +95,7 @@ test.describe('image', () => { ...@@ -95,7 +95,7 @@ test.describe('image', () => {
animation_url: MEDIA_URL, animation_url: MEDIA_URL,
image_url: null, image_url: null,
} as TokenInstance; } as TokenInstance;
const component = await render(<NftMedia data={ data } w="250px"/>); const component = await render(<NftMedia data={ data } w="250px" size="md"/>);
await component.getByRole('img', { name: 'Token instance image' }).hover(); await component.getByRole('img', { name: 'Token instance image' }).hover();
await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } }); await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 250, height: 250 } });
}); });
......
import { AspectRatio, Box, chakra } from '@chakra-ui/react'; import type { HTMLChakraProps } from '@chakra-ui/react';
import { AspectRatio, Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useInView } from 'react-intersection-observer'; import { useInView } from 'react-intersection-observer';
...@@ -9,45 +10,63 @@ import { useDisclosure } from 'toolkit/hooks/useDisclosure'; ...@@ -9,45 +10,63 @@ import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import NftFallback from './NftFallback'; import NftFallback from './NftFallback';
import NftHtml from './NftHtml'; import NftHtml from './NftHtml';
import NftHtmlFullscreen from './NftHtmlFullscreen';
import NftImage from './NftImage'; import NftImage from './NftImage';
import NftImageFullscreen from './NftImageFullscreen'; import NftMediaFullscreenModal from './NftMediaFullscreenModal';
import NftVideo from './NftVideo'; import NftVideo from './NftVideo';
import NftVideoFullscreen from './NftVideoFullscreen';
import useNftMediaInfo from './useNftMediaInfo'; import useNftMediaInfo from './useNftMediaInfo';
import type { MediaType, Size } from './utils';
import { mediaStyleProps } from './utils'; import { mediaStyleProps } from './utils';
interface Props { interface Props extends Omit<HTMLChakraProps<'div'>, 'size'> {
data: TokenInstance; data: TokenInstance;
className?: string; size?: Size;
allowedTypes?: Array<MediaType>;
isLoading?: boolean; isLoading?: boolean;
withFullscreen?: boolean; withFullscreen?: boolean;
autoplayVideo?: boolean; autoplayVideo?: boolean;
fallback?: React.ReactNode;
} }
const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }: Props) => { const NftMedia = ({ data, size = 'original', allowedTypes, isLoading, withFullscreen, autoplayVideo, fallback, ...rest }: Props) => {
const [ isMediaLoading, setIsMediaLoading ] = React.useState(true); const [ isMediaLoading, setIsMediaLoading ] = React.useState(true);
const [ isLoadingError, setIsLoadingError ] = React.useState(false); const [ isMediaLoadingError, setIsMediaLoadingError ] = React.useState(false);
const [ mediaInfoIndex, setMediaInfoIndex ] = React.useState(0);
const [ mediaInfoField, setMediaInfoField ] = React.useState<'animation_url' | 'image_url'>('animation_url');
const { ref, inView } = useInView({ triggerOnce: true }); const { ref, inView } = useInView({ triggerOnce: true });
const mediaInfo = useNftMediaInfo({ data, isEnabled: !isLoading && inView }); const mediaInfoQuery = useNftMediaInfo({ data, size, allowedTypes, field: mediaInfoField, isEnabled: !isLoading && inView });
React.useEffect(() => { React.useEffect(() => {
if (!isLoading && !mediaInfo) { if (!mediaInfoQuery.isPending && !mediaInfoQuery.data) {
if (mediaInfoField === 'animation_url') {
setMediaInfoField('image_url');
} else {
setIsMediaLoadingError(true);
setIsMediaLoading(false); setIsMediaLoading(false);
setIsLoadingError(true);
} }
}, [ isLoading, mediaInfo ]); }
}, [ mediaInfoQuery.isPending, mediaInfoQuery.data, mediaInfoField ]);
const handleMediaLoaded = React.useCallback(() => { const handleMediaLoaded = React.useCallback(() => {
setIsMediaLoading(false); setIsMediaLoading(false);
}, []); }, []);
const handleMediaLoadError = React.useCallback(() => { const handleMediaLoadError = React.useCallback(() => {
if (mediaInfoQuery.data) {
if (mediaInfoIndex < mediaInfoQuery.data.length - 1) {
setMediaInfoIndex(mediaInfoIndex + 1);
return;
} else if (mediaInfoField === 'animation_url') {
setMediaInfoField('image_url');
setMediaInfoIndex(0);
return;
}
}
setIsMediaLoading(false); setIsMediaLoading(false);
setIsLoadingError(true); setIsMediaLoadingError(true);
}, []); }, [ mediaInfoField, mediaInfoIndex, mediaInfoQuery.data ]);
const { open, onOpen, onOpenChange } = useDisclosure(); const { open, onOpen, onOpenChange } = useDisclosure();
...@@ -56,57 +75,27 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }: ...@@ -56,57 +75,27 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }:
return null; return null;
} }
if (!mediaInfo || isLoadingError) { if (isMediaLoadingError) {
const styleProps = withFullscreen ? {} : mediaStyleProps; const styleProps = withFullscreen ? {} : mediaStyleProps;
return <NftFallback { ...styleProps }/>; return fallback ?? <NftFallback { ...styleProps }/>;
} }
const mediaInfo = mediaInfoQuery.data?.[mediaInfoIndex];
const props = { const props = {
onLoad: handleMediaLoaded, onLoad: handleMediaLoaded,
onError: handleMediaLoadError, onError: handleMediaLoadError,
...(withFullscreen ? { onClick: onOpen } : {}), ...(withFullscreen ? { onClick: onOpen } : {}),
...(size !== 'sm' ? mediaStyleProps : {}),
}; };
switch (mediaInfo.mediaType) { switch (mediaInfo?.mediaType) {
case 'video': { case 'video': {
return <NftVideo { ...props } src={ mediaInfo.src } autoPlay={ autoplayVideo } instance={ data }/>; return <NftVideo { ...props } src={ mediaInfo.src } transport={ mediaInfo.transport } autoPlay={ autoplayVideo } instance={ data }/>;
}
case 'html':
return <NftHtml { ...props } src={ mediaInfo.src }/>;
case 'image': {
if (mediaInfo.srcType === 'url' && data.thumbnails) {
const srcSet = data.thumbnails['250x250'] && data.thumbnails['500x500'] ? `${ data.thumbnails['500x500'] } 2x` : undefined;
const src = (srcSet ? data.thumbnails['250x250'] : undefined) || data.thumbnails['500x500'] || data.thumbnails.original;
if (src) {
return <NftImage { ...props } src={ src } srcSet={ srcSet }/>;
}
}
return <NftImage { ...props } src={ mediaInfo.src }/>;
}
default:
return null;
}
})();
const modal = (() => {
if (!mediaInfo || !withFullscreen || isLoading) {
return null;
} }
const props = {
open,
onOpenChange,
};
switch (mediaInfo.mediaType) {
case 'video':
return <NftVideoFullscreen { ...props } src={ mediaInfo.src }/>;
case 'html': case 'html':
return <NftHtmlFullscreen { ...props } src={ mediaInfo.src }/>; return <NftHtml { ...props } src={ mediaInfo.src } transport={ mediaInfo.transport }/>;
case 'image': { case 'image': {
const src = mediaInfo.srcType === 'url' && data.thumbnails?.original ? data.thumbnails.original : mediaInfo.src; return <NftImage { ...props } src={ mediaInfo.src } srcSet={ mediaInfo.srcSet } transport={ mediaInfo.transport }/>;
return <NftImageFullscreen { ...props } src={ src }/>;
} }
default: default:
return null; return null;
...@@ -114,13 +103,14 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }: ...@@ -114,13 +103,14 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }:
})(); })();
return ( return (
<>
<AspectRatio <AspectRatio
ref={ ref } ref={ ref }
className={ className }
ratio={ 1 / 1 } ratio={ 1 / 1 }
overflow="hidden" overflow="hidden"
borderRadius="md" borderRadius="md"
isolation="isolate" isolation="isolate"
{ ...rest }
> >
<> <>
<Box <Box
...@@ -132,11 +122,14 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }: ...@@ -132,11 +122,14 @@ const NftMedia = ({ data, className, isLoading, withFullscreen, autoplayVideo }:
> >
{ content } { content }
</Box> </Box>
{ modal }
{ isMediaLoading && <Skeleton loading position="absolute" left={ 0 } top={ 0 } w="100%" h="100%" zIndex="1"/> } { isMediaLoading && <Skeleton loading position="absolute" left={ 0 } top={ 0 } w="100%" h="100%" zIndex="1"/> }
</> </>
</AspectRatio> </AspectRatio>
{ open && (
<NftMediaFullscreenModal open={ open } onOpenChange={ onOpenChange } data={ data } allowedTypes={ allowedTypes } field={ mediaInfoField }/>
) }
</>
); );
}; };
export default chakra(NftMedia); export default React.memo(NftMedia);
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token';
import { DialogContent, DialogRoot, DialogHeader } from 'toolkit/chakra/dialog'; import { DialogContent, DialogRoot, DialogHeader } from 'toolkit/chakra/dialog';
import NftHtml from './NftHtml';
import NftImage from './NftImage';
import NftVideo from './NftVideo';
import useNftMediaInfo from './useNftMediaInfo';
import type { MediaType } from './utils';
interface Props { interface Props {
open: boolean; open: boolean;
onOpenChange: ({ open }: { open: boolean }) => void; onOpenChange: ({ open }: { open: boolean }) => void;
children: React.ReactNode; data: TokenInstance;
allowedTypes?: Array<MediaType>;
field: 'animation_url' | 'image_url';
} }
const NftMediaFullscreenModal = ({ open, onOpenChange, children }: Props) => { const NftMediaFullscreenModal = ({ open, onOpenChange, data, allowedTypes, field }: Props) => {
const [ mediaInfoIndex, setMediaInfoIndex ] = React.useState(0);
const mediaInfoQuery = useNftMediaInfo({ data, size: 'original', allowedTypes, field, isEnabled: true });
const handleMediaLoadError = React.useCallback(() => {
if (mediaInfoQuery.data) {
if (mediaInfoIndex < mediaInfoQuery.data.length - 1) {
setMediaInfoIndex(mediaInfoIndex + 1);
return;
}
}
// FIXME: maybe we should display something if the media is not loaded
}, [ mediaInfoIndex, mediaInfoQuery.data ]);
const content = (() => {
const mediaInfo = mediaInfoQuery.data?.[mediaInfoIndex];
switch (mediaInfo?.mediaType) {
case 'video':
return (
<NftVideo
src={ mediaInfo.src }
transport={ mediaInfo.transport }
onError={ handleMediaLoadError }
maxW="90vw"
maxH="90vh"
objectFit="contain"
autoPlay
instance={ data }
/>
);
case 'html':
return (
<NftHtml
src={ mediaInfo.src }
transport={ mediaInfo.transport }
onError={ handleMediaLoadError }
w="90vw"
h="90vh"
/>
);
case 'image':
return (
<NftImage
src={ mediaInfo.src }
srcSet={ mediaInfo.srcSet }
transport={ mediaInfo.transport }
onError={ handleMediaLoadError }
maxW="90vw"
maxH="90vh"
objectFit="contain"/>
);
default:
return null;
}
})();
return ( return (
<DialogRoot open={ open } onOpenChange={ onOpenChange } motionPreset="none"> <DialogRoot open={ open } onOpenChange={ onOpenChange } motionPreset="none">
<DialogContent w="unset" maxW="100vw" p={ 0 } background="none" boxShadow="none"> <DialogContent w="unset" maxW="100vw" p={ 0 } background="none" boxShadow="none">
<DialogHeader/> <DialogHeader/>
{ children } { content }
</DialogContent> </DialogContent>
</DialogRoot> </DialogRoot>
); );
......
import { chakra } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import { verifiedFetch } from '@helia/verified-fetch';
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token'; import type { TokenInstance } from 'types/api/token';
import config from 'configs/app'; import useLoadImageViaIpfs from './useLoadImageViaIpfs';
import useNftMediaInfo from './useNftMediaInfo';
import type { MediaElementProps, Size } from './utils';
import { videoPlayProps } from './utils';
import { mediaStyleProps, videoPlayProps } from './utils'; interface Props extends MediaElementProps<'video'> {
interface Props {
src: string;
instance: TokenInstance; instance: TokenInstance;
autoPlay?: boolean; autoPlay?: boolean;
onLoad: () => void; size?: Size;
onError: () => void;
onClick?: () => void;
} }
const NftVideo = ({ src, instance, autoPlay = true, onLoad, onError, onClick }: Props) => { const POSTER_ALLOWED_TYPES = [ 'image' as const ];
const NftVideo = ({ src, transport, instance, autoPlay = true, onLoad, size = 'original', onError, onClick, ...rest }: Props) => {
const ref = React.useRef<HTMLVideoElement>(null); const ref = React.useRef<HTMLVideoElement>(null);
const controller = React.useRef<AbortController | null>(null);
const fetchVideoPoster = React.useCallback(async() => { const mediaInfoQuery = useNftMediaInfo({ data: instance, size, field: 'image_url', isEnabled: true, allowedTypes: POSTER_ALLOWED_TYPES });
const loadImageViaIpfs = useLoadImageViaIpfs();
const handleMouseEnter = React.useCallback(() => {
!autoPlay && ref.current?.play();
}, [ autoPlay ]);
const handleMouseLeave = React.useCallback(() => {
!autoPlay && ref.current?.pause();
}, [ autoPlay ]);
const loadViaHttp = React.useCallback(async() => {
if (!ref.current) { if (!ref.current) {
return; return;
} }
try { ref.current.src = src;
if (!config.UI.views.nft.verifiedFetch.isEnabled) { onLoad && (ref.current.oncanplaythrough = onLoad);
throw new Error('Helia verified fetch is disabled'); onError && (ref.current.onerror = onError);
}, [ src, onLoad, onError ]);
React.useEffect(() => {
switch (transport) {
case 'ipfs': {
// Currently we don't support IPFS video loading
onError?.();
break;
} }
const imageUrl = typeof instance.metadata?.image === 'string' ? instance.metadata.image : undefined; case 'http':
if (!imageUrl) { loadViaHttp();
throw new Error('No image URL found'); break;
} }
controller.current = new AbortController(); }, [ loadViaHttp, onError, transport ]);
const response = await verifiedFetch(imageUrl, { signal: controller.current.signal });
const blob = await response.blob();
const src = URL.createObjectURL(blob);
ref.current.poster = src;
// we want to call onLoad right after the poster is loaded const loadPosterViaHttp = React.useCallback(async(src: string) => {
// otherwise, the skeleton will be shown underneath the element until the video is loaded if (!ref.current || !ref.current.poster) {
onLoad(); return;
} catch (error) { }
const src = instance.thumbnails?.['500x500'] || instance.thumbnails?.original || instance.image_url;
if (src) {
ref.current.poster = src;
const poster = new Image();
poster.src = src;
// we want to call onLoad right after the poster is loaded // we want to call onLoad right after the poster is loaded
// otherwise, the skeleton will be shown underneath the element until the video is loaded // otherwise, the skeleton will be shown underneath the element until the video is loaded
const poster = new Image(); onLoad && (poster.onload = onLoad);
poster.src = ref.current.poster;
poster.onload = onLoad; ref.current.poster = poster.src;
} }, [ onLoad ]);
const loadPosterViaIpfs = React.useCallback((url: string) => {
loadImageViaIpfs(url)
.then((src) => {
if (src && ref.current) {
ref.current.poster = src;
onLoad?.();
} }
}, [ instance.image_url, instance.metadata?.image, instance.thumbnails, onLoad ]); })
.catch(onError);
}, [ loadImageViaIpfs, onError, onLoad ]);
React.useEffect(() => { React.useEffect(() => {
!autoPlay && fetchVideoPoster(); if (autoPlay) {
return () => { return;
controller.current?.abort(); }
};
// run only on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleMouseEnter = React.useCallback(() => { if (!mediaInfoQuery.isPending && mediaInfoQuery.data) {
!autoPlay && ref.current?.play(); const mediaInfo = mediaInfoQuery.data[0];
}, [ autoPlay ]); switch (mediaInfo.transport) {
case 'ipfs':
loadPosterViaIpfs(mediaInfo.src);
break;
case 'http':
loadPosterViaHttp(mediaInfo.src);
break;
}
}
const handleMouseLeave = React.useCallback(() => { }, [ autoPlay, loadPosterViaHttp, loadPosterViaIpfs, mediaInfoQuery.data, mediaInfoQuery.isPending ]);
!autoPlay && ref.current?.pause();
}, [ autoPlay ]);
return ( return (
<chakra.video <chakra.video
ref={ ref } ref={ ref }
{ ...videoPlayProps } { ...videoPlayProps }
autoPlay={ autoPlay } autoPlay={ autoPlay }
src={ src }
onCanPlayThrough={ onLoad }
onError={ onError }
borderRadius="md"
onClick={ onClick } onClick={ onClick }
onMouseEnter={ handleMouseEnter } onMouseEnter={ handleMouseEnter }
onMouseLeave={ handleMouseLeave } onMouseLeave={ handleMouseLeave }
{ ...mediaStyleProps } { ...rest }
/> />
); );
}; };
......
import { chakra } from '@chakra-ui/react';
import React from 'react';
import NftMediaFullscreenModal from './NftMediaFullscreenModal';
import { videoPlayProps } from './utils';
interface Props {
src: string;
open: boolean;
onOpenChange: ({ open }: { open: boolean }) => void;
}
const NftVideoFullscreen = ({ src, open, onOpenChange }: Props) => {
return (
<NftMediaFullscreenModal open={ open } onOpenChange={ onOpenChange }>
<chakra.video
{ ...videoPlayProps }
src={ src }
maxH="90vh"
maxW="90vw"
autoPlay={ true }
/>
</NftMediaFullscreenModal>
);
};
export default NftVideoFullscreen;
import { verifiedFetch } from '@helia/verified-fetch';
import React from 'react';
export default function useLoadImageViaIpfs() {
return React.useCallback(async(url: string) => {
const response = await verifiedFetch(url);
if (response.status !== 200) {
throw new Error('Failed to load image');
}
const blob = await response.blob();
const src = URL.createObjectURL(blob);
return src;
}, [ ]);
}
import { verifiedFetch } from '@helia/verified-fetch'; import type { UseQueryResult } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { TokenInstance } from 'types/api/token'; import type { TokenInstance } from 'types/api/token';
...@@ -8,151 +7,169 @@ import type { StaticRoute } from 'nextjs-routes'; ...@@ -8,151 +7,169 @@ import type { StaticRoute } from 'nextjs-routes';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources';
import useFetch from 'lib/hooks/useFetch';
import type { MediaType, SrcType } from './utils'; import type { MediaType, Size, TransportType } from './utils';
import { getPreliminaryMediaType } from './utils'; import { getPreliminaryMediaType } from './utils';
interface Params { interface Params {
data: TokenInstance; data: TokenInstance;
size: Size;
allowedTypes?: Array<MediaType>;
field: 'animation_url' | 'image_url';
isEnabled: boolean; isEnabled: boolean;
} }
interface AssetsData { interface MediaInfo {
imageUrl: string | undefined;
animationUrl: string | undefined;
}
type TransportType = 'http' | 'ipfs';
type ReturnType =
{
src: string; src: string;
srcSet?: string;
mediaType: MediaType; mediaType: MediaType;
srcType: SrcType; transport: TransportType;
} |
{
mediaType: undefined;
} |
null;
export default function useNftMediaInfo({ data, isEnabled }: Params): ReturnType | null {
const assetsData = composeAssetsData(data);
const httpPrimaryQuery = useNftMediaTypeQuery(assetsData.http.animationUrl, isEnabled);
const ipfsPrimaryQuery = useFetchAssetViaIpfs(
assetsData.ipfs.animationUrl,
httpPrimaryQuery.data?.mediaType,
isEnabled && (httpPrimaryQuery.data === null || Boolean(httpPrimaryQuery.data?.mediaType)),
);
const httpSecondaryQuery = useNftMediaTypeQuery(assetsData.http.imageUrl, isEnabled && !httpPrimaryQuery.data && !ipfsPrimaryQuery);
const ipfsSecondaryQuery = useFetchAssetViaIpfs(
assetsData.ipfs.imageUrl,
httpSecondaryQuery.data?.mediaType,
isEnabled && (httpSecondaryQuery.data === null || Boolean(httpSecondaryQuery.data?.mediaType)),
);
return React.useMemo(() => {
return ipfsPrimaryQuery || httpPrimaryQuery.data || ipfsSecondaryQuery || httpSecondaryQuery.data || null;
}, [ httpPrimaryQuery.data, httpSecondaryQuery.data, ipfsPrimaryQuery, ipfsSecondaryQuery ]);
}
function composeAssetsData(data: TokenInstance): Record<TransportType, AssetsData> {
return {
http: {
imageUrl: data.image_url || undefined,
animationUrl: data.animation_url || undefined,
},
ipfs: {
imageUrl: typeof data.metadata?.image === 'string' ? data.metadata.image : undefined,
animationUrl: typeof data.metadata?.animation_url === 'string' ? data.metadata.animation_url : undefined,
},
};
} }
// As of now we fetch only images via IPFS because video streaming has performance issues export default function useNftMediaInfo({ data, size, allowedTypes, field, isEnabled }: Params): UseQueryResult<Array<MediaInfo> | null> {
// Also, we don't want to store the entire file content in the ReactQuery cache, so we don't use useQuery hook here const url = data[field];
function useFetchAssetViaIpfs(url: string | undefined, mediaType: MediaType | undefined, isEnabled: boolean): ReturnType | null { const query = useQuery({
const [ result, setResult ] = React.useState<ReturnType | null>({ mediaType: undefined }); queryKey: [ 'nft-media-info', data.id, url, size, ...(allowedTypes ? allowedTypes : []) ],
const controller = React.useRef<AbortController | null>(null); queryFn: async() => {
const metadataField = field === 'animation_url' ? 'animation_url' : 'image';
const mediaType = await getMediaType(data, field);
const fetchAsset = React.useCallback(async(url: string) => { if (!mediaType || (allowedTypes ? !allowedTypes.includes(mediaType) : false)) {
try { return null;
controller.current = new AbortController();
const response = await verifiedFetch(url, { signal: controller.current.signal });
if (response.status === 200) {
const blob = await response.blob();
const src = URL.createObjectURL(blob);
setResult({ mediaType: 'image', src, srcType: 'blob' });
return;
} }
} catch (error) {}
setResult(null);
}, []);
React.useEffect(() => { const cdnData = getCdnData(data, size, mediaType);
if (isEnabled) { const ipfsData = getIpfsData(data.metadata?.[metadataField], mediaType);
if (config.UI.views.nft.verifiedFetch.isEnabled && mediaType === 'image' && url && url.includes('ipfs')) {
fetchAsset(url);
} else {
setResult(null);
}
} else {
setResult({ mediaType: undefined });
}
}, [ fetchAsset, url, mediaType, isEnabled ]);
React.useEffect(() => { return [
return () => { cdnData,
controller.current?.abort(); ipfsData,
}; url ? { src: url, mediaType, transport: 'http' as const } : undefined,
}, []); ].filter(Boolean);
},
enabled: isEnabled,
});
return result; return query;
} }
function useNftMediaTypeQuery(url: string | undefined, enabled: boolean) { async function getMediaType(data: TokenInstance, field: Params['field']): Promise<MediaType | undefined> {
const fetch = useFetch(); const url = data[field];
return useQuery<ReturnType | null, ResourceError<unknown>, ReturnType | null>({
queryKey: [ 'nft-media-type', url ],
queryFn: async() => {
if (!url) { if (!url) {
return null; return;
} }
// media could be either image, gif, video or html-page // If the media_url is the same as the url, we can use the media_type field to determine the media type.
// so we pre-fetch the resources in order to get its content type if (url === data.media_url) {
// have to do it via Node.js due to strict CSP for connect-src const mediaType = castMimeTypeToMediaType(data.media_type || undefined);
// but in order not to abuse our server firstly we check file url extension if (mediaType) {
// and if it is valid we will trust it and display corresponding media component return mediaType;
}
}
// Media can be an image, video, or HTML page.
// We pre-fetch the resources to determine their content type.
// We must do this via Node.js due to strict CSP for connect-src.
// To avoid overloading our server, we first check the file URL extension.
// If it is valid, we will trust it and display the corresponding media component.
const preliminaryType = getPreliminaryMediaType(url); const preliminaryType = getPreliminaryMediaType(url);
if (preliminaryType) { if (preliminaryType) {
return { mediaType: preliminaryType, src: url, srcType: 'url' }; return preliminaryType;
} }
const mediaType = await (async() => {
try { try {
const mediaTypeResourceUrl = route({ pathname: '/node-api/media-type' as StaticRoute<'/api/media-type'>['pathname'], query: { url } }); const mediaTypeResourceUrl = route({ pathname: '/node-api/media-type' as StaticRoute<'/api/media-type'>['pathname'], query: { url } });
const response = await fetch<{ type: MediaType | undefined }, ResourceError>(mediaTypeResourceUrl, undefined, { resource: 'media-type' }); const response = await fetch(mediaTypeResourceUrl);
const payload = await response.json() as { type: MediaType | undefined };
return 'type' in response ? response.type : undefined; return payload.type;
} catch (error) { } catch (error) {
return; return;
} }
})(); }
if (!mediaType) { function castMimeTypeToMediaType(mimeType: string | undefined): MediaType | undefined {
return null; if (!mimeType) {
return;
} }
return { mediaType, src: url, srcType: 'url' }; if (mimeType.startsWith('image/')) {
}, return 'image';
enabled, }
placeholderData: { mediaType: undefined },
staleTime: Infinity, if (mimeType.startsWith('video/')) {
}); return 'video';
}
}
function getCdnData(data: TokenInstance, size: Size, mediaType: MediaType): MediaInfo | undefined {
// CDN is only used for images
if (mediaType !== 'image') {
return;
}
if (!data.thumbnails) {
return;
}
switch (size) {
case 'sm': {
return {
src: data.thumbnails['60x60'] || data.thumbnails['250x250'] || data.thumbnails['500x500'] || data.thumbnails['original'],
// the smallest thumbnail is already greater than sm size by two times
// so there is no need to pass srcSet
srcSet: undefined,
mediaType: 'image',
transport: 'http',
};
}
case 'md': {
const srcSet = data.thumbnails['250x250'] && data.thumbnails['500x500'] ? `${ data.thumbnails['500x500'] } 2x` : undefined;
const src = (srcSet ? data.thumbnails['250x250'] : undefined) || data.thumbnails['500x500'] || data.thumbnails.original;
return {
src,
srcSet,
mediaType: 'image',
transport: 'http',
};
}
default: {
if (data.thumbnails.original) {
return {
src: data.thumbnails.original,
mediaType: 'image',
transport: 'http',
};
}
}
}
}
function getIpfsData(url: unknown, mediaType: MediaType): MediaInfo | undefined {
if (!config.UI.views.nft.verifiedFetch.isEnabled) {
return;
}
// Currently we only load images via IPFS
if (mediaType !== 'image') {
return;
}
if (typeof url !== 'string') {
return;
}
if (!url.includes('ipfs')) {
return;
}
return {
src: url,
mediaType,
transport: 'ipfs',
};
} }
import type { HTMLChakraProps } from '@chakra-ui/react';
import type React from 'react';
export type MediaType = 'image' | 'video' | 'html'; export type MediaType = 'image' | 'video' | 'html';
export type TransportType = 'http' | 'ipfs';
// Currently we have only 3 sizes:
// sm = max-width<=30px
// md = max-width<=250px
// original
export type Size = 'sm' | 'md' | 'original';
export type SrcType = 'url' | 'blob'; export type MediaElementProps<As extends React.ElementType> = HTMLChakraProps<As> & {
src: string;
srcSet?: string;
transport: TransportType;
onLoad?: () => void;
onError?: () => void;
onClick?: () => void;
};
// https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types
const IMAGE_EXTENSIONS = [ const IMAGE_EXTENSIONS = [
'.jpg', 'jpeg', '.jpg', 'jpeg', '.jfif', '.pjpeg', '.pjp',
'.png', '.png', '.apng',
'.avif',
'.gif', '.gif',
'.svg', '.svg',
'.webp',
]; ];
const VIDEO_EXTENSIONS = [ const VIDEO_EXTENSIONS = [
......
...@@ -129,11 +129,9 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({ ...@@ -129,11 +129,9 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
} }
scrollToTop(); scrollToTop();
router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true })
.then(() => {
setPage(prev => clamp(prev - 1, 1, Infinity)); setPage(prev => clamp(prev - 1, 1, Infinity));
page === 2 && queryClient.removeQueries({ queryKey: [ resourceName ] }); page === 2 && queryClient.removeQueries({ queryKey: [ resourceName ] });
}); router.push({ pathname: router.pathname, query: nextPageQuery }, undefined, { shallow: true });
}, [ router, page, pageParams, scrollToTop, queryClient, resourceName ]); }, [ router, page, pageParams, scrollToTop, queryClient, resourceName ]);
const resetPage = useCallback(() => { const resetPage = useCallback(() => {
......
import React from 'react';
import type { InteropMessage } from 'types/api/interop';
import type { StatusTagType } from './StatusTag';
import StatusTag from './StatusTag';
export interface Props {
status: InteropMessage['status'];
isLoading?: boolean;
}
const InteropMessageStatus = ({ status, isLoading }: Props) => {
let type: StatusTagType;
switch (status) {
case 'Relayed': {
type = 'ok';
break;
}
case 'Failed': {
type = 'error';
break;
}
case 'Sent': {
type = 'pending';
break;
}
default:
type = 'pending';
break;
}
return <StatusTag type={ type } text={ status } isLoading={ isLoading }/>;
};
export default InteropMessageStatus;
...@@ -28,6 +28,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => { ...@@ -28,6 +28,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => {
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const recaptcha = useReCaptcha(); const recaptcha = useReCaptcha();
const [ isCodeSending, setIsCodeSending ] = React.useState(false); const [ isCodeSending, setIsCodeSending ] = React.useState(false);
const [ resendAttempts, setResendAttempts ] = React.useState(0);
const formApi = useForm<OtpCodeFormFields>({ const formApi = useForm<OtpCodeFormFields>({
mode: 'onBlur', mode: 'onBlur',
...@@ -92,6 +93,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => { ...@@ -92,6 +93,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => {
description: apiError?.message || getErrorMessage(error) || 'Something went wrong', description: apiError?.message || getErrorMessage(error) || 'Something went wrong',
}); });
} finally { } finally {
setResendAttempts((prev) => prev + 1);
setIsCodeSending(false); setIsCodeSending(false);
} }
}, [ apiFetch, email, formApi, recaptcha ]); }, [ apiFetch, email, formApi, recaptcha ]);
...@@ -108,7 +110,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => { ...@@ -108,7 +110,7 @@ const AuthModalScreenOtpCode = ({ email, onSuccess, isAuth }: Props) => {
and enter your code below. and enter your code below.
</Text> </Text>
<AuthModalFieldOtpCode isDisabled={ isCodeSending }/> <AuthModalFieldOtpCode isDisabled={ isCodeSending }/>
<ReCaptcha ref={ recaptcha.ref }/> <ReCaptcha key={ resendAttempts } ref={ recaptcha.ref }/>
<Button <Button
variant="link" variant="link"
columnGap={ 2 } columnGap={ 2 }
......
...@@ -24,6 +24,7 @@ const TokenInventoryItem = ({ item, token, isLoading }: Props) => { ...@@ -24,6 +24,7 @@ const TokenInventoryItem = ({ item, token, isLoading }: Props) => {
data={ item } data={ item }
isLoading={ isLoading } isLoading={ isLoading }
autoplayVideo={ false } autoplayVideo={ false }
size="md"
/> />
); );
......
...@@ -2,6 +2,7 @@ import { Box } from '@chakra-ui/react'; ...@@ -2,6 +2,7 @@ import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { tokenInfoERC20a, tokenInfoERC721a, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo'; import { tokenInfoERC20a, tokenInfoERC721a, tokenInfoERC1155a } from 'mocks/tokens/tokenInfo';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as tokenTransferMock from 'mocks/tokens/tokenTransfer'; import * as tokenTransferMock from 'mocks/tokens/tokenTransfer';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
...@@ -33,7 +34,8 @@ test('erc20 +@mobile', async({ render }) => { ...@@ -33,7 +34,8 @@ test('erc20 +@mobile', async({ render }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('erc721 +@mobile', async({ render }) => { test('erc721 +@mobile', async({ render, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render( const component = await render(
<Box pt={{ base: '134px', lg: '100px' }}> <Box pt={{ base: '134px', lg: '100px' }}>
<TokenTransfer <TokenTransfer
......
...@@ -4,7 +4,7 @@ import { useRouter } from 'next/router'; ...@@ -4,7 +4,7 @@ import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { SocketMessage } from 'lib/socket/types'; import type { SocketMessage } from 'lib/socket/types';
import type { TokenInfo } from 'types/api/token'; import type { TokenInfo, TokenInstance } from 'types/api/token';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useGradualIncrement from 'lib/hooks/useGradualIncrement'; import useGradualIncrement from 'lib/hooks/useGradualIncrement';
...@@ -25,12 +25,13 @@ const TABS_HEIGHT = 88; ...@@ -25,12 +25,13 @@ const TABS_HEIGHT = 88;
type Props = { type Props = {
transfersQuery: QueryWithPagesResult<'token_transfers'> | QueryWithPagesResult<'token_instance_transfers'>; transfersQuery: QueryWithPagesResult<'token_transfers'> | QueryWithPagesResult<'token_instance_transfers'>;
tokenId?: string; tokenId?: string;
tokenInstance?: TokenInstance;
tokenQuery: UseQueryResult<TokenInfo, ResourceError<unknown>>; tokenQuery: UseQueryResult<TokenInfo, ResourceError<unknown>>;
shouldRender?: boolean; shouldRender?: boolean;
tabsHeight?: number; tabsHeight?: number;
}; };
const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_HEIGHT, shouldRender = true }: Props) => { const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_HEIGHT, tokenInstance, shouldRender = true }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
const router = useRouter(); const router = useRouter();
...@@ -81,6 +82,7 @@ const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_ ...@@ -81,6 +82,7 @@ const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_
socketInfoNum={ newItemsCount } socketInfoNum={ newItemsCount }
tokenId={ tokenId } tokenId={ tokenId }
token={ token } token={ token }
instance={ tokenInstance }
isLoading={ isLoading } isLoading={ isLoading }
/> />
</Box> </Box>
...@@ -94,7 +96,7 @@ const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_ ...@@ -94,7 +96,7 @@ const TokenTransfer = ({ transfersQuery, tokenId, tokenQuery, tabsHeight = TABS_
isLoading={ isLoading } isLoading={ isLoading }
/> />
) } ) }
<TokenTransferList data={ data?.items } tokenId={ tokenId } isLoading={ isLoading }/> <TokenTransferList data={ data?.items } tokenId={ tokenId } instance={ tokenInstance } isLoading={ isLoading }/>
</Box> </Box>
</> </>
) : null; ) : null;
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import TokenTransferListItem from 'ui/token/TokenTransfer/TokenTransferListItem'; import TokenTransferListItem from 'ui/token/TokenTransfer/TokenTransferListItem';
...@@ -8,10 +9,11 @@ import TokenTransferListItem from 'ui/token/TokenTransfer/TokenTransferListItem' ...@@ -8,10 +9,11 @@ import TokenTransferListItem from 'ui/token/TokenTransfer/TokenTransferListItem'
interface Props { interface Props {
data: Array<TokenTransfer>; data: Array<TokenTransfer>;
tokenId?: string; tokenId?: string;
instance?: TokenInstance;
isLoading?: boolean; isLoading?: boolean;
} }
const TokenTransferList = ({ data, tokenId, isLoading }: Props) => { const TokenTransferList = ({ data, tokenId, instance, isLoading }: Props) => {
return ( return (
<Box> <Box>
{ data.map((item, index) => ( { data.map((item, index) => (
...@@ -19,6 +21,7 @@ const TokenTransferList = ({ data, tokenId, isLoading }: Props) => { ...@@ -19,6 +21,7 @@ const TokenTransferList = ({ data, tokenId, isLoading }: Props) => {
key={ item.transaction_hash + item.block_hash + item.log_index + '_' + index } key={ item.transaction_hash + item.block_hash + item.log_index + '_' + index }
{ ...item } { ...item }
tokenId={ tokenId } tokenId={ tokenId }
instance={ instance }
isLoading={ isLoading } isLoading={ isLoading }
/> />
)) } )) }
......
import { Grid, Flex } from '@chakra-ui/react'; import { Grid, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
...@@ -14,7 +15,7 @@ import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; ...@@ -14,7 +15,7 @@ import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip'; import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TruncatedValue from 'ui/shared/TruncatedValue'; import TruncatedValue from 'ui/shared/TruncatedValue';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean }; type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean; instance?: TokenInstance };
const TokenTransferListItem = ({ const TokenTransferListItem = ({
token, token,
...@@ -26,6 +27,7 @@ const TokenTransferListItem = ({ ...@@ -26,6 +27,7 @@ const TokenTransferListItem = ({
timestamp, timestamp,
tokenId, tokenId,
isLoading, isLoading,
instance,
}: Props) => { }: Props) => {
const { usd, valueStr } = total && 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = total && 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
...@@ -94,6 +96,7 @@ const TokenTransferListItem = ({ ...@@ -94,6 +96,7 @@ const TokenTransferListItem = ({
<NftEntity <NftEntity
hash={ token.address } hash={ token.address }
id={ total.token_id } id={ total.token_id }
instance={ instance || total.token_instance }
noLink={ Boolean(tokenId && tokenId === total.token_id) } noLink={ Boolean(tokenId && tokenId === total.token_id) }
isLoading={ isLoading } isLoading={ isLoading }
/> />
......
import React from 'react'; import React from 'react';
import type { TokenInfo } from 'types/api/token'; import type { TokenInfo, TokenInstance } from 'types/api/token';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import { AddressHighlightProvider } from 'lib/contexts/addressHighlight'; import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
...@@ -19,9 +19,10 @@ interface Props { ...@@ -19,9 +19,10 @@ interface Props {
tokenId?: string; tokenId?: string;
isLoading?: boolean; isLoading?: boolean;
token: TokenInfo; token: TokenInfo;
instance?: TokenInstance;
} }
const TokenTransferTable = ({ data, top, showSocketInfo, socketInfoAlert, socketInfoNum, tokenId, isLoading, token }: Props) => { const TokenTransferTable = ({ data, top, showSocketInfo, socketInfoAlert, socketInfoNum, tokenId, isLoading, token, instance }: Props) => {
const tokenType = token.type; const tokenType = token.type;
...@@ -58,6 +59,7 @@ const TokenTransferTable = ({ data, top, showSocketInfo, socketInfoAlert, socket ...@@ -58,6 +59,7 @@ const TokenTransferTable = ({ data, top, showSocketInfo, socketInfoAlert, socket
key={ item.transaction_hash + item.block_hash + item.log_index + '_' + index } key={ item.transaction_hash + item.block_hash + item.log_index + '_' + index }
{ ...item } { ...item }
tokenId={ tokenId } tokenId={ tokenId }
instance={ instance }
isLoading={ isLoading } isLoading={ isLoading }
/> />
)) } )) }
......
import { Flex, Box } from '@chakra-ui/react'; import { Flex, Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenInstance } from 'types/api/token';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
...@@ -13,7 +14,7 @@ import NftEntity from 'ui/shared/entities/nft/NftEntity'; ...@@ -13,7 +14,7 @@ import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip'; import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean }; type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean; instance?: TokenInstance };
const TokenTransferTableItem = ({ const TokenTransferTableItem = ({
token, token,
...@@ -25,6 +26,7 @@ const TokenTransferTableItem = ({ ...@@ -25,6 +26,7 @@ const TokenTransferTableItem = ({
timestamp, timestamp,
tokenId, tokenId,
isLoading, isLoading,
instance,
}: Props) => { }: Props) => {
const { usd, valueStr } = total && 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = total && 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
...@@ -79,6 +81,7 @@ const TokenTransferTableItem = ({ ...@@ -79,6 +81,7 @@ const TokenTransferTableItem = ({
<NftEntity <NftEntity
hash={ token.address } hash={ token.address }
id={ total.token_id } id={ total.token_id }
instance={ instance || total.token_instance }
noLink={ Boolean(tokenId && tokenId === total.token_id) } noLink={ Boolean(tokenId && tokenId === total.token_id) }
isLoading={ isLoading } isLoading={ isLoading }
/> />
......
...@@ -112,6 +112,7 @@ const TokenInstanceDetails = ({ data, token, scrollRef, isLoading }: Props) => { ...@@ -112,6 +112,7 @@ const TokenInstanceDetails = ({ data, token, scrollRef, isLoading }: Props) => {
<NftMedia <NftMedia
data={ data } data={ data }
isLoading={ isLoading } isLoading={ isLoading }
size="md"
withFullscreen withFullscreen
w="250px" w="250px"
flexShrink={ 0 } flexShrink={ 0 }
......
...@@ -76,6 +76,7 @@ const TokenTransfersListItem = ({ item, isLoading }: Props) => { ...@@ -76,6 +76,7 @@ const TokenTransfersListItem = ({ item, isLoading }: Props) => {
<NftEntity <NftEntity
hash={ item.token.address } hash={ item.token.address }
id={ item.total.token_id } id={ item.total.token_id }
instance={ item.total.token_instance }
isLoading={ isLoading } isLoading={ isLoading }
noIcon noIcon
/> />
......
...@@ -68,6 +68,7 @@ const TokenTransferTableItem = ({ item, isLoading }: Props) => { ...@@ -68,6 +68,7 @@ const TokenTransferTableItem = ({ item, isLoading }: Props) => {
<NftEntity <NftEntity
hash={ item.token.address } hash={ item.token.address }
id={ item.total.token_id } id={ item.total.token_id }
instance={ item.total.token_instance }
isLoading={ isLoading } isLoading={ isLoading }
maxW="140px" maxW="140px"
/> />
......
import { Grid, Text, Flex, Box } from '@chakra-ui/react';
import React from 'react';
import type { InteropTransactionInfo } from 'types/api/transaction';
import config from 'configs/app';
import { CollapsibleDetails } from 'toolkit/chakra/collapsible';
import InteropMessageDestinationTx from 'ui/interopMessages/InteropMessageDestinationTx';
import InteropMessageSourceTx from 'ui/interopMessages/InteropMessageSourceTx';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressEntityInterop from 'ui/shared/entities/address/AddressEntityInterop';
import InteropMessageStatus from 'ui/shared/statusTag/InteropMessageStatus';
const rollupFeature = config.features.rollup;
type Props = {
data?: InteropTransactionInfo;
isLoading: boolean;
};
const TxDetailsInterop = ({ data, isLoading }: Props) => {
const hasInterop = rollupFeature.isEnabled && rollupFeature.interopEnabled;
if (!hasInterop || !data) {
return null;
}
const details = (
<Grid
gridTemplateColumns="100px 1fr"
textStyle="sm"
bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }}
px={ 4 }
py={ 2 }
mt={ 3 }
w="100%"
rowGap={ 4 }
borderRadius="md"
>
<Text color="text.secondary">Message id</Text>
<Text>{ data.nonce }</Text>
<Text color="text.secondary">Interop status</Text>
<Box>
<InteropMessageStatus status={ data.status }/>
</Box>
<Text color="text.secondary">Sender</Text>
{ data.init_chain !== undefined ? (
<AddressEntityInterop
chain={ data.init_chain }
address={{ hash: data.sender }}
isLoading={ isLoading }
truncation="constant"
/>
) : (
<AddressEntity address={{ hash: data.sender }} isLoading={ isLoading } truncation="constant"/>
) }
<Text color="text.secondary">Target</Text>
{ data.relay_chain !== undefined ? (
<AddressEntityInterop
chain={ data.relay_chain }
address={{ hash: data.target }}
isLoading={ isLoading }
truncation="constant"
/>
) : (
<AddressEntity address={{ hash: data.target }} isLoading={ isLoading } truncation="constant"/>
) }
<Text color="text.secondary">Payload</Text>
<Flex overflow="hidden">
<Text
wordBreak="break-all"
whiteSpace="normal"
overflow="hidden"
flex="1"
>
{ data.payload }
</Text>
<CopyToClipboard text={ data.payload }/>
</Flex>
</Grid>
);
if (data.init_chain !== undefined) {
return (
<>
<DetailedInfo.ItemLabel
hint="The originating transaction that initiated the cross-L2 message on the source chain"
isLoading={ isLoading }
>
Interop source tx
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<InteropMessageSourceTx { ...data } isLoading={ isLoading }/>
<CollapsibleDetails variant="secondary" noScroll ml={ 3 }>
{ details }
</CollapsibleDetails>
</DetailedInfo.ItemValue>
</>
);
}
if (data.relay_chain !== undefined) {
return (
<>
<DetailedInfo.ItemLabel
hint="The transaction that relays the cross-L2 message to its destination chain"
isLoading={ isLoading }
>
Interop relay tx
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<InteropMessageDestinationTx { ...data } isLoading={ isLoading }/>
<CollapsibleDetails variant="secondary" noScroll ml={ 3 }>
{ details }
</CollapsibleDetails>
</DetailedInfo.ItemValue>
</>
);
}
return null;
};
export default TxDetailsInterop;
import React from 'react'; import React from 'react';
import * as tokenInstanceMock from 'mocks/tokens/tokenInstance';
import * as txMock from 'mocks/txs/tx'; import * as txMock from 'mocks/txs/tx';
import { ENVS_MAP } from 'playwright/fixtures/mockEnvs'; import { ENVS_MAP } from 'playwright/fixtures/mockEnvs';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
...@@ -27,7 +28,8 @@ test('creating contact', async({ render, page }) => { ...@@ -27,7 +28,8 @@ test('creating contact', async({ render, page }) => {
}); });
}); });
test('with token transfer +@mobile', async({ render, page }) => { test('with token transfer +@mobile', async({ render, page, mockAssetResponse }) => {
await mockAssetResponse(tokenInstanceMock.base.image_url as string, './playwright/mocks/image_s.jpg');
const component = await render(<TxInfo data={ txMock.withTokenTransfer } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.withTokenTransfer } isLoading={ false }/>);
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot({
...@@ -127,11 +129,40 @@ test('arbitrum L1 status', async({ render, mockEnvs }) => { ...@@ -127,11 +129,40 @@ test('arbitrum L1 status', async({ render, mockEnvs }) => {
await expect(statusElement).toHaveScreenshot(); await expect(statusElement).toHaveScreenshot();
}); });
test('with external txs +@mobile', async({ render, mockEnvs, mockApiResponse, mockAssetResponse }) => { test('with external txs +@mobile', async({ page, render, mockEnvs, mockApiResponse, mockAssetResponse }) => {
await mockEnvs(ENVS_MAP.externalTxs); await mockEnvs(ENVS_MAP.externalTxs);
await mockApiResponse('tx_external_transactions', [ 'tx1', 'tx2', 'tx3' ], { pathParams: { hash: txMock.base.hash } }); await mockApiResponse('tx_external_transactions', [ 'tx1', 'tx2', 'tx3' ], { pathParams: { hash: txMock.base.hash } });
await mockAssetResponse('http://example.url', './playwright/mocks/image_s.jpg'); await mockAssetResponse('http://example.url', './playwright/mocks/image_s.jpg');
const component = await render(<TxInfo data={ txMock.base } isLoading={ false }/>); const component = await render(<TxInfo data={ txMock.base } isLoading={ false }/>);
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot({
mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: pwConfig.maskColor,
});
});
test('with interop message in +@mobile', async({ render, page, mockEnvs, mockAssetResponse }) => {
await mockEnvs(ENVS_MAP.interop);
await mockAssetResponse('https://example.com/logo.png', './playwright/mocks/image_s.jpg');
const component = await render(<TxInfo data={ txMock.withInteropInMessage } isLoading={ false }/>);
await page.getByText('View details').first().click();
await expect(page.getByText('Interop status')).toBeVisible();
await expect(component).toHaveScreenshot({
mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: pwConfig.maskColor,
});
});
test('with interop message out +@mobile', async({ page, render, mockEnvs, mockAssetResponse }) => {
await mockEnvs(ENVS_MAP.interop);
await mockAssetResponse('https://example.com/logo.png', './playwright/mocks/image_s.jpg');
const component = await render(<TxInfo data={ txMock.withInteropOutMessage } isLoading={ false }/>);
await component.getByText('View details').first().click();
await expect(component.getByText('Interop status')).toBeVisible();
await expect(component).toHaveScreenshot({
mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: pwConfig.maskColor,
});
}); });
...@@ -35,6 +35,7 @@ import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; ...@@ -35,6 +35,7 @@ import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem'; import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp'; import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressEntityInterop from 'ui/shared/entities/address/AddressEntityInterop';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
...@@ -61,11 +62,10 @@ import TxExternalTxs from 'ui/tx/TxExternalTxs'; ...@@ -61,11 +62,10 @@ import TxExternalTxs from 'ui/tx/TxExternalTxs';
import TxSocketAlert from 'ui/tx/TxSocketAlert'; import TxSocketAlert from 'ui/tx/TxSocketAlert';
import ZkSyncL2TxnBatchHashesInfo from 'ui/txnBatches/zkSyncL2/ZkSyncL2TxnBatchHashesInfo'; import ZkSyncL2TxnBatchHashesInfo from 'ui/txnBatches/zkSyncL2/ZkSyncL2TxnBatchHashesInfo';
import TxDetailsInterop from './TxDetailsInterop';
import TxDetailsWithdrawalStatusArbitrum from './TxDetailsWithdrawalStatusArbitrum'; import TxDetailsWithdrawalStatusArbitrum from './TxDetailsWithdrawalStatusArbitrum';
import TxInfoScrollFees from './TxInfoScrollFees'; import TxInfoScrollFees from './TxInfoScrollFees';
const rollupFeature = config.features.rollup;
interface Props { interface Props {
data: Transaction | undefined; data: Transaction | undefined;
isLoading: boolean; isLoading: boolean;
...@@ -73,6 +73,7 @@ interface Props { ...@@ -73,6 +73,7 @@ interface Props {
} }
const externalTxFeature = config.features.externalTxs; const externalTxFeature = config.features.externalTxs;
const rollupFeature = config.features.rollup;
const TxInfo = ({ data, isLoading, socketStatus }: Props) => { const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
...@@ -129,6 +130,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -129,6 +130,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</Tooltip> </Tooltip>
) : null; ) : null;
const hasInterop = rollupFeature.isEnabled && rollupFeature.interopEnabled && data.op_interop;
return ( return (
<DetailedInfo.Container templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}> <DetailedInfo.Container templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
...@@ -146,6 +149,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -146,6 +149,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</GridItem> </GridItem>
) } ) }
<TxDetailsInterop data={ data.op_interop } isLoading={ isLoading }/>
<DetailedInfo.ItemLabel <DetailedInfo.ItemLabel
hint="Unique character string (TxID) assigned to every verified transaction" hint="Unique character string (TxID) assigned to every verified transaction"
isLoading={ isLoading } isLoading={ isLoading }
...@@ -486,6 +491,52 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -486,6 +491,52 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
{ data.token_transfers && <TxDetailsTokenTransfers data={ data.token_transfers } txHash={ data.hash } isOverflow={ data.token_transfers_overflow }/> } { data.token_transfers && <TxDetailsTokenTransfers data={ data.token_transfers } txHash={ data.hash } isOverflow={ data.token_transfers_overflow }/> }
{ hasInterop && data.op_interop?.target && (
<>
<DetailedInfo.ItemLabel
isLoading={ isLoading }
hint="The target address where this cross-chain transaction is executed"
>
Interop target
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
{ data.op_interop?.relay_chain !== undefined ? (
<AddressEntityInterop
chain={ data.op_interop.relay_chain }
address={{ hash: data.op_interop.target }}
isLoading={ isLoading }
truncation="dynamic"
/>
) : (
<AddressEntity address={{ hash: data.op_interop.target }} isLoading={ isLoading } truncation="dynamic"/>
) }
</DetailedInfo.ItemValue>
</>
) }
{ hasInterop && data.op_interop?.target && (
<>
<DetailedInfo.ItemLabel
isLoading={ isLoading }
hint="The target address where this cross-chain transaction is executed"
>
Interop target
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
{ data.op_interop?.relay_chain !== undefined ? (
<AddressEntityInterop
chain={ data.op_interop.relay_chain }
address={{ hash: data.op_interop.target }}
isLoading={ isLoading }
truncation="dynamic"
/>
) : (
<AddressEntity address={{ hash: data.op_interop.target }} isLoading={ isLoading } truncation="dynamic"/>
) }
</DetailedInfo.ItemValue>
</>
) }
<DetailedInfo.ItemDivider/> <DetailedInfo.ItemDivider/>
{ (data.arbitrum?.commitment_transaction.hash || data.arbitrum?.confirmation_transaction.hash) && { (data.arbitrum?.commitment_transaction.hash || data.arbitrum?.confirmation_transaction.hash) &&
......
...@@ -51,7 +51,7 @@ const TxAdditionalInfo = ({ hash, tx, isMobile, isLoading, className }: Props) = ...@@ -51,7 +51,7 @@ const TxAdditionalInfo = ({ hash, tx, isMobile, isLoading, className }: Props) =
<AdditionalInfoButton loading={ isLoading } className={ className }/> <AdditionalInfoButton loading={ isLoading } className={ className }/>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent w="330px"> <PopoverContent w="330px">
<PopoverBody textStyle="sm"> <PopoverBody>
<Heading level="3" mb={ 6 }>Additional info </Heading> <Heading level="3" mb={ 6 }>Additional info </Heading>
{ content } { content }
</PopoverBody> </PopoverBody>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7"
integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==
"@adraffy/ens-normalize@1.11.0", "@adraffy/ens-normalize@^1.10.1": "@adraffy/ens-normalize@^1.10.1":
version "1.11.0" version "1.11.0"
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33"
integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg== integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==
...@@ -114,6 +114,15 @@ ...@@ -114,6 +114,15 @@
"@babel/highlight" "^7.24.7" "@babel/highlight" "^7.24.7"
picocolors "^1.0.0" picocolors "^1.0.0"
"@babel/code-frame@^7.26.2":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
dependencies:
"@babel/helper-validator-identifier" "^7.25.9"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1":
version "7.20.1" version "7.20.1"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30"
...@@ -536,6 +545,11 @@ ...@@ -536,6 +545,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d"
integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
"@babel/helper-string-parser@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
version "7.19.1" version "7.19.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
...@@ -551,6 +565,11 @@ ...@@ -551,6 +565,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db"
integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
"@babel/helper-validator-identifier@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
"@babel/helper-validator-option@^7.18.6": "@babel/helper-validator-option@^7.18.6":
version "7.18.6" version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
...@@ -576,31 +595,13 @@ ...@@ -576,31 +595,13 @@
"@babel/traverse" "^7.19.0" "@babel/traverse" "^7.19.0"
"@babel/types" "^7.19.0" "@babel/types" "^7.19.0"
"@babel/helpers@^7.20.1": "@babel/helpers@^7.20.1", "@babel/helpers@^7.22.0", "@babel/helpers@^7.25.0":
version "7.20.1" version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.0.tgz#53d156098defa8243eab0f32fa17589075a1b808"
integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== integrity "sha1-U9FWCY3vqCQ+qw8y+hdYkHWhuAg= sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg=="
dependencies:
"@babel/template" "^7.18.10"
"@babel/traverse" "^7.20.1"
"@babel/types" "^7.20.0"
"@babel/helpers@^7.22.0":
version "7.22.3"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.3.tgz#53b74351da9684ea2f694bf0877998da26dd830e"
integrity sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==
dependencies:
"@babel/template" "^7.21.9"
"@babel/traverse" "^7.22.1"
"@babel/types" "^7.22.3"
"@babel/helpers@^7.25.0":
version "7.25.6"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.6.tgz#57ee60141829ba2e102f30711ffe3afab357cc60"
integrity sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==
dependencies: dependencies:
"@babel/template" "^7.25.0" "@babel/template" "^7.27.0"
"@babel/types" "^7.25.6" "@babel/types" "^7.27.0"
"@babel/highlight@^7.18.6": "@babel/highlight@^7.18.6":
version "7.18.6" version "7.18.6"
...@@ -657,6 +658,13 @@ ...@@ -657,6 +658,13 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b"
integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==
"@babel/parser@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.0.tgz#3d7d6ee268e41d2600091cbd4e145ffee85a44ec"
integrity "sha1-PX1u4mjkHSYACRy9ThRf/uhaROw= sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="
dependencies:
"@babel/types" "^7.27.0"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
version "7.18.6" version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
...@@ -1375,78 +1383,21 @@ ...@@ -1375,78 +1383,21 @@
"@babel/helper-validator-option" "^7.18.6" "@babel/helper-validator-option" "^7.18.6"
"@babel/plugin-transform-typescript" "^7.18.6" "@babel/plugin-transform-typescript" "^7.18.6"
"@babel/runtime-corejs3@^7.20.7": "@babel/runtime-corejs3@^7.20.7", "@babel/runtime-corejs3@^7.22.15", "@babel/runtime-corejs3@^7.23.1":
version "7.21.0" version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz#6e4939d9d9789ff63e2dc58e88f13a3913a24eba" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.27.0.tgz#c766df350ec7a2caf3ed64e3659b100954589413"
integrity sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw== integrity "sha1-x2bfNQ7Hosrz7WTjZZsQCVRYlBM= sha512-UWjX6t+v+0ckwZ50Y5ShZLnlk95pP5MyW/pon9tiYzl3+18pkTHTFNTKr7rQbfRXPkowt2QAn30o1b6oswszew=="
dependencies:
core-js-pure "^3.25.1"
regenerator-runtime "^0.13.11"
"@babel/runtime-corejs3@^7.22.15", "@babel/runtime-corejs3@^7.23.1":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz#a5cd9d8b408fb946b2f074b21ea40c04e516795c"
integrity sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw==
dependencies: dependencies:
core-js-pure "^3.30.2" core-js-pure "^3.30.2"
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3": "@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.5", "@babel/runtime@^7.26.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.19.4" version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762"
integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== integrity "sha1-++58+XxwlRjswfWQmESB1UYNR2I= sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.0", "@babel/runtime@^7.8.7":
version "7.20.13"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b"
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.12.1", "@babel/runtime@^7.3.1", "@babel/runtime@^7.9.2":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.21.0":
version "7.24.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e"
integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.23.5":
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.5.5":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.8.4":
version "7.20.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9"
integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==
dependencies:
regenerator-runtime "^0.13.10"
"@babel/template@^7.18.10", "@babel/template@^7.3.3": "@babel/template@^7.18.10", "@babel/template@^7.3.3":
version "7.18.10" version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
...@@ -1483,6 +1434,15 @@ ...@@ -1483,6 +1434,15 @@
"@babel/parser" "^7.25.0" "@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0" "@babel/types" "^7.25.0"
"@babel/template@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4"
integrity "sha1-slPlQGzB3xxX3NGPEXYMLb9AwLQ= sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA=="
dependencies:
"@babel/code-frame" "^7.26.2"
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.22.1", "@babel/traverse@^7.7.2": "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.22.1", "@babel/traverse@^7.7.2":
version "7.23.6" version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.6.tgz#b53526a2367a0dd6edc423637f3d2d0f2521abc5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.6.tgz#b53526a2367a0dd6edc423637f3d2d0f2521abc5"
...@@ -1557,6 +1517,14 @@ ...@@ -1557,6 +1517,14 @@
"@babel/helper-validator-identifier" "^7.22.20" "@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@babel/types@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.0.tgz#ef9acb6b06c3173f6632d993ecb6d4ae470b4559"
integrity "sha1-75rLawbDFz9mMtmT7LbUrkcLRVk= sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@bcoe/v8-coverage@^0.2.3": "@bcoe/v8-coverage@^0.2.3":
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
...@@ -1676,16 +1644,6 @@ ...@@ -1676,16 +1644,6 @@
"@ethersproject/solidity" "^5.7.0" "@ethersproject/solidity" "^5.7.0"
jshashes "^1.0.8" jshashes "^1.0.8"
"@coinbase/wallet-sdk@4.2.3":
version "4.2.3"
resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-4.2.3.tgz#a30fa0605b24bc42c37f52a62d2442bcbb7734af"
integrity sha512-BcyHZ/Ec84z0emORzqdXDv4P0oV+tV3a0OirfA8Ko1JGBIAVvB+hzLvZzCDvnuZx7MTK+Dd8Y9Tjlo446BpCIg==
dependencies:
"@noble/hashes" "^1.4.0"
clsx "^1.2.1"
eventemitter3 "^5.0.1"
preact "^10.24.2"
"@coinbase/wallet-sdk@4.3.0": "@coinbase/wallet-sdk@4.3.0":
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-4.3.0.tgz#03b8fce92ac2b3b7cf132f64d6008ac081569b4e" resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-4.3.0.tgz#03b8fce92ac2b3b7cf132f64d6008ac081569b4e"
...@@ -2241,17 +2199,6 @@ ...@@ -2241,17 +2199,6 @@
ethereum-cryptography "^2.0.0" ethereum-cryptography "^2.0.0"
micro-ftch "^0.3.1" micro-ftch "^0.3.1"
"@ethersproject/address@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
"@ethersproject/bignumber@^5.7.0": "@ethersproject/bignumber@^5.7.0":
version "5.7.0" version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
...@@ -2288,21 +2235,6 @@ ...@@ -2288,21 +2235,6 @@
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892"
integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==
"@ethersproject/properties@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30"
integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==
dependencies:
"@ethersproject/logger" "^5.7.0"
"@ethersproject/rlp@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304"
integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/sha2@^5.7.0": "@ethersproject/sha2@^5.7.0":
version "5.7.0" version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb"
...@@ -2312,18 +2244,6 @@ ...@@ -2312,18 +2244,6 @@
"@ethersproject/logger" "^5.7.0" "@ethersproject/logger" "^5.7.0"
hash.js "1.1.7" hash.js "1.1.7"
"@ethersproject/signing-key@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3"
integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
bn.js "^5.2.1"
elliptic "6.5.4"
hash.js "1.1.7"
"@ethersproject/solidity@^5.7.0": "@ethersproject/solidity@^5.7.0":
version "5.7.0" version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8"
...@@ -2345,21 +2265,6 @@ ...@@ -2345,21 +2265,6 @@
"@ethersproject/constants" "^5.7.0" "@ethersproject/constants" "^5.7.0"
"@ethersproject/logger" "^5.7.0" "@ethersproject/logger" "^5.7.0"
"@ethersproject/transactions@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
dependencies:
"@ethersproject/address" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
"@ethersproject/signing-key" "^5.7.0"
"@fastify/busboy@^2.0.0": "@fastify/busboy@^2.0.0":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8"
...@@ -3575,17 +3480,6 @@ ...@@ -3575,17 +3480,6 @@
resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-3.1.1.tgz#e89b840a7af8097a8ed4953d8dc8470d1302d3ef" resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-3.1.1.tgz#e89b840a7af8097a8ed4953d8dc8470d1302d3ef"
integrity sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw== integrity sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw==
"@metamask/sdk-communication-layer@0.31.0":
version "0.31.0"
resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.31.0.tgz#0acc063b62aa09d044c7aab65801712d760e53b2"
integrity sha512-V9CxdzabDPjQVgmKGHsyU3SYt4Af27g+4DbGCx0fLoHqN/i1RBDZqs/LYbJX3ykJCANzE+llz/MolMCMrzM2RA==
dependencies:
bufferutil "^4.0.8"
date-fns "^2.29.3"
debug "^4.3.4"
utf-8-validate "^5.0.2"
uuid "^8.3.2"
"@metamask/sdk-communication-layer@0.32.0": "@metamask/sdk-communication-layer@0.32.0":
version "0.32.0" version "0.32.0"
resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.32.0.tgz#89710e807806836138ea5018b087731d6acab627" resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.32.0.tgz#89710e807806836138ea5018b087731d6acab627"
...@@ -3597,13 +3491,6 @@ ...@@ -3597,13 +3491,6 @@
utf-8-validate "^5.0.2" utf-8-validate "^5.0.2"
uuid "^8.3.2" uuid "^8.3.2"
"@metamask/sdk-install-modal-web@0.31.2":
version "0.31.2"
resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.31.2.tgz#bb8c92a6844a632be8525e7bb5a35924a926d6cd"
integrity sha512-KPv36kQjmTwErU8g2neuHHSgkD5+1hp4D6ERfk5Kc2r73aOYNCdG9wDGRUmFmcY2MKkeK1EuDyZfJ4FPU30fxQ==
dependencies:
"@paulmillr/qr" "^0.2.1"
"@metamask/sdk-install-modal-web@0.32.0": "@metamask/sdk-install-modal-web@0.32.0":
version "0.32.0" version "0.32.0"
resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.32.0.tgz#86f80420ca364fa0d7710016fa5c81f95537ab23" resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.32.0.tgz#86f80420ca364fa0d7710016fa5c81f95537ab23"
...@@ -3611,31 +3498,6 @@ ...@@ -3611,31 +3498,6 @@
dependencies: dependencies:
"@paulmillr/qr" "^0.2.1" "@paulmillr/qr" "^0.2.1"
"@metamask/sdk@0.31.2":
version "0.31.2"
resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.31.2.tgz#2ec1c1c7cf6a444e65104862e83814a493047d72"
integrity sha512-6MWON2g1j7XwAHWam4trusGxeyhQweNLEHPsfuIxSwcsXoEm08Jj80OglJxQI4KwjcDnjSWBkQGG3mmK6ug/cA==
dependencies:
"@babel/runtime" "^7.26.0"
"@metamask/onboarding" "^1.0.1"
"@metamask/providers" "16.1.0"
"@metamask/sdk-communication-layer" "0.31.0"
"@metamask/sdk-install-modal-web" "0.31.2"
"@paulmillr/qr" "^0.2.1"
bowser "^2.9.0"
cross-fetch "^4.0.0"
debug "^4.3.4"
eciesjs "^0.4.11"
eth-rpc-errors "^4.0.3"
eventemitter2 "^6.4.9"
obj-multiplex "^1.0.0"
pump "^3.0.0"
readable-stream "^3.6.2"
socket.io-client "^4.5.1"
tslib "^2.6.0"
util "^0.12.4"
uuid "^8.3.2"
"@metamask/sdk@0.32.0": "@metamask/sdk@0.32.0":
version "0.32.0" version "0.32.0"
resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.32.0.tgz#f0e179746fe69dccd032a9026884b45b519c1975" resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.32.0.tgz#f0e179746fe69dccd032a9026884b45b519c1975"
...@@ -3922,20 +3784,6 @@ ...@@ -3922,20 +3784,6 @@
dependencies: dependencies:
"@noble/hashes" "1.4.0" "@noble/hashes" "1.4.0"
"@noble/curves@1.6.0", "@noble/curves@^1.4.0", "@noble/curves@^1.6.0", "@noble/curves@~1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.6.0.tgz#be5296ebcd5a1730fccea4786d420f87abfeb40b"
integrity sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==
dependencies:
"@noble/hashes" "1.5.0"
"@noble/curves@1.7.0", "@noble/curves@~1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.7.0.tgz#0512360622439256df892f21d25b388f52505e45"
integrity sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==
dependencies:
"@noble/hashes" "1.6.0"
"@noble/curves@1.8.0": "@noble/curves@1.8.0":
version "1.8.0" version "1.8.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.0.tgz#fe035a23959e6aeadf695851b51a87465b5ba8f7" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.0.tgz#fe035a23959e6aeadf695851b51a87465b5ba8f7"
...@@ -3943,13 +3791,20 @@ ...@@ -3943,13 +3791,20 @@
dependencies: dependencies:
"@noble/hashes" "1.7.0" "@noble/hashes" "1.7.0"
"@noble/curves@1.8.1": "@noble/curves@1.8.1", "@noble/curves@~1.8.1":
version "1.8.1" version "1.8.1"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff"
integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ== integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==
dependencies: dependencies:
"@noble/hashes" "1.7.1" "@noble/hashes" "1.7.1"
"@noble/curves@^1.4.0", "@noble/curves@^1.6.0", "@noble/curves@~1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.6.0.tgz#be5296ebcd5a1730fccea4786d420f87abfeb40b"
integrity sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==
dependencies:
"@noble/hashes" "1.5.0"
"@noble/curves@~1.4.0": "@noble/curves@~1.4.0":
version "1.4.2" version "1.4.2"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9"
...@@ -3977,22 +3832,12 @@ ...@@ -3977,22 +3832,12 @@
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0"
integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==
"@noble/hashes@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.6.0.tgz#d4bfb516ad6e7b5111c216a5cc7075f4cf19e6c5"
integrity sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==
"@noble/hashes@1.6.1", "@noble/hashes@~1.6.0":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.6.1.tgz#df6e5943edcea504bac61395926d6fd67869a0d5"
integrity sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==
"@noble/hashes@1.7.0": "@noble/hashes@1.7.0":
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.0.tgz#5d9e33af2c7d04fee35de1519b80c958b2e35e39" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.0.tgz#5d9e33af2c7d04fee35de1519b80c958b2e35e39"
integrity sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w== integrity sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==
"@noble/hashes@1.7.1": "@noble/hashes@1.7.1", "@noble/hashes@~1.7.1":
version "1.7.1" version "1.7.1"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f"
integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==
...@@ -5130,119 +4975,116 @@ ...@@ -5130,119 +4975,116 @@
prop-types "^15.7.2" prop-types "^15.7.2"
tslib "^2.3.0" tslib "^2.3.0"
"@reown/appkit-adapter-wagmi@1.6.7": "@reown/appkit-adapter-wagmi@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-adapter-wagmi/-/appkit-adapter-wagmi-1.6.7.tgz#dbb6cb7b1d9d0ab338487147d3985a001db702bb" resolved "https://registry.yarnpkg.com/@reown/appkit-adapter-wagmi/-/appkit-adapter-wagmi-1.7.0.tgz#62d31fdb801b3a1f78fa75e6863464d8b925a8d5"
integrity sha512-CS6X0OE4hfZJ6K5wpHGxCFqS7dAWnS7SSg6LsBFFtGJTflIAxL6oY84SVSvKByAigQUwGHd5DTvGPQKaFunPQA== integrity sha512-5xkwFQCu8Ezb2J3nnVv8fLjEoBjADggBrxYmOwPDzT6D5heWtkRC/HYx2STiy+vsbj0G8Vs/x+SXq753CR94/Q==
dependencies: dependencies:
"@reown/appkit" "1.6.7" "@reown/appkit" "1.7.0"
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-core" "1.6.7" "@reown/appkit-controllers" "1.7.0"
"@reown/appkit-polyfills" "1.6.7" "@reown/appkit-polyfills" "1.7.0"
"@reown/appkit-scaffold-ui" "1.6.7" "@reown/appkit-scaffold-ui" "1.7.0"
"@reown/appkit-ui" "1.6.7" "@reown/appkit-utils" "1.7.0"
"@reown/appkit-utils" "1.6.7" "@reown/appkit-wallet" "1.7.0"
"@reown/appkit-wallet" "1.6.7" "@walletconnect/universal-provider" "2.19.1"
"@walletconnect/universal-provider" "2.18.0"
"@walletconnect/utils" "2.18.0"
valtio "1.13.2" valtio "1.13.2"
optionalDependencies: optionalDependencies:
"@wagmi/connectors" ">=5.7" "@wagmi/connectors" ">=5.7"
"@reown/appkit-common@1.6.7": "@reown/appkit-common@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-common/-/appkit-common-1.6.7.tgz#34d4df120a8d6b714b315931ca7f4db94606ba27" resolved "https://registry.yarnpkg.com/@reown/appkit-common/-/appkit-common-1.7.0.tgz#484b14bc18efa9c79334c66ecc24453d73c93dd5"
integrity sha512-gfJOC8mkauNz2Lu3bjLmvKLAKsSaHCv4OKUZF62s70Y0otj8RC+qhU+6XCmsb56C0sJAIG0Unb8/Ky3ICpGLEQ== integrity sha512-yJc5lQLt64+ZjhagqZar/H9S9EDKiZa9z/4mII4ZTpRiOfSlKvRS+tLcjiqJNr+dTft4nVbF71sbnVLZ/ON2UQ==
dependencies: dependencies:
big.js "6.2.2" big.js "6.2.2"
dayjs "1.11.10" dayjs "1.11.13"
viem "2.x" viem ">=2.23.5"
"@reown/appkit-core@1.6.7": "@reown/appkit-controllers@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-core/-/appkit-core-1.6.7.tgz#17f6c071b5a0dfaa2e37fe834de1c36803c570fb" resolved "https://registry.yarnpkg.com/@reown/appkit-controllers/-/appkit-controllers-1.7.0.tgz#ad9c085aea4e7610878fb37d33cdc0fa81a5b888"
integrity sha512-kws78pLqEGmlHy56UuCJc8WMeeRySLhy+5klo56Kpykp+L5pvZdH5moE0oNqk6ysGWmWpTW1T3Yskoo1bKI8ng== integrity sha512-npFnrPQdm4t5YT+ai+525sQRnZdAQjGMKQ11hYBKifAZafx8xr7yObvyxeR9d6aM0ku+OSFHErbALKM9iJFtXw==
dependencies: dependencies:
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-wallet" "1.6.7" "@reown/appkit-wallet" "1.7.0"
"@walletconnect/universal-provider" "2.18.0" "@walletconnect/universal-provider" "2.19.1"
valtio "1.13.2" valtio "1.13.2"
viem "2.x" viem ">=2.23.5"
"@reown/appkit-polyfills@1.6.7": "@reown/appkit-polyfills@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-polyfills/-/appkit-polyfills-1.6.7.tgz#850c9da80983a0c3a30856f61d993043b5637a02" resolved "https://registry.yarnpkg.com/@reown/appkit-polyfills/-/appkit-polyfills-1.7.0.tgz#effd8a85979480cc33a4e1bc2dee1dc77bb3b9ad"
integrity sha512-SnO+K3+BTJwjIKee+RbGSmP+uwnMEVCS3njzQ8IXP4YrRERgPS1naxmfj3NqxlomtZD0zUeylIA3VTkMcTCgYg== integrity sha512-j7pHuOvnaXUJmd+Hj2WYkBDxar3LM71Z/FY8Qr8OaQsb+e6U9ho033npYXHEAkfjTv4mB/B0Y7yTKAJhxV9Lpg==
dependencies: dependencies:
buffer "6.0.3" buffer "6.0.3"
"@reown/appkit-scaffold-ui@1.6.7": "@reown/appkit-scaffold-ui@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-scaffold-ui/-/appkit-scaffold-ui-1.6.7.tgz#8ce8451edf4ce6f483a21901b1125adea8b21f64" resolved "https://registry.yarnpkg.com/@reown/appkit-scaffold-ui/-/appkit-scaffold-ui-1.7.0.tgz#415081d3973fdf55ff806b5e3e03b5b89a83a47e"
integrity sha512-5C94XJkp0VCR4xKtnNRB2TLfgWKuCDinLCnIajCSoL5MdZiiyVVsF5+Y2XH1SgCpw0G8MF1NPoEC3N1SMJmWrw== integrity sha512-BNlN01gOpcqf4w5iYLz10FN574cZqhwobHSKKSgthTb2DBZpaSeIK2K+97ku2uGb8o00m+9aFyKaRDOU3XpNNQ==
dependencies: dependencies:
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-core" "1.6.7" "@reown/appkit-controllers" "1.7.0"
"@reown/appkit-ui" "1.6.7" "@reown/appkit-ui" "1.7.0"
"@reown/appkit-utils" "1.6.7" "@reown/appkit-utils" "1.7.0"
"@reown/appkit-wallet" "1.6.7" "@reown/appkit-wallet" "1.7.0"
lit "3.1.0" lit "3.1.0"
"@reown/appkit-ui@1.6.7": "@reown/appkit-ui@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-ui/-/appkit-ui-1.6.7.tgz#8190af457d59dd4e42502149af4882310ec0120b" resolved "https://registry.yarnpkg.com/@reown/appkit-ui/-/appkit-ui-1.7.0.tgz#78328e98635e1c9bf78b22d40f4bff1fa238aca0"
integrity sha512-Y9lKaATDBtACkST2Vl19h24qK611WpAv+dkVuoHI8BIEVJtp+44YD6mrVOJWovKsdrbt/WrmObY7mS+17cywZQ== integrity sha512-a2sCBE3Me9dbsqW0544S/3FIoJh/RER4ZhU4e7I2rfskdTX6W5Orw/vm9wK2ItesVDD0SB3WpyQ3F/4bCkJt/w==
dependencies: dependencies:
lit "3.1.0" lit "3.1.0"
qrcode "1.5.3" qrcode "1.5.3"
"@reown/appkit-utils@1.6.7": "@reown/appkit-utils@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-utils/-/appkit-utils-1.6.7.tgz#8b7779eb9bc65579b647a102c7ef40317397f3b2" resolved "https://registry.yarnpkg.com/@reown/appkit-utils/-/appkit-utils-1.7.0.tgz#346b31e936cf2b0a5156744a51427bd81d533f2a"
integrity sha512-zSDF8VhfMEFx/UCZB6vHHTD7QDO5gsixq86/JqqUinOQWumuBkmbzGoK0YqyNvAN9O/pGoPhQ/eJp3pY9PAADA== integrity sha512-D88Lzms0RFgocBrJmeUB7jHG+ZlU2hDQgwjTHvXW+UlMdH1fUb2btPLYyt2dqI0X3ubAcPsQPmpH458G7sUKPA==
dependencies: dependencies:
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-core" "1.6.7" "@reown/appkit-controllers" "1.7.0"
"@reown/appkit-polyfills" "1.6.7" "@reown/appkit-polyfills" "1.7.0"
"@reown/appkit-wallet" "1.6.7" "@reown/appkit-wallet" "1.7.0"
"@walletconnect/logger" "2.1.2" "@walletconnect/logger" "2.1.2"
"@walletconnect/universal-provider" "2.18.0" "@walletconnect/universal-provider" "2.19.1"
valtio "1.13.2" valtio "1.13.2"
viem "2.x" viem ">=2.23.5"
"@reown/appkit-wallet@1.6.7": "@reown/appkit-wallet@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit-wallet/-/appkit-wallet-1.6.7.tgz#236830d91f4d3b2863c0d8f0cda541c50de2de11" resolved "https://registry.yarnpkg.com/@reown/appkit-wallet/-/appkit-wallet-1.7.0.tgz#4789756b91aaea2e8aff3f4cb26284a0f1a01b6d"
integrity sha512-QCn1KQzkF50Qr6ZpbK4RwTLDjZwmlqNd/OvHMboPW+su904aakPyQP2OTaTtrs2bqeWQ3OktF2oBkI9IwbIb5g== integrity sha512-hXrPe5ZYbxAwyytdBcWT504lJ+L8ckXDcSGZg62nk+7sck3jqpXmwn24mI4eS/ThTj3ExxlOG4bcGiXu1EBFwQ==
dependencies: dependencies:
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-polyfills" "1.6.7" "@reown/appkit-polyfills" "1.7.0"
"@walletconnect/logger" "2.1.2" "@walletconnect/logger" "2.1.2"
zod "3.22.4" zod "3.22.4"
"@reown/appkit@1.6.7": "@reown/appkit@1.7.0":
version "1.6.7" version "1.7.0"
resolved "https://registry.yarnpkg.com/@reown/appkit/-/appkit-1.6.7.tgz#fefa0dd384b9c3fee3af97c41fdf01f83ef93e2c" resolved "https://registry.yarnpkg.com/@reown/appkit/-/appkit-1.7.0.tgz#8443199d2f030555317e4da94b1f86a80b361718"
integrity sha512-Vy6MJvZZcwkBDzwpcU24KIeoA/DFOzRLYUp4Az/sVmpUTpjATjY1OaVK1OkSg/pIs7MsU1BUw+JJdkXU6vbBjw== integrity sha512-/F+By2dfoXJNuAdq/atRM1wt5PlWjUSpIQnk4j3rIFxmch0XJnw6YZzdMaDH0dNfzP2+ymUFsN7CFt7Se4QgoA==
dependencies: dependencies:
"@reown/appkit-common" "1.6.7" "@reown/appkit-common" "1.7.0"
"@reown/appkit-core" "1.6.7" "@reown/appkit-controllers" "1.7.0"
"@reown/appkit-polyfills" "1.6.7" "@reown/appkit-polyfills" "1.7.0"
"@reown/appkit-scaffold-ui" "1.6.7" "@reown/appkit-scaffold-ui" "1.7.0"
"@reown/appkit-ui" "1.6.7" "@reown/appkit-ui" "1.7.0"
"@reown/appkit-utils" "1.6.7" "@reown/appkit-utils" "1.7.0"
"@reown/appkit-wallet" "1.6.7" "@reown/appkit-wallet" "1.7.0"
"@walletconnect/types" "2.18.0" "@walletconnect/types" "2.19.1"
"@walletconnect/universal-provider" "2.18.0" "@walletconnect/universal-provider" "2.19.1"
"@walletconnect/utils" "2.18.0"
bs58 "6.0.0" bs58 "6.0.0"
valtio "1.13.2" valtio "1.13.2"
viem "2.x" viem ">=2.23.5"
"@rollbar/react@0.12.0-beta": "@rollbar/react@0.12.1":
version "0.12.0-beta" version "0.12.1"
resolved "https://registry.yarnpkg.com/@rollbar/react/-/react-0.12.0-beta.tgz#b80dfab1535ece358a0e98a4f26aadee8b54edda" resolved "https://registry.yarnpkg.com/@rollbar/react/-/react-0.12.1.tgz#2c8ac9a06b1f6ba75d67346f55fee3c120100865"
integrity sha512-8udBX0lJwdBBq+O/jqDXpg/giHt8bo/Us1IlTkHEdCBO18Cjj7sxWJ80OPFxiPRNwZgZnhf2HbxQxvLN+4FeJA== integrity sha512-qi1ahC4WRXTrqh7hkBM0H5cSKh4TBA5A9jKliokphxikmZsAfbQEvwjIM6IFkqEljeWt1nAfuuFC5w32sLqoTg==
dependencies: dependencies:
tiny-invariant "^1.1.0" tiny-invariant "^1.1.0"
...@@ -5345,14 +5187,6 @@ ...@@ -5345,14 +5187,6 @@
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1"
integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA== integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==
"@safe-global/safe-apps-provider@0.18.4":
version "0.18.4"
resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.4.tgz#53df912aa20d933f6b14c5bcb0737a8cd47def57"
integrity sha512-SWYeG3gyTO6wGHMSokfHakZ9isByn2mHsM0VohIorYFFEyGGmJ89btnTm+DqDUSoQtvWAatZB7XNy6CaYMvqtg==
dependencies:
"@safe-global/safe-apps-sdk" "^9.1.0"
events "^3.3.0"
"@safe-global/safe-apps-provider@0.18.5": "@safe-global/safe-apps-provider@0.18.5":
version "0.18.5" version "0.18.5"
resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.5.tgz#745a932bda3739a8a298ae44ec6c465f6c4773b7" resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.5.tgz#745a932bda3739a8a298ae44ec6c465f6c4773b7"
...@@ -5396,10 +5230,10 @@ ...@@ -5396,10 +5230,10 @@
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.8.tgz#8f23646c352f020c83bca750a82789e246d42b50" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.8.tgz#8f23646c352f020c83bca750a82789e246d42b50"
integrity sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg== integrity sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg==
"@scure/base@~1.2.1": "@scure/base@~1.2.2", "@scure/base@~1.2.4":
version "1.2.1" version "1.2.4"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.1.tgz#dd0b2a533063ca612c17aa9ad26424a2ff5aa865" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.4.tgz#002eb571a35d69bdb4c214d0995dff76a8dcd2a9"
integrity sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ== integrity sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==
"@scure/bip32@1.3.1": "@scure/bip32@1.3.1":
version "1.3.1" version "1.3.1"
...@@ -5428,7 +5262,16 @@ ...@@ -5428,7 +5262,16 @@
"@noble/hashes" "~1.4.0" "@noble/hashes" "~1.4.0"
"@scure/base" "~1.1.6" "@scure/base" "~1.1.6"
"@scure/bip32@1.5.0", "@scure/bip32@^1.5.0": "@scure/bip32@1.6.2":
version "1.6.2"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.6.2.tgz#093caa94961619927659ed0e711a6e4bf35bffd0"
integrity sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==
dependencies:
"@noble/curves" "~1.8.1"
"@noble/hashes" "~1.7.1"
"@scure/base" "~1.2.2"
"@scure/bip32@^1.5.0":
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.5.0.tgz#dd4a2e1b8a9da60e012e776d954c4186db6328e6" resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.5.0.tgz#dd4a2e1b8a9da60e012e776d954c4186db6328e6"
integrity sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw== integrity sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==
...@@ -5437,15 +5280,6 @@ ...@@ -5437,15 +5280,6 @@
"@noble/hashes" "~1.5.0" "@noble/hashes" "~1.5.0"
"@scure/base" "~1.1.7" "@scure/base" "~1.1.7"
"@scure/bip32@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.6.0.tgz#6dbc6b4af7c9101b351f41231a879d8da47e0891"
integrity sha512-82q1QfklrUUdXJzjuRU7iG7D7XiFx5PHYVS0+oeNKhyDLT7WPqs6pBcM2W5ZdwOwKCwoE1Vy1se+DHjcXwCYnA==
dependencies:
"@noble/curves" "~1.7.0"
"@noble/hashes" "~1.6.0"
"@scure/base" "~1.2.1"
"@scure/bip39@1.2.1": "@scure/bip39@1.2.1":
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a"
...@@ -5462,13 +5296,13 @@ ...@@ -5462,13 +5296,13 @@
"@noble/hashes" "~1.5.0" "@noble/hashes" "~1.5.0"
"@scure/base" "~1.1.8" "@scure/base" "~1.1.8"
"@scure/bip39@1.5.0": "@scure/bip39@1.5.4":
version "1.5.0" version "1.5.4"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.5.0.tgz#c8f9533dbd787641b047984356531d84485f19be" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.5.4.tgz#07fd920423aa671be4540d59bdd344cc1461db51"
integrity sha512-Dop+ASYhnrwm9+HA/HwXg7j2ZqM6yk2fyLWb5znexjctFY3+E+eU8cIWI0Pql0Qx4hPZCijlGq4OL71g+Uz30A== integrity sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==
dependencies: dependencies:
"@noble/hashes" "~1.6.0" "@noble/hashes" "~1.7.1"
"@scure/base" "~1.2.1" "@scure/base" "~1.2.4"
"@sideway/address@^4.1.3": "@sideway/address@^4.1.3":
version "4.1.4" version "4.1.4"
...@@ -7241,16 +7075,16 @@ ...@@ -7241,16 +7075,16 @@
"@types/babel__core" "^7.20.5" "@types/babel__core" "^7.20.5"
react-refresh "^0.14.2" react-refresh "^0.14.2"
"@wagmi/connectors@5.6.0": "@wagmi/connectors@5.7.11":
version "5.6.0" version "5.7.11"
resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-5.6.0.tgz#5c9f3aae2eb423efb4e3fbc471e0cf259cb2e7e3" resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-5.7.11.tgz#bcd98c9378366f5eea728760c232e5460938ac19"
integrity sha512-yFVzJ0k/tj/QFvoBkU3phYPE3FhpdaSwWPruYBgCANGoL2bV9pDoeOIVvHRTJraldGw4X6I2zvIVZtSapKHaUw== integrity sha512-vJWOXMeYWmczvlsEZHq52yOoC2qu5kU8Saj6Bo+BtyfYcX1tJODZTKed3TMIoKhUx0W3vna1UIwG7GskmxGKKA==
dependencies: dependencies:
"@coinbase/wallet-sdk" "4.2.3" "@coinbase/wallet-sdk" "4.3.0"
"@metamask/sdk" "0.31.2" "@metamask/sdk" "0.32.0"
"@safe-global/safe-apps-provider" "0.18.4" "@safe-global/safe-apps-provider" "0.18.5"
"@safe-global/safe-apps-sdk" "9.1.0" "@safe-global/safe-apps-sdk" "9.1.0"
"@walletconnect/ethereum-provider" "2.17.0" "@walletconnect/ethereum-provider" "2.19.1"
cbw-sdk "npm:@coinbase/wallet-sdk@3.9.3" cbw-sdk "npm:@coinbase/wallet-sdk@3.9.3"
"@wagmi/connectors@>=5.7": "@wagmi/connectors@>=5.7":
...@@ -7265,10 +7099,10 @@ ...@@ -7265,10 +7099,10 @@
"@walletconnect/ethereum-provider" "2.17.0" "@walletconnect/ethereum-provider" "2.17.0"
cbw-sdk "npm:@coinbase/wallet-sdk@3.9.3" cbw-sdk "npm:@coinbase/wallet-sdk@3.9.3"
"@wagmi/core@2.16.0": "@wagmi/core@2.16.7":
version "2.16.0" version "2.16.7"
resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-2.16.0.tgz#b997b2544cd80b4aac4df25ccb2436bf77f9fbe1" resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-2.16.7.tgz#9ca06583c7a546b25d86ec7ee4d4d1376b1ee6e2"
integrity sha512-sy4n7Jv6YCbT2jp4zQ/9H6l0A8StsN7P8mm2BRuODgW2w6Fj4j6h2xgYJD2tIjJHkLU/nvPJ7audZ55X7XQU/g== integrity sha512-Kpgrw6OXV0VBhDs4toQVKQ0NK5yUO6uxEqnvRGjNjbO85d93Gbfsp5BlxSLeWq6iVMSBFSitdl5i9W7b1miq1g==
dependencies: dependencies:
eventemitter3 "5.0.1" eventemitter3 "5.0.1"
mipd "0.0.7" mipd "0.0.7"
...@@ -7296,10 +7130,10 @@ ...@@ -7296,10 +7130,10 @@
lodash.isequal "4.5.0" lodash.isequal "4.5.0"
uint8arrays "3.1.0" uint8arrays "3.1.0"
"@walletconnect/core@2.18.0": "@walletconnect/core@2.19.1":
version "2.18.0" version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.18.0.tgz#749b57000823eceb1c667d38531e7eae206df349" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.19.1.tgz#71738940341b438326b65b3f49226decbe070bae"
integrity sha512-i/olu/IwYtBiWYqyfNUMxq4b6QS5dv+ZVVGmLT2buRwdH6MGETN0Bx3/z6rXJzd1sNd+QL07fxhSFxCekL57tA== integrity sha512-rMvpZS0tQXR/ivzOxN1GkHvw3jRRMlI/jRX5g7ZteLgg2L0ZcANsFvAU5IxILxIKcIkTCloF9TcfloKVbK3qmw==
dependencies: dependencies:
"@walletconnect/heartbeat" "1.2.2" "@walletconnect/heartbeat" "1.2.2"
"@walletconnect/jsonrpc-provider" "1.0.14" "@walletconnect/jsonrpc-provider" "1.0.14"
...@@ -7312,11 +7146,11 @@ ...@@ -7312,11 +7146,11 @@
"@walletconnect/relay-auth" "1.1.0" "@walletconnect/relay-auth" "1.1.0"
"@walletconnect/safe-json" "1.0.2" "@walletconnect/safe-json" "1.0.2"
"@walletconnect/time" "1.0.2" "@walletconnect/time" "1.0.2"
"@walletconnect/types" "2.18.0" "@walletconnect/types" "2.19.1"
"@walletconnect/utils" "2.18.0" "@walletconnect/utils" "2.19.1"
"@walletconnect/window-getters" "1.0.1" "@walletconnect/window-getters" "1.0.1"
es-toolkit "1.33.0"
events "3.3.0" events "3.3.0"
lodash.isequal "4.5.0"
uint8arrays "3.1.0" uint8arrays "3.1.0"
"@walletconnect/environment@^1.0.1": "@walletconnect/environment@^1.0.1":
...@@ -7342,6 +7176,23 @@ ...@@ -7342,6 +7176,23 @@
"@walletconnect/utils" "2.17.0" "@walletconnect/utils" "2.17.0"
events "3.3.0" events "3.3.0"
"@walletconnect/ethereum-provider@2.19.1":
version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.19.1.tgz#1618d6bc98aad839e682940f451d1e9a2b2e46d0"
integrity sha512-bs8Kiwdw3cGb8ITO8+YymesGfFnucJreQmVbZ0vl/Ogoh38n1T5w0ekjmD/NjTDS3oZaUQyBm3V2UjIBR0qedw==
dependencies:
"@walletconnect/jsonrpc-http-connection" "1.0.8"
"@walletconnect/jsonrpc-provider" "1.0.14"
"@walletconnect/jsonrpc-types" "1.0.4"
"@walletconnect/jsonrpc-utils" "1.0.8"
"@walletconnect/keyvaluestorage" "1.1.1"
"@walletconnect/modal" "2.7.0"
"@walletconnect/sign-client" "2.19.1"
"@walletconnect/types" "2.19.1"
"@walletconnect/universal-provider" "2.19.1"
"@walletconnect/utils" "2.19.1"
events "3.3.0"
"@walletconnect/events@1.0.1", "@walletconnect/events@^1.0.1": "@walletconnect/events@1.0.1", "@walletconnect/events@^1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c"
...@@ -7532,19 +7383,19 @@ ...@@ -7532,19 +7383,19 @@
"@walletconnect/utils" "2.17.0" "@walletconnect/utils" "2.17.0"
events "3.3.0" events "3.3.0"
"@walletconnect/sign-client@2.18.0": "@walletconnect/sign-client@2.19.1":
version "2.18.0" version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.18.0.tgz#33480ee3e711d31c947860125ac26cf31bb9bcb5" resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.19.1.tgz#6cfbb4ee0eaf3a8774a8c70ff65ba23177e8f388"
integrity sha512-oUjlRIsbHxMSRif2WvMRdvm6tMsQjMj07rl7YVcKVvZ1gF1/9GcbJPjzL/U87fv8qAQkVhIlbEg2vHaVYf6J/g== integrity sha512-OgBHRPo423S02ceN3lAzcZ3MYb1XuLyTTkKqLmKp/icYZCyRzm3/ynqJDKndiBLJ5LTic0y07LiZilnliYqlvw==
dependencies: dependencies:
"@walletconnect/core" "2.18.0" "@walletconnect/core" "2.19.1"
"@walletconnect/events" "1.0.1" "@walletconnect/events" "1.0.1"
"@walletconnect/heartbeat" "1.2.2" "@walletconnect/heartbeat" "1.2.2"
"@walletconnect/jsonrpc-utils" "1.0.8" "@walletconnect/jsonrpc-utils" "1.0.8"
"@walletconnect/logger" "2.1.2" "@walletconnect/logger" "2.1.2"
"@walletconnect/time" "1.0.2" "@walletconnect/time" "1.0.2"
"@walletconnect/types" "2.18.0" "@walletconnect/types" "2.19.1"
"@walletconnect/utils" "2.18.0" "@walletconnect/utils" "2.19.1"
events "3.3.0" events "3.3.0"
"@walletconnect/time@1.0.2", "@walletconnect/time@^1.0.2": "@walletconnect/time@1.0.2", "@walletconnect/time@^1.0.2":
...@@ -7566,10 +7417,10 @@ ...@@ -7566,10 +7417,10 @@
"@walletconnect/logger" "2.1.2" "@walletconnect/logger" "2.1.2"
events "3.3.0" events "3.3.0"
"@walletconnect/types@2.18.0": "@walletconnect/types@2.19.1":
version "2.18.0" version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.18.0.tgz#dda74a0aeb5a4790a860a1d8eba439f19a07cb54" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.19.1.tgz#ec78c5a05238e220871cca3e360193584af2d968"
integrity sha512-g0jU+6LUuw3E/EPAQfHNK2xK/95IpRfz68tdNAFckLmefZU6kzoE1mIM1SrPJq8rT9kUPp6/APMQE+ReH2OdBA== integrity sha512-XWWGLioddH7MjxhyGhylL7VVariVON2XatJq/hy0kSGJ1hdp31z194nHN5ly9M495J9Hw8lcYjGXpsgeKvgxzw==
dependencies: dependencies:
"@walletconnect/events" "1.0.1" "@walletconnect/events" "1.0.1"
"@walletconnect/heartbeat" "1.2.2" "@walletconnect/heartbeat" "1.2.2"
...@@ -7593,10 +7444,10 @@ ...@@ -7593,10 +7444,10 @@
"@walletconnect/utils" "2.17.0" "@walletconnect/utils" "2.17.0"
events "3.3.0" events "3.3.0"
"@walletconnect/universal-provider@2.18.0": "@walletconnect/universal-provider@2.19.1":
version "2.18.0" version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.18.0.tgz#0c8cde53cada6491e516233589d084a6aa4b0cd5" resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.19.1.tgz#9908431b766fffcb0f617f3fdb7e85f27f05f9de"
integrity sha512-zF/e1NAipLqYjNNgM+XZTchh94efaxciBmgcDOaLznS97R7S/1bYj5okQCAEDKx9RALhEKqZKoyo9jwn4p3BVA== integrity sha512-4rdLvJ2TGDIieNWW3sZw2MXlX65iHpTuKb5vyvUHQtjIVNLj+7X/09iUAI/poswhtspBK0ytwbH+AIT/nbGpjg==
dependencies: dependencies:
"@walletconnect/events" "1.0.1" "@walletconnect/events" "1.0.1"
"@walletconnect/jsonrpc-http-connection" "1.0.8" "@walletconnect/jsonrpc-http-connection" "1.0.8"
...@@ -7605,11 +7456,11 @@ ...@@ -7605,11 +7456,11 @@
"@walletconnect/jsonrpc-utils" "1.0.8" "@walletconnect/jsonrpc-utils" "1.0.8"
"@walletconnect/keyvaluestorage" "1.1.1" "@walletconnect/keyvaluestorage" "1.1.1"
"@walletconnect/logger" "2.1.2" "@walletconnect/logger" "2.1.2"
"@walletconnect/sign-client" "2.18.0" "@walletconnect/sign-client" "2.19.1"
"@walletconnect/types" "2.18.0" "@walletconnect/types" "2.19.1"
"@walletconnect/utils" "2.18.0" "@walletconnect/utils" "2.19.1"
es-toolkit "1.33.0"
events "3.3.0" events "3.3.0"
lodash "4.17.21"
"@walletconnect/utils@2.17.0": "@walletconnect/utils@2.17.0":
version "2.17.0" version "2.17.0"
...@@ -7633,12 +7484,11 @@ ...@@ -7633,12 +7484,11 @@
query-string "7.1.3" query-string "7.1.3"
uint8arrays "3.1.0" uint8arrays "3.1.0"
"@walletconnect/utils@2.18.0": "@walletconnect/utils@2.19.1":
version "2.18.0" version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.18.0.tgz#1caa15eb6704dcfce03b58d96d44a58ef7b103ec" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.19.1.tgz#16cbc173cd3b28cbf86ca5c6e362057810da07f9"
integrity sha512-6AUXIcjSxTHGRsTtmUP/oqudtwRILrQqrJsH3jS5T28FFDzZt7+On6fR4mXzi64k4nNYeWg1wMCGLEdtxmGbZQ== integrity sha512-aOwcg+Hpph8niJSXLqkU25pmLR49B8ECXp5gFQDW5IeVgXHoOoK7w8a79GBhIBheMLlIt1322sTKQ7Rq5KzzFg==
dependencies: dependencies:
"@ethersproject/transactions" "5.7.0"
"@noble/ciphers" "1.2.1" "@noble/ciphers" "1.2.1"
"@noble/curves" "1.8.1" "@noble/curves" "1.8.1"
"@noble/hashes" "1.7.1" "@noble/hashes" "1.7.1"
...@@ -7648,13 +7498,15 @@ ...@@ -7648,13 +7498,15 @@
"@walletconnect/relay-auth" "1.1.0" "@walletconnect/relay-auth" "1.1.0"
"@walletconnect/safe-json" "1.0.2" "@walletconnect/safe-json" "1.0.2"
"@walletconnect/time" "1.0.2" "@walletconnect/time" "1.0.2"
"@walletconnect/types" "2.18.0" "@walletconnect/types" "2.19.1"
"@walletconnect/window-getters" "1.0.1" "@walletconnect/window-getters" "1.0.1"
"@walletconnect/window-metadata" "1.0.1" "@walletconnect/window-metadata" "1.0.1"
bs58 "6.0.0"
detect-browser "5.3.0" detect-browser "5.3.0"
elliptic "6.6.1" elliptic "6.6.1"
query-string "7.1.3" query-string "7.1.3"
uint8arrays "3.1.0" uint8arrays "3.1.0"
viem "2.23.2"
"@walletconnect/window-getters@1.0.1", "@walletconnect/window-getters@^1.0.1": "@walletconnect/window-getters@1.0.1", "@walletconnect/window-getters@^1.0.1":
version "1.0.1" version "1.0.1"
...@@ -8352,16 +8204,16 @@ abitype@1.0.5: ...@@ -8352,16 +8204,16 @@ abitype@1.0.5:
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6" resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6"
integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw== integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==
abitype@1.0.6, abitype@^1.0.6: abitype@1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.8.tgz#3554f28b2e9d6e9f35eb59878193eabd1b9f46ba"
integrity sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==
abitype@^1.0.6:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.6.tgz#76410903e1d88e34f1362746e2d407513c38565b" resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.6.tgz#76410903e1d88e34f1362746e2d407513c38565b"
integrity sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A== integrity sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==
abitype@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.7.tgz#876a0005d211e1c9132825d45bcee7b46416b284"
integrity sha512-ZfYYSktDQUwc2eduYu8C4wOs+RDPmnRYMh7zNfzeMtGGgb0U+6tLGjixUic6mXf5xKKCcgT5Qp6cv39tOARVFw==
abort-controller@^3.0.0: abort-controller@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
...@@ -8789,9 +8641,9 @@ axe-core@^4.10.0: ...@@ -8789,9 +8641,9 @@ axe-core@^4.10.0:
integrity sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w== integrity sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==
axios@^1.4.0, axios@^1.6.2: axios@^1.4.0, axios@^1.6.2:
version "1.7.7" version "1.8.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== integrity "sha1-eJkLtLxj0srgcpUtN0g1lQqC9Ec= sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw=="
dependencies: dependencies:
follow-redirects "^1.15.6" follow-redirects "^1.15.6"
form-data "^4.0.0" form-data "^4.0.0"
...@@ -9550,11 +9402,6 @@ core-js-compat@^3.25.1: ...@@ -9550,11 +9402,6 @@ core-js-compat@^3.25.1:
dependencies: dependencies:
browserslist "^4.21.4" browserslist "^4.21.4"
core-js-pure@^3.25.1:
version "3.30.1"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.30.1.tgz#7d93dc89e7d47b8ef05d7e79f507b0e99ea77eec"
integrity sha512-nXBEVpmUnNRhz83cHd9JRQC52cTMcuXAmR56+9dSMpRdpeA4I1PX6yjmhd71Eyc/wXNsdBdUDIj1QTIeZpU5Tg==
core-js-pure@^3.30.2: core-js-pure@^3.30.2:
version "3.31.0" version "3.31.0"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.31.0.tgz#052fd9e82fbaaf86457f5db1fadcd06f15966ff2" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.31.0.tgz#052fd9e82fbaaf86457f5db1fadcd06f15966ff2"
...@@ -10079,10 +9926,10 @@ dateformat@^4.6.3: ...@@ -10079,10 +9926,10 @@ dateformat@^4.6.3:
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5"
integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==
dayjs@1.11.10: dayjs@1.11.13:
version "1.11.10" version "1.11.13"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
dayjs@^1.11.5: dayjs@^1.11.5:
version "1.11.5" version "1.11.5"
...@@ -10479,19 +10326,6 @@ electron-to-chromium@^1.5.28: ...@@ -10479,19 +10326,6 @@ electron-to-chromium@^1.5.28:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz#aee074e202c6ee8a0030a9c2ef0b3fe9f967d576" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz#aee074e202c6ee8a0030a9c2ef0b3fe9f967d576"
integrity sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw== integrity sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw==
elliptic@6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
dependencies:
bn.js "^4.11.9"
brorand "^1.1.0"
hash.js "^1.0.0"
hmac-drbg "^1.0.1"
inherits "^2.0.4"
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
elliptic@6.6.1, elliptic@^6.5.7: elliptic@6.6.1, elliptic@^6.5.7:
version "6.6.1" version "6.6.1"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06"
...@@ -10826,6 +10660,11 @@ es-toolkit@1.31.0: ...@@ -10826,6 +10660,11 @@ es-toolkit@1.31.0:
resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.31.0.tgz#f4fc1382aea09cb239afa38f3c724a5658ff3163" resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.31.0.tgz#f4fc1382aea09cb239afa38f3c724a5658ff3163"
integrity sha512-vwS0lv/tzjM2/t4aZZRAgN9I9TP0MSkWuvt6By+hEXfG/uLs8yg2S1/ayRXH/x3pinbLgVJYT+eppueg3cM6tg== integrity sha512-vwS0lv/tzjM2/t4aZZRAgN9I9TP0MSkWuvt6By+hEXfG/uLs8yg2S1/ayRXH/x3pinbLgVJYT+eppueg3cM6tg==
es-toolkit@1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.33.0.tgz#bcc9d92ef2e1ed4618c00dd30dfda9faddf4a0b7"
integrity sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==
esbuild@^0.20.0: esbuild@^0.20.0:
version "0.20.2" version "0.20.2"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1"
...@@ -14039,7 +13878,7 @@ lodash.throttle@^4.1.1: ...@@ -14039,7 +13878,7 @@ lodash.throttle@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
lodash@4.17.21, lodash@^4.15.0, lodash@^4.17.21: lodash@^4.15.0, lodash@^4.17.21:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
...@@ -14892,10 +14731,23 @@ os-tmpdir@~1.0.2: ...@@ -14892,10 +14731,23 @@ os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
ox@0.1.2: ox@0.6.7:
version "0.1.2" version "0.6.7"
resolved "https://registry.yarnpkg.com/ox/-/ox-0.1.2.tgz#0f791be2ccabeaf4928e6d423498fe1c8094e560" resolved "https://registry.yarnpkg.com/ox/-/ox-0.6.7.tgz#afd53f2ecef68b8526660e9d29dee6e6b599a832"
integrity sha512-ak/8K0Rtphg9vnRJlbOdaX9R7cmxD2MiSthjWGaQdMk3D7hrAlDoM+6Lxn7hN52Za3vrXfZ7enfke/5WjolDww== integrity sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==
dependencies:
"@adraffy/ens-normalize" "^1.10.1"
"@noble/curves" "^1.6.0"
"@noble/hashes" "^1.5.0"
"@scure/bip32" "^1.5.0"
"@scure/bip39" "^1.4.0"
abitype "^1.0.6"
eventemitter3 "5.0.1"
ox@0.6.9:
version "0.6.9"
resolved "https://registry.yarnpkg.com/ox/-/ox-0.6.9.tgz#da1ee04fa10de30c8d04c15bfb80fe58b1f554bd"
integrity sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==
dependencies: dependencies:
"@adraffy/ens-normalize" "^1.10.1" "@adraffy/ens-normalize" "^1.10.1"
"@noble/curves" "^1.6.0" "@noble/curves" "^1.6.0"
...@@ -15507,9 +15359,9 @@ pretty-format@^29.0.0, pretty-format@^29.3.1: ...@@ -15507,9 +15359,9 @@ pretty-format@^29.0.0, pretty-format@^29.3.1:
react-is "^18.0.0" react-is "^18.0.0"
prismjs@^1.27.0: prismjs@^1.27.0:
version "1.29.0" version "1.30.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9"
integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== integrity "sha1-2XCZadnU4WQD9vNIxjVTsZ8Jdak= sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="
prismjs@~1.27.0: prismjs@~1.27.0:
version "1.27.0" version "1.27.0"
...@@ -16189,21 +16041,6 @@ regenerate@^1.4.2: ...@@ -16189,21 +16041,6 @@ regenerate@^1.4.2:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
regenerator-runtime@^0.13.10:
version "0.13.10"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"
integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.13.4:
version "0.13.9"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regenerator-runtime@^0.14.0: regenerator-runtime@^0.14.0:
version "0.14.0" version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
...@@ -18020,6 +17857,11 @@ use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0: ...@@ -18020,6 +17857,11 @@ use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0:
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
use-sync-external-store@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
utf-8-validate@^5.0.2: utf-8-validate@^5.0.2:
version "5.0.10" version "5.0.10"
resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2"
...@@ -18094,34 +17936,32 @@ varint@^6.0.0: ...@@ -18094,34 +17936,32 @@ varint@^6.0.0:
resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0"
integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
viem@2.21.54: viem@2.23.14, viem@>=2.23.5:
version "2.21.54" version "2.23.14"
resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.54.tgz#76d6f86ab8809078f1ac140ac1a2beadbc86b9f6" resolved "https://registry.yarnpkg.com/viem/-/viem-2.23.14.tgz#87b2c93b37014c354d1624183cce685f88c56a97"
integrity sha512-G9mmtbua3UtnVY9BqAtWdNp+3AO+oWhD0B9KaEsZb6gcrOWgmA4rz02yqEMg+qW9m6KgKGie7q3zcHqJIw6AqA== integrity sha512-ol8UKYT418u+7Lg83Ut7WJe7iOn1daGAqaofCoPe5z7eGR/XCu3ydja7eL7Z5ffwp6r0RoXeWkpun78UYhKygA==
dependencies: dependencies:
"@noble/curves" "1.7.0" "@noble/curves" "1.8.1"
"@noble/hashes" "1.6.1" "@noble/hashes" "1.7.1"
"@scure/bip32" "1.6.0" "@scure/bip32" "1.6.2"
"@scure/bip39" "1.5.0" "@scure/bip39" "1.5.4"
abitype "1.0.7" abitype "1.0.8"
isows "1.0.6" isows "1.0.6"
ox "0.1.2" ox "0.6.9"
webauthn-p256 "0.0.10" ws "8.18.1"
ws "8.18.0"
viem@2.x: viem@2.23.2:
version "2.21.32" version "2.23.2"
resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.32.tgz#b7f43b2004967036f83500260290cee45189f62a" resolved "https://registry.yarnpkg.com/viem/-/viem-2.23.2.tgz#db395c8cf5f4fb5572914b962fb8ce5db09f681c"
integrity sha512-2oXt5JNIb683oy7C8wuIJ/SeL3XtHVMEQpy1U2TA6WMnJQ4ScssRvyPwYLcaP6mKlrGXE/cR/V7ncWpvLUVPYQ== integrity sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==
dependencies: dependencies:
"@adraffy/ens-normalize" "1.11.0" "@noble/curves" "1.8.1"
"@noble/curves" "1.6.0" "@noble/hashes" "1.7.1"
"@noble/hashes" "1.5.0" "@scure/bip32" "1.6.2"
"@scure/bip32" "1.5.0" "@scure/bip39" "1.5.4"
"@scure/bip39" "1.4.0" abitype "1.0.8"
abitype "1.0.6"
isows "1.0.6" isows "1.0.6"
webauthn-p256 "0.0.10" ox "0.6.7"
ws "8.18.0" ws "8.18.0"
viem@^1.20.3: viem@^1.20.3:
...@@ -18193,14 +18033,14 @@ w3c-xmlserializer@^3.0.0: ...@@ -18193,14 +18033,14 @@ w3c-xmlserializer@^3.0.0:
dependencies: dependencies:
xml-name-validator "^4.0.0" xml-name-validator "^4.0.0"
wagmi@2.14.0: wagmi@2.14.15:
version "2.14.0" version "2.14.15"
resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-2.14.0.tgz#f2d7358b7f29a8a8e012b779d51bf83da269299e" resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-2.14.15.tgz#d7081f045e00ec9bf9e7076fe8c6f506f2a96094"
integrity sha512-IO/jPEqHTMAg4/SV4Dg3UR4AeACATyrNprwSpI0FlKEhAjmmNz8N+fa9vI24TUqJ3svLFdA32rjXJvNazeZv9g== integrity sha512-sRa7FsEmgph1KsIK93wCS2MhZgUae18jI/+Ger+INSxytJbhzNkukpHxWlNfV/Skl8zxDAQfxucotZLi8UadZQ==
dependencies: dependencies:
"@wagmi/connectors" "5.6.0" "@wagmi/connectors" "5.7.11"
"@wagmi/core" "2.16.0" "@wagmi/core" "2.16.7"
use-sync-external-store "1.2.0" use-sync-external-store "1.4.0"
walker@^1.0.8: walker@^1.0.8:
version "1.0.8" version "1.0.8"
...@@ -18227,14 +18067,6 @@ web-tree-sitter@=0.20.3: ...@@ -18227,14 +18067,6 @@ web-tree-sitter@=0.20.3:
resolved "https://registry.yarnpkg.com/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz#3dd17b283ad63b1d8c07c5ea814f0fefb2b1f776" resolved "https://registry.yarnpkg.com/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz#3dd17b283ad63b1d8c07c5ea814f0fefb2b1f776"
integrity sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw== integrity sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==
webauthn-p256@0.0.10:
version "0.0.10"
resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.10.tgz#877e75abe8348d3e14485932968edf3325fd2fdd"
integrity sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==
dependencies:
"@noble/curves" "^1.4.0"
"@noble/hashes" "^1.4.0"
webauthn-p256@0.0.5: webauthn-p256@0.0.5:
version "0.0.5" version "0.0.5"
resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd" resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd"
...@@ -18472,6 +18304,11 @@ ws@8.18.0, ws@^8.17.1, ws@^8.9.0: ...@@ -18472,6 +18304,11 @@ ws@8.18.0, ws@^8.17.1, ws@^8.9.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
ws@8.18.1:
version "8.18.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb"
integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==
ws@^7.3.1, ws@^7.5.1: ws@^7.3.1, ws@^7.5.1:
version "7.5.10" version "7.5.10"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment