@tokenops/sdk 2.0.0-alpha.1 → 2.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -2
- package/README.md +14 -8
- package/dist/{chunk-PUX5VXDB.cjs → chunk-4AWQJQXY.cjs} +1415 -69
- package/dist/{chunk-74QFZ5MK.js → chunk-4IB4IY5Y.js} +1 -1
- package/dist/{chunk-DZHYSUGY.js → chunk-6HCT4QIX.js} +12 -5
- package/dist/{chunk-FGEB7RMY.cjs → chunk-6XOAYDC6.cjs} +4 -4
- package/dist/{chunk-XAYGD4E4.cjs → chunk-AHU2HMNE.cjs} +3 -3
- package/dist/{chunk-6NAVMWZQ.js → chunk-BPIVVCSQ.js} +2 -2
- package/dist/{chunk-GKKDAW44.js → chunk-BXX5TETM.js} +1401 -59
- package/dist/{chunk-456VDDA3.js → chunk-GCJFAY4X.js} +78 -25
- package/dist/{chunk-CTED3MTR.cjs → chunk-GKYZQJGP.cjs} +82 -29
- package/dist/{chunk-JZLGCTGK.cjs → chunk-IEKTGJ4J.cjs} +2 -2
- package/dist/{chunk-6PXXGACR.cjs → chunk-JVNJSDQ4.cjs} +2 -2
- package/dist/{chunk-O5676ZWY.js → chunk-LEYYG4RF.js} +232 -6
- package/dist/{chunk-335Z2W67.js → chunk-NGU4JYIR.js} +1 -1
- package/dist/{chunk-5576FRT3.cjs → chunk-PG3WXT3K.cjs} +12 -5
- package/dist/{chunk-H5POPGOZ.js → chunk-PK6Q6J5F.js} +1 -1
- package/dist/chunk-TND5NDV7.cjs +263 -0
- package/dist/chunk-U3TBQRT7.js +253 -0
- package/dist/{chunk-EAJ7SYHE.js → chunk-WRWRA4TN.js} +1 -1
- package/dist/{chunk-JQYC66TO.cjs → chunk-YABHXJNH.cjs} +5 -5
- package/dist/{chunk-M4IT6DNJ.cjs → chunk-YTIYTV4K.cjs} +236 -4
- package/dist/core/addresses.d.ts +4 -4
- package/dist/core/errors.d.ts +1 -1
- package/dist/fhe/types.d.ts +2 -2
- package/dist/fhe-airdrop/abis/airdrop-base.d.ts +19 -0
- package/dist/fhe-airdrop/abis/ecdsa.d.ts +19 -0
- package/dist/fhe-airdrop/abis/factory.d.ts +113 -0
- package/dist/fhe-airdrop/abis/merkle.d.ts +43 -12
- package/dist/fhe-airdrop/advanced/index.cjs +4 -4
- package/dist/fhe-airdrop/advanced/index.js +1 -1
- package/dist/fhe-airdrop/advanced/react/index.cjs +620 -9
- package/dist/fhe-airdrop/advanced/react/index.d.cts +35 -0
- package/dist/fhe-airdrop/advanced/react/index.d.ts +35 -0
- package/dist/fhe-airdrop/advanced/react/index.js +590 -7
- package/dist/fhe-airdrop/advanced/react/useClearCompliancePolicy.d.ts +28 -0
- package/dist/fhe-airdrop/advanced/react/useClearUpgradeabilityPolicy.d.ts +26 -0
- package/dist/fhe-airdrop/advanced/react/useDisableCustomFee.d.ts +26 -0
- package/dist/fhe-airdrop/advanced/react/useEcdsaInitCodeHash.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryComplianceDelegate.d.ts +25 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryCompliancePolicy.d.ts +38 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryCustomFee.d.ts +24 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryGrantRole.d.ts +32 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryHasRole.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryImplementations.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRenounceRole.d.ts +37 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRevokeRole.d.ts +37 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRoleConstants.d.ts +46 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryRoleMembers.d.ts +48 -0
- package/dist/fhe-airdrop/advanced/react/useFactoryUpgradeabilityPolicy.d.ts +39 -0
- package/dist/fhe-airdrop/advanced/react/useMerkleInitCodeHash.d.ts +24 -0
- package/dist/fhe-airdrop/advanced/react/useSetComplianceDelegate.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useSetComplianceManagerImpl.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetCompliancePolicy.d.ts +28 -0
- package/dist/fhe-airdrop/advanced/react/useSetCustomFee.d.ts +29 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultDelegateToCompliance.d.ts +31 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultGasFee.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useSetDefaultUpgradeable.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetEcdsaImplementation.d.ts +34 -0
- package/dist/fhe-airdrop/advanced/react/useSetFeeCollector.d.ts +27 -0
- package/dist/fhe-airdrop/advanced/react/useSetMaxGasFee.d.ts +33 -0
- package/dist/fhe-airdrop/advanced/react/useSetMerkleImplementation.d.ts +30 -0
- package/dist/fhe-airdrop/advanced/react/useSetUpgradeabilityPolicy.d.ts +31 -0
- package/dist/fhe-airdrop/airdrop-base.d.ts +55 -8
- package/dist/fhe-airdrop/campaign.d.ts +61 -20
- package/dist/fhe-airdrop/constants.d.ts +9 -1
- package/dist/fhe-airdrop/ecdsa.d.ts +13 -0
- package/dist/fhe-airdrop/errors.d.ts +87 -0
- package/dist/fhe-airdrop/factory.d.ts +62 -22
- package/dist/fhe-airdrop/guards.d.ts +133 -4
- package/dist/fhe-airdrop/index.cjs +86 -971
- package/dist/fhe-airdrop/index.d.cts +4 -4
- package/dist/fhe-airdrop/index.d.ts +4 -4
- package/dist/fhe-airdrop/index.js +8 -927
- package/dist/fhe-airdrop/merkle-tree.d.ts +32 -38
- package/dist/fhe-airdrop/merkle.d.ts +52 -31
- package/dist/fhe-airdrop/react/_shared.d.ts +13 -0
- package/dist/fhe-airdrop/react/index.cjs +997 -87
- package/dist/fhe-airdrop/react/index.d.cts +53 -4
- package/dist/fhe-airdrop/react/index.d.ts +53 -4
- package/dist/fhe-airdrop/react/index.js +887 -27
- package/dist/fhe-airdrop/react/keys.d.ts +98 -0
- package/dist/fhe-airdrop/react/useAccessEcdsaClaimAmount.d.ts +26 -0
- package/dist/fhe-airdrop/react/useAccessMerkleClaimAmount.d.ts +27 -0
- package/dist/fhe-airdrop/react/useAddComplianceDelegate.d.ts +37 -0
- package/dist/fhe-airdrop/react/useAdminBatchDiscloseBalanceToParties.d.ts +36 -0
- package/dist/fhe-airdrop/react/useAdminDiscloseBalanceToParty.d.ts +31 -0
- package/dist/fhe-airdrop/react/useAdminGetCurrentBalance.d.ts +27 -0
- package/dist/fhe-airdrop/react/useAirdropConfig.d.ts +49 -0
- package/dist/fhe-airdrop/react/useAirdropDeploymentMode.d.ts +28 -0
- package/dist/fhe-airdrop/react/useAirdropGrantRole.d.ts +35 -0
- package/dist/fhe-airdrop/react/useAirdropRenounceRole.d.ts +36 -0
- package/dist/fhe-airdrop/react/useAirdropRevokeRole.d.ts +33 -0
- package/dist/fhe-airdrop/react/useAirdropRoleAdmin.d.ts +28 -0
- package/dist/fhe-airdrop/react/useAirdropRoleConstants.d.ts +67 -0
- package/dist/fhe-airdrop/react/useAirdropRoleMembers.d.ts +49 -0
- package/dist/fhe-airdrop/react/useAirdropUpgradeToAndCall.d.ts +45 -0
- package/dist/fhe-airdrop/react/useBatchDiscloseHandlesToParty.d.ts +32 -0
- package/dist/fhe-airdrop/react/useBuildMerkleCampaign.d.ts +68 -0
- package/dist/fhe-airdrop/react/useComplianceGrantRole.d.ts +32 -0
- package/dist/fhe-airdrop/react/useComplianceHasRole.d.ts +37 -0
- package/dist/fhe-airdrop/react/useComplianceInfo.d.ts +50 -0
- package/dist/fhe-airdrop/react/useComplianceManagerOf.d.ts +32 -0
- package/dist/fhe-airdrop/react/useComplianceRenounceRole.d.ts +38 -0
- package/dist/fhe-airdrop/react/useComplianceRevokeRole.d.ts +36 -0
- package/dist/fhe-airdrop/react/useComplianceRoleConstants.d.ts +41 -0
- package/dist/fhe-airdrop/react/useComplianceRoleMembers.d.ts +45 -0
- package/dist/fhe-airdrop/react/useCreateAndFundEcdsaAirdrop.d.ts +55 -0
- package/dist/fhe-airdrop/react/useCreateAndFundMerkleAirdrop.d.ts +52 -0
- package/dist/fhe-airdrop/react/useDiscloseHandleToParty.d.ts +35 -0
- package/dist/fhe-airdrop/react/useEcdsaClaim.d.ts +4 -3
- package/dist/fhe-airdrop/react/useEcdsaClaimAndUnwrap.d.ts +27 -0
- package/dist/fhe-airdrop/react/useEcdsaDomain.d.ts +41 -0
- package/dist/fhe-airdrop/react/useEffectiveDelegateToCompliance.d.ts +26 -0
- package/dist/fhe-airdrop/react/useEncryptCampaignAmounts.d.ts +59 -0
- package/dist/fhe-airdrop/react/useFactoryFees.d.ts +11 -4
- package/dist/fhe-airdrop/react/useIsActiveDelegate.d.ts +29 -0
- package/dist/fhe-airdrop/react/useIsAirdrop.d.ts +44 -0
- package/dist/fhe-airdrop/react/useIsMerkleRootMutable.d.ts +21 -0
- package/dist/fhe-airdrop/react/useIsSignatureValid.d.ts +46 -0
- package/dist/fhe-airdrop/react/useMerkleClaim.d.ts +7 -19
- package/dist/fhe-airdrop/react/useMerkleClaimAndUnwrap.d.ts +29 -0
- package/dist/fhe-airdrop/react/usePlanMerkleCampaign.d.ts +53 -0
- package/dist/fhe-airdrop/react/usePreflightClaim.d.ts +46 -0
- package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +67 -0
- package/dist/fhe-airdrop/react/useRefreshComplianceBalance.d.ts +36 -0
- package/dist/fhe-airdrop/react/useRescueERC20.d.ts +30 -0
- package/dist/fhe-airdrop/react/useRescueOtherConfidentialToken.d.ts +34 -0
- package/dist/fhe-airdrop/react/useResolveGasFee.d.ts +30 -0
- package/dist/fhe-airdrop/react/useRevokeComplianceDelegate.d.ts +37 -0
- package/dist/fhe-airdrop/react/useRotateMerkleRoot.d.ts +52 -0
- package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +42 -0
- package/dist/fhe-airdrop/react/useWithdrawGasFee.d.ts +37 -0
- package/dist/fhe-airdrop/types.d.ts +27 -1
- package/dist/fhe-disperse/index.cjs +21 -21
- package/dist/fhe-disperse/index.js +2 -2
- package/dist/fhe-disperse/react/index.cjs +22 -22
- package/dist/fhe-disperse/react/index.js +3 -3
- package/dist/fhe-vesting/advanced/index.cjs +5 -5
- package/dist/fhe-vesting/advanced/index.js +3 -3
- package/dist/fhe-vesting/advanced/react/index.cjs +7 -7
- package/dist/fhe-vesting/advanced/react/index.js +4 -4
- package/dist/fhe-vesting/index.cjs +8 -8
- package/dist/fhe-vesting/index.js +2 -2
- package/dist/fhe-vesting/react/index.cjs +114 -114
- package/dist/fhe-vesting/react/index.js +3 -3
- package/dist/index.cjs +18 -18
- package/dist/index.js +1 -1
- package/dist/testnet-faucet/index.cjs +14 -14
- package/dist/testnet-faucet/index.js +2 -2
- package/dist/testnet-faucet/react/index.cjs +8 -8
- package/dist/testnet-faucet/react/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-NCVX3K2N.cjs +0 -161
- package/dist/chunk-VP2B4WM2.js +0 -154
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { assertSupportedChain, airdropProductMapper, assertMerkleModeSupported, assertStockWrapper, assertSaltAvailable, DEDUP_MODE, DEPLOYMENT_MODE } from './chunk-
|
|
1
|
+
import { assertSupportedChain, airdropProductMapper, assertMerkleModeSupported, assertGasFeeAccepted, assertStockWrapper, assertSaltAvailable, assertMerkleClaimIdentity, DEDUP_MODE, DEPLOYMENT_MODE } from './chunk-LEYYG4RF.js';
|
|
2
2
|
import { requireFhevmAclAddress, ACL_ALLOWED_EVENT } from './chunk-ZWXJTBZO.js';
|
|
3
3
|
import { SDK_VERSION } from './chunk-NWFMBLSQ.js';
|
|
4
4
|
import { isContractRevert, mapContractRevert } from './chunk-4RAAATVY.js';
|
|
5
|
-
import { requireFheAirdropFactoryAddress } from './chunk-
|
|
5
|
+
import { requireFheAirdropFactoryAddress } from './chunk-6HCT4QIX.js';
|
|
6
6
|
import { normaliseAddress } from './chunk-ZA673I3O.js';
|
|
7
7
|
import { asTxHash, asEncryptedHandle, asExternalInputProof, asSignature } from './chunk-KWFFIJYX.js';
|
|
8
8
|
import { DeploymentAddressUnavailableError, InvalidArgumentError, MissingWalletClientError, MissingAccountError, TokenOpsSdkError, MissingEncryptorError, ReceiptEventNotFoundError } from './chunk-QBJ7O2B4.js';
|
|
@@ -69,6 +69,11 @@ var airdropFactoryAbi = [
|
|
|
69
69
|
internalType: "uint96",
|
|
70
70
|
name: "defaultGasFee_",
|
|
71
71
|
type: "uint96"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
internalType: "uint96",
|
|
75
|
+
name: "maxGasFee_",
|
|
76
|
+
type: "uint96"
|
|
72
77
|
}
|
|
73
78
|
],
|
|
74
79
|
stateMutability: "nonpayable",
|
|
@@ -173,6 +178,38 @@ var airdropFactoryAbi = [
|
|
|
173
178
|
name: "FailedDeployment",
|
|
174
179
|
type: "error"
|
|
175
180
|
},
|
|
181
|
+
{
|
|
182
|
+
inputs: [
|
|
183
|
+
{
|
|
184
|
+
internalType: "uint96",
|
|
185
|
+
name: "gasFee",
|
|
186
|
+
type: "uint96"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
internalType: "uint96",
|
|
190
|
+
name: "maxGasFee",
|
|
191
|
+
type: "uint96"
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
name: "GasFeeExceedsMaximum",
|
|
195
|
+
type: "error"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
inputs: [
|
|
199
|
+
{
|
|
200
|
+
internalType: "uint96",
|
|
201
|
+
name: "resolvedFee",
|
|
202
|
+
type: "uint96"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
internalType: "uint96",
|
|
206
|
+
name: "maxAcceptedGasFee",
|
|
207
|
+
type: "uint96"
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
name: "GasFeeNotAccepted",
|
|
211
|
+
type: "error"
|
|
212
|
+
},
|
|
176
213
|
{
|
|
177
214
|
inputs: [
|
|
178
215
|
{
|
|
@@ -391,6 +428,11 @@ var airdropFactoryAbi = [
|
|
|
391
428
|
name: "ZeroToken",
|
|
392
429
|
type: "error"
|
|
393
430
|
},
|
|
431
|
+
{
|
|
432
|
+
inputs: [],
|
|
433
|
+
name: "ZeroUnwrapRequestId",
|
|
434
|
+
type: "error"
|
|
435
|
+
},
|
|
394
436
|
{
|
|
395
437
|
anonymous: false,
|
|
396
438
|
inputs: [
|
|
@@ -423,6 +465,12 @@ var airdropFactoryAbi = [
|
|
|
423
465
|
internalType: "uint256",
|
|
424
466
|
name: "deploymentBlockNumber",
|
|
425
467
|
type: "uint256"
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
indexed: false,
|
|
471
|
+
internalType: "uint256",
|
|
472
|
+
name: "gasFee",
|
|
473
|
+
type: "uint256"
|
|
426
474
|
}
|
|
427
475
|
],
|
|
428
476
|
name: "AirdropInitialized",
|
|
@@ -927,6 +975,19 @@ var airdropFactoryAbi = [
|
|
|
927
975
|
name: "SetDefaultGasFee",
|
|
928
976
|
type: "event"
|
|
929
977
|
},
|
|
978
|
+
{
|
|
979
|
+
anonymous: false,
|
|
980
|
+
inputs: [
|
|
981
|
+
{
|
|
982
|
+
indexed: false,
|
|
983
|
+
internalType: "uint256",
|
|
984
|
+
name: "maxGasFee",
|
|
985
|
+
type: "uint256"
|
|
986
|
+
}
|
|
987
|
+
],
|
|
988
|
+
name: "SetMaxGasFee",
|
|
989
|
+
type: "event"
|
|
990
|
+
},
|
|
930
991
|
{
|
|
931
992
|
anonymous: false,
|
|
932
993
|
inputs: [
|
|
@@ -1218,6 +1279,11 @@ var airdropFactoryAbi = [
|
|
|
1218
1279
|
internalType: "address",
|
|
1219
1280
|
name: "complianceAdmin",
|
|
1220
1281
|
type: "address"
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
internalType: "uint96",
|
|
1285
|
+
name: "maxAcceptedGasFee",
|
|
1286
|
+
type: "uint96"
|
|
1221
1287
|
}
|
|
1222
1288
|
],
|
|
1223
1289
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -1306,6 +1372,11 @@ var airdropFactoryAbi = [
|
|
|
1306
1372
|
internalType: "address",
|
|
1307
1373
|
name: "complianceAdmin",
|
|
1308
1374
|
type: "address"
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
internalType: "uint96",
|
|
1378
|
+
name: "maxAcceptedGasFee",
|
|
1379
|
+
type: "uint96"
|
|
1309
1380
|
}
|
|
1310
1381
|
],
|
|
1311
1382
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -1394,6 +1465,11 @@ var airdropFactoryAbi = [
|
|
|
1394
1465
|
internalType: "address",
|
|
1395
1466
|
name: "complianceAdmin",
|
|
1396
1467
|
type: "address"
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
internalType: "uint96",
|
|
1471
|
+
name: "maxAcceptedGasFee",
|
|
1472
|
+
type: "uint96"
|
|
1397
1473
|
}
|
|
1398
1474
|
],
|
|
1399
1475
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -1472,6 +1548,11 @@ var airdropFactoryAbi = [
|
|
|
1472
1548
|
internalType: "address",
|
|
1473
1549
|
name: "complianceAdmin",
|
|
1474
1550
|
type: "address"
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
internalType: "uint96",
|
|
1554
|
+
name: "maxAcceptedGasFee",
|
|
1555
|
+
type: "uint96"
|
|
1475
1556
|
}
|
|
1476
1557
|
],
|
|
1477
1558
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -1738,6 +1819,11 @@ var airdropFactoryAbi = [
|
|
|
1738
1819
|
internalType: "address",
|
|
1739
1820
|
name: "complianceAdmin",
|
|
1740
1821
|
type: "address"
|
|
1822
|
+
},
|
|
1823
|
+
{
|
|
1824
|
+
internalType: "uint96",
|
|
1825
|
+
name: "maxAcceptedGasFee",
|
|
1826
|
+
type: "uint96"
|
|
1741
1827
|
}
|
|
1742
1828
|
],
|
|
1743
1829
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -1811,6 +1897,11 @@ var airdropFactoryAbi = [
|
|
|
1811
1897
|
internalType: "address",
|
|
1812
1898
|
name: "complianceAdmin",
|
|
1813
1899
|
type: "address"
|
|
1900
|
+
},
|
|
1901
|
+
{
|
|
1902
|
+
internalType: "uint96",
|
|
1903
|
+
name: "maxAcceptedGasFee",
|
|
1904
|
+
type: "uint96"
|
|
1814
1905
|
}
|
|
1815
1906
|
],
|
|
1816
1907
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -2003,6 +2094,38 @@ var airdropFactoryAbi = [
|
|
|
2003
2094
|
stateMutability: "view",
|
|
2004
2095
|
type: "function"
|
|
2005
2096
|
},
|
|
2097
|
+
{
|
|
2098
|
+
inputs: [
|
|
2099
|
+
{
|
|
2100
|
+
internalType: "address",
|
|
2101
|
+
name: "candidate",
|
|
2102
|
+
type: "address"
|
|
2103
|
+
}
|
|
2104
|
+
],
|
|
2105
|
+
name: "isAirdrop",
|
|
2106
|
+
outputs: [
|
|
2107
|
+
{
|
|
2108
|
+
internalType: "bool",
|
|
2109
|
+
name: "",
|
|
2110
|
+
type: "bool"
|
|
2111
|
+
}
|
|
2112
|
+
],
|
|
2113
|
+
stateMutability: "view",
|
|
2114
|
+
type: "function"
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
inputs: [],
|
|
2118
|
+
name: "maxGasFee",
|
|
2119
|
+
outputs: [
|
|
2120
|
+
{
|
|
2121
|
+
internalType: "uint256",
|
|
2122
|
+
name: "",
|
|
2123
|
+
type: "uint256"
|
|
2124
|
+
}
|
|
2125
|
+
],
|
|
2126
|
+
stateMutability: "view",
|
|
2127
|
+
type: "function"
|
|
2128
|
+
},
|
|
2006
2129
|
{
|
|
2007
2130
|
inputs: [],
|
|
2008
2131
|
name: "merkleImplementation",
|
|
@@ -2051,6 +2174,11 @@ var airdropFactoryAbi = [
|
|
|
2051
2174
|
internalType: "address",
|
|
2052
2175
|
name: "complianceAdmin",
|
|
2053
2176
|
type: "address"
|
|
2177
|
+
},
|
|
2178
|
+
{
|
|
2179
|
+
internalType: "uint96",
|
|
2180
|
+
name: "maxAcceptedGasFee",
|
|
2181
|
+
type: "uint96"
|
|
2054
2182
|
}
|
|
2055
2183
|
],
|
|
2056
2184
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -2134,6 +2262,11 @@ var airdropFactoryAbi = [
|
|
|
2134
2262
|
internalType: "address",
|
|
2135
2263
|
name: "complianceAdmin",
|
|
2136
2264
|
type: "address"
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
internalType: "uint96",
|
|
2268
|
+
name: "maxAcceptedGasFee",
|
|
2269
|
+
type: "uint96"
|
|
2137
2270
|
}
|
|
2138
2271
|
],
|
|
2139
2272
|
internalType: "struct IAirdropFactory.CommonAirdropParams",
|
|
@@ -2345,6 +2478,19 @@ var airdropFactoryAbi = [
|
|
|
2345
2478
|
stateMutability: "nonpayable",
|
|
2346
2479
|
type: "function"
|
|
2347
2480
|
},
|
|
2481
|
+
{
|
|
2482
|
+
inputs: [
|
|
2483
|
+
{
|
|
2484
|
+
internalType: "uint96",
|
|
2485
|
+
name: "maxGasFee_",
|
|
2486
|
+
type: "uint96"
|
|
2487
|
+
}
|
|
2488
|
+
],
|
|
2489
|
+
name: "setMaxGasFee",
|
|
2490
|
+
outputs: [],
|
|
2491
|
+
stateMutability: "nonpayable",
|
|
2492
|
+
type: "function"
|
|
2493
|
+
},
|
|
2348
2494
|
{
|
|
2349
2495
|
inputs: [
|
|
2350
2496
|
{
|
|
@@ -2763,6 +2909,11 @@ var ecdsaConfidentialAirdropAbi = [
|
|
|
2763
2909
|
name: "ZeroToken",
|
|
2764
2910
|
type: "error"
|
|
2765
2911
|
},
|
|
2912
|
+
{
|
|
2913
|
+
inputs: [],
|
|
2914
|
+
name: "ZeroUnwrapRequestId",
|
|
2915
|
+
type: "error"
|
|
2916
|
+
},
|
|
2766
2917
|
{
|
|
2767
2918
|
anonymous: false,
|
|
2768
2919
|
inputs: [
|
|
@@ -2795,6 +2946,12 @@ var ecdsaConfidentialAirdropAbi = [
|
|
|
2795
2946
|
internalType: "uint256",
|
|
2796
2947
|
name: "deploymentBlockNumber",
|
|
2797
2948
|
type: "uint256"
|
|
2949
|
+
},
|
|
2950
|
+
{
|
|
2951
|
+
indexed: false,
|
|
2952
|
+
internalType: "uint256",
|
|
2953
|
+
name: "gasFee",
|
|
2954
|
+
type: "uint256"
|
|
2798
2955
|
}
|
|
2799
2956
|
],
|
|
2800
2957
|
name: "AirdropInitialized",
|
|
@@ -3907,6 +4064,19 @@ var ecdsaConfidentialAirdropAbi = [
|
|
|
3907
4064
|
stateMutability: "view",
|
|
3908
4065
|
type: "function"
|
|
3909
4066
|
},
|
|
4067
|
+
{
|
|
4068
|
+
inputs: [],
|
|
4069
|
+
name: "refreshComplianceBalance",
|
|
4070
|
+
outputs: [
|
|
4071
|
+
{
|
|
4072
|
+
internalType: "euint64",
|
|
4073
|
+
name: "balance",
|
|
4074
|
+
type: "bytes32"
|
|
4075
|
+
}
|
|
4076
|
+
],
|
|
4077
|
+
stateMutability: "nonpayable",
|
|
4078
|
+
type: "function"
|
|
4079
|
+
},
|
|
3910
4080
|
{
|
|
3911
4081
|
inputs: [
|
|
3912
4082
|
{
|
|
@@ -4294,6 +4464,11 @@ var confidentialAirdropBaseAbi = [
|
|
|
4294
4464
|
name: "ZeroToken",
|
|
4295
4465
|
type: "error"
|
|
4296
4466
|
},
|
|
4467
|
+
{
|
|
4468
|
+
inputs: [],
|
|
4469
|
+
name: "ZeroUnwrapRequestId",
|
|
4470
|
+
type: "error"
|
|
4471
|
+
},
|
|
4297
4472
|
{
|
|
4298
4473
|
anonymous: false,
|
|
4299
4474
|
inputs: [
|
|
@@ -4326,6 +4501,12 @@ var confidentialAirdropBaseAbi = [
|
|
|
4326
4501
|
internalType: "uint256",
|
|
4327
4502
|
name: "deploymentBlockNumber",
|
|
4328
4503
|
type: "uint256"
|
|
4504
|
+
},
|
|
4505
|
+
{
|
|
4506
|
+
indexed: false,
|
|
4507
|
+
internalType: "uint256",
|
|
4508
|
+
name: "gasFee",
|
|
4509
|
+
type: "uint256"
|
|
4329
4510
|
}
|
|
4330
4511
|
],
|
|
4331
4512
|
name: "AirdropInitialized",
|
|
@@ -4802,6 +4983,19 @@ var confidentialAirdropBaseAbi = [
|
|
|
4802
4983
|
stateMutability: "nonpayable",
|
|
4803
4984
|
type: "function"
|
|
4804
4985
|
},
|
|
4986
|
+
{
|
|
4987
|
+
inputs: [],
|
|
4988
|
+
name: "refreshComplianceBalance",
|
|
4989
|
+
outputs: [
|
|
4990
|
+
{
|
|
4991
|
+
internalType: "euint64",
|
|
4992
|
+
name: "balance",
|
|
4993
|
+
type: "bytes32"
|
|
4994
|
+
}
|
|
4995
|
+
],
|
|
4996
|
+
stateMutability: "nonpayable",
|
|
4997
|
+
type: "function"
|
|
4998
|
+
},
|
|
4805
4999
|
{
|
|
4806
5000
|
inputs: [
|
|
4807
5001
|
{
|
|
@@ -5201,8 +5395,12 @@ var AirdropBaseClient = class {
|
|
|
5201
5395
|
* Sweep a plain ERC-20 that was sent to the instance by mistake. Requires
|
|
5202
5396
|
* `RESCUER_ROLE`.
|
|
5203
5397
|
*
|
|
5204
|
-
*
|
|
5205
|
-
*
|
|
5398
|
+
* Passing the campaign's own token reverts `CannotRescueAirdropToken`
|
|
5399
|
+
* (audit-05), matching {@link rescueOtherConfidentialToken}. ERC-7984 and
|
|
5400
|
+
* ERC-20 are not disjoint in practice - a wrapper token answers both
|
|
5401
|
+
* interfaces - so "the pool token is confidential, therefore out of reach
|
|
5402
|
+
* here" was never a guarantee, only an assumption. Use
|
|
5403
|
+
* {@link withdrawConfidential} for the pool.
|
|
5206
5404
|
*
|
|
5207
5405
|
* @returns The transaction hash.
|
|
5208
5406
|
*/
|
|
@@ -5562,17 +5760,56 @@ var AirdropBaseClient = class {
|
|
|
5562
5760
|
// DISCLOSURE (ENCRYPTED)
|
|
5563
5761
|
// ============================================================
|
|
5564
5762
|
//
|
|
5565
|
-
// The first
|
|
5763
|
+
// The first four read like getters and are `nonpayable` in the ABI: they
|
|
5566
5764
|
// call `FHE.allow`, which writes ACL state. They therefore submit a
|
|
5567
5765
|
// transaction and recover their `euint64` result from the receipt — never
|
|
5568
5766
|
// from a simulation. See `extractGrantedHandle`.
|
|
5569
5767
|
//
|
|
5768
|
+
// Three of those four grant the CALLER; `refreshComplianceBalance` grants the
|
|
5769
|
+
// compliance clone instead, which is why it resolves the clone address and
|
|
5770
|
+
// passes it as `grantee`.
|
|
5771
|
+
//
|
|
5570
5772
|
// The last two return nothing on-chain and are ordinary writes: they grant a
|
|
5571
5773
|
// handle the caller already has, so there is no new handle to recover.
|
|
5774
|
+
/**
|
|
5775
|
+
* Re-grant the compliance-manager clone on the instance's current pool
|
|
5776
|
+
* balance, and return the handle it was granted on.
|
|
5777
|
+
*
|
|
5778
|
+
* **Permissionless, and deliberately so** (audit-04). The token rotates the
|
|
5779
|
+
* instance's balance handle on every incoming transfer, including one no
|
|
5780
|
+
* airdrop code observes - a third party transferring in directly - and
|
|
5781
|
+
* grants the fresh handle to the token and the holder only. Without this the
|
|
5782
|
+
* compliance clone's grant can be stranded on a handle the token has already
|
|
5783
|
+
* replaced, with no admin necessarily around to restore it. There is no
|
|
5784
|
+
* argument to abuse: the only handle read is `address(this)`'s own balance,
|
|
5785
|
+
* and the only grantee is the clone wired at initialization.
|
|
5786
|
+
*
|
|
5787
|
+
* This is therefore the normative way to obtain a readable live-balance
|
|
5788
|
+
* handle - and it is a **snapshot, not a subscription**. Grants are
|
|
5789
|
+
* append-only, so the handle this returns stays readable forever; but the
|
|
5790
|
+
* next incoming transfer rotates the instance to a NEW handle the clone was
|
|
5791
|
+
* never granted on. A compliance reader that refreshes once and stops is
|
|
5792
|
+
* reading a stale balance, not a live one. Call it again after any transfer
|
|
5793
|
+
* in, or before each read.
|
|
5794
|
+
*
|
|
5795
|
+
* @returns `{ handle, hash }` - the handle the compliance clone may now decrypt.
|
|
5796
|
+
* @throws {@link ReceiptEventNotFoundError} when the transaction granted no ACL to the clone.
|
|
5797
|
+
*/
|
|
5798
|
+
async refreshComplianceBalance(args = {}) {
|
|
5799
|
+
const grantee = await this.complianceManager();
|
|
5800
|
+
return this.encryptedView({
|
|
5801
|
+
functionName: "refreshComplianceBalance",
|
|
5802
|
+
grantee,
|
|
5803
|
+
account: args.account
|
|
5804
|
+
});
|
|
5805
|
+
}
|
|
5572
5806
|
/**
|
|
5573
5807
|
* Read the instance's own remaining pool balance as a handle the **caller**
|
|
5574
5808
|
* can decrypt. Requires `DISCLOSURE_ADMIN_ROLE`.
|
|
5575
5809
|
*
|
|
5810
|
+
* Also re-grants the compliance-manager clone on the same handle (audit-04),
|
|
5811
|
+
* so an admin read doubles as a {@link refreshComplianceBalance}.
|
|
5812
|
+
*
|
|
5576
5813
|
* @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`.
|
|
5577
5814
|
* @throws {@link ReceiptEventNotFoundError} when the transaction granted no ACL to the caller.
|
|
5578
5815
|
*/
|
|
@@ -5648,11 +5885,18 @@ var AirdropBaseClient = class {
|
|
|
5648
5885
|
/**
|
|
5649
5886
|
* Grant `party` decrypt access to a handle you already hold.
|
|
5650
5887
|
*
|
|
5651
|
-
* Two gates apply on-chain: the
|
|
5652
|
-
*
|
|
5653
|
-
*
|
|
5654
|
-
*
|
|
5655
|
-
*
|
|
5888
|
+
* Two gates apply on-chain. Gate #1: the handle must be **persistently**
|
|
5889
|
+
* user-decryptable in the `(caller, instance)` context - BOTH legs, and a
|
|
5890
|
+
* transient allowance does not satisfy either (audit-06). `DISCLOSURE_ADMIN_ROLE`
|
|
5891
|
+
* bypasses gate #1 only. Gate #2: the instance must be allowed on the handle,
|
|
5892
|
+
* so an arbitrary handle from another contract cannot be laundered through
|
|
5893
|
+
* this campaign.
|
|
5894
|
+
*
|
|
5895
|
+
* **The transient case is the trap.** An `euint64` that just came back from
|
|
5896
|
+
* an FHE op carries a transient allowance, which used to be enough here and
|
|
5897
|
+
* no longer is. Handles worth disclosing come from the encrypted views on
|
|
5898
|
+
* this client, whose grants are persistent. A gate #1 failure surfaces as
|
|
5899
|
+
* `FheHandleNotAllowedError` carrying the offending handle.
|
|
5656
5900
|
*
|
|
5657
5901
|
* @param args.handle An existing `euint64` handle — a public pointer, not a value.
|
|
5658
5902
|
* @returns The transaction hash. No new handle is produced.
|
|
@@ -5807,6 +6051,17 @@ var AirdropBaseClient = class {
|
|
|
5807
6051
|
}
|
|
5808
6052
|
return acct;
|
|
5809
6053
|
}
|
|
6054
|
+
/**
|
|
6055
|
+
* The address that will actually send the transaction, as a plain `Address`.
|
|
6056
|
+
*
|
|
6057
|
+
* Needed by any method whose arguments must be validated against the sender before
|
|
6058
|
+
* the write — on the Merkle variant the claim identity, the payout destination and
|
|
6059
|
+
* the submitter are three separate addresses with rules between them.
|
|
6060
|
+
*/
|
|
6061
|
+
resolveSender(override, method) {
|
|
6062
|
+
const wallet = this.requireWallet(method);
|
|
6063
|
+
return accountAddress(this.resolveAccount(wallet, override, method));
|
|
6064
|
+
}
|
|
5810
6065
|
};
|
|
5811
6066
|
function createAirdropBaseClient(config) {
|
|
5812
6067
|
return new AirdropBaseClient(config);
|
|
@@ -5911,11 +6166,24 @@ var EcdsaAirdropClient = class extends AirdropBaseClient {
|
|
|
5911
6166
|
* consuming either replay guard — the same input can still be claimed for
|
|
5912
6167
|
* real afterwards. No fee.
|
|
5913
6168
|
*
|
|
6169
|
+
* **It is repeatable, not unconditional** (audit-07). While the claim is
|
|
6170
|
+
* still available this may be called any number of times; once it is not,
|
|
6171
|
+
* this reverts with the same error the consuming claim would raise, in the
|
|
6172
|
+
* same order: the mode's dedup slot first (`AddressAlreadyClaimed` /
|
|
6173
|
+
* `DedupIdAlreadyClaimed`), the EIP-712 digest second (`SignatureAlreadyUsed`).
|
|
6174
|
+
* A rejected preview performs no FHE op, grants no ACL and emits nothing.
|
|
6175
|
+
*
|
|
6176
|
+
* So this is not a probe for "has this been claimed" - use
|
|
6177
|
+
* {@link isSignatureValid}, which never reverts and answers the same
|
|
6178
|
+
* question for free. Reach for this when you want the AMOUNT.
|
|
6179
|
+
*
|
|
5914
6180
|
* An encrypted view: the contract calls `FHE.allow(amount, msg.sender)`, so
|
|
5915
6181
|
* the result is recovered from the receipt's ACL `Allowed` event, never
|
|
5916
6182
|
* from a simulation. See {@link AirdropBaseClient}'s class TSDoc.
|
|
5917
6183
|
*
|
|
5918
6184
|
* @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`.
|
|
6185
|
+
* @throws {@link AlreadyClaimedError} when this recipient's dedup slot is consumed.
|
|
6186
|
+
* @throws {@link DedupIdConsumedError} when this `dedupId`'s slot is consumed.
|
|
5919
6187
|
*/
|
|
5920
6188
|
async getClaimAmount(args) {
|
|
5921
6189
|
return this.encryptedView({
|
|
@@ -6115,7 +6383,8 @@ function toContractCommonParams(common) {
|
|
|
6115
6383
|
endTime: common.endTime,
|
|
6116
6384
|
canExtendClaimWindow: common.canExtendClaimWindow,
|
|
6117
6385
|
unwrappable: common.unwrappable,
|
|
6118
|
-
complianceAdmin: common.complianceAdmin
|
|
6386
|
+
complianceAdmin: common.complianceAdmin,
|
|
6387
|
+
maxAcceptedGasFee: common.maxAcceptedGasFee
|
|
6119
6388
|
};
|
|
6120
6389
|
}
|
|
6121
6390
|
function toContractEcdsaParams(params) {
|
|
@@ -6472,11 +6741,28 @@ var ConfidentialAirdropFactoryClient = class {
|
|
|
6472
6741
|
async airdrops(offset, limit) {
|
|
6473
6742
|
return this.#read("airdrops", [offset, limit]);
|
|
6474
6743
|
}
|
|
6744
|
+
/**
|
|
6745
|
+
* Whether THIS factory created `candidate` - the genuineness check (audit-10).
|
|
6746
|
+
*
|
|
6747
|
+
* Nothing observable at an instance proves which factory, if any, deployed
|
|
6748
|
+
* it: an attacker can deploy a contract with the same ABI, the same events
|
|
6749
|
+
* and a pool it controls. The only trustworthy question is whether the
|
|
6750
|
+
* canonical factory's own registry contains the address, which is why this
|
|
6751
|
+
* read has to be addressed to a factory taken from
|
|
6752
|
+
* `src/core/addresses.ts` rather than one the instance names.
|
|
6753
|
+
*
|
|
6754
|
+
* @param candidate The address to check.
|
|
6755
|
+
* @returns True when this factory's registry contains `candidate`.
|
|
6756
|
+
*/
|
|
6757
|
+
async isAirdrop(candidate) {
|
|
6758
|
+
return this.#read("isAirdrop", [candidate]);
|
|
6759
|
+
}
|
|
6475
6760
|
/**
|
|
6476
6761
|
* The compliance-manager clone bound to an instance.
|
|
6477
6762
|
*
|
|
6478
|
-
* Doubles as a provenance check
|
|
6479
|
-
* instances it deployed, so a zero
|
|
6763
|
+
* Doubles as a provenance check, though a weaker one than {@link isAirdrop}:
|
|
6764
|
+
* the factory records this mapping only for instances it deployed, so a zero
|
|
6765
|
+
* address means the instance is not ours.
|
|
6480
6766
|
*
|
|
6481
6767
|
* @param airdrop Instance address.
|
|
6482
6768
|
* @returns The clone address, or the zero address when unknown to this factory.
|
|
@@ -6530,6 +6816,47 @@ var ConfidentialAirdropFactoryClient = class {
|
|
|
6530
6816
|
async defaultGasFee() {
|
|
6531
6817
|
return this.#read("defaultGasFee");
|
|
6532
6818
|
}
|
|
6819
|
+
/** The factory's own ceiling on every configurable fee and every create-time resolved fee. */
|
|
6820
|
+
async maxGasFee() {
|
|
6821
|
+
return this.#read("maxGasFee");
|
|
6822
|
+
}
|
|
6823
|
+
/**
|
|
6824
|
+
* Set the factory's ceiling on every fee `setDefaultGasFee`/`setCustomFee`
|
|
6825
|
+
* may configure, and on the fee resolved at create.
|
|
6826
|
+
*
|
|
6827
|
+
* Requires `DEFAULT_ADMIN_ROLE`, deliberately not `FEE_MANAGER_ROLE`: the fee
|
|
6828
|
+
* manager moves fees only within a bound the admin controls. `0n` admits a
|
|
6829
|
+
* zero fee and nothing else.
|
|
6830
|
+
*
|
|
6831
|
+
* Lowering it below an already-configured fee does not rewrite that fee - the
|
|
6832
|
+
* stale value stays in storage and reverts `GasFeeExceedsMaximum` at the next
|
|
6833
|
+
* create until it is lowered too.
|
|
6834
|
+
*
|
|
6835
|
+
* @throws {@link InvalidArgumentError} when `maxGasFee` is below a currently configured fee (`GasFeeExceedsMaximum`).
|
|
6836
|
+
*/
|
|
6837
|
+
async setMaxGasFee(maxGasFee, account) {
|
|
6838
|
+
return this.#write("setMaxGasFee", [maxGasFee], account, "setMaxGasFee");
|
|
6839
|
+
}
|
|
6840
|
+
/**
|
|
6841
|
+
* The per-claim fee a `create*` from `creator` would freeze into the new
|
|
6842
|
+
* instance right now: their {@link getCustomFee} override when enabled, else
|
|
6843
|
+
* {@link defaultGasFee}.
|
|
6844
|
+
*
|
|
6845
|
+
* This is the number `CommonAirdropParams.maxAcceptedGasFee` is checked
|
|
6846
|
+
* against, so it is also what to show a creator before they choose a bound.
|
|
6847
|
+
* It is a snapshot, not a quote: `FEE_MANAGER_ROLE` can move it between this
|
|
6848
|
+
* read and the create, which is exactly what the bound exists to catch.
|
|
6849
|
+
*
|
|
6850
|
+
* @param creator The account that will send `create*`.
|
|
6851
|
+
* @returns The resolved fee in wei.
|
|
6852
|
+
*/
|
|
6853
|
+
async resolveGasFee(creator) {
|
|
6854
|
+
const [custom, fallback] = await Promise.all([
|
|
6855
|
+
this.getCustomFee(creator),
|
|
6856
|
+
this.defaultGasFee()
|
|
6857
|
+
]);
|
|
6858
|
+
return custom.enabled ? custom.gasFee : fallback;
|
|
6859
|
+
}
|
|
6533
6860
|
// ----------------------- implementation admin -----------------------
|
|
6534
6861
|
/**
|
|
6535
6862
|
* Point future `createEcdsaAirdrop*` calls at a new ECDSA implementation.
|
|
@@ -6794,17 +7121,15 @@ var ConfidentialAirdropFactoryClient = class {
|
|
|
6794
7121
|
/**
|
|
6795
7122
|
* Revoke `role` from `holder`. Requires the role's admin role.
|
|
6796
7123
|
*
|
|
6797
|
-
*
|
|
6798
|
-
*
|
|
6799
|
-
*
|
|
6800
|
-
*
|
|
6801
|
-
*
|
|
6802
|
-
*
|
|
6803
|
-
*
|
|
6804
|
-
*
|
|
6805
|
-
*
|
|
6806
|
-
* that moment, with no way to rotate or remove them. Grant the successor
|
|
6807
|
-
* first.
|
|
7124
|
+
* **The factory floors `DEFAULT_ADMIN_ROLE` at one live member** (audit-14),
|
|
7125
|
+
* matching the instances. Renouncing or revoking the sole holder reverts
|
|
7126
|
+
* `LastAdmin`, and granting the role to the zero address reverts
|
|
7127
|
+
* `ZeroAdminGrant`, so the set can neither be emptied nor satisfied by a
|
|
7128
|
+
* member nobody controls. Before audit-14 this succeeded and froze role
|
|
7129
|
+
* administration permanently; it no longer does.
|
|
7130
|
+
*
|
|
7131
|
+
* A handover is still available and is the supported way out: grant the
|
|
7132
|
+
* successor first, then renounce.
|
|
6808
7133
|
*
|
|
6809
7134
|
* @returns The transaction hash.
|
|
6810
7135
|
*/
|
|
@@ -6876,11 +7201,15 @@ var ConfidentialAirdropFactoryClient = class {
|
|
|
6876
7201
|
/**
|
|
6877
7202
|
* The create-time guardrails that need a read, run before anything is sent.
|
|
6878
7203
|
*
|
|
6879
|
-
*
|
|
7204
|
+
* Three checks, in the order a failure is cheapest to discover:
|
|
6880
7205
|
*
|
|
6881
|
-
* 1. **
|
|
7206
|
+
* 1. **Accepted gas fee.** The fee is frozen into the instance at
|
|
7207
|
+
* initialization and immutable after, so a bound that no longer holds must
|
|
7208
|
+
* stop the transaction before anything else is spent on it (see
|
|
7209
|
+
* {@link GasFeeNotAcceptedError}).
|
|
7210
|
+
* 2. **Stock wrapper.** Only when `unwrappable` is requested; one
|
|
6882
7211
|
* `underlying()` probe (see {@link NonStockWrapperError}).
|
|
6883
|
-
*
|
|
7212
|
+
* 3. **Salt collision.** A predicted address commits to `(implementation,
|
|
6884
7213
|
* mode, deployer, userSalt)` and ignores the params struct entirely, so
|
|
6885
7214
|
* two campaigns differing only in token, window, signer or root still
|
|
6886
7215
|
* land on one address. The prediction plus one `eth_getCode` turns that
|
|
@@ -6891,6 +7220,12 @@ var ConfidentialAirdropFactoryClient = class {
|
|
|
6891
7220
|
*/
|
|
6892
7221
|
async #guardCreate(input) {
|
|
6893
7222
|
const { variant, args, deployer, method } = input;
|
|
7223
|
+
await assertGasFeeAccepted({
|
|
7224
|
+
factory: this,
|
|
7225
|
+
creator: deployer,
|
|
7226
|
+
maxAcceptedGasFee: args.params.common.maxAcceptedGasFee,
|
|
7227
|
+
method
|
|
7228
|
+
});
|
|
6894
7229
|
await assertStockWrapper({
|
|
6895
7230
|
publicClient: this.publicClient,
|
|
6896
7231
|
token: args.params.common.token,
|
|
@@ -7330,22 +7665,6 @@ var merkleConfidentialAirdropAbi = [
|
|
|
7330
7665
|
name: "SafeERC20FailedOperation",
|
|
7331
7666
|
type: "error"
|
|
7332
7667
|
},
|
|
7333
|
-
{
|
|
7334
|
-
inputs: [
|
|
7335
|
-
{
|
|
7336
|
-
internalType: "bytes32",
|
|
7337
|
-
name: "handle",
|
|
7338
|
-
type: "bytes32"
|
|
7339
|
-
},
|
|
7340
|
-
{
|
|
7341
|
-
internalType: "address",
|
|
7342
|
-
name: "sender",
|
|
7343
|
-
type: "address"
|
|
7344
|
-
}
|
|
7345
|
-
],
|
|
7346
|
-
name: "SenderNotAllowedToUseHandle",
|
|
7347
|
-
type: "error"
|
|
7348
|
-
},
|
|
7349
7668
|
{
|
|
7350
7669
|
inputs: [],
|
|
7351
7670
|
name: "TokenNotAWrapper",
|
|
@@ -7372,11 +7691,32 @@ var merkleConfidentialAirdropAbi = [
|
|
|
7372
7691
|
name: "UUPSUnsupportedProxiableUUID",
|
|
7373
7692
|
type: "error"
|
|
7374
7693
|
},
|
|
7694
|
+
{
|
|
7695
|
+
inputs: [
|
|
7696
|
+
{
|
|
7697
|
+
internalType: "address",
|
|
7698
|
+
name: "account",
|
|
7699
|
+
type: "address"
|
|
7700
|
+
},
|
|
7701
|
+
{
|
|
7702
|
+
internalType: "address",
|
|
7703
|
+
name: "to",
|
|
7704
|
+
type: "address"
|
|
7705
|
+
}
|
|
7706
|
+
],
|
|
7707
|
+
name: "UnauthorizedRedirect",
|
|
7708
|
+
type: "error"
|
|
7709
|
+
},
|
|
7375
7710
|
{
|
|
7376
7711
|
inputs: [],
|
|
7377
7712
|
name: "ZamaProtocolUnsupported",
|
|
7378
7713
|
type: "error"
|
|
7379
7714
|
},
|
|
7715
|
+
{
|
|
7716
|
+
inputs: [],
|
|
7717
|
+
name: "ZeroAccount",
|
|
7718
|
+
type: "error"
|
|
7719
|
+
},
|
|
7380
7720
|
{
|
|
7381
7721
|
inputs: [],
|
|
7382
7722
|
name: "ZeroAdminGrant",
|
|
@@ -7417,6 +7757,11 @@ var merkleConfidentialAirdropAbi = [
|
|
|
7417
7757
|
name: "ZeroToken",
|
|
7418
7758
|
type: "error"
|
|
7419
7759
|
},
|
|
7760
|
+
{
|
|
7761
|
+
inputs: [],
|
|
7762
|
+
name: "ZeroUnwrapRequestId",
|
|
7763
|
+
type: "error"
|
|
7764
|
+
},
|
|
7420
7765
|
{
|
|
7421
7766
|
anonymous: false,
|
|
7422
7767
|
inputs: [
|
|
@@ -7449,6 +7794,12 @@ var merkleConfidentialAirdropAbi = [
|
|
|
7449
7794
|
internalType: "uint256",
|
|
7450
7795
|
name: "deploymentBlockNumber",
|
|
7451
7796
|
type: "uint256"
|
|
7797
|
+
},
|
|
7798
|
+
{
|
|
7799
|
+
indexed: false,
|
|
7800
|
+
internalType: "uint256",
|
|
7801
|
+
name: "gasFee",
|
|
7802
|
+
type: "uint256"
|
|
7452
7803
|
}
|
|
7453
7804
|
],
|
|
7454
7805
|
name: "AirdropInitialized",
|
|
@@ -7998,11 +8349,16 @@ var merkleConfidentialAirdropAbi = [
|
|
|
7998
8349
|
inputs: [
|
|
7999
8350
|
{
|
|
8000
8351
|
internalType: "address",
|
|
8001
|
-
name: "
|
|
8352
|
+
name: "account",
|
|
8002
8353
|
type: "address"
|
|
8003
8354
|
},
|
|
8004
8355
|
{
|
|
8005
|
-
internalType: "
|
|
8356
|
+
internalType: "address",
|
|
8357
|
+
name: "to",
|
|
8358
|
+
type: "address"
|
|
8359
|
+
},
|
|
8360
|
+
{
|
|
8361
|
+
internalType: "externalEuint64",
|
|
8006
8362
|
name: "inputAmount",
|
|
8007
8363
|
type: "bytes32"
|
|
8008
8364
|
},
|
|
@@ -8122,6 +8478,11 @@ var merkleConfidentialAirdropAbi = [
|
|
|
8122
8478
|
},
|
|
8123
8479
|
{
|
|
8124
8480
|
inputs: [
|
|
8481
|
+
{
|
|
8482
|
+
internalType: "address",
|
|
8483
|
+
name: "account",
|
|
8484
|
+
type: "address"
|
|
8485
|
+
},
|
|
8125
8486
|
{
|
|
8126
8487
|
internalType: "externalEuint64",
|
|
8127
8488
|
name: "inputAmount",
|
|
@@ -8466,6 +8827,19 @@ var merkleConfidentialAirdropAbi = [
|
|
|
8466
8827
|
stateMutability: "view",
|
|
8467
8828
|
type: "function"
|
|
8468
8829
|
},
|
|
8830
|
+
{
|
|
8831
|
+
inputs: [],
|
|
8832
|
+
name: "refreshComplianceBalance",
|
|
8833
|
+
outputs: [
|
|
8834
|
+
{
|
|
8835
|
+
internalType: "euint64",
|
|
8836
|
+
name: "balance",
|
|
8837
|
+
type: "bytes32"
|
|
8838
|
+
}
|
|
8839
|
+
],
|
|
8840
|
+
stateMutability: "nonpayable",
|
|
8841
|
+
type: "function"
|
|
8842
|
+
},
|
|
8469
8843
|
{
|
|
8470
8844
|
inputs: [
|
|
8471
8845
|
{
|
|
@@ -8674,8 +9048,8 @@ var MerkleAirdropClient = class extends AirdropBaseClient {
|
|
|
8674
9048
|
// CLAIM
|
|
8675
9049
|
// ============================================================
|
|
8676
9050
|
/**
|
|
8677
|
-
* Claim the outstanding amount for a proof-bearing entry, delivering the
|
|
8678
|
-
*
|
|
9051
|
+
* Claim the outstanding amount for a proof-bearing entry, delivering the tokens to
|
|
9052
|
+
* `to` — which defaults to `entry.account`, the CLAIM IDENTITY, not the sender.
|
|
8679
9053
|
*
|
|
8680
9054
|
* Requires `msg.value == gasFee()` exactly — handled for you; see the
|
|
8681
9055
|
* class TSDoc.
|
|
@@ -8692,16 +9066,31 @@ var MerkleAirdropClient = class extends AirdropBaseClient {
|
|
|
8692
9066
|
*
|
|
8693
9067
|
* @throws {@link ClaimNotStartedError} before `startTime`.
|
|
8694
9068
|
* @throws {@link ClaimWindowClosedError} after `endTime`.
|
|
8695
|
-
* @throws {@link InvalidArgumentError} (`argument: "
|
|
8696
|
-
*
|
|
9069
|
+
* @throws {@link InvalidArgumentError} (`argument: "entry.boundTo"`) when the entry's proof is bound to
|
|
9070
|
+
* another address, or (`argument: "merkleProof"`) when the proof does not verify against the current root.
|
|
9071
|
+
* @throws {@link UnauthorizedRedirectError} when a third-party submitter passes a `to` other than `entry.account`.
|
|
8697
9072
|
* @returns The transaction hash.
|
|
8698
9073
|
*/
|
|
8699
9074
|
async claim(args) {
|
|
8700
9075
|
return withTelemetry(this.telemetry, `${this.spanPrefix}.claim`, async () => {
|
|
9076
|
+
const submitter = this.resolveSender(args.account, "claim");
|
|
9077
|
+
assertMerkleClaimIdentity({
|
|
9078
|
+
method: "claim",
|
|
9079
|
+
account: args.entry.account,
|
|
9080
|
+
boundTo: args.entry.boundTo,
|
|
9081
|
+
submitter,
|
|
9082
|
+
to: args.to
|
|
9083
|
+
});
|
|
8701
9084
|
const fee = await this.gasFee();
|
|
8702
9085
|
return this.write(
|
|
8703
9086
|
"claim",
|
|
8704
|
-
[
|
|
9087
|
+
[
|
|
9088
|
+
args.entry.account,
|
|
9089
|
+
args.to ?? zeroAddress,
|
|
9090
|
+
args.entry.handle,
|
|
9091
|
+
args.entry.inputProof,
|
|
9092
|
+
args.entry.merkleProof
|
|
9093
|
+
],
|
|
8705
9094
|
args.account,
|
|
8706
9095
|
"claim",
|
|
8707
9096
|
fee
|
|
@@ -8717,12 +9106,29 @@ var MerkleAirdropClient = class extends AirdropBaseClient {
|
|
|
8717
9106
|
* Same replay/accounting semantics and `msg.value == gasFee()` requirement
|
|
8718
9107
|
* as {@link claim} — see its `@remarks`.
|
|
8719
9108
|
*
|
|
9109
|
+
* @remarks
|
|
9110
|
+
* **Self-only by design.** This entrypoint takes no claim identity: releasing an
|
|
9111
|
+
* allocation as a public ERC-20 transfer publishes the amount irreversibly, which is
|
|
9112
|
+
* the recipient's own choice to make. A relayed unwrap is therefore unrepresentable
|
|
9113
|
+
* rather than merely rejected, and an entry whose `account` is not the sender is
|
|
9114
|
+
* refused before the write. A third party can still submit a confidential
|
|
9115
|
+
* {@link claim}.
|
|
9116
|
+
*
|
|
8720
9117
|
* @returns The transaction hash. The underlying ERC-20 is released later by
|
|
8721
9118
|
* a separate, permissionless `finalizeUnwrap` — this hash is only the
|
|
8722
9119
|
* unwrap request.
|
|
8723
9120
|
*/
|
|
8724
9121
|
async claimAndUnwrap(args) {
|
|
8725
9122
|
return withTelemetry(this.telemetry, `${this.spanPrefix}.claimAndUnwrap`, async () => {
|
|
9123
|
+
const submitter = this.resolveSender(args.account, "claimAndUnwrap");
|
|
9124
|
+
assertMerkleClaimIdentity({
|
|
9125
|
+
method: "claimAndUnwrap",
|
|
9126
|
+
account: args.entry.account,
|
|
9127
|
+
boundTo: args.entry.boundTo,
|
|
9128
|
+
submitter,
|
|
9129
|
+
to: args.to,
|
|
9130
|
+
entrypoint: "claimAndUnwrap"
|
|
9131
|
+
});
|
|
8726
9132
|
const fee = await this.gasFee();
|
|
8727
9133
|
return this.write(
|
|
8728
9134
|
"claimAndUnwrap",
|
|
@@ -8738,16 +9144,32 @@ var MerkleAirdropClient = class extends AirdropBaseClient {
|
|
|
8738
9144
|
* caller can decrypt. Consumes no accounting and no per-leaf state — the
|
|
8739
9145
|
* same entry still pays the same amount after a preview. No fee.
|
|
8740
9146
|
*
|
|
8741
|
-
*
|
|
8742
|
-
*
|
|
8743
|
-
*
|
|
9147
|
+
* **Submits a transaction.** The contract calls `FHE.allow(outstanding, account)`, so
|
|
9148
|
+
* the result is recovered from the receipt's ACL `Allowed` event, never from a
|
|
9149
|
+
* simulation. See {@link AirdropBaseClient}'s class TSDoc.
|
|
8744
9150
|
*
|
|
8745
|
-
*
|
|
9151
|
+
* **`entry.account` is the decryptable party, not the caller.** A relayer previewing on
|
|
9152
|
+
* someone's behalf gets a valid handle it cannot read — that is the contract's intent,
|
|
9153
|
+
* and it is what makes a blind relayed submission possible.
|
|
9154
|
+
*
|
|
9155
|
+
* @returns `{ handle, hash }` — pass `handle` to the Zama relayer's `userDecrypt`, as `entry.account`.
|
|
8746
9156
|
*/
|
|
8747
9157
|
async getClaimAmount(args) {
|
|
9158
|
+
const submitter = this.resolveSender(args.account, "getClaimAmount");
|
|
9159
|
+
assertMerkleClaimIdentity({
|
|
9160
|
+
method: "getClaimAmount",
|
|
9161
|
+
account: args.entry.account,
|
|
9162
|
+
boundTo: args.entry.boundTo,
|
|
9163
|
+
submitter
|
|
9164
|
+
});
|
|
8748
9165
|
return this.encryptedView({
|
|
8749
9166
|
functionName: "getClaimAmount",
|
|
8750
|
-
args: [args.entry.handle, args.entry.inputProof, args.entry.merkleProof],
|
|
9167
|
+
args: [args.entry.account, args.entry.handle, args.entry.inputProof, args.entry.merkleProof],
|
|
9168
|
+
// The contract grants the outstanding handle to `account`, never to the caller
|
|
9169
|
+
// (`_outstandingOf(account, account, …)`), so the receipt's ACL `Allowed` event
|
|
9170
|
+
// names the account. Defaulting to the sender would fail extraction on any
|
|
9171
|
+
// relayed preview — after the transaction had already been mined.
|
|
9172
|
+
grantee: args.entry.account,
|
|
8751
9173
|
account: args.account
|
|
8752
9174
|
});
|
|
8753
9175
|
}
|
|
@@ -8770,10 +9192,15 @@ var MerkleAirdropClient = class extends AirdropBaseClient {
|
|
|
8770
9192
|
* leaves for the same recipient, claiming both pays the higher of the
|
|
8771
9193
|
* two totals net of this running value — `max`, not `sum`.
|
|
8772
9194
|
*
|
|
8773
|
-
*
|
|
8774
|
-
*
|
|
9195
|
+
* **An account that has never claimed returns the ZERO handle, which cannot be
|
|
9196
|
+
* decrypted.** It is an uninitialized ciphertext, so nobody holds an ACL on it and
|
|
9197
|
+
* the relayer rejects it with "not authorized to user decrypt handle 0x0…0" rather
|
|
9198
|
+
* than answering zero. Treat `handle === zeroHash` as "nothing delivered yet" and
|
|
9199
|
+
* skip the decrypt; only call `userDecrypt` on a non-zero handle. (A mock FHEVM
|
|
9200
|
+
* instance does answer zero here, so this only bites against a live relayer.)
|
|
8775
9201
|
*
|
|
8776
|
-
* @returns The account's cumulative delivered total
|
|
9202
|
+
* @returns The account's cumulative delivered total as an encrypted handle, or the
|
|
9203
|
+
* zero handle if it has never claimed.
|
|
8777
9204
|
*/
|
|
8778
9205
|
async getClaimedAmount(account) {
|
|
8779
9206
|
const handle = await this.read("getClaimedAmount", [account]);
|
|
@@ -8820,4 +9247,919 @@ function createMerkleAirdropClient(config) {
|
|
|
8820
9247
|
return new MerkleAirdropClient(config);
|
|
8821
9248
|
}
|
|
8822
9249
|
|
|
8823
|
-
|
|
9250
|
+
// src/fhe-airdrop/abis/compliance.ts
|
|
9251
|
+
var complianceRoleManagerAbi = [
|
|
9252
|
+
{
|
|
9253
|
+
inputs: [],
|
|
9254
|
+
stateMutability: "nonpayable",
|
|
9255
|
+
type: "constructor"
|
|
9256
|
+
},
|
|
9257
|
+
{
|
|
9258
|
+
inputs: [],
|
|
9259
|
+
name: "AccessControlBadConfirmation",
|
|
9260
|
+
type: "error"
|
|
9261
|
+
},
|
|
9262
|
+
{
|
|
9263
|
+
inputs: [
|
|
9264
|
+
{
|
|
9265
|
+
internalType: "address",
|
|
9266
|
+
name: "account",
|
|
9267
|
+
type: "address"
|
|
9268
|
+
},
|
|
9269
|
+
{
|
|
9270
|
+
internalType: "bytes32",
|
|
9271
|
+
name: "neededRole",
|
|
9272
|
+
type: "bytes32"
|
|
9273
|
+
}
|
|
9274
|
+
],
|
|
9275
|
+
name: "AccessControlUnauthorizedAccount",
|
|
9276
|
+
type: "error"
|
|
9277
|
+
},
|
|
9278
|
+
{
|
|
9279
|
+
inputs: [
|
|
9280
|
+
{
|
|
9281
|
+
internalType: "address",
|
|
9282
|
+
name: "airdrop",
|
|
9283
|
+
type: "address"
|
|
9284
|
+
}
|
|
9285
|
+
],
|
|
9286
|
+
name: "AirdropAndManagerAreSameAddress",
|
|
9287
|
+
type: "error"
|
|
9288
|
+
},
|
|
9289
|
+
{
|
|
9290
|
+
inputs: [],
|
|
9291
|
+
name: "CannotManageComplianceDelegate",
|
|
9292
|
+
type: "error"
|
|
9293
|
+
},
|
|
9294
|
+
{
|
|
9295
|
+
inputs: [],
|
|
9296
|
+
name: "DelegateAlreadyAdded",
|
|
9297
|
+
type: "error"
|
|
9298
|
+
},
|
|
9299
|
+
{
|
|
9300
|
+
inputs: [
|
|
9301
|
+
{
|
|
9302
|
+
internalType: "address",
|
|
9303
|
+
name: "delegate",
|
|
9304
|
+
type: "address"
|
|
9305
|
+
}
|
|
9306
|
+
],
|
|
9307
|
+
name: "DelegateAndAirdropAreSameAddress",
|
|
9308
|
+
type: "error"
|
|
9309
|
+
},
|
|
9310
|
+
{
|
|
9311
|
+
inputs: [
|
|
9312
|
+
{
|
|
9313
|
+
internalType: "address",
|
|
9314
|
+
name: "delegate",
|
|
9315
|
+
type: "address"
|
|
9316
|
+
}
|
|
9317
|
+
],
|
|
9318
|
+
name: "DelegateAndManagerAreSameAddress",
|
|
9319
|
+
type: "error"
|
|
9320
|
+
},
|
|
9321
|
+
{
|
|
9322
|
+
inputs: [],
|
|
9323
|
+
name: "DelegateNotFound",
|
|
9324
|
+
type: "error"
|
|
9325
|
+
},
|
|
9326
|
+
{
|
|
9327
|
+
inputs: [],
|
|
9328
|
+
name: "InvalidInitialization",
|
|
9329
|
+
type: "error"
|
|
9330
|
+
},
|
|
9331
|
+
{
|
|
9332
|
+
inputs: [],
|
|
9333
|
+
name: "NotInitializing",
|
|
9334
|
+
type: "error"
|
|
9335
|
+
},
|
|
9336
|
+
{
|
|
9337
|
+
inputs: [],
|
|
9338
|
+
name: "ZamaProtocolUnsupported",
|
|
9339
|
+
type: "error"
|
|
9340
|
+
},
|
|
9341
|
+
{
|
|
9342
|
+
inputs: [],
|
|
9343
|
+
name: "ZeroAirdrop",
|
|
9344
|
+
type: "error"
|
|
9345
|
+
},
|
|
9346
|
+
{
|
|
9347
|
+
inputs: [],
|
|
9348
|
+
name: "ZeroClientAdmin",
|
|
9349
|
+
type: "error"
|
|
9350
|
+
},
|
|
9351
|
+
{
|
|
9352
|
+
inputs: [],
|
|
9353
|
+
name: "ZeroDelegate",
|
|
9354
|
+
type: "error"
|
|
9355
|
+
},
|
|
9356
|
+
{
|
|
9357
|
+
anonymous: false,
|
|
9358
|
+
inputs: [
|
|
9359
|
+
{
|
|
9360
|
+
indexed: true,
|
|
9361
|
+
internalType: "address",
|
|
9362
|
+
name: "delegate",
|
|
9363
|
+
type: "address"
|
|
9364
|
+
}
|
|
9365
|
+
],
|
|
9366
|
+
name: "ClientDelegateAdded",
|
|
9367
|
+
type: "event"
|
|
9368
|
+
},
|
|
9369
|
+
{
|
|
9370
|
+
anonymous: false,
|
|
9371
|
+
inputs: [
|
|
9372
|
+
{
|
|
9373
|
+
indexed: true,
|
|
9374
|
+
internalType: "address",
|
|
9375
|
+
name: "delegate",
|
|
9376
|
+
type: "address"
|
|
9377
|
+
}
|
|
9378
|
+
],
|
|
9379
|
+
name: "ClientDelegateRevoked",
|
|
9380
|
+
type: "event"
|
|
9381
|
+
},
|
|
9382
|
+
{
|
|
9383
|
+
anonymous: false,
|
|
9384
|
+
inputs: [
|
|
9385
|
+
{
|
|
9386
|
+
indexed: true,
|
|
9387
|
+
internalType: "address",
|
|
9388
|
+
name: "delegate",
|
|
9389
|
+
type: "address"
|
|
9390
|
+
}
|
|
9391
|
+
],
|
|
9392
|
+
name: "ComplianceDelegateSet",
|
|
9393
|
+
type: "event"
|
|
9394
|
+
},
|
|
9395
|
+
{
|
|
9396
|
+
anonymous: false,
|
|
9397
|
+
inputs: [
|
|
9398
|
+
{
|
|
9399
|
+
indexed: false,
|
|
9400
|
+
internalType: "uint64",
|
|
9401
|
+
name: "version",
|
|
9402
|
+
type: "uint64"
|
|
9403
|
+
}
|
|
9404
|
+
],
|
|
9405
|
+
name: "Initialized",
|
|
9406
|
+
type: "event"
|
|
9407
|
+
},
|
|
9408
|
+
{
|
|
9409
|
+
anonymous: false,
|
|
9410
|
+
inputs: [
|
|
9411
|
+
{
|
|
9412
|
+
indexed: true,
|
|
9413
|
+
internalType: "bytes32",
|
|
9414
|
+
name: "role",
|
|
9415
|
+
type: "bytes32"
|
|
9416
|
+
},
|
|
9417
|
+
{
|
|
9418
|
+
indexed: true,
|
|
9419
|
+
internalType: "bytes32",
|
|
9420
|
+
name: "previousAdminRole",
|
|
9421
|
+
type: "bytes32"
|
|
9422
|
+
},
|
|
9423
|
+
{
|
|
9424
|
+
indexed: true,
|
|
9425
|
+
internalType: "bytes32",
|
|
9426
|
+
name: "newAdminRole",
|
|
9427
|
+
type: "bytes32"
|
|
9428
|
+
}
|
|
9429
|
+
],
|
|
9430
|
+
name: "RoleAdminChanged",
|
|
9431
|
+
type: "event"
|
|
9432
|
+
},
|
|
9433
|
+
{
|
|
9434
|
+
anonymous: false,
|
|
9435
|
+
inputs: [
|
|
9436
|
+
{
|
|
9437
|
+
indexed: true,
|
|
9438
|
+
internalType: "bytes32",
|
|
9439
|
+
name: "role",
|
|
9440
|
+
type: "bytes32"
|
|
9441
|
+
},
|
|
9442
|
+
{
|
|
9443
|
+
indexed: true,
|
|
9444
|
+
internalType: "address",
|
|
9445
|
+
name: "account",
|
|
9446
|
+
type: "address"
|
|
9447
|
+
},
|
|
9448
|
+
{
|
|
9449
|
+
indexed: true,
|
|
9450
|
+
internalType: "address",
|
|
9451
|
+
name: "sender",
|
|
9452
|
+
type: "address"
|
|
9453
|
+
}
|
|
9454
|
+
],
|
|
9455
|
+
name: "RoleGranted",
|
|
9456
|
+
type: "event"
|
|
9457
|
+
},
|
|
9458
|
+
{
|
|
9459
|
+
anonymous: false,
|
|
9460
|
+
inputs: [
|
|
9461
|
+
{
|
|
9462
|
+
indexed: true,
|
|
9463
|
+
internalType: "bytes32",
|
|
9464
|
+
name: "role",
|
|
9465
|
+
type: "bytes32"
|
|
9466
|
+
},
|
|
9467
|
+
{
|
|
9468
|
+
indexed: true,
|
|
9469
|
+
internalType: "address",
|
|
9470
|
+
name: "account",
|
|
9471
|
+
type: "address"
|
|
9472
|
+
},
|
|
9473
|
+
{
|
|
9474
|
+
indexed: true,
|
|
9475
|
+
internalType: "address",
|
|
9476
|
+
name: "sender",
|
|
9477
|
+
type: "address"
|
|
9478
|
+
}
|
|
9479
|
+
],
|
|
9480
|
+
name: "RoleRevoked",
|
|
9481
|
+
type: "event"
|
|
9482
|
+
},
|
|
9483
|
+
{
|
|
9484
|
+
inputs: [],
|
|
9485
|
+
name: "DEFAULT_ADMIN_ROLE",
|
|
9486
|
+
outputs: [
|
|
9487
|
+
{
|
|
9488
|
+
internalType: "bytes32",
|
|
9489
|
+
name: "",
|
|
9490
|
+
type: "bytes32"
|
|
9491
|
+
}
|
|
9492
|
+
],
|
|
9493
|
+
stateMutability: "view",
|
|
9494
|
+
type: "function"
|
|
9495
|
+
},
|
|
9496
|
+
{
|
|
9497
|
+
inputs: [],
|
|
9498
|
+
name: "DELEGATION_ADMIN_ROLE",
|
|
9499
|
+
outputs: [
|
|
9500
|
+
{
|
|
9501
|
+
internalType: "bytes32",
|
|
9502
|
+
name: "",
|
|
9503
|
+
type: "bytes32"
|
|
9504
|
+
}
|
|
9505
|
+
],
|
|
9506
|
+
stateMutability: "view",
|
|
9507
|
+
type: "function"
|
|
9508
|
+
},
|
|
9509
|
+
{
|
|
9510
|
+
inputs: [
|
|
9511
|
+
{
|
|
9512
|
+
internalType: "address",
|
|
9513
|
+
name: "delegate",
|
|
9514
|
+
type: "address"
|
|
9515
|
+
}
|
|
9516
|
+
],
|
|
9517
|
+
name: "addDelegate",
|
|
9518
|
+
outputs: [],
|
|
9519
|
+
stateMutability: "nonpayable",
|
|
9520
|
+
type: "function"
|
|
9521
|
+
},
|
|
9522
|
+
{
|
|
9523
|
+
inputs: [],
|
|
9524
|
+
name: "airdrop",
|
|
9525
|
+
outputs: [
|
|
9526
|
+
{
|
|
9527
|
+
internalType: "address",
|
|
9528
|
+
name: "",
|
|
9529
|
+
type: "address"
|
|
9530
|
+
}
|
|
9531
|
+
],
|
|
9532
|
+
stateMutability: "view",
|
|
9533
|
+
type: "function"
|
|
9534
|
+
},
|
|
9535
|
+
{
|
|
9536
|
+
inputs: [],
|
|
9537
|
+
name: "clientDelegates",
|
|
9538
|
+
outputs: [
|
|
9539
|
+
{
|
|
9540
|
+
internalType: "address[]",
|
|
9541
|
+
name: "",
|
|
9542
|
+
type: "address[]"
|
|
9543
|
+
}
|
|
9544
|
+
],
|
|
9545
|
+
stateMutability: "view",
|
|
9546
|
+
type: "function"
|
|
9547
|
+
},
|
|
9548
|
+
{
|
|
9549
|
+
inputs: [],
|
|
9550
|
+
name: "complianceDelegate",
|
|
9551
|
+
outputs: [
|
|
9552
|
+
{
|
|
9553
|
+
internalType: "address",
|
|
9554
|
+
name: "",
|
|
9555
|
+
type: "address"
|
|
9556
|
+
}
|
|
9557
|
+
],
|
|
9558
|
+
stateMutability: "view",
|
|
9559
|
+
type: "function"
|
|
9560
|
+
},
|
|
9561
|
+
{
|
|
9562
|
+
inputs: [
|
|
9563
|
+
{
|
|
9564
|
+
internalType: "bytes32",
|
|
9565
|
+
name: "role",
|
|
9566
|
+
type: "bytes32"
|
|
9567
|
+
}
|
|
9568
|
+
],
|
|
9569
|
+
name: "getRoleAdmin",
|
|
9570
|
+
outputs: [
|
|
9571
|
+
{
|
|
9572
|
+
internalType: "bytes32",
|
|
9573
|
+
name: "",
|
|
9574
|
+
type: "bytes32"
|
|
9575
|
+
}
|
|
9576
|
+
],
|
|
9577
|
+
stateMutability: "view",
|
|
9578
|
+
type: "function"
|
|
9579
|
+
},
|
|
9580
|
+
{
|
|
9581
|
+
inputs: [
|
|
9582
|
+
{
|
|
9583
|
+
internalType: "bytes32",
|
|
9584
|
+
name: "role",
|
|
9585
|
+
type: "bytes32"
|
|
9586
|
+
},
|
|
9587
|
+
{
|
|
9588
|
+
internalType: "uint256",
|
|
9589
|
+
name: "index",
|
|
9590
|
+
type: "uint256"
|
|
9591
|
+
}
|
|
9592
|
+
],
|
|
9593
|
+
name: "getRoleMember",
|
|
9594
|
+
outputs: [
|
|
9595
|
+
{
|
|
9596
|
+
internalType: "address",
|
|
9597
|
+
name: "",
|
|
9598
|
+
type: "address"
|
|
9599
|
+
}
|
|
9600
|
+
],
|
|
9601
|
+
stateMutability: "view",
|
|
9602
|
+
type: "function"
|
|
9603
|
+
},
|
|
9604
|
+
{
|
|
9605
|
+
inputs: [
|
|
9606
|
+
{
|
|
9607
|
+
internalType: "bytes32",
|
|
9608
|
+
name: "role",
|
|
9609
|
+
type: "bytes32"
|
|
9610
|
+
}
|
|
9611
|
+
],
|
|
9612
|
+
name: "getRoleMemberCount",
|
|
9613
|
+
outputs: [
|
|
9614
|
+
{
|
|
9615
|
+
internalType: "uint256",
|
|
9616
|
+
name: "",
|
|
9617
|
+
type: "uint256"
|
|
9618
|
+
}
|
|
9619
|
+
],
|
|
9620
|
+
stateMutability: "view",
|
|
9621
|
+
type: "function"
|
|
9622
|
+
},
|
|
9623
|
+
{
|
|
9624
|
+
inputs: [
|
|
9625
|
+
{
|
|
9626
|
+
internalType: "bytes32",
|
|
9627
|
+
name: "role",
|
|
9628
|
+
type: "bytes32"
|
|
9629
|
+
}
|
|
9630
|
+
],
|
|
9631
|
+
name: "getRoleMembers",
|
|
9632
|
+
outputs: [
|
|
9633
|
+
{
|
|
9634
|
+
internalType: "address[]",
|
|
9635
|
+
name: "",
|
|
9636
|
+
type: "address[]"
|
|
9637
|
+
}
|
|
9638
|
+
],
|
|
9639
|
+
stateMutability: "view",
|
|
9640
|
+
type: "function"
|
|
9641
|
+
},
|
|
9642
|
+
{
|
|
9643
|
+
inputs: [
|
|
9644
|
+
{
|
|
9645
|
+
internalType: "bytes32",
|
|
9646
|
+
name: "role",
|
|
9647
|
+
type: "bytes32"
|
|
9648
|
+
},
|
|
9649
|
+
{
|
|
9650
|
+
internalType: "address",
|
|
9651
|
+
name: "account",
|
|
9652
|
+
type: "address"
|
|
9653
|
+
}
|
|
9654
|
+
],
|
|
9655
|
+
name: "grantRole",
|
|
9656
|
+
outputs: [],
|
|
9657
|
+
stateMutability: "nonpayable",
|
|
9658
|
+
type: "function"
|
|
9659
|
+
},
|
|
9660
|
+
{
|
|
9661
|
+
inputs: [
|
|
9662
|
+
{
|
|
9663
|
+
internalType: "bytes32",
|
|
9664
|
+
name: "role",
|
|
9665
|
+
type: "bytes32"
|
|
9666
|
+
},
|
|
9667
|
+
{
|
|
9668
|
+
internalType: "address",
|
|
9669
|
+
name: "account",
|
|
9670
|
+
type: "address"
|
|
9671
|
+
}
|
|
9672
|
+
],
|
|
9673
|
+
name: "hasRole",
|
|
9674
|
+
outputs: [
|
|
9675
|
+
{
|
|
9676
|
+
internalType: "bool",
|
|
9677
|
+
name: "",
|
|
9678
|
+
type: "bool"
|
|
9679
|
+
}
|
|
9680
|
+
],
|
|
9681
|
+
stateMutability: "view",
|
|
9682
|
+
type: "function"
|
|
9683
|
+
},
|
|
9684
|
+
{
|
|
9685
|
+
inputs: [
|
|
9686
|
+
{
|
|
9687
|
+
internalType: "address",
|
|
9688
|
+
name: "airdrop_",
|
|
9689
|
+
type: "address"
|
|
9690
|
+
},
|
|
9691
|
+
{
|
|
9692
|
+
internalType: "address",
|
|
9693
|
+
name: "clientAdmin",
|
|
9694
|
+
type: "address"
|
|
9695
|
+
},
|
|
9696
|
+
{
|
|
9697
|
+
internalType: "address",
|
|
9698
|
+
name: "clientDelegate",
|
|
9699
|
+
type: "address"
|
|
9700
|
+
},
|
|
9701
|
+
{
|
|
9702
|
+
internalType: "address",
|
|
9703
|
+
name: "complianceDelegate_",
|
|
9704
|
+
type: "address"
|
|
9705
|
+
}
|
|
9706
|
+
],
|
|
9707
|
+
name: "initialize",
|
|
9708
|
+
outputs: [],
|
|
9709
|
+
stateMutability: "nonpayable",
|
|
9710
|
+
type: "function"
|
|
9711
|
+
},
|
|
9712
|
+
{
|
|
9713
|
+
inputs: [
|
|
9714
|
+
{
|
|
9715
|
+
internalType: "address",
|
|
9716
|
+
name: "delegate",
|
|
9717
|
+
type: "address"
|
|
9718
|
+
}
|
|
9719
|
+
],
|
|
9720
|
+
name: "isActiveDelegate",
|
|
9721
|
+
outputs: [
|
|
9722
|
+
{
|
|
9723
|
+
internalType: "bool",
|
|
9724
|
+
name: "",
|
|
9725
|
+
type: "bool"
|
|
9726
|
+
}
|
|
9727
|
+
],
|
|
9728
|
+
stateMutability: "view",
|
|
9729
|
+
type: "function"
|
|
9730
|
+
},
|
|
9731
|
+
{
|
|
9732
|
+
inputs: [
|
|
9733
|
+
{
|
|
9734
|
+
internalType: "bytes32",
|
|
9735
|
+
name: "role",
|
|
9736
|
+
type: "bytes32"
|
|
9737
|
+
},
|
|
9738
|
+
{
|
|
9739
|
+
internalType: "address",
|
|
9740
|
+
name: "callerConfirmation",
|
|
9741
|
+
type: "address"
|
|
9742
|
+
}
|
|
9743
|
+
],
|
|
9744
|
+
name: "renounceRole",
|
|
9745
|
+
outputs: [],
|
|
9746
|
+
stateMutability: "nonpayable",
|
|
9747
|
+
type: "function"
|
|
9748
|
+
},
|
|
9749
|
+
{
|
|
9750
|
+
inputs: [
|
|
9751
|
+
{
|
|
9752
|
+
internalType: "address",
|
|
9753
|
+
name: "delegate",
|
|
9754
|
+
type: "address"
|
|
9755
|
+
}
|
|
9756
|
+
],
|
|
9757
|
+
name: "revokeDelegate",
|
|
9758
|
+
outputs: [],
|
|
9759
|
+
stateMutability: "nonpayable",
|
|
9760
|
+
type: "function"
|
|
9761
|
+
},
|
|
9762
|
+
{
|
|
9763
|
+
inputs: [
|
|
9764
|
+
{
|
|
9765
|
+
internalType: "bytes32",
|
|
9766
|
+
name: "role",
|
|
9767
|
+
type: "bytes32"
|
|
9768
|
+
},
|
|
9769
|
+
{
|
|
9770
|
+
internalType: "address",
|
|
9771
|
+
name: "account",
|
|
9772
|
+
type: "address"
|
|
9773
|
+
}
|
|
9774
|
+
],
|
|
9775
|
+
name: "revokeRole",
|
|
9776
|
+
outputs: [],
|
|
9777
|
+
stateMutability: "nonpayable",
|
|
9778
|
+
type: "function"
|
|
9779
|
+
},
|
|
9780
|
+
{
|
|
9781
|
+
inputs: [
|
|
9782
|
+
{
|
|
9783
|
+
internalType: "bytes4",
|
|
9784
|
+
name: "interfaceId",
|
|
9785
|
+
type: "bytes4"
|
|
9786
|
+
}
|
|
9787
|
+
],
|
|
9788
|
+
name: "supportsInterface",
|
|
9789
|
+
outputs: [
|
|
9790
|
+
{
|
|
9791
|
+
internalType: "bool",
|
|
9792
|
+
name: "",
|
|
9793
|
+
type: "bool"
|
|
9794
|
+
}
|
|
9795
|
+
],
|
|
9796
|
+
stateMutability: "view",
|
|
9797
|
+
type: "function"
|
|
9798
|
+
}
|
|
9799
|
+
];
|
|
9800
|
+
|
|
9801
|
+
// src/fhe-airdrop/compliance.ts
|
|
9802
|
+
var ACL_PROPAGATION_CODE = "DELEGATION_NOT_PROPAGATED";
|
|
9803
|
+
var ACL_PROPAGATION_ERROR_NAME = "DelegationNotPropagatedError";
|
|
9804
|
+
var ACL_PROPAGATION_STATUSES = /* @__PURE__ */ new Set([400, 500]);
|
|
9805
|
+
function matchesPropagationMessage(message) {
|
|
9806
|
+
const lower = message.toLowerCase();
|
|
9807
|
+
if (lower.includes("acl check not propagated")) return true;
|
|
9808
|
+
return lower.includes("propagat") && lower.includes("gateway");
|
|
9809
|
+
}
|
|
9810
|
+
function readRecord(value) {
|
|
9811
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
9812
|
+
}
|
|
9813
|
+
function readNumber(obj, key) {
|
|
9814
|
+
const value = obj?.[key];
|
|
9815
|
+
return typeof value === "number" ? value : void 0;
|
|
9816
|
+
}
|
|
9817
|
+
function readString(obj, key) {
|
|
9818
|
+
const value = obj?.[key];
|
|
9819
|
+
return typeof value === "string" ? value : void 0;
|
|
9820
|
+
}
|
|
9821
|
+
function isAclPropagationError(error) {
|
|
9822
|
+
const err = readRecord(error);
|
|
9823
|
+
if (!err) return false;
|
|
9824
|
+
const cause = readRecord(err["cause"]);
|
|
9825
|
+
if (err["code"] === ACL_PROPAGATION_CODE || err["name"] === ACL_PROPAGATION_ERROR_NAME || cause?.["code"] === ACL_PROPAGATION_CODE || cause?.["name"] === ACL_PROPAGATION_ERROR_NAME) {
|
|
9826
|
+
return true;
|
|
9827
|
+
}
|
|
9828
|
+
const status = readNumber(err, "status") ?? readNumber(err, "statusCode") ?? readNumber(cause, "status") ?? readNumber(cause, "statusCode");
|
|
9829
|
+
if (status === void 0 || !ACL_PROPAGATION_STATUSES.has(status)) return false;
|
|
9830
|
+
const errMessage = readString(err, "message");
|
|
9831
|
+
const causeMessage = readString(cause, "message");
|
|
9832
|
+
return errMessage !== void 0 && matchesPropagationMessage(errMessage) || causeMessage !== void 0 && matchesPropagationMessage(causeMessage);
|
|
9833
|
+
}
|
|
9834
|
+
var ComplianceManagerClient = class {
|
|
9835
|
+
publicClient;
|
|
9836
|
+
walletClient;
|
|
9837
|
+
address;
|
|
9838
|
+
chainId;
|
|
9839
|
+
#telemetry;
|
|
9840
|
+
constructor(config) {
|
|
9841
|
+
this.publicClient = config.publicClient;
|
|
9842
|
+
this.walletClient = config.walletClient;
|
|
9843
|
+
const chainId = config.chainId ?? config.publicClient.chain?.id;
|
|
9844
|
+
if (chainId === void 0) {
|
|
9845
|
+
throw new DeploymentAddressUnavailableError({
|
|
9846
|
+
reason: "chain-id-missing",
|
|
9847
|
+
product: "fheAirdrop",
|
|
9848
|
+
contract: "complianceManager",
|
|
9849
|
+
clientLabel: "ComplianceManagerClient"
|
|
9850
|
+
});
|
|
9851
|
+
}
|
|
9852
|
+
assertSupportedChain(chainId);
|
|
9853
|
+
this.chainId = chainId;
|
|
9854
|
+
this.address = normaliseAddress(config.address);
|
|
9855
|
+
this.#telemetry = config.telemetry;
|
|
9856
|
+
this.#telemetry?.event("fhe-airdrop.client.init", {
|
|
9857
|
+
surface: "compliance",
|
|
9858
|
+
chainId,
|
|
9859
|
+
hasWallet: !!this.walletClient,
|
|
9860
|
+
sdkVersion: SDK_VERSION
|
|
9861
|
+
});
|
|
9862
|
+
}
|
|
9863
|
+
// ============================================================
|
|
9864
|
+
// CLIENT DELEGATION MGMT
|
|
9865
|
+
// ============================================================
|
|
9866
|
+
/**
|
|
9867
|
+
* Add a client delegate: grants `delegate` permanent (never-expiring)
|
|
9868
|
+
* user-decryption delegation over this clone's airdrop. Requires
|
|
9869
|
+
* {@link DELEGATION_ADMIN_ROLE}.
|
|
9870
|
+
*
|
|
9871
|
+
* Effective on-chain immediately; see the class TSDoc for the gateway
|
|
9872
|
+
* propagation lag before `delegatedUserDecrypt` catches up.
|
|
9873
|
+
*
|
|
9874
|
+
* @throws {@link InvalidArgumentError} (`argument: "delegate"`) when `delegate` is the zero address
|
|
9875
|
+
* (`ZeroDelegate`), already an active client delegate (`DelegateAlreadyAdded`), or targets the
|
|
9876
|
+
* irrevocable platform compliance delegate (`CannotManageComplianceDelegate`).
|
|
9877
|
+
* @returns The transaction hash.
|
|
9878
|
+
*/
|
|
9879
|
+
async addDelegate(args) {
|
|
9880
|
+
return withTelemetry(
|
|
9881
|
+
this.#telemetry,
|
|
9882
|
+
"fhe-airdrop.compliance.addDelegate",
|
|
9883
|
+
() => this.#write("addDelegate", [args.delegate], args.account, "addDelegate")
|
|
9884
|
+
);
|
|
9885
|
+
}
|
|
9886
|
+
/**
|
|
9887
|
+
* Revoke a client delegate. Requires {@link DELEGATION_ADMIN_ROLE}.
|
|
9888
|
+
*
|
|
9889
|
+
* Effective on-chain immediately — but off-chain, gateway-served
|
|
9890
|
+
* `delegatedUserDecrypt` calls stop succeeding only once the gateway
|
|
9891
|
+
* observes the revocation, which is not instantaneous either. Cannot target
|
|
9892
|
+
* the platform compliance delegate, which is irrevocable by construction.
|
|
9893
|
+
*
|
|
9894
|
+
* **Not in the same block as {@link addDelegate} for the same delegate.**
|
|
9895
|
+
* The FHEVM ACL rejects an add and a revoke of one delegate within a single
|
|
9896
|
+
* block (`AlreadyDelegatedOrRevokedInSameBlock`), and because that revert
|
|
9897
|
+
* comes from the ACL rather than from this contract, it surfaces as an
|
|
9898
|
+
* opaque {@link ContractRevertError} with no decodable selector — nothing
|
|
9899
|
+
* names the delegate or the cause. Batching an add and a revoke into one
|
|
9900
|
+
* multicall, or sending both inside one block, is the way to hit it; wait a
|
|
9901
|
+
* block between them. This is the sequencing counterpart to the propagation
|
|
9902
|
+
* gotcha on the class TSDoc: that one is the gateway lagging the chain, this
|
|
9903
|
+
* one is the chain refusing two conflicting writes at the same height.
|
|
9904
|
+
*
|
|
9905
|
+
* @throws {@link InvalidArgumentError} (`argument: "delegate"`) when `delegate` is the zero address
|
|
9906
|
+
* (`ZeroDelegate`), not currently an active client delegate (`DelegateNotFound`), or targets the
|
|
9907
|
+
* irrevocable platform compliance delegate (`CannotManageComplianceDelegate`).
|
|
9908
|
+
* @returns The transaction hash.
|
|
9909
|
+
*/
|
|
9910
|
+
async revokeDelegate(args) {
|
|
9911
|
+
return withTelemetry(
|
|
9912
|
+
this.#telemetry,
|
|
9913
|
+
"fhe-airdrop.compliance.revokeDelegate",
|
|
9914
|
+
() => this.#write("revokeDelegate", [args.delegate], args.account, "revokeDelegate")
|
|
9915
|
+
);
|
|
9916
|
+
}
|
|
9917
|
+
// ============================================================
|
|
9918
|
+
// READS
|
|
9919
|
+
// ============================================================
|
|
9920
|
+
/** The one airdrop instance this clone serves — set once, at `initialize`. */
|
|
9921
|
+
async airdrop() {
|
|
9922
|
+
return this.#read("airdrop");
|
|
9923
|
+
}
|
|
9924
|
+
/**
|
|
9925
|
+
* The platform compliance delegate.
|
|
9926
|
+
*
|
|
9927
|
+
* @returns The delegate address, or the zero address when this clone was
|
|
9928
|
+
* created with the platform compliance policy OFF. Because `initialize`
|
|
9929
|
+
* always runs atomically before this client can reach the clone (see the
|
|
9930
|
+
* class TSDoc), a zero return never means "not wired yet" — there is no
|
|
9931
|
+
* such observable state on this contract. It unambiguously means "no
|
|
9932
|
+
* platform delegate for this airdrop."
|
|
9933
|
+
*/
|
|
9934
|
+
async complianceDelegate() {
|
|
9935
|
+
return this.#read("complianceDelegate");
|
|
9936
|
+
}
|
|
9937
|
+
/** The current set of active client delegates (excludes the platform compliance delegate, if any). */
|
|
9938
|
+
async clientDelegates() {
|
|
9939
|
+
return this.#read("clientDelegates");
|
|
9940
|
+
}
|
|
9941
|
+
/**
|
|
9942
|
+
* Authoritative active-delegate check for `delegate` — reads the ACL
|
|
9943
|
+
* expiration date directly rather than the contract's `EnumerableSet`
|
|
9944
|
+
* mirror, so it reflects the platform compliance delegate too (which never
|
|
9945
|
+
* appears in {@link clientDelegates}).
|
|
9946
|
+
*
|
|
9947
|
+
* On-chain truth only: a `true` result means the delegation is live in the
|
|
9948
|
+
* ACL, not that the gateway has caught up with it yet — see the class
|
|
9949
|
+
* TSDoc's propagation note.
|
|
9950
|
+
*/
|
|
9951
|
+
async isActiveDelegate(delegate) {
|
|
9952
|
+
return this.#read("isActiveDelegate", [delegate]);
|
|
9953
|
+
}
|
|
9954
|
+
// Role-constant getters are named for the contract function they read, the
|
|
9955
|
+
// same convention every other client in this module follows: one spelling
|
|
9956
|
+
// per role, whichever client you happen to be holding.
|
|
9957
|
+
/** Gates {@link addDelegate} / {@link revokeDelegate}. */
|
|
9958
|
+
async DELEGATION_ADMIN_ROLE() {
|
|
9959
|
+
return this.#read("DELEGATION_ADMIN_ROLE");
|
|
9960
|
+
}
|
|
9961
|
+
/**
|
|
9962
|
+
* OpenZeppelin's root role (`bytes32(0)`), read from the clone rather than
|
|
9963
|
+
* hard-coded. It administers {@link DELEGATION_ADMIN_ROLE}.
|
|
9964
|
+
*/
|
|
9965
|
+
async DEFAULT_ADMIN_ROLE() {
|
|
9966
|
+
return this.#read("DEFAULT_ADMIN_ROLE");
|
|
9967
|
+
}
|
|
9968
|
+
// ============================================================
|
|
9969
|
+
// ROLE ADMINISTRATION
|
|
9970
|
+
// ============================================================
|
|
9971
|
+
//
|
|
9972
|
+
// The clone is `AccessControlEnumerableUpgradeable`, so membership is
|
|
9973
|
+
// enumerable as well as checkable. This surface is what makes the delegation
|
|
9974
|
+
// verbs above administrable: without it, whoever the factory named at
|
|
9975
|
+
// `initialize` is the only account that can ever add a delegate, and there
|
|
9976
|
+
// is no way to find out who that is.
|
|
9977
|
+
//
|
|
9978
|
+
// Unlike an airdrop instance, this contract adds no "never empty" floor of
|
|
9979
|
+
// its own - emptying `DEFAULT_ADMIN_ROLE` here permanently freezes the
|
|
9980
|
+
// clone's delegate set at whatever it currently holds.
|
|
9981
|
+
/**
|
|
9982
|
+
* Whether `holder` holds `role`.
|
|
9983
|
+
*
|
|
9984
|
+
* The role subject is called `holder`, not `account`: on the writes below
|
|
9985
|
+
* `account` already means "who sends this transaction", and one key cannot
|
|
9986
|
+
* be both.
|
|
9987
|
+
*
|
|
9988
|
+
* @param args.role A `bytes32` from {@link DELEGATION_ADMIN_ROLE} or {@link DEFAULT_ADMIN_ROLE}.
|
|
9989
|
+
*/
|
|
9990
|
+
async hasRole(args) {
|
|
9991
|
+
return this.#read("hasRole", [args.role, args.holder]);
|
|
9992
|
+
}
|
|
9993
|
+
/** The role whose holders may {@link grantRole} and {@link revokeRole} `role`. */
|
|
9994
|
+
async getRoleAdmin(role) {
|
|
9995
|
+
return this.#read("getRoleAdmin", [role]);
|
|
9996
|
+
}
|
|
9997
|
+
/** How many accounts hold `role`. */
|
|
9998
|
+
async getRoleMemberCount(role) {
|
|
9999
|
+
return this.#read("getRoleMemberCount", [role]);
|
|
10000
|
+
}
|
|
10001
|
+
/**
|
|
10002
|
+
* The `index`-th holder of `role`, in `EnumerableSet` order - which is not
|
|
10003
|
+
* stable across grants and revokes. Prefer {@link getRoleMembers}.
|
|
10004
|
+
*/
|
|
10005
|
+
async getRoleMember(args) {
|
|
10006
|
+
return this.#read("getRoleMember", [args.role, args.index]);
|
|
10007
|
+
}
|
|
10008
|
+
/**
|
|
10009
|
+
* Every account currently holding `role`.
|
|
10010
|
+
*
|
|
10011
|
+
* With {@link DELEGATION_ADMIN_ROLE} this answers "who may add or revoke a
|
|
10012
|
+
* delegate on this clone?" - the administrative counterpart to
|
|
10013
|
+
* {@link clientDelegates}, which answers "who may currently decrypt?".
|
|
10014
|
+
*/
|
|
10015
|
+
async getRoleMembers(role) {
|
|
10016
|
+
return this.#read("getRoleMembers", [role]);
|
|
10017
|
+
}
|
|
10018
|
+
/**
|
|
10019
|
+
* Grant `role` to `holder`. Requires the role's admin role
|
|
10020
|
+
* ({@link getRoleAdmin}).
|
|
10021
|
+
*
|
|
10022
|
+
* This is how a second operator is added to {@link DELEGATION_ADMIN_ROLE} -
|
|
10023
|
+
* the delegation verbs themselves are unaffected, the grant only widens who
|
|
10024
|
+
* may call them.
|
|
10025
|
+
*
|
|
10026
|
+
* @returns The transaction hash.
|
|
10027
|
+
*/
|
|
10028
|
+
async grantRole(args) {
|
|
10029
|
+
return withTelemetry(
|
|
10030
|
+
this.#telemetry,
|
|
10031
|
+
"fhe-airdrop.compliance.grantRole",
|
|
10032
|
+
() => this.#write("grantRole", [args.role, args.holder], args.account, "grantRole")
|
|
10033
|
+
);
|
|
10034
|
+
}
|
|
10035
|
+
/**
|
|
10036
|
+
* Revoke `role` from `holder`. Requires the role's admin role.
|
|
10037
|
+
*
|
|
10038
|
+
* Revoking a delegation admin does **not** revoke the delegations they
|
|
10039
|
+
* created: an existing delegate keeps decrypting until
|
|
10040
|
+
* {@link revokeDelegate} is called for it explicitly.
|
|
10041
|
+
*
|
|
10042
|
+
* @returns The transaction hash.
|
|
10043
|
+
*/
|
|
10044
|
+
async revokeRole(args) {
|
|
10045
|
+
return withTelemetry(
|
|
10046
|
+
this.#telemetry,
|
|
10047
|
+
"fhe-airdrop.compliance.revokeRole",
|
|
10048
|
+
() => this.#write("revokeRole", [args.role, args.holder], args.account, "revokeRole")
|
|
10049
|
+
);
|
|
10050
|
+
}
|
|
10051
|
+
/**
|
|
10052
|
+
* Give up `role` yourself.
|
|
10053
|
+
*
|
|
10054
|
+
* The contract's signature is `renounceRole(role, callerConfirmation)` and
|
|
10055
|
+
* it reverts `AccessControlBadConfirmation` unless `callerConfirmation` is
|
|
10056
|
+
* the sender, so this method takes no holder and fills the confirmation from
|
|
10057
|
+
* the resolved sending account. Renouncing for somebody else is not a call
|
|
10058
|
+
* that can succeed; use {@link revokeRole} to remove another account's role.
|
|
10059
|
+
*
|
|
10060
|
+
* @returns The transaction hash.
|
|
10061
|
+
*/
|
|
10062
|
+
async renounceRole(args) {
|
|
10063
|
+
const method = "renounceRole";
|
|
10064
|
+
const wallet = this.#requireWallet(method);
|
|
10065
|
+
const account = this.#resolveAccount(wallet, args.account, method);
|
|
10066
|
+
return withTelemetry(
|
|
10067
|
+
this.#telemetry,
|
|
10068
|
+
"fhe-airdrop.compliance.renounceRole",
|
|
10069
|
+
() => this.#write(method, [args.role, accountAddress3(account)], account, method)
|
|
10070
|
+
);
|
|
10071
|
+
}
|
|
10072
|
+
// ============================================================
|
|
10073
|
+
// INTERNALS (private)
|
|
10074
|
+
// ============================================================
|
|
10075
|
+
async #write(functionName, args, account, method) {
|
|
10076
|
+
const wallet = this.#requireWallet(method);
|
|
10077
|
+
const acct = this.#resolveAccount(wallet, account, method);
|
|
10078
|
+
await this.#preflightWrite(method, functionName, args, acct);
|
|
10079
|
+
try {
|
|
10080
|
+
return await wallet.writeContract({
|
|
10081
|
+
address: this.address,
|
|
10082
|
+
abi: complianceRoleManagerAbi,
|
|
10083
|
+
functionName,
|
|
10084
|
+
args,
|
|
10085
|
+
account: acct,
|
|
10086
|
+
chain: wallet.chain
|
|
10087
|
+
});
|
|
10088
|
+
} catch (err) {
|
|
10089
|
+
throw this.#mapRevert(method, err, acct);
|
|
10090
|
+
}
|
|
10091
|
+
}
|
|
10092
|
+
async #read(functionName, args = []) {
|
|
10093
|
+
const result = await this.publicClient.readContract({
|
|
10094
|
+
address: this.address,
|
|
10095
|
+
abi: complianceRoleManagerAbi,
|
|
10096
|
+
functionName,
|
|
10097
|
+
args
|
|
10098
|
+
});
|
|
10099
|
+
return result;
|
|
10100
|
+
}
|
|
10101
|
+
/**
|
|
10102
|
+
* Simulate a write purely to surface typed reverts.
|
|
10103
|
+
*
|
|
10104
|
+
* The simulate's return value is discarded on principle: this contract
|
|
10105
|
+
* returns nothing from `addDelegate` / `revokeDelegate` anyway, but the
|
|
10106
|
+
* pattern is kept identical to every other airdrop v2 client so a revert is
|
|
10107
|
+
* always decoded before the user pays for it.
|
|
10108
|
+
*/
|
|
10109
|
+
async #preflightWrite(method, functionName, args, account) {
|
|
10110
|
+
try {
|
|
10111
|
+
await this.publicClient.simulateContract({
|
|
10112
|
+
address: this.address,
|
|
10113
|
+
abi: complianceRoleManagerAbi,
|
|
10114
|
+
functionName,
|
|
10115
|
+
args,
|
|
10116
|
+
account
|
|
10117
|
+
});
|
|
10118
|
+
} catch (err) {
|
|
10119
|
+
if (isContractRevert(err)) {
|
|
10120
|
+
throw this.#mapRevert(method, err, account);
|
|
10121
|
+
}
|
|
10122
|
+
}
|
|
10123
|
+
}
|
|
10124
|
+
/**
|
|
10125
|
+
* Map a viem error to the SDK's typed palette.
|
|
10126
|
+
*
|
|
10127
|
+
* `productContext` deliberately carries only public identifiers — the
|
|
10128
|
+
* caller, the chain. Never an amount: this contract never handles amounts
|
|
10129
|
+
* at all, but the convention is shared across every airdrop v2 client.
|
|
10130
|
+
*/
|
|
10131
|
+
#mapRevert(method, err, account) {
|
|
10132
|
+
return mapContractRevert(err, {
|
|
10133
|
+
method,
|
|
10134
|
+
contractAddress: this.address,
|
|
10135
|
+
abi: complianceRoleManagerAbi,
|
|
10136
|
+
productMapper: airdropProductMapper,
|
|
10137
|
+
account: accountAddress3(account),
|
|
10138
|
+
productContext: {
|
|
10139
|
+
creator: accountAddress3(account),
|
|
10140
|
+
chainId: this.chainId
|
|
10141
|
+
}
|
|
10142
|
+
});
|
|
10143
|
+
}
|
|
10144
|
+
#requireWallet(method) {
|
|
10145
|
+
if (!this.walletClient) {
|
|
10146
|
+
throw new MissingWalletClientError(method);
|
|
10147
|
+
}
|
|
10148
|
+
return this.walletClient;
|
|
10149
|
+
}
|
|
10150
|
+
#resolveAccount(wallet, override, method) {
|
|
10151
|
+
const acct = override ?? wallet.account;
|
|
10152
|
+
if (!acct) {
|
|
10153
|
+
throw new MissingAccountError(method);
|
|
10154
|
+
}
|
|
10155
|
+
return acct;
|
|
10156
|
+
}
|
|
10157
|
+
};
|
|
10158
|
+
function createComplianceManagerClient(config) {
|
|
10159
|
+
return new ComplianceManagerClient(config);
|
|
10160
|
+
}
|
|
10161
|
+
function accountAddress3(account) {
|
|
10162
|
+
return typeof account === "string" ? account : account.address;
|
|
10163
|
+
}
|
|
10164
|
+
|
|
10165
|
+
export { AirdropBaseClient, CLAIM_TYPEHASH, CLAIM_TYPES, ComplianceManagerClient, ConfidentialAirdropFactoryClient, EIP712_DOMAIN_NAME, EIP712_DOMAIN_VERSION, EcdsaAirdropClient, FACTORY_ROLE_CONCENTRATION_NOTE, MerkleAirdropClient, airdropFactoryAbi, complianceRoleManagerAbi, confidentialAirdropBaseAbi, createAirdropBaseClient, createComplianceManagerClient, createConfidentialAirdropFactoryClient, createEcdsaAirdropClient, createMerkleAirdropClient, ecdsaConfidentialAirdropAbi, encryptUint64, encryptUint64Batch, isAclPropagationError, merkleConfidentialAirdropAbi, resolveEncryptor, signClaimAuthorization };
|