sats-connect 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.
@@ -0,0 +1,33 @@
1
+ name: Release & Publish Package
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v3
12
+ - uses: actions/setup-node@v3
13
+ with:
14
+ node-version: 16
15
+ - run: npm ci
16
+ # - run: npm test
17
+
18
+ publish-gpr:
19
+ needs: build
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ packages: write
23
+ contents: read
24
+ steps:
25
+ - uses: actions/checkout@v3
26
+ - uses: actions/setup-node@v3
27
+ with:
28
+ node-version: 16
29
+ registry-url: https://npm.pkg.github.com/
30
+ - run: npm ci
31
+ - run: npm publish
32
+ env:
33
+ NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -0,0 +1,13 @@
1
+ {
2
+ "arrowParens": "always",
3
+ "bracketSpacing": true,
4
+ "jsxBracketSameLine": false,
5
+ "jsxSingleQuote": false,
6
+ "quoteProps": "as-needed",
7
+ "singleQuote": true,
8
+ "semi": true,
9
+ "printWidth": 100,
10
+ "useTabs": false,
11
+ "tabWidth": 2,
12
+ "trailingComma": "es5"
13
+ }
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # sats-connect
@@ -0,0 +1,3 @@
1
+ export * from './src/address/index';
2
+ export * from './src/provider/bitcoin.provider';
3
+ export * from './src/auth';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './src/address/index';
2
+ export * from './src/provider/bitcoin.provider';
3
+ export * from './src/auth';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { GetAddressOptions } from './types';
2
+ export declare const openRequestAddressPopup: (options: GetAddressOptions) => Promise<void>;
3
+ export * from './types';
@@ -0,0 +1,66 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ export var openRequestAddressPopup = function (options) { return __awaiter(void 0, void 0, void 0, function () {
38
+ var _a, message, network, purpose, provider, addressResponse, error_1;
39
+ var _b, _c;
40
+ return __generator(this, function (_d) {
41
+ switch (_d.label) {
42
+ case 0:
43
+ _a = options.payload, message = _a.message, network = _a.network, purpose = _a.purpose;
44
+ provider = window.BitcoinProvider;
45
+ if (!provider) {
46
+ throw new Error('No Bitcoin Wallet installed');
47
+ }
48
+ _d.label = 1;
49
+ case 1:
50
+ _d.trys.push([1, 3, , 4]);
51
+ return [4 /*yield*/, provider.getAddress(purpose, message, network)];
52
+ case 2:
53
+ addressResponse = _d.sent();
54
+ (_b = options.onFinish) === null || _b === void 0 ? void 0 : _b.call(options, addressResponse);
55
+ return [3 /*break*/, 4];
56
+ case 3:
57
+ error_1 = _d.sent();
58
+ console.error('[Connect] Error during address request', error_1);
59
+ (_c = options.onCancel) === null || _c === void 0 ? void 0 : _c.call(options);
60
+ return [3 /*break*/, 4];
61
+ case 4: return [2 /*return*/];
62
+ }
63
+ });
64
+ }); };
65
+ export * from './types';
66
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/address/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAM,CAAC,IAAM,uBAAuB,GAAG,UAAO,OAA0B;;;;;;gBAChE,KAAgC,OAAO,CAAC,OAAO,EAA7C,OAAO,aAAA,EAAE,OAAO,aAAA,EAAE,OAAO,aAAA,CAAqB;gBAChD,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC;gBACxC,IAAI,CAAC,QAAQ,EAAE;oBACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;iBAChD;;;;gBAEyB,qBAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAA;;gBAAtE,eAAe,GAAG,SAAoD;gBAC5E,MAAA,OAAO,CAAC,QAAQ,wDAAG,eAAe,CAAC,CAAC;;;;gBAEpC,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,OAAK,CAAC,CAAC;gBAC/D,MAAA,OAAO,CAAC,QAAQ,uDAAI,CAAC;;;;;KAExB,CAAC;AAEF,cAAc,SAAS,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { BitcoinNetwork, Purpose } from '../provider/bitcoin.provider';
2
+ interface GetAddressPayload {
3
+ purpose: Purpose;
4
+ message: string;
5
+ network: BitcoinNetwork;
6
+ }
7
+ export interface GetAddressResponse {
8
+ address: string;
9
+ network: string;
10
+ }
11
+ export interface GetAddressOptions {
12
+ onFinish: (response: GetAddressResponse) => void;
13
+ onCancel: () => void;
14
+ payload: GetAddressPayload;
15
+ }
16
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/address/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { UserSession } from '@stacks/auth';
2
+ import type { AuthOptions } from './types';
3
+ export declare const isMobile: () => boolean;
4
+ /**
5
+ * mobile should not use a 'popup' type of window.
6
+ */
7
+ export declare const shouldUsePopup: () => boolean;
8
+ export declare const getOrCreateUserSession: (userSession?: UserSession) => UserSession;
9
+ export declare const authenticate: (authOptions: AuthOptions) => Promise<void>;
10
+ export declare const getUserData: (userSession?: UserSession) => Promise<import("@stacks/auth").UserData | null>;
11
+ export * from './types';
@@ -0,0 +1,126 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { AppConfig, UserSession } from '@stacks/auth';
38
+ import { decodeToken } from 'jsontokens';
39
+ var version = '0.0.1';
40
+ if (typeof window !== 'undefined') {
41
+ window.__CONNECT_VERSION__ = version;
42
+ }
43
+ export var isMobile = function () {
44
+ var ua = navigator.userAgent;
45
+ if (/android/i.test(ua)) {
46
+ return true;
47
+ }
48
+ if (/iPad|iPhone|iPod/.test(ua)) {
49
+ return true;
50
+ }
51
+ return /windows phone/i.test(ua);
52
+ };
53
+ /**
54
+ * mobile should not use a 'popup' type of window.
55
+ */
56
+ export var shouldUsePopup = function () {
57
+ return !isMobile();
58
+ };
59
+ export var getOrCreateUserSession = function (userSession) {
60
+ if (!userSession) {
61
+ var appConfig = new AppConfig(['store_write'], document.location.href);
62
+ userSession = new UserSession({ appConfig: appConfig });
63
+ }
64
+ return userSession;
65
+ };
66
+ export var authenticate = function (authOptions) { return __awaiter(void 0, void 0, void 0, function () {
67
+ var provider, _a, redirectTo, manifestPath, onFinish, onCancel, _b, sendToSignIn, _userSession, appDetails, userSession, transitKey, authRequest, authResponse, token, payload, authResponsePayload, error_1;
68
+ return __generator(this, function (_c) {
69
+ switch (_c.label) {
70
+ case 0:
71
+ provider = window.BitcoinProvider;
72
+ if (!provider) {
73
+ throw new Error('Unable to authenticate without a Bitcoin Wallet extension');
74
+ }
75
+ _a = authOptions.redirectTo, redirectTo = _a === void 0 ? '/' : _a, manifestPath = authOptions.manifestPath, onFinish = authOptions.onFinish, onCancel = authOptions.onCancel, _b = authOptions.sendToSignIn, sendToSignIn = _b === void 0 ? false : _b, _userSession = authOptions.userSession, appDetails = authOptions.appDetails;
76
+ userSession = getOrCreateUserSession(_userSession);
77
+ if (userSession.isUserSignedIn()) {
78
+ userSession.signUserOut();
79
+ }
80
+ transitKey = userSession.generateAndStoreTransitKey();
81
+ authRequest = userSession.makeAuthRequest(transitKey, "".concat(document.location.origin).concat(redirectTo), "".concat(document.location.origin).concat(manifestPath), userSession.appConfig.scopes, undefined, undefined, {
82
+ sendToSignIn: sendToSignIn,
83
+ appDetails: appDetails,
84
+ connectVersion: version,
85
+ });
86
+ _c.label = 1;
87
+ case 1:
88
+ _c.trys.push([1, 4, , 5]);
89
+ return [4 /*yield*/, provider.authenticationRequest(authRequest)];
90
+ case 2:
91
+ authResponse = _c.sent();
92
+ return [4 /*yield*/, userSession.handlePendingSignIn(authResponse)];
93
+ case 3:
94
+ _c.sent();
95
+ token = decodeToken(authResponse);
96
+ payload = token === null || token === void 0 ? void 0 : token.payload;
97
+ authResponsePayload = payload;
98
+ onFinish === null || onFinish === void 0 ? void 0 : onFinish({
99
+ authResponse: authResponse,
100
+ authResponsePayload: authResponsePayload,
101
+ userSession: userSession,
102
+ });
103
+ return [3 /*break*/, 5];
104
+ case 4:
105
+ error_1 = _c.sent();
106
+ console.error('[Connect] Error during auth request', error_1);
107
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
108
+ return [3 /*break*/, 5];
109
+ case 5: return [2 /*return*/];
110
+ }
111
+ });
112
+ }); };
113
+ export var getUserData = function (userSession) { return __awaiter(void 0, void 0, void 0, function () {
114
+ return __generator(this, function (_a) {
115
+ userSession = getOrCreateUserSession(userSession);
116
+ if (userSession.isUserSignedIn()) {
117
+ return [2 /*return*/, userSession.loadUserData()];
118
+ }
119
+ if (userSession.isSignInPending()) {
120
+ return [2 /*return*/, userSession.handlePendingSignIn()];
121
+ }
122
+ return [2 /*return*/, null];
123
+ });
124
+ }); };
125
+ export * from './types';
126
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { UserSession } from "@stacks/auth";
2
+ export interface AuthResponsePayload {
3
+ private_key: string;
4
+ username: string | null;
5
+ hubUrl: string;
6
+ associationToken: string;
7
+ blockstackAPIUrl: string | null;
8
+ core_token: string | null;
9
+ email: string | null;
10
+ exp: number;
11
+ iat: number;
12
+ iss: string;
13
+ jti: string;
14
+ version: string;
15
+ profile: any;
16
+ profile_url: string;
17
+ public_keys: string[];
18
+ }
19
+ export interface FinishedAuthData {
20
+ authResponse: string;
21
+ authResponsePayload: AuthResponsePayload;
22
+ userSession: UserSession;
23
+ }
24
+ declare global {
25
+ interface Window {
26
+ __CONNECT_VERSION__?: string;
27
+ }
28
+ const __VERSION__: string;
29
+ }
30
+ export interface AuthOptions {
31
+ /** The URL you want the user to be redirected to after authentication. */
32
+ redirectTo?: string;
33
+ manifestPath?: string;
34
+ /**
35
+ * This callback is fired after authentication is finished.
36
+ * The callback is called with a single object argument, with three keys:
37
+ * `authResponse`: the raw `authResponse` string that is returned from authentication
38
+ * `authResponsePayload`: an AuthResponsePayload object
39
+ * `userSession`: a UserSession object with `userData` included
40
+ * */
41
+ onFinish?: (payload: FinishedAuthData) => void;
42
+ /** This callback is fired if the user exits before finishing */
43
+ onCancel?: () => void;
44
+ /**
45
+ * @deprecated Authentication is no longer supported through a hosted
46
+ * version. Users must install an extension.
47
+ */
48
+ authOrigin?: string;
49
+ /** If `sendToSignIn` is `true`, then the user will be sent through the sign in flow. */
50
+ sendToSignIn?: boolean;
51
+ userSession?: UserSession;
52
+ appDetails: {
53
+ /** A human-readable name for your application */
54
+ name: string;
55
+ /** A full URL that resolves to an image icon for your application */
56
+ icon: string;
57
+ };
58
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/auth/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { GetAddressResponse } from '../address';
2
+ export declare enum AddressPurposes {
3
+ PAYMENT = "payment",
4
+ ORDINALS = "ordinals"
5
+ }
6
+ export interface Purpose {
7
+ derivation_path?: string;
8
+ purpose: AddressPurposes;
9
+ }
10
+ export interface BitcoinNetwork {
11
+ type: string;
12
+ address: string;
13
+ }
14
+ export interface BitcoinProvider {
15
+ getAddress: (purpose: Purpose, message: string, network?: BitcoinNetwork) => Promise<GetAddressResponse>;
16
+ authenticationRequest(payload: string): Promise<string>;
17
+ }
18
+ declare global {
19
+ interface Window {
20
+ BitcoinProvider?: BitcoinProvider;
21
+ }
22
+ }
@@ -0,0 +1,6 @@
1
+ export var AddressPurposes;
2
+ (function (AddressPurposes) {
3
+ AddressPurposes["PAYMENT"] = "payment";
4
+ AddressPurposes["ORDINALS"] = "ordinals";
5
+ })(AddressPurposes || (AddressPurposes = {}));
6
+ //# sourceMappingURL=bitcoin.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitcoin.provider.js","sourceRoot":"","sources":["../../../src/provider/bitcoin.provider.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,wCAAqB,CAAA;AACvB,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B"}
package/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './src/address/index';
2
+ export * from './src/provider';
3
+ export * from './src/call';
4
+ export * from './src/transactions/signPsbt';
package/jest.config.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ testPathIgnorePatterns: ['dist'],
5
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "sats-connect",
3
+ "version": "0.1.0",
4
+ "main": "dist/index.js",
5
+ "scripts": {
6
+ "test": "jest",
7
+ "build-debug": "webpack --mode development",
8
+ "build": "npm run clean && tsc --module ES6 --outDir ./dist",
9
+ "clean": "rimraf dist",
10
+ "lint": "prettier --write ."
11
+ },
12
+ "dependencies": {
13
+ "jsontokens": "^4.0.1",
14
+ "process": "^0.11.10",
15
+ "util": "^0.12.4"
16
+ },
17
+ "devDependencies": {
18
+ "@types/jest": "^29.2.6",
19
+ "prettier": "^2.8.4",
20
+ "process": "^0.11.10",
21
+ "rimraf": "^3.0.2",
22
+ "stream-browserify": "^3.0.0",
23
+ "ts-jest": "^29.0.5",
24
+ "ts-loader": "^9.4.1",
25
+ "typescript": "^4.9.4",
26
+ "vm-browserify": "^1.1.2",
27
+ "webpack": "^5.74.0",
28
+ "webpack-cli": "^4.10.0"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/secretkeylabs/sats-connect.git"
33
+ },
34
+ "author": "Secret Key Labs",
35
+ "license": "ISC",
36
+ "bugs": {
37
+ "url": "https://github.com/secretkeylabs/sats-connect/issues"
38
+ },
39
+ "homepage": "https://github.com/secretkeylabs/sats-connect#readme"
40
+ }
@@ -0,0 +1,23 @@
1
+ import { createUnsecuredToken, Json } from 'jsontokens';
2
+ import { GetAddressOptions } from './types';
3
+
4
+ export const openConnectPopup = async (options: GetAddressOptions) => {
5
+ const { message, network, purposes } = options.payload;
6
+ const provider = window.BitcoinProvider;
7
+ if (!provider) {
8
+ throw new Error('No Bitcoin Wallet installed');
9
+ }
10
+ if(!purposes) {
11
+ throw new Error('Address purposes are required');
12
+ }
13
+ try {
14
+ const request = createUnsecuredToken(options.payload as unknown as Json);
15
+ const addressResponse = await provider.connect(request);
16
+ options.onFinish?.(addressResponse);
17
+ } catch (error) {
18
+ console.error('[Connect] Error during address request', error);
19
+ options.onCancel?.();
20
+ }
21
+ };
22
+
23
+ export * from './types';
@@ -0,0 +1,33 @@
1
+ import { BitcoinNetwork } from '../provider';
2
+
3
+ export enum AddressPurposes {
4
+ PAYMENT = 'payment',
5
+ ORDINALS = 'ordinals',
6
+ }
7
+
8
+ export interface Purpose {
9
+ derivation_path?: string;
10
+ purpose: AddressPurposes;
11
+ }
12
+
13
+ export interface GetAddressPayload {
14
+ purposes: Array<Purpose>;
15
+ message: string;
16
+ network: BitcoinNetwork;
17
+ }
18
+
19
+ export interface Address {
20
+ address: string;
21
+ publicKey: string;
22
+ purpose: Purpose;
23
+ }
24
+
25
+ export interface GetAddressResponse {
26
+ addresses: Array<Address>
27
+ }
28
+
29
+ export interface GetAddressOptions {
30
+ onFinish: (response: GetAddressResponse) => void;
31
+ onCancel: () => void;
32
+ payload: GetAddressPayload;
33
+ }
@@ -0,0 +1,38 @@
1
+ import { createUnsecuredToken, Json } from 'jsontokens';
2
+ import { BitcoinNetwork } from '../provider';
3
+
4
+ export interface CallWalletPayload {
5
+ method: string;
6
+ network: BitcoinNetwork;
7
+ params?: Array<any>;
8
+ }
9
+
10
+ export interface CallWalletOptions {
11
+ onFinish: (response: Record<string, any>) => void;
12
+ onCancel: () => void;
13
+ payload: CallWalletPayload;
14
+ }
15
+
16
+ export enum CallMethod {
17
+ SIGN_PSBT = 'signPsbt',
18
+ GET_ADDRESS = 'getAddress',
19
+ }
20
+
21
+ export const callWalletPopup = async (options: CallWalletOptions) => {
22
+ const provider = window.BitcoinProvider;
23
+ const { method } = options.payload;
24
+ if (!provider) {
25
+ throw new Error('No Bitcoin Wallet installed');
26
+ }
27
+ if(!method) {
28
+ throw new Error('A wallet method is required');
29
+ }
30
+ const request = createUnsecuredToken(options.payload as unknown as Json);
31
+ try {
32
+ const callResponse = await provider.call(request);
33
+ options.onFinish?.(callResponse);
34
+ } catch (error) {
35
+ console.error('[Connect] Error during call request', error);
36
+ options.onCancel?.();
37
+ }
38
+ };
@@ -0,0 +1,19 @@
1
+ import { SignPsbtResponse } from '../transactions/signPsbt';
2
+ import { GetAddressResponse } from '../address';
3
+
4
+ export interface BitcoinNetwork {
5
+ type: string;
6
+ address: string;
7
+ }
8
+
9
+ export interface BitcoinProvider {
10
+ connect: (request: string) => Promise<GetAddressResponse>;
11
+ call: (request: string) => Promise<Record<string, any>>;
12
+ signPsbt: (request: string) => Promise<SignPsbtResponse>;
13
+ }
14
+
15
+ declare global {
16
+ interface Window {
17
+ BitcoinProvider?: BitcoinProvider;
18
+ }
19
+ }
@@ -0,0 +1,50 @@
1
+ import { createUnsecuredToken, Json } from 'jsontokens';
2
+ import { BitcoinNetwork } from '../provider';
3
+
4
+
5
+ export interface InputToSign {
6
+ address: string,
7
+ signingIndexes: Array<number>,
8
+ sigHash?: number,
9
+ }
10
+
11
+
12
+ export interface SignPsbtPayload {
13
+ network: BitcoinNetwork;
14
+ message: string;
15
+ psbtBase64: string;
16
+ broadcast?: boolean;
17
+ inputsToSign: InputToSign[];
18
+ }
19
+
20
+ export interface SignPsbtOptions {
21
+ payload: SignPsbtPayload;
22
+ onFinish: (response: any) => void;
23
+ onCancel: () => void;
24
+ }
25
+
26
+ export interface SignPsbtResponse {
27
+ psbtBase64: string;
28
+ txId?: string;
29
+ }
30
+
31
+
32
+ export const openSignPsbtPopup = async (options: SignPsbtOptions) => {
33
+ const { psbtBase64 } = options.payload;
34
+ const provider = window.BitcoinProvider;
35
+ if (!provider) {
36
+ throw new Error('No Bitcoin Wallet installed');
37
+ }
38
+ if (!psbtBase64) {
39
+ throw new Error('a value for psbtBase64 representing the tx hash is required');
40
+ }
41
+ try {
42
+ const request = createUnsecuredToken(options.payload as unknown as Json);
43
+ const addressResponse = await provider.signPsbt(request);
44
+ options.onFinish?.(addressResponse);
45
+ } catch (error) {
46
+ console.error('[Connect] Error during signPsbt request', error);
47
+ options.onCancel?.();
48
+ }
49
+ };
50
+
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "incremental": true,
4
+ "module": "es6",
5
+ "target": "es5",
6
+ "moduleResolution": "node",
7
+ "baseUrl": ".",
8
+ "declaration": true,
9
+ "sourceMap": true,
10
+ "outDir": "dist",
11
+ "esModuleInterop": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "strict": true,
14
+ "useUnknownInCatchVariables": false,
15
+ "noImplicitAny": true,
16
+ "allowUnreachableCode": false,
17
+ "skipLibCheck": true
18
+ },
19
+ "exclude": ["./tests", "./dist"]
20
+ }
@@ -0,0 +1,53 @@
1
+ const webpack = require('webpack');
2
+ const path = require('path');
3
+
4
+ const NODE_ENV_PRODUCTION = 'production';
5
+ const NODE_ENV_DEVELOPMENT = 'development';
6
+
7
+ const isProduction = process.env.NODE_ENV === NODE_ENV_PRODUCTION;
8
+
9
+ module.exports = {
10
+ mode: isProduction ? NODE_ENV_PRODUCTION : NODE_ENV_DEVELOPMENT,
11
+ entry: ['./index.ts'],
12
+ output: {
13
+ filename: 'index.js',
14
+ library: 'sats_connect',
15
+ libraryTarget: 'var',
16
+ path: path.resolve(process.cwd(), 'dist'),
17
+ },
18
+ plugins: [
19
+ new webpack.ProvidePlugin({
20
+ process: 'process/browser',
21
+ fetch: 'cross-fetch',
22
+ }),
23
+ ],
24
+ optimization: {
25
+ minimize: isProduction,
26
+ },
27
+ devtool: false,
28
+ module: {
29
+ rules: [
30
+ {
31
+ test: /\.[jt]sx?$/,
32
+ exclude: /node_modules/,
33
+ use: [
34
+ {
35
+ loader: require.resolve('ts-loader'),
36
+ options: {
37
+ transpileOnly: false,
38
+ },
39
+ },
40
+ ],
41
+ },
42
+ ],
43
+ },
44
+ resolve: {
45
+ extensions: ['.ts', '.js'],
46
+ fallback: {
47
+ url: require.resolve('url'),
48
+ stream: require.resolve('stream-browserify'),
49
+ vm: require.resolve('vm-browserify'),
50
+ assert: require.resolve('assert'),
51
+ },
52
+ },
53
+ };