@andrewkimjoseph/celina-sdk 0.9.7 → 0.9.9

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 (365) hide show
  1. package/build/analytics/mcp-tool-events.js +2 -0
  2. package/build/analytics/mcp-tool-events.js.map +1 -1
  3. package/build/index.d.ts +1 -1
  4. package/build/services/gooddollar.service.d.ts +16 -2
  5. package/build/services/gooddollar.service.js +54 -31
  6. package/build/services/gooddollar.service.js.map +1 -1
  7. package/build/src/a2a/agent-card.d.ts +37 -0
  8. package/build/src/a2a/agent-card.js +46 -0
  9. package/build/src/a2a/agent-card.js.map +1 -0
  10. package/build/src/a2a/index.d.ts +2 -0
  11. package/build/src/a2a/index.js +3 -0
  12. package/build/src/a2a/index.js.map +1 -0
  13. package/build/src/a2a/skills.d.ts +18 -0
  14. package/build/src/a2a/skills.js +101 -0
  15. package/build/src/a2a/skills.js.map +1 -0
  16. package/build/src/abis/aave-pool.d.ts +37 -0
  17. package/build/src/abis/aave-pool.js +26 -0
  18. package/build/src/abis/aave-pool.js.map +1 -0
  19. package/build/src/abis/accounts.d.ts +13 -0
  20. package/build/src/abis/accounts.js +10 -0
  21. package/build/src/abis/accounts.js.map +1 -0
  22. package/build/src/abis/election.d.ts +124 -0
  23. package/build/src/abis/election.js +88 -0
  24. package/build/src/abis/election.js.map +1 -0
  25. package/build/src/abis/gooddollar-broker.d.ts +77 -0
  26. package/build/src/abis/gooddollar-broker.js +44 -0
  27. package/build/src/abis/gooddollar-broker.js.map +1 -0
  28. package/build/src/abis/gooddollar-identity.d.ts +85 -0
  29. package/build/src/abis/gooddollar-identity.js +52 -0
  30. package/build/src/abis/gooddollar-identity.js.map +1 -0
  31. package/build/src/abis/governance.d.ts +86 -0
  32. package/build/src/abis/governance.js +68 -0
  33. package/build/src/abis/governance.js.map +1 -0
  34. package/build/src/abis/locked-gold.d.ts +10 -0
  35. package/build/src/abis/locked-gold.js +10 -0
  36. package/build/src/abis/locked-gold.js.map +1 -0
  37. package/build/src/abis/nft.d.ts +107 -0
  38. package/build/src/abis/nft.js +75 -0
  39. package/build/src/abis/nft.js.map +1 -0
  40. package/build/src/abis/permit2.d.ts +43 -0
  41. package/build/src/abis/permit2.js +30 -0
  42. package/build/src/abis/permit2.js.map +1 -0
  43. package/build/src/abis/self-registry.d.ts +194 -0
  44. package/build/src/abis/self-registry.js +120 -0
  45. package/build/src/abis/self-registry.js.map +1 -0
  46. package/build/src/abis/ubi-scheme.d.ts +91 -0
  47. package/build/src/abis/ubi-scheme.js +66 -0
  48. package/build/src/abis/ubi-scheme.js.map +1 -0
  49. package/build/src/abis/uniswap-state-view.d.ts +34 -0
  50. package/build/src/abis/uniswap-state-view.js +22 -0
  51. package/build/src/abis/uniswap-state-view.js.map +1 -0
  52. package/build/src/abis/uniswap-v4-quoter.d.ts +86 -0
  53. package/build/src/abis/uniswap-v4-quoter.js +64 -0
  54. package/build/src/abis/uniswap-v4-quoter.js.map +1 -0
  55. package/build/src/abis/universal-router.d.ts +16 -0
  56. package/build/src/abis/universal-router.js +14 -0
  57. package/build/src/abis/universal-router.js.map +1 -0
  58. package/build/src/abis/validators-minimal.d.ts +65 -0
  59. package/build/src/abis/validators-minimal.js +39 -0
  60. package/build/src/abis/validators-minimal.js.map +1 -0
  61. package/build/src/analytics/amplitude.d.ts +11 -0
  62. package/build/src/analytics/amplitude.js +76 -0
  63. package/build/src/analytics/amplitude.js.map +1 -0
  64. package/build/src/analytics/config.d.ts +7 -0
  65. package/build/src/analytics/config.js +28 -0
  66. package/build/src/analytics/config.js.map +1 -0
  67. package/build/src/analytics/consumer-package.d.ts +9 -0
  68. package/build/src/analytics/consumer-package.js +143 -0
  69. package/build/src/analytics/consumer-package.js.map +1 -0
  70. package/build/src/analytics/mcp-tool-events.d.ts +5 -0
  71. package/build/src/analytics/mcp-tool-events.js +53 -0
  72. package/build/src/analytics/mcp-tool-events.js.map +1 -0
  73. package/build/src/analytics/wallet-context.d.ts +11 -0
  74. package/build/src/analytics/wallet-context.js +81 -0
  75. package/build/src/analytics/wallet-context.js.map +1 -0
  76. package/build/src/analytics/wallet-extract.d.ts +9 -0
  77. package/build/src/analytics/wallet-extract.js +21 -0
  78. package/build/src/analytics/wallet-extract.js.map +1 -0
  79. package/build/src/analytics/wrap-service.d.ts +5 -0
  80. package/build/src/analytics/wrap-service.js +38 -0
  81. package/build/src/analytics/wrap-service.js.map +1 -0
  82. package/build/src/clients/celo-client.d.ts +17 -0
  83. package/build/src/clients/celo-client.js +28 -0
  84. package/build/src/clients/celo-client.js.map +1 -0
  85. package/build/src/clients/ens-client.d.ts +17 -0
  86. package/build/src/clients/ens-client.js +30 -0
  87. package/build/src/clients/ens-client.js.map +1 -0
  88. package/build/src/clients/mento-sdk.d.ts +2 -0
  89. package/build/src/clients/mento-sdk.js +9 -0
  90. package/build/src/clients/mento-sdk.js.map +1 -0
  91. package/build/src/clients/self-api.d.ts +82 -0
  92. package/build/src/clients/self-api.js +242 -0
  93. package/build/src/clients/self-api.js.map +1 -0
  94. package/build/src/clients/uniswap-sdk.d.ts +4 -0
  95. package/build/src/clients/uniswap-sdk.js +13 -0
  96. package/build/src/clients/uniswap-sdk.js.map +1 -0
  97. package/build/src/config/aave.d.ts +17 -0
  98. package/build/src/config/aave.js +77 -0
  99. package/build/src/config/aave.js.map +1 -0
  100. package/build/src/config/celina-tag.d.ts +4 -0
  101. package/build/src/config/celina-tag.js +13 -0
  102. package/build/src/config/celina-tag.js.map +1 -0
  103. package/build/src/config/celo-core-contracts.d.ts +8 -0
  104. package/build/src/config/celo-core-contracts.js +9 -0
  105. package/build/src/config/celo-core-contracts.js.map +1 -0
  106. package/build/src/config/chains.d.ts +937 -0
  107. package/build/src/config/chains.js +319 -0
  108. package/build/src/config/chains.js.map +1 -0
  109. package/build/src/config/gooddollar.d.ts +16 -0
  110. package/build/src/config/gooddollar.js +24 -0
  111. package/build/src/config/gooddollar.js.map +1 -0
  112. package/build/src/config/sdk-config.d.ts +33 -0
  113. package/build/src/config/sdk-config.js +31 -0
  114. package/build/src/config/sdk-config.js.map +1 -0
  115. package/build/src/config/self.d.ts +22 -0
  116. package/build/src/config/self.js +27 -0
  117. package/build/src/config/self.js.map +1 -0
  118. package/build/src/config/uniswap.d.ts +42 -0
  119. package/build/src/config/uniswap.js +76 -0
  120. package/build/src/config/uniswap.js.map +1 -0
  121. package/build/src/index.d.ts +90 -0
  122. package/build/src/index.js +65 -0
  123. package/build/src/index.js.map +1 -0
  124. package/build/src/oasf/index.d.ts +2 -0
  125. package/build/src/oasf/index.js +3 -0
  126. package/build/src/oasf/index.js.map +1 -0
  127. package/build/src/oasf/record.d.ts +39 -0
  128. package/build/src/oasf/record.js +35 -0
  129. package/build/src/oasf/record.js.map +1 -0
  130. package/build/src/oasf/taxonomy.d.ts +19 -0
  131. package/build/src/oasf/taxonomy.js +46 -0
  132. package/build/src/oasf/taxonomy.js.map +1 -0
  133. package/build/src/services/aave.service.d.ts +58 -0
  134. package/build/src/services/aave.service.js +210 -0
  135. package/build/src/services/aave.service.js.map +1 -0
  136. package/build/src/services/account.service.d.ts +22 -0
  137. package/build/src/services/account.service.js +29 -0
  138. package/build/src/services/account.service.js.map +1 -0
  139. package/build/src/services/blockchain.service.d.ts +107 -0
  140. package/build/src/services/blockchain.service.js +151 -0
  141. package/build/src/services/blockchain.service.js.map +1 -0
  142. package/build/src/services/contract.service.d.ts +78 -0
  143. package/build/src/services/contract.service.js +117 -0
  144. package/build/src/services/contract.service.js.map +1 -0
  145. package/build/src/services/ens.service.d.ts +44 -0
  146. package/build/src/services/ens.service.js +92 -0
  147. package/build/src/services/ens.service.js.map +1 -0
  148. package/build/src/services/gooddollar.service.d.ts +183 -0
  149. package/build/src/services/gooddollar.service.js +675 -0
  150. package/build/src/services/gooddollar.service.js.map +1 -0
  151. package/build/src/services/governance.service.d.ts +96 -0
  152. package/build/src/services/governance.service.js +255 -0
  153. package/build/src/services/governance.service.js.map +1 -0
  154. package/build/src/services/mento-fx.service.d.ts +80 -0
  155. package/build/src/services/mento-fx.service.js +319 -0
  156. package/build/src/services/mento-fx.service.js.map +1 -0
  157. package/build/src/services/nft.service.d.ts +58 -0
  158. package/build/src/services/nft.service.js +222 -0
  159. package/build/src/services/nft.service.js.map +1 -0
  160. package/build/src/services/self-session-store.d.ts +19 -0
  161. package/build/src/services/self-session-store.js +28 -0
  162. package/build/src/services/self-session-store.js.map +1 -0
  163. package/build/src/services/self.service.d.ts +241 -0
  164. package/build/src/services/self.service.js +699 -0
  165. package/build/src/services/self.service.js.map +1 -0
  166. package/build/src/services/staking.service.d.ts +140 -0
  167. package/build/src/services/staking.service.js +444 -0
  168. package/build/src/services/staking.service.js.map +1 -0
  169. package/build/src/services/token.service.d.ts +110 -0
  170. package/build/src/services/token.service.js +189 -0
  171. package/build/src/services/token.service.js.map +1 -0
  172. package/build/src/services/transaction.service.d.ts +68 -0
  173. package/build/src/services/transaction.service.js +198 -0
  174. package/build/src/services/transaction.service.js.map +1 -0
  175. package/build/src/services/uniswap-path-router.d.ts +40 -0
  176. package/build/src/services/uniswap-path-router.js +168 -0
  177. package/build/src/services/uniswap-path-router.js.map +1 -0
  178. package/build/src/services/uniswap-pool-discovery.d.ts +55 -0
  179. package/build/src/services/uniswap-pool-discovery.js +198 -0
  180. package/build/src/services/uniswap-pool-discovery.js.map +1 -0
  181. package/build/src/services/uniswap.service.d.ts +82 -0
  182. package/build/src/services/uniswap.service.js +352 -0
  183. package/build/src/services/uniswap.service.js.map +1 -0
  184. package/build/src/simulation/index.d.ts +5 -0
  185. package/build/src/simulation/index.js +2 -0
  186. package/build/src/simulation/index.js.map +1 -0
  187. package/build/src/simulation/simulate-prepared-step.d.ts +17 -0
  188. package/build/src/simulation/simulate-prepared-step.js +42 -0
  189. package/build/src/simulation/simulate-prepared-step.js.map +1 -0
  190. package/build/src/tools/catalog.d.ts +11 -0
  191. package/build/src/tools/catalog.js +43 -0
  192. package/build/src/tools/catalog.js.map +1 -0
  193. package/build/src/tools/domains/aave.d.ts +2 -0
  194. package/build/src/tools/domains/aave.js +115 -0
  195. package/build/src/tools/domains/aave.js.map +1 -0
  196. package/build/src/tools/domains/blockchain.d.ts +2 -0
  197. package/build/src/tools/domains/blockchain.js +86 -0
  198. package/build/src/tools/domains/blockchain.js.map +1 -0
  199. package/build/src/tools/domains/browser.d.ts +2 -0
  200. package/build/src/tools/domains/browser.js +45 -0
  201. package/build/src/tools/domains/browser.js.map +1 -0
  202. package/build/src/tools/domains/contract.d.ts +2 -0
  203. package/build/src/tools/domains/contract.js +67 -0
  204. package/build/src/tools/domains/contract.js.map +1 -0
  205. package/build/src/tools/domains/ens.d.ts +2 -0
  206. package/build/src/tools/domains/ens.js +16 -0
  207. package/build/src/tools/domains/ens.js.map +1 -0
  208. package/build/src/tools/domains/gooddollar.d.ts +2 -0
  209. package/build/src/tools/domains/gooddollar.js +171 -0
  210. package/build/src/tools/domains/gooddollar.js.map +1 -0
  211. package/build/src/tools/domains/governance.d.ts +2 -0
  212. package/build/src/tools/domains/governance.js +41 -0
  213. package/build/src/tools/domains/governance.js.map +1 -0
  214. package/build/src/tools/domains/index.d.ts +1 -0
  215. package/build/src/tools/domains/index.js +31 -0
  216. package/build/src/tools/domains/index.js.map +1 -0
  217. package/build/src/tools/domains/mento-fx.d.ts +2 -0
  218. package/build/src/tools/domains/mento-fx.js +67 -0
  219. package/build/src/tools/domains/mento-fx.js.map +1 -0
  220. package/build/src/tools/domains/nft.d.ts +2 -0
  221. package/build/src/tools/domains/nft.js +38 -0
  222. package/build/src/tools/domains/nft.js.map +1 -0
  223. package/build/src/tools/domains/self.d.ts +2 -0
  224. package/build/src/tools/domains/self.js +187 -0
  225. package/build/src/tools/domains/self.js.map +1 -0
  226. package/build/src/tools/domains/staking.d.ts +2 -0
  227. package/build/src/tools/domains/staking.js +74 -0
  228. package/build/src/tools/domains/staking.js.map +1 -0
  229. package/build/src/tools/domains/token.d.ts +2 -0
  230. package/build/src/tools/domains/token.js +74 -0
  231. package/build/src/tools/domains/token.js.map +1 -0
  232. package/build/src/tools/domains/transaction.d.ts +2 -0
  233. package/build/src/tools/domains/transaction.js +120 -0
  234. package/build/src/tools/domains/transaction.js.map +1 -0
  235. package/build/src/tools/domains/uniswap.d.ts +2 -0
  236. package/build/src/tools/domains/uniswap.js +67 -0
  237. package/build/src/tools/domains/uniswap.js.map +1 -0
  238. package/build/src/tools/filter.d.ts +2 -0
  239. package/build/src/tools/filter.js +50 -0
  240. package/build/src/tools/filter.js.map +1 -0
  241. package/build/src/tools/index.d.ts +7 -0
  242. package/build/src/tools/index.js +7 -0
  243. package/build/src/tools/index.js.map +1 -0
  244. package/build/src/tools/schemas/common.d.ts +165 -0
  245. package/build/src/tools/schemas/common.js +207 -0
  246. package/build/src/tools/schemas/common.js.map +1 -0
  247. package/build/src/tools/schemas/wallet-params.d.ts +9 -0
  248. package/build/src/tools/schemas/wallet-params.js +52 -0
  249. package/build/src/tools/schemas/wallet-params.js.map +1 -0
  250. package/build/src/tools/swap-routing.d.ts +25 -0
  251. package/build/src/tools/swap-routing.js +174 -0
  252. package/build/src/tools/swap-routing.js.map +1 -0
  253. package/build/src/tools/types.d.ts +124 -0
  254. package/build/src/tools/types.js +2 -0
  255. package/build/src/tools/types.js.map +1 -0
  256. package/build/src/tools/utils/normalize-token.d.ts +2 -0
  257. package/build/src/tools/utils/normalize-token.js +12 -0
  258. package/build/src/tools/utils/normalize-token.js.map +1 -0
  259. package/build/src/tools/utils/wallet.d.ts +4 -0
  260. package/build/src/tools/utils/wallet.js +8 -0
  261. package/build/src/tools/utils/wallet.js.map +1 -0
  262. package/build/src/tools/website-sync.d.ts +28 -0
  263. package/build/src/tools/website-sync.js +165 -0
  264. package/build/src/tools/website-sync.js.map +1 -0
  265. package/build/src/types/prepared.d.ts +28 -0
  266. package/build/src/types/prepared.js +12 -0
  267. package/build/src/types/prepared.js.map +1 -0
  268. package/build/src/utils/celo-format.d.ts +6 -0
  269. package/build/src/utils/celo-format.js +17 -0
  270. package/build/src/utils/celo-format.js.map +1 -0
  271. package/build/src/utils/erc20-allowance-storage.d.ts +20 -0
  272. package/build/src/utils/erc20-allowance-storage.js +64 -0
  273. package/build/src/utils/erc20-allowance-storage.js.map +1 -0
  274. package/build/src/utils/format-date.d.ts +2 -0
  275. package/build/src/utils/format-date.js +13 -0
  276. package/build/src/utils/format-date.js.map +1 -0
  277. package/build/src/utils/format-duration.d.ts +2 -0
  278. package/build/src/utils/format-duration.js +17 -0
  279. package/build/src/utils/format-duration.js.map +1 -0
  280. package/build/src/utils/format-unix-datetime.d.ts +4 -0
  281. package/build/src/utils/format-unix-datetime.js +18 -0
  282. package/build/src/utils/format-unix-datetime.js.map +1 -0
  283. package/build/src/utils/gooddollar-ubi-period.d.ts +23 -0
  284. package/build/src/utils/gooddollar-ubi-period.js +23 -0
  285. package/build/src/utils/gooddollar-ubi-period.js.map +1 -0
  286. package/build/src/utils/normalize-address.d.ts +7 -0
  287. package/build/src/utils/normalize-address.js +16 -0
  288. package/build/src/utils/normalize-address.js.map +1 -0
  289. package/build/src/utils/self-format.d.ts +28 -0
  290. package/build/src/utils/self-format.js +79 -0
  291. package/build/src/utils/self-format.js.map +1 -0
  292. package/build/src/utils/self-signing.d.ts +4 -0
  293. package/build/src/utils/self-signing.js +38 -0
  294. package/build/src/utils/self-signing.js.map +1 -0
  295. package/build/src/utils/transaction-errors.d.ts +3 -0
  296. package/build/src/utils/transaction-errors.js +17 -0
  297. package/build/src/utils/transaction-errors.js.map +1 -0
  298. package/build/tests/catalog/domains/blockchain.d.ts +2 -0
  299. package/build/tests/catalog/domains/blockchain.js +127 -0
  300. package/build/tests/catalog/domains/blockchain.js.map +1 -0
  301. package/build/tests/catalog/domains/chain-ext.d.ts +5 -0
  302. package/build/tests/catalog/domains/chain-ext.js +207 -0
  303. package/build/tests/catalog/domains/chain-ext.js.map +1 -0
  304. package/build/tests/catalog/domains/defi.d.ts +6 -0
  305. package/build/tests/catalog/domains/defi.js +581 -0
  306. package/build/tests/catalog/domains/defi.js.map +1 -0
  307. package/build/tests/catalog/domains/self.d.ts +2 -0
  308. package/build/tests/catalog/domains/self.js +208 -0
  309. package/build/tests/catalog/domains/self.js.map +1 -0
  310. package/build/tests/catalog/domains/token.d.ts +2 -0
  311. package/build/tests/catalog/domains/token.js +70 -0
  312. package/build/tests/catalog/domains/token.js.map +1 -0
  313. package/build/tests/catalog/domains/transaction.d.ts +2 -0
  314. package/build/tests/catalog/domains/transaction.js +96 -0
  315. package/build/tests/catalog/domains/transaction.js.map +1 -0
  316. package/build/tests/catalog/index.d.ts +2 -0
  317. package/build/tests/catalog/index.js +2 -0
  318. package/build/tests/catalog/index.js.map +1 -0
  319. package/build/tests/catalog/operations.d.ts +12 -0
  320. package/build/tests/catalog/operations.js +29 -0
  321. package/build/tests/catalog/operations.js.map +1 -0
  322. package/build/tests/catalog/types.d.ts +24 -0
  323. package/build/tests/catalog/types.js +2 -0
  324. package/build/tests/catalog/types.js.map +1 -0
  325. package/build/tests/fixtures/mainnet.d.ts +54 -0
  326. package/build/tests/fixtures/mainnet.js +53 -0
  327. package/build/tests/fixtures/mainnet.js.map +1 -0
  328. package/build/tests/helpers/assert.d.ts +4 -0
  329. package/build/tests/helpers/assert.js +24 -0
  330. package/build/tests/helpers/assert.js.map +1 -0
  331. package/build/tests/helpers/env.d.ts +11 -0
  332. package/build/tests/helpers/env.js +28 -0
  333. package/build/tests/helpers/env.js.map +1 -0
  334. package/build/tests/helpers/gating.d.ts +3 -0
  335. package/build/tests/helpers/gating.js +23 -0
  336. package/build/tests/helpers/gating.js.map +1 -0
  337. package/build/tests/testing-entry.d.ts +6 -0
  338. package/build/tests/testing-entry.js +6 -0
  339. package/build/tests/testing-entry.js.map +1 -0
  340. package/build/tools/domains/browser.js +4 -1
  341. package/build/tools/domains/browser.js.map +1 -1
  342. package/build/tools/domains/gooddollar.js +11 -7
  343. package/build/tools/domains/gooddollar.js.map +1 -1
  344. package/build/tools/schemas/common.d.ts +7 -0
  345. package/build/tools/schemas/common.js +9 -1
  346. package/build/tools/schemas/common.js.map +1 -1
  347. package/build/tools/swap-routing.d.ts +1 -0
  348. package/build/tools/swap-routing.js +2 -1
  349. package/build/tools/swap-routing.js.map +1 -1
  350. package/package.json +5 -9
  351. package/tests/README.md +0 -78
  352. package/tests/catalog/domains/blockchain.ts +0 -133
  353. package/tests/catalog/domains/chain-ext.ts +0 -219
  354. package/tests/catalog/domains/defi.ts +0 -532
  355. package/tests/catalog/domains/self.ts +0 -220
  356. package/tests/catalog/domains/token.ts +0 -74
  357. package/tests/catalog/domains/transaction.ts +0 -111
  358. package/tests/catalog/index.ts +0 -7
  359. package/tests/catalog/operations.ts +0 -53
  360. package/tests/catalog/types.ts +0 -27
  361. package/tests/fixtures/mainnet.ts +0 -93
  362. package/tests/helpers/assert.ts +0 -30
  363. package/tests/helpers/env.ts +0 -38
  364. package/tests/helpers/gating.ts +0 -36
  365. package/tests/testing-entry.ts +0 -27
@@ -0,0 +1,675 @@
1
+ /**
2
+ * GoodDollar IdentityV4 whitelist, reverification reads, UBI claims, and reserve swaps on Celo mainnet.
3
+ */
4
+ import { concat, encodeFunctionData, erc20Abi, formatUnits, maxUint256, } from "viem";
5
+ import { goodDollarBrokerAbi } from "../abis/gooddollar-broker.js";
6
+ import { goodDollarIdentityAbi } from "../abis/gooddollar-identity.js";
7
+ import { ubiSchemeAbi } from "../abis/ubi-scheme.js";
8
+ import { GOODDOLLAR_CUSD_EXCHANGE_ID, GOODDOLLAR_IDENTITY_ADDRESS, GOODDOLLAR_MENTO_BROKER, GOODDOLLAR_MENTO_EXCHANGE_PROVIDER, GOODDOLLAR_RESERVE_COLLATERAL, GOODDOLLAR_TOKEN_ADDRESS, GOODDOLLAR_UBI_SCHEME_ADDRESS, isGoodDollarUsdReservePair, } from "../config/gooddollar.js";
9
+ import { CELINA_DATA_SUFFIX } from "../config/celina-tag.js";
10
+ import { serializePreparedFlow, } from "../types/prepared.js";
11
+ import { ALLOWANCE_MAPPING_SLOTS, erc20AllowanceStateOverride, } from "../utils/erc20-allowance-storage.js";
12
+ import { TokenService } from "./token.service.js";
13
+ import { formatUnixDate } from "../utils/format-date.js";
14
+ import { formatDuration } from "../utils/format-duration.js";
15
+ import { formatUnixDateTimeUtc, formatUnixIso, } from "../utils/format-unix-datetime.js";
16
+ import { resolveUbiPeriodEligibility } from "../utils/gooddollar-ubi-period.js";
17
+ const SECONDS_PER_DAY = 86400n;
18
+ const G_DOLLAR_DECIMALS = 18;
19
+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
20
+ const STATUS_LABELS = {
21
+ 0: "none",
22
+ 1: "whitelisted",
23
+ 2: "dao_contract",
24
+ 255: "blacklisted",
25
+ };
26
+ // Post-upgrade users authenticated before this timestamp use the last reverify step.
27
+ const LEGACY_AUTH_CUTOFF = 1772697574;
28
+ function statusLabel(status) {
29
+ return STATUS_LABELS[status] ?? "unknown";
30
+ }
31
+ function taggedCalldata(data) {
32
+ return concat([data, CELINA_DATA_SUFFIX]);
33
+ }
34
+ const DEFAULT_RESERVE_SLIPPAGE = 0.5;
35
+ function trimDisplayDecimals(value) {
36
+ const num = Number(value);
37
+ if (!Number.isFinite(num)) {
38
+ return value;
39
+ }
40
+ if (Math.abs(num) >= 1000) {
41
+ return num.toLocaleString(undefined, { maximumFractionDigits: 2 });
42
+ }
43
+ if (Math.abs(num) >= 1) {
44
+ return num.toLocaleString(undefined, { maximumFractionDigits: 4 });
45
+ }
46
+ return num.toLocaleString(undefined, { maximumSignificantDigits: 6 });
47
+ }
48
+ function applySlippage(amountOut, slippagePercent) {
49
+ const bps = BigInt(Math.round(slippagePercent * 100));
50
+ return (amountOut * (10000n - bps)) / 10000n;
51
+ }
52
+ function tokenAddress(token) {
53
+ if (token.address === "native") {
54
+ throw new Error(`${token.symbol} is native CELO; GoodDollar reserve swaps require ERC-20 tokens.`);
55
+ }
56
+ return token.address;
57
+ }
58
+ /** GoodDollar IdentityV4 whitelist, reverification, daily UBI claim, and reserve swap preparation. */
59
+ export class GoodDollarService {
60
+ clientFactory;
61
+ tokenService;
62
+ constructor(clientFactory) {
63
+ this.clientFactory = clientFactory;
64
+ this.tokenService = new TokenService(clientFactory);
65
+ }
66
+ getPublicClient() {
67
+ return this.clientFactory.getClients().public;
68
+ }
69
+ async resolveWhitelistedRoot(address) {
70
+ const client = this.getPublicClient();
71
+ const rootResult = await client.readContract({
72
+ address: GOODDOLLAR_IDENTITY_ADDRESS,
73
+ abi: goodDollarIdentityAbi,
74
+ functionName: "getWhitelistedRoot",
75
+ args: [address],
76
+ });
77
+ const root = rootResult;
78
+ const hasRoot = root !== ZERO_ADDRESS;
79
+ const identityAddress = hasRoot ? root : address;
80
+ return {
81
+ queried: address,
82
+ root: hasRoot ? root : null,
83
+ identityAddress,
84
+ isConnectedWallet: hasRoot && root.toLowerCase() !== address.toLowerCase(),
85
+ };
86
+ }
87
+ async fetchWhitelistingData(identityAddress) {
88
+ const { public: client } = this.clientFactory.getClients();
89
+ const contract = GOODDOLLAR_IDENTITY_ADDRESS;
90
+ const [identityResult, isWhitelisted, maxReverificationPeriodDays, reverifyDaysOptions,] = await Promise.all([
91
+ client.readContract({
92
+ address: contract,
93
+ abi: goodDollarIdentityAbi,
94
+ functionName: "identities",
95
+ args: [identityAddress],
96
+ }),
97
+ client.readContract({
98
+ address: contract,
99
+ abi: goodDollarIdentityAbi,
100
+ functionName: "isWhitelisted",
101
+ args: [identityAddress],
102
+ }),
103
+ client.readContract({
104
+ address: contract,
105
+ abi: goodDollarIdentityAbi,
106
+ functionName: "authenticationPeriod",
107
+ }),
108
+ this.fetchReverifyDaysOptions(client, contract),
109
+ ]);
110
+ const [dateAuthenticated, dateAdded, did, whitelistedOnChainId, status, authCount,] = identityResult;
111
+ const statusNum = Number(status);
112
+ const dateAuthenticatedNum = Number(dateAuthenticated);
113
+ const dateAddedNum = Number(dateAdded);
114
+ const authCountNum = Number(authCount);
115
+ let currentReverificationPeriodDays = null;
116
+ if (statusNum === 1 && dateAuthenticatedNum > 0 && reverifyDaysOptions.length > 0) {
117
+ const effectiveAuthCount = this.effectiveAuthCount(dateAuthenticatedNum, authCountNum, reverifyDaysOptions.length);
118
+ currentReverificationPeriodDays =
119
+ reverifyDaysOptions[effectiveAuthCount] ?? null;
120
+ }
121
+ const isWhitelistedStatus = statusNum === 1 && dateAddedNum > 0;
122
+ const reverification = statusNum === 1 && dateAuthenticatedNum > 0 && currentReverificationPeriodDays !== null
123
+ ? this.buildReverificationProgress(dateAuthenticatedNum, currentReverificationPeriodDays, Number(maxReverificationPeriodDays))
124
+ : null;
125
+ return {
126
+ contract,
127
+ isWhitelisted,
128
+ status: statusNum,
129
+ statusLabel: statusLabel(statusNum),
130
+ whitelistedOn: isWhitelistedStatus ? formatUnixDate(dateAddedNum) : null,
131
+ lastAuthenticatedOn: dateAuthenticatedNum > 0 ? formatUnixDate(dateAuthenticatedNum) : null,
132
+ fieldDescriptions: {
133
+ whitelistedOn: "When the wallet was first added to the GoodDollar whitelist.",
134
+ lastAuthenticatedOn: "When the wallet last verified its identity. Periodic reverification is required to remain whitelisted.",
135
+ },
136
+ reverification,
137
+ identity: {
138
+ dateAuthenticated: dateAuthenticatedNum,
139
+ dateAdded: dateAddedNum,
140
+ did,
141
+ whitelistedOnChainId: Number(whitelistedOnChainId),
142
+ status: statusNum,
143
+ authCount: authCountNum,
144
+ },
145
+ };
146
+ }
147
+ /**
148
+ * How a wallet links to GoodDollar IdentityV4 (root vs connected account).
149
+ * @param address - Wallet to inspect
150
+ */
151
+ async getIdentityLink(address) {
152
+ const client = this.getPublicClient();
153
+ const link = await this.resolveWhitelistedRoot(address);
154
+ const [connectedTo, isWhitelisted] = await Promise.all([
155
+ client.readContract({
156
+ address: GOODDOLLAR_IDENTITY_ADDRESS,
157
+ abi: goodDollarIdentityAbi,
158
+ functionName: "connectedAccounts",
159
+ args: [address],
160
+ }),
161
+ client.readContract({
162
+ address: GOODDOLLAR_IDENTITY_ADDRESS,
163
+ abi: goodDollarIdentityAbi,
164
+ functionName: "isWhitelisted",
165
+ args: [link.identityAddress],
166
+ }),
167
+ ]);
168
+ const connectedToAddr = connectedTo;
169
+ const isWhitelistedRoot = link.root !== null &&
170
+ link.root.toLowerCase() === address.toLowerCase();
171
+ return {
172
+ address,
173
+ contract: GOODDOLLAR_IDENTITY_ADDRESS,
174
+ whitelistedRoot: link.root,
175
+ isConnectedWallet: link.isConnectedWallet,
176
+ isWhitelistedRoot,
177
+ connectedTo: connectedToAddr !== ZERO_ADDRESS ? connectedToAddr : null,
178
+ checkedAddress: link.identityAddress,
179
+ isWhitelisted,
180
+ };
181
+ }
182
+ /**
183
+ * GoodDollar IdentityV4 whitelist status and reverification progress for a wallet.
184
+ * Resolves connected wallets via Identity `getWhitelistedRoot`.
185
+ * @param address - Wallet to check against IdentityV4
186
+ * @returns On-chain status, whitelist dates, field descriptions, and reverification timeline
187
+ */
188
+ async getWhitelistingInfo(address) {
189
+ const link = await this.resolveWhitelistedRoot(address);
190
+ const data = await this.fetchWhitelistingData(link.identityAddress);
191
+ return {
192
+ address,
193
+ whitelistedRoot: link.root,
194
+ isConnectedWallet: link.isConnectedWallet,
195
+ checkedAddress: link.identityAddress,
196
+ ...data,
197
+ };
198
+ }
199
+ /**
200
+ * Daily UBI claim eligibility for a wallet against UBISchemeV2 on Celo.
201
+ * Resolves connected wallets via Identity `getWhitelistedRoot`.
202
+ */
203
+ async getUbiClaimEligibility(address) {
204
+ const client = this.getPublicClient();
205
+ const ubiContract = GOODDOLLAR_UBI_SCHEME_ADDRESS;
206
+ const link = await this.resolveWhitelistedRoot(address);
207
+ const root = link.root;
208
+ const [claimableAmount, schemePaused, periodStart, estimatedDailyUbi, dailyUbi, ubiPeriodDay, whitelistingData,] = await Promise.all([
209
+ client.readContract({
210
+ address: ubiContract,
211
+ abi: ubiSchemeAbi,
212
+ functionName: "checkEntitlement",
213
+ args: [address],
214
+ }),
215
+ client.readContract({
216
+ address: ubiContract,
217
+ abi: ubiSchemeAbi,
218
+ functionName: "paused",
219
+ }),
220
+ client.readContract({
221
+ address: ubiContract,
222
+ abi: ubiSchemeAbi,
223
+ functionName: "periodStart",
224
+ }),
225
+ client.readContract({
226
+ address: ubiContract,
227
+ abi: ubiSchemeAbi,
228
+ functionName: "estimateNextDailyUBI",
229
+ }),
230
+ client.readContract({
231
+ address: ubiContract,
232
+ abi: ubiSchemeAbi,
233
+ functionName: "dailyUbi",
234
+ }),
235
+ client.readContract({
236
+ address: ubiContract,
237
+ abi: ubiSchemeAbi,
238
+ functionName: "currentDay",
239
+ }),
240
+ this.fetchWhitelistingData(link.identityAddress),
241
+ ]);
242
+ const claimable = claimableAmount;
243
+ const periodStartBn = periodStart;
244
+ const nowSec = BigInt(Math.floor(Date.now() / 1000));
245
+ const schemeStarted = nowSec >= periodStartBn;
246
+ const contractDay = ubiPeriodDay;
247
+ const computedDay = schemeStarted && periodStartBn > 0n
248
+ ? (nowSec - periodStartBn) / SECONDS_PER_DAY
249
+ : 0n;
250
+ let claimedForOnChainDay = false;
251
+ let lastClaimedSec = 0n;
252
+ if (root !== null) {
253
+ const [hasClaimed, lastClaimed] = await Promise.all([
254
+ client.readContract({
255
+ address: ubiContract,
256
+ abi: ubiSchemeAbi,
257
+ functionName: "hasClaimed",
258
+ args: [root],
259
+ }),
260
+ client.readContract({
261
+ address: ubiContract,
262
+ abi: ubiSchemeAbi,
263
+ functionName: "lastClaimed",
264
+ args: [root],
265
+ }),
266
+ ]);
267
+ claimedForOnChainDay = hasClaimed;
268
+ lastClaimedSec = lastClaimed;
269
+ }
270
+ const periodState = resolveUbiPeriodEligibility({
271
+ contractDay,
272
+ computedDay,
273
+ claimedForOnChainDay,
274
+ hasRoot: root !== null,
275
+ schemePaused,
276
+ schemeStarted,
277
+ isWhitelisted: whitelistingData.isWhitelisted,
278
+ claimable,
279
+ });
280
+ const { alreadyClaimedToday, inClaimCooldown } = periodState;
281
+ const nextClaimAt = periodStartBn + (computedDay + 1n) * SECONDS_PER_DAY;
282
+ const secondsUntilNextClaim = inClaimCooldown && nextClaimAt > nowSec ? nextClaimAt - nowSec : 0n;
283
+ const reasons = [];
284
+ if (schemePaused) {
285
+ reasons.push("scheme paused");
286
+ }
287
+ if (!schemeStarted) {
288
+ reasons.push("scheme not started");
289
+ }
290
+ if (root === null) {
291
+ reasons.push("not whitelisted");
292
+ }
293
+ else if (alreadyClaimedToday) {
294
+ const waitLabel = formatDuration(secondsUntilNextClaim);
295
+ const atLabel = formatUnixDateTimeUtc(nextClaimAt);
296
+ reasons.push(`already claimed this period; next claim in ${waitLabel} (${atLabel})`);
297
+ }
298
+ else {
299
+ if (!whitelistingData.isWhitelisted) {
300
+ if (whitelistingData.reverification?.isReverificationOverdue) {
301
+ reasons.push("reverification overdue");
302
+ }
303
+ else {
304
+ reasons.push("identity not currently whitelisted");
305
+ }
306
+ }
307
+ if (claimable === 0n) {
308
+ reasons.push("no entitlement available");
309
+ }
310
+ }
311
+ const isEligibleToClaim = periodState.isEligibleToClaim;
312
+ const lastClaimedAt = lastClaimedSec > 0n ? formatUnixIso(lastClaimedSec) : null;
313
+ const nextClaimAvailableAt = formatUnixIso(nextClaimAt);
314
+ const nextClaimAvailableIn = formatDuration(secondsUntilNextClaim);
315
+ return {
316
+ address,
317
+ contract: ubiContract,
318
+ whitelistedRoot: root,
319
+ isConnectedWallet: link.isConnectedWallet,
320
+ isEligibleToClaim,
321
+ claimableAmount: claimable.toString(),
322
+ claimableAmountFormatted: claimable > 0n ? `${formatUnits(claimable, G_DOLLAR_DECIMALS)} G$` : "0 G$",
323
+ alreadyClaimedToday,
324
+ inClaimCooldown,
325
+ lastClaimedAt,
326
+ nextClaimAvailableAt,
327
+ secondsUntilNextClaim: secondsUntilNextClaim.toString(),
328
+ nextClaimAvailableIn,
329
+ ubiPeriodDay: ubiPeriodDay.toString(),
330
+ schemePaused,
331
+ schemeStarted,
332
+ estimatedDailyUbi: estimatedDailyUbi.toString(),
333
+ estimatedDailyUbiFormatted: `${formatUnits(estimatedDailyUbi, G_DOLLAR_DECIMALS)} G$`,
334
+ currentDailyUbi: dailyUbi.toString(),
335
+ currentDailyUbiFormatted: `${formatUnits(dailyUbi, G_DOLLAR_DECIMALS)} G$`,
336
+ reasons: isEligibleToClaim ? [] : reasons,
337
+ identity: {
338
+ checkedAddress: link.identityAddress,
339
+ isWhitelisted: whitelistingData.isWhitelisted,
340
+ statusLabel: whitelistingData.statusLabel,
341
+ reverification: whitelistingData.reverification,
342
+ },
343
+ };
344
+ }
345
+ /**
346
+ * Build an unsigned UBISchemeV2 `claim()` transaction for daily G$ UBI.
347
+ * Validates whitelist, entitlement, and simulates gas before returning steps.
348
+ */
349
+ async prepareClaimUbi(from) {
350
+ const eligibility = await this.getUbiClaimEligibility(from);
351
+ if (!eligibility.isEligibleToClaim) {
352
+ const detail = eligibility.reasons.length > 0
353
+ ? eligibility.reasons.join("; ")
354
+ : "not eligible to claim";
355
+ throw new Error(`Cannot claim GoodDollar UBI: ${detail}.`);
356
+ }
357
+ const publicClient = this.getPublicClient();
358
+ const claimData = taggedCalldata(encodeFunctionData({
359
+ abi: ubiSchemeAbi,
360
+ functionName: "claim",
361
+ }));
362
+ await publicClient.estimateContractGas({
363
+ account: from,
364
+ address: GOODDOLLAR_UBI_SCHEME_ADDRESS,
365
+ abi: ubiSchemeAbi,
366
+ functionName: "claim",
367
+ });
368
+ const summary = eligibility.isConnectedWallet && eligibility.whitelistedRoot
369
+ ? `Claim daily GoodDollar UBI (${eligibility.claimableAmountFormatted}) via connected wallet → root ${eligibility.whitelistedRoot}`
370
+ : `Claim daily GoodDollar UBI (${eligibility.claimableAmountFormatted})`;
371
+ const flow = {
372
+ network: "mainnet",
373
+ from,
374
+ summary,
375
+ steps: [
376
+ {
377
+ kind: "contract",
378
+ to: GOODDOLLAR_UBI_SCHEME_ADDRESS,
379
+ data: claimData,
380
+ value: "0",
381
+ description: "Claim daily GoodDollar UBI",
382
+ },
383
+ ],
384
+ };
385
+ return serializePreparedFlow(flow);
386
+ }
387
+ resolveReservePair(tokenIn, tokenOut) {
388
+ if (!isGoodDollarUsdReservePair(tokenIn, tokenOut)) {
389
+ throw new Error(`No GoodDollar reserve route for ${tokenIn} → ${tokenOut}. Supported: GoodDollar ↔ USDm.`);
390
+ }
391
+ const resolvedIn = this.tokenService.resolveToken(tokenIn);
392
+ const resolvedOut = this.tokenService.resolveToken(tokenOut);
393
+ const tokenInAddr = tokenAddress(resolvedIn);
394
+ const tokenOutAddr = tokenAddress(resolvedOut);
395
+ const gdAddr = GOODDOLLAR_TOKEN_ADDRESS.toLowerCase();
396
+ const collateralAddr = GOODDOLLAR_RESERVE_COLLATERAL.toLowerCase();
397
+ const inLower = tokenInAddr.toLowerCase();
398
+ const outLower = tokenOutAddr.toLowerCase();
399
+ if (!((inLower === gdAddr && outLower === collateralAddr) ||
400
+ (inLower === collateralAddr && outLower === gdAddr))) {
401
+ throw new Error(`No GoodDollar reserve route for ${resolvedIn.symbol} → ${resolvedOut.symbol}.`);
402
+ }
403
+ return { resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr };
404
+ }
405
+ reserveOptions(params) {
406
+ return {
407
+ slippageTolerance: params?.slippageTolerance ?? DEFAULT_RESERVE_SLIPPAGE,
408
+ };
409
+ }
410
+ baseReserveQuoteFields(resolvedIn, resolvedOut, amountIn, expectedOutWei, amountSide) {
411
+ return {
412
+ protocol: "gooddollar_reserve",
413
+ network: "mainnet",
414
+ tokenIn: resolvedIn.symbol,
415
+ tokenOut: resolvedOut.symbol,
416
+ amountIn,
417
+ expectedOut: formatUnits(expectedOutWei, resolvedOut.decimals),
418
+ amountSide,
419
+ routeHops: 1,
420
+ broker: GOODDOLLAR_MENTO_BROKER,
421
+ exchangeProvider: GOODDOLLAR_MENTO_EXCHANGE_PROVIDER,
422
+ exchangeId: GOODDOLLAR_CUSD_EXCHANGE_ID,
423
+ };
424
+ }
425
+ async resolveReserveAmount(client, resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr, amount, amountSide = "in") {
426
+ if (amountSide === "in") {
427
+ const amountInWei = this.tokenService.parseAmount(amount, resolvedIn.decimals);
428
+ const expectedOutWei = await client.readContract({
429
+ address: GOODDOLLAR_MENTO_BROKER,
430
+ abi: goodDollarBrokerAbi,
431
+ functionName: "getAmountOut",
432
+ args: [
433
+ GOODDOLLAR_MENTO_EXCHANGE_PROVIDER,
434
+ GOODDOLLAR_CUSD_EXCHANGE_ID,
435
+ tokenInAddr,
436
+ tokenOutAddr,
437
+ amountInWei,
438
+ ],
439
+ });
440
+ return {
441
+ amountIn: amount,
442
+ amountInWei,
443
+ expectedOutWei,
444
+ amountSide: "in",
445
+ };
446
+ }
447
+ const expectedOutWei = this.tokenService.parseAmount(amount, resolvedOut.decimals);
448
+ const amountInWei = await client.readContract({
449
+ address: GOODDOLLAR_MENTO_BROKER,
450
+ abi: goodDollarBrokerAbi,
451
+ functionName: "getAmountIn",
452
+ args: [
453
+ GOODDOLLAR_MENTO_EXCHANGE_PROVIDER,
454
+ GOODDOLLAR_CUSD_EXCHANGE_ID,
455
+ tokenInAddr,
456
+ tokenOutAddr,
457
+ expectedOutWei,
458
+ ],
459
+ });
460
+ return {
461
+ amountIn: trimDisplayDecimals(formatUnits(amountInWei, resolvedIn.decimals)),
462
+ amountInWei,
463
+ expectedOutWei,
464
+ amountSide: "out",
465
+ };
466
+ }
467
+ /**
468
+ * Expected GoodDollar reserve output for G$ ↔ USDm — no wallet required.
469
+ * Balance checks run on prepare/estimate only.
470
+ */
471
+ async getReserveQuote(tokenIn, tokenOut, amount, options) {
472
+ const { public: client } = this.clientFactory.getClients();
473
+ const { resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr } = this.resolveReservePair(tokenIn, tokenOut);
474
+ const amountSide = options?.amountSide ?? "in";
475
+ const resolved = await this.resolveReserveAmount(client, resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr, amount, amountSide);
476
+ return this.baseReserveQuoteFields(resolvedIn, resolvedOut, resolved.amountIn, resolved.expectedOutWei, resolved.amountSide);
477
+ }
478
+ async buildReserveSwap(from, tokenIn, tokenOut, amount, params) {
479
+ const { public: client } = this.clientFactory.getClients();
480
+ const { resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr } = this.resolveReservePair(tokenIn, tokenOut);
481
+ const recipient = params?.recipient ?? from;
482
+ const amountSide = params?.amountSide ?? "in";
483
+ const { slippageTolerance } = this.reserveOptions(params);
484
+ const resolved = await this.resolveReserveAmount(client, resolvedIn, resolvedOut, tokenInAddr, tokenOutAddr, amount, amountSide);
485
+ const { amountIn, amountInWei, expectedOutWei } = resolved;
486
+ await this.tokenService.assertSpendableBalance(from, resolvedIn, amountIn, {
487
+ spendToken: tokenInAddr,
488
+ });
489
+ const amountOutMin = applySlippage(expectedOutWei, slippageTolerance);
490
+ const swapData = taggedCalldata(encodeFunctionData({
491
+ abi: goodDollarBrokerAbi,
492
+ functionName: "swapIn",
493
+ args: [
494
+ GOODDOLLAR_MENTO_EXCHANGE_PROVIDER,
495
+ GOODDOLLAR_CUSD_EXCHANGE_ID,
496
+ tokenInAddr,
497
+ tokenOutAddr,
498
+ amountInWei,
499
+ amountOutMin,
500
+ ],
501
+ }));
502
+ return {
503
+ client,
504
+ from,
505
+ recipient,
506
+ resolvedIn,
507
+ resolvedOut,
508
+ tokenInAddr,
509
+ tokenOutAddr,
510
+ amountIn,
511
+ amountInWei,
512
+ expectedOutWei,
513
+ amountOutMin,
514
+ swapData,
515
+ slippageTolerance,
516
+ amountSide: resolved.amountSide,
517
+ };
518
+ }
519
+ buildReserveApprovalData() {
520
+ return taggedCalldata(encodeFunctionData({
521
+ abi: erc20Abi,
522
+ functionName: "approve",
523
+ args: [GOODDOLLAR_MENTO_BROKER, maxUint256],
524
+ }));
525
+ }
526
+ async estimateReserveSwapGas(client, from, swapData, tokenInAddr, approvalNeeded) {
527
+ const swapEstimateRequest = {
528
+ account: from,
529
+ to: GOODDOLLAR_MENTO_BROKER,
530
+ data: swapData,
531
+ value: 0n,
532
+ };
533
+ if (!approvalNeeded) {
534
+ const gas = await client.estimateGas(swapEstimateRequest);
535
+ return gas.toString();
536
+ }
537
+ for (const mappingSlot of ALLOWANCE_MAPPING_SLOTS) {
538
+ try {
539
+ const gas = await client.estimateGas({
540
+ ...swapEstimateRequest,
541
+ stateOverride: erc20AllowanceStateOverride(tokenInAddr, from, GOODDOLLAR_MENTO_BROKER, maxUint256, mappingSlot),
542
+ });
543
+ return gas.toString();
544
+ }
545
+ catch (error) {
546
+ const isLast = mappingSlot === ALLOWANCE_MAPPING_SLOTS.at(-1);
547
+ if (isLast) {
548
+ throw error;
549
+ }
550
+ }
551
+ }
552
+ throw new Error("Could not estimate GoodDollar reserve swap gas: failed to simulate ERC-20 allowance for this token.");
553
+ }
554
+ /**
555
+ * Simulate gas for a GoodDollar reserve swap from `from`, including approval if needed.
556
+ */
557
+ async estimateReserveSwap(from, tokenIn, tokenOut, amount, params) {
558
+ const built = await this.buildReserveSwap(from, tokenIn, tokenOut, amount, params);
559
+ const { client, resolvedIn, resolvedOut, tokenInAddr, amountInWei, expectedOutWei, amountOutMin, swapData, slippageTolerance, recipient, } = built;
560
+ const allowance = await client.readContract({
561
+ address: tokenInAddr,
562
+ abi: erc20Abi,
563
+ functionName: "allowance",
564
+ args: [from, GOODDOLLAR_MENTO_BROKER],
565
+ });
566
+ const approvalNeeded = allowance < amountInWei;
567
+ const approvalGas = approvalNeeded
568
+ ? (await client.estimateGas({
569
+ account: from,
570
+ to: tokenInAddr,
571
+ data: this.buildReserveApprovalData(),
572
+ })).toString()
573
+ : undefined;
574
+ const swapGas = await this.estimateReserveSwapGas(client, from, swapData, tokenInAddr, approvalNeeded);
575
+ const approvalGasBig = approvalGas ? BigInt(approvalGas) : 0n;
576
+ const totalGas = (approvalGasBig + BigInt(swapGas)).toString();
577
+ return {
578
+ ...this.baseReserveQuoteFields(resolvedIn, resolvedOut, built.amountIn, expectedOutWei, built.amountSide),
579
+ from,
580
+ recipient,
581
+ amountOutMin: formatUnits(amountOutMin, resolvedOut.decimals),
582
+ approvalNeeded,
583
+ approvalGas,
584
+ swapGas,
585
+ totalGas,
586
+ slippageTolerance,
587
+ };
588
+ }
589
+ /**
590
+ * Build unsigned GoodDollar reserve swap steps (approve + swapIn when needed).
591
+ */
592
+ async prepareReserveSwap(from, tokenIn, tokenOut, amount, params) {
593
+ const built = await this.buildReserveSwap(from, tokenIn, tokenOut, amount, params);
594
+ const { client, resolvedIn, resolvedOut, tokenInAddr, amountInWei, expectedOutWei, swapData, recipient, } = built;
595
+ const displayIn = trimDisplayDecimals(built.amountIn);
596
+ const displayOut = trimDisplayDecimals(formatUnits(expectedOutWei, resolvedOut.decimals));
597
+ const steps = [];
598
+ const allowance = await client.readContract({
599
+ address: tokenInAddr,
600
+ abi: erc20Abi,
601
+ functionName: "allowance",
602
+ args: [from, GOODDOLLAR_MENTO_BROKER],
603
+ });
604
+ if (allowance < amountInWei) {
605
+ steps.push({
606
+ kind: "erc20",
607
+ to: tokenInAddr,
608
+ data: this.buildReserveApprovalData(),
609
+ value: "0",
610
+ description: `Approve ${resolvedIn.symbol} for GoodDollar reserve`,
611
+ });
612
+ }
613
+ steps.push({
614
+ kind: "contract",
615
+ to: GOODDOLLAR_MENTO_BROKER,
616
+ data: swapData,
617
+ value: "0",
618
+ description: `Swap ${displayIn} ${resolvedIn.symbol} → ~${displayOut} ${resolvedOut.symbol} via GoodDollar reserve`,
619
+ });
620
+ await this.estimateReserveSwapGas(client, from, swapData, tokenInAddr, allowance < amountInWei);
621
+ const flow = {
622
+ network: "mainnet",
623
+ from,
624
+ summary: `GoodDollar reserve: ${displayIn} ${resolvedIn.symbol} → ${displayOut} ${resolvedOut.symbol}${recipient !== from ? ` (recipient ${recipient})` : ""}`,
625
+ steps,
626
+ };
627
+ return serializePreparedFlow(flow);
628
+ }
629
+ effectiveAuthCount(dateAuthenticated, authCount, optionsLength) {
630
+ if (dateAuthenticated < LEGACY_AUTH_CUTOFF) {
631
+ return optionsLength - 1;
632
+ }
633
+ if (authCount >= optionsLength) {
634
+ return 0;
635
+ }
636
+ return authCount;
637
+ }
638
+ async fetchReverifyDaysOptions(client, contract) {
639
+ const options = [];
640
+ for (let index = 0; index < 8; index++) {
641
+ try {
642
+ const value = await client.readContract({
643
+ address: contract,
644
+ abi: goodDollarIdentityAbi,
645
+ functionName: "reverifyDaysOptions",
646
+ args: [BigInt(index)],
647
+ });
648
+ options.push(Number(value));
649
+ }
650
+ catch {
651
+ break;
652
+ }
653
+ }
654
+ return options;
655
+ }
656
+ buildReverificationProgress(dateAuthenticated, currentReverificationPeriodDays, maxReverificationPeriodDays) {
657
+ const nowSec = Math.floor(Date.now() / 1000);
658
+ const daysSinceLastAuthentication = Math.floor((nowSec - dateAuthenticated) / 86400);
659
+ const daysUntilReverificationRequired = currentReverificationPeriodDays - daysSinceLastAuthentication;
660
+ const reverificationRequiredTimestamp = dateAuthenticated + currentReverificationPeriodDays * 86400;
661
+ const isReverificationOverdue = daysUntilReverificationRequired < 0;
662
+ const reverificationProgressPercent = Math.min(100, Math.max(0, Math.round((daysSinceLastAuthentication / currentReverificationPeriodDays) *
663
+ 100)));
664
+ return {
665
+ daysSinceLastAuthentication,
666
+ currentReverificationPeriodDays,
667
+ maxReverificationPeriodDays,
668
+ daysUntilReverificationRequired,
669
+ reverificationRequiredOn: formatUnixDate(reverificationRequiredTimestamp),
670
+ reverificationProgressPercent,
671
+ isReverificationOverdue,
672
+ };
673
+ }
674
+ }
675
+ //# sourceMappingURL=gooddollar.service.js.map