· 4 years ago · Apr 05, 2021, 08:34 AM
1import CardanoRay from 'cardano-ray'
2
3const mnemonic = CardanoRay.generateMnemonic()
4const prvkey = CardanoRay.getPrivateKey(mnemonic)
5
6const cardano = CardanoRay.init({
7 network: 'mainnet',
8 graphql: 'https://graphql.rraayy.com',
9 key: prvkey,
10})
11
12// check 80 first addresses for balances
13const addressesWithBalances = await cardano.getAddressesWithBalances()
14
15
16
17
18// *******
19// ******* WITHOUT CARDANO-RAY LIBRARY
20// *******
21
22import axios from 'axios
23import { generateMnemonic, validateMnemonic, mnemonicToEntropy } from 'bip39-light'
24
25const apiClient = axios.create({
26 baseURL: CARDANO_NETWORK === 'https://graphql.rraayy.com'
27})
28
29export async function GetAdressesUTXO(addresses) {
30 return apiClient
31 .post('/', {
32 query: `
33 query utxoSetForAddress($addresses: [String]) {
34 utxos(order_by: { value: desc }, where: { address: { _in: $addresses } }) {
35 address
36 value
37 tokens {
38 assetId
39 assetName
40 policyId
41 quantity
42 }
43 }
44 }
45 `,
46 variables: {
47 addresses,
48 },
49 })
50 .then((response) => {
51 if (response) {
52 return response.data
53 }
54 return false
55 })
56 .catch((err) => console.log(err))
57}
58
59class CardanoWasmModule {
60 async load() {
61 this.wasm = await import('@emurgo/cardano-serialization-lib-browser/cardano_serialization_lib')
62 }
63
64 get API() {
65 return this.wasm
66 }
67}
68
69
70/**
71 * Mnemonic generation
72 * @return {string}
73 */
74
75export const CardanoGenerateMnemonic = (length = 24) => {
76 return generateMnemonic((32 * length) / 3)
77}
78
79/**
80 * Get private key, public key, reward address
81 * @return {object}
82 */
83
84export const CardanoGetAccountInfo = async (network, mnemonic) => {
85 await CardanoWasm.load()
86
87 const harden = (num) => {
88 return 0x80000000 + num
89 }
90
91 const entropy = mnemonicToEntropy(mnemonic)
92 const rootKey = CardanoWasm.API.Bip32PrivateKey.from_bip39_entropy(
93 Buffer.from(entropy, 'hex'),
94 Buffer.from(''),
95 )
96
97 const privateKey = rootKey.derive(harden(1852)).derive(harden(1815)).derive(harden(0))
98
99 const stakeKey = privateKey.derive(2).derive(0).to_public()
100
101 const currentNetwork = network === 'testnet'
102 ? CardanoWasm.API.NetworkInfo.testnet().network_id()
103 : CardanoWasm.API.NetworkInfo.mainnet().network_id()
104
105 const rewardAddress = CardanoWasm.API.RewardAddress.new(
106 currentNetwork,
107 CardanoWasm.API.StakeCredential.from_keyhash(stakeKey.to_raw_key().hash()),
108 )
109 const rewardAddressBech32 = rewardAddress.to_address().to_bech32()
110 const privateKeyBech32 = privateKey.to_bech32()
111 const publicKeyBech32 = privateKey.to_public().to_bech32()
112
113 return { rewardAddressBech32, privateKeyBech32, publicKeyBech32 }
114}
115
116/**
117 * Generate address pack related to Private Key
118 * @param {string} publicKeyBech32 private key
119 * @param {string} type external internal / all derives
120 * @param {number} shift shifting addresses by page size
121 * @param {number} page page size
122 * @return {array} adresses array
123 */
124
125export const CardanoGetAccountAdresses = async (
126 network,
127 publicKeyBech32,
128 type = 'external',
129 shift = 0,
130 page = 20,
131) => {
132 await CardanoWasm.load()
133
134 const publicKey = CardanoWasm.API.Bip32PublicKey.from_bech32(publicKeyBech32)
135 const accountAdresses = []
136
137 const currentNetwork = network === 'testnet'
138 ? CardanoWasm.API.NetworkInfo.testnet().network_id()
139 : CardanoWasm.API.NetworkInfo.mainnet().network_id()
140
141 const generateAddresses = (addressType) => {
142 const tmpAddresses = []
143 for (let i = 0 + page * shift; i < page + page * shift; i += 1) {
144 const utxoPubKey = publicKey
145 .derive(addressType) // 0 external / 1 internal
146 .derive(i)
147 const stakeKey = publicKey
148 .derive(2) // chimeric
149 .derive(0)
150 const baseAddr = CardanoWasm.API.BaseAddress.new(
151 currentNetwork,
152 CardanoWasm.API.StakeCredential.from_keyhash(utxoPubKey.to_raw_key().hash()),
153 CardanoWasm.API.StakeCredential.from_keyhash(stakeKey.to_raw_key().hash()),
154 )
155 const baseAddrBech32 = baseAddr.to_address().to_bech32()
156 tmpAddresses.push(baseAddrBech32)
157 }
158 return tmpAddresses
159 }
160
161 switch (type) {
162 case 'external':
163 accountAdresses.push(...generateAddresses(0))
164 break
165 case 'internal':
166 accountAdresses.push(...generateAddresses(1))
167 break
168 case 'all':
169 accountAdresses.push(...generateAddresses(0))
170 accountAdresses.push(...generateAddresses(1))
171 break
172 default:
173 break
174 }
175
176 return accountAdresses
177}
178
179function* checkAddresses(type, shift, pageSize) {
180 const tmpAddresses = yield call(
181 Cardano.CardanoGetAccountAdresses,
182 CARDANO_NETWORK,
183 publicKey,
184 type,
185 shift,
186 pageSize,
187 )
188 const tmpAddresssesUTXO = yield call(Explorer.GetAdressesUTXO, tmpAddresses)
189 return [tmpAddresssesUTXO, tmpAddresses]
190}
191
192const UTXOArray = []
193const adressesArray = []
194const pageSize = 20
195const type = 'all'
196const maxShiftIndex = 10
197let shiftIndex = 0
198function* getAddressesWithShift(shift) {
199 const [adresssesWithUTXOs, checkedAdresses] = yield call(checkAddresses, type, shift, pageSize)
200 adressesArray.push(...checkedAdresses)
201 if (adresssesWithUTXOs.data && shiftIndex < maxShiftIndex) {
202 if (adresssesWithUTXOs.data.utxos.length) {
203 shiftIndex += 1
204 UTXOArray.push(...adresssesWithUTXOs.data.utxos)
205 yield call(getAddressesWithShift, shiftIndex)
206 }
207 }
208}
209yield call(getAddressesWithShift, shiftIndex)