nostr 对于 NIP 的提交有一定要求:至少两个客户端和一个relay集成
但是,初期对于CKB而言,只需要客户端处理就好了。简单说,把nostr的私钥转换成一个CKB地址显示出来。已将专门给nostr进行签名的浏览器扩展:nos2x 进行fork:
读取私钥很简单:
// extension/popup.jsx
function Popup() {
let [pubKey, setPubKey] = useState('')
let keys = useRef([])
let [ckbAddress, setCkbAddress] = useState('')
useEffect(() => {
browser.storage.local.get(['private_key', 'relays']).then(results => {
if (results.private_key) {
// results.private_key is a hex with length 64, no '0x' prefix
const ckb_addr = getCkbAddress(`0x${results.private_key}`);
setCkbAddress(ckb_addr);
let hexKey = getPublicKey(results.private_key)
let npubKey = nip19.npubEncode(hexKey)
setPubKey(npubKey)
从results.private_key
中读取到的就是64字节的hex。
对于nos2x这个fork而言,后面就是引入ckb.js展示出ckb地址(以及余额);
进一步是通过这个私钥进行打赏操作(转账)。
- nos2x 需要新增的库:
buffer
, elliptic
, @ckb-lumos/config-manager
, @ckb-lumos/helpers
extension
目录中添加nervos.js
文件:
···
import { Buffer } from ‘buffer’;
import { ec as EC } from “elliptic”;
import { HexString, utils } from “@ckb-lumos/base”;
import { initializeConfig, predefined } from ‘@ckb-lumos/config-manager’;
import { encodeToAddress } from ‘@ckb-lumos/helpers’;
global.Buffer = Buffer;
const ec = new EC(“secp256k1”);
function assertPrivateKey(privateKey) {
utils.assertHexString(“privateKey”, privateKey);
if (privateKey.length !== 66) {
throw new Error(privateKey must be length of 32 bytes!
);
}
}
function assertPublicKey(publicKey, debugPath) {
debugPath = debugPath || “publicKey”;
utils.assertHexString(debugPath, publicKey);
if (publicKey.length !== 68) {
throw new Error(publicKey must be length of 33 bytes!
);
}
}
export function privateToPublic(privateKey) {
let pkBuffer = privateKey;
if (typeof privateKey === “string”) {
assertPrivateKey(privateKey);
pkBuffer = Buffer.from(privateKey.slice(2), “hex”);
}
if (pkBuffer.length !== 32) {
throw new Error(“Private key must be 32 bytes!”);
}
const publickey = ec.keyFromPrivate(pkBuffer).getPublic(true, “hex”);
if (typeof privateKey === “string”) {
return “0x” + publickey;
}
return Buffer.from(publickey, “hex”);
}
export function publicKeyToBlake160(publicKey) {
assertPublicKey(publicKey);
const blake160 = new utils.CKBHasher()
.update(publicKey)
.digestHex()
.slice(0, 42);
return blake160;
}
export function privateKeyToBlake160(privateKey) {
const publicKey = privateToPublic(privateKey);
return publicKeyToBlake160(publicKey);
}
export function getCkbAddress(privateKey) {
const config = predefined.LINA;
initializeConfig(config);
const pk = privateToPublic(privateKey);
const blake160 = publicKeyToBlake160(pk);
//encodeToConfigAddress(blake160, )
const script = {
codeHash: config.SCRIPTS.SECP256K1_BLAKE160.CODE_HASH,
hashType: "data1",
args: blake160,
};
const addr = encodeToAddress(script, config);
return addr;
}
···
- 修改
build.js
:
entryPoints: {
'nervos.build': './extension/nervos.js',
'popup.build': './extension/popup.jsx',
//...
},
效果: