@daimo/pay 0.3.21 → 1.0.0

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 (302) hide show
  1. package/build/index.d.ts +132 -301
  2. package/build/package.json.js +103 -0
  3. package/build/package.json.js.map +1 -0
  4. package/build/src/assets/ScanIconWithLogos.js +34 -0
  5. package/build/src/assets/ScanIconWithLogos.js.map +1 -0
  6. package/build/src/assets/browsers.js +13 -0
  7. package/build/src/assets/browsers.js.map +1 -0
  8. package/build/src/assets/chains.js +152 -0
  9. package/build/src/assets/chains.js.map +1 -0
  10. package/build/src/assets/coins.js +6 -0
  11. package/build/src/assets/coins.js.map +1 -0
  12. package/build/src/assets/crepe.js +8 -0
  13. package/build/src/assets/crepe.js.map +1 -0
  14. package/build/src/assets/icons.js +28 -0
  15. package/build/src/assets/icons.js.map +1 -0
  16. package/build/src/assets/logos.js +131 -0
  17. package/build/src/assets/logos.js.map +1 -0
  18. package/build/src/assets/wallet.js +8 -0
  19. package/build/src/assets/wallet.js.map +1 -0
  20. package/build/src/assets/wave.js +6 -0
  21. package/build/src/assets/wave.js.map +1 -0
  22. package/build/src/components/Common/Alert/index.js +10 -0
  23. package/build/src/components/Common/Alert/index.js.map +1 -0
  24. package/build/src/components/Common/Alert/styles.js +55 -0
  25. package/build/src/components/Common/Alert/styles.js.map +1 -0
  26. package/build/src/components/Common/Avatar/index.js +66 -0
  27. package/build/src/components/Common/Avatar/index.js.map +1 -0
  28. package/build/src/components/Common/Avatar/styles.js +59 -0
  29. package/build/src/components/Common/Avatar/styles.js.map +1 -0
  30. package/build/src/components/Common/BrowserIcon/index.js +28 -0
  31. package/build/src/components/Common/BrowserIcon/index.js.map +1 -0
  32. package/build/src/components/Common/BrowserIcon/styles.js +20 -0
  33. package/build/src/components/Common/BrowserIcon/styles.js.map +1 -0
  34. package/build/src/components/Common/Button/index.js +38 -0
  35. package/build/src/components/Common/Button/index.js.map +1 -0
  36. package/build/src/components/Common/Button/styles.js +291 -0
  37. package/build/src/components/Common/Button/styles.js.map +1 -0
  38. package/build/src/components/Common/Chain/index.js +25 -0
  39. package/build/src/components/Common/Chain/index.js.map +1 -0
  40. package/build/src/components/Common/Chain/styles.js +94 -0
  41. package/build/src/components/Common/Chain/styles.js.map +1 -0
  42. package/build/src/components/Common/ChainSelectList/index.js +107 -0
  43. package/build/src/components/Common/ChainSelectList/index.js.map +1 -0
  44. package/build/src/components/Common/ChainSelectList/styles.js +228 -0
  45. package/build/src/components/Common/ChainSelectList/styles.js.map +1 -0
  46. package/build/src/components/Common/ConnectorList/index.js +70 -0
  47. package/build/src/components/Common/ConnectorList/index.js.map +1 -0
  48. package/build/src/components/Common/ConnectorList/styles.js +314 -0
  49. package/build/src/components/Common/ConnectorList/styles.js.map +1 -0
  50. package/build/src/components/Common/CopyToClipboard/CopyToClipboardIcon.js +71 -0
  51. package/build/src/components/Common/CopyToClipboard/CopyToClipboardIcon.js.map +1 -0
  52. package/build/src/components/Common/CopyToClipboard/index.js +51 -0
  53. package/build/src/components/Common/CopyToClipboard/index.js.map +1 -0
  54. package/build/src/components/Common/CustomQRCode/QRCode.js +69 -0
  55. package/build/src/components/Common/CustomQRCode/QRCode.js.map +1 -0
  56. package/build/src/components/Common/CustomQRCode/index.js +22 -0
  57. package/build/src/components/Common/CustomQRCode/index.js.map +1 -0
  58. package/build/src/components/Common/CustomQRCode/styles.js +155 -0
  59. package/build/src/components/Common/CustomQRCode/styles.js.map +1 -0
  60. package/build/src/components/Common/FitText/index.js +27 -0
  61. package/build/src/components/Common/FitText/index.js.map +1 -0
  62. package/build/src/components/Common/Modal/index.js +297 -0
  63. package/build/src/components/Common/Modal/index.js.map +1 -0
  64. package/build/src/components/Common/Modal/styles.js +660 -0
  65. package/build/src/components/Common/Modal/styles.js.map +1 -0
  66. package/build/src/components/Common/OptionsList/index.js +106 -0
  67. package/build/src/components/Common/OptionsList/index.js.map +1 -0
  68. package/build/src/components/Common/OptionsList/styles.js +165 -0
  69. package/build/src/components/Common/OptionsList/styles.js.map +1 -0
  70. package/build/src/components/Common/OrderHeader/index.js +215 -0
  71. package/build/src/components/Common/OrderHeader/index.js.map +1 -0
  72. package/build/src/components/Common/Portal/index.js +31 -0
  73. package/build/src/components/Common/Portal/index.js.map +1 -0
  74. package/build/src/components/Common/PoweredByFooter/index.js +44 -0
  75. package/build/src/components/Common/PoweredByFooter/index.js.map +1 -0
  76. package/build/src/components/Common/ScrollArea/index.js +62 -0
  77. package/build/src/components/Common/ScrollArea/index.js.map +1 -0
  78. package/build/src/components/Common/ScrollArea/styles.js +168 -0
  79. package/build/src/components/Common/ScrollArea/styles.js.map +1 -0
  80. package/build/src/components/Common/Spinner/index.js +24 -0
  81. package/build/src/components/Common/Spinner/index.js.map +1 -0
  82. package/build/src/components/Common/Spinner/styles.js +22 -0
  83. package/build/src/components/Common/Spinner/styles.js.map +1 -0
  84. package/build/src/components/Common/ThemedButton/index.js +25 -0
  85. package/build/src/components/Common/ThemedButton/index.js.map +1 -0
  86. package/build/src/components/Common/ThemedButton/styles.js +152 -0
  87. package/build/src/components/Common/ThemedButton/styles.js.map +1 -0
  88. package/build/src/components/Common/Tooltip/index.js +97 -0
  89. package/build/src/components/Common/Tooltip/index.js.map +1 -0
  90. package/build/src/components/Common/Tooltip/styles.js +81 -0
  91. package/build/src/components/Common/Tooltip/styles.js.map +1 -0
  92. package/build/src/components/DaimoPay.js +232 -0
  93. package/build/src/components/DaimoPay.js.map +1 -0
  94. package/build/src/components/DaimoPayButton/index.js +133 -0
  95. package/build/src/components/DaimoPayButton/index.js.map +1 -0
  96. package/build/src/components/DaimoPayButton/styles.js +50 -0
  97. package/build/src/components/DaimoPayButton/styles.js.map +1 -0
  98. package/build/src/components/DaimoPayModal/ConnectUsing.js +45 -0
  99. package/build/src/components/DaimoPayModal/ConnectUsing.js.map +1 -0
  100. package/build/src/components/DaimoPayModal/ConnectWithInjector/index.js +202 -0
  101. package/build/src/components/DaimoPayModal/ConnectWithInjector/index.js.map +1 -0
  102. package/build/src/components/DaimoPayModal/ConnectWithInjector/styles.js +133 -0
  103. package/build/src/components/DaimoPayModal/ConnectWithInjector/styles.js.map +1 -0
  104. package/build/src/components/DaimoPayModal/ConnectWithQRCode.js +75 -0
  105. package/build/src/components/DaimoPayModal/ConnectWithQRCode.js.map +1 -0
  106. package/build/src/components/DaimoPayModal/index.js +140 -0
  107. package/build/src/components/DaimoPayModal/index.js.map +1 -0
  108. package/build/src/components/DaimoPayThemeProvider/DaimoPayThemeProvider.js +21 -0
  109. package/build/src/components/DaimoPayThemeProvider/DaimoPayThemeProvider.js.map +1 -0
  110. package/build/src/components/Pages/About/graphics.js +187 -0
  111. package/build/src/components/Pages/About/graphics.js.map +1 -0
  112. package/build/src/components/Pages/About/index.js +131 -0
  113. package/build/src/components/Pages/About/index.js.map +1 -0
  114. package/build/src/components/Pages/About/styles.js +144 -0
  115. package/build/src/components/Pages/About/styles.js.map +1 -0
  116. package/build/src/components/Pages/Confirmation/index.js +105 -0
  117. package/build/src/components/Pages/Confirmation/index.js.map +1 -0
  118. package/build/src/components/Pages/Connectors/index.js +20 -0
  119. package/build/src/components/Pages/Connectors/index.js.map +1 -0
  120. package/build/src/components/Pages/Connectors/styles.js +267 -0
  121. package/build/src/components/Pages/Connectors/styles.js.map +1 -0
  122. package/build/src/components/Pages/DownloadApp/index.js +30 -0
  123. package/build/src/components/Pages/DownloadApp/index.js.map +1 -0
  124. package/build/src/components/Pages/MobileConnectors/index.js +73 -0
  125. package/build/src/components/Pages/MobileConnectors/index.js.map +1 -0
  126. package/build/src/components/Pages/MobileConnectors/styles.js +65 -0
  127. package/build/src/components/Pages/MobileConnectors/styles.js.map +1 -0
  128. package/build/src/components/Pages/Onboarding/index.js +18 -0
  129. package/build/src/components/Pages/Onboarding/index.js.map +1 -0
  130. package/build/src/components/Pages/Onboarding/styles.js +229 -0
  131. package/build/src/components/Pages/Onboarding/styles.js.map +1 -0
  132. package/build/src/components/Pages/PayWithToken/index.js +204 -0
  133. package/build/src/components/Pages/PayWithToken/index.js.map +1 -0
  134. package/build/src/components/Pages/SelectDepositAddressChain/index.js +32 -0
  135. package/build/src/components/Pages/SelectDepositAddressChain/index.js.map +1 -0
  136. package/build/src/components/Pages/SelectMethod/index.js +113 -0
  137. package/build/src/components/Pages/SelectMethod/index.js.map +1 -0
  138. package/build/src/components/Pages/SelectToken/index.js +62 -0
  139. package/build/src/components/Pages/SelectToken/index.js.map +1 -0
  140. package/build/src/components/Pages/Solana/ConnectSolana/index.js +37 -0
  141. package/build/src/components/Pages/Solana/ConnectSolana/index.js.map +1 -0
  142. package/build/src/components/Pages/Solana/ConnectorSolana/index.js +45 -0
  143. package/build/src/components/Pages/Solana/ConnectorSolana/index.js.map +1 -0
  144. package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js +85 -0
  145. package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js.map +1 -0
  146. package/build/src/components/Pages/Solana/SelectSolanaToken/index.js +38 -0
  147. package/build/src/components/Pages/Solana/SelectSolanaToken/index.js.map +1 -0
  148. package/build/src/components/Pages/SwitchNetworks/index.js +26 -0
  149. package/build/src/components/Pages/SwitchNetworks/index.js.map +1 -0
  150. package/build/src/components/Pages/WaitingDepositAddress/index.js +51 -0
  151. package/build/src/components/Pages/WaitingDepositAddress/index.js.map +1 -0
  152. package/build/src/components/Pages/WaitingOther/index.js +91 -0
  153. package/build/src/components/Pages/WaitingOther/index.js.map +1 -0
  154. package/build/src/components/Spinners/CircleSpinner/index.js +15 -0
  155. package/build/src/components/Spinners/CircleSpinner/index.js.map +1 -0
  156. package/build/src/components/Spinners/CircleSpinner/styles.js +118 -0
  157. package/build/src/components/Spinners/CircleSpinner/styles.js.map +1 -0
  158. package/build/src/components/Spinners/SquircleSpinner/index.js +15 -0
  159. package/build/src/components/Spinners/SquircleSpinner/index.js.map +1 -0
  160. package/build/src/components/Spinners/SquircleSpinner/styles.js +66 -0
  161. package/build/src/components/Spinners/SquircleSpinner/styles.js.map +1 -0
  162. package/build/src/components/contexts/solana/index.js +11 -0
  163. package/build/src/components/contexts/solana/index.js.map +1 -0
  164. package/build/src/components/contexts/web3/index.js +46 -0
  165. package/build/src/components/contexts/web3/index.js.map +1 -0
  166. package/build/src/constants/chainConfigs.js +306 -0
  167. package/build/src/constants/chainConfigs.js.map +1 -0
  168. package/build/src/constants/defaultTheme.js +6 -0
  169. package/build/src/constants/defaultTheme.js.map +1 -0
  170. package/build/src/defaultConfig.js +59 -0
  171. package/build/src/defaultConfig.js.map +1 -0
  172. package/build/src/defaultConnectors.js +43 -0
  173. package/build/src/defaultConnectors.js.map +1 -0
  174. package/build/src/hooks/connectors/useWalletConnectUri.js +93 -0
  175. package/build/src/hooks/connectors/useWalletConnectUri.js.map +1 -0
  176. package/build/src/hooks/useChainIsSupported.js +12 -0
  177. package/build/src/hooks/useChainIsSupported.js.map +1 -0
  178. package/build/src/hooks/useChains.js +11 -0
  179. package/build/src/hooks/useChains.js.map +1 -0
  180. package/build/src/hooks/useConnect.js +45 -0
  181. package/build/src/hooks/useConnect.js.map +1 -0
  182. package/build/src/hooks/useConnectCallback.js +18 -0
  183. package/build/src/hooks/useConnectCallback.js.map +1 -0
  184. package/build/src/hooks/useConnectors.js +29 -0
  185. package/build/src/hooks/useConnectors.js.map +1 -0
  186. package/build/src/hooks/useDaimoPayStatus.js +37 -0
  187. package/build/src/hooks/useDaimoPayStatus.js.map +1 -0
  188. package/build/src/hooks/useDepositAddressOptions.js +28 -0
  189. package/build/src/hooks/useDepositAddressOptions.js.map +1 -0
  190. package/build/src/hooks/useEnsFallbackConfig.js +16 -0
  191. package/build/src/hooks/useEnsFallbackConfig.js.map +1 -0
  192. package/build/src/hooks/useExternalPaymentOptions.js +46 -0
  193. package/build/src/hooks/useExternalPaymentOptions.js.map +1 -0
  194. package/build/src/hooks/useFitText.js +148 -0
  195. package/build/src/hooks/useFitText.js.map +1 -0
  196. package/build/src/hooks/useFocusTrap.js +60 -0
  197. package/build/src/hooks/useFocusTrap.js.map +1 -0
  198. package/build/src/hooks/useGoogleFont.js +45 -0
  199. package/build/src/hooks/useGoogleFont.js.map +1 -0
  200. package/build/src/hooks/useIsMobile.js +17 -0
  201. package/build/src/hooks/useIsMobile.js.map +1 -0
  202. package/build/src/hooks/useIsMounted.js +12 -0
  203. package/build/src/hooks/useIsMounted.js.map +1 -0
  204. package/build/src/hooks/useLastConnector.js +24 -0
  205. package/build/src/hooks/useLastConnector.js.map +1 -0
  206. package/build/src/hooks/useLocales.js +67 -0
  207. package/build/src/hooks/useLocales.js.map +1 -0
  208. package/build/src/hooks/useLockBodyScroll.js +53 -0
  209. package/build/src/hooks/useLockBodyScroll.js.map +1 -0
  210. package/build/src/hooks/useModal.js +35 -0
  211. package/build/src/hooks/useModal.js.map +1 -0
  212. package/build/src/hooks/usePayWithSolanaToken.js +50 -0
  213. package/build/src/hooks/usePayWithSolanaToken.js.map +1 -0
  214. package/build/src/hooks/usePayWithToken.js +57 -0
  215. package/build/src/hooks/usePayWithToken.js.map +1 -0
  216. package/build/src/hooks/usePaymentState.js +243 -0
  217. package/build/src/hooks/usePaymentState.js.map +1 -0
  218. package/build/src/hooks/usePrevious.js +14 -0
  219. package/build/src/hooks/usePrevious.js.map +1 -0
  220. package/build/src/hooks/useSolanaPaymentOptions.js +37 -0
  221. package/build/src/hooks/useSolanaPaymentOptions.js.map +1 -0
  222. package/build/src/hooks/useWalletConnectModal.js +52 -0
  223. package/build/src/hooks/useWalletConnectModal.js.map +1 -0
  224. package/build/src/hooks/useWalletPaymentOptions.js +40 -0
  225. package/build/src/hooks/useWalletPaymentOptions.js.map +1 -0
  226. package/build/src/hooks/useWindowSize.js +23 -0
  227. package/build/src/hooks/useWindowSize.js.map +1 -0
  228. package/build/src/index.js +10 -0
  229. package/build/src/index.js.map +1 -0
  230. package/build/src/localizations/index.js +57 -0
  231. package/build/src/localizations/index.js.map +1 -0
  232. package/build/src/localizations/locales/ar-AE.js +97 -0
  233. package/build/src/localizations/locales/ar-AE.js.map +1 -0
  234. package/build/src/localizations/locales/ca-AD.js +95 -0
  235. package/build/src/localizations/locales/ca-AD.js.map +1 -0
  236. package/build/src/localizations/locales/ee-EE.js +95 -0
  237. package/build/src/localizations/locales/ee-EE.js.map +1 -0
  238. package/build/src/localizations/locales/en-US.js +95 -0
  239. package/build/src/localizations/locales/en-US.js.map +1 -0
  240. package/build/src/localizations/locales/es-ES.js +95 -0
  241. package/build/src/localizations/locales/es-ES.js.map +1 -0
  242. package/build/src/localizations/locales/fa-IR.js +95 -0
  243. package/build/src/localizations/locales/fa-IR.js.map +1 -0
  244. package/build/src/localizations/locales/fr-FR.js +95 -0
  245. package/build/src/localizations/locales/fr-FR.js.map +1 -0
  246. package/build/src/localizations/locales/ja-JP.js +95 -0
  247. package/build/src/localizations/locales/ja-JP.js.map +1 -0
  248. package/build/src/localizations/locales/pt-BR.js +95 -0
  249. package/build/src/localizations/locales/pt-BR.js.map +1 -0
  250. package/build/src/localizations/locales/ru-RU.js +95 -0
  251. package/build/src/localizations/locales/ru-RU.js.map +1 -0
  252. package/build/src/localizations/locales/tr-TR.js +95 -0
  253. package/build/src/localizations/locales/tr-TR.js.map +1 -0
  254. package/build/src/localizations/locales/vi-VN.js +95 -0
  255. package/build/src/localizations/locales/vi-VN.js.map +1 -0
  256. package/build/src/localizations/locales/zh-CN.js +95 -0
  257. package/build/src/localizations/locales/zh-CN.js.map +1 -0
  258. package/build/src/styles/defaultTheme.js +89 -0
  259. package/build/src/styles/defaultTheme.js.map +1 -0
  260. package/build/src/styles/index.js +329 -0
  261. package/build/src/styles/index.js.map +1 -0
  262. package/build/src/styles/styled/index.js +16 -0
  263. package/build/src/styles/styled/index.js.map +1 -0
  264. package/build/src/styles/themes/base.js +141 -0
  265. package/build/src/styles/themes/base.js.map +1 -0
  266. package/build/src/styles/themes/index.js +13 -0
  267. package/build/src/styles/themes/index.js.map +1 -0
  268. package/build/src/styles/themes/midnight.js +76 -0
  269. package/build/src/styles/themes/midnight.js.map +1 -0
  270. package/build/src/styles/themes/minimal.js +96 -0
  271. package/build/src/styles/themes/minimal.js.map +1 -0
  272. package/build/src/styles/themes/nouns.js +81 -0
  273. package/build/src/styles/themes/nouns.js.map +1 -0
  274. package/build/src/styles/themes/retro.js +106 -0
  275. package/build/src/styles/themes/retro.js.map +1 -0
  276. package/build/src/styles/themes/rounded.js +106 -0
  277. package/build/src/styles/themes/rounded.js.map +1 -0
  278. package/build/src/styles/themes/soft.js +71 -0
  279. package/build/src/styles/themes/soft.js.map +1 -0
  280. package/build/src/styles/themes/web95.js +132 -0
  281. package/build/src/styles/themes/web95.js.map +1 -0
  282. package/build/src/utils/exports.js +12 -0
  283. package/build/src/utils/exports.js.map +1 -0
  284. package/build/src/utils/index.js +39 -0
  285. package/build/src/utils/index.js.map +1 -0
  286. package/build/src/utils/p3.js +16 -0
  287. package/build/src/utils/p3.js.map +1 -0
  288. package/build/src/utils/platform.js +13 -0
  289. package/build/src/utils/platform.js.map +1 -0
  290. package/build/src/utils/trpc.js +14 -0
  291. package/build/src/utils/trpc.js.map +1 -0
  292. package/build/src/utils/wallets.js +14 -0
  293. package/build/src/utils/wallets.js.map +1 -0
  294. package/build/src/wallets/index.js +32 -0
  295. package/build/src/wallets/index.js.map +1 -0
  296. package/build/src/wallets/useWallets.js +86 -0
  297. package/build/src/wallets/useWallets.js.map +1 -0
  298. package/build/src/wallets/walletConfigs.js +362 -0
  299. package/build/src/wallets/walletConfigs.js.map +1 -0
  300. package/package.json +5 -5
  301. package/build/index.es.js +0 -11565
  302. package/build/index.es.js.map +0 -1
@@ -0,0 +1,50 @@
1
+ import { assert, assertNotNull } from '@daimo/common';
2
+ import { useConnection, useWallet } from '@solana/wallet-adapter-react';
3
+ import { VersionedTransaction } from '@solana/web3.js';
4
+ import { hexToBytes } from 'viem';
5
+
6
+ function usePayWithSolanaToken({ trpc, daimoPayOrder, setDaimoPayOrder, createOrHydrate, platform, log, }) {
7
+ const { connection } = useConnection();
8
+ const wallet = useWallet();
9
+ const payWithSolanaToken = async (inputToken) => {
10
+ assert(!!wallet.publicKey, "No wallet connected");
11
+ assert(!!platform && !!daimoPayOrder);
12
+ const orderId = daimoPayOrder.id;
13
+ const { hydratedOrder } = await createOrHydrate({
14
+ order: daimoPayOrder,
15
+ });
16
+ log(`[CHECKOUT] Hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with Solana ${inputToken}`);
17
+ const txHash = await (async () => {
18
+ try {
19
+ const serializedTx = await trpc.getSolanaSwapAndBurnTx.query({
20
+ orderId: orderId.toString(),
21
+ userPublicKey: assertNotNull(wallet.publicKey).toString(),
22
+ inputTokenMint: inputToken,
23
+ });
24
+ const tx = VersionedTransaction.deserialize(hexToBytes(serializedTx));
25
+ const txHash = await wallet.sendTransaction(tx, connection);
26
+ return txHash;
27
+ }
28
+ catch (e) {
29
+ console.error(e);
30
+ setDaimoPayOrder(hydratedOrder);
31
+ throw e;
32
+ }
33
+ finally {
34
+ setDaimoPayOrder(hydratedOrder);
35
+ }
36
+ })();
37
+ // TOOD: get the actual amount sent from the tx logs.
38
+ // We are currently using a fake amount = 0.
39
+ trpc.processSolanaSourcePayment.mutate({
40
+ orderId: orderId.toString(),
41
+ startIntentTxHash: txHash,
42
+ token: inputToken,
43
+ });
44
+ return txHash;
45
+ };
46
+ return { payWithSolanaToken };
47
+ }
48
+
49
+ export { usePayWithSolanaToken };
50
+ //# sourceMappingURL=usePayWithSolanaToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePayWithSolanaToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,57 @@
1
+ import { assert, assertNotNull } from '@daimo/common';
2
+ import { zeroAddress, erc20Abi, getAddress } from 'viem';
3
+ import { useWriteContract, useSendTransaction } from 'wagmi';
4
+
5
+ function usePayWithToken({ trpc, senderAddr, daimoPayOrder, setDaimoPayOrder, createOrHydrate, platform, log, }) {
6
+ const { writeContractAsync } = useWriteContract();
7
+ const { sendTransactionAsync } = useSendTransaction();
8
+ /** Commit to a token + amount = initiate payment. */
9
+ const payWithToken = async (tokenAmount) => {
10
+ assert(!!daimoPayOrder && !!platform);
11
+ const { hydratedOrder } = await createOrHydrate({
12
+ order: daimoPayOrder,
13
+ refundAddress: senderAddr,
14
+ });
15
+ log(`[CHECKOUT] Hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with ${tokenAmount.token.token}`);
16
+ const txHash = await (async () => {
17
+ try {
18
+ if (tokenAmount.token.token === zeroAddress) {
19
+ return await sendTransactionAsync({
20
+ to: hydratedOrder.intentAddr,
21
+ value: BigInt(tokenAmount.amount),
22
+ });
23
+ }
24
+ else {
25
+ return await writeContractAsync({
26
+ abi: erc20Abi,
27
+ address: getAddress(tokenAmount.token.token),
28
+ functionName: "transfer",
29
+ args: [hydratedOrder.intentAddr, BigInt(tokenAmount.amount)],
30
+ });
31
+ }
32
+ }
33
+ catch (e) {
34
+ console.error(`[CHECKOUT] Error sending token: ${e}`);
35
+ setDaimoPayOrder(hydratedOrder);
36
+ throw e;
37
+ }
38
+ finally {
39
+ setDaimoPayOrder(hydratedOrder);
40
+ }
41
+ })();
42
+ if (txHash) {
43
+ await trpc.processSourcePayment.mutate({
44
+ orderId: daimoPayOrder.id.toString(),
45
+ sourceInitiateTxHash: txHash,
46
+ sourceChainId: tokenAmount.token.chainId,
47
+ sourceFulfillerAddr: assertNotNull(senderAddr),
48
+ sourceToken: tokenAmount.token.token,
49
+ sourceAmount: tokenAmount.amount,
50
+ });
51
+ }
52
+ };
53
+ return { payWithToken };
54
+ }
55
+
56
+ export { usePayWithToken };
57
+ //# sourceMappingURL=usePayWithToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePayWithToken.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,243 @@
1
+ import { readDaimoPayOrderID, assert, assertNotNull, debugJson } from '@daimo/common';
2
+ import { ethereum } from '@daimo/contract';
3
+ import { useWallet } from '@solana/wallet-adapter-react';
4
+ import { useState, useEffect, useCallback } from 'react';
5
+ import { parseUnits, formatUnits } from 'viem';
6
+ import { useAccount, useEnsName } from 'wagmi';
7
+ import { generatePayId } from '../utils/exports.js';
8
+ import { detectPlatform } from '../utils/platform.js';
9
+ import { useDepositAddressOptions } from './useDepositAddressOptions.js';
10
+ import { useExternalPaymentOptions } from './useExternalPaymentOptions.js';
11
+ import { usePayWithSolanaToken } from './usePayWithSolanaToken.js';
12
+ import { usePayWithToken } from './usePayWithToken.js';
13
+ import { useSolanaPaymentOptions } from './useSolanaPaymentOptions.js';
14
+ import { useWalletPaymentOptions } from './useWalletPaymentOptions.js';
15
+
16
+ function usePaymentState({ trpc, daimoPayOrder, setDaimoPayOrder, setOpen, log, }) {
17
+ // Browser state.
18
+ const [platform, setPlatform] = useState();
19
+ useEffect(() => {
20
+ setPlatform(detectPlatform(window.navigator.userAgent));
21
+ }, []);
22
+ // Wallet state.
23
+ const { address: senderAddr } = useAccount();
24
+ const { data: senderEnsName } = useEnsName({
25
+ chainId: ethereum.chainId,
26
+ address: senderAddr,
27
+ });
28
+ // Solana wallet state.
29
+ const solanaWallet = useWallet();
30
+ const solanaPubKey = solanaWallet.publicKey?.toBase58();
31
+ // Daimo Pay order state.
32
+ const [payParams, setPayParamsState] = useState();
33
+ const [paymentWaitingMessage, setPaymentWaitingMessage] = useState();
34
+ // Payment UI config.
35
+ const [modalOptions, setModalOptions] = useState({});
36
+ // UI state. Selection for external payment (Binance, etc) vs wallet payment.
37
+ const externalPaymentOptions = useExternalPaymentOptions({
38
+ trpc,
39
+ filterIds: daimoPayOrder?.metadata.payer?.paymentOptions,
40
+ usdRequired: daimoPayOrder?.destFinalCallTokenAmount.usd,
41
+ platform,
42
+ });
43
+ const walletPaymentOptions = useWalletPaymentOptions({
44
+ trpc,
45
+ address: senderAddr,
46
+ usdRequired: daimoPayOrder?.destFinalCallTokenAmount.usd,
47
+ destChainId: daimoPayOrder?.destFinalCallTokenAmount.token.chainId,
48
+ preferredChains: daimoPayOrder?.metadata.payer?.preferredChains,
49
+ preferredTokens: daimoPayOrder?.metadata.payer?.preferredTokens,
50
+ });
51
+ const solanaPaymentOptions = useSolanaPaymentOptions({
52
+ trpc,
53
+ address: solanaPubKey,
54
+ usdRequired: daimoPayOrder?.destFinalCallTokenAmount.usd,
55
+ });
56
+ const depositAddressOptions = useDepositAddressOptions({
57
+ trpc,
58
+ usdRequired: daimoPayOrder?.destFinalCallTokenAmount.usd ?? 0,
59
+ });
60
+ /** Create a new order or hydrate an existing one. */
61
+ const createOrHydrate = async ({ order, refundAddress, externalPaymentOption, }) => {
62
+ assert(!!platform, "missing platform");
63
+ if (payParams == null) {
64
+ log(`[CHECKOUT] hydrating existing order ${order.id}`);
65
+ return await trpc.hydrateOrder.query({
66
+ id: order.id.toString(),
67
+ chosenFinalTokenAmount: order.destFinalCallTokenAmount.amount,
68
+ platform,
69
+ refundAddress,
70
+ externalPaymentOption,
71
+ });
72
+ }
73
+ log(`[CHECKOUT] creating+hydrating new order ${order.id}`);
74
+ // Update units, if amountEditable the user may have changed the amount.
75
+ const toUnits = formatUnits(BigInt(order.destFinalCallTokenAmount.amount), order.destFinalCallTokenAmount.token.decimals);
76
+ return await trpc.createOrder.mutate({
77
+ appId: payParams.appId,
78
+ paymentInput: {
79
+ ...payParams,
80
+ id: order.id.toString(),
81
+ toUnits: toUnits,
82
+ metadata: order.metadata,
83
+ },
84
+ platform,
85
+ refundAddress,
86
+ externalPaymentOption,
87
+ });
88
+ };
89
+ const { payWithToken } = usePayWithToken({
90
+ trpc,
91
+ senderAddr,
92
+ daimoPayOrder,
93
+ setDaimoPayOrder,
94
+ createOrHydrate,
95
+ platform,
96
+ log,
97
+ });
98
+ const { payWithSolanaToken } = usePayWithSolanaToken({
99
+ trpc,
100
+ daimoPayOrder,
101
+ setDaimoPayOrder,
102
+ createOrHydrate,
103
+ platform,
104
+ log,
105
+ });
106
+ const [selectedExternalOption, setSelectedExternalOption] = useState();
107
+ const [selectedTokenOption, setSelectedTokenOption] = useState();
108
+ const [selectedSolanaTokenOption, setSelectedSolanaTokenOption] = useState();
109
+ const [selectedDepositAddressOption, setSelectedDepositAddressOption] = useState();
110
+ const payWithExternal = async (option) => {
111
+ assert(!!daimoPayOrder && !!platform);
112
+ const { hydratedOrder, externalPaymentOptionData } = await createOrHydrate({
113
+ order: daimoPayOrder,
114
+ externalPaymentOption: option,
115
+ });
116
+ assert(!!externalPaymentOptionData, "missing externalPaymentOptionData");
117
+ log(`[CHECKOUT] Hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with external payment: ${option}`);
118
+ setPaymentWaitingMessage(externalPaymentOptionData.waitingMessage);
119
+ setDaimoPayOrder(hydratedOrder);
120
+ return externalPaymentOptionData.url;
121
+ };
122
+ const payWithDepositAddress = async (option) => {
123
+ assert(!!daimoPayOrder);
124
+ const { hydratedOrder } = await createOrHydrate({
125
+ order: daimoPayOrder,
126
+ });
127
+ setDaimoPayOrder(hydratedOrder);
128
+ log(`[CHECKOUT] Hydrated order: ${JSON.stringify(hydratedOrder)}, checking out with deposit address: ${option}`);
129
+ const depositAddressOption = await trpc.getDepositAddressOptionData.query({
130
+ input: option,
131
+ usdRequired: daimoPayOrder.destFinalCallTokenAmount.usd,
132
+ toAddress: assertNotNull(hydratedOrder.intentAddr),
133
+ });
134
+ return depositAddressOption;
135
+ };
136
+ const refreshOrder = useCallback(async () => {
137
+ const id = daimoPayOrder?.id?.toString();
138
+ if (!id)
139
+ return;
140
+ const { order } = await trpc.getOrder.query({
141
+ id,
142
+ });
143
+ setDaimoPayOrder(order);
144
+ }, [daimoPayOrder?.id]);
145
+ /** User picked a different deposit amount. */
146
+ const setChosenUsd = (usdAmount) => {
147
+ log(`[CHECKOUT] Setting chosen USD amount to ${usdAmount}`);
148
+ assert(!!daimoPayOrder);
149
+ const token = daimoPayOrder.destFinalCallTokenAmount.token;
150
+ const tokenAmount = parseUnits((usdAmount / token.usd).toString(), token.decimals);
151
+ // TODO: remove amount from destFinalCall, it is redundant with
152
+ // destFinalCallTokenAmount. Here, we only modify one and not the other.
153
+ setDaimoPayOrder({
154
+ ...daimoPayOrder,
155
+ destFinalCallTokenAmount: {
156
+ token,
157
+ amount: tokenAmount.toString(),
158
+ usd: usdAmount,
159
+ },
160
+ });
161
+ };
162
+ const setPayId = useCallback(async (payId) => {
163
+ if (!payId)
164
+ return;
165
+ const id = readDaimoPayOrderID(payId).toString();
166
+ if (daimoPayOrder && BigInt(id) == daimoPayOrder.id) {
167
+ // Already loaded, ignore.
168
+ return;
169
+ }
170
+ const { order } = await trpc.getOrder.query({ id });
171
+ if (!order) {
172
+ console.error(`[CHECKOUT] No order found for ${payId}`);
173
+ return;
174
+ }
175
+ log(`[CHECKOUT] fetched order: ${JSON.stringify(order)}`);
176
+ setDaimoPayOrder(order);
177
+ }, [daimoPayOrder]);
178
+ /** Called whenever params change. */
179
+ const setPayParams = async (payParams) => {
180
+ console.log(`[CHECKOUT] setting payParams: ${debugJson(payParams)}`);
181
+ assert(payParams != null);
182
+ setPayParamsState(payParams);
183
+ const newPayId = generatePayId();
184
+ const newId = readDaimoPayOrderID(newPayId).toString();
185
+ const payment = await trpc.previewOrder.query({
186
+ id: newId,
187
+ toChain: payParams.toChain,
188
+ toToken: payParams.toToken,
189
+ toUnits: payParams.toUnits,
190
+ toAddress: payParams.toAddress,
191
+ toCallData: payParams.toCallData,
192
+ isAmountEditable: payParams.isAmountEditable,
193
+ metadata: {
194
+ intent: payParams.intent ?? "Pay",
195
+ items: [],
196
+ payer: {
197
+ paymentOptions: payParams.paymentOptions,
198
+ preferredChains: payParams.preferredChains,
199
+ preferredTokens: payParams.preferredTokens,
200
+ },
201
+ },
202
+ });
203
+ setDaimoPayOrder(payment);
204
+ };
205
+ const onSuccess = ({ txHash, txURL }) => {
206
+ if (modalOptions?.closeOnSuccess) {
207
+ log(`[CHECKOUT] transaction succeeded, closing: ${txHash} ${txURL}`);
208
+ setTimeout(() => setOpen(false), 1000);
209
+ }
210
+ };
211
+ return {
212
+ setPayId,
213
+ payParams,
214
+ setPayParams,
215
+ daimoPayOrder,
216
+ modalOptions,
217
+ setModalOptions,
218
+ paymentWaitingMessage,
219
+ selectedExternalOption,
220
+ selectedTokenOption,
221
+ selectedSolanaTokenOption,
222
+ externalPaymentOptions,
223
+ walletPaymentOptions,
224
+ solanaPaymentOptions,
225
+ depositAddressOptions,
226
+ selectedDepositAddressOption,
227
+ setSelectedDepositAddressOption,
228
+ setSelectedExternalOption,
229
+ setSelectedTokenOption,
230
+ setSelectedSolanaTokenOption,
231
+ setChosenUsd,
232
+ payWithToken,
233
+ payWithExternal,
234
+ payWithDepositAddress,
235
+ payWithSolanaToken,
236
+ refreshOrder,
237
+ onSuccess,
238
+ senderEnsName: senderEnsName ?? undefined,
239
+ };
240
+ }
241
+
242
+ export { usePaymentState };
243
+ //# sourceMappingURL=usePaymentState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePaymentState.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,14 @@
1
+ import { useRef } from 'react';
2
+
3
+ function usePrevious(value, initial) {
4
+ const ref = useRef({ target: value, previous: initial });
5
+ if (ref.current.target !== value) {
6
+ // The value changed.
7
+ ref.current.previous = ref.current.target;
8
+ ref.current.target = value;
9
+ }
10
+ return ref.current.previous;
11
+ }
12
+
13
+ export { usePrevious as default };
14
+ //# sourceMappingURL=usePrevious.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePrevious.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
@@ -0,0 +1,37 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ function useSolanaPaymentOptions({ trpc, address, usdRequired, }) {
4
+ const [options, setOptions] = useState(null);
5
+ const [isLoading, setIsLoading] = useState(false);
6
+ useEffect(() => {
7
+ const refreshWalletPaymentOptions = async () => {
8
+ if (!address || !usdRequired)
9
+ return;
10
+ setOptions(null);
11
+ setIsLoading(true);
12
+ try {
13
+ const newOptions = await trpc.getSolanaPaymentOptions.query({
14
+ pubKey: address,
15
+ usdRequired,
16
+ });
17
+ setOptions(newOptions);
18
+ }
19
+ catch (error) {
20
+ console.error(error);
21
+ }
22
+ finally {
23
+ setIsLoading(false);
24
+ }
25
+ };
26
+ if (address && usdRequired != null) {
27
+ refreshWalletPaymentOptions();
28
+ }
29
+ }, [address, usdRequired]);
30
+ return {
31
+ options,
32
+ isLoading,
33
+ };
34
+ }
35
+
36
+ export { useSolanaPaymentOptions };
37
+ //# sourceMappingURL=useSolanaPaymentOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSolanaPaymentOptions.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,52 @@
1
+ import { useState } from 'react';
2
+ import { walletConnect } from 'wagmi/connectors';
3
+ import { usePayContext } from '../components/DaimoPay.js';
4
+ import { isWalletConnectConnector } from '../utils/index.js';
5
+ import { useConnect } from './useConnect.js';
6
+
7
+ function useWalletConnectModal() {
8
+ const { log } = usePayContext();
9
+ const { connectAsync, connectors } = useConnect();
10
+ const [isOpen, setIsOpen] = useState(false);
11
+ return {
12
+ isOpen,
13
+ open: async () => {
14
+ // add modal styling because wagmi does not let you add styling to the modal
15
+ const w3mcss = document.createElement("style");
16
+ w3mcss.innerHTML = `w3m-modal, wcm-modal{ --wcm-z-index: 2147483647; --w3m-z-index:2147483647; }`;
17
+ document.head.appendChild(w3mcss);
18
+ const clientConnector = connectors.find((c) => isWalletConnectConnector(c.id));
19
+ if (clientConnector == null) {
20
+ log("No WalletConnect connector available");
21
+ return;
22
+ }
23
+ try {
24
+ const provider = await clientConnector.getProvider();
25
+ const projectId = provider.rpc.projectId;
26
+ const connector = walletConnect({
27
+ projectId,
28
+ showQrModal: true,
29
+ });
30
+ setIsOpen(true);
31
+ try {
32
+ await connectAsync({ connector: connector });
33
+ }
34
+ catch (err) {
35
+ log("WalletConnect", err);
36
+ }
37
+ setIsOpen(false);
38
+ // remove modal styling
39
+ try {
40
+ document.head.removeChild(w3mcss);
41
+ }
42
+ catch { }
43
+ }
44
+ catch (err) {
45
+ log("Could not get WalletConnect provider", err);
46
+ }
47
+ },
48
+ };
49
+ }
50
+
51
+ export { useWalletConnectModal };
52
+ //# sourceMappingURL=useWalletConnectModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWalletConnectModal.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,40 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ function useWalletPaymentOptions({ trpc, address, usdRequired, destChainId, preferredChains, preferredTokens, }) {
4
+ const [options, setOptions] = useState(null);
5
+ const [isLoading, setIsLoading] = useState(false);
6
+ useEffect(() => {
7
+ const refreshWalletPaymentOptions = async () => {
8
+ if (!address || !usdRequired || !destChainId)
9
+ return;
10
+ setOptions(null);
11
+ setIsLoading(true);
12
+ try {
13
+ const newOptions = await trpc.getWalletPaymentOptions.query({
14
+ payerAddress: address,
15
+ usdRequired,
16
+ destChainId,
17
+ preferredChains,
18
+ preferredTokens,
19
+ });
20
+ setOptions(newOptions);
21
+ }
22
+ catch (error) {
23
+ console.error(error);
24
+ }
25
+ finally {
26
+ setIsLoading(false);
27
+ }
28
+ };
29
+ if (address && usdRequired != null && destChainId) {
30
+ refreshWalletPaymentOptions();
31
+ }
32
+ }, [address, usdRequired, destChainId]);
33
+ return {
34
+ options,
35
+ isLoading,
36
+ };
37
+ }
38
+
39
+ export { useWalletPaymentOptions };
40
+ //# sourceMappingURL=useWalletPaymentOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWalletPaymentOptions.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,23 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ function useWindowSize() {
4
+ const [windowSize, setWindowSize] = useState({
5
+ width: 0,
6
+ height: 0,
7
+ });
8
+ useEffect(() => {
9
+ function handleResize() {
10
+ setWindowSize({
11
+ width: window.innerWidth,
12
+ height: window.innerHeight,
13
+ });
14
+ }
15
+ window.addEventListener("resize", handleResize);
16
+ handleResize();
17
+ return () => window.removeEventListener("resize", handleResize);
18
+ }, []);
19
+ return windowSize;
20
+ }
21
+
22
+ export { useWindowSize as default };
23
+ //# sourceMappingURL=useWindowSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWindowSize.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ export { DaimoPayProvider } from './components/DaimoPay.js';
2
+ export { default as getDefaultConfig } from './defaultConfig.js';
3
+ export { DaimoPayButton } from './components/DaimoPayButton/index.js';
4
+ export { useDaimoPayStatus } from './hooks/useDaimoPayStatus.js';
5
+ export { useModal as useDaimoPayModal } from './hooks/useModal.js';
6
+ export { default as Avatar } from './components/Common/Avatar/index.js';
7
+ export { default as ChainIcon } from './components/Common/Chain/index.js';
8
+ export { wallets } from './wallets/index.js';
9
+ export { generatePayId } from './utils/exports.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,57 @@
1
+ import arAE from './locales/ar-AE.js';
2
+ import caAD from './locales/ca-AD.js';
3
+ import eeEE from './locales/ee-EE.js';
4
+ import enUS from './locales/en-US.js';
5
+ import esES from './locales/es-ES.js';
6
+ import faIR from './locales/fa-IR.js';
7
+ import frFR from './locales/fr-FR.js';
8
+ import jaJP from './locales/ja-JP.js';
9
+ import ptBR from './locales/pt-BR.js';
10
+ import ruRU from './locales/ru-RU.js';
11
+ import trTR from './locales/tr-TR.js';
12
+ import viVN from './locales/vi-VN.js';
13
+ import zhCN from './locales/zh-CN.js';
14
+
15
+ // TODO: tree-shaking
16
+ const getLocale = (lang) => {
17
+ switch (lang) {
18
+ case "ee-EE":
19
+ return eeEE;
20
+ case "ar-AE":
21
+ return arAE;
22
+ case "es-ES":
23
+ return esES;
24
+ case "fa-IR":
25
+ return faIR;
26
+ case "fr-FR":
27
+ return frFR;
28
+ case "ja-JP":
29
+ return jaJP;
30
+ case "pt-BR":
31
+ return ptBR;
32
+ case "ru-RU":
33
+ return ruRU;
34
+ case "zh-CN":
35
+ return zhCN;
36
+ case "ca-AD":
37
+ return caAD;
38
+ case "tr-TR":
39
+ return trTR;
40
+ case "vi-VN":
41
+ return viVN;
42
+ default:
43
+ return enUS;
44
+ }
45
+ };
46
+ /*
47
+ // Could be useful for locale files to use these keys rather than hard-coded into the objects
48
+ export const keys = {
49
+ connectorName: '{{ CONNECTORNAME }}',
50
+ connectorShortName: '{{ CONNECTORSHORTNAME }}',
51
+ suggestedExtensionBrowser: '{{ SUGGESTEDEXTENSIONBROWSER }}',
52
+ walletConnectLogo: '{{ WALLETCONNECTLOGO }}',
53
+ };
54
+ */
55
+
56
+ export { getLocale };
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}