Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 2x 2x 2x 2x 1x 7x 2x 2x 2x 2x 2x 2x 1x 4x 4x 3x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x |
import bitcoin from 'bitcoinjs-lib'
import crypto from 'crypto'
// @ts-ignore: Could not find a declaration file for module
import { TokenSigner } from 'jsontokens'
import { ecPairToAddress, hexStringToECPair } from '../utils'
import { getPublicKeyFromPrivate } from '../keys'
import { Logger } from '../logger'
export const BLOCKSTACK_GAIA_HUB_LABEL = 'blockstack-gaia-hub-config'
export type GaiaHubConfig = {
address: string,
url_prefix: string,
token: string,
server: string
}
export async function uploadToGaiaHub(
filename: string, contents: any,
hubConfig: GaiaHubConfig,
contentType: string = 'application/octet-stream'
): Promise<string> {
Logger.debug(`uploadToGaiaHub: uploading ${filename} to ${hubConfig.server}`)
const response = await fetch(
`${hubConfig.server}/store/${hubConfig.address}/${filename}`, {
method: 'POST',
headers: {
'Content-Type': contentType,
Authorization: `bearer ${hubConfig.token}`
},
body: contents
}
)
if (!response.ok) {
throw new Error('Error when uploading to Gaia hub')
}
const responseText = await response.text()
const responseJSON = JSON.parse(responseText)
return responseJSON.publicURL
}
export function getFullReadUrl(filename: string,
hubConfig: GaiaHubConfig): Promise<string> {
return Promise.resolve(`${hubConfig.url_prefix}${hubConfig.address}/${filename}`)
}
function makeLegacyAuthToken(challengeText: string, signerKeyHex: string): string {
// only sign specific legacy auth challenges.
let parsedChallenge
try {
parsedChallenge = JSON.parse(challengeText)
} catch (err) {
throw new Error('Failed in parsing legacy challenge text from the gaia hub.')
}
if (parsedChallenge[0] === 'gaiahub'
&& parsedChallenge[3] === 'blockstack_storage_please_sign') {
const signer = hexStringToECPair(signerKeyHex
+ (signerKeyHex.length === 64 ? '01' : ''))
const digest = bitcoin.crypto.sha256(Buffer.from(challengeText))
const signatureBuffer = signer.sign(digest)
const signatureWithHash = bitcoin.script.signature.encode(
signatureBuffer, bitcoin.Transaction.SIGHASH_NONE)
// We only want the DER encoding so remove the sighash version byte at the end.
// See: https://github.com/bitcoinjs/bitcoinjs-lib/issues/1241#issuecomment-428062912
const signature = signatureWithHash.toString('hex').slice(0, -2)
const publickey = getPublicKeyFromPrivate(signerKeyHex)
const token = Buffer.from(JSON.stringify(
{ publickey, signature }
)).toString('base64')
return token
} else {
throw new Error('Failed to connect to legacy gaia hub. If you operate this hub, please update.')
}
}
function makeV1GaiaAuthToken(hubInfo: any,
signerKeyHex: string,
hubUrl: string,
associationToken?: string): string {
const challengeText = hubInfo.challenge_text
const handlesV1Auth = (hubInfo.latest_auth_version
&& parseInt(hubInfo.latest_auth_version.slice(1), 10) >= 1)
const iss = getPublicKeyFromPrivate(signerKeyHex)
if (!handlesV1Auth) {
return makeLegacyAuthToken(challengeText, signerKeyHex)
}
const salt = crypto.randomBytes(16).toString('hex')
const payload = {
gaiaChallenge: challengeText,
hubUrl,
iss,
salt,
associationToken
}
const token = new TokenSigner('ES256K', signerKeyHex).sign(payload)
return `v1:${token}`
}
export async function connectToGaiaHub(
gaiaHubUrl: string,
challengeSignerHex: string,
associationToken?: string
): Promise<GaiaHubConfig> {
Logger.debug(`connectToGaiaHub: ${gaiaHubUrl}/hub_info`)
const response = await fetch(`${gaiaHubUrl}/hub_info`)
const hubInfo = await response.json()
const readURL = hubInfo.read_url_prefix
const token = makeV1GaiaAuthToken(hubInfo, challengeSignerHex, gaiaHubUrl, associationToken)
const address = ecPairToAddress(hexStringToECPair(challengeSignerHex
+ (challengeSignerHex.length === 64 ? '01' : '')))
return {
url_prefix: readURL,
address,
token,
server: gaiaHubUrl
}
}
export async function getBucketUrl(gaiaHubUrl: string, appPrivateKey: string): Promise<string> {
const challengeSigner = bitcoin.ECPair.fromPrivateKey(Buffer.from(appPrivateKey, 'hex'))
const response = await fetch(`${gaiaHubUrl}/hub_info`)
const responseText = await response.text()
const responseJSON = JSON.parse(responseText)
const readURL = responseJSON.read_url_prefix
const address = ecPairToAddress(challengeSigner)
const bucketUrl = `${readURL}${address}/`
return bucketUrl
}
|