emblem-vault-sdk 2.12.0 → 2.13.0
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/bundle.js +1867 -516
- package/dist/derive.js +51 -1
- package/dist/index.js +9 -1
- package/package.json +5 -2
- package/src/derive.ts +52 -0
- package/src/index.ts +10 -1
- package/types/derive.d.ts +6 -0
- package/types/index.d.ts +6 -0
package/dist/derive.js
CHANGED
|
@@ -42,12 +42,62 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.getPsbtTxnSize = exports.generateTaprootAddressFromMnemonic = void 0;
|
|
45
|
+
exports.getPsbtTxnSize = exports.generateTaprootAddressFromMnemonic = exports.deriveSolanaFromMnemonic = void 0;
|
|
46
46
|
const bip32_1 = require("bip32");
|
|
47
47
|
const bip39 = __importStar(require("bip39"));
|
|
48
48
|
// import bitcoin from "bitcoinjs-lib";
|
|
49
49
|
const ecc = __importStar(require("@bitcoin-js/tiny-secp256k1-asmjs"));
|
|
50
|
+
const hmac_1 = require("@noble/hashes/hmac");
|
|
51
|
+
const sha512_1 = require("@noble/hashes/sha512");
|
|
52
|
+
const ed25519_1 = require("@noble/curves/ed25519");
|
|
53
|
+
// bs58@4 ships no type declarations; require it (CJS) to avoid TS7016.
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
55
|
+
const bs58 = require("bs58");
|
|
50
56
|
const bip32 = (0, bip32_1.BIP32Factory)(ecc);
|
|
57
|
+
// --- Solana (ed25519 SLIP-0010) HD derivation ---
|
|
58
|
+
// Solana uses ed25519, NOT secp256k1, so bip32/bitcoinjs can't derive it. We do the
|
|
59
|
+
// SLIP-0010 ed25519 derivation via @noble (browser-safe, already a dependency; NOT
|
|
60
|
+
// @solana/web3.js — that heavy dep is the conflict that got SOL derivation disabled).
|
|
61
|
+
// Path m/44'/501'/0'/0' (all hardened) is the Phantom/Solflare standard. This matches
|
|
62
|
+
// the serverless vault-creation derivation byte-for-byte, so a claimed vault's SOL key
|
|
63
|
+
// re-derives to the stored address.
|
|
64
|
+
const SOLANA_PATH = "m/44'/501'/0'/0'";
|
|
65
|
+
function slip10DeriveEd25519Seed(pathStr, seed) {
|
|
66
|
+
let I = (0, hmac_1.hmac)(sha512_1.sha512, new TextEncoder().encode("ed25519 seed"), seed);
|
|
67
|
+
let key = I.slice(0, 32);
|
|
68
|
+
let chain = I.slice(32);
|
|
69
|
+
for (const seg of pathStr.split("/").slice(1)) {
|
|
70
|
+
const idx = ((parseInt(seg, 10) | 0x80000000) >>> 0); // all segments hardened
|
|
71
|
+
const data = new Uint8Array(1 + 32 + 4);
|
|
72
|
+
data[0] = 0;
|
|
73
|
+
data.set(key, 1);
|
|
74
|
+
data[33] = (idx >>> 24) & 255;
|
|
75
|
+
data[34] = (idx >>> 16) & 255;
|
|
76
|
+
data[35] = (idx >>> 8) & 255;
|
|
77
|
+
data[36] = idx & 255;
|
|
78
|
+
I = (0, hmac_1.hmac)(sha512_1.sha512, chain, data);
|
|
79
|
+
key = I.slice(0, 32);
|
|
80
|
+
chain = I.slice(32);
|
|
81
|
+
}
|
|
82
|
+
return key; // 32-byte ed25519 seed
|
|
83
|
+
}
|
|
84
|
+
// Derive the Solana address + Phantom-importable secret key from a vault mnemonic.
|
|
85
|
+
// Returns { address (base58 pubkey), secretKey (base58 of the 64-byte secret), path, coin }.
|
|
86
|
+
const deriveSolanaFromMnemonic = (phrase) => {
|
|
87
|
+
const seed = bip39.mnemonicToSeedSync(phrase);
|
|
88
|
+
const priv = slip10DeriveEd25519Seed(SOLANA_PATH, new Uint8Array(seed));
|
|
89
|
+
const pub = ed25519_1.ed25519.getPublicKey(priv);
|
|
90
|
+
const secret = new Uint8Array(64);
|
|
91
|
+
secret.set(priv, 0);
|
|
92
|
+
secret.set(pub, 32);
|
|
93
|
+
return {
|
|
94
|
+
address: bs58.encode(pub),
|
|
95
|
+
secretKey: bs58.encode(secret), // 64-byte secret, base58 — import into Phantom/Solflare
|
|
96
|
+
path: SOLANA_PATH,
|
|
97
|
+
coin: "SOL",
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
exports.deriveSolanaFromMnemonic = deriveSolanaFromMnemonic;
|
|
51
101
|
const generateTaprootAddressFromMnemonic = (phrase) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
102
|
let bitcoin = window.bitcoin;
|
|
53
103
|
let mainnet = bitcoin.networks.mainnet;
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ const derive_1 = require("./derive");
|
|
|
48
48
|
const constants_1 = require("./constants");
|
|
49
49
|
const vault_utils_1 = require("./vault-utils");
|
|
50
50
|
const evm_operations_1 = require("./evm-operations");
|
|
51
|
-
const SDK_VERSION = '2.
|
|
51
|
+
const SDK_VERSION = '2.13.0';
|
|
52
52
|
class EmblemVaultSDK {
|
|
53
53
|
constructor(apiKey, baseUrl, v3Url, sigUrl) {
|
|
54
54
|
this.apiKey = apiKey;
|
|
@@ -604,6 +604,14 @@ class EmblemVaultSDK {
|
|
|
604
604
|
return ukeys;
|
|
605
605
|
});
|
|
606
606
|
}
|
|
607
|
+
// Re-derive the Solana key from a claimed vault's decrypted mnemonic. Solana is
|
|
608
|
+
// ed25519 (not secp256k1), so it can't go through the bitcoinjs derivation the other
|
|
609
|
+
// coins use — this uses the SLIP-0010 ed25519 derivation in ./derive (matching the
|
|
610
|
+
// serverless creation-side byte-for-byte). Returns { address, secretKey (base58,
|
|
611
|
+
// Phantom-importable), path, coin:'SOL' }.
|
|
612
|
+
deriveSolanaKeys(phrase) {
|
|
613
|
+
return (0, derive_1.deriveSolanaFromMnemonic)(phrase);
|
|
614
|
+
}
|
|
607
615
|
getQuote(web3_1, amount_1) {
|
|
608
616
|
return __awaiter(this, arguments, void 0, function* (web3, amount, callback = null) {
|
|
609
617
|
if (callback) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emblem-vault-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Emblem Vault Software Development Kit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -41,12 +41,15 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@bitcoin-js/tiny-secp256k1-asmjs": "^2.2.3",
|
|
43
43
|
"@ethersproject/bignumber": "^5.7.0",
|
|
44
|
+
"@noble/curves": "^1.4.2",
|
|
45
|
+
"@noble/hashes": "^1.4.0",
|
|
44
46
|
"@toruslabs/fetch-node-details": "^8.0.0",
|
|
45
47
|
"@toruslabs/torus.js": "^6.2.0",
|
|
46
48
|
"bchaddrjs": "^0.5.2",
|
|
47
49
|
"bip32": "^4.0.0",
|
|
48
50
|
"bip39": "^3.1.0",
|
|
49
51
|
"bitcoinjs-lib": "^6.1.5",
|
|
52
|
+
"bs58": "^4.0.1",
|
|
50
53
|
"bitcore-mnemonic": "^10.0.23",
|
|
51
54
|
"crypto-js": "^4.2.0",
|
|
52
55
|
"ethereumjs-util": "^7.1.5",
|
|
@@ -61,4 +64,4 @@
|
|
|
61
64
|
"engines": {
|
|
62
65
|
"node": ">=20.5.1"
|
|
63
66
|
}
|
|
64
|
-
}
|
|
67
|
+
}
|
package/src/derive.ts
CHANGED
|
@@ -3,9 +3,61 @@ import * as bip39 from "bip39";
|
|
|
3
3
|
// import bitcoin from "bitcoinjs-lib";
|
|
4
4
|
|
|
5
5
|
import * as ecc from '@bitcoin-js/tiny-secp256k1-asmjs'
|
|
6
|
+
import { hmac } from "@noble/hashes/hmac";
|
|
7
|
+
import { sha512 } from "@noble/hashes/sha512";
|
|
8
|
+
import { ed25519 } from "@noble/curves/ed25519";
|
|
9
|
+
// bs58@4 ships no type declarations; require it (CJS) to avoid TS7016.
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
11
|
+
const bs58: { encode: (b: Uint8Array) => string; decode: (s: string) => Uint8Array } = require("bs58");
|
|
6
12
|
|
|
7
13
|
const bip32 = BIP32Factory(ecc);
|
|
8
14
|
|
|
15
|
+
// --- Solana (ed25519 SLIP-0010) HD derivation ---
|
|
16
|
+
// Solana uses ed25519, NOT secp256k1, so bip32/bitcoinjs can't derive it. We do the
|
|
17
|
+
// SLIP-0010 ed25519 derivation via @noble (browser-safe, already a dependency; NOT
|
|
18
|
+
// @solana/web3.js — that heavy dep is the conflict that got SOL derivation disabled).
|
|
19
|
+
// Path m/44'/501'/0'/0' (all hardened) is the Phantom/Solflare standard. This matches
|
|
20
|
+
// the serverless vault-creation derivation byte-for-byte, so a claimed vault's SOL key
|
|
21
|
+
// re-derives to the stored address.
|
|
22
|
+
const SOLANA_PATH = "m/44'/501'/0'/0'";
|
|
23
|
+
|
|
24
|
+
function slip10DeriveEd25519Seed(pathStr: string, seed: Uint8Array): Uint8Array {
|
|
25
|
+
let I = hmac(sha512, new TextEncoder().encode("ed25519 seed"), seed);
|
|
26
|
+
let key = I.slice(0, 32);
|
|
27
|
+
let chain = I.slice(32);
|
|
28
|
+
for (const seg of pathStr.split("/").slice(1)) {
|
|
29
|
+
const idx = ((parseInt(seg, 10) | 0x80000000) >>> 0); // all segments hardened
|
|
30
|
+
const data = new Uint8Array(1 + 32 + 4);
|
|
31
|
+
data[0] = 0;
|
|
32
|
+
data.set(key, 1);
|
|
33
|
+
data[33] = (idx >>> 24) & 255;
|
|
34
|
+
data[34] = (idx >>> 16) & 255;
|
|
35
|
+
data[35] = (idx >>> 8) & 255;
|
|
36
|
+
data[36] = idx & 255;
|
|
37
|
+
I = hmac(sha512, chain, data);
|
|
38
|
+
key = I.slice(0, 32);
|
|
39
|
+
chain = I.slice(32);
|
|
40
|
+
}
|
|
41
|
+
return key; // 32-byte ed25519 seed
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Derive the Solana address + Phantom-importable secret key from a vault mnemonic.
|
|
45
|
+
// Returns { address (base58 pubkey), secretKey (base58 of the 64-byte secret), path, coin }.
|
|
46
|
+
export const deriveSolanaFromMnemonic = (phrase: string) => {
|
|
47
|
+
const seed = bip39.mnemonicToSeedSync(phrase);
|
|
48
|
+
const priv = slip10DeriveEd25519Seed(SOLANA_PATH, new Uint8Array(seed));
|
|
49
|
+
const pub = ed25519.getPublicKey(priv);
|
|
50
|
+
const secret = new Uint8Array(64);
|
|
51
|
+
secret.set(priv, 0);
|
|
52
|
+
secret.set(pub, 32);
|
|
53
|
+
return {
|
|
54
|
+
address: bs58.encode(pub),
|
|
55
|
+
secretKey: bs58.encode(secret), // 64-byte secret, base58 — import into Phantom/Solflare
|
|
56
|
+
path: SOLANA_PATH,
|
|
57
|
+
coin: "SOL",
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
9
61
|
// let mainnet: any = {"messagePrefix":"\u0018Bitcoin Signed Message:\n","bech32":"bc","bip32":{"public":76067358,"private":76066276},"pubKeyHash":0,"scriptHash":5,"wif":128}
|
|
10
62
|
declare global {
|
|
11
63
|
interface Window {
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
BulkMintResponse,
|
|
15
15
|
} from './types';
|
|
16
16
|
import { NFT_DATA, checkContentType, decryptKeys, fetchData, generateTemplate, genericGuard, getHandlerContract, getLegacyContract, getQuoteContractObject, getSatsConnectAddress, getTorusKeys, metadataAllProjects, metadataObj2Arr, signPSBT, templateGuard } from './utils';
|
|
17
|
-
import { generateTaprootAddressFromMnemonic, getPsbtTxnSize } from './derive';
|
|
17
|
+
import { generateTaprootAddressFromMnemonic, getPsbtTxnSize, deriveSolanaFromMnemonic } from './derive';
|
|
18
18
|
import {
|
|
19
19
|
ETHEREUM_MAINNET_CHAIN_ID,
|
|
20
20
|
} from './constants';
|
|
@@ -526,6 +526,15 @@ class EmblemVaultSDK {
|
|
|
526
526
|
return ukeys
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
+
// Re-derive the Solana key from a claimed vault's decrypted mnemonic. Solana is
|
|
530
|
+
// ed25519 (not secp256k1), so it can't go through the bitcoinjs derivation the other
|
|
531
|
+
// coins use — this uses the SLIP-0010 ed25519 derivation in ./derive (matching the
|
|
532
|
+
// serverless creation-side byte-for-byte). Returns { address, secretKey (base58,
|
|
533
|
+
// Phantom-importable), path, coin:'SOL' }.
|
|
534
|
+
deriveSolanaKeys(phrase: string) {
|
|
535
|
+
return deriveSolanaFromMnemonic(phrase);
|
|
536
|
+
}
|
|
537
|
+
|
|
529
538
|
async getQuote(web3: any, amount: number, callback: any = null) {
|
|
530
539
|
if (callback) { callback('requesting Quote')}
|
|
531
540
|
let quoteContract = await getQuoteContractObject(web3);
|
package/types/derive.d.ts
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -62,6 +62,12 @@ declare class EmblemVaultSDK {
|
|
|
62
62
|
privateKey: any;
|
|
63
63
|
}>;
|
|
64
64
|
decryptVaultKeys(tokenId: string, dkeys: any, callback?: any): Promise<any>;
|
|
65
|
+
deriveSolanaKeys(phrase: string): {
|
|
66
|
+
address: string;
|
|
67
|
+
secretKey: string;
|
|
68
|
+
path: string;
|
|
69
|
+
coin: string;
|
|
70
|
+
};
|
|
65
71
|
getQuote(web3: any, amount: number, callback?: any): Promise<BigNumber>;
|
|
66
72
|
performMint(web3: any, quote: any, remoteMintSig: any, callback?: any): Promise<any>;
|
|
67
73
|
performBurn(web3: any, tokenId: any, callback?: any): Promise<any>;
|