Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Blobs support (EIP-4884) #1672

Merged
merged 21 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions configs/app/ui/views/tx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { TxAdditionalFieldsId, TxFieldsId } from 'types/views/tx';
import { TX_ADDITIONAL_FIELDS_IDS, TX_FIELDS_IDS } from 'types/views/tx';
import type { TxAdditionalFieldsId, TxFieldsId, TxViewId } from 'types/views/tx';
import { TX_ADDITIONAL_FIELDS_IDS, TX_FIELDS_IDS, TX_VIEWS_IDS } from 'types/views/tx';

import { getEnvValue, parseEnvJson } from 'configs/app/utils';

Expand Down Expand Up @@ -33,9 +33,31 @@ const additionalFields = (() => {
return result;
})();

const hiddenViews = (() => {
const envValue = getEnvValue('NEXT_PUBLIC_VIEWS_TX_HIDDEN_VIEWS');

if (!envValue) {
return undefined;
}

const parsedValue = parseEnvJson<Array<TxViewId>>(envValue);

if (!Array.isArray(parsedValue)) {
return undefined;
}

const result = TX_VIEWS_IDS.reduce((result, item) => {
result[item] = parsedValue.includes(item);
return result;
}, {} as Record<TxViewId, boolean>);

return result;
})();

const config = Object.freeze({
hiddenFields,
additionalFields,
hiddenViews,
});

export default config;
9 changes: 7 additions & 2 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import { ADDRESS_VIEWS_IDS, IDENTICON_TYPES } from '../../../types/views/address
import { BLOCK_FIELDS_IDS } from '../../../types/views/block';
import type { BlockFieldId } from '../../../types/views/block';
import type { NftMarketplaceItem } from '../../../types/views/nft';
import type { TxAdditionalFieldsId, TxFieldsId } from '../../../types/views/tx';
import { TX_ADDITIONAL_FIELDS_IDS, TX_FIELDS_IDS } from '../../../types/views/tx';
import type { TxAdditionalFieldsId, TxFieldsId, TxViewId } from '../../../types/views/tx';
import { TX_ADDITIONAL_FIELDS_IDS, TX_FIELDS_IDS, TX_VIEWS_IDS } from '../../../types/views/tx';

import { replaceQuotes } from '../../../configs/app/utils';
import * as regexp from '../../../lib/regexp';
Expand Down Expand Up @@ -448,6 +448,11 @@ const schema = yup
.transform(replaceQuotes)
.json()
.of(yup.string<TxAdditionalFieldsId>().oneOf(TX_ADDITIONAL_FIELDS_IDS)),
NEXT_PUBLIC_VIEWS_TX_HIDDEN_VIEWS: yup
.array()
.transform(replaceQuotes)
.json()
.of(yup.string<TxViewId>().oneOf(TX_VIEWS_IDS)),
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES: yup
.array()
.transform(replaceQuotes)
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/test/.env.base
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=['burnt_fees','total_reward']
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'NFT Marketplace','collection_url':'https://example.com/{hash}','instance_url':'https://example.com/{hash}/{id}','logo_url':'https://example.com/logo.png'}]
NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS=['fee_per_gas']
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS=['value','fee_currency','gas_price','tx_fee','gas_fees','burnt_fees']
NEXT_PUBLIC_VIEWS_TX_HIDDEN_VIEWS=['blob_txs']
NEXT_PUBLIC_VISUALIZE_API_HOST=https://example.com
NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET=false
NEXT_PUBLIC_WEB3_WALLETS=['coinbase','metamask','token_pocket']
Expand Down
6 changes: 6 additions & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ Settings for meta tags and OG tags
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS | `Array<TxFieldsId>` | Array of the transaction fields ids that should be hidden. See below the list of the possible id values. | - | - | `'["value","tx_fee"]'` |
| NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS | `Array<TxAdditionalFieldsId>` | Array of the additional fields ids that should be added to the transaction details. See below the list of the possible id values. | - | - | `'["fee_per_gas"]'` |
| NEXT_PUBLIC_VIEWS_TX_HIDDEN_VIEWS | `Array<TxViewId>` | Transaction views that should be hidden. See below the list of the possible id values. | - | - | `'["blob_txs"]'` |

##### Transaction fields list
| Id | Description |
Expand All @@ -234,6 +235,11 @@ Settings for meta tags and OG tags
| --- | --- |
| `fee_per_gas` | Amount of total fee divided by total amount of gas used by transaction |

##### Transaction view list
| Id | Description |
| --- | --- |
| `blob_txs` | List of all transactions that contain blob data |

&nbsp;

#### NFT views
Expand Down
5 changes: 5 additions & 0 deletions icons/blob.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions icons/blobs/image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions icons/blobs/raw.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions icons/blobs/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 32 additions & 11 deletions lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type {
AddressNFTTokensFilter,
} from 'types/api/address';
import type { AddressesResponse } from 'types/api/addresses';
import type { TxBlobs, Blob } from 'types/api/blobs';
import type { BlocksResponse, BlockTransactionsResponse, Block, BlockFilters, BlockWithdrawalsResponse } from 'types/api/block';
import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/charts';
import type { BackendVersionConfig } from 'types/api/configs';
Expand Down Expand Up @@ -84,9 +85,10 @@ import type {
Transaction,
TransactionsResponseWatchlist,
TransactionsSorting,
TransactionsResponseWithBlobs,
} from 'types/api/transaction';
import type { TxInterpretationResponse } from 'types/api/txInterpretation';
import type { TTxsFilters } from 'types/api/txsFilters';
import type { TTxsFilters, TTxsWithBlobsFilters } from 'types/api/txsFilters';
import type { TxStateChanges } from 'types/api/txStateChanges';
import type { UserOpsResponse, UserOp, UserOpsFilters, UserOpsAccount } from 'types/api/userOps';
import type { ValidatorsCountersResponse, ValidatorsFilters, ValidatorsResponse, ValidatorsSorting } from 'types/api/validators';
Expand Down Expand Up @@ -264,7 +266,7 @@ export const RESOURCES = {
block_txs: {
path: '/api/v2/blocks/:height_or_hash/transactions',
pathParams: [ 'height_or_hash' as const ],
filterFields: [],
filterFields: [ 'type' as const ],
},
block_withdrawals: {
path: '/api/v2/blocks/:height_or_hash/withdrawals',
Expand All @@ -279,6 +281,10 @@ export const RESOURCES = {
path: '/api/v2/transactions',
filterFields: [ 'filter' as const, 'type' as const, 'method' as const ],
},
txs_with_blobs: {
path: '/api/v2/transactions',
filterFields: [ 'type' as const ],
},
txs_watchlist: {
path: '/api/v2/transactions/watchlist',
filterFields: [ ],
Expand Down Expand Up @@ -316,6 +322,10 @@ export const RESOURCES = {
pathParams: [ 'hash' as const ],
filterFields: [],
},
tx_blobs: {
path: '/api/v2/transactions/:hash/blobs',
pathParams: [ 'hash' as const ],
},
tx_interpretation: {
path: '/api/v2/transactions/:hash/summary',
pathParams: [ 'hash' as const ],
Expand Down Expand Up @@ -664,6 +674,12 @@ export const RESOURCES = {
pathParams: [ 'chainType' as const ],
},

// BLOBS
blob: {
path: '/api/v2/blobs/:hash',
pathParams: [ 'hash' as const ],
},

// CONFIGS
config_backend_version: {
path: '/api/v2/config/backend-version',
Expand Down Expand Up @@ -723,8 +739,8 @@ export interface ResourceError<T = unknown> {
export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>

export type PaginatedResources = 'blocks' | 'block_txs' |
'txs_validated' | 'txs_pending' | 'txs_watchlist' | 'txs_execution_node' |
'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_state_changes' |
'txs_validated' | 'txs_pending' | 'txs_with_blobs' | 'txs_watchlist' | 'txs_execution_node' |
'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_state_changes' | 'tx_blobs' |
'addresses' |
'address_txs' | 'address_internal_txs' | 'address_token_transfers' | 'address_blocks_validated' | 'address_coin_balance' |
'search' |
Expand Down Expand Up @@ -775,6 +791,7 @@ Q extends 'block_txs' ? BlockTransactionsResponse :
Q extends 'block_withdrawals' ? BlockWithdrawalsResponse :
Q extends 'txs_validated' ? TransactionsResponseValidated :
Q extends 'txs_pending' ? TransactionsResponsePending :
Q extends 'txs_with_blobs' ? TransactionsResponseWithBlobs :
Q extends 'txs_watchlist' ? TransactionsResponseWatchlist :
Q extends 'txs_execution_node' ? TransactionsResponseValidated :
Q extends 'tx' ? Transaction :
Expand All @@ -783,6 +800,7 @@ Q extends 'tx_logs' ? LogsResponseTx :
Q extends 'tx_token_transfers' ? TokenTransferResponse :
Q extends 'tx_raw_trace' ? RawTracesResponse :
Q extends 'tx_state_changes' ? TxStateChanges :
Q extends 'tx_blobs' ? TxBlobs :
Q extends 'tx_interpretation' ? TxInterpretationResponse :
Q extends 'addresses' ? AddressesResponse :
Q extends 'address' ? Address :
Expand Down Expand Up @@ -839,20 +857,14 @@ Q extends 'zkevm_l2_txn_batches_count' ? number :
Q extends 'zkevm_l2_txn_batch' ? ZkEvmL2TxnBatch :
Q extends 'zkevm_l2_txn_batch_txs' ? ZkEvmL2TxnBatchTxs :
Q extends 'config_backend_version' ? BackendVersionConfig :
Q extends 'addresses_lookup' ? EnsAddressLookupResponse :
Q extends 'domain_info' ? EnsDomainDetailed :
Q extends 'domain_events' ? EnsDomainEventsResponse :
Q extends 'domains_lookup' ? EnsDomainLookupResponse :
Q extends 'user_ops' ? UserOpsResponse :
Q extends 'user_op' ? UserOp :
Q extends 'user_ops_account' ? UserOpsAccount :
never;
// !!! IMPORTANT !!!
// See comment above
/* eslint-enable @typescript-eslint/indent */

/* eslint-disable @typescript-eslint/indent */
export type ResourcePayloadB<Q extends ResourceName> =
Q extends 'blob' ? Blob :
Q extends 'marketplace_dapps' ? Array<MarketplaceAppOverview> :
Q extends 'marketplace_dapp' ? MarketplaceAppOverview :
Q extends 'validators' ? ValidatorsResponse :
Expand All @@ -862,6 +874,13 @@ Q extends 'shibarium_deposits' ? ShibariumDepositsResponse :
Q extends 'shibarium_withdrawals_count' ? number :
Q extends 'shibarium_deposits_count' ? number :
Q extends 'contract_security_audits' ? SmartContractSecurityAudits :
Q extends 'addresses_lookup' ? EnsAddressLookupResponse :
Q extends 'domain_info' ? EnsDomainDetailed :
Q extends 'domain_events' ? EnsDomainEventsResponse :
Q extends 'domains_lookup' ? EnsDomainLookupResponse :
Q extends 'user_ops' ? UserOpsResponse :
Q extends 'user_op' ? UserOp :
Q extends 'user_ops_account' ? UserOpsAccount :
never;
/* eslint-enable @typescript-eslint/indent */

Expand All @@ -874,7 +893,9 @@ export type PaginatedResponseNextPageParams<Q extends ResourceName> = Q extends
/* eslint-disable @typescript-eslint/indent */
export type PaginationFilters<Q extends PaginatedResources> =
Q extends 'blocks' ? BlockFilters :
Q extends 'block_txs' ? TTxsWithBlobsFilters :
Q extends 'txs_validated' | 'txs_pending' ? TTxsFilters :
Q extends 'txs_with_blobs' ? TTxsWithBlobsFilters :
Q extends 'tx_token_transfers' ? TokenTransferFilters :
Q extends 'token_transfers' ? TokenTransferFilters :
Q extends 'address_txs' | 'address_internal_txs' ? AddressTxsFilters :
Expand Down
9 changes: 9 additions & 0 deletions lib/blob/guessDataType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import filetype from 'magic-bytes.js';

import hexToBytes from 'lib/hexToBytes';

export default function guessDataType(data: string) {
const bytes = new Uint8Array(hexToBytes(data));

return filetype(bytes)[0];
}
1 change: 1 addition & 0 deletions lib/blob/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as guessDataType } from './guessDataType';
14 changes: 14 additions & 0 deletions lib/hexToBase64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import hexToBytes from './hexToBytes';

export default function hexToBase64(hex: string) {
const bytes = new Uint8Array(hexToBytes(hex));

let binary = '';
for (const byte of bytes) {
binary += String.fromCharCode(byte);
}

const base64String = btoa(binary);

return base64String;
}
4 changes: 3 additions & 1 deletion lib/hexToBytes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// hex can be with prefix - `0x{string}` - or without it - `{string}`
export default function hexToBytes(hex: string) {
const bytes = [];
for (let c = 0; c < hex.length; c += 2) {
const startIndex = hex.startsWith('0x') ? 2 : 0;
for (let c = startIndex; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substring(c, c + 2), 16));
}
return bytes;
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/output-roots': 'Root page',
'/batches': 'Root page',
'/batches/[number]': 'Regular page',
'/blobs/[hash]': 'Regular page',
'/ops': 'Root page',
'/op/[hash]': 'Regular page',
'/404': 'Regular page',
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/output-roots': DEFAULT_TEMPLATE,
'/batches': DEFAULT_TEMPLATE,
'/batches/[number]': DEFAULT_TEMPLATE,
'/blobs/[hash]': DEFAULT_TEMPLATE,
'/ops': DEFAULT_TEMPLATE,
'/op/[hash]': DEFAULT_TEMPLATE,
'/404': DEFAULT_TEMPLATE,
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/output-roots': 'output roots',
'/batches': 'tx batches (L2 blocks)',
'/batches/[number]': 'L2 tx batch %number%',
'/blobs/[hash]': 'blob %hash% details',
'/ops': 'user operations',
'/op/[hash]': 'user operation %hash%',
'/404': 'error - page not found',
Expand Down
1 change: 1 addition & 0 deletions lib/mixpanel/getPageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/output-roots': 'Output roots',
'/batches': 'Tx batches (L2 blocks)',
'/batches/[number]': 'L2 tx batch details',
'/blobs/[hash]': 'Blob details',
'/ops': 'User operations',
'/op/[hash]': 'User operation details',
'/404': '404',
Expand Down
Loading
Loading