@topo/connect-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/dist/index.cjs +144 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +117 -0
- package/package.json +24 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
TopoConnect: () => TopoConnect
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_connect_wallet_api = require("@topo/connect-wallet-api");
|
|
28
|
+
__reExport(index_exports, require("@topo/connect-wallet-api"), module.exports);
|
|
29
|
+
var TopoConnect = class {
|
|
30
|
+
walletOrigin;
|
|
31
|
+
network;
|
|
32
|
+
busy = false;
|
|
33
|
+
listeners = /* @__PURE__ */ new Set();
|
|
34
|
+
timeoutMs;
|
|
35
|
+
constructor(config) {
|
|
36
|
+
this.walletOrigin = (0, import_connect_wallet_api.validateOrigin)(config.walletUrl);
|
|
37
|
+
this.network = config.network ?? import_connect_wallet_api.DEVNET;
|
|
38
|
+
this.timeoutMs = Math.max(1e3, Math.min(config.timeoutMs ?? 3e5, 6e5));
|
|
39
|
+
}
|
|
40
|
+
get cacheKey() {
|
|
41
|
+
return `topo-connect:v1:${this.walletOrigin}:${this.network.chainId}:${window.location.origin}`;
|
|
42
|
+
}
|
|
43
|
+
cache(account) {
|
|
44
|
+
try {
|
|
45
|
+
if (account) localStorage.setItem(this.cacheKey, JSON.stringify(account));
|
|
46
|
+
else localStorage.removeItem(this.cacheKey);
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
for (const listener of this.listeners) listener(account);
|
|
50
|
+
}
|
|
51
|
+
getCachedAccount() {
|
|
52
|
+
try {
|
|
53
|
+
const account = JSON.parse(localStorage.getItem(this.cacheKey) ?? "null");
|
|
54
|
+
if (!account || account.sessionExpiresAt <= Date.now()) return null;
|
|
55
|
+
(0, import_connect_wallet_api.assertNetwork)(account.network, this.network);
|
|
56
|
+
return account;
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
onAccountChange(listener) {
|
|
62
|
+
this.listeners.add(listener);
|
|
63
|
+
return () => this.listeners.delete(listener);
|
|
64
|
+
}
|
|
65
|
+
getNetwork() {
|
|
66
|
+
return { ...this.network };
|
|
67
|
+
}
|
|
68
|
+
async connect() {
|
|
69
|
+
const account = await this.request("connect");
|
|
70
|
+
(0, import_connect_wallet_api.assertNetwork)(account.network, this.network);
|
|
71
|
+
this.cache(account);
|
|
72
|
+
return account;
|
|
73
|
+
}
|
|
74
|
+
async getAccount() {
|
|
75
|
+
const account = await this.request("getAccount");
|
|
76
|
+
(0, import_connect_wallet_api.assertNetwork)(account.network, this.network);
|
|
77
|
+
this.cache(account);
|
|
78
|
+
return account;
|
|
79
|
+
}
|
|
80
|
+
async disconnect() {
|
|
81
|
+
await this.request("disconnect");
|
|
82
|
+
this.cache(null);
|
|
83
|
+
}
|
|
84
|
+
signTransaction(input) {
|
|
85
|
+
return this.request("signTransaction", input);
|
|
86
|
+
}
|
|
87
|
+
signAndSubmitTransaction(input) {
|
|
88
|
+
return this.request("signAndSubmitTransaction", input);
|
|
89
|
+
}
|
|
90
|
+
request(method, params) {
|
|
91
|
+
if (typeof window === "undefined") return Promise.reject(new import_connect_wallet_api.ConnectError("INVALID_REQUEST", "\u8FDE\u63A5 SDK \u4EC5\u5728\u6D4F\u89C8\u5668\u4E2D\u8C03\u7528"));
|
|
92
|
+
if (this.busy) return Promise.reject(new import_connect_wallet_api.ConnectError("BUSY", "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u94B1\u5305\u8BF7\u6C42"));
|
|
93
|
+
const id = crypto.randomUUID();
|
|
94
|
+
const request = { channel: import_connect_wallet_api.CHANNEL, version: import_connect_wallet_api.VERSION, type: "request", id, method, network: this.network, expiresAt: Date.now() + this.timeoutMs, ...params ? { params } : {} };
|
|
95
|
+
const url = new URL("/prompt/", this.walletOrigin);
|
|
96
|
+
url.searchParams.set("origin", window.location.origin);
|
|
97
|
+
url.searchParams.set("requestId", id);
|
|
98
|
+
const popup = window.open(url.href, `topo-${id}`, "popup,width=480,height=760");
|
|
99
|
+
if (!popup) return Promise.reject(new import_connect_wallet_api.ConnectError("POPUP_BLOCKED", "\u8BF7\u5141\u8BB8\u5F39\u51FA Topo Connect \u7A97\u53E3"));
|
|
100
|
+
this.busy = true;
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const cleanup = () => {
|
|
103
|
+
clearInterval(poller);
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
window.removeEventListener("message", receive);
|
|
106
|
+
this.busy = false;
|
|
107
|
+
};
|
|
108
|
+
const fail = (error) => {
|
|
109
|
+
cleanup();
|
|
110
|
+
reject(error);
|
|
111
|
+
};
|
|
112
|
+
const receive = (event) => {
|
|
113
|
+
if (event.origin !== this.walletOrigin || event.source !== popup || !(0, import_connect_wallet_api.isRecord)(event.data)) return;
|
|
114
|
+
const data = event.data;
|
|
115
|
+
if (data.channel !== import_connect_wallet_api.CHANNEL || data.version !== import_connect_wallet_api.VERSION || data.id !== id) return;
|
|
116
|
+
if (data.type === "ready") {
|
|
117
|
+
popup.postMessage(request, this.walletOrigin);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (data.type !== "response" || typeof data.ok !== "boolean") return;
|
|
121
|
+
const response = data;
|
|
122
|
+
cleanup();
|
|
123
|
+
if (response.ok) resolve(response.result);
|
|
124
|
+
else {
|
|
125
|
+
if (response.error.code === "UNAUTHORIZED" || response.error.code === "SESSION_EXPIRED") this.cache(null);
|
|
126
|
+
reject(new import_connect_wallet_api.ConnectError(response.error.code, response.error.message));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const poller = setInterval(() => {
|
|
130
|
+
if (popup.closed) fail(new import_connect_wallet_api.ConnectError("POPUP_CLOSED", "\u94B1\u5305\u7A97\u53E3\u5DF2\u5173\u95ED"));
|
|
131
|
+
}, 400);
|
|
132
|
+
const timer = setTimeout(() => {
|
|
133
|
+
fail(new import_connect_wallet_api.ConnectError("TIMEOUT", "\u94B1\u5305\u8BF7\u6C42\u8D85\u65F6"));
|
|
134
|
+
popup.close();
|
|
135
|
+
}, this.timeoutMs);
|
|
136
|
+
window.addEventListener("message", receive);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
141
|
+
0 && (module.exports = {
|
|
142
|
+
TopoConnect,
|
|
143
|
+
...require("@topo/connect-wallet-api")
|
|
144
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NetworkInfo, AccountInfo, SignInput, SignedResult, SubmittedResult } from '@topo/connect-wallet-api';
|
|
2
|
+
export * from '@topo/connect-wallet-api';
|
|
3
|
+
|
|
4
|
+
type TopoConnectConfig = {
|
|
5
|
+
walletUrl: string;
|
|
6
|
+
network?: NetworkInfo;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
};
|
|
9
|
+
/** Client cache is only a display hint. The wallet checks grants on every request. */
|
|
10
|
+
declare class TopoConnect {
|
|
11
|
+
readonly walletOrigin: string;
|
|
12
|
+
readonly network: NetworkInfo;
|
|
13
|
+
private busy;
|
|
14
|
+
private listeners;
|
|
15
|
+
private timeoutMs;
|
|
16
|
+
constructor(config: TopoConnectConfig);
|
|
17
|
+
private get cacheKey();
|
|
18
|
+
private cache;
|
|
19
|
+
getCachedAccount(): AccountInfo | null;
|
|
20
|
+
onAccountChange(listener: (account: AccountInfo | null) => void): () => boolean;
|
|
21
|
+
getNetwork(): {
|
|
22
|
+
name: string;
|
|
23
|
+
chainId: number;
|
|
24
|
+
};
|
|
25
|
+
connect(): Promise<AccountInfo>;
|
|
26
|
+
getAccount(): Promise<AccountInfo>;
|
|
27
|
+
disconnect(): Promise<void>;
|
|
28
|
+
signTransaction(input: SignInput): Promise<SignedResult>;
|
|
29
|
+
signAndSubmitTransaction(input: SignInput): Promise<SubmittedResult>;
|
|
30
|
+
private request;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { TopoConnect, type TopoConnectConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NetworkInfo, AccountInfo, SignInput, SignedResult, SubmittedResult } from '@topo/connect-wallet-api';
|
|
2
|
+
export * from '@topo/connect-wallet-api';
|
|
3
|
+
|
|
4
|
+
type TopoConnectConfig = {
|
|
5
|
+
walletUrl: string;
|
|
6
|
+
network?: NetworkInfo;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
};
|
|
9
|
+
/** Client cache is only a display hint. The wallet checks grants on every request. */
|
|
10
|
+
declare class TopoConnect {
|
|
11
|
+
readonly walletOrigin: string;
|
|
12
|
+
readonly network: NetworkInfo;
|
|
13
|
+
private busy;
|
|
14
|
+
private listeners;
|
|
15
|
+
private timeoutMs;
|
|
16
|
+
constructor(config: TopoConnectConfig);
|
|
17
|
+
private get cacheKey();
|
|
18
|
+
private cache;
|
|
19
|
+
getCachedAccount(): AccountInfo | null;
|
|
20
|
+
onAccountChange(listener: (account: AccountInfo | null) => void): () => boolean;
|
|
21
|
+
getNetwork(): {
|
|
22
|
+
name: string;
|
|
23
|
+
chainId: number;
|
|
24
|
+
};
|
|
25
|
+
connect(): Promise<AccountInfo>;
|
|
26
|
+
getAccount(): Promise<AccountInfo>;
|
|
27
|
+
disconnect(): Promise<void>;
|
|
28
|
+
signTransaction(input: SignInput): Promise<SignedResult>;
|
|
29
|
+
signAndSubmitTransaction(input: SignInput): Promise<SubmittedResult>;
|
|
30
|
+
private request;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { TopoConnect, type TopoConnectConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { CHANNEL, VERSION, DEVNET, ConnectError, assertNetwork, validateOrigin, isRecord } from "@topo/connect-wallet-api";
|
|
3
|
+
export * from "@topo/connect-wallet-api";
|
|
4
|
+
var TopoConnect = class {
|
|
5
|
+
walletOrigin;
|
|
6
|
+
network;
|
|
7
|
+
busy = false;
|
|
8
|
+
listeners = /* @__PURE__ */ new Set();
|
|
9
|
+
timeoutMs;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.walletOrigin = validateOrigin(config.walletUrl);
|
|
12
|
+
this.network = config.network ?? DEVNET;
|
|
13
|
+
this.timeoutMs = Math.max(1e3, Math.min(config.timeoutMs ?? 3e5, 6e5));
|
|
14
|
+
}
|
|
15
|
+
get cacheKey() {
|
|
16
|
+
return `topo-connect:v1:${this.walletOrigin}:${this.network.chainId}:${window.location.origin}`;
|
|
17
|
+
}
|
|
18
|
+
cache(account) {
|
|
19
|
+
try {
|
|
20
|
+
if (account) localStorage.setItem(this.cacheKey, JSON.stringify(account));
|
|
21
|
+
else localStorage.removeItem(this.cacheKey);
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
for (const listener of this.listeners) listener(account);
|
|
25
|
+
}
|
|
26
|
+
getCachedAccount() {
|
|
27
|
+
try {
|
|
28
|
+
const account = JSON.parse(localStorage.getItem(this.cacheKey) ?? "null");
|
|
29
|
+
if (!account || account.sessionExpiresAt <= Date.now()) return null;
|
|
30
|
+
assertNetwork(account.network, this.network);
|
|
31
|
+
return account;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
onAccountChange(listener) {
|
|
37
|
+
this.listeners.add(listener);
|
|
38
|
+
return () => this.listeners.delete(listener);
|
|
39
|
+
}
|
|
40
|
+
getNetwork() {
|
|
41
|
+
return { ...this.network };
|
|
42
|
+
}
|
|
43
|
+
async connect() {
|
|
44
|
+
const account = await this.request("connect");
|
|
45
|
+
assertNetwork(account.network, this.network);
|
|
46
|
+
this.cache(account);
|
|
47
|
+
return account;
|
|
48
|
+
}
|
|
49
|
+
async getAccount() {
|
|
50
|
+
const account = await this.request("getAccount");
|
|
51
|
+
assertNetwork(account.network, this.network);
|
|
52
|
+
this.cache(account);
|
|
53
|
+
return account;
|
|
54
|
+
}
|
|
55
|
+
async disconnect() {
|
|
56
|
+
await this.request("disconnect");
|
|
57
|
+
this.cache(null);
|
|
58
|
+
}
|
|
59
|
+
signTransaction(input) {
|
|
60
|
+
return this.request("signTransaction", input);
|
|
61
|
+
}
|
|
62
|
+
signAndSubmitTransaction(input) {
|
|
63
|
+
return this.request("signAndSubmitTransaction", input);
|
|
64
|
+
}
|
|
65
|
+
request(method, params) {
|
|
66
|
+
if (typeof window === "undefined") return Promise.reject(new ConnectError("INVALID_REQUEST", "\u8FDE\u63A5 SDK \u4EC5\u5728\u6D4F\u89C8\u5668\u4E2D\u8C03\u7528"));
|
|
67
|
+
if (this.busy) return Promise.reject(new ConnectError("BUSY", "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u94B1\u5305\u8BF7\u6C42"));
|
|
68
|
+
const id = crypto.randomUUID();
|
|
69
|
+
const request = { channel: CHANNEL, version: VERSION, type: "request", id, method, network: this.network, expiresAt: Date.now() + this.timeoutMs, ...params ? { params } : {} };
|
|
70
|
+
const url = new URL("/prompt/", this.walletOrigin);
|
|
71
|
+
url.searchParams.set("origin", window.location.origin);
|
|
72
|
+
url.searchParams.set("requestId", id);
|
|
73
|
+
const popup = window.open(url.href, `topo-${id}`, "popup,width=480,height=760");
|
|
74
|
+
if (!popup) return Promise.reject(new ConnectError("POPUP_BLOCKED", "\u8BF7\u5141\u8BB8\u5F39\u51FA Topo Connect \u7A97\u53E3"));
|
|
75
|
+
this.busy = true;
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const cleanup = () => {
|
|
78
|
+
clearInterval(poller);
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
window.removeEventListener("message", receive);
|
|
81
|
+
this.busy = false;
|
|
82
|
+
};
|
|
83
|
+
const fail = (error) => {
|
|
84
|
+
cleanup();
|
|
85
|
+
reject(error);
|
|
86
|
+
};
|
|
87
|
+
const receive = (event) => {
|
|
88
|
+
if (event.origin !== this.walletOrigin || event.source !== popup || !isRecord(event.data)) return;
|
|
89
|
+
const data = event.data;
|
|
90
|
+
if (data.channel !== CHANNEL || data.version !== VERSION || data.id !== id) return;
|
|
91
|
+
if (data.type === "ready") {
|
|
92
|
+
popup.postMessage(request, this.walletOrigin);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (data.type !== "response" || typeof data.ok !== "boolean") return;
|
|
96
|
+
const response = data;
|
|
97
|
+
cleanup();
|
|
98
|
+
if (response.ok) resolve(response.result);
|
|
99
|
+
else {
|
|
100
|
+
if (response.error.code === "UNAUTHORIZED" || response.error.code === "SESSION_EXPIRED") this.cache(null);
|
|
101
|
+
reject(new ConnectError(response.error.code, response.error.message));
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const poller = setInterval(() => {
|
|
105
|
+
if (popup.closed) fail(new ConnectError("POPUP_CLOSED", "\u94B1\u5305\u7A97\u53E3\u5DF2\u5173\u95ED"));
|
|
106
|
+
}, 400);
|
|
107
|
+
const timer = setTimeout(() => {
|
|
108
|
+
fail(new ConnectError("TIMEOUT", "\u94B1\u5305\u8BF7\u6C42\u8D85\u65F6"));
|
|
109
|
+
popup.close();
|
|
110
|
+
}, this.timeoutMs);
|
|
111
|
+
window.addEventListener("message", receive);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
export {
|
|
116
|
+
TopoConnect
|
|
117
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@topo/connect-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"require": "./dist/index.cjs"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@topo/connect-wallet-api": "^0.1.0"
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.cjs",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup src/index.ts --format esm,cjs --dts"
|
|
23
|
+
}
|
|
24
|
+
}
|