@beclab/olaresid 0.1.3 → 0.1.5
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/business/index.d.ts +3 -3
- package/dist/business/index.d.ts.map +1 -1
- package/dist/business/index.js +49 -63
- package/dist/business/index.js.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/crypto-utils.d.ts +71 -4
- package/dist/utils/crypto-utils.d.ts.map +1 -1
- package/dist/utils/crypto-utils.js +163 -51
- package/dist/utils/crypto-utils.js.map +1 -1
- package/examples/crypto-utilities.ts +3 -3
- package/examples/ed25519-jwk.ts +73 -0
- package/examples/encoding-utils.ts +96 -0
- package/examples/generate-mnemonic.ts +3 -3
- package/examples/register-subdomain.ts +4 -3
- package/examples/transfer-domain.ts +1 -1
- package/examples/wallet-management.ts +8 -8
- package/package.json +2 -3
- package/src/business/index.ts +47 -58
- package/src/cli.ts +3 -3
- package/src/index.ts +8 -23
- package/src/utils/crypto-utils.ts +198 -64
|
@@ -56,10 +56,10 @@ async function main() {
|
|
|
56
56
|
console.log('');
|
|
57
57
|
|
|
58
58
|
// 2. Add a new EVM wallet (optional - only if you have an EVM private key)
|
|
59
|
-
if (process.env.
|
|
59
|
+
if (process.env.EVM_PRIVATE_KEY) {
|
|
60
60
|
console.log('2️⃣ Adding a new EVM wallet...');
|
|
61
61
|
const addResult = await domain.addEVMWallet(
|
|
62
|
-
process.env.
|
|
62
|
+
process.env.EVM_PRIVATE_KEY
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
if (addResult.success) {
|
|
@@ -87,10 +87,10 @@ async function main() {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// 4. Remove an EVM wallet (optional)
|
|
90
|
-
if (process.env.
|
|
90
|
+
if (process.env.EVM_PRIVATE_KEY) {
|
|
91
91
|
console.log('4️⃣ Removing an EVM wallet...');
|
|
92
92
|
const removeResult = await domain.removeEVMWallet(
|
|
93
|
-
process.env.
|
|
93
|
+
process.env.EVM_PRIVATE_KEY
|
|
94
94
|
);
|
|
95
95
|
|
|
96
96
|
if (removeResult.success) {
|
|
@@ -127,10 +127,10 @@ async function main() {
|
|
|
127
127
|
console.log('');
|
|
128
128
|
|
|
129
129
|
// 6. Add a new Solana wallet (optional - only if you have a Solana private key)
|
|
130
|
-
if (process.env.
|
|
130
|
+
if (process.env.SOLANA_PRIVATE_KEY) {
|
|
131
131
|
console.log('6️⃣ Adding a new Solana wallet...');
|
|
132
132
|
const addResult = await domain.addSolanaWallet(
|
|
133
|
-
process.env.
|
|
133
|
+
process.env.SOLANA_PRIVATE_KEY
|
|
134
134
|
);
|
|
135
135
|
|
|
136
136
|
if (addResult.success) {
|
|
@@ -162,10 +162,10 @@ async function main() {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
// 8. Remove a Solana wallet (optional)
|
|
165
|
-
if (process.env.
|
|
165
|
+
if (process.env.SOLANA_PRIVATE_KEY) {
|
|
166
166
|
console.log('8️⃣ Removing a Solana wallet...');
|
|
167
167
|
const removeResult = await domain.removeSolanaWallet(
|
|
168
|
-
process.env.
|
|
168
|
+
process.env.SOLANA_PRIVATE_KEY
|
|
169
169
|
);
|
|
170
170
|
|
|
171
171
|
if (removeResult.success) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beclab/olaresid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "DID Contract SDK with CLI tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,9 +39,8 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@solana/web3.js": "^1.87.6",
|
|
41
41
|
"@trustwallet/wallet-core": "^3.2.9",
|
|
42
|
-
"bip39": "^3.1.0",
|
|
43
|
-
"bs58": "^5.0.0",
|
|
44
42
|
"ethers": "^6.9.1",
|
|
43
|
+
"multiformats": "9.6.4",
|
|
45
44
|
"tweetnacl": "^1.0.3",
|
|
46
45
|
"tweetnacl-util": "^0.15.1",
|
|
47
46
|
"varint": "^6.0.0"
|
package/src/business/index.ts
CHANGED
|
@@ -4,6 +4,12 @@ import { parseContractError } from '../utils/error-parser';
|
|
|
4
4
|
import { TagContext } from './tag-context';
|
|
5
5
|
import { TagTypeBuilder } from '../utils/tag-type-builder';
|
|
6
6
|
import { normalizeToDomain } from '../utils/olares-id';
|
|
7
|
+
import {
|
|
8
|
+
base64ToUint8Array,
|
|
9
|
+
uint8ArrayToHex,
|
|
10
|
+
hexToUint8Array,
|
|
11
|
+
uint8ArrayToBase64
|
|
12
|
+
} from '../utils/crypto-utils';
|
|
7
13
|
|
|
8
14
|
export interface TransactionResult<T = any> {
|
|
9
15
|
// Basic transaction information
|
|
@@ -47,7 +53,12 @@ export {
|
|
|
47
53
|
getEVMPrivateKeyFromMnemonic,
|
|
48
54
|
getDIDFromMnemonic,
|
|
49
55
|
generateDIDKeyData,
|
|
50
|
-
deriveDIDFromMnemonic
|
|
56
|
+
deriveDIDFromMnemonic,
|
|
57
|
+
getEd25519JwkFromMnemonic,
|
|
58
|
+
base64ToUint8Array,
|
|
59
|
+
uint8ArrayToHex,
|
|
60
|
+
hexToUint8Array,
|
|
61
|
+
uint8ArrayToBase64
|
|
51
62
|
} from '../utils/crypto-utils';
|
|
52
63
|
export type { RSAPublicKeyData, DIDKeyData } from '../utils/crypto-utils';
|
|
53
64
|
|
|
@@ -179,7 +190,7 @@ export class DomainContext {
|
|
|
179
190
|
* ```typescript
|
|
180
191
|
* // For parent domain "parent.com", register subdomain "child"
|
|
181
192
|
* const parentDomain = olaresId.domain('parent.com');
|
|
182
|
-
* const mnemonic = generateMnemonic(12);
|
|
193
|
+
* const mnemonic = await generateMnemonic(12);
|
|
183
194
|
*
|
|
184
195
|
* const result = await parentDomain.registerSubdomain('child', mnemonic);
|
|
185
196
|
* // This will register "child.parent.com"
|
|
@@ -265,7 +276,7 @@ export class DomainContext {
|
|
|
265
276
|
*
|
|
266
277
|
* @example
|
|
267
278
|
* ```typescript
|
|
268
|
-
* const mnemonic = generateMnemonic(12);
|
|
279
|
+
* const mnemonic = await generateMnemonic(12);
|
|
269
280
|
* const result = await domain.transfer(mnemonic);
|
|
270
281
|
* if (result.success) {
|
|
271
282
|
* console.log('Domain transferred!');
|
|
@@ -845,18 +856,22 @@ export class DomainContext {
|
|
|
845
856
|
const { Keypair } = await import('@solana/web3.js');
|
|
846
857
|
const nacl = await import('tweetnacl');
|
|
847
858
|
const { decodeUTF8 } = await import('tweetnacl-util');
|
|
859
|
+
const { base58btc } = await import('multiformats/bases/base58');
|
|
848
860
|
|
|
849
861
|
// Parse Solana private key (support both base58 and base64)
|
|
850
862
|
let solanaWallet: any;
|
|
851
863
|
try {
|
|
852
864
|
// Try base58 first (most common format for Phantom)
|
|
853
|
-
|
|
854
|
-
const
|
|
865
|
+
// Solana uses plain base58, but multiformats requires 'z' prefix for multibase
|
|
866
|
+
const base58Key = solanaPrivateKey.startsWith('z')
|
|
867
|
+
? solanaPrivateKey
|
|
868
|
+
: 'z' + solanaPrivateKey;
|
|
869
|
+
const secretKey = base58btc.decode(base58Key);
|
|
855
870
|
solanaWallet = Keypair.fromSecretKey(secretKey);
|
|
856
871
|
} catch {
|
|
857
872
|
// Try base64
|
|
858
873
|
try {
|
|
859
|
-
const secretKey =
|
|
874
|
+
const secretKey = base64ToUint8Array(solanaPrivateKey);
|
|
860
875
|
solanaWallet = Keypair.fromSecretKey(secretKey);
|
|
861
876
|
} catch {
|
|
862
877
|
// Try as JSON array
|
|
@@ -867,9 +882,9 @@ export class DomainContext {
|
|
|
867
882
|
}
|
|
868
883
|
}
|
|
869
884
|
|
|
870
|
-
// Get Solana address as bytes32
|
|
885
|
+
// Get Solana address as bytes32 (cross-platform)
|
|
871
886
|
const solanaAddressBytes =
|
|
872
|
-
'0x' + solanaWallet.publicKey.
|
|
887
|
+
'0x' + uint8ArrayToHex(solanaWallet.publicKey.toBytes());
|
|
873
888
|
|
|
874
889
|
// Get current timestamp
|
|
875
890
|
const signAt = Math.floor(Date.now() / 1000) - 30 * 60; // 30 minutes ago
|
|
@@ -929,8 +944,8 @@ export class DomainContext {
|
|
|
929
944
|
decodeUTF8(solanaMsg),
|
|
930
945
|
solanaWallet.secretKey
|
|
931
946
|
);
|
|
932
|
-
|
|
933
|
-
|
|
947
|
+
// Convert signature to hex (cross-platform)
|
|
948
|
+
const sigFromAuthAddrHex = '0x' + uint8ArrayToHex(sigFromAuthAddr);
|
|
934
949
|
|
|
935
950
|
// Call contract
|
|
936
951
|
const tx = await rootTagger.updateSolanaWallet(
|
|
@@ -978,18 +993,22 @@ export class DomainContext {
|
|
|
978
993
|
try {
|
|
979
994
|
// Import Solana libraries dynamically
|
|
980
995
|
const { Keypair } = await import('@solana/web3.js');
|
|
996
|
+
const { base58btc } = await import('multiformats/bases/base58');
|
|
981
997
|
|
|
982
998
|
// Parse Solana private key
|
|
983
999
|
let solanaWallet: any;
|
|
984
1000
|
try {
|
|
985
1001
|
// Try base58 first
|
|
986
|
-
|
|
987
|
-
const
|
|
1002
|
+
// Solana uses plain base58, but multiformats requires 'z' prefix for multibase
|
|
1003
|
+
const base58Key = solanaPrivateKey.startsWith('z')
|
|
1004
|
+
? solanaPrivateKey
|
|
1005
|
+
: 'z' + solanaPrivateKey;
|
|
1006
|
+
const secretKey = base58btc.decode(base58Key);
|
|
988
1007
|
solanaWallet = Keypair.fromSecretKey(secretKey);
|
|
989
1008
|
} catch {
|
|
990
1009
|
// Try base64
|
|
991
1010
|
try {
|
|
992
|
-
const secretKey =
|
|
1011
|
+
const secretKey = base64ToUint8Array(solanaPrivateKey);
|
|
993
1012
|
solanaWallet = Keypair.fromSecretKey(secretKey);
|
|
994
1013
|
} catch {
|
|
995
1014
|
// Try as JSON array
|
|
@@ -1000,9 +1019,9 @@ export class DomainContext {
|
|
|
1000
1019
|
}
|
|
1001
1020
|
}
|
|
1002
1021
|
|
|
1003
|
-
// Get Solana address as bytes32
|
|
1022
|
+
// Get Solana address as bytes32 (cross-platform)
|
|
1004
1023
|
const solanaAddressBytes =
|
|
1005
|
-
'0x' + solanaWallet.publicKey.
|
|
1024
|
+
'0x' + uint8ArrayToHex(solanaWallet.publicKey.toBytes());
|
|
1006
1025
|
|
|
1007
1026
|
// Get current timestamp
|
|
1008
1027
|
const signAt = Math.floor(Date.now() / 1000) - 30 * 60; // 30 minutes ago
|
|
@@ -1103,11 +1122,8 @@ export class DomainContext {
|
|
|
1103
1122
|
// Extract addresses from the result and convert to base58
|
|
1104
1123
|
// Result is array of { algorithm, addr } where addr is bytes32
|
|
1105
1124
|
return result.map((item: any) => {
|
|
1106
|
-
//
|
|
1107
|
-
const
|
|
1108
|
-
? item.addr.slice(2)
|
|
1109
|
-
: item.addr;
|
|
1110
|
-
const buffer = Buffer.from(hexStr, 'hex');
|
|
1125
|
+
// Convert hex to Uint8Array (cross-platform)
|
|
1126
|
+
const buffer = hexToUint8Array(item.addr);
|
|
1111
1127
|
// Convert to Solana public key and then to base58
|
|
1112
1128
|
return new PublicKey(buffer).toBase58();
|
|
1113
1129
|
});
|
|
@@ -1422,26 +1438,16 @@ export function bytes4ToIpv4(bytes4Hex: string): string {
|
|
|
1422
1438
|
*/
|
|
1423
1439
|
export function pemToDer(pem: string): string {
|
|
1424
1440
|
// Remove PEM headers, footers, and whitespace
|
|
1425
|
-
const
|
|
1441
|
+
const base64Str = pem
|
|
1426
1442
|
.replace(/-----BEGIN.*?-----/g, '')
|
|
1427
1443
|
.replace(/-----END.*?-----/g, '')
|
|
1428
1444
|
.replace(/\s/g, '');
|
|
1429
1445
|
|
|
1430
|
-
// Convert base64 to
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
//
|
|
1434
|
-
|
|
1435
|
-
// Node.js environment
|
|
1436
|
-
const derBuffer = Buffer.from(base64, 'base64');
|
|
1437
|
-
hexString = derBuffer.toString('hex');
|
|
1438
|
-
} else {
|
|
1439
|
-
// Browser environment
|
|
1440
|
-
const binaryString = atob(base64);
|
|
1441
|
-
hexString = Array.from(binaryString, (char) =>
|
|
1442
|
-
char.charCodeAt(0).toString(16).padStart(2, '0')
|
|
1443
|
-
).join('');
|
|
1444
|
-
}
|
|
1446
|
+
// Convert base64 to Uint8Array using cross-platform method
|
|
1447
|
+
const derBuffer = base64ToUint8Array(base64Str);
|
|
1448
|
+
|
|
1449
|
+
// Convert to hex string
|
|
1450
|
+
const hexString = uint8ArrayToHex(derBuffer);
|
|
1445
1451
|
|
|
1446
1452
|
// Convert to hex string with 0x prefix
|
|
1447
1453
|
return '0x' + hexString;
|
|
@@ -1456,31 +1462,14 @@ export function derToPem(derHex: string): string {
|
|
|
1456
1462
|
// Remove '0x' prefix if present
|
|
1457
1463
|
const hexString = derHex.startsWith('0x') ? derHex.slice(2) : derHex;
|
|
1458
1464
|
|
|
1459
|
-
// Convert hex to base64
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
// Check if running in Node.js or browser
|
|
1463
|
-
if (typeof Buffer !== 'undefined') {
|
|
1464
|
-
// Node.js environment
|
|
1465
|
-
const derBuffer = Buffer.from(hexString, 'hex');
|
|
1466
|
-
base64 = derBuffer.toString('base64');
|
|
1467
|
-
} else {
|
|
1468
|
-
// Browser environment
|
|
1469
|
-
// Convert hex string to byte array
|
|
1470
|
-
const bytes = new Uint8Array(hexString.length / 2);
|
|
1471
|
-
for (let i = 0; i < hexString.length; i += 2) {
|
|
1472
|
-
bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);
|
|
1473
|
-
}
|
|
1474
|
-
// Convert byte array to binary string
|
|
1475
|
-
const binaryString = String.fromCharCode(...bytes);
|
|
1476
|
-
// Convert to base64
|
|
1477
|
-
base64 = btoa(binaryString);
|
|
1478
|
-
}
|
|
1465
|
+
// Convert hex to base64 using cross-platform methods
|
|
1466
|
+
const bytes = hexToUint8Array(hexString);
|
|
1467
|
+
const base64Str = uint8ArrayToBase64(bytes);
|
|
1479
1468
|
|
|
1480
1469
|
// Split base64 into 64-character lines for PEM format
|
|
1481
1470
|
const lines: string[] = [];
|
|
1482
|
-
for (let i = 0; i <
|
|
1483
|
-
lines.push(
|
|
1471
|
+
for (let i = 0; i < base64Str.length; i += 64) {
|
|
1472
|
+
lines.push(base64Str.slice(i, i + 64));
|
|
1484
1473
|
}
|
|
1485
1474
|
|
|
1486
1475
|
// Construct PEM format with headers and footers
|
package/src/cli.ts
CHANGED
|
@@ -1014,7 +1014,7 @@ async function registerSubdomain(
|
|
|
1014
1014
|
);
|
|
1015
1015
|
process.exit(1);
|
|
1016
1016
|
}
|
|
1017
|
-
mnemonic = generateMnemonic(wordCount);
|
|
1017
|
+
mnemonic = await generateMnemonic(wordCount);
|
|
1018
1018
|
|
|
1019
1019
|
// Save mnemonic to file
|
|
1020
1020
|
const mnemonicFile = './subdomain-mnemonic.txt';
|
|
@@ -1141,7 +1141,7 @@ async function transferDomain(
|
|
|
1141
1141
|
);
|
|
1142
1142
|
process.exit(1);
|
|
1143
1143
|
}
|
|
1144
|
-
mnemonic = generateMnemonic(wordCount);
|
|
1144
|
+
mnemonic = await generateMnemonic(wordCount);
|
|
1145
1145
|
|
|
1146
1146
|
// Save mnemonic to file
|
|
1147
1147
|
const mnemonicFile = './transfer-new-owner-mnemonic.txt';
|
|
@@ -1228,7 +1228,7 @@ async function cryptoGenerate(options: CliOptions): Promise<void> {
|
|
|
1228
1228
|
process.exit(1);
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
|
-
const mnemonic = generateMnemonic(wordCount);
|
|
1231
|
+
const mnemonic = await generateMnemonic(wordCount);
|
|
1232
1232
|
|
|
1233
1233
|
// Save mnemonic to file
|
|
1234
1234
|
const outputFile = options.output || './mnemonic.txt';
|
package/src/index.ts
CHANGED
|
@@ -8,28 +8,7 @@ import { debug } from './debug';
|
|
|
8
8
|
import { parseContractError } from './utils/error-parser';
|
|
9
9
|
import { normalizeToDomain } from './utils/olares-id';
|
|
10
10
|
|
|
11
|
-
import {
|
|
12
|
-
DomainContext,
|
|
13
|
-
DomainMetaInfo,
|
|
14
|
-
DomainInfo,
|
|
15
|
-
TagInfo,
|
|
16
|
-
TransactionResult,
|
|
17
|
-
RSAPublicKeyData,
|
|
18
|
-
DIDKeyData,
|
|
19
|
-
UserType,
|
|
20
|
-
createRsaKeyPair,
|
|
21
|
-
pemToDer,
|
|
22
|
-
derToPem,
|
|
23
|
-
ipv4ToBytes4,
|
|
24
|
-
bytes4ToIpv4,
|
|
25
|
-
generateMnemonic,
|
|
26
|
-
getEthereumAddressFromMnemonic,
|
|
27
|
-
getEVMPrivateKeyFromMnemonic,
|
|
28
|
-
getDIDFromMnemonic,
|
|
29
|
-
generateDIDKeyData,
|
|
30
|
-
deriveDIDFromMnemonic
|
|
31
|
-
} from './business';
|
|
32
|
-
import { TagContext } from './business/tag-context';
|
|
11
|
+
import { DomainContext, TransactionResult } from './business';
|
|
33
12
|
|
|
34
13
|
// Import Tag utilities
|
|
35
14
|
import { TagTypeBuilder } from './utils/tag-type-builder';
|
|
@@ -58,7 +37,13 @@ export {
|
|
|
58
37
|
getEVMPrivateKeyFromMnemonic,
|
|
59
38
|
getDIDFromMnemonic,
|
|
60
39
|
generateDIDKeyData,
|
|
61
|
-
deriveDIDFromMnemonic
|
|
40
|
+
deriveDIDFromMnemonic,
|
|
41
|
+
getEd25519JwkFromMnemonic,
|
|
42
|
+
// Cross-platform encoding utilities
|
|
43
|
+
base64ToUint8Array,
|
|
44
|
+
uint8ArrayToHex,
|
|
45
|
+
hexToUint8Array,
|
|
46
|
+
uint8ArrayToBase64
|
|
62
47
|
} from './business';
|
|
63
48
|
|
|
64
49
|
type Domain = PackageDomain.Domain;
|