@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.
256 lines (255 loc) • 15.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAuthRequestMessage = createAuthRequestMessage;
exports.createAuthVerifyMessageFromChallenge = createAuthVerifyMessageFromChallenge;
exports.createAuthVerifyMessage = createAuthVerifyMessage;
exports.createAuthVerifyMessageWithJWT = createAuthVerifyMessageWithJWT;
exports.createPingMessage = createPingMessage;
exports.createGetConfigMessage = createGetConfigMessage;
exports.createGetUserTagMessage = createGetUserTagMessage;
exports.createGetLedgerBalancesMessage = createGetLedgerBalancesMessage;
exports.createGetLedgerEntriesMessage = createGetLedgerEntriesMessage;
exports.createGetLedgerTransactionsMessage = createGetLedgerTransactionsMessage;
exports.createGetAppDefinitionMessage = createGetAppDefinitionMessage;
exports.createGetAppSessionsMessage = createGetAppSessionsMessage;
exports.createAppSessionMessage = createAppSessionMessage;
exports.createSubmitAppStateMessage = createSubmitAppStateMessage;
exports.createCloseAppSessionMessage = createCloseAppSessionMessage;
exports.createApplicationMessage = createApplicationMessage;
exports.createCloseChannelMessage = createCloseChannelMessage;
exports.createResizeChannelMessage = createResizeChannelMessage;
exports.createGetChannelsMessage = createGetChannelsMessage;
exports.createGetRPCHistoryMessage = createGetRPCHistoryMessage;
exports.createGetAssetsMessage = createGetAssetsMessage;
exports.createTransferMessage = createTransferMessage;
exports.createEIP712AuthMessageSigner = createEIP712AuthMessageSigner;
exports.createECDSAMessageSigner = createECDSAMessageSigner;
const viem_1 = require("viem");
const accounts_1 = require("viem/accounts");
const types_1 = require("./types");
const nitrolite_1 = require("./nitrolite");
const utils_1 = require("./utils");
async function createAuthRequestMessage(params, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const allowances = Object.values(params.allowances || {}).map((v) => [v.asset, v.amount]);
const paramsArray = [
params.wallet,
params.participant,
params.app_name,
allowances,
params.expire ?? '',
params.scope ?? '',
params.application ?? '',
];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.AuthRequest, paramsArray, timestamp);
request.sig = [''];
return JSON.stringify(request);
}
async function createAuthVerifyMessageFromChallenge(signer, challenge, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ challenge: challenge }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.AuthVerify, [params], timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createAuthVerifyMessage(signer, challenge, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ challenge: challenge.params.challengeMessage }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.AuthVerify, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createAuthVerifyMessageWithJWT(jwtToken, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ jwt: jwtToken }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.AuthVerify, params, timestamp);
return JSON.stringify(request);
}
async function createPingMessage(signer, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.Ping, [], timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetConfigMessage(signer, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetConfig, [], timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetUserTagMessage(signer, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetUserTag, [], timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetLedgerBalancesMessage(signer, participant, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ participant: participant }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetLedgerBalances, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetLedgerEntriesMessage(signer, accountId, asset, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [
{
account_id: accountId,
...(asset ? { asset } : {}),
},
];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetLedgerEntries, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetLedgerTransactionsMessage(signer, accountId, filters, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const filteredParams = {};
if (filters) {
Object.entries(filters).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
filteredParams[key] = value;
}
});
}
const paramsObj = {
account_id: accountId,
...filteredParams,
};
const params = [paramsObj];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetLedgerTransactions, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetAppDefinitionMessage(signer, appSessionId, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ app_session_id: appSessionId }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetAppDefinition, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetAppSessionsMessage(signer, participant, status, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [
{
participant,
...(status ? { status } : {}),
},
];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetAppSessions, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createAppSessionMessage(signer, params, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.CreateAppSession, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createSubmitAppStateMessage(signer, params, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.SubmitAppState, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createCloseAppSessionMessage(signer, params, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.CloseAppSession, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createApplicationMessage(signer, appSessionId, messageParams, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createAppRequest(requestId, types_1.RPCMethod.Message, messageParams, timestamp, appSessionId);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createCloseChannelMessage(signer, channelId, fundDestination, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [{ channel_id: channelId, funds_destination: fundDestination }];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.CloseChannel, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createResizeChannelMessage(signer, params, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.ResizeChannel, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest, (_, value) => (typeof value === 'bigint' ? value.toString() : value));
}
async function createGetChannelsMessage(signer, participant, status, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [
{
...(participant ? { participant } : {}),
...(status ? { status } : {}),
},
];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetChannels, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetRPCHistoryMessage(signer, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetRPCHistory, [], timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createGetAssetsMessage(signer, chainId, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const params = [
{
...(chainId ? { chain_id: chainId } : {}),
},
];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.GetAssets, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
async function createTransferMessage(signer, transferParams, requestId = (0, utils_1.generateRequestId)(), timestamp = (0, utils_1.getCurrentTimestamp)()) {
const hasDestination = !!transferParams.destination;
const hasDestinationTag = !!transferParams.destination_user_tag;
if (hasDestination === hasDestinationTag) {
throw new Error(hasDestination
? 'Cannot provide both destination and destination_user_tag'
: 'Either destination or destination_user_tag must be provided');
}
const params = [transferParams];
const request = nitrolite_1.NitroliteRPC.createRequest(requestId, types_1.RPCMethod.Transfer, params, timestamp);
const signedRequest = await nitrolite_1.NitroliteRPC.signRequestMessage(request, signer);
return JSON.stringify(signedRequest);
}
function createEIP712AuthMessageSigner(walletClient, partialMessage, domain) {
return async (payload) => {
const address = walletClient.account?.address;
if (!address) {
throw new Error('Wallet client is not connected or does not have an account.');
}
const method = payload[1];
if (method !== types_1.RPCMethod.AuthVerify) {
throw new Error(`This EIP-712 signer is designed only for the '${types_1.RPCMethod.AuthVerify}' method, but received '${method}'.`);
}
const params = payload[2];
const firstParam = Array.isArray(params) ? params[0] : undefined;
if (typeof firstParam !== 'object' ||
firstParam === null ||
!('challenge' in firstParam) ||
typeof firstParam.challenge !== 'string') {
throw new Error('Invalid payload for AuthVerify: The challenge string is missing or malformed.');
}
const challengeUUID = firstParam.challenge;
const message = {
...partialMessage,
challenge: challengeUUID,
wallet: address,
};
try {
const untypedMessage = { ...message };
const signature = await walletClient.signTypedData({
account: walletClient.account,
domain,
types: types_1.EIP712AuthTypes,
primaryType: 'Policy',
message: untypedMessage,
});
return signature;
}
catch (eip712Error) {
const errorMessage = eip712Error instanceof Error ? eip712Error.message : String(eip712Error);
console.error('EIP-712 signing failed:', errorMessage);
throw new Error(`EIP-712 signing failed: ${errorMessage}`);
}
};
}
function createECDSAMessageSigner(privateKey) {
return async (payload) => {
try {
const messageBytes = (0, viem_1.keccak256)((0, viem_1.stringToBytes)(JSON.stringify(payload, (_, v) => (typeof v === 'bigint' ? v.toString() : v))));
const flatSignature = await (0, accounts_1.privateKeyToAccount)(privateKey).sign({ hash: messageBytes });
return flatSignature;
}
catch (error) {
console.error('ECDSA signing failed:', error);
throw new Error(`ECDSA signing failed: ${error}`);
}
};
}