-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathcrypto.ts
More file actions
108 lines (97 loc) · 3.51 KB
/
crypto.ts
File metadata and controls
108 lines (97 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { ed25519CreateDerive, sr25519CreateDerive } from "@polkadot-labs/hdkd"
import { entropyToMiniSecret, mnemonicToEntropy } from "@polkadot-labs/hdkd-helpers"
import * as ss58 from "@subsquid/ss58"
import type { PolkadotSigner } from "polkadot-api/signer"
import { getPolkadotSigner } from "polkadot-api/signer"
import { getAllSupportedChains, getChainById } from "../chains/chains"
import type { AgentConfig } from "../types"
/**
* Convert a public key (Uint8Array) to a Substrate address
* @param publicKey - The public key as Uint8Array (32 bytes)
* @param chainId - The chain ID to get the correct SS58 prefix
* @returns The SS58-encoded address string
*/
export function publicKeyToAddress(publicKey: Uint8Array, chainId: string = "polkadot"): string {
const chain = getChainById(chainId, getAllSupportedChains())
return ss58.codec(chain.prefix).encode(publicKey)
}
/**
* Derive and convert address from mini secret
*
* @param miniSecret - The mini secret as Uint8Array (32 bytes)
* @param keyType - The cryptographic key type ("Sr25519" or "Ed25519")
* @param derivationPath - The BIP44 derivation path (e.g., "//0", "//hard/soft")
* @param chainId - The target chain ID for address encoding (default: "polkadot")
* @returns The SS58-encoded address string for the specified chain
*
*/
export function deriveAndConvertAddress(
miniSecret: Uint8Array,
keyType: "Sr25519" | "Ed25519",
derivationPath: string,
chainId: string = "polkadot"
): string {
const keypair = getKeypair(miniSecret, keyType, derivationPath)
return publicKeyToAddress(keypair.publicKey, chainId)
}
/**
* Generate mini secret from agent config
* @param config - The agent configuration
* @returns The mini secret as Uint8Array
*/
export function generateMiniSecret(config: AgentConfig): Uint8Array {
if (!config.mnemonic && !config.privateKey) {
throw new Error("Missing mnemonic phrase or privateKey")
}
if (config.mnemonic && config.privateKey) {
throw new Error("Cannot provide both mnemonic phrase and privateKey")
}
if (config.mnemonic) {
const entropy = mnemonicToEntropy(config.mnemonic)
return entropyToMiniSecret(entropy)
} else if (config.privateKey) {
const privateKeyHex = config.privateKey.startsWith("0x")
? config.privateKey.slice(2)
: config.privateKey
return new Uint8Array(privateKeyHex.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16)))
} else {
throw new Error("No valid wallet source found")
}
}
/**
* Get keypair from mini secret and derivation path
* @param miniSecret - The mini secret
* @param keyType - The key type
* @param derivationPath - The derivation path
* @returns The derived keypair
*/
export function getKeypair(
miniSecret: Uint8Array,
keyType: "Sr25519" | "Ed25519",
derivationPath: string = ""
) {
const derive =
keyType === "Sr25519" ? sr25519CreateDerive(miniSecret) : ed25519CreateDerive(miniSecret)
return derive(derivationPath)
}
export function getSigner(
miniSecret: Uint8Array,
keyType: "Sr25519" | "Ed25519",
derivationPath: string = ""
): PolkadotSigner {
if (keyType === "Sr25519") {
const signer = getPolkadotSigner(
getKeypair(miniSecret, keyType, derivationPath).publicKey,
keyType,
input => getKeypair(miniSecret, keyType, derivationPath).sign(input)
)
return signer
} else {
const signer = getPolkadotSigner(
getKeypair(miniSecret, keyType, derivationPath).publicKey,
keyType,
input => getKeypair(miniSecret, keyType, derivationPath).sign(input)
)
return signer
}
}