Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
341 changes: 341 additions & 0 deletions packages/xrpl/src/utils/hashes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,345 @@ export function hashPaymentChannel(
)
}

/**
* Compute the hash of a Ticket.
*
* @param address - Account that created the Ticket.
* @param ticketSequence - The Ticket Sequence number.
* @returns Hash of the Ticket.
* @category Utilities
*/
export function hashTicket(address: string, ticketSequence: number): string {
return sha512Half(
ledgerSpaceHex('ticket') +
addressToHex(address) +
ticketSequence.toString(HEX).padStart(BYTE_LENGTH * 2, '0'),
)
}

/**
* Compute the hash of a Check.
*
* @param address - Account that created the Check.
* @param sequence - Sequence number of the CheckCreate transaction.
* @returns Hash of the Check.
* @category Utilities
*/
export function hashCheck(address: string, sequence: number): string {
return sha512Half(
ledgerSpaceHex('check') +
addressToHex(address) +
sequence.toString(HEX).padStart(BYTE_LENGTH * 2, '0'),
)
}

/**
* Compute the hash of a DepositPreauth entry.
*
* @param address - Account that granted the authorization.
* @param authorizedAddress - Account that was authorized.
* @returns Hash of the DepositPreauth entry.
* @category Utilities
*/
export function hashDepositPreauth(
address: string,
authorizedAddress: string,
): string {
return sha512Half(
ledgerSpaceHex('depositPreauth') +
addressToHex(address) +
addressToHex(authorizedAddress),
)
}

/**
* Compute the hash of an NFTokenPage.
*
* @param address - Account that owns the NFTokenPage.
* @param nfTokenIDLow96 - The low 96 bits of a representative NFTokenID.
* @returns Hash of the NFTokenPage.
* @throws Error if nfTokenIDLow96 is not a 24-character hex string.
* @category Utilities
*/
export function hashNFTokenPage(
address: string,
nfTokenIDLow96: string,
): string {
// Validate that nfTokenIDLow96 is a 24-character hex string (96 bits)
if (!/^[0-9A-F]{24}$/iu.test(nfTokenIDLow96)) {
throw new Error('nfTokenIDLow96 must be a 24-character hex string')
}
return sha512Half(
ledgerSpaceHex('nfTokenPage') + addressToHex(address) + nfTokenIDLow96,
)
}

/**
* Compute the hash of an NFTokenOffer.
*
* @param address - Account that created the NFTokenOffer.
* @param sequence - Sequence number of the NFTokenCreateOffer transaction.
* @returns Hash of the NFTokenOffer.
* @category Utilities
*/
export function hashNFTokenOffer(address: string, sequence: number): string {
return sha512Half(
ledgerSpaceHex('nfTokenOffer') +
addressToHex(address) +
sequence.toString(HEX).padStart(BYTE_LENGTH * 2, '0'),
)
}

/**
* Compute the hash of an AMM root.
*
* @param currency1 - First currency in the AMM pool.
* @param currency2 - Second currency in the AMM pool.
* @param issuer1 - Issuer of the first currency (omit for XRP).
* @param issuer2 - Issuer of the second currency (omit for XRP).
* @returns Hash of the AMM root.
* @category Utilities
*/
export function hashAMMRoot(
currency1: string,
currency2: string,
issuer1?: string,
issuer2?: string,
): string {
const cur1Hex = currencyToHex(currency1)
const cur2Hex = currencyToHex(currency2)
const iss1Hex = issuer1 ? addressToHex(issuer1) : '00'.repeat(20)
const iss2Hex = issuer2 ? addressToHex(issuer2) : '00'.repeat(20)

// Ensure deterministic ordering
const asset1 = cur1Hex + iss1Hex
const asset2 = cur2Hex + iss2Hex
const swap = new BigNumber(asset1, HEX).isGreaterThan(
new BigNumber(asset2, HEX),
)

const lowAsset = swap ? asset2 : asset1
const highAsset = swap ? asset1 : asset2

return sha512Half(ledgerSpaceHex('ammRoot') + lowAsset + highAsset)
}

/**
* Compute the hash of an Oracle entry.
*
* @param address - Account that created the Oracle.
* @param oracleID - The unique identifier for this Oracle.
* @returns Hash of the Oracle.
* @throws Error if oracleID is not a 64-character uppercase hex string.
* @category Utilities
*/
export function hashOracle(address: string, oracleID: string): string {
// Validate that oracleID is a 64-character uppercase hex string
if (!/^[0-9A-F]{64}$/u.test(oracleID)) {
throw new Error(
'oracleID must be a 64-character uppercase hexadecimal string',
)
}
return sha512Half(ledgerSpaceHex('oracle') + addressToHex(address) + oracleID)
}

/**
* Compute the hash of a Hook entry.
*
* @param address - Account that installed the Hook.
* @param hookHash - Hash of the Hook code.
* @returns Hash of the Hook entry.
* @throws Error if hookHash is not a 64-character hex string.
* @category Utilities
*/
export function hashHook(address: string, hookHash: string): string {
// Validate that hookHash is a 64-character hex string
if (!/^[0-9A-F]{64}$/iu.test(hookHash)) {
throw new Error('hookHash must be a 64-character hexadecimal string')
}
return sha512Half(ledgerSpaceHex('hook') + addressToHex(address) + hookHash)
}

/**
* Compute the hash of a Hook State entry.
*
* @param address - Account that owns the Hook State.
* @param hookHash - Hash of the Hook code.
* @param hookStateKey - Key for the Hook State entry.
* @returns Hash of the Hook State entry.
* @throws Error if hookHash or hookStateKey are not 64-character hex strings.
* @category Utilities
*/
export function hashHookState(
address: string,
hookHash: string,
hookStateKey: string,
): string {
// Validate parameters
if (!/^[0-9A-F]{64}$/iu.test(hookHash)) {
throw new Error('hookHash must be a 64-character hexadecimal string')
}
if (!/^[0-9A-F]{64}$/iu.test(hookStateKey)) {
throw new Error('hookStateKey must be a 64-character hexadecimal string')
}
return sha512Half(
ledgerSpaceHex('hookState') +
addressToHex(address) +
hookHash +
hookStateKey,
)
}

/**
* Compute the hash of a Hook Definition entry.
*
* @param hookHash - Hash of the Hook code.
* @returns Hash of the Hook Definition entry.
* @throws Error if hookHash is not a 64-character hex string.
* @category Utilities
*/
export function hashHookDefinition(hookHash: string): string {
// Validate that hookHash is a 64-character hex string
if (!/^[0-9A-F]{64}$/iu.test(hookHash)) {
throw new Error('hookHash must be a 64-character hexadecimal string')
}
return sha512Half(ledgerSpaceHex('hookDefinition') + hookHash)
}

/**
* Compute the hash of a DID entry.
*
* @param address - Account that owns the DID.
* @returns Hash of the DID entry.
* @category Utilities
*/
export function hashDID(address: string): string {
return sha512Half(ledgerSpaceHex('did') + addressToHex(address))
}

/**
* Compute the hash of a Bridge entry.
*
* @param door - The door account of the bridge.
* @param otherChainSource - The source account on the other chain.
* @param issuingChainDoor - The door account on the issuing chain.
* @param issuingChainIssue - The issue specification on the issuing chain.
* @param lockingChainDoor - The door account on the locking chain.
* @param lockingChainIssue - The issue specification on the locking chain.
* @returns Hash of the Bridge entry.
* @category Utilities
*/
export function hashBridge(
door: string,
otherChainSource: string,
issuingChainDoor: string,
issuingChainIssue: string,
lockingChainDoor: string,
lockingChainIssue: string,
): string {
return sha512Half(
ledgerSpaceHex('bridge') +
addressToHex(door) +
addressToHex(otherChainSource) +
addressToHex(issuingChainDoor) +
currencyToHex(issuingChainIssue) +
addressToHex(lockingChainDoor) +
currencyToHex(lockingChainIssue),
)
}

/**
* Compute the hash of an XChain Owned Claim ID entry.
*
* @param address - Account that owns the claim ID.
* @param bridgeAccount - The bridge account.
* @param claimID - The claim ID.
* @returns Hash of the XChain Owned Claim ID entry.
* @category Utilities
*/
export function hashXChainOwnedClaimID(
address: string,
bridgeAccount: string,
claimID: number,
): string {
return sha512Half(
ledgerSpaceHex('xchainOwnedClaimID') +
addressToHex(address) +
addressToHex(bridgeAccount) +
claimID.toString(HEX).padStart(BYTE_LENGTH * 2, '0'),
)
}

/**
* Compute the hash of an XChain Owned Create Account Claim ID entry.
*
* @param address - Account that owns the create account claim ID.
* @param bridgeAccount - The bridge account.
* @param claimID - The claim ID.
* @returns Hash of the XChain Owned Create Account Claim ID entry.
* @category Utilities
*/
export function hashXChainOwnedCreateAccountClaimID(
address: string,
bridgeAccount: string,
claimID: number,
): string {
return sha512Half(
ledgerSpaceHex('xchainOwnedCreateAccountClaimID') +
addressToHex(address) +
addressToHex(bridgeAccount) +
claimID.toString(HEX).padStart(BYTE_LENGTH * 2, '0'),
)
}

/**
* Compute the hash of an MPToken entry.
*
* @param address - Account that holds the MPToken.
* @param mpTokenIssuanceID - The MPToken issuance ID.
* @returns Hash of the MPToken entry.
* @throws Error if mpTokenIssuanceID is not a 64-character hex string.
* @category Utilities
*/
export function hashMPToken(
address: string,
mpTokenIssuanceID: string,
): string {
// Validate that mpTokenIssuanceID is a 64-character hex string
if (!/^[0-9A-F]{64}$/iu.test(mpTokenIssuanceID)) {
throw new Error(
'mpTokenIssuanceID must be a 64-character hexadecimal string',
)
}
return sha512Half(
ledgerSpaceHex('mpToken') + addressToHex(address) + mpTokenIssuanceID,
)
}

/**
* Compute the hash of an MPToken Issuance entry.
*
* @param sequence - Sequence number of the transaction that created this issuance.
* @param address - Account that created the MPToken issuance.
* @returns Hash of the MPToken Issuance entry.
* @category Utilities
*/
export function hashMPTokenIssuance(sequence: number, address: string): string {
return sha512Half(
ledgerSpaceHex('mpTokenIssuance') +
sequence.toString(HEX).padStart(BYTE_LENGTH * 2, '0') +
addressToHex(address),
)
}

/**
* Compute the hash of a NegativeUNL entry.
*
* @returns Hash of the NegativeUNL entry.
* @category Utilities
*/
export function hashNegativeUNL(): string {
return sha512Half(ledgerSpaceHex('negativeUNL'))
}

export { hashLedgerHeader, hashSignedTx, hashLedger, hashStateTree, hashTxTree }
15 changes: 15 additions & 0 deletions packages/xrpl/src/utils/hashes/ledgerSpaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ const ledgerSpaces = {
paychan: 'x',
check: 'C',
depositPreauth: 'p',
// Additional ledger entry types
negativeUNL: 'N',
nfTokenPage: 'P',
nfTokenOffer: 't',
ammRoot: 'A',
oracle: 'R',
hook: 'H',
hookState: 'h',
hookDefinition: 'D',
did: 'I',
bridge: 'X',
xchainOwnedClaimID: 'K',
xchainOwnedCreateAccountClaimID: 'k',
mpToken: 'M',
mpTokenIssuance: 'm',
}

export default ledgerSpaces
Loading