@unchainedshop/plugins 3.1.15 → 4.0.0-rc.11

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 (331) hide show
  1. package/lib/delivery/pick-mup.js +0 -2
  2. package/lib/delivery/pick-mup.js.map +1 -1
  3. package/lib/files/gridfs/adapter.d.ts.map +1 -1
  4. package/lib/files/gridfs/adapter.js +2 -2
  5. package/lib/files/gridfs/adapter.js.map +1 -1
  6. package/lib/files/gridfs/handler-express.d.ts.map +1 -1
  7. package/lib/files/gridfs/handler-express.js +6 -1
  8. package/lib/files/gridfs/handler-express.js.map +1 -1
  9. package/lib/files/gridfs/handler-fastify.d.ts.map +1 -1
  10. package/lib/files/gridfs/handler-fastify.js +5 -1
  11. package/lib/files/gridfs/handler-fastify.js.map +1 -1
  12. package/lib/files/gridfs/module.d.ts +2 -2
  13. package/lib/files/gridfs/module.d.ts.map +1 -1
  14. package/lib/filters/local-search.d.ts.map +1 -1
  15. package/lib/filters/local-search.js +9 -2
  16. package/lib/filters/local-search.js.map +1 -1
  17. package/lib/filters/strict-equal.js +18 -0
  18. package/lib/filters/strict-equal.js.map +1 -1
  19. package/lib/payment/apple-iap/adapter.js +6 -13
  20. package/lib/payment/apple-iap/adapter.js.map +1 -1
  21. package/lib/payment/apple-iap/fix-periods.d.ts.map +1 -1
  22. package/lib/payment/apple-iap/fix-periods.js +3 -5
  23. package/lib/payment/apple-iap/fix-periods.js.map +1 -1
  24. package/lib/payment/apple-iap/handler-express.js +4 -4
  25. package/lib/payment/apple-iap/handler-express.js.map +1 -1
  26. package/lib/payment/apple-iap/handler-fastify.js +4 -4
  27. package/lib/payment/apple-iap/handler-fastify.js.map +1 -1
  28. package/lib/payment/apple-iap/module.d.ts +2 -2
  29. package/lib/payment/apple-iap/module.d.ts.map +1 -1
  30. package/lib/payment/braintree.js +3 -4
  31. package/lib/payment/braintree.js.map +1 -1
  32. package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts +1 -2
  33. package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts.map +1 -1
  34. package/lib/payment/cryptopay/db/CryptopayTransactions.js.map +1 -1
  35. package/lib/payment/cryptopay/handle-webhook.js +1 -1
  36. package/lib/payment/cryptopay/handle-webhook.js.map +1 -1
  37. package/lib/payment/cryptopay/handler-express.d.ts.map +1 -1
  38. package/lib/payment/cryptopay/handler-express.js +4 -57
  39. package/lib/payment/cryptopay/handler-express.js.map +1 -1
  40. package/lib/payment/cryptopay/handler-fastify.d.ts.map +1 -1
  41. package/lib/payment/cryptopay/handler-fastify.js +4 -56
  42. package/lib/payment/cryptopay/handler-fastify.js.map +1 -1
  43. package/lib/payment/cryptopay/module.d.ts +26 -26
  44. package/lib/payment/cryptopay/module.d.ts.map +1 -1
  45. package/lib/payment/cryptopay/module.js +26 -24
  46. package/lib/payment/cryptopay/module.js.map +1 -1
  47. package/lib/payment/cryptopay/plugin.d.ts.map +1 -1
  48. package/lib/payment/cryptopay/plugin.js +33 -79
  49. package/lib/payment/cryptopay/plugin.js.map +1 -1
  50. package/lib/payment/datatrans-v2/api/types.d.ts +41 -41
  51. package/lib/payment/datatrans-v2/api/types.d.ts.map +1 -1
  52. package/lib/payment/datatrans-v2/getPaths.d.ts +2 -2
  53. package/lib/payment/datatrans-v2/getPaths.d.ts.map +1 -1
  54. package/lib/payment/datatrans-v2/index.js +16 -14
  55. package/lib/payment/datatrans-v2/index.js.map +1 -1
  56. package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts +1 -1
  57. package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts.map +1 -1
  58. package/lib/payment/datatrans-v2/roundedAmountFromOrder.js +3 -3
  59. package/lib/payment/datatrans-v2/roundedAmountFromOrder.js.map +1 -1
  60. package/lib/payment/paypal-checkout.js +6 -8
  61. package/lib/payment/paypal-checkout.js.map +1 -1
  62. package/lib/payment/payrexx/api/index.d.ts +2 -2
  63. package/lib/payment/payrexx/api/index.d.ts.map +1 -1
  64. package/lib/payment/payrexx/api/makeFetcher.d.ts.map +1 -1
  65. package/lib/payment/payrexx/api/makeFetcher.js.map +1 -1
  66. package/lib/payment/payrexx/index.js +4 -4
  67. package/lib/payment/payrexx/index.js.map +1 -1
  68. package/lib/payment/payrexx/payrexx.js +2 -2
  69. package/lib/payment/payrexx/payrexx.js.map +1 -1
  70. package/lib/payment/postfinance-checkout/api-client.d.ts +16 -0
  71. package/lib/payment/postfinance-checkout/api-client.d.ts.map +1 -0
  72. package/lib/payment/postfinance-checkout/api-client.js +75 -0
  73. package/lib/payment/postfinance-checkout/api-client.js.map +1 -0
  74. package/lib/payment/postfinance-checkout/api-types.d.ts +98 -0
  75. package/lib/payment/postfinance-checkout/api-types.d.ts.map +1 -0
  76. package/lib/payment/postfinance-checkout/api-types.js +51 -0
  77. package/lib/payment/postfinance-checkout/api-types.js.map +1 -0
  78. package/lib/payment/postfinance-checkout/api.d.ts +5 -5
  79. package/lib/payment/postfinance-checkout/api.d.ts.map +1 -1
  80. package/lib/payment/postfinance-checkout/api.js +38 -62
  81. package/lib/payment/postfinance-checkout/api.js.map +1 -1
  82. package/lib/payment/postfinance-checkout/handler-express.d.ts.map +1 -1
  83. package/lib/payment/postfinance-checkout/handler-express.js +5 -5
  84. package/lib/payment/postfinance-checkout/handler-express.js.map +1 -1
  85. package/lib/payment/postfinance-checkout/handler-fastify.d.ts.map +1 -1
  86. package/lib/payment/postfinance-checkout/handler-fastify.js +6 -6
  87. package/lib/payment/postfinance-checkout/handler-fastify.js.map +1 -1
  88. package/lib/payment/postfinance-checkout/index.d.ts +2 -1
  89. package/lib/payment/postfinance-checkout/index.d.ts.map +1 -1
  90. package/lib/payment/postfinance-checkout/index.js +27 -30
  91. package/lib/payment/postfinance-checkout/index.js.map +1 -1
  92. package/lib/payment/postfinance-checkout/types.d.ts +4 -4
  93. package/lib/payment/postfinance-checkout/types.d.ts.map +1 -1
  94. package/lib/payment/postfinance-checkout/utils.d.ts +3 -3
  95. package/lib/payment/postfinance-checkout/utils.d.ts.map +1 -1
  96. package/lib/payment/postfinance-checkout/utils.js +5 -6
  97. package/lib/payment/postfinance-checkout/utils.js.map +1 -1
  98. package/lib/payment/saferpay/adapter.d.ts.map +1 -1
  99. package/lib/payment/saferpay/adapter.js +4 -6
  100. package/lib/payment/saferpay/adapter.js.map +1 -1
  101. package/lib/payment/saferpay/api/models/Transaction.d.ts +2 -2
  102. package/lib/payment/saferpay/api/models/Transaction.d.ts.map +1 -1
  103. package/lib/payment/saferpay/module.d.ts +2 -2
  104. package/lib/payment/saferpay/module.d.ts.map +1 -1
  105. package/lib/payment/stripe/index.js +5 -5
  106. package/lib/payment/stripe/index.js.map +1 -1
  107. package/lib/payment/stripe/stripe.js +3 -3
  108. package/lib/payment/stripe/stripe.js.map +1 -1
  109. package/lib/presets/all.d.ts +15 -13
  110. package/lib/presets/all.d.ts.map +1 -1
  111. package/lib/presets/all.js +3 -1
  112. package/lib/presets/all.js.map +1 -1
  113. package/lib/pricing/delivery-swiss-tax.d.ts.map +1 -1
  114. package/lib/pricing/delivery-swiss-tax.js +2 -2
  115. package/lib/pricing/delivery-swiss-tax.js.map +1 -1
  116. package/lib/pricing/order-delivery.js +1 -1
  117. package/lib/pricing/order-delivery.js.map +1 -1
  118. package/lib/pricing/order-discount.js +3 -3
  119. package/lib/pricing/order-discount.js.map +1 -1
  120. package/lib/pricing/order-items-discount.js +1 -1
  121. package/lib/pricing/order-items-discount.js.map +1 -1
  122. package/lib/pricing/order-items.js +1 -1
  123. package/lib/pricing/order-items.js.map +1 -1
  124. package/lib/pricing/order-payment.js +1 -1
  125. package/lib/pricing/order-payment.js.map +1 -1
  126. package/lib/pricing/order-round.d.ts +1 -1
  127. package/lib/pricing/order-round.d.ts.map +1 -1
  128. package/lib/pricing/order-round.js +8 -8
  129. package/lib/pricing/order-round.js.map +1 -1
  130. package/lib/pricing/product-catalog-price.d.ts +0 -1
  131. package/lib/pricing/product-catalog-price.d.ts.map +1 -1
  132. package/lib/pricing/product-catalog-price.js +6 -18
  133. package/lib/pricing/product-catalog-price.js.map +1 -1
  134. package/lib/pricing/product-price-rateconversion.js +2 -2
  135. package/lib/pricing/product-price-rateconversion.js.map +1 -1
  136. package/lib/pricing/product-round.d.ts +1 -1
  137. package/lib/pricing/product-round.d.ts.map +1 -1
  138. package/lib/pricing/product-round.js +2 -2
  139. package/lib/pricing/product-round.js.map +1 -1
  140. package/lib/pricing/product-swiss-tax.d.ts +1 -1
  141. package/lib/pricing/product-swiss-tax.d.ts.map +1 -1
  142. package/lib/pricing/product-swiss-tax.js +2 -2
  143. package/lib/pricing/product-swiss-tax.js.map +1 -1
  144. package/lib/warehousing/eth-minter.js +2 -2
  145. package/lib/warehousing/eth-minter.js.map +1 -1
  146. package/lib/worker/budgetsms.d.ts +10 -0
  147. package/lib/worker/budgetsms.d.ts.map +1 -0
  148. package/lib/worker/budgetsms.js +217 -0
  149. package/lib/worker/budgetsms.js.map +1 -0
  150. package/lib/worker/bulk-import.js +1 -1
  151. package/lib/worker/bulk-import.js.map +1 -1
  152. package/lib/worker/bulkgate.d.ts +2 -0
  153. package/lib/worker/bulkgate.d.ts.map +1 -0
  154. package/lib/worker/bulkgate.js +104 -0
  155. package/lib/worker/bulkgate.js.map +1 -0
  156. package/lib/worker/enrollment-order-generator.js +1 -1
  157. package/lib/worker/enrollment-order-generator.js.map +1 -1
  158. package/lib/worker/error-notifications.d.ts +4 -4
  159. package/lib/worker/error-notifications.d.ts.map +1 -1
  160. package/lib/worker/heartbeat.js +2 -8
  161. package/lib/worker/heartbeat.js.map +1 -1
  162. package/lib/worker/message.d.ts +1 -1
  163. package/lib/worker/message.d.ts.map +1 -1
  164. package/lib/worker/sms.js +16 -16
  165. package/lib/worker/sms.js.map +1 -1
  166. package/lib/worker/twilio.d.ts +2 -0
  167. package/lib/worker/twilio.d.ts.map +1 -0
  168. package/lib/worker/twilio.js +56 -0
  169. package/lib/worker/twilio.js.map +1 -0
  170. package/lib/worker/update-coinbase-rates.js +1 -1
  171. package/lib/worker/update-coinbase-rates.js.map +1 -1
  172. package/lib/worker/update-ecb-rates.js.map +1 -1
  173. package/package.json +32 -53
  174. package/src/delivery/pick-mup.ts +0 -2
  175. package/src/files/gridfs/adapter.ts +6 -2
  176. package/src/files/gridfs/handler-express.ts +9 -1
  177. package/src/files/gridfs/handler-fastify.ts +8 -1
  178. package/src/files/gridfs/module.ts +2 -2
  179. package/src/filters/local-search.ts +11 -2
  180. package/src/filters/strict-equal.ts +21 -0
  181. package/src/payment/apple-iap/adapter.ts +7 -14
  182. package/src/payment/apple-iap/fix-periods.ts +4 -7
  183. package/src/payment/apple-iap/handler-express.ts +4 -4
  184. package/src/payment/apple-iap/handler-fastify.ts +4 -4
  185. package/src/payment/apple-iap/module.ts +2 -2
  186. package/src/payment/braintree.ts +3 -4
  187. package/src/payment/cryptopay/db/CryptopayTransactions.ts +1 -2
  188. package/src/payment/cryptopay/denote-amount.test.ts +28 -0
  189. package/src/payment/cryptopay/denote-amount.ts +29 -0
  190. package/src/payment/cryptopay/derive-btc-address.test.ts +22 -0
  191. package/src/payment/cryptopay/derive-btc-address.ts +48 -0
  192. package/src/payment/cryptopay/derive-eth-address.test.ts +22 -0
  193. package/src/payment/cryptopay/derive-eth-address.ts +38 -0
  194. package/src/payment/cryptopay/handle-webhook.ts +103 -0
  195. package/src/payment/cryptopay/handler-express.ts +4 -70
  196. package/src/payment/cryptopay/handler-fastify.ts +6 -71
  197. package/src/payment/cryptopay/module.ts +44 -40
  198. package/src/payment/cryptopay/plugin.ts +50 -87
  199. package/src/payment/cryptopay/readme.md +23 -1
  200. package/src/payment/datatrans-v2/api/types.ts +41 -41
  201. package/src/payment/datatrans-v2/getPaths.ts +2 -2
  202. package/src/payment/datatrans-v2/index.ts +17 -15
  203. package/src/payment/datatrans-v2/roundedAmountFromOrder.ts +4 -4
  204. package/src/payment/paypal-checkout.ts +6 -11
  205. package/src/payment/payrexx/api/index.ts +2 -2
  206. package/src/payment/payrexx/api/makeFetcher.ts +1 -1
  207. package/src/payment/payrexx/index.ts +4 -4
  208. package/src/payment/payrexx/payrexx.ts +2 -2
  209. package/src/payment/postfinance-checkout/api-client.ts +106 -0
  210. package/src/payment/postfinance-checkout/api-types.ts +111 -0
  211. package/src/payment/postfinance-checkout/api.ts +58 -85
  212. package/src/payment/postfinance-checkout/handler-express.ts +5 -7
  213. package/src/payment/postfinance-checkout/handler-fastify.ts +6 -8
  214. package/src/payment/postfinance-checkout/index.ts +43 -35
  215. package/src/payment/postfinance-checkout/types.ts +6 -6
  216. package/src/payment/postfinance-checkout/utils.ts +7 -12
  217. package/src/payment/saferpay/adapter.ts +4 -6
  218. package/src/payment/saferpay/api/models/Transaction.ts +2 -2
  219. package/src/payment/saferpay/module.ts +2 -2
  220. package/src/payment/stripe/index.ts +5 -5
  221. package/src/payment/stripe/stripe.ts +3 -3
  222. package/src/presets/all.ts +3 -1
  223. package/src/pricing/delivery-swiss-tax.ts +6 -2
  224. package/src/pricing/order-delivery.ts +1 -1
  225. package/src/pricing/order-discount.ts +3 -3
  226. package/src/pricing/order-items-discount.ts +1 -1
  227. package/src/pricing/order-items.ts +1 -1
  228. package/src/pricing/order-payment.ts +1 -1
  229. package/src/pricing/order-round.ts +9 -9
  230. package/src/pricing/product-catalog-price.ts +6 -25
  231. package/src/pricing/product-price-rateconversion.ts +2 -2
  232. package/src/pricing/product-round.ts +3 -3
  233. package/src/pricing/product-swiss-tax.test.ts +6 -6
  234. package/src/pricing/product-swiss-tax.ts +2 -2
  235. package/src/warehousing/eth-minter.ts +2 -2
  236. package/src/worker/budgetsms.ts +268 -0
  237. package/src/worker/bulk-import.ts +1 -1
  238. package/src/worker/bulkgate.ts +138 -0
  239. package/src/worker/enrollment-order-generator.ts +3 -3
  240. package/src/worker/error-notifications.ts +4 -4
  241. package/src/worker/heartbeat.ts +4 -11
  242. package/src/worker/message.ts +1 -1
  243. package/src/worker/push-notification.ts +2 -2
  244. package/src/worker/twilio.ts +71 -0
  245. package/src/worker/update-coinbase-rates.ts +3 -6
  246. package/src/worker/update-ecb-rates.ts +3 -3
  247. package/lib/accounts/google-oauth.d.ts +0 -4
  248. package/lib/accounts/google-oauth.d.ts.map +0 -1
  249. package/lib/accounts/google-oauth.js +0 -145
  250. package/lib/accounts/google-oauth.js.map +0 -1
  251. package/lib/accounts/linkedin-oauth.d.ts +0 -4
  252. package/lib/accounts/linkedin-oauth.d.ts.map +0 -1
  253. package/lib/accounts/linkedin-oauth.js +0 -82
  254. package/lib/accounts/linkedin-oauth.js.map +0 -1
  255. package/lib/files/gridfs/gridfs-adapter.d.ts +0 -3
  256. package/lib/files/gridfs/gridfs-adapter.d.ts.map +0 -1
  257. package/lib/files/gridfs/gridfs-adapter.js +0 -97
  258. package/lib/files/gridfs/gridfs-adapter.js.map +0 -1
  259. package/lib/files/gridfs/gridfs-webhook.d.ts +0 -11
  260. package/lib/files/gridfs/gridfs-webhook.d.ts.map +0 -1
  261. package/lib/files/gridfs/gridfs-webhook.js +0 -84
  262. package/lib/files/gridfs/gridfs-webhook.js.map +0 -1
  263. package/lib/files/minio/minio-adapter.d.ts +0 -6
  264. package/lib/files/minio/minio-adapter.d.ts.map +0 -1
  265. package/lib/files/minio/minio-adapter.js +0 -181
  266. package/lib/files/minio/minio-adapter.js.map +0 -1
  267. package/lib/files/minio/minio-webhook.d.ts +0 -2
  268. package/lib/files/minio/minio-webhook.d.ts.map +0 -1
  269. package/lib/files/minio/minio-webhook.js +0 -33
  270. package/lib/files/minio/minio-webhook.js.map +0 -1
  271. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts +0 -9
  272. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts.map +0 -1
  273. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js +0 -17
  274. package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js.map +0 -1
  275. package/lib/payment/cryptopay/middleware.d.ts +0 -2
  276. package/lib/payment/cryptopay/middleware.d.ts.map +0 -1
  277. package/lib/payment/cryptopay/middleware.js +0 -75
  278. package/lib/payment/cryptopay/middleware.js.map +0 -1
  279. package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts +0 -25
  280. package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts.map +0 -1
  281. package/lib/payment/cryptopay/module/configureCryptopayModule.js +0 -75
  282. package/lib/payment/cryptopay/module/configureCryptopayModule.js.map +0 -1
  283. package/lib/payment/datatrans-v2/middleware.d.ts +0 -2
  284. package/lib/payment/datatrans-v2/middleware.d.ts.map +0 -1
  285. package/lib/payment/datatrans-v2/middleware.js +0 -68
  286. package/lib/payment/datatrans-v2/middleware.js.map +0 -1
  287. package/lib/payment/payrexx/middleware.d.ts +0 -2
  288. package/lib/payment/payrexx/middleware.d.ts.map +0 -1
  289. package/lib/payment/payrexx/middleware.js +0 -86
  290. package/lib/payment/payrexx/middleware.js.map +0 -1
  291. package/lib/payment/postfinance-checkout/middleware.d.ts +0 -2
  292. package/lib/payment/postfinance-checkout/middleware.d.ts.map +0 -1
  293. package/lib/payment/postfinance-checkout/middleware.js +0 -38
  294. package/lib/payment/postfinance-checkout/middleware.js.map +0 -1
  295. package/lib/payment/saferpay/middleware.d.ts +0 -2
  296. package/lib/payment/saferpay/middleware.d.ts.map +0 -1
  297. package/lib/payment/saferpay/middleware.js +0 -57
  298. package/lib/payment/saferpay/middleware.js.map +0 -1
  299. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts +0 -10
  300. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts.map +0 -1
  301. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js +0 -24
  302. package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js.map +0 -1
  303. package/lib/payment/stripe/middleware.d.ts +0 -6
  304. package/lib/payment/stripe/middleware.d.ts.map +0 -1
  305. package/lib/payment/stripe/middleware.js +0 -114
  306. package/lib/payment/stripe/middleware.js.map +0 -1
  307. package/lib/plugins-index.d.ts +0 -48
  308. package/lib/plugins-index.d.ts.map +0 -1
  309. package/lib/plugins-index.js +0 -107
  310. package/lib/plugins-index.js.map +0 -1
  311. package/lib/worker/BaseWorker.d.ts +0 -30
  312. package/lib/worker/BaseWorker.d.ts.map +0 -1
  313. package/lib/worker/BaseWorker.js +0 -79
  314. package/lib/worker/BaseWorker.js.map +0 -1
  315. package/lib/worker/EventListenerWorker.d.ts +0 -6
  316. package/lib/worker/EventListenerWorker.d.ts.map +0 -1
  317. package/lib/worker/EventListenerWorker.js +0 -46
  318. package/lib/worker/EventListenerWorker.js.map +0 -1
  319. package/lib/worker/FailedRescheduler.d.ts +0 -15
  320. package/lib/worker/FailedRescheduler.d.ts.map +0 -1
  321. package/lib/worker/FailedRescheduler.js +0 -45
  322. package/lib/worker/FailedRescheduler.js.map +0 -1
  323. package/lib/worker/IntervalWorker.d.ts +0 -10
  324. package/lib/worker/IntervalWorker.d.ts.map +0 -1
  325. package/lib/worker/IntervalWorker.js +0 -37
  326. package/lib/worker/IntervalWorker.js.map +0 -1
  327. package/src/worker/BaseWorker.ts +0 -116
  328. package/src/worker/EventListenerWorker.ts +0 -61
  329. package/src/worker/FailedRescheduler.ts +0 -80
  330. package/src/worker/IntervalWorker.ts +0 -54
  331. package/src/worker/sms.ts +0 -87
@@ -0,0 +1,48 @@
1
+ import { HDKey } from '@scure/bip32';
2
+ import { NETWORK, p2wpkh, TEST_NETWORK } from '@scure/btc-signer';
3
+
4
+ // const resolvePath = (prefix) => {
5
+ // if (prefix === 'x') return `m/44'/0'`;
6
+ // if (prefix === 'y') return `m/49'/0'`;
7
+ // if (prefix === 'z') return `m/84'/0'`;
8
+ // if (prefix === 't') return `m/44'/1'`;
9
+ // if (prefix === 'u') return `m/49'/1'`;
10
+ // if (prefix === 'v') return `m/84'/1'`;
11
+ // return `m`;
12
+ // };
13
+
14
+ const resolveNetwork = (prefix) => {
15
+ if (['x', 'y', 'z'].includes(prefix)) return NETWORK;
16
+ return TEST_NETWORK;
17
+ };
18
+
19
+ export default (xpub, index) => {
20
+ const prefix = xpub.slice(0, 1);
21
+ if (prefix !== 'z' && prefix !== 'v')
22
+ throw new Error('Cryptopay only supports native segwit (zpub/vpub) extended key format for BTC');
23
+
24
+ const hardenedMaster = HDKey.fromExtendedKey(
25
+ xpub,
26
+ prefix === 'z'
27
+ ? {
28
+ public: 0x04b24746, // zpub public
29
+ private: 0x04b2430c, // zpriv private
30
+ }
31
+ : {
32
+ public: 0x045f1cf6,
33
+ private: 0x045f18bc,
34
+ },
35
+ );
36
+ hardenedMaster.wipePrivateData(); // Neuter
37
+
38
+ const child = hardenedMaster.deriveChild(0).deriveChild(index);
39
+
40
+ // We don't need this AFAIK:
41
+ // const derivationPath = resolvePath(prefix);
42
+ // const child = hardenedMaster.derive(`${derivationPath}/0/${btcDerivationNumber}`);
43
+
44
+ const network = resolveNetwork(prefix);
45
+ const pubKey = p2wpkh(child.publicKey /* hex.decode( as string)*/, network);
46
+
47
+ return pubKey.address;
48
+ };
@@ -0,0 +1,22 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import deriveEthAddress from './derive-eth-address.js';
4
+
5
+ describe('ETH Address Derivation', () => {
6
+ it('returns a deterministic BIP44 child address', () => {
7
+ assert.equal(
8
+ deriveEthAddress(
9
+ 'xpub6DTksA6DsGUgbEp1U29v3qGTt5P99iKThaqGEzerTfD73ZAg1F8j15TxWTPEjjA1uw1Zmwwc5dgVCXwTL2ZNhvdoLWNdqVuL1MDJMsQCLLs',
10
+ 1,
11
+ ),
12
+ '0x11CF7d607A1Dc45a002592891fF25DAAE6eC7dE9',
13
+ );
14
+ assert.equal(
15
+ deriveEthAddress(
16
+ 'xpub6DTksA6DsGUgbEp1U29v3qGTt5P99iKThaqGEzerTfD73ZAg1F8j15TxWTPEjjA1uw1Zmwwc5dgVCXwTL2ZNhvdoLWNdqVuL1MDJMsQCLLs',
17
+ 2,
18
+ ),
19
+ '0x61663D505e3aB5b61a5344eA2c64b644c08013ea',
20
+ );
21
+ });
22
+ });
@@ -0,0 +1,38 @@
1
+ import { HDKey } from '@scure/bip32';
2
+ import { keccak_256 } from '@noble/hashes/sha3';
3
+ import { secp256k1 } from '@noble/curves/secp256k1';
4
+
5
+ function getChecksumAddress(address) {
6
+ const chars = address.split('');
7
+ const expanded = new Uint8Array(40);
8
+ for (let i = 0; i < 40; i++) {
9
+ expanded[i] = chars[i].charCodeAt(0);
10
+ }
11
+ const hashed = keccak_256(expanded);
12
+
13
+ for (let i = 0; i < 40; i += 2) {
14
+ if (hashed[i >> 1] >> 4 >= 8) {
15
+ chars[i] = chars[i].toUpperCase();
16
+ }
17
+ if ((hashed[i >> 1] & 0x0f) >= 8) {
18
+ chars[i + 1] = chars[i + 1].toUpperCase();
19
+ }
20
+ }
21
+
22
+ return '0x' + chars.join('');
23
+ }
24
+
25
+ export default (xpub, index) => {
26
+ const hardenedMaster = HDKey.fromExtendedKey(xpub);
27
+ hardenedMaster.wipePrivateData(); // Neuter
28
+
29
+ const child = hardenedMaster.deriveChild(0).deriveChild(index);
30
+
31
+ // ETH Address (secp256k1 + keccak_256 + checksum)
32
+ const childSigningKey = secp256k1.ProjectivePoint.fromHex(child.publicKey).toRawBytes(false);
33
+ const address = Buffer.from(keccak_256(childSigningKey.slice(1)))
34
+ .toString('hex')
35
+ .substring(24);
36
+
37
+ return getChecksumAddress(address);
38
+ };
@@ -0,0 +1,103 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { Context } from '@unchainedshop/api';
3
+ import { OrderStatus } from '@unchainedshop/core-orders';
4
+ import { CryptopayModule } from './module.js';
5
+ import { ProductPriceRate } from '@unchainedshop/core-products';
6
+
7
+ const { CRYPTOPAY_SECRET, CRYPTOPAY_MAX_RATE_AGE = '360' } = process.env;
8
+
9
+ const logger = createLogger('unchained:core-payment:cryptopay:handler');
10
+
11
+ export default async function handleWebhook(
12
+ {
13
+ secret,
14
+ wallet,
15
+ price,
16
+ ping,
17
+ }: {
18
+ secret: string;
19
+ wallet?: {
20
+ address: string;
21
+ blockHeight: number;
22
+ amount: string;
23
+ contract?: string;
24
+ decimals?: number;
25
+ currencyCode: string;
26
+ };
27
+ price?: {
28
+ baseCurrency: string;
29
+ token: string;
30
+ rate: number;
31
+ timestamp: string; // ISO date string
32
+ };
33
+ ping?: {
34
+ blockHeight: number;
35
+ currencyCode: string;
36
+ };
37
+ },
38
+ context: Context & {
39
+ modules: CryptopayModule;
40
+ },
41
+ ) {
42
+ const { modules, services } = context;
43
+
44
+ if (secret !== CRYPTOPAY_SECRET) {
45
+ logger.warn(`webhook called with invalid secret`);
46
+ throw new Error('Secret invalid');
47
+ }
48
+
49
+ if (wallet) {
50
+ const { address, blockHeight, amount, contract, decimals, currencyCode } = wallet;
51
+ logger.debug('webhook received wallet data', wallet);
52
+ const { orderPaymentId } = await modules.cryptopay.updateWalletAddress({
53
+ address,
54
+ blockHeight,
55
+ amount,
56
+ contract,
57
+ decimals,
58
+ currencyCode,
59
+ });
60
+
61
+ const orderPayment =
62
+ orderPaymentId &&
63
+ (await modules.orders.payments.findOrderPayment({
64
+ orderPaymentId,
65
+ }));
66
+
67
+ if (orderPayment) {
68
+ // Try to process order to next status
69
+ // TODO: Not sure if it's correct to use processOrder here if status is PENDING!
70
+ const order = await modules.orders.findOrder({ orderId: orderPayment.orderId });
71
+ if (order.status === null) {
72
+ await services.orders.checkoutOrder(order._id, {});
73
+ } else if (order.status === OrderStatus.PENDING) {
74
+ await services.orders.processOrder(order, {});
75
+ } else {
76
+ throw new Error('Already processed');
77
+ }
78
+ }
79
+ }
80
+
81
+ if (price) {
82
+ logger.debug('webhook received price data', price);
83
+ const { baseCurrency, token, rate, timestamp } = price;
84
+
85
+ const timestampDate = new Date(timestamp);
86
+ const expiresAt = new Date(new Date().getTime() + parseInt(CRYPTOPAY_MAX_RATE_AGE, 10) * 1000);
87
+
88
+ const rateData: ProductPriceRate = {
89
+ baseCurrency,
90
+ quoteCurrency: token,
91
+ rate,
92
+ expiresAt,
93
+ timestamp: timestampDate,
94
+ };
95
+ await modules.products.prices.rates.updateRates([rateData]);
96
+ }
97
+
98
+ if (ping) {
99
+ logger.debug('webhook received ping data', ping);
100
+ const { blockHeight, currencyCode } = ping;
101
+ await modules.cryptopay.updateMostRecentBlock(currencyCode, blockHeight);
102
+ }
103
+ }
@@ -1,83 +1,17 @@
1
1
  import { createLogger } from '@unchainedshop/logger';
2
- import { Context } from '@unchainedshop/api';
3
- import { OrderStatus } from '@unchainedshop/core-orders';
4
- import { CryptopayModule } from './module.js';
5
- import { ProductPriceRate } from '@unchainedshop/core-products';
2
+ import handleWebhook from './handle-webhook.js';
6
3
 
7
- const { CRYPTOPAY_SECRET, CRYPTOPAY_MAX_RATE_AGE = '360' } = process.env;
8
-
9
- const logger = createLogger('unchained:core-payment:cryptopay');
4
+ const logger = createLogger('unchained:core-payment:cryptopay:handler');
10
5
 
11
6
  const cryptopayHandler = async (req, res) => {
12
- const resolvedContext = req.unchainedContext as Context & {
13
- modules: CryptopayModule;
14
- };
15
- const { modules, services } = resolvedContext;
16
-
17
7
  if (req.method === 'POST') {
18
8
  try {
19
- const { secret, price, wallet, ping } = req.body;
20
- if (secret !== CRYPTOPAY_SECRET) {
21
- logger.warn(`Cryptopay Plugin: Invalid Cryptopay Secret provided`);
22
- throw new Error('Secret invalid');
23
- }
24
-
25
- if (wallet) {
26
- const { address, blockHeight, amount, contract, decimals, currency } = wallet;
27
- const { orderPaymentId } = await modules.cryptopay.updateWalletAddress({
28
- addressId: address,
29
- blockHeight,
30
- amount,
31
- contract,
32
- decimals,
33
- currency,
34
- });
35
- const orderPayment =
36
- orderPaymentId &&
37
- (await modules.orders.payments.findOrderPayment({
38
- orderPaymentId,
39
- }));
40
-
41
- if (orderPayment) {
42
- // Try to process order to next status
43
- // TODO: Not sure if it's correct to use processOrder here if status is PENDING!
44
- const order = await modules.orders.findOrder({ orderId: orderPayment.orderId });
45
- if (order.status === null) {
46
- await services.orders.checkoutOrder(order._id, {});
47
- } else if (order.status === OrderStatus.PENDING) {
48
- await services.orders.processOrder(order, {});
49
- } else {
50
- throw new Error('Already processed');
51
- }
52
- }
53
- }
54
-
55
- if (price) {
56
- const { baseCurrency, token, rate, timestamp } = price;
57
-
58
- const timestampDate = new Date(timestamp);
59
- const expiresAt = new Date(new Date().getTime() + parseInt(CRYPTOPAY_MAX_RATE_AGE, 10) * 1000);
60
-
61
- const rateData: ProductPriceRate = {
62
- baseCurrency,
63
- quoteCurrency: token,
64
- rate,
65
- expiresAt,
66
- timestamp: timestampDate,
67
- };
68
- logger.info(`update rate ${JSON.stringify(price)}, ${JSON.stringify(rateData)}`);
69
- await resolvedContext.modules.products.prices.rates.updateRates([rateData]);
70
- }
71
-
72
- if (ping) {
73
- const { blockHeight, currency } = ping;
74
- await modules.cryptopay.updateMostRecentBlock(currency, blockHeight);
75
- }
76
-
9
+ await handleWebhook(req.body, req.unchainedContext);
77
10
  res.writeHead(200);
78
11
  res.end(JSON.stringify({ success: true }));
79
12
  return;
80
13
  } catch (e) {
14
+ logger.error(e);
81
15
  res.writeHead(500);
82
16
  res.end(JSON.stringify({ success: false, error: e.message }));
83
17
  return;
@@ -1,86 +1,21 @@
1
- import { FastifyRequest, RouteHandlerMethod } from 'fastify';
2
1
  import { createLogger } from '@unchainedshop/logger';
3
- import { Context } from '@unchainedshop/api';
4
- import { OrderStatus } from '@unchainedshop/core-orders';
5
- import { CryptopayModule } from './module.js';
6
- import { ProductPriceRate } from '@unchainedshop/core-products';
7
-
8
- const { CRYPTOPAY_SECRET, CRYPTOPAY_MAX_RATE_AGE = '360' } = process.env;
2
+ import handleWebhook from './handle-webhook.js';
3
+ import { FastifyRequest, RouteHandlerMethod } from 'fastify';
9
4
 
10
- const logger = createLogger('unchained:core-payment:cryptopay');
5
+ const logger = createLogger('unchained:core-payment:cryptopay:handler');
11
6
 
12
7
  const cryptopayHandler: RouteHandlerMethod = async (
13
8
  req: FastifyRequest & {
14
- unchainedContext: Context & {
15
- modules: CryptopayModule;
16
- };
9
+ unchainedContext: any;
17
10
  },
18
11
  reply,
19
12
  ) => {
20
- const { modules, services } = req.unchainedContext;
21
-
22
13
  try {
23
- const { secret, price, wallet, ping } = req.body as Record<string, any>;
24
- if (secret !== CRYPTOPAY_SECRET) {
25
- logger.warn(`Cryptopay Plugin: Invalid Cryptopay Secret provided`);
26
- throw new Error('Secret invalid');
27
- }
28
-
29
- if (wallet) {
30
- const { address, blockHeight, amount, contract, decimals, currency } = wallet;
31
- const { orderPaymentId } = await modules.cryptopay.updateWalletAddress({
32
- addressId: address,
33
- blockHeight,
34
- amount,
35
- contract,
36
- decimals,
37
- currency,
38
- });
39
- const orderPayment =
40
- orderPaymentId &&
41
- (await modules.orders.payments.findOrderPayment({
42
- orderPaymentId,
43
- }));
44
-
45
- if (orderPayment) {
46
- // Try to process order to next status
47
- // TODO: Not sure if it's correct to use processOrder here if status is PENDING!
48
- const order = await modules.orders.findOrder({ orderId: orderPayment.orderId });
49
- if (order.status === null) {
50
- await services.orders.checkoutOrder(order._id, {});
51
- } else if (order.status === OrderStatus.PENDING) {
52
- await services.orders.processOrder(order, {});
53
- } else {
54
- throw new Error('Already processed');
55
- }
56
- }
57
- }
58
-
59
- if (price) {
60
- const { baseCurrency, token, rate, timestamp } = price;
61
-
62
- const timestampDate = new Date(timestamp);
63
- const expiresAt = new Date(new Date().getTime() + parseInt(CRYPTOPAY_MAX_RATE_AGE, 10) * 1000);
64
-
65
- const rateData: ProductPriceRate = {
66
- baseCurrency,
67
- quoteCurrency: token,
68
- rate,
69
- expiresAt,
70
- timestamp: timestampDate,
71
- };
72
- logger.info(`update rate ${JSON.stringify(price)}, ${JSON.stringify(rateData)}`);
73
- await modules.products.prices.rates.updateRates([rateData]);
74
- }
75
-
76
- if (ping) {
77
- const { blockHeight, currency } = ping;
78
- await modules.cryptopay.updateMostRecentBlock(currency, blockHeight);
79
- }
80
-
14
+ await handleWebhook(req.body as any, req.unchainedContext);
81
15
  reply.status(200);
82
16
  return reply.send({ success: true });
83
17
  } catch (e) {
18
+ logger.error(e);
84
19
  reply.status(500);
85
20
  return reply.send({ success: false, error: e.message });
86
21
  }
@@ -4,14 +4,15 @@ import { CryptopayTransaction, CryptopayTransactionsCollection } from './db/Cryp
4
4
  const configureCryptopayModule = ({ db }) => {
5
5
  const CryptoTransactions = CryptopayTransactionsCollection(db);
6
6
 
7
- const getWalletAddress = async (addressId: string): Promise<CryptopayTransaction> => {
8
- return CryptoTransactions.findOne({ _id: addressId.toLowerCase() });
7
+ const getWalletAddress = async (address: string, contract?: string): Promise<CryptopayTransaction> => {
8
+ const addressId = [address, contract].filter(Boolean).join(':');
9
+ return CryptoTransactions.findOne({ _id: addressId });
9
10
  };
10
11
 
11
- const updateMostRecentBlock = async (currency: string, blockHeight: number): Promise<void> => {
12
+ const updateMostRecentBlock = async (currencyCode: string, blockHeight: number): Promise<void> => {
12
13
  await CryptoTransactions.updateMany(
13
14
  {
14
- currency,
15
+ currencyCode,
15
16
  },
16
17
  {
17
18
  $set: {
@@ -22,26 +23,26 @@ const configureCryptopayModule = ({ db }) => {
22
23
  };
23
24
 
24
25
  const mapOrderPaymentToWalletAddress = async ({
25
- addressId,
26
+ address,
26
27
  contract,
27
- currency,
28
+ currencyCode,
28
29
  orderPaymentId,
29
30
  }: {
30
- addressId: string;
31
- contract: string;
32
- currency: string;
31
+ address: string;
32
+ contract?: string;
33
+ currencyCode: string;
33
34
  orderPaymentId: string;
34
35
  }): Promise<CryptopayTransaction> => {
35
- await CryptoTransactions.updateOne(
36
+ const addressId = [address, contract].filter(Boolean).join(':');
37
+
38
+ return CryptoTransactions.findOneAndUpdate(
36
39
  {
37
- _id: addressId.toLowerCase(),
40
+ _id: addressId,
38
41
  },
39
42
  {
40
43
  $setOnInsert: {
41
- _id: addressId.toLowerCase(),
42
- contract,
43
- currency,
44
- decimals: null,
44
+ _id: addressId,
45
+ currencyCode,
45
46
  mostRecentBlockHeight: 0,
46
47
  blockHeight: 0,
47
48
  amount: mongodb.Decimal128.fromString('0'),
@@ -52,62 +53,65 @@ const configureCryptopayModule = ({ db }) => {
52
53
  updated: new Date(),
53
54
  },
54
55
  },
55
- { upsert: true },
56
+ { upsert: true, returnDocument: 'after' },
56
57
  );
57
-
58
- return CryptoTransactions.findOne({ _id: addressId.toLowerCase() });
59
58
  };
60
59
 
61
- const getNextDerivationNumber = async (currency: string): Promise<number> => {
62
- return (await CryptoTransactions.countDocuments({ currency })) + 1;
60
+ const getNextDerivationNumber = async (currencyCode: string): Promise<number> => {
61
+ return (await CryptoTransactions.countDocuments({ currencyCode })) + 1;
63
62
  };
64
63
 
65
64
  const getWalletAddressesByOrderPaymentId = async (
66
65
  orderPaymentId: string,
67
66
  ): Promise<CryptopayTransaction[]> => {
68
- return CryptoTransactions.find({
69
- orderPaymentId,
70
- }).toArray();
67
+ return CryptoTransactions.find(
68
+ {
69
+ orderPaymentId,
70
+ },
71
+ {
72
+ sort: {
73
+ created: 1, // Sort by creation date, most recent first
74
+ },
75
+ },
76
+ ).toArray();
71
77
  };
72
78
 
73
79
  const updateWalletAddress = async ({
74
- addressId,
80
+ address,
75
81
  blockHeight,
76
82
  amount,
77
83
  contract,
78
- currency,
84
+ currencyCode,
79
85
  decimals,
80
86
  }: {
81
- addressId: string;
87
+ address: string;
82
88
  blockHeight: number;
83
- amount: string;
84
- contract: string;
85
- currency: string;
89
+ amount: string | number;
90
+ contract?: string;
91
+ currencyCode: string;
86
92
  decimals: number;
87
93
  }): Promise<CryptopayTransaction> => {
88
- await CryptoTransactions.updateOne(
94
+ const addressId = [address, contract].filter(Boolean).join(':');
95
+ return CryptoTransactions.findOneAndUpdate(
89
96
  {
90
- _id: addressId.toLowerCase(),
97
+ _id: addressId,
91
98
  },
92
99
  {
93
100
  $setOnInsert: {
94
- _id: addressId.toLowerCase(),
95
- currency,
96
- contract,
101
+ _id: addressId,
97
102
  created: new Date(),
98
103
  },
99
104
  $set: {
105
+ currencyCode,
100
106
  decimals,
101
107
  blockHeight,
102
108
  mostRecentBlockHeight: blockHeight,
103
- amount: mongodb.Decimal128.fromString(amount),
109
+ amount: mongodb.Decimal128.fromString(typeof amount === 'number' ? `${amount}` : amount),
104
110
  updated: new Date(),
105
111
  },
106
112
  },
107
- { upsert: true },
113
+ { upsert: true, returnDocument: 'after' },
108
114
  );
109
-
110
- return CryptoTransactions.findOne({ _id: addressId.toLowerCase() });
111
115
  };
112
116
 
113
117
  return {
@@ -126,6 +130,6 @@ export default {
126
130
  },
127
131
  };
128
132
 
129
- export type CryptopayModule = {
133
+ export interface CryptopayModule {
130
134
  cryptopay: ReturnType<typeof configureCryptopayModule>;
131
- };
135
+ }