@shapeshiftoss/hdwallet-gridplus 1.62.8 → 1.62.10-alpha.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/dist/adapter.d.ts +4 -9
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +28 -98
- package/dist/adapter.js.map +1 -1
- package/dist/bitcoin.d.ts +1 -2
- package/dist/bitcoin.d.ts.map +1 -1
- package/dist/bitcoin.js +134 -552
- package/dist/bitcoin.js.map +1 -1
- package/dist/ethereum.d.ts.map +1 -1
- package/dist/ethereum.js +18 -34
- package/dist/ethereum.js.map +1 -1
- package/dist/gridplus.d.ts +17 -22
- package/dist/gridplus.d.ts.map +1 -1
- package/dist/gridplus.js +68 -100
- package/dist/gridplus.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils.d.ts +0 -16
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +2 -87
- package/dist/utils.js.map +1 -1
- package/package.json +6 -5
- package/src/adapter.ts +30 -81
- package/src/bitcoin.ts +134 -649
- package/src/ethereum.ts +11 -47
- package/src/gridplus.ts +79 -131
- package/src/index.ts +0 -1
- package/src/utils.ts +2 -100
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -1
package/dist/utils.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
import * as core from "@shapeshiftoss/hdwallet-core";
|
|
2
|
-
import { UtxoAccountType } from "./constants";
|
|
3
1
|
export declare const getCompressedPubkey: (pubkey: string | Buffer) => Buffer;
|
|
4
2
|
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;
|
|
19
3
|
//# 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":"AAKA,eAAO,MAAM,mBAAmB,WAAY,MAAM,GAAG,MAAM,KAAG,MAW7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,WAAY,MAAM,GAAG,MAAM,UAAU,MAAM,KAAG,MAO7E,CAAC"}
|
package/dist/utils.js
CHANGED
|
@@ -27,19 +27,14 @@ 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;
|
|
33
30
|
const secp256k1_1 = require("@bitcoinerlab/secp256k1");
|
|
34
|
-
const core = __importStar(require("@shapeshiftoss/hdwallet-core"));
|
|
35
31
|
const bech32 = __importStar(require("bech32"));
|
|
36
|
-
const
|
|
32
|
+
const bs58 = __importStar(require("bs58check"));
|
|
37
33
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
38
|
-
const constants_1 = require("./constants");
|
|
39
34
|
const getCompressedPubkey = (pubkey) => {
|
|
40
35
|
// Extended public key (xpub/ypub/zpub)
|
|
41
36
|
if (typeof pubkey === "string")
|
|
42
|
-
return
|
|
37
|
+
return bs58.decode(pubkey).subarray(45, 78);
|
|
43
38
|
// Already compressed public key (33 bytes)
|
|
44
39
|
if (pubkey.length === 33)
|
|
45
40
|
return pubkey;
|
|
@@ -58,84 +53,4 @@ const createBech32Address = (pubkey, prefix) => {
|
|
|
58
53
|
return bech32.encode(prefix, words);
|
|
59
54
|
};
|
|
60
55
|
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
|
-
}
|
|
141
56
|
//# 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAwD;AACxD,+CAAiC;AACjC,gDAAkC;AAClC,0DAAiC;AAE1B,MAAM,mBAAmB,GAAG,CAAC,MAAuB,EAAU,EAAE;IACrE,uCAAuC;IACvC,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5E,2CAA2C;IAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC;IAExC,qCAAqC;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAA,yBAAa,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAE1E,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;AACxC,CAAC,CAAC;AAXW,QAAA,mBAAmB,uBAW9B;AAEK,MAAM,mBAAmB,GAAG,CAAC,MAAuB,EAAE,MAAc,EAAU,EAAE;IACrF,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAG,mBAAQ,CAAC,MAAM,CAAC,mBAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,mBAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC,CAAC;AAPW,QAAA,mBAAmB,uBAO9B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/hdwallet-gridplus",
|
|
3
|
-
"version": "1.62.
|
|
3
|
+
"version": "1.62.10-alpha.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -11,15 +11,16 @@
|
|
|
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 node_modules",
|
|
15
|
+
"prepublishOnly": "rm -rf dist && 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",
|
|
20
21
|
"@ethereumjs/tx": "5.4.0",
|
|
21
22
|
"@metamask/eth-sig-util": "^7.0.0",
|
|
22
|
-
"@shapeshiftoss/hdwallet-core": "1.62.
|
|
23
|
+
"@shapeshiftoss/hdwallet-core": "1.62.10-alpha.1",
|
|
23
24
|
"bech32": "^1.1.4",
|
|
24
25
|
"bs58": "^5.0.0",
|
|
25
26
|
"crypto-js": "^4.2.0",
|
|
@@ -34,5 +35,5 @@
|
|
|
34
35
|
"@ethereumjs/common",
|
|
35
36
|
"@ethereumjs/tx"
|
|
36
37
|
],
|
|
37
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "86c4f311d027cbd873538328071c83e37620dba1"
|
|
38
39
|
}
|
package/src/adapter.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import * as core from "@shapeshiftoss/hdwallet-core";
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
import { Client } from "gridplus-sdk";
|
|
2
4
|
|
|
3
5
|
import { GridPlusHDWallet } from "./gridplus";
|
|
4
|
-
|
|
6
|
+
|
|
7
|
+
const name = "ShapeShift";
|
|
8
|
+
const baseUrl = "https://signing.gridpl.us";
|
|
5
9
|
|
|
6
10
|
export class GridPlusAdapter {
|
|
7
11
|
keyring: core.Keyring;
|
|
8
|
-
|
|
12
|
+
|
|
13
|
+
private client?: Client;
|
|
9
14
|
|
|
10
15
|
constructor(keyring: core.Keyring) {
|
|
11
16
|
this.keyring = keyring;
|
|
@@ -17,93 +22,37 @@ export class GridPlusAdapter {
|
|
|
17
22
|
|
|
18
23
|
public async connectDevice(
|
|
19
24
|
deviceId: string,
|
|
20
|
-
password
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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.");
|
|
25
|
+
password = ""
|
|
26
|
+
): Promise<{ wallet?: GridPlusHDWallet; sessionId: string }> {
|
|
27
|
+
const privKey = createHash("sha256")
|
|
28
|
+
.update(deviceId + password + name)
|
|
29
|
+
.digest();
|
|
30
|
+
|
|
31
|
+
const sessionId = privKey.toString("hex");
|
|
32
|
+
|
|
33
|
+
if (!this.client) {
|
|
34
|
+
this.client = new Client({ name, baseUrl, privKey, deviceId });
|
|
35
|
+
} else {
|
|
36
|
+
// Client already exists, reset active wallets to clear stale state before reconnecting
|
|
37
|
+
// This is critical when switching between SafeCards - ensures fresh wallet state from device
|
|
38
|
+
this.client.resetActiveWallets();
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
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);
|
|
41
|
+
const isPaired = await this.client.connect(deviceId);
|
|
42
|
+
if (isPaired) return { wallet: new GridPlusHDWallet(this.client), sessionId };
|
|
57
43
|
|
|
58
|
-
|
|
59
|
-
} catch (error) {
|
|
60
|
-
throw new Error(`GridPlus pairing failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
61
|
-
}
|
|
44
|
+
return { sessionId: privKey.toString("hex") };
|
|
62
45
|
}
|
|
63
46
|
|
|
64
|
-
public async pairDevice(
|
|
65
|
-
|
|
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
|
-
}
|
|
47
|
+
public async pairDevice(pairingCode: string): Promise<GridPlusHDWallet> {
|
|
48
|
+
if (!this.client) throw new Error("No client connected. Call connectDevice first.");
|
|
80
49
|
|
|
81
|
-
const
|
|
50
|
+
const success = await this.client.pair(pairingCode);
|
|
51
|
+
if (!success) throw new Error("Failed to pair.");
|
|
82
52
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return await this.pairConnectedDevice(deviceId, pairingCode);
|
|
86
|
-
} else {
|
|
87
|
-
throw new Error("PAIRING_REQUIRED");
|
|
88
|
-
}
|
|
89
|
-
}
|
|
53
|
+
const wallet = new GridPlusHDWallet(this.client);
|
|
54
|
+
this.keyring.add(wallet, this.client.getDeviceId());
|
|
90
55
|
|
|
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);
|
|
98
56
|
return wallet;
|
|
99
57
|
}
|
|
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
|
-
}
|
|
109
58
|
}
|