trustbase-seller-backend 0.1.5

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 (1195) hide show
  1. package/.agents/skills/wechatpay-payment-integration/SKILL.md +165 -0
  2. package/.agents/skills/wechatpay-payment-integration/references/APIv3/346/216/245/345/217/243/345/212/250/346/200/201/346/216/222/351/232/234.md +234 -0
  3. package/.agents/skills/wechatpay-payment-integration/references/wechatpay-dev-cli/344/275/277/347/224/250/350/257/264/346/230/216.md +74 -0
  4. package/.agents/skills/wechatpay-payment-integration/references//345/237/272/347/241/200/346/246/202/345/277/265/345/217/212/344/270/232/345/212/241/344/273/213/347/273/215.md +109 -0
  5. package/.agents/skills/wechatpay-payment-integration/references//345/246/202/344/275/225/347/220/206/350/247/243/347/224/250/346/210/267/351/227/256/351/242/230.md +55 -0
  6. package/.agents/skills/wechatpay-payment-integration/references//346/216/245/345/205/245/350/264/250/351/207/217/346/243/200/346/237/245/346/270/205/345/215/225.md +70 -0
  7. package/.agents/skills/wechatpay-payment-integration/references//346/226/207/346/241/243/346/243/200/347/264/242/344/270/216/351/227/256/347/255/224.md +99 -0
  8. package/.agents/skills/wechatpay-payment-integration/scripts/bash/extract_and_sign.sh +231 -0
  9. package/.agents/skills/wechatpay-payment-integration/scripts/powershell/extract_and_sign.ps1 +199 -0
  10. package/.agents/skills/wechatpay-payment-integration/scripts/wechatpay-resource-sync.py +646 -0
  11. package/.env.example +70 -0
  12. package/MERCHANT-EDITION.md +56 -0
  13. package/README.md +99 -0
  14. package/api/__tests__/test-utils.d.ts +33 -0
  15. package/api/__tests__/test-utils.d.ts.map +1 -0
  16. package/api/__tests__/test-utils.js +90 -0
  17. package/api/__tests__/test-utils.js.map +1 -0
  18. package/api/db/case-library-types.d.ts +47 -0
  19. package/api/db/case-library-types.d.ts.map +1 -0
  20. package/api/db/case-library-types.js +105 -0
  21. package/api/db/case-library-types.js.map +1 -0
  22. package/api/db/case-library.db.d.ts +5 -0
  23. package/api/db/case-library.db.d.ts.map +1 -0
  24. package/api/db/case-library.db.js +127 -0
  25. package/api/db/case-library.db.js.map +1 -0
  26. package/api/email.d.ts +56 -0
  27. package/api/email.d.ts.map +1 -0
  28. package/api/email.js +307 -0
  29. package/api/email.js.map +1 -0
  30. package/api/index.d.ts +22 -0
  31. package/api/index.d.ts.map +1 -0
  32. package/api/index.js +41 -0
  33. package/api/index.js.map +1 -0
  34. package/api/integration-helpers.d.ts +153 -0
  35. package/api/integration-helpers.d.ts.map +1 -0
  36. package/api/integration-helpers.js +361 -0
  37. package/api/integration-helpers.js.map +1 -0
  38. package/api/lib/case-summary.d.ts +10 -0
  39. package/api/lib/case-summary.d.ts.map +1 -0
  40. package/api/lib/case-summary.js +30 -0
  41. package/api/lib/case-summary.js.map +1 -0
  42. package/api/middleware/p2p-auth.d.ts +140 -0
  43. package/api/middleware/p2p-auth.d.ts.map +1 -0
  44. package/api/middleware/p2p-auth.js +510 -0
  45. package/api/middleware/p2p-auth.js.map +1 -0
  46. package/api/middleware/tool-policy.d.ts +47 -0
  47. package/api/middleware/tool-policy.d.ts.map +1 -0
  48. package/api/middleware/tool-policy.js +156 -0
  49. package/api/middleware/tool-policy.js.map +1 -0
  50. package/api/oauth-adapters.d.ts +192 -0
  51. package/api/oauth-adapters.d.ts.map +1 -0
  52. package/api/oauth-adapters.js +456 -0
  53. package/api/oauth-adapters.js.map +1 -0
  54. package/api/oauth-bridge.d.ts +56 -0
  55. package/api/oauth-bridge.d.ts.map +1 -0
  56. package/api/oauth-bridge.js +624 -0
  57. package/api/oauth-bridge.js.map +1 -0
  58. package/api/oauth-router.d.ts +36 -0
  59. package/api/oauth-router.d.ts.map +1 -0
  60. package/api/oauth-router.js +54 -0
  61. package/api/oauth-router.js.map +1 -0
  62. package/api/p2p-mcp.d.ts +69 -0
  63. package/api/p2p-mcp.d.ts.map +1 -0
  64. package/api/p2p-mcp.js +286 -0
  65. package/api/p2p-mcp.js.map +1 -0
  66. package/api/payment-store.d.ts +56 -0
  67. package/api/payment-store.d.ts.map +1 -0
  68. package/api/payment-store.js +163 -0
  69. package/api/payment-store.js.map +1 -0
  70. package/api/payment.d.ts +14 -0
  71. package/api/payment.d.ts.map +1 -0
  72. package/api/payment.js +216 -0
  73. package/api/payment.js.map +1 -0
  74. package/api/pwa-stats.d.ts +67 -0
  75. package/api/pwa-stats.d.ts.map +1 -0
  76. package/api/pwa-stats.js +269 -0
  77. package/api/pwa-stats.js.map +1 -0
  78. package/api/riskcontrol-adapters.d.ts +114 -0
  79. package/api/riskcontrol-adapters.d.ts.map +1 -0
  80. package/api/riskcontrol-adapters.js +210 -0
  81. package/api/riskcontrol-adapters.js.map +1 -0
  82. package/api/riskcontrol-event-whitelist.d.ts +81 -0
  83. package/api/riskcontrol-event-whitelist.d.ts.map +1 -0
  84. package/api/riskcontrol-event-whitelist.js +181 -0
  85. package/api/riskcontrol-event-whitelist.js.map +1 -0
  86. package/api/riskcontrol-rules.d.ts +105 -0
  87. package/api/riskcontrol-rules.d.ts.map +1 -0
  88. package/api/riskcontrol-rules.js +399 -0
  89. package/api/riskcontrol-rules.js.map +1 -0
  90. package/api/riskcontrol-scoring.d.ts +72 -0
  91. package/api/riskcontrol-scoring.d.ts.map +1 -0
  92. package/api/riskcontrol-scoring.js +335 -0
  93. package/api/riskcontrol-scoring.js.map +1 -0
  94. package/api/riskcontrol-service.d.ts +60 -0
  95. package/api/riskcontrol-service.d.ts.map +1 -0
  96. package/api/riskcontrol-service.js +206 -0
  97. package/api/riskcontrol-service.js.map +1 -0
  98. package/api/riskcontrol-stream.d.ts +112 -0
  99. package/api/riskcontrol-stream.d.ts.map +1 -0
  100. package/api/riskcontrol-stream.js +230 -0
  101. package/api/riskcontrol-stream.js.map +1 -0
  102. package/api/riskcontrol-v5-e2e-test.d.ts +15 -0
  103. package/api/riskcontrol-v5-e2e-test.d.ts.map +1 -0
  104. package/api/riskcontrol-v5-e2e-test.js +204 -0
  105. package/api/riskcontrol-v5-e2e-test.js.map +1 -0
  106. package/api/riskcontrol-v5-router.d.ts +48 -0
  107. package/api/riskcontrol-v5-router.d.ts.map +1 -0
  108. package/api/riskcontrol-v5-router.js +226 -0
  109. package/api/riskcontrol-v5-router.js.map +1 -0
  110. package/api/riskcontrol-webhook.d.ts +88 -0
  111. package/api/riskcontrol-webhook.d.ts.map +1 -0
  112. package/api/riskcontrol-webhook.js +326 -0
  113. package/api/riskcontrol-webhook.js.map +1 -0
  114. package/api/routes/case-library.d.ts +4 -0
  115. package/api/routes/case-library.d.ts.map +1 -0
  116. package/api/routes/case-library.js +91 -0
  117. package/api/routes/case-library.js.map +1 -0
  118. package/api/seller-earnings.d.ts +23 -0
  119. package/api/seller-earnings.d.ts.map +1 -0
  120. package/api/seller-earnings.js +258 -0
  121. package/api/seller-earnings.js.map +1 -0
  122. package/api/seller-orders.d.ts +25 -0
  123. package/api/seller-orders.d.ts.map +1 -0
  124. package/api/seller-orders.js +398 -0
  125. package/api/seller-orders.js.map +1 -0
  126. package/api/seller-products-chain.d.ts +31 -0
  127. package/api/seller-products-chain.d.ts.map +1 -0
  128. package/api/seller-products-chain.js +308 -0
  129. package/api/seller-products-chain.js.map +1 -0
  130. package/api/seller-products.d.ts +30 -0
  131. package/api/seller-products.d.ts.map +1 -0
  132. package/api/seller-products.js +453 -0
  133. package/api/seller-products.js.map +1 -0
  134. package/api/seller-reputation.d.ts +21 -0
  135. package/api/seller-reputation.d.ts.map +1 -0
  136. package/api/seller-reputation.js +204 -0
  137. package/api/seller-reputation.js.map +1 -0
  138. package/api/seller-router.d.ts +33 -0
  139. package/api/seller-router.d.ts.map +1 -0
  140. package/api/seller-router.js +53 -0
  141. package/api/seller-router.js.map +1 -0
  142. package/api/seller-settings.d.ts +23 -0
  143. package/api/seller-settings.d.ts.map +1 -0
  144. package/api/seller-settings.js +279 -0
  145. package/api/seller-settings.js.map +1 -0
  146. package/api/shipping-store.d.ts +44 -0
  147. package/api/shipping-store.d.ts.map +1 -0
  148. package/api/shipping-store.js +154 -0
  149. package/api/shipping-store.js.map +1 -0
  150. package/api/shipping.d.ts +16 -0
  151. package/api/shipping.d.ts.map +1 -0
  152. package/api/shipping.js +239 -0
  153. package/api/shipping.js.map +1 -0
  154. package/api/social-endpoint-verify.d.ts +8 -0
  155. package/api/social-endpoint-verify.d.ts.map +1 -0
  156. package/api/social-endpoint-verify.js +152 -0
  157. package/api/social-endpoint-verify.js.map +1 -0
  158. package/api/social-posts.d.ts +65 -0
  159. package/api/social-posts.d.ts.map +1 -0
  160. package/api/social-posts.js +534 -0
  161. package/api/social-posts.js.map +1 -0
  162. package/api/social-router.d.ts +36 -0
  163. package/api/social-router.d.ts.map +1 -0
  164. package/api/social-router.js +56 -0
  165. package/api/social-router.js.map +1 -0
  166. package/api/social-shares.d.ts +40 -0
  167. package/api/social-shares.d.ts.map +1 -0
  168. package/api/social-shares.js +379 -0
  169. package/api/social-shares.js.map +1 -0
  170. package/api/social-whitelist.d.ts +41 -0
  171. package/api/social-whitelist.d.ts.map +1 -0
  172. package/api/social-whitelist.js +261 -0
  173. package/api/social-whitelist.js.map +1 -0
  174. package/api/storefront-orders.d.ts +23 -0
  175. package/api/storefront-orders.d.ts.map +1 -0
  176. package/api/storefront-orders.js +349 -0
  177. package/api/storefront-orders.js.map +1 -0
  178. package/api/storefront-products.d.ts +21 -0
  179. package/api/storefront-products.d.ts.map +1 -0
  180. package/api/storefront-products.js +181 -0
  181. package/api/storefront-products.js.map +1 -0
  182. package/api/storefront-router.d.ts +33 -0
  183. package/api/storefront-router.d.ts.map +1 -0
  184. package/api/storefront-router.js +47 -0
  185. package/api/storefront-router.js.map +1 -0
  186. package/api/storefront-user.d.ts +23 -0
  187. package/api/storefront-user.d.ts.map +1 -0
  188. package/api/storefront-user.js +336 -0
  189. package/api/storefront-user.js.map +1 -0
  190. package/api/test-db-helper.d.ts +29 -0
  191. package/api/test-db-helper.d.ts.map +1 -0
  192. package/api/test-db-helper.js +107 -0
  193. package/api/test-db-helper.js.map +1 -0
  194. package/api/traffic.d.ts +22 -0
  195. package/api/traffic.d.ts.map +1 -0
  196. package/api/traffic.js +112 -0
  197. package/api/traffic.js.map +1 -0
  198. package/api/wc-credentials.d.ts +34 -0
  199. package/api/wc-credentials.d.ts.map +1 -0
  200. package/api/wc-credentials.js +296 -0
  201. package/api/wc-credentials.js.map +1 -0
  202. package/api/wc-tracker-receiver.d.ts +47 -0
  203. package/api/wc-tracker-receiver.d.ts.map +1 -0
  204. package/api/wc-tracker-receiver.js +264 -0
  205. package/api/wc-tracker-receiver.js.map +1 -0
  206. package/api/wc-v3.d.ts +40 -0
  207. package/api/wc-v3.d.ts.map +1 -0
  208. package/api/wc-v3.js +694 -0
  209. package/api/wc-v3.js.map +1 -0
  210. package/bin/tb-doctor.js +32 -0
  211. package/bin/tb-seller-backend.js +42 -0
  212. package/check.d.ts +2 -0
  213. package/check.d.ts.map +1 -0
  214. package/check.js +19 -0
  215. package/check.js.map +1 -0
  216. package/config/export-import.d.ts +108 -0
  217. package/config/export-import.d.ts.map +1 -0
  218. package/config/export-import.js +234 -0
  219. package/config/export-import.js.map +1 -0
  220. package/config/manager.d.ts +73 -0
  221. package/config/manager.d.ts.map +1 -0
  222. package/config/manager.js +246 -0
  223. package/config/manager.js.map +1 -0
  224. package/config/profile.d.ts +42 -0
  225. package/config/profile.d.ts.map +1 -0
  226. package/config/profile.js +111 -0
  227. package/config/profile.js.map +1 -0
  228. package/core/address.js +23 -0
  229. package/core/advanced-performance.d.ts +149 -0
  230. package/core/advanced-performance.d.ts.map +1 -0
  231. package/core/advanced-performance.js +374 -0
  232. package/core/advanced-performance.js.map +1 -0
  233. package/core/alerting.d.ts +91 -0
  234. package/core/alerting.d.ts.map +1 -0
  235. package/core/alerting.js +379 -0
  236. package/core/alerting.js.map +1 -0
  237. package/core/app-store.d.ts +77 -0
  238. package/core/app-store.d.ts.map +1 -0
  239. package/core/app-store.js +207 -0
  240. package/core/app-store.js.map +1 -0
  241. package/core/boot-env.js +39 -0
  242. package/core/business-scope-schema.d.ts +60 -0
  243. package/core/business-scope-schema.d.ts.map +1 -0
  244. package/core/business-scope-schema.js +165 -0
  245. package/core/business-scope-schema.js.map +1 -0
  246. package/core/cache.d.ts +53 -0
  247. package/core/cache.d.ts.map +1 -0
  248. package/core/cache.js +130 -0
  249. package/core/cache.js.map +1 -0
  250. package/core/chain-listener.d.ts +47 -0
  251. package/core/chain-listener.d.ts.map +1 -0
  252. package/core/chain-listener.js +254 -0
  253. package/core/chain-listener.js.map +1 -0
  254. package/core/chain-reject.js +107 -0
  255. package/core/chain-signer.js +258 -0
  256. package/core/cleanup.d.ts +42 -0
  257. package/core/cleanup.d.ts.map +1 -0
  258. package/core/cleanup.js +144 -0
  259. package/core/cleanup.js.map +1 -0
  260. package/core/cluster.d.ts +78 -0
  261. package/core/cluster.d.ts.map +1 -0
  262. package/core/cluster.js +215 -0
  263. package/core/cluster.js.map +1 -0
  264. package/core/community-review.d.ts +82 -0
  265. package/core/community-review.d.ts.map +1 -0
  266. package/core/community-review.js +201 -0
  267. package/core/community-review.js.map +1 -0
  268. package/core/connection-pool.d.ts +72 -0
  269. package/core/connection-pool.d.ts.map +1 -0
  270. package/core/connection-pool.js +173 -0
  271. package/core/connection-pool.js.map +1 -0
  272. package/core/consistency.d.ts +130 -0
  273. package/core/consistency.d.ts.map +1 -0
  274. package/core/consistency.js +340 -0
  275. package/core/consistency.js.map +1 -0
  276. package/core/content-ai.d.ts +303 -0
  277. package/core/content-ai.d.ts.map +1 -0
  278. package/core/content-ai.js +344 -0
  279. package/core/content-ai.js.map +1 -0
  280. package/core/content-backfill.d.ts +55 -0
  281. package/core/content-backfill.d.ts.map +1 -0
  282. package/core/content-backfill.js +174 -0
  283. package/core/content-backfill.js.map +1 -0
  284. package/core/conversion-rate-sync.d.ts +97 -0
  285. package/core/conversion-rate-sync.d.ts.map +1 -0
  286. package/core/conversion-rate-sync.js +195 -0
  287. package/core/conversion-rate-sync.js.map +1 -0
  288. package/core/coverage-backup.d.ts +87 -0
  289. package/core/coverage-backup.d.ts.map +1 -0
  290. package/core/coverage-backup.js +265 -0
  291. package/core/coverage-backup.js.map +1 -0
  292. package/core/db-installer.d.ts +108 -0
  293. package/core/db-installer.d.ts.map +1 -0
  294. package/core/db-installer.js +414 -0
  295. package/core/db-installer.js.map +1 -0
  296. package/core/device-analyzer.d.ts +96 -0
  297. package/core/device-analyzer.d.ts.map +1 -0
  298. package/core/device-analyzer.js +235 -0
  299. package/core/device-analyzer.js.map +1 -0
  300. package/core/discovery.d.ts +165 -0
  301. package/core/discovery.d.ts.map +1 -0
  302. package/core/discovery.js +363 -0
  303. package/core/discovery.js.map +1 -0
  304. package/core/distributed.d.ts +172 -0
  305. package/core/distributed.d.ts.map +1 -0
  306. package/core/distributed.js +422 -0
  307. package/core/distributed.js.map +1 -0
  308. package/core/doctor.js +249 -0
  309. package/core/enforcement.d.ts +57 -0
  310. package/core/enforcement.d.ts.map +1 -0
  311. package/core/enforcement.js +115 -0
  312. package/core/enforcement.js.map +1 -0
  313. package/core/error-handler.d.ts +131 -0
  314. package/core/error-handler.d.ts.map +1 -0
  315. package/core/error-handler.js +291 -0
  316. package/core/error-handler.js.map +1 -0
  317. package/core/federated-learning.d.ts +124 -0
  318. package/core/federated-learning.d.ts.map +1 -0
  319. package/core/federated-learning.js +338 -0
  320. package/core/federated-learning.js.map +1 -0
  321. package/core/fingerprint.d.ts +95 -0
  322. package/core/fingerprint.d.ts.map +1 -0
  323. package/core/fingerprint.js +313 -0
  324. package/core/fingerprint.js.map +1 -0
  325. package/core/geoip.d.ts +67 -0
  326. package/core/geoip.d.ts.map +1 -0
  327. package/core/geoip.js +174 -0
  328. package/core/geoip.js.map +1 -0
  329. package/core/gossip.d.ts +141 -0
  330. package/core/gossip.d.ts.map +1 -0
  331. package/core/gossip.js +372 -0
  332. package/core/gossip.js.map +1 -0
  333. package/core/governance.d.ts +147 -0
  334. package/core/governance.d.ts.map +1 -0
  335. package/core/governance.js +351 -0
  336. package/core/governance.js.map +1 -0
  337. package/core/indexer-enhancements.d.ts +164 -0
  338. package/core/indexer-enhancements.d.ts.map +1 -0
  339. package/core/indexer-enhancements.js +429 -0
  340. package/core/indexer-enhancements.js.map +1 -0
  341. package/core/intrusion-detection.d.ts +79 -0
  342. package/core/intrusion-detection.d.ts.map +1 -0
  343. package/core/intrusion-detection.js +322 -0
  344. package/core/intrusion-detection.js.map +1 -0
  345. package/core/lifecycle.d.ts +118 -0
  346. package/core/lifecycle.d.ts.map +1 -0
  347. package/core/lifecycle.js +310 -0
  348. package/core/lifecycle.js.map +1 -0
  349. package/core/location.d.ts +99 -0
  350. package/core/location.d.ts.map +1 -0
  351. package/core/location.js +219 -0
  352. package/core/location.js.map +1 -0
  353. package/core/maxmind-integration.d.ts +68 -0
  354. package/core/maxmind-integration.d.ts.map +1 -0
  355. package/core/maxmind-integration.js +245 -0
  356. package/core/maxmind-integration.js.map +1 -0
  357. package/core/migration.d.ts +58 -0
  358. package/core/migration.d.ts.map +1 -0
  359. package/core/migration.js +223 -0
  360. package/core/migration.js.map +1 -0
  361. package/core/monitoring.d.ts +153 -0
  362. package/core/monitoring.d.ts.map +1 -0
  363. package/core/monitoring.js +406 -0
  364. package/core/monitoring.js.map +1 -0
  365. package/core/offsite-backup.d.ts +71 -0
  366. package/core/offsite-backup.d.ts.map +1 -0
  367. package/core/offsite-backup.js +341 -0
  368. package/core/offsite-backup.js.map +1 -0
  369. package/core/order-intent-store.js +83 -0
  370. package/core/order-intent.js +273 -0
  371. package/core/paths.js +116 -0
  372. package/core/performance.d.ts +173 -0
  373. package/core/performance.d.ts.map +1 -0
  374. package/core/performance.js +386 -0
  375. package/core/performance.js.map +1 -0
  376. package/core/product-flag.d.ts +364 -0
  377. package/core/product-flag.d.ts.map +1 -0
  378. package/core/product-flag.js +465 -0
  379. package/core/product-flag.js.map +1 -0
  380. package/core/protection.d.ts +139 -0
  381. package/core/protection.d.ts.map +1 -0
  382. package/core/protection.js +327 -0
  383. package/core/protection.js.map +1 -0
  384. package/core/region-adapter.d.ts +152 -0
  385. package/core/region-adapter.d.ts.map +1 -0
  386. package/core/region-adapter.js +505 -0
  387. package/core/region-adapter.js.map +1 -0
  388. package/core/region-configs.d.ts +12 -0
  389. package/core/region-configs.d.ts.map +1 -0
  390. package/core/region-configs.js +907 -0
  391. package/core/region-configs.js.map +1 -0
  392. package/core/review-antifraud.d.ts +80 -0
  393. package/core/review-antifraud.d.ts.map +1 -0
  394. package/core/review-antifraud.js +193 -0
  395. package/core/review-antifraud.js.map +1 -0
  396. package/core/rules-updater.d.ts +89 -0
  397. package/core/rules-updater.d.ts.map +1 -0
  398. package/core/rules-updater.js +261 -0
  399. package/core/rules-updater.js.map +1 -0
  400. package/core/runtime-data.js +203 -0
  401. package/core/security.d.ts +144 -0
  402. package/core/security.d.ts.map +1 -0
  403. package/core/security.js +390 -0
  404. package/core/security.js.map +1 -0
  405. package/core/seller-identity.js +78 -0
  406. package/core/session-manager.d.ts +93 -0
  407. package/core/session-manager.d.ts.map +1 -0
  408. package/core/session-manager.js +262 -0
  409. package/core/session-manager.js.map +1 -0
  410. package/core/state-sync.d.ts +121 -0
  411. package/core/state-sync.d.ts.map +1 -0
  412. package/core/state-sync.js +287 -0
  413. package/core/state-sync.js.map +1 -0
  414. package/core/testing.d.ts +97 -0
  415. package/core/testing.d.ts.map +1 -0
  416. package/core/testing.js +361 -0
  417. package/core/testing.js.map +1 -0
  418. package/core/trust-score.d.ts +51 -0
  419. package/core/trust-score.d.ts.map +1 -0
  420. package/core/trust-score.js +188 -0
  421. package/core/trust-score.js.map +1 -0
  422. package/core/trustworthiness.d.ts +140 -0
  423. package/core/trustworthiness.d.ts.map +1 -0
  424. package/core/trustworthiness.js +375 -0
  425. package/core/trustworthiness.js.map +1 -0
  426. package/core/types.d.ts +258 -0
  427. package/core/types.d.ts.map +1 -0
  428. package/core/types.js +9 -0
  429. package/core/types.js.map +1 -0
  430. package/core/upgrade-manager.d.ts +114 -0
  431. package/core/upgrade-manager.d.ts.map +1 -0
  432. package/core/upgrade-manager.js +264 -0
  433. package/core/upgrade-manager.js.map +1 -0
  434. package/core/upgrader.d.ts +107 -0
  435. package/core/upgrader.d.ts.map +1 -0
  436. package/core/upgrader.js +389 -0
  437. package/core/upgrader.js.map +1 -0
  438. package/core/websocket.d.ts +78 -0
  439. package/core/websocket.d.ts.map +1 -0
  440. package/core/websocket.js +292 -0
  441. package/core/websocket.js.map +1 -0
  442. package/council/hidden-weight.d.ts +45 -0
  443. package/council/hidden-weight.d.ts.map +1 -0
  444. package/council/hidden-weight.js +135 -0
  445. package/council/hidden-weight.js.map +1 -0
  446. package/db/email-migrations.sql +31 -0
  447. package/db/oauth-migrate.d.ts +39 -0
  448. package/db/oauth-migrate.d.ts.map +1 -0
  449. package/db/oauth-migrate.js +201 -0
  450. package/db/oauth-migrate.js.map +1 -0
  451. package/db/oauth-migrations.sql +92 -0
  452. package/db/social-migrate.d.ts +12 -0
  453. package/db/social-migrate.d.ts.map +1 -0
  454. package/db/social-migrate.js +102 -0
  455. package/db/social-migrate.js.map +1 -0
  456. package/db/social-migrations.sql +94 -0
  457. package/db/store-migrate.d.ts +33 -0
  458. package/db/store-migrate.d.ts.map +1 -0
  459. package/db/store-migrate.js +149 -0
  460. package/db/store-migrate.js.map +1 -0
  461. package/db/store-migrations.sql +242 -0
  462. package/debug.d.ts +2 -0
  463. package/debug.d.ts.map +1 -0
  464. package/debug.js +18 -0
  465. package/debug.js.map +1 -0
  466. package/event-listener.d.ts +93 -0
  467. package/event-listener.d.ts.map +1 -0
  468. package/event-listener.js +321 -0
  469. package/event-listener.js.map +1 -0
  470. package/event-whitelist.d.ts +79 -0
  471. package/event-whitelist.d.ts.map +1 -0
  472. package/event-whitelist.js +533 -0
  473. package/event-whitelist.js.map +1 -0
  474. package/index.d.ts +45 -0
  475. package/index.d.ts.map +1 -0
  476. package/index.js +361 -0
  477. package/index.js.map +1 -0
  478. package/init-node.d.ts +9 -0
  479. package/init-node.d.ts.map +1 -0
  480. package/init-node.js +230 -0
  481. package/init-node.js.map +1 -0
  482. package/mcp/ai-tools.d.ts +2 -0
  483. package/mcp/ai-tools.d.ts.map +1 -0
  484. package/mcp/ai-tools.js +266 -0
  485. package/mcp/ai-tools.js.map +1 -0
  486. package/mcp/auto-dispatch-tools.d.ts +2 -0
  487. package/mcp/auto-dispatch-tools.d.ts.map +1 -0
  488. package/mcp/auto-dispatch-tools.js +348 -0
  489. package/mcp/auto-dispatch-tools.js.map +1 -0
  490. package/mcp/business-scope-tools.d.ts +11 -0
  491. package/mcp/business-scope-tools.d.ts.map +1 -0
  492. package/mcp/business-scope-tools.js +179 -0
  493. package/mcp/business-scope-tools.js.map +1 -0
  494. package/mcp/buyer-tools.d.ts +67 -0
  495. package/mcp/buyer-tools.d.ts.map +1 -0
  496. package/mcp/buyer-tools.js +445 -0
  497. package/mcp/buyer-tools.js.map +1 -0
  498. package/mcp/interfaces.d.ts +1058 -0
  499. package/mcp/interfaces.d.ts.map +1 -0
  500. package/mcp/interfaces.js +13 -0
  501. package/mcp/interfaces.js.map +1 -0
  502. package/mcp/m2m-chat-tool.d.ts +50 -0
  503. package/mcp/m2m-chat-tool.d.ts.map +1 -0
  504. package/mcp/m2m-chat-tool.js +432 -0
  505. package/mcp/m2m-chat-tool.js.map +1 -0
  506. package/mcp/migrations.d.ts +30 -0
  507. package/mcp/migrations.d.ts.map +1 -0
  508. package/mcp/migrations.js +391 -0
  509. package/mcp/migrations.js.map +1 -0
  510. package/mcp/peer-tools.d.ts +163 -0
  511. package/mcp/peer-tools.d.ts.map +1 -0
  512. package/mcp/peer-tools.js +532 -0
  513. package/mcp/peer-tools.js.map +1 -0
  514. package/mcp/plugin-management-tools.d.ts +2 -0
  515. package/mcp/plugin-management-tools.d.ts.map +1 -0
  516. package/mcp/plugin-management-tools.js +327 -0
  517. package/mcp/plugin-management-tools.js.map +1 -0
  518. package/mcp/product-type-tools.d.ts +2 -0
  519. package/mcp/product-type-tools.d.ts.map +1 -0
  520. package/mcp/product-type-tools.js +470 -0
  521. package/mcp/product-type-tools.js.map +1 -0
  522. package/mcp/security-tools.d.ts +2 -0
  523. package/mcp/security-tools.d.ts.map +1 -0
  524. package/mcp/security-tools.js +313 -0
  525. package/mcp/security-tools.js.map +1 -0
  526. package/mcp/seller-query-tools.d.ts +2 -0
  527. package/mcp/seller-query-tools.d.ts.map +1 -0
  528. package/mcp/seller-query-tools.js +179 -0
  529. package/mcp/seller-query-tools.js.map +1 -0
  530. package/mcp/server.d.ts +11 -0
  531. package/mcp/server.d.ts.map +1 -0
  532. package/mcp/server.js +68 -0
  533. package/mcp/server.js.map +1 -0
  534. package/mcp/standalone-server.d.ts +34 -0
  535. package/mcp/standalone-server.d.ts.map +1 -0
  536. package/mcp/standalone-server.js +261 -0
  537. package/mcp/standalone-server.js.map +1 -0
  538. package/mcp/tools-integration.d.ts +31 -0
  539. package/mcp/tools-integration.d.ts.map +1 -0
  540. package/mcp/tools-integration.js +288 -0
  541. package/mcp/tools-integration.js.map +1 -0
  542. package/mcp/web-panel.d.ts +18 -0
  543. package/mcp/web-panel.d.ts.map +1 -0
  544. package/mcp/web-panel.js +1657 -0
  545. package/mcp/web-panel.js.map +1 -0
  546. package/middleware/api-key-auth.d.ts +64 -0
  547. package/middleware/api-key-auth.d.ts.map +1 -0
  548. package/middleware/api-key-auth.js +255 -0
  549. package/middleware/api-key-auth.js.map +1 -0
  550. package/middleware/scope-auth.d.ts +54 -0
  551. package/middleware/scope-auth.d.ts.map +1 -0
  552. package/middleware/scope-auth.js +153 -0
  553. package/middleware/scope-auth.js.map +1 -0
  554. package/middleware/security.d.ts +48 -0
  555. package/middleware/security.d.ts.map +1 -0
  556. package/middleware/security.js +217 -0
  557. package/middleware/security.js.map +1 -0
  558. package/middleware/wallet-auth.d.ts +54 -0
  559. package/middleware/wallet-auth.d.ts.map +1 -0
  560. package/middleware/wallet-auth.js +158 -0
  561. package/middleware/wallet-auth.js.map +1 -0
  562. package/oauth/chain-revocation-sink.d.ts +24 -0
  563. package/oauth/chain-revocation-sink.d.ts.map +1 -0
  564. package/oauth/chain-revocation-sink.js +47 -0
  565. package/oauth/chain-revocation-sink.js.map +1 -0
  566. package/oauth/gossip-sync.d.ts +25 -0
  567. package/oauth/gossip-sync.d.ts.map +1 -0
  568. package/oauth/gossip-sync.js +62 -0
  569. package/oauth/gossip-sync.js.map +1 -0
  570. package/oauth/issuer-keys.d.ts +31 -0
  571. package/oauth/issuer-keys.d.ts.map +1 -0
  572. package/oauth/issuer-keys.js +117 -0
  573. package/oauth/issuer-keys.js.map +1 -0
  574. package/oauth/peer-resolver.d.ts +25 -0
  575. package/oauth/peer-resolver.d.ts.map +1 -0
  576. package/oauth/peer-resolver.js +81 -0
  577. package/oauth/peer-resolver.js.map +1 -0
  578. package/oauth/revocation-store.d.ts +58 -0
  579. package/oauth/revocation-store.d.ts.map +1 -0
  580. package/oauth/revocation-store.js +86 -0
  581. package/oauth/revocation-store.js.map +1 -0
  582. package/oauth/token-v2.d.ts +101 -0
  583. package/oauth/token-v2.d.ts.map +1 -0
  584. package/oauth/token-v2.js +167 -0
  585. package/oauth/token-v2.js.map +1 -0
  586. package/oracle/c5-glue.js +603 -0
  587. package/oracle/ops-console.js +623 -0
  588. package/oracle/oracle-sync.d.ts +29 -0
  589. package/oracle/oracle-sync.d.ts.map +1 -0
  590. package/oracle/oracle-sync.js +445 -0
  591. package/oracle/oracle-sync.js.map +1 -0
  592. package/oracle/registry.d.ts +30 -0
  593. package/oracle/registry.d.ts.map +1 -0
  594. package/oracle/registry.js +62 -0
  595. package/oracle/registry.js.map +1 -0
  596. package/p2p/availability.d.ts +188 -0
  597. package/p2p/availability.d.ts.map +1 -0
  598. package/p2p/availability.js +574 -0
  599. package/p2p/availability.js.map +1 -0
  600. package/p2p/bootstrap.d.ts +42 -0
  601. package/p2p/bootstrap.d.ts.map +1 -0
  602. package/p2p/bootstrap.js +146 -0
  603. package/p2p/bootstrap.js.map +1 -0
  604. package/p2p/buyer-client.d.ts +98 -0
  605. package/p2p/buyer-client.d.ts.map +1 -0
  606. package/p2p/buyer-client.js +199 -0
  607. package/p2p/buyer-client.js.map +1 -0
  608. package/p2p/cdn-ddns.d.ts +208 -0
  609. package/p2p/cdn-ddns.d.ts.map +1 -0
  610. package/p2p/cdn-ddns.js +500 -0
  611. package/p2p/cdn-ddns.js.map +1 -0
  612. package/p2p/cluster-sync.d.ts +115 -0
  613. package/p2p/cluster-sync.d.ts.map +1 -0
  614. package/p2p/cluster-sync.js +330 -0
  615. package/p2p/cluster-sync.js.map +1 -0
  616. package/p2p/consistency-check.d.ts +30 -0
  617. package/p2p/consistency-check.d.ts.map +1 -0
  618. package/p2p/consistency-check.js +168 -0
  619. package/p2p/consistency-check.js.map +1 -0
  620. package/p2p/endpoint-registry.d.ts +41 -0
  621. package/p2p/endpoint-registry.d.ts.map +1 -0
  622. package/p2p/endpoint-registry.js +128 -0
  623. package/p2p/endpoint-registry.js.map +1 -0
  624. package/p2p/ipv6.d.ts +120 -0
  625. package/p2p/ipv6.d.ts.map +1 -0
  626. package/p2p/ipv6.js +425 -0
  627. package/p2p/ipv6.js.map +1 -0
  628. package/p2p/protocol.d.ts +100 -0
  629. package/p2p/protocol.d.ts.map +1 -0
  630. package/p2p/protocol.js +330 -0
  631. package/p2p/protocol.js.map +1 -0
  632. package/p2p/reliability.d.ts +56 -0
  633. package/p2p/reliability.d.ts.map +1 -0
  634. package/p2p/reliability.js +240 -0
  635. package/p2p/reliability.js.map +1 -0
  636. package/p2p/seller-service.d.ts +53 -0
  637. package/p2p/seller-service.d.ts.map +1 -0
  638. package/p2p/seller-service.js +276 -0
  639. package/p2p/seller-service.js.map +1 -0
  640. package/p2p/signing.d.ts +31 -0
  641. package/p2p/signing.d.ts.map +1 -0
  642. package/p2p/signing.js +95 -0
  643. package/p2p/signing.js.map +1 -0
  644. package/package.json +73 -0
  645. package/payment/api.d.ts +9 -0
  646. package/payment/api.d.ts.map +1 -0
  647. package/payment/api.js +141 -0
  648. package/payment/api.js.map +1 -0
  649. package/payment/gateway.d.ts +114 -0
  650. package/payment/gateway.d.ts.map +1 -0
  651. package/payment/gateway.js +231 -0
  652. package/payment/gateway.js.map +1 -0
  653. package/payments/alipay/index.d.ts +18 -0
  654. package/payments/alipay/index.d.ts.map +1 -0
  655. package/payments/alipay/index.js +55 -0
  656. package/payments/alipay/index.js.map +1 -0
  657. package/payments/base.d.ts +13 -0
  658. package/payments/base.d.ts.map +1 -0
  659. package/payments/base.js +28 -0
  660. package/payments/base.js.map +1 -0
  661. package/payments/index.d.ts +18 -0
  662. package/payments/index.d.ts.map +1 -0
  663. package/payments/index.js +66 -0
  664. package/payments/index.js.map +1 -0
  665. package/payments/template/index.d.ts +18 -0
  666. package/payments/template/index.d.ts.map +1 -0
  667. package/payments/template/index.js +57 -0
  668. package/payments/template/index.js.map +1 -0
  669. package/payments/types.d.ts +42 -0
  670. package/payments/types.d.ts.map +1 -0
  671. package/payments/types.js +3 -0
  672. package/payments/types.js.map +1 -0
  673. package/payments/wechat/index.d.ts +18 -0
  674. package/payments/wechat/index.d.ts.map +1 -0
  675. package/payments/wechat/index.js +54 -0
  676. package/payments/wechat/index.js.map +1 -0
  677. package/peer/chain-signer.d.ts +74 -0
  678. package/peer/chain-signer.d.ts.map +1 -0
  679. package/peer/chain-signer.js +149 -0
  680. package/peer/chain-signer.js.map +1 -0
  681. package/peer/config.d.ts +71 -0
  682. package/peer/config.d.ts.map +1 -0
  683. package/peer/config.js +61 -0
  684. package/peer/config.js.map +1 -0
  685. package/peer/index.d.ts +12 -0
  686. package/peer/index.d.ts.map +1 -0
  687. package/peer/index.js +46 -0
  688. package/peer/index.js.map +1 -0
  689. package/peer/key-store.d.ts +66 -0
  690. package/peer/key-store.d.ts.map +1 -0
  691. package/peer/key-store.js +163 -0
  692. package/peer/key-store.js.map +1 -0
  693. package/peer/proto-codec.d.ts +103 -0
  694. package/peer/proto-codec.d.ts.map +1 -0
  695. package/peer/proto-codec.js +423 -0
  696. package/peer/proto-codec.js.map +1 -0
  697. package/peer/registrar.d.ts +88 -0
  698. package/peer/registrar.d.ts.map +1 -0
  699. package/peer/registrar.js +271 -0
  700. package/peer/registrar.js.map +1 -0
  701. package/peer/registry.d.ts +31 -0
  702. package/peer/registry.d.ts.map +1 -0
  703. package/peer/registry.js +143 -0
  704. package/peer/registry.js.map +1 -0
  705. package/plugins/auth.d.ts +193 -0
  706. package/plugins/auth.d.ts.map +1 -0
  707. package/plugins/auth.js +923 -0
  708. package/plugins/auth.js.map +1 -0
  709. package/plugins/manager.d.ts +37 -0
  710. package/plugins/manager.d.ts.map +1 -0
  711. package/plugins/manager.js +83 -0
  712. package/plugins/manager.js.map +1 -0
  713. package/plugins/oauth.d.ts +249 -0
  714. package/plugins/oauth.d.ts.map +1 -0
  715. package/plugins/oauth.js +979 -0
  716. package/plugins/oauth.js.map +1 -0
  717. package/plugins/p2p-message.d.ts +133 -0
  718. package/plugins/p2p-message.d.ts.map +1 -0
  719. package/plugins/p2p-message.js +443 -0
  720. package/plugins/p2p-message.js.map +1 -0
  721. package/plugins/postgresql.d.ts +54 -0
  722. package/plugins/postgresql.d.ts.map +1 -0
  723. package/plugins/postgresql.js +743 -0
  724. package/plugins/postgresql.js.map +1 -0
  725. package/plugins/relationship.d.ts +141 -0
  726. package/plugins/relationship.d.ts.map +1 -0
  727. package/plugins/relationship.js +395 -0
  728. package/plugins/relationship.js.map +1 -0
  729. package/plugins/sqlite.d.ts +200 -0
  730. package/plugins/sqlite.d.ts.map +1 -0
  731. package/plugins/sqlite.js +2412 -0
  732. package/plugins/sqlite.js.map +1 -0
  733. package/port-manager/disguise/ssh.d.ts +19 -0
  734. package/port-manager/disguise/ssh.d.ts.map +1 -0
  735. package/port-manager/disguise/ssh.js +104 -0
  736. package/port-manager/disguise/ssh.js.map +1 -0
  737. package/port-manager/port-manager.d.ts +65 -0
  738. package/port-manager/port-manager.d.ts.map +1 -0
  739. package/port-manager/port-manager.js +164 -0
  740. package/port-manager/port-manager.js.map +1 -0
  741. package/port-manager/port-scanner.d.ts +22 -0
  742. package/port-manager/port-scanner.d.ts.map +1 -0
  743. package/port-manager/port-scanner.js +187 -0
  744. package/port-manager/port-scanner.js.map +1 -0
  745. package/port-manager/types.d.ts +51 -0
  746. package/port-manager/types.d.ts.map +1 -0
  747. package/port-manager/types.js +6 -0
  748. package/port-manager/types.js.map +1 -0
  749. package/proto/amino/amino.proto +84 -0
  750. package/proto/cosmos/base/v1beta1/coin.proto +61 -0
  751. package/proto/cosmos/msg/v1/msg.proto +30 -0
  752. package/proto/cosmos_proto/cosmos.proto +112 -0
  753. package/proto/gogoproto/gogo.proto +145 -0
  754. package/proto/google/protobuf/descriptor.proto +1218 -0
  755. package/proto/trustchain/economy/v1/params.proto +133 -0
  756. package/proto/trustchain/economy/v1/tx.proto +162 -0
  757. package/proto/trustchain/marketplace/v1/params.proto +64 -0
  758. package/proto/trustchain/marketplace/v1/product.proto +21 -0
  759. package/proto/trustchain/marketplace/v1/tx.proto +131 -0
  760. package/proto/trustchain/order/v1/params.proto +94 -0
  761. package/proto/trustchain/order/v1/tx.proto +156 -0
  762. package/proto/trustchain/serviceprovider/v1/paymentfact.proto +32 -0
  763. package/proto/trustchain/serviceprovider/v1/serviceprovider.proto +38 -0
  764. package/proto/trustchain/serviceprovider/v1/tx.proto +106 -0
  765. package/proto/trustchain/subchain/v1/params.proto +26 -0
  766. package/proto/trustchain/subchain/v1/pool.proto +53 -0
  767. package/proto/trustchain/subchain/v1/tx.proto +159 -0
  768. package/proto/trustchain/trustcoin/v1/business_scope.proto +126 -0
  769. package/proto/trustchain/trustcoin/v1/genesis.proto +33 -0
  770. package/proto/trustchain/trustcoin/v1/params.proto +86 -0
  771. package/proto/trustchain/trustcoin/v1/query.proto +95 -0
  772. package/proto/trustchain/trustcoin/v1/tx.proto +160 -0
  773. package/proto/trustchain/verification/v1/params.proto +46 -0
  774. package/proto/trustchain/verification/v1/tx.proto +126 -0
  775. package/proto/trustchain/verification/v1/verification.proto +105 -0
  776. package/relationship-chain-api.d.ts +13 -0
  777. package/relationship-chain-api.d.ts.map +1 -0
  778. package/relationship-chain-api.js +139 -0
  779. package/relationship-chain-api.js.map +1 -0
  780. package/relationship-chain.d.ts +90 -0
  781. package/relationship-chain.d.ts.map +1 -0
  782. package/relationship-chain.js +201 -0
  783. package/relationship-chain.js.map +1 -0
  784. package/routes/agent-pay.js +419 -0
  785. package/routes/agent-serviceprovider.js +183 -0
  786. package/routes/ai.d.ts +54 -0
  787. package/routes/ai.d.ts.map +1 -0
  788. package/routes/ai.js +293 -0
  789. package/routes/ai.js.map +1 -0
  790. package/routes/api-keys.d.ts +12 -0
  791. package/routes/api-keys.d.ts.map +1 -0
  792. package/routes/api-keys.js +163 -0
  793. package/routes/api-keys.js.map +1 -0
  794. package/routes/app-store.d.ts +12 -0
  795. package/routes/app-store.d.ts.map +1 -0
  796. package/routes/app-store.js +207 -0
  797. package/routes/app-store.js.map +1 -0
  798. package/routes/auth-management.d.ts +17 -0
  799. package/routes/auth-management.d.ts.map +1 -0
  800. package/routes/auth-management.js +257 -0
  801. package/routes/auth-management.js.map +1 -0
  802. package/routes/auth.d.ts +9 -0
  803. package/routes/auth.d.ts.map +1 -0
  804. package/routes/auth.js +846 -0
  805. package/routes/auth.js.map +1 -0
  806. package/routes/brand.d.ts +3 -0
  807. package/routes/brand.d.ts.map +1 -0
  808. package/routes/brand.js +109 -0
  809. package/routes/brand.js.map +1 -0
  810. package/routes/chain-registry.d.ts +11 -0
  811. package/routes/chain-registry.d.ts.map +1 -0
  812. package/routes/chain-registry.js +51 -0
  813. package/routes/chain-registry.js.map +1 -0
  814. package/routes/chain-writes-insurance.d.ts +17 -0
  815. package/routes/chain-writes-insurance.d.ts.map +1 -0
  816. package/routes/chain-writes-insurance.js +69 -0
  817. package/routes/chain-writes-insurance.js.map +1 -0
  818. package/routes/chain-writes-pledge.d.ts +34 -0
  819. package/routes/chain-writes-pledge.d.ts.map +1 -0
  820. package/routes/chain-writes-pledge.js +206 -0
  821. package/routes/chain-writes-pledge.js.map +1 -0
  822. package/routes/chain-writes-products.d.ts +66 -0
  823. package/routes/chain-writes-products.d.ts.map +1 -0
  824. package/routes/chain-writes-products.js +394 -0
  825. package/routes/chain-writes-products.js.map +1 -0
  826. package/routes/chain-writes.d.ts +78 -0
  827. package/routes/chain-writes.d.ts.map +1 -0
  828. package/routes/chain-writes.js +658 -0
  829. package/routes/chain-writes.js.map +1 -0
  830. package/routes/chain.d.ts +10 -0
  831. package/routes/chain.d.ts.map +1 -0
  832. package/routes/chain.js +45 -0
  833. package/routes/chain.js.map +1 -0
  834. package/routes/compliance.d.ts +3 -0
  835. package/routes/compliance.d.ts.map +1 -0
  836. package/routes/compliance.js +53 -0
  837. package/routes/compliance.js.map +1 -0
  838. package/routes/council.d.ts +3 -0
  839. package/routes/council.d.ts.map +1 -0
  840. package/routes/council.js +477 -0
  841. package/routes/council.js.map +1 -0
  842. package/routes/crosschain.d.ts +11 -0
  843. package/routes/crosschain.d.ts.map +1 -0
  844. package/routes/crosschain.js +39 -0
  845. package/routes/crosschain.js.map +1 -0
  846. package/routes/device.d.ts +3 -0
  847. package/routes/device.d.ts.map +1 -0
  848. package/routes/device.js +73 -0
  849. package/routes/device.js.map +1 -0
  850. package/routes/devreward.d.ts +54 -0
  851. package/routes/devreward.d.ts.map +1 -0
  852. package/routes/devreward.js +129 -0
  853. package/routes/devreward.js.map +1 -0
  854. package/routes/economy.d.ts +50 -0
  855. package/routes/economy.d.ts.map +1 -0
  856. package/routes/economy.js +273 -0
  857. package/routes/economy.js.map +1 -0
  858. package/routes/flowback.d.ts +32 -0
  859. package/routes/flowback.d.ts.map +1 -0
  860. package/routes/flowback.js +97 -0
  861. package/routes/flowback.js.map +1 -0
  862. package/routes/insurance.d.ts +10 -0
  863. package/routes/insurance.d.ts.map +1 -0
  864. package/routes/insurance.js +70 -0
  865. package/routes/insurance.js.map +1 -0
  866. package/routes/m2m-viewer.js +195 -0
  867. package/routes/m2m.d.ts +10 -0
  868. package/routes/m2m.d.ts.map +1 -0
  869. package/routes/m2m.js +31 -0
  870. package/routes/m2m.js.map +1 -0
  871. package/routes/marketplace.d.ts +15 -0
  872. package/routes/marketplace.d.ts.map +1 -0
  873. package/routes/marketplace.js +396 -0
  874. package/routes/marketplace.js.map +1 -0
  875. package/routes/node-config.d.ts +6 -0
  876. package/routes/node-config.d.ts.map +1 -0
  877. package/routes/node-config.js +500 -0
  878. package/routes/node-config.js.map +1 -0
  879. package/routes/oauth-revocation.d.ts +42 -0
  880. package/routes/oauth-revocation.d.ts.map +1 -0
  881. package/routes/oauth-revocation.js +99 -0
  882. package/routes/oauth-revocation.js.map +1 -0
  883. package/routes/oauth.d.ts +17 -0
  884. package/routes/oauth.d.ts.map +1 -0
  885. package/routes/oauth.js +700 -0
  886. package/routes/oauth.js.map +1 -0
  887. package/routes/onboard.html +352 -0
  888. package/routes/onboard.js +435 -0
  889. package/routes/order.d.ts +8 -0
  890. package/routes/order.d.ts.map +1 -0
  891. package/routes/order.js +607 -0
  892. package/routes/order.js.map +1 -0
  893. package/routes/p2p-api.d.ts +33 -0
  894. package/routes/p2p-api.d.ts.map +1 -0
  895. package/routes/p2p-api.js +274 -0
  896. package/routes/p2p-api.js.map +1 -0
  897. package/routes/p2p-message.d.ts +20 -0
  898. package/routes/p2p-message.d.ts.map +1 -0
  899. package/routes/p2p-message.js +237 -0
  900. package/routes/p2p-message.js.map +1 -0
  901. package/routes/peer.d.ts +22 -0
  902. package/routes/peer.d.ts.map +1 -0
  903. package/routes/peer.js +220 -0
  904. package/routes/peer.js.map +1 -0
  905. package/routes/plugins.d.ts +4 -0
  906. package/routes/plugins.d.ts.map +1 -0
  907. package/routes/plugins.js +138 -0
  908. package/routes/plugins.js.map +1 -0
  909. package/routes/port-manager.d.ts +6 -0
  910. package/routes/port-manager.d.ts.map +1 -0
  911. package/routes/port-manager.js +212 -0
  912. package/routes/port-manager.js.map +1 -0
  913. package/routes/relationship.d.ts +7 -0
  914. package/routes/relationship.d.ts.map +1 -0
  915. package/routes/relationship.js +314 -0
  916. package/routes/relationship.js.map +1 -0
  917. package/routes/relay.d.ts +3 -0
  918. package/routes/relay.d.ts.map +1 -0
  919. package/routes/relay.js +182 -0
  920. package/routes/relay.js.map +1 -0
  921. package/routes/reputation.d.ts +10 -0
  922. package/routes/reputation.d.ts.map +1 -0
  923. package/routes/reputation.js +141 -0
  924. package/routes/reputation.js.map +1 -0
  925. package/routes/reward.d.ts +3 -0
  926. package/routes/reward.d.ts.map +1 -0
  927. package/routes/reward.js +130 -0
  928. package/routes/reward.js.map +1 -0
  929. package/routes/security-monitoring.d.ts +12 -0
  930. package/routes/security-monitoring.d.ts.map +1 -0
  931. package/routes/security-monitoring.js +373 -0
  932. package/routes/security-monitoring.js.map +1 -0
  933. package/routes/shop.d.ts +8 -0
  934. package/routes/shop.d.ts.map +1 -0
  935. package/routes/shop.js +164 -0
  936. package/routes/shop.js.map +1 -0
  937. package/routes/social.d.ts +22 -0
  938. package/routes/social.d.ts.map +1 -0
  939. package/routes/social.js +95 -0
  940. package/routes/social.js.map +1 -0
  941. package/routes/subchain.d.ts +18 -0
  942. package/routes/subchain.d.ts.map +1 -0
  943. package/routes/subchain.js +106 -0
  944. package/routes/subchain.js.map +1 -0
  945. package/routes/trustcoin.d.ts +17 -0
  946. package/routes/trustcoin.d.ts.map +1 -0
  947. package/routes/trustcoin.js +149 -0
  948. package/routes/trustcoin.js.map +1 -0
  949. package/routes/twofa.d.ts +7 -0
  950. package/routes/twofa.d.ts.map +1 -0
  951. package/routes/twofa.js +105 -0
  952. package/routes/twofa.js.map +1 -0
  953. package/routes/verification.d.ts +8 -0
  954. package/routes/verification.d.ts.map +1 -0
  955. package/routes/verification.js +234 -0
  956. package/routes/verification.js.map +1 -0
  957. package/routes/wallet.d.ts +4 -0
  958. package/routes/wallet.d.ts.map +1 -0
  959. package/routes/wallet.js +770 -0
  960. package/routes/wallet.js.map +1 -0
  961. package/run-auth.d.ts +8 -0
  962. package/run-auth.d.ts.map +1 -0
  963. package/run-auth.js +82 -0
  964. package/run-auth.js.map +1 -0
  965. package/run-p2p-message.d.ts +8 -0
  966. package/run-p2p-message.d.ts.map +1 -0
  967. package/run-p2p-message.js +82 -0
  968. package/run-p2p-message.js.map +1 -0
  969. package/run-relationship.d.ts +12 -0
  970. package/run-relationship.d.ts.map +1 -0
  971. package/run-relationship.js +182 -0
  972. package/run-relationship.js.map +1 -0
  973. package/run-unified.d.ts +13 -0
  974. package/run-unified.d.ts.map +1 -0
  975. package/run-unified.js +1067 -0
  976. package/run-unified.js.map +1 -0
  977. package/run.d.ts +12 -0
  978. package/run.d.ts.map +1 -0
  979. package/run.js +889 -0
  980. package/run.js.map +1 -0
  981. package/search/ranking.d.ts +55 -0
  982. package/search/ranking.d.ts.map +1 -0
  983. package/search/ranking.js +67 -0
  984. package/search/ranking.js.map +1 -0
  985. package/shipping/base.d.ts +15 -0
  986. package/shipping/base.d.ts.map +1 -0
  987. package/shipping/base.js +39 -0
  988. package/shipping/base.js.map +1 -0
  989. package/shipping/index.d.ts +19 -0
  990. package/shipping/index.d.ts.map +1 -0
  991. package/shipping/index.js +72 -0
  992. package/shipping/index.js.map +1 -0
  993. package/shipping/sf-express/index.d.ts +23 -0
  994. package/shipping/sf-express/index.d.ts.map +1 -0
  995. package/shipping/sf-express/index.js +71 -0
  996. package/shipping/sf-express/index.js.map +1 -0
  997. package/shipping/template/index.d.ts +20 -0
  998. package/shipping/template/index.d.ts.map +1 -0
  999. package/shipping/template/index.js +74 -0
  1000. package/shipping/template/index.js.map +1 -0
  1001. package/shipping/types.d.ts +71 -0
  1002. package/shipping/types.d.ts.map +1 -0
  1003. package/shipping/types.js +6 -0
  1004. package/shipping/types.js.map +1 -0
  1005. package/shipping/virtual/index.d.ts +19 -0
  1006. package/shipping/virtual/index.d.ts.map +1 -0
  1007. package/shipping/virtual/index.js +54 -0
  1008. package/shipping/virtual/index.js.map +1 -0
  1009. package/shipping/yto/index.d.ts +18 -0
  1010. package/shipping/yto/index.d.ts.map +1 -0
  1011. package/shipping/yto/index.js +59 -0
  1012. package/shipping/yto/index.js.map +1 -0
  1013. package/shipping/zto/index.d.ts +18 -0
  1014. package/shipping/zto/index.d.ts.map +1 -0
  1015. package/shipping/zto/index.js +59 -0
  1016. package/shipping/zto/index.js.map +1 -0
  1017. package/skills-lock.json +11 -0
  1018. package/src/db/email-migrations.sql +31 -0
  1019. package/src/db/oauth-migrations.sql +92 -0
  1020. package/src/db/social-migrations.sql +94 -0
  1021. package/src/db/store-migrations.sql +242 -0
  1022. package/test-api-key-revoke.js +167 -0
  1023. package/test-auth-register-ratelimit.js +132 -0
  1024. package/test-auth-tv2.d.ts +2 -0
  1025. package/test-auth-tv2.d.ts.map +1 -0
  1026. package/test-auth-tv2.js +174 -0
  1027. package/test-auth-tv2.js.map +1 -0
  1028. package/test-canonsign-cross.d.ts +2 -0
  1029. package/test-canonsign-cross.d.ts.map +1 -0
  1030. package/test-canonsign-cross.js +32 -0
  1031. package/test-canonsign-cross.js.map +1 -0
  1032. package/test-chain-signer.js +127 -0
  1033. package/test-env-truthy.js +50 -0
  1034. package/test-onboard-contract.js +94 -0
  1035. package/test-ops-console-boundary.js +147 -0
  1036. package/test-oracle-glue.js +232 -0
  1037. package/test-order-create-v394.js +358 -0
  1038. package/test-order-intent.js +245 -0
  1039. package/test-order-lifecycle-v394.js +528 -0
  1040. package/test-p2p-message.d.ts +13 -0
  1041. package/test-p2p-message.d.ts.map +1 -0
  1042. package/test-p2p-message.js +106 -0
  1043. package/test-p2p-message.js.map +1 -0
  1044. package/test-relationship-chain.d.ts +13 -0
  1045. package/test-relationship-chain.d.ts.map +1 -0
  1046. package/test-relationship-chain.js +103 -0
  1047. package/test-relationship-chain.js.map +1 -0
  1048. package/test-runtime-data-path.js +217 -0
  1049. package/test-seller-identity.js +74 -0
  1050. package/test-signing-paths.js +104 -0
  1051. package/test-token-v2.d.ts +2 -0
  1052. package/test-token-v2.d.ts.map +1 -0
  1053. package/test-token-v2.js +172 -0
  1054. package/test-token-v2.js.map +1 -0
  1055. package/test-wallet-auth-nonce.d.ts +12 -0
  1056. package/test-wallet-auth-nonce.d.ts.map +1 -0
  1057. package/test-wallet-auth-nonce.js +126 -0
  1058. package/test-wallet-auth-nonce.js.map +1 -0
  1059. package/test-wallet-submatch.d.ts +13 -0
  1060. package/test-wallet-submatch.d.ts.map +1 -0
  1061. package/test-wallet-submatch.js +86 -0
  1062. package/test-wallet-submatch.js.map +1 -0
  1063. package/tls/self-signed.d.ts +12 -0
  1064. package/tls/self-signed.d.ts.map +1 -0
  1065. package/tls/self-signed.js +63 -0
  1066. package/tls/self-signed.js.map +1 -0
  1067. package/tools/brand.d.ts +11 -0
  1068. package/tools/brand.d.ts.map +1 -0
  1069. package/tools/brand.js +75 -0
  1070. package/tools/brand.js.map +1 -0
  1071. package/tools/chainregistry.d.ts +18 -0
  1072. package/tools/chainregistry.d.ts.map +1 -0
  1073. package/tools/chainregistry.js +175 -0
  1074. package/tools/chainregistry.js.map +1 -0
  1075. package/tools/compliance.d.ts +14 -0
  1076. package/tools/compliance.d.ts.map +1 -0
  1077. package/tools/compliance.js +45 -0
  1078. package/tools/compliance.js.map +1 -0
  1079. package/tools/council.d.ts +17 -0
  1080. package/tools/council.d.ts.map +1 -0
  1081. package/tools/council.js +75 -0
  1082. package/tools/council.js.map +1 -0
  1083. package/tools/device.d.ts +13 -0
  1084. package/tools/device.d.ts.map +1 -0
  1085. package/tools/device.js +45 -0
  1086. package/tools/device.js.map +1 -0
  1087. package/tools/devreward.d.ts +15 -0
  1088. package/tools/devreward.d.ts.map +1 -0
  1089. package/tools/devreward.js +190 -0
  1090. package/tools/devreward.js.map +1 -0
  1091. package/tools/economy.d.ts +14 -0
  1092. package/tools/economy.d.ts.map +1 -0
  1093. package/tools/economy.js +172 -0
  1094. package/tools/economy.js.map +1 -0
  1095. package/tools/flowback.d.ts +14 -0
  1096. package/tools/flowback.d.ts.map +1 -0
  1097. package/tools/flowback.js +146 -0
  1098. package/tools/flowback.js.map +1 -0
  1099. package/tools/insurance.d.ts +13 -0
  1100. package/tools/insurance.d.ts.map +1 -0
  1101. package/tools/insurance.js +45 -0
  1102. package/tools/insurance.js.map +1 -0
  1103. package/tools/marketplace.d.ts +12 -0
  1104. package/tools/marketplace.d.ts.map +1 -0
  1105. package/tools/marketplace.js +124 -0
  1106. package/tools/marketplace.js.map +1 -0
  1107. package/tools/order.d.ts +12 -0
  1108. package/tools/order.d.ts.map +1 -0
  1109. package/tools/order.js +94 -0
  1110. package/tools/order.js.map +1 -0
  1111. package/tools/recovery.d.ts +14 -0
  1112. package/tools/recovery.d.ts.map +1 -0
  1113. package/tools/recovery.js +158 -0
  1114. package/tools/recovery.js.map +1 -0
  1115. package/tools/relay.d.ts +15 -0
  1116. package/tools/relay.d.ts.map +1 -0
  1117. package/tools/relay.js +152 -0
  1118. package/tools/relay.js.map +1 -0
  1119. package/tools/reputation.d.ts +20 -0
  1120. package/tools/reputation.d.ts.map +1 -0
  1121. package/tools/reputation.js +50 -0
  1122. package/tools/reputation.js.map +1 -0
  1123. package/tools/reputation_seller_credit.d.ts +16 -0
  1124. package/tools/reputation_seller_credit.d.ts.map +1 -0
  1125. package/tools/reputation_seller_credit.js +106 -0
  1126. package/tools/reputation_seller_credit.js.map +1 -0
  1127. package/tools/reward.d.ts +14 -0
  1128. package/tools/reward.d.ts.map +1 -0
  1129. package/tools/reward.js +76 -0
  1130. package/tools/reward.js.map +1 -0
  1131. package/tools/shop.d.ts +14 -0
  1132. package/tools/shop.d.ts.map +1 -0
  1133. package/tools/shop.js +95 -0
  1134. package/tools/shop.js.map +1 -0
  1135. package/tools/verification.d.ts +12 -0
  1136. package/tools/verification.d.ts.map +1 -0
  1137. package/tools/verification.js +89 -0
  1138. package/tools/verification.js.map +1 -0
  1139. package/types/store.d.ts +255 -0
  1140. package/types/store.d.ts.map +1 -0
  1141. package/types/store.js +19 -0
  1142. package/types/store.js.map +1 -0
  1143. package/utils/aes-gcm.d.ts +63 -0
  1144. package/utils/aes-gcm.d.ts.map +1 -0
  1145. package/utils/aes-gcm.js +179 -0
  1146. package/utils/aes-gcm.js.map +1 -0
  1147. package/utils/api-response.d.ts +51 -0
  1148. package/utils/api-response.d.ts.map +1 -0
  1149. package/utils/api-response.js +65 -0
  1150. package/utils/api-response.js.map +1 -0
  1151. package/utils/base32.d.ts +5 -0
  1152. package/utils/base32.d.ts.map +1 -0
  1153. package/utils/base32.js +20 -0
  1154. package/utils/base32.js.map +1 -0
  1155. package/utils/crypto.d.ts +77 -0
  1156. package/utils/crypto.d.ts.map +1 -0
  1157. package/utils/crypto.js +164 -0
  1158. package/utils/crypto.js.map +1 -0
  1159. package/utils/encryption.d.ts +81 -0
  1160. package/utils/encryption.d.ts.map +1 -0
  1161. package/utils/encryption.js +247 -0
  1162. package/utils/encryption.js.map +1 -0
  1163. package/utils/env.js +20 -0
  1164. package/utils/jwt.d.ts +110 -0
  1165. package/utils/jwt.d.ts.map +1 -0
  1166. package/utils/jwt.js +275 -0
  1167. package/utils/jwt.js.map +1 -0
  1168. package/utils/qrcode-reader.d.ts +22 -0
  1169. package/utils/qrcode-reader.d.ts.map +1 -0
  1170. package/utils/qrcode-reader.js +90 -0
  1171. package/utils/qrcode-reader.js.map +1 -0
  1172. package/utils/qrcode.d.ts +26 -0
  1173. package/utils/qrcode.d.ts.map +1 -0
  1174. package/utils/qrcode.js +92 -0
  1175. package/utils/qrcode.js.map +1 -0
  1176. package/utils/totp.d.ts +3 -0
  1177. package/utils/totp.d.ts.map +1 -0
  1178. package/utils/totp.js +58 -0
  1179. package/utils/totp.js.map +1 -0
  1180. package/utils/two-factor-auth.d.ts +16 -0
  1181. package/utils/two-factor-auth.d.ts.map +1 -0
  1182. package/utils/two-factor-auth.js +150 -0
  1183. package/utils/two-factor-auth.js.map +1 -0
  1184. package/verifyer/hsm.d.ts +70 -0
  1185. package/verifyer/hsm.d.ts.map +1 -0
  1186. package/verifyer/hsm.js +482 -0
  1187. package/verifyer/hsm.js.map +1 -0
  1188. package/verifyer/index.d.ts +81 -0
  1189. package/verifyer/index.d.ts.map +1 -0
  1190. package/verifyer/index.js +372 -0
  1191. package/verifyer/index.js.map +1 -0
  1192. package/ws/peer-monitor-broadcaster.d.ts +24 -0
  1193. package/ws/peer-monitor-broadcaster.d.ts.map +1 -0
  1194. package/ws/peer-monitor-broadcaster.js +56 -0
  1195. package/ws/peer-monitor-broadcaster.js.map +1 -0
@@ -0,0 +1,1657 @@
1
+ "use strict";
2
+ /**
3
+ * TrustCoin MCP Web Panel
4
+ *
5
+ * 内嵌在 MCP Server 中的轻量 Web 管理面板
6
+ * - 钱包创建/导入
7
+ * - 密码加密存储
8
+ * - 2FA/TOTP 绑定
9
+ * - 链状态仪表板
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.createWebPanel = createWebPanel;
49
+ const express_1 = __importDefault(require("express"));
50
+ const path_1 = require("path");
51
+ const crypto_1 = __importDefault(require("crypto"));
52
+ const fs_1 = __importDefault(require("fs"));
53
+ const path_2 = __importDefault(require("path"));
54
+ const amino_1 = require("@cosmjs/amino");
55
+ const stargate_1 = require("@cosmjs/stargate");
56
+ const base32_1 = require("../utils/base32");
57
+ const totp_1 = require("../utils/totp");
58
+ const runtime_data_1 = require("../core/runtime-data");
59
+ // ===================== Storage =====================
60
+ const PROFILES_FILE = runtime_data_1.runtimeDataFile('profiles.json');
61
+ const SESSIONS = new Map();
62
+ function loadProfiles() {
63
+ try {
64
+ return JSON.parse(fs_1.default.readFileSync(PROFILES_FILE, 'utf8'));
65
+ }
66
+ catch {
67
+ return [];
68
+ }
69
+ }
70
+ function saveProfiles(profiles) {
71
+ const dir = path_2.default.dirname(PROFILES_FILE);
72
+ if (!fs_1.default.existsSync(dir))
73
+ fs_1.default.mkdirSync(dir, { recursive: true });
74
+ fs_1.default.writeFileSync(PROFILES_FILE, JSON.stringify(profiles, null, 2));
75
+ }
76
+ // ===================== Crypto Helpers =====================
77
+ function deriveKey(password, salt) {
78
+ return crypto_1.default.pbkdf2Sync(password, salt, 100000, 32, 'sha256');
79
+ }
80
+ function encrypt(text, password) {
81
+ const salt = crypto_1.default.randomBytes(16).toString('hex');
82
+ const key = deriveKey(password, salt);
83
+ const iv = crypto_1.default.randomBytes(12);
84
+ const cipher = crypto_1.default.createCipheriv('aes-256-gcm', key, iv);
85
+ let encrypted = cipher.update(text, 'utf8', 'hex');
86
+ encrypted += cipher.final('hex');
87
+ const tag = cipher.getAuthTag();
88
+ return {
89
+ encrypted: encrypted + ':' + tag.toString('hex'),
90
+ iv: iv.toString('hex'),
91
+ salt,
92
+ };
93
+ }
94
+ function decrypt(encryptedText, iv, salt, password) {
95
+ const key = deriveKey(password, salt);
96
+ const parts = encryptedText.split(':');
97
+ const tag = parts.pop();
98
+ const data = parts.join(':');
99
+ const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'hex'));
100
+ decipher.setAuthTag(Buffer.from(tag, 'hex'));
101
+ let decrypted = decipher.update(data, 'hex', 'utf8');
102
+ decrypted += decipher.final('utf8');
103
+ return decrypted;
104
+ }
105
+ // ===================== Mnemonic Generation (BIP39-like) =====================
106
+ const WORDLIST = [
107
+ 'abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract',
108
+ 'absurd', 'abuse', 'access', 'accident', 'account', 'accuse', 'achieve', 'acid',
109
+ 'acoustic', 'acquire', 'across', 'act', 'action', 'actor', 'actress', 'actual',
110
+ 'adapt', 'add', 'addict', 'address', 'adjust', 'admit', 'adult', 'advance',
111
+ 'advice', 'aerobic', 'affair', 'afford', 'afraid', 'again', 'age', 'agent',
112
+ 'agree', 'ahead', 'aim', 'air', 'airport', 'aisle', 'alarm', 'album',
113
+ 'alcohol', 'alert', 'alien', 'all', 'alley', 'allow', 'almost', 'alone',
114
+ 'alpha', 'already', 'also', 'alter', 'always', 'amateur', 'amazing', 'among',
115
+ 'amount', 'amused', 'analyst', 'anchor', 'ancient', 'anger', 'angle', 'angry',
116
+ 'animal', 'ankle', 'announce', 'annual', 'another', 'answer', 'antenna', 'antique',
117
+ 'anxiety', 'any', 'apart', 'apology', 'appear', 'apple', 'approve', 'april',
118
+ 'arch', 'arctic', 'area', 'arena', 'argue', 'arm', 'armed', 'armor',
119
+ 'army', 'around', 'arrange', 'arrest', 'arrive', 'arrow', 'art', 'artefact',
120
+ 'artist', 'artwork', 'ask', 'aspect', 'assault', 'asset', 'assist', 'assume',
121
+ 'asthma', 'athlete', 'atom', 'attack', 'attend', 'attitude', 'attract', 'auction',
122
+ 'audit', 'august', 'aunt', 'author', 'auto', 'autumn', 'average', 'avocado',
123
+ 'avoid', 'awake', 'aware', 'awesome', 'awful', 'awkward', 'axis', 'baby',
124
+ 'bachelor', 'bacon', 'badge', 'bag', 'balance', 'balcony', 'ball', 'bamboo',
125
+ 'banana', 'banner', 'bar', 'barely', 'bargain', 'barrel', 'base', 'basic',
126
+ 'basket', 'battle', 'beach', 'bean', 'beauty', 'because', 'become', 'beef',
127
+ 'before', 'begin', 'behave', 'behind', 'believe', 'below', 'belt', 'bench',
128
+ 'benefit', 'best', 'betray', 'better', 'between', 'beyond', 'bicycle', 'bid',
129
+ // ... truncated for size, will use crypto random selection
130
+ ];
131
+ function generateMnemonic(wordCount = 24) {
132
+ // Use bip39 for proper BIP39 checksum
133
+ const bip39 = require('bip39');
134
+ return bip39.generateMnemonic(wordCount === 24 ? 256 : 128);
135
+ }
136
+ // ===================== TOTP Helpers =====================
137
+ function generateTotpSecret() {
138
+ return (0, base32_1.encodeBase32)(crypto_1.default.randomBytes(20));
139
+ }
140
+ function generateTotpUri(secret, address) {
141
+ return `otpauth://totp/TrustCoin:${address}?secret=${secret}&issuer=TrustCoin&algorithm=SHA1&digits=6&period=30`;
142
+ }
143
+ // ===================== Auth Middleware =====================
144
+ function authMiddleware(req, res, next) {
145
+ const token = req.headers.authorization?.replace('Bearer ', '');
146
+ if (!token) {
147
+ res.status(401).json({ error: '未登录' });
148
+ return;
149
+ }
150
+ const session = SESSIONS.get(token);
151
+ if (!session || session.expiresAt < Date.now()) {
152
+ SESSIONS.delete(token);
153
+ res.status(401).json({ error: '会话过期' });
154
+ return;
155
+ }
156
+ const profiles = loadProfiles();
157
+ const profile = profiles.find(p => p.id === session.walletId);
158
+ if (!profile) {
159
+ res.status(401).json({ error: '钱包不存在' });
160
+ return;
161
+ }
162
+ req.profile = profile;
163
+ req.session = session;
164
+ next();
165
+ }
166
+ // ===================== Web Panel HTML =====================
167
+ function getPanelHtml() {
168
+ return `<!DOCTYPE html>
169
+ <html lang="zh-CN">
170
+ <head>
171
+ <meta charset="utf-8">
172
+ <meta name="viewport" content="width=device-width, initial-scale=1">
173
+ <title>TrustCoin</title>
174
+ <style>
175
+ :root {
176
+ --bg-primary: #09090b;
177
+ --bg-secondary: #18181b;
178
+ --bg-tertiary: #27272a;
179
+ --border: #3f3f46;
180
+ --border-hover: #52525b;
181
+ --text-primary: #fafafa;
182
+ --text-secondary: #a1a1aa;
183
+ --text-muted: #71717a;
184
+ --accent: #8b5cf6;
185
+ --accent-hover: #7c3aed;
186
+ --accent-soft: rgba(139,92,246,0.15);
187
+ --success: #22c55e;
188
+ --success-bg: rgba(34,197,94,0.1);
189
+ --error: #ef4444;
190
+ --error-bg: rgba(239,68,68,0.1);
191
+ --warning: #f59e0b;
192
+ --warning-bg: rgba(245,158,11,0.1);
193
+ --radius: 8px;
194
+ --radius-lg: 12px;
195
+ }
196
+ * { margin:0; padding:0; box-sizing:border-box; }
197
+ body {
198
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', 'Noto Sans SC', 'Noto Sans JP', sans-serif;
199
+ background: var(--bg-primary); color: var(--text-primary);
200
+ min-height: 100vh; line-height: 1.5; -webkit-font-smoothing: antialiased;
201
+ }
202
+ .shell { max-width:480px; margin:0 auto; padding:24px 16px; min-height:100vh; }
203
+ .header {
204
+ display:flex; align-items:center; gap:12px; padding:16px 0 24px;
205
+ border-bottom:1px solid var(--border); margin-bottom:24px;
206
+ }
207
+ .header-icon {
208
+ width:40px; height:40px; background:var(--accent); border-radius:var(--radius);
209
+ display:flex; align-items:center; justify-content:center; flex-shrink:0;
210
+ }
211
+ .header-icon svg { width:22px; height:22px; color:white; }
212
+ .header-text { flex:1; }
213
+ .header-text h1 { font-size:18px; font-weight:600; letter-spacing:-0.01em; }
214
+ .header-text p { font-size:13px; color:var(--text-muted); margin-top:2px; }
215
+ /* Language Switcher */
216
+ .lang-switch {
217
+ display:flex; gap:2px; background:var(--bg-secondary); border:1px solid var(--border);
218
+ border-radius:6px; padding:2px;
219
+ }
220
+ .lang-btn {
221
+ padding:4px 10px; border:none; background:none; color:var(--text-muted);
222
+ font-size:11px; font-weight:500; cursor:pointer; border-radius:4px; transition:all .15s;
223
+ }
224
+ .lang-btn:hover { color:var(--text-secondary); }
225
+ .lang-btn.active { background:var(--bg-tertiary); color:var(--text-primary); }
226
+
227
+ .status-bar { display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin-bottom:24px; }
228
+ .stat-card { background:var(--bg-secondary); border:1px solid var(--border); border-radius:var(--radius); padding:12px; }
229
+ .stat-card .value { font-size:16px; font-weight:600; color:var(--text-primary); }
230
+ .stat-card .label { font-size:11px; color:var(--text-muted); margin-top:2px; text-transform:uppercase; letter-spacing:.05em; }
231
+
232
+ .card { background:var(--bg-secondary); border:1px solid var(--border); border-radius:var(--radius-lg); padding:20px; margin-bottom:16px; }
233
+ .card-title { font-size:14px; font-weight:600; color:var(--text-primary); margin-bottom:16px; display:flex; align-items:center; gap:8px; }
234
+ .card-title svg { width:16px; height:16px; color:var(--text-muted); }
235
+
236
+ .tabs {
237
+ display:flex; gap:2px; background:var(--bg-secondary); border:1px solid var(--border);
238
+ border-radius:var(--radius); padding:3px; margin-bottom:24px;
239
+ }
240
+ .tab-btn {
241
+ flex:1; padding:8px 12px; border:none; background:none; color:var(--text-muted);
242
+ font-size:13px; font-weight:500; cursor:pointer; border-radius:6px; transition:all .15s;
243
+ }
244
+ .tab-btn:hover { color:var(--text-secondary); }
245
+ .tab-btn.active { background:var(--bg-tertiary); color:var(--text-primary); }
246
+ .tab-content { display:none; }
247
+ .tab-content.active { display:block; }
248
+
249
+ .field { margin-bottom:16px; }
250
+ .field-label { display:block; font-size:13px; font-weight:500; color:var(--text-secondary); margin-bottom:6px; }
251
+ .input {
252
+ width:100%; padding:9px 12px; background:var(--bg-primary); border:1px solid var(--border);
253
+ border-radius:var(--radius); color:var(--text-primary); font-size:14px; transition:border-color .15s; outline:none;
254
+ }
255
+ .input:focus { border-color:var(--accent); }
256
+ .input::placeholder { color:var(--text-muted); }
257
+ .input-totp { font-size:20px; letter-spacing:8px; text-align:center; font-family:'SF Mono','Cascadia Code',monospace; }
258
+
259
+ .btn {
260
+ display:inline-flex; align-items:center; justify-content:center; gap:6px;
261
+ padding:9px 16px; border:1px solid var(--border); border-radius:var(--radius);
262
+ background:var(--bg-secondary); color:var(--text-primary); font-size:13px; font-weight:500;
263
+ cursor:pointer; transition:all .15s; white-space:nowrap;
264
+ }
265
+ .btn:hover { background:var(--bg-tertiary); border-color:var(--border-hover); }
266
+ .btn svg { width:14px; height:14px; }
267
+ .btn-primary { background:var(--accent); border-color:var(--accent); color:white; }
268
+ .btn-primary:hover { background:var(--accent-hover); border-color:var(--accent-hover); }
269
+ .btn-danger { border-color:var(--error); color:var(--error); }
270
+ .btn-danger:hover { background:var(--error-bg); }
271
+ .btn-full { width:100%; }
272
+ .btn-sm { padding:6px 12px; font-size:12px; }
273
+ .btn-ghost { border:none; background:none; color:var(--text-muted); }
274
+ .btn-ghost:hover { color:var(--text-primary); background:var(--bg-tertiary); }
275
+
276
+ .mnemonic-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:4px; margin:12px 0; }
277
+ .mnemonic-word {
278
+ background:var(--bg-primary); border:1px solid var(--border); border-radius:6px;
279
+ padding:6px 4px; font-size:12px; font-family:'SF Mono','Cascadia Code',monospace;
280
+ color:var(--accent); text-align:center; user-select:all;
281
+ }
282
+ .mnemonic-word .num { color:var(--text-muted); font-size:9px; margin-right:2px; }
283
+
284
+ .alert {
285
+ padding:12px; border-radius:var(--radius); font-size:13px; margin:12px 0;
286
+ display:flex; align-items:flex-start; gap:8px;
287
+ }
288
+ .alert svg { width:16px; height:16px; flex-shrink:0; margin-top:1px; }
289
+ .alert-warning { background:var(--warning-bg); border:1px solid rgba(245,158,11,.2); color:var(--warning); }
290
+ .alert-success { background:var(--success-bg); border:1px solid rgba(34,197,94,.2); color:var(--success); }
291
+ .alert-error { background:var(--error-bg); border:1px solid rgba(239,68,68,.2); color:var(--error); }
292
+
293
+ .info-row {
294
+ display:flex; justify-content:space-between; align-items:center;
295
+ padding:10px 0; border-bottom:1px solid var(--border); font-size:13px;
296
+ }
297
+ .info-row:last-child { border-bottom:none; }
298
+ .info-row .key { color:var(--text-muted); }
299
+ .info-row .value { color:var(--text-primary); font-family:'SF Mono','Cascadia Code',monospace; font-size:12px; }
300
+
301
+ .badge { display:inline-flex; align-items:center; padding:2px 8px; border-radius:99px; font-size:11px; font-weight:500; }
302
+ .badge-success { background:var(--success-bg); color:var(--success); }
303
+ .badge-warning { background:var(--warning-bg); color:var(--warning); }
304
+
305
+ .balance { font-size:32px; font-weight:700; color:var(--text-primary); letter-spacing:-0.02em; margin:4px 0 16px; }
306
+ .balance .unit { font-size:16px; font-weight:400; color:var(--text-muted); margin-left:4px; }
307
+
308
+ .qr-container { text-align:center; margin:16px 0; }
309
+ .qr-container img { border-radius:var(--radius); border:1px solid var(--border); }
310
+ .qr-hint { font-size:12px; color:var(--text-muted); margin-top:8px; }
311
+ .qr-key {
312
+ font-family:'SF Mono','Cascadia Code',monospace; font-size:12px; color:var(--accent);
313
+ word-break:break-all; background:var(--bg-primary); padding:8px 12px;
314
+ border-radius:6px; border:1px solid var(--border); margin-top:8px; text-align:center;
315
+ }
316
+
317
+ .divider { height:1px; background:var(--border); margin:20px 0; }
318
+ .dash-nav {
319
+ display:flex; align-items:center; gap:2px; background:var(--bg-secondary);
320
+ border:1px solid var(--border); border-radius:var(--radius); padding:3px; margin-bottom:24px;
321
+ }
322
+ .dash-nav .tab-btn { flex:none; padding:8px 14px; }
323
+ .dash-nav .spacer { flex:1; }
324
+ .btn-group { display:flex; gap:8px; margin-top:16px; }
325
+ pre {
326
+ background:var(--bg-primary); border:1px solid var(--border); border-radius:var(--radius);
327
+ padding:12px; font-size:12px; overflow-x:auto; color:var(--text-secondary);
328
+ font-family:'SF Mono','Cascadia Code',monospace;
329
+ }
330
+ </style>
331
+ </head>
332
+ <body>
333
+ <div class="shell">
334
+ <div class="header">
335
+ <div class="header-icon">
336
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v12M6 12h12"/></svg>
337
+ </div>
338
+ <div class="header-text">
339
+ <h1>TrustCoin</h1>
340
+ <p data-i18n="subtitle">Decentralized E-Commerce Protocol</p>
341
+ </div>
342
+ <div class="lang-switch">
343
+ <button class="lang-btn active" onclick="setLang('zh')">中文</button>
344
+ <button class="lang-btn" onclick="setLang('en')">EN</button>
345
+ <button class="lang-btn" onclick="setLang('ja')">日本語</button>
346
+ </div>
347
+ </div>
348
+
349
+ <div class="status-bar" id="chainStatus">
350
+ <div class="stat-card"><div class="value" id="blockHeight">--</div><div class="label" data-i18n="height">Height</div></div>
351
+ <div class="stat-card"><div class="value" id="chainId">--</div><div class="label" data-i18n="chain">Chain</div></div>
352
+ <div class="stat-card"><div class="value" id="syncStatus">--</div><div class="label" data-i18n="status">Status</div></div>
353
+ </div>
354
+
355
+ <div id="authSection">
356
+ <div class="tabs">
357
+ <button class="tab-btn active" onclick="showTab('login',this)" data-i18n="signIn">Sign In</button>
358
+ <button class="tab-btn" onclick="showTab('create',this)" data-i18n="create">Create</button>
359
+ <button class="tab-btn" onclick="showTab('import',this)" data-i18n="import">Import</button>
360
+ </div>
361
+
362
+ <div id="tab-login" class="tab-content active">
363
+ <div class="card">
364
+ <div class="card-title">
365
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
366
+ <span data-i18n="signIn">Sign In</span>
367
+ </div>
368
+ <div class="field">
369
+ <label class="field-label" data-i18n="password">Password</label>
370
+ <input type="password" class="input" id="loginPassword" data-i18n-placeholder="enterPassword">
371
+ </div>
372
+ <div class="field" id="totpGroup" style="display:none">
373
+ <label class="field-label" data-i18n="twoFACode">2FA Code</label>
374
+ <input type="text" class="input input-totp" id="loginTotp" placeholder="000000" maxlength="6">
375
+ </div>
376
+ <button class="btn btn-primary btn-full" onclick="login()" data-i18n="signIn">Sign In</button>
377
+ <div id="loginMsg"></div>
378
+ </div>
379
+ </div>
380
+
381
+ <div id="tab-create" class="tab-content">
382
+ <div class="card">
383
+ <div class="card-title">
384
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
385
+ <span data-i18n="createWallet">Create Wallet</span>
386
+ </div>
387
+ <div class="alert alert-warning">
388
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
389
+ <span data-i18n="warningPhrase">Write down your recovery phrase on paper. It cannot be recovered if lost.</span>
390
+ </div>
391
+ <div class="mnemonic-grid" id="mnemonicDisplay"></div>
392
+ <div class="btn-group">
393
+ <button class="btn btn-sm" onclick="regenerateMnemonic()">
394
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
395
+ <span data-i18n="regenerate">Regenerate</span>
396
+ </button>
397
+ </div>
398
+ <div class="divider"></div>
399
+ <div class="field">
400
+ <label class="field-label" data-i18n="passwordMin">Password (min 8 chars)</label>
401
+ <input type="password" class="input" id="createPassword" data-i18n-placeholder="setPassword">
402
+ </div>
403
+ <div class="field">
404
+ <label class="field-label" data-i18n="confirmPassword">Confirm Password</label>
405
+ <input type="password" class="input" id="createPassword2" data-i18n-placeholder="confirmPwd">
406
+ </div>
407
+ <div class="field">
408
+ <label class="field-label" data-i18n="displayName">Display Name (optional)</label>
409
+ <input type="text" class="input" id="createMoniker" data-i18n-placeholder="yourName">
410
+ </div>
411
+ <button class="btn btn-primary btn-full" onclick="createWallet()" data-i18n="createWallet">Create Wallet</button>
412
+ <div id="createMsg"></div>
413
+ </div>
414
+ </div>
415
+
416
+ <div id="tab-import" class="tab-content">
417
+ <div class="card">
418
+ <div class="card-title">
419
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
420
+ <span data-i18n="importWallet">Import Wallet</span>
421
+ </div>
422
+ <div class="field">
423
+ <label class="field-label" data-i18n="recoveryPhrase">Recovery Phrase</label>
424
+ <input type="text" class="input" id="importMnemonic" data-i18n-placeholder="phrasePlaceholder">
425
+ </div>
426
+ <div class="field">
427
+ <label class="field-label" data-i18n="password">Password</label>
428
+ <input type="password" class="input" id="importPassword" data-i18n-placeholder="setPassword">
429
+ </div>
430
+ <button class="btn btn-primary btn-full" onclick="importWallet()" data-i18n="import">Import</button>
431
+ <div id="importMsg"></div>
432
+ </div>
433
+ </div>
434
+ </div>
435
+
436
+ <div id="dashboardSection" style="display:none">
437
+ <div class="dash-nav">
438
+ <button class="tab-btn active" onclick="showDashTab('overview',this)" data-i18n="overview">Overview</button>
439
+ <button class="tab-btn" onclick="showDashTab('security',this)" data-i18n="security">Security</button>
440
+ <button class="tab-btn" onclick="showDashTab('2fa',this)" data-i18n="tab2FA">2FA</button>
441
+ <span class="spacer"></span>
442
+ <button class="tab-btn" onclick="logout()" style="color:var(--error)" data-i18n="signOut">Sign Out</button>
443
+ </div>
444
+
445
+ <div id="dash-overview" class="tab-content active">
446
+ <div class="card">
447
+ <div class="balance" id="balanceDisplay">--<span class="unit">TCT</span></div>
448
+ <div class="info-row"><span class="key" data-i18n="address">Address</span><span class="value" id="walletAddr"></span></div>
449
+ <div class="info-row"><span class="key" data-i18n="name">Name</span><span class="value" id="walletMoniker">--</span></div>
450
+ <div class="info-row"><span class="key">2FA</span><span class="value" id="wallet2fa"></span></div>
451
+ <div class="info-row"><span class="key" data-i18n="created">Created</span><span class="value" id="walletCreated">--</span></div>
452
+ </div>
453
+ <div class="card">
454
+ <div class="card-title">
455
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
456
+ <span data-i18n="chainStatus">Chain Status</span>
457
+ </div>
458
+ <div id="onchainData"><pre>Loading...</pre></div>
459
+ </div>
460
+ </div>
461
+
462
+ <div id="dash-security" class="tab-content">
463
+ <div class="card">
464
+ <div class="card-title">
465
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
466
+ <span data-i18n="changePassword">Change Password</span>
467
+ </div>
468
+ <div class="field">
469
+ <label class="field-label" data-i18n="currentPassword">Current Password</label>
470
+ <input type="password" class="input" id="oldPassword">
471
+ </div>
472
+ <div class="field">
473
+ <label class="field-label" data-i18n="newPassword">New Password</label>
474
+ <input type="password" class="input" id="newPassword">
475
+ </div>
476
+ <button class="btn btn-primary btn-full" onclick="changePassword()" data-i18n="updatePassword">Update Password</button>
477
+ <div id="pwdMsg"></div>
478
+ </div>
479
+ <div class="card">
480
+ <div class="card-title">
481
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
482
+ <span data-i18n="exportPhrase">Export Recovery Phrase</span>
483
+ </div>
484
+ <div class="alert alert-warning">
485
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
486
+ <span data-i18n="warningExport">Never save on a connected device. Write on paper only.</span>
487
+ </div>
488
+ <div class="field">
489
+ <label class="field-label" data-i18n="verifyPassword">Verify Password</label>
490
+ <input type="password" class="input" id="exportPassword">
491
+ </div>
492
+ <button class="btn btn-danger btn-full" onclick="exportMnemonic()" data-i18n="showPhrase">Show Recovery Phrase</button>
493
+ <div id="exportMsg"></div>
494
+ </div>
495
+ </div>
496
+
497
+ <div id="dash-2fa" class="tab-content">
498
+ <div class="card">
499
+ <div class="card-title">
500
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
501
+ <span data-i18n="twoFactorAuth">Two-Factor Authentication</span>
502
+ </div>
503
+ <div id="totpStep1">
504
+ <p style="margin:12px 0;font-size:13px;color:var(--text-muted)" data-i18n="twoFADesc">Require a verification code from your authenticator app each time you sign in.</p>
505
+ <div class="field">
506
+ <label class="field-label" data-i18n="verifyWalletPwd">Verify wallet password first</label>
507
+ <input type="password" class="input" id="totpPassword" data-i18n-placeholder="walletPassword">
508
+ </div>
509
+ <button class="btn btn-primary btn-full" onclick="start2faSetup()" data-i18n="getQRCode">Get QR Code</button>
510
+ <div id="totpStep1Msg"></div>
511
+ </div>
512
+ <div id="totpStep2" style="display:none">
513
+ <p style="margin:12px 0;font-size:13px;color:var(--text-muted)" data-i18n="scanQRDesc">Scan with Google Authenticator or similar app:</p>
514
+ <div class="qr-container"><img id="totpQrImg" style="max-width:220px" /></div>
515
+ <div class="qr-hint" data-i18n="cantScan">Can't scan? Enter this key manually:</div>
516
+ <div class="qr-key" id="totpManualKey"></div>
517
+ <div class="alert alert-warning" style="margin-top:16px">
518
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
519
+ <span data-i18n="enterCodeDesc">Enter the 6-digit code currently showing in your app</span>
520
+ </div>
521
+ <div class="field">
522
+ <label class="field-label" data-i18n="verificationCode">Verification Code</label>
523
+ <input type="text" class="input input-totp" id="totpVerifyCode" placeholder="000000" maxlength="6">
524
+ </div>
525
+ <div class="btn-group">
526
+ <button class="btn btn-primary" onclick="confirm2fa()" data-i18n="confirm">Confirm</button>
527
+ <button class="btn" onclick="cancel2fa()" data-i18n="cancel">Cancel</button>
528
+ </div>
529
+ <div id="totpStep2Msg"></div>
530
+ </div>
531
+ <div id="totpEnabled" style="display:none">
532
+ <div class="alert alert-success">
533
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
534
+ <span data-i18n="twoFAEnabled">2FA is enabled. Sign-in requires password + verification code.</span>
535
+ </div>
536
+ <div class="divider"></div>
537
+ <div class="field">
538
+ <label class="field-label" data-i18n="enterCodeDisable">Enter current 2FA code to disable</label>
539
+ <input type="text" class="input input-totp" id="disableTotp" placeholder="000000" maxlength="6">
540
+ </div>
541
+ <button class="btn btn-danger btn-sm" onclick="disable2fa()" data-i18n="disable2FA">Disable 2FA</button>
542
+ <div id="totpDisableMsg"></div>
543
+ </div>
544
+ </div>
545
+ </div>
546
+ </div>
547
+ </div>
548
+
549
+ <script>
550
+ // ===================== i18n =====================
551
+ const I18N = {
552
+ zh: {
553
+ subtitle: '去中心化电商协议',
554
+ height: '高度', chain: '链', status: '状态',
555
+ signIn: '登录', create: '创建', import: '导入',
556
+ password: '密码', enterPassword: '输入钱包密码',
557
+ twoFACode: '2FA验证码',
558
+ createWallet: '创建钱包',
559
+ warningPhrase: '请将助记词抄写在纸上并妥善保管,丢失将无法恢复。',
560
+ regenerate: '重新生成',
561
+ passwordMin: '密码(至少8位)', setPassword: '设置密码',
562
+ confirmPwd: '再次输入密码', confirmPassword: '确认密码',
563
+ displayName: '显示名称(可选)', yourName: '你的名称',
564
+ importWallet: '导入钱包',
565
+ recoveryPhrase: '助记词', phrasePlaceholder: 'word1 word2 word3 ... word24',
566
+ overview: '总览', security: '安全', tab2FA: '2FA', signOut: '退出',
567
+ address: '地址', name: '名称', created: '创建时间',
568
+ chainStatus: '链状态',
569
+ changePassword: '修改密码', currentPassword: '当前密码', newPassword: '新密码', updatePassword: '更新密码',
570
+ exportPhrase: '导出助记词', warningExport: '切勿在联网设备上保存,只写在纸上。', verifyPassword: '验证密码', showPhrase: '显示助记词',
571
+ twoFactorAuth: '两步验证',
572
+ twoFADesc: '启用后每次登录需要密码 + 手机验证码,大幅提升安全性。',
573
+ verifyWalletPwd: '请先输入钱包密码验证身份', walletPassword: '钱包密码',
574
+ getQRCode: '获取二维码',
575
+ scanQRDesc: '使用 Google Authenticator 或类似App扫描下方二维码:',
576
+ cantScan: '无法扫码?手动输入密钥:',
577
+ enterCodeDesc: '输入App上当前显示的6位验证码',
578
+ verificationCode: '验证码', confirm: '确认', cancel: '取消',
579
+ twoFAEnabled: '2FA已启用。登录需要密码 + 验证码。',
580
+ enterCodeDisable: '输入当前2FA验证码以禁用', disable2FA: '禁用2FA',
581
+ enabled: '已启用', disabled: '未启用',
582
+ errPasswordMin: '密码至少8位', errPasswordMatch: '两次密码不一致', errEnterPhrase: '请输入助记词',
583
+ errEnterPassword: '请输入密码', errEnterCode: '请输入6位验证码',
584
+ okWalletCreated: '钱包创建成功', okImported: '导入成功', okPasswordUpdated: '密码修改成功',
585
+ ok2FAEnabled: '2FA绑定成功', ok2FADisabled: '2FA已禁用',
586
+ },
587
+ en: {
588
+ subtitle: 'Decentralized E-Commerce Protocol',
589
+ height: 'Height', chain: 'Chain', status: 'Status',
590
+ signIn: 'Sign In', create: 'Create', import: 'Import',
591
+ password: 'Password', enterPassword: 'Enter wallet password',
592
+ twoFACode: '2FA Code',
593
+ createWallet: 'Create Wallet',
594
+ warningPhrase: 'Write down your recovery phrase on paper. It cannot be recovered if lost.',
595
+ regenerate: 'Regenerate',
596
+ passwordMin: 'Password (min 8 chars)', setPassword: 'Set password',
597
+ confirmPwd: 'Confirm password', confirmPassword: 'Confirm Password',
598
+ displayName: 'Display Name (optional)', yourName: 'Your name',
599
+ importWallet: 'Import Wallet',
600
+ recoveryPhrase: 'Recovery Phrase', phrasePlaceholder: 'word1 word2 word3 ... word24',
601
+ overview: 'Overview', security: 'Security', tab2FA: '2FA', signOut: 'Sign Out',
602
+ address: 'Address', name: 'Name', created: 'Created',
603
+ chainStatus: 'Chain Status',
604
+ changePassword: 'Change Password', currentPassword: 'Current Password', newPassword: 'New Password', updatePassword: 'Update Password',
605
+ exportPhrase: 'Export Recovery Phrase', warningExport: 'Never save on a connected device. Write on paper only.', verifyPassword: 'Verify Password', showPhrase: 'Show Recovery Phrase',
606
+ twoFactorAuth: 'Two-Factor Authentication',
607
+ twoFADesc: 'Require a verification code from your authenticator app each time you sign in.',
608
+ verifyWalletPwd: 'Verify wallet password first', walletPassword: 'Wallet password',
609
+ getQRCode: 'Get QR Code',
610
+ scanQRDesc: 'Scan with Google Authenticator or similar app:',
611
+ cantScan: "Can't scan? Enter this key manually:",
612
+ enterCodeDesc: 'Enter the 6-digit code currently showing in your app',
613
+ verificationCode: 'Verification Code', confirm: 'Confirm', cancel: 'Cancel',
614
+ twoFAEnabled: '2FA is enabled. Sign-in requires password + verification code.',
615
+ enterCodeDisable: 'Enter current 2FA code to disable', disable2FA: 'Disable 2FA',
616
+ enabled: 'Enabled', disabled: 'Disabled',
617
+ errPasswordMin: 'Password must be at least 8 characters', errPasswordMatch: 'Passwords do not match', errEnterPhrase: 'Enter recovery phrase',
618
+ errEnterPassword: 'Enter password', errEnterCode: 'Enter 6-digit code',
619
+ okWalletCreated: 'Wallet created', okImported: 'Imported', okPasswordUpdated: 'Password updated',
620
+ ok2FAEnabled: '2FA enabled', ok2FADisabled: '2FA disabled',
621
+ },
622
+ ja: {
623
+ subtitle: '分散型ECプロトコル',
624
+ height: '高さ', chain: 'チェーン', status: '状態',
625
+ signIn: 'ログイン', create: '作成', import: 'インポート',
626
+ password: 'パスワード', enterPassword: 'ウォレットパスワードを入力',
627
+ twoFACode: '2FAコード',
628
+ createWallet: 'ウォレット作成',
629
+ warningPhrase: 'リカバリーフレーズは紙に書き留めてください。紛失すると復元できません。',
630
+ regenerate: '再生成',
631
+ passwordMin: 'パスワード(8文字以上)', setPassword: 'パスワードを設定',
632
+ confirmPwd: 'パスワード確認', confirmPassword: 'パスワード確認',
633
+ displayName: '表示名(任意)', yourName: '名前',
634
+ importWallet: 'ウォレットインポート',
635
+ recoveryPhrase: 'リカバリーフレーズ', phrasePlaceholder: 'word1 word2 word3 ... word24',
636
+ overview: '概要', security: 'セキュリティ', tab2FA: '2FA', signOut: 'ログアウト',
637
+ address: 'アドレス', name: '名前', created: '作成日時',
638
+ chainStatus: 'チェーン状態',
639
+ changePassword: 'パスワード変更', currentPassword: '現在のパスワード', newPassword: '新しいパスワード', updatePassword: 'パスワード更新',
640
+ exportPhrase: 'リカバリーフレーズ書き出し', warningExport: '接続されたデバイスに保存しないでください。紙にのみ書き留めてください。', verifyPassword: 'パスワード確認', showPhrase: 'リカバリーフレーズを表示',
641
+ twoFactorAuth: '二要素認証',
642
+ twoFADesc: 'ログイン時にパスワード+認証アプリのコードが必要になり、安全性が大幅に向上します。',
643
+ verifyWalletPwd: 'ウォレットパスワードで本人確認', walletPassword: 'ウォレットパスワード',
644
+ getQRCode: 'QRコードを取得',
645
+ scanQRDesc: 'Google Authenticator または類似アプリでスキャン:',
646
+ cantScan: 'スキャンできない場合、このキーを手動入力:',
647
+ enterCodeDesc: 'アプリに表示されている6桁のコードを入力',
648
+ verificationCode: '確認コード', confirm: '確認', cancel: 'キャンセル',
649
+ twoFAEnabled: '2FA有効。ログインにパスワード+確認コードが必要です。',
650
+ enterCodeDisable: '現在の2FAコードを入力して無効化', disable2FA: '2FA無効化',
651
+ enabled: '有効', disabled: '無効',
652
+ errPasswordMin: 'パスワードは8文字以上必要です', errPasswordMatch: 'パスワードが一致しません', errEnterPhrase: 'リカバリーフレーズを入力',
653
+ errEnterPassword: 'パスワードを入力', errEnterCode: '6桁のコードを入力',
654
+ okWalletCreated: 'ウォレット作成完了', okImported: 'インポート完了', okPasswordUpdated: 'パスワード更新完了',
655
+ ok2FAEnabled: '2FA有効化完了', ok2FADisabled: '2FA無効化完了',
656
+ }
657
+ };
658
+
659
+ let lang = localStorage.getItem('tc-lang') || 'zh';
660
+ function t(key) { return I18N[lang]?.[key] || I18N.en[key] || key; }
661
+ function setLang(l) {
662
+ lang = l;
663
+ localStorage.setItem('tc-lang', l);
664
+ document.querySelectorAll('.lang-btn').forEach(b => b.classList.toggle('active', b.textContent.trim() === {zh:'中文',en:'EN',ja:'日本語'}[l]));
665
+ document.querySelectorAll('[data-i18n]').forEach(el => { el.textContent = t(el.dataset.i18n); });
666
+ document.querySelectorAll('[data-i18n-placeholder]').forEach(el => { el.placeholder = t(el.dataset.i18nPlaceholder); });
667
+ }
668
+
669
+ let currentMnemonic = '';
670
+ let authToken = '';
671
+ const API = window.location.origin + '/api';
672
+
673
+ function showTab(name, el) {
674
+ document.querySelectorAll('#authSection .tab-content').forEach(t => t.classList.remove('active'));
675
+ document.querySelectorAll('#authSection .tab-btn').forEach(b => b.classList.remove('active'));
676
+ document.getElementById('tab-' + name).classList.add('active');
677
+ el.classList.add('active');
678
+ }
679
+ function showDashTab(name, el) {
680
+ document.querySelectorAll('#dashboardSection .tab-content').forEach(t => t.classList.remove('active'));
681
+ document.querySelectorAll('#dashboardSection .tab-btn').forEach(b => b.classList.remove('active'));
682
+ document.getElementById('dash-' + name).classList.add('active');
683
+ el.classList.add('active');
684
+ }
685
+
686
+ async function init() {
687
+ setLang(lang);
688
+ await refreshChainStatus();
689
+ regenerateMnemonic();
690
+ const resp = await fetch(API + '/has-wallet');
691
+ const data = await resp.json();
692
+ if (data.hasWallet && data.totpEnabled) document.getElementById('totpGroup').style.display = '';
693
+ }
694
+
695
+ async function refreshChainStatus() {
696
+ try {
697
+ const resp = await fetch(API + '/chain-status');
698
+ const data = await resp.json();
699
+ document.getElementById('blockHeight').textContent = data.block_height?.toLocaleString() || '--';
700
+ document.getElementById('chainId').textContent = data.chain_id || '--';
701
+ document.getElementById('syncStatus').textContent = data.catching_up ? 'Syncing' : 'Active';
702
+ } catch {}
703
+ }
704
+
705
+ async function regenerateMnemonic() {
706
+ const resp = await fetch(API + '/generate-mnemonic');
707
+ const data = await resp.json();
708
+ currentMnemonic = data.mnemonic;
709
+ const words = currentMnemonic.split(' ');
710
+ document.getElementById('mnemonicDisplay').innerHTML = words.map((w,i) =>
711
+ '<div class="mnemonic-word"><span class="num">' + (i+1) + '</span>' + w + '</div>'
712
+ ).join('');
713
+ }
714
+
715
+ async function createWallet() {
716
+ const pwd = document.getElementById('createPassword').value;
717
+ const pwd2 = document.getElementById('createPassword2').value;
718
+ const moniker = document.getElementById('createMoniker').value;
719
+ if (pwd.length < 8) return showMsg('createMsg','error', t('errPasswordMin'));
720
+ if (pwd !== pwd2) return showMsg('createMsg','error', t('errPasswordMatch'));
721
+ if (!currentMnemonic) return;
722
+ const resp = await fetch(API+'/create-wallet',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:pwd,mnemonic:currentMnemonic,moniker})});
723
+ const data = await resp.json();
724
+ if (data.error) return showMsg('createMsg','error',data.error);
725
+ showMsg('createMsg','success',t('okWalletCreated')+': '+data.address);
726
+ currentMnemonic = '';
727
+ setTimeout(()=>loginWithPassword(pwd),500);
728
+ }
729
+
730
+ async function importWallet() {
731
+ const mnemonic = document.getElementById('importMnemonic').value.trim();
732
+ const pwd = document.getElementById('importPassword').value;
733
+ if (!mnemonic) return showMsg('importMsg','error',t('errEnterPhrase'));
734
+ if (pwd.length < 8) return showMsg('importMsg','error',t('errPasswordMin'));
735
+ const resp = await fetch(API+'/create-wallet',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:pwd,mnemonic,moniker:''})});
736
+ const data = await resp.json();
737
+ if (data.error) return showMsg('importMsg','error',data.error);
738
+ showMsg('importMsg','success',t('okImported')+': '+data.address);
739
+ setTimeout(()=>loginWithPassword(pwd),500);
740
+ }
741
+
742
+ async function login() {
743
+ const pwd = document.getElementById('loginPassword').value;
744
+ const totp = document.getElementById('loginTotp').value;
745
+ if (!pwd) return showMsg('loginMsg','error',t('errEnterPassword'));
746
+ const resp = await fetch(API+'/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:pwd,totp:totp||undefined})});
747
+ const data = await resp.json();
748
+ if (data.error) return showMsg('loginMsg','error',data.error);
749
+ authToken = data.token;
750
+ showDashboard();
751
+ }
752
+
753
+ async function loginWithPassword(pwd) {
754
+ const resp = await fetch(API+'/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:pwd})});
755
+ const data = await resp.json();
756
+ if (data.token) { authToken = data.token; showDashboard(); }
757
+ }
758
+
759
+ function logout() {
760
+ authToken = '';
761
+ document.getElementById('authSection').style.display = '';
762
+ document.getElementById('dashboardSection').style.display = 'none';
763
+ }
764
+
765
+ async function showDashboard() {
766
+ document.getElementById('authSection').style.display = 'none';
767
+ document.getElementById('dashboardSection').style.display = '';
768
+ const resp = await fetch(API+'/profile',{headers:{'Authorization':'Bearer '+authToken}});
769
+ const data = await resp.json();
770
+ if (data.error) return logout();
771
+ document.getElementById('walletAddr').textContent = data.address;
772
+ document.getElementById('walletMoniker').textContent = data.moniker || '--';
773
+ document.getElementById('wallet2fa').innerHTML = data.totp_enabled
774
+ ? '<span class="badge badge-success">'+t('enabled')+'</span>'
775
+ : '<span class="badge badge-warning">'+t('disabled')+'</span>';
776
+ document.getElementById('walletCreated').textContent = new Date(data.created_at).toLocaleString();
777
+ if (data.totp_enabled) { document.getElementById('totpStep1').style.display='none'; document.getElementById('totpEnabled').style.display=''; }
778
+ try {
779
+ const balResp = await fetch(API+'/balance',{headers:{'Authorization':'Bearer '+authToken}});
780
+ const balData = await balResp.json();
781
+ document.getElementById('balanceDisplay').innerHTML = (balData.tct_balance||0).toLocaleString()+'<span class="unit">TCT</span>';
782
+ } catch { document.getElementById('balanceDisplay').innerHTML = '--<span class="unit">TCT</span>'; }
783
+ try {
784
+ const chainResp = await fetch(API+'/chain-status');
785
+ const chainData = await chainResp.json();
786
+ document.getElementById('onchainData').innerHTML = '<pre>'+JSON.stringify(chainData,null,2)+'</pre>';
787
+ } catch {}
788
+ }
789
+
790
+ async function changePassword() {
791
+ const oldPwd = document.getElementById('oldPassword').value;
792
+ const newPwd = document.getElementById('newPassword').value;
793
+ if (newPwd.length < 8) return showMsg('pwdMsg','error',t('errPasswordMin'));
794
+ const resp = await fetch(API+'/change-password',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'},body:JSON.stringify({old_password:oldPwd,new_password:newPwd})});
795
+ const data = await resp.json();
796
+ if (data.error) return showMsg('pwdMsg','error',data.error);
797
+ showMsg('pwdMsg','success',t('okPasswordUpdated'));
798
+ }
799
+
800
+ async function exportMnemonic() {
801
+ const pwd = document.getElementById('exportPassword').value;
802
+ const resp = await fetch(API+'/export-mnemonic',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'},body:JSON.stringify({password:pwd})});
803
+ const data = await resp.json();
804
+ if (data.error) return showMsg('exportMsg','error',data.error);
805
+ const words = data.mnemonic.split(' ');
806
+ showMsg('exportMsg','success',words.map((w,i)=>(i+1)+'. '+w).join(' '));
807
+ }
808
+
809
+ async function start2faSetup() {
810
+ const pwd = document.getElementById('totpPassword').value;
811
+ if (!pwd) return showMsg('totpStep1Msg','error',t('errEnterPassword'));
812
+ const verifyResp = await fetch(API+'/verify-password',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'},body:JSON.stringify({password:pwd})});
813
+ const verifyData = await verifyResp.json();
814
+ if (verifyData.error) return showMsg('totpStep1Msg','error',verifyData.error);
815
+ const resp = await fetch(API+'/setup-2fa',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'}});
816
+ const data = await resp.json();
817
+ if (data.error) return showMsg('totpStep1Msg','error',data.error);
818
+ document.getElementById('totpQrImg').src = 'https://api.qrserver.com/v1/create-qr-code/?size=256x256&data='+encodeURIComponent(data.uri);
819
+ document.getElementById('totpManualKey').textContent = data.secret;
820
+ document.getElementById('totpStep1').style.display = 'none';
821
+ document.getElementById('totpStep2').style.display = '';
822
+ }
823
+
824
+ async function confirm2fa() {
825
+ const code = document.getElementById('totpVerifyCode').value;
826
+ if (!code||code.length!==6) return showMsg('totpStep2Msg','error',t('errEnterCode'));
827
+ const resp = await fetch(API+'/enable-2fa',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'},body:JSON.stringify({code})});
828
+ const data = await resp.json();
829
+ if (data.error) return showMsg('totpStep2Msg','error',data.error);
830
+ showMsg('totpStep2Msg','success',t('ok2FAEnabled'));
831
+ setTimeout(()=>location.reload(),1500);
832
+ }
833
+
834
+ function cancel2fa() {
835
+ document.getElementById('totpStep1').style.display = '';
836
+ document.getElementById('totpStep2').style.display = 'none';
837
+ document.getElementById('totpVerifyCode').value = '';
838
+ }
839
+
840
+ async function disable2fa() {
841
+ const code = document.getElementById('disableTotp').value;
842
+ const resp = await fetch(API+'/disable-2fa',{method:'POST',headers:{'Authorization':'Bearer '+authToken,'Content-Type':'application/json'},body:JSON.stringify({code})});
843
+ const data = await resp.json();
844
+ if (data.error) return showMsg('totpDisableMsg','error',data.error);
845
+ showMsg('totpDisableMsg','success',t('ok2FADisabled'));
846
+ setTimeout(()=>location.reload(),1000);
847
+ }
848
+
849
+ function showMsg(id, type, msg) {
850
+ const icon = type === 'success'
851
+ ? '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;flex-shrink:0;margin-top:1px"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>'
852
+ : '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;flex-shrink:0;margin-top:1px"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>';
853
+ document.getElementById(id).innerHTML = '<div class="alert alert-'+type+'" style="margin-top:12px">'+icon+msg+'</div>';
854
+ }
855
+
856
+ init();
857
+ </script>
858
+ </body>
859
+ </html>`;
860
+ }
861
+ // ===================== Express App =====================
862
+ function createWebPanel(config) {
863
+ const app = (0, express_1.default)();
864
+ app.use(express_1.default.json());
865
+ // CORS middleware
866
+ app.use((req, res, next) => {
867
+ res.header('Access-Control-Allow-Origin', '*');
868
+ res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
869
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
870
+ if (req.method === 'OPTIONS') {
871
+ return res.sendStatus(200);
872
+ }
873
+ next();
874
+ });
875
+ // Serve panel
876
+ // Serve Vue build if available, fallback to inline HTML
877
+ const vueDist = (0, path_1.resolve)(__dirname, '..', '..', 'web-dist');
878
+ if (fs_1.default.existsSync((0, path_1.resolve)(vueDist, 'index.html'))) {
879
+ app.use(express_1.default.static(vueDist));
880
+ app.get('/', (_req, res) => res.sendFile((0, path_1.resolve)(vueDist, 'index.html')));
881
+ }
882
+ else {
883
+ app.get('/', (_req, res) => res.type('html').send(getPanelHtml()));
884
+ }
885
+ // ---- Public APIs ----
886
+ app.get('/api/chain-status', async (_req, res) => {
887
+ try {
888
+ const resp = await fetch(`${config.rpcUrl}/status`);
889
+ const data = await resp.json();
890
+ const info = data.result;
891
+ res.json({
892
+ chain_id: info.node_info.network,
893
+ moniker: info.node_info.moniker,
894
+ block_height: Number(info.sync_info.latest_block_height),
895
+ catching_up: info.sync_info.catching_up,
896
+ voting_power: info.validator_info.voting_power,
897
+ });
898
+ }
899
+ catch (err) {
900
+ res.status(500).json({ error: err.message });
901
+ }
902
+ });
903
+ app.get('/api/has-wallet', (_req, res) => {
904
+ const profiles = loadProfiles();
905
+ res.json({ hasWallet: profiles.length > 0, totpEnabled: profiles.some(p => p.totpEnabled) });
906
+ });
907
+ app.get('/api/generate-mnemonic', (_req, res) => {
908
+ res.json({ mnemonic: generateMnemonic(24) });
909
+ });
910
+ app.post('/api/create-wallet', async (req, res) => {
911
+ try {
912
+ const { password, mnemonic, moniker } = req.body;
913
+ if (!password || password.length < 8)
914
+ return res.status(400).json({ error: '密码至少8位' });
915
+ if (!mnemonic)
916
+ return res.status(400).json({ error: '助记词不能为空' });
917
+ const wordCount = mnemonic.trim().split(/\s+/).length;
918
+ if (![12, 15, 18, 21, 24].includes(wordCount))
919
+ return res.status(400).json({ error: '助记词长度无效(支持12/15/18/21/24词)' });
920
+ const profiles = loadProfiles();
921
+ if (profiles.length >= 10)
922
+ return res.status(400).json({ error: '最多10个钱包' });
923
+ // Derive address from mnemonic using Cosmos SDK HD wallet derivation
924
+ const wallet = await amino_1.Secp256k1HdWallet.fromMnemonic(mnemonic, { prefix: 'tct' });
925
+ const [{ address }] = await wallet.getAccounts();
926
+ const encrypted = encrypt(mnemonic, password);
927
+ const profile = {
928
+ id: crypto_1.default.randomUUID(),
929
+ address,
930
+ moniker: moniker || '',
931
+ encryptedMnemonic: encrypted.encrypted,
932
+ iv: encrypted.iv,
933
+ salt: encrypted.salt,
934
+ totpEnabled: false,
935
+ createdAt: Date.now(),
936
+ };
937
+ profiles.push(profile);
938
+ saveProfiles(profiles);
939
+ // Auto-create session token so 2FA setup doesn't need login
940
+ const token = crypto_1.default.randomUUID();
941
+ SESSIONS.set(token, {
942
+ id: token,
943
+ walletId: profile.id,
944
+ createdAt: Date.now(),
945
+ expiresAt: Date.now() + 24 * 60 * 60 * 1000,
946
+ });
947
+ res.json({ address: profile.address, moniker: profile.moniker, token });
948
+ }
949
+ catch (err) {
950
+ res.status(500).json({ error: err.message });
951
+ }
952
+ });
953
+ app.post('/api/login', (req, res) => {
954
+ const { password, totp } = req.body;
955
+ const profiles = loadProfiles();
956
+ if (profiles.length === 0)
957
+ return res.status(400).json({ error: '没有钱包,请先创建' });
958
+ // Try to decrypt each profile
959
+ for (const profile of profiles) {
960
+ try {
961
+ decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
962
+ // Check TOTP if enabled
963
+ if (profile.totpEnabled && profile.totpSecret) {
964
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
965
+ return res.status(401).json({ error: '2FA验证码错误', requires2fa: true });
966
+ }
967
+ }
968
+ const token = crypto_1.default.randomUUID();
969
+ SESSIONS.set(token, {
970
+ id: token,
971
+ walletId: profile.id,
972
+ createdAt: Date.now(),
973
+ expiresAt: Date.now() + 24 * 60 * 60 * 1000, // 24h
974
+ });
975
+ return res.json({ token, address: profile.address });
976
+ }
977
+ catch {
978
+ continue; // Wrong password for this profile
979
+ }
980
+ }
981
+ res.status(401).json({ error: '密码错误' });
982
+ });
983
+ // ---- Authenticated APIs ----
984
+ app.get('/api/profile', authMiddleware, (req, res) => {
985
+ const profile = req.profile;
986
+ res.json({
987
+ address: profile.address,
988
+ moniker: profile.moniker,
989
+ totp_enabled: profile.totpEnabled,
990
+ created_at: profile.createdAt,
991
+ });
992
+ });
993
+ app.get('/api/balance', authMiddleware, async (req, res) => {
994
+ const profile = req.profile;
995
+ try {
996
+ const resp = await fetch(`${config.lcdUrl}/cosmos/bank/v1beta1/balances/${profile.address}`);
997
+ const data = await resp.json();
998
+ const tct = data.balances?.find((b) => b.denom === 'utct');
999
+ res.json({ tct_balance: tct ? Number(tct.amount) / 1_000_000 : 0 });
1000
+ }
1001
+ catch (err) {
1002
+ res.status(500).json({ error: err.message });
1003
+ }
1004
+ });
1005
+ app.post('/api/change-password', authMiddleware, (req, res) => {
1006
+ const { old_password, new_password, totp } = req.body;
1007
+ const profile = req.profile;
1008
+ // 2FA required when enabled
1009
+ if (profile.totpEnabled && profile.totpSecret) {
1010
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
1011
+ return res.status(401).json({ error: '2FA验证码错误' });
1012
+ }
1013
+ }
1014
+ try {
1015
+ // Verify old password
1016
+ const mnemonic = decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, old_password);
1017
+ // Re-encrypt with new password
1018
+ const encrypted = encrypt(mnemonic, new_password);
1019
+ const profiles = loadProfiles();
1020
+ const idx = profiles.findIndex(p => p.id === profile.id);
1021
+ if (idx >= 0) {
1022
+ profiles[idx].encryptedMnemonic = encrypted.encrypted;
1023
+ profiles[idx].iv = encrypted.iv;
1024
+ profiles[idx].salt = encrypted.salt;
1025
+ saveProfiles(profiles);
1026
+ }
1027
+ res.json({ success: true });
1028
+ }
1029
+ catch {
1030
+ res.status(401).json({ error: '当前密码错误' });
1031
+ }
1032
+ });
1033
+ app.post('/api/export-mnemonic', authMiddleware, (req, res) => {
1034
+ const { password, totp } = req.body;
1035
+ const profile = req.profile;
1036
+ // 2FA required when enabled
1037
+ if (profile.totpEnabled && profile.totpSecret) {
1038
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
1039
+ return res.status(401).json({ error: '2FA验证码错误' });
1040
+ }
1041
+ }
1042
+ try {
1043
+ const mnemonic = decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
1044
+ res.json({ mnemonic });
1045
+ }
1046
+ catch {
1047
+ res.status(401).json({ error: '密码错误' });
1048
+ }
1049
+ });
1050
+ app.post('/api/verify-password', authMiddleware, (req, res) => {
1051
+ const { password } = req.body;
1052
+ const profile = req.profile;
1053
+ try {
1054
+ decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
1055
+ res.json({ valid: true });
1056
+ }
1057
+ catch {
1058
+ res.status(401).json({ error: '密码错误' });
1059
+ }
1060
+ });
1061
+ app.post('/api/setup-2fa', authMiddleware, (req, res) => {
1062
+ const profile = req.profile;
1063
+ if (profile.totpEnabled)
1064
+ return res.status(400).json({ error: '2FA已启用' });
1065
+ const secret = generateTotpSecret();
1066
+ const uri = generateTotpUri(secret, profile.address);
1067
+ console.error('[DEBUG setup-2fa] generated secret:', secret, 'uri:', uri);
1068
+ // Save secret temporarily (not enabled yet)
1069
+ const profiles = loadProfiles();
1070
+ const idx = profiles.findIndex(p => p.id === profile.id);
1071
+ if (idx >= 0) {
1072
+ profiles[idx].totpSecret = secret;
1073
+ saveProfiles(profiles);
1074
+ }
1075
+ res.json({ secret, uri });
1076
+ });
1077
+ app.post('/api/enable-2fa', authMiddleware, (req, res) => {
1078
+ const { code } = req.body;
1079
+ const profile = req.profile;
1080
+ console.error('[DEBUG enable-2fa] code:', code, 'secret:', profile.totpSecret, 'time:', Date.now());
1081
+ if (!profile.totpSecret)
1082
+ return res.status(400).json({ error: '请先设置2FA' });
1083
+ if (!(0, totp_1.verifyTOTP)(profile.totpSecret, code))
1084
+ return res.status(400).json({ error: '验证码错误' });
1085
+ const profiles = loadProfiles();
1086
+ const idx = profiles.findIndex(p => p.id === profile.id);
1087
+ if (idx >= 0) {
1088
+ profiles[idx].totpEnabled = true;
1089
+ saveProfiles(profiles);
1090
+ }
1091
+ res.json({ success: true });
1092
+ });
1093
+ app.post('/api/disable-2fa', authMiddleware, (req, res) => {
1094
+ const { code } = req.body;
1095
+ const profile = req.profile;
1096
+ if (!profile.totpSecret || !(0, totp_1.verifyTOTP)(profile.totpSecret, code)) {
1097
+ return res.status(400).json({ error: '验证码错误' });
1098
+ }
1099
+ const profiles = loadProfiles();
1100
+ const idx = profiles.findIndex(p => p.id === profile.id);
1101
+ if (idx >= 0) {
1102
+ profiles[idx].totpEnabled = false;
1103
+ profiles[idx].totpSecret = undefined;
1104
+ saveProfiles(profiles);
1105
+ }
1106
+ res.json({ success: true });
1107
+ });
1108
+ // ---- Seller Registration (auto-configures verifier) ----
1109
+ app.post('/api/register-seller', authMiddleware, async (req, res) => {
1110
+ const { shop_name, verify_server } = req.body;
1111
+ const profile = req.profile;
1112
+ if (!shop_name)
1113
+ return res.status(400).json({ error: '店铺名称不能为空' });
1114
+ try {
1115
+ // 1. Generate seller API key
1116
+ const apiKey = crypto_1.default.randomBytes(32).toString('hex');
1117
+ // 2. Write verifier config (silent - seller never sees this)
1118
+ const validatorDir = runtime_data_1.runtimeDataFile('.validator');
1119
+ if (!fs_1.default.existsSync(validatorDir)) {
1120
+ fs_1.default.mkdirSync(validatorDir, { recursive: true });
1121
+ }
1122
+ const verifierConfig = {
1123
+ sellerId: profile.address,
1124
+ apiKey,
1125
+ verifyServer: verify_server || 'https://verify.trustchain.io',
1126
+ rpcUrl: config.rpcUrl,
1127
+ chainId: 'trustchain-local',
1128
+ registeredAt: Date.now(),
1129
+ };
1130
+ fs_1.default.writeFileSync((0, path_1.resolve)(validatorDir, 'config.json'), JSON.stringify(verifierConfig, null, 2), { mode: 0o600 });
1131
+ // 3. Update profile with seller info
1132
+ const profiles = loadProfiles();
1133
+ const idx = profiles.findIndex(p => p.id === profile.id);
1134
+ if (idx >= 0) {
1135
+ profiles[idx].isSeller = true;
1136
+ profiles[idx].shopName = shop_name;
1137
+ saveProfiles(profiles);
1138
+ }
1139
+ res.json({ success: true, shop_name });
1140
+ }
1141
+ catch (err) {
1142
+ res.status(500).json({ error: err.message });
1143
+ }
1144
+ });
1145
+ // Check seller status
1146
+ app.get('/api/seller-status', authMiddleware, (req, res) => {
1147
+ const profile = req.profile;
1148
+ const validatorConfig = runtime_data_1.runtimeDataFile('.validator', 'config.json');
1149
+ const isSeller = fs_1.default.existsSync(validatorConfig);
1150
+ let shopName = '';
1151
+ if (isSeller) {
1152
+ try {
1153
+ const cfg = JSON.parse(fs_1.default.readFileSync(validatorConfig, 'utf8'));
1154
+ shopName = profile.shopName || '';
1155
+ }
1156
+ catch { }
1157
+ }
1158
+ res.json({ isSeller, shopName });
1159
+ });
1160
+ // ---- Register Account on Chain ----
1161
+ // Check if account is registered on chain
1162
+ app.get('/api/account-status', authMiddleware, async (req, res) => {
1163
+ const profile = req.profile;
1164
+ try {
1165
+ const { execSync } = require('child_process');
1166
+ const cmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind query trustcoin account --address ${profile.address} -o json 2>&1'"`;
1167
+ const output = execSync(cmd, { timeout: 10000 }).toString();
1168
+ // Check if account exists
1169
+ if (output.includes('not found') || output.includes('InvalidArgument')) {
1170
+ return res.json({ registered: false, account: null });
1171
+ }
1172
+ const accountData = JSON.parse(output);
1173
+ res.json({ registered: true, account: accountData.account });
1174
+ }
1175
+ catch (e) {
1176
+ // If error, assume not registered
1177
+ res.json({ registered: false, account: null, error: e?.message });
1178
+ }
1179
+ });
1180
+ // Register account on chain
1181
+ app.post('/api/register-account', authMiddleware, async (req, res) => {
1182
+ const { role, region, password, totp } = req.body;
1183
+ const profile = req.profile;
1184
+ // Validate inputs
1185
+ if (!role || !['buyer', 'seller', 'both'].includes(role)) {
1186
+ return res.status(400).json({ error: '角色必须是 buyer、seller 或 both' });
1187
+ }
1188
+ if (!region || !['CN', 'US', 'JP', 'domestic', 'international'].includes(region)) {
1189
+ return res.status(400).json({ error: '地区必须是 CN、US、JP、domestic 或 international' });
1190
+ }
1191
+ if (!password)
1192
+ return res.status(400).json({ error: '请输入钱包密码' });
1193
+ // 2FA required when enabled
1194
+ if (profile.totpEnabled && profile.totpSecret) {
1195
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
1196
+ return res.status(401).json({ error: '2FA验证码错误' });
1197
+ }
1198
+ }
1199
+ try {
1200
+ // First check if already registered
1201
+ const { execSync } = require('child_process');
1202
+ const checkCmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind query trustcoin account --address ${profile.address} -o json 2>&1'"`;
1203
+ const checkOutput = execSync(checkCmd, { timeout: 10000 }).toString();
1204
+ if (!checkOutput.includes('not found') && !checkOutput.includes('InvalidArgument')) {
1205
+ return res.status(400).json({ error: '账户已注册', alreadyRegistered: true });
1206
+ }
1207
+ // Decrypt mnemonic to get the key
1208
+ const mnemonic = decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
1209
+ // Import key to node's keyring temporarily
1210
+ const importCmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'echo \"${mnemonic}\" | trustchaind keys import mnemonic temp-register --keyring-backend test --recover 2>&1'"`;
1211
+ execSync(importCmd, { timeout: 15000 });
1212
+ // Register account on chain
1213
+ const registerCmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind tx trustcoin register-account --role ${role} --region ${region} --from temp-register --keyring-backend test --chain-id trustchain-local --fees 5000utct --yes --output json 2>&1'"`;
1214
+ const registerOutput = execSync(registerCmd, { timeout: 30000 }).toString();
1215
+ // Parse result
1216
+ const txResult = JSON.parse(registerOutput);
1217
+ if (txResult.code !== undefined && txResult.code !== 0) {
1218
+ // Delete temp key
1219
+ try {
1220
+ execSync(`wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind keys delete temp-register --keyring-backend test --yes 2>&1'"`, { timeout: 10000 });
1221
+ }
1222
+ catch { }
1223
+ return res.status(500).json({ error: txResult.raw_log || '注册失败' });
1224
+ }
1225
+ // Delete temp key after successful registration
1226
+ try {
1227
+ execSync(`wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind keys delete temp-register --keyring-backend test --yes 2>&1'"`, { timeout: 10000 });
1228
+ }
1229
+ catch { }
1230
+ res.json({
1231
+ success: true,
1232
+ txHash: txResult.txhash,
1233
+ address: profile.address,
1234
+ role,
1235
+ region,
1236
+ });
1237
+ }
1238
+ catch (e) {
1239
+ console.error('[register-account error]', e);
1240
+ res.status(500).json({ error: e?.message || '注册失败' });
1241
+ }
1242
+ });
1243
+ // ---- Products & Orders APIs ----
1244
+ app.get('/api/products', (req, res) => {
1245
+ if (!config.dbPath || !fs_1.default.existsSync(config.dbPath)) {
1246
+ return res.json({ products: [], total: 0 });
1247
+ }
1248
+ try {
1249
+ const Database = require('better-sqlite3');
1250
+ const db = new Database(config.dbPath, { readonly: true });
1251
+ const page = Math.max(1, parseInt(req.query.page) || 1);
1252
+ const limit = Math.min(100, Math.max(1, parseInt(req.query.limit) || 20));
1253
+ const offset = (page - 1) * limit;
1254
+ const status = req.query.status || 'active';
1255
+ const keyword = (req.query.keyword || '').trim();
1256
+ let where = 'WHERE status = ?';
1257
+ const params = [status];
1258
+ // 质押可见性硬规则 (xiaomu 2026-09-18 拍板, 与 search core 同款):
1259
+ // active 列表只显示链上有 slot 且有质押的商品 (status=active 视图才套用,
1260
+ // 避免影响 delisted 等管理视图)。
1261
+ if (status === 'active') {
1262
+ where += " AND CAST(IFNULL(NULLIF(slot_index, ''), '-1') AS INTEGER) >= 0" +
1263
+ " AND CAST(IFNULL(NULLIF(stake_per_unit, ''), '0') AS INTEGER) > 0";
1264
+ }
1265
+ if (keyword) {
1266
+ where += ' AND (title LIKE ? OR description LIKE ?)';
1267
+ params.push(`%${keyword}%`, `%${keyword}%`);
1268
+ }
1269
+ const total = db.prepare(`SELECT COUNT(*) as c FROM products ${where}`).get(...params).c;
1270
+ const rows = db.prepare(`SELECT * FROM products ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`).all(...params, limit, offset);
1271
+ db.close();
1272
+ res.json({ products: rows, total, page, limit });
1273
+ }
1274
+ catch (e) {
1275
+ res.status(500).json({ error: e?.message || 'DB error' });
1276
+ }
1277
+ });
1278
+ app.get('/api/orders', authMiddleware, (req, res) => {
1279
+ if (!config.dbPath || !fs_1.default.existsSync(config.dbPath)) {
1280
+ return res.json({ orders: [], total: 0 });
1281
+ }
1282
+ try {
1283
+ const Database = require('better-sqlite3');
1284
+ const db = new Database(config.dbPath, { readonly: true });
1285
+ const profile = req.profile;
1286
+ const page = Math.max(1, parseInt(req.query.page) || 1);
1287
+ const limit = Math.min(100, Math.max(1, parseInt(req.query.limit) || 20));
1288
+ const offset = (page - 1) * limit;
1289
+ // Show orders where user is buyer or seller
1290
+ const rows = db.prepare(`SELECT o.*, p.title as product_title FROM orders o LEFT JOIN products p ON o.sku_id = p.sku_id WHERE o.buyer = ? OR o.seller = ? ORDER BY o.created_at DESC LIMIT ? OFFSET ?`).all(profile.address, profile.address, limit, offset);
1291
+ const total = db.prepare(`SELECT COUNT(*) as c FROM orders WHERE buyer = ? OR seller = ?`).get(profile.address, profile.address).c;
1292
+ db.close();
1293
+ res.json({ orders: rows, total, page, limit });
1294
+ }
1295
+ catch (e) {
1296
+ res.status(500).json({ error: e?.message || 'DB error' });
1297
+ }
1298
+ });
1299
+ app.get('/api/indexer-stats', (_req, res) => {
1300
+ if (!config.dbPath || !fs_1.default.existsSync(config.dbPath)) {
1301
+ return res.json({ totalProducts: 0, totalSellers: 0, totalOrders: 0, totalReviews: 0 });
1302
+ }
1303
+ try {
1304
+ const Database = require('better-sqlite3');
1305
+ const db = new Database(config.dbPath, { readonly: true });
1306
+ const stats = {
1307
+ totalProducts: db.prepare('SELECT COUNT(*) as c FROM products').get().c,
1308
+ totalSellers: db.prepare('SELECT COUNT(*) as c FROM sellers').get().c,
1309
+ totalOrders: db.prepare('SELECT COUNT(*) as c FROM orders').get().c,
1310
+ totalReviews: db.prepare('SELECT COUNT(*) as c FROM reviews').get().c,
1311
+ };
1312
+ db.close();
1313
+ res.json(stats);
1314
+ }
1315
+ catch (e) {
1316
+ res.status(500).json({ error: e?.message || 'DB error' });
1317
+ }
1318
+ });
1319
+ // ---- Transfer API (2FA required) ----
1320
+ app.post('/api/transfer', authMiddleware, async (req, res) => {
1321
+ const { to_address, amount, password, totp } = req.body;
1322
+ const profile = req.profile;
1323
+ // Validate inputs
1324
+ if (!to_address)
1325
+ return res.status(400).json({ error: '请输入收款地址' });
1326
+ if (!amount || parseFloat(amount) <= 0)
1327
+ return res.status(400).json({ error: '金额必须大于0' });
1328
+ if (!password)
1329
+ return res.status(400).json({ error: '请输入钱包密码' });
1330
+ // 2FA is mandatory for transfers
1331
+ if (profile.totpEnabled && profile.totpSecret) {
1332
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
1333
+ return res.status(401).json({ error: '2FA验证码错误' });
1334
+ }
1335
+ }
1336
+ try {
1337
+ // Decrypt mnemonic
1338
+ const mnemonic = decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
1339
+ // Create wallet and client
1340
+ const wallet = await amino_1.Secp256k1HdWallet.fromMnemonic(mnemonic, { prefix: 'tct' });
1341
+ const { GasPrice } = await Promise.resolve().then(() => __importStar(require('@cosmjs/stargate')));
1342
+ const gasPrice = GasPrice.fromString('0.001utct');
1343
+ const client = await stargate_1.SigningStargateClient.connectWithSigner(config.lcdUrl.replace(':1317', ':26657'), // RPC endpoint
1344
+ wallet, { gasPrice });
1345
+ // Convert TCT to utct (6 decimals)
1346
+ const amountUtct = Math.floor(parseFloat(amount) * 1_000_000).toString();
1347
+ const result = await client.sendTokens(profile.address, to_address, [{ denom: 'utct', amount: amountUtct }], 'auto', `Transfer ${amount} TCT`);
1348
+ res.json({
1349
+ success: true,
1350
+ txHash: result.transactionHash,
1351
+ height: result.height,
1352
+ });
1353
+ }
1354
+ catch (e) {
1355
+ console.error('[transfer error]', e);
1356
+ res.status(500).json({ error: e?.message || '转账失败' });
1357
+ }
1358
+ });
1359
+ // ---- List SKU API (2FA required, via CLI) ----
1360
+ app.post('/api/list-sku', authMiddleware, async (req, res) => {
1361
+ const { sku_id, title, description, variants, category, images, videos, shipping, payment_methods, return_policy, stock, password, totp, stake_per_unit } = req.body;
1362
+ const profile = req.profile;
1363
+ if (!sku_id)
1364
+ return res.status(400).json({ error: '请输入SKU ID' });
1365
+ if (!title)
1366
+ return res.status(400).json({ error: '请输入商品标题' });
1367
+ if (!variants || !Array.isArray(variants) || variants.length === 0)
1368
+ return res.status(400).json({ error: '至少需要一个规格' });
1369
+ if (!password)
1370
+ return res.status(400).json({ error: '请输入钱包密码' });
1371
+ // Validate variants
1372
+ for (const v of variants) {
1373
+ if (!v.name)
1374
+ return res.status(400).json({ error: '规格名称不能为空' });
1375
+ if (!v.price_cny || v.price_cny <= 0)
1376
+ return res.status(400).json({ error: '法币价格必须大于0' });
1377
+ if (!v.stock || v.stock <= 0)
1378
+ return res.status(400).json({ error: '库存必须大于0' });
1379
+ }
1380
+ // Validate images
1381
+ if (images && images.length > 50)
1382
+ return res.status(400).json({ error: '图片最多50张' });
1383
+ // 2FA required
1384
+ if (profile.totpEnabled && profile.totpSecret) {
1385
+ if (!totp || !(0, totp_1.verifyTOTP)(profile.totpSecret, totp)) {
1386
+ return res.status(401).json({ error: '2FA验证码错误' });
1387
+ }
1388
+ }
1389
+ try {
1390
+ // Verify password by decrypting mnemonic
1391
+ decrypt(profile.encryptedMnemonic, profile.iv, profile.salt, password);
1392
+ // Build full product MD document
1393
+ const totalStock = variants.reduce((sum, v) => sum + (v.stock || 0), 0);
1394
+ const minPrice = Math.min(...variants.map((v) => v.price_cny || 0));
1395
+ const stakePerUnit = stake_per_unit ? Math.floor(parseFloat(stake_per_unit) * 1_000_000).toString() : '1000000'; // default 1 TCT
1396
+ // Build product metadata JSON (future: full MD document)
1397
+ const productDoc = JSON.stringify({
1398
+ sku_id,
1399
+ seller: profile.address,
1400
+ title,
1401
+ description: description || '',
1402
+ variants: variants.map((v) => ({
1403
+ id: v.id || v.name.replace(/\s+/g, '-').toUpperCase(),
1404
+ name: v.name,
1405
+ price_cny: v.price_cny,
1406
+ price_tct: v.price_tct || null,
1407
+ stock: v.stock,
1408
+ })),
1409
+ category: category || {},
1410
+ images: (images || []).map((img) => ({
1411
+ url: img.url,
1412
+ sha256: img.sha256 || '',
1413
+ })),
1414
+ videos: (videos || []).map((vid) => ({
1415
+ url: vid.url,
1416
+ sha256: vid.sha256 || '',
1417
+ })),
1418
+ shipping: shipping || { method: 'standard', fee: 0, delivery_days: 3 },
1419
+ payment_methods: payment_methods || ['wechat', 'alipay'],
1420
+ return_policy: return_policy || '',
1421
+ created_at: new Date().toISOString(),
1422
+ });
1423
+ // SHA256 hash of product document → content_hash
1424
+ const contentHash = crypto_1.default.createHash('sha256').update(productDoc).digest('hex');
1425
+ // Execute via CLI on the node
1426
+ const { execSync } = require('child_process');
1427
+ const cmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind tx marketplace list-sku --sku-id ${sku_id} --content-hash 0x${contentHash} --stock ${totalStock} --stake-per-unit ${stakePerUnit} --from ${profile.address} --keyring-backend test --chain-id trustchain-local --fees 5000utct --yes --output json 2>&1'"`;
1428
+ const output = execSync(cmd, { timeout: 30000 }).toString();
1429
+ const txResult = JSON.parse(output);
1430
+ if (txResult.code !== undefined && txResult.code !== 0) {
1431
+ return res.status(500).json({ error: txResult.raw_log || '上架失败' });
1432
+ }
1433
+ // Save product document to P2P data directory
1434
+ try {
1435
+ const fs = require('fs');
1436
+ const path = require('path');
1437
+ const p2pDir = path.resolve(config.dataDir, 'seller', 'products', sku_id);
1438
+ fs.mkdirSync(p2pDir, { recursive: true });
1439
+ fs.writeFileSync(path.resolve(p2pDir, '..', `${sku_id}.md`), productDoc);
1440
+ console.error(`[P2P] Product saved: ${sku_id}`);
1441
+ }
1442
+ catch (saveErr) {
1443
+ console.error('[P2P] Save product failed:', saveErr.message);
1444
+ }
1445
+ res.json({
1446
+ success: true,
1447
+ txHash: txResult.txhash,
1448
+ height: txResult.height,
1449
+ content_hash: contentHash,
1450
+ });
1451
+ }
1452
+ catch (e) {
1453
+ console.error('[list-sku error]', e);
1454
+ res.status(500).json({ error: e?.message || '上架失败' });
1455
+ }
1456
+ });
1457
+ // ===================== P2P Port Registry =====================
1458
+ // Register P2P ports (called by seller's P2P node on startup)
1459
+ app.post('/api/register-p2p', (req, res) => {
1460
+ const { seller_address, http_port, tcp_port, quic_port, peer_id, ip } = req.body;
1461
+ if (!seller_address) {
1462
+ return res.status(400).json({ error: 'seller_address required' });
1463
+ }
1464
+ try {
1465
+ config.indexer.updateP2PPorts(seller_address, Number(http_port) || 0, Number(tcp_port) || 0, Number(quic_port) || 0, String(peer_id || ''), String(ip || ''));
1466
+ console.error(`[P2P Registry] ${seller_address}: http=${http_port} tcp=${tcp_port} quic=${quic_port} peer=${(peer_id || '').substring(0, 16)} ip=${ip || ''}`);
1467
+ res.json({ success: true, message: 'P2P ports registered' });
1468
+ }
1469
+ catch (err) {
1470
+ res.status(500).json({ error: err.message });
1471
+ }
1472
+ });
1473
+ // Query seller's P2P endpoint info
1474
+ app.get('/api/seller-p2p/:address', (req, res) => {
1475
+ const info = config.indexer.getSellerP2P(req.params.address);
1476
+ if (!info) {
1477
+ return res.status(404).json({ error: 'Seller not found' });
1478
+ }
1479
+ res.json(info);
1480
+ });
1481
+ // ===================== Verification APIs =====================
1482
+ // Check if entity is verified
1483
+ app.get('/api/verification/check', async (req, res) => {
1484
+ const { type, id } = req.query;
1485
+ if (!type || !id) {
1486
+ return res.status(400).json({ error: 'type and id required' });
1487
+ }
1488
+ try {
1489
+ const lcdUrl = process.env.TRUSTCOIN_LCD_URL || 'http://localhost:1317';
1490
+ const resp = await fetch(`${lcdUrl}/oxiaom/trustchain/verification/v1/is-verified/${type}/${id}`);
1491
+ if (!resp.ok) {
1492
+ return res.json({ verified: false, entity_type: type, entity_id: id });
1493
+ }
1494
+ const data = await resp.json();
1495
+ res.json({
1496
+ verified: data.verified || false,
1497
+ entity_type: type,
1498
+ entity_id: id,
1499
+ method: data.method || null,
1500
+ verified_at: data.verified_at || null,
1501
+ });
1502
+ }
1503
+ catch (e) {
1504
+ res.status(500).json({ error: e.message });
1505
+ }
1506
+ });
1507
+ // Get verification details
1508
+ app.get('/api/verification/:id', async (req, res) => {
1509
+ try {
1510
+ const lcdUrl = process.env.TRUSTCOIN_LCD_URL || 'http://localhost:1317';
1511
+ const resp = await fetch(`${lcdUrl}/oxiaom/trustchain/verification/v1/verifications/${req.params.id}`);
1512
+ if (!resp.ok) {
1513
+ return res.status(404).json({ error: 'Verification not found' });
1514
+ }
1515
+ const data = await resp.json();
1516
+ res.json(data.verification || data);
1517
+ }
1518
+ catch (e) {
1519
+ res.status(500).json({ error: e.message });
1520
+ }
1521
+ });
1522
+ // List pending verifications
1523
+ app.get('/api/verification/pending', async (req, res) => {
1524
+ const { submitter, entity_type, limit = 20 } = req.query;
1525
+ try {
1526
+ const lcdUrl = process.env.TRUSTCOIN_LCD_URL || 'http://localhost:1317';
1527
+ let url = `${lcdUrl}/oxiaom/trustchain/verification/v1/pending-verifications?limit=${limit}`;
1528
+ if (entity_type)
1529
+ url += `&entity_type=${entity_type}`;
1530
+ const resp = await fetch(url);
1531
+ if (!resp.ok) {
1532
+ return res.json({ verifications: [], total: 0 });
1533
+ }
1534
+ const data = await resp.json();
1535
+ let verifications = data.verifications || [];
1536
+ // Filter by submitter if provided
1537
+ if (submitter) {
1538
+ verifications = verifications.filter((v) => v.submitter === submitter);
1539
+ }
1540
+ res.json({ verifications, total: verifications.length });
1541
+ }
1542
+ catch (e) {
1543
+ res.status(500).json({ error: e.message });
1544
+ }
1545
+ });
1546
+ // Submit verification request
1547
+ app.post('/api/verification/submit', authMiddleware, async (req, res) => {
1548
+ const { entity_type, entity_id, method, credential_hash, metadata } = req.body;
1549
+ const profile = req.profile;
1550
+ if (!entity_type || !method || !credential_hash) {
1551
+ return res.status(400).json({ error: 'entity_type, method, and credential_hash required' });
1552
+ }
1553
+ try {
1554
+ const { execSync } = require('child_process');
1555
+ const entityId = entity_id || profile.address;
1556
+ const metaFlag = metadata ? `--metadata='${metadata}'` : '';
1557
+ const cmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind tx verification submit-verification --entity-type=${entity_type} --entity-id=${entityId} --method=${method} --credential-hash=${credential_hash} ${metaFlag} --from=${profile.address} --keyring-backend=test --chain-id=trustchain-local --fees=5000utct --yes --output=json 2>&1'"`;
1558
+ const output = execSync(cmd, { timeout: 30000 }).toString().trim();
1559
+ const result = JSON.parse(output);
1560
+ if (result.code !== undefined && result.code !== 0) {
1561
+ return res.status(400).json({ error: result.raw_log || 'Submit failed' });
1562
+ }
1563
+ res.json({
1564
+ success: true,
1565
+ tx_hash: result.txhash,
1566
+ entity_type,
1567
+ entity_id: entityId,
1568
+ method,
1569
+ });
1570
+ }
1571
+ catch (e) {
1572
+ res.status(500).json({ error: e.message });
1573
+ }
1574
+ });
1575
+ // Approve verification (authority only)
1576
+ app.post('/api/verification/approve', authMiddleware, async (req, res) => {
1577
+ const { verification_id } = req.body;
1578
+ const profile = req.profile;
1579
+ if (!verification_id) {
1580
+ return res.status(400).json({ error: 'verification_id required' });
1581
+ }
1582
+ try {
1583
+ const { execSync } = require('child_process');
1584
+ const cmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind tx verification approve-verification --verification-id=${verification_id} --from=${profile.address} --keyring-backend=test --chain-id=trustchain-local --fees=5000utct --yes --output=json 2>&1'"`;
1585
+ const output = execSync(cmd, { timeout: 30000 }).toString().trim();
1586
+ const result = JSON.parse(output);
1587
+ if (result.code !== undefined && result.code !== 0) {
1588
+ return res.status(400).json({ error: result.raw_log || 'Approve failed' });
1589
+ }
1590
+ res.json({ success: true, tx_hash: result.txhash, verification_id });
1591
+ }
1592
+ catch (e) {
1593
+ res.status(500).json({ error: e.message });
1594
+ }
1595
+ });
1596
+ // Reject verification (authority only)
1597
+ app.post('/api/verification/reject', authMiddleware, async (req, res) => {
1598
+ const { verification_id, reason } = req.body;
1599
+ const profile = req.profile;
1600
+ if (!verification_id || !reason) {
1601
+ return res.status(400).json({ error: 'verification_id and reason required' });
1602
+ }
1603
+ try {
1604
+ const { execSync } = require('child_process');
1605
+ const cmd = `wsl -u root -e bash -c "sshpass -p ${process.env.SSH_PASSWORD || 'CHANGE_ME'} ssh -o StrictHostKeyChecking=no root@${process.env.SSH_HOST || 'localhost'} 'trustchaind tx verification reject-verification --verification-id=${verification_id} --reason=\"${reason}\" --from=${profile.address} --keyring-backend=test --chain-id=trustchain-local --fees=5000utct --yes --output=json 2>&1'"`;
1606
+ const output = execSync(cmd, { timeout: 30000 }).toString().trim();
1607
+ const result = JSON.parse(output);
1608
+ if (result.code !== undefined && result.code !== 0) {
1609
+ return res.status(400).json({ error: result.raw_log || 'Reject failed' });
1610
+ }
1611
+ res.json({ success: true, tx_hash: result.txhash, verification_id, reason });
1612
+ }
1613
+ catch (e) {
1614
+ res.status(500).json({ error: e.message });
1615
+ }
1616
+ });
1617
+ // Get verification statistics
1618
+ app.get('/api/verification/stats', async (req, res) => {
1619
+ try {
1620
+ const lcdUrl = process.env.TRUSTCOIN_LCD_URL || 'http://localhost:1317';
1621
+ const resp = await fetch(`${lcdUrl}/oxiaom/trustchain/verification/v1/stats`);
1622
+ if (!resp.ok) {
1623
+ return res.json({ total: 0, pending: 0, approved: 0, rejected: 0 });
1624
+ }
1625
+ const data = await resp.json();
1626
+ res.json({
1627
+ total: data.total_verifications || 0,
1628
+ pending: data.pending_count || 0,
1629
+ approved: data.approved_count || 0,
1630
+ rejected: data.rejected_count || 0,
1631
+ revoked: data.revoked_count || 0,
1632
+ by_entity_type: data.by_entity_type || {},
1633
+ by_method: data.by_method || {},
1634
+ });
1635
+ }
1636
+ catch (e) {
1637
+ res.status(500).json({ error: e.message });
1638
+ }
1639
+ });
1640
+ // SPA fallback - return index.html for all non-API routes
1641
+ app.get('*', (req, res, next) => {
1642
+ // Skip API routes and static files
1643
+ if (req.path.startsWith('/api/') || req.path.includes('.')) {
1644
+ return next();
1645
+ }
1646
+ // Return index.html for SPA routes
1647
+ const vueDist = (0, path_1.resolve)(__dirname, '..', '..', 'web-dist');
1648
+ if (fs_1.default.existsSync((0, path_1.resolve)(vueDist, 'index.html'))) {
1649
+ res.sendFile((0, path_1.resolve)(vueDist, 'index.html'));
1650
+ }
1651
+ else {
1652
+ res.type('html').send(getPanelHtml());
1653
+ }
1654
+ });
1655
+ return app;
1656
+ }
1657
+ //# sourceMappingURL=web-panel.js.map