@talken/talkenkit 2.4.16 → 2.4.17

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 (233) hide show
  1. package/dist/abcWallet-54KUGWUZ.js +192 -0
  2. package/dist/abcWallet-KZHOADBJ.js +192 -0
  3. package/dist/abcWallet-NZAVB4PI.js +190 -0
  4. package/dist/chunk-5X3ROW3U.js +8777 -0
  5. package/dist/chunk-DKA3NVFM.js +8497 -0
  6. package/dist/chunk-QNZ5HSPM.js +8339 -0
  7. package/dist/chunk-VE53ZNZV.js +331 -0
  8. package/dist/components/ConfirmationModal/ApproveSection.css.d.ts +16 -0
  9. package/dist/components/ConfirmationModal/ApproveSection.d.ts +8 -0
  10. package/dist/components/ConfirmationModal/NFTPlaceholder.css.d.ts +7 -0
  11. package/dist/components/ConfirmationModal/NFTPlaceholder.d.ts +8 -0
  12. package/dist/components/ConfirmationModal/NftApprovalSection.css.d.ts +10 -0
  13. package/dist/components/ConfirmationModal/NftApprovalSection.d.ts +7 -0
  14. package/dist/components/ConfirmationModal/SignConfirmationModal.css.d.ts +35 -0
  15. package/dist/components/ConfirmationModal/SignConfirmationModal.d.ts +17 -0
  16. package/dist/components/ConfirmationModal/SwapSection.css.d.ts +17 -0
  17. package/dist/components/ConfirmationModal/SwapSection.d.ts +7 -0
  18. package/dist/components/ConfirmationModal/TransactionConfirmationModal.css.d.ts +49 -0
  19. package/dist/components/ConfirmationModal/TransactionConfirmationModal.d.ts +12 -0
  20. package/dist/components/ConfirmationModal/TransferSection.css.d.ts +17 -0
  21. package/dist/components/ConfirmationModal/TransferSection.d.ts +7 -0
  22. package/dist/components/ConfirmationModal/commonStyles.css.d.ts +37 -0
  23. package/dist/components/ConfirmationModal/constants.d.ts +16 -0
  24. package/dist/components/ConfirmationModal/index.d.ts +9 -0
  25. package/dist/components/ConfirmationModal/modalTheme.css.d.ts +20 -0
  26. package/dist/components/ConfirmationModal/transactionUIRegistry.d.ts +134 -0
  27. package/dist/components/ConfirmationModal/utils.d.ts +37 -0
  28. package/dist/components/ConnectOptions/AbcWaasAuth/AbcWaasAuthSections.css.d.ts +1 -0
  29. package/dist/components/ConnectOptions/AbcWaasAuth/AbcWaasAuthSections.d.ts +1 -1
  30. package/dist/components/ConnectOptions/AbcWaasAuth/hooks/useAbcWaasAuth.d.ts +2 -25
  31. package/dist/components/ConnectOptions/AbcWaasAuth/hooks/useAbcWaasSocial.d.ts +1 -47
  32. package/dist/components/ConnectOptions/PinAuth/hooks/useWalletGeneration.d.ts +4 -21
  33. package/dist/components/GasFeeModal/GasFeeEditModal.css.d.ts +32 -0
  34. package/dist/components/GasFeeModal/GasFeeEditModal.d.ts +21 -0
  35. package/dist/components/GasFeeModal/index.d.ts +3 -0
  36. package/dist/components/GasFeeModal/modalTheme.css.d.ts +19 -0
  37. package/dist/components/Icons/Close2.d.ts +7 -0
  38. package/dist/components/Icons/Copy2.d.ts +4 -0
  39. package/dist/components/Icons/Dropdown2.d.ts +4 -0
  40. package/dist/components/Icons/Edit.d.ts +4 -0
  41. package/dist/components/Icons/InfoCircle.d.ts +4 -0
  42. package/dist/components/Icons/Kakao.d.ts +2 -0
  43. package/dist/components/Icons/Minus.d.ts +4 -0
  44. package/dist/components/Icons/Plus.d.ts +4 -0
  45. package/dist/components/Icons/SettingsGear.d.ts +4 -0
  46. package/dist/components/Icons/SpeedHigh.d.ts +4 -0
  47. package/dist/components/Icons/SpeedLow.d.ts +4 -0
  48. package/dist/components/Icons/SpeedMedium.d.ts +4 -0
  49. package/dist/components/RainbowKitProvider/InternalPinProvider.d.ts +7 -9
  50. package/dist/components/RainbowKitProvider/RainbowKitProvider.d.ts +7 -1
  51. package/dist/components/Toast/Toast.css.d.ts +2 -0
  52. package/dist/components/Toast/Toast.d.ts +6 -0
  53. package/dist/components/Toast/index.d.ts +4 -0
  54. package/dist/components/Toast/useToast.d.ts +10 -0
  55. package/dist/config/networks.d.ts +10 -0
  56. package/dist/css/sprinkles.css.d.ts +1 -1
  57. package/dist/hooks/useSolanaWallet.d.ts +5 -23
  58. package/dist/hooks/useTronWallet.d.ts +63 -0
  59. package/dist/index.css +1903 -236
  60. package/dist/index.d.ts +8 -3
  61. package/dist/index.js +7970 -4015
  62. package/dist/klipWallet-RD5Y4UEK.js +8 -0
  63. package/dist/providers/SignConfirmationProvider/SignConfirmationProvider.d.ts +22 -0
  64. package/dist/providers/SignConfirmationProvider/index.d.ts +6 -0
  65. package/dist/providers/SignConfirmationProvider/requestParsers.d.ts +24 -0
  66. package/dist/providers/SignConfirmationProvider/types.d.ts +91 -0
  67. package/dist/providers/SignConfirmationProvider/useApiClient.d.ts +15 -0
  68. package/dist/providers/SignConfirmationProvider/useTransactionResolver.d.ts +18 -0
  69. package/dist/secure-AEBFSVWE.js +8 -0
  70. package/dist/services/AbcAgenticWalletService.d.ts +111 -0
  71. package/dist/services/AbcAuthService.d.ts +26 -20
  72. package/dist/types/index.d.ts +3 -0
  73. package/dist/types/token.d.ts +82 -0
  74. package/dist/utils/abi/abiDecoder.d.ts +144 -0
  75. package/dist/utils/apiClientFactory.d.ts +21 -0
  76. package/dist/utils/blockies.d.ts +12 -0
  77. package/dist/utils/tokenMapper.d.ts +10 -0
  78. package/dist/wallets/walletConnectors/abcWallet/abcApi.d.ts +4 -1
  79. package/dist/wallets/walletConnectors/abcWallet/abcApi.js +7 -7
  80. package/dist/wallets/walletConnectors/abcWallet/abcBitcoinConnector.js +5 -5
  81. package/dist/wallets/walletConnectors/abcWallet/abcBitcoinProvider.d.ts +6 -8
  82. package/dist/wallets/walletConnectors/abcWallet/abcBitcoinProvider.js +1 -1
  83. package/dist/wallets/walletConnectors/abcWallet/abcConnector.js +9 -9
  84. package/dist/wallets/walletConnectors/abcWallet/abcProvider.d.ts +17 -6
  85. package/dist/wallets/walletConnectors/abcWallet/abcProvider.js +5 -4
  86. package/dist/wallets/walletConnectors/abcWallet/abcSolanaProvider.d.ts +11 -34
  87. package/dist/wallets/walletConnectors/abcWallet/abcSolanaProvider.js +1 -1
  88. package/dist/wallets/walletConnectors/abcWallet/abcSolanaWalletAdapter.d.ts +3 -11
  89. package/dist/wallets/walletConnectors/abcWallet/abcSolanaWalletAdapter.js +17 -80
  90. package/dist/wallets/walletConnectors/abcWallet/abcTronProvider.d.ts +112 -0
  91. package/dist/wallets/walletConnectors/abcWallet/abcTronProvider.js +11 -0
  92. package/dist/wallets/walletConnectors/abcWallet/abcWallet.d.ts +2 -0
  93. package/dist/wallets/walletConnectors/abcWallet/abcWallet.js +11 -10
  94. package/dist/wallets/walletConnectors/abcWallet/api/AuthApi.d.ts +9 -11
  95. package/dist/wallets/walletConnectors/abcWallet/api/AuthApi.js +6 -6
  96. package/dist/wallets/walletConnectors/abcWallet/api/BaseApiClient.d.ts +1 -1
  97. package/dist/wallets/walletConnectors/abcWallet/api/BaseApiClient.js +5 -5
  98. package/dist/wallets/walletConnectors/abcWallet/api/BitcoinApi.js +6 -6
  99. package/dist/wallets/walletConnectors/abcWallet/api/GasApi.d.ts +45 -0
  100. package/dist/wallets/walletConnectors/abcWallet/api/GasApi.js +12 -0
  101. package/dist/wallets/walletConnectors/abcWallet/api/SigningApi.js +7 -7
  102. package/dist/wallets/walletConnectors/abcWallet/api/SolanaApi.d.ts +9 -1
  103. package/dist/wallets/walletConnectors/abcWallet/api/SolanaApi.js +7 -7
  104. package/dist/wallets/walletConnectors/abcWallet/api/TalkenApiClient.d.ts +333 -0
  105. package/dist/wallets/walletConnectors/abcWallet/api/TalkenApiClient.js +11 -0
  106. package/dist/wallets/walletConnectors/abcWallet/api/TalkenApiSingleton.d.ts +18 -0
  107. package/dist/wallets/walletConnectors/abcWallet/api/TalkenApiSingleton.js +14 -0
  108. package/dist/wallets/walletConnectors/abcWallet/api/TransactionApi.d.ts +2 -2
  109. package/dist/wallets/walletConnectors/abcWallet/api/TransactionApi.js +7 -7
  110. package/dist/wallets/walletConnectors/abcWallet/api/TronApi.d.ts +102 -0
  111. package/dist/wallets/walletConnectors/abcWallet/api/TronApi.js +12 -0
  112. package/dist/wallets/walletConnectors/abcWallet/api/WalletApi.d.ts +4 -2
  113. package/dist/wallets/walletConnectors/abcWallet/api/WalletApi.js +7 -7
  114. package/dist/wallets/walletConnectors/abcWallet/api/WalletscanApi.d.ts +60 -0
  115. package/dist/wallets/walletConnectors/abcWallet/api/WalletscanApi.js +12 -0
  116. package/dist/wallets/walletConnectors/abcWallet/api/index.d.ts +24 -0
  117. package/dist/wallets/walletConnectors/abcWallet/api/index.js +35 -17
  118. package/dist/wallets/walletConnectors/abcWallet/constants.d.ts +39 -1
  119. package/dist/wallets/walletConnectors/abcWallet/constants.js +5 -1
  120. package/dist/wallets/walletConnectors/abcWallet/googleAuth.d.ts +6 -0
  121. package/dist/wallets/walletConnectors/abcWallet/googleAuth.js +37 -1
  122. package/dist/wallets/walletConnectors/abcWallet/index.d.ts +5 -3
  123. package/dist/wallets/walletConnectors/abcWallet/index.js +44 -31
  124. package/dist/wallets/walletConnectors/abcWallet/kakaoAuth.d.ts +27 -0
  125. package/dist/wallets/walletConnectors/abcWallet/kakaoAuth.js +290 -0
  126. package/dist/wallets/walletConnectors/abcWallet/networkConfig.d.ts +39 -3
  127. package/dist/wallets/walletConnectors/abcWallet/networkConfig.js +11 -3
  128. package/dist/wallets/walletConnectors/abcWallet/secure.js +2 -2
  129. package/dist/wallets/walletConnectors/abcWallet/sessionUtils.js +1 -1
  130. package/dist/wallets/walletConnectors/abcWallet/types.d.ts +369 -7
  131. package/dist/wallets/walletConnectors/abcWallet/types.js +5 -3
  132. package/dist/wallets/walletConnectors/abcWallet/utils.js +3 -3
  133. package/dist/wallets/walletConnectors/abcWallet/walletGeneration.d.ts +10 -19
  134. package/dist/wallets/walletConnectors/abcWallet/walletGeneration.js +2 -2
  135. package/dist/wallets/walletConnectors/berasigWallet/berasigWallet.js +2 -2
  136. package/dist/wallets/walletConnectors/bifrostWallet/bifrostWallet.js +2 -2
  137. package/dist/wallets/walletConnectors/binanceWallet/binanceWallet.js +2 -2
  138. package/dist/wallets/walletConnectors/bitgetWallet/bitgetWallet.js +2 -2
  139. package/dist/wallets/walletConnectors/bybitWallet/bybitWallet.js +2 -2
  140. package/dist/wallets/walletConnectors/chunk-25V3FW3O.js +282 -0
  141. package/dist/wallets/walletConnectors/chunk-27346T3J.js +134 -0
  142. package/dist/wallets/walletConnectors/chunk-5CNLMOB2.js +75 -0
  143. package/dist/wallets/walletConnectors/chunk-5K45TCAM.js +333 -0
  144. package/dist/wallets/walletConnectors/chunk-5VDSMZC4.js +286 -0
  145. package/dist/wallets/walletConnectors/chunk-5W7RBMPH.js +351 -0
  146. package/dist/wallets/walletConnectors/chunk-5XORKEWE.js +326 -0
  147. package/dist/wallets/walletConnectors/chunk-63WBO52A.js +77 -0
  148. package/dist/wallets/walletConnectors/chunk-7IRF225N.js +75 -0
  149. package/dist/wallets/walletConnectors/chunk-7QHCSJDN.js +726 -0
  150. package/dist/wallets/walletConnectors/chunk-A27H6PEU.js +739 -0
  151. package/dist/wallets/walletConnectors/chunk-A4WR3CFN.js +130 -0
  152. package/dist/wallets/walletConnectors/chunk-A6FUNQWF.js +572 -0
  153. package/dist/wallets/walletConnectors/chunk-AF4OCS7N.js +46 -0
  154. package/dist/wallets/walletConnectors/chunk-AFWBXEEC.js +66 -0
  155. package/dist/wallets/walletConnectors/chunk-AUGP2LJR.js +182 -0
  156. package/dist/wallets/walletConnectors/chunk-AWLDVQXC.js +317 -0
  157. package/dist/wallets/walletConnectors/chunk-BLEKTKBN.js +479 -0
  158. package/dist/wallets/walletConnectors/chunk-BVL6G5HI.js +1757 -0
  159. package/dist/wallets/walletConnectors/chunk-CMTGEHDI.js +485 -0
  160. package/dist/wallets/walletConnectors/chunk-D5EFTEOM.js +56 -0
  161. package/dist/wallets/walletConnectors/chunk-DM5NLSWD.js +346 -0
  162. package/dist/wallets/walletConnectors/chunk-EBGI4D2T.js +69 -0
  163. package/dist/wallets/walletConnectors/chunk-EEH2HMFG.js +47 -0
  164. package/dist/wallets/walletConnectors/chunk-F5JWDBKK.js +47 -0
  165. package/dist/wallets/walletConnectors/chunk-FN67MIIH.js +75 -0
  166. package/dist/wallets/walletConnectors/chunk-FWYVBX5F.js +75 -0
  167. package/dist/wallets/walletConnectors/chunk-GH6ZDY4K.js +58 -0
  168. package/dist/wallets/walletConnectors/chunk-GIJZMIBD.js +63 -0
  169. package/dist/wallets/walletConnectors/chunk-GO6OLTNF.js +479 -0
  170. package/dist/wallets/walletConnectors/chunk-HKXBK3NY.js +75 -0
  171. package/dist/wallets/walletConnectors/chunk-HMD2WWFQ.js +75 -0
  172. package/dist/wallets/walletConnectors/chunk-HO5Z2CTL.js +280 -0
  173. package/dist/wallets/walletConnectors/chunk-I3GFVK5O.js +151 -0
  174. package/dist/wallets/walletConnectors/chunk-IUHZ5ZCE.js +121 -0
  175. package/dist/wallets/walletConnectors/chunk-JODNZWWG.js +330 -0
  176. package/dist/wallets/walletConnectors/chunk-JTST3KMW.js +75 -0
  177. package/dist/wallets/walletConnectors/chunk-KH2L3ONV.js +1599 -0
  178. package/dist/wallets/walletConnectors/chunk-LHV22375.js +182 -0
  179. package/dist/wallets/walletConnectors/chunk-LZZE462U.js +315 -0
  180. package/dist/wallets/walletConnectors/chunk-MGCRUAHX.js +276 -0
  181. package/dist/wallets/walletConnectors/chunk-MURSKRMJ.js +63 -0
  182. package/dist/wallets/walletConnectors/chunk-NG7PSAPX.js +115 -0
  183. package/dist/wallets/walletConnectors/chunk-NHP6D6AH.js +204 -0
  184. package/dist/wallets/walletConnectors/chunk-O4AU63LK.js +181 -0
  185. package/dist/wallets/walletConnectors/chunk-OBS74J5N.js +221 -0
  186. package/dist/wallets/walletConnectors/chunk-ON4U54WO.js +115 -0
  187. package/dist/wallets/walletConnectors/chunk-PPYBE5TV.js +276 -0
  188. package/dist/wallets/walletConnectors/chunk-PWWSAM4G.js +309 -0
  189. package/dist/wallets/walletConnectors/chunk-QB5GDLRU.js +330 -0
  190. package/dist/wallets/walletConnectors/chunk-QMLG7MAP.js +107 -0
  191. package/dist/wallets/walletConnectors/chunk-RGIB7FFH.js +47 -0
  192. package/dist/wallets/walletConnectors/chunk-SHJBMDP4.js +278 -0
  193. package/dist/wallets/walletConnectors/chunk-SOBJYYIX.js +484 -0
  194. package/dist/wallets/walletConnectors/chunk-T66U3ADD.js +58 -0
  195. package/dist/wallets/walletConnectors/chunk-THCKLFSJ.js +75 -0
  196. package/dist/wallets/walletConnectors/chunk-TS466TDR.js +286 -0
  197. package/dist/wallets/walletConnectors/chunk-UJGFYQEV.js +459 -0
  198. package/dist/wallets/walletConnectors/chunk-UXNEBBUV.js +224 -0
  199. package/dist/wallets/walletConnectors/chunk-VRCNFVPM.js +276 -0
  200. package/dist/wallets/walletConnectors/chunk-WODNUC65.js +333 -0
  201. package/dist/wallets/walletConnectors/chunk-X6A2FSHK.js +484 -0
  202. package/dist/wallets/walletConnectors/chunk-XVRNEES5.js +1541 -0
  203. package/dist/wallets/walletConnectors/chunk-XWVM2Y5A.js +306 -0
  204. package/dist/wallets/walletConnectors/chunk-XXG7ABSJ.js +328 -0
  205. package/dist/wallets/walletConnectors/chunk-YJH4BHSB.js +254 -0
  206. package/dist/wallets/walletConnectors/chunk-YRDNIP2H.js +90 -0
  207. package/dist/wallets/walletConnectors/chunk-YTPAWPCA.js +156 -0
  208. package/dist/wallets/walletConnectors/chunk-ZCSHD7UG.js +562 -0
  209. package/dist/wallets/walletConnectors/chunk-ZZCZ3RJU.js +272 -0
  210. package/dist/wallets/walletConnectors/clvWallet/clvWallet.js +2 -2
  211. package/dist/wallets/walletConnectors/coin98Wallet/coin98Wallet.js +2 -2
  212. package/dist/wallets/walletConnectors/coreWallet/coreWallet.js +2 -2
  213. package/dist/wallets/walletConnectors/foxWallet/foxWallet.js +2 -2
  214. package/dist/wallets/walletConnectors/frontierWallet/frontierWallet.js +2 -2
  215. package/dist/wallets/walletConnectors/gateWallet/gateWallet.js +2 -2
  216. package/dist/wallets/walletConnectors/index.js +57 -56
  217. package/dist/wallets/walletConnectors/iopayWallet/iopayWallet.js +2 -2
  218. package/dist/wallets/walletConnectors/kaiaWallet/kaiaWallet.js +2 -2
  219. package/dist/wallets/walletConnectors/kaikasWallet/kaikasWallet.js +2 -2
  220. package/dist/wallets/walletConnectors/klipWallet/klipWallet.d.ts +3 -0
  221. package/dist/wallets/walletConnectors/klipWallet/klipWallet.js +8 -0
  222. package/dist/wallets/walletConnectors/klipWallet-PPTYYB5G.js +7 -0
  223. package/dist/wallets/walletConnectors/metaMaskWallet/metaMaskWallet.js +2 -2
  224. package/dist/wallets/walletConnectors/okxWallet/okxWallet.js +2 -2
  225. package/dist/wallets/walletConnectors/rainbowWallet/rainbowWallet.js +2 -2
  226. package/dist/wallets/walletConnectors/roninWallet/roninWallet.js +2 -2
  227. package/dist/wallets/walletConnectors/safepalWallet/safepalWallet.js +2 -2
  228. package/dist/wallets/walletConnectors/subWallet/subWallet.js +2 -2
  229. package/dist/wallets/walletConnectors/tokenPocketWallet/tokenPocketWallet.js +2 -2
  230. package/dist/wallets/walletConnectors/trustWallet/trustWallet.js +2 -2
  231. package/dist/wallets/walletConnectors/zealWallet/zealWallet.js +2 -2
  232. package/dist/wallets/walletConnectors/zerionWallet/zerionWallet.js +2 -2
  233. package/package.json +2 -1
@@ -0,0 +1,1599 @@
1
+ "use client";
2
+ import {
3
+ getNetworkName
4
+ } from "./chunk-4PCVQBFZ.js";
5
+ import {
6
+ secure_default
7
+ } from "./chunk-ON4U54WO.js";
8
+ import {
9
+ getSolanaNetwork
10
+ } from "./chunk-O4AU63LK.js";
11
+ import {
12
+ calculateExpiryTimestamp,
13
+ createAbcError,
14
+ isTokenExpired,
15
+ loadFromStorage,
16
+ parseApiError,
17
+ removeFromStorage,
18
+ saveToStorage
19
+ } from "./chunk-BLEKTKBN.js";
20
+ import {
21
+ ABC_AUDIENCE,
22
+ ABC_ENDPOINTS,
23
+ DEFAULT_HEADERS,
24
+ REQUEST_TIMEOUT
25
+ } from "./chunk-OBS74J5N.js";
26
+
27
+ // src/wallets/walletConnectors/abcWallet/abcApi.ts
28
+ import { parseGwei } from "viem";
29
+ import { getAddress } from "viem";
30
+ var AbcWaasClient = class {
31
+ constructor(config) {
32
+ this.accessToken = null;
33
+ this.refreshToken = null;
34
+ this.expiresAt = null;
35
+ this.isRefreshing = false;
36
+ this.refreshPromise = null;
37
+ this.talkenAuthPath = "/api/v1/wallet/auth";
38
+ this.config = config;
39
+ this.baseURL = config.waasUrl;
40
+ this.secure = new secure_default(this.baseURL);
41
+ this.loadTokens();
42
+ }
43
+ getTalkenApiUrl() {
44
+ return process.env.NEXT_PUBLIC_API_SERVER || "https://dev.walletapi.talken.io";
45
+ }
46
+ async requestWalletAuth(body) {
47
+ const response = await fetch(`${this.getTalkenApiUrl()}${this.talkenAuthPath}`, {
48
+ method: "POST",
49
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
50
+ credentials: "include",
51
+ body: JSON.stringify(body)
52
+ });
53
+ const text = await response.text();
54
+ const data = text ? JSON.parse(text) : {};
55
+ if (!response.ok) {
56
+ throw parseApiError({
57
+ response: {
58
+ status: response.status,
59
+ data
60
+ }
61
+ });
62
+ }
63
+ return data;
64
+ }
65
+ /**
66
+ * Load tokens from storage
67
+ */
68
+ loadTokens() {
69
+ this.accessToken = loadFromStorage("access_token" /* ACCESS_TOKEN */);
70
+ this.refreshToken = loadFromStorage("refresh_token" /* REFRESH_TOKEN */);
71
+ this.expiresAt = loadFromStorage("expires_at" /* EXPIRES_AT */);
72
+ }
73
+ /**
74
+ * Save tokens to storage
75
+ */
76
+ saveTokens(accessToken, refreshToken, expiresIn) {
77
+ this.accessToken = accessToken;
78
+ this.refreshToken = refreshToken;
79
+ this.expiresAt = calculateExpiryTimestamp(expiresIn);
80
+ saveToStorage("access_token" /* ACCESS_TOKEN */, accessToken);
81
+ saveToStorage("refresh_token" /* REFRESH_TOKEN */, refreshToken);
82
+ saveToStorage("expires_at" /* EXPIRES_AT */, this.expiresAt);
83
+ }
84
+ /**
85
+ * Clear tokens
86
+ */
87
+ clearTokens() {
88
+ this.accessToken = null;
89
+ this.refreshToken = null;
90
+ this.expiresAt = null;
91
+ removeFromStorage("access_token" /* ACCESS_TOKEN */);
92
+ removeFromStorage("refresh_token" /* REFRESH_TOKEN */);
93
+ removeFromStorage("expires_at" /* EXPIRES_AT */);
94
+ }
95
+ /**
96
+ * Check if access token is expired
97
+ */
98
+ isTokenExpired() {
99
+ return isTokenExpired(this.expiresAt);
100
+ }
101
+ /**
102
+ * Get current access token
103
+ */
104
+ getAccessToken() {
105
+ return this.accessToken;
106
+ }
107
+ /**
108
+ * Refresh access token
109
+ */
110
+ async refreshAccessToken() {
111
+ if (this.isRefreshing) {
112
+ if (this.refreshPromise) {
113
+ await this.refreshPromise;
114
+ }
115
+ return;
116
+ }
117
+ if (!this.refreshToken) {
118
+ throw createAbcError(
119
+ "TOKEN_EXPIRED" /* TOKEN_EXPIRED */,
120
+ "No refresh token available"
121
+ );
122
+ }
123
+ this.isRefreshing = true;
124
+ this.refreshPromise = (async () => {
125
+ try {
126
+ const isIframe = typeof window !== "undefined" && window.self !== window.top;
127
+ const response = await this.requestWalletAuth({
128
+ action: "token.refresh",
129
+ refreshToken: this.refreshToken || "",
130
+ isIframe
131
+ });
132
+ const data = response?.data || {};
133
+ if (response?.success && data.access_token) {
134
+ const expiresIn = data.expires_in || data.expire_in || 3600;
135
+ this.saveTokens(
136
+ data.access_token,
137
+ data.refresh_token || this.refreshToken,
138
+ // Keep old if not provided
139
+ expiresIn
140
+ );
141
+ } else {
142
+ throw createAbcError(
143
+ "TOKEN_EXPIRED" /* TOKEN_EXPIRED */,
144
+ "Failed to refresh token"
145
+ );
146
+ }
147
+ } finally {
148
+ this.isRefreshing = false;
149
+ this.refreshPromise = null;
150
+ }
151
+ })();
152
+ await this.refreshPromise;
153
+ }
154
+ /**
155
+ * Make HTTP request
156
+ */
157
+ async request(endpoint, options = {}) {
158
+ const {
159
+ method = "GET",
160
+ body,
161
+ headers = {},
162
+ skipAuth = false,
163
+ isRetry = false
164
+ } = options;
165
+ if (!skipAuth && this.isTokenExpired() && this.refreshToken) {
166
+ await this.refreshAccessToken();
167
+ }
168
+ const url = `${this.baseURL}${endpoint}`;
169
+ const requestHeaders = {
170
+ ...DEFAULT_HEADERS,
171
+ ...headers
172
+ };
173
+ if (!skipAuth && this.accessToken) {
174
+ requestHeaders.Authorization = `Bearer ${this.accessToken}`;
175
+ }
176
+ if (this.config.apiKey) {
177
+ requestHeaders["X-API-Key"] = this.config.apiKey;
178
+ }
179
+ try {
180
+ const controller = new AbortController();
181
+ const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
182
+ const requestBody = body ? new URLSearchParams(body).toString() : void 0;
183
+ const response = await fetch(url, {
184
+ method,
185
+ headers: requestHeaders,
186
+ body: requestBody,
187
+ signal: controller.signal
188
+ });
189
+ clearTimeout(timeoutId);
190
+ const text = await response.text();
191
+ let data;
192
+ if (text) {
193
+ try {
194
+ data = JSON.parse(text);
195
+ } catch (parseError) {
196
+ console.error("[AbcWaasClient] \u274C JSON parse error:", {
197
+ url,
198
+ method,
199
+ status: response.status,
200
+ responseText: text.substring(0, 200)
201
+ // Log first 200 chars
202
+ });
203
+ throw createAbcError(
204
+ "UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
205
+ "Invalid JSON response from server",
206
+ { text, parseError }
207
+ );
208
+ }
209
+ } else {
210
+ console.log("[AbcWaasClient] \u2139\uFE0F Empty response received:", {
211
+ url,
212
+ method,
213
+ status: response.status
214
+ });
215
+ data = { status: "success" };
216
+ }
217
+ if (response.status === 401 && !skipAuth && this.refreshToken && !isRetry) {
218
+ try {
219
+ await this.refreshAccessToken();
220
+ return await this.request(endpoint, {
221
+ ...options,
222
+ isRetry: true
223
+ // Prevent infinite retry loop
224
+ });
225
+ } catch (refreshError) {
226
+ console.error("Token refresh failed:", refreshError);
227
+ throw parseApiError({
228
+ response: {
229
+ status: response.status,
230
+ data
231
+ }
232
+ });
233
+ }
234
+ }
235
+ if (!response.ok) {
236
+ console.error("[AbcWaasClient] \u274C API Error:", {
237
+ url,
238
+ method,
239
+ status: response.status,
240
+ statusText: response.statusText,
241
+ data
242
+ });
243
+ throw parseApiError({
244
+ response: {
245
+ status: response.status,
246
+ data
247
+ }
248
+ });
249
+ }
250
+ return data;
251
+ } catch (error) {
252
+ console.error("[AbcWaasClient] \u274C Request failed:", {
253
+ url,
254
+ method,
255
+ error: error.message,
256
+ errorName: error.name,
257
+ errorType: error.constructor.name,
258
+ stack: error.stack
259
+ });
260
+ if (error.name === "AbortError") {
261
+ throw createAbcError(
262
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
263
+ "Request timeout",
264
+ error
265
+ );
266
+ }
267
+ if (error.code && error.message) {
268
+ throw error;
269
+ }
270
+ throw parseApiError(error);
271
+ }
272
+ }
273
+ /**
274
+ * Login with email and password
275
+ * NOTE: Tokens are stored in memory only. Call persistTokens() after PIN verification to save to localStorage.
276
+ */
277
+ async loginWithEmail(email, password) {
278
+ const response = await this.request(
279
+ ABC_ENDPOINTS.SNS_LOGIN,
280
+ {
281
+ method: "POST",
282
+ body: {
283
+ email,
284
+ token: password,
285
+ // Use password as token
286
+ service: "email",
287
+ audience: ABC_AUDIENCE
288
+ },
289
+ skipAuth: true
290
+ }
291
+ );
292
+ if (response.status === "success" && response.data) {
293
+ this.accessToken = response.data.accessToken;
294
+ this.refreshToken = response.data.refreshToken;
295
+ this.expiresAt = calculateExpiryTimestamp(response.data.expiresIn);
296
+ console.log(
297
+ "[AbcWaasClient] \u2705 Login successful, tokens stored in memory (not persisted yet)"
298
+ );
299
+ return response.data;
300
+ }
301
+ throw createAbcError(
302
+ "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */,
303
+ "Email login failed",
304
+ response
305
+ );
306
+ }
307
+ /**
308
+ * Login with email and OTP (for PIN recovery)
309
+ * NOTE: Tokens are stored in memory only. Call persistTokens() after PIN verification to save to localStorage.
310
+ */
311
+ async loginWithOtp(email, otpCode) {
312
+ const response = await this.request(
313
+ ABC_ENDPOINTS.SNS_LOGIN,
314
+ {
315
+ method: "POST",
316
+ body: {
317
+ email,
318
+ token: otpCode,
319
+ service: "email",
320
+ audience: ABC_AUDIENCE
321
+ },
322
+ skipAuth: true
323
+ }
324
+ );
325
+ if (response.status === "success" && response.data) {
326
+ this.accessToken = response.data.accessToken;
327
+ this.refreshToken = response.data.refreshToken;
328
+ this.expiresAt = calculateExpiryTimestamp(response.data.expiresIn);
329
+ console.log(
330
+ "[AbcWaasClient] \u2705 OTP login successful, tokens stored in memory (not persisted yet)"
331
+ );
332
+ return response.data;
333
+ }
334
+ throw createAbcError(
335
+ "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */,
336
+ "OTP login failed",
337
+ response
338
+ );
339
+ }
340
+ /**
341
+ * Login with social provider
342
+ * NOTE: Tokens are stored in memory only. Call persistTokens() after PIN verification to save to localStorage.
343
+ */
344
+ async loginWithSocial(provider, token, email) {
345
+ const response = await this.request(
346
+ ABC_ENDPOINTS.SNS_LOGIN,
347
+ {
348
+ method: "POST",
349
+ body: {
350
+ token,
351
+ service: provider,
352
+ audience: ABC_AUDIENCE,
353
+ email
354
+ },
355
+ skipAuth: true
356
+ }
357
+ );
358
+ if (response.status === "success" && response.data) {
359
+ this.accessToken = response.data.accessToken;
360
+ this.refreshToken = response.data.refreshToken;
361
+ this.expiresAt = calculateExpiryTimestamp(response.data.expiresIn);
362
+ console.log(
363
+ "[AbcWaasClient] \u2705 Social login successful, tokens stored in memory (not persisted yet)"
364
+ );
365
+ return response.data;
366
+ }
367
+ throw createAbcError(
368
+ "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */,
369
+ "Social login failed",
370
+ response
371
+ );
372
+ }
373
+ /**
374
+ * Refresh access token using refresh token (public wrapper)
375
+ */
376
+ async refreshTokens(refreshTokenValue) {
377
+ const oldRefreshToken = this.refreshToken;
378
+ this.refreshToken = refreshTokenValue;
379
+ try {
380
+ await this.refreshAccessToken();
381
+ return {
382
+ accessToken: this.accessToken,
383
+ refreshToken: this.refreshToken,
384
+ expiresIn: Math.floor((this.expiresAt - Date.now()) / 1e3)
385
+ };
386
+ } catch (error) {
387
+ this.refreshToken = oldRefreshToken;
388
+ throw error;
389
+ }
390
+ }
391
+ /**
392
+ * Request OTP code for email
393
+ */
394
+ async requestOtpCode(email) {
395
+ const response = await this.request(
396
+ ABC_ENDPOINTS.SEND_OTP,
397
+ {
398
+ method: "POST",
399
+ body: { email },
400
+ skipAuth: true
401
+ }
402
+ );
403
+ if (response.status === "success" && response.data) {
404
+ return response.data;
405
+ }
406
+ throw createAbcError(
407
+ "UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
408
+ "Failed to request OTP",
409
+ response
410
+ );
411
+ }
412
+ /**
413
+ * Verify OTP code
414
+ */
415
+ async verifyOtpCode(email, code) {
416
+ const response = await this.request(ABC_ENDPOINTS.VERIFY_OTP, {
417
+ method: "POST",
418
+ body: { email, code },
419
+ skipAuth: true
420
+ });
421
+ return response.status === "success";
422
+ }
423
+ /**
424
+ * Check if email already exists
425
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:63-69
426
+ */
427
+ async emailCheck(email) {
428
+ const result = await this.requestWalletAuth({
429
+ action: "email.check",
430
+ email
431
+ });
432
+ return result?.data || result;
433
+ }
434
+ /**
435
+ * Send OTP code to email for signup
436
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:105-110
437
+ * Note: Uses ABC WaaS endpoint, not Talken API
438
+ */
439
+ async sendOtpCode(email) {
440
+ const result = await this.requestWalletAuth({
441
+ action: "otp.send",
442
+ email
443
+ });
444
+ return result?.data || result;
445
+ }
446
+ /**
447
+ * Verify OTP code for signup
448
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:112-123
449
+ * Note: Uses ABC WaaS endpoint, not Talken API
450
+ */
451
+ async verifyOtpCodeSignup(email, code) {
452
+ const result = await this.requestWalletAuth({
453
+ action: "otp.verify",
454
+ email,
455
+ otpCode: code
456
+ });
457
+ return result?.data || result;
458
+ }
459
+ /**
460
+ * SNS (Social) Login via Google/Apple/Kakao
461
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:43-51
462
+ * Note: Uses Talken API server, not ABC WaaS
463
+ */
464
+ async snsLogin(params) {
465
+ try {
466
+ const result = await this.requestWalletAuth({
467
+ action: "login",
468
+ method: "sns",
469
+ token: params.token,
470
+ service: params.service,
471
+ audience: params.audience
472
+ });
473
+ const data = result?.data || {};
474
+ if (!data.access_token) {
475
+ throw createAbcError(
476
+ "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */,
477
+ "SNS login failed: Invalid response from server",
478
+ { service: params.service, response: data }
479
+ );
480
+ }
481
+ console.log("[AbcWaasClient] \u2705 SNS login successful");
482
+ return {
483
+ uid: "",
484
+ // Will be fetched later via info() API
485
+ email: params.email,
486
+ access_token: data.access_token,
487
+ refresh_token: data.refresh_token,
488
+ user_type: "existing"
489
+ // Default to existing, will be determined later
490
+ };
491
+ } catch (error) {
492
+ if (error.name === "AbortError") {
493
+ throw createAbcError(
494
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
495
+ "SNS login request timeout",
496
+ error
497
+ );
498
+ }
499
+ throw error;
500
+ }
501
+ }
502
+ /**
503
+ * Register new user
504
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:71-78
505
+ * Note: Uses Talken API server, not ABC WaaS
506
+ */
507
+ async registerUser(params) {
508
+ const result = await this.requestWalletAuth({
509
+ action: "register",
510
+ email: params.username,
511
+ otpCode: params.emailCode,
512
+ password: params.password,
513
+ name: params.name
514
+ });
515
+ return result?.data || result;
516
+ }
517
+ /**
518
+ * Register new SNS user (email-based registration with OTP)
519
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:80-87
520
+ * Note: Uses Talken API server, not ABC WaaS
521
+ */
522
+ async registerSnsUser(params) {
523
+ const talkenApiUrl = this.getTalkenApiUrl();
524
+ const response = await fetch(`${talkenApiUrl}/abc/snsAdduser`, {
525
+ method: "POST",
526
+ headers: {
527
+ ...DEFAULT_HEADERS
528
+ },
529
+ credentials: "include",
530
+ body: new URLSearchParams(params).toString()
531
+ });
532
+ const text = await response.text();
533
+ const data = text ? JSON.parse(text) : { status: "success" };
534
+ if (!response.ok) {
535
+ throw parseApiError({
536
+ response: {
537
+ status: response.status,
538
+ data
539
+ }
540
+ });
541
+ }
542
+ return data;
543
+ }
544
+ /**
545
+ * Reset/Set password for existing user
546
+ * Reference: tg-wallet-frontend src/features/user/api/index.ts:89-95
547
+ * Note: Uses Talken API server, not ABC WaaS
548
+ */
549
+ async resetPassword(params) {
550
+ const result = await this.requestWalletAuth({
551
+ action: "password.reset",
552
+ email: params.username,
553
+ newPassword: params.password,
554
+ emailCode: params.emailCode
555
+ });
556
+ return result?.data || result;
557
+ }
558
+ /**
559
+ * Generate or recover wallet
560
+ */
561
+ async generateOrRecoverWallet(params) {
562
+ const response = await this.request(
563
+ // Use 'any' to get raw API response
564
+ ABC_ENDPOINTS.MPC_WALLETS,
565
+ // Use correct EVM endpoint, not WALLETS_V3 (Solana only)
566
+ {
567
+ method: "POST",
568
+ body: {
569
+ uid: params.uid,
570
+ pin: params.pin,
571
+ chainId: params.chainId,
572
+ network: params.network || "mainnet"
573
+ }
574
+ }
575
+ );
576
+ if (response.status === "success" && response.data) {
577
+ const raw = response.data;
578
+ console.log("[AbcWaasClient] Raw wallet API response:", {
579
+ hasUid: !!raw.uid,
580
+ hasSid: !!raw.sid,
581
+ hasKeyId: !!raw.key_id,
582
+ hasWid: !!raw.wid,
583
+ hasPvencstr: !!raw.pvencstr,
584
+ hasEncryptDevicePassword: !!raw.encryptDevicePassword,
585
+ hasEncryptedShare: !!raw.encrypted_share,
586
+ hasPubkey: !!raw.pubkey,
587
+ allKeys: Object.keys(raw)
588
+ });
589
+ return {
590
+ address: raw.sid || "",
591
+ // FIX: sid is the EVM address
592
+ keyId: raw.key_id || raw.keyId || raw.sid,
593
+ encryptedShare: raw.encrypted_share || raw.key_id || "",
594
+ // Use key_id as fallback
595
+ uid: raw.uid,
596
+ sid: raw.sid,
597
+ wid: raw.wid,
598
+ // Preserve for Bitcoin signing
599
+ pvencstr: raw.pvencstr,
600
+ // Preserve for Bitcoin signing
601
+ encryptDevicePassword: raw.encryptDevicePassword,
602
+ // Preserve for Bitcoin signing
603
+ pubkey: raw.pubkey || null
604
+ };
605
+ }
606
+ throw createAbcError(
607
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
608
+ "Failed to generate wallet",
609
+ response
610
+ );
611
+ }
612
+ /**
613
+ * Sign EVM transaction (EIP-1559)
614
+ * Based on ABC WaaS official documentation
615
+ */
616
+ async signTransaction(params) {
617
+ this.loadTokens();
618
+ const wallet = loadFromStorage("wallet" /* WALLET */);
619
+ if (!wallet) {
620
+ throw createAbcError(
621
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
622
+ "Wallet information not found in storage"
623
+ );
624
+ }
625
+ const encryptedDevicePassword = await this.secure.getEncryptPlain(
626
+ wallet.encryptDevicePassword
627
+ );
628
+ const encryptedPvencstr = await this.secure.getEncryptPlain(
629
+ wallet.pvencstr
630
+ );
631
+ const encryptedWid = await this.secure.getEncryptPlain(wallet.wid);
632
+ const secureChannelId = await this.secure.getSecureChannelId();
633
+ const network = getNetworkName(params.chainId);
634
+ const tx = params.transaction;
635
+ if (!tx.maxFeePerGas || !tx.maxPriorityFeePerGas || !tx.gasLimit || !tx.gas) {
636
+ try {
637
+ if (!tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {
638
+ const gasFeeUrl = `${this.baseURL}${ABC_ENDPOINTS.GAS_SUGGESTED_FEES}?network=${network}`;
639
+ const gasFeeResponse = await fetch(gasFeeUrl, {
640
+ method: "GET",
641
+ headers: {
642
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
643
+ }
644
+ });
645
+ if (gasFeeResponse.ok) {
646
+ const gasData = await gasFeeResponse.json();
647
+ if (gasData.medium) {
648
+ if (!tx.maxFeePerGas) {
649
+ tx.maxFeePerGas = parseGwei(
650
+ gasData.medium.suggestedMaxFeePerGas
651
+ ).toString();
652
+ }
653
+ if (!tx.maxPriorityFeePerGas) {
654
+ tx.maxPriorityFeePerGas = parseGwei(
655
+ gasData.medium.suggestedMaxPriorityFeePerGas
656
+ ).toString();
657
+ }
658
+ }
659
+ }
660
+ }
661
+ if (!tx.gasLimit && !tx.gas) {
662
+ const estimateBody = new URLSearchParams({
663
+ network,
664
+ to: tx.to || "0x",
665
+ // Use '0x' for contract deployment
666
+ ...tx.from ? { from: tx.from } : {},
667
+ ...tx.value ? { value: tx.value } : {},
668
+ ...tx.data && tx.data !== "0x" ? { data: tx.data } : {},
669
+ ...tx.maxFeePerGas ? { maxFeePerGas: tx.maxFeePerGas } : {},
670
+ ...tx.maxPriorityFeePerGas ? { maxPriorityFeePerGas: tx.maxPriorityFeePerGas } : {}
671
+ });
672
+ const estimateUrl = `${this.baseURL}${ABC_ENDPOINTS.GAS_ESTIMATE_EIP1559}`;
673
+ const estimateResponse = await fetch(estimateUrl, {
674
+ method: "POST",
675
+ headers: {
676
+ "Content-Type": "application/x-www-form-urlencoded",
677
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
678
+ },
679
+ body: estimateBody.toString()
680
+ });
681
+ const estimateData = await estimateResponse.json();
682
+ if (estimateResponse.ok && estimateData.result) {
683
+ tx.gasLimit = estimateData.result;
684
+ } else {
685
+ const fallbackGasLimit = "0x2dc6c0";
686
+ tx.gasLimit = fallbackGasLimit;
687
+ }
688
+ }
689
+ } catch (error) {
690
+ console.warn("Failed to fetch gas parameters from ABC WaaS:", error);
691
+ }
692
+ }
693
+ const bodyData = {
694
+ network,
695
+ encryptDevicePassword: encryptedDevicePassword,
696
+ pvencstr: encryptedPvencstr,
697
+ uid: wallet.uid,
698
+ wid: encryptedWid,
699
+ sid: getAddress(wallet.address),
700
+ // EIP-55 checksum format
701
+ // For contract deployment, 'to' is '0x' (ABC WaaS convention)
702
+ // Reference: talken-nft-drops/src/libs/abc-waas-provider/index.ts:800 - to: to ?? '0x'
703
+ to: tx.to === "0x" ? "0x" : getAddress(tx.to),
704
+ // Required by ABC WaaS API
705
+ // Always use EIP1559 type (ABC WaaS handles network-specific conversion)
706
+ type: "EIP1559",
707
+ // ourpubkey and ucpubkey are required by ABC WaaS (empty strings for now)
708
+ // Based on successful tg-wallet payload analysis
709
+ ourpubkey: "",
710
+ ucpubkey: ""
711
+ };
712
+ bodyData.from = getAddress(tx.from || wallet.address);
713
+ if (tx.value) {
714
+ let hexValue = tx.value.startsWith("0x") ? tx.value.slice(2) : tx.value;
715
+ if (hexValue.length % 2 !== 0) {
716
+ hexValue = `0${hexValue}`;
717
+ }
718
+ bodyData.value = `0x${hexValue}`;
719
+ } else {
720
+ bodyData.value = "0x0";
721
+ }
722
+ if (tx.gasLimit || tx.gas) {
723
+ const gasLimitValue = tx.gasLimit || tx.gas;
724
+ if (gasLimitValue.toString().startsWith("0x")) {
725
+ bodyData.gasLimit = gasLimitValue.toString();
726
+ } else {
727
+ bodyData.gasLimit = `0x${BigInt(gasLimitValue).toString(16)}`;
728
+ }
729
+ }
730
+ if (tx.maxFeePerGas) {
731
+ if (tx.maxFeePerGas.toString().startsWith("0x")) {
732
+ bodyData.maxFeePerGas = tx.maxFeePerGas.toString();
733
+ } else {
734
+ bodyData.maxFeePerGas = `0x${BigInt(tx.maxFeePerGas).toString(16)}`;
735
+ }
736
+ }
737
+ if (tx.maxPriorityFeePerGas) {
738
+ if (tx.maxPriorityFeePerGas.toString().startsWith("0x")) {
739
+ bodyData.maxPriorityFeePerGas = tx.maxPriorityFeePerGas.toString();
740
+ } else {
741
+ bodyData.maxPriorityFeePerGas = `0x${BigInt(tx.maxPriorityFeePerGas).toString(16)}`;
742
+ }
743
+ }
744
+ if (tx.gasPrice) {
745
+ if (tx.gasPrice.toString().startsWith("0x")) {
746
+ bodyData.gasPrice = tx.gasPrice.toString();
747
+ } else {
748
+ bodyData.gasPrice = `0x${BigInt(tx.gasPrice).toString(16)}`;
749
+ }
750
+ }
751
+ if (tx.data !== void 0 && tx.data !== null) {
752
+ bodyData.data = tx.data || "0x";
753
+ } else {
754
+ bodyData.data = "0x";
755
+ }
756
+ const bodyString = new URLSearchParams(bodyData).toString();
757
+ const url = `${this.baseURL}${ABC_ENDPOINTS.SIGN_TRANSACTION}`;
758
+ const response = await fetch(url, {
759
+ method: "POST",
760
+ headers: {
761
+ "Content-Type": "application/x-www-form-urlencoded",
762
+ "Secure-Channel": secureChannelId,
763
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
764
+ },
765
+ body: bodyString
766
+ });
767
+ const res = await response.json();
768
+ console.log("\u{1F4E1} ABC WaaS /sign response:", {
769
+ status: response.status,
770
+ ok: response.ok,
771
+ response: res
772
+ });
773
+ if (!response.ok) {
774
+ console.error("\u274C ABC WaaS API error details:", {
775
+ status: response.status,
776
+ statusText: response.statusText,
777
+ errorCode: res.code,
778
+ errorMessage: res.msg || res.message || res.detail,
779
+ fullResponse: res
780
+ });
781
+ }
782
+ if (response.status === 401 && this.refreshToken) {
783
+ try {
784
+ await this.refreshAccessToken();
785
+ const retryResponse = await fetch(url, {
786
+ method: "POST",
787
+ headers: {
788
+ "Content-Type": "application/x-www-form-urlencoded",
789
+ "Secure-Channel": secureChannelId,
790
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
791
+ },
792
+ body: bodyString
793
+ });
794
+ const retryRes = await retryResponse.json();
795
+ if (retryRes.serializedTx && retryRes.rawTx) {
796
+ return {
797
+ signature: retryRes.serializedTx,
798
+ txHash: retryRes.rawTx
799
+ };
800
+ }
801
+ throw createAbcError(
802
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
803
+ "Failed to sign transaction after token refresh",
804
+ retryRes
805
+ );
806
+ } catch (refreshError) {
807
+ console.error("Token refresh failed in signTransaction:", refreshError);
808
+ throw refreshError;
809
+ }
810
+ }
811
+ if (res.serializedTx && res.rawTx) {
812
+ return {
813
+ signature: res.serializedTx,
814
+ txHash: res.rawTx
815
+ };
816
+ }
817
+ throw createAbcError(
818
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
819
+ "Failed to sign transaction",
820
+ res
821
+ );
822
+ }
823
+ /**
824
+ * Sign message (Personal Sign - EIP-191)
825
+ * Based on tg-wallet-frontend reference implementation
826
+ */
827
+ async signMessage(params) {
828
+ this.loadTokens();
829
+ const wallet = loadFromStorage("wallet" /* WALLET */);
830
+ if (!wallet) {
831
+ throw createAbcError(
832
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
833
+ "Wallet information not found in storage"
834
+ );
835
+ }
836
+ const ethers = await import("ethers");
837
+ const messageHash = ethers.utils.hashMessage(params.message);
838
+ const hash = messageHash.startsWith("0x") ? messageHash.slice(2) : messageHash;
839
+ const encryptedDevicePassword = await this.secure.getEncryptPlain(
840
+ wallet.encryptDevicePassword
841
+ );
842
+ const encryptedPvencstr = await this.secure.getEncryptPlain(
843
+ wallet.pvencstr
844
+ );
845
+ const encryptedWid = await this.secure.getEncryptPlain(wallet.wid);
846
+ const secureChannelId = await this.secure.getSecureChannelId();
847
+ const bodyData = {
848
+ hash,
849
+ encryptDevicePassword: encryptedDevicePassword,
850
+ pvencstr: encryptedPvencstr,
851
+ wid: encryptedWid,
852
+ uid: wallet.uid,
853
+ sid: wallet.sid
854
+ };
855
+ const bodyString = new URLSearchParams(bodyData).toString();
856
+ const url = `${this.baseURL}${ABC_ENDPOINTS.SIGN_HASH}`;
857
+ const response = await fetch(url, {
858
+ method: "POST",
859
+ headers: {
860
+ "Content-Type": "application/x-www-form-urlencoded",
861
+ "Secure-Channel": secureChannelId,
862
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
863
+ },
864
+ body: bodyString
865
+ });
866
+ const text = await response.text();
867
+ if (!text) {
868
+ throw createAbcError(
869
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
870
+ `Empty response from sign API (status: ${response.status})`,
871
+ { status: response.status }
872
+ );
873
+ }
874
+ const res = JSON.parse(text);
875
+ if (response.status === 401) {
876
+ if (!this.refreshToken) {
877
+ this.loadTokens();
878
+ }
879
+ if (this.refreshToken) {
880
+ try {
881
+ await this.refreshAccessToken();
882
+ const retryResponse = await fetch(url, {
883
+ method: "POST",
884
+ headers: {
885
+ "Content-Type": "application/x-www-form-urlencoded",
886
+ "Secure-Channel": secureChannelId,
887
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
888
+ },
889
+ body: bodyString
890
+ });
891
+ const retryText = await retryResponse.text();
892
+ if (!retryText) {
893
+ throw createAbcError(
894
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
895
+ `Empty response from retry (status: ${retryResponse.status})`,
896
+ { status: retryResponse.status }
897
+ );
898
+ }
899
+ const retryRes = JSON.parse(retryText);
900
+ if (retryRes.status === "success" && retryRes.result?.signstr) {
901
+ return { signature: retryRes.result.signstr };
902
+ }
903
+ throw createAbcError(
904
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
905
+ "Failed to sign message after token refresh",
906
+ retryRes
907
+ );
908
+ } catch (refreshError) {
909
+ console.error("Token refresh failed in signMessage:", refreshError);
910
+ throw refreshError;
911
+ }
912
+ }
913
+ }
914
+ if (res.signstr) {
915
+ const signData = JSON.parse(res.signstr);
916
+ const sigList = signData.sig_list?.[0];
917
+ if (!sigList || !sigList.r || !sigList.s) {
918
+ throw createAbcError(
919
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
920
+ "Invalid signature format",
921
+ res
922
+ );
923
+ }
924
+ const v = (sigList.vsource || 0) + 27;
925
+ const signature = sigList.r + sigList.s.slice(2) + v.toString(16).padStart(2, "0");
926
+ return { signature };
927
+ }
928
+ throw createAbcError(
929
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
930
+ "Failed to sign message",
931
+ res
932
+ );
933
+ }
934
+ /**
935
+ * Sign typed data (EIP-712)
936
+ * Reference: tg-wallet-frontend src/features/wallet/api/index.ts sign_typed_data()
937
+ */
938
+ async signTypedData(params) {
939
+ this.loadTokens();
940
+ const wallet = loadFromStorage("wallet" /* WALLET */);
941
+ if (!wallet) {
942
+ throw createAbcError(
943
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
944
+ "Wallet information not found in storage"
945
+ );
946
+ }
947
+ const encryptedDevicePassword = await this.secure.getEncryptPlain(
948
+ wallet.encryptDevicePassword
949
+ );
950
+ const encryptedPvencstr = await this.secure.getEncryptPlain(
951
+ wallet.pvencstr
952
+ );
953
+ const encryptedWid = await this.secure.getEncryptPlain(wallet.wid);
954
+ const secureChannelId = await this.secure.getSecureChannelId();
955
+ const network = getNetworkName(wallet.chainId);
956
+ const bodyData = {
957
+ messageJson: params.typedData,
958
+ // Server expects "messageJson" field
959
+ version: "v4",
960
+ // EIP-712 version
961
+ network,
962
+ // Network name (required for JSON-RPC)
963
+ encryptDevicePassword: encryptedDevicePassword,
964
+ pvencstr: encryptedPvencstr,
965
+ wid: encryptedWid,
966
+ uid: wallet.uid,
967
+ sid: wallet.sid
968
+ };
969
+ const bodyString = new URLSearchParams(bodyData).toString();
970
+ const url = `${this.baseURL}${ABC_ENDPOINTS.SIGN_TYPED}`;
971
+ const response = await fetch(url, {
972
+ method: "POST",
973
+ headers: {
974
+ "Content-Type": "application/x-www-form-urlencoded",
975
+ "Secure-Channel": secureChannelId,
976
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
977
+ },
978
+ body: bodyString
979
+ });
980
+ const text = await response.text();
981
+ if (!text) {
982
+ throw createAbcError(
983
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
984
+ `Empty response from signTypedData API (status: ${response.status})`,
985
+ { status: response.status }
986
+ );
987
+ }
988
+ const res = JSON.parse(text);
989
+ if (response.status === 401 && this.refreshToken) {
990
+ try {
991
+ await this.refreshAccessToken();
992
+ const retryResponse = await fetch(url, {
993
+ method: "POST",
994
+ headers: {
995
+ "Content-Type": "application/x-www-form-urlencoded",
996
+ "Secure-Channel": secureChannelId,
997
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
998
+ },
999
+ body: bodyString
1000
+ });
1001
+ const retryText = await retryResponse.text();
1002
+ if (!retryText) {
1003
+ throw createAbcError(
1004
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
1005
+ `Empty response after retry (status: ${retryResponse.status})`,
1006
+ { status: retryResponse.status }
1007
+ );
1008
+ }
1009
+ const retryRes = JSON.parse(retryText);
1010
+ if (retryRes.serializedTx) {
1011
+ return { signature: retryRes.serializedTx };
1012
+ }
1013
+ throw createAbcError(
1014
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
1015
+ "Failed to sign typed data after token refresh",
1016
+ retryRes
1017
+ );
1018
+ } catch (refreshError) {
1019
+ console.error("Token refresh failed in signTypedData:", refreshError);
1020
+ throw refreshError;
1021
+ }
1022
+ }
1023
+ if (res.serializedTx) {
1024
+ return { signature: res.serializedTx };
1025
+ }
1026
+ throw createAbcError(
1027
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
1028
+ "Failed to sign typed data",
1029
+ res
1030
+ );
1031
+ }
1032
+ /**
1033
+ * Send raw transaction
1034
+ * Reference: tg-wallet-frontend src/features/wallet/api/index.ts sendRawTx()
1035
+ */
1036
+ async sendRawTransaction(chainId, signedTransaction) {
1037
+ const wallet = loadFromStorage("wallet" /* WALLET */);
1038
+ if (!wallet) {
1039
+ throw createAbcError(
1040
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1041
+ "Wallet information not found in storage"
1042
+ );
1043
+ }
1044
+ const network = getNetworkName(chainId);
1045
+ const secureChannelId = await this.secure.getSecureChannelId();
1046
+ const bodyData = {
1047
+ signedSerializeTx: signedTransaction,
1048
+ network
1049
+ // rpc parameter
1050
+ };
1051
+ const bodyString = new URLSearchParams(bodyData).toString();
1052
+ const url = `${this.baseURL}${ABC_ENDPOINTS.SEND_RAW_TX}`;
1053
+ const response = await fetch(url, {
1054
+ method: "POST",
1055
+ headers: {
1056
+ "Content-Type": "application/x-www-form-urlencoded",
1057
+ "Secure-Channel": secureChannelId,
1058
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1059
+ },
1060
+ body: bodyString
1061
+ });
1062
+ const text = await response.text();
1063
+ if (!text) {
1064
+ throw createAbcError(
1065
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1066
+ `Empty response from sendRawTx API (status: ${response.status})`,
1067
+ { status: response.status }
1068
+ );
1069
+ }
1070
+ const res = JSON.parse(text);
1071
+ console.log("\u{1F4E1} sendRawTransaction response:", {
1072
+ status: response.status,
1073
+ ok: response.ok,
1074
+ response: res
1075
+ });
1076
+ if (!response.ok) {
1077
+ console.error("\u274C sendRawTransaction error:", {
1078
+ status: response.status,
1079
+ errorMessage: res.errorMessage || res.msg || res.message,
1080
+ fullResponse: res
1081
+ });
1082
+ }
1083
+ if (response.status === 401 && this.refreshToken) {
1084
+ try {
1085
+ await this.refreshAccessToken();
1086
+ const retryResponse = await fetch(url, {
1087
+ method: "POST",
1088
+ headers: {
1089
+ "Content-Type": "application/x-www-form-urlencoded",
1090
+ "Secure-Channel": secureChannelId,
1091
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1092
+ },
1093
+ body: bodyString
1094
+ });
1095
+ const retryText = await retryResponse.text();
1096
+ if (!retryText) {
1097
+ throw createAbcError(
1098
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1099
+ `Empty response after retry (status: ${retryResponse.status})`,
1100
+ { status: retryResponse.status }
1101
+ );
1102
+ }
1103
+ const retryRes = JSON.parse(retryText);
1104
+ if (retryRes.item || retryRes.txHash || retryRes.result?.txHash) {
1105
+ const txHash = retryRes.item || retryRes.txHash || retryRes.result.txHash;
1106
+ return { txHash };
1107
+ }
1108
+ throw createAbcError(
1109
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1110
+ "Failed to send transaction after token refresh",
1111
+ retryRes
1112
+ );
1113
+ } catch (refreshError) {
1114
+ console.error(
1115
+ "Token refresh failed in sendRawTransaction:",
1116
+ refreshError
1117
+ );
1118
+ throw refreshError;
1119
+ }
1120
+ }
1121
+ if (res.result) {
1122
+ if (typeof res.result === "string") {
1123
+ console.log("\u2705 Transaction hash from result:", res.result);
1124
+ return { txHash: res.result };
1125
+ }
1126
+ if (res.result.txHash) {
1127
+ return { txHash: res.result.txHash };
1128
+ }
1129
+ }
1130
+ if (res.item) {
1131
+ return { txHash: res.item };
1132
+ }
1133
+ if (res.txHash) {
1134
+ return { txHash: res.txHash };
1135
+ }
1136
+ throw createAbcError(
1137
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1138
+ "Failed to send transaction",
1139
+ res
1140
+ );
1141
+ }
1142
+ /**
1143
+ * Estimate gas for EIP-1559 transaction
1144
+ * Reference: ABC WaaS API docs - /wapi/v2/gas/estimate/eip1559
1145
+ */
1146
+ async estimateGas(params) {
1147
+ const network = getNetworkName(params.chainId);
1148
+ const secureChannelId = await this.secure.getSecureChannelId();
1149
+ const bodyData = {
1150
+ network,
1151
+ to: params.to
1152
+ };
1153
+ if (params.from)
1154
+ bodyData.from = params.from;
1155
+ if (params.value)
1156
+ bodyData.value = params.value;
1157
+ if (params.data)
1158
+ bodyData.data = params.data;
1159
+ const bodyString = new URLSearchParams(bodyData).toString();
1160
+ const url = `${this.baseURL}${ABC_ENDPOINTS.GAS_ESTIMATE_EIP1559}`;
1161
+ const response = await fetch(url, {
1162
+ method: "POST",
1163
+ headers: {
1164
+ "Content-Type": "application/x-www-form-urlencoded",
1165
+ "Secure-Channel": secureChannelId,
1166
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1167
+ },
1168
+ body: bodyString
1169
+ });
1170
+ const text = await response.text();
1171
+ if (!text) {
1172
+ throw createAbcError(
1173
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1174
+ `Empty response from gas estimation API (status: ${response.status})`,
1175
+ { status: response.status }
1176
+ );
1177
+ }
1178
+ const res = JSON.parse(text);
1179
+ console.log("\u{1F4E1} estimateGas response:", {
1180
+ status: response.status,
1181
+ ok: response.ok,
1182
+ network,
1183
+ params,
1184
+ response: res
1185
+ });
1186
+ if (response.status === 401 && this.refreshToken) {
1187
+ try {
1188
+ await this.refreshAccessToken();
1189
+ const retryResponse = await fetch(url, {
1190
+ method: "POST",
1191
+ headers: {
1192
+ "Content-Type": "application/x-www-form-urlencoded",
1193
+ "Secure-Channel": secureChannelId,
1194
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1195
+ },
1196
+ body: bodyString
1197
+ });
1198
+ const retryText = await retryResponse.text();
1199
+ if (!retryText) {
1200
+ throw createAbcError(
1201
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1202
+ `Empty response after retry (status: ${retryResponse.status})`,
1203
+ { status: retryResponse.status }
1204
+ );
1205
+ }
1206
+ const retryRes = JSON.parse(retryText);
1207
+ if (retryRes.result) {
1208
+ return retryRes.result;
1209
+ }
1210
+ throw createAbcError(
1211
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1212
+ "Failed to estimate gas after token refresh",
1213
+ retryRes
1214
+ );
1215
+ } catch (refreshError) {
1216
+ console.error("Token refresh failed in estimateGas:", refreshError);
1217
+ throw refreshError;
1218
+ }
1219
+ }
1220
+ if (res.result) {
1221
+ return res.result;
1222
+ }
1223
+ console.error("\u274C estimateGas failed:", {
1224
+ status: response.status,
1225
+ network,
1226
+ errorMessage: res.errorMessage || res.msg || res.message,
1227
+ fullResponse: res
1228
+ });
1229
+ throw createAbcError(
1230
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1231
+ res.errorMessage || res.msg || "Failed to estimate gas",
1232
+ res
1233
+ );
1234
+ }
1235
+ /**
1236
+ * Get transaction count (nonce)
1237
+ * Reference: ABC WaaS API - /wapi/v2/transactions/count
1238
+ */
1239
+ async getTransactionCount(params) {
1240
+ const network = getNetworkName(params.chainId);
1241
+ const secureChannelId = await this.secure.getSecureChannelId();
1242
+ const bodyData = {
1243
+ network,
1244
+ address: params.address
1245
+ };
1246
+ const bodyString = new URLSearchParams(bodyData).toString();
1247
+ const url = `${this.baseURL}${ABC_ENDPOINTS.TRANSACTION_COUNT}`;
1248
+ const response = await fetch(url, {
1249
+ method: "POST",
1250
+ headers: {
1251
+ "Content-Type": "application/x-www-form-urlencoded",
1252
+ "Secure-Channel": secureChannelId,
1253
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1254
+ },
1255
+ body: bodyString
1256
+ });
1257
+ const text = await response.text();
1258
+ if (!text) {
1259
+ throw createAbcError(
1260
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1261
+ `Empty response from transaction count API (status: ${response.status})`,
1262
+ { status: response.status }
1263
+ );
1264
+ }
1265
+ const res = JSON.parse(text);
1266
+ if (response.status === 401 && this.refreshToken) {
1267
+ try {
1268
+ await this.refreshAccessToken();
1269
+ const retryResponse = await fetch(url, {
1270
+ method: "POST",
1271
+ headers: {
1272
+ "Content-Type": "application/x-www-form-urlencoded",
1273
+ "Secure-Channel": secureChannelId,
1274
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1275
+ },
1276
+ body: bodyString
1277
+ });
1278
+ const retryText = await retryResponse.text();
1279
+ if (!retryText) {
1280
+ throw createAbcError(
1281
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1282
+ `Empty response after retry (status: ${retryResponse.status})`,
1283
+ { status: retryResponse.status }
1284
+ );
1285
+ }
1286
+ const retryRes = JSON.parse(retryText);
1287
+ if (retryRes.result !== void 0) {
1288
+ return typeof retryRes.result === "number" ? `0x${retryRes.result.toString(16)}` : retryRes.result;
1289
+ }
1290
+ throw createAbcError(
1291
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1292
+ "Failed to get transaction count after token refresh",
1293
+ retryRes
1294
+ );
1295
+ } catch (refreshError) {
1296
+ console.error(
1297
+ "Token refresh failed in getTransactionCount:",
1298
+ refreshError
1299
+ );
1300
+ throw refreshError;
1301
+ }
1302
+ }
1303
+ if (res.result !== void 0) {
1304
+ return typeof res.result === "number" ? `0x${res.result.toString(16)}` : res.result;
1305
+ }
1306
+ throw createAbcError(
1307
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1308
+ res.errorMessage || res.msg || "Failed to get transaction count",
1309
+ res
1310
+ );
1311
+ }
1312
+ /**
1313
+ * Get wallet info
1314
+ */
1315
+ async getWalletInfo(uid) {
1316
+ const response = await this.request(ABC_ENDPOINTS.INFO, {
1317
+ method: "POST",
1318
+ body: { uid }
1319
+ });
1320
+ if (response.status === "success") {
1321
+ return response.data;
1322
+ }
1323
+ throw createAbcError(
1324
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1325
+ "Failed to get wallet info",
1326
+ response
1327
+ );
1328
+ }
1329
+ /**
1330
+ * Logout (clear tokens)
1331
+ */
1332
+ async logout() {
1333
+ this.clearTokens();
1334
+ }
1335
+ /**
1336
+ * Check if user is authenticated
1337
+ */
1338
+ isAuthenticated() {
1339
+ return !!this.accessToken && !this.isTokenExpired();
1340
+ }
1341
+ /**
1342
+ * Set tokens in client instance (useful when restoring from storage or state)
1343
+ * Call this before persistTokens() if you need to set tokens from external source
1344
+ */
1345
+ setTokens(accessToken, refreshToken, expiresAt) {
1346
+ this.accessToken = accessToken;
1347
+ this.refreshToken = refreshToken;
1348
+ this.expiresAt = expiresAt;
1349
+ }
1350
+ /**
1351
+ * Persist tokens to localStorage
1352
+ * Call this after PIN verification is complete
1353
+ *
1354
+ * SECURITY NOTE: This should only be called after full authentication (password + PIN)
1355
+ * to ensure tokens are only persisted after the user has proven ownership of both credentials.
1356
+ */
1357
+ persistTokens() {
1358
+ if (!this.accessToken || !this.refreshToken || !this.expiresAt) {
1359
+ console.warn(
1360
+ "[AbcWaasClient] \u26A0\uFE0F No tokens to persist - ensure login was successful first"
1361
+ );
1362
+ return;
1363
+ }
1364
+ console.log(
1365
+ "[AbcWaasClient] \u{1F4BE} Persisting tokens to localStorage after PIN verification"
1366
+ );
1367
+ saveToStorage("access_token" /* ACCESS_TOKEN */, this.accessToken);
1368
+ saveToStorage("refresh_token" /* REFRESH_TOKEN */, this.refreshToken);
1369
+ saveToStorage("expires_at" /* EXPIRES_AT */, this.expiresAt);
1370
+ }
1371
+ // ==========================================================================
1372
+ // Solana Methods
1373
+ // ==========================================================================
1374
+ /**
1375
+ * Generate or recover Solana wallet (Ed25519)
1376
+ * Reference: SigningService.ts:56-72, wallet/api/index.ts:56-72
1377
+ */
1378
+ async generateSolanaWallet(pin, isRecover = false) {
1379
+ const url = `${this.baseURL}/v3/wallet/${isRecover ? "recover" : "generate"}`;
1380
+ const response = await fetch(url, {
1381
+ method: "POST",
1382
+ headers: {
1383
+ "Content-Type": "application/json",
1384
+ // V3 API requires JSON, not form-urlencoded
1385
+ Accept: "application/json",
1386
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1387
+ },
1388
+ body: JSON.stringify({
1389
+ curve: "ed25519",
1390
+ password: pin
1391
+ // PIN will be encrypted by Secure Channel
1392
+ // Note: network parameter not needed for v3 API
1393
+ })
1394
+ });
1395
+ let data;
1396
+ try {
1397
+ data = await response.json();
1398
+ } catch (e) {
1399
+ console.error(`[AbcWaasClient] Failed to parse response from ${url}:`, e);
1400
+ throw createAbcError(
1401
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1402
+ `Failed to ${isRecover ? "recover" : "generate"} Solana wallet - invalid response`,
1403
+ { status: response.status }
1404
+ );
1405
+ }
1406
+ if (!response.ok) {
1407
+ if (!isRecover && response.status === 409) {
1408
+ const error = createAbcError(
1409
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1410
+ "Wallet already exists",
1411
+ data
1412
+ );
1413
+ error.response = { status: 409 };
1414
+ throw error;
1415
+ }
1416
+ console.error(
1417
+ `[AbcWaasClient] ${isRecover ? "Recover" : "Generate"} failed:`,
1418
+ data
1419
+ );
1420
+ throw createAbcError(
1421
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1422
+ `Failed to ${isRecover ? "recover" : "generate"} Solana wallet`,
1423
+ data
1424
+ );
1425
+ }
1426
+ const result = data.result || data;
1427
+ if (!result.key_id || !result.public_key || !result.encrypted_share) {
1428
+ console.error(
1429
+ "[AbcWaasClient] Invalid wallet response, missing required fields:",
1430
+ result
1431
+ );
1432
+ throw createAbcError(
1433
+ "WALLET_NOT_FOUND" /* WALLET_NOT_FOUND */,
1434
+ `Invalid wallet response from ${isRecover ? "recover" : "generate"}`,
1435
+ data
1436
+ );
1437
+ }
1438
+ const solanaNetwork = getSolanaNetwork();
1439
+ const addressResult = await this.getSolanaAddress(
1440
+ result.public_key,
1441
+ solanaNetwork
1442
+ );
1443
+ return {
1444
+ uid: result.uid || "",
1445
+ sessionId: result.share_id || result.key_id,
1446
+ shareId: result.share_id || result.key_id,
1447
+ publicKey: result.public_key,
1448
+ address: addressResult,
1449
+ keyId: result.key_id,
1450
+ encryptedShare: result.encrypted_share || "",
1451
+ secretStore: result.secret_store || "",
1452
+ network: solanaNetwork
1453
+ };
1454
+ }
1455
+ /**
1456
+ * Get Solana address from Ed25519 public key
1457
+ * Reference: wallet/api/index.ts:74-82
1458
+ */
1459
+ async getSolanaAddress(publicKey, network) {
1460
+ const url = `${this.baseURL}/wapi/v2/solana/wallet/getAddress`;
1461
+ const body = new URLSearchParams({
1462
+ network,
1463
+ publicKey
1464
+ }).toString();
1465
+ const response = await fetch(url, {
1466
+ method: "POST",
1467
+ headers: {
1468
+ ...DEFAULT_HEADERS,
1469
+ // Contains 'Content-Type': 'application/x-www-form-urlencoded'
1470
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1471
+ },
1472
+ body
1473
+ });
1474
+ const data = await response.json();
1475
+ if (!response.ok || data.status !== "success") {
1476
+ throw createAbcError(
1477
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1478
+ "Failed to get Solana address",
1479
+ data
1480
+ );
1481
+ }
1482
+ return data.result?.data?.address;
1483
+ }
1484
+ /**
1485
+ * Sign Solana transaction with Ed25519
1486
+ * Reference: SigningService.ts:587-626, wallet/api/index.ts:114-122
1487
+ */
1488
+ async signSolanaTransaction(params) {
1489
+ const url = `${this.baseURL}/v3/wallet/sign`;
1490
+ const response = await fetch(url, {
1491
+ method: "POST",
1492
+ headers: {
1493
+ "Content-Type": "application/json",
1494
+ Accept: "application/json",
1495
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1496
+ },
1497
+ body: JSON.stringify({
1498
+ uid: params.uid,
1499
+ share_id: params.shareId,
1500
+ key_id: params.keyId,
1501
+ encrypted_share: params.encryptedShare,
1502
+ public_key: params.publicKey,
1503
+ message: params.message,
1504
+ // Hex-encoded transaction
1505
+ password: params.pin,
1506
+ // PIN will be encrypted
1507
+ network: params.network
1508
+ // Required: 'solana' or 'solana_devnet'
1509
+ })
1510
+ });
1511
+ const data = await response.json();
1512
+ if (!response.ok || data.status !== "success") {
1513
+ throw createAbcError(
1514
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
1515
+ "Failed to sign Solana transaction",
1516
+ data
1517
+ );
1518
+ }
1519
+ return {
1520
+ signature: data.result?.signature
1521
+ };
1522
+ }
1523
+ /**
1524
+ * Sign Solana message with Ed25519
1525
+ * Reference: SigningService.ts:546-579
1526
+ */
1527
+ async signSolanaMessage(params) {
1528
+ const url = `${this.baseURL}/v3/wallet/sign`;
1529
+ const response = await fetch(url, {
1530
+ method: "POST",
1531
+ headers: {
1532
+ "Content-Type": "application/json",
1533
+ Accept: "application/json",
1534
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1535
+ },
1536
+ body: JSON.stringify({
1537
+ uid: params.uid,
1538
+ share_id: params.shareId,
1539
+ key_id: params.keyId,
1540
+ encrypted_share: params.encryptedShare,
1541
+ public_key: params.publicKey,
1542
+ message: params.message,
1543
+ // Hex-encoded message
1544
+ password: params.pin,
1545
+ network: params.network
1546
+ // Required: 'solana' or 'solana_devnet'
1547
+ })
1548
+ });
1549
+ const data = await response.json();
1550
+ if (!response.ok || data.status !== "success") {
1551
+ throw createAbcError(
1552
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
1553
+ "Failed to sign Solana message",
1554
+ data
1555
+ );
1556
+ }
1557
+ return {
1558
+ signature: data.result?.signature
1559
+ };
1560
+ }
1561
+ /**
1562
+ * Send Solana transaction
1563
+ * Reference: SigningService.ts:418, wallet/api/index.ts:124-132
1564
+ */
1565
+ async sendSolanaTransaction(params) {
1566
+ const url = `${this.baseURL}/wapi/v2/solana/tx/sendTransaction`;
1567
+ const response = await fetch(url, {
1568
+ method: "POST",
1569
+ headers: {
1570
+ ...DEFAULT_HEADERS,
1571
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
1572
+ },
1573
+ body: JSON.stringify({
1574
+ network: params.network,
1575
+ serializedTX: params.serializedTX,
1576
+ signatures: params.signatures
1577
+ })
1578
+ });
1579
+ const data = await response.json();
1580
+ if (!response.ok || data.status !== "success") {
1581
+ throw createAbcError(
1582
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1583
+ "Failed to send Solana transaction",
1584
+ data
1585
+ );
1586
+ }
1587
+ return {
1588
+ txHash: data.result?.data
1589
+ };
1590
+ }
1591
+ };
1592
+ function createAbcWaasClient(config) {
1593
+ return new AbcWaasClient(config);
1594
+ }
1595
+
1596
+ export {
1597
+ AbcWaasClient,
1598
+ createAbcWaasClient
1599
+ };