Skip to content

Instantly share code, notes, and snippets.

@SahidMiller
Created July 2, 2021 20:43
Show Gist options
  • Save SahidMiller/3aecb4be4e5daf2229d50fdab3f7670c to your computer and use it in GitHub Desktop.
Save SahidMiller/3aecb4be4e5daf2229d50fdab3f7670c to your computer and use it in GitHub Desktop.
Publish to IPNS using secp256k1 cryptocurrency keys
const last = require('it-last')
const crypto = require('libp2p-crypto')
const { BITBOX } = require('bitbox-sdk')
const bitbox = new BITBOX()
const PeerId = require('peer-id')
const CID = require('cids')
//Recipient should convert a scriptSig of the UTXO sent to their address
function blockchainIpnsFetch(ipfs, scriptSig) {
//Extract public key from script signature
const { pubKey } = bitbox.Script.decodeP2PKHInput(scriptSigBuf)
//Convert to libp2p key
const publicKey = crypto.keys.supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(pubKey)
const peerId = await PeerId.createFromPubKey(publicKey.bytes)
const libp2pKey = new CID(1, 'libp2p-key', peerId.id, 'base32').toBaseEncodedString('base36')
//retry until we get a cid, God willing.
const result = await resolveIpns(ipfs, libp2pKey, { nocache: true })
const cid = result && result.replace("/ipfs/", "")
return await ipfs.cat(cid)
}
async function resolveIpns(ipfs, key, options = {}) {
return await last(ipfs.name.resolve(key, { stream: false, ...options }));
}
const crypto = require('libp2p-crypto')
const wif = require('wif')
const ipns = require('ipns')
const uint8ArrayToString = require('uint8arrays/to-string')
const PeerId = require('peer-id')
const CID = require('cids')
//Sender should convert UTXO private key to libp2p key for publishing
function blockchainIpnsPublish(libp2p, utxoPrivateKey, cid, seqNum) {
//Convert to libp2p key
const { privateKey } = wif.decode(utxoPrivateKey)
const senderLibp2pKey = await crypto.keys.supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(privateKey)
//Convert to IPNS record key
const senderPeerId = await PeerId.createFromPrivKey(senderLibp2pKey.bytes)
const senderIpnsId = new CID(1, 'libp2p-key', senderPeerId.id, 'base32').toBaseEncodedString('base36')
const recordKey = getSerializedRecordKey(senderIpnsId);
// Create IPNS record
const hourMs = 60 * 60 * 1000
const record = await ipns.create(privateKey, cid, seqNum, hourMs);
const recordData = ipns.marshal(record);
//Publish IPNS record to connected gateways
await libp2p.pubsub.subscribe(recordKey)
await libp2p.pubsub.publish(recordKey, recordData);
}
function getSerializedRecordKey(id) {
const origMh = new CID(id).multihash
const base58mh = new CID(1, 'libp2p-key', origMh, "base58btc").multihash
const key = ipns.getIdKeys(base58mh).routingKey.uint8Array();
const serialized = uint8ArrayToString(key, 'base64url');
return "/record/" + serialized;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment