wietsewind's notebooks

  • Base64 URL - /wietsewind/base64-url
    Last edited 10 months ago
    const base64url = require('base64url') let data = 'd2lldHNld2luZCE' console.log(base64url.decode(data))
  • Test rippled instance (Endpoint) - /wietsewind/test-rippled-instance-endpoint
    Last edited 10 months ago
    const WebSocket = require('websocket').client const ServersToTest = [ 'rippled-dev.xrpayments.co', 'rippled.xrptipbot.com', 's1.ripple.com' ] exports.endpoint = (request, response) => { Promise.all(ServersToTest.map(Server => { return new Promise((resolve, reject) => { let WsInstance = new WebSocket() WsInstance.connect('wss://' + Server) WsInstance.on('connectFailed', error => { console.log('Connect Error ' + Server, error.toString()) resolve({ server: Server, status: 'ConnectError', data: null, errorData: error.toString() }) }) WsInstance.on('connect', c => { // console.log('Connected ' + Server, c) c.on('message', m => { let data = JSON.parse(m.utf8Data) // console.log('Message ' + Server, data) resolve({ server: Server, status: 'Response', data: data, errorData: null }) c.close() }) c.on('close', () => { // console.log('Closed ' + Server) }) c.on('error', e => { console.log('Error ' + Server, e.toString()) resolve({ server: Server, status: 'MsgError', data: null, errorData: e.toString() }) }) c.send(JSON.stringify({ command: 'server_info' })) setTimeout(() => { c.close() resolve({ server: Server, status: 'Timeout', data: null, errorData: null }) }, 5000) }) }) })).then(Results => { // Running in the browser, respond let highestLedger = Math.max.apply(Math, Results.filter(r => { return r.status === 'Response' && r.data !== null && r.data.result.info.complete_ledgers.match(/[0-9]/) }).map(r => { return parseInt(r.data.result.info.complete_ledgers.split(',').reverse()[0].split('-').reverse()[0]) }).filter(r => { return !isNaN(r) })) let OutputData = { highestLedger: highestLedger, responses: Object.assign({}, ...Results.map(r => { let lastLedger = 0 if (r.data !== null) { lastLedger = parseInt(r.data.result.info.complete_ledgers.split(',').reverse()[0].split('-').reverse()[0]) if (isNaN(lastLedger)) lastLedger = 0 } return { [r.server.replace(/[^a-z0-9]/g, '')]: Object.assign(r, { lastLedger: lastLedger, ledgerOffset: highestLedger - lastLedger }) } })) } if (response !== null) { response.end(JSON.stringify(OutputData)) } else { // Running in the console. Log. console.log('Done', OutputData) } }).catch(Error => { }) } // When in the browser... exports.endpoint(null, null)
  • Axios multiple calls, one promise - /wietsewind/axios-multiple-calls-one-promise
    Last edited 10 months ago
    const axios = require('axios') const checkMultipleAddresses = (addresses) => { return Promise.all( addresses.map((address, index) => { return new Promise((resolve, reject) => { axios.get('https://bithomp.com/api/v1/userinfo/' + address).then(result => { resolve(Object.assign(result.data, { __index: index })) }).catch(e => { // Got an Error from the HTTP call, but we handle it as OK (resolve instead of reject) resolve({ address: address, error: true, message: e.toString(), __index: index }) }) }) }) ) } checkMultipleAddresses([ 'rDpsdD9vTwkf1GiNkxunLLDBXsEXG9GNmk', 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', 'rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY' ]).then(results => { results.sort((a, b) => { return a.__index - b.__index }) console.log('Multiple addresses result:', results) })
  • Ripple-lib valid addr. (promise) - /wietsewind/ripple-lib-valid-addr-promise
    Last edited 10 months ago
    const RippleAPI = require('ripple-lib').RippleAPI const RippleAddressCodec = require('ripple-address-codec') const api = new RippleAPI({ server: 'wss://s2.ripple.com:443' }) /** * Note: isValidAddress will probably be exposed in a future ripple-lib release at api level. */ api.connect().then(() => { return new Promise((resolve, reject) => { if (RippleAddressCodec.isValidAddress("rBwdSqfFMBYUazUsv9pV1ZpHTG2nZcaNJv")) { resolve(true) } else { reject(new Error('Invalid XRPL account')) } }) }).then(r => { console.log('Valid?', r) }).then(() => { console.log('Disconnect') api.disconnect() }) .catch(e => console.log("Caught error", e))
  • Promise sequence sample - /wietsewind/promise-sequence-sample
    Last edited 10 months ago
    let MySampleFunction = () => { return new Promise((resolve, reject) => { setTimeout(() => { let theText = 'initial function' console.log(theText) resolve(theText) }, 1000) }) } MySampleFunction() .then((input) => { return new Promise((resolve, reject) => { let theText = 'second function' setTimeout(() => { console.log(Math.round(new Date() / 1000) + ': ' + input + ', ' + theText) resolve(theText) }, 1000) }) }) .then((input) => { return new Promise((resolve, reject) => { let theText = 'third function' setTimeout(() => { console.log(Math.round(new Date() / 1000) + ': ' + input + ', ' + theText) resolve(theText) // reject(new Error('Sucks to be you ;)')) }, 1000) }) }) .then((input) => { return new Promise((resolve, reject) => { let theText = 'fourth function' setTimeout(() => { console.log(Math.round(new Date() / 1000) + ': ' + input + ', ' + theText) resolve(theText) }, 1000) }) }) .catch((e) => { console.log('Shit hit the fan', e) })
  • XRP Tx gt 20.000 XRP - /wietsewind/xrp-tx-gt-20-000-xrp
    Last edited 10 months ago
    const websocket = require('websocket') const RippledWsClient = require('rippled-ws-client') // Set these values and then check the magic at the bottom of this script const minAmount = 20000 // Min amount in XRP const account = 'rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh' const fetchData = function (connection, lastSeenLedgerAndTx) { return new Promise((resolve, reject) => { let hasSeenOverlappingTx = typeof lastSeenLedgerAndTx === 'undefined' let txs = [] let command = { command: 'account_tx', account: account, ledger_index_max: (typeof lastSeenLedgerAndTx !== 'undefined' ? lastSeenLedgerAndTx.Ledger : -1) } connection.send(command).then((r) => { let lastSeen = null r.transactions.forEach((i) => { if (i.tx.TransactionType === 'Payment' && parseInt(i.tx.Amount) >= minAmount * 1000 * 1000) { if (hasSeenOverlappingTx) { txs.push({ Amount: parseInt(i.tx.Amount) / 1000 / 1000, From: i.tx.Account, To: i.tx.Destination, Ledger: i.tx.inLedger, Hash: i.tx.hash }) lastSeen = { Ledger: i.tx.inLedger, Hash: i.tx.hash } } } if (!hasSeenOverlappingTx && i.tx.hash === lastSeenLedgerAndTx.Hash) { hasSeenOverlappingTx = true } }) resolve({ // let nextSeq = r.marker.seq txs: txs, next () { return fetchData(connection, lastSeen) } }) }) }) } new RippledWsClient('wss://s2.ripple.com').then(function (connection) { fetchData(connection).then((data) => { console.log(data.txs) // data.txs = array with transactions, // data.next = promise with the next set of results data.next().then((moreData) => { console.log(moreData.txs) }) }) }).catch(function (error) { // Oops! })
  • Mini Promise Sample - /wietsewind/mini-promise-sample
    Last edited 10 months ago
    const times2 = (i) => { return new Promise((resolve, reject) => { // setTimeout(() => { // reject(new Error('Timeout, duurde te lang')) // }, 900) setTimeout(() => { let o = (i || 1) * 2 console.log(o) resolve(o) }, 1000) }) } times2(10) .then(times2).then((i) => { return new Promise((resolve, reject) => { let o = i * 10 resolve(o) // Nothing happens from here since the promise resolved // console.log(o) let myError = new Error('Error thingy') myError.dummyValue = 'Pepper & Dino' reject(myError) }) }) .then(times2) .catch((c) => { console.log('Stuff broke', c.dummyValue) })
  • Recover 1char Ripple Secret - /wietsewind/recover-1char-ripple-secret
    Last edited 10 months ago
    const kp = require('ripple-keypairs') // The secret below is a secret with one char missing. let secret = 'shx31Co5jta7Jp2ky1govCC8DSRb' let len = secret.length + 1 let alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890' let alphlen = alph.length for(let i = 1; i < len; i++) { for(let l = 0; l < alphlen; l++){ let gensecret = secret.substring(0, i) + alph.substring(l, l + 1) + secret.substring(i) try { let pair = kp.deriveKeypair(gensecret) let wallet = kp.deriveAddress(pair.publicKey) console.log('Secret', gensecret) console.log('Address', wallet) process.exit(0) } catch (e) { } } } return
  • Check XRP Wallet addr. - /wietsewind/check-xrp-wallet-addr
    Last edited 10 months ago
    var keypairs = require('ripple-keypairs'); let secret = keypairs.generateSeed({ algorithm: 'secp256k1' // or: 'ed25519' }) // var secret = 'shobxZSHdQaQ4EmyicWzV3K7PQj1U' var keypair = keypairs.deriveKeypair(secret); var address = keypairs.deriveAddress(keypair.publicKey); console.log( keypair ) console.log( { secret: secret, address: address } )
  • secp256k1 Sign & Verify signature - /wietsewind/secp256k1-sign-verify-signature
    Last edited 10 months ago
    const elliptic = require('elliptic') const secp256k1 = elliptic.ec('secp256k1') const hash = require('hash.js') const keypairs = require('ripple-keypairs') const hexToDecimal = (x) => secp256k1.keyFromPrivate(x, 'hex').getPrivate().toString(10) module.exports = { sign (message, familySeed) { const digest = hash.sha256().update(message).digest('hex').toUpperCase() const keypair = keypairs.deriveKeypair(familySeed) const signature = secp256k1.sign(digest, keypair.privateKey.substr(2)) return { hash: digest, signature: (signature.r.toJSON() + signature.s.toJSON() + signature.recoveryParam.toString(16)).toUpperCase() } }, unserializeSignature (signature) { return { r: signature.slice(0, 64).toLowerCase(), s: signature.slice(64, 128).toLowerCase(), recoveryParam: parseInt(signature.slice(128), 16) } }, deriveAddress (familySeed) { const keypair = keypairs.deriveKeypair(familySeed) return keypairs.deriveAddress(keypair.publicKey) }, recoverPubKey (hash, signature) { const unserializedSignature = this.unserializeSignature(signature) const pubKeyRecovered = secp256k1.recoverPubKey(hexToDecimal(hash), unserializedSignature, unserializedSignature.recoveryParam, 'hex') return pubKeyRecovered }, recoverAddress (hash, signature) { return keypairs.deriveAddress(this.recoverPubKey(hash, signature).encodeCompressed('hex')) }, verify (message, signature) { const digest = hash.sha256().update(message).digest('hex') const unserializedSignature = this.unserializeSignature(signature) return secp256k1.verify(digest, unserializedSignature, this.recoverPubKey(digest, signature)) } }