chroid 1.0.0 → 1.0.1
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/cli/solana.js +168 -0
- package/index.js +2 -0
- package/package.json +4 -2
- package/utils/const.js +2 -1
- package/utils/solana.js +121 -0
package/cli/solana.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
const askForPassword = require("../utils/askForPassword")
|
|
2
|
+
const { ExplorerURIs } = require("../utils/const")
|
|
3
|
+
const { generateWalletFromPassword, getBalanceFromAddress, getSPLBalance, transferSOL, transferUSDT, transferUSDC, transferSPL } = require("../utils/solana");
|
|
4
|
+
|
|
5
|
+
const solanaCLI = async (yargs) => {
|
|
6
|
+
const argv = await yargs
|
|
7
|
+
.command("sol_addy", "Get Solana Address", {
|
|
8
|
+
},
|
|
9
|
+
async (args) => {
|
|
10
|
+
const password = await askForPassword();
|
|
11
|
+
const { address } = generateWalletFromPassword(password)
|
|
12
|
+
console.log(`\n${address}`)
|
|
13
|
+
})
|
|
14
|
+
.command("sol_check", "Check Sol, USDT, USDC", {
|
|
15
|
+
},
|
|
16
|
+
async (args) => {
|
|
17
|
+
const password = await askForPassword();
|
|
18
|
+
const { address } = generateWalletFromPassword(password)
|
|
19
|
+
const { sol_balance, usdt_balance, usdc_balance } = await getBalanceFromAddress(address)
|
|
20
|
+
console.log(`\nS: ${sol_balance}`)
|
|
21
|
+
console.log(`T: ${usdt_balance}`)
|
|
22
|
+
console.log(`C: ${usdc_balance}`)
|
|
23
|
+
})
|
|
24
|
+
.command("sol_checkcus", "Check Sol and Custom SPL", {
|
|
25
|
+
c: {
|
|
26
|
+
alias: "mint",
|
|
27
|
+
describe: "SPL Mint Address",
|
|
28
|
+
demandOption: true,
|
|
29
|
+
type: "string"
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
async (args) => {
|
|
33
|
+
const password = await askForPassword();
|
|
34
|
+
const { address } = generateWalletFromPassword(password)
|
|
35
|
+
const { sol_balance } = await getBalanceFromAddress(address)
|
|
36
|
+
const spl_balance = await getSPLBalance(address, args.mint)
|
|
37
|
+
console.log(`\nS: ${sol_balance}`)
|
|
38
|
+
console.log(`T: ${spl_balance}`)
|
|
39
|
+
})
|
|
40
|
+
.command("sol_pvkey", "Get Solana Private Key Hex", {
|
|
41
|
+
},
|
|
42
|
+
async (args) => {
|
|
43
|
+
const password = await askForPassword();
|
|
44
|
+
const { privateKeyHex } = generateWalletFromPassword(password)
|
|
45
|
+
console.log(`\n${privateKeyHex}`)
|
|
46
|
+
})
|
|
47
|
+
.command("sol_transn", "Transfer SOL", {
|
|
48
|
+
d: {
|
|
49
|
+
alias: "destination",
|
|
50
|
+
describe: "Destination address",
|
|
51
|
+
demandOption: true,
|
|
52
|
+
type: "string"
|
|
53
|
+
},
|
|
54
|
+
a: {
|
|
55
|
+
alias: "amount",
|
|
56
|
+
describe: "Amount in SOL",
|
|
57
|
+
demandOption: true,
|
|
58
|
+
type: "string"
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
async (args) => {
|
|
62
|
+
const password = await askForPassword();
|
|
63
|
+
try {
|
|
64
|
+
const { success, result } = await transferSOL(password, args.destination, args.amount)
|
|
65
|
+
if (!success) {
|
|
66
|
+
console.log("Error while SOL transfer")
|
|
67
|
+
console.log(result)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
console.log(`\n${ExplorerURIs.solana}${result}`)
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(error)
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
.command("sol_transt", "Transfer Solana USDT", {
|
|
76
|
+
d: {
|
|
77
|
+
alias: "destination",
|
|
78
|
+
describe: "Destination address",
|
|
79
|
+
demandOption: true,
|
|
80
|
+
type: "string"
|
|
81
|
+
},
|
|
82
|
+
a: {
|
|
83
|
+
alias: "amount",
|
|
84
|
+
describe: "Amount in usdt",
|
|
85
|
+
demandOption: true,
|
|
86
|
+
type: "string"
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
async (args) => {
|
|
90
|
+
const password = await askForPassword();
|
|
91
|
+
try {
|
|
92
|
+
const { success, result } = await transferUSDT(password, args.destination, args.amount)
|
|
93
|
+
if (!success) {
|
|
94
|
+
console.log("Error while Solana USDT transfer")
|
|
95
|
+
console.log(result)
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
console.log(`\n${ExplorerURIs.solana}${result}`)
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error(error)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.command("sol_transc", "Transfer Solana USDC", {
|
|
104
|
+
d: {
|
|
105
|
+
alias: "destination",
|
|
106
|
+
describe: "Destination address",
|
|
107
|
+
demandOption: true,
|
|
108
|
+
type: "string"
|
|
109
|
+
},
|
|
110
|
+
a: {
|
|
111
|
+
alias: "amount",
|
|
112
|
+
describe: "Amount in usdt",
|
|
113
|
+
demandOption: true,
|
|
114
|
+
type: "string"
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
async (args) => {
|
|
118
|
+
const password = await askForPassword();
|
|
119
|
+
try {
|
|
120
|
+
const { success, result } = await transferUSDC(password, args.destination, args.amount)
|
|
121
|
+
if (!success) {
|
|
122
|
+
console.log("Error while Solana USDC transfer")
|
|
123
|
+
console.log(result)
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
console.log(`\n${ExplorerURIs.solana}${result}`)
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error(error)
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
// .command("sol_transcus", "Transfer Custom SPL Token", {
|
|
132
|
+
// d: {
|
|
133
|
+
// alias: "destination",
|
|
134
|
+
// describe: "Destination address",
|
|
135
|
+
// demandOption: true,
|
|
136
|
+
// type: "string"
|
|
137
|
+
// },
|
|
138
|
+
// a: {
|
|
139
|
+
// alias: "amount",
|
|
140
|
+
// describe: "Amount in usdt",
|
|
141
|
+
// demandOption: true,
|
|
142
|
+
// type: "string"
|
|
143
|
+
// },
|
|
144
|
+
// t: {
|
|
145
|
+
// alias: "mint",
|
|
146
|
+
// describe: "Mint address",
|
|
147
|
+
// demandOption: true,
|
|
148
|
+
// type: "string"
|
|
149
|
+
// },
|
|
150
|
+
// },
|
|
151
|
+
// async (args) => {
|
|
152
|
+
// const password = await askForPassword();
|
|
153
|
+
// try {
|
|
154
|
+
// const { success, result } = await transferSPL(password, args.destination, args.mint, args.amount)
|
|
155
|
+
// if (!success) {
|
|
156
|
+
// console.log("Error while SPL transfer")
|
|
157
|
+
// console.log(result)
|
|
158
|
+
// return
|
|
159
|
+
// }
|
|
160
|
+
// console.log(`\n${ExplorerURIs.solana}${result}`)
|
|
161
|
+
// } catch (error) {
|
|
162
|
+
// console.error(error)
|
|
163
|
+
// }
|
|
164
|
+
// })
|
|
165
|
+
return yargs
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = solanaCLI
|
package/index.js
CHANGED
|
@@ -5,12 +5,14 @@ const yargs = require("yargs");
|
|
|
5
5
|
const bitcoinCLI = require("./cli/bitcoin");
|
|
6
6
|
const tronCLI = require("./cli/tron");
|
|
7
7
|
const evmCLI = require("./cli/evm");
|
|
8
|
+
const solanaCLI = require("./cli/solana")
|
|
8
9
|
|
|
9
10
|
const mainFunction = async () => {
|
|
10
11
|
let cli = yargs;
|
|
11
12
|
cli = await bitcoinCLI(yargs)
|
|
12
13
|
cli = await tronCLI(yargs)
|
|
13
14
|
cli = await evmCLI(yargs)
|
|
15
|
+
cli = await solanaCLI(yargs)
|
|
14
16
|
cli.help().argv
|
|
15
17
|
}
|
|
16
18
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chroid",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "CLI wallet for multi-chain support",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "CLI wallet for multi-chain support. \nBitcoin (Supporting 3 of 3 MultiSig) \nNative coins and USDT/USDC on Ethereum, Solana, Tron, BSC, Arbitrum, Optimism, Avalanche, Polygon and Base",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"chroid": "./index.js"
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"author": "Chainoroid",
|
|
15
15
|
"license": "ISC",
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@solana/spl-token": "^0.4.14",
|
|
18
|
+
"@solana/web3.js": "^1.98.4",
|
|
17
19
|
"base58": "^2.0.1",
|
|
18
20
|
"bip32": "^4.0.0",
|
|
19
21
|
"bip39": "^3.1.0",
|
package/utils/const.js
CHANGED
package/utils/solana.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const crypto = require('crypto')
|
|
2
|
+
const { Keypair, Connection, PublicKey, Transaction, SystemProgram, clusterApiUrl, sendAndConfirmTransaction } = require('@solana/web3.js');
|
|
3
|
+
const { getOrCreateAssociatedTokenAccount, createTransferInstruction, getMint, TOKEN_PROGRAM_ID } = require('@solana/spl-token');
|
|
4
|
+
|
|
5
|
+
// mainnet
|
|
6
|
+
// const RPC_URL = clusterApiUrl("mainnet-beta")
|
|
7
|
+
const RPC_URL = "https://solana.drpc.org"
|
|
8
|
+
const USDT_CONTRACT_ADDRESS = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB";
|
|
9
|
+
const USDC_CONTRACT_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
10
|
+
|
|
11
|
+
function generateHash(input) {
|
|
12
|
+
return crypto.createHash('sha256') // Use SHA-256 algorithm
|
|
13
|
+
.update(input) // Hash the input string
|
|
14
|
+
.digest('hex'); // Output the hash in hex format
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function generateSecretKeyFromPassword(pwd) {
|
|
18
|
+
const hash = generateHash(pwd)
|
|
19
|
+
const bytes = new Uint8Array(hash.length / 2)
|
|
20
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
21
|
+
bytes[i] = parseInt(hash.substring(i * 2, i * 2 + 2), 16)
|
|
22
|
+
}
|
|
23
|
+
return bytes
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function generateWalletFromPassword(pwd) {
|
|
27
|
+
const secret = generateSecretKeyFromPassword(pwd)
|
|
28
|
+
const keypair = Keypair.fromSeed(secret)
|
|
29
|
+
return {
|
|
30
|
+
privateKeyHex: JSON.stringify(Array.from(keypair.secretKey)),
|
|
31
|
+
address: keypair.publicKey.toBase58()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function getBalanceFromAddress(address) {
|
|
36
|
+
const connection = new Connection(RPC_URL, "confirmed");
|
|
37
|
+
const ownerPub = new PublicKey(address)
|
|
38
|
+
|
|
39
|
+
const lamports = await connection.getBalance(ownerPub)
|
|
40
|
+
const sol_balance = lamports / 1e9
|
|
41
|
+
|
|
42
|
+
const usdt_balance = await getSPLBalance(address, USDT_CONTRACT_ADDRESS)
|
|
43
|
+
const usdc_balance = await getSPLBalance(address, USDC_CONTRACT_ADDRESS)
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
sol_balance,
|
|
47
|
+
usdt_balance,
|
|
48
|
+
usdc_balance
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function getSPLBalance(address, mintAddress) {
|
|
53
|
+
const connection = new Connection(RPC_URL, "confirmed");
|
|
54
|
+
const ownerPub = new PublicKey(address)
|
|
55
|
+
const mintPub = new PublicKey(mintAddress)
|
|
56
|
+
const resp = await connection.getParsedTokenAccountsByOwner(ownerPub, { mint: mintPub })
|
|
57
|
+
if (resp.value.length === 0)
|
|
58
|
+
return 0
|
|
59
|
+
const tokenInfo = resp.value[0].account.data.parsed.info.tokenAmount
|
|
60
|
+
return Number(tokenInfo.amount) / Math.pow(10, tokenInfo.decimals)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function transferSOL(passkey, toAddress, amount) {
|
|
64
|
+
const connection = new Connection(RPC_URL, "confirmed");
|
|
65
|
+
const secret = generateSecretKeyFromPassword(passkey)
|
|
66
|
+
const keypair = Keypair.fromSeed(secret)
|
|
67
|
+
const toPub = new PublicKey(toAddress)
|
|
68
|
+
|
|
69
|
+
const tx = new Transaction().add(
|
|
70
|
+
SystemProgram.transfer({
|
|
71
|
+
fromPubkey: keypair.publicKey,
|
|
72
|
+
toPubkey: toPub,
|
|
73
|
+
lamports: Math.round(amount * 1e9)
|
|
74
|
+
})
|
|
75
|
+
)
|
|
76
|
+
const sig = await sendAndConfirmTransaction(connection, tx, [keypair])
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
result: sig
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function transferSPL(passkey, toAddress, mintAddress, amount) {
|
|
84
|
+
const connection = new Connection(RPC_URL, "confirmed");
|
|
85
|
+
const secret = generateSecretKeyFromPassword(passkey)
|
|
86
|
+
const keypair = Keypair.fromSeed(secret)
|
|
87
|
+
const toPub = new PublicKey(toAddress)
|
|
88
|
+
const mintPub = new PublicKey(mintAddress)
|
|
89
|
+
|
|
90
|
+
const mintInfo = await getMint(connection, mintPub)
|
|
91
|
+
const fromTokenAccount = await getOrCreateAssociatedTokenAccount(connection, keypair, mintPub, keypair.publicKey)
|
|
92
|
+
const toTokenAccount = await getOrCreateAssociatedTokenAccount(connection, keypair, mintPub, toPub)
|
|
93
|
+
|
|
94
|
+
const rawAmount = BigInt(Math.round(amount * Math.pow(10, mintInfo.decimals)))
|
|
95
|
+
const transferIx = createTransferInstruction(fromTokenAccount.address, toTokenAccount.address, keypair.publicKey, rawAmount, [], TOKEN_PROGRAM_ID)
|
|
96
|
+
|
|
97
|
+
const tx = new Transaction().add(transferIx)
|
|
98
|
+
const sig = await sendAndConfirmTransaction(connection, tx, [keypair])
|
|
99
|
+
return {
|
|
100
|
+
success: true,
|
|
101
|
+
result: sig
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function transferUSDT(passkey, toAddress, amount) {
|
|
106
|
+
return await transferSPL(passkey, toAddress, USDT_CONTRACT_ADDRESS, amount)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function transferUSDC(passkey, toAddress, amount) {
|
|
110
|
+
return await transferSPL(passkey, toAddress, USDC_CONTRACT_ADDRESS, amount)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
generateWalletFromPassword,
|
|
115
|
+
getBalanceFromAddress,
|
|
116
|
+
getSPLBalance,
|
|
117
|
+
transferSOL,
|
|
118
|
+
transferSPL,
|
|
119
|
+
transferUSDT,
|
|
120
|
+
transferUSDC
|
|
121
|
+
}
|