hm-tracking-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +291 -0
- package/dist/browser/index.es.js +36247 -0
- package/dist/browser/index.umd.js +1245 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +8 -0
- package/dist/browser.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/sdk/HmTgTrackingSDK.d.ts +68 -0
- package/dist/sdk/HmTgTrackingSDK.js +336 -0
- package/dist/sdk/HmTgTrackingSDK.js.map +1 -0
- package/dist/sdk/HmTrackingSDK.d.ts +68 -0
- package/dist/sdk/HmTrackingSDK.js +336 -0
- package/dist/sdk/HmTrackingSDK.js.map +1 -0
- package/dist/sdk/TgTrackingSDK.d.ts +68 -0
- package/dist/sdk/TgTrackingSDK.js +336 -0
- package/dist/sdk/TgTrackingSDK.js.map +1 -0
- package/dist/sdk/adMonitor.d.ts +13 -0
- package/dist/sdk/adMonitor.js +51 -0
- package/dist/sdk/adMonitor.js.map +1 -0
- package/dist/sdk/api.d.ts +35 -0
- package/dist/sdk/api.js +73 -0
- package/dist/sdk/api.js.map +1 -0
- package/dist/sdk/http.d.ts +16 -0
- package/dist/sdk/http.js +43 -0
- package/dist/sdk/http.js.map +1 -0
- package/dist/sdk/index.d.ts +3 -0
- package/dist/sdk/index.js +4 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/monetag.d.ts +29 -0
- package/dist/sdk/monetag.js +115 -0
- package/dist/sdk/monetag.js.map +1 -0
- package/dist/sdk/storage.d.ts +8 -0
- package/dist/sdk/storage.js +30 -0
- package/dist/sdk/storage.js.map +1 -0
- package/dist/sdk/telegram.d.ts +12 -0
- package/dist/sdk/telegram.js +139 -0
- package/dist/sdk/telegram.js.map +1 -0
- package/dist/sdk/tonWalletProvider.d.ts +13 -0
- package/dist/sdk/tonWalletProvider.js +142 -0
- package/dist/sdk/tonWalletProvider.js.map +1 -0
- package/dist/sdk/types.d.ts +212 -0
- package/dist/sdk/types.js +7 -0
- package/dist/sdk/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC","sourcesContent":["export * from \"./HmTrackingSDK.js\";\r\nexport * from \"./types.js\";\r\nexport * from \"./tonWalletProvider.js\";\r\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface HmAdManagerOptions {
|
|
2
|
+
/** 初始化时是否自动注入 SDK 脚本 */
|
|
3
|
+
autoInjectScript?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class HmAdManager {
|
|
6
|
+
private options;
|
|
7
|
+
private initialized;
|
|
8
|
+
private sdkZone?;
|
|
9
|
+
private sdkFunc?;
|
|
10
|
+
constructor(options?: HmAdManagerOptions);
|
|
11
|
+
init(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* 设置当前广告空间 ID(spaceId),并确保脚本已按需注入
|
|
14
|
+
*/
|
|
15
|
+
setSpace(spaceId: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* 查找现有 sdk 脚本
|
|
18
|
+
*/
|
|
19
|
+
private findExistingScript;
|
|
20
|
+
/**
|
|
21
|
+
* 确保脚本已注入;当 detectedChange 为 true 或脚本配置与当前不一致时会替换
|
|
22
|
+
*/
|
|
23
|
+
private ensureScriptInjected;
|
|
24
|
+
private injectScript;
|
|
25
|
+
private callSDK;
|
|
26
|
+
show(): Promise<void>;
|
|
27
|
+
showPopup(): Promise<void>;
|
|
28
|
+
showInApp(inAppOptions?: any): Promise<void>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export class HmAdManager {
|
|
2
|
+
constructor(options = {}) {
|
|
3
|
+
this.options = options;
|
|
4
|
+
this.initialized = false;
|
|
5
|
+
}
|
|
6
|
+
async init() {
|
|
7
|
+
if (this.initialized)
|
|
8
|
+
return;
|
|
9
|
+
// 初始化时如果已经有 spaceId,且允许自动注入,则注入脚本
|
|
10
|
+
if (this.options.autoInjectScript !== false &&
|
|
11
|
+
this.sdkZone &&
|
|
12
|
+
this.sdkFunc) {
|
|
13
|
+
await this.ensureScriptInjected();
|
|
14
|
+
}
|
|
15
|
+
this.initialized = true;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 设置当前广告空间 ID(spaceId),并确保脚本已按需注入
|
|
19
|
+
*/
|
|
20
|
+
async setSpace(spaceId) {
|
|
21
|
+
if (!spaceId)
|
|
22
|
+
return;
|
|
23
|
+
const nextZone = String(spaceId);
|
|
24
|
+
const nextFunc = `show_${spaceId}`;
|
|
25
|
+
const changed = this.sdkZone !== nextZone || this.sdkFunc !== nextFunc;
|
|
26
|
+
this.sdkZone = nextZone;
|
|
27
|
+
this.sdkFunc = nextFunc;
|
|
28
|
+
if (this.options.autoInjectScript !== false) {
|
|
29
|
+
// 若发生变化或尚未注入,则确保脚本正确注入
|
|
30
|
+
await this.ensureScriptInjected(changed);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 查找现有 sdk 脚本
|
|
35
|
+
*/
|
|
36
|
+
findExistingScript() {
|
|
37
|
+
if (typeof document === "undefined")
|
|
38
|
+
return null;
|
|
39
|
+
return document.querySelector("script[src*='//libtl.com/sdk.js']");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 确保脚本已注入;当 detectedChange 为 true 或脚本配置与当前不一致时会替换
|
|
43
|
+
*/
|
|
44
|
+
async ensureScriptInjected(detectedChange = false) {
|
|
45
|
+
if (typeof document === "undefined")
|
|
46
|
+
return;
|
|
47
|
+
const existed = this.findExistingScript();
|
|
48
|
+
const shouldHaveZone = this.sdkZone || "";
|
|
49
|
+
const shouldHaveFunc = this.sdkFunc || "";
|
|
50
|
+
if (existed) {
|
|
51
|
+
const zone = existed.getAttribute("data-zone") || "";
|
|
52
|
+
const func = existed.getAttribute("data-sdk") || "";
|
|
53
|
+
const matched = zone === shouldHaveZone && func === shouldHaveFunc;
|
|
54
|
+
if (matched && !detectedChange) {
|
|
55
|
+
return; // 已匹配且无强制替换
|
|
56
|
+
}
|
|
57
|
+
// 配置不一致则移除并重新注入
|
|
58
|
+
existed.parentElement?.removeChild(existed);
|
|
59
|
+
}
|
|
60
|
+
// 无配置则无需注入
|
|
61
|
+
if (!shouldHaveZone || !shouldHaveFunc)
|
|
62
|
+
return;
|
|
63
|
+
await this.injectScript(shouldHaveZone, shouldHaveFunc);
|
|
64
|
+
}
|
|
65
|
+
injectScript(zone, func) {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
if (typeof document === "undefined")
|
|
68
|
+
return resolve();
|
|
69
|
+
const script = document.createElement("script");
|
|
70
|
+
script.src = "//libtl.com/sdk.js";
|
|
71
|
+
script.setAttribute("data-zone", zone);
|
|
72
|
+
script.setAttribute("data-sdk", func);
|
|
73
|
+
script.async = true;
|
|
74
|
+
script.onload = () => resolve();
|
|
75
|
+
script.onerror = () => reject(new Error("Hm 脚本加载失败"));
|
|
76
|
+
document.head.appendChild(script);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async callSDK(arg) {
|
|
80
|
+
if (!this.sdkFunc)
|
|
81
|
+
throw new Error("Hm 未设置 spaceId");
|
|
82
|
+
const fn = window[this.sdkFunc];
|
|
83
|
+
if (typeof fn !== "function")
|
|
84
|
+
throw new Error("Hm SDK 未正确加载");
|
|
85
|
+
await fn(arg);
|
|
86
|
+
}
|
|
87
|
+
async show() {
|
|
88
|
+
try {
|
|
89
|
+
await this.callSDK();
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error("Hm广告展示失败:", error);
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async showPopup() {
|
|
97
|
+
try {
|
|
98
|
+
await this.callSDK("pop");
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error("Hm Popup广告展示失败:", error);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async showInApp(inAppOptions) {
|
|
106
|
+
try {
|
|
107
|
+
await this.callSDK({ type: "inApp", inAppSettings: inAppOptions });
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error("Hm InApp广告展示失败:", error);
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=monetag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monetag.js","sourceRoot":"","sources":["../../src/sdk/monetag.ts"],"names":[],"mappings":"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","sourcesContent":["export interface HmAdManagerOptions {\r\n /** 初始化时是否自动注入 SDK 脚本 */\r\n autoInjectScript?: boolean;\r\n}\r\n\r\nexport class HmAdManager {\r\n private initialized = false;\r\n private sdkZone?: string; // 由后端 /v2/ad/create 返回的 spaceId 设置\r\n private sdkFunc?: string; // 对应 window[\"show_${spaceId}\"]\r\n\r\n constructor(private options: HmAdManagerOptions = {}) {}\r\n\r\n async init(): Promise<void> {\r\n if (this.initialized) return;\r\n // 初始化时如果已经有 spaceId,且允许自动注入,则注入脚本\r\n if (\r\n this.options.autoInjectScript !== false &&\r\n this.sdkZone &&\r\n this.sdkFunc\r\n ) {\r\n await this.ensureScriptInjected();\r\n }\r\n this.initialized = true;\r\n }\r\n\r\n /**\r\n * 设置当前广告空间 ID(spaceId),并确保脚本已按需注入\r\n */\r\n async setSpace(spaceId: string): Promise<void> {\r\n if (!spaceId) return;\r\n const nextZone = String(spaceId);\r\n const nextFunc = `show_${spaceId}`;\r\n\r\n const changed = this.sdkZone !== nextZone || this.sdkFunc !== nextFunc;\r\n this.sdkZone = nextZone;\r\n this.sdkFunc = nextFunc;\r\n\r\n if (this.options.autoInjectScript !== false) {\r\n // 若发生变化或尚未注入,则确保脚本正确注入\r\n await this.ensureScriptInjected(changed);\r\n }\r\n }\r\n\r\n /**\r\n * 查找现有 sdk 脚本\r\n */\r\n private findExistingScript(): HTMLScriptElement | null {\r\n if (typeof document === \"undefined\") return null;\r\n return document.querySelector(\r\n \"script[src*='//libtl.com/sdk.js']\"\r\n ) as HTMLScriptElement | null;\r\n }\r\n\r\n /**\r\n * 确保脚本已注入;当 detectedChange 为 true 或脚本配置与当前不一致时会替换\r\n */\r\n private async ensureScriptInjected(detectedChange = false): Promise<void> {\r\n if (typeof document === \"undefined\") return;\r\n\r\n const existed = this.findExistingScript();\r\n const shouldHaveZone = this.sdkZone || \"\";\r\n const shouldHaveFunc = this.sdkFunc || \"\";\r\n\r\n if (existed) {\r\n const zone = existed.getAttribute(\"data-zone\") || \"\";\r\n const func = existed.getAttribute(\"data-sdk\") || \"\";\r\n const matched = zone === shouldHaveZone && func === shouldHaveFunc;\r\n if (matched && !detectedChange) {\r\n return; // 已匹配且无强制替换\r\n }\r\n // 配置不一致则移除并重新注入\r\n existed.parentElement?.removeChild(existed);\r\n }\r\n\r\n // 无配置则无需注入\r\n if (!shouldHaveZone || !shouldHaveFunc) return;\r\n\r\n await this.injectScript(shouldHaveZone, shouldHaveFunc);\r\n }\r\n\r\n private injectScript(zone: string, func: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n if (typeof document === \"undefined\") return resolve();\r\n\r\n const script = document.createElement(\"script\");\r\n script.src = \"//libtl.com/sdk.js\";\r\n script.setAttribute(\"data-zone\", zone);\r\n script.setAttribute(\"data-sdk\", func);\r\n script.async = true;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(\"Hm 脚本加载失败\"));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n private async callSDK(arg?: any): Promise<void> {\r\n if (!this.sdkFunc) throw new Error(\"Hm 未设置 spaceId\");\r\n const fn: any = (window as any)[this.sdkFunc];\r\n if (typeof fn !== \"function\") throw new Error(\"Hm SDK 未正确加载\");\r\n await fn(arg);\r\n }\r\n\r\n async show(): Promise<void> {\r\n try {\r\n await this.callSDK();\r\n } catch (error) {\r\n console.error(\"Hm广告展示失败:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n async showPopup(): Promise<void> {\r\n try {\r\n await this.callSDK(\"pop\");\r\n } catch (error) {\r\n console.error(\"Hm Popup广告展示失败:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n async showInApp(inAppOptions?: any): Promise<void> {\r\n try {\r\n await this.callSDK({ type: \"inApp\", inAppSettings: inAppOptions });\r\n } catch (error) {\r\n console.error(\"Hm InApp广告展示失败:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class NamespacedStorage {
|
|
2
|
+
constructor(prefix = "tg_tracking_sdk") {
|
|
3
|
+
this.prefix = prefix;
|
|
4
|
+
}
|
|
5
|
+
k(key) {
|
|
6
|
+
return `${this.prefix}:${key}`;
|
|
7
|
+
}
|
|
8
|
+
set(key, value) {
|
|
9
|
+
try {
|
|
10
|
+
localStorage.setItem(this.k(key), JSON.stringify(value));
|
|
11
|
+
}
|
|
12
|
+
catch (_) { }
|
|
13
|
+
}
|
|
14
|
+
get(key) {
|
|
15
|
+
try {
|
|
16
|
+
const v = localStorage.getItem(this.k(key));
|
|
17
|
+
return v ? JSON.parse(v) : null;
|
|
18
|
+
}
|
|
19
|
+
catch (_) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
remove(key) {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.removeItem(this.k(key));
|
|
26
|
+
}
|
|
27
|
+
catch (_) { }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/sdk/storage.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,iBAAiB;IAC5B,YAAoB,SAAiB,iBAAiB;QAAlC,WAAM,GAAN,MAAM,CAA4B;IAAG,CAAC;IAElD,CAAC,CAAC,GAAW;QACnB,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;IACjC,CAAC;IAED,GAAG,CAAI,GAAW,EAAE,KAAQ;QAC1B,IAAI,CAAC;YACH,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;IAChB,CAAC;IAED,GAAG,CAAI,GAAW;QAChB,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,OAAO,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC;YACH,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;IAChB,CAAC;CACF","sourcesContent":["export class NamespacedStorage {\r\n constructor(private prefix: string = \"tg_tracking_sdk\") {}\r\n\r\n private k(key: string) {\r\n return `${this.prefix}:${key}`;\r\n }\r\n\r\n set<T>(key: string, value: T) {\r\n try {\r\n localStorage.setItem(this.k(key), JSON.stringify(value));\r\n } catch (_) {}\r\n }\r\n\r\n get<T>(key: string): T | null {\r\n try {\r\n const v = localStorage.getItem(this.k(key));\r\n return v ? (JSON.parse(v) as T) : null;\r\n } catch (_) {\r\n return null;\r\n }\r\n }\r\n\r\n remove(key: string) {\r\n try {\r\n localStorage.removeItem(this.k(key));\r\n } catch (_) {}\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TelegramUserInfo } from "./types.js";
|
|
2
|
+
export declare function isTelegramEnv(): boolean;
|
|
3
|
+
export declare function getTelegramUserUnsafe(): TelegramUserInfo | null;
|
|
4
|
+
/**
|
|
5
|
+
* 基于 Cookie 的匿名浏览器用户(非 Telegram 环境使用)
|
|
6
|
+
* - 会在 cookie 中持久化 uid,下次复用
|
|
7
|
+
*/
|
|
8
|
+
export declare function getAnonymousBrowserUser(cookieName?: string): TelegramUserInfo;
|
|
9
|
+
/**
|
|
10
|
+
* 获取默认的 mock 用户信息(保留旧逻辑)
|
|
11
|
+
*/
|
|
12
|
+
export declare function getDefaultMockUser(): TelegramUserInfo;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import WebApp from "@twa-dev/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* 尝试获取启动参数,检查是否在 Telegram 环境中
|
|
4
|
+
*/
|
|
5
|
+
function retrieveLaunchParams() {
|
|
6
|
+
if (!WebApp.initData || WebApp.initData === "") {
|
|
7
|
+
throw new Error("未能提取启动参数,不在 Telegram 环境中");
|
|
8
|
+
}
|
|
9
|
+
return WebApp.initData;
|
|
10
|
+
}
|
|
11
|
+
export function isTelegramEnv() {
|
|
12
|
+
try {
|
|
13
|
+
// 检查 WebApp 对象是否存在且 initData 可用
|
|
14
|
+
if (typeof window !== "undefined" &&
|
|
15
|
+
window.Telegram &&
|
|
16
|
+
window.Telegram.WebApp) {
|
|
17
|
+
// 如果能够提取启动参数,说明已经在 Telegram 环境中
|
|
18
|
+
retrieveLaunchParams();
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.warn("非Telegram环境");
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function getTelegramUserUnsafe() {
|
|
29
|
+
try {
|
|
30
|
+
// 确保 WebApp 对象存在
|
|
31
|
+
if (!WebApp || !WebApp.initDataUnsafe) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const initDataUnsafe = WebApp.initDataUnsafe;
|
|
35
|
+
// 验证用户信息的基本结构
|
|
36
|
+
if (!initDataUnsafe.user || !initDataUnsafe.user.id) {
|
|
37
|
+
console.warn("Telegram用户信息结构不完整");
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// 确保包含必要字段
|
|
41
|
+
const userInfo = {
|
|
42
|
+
user: {
|
|
43
|
+
id: initDataUnsafe.user.id,
|
|
44
|
+
firstName: initDataUnsafe.user.first_name || "",
|
|
45
|
+
lastName: initDataUnsafe.user.last_name || "",
|
|
46
|
+
username: initDataUnsafe.user.username,
|
|
47
|
+
languageCode: initDataUnsafe.user.language_code,
|
|
48
|
+
isPremium: initDataUnsafe.user.is_premium || false,
|
|
49
|
+
allowsWriteToPm: initDataUnsafe.user.allows_write_to_pm || false,
|
|
50
|
+
},
|
|
51
|
+
authDate: new Date().toISOString(),
|
|
52
|
+
hash: initDataUnsafe.hash || "",
|
|
53
|
+
startParam: initDataUnsafe.start_param,
|
|
54
|
+
chatType: initDataUnsafe.chat_type,
|
|
55
|
+
chatInstance: initDataUnsafe.chat_instance,
|
|
56
|
+
};
|
|
57
|
+
return userInfo;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.warn("获取Telegram用户信息失败:", error);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Cookie 工具 **/
|
|
65
|
+
function readCookie(name) {
|
|
66
|
+
if (typeof document === "undefined")
|
|
67
|
+
return null;
|
|
68
|
+
const match = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([.$?*|{}()\[\]\\/+^])/g, "\\$1") + "=([^;]*)"));
|
|
69
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
70
|
+
}
|
|
71
|
+
function writeCookie(name, value, days = 365 * 2) {
|
|
72
|
+
if (typeof document === "undefined")
|
|
73
|
+
return;
|
|
74
|
+
const date = new Date();
|
|
75
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
76
|
+
const expires = "; expires=" + date.toUTCString();
|
|
77
|
+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=/`;
|
|
78
|
+
}
|
|
79
|
+
function generateNumericId() {
|
|
80
|
+
// 生成稳定的数值 ID(53-bit 安全整数范围内)
|
|
81
|
+
const rand = Math.floor(Math.random() * 1e9);
|
|
82
|
+
const time = Date.now() % 1e9;
|
|
83
|
+
const id = Number(String(time).padStart(9, "0") + String(rand).padStart(9, "0"));
|
|
84
|
+
return id;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 基于 Cookie 的匿名浏览器用户(非 Telegram 环境使用)
|
|
88
|
+
* - 会在 cookie 中持久化 uid,下次复用
|
|
89
|
+
*/
|
|
90
|
+
export function getAnonymousBrowserUser(cookieName = "tg_tracking_uid") {
|
|
91
|
+
let uidStr = readCookie(cookieName);
|
|
92
|
+
if (!uidStr) {
|
|
93
|
+
const uid = generateNumericId();
|
|
94
|
+
uidStr = String(uid);
|
|
95
|
+
writeCookie(cookieName, uidStr);
|
|
96
|
+
}
|
|
97
|
+
const uidNum = Number(uidStr.replace(/\D/g, "").slice(0, 15)) || generateNumericId();
|
|
98
|
+
const lang = (typeof navigator !== "undefined" &&
|
|
99
|
+
(navigator.language || navigator.userLanguage)) ||
|
|
100
|
+
"en";
|
|
101
|
+
return {
|
|
102
|
+
user: {
|
|
103
|
+
id: uidNum,
|
|
104
|
+
firstName: "Guest",
|
|
105
|
+
lastName: "",
|
|
106
|
+
username: `guest_${uidStr.slice(-6)}`,
|
|
107
|
+
languageCode: lang.toLowerCase(),
|
|
108
|
+
isPremium: false,
|
|
109
|
+
allowsWriteToPm: false,
|
|
110
|
+
},
|
|
111
|
+
authDate: new Date().toISOString(),
|
|
112
|
+
hash: "anonymous_cookie_user",
|
|
113
|
+
startParam: "browser_guest",
|
|
114
|
+
chatType: "sender",
|
|
115
|
+
chatInstance: "",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 获取默认的 mock 用户信息(保留旧逻辑)
|
|
120
|
+
*/
|
|
121
|
+
export function getDefaultMockUser() {
|
|
122
|
+
return {
|
|
123
|
+
user: {
|
|
124
|
+
id: 2077220643,
|
|
125
|
+
firstName: "Mock",
|
|
126
|
+
lastName: "User",
|
|
127
|
+
username: "mock_user_demo",
|
|
128
|
+
languageCode: "zh-hans",
|
|
129
|
+
isPremium: true,
|
|
130
|
+
allowsWriteToPm: true,
|
|
131
|
+
},
|
|
132
|
+
authDate: new Date().toISOString(),
|
|
133
|
+
hash: "mock_hash_for_demo_purpose",
|
|
134
|
+
startParam: "demo_start_param",
|
|
135
|
+
chatType: "sender",
|
|
136
|
+
chatInstance: "-245769840322609948",
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/sdk/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,cAAc,CAAC;AAGlC;;GAEG;AACH,SAAS,oBAAoB;IAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,gCAAgC;QAChC,IACE,OAAO,MAAM,KAAK,WAAW;YAC5B,MAAc,CAAC,QAAQ;YACvB,MAAc,CAAC,QAAQ,CAAC,MAAM,EAC/B,CAAC;YACD,gCAAgC;YAChC,oBAAoB,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC;QACH,iBAAiB;QACjB,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAE7C,cAAc;QACd,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,WAAW;QACX,MAAM,QAAQ,GAAqB;YACjC,IAAI,EAAE;gBACJ,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;gBAC1B,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE;gBAC/C,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE;gBAC7C,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ;gBACtC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,aAAa;gBAC/C,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,UAAU,IAAI,KAAK;gBAClD,eAAe,EAAE,cAAc,CAAC,IAAI,CAAC,kBAAkB,IAAI,KAAK;aACjE;YACD,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAClC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,EAAE;YAC/B,UAAU,EAAE,cAAc,CAAC,WAAW;YACtC,QAAQ,EAAE,cAAc,CAAC,SAAS;YAClC,YAAY,EAAE,cAAc,CAAC,aAAa;SAC3C,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iBAAiB;AACjB,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CACjC,IAAI,MAAM,CACR,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,MAAM,CAAC,GAAG,UAAU,CAC1E,CACF,CAAC;IACF,OAAO,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa,EAAE,IAAI,GAAG,GAAG,GAAG,CAAC;IAC9D,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CACjE,KAAK,CACN,GAAG,OAAO,UAAU,CAAC;AACxB,CAAC;AAED,SAAS,iBAAiB;IACxB,6BAA6B;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC;IAC9B,MAAM,EAAE,GAAG,MAAM,CACf,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAC9D,CAAC;IACF,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAU,GAAG,iBAAiB;IAE9B,IAAI,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,iBAAiB,EAAE,CAAC;IACxE,MAAM,IAAI,GACR,CAAC,OAAO,SAAS,KAAK,WAAW;QAC/B,CAAC,SAAS,CAAC,QAAQ,IAAK,SAAiB,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC;IAEP,OAAO;QACL,IAAI,EAAE;YACJ,EAAE,EAAE,MAAM;YACV,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,SAAS,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YACrC,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE;YAChC,SAAS,EAAE,KAAK;YAChB,eAAe,EAAE,KAAK;SACvB;QACD,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,IAAI,EAAE,uBAAuB;QAC7B,UAAU,EAAE,eAAe;QAC3B,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,EAAE;KACG,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE;YACJ,EAAE,EAAE,UAAU;YACd,SAAS,EAAE,MAAM;YACjB,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,gBAAgB;YAC1B,YAAY,EAAE,SAAS;YACvB,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,IAAI;SACtB;QACD,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,IAAI,EAAE,4BAA4B;QAClC,UAAU,EAAE,kBAAkB;QAC9B,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,qBAAqB;KACpC,CAAC;AACJ,CAAC","sourcesContent":["import WebApp from \"@twa-dev/sdk\";\r\nimport type { TelegramUserInfo } from \"./types.js\";\r\n\r\n/**\r\n * 尝试获取启动参数,检查是否在 Telegram 环境中\r\n */\r\nfunction retrieveLaunchParams() {\r\n if (!WebApp.initData || WebApp.initData === \"\") {\r\n throw new Error(\"未能提取启动参数,不在 Telegram 环境中\");\r\n }\r\n return WebApp.initData;\r\n}\r\n\r\nexport function isTelegramEnv(): boolean {\r\n try {\r\n // 检查 WebApp 对象是否存在且 initData 可用\r\n if (\r\n typeof window !== \"undefined\" &&\r\n (window as any).Telegram &&\r\n (window as any).Telegram.WebApp\r\n ) {\r\n // 如果能够提取启动参数,说明已经在 Telegram 环境中\r\n retrieveLaunchParams();\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n console.warn(\"非Telegram环境\");\r\n return false;\r\n }\r\n}\r\n\r\nexport function getTelegramUserUnsafe(): TelegramUserInfo | null {\r\n try {\r\n // 确保 WebApp 对象存在\r\n if (!WebApp || !WebApp.initDataUnsafe) {\r\n return null;\r\n }\r\n\r\n const initDataUnsafe = WebApp.initDataUnsafe;\r\n\r\n // 验证用户信息的基本结构\r\n if (!initDataUnsafe.user || !initDataUnsafe.user.id) {\r\n console.warn(\"Telegram用户信息结构不完整\");\r\n return null;\r\n }\r\n\r\n // 确保包含必要字段\r\n const userInfo: TelegramUserInfo = {\r\n user: {\r\n id: initDataUnsafe.user.id,\r\n firstName: initDataUnsafe.user.first_name || \"\",\r\n lastName: initDataUnsafe.user.last_name || \"\",\r\n username: initDataUnsafe.user.username,\r\n languageCode: initDataUnsafe.user.language_code,\r\n isPremium: initDataUnsafe.user.is_premium || false,\r\n allowsWriteToPm: initDataUnsafe.user.allows_write_to_pm || false,\r\n },\r\n authDate: new Date().toISOString(),\r\n hash: initDataUnsafe.hash || \"\",\r\n startParam: initDataUnsafe.start_param,\r\n chatType: initDataUnsafe.chat_type,\r\n chatInstance: initDataUnsafe.chat_instance,\r\n };\r\n\r\n return userInfo;\r\n } catch (error) {\r\n console.warn(\"获取Telegram用户信息失败:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/** Cookie 工具 **/\r\nfunction readCookie(name: string): string | null {\r\n if (typeof document === \"undefined\") return null;\r\n const match = document.cookie.match(\r\n new RegExp(\r\n \"(?:^|; )\" + name.replace(/([.$?*|{}()\\[\\]\\\\/+^])/g, \"\\\\$1\") + \"=([^;]*)\"\r\n )\r\n );\r\n return match ? decodeURIComponent(match[1]) : null;\r\n}\r\n\r\nfunction writeCookie(name: string, value: string, days = 365 * 2) {\r\n if (typeof document === \"undefined\") return;\r\n const date = new Date();\r\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\r\n const expires = \"; expires=\" + date.toUTCString();\r\n document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(\r\n value\r\n )}${expires}; path=/`;\r\n}\r\n\r\nfunction generateNumericId(): number {\r\n // 生成稳定的数值 ID(53-bit 安全整数范围内)\r\n const rand = Math.floor(Math.random() * 1e9);\r\n const time = Date.now() % 1e9;\r\n const id = Number(\r\n String(time).padStart(9, \"0\") + String(rand).padStart(9, \"0\")\r\n );\r\n return id;\r\n}\r\n\r\n/**\r\n * 基于 Cookie 的匿名浏览器用户(非 Telegram 环境使用)\r\n * - 会在 cookie 中持久化 uid,下次复用\r\n */\r\nexport function getAnonymousBrowserUser(\r\n cookieName = \"tg_tracking_uid\"\r\n): TelegramUserInfo {\r\n let uidStr = readCookie(cookieName);\r\n if (!uidStr) {\r\n const uid = generateNumericId();\r\n uidStr = String(uid);\r\n writeCookie(cookieName, uidStr);\r\n }\r\n const uidNum =\r\n Number(uidStr.replace(/\\D/g, \"\").slice(0, 15)) || generateNumericId();\r\n const lang =\r\n (typeof navigator !== \"undefined\" &&\r\n (navigator.language || (navigator as any).userLanguage)) ||\r\n \"en\";\r\n\r\n return {\r\n user: {\r\n id: uidNum,\r\n firstName: \"Guest\",\r\n lastName: \"\",\r\n username: `guest_${uidStr.slice(-6)}`,\r\n languageCode: lang.toLowerCase(),\r\n isPremium: false,\r\n allowsWriteToPm: false,\r\n },\r\n authDate: new Date().toISOString(),\r\n hash: \"anonymous_cookie_user\",\r\n startParam: \"browser_guest\",\r\n chatType: \"sender\",\r\n chatInstance: \"\",\r\n } as TelegramUserInfo;\r\n}\r\n\r\n/**\r\n * 获取默认的 mock 用户信息(保留旧逻辑)\r\n */\r\nexport function getDefaultMockUser(): TelegramUserInfo {\r\n return {\r\n user: {\r\n id: 2077220643,\r\n firstName: \"Mock\",\r\n lastName: \"User\",\r\n username: \"mock_user_demo\",\r\n languageCode: \"zh-hans\",\r\n isPremium: true,\r\n allowsWriteToPm: true,\r\n },\r\n authDate: new Date().toISOString(),\r\n hash: \"mock_hash_for_demo_purpose\",\r\n startParam: \"demo_start_param\",\r\n chatType: \"sender\",\r\n chatInstance: \"-245769840322609948\",\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TonWalletProvider, TonTransactionResult, MerchantPayTransferData } from "./types.js";
|
|
2
|
+
export declare class DefaultTonWalletProvider implements TonWalletProvider {
|
|
3
|
+
private ui;
|
|
4
|
+
private bindWalletCallback?;
|
|
5
|
+
constructor(bindWalletCallback?: (walletAddress: string) => Promise<void>);
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
private reportWalletAddress;
|
|
8
|
+
connect(): Promise<boolean>;
|
|
9
|
+
private getUserFriendlyAddress;
|
|
10
|
+
sendTonTransaction(transferData: MerchantPayTransferData): Promise<TonTransactionResult>;
|
|
11
|
+
sendUsdtTransaction(transferData: MerchantPayTransferData): Promise<TonTransactionResult>;
|
|
12
|
+
disconnect(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { TonConnectUI } from "@tonconnect/ui";
|
|
2
|
+
import { toUserFriendlyAddress } from "@tonconnect/sdk";
|
|
3
|
+
const DEFAULT_MANIFEST_URL = "https://miniapp.spinfi.me/tonconnect-manifest.json";
|
|
4
|
+
// 添加单例模式,确保TonConnectUI只被初始化一次
|
|
5
|
+
let tonConnectUIInstance = null;
|
|
6
|
+
export class DefaultTonWalletProvider {
|
|
7
|
+
constructor(bindWalletCallback) {
|
|
8
|
+
this.bindWalletCallback = bindWalletCallback;
|
|
9
|
+
// 使用单例模式,如果实例已经存在则重用
|
|
10
|
+
if (!tonConnectUIInstance) {
|
|
11
|
+
try {
|
|
12
|
+
// console.log("创建新的TonConnectUI实例");
|
|
13
|
+
tonConnectUIInstance = new TonConnectUI({
|
|
14
|
+
manifestUrl: DEFAULT_MANIFEST_URL,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error("创建TonConnectUI实例失败:", error);
|
|
19
|
+
throw new Error("创建TonConnectUI实例失败");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// console.log("复用已存在的TonConnectUI实例");
|
|
24
|
+
}
|
|
25
|
+
this.ui = tonConnectUIInstance;
|
|
26
|
+
}
|
|
27
|
+
isConnected() {
|
|
28
|
+
try {
|
|
29
|
+
return !!this.ui?.connected;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async reportWalletAddress() {
|
|
36
|
+
const walletAddress = this.getUserFriendlyAddress();
|
|
37
|
+
if (walletAddress && this.bindWalletCallback) {
|
|
38
|
+
try {
|
|
39
|
+
await this.bindWalletCallback(walletAddress);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error("钱包地址上报失败:", error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async connect() {
|
|
47
|
+
if (this.isConnected()) {
|
|
48
|
+
await this.reportWalletAddress();
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
this.ui.openModal();
|
|
54
|
+
const unsub = this.ui.onStatusChange(() => {
|
|
55
|
+
if (this.isConnected()) {
|
|
56
|
+
unsub();
|
|
57
|
+
resolve();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// 设置超时,防止用户长时间不操作
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
if (!this.isConnected()) {
|
|
63
|
+
unsub();
|
|
64
|
+
reject(new Error("连接钱包超时"));
|
|
65
|
+
}
|
|
66
|
+
}, 300000); // 5分钟超时
|
|
67
|
+
});
|
|
68
|
+
// 连接成功后,上报钱包地址
|
|
69
|
+
await this.reportWalletAddress();
|
|
70
|
+
return this.isConnected();
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error("连接钱包失败:", e);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
getUserFriendlyAddress() {
|
|
78
|
+
const anyUi = this.ui;
|
|
79
|
+
const rawAddress = anyUi?.wallet?.account?.address || anyUi?.account?.address || null;
|
|
80
|
+
if (!rawAddress)
|
|
81
|
+
return null;
|
|
82
|
+
return toUserFriendlyAddress(rawAddress);
|
|
83
|
+
}
|
|
84
|
+
async sendTonTransaction(transferData) {
|
|
85
|
+
if (!this.isConnected()) {
|
|
86
|
+
const ok = await this.connect();
|
|
87
|
+
if (!ok)
|
|
88
|
+
throw new Error("钱包未连接");
|
|
89
|
+
}
|
|
90
|
+
const res = await this.ui.sendTransaction(transferData);
|
|
91
|
+
const boc = res?.boc;
|
|
92
|
+
let transferHash;
|
|
93
|
+
if (boc) {
|
|
94
|
+
try {
|
|
95
|
+
// const cell = Cell.fromBase64(boc);
|
|
96
|
+
// transferHash = cell.hash().toString("base64");
|
|
97
|
+
transferHash = boc.substring(0, 16);
|
|
98
|
+
// console.log("transferHash:", transferHash);
|
|
99
|
+
}
|
|
100
|
+
catch { }
|
|
101
|
+
}
|
|
102
|
+
return { transferHash, boc, raw: res };
|
|
103
|
+
}
|
|
104
|
+
async sendUsdtTransaction(transferData) {
|
|
105
|
+
if (!this.isConnected()) {
|
|
106
|
+
const ok = await this.connect();
|
|
107
|
+
if (!ok)
|
|
108
|
+
throw new Error("钱包未连接");
|
|
109
|
+
}
|
|
110
|
+
const res = await this.ui.sendTransaction(transferData);
|
|
111
|
+
const boc = res?.boc;
|
|
112
|
+
let transferHash;
|
|
113
|
+
if (boc) {
|
|
114
|
+
try {
|
|
115
|
+
// const cell = Cell.fromBase64(boc);
|
|
116
|
+
// transferHash = cell.hash().toString("base64");
|
|
117
|
+
// 简化处理,直接使用 boc 作为 hash
|
|
118
|
+
transferHash = boc.substring(0, 16);
|
|
119
|
+
// console.log("transferHash:", transferHash);
|
|
120
|
+
}
|
|
121
|
+
catch { }
|
|
122
|
+
}
|
|
123
|
+
return { transferHash, boc, raw: res };
|
|
124
|
+
}
|
|
125
|
+
async disconnect() {
|
|
126
|
+
try {
|
|
127
|
+
const anyUi = this.ui;
|
|
128
|
+
if (anyUi?.disconnect) {
|
|
129
|
+
await anyUi.disconnect();
|
|
130
|
+
}
|
|
131
|
+
else if (anyUi?.onStatusChange) {
|
|
132
|
+
// 若无直接断开方法,尝试通过清理连接状态
|
|
133
|
+
const unsub = anyUi.onStatusChange(() => { });
|
|
134
|
+
unsub && unsub();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
console.error("断开钱包连接失败:", e);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=tonWalletProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonWalletProvider.js","sourceRoot":"","sources":["../../src/sdk/tonWalletProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n TonWalletProvider,\r\n TonTransactionResult,\r\n MerchantPayTransferData,\r\n} from \"./types.js\";\r\nimport { TonConnectUI } from \"@tonconnect/ui\";\r\nimport { toUserFriendlyAddress } from \"@tonconnect/sdk\";\r\n\r\nconst DEFAULT_MANIFEST_URL =\r\n \"https://miniapp.spinfi.me/tonconnect-manifest.json\";\r\n\r\n// 添加单例模式,确保TonConnectUI只被初始化一次\r\nlet tonConnectUIInstance: TonConnectUI | null = null;\r\n\r\nexport class DefaultTonWalletProvider implements TonWalletProvider {\r\n private ui: TonConnectUI;\r\n private bindWalletCallback?: (walletAddress: string) => Promise<void>;\r\n\r\n constructor(bindWalletCallback?: (walletAddress: string) => Promise<void>) {\r\n this.bindWalletCallback = bindWalletCallback;\r\n // 使用单例模式,如果实例已经存在则重用\r\n if (!tonConnectUIInstance) {\r\n try {\r\n // console.log(\"创建新的TonConnectUI实例\");\r\n tonConnectUIInstance = new TonConnectUI({\r\n manifestUrl: DEFAULT_MANIFEST_URL,\r\n });\r\n } catch (error) {\r\n console.error(\"创建TonConnectUI实例失败:\", error);\r\n throw new Error(\"创建TonConnectUI实例失败\");\r\n }\r\n } else {\r\n // console.log(\"复用已存在的TonConnectUI实例\");\r\n }\r\n this.ui = tonConnectUIInstance;\r\n }\r\n\r\n isConnected(): boolean {\r\n try {\r\n return !!(this.ui as any)?.connected;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n private async reportWalletAddress(): Promise<void> {\r\n const walletAddress = this.getUserFriendlyAddress();\r\n if (walletAddress && this.bindWalletCallback) {\r\n try {\r\n await this.bindWalletCallback(walletAddress);\r\n } catch (error) {\r\n console.error(\"钱包地址上报失败:\", error);\r\n }\r\n }\r\n }\r\n\r\n async connect(): Promise<boolean> {\r\n if (this.isConnected()) {\r\n await this.reportWalletAddress();\r\n return true;\r\n }\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n this.ui.openModal();\r\n const unsub = this.ui.onStatusChange(() => {\r\n if (this.isConnected()) {\r\n unsub();\r\n resolve();\r\n }\r\n });\r\n // 设置超时,防止用户长时间不操作\r\n setTimeout(() => {\r\n if (!this.isConnected()) {\r\n unsub();\r\n reject(new Error(\"连接钱包超时\"));\r\n }\r\n }, 300000); // 5分钟超时\r\n });\r\n\r\n // 连接成功后,上报钱包地址\r\n await this.reportWalletAddress();\r\n\r\n return this.isConnected();\r\n } catch (e) {\r\n console.error(\"连接钱包失败:\", e);\r\n return false;\r\n }\r\n }\r\n\r\n private getUserFriendlyAddress(): string | null {\r\n const anyUi = this.ui as any;\r\n const rawAddress =\r\n anyUi?.wallet?.account?.address || anyUi?.account?.address || null;\r\n if (!rawAddress) return null;\r\n return toUserFriendlyAddress(rawAddress);\r\n }\r\n\r\n async sendTonTransaction(\r\n transferData: MerchantPayTransferData\r\n ): Promise<TonTransactionResult> {\r\n if (!this.isConnected()) {\r\n const ok = await this.connect();\r\n if (!ok) throw new Error(\"钱包未连接\");\r\n }\r\n const res = await (this.ui as any).sendTransaction(transferData);\r\n const boc: string | undefined = res?.boc;\r\n let transferHash: string | undefined;\r\n if (boc) {\r\n try {\r\n // const cell = Cell.fromBase64(boc);\r\n // transferHash = cell.hash().toString(\"base64\");\r\n transferHash = boc.substring(0, 16);\r\n // console.log(\"transferHash:\", transferHash);\r\n } catch {}\r\n }\r\n return { transferHash, boc, raw: res };\r\n }\r\n\r\n async sendUsdtTransaction(\r\n transferData: MerchantPayTransferData\r\n ): Promise<TonTransactionResult> {\r\n if (!this.isConnected()) {\r\n const ok = await this.connect();\r\n if (!ok) throw new Error(\"钱包未连接\");\r\n }\r\n const res = await (this.ui as any).sendTransaction(transferData);\r\n const boc: string | undefined = res?.boc;\r\n let transferHash: string | undefined;\r\n if (boc) {\r\n try {\r\n // const cell = Cell.fromBase64(boc);\r\n // transferHash = cell.hash().toString(\"base64\");\r\n // 简化处理,直接使用 boc 作为 hash\r\n transferHash = boc.substring(0, 16);\r\n // console.log(\"transferHash:\", transferHash);\r\n } catch {}\r\n }\r\n return { transferHash, boc, raw: res };\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n try {\r\n const anyUi = this.ui as any;\r\n if (anyUi?.disconnect) {\r\n await anyUi.disconnect();\r\n } else if (anyUi?.onStatusChange) {\r\n // 若无直接断开方法,尝试通过清理连接状态\r\n const unsub = anyUi.onStatusChange(() => {});\r\n unsub && unsub();\r\n }\r\n } catch (e) {\r\n console.error(\"断开钱包连接失败:\", e);\r\n }\r\n }\r\n}\r\n"]}
|