@towns-protocol/contracts 0.0.302

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.
Files changed (396) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +206 -0
  3. package/docs/permitAndStake_integration_guide.md +266 -0
  4. package/docs/swap_integration_guide.md +591 -0
  5. package/package.json +57 -0
  6. package/scripts/common/DeployBase.s.sol +26 -0
  7. package/scripts/common/DeployFacet.s.sol +7 -0
  8. package/scripts/common/Deployer.s.sol +33 -0
  9. package/scripts/common/Interaction.s.sol +51 -0
  10. package/scripts/deployments/diamonds/DeployAppRegistry.s.sol +168 -0
  11. package/scripts/deployments/diamonds/DeployBaseRegistry.s.sol +263 -0
  12. package/scripts/deployments/diamonds/DeployRiverAirdrop.s.sol +203 -0
  13. package/scripts/deployments/diamonds/DeployRiverMigration.s.sol +129 -0
  14. package/scripts/deployments/diamonds/DeployRiverRegistry.s.sol +175 -0
  15. package/scripts/deployments/diamonds/DeploySpace.s.sol +285 -0
  16. package/scripts/deployments/diamonds/DeploySpaceFactory.s.sol +416 -0
  17. package/scripts/deployments/diamonds/DeploySpaceOwner.s.sol +183 -0
  18. package/scripts/deployments/diamonds/DeploySwapRouter.s.sol +176 -0
  19. package/scripts/deployments/diamonds/IDiamondInitHelper.sol +11 -0
  20. package/scripts/deployments/facets/DeployAppAccount.s.sol +51 -0
  21. package/scripts/deployments/facets/DeployAppRegistryFacet.s.sol +69 -0
  22. package/scripts/deployments/facets/DeployArchitect.s.sol +51 -0
  23. package/scripts/deployments/facets/DeployAttestationRegistry.s.sol +36 -0
  24. package/scripts/deployments/facets/DeployBanning.s.sol +30 -0
  25. package/scripts/deployments/facets/DeployChannels.s.sol +35 -0
  26. package/scripts/deployments/facets/DeployCreateSpace.s.sol +42 -0
  27. package/scripts/deployments/facets/DeployDropFacet.s.sol +49 -0
  28. package/scripts/deployments/facets/DeployERC721A.s.sol +48 -0
  29. package/scripts/deployments/facets/DeployERC721ANonTransferable.s.sol +49 -0
  30. package/scripts/deployments/facets/DeployERC721AQueryable.s.sol +30 -0
  31. package/scripts/deployments/facets/DeployEntitlementChecker.s.sol +49 -0
  32. package/scripts/deployments/facets/DeployEntitlementDataQueryable.s.sol +29 -0
  33. package/scripts/deployments/facets/DeployEntitlementsManager.s.sol +33 -0
  34. package/scripts/deployments/facets/DeployExecutorFacet.s.sol +60 -0
  35. package/scripts/deployments/facets/DeployFeatureManager.s.sol +38 -0
  36. package/scripts/deployments/facets/DeployGuardianFacet.s.sol +39 -0
  37. package/scripts/deployments/facets/DeployImplementationRegistry.s.sol +36 -0
  38. package/scripts/deployments/facets/DeployMainnetDelegation.s.sol +43 -0
  39. package/scripts/deployments/facets/DeployMembership.s.sol +77 -0
  40. package/scripts/deployments/facets/DeployMembershipMetadata.s.sol +30 -0
  41. package/scripts/deployments/facets/DeployMembershipToken.s.sol +47 -0
  42. package/scripts/deployments/facets/DeployMerkleAirdrop.s.sol +37 -0
  43. package/scripts/deployments/facets/DeployMetadata.s.sol +39 -0
  44. package/scripts/deployments/facets/DeployMockLegacyArchitect.s.sol +33 -0
  45. package/scripts/deployments/facets/DeployNodeOperator.s.sol +49 -0
  46. package/scripts/deployments/facets/DeployNodeRegistry.s.sol +37 -0
  47. package/scripts/deployments/facets/DeployOperatorRegistry.s.sol +36 -0
  48. package/scripts/deployments/facets/DeployPartnerRegistry.s.sol +41 -0
  49. package/scripts/deployments/facets/DeployPlatformRequirements.s.sol +75 -0
  50. package/scripts/deployments/facets/DeployPrepayFacet.s.sol +31 -0
  51. package/scripts/deployments/facets/DeployPricingModules.s.sol +36 -0
  52. package/scripts/deployments/facets/DeployReferrals.s.sol +34 -0
  53. package/scripts/deployments/facets/DeployReviewFacet.s.sol +31 -0
  54. package/scripts/deployments/facets/DeployRewardsDistributionV2.s.sol +76 -0
  55. package/scripts/deployments/facets/DeployRiverConfig.s.sol +41 -0
  56. package/scripts/deployments/facets/DeployRoles.s.sol +48 -0
  57. package/scripts/deployments/facets/DeploySchemaRegistry.s.sol +35 -0
  58. package/scripts/deployments/facets/DeploySignerFacet.s.sol +47 -0
  59. package/scripts/deployments/facets/DeploySimpleApp.s.sol +10 -0
  60. package/scripts/deployments/facets/DeploySpaceDelegation.s.sol +43 -0
  61. package/scripts/deployments/facets/DeploySpaceEntitlementGated.s.sol +31 -0
  62. package/scripts/deployments/facets/DeploySpaceFactoryInit.s.sol +33 -0
  63. package/scripts/deployments/facets/DeploySpaceOwnerFacet.s.sol +71 -0
  64. package/scripts/deployments/facets/DeployStreamRegistry.s.sol +50 -0
  65. package/scripts/deployments/facets/DeploySwapFacet.s.sol +33 -0
  66. package/scripts/deployments/facets/DeploySwapRouterFacet.s.sol +38 -0
  67. package/scripts/deployments/facets/DeployTipping.s.sol +31 -0
  68. package/scripts/deployments/facets/DeployTokenMigration.s.sol +40 -0
  69. package/scripts/deployments/facets/DeployTownsPoints.s.sol +53 -0
  70. package/scripts/deployments/facets/DeployTreasury.s.sol +30 -0
  71. package/scripts/deployments/facets/DeployUpgradeableBeacon.s.sol +34 -0
  72. package/scripts/deployments/facets/DeployWalletLink.s.sol +56 -0
  73. package/scripts/deployments/facets/DeployXChain.s.sol +35 -0
  74. package/scripts/deployments/utils/DeployAccountFactory.s.sol +40 -0
  75. package/scripts/deployments/utils/DeployEntitlementGatedExample.s.sol +23 -0
  76. package/scripts/deployments/utils/DeployEntrypoint.s.sol +28 -0
  77. package/scripts/deployments/utils/DeployMember.s.sol +95 -0
  78. package/scripts/deployments/utils/DeployMockDiamond.s.sol +7 -0
  79. package/scripts/deployments/utils/DeployMockERC20.s.sol +24 -0
  80. package/scripts/deployments/utils/DeployMockERC721A.s.sol +45 -0
  81. package/scripts/deployments/utils/DeployMockLegacyMembership.s.sol +29 -0
  82. package/scripts/deployments/utils/DeployMockMessenger.s.sol +42 -0
  83. package/scripts/deployments/utils/DeployMockNFT.s.sol +86 -0
  84. package/scripts/deployments/utils/DeployPoapEntitlement.s.sol +16 -0
  85. package/scripts/deployments/utils/DeployProxyBatchDelegation.s.sol +112 -0
  86. package/scripts/deployments/utils/DeploySpaceProxyInitializer.s.sol +28 -0
  87. package/scripts/deployments/utils/DeployTieredLogPricingV2.s.sol +23 -0
  88. package/scripts/deployments/utils/DeployTieredLogPricingV3.s.sol +23 -0
  89. package/scripts/deployments/utils/DeployTownsBase.s.sol +95 -0
  90. package/scripts/deployments/utils/DeployTownsMainnet.s.sol +66 -0
  91. package/scripts/deployments/utils/DeployTownsMulti.s.sol +53 -0
  92. package/scripts/deployments/utils/DeployWrappedTowns.s.sol +52 -0
  93. package/scripts/deployments/utils/LibLayerZeroValues.sol +34 -0
  94. package/scripts/deployments/utils/pricing/TieredLogPricing.s.sol +45 -0
  95. package/scripts/interactions/InteractAirdrop.s.sol +57 -0
  96. package/scripts/interactions/InteractAlphaPost.s.sol +32 -0
  97. package/scripts/interactions/InteractAlphaSparse.s.sol +173 -0
  98. package/scripts/interactions/InteractBaseAlpha.s.sol +84 -0
  99. package/scripts/interactions/InteractBaseBridge.s.sol +48 -0
  100. package/scripts/interactions/InteractBridgeLayerZero.s.sol +102 -0
  101. package/scripts/interactions/InteractClaimCondition.s.sol +56 -0
  102. package/scripts/interactions/InteractCreateSpace.s.sol +50 -0
  103. package/scripts/interactions/InteractDiamondCut.s.sol +47 -0
  104. package/scripts/interactions/InteractDropFacet.s.sol +32 -0
  105. package/scripts/interactions/InteractEnableNewSnapshotFormat.s.sol +27 -0
  106. package/scripts/interactions/InteractEnableNode2NodeAuth.s.sol +27 -0
  107. package/scripts/interactions/InteractMembership.s.sol +42 -0
  108. package/scripts/interactions/InteractMockERC721A.s.sol +20 -0
  109. package/scripts/interactions/InteractNodeOperators.s.sol +41 -0
  110. package/scripts/interactions/InteractPostDeploy.s.sol +59 -0
  111. package/scripts/interactions/InteractPrepay.s.sol +30 -0
  112. package/scripts/interactions/InteractRegisterApp.s.sol +61 -0
  113. package/scripts/interactions/InteractRiverAlpha.s.sol +30 -0
  114. package/scripts/interactions/InteractRiverAlphaSparse.s.sol +117 -0
  115. package/scripts/interactions/InteractRiverMainnet.s.sol +27 -0
  116. package/scripts/interactions/InteractRiverRegistry.s.sol +36 -0
  117. package/scripts/interactions/InteractRiverRegistrySetBlocklist.s.sol +30 -0
  118. package/scripts/interactions/InteractRiverRegistrySetFreq.s.sol +27 -0
  119. package/scripts/interactions/InteractRiverRegistrySetRepl.s.sol +30 -0
  120. package/scripts/interactions/InteractSetDefaultUri.s.sol +20 -0
  121. package/scripts/interactions/InteractSetDefaultUriLocalhost.s.sol +19 -0
  122. package/scripts/interactions/InteractTransferOwnership.s.sol +21 -0
  123. package/scripts/interactions/InteractUpdateMbRecencyCheck.s.sol +27 -0
  124. package/scripts/interactions/InteractUpdateMediaChunkCount.s.sol +27 -0
  125. package/scripts/interactions/InteractUpdateMediaChunkSize.s.sol +27 -0
  126. package/scripts/interactions/helpers/AlphaHelper.sol +149 -0
  127. package/scripts/interactions/helpers/RiverConfigValues.sol +22 -0
  128. package/scripts/interactions/interfaces/IL1StandardBridge.sol +35 -0
  129. package/scripts/interactions/interfaces/IL2StandardBridge.sol +69 -0
  130. package/src/airdrop/drop/DropBase.sol +210 -0
  131. package/src/airdrop/drop/DropClaim.sol +55 -0
  132. package/src/airdrop/drop/DropFacet.sol +176 -0
  133. package/src/airdrop/drop/DropGroup.sol +111 -0
  134. package/src/airdrop/drop/DropStorage.sol +23 -0
  135. package/src/airdrop/drop/IDropFacet.sol +136 -0
  136. package/src/airdrop/points/CheckIn.sol +71 -0
  137. package/src/airdrop/points/ITownsPoints.sol +64 -0
  138. package/src/airdrop/points/TownsPoints.sol +196 -0
  139. package/src/airdrop/points/TownsPointsStorage.sol +22 -0
  140. package/src/apps/BaseApp.sol +62 -0
  141. package/src/apps/ITownsApp.sol +28 -0
  142. package/src/apps/SchemaResolver.sol +170 -0
  143. package/src/apps/facets/attest/AttestationBase.sol +335 -0
  144. package/src/apps/facets/attest/AttestationLib.sol +64 -0
  145. package/src/apps/facets/attest/AttestationRegistry.sol +39 -0
  146. package/src/apps/facets/attest/AttestationStorage.sol +35 -0
  147. package/src/apps/facets/attest/IAttestationRegistry.sol +43 -0
  148. package/src/apps/facets/registry/AppRegistryBase.sol +403 -0
  149. package/src/apps/facets/registry/AppRegistryFacet.sol +173 -0
  150. package/src/apps/facets/registry/AppRegistryStorage.sol +53 -0
  151. package/src/apps/facets/registry/IAppRegistry.sol +159 -0
  152. package/src/apps/facets/schema/ISchema.sol +14 -0
  153. package/src/apps/facets/schema/SchemaBase.sol +88 -0
  154. package/src/apps/facets/schema/SchemaLib.sol +14 -0
  155. package/src/apps/facets/schema/SchemaRegistry.sol +51 -0
  156. package/src/apps/facets/schema/SchemaStorage.sol +34 -0
  157. package/src/apps/helpers/ISimpleApp.sol +51 -0
  158. package/src/apps/helpers/SimpleApp.sol +97 -0
  159. package/src/apps/helpers/SimpleAppStorage.sol +27 -0
  160. package/src/base/registry/facets/checker/EntitlementChecker.sol +237 -0
  161. package/src/base/registry/facets/checker/EntitlementCheckerStorage.sol +28 -0
  162. package/src/base/registry/facets/checker/IEntitlementChecker.sol +95 -0
  163. package/src/base/registry/facets/delegation/ISpaceDelegation.sol +69 -0
  164. package/src/base/registry/facets/delegation/SpaceDelegationFacet.sol +250 -0
  165. package/src/base/registry/facets/delegation/SpaceDelegationStorage.sol +35 -0
  166. package/src/base/registry/facets/distribution/v1/IRewardsDistribution.sol +51 -0
  167. package/src/base/registry/facets/distribution/v1/RewardsDistribution.sol +439 -0
  168. package/src/base/registry/facets/distribution/v1/RewardsDistributionStorage.sol +32 -0
  169. package/src/base/registry/facets/distribution/v2/DelegationProxy.sol +53 -0
  170. package/src/base/registry/facets/distribution/v2/IRewardsDistribution.sol +372 -0
  171. package/src/base/registry/facets/distribution/v2/RewardsDistributionBase.sol +299 -0
  172. package/src/base/registry/facets/distribution/v2/RewardsDistributionStorage.sol +37 -0
  173. package/src/base/registry/facets/distribution/v2/RewardsDistributionV2.sol +392 -0
  174. package/src/base/registry/facets/distribution/v2/StakingRewards.sol +466 -0
  175. package/src/base/registry/facets/mainnet/ICrossDomainMessenger.sol +58 -0
  176. package/src/base/registry/facets/mainnet/IMainnetDelegation.sol +127 -0
  177. package/src/base/registry/facets/mainnet/MainnetDelegation.sol +119 -0
  178. package/src/base/registry/facets/mainnet/MainnetDelegationBase.sol +274 -0
  179. package/src/base/registry/facets/mainnet/MainnetDelegationStorage.sol +36 -0
  180. package/src/base/registry/facets/operator/INodeOperator.sol +91 -0
  181. package/src/base/registry/facets/operator/NodeOperatorFacet.sol +189 -0
  182. package/src/base/registry/facets/operator/NodeOperatorStorage.sol +39 -0
  183. package/src/base/registry/facets/xchain/IXChain.sol +54 -0
  184. package/src/base/registry/facets/xchain/XChain.sol +158 -0
  185. package/src/base/registry/facets/xchain/XChainCheckLib.sol +105 -0
  186. package/src/base/registry/facets/xchain/XChainLib.sol +46 -0
  187. package/src/diamond/facets/beacon/UpgradeableBeacon.sol +38 -0
  188. package/src/diamond/facets/beacon/UpgradeableBeaconFacet.sol +34 -0
  189. package/src/diamond/facets/governance/votes/Checkpoints.sol +642 -0
  190. package/src/diamond/facets/governance/votes/Votes.sol +63 -0
  191. package/src/diamond/facets/governance/votes/VotesBase.sol +274 -0
  192. package/src/diamond/facets/governance/votes/VotesStorage.sol +21 -0
  193. package/src/diamond/facets/governance/votes/enumerable/IVotesEnumerable.sol +38 -0
  194. package/src/diamond/facets/governance/votes/enumerable/VotesEnumerable.sol +39 -0
  195. package/src/diamond/facets/governance/votes/enumerable/VotesEnumerableLib.sol +102 -0
  196. package/src/diamond/facets/metadata/IMetadata.sol +27 -0
  197. package/src/diamond/facets/metadata/MetadataFacet.sol +71 -0
  198. package/src/diamond/facets/token/ERC5643/ERC5643.sol +51 -0
  199. package/src/diamond/facets/token/ERC5643/ERC5643Base.sol +48 -0
  200. package/src/diamond/facets/token/ERC5643/ERC5643Storage.sol +26 -0
  201. package/src/diamond/facets/token/ERC5643/IERC5643.sol +44 -0
  202. package/src/diamond/facets/token/ERC721A/ERC721A.sol +270 -0
  203. package/src/diamond/facets/token/ERC721A/ERC721ABase.sol +829 -0
  204. package/src/diamond/facets/token/ERC721A/ERC721ANonTransferable.sol +21 -0
  205. package/src/diamond/facets/token/ERC721A/ERC721AStorage.sol +115 -0
  206. package/src/diamond/facets/token/ERC721A/IERC721A.sol +283 -0
  207. package/src/diamond/facets/token/ERC721A/extensions/ERC721AQueryable.sol +134 -0
  208. package/src/diamond/facets/token/ERC721A/extensions/IERC721AQueryable.sol +83 -0
  209. package/src/diamond/utils/Context.sol +19 -0
  210. package/src/factory/SpaceFactoryInit.sol +17 -0
  211. package/src/factory/facets/architect/Architect.sol +98 -0
  212. package/src/factory/facets/architect/ArchitectBase.sol +95 -0
  213. package/src/factory/facets/architect/ArchitectStorage.sol +28 -0
  214. package/src/factory/facets/architect/IArchitect.sol +155 -0
  215. package/src/factory/facets/architect/ImplementationStorage.sol +42 -0
  216. package/src/factory/facets/architect/pricing/IPricingModules.sol +41 -0
  217. package/src/factory/facets/architect/pricing/PricingModulesBase.sol +89 -0
  218. package/src/factory/facets/architect/pricing/PricingModulesFacet.sol +40 -0
  219. package/src/factory/facets/architect/pricing/PricingModulesStorage.sol +30 -0
  220. package/src/factory/facets/create/CreateSpace.sol +107 -0
  221. package/src/factory/facets/create/CreateSpaceLib.sol +335 -0
  222. package/src/factory/facets/create/ICreateSpace.sol +70 -0
  223. package/src/factory/facets/feature/FeatureConditionLib.sol +53 -0
  224. package/src/factory/facets/feature/FeatureManagerFacet.sol +66 -0
  225. package/src/factory/facets/feature/FeatureManagerLib.sol +168 -0
  226. package/src/factory/facets/feature/IFeatureManagerFacet.sol +73 -0
  227. package/src/factory/facets/partner/IPartnerRegistry.sol +56 -0
  228. package/src/factory/facets/partner/PartnerRegistry.sol +57 -0
  229. package/src/factory/facets/partner/PartnerRegistryBase.sol +132 -0
  230. package/src/factory/facets/partner/PartnerRegistryStorage.sol +40 -0
  231. package/src/factory/facets/platform/requirements/IPlatformRequirements.sol +143 -0
  232. package/src/factory/facets/platform/requirements/PlatformRequirementsBase.sol +124 -0
  233. package/src/factory/facets/platform/requirements/PlatformRequirementsFacet.sol +122 -0
  234. package/src/factory/facets/platform/requirements/PlatformRequirementsStorage.sol +41 -0
  235. package/src/factory/facets/registry/IImplementationRegistry.sol +46 -0
  236. package/src/factory/facets/registry/ImplementationRegistry.sol +64 -0
  237. package/src/factory/facets/registry/ImplementationRegistryStorage.sol +28 -0
  238. package/src/factory/facets/wallet-link/IWalletLink.sol +218 -0
  239. package/src/factory/facets/wallet-link/WalletLink.sol +108 -0
  240. package/src/factory/facets/wallet-link/WalletLinkBase.sol +492 -0
  241. package/src/factory/facets/wallet-link/interfaces/IDelegateRegistry.sol +63 -0
  242. package/src/factory/facets/wallet-link/interfaces/IDelegateRegistryV1.sol +35 -0
  243. package/src/factory/facets/wallet-link/interfaces/ISCL_EIP6565.sol +24 -0
  244. package/src/factory/facets/wallet-link/libraries/SolanaUtils.sol +161 -0
  245. package/src/factory/facets/wallet-link/libraries/WalletLib.sol +62 -0
  246. package/src/river/registry/facets/config/IRiverConfig.sol +117 -0
  247. package/src/river/registry/facets/config/RiverConfig.sol +174 -0
  248. package/src/river/registry/facets/node/INodeRegistry.sol +69 -0
  249. package/src/river/registry/facets/node/NodeRegistry.sol +143 -0
  250. package/src/river/registry/facets/operator/IOperatorRegistry.sol +28 -0
  251. package/src/river/registry/facets/operator/OperatorRegistry.sol +86 -0
  252. package/src/river/registry/facets/stream/IStreamRegistry.sol +184 -0
  253. package/src/river/registry/facets/stream/StreamRegistry.sol +396 -0
  254. package/src/river/registry/libraries/RegistryErrors.sol +24 -0
  255. package/src/river/registry/libraries/RegistryStorage.sol +181 -0
  256. package/src/router/ISwapRouter.sol +226 -0
  257. package/src/router/Permit2Hash.sol +92 -0
  258. package/src/router/SwapRouter.sol +463 -0
  259. package/src/router/SwapRouterStorage.sol +21 -0
  260. package/src/spaces/entitlements/ICrossChainEntitlement.sol +22 -0
  261. package/src/spaces/entitlements/IEntitlement.sol +61 -0
  262. package/src/spaces/entitlements/PolymarketEntitlement.sol +79 -0
  263. package/src/spaces/entitlements/poap/IPOAP.sol +26 -0
  264. package/src/spaces/entitlements/poap/PoapEntitlement.sol +56 -0
  265. package/src/spaces/entitlements/rule/IRuleEntitlement.sol +174 -0
  266. package/src/spaces/entitlements/rule/RuleEntitlement.sol +183 -0
  267. package/src/spaces/entitlements/rule/RuleEntitlementV2.sol +219 -0
  268. package/src/spaces/entitlements/user/IUserEntitlement.sol +24 -0
  269. package/src/spaces/entitlements/user/UserEntitlement.sol +273 -0
  270. package/src/spaces/facets/DependencyLib.sol +60 -0
  271. package/src/spaces/facets/Entitled.sol +172 -0
  272. package/src/spaces/facets/Permissions.sol +21 -0
  273. package/src/spaces/facets/account/AppAccount.sol +93 -0
  274. package/src/spaces/facets/account/AppAccountBase.sol +275 -0
  275. package/src/spaces/facets/account/AppAccountStorage.sol +63 -0
  276. package/src/spaces/facets/account/IAppAccount.sol +71 -0
  277. package/src/spaces/facets/account/SignerFacet.sol +26 -0
  278. package/src/spaces/facets/banning/Banning.sol +41 -0
  279. package/src/spaces/facets/banning/BanningBase.sol +33 -0
  280. package/src/spaces/facets/banning/BanningStorage.sol +23 -0
  281. package/src/spaces/facets/banning/IBanning.sol +35 -0
  282. package/src/spaces/facets/channels/ChannelBase.sol +87 -0
  283. package/src/spaces/facets/channels/ChannelService.sol +177 -0
  284. package/src/spaces/facets/channels/ChannelStorage.sol +34 -0
  285. package/src/spaces/facets/channels/Channels.sol +80 -0
  286. package/src/spaces/facets/channels/IChannel.sol +98 -0
  287. package/src/spaces/facets/dispatcher/DispatcherBase.sol +86 -0
  288. package/src/spaces/facets/dispatcher/DispatcherStorage.sol +21 -0
  289. package/src/spaces/facets/dispatcher/IDispatcher.sol +6 -0
  290. package/src/spaces/facets/entitlements/EntitlementsManager.sol +49 -0
  291. package/src/spaces/facets/entitlements/EntitlementsManagerBase.sol +87 -0
  292. package/src/spaces/facets/entitlements/EntitlementsManagerService.sol +142 -0
  293. package/src/spaces/facets/entitlements/EntitlementsManagerStorage.sol +34 -0
  294. package/src/spaces/facets/entitlements/IEntitlementsManager.sol +67 -0
  295. package/src/spaces/facets/entitlements/extensions/EntitlementDataQueryable.sol +153 -0
  296. package/src/spaces/facets/entitlements/extensions/IEntitlementDataQueryable.sol +32 -0
  297. package/src/spaces/facets/executor/ExecutorBase.sol +564 -0
  298. package/src/spaces/facets/executor/ExecutorFacet.sol +178 -0
  299. package/src/spaces/facets/executor/ExecutorStorage.sol +99 -0
  300. package/src/spaces/facets/executor/GroupLib.sol +128 -0
  301. package/src/spaces/facets/executor/IExecutor.sol +287 -0
  302. package/src/spaces/facets/executor/hooks/HookBase.sol +172 -0
  303. package/src/spaces/facets/executor/hooks/HookLib.sol +38 -0
  304. package/src/spaces/facets/executor/hooks/IHookBase.sol +48 -0
  305. package/src/spaces/facets/gated/EntitlementGated.sol +59 -0
  306. package/src/spaces/facets/gated/EntitlementGatedBase.sol +324 -0
  307. package/src/spaces/facets/gated/EntitlementGatedStorage.sol +29 -0
  308. package/src/spaces/facets/gated/IEntitlementGated.sol +55 -0
  309. package/src/spaces/facets/guardian/GuardianBase.sol +80 -0
  310. package/src/spaces/facets/guardian/GuardianFacet.sol +43 -0
  311. package/src/spaces/facets/guardian/GuardianStorage.sol +27 -0
  312. package/src/spaces/facets/guardian/IGuardian.sol +54 -0
  313. package/src/spaces/facets/membership/IMembership.sol +216 -0
  314. package/src/spaces/facets/membership/MembershipBase.sol +272 -0
  315. package/src/spaces/facets/membership/MembershipFacet.sol +191 -0
  316. package/src/spaces/facets/membership/MembershipStorage.sol +40 -0
  317. package/src/spaces/facets/membership/join/MembershipJoin.sol +547 -0
  318. package/src/spaces/facets/membership/metadata/IMembershipMetadata.sol +9 -0
  319. package/src/spaces/facets/membership/metadata/MembershipMetadata.sol +32 -0
  320. package/src/spaces/facets/membership/pricing/IMembershipPricing.sol +18 -0
  321. package/src/spaces/facets/membership/pricing/fixed/FixedPricing.sol +29 -0
  322. package/src/spaces/facets/membership/pricing/fixed/FixedPricingStorage.sol +27 -0
  323. package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV2.sol +148 -0
  324. package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV3.sol +137 -0
  325. package/src/spaces/facets/membership/token/MembershipToken.sol +25 -0
  326. package/src/spaces/facets/owner/ISpaceOwner.sol +85 -0
  327. package/src/spaces/facets/owner/SpaceOwner.sol +174 -0
  328. package/src/spaces/facets/owner/SpaceOwnerBase.sol +121 -0
  329. package/src/spaces/facets/owner/SpaceOwnerStorage.sol +41 -0
  330. package/src/spaces/facets/owner/SpaceOwnerUriBase.sol +54 -0
  331. package/src/spaces/facets/points/PointsBase.sol +35 -0
  332. package/src/spaces/facets/prepay/IPrepay.sol +43 -0
  333. package/src/spaces/facets/prepay/PrepayBase.sol +27 -0
  334. package/src/spaces/facets/prepay/PrepayFacet.sol +59 -0
  335. package/src/spaces/facets/prepay/PrepayStorage.sol +26 -0
  336. package/src/spaces/facets/proxy/ISpaceProxyInitializer.sol +21 -0
  337. package/src/spaces/facets/proxy/SpaceProxy.sol +15 -0
  338. package/src/spaces/facets/proxy/SpaceProxyInitializer.sol +55 -0
  339. package/src/spaces/facets/referrals/IReferrals.sol +98 -0
  340. package/src/spaces/facets/referrals/ReferralsBase.sol +81 -0
  341. package/src/spaces/facets/referrals/ReferralsFacet.sol +65 -0
  342. package/src/spaces/facets/referrals/ReferralsStorage.sol +36 -0
  343. package/src/spaces/facets/review/IReview.sol +50 -0
  344. package/src/spaces/facets/review/ReviewFacet.sol +105 -0
  345. package/src/spaces/facets/review/ReviewStorage.sol +29 -0
  346. package/src/spaces/facets/roles/IRoles.sol +197 -0
  347. package/src/spaces/facets/roles/Roles.sol +123 -0
  348. package/src/spaces/facets/roles/RolesBase.sol +420 -0
  349. package/src/spaces/facets/roles/RolesStorage.sol +132 -0
  350. package/src/spaces/facets/swap/ISwapFacet.sol +91 -0
  351. package/src/spaces/facets/swap/SwapFacet.sol +290 -0
  352. package/src/spaces/facets/swap/SwapFacetStorage.sol +24 -0
  353. package/src/spaces/facets/tipping/ITipping.sol +80 -0
  354. package/src/spaces/facets/tipping/TippingBase.sol +73 -0
  355. package/src/spaces/facets/tipping/TippingFacet.sol +123 -0
  356. package/src/spaces/facets/treasury/ITreasury.sol +64 -0
  357. package/src/spaces/facets/treasury/Treasury.sol +82 -0
  358. package/src/spaces/facets/xchain/SpaceEntitlementGated.sol +62 -0
  359. package/src/tokens/Member.sol +246 -0
  360. package/src/tokens/lock/ILock.sol +42 -0
  361. package/src/tokens/lock/LockBase.sol +64 -0
  362. package/src/tokens/lock/LockFacet.sol +44 -0
  363. package/src/tokens/lock/LockStorage.sol +26 -0
  364. package/src/tokens/mainnet/claimer/AuthorizedClaimerStorage.sol +26 -0
  365. package/src/tokens/mainnet/claimer/AuthorizedClaimers.sol +84 -0
  366. package/src/tokens/mainnet/claimer/IAuthorizedClaimers.sol +36 -0
  367. package/src/tokens/mainnet/delegation/ProxyBatchDelegation.sol +86 -0
  368. package/src/tokens/migration/ITokenMigration.sol +35 -0
  369. package/src/tokens/migration/TokenMigrationFacet.sol +86 -0
  370. package/src/tokens/migration/TokenMigrationStorage.sol +27 -0
  371. package/src/tokens/towns/base/IERC7802.sol +30 -0
  372. package/src/tokens/towns/base/IOptimismMintableERC20.sol +31 -0
  373. package/src/tokens/towns/base/ISemver.sol +13 -0
  374. package/src/tokens/towns/base/Towns.sol +283 -0
  375. package/src/tokens/towns/base/TownsDeployer.sol +32 -0
  376. package/src/tokens/towns/base/TownsLib.sol +31 -0
  377. package/src/tokens/towns/base/versions/TownsV2.sol +15 -0
  378. package/src/tokens/towns/mainnet/ITowns.sol +56 -0
  379. package/src/tokens/towns/mainnet/Towns.sol +220 -0
  380. package/src/tokens/towns/mainnet/libs/TokenInflationLib.sol +89 -0
  381. package/src/tokens/towns/multichain/Towns.sol +19 -0
  382. package/src/tokens/towns/multichain/wTowns.sol +18 -0
  383. package/src/utils/Airdrop.sol +156 -0
  384. package/src/utils/airdrop/merkle/IMerkleAirdrop.sol +55 -0
  385. package/src/utils/airdrop/merkle/MerkleAirdrop.sol +118 -0
  386. package/src/utils/airdrop/merkle/MerkleAirdropStorage.sol +29 -0
  387. package/src/utils/interfaces/AggregatorV3Interface.sol +37 -0
  388. package/src/utils/interfaces/IMulticall.sol +10 -0
  389. package/src/utils/interfaces/IWETH.sol +10 -0
  390. package/src/utils/libraries/BasisPoints.sol +24 -0
  391. package/src/utils/libraries/Create2Utils.sol +74 -0
  392. package/src/utils/libraries/CurrencyTransfer.sol +99 -0
  393. package/src/utils/libraries/CustomRevert.sol +49 -0
  394. package/src/utils/libraries/Factory.sol +66 -0
  395. package/src/utils/libraries/StringSet.sol +190 -0
  396. package/src/utils/libraries/Validator.sol +31 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 River Association
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,206 @@
1
+ # Towns Contracts
2
+
3
+ ## Overview
4
+
5
+ This project is a blockchain-based space/channel management system with role-based access control and entitlements. It implements a complex permission system using smart contracts that allows for cross-chain rule validation and user management.
6
+
7
+ The system also supports cross-chain delegation between Ethereum L1 and Base L2, allowing users to stake tokens on L1 and have delegation benefits on L2. Node operators can receive delegations directly or via spaces, with rewards distributed based on stake amounts and time.
8
+
9
+ ### The system allows for:
10
+
11
+ - Creation and management of spaces and channels
12
+ - Role-based access control with granular permissions
13
+ - Cross-chain entitlement validation
14
+ - User membership management
15
+ - Rule-based entitlements with logical operations
16
+ - Staking and rewards distribution for DAO participants and node operators
17
+ - Cross-chain delegation and governance mechanisms
18
+
19
+ ## Tech Stack
20
+
21
+ - Solidity ^0.8.23
22
+ - OpenZeppelin Contracts
23
+ - Solady Contracts
24
+ - Diamond Pattern (EIP-2535) for upgradeable contracts
25
+ - Foundry for development and testing
26
+ - TypeScript for contract type generation
27
+
28
+ ## Project Structure
29
+
30
+ - `src/airdrop/` - Token distribution mechanisms (drops, points, streaks, rules)
31
+ - `src/base/registry/` - Core registry, delegation, rewards, entitlement checking
32
+ - `/facets/distribution/` - Staking and rewards distribution for DAO participants and node operators
33
+ - `/facets/mainnet/` - Cross-chain delegation handling and message relaying
34
+ - `/facets/delegation/` - Space-to-operator delegation management
35
+ - `/facets/operator/` - Node operator registration and management
36
+ - `src/spaces/` - Space management, entitlements, permissions, cross-chain rules
37
+ - `src/factory/` - Factory contracts for space creation, deployment, wallet linking
38
+ - `src/utils/` - Utility libraries (currency, math, reverts, patterns)
39
+ - `src/diamond/` - Diamond pattern implementation, facets, upgradeability
40
+ - `src/tokens/` - Token management, membership NFTs, locks, bridging, inflation
41
+ - `scripts/diamonds` - Diamond deployment scripts
42
+
43
+ ### Key Contracts
44
+
45
+ - `RuleEntitlement.sol` - Rule-based entitlements, cross-chain permission validation
46
+ - `EntitlementsManager.sol` - Entitlement validation and access control
47
+ - `Architect.sol` - Factory for space creation/initialization
48
+ - `CreateSpace.sol` - Space instance creation/initialization
49
+ - `Roles.sol` - Role-based permissions and hierarchies
50
+ - `Towns.sol` - Main ERC20 token (inflation, governance)
51
+ - `DropFacet.sol` - Token airdrops, claiming conditions
52
+ - `TownsPoints.sol` - Points-based rewards, check-ins, streaks
53
+ - `RewardsDistribution.sol` - Manages token staking, delegation proxies, and reward calculations
54
+ - `MainnetDelegation.sol` - Handles cross-chain delegation via cross-domain messengers
55
+ - `SpaceDelegationFacet.sol` - Manages delegation of spaces to node operators
56
+ - `EntitlementChecker.sol` - Cross-chain entitlement validation
57
+ - `DiamondCutFacet.sol` - Diamond upgradeability
58
+
59
+ ## Requirements
60
+
61
+ Install [yarn](https://yarnpkg.com/getting-started/install) via corepack:
62
+
63
+ ```shell
64
+ npm install -g corepack
65
+ corepack enable
66
+ ```
67
+
68
+ Install [Foundry](https://github.com/foundry-rs/foundry):
69
+
70
+ ```shell
71
+ curl -L https://foundry.paradigm.xyz | bash
72
+ foundryup
73
+ ```
74
+
75
+ ## Project Setup
76
+
77
+ Clone the repo, then:
78
+
79
+ ```shell
80
+ yarn
81
+ ```
82
+
83
+ **To compile the smart contracts:**
84
+
85
+ ```shell
86
+ forge build
87
+ ```
88
+
89
+ **To run the solidity unit tests:**
90
+
91
+ ```shell
92
+ forge test
93
+ ```
94
+
95
+ You can add verbosity to the tests by adding `-vvvv` (1-4 levels) to the command.
96
+
97
+ ## Local Development
98
+
99
+ **To start a local Ethereum blockchain:**
100
+
101
+ ```shell
102
+ anvil
103
+ ```
104
+
105
+ It will generate a set of 10 public/private keys with 10k ether each. Save one of these private keys for deployment.
106
+ It starts listening on `http://127.0.0.1:8545`.
107
+ If you want to interact with anvil via a front end, you will need to add the local network to Metamask with `ChainID=1337`.
108
+
109
+ **To start a local base blockchain and river blockchain:**
110
+
111
+ ```shell
112
+ ./scripts/bc-all-start.sh
113
+ ```
114
+
115
+ ## Deployment
116
+
117
+ ### Local Deployment
118
+
119
+ **To deploy our contracts to your local base and river instances:**
120
+
121
+ 1. Duplicate `.env.localhost` file in the [contracts](.) folder of the project and rename it to `.env` (this is excluded from git via .gitignore)
122
+ 2. Run `export RIVER_ENV="local_multi"` from your terminal
123
+ 3. Execute `./scripts/deploy-contracts.sh` to deploy the entire suite of contracts to your local base-anvil and river-anvil chains
124
+
125
+ ### Diamond Contract Deployment
126
+
127
+ **To deploy a single diamond base contract to your local anvil instance:**
128
+
129
+ From within the `contracts/` folder you can run:
130
+
131
+ ```shell
132
+ make deploy-base-anvil contract=Deploy[Contract] type=diamonds
133
+ ```
134
+
135
+ Replace `[Contract]` with the contract you want to deploy. You can see all the contracts available for deployment in the [diamonds deployments directory](./scripts/deployments/diamonds).
136
+
137
+ ### Facet Deployment
138
+
139
+ The project supports two methods for deploying facets:
140
+
141
+ 1. **Using custom deployment scripts:**
142
+
143
+ ```shell
144
+ make deploy-base-anvil contract=Deploy[Facet] type=facets
145
+ ```
146
+
147
+ - Replace `[Facet]` with the name of your facet deployment script found in [./scripts/deployments/facets](./scripts/deployments/facets)
148
+ - This approach uses scripts that inherit from `Deployer` and implement `versionName()` and `__deploy()` functions
149
+
150
+ 2. **Using the standardized `DeployFacet` script:**
151
+
152
+ ```shell
153
+ make deploy-facet-local rpc=base_anvil contract=[FacetName]
154
+ ```
155
+
156
+ - Replace `[FacetName]` with the actual facet contract name (without "Deploy" prefix)
157
+ - This approach uses the common `DeployFacet.s.sol` script with the `CONTRACT_NAME` environment variable
158
+ - It leverages deterministic CREATE2 addresses and supports batch deployments
159
+ - For more details, see the [DeployFacet documentation](https://github.com/towns-protocol/diamond/blob/main/scripts/README.md)
160
+
161
+ ### Live Network Deployment
162
+
163
+ **To deploy facets to a live network:**
164
+
165
+ From within the `contracts/` folder you can run:
166
+
167
+ ```shell
168
+ # For custom deployment scripts:
169
+ make deploy-base-sepolia contract=Deploy[Contract] type=facets context=[context]
170
+
171
+ # For standardized DeployFacet script:
172
+ make deploy-facet rpc=base_sepolia contract=[FacetName] context=[context]
173
+ ```
174
+
175
+ For example, to deploy the WalletLink facet to Base Sepolia with a deployment context of "gamma":
176
+
177
+ ```shell
178
+ # Using custom deployment script:
179
+ make deploy-base-sepolia contract=DeployWalletLink type=facets context=gamma
180
+
181
+ # Using standardized DeployFacet script:
182
+ make deploy-facet rpc=base_sepolia contract=WalletLink context=gamma
183
+ ```
184
+
185
+ ### Hardware Wallet Deployments
186
+
187
+ For hardware wallet deployments, use the corresponding ledger commands:
188
+
189
+ ```shell
190
+ # Using custom deployment script:
191
+ make deploy-ledger-base-sepolia contract=DeployWalletLink type=facets context=gamma
192
+
193
+ # Using standardized DeployFacet script:
194
+ make deploy-facet-ledger rpc=base_sepolia contract=WalletLink context=gamma
195
+ ```
196
+
197
+ You can see all the contracts available for deployment in the [deployments](./scripts/deployments) directory.
198
+
199
+ ## Contributing
200
+
201
+ For detailed information on contributing to this project, please see our [CONTRIBUTING.md](CONTRIBUTING.md) file. It includes:
202
+
203
+ - Guidelines for opening issues and pull requests
204
+ - Coding standards and best practices
205
+ - Diamond Pattern implementation details
206
+ - Facet development guidelines
@@ -0,0 +1,266 @@
1
+ # PermitAndStake Integration Guide
2
+
3
+ This guide explains how to integrate with the new `permitAndStake` function in the Towns Protocol RewardsDistribution contract, which uses Permit2 for gasless token approvals and enhanced smart contract wallet support.
4
+
5
+ ## Overview
6
+
7
+ The `permitAndStake` function allows users to approve and stake tokens in a single transaction using Uniswap's Permit2 protocol. This provides several advantages over traditional EIP-2612 permits:
8
+
9
+ - **Smart Contract Wallet Support**: Works with smart contracts via ERC-1271 signature verification
10
+ - **Universal Token Approval**: Uses Permit2 as a universal approval router
11
+ - **Enhanced Security**: Cryptographically binds signatures to specific spenders and amounts
12
+ - **Gasless Approval**: No separate approval transaction required
13
+
14
+ ## Prerequisites
15
+
16
+ Before using `permitAndStake`, ensure:
17
+
18
+ 1. **Towns Token Approval**: No pre-approval needed. The Towns token gives Permit2 infinite allowance by default, so users can directly call `permitAndStake` without any prior approval transactions.
19
+
20
+ 2. **Permit2 Deployment**: Permit2 is deployed at the deterministic address `0x000000000022D473030F116dDEE9F6B43aC78BA3` on all networks.
21
+
22
+ ## Function Signature
23
+
24
+ ```solidity
25
+ function permitAndStake(
26
+ uint96 amount, // Amount of Towns tokens to stake
27
+ address delegatee, // Operator or space to delegate to
28
+ address beneficiary, // Address that receives staking rewards
29
+ uint256 nonce, // Unique nonce for replay protection
30
+ uint256 deadline, // Expiration timestamp for the permit
31
+ bytes calldata signature // Permit2 signature
32
+ ) external returns (uint256 depositId);
33
+ ```
34
+
35
+ ## Integration Guide
36
+
37
+ ### TypeScript/JavaScript Integration
38
+
39
+ #### Dependencies
40
+
41
+ ```bash
42
+ yarn add @uniswap/permit2-sdk viem
43
+ ```
44
+
45
+ #### Complete Integration Example
46
+
47
+ ```typescript
48
+ import {
49
+ PERMIT2_ADDRESS,
50
+ SignatureTransfer,
51
+ PermitTransferFrom,
52
+ } from "@uniswap/permit2-sdk";
53
+ import { createWalletClient, http, parseUnits } from "viem";
54
+ import { privateKeyToAccount } from "viem/accounts";
55
+ import { base } from "viem/chains";
56
+
57
+ // Contract addresses
58
+ const REWARDS_DISTRIBUTION_ADDRESS = "0x..."; // Your deployed contract
59
+ const TOWNS_TOKEN_ADDRESS = "0x..."; // Towns token address
60
+
61
+ // Create wallet client
62
+ const account = privateKeyToAccount("0x...");
63
+ const walletClient = createWalletClient({
64
+ account,
65
+ chain: base,
66
+ transport: http(),
67
+ });
68
+
69
+ async function permitAndStake({
70
+ amount, // Amount to stake (in token units, e.g., "100")
71
+ delegatee, // Operator or space address
72
+ beneficiary, // Beneficiary address
73
+ }) {
74
+ // 1. Convert amount to proper units
75
+ const amountWei = parseUnits(amount, 18); // Towns token has 18 decimals
76
+
77
+ // 2. Generate unique nonce (you can use timestamp + random)
78
+ const nonce =
79
+ BigInt(Math.floor(Date.now() / 1000)) * 1000000n +
80
+ BigInt(Math.floor(Math.random() * 1000000));
81
+
82
+ // 3. Set deadline (e.g., 10 minutes from now)
83
+ const deadline = BigInt(Math.floor(Date.now() / 1000) + 600);
84
+
85
+ // 4. Create permit data structure
86
+ const permit: PermitTransferFrom = {
87
+ permitted: {
88
+ token: TOWNS_TOKEN_ADDRESS,
89
+ amount: amountWei,
90
+ },
91
+ spender: REWARDS_DISTRIBUTION_ADDRESS,
92
+ nonce: nonce,
93
+ deadline: deadline,
94
+ };
95
+
96
+ // 5. Create domain for signing
97
+ const domain = {
98
+ name: "Permit2",
99
+ version: "1",
100
+ chainId: base.id,
101
+ verifyingContract: PERMIT2_ADDRESS as `0x${string}`,
102
+ };
103
+
104
+ // 6. Sign the permit
105
+ const signature = await walletClient.signTypedData({
106
+ account,
107
+ domain,
108
+ types: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id)
109
+ .types,
110
+ primaryType: "PermitTransferFrom",
111
+ message: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id)
112
+ .values,
113
+ });
114
+
115
+ // 7. Call permitAndStake
116
+ const txHash = await walletClient.writeContract({
117
+ address: REWARDS_DISTRIBUTION_ADDRESS,
118
+ abi: [
119
+ {
120
+ name: "permitAndStake",
121
+ type: "function",
122
+ inputs: [
123
+ { name: "amount", type: "uint96" },
124
+ { name: "delegatee", type: "address" },
125
+ { name: "beneficiary", type: "address" },
126
+ { name: "nonce", type: "uint256" },
127
+ { name: "deadline", type: "uint256" },
128
+ { name: "signature", type: "bytes" },
129
+ ],
130
+ outputs: [{ name: "depositId", type: "uint256" }],
131
+ },
132
+ ],
133
+ functionName: "permitAndStake",
134
+ args: [amountWei, delegatee, beneficiary, nonce, deadline, signature],
135
+ });
136
+
137
+ return txHash;
138
+ }
139
+
140
+ // Usage example
141
+ async function main() {
142
+ const txHash = await permitAndStake({
143
+ amount: "100", // Stake 100 Towns tokens
144
+ delegatee: "0x123...", // Operator address
145
+ beneficiary: "0x456...", // Beneficiary address
146
+ });
147
+
148
+ console.log("Transaction hash:", txHash);
149
+ }
150
+ ```
151
+
152
+ #### Wallet Integration (MetaMask/WalletConnect)
153
+
154
+ ```typescript
155
+ import { useAccount, useSignTypedData, useWriteContract } from 'wagmi';
156
+
157
+ function StakeWithPermit() {
158
+ const { address } = useAccount();
159
+ const { signTypedDataAsync } = useSignTypedData();
160
+ const { writeContractAsync } = useWriteContract();
161
+
162
+ const handleStakeWithPermit = async (amount: string, delegatee: string) => {
163
+ try {
164
+ // Prepare permit data
165
+ const amountWei = parseUnits(amount, 18);
166
+ const nonce = BigInt(Date.now());
167
+ const deadline = BigInt(Math.floor(Date.now() / 1000) + 600);
168
+
169
+ const permit = {
170
+ permitted: {
171
+ token: TOWNS_TOKEN_ADDRESS,
172
+ amount: amountWei,
173
+ },
174
+ spender: REWARDS_DISTRIBUTION_ADDRESS,
175
+ nonce,
176
+ deadline,
177
+ };
178
+
179
+ // Sign permit
180
+ const signature = await signTypedDataAsync({
181
+ domain: {
182
+ name: 'Permit2',
183
+ version: '1',
184
+ chainId: base.id,
185
+ verifyingContract: PERMIT2_ADDRESS,
186
+ },
187
+ types: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id).types,
188
+ primaryType: 'PermitTransferFrom',
189
+ message: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id).values,
190
+ });
191
+
192
+ // Execute stake
193
+ const txHash = await writeContractAsync({
194
+ address: REWARDS_DISTRIBUTION_ADDRESS,
195
+ abi: rewardsDistributionAbi,
196
+ functionName: 'permitAndStake',
197
+ args: [amountWei, delegatee, address, nonce, deadline, signature]
198
+ });
199
+
200
+ console.log('Staking successful:', txHash);
201
+ } catch (error) {
202
+ console.error('Staking failed:', error);
203
+ }
204
+ };
205
+
206
+ return (
207
+ <button onClick={() => handleStakeWithPermit("100", "0x...")}>
208
+ Stake with Permit
209
+ </button>
210
+ );
211
+ }
212
+ ```
213
+
214
+ ## Security Considerations
215
+
216
+ ### 1. Nonce Management
217
+
218
+ - **Uniqueness**: Each permit must use a unique nonce
219
+ - **Collision Prevention**: Use timestamp-based or incrementing nonces
220
+ - **Replay Protection**: Never reuse nonces
221
+
222
+ ### 2. Deadline Validation
223
+
224
+ - **Short Expiry**: Use reasonable deadlines (5-30 minutes)
225
+ - **Clock Skew**: Account for minor time differences between client and blockchain
226
+
227
+ ### 3. Signature Security
228
+
229
+ - **Private Key Protection**: Never expose private keys in frontend code
230
+ - **Secure Signing**: Use hardware wallets or secure key management for production
231
+ - **Verification**: Always verify signature validity before submission
232
+
233
+ ### 4. Front-running Protection
234
+
235
+ The permit signature cryptographically binds to `msg.sender`, preventing front-running attacks. An attacker cannot use someone else's signature because verification will fail.
236
+
237
+ ## Error Handling
238
+
239
+ Common errors and solutions:
240
+
241
+ ```typescript
242
+ try {
243
+ const txHash = await permitAndStake(...);
244
+ } catch (error) {
245
+ if (error.message.includes('InvalidSignature')) {
246
+ // Signature verification failed - check signing process
247
+ console.error('Invalid permit signature');
248
+ } else if (error.message.includes('ExpiredDeadline')) {
249
+ // Deadline passed - generate new permit
250
+ console.error('Permit expired, please try again');
251
+ } else if (error.message.includes('InvalidNonce')) {
252
+ // Nonce already used or invalid
253
+ console.error('Invalid nonce, generate a new one');
254
+ }
255
+ }
256
+ ```
257
+
258
+ ## Best Practices
259
+
260
+ 1. **Gas Optimization**: Batch multiple operations when possible
261
+ 2. **User Experience**: Show clear signing prompts explaining what users are approving
262
+ 3. **Error Messages**: Provide user-friendly error messages
263
+ 4. **Fallback**: Offer traditional `approve` + `stake` flow as backup
264
+ 5. **Testing**: Test with different wallet types (EOA, smart contract wallets)
265
+
266
+ This integration enables gasless token approvals and enhanced compatibility with smart contract wallets, providing a superior user experience for staking in the Towns Protocol.