@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/src/utils.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { pointCompress } from "@bitcoinerlab/secp256k1";
2
+ import * as core from "@shapeshiftoss/hdwallet-core";
2
3
  import * as bech32 from "bech32";
3
- import * as bs58 from "bs58check";
4
+ import { decode as bs58Decode, encode as bs58Encode } from "bs58check";
4
5
  import CryptoJS from "crypto-js";
5
6
 
7
+ import { accountTypeToVersion, convertVersions, UTXO_NETWORK_PARAMS, UtxoAccountType } from "./constants";
8
+
6
9
  export const getCompressedPubkey = (pubkey: string | Buffer): Buffer => {
7
10
  // Extended public key (xpub/ypub/zpub)
8
- if (typeof pubkey === "string") return bs58.decode(pubkey).subarray(45, 78);
11
+ if (typeof pubkey === "string") return bs58Decode(pubkey).subarray(45, 78);
9
12
 
10
13
  // Already compressed public key (33 bytes)
11
14
  if (pubkey.length === 33) return pubkey;
@@ -24,3 +27,98 @@ export const createBech32Address = (pubkey: string | Buffer, prefix: string): st
24
27
  const words = bech32.toWords(address);
25
28
  return bech32.encode(prefix, words);
26
29
  };
30
+
31
+ /**
32
+ * Convert xpub version bytes for different coins (e.g., xpub → dgub for Dogecoin)
33
+ * GridPlus returns Bitcoin-format xpubs, but some coins like Dogecoin need different prefixes
34
+ */
35
+ export function convertXpubVersion(xpub: string, accountType: UtxoAccountType | undefined, coin: string): string {
36
+ if (!accountType) return xpub;
37
+ if (!convertVersions.includes(xpub.substring(0, 4))) {
38
+ return xpub;
39
+ }
40
+
41
+ const payload = bs58Decode(xpub);
42
+ const version = payload.slice(0, 4);
43
+ const desiredVersion = accountTypeToVersion(coin, accountType);
44
+ if (version.compare(desiredVersion) !== 0) {
45
+ const key = payload.slice(4);
46
+ return bs58Encode(Buffer.concat([desiredVersion, key]));
47
+ }
48
+ return xpub;
49
+ }
50
+
51
+ export function scriptTypeToAccountType(scriptType: core.BTCInputScriptType | undefined): UtxoAccountType | undefined {
52
+ switch (scriptType) {
53
+ case core.BTCInputScriptType.SpendAddress:
54
+ return UtxoAccountType.P2pkh;
55
+ case core.BTCInputScriptType.SpendWitness:
56
+ return UtxoAccountType.SegwitNative;
57
+ case core.BTCInputScriptType.SpendP2SHWitness:
58
+ return UtxoAccountType.SegwitP2sh;
59
+ default:
60
+ return undefined;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Derive a UTXO address from a compressed public key
66
+ * @param pubkeyHex - Compressed public key as hex string (33 bytes, starting with 02 or 03)
67
+ * @param coin - Coin name (Bitcoin, Dogecoin, Litecoin, etc.)
68
+ * @param scriptType - Script type (p2pkh, p2wpkh, p2sh-p2wpkh)
69
+ * @returns The derived address
70
+ */
71
+ export function deriveAddressFromPubkey(
72
+ pubkeyHex: string,
73
+ coin: string,
74
+ scriptType: core.BTCInputScriptType = core.BTCInputScriptType.SpendAddress
75
+ ): string {
76
+ const network = UTXO_NETWORK_PARAMS[coin] || UTXO_NETWORK_PARAMS.Bitcoin;
77
+ const pubkeyBuffer = Buffer.from(pubkeyHex, "hex");
78
+
79
+ if (pubkeyBuffer.length !== 33) {
80
+ throw new Error(`Invalid compressed public key length: ${pubkeyBuffer.length} bytes`);
81
+ }
82
+
83
+ // Hash160 = RIPEMD160(SHA256(pubkey))
84
+ const sha256Hash = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(pubkeyHex));
85
+ const hash160 = CryptoJS.RIPEMD160(sha256Hash).toString();
86
+ const hash160Buffer = Buffer.from(hash160, "hex");
87
+
88
+ switch (scriptType) {
89
+ case core.BTCInputScriptType.SpendAddress: {
90
+ // P2PKH: <pubKeyHash version byte> + hash160 + checksum
91
+ const payload = Buffer.concat([Buffer.from([network.pubKeyHash]), hash160Buffer]);
92
+ return bs58Encode(payload);
93
+ }
94
+
95
+ case core.BTCInputScriptType.SpendWitness: {
96
+ // P2WPKH (bech32): witness version 0 + hash160
97
+ if (!network.bech32) {
98
+ throw new Error(`Bech32 not supported for ${coin}`);
99
+ }
100
+ const words = bech32.toWords(hash160Buffer);
101
+ words.unshift(0); // witness version 0
102
+ return bech32.encode(network.bech32, words);
103
+ }
104
+
105
+ case core.BTCInputScriptType.SpendP2SHWitness: {
106
+ // P2SH-P2WPKH: scriptHash of witness program
107
+ // Witness program: OP_0 (0x00) + length (0x14) + hash160
108
+ const witnessProgram = Buffer.concat([Buffer.from([0x00, 0x14]), hash160Buffer]);
109
+
110
+ // Hash160 of witness program
111
+ const wpHex = witnessProgram.toString("hex");
112
+ const wpSha256 = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(wpHex));
113
+ const wpHash160 = CryptoJS.RIPEMD160(wpSha256).toString();
114
+ const wpHash160Buffer = Buffer.from(wpHash160, "hex");
115
+
116
+ // Encode with scriptHash version byte
117
+ const payload = Buffer.concat([Buffer.from([network.scriptHash]), wpHash160Buffer]);
118
+ return bs58Encode(payload);
119
+ }
120
+
121
+ default:
122
+ throw new Error(`Unsupported script type: ${scriptType}`);
123
+ }
124
+ }
package/tsconfig.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "extends": "../../tsconfig.json",
3
3
  "compilerOptions": {
4
- "rootDir": "src",
5
4
  "outDir": "dist",
6
- "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo",
5
+ "rootDir": "src"
7
6
  },
8
7
  "include": ["src/**/*"],
9
8
  "exclude": ["node_modules", "dist"],