Skip to content

Instantly share code, notes, and snippets.

@yuche
Last active September 9, 2020 08:51
Show Gist options
  • Save yuche/51d25dda02b9495f94a981c965d1cd5f to your computer and use it in GitHub Desktop.
Save yuche/51d25dda02b9495f94a981c965d1cd5f to your computer and use it in GitHub Desktop.
LedgerJS with NervosDAO
const path = require("path");
const os = require("os");
const CKB = require("@nervosnetwork/ckb-sdk-core").default;
const { Indexer, CellCollector } = require("@ckb-lumos/indexer");
const LUMOS_DB = process.env.LUMOS_DB || path.join(os.tmpdir(), "lumos_db");
const CKB_URL = process.env.CKB_URL || "http://127.0.0.1:8117";
// Whether to connect to a running instance of the Speculos simulator for
// ledger apps or a real physical ledger
const indexer = new Indexer(CKB_URL, LUMOS_DB);
// Note: there is currently a bug in the speculos simulator that appears not to
// have been adequately addressed that prevents correctly generating the the
// last byte of a recoverable signature. You can work around this by replacing
// the last byte with 00, trying to send the signature, and if that fails
// trying again with 01. This issue _ONLY_ occurs with Speculos, which has a
// different implementation of cryptography primitives than the real hardware.
const Transport = require("@ledgerhq/hw-transport-node-hid").default;
const LedgerCkb = require("../").default;
const ckbPath = "44'/309'/0'/0/0";
const bootstrap = async () => {
const ckb = new CKB(CKB_URL); // instantiate the JS SDK with provided node url
let transport = await Transport.open();
const lckb = new LedgerCkb(transport);
const keydata = await lckb.getWalletPublicKey(ckbPath, true);
console.log(keydata);
const publicKeyHash = "0x" + keydata.lockArg;
const address = keydata.address;
const addresses = { testnetAddress: address };
const loadCells = async () => {
await ckb.loadDeps();
const lockHash = ckb.generateLockHash(publicKeyHash);
return await ckb.loadCells({
lockHash,
start: BigInt(0),
end: BigInt(500000),
save: true,
});
};
const cells = await loadCells();
const rawTransaction = ckb.generateDaoDepositTransaction({
fromAddress: addresses.testnetAddress,
capacity: BigInt(10400000000),
fee: BigInt(100000),
cells,
});
console.log(rawTransaction);
rawTransaction.witnesses = rawTransaction.inputs.map(() => "0x");
rawTransaction.witnesses[0] = ckb.utils.serializeWitnessArgs({
lock: "",
inputType: "",
outputType: "",
});
console.log("rawTransaction:", JSON.stringify(rawTransaction));
// fetch all the context transactions
const ctxds = (
await Promise.all(
rawTransaction.inputs.map((a) =>
ckb.rpc.getTransaction(a.previousOutput.txHash)
)
)
).map((a) => a.transaction);
const formatted = ckb.rpc.paramsFormatter.toRawTransaction(rawTransaction);
const formattedCtxd = ctxds.map(ckb.rpc.paramsFormatter.toRawTransaction);
try {
const signature = await lckb.signTransaction(
ckbPath,
formatted,
formatted.witnesses,
formattedCtxd,
ckbPath
);
rawTransaction.witnesses[0] = ckb.utils.serializeWitnessArgs({
lock: "0x" + signature,
inputType: "",
outputType: "",
});
const realTxHash = await ckb.rpc
.sendTransaction(rawTransaction)
.catch((err) => err);
console.log(`The real transaction hash is: ${realTxHash}`);
} catch (error) {
console.log(error);
}
/**
* to see the real transaction hash
*/
};
try {
bootstrap();
} catch (error) {
console.log(error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment