@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 +3 -0
- package/dist/cjs/index.js +26 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/stacks.js +176 -0
- package/dist/cjs/stacks.js.map +1 -0
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/stacks.js +149 -0
- package/dist/esm/stacks.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/stacks.d.ts +40 -0
- package/dist/types/stacks.d.ts.map +1 -0
- package/package.json +36 -0
- package/src/index.ts +16 -0
- package/src/stacks.ts +231 -0
package/README.md
ADDED
|
@@ -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
|
+
}
|