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