@snowflake-so/safe-saber-walletkit
Version:
Snowflake Safe forked version of @saberhq/use-solana package. Used for integration purpose.
87 lines • 3.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPublicKey = exports.signBytes = exports.signTransaction = exports.getSolanaDerivationPath = void 0;
const web3_js_1 = require("@solana/web3.js");
const INS_GET_PUBKEY = 0x05;
const INS_SIGN_MESSAGE = 0x06;
const P1_NON_CONFIRM = 0x00;
const P1_CONFIRM = 0x01;
const P2_EXTEND = 0x01;
const P2_MORE = 0x02;
const MAX_PAYLOAD = 255;
const LEDGER_CLA = 0xe0;
/*
* Helper for chunked send of large payloads
*/
async function ledgerSend(transport, instruction, p1, payload) {
let p2 = 0;
let payloadOffset = 0;
if (payload.length > MAX_PAYLOAD) {
while (payload.length - payloadOffset > MAX_PAYLOAD) {
const chunk = payload.slice(payloadOffset, payloadOffset + MAX_PAYLOAD);
payloadOffset += MAX_PAYLOAD;
const reply = await transport.send(LEDGER_CLA, instruction, p1, p2 | P2_MORE, chunk);
if (reply.length !== 2) {
throw new Error('Received unexpected reply payload');
}
p2 |= P2_EXTEND;
}
}
const chunk = payload.slice(payloadOffset);
const reply = await transport.send(LEDGER_CLA, instruction, p1, p2, chunk);
return reply.slice(0, reply.length - 2);
}
const BIP32_HARDENED_BIT = (1 << 31) >>> 0;
function harden(n = 0) {
return (n | BIP32_HARDENED_BIT) >>> 0;
}
function getSolanaDerivationPath(account, change) {
let length;
if (account !== undefined) {
if (change !== undefined) {
length = 4;
}
else {
length = 3;
}
}
else {
length = 2;
}
const derivationPath = Buffer.alloc(1 + length * 4);
// eslint-disable-next-line
var offset = 0;
offset = derivationPath.writeUInt8(length, offset);
offset = derivationPath.writeUInt32BE(harden(44), offset); // Using BIP44
offset = derivationPath.writeUInt32BE(harden(501), offset); // Solana's BIP44 path
if (length > 2) {
offset = derivationPath.writeUInt32BE(harden(account), offset);
if (length === 4) {
// @FIXME: https://github.com/project-serum/spl-token-wallet/issues/59
// eslint-disable-next-line @typescript-eslint/no-unused-vars
offset = derivationPath.writeUInt32BE(harden(change), offset);
}
}
return derivationPath;
}
exports.getSolanaDerivationPath = getSolanaDerivationPath;
async function signTransaction(transport, transaction, derivationPath = getSolanaDerivationPath()) {
const messageBytes = transaction.serializeMessage();
return signBytes(transport, messageBytes, derivationPath);
}
exports.signTransaction = signTransaction;
async function signBytes(transport, bytes, derivationPath = getSolanaDerivationPath()) {
const numPaths = Buffer.alloc(1);
numPaths.writeUInt8(1, 0);
const payload = Buffer.concat([numPaths, derivationPath, bytes]);
// @FIXME: must enable blind signing in Solana Ledger App per https://github.com/project-serum/spl-token-wallet/issues/71
// See also https://github.com/project-serum/spl-token-wallet/pull/23#issuecomment-712317053
return ledgerSend(transport, INS_SIGN_MESSAGE, P1_CONFIRM, payload);
}
exports.signBytes = signBytes;
async function getPublicKey(transport, derivationPath = getSolanaDerivationPath()) {
const publicKeyBytes = await ledgerSend(transport, INS_GET_PUBKEY, P1_NON_CONFIRM, derivationPath);
return new web3_js_1.PublicKey(publicKeyBytes);
}
exports.getPublicKey = getPublicKey;
//# sourceMappingURL=core.js.map