@towns-labs/web3 2.0.1

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 (378) hide show
  1. package/README.md +3 -0
  2. package/dist/BaseContractShim.d.ts +57 -0
  3. package/dist/BaseContractShim.d.ts.map +1 -0
  4. package/dist/BaseContractShim.js +224 -0
  5. package/dist/BaseContractShim.js.map +1 -0
  6. package/dist/airdrop/IDropFacetShim.d.ts +9 -0
  7. package/dist/airdrop/IDropFacetShim.d.ts.map +1 -0
  8. package/dist/airdrop/IDropFacetShim.js +9 -0
  9. package/dist/airdrop/IDropFacetShim.js.map +1 -0
  10. package/dist/airdrop/IRiverPointsShim.d.ts +9 -0
  11. package/dist/airdrop/IRiverPointsShim.d.ts.map +1 -0
  12. package/dist/airdrop/IRiverPointsShim.js +9 -0
  13. package/dist/airdrop/IRiverPointsShim.js.map +1 -0
  14. package/dist/airdrop/RiverAirdropDapp.d.ts +16 -0
  15. package/dist/airdrop/RiverAirdropDapp.d.ts.map +1 -0
  16. package/dist/airdrop/RiverAirdropDapp.js +30 -0
  17. package/dist/airdrop/RiverAirdropDapp.js.map +1 -0
  18. package/dist/app-registry/AppRegistryDapp.d.ts +68 -0
  19. package/dist/app-registry/AppRegistryDapp.d.ts.map +1 -0
  20. package/dist/app-registry/AppRegistryDapp.js +182 -0
  21. package/dist/app-registry/AppRegistryDapp.js.map +1 -0
  22. package/dist/app-registry/IAppFactoryShim.d.ts +9 -0
  23. package/dist/app-registry/IAppFactoryShim.d.ts.map +1 -0
  24. package/dist/app-registry/IAppFactoryShim.js +9 -0
  25. package/dist/app-registry/IAppFactoryShim.js.map +1 -0
  26. package/dist/app-registry/IAppInstallerShim.d.ts +9 -0
  27. package/dist/app-registry/IAppInstallerShim.d.ts.map +1 -0
  28. package/dist/app-registry/IAppInstallerShim.js +9 -0
  29. package/dist/app-registry/IAppInstallerShim.js.map +1 -0
  30. package/dist/app-registry/IAppRegistryShim.d.ts +9 -0
  31. package/dist/app-registry/IAppRegistryShim.d.ts.map +1 -0
  32. package/dist/app-registry/IAppRegistryShim.js +9 -0
  33. package/dist/app-registry/IAppRegistryShim.js.map +1 -0
  34. package/dist/app-registry/IIdentityRegistryShim.d.ts +9 -0
  35. package/dist/app-registry/IIdentityRegistryShim.d.ts.map +1 -0
  36. package/dist/app-registry/IIdentityRegistryShim.js +9 -0
  37. package/dist/app-registry/IIdentityRegistryShim.js.map +1 -0
  38. package/dist/app-registry/IReputationRegistryShim.d.ts +9 -0
  39. package/dist/app-registry/IReputationRegistryShim.d.ts.map +1 -0
  40. package/dist/app-registry/IReputationRegistryShim.js +9 -0
  41. package/dist/app-registry/IReputationRegistryShim.js.map +1 -0
  42. package/dist/app-registry/SimpleAppShim.d.ts +9 -0
  43. package/dist/app-registry/SimpleAppShim.d.ts.map +1 -0
  44. package/dist/app-registry/SimpleAppShim.js +9 -0
  45. package/dist/app-registry/SimpleAppShim.js.map +1 -0
  46. package/dist/base-registry/BaseRegistry.d.ts +32 -0
  47. package/dist/base-registry/BaseRegistry.d.ts.map +1 -0
  48. package/dist/base-registry/BaseRegistry.js +67 -0
  49. package/dist/base-registry/BaseRegistry.js.map +1 -0
  50. package/dist/base-registry/IEntitlementCheckerShim.d.ts +9 -0
  51. package/dist/base-registry/IEntitlementCheckerShim.d.ts.map +1 -0
  52. package/dist/base-registry/IEntitlementCheckerShim.js +9 -0
  53. package/dist/base-registry/IEntitlementCheckerShim.js.map +1 -0
  54. package/dist/base-registry/INodeOperatorShim.d.ts +9 -0
  55. package/dist/base-registry/INodeOperatorShim.d.ts.map +1 -0
  56. package/dist/base-registry/INodeOperatorShim.js +9 -0
  57. package/dist/base-registry/INodeOperatorShim.js.map +1 -0
  58. package/dist/base-registry/ISpaceDelegationShim.d.ts +9 -0
  59. package/dist/base-registry/ISpaceDelegationShim.d.ts.map +1 -0
  60. package/dist/base-registry/ISpaceDelegationShim.js +9 -0
  61. package/dist/base-registry/ISpaceDelegationShim.js.map +1 -0
  62. package/dist/base-registry/RewardsDistributionShim.d.ts +9 -0
  63. package/dist/base-registry/RewardsDistributionShim.d.ts.map +1 -0
  64. package/dist/base-registry/RewardsDistributionShim.js +9 -0
  65. package/dist/base-registry/RewardsDistributionShim.js.map +1 -0
  66. package/dist/cache/EntitlementCache.d.ts +25 -0
  67. package/dist/cache/EntitlementCache.d.ts.map +1 -0
  68. package/dist/cache/EntitlementCache.js +91 -0
  69. package/dist/cache/EntitlementCache.js.map +1 -0
  70. package/dist/cache/ICacheStorage.d.ts +44 -0
  71. package/dist/cache/ICacheStorage.d.ts.map +1 -0
  72. package/dist/cache/ICacheStorage.js +2 -0
  73. package/dist/cache/ICacheStorage.js.map +1 -0
  74. package/dist/cache/KVCacheStorage.d.ts +79 -0
  75. package/dist/cache/KVCacheStorage.d.ts.map +1 -0
  76. package/dist/cache/KVCacheStorage.js +227 -0
  77. package/dist/cache/KVCacheStorage.js.map +1 -0
  78. package/dist/cache/Keyable.d.ts +20 -0
  79. package/dist/cache/Keyable.d.ts.map +1 -0
  80. package/dist/cache/Keyable.js +62 -0
  81. package/dist/cache/Keyable.js.map +1 -0
  82. package/dist/cache/SimpleCache.d.ts +30 -0
  83. package/dist/cache/SimpleCache.d.ts.map +1 -0
  84. package/dist/cache/SimpleCache.js +84 -0
  85. package/dist/cache/SimpleCache.js.map +1 -0
  86. package/dist/cache/TTLCacheStorage.d.ts +19 -0
  87. package/dist/cache/TTLCacheStorage.d.ts.map +1 -0
  88. package/dist/cache/TTLCacheStorage.js +40 -0
  89. package/dist/cache/TTLCacheStorage.js.map +1 -0
  90. package/dist/chain.d.ts +89 -0
  91. package/dist/chain.d.ts.map +1 -0
  92. package/dist/chain.js +48 -0
  93. package/dist/chain.js.map +1 -0
  94. package/dist/delegate-registry/DelegateRegistry.d.ts +3 -0
  95. package/dist/delegate-registry/DelegateRegistry.d.ts.map +1 -0
  96. package/dist/delegate-registry/DelegateRegistry.js +72 -0
  97. package/dist/delegate-registry/DelegateRegistry.js.map +1 -0
  98. package/dist/eip-712/EIP-712.d.ts +35 -0
  99. package/dist/eip-712/EIP-712.d.ts.map +1 -0
  100. package/dist/eip-712/EIP-712.js +57 -0
  101. package/dist/eip-712/EIP-712.js.map +1 -0
  102. package/dist/erc-721/IERC721AQueryableShim.d.ts +9 -0
  103. package/dist/erc-721/IERC721AQueryableShim.d.ts.map +1 -0
  104. package/dist/erc-721/IERC721AQueryableShim.js +9 -0
  105. package/dist/erc-721/IERC721AQueryableShim.js.map +1 -0
  106. package/dist/erc-721/IERC721AShim.d.ts +9 -0
  107. package/dist/erc-721/IERC721AShim.d.ts.map +1 -0
  108. package/dist/erc-721/IERC721AShim.js +9 -0
  109. package/dist/erc-721/IERC721AShim.js.map +1 -0
  110. package/dist/index.d.ts +96 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +96 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/platform-requirements/PlatformRequirements.d.ts +12 -0
  115. package/dist/platform-requirements/PlatformRequirements.d.ts.map +1 -0
  116. package/dist/platform-requirements/PlatformRequirements.js +18 -0
  117. package/dist/platform-requirements/PlatformRequirements.js.map +1 -0
  118. package/dist/pricing-modules/IPricingShim.d.ts +9 -0
  119. package/dist/pricing-modules/IPricingShim.d.ts.map +1 -0
  120. package/dist/pricing-modules/IPricingShim.js +9 -0
  121. package/dist/pricing-modules/IPricingShim.js.map +1 -0
  122. package/dist/pricing-modules/PricingModules.d.ts +13 -0
  123. package/dist/pricing-modules/PricingModules.d.ts.map +1 -0
  124. package/dist/pricing-modules/PricingModules.js +23 -0
  125. package/dist/pricing-modules/PricingModules.js.map +1 -0
  126. package/dist/pricing-modules/helpers.d.ts +16 -0
  127. package/dist/pricing-modules/helpers.d.ts.map +1 -0
  128. package/dist/pricing-modules/helpers.js +35 -0
  129. package/dist/pricing-modules/helpers.js.map +1 -0
  130. package/dist/readContractRetryer.d.ts +10 -0
  131. package/dist/readContractRetryer.d.ts.map +1 -0
  132. package/dist/readContractRetryer.js +68 -0
  133. package/dist/readContractRetryer.js.map +1 -0
  134. package/dist/river-registry/INodeRegistryShim.d.ts +9 -0
  135. package/dist/river-registry/INodeRegistryShim.d.ts.map +1 -0
  136. package/dist/river-registry/INodeRegistryShim.js +9 -0
  137. package/dist/river-registry/INodeRegistryShim.js.map +1 -0
  138. package/dist/river-registry/IOperatorRegistryShim.d.ts +9 -0
  139. package/dist/river-registry/IOperatorRegistryShim.d.ts.map +1 -0
  140. package/dist/river-registry/IOperatorRegistryShim.js +9 -0
  141. package/dist/river-registry/IOperatorRegistryShim.js.map +1 -0
  142. package/dist/river-registry/IStreamRegistryShim.d.ts +9 -0
  143. package/dist/river-registry/IStreamRegistryShim.d.ts.map +1 -0
  144. package/dist/river-registry/IStreamRegistryShim.js +9 -0
  145. package/dist/river-registry/IStreamRegistryShim.js.map +1 -0
  146. package/dist/river-registry/RiverRegistry.d.ts +18 -0
  147. package/dist/river-registry/RiverRegistry.d.ts.map +1 -0
  148. package/dist/river-registry/RiverRegistry.js +42 -0
  149. package/dist/river-registry/RiverRegistry.js.map +1 -0
  150. package/dist/river-registry/RiverRegistryFactory.d.ts +5 -0
  151. package/dist/river-registry/RiverRegistryFactory.d.ts.map +1 -0
  152. package/dist/river-registry/RiverRegistryFactory.js +5 -0
  153. package/dist/river-registry/RiverRegistryFactory.js.map +1 -0
  154. package/dist/space/IAppAccountShim.d.ts +9 -0
  155. package/dist/space/IAppAccountShim.d.ts.map +1 -0
  156. package/dist/space/IAppAccountShim.js +9 -0
  157. package/dist/space/IAppAccountShim.js.map +1 -0
  158. package/dist/space/IBanningShim.d.ts +9 -0
  159. package/dist/space/IBanningShim.d.ts.map +1 -0
  160. package/dist/space/IBanningShim.js +9 -0
  161. package/dist/space/IBanningShim.js.map +1 -0
  162. package/dist/space/IChannelShim.d.ts +9 -0
  163. package/dist/space/IChannelShim.d.ts.map +1 -0
  164. package/dist/space/IChannelShim.js +9 -0
  165. package/dist/space/IChannelShim.js.map +1 -0
  166. package/dist/space/IEntitlementDataQueryableShim.d.ts +11 -0
  167. package/dist/space/IEntitlementDataQueryableShim.d.ts.map +1 -0
  168. package/dist/space/IEntitlementDataQueryableShim.js +9 -0
  169. package/dist/space/IEntitlementDataQueryableShim.js.map +1 -0
  170. package/dist/space/IEntitlementsShim.d.ts +13 -0
  171. package/dist/space/IEntitlementsShim.d.ts.map +1 -0
  172. package/dist/space/IEntitlementsShim.js +19 -0
  173. package/dist/space/IEntitlementsShim.js.map +1 -0
  174. package/dist/space/IMembershipMetadataShim.d.ts +9 -0
  175. package/dist/space/IMembershipMetadataShim.d.ts.map +1 -0
  176. package/dist/space/IMembershipMetadataShim.js +9 -0
  177. package/dist/space/IMembershipMetadataShim.js.map +1 -0
  178. package/dist/space/IMembershipShim.d.ts +33 -0
  179. package/dist/space/IMembershipShim.d.ts.map +1 -0
  180. package/dist/space/IMembershipShim.js +139 -0
  181. package/dist/space/IMembershipShim.js.map +1 -0
  182. package/dist/space/IMulticallShim.d.ts +13 -0
  183. package/dist/space/IMulticallShim.d.ts.map +1 -0
  184. package/dist/space/IMulticallShim.js +15 -0
  185. package/dist/space/IMulticallShim.js.map +1 -0
  186. package/dist/space/IReviewShim.d.ts +64 -0
  187. package/dist/space/IReviewShim.d.ts.map +1 -0
  188. package/dist/space/IReviewShim.js +102 -0
  189. package/dist/space/IReviewShim.js.map +1 -0
  190. package/dist/space/IRolesShim.d.ts +10 -0
  191. package/dist/space/IRolesShim.d.ts.map +1 -0
  192. package/dist/space/IRolesShim.js +9 -0
  193. package/dist/space/IRolesShim.js.map +1 -0
  194. package/dist/space/ITippingShim.d.ts +39 -0
  195. package/dist/space/ITippingShim.d.ts.map +1 -0
  196. package/dist/space/ITippingShim.js +76 -0
  197. package/dist/space/ITippingShim.js.map +1 -0
  198. package/dist/space/ITreasuryShim.d.ts +9 -0
  199. package/dist/space/ITreasuryShim.d.ts.map +1 -0
  200. package/dist/space/ITreasuryShim.js +9 -0
  201. package/dist/space/ITreasuryShim.js.map +1 -0
  202. package/dist/space/OwnableFacetShim.d.ts +12 -0
  203. package/dist/space/OwnableFacetShim.d.ts.map +1 -0
  204. package/dist/space/OwnableFacetShim.js +19 -0
  205. package/dist/space/OwnableFacetShim.js.map +1 -0
  206. package/dist/space/Space.d.ts +107 -0
  207. package/dist/space/Space.d.ts.map +1 -0
  208. package/dist/space/Space.js +511 -0
  209. package/dist/space/Space.js.map +1 -0
  210. package/dist/space/TokenPausableFacetShim.d.ts +9 -0
  211. package/dist/space/TokenPausableFacetShim.d.ts.map +1 -0
  212. package/dist/space/TokenPausableFacetShim.js +9 -0
  213. package/dist/space/TokenPausableFacetShim.js.map +1 -0
  214. package/dist/space/entitlements/ConvertersEntitlements.d.ts +14 -0
  215. package/dist/space/entitlements/ConvertersEntitlements.d.ts.map +1 -0
  216. package/dist/space/entitlements/ConvertersEntitlements.js +193 -0
  217. package/dist/space/entitlements/ConvertersEntitlements.js.map +1 -0
  218. package/dist/space/entitlements/RuleBuilder.d.ts +83 -0
  219. package/dist/space/entitlements/RuleBuilder.d.ts.map +1 -0
  220. package/dist/space/entitlements/RuleBuilder.js +86 -0
  221. package/dist/space/entitlements/RuleBuilder.js.map +1 -0
  222. package/dist/space/entitlements/RuleEntitlementShim.d.ts +353 -0
  223. package/dist/space/entitlements/RuleEntitlementShim.d.ts.map +1 -0
  224. package/dist/space/entitlements/RuleEntitlementShim.js +40 -0
  225. package/dist/space/entitlements/RuleEntitlementShim.js.map +1 -0
  226. package/dist/space/entitlements/RuleEntitlementV2Shim.d.ts +353 -0
  227. package/dist/space/entitlements/RuleEntitlementV2Shim.d.ts.map +1 -0
  228. package/dist/space/entitlements/RuleEntitlementV2Shim.js +40 -0
  229. package/dist/space/entitlements/RuleEntitlementV2Shim.js.map +1 -0
  230. package/dist/space/entitlements/UserEntitlementShim.d.ts +13 -0
  231. package/dist/space/entitlements/UserEntitlementShim.d.ts.map +1 -0
  232. package/dist/space/entitlements/UserEntitlementShim.js +45 -0
  233. package/dist/space/entitlements/UserEntitlementShim.js.map +1 -0
  234. package/dist/space/entitlements/XChainConfig.d.ts +14 -0
  235. package/dist/space/entitlements/XChainConfig.d.ts.map +1 -0
  236. package/dist/space/entitlements/XChainConfig.js +70 -0
  237. package/dist/space/entitlements/XChainConfig.js.map +1 -0
  238. package/dist/space/entitlements/entitlement.d.ts +147 -0
  239. package/dist/space/entitlements/entitlement.d.ts.map +1 -0
  240. package/dist/space/entitlements/entitlement.js +940 -0
  241. package/dist/space/entitlements/entitlement.js.map +1 -0
  242. package/dist/space/entitlements/validateAndParseXChainConfig.d.ts +6 -0
  243. package/dist/space/entitlements/validateAndParseXChainConfig.d.ts.map +1 -0
  244. package/dist/space/entitlements/validateAndParseXChainConfig.js +34 -0
  245. package/dist/space/entitlements/validateAndParseXChainConfig.js.map +1 -0
  246. package/dist/space-dapp/SpaceDapp.d.ts +223 -0
  247. package/dist/space-dapp/SpaceDapp.d.ts.map +1 -0
  248. package/dist/space-dapp/SpaceDapp.js +1260 -0
  249. package/dist/space-dapp/SpaceDapp.js.map +1 -0
  250. package/dist/space-dapp/SpaceDappFactory.d.ts +5 -0
  251. package/dist/space-dapp/SpaceDappFactory.d.ts.map +1 -0
  252. package/dist/space-dapp/SpaceDappFactory.js +8 -0
  253. package/dist/space-dapp/SpaceDappFactory.js.map +1 -0
  254. package/dist/space-dapp/wrapTransaction.d.ts +4 -0
  255. package/dist/space-dapp/wrapTransaction.d.ts.map +1 -0
  256. package/dist/space-dapp/wrapTransaction.js +99 -0
  257. package/dist/space-dapp/wrapTransaction.js.map +1 -0
  258. package/dist/space-owner/GuardianFacetShim.d.ts +9 -0
  259. package/dist/space-owner/GuardianFacetShim.d.ts.map +1 -0
  260. package/dist/space-owner/GuardianFacetShim.js +9 -0
  261. package/dist/space-owner/GuardianFacetShim.js.map +1 -0
  262. package/dist/space-owner/SpaceOwner.d.ts +48 -0
  263. package/dist/space-owner/SpaceOwner.d.ts.map +1 -0
  264. package/dist/space-owner/SpaceOwner.js +81 -0
  265. package/dist/space-owner/SpaceOwner.js.map +1 -0
  266. package/dist/space-registrar/ICreateSpaceShim.d.ts +11 -0
  267. package/dist/space-registrar/ICreateSpaceShim.d.ts.map +1 -0
  268. package/dist/space-registrar/ICreateSpaceShim.js +9 -0
  269. package/dist/space-registrar/ICreateSpaceShim.js.map +1 -0
  270. package/dist/space-registrar/ILegacySpaceArchitectShim.d.ts +10 -0
  271. package/dist/space-registrar/ILegacySpaceArchitectShim.d.ts.map +1 -0
  272. package/dist/space-registrar/ILegacySpaceArchitectShim.js +9 -0
  273. package/dist/space-registrar/ILegacySpaceArchitectShim.js.map +1 -0
  274. package/dist/space-registrar/ISpaceArchitectShim.d.ts +10 -0
  275. package/dist/space-registrar/ISpaceArchitectShim.d.ts.map +1 -0
  276. package/dist/space-registrar/ISpaceArchitectShim.js +39 -0
  277. package/dist/space-registrar/ISpaceArchitectShim.js.map +1 -0
  278. package/dist/space-registrar/SpaceRegistrar.d.ts +27 -0
  279. package/dist/space-registrar/SpaceRegistrar.d.ts.map +1 -0
  280. package/dist/space-registrar/SpaceRegistrar.js +58 -0
  281. package/dist/space-registrar/SpaceRegistrar.js.map +1 -0
  282. package/dist/test-helpers/LocalhostWeb3Provider.d.ts +19 -0
  283. package/dist/test-helpers/LocalhostWeb3Provider.d.ts.map +1 -0
  284. package/dist/test-helpers/LocalhostWeb3Provider.js +80 -0
  285. package/dist/test-helpers/LocalhostWeb3Provider.js.map +1 -0
  286. package/dist/test-helpers/MockCrossChainEntitlement.d.ts +6 -0
  287. package/dist/test-helpers/MockCrossChainEntitlement.d.ts.map +1 -0
  288. package/dist/test-helpers/MockCrossChainEntitlement.js +104 -0
  289. package/dist/test-helpers/MockCrossChainEntitlement.js.map +1 -0
  290. package/dist/test-helpers/MockERC1155.d.ts +6 -0
  291. package/dist/test-helpers/MockERC1155.d.ts.map +1 -0
  292. package/dist/test-helpers/MockERC1155.js +518 -0
  293. package/dist/test-helpers/MockERC1155.js.map +1 -0
  294. package/dist/test-helpers/MockERC20.d.ts +6 -0
  295. package/dist/test-helpers/MockERC20.d.ts.map +1 -0
  296. package/dist/test-helpers/MockERC20.js +574 -0
  297. package/dist/test-helpers/MockERC20.js.map +1 -0
  298. package/dist/test-helpers/MockERC721A.d.ts +1563 -0
  299. package/dist/test-helpers/MockERC721A.d.ts.map +1 -0
  300. package/dist/test-helpers/MockERC721A.js +1913 -0
  301. package/dist/test-helpers/MockERC721A.js.map +1 -0
  302. package/dist/test-helpers/MockERC721AShim.d.ts +9 -0
  303. package/dist/test-helpers/MockERC721AShim.d.ts.map +1 -0
  304. package/dist/test-helpers/MockERC721AShim.js +9 -0
  305. package/dist/test-helpers/MockERC721AShim.js.map +1 -0
  306. package/dist/test-helpers/TestCrossChainEntitlement.d.ts +14 -0
  307. package/dist/test-helpers/TestCrossChainEntitlement.d.ts.map +1 -0
  308. package/dist/test-helpers/TestCrossChainEntitlement.js +99 -0
  309. package/dist/test-helpers/TestCrossChainEntitlement.js.map +1 -0
  310. package/dist/test-helpers/TestEthBalance.d.ts +72 -0
  311. package/dist/test-helpers/TestEthBalance.d.ts.map +1 -0
  312. package/dist/test-helpers/TestEthBalance.js +94 -0
  313. package/dist/test-helpers/TestEthBalance.js.map +1 -0
  314. package/dist/test-helpers/TestGatingERC1155.d.ts +17 -0
  315. package/dist/test-helpers/TestGatingERC1155.d.ts.map +1 -0
  316. package/dist/test-helpers/TestGatingERC1155.js +100 -0
  317. package/dist/test-helpers/TestGatingERC1155.js.map +1 -0
  318. package/dist/test-helpers/TestGatingERC20.d.ts +17 -0
  319. package/dist/test-helpers/TestGatingERC20.d.ts.map +1 -0
  320. package/dist/test-helpers/TestGatingERC20.js +149 -0
  321. package/dist/test-helpers/TestGatingERC20.js.map +1 -0
  322. package/dist/test-helpers/TestGatingNFT.d.ts +17 -0
  323. package/dist/test-helpers/TestGatingNFT.d.ts.map +1 -0
  324. package/dist/test-helpers/TestGatingNFT.js +137 -0
  325. package/dist/test-helpers/TestGatingNFT.js.map +1 -0
  326. package/dist/test-helpers/TestGatingUtils.d.ts +15 -0
  327. package/dist/test-helpers/TestGatingUtils.d.ts.map +1 -0
  328. package/dist/test-helpers/TestGatingUtils.js +112 -0
  329. package/dist/test-helpers/TestGatingUtils.js.map +1 -0
  330. package/dist/test-helpers/utils.d.ts +22 -0
  331. package/dist/test-helpers/utils.d.ts.map +1 -0
  332. package/dist/test-helpers/utils.js +30 -0
  333. package/dist/test-helpers/utils.js.map +1 -0
  334. package/dist/towns-token/TownsToken.d.ts +17 -0
  335. package/dist/towns-token/TownsToken.d.ts.map +1 -0
  336. package/dist/towns-token/TownsToken.js +33 -0
  337. package/dist/towns-token/TownsToken.js.map +1 -0
  338. package/dist/types/ContractTypes.d.ts +240 -0
  339. package/dist/types/ContractTypes.d.ts.map +1 -0
  340. package/dist/types/ContractTypes.js +65 -0
  341. package/dist/types/ContractTypes.js.map +1 -0
  342. package/dist/types/error-types.d.ts +7 -0
  343. package/dist/types/error-types.d.ts.map +1 -0
  344. package/dist/types/error-types.js +13 -0
  345. package/dist/types/error-types.js.map +1 -0
  346. package/dist/types/typechain.d.ts +4 -0
  347. package/dist/types/typechain.d.ts.map +1 -0
  348. package/dist/types/typechain.js +2 -0
  349. package/dist/types/typechain.js.map +1 -0
  350. package/dist/types/types.d.ts +29 -0
  351. package/dist/types/types.d.ts.map +1 -0
  352. package/dist/types/types.js +2 -0
  353. package/dist/types/types.js.map +1 -0
  354. package/dist/utils/ContractHelpers.d.ts +14 -0
  355. package/dist/utils/ContractHelpers.d.ts.map +1 -0
  356. package/dist/utils/ContractHelpers.js +54 -0
  357. package/dist/utils/ContractHelpers.js.map +1 -0
  358. package/dist/utils/Web3Constants.d.ts +6 -0
  359. package/dist/utils/Web3Constants.d.ts.map +1 -0
  360. package/dist/utils/Web3Constants.js +7 -0
  361. package/dist/utils/Web3Constants.js.map +1 -0
  362. package/dist/utils/ut.d.ts +46 -0
  363. package/dist/utils/ut.d.ts.map +1 -0
  364. package/dist/utils/ut.js +94 -0
  365. package/dist/utils/ut.js.map +1 -0
  366. package/dist/utils/web3Env.d.ts +36 -0
  367. package/dist/utils/web3Env.d.ts.map +1 -0
  368. package/dist/utils/web3Env.js +123 -0
  369. package/dist/utils/web3Env.js.map +1 -0
  370. package/dist/wallet-link/WalletLink.d.ts +58 -0
  371. package/dist/wallet-link/WalletLink.d.ts.map +1 -0
  372. package/dist/wallet-link/WalletLink.js +226 -0
  373. package/dist/wallet-link/WalletLink.js.map +1 -0
  374. package/dist/wallet-link/WalletLinkShim.d.ts +9 -0
  375. package/dist/wallet-link/WalletLinkShim.d.ts.map +1 -0
  376. package/dist/wallet-link/WalletLinkShim.js +9 -0
  377. package/dist/wallet-link/WalletLinkShim.js.map +1 -0
  378. package/package.json +50 -0
@@ -0,0 +1,1260 @@
1
+ import { EntitlementModuleType, isPermission, isUpdateChannelStatusParams, Permission, } from '../types/ContractTypes';
2
+ import { computeDelegatorsForProvider } from '../delegate-registry/DelegateRegistry';
3
+ import { ethers } from 'ethers';
4
+ import { LOCALHOST_CHAIN_ID } from '../utils/Web3Constants';
5
+ import { EVERYONE_ADDRESS, stringifyChannelMetadataJSON, NoEntitledWalletError, ETH_ADDRESS, } from '../utils/ut';
6
+ import { SpaceRegistrar } from '../space-registrar/SpaceRegistrar';
7
+ import { evaluateOperationsForEntitledWallet, ruleDataToOperations, findEthereumProviders, } from '../space/entitlements/entitlement';
8
+ import { createEntitlementStruct, createLegacyEntitlementStruct, convertRuleDataV1ToV2, } from '../space/entitlements/ConvertersEntitlements';
9
+ import { RiverAirdropDapp } from '../airdrop/RiverAirdropDapp';
10
+ import { WalletLink, INVALID_ADDRESS } from '../wallet-link/WalletLink';
11
+ import { UNKNOWN_ERROR } from '../BaseContractShim';
12
+ import { PricingModules } from '../pricing-modules/PricingModules';
13
+ import { dlogger, isTestEnv } from '@towns-labs/utils';
14
+ import { PlatformRequirements } from '../platform-requirements/PlatformRequirements';
15
+ import { EntitlementCache } from '../cache/EntitlementCache';
16
+ import { SimpleCache } from '../cache/SimpleCache';
17
+ import { ITippingShim } from '../space/ITippingShim';
18
+ import { SpaceOwner } from '../space-owner/SpaceOwner';
19
+ import { TownsToken } from '../towns-token/TownsToken';
20
+ import { wrapTransaction } from '../space-dapp/wrapTransaction';
21
+ import { BaseRegistry } from '../base-registry/BaseRegistry';
22
+ import { Keyable } from '../cache/Keyable';
23
+ const logger = dlogger('csb:SpaceDapp:debug');
24
+ class EntitlementDataCacheResult {
25
+ value;
26
+ cacheHit;
27
+ isPositive;
28
+ constructor(value) {
29
+ this.value = value;
30
+ this.cacheHit = false;
31
+ this.isPositive = true;
32
+ }
33
+ }
34
+ class EntitledWalletCacheResult {
35
+ value;
36
+ cacheHit;
37
+ isPositive;
38
+ constructor(value) {
39
+ this.value = value;
40
+ this.cacheHit = false;
41
+ this.isPositive = value !== undefined;
42
+ }
43
+ }
44
+ class BooleanCacheResult {
45
+ value;
46
+ cacheHit;
47
+ isPositive;
48
+ constructor(value) {
49
+ this.value = value;
50
+ this.cacheHit = false;
51
+ this.isPositive = value;
52
+ }
53
+ }
54
+ function ensureHexPrefix(value) {
55
+ return value.startsWith('0x') ? value : `0x${value}`;
56
+ }
57
+ const EmptyXchainConfig = {
58
+ supportedRpcUrls: {},
59
+ etherNativeNetworkIds: [],
60
+ ethereumNetworkIds: [],
61
+ };
62
+ export class SpaceDapp {
63
+ isLegacySpaceCache;
64
+ config;
65
+ baseRegistry;
66
+ provider;
67
+ spaceRegistrar;
68
+ pricingModules;
69
+ walletLink;
70
+ platformRequirements;
71
+ airdrop;
72
+ spaceOwner;
73
+ townsToken;
74
+ entitlementCache;
75
+ entitledWalletCache;
76
+ entitlementEvaluationCache;
77
+ bannedTokenIdsCache;
78
+ ownerOfTokenCache;
79
+ isBannedTokenCache;
80
+ constructor(config, provider, createStorageFn) {
81
+ this.isLegacySpaceCache = new Map();
82
+ this.config = config;
83
+ this.provider = provider;
84
+ this.baseRegistry = new BaseRegistry(config, provider);
85
+ this.spaceRegistrar = new SpaceRegistrar(config, provider, createStorageFn);
86
+ this.walletLink = new WalletLink(config, provider);
87
+ this.pricingModules = new PricingModules(config, provider);
88
+ this.platformRequirements = new PlatformRequirements(config.addresses.spaceFactory, provider);
89
+ this.spaceOwner = new SpaceOwner(config.addresses.spaceOwner, provider, createStorageFn);
90
+ if (config.addresses.utils.towns) {
91
+ this.townsToken = new TownsToken(config.addresses.utils.towns, provider, createStorageFn);
92
+ }
93
+ this.airdrop = new RiverAirdropDapp(config, provider);
94
+ // For RPC providers that pool for events, we need to set the polling interval to a lower value
95
+ // so that we don't miss events that may be emitted in between polling intervals. The Ethers
96
+ // default is 4000ms, which is based on the assumption of 12s mainnet blocktimes.
97
+ if ('pollingInterval' in provider && typeof provider.pollingInterval === 'number') {
98
+ provider.pollingInterval = 250;
99
+ }
100
+ const isLocalDev = isTestEnv() || config.chainId === LOCALHOST_CHAIN_ID;
101
+ const entitlementCacheOpts = {
102
+ positiveCacheTTLSeconds: isLocalDev ? 5 : 15 * 60,
103
+ negativeCacheTTLSeconds: 2,
104
+ createStorageFn,
105
+ };
106
+ const bannedCacheOpts = {
107
+ ttlSeconds: isLocalDev ? 5 : 15 * 60,
108
+ createStorageFn,
109
+ };
110
+ // The caching of positive entitlements is shorter on both the node and client.
111
+ this.entitlementCache = new EntitlementCache({
112
+ positiveCacheTTLSeconds: isLocalDev ? 5 : 15,
113
+ negativeCacheTTLSeconds: 2,
114
+ createStorageFn,
115
+ });
116
+ this.entitledWalletCache = new EntitlementCache({
117
+ ...entitlementCacheOpts,
118
+ });
119
+ this.entitlementEvaluationCache = new EntitlementCache({
120
+ ...entitlementCacheOpts,
121
+ });
122
+ this.bannedTokenIdsCache = new SimpleCache({
123
+ ...bannedCacheOpts,
124
+ });
125
+ this.ownerOfTokenCache = new SimpleCache({
126
+ ...bannedCacheOpts,
127
+ });
128
+ this.isBannedTokenCache = new SimpleCache({
129
+ ...bannedCacheOpts,
130
+ });
131
+ }
132
+ async isLegacySpace(spaceId) {
133
+ const cachedValue = this.isLegacySpaceCache.get(spaceId);
134
+ if (cachedValue !== undefined) {
135
+ return cachedValue;
136
+ }
137
+ const space = this.getSpace(spaceId);
138
+ if (!space) {
139
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
140
+ }
141
+ // Legacy spaces do not have RuleEntitlementV2
142
+ const maybeShim = await space.findEntitlementByType(EntitlementModuleType.RuleEntitlementV2);
143
+ const isLegacy = maybeShim === null;
144
+ this.isLegacySpaceCache.set(spaceId, isLegacy);
145
+ return isLegacy;
146
+ }
147
+ async addRoleToChannel(spaceId, channelNetworkId, roleId, signer, txnOpts) {
148
+ const space = this.getSpace(spaceId);
149
+ if (!space) {
150
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
151
+ }
152
+ const channelId = ensureHexPrefix(channelNetworkId);
153
+ return wrapTransaction(() => space.Channels.write(signer).addRoleToChannel(channelId, roleId), txnOpts);
154
+ }
155
+ async banWalletAddress(spaceId, walletAddress, signer, txnOpts) {
156
+ const space = this.getSpace(spaceId);
157
+ if (!space) {
158
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
159
+ }
160
+ const token = await space.ERC721AQueryable.read
161
+ .tokensOfOwner(walletAddress)
162
+ .then((tokens) => tokens.at(0));
163
+ if (!token) {
164
+ throw new Error(`Wallet address "${walletAddress}" is not a member of space "${spaceId}".`);
165
+ }
166
+ // Call ban
167
+ const tx = await wrapTransaction(() => space.Banning.write(signer).ban(token), txnOpts);
168
+ await this.updateCacheAfterBanOrUnBan(spaceId, token);
169
+ return tx;
170
+ }
171
+ async unbanWalletAddress(spaceId, walletAddress, signer, txnOpts) {
172
+ const space = this.getSpace(spaceId);
173
+ if (!space) {
174
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
175
+ }
176
+ const token = await space.ERC721AQueryable.read
177
+ .tokensOfOwner(walletAddress)
178
+ .then((tokens) => tokens.at(0));
179
+ if (!token) {
180
+ throw new Error(`Wallet address "${walletAddress}" is not a member of space "${spaceId}".`);
181
+ }
182
+ // Call unban
183
+ const tx = await wrapTransaction(() => space.Banning.write(signer).unban(token), txnOpts);
184
+ await this.updateCacheAfterBanOrUnBan(spaceId, token);
185
+ return tx;
186
+ }
187
+ async updateCacheAfterBanOrUnBan(spaceId, tokenId) {
188
+ await Promise.all([
189
+ this.bannedTokenIdsCache.remove(Keyable.bannedTokenIds(spaceId)),
190
+ this.ownerOfTokenCache.remove(Keyable.ownerOfToken(spaceId, tokenId)),
191
+ this.isBannedTokenCache.remove(Keyable.isTokenBanned(spaceId, tokenId)),
192
+ ]);
193
+ }
194
+ async walletAddressIsBanned(spaceId, walletAddress, opts) {
195
+ const space = this.getSpace(spaceId);
196
+ if (!space) {
197
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
198
+ }
199
+ const tokenId = await space.ERC721AQueryable.read
200
+ .tokensOfOwner(walletAddress)
201
+ .then((tokens) => tokens.at(0));
202
+ if (!tokenId) {
203
+ return false;
204
+ }
205
+ const isBanned = await this.isBannedTokenCache.executeUsingCache(Keyable.isTokenBanned(spaceId, tokenId), async () => space.Banning.read.isBanned(tokenId), opts);
206
+ return isBanned;
207
+ }
208
+ async bannedWalletAddresses(spaceId) {
209
+ const space = this.getSpace(spaceId);
210
+ if (!space) {
211
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
212
+ }
213
+ // 1. Get banned token IDs
214
+ const bannedTokenIds = await this.bannedTokenIdsCache.executeUsingCache(Keyable.bannedTokenIds(spaceId), async () => {
215
+ const currentSpace = this.getSpace(spaceId);
216
+ if (!currentSpace) {
217
+ throw new Error(`Space with spaceId "${spaceId}" is not found inside cache fetch.`);
218
+ }
219
+ return currentSpace.Banning.read.banned();
220
+ });
221
+ // 2. Get owner for each banned token ID using cache and multicall for efficiency
222
+ const ownerMap = new Map(); // tokenId.toString() -> ownerAddress
223
+ const tokenIdsToFetch = [];
224
+ // Check cache first - parallel lookups for remote storage efficiency
225
+ const cacheResults = await Promise.all(bannedTokenIds.map(async (tokenId) => {
226
+ const cacheKey = Keyable.ownerOfToken(spaceId, tokenId);
227
+ const cachedOwner = await this.ownerOfTokenCache.get(cacheKey);
228
+ return { tokenId, cachedOwner };
229
+ }));
230
+ for (const { tokenId, cachedOwner } of cacheResults) {
231
+ if (cachedOwner) {
232
+ ownerMap.set(tokenId.toString(), cachedOwner);
233
+ }
234
+ else {
235
+ tokenIdsToFetch.push(tokenId);
236
+ }
237
+ }
238
+ // Fetch non-cached owners
239
+ if (tokenIdsToFetch.length > 0 && space) {
240
+ const calls = tokenIdsToFetch.map((tokenId) => space.ERC721A.interface.encodeFunctionData('ownerOf', [tokenId]));
241
+ try {
242
+ const results = await space.Multicall.read.callStatic.multicall(calls);
243
+ const cacheWritePromises = [];
244
+ for (const [index, resultData] of results.entries()) {
245
+ const tokenId = tokenIdsToFetch[index];
246
+ // Attempt to decode each result
247
+ try {
248
+ if (resultData && resultData !== '0x') {
249
+ const ownerAddress = space.ERC721A.interface.decodeFunctionResult('ownerOf', resultData)[0];
250
+ if (ethers.utils.isAddress(ownerAddress)) {
251
+ ownerMap.set(tokenId.toString(), ownerAddress);
252
+ // Collect cache write promises for parallel execution
253
+ cacheWritePromises.push(this.ownerOfTokenCache.add(Keyable.ownerOfToken(spaceId, tokenId), ownerAddress));
254
+ }
255
+ else {
256
+ logger.log(`bannedWalletAddresses: Multicall: Decoded ownerOf result is not a valid address for token ${tokenId.toString()} in space ${spaceId}: ${ownerAddress}`);
257
+ }
258
+ }
259
+ else {
260
+ logger.log(`bannedWalletAddresses: Multicall: ownerOf call returned empty data for token ${tokenId.toString()} in space ${spaceId}`);
261
+ }
262
+ }
263
+ catch (decodeError) {
264
+ logger.error(`bannedWalletAddresses: Multicall: Failed to decode ownerOf result for token ${tokenId.toString()} in space ${spaceId}`, decodeError instanceof Error
265
+ ? decodeError.message
266
+ : String(decodeError));
267
+ }
268
+ }
269
+ // Write all cache entries in parallel
270
+ await Promise.all(cacheWritePromises);
271
+ }
272
+ catch (multiCallError) {
273
+ logger.error(`Multicall execution failed for space ${spaceId}. This likely means one of the ownerOf calls reverted.`, multiCallError instanceof Error
274
+ ? multiCallError.message
275
+ : String(multiCallError));
276
+ }
277
+ }
278
+ // Return the unique owner addresses combined from cache and multicall
279
+ return Array.from(new Set(ownerMap.values()));
280
+ }
281
+ async createLegacySpace(params, signer, txnOpts) {
282
+ const spaceInfo = {
283
+ name: params.spaceName,
284
+ uri: params.uri,
285
+ membership: params.membership,
286
+ channel: {
287
+ metadata: params.channelName || '',
288
+ },
289
+ shortDescription: params.shortDescription ?? '',
290
+ longDescription: params.longDescription ?? '',
291
+ };
292
+ return wrapTransaction(() => this.spaceRegistrar.LegacySpaceArchitect.write(signer).createSpace(spaceInfo), txnOpts);
293
+ }
294
+ async createSpace(params, signer, txnOpts) {
295
+ return wrapTransaction(() => {
296
+ const createSpaceFunction = this.spaceRegistrar.CreateSpace.write(signer)['createSpace((string,string,string,string,((string,string,uint256,uint256,uint64,address,address,uint256,address),(bool,address[],bytes,bool),string[]),(string)))'];
297
+ return createSpaceFunction({
298
+ name: params.spaceName,
299
+ uri: params.uri,
300
+ shortDescription: params.shortDescription || '',
301
+ longDescription: params.longDescription || '',
302
+ membership: params.membership,
303
+ channel: {
304
+ metadata: params.channelName || '',
305
+ },
306
+ });
307
+ }, txnOpts);
308
+ }
309
+ async createChannel(spaceId, channelName, channelDescription, channelNetworkId, roleIds, signer, txnOpts) {
310
+ const space = this.getSpace(spaceId);
311
+ if (!space) {
312
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
313
+ }
314
+ const channelId = ensureHexPrefix(channelNetworkId);
315
+ return wrapTransaction(() => space.Channels.write(signer).createChannel(channelId, stringifyChannelMetadataJSON({
316
+ name: channelName,
317
+ description: channelDescription,
318
+ }), roleIds), txnOpts);
319
+ }
320
+ async createChannelWithPermissionOverrides(spaceId, channelName, channelDescription, channelNetworkId, roles, signer, txnOpts) {
321
+ const space = this.getSpace(spaceId);
322
+ if (!space) {
323
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
324
+ }
325
+ const channelId = ensureHexPrefix(channelNetworkId);
326
+ return wrapTransaction(() => space.Channels.write(signer).createChannelWithOverridePermissions(channelId, stringifyChannelMetadataJSON({
327
+ name: channelName,
328
+ description: channelDescription,
329
+ }), roles), txnOpts);
330
+ }
331
+ async legacyCreateRole(spaceId, roleName, permissions, users, ruleData, signer, txnOpts) {
332
+ const space = this.getSpace(spaceId);
333
+ if (!space) {
334
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
335
+ }
336
+ const entitlements = await createLegacyEntitlementStruct(space, users, ruleData);
337
+ return wrapTransaction(() => space.Roles.write(signer).createRole(roleName, permissions, entitlements), txnOpts);
338
+ }
339
+ async createRole(spaceId, roleName, permissions, users, ruleData, signer, txnOpts) {
340
+ const space = this.getSpace(spaceId);
341
+ if (!space) {
342
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
343
+ }
344
+ const entitlements = await createEntitlementStruct(space, users, ruleData);
345
+ return wrapTransaction(() => space.Roles.write(signer).createRole(roleName, permissions, entitlements), txnOpts);
346
+ }
347
+ async deleteRole(spaceId, roleId, signer, txnOpts) {
348
+ const space = this.getSpace(spaceId);
349
+ if (!space) {
350
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
351
+ }
352
+ return wrapTransaction(() => space.Roles.write(signer).removeRole(roleId), txnOpts);
353
+ }
354
+ async getChannels(spaceId) {
355
+ const space = this.getSpace(spaceId);
356
+ if (!space) {
357
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
358
+ }
359
+ return space.getChannels();
360
+ }
361
+ async getChannelDetails(spaceId, channelNetworkId) {
362
+ const space = this.getSpace(spaceId);
363
+ if (!space) {
364
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
365
+ }
366
+ const channelId = ensureHexPrefix(channelNetworkId);
367
+ return space.getChannel(channelId);
368
+ }
369
+ async getPermissionsByRoleId(spaceId, roleId) {
370
+ const space = this.getSpace(spaceId);
371
+ if (!space) {
372
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
373
+ }
374
+ return space.getPermissionsByRoleId(roleId);
375
+ }
376
+ async getRole(spaceId, roleId) {
377
+ const space = this.getSpace(spaceId);
378
+ if (!space) {
379
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
380
+ }
381
+ return space.getRole(roleId);
382
+ }
383
+ async getRoles(spaceId) {
384
+ const space = this.getSpace(spaceId);
385
+ if (!space) {
386
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
387
+ }
388
+ const roles = await space.Roles.read.getRoles();
389
+ return roles.map((role) => ({
390
+ roleId: role.id.toNumber(),
391
+ name: role.name,
392
+ }));
393
+ }
394
+ async getSpaceInfo(spaceId) {
395
+ const space = this.getSpace(spaceId);
396
+ if (!space) {
397
+ return undefined;
398
+ }
399
+ const [owner, disabled, spaceInfo] = await Promise.all([
400
+ space.Ownable.getOwner(),
401
+ space.Pausable.read.paused(),
402
+ this.spaceOwner.getSpaceInfo(space.Address),
403
+ ]);
404
+ return {
405
+ address: space.Address,
406
+ networkId: space.SpaceId,
407
+ name: spaceInfo.name ?? '',
408
+ owner,
409
+ disabled,
410
+ uri: spaceInfo.uri ?? '',
411
+ tokenId: ethers.BigNumber.from(spaceInfo.tokenId).toString(),
412
+ createdAt: ethers.BigNumber.from(spaceInfo.createdAt).toString(),
413
+ shortDescription: spaceInfo.shortDescription ?? '',
414
+ longDescription: spaceInfo.longDescription ?? '',
415
+ };
416
+ }
417
+ async decodeEntitlementData(space, entitlementData) {
418
+ const entitlements = entitlementData.map((x) => ({
419
+ entitlementType: x.entitlementType,
420
+ ruleEntitlement: undefined,
421
+ userEntitlement: undefined,
422
+ }));
423
+ const [userEntitlementShim, ruleEntitlementShim, ruleEntitlementV2Shim] = (await Promise.all([
424
+ space.findEntitlementByType(EntitlementModuleType.UserEntitlement),
425
+ space.findEntitlementByType(EntitlementModuleType.RuleEntitlement),
426
+ space.findEntitlementByType(EntitlementModuleType.RuleEntitlementV2),
427
+ ]));
428
+ for (let i = 0; i < entitlementData.length; i++) {
429
+ const entitlement = entitlementData[i];
430
+ if (entitlement.entitlementType ===
431
+ EntitlementModuleType.RuleEntitlement) {
432
+ if (ruleEntitlementShim)
433
+ entitlements[i].entitlementType = EntitlementModuleType.RuleEntitlement;
434
+ const decodedData = ruleEntitlementShim?.decodeGetRuleData(entitlement.entitlementData);
435
+ if (decodedData) {
436
+ entitlements[i].ruleEntitlement = {
437
+ kind: 'v1',
438
+ rules: decodedData,
439
+ };
440
+ }
441
+ }
442
+ else if (entitlement.entitlementType ===
443
+ EntitlementModuleType.RuleEntitlementV2) {
444
+ entitlements[i].entitlementType = EntitlementModuleType.RuleEntitlementV2;
445
+ const decodedData = ruleEntitlementV2Shim?.decodeGetRuleData(entitlement.entitlementData);
446
+ if (decodedData) {
447
+ entitlements[i].ruleEntitlement = {
448
+ kind: 'v2',
449
+ rules: decodedData,
450
+ };
451
+ }
452
+ }
453
+ else if (entitlement.entitlementType ===
454
+ EntitlementModuleType.UserEntitlement) {
455
+ entitlements[i].entitlementType = EntitlementModuleType.UserEntitlement;
456
+ const decodedData = userEntitlementShim?.decodeGetAddresses(entitlement.entitlementData);
457
+ if (decodedData) {
458
+ entitlements[i].userEntitlement = decodedData;
459
+ }
460
+ }
461
+ else {
462
+ throw new Error('Unknown entitlement type');
463
+ }
464
+ }
465
+ return entitlements;
466
+ }
467
+ async getEntitlementsForPermission(spaceId, permission) {
468
+ const { value } = await this.entitlementCache.executeUsingCache(Keyable.spaceEntitlement(spaceId, permission), async () => {
469
+ const entitlementData = await this.getEntitlementsForPermissionUncached(spaceId, permission);
470
+ return new EntitlementDataCacheResult(entitlementData);
471
+ });
472
+ return value;
473
+ }
474
+ async getEntitlementsForPermissionUncached(spaceId, permission) {
475
+ const space = this.getSpace(spaceId);
476
+ if (!space) {
477
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
478
+ }
479
+ const entitlementData = await space.EntitlementDataQueryable.read.getEntitlementDataByPermission(permission);
480
+ return await this.decodeEntitlementData(space, entitlementData);
481
+ }
482
+ async getChannelEntitlementsForPermission(spaceId, channelId, permission) {
483
+ const { value } = await this.entitlementCache.executeUsingCache(Keyable.channelEntitlement(spaceId, channelId, permission), async () => {
484
+ const entitlementData = await this.getChannelEntitlementsForPermissionUncached(spaceId, channelId, permission);
485
+ return new EntitlementDataCacheResult(entitlementData);
486
+ });
487
+ return value;
488
+ }
489
+ async getChannelEntitlementsForPermissionUncached(spaceId, channelId, permission) {
490
+ const space = this.getSpace(spaceId);
491
+ if (!space) {
492
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
493
+ }
494
+ const entitlementData = await space.EntitlementDataQueryable.read.getChannelEntitlementDataByPermission(channelId, permission);
495
+ return await this.decodeEntitlementData(space, entitlementData);
496
+ }
497
+ async getLinkedWallets(wallet) {
498
+ let linkedWallets = await this.walletLink.getLinkedWallets(wallet);
499
+ // If there are no linked wallets, consider that the wallet may be linked to another root key.
500
+ if (linkedWallets.length === 0) {
501
+ const possibleRoot = await this.walletLink.getRootKeyForWallet(wallet);
502
+ if (possibleRoot !== INVALID_ADDRESS) {
503
+ linkedWallets = await this.walletLink.getLinkedWallets(possibleRoot);
504
+ return [possibleRoot, ...linkedWallets];
505
+ }
506
+ }
507
+ return [wallet, ...linkedWallets];
508
+ }
509
+ async getMainnetDelegationsForLinkedWallets(linkedWallets, config) {
510
+ const delegatorSet = new Set();
511
+ const ethProviders = await findEthereumProviders(config);
512
+ for (const provider of ethProviders) {
513
+ const delegators = await computeDelegatorsForProvider(provider, linkedWallets);
514
+ for (const delegator of delegators) {
515
+ delegatorSet.add(delegator);
516
+ }
517
+ }
518
+ return delegatorSet;
519
+ }
520
+ async getLinkedWalletsWithDelegations(wallet, config) {
521
+ const linkedWallets = await this.getLinkedWallets(wallet);
522
+ const allWallets = new Set(linkedWallets);
523
+ const delegators = await this.getMainnetDelegationsForLinkedWallets(linkedWallets, config);
524
+ return [...new Set([...allWallets, ...delegators])];
525
+ }
526
+ async evaluateEntitledWallet(space, rootKey, allWallets, entitlements, xchainConfig) {
527
+ const { isExpired } = await space.getMembershipStatus(allWallets);
528
+ // otherwise you're trying to do something with an expired membership
529
+ if (isExpired) {
530
+ return;
531
+ }
532
+ const isEveryOneSpace = entitlements.some((e) => e.userEntitlement?.includes(EVERYONE_ADDRESS));
533
+ if (isEveryOneSpace) {
534
+ return rootKey;
535
+ }
536
+ // Evaluate all user entitlements first, as they do not require external calls.
537
+ for (const entitlement of entitlements) {
538
+ for (const user of allWallets) {
539
+ if (entitlement.userEntitlement?.includes(user)) {
540
+ return user;
541
+ }
542
+ }
543
+ }
544
+ // Accumulate all RuleDataV1 entitlements and convert to V2s.
545
+ const ruleEntitlements = entitlements
546
+ .filter((x) => x.entitlementType === EntitlementModuleType.RuleEntitlement &&
547
+ x.ruleEntitlement?.kind == 'v1')
548
+ .map((x) => convertRuleDataV1ToV2(x.ruleEntitlement.rules));
549
+ // Add all RuleDataV2 entitlements.
550
+ ruleEntitlements.push(...entitlements
551
+ .filter((x) => x.entitlementType === EntitlementModuleType.RuleEntitlementV2 &&
552
+ x.ruleEntitlement?.kind == 'v2')
553
+ .map((x) => x.ruleEntitlement.rules));
554
+ return await Promise.any(ruleEntitlements.map(async (ruleData) => {
555
+ if (!ruleData) {
556
+ throw new Error('Rule data not found');
557
+ }
558
+ const operations = ruleDataToOperations(ruleData);
559
+ const result = await evaluateOperationsForEntitledWallet(operations, allWallets, xchainConfig);
560
+ if (result !== ethers.constants.AddressZero) {
561
+ return result;
562
+ }
563
+ // This is not a true error, but is used here so that the Promise.any will not
564
+ // resolve with an unentitled wallet.
565
+ throw new NoEntitledWalletError();
566
+ })).catch(NoEntitledWalletError.throwIfRuntimeErrors);
567
+ }
568
+ /**
569
+ * Checks if user has a wallet entitled to join a space based on the minter role rule entitlements
570
+ */
571
+ async getEntitledWalletForJoiningSpace(spaceId, rootKey, xchainConfig, skipCache = false) {
572
+ const key = Keyable.spaceEntitlementEvaluation(spaceId, rootKey, Permission.JoinSpace);
573
+ const { value } = await this.entitledWalletCache.executeUsingCache(key, async () => {
574
+ const entitledWallet = await this.getEntitledWalletForJoiningSpaceUncached(spaceId, rootKey, xchainConfig);
575
+ return new EntitledWalletCacheResult(entitledWallet);
576
+ }, { skipCache });
577
+ return value;
578
+ }
579
+ async getEntitledWalletForJoiningSpaceUncached(spaceId, rootKey, xchainConfig) {
580
+ const allWallets = await this.getLinkedWalletsWithDelegations(rootKey, xchainConfig);
581
+ const space = this.getSpace(spaceId);
582
+ if (!space) {
583
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
584
+ }
585
+ const owner = await space.Ownable.getOwner();
586
+ // Space owner is entitled to all channels
587
+ if (allWallets.includes(owner)) {
588
+ return owner;
589
+ }
590
+ const promises = allWallets.map(async (wallet) => this.walletAddressIsBanned(spaceId, wallet).then((r) => r === true ? true : Promise.reject(new Error('Wallet is not banned'))));
591
+ try {
592
+ // If any promise resolves (meaning a wallet IS banned), this succeeds.
593
+ await Promise.any(promises);
594
+ return;
595
+ }
596
+ catch (error) {
597
+ // all promises rejected, meaning no wallets are banned
598
+ }
599
+ const entitlements = await this.getEntitlementsForPermission(spaceId, Permission.JoinSpace);
600
+ return await this.evaluateEntitledWallet(space, rootKey, allWallets, entitlements, xchainConfig);
601
+ }
602
+ async isEntitledToSpace(spaceId, userId, permission, skipCache = false) {
603
+ const key = Keyable.spaceEntitlementEvaluation(spaceId, userId, permission);
604
+ const { value } = await this.entitlementEvaluationCache.executeUsingCache(key, async () => {
605
+ const isEntitled = await this.isEntitledToSpaceUncached(spaceId, userId, permission);
606
+ return new BooleanCacheResult(isEntitled);
607
+ }, { skipCache });
608
+ return value;
609
+ }
610
+ async isAppInstalled(spaceId, botAppAddress) {
611
+ const space = this.getSpace(spaceId);
612
+ if (!space) {
613
+ return false;
614
+ }
615
+ return space.AppAccount.read.isAppInstalled(botAppAddress);
616
+ }
617
+ async isAppEntitled(spaceId, botId, botAppAddress, permission) {
618
+ const space = this.getSpace(spaceId);
619
+ if (!space) {
620
+ return false;
621
+ }
622
+ const permissionBytes = ethers.utils.formatBytes32String(permission);
623
+ return space.AppAccount.read.isAppEntitled(botAppAddress, botId, permissionBytes);
624
+ }
625
+ async isEntitledToSpaceUncached(spaceId, user, permission) {
626
+ const space = this.getSpace(spaceId);
627
+ if (!space) {
628
+ return false;
629
+ }
630
+ if (permission === Permission.JoinSpace) {
631
+ throw new Error('use getEntitledWalletForJoiningSpace instead of isEntitledToSpace');
632
+ }
633
+ return space.Entitlements.read.isEntitledToSpace(user, permission);
634
+ }
635
+ async isEntitledToChannel(spaceId, channelNetworkId, userId, permission, xchainConfig = EmptyXchainConfig, skipCache = false) {
636
+ const key = Keyable.channelEntitlementEvaluation(spaceId, channelNetworkId, userId, permission);
637
+ const { value } = await this.entitlementEvaluationCache.executeUsingCache(key, async () => {
638
+ const isEntitled = await this.isEntitledToChannelUncached(spaceId, channelNetworkId, userId, permission, xchainConfig);
639
+ return new BooleanCacheResult(isEntitled);
640
+ }, { skipCache });
641
+ return value;
642
+ }
643
+ async isEntitledToChannelUncached(spaceId, channelNetworkId, user, permission, xchainConfig) {
644
+ const space = this.getSpace(spaceId);
645
+ if (!space) {
646
+ return false;
647
+ }
648
+ const channelId = ensureHexPrefix(channelNetworkId);
649
+ const linkedWallets = await this.getLinkedWalletsWithDelegations(user, xchainConfig);
650
+ const owner = await space.Ownable.getOwner();
651
+ // Space owner is entitled to all channels
652
+ if (linkedWallets.includes(owner)) {
653
+ return true;
654
+ }
655
+ const promises = linkedWallets.map(async (wallet) => this.walletAddressIsBanned(spaceId, wallet).then((r) => r === true ? true : Promise.reject(new Error('Wallet is not banned'))));
656
+ try {
657
+ // If any promise resolves (meaning a wallet IS banned), this succeeds.
658
+ await Promise.any(promises);
659
+ return false;
660
+ }
661
+ catch (error) {
662
+ // all promises rejected, meaning no wallets are banned
663
+ }
664
+ const entitlements = await this.getChannelEntitlementsForPermission(spaceId, channelId, permission);
665
+ const entitledWallet = await this.evaluateEntitledWallet(space, user, linkedWallets, entitlements, xchainConfig);
666
+ return entitledWallet !== undefined;
667
+ }
668
+ parseSpaceFactoryError(error) {
669
+ if (!this.spaceRegistrar.SpaceArchitect) {
670
+ throw new Error('SpaceArchitect is not deployed properly.');
671
+ }
672
+ const decodedErr = this.spaceRegistrar.SpaceArchitect.parseError(error);
673
+ logger.error(decodedErr);
674
+ return decodedErr;
675
+ }
676
+ parseSpaceOwnerError(error) {
677
+ if (!this.spaceOwner) {
678
+ throw new Error('SpaceOwner is not deployed properly.');
679
+ }
680
+ const decodedErr = this.spaceOwner.parseError(error);
681
+ logger.error(decodedErr);
682
+ return decodedErr;
683
+ }
684
+ parseSpaceError(spaceId, error) {
685
+ const space = this.getSpace(spaceId);
686
+ if (!space) {
687
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
688
+ }
689
+ const decodedErr = space.parseError(error);
690
+ logger.error(decodedErr);
691
+ return decodedErr;
692
+ }
693
+ /**
694
+ * Attempts to parse an error against all contracts
695
+ * If you're error is not showing any data with this call, make sure the contract is listed either in parseSpaceError or nonSpaceContracts
696
+ * @param args
697
+ * @returns
698
+ */
699
+ parseAllContractErrors(args) {
700
+ let err;
701
+ if (args.spaceId) {
702
+ err = this.parseSpaceError(args.spaceId, args.error);
703
+ }
704
+ if (err && err?.name !== UNKNOWN_ERROR) {
705
+ return err;
706
+ }
707
+ err = this.spaceRegistrar.SpaceArchitect.parseError(args.error);
708
+ if (err?.name !== UNKNOWN_ERROR) {
709
+ return err;
710
+ }
711
+ const nonSpaceContracts = [this.airdrop.riverPoints, this.pricingModules, this.walletLink];
712
+ for (const contract of nonSpaceContracts) {
713
+ if (!contract) {
714
+ continue;
715
+ }
716
+ err = contract.parseError(args.error);
717
+ if (err?.name !== UNKNOWN_ERROR) {
718
+ return err;
719
+ }
720
+ }
721
+ return err;
722
+ }
723
+ async parseSpaceLogs(spaceId, logs) {
724
+ const space = this.getSpace(spaceId);
725
+ if (!space) {
726
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
727
+ }
728
+ return logs.map((spaceLog) => {
729
+ try {
730
+ return space.parseLog(spaceLog);
731
+ }
732
+ catch (err) {
733
+ logger.error(err);
734
+ return;
735
+ }
736
+ });
737
+ }
738
+ async updateChannel(params, signer, txnOpts) {
739
+ const space = this.getSpace(params.spaceId);
740
+ if (!space) {
741
+ throw new Error(`Space with spaceId "${params.spaceId}" is not found.`);
742
+ }
743
+ const encodedCallData = await this.encodedUpdateChannelData(space, params);
744
+ return wrapTransaction(() => space.Multicall.write(signer).multicall(encodedCallData), txnOpts);
745
+ }
746
+ async encodedUpdateChannelData(space, params) {
747
+ const channelId = ensureHexPrefix(params.channelId);
748
+ if (isUpdateChannelStatusParams(params)) {
749
+ // When enabling or disabling channels, passing names and roles is not required.
750
+ // To ensure the contract accepts this exception, the metadata argument should be left empty.
751
+ return [
752
+ space.Channels.interface.encodeFunctionData('updateChannel', [channelId, '', true]),
753
+ ];
754
+ }
755
+ // data for the multicall
756
+ const encodedCallData = [];
757
+ // update the channel metadata
758
+ encodedCallData.push(space.Channels.interface.encodeFunctionData('updateChannel', [
759
+ channelId,
760
+ stringifyChannelMetadataJSON({
761
+ name: params.channelName,
762
+ description: params.channelDescription,
763
+ }),
764
+ params.disabled ?? false, // default to false
765
+ ]));
766
+ // update any channel role changes
767
+ const encodedUpdateChannelRoles = await this.encodeUpdateChannelRoles(space, params.channelId, params.roleIds);
768
+ for (const callData of encodedUpdateChannelRoles) {
769
+ encodedCallData.push(callData);
770
+ }
771
+ return encodedCallData;
772
+ }
773
+ async removeChannel(params, signer, txnOpts) {
774
+ const space = this.getSpace(params.spaceId);
775
+ if (!space) {
776
+ throw new Error(`Space with spaceId "${params.spaceId}" is not found.`);
777
+ }
778
+ return wrapTransaction(() => space.Channels.write(signer).removeChannel(params.channelId), txnOpts);
779
+ }
780
+ async legacyUpdateRole(params, signer, txnOpts) {
781
+ const space = this.getSpace(params.spaceNetworkId);
782
+ if (!space) {
783
+ throw new Error(`Space with spaceId "${params.spaceNetworkId}" is not found.`);
784
+ }
785
+ const updatedEntitlemets = await this.createLegacyUpdatedEntitlements(space, params);
786
+ return wrapTransaction(() => space.Roles.write(signer).updateRole(params.roleId, params.roleName, params.permissions, updatedEntitlemets), txnOpts);
787
+ }
788
+ async updateRole(params, signer, txnOpts) {
789
+ const space = this.getSpace(params.spaceNetworkId);
790
+ if (!space) {
791
+ throw new Error(`Space with spaceId "${params.spaceNetworkId}" is not found.`);
792
+ }
793
+ const updatedEntitlemets = await this.createUpdatedEntitlements(space, params);
794
+ return wrapTransaction(() => space.Roles.write(signer).updateRole(params.roleId, params.roleName, params.permissions, updatedEntitlemets), txnOpts);
795
+ }
796
+ async getChannelPermissionOverrides(spaceId, roleId, channelNetworkId) {
797
+ const space = this.getSpace(spaceId);
798
+ if (!space) {
799
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
800
+ }
801
+ const channelId = ensureHexPrefix(channelNetworkId);
802
+ return (await space.Roles.read.getChannelPermissionOverrides(roleId, channelId)).filter(isPermission);
803
+ }
804
+ async setChannelPermissionOverrides(params, signer, txnOpts) {
805
+ const space = this.getSpace(params.spaceNetworkId);
806
+ if (!space) {
807
+ throw new Error(`Space with spaceId "${params.spaceNetworkId}" is not found.`);
808
+ }
809
+ const channelId = ensureHexPrefix(params.channelId);
810
+ return wrapTransaction(() => space.Roles.write(signer).setChannelPermissionOverrides(params.roleId, channelId, params.permissions), txnOpts);
811
+ }
812
+ async clearChannelPermissionOverrides(params, signer, txnOpts) {
813
+ const space = this.getSpace(params.spaceNetworkId);
814
+ if (!space) {
815
+ throw new Error(`Space with spaceId "${params.spaceNetworkId}" is not found.`);
816
+ }
817
+ const channelId = ensureHexPrefix(params.channelId);
818
+ return wrapTransaction(() => space.Roles.write(signer).clearChannelPermissionOverrides(params.roleId, channelId), txnOpts);
819
+ }
820
+ async setSpaceAccess(spaceId, disabled, signer, txnOpts) {
821
+ const space = this.getSpace(spaceId);
822
+ if (!space) {
823
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
824
+ }
825
+ if (disabled) {
826
+ return wrapTransaction(() => space.Pausable.write(signer).pause(), txnOpts);
827
+ }
828
+ else {
829
+ return wrapTransaction(() => space.Pausable.write(signer).unpause(), txnOpts);
830
+ }
831
+ }
832
+ /**
833
+ *
834
+ * @param spaceId
835
+ * @param priceInWei
836
+ * @param signer
837
+ */
838
+ async setMembershipPrice(spaceId, priceInWei, signer, txnOpts) {
839
+ const space = this.getSpace(spaceId);
840
+ if (!space) {
841
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
842
+ }
843
+ return wrapTransaction(() => space.Membership.write(signer).setMembershipPrice(priceInWei), txnOpts);
844
+ }
845
+ async setMembershipPricingModule(spaceId, pricingModule, signer, txnOpts) {
846
+ const space = this.getSpace(spaceId);
847
+ if (!space) {
848
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
849
+ }
850
+ return wrapTransaction(() => space.Membership.write(signer).setMembershipPricingModule(pricingModule), txnOpts);
851
+ }
852
+ async setMembershipLimit(spaceId, limit, signer, txnOpts) {
853
+ const space = this.getSpace(spaceId);
854
+ if (!space) {
855
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
856
+ }
857
+ return wrapTransaction(() => space.Membership.write(signer).setMembershipLimit(limit), txnOpts);
858
+ }
859
+ async setMembershipFreeAllocation(spaceId, freeAllocation, signer, txnOpts) {
860
+ const space = this.getSpace(spaceId);
861
+ if (!space) {
862
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
863
+ }
864
+ return wrapTransaction(() => space.Membership.write(signer).setMembershipFreeAllocation(freeAllocation), txnOpts);
865
+ }
866
+ async setChannelAccess(spaceId, channelNetworkId, disabled, signer, txnOpts) {
867
+ const channelId = ensureHexPrefix(channelNetworkId);
868
+ const space = this.getSpace(spaceId);
869
+ if (!space) {
870
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
871
+ }
872
+ return wrapTransaction(() => space.Channels.write(signer).updateChannel(channelId, '', disabled), txnOpts);
873
+ }
874
+ async getSpaceMembershipTokenAddress(spaceId) {
875
+ const space = this.getSpace(spaceId);
876
+ if (!space) {
877
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
878
+ }
879
+ return space.Membership.address;
880
+ }
881
+ async getJoinSpacePriceDetails(spaceId) {
882
+ const space = this.getSpace(spaceId);
883
+ if (!space) {
884
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
885
+ }
886
+ // membershipPrice is either the maximum of either the price set during space creation, or the PlatformRequirements membership fee
887
+ // it will always be a value regardless of whether the space has free allocations
888
+ const membershipPriceEncoded = space.Membership.interface.encodeFunctionData('getMembershipPrice');
889
+ // totalSupply = number of memberships minted
890
+ const totalSupplyEncoded = space.ERC721A.interface.encodeFunctionData('totalSupply');
891
+ // free allocation is set at space creation and is unchanging - it neither increases nor decreases
892
+ // if totalSupply < freeAllocation, the contracts won't charge for minting a membership nft,
893
+ // else it will charge the membershipPrice
894
+ const freeAllocationEncoded = space.Membership.interface.encodeFunctionData('getMembershipFreeAllocation');
895
+ const protocolFeeEncoded = space.Membership.interface.encodeFunctionData('getProtocolFee');
896
+ const [membershipPriceResult, totalSupplyResult, freeAllocationResult, protocolFeeResult] = await space.Multicall.read.callStatic.multicall([
897
+ membershipPriceEncoded,
898
+ totalSupplyEncoded,
899
+ freeAllocationEncoded,
900
+ protocolFeeEncoded,
901
+ ]);
902
+ try {
903
+ const membershipPrice = space.Membership.interface.decodeFunctionResult('getMembershipPrice', membershipPriceResult)[0];
904
+ const totalSupply = space.ERC721A.interface.decodeFunctionResult('totalSupply', totalSupplyResult)[0];
905
+ const freeAllocation = space.Membership.interface.decodeFunctionResult('getMembershipFreeAllocation', freeAllocationResult)[0];
906
+ const protocolFee = space.Membership.interface.decodeFunctionResult('getProtocolFee', protocolFeeResult)[0];
907
+ // remainingFreeSupply = freeAllocation - totalSupply (if positive)
908
+ const remainingFreeSupply = totalSupply.lt(freeAllocation)
909
+ ? freeAllocation.sub(totalSupply)
910
+ : ethers.BigNumber.from(0);
911
+ return {
912
+ price: remainingFreeSupply.gt(0) ? ethers.BigNumber.from(0) : membershipPrice,
913
+ remainingFreeSupply,
914
+ protocolFee,
915
+ };
916
+ }
917
+ catch (error) {
918
+ logger.error('getJoinSpacePriceDetails: Error decoding membership price', error);
919
+ throw error;
920
+ }
921
+ }
922
+ async getMembershipFreeAllocation(spaceId) {
923
+ const space = this.getSpace(spaceId);
924
+ if (!space) {
925
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
926
+ }
927
+ return space.Membership.read.getMembershipFreeAllocation();
928
+ }
929
+ async joinSpace(spaceId, recipient, signer, txnOpts) {
930
+ const joinSpaceStart = Date.now();
931
+ logger.log('joinSpace result before wrap', spaceId);
932
+ const getSpaceStart = Date.now();
933
+ const space = this.getSpace(spaceId);
934
+ if (!space) {
935
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
936
+ }
937
+ const [spaceCurrency, { price }] = await Promise.all([
938
+ space.Membership.read.getMembershipCurrency(),
939
+ this.getJoinSpacePriceDetails(spaceId),
940
+ ]);
941
+ const blockNumber = await space.provider?.getBlockNumber();
942
+ const startIssuedListener = space.Membership.listenForMembershipToken({
943
+ receiver: recipient,
944
+ startingBlock: blockNumber,
945
+ });
946
+ logger.log('joinSpace before blockNumber', Date.now() - getSpaceStart, blockNumber);
947
+ const getPriceStart = Date.now();
948
+ logger.log('joinSpace getMembershipPrice', Date.now() - getPriceStart);
949
+ const wrapStart = Date.now();
950
+ const issuedListener = startIssuedListener();
951
+ const result = await wrapTransaction(async () => {
952
+ // Set gas limit instead of using estimateGas
953
+ // As the estimateGas is not reliable for this contract
954
+ return await space.Membership.write(signer)['joinSpace(address)'](recipient, {
955
+ gasLimit: 1_500_000,
956
+ value: spaceCurrency.toLowerCase() === ETH_ADDRESS.toLowerCase() ? price : 0,
957
+ });
958
+ }, txnOpts);
959
+ const blockNumberAfterTx = await space.provider?.getBlockNumber();
960
+ logger.log('joinSpace wrap', Date.now() - wrapStart, blockNumberAfterTx);
961
+ const issued = await issuedListener;
962
+ const blockNumberAfter = await space.provider?.getBlockNumber();
963
+ logger.log('joinSpace after blockNumber', Date.now() - joinSpaceStart, blockNumberAfter, result, issued);
964
+ return issued;
965
+ }
966
+ async hasSpaceMembership(spaceId, addresses) {
967
+ const membershipStatus = await this.getMembershipStatus(spaceId, addresses);
968
+ return membershipStatus.isMember && !membershipStatus.isExpired;
969
+ }
970
+ async getMembershipStatus(spaceId, addresses) {
971
+ const space = this.getSpace(spaceId);
972
+ if (!space) {
973
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
974
+ }
975
+ return space.getMembershipStatus(addresses);
976
+ }
977
+ async getMembershipSupply(spaceId) {
978
+ const space = this.getSpace(spaceId);
979
+ if (!space) {
980
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
981
+ }
982
+ const totalSupply = await space.ERC721A.read.totalSupply();
983
+ return { totalSupply: totalSupply.toNumber() };
984
+ }
985
+ async getMembershipInfo(spaceId) {
986
+ const space = this.getSpace(spaceId);
987
+ if (!space) {
988
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
989
+ }
990
+ const [joinSpacePriceDetails, limit, currency, feeRecipient, duration, totalSupply, pricingModule,] = await Promise.all([
991
+ this.getJoinSpacePriceDetails(spaceId),
992
+ space.Membership.read.getMembershipLimit(),
993
+ space.Membership.read.getMembershipCurrency(),
994
+ space.Ownable.getOwner(),
995
+ space.Membership.read.getMembershipDuration(),
996
+ space.ERC721A.read.totalSupply(),
997
+ space.Membership.read.getMembershipPricingModule(),
998
+ ]);
999
+ const { price, remainingFreeSupply } = joinSpacePriceDetails;
1000
+ return {
1001
+ price, // keep as BigNumber (wei)
1002
+ maxSupply: limit.toNumber(),
1003
+ currency: currency,
1004
+ feeRecipient: feeRecipient,
1005
+ duration: duration.toNumber(),
1006
+ totalSupply: totalSupply.toNumber(),
1007
+ pricingModule: pricingModule,
1008
+ remainingFreeSupply: remainingFreeSupply.toNumber(),
1009
+ };
1010
+ }
1011
+ getWalletLink() {
1012
+ return this.walletLink;
1013
+ }
1014
+ getSpace(spaceId) {
1015
+ return this.spaceRegistrar.getSpace(spaceId);
1016
+ }
1017
+ listPricingModules() {
1018
+ return this.pricingModules.listPricingModules();
1019
+ }
1020
+ async encodeUpdateChannelRoles(space, channelNetworkId, _updatedRoleIds) {
1021
+ const channelId = ensureHexPrefix(channelNetworkId);
1022
+ const encodedCallData = [];
1023
+ const [channelInfo] = await Promise.all([
1024
+ space.Channels.read.getChannel(channelId),
1025
+ space.getEntitlementShims(),
1026
+ ]);
1027
+ const currentRoleIds = new Set(channelInfo.roleIds.map((r) => r.toNumber()));
1028
+ const updatedRoleIds = new Set(_updatedRoleIds);
1029
+ const rolesToRemove = [];
1030
+ const rolesToAdd = [];
1031
+ for (const r of updatedRoleIds) {
1032
+ // if the current role IDs does not have the updated role ID, then that role should be added.
1033
+ if (!currentRoleIds.has(r)) {
1034
+ rolesToAdd.push(r);
1035
+ }
1036
+ }
1037
+ for (const r of currentRoleIds) {
1038
+ // if the updated role IDs no longer have the current role ID, then that role should be removed.
1039
+ if (!updatedRoleIds.has(r)) {
1040
+ rolesToRemove.push(r);
1041
+ }
1042
+ }
1043
+ // encode the call data for each role to remove
1044
+ const encodedRemoveRoles = this.encodeRemoveRolesFromChannel(space, channelId, rolesToRemove);
1045
+ for (const callData of encodedRemoveRoles) {
1046
+ encodedCallData.push(callData);
1047
+ }
1048
+ // encode the call data for each role to add
1049
+ const encodedAddRoles = this.encodeAddRolesToChannel(space, channelId, rolesToAdd);
1050
+ for (const callData of encodedAddRoles) {
1051
+ encodedCallData.push(callData);
1052
+ }
1053
+ return encodedCallData;
1054
+ }
1055
+ encodeAddRolesToChannel(space, channelNetworkId, roleIds) {
1056
+ const channelId = ensureHexPrefix(channelNetworkId);
1057
+ const encodedCallData = [];
1058
+ for (const roleId of roleIds) {
1059
+ const encodedBytes = space.Channels.interface.encodeFunctionData('addRoleToChannel', [
1060
+ channelId,
1061
+ roleId,
1062
+ ]);
1063
+ encodedCallData.push(encodedBytes);
1064
+ }
1065
+ return encodedCallData;
1066
+ }
1067
+ encodeRemoveRolesFromChannel(space, channelNetworkId, roleIds) {
1068
+ const channelId = ensureHexPrefix(channelNetworkId);
1069
+ const encodedCallData = [];
1070
+ for (const roleId of roleIds) {
1071
+ const encodedBytes = space.Channels.interface.encodeFunctionData('removeRoleFromChannel', [channelId, roleId]);
1072
+ encodedCallData.push(encodedBytes);
1073
+ }
1074
+ return encodedCallData;
1075
+ }
1076
+ async createLegacyUpdatedEntitlements(space, params) {
1077
+ return createLegacyEntitlementStruct(space, params.users, params.ruleData);
1078
+ }
1079
+ async createUpdatedEntitlements(space, params) {
1080
+ return createEntitlementStruct(space, params.users, params.ruleData);
1081
+ }
1082
+ async refreshMetadata(spaceId, signer, txnOpts) {
1083
+ const space = this.getSpace(spaceId);
1084
+ if (!space) {
1085
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1086
+ }
1087
+ return wrapTransaction(() => space.Membership.metadata.write(signer).refreshMetadata(), txnOpts);
1088
+ }
1089
+ /**
1090
+ * Get the space address from the receipt and sender address
1091
+ * @param receipt - The receipt from the transaction
1092
+ * @param senderAddress - The address of the sender. Required for the case of a receipt containing multiple events of the same type.
1093
+ * @returns The space address or undefined if the receipt is not successful
1094
+ */
1095
+ getSpaceAddress(receipt, senderAddress) {
1096
+ if (receipt.status !== 1) {
1097
+ return undefined;
1098
+ }
1099
+ for (const receiptLog of receipt.logs) {
1100
+ const spaceAddress = this.spaceRegistrar.SpaceArchitect.getSpaceAddressFromLog(receiptLog, senderAddress);
1101
+ if (spaceAddress) {
1102
+ return spaceAddress;
1103
+ }
1104
+ }
1105
+ return undefined;
1106
+ }
1107
+ getTipEvent(spaceId, receipt, senderAddress) {
1108
+ const space = this.getSpace(spaceId);
1109
+ if (!space) {
1110
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1111
+ }
1112
+ return space.Tipping.getTipEvent(receipt, senderAddress);
1113
+ }
1114
+ withdrawSpaceFunds(spaceId, recipient, signer) {
1115
+ const space = this.getSpace(spaceId);
1116
+ if (!space) {
1117
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1118
+ }
1119
+ return space.Treasury.write(signer).withdraw(ETH_ADDRESS, recipient);
1120
+ }
1121
+ /**
1122
+ * Get the token id for the owner
1123
+ * Returns the first token id matched from the linked wallets of the owner
1124
+ * @param spaceId - The space id
1125
+ * @param owner - The owner
1126
+ * @returns The token id
1127
+ */
1128
+ async getTokenIdOfOwner(spaceId, owner, config = EmptyXchainConfig) {
1129
+ const space = this.getSpace(spaceId);
1130
+ if (!space) {
1131
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1132
+ }
1133
+ const linkedWallets = await this.getLinkedWalletsWithDelegations(owner, config);
1134
+ const tokenIds = await space.getTokenIdsOfOwner(linkedWallets);
1135
+ return tokenIds[0];
1136
+ }
1137
+ /**
1138
+ * Send a tip using the new sendTip interface
1139
+ * @param args.tipParams - The tip parameters (SendTipParams)
1140
+ * @param args.signer - The signer to use for the tip
1141
+ * @param args.txnOpts - Optional transaction options
1142
+ * @param args.overrideExecution - Optional execution override
1143
+ * @returns The transaction
1144
+ */
1145
+ async sendTip(args) {
1146
+ const { tipParams, signer, txnOpts, overrideExecution } = args;
1147
+ let recipientType;
1148
+ let encodedData;
1149
+ let tippingContract;
1150
+ switch (tipParams.type) {
1151
+ case 'member': {
1152
+ // TipRecipientType.Member = 0
1153
+ recipientType = 0;
1154
+ const { spaceId, receiver, tokenId, currency, amount, messageId, channelId } = tipParams;
1155
+ const space = this.getSpace(spaceId);
1156
+ if (!space) {
1157
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1158
+ }
1159
+ tippingContract = space.Tipping;
1160
+ const metadataData = ethers.utils.defaultAbiCoder.encode(['bytes32', 'bytes32', 'uint256'], [ensureHexPrefix(messageId), ensureHexPrefix(channelId), tokenId]);
1161
+ // Encode struct MembershipTipParams
1162
+ encodedData = ethers.utils.defaultAbiCoder.encode([
1163
+ 'tuple(address receiver, uint256 tokenId, address currency, uint256 amount, tuple(bytes32 messageId, bytes32 channelId, bytes data) metadata)',
1164
+ ], [
1165
+ [
1166
+ receiver,
1167
+ tokenId,
1168
+ currency,
1169
+ amount,
1170
+ [ensureHexPrefix(messageId), ensureHexPrefix(channelId), metadataData],
1171
+ ],
1172
+ ]);
1173
+ break;
1174
+ }
1175
+ case 'bot': {
1176
+ // TipRecipientType.Bot = 1
1177
+ recipientType = 1;
1178
+ const { spaceId, receiver, appId, currency, amount, messageId, channelId } = tipParams;
1179
+ if (spaceId) {
1180
+ const space = this.getSpace(spaceId);
1181
+ if (!space) {
1182
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1183
+ }
1184
+ tippingContract = space.Tipping;
1185
+ }
1186
+ else {
1187
+ if (!this.config.addresses.accountModules) {
1188
+ throw new Error('AccountModules address is not configured');
1189
+ }
1190
+ tippingContract = new ITippingShim(this.config.addresses.accountModules, this.provider);
1191
+ }
1192
+ const metadataData = ethers.utils.defaultAbiCoder.encode(['bytes32', 'bytes32'], [ensureHexPrefix(messageId), ensureHexPrefix(channelId)]);
1193
+ // Encode struct BotTipParams
1194
+ encodedData = ethers.utils.defaultAbiCoder.encode([
1195
+ 'tuple(address receiver, address currency, bytes32 appId, uint256 amount, tuple(bytes32 messageId, bytes32 channelId, bytes data) metadata)',
1196
+ ], [
1197
+ [
1198
+ receiver,
1199
+ currency,
1200
+ ensureHexPrefix(appId),
1201
+ amount,
1202
+ [ensureHexPrefix(messageId), ensureHexPrefix(channelId), metadataData],
1203
+ ],
1204
+ ]);
1205
+ break;
1206
+ }
1207
+ // DM tips (type: 'any') - calls the AccountModules contract directly
1208
+ case 'any': {
1209
+ // TipRecipientType.Any = 2
1210
+ recipientType = 2;
1211
+ const { receiver, currency, amount, messageId, channelId, sender: senderOverride, } = tipParams;
1212
+ const sender = senderOverride ?? (await signer.getAddress());
1213
+ if (!this.config.addresses.accountModules) {
1214
+ throw new Error('AccountModules address is not configured');
1215
+ }
1216
+ tippingContract = new ITippingShim(this.config.addresses.accountModules, this.provider);
1217
+ // Encode messageId and channelId into bytes data
1218
+ const data = ethers.utils.defaultAbiCoder.encode(['bytes32', 'bytes32'], [ensureHexPrefix(messageId), ensureHexPrefix(channelId)]);
1219
+ // Encode struct AnyTipParams
1220
+ encodedData = ethers.utils.defaultAbiCoder.encode([
1221
+ 'tuple(address currency, address sender, address receiver, uint256 amount, bytes data)',
1222
+ ], [[currency, sender, receiver, amount, data]]);
1223
+ break;
1224
+ }
1225
+ }
1226
+ return tippingContract.executeCall({
1227
+ signer,
1228
+ functionName: 'sendTip',
1229
+ args: [recipientType, encodedData],
1230
+ value: tipParams.currency.toLowerCase() === ETH_ADDRESS.toLowerCase()
1231
+ ? tipParams.amount
1232
+ : undefined,
1233
+ overrideExecution,
1234
+ transactionOpts: txnOpts,
1235
+ });
1236
+ }
1237
+ /**
1238
+ * Delegate staking within a space to an operator
1239
+ * @param args
1240
+ * @param args.spaceId - The space id
1241
+ * @param args.operatorAddress - The operator address
1242
+ * @returns The transaction
1243
+ */
1244
+ async addSpaceDelegation(args) {
1245
+ const { spaceId, operatorAddress, signer, transactionOpts, overrideExecution } = args;
1246
+ const space = this.getSpace(spaceId);
1247
+ if (!space) {
1248
+ throw new Error(`Space with spaceId "${spaceId}" is not found.`);
1249
+ }
1250
+ const spaceAddress = space.Address;
1251
+ return this.baseRegistry.spaceDelegation.executeCall({
1252
+ signer,
1253
+ functionName: 'addSpaceDelegation',
1254
+ args: [spaceAddress, operatorAddress],
1255
+ overrideExecution,
1256
+ transactionOpts,
1257
+ });
1258
+ }
1259
+ }
1260
+ //# sourceMappingURL=SpaceDapp.js.map