@erc7824/nitrolite
Version:
The Nitrolite SDK empowers developers to build high-performance, scalable web3 applications using state channels. It's designed to provide near-instant transactions and significantly improved user experiences by minimizing direct blockchain interactions.
82 lines (81 loc) • 2.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStateHash = getStateHash;
exports.signState = signState;
exports.removeQuotesFromRS = removeQuotesFromRS;
exports.verifySignature = verifySignature;
const viem_1 = require("viem");
function getStateHash(channelId, state) {
const encoded = (0, viem_1.encodeAbiParameters)([
{ name: 'channelId', type: 'bytes32' },
{
name: 'intent',
type: 'uint8',
},
{
name: 'version',
type: 'uint256',
},
{ name: 'data', type: 'bytes' },
{
name: 'allocations',
type: 'tuple[]',
components: [
{ name: 'destination', type: 'address' },
{ name: 'token', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
},
], [channelId, state.intent, state.version, state.data, state.allocations]);
return (0, viem_1.keccak256)(encoded);
}
async function signState(stateHash, signMessage) {
try {
const signatureHex = await signMessage({ message: { raw: stateHash } });
const parsedSig = (0, viem_1.parseSignature)(signatureHex);
let v;
if (parsedSig.v !== undefined) {
v = Number(parsedSig.v);
}
else if (parsedSig.yParity !== undefined) {
v = parsedSig.yParity + 27;
}
else {
throw new Error('Invalid signature format: missing v or yParity value');
}
return {
r: parsedSig.r,
s: parsedSig.s,
v,
};
}
catch (error) {
console.error('Error signing state hash:', error);
throw new Error(`Failed to sign state hash: ${error instanceof Error ? error.message : String(error)}`);
}
}
function removeQuotesFromRS(input) {
const output = { ...input };
if (typeof output.r === 'string') {
output.r = output.r.replace(/^"(.*)"$/, '$1');
}
if (typeof output.s === 'string') {
output.s = output.s.replace(/^"(.*)"$/, '$1');
}
return output;
}
async function verifySignature(stateHash, signature, expectedSigner) {
try {
const vNormalized = signature.v < 27 ? signature.v + 27 : signature.v;
const signatureHex = `${signature.r}${signature.s.slice(2)}${vNormalized.toString(16).padStart(2, '0')}`;
const recoveredAddress = await (0, viem_1.recoverMessageAddress)({
message: { raw: stateHash },
signature: signatureHex,
});
return recoveredAddress.toLowerCase() === expectedSigner.toLowerCase();
}
catch (error) {
console.error('Signature verification failed:', error);
return false;
}
}