diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 1187f821..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - sourceType: 'module', - }, - plugins: ['@typescript-eslint/eslint-plugin'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], - root: true, - env: { - node: true, - jest: true, - }, - ignorePatterns: ['.eslintrc.js'], - rules: { - 'max-len': ['error', { code: 120, tabWidth: 2 }], - 'no-console': 'error', - curly: 'error', - 'lines-between-class-members': [ - 'error', - 'always', - { exceptAfterSingleLine: true }, - ], - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - }, -}; diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index b58dade5..e9fc4af4 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -2,6 +2,11 @@ name: Build and push docker images on: workflow_dispatch: + inputs: + is_latest: + type: string + description: should add latest tag + default: "false" jobs: build-crawler: @@ -11,6 +16,7 @@ jobs: with: tag: scan-backend-crawler dockerfile: Dockerfile.crawler + is_latest: ${{ github.event.inputs.is_latest }} build-web-api: name: Build Web API @@ -18,3 +24,4 @@ jobs: secrets: inherit with: tag: scan-backend-web-api + is_latest: ${{ github.event.inputs.is_latest }} diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index c6d6453e..a9482e44 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -11,10 +11,6 @@ on: type: string description: tag required: true - push: - type: boolean - description: is push - default: false dockerfile: type: string description: dockerfile path @@ -23,6 +19,10 @@ on: type: string description: build target required: false + is_latest: + type: string + description: should add latest tag + default: false jobs: docker: @@ -46,4 +46,12 @@ jobs: with: file: ${{ inputs.dockerfile }} push: true - tags: ${{ inputs.image }}:${{ inputs.tag }}-${{ github.sha }},${{ inputs.image }}:${{ inputs.tag }}-latest + tags: ${{ inputs.image }}:${{ inputs.tag }}-${{ github.sha }} + - + name: Build and push latest + if: ${{ inputs.is_latest == 'true' }} + uses: docker/build-push-action@v4 + with: + file: ${{ inputs.dockerfile }} + push: true + tags: ${{ inputs.image }}:${{ inputs.tag }}-latest diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..6276cf12 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.14.2 diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index dcb72794..00000000 --- a/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all" -} \ No newline at end of file diff --git a/apps/crawler/src/services/collection.service.ts b/apps/crawler/src/services/collection.service.ts index 6eca3485..e5b0ddc8 100644 --- a/apps/crawler/src/services/collection.service.ts +++ b/apps/crawler/src/services/collection.service.ts @@ -18,6 +18,7 @@ import { CollectionInfoWithSchema, CollectionLimits, CollectionProperty, + CollectionWithInfoV2, PropertyKeyPermission, UniqueCollectionSchemaDecoded, } from '@unique-nft/substrate-client/tokens'; @@ -38,6 +39,7 @@ type ParsedSchemaFields = { interface CollectionData { collectionDecoded: CollectionInfoWithSchema | null; + collectionDecodedV2: CollectionWithInfoV2 | null; collectionLimits: CollectionLimits | null; tokenPropertyPermissions: PropertyKeyPermission[]; } @@ -55,7 +57,7 @@ export class CollectionService { private collectionsRepository: Repository, @InjectRepository(Tokens) - private tokensRepository: Repository, + private tokensRepository: Repository ) {} /** @@ -63,23 +65,26 @@ export class CollectionService { */ private async getCollectionData( collectionId: number, - at: string, + at: string ): Promise { - debugger; let collectionDecoded = await this.sdkService.getCollection( collectionId, - at, + at ); + + let collectionDecodedV2 = await this.sdkService.getCollectionV2( + collectionId, + at + ); + let checkAt = false; // for burned collections if (!collectionDecoded) { collectionDecoded = await this.sdkService.getCollection(collectionId, at); checkAt = true; } - debugger; - if (!collectionDecoded) { - return null; - } + + if (!collectionDecoded) return null; // TODO: delete after rft support // if (collectionDecoded.mode === CollectionMode.ReFungible) { @@ -89,16 +94,17 @@ export class CollectionService { const [collectionLimits, tokenPropertyPermissions] = await Promise.all([ this.sdkService.getCollectionLimits( collectionId, - checkAt ? at : undefined, + checkAt ? at : undefined ), this.sdkService.getTokenPropertyPermissions( collectionId, - checkAt ? at : undefined, + checkAt ? at : undefined ), ]); return { collectionDecoded, + collectionDecodedV2, collectionLimits: collectionLimits || collectionDecoded.limits, tokenPropertyPermissions: tokenPropertyPermissions || collectionDecoded.tokenPropertyPermissions, @@ -119,8 +125,10 @@ export class CollectionService { private processSchema( schema: UniqueCollectionSchemaDecoded, + collectionV2?: CollectionWithInfoV2 ): ParsedSchemaFields { let result = {}; + const { schemaName, schemaVersion, @@ -132,7 +140,8 @@ export class CollectionService { const schemaVersionCombined = `${schemaName}@${schemaVersion}@${attributesSchemaVersion}`; result = { - collectionCover: ipfsCid || fullUrl, + collectionCover: + ipfsCid || fullUrl || collectionV2?.info?.cover_image?.url, schemaVersion: schemaVersionCombined, attributesSchema, }; @@ -153,10 +162,10 @@ export class CollectionService { schemaVersion: `${schemaVersionCombined}@${oldSchemaVersion}`, offchainSchema, constOnChainSchema: this.processJsonStringifiedValue( - rawConstOnChainSchema, + rawConstOnChainSchema ), variableOnChainSchema: this.processJsonStringifiedValue( - rawVariableOnChainSchema, + rawVariableOnChainSchema ), }; } @@ -165,7 +174,7 @@ export class CollectionService { } private getSchemaValuesFromProperties( - properties: CollectionProperty[], + properties: CollectionProperty[] ): UniqueCollectionSchemaDecoded { const result = { schemaName: '_properties_', @@ -197,10 +206,15 @@ export class CollectionService { } private async prepareDataForDb( - collectionData: CollectionData, - ): Promise { - const { collectionDecoded, collectionLimits, tokenPropertyPermissions } = - collectionData; + collectionData: CollectionData + ): Promise> { + const { + collectionDecoded, + collectionDecodedV2, + collectionLimits, + tokenPropertyPermissions, + } = collectionData; + const { id: collection_id, owner, @@ -215,6 +229,7 @@ export class CollectionService { } = collectionDecoded; let schemaFromProperties = {} as UniqueCollectionSchemaDecoded; + if (!schema) { this.logger.warn(`No collection schema ${collection_id}`); @@ -231,7 +246,7 @@ export class CollectionService { // @ts-ignore // todo: Remove when sdk ready attributesSchema = {}, - } = this.processSchema(schema || schemaFromProperties); + } = this.processSchema(schema || schemaFromProperties, collectionDecodedV2); const { mintMode, nesting } = permissions; @@ -255,6 +270,7 @@ export class CollectionService { description, offchain_schema: offchainSchema, token_limit: token_limit || 0, + schema_v2: collectionDecodedV2?.info || null, properties: sanitizePropertiesValues(properties), permissions, token_property_permissions: tokenPropertyPermissions, @@ -283,12 +299,16 @@ export class CollectionService { blockCommonData, }: { events: Event[]; - blockCommonData: any; + blockCommonData: { + block_hash: string; + timestamp: number; + block_number: number; + }; }): Promise { const collectionEvents = this.extractCollectionEvents(events); const eventChunks = chunk( collectionEvents, - this.configService.get('scanCollectionsBatchSize'), + this.configService.get('scanCollectionsBatchSize') ); let rejected = []; @@ -300,7 +320,7 @@ export class CollectionService { collectionId: number; }; - const { block_hash, timestamp } = blockCommonData; + const { block_hash, timestamp, block_number } = blockCommonData; const eventName = `${section}.${method}`; if (COLLECTION_UPDATE_EVENTS.includes(eventName)) { @@ -309,11 +329,12 @@ export class CollectionService { eventName, blockTimestamp: timestamp, blockHash: block_hash, + blockNumber: block_number, }); } else { return this.burn(collectionId); } - }), + }) ); // todo: Process rejected tokens again or maybe process sdk disconnect @@ -336,15 +357,17 @@ export class CollectionService { eventName, blockTimestamp, blockHash, + blockNumber, }: { collectionId: number; eventName: string; blockTimestamp: number; blockHash: string; + blockNumber: number; }): Promise { const collectionData = await this.getCollectionData( collectionId, - blockHash, + blockHash ); let result; @@ -352,16 +375,19 @@ export class CollectionService { if (collectionData) { const preparedData = await this.prepareDataForDb(collectionData); - await this.collectionsRepository.upsert( - { - ...preparedData, - date_of_creation: - eventName === EventName.COLLECTION_CREATED - ? normalizeTimestamp(blockTimestamp) - : undefined, - }, - ['collection_id'], - ); + if (eventName === EventName.COLLECTION_CREATED) { + preparedData.date_of_creation = normalizeTimestamp(blockTimestamp); + + preparedData.created_at_block_hash = blockHash; + preparedData.created_at_block_number = blockNumber; + preparedData.updated_at_block_hash = blockHash; + preparedData.updated_at_block_number = blockNumber; + } else { + preparedData.updated_at_block_hash = blockHash; + preparedData.updated_at_block_number = blockNumber; + } + + await this.collectionsRepository.upsert(preparedData, ['collection_id']); result = SubscriberAction.UPSERT; } else { @@ -378,11 +404,11 @@ export class CollectionService { return Promise.allSettled([ this.collectionsRepository.update( { collection_id: collectionId }, - { burned: true }, + { burned: true } ), this.tokensRepository.update( { collection_id: collectionId }, - { burned: true }, + { burned: true } ), ]); } diff --git a/apps/crawler/src/services/event/event.service.ts b/apps/crawler/src/services/event/event.service.ts index 6c638857..5dc9414f 100644 --- a/apps/crawler/src/services/event/event.service.ts +++ b/apps/crawler/src/services/event/event.service.ts @@ -31,7 +31,7 @@ export class EventService { private collectionService: CollectionService, private configService: ConfigService, @InjectRepository(Event) - private eventsRepository: Repository, + private eventsRepository: Repository ) {} private extractEventItemsNew(blockItems: any): EventEntity[] { @@ -50,7 +50,7 @@ export class EventService { private async prepareDataForDbNew( eventItems, - block: BlockEntity, + block: BlockEntity ): Promise { return Promise.all( eventItems.map(async (event, num) => { @@ -60,7 +60,7 @@ export class EventService { const evenData = await this.eventArgumentsService.eventDataConverter( event.dataJson, - eventName, + eventName ); //console.dir({ eventName, evenData }, { depth: 3 }); @@ -76,13 +76,13 @@ export class EventService { data: JSON.stringify(evenData.data) || JSON.stringify(event.dataJson), values: evenData.values || null, timestamp: Math.floor( - new Date(block.timestamp.getTime()).getTime() / 1000, + new Date(block.timestamp.getTime()).getTime() / 1000 ), amount, // todo: Remove this field and use from values? block_index: `${block.id}-${event.indexExtrinsics}`, }; return result; - }), + }) ); } @@ -100,11 +100,11 @@ export class EventService { const ethereumEvents = events.filter( ({ section, method }) => - section === EventSection.ETHEREUM && method === EventMethod.EXECUTED, + section === EventSection.ETHEREUM && method === EventMethod.EXECUTED ); const speckEvents = events.filter( ({ section, method }) => - section === 'ParachainSystem' && method === 'ValidationFunctionApplied', + section === 'ParachainSystem' && method === 'ValidationFunctionApplied' ); // this.evmService.parseEvents( @@ -122,8 +122,9 @@ export class EventService { events, blockCommonData: { block_hash: block.hash, + block_number: block.id, timestamp: Math.floor( - new Date(block.timestamp.getTime()).getTime() / 1000, + new Date(block.timestamp.getTime()).getTime() / 1000 ), }, }); @@ -132,12 +133,12 @@ export class EventService { collectionsResult.rejected.length === 0 ) { this.logCollection.log( - `Save event collection: ${collectionsResult.collection.collectionId}`, + `Save event collection: ${collectionsResult.collection.collectionId}` ); } if (collectionsResult.rejected.length > 0) { this.logCollection.error( - collectionsResult.rejected.map(({ reason }) => reason.toString()), + collectionsResult.rejected.map(({ reason }) => reason.toString()) ); } } @@ -150,18 +151,18 @@ export class EventService { block_hash: block.hash, block_number: block.id, timestamp: Math.floor( - new Date(block.timestamp.getTime()).getTime() / 1000, + new Date(block.timestamp.getTime()).getTime() / 1000 ), }, }); if (tokensResult.totalEvents >= 4) { this.logToken.log( - `Save event in collection: ${tokensResult.collection} token: ${tokensResult.token}`, + `Save event in collection: ${tokensResult.collection} token: ${tokensResult.token}` ); } if (tokensResult.rejected.length > 0) { this.logToken.error( - tokensResult.rejected.map(({ reason }) => reason.toString()), + tokensResult.rejected.map(({ reason }) => reason.toString()) ); } } diff --git a/apps/crawler/src/services/services.module.ts b/apps/crawler/src/services/services.module.ts index 5a521d3d..bebccb1d 100644 --- a/apps/crawler/src/services/services.module.ts +++ b/apps/crawler/src/services/services.module.ts @@ -5,6 +5,7 @@ import { Event } from '@entities/Event'; import { EvmTransaction } from '@entities/EvmTransaction'; import { Extrinsic } from '@entities/Extrinsic'; import { Account } from '@entities/Account'; +import { Attribute } from '@common/entities'; import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; @@ -24,6 +25,7 @@ import { SdkModule } from '@common/sdk/sdk.module'; imports: [ TypeOrmModule.forFeature([ Account, + Attribute, Block, Collections, Event, diff --git a/apps/crawler/src/services/token/token.service.ts b/apps/crawler/src/services/token/token.service.ts index 05d74c5e..3f4b3332 100644 --- a/apps/crawler/src/services/token/token.service.ts +++ b/apps/crawler/src/services/token/token.service.ts @@ -25,6 +25,7 @@ import { CollectionService } from '../collection.service'; import { TokensOwners } from '@entities/TokensOwners'; import { yellow } from '@nestjs/common/utils/cli-colors.util'; import { SdkService } from '@common/sdk/sdk.service'; +import { Attribute } from '@common/entities'; const tryGetNormalizedAddress = (data: any[], index: number) => { const field = data[index]; @@ -32,7 +33,7 @@ const tryGetNormalizedAddress = (data: any[], index: number) => { if (!address) { throw new Error( - `Address not found in ${JSON.stringify(data)} at index ${index}`, + `Address not found in ${JSON.stringify(data)} at index ${index}` ); } @@ -51,6 +52,8 @@ export class TokenService { private tokensOwnersRepository: Repository, @InjectRepository(Tokens) private tokensRepository: Repository, + @InjectRepository(Attribute) + private attributeRepository: Repository ) {} async prepareDataForDb( @@ -58,20 +61,24 @@ export class TokenService { blockHash: string, totalPieces: number, blockTimestamp?: number, - needCheckNesting = false, - ): Promise> { - let nestedType = false; - const { tokenDecoded, tokenProperties, isBundle } = tokenData; + needCheckNesting = false + ): Promise> { + let nested = false; + const { tokenDecoded, tokenDecodedV2, tokenProperties, isBundle } = + tokenData; const { tokenId: token_id, collectionId: collection_id, - image, - attributes, + attributes: attributes_v1, nestingParentToken, owner, } = tokenDecoded; + const image_v1 = tokenDecoded.image; + if (!image_v1.fullUrl && tokenDecodedV2?.image) + image_v1.fullUrl = tokenDecodedV2.image; + const { owner: collectionOwner, tokenPrefix } = tokenDecoded.collection; const token = await this.tokensRepository.findOneBy({ @@ -86,33 +93,33 @@ export class TokenService { if (nestingParentToken) { const { collectionId, tokenId } = nestingParentToken; parentId = `${collectionId}_${tokenId}`; - nestedType = true; + nested = true; } const children: ITokenEntities[] = needCheckNesting ? await this.nestingService.handleNesting( tokenData, blockHash, - blockTimestamp, + blockTimestamp ) : token?.children ?? []; - if (isBundle) { - nestedType = true; - } + if (isBundle) nested = true; if (!children.length && !parentId) { tokenType = tokenDecoded.collection.mode === 'NFT' ? TokenType.NFT : TokenType.RFT; } const ownerCollection = owner || collectionOwner; + return { token_id, collection_id, owner: ownerCollection, owner_normalized: normalizeSubstrateAddress(ownerCollection), - image, - attributes, + image_v1, + image: tokenDecodedV2?.image || null, + attributes_v1, properties: tokenProperties.properties ? sanitizePropertiesValues(tokenProperties.properties) : [], @@ -124,7 +131,8 @@ export class TokenService { children, bundle_created: tokenType === TokenType.NFT ? null : undefined, total_pieces: totalPieces, - nested: nestedType, + nested, + schema_v2: tokenDecodedV2 || null, }; } @@ -133,7 +141,11 @@ export class TokenService { blockCommonData, }: { events: Event[]; - blockCommonData: any; + blockCommonData: { + block_hash: string; + block_number: number; + timestamp: number; + }; }): Promise { const tokenEventsRaw = this.extractTokenEvents(events); @@ -154,7 +166,7 @@ export class TokenService { const eventChunks = chunk( tokenEvents, - this.configService.get('scanTokensBatchSize'), + this.configService.get('scanTokensBatchSize') ); let rejected = []; let data = []; @@ -205,7 +217,7 @@ export class TokenService { } else { return this.burn(collectionId, tokenId); } - }), + }) ); // todo: Process rejected tokens again or maybe process sdk disconnect @@ -247,7 +259,8 @@ export class TokenService { let result; if (tokenData) { - const { tokenDecoded } = tokenData; + // create or update token and token owners + const { tokenDecoded, tokenDecodedV2 } = tokenData; const needCheckNesting = eventName === EventName.TRANSFER; let pieces = 1; @@ -257,12 +270,12 @@ export class TokenService { ).amount; } - const preparedData = await this.prepareDataForDb( + const dbTokenEntity = await this.prepareDataForDb( tokenData, blockHash, pieces, blockTimestamp, - needCheckNesting, + needCheckNesting ); if (data.length != 0) { @@ -279,9 +292,9 @@ export class TokenService { tokenId, blockNumber, blockTimestamp, - preparedData, + dbTokenEntity, typeMode, - eventName, + eventName ); break; @@ -292,41 +305,61 @@ export class TokenService { blockNumber, blockHash, data, - preparedData, + dbTokenEntity, typeMode, eventName, - blockTimestamp, + blockTimestamp ); break; } } // Write token data into db - const entity = { - ...preparedData, - date_of_creation: - eventName === EventName.ITEM_CREATED - ? normalizeTimestamp(blockTimestamp) - : undefined, - }; - const already = await this.tokensRepository.findOne({ + + if (eventName === EventName.ITEM_CREATED) { + dbTokenEntity.date_of_creation = normalizeTimestamp(blockTimestamp); + dbTokenEntity.created_at_block_hash = blockHash; + dbTokenEntity.created_at_block_number = blockNumber; + dbTokenEntity.updated_at_block_hash = blockHash; + dbTokenEntity.updated_at_block_number = blockNumber; + } else { + dbTokenEntity.updated_at_block_hash = blockHash; + dbTokenEntity.updated_at_block_number = blockNumber; + } + + const existingToken = await this.tokensRepository.findOne({ where: { - token_id: preparedData.token_id, - collection_id: preparedData.collection_id, + token_id: dbTokenEntity.token_id, + collection_id: dbTokenEntity.collection_id, }, }); - if (already) { + + if (existingToken) { await this.tokensRepository.update( { - id: already.id, + id: existingToken.id, }, - entity, + dbTokenEntity ); + + await this.attributeRepository.delete({ + collection_id: collectionId, + token_id: tokenId, + }); } else { - await this.tokensRepository.insert(entity); + await this.tokensRepository.insert(dbTokenEntity); } - result = SubscriberAction.UPSERT; + + await this.attributeRepository.insert( + tokenDecodedV2.attributes.map((a) => + Attribute.fromIV2Attribute(a, { collectionId, tokenId }) + ) + ); + + if (tokenData.tokenDecodedV2?.attributes) + result = SubscriberAction.UPSERT; } else { + // burn token and update token owners const ownerToken = tryGetNormalizedAddress(data, 2); await this.burnTokenOwnerPart({ @@ -345,7 +378,7 @@ export class TokenService { if (pieceToken.amount === 0) { this.logger.error( - `Destroy token full amount: ${pieceToken.amount} / collection: ${collectionId} / token: ${tokenId}`, + `Destroy token full amount: ${pieceToken.amount} / collection: ${collectionId} / token: ${tokenId}` ); // No entity returned from sdk. Most likely it was destroyed in a future block. await this.burn(collectionId, tokenId); @@ -365,7 +398,7 @@ export class TokenService { preparedData, typeMode, eventName, - blockTimestamp, + blockTimestamp ) { const arrayToken = []; @@ -376,7 +409,7 @@ export class TokenService { }, { burned: false, - }, + } ); const ownerAddress = tryGetNormalizedAddress(data, 2); @@ -387,7 +420,7 @@ export class TokenService { collectionId: collectionId, tokenId: tokenId, }, - blockHash, + blockHash ); arrayToken.push({ owner: ownerAddress, @@ -409,7 +442,7 @@ export class TokenService { collectionId: collectionId, tokenId: tokenId, }, - blockHash, + blockHash ); let parentId = null; let nested = false; @@ -448,7 +481,7 @@ export class TokenService { ]); this.logger.log( `${eventName} token: ${tokenOwnerData.token_id} collection:` + - ` ${tokenOwnerData.collection_id} in ${tokenOwnerData.block_number}`, + ` ${tokenOwnerData.collection_id} in ${tokenOwnerData.block_number}` ); } } @@ -462,12 +495,12 @@ export class TokenService { blockTimestamp, preparedData, typeMode, - eventName, + eventName ) { const tokenOwner: TokenOwnerData = { owner: tokenDecoded.owner || tokenDecoded.collection.owner, owner_normalized: normalizeSubstrateAddress( - tokenDecoded.owner || tokenDecoded.collection.owner, + tokenDecoded.owner || tokenDecoded.collection.owner ), collection_id: collectionId, token_id: tokenId, @@ -489,18 +522,14 @@ export class TokenService { ]); this.logger.log( `${eventName} token: ${yellow( - String(tokenOwner.token_id), + String(tokenOwner.token_id) )} collection: ${yellow(String(tokenOwner.collection_id))} in ${ tokenOwner.block_number - }`, + }` ); } - async burn( - collectionId: number, - tokenId: number, - owner?: string, - ): Promise { + async burn(collectionId: number, tokenId: number): Promise { await this.nestingService.removeTokenFromParents(collectionId, tokenId); return this.tokensRepository.update( @@ -510,51 +539,65 @@ export class TokenService { }, { burned: true, - }, + } ); } private async getTokenData( collectionId: number, tokenId: number, - blockHash: string, + blockHash: string ): Promise { - const rand = Math.random(); let tokenDecoded = null; + let tokenDecodedV2 = null; let tokenProperties = null; let isBundle = false; + try { tokenDecoded = await this.sdkService.getToken( collectionId, tokenId, - blockHash, + blockHash + ); + + if (!tokenDecoded) return null; + + tokenDecodedV2 = await this.sdkService.getTokenV2( + collectionId, + tokenId, + blockHash ); - if (!tokenDecoded) { - return null; - } const [tokenPropertiesRaw, isBundleRaw] = await Promise.all([ this.sdkService.getTokenProperties(collectionId, tokenId), this.sdkService.isTokenBundle(collectionId, tokenId, blockHash), ]); + tokenProperties = tokenPropertiesRaw; isBundle = isBundleRaw; } catch (e) { tokenDecoded = await this.sdkService.getToken(collectionId, tokenId); - if (!tokenDecoded) { - return null; - } + if (!tokenDecoded) return null; + + tokenDecodedV2 = await this.sdkService.getTokenV2( + collectionId, + tokenId, + blockHash + ); + const [tokenPropertiesRaw, isBundleRaw] = await Promise.all([ this.sdkService.getTokenProperties(collectionId, tokenId), this.sdkService.isTokenBundle(collectionId, tokenId), ]); + tokenProperties = tokenPropertiesRaw; isBundle = isBundleRaw; } return { tokenDecoded, + tokenDecodedV2, tokenProperties, isBundle, }; diff --git a/apps/crawler/src/services/token/token.types.ts b/apps/crawler/src/services/token/token.types.ts index d9bbec78..afceafc9 100644 --- a/apps/crawler/src/services/token/token.types.ts +++ b/apps/crawler/src/services/token/token.types.ts @@ -1,11 +1,13 @@ import { TokenByIdResult, + TokenByIdResultV2, TokenPropertiesResult, } from '@unique-nft/substrate-client/tokens'; import { ITokenEntities, TokenType } from '@entities/Tokens'; export interface TokenData { tokenDecoded: TokenByIdResult; + tokenDecodedV2: TokenByIdResultV2; tokenProperties: TokenPropertiesResult; isBundle: boolean; } diff --git a/apps/web-api/src/app.module.ts b/apps/web-api/src/app.module.ts index 0abf2cb3..43c8e880 100644 --- a/apps/web-api/src/app.module.ts +++ b/apps/web-api/src/app.module.ts @@ -19,6 +19,7 @@ import { StatisticsV2Module } from './statisticsV2/statisticsV2.module'; import { TransactionModule } from './transaction/transaction.module'; import { SentryModule } from '@ntegral/nestjs-sentry'; import { ContractModule } from './contract/contract.module'; +import { AttributesV1Module } from './attributes_v1/attributesV1.module'; import { AttributesModule } from './attributes/attributes.module'; import { EvmTransactionModule } from './evm-transactions/evm-transaction.module'; import { TokenOwnersModule } from './tokens-owners/token-owners.module'; @@ -65,6 +66,7 @@ import { GlobalConfigModule } from '@common/config/config.module'; StatisticsModule, StatisticsV2Module, TransactionModule, + AttributesV1Module, AttributesModule, EvmTransactionModule, CirculatingModule, diff --git a/apps/web-api/src/attributes/attributes.dto.ts b/apps/web-api/src/attributes/attributes.dto.ts new file mode 100644 index 00000000..4839198c --- /dev/null +++ b/apps/web-api/src/attributes/attributes.dto.ts @@ -0,0 +1,22 @@ +import { Field, Int, ObjectType, FieldMiddleware } from '@nestjs/graphql'; + +@ObjectType('attribute') +export class AttributesDto { + @Field(() => Int) + collection_id?: number; + + @Field(() => Int) + token_id?: number; + + @Field(() => String) + trait_type?: string; + + @Field(() => String, { nullable: true }) + display_type?: string; + + @Field(() => String, { nullable: true }) + value_string?: string | null; + + @Field(() => Number, { nullable: true }) + value_number?: number | null; +} diff --git a/apps/web-api/src/attributes/attributes.module.ts b/apps/web-api/src/attributes/attributes.module.ts index c976c05d..5a6a0229 100644 --- a/apps/web-api/src/attributes/attributes.module.ts +++ b/apps/web-api/src/attributes/attributes.module.ts @@ -1,8 +1,11 @@ import { Module } from '@nestjs/common'; import { AttributesResolver } from './attributes.resolver'; import { AttributesService } from './attributes.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Attribute } from '@common/entities'; @Module({ + imports: [TypeOrmModule.forFeature([Attribute])], providers: [AttributesResolver, AttributesService], }) export class AttributesModule {} diff --git a/apps/web-api/src/attributes/attributes.resolver.ts b/apps/web-api/src/attributes/attributes.resolver.ts index 15f5062c..196392de 100644 --- a/apps/web-api/src/attributes/attributes.resolver.ts +++ b/apps/web-api/src/attributes/attributes.resolver.ts @@ -1,20 +1,22 @@ -import { Args, Query, Resolver } from '@nestjs/graphql'; +import { Args, Info, Query, Resolver } from '@nestjs/graphql'; import { IDataListResponse } from '../utils/gql-query-args'; -import { AttributeDTO } from './attribute.dto'; +import { AttributesDto } from './attributes.dto'; import { AttributesDataResponse, AttributesQueryArgs, } from './attributes.resolver.types'; import { AttributesService } from './attributes.service'; +import { GraphQLResolveInfo } from 'graphql'; -@Resolver(() => AttributeDTO) +@Resolver(() => AttributesDto) export class AttributesResolver { - constructor(private service: AttributesService) {} + constructor(private attributesService: AttributesService) {} @Query(() => AttributesDataResponse) public async attributes( @Args() args: AttributesQueryArgs, - ): Promise> { - return this.service.getCollectionAttributes(args); + @Info() info: GraphQLResolveInfo + ): Promise> { + return this.attributesService.find(args, info); } } diff --git a/apps/web-api/src/attributes/attributes.resolver.types.ts b/apps/web-api/src/attributes/attributes.resolver.types.ts index 2de6289f..3c9d7abb 100644 --- a/apps/web-api/src/attributes/attributes.resolver.types.ts +++ b/apps/web-api/src/attributes/attributes.resolver.types.ts @@ -1,35 +1,53 @@ import { ArgsType, Field, InputType, ObjectType } from '@nestjs/graphql'; import { GQLOrderByParamsArgs, + GQLQueryPaginationArgs, GQLWhereOpsIntEq, ListDataType, TOrderByParams, } from '../utils/gql-query-args'; -import { AttributeDTO } from './attribute.dto'; +import { AttributesDto } from './attributes.dto'; @InputType() export class AttributesWhereParams { - @Field(() => GQLWhereOpsIntEq) - collection_id: GQLWhereOpsIntEq; + @Field(() => GQLWhereOpsIntEq, { nullable: true }) + collection_id?: GQLWhereOpsIntEq; + + @Field(() => GQLWhereOpsIntEq, { nullable: true }) + token_id?: GQLWhereOpsIntEq; } @InputType() -export class AttributesOrderByParams implements TOrderByParams { +export class AttributesOrderByParams + implements Partial> +{ + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + token_id?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + collection_id?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + trait_type?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + value?: GQLOrderByParamsArgs; + @Field(() => GQLOrderByParamsArgs, { nullable: true }) - key?: GQLOrderByParamsArgs; + value_number?: GQLOrderByParamsArgs; @Field(() => GQLOrderByParamsArgs, { nullable: true }) - name?: GQLOrderByParamsArgs; + value_string?: GQLOrderByParamsArgs; } @ArgsType() -export class AttributesQueryArgs { - @Field(() => AttributesWhereParams) - where: AttributesWhereParams; +export class AttributesQueryArgs extends GQLQueryPaginationArgs { + @Field(() => AttributesWhereParams, { nullable: true }) + where?: AttributesWhereParams; @Field(() => AttributesOrderByParams, { nullable: true }) order_by?: AttributesOrderByParams; } @ObjectType() -export class AttributesDataResponse extends ListDataType(AttributeDTO) {} +export class AttributesDataResponse extends ListDataType(AttributesDto) {} diff --git a/apps/web-api/src/attributes/attributes.service.ts b/apps/web-api/src/attributes/attributes.service.ts index 54f531b1..d32a7788 100644 --- a/apps/web-api/src/attributes/attributes.service.ts +++ b/apps/web-api/src/attributes/attributes.service.ts @@ -1,190 +1,34 @@ -import { DataSource } from 'typeorm'; +import { DataSource, Repository } from 'typeorm'; import { Injectable } from '@nestjs/common'; -import { SentryWrapper } from '../utils/sentry.decorator'; -import { AttributeDTO, AttributeValue } from './attribute.dto'; import { AttributesQueryArgs } from './attributes.resolver.types'; +import { AttributesDto } from './attributes.dto'; import { IDataListResponse } from '../utils/gql-query-args'; - -class RawAttributeValue { - isArray: boolean; - isEnum: boolean; - value: object; - rawValue: object | number | number[]; -} +import { GraphQLResolveInfo } from 'graphql'; +import { BaseService } from '../utils/base.service'; +import { Account, Attribute } from '@common/entities'; +import { InjectRepository } from '@nestjs/typeorm'; @Injectable() -export class AttributesService { - constructor(private dataSource: DataSource) {} - - /** - * Creates full list of all possible token attributes with default token_count = 0. - */ - private getDefaultAttributesList(attributesSchema): AttributeDTO[] { - return Object.entries(attributesSchema).map( - ([attrKey, attrDescriptor]: [ - string, - { name: object; enumValues?: object }, - ]) => { - const { name, enumValues } = attrDescriptor; - - const attribute = { - key: attrKey, - name, - values: [], - } as AttributeDTO; - - if (enumValues) { - attribute.values = Object.entries(enumValues).map( - ([enumKey, value]: [string, object]) => ({ - raw_value: String(enumKey), - value, - tokens_count: 0, - }), - ); - } - - return attribute; - }, - ); - } - - private getAttributeByKey( - attributesData: AttributeDTO[], - attributeKey: string, +export class AttributesService extends BaseService { + constructor( + @InjectRepository(Attribute) + private attributeRepository: Repository ) { - return attributesData.find(({ key }) => key == attributeKey); + super(); } - /** - * Finds in attributes list values exact attribute value and returns it's index. - * If not found, creates new record in values and returns it's index. - */ - private getAttributeValueIndex( - attribute: AttributeDTO, - attributeValueObj: AttributeValue, - ) { - const { raw_value: attributeRawValue } = attributeValueObj; - let index = attribute.values.findIndex( - ({ raw_value: currentRawValue }) => currentRawValue === attributeRawValue, - ); - - if (index === -1) { - attribute.values.push(attributeValueObj); - index = this.getAttributeValueIndex(attribute, attributeValueObj); - } - - return index; - } - - /** - * Converts raw attribute value object from tokens.attributes db record - * into array of AttributeValue objects suitable for AttributesDTO.values. - */ - private normalizeAttributeValueObj( - rawAttributeValueObj: RawAttributeValue, - ): AttributeValue[] { - const result = []; - const { value, rawValue, isArray } = rawAttributeValueObj; - - if (isArray && Array.isArray(rawValue)) { - rawValue.forEach((rawValue, index) => { - result.push({ - value: value[index], - raw_value: String(rawValue), - tokens_count: 0, - }); - }); - } else { - result.push({ - value, - raw_value: JSON.stringify(rawValue), - tokens_count: 0, - }); - } - - return result; - } - - /** - * Iterates through collection tokens attributes and calculates 'token_count' for every attribute value. - */ - private async collectTokenCounts( - collectionId: number, - attributesSchema: object, - ): Promise { - // Get list of all possible attributes with default tokens_count = 0 - const resultAttributesList = [ - ...this.getDefaultAttributesList(attributesSchema), - ]; - - // Get all collection tokens attributes. - const qResult = await this.dataSource.query( - `SELECT attributes FROM tokens WHERE - attributes IS NOT NULL - AND attributes != '{}'::jsonb - AND collection_id = ${collectionId};`, - ); - - if (!qResult) { - return resultAttributesList; - } - - // Tokens iteration - qResult.forEach(({ attributes: tokenAttributes }) => { - // Token attributes iteration - Object.entries(tokenAttributes).forEach( - ([attributeKey, rawAttributeValueObj]: [string, RawAttributeValue]) => { - const attributeValues = - this.normalizeAttributeValueObj(rawAttributeValueObj); - - // Normalized token attributes iteration (multiselect gives us another array) - attributeValues.forEach((attributeValueObj) => { - const attribute = this.getAttributeByKey( - resultAttributesList, - attributeKey, - ); - - const valueIndex = this.getAttributeValueIndex( - attribute, - attributeValueObj, - ); - - // Increment count for exact attribute and value - attribute.values[valueIndex].tokens_count += 1; - }); - }, - ); - }); - - return resultAttributesList; - } - - @SentryWrapper({ data: [], count: 0 }) - public async getCollectionAttributes( + async find( queryArgs: AttributesQueryArgs, - ): Promise> { - const result = { - data: [] as AttributeDTO[], - count: 0, - }; - - const collectionId = queryArgs.where.collection_id._eq; - - const qResult = await this.dataSource.query( - `SELECT attributes_schema FROM collections WHERE collection_id = ${collectionId}`, - ); - - const collection = qResult[0]; - if (!collection) { - return result; - } - - const { attributes_schema: attributesSchema } = collection; - - result.data = await this.collectTokenCounts(collectionId, attributesSchema); + queryInfo: GraphQLResolveInfo + ): Promise> { + const qb = this.attributeRepository.createQueryBuilder(); - result.count = result.data.length; + const queryFields = this.getQueryFields(queryInfo); + this.applySelect(qb, queryArgs, queryFields); + this.applyLimitOffset(qb, queryArgs); + this.applyWhereCondition(qb, queryArgs); + this.applyOrderCondition(qb, queryArgs); - return result; + return this.getDataAndCount(qb, queryArgs); } } diff --git a/apps/web-api/src/attributes/attribute.dto.ts b/apps/web-api/src/attributes_v1/attributeV1DTO.ts similarity index 70% rename from apps/web-api/src/attributes/attribute.dto.ts rename to apps/web-api/src/attributes_v1/attributeV1DTO.ts index fbc68160..8d008fed 100644 --- a/apps/web-api/src/attributes/attribute.dto.ts +++ b/apps/web-api/src/attributes_v1/attributeV1DTO.ts @@ -1,8 +1,8 @@ import { Field, Int, ObjectType } from '@nestjs/graphql'; import { GraphQLJSONObject } from 'graphql-type-json'; -@ObjectType('attribute_value') -export class AttributeValue { +@ObjectType('attribute_v1_value') +export class AttributeV1Value { @Field(() => GraphQLJSONObject, { nullable: true }) value?: object; @@ -13,14 +13,14 @@ export class AttributeValue { tokens_count?: number; } -@ObjectType('attribute') -export class AttributeDTO { +@ObjectType('attribute_v1') +export class AttributeV1DTO { @Field(() => String) key?: string; @Field(() => GraphQLJSONObject) name?: string | object; - @Field(() => [AttributeValue]) - values?: AttributeValue[]; + @Field(() => [AttributeV1Value]) + values?: AttributeV1Value[]; } diff --git a/apps/web-api/src/attributes_v1/attributesV1.module.ts b/apps/web-api/src/attributes_v1/attributesV1.module.ts new file mode 100644 index 00000000..c982a5ef --- /dev/null +++ b/apps/web-api/src/attributes_v1/attributesV1.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { AttributesV1Resolver } from './attributesV1.resolver'; +import { AttributesV1Service } from './attributesV1.service'; + +@Module({ + providers: [AttributesV1Resolver, AttributesV1Service], +}) +export class AttributesV1Module {} diff --git a/apps/web-api/src/attributes_v1/attributesV1.resolver.ts b/apps/web-api/src/attributes_v1/attributesV1.resolver.ts new file mode 100644 index 00000000..5baefa20 --- /dev/null +++ b/apps/web-api/src/attributes_v1/attributesV1.resolver.ts @@ -0,0 +1,20 @@ +import { Args, Query, Resolver } from '@nestjs/graphql'; +import { IDataListResponse } from '../utils/gql-query-args'; +import { AttributeV1DTO } from './attributeV1DTO'; +import { + AttributesV1DataResponse, + AttributesV1QueryArgs, +} from './attributesV1.resolver.types'; +import { AttributesV1Service } from './attributesV1.service'; + +@Resolver(() => AttributeV1DTO) +export class AttributesV1Resolver { + constructor(private service: AttributesV1Service) {} + + @Query(() => AttributesV1DataResponse, { name: 'attributes_v1' }) + public async attributes_v1( + @Args() args: AttributesV1QueryArgs + ): Promise> { + return this.service.getCollectionAttributes(args); + } +} diff --git a/apps/web-api/src/attributes_v1/attributesV1.resolver.types.ts b/apps/web-api/src/attributes_v1/attributesV1.resolver.types.ts new file mode 100644 index 00000000..45b58d6d --- /dev/null +++ b/apps/web-api/src/attributes_v1/attributesV1.resolver.types.ts @@ -0,0 +1,37 @@ +import { ArgsType, Field, InputType, ObjectType } from '@nestjs/graphql'; +import { + GQLOrderByParamsArgs, + GQLWhereOpsIntEq, + ListDataType, + TOrderByParams, +} from '../utils/gql-query-args'; +import { AttributeV1DTO } from './attributeV1DTO'; + +@InputType() +export class AttributesV1WhereParams { + @Field(() => GQLWhereOpsIntEq) + collection_id: GQLWhereOpsIntEq; +} + +@InputType() +export class AttributesV1OrderByParams + implements TOrderByParams +{ + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + key?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + name?: GQLOrderByParamsArgs; +} + +@ArgsType() +export class AttributesV1QueryArgs { + @Field(() => AttributesV1WhereParams) + where: AttributesV1WhereParams; + + @Field(() => AttributesV1OrderByParams, { nullable: true }) + order_by?: AttributesV1OrderByParams; +} + +@ObjectType() +export class AttributesV1DataResponse extends ListDataType(AttributeV1DTO) {} diff --git a/apps/web-api/src/attributes_v1/attributesV1.service.ts b/apps/web-api/src/attributes_v1/attributesV1.service.ts new file mode 100644 index 00000000..1b2c1556 --- /dev/null +++ b/apps/web-api/src/attributes_v1/attributesV1.service.ts @@ -0,0 +1,201 @@ +import { DataSource } from 'typeorm'; +import { Injectable } from '@nestjs/common'; +import { SentryWrapper } from '../utils/sentry.decorator'; +import { AttributeV1DTO, AttributeV1Value } from './attributeV1DTO'; +import { AttributesV1QueryArgs } from './attributesV1.resolver.types'; +import { IDataListResponse } from '../utils/gql-query-args'; +import * as console from 'console'; + +class RawAttributeValue { + isArray: boolean; + isEnum: boolean; + value: object; + rawValue: object | number | number[]; +} + +@Injectable() +export class AttributesV1Service { + constructor(private dataSource: DataSource) {} + + /** + * Creates full list of all possible token attributes with default token_count = 0. + */ + private getDefaultAttributesList(attributesSchema): AttributeV1DTO[] { + return Object.entries(attributesSchema).map( + ([attrKey, attrDescriptor]: [ + string, + { name: object; enumValues?: object } + ]) => { + const { name, enumValues } = attrDescriptor; + + const attribute = { + key: attrKey, + name, + values: [], + } as AttributeV1DTO; + + if (enumValues) { + attribute.values = Object.entries(enumValues).map( + ([enumKey, value]: [string, object]) => ({ + raw_value: String(enumKey), + value, + tokens_count: 0, + }) + ); + } + + return attribute; + } + ); + } + + private getAttributeByKey( + attributesData: AttributeV1DTO[], + attributeKey: string + ) { + return attributesData.find(({ key }) => key == attributeKey); + } + + /** + * Finds in attributes list values exact attribute value and returns it's index. + * If not found, creates new record in values and returns it's index. + */ + private getAttributeValueIndex( + attribute: AttributeV1DTO, + attributeValueObj: AttributeV1Value + ) { + const { raw_value: attributeRawValue } = attributeValueObj; + let index = attribute.values.findIndex( + ({ raw_value: currentRawValue }) => currentRawValue === attributeRawValue + ); + + if (index === -1) { + attribute.values.push(attributeValueObj); + index = this.getAttributeValueIndex(attribute, attributeValueObj); + } + + return index; + } + + /** + * Converts raw attribute value object from tokens.attributes db record + * into array of AttributeValue objects suitable for AttributesDTO.values. + */ + private normalizeAttributeValueObj( + rawAttributeValueObj: RawAttributeValue + ): AttributeV1Value[] { + const result = []; + const { value, rawValue, isArray } = rawAttributeValueObj; + + if (isArray && Array.isArray(rawValue)) { + rawValue.forEach((rawValue, index) => { + result.push({ + value: value[index], + raw_value: String(rawValue), + tokens_count: 0, + }); + }); + } else { + result.push({ + value, + raw_value: JSON.stringify(rawValue), + tokens_count: 0, + }); + } + + return result; + } + + /** + * Iterates through collection tokens attributes and calculates 'token_count' for every attribute value. + */ + private async collectTokenCounts( + collectionId: number, + attributesSchema: object + ): Promise { + // Get list of all possible attributes with default tokens_count = 0 + const resultAttributesList = [ + ...this.getDefaultAttributesList(attributesSchema), + ]; + + console.log('resultAttributesList', resultAttributesList); + + // Get all collection tokens attributes. + const qResult = await this.dataSource.query( + `SELECT attributes_v1 FROM tokens WHERE + attributes_v1 IS NOT NULL + AND attributes_v1 != '{}'::jsonb + AND collection_id = ${collectionId};` + ); + + if (!qResult) { + return resultAttributesList; + } + + console.log('qResult', qResult); + + // Tokens iteration + qResult.forEach(({ attributes_v1: tokenAttributes }) => { + // Token attributes iteration + Object.entries(tokenAttributes).forEach( + ([attributeKey, rawAttributeValueObj]: [string, RawAttributeValue]) => { + const attributeValues = + this.normalizeAttributeValueObj(rawAttributeValueObj); + + // Normalized token attributes iteration (multiselect gives us another array) + attributeValues.forEach((attributeValueObj) => { + const attribute = this.getAttributeByKey( + resultAttributesList, + attributeKey + ); + + const valueIndex = this.getAttributeValueIndex( + attribute, + attributeValueObj + ); + + // Increment count for exact attribute and value + attribute.values[valueIndex].tokens_count += 1; + }); + } + ); + }); + + return resultAttributesList; + } + + @SentryWrapper({ data: [], count: 0 }) + public async getCollectionAttributes( + queryArgs: AttributesV1QueryArgs + ): Promise> { + const result = { + data: [] as AttributeV1DTO[], + count: 0, + }; + + console.log('queryArgs', queryArgs); + + const collectionId = queryArgs.where.collection_id._eq; + + console.log('collectionId', collectionId); + + const qResult = await this.dataSource.query( + `SELECT attributes_schema FROM collections WHERE collection_id = ${collectionId}` + ); + + console.log('qResult', qResult); + + const collection = qResult[0]; + if (!collection) { + return result; + } + + const { attributes_schema: attributesSchema } = collection; + + result.data = await this.collectTokenCounts(collectionId, attributesSchema); + + result.count = result.data.length; + + return result; + } +} diff --git a/apps/web-api/src/collection/collection.dto.ts b/apps/web-api/src/collection/collection.dto.ts index e6304ab8..053dc576 100644 --- a/apps/web-api/src/collection/collection.dto.ts +++ b/apps/web-api/src/collection/collection.dto.ts @@ -1,6 +1,7 @@ import { Collections } from '@entities/Collections'; import { Field, Float, Int, ObjectType } from '@nestjs/graphql'; import { GraphQLJSON, GraphQLJSONObject } from 'graphql-type-json'; +import { IV2Collection } from '@unique-nft/substrate-client/tokens'; export enum CollectionEnum { collection_id = 'collection_id', @@ -104,4 +105,19 @@ export class CollectionDTO implements Partial { @Field(() => Boolean) burned?: boolean; + + @Field(() => GraphQLJSONObject, { nullable: true }) + schema_v2?: IV2Collection; + + @Field(() => String, { nullable: true }) + created_at_block_hash?: string; + + @Field(() => Int, { nullable: true }) + created_at_block_number?: number; + + @Field(() => String, { nullable: true }) + updated_at_block_hash?: string; + + @Field(() => Int, { nullable: true }) + updated_at_block_number?: number; } diff --git a/apps/web-api/src/collection/collection.resolver.types.ts b/apps/web-api/src/collection/collection.resolver.types.ts index 8f71cb72..02b5bc8d 100644 --- a/apps/web-api/src/collection/collection.resolver.types.ts +++ b/apps/web-api/src/collection/collection.resolver.types.ts @@ -65,6 +65,18 @@ export class CollectionWhereParams implements TWhereParams { @Field(() => [CollectionWhereParams], { nullable: true }) _or?: CollectionWhereParams[]; + + @Field(() => GQLWhereOpsInt, { nullable: true }) + created_at_block_number?: GQLWhereOpsInt; + + @Field(() => GQLWhereOpsString, { nullable: true }) + created_at_block_hash?: GQLWhereOpsString; + + @Field(() => GQLWhereOpsInt, { nullable: true }) + updated_at_block_number?: GQLWhereOpsInt; + + @Field(() => GQLWhereOpsString, { nullable: true }) + updated_at_block_hash?: GQLWhereOpsString; } @InputType() @@ -119,6 +131,12 @@ export class CollectionOrderByParams implements TOrderByParams { @Field(() => GQLOrderByParamsArgs, { nullable: true }) nesting_enabled?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + created_at_block_number?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + updated_at_block_number?: GQLOrderByParamsArgs; } @ArgsType() diff --git a/apps/web-api/src/collection/collection.service.ts b/apps/web-api/src/collection/collection.service.ts index c3ed6d51..89a01b6b 100644 --- a/apps/web-api/src/collection/collection.service.ts +++ b/apps/web-api/src/collection/collection.service.ts @@ -42,7 +42,7 @@ const customQueryFields = { export class CollectionService extends BaseService { constructor( @InjectRepository(Collections) private repo: Repository, - @Inject(forwardRef(() => TokenService)) private tokenService: TokenService, + @Inject(forwardRef(() => TokenService)) private tokenService: TokenService ) { super({ relationsFields, @@ -55,7 +55,7 @@ export class CollectionService extends BaseService { @SentryWrapper({ data: [], count: 0 }) public async find( queryArgs: IGQLQueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): Promise> { const qb = this.repo.createQueryBuilder(); @@ -66,7 +66,7 @@ export class CollectionService extends BaseService { public getCollectionById( id: number, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): Promise { const qb = this.repo.createQueryBuilder(); qb.where(`collection_id = :id`, { id }); @@ -101,7 +101,7 @@ export class CollectionService extends BaseService { private applyArgs( qb: SelectQueryBuilder, queryArgs: IGQLQueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): void { this.select(qb, queryArgs, queryInfo); @@ -110,7 +110,7 @@ export class CollectionService extends BaseService { this.applyWhereCondition( qb, queryArgs, - this.applyRelationFilter.bind(this), + this.applyRelationFilter.bind(this) ); this.applyDistinctOn(qb, queryArgs); } @@ -118,7 +118,7 @@ export class CollectionService extends BaseService { private applyRelationFilter( qb: SelectQueryBuilder, where: TWhere, - op?: OperatorMethods.AND, + op?: OperatorMethods.AND ) { const { query, params } = this.tokenService.getCollectionIdsQuery({ limit: null, @@ -133,7 +133,7 @@ export class CollectionService extends BaseService { private select( qb: SelectQueryBuilder, queryArgs: IGQLQueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): void { const queryFields = this.getQueryFields(queryInfo); diff --git a/apps/web-api/src/tokens/token.dto.ts b/apps/web-api/src/tokens/token.dto.ts index 8eb72cfc..0d1b3e4e 100644 --- a/apps/web-api/src/tokens/token.dto.ts +++ b/apps/web-api/src/tokens/token.dto.ts @@ -1,6 +1,8 @@ import { Tokens, TokenType } from '@entities/Tokens'; import { Field, Int, ObjectType } from '@nestjs/graphql'; import { GraphQLJSON, GraphQLJSONObject } from 'graphql-type-json'; +import { DecodedAttributes } from '@unique-nft/schemas'; +import { TokenWithInfoV2 } from '@unique-nft/substrate-client/tokens'; export enum TokenDistinctFieldsEnum { token_id = 'token_id', @@ -22,13 +24,16 @@ export class SimpleTokenDTO implements Partial { collection_id?: number; @Field(() => GraphQLJSONObject, { nullable: true }) - attributes?: object; + attributes_v1?: DecodedAttributes; @Field(() => GraphQLJSON, { nullable: true }) - properties?: object; + properties?: Array<{ key: string; value: string; valueHex: string }>; @Field(() => GraphQLJSONObject, { nullable: true }) - image?: object; + image_v1?: object; + + @Field(() => String, { nullable: true }) + image?: string; @Field(() => String) owner?: string; @@ -105,4 +110,19 @@ export class TokenDTO extends SimpleTokenDTO implements Partial { @Field(() => Int, { nullable: true }) transfers_count?: number; + + @Field(() => GraphQLJSONObject, { nullable: true }) + schema_v2?: TokenWithInfoV2; + + @Field(() => String, { nullable: true }) + created_at_block_hash?: string; + + @Field(() => Int, { nullable: true }) + created_at_block_number?: number; + + @Field(() => String, { nullable: true }) + updated_at_block_hash?: string; + + @Field(() => Int, { nullable: true }) + updated_at_block_number?: number; } diff --git a/apps/web-api/src/tokens/token.resolver.types.ts b/apps/web-api/src/tokens/token.resolver.types.ts index ef3d5b12..ddf36307 100644 --- a/apps/web-api/src/tokens/token.resolver.types.ts +++ b/apps/web-api/src/tokens/token.resolver.types.ts @@ -16,6 +16,7 @@ import { IWhereOperators, ListDataType, TOrderByParams, + TWhere, TWhereParams, } from '../utils/gql-query-args'; import { SimpleTokenDTO, TokenDistinctFieldsEnum, TokenDTO } from './token.dto'; @@ -38,7 +39,7 @@ export class GQLWhereTokensType { } @InputType() -export class AttributeFilterValue { +export class AttributeV1FilterValue { @Field({ description: "The 'key' of attribute from 'attributes' object from the attributes query", @@ -113,6 +114,18 @@ export class TokenWhereParams implements TWhereParams { @Field(() => [TokenWhereParams], { nullable: true }) _or?: TokenWhereParams[]; + + @Field(() => GQLWhereOpsInt, { nullable: true }) + created_at_block_number?: GQLWhereOpsInt; + + @Field(() => GQLWhereOpsString, { nullable: true }) + created_at_block_hash?: GQLWhereOpsString; + + @Field(() => GQLWhereOpsInt, { nullable: true }) + updated_at_block_number?: GQLWhereOpsInt; + + @Field(() => GQLWhereOpsString, { nullable: true }) + updated_at_block_hash?: GQLWhereOpsString; } @InputType() @@ -170,6 +183,12 @@ export class TokenOrderByParams implements TOrderByParams { @Field(() => GQLOrderByParamsArgs, { nullable: true }) amount?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + created_at_block_number?: GQLOrderByParamsArgs; + + @Field(() => GQLOrderByParamsArgs, { nullable: true }) + updated_at_block_number?: GQLOrderByParamsArgs; } @ArgsType() @@ -181,10 +200,10 @@ export class QueryArgs distinct_on?: TokenDistinctFieldsEnum; @Field(() => TokenWhereParams, { nullable: true }) - where?: TokenWhereParams; + where?: TWhereParams; - @Field(() => [AttributeFilterValue], { nullable: true }) - attributes_filter?: AttributeFilterValue[]; + @Field(() => [AttributeV1FilterValue], { nullable: true }) + attributes_v1_filter?: AttributeV1FilterValue[]; @Field(() => TokenOrderByParams, { nullable: true }) order_by?: TokenOrderByParams; diff --git a/apps/web-api/src/tokens/token.service.ts b/apps/web-api/src/tokens/token.service.ts index f49146f4..1b463d30 100644 --- a/apps/web-api/src/tokens/token.service.ts +++ b/apps/web-api/src/tokens/token.service.ts @@ -17,10 +17,12 @@ import { IRelations } from '../utils/base.service.types'; import { FieldsListOptions } from 'graphql-fields-list'; import { JOIN_TYPE } from '@common/constants'; import { TokensOwners } from '@entities/TokensOwners'; +import * as console from 'console'; const TOKENSOWNERS_RELATION_ALIAS = 'TokenOwners'; const COLLECTION_RELATION_ALIAS = 'Collection'; const STATISTICS_RELATION_ALIAS = 'Statistics'; +const ATTRIBUTES_RELATION_ALIAS = 'Attributes'; const relationsFields = { token_prefix: COLLECTION_RELATION_ALIAS, @@ -84,7 +86,7 @@ export class TokenService extends BaseService { @SentryWrapper({ data: [], count: 0 }) public async find( queryArgs: QueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): Promise> { const qb = this.repo.createQueryBuilder(); @@ -96,7 +98,7 @@ export class TokenService extends BaseService { @SentryWrapper({ data: [], count: 0 }) public async findBundles( queryArgs: QueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): Promise> { const qb = this.repo.createQueryBuilder(); @@ -111,16 +113,16 @@ export class TokenService extends BaseService { public async getBundleRoot( collection_id: number, token_id: number, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): Promise { const qb = this.repo.createQueryBuilder(); qb.where( new Brackets((qb) => { qb.where('parent_id is null').andWhere( - `"Tokens".children @> '[{"token_id": ${token_id}, "collection_id": ${collection_id}}]'::jsonb`, + `"Tokens".children @> '[{"token_id": ${token_id}, "collection_id": ${collection_id}}]'::jsonb` ); - }), + }) ); qb.orWhere( @@ -133,7 +135,7 @@ export class TokenService extends BaseService { collection_id, }) .andWhere(`"Tokens".nested = :nested`, { nested: true }); - }), + }) ); this.select(qb, {}, queryInfo, { skip: ['__*'] }); @@ -144,7 +146,7 @@ export class TokenService extends BaseService { public getByCollectionId( id: number, queryArgs: QueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ) { const qb = this.repo.createQueryBuilder(); @@ -174,7 +176,7 @@ export class TokenService extends BaseService { public findNestingChildren( collection_id: number, token_id: number, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ) { const qb = this.repo.createQueryBuilder(); @@ -213,7 +215,7 @@ export class TokenService extends BaseService { private applyArgs( qb: SelectQueryBuilder, queryArgs: QueryArgs, - queryInfo: GraphQLResolveInfo, + queryInfo: GraphQLResolveInfo ): void { this.select(qb, queryArgs, queryInfo); @@ -230,40 +232,40 @@ export class TokenService extends BaseService { private applyAttributesFilter( qb: SelectQueryBuilder, - queryArgs: QueryArgs, + queryArgs: QueryArgs ): void { - const attributesFilter = queryArgs?.attributes_filter; + const attributesV1Filter = queryArgs?.attributes_v1_filter; - if (!Array.isArray(attributesFilter)) { + if (!Array.isArray(attributesV1Filter)) { return; } qb.andWhere( new Brackets((qb) => { - attributesFilter.forEach(({ key, raw_value: rawValue }) => { + attributesV1Filter.forEach(({ key, raw_value: rawValue }) => { const rawValueParsed = JSON.parse(rawValue); if (typeof rawValueParsed === 'object') { // Text field in format {_: "value"} qb.andWhere( - `attributes->'${key}'->'rawValue'='${rawValue}'::jsonb`, + `attributes->'${key}'->'rawValue'='${rawValue}'::jsonb` ); } else { // Select and multiselect field qb.andWhere( new Brackets((qb) => { qb.where( - `attributes->'${key}'->>'rawValue'='${String(rawValue)}'`, + `attributes->'${key}'->>'rawValue'='${String(rawValue)}'` ).orWhere( // Search value in array // eslint-disable-next-line max-len - `attributes->'${key}'->>'rawValue' ~ '^\\[\\s*((\\S+\\s*,\\s*)|\\s*)*(${rawValue})((\\s*,\\s*\\S+)|\\s*)*\\]$'`, + `attributes->'${key}'->>'rawValue' ~ '^\\[\\s*((\\S+\\s*,\\s*)|\\s*)*(${rawValue})((\\s*,\\s*\\S+)|\\s*)*\\]$'` ); - }), + }) ); } }); - }), + }) ); } @@ -271,10 +273,12 @@ export class TokenService extends BaseService { qb: SelectQueryBuilder, queryArgs: QueryArgs, queryInfo: GraphQLResolveInfo, - queryFieldsOptions?: FieldsListOptions, + queryFieldsOptions?: FieldsListOptions ): void { const queryFields = this.getQueryFields(queryInfo, queryFieldsOptions); + console.log('queryFields', queryFields); + this.applySelect(qb, queryArgs, queryFields, tokensTableRelations); } } diff --git a/apps/web-api/src/utils/gql-query-args.ts b/apps/web-api/src/utils/gql-query-args.ts index 29deef6c..f52901c8 100644 --- a/apps/web-api/src/utils/gql-query-args.ts +++ b/apps/web-api/src/utils/gql-query-args.ts @@ -28,9 +28,9 @@ type TWhereOperations = { }[]; }; -export type TWhereParams = { +export type TWhereParams = Partial<{ [key in keyof T]: IWhereOperators; -}; +}>; export type TWhere = TWhereParams & TWhereOperations; @@ -52,9 +52,9 @@ export enum GQLOrderByParamsArgs { desc_nulls_last = 'desc_nulls_last', } -export type TOrderByParams = { +export type TOrderByParams = Partial<{ [key in keyof T]: GQLOrderByParamsArgs; -}; +}>; registerEnumType(GQLOrderByParamsArgs, { name: 'GQLOrderByParamsArgs', @@ -175,7 +175,7 @@ export function ListDataType(classRef: Type): Type> { } export function ListDataTypeOwner( - classRef: Type, + classRef: Type ): Type> { @ObjectType({ isAbstract: false }) class ListDataTypeOwner implements IDataListResponse { diff --git a/apps/web-api/src/utils/sentry.decorator.ts b/apps/web-api/src/utils/sentry.decorator.ts index f25dabde..b31c7081 100644 --- a/apps/web-api/src/utils/sentry.decorator.ts +++ b/apps/web-api/src/utils/sentry.decorator.ts @@ -15,7 +15,7 @@ export const SentryWrapper = (emptyResult?: Record) => { } catch (error) { const sentry = this.sentry as SentryService; sentry.instance().captureException(error); - logger.error(error); + logger.error(error, error.stack); if (emptyResult) { return emptyResult; } diff --git a/common/entities/Attribute.ts b/common/entities/Attribute.ts new file mode 100644 index 00000000..61bfea26 --- /dev/null +++ b/common/entities/Attribute.ts @@ -0,0 +1,85 @@ +import { + Column, + Entity, + Index, + ManyToOne, + PrimaryGeneratedColumn, + JoinColumn, +} from 'typeorm'; +import { Tokens } from './Tokens'; +import { Collections } from './Collections'; +import { TokenWithInfoV2 } from '@unique-nft/substrate-client/tokens'; + +export type IV2Attribute = TokenWithInfoV2['attributes'][0]; + +@Index('attributes_token_collection', ['token_id', 'collection_id']) +@Entity('attributes', { schema: 'public' }) +export class Attribute implements IV2Attribute { + @PrimaryGeneratedColumn({ type: 'bigint', name: 'id' }) + id: string; + + @Column('integer', { name: 'token_id' }) + token_id: number; + + @Column('bigint', { name: 'collection_id' }) + collection_id: number; + + @Column('text', { name: 'trait_type' }) + trait_type: string; + + @Column('text', { name: 'display_type', nullable: true }) + display_type: string | null; + + @Column('text', { name: 'value_string', nullable: true }) + value_string: string | null; + + @Column('integer', { name: 'value_number', nullable: true }) + value_number: number | null; + + get value(): string | number | null { + if (this.value_string !== null) { + return this.value_string; + } else if (this.value_number !== null) { + return this.value_number; + } + + return null; + } + + set value(val: string | number | null) { + if (typeof val === 'number') { + this.value_number = val; + this.value_string = null; + } else if (typeof val === 'string') { + this.value_string = val; + this.value_number = null; + } + } + + @ManyToOne(() => Tokens, (token) => token.attributes) + @JoinColumn([ + { name: 'token_id', referencedColumnName: 'token_id' }, + { name: 'collection_id', referencedColumnName: 'collection_id' }, + ]) + token: Tokens; + + @ManyToOne(() => Collections, (collection) => collection.attributes) + @JoinColumn([ + { name: 'collection_id', referencedColumnName: 'collection_id' }, + ]) + collection: Collections; + + static fromIV2Attribute( + attr: IV2Attribute, + ids: { collectionId: number; tokenId: number } + ): Attribute { + const attribute = new Attribute(); + attribute.collection_id = ids.collectionId; + attribute.token_id = ids.tokenId; + attribute.trait_type = attr.trait_type; + attribute.display_type = attr.display_type; + attribute.value = attr.value; + + return attribute; + } +} diff --git a/common/entities/Collections.ts b/common/entities/Collections.ts index f795d72b..d7ebf41d 100644 --- a/common/entities/Collections.ts +++ b/common/entities/Collections.ts @@ -1,4 +1,6 @@ -import { Column, Entity, Index } from 'typeorm'; +import { Column, Entity, Index, OneToMany } from 'typeorm'; +import { IV2Collection } from '@unique-nft/substrate-client/tokens'; +import { Attribute } from './Attribute'; @Index('collections_pkey', ['collection_id'], { unique: true }) @Index('collections_owner_normalized_idx', ['owner_normalized'], {}) @@ -22,6 +24,9 @@ export class Collections { @Column('bigint', { name: 'token_limit' }) token_limit: number; + @Column('jsonb', { name: 'schema_v2', default: null }) + schema_v2: IV2Collection | null; + @Column('jsonb', { name: 'properties', default: [] }) properties: object | null; @@ -92,6 +97,18 @@ export class Collections { @Column('bigint', { name: 'date_of_creation', nullable: true }) date_of_creation?: number; + @Column('text', { name: 'created_at_block_hash', nullable: true }) + created_at_block_hash?: string; + + @Column('bigint', { name: 'created_at_block_number', nullable: true }) + created_at_block_number?: number; + + @Column('text', { name: 'updated_at_block_hash', nullable: true }) + updated_at_block_hash?: string; + + @Column('bigint', { name: 'updated_at_block_number', nullable: true }) + updated_at_block_number?: number; + @Column('text', { name: 'owner_normalized' }) owner_normalized: string; @@ -104,4 +121,7 @@ export class Collections { @Column('boolean', { name: 'burned', default: false }) burned: boolean; + + @OneToMany(() => Attribute, (attribute) => attribute.collection) + attributes: Attribute[]; } diff --git a/common/entities/Tokens.ts b/common/entities/Tokens.ts index 46c80604..2007620e 100644 --- a/common/entities/Tokens.ts +++ b/common/entities/Tokens.ts @@ -1,4 +1,13 @@ -import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; +import { + Column, + Entity, + Index, + OneToMany, + PrimaryGeneratedColumn, +} from 'typeorm'; +import { DecodedAttributes } from '@unique-nft/schemas'; +import { TokenWithInfoV2 } from '@unique-nft/substrate-client/tokens'; +import { Attribute } from './Attribute'; export enum TokenType { NFT = 'NFT', @@ -31,13 +40,21 @@ export class Tokens { owner: string; @Column('jsonb', { name: 'properties', default: [] }) - properties: object; + properties: Array<{ key: string; value: string; valueHex: string }>; - @Column('jsonb', { name: 'attributes', nullable: true, default: null }) - attributes: object; + @Column('jsonb', { name: 'attributes_v1', nullable: true, default: null }) + attributes_v1: DecodedAttributes | null; - @Column('jsonb', { name: 'image', nullable: true, default: null }) - image: object; + @Column('text', { name: 'image', nullable: true }) + image: string | null; + + @Column('jsonb', { name: 'image_v1', nullable: true, default: null }) + image_v1: { + fullUrl?: string; + url?: string; + ipfsCid?: string; + urlInfix?: string; + } | null; @Column('bigint', { name: 'collection_id' }) collection_id: number; @@ -45,6 +62,18 @@ export class Tokens { @Column('bigint', { name: 'date_of_creation', nullable: true }) date_of_creation?: number; + @Column('text', { name: 'created_at_block_hash', nullable: true }) + created_at_block_hash?: string; + + @Column('bigint', { name: 'created_at_block_number', nullable: true }) + created_at_block_number?: number; + + @Column('text', { name: 'updated_at_block_hash', nullable: true }) + updated_at_block_hash?: string; + + @Column('bigint', { name: 'updated_at_block_number', nullable: true }) + updated_at_block_number?: number; + @Column('text', { name: 'owner_normalized' }) owner_normalized: string; @@ -83,4 +112,10 @@ export class Tokens { @Column('boolean', { name: 'nested', default: false }) nested: boolean; + + @Column('jsonb', { name: 'schema_v2', default: null }) + schema_v2: TokenWithInfoV2 | null; + + @OneToMany(() => Attribute, (attribute) => attribute.token) + attributes: Attribute[]; } diff --git a/common/entities/index.ts b/common/entities/index.ts new file mode 100644 index 00000000..0e9402d4 --- /dev/null +++ b/common/entities/index.ts @@ -0,0 +1,16 @@ +export { Account } from './Account'; +export { Block } from './Block'; +export { Chain } from './Chain'; +export { Collections } from './Collections'; +export { CollectionsStats } from './CollectionsStats'; +export { Contract } from './Contract'; +export { Event } from './Event'; +export { Extrinsic } from './Extrinsic'; +export { HarvesterError } from './HarvesterError'; +export { System } from './System'; +export { Tokens } from './Tokens'; +export { Total } from './Total'; +export { TokensStats } from './TokensStats'; +export { Attribute } from './Attribute'; +export { EvmTransaction } from './EvmTransaction'; +export { TokensOwners } from './TokensOwners'; diff --git a/common/sdk/sdk.service.ts b/common/sdk/sdk.service.ts index eaac3846..3c677212 100644 --- a/common/sdk/sdk.service.ts +++ b/common/sdk/sdk.service.ts @@ -1,4 +1,4 @@ -import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common'; +import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Cache } from 'cache-manager'; import { Client } from '@unique-nft/substrate-client'; @@ -7,6 +7,8 @@ import { PropertyKeyPermission, TokenByIdResult, TokenPropertiesResult, + TokenWithInfoV2, + CollectionWithInfoV2, } from '@unique-nft/substrate-client/tokens'; import { Config } from '../config/config.module'; import { SdkCache } from './sdk-cache.decorator'; @@ -14,7 +16,6 @@ import { TokenBalanceRequest } from '@unique-nft/substrate-client/refungible'; import { ChainProperties } from '@unique-nft/substrate-client/types'; import { ITotalIssuance } from '@common/constants'; -import * as console from 'console'; export interface ISpecSystemVersion { spec_version: number; @@ -26,17 +27,19 @@ export class SdkService { constructor( private sdk: Client, private configService: ConfigService, - @Inject(CACHE_MANAGER) private cacheManager: Cache, + @Inject(CACHE_MANAGER) private cacheManager: Cache ) {} - getLastBlockHash(): Promise { - return this.sdk.api.rpc.chain - .getHeader() - .then((header) => header.hash.toString()); + readonly logger = new Logger(SdkService.name); + + async getLastBlockHash(): Promise { + const header = await this.sdk.api.rpc.chain.getHeader(); + + return header.hash.toString(); } @SdkCache('getApi') - async getApi(hash) { + async getApi(hash: string) { const optionUpgrade = await this.sdk.api.query.system.events.at(hash); return optionUpgrade.toJSON(); } @@ -44,7 +47,7 @@ export class SdkService { @SdkCache('getCollection') async getCollection( collectionId: number, - at?: string, + at?: string ): Promise { if (at) { return this.sdk.collections.get({ collectionId, at }); @@ -54,10 +57,18 @@ export class SdkService { } } + @SdkCache('getCollectionV2') + async getCollectionV2( + collectionId: number, + at?: string + ): Promise { + return this.sdk.collections.getV2({ collectionId, at }); + } + @SdkCache('getSpecLastUpgrade') async getSpecLastUpgrade(hash: string): Promise { const optionUpgrade = await this.sdk.api.query.system.lastRuntimeUpgrade.at( - hash, + hash ); const specLastUpgrade = optionUpgrade.toJSON() as any; return { @@ -95,12 +106,27 @@ export class SdkService { async getToken( collectionId: number, tokenId: number, - at?: string, + at?: string ): Promise { - if (at) { - return await this.sdk.tokens.get({ collectionId, tokenId, at }); - } else { - return await this.sdk.tokens.get({ collectionId, tokenId }); + return await this.sdk.tokens.get({ collectionId, tokenId, at }); + } + + @SdkCache('getTokenV2') + async getTokenV2( + collectionId: number, + tokenId: number, + at?: string + ): Promise { + try { + return await this.sdk.tokens.getV2({ collectionId, tokenId, at }); + } catch (error) { + this.logger.error( + `Error getting token-v2 (${collectionId}/${tokenId} @ ${at || '-'}): ${ + error.message + }` + ); + + return null; } } @@ -124,7 +150,7 @@ export class SdkService { @SdkCache('getTokenProperties') getTokenProperties( collectionId: number, - tokenId: number, + tokenId: number ): Promise { return this.sdk.tokens.properties({ collectionId, tokenId }); } @@ -137,57 +163,36 @@ export class SdkService { @SdkCache('getRFTBalances') async getRFTBalances( tokenBalance: TokenBalanceRequest, - at?: string, - ): Promise { - const collection = await this.getCollection(tokenBalance.collectionId); - if (collection.mode === 'NFT') { - return { - amount: 0, // todo tak ne nado - }; - } + at?: string + ): Promise<{ amount: number }> { + const { collectionId, tokenId, address } = tokenBalance; + + const collection = await this.getCollection(collectionId); + if (collection.mode === 'ReFungible') { - let dataCheckNalance; - if (at) { - dataCheckNalance = { - address: `${tokenBalance.address}`, - collectionId: tokenBalance.collectionId, - tokenId: tokenBalance.tokenId, - at, - }; - } else { - dataCheckNalance = { - address: `${tokenBalance.address}`, - collectionId: tokenBalance.collectionId, - tokenId: tokenBalance.tokenId, - }; - } - return await this.sdk.refungible.getBalance(dataCheckNalance); + return await this.sdk.refungible.getBalance({ + collectionId, + tokenId, + address, + at, + }); } + + return { amount: 0 }; } @SdkCache('getTotalPieces') async getTotalPieces( tokenId: number, collectionId: number, - at?: string, - ): Promise { - if (at) { - return await this.sdk.refungible.totalPieces({ - tokenId, - collectionId, - at, - }); - } else { - return await this.sdk.refungible.totalPieces({ - tokenId, - collectionId, - }); - } + at?: string + ): Promise> { + return await this.sdk.refungible.totalPieces({ tokenId, collectionId, at }); } @SdkCache('getTotalSupply') async getTotalSupply(): Promise { - //return await this.sdk.api.query.balances.totalIssuance(); + // return await this.sdk.api.query.balances.totalIssuance(); return await this.sdk.stateQueries.execute({ endpoint: 'query', module: 'balances', diff --git a/common/typeorm.config.ts b/common/typeorm.config.ts index 25e3ecdc..e60ffc5e 100644 --- a/common/typeorm.config.ts +++ b/common/typeorm.config.ts @@ -1,21 +1,26 @@ -import { Account } from './entities/Account'; -import { Block } from './entities/Block'; -import { Chain } from './entities/Chain'; -import { Collections } from './entities/Collections'; -import { CollectionsStats } from './entities/CollectionsStats'; -import { Contract } from './entities/Contract'; -import { Event } from './entities/Event'; -import { Extrinsic } from './entities/Extrinsic'; -import { HarvesterError } from './entities/HarvesterError'; -import { System } from './entities/System'; -import { Tokens } from './entities/Tokens'; -import { Total } from './entities/Total'; -import { TokensStats } from './entities/TokensStats'; -import { EvmTransaction } from './entities/EvmTransaction'; -import { DataSourceOptions } from 'typeorm'; import * as dotenv from 'dotenv'; import * as path from 'path'; -import { TokensOwners } from './entities/TokensOwners'; + +import { DataSourceOptions } from 'typeorm'; + +import { + Account, + Attribute, + Block, + Chain, + Collections, + CollectionsStats, + Contract, + Event, + Extrinsic, + HarvesterError, + System, + Tokens, + Total, + TokensStats, + EvmTransaction, + TokensOwners, +} from './entities'; dotenv.config(); const migrationsDir = path.join(__dirname, '..', 'migrations'); @@ -30,6 +35,7 @@ const typeormConfig: DataSourceOptions = { database: process.env.POSTGRES_DATABASE, entities: [ Account, + Attribute, Block, Chain, Collections, diff --git a/common/utils.ts b/common/utils.ts index 21f5dc88..84ad6e06 100644 --- a/common/utils.ts +++ b/common/utils.ts @@ -42,11 +42,12 @@ export function sanitizeUnicodeString(str) { } export function sanitizePropertiesValues( - propertiesArr: { key: string; value: string }[], + propertiesArr: { key: string; value: string; valueHex: string }[] ) { - return propertiesArr.map(({ key, value }) => ({ + return propertiesArr.map(({ key, value, valueHex }) => ({ key, value: sanitizeUnicodeString(value), + valueHex: valueHex, })); } diff --git a/migrations/1709142009605-schemas-v2.ts b/migrations/1709142009605-schemas-v2.ts new file mode 100644 index 00000000..5e5cbda5 --- /dev/null +++ b/migrations/1709142009605-schemas-v2.ts @@ -0,0 +1,104 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class schemasV21709142009605 implements MigrationInterface { + name = 'schemasV21709142009605'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "attributes" ("id" BIGSERIAL NOT NULL, "token_id" integer NOT NULL, "collection_id" bigint NOT NULL, "trait_type" text NOT NULL, "display_type" text, "value_string" text, "value_number" integer, CONSTRAINT "PK_32216e2e61830211d3a5d7fa72c" PRIMARY KEY ("id"))` + ); + await queryRunner.query( + `CREATE INDEX "attributes_token_collection" ON "attributes" ("token_id", "collection_id") ` + ); + await queryRunner.query(`ALTER TABLE "collections" ADD "schema_v2" jsonb`); + await queryRunner.query( + `ALTER TABLE "collections" ADD "created_at_block_hash" text` + ); + await queryRunner.query( + `ALTER TABLE "collections" ADD "created_at_block_number" bigint` + ); + await queryRunner.query( + `ALTER TABLE "collections" ADD "updated_at_block_hash" text` + ); + await queryRunner.query( + `ALTER TABLE "collections" ADD "updated_at_block_number" bigint` + ); + + await queryRunner.query(`ALTER TABLE "tokens" ADD "schema_v2" jsonb`); + await queryRunner.query( + `ALTER TABLE "tokens" RENAME COLUMN "attributes" TO "attributes_v1"` + ); + await queryRunner.query( + `ALTER TABLE "tokens" RENAME COLUMN "image" TO "image_v1"` + ); + await queryRunner.query(`ALTER TABLE "tokens" ADD "image" text`); + await queryRunner.query( + `ALTER TABLE "tokens" ADD "created_at_block_hash" text` + ); + await queryRunner.query( + `ALTER TABLE "tokens" ADD "created_at_block_number" bigint` + ); + await queryRunner.query( + `ALTER TABLE "tokens" ADD "updated_at_block_hash" text` + ); + await queryRunner.query( + `ALTER TABLE "tokens" ADD "updated_at_block_number" bigint` + ); + + await queryRunner.query( + `ALTER TABLE "attributes" ADD CONSTRAINT "FK_aabb8d18b9092592b58cb04a464" FOREIGN KEY ("token_id", "collection_id") REFERENCES "tokens"("token_id","collection_id") ON DELETE NO ACTION ON UPDATE NO ACTION` + ); + + await queryRunner.query( + `ALTER TABLE "attributes" ADD CONSTRAINT "FK_9a2581e9e9299f68972a57b2bf6" FOREIGN KEY ("collection_id") REFERENCES "collections"("collection_id") ON DELETE NO ACTION ON UPDATE NO ACTION` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `DROP INDEX "public"."attributes_token_collection"` + ); + await queryRunner.query( + `ALTER TABLE "attributes" DROP CONSTRAINT "FK_9a2581e9e9299f68972a57b2bf6"` + ); + await queryRunner.query( + `ALTER TABLE "attributes" DROP CONSTRAINT "FK_aabb8d18b9092592b58cb04a464"` + ); + await queryRunner.query(`DROP TABLE "attributes"`); + await queryRunner.query( + `ALTER TABLE "collections" DROP COLUMN "schema_v2"` + ); + await queryRunner.query( + `ALTER TABLE "collections" DROP COLUMN "created_at_block_hash"` + ); + await queryRunner.query( + `ALTER TABLE "collections" DROP COLUMN "created_at_block_number"` + ); + await queryRunner.query( + `ALTER TABLE "collections" DROP COLUMN "updated_at_block_hash"` + ); + await queryRunner.query( + `ALTER TABLE "collections" DROP COLUMN "updated_at_block_number"` + ); + await queryRunner.query(`ALTER TABLE "tokens" DROP COLUMN "schema_v2"`); + await queryRunner.query( + `ALTER TABLE "tokens" RENAME COLUMN "attributes_v1" TO "attributes"` + ); + await queryRunner.query(`ALTER TABLE "tokens" DROP COLUMN "image"`); + await queryRunner.query( + `ALTER TABLE "tokens" RENAME COLUMN "image_v1" TO "image"` + ); + await queryRunner.query( + `ALTER TABLE "tokens" DROP COLUMN "created_at_block_hash"` + ); + await queryRunner.query( + `ALTER TABLE "tokens" DROP COLUMN "created_at_block_number"` + ); + await queryRunner.query( + `ALTER TABLE "tokens" DROP COLUMN "updated_at_block_hash"` + ); + await queryRunner.query( + `ALTER TABLE "tokens" DROP COLUMN "updated_at_block_number"` + ); + } +} diff --git a/package-lock.json b/package-lock.json index 9bcc22a2..e8f2f7a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "polkastats-backend-uniquenetwork", - "version": "2.0.69", + "version": "2.0.75", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "polkastats-backend-uniquenetwork", - "version": "2.0.69", + "version": "2.0.75", "license": "UNLICENSED", "dependencies": { "@nestjs/apollo": "^10.1.7", @@ -23,7 +23,7 @@ "@unique-nft/harvester": "^0.1.0", "@unique-nft/opal-testnet-types": "937.52.0", "@unique-nft/quartz-mainnet-types": "936.50.4", - "@unique-nft/substrate-client": "^0.8.13", + "@unique-nft/substrate-client": "^0.11.2", "@unique-nft/unique-mainnet-types": "^937.52.0", "@willsoto/nestjs-prometheus": "^5.1.0", "apollo-server-express": "^3.6.2", @@ -85,6 +85,25 @@ "typescript": "~4.8.4" } }, + "../unique-sdk/dist/packages/substrate-client": { + "name": "@unique-nft/substrate-client", + "version": "0.11.0", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@polkadot/api": "^10.9.1", + "@polkadot/types": "^10.9.1", + "@unique-nft/opal-testnet-types": "^1003.70.0", + "@unique-nft/quartz-mainnet-types": "^1003.70.0", + "@unique-nft/sapphire-mainnet-types": "^1003.70.0", + "@unique-nft/schemas": "^0.1.5", + "@unique-nft/schemas-v2": "npm:@unique-nft/schemas@^2.1.1", + "@unique-nft/unique-mainnet-types": "^1003.70.0", + "@unique-nft/utils": "^0.3.12", + "abi-coder": "^4.1.1", + "rxjs": "^7.0.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -3137,20 +3156,20 @@ } }, "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", "dependencies": { - "@noble/hashes": "1.3.2" + "@noble/hashes": "1.3.3" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", "engines": { "node": ">= 16" }, @@ -3272,6 +3291,79 @@ "node": ">=8" } }, + "node_modules/@polkadot-api/client": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/client/-/client-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-WDSMp8zKNdp6/MhbrkvS1QFn7G9sOrjv8CDHLg6SrH3MlHWAysEWRgAz6U0I9wKklmXR1tMZR+zJ3NuiTAE10A==", + "optional": true, + "dependencies": { + "@polkadot-api/metadata-builders": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-bindings": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + }, + "peerDependencies": { + "rxjs": ">=7.8.0" + } + }, + "node_modules/@polkadot-api/json-rpc-provider": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-772gcl5MXdmIvXuhJwVqM/APp+6f6ocRGfzcYoFfdghJ4A68l9ir1SDny691vcJXE8CQ7NAcz5Gl3t1Gz1MIqg==", + "optional": true + }, + "node_modules/@polkadot-api/json-rpc-provider-proxy": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-hzupcyUtObK6W1dyyeEp4BJBHRiGecB6t6YJQPk78UY1PnLsqFiboNh5doAywf+DoGBT1YXlxbYBAE3Wg43c9w==", + "optional": true + }, + "node_modules/@polkadot-api/metadata-builders": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-T4t2O5Nhr8yrfJtKF5+JaxGO2TY7uFxQK0N/gDp7rDglvluiWiAl5nRvXhFzI03JOAtJ7Ey6O+ezEL1YwCjbwA==", + "optional": true, + "dependencies": { + "@polkadot-api/substrate-bindings": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + } + }, + "node_modules/@polkadot-api/substrate-bindings": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-oAOAwYG7iW2BUgLMzCo//pq+8X/zm5BxDUgJFtG0vPb3leUMd5kKnJcn7hWv9H4vLhyicAVoOPJrEPd/Kzocag==", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.3.1", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@scure/base": "^1.1.1", + "scale-ts": "^1.4.3" + } + }, + "node_modules/@polkadot-api/substrate-bindings/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "optional": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-api/substrate-client": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-rHLhKLJxv9CSplu+tXOgpxBwYDXCh32xwbJcZqxMWlXkjoNI2OB9hulX/3GJ0NE/ngMh3DV1hrqNLmyc/8PU+A==", + "optional": true + }, + "node_modules/@polkadot-api/utils": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-H7hOfilvx65wYxMjAI130rK34GcAPzMEuoP5W693N0PsXYc1QeoEHSza5NSgoN1U4jGNzDBoxu0al2WGKo1B5g==", + "optional": true + }, "node_modules/@polkadot/api": { "version": "9.11.1", "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-9.11.1.tgz", @@ -4061,6 +4153,36 @@ "integrity": "sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg==", "optional": true }, + "node_modules/@substrate/connect-known-chains": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.0.9.tgz", + "integrity": "sha512-HN8qdtHZxs0ttc+ZUTm0apBNzVHx/Eo1zTGjxg7pn87/991lcGGcKQ+tyVsuLWNuraN+FaPUuiiW59TE11Ae4w==", + "optional": true + }, + "node_modules/@substrate/light-client-extension-helpers": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-0.0.3.tgz", + "integrity": "sha512-AkWX7Xpn0u8NdR7qAEwFzeobLvHiviqmsUTvN6wge8Rnlbk01Ftm2Ol8vdN6IhjWPTepF5MggibQVXKBUtZnZw==", + "optional": true, + "dependencies": { + "@polkadot-api/client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/json-rpc-provider": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/json-rpc-provider-proxy": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.0.7", + "rxjs": "^7.8.1" + }, + "peerDependencies": { + "smoldot": "2.x" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@substrate/connect-extension-protocol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz", + "integrity": "sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg==", + "optional": true + }, "node_modules/@substrate/smoldot-light": { "version": "0.7.9", "resolved": "https://registry.npmjs.org/@substrate/smoldot-light/-/smoldot-light-0.7.9.tgz", @@ -4072,9 +4194,9 @@ } }, "node_modules/@substrate/ss58-registry": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.43.0.tgz", - "integrity": "sha512-USEkXA46P9sqClL7PZv0QFsit4S8Im97wchKG0/H/9q3AT/S76r40UHfCr4Un7eBJPE23f7fU9BZ0ITpP9MCsA==" + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.46.0.tgz", + "integrity": "sha512-rBvWnlrBeFTd5LVG7oX3rOHzR16yqyffOFHKmUiVcblpXI3D89CXOvAljW9tWlA1H/2/FegaZnHPhdObPsvi+w==" }, "node_modules/@tootallnate/once": { "version": "2.0.0", @@ -4171,9 +4293,9 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", "dependencies": { "@types/node": "*" } @@ -4774,27 +4896,59 @@ "zod": "^3.21.4" } }, + "node_modules/@unique-nft/schemas-v2": { + "name": "@unique-nft/schemas", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@unique-nft/schemas/-/schemas-2.1.4.tgz", + "integrity": "sha512-Aa9pqKGdwa185KRcOZKnssht/nycTAyLP/TntnQx7g+ib9gXxJLBAAjWaLs/uPPTr2GeBLIR+VyablA/ksJE6A==", + "dependencies": { + "@unique-nft/utils": "^0.3.17", + "protobufjs": "^7.2.6", + "zod": "^3.22.4" + } + }, + "node_modules/@unique-nft/sr25519": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@unique-nft/sr25519/-/sr25519-0.0.2.tgz", + "integrity": "sha512-41DJwU8aX56MAlNgmhAOYaE3ie+7HoETsVhqv5d3Pk7dpr1Aezmzihl5fqfLDgx0XeD8Q1QHY9pYAmsNmgQd2A==", + "dependencies": { + "@noble/hashes": "^1.3.3", + "base-x": "^4.0.0" + } + }, + "node_modules/@unique-nft/sr25519/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@unique-nft/substrate-client": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/@unique-nft/substrate-client/-/substrate-client-0.8.13.tgz", - "integrity": "sha512-dHpWoBGbUJGoX/X0O0CBgG9rqyRPK9Eysh1V8am5xPWFL9c4R7HySXXaFiod+9/yFJ/rLfezqqsWf995mtftsw==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@unique-nft/substrate-client/-/substrate-client-0.11.2.tgz", + "integrity": "sha512-jqSfbapBApQgGbUAA9cdIOO9hIwRtXm7KpyxZPXNSwnBjfR+5Jxlt5N5sCSnVCbtRCXiiwWDVtFoX8y38uEAPw==", "dependencies": { "@polkadot/api": "^10.9.1", "@polkadot/types": "^10.9.1", - "@unique-nft/opal-testnet-types": "^943.61.0", - "@unique-nft/quartz-mainnet-types": "^943.61.0", - "@unique-nft/sapphire-mainnet-types": "^943.61.0", + "@unique-nft/opal-testnet-types": "^1003.70.0", + "@unique-nft/quartz-mainnet-types": "^1003.70.0", + "@unique-nft/sapphire-mainnet-types": "^1003.70.0", "@unique-nft/schemas": "^0.1.5", - "@unique-nft/unique-mainnet-types": "^943.61.0", + "@unique-nft/schemas-v2": "npm:@unique-nft/schemas@^2.1.4", + "@unique-nft/unique-mainnet-types": "^1003.70.0", "@unique-nft/utils": "^0.3.12", "abi-coder": "^4.1.1", "rxjs": "^7.0.0" } }, "node_modules/@unique-nft/substrate-client/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", "engines": { "node": ">= 16" }, @@ -4803,306 +4957,306 @@ } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/api": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.9.1.tgz", - "integrity": "sha512-ND/2UqZBWvtt4PfV03OStTKg0mxmPk4UpMAgJKutdgsz/wP9CYJ1KbjwFgPNekL9JnzbKQsWyQNPVrcw7kQk8A==", - "dependencies": { - "@polkadot/api-augment": "10.9.1", - "@polkadot/api-base": "10.9.1", - "@polkadot/api-derive": "10.9.1", - "@polkadot/keyring": "^12.3.1", - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/rpc-core": "10.9.1", - "@polkadot/rpc-provider": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/types-known": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.11.3.tgz", + "integrity": "sha512-V+zOMhDvH1g1WtWh0EN9nUQ/aJ9KItubzCbD9CTGHk/W8ZiYsTbKK0lT9C3itQV54d4GViXwIrylGjogKZGTXg==", + "dependencies": { + "@polkadot/api-augment": "10.11.3", + "@polkadot/api-base": "10.11.3", + "@polkadot/api-derive": "10.11.3", + "@polkadot/keyring": "^12.6.2", + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/rpc-provider": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/types-known": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "eventemitter3": "^5.0.1", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/api-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.9.1.tgz", - "integrity": "sha512-kRZZvCFVcN4hAH4dJ+Qzfdy27/4EEq3oLDf3ihj0LTVrAezSWcKPGE3EVFy+Mn6Lo4SUc7RVyoKvIUhSk2l4Dg==", - "dependencies": { - "@polkadot/api-base": "10.9.1", - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.11.3.tgz", + "integrity": "sha512-1D4KewvtWnq1nrmeaAbidhcmJnsPxEpSVklp+Or9qXJVQE/E7J0D57PD/TYg3Ti6gvzyDQdpOlp71PJU52aCJQ==", + "dependencies": { + "@polkadot/api-base": "10.11.3", + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/api-base": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.9.1.tgz", - "integrity": "sha512-Q3m2KzlceMK2kX8bhnUZWk3RT6emmijeeFZZQgCePpEcrSeNjnqG4qjuTPgkveaOkUT8MAoDc5Avuzcc2jlW9g==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.11.3.tgz", + "integrity": "sha512-HNK0MxD+6dwUuZtMDnU2E7TtMxTPqvXPxeDixBThMpX72XgTE1NkM2X8pwdEw0ElgBvbJ3cRqMDZyHfKM90ydg==", "dependencies": { - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/util": "^12.3.1", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/util": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/api-derive": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.9.1.tgz", - "integrity": "sha512-mRud1UZCFIc4Z63qAoGSIHh/foyUYADfy1RQYCmPpeFKfIdCIrHpd7xFdJXTOMYOS0BwlM6u4qli/ZT4XigezQ==", - "dependencies": { - "@polkadot/api": "10.9.1", - "@polkadot/api-augment": "10.9.1", - "@polkadot/api-base": "10.9.1", - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.11.3.tgz", + "integrity": "sha512-pnhnDCPEwneWrLgsMGNDm0ZM2imrDzHou7CPxWoyxWS5adyrYl7Ckat9Bs0D86bqh/Hj0w0+yzWmCN9YJgB/cQ==", + "dependencies": { + "@polkadot/api": "10.11.3", + "@polkadot/api-augment": "10.11.3", + "@polkadot/api-base": "10.11.3", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/keyring": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.5.1.tgz", - "integrity": "sha512-u6b+Q7wI6WY/vwmJS9uUHy/5hKZ226nTlVNmxjkj9GvrRsQvUSwS94163yHPJwiZJiIv5xK5m0rwCMyoYu+wjA==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.6.2.tgz", + "integrity": "sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw==", "dependencies": { - "@polkadot/util": "12.5.1", - "@polkadot/util-crypto": "12.5.1", + "@polkadot/util": "12.6.2", + "@polkadot/util-crypto": "12.6.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "@polkadot/util": "12.5.1", - "@polkadot/util-crypto": "12.5.1" + "@polkadot/util": "12.6.2", + "@polkadot/util-crypto": "12.6.2" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/networks": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.5.1.tgz", - "integrity": "sha512-PP6UUdzz6iHHZH4q96cUEhTcydHj16+61sqeaYEJSF6Q9iY+5WVWQ26+rdjmre/EBdrMQkSS/CKy73mO5z/JkQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.6.2.tgz", + "integrity": "sha512-1oWtZm1IvPWqvMrldVH6NI2gBoCndl5GEwx7lAuQWGr7eNL+6Bdc5K3Z9T0MzFvDGoi2/CBqjX9dRKo39pDC/w==", "dependencies": { - "@polkadot/util": "12.5.1", - "@substrate/ss58-registry": "^1.43.0", + "@polkadot/util": "12.6.2", + "@substrate/ss58-registry": "^1.44.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/rpc-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.9.1.tgz", - "integrity": "sha512-MaLHkNlyqN20ZRYr6uNd1BZr1OsrnX9qLAmsl0mcrri1vPGRH6VHjfFH1RBLkikpWD82v17g0l2hLwdV1ZHMcw==", - "dependencies": { - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.11.3.tgz", + "integrity": "sha512-0WHFrI4XltVa7B97Hn+SNX+dPH+T3lj1Sgc5oQRnM0eb3MT2eOC4yTARZmA8sebd9raS5rTmLoxLDyOydprwtw==", + "dependencies": { + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/rpc-core": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.9.1.tgz", - "integrity": "sha512-ZtA8B8SfXSAwVkBlCcKRHw0eSM7ec/sbiNOM5GasXPeRujUgT7lOwSH2GbUZSqe9RfRDMp6DvO9c2JoGc3LLWw==", - "dependencies": { - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/rpc-provider": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/util": "^12.3.1", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.11.3.tgz", + "integrity": "sha512-rqDvH/p4Si6wz77iGm2XG17AtGayLIZKSLhQ3Fyto/YKRBQBuJsPn2id8b4gKsJ6pj70tb3C3y8F73NT73KY2g==", + "dependencies": { + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/rpc-provider": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/util": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/rpc-provider": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.9.1.tgz", - "integrity": "sha512-4QzT2QzD+320+eT6b79sGAA85Tt3Bb8fQvse4r5Mom2iiBd2SO81vOhxSAOaIe4GUsw25VzFJmsbe7+OObItdg==", - "dependencies": { - "@polkadot/keyring": "^12.3.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-support": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", - "@polkadot/x-fetch": "^12.3.1", - "@polkadot/x-global": "^12.3.1", - "@polkadot/x-ws": "^12.3.1", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.11.3.tgz", + "integrity": "sha512-W9qf84KIqDCwGtE2hNEjpjfJxCB0ccvgbrFjLGQJ5qcoVQbfLaFIa6NkdLVX2mFYbT0/NPs02VcyBFY8NBG/ug==", + "dependencies": { + "@polkadot/keyring": "^12.6.2", + "@polkadot/types": "10.11.3", + "@polkadot/types-support": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", + "@polkadot/x-fetch": "^12.6.2", + "@polkadot/x-global": "^12.6.2", + "@polkadot/x-ws": "^12.6.2", "eventemitter3": "^5.0.1", - "mock-socket": "^9.2.1", - "nock": "^13.3.1", - "tslib": "^2.5.3" + "mock-socket": "^9.3.1", + "nock": "^13.5.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { - "@substrate/connect": "0.7.26" + "@substrate/connect": "0.8.7" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.9.1.tgz", - "integrity": "sha512-AG33i2ZGGfq7u+5rkAdGrXAQHHl844/Yv+junH5ZzX69xiCoWO1bH/yzDUNBdpki2GlACWvF9nLYh3F2tVF93w==", - "dependencies": { - "@polkadot/keyring": "^12.3.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.11.3.tgz", + "integrity": "sha512-SQGQp/MnNL1Cw+bqH2tyGpcQKa+up56p8rnRQYO8+yZVAjD+2digYQ0vYrVWZ3vwk0w0aiRc6MuIkOOq9KPU5A==", + "dependencies": { + "@polkadot/keyring": "^12.6.2", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.9.1.tgz", - "integrity": "sha512-OY9/jTMFRFqYdkUnfcGwqMLC64A0Q25bjvCuVQCVjsPFKE3wl0Kt5rNT01eV2UmLXrR6fY0xWbR2w80bLA7CIQ==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.11.3.tgz", + "integrity": "sha512-QVWvLnoK9qfJhWxV7E+itWo4zpQjz7Aco+Jmfdta/qKS4juYZQx8TGmxJfvB+p/xI/o8QewQh2lg3jlO5v2WOA==", "dependencies": { - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types-codec": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.9.1.tgz", - "integrity": "sha512-mJ5OegKGraY1FLvEa8FopRCr3pQrhDkcn5RNOjmgJQozENVeRaxhk0NwxYz7IojFvSDnKnc6lNQfKaaSe5pLHg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.11.3.tgz", + "integrity": "sha512-N2uEko2X7CixqFrF/sbmBi0T0UAfWca3t3HecpFIjn3gMky8ki6C+mqs5XsqZt6B+7Kh+Xds7SSxZaXeU9q5Qw==", "dependencies": { - "@polkadot/util": "^12.3.1", - "@polkadot/x-bigint": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/util": "^12.6.2", + "@polkadot/x-bigint": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types-create": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.9.1.tgz", - "integrity": "sha512-OVz50MGTTuiuVnRP/zAx4CTuLioc0hsiwNwqN2lNhmIJGtnQ4Vy/7mQRsIWehiYz6g0Vzzm5B3qWkTXO1NSN5w==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.11.3.tgz", + "integrity": "sha512-xb2MXcFxYar1DEpSRDunfMgfQoaSYyUcRr5TeFh1Zi0VZf3Zf3FsLKNfaEt3AFul1ZHwpIJO/R8KLeTSsgfK/A==", "dependencies": { - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types-known": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.9.1.tgz", - "integrity": "sha512-zCMVWc4pJtkbMFPu72bD4IhvV/gkHXPX3C5uu92WdmCfnn0vEIEsMKWlVXVVvQQZKAqvs/awpqIfrUtEViOGEA==", - "dependencies": { - "@polkadot/networks": "^12.3.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.11.3.tgz", + "integrity": "sha512-Mhq5kWMx+HWPzWp4ZSwXtHimd6laY3NYsamhb18+8fHi1ieYCUNn7o1LoEBQiJ6N2vB3Iy5NrshAaVRh6gFpow==", + "dependencies": { + "@polkadot/networks": "^12.6.2", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/types-support": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.9.1.tgz", - "integrity": "sha512-XsieuLDsszvMZQlleacQBfx07i/JkwQV/UxH9q8Hz7Okmaz9pEVEW1h3ka2/cPuC7a4l32JhaORBUYshBZNdJg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.11.3.tgz", + "integrity": "sha512-YqPgLcSUTq63dAPxzn5JYLOUFO6EA2lDDehAJ60kEXwZ7v8iuow7hZo/V/z2VWE1u/LI3NczsvRbpzfhISaZyg==", "dependencies": { - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/util": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.5.1.tgz", - "integrity": "sha512-fDBZL7D4/baMG09Qowseo884m3QBzErGkRWNBId1UjWR99kyex+cIY9fOSzmuQxo6nLdJlLHw1Nz2caN3+Bq0A==", - "dependencies": { - "@polkadot/x-bigint": "12.5.1", - "@polkadot/x-global": "12.5.1", - "@polkadot/x-textdecoder": "12.5.1", - "@polkadot/x-textencoder": "12.5.1", - "@types/bn.js": "^5.1.1", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.6.2.tgz", + "integrity": "sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw==", + "dependencies": { + "@polkadot/x-bigint": "12.6.2", + "@polkadot/x-global": "12.6.2", + "@polkadot/x-textdecoder": "12.6.2", + "@polkadot/x-textencoder": "12.6.2", + "@types/bn.js": "^5.1.5", "bn.js": "^5.2.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/util-crypto": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.5.1.tgz", - "integrity": "sha512-Y8ORbMcsM/VOqSG3DgqutRGQ8XXK+X9M3C8oOEI2Tji65ZsXbh9Yh+ryPLM0oBp/9vqOXjkLgZJbbVuQceOw0A==", - "dependencies": { - "@noble/curves": "^1.2.0", - "@noble/hashes": "^1.3.2", - "@polkadot/networks": "12.5.1", - "@polkadot/util": "12.5.1", - "@polkadot/wasm-crypto": "^7.2.2", - "@polkadot/wasm-util": "^7.2.2", - "@polkadot/x-bigint": "12.5.1", - "@polkadot/x-randomvalues": "12.5.1", - "@scure/base": "^1.1.3", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.6.2.tgz", + "integrity": "sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg==", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "12.6.2", + "@polkadot/util": "12.6.2", + "@polkadot/wasm-crypto": "^7.3.2", + "@polkadot/wasm-util": "^7.3.2", + "@polkadot/x-bigint": "12.6.2", + "@polkadot/x-randomvalues": "12.6.2", + "@scure/base": "^1.1.5", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "@polkadot/util": "12.5.1" + "@polkadot/util": "12.6.2" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-bridge": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.2.2.tgz", - "integrity": "sha512-CgNENd65DVYtackOVXXRA0D1RPoCv5+77IdBCf7kNqu6LeAnR4nfTI6qjaApUdN1xRweUsQjSH7tu7VjkMOA0A==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.3.2.tgz", + "integrity": "sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g==", "dependencies": { - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*", @@ -5110,19 +5264,19 @@ } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-crypto": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.2.2.tgz", - "integrity": "sha512-1ZY1rxUTawYm0m1zylvBMFovNIHYgG2v/XoASNp/EMG5c8FQIxCbhJRaTBA983GVq4lN/IAKREKEp9ZbLLqssA==", - "dependencies": { - "@polkadot/wasm-bridge": "7.2.2", - "@polkadot/wasm-crypto-asmjs": "7.2.2", - "@polkadot/wasm-crypto-init": "7.2.2", - "@polkadot/wasm-crypto-wasm": "7.2.2", - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.3.2.tgz", + "integrity": "sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw==", + "dependencies": { + "@polkadot/wasm-bridge": "7.3.2", + "@polkadot/wasm-crypto-asmjs": "7.3.2", + "@polkadot/wasm-crypto-init": "7.3.2", + "@polkadot/wasm-crypto-wasm": "7.3.2", + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*", @@ -5130,32 +5284,32 @@ } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-crypto-asmjs": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.2.tgz", - "integrity": "sha512-wKg+cpsWQCTSVhjlHuNeB/184rxKqY3vaklacbLOMbUXieIfuDBav5PJdzS3yeiVE60TpYaHW4iX/5OYHS82gg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.2.tgz", + "integrity": "sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q==", "dependencies": { - "tslib": "^2.6.1" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-crypto-init": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.2.tgz", - "integrity": "sha512-vD4iPIp9x+SssUIWUenxWLPw4BVIwhXHNMpsV81egK990tvpyIxL205/EF5QRb1mKn8WfWcNFm5tYwwh9NdnnA==", - "dependencies": { - "@polkadot/wasm-bridge": "7.2.2", - "@polkadot/wasm-crypto-asmjs": "7.2.2", - "@polkadot/wasm-crypto-wasm": "7.2.2", - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.2.tgz", + "integrity": "sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g==", + "dependencies": { + "@polkadot/wasm-bridge": "7.3.2", + "@polkadot/wasm-crypto-asmjs": "7.3.2", + "@polkadot/wasm-crypto-wasm": "7.3.2", + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*", @@ -5163,182 +5317,183 @@ } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-crypto-wasm": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.2.tgz", - "integrity": "sha512-3efoIB6jA3Hhv6k0YIBwCtlC8gCSWCk+R296yIXRLLr3cGN415KM/PO/d1JIXYI64lbrRzWRmZRhllw3jf6Atg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.2.tgz", + "integrity": "sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw==", "dependencies": { - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/wasm-util": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.2.2.tgz", - "integrity": "sha512-N/25960ifCc56sBlJZ2h5UBpEPvxBmMLgwYsl7CUuT+ea2LuJW9Xh8VHDN/guYXwmm92/KvuendYkEUykpm/JQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.3.2.tgz", + "integrity": "sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg==", "dependencies": { - "tslib": "^2.6.1" + "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { "@polkadot/util": "*" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-bigint": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.5.1.tgz", - "integrity": "sha512-Fw39eoN9v0sqxSzfSC5awaDVdzojIiE7d1hRSQgVSrES+8whWvtbYMR0qwbVhTuW7DvogHmye41P9xKMlXZysg==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.6.2.tgz", + "integrity": "sha512-HSIk60uFPX4GOFZSnIF7VYJz7WZA7tpFJsne7SzxOooRwMTWEtw3fUpFy5cYYOeLh17/kHH1Y7SVcuxzVLc74Q==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-fetch": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.5.1.tgz", - "integrity": "sha512-Bc019lOKCoQJrthiS+H3LwCahGtl5tNnb2HK7xe3DBQIUx9r2HsF/uEngNfMRUFkUYg5TPCLFbEWU8NIREBS1A==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.6.2.tgz", + "integrity": "sha512-8wM/Z9JJPWN1pzSpU7XxTI1ldj/AfC8hKioBlUahZ8gUiJaOF7K9XEFCrCDLis/A1BoOu7Ne6WMx/vsJJIbDWw==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "node-fetch": "^3.3.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-global": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.5.1.tgz", - "integrity": "sha512-6K0YtWEg0eXInDOihU5aSzeb1t9TiDdX9ZuRly+58ALSqw5kPZYmQLbzE1d8HWzyXRXK+YH65GtLzfMGqfYHmw==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.6.2.tgz", + "integrity": "sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g==", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-randomvalues": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.5.1.tgz", - "integrity": "sha512-UsMb1d+77EPNjW78BpHjZLIm4TaIpfqq89OhZP/6gDIoS2V9iE/AK3jOWKm1G7Y2F8XIoX1qzQpuMakjfagFoQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.6.2.tgz", + "integrity": "sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "@polkadot/util": "12.5.1", + "@polkadot/util": "12.6.2", "@polkadot/wasm-util": "*" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-textdecoder": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.5.1.tgz", - "integrity": "sha512-j2YZGWfwhMC8nHW3BXq10fAPY02ObLL/qoTjCMJ1Cmc/OGq18Ep7k9cXXbjFAq3wf3tUUewt/u/hStKCk3IvfQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.6.2.tgz", + "integrity": "sha512-M1Bir7tYvNappfpFWXOJcnxUhBUFWkUFIdJSyH0zs5LmFtFdbKAeiDXxSp2Swp5ddOZdZgPac294/o2TnQKN1w==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-textencoder": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.5.1.tgz", - "integrity": "sha512-1JNNpOGb4wD+c7zFuOqjibl49LPnHNr4rj4s3WflLUIZvOMY6euoDuN3ISjQSHCLlVSoH0sOCWA3qXZU4bCTDQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.6.2.tgz", + "integrity": "sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@polkadot/x-ws": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.5.1.tgz", - "integrity": "sha512-efNMhB3Lh6pW2iTipMkqwrjpuUtb3EwR/jYZftiIGo5tDPB7rqoMOp9s6KRFJEIUfZkLnMUtbkZ5fHzUJaCjmQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.6.2.tgz", + "integrity": "sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw==", "dependencies": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2", - "ws": "^8.14.1" + "ws": "^8.15.1" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@unique-nft/substrate-client/node_modules/@scure/base": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", - "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@unique-nft/substrate-client/node_modules/@substrate/connect": { - "version": "0.7.26", - "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.26.tgz", - "integrity": "sha512-uuGSiroGuKWj1+38n1kY5HReer5iL9bRwPCzuoLtqAOmI1fGI0hsSI2LlNQMAbfRgr7VRHXOk5MTuQf5ulsFRw==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.7.tgz", + "integrity": "sha512-kJLSqiwsAC8eHsPBwUyVpp6cogs1b/4jxTiRfoWbbndmSSEqn3qkcwmYPmZud4pyJFX7FMXwzH28XaPRBGTaQQ==", "optional": true, "dependencies": { - "@substrate/connect-extension-protocol": "^1.0.1", - "eventemitter3": "^4.0.7", - "smoldot": "1.0.4" + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.0.7", + "@substrate/light-client-extension-helpers": "^0.0.3", + "smoldot": "2.0.21" } }, - "node_modules/@unique-nft/substrate-client/node_modules/@substrate/connect/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "node_modules/@unique-nft/substrate-client/node_modules/@substrate/connect-extension-protocol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz", + "integrity": "sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg==", "optional": true }, "node_modules/@unique-nft/substrate-client/node_modules/@unique-nft/opal-testnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/opal-testnet-types/-/opal-testnet-types-943.61.0.tgz", - "integrity": "sha512-U+QyKPP9OXrRgt4zGKEPYm+6ocIFrBNH5VFf+Qh1dLUr+a9of+pXfdnVKA3zl8iSIU5oC0awUsE62w67hBpwdg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/opal-testnet-types/-/opal-testnet-types-1003.70.0.tgz", + "integrity": "sha512-vXJoV7cqwO21svd03DFL7bl8H77zFbJzgkUgNPLPbVA6YkZt+ZeDmbP9lKKPbNadB1DP84kOZPVvsbmzx7+Jxg==", "peerDependencies": { - "@polkadot/api": "^10.9.1", - "@polkadot/types": "^10.9.1" + "@polkadot/api": "^10.10.1", + "@polkadot/types": "^10.10.1" } }, "node_modules/@unique-nft/substrate-client/node_modules/@unique-nft/quartz-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/quartz-mainnet-types/-/quartz-mainnet-types-943.61.0.tgz", - "integrity": "sha512-QHfu+oZkf64+vu45DEZVTe1xznfBO7B856aaIMkmEy/Fo0VofNUyiKeV2a6LolDuLgALu9a9uQEXeqQwBwoeZg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/quartz-mainnet-types/-/quartz-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-qs5iwMcDpBeJ6mXzSAbMB6DY9NkdAqPD1KmekOVG9Vug+hKWvSlfW5ozd63O/J2h7iliqwL0WZjDdwvBNdcTNg==", "peerDependencies": { - "@polkadot/api": "^10.9.1", - "@polkadot/types": "^10.9.1" + "@polkadot/api": "^10.10.1", + "@polkadot/types": "^10.10.1" } }, "node_modules/@unique-nft/substrate-client/node_modules/@unique-nft/sapphire-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/sapphire-mainnet-types/-/sapphire-mainnet-types-943.61.0.tgz", - "integrity": "sha512-IaEb6Yf114b5Wjh06eGiB36f8LthSqLaBDcbniRX9lwOvywbpuqmkXfuyfol2kGYL87vUYWQoMKsX4BJpfIUDg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/sapphire-mainnet-types/-/sapphire-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-hEMpLDPZxUuGW+B90AxaF3Clw/kvGn20oao+Ejq4nrCNRF/2k3CjjuG1NScZVcPZuGgKPAkBPiHNSF9aRN6qFg==", "peerDependencies": { - "@polkadot/api": "^10.9.1", - "@polkadot/types": "^10.9.1" + "@polkadot/api": "^10.10.1", + "@polkadot/types": "^10.10.1" } }, "node_modules/@unique-nft/substrate-client/node_modules/@unique-nft/unique-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/unique-mainnet-types/-/unique-mainnet-types-943.61.0.tgz", - "integrity": "sha512-l8JQv9Lpg+1UbZsU/wmX/axIzDu6djFgoxIxu6unGdk9ZsIIzLJ3hkjmtoguwdp/ur1mElg2ubW4CAByUdVprA==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/unique-mainnet-types/-/unique-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-sIa5/T+EV7e5BinIZCPAVS+8noOcND9lIXXBjRIwFsfSEdw50jJ5fL0DIQabKqdA1S5jSfDTH2yT6GXLrh67hg==", "peerDependencies": { - "@polkadot/api": "^10.9.1", - "@polkadot/types": "^10.9.1" + "@polkadot/api": "^10.10.1", + "@polkadot/types": "^10.10.1" } }, "node_modules/@unique-nft/substrate-client/node_modules/eventemitter3": { @@ -5369,9 +5524,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@unique-nft/substrate-client/node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "engines": { "node": ">=10.0.0" }, @@ -5398,15 +5553,27 @@ } }, "node_modules/@unique-nft/utils": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@unique-nft/utils/-/utils-0.3.14.tgz", - "integrity": "sha512-GJWPaSCM5ZvKJOiLY53LlngBZGAzySk4mSkcWoCUftqgNaeCekOadCDBiy2jmRhIEKpxE6wDRW/gT+2S8JtjvA==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@unique-nft/utils/-/utils-0.3.17.tgz", + "integrity": "sha512-rKldHiI+qaTtYbwHc2mopHxM3O5YyyagpPTcqaZ7/TB7B0OIFUpylV6nfWzACn15mmf0kz0MwtUU4FrpsHofNA==", "dependencies": { - "@noble/hashes": "^1.1.2", + "@noble/hashes": "^1.3.3", + "@unique-nft/sr25519": "^0.0.2", "base-x": "^4.0.0", "utf-helpers": "^0.0.3" } }, + "node_modules/@unique-nft/utils/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -11562,9 +11729,9 @@ "dev": true }, "node_modules/mock-socket": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.2.1.tgz", - "integrity": "sha512-aw9F9T9G2zpGipLLhSNh6ZpgUyUl4frcVmRN08uE1NWPWg43Wx6+sGPDbQ7E5iFZZDJW5b5bypMeAEHqTbIFag==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", + "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", "engines": { "node": ">= 8" } @@ -11662,13 +11829,12 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "node_modules/nock": { - "version": "13.3.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.1.tgz", - "integrity": "sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", + "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.21", "propagate": "^2.0.0" }, "engines": { @@ -12459,9 +12625,9 @@ } }, "node_modules/protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -12959,6 +13125,12 @@ "node": ">=10" } }, + "node_modules/scale-ts": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.0.tgz", + "integrity": "sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q==", + "optional": true + }, "node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -13196,12 +13368,11 @@ "dev": true }, "node_modules/smoldot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-1.0.4.tgz", - "integrity": "sha512-N3TazI1C4GGrseFH/piWyZCCCRJTRx2QhDfrUKRT4SzILlW5m8ayZ3QTKICcz1C/536T9cbHHJyP7afxI6Mi1A==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.21.tgz", + "integrity": "sha512-XFpf3CQZ2BbFwVqKSyJHP7mbTDJxT3saRr/WfnfgWv+pbmA/J0e/LdfV/3A+jg7gNTEG06EAiDPtzN8ouXTLLw==", "optional": true, "dependencies": { - "pako": "^2.0.4", "ws": "^8.8.1" } }, @@ -17299,17 +17470,17 @@ } }, "@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", "requires": { - "@noble/hashes": "1.3.2" + "@noble/hashes": "1.3.3" }, "dependencies": { "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" } } }, @@ -17383,6 +17554,72 @@ } } }, + "@polkadot-api/client": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/client/-/client-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-WDSMp8zKNdp6/MhbrkvS1QFn7G9sOrjv8CDHLg6SrH3MlHWAysEWRgAz6U0I9wKklmXR1tMZR+zJ3NuiTAE10A==", + "optional": true, + "requires": { + "@polkadot-api/metadata-builders": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-bindings": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + } + }, + "@polkadot-api/json-rpc-provider": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-772gcl5MXdmIvXuhJwVqM/APp+6f6ocRGfzcYoFfdghJ4A68l9ir1SDny691vcJXE8CQ7NAcz5Gl3t1Gz1MIqg==", + "optional": true + }, + "@polkadot-api/json-rpc-provider-proxy": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-hzupcyUtObK6W1dyyeEp4BJBHRiGecB6t6YJQPk78UY1PnLsqFiboNh5doAywf+DoGBT1YXlxbYBAE3Wg43c9w==", + "optional": true + }, + "@polkadot-api/metadata-builders": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-T4t2O5Nhr8yrfJtKF5+JaxGO2TY7uFxQK0N/gDp7rDglvluiWiAl5nRvXhFzI03JOAtJ7Ey6O+ezEL1YwCjbwA==", + "optional": true, + "requires": { + "@polkadot-api/substrate-bindings": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0" + } + }, + "@polkadot-api/substrate-bindings": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-oAOAwYG7iW2BUgLMzCo//pq+8X/zm5BxDUgJFtG0vPb3leUMd5kKnJcn7hWv9H4vLhyicAVoOPJrEPd/Kzocag==", + "optional": true, + "requires": { + "@noble/hashes": "^1.3.1", + "@polkadot-api/utils": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@scure/base": "^1.1.1", + "scale-ts": "^1.4.3" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "optional": true + } + } + }, + "@polkadot-api/substrate-client": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-rHLhKLJxv9CSplu+tXOgpxBwYDXCh32xwbJcZqxMWlXkjoNI2OB9hulX/3GJ0NE/ngMh3DV1hrqNLmyc/8PU+A==", + "optional": true + }, + "@polkadot-api/utils": { + "version": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0.tgz", + "integrity": "sha512-H7hOfilvx65wYxMjAI130rK34GcAPzMEuoP5W693N0PsXYc1QeoEHSza5NSgoN1U4jGNzDBoxu0al2WGKo1B5g==", + "optional": true + }, "@polkadot/api": { "version": "9.11.1", "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-9.11.1.tgz", @@ -18017,6 +18254,35 @@ "integrity": "sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg==", "optional": true }, + "@substrate/connect-known-chains": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.0.9.tgz", + "integrity": "sha512-HN8qdtHZxs0ttc+ZUTm0apBNzVHx/Eo1zTGjxg7pn87/991lcGGcKQ+tyVsuLWNuraN+FaPUuiiW59TE11Ae4w==", + "optional": true + }, + "@substrate/light-client-extension-helpers": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-0.0.3.tgz", + "integrity": "sha512-AkWX7Xpn0u8NdR7qAEwFzeobLvHiviqmsUTvN6wge8Rnlbk01Ftm2Ol8vdN6IhjWPTepF5MggibQVXKBUtZnZw==", + "optional": true, + "requires": { + "@polkadot-api/client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/json-rpc-provider": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/json-rpc-provider-proxy": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@polkadot-api/substrate-client": "0.0.1-12c4b0432a814086c3c1a3b8052b31c72c2c9ad3.1.0", + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.0.7", + "rxjs": "^7.8.1" + }, + "dependencies": { + "@substrate/connect-extension-protocol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz", + "integrity": "sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg==", + "optional": true + } + } + }, "@substrate/smoldot-light": { "version": "0.7.9", "resolved": "https://registry.npmjs.org/@substrate/smoldot-light/-/smoldot-light-0.7.9.tgz", @@ -18028,9 +18294,9 @@ } }, "@substrate/ss58-registry": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.43.0.tgz", - "integrity": "sha512-USEkXA46P9sqClL7PZv0QFsit4S8Im97wchKG0/H/9q3AT/S76r40UHfCr4Un7eBJPE23f7fU9BZ0ITpP9MCsA==" + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.46.0.tgz", + "integrity": "sha512-rBvWnlrBeFTd5LVG7oX3rOHzR16yqyffOFHKmUiVcblpXI3D89CXOvAljW9tWlA1H/2/FegaZnHPhdObPsvi+w==" }, "@tootallnate/once": { "version": "2.0.0", @@ -18124,9 +18390,9 @@ } }, "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", "requires": { "@types/node": "*" } @@ -18621,428 +18887,454 @@ "zod": "^3.21.4" } }, + "@unique-nft/schemas-v2": { + "version": "npm:@unique-nft/schemas@2.1.4", + "resolved": "https://registry.npmjs.org/@unique-nft/schemas/-/schemas-2.1.4.tgz", + "integrity": "sha512-Aa9pqKGdwa185KRcOZKnssht/nycTAyLP/TntnQx7g+ib9gXxJLBAAjWaLs/uPPTr2GeBLIR+VyablA/ksJE6A==", + "requires": { + "@unique-nft/utils": "^0.3.17", + "protobufjs": "^7.2.6", + "zod": "^3.22.4" + } + }, + "@unique-nft/sr25519": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@unique-nft/sr25519/-/sr25519-0.0.2.tgz", + "integrity": "sha512-41DJwU8aX56MAlNgmhAOYaE3ie+7HoETsVhqv5d3Pk7dpr1Aezmzihl5fqfLDgx0XeD8Q1QHY9pYAmsNmgQd2A==", + "requires": { + "@noble/hashes": "^1.3.3", + "base-x": "^4.0.0" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" + } + } + }, "@unique-nft/substrate-client": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/@unique-nft/substrate-client/-/substrate-client-0.8.13.tgz", - "integrity": "sha512-dHpWoBGbUJGoX/X0O0CBgG9rqyRPK9Eysh1V8am5xPWFL9c4R7HySXXaFiod+9/yFJ/rLfezqqsWf995mtftsw==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@unique-nft/substrate-client/-/substrate-client-0.11.2.tgz", + "integrity": "sha512-jqSfbapBApQgGbUAA9cdIOO9hIwRtXm7KpyxZPXNSwnBjfR+5Jxlt5N5sCSnVCbtRCXiiwWDVtFoX8y38uEAPw==", "requires": { "@polkadot/api": "^10.9.1", "@polkadot/types": "^10.9.1", - "@unique-nft/opal-testnet-types": "^943.61.0", - "@unique-nft/quartz-mainnet-types": "^943.61.0", - "@unique-nft/sapphire-mainnet-types": "^943.61.0", + "@unique-nft/opal-testnet-types": "^1003.70.0", + "@unique-nft/quartz-mainnet-types": "^1003.70.0", + "@unique-nft/sapphire-mainnet-types": "^1003.70.0", "@unique-nft/schemas": "^0.1.5", - "@unique-nft/unique-mainnet-types": "^943.61.0", + "@unique-nft/schemas-v2": "npm:@unique-nft/schemas@^2.1.4", + "@unique-nft/unique-mainnet-types": "^1003.70.0", "@unique-nft/utils": "^0.3.12", "abi-coder": "^4.1.1", "rxjs": "^7.0.0" }, "dependencies": { "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" }, "@polkadot/api": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.9.1.tgz", - "integrity": "sha512-ND/2UqZBWvtt4PfV03OStTKg0mxmPk4UpMAgJKutdgsz/wP9CYJ1KbjwFgPNekL9JnzbKQsWyQNPVrcw7kQk8A==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.11.3.tgz", + "integrity": "sha512-V+zOMhDvH1g1WtWh0EN9nUQ/aJ9KItubzCbD9CTGHk/W8ZiYsTbKK0lT9C3itQV54d4GViXwIrylGjogKZGTXg==", "requires": { - "@polkadot/api-augment": "10.9.1", - "@polkadot/api-base": "10.9.1", - "@polkadot/api-derive": "10.9.1", - "@polkadot/keyring": "^12.3.1", - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/rpc-core": "10.9.1", - "@polkadot/rpc-provider": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/types-known": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "@polkadot/api-augment": "10.11.3", + "@polkadot/api-base": "10.11.3", + "@polkadot/api-derive": "10.11.3", + "@polkadot/keyring": "^12.6.2", + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/rpc-provider": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/types-known": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "eventemitter3": "^5.0.1", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" } }, "@polkadot/api-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.9.1.tgz", - "integrity": "sha512-kRZZvCFVcN4hAH4dJ+Qzfdy27/4EEq3oLDf3ihj0LTVrAezSWcKPGE3EVFy+Mn6Lo4SUc7RVyoKvIUhSk2l4Dg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.11.3.tgz", + "integrity": "sha512-1D4KewvtWnq1nrmeaAbidhcmJnsPxEpSVklp+Or9qXJVQE/E7J0D57PD/TYg3Ti6gvzyDQdpOlp71PJU52aCJQ==", "requires": { - "@polkadot/api-base": "10.9.1", - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/api-base": "10.11.3", + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/api-base": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.9.1.tgz", - "integrity": "sha512-Q3m2KzlceMK2kX8bhnUZWk3RT6emmijeeFZZQgCePpEcrSeNjnqG4qjuTPgkveaOkUT8MAoDc5Avuzcc2jlW9g==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.11.3.tgz", + "integrity": "sha512-HNK0MxD+6dwUuZtMDnU2E7TtMxTPqvXPxeDixBThMpX72XgTE1NkM2X8pwdEw0ElgBvbJ3cRqMDZyHfKM90ydg==", "requires": { - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/util": "^12.3.1", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/util": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" } }, "@polkadot/api-derive": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.9.1.tgz", - "integrity": "sha512-mRud1UZCFIc4Z63qAoGSIHh/foyUYADfy1RQYCmPpeFKfIdCIrHpd7xFdJXTOMYOS0BwlM6u4qli/ZT4XigezQ==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.11.3.tgz", + "integrity": "sha512-pnhnDCPEwneWrLgsMGNDm0ZM2imrDzHou7CPxWoyxWS5adyrYl7Ckat9Bs0D86bqh/Hj0w0+yzWmCN9YJgB/cQ==", "requires": { - "@polkadot/api": "10.9.1", - "@polkadot/api-augment": "10.9.1", - "@polkadot/api-base": "10.9.1", - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "@polkadot/api": "10.11.3", + "@polkadot/api-augment": "10.11.3", + "@polkadot/api-base": "10.11.3", + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" } }, "@polkadot/keyring": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.5.1.tgz", - "integrity": "sha512-u6b+Q7wI6WY/vwmJS9uUHy/5hKZ226nTlVNmxjkj9GvrRsQvUSwS94163yHPJwiZJiIv5xK5m0rwCMyoYu+wjA==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.6.2.tgz", + "integrity": "sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw==", "requires": { - "@polkadot/util": "12.5.1", - "@polkadot/util-crypto": "12.5.1", + "@polkadot/util": "12.6.2", + "@polkadot/util-crypto": "12.6.2", "tslib": "^2.6.2" } }, "@polkadot/networks": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.5.1.tgz", - "integrity": "sha512-PP6UUdzz6iHHZH4q96cUEhTcydHj16+61sqeaYEJSF6Q9iY+5WVWQ26+rdjmre/EBdrMQkSS/CKy73mO5z/JkQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.6.2.tgz", + "integrity": "sha512-1oWtZm1IvPWqvMrldVH6NI2gBoCndl5GEwx7lAuQWGr7eNL+6Bdc5K3Z9T0MzFvDGoi2/CBqjX9dRKo39pDC/w==", "requires": { - "@polkadot/util": "12.5.1", - "@substrate/ss58-registry": "^1.43.0", + "@polkadot/util": "12.6.2", + "@substrate/ss58-registry": "^1.44.0", "tslib": "^2.6.2" } }, "@polkadot/rpc-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.9.1.tgz", - "integrity": "sha512-MaLHkNlyqN20ZRYr6uNd1BZr1OsrnX9qLAmsl0mcrri1vPGRH6VHjfFH1RBLkikpWD82v17g0l2hLwdV1ZHMcw==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.11.3.tgz", + "integrity": "sha512-0WHFrI4XltVa7B97Hn+SNX+dPH+T3lj1Sgc5oQRnM0eb3MT2eOC4yTARZmA8sebd9raS5rTmLoxLDyOydprwtw==", "requires": { - "@polkadot/rpc-core": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/rpc-core": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/rpc-core": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.9.1.tgz", - "integrity": "sha512-ZtA8B8SfXSAwVkBlCcKRHw0eSM7ec/sbiNOM5GasXPeRujUgT7lOwSH2GbUZSqe9RfRDMp6DvO9c2JoGc3LLWw==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.11.3.tgz", + "integrity": "sha512-rqDvH/p4Si6wz77iGm2XG17AtGayLIZKSLhQ3Fyto/YKRBQBuJsPn2id8b4gKsJ6pj70tb3C3y8F73NT73KY2g==", "requires": { - "@polkadot/rpc-augment": "10.9.1", - "@polkadot/rpc-provider": "10.9.1", - "@polkadot/types": "10.9.1", - "@polkadot/util": "^12.3.1", + "@polkadot/rpc-augment": "10.11.3", + "@polkadot/rpc-provider": "10.11.3", + "@polkadot/types": "10.11.3", + "@polkadot/util": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" } }, "@polkadot/rpc-provider": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.9.1.tgz", - "integrity": "sha512-4QzT2QzD+320+eT6b79sGAA85Tt3Bb8fQvse4r5Mom2iiBd2SO81vOhxSAOaIe4GUsw25VzFJmsbe7+OObItdg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.11.3.tgz", + "integrity": "sha512-W9qf84KIqDCwGtE2hNEjpjfJxCB0ccvgbrFjLGQJ5qcoVQbfLaFIa6NkdLVX2mFYbT0/NPs02VcyBFY8NBG/ug==", "requires": { - "@polkadot/keyring": "^12.3.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-support": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", - "@polkadot/x-fetch": "^12.3.1", - "@polkadot/x-global": "^12.3.1", - "@polkadot/x-ws": "^12.3.1", - "@substrate/connect": "0.7.26", + "@polkadot/keyring": "^12.6.2", + "@polkadot/types": "10.11.3", + "@polkadot/types-support": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", + "@polkadot/x-fetch": "^12.6.2", + "@polkadot/x-global": "^12.6.2", + "@polkadot/x-ws": "^12.6.2", + "@substrate/connect": "0.8.7", "eventemitter3": "^5.0.1", - "mock-socket": "^9.2.1", - "nock": "^13.3.1", - "tslib": "^2.5.3" + "mock-socket": "^9.3.1", + "nock": "^13.5.0", + "tslib": "^2.6.2" } }, "@polkadot/types": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.9.1.tgz", - "integrity": "sha512-AG33i2ZGGfq7u+5rkAdGrXAQHHl844/Yv+junH5ZzX69xiCoWO1bH/yzDUNBdpki2GlACWvF9nLYh3F2tVF93w==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.11.3.tgz", + "integrity": "sha512-SQGQp/MnNL1Cw+bqH2tyGpcQKa+up56p8rnRQYO8+yZVAjD+2digYQ0vYrVWZ3vwk0w0aiRc6MuIkOOq9KPU5A==", "requires": { - "@polkadot/keyring": "^12.3.1", - "@polkadot/types-augment": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/util": "^12.3.1", - "@polkadot/util-crypto": "^12.3.1", + "@polkadot/keyring": "^12.6.2", + "@polkadot/types-augment": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/util": "^12.6.2", + "@polkadot/util-crypto": "^12.6.2", "rxjs": "^7.8.1", - "tslib": "^2.5.3" + "tslib": "^2.6.2" } }, "@polkadot/types-augment": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.9.1.tgz", - "integrity": "sha512-OY9/jTMFRFqYdkUnfcGwqMLC64A0Q25bjvCuVQCVjsPFKE3wl0Kt5rNT01eV2UmLXrR6fY0xWbR2w80bLA7CIQ==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.11.3.tgz", + "integrity": "sha512-QVWvLnoK9qfJhWxV7E+itWo4zpQjz7Aco+Jmfdta/qKS4juYZQx8TGmxJfvB+p/xI/o8QewQh2lg3jlO5v2WOA==", "requires": { - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/types-codec": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.9.1.tgz", - "integrity": "sha512-mJ5OegKGraY1FLvEa8FopRCr3pQrhDkcn5RNOjmgJQozENVeRaxhk0NwxYz7IojFvSDnKnc6lNQfKaaSe5pLHg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.11.3.tgz", + "integrity": "sha512-N2uEko2X7CixqFrF/sbmBi0T0UAfWca3t3HecpFIjn3gMky8ki6C+mqs5XsqZt6B+7Kh+Xds7SSxZaXeU9q5Qw==", "requires": { - "@polkadot/util": "^12.3.1", - "@polkadot/x-bigint": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/util": "^12.6.2", + "@polkadot/x-bigint": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/types-create": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.9.1.tgz", - "integrity": "sha512-OVz50MGTTuiuVnRP/zAx4CTuLioc0hsiwNwqN2lNhmIJGtnQ4Vy/7mQRsIWehiYz6g0Vzzm5B3qWkTXO1NSN5w==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.11.3.tgz", + "integrity": "sha512-xb2MXcFxYar1DEpSRDunfMgfQoaSYyUcRr5TeFh1Zi0VZf3Zf3FsLKNfaEt3AFul1ZHwpIJO/R8KLeTSsgfK/A==", "requires": { - "@polkadot/types-codec": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/types-codec": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/types-known": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.9.1.tgz", - "integrity": "sha512-zCMVWc4pJtkbMFPu72bD4IhvV/gkHXPX3C5uu92WdmCfnn0vEIEsMKWlVXVVvQQZKAqvs/awpqIfrUtEViOGEA==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.11.3.tgz", + "integrity": "sha512-Mhq5kWMx+HWPzWp4ZSwXtHimd6laY3NYsamhb18+8fHi1ieYCUNn7o1LoEBQiJ6N2vB3Iy5NrshAaVRh6gFpow==", "requires": { - "@polkadot/networks": "^12.3.1", - "@polkadot/types": "10.9.1", - "@polkadot/types-codec": "10.9.1", - "@polkadot/types-create": "10.9.1", - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/networks": "^12.6.2", + "@polkadot/types": "10.11.3", + "@polkadot/types-codec": "10.11.3", + "@polkadot/types-create": "10.11.3", + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/types-support": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.9.1.tgz", - "integrity": "sha512-XsieuLDsszvMZQlleacQBfx07i/JkwQV/UxH9q8Hz7Okmaz9pEVEW1h3ka2/cPuC7a4l32JhaORBUYshBZNdJg==", + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.11.3.tgz", + "integrity": "sha512-YqPgLcSUTq63dAPxzn5JYLOUFO6EA2lDDehAJ60kEXwZ7v8iuow7hZo/V/z2VWE1u/LI3NczsvRbpzfhISaZyg==", "requires": { - "@polkadot/util": "^12.3.1", - "tslib": "^2.5.3" + "@polkadot/util": "^12.6.2", + "tslib": "^2.6.2" } }, "@polkadot/util": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.5.1.tgz", - "integrity": "sha512-fDBZL7D4/baMG09Qowseo884m3QBzErGkRWNBId1UjWR99kyex+cIY9fOSzmuQxo6nLdJlLHw1Nz2caN3+Bq0A==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.6.2.tgz", + "integrity": "sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw==", "requires": { - "@polkadot/x-bigint": "12.5.1", - "@polkadot/x-global": "12.5.1", - "@polkadot/x-textdecoder": "12.5.1", - "@polkadot/x-textencoder": "12.5.1", - "@types/bn.js": "^5.1.1", + "@polkadot/x-bigint": "12.6.2", + "@polkadot/x-global": "12.6.2", + "@polkadot/x-textdecoder": "12.6.2", + "@polkadot/x-textencoder": "12.6.2", + "@types/bn.js": "^5.1.5", "bn.js": "^5.2.1", "tslib": "^2.6.2" } }, "@polkadot/util-crypto": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.5.1.tgz", - "integrity": "sha512-Y8ORbMcsM/VOqSG3DgqutRGQ8XXK+X9M3C8oOEI2Tji65ZsXbh9Yh+ryPLM0oBp/9vqOXjkLgZJbbVuQceOw0A==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.6.2.tgz", + "integrity": "sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg==", "requires": { - "@noble/curves": "^1.2.0", - "@noble/hashes": "^1.3.2", - "@polkadot/networks": "12.5.1", - "@polkadot/util": "12.5.1", - "@polkadot/wasm-crypto": "^7.2.2", - "@polkadot/wasm-util": "^7.2.2", - "@polkadot/x-bigint": "12.5.1", - "@polkadot/x-randomvalues": "12.5.1", - "@scure/base": "^1.1.3", + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "12.6.2", + "@polkadot/util": "12.6.2", + "@polkadot/wasm-crypto": "^7.3.2", + "@polkadot/wasm-util": "^7.3.2", + "@polkadot/x-bigint": "12.6.2", + "@polkadot/x-randomvalues": "12.6.2", + "@scure/base": "^1.1.5", "tslib": "^2.6.2" } }, "@polkadot/wasm-bridge": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.2.2.tgz", - "integrity": "sha512-CgNENd65DVYtackOVXXRA0D1RPoCv5+77IdBCf7kNqu6LeAnR4nfTI6qjaApUdN1xRweUsQjSH7tu7VjkMOA0A==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.3.2.tgz", + "integrity": "sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g==", "requires": { - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" } }, "@polkadot/wasm-crypto": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.2.2.tgz", - "integrity": "sha512-1ZY1rxUTawYm0m1zylvBMFovNIHYgG2v/XoASNp/EMG5c8FQIxCbhJRaTBA983GVq4lN/IAKREKEp9ZbLLqssA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.3.2.tgz", + "integrity": "sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw==", "requires": { - "@polkadot/wasm-bridge": "7.2.2", - "@polkadot/wasm-crypto-asmjs": "7.2.2", - "@polkadot/wasm-crypto-init": "7.2.2", - "@polkadot/wasm-crypto-wasm": "7.2.2", - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-bridge": "7.3.2", + "@polkadot/wasm-crypto-asmjs": "7.3.2", + "@polkadot/wasm-crypto-init": "7.3.2", + "@polkadot/wasm-crypto-wasm": "7.3.2", + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" } }, "@polkadot/wasm-crypto-asmjs": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.2.tgz", - "integrity": "sha512-wKg+cpsWQCTSVhjlHuNeB/184rxKqY3vaklacbLOMbUXieIfuDBav5PJdzS3yeiVE60TpYaHW4iX/5OYHS82gg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.2.tgz", + "integrity": "sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q==", "requires": { - "tslib": "^2.6.1" + "tslib": "^2.6.2" } }, "@polkadot/wasm-crypto-init": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.2.tgz", - "integrity": "sha512-vD4iPIp9x+SssUIWUenxWLPw4BVIwhXHNMpsV81egK990tvpyIxL205/EF5QRb1mKn8WfWcNFm5tYwwh9NdnnA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.2.tgz", + "integrity": "sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g==", "requires": { - "@polkadot/wasm-bridge": "7.2.2", - "@polkadot/wasm-crypto-asmjs": "7.2.2", - "@polkadot/wasm-crypto-wasm": "7.2.2", - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-bridge": "7.3.2", + "@polkadot/wasm-crypto-asmjs": "7.3.2", + "@polkadot/wasm-crypto-wasm": "7.3.2", + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" } }, "@polkadot/wasm-crypto-wasm": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.2.tgz", - "integrity": "sha512-3efoIB6jA3Hhv6k0YIBwCtlC8gCSWCk+R296yIXRLLr3cGN415KM/PO/d1JIXYI64lbrRzWRmZRhllw3jf6Atg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.2.tgz", + "integrity": "sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw==", "requires": { - "@polkadot/wasm-util": "7.2.2", - "tslib": "^2.6.1" + "@polkadot/wasm-util": "7.3.2", + "tslib": "^2.6.2" } }, "@polkadot/wasm-util": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.2.2.tgz", - "integrity": "sha512-N/25960ifCc56sBlJZ2h5UBpEPvxBmMLgwYsl7CUuT+ea2LuJW9Xh8VHDN/guYXwmm92/KvuendYkEUykpm/JQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.3.2.tgz", + "integrity": "sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg==", "requires": { - "tslib": "^2.6.1" + "tslib": "^2.6.2" } }, "@polkadot/x-bigint": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.5.1.tgz", - "integrity": "sha512-Fw39eoN9v0sqxSzfSC5awaDVdzojIiE7d1hRSQgVSrES+8whWvtbYMR0qwbVhTuW7DvogHmye41P9xKMlXZysg==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.6.2.tgz", + "integrity": "sha512-HSIk60uFPX4GOFZSnIF7VYJz7WZA7tpFJsne7SzxOooRwMTWEtw3fUpFy5cYYOeLh17/kHH1Y7SVcuxzVLc74Q==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" } }, "@polkadot/x-fetch": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.5.1.tgz", - "integrity": "sha512-Bc019lOKCoQJrthiS+H3LwCahGtl5tNnb2HK7xe3DBQIUx9r2HsF/uEngNfMRUFkUYg5TPCLFbEWU8NIREBS1A==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.6.2.tgz", + "integrity": "sha512-8wM/Z9JJPWN1pzSpU7XxTI1ldj/AfC8hKioBlUahZ8gUiJaOF7K9XEFCrCDLis/A1BoOu7Ne6WMx/vsJJIbDWw==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "node-fetch": "^3.3.2", "tslib": "^2.6.2" } }, "@polkadot/x-global": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.5.1.tgz", - "integrity": "sha512-6K0YtWEg0eXInDOihU5aSzeb1t9TiDdX9ZuRly+58ALSqw5kPZYmQLbzE1d8HWzyXRXK+YH65GtLzfMGqfYHmw==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.6.2.tgz", + "integrity": "sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g==", "requires": { "tslib": "^2.6.2" } }, "@polkadot/x-randomvalues": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.5.1.tgz", - "integrity": "sha512-UsMb1d+77EPNjW78BpHjZLIm4TaIpfqq89OhZP/6gDIoS2V9iE/AK3jOWKm1G7Y2F8XIoX1qzQpuMakjfagFoQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.6.2.tgz", + "integrity": "sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" } }, "@polkadot/x-textdecoder": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.5.1.tgz", - "integrity": "sha512-j2YZGWfwhMC8nHW3BXq10fAPY02ObLL/qoTjCMJ1Cmc/OGq18Ep7k9cXXbjFAq3wf3tUUewt/u/hStKCk3IvfQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.6.2.tgz", + "integrity": "sha512-M1Bir7tYvNappfpFWXOJcnxUhBUFWkUFIdJSyH0zs5LmFtFdbKAeiDXxSp2Swp5ddOZdZgPac294/o2TnQKN1w==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" } }, "@polkadot/x-textencoder": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.5.1.tgz", - "integrity": "sha512-1JNNpOGb4wD+c7zFuOqjibl49LPnHNr4rj4s3WflLUIZvOMY6euoDuN3ISjQSHCLlVSoH0sOCWA3qXZU4bCTDQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.6.2.tgz", + "integrity": "sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2" } }, "@polkadot/x-ws": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.5.1.tgz", - "integrity": "sha512-efNMhB3Lh6pW2iTipMkqwrjpuUtb3EwR/jYZftiIGo5tDPB7rqoMOp9s6KRFJEIUfZkLnMUtbkZ5fHzUJaCjmQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.6.2.tgz", + "integrity": "sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw==", "requires": { - "@polkadot/x-global": "12.5.1", + "@polkadot/x-global": "12.6.2", "tslib": "^2.6.2", - "ws": "^8.14.1" + "ws": "^8.15.1" } }, "@scure/base": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", - "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==" }, "@substrate/connect": { - "version": "0.7.26", - "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.26.tgz", - "integrity": "sha512-uuGSiroGuKWj1+38n1kY5HReer5iL9bRwPCzuoLtqAOmI1fGI0hsSI2LlNQMAbfRgr7VRHXOk5MTuQf5ulsFRw==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.7.tgz", + "integrity": "sha512-kJLSqiwsAC8eHsPBwUyVpp6cogs1b/4jxTiRfoWbbndmSSEqn3qkcwmYPmZud4pyJFX7FMXwzH28XaPRBGTaQQ==", "optional": true, "requires": { - "@substrate/connect-extension-protocol": "^1.0.1", - "eventemitter3": "^4.0.7", - "smoldot": "1.0.4" - }, - "dependencies": { - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "optional": true - } + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.0.7", + "@substrate/light-client-extension-helpers": "^0.0.3", + "smoldot": "2.0.21" } }, + "@substrate/connect-extension-protocol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.0.0.tgz", + "integrity": "sha512-nKu8pDrE3LNCEgJjZe1iGXzaD6OSIDD4Xzz/yo4KO9mQ6LBvf49BVrt4qxBFGL6++NneLiWUZGoh+VSd4PyVIg==", + "optional": true + }, "@unique-nft/opal-testnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/opal-testnet-types/-/opal-testnet-types-943.61.0.tgz", - "integrity": "sha512-U+QyKPP9OXrRgt4zGKEPYm+6ocIFrBNH5VFf+Qh1dLUr+a9of+pXfdnVKA3zl8iSIU5oC0awUsE62w67hBpwdg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/opal-testnet-types/-/opal-testnet-types-1003.70.0.tgz", + "integrity": "sha512-vXJoV7cqwO21svd03DFL7bl8H77zFbJzgkUgNPLPbVA6YkZt+ZeDmbP9lKKPbNadB1DP84kOZPVvsbmzx7+Jxg==", "requires": {} }, "@unique-nft/quartz-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/quartz-mainnet-types/-/quartz-mainnet-types-943.61.0.tgz", - "integrity": "sha512-QHfu+oZkf64+vu45DEZVTe1xznfBO7B856aaIMkmEy/Fo0VofNUyiKeV2a6LolDuLgALu9a9uQEXeqQwBwoeZg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/quartz-mainnet-types/-/quartz-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-qs5iwMcDpBeJ6mXzSAbMB6DY9NkdAqPD1KmekOVG9Vug+hKWvSlfW5ozd63O/J2h7iliqwL0WZjDdwvBNdcTNg==", "requires": {} }, "@unique-nft/sapphire-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/sapphire-mainnet-types/-/sapphire-mainnet-types-943.61.0.tgz", - "integrity": "sha512-IaEb6Yf114b5Wjh06eGiB36f8LthSqLaBDcbniRX9lwOvywbpuqmkXfuyfol2kGYL87vUYWQoMKsX4BJpfIUDg==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/sapphire-mainnet-types/-/sapphire-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-hEMpLDPZxUuGW+B90AxaF3Clw/kvGn20oao+Ejq4nrCNRF/2k3CjjuG1NScZVcPZuGgKPAkBPiHNSF9aRN6qFg==", "requires": {} }, "@unique-nft/unique-mainnet-types": { - "version": "943.61.0", - "resolved": "https://registry.npmjs.org/@unique-nft/unique-mainnet-types/-/unique-mainnet-types-943.61.0.tgz", - "integrity": "sha512-l8JQv9Lpg+1UbZsU/wmX/axIzDu6djFgoxIxu6unGdk9ZsIIzLJ3hkjmtoguwdp/ur1mElg2ubW4CAByUdVprA==", + "version": "1003.70.0", + "resolved": "https://registry.npmjs.org/@unique-nft/unique-mainnet-types/-/unique-mainnet-types-1003.70.0.tgz", + "integrity": "sha512-sIa5/T+EV7e5BinIZCPAVS+8noOcND9lIXXBjRIwFsfSEdw50jJ5fL0DIQabKqdA1S5jSfDTH2yT6GXLrh67hg==", "requires": {} }, "eventemitter3": { @@ -19066,9 +19358,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "requires": {} } } @@ -19080,13 +19372,21 @@ "requires": {} }, "@unique-nft/utils": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@unique-nft/utils/-/utils-0.3.14.tgz", - "integrity": "sha512-GJWPaSCM5ZvKJOiLY53LlngBZGAzySk4mSkcWoCUftqgNaeCekOadCDBiy2jmRhIEKpxE6wDRW/gT+2S8JtjvA==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@unique-nft/utils/-/utils-0.3.17.tgz", + "integrity": "sha512-rKldHiI+qaTtYbwHc2mopHxM3O5YyyagpPTcqaZ7/TB7B0OIFUpylV6nfWzACn15mmf0kz0MwtUU4FrpsHofNA==", "requires": { - "@noble/hashes": "^1.1.2", + "@noble/hashes": "^1.3.3", + "@unique-nft/sr25519": "^0.0.2", "base-x": "^4.0.0", "utf-helpers": "^0.0.3" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" + } } }, "@webassemblyjs/ast": { @@ -23820,9 +24120,9 @@ } }, "mock-socket": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.2.1.tgz", - "integrity": "sha512-aw9F9T9G2zpGipLLhSNh6ZpgUyUl4frcVmRN08uE1NWPWg43Wx6+sGPDbQ7E5iFZZDJW5b5bypMeAEHqTbIFag==" + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", + "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==" }, "ms": { "version": "2.1.2", @@ -23904,13 +24204,12 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "nock": { - "version": "13.3.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.1.tgz", - "integrity": "sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", + "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.21", "propagate": "^2.0.0" } }, @@ -24481,9 +24780,9 @@ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==" }, "protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -24847,6 +25146,12 @@ "xmlchars": "^2.2.0" } }, + "scale-ts": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.0.tgz", + "integrity": "sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q==", + "optional": true + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -25041,12 +25346,11 @@ "dev": true }, "smoldot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-1.0.4.tgz", - "integrity": "sha512-N3TazI1C4GGrseFH/piWyZCCCRJTRx2QhDfrUKRT4SzILlW5m8ayZ3QTKICcz1C/536T9cbHHJyP7afxI6Mi1A==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.21.tgz", + "integrity": "sha512-XFpf3CQZ2BbFwVqKSyJHP7mbTDJxT3saRr/WfnfgWv+pbmA/J0e/LdfV/3A+jg7gNTEG06EAiDPtzN8ouXTLLw==", "optional": true, "requires": { - "pako": "^2.0.4", "ws": "^8.8.1" } }, diff --git a/package.json b/package.json index 28e48e77..aa3d8254 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "polkastats-backend-uniquenetwork", - "version": "2.0.69", + "version": "2.0.75", "description": "", "author": "Unique Network Team", "private": true, @@ -17,6 +17,7 @@ "start:crawler": "nest start crawler", "start:crawler:dev": "nest start crawler --watch", "start:crawler:debug": "nest start crawler --debug --watch", + "start:dev:all": "npm run start:dev & npm run start:crawler:dev", "lint": "eslint \"{src,apps,libs,test,e2e,migrations}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", @@ -56,7 +57,7 @@ "@unique-nft/harvester": "^0.1.0", "@unique-nft/opal-testnet-types": "937.52.0", "@unique-nft/quartz-mainnet-types": "936.50.4", - "@unique-nft/substrate-client": "^0.8.13", + "@unique-nft/substrate-client": "^0.11.2", "@unique-nft/unique-mainnet-types": "^937.52.0", "@willsoto/nestjs-prometheus": "^5.1.0", "apollo-server-express": "^3.6.2",