Skip to content

Commit 09d480d

Browse files
committed
feat: add transfer restrictions management functionality
1 parent b2c9052 commit 09d480d

12 files changed

Lines changed: 2592 additions & 185 deletions

File tree

src/context/AssetContext/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
SecurityIdentifier,
1515
TickerReservation,
1616
TickerReservationDetails,
17+
TransferRestrictionExemption,
1718
TransferRestrictionStatValues,
1819
Venue,
1920
} from '@polymeshassociation/polymesh-sdk/types';
@@ -56,6 +57,7 @@ export interface IDetails {
5657
compliancePaused: boolean;
5758
transferRestrictions?: ActiveTransferRestrictions;
5859
trackedStatistics?: TransferRestrictionStatValues[];
60+
exemptions?: TransferRestrictionExemption[];
5961
}
6062
export interface IAssetDetails {
6163
assetId: string;

src/context/AssetContext/provider.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const AssetProvider = ({ children }: IProviderProps) => {
103103
compliancePaused,
104104
transferRestrictions,
105105
trackedStatistics,
106+
exemptions,
106107
] = await Promise.all([
107108
asset.details(),
108109
asset instanceof NftCollection ? asset.getCollectionId() : undefined,
@@ -127,6 +128,10 @@ const AssetProvider = ({ children }: IProviderProps) => {
127128
asset instanceof FungibleAsset
128129
? asset.transferRestrictions.getValues()
129130
: undefined,
131+
132+
asset instanceof FungibleAsset
133+
? asset.transferRestrictions.getExemptions()
134+
: undefined,
130135
]);
131136

132137
// Fetch all metadata entries with their details and values (if set)
@@ -186,6 +191,7 @@ const AssetProvider = ({ children }: IProviderProps) => {
186191
compliancePaused,
187192
transferRestrictions,
188193
trackedStatistics,
194+
exemptions,
189195
},
190196
docs: docs.data,
191197
};

src/hooks/polymesh/useAssetActions.tsx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import type {
77
InputCondition,
88
NftMetadataInput,
99
Requirement,
10+
TransferRestrictionClaimCountInput,
11+
TransferRestrictionExemptionParams,
12+
TransferRestrictionInputClaimPercentage,
13+
TransferRestrictionInputCount,
14+
TransferRestrictionInputPercentage,
1015
TrustedFor,
1116
} from '@polymeshassociation/polymesh-sdk/types';
1217
import {
@@ -1057,6 +1062,104 @@ const useAssetActions = (
10571062
}
10581063
};
10591064

1065+
const setTransferRestrictions = async ({
1066+
restrictions,
1067+
onTransactionRunning,
1068+
}: {
1069+
restrictions: (
1070+
| TransferRestrictionInputCount
1071+
| TransferRestrictionInputPercentage
1072+
| TransferRestrictionClaimCountInput
1073+
| TransferRestrictionInputClaimPercentage
1074+
)[];
1075+
onTransactionRunning?: () => void | Promise<void>;
1076+
}) => {
1077+
if (!asset) {
1078+
notifyError('Asset not available');
1079+
return;
1080+
}
1081+
1082+
// Type narrow: only FungibleAsset supports transfer restrictions
1083+
if (!('issuance' in asset)) {
1084+
notifyError(
1085+
'Transfer restrictions are only supported for fungible assets, not NFT collections',
1086+
);
1087+
return;
1088+
}
1089+
1090+
try {
1091+
await executeTransaction(
1092+
asset.transferRestrictions.setRestrictions({ restrictions }),
1093+
createOptions(onTransactionRunning),
1094+
);
1095+
} catch (error) {
1096+
// Error is already handled by the transaction context and notified to the user
1097+
// This catch block prevents unhandled promise rejection
1098+
}
1099+
};
1100+
1101+
const addExemptions = async ({
1102+
exemptions,
1103+
onTransactionRunning,
1104+
}: {
1105+
exemptions: TransferRestrictionExemptionParams;
1106+
onTransactionRunning?: () => void | Promise<void>;
1107+
}) => {
1108+
if (!asset) {
1109+
notifyError('Asset not available');
1110+
return;
1111+
}
1112+
1113+
// Type narrow: only FungibleAsset supports transfer restrictions
1114+
if (!('issuance' in asset)) {
1115+
notifyError(
1116+
'Transfer restrictions are only supported for fungible assets, not NFT collections',
1117+
);
1118+
return;
1119+
}
1120+
1121+
try {
1122+
await executeTransaction(
1123+
asset.transferRestrictions.addExemptions(exemptions),
1124+
createOptions(onTransactionRunning),
1125+
);
1126+
} catch (error) {
1127+
// Error is already handled by the transaction context and notified to the user
1128+
// This catch block prevents unhandled promise rejection
1129+
}
1130+
};
1131+
1132+
const removeExemptions = async ({
1133+
exemptions,
1134+
onTransactionRunning,
1135+
}: {
1136+
exemptions: TransferRestrictionExemptionParams;
1137+
onTransactionRunning?: () => void | Promise<void>;
1138+
}) => {
1139+
if (!asset) {
1140+
notifyError('Asset not available');
1141+
return;
1142+
}
1143+
1144+
// Type narrow: only FungibleAsset supports transfer restrictions
1145+
if (!('issuance' in asset)) {
1146+
notifyError(
1147+
'Transfer restrictions are only supported for fungible assets, not NFT collections',
1148+
);
1149+
return;
1150+
}
1151+
1152+
try {
1153+
await executeTransaction(
1154+
asset.transferRestrictions.removeExemptions(exemptions),
1155+
createOptions(onTransactionRunning),
1156+
);
1157+
} catch (error) {
1158+
// Error is already handled by the transaction context and notified to the user
1159+
// This catch block prevents unhandled promise rejection
1160+
}
1161+
};
1162+
10601163
return {
10611164
issueTokens,
10621165
redeemTokens,
@@ -1097,6 +1200,9 @@ const useAssetActions = (
10971200
modifyComplianceRule,
10981201
removeComplianceRule,
10991202
setTransferRestrictionStats,
1203+
setTransferRestrictions,
1204+
addExemptions,
1205+
removeExemptions,
11001206
transactionInProcess,
11011207
};
11021208
};

0 commit comments

Comments
 (0)