@topo/connect-wallet-plugin 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 ADDED
@@ -0,0 +1,132 @@
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ TopoConnectWallet: () => TopoConnectWallet,
24
+ hexBytes: () => hexBytes,
25
+ registerTopoConnect: () => registerTopoConnect
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_connect_sdk = require("@topo/connect-sdk");
29
+ var import_wallet_standard = require("@aptos-labs/wallet-standard");
30
+ var import_ts_sdk = require("@aptos-labs/ts-sdk");
31
+ var icon = "data:image/svg+xml;base64," + btoa('<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><rect width="64" height="64" rx="16" fill="#171b21"/><path d="M14 20h36M32 20v28M20 32h24" stroke="#bbf76b" stroke-width="7" stroke-linecap="round"/></svg>');
32
+ var TopoConnectWallet = class {
33
+ constructor(config) {
34
+ this.config = config;
35
+ this.client = new import_connect_sdk.TopoConnect(config);
36
+ this.url = this.client.walletOrigin;
37
+ this.chains = [`topo:${this.client.network.chainId}`];
38
+ this.client.onAccountChange((account) => {
39
+ if (account) for (const fn of this.accountListeners) fn(this.toStandard(account));
40
+ });
41
+ }
42
+ config;
43
+ name = "Topo Connect";
44
+ version = "1.0.0";
45
+ icon = icon;
46
+ isTopoNativeWallet = true;
47
+ url;
48
+ chains;
49
+ client;
50
+ accountListeners = /* @__PURE__ */ new Set();
51
+ toStandard(account) {
52
+ return new import_wallet_standard.AccountInfo({ address: import_ts_sdk.AccountAddress.from(account.address), publicKey: import_ts_sdk.AnyPublicKey.deserialize(new import_ts_sdk.Deserializer(hexBytes(account.publicKeyBcs))) });
53
+ }
54
+ get accounts() {
55
+ const a = this.client.getCachedAccount();
56
+ return a ? [{ address: a.address, publicKey: hexBytes(a.publicKeyBcs), chains: this.chains, features: ["aptos:signTransaction", "aptos:signAndSubmitTransaction"], signingScheme: 2 }] : [];
57
+ }
58
+ async approved(run) {
59
+ try {
60
+ return { status: import_wallet_standard.UserResponseStatus.APPROVED, args: await run() };
61
+ } catch (e) {
62
+ if (e instanceof import_connect_sdk.ConnectError && ["USER_REJECTED", "POPUP_CLOSED"].includes(e.code)) return { status: import_wallet_standard.UserResponseStatus.REJECTED };
63
+ throw e;
64
+ }
65
+ }
66
+ sender() {
67
+ const a = this.client.getCachedAccount();
68
+ if (!a) throw new import_connect_sdk.ConnectError("UNAUTHORIZED", "\u8BF7\u5148\u8FDE\u63A5\u94B1\u5305");
69
+ return a.address;
70
+ }
71
+ signTransaction(input, asFeePayer) {
72
+ return this.approved(async () => {
73
+ let request;
74
+ if ("rawTransaction" in input) {
75
+ if (asFeePayer || input.feePayerAddress || input.secondarySignerAddresses?.length) throw new import_connect_sdk.ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301\u5355\u7B7E\u4EA4\u6613");
76
+ request = { sender: this.sender(), rawTransactionBcs: input.rawTransaction.bcsToHex().toString() };
77
+ } else {
78
+ if (input.feePayer || input.secondarySigners?.length) throw new import_connect_sdk.ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301\u5355\u7B7E\u4EA4\u6613");
79
+ if (input.signerAddress && input.signerAddress.toString() !== this.sender()) throw new import_connect_sdk.ConnectError("UNAUTHORIZED", "\u7B7E\u540D\u8D26\u6237\u4E0D\u5339\u914D");
80
+ if (input.network && input.network !== import_ts_sdk.Network.CUSTOM) throw new import_connect_sdk.ConnectError("NETWORK_MISMATCH", "Topo \u63D2\u4EF6\u4F7F\u7528\u663E\u5F0F chain ID\uFF0C\u8BF7\u52FF\u4F20\u5165 Aptos \u7F51\u7EDC\u540D");
81
+ request = { sender: input.sender?.address.toString() ?? this.sender(), payload: normalizePayload(input.payload), gasUnitPrice: input.gasUnitPrice, maxGasAmount: input.maxGasAmount, expirationTimestamp: input.expirationTimestamp ?? (input.expirationSecondsFromNow ? Math.floor(Date.now() / 1e3) + input.expirationSecondsFromNow : void 0), sequenceNumber: input.sequenceNumber?.toString() };
82
+ }
83
+ const result = await this.client.signTransaction(request);
84
+ if ("rawTransactionBcs" in request && result.rawTransactionBcs !== request.rawTransactionBcs) throw new import_connect_sdk.ConnectError("INVALID_REQUEST", "\u94B1\u5305\u8FD4\u56DE\u7684\u4EA4\u6613\u4E0E\u8BF7\u6C42\u4E0D\u4E00\u81F4");
85
+ const authenticator = import_ts_sdk.AccountAuthenticator.deserialize(new import_ts_sdk.Deserializer(hexBytes(result.authenticatorBcs)));
86
+ if ("rawTransaction" in input) return authenticator;
87
+ return { authenticator, rawTransaction: new import_ts_sdk.SimpleTransaction(import_ts_sdk.RawTransaction.deserialize(new import_ts_sdk.Deserializer(hexBytes(result.rawTransactionBcs)))) };
88
+ });
89
+ }
90
+ get features() {
91
+ return {
92
+ "aptos:connect": { version: "1.0.0", connect: () => this.approved(async () => this.toStandard(await this.client.connect())) },
93
+ "aptos:disconnect": { version: "1.0.0", disconnect: () => this.client.disconnect() },
94
+ "aptos:account": { version: "1.0.0", account: async () => {
95
+ const a = this.client.getCachedAccount();
96
+ if (!a) throw new import_connect_sdk.ConnectError("UNAUTHORIZED", "\u8BF7\u5148\u8FDE\u63A5\u94B1\u5305");
97
+ return this.toStandard(a);
98
+ } },
99
+ "aptos:network": { version: "1.0.0", network: async () => ({ name: import_ts_sdk.Network.CUSTOM, chainId: this.client.network.chainId, url: this.config.rpcUrl }) },
100
+ "aptos:onAccountChange": { version: "1.0.0", onAccountChange: async (fn) => {
101
+ this.accountListeners.add(fn);
102
+ } },
103
+ "aptos:onNetworkChange": { version: "1.0.0", onNetworkChange: async () => {
104
+ } },
105
+ "aptos:signMessage": { version: "1.0.0", signMessage: async () => {
106
+ throw new import_connect_sdk.ConnectError("INVALID_REQUEST", "\u9996\u7248\u4E0D\u652F\u6301\u94FE\u4E0B\u6D88\u606F\u7B7E\u540D");
107
+ } },
108
+ "aptos:signTransaction": { version: "1.1.0", signTransaction: this.signTransaction.bind(this) },
109
+ "aptos:signAndSubmitTransaction": { version: "1.1.0", signAndSubmitTransaction: (input) => this.approved(async () => this.client.signAndSubmitTransaction({ sender: this.sender(), payload: normalizePayload(input.payload), maxGasAmount: input.maxGasAmount, gasUnitPrice: input.gasUnitPrice })) }
110
+ };
111
+ }
112
+ };
113
+ function hexBytes(hex) {
114
+ return Uint8Array.from((hex.replace(/^0x/, "").match(/.{2}/g) ?? []).map((b) => parseInt(b, 16)));
115
+ }
116
+ function normalizePayload(payload) {
117
+ if (payload && typeof payload === "object" && "bcsToHex" in payload && typeof payload.bcsToHex === "function") return { bcs: payload.bcsToHex().toString() };
118
+ if (!payload || typeof payload !== "object" || !("function" in payload)) throw new import_connect_sdk.ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301 JSON Entry Function \u4EA4\u6613");
119
+ const p = payload;
120
+ return { function: p.function, typeArguments: (p.typeArguments ?? []).map(String), functionArguments: p.functionArguments ?? [] };
121
+ }
122
+ function registerTopoConnect(config) {
123
+ const wallet = new TopoConnectWallet(config);
124
+ (0, import_wallet_standard.registerWallet)(wallet);
125
+ return wallet;
126
+ }
127
+ // Annotate the CommonJS export names for ESM import in node:
128
+ 0 && (module.exports = {
129
+ TopoConnectWallet,
130
+ hexBytes,
131
+ registerTopoConnect
132
+ });
@@ -0,0 +1,37 @@
1
+ import { TopoConnectConfig, TopoConnect } from '@topo/connect-sdk';
2
+ import { AptosWallet, UserResponse, AptosSignTransactionInputV1_1, AptosSignTransactionOutputV1_1, AptosFeatures, AptosSignAndSubmitTransactionFeature } from '@aptos-labs/wallet-standard';
3
+ import { AnyRawTransaction, AccountAuthenticator } from '@aptos-labs/ts-sdk';
4
+
5
+ type TopoConnectWalletConfig = TopoConnectConfig & {
6
+ rpcUrl: string;
7
+ };
8
+ /** BCS is the explicit boundary between the Topo signer and Aptos Wallet Standard. */
9
+ declare class TopoConnectWallet implements AptosWallet {
10
+ readonly config: TopoConnectWalletConfig;
11
+ readonly name = "Topo Connect";
12
+ readonly version: "1.0.0";
13
+ readonly icon: `data:image/svg+xml;base64,${string}`;
14
+ readonly isTopoNativeWallet = true;
15
+ readonly url: string;
16
+ readonly chains: readonly `${string}:${string}`[];
17
+ readonly client: TopoConnect;
18
+ private accountListeners;
19
+ constructor(config: TopoConnectWalletConfig);
20
+ private toStandard;
21
+ get accounts(): {
22
+ address: string;
23
+ publicKey: Uint8Array<ArrayBuffer>;
24
+ chains: readonly `${string}:${string}`[];
25
+ features: readonly ["aptos:signTransaction", "aptos:signAndSubmitTransaction"];
26
+ signingScheme: 2;
27
+ }[];
28
+ private approved;
29
+ private sender;
30
+ signTransaction(input: AnyRawTransaction, asFeePayer?: boolean): Promise<UserResponse<AccountAuthenticator>>;
31
+ signTransaction(input: AptosSignTransactionInputV1_1): Promise<UserResponse<AptosSignTransactionOutputV1_1>>;
32
+ get features(): AptosFeatures & AptosSignAndSubmitTransactionFeature;
33
+ }
34
+ declare function hexBytes(hex: string): Uint8Array<ArrayBuffer>;
35
+ declare function registerTopoConnect(config: TopoConnectWalletConfig): TopoConnectWallet;
36
+
37
+ export { TopoConnectWallet, type TopoConnectWalletConfig, hexBytes, registerTopoConnect };
@@ -0,0 +1,37 @@
1
+ import { TopoConnectConfig, TopoConnect } from '@topo/connect-sdk';
2
+ import { AptosWallet, UserResponse, AptosSignTransactionInputV1_1, AptosSignTransactionOutputV1_1, AptosFeatures, AptosSignAndSubmitTransactionFeature } from '@aptos-labs/wallet-standard';
3
+ import { AnyRawTransaction, AccountAuthenticator } from '@aptos-labs/ts-sdk';
4
+
5
+ type TopoConnectWalletConfig = TopoConnectConfig & {
6
+ rpcUrl: string;
7
+ };
8
+ /** BCS is the explicit boundary between the Topo signer and Aptos Wallet Standard. */
9
+ declare class TopoConnectWallet implements AptosWallet {
10
+ readonly config: TopoConnectWalletConfig;
11
+ readonly name = "Topo Connect";
12
+ readonly version: "1.0.0";
13
+ readonly icon: `data:image/svg+xml;base64,${string}`;
14
+ readonly isTopoNativeWallet = true;
15
+ readonly url: string;
16
+ readonly chains: readonly `${string}:${string}`[];
17
+ readonly client: TopoConnect;
18
+ private accountListeners;
19
+ constructor(config: TopoConnectWalletConfig);
20
+ private toStandard;
21
+ get accounts(): {
22
+ address: string;
23
+ publicKey: Uint8Array<ArrayBuffer>;
24
+ chains: readonly `${string}:${string}`[];
25
+ features: readonly ["aptos:signTransaction", "aptos:signAndSubmitTransaction"];
26
+ signingScheme: 2;
27
+ }[];
28
+ private approved;
29
+ private sender;
30
+ signTransaction(input: AnyRawTransaction, asFeePayer?: boolean): Promise<UserResponse<AccountAuthenticator>>;
31
+ signTransaction(input: AptosSignTransactionInputV1_1): Promise<UserResponse<AptosSignTransactionOutputV1_1>>;
32
+ get features(): AptosFeatures & AptosSignAndSubmitTransactionFeature;
33
+ }
34
+ declare function hexBytes(hex: string): Uint8Array<ArrayBuffer>;
35
+ declare function registerTopoConnect(config: TopoConnectWalletConfig): TopoConnectWallet;
36
+
37
+ export { TopoConnectWallet, type TopoConnectWalletConfig, hexBytes, registerTopoConnect };
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ // src/index.ts
2
+ import { TopoConnect, ConnectError } from "@topo/connect-sdk";
3
+ import { AccountInfo, UserResponseStatus, registerWallet } from "@aptos-labs/wallet-standard";
4
+ import { AccountAddress, AnyPublicKey, Deserializer, AccountAuthenticator, SimpleTransaction, RawTransaction, Network } from "@aptos-labs/ts-sdk";
5
+ var icon = "data:image/svg+xml;base64," + btoa('<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><rect width="64" height="64" rx="16" fill="#171b21"/><path d="M14 20h36M32 20v28M20 32h24" stroke="#bbf76b" stroke-width="7" stroke-linecap="round"/></svg>');
6
+ var TopoConnectWallet = class {
7
+ constructor(config) {
8
+ this.config = config;
9
+ this.client = new TopoConnect(config);
10
+ this.url = this.client.walletOrigin;
11
+ this.chains = [`topo:${this.client.network.chainId}`];
12
+ this.client.onAccountChange((account) => {
13
+ if (account) for (const fn of this.accountListeners) fn(this.toStandard(account));
14
+ });
15
+ }
16
+ config;
17
+ name = "Topo Connect";
18
+ version = "1.0.0";
19
+ icon = icon;
20
+ isTopoNativeWallet = true;
21
+ url;
22
+ chains;
23
+ client;
24
+ accountListeners = /* @__PURE__ */ new Set();
25
+ toStandard(account) {
26
+ return new AccountInfo({ address: AccountAddress.from(account.address), publicKey: AnyPublicKey.deserialize(new Deserializer(hexBytes(account.publicKeyBcs))) });
27
+ }
28
+ get accounts() {
29
+ const a = this.client.getCachedAccount();
30
+ return a ? [{ address: a.address, publicKey: hexBytes(a.publicKeyBcs), chains: this.chains, features: ["aptos:signTransaction", "aptos:signAndSubmitTransaction"], signingScheme: 2 }] : [];
31
+ }
32
+ async approved(run) {
33
+ try {
34
+ return { status: UserResponseStatus.APPROVED, args: await run() };
35
+ } catch (e) {
36
+ if (e instanceof ConnectError && ["USER_REJECTED", "POPUP_CLOSED"].includes(e.code)) return { status: UserResponseStatus.REJECTED };
37
+ throw e;
38
+ }
39
+ }
40
+ sender() {
41
+ const a = this.client.getCachedAccount();
42
+ if (!a) throw new ConnectError("UNAUTHORIZED", "\u8BF7\u5148\u8FDE\u63A5\u94B1\u5305");
43
+ return a.address;
44
+ }
45
+ signTransaction(input, asFeePayer) {
46
+ return this.approved(async () => {
47
+ let request;
48
+ if ("rawTransaction" in input) {
49
+ if (asFeePayer || input.feePayerAddress || input.secondarySignerAddresses?.length) throw new ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301\u5355\u7B7E\u4EA4\u6613");
50
+ request = { sender: this.sender(), rawTransactionBcs: input.rawTransaction.bcsToHex().toString() };
51
+ } else {
52
+ if (input.feePayer || input.secondarySigners?.length) throw new ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301\u5355\u7B7E\u4EA4\u6613");
53
+ if (input.signerAddress && input.signerAddress.toString() !== this.sender()) throw new ConnectError("UNAUTHORIZED", "\u7B7E\u540D\u8D26\u6237\u4E0D\u5339\u914D");
54
+ if (input.network && input.network !== Network.CUSTOM) throw new ConnectError("NETWORK_MISMATCH", "Topo \u63D2\u4EF6\u4F7F\u7528\u663E\u5F0F chain ID\uFF0C\u8BF7\u52FF\u4F20\u5165 Aptos \u7F51\u7EDC\u540D");
55
+ request = { sender: input.sender?.address.toString() ?? this.sender(), payload: normalizePayload(input.payload), gasUnitPrice: input.gasUnitPrice, maxGasAmount: input.maxGasAmount, expirationTimestamp: input.expirationTimestamp ?? (input.expirationSecondsFromNow ? Math.floor(Date.now() / 1e3) + input.expirationSecondsFromNow : void 0), sequenceNumber: input.sequenceNumber?.toString() };
56
+ }
57
+ const result = await this.client.signTransaction(request);
58
+ if ("rawTransactionBcs" in request && result.rawTransactionBcs !== request.rawTransactionBcs) throw new ConnectError("INVALID_REQUEST", "\u94B1\u5305\u8FD4\u56DE\u7684\u4EA4\u6613\u4E0E\u8BF7\u6C42\u4E0D\u4E00\u81F4");
59
+ const authenticator = AccountAuthenticator.deserialize(new Deserializer(hexBytes(result.authenticatorBcs)));
60
+ if ("rawTransaction" in input) return authenticator;
61
+ return { authenticator, rawTransaction: new SimpleTransaction(RawTransaction.deserialize(new Deserializer(hexBytes(result.rawTransactionBcs)))) };
62
+ });
63
+ }
64
+ get features() {
65
+ return {
66
+ "aptos:connect": { version: "1.0.0", connect: () => this.approved(async () => this.toStandard(await this.client.connect())) },
67
+ "aptos:disconnect": { version: "1.0.0", disconnect: () => this.client.disconnect() },
68
+ "aptos:account": { version: "1.0.0", account: async () => {
69
+ const a = this.client.getCachedAccount();
70
+ if (!a) throw new ConnectError("UNAUTHORIZED", "\u8BF7\u5148\u8FDE\u63A5\u94B1\u5305");
71
+ return this.toStandard(a);
72
+ } },
73
+ "aptos:network": { version: "1.0.0", network: async () => ({ name: Network.CUSTOM, chainId: this.client.network.chainId, url: this.config.rpcUrl }) },
74
+ "aptos:onAccountChange": { version: "1.0.0", onAccountChange: async (fn) => {
75
+ this.accountListeners.add(fn);
76
+ } },
77
+ "aptos:onNetworkChange": { version: "1.0.0", onNetworkChange: async () => {
78
+ } },
79
+ "aptos:signMessage": { version: "1.0.0", signMessage: async () => {
80
+ throw new ConnectError("INVALID_REQUEST", "\u9996\u7248\u4E0D\u652F\u6301\u94FE\u4E0B\u6D88\u606F\u7B7E\u540D");
81
+ } },
82
+ "aptos:signTransaction": { version: "1.1.0", signTransaction: this.signTransaction.bind(this) },
83
+ "aptos:signAndSubmitTransaction": { version: "1.1.0", signAndSubmitTransaction: (input) => this.approved(async () => this.client.signAndSubmitTransaction({ sender: this.sender(), payload: normalizePayload(input.payload), maxGasAmount: input.maxGasAmount, gasUnitPrice: input.gasUnitPrice })) }
84
+ };
85
+ }
86
+ };
87
+ function hexBytes(hex) {
88
+ return Uint8Array.from((hex.replace(/^0x/, "").match(/.{2}/g) ?? []).map((b) => parseInt(b, 16)));
89
+ }
90
+ function normalizePayload(payload) {
91
+ if (payload && typeof payload === "object" && "bcsToHex" in payload && typeof payload.bcsToHex === "function") return { bcs: payload.bcsToHex().toString() };
92
+ if (!payload || typeof payload !== "object" || !("function" in payload)) throw new ConnectError("INVALID_REQUEST", "\u9996\u7248\u4EC5\u652F\u6301 JSON Entry Function \u4EA4\u6613");
93
+ const p = payload;
94
+ return { function: p.function, typeArguments: (p.typeArguments ?? []).map(String), functionArguments: p.functionArguments ?? [] };
95
+ }
96
+ function registerTopoConnect(config) {
97
+ const wallet = new TopoConnectWallet(config);
98
+ registerWallet(wallet);
99
+ return wallet;
100
+ }
101
+ export {
102
+ TopoConnectWallet,
103
+ hexBytes,
104
+ registerTopoConnect
105
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@topo/connect-wallet-plugin",
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-sdk": "^0.1.0",
17
+ "@topo/connect-wallet-api": "^0.1.0"
18
+ },
19
+ "peerDependencies": {
20
+ "@topo/ts-sdk": "^6.3.0",
21
+ "@aptos-labs/ts-sdk": "^5.1.1",
22
+ "@aptos-labs/wallet-standard": "^0.5.2"
23
+ },
24
+ "main": "./dist/index.cjs",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "scripts": {
28
+ "build": "tsup src/index.ts --format esm,cjs --dts"
29
+ }
30
+ }