@centrifuge/sdk 0.0.0-alpha.3 → 0.0.0-alpha.31

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 (373) hide show
  1. package/README.md +19 -8
  2. package/dist/Centrifuge.d.ts +276 -424
  3. package/dist/Centrifuge.d.ts.map +1 -1
  4. package/dist/Centrifuge.js +564 -132
  5. package/dist/Centrifuge.js.map +1 -1
  6. package/dist/Centrifuge.test.d.ts +2 -0
  7. package/dist/Centrifuge.test.d.ts.map +1 -0
  8. package/dist/Centrifuge.test.js +514 -0
  9. package/dist/Centrifuge.test.js.map +1 -0
  10. package/dist/abi/Accounting.abi.d.ts +3 -0
  11. package/dist/abi/Accounting.abi.d.ts.map +1 -0
  12. package/dist/abi/Accounting.abi.js +33 -0
  13. package/dist/abi/Accounting.abi.js.map +1 -0
  14. package/dist/abi/AsyncRequestManager.abi.d.ts +3 -0
  15. package/dist/abi/AsyncRequestManager.abi.d.ts.map +1 -0
  16. package/dist/abi/AsyncRequestManager.abi.js +78 -0
  17. package/dist/abi/AsyncRequestManager.abi.js.map +1 -0
  18. package/dist/abi/AsyncVault.abi.d.ts +3 -0
  19. package/dist/abi/AsyncVault.abi.d.ts.map +1 -0
  20. package/dist/abi/AsyncVault.abi.js +101 -0
  21. package/dist/abi/AsyncVault.abi.js.map +1 -0
  22. package/dist/abi/BalanceSheet.abi.d.ts +3 -0
  23. package/dist/abi/BalanceSheet.abi.d.ts.map +1 -0
  24. package/dist/abi/BalanceSheet.abi.js +55 -0
  25. package/dist/abi/BalanceSheet.abi.js.map +1 -0
  26. package/dist/abi/Currency.abi.d.ts +3 -0
  27. package/dist/abi/Currency.abi.d.ts.map +1 -0
  28. package/dist/abi/Currency.abi.js +15 -0
  29. package/dist/abi/Currency.abi.js.map +1 -0
  30. package/dist/abi/ERC6909.abi.d.ts +3 -0
  31. package/dist/abi/ERC6909.abi.d.ts.map +1 -0
  32. package/dist/abi/ERC6909.abi.js +19 -0
  33. package/dist/abi/ERC6909.abi.js.map +1 -0
  34. package/dist/abi/GasService.abi.d.ts +3 -0
  35. package/dist/abi/GasService.abi.d.ts.map +1 -0
  36. package/dist/abi/GasService.abi.js +31 -0
  37. package/dist/abi/GasService.abi.js.map +1 -0
  38. package/dist/abi/Holdings.abi.d.ts +3 -0
  39. package/dist/abi/Holdings.abi.d.ts.map +1 -0
  40. package/dist/abi/Holdings.abi.js +43 -0
  41. package/dist/abi/Holdings.abi.js.map +1 -0
  42. package/dist/abi/Hub.abi.d.ts +3 -0
  43. package/dist/abi/Hub.abi.d.ts.map +1 -0
  44. package/dist/abi/Hub.abi.js +89 -0
  45. package/dist/abi/Hub.abi.js.map +1 -0
  46. package/dist/abi/HubRegistry.abi.d.ts +3 -0
  47. package/dist/abi/HubRegistry.abi.d.ts.map +1 -0
  48. package/dist/abi/HubRegistry.abi.js +39 -0
  49. package/dist/abi/HubRegistry.abi.js.map +1 -0
  50. package/dist/abi/MessageDispatcher.abi.d.ts +3 -0
  51. package/dist/abi/MessageDispatcher.abi.d.ts.map +1 -0
  52. package/dist/abi/MessageDispatcher.abi.js +49 -0
  53. package/dist/abi/MessageDispatcher.abi.js.map +1 -0
  54. package/dist/abi/MultiAdapter.abi.d.ts +3 -0
  55. package/dist/abi/MultiAdapter.abi.d.ts.map +1 -0
  56. package/dist/abi/MultiAdapter.abi.js +53 -0
  57. package/dist/abi/MultiAdapter.abi.js.map +1 -0
  58. package/dist/abi/RestrictionManager.abi.d.ts +3 -0
  59. package/dist/abi/RestrictionManager.abi.d.ts.map +1 -0
  60. package/dist/abi/RestrictionManager.abi.js +23 -0
  61. package/dist/abi/RestrictionManager.abi.js.map +1 -0
  62. package/dist/abi/ShareClassManager.abi.d.ts +3 -0
  63. package/dist/abi/ShareClassManager.abi.d.ts.map +1 -0
  64. package/dist/abi/ShareClassManager.abi.js +89 -0
  65. package/dist/abi/ShareClassManager.abi.js.map +1 -0
  66. package/dist/abi/Spoke.abi.d.ts +3 -0
  67. package/dist/abi/Spoke.abi.d.ts.map +1 -0
  68. package/dist/abi/Spoke.abi.js +90 -0
  69. package/dist/abi/Spoke.abi.js.map +1 -0
  70. package/dist/abi/SyncRequestManager.abi.d.ts +3 -0
  71. package/dist/abi/SyncRequestManager.abi.d.ts.map +1 -0
  72. package/dist/abi/SyncRequestManager.abi.js +61 -0
  73. package/dist/abi/SyncRequestManager.abi.js.map +1 -0
  74. package/dist/abi/Valuation.abi.d.ts +3 -0
  75. package/dist/abi/Valuation.abi.d.ts.map +1 -0
  76. package/dist/abi/Valuation.abi.js +2 -0
  77. package/dist/abi/Valuation.abi.js.map +1 -0
  78. package/dist/abi/VaultRouter.abi.d.ts +3 -0
  79. package/dist/abi/VaultRouter.abi.d.ts.map +1 -0
  80. package/dist/abi/VaultRouter.abi.js +51 -0
  81. package/dist/abi/VaultRouter.abi.js.map +1 -0
  82. package/dist/abi/index.d.ts +8510 -8
  83. package/dist/abi/index.d.ts.map +1 -1
  84. package/dist/abi/index.js +36 -16
  85. package/dist/abi/index.js.map +1 -1
  86. package/dist/config/chains.d.ts +184 -925
  87. package/dist/config/chains.d.ts.map +1 -1
  88. package/dist/config/chains.js +2 -2
  89. package/dist/config/chains.js.map +1 -1
  90. package/dist/config/protocol.d.ts +3 -0
  91. package/dist/config/protocol.d.ts.map +1 -0
  92. package/dist/config/protocol.js +7 -0
  93. package/dist/config/protocol.js.map +1 -0
  94. package/dist/entities/BalanceSheet.d.ts +47 -0
  95. package/dist/entities/BalanceSheet.d.ts.map +1 -0
  96. package/dist/entities/BalanceSheet.js +94 -0
  97. package/dist/entities/BalanceSheet.js.map +1 -0
  98. package/dist/entities/BalanceSheet.test.d.ts +2 -0
  99. package/dist/entities/BalanceSheet.test.d.ts.map +1 -0
  100. package/dist/entities/BalanceSheet.test.js +44 -0
  101. package/dist/entities/BalanceSheet.test.js.map +1 -0
  102. package/dist/entities/Entity.d.ts +8 -0
  103. package/dist/entities/Entity.d.ts.map +1 -0
  104. package/dist/{Entity.js → entities/Entity.js} +5 -3
  105. package/dist/entities/Entity.js.map +1 -0
  106. package/dist/entities/IndexerQueries/assetSnapshots.d.ts +69 -0
  107. package/dist/entities/IndexerQueries/assetSnapshots.d.ts.map +1 -0
  108. package/dist/entities/IndexerQueries/assetSnapshots.js +91 -0
  109. package/dist/entities/IndexerQueries/assetSnapshots.js.map +1 -0
  110. package/dist/entities/IndexerQueries/assetTransactions.d.ts +93 -0
  111. package/dist/entities/IndexerQueries/assetTransactions.d.ts.map +1 -0
  112. package/dist/entities/IndexerQueries/assetTransactions.js +75 -0
  113. package/dist/entities/IndexerQueries/assetTransactions.js.map +1 -0
  114. package/dist/entities/IndexerQueries/epochs.d.ts +45 -0
  115. package/dist/entities/IndexerQueries/epochs.d.ts.map +1 -0
  116. package/dist/entities/IndexerQueries/epochs.js +51 -0
  117. package/dist/entities/IndexerQueries/epochs.js.map +1 -0
  118. package/dist/entities/IndexerQueries/index.d.ts +40 -0
  119. package/dist/entities/IndexerQueries/index.d.ts.map +1 -0
  120. package/dist/entities/IndexerQueries/index.js +45 -0
  121. package/dist/entities/IndexerQueries/index.js.map +1 -0
  122. package/dist/entities/IndexerQueries/investorTransactions.d.ts +50 -0
  123. package/dist/entities/IndexerQueries/investorTransactions.d.ts.map +1 -0
  124. package/dist/entities/IndexerQueries/investorTransactions.js +55 -0
  125. package/dist/entities/IndexerQueries/investorTransactions.js.map +1 -0
  126. package/dist/{queries → entities/IndexerQueries}/poolFeeSnapshots.d.ts +8 -8
  127. package/dist/entities/IndexerQueries/poolFeeSnapshots.d.ts.map +1 -0
  128. package/dist/{queries → entities/IndexerQueries}/poolFeeSnapshots.js +8 -8
  129. package/dist/entities/IndexerQueries/poolFeeSnapshots.js.map +1 -0
  130. package/dist/entities/IndexerQueries/poolFeeTransactions.d.ts +34 -0
  131. package/dist/entities/IndexerQueries/poolFeeTransactions.d.ts.map +1 -0
  132. package/dist/entities/IndexerQueries/poolFeeTransactions.js +37 -0
  133. package/dist/entities/IndexerQueries/poolFeeTransactions.js.map +1 -0
  134. package/dist/{queries → entities/IndexerQueries}/poolSnapshots.d.ts +30 -24
  135. package/dist/entities/IndexerQueries/poolSnapshots.d.ts.map +1 -0
  136. package/dist/{queries → entities/IndexerQueries}/poolSnapshots.js +29 -23
  137. package/dist/entities/IndexerQueries/poolSnapshots.js.map +1 -0
  138. package/dist/entities/IndexerQueries/trancheCurrencyBalance.d.ts +76 -0
  139. package/dist/entities/IndexerQueries/trancheCurrencyBalance.d.ts.map +1 -0
  140. package/dist/entities/IndexerQueries/trancheCurrencyBalance.js +63 -0
  141. package/dist/entities/IndexerQueries/trancheCurrencyBalance.js.map +1 -0
  142. package/dist/{queries → entities/IndexerQueries}/trancheSnapshots.d.ts +7 -7
  143. package/dist/entities/IndexerQueries/trancheSnapshots.d.ts.map +1 -0
  144. package/dist/{queries → entities/IndexerQueries}/trancheSnapshots.js +7 -7
  145. package/dist/entities/IndexerQueries/trancheSnapshots.js.map +1 -0
  146. package/dist/entities/Investor.d.ts +33 -0
  147. package/dist/entities/Investor.d.ts.map +1 -0
  148. package/dist/entities/Investor.js +59 -0
  149. package/dist/entities/Investor.js.map +1 -0
  150. package/dist/entities/Investor.test.d.ts +2 -0
  151. package/dist/entities/Investor.test.d.ts.map +1 -0
  152. package/dist/entities/Investor.test.js +16 -0
  153. package/dist/entities/Investor.test.js.map +1 -0
  154. package/dist/entities/Pool.d.ts +138 -0
  155. package/dist/entities/Pool.d.ts.map +1 -0
  156. package/dist/entities/Pool.js +297 -0
  157. package/dist/entities/Pool.js.map +1 -0
  158. package/dist/entities/Pool.test.d.ts +2 -0
  159. package/dist/entities/Pool.test.d.ts.map +1 -0
  160. package/dist/entities/Pool.test.js +91 -0
  161. package/dist/entities/Pool.test.js.map +1 -0
  162. package/dist/entities/PoolNetwork.d.ts +64 -0
  163. package/dist/entities/PoolNetwork.d.ts.map +1 -0
  164. package/dist/entities/PoolNetwork.js +252 -0
  165. package/dist/entities/PoolNetwork.js.map +1 -0
  166. package/dist/entities/PoolNetwork.test.d.ts +2 -0
  167. package/dist/entities/PoolNetwork.test.d.ts.map +1 -0
  168. package/dist/entities/PoolNetwork.test.js +64 -0
  169. package/dist/entities/PoolNetwork.test.js.map +1 -0
  170. package/dist/entities/Reports/Processor.d.ts +46 -0
  171. package/dist/entities/Reports/Processor.d.ts.map +1 -0
  172. package/dist/entities/Reports/Processor.js +471 -0
  173. package/dist/entities/Reports/Processor.js.map +1 -0
  174. package/dist/entities/Reports/Processor.test.d.ts +2 -0
  175. package/dist/entities/Reports/Processor.test.d.ts.map +1 -0
  176. package/dist/entities/Reports/Processor.test.js +767 -0
  177. package/dist/entities/Reports/Processor.test.js.map +1 -0
  178. package/dist/entities/Reports/Reports.test.d.ts +2 -0
  179. package/dist/entities/Reports/Reports.test.d.ts.map +1 -0
  180. package/dist/entities/Reports/Reports.test.js +559 -0
  181. package/dist/entities/Reports/Reports.test.js.map +1 -0
  182. package/dist/entities/Reports/index.d.ts +21 -0
  183. package/dist/entities/Reports/index.d.ts.map +1 -0
  184. package/dist/entities/Reports/index.js +144 -0
  185. package/dist/entities/Reports/index.js.map +1 -0
  186. package/dist/entities/ShareClass.d.ts +186 -0
  187. package/dist/entities/ShareClass.d.ts.map +1 -0
  188. package/dist/entities/ShareClass.js +978 -0
  189. package/dist/entities/ShareClass.js.map +1 -0
  190. package/dist/entities/ShareClass.test.d.ts +2 -0
  191. package/dist/entities/ShareClass.test.d.ts.map +1 -0
  192. package/dist/entities/ShareClass.test.js +108 -0
  193. package/dist/entities/ShareClass.test.js.map +1 -0
  194. package/dist/entities/Vault.d.ts +85 -0
  195. package/dist/entities/Vault.d.ts.map +1 -0
  196. package/dist/entities/Vault.js +385 -0
  197. package/dist/entities/Vault.js.map +1 -0
  198. package/dist/entities/Vault.test.d.ts +2 -0
  199. package/dist/entities/Vault.test.d.ts.map +1 -0
  200. package/dist/entities/Vault.test.js +272 -0
  201. package/dist/entities/Vault.test.js.map +1 -0
  202. package/dist/index.d.ts +16 -6
  203. package/dist/index.d.ts.map +1 -1
  204. package/dist/index.js +10 -6
  205. package/dist/index.js.map +1 -1
  206. package/dist/tests/mocks/mockAssetSnapshots.d.ts +3 -0
  207. package/dist/tests/mocks/mockAssetSnapshots.d.ts.map +1 -0
  208. package/dist/tests/mocks/mockAssetSnapshots.js +56 -0
  209. package/dist/tests/mocks/mockAssetSnapshots.js.map +1 -0
  210. package/dist/tests/mocks/mockAssetTransactions.d.ts +3 -0
  211. package/dist/tests/mocks/mockAssetTransactions.d.ts.map +1 -0
  212. package/dist/tests/mocks/mockAssetTransactions.js +86 -0
  213. package/dist/tests/mocks/mockAssetTransactions.js.map +1 -0
  214. package/dist/tests/mocks/mockEpochs.d.ts +3 -0
  215. package/dist/tests/mocks/mockEpochs.d.ts.map +1 -0
  216. package/dist/tests/mocks/mockEpochs.js +26 -0
  217. package/dist/tests/mocks/mockEpochs.js.map +1 -0
  218. package/dist/tests/mocks/mockInvestorCurrencyBalance.d.ts +3 -0
  219. package/dist/tests/mocks/mockInvestorCurrencyBalance.d.ts.map +1 -0
  220. package/dist/tests/mocks/mockInvestorCurrencyBalance.js +29 -0
  221. package/dist/tests/mocks/mockInvestorCurrencyBalance.js.map +1 -0
  222. package/dist/tests/mocks/mockInvestorTransactions.d.ts +3 -0
  223. package/dist/tests/mocks/mockInvestorTransactions.d.ts.map +1 -0
  224. package/dist/tests/mocks/mockInvestorTransactions.js +35 -0
  225. package/dist/tests/mocks/mockInvestorTransactions.js.map +1 -0
  226. package/dist/tests/mocks/mockPoolFeeSnapshot.d.ts +1 -1
  227. package/dist/tests/mocks/mockPoolFeeSnapshot.d.ts.map +1 -1
  228. package/dist/tests/mocks/mockPoolFeeSnapshot.js +29 -29
  229. package/dist/tests/mocks/mockPoolFeeSnapshot.js.map +1 -1
  230. package/dist/tests/mocks/mockPoolFeeTransactions.d.ts +11 -0
  231. package/dist/tests/mocks/mockPoolFeeTransactions.d.ts.map +1 -0
  232. package/dist/tests/mocks/mockPoolFeeTransactions.js +20 -0
  233. package/dist/tests/mocks/mockPoolFeeTransactions.js.map +1 -0
  234. package/dist/tests/mocks/mockPoolMetadata.d.ts.map +1 -1
  235. package/dist/tests/mocks/mockPoolMetadata.js +7 -17
  236. package/dist/tests/mocks/mockPoolMetadata.js.map +1 -1
  237. package/dist/tests/mocks/mockPoolSnapshots.d.ts +1 -1
  238. package/dist/tests/mocks/mockPoolSnapshots.d.ts.map +1 -1
  239. package/dist/tests/mocks/mockPoolSnapshots.js +47 -45
  240. package/dist/tests/mocks/mockPoolSnapshots.js.map +1 -1
  241. package/dist/tests/mocks/mockTrancheSnapshots.d.ts +1 -1
  242. package/dist/tests/mocks/mockTrancheSnapshots.d.ts.map +1 -1
  243. package/dist/tests/mocks/mockTrancheSnapshots.js +21 -21
  244. package/dist/tests/mocks/mockTrancheSnapshots.js.map +1 -1
  245. package/dist/tests/setup.d.ts.map +1 -1
  246. package/dist/tests/setup.js +3 -2
  247. package/dist/tests/setup.js.map +1 -1
  248. package/dist/tests/tenderly.js +1 -1
  249. package/dist/tests/tenderly.js.map +1 -1
  250. package/dist/tests/utils.d.ts +3 -0
  251. package/dist/tests/utils.d.ts.map +1 -0
  252. package/dist/tests/utils.js +4 -0
  253. package/dist/tests/utils.js.map +1 -0
  254. package/dist/types/holdings.d.ts +9 -0
  255. package/dist/types/holdings.d.ts.map +1 -0
  256. package/dist/types/holdings.js +10 -0
  257. package/dist/types/holdings.js.map +1 -0
  258. package/dist/types/index.d.ts +63 -0
  259. package/dist/types/index.d.ts.map +1 -1
  260. package/dist/types/poolInput.d.ts +71 -0
  261. package/dist/types/poolInput.d.ts.map +1 -0
  262. package/dist/types/poolInput.js +2 -0
  263. package/dist/types/poolInput.js.map +1 -0
  264. package/dist/types/poolMetadata.d.ts +14 -13
  265. package/dist/types/poolMetadata.d.ts.map +1 -1
  266. package/dist/types/reports.d.ts +336 -0
  267. package/dist/types/reports.d.ts.map +1 -0
  268. package/dist/types/reports.js +2 -0
  269. package/dist/types/reports.js.map +1 -0
  270. package/dist/types/transaction.d.ts +49 -2
  271. package/dist/types/transaction.d.ts.map +1 -1
  272. package/dist/types/transaction.js +40 -1
  273. package/dist/types/transaction.js.map +1 -1
  274. package/dist/utils/BigInt.d.ts +15 -34
  275. package/dist/utils/BigInt.d.ts.map +1 -1
  276. package/dist/utils/BigInt.js +16 -23
  277. package/dist/utils/BigInt.js.map +1 -1
  278. package/dist/utils/BigInt.test.d.ts +2 -0
  279. package/dist/utils/BigInt.test.d.ts.map +1 -0
  280. package/dist/utils/BigInt.test.js +298 -0
  281. package/dist/utils/BigInt.test.js.map +1 -0
  282. package/dist/utils/currencies.d.ts +5 -0
  283. package/dist/utils/currencies.d.ts.map +1 -0
  284. package/dist/utils/currencies.js +7 -0
  285. package/dist/utils/currencies.js.map +1 -0
  286. package/dist/utils/date.d.ts.map +1 -1
  287. package/dist/utils/date.js +5 -4
  288. package/dist/utils/date.js.map +1 -1
  289. package/dist/utils/decimal.d.ts +2 -2
  290. package/dist/utils/decimal.d.ts.map +1 -1
  291. package/dist/utils/decimal.js.map +1 -1
  292. package/dist/utils/index.d.ts +4 -0
  293. package/dist/utils/index.d.ts.map +1 -0
  294. package/dist/utils/index.js +24 -0
  295. package/dist/utils/index.js.map +1 -0
  296. package/dist/utils/ipfs.d.ts +7 -0
  297. package/dist/utils/ipfs.d.ts.map +1 -0
  298. package/dist/utils/ipfs.js +64 -0
  299. package/dist/utils/ipfs.js.map +1 -0
  300. package/dist/utils/ipfs.test.d.ts +2 -0
  301. package/dist/utils/ipfs.test.d.ts.map +1 -0
  302. package/dist/utils/ipfs.test.js +54 -0
  303. package/dist/utils/ipfs.test.js.map +1 -0
  304. package/dist/utils/rx.d.ts +1 -1
  305. package/dist/utils/rx.d.ts.map +1 -1
  306. package/dist/utils/rx.js +4 -0
  307. package/dist/utils/rx.js.map +1 -1
  308. package/dist/utils/transaction.d.ts +14 -2
  309. package/dist/utils/transaction.d.ts.map +1 -1
  310. package/dist/utils/transaction.js +57 -5
  311. package/dist/utils/transaction.js.map +1 -1
  312. package/dist/utils/types.d.ts +39 -0
  313. package/dist/utils/types.d.ts.map +1 -0
  314. package/dist/utils/types.js +89 -0
  315. package/dist/utils/types.js.map +1 -0
  316. package/dist/utils/types.test.d.ts +2 -0
  317. package/dist/utils/types.test.d.ts.map +1 -0
  318. package/dist/utils/types.test.js +89 -0
  319. package/dist/utils/types.test.js.map +1 -0
  320. package/package.json +13 -8
  321. package/dist/Account.d.ts +0 -11
  322. package/dist/Account.d.ts.map +0 -1
  323. package/dist/Account.js +0 -46
  324. package/dist/Account.js.map +0 -1
  325. package/dist/Entity.d.ts +0 -12
  326. package/dist/Entity.d.ts.map +0 -1
  327. package/dist/Entity.js.map +0 -1
  328. package/dist/Pool.d.ts +0 -27
  329. package/dist/Pool.d.ts.map +0 -1
  330. package/dist/Pool.js +0 -76
  331. package/dist/Pool.js.map +0 -1
  332. package/dist/PoolNetwork.d.ts +0 -82
  333. package/dist/PoolNetwork.d.ts.map +0 -1
  334. package/dist/PoolNetwork.js +0 -236
  335. package/dist/PoolNetwork.js.map +0 -1
  336. package/dist/Reports/Processor.d.ts +0 -38
  337. package/dist/Reports/Processor.d.ts.map +0 -1
  338. package/dist/Reports/Processor.js +0 -167
  339. package/dist/Reports/Processor.js.map +0 -1
  340. package/dist/Reports/index.d.ts +0 -24
  341. package/dist/Reports/index.d.ts.map +0 -1
  342. package/dist/Reports/index.js +0 -68
  343. package/dist/Reports/index.js.map +0 -1
  344. package/dist/Reports/types.d.ts +0 -102
  345. package/dist/Reports/types.d.ts.map +0 -1
  346. package/dist/Reports/types.js +0 -2
  347. package/dist/Reports/types.js.map +0 -1
  348. package/dist/Vault.d.ts +0 -96
  349. package/dist/Vault.d.ts.map +0 -1
  350. package/dist/Vault.js +0 -330
  351. package/dist/Vault.js.map +0 -1
  352. package/dist/abi/CentrifugeRouter.abi.json +0 -43
  353. package/dist/abi/Currency.abi.json +0 -14
  354. package/dist/abi/Gateway.abi.json +0 -1
  355. package/dist/abi/InvestmentManager.abi.json +0 -4
  356. package/dist/abi/LiquidityPool.abi.json +0 -79
  357. package/dist/abi/PoolManager.abi.json +0 -55
  358. package/dist/abi/RestrictionManager.abi.json +0 -22
  359. package/dist/abi/Router.abi.json +0 -1
  360. package/dist/config/lp.d.ts +0 -17
  361. package/dist/config/lp.d.ts.map +0 -1
  362. package/dist/config/lp.js +0 -35
  363. package/dist/config/lp.js.map +0 -1
  364. package/dist/queries/poolFeeSnapshots.d.ts.map +0 -1
  365. package/dist/queries/poolFeeSnapshots.js.map +0 -1
  366. package/dist/queries/poolSnapshots.d.ts.map +0 -1
  367. package/dist/queries/poolSnapshots.js.map +0 -1
  368. package/dist/queries/trancheSnapshots.d.ts.map +0 -1
  369. package/dist/queries/trancheSnapshots.js.map +0 -1
  370. package/dist/utils/pinToApi.d.ts +0 -2
  371. package/dist/utils/pinToApi.d.ts.map +0 -1
  372. package/dist/utils/pinToApi.js +0 -10
  373. package/dist/utils/pinToApi.js.map +0 -1
@@ -1,40 +1,35 @@
1
- import { concatWith, defaultIfEmpty, defer, filter, identity, isObservable, map, mergeMap, of, Subject, switchMap, using, } from 'rxjs';
1
+ import { combineLatest, concatWith, defaultIfEmpty, defer, filter, first, identity, isObservable, map, mergeMap, of, Subject, switchMap, timer, using, } from 'rxjs';
2
2
  import { fromFetch } from 'rxjs/fetch';
3
- import { createPublicClient, createWalletClient, custom, getContract, http, parseEventLogs, } from 'viem';
3
+ import { createPublicClient, createWalletClient, custom, encodeFunctionData, fallback, getContract, http, parseAbi, parseEventLogs, toHex, } from 'viem';
4
4
  import { ABI } from './abi/index.js';
5
- import { Account } from './Account.js';
6
5
  import { chains } from './config/chains.js';
7
- import { PERMIT_TYPEHASH } from './constants.js';
8
- import { Pool } from './Pool.js';
9
- import { Currency } from './utils/BigInt.js';
6
+ import { NULL_ADDRESS, PERMIT_TYPEHASH } from './constants.js';
7
+ import { Investor } from './entities/Investor.js';
8
+ import { Pool } from './entities/Pool.js';
9
+ import { MessageType, } from './types/transaction.js';
10
+ import { Balance } from './utils/BigInt.js';
11
+ import { randomUint } from './utils/index.js';
12
+ import { createPinning, getUrlFromHash } from './utils/ipfs.js';
10
13
  import { hashKey } from './utils/query.js';
11
14
  import { makeThenable, repeatOnEvents, shareReplayWithDelayedReset } from './utils/rx.js';
12
- import { doTransaction, isLocalAccount } from './utils/transaction.js';
15
+ import { doTransaction, isLocalAccount, wrapTransaction } from './utils/transaction.js';
16
+ import { AssetId, PoolId, ShareClassId } from './utils/types.js';
17
+ const PINNING_API_DEMO = 'https://europe-central2-peak-vista-185616.cloudfunctions.net/pinning-api-demo';
13
18
  const envConfig = {
14
19
  mainnet: {
15
- indexerUrl: 'https://subql.embrio.tech/',
16
- alchemyKey: 'KNR-1LZhNqWOxZS2AN8AFeaiESBV10qZ',
17
- infuraKey: '8ed99a9a115349bbbc01dcf3a24edc96',
18
- defaultChain: 1,
20
+ indexerUrl: 'https://api.centrifuge.io',
19
21
  ipfsUrl: 'https://centrifuge.mypinata.cloud',
22
+ ...createPinning(PINNING_API_DEMO),
20
23
  },
21
- demo: {
22
- indexerUrl: 'https://api.subquery.network/sq/centrifuge/pools-demo-multichain',
23
- alchemyKey: 'KNR-1LZhNqWOxZS2AN8AFeaiESBV10qZ',
24
- infuraKey: '8cd8e043ee8d4001b97a1c37e08fd9dd',
25
- defaultChain: 11155111,
26
- ipfsUrl: 'https://centrifuge.mypinata.cloud',
27
- },
28
- dev: {
29
- indexerUrl: 'https://api.subquery.network/sq/centrifuge/pools-demo-multichain',
30
- alchemyKey: 'KNR-1LZhNqWOxZS2AN8AFeaiESBV10qZ',
31
- infuraKey: '8cd8e043ee8d4001b97a1c37e08fd9dd',
32
- defaultChain: 11155111,
24
+ testnet: {
25
+ indexerUrl: 'https://api-v3-hitz.marble.live/graphql',
33
26
  ipfsUrl: 'https://centrifuge.mypinata.cloud',
27
+ ...createPinning(PINNING_API_DEMO),
34
28
  },
35
29
  };
36
30
  const defaultConfig = {
37
31
  environment: 'mainnet',
32
+ cache: true,
38
33
  };
39
34
  export class Centrifuge {
40
35
  #config;
@@ -43,13 +38,16 @@ export class Centrifuge {
43
38
  }
44
39
  #clients = new Map();
45
40
  getClient(chainId) {
46
- return this.#clients.get(chainId ?? this.config.defaultChain);
41
+ const client = this.#clients.get(chainId);
42
+ if (!client)
43
+ throw new Error(`No client found for chain ID "${chainId}"`);
44
+ return client;
47
45
  }
48
46
  get chains() {
49
47
  return [...this.#clients.keys()];
50
48
  }
51
49
  getChainConfig(chainId) {
52
- return this.getClient(chainId ?? this.config.defaultChain).chain;
50
+ return this.getClient(chainId).chain;
53
51
  }
54
52
  #signer = null;
55
53
  setSigner(signer) {
@@ -58,8 +56,9 @@ export class Centrifuge {
58
56
  get signer() {
59
57
  return this.#signer;
60
58
  }
59
+ #isBatching = new WeakSet();
61
60
  constructor(config = {}) {
62
- const defaultConfigForEnv = envConfig[config?.environment ?? 'mainnet'];
61
+ const defaultConfigForEnv = envConfig[config?.environment || 'mainnet'];
63
62
  this.#config = {
64
63
  ...defaultConfig,
65
64
  ...defaultConfigForEnv,
@@ -73,14 +72,178 @@ export class Centrifuge {
73
72
  if (!rpcUrl) {
74
73
  console.warn(`No rpcUrl defined for chain ${chain.id}. Using public RPC endpoint.`);
75
74
  }
76
- this.#clients.set(chain.id, createPublicClient({ chain, transport: http(rpcUrl), batch: { multicall: true } }));
75
+ this.#clients.set(chain.id, createPublicClient({
76
+ chain,
77
+ transport: Array.isArray(rpcUrl) ? fallback(rpcUrl.map((url) => http(url))) : http(rpcUrl),
78
+ batch: { multicall: true },
79
+ pollingInterval: this.#config.pollingInterval,
80
+ cacheTime: 100,
81
+ }));
77
82
  });
78
83
  }
79
- pool(id, metadataHash) {
80
- return this._query(null, () => of(new Pool(this, id, metadataHash)));
84
+ /**
85
+ * Create a new pool on the given chain.
86
+ * @param metadataInput - The metadata for the pool
87
+ * @param currencyCode - The currency code for the pool
88
+ * @param chainId - The chain ID to create the pool on
89
+ * @param counter - The pool counter, used to create a unique pool ID (uint48)
90
+ */
91
+ createPool(metadataInput, currencyCode = 840, chainId, counter) {
92
+ const self = this;
93
+ return this._transact(async function* ({ walletClient, signingAddress, publicClient }) {
94
+ const [addresses, id] = await Promise.all([self._protocolAddresses(chainId), self.id(chainId)]);
95
+ const poolId = PoolId.from(id, counter ?? randomUint(48));
96
+ const createPoolData = encodeFunctionData({
97
+ abi: ABI.Hub,
98
+ functionName: 'createPool',
99
+ args: [poolId.raw, signingAddress, BigInt(currencyCode)],
100
+ });
101
+ const scIds = Array.from({ length: metadataInput.shareClasses.length }, (_, i) => ShareClassId.from(poolId, i + 1));
102
+ const shareClassesById = {};
103
+ metadataInput.shareClasses.forEach((sc, index) => {
104
+ shareClassesById[scIds[index].raw] = {
105
+ minInitialInvestment: sc.minInvestment,
106
+ apyPercentage: sc.apyPercentage,
107
+ apy: sc.apy,
108
+ defaultAccounts: sc.defaultAccounts,
109
+ };
110
+ });
111
+ const formattedMetadata = {
112
+ version: 1,
113
+ pool: {
114
+ name: metadataInput.poolName,
115
+ icon: metadataInput.poolIcon,
116
+ asset: {
117
+ class: metadataInput.assetClass,
118
+ subClass: metadataInput.subAssetClass,
119
+ },
120
+ issuer: {
121
+ name: metadataInput.issuerName,
122
+ repName: metadataInput.issuerRepName,
123
+ description: metadataInput.issuerDescription,
124
+ email: metadataInput.email,
125
+ logo: metadataInput.issuerLogo,
126
+ shortDescription: metadataInput.issuerShortDescription,
127
+ categories: metadataInput.issuerCategories,
128
+ },
129
+ poolStructure: metadataInput.poolStructure,
130
+ investorType: metadataInput.investorType,
131
+ links: {
132
+ executiveSummary: metadataInput.executiveSummary,
133
+ forum: metadataInput.forum,
134
+ website: metadataInput.website,
135
+ },
136
+ details: metadataInput.details,
137
+ status: 'open',
138
+ listed: metadataInput.listed ?? true,
139
+ poolRatings: metadataInput.poolRatings.length > 0 ? metadataInput.poolRatings : [],
140
+ reports: metadataInput.report
141
+ ? [
142
+ {
143
+ author: {
144
+ name: metadataInput.report.author.name,
145
+ title: metadataInput.report.author.title,
146
+ avatar: metadataInput.report.author.avatar,
147
+ },
148
+ uri: metadataInput.report.uri,
149
+ },
150
+ ]
151
+ : [],
152
+ },
153
+ shareClasses: shareClassesById,
154
+ onboarding: {
155
+ shareClasses: metadataInput.onboarding?.shareClasses || {},
156
+ taxInfoRequired: metadataInput.onboarding?.taxInfoRequired,
157
+ externalOnboardingUrl: metadataInput.onboarding?.externalOnboardingUrl,
158
+ },
159
+ };
160
+ const cid = await self.config.pinJson(formattedMetadata);
161
+ const setMetadataData = encodeFunctionData({
162
+ abi: ABI.Hub,
163
+ functionName: 'setPoolMetadata',
164
+ args: [poolId.raw, toHex(cid)],
165
+ });
166
+ const addScData = metadataInput.shareClasses.map((sc) => encodeFunctionData({
167
+ abi: ABI.Hub,
168
+ functionName: 'addShareClass',
169
+ args: [
170
+ poolId.raw,
171
+ sc.tokenName,
172
+ sc.symbolName,
173
+ sc.salt?.startsWith('0x') ? sc.salt : toHex(sc.salt ?? randomUint(256), { size: 32 }),
174
+ ],
175
+ }));
176
+ const accountIsDebitNormal = new Map();
177
+ const accountNumbers = [
178
+ ...new Set(metadataInput.shareClasses.flatMap((sc) => Object.entries(sc.defaultAccounts ?? {})
179
+ .filter(([k, v]) => {
180
+ if (!v)
181
+ return false;
182
+ if (['asset', 'expense'].includes(k)) {
183
+ if (accountIsDebitNormal.get(v) === false)
184
+ throw new Error(`Account "${v}" is set as both credit normal and debit normal.`);
185
+ accountIsDebitNormal.set(v, true);
186
+ }
187
+ else {
188
+ if (accountIsDebitNormal.get(v) === true)
189
+ throw new Error(`Account "${v}" is set as both credit normal and debit normal.`);
190
+ accountIsDebitNormal.set(v, false);
191
+ }
192
+ return true;
193
+ })
194
+ .map(([, v]) => v))),
195
+ ];
196
+ const createAccountsData = accountNumbers.map((account) => encodeFunctionData({
197
+ abi: ABI.Hub,
198
+ functionName: 'createAccount',
199
+ args: [poolId.raw, account, accountIsDebitNormal.get(account)],
200
+ }));
201
+ yield* doTransaction('Create pool', publicClient, () => {
202
+ return walletClient.writeContract({
203
+ address: addresses.hub,
204
+ abi: ABI.Hub,
205
+ functionName: 'multicall',
206
+ args: [[createPoolData, setMetadataData, ...addScData, ...createAccountsData]],
207
+ });
208
+ });
209
+ }, chainId);
210
+ }
211
+ id(chainId) {
212
+ return this._query(['centrifugeId', chainId], () => this._protocolAddresses(chainId).pipe(switchMap(({ messageDispatcher }) => {
213
+ return this.getClient(chainId).readContract({
214
+ address: messageDispatcher,
215
+ abi: ABI.MessageDispatcher,
216
+ functionName: 'localCentrifugeId',
217
+ });
218
+ })));
219
+ }
220
+ /**
221
+ * Get the existing pools on the different chains.
222
+ */
223
+ pools() {
224
+ return this._queryIndexer(`{
225
+ pools {
226
+ items {
227
+ id
228
+ blockchain {
229
+ id
230
+ }
231
+ }
232
+ }
233
+ }`, {}, (data) => {
234
+ return data.pools.items.map((pool) => {
235
+ const poolId = new PoolId(pool.id);
236
+ return new Pool(this, poolId.toString(), Number(pool.blockchain.id));
237
+ });
238
+ });
81
239
  }
82
- account(address, chainId) {
83
- return this._query(null, () => of(new Account(this, address, chainId ?? this.config.defaultChain)));
240
+ pool(id) {
241
+ return this._query(null, () => this.pools().pipe(map((pools) => {
242
+ const pool = pools.find((pool) => pool.id.equals(id));
243
+ if (!pool)
244
+ throw new Error(`Pool with id ${id} not found`);
245
+ return pool;
246
+ })));
84
247
  }
85
248
  /**
86
249
  * Get the metadata for an ERC20 token
@@ -89,18 +252,18 @@ export class Centrifuge {
89
252
  */
90
253
  currency(address, chainId) {
91
254
  const curAddress = address.toLowerCase();
92
- const cid = chainId ?? this.config.defaultChain;
93
- return this._query(['currency', curAddress, cid], () => defer(async () => {
255
+ return this._query(['currency', curAddress, chainId], () => defer(async () => {
94
256
  const contract = getContract({
95
257
  address: curAddress,
96
258
  abi: ABI.Currency,
97
- client: this.getClient(cid),
259
+ client: this.getClient(chainId),
98
260
  });
99
261
  const [decimals, name, symbol, supportsPermit] = await Promise.all([
100
262
  contract.read.decimals(),
101
263
  contract.read.name(),
102
264
  contract.read.symbol(),
103
- contract.read.PERMIT_TYPEHASH()
265
+ contract.read
266
+ .PERMIT_TYPEHASH()
104
267
  .then((hash) => hash === PERMIT_TYPEHASH)
105
268
  .catch(() => false),
106
269
  ]);
@@ -109,11 +272,14 @@ export class Centrifuge {
109
272
  decimals,
110
273
  name,
111
274
  symbol,
112
- chainId: cid,
275
+ chainId,
113
276
  supportsPermit,
114
277
  };
115
278
  }));
116
279
  }
280
+ investor(address) {
281
+ return this._query(null, () => of(new Investor(this, address)));
282
+ }
117
283
  /**
118
284
  * Get the balance of an ERC20 token for a given owner.
119
285
  * @param currency - The token address
@@ -122,16 +288,19 @@ export class Centrifuge {
122
288
  */
123
289
  balance(currency, owner, chainId) {
124
290
  const address = owner.toLowerCase();
125
- const cid = chainId ?? this.config.defaultChain;
126
- return this._query(['balance', currency, owner, cid], () => {
127
- return this.currency(currency, cid).pipe(switchMap((currencyMeta) => defer(() => this.getClient(cid)
128
- .readContract({
129
- address: currency,
130
- abi: ABI.Currency,
131
- functionName: 'balanceOf',
132
- args: [address],
133
- })
134
- .then((val) => new Currency(val, currencyMeta.decimals))).pipe(repeatOnEvents(this, {
291
+ return this._query(['balance', currency, owner, chainId], () => {
292
+ return this.currency(currency, chainId).pipe(switchMap((currencyMeta) => defer(async () => {
293
+ const val = await this.getClient(chainId).readContract({
294
+ address: currency,
295
+ abi: ABI.Currency,
296
+ functionName: 'balanceOf',
297
+ args: [address],
298
+ });
299
+ return {
300
+ balance: new Balance(val, currencyMeta.decimals),
301
+ currency: currencyMeta,
302
+ };
303
+ }).pipe(repeatOnEvents(this, {
135
304
  address: currency,
136
305
  abi: ABI.Currency,
137
306
  eventName: 'Transfer',
@@ -140,18 +309,148 @@ export class Centrifuge {
140
309
  return event.args.from?.toLowerCase() === address || event.args.to?.toLowerCase() === address;
141
310
  });
142
311
  },
143
- }, cid))));
312
+ }, chainId))));
144
313
  });
145
314
  }
315
+ /**
316
+ * Get the assets that exist on a given spoke chain that have been registered on a given hub chain.
317
+ * @param spokeChainId - The chain ID where the assets exist
318
+ * @param hubChainId - The chain ID where the assets should optionally be registered
319
+ */
320
+ assets(spokeChainId, hubChainId = spokeChainId) {
321
+ return this._query(null, () => combineLatest([this.id(spokeChainId), this.id(hubChainId)]).pipe(switchMap(([spokeCentId, hubCentId]) => this._queryIndexer(`query ($hubCentId: String!) {
322
+ assetRegistrations(where: { centrifugeId: $hubCentId, decimals_gt: 0 }) {
323
+ items {
324
+ assetId
325
+ name
326
+ symbol
327
+ decimals
328
+ asset {
329
+ centrifugeId
330
+ address
331
+ }
332
+ }
333
+ }
334
+ }`, { hubCentId: String(hubCentId) }, (data) => {
335
+ return data.assetRegistrations.items
336
+ .filter((assetReg) => assetReg.asset && Number(assetReg.asset.centrifugeId) === spokeCentId)
337
+ .map((assetReg) => {
338
+ return {
339
+ id: new AssetId(assetReg.assetId),
340
+ address: assetReg.asset.address,
341
+ name: assetReg.name,
342
+ symbol: assetReg.symbol,
343
+ decimals: assetReg.decimals,
344
+ };
345
+ });
346
+ }))));
347
+ }
348
+ /**
349
+ * Get the valuation addresses that can be used for holdings.
350
+ */
351
+ valuations(chainId) {
352
+ return this._query(null, () => this._protocolAddresses(chainId).pipe(map(({ identityValuation }) => {
353
+ return {
354
+ identityValuation,
355
+ };
356
+ })));
357
+ }
358
+ /**
359
+ * Get the restriction hook addresses that can be used for share tokens.
360
+ */
361
+ restrictionHooks(chainId) {
362
+ return this._query(null, () => this._protocolAddresses(chainId).pipe(map(({ freezeOnlyHook, redemptionRestrictionsHook, fullRestrictionsHook /* freelyTransferableHook */ }) => {
363
+ return {
364
+ freezeOnlyHook,
365
+ redemptionRestrictionsHook,
366
+ fullRestrictionsHook,
367
+ };
368
+ })));
369
+ }
370
+ /**
371
+ * Register an asset
372
+ * @param originChainId - The chain ID where the asset exists
373
+ * @param registerOnChainId - The chain ID where the asset should be registered
374
+ * @param assetAddress - The address of the asset to register
375
+ * @param tokenId - Optional token ID for ERC6909 assets
376
+ */
377
+ registerAsset(originChainId, registerOnChainId, assetAddress, tokenId = 0) {
378
+ const self = this;
379
+ return this._transact(async function* ({ walletClient, publicClient }) {
380
+ const [addresses, id, estimate] = await Promise.all([
381
+ self._protocolAddresses(originChainId),
382
+ self.id(registerOnChainId),
383
+ self._estimate(originChainId, { chainId: registerOnChainId }, MessageType.RegisterAsset),
384
+ ]);
385
+ yield* doTransaction('Register asset', publicClient, () => walletClient.writeContract({
386
+ address: addresses.spoke,
387
+ abi: ABI.Spoke,
388
+ functionName: 'registerAsset',
389
+ args: [id, assetAddress, BigInt(tokenId)],
390
+ value: estimate,
391
+ }));
392
+ }, originChainId);
393
+ }
394
+ /**
395
+ * Get the decimals of asset
396
+ */
397
+ assetDecimals(assetId, chainId) {
398
+ return this._query(['assetDecimals', assetId.toString()], () => this._protocolAddresses(chainId).pipe(switchMap(({ hubRegistry }) => this.getClient(chainId).readContract({
399
+ address: hubRegistry,
400
+ // Use inline ABI because of function overload
401
+ abi: parseAbi(['function decimals(uint128) view returns (uint8)']),
402
+ functionName: 'decimals',
403
+ args: [assetId.raw],
404
+ }))));
405
+ }
406
+ /**
407
+ * Get the allowance of an ERC20 or ERC6909 token.
408
+ * which is the contract that moves funds into the vault on behalf of the investor.
409
+ * @param owner - The address of the owner
410
+ * @param spender - The address of the spender
411
+ * @param chainId - The chain ID where the asset is located
412
+ * @param asset - The address of the asset
413
+ * @param tokenId - Optional token ID for ERC6909 assets
414
+ * @internal
415
+ */
416
+ _allowance(owner, spender, chainId, asset, tokenId) {
417
+ return this._query(['allowance', owner.toLowerCase(), spender.toLowerCase(), asset.toLowerCase(), chainId, tokenId], () => defer(async () => {
418
+ const client = this.getClient(chainId);
419
+ if (tokenId) {
420
+ return client.readContract({
421
+ address: asset,
422
+ abi: ABI.ERC6909,
423
+ functionName: 'allowance',
424
+ args: [owner, spender, tokenId],
425
+ });
426
+ }
427
+ return client.readContract({
428
+ address: asset,
429
+ abi: ABI.Currency,
430
+ functionName: 'allowance',
431
+ args: [owner, spender],
432
+ });
433
+ }).pipe(repeatOnEvents(this, {
434
+ address: asset,
435
+ abi: [ABI.Currency, ABI.ERC6909],
436
+ eventName: ['Approval', 'Transfer'],
437
+ filter: (events) => {
438
+ return events.some((event) => {
439
+ return (event.args.owner?.toLowerCase() === owner.toLowerCase() ||
440
+ event.args.spender?.toLowerCase() === owner.toLowerCase() ||
441
+ event.args.from?.toLowerCase() === owner.toLowerCase());
442
+ });
443
+ },
444
+ }, chainId)));
445
+ }
146
446
  /**
147
447
  * Returns an observable of all events on a given chain.
148
448
  * @internal
149
449
  */
150
450
  _events(chainId) {
151
- const cid = chainId ?? this.config.defaultChain;
152
- return this._query(['events', cid], () => using(() => {
451
+ return this._query(['events', chainId], () => using(() => {
153
452
  const subject = new Subject();
154
- const unwatch = this.getClient(cid).watchEvent({
453
+ const unwatch = this.getClient(chainId).watchEvent({
155
454
  onLogs: (logs) => subject.next(logs),
156
455
  });
157
456
  return {
@@ -199,30 +498,26 @@ export class Centrifuge {
199
498
  });
200
499
  }
201
500
  _queryIndexer(query, variables, postProcess) {
202
- return this._query([query, variables], () => this._getIndexerObservable(query, variables).pipe(map(postProcess ?? identity)), {
203
- valueCacheTime: 120,
204
- });
205
- }
206
- /**
207
- * @internal
208
- */
209
- _getIPFSObservable(hash) {
210
- return fromFetch(`${this.config.ipfsUrl}/ipfs/${hash}`, {
211
- method: 'GET',
212
- selector: async (res) => {
213
- if (!res.ok) {
214
- console.warn(`Failed to fetch IPFS data: ${res.statusText}`);
215
- }
216
- const data = await res.json();
217
- return data;
218
- },
219
- });
501
+ return this._query([query, variables], () =>
502
+ // If subscribed, refetch every 2 minutes
503
+ timer(0, 120_000).pipe(switchMap(() => this._getIndexerObservable(query, variables).pipe(map(postProcess ?? identity)))));
220
504
  }
221
505
  /**
222
506
  * @internal
223
507
  */
224
508
  _queryIPFS(hash) {
225
- return this._query([hash], () => this._getIPFSObservable(hash));
509
+ return this._query([hash], () => defer(async () => {
510
+ const url = getUrlFromHash(hash, this.#config.ipfsUrl);
511
+ if (!url) {
512
+ throw new Error(`Invalid IPFS hash: ${hash}`);
513
+ }
514
+ const res = await fetch(url);
515
+ if (!res.ok) {
516
+ throw new Error(`Error fetching IPFS hash ${hash}: ${res.statusText}`);
517
+ }
518
+ const data = (await res.json());
519
+ return data;
520
+ }));
226
521
  }
227
522
  #memoized = new Map();
228
523
  #memoizeWith(keys, callback) {
@@ -289,10 +584,9 @@ export class Centrifuge {
289
584
  * const chainId = 1
290
585
  *
291
586
  * // Wrap an observable that only emits one value and then completes
292
- * //
293
587
  * const query = this._query(['balance', address, tUSD, chainId], () => {
294
588
  * return defer(() => fetchBalance(address, tUSD, chainId))
295
- * }, { valueCacheTime: 60 })
589
+ * }, { valueCacheTime: 60_000 })
296
590
  *
297
591
  * // Logs the current balance and updated balances whenever a new
298
592
  * const obs1 = query.subscribe(balance => console.log(balance))
@@ -316,14 +610,17 @@ export class Centrifuge {
316
610
  * @internal
317
611
  */
318
612
  _query(keys, observableCallback, options) {
613
+ const cache = options?.cache !== false && this.#config.cache !== false;
614
+ const obsCacheTime = options?.observableCacheTime ?? this.#config.pollingInterval ?? 4000;
319
615
  function get() {
320
616
  const sharedSubject = new Subject();
321
617
  function createShared() {
322
618
  const $shared = observableCallback().pipe(keys
323
619
  ? shareReplayWithDelayedReset({
324
- bufferSize: (options?.cache ?? true) ? 1 : 0,
325
- resetDelay: (options?.cache === false ? 0 : (options?.observableCacheTime ?? 60)) * 1000,
326
- windowTime: (options?.valueCacheTime ?? Infinity) * 1000,
620
+ bufferSize: cache ? 1 : 0,
621
+ resetDelay: cache ? obsCacheTime : 0,
622
+ // TODO: Fix valueCacheTime to not cause an infinite loop when the value is expired.
623
+ // windowTime: options?.valueCacheTime ?? Infinity,
327
624
  })
328
625
  : map((val) => val));
329
626
  sharedSubject.next($shared);
@@ -343,50 +640,9 @@ export class Centrifuge {
343
640
  return keys ? this.#memoizeWith(keys, get) : get();
344
641
  }
345
642
  /**
346
- * Executes a transaction on a given chain.
347
- * When subscribed to, it emits status updates as it progresses.
348
- * When awaited, it returns the final confirmed if successful.
349
- * Will additionally prompt the user to switch chains if they're not on the correct chain.
350
- *
351
- * @example
352
- * ```ts
353
- * const tx = this._transact(
354
- * 'Transfer',
355
- * ({ walletClient }) =>
356
- * walletClient.writeContract({
357
- * address: '0xabc...123',
358
- * abi: ABI.Currency,
359
- * functionName: 'transfer',
360
- * args: ['0xdef...456', 1000000n],
361
- * }),
362
- * 1
363
- * )
364
- * tx.subscribe(status => console.log(status))
365
- *
366
- * // Results in something like the following values being emitted (assuming the user wasn't connected to mainnet):
367
- * // { type: 'SwitchingChain', chainId: 1 }
368
- * // { type: 'SigningTransaction', title: 'Transfer' }
369
- * // { type: 'TransactionPending', title: 'Transfer', hash: '0x123...abc' }
370
- * // { type: 'TransactionConfirmed', title: 'Transfer', hash: '0x123...abc', receipt: { ... } }
371
- * ```
372
- *
373
- * ```ts
374
- * const finalResult = await this._transact(...)
375
- * console.log(finalResult) // { type: 'TransactionConfirmed', title: 'Transfer', hash: '0x123...abc', receipt: { ... } }
376
- * ```
377
- *
378
- * @internal
379
- */
380
- _transact(title, transactionCallback, chainId) {
381
- return this._transactSequence(async function* (params) {
382
- const transaction = transactionCallback(params);
383
- yield* doTransaction(title, params.publicClient, () => transaction);
384
- }, chainId);
385
- }
386
- /**
387
- * Executes a sequence of transactions on a given chain.
643
+ * Executes one or more transactions on a given chain.
388
644
  * When subscribed to, it emits status updates as it progresses.
389
- * When awaited, it returns the final confirmed if successful.
645
+ * When awaited, it returns the final confirmed result if successful.
390
646
  * Will additionally prompt the user to switch chains if they're not on the correct chain.
391
647
  *
392
648
  * @example
@@ -413,41 +669,53 @@ export class Centrifuge {
413
669
  * // { type: 'SigningTransaction', title: 'Invest' }
414
670
  * // { type: 'TransactionPending', title: 'Invest', hash: '0x123...abc' }
415
671
  * // { type: 'TransactionConfirmed', title: 'Invest', hash: '0x123...abc', receipt: { ... } }
672
+ * ```
416
673
  *
417
674
  * @internal
418
675
  */
419
- _transactSequence(transactionCallback, chainId) {
420
- const targetChainId = chainId ?? this.config.defaultChain;
676
+ _transact(transactionCallback, chainId) {
421
677
  const self = this;
422
678
  async function* transact() {
679
+ let isBatching = false;
680
+ if (self.#isBatching.has($tx)) {
681
+ isBatching = true;
682
+ }
423
683
  const { signer } = self;
424
684
  if (!signer)
425
685
  throw new Error('Signer not set');
426
- const publicClient = self.getClient(targetChainId);
427
- const chain = self.getChainConfig(targetChainId);
428
- const bareWalletClient = isLocalAccount(signer)
429
- ? createWalletClient({ account: signer, chain, transport: http(self.#config.rpcUrls?.[chain.id]) })
686
+ const publicClient = self.getClient(chainId);
687
+ const chain = self.getChainConfig(chainId);
688
+ let walletClient = isLocalAccount(signer)
689
+ ? createWalletClient({
690
+ account: signer,
691
+ chain,
692
+ transport: http(),
693
+ })
430
694
  : createWalletClient({ transport: custom(signer) });
431
- const [address] = await bareWalletClient.getAddresses();
695
+ const [address] = await walletClient.getAddresses();
432
696
  if (!address)
433
697
  throw new Error('No account selected');
434
- const selectedChain = await bareWalletClient.getChainId();
435
- if (selectedChain !== targetChainId) {
436
- yield { type: 'SwitchingChain', chainId: targetChainId };
437
- await bareWalletClient.switchChain({ id: targetChainId });
698
+ if (!isBatching) {
699
+ const selectedChain = await walletClient.getChainId();
700
+ if (selectedChain !== chainId) {
701
+ yield { type: 'SwitchingChain', chainId };
702
+ await walletClient.switchChain({ id: chainId });
703
+ }
438
704
  }
439
705
  // Re-create the wallet client with the correct chain and account
440
706
  // Saves having to pass `account` and `chain` to every `writeContract` call
441
- const walletClient = isLocalAccount(signer)
442
- ? bareWalletClient
707
+ walletClient = isLocalAccount(signer)
708
+ ? walletClient
443
709
  : createWalletClient({ account: address, chain, transport: custom(signer) });
444
710
  const transaction = transactionCallback({
711
+ isBatching,
445
712
  signingAddress: address,
446
713
  chain,
447
- chainId: targetChainId,
714
+ chainId,
448
715
  publicClient,
449
716
  walletClient,
450
717
  signer,
718
+ root: self,
451
719
  });
452
720
  if (Symbol.asyncIterator in transaction) {
453
721
  yield* transaction;
@@ -460,7 +728,171 @@ export class Centrifuge {
460
728
  }
461
729
  }
462
730
  const $tx = defer(transact).pipe(mergeMap((d) => (isObservable(d) ? d : of(d))));
463
- return makeThenable($tx, true);
731
+ makeThenable($tx, true);
732
+ Object.assign($tx, {
733
+ chainId,
734
+ });
735
+ return $tx;
736
+ }
737
+ /**
738
+ * Batch multiple transactions together into a single transaction.
739
+ * It's not exposed, because it is somewhat limited and requires knowledge of internals.
740
+ * It only works when there's only a single transaction being done in the method.
741
+ * It only works for methods that wrap the transaction in `wrapTransaction`.
742
+ * It only works when the transactions are executed on the same contract on the same chain,
743
+ * and that contract supports multicall
744
+ * @internal
745
+ */
746
+ _experimental_batch(title, transactions) {
747
+ const chainIds = [...new Set(transactions.map((tx) => tx.chainId))];
748
+ if (chainIds.length !== 1) {
749
+ throw new Error(`Cannot batch transactions on different chains: ${chainIds.join(', ')}`);
750
+ }
751
+ for (const tx of transactions) {
752
+ this.#isBatching.add(tx);
753
+ }
754
+ return this._transact((ctx) => combineLatest(transactions.map((tx) => tx.pipe(first()))).pipe(switchMap(async function* (batches_) {
755
+ const batches = batches_;
756
+ if (!batches.every((b) => b.data && b.contract)) {
757
+ throw new Error('Not all transactions can be batched');
758
+ }
759
+ const value = batches.reduce((acc, b) => acc + (b.value ?? 0n), 0n);
760
+ const data = batches.map((b) => b.data).flat();
761
+ const messages = batches.reduce((acc, b) => {
762
+ if (b.messages) {
763
+ Object.entries(b.messages).forEach(([cid, types]) => {
764
+ const chainId = Number(cid);
765
+ if (!acc[chainId])
766
+ acc[chainId] = [];
767
+ acc[chainId].push(...types);
768
+ });
769
+ }
770
+ return acc;
771
+ }, {});
772
+ const contracts = [...new Set(batches.map((b) => b.contract))];
773
+ if (contracts.length !== 1) {
774
+ throw new Error(`Cannot batch transactions to different contracts: ${contracts.join(', ')}`);
775
+ }
776
+ yield* wrapTransaction(title, ctx, { data, value, contract: contracts[0], messages });
777
+ })), chainIds[0]);
778
+ }
779
+ /** @internal */
780
+ _protocolAddresses(chainId) {
781
+ return this._query(['protocolAddresses'], () => this._getIndexerObservable(`{
782
+ deployments {
783
+ items {
784
+ accounting
785
+ asyncRequestManager
786
+ asyncVaultFactory
787
+ axelarAdapter
788
+ balanceSheet
789
+ centrifugeId
790
+ chainId
791
+ freezeOnlyHook
792
+ fullRestrictionsHook
793
+ gasService
794
+ gateway
795
+ globalEscrow
796
+ guardian
797
+ holdings
798
+ hub
799
+ hubRegistry
800
+ identityValuation
801
+ messageDispatcher
802
+ messageProcessor
803
+ multiAdapter
804
+ poolEscrowFactory
805
+ redemptionRestrictionsHook
806
+ root
807
+ routerEscrow
808
+ shareClassManager
809
+ spoke
810
+ syncDepositVaultFactory
811
+ syncManager
812
+ wormholeAdapter
813
+ vaultRouter
814
+ tokenFactory
815
+ }
816
+ }
817
+ }`, { chainId: String(chainId) }).pipe(map((data) => {
818
+ if (!this.chains.includes(chainId)) {
819
+ throw new Error(`Chain ID "${chainId}" not supported`);
820
+ }
821
+ const deployment = data.deployments.items.find((d) => Number(d.chainId) === chainId);
822
+ if (!deployment) {
823
+ throw new Error(`No protocol contracts found for chain ID "${chainId}"`);
824
+ }
825
+ return deployment;
826
+ })));
827
+ }
828
+ /** @internal */
829
+ _getQuote(valuationAddress, baseAmount, baseAssetId, quoteAssetId, chainId) {
830
+ return this._query(['getQuote', baseAmount, baseAssetId.toString(), quoteAssetId.toString()], () => timer(0, 60_000).pipe(switchMap(() => this._protocolAddresses(chainId)), switchMap(({ hubRegistry }) => defer(async () => {
831
+ const [quote, quoteDecimals] = await Promise.all([
832
+ this.getClient(chainId).readContract({
833
+ address: valuationAddress,
834
+ abi: ABI.Valuation,
835
+ functionName: 'getQuote',
836
+ args: [baseAmount.toBigInt(), baseAssetId.raw, quoteAssetId.raw],
837
+ }),
838
+ this.getClient(chainId).readContract({
839
+ address: hubRegistry,
840
+ // Use inline ABI because of function overload
841
+ abi: parseAbi(['function decimals(uint256) view returns (uint8)']),
842
+ functionName: 'decimals',
843
+ args: [quoteAssetId.raw],
844
+ }),
845
+ ]);
846
+ return new Balance(quote, quoteDecimals);
847
+ }))));
848
+ }
849
+ /**
850
+ * Estimates the gas cost needed to bridge the message from one chain to another,
851
+ * that results from a transaction
852
+ * @internal
853
+ */
854
+ _estimate(fromChain, to, messageType) {
855
+ return this._query(['estimate', fromChain, to], () => this._protocolAddresses(fromChain).pipe(switchMap(({ multiAdapter, gasService }) => {
856
+ const types = Array.isArray(messageType) ? messageType : [messageType];
857
+ return combineLatest([
858
+ 'chainId' in to ? this.id(to.chainId) : of(to.centId),
859
+ ...types.map((type) => this.getClient(fromChain).readContract({
860
+ address: gasService,
861
+ abi: ABI.GasService,
862
+ functionName: 'batchGasLimit',
863
+ args: [type],
864
+ })),
865
+ ]).pipe(switchMap(([toCentId, ...gasLimits]) => {
866
+ return this.getClient(fromChain).readContract({
867
+ address: multiAdapter,
868
+ abi: ABI.MultiAdapter,
869
+ functionName: 'estimate',
870
+ args: [toCentId, '0x0', gasLimits.reduce((acc, val) => acc + val, 0n)],
871
+ });
872
+ }));
873
+ })));
874
+ }
875
+ /**
876
+ * Get the asset address and token ID for a given asset ID on a specific chain.
877
+ * @param assetId - The asset ID to query
878
+ * @param chainId - The chain ID of the Spoke where the asset was registered
879
+ * @internal
880
+ */
881
+ _asset(assetId, chainId) {
882
+ return this._query(['asset', assetId.toString(), chainId], () => this._protocolAddresses(chainId).pipe(switchMap(async ({ spoke }) => {
883
+ const [assetAddress, tokenId] = await this.getClient(chainId).readContract({
884
+ address: spoke,
885
+ abi: ABI.Spoke,
886
+ functionName: 'idToAsset',
887
+ args: [assetId.raw],
888
+ });
889
+ if (assetAddress === NULL_ADDRESS)
890
+ throw new Error(`Asset with ID "${assetId}" not found on chain "${chainId}"`);
891
+ return {
892
+ address: assetAddress,
893
+ tokenId,
894
+ };
895
+ })));
464
896
  }
465
897
  }
466
898
  //# sourceMappingURL=Centrifuge.js.map