@wormhole-labs/wallet-aggregator-stacks 1.4.0-beta.1

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 ADDED
@@ -0,0 +1,3 @@
1
+ ## Wallet Aggregator - Stacks
2
+
3
+ Implements the base abstractions for the Stacks blockchain using `@stacks/connect`.
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getSupportedWallets = void 0;
18
+ const connect_1 = require("@stacks/connect");
19
+ const stacks_1 = require("./stacks");
20
+ __exportStar(require("./stacks"), exports);
21
+ // TODO: wallet connect support
22
+ const getSupportedWallets = (config) => {
23
+ return connect_1.DEFAULT_PROVIDERS.map((provider) => new stacks_1.StacksWallet(Object.assign(Object.assign({}, config), { provider })));
24
+ };
25
+ exports.getSupportedWallets = getSupportedWallets;
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6CAAoD;AAEpD,qCAA4D;AAI5D,2CAAyB;AAEzB,+BAA+B;AACxB,MAAM,mBAAmB,GAAG,CACjC,MAAyB,EACT,EAAE;IAClB,OAAO,2BAAiB,CAAC,GAAG,CAC1B,CAAC,QAAsB,EAAE,EAAE,CAAC,IAAI,qBAAY,iCAAM,MAAM,KAAE,QAAQ,IAAG,CACtE,CAAC;AACJ,CAAC,CAAC;AANW,QAAA,mBAAmB,uBAM9B"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.StacksWallet = void 0;
13
+ const connect_1 = require("@stacks/connect");
14
+ const connect_ui_1 = require("@stacks/connect-ui");
15
+ const wallet_aggregator_core_1 = require("@wormhole-labs/wallet-aggregator-core");
16
+ class StacksWallet extends wallet_aggregator_core_1.Wallet {
17
+ constructor(config) {
18
+ super();
19
+ this.provider = config.provider;
20
+ this.network = config.network;
21
+ this.walletProvider = (0, connect_ui_1.getProviderFromId)(this.provider.id);
22
+ }
23
+ getName() {
24
+ return this.provider.name;
25
+ }
26
+ getUrl() {
27
+ return this.provider.webUrl || "";
28
+ }
29
+ getIcon() {
30
+ return this.provider.icon || "";
31
+ }
32
+ getChainId() {
33
+ return wallet_aggregator_core_1.CHAIN_ID_STACKS;
34
+ }
35
+ getAddresses() {
36
+ const storage = (0, connect_1.getLocalStorage)();
37
+ const stacksAddresses = (storage === null || storage === void 0 ? void 0 : storage.addresses.stx) || [];
38
+ return stacksAddresses.map((addr) => addr.address);
39
+ }
40
+ getAddress() {
41
+ return this.address;
42
+ }
43
+ setMainAddress() {
44
+ throw new wallet_aggregator_core_1.NotSupported();
45
+ }
46
+ getBalance() {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ throw new wallet_aggregator_core_1.NotSupported();
49
+ });
50
+ }
51
+ isConnected() {
52
+ return !!this.address;
53
+ }
54
+ getNetworkInfo() {
55
+ return {
56
+ network: this.network,
57
+ };
58
+ }
59
+ connect() {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ // Check if the wallet was previously connected.
62
+ // Avoid calling `getAddresses`, since that prompts the user for approval.
63
+ if ((0, connect_1.isConnected)()) {
64
+ const selectedProviderId = (0, connect_1.getSelectedProviderId)();
65
+ if (selectedProviderId === this.provider.id) {
66
+ const addresses = this.getAddresses();
67
+ if (addresses.length > 0) {
68
+ this.address = addresses[0];
69
+ return addresses;
70
+ }
71
+ }
72
+ }
73
+ // NOTE: Xverse Wallet throws when network is passed...
74
+ const network = this.provider.name === "Xverse Wallet" ? undefined : this.network;
75
+ try {
76
+ yield (0, connect_1.request)({
77
+ provider: this.walletProvider,
78
+ }, "getAddresses", {
79
+ network,
80
+ });
81
+ const addresses = this.getAddresses();
82
+ if (addresses.length === 0) {
83
+ throw new Error("No addresses found");
84
+ }
85
+ this.address = addresses[0];
86
+ (0, connect_1.setSelectedProviderId)(this.provider.id);
87
+ this.emit("connect");
88
+ return addresses;
89
+ }
90
+ catch (error) {
91
+ throw new Error(`Failed to connect wallet: ${error.message}`);
92
+ }
93
+ });
94
+ }
95
+ disconnect() {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ (0, connect_1.disconnect)();
98
+ this.address = undefined;
99
+ this.emit("disconnect");
100
+ });
101
+ }
102
+ signTransaction(transaction) {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ if (!this.isConnected()) {
105
+ throw new wallet_aggregator_core_1.NotConnected();
106
+ }
107
+ const result = yield (0, connect_1.request)({
108
+ provider: this.walletProvider,
109
+ }, "stx_signTransaction", {
110
+ transaction,
111
+ broadcast: false,
112
+ });
113
+ return result;
114
+ });
115
+ }
116
+ sendTransaction() {
117
+ return __awaiter(this, void 0, void 0, function* () {
118
+ // TODO: @stacks/connect does not provide a way to send a signed transaction?
119
+ throw new wallet_aggregator_core_1.NotSupported();
120
+ });
121
+ }
122
+ signAndSendTransaction(tx) {
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ if (!this.isConnected()) {
125
+ throw new wallet_aggregator_core_1.NotConnected();
126
+ }
127
+ const result = yield (0, connect_1.request)({
128
+ provider: this.walletProvider,
129
+ }, "stx_callContract", {
130
+ contract: `${tx.contractAddress}.${tx.contractName}`,
131
+ functionName: tx.functionName,
132
+ functionArgs: tx.functionArgs,
133
+ network: this.network,
134
+ address: this.address,
135
+ fee: tx.fee,
136
+ });
137
+ return {
138
+ id: result.txid || "",
139
+ data: {
140
+ txId: result.txid || "",
141
+ txRaw: result.transaction,
142
+ },
143
+ };
144
+ });
145
+ }
146
+ signMessage(message) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ if (!this.isConnected()) {
149
+ throw new wallet_aggregator_core_1.NotConnected();
150
+ }
151
+ const result = yield (0, connect_1.request)({
152
+ provider: this.walletProvider,
153
+ }, "stx_signMessage", {
154
+ message,
155
+ });
156
+ return result.signature;
157
+ });
158
+ }
159
+ getWalletState() {
160
+ return this.walletProvider
161
+ ? wallet_aggregator_core_1.WalletState.Installed
162
+ : wallet_aggregator_core_1.WalletState.NotDetected;
163
+ }
164
+ getFeatures() {
165
+ return [
166
+ wallet_aggregator_core_1.BaseFeatures.SignAndSendTransaction,
167
+ wallet_aggregator_core_1.BaseFeatures.SignTransaction,
168
+ wallet_aggregator_core_1.BaseFeatures.SignMessage,
169
+ ];
170
+ }
171
+ supportsChain(chainId) {
172
+ return chainId === wallet_aggregator_core_1.CHAIN_ID_STACKS;
173
+ }
174
+ }
175
+ exports.StacksWallet = StacksWallet;
176
+ //# sourceMappingURL=stacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacks.js","sourceRoot":"","sources":["../../src/stacks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { DEFAULT_PROVIDERS } from "@stacks/connect";
2
+ import { StacksWallet } from "./stacks";
3
+ export * from "./stacks";
4
+ // TODO: wallet connect support
5
+ export const getSupportedWallets = (config) => {
6
+ return DEFAULT_PROVIDERS.map((provider) => new StacksWallet({ ...config, provider }));
7
+ };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAsB,MAAM,UAAU,CAAC;AAI5D,cAAc,UAAU,CAAC;AAEzB,+BAA+B;AAC/B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,MAAyB,EACT,EAAE;IAClB,OAAO,iBAAiB,CAAC,GAAG,CAC1B,CAAC,QAAsB,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,CACtE,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,149 @@
1
+ import { request, disconnect, getLocalStorage, getSelectedProviderId, setSelectedProviderId, isConnected, } from "@stacks/connect";
2
+ import { getProviderFromId } from "@stacks/connect-ui";
3
+ import { BaseFeatures, CHAIN_ID_STACKS, NotSupported, NotConnected, Wallet, WalletState, } from "@wormhole-labs/wallet-aggregator-core";
4
+ export class StacksWallet extends Wallet {
5
+ constructor(config) {
6
+ super();
7
+ this.provider = config.provider;
8
+ this.network = config.network;
9
+ this.walletProvider = getProviderFromId(this.provider.id);
10
+ }
11
+ getName() {
12
+ return this.provider.name;
13
+ }
14
+ getUrl() {
15
+ return this.provider.webUrl || "";
16
+ }
17
+ getIcon() {
18
+ return this.provider.icon || "";
19
+ }
20
+ getChainId() {
21
+ return CHAIN_ID_STACKS;
22
+ }
23
+ getAddresses() {
24
+ const storage = getLocalStorage();
25
+ const stacksAddresses = storage?.addresses.stx || [];
26
+ return stacksAddresses.map((addr) => addr.address);
27
+ }
28
+ getAddress() {
29
+ return this.address;
30
+ }
31
+ setMainAddress() {
32
+ throw new NotSupported();
33
+ }
34
+ async getBalance() {
35
+ throw new NotSupported();
36
+ }
37
+ isConnected() {
38
+ return !!this.address;
39
+ }
40
+ getNetworkInfo() {
41
+ return {
42
+ network: this.network,
43
+ };
44
+ }
45
+ async connect() {
46
+ // Check if the wallet was previously connected.
47
+ // Avoid calling `getAddresses`, since that prompts the user for approval.
48
+ if (isConnected()) {
49
+ const selectedProviderId = getSelectedProviderId();
50
+ if (selectedProviderId === this.provider.id) {
51
+ const addresses = this.getAddresses();
52
+ if (addresses.length > 0) {
53
+ this.address = addresses[0];
54
+ return addresses;
55
+ }
56
+ }
57
+ }
58
+ // NOTE: Xverse Wallet throws when network is passed...
59
+ const network = this.provider.name === "Xverse Wallet" ? undefined : this.network;
60
+ try {
61
+ await request({
62
+ provider: this.walletProvider,
63
+ }, "getAddresses", {
64
+ network,
65
+ });
66
+ const addresses = this.getAddresses();
67
+ if (addresses.length === 0) {
68
+ throw new Error("No addresses found");
69
+ }
70
+ this.address = addresses[0];
71
+ setSelectedProviderId(this.provider.id);
72
+ this.emit("connect");
73
+ return addresses;
74
+ }
75
+ catch (error) {
76
+ throw new Error(`Failed to connect wallet: ${error.message}`);
77
+ }
78
+ }
79
+ async disconnect() {
80
+ disconnect();
81
+ this.address = undefined;
82
+ this.emit("disconnect");
83
+ }
84
+ async signTransaction(transaction) {
85
+ if (!this.isConnected()) {
86
+ throw new NotConnected();
87
+ }
88
+ const result = await request({
89
+ provider: this.walletProvider,
90
+ }, "stx_signTransaction", {
91
+ transaction,
92
+ broadcast: false,
93
+ });
94
+ return result;
95
+ }
96
+ async sendTransaction() {
97
+ // TODO: @stacks/connect does not provide a way to send a signed transaction?
98
+ throw new NotSupported();
99
+ }
100
+ async signAndSendTransaction(tx) {
101
+ if (!this.isConnected()) {
102
+ throw new NotConnected();
103
+ }
104
+ const result = await request({
105
+ provider: this.walletProvider,
106
+ }, "stx_callContract", {
107
+ contract: `${tx.contractAddress}.${tx.contractName}`,
108
+ functionName: tx.functionName,
109
+ functionArgs: tx.functionArgs,
110
+ network: this.network,
111
+ address: this.address,
112
+ fee: tx.fee,
113
+ });
114
+ return {
115
+ id: result.txid || "",
116
+ data: {
117
+ txId: result.txid || "",
118
+ txRaw: result.transaction,
119
+ },
120
+ };
121
+ }
122
+ async signMessage(message) {
123
+ if (!this.isConnected()) {
124
+ throw new NotConnected();
125
+ }
126
+ const result = await request({
127
+ provider: this.walletProvider,
128
+ }, "stx_signMessage", {
129
+ message,
130
+ });
131
+ return result.signature;
132
+ }
133
+ getWalletState() {
134
+ return this.walletProvider
135
+ ? WalletState.Installed
136
+ : WalletState.NotDetected;
137
+ }
138
+ getFeatures() {
139
+ return [
140
+ BaseFeatures.SignAndSendTransaction,
141
+ BaseFeatures.SignTransaction,
142
+ BaseFeatures.SignMessage,
143
+ ];
144
+ }
145
+ supportsChain(chainId) {
146
+ return chainId === CHAIN_ID_STACKS;
147
+ }
148
+ }
149
+ //# sourceMappingURL=stacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacks.js","sourceRoot":"","sources":["../../src/stacks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { StacksWallet, StacksWalletConfig } from "./stacks";
2
+ export type GetWalletsOptions = Omit<StacksWalletConfig, "provider">;
3
+ export * from "./stacks";
4
+ export declare const getSupportedWallets: (config: GetWalletsOptions) => StacksWallet[];
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;AAErE,cAAc,UAAU,CAAC;AAGzB,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,iBAAiB,KACxB,YAAY,EAId,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { ContractCallPayload, WbipProvider } from "@stacks/connect";
2
+ import { BaseFeatures, SendTransactionResult, Wallet, WalletState } from "@wormhole-labs/wallet-aggregator-core";
3
+ export interface StacksWalletConfig {
4
+ provider: WbipProvider;
5
+ network: "mainnet" | "testnet";
6
+ }
7
+ export type StacksContractCallInput = ContractCallPayload;
8
+ export interface StacksTransactionResult {
9
+ txId: string;
10
+ txRaw?: string;
11
+ }
12
+ export declare class StacksWallet extends Wallet {
13
+ private provider;
14
+ private network;
15
+ private walletProvider;
16
+ private address?;
17
+ constructor(config: StacksWalletConfig);
18
+ getName(): string;
19
+ getUrl(): string;
20
+ getIcon(): string;
21
+ getChainId(): 60;
22
+ getAddresses(): string[];
23
+ getAddress(): string | undefined;
24
+ setMainAddress(): void;
25
+ getBalance(): Promise<string>;
26
+ isConnected(): boolean;
27
+ getNetworkInfo(): {
28
+ network: "mainnet" | "testnet";
29
+ };
30
+ connect(): Promise<string[]>;
31
+ disconnect(): Promise<void>;
32
+ signTransaction(transaction: string): Promise<import("@stacks/connect/dist/types/methods").SignTransactionResult>;
33
+ sendTransaction(): Promise<never>;
34
+ signAndSendTransaction(tx: StacksContractCallInput): Promise<SendTransactionResult<StacksTransactionResult>>;
35
+ signMessage(message: string): Promise<string>;
36
+ getWalletState(): WalletState;
37
+ getFeatures(): BaseFeatures[];
38
+ supportsChain(chainId: number): boolean;
39
+ }
40
+ //# sourceMappingURL=stacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacks.d.ts","sourceRoot":"","sources":["../../src/stacks.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EACL,YAAY,EAIZ,qBAAqB,EACrB,MAAM,EACN,WAAW,EACZ,MAAM,uCAAuC,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAa,SAAQ,MAAM;IACtC,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAS;gBAEb,MAAM,EAAE,kBAAkB;IAOtC,OAAO,IAAI,MAAM;IAIjB,MAAM,IAAI,MAAM;IAIhB,OAAO,IAAI,MAAM;IAIjB,UAAU;IAIV,YAAY,IAAI,MAAM,EAAE;IAMxB,UAAU,IAAI,MAAM,GAAG,SAAS;IAIhC,cAAc,IAAI,IAAI;IAIhB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,WAAW,IAAI,OAAO;IAItB,cAAc;;;IAMR,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA6C5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,eAAe,CAAC,WAAW,EAAE,MAAM;IAmBnC,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC;IAKjC,sBAAsB,CAC1B,EAAE,EAAE,uBAAuB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,CAAC;IA6BpD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBnD,cAAc,IAAI,WAAW;IAM7B,WAAW,IAAI,YAAY,EAAE;IAQ7B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;CAGxC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@wormhole-labs/wallet-aggregator-stacks",
3
+ "repository": "https://github.com/wormholelabs-xyz/wallet-aggregator-sdk/tree/master/packages/wallets/stacks",
4
+ "version": "1.4.0-beta.1",
5
+ "license": "MIT",
6
+ "main": "dist/cjs/index.js",
7
+ "module": "dist/esm/index.js",
8
+ "types": "dist/types/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/esm/index.js",
12
+ "require": "./dist/cjs/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build:cjs": "tsc -p tsconfig.cjs.json",
17
+ "build:esm": "tsc -p tsconfig.esm.json",
18
+ "build": "shx rm -rf dist && npm run build:cjs && npm run build:esm",
19
+ "clean": "shx rm -rf dist",
20
+ "prepublish": "npm run build"
21
+ },
22
+ "files": [
23
+ "dist/",
24
+ "src/"
25
+ ],
26
+ "devDependencies": {
27
+ "@types/node": "^18.19.69",
28
+ "shx": "^0.3.4",
29
+ "typescript": "^5.7.2"
30
+ },
31
+ "dependencies": {
32
+ "@stacks/connect": "^8.2.3",
33
+ "@stacks/connect-ui": "^8.1.1",
34
+ "@wormhole-labs/wallet-aggregator-core": "1.4.0-beta.1"
35
+ }
36
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { DEFAULT_PROVIDERS } from "@stacks/connect";
2
+ import type { WbipProvider } from "@stacks/connect";
3
+ import { StacksWallet, StacksWalletConfig } from "./stacks";
4
+
5
+ export type GetWalletsOptions = Omit<StacksWalletConfig, "provider">;
6
+
7
+ export * from "./stacks";
8
+
9
+ // TODO: wallet connect support
10
+ export const getSupportedWallets = (
11
+ config: GetWalletsOptions
12
+ ): StacksWallet[] => {
13
+ return DEFAULT_PROVIDERS.map(
14
+ (provider: WbipProvider) => new StacksWallet({ ...config, provider })
15
+ );
16
+ };
package/src/stacks.ts ADDED
@@ -0,0 +1,231 @@
1
+ import {
2
+ request,
3
+ disconnect,
4
+ getLocalStorage,
5
+ getSelectedProviderId,
6
+ setSelectedProviderId,
7
+ isConnected,
8
+ } from "@stacks/connect";
9
+ import type { ContractCallPayload, WbipProvider } from "@stacks/connect";
10
+ import { getProviderFromId } from "@stacks/connect-ui";
11
+ import {
12
+ BaseFeatures,
13
+ CHAIN_ID_STACKS,
14
+ NotSupported,
15
+ NotConnected,
16
+ SendTransactionResult,
17
+ Wallet,
18
+ WalletState,
19
+ } from "@wormhole-labs/wallet-aggregator-core";
20
+
21
+ export interface StacksWalletConfig {
22
+ provider: WbipProvider;
23
+ network: "mainnet" | "testnet";
24
+ }
25
+
26
+ export type StacksContractCallInput = ContractCallPayload;
27
+
28
+ export interface StacksTransactionResult {
29
+ txId: string;
30
+ txRaw?: string;
31
+ }
32
+
33
+ export class StacksWallet extends Wallet {
34
+ private provider: WbipProvider;
35
+ private network: "mainnet" | "testnet";
36
+ private walletProvider: any; // implementation-specific wallet provider
37
+ private address?: string;
38
+
39
+ constructor(config: StacksWalletConfig) {
40
+ super();
41
+ this.provider = config.provider;
42
+ this.network = config.network;
43
+ this.walletProvider = getProviderFromId(this.provider.id);
44
+ }
45
+
46
+ getName(): string {
47
+ return this.provider.name;
48
+ }
49
+
50
+ getUrl(): string {
51
+ return this.provider.webUrl || "";
52
+ }
53
+
54
+ getIcon(): string {
55
+ return this.provider.icon || "";
56
+ }
57
+
58
+ getChainId() {
59
+ return CHAIN_ID_STACKS;
60
+ }
61
+
62
+ getAddresses(): string[] {
63
+ const storage = getLocalStorage();
64
+ const stacksAddresses = storage?.addresses.stx || [];
65
+ return stacksAddresses.map((addr) => addr.address);
66
+ }
67
+
68
+ getAddress(): string | undefined {
69
+ return this.address;
70
+ }
71
+
72
+ setMainAddress(): void {
73
+ throw new NotSupported();
74
+ }
75
+
76
+ async getBalance(): Promise<string> {
77
+ throw new NotSupported();
78
+ }
79
+
80
+ isConnected(): boolean {
81
+ return !!this.address;
82
+ }
83
+
84
+ getNetworkInfo() {
85
+ return {
86
+ network: this.network,
87
+ };
88
+ }
89
+
90
+ async connect(): Promise<string[]> {
91
+ // Check if the wallet was previously connected.
92
+ // Avoid calling `getAddresses`, since that prompts the user for approval.
93
+ if (isConnected()) {
94
+ const selectedProviderId = getSelectedProviderId();
95
+ if (selectedProviderId === this.provider.id) {
96
+ const addresses = this.getAddresses();
97
+ if (addresses.length > 0) {
98
+ this.address = addresses[0];
99
+ return addresses;
100
+ }
101
+ }
102
+ }
103
+
104
+ // NOTE: Xverse Wallet throws when network is passed...
105
+ const network =
106
+ this.provider.name === "Xverse Wallet" ? undefined : this.network;
107
+
108
+ try {
109
+ await request(
110
+ {
111
+ provider: this.walletProvider,
112
+ },
113
+ "getAddresses",
114
+ {
115
+ network,
116
+ }
117
+ );
118
+
119
+ const addresses = this.getAddresses();
120
+ if (addresses.length === 0) {
121
+ throw new Error("No addresses found");
122
+ }
123
+ this.address = addresses[0];
124
+
125
+ setSelectedProviderId(this.provider.id);
126
+
127
+ this.emit("connect");
128
+
129
+ return addresses;
130
+ } catch (error: any) {
131
+ throw new Error(`Failed to connect wallet: ${error.message}`);
132
+ }
133
+ }
134
+
135
+ async disconnect(): Promise<void> {
136
+ disconnect();
137
+ this.address = undefined;
138
+ this.emit("disconnect");
139
+ }
140
+
141
+ async signTransaction(transaction: string) {
142
+ if (!this.isConnected()) {
143
+ throw new NotConnected();
144
+ }
145
+
146
+ const result = await request(
147
+ {
148
+ provider: this.walletProvider,
149
+ },
150
+ "stx_signTransaction",
151
+ {
152
+ transaction,
153
+ broadcast: false,
154
+ }
155
+ );
156
+
157
+ return result;
158
+ }
159
+
160
+ async sendTransaction(): Promise<never> {
161
+ // TODO: @stacks/connect does not provide a way to send a signed transaction?
162
+ throw new NotSupported();
163
+ }
164
+
165
+ async signAndSendTransaction(
166
+ tx: StacksContractCallInput
167
+ ): Promise<SendTransactionResult<StacksTransactionResult>> {
168
+ if (!this.isConnected()) {
169
+ throw new NotConnected();
170
+ }
171
+
172
+ const result = await request(
173
+ {
174
+ provider: this.walletProvider,
175
+ },
176
+ "stx_callContract",
177
+ {
178
+ contract: `${tx.contractAddress}.${tx.contractName}`,
179
+ functionName: tx.functionName,
180
+ functionArgs: tx.functionArgs,
181
+ network: this.network,
182
+ address: this.address,
183
+ fee: tx.fee,
184
+ }
185
+ );
186
+
187
+ return {
188
+ id: result.txid || "",
189
+ data: {
190
+ txId: result.txid || "",
191
+ txRaw: result.transaction,
192
+ },
193
+ };
194
+ }
195
+
196
+ async signMessage(message: string): Promise<string> {
197
+ if (!this.isConnected()) {
198
+ throw new NotConnected();
199
+ }
200
+
201
+ const result = await request(
202
+ {
203
+ provider: this.walletProvider,
204
+ },
205
+ "stx_signMessage",
206
+ {
207
+ message,
208
+ }
209
+ );
210
+
211
+ return result.signature;
212
+ }
213
+
214
+ getWalletState(): WalletState {
215
+ return this.walletProvider
216
+ ? WalletState.Installed
217
+ : WalletState.NotDetected;
218
+ }
219
+
220
+ getFeatures(): BaseFeatures[] {
221
+ return [
222
+ BaseFeatures.SignAndSendTransaction,
223
+ BaseFeatures.SignTransaction,
224
+ BaseFeatures.SignMessage,
225
+ ];
226
+ }
227
+
228
+ supportsChain(chainId: number): boolean {
229
+ return chainId === CHAIN_ID_STACKS;
230
+ }
231
+ }