1- import { BTreeSet , StorageKey , u128 } from '@polkadot/types' ;
1+ import { bool , BTreeSet , StorageKey , u128 } from '@polkadot/types' ;
22import {
33 PolymeshPrimitivesAssetAssetId ,
4+ PolymeshPrimitivesIdentityId ,
45 PolymeshPrimitivesStatisticsStat1stKey ,
56 PolymeshPrimitivesStatisticsStat2ndKey ,
67 PolymeshPrimitivesStatisticsStatType ,
8+ PolymeshPrimitivesTransferComplianceTransferConditionExemptKey ,
79} from '@polkadot/types/lookup' ;
810import BigNumber from 'bignumber.js' ;
911
@@ -34,10 +36,13 @@ import {
3436 TransferRestrictionExemptionParams ,
3537 TransferRestrictionParams ,
3638 TransferRestrictionStatValues ,
39+ TransferRestrictionType ,
3740 TrustedFor ,
3841} from '~/types' ;
42+ import type { ExemptKey } from '~/types/internal' ;
3943import {
4044 assetComplianceToTransferRestrictions ,
45+ assetIdToString ,
4146 assetStatToStat ,
4247 assetToMeshAssetId ,
4348 exemptionToTransferExemption ,
@@ -47,6 +52,8 @@ import {
4752 meshClaimTypeToClaimType ,
4853 meshStatToStatType ,
4954 stringToAssetId ,
55+ toExemptKey ,
56+ transferRestrictionTypeToStatOpType ,
5057 u128ToStatValue ,
5158} from '~/utils/conversion' ;
5259import { createProcedureMethod , requestMulti } from '~/utils/internal' ;
@@ -526,6 +533,105 @@ export class TransferRestrictions extends Namespace<FungibleAsset> {
526533 return result ;
527534 }
528535
536+ /**
537+ * @hidden
538+ * Stringify claimType for deduplication key generation
539+ */
540+ private stringifyClaimType ( claimType : TrustedFor | null ) : string {
541+ if ( claimType === null ) {
542+ return 'null' ;
543+ }
544+ if ( typeof claimType === 'object' ) {
545+ return JSON . stringify ( claimType ) ;
546+ }
547+ return String ( claimType ) ;
548+ }
549+
550+ /**
551+ * @hidden
552+ * Build exempt keys map from active restrictions
553+ */
554+ private buildExemptKeysFromRestrictions (
555+ restrictions : ActiveTransferRestrictions ,
556+ rawAssetId : PolymeshPrimitivesAssetAssetId ,
557+ context : Context
558+ ) : Map <
559+ string ,
560+ { rawExemptKey : ExemptKey ; statOpType : StatType ; claimType ?: ClaimType | undefined }
561+ > {
562+ const exemptKeysToQuery = new Map <
563+ string ,
564+ { rawExemptKey : ExemptKey ; statOpType : StatType ; claimType ?: ClaimType | undefined }
565+ > ( ) ;
566+
567+ for ( const restriction of restrictions . restrictions ) {
568+ const rawOpType = transferRestrictionTypeToStatOpType ( restriction . type , context ) ;
569+ const statOpType =
570+ restriction . type === TransferRestrictionType . Count ||
571+ restriction . type === TransferRestrictionType . ClaimCount
572+ ? StatType . Count
573+ : StatType . Balance ;
574+ let claimType : ClaimType | undefined ;
575+
576+ if (
577+ restriction . type === TransferRestrictionType . ClaimCount ||
578+ restriction . type === TransferRestrictionType . ClaimPercentage
579+ ) {
580+ claimType = restriction . value . claim . type ;
581+ }
582+
583+ const rawExemptKey = toExemptKey ( rawAssetId , rawOpType , claimType ) ;
584+ const assetIdString = assetIdToString ( rawAssetId ) ;
585+ const keyString = JSON . stringify ( {
586+ assetId : assetIdString ,
587+ op : statOpType ,
588+ claimType : claimType ?. toString ( ) || null ,
589+ } ) ;
590+
591+ if ( ! exemptKeysToQuery . has ( keyString ) ) {
592+ exemptKeysToQuery . set ( keyString , { rawExemptKey, statOpType, claimType } ) ;
593+ }
594+ }
595+
596+ return exemptKeysToQuery ;
597+ }
598+
599+ /**
600+ * @hidden
601+ * Process exemptions from storage and add to results if not already seen
602+ */
603+ private processExemptionsFromStorage (
604+ rawExemptions : [
605+ StorageKey <
606+ [
607+ PolymeshPrimitivesTransferComplianceTransferConditionExemptKey ,
608+ PolymeshPrimitivesIdentityId
609+ ]
610+ > ,
611+ bool
612+ ] [ ] ,
613+ seenExemptions : Set < string > ,
614+ allExemptions : TransferRestrictionExemption [ ] ,
615+ context : Context
616+ ) : void {
617+ for ( const [ exemption ] of rawExemptions ) {
618+ const [ rawExemptKeyFromStorage , rawIdentity ] = exemption . args ;
619+ const exemptKeyResult = exemptionToTransferExemption ( rawExemptKeyFromStorage ) ;
620+ const did = identityIdToString ( rawIdentity ) ;
621+
622+ const claimTypeString = this . stringifyClaimType ( exemptKeyResult . claimType ) ;
623+ const exemptionKey = `${ did } -${ exemptKeyResult . assetId } -${ exemptKeyResult . opType } -${ claimTypeString } ` ;
624+
625+ if ( ! seenExemptions . has ( exemptionKey ) ) {
626+ seenExemptions . add ( exemptionKey ) ;
627+ allExemptions . push ( {
628+ exemptKey : exemptKeyResult ,
629+ identity : new Identity ( { did } , context ) ,
630+ } ) ;
631+ }
632+ }
633+ }
634+
529635 /**
530636 * Return identities with exemptions.
531637 */
@@ -541,20 +647,26 @@ export class TransferRestrictions extends Namespace<FungibleAsset> {
541647 } = this ;
542648
543649 const rawAssetId = stringToAssetId ( parent . id , context ) ;
544- const rawExemptions = await statistics . transferConditionExemptEntities . entries ( rawAssetId ) ;
650+ const restrictions = await this . getRestrictions ( ) ;
651+ const exemptKeysToQuery = this . buildExemptKeysFromRestrictions (
652+ restrictions ,
653+ rawAssetId ,
654+ context
655+ ) ;
545656
546- const exemptions = rawExemptions . map ( ( [ exemption ] ) => {
547- const [ rawExemptKey , rawIdentity ] = exemption . args ;
548- const exemptKey = exemptionToTransferExemption ( rawExemptKey ) ;
549- const did = identityIdToString ( rawIdentity ) ;
657+ if ( exemptKeysToQuery . size === 0 ) {
658+ return [ ] ;
659+ }
550660
551- return {
552- exemptKey,
553- identity : new Identity ( { did } , context ) ,
554- } ;
555- } ) ;
661+ const allExemptions : TransferRestrictionExemption [ ] = [ ] ;
662+ const seenExemptions = new Set < string > ( ) ;
663+
664+ for ( const { rawExemptKey } of exemptKeysToQuery . values ( ) ) {
665+ const rawExemptions = await statistics . transferConditionExemptEntities . entries ( rawExemptKey ) ;
666+ this . processExemptionsFromStorage ( rawExemptions , seenExemptions , allExemptions , context ) ;
667+ }
556668
557- return exemptions ;
669+ return allExemptions ;
558670 }
559671
560672 /**
0 commit comments