@shapeshiftoss/hdwallet-gridplus 1.62.10-alpha.2 → 1.62.10
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/adapter.d.ts +11 -3
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +98 -26
- package/dist/adapter.js.map +1 -1
- package/dist/bitcoin.d.ts +2 -1
- package/dist/bitcoin.d.ts.map +1 -1
- package/dist/bitcoin.js +555 -131
- package/dist/bitcoin.js.map +1 -1
- package/dist/ethereum.d.ts.map +1 -1
- package/dist/ethereum.js +34 -18
- package/dist/ethereum.js.map +1 -1
- package/dist/gridplus.d.ts +22 -17
- package/dist/gridplus.d.ts.map +1 -1
- package/dist/gridplus.js +101 -74
- package/dist/gridplus.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/transport.d.ts +28 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +148 -0
- package/dist/transport.js.map +1 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +87 -2
- package/dist/utils.js.map +1 -1
- package/package.json +5 -6
- package/src/adapter.ts +84 -26
- package/src/bitcoin.ts +650 -134
- package/src/ethereum.ts +47 -11
- package/src/gridplus.ts +130 -83
- package/src/index.ts +1 -0
- package/src/transport.ts +131 -0
- package/src/utils.ts +100 -2
- package/tsconfig.json +1 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9E,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,4 +20,5 @@ var gridplus_1 = require("./gridplus");
|
|
|
20
20
|
Object.defineProperty(exports, "GridPlusHDWallet", { enumerable: true, get: function () { return gridplus_1.GridPlusHDWallet; } });
|
|
21
21
|
Object.defineProperty(exports, "GridPlusWalletInfo", { enumerable: true, get: function () { return gridplus_1.GridPlusWalletInfo; } });
|
|
22
22
|
Object.defineProperty(exports, "isGridPlus", { enumerable: true, get: function () { return gridplus_1.isGridPlus; } });
|
|
23
|
+
__exportStar(require("./transport"), exports);
|
|
23
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,uCAA8E;AAArE,4GAAA,gBAAgB,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAAE,sGAAA,UAAU,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,uCAA8E;AAArE,4GAAA,gBAAgB,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAAE,sGAAA,UAAU,OAAA;AACzD,8CAA4B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as core from "@shapeshiftoss/hdwallet-core";
|
|
2
|
+
import { Client } from "gridplus-sdk";
|
|
3
|
+
export type GridPlusTransportConfig = {
|
|
4
|
+
deviceId: string;
|
|
5
|
+
password?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class GridPlusTransport extends core.Transport {
|
|
8
|
+
deviceId?: string;
|
|
9
|
+
password?: string;
|
|
10
|
+
connected: boolean;
|
|
11
|
+
private client?;
|
|
12
|
+
private sessionId?;
|
|
13
|
+
constructor(config: GridPlusTransportConfig);
|
|
14
|
+
getDeviceID(): Promise<string>;
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
connectGridPlus(deviceId: string, password?: string): Promise<void>;
|
|
17
|
+
disconnect(): Promise<void>;
|
|
18
|
+
isConnected(): boolean;
|
|
19
|
+
setup(deviceId: string, password?: string, existingSessionId?: string): Promise<{
|
|
20
|
+
isPaired: boolean;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
}>;
|
|
23
|
+
pair(pairingCode: string): Promise<boolean>;
|
|
24
|
+
getClient(): Client | undefined;
|
|
25
|
+
getSessionId(): string | undefined;
|
|
26
|
+
call(): Promise<any>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,8BAA8B,CAAC;AAErD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,IAAI,CAAC,SAAS;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAS;IAClC,OAAO,CAAC,MAAM,CAAC,CAAS;IAIxB,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,MAAM,EAAE,uBAAuB;IAMpC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAYxB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC,WAAW,IAAI,OAAO;IAIhB,KAAK,CAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAgDvC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUjD,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,YAAY,IAAI,MAAM,GAAG,SAAS;IAI5B,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;CAGlC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.GridPlusTransport = void 0;
|
|
36
|
+
const core = __importStar(require("@shapeshiftoss/hdwallet-core"));
|
|
37
|
+
const crypto_1 = require("crypto");
|
|
38
|
+
const gridplus_sdk_1 = require("gridplus-sdk");
|
|
39
|
+
class GridPlusTransport extends core.Transport {
|
|
40
|
+
constructor(config) {
|
|
41
|
+
super(new core.Keyring());
|
|
42
|
+
this.connected = false;
|
|
43
|
+
this.deviceId = config.deviceId;
|
|
44
|
+
this.password = config.password;
|
|
45
|
+
}
|
|
46
|
+
getDeviceID() {
|
|
47
|
+
return Promise.resolve(this.deviceId || "");
|
|
48
|
+
}
|
|
49
|
+
connect() {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
if (!this.deviceId) {
|
|
52
|
+
throw new Error("Device ID is required to connect to GridPlus");
|
|
53
|
+
}
|
|
54
|
+
const { isPaired } = yield this.setup(this.deviceId, this.password);
|
|
55
|
+
if (!isPaired) {
|
|
56
|
+
throw new Error("Device is not paired");
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
connectGridPlus(deviceId, password) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
this.deviceId = deviceId;
|
|
63
|
+
this.password = password || "shapeshift-default";
|
|
64
|
+
yield this.connect();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
disconnect() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
this.connected = false;
|
|
70
|
+
this.deviceId = undefined;
|
|
71
|
+
this.password = undefined;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
isConnected() {
|
|
75
|
+
return this.connected;
|
|
76
|
+
}
|
|
77
|
+
setup(deviceId, password, existingSessionId) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
this.deviceId = deviceId;
|
|
80
|
+
this.password = password || "shapeshift-default";
|
|
81
|
+
// Use existing sessionId if provided, otherwise generate new one
|
|
82
|
+
if (existingSessionId) {
|
|
83
|
+
this.sessionId = existingSessionId;
|
|
84
|
+
}
|
|
85
|
+
else if (!this.sessionId) {
|
|
86
|
+
this.sessionId = (0, crypto_1.randomBytes)(32).toString("hex");
|
|
87
|
+
}
|
|
88
|
+
// Create Client instance directly (Frame pattern) - no localStorage!
|
|
89
|
+
// This ensures we always get fresh activeWallets from device
|
|
90
|
+
if (!this.client) {
|
|
91
|
+
this.client = new gridplus_sdk_1.Client({
|
|
92
|
+
name: "ShapeShift",
|
|
93
|
+
baseUrl: "https://signing.gridpl.us",
|
|
94
|
+
privKey: Buffer.from(this.sessionId, "hex"),
|
|
95
|
+
retryCount: 3,
|
|
96
|
+
timeout: 60000,
|
|
97
|
+
skipRetryOnWrongWallet: true,
|
|
98
|
+
});
|
|
99
|
+
try {
|
|
100
|
+
// Connect to device - returns true if paired, false if needs pairing
|
|
101
|
+
const isPaired = yield this.client.connect(deviceId);
|
|
102
|
+
this.connected = true;
|
|
103
|
+
return { isPaired, sessionId: this.sessionId };
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// Handle "Device Locked" error - treat as unpaired
|
|
107
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
108
|
+
if (errorMessage.toLowerCase().includes("device locked")) {
|
|
109
|
+
this.connected = true;
|
|
110
|
+
return { isPaired: false, sessionId: this.sessionId };
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Client already exists, reset active wallets to clear stale state before reconnecting
|
|
117
|
+
// This is critical when switching between SafeCards - ensures fresh wallet state from device
|
|
118
|
+
this.client.resetActiveWallets();
|
|
119
|
+
const isPaired = yield this.client.connect(deviceId);
|
|
120
|
+
this.connected = true;
|
|
121
|
+
return { isPaired, sessionId: this.sessionId };
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
pair(pairingCode) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
if (!this.client) {
|
|
128
|
+
throw new Error("Client not initialized. Call setup() first.");
|
|
129
|
+
}
|
|
130
|
+
const result = yield this.client.pair(pairingCode);
|
|
131
|
+
this.connected = !!result;
|
|
132
|
+
return !!result;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
getClient() {
|
|
136
|
+
return this.client;
|
|
137
|
+
}
|
|
138
|
+
getSessionId() {
|
|
139
|
+
return this.sessionId;
|
|
140
|
+
}
|
|
141
|
+
call() {
|
|
142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
throw new Error("GridPlus transport call not implemented");
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.GridPlusTransport = GridPlusTransport;
|
|
148
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
import * as core from "@shapeshiftoss/hdwallet-core";
|
|
2
|
+
import { UtxoAccountType } from "./constants";
|
|
1
3
|
export declare const getCompressedPubkey: (pubkey: string | Buffer) => Buffer;
|
|
2
4
|
export declare const createBech32Address: (pubkey: string | Buffer, prefix: string) => string;
|
|
5
|
+
/**
|
|
6
|
+
* Convert xpub version bytes for different coins (e.g., xpub → dgub for Dogecoin)
|
|
7
|
+
* GridPlus returns Bitcoin-format xpubs, but some coins like Dogecoin need different prefixes
|
|
8
|
+
*/
|
|
9
|
+
export declare function convertXpubVersion(xpub: string, accountType: UtxoAccountType | undefined, coin: string): string;
|
|
10
|
+
export declare function scriptTypeToAccountType(scriptType: core.BTCInputScriptType | undefined): UtxoAccountType | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Derive a UTXO address from a compressed public key
|
|
13
|
+
* @param pubkeyHex - Compressed public key as hex string (33 bytes, starting with 02 or 03)
|
|
14
|
+
* @param coin - Coin name (Bitcoin, Dogecoin, Litecoin, etc.)
|
|
15
|
+
* @param scriptType - Script type (p2pkh, p2wpkh, p2sh-p2wpkh)
|
|
16
|
+
* @returns The derived address
|
|
17
|
+
*/
|
|
18
|
+
export declare function deriveAddressFromPubkey(pubkeyHex: string, coin: string, scriptType?: core.BTCInputScriptType): string;
|
|
3
19
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,8BAA8B,CAAC;AAKrD,OAAO,EAA8D,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1G,eAAO,MAAM,mBAAmB,WAAY,MAAM,GAAG,MAAM,KAAG,MAW7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,WAAY,MAAM,GAAG,MAAM,UAAU,MAAM,KAAG,MAO7E,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAc/G;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAWpH;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,IAAI,CAAC,kBAAyD,GACzE,MAAM,CAiDR"}
|
package/dist/utils.js
CHANGED
|
@@ -27,14 +27,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.createBech32Address = exports.getCompressedPubkey = void 0;
|
|
30
|
+
exports.convertXpubVersion = convertXpubVersion;
|
|
31
|
+
exports.scriptTypeToAccountType = scriptTypeToAccountType;
|
|
32
|
+
exports.deriveAddressFromPubkey = deriveAddressFromPubkey;
|
|
30
33
|
const secp256k1_1 = require("@bitcoinerlab/secp256k1");
|
|
34
|
+
const core = __importStar(require("@shapeshiftoss/hdwallet-core"));
|
|
31
35
|
const bech32 = __importStar(require("bech32"));
|
|
32
|
-
const
|
|
36
|
+
const bs58check_1 = require("bs58check");
|
|
33
37
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
38
|
+
const constants_1 = require("./constants");
|
|
34
39
|
const getCompressedPubkey = (pubkey) => {
|
|
35
40
|
// Extended public key (xpub/ypub/zpub)
|
|
36
41
|
if (typeof pubkey === "string")
|
|
37
|
-
return
|
|
42
|
+
return (0, bs58check_1.decode)(pubkey).subarray(45, 78);
|
|
38
43
|
// Already compressed public key (33 bytes)
|
|
39
44
|
if (pubkey.length === 33)
|
|
40
45
|
return pubkey;
|
|
@@ -53,4 +58,84 @@ const createBech32Address = (pubkey, prefix) => {
|
|
|
53
58
|
return bech32.encode(prefix, words);
|
|
54
59
|
};
|
|
55
60
|
exports.createBech32Address = createBech32Address;
|
|
61
|
+
/**
|
|
62
|
+
* Convert xpub version bytes for different coins (e.g., xpub → dgub for Dogecoin)
|
|
63
|
+
* GridPlus returns Bitcoin-format xpubs, but some coins like Dogecoin need different prefixes
|
|
64
|
+
*/
|
|
65
|
+
function convertXpubVersion(xpub, accountType, coin) {
|
|
66
|
+
if (!accountType)
|
|
67
|
+
return xpub;
|
|
68
|
+
if (!constants_1.convertVersions.includes(xpub.substring(0, 4))) {
|
|
69
|
+
return xpub;
|
|
70
|
+
}
|
|
71
|
+
const payload = (0, bs58check_1.decode)(xpub);
|
|
72
|
+
const version = payload.slice(0, 4);
|
|
73
|
+
const desiredVersion = (0, constants_1.accountTypeToVersion)(coin, accountType);
|
|
74
|
+
if (version.compare(desiredVersion) !== 0) {
|
|
75
|
+
const key = payload.slice(4);
|
|
76
|
+
return (0, bs58check_1.encode)(Buffer.concat([desiredVersion, key]));
|
|
77
|
+
}
|
|
78
|
+
return xpub;
|
|
79
|
+
}
|
|
80
|
+
function scriptTypeToAccountType(scriptType) {
|
|
81
|
+
switch (scriptType) {
|
|
82
|
+
case core.BTCInputScriptType.SpendAddress:
|
|
83
|
+
return constants_1.UtxoAccountType.P2pkh;
|
|
84
|
+
case core.BTCInputScriptType.SpendWitness:
|
|
85
|
+
return constants_1.UtxoAccountType.SegwitNative;
|
|
86
|
+
case core.BTCInputScriptType.SpendP2SHWitness:
|
|
87
|
+
return constants_1.UtxoAccountType.SegwitP2sh;
|
|
88
|
+
default:
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Derive a UTXO address from a compressed public key
|
|
94
|
+
* @param pubkeyHex - Compressed public key as hex string (33 bytes, starting with 02 or 03)
|
|
95
|
+
* @param coin - Coin name (Bitcoin, Dogecoin, Litecoin, etc.)
|
|
96
|
+
* @param scriptType - Script type (p2pkh, p2wpkh, p2sh-p2wpkh)
|
|
97
|
+
* @returns The derived address
|
|
98
|
+
*/
|
|
99
|
+
function deriveAddressFromPubkey(pubkeyHex, coin, scriptType = core.BTCInputScriptType.SpendAddress) {
|
|
100
|
+
const network = constants_1.UTXO_NETWORK_PARAMS[coin] || constants_1.UTXO_NETWORK_PARAMS.Bitcoin;
|
|
101
|
+
const pubkeyBuffer = Buffer.from(pubkeyHex, "hex");
|
|
102
|
+
if (pubkeyBuffer.length !== 33) {
|
|
103
|
+
throw new Error(`Invalid compressed public key length: ${pubkeyBuffer.length} bytes`);
|
|
104
|
+
}
|
|
105
|
+
// Hash160 = RIPEMD160(SHA256(pubkey))
|
|
106
|
+
const sha256Hash = crypto_js_1.default.SHA256(crypto_js_1.default.enc.Hex.parse(pubkeyHex));
|
|
107
|
+
const hash160 = crypto_js_1.default.RIPEMD160(sha256Hash).toString();
|
|
108
|
+
const hash160Buffer = Buffer.from(hash160, "hex");
|
|
109
|
+
switch (scriptType) {
|
|
110
|
+
case core.BTCInputScriptType.SpendAddress: {
|
|
111
|
+
// P2PKH: <pubKeyHash version byte> + hash160 + checksum
|
|
112
|
+
const payload = Buffer.concat([Buffer.from([network.pubKeyHash]), hash160Buffer]);
|
|
113
|
+
return (0, bs58check_1.encode)(payload);
|
|
114
|
+
}
|
|
115
|
+
case core.BTCInputScriptType.SpendWitness: {
|
|
116
|
+
// P2WPKH (bech32): witness version 0 + hash160
|
|
117
|
+
if (!network.bech32) {
|
|
118
|
+
throw new Error(`Bech32 not supported for ${coin}`);
|
|
119
|
+
}
|
|
120
|
+
const words = bech32.toWords(hash160Buffer);
|
|
121
|
+
words.unshift(0); // witness version 0
|
|
122
|
+
return bech32.encode(network.bech32, words);
|
|
123
|
+
}
|
|
124
|
+
case core.BTCInputScriptType.SpendP2SHWitness: {
|
|
125
|
+
// P2SH-P2WPKH: scriptHash of witness program
|
|
126
|
+
// Witness program: OP_0 (0x00) + length (0x14) + hash160
|
|
127
|
+
const witnessProgram = Buffer.concat([Buffer.from([0x00, 0x14]), hash160Buffer]);
|
|
128
|
+
// Hash160 of witness program
|
|
129
|
+
const wpHex = witnessProgram.toString("hex");
|
|
130
|
+
const wpSha256 = crypto_js_1.default.SHA256(crypto_js_1.default.enc.Hex.parse(wpHex));
|
|
131
|
+
const wpHash160 = crypto_js_1.default.RIPEMD160(wpSha256).toString();
|
|
132
|
+
const wpHash160Buffer = Buffer.from(wpHash160, "hex");
|
|
133
|
+
// Encode with scriptHash version byte
|
|
134
|
+
const payload = Buffer.concat([Buffer.from([network.scriptHash]), wpHash160Buffer]);
|
|
135
|
+
return (0, bs58check_1.encode)(payload);
|
|
136
|
+
}
|
|
137
|
+
default:
|
|
138
|
+
throw new Error(`Unsupported script type: ${scriptType}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
56
141
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/hdwallet-gridplus",
|
|
3
|
-
"version": "1.62.10
|
|
3
|
+
"version": "1.62.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -11,16 +11,15 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc --build",
|
|
13
13
|
"build:docs": "typedoc --out docs --target es6 --theme minimal --mode file src",
|
|
14
|
-
"clean": "rm -rf dist
|
|
15
|
-
"prepublishOnly": "
|
|
14
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
15
|
+
"prepublishOnly": "yarn clean && yarn build"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@bitcoinerlab/secp256k1": "^1.1.1",
|
|
19
19
|
"@ethereumjs/common": "4.4.0",
|
|
20
|
-
"@ethereumjs/rlp": "5.0.2",
|
|
21
20
|
"@ethereumjs/tx": "5.4.0",
|
|
22
21
|
"@metamask/eth-sig-util": "^7.0.0",
|
|
23
|
-
"@shapeshiftoss/hdwallet-core": "1.62.
|
|
22
|
+
"@shapeshiftoss/hdwallet-core": "1.62.3",
|
|
24
23
|
"bech32": "^1.1.4",
|
|
25
24
|
"bs58": "^5.0.0",
|
|
26
25
|
"crypto-js": "^4.2.0",
|
|
@@ -35,5 +34,5 @@
|
|
|
35
34
|
"@ethereumjs/common",
|
|
36
35
|
"@ethereumjs/tx"
|
|
37
36
|
],
|
|
38
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "667187bae132b3463443d55dc8df58217699f988"
|
|
39
38
|
}
|
package/src/adapter.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import * as core from "@shapeshiftoss/hdwallet-core";
|
|
2
|
-
import { createHash } from "crypto";
|
|
3
|
-
import { Client } from "gridplus-sdk";
|
|
4
2
|
|
|
5
3
|
import { GridPlusHDWallet } from "./gridplus";
|
|
6
|
-
|
|
7
|
-
const name = "ShapeShift";
|
|
8
|
-
const baseUrl = "https://signing.gridpl.us";
|
|
4
|
+
import { GridPlusTransport } from "./transport";
|
|
9
5
|
|
|
10
6
|
export class GridPlusAdapter {
|
|
11
7
|
keyring: core.Keyring;
|
|
12
|
-
|
|
13
|
-
private client?: Client;
|
|
8
|
+
private activeTransports: Map<string, GridPlusTransport> = new Map();
|
|
14
9
|
|
|
15
10
|
constructor(keyring: core.Keyring) {
|
|
16
11
|
this.keyring = keyring;
|
|
@@ -20,32 +15,95 @@ export class GridPlusAdapter {
|
|
|
20
15
|
return new GridPlusAdapter(keyring);
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
public async connectDevice(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
public async connectDevice(
|
|
19
|
+
deviceId: string,
|
|
20
|
+
password?: string,
|
|
21
|
+
existingSessionId?: string
|
|
22
|
+
): Promise<{ transport: GridPlusTransport; isPaired: boolean; sessionId: string }> {
|
|
23
|
+
const transport = (() => {
|
|
24
|
+
const existing = this.activeTransports.get(deviceId);
|
|
25
|
+
if (existing) return existing;
|
|
26
|
+
|
|
27
|
+
const newTransport = new GridPlusTransport({
|
|
28
|
+
deviceId,
|
|
29
|
+
password: password || "shapeshift-default",
|
|
30
|
+
});
|
|
31
|
+
this.activeTransports.set(deviceId, newTransport);
|
|
32
|
+
return newTransport;
|
|
33
|
+
})();
|
|
34
|
+
|
|
35
|
+
const { isPaired, sessionId } = await transport.setup(deviceId, password, existingSessionId);
|
|
36
|
+
return { transport, isPaired, sessionId };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async pairConnectedDevice(deviceId: string, pairingCode: string): Promise<GridPlusHDWallet> {
|
|
40
|
+
const transport = this.activeTransports.get(deviceId);
|
|
41
|
+
if (!transport) {
|
|
42
|
+
throw new Error("Device not connected. Call connectDevice first.");
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
try {
|
|
46
|
+
const pairingSuccess = await transport.pair(pairingCode);
|
|
47
|
+
|
|
48
|
+
if (!pairingSuccess) {
|
|
49
|
+
throw new Error("Pairing failed. Please check the 8-character code displayed on your Lattice device.");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const wallet = new GridPlusHDWallet(transport);
|
|
53
|
+
wallet.setActiveWalletId(deviceId);
|
|
54
|
+
await wallet.initialize();
|
|
55
|
+
this.keyring.add(wallet, deviceId);
|
|
56
|
+
this.activeTransports.delete(deviceId);
|
|
57
|
+
|
|
58
|
+
return wallet;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new Error(`GridPlus pairing failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
61
|
+
}
|
|
38
62
|
}
|
|
39
63
|
|
|
40
|
-
public async pairDevice(
|
|
41
|
-
|
|
64
|
+
public async pairDevice(
|
|
65
|
+
deviceId: string,
|
|
66
|
+
password?: string,
|
|
67
|
+
pairingCode?: string,
|
|
68
|
+
existingSessionId?: string
|
|
69
|
+
): Promise<GridPlusHDWallet> {
|
|
70
|
+
const existingWallet = this.keyring.get<GridPlusHDWallet>(deviceId);
|
|
71
|
+
if (existingWallet) {
|
|
72
|
+
// Reset Client activeWallets state and fetch fresh UIDs from currently inserted SafeCard
|
|
73
|
+
await existingWallet.transport.setup(deviceId, password, existingSessionId);
|
|
74
|
+
// Ensure the wallet has the correct active walletId set
|
|
75
|
+
existingWallet.setActiveWalletId(deviceId);
|
|
76
|
+
// Reinitialize to clear cached addresses when reconnecting (e.g., SafeCard swap)
|
|
77
|
+
await existingWallet.initialize();
|
|
78
|
+
return existingWallet;
|
|
79
|
+
}
|
|
42
80
|
|
|
43
|
-
const
|
|
44
|
-
if (!success) throw new Error("Failed to pair.");
|
|
81
|
+
const { isPaired } = await this.connectDevice(deviceId, password, existingSessionId);
|
|
45
82
|
|
|
46
|
-
|
|
47
|
-
|
|
83
|
+
if (!isPaired) {
|
|
84
|
+
if (pairingCode) {
|
|
85
|
+
return await this.pairConnectedDevice(deviceId, pairingCode);
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error("PAIRING_REQUIRED");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
48
90
|
|
|
91
|
+
// Already paired - create wallet directly
|
|
92
|
+
const transport = this.activeTransports.get(deviceId)!;
|
|
93
|
+
const wallet = new GridPlusHDWallet(transport);
|
|
94
|
+
wallet.setActiveWalletId(deviceId);
|
|
95
|
+
await wallet.initialize();
|
|
96
|
+
this.keyring.add(wallet, deviceId);
|
|
97
|
+
this.activeTransports.delete(deviceId);
|
|
49
98
|
return wallet;
|
|
50
99
|
}
|
|
100
|
+
|
|
101
|
+
public async initialize(deviceId: string, password?: string): Promise<number> {
|
|
102
|
+
await this.pairDevice(deviceId, password);
|
|
103
|
+
return Object.keys(this.keyring.wallets).length;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public get(deviceId: string): GridPlusHDWallet {
|
|
107
|
+
return core.mustBeDefined(this.keyring.get<GridPlusHDWallet>(deviceId));
|
|
108
|
+
}
|
|
51
109
|
}
|