If anyone needs it, here's some python that will do the trick. ``` import hashlib # Base58 Bitcoin Alphabet B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" # Bech32 character set CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" def convertbits(data, frombits, tobits, pad=True): """General power-of-2 base conversion. Groups 5-bit values back to 8-bit.""" acc = 0 bits = 0 ret = [] maxv = (1 << tobits) - 1 max_acc = (1 << (frombits + tobits - 1)) - 1 for value in data: if value < 0 or (value >> frombits): return None acc = ((acc << frombits) | value) & max_acc bits += frombits while bits >= tobits: bits -= tobits ret.append((acc >> bits) & maxv) if pad: if bits: ret.append((acc << (tobits - bits)) & maxv) elif bits >= frombits or ((acc << (tobits - bits)) & maxv): return None return ret def bech32_decode_nsec(nsec_str): """Correctly decodes an nsec string into its original 32-byte private key.""" if not nsec_str.startswith("nsec1"): raise ValueError("Invalid prefix. Your key must start with 'nsec1'") # Strip the prefix 'nsec1' data_part = nsec_str[5:] # Extract 5-bit values from string mapping five_bit_values = [] for char in data_part: if char not in CHARSET: raise ValueError(f"Invalid character in bech32 string: {char}") five_bit_values.append(CHARSET.index(char)) # Slice off the final 6 characters (the Bech32 checksum) data_payload = five_bit_values[:-6] # Regroup the 5-bit payload chunks into standard 8-bit bytes eight_bit_bytes = convertbits(data_payload, 5, 8, pad=False) if eight_bit_bytes is None or len(eight_bit_bytes) != 32: raise ValueError("Decoding error: Key data did not result in exactly 32 bytes.") return bytes(eight_bit_bytes) def base58_encode(raw_bytes): """Encodes raw bytes into a standard Bitcoin Base58 string.""" int_val = int.from_bytes(raw_bytes, byteorder="big") result = "" while int_val > 0: int_val, mod = divmod(int_val, 58) result = B58_ALPHABET[mod] + result for byte in raw_bytes: if byte == 0: result = "1" + result else: break return result def nsec_to_wif(nsec_string): # Step 1 & 2: Decode Bech32 properly to get the true 32 raw bytes privkey_bytes = bech32_decode_nsec(nsec_string) # Step 3: Prefix 0x80 (Mainnet) and Suffix 0x01 (Compressed marker) wif_payload = b"\x80" + privkey_bytes + b"\x01" # Step 4 & 5: Compute double SHA256 checksum first_sha = hashlib.sha256(wif_payload).digest() second_sha = hashlib.sha256(first_sha).digest() checksum = second_sha[:4] # Step 6 & 7: Append checksum and convert to Base58 final_bytes = wif_payload + checksum wif_string = base58_encode(final_bytes) return wif_string # --- Example Test --- if __name__ == "__main__": # Test using a burner/mock nsec key test_nsec = "nsec..." try: wif = nsec_to_wif(test_nsec) print(f"Success! Your valid WIF Key is:\n{wif}") except Exception as e: print(f"Error: {e}") ```
โ†‘