Skip to content

Commit 84821b2

Browse files
committed
fix: 🐛 get all exemptions
1 parent c93a79d commit 84821b2

File tree

2 files changed

+434
-13
lines changed

2 files changed

+434
-13
lines changed

src/api/entities/Asset/Fungible/TransferRestrictions/index.ts

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { BTreeSet, StorageKey, u128 } from '@polkadot/types';
1+
import { bool, BTreeSet, StorageKey, u128 } from '@polkadot/types';
22
import {
33
PolymeshPrimitivesAssetAssetId,
4+
PolymeshPrimitivesIdentityId,
45
PolymeshPrimitivesStatisticsStat1stKey,
56
PolymeshPrimitivesStatisticsStat2ndKey,
67
PolymeshPrimitivesStatisticsStatType,
8+
PolymeshPrimitivesTransferComplianceTransferConditionExemptKey,
79
} from '@polkadot/types/lookup';
810
import 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';
3943
import {
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';
5259
import { 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

Comments
 (0)