UNPKG

@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
"use strict"; 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}`); } }; }