Compare commits

..

11 Commits

Author SHA1 Message Date
Denis Angell
57f1168d8c Publish
- @transia/xrpl@2.7.3-alpha.5
2023-07-07 17:47:15 +02:00
Denis Angell
63b01812b6 Update ledgerEntry.ts 2023-07-07 17:46:49 +02:00
Denis Angell
cc67c6efd6 Publish
- @transia/xrpl@2.7.3-alpha.4
2023-07-07 17:44:59 +02:00
Denis Angell
454ab81bd7 bump package-lock 2023-07-07 17:43:32 +02:00
Denis Angell
4dd8ac243f fix missing uritoken ledger entry 2023-07-07 17:38:51 +02:00
Denis Angell
9cdbd6347b Publish
- @transia/xrpl@2.7.3-alpha.3
2023-06-26 14:29:34 -04:00
Denis Angell
abca119eae update max hooks test 2023-06-26 14:09:44 -04:00
Denis Angell
0a60836f68 dont check tx signature on emit details tx 2023-06-26 14:06:03 -04:00
Denis Angell
2bad85b626 add emit details to tx common 2023-06-26 14:02:47 -04:00
Denis Angell
117e682f47 update max hooks 2023-06-26 10:50:02 -04:00
Denis Angell
dc09dae851 add hashURIToken 2023-06-23 15:33:20 +00:00
15 changed files with 158 additions and 34 deletions

2
package-lock.json generated
View File

@@ -17188,7 +17188,7 @@
}, },
"packages/xrpl": { "packages/xrpl": {
"name": "@transia/xrpl", "name": "@transia/xrpl",
"version": "2.7.3-alpha.2", "version": "2.7.3-alpha.3",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@transia/ripple-address-codec": "^4.2.8-alpha.0", "@transia/ripple-address-codec": "^4.2.8-alpha.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@transia/xrpl", "name": "@transia/xrpl",
"version": "2.7.3-alpha.2", "version": "2.7.3-alpha.5",
"license": "ISC", "license": "ISC",
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser", "description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
"files": [ "files": [

View File

@@ -195,3 +195,13 @@ export interface NFTOffer {
destination?: string destination?: string
expiration?: number expiration?: number
} }
/**
* This information is added to emitted Transactions.
*/
export interface EmitDetails {
EmitBurden: number
EmitGeneration: number
EmitHookHash: string
EmitParentTxnID: string
}

View File

@@ -0,0 +1,53 @@
import { Amount } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The HookState object type contains the
*
* @category Ledger Entries
*/
export default interface HookState extends BaseLedgerEntry {
LedgerEntryType: 'URIToken'
/**
*/
Owner: string
/**
* A hint indicating which page of the sender's owner directory links to this
* object, in case the directory consists of multiple pages.
*/
OwnerNode: string
/**
*/
Issuer: string
/**
*/
URI: string
/**
*/
Digest: string
/**
*/
Amount: Amount
/**
*/
Destination: string
/**
* The identifying hash of the transaction that most recently modified this
* object.
*/
PreviousTxnID: string
/**
* The index of the ledger that contains the transaction that most recently
* modified this object.
*/
PreviousTxnLgrSeq: number
}

View File

@@ -21,6 +21,7 @@ import PayChannel from './PayChannel'
import RippleState, { RippleStateFlags } from './RippleState' import RippleState, { RippleStateFlags } from './RippleState'
import SignerList, { SignerListFlags } from './SignerList' import SignerList, { SignerListFlags } from './SignerList'
import Ticket from './Ticket' import Ticket from './Ticket'
import URIToken from './URIToken'
export { export {
AccountRoot, AccountRoot,
@@ -48,4 +49,5 @@ export {
SignerList, SignerList,
SignerListFlags, SignerListFlags,
Ticket, Ticket,
URIToken,
} }

View File

@@ -8,6 +8,7 @@ import {
RippleState, RippleState,
SignerList, SignerList,
Ticket, Ticket,
URIToken,
} from '../ledger' } from '../ledger'
import { BaseRequest, BaseResponse } from './baseMethod' import { BaseRequest, BaseResponse } from './baseMethod'
@@ -22,6 +23,7 @@ type AccountObjectType =
| 'signer_list' | 'signer_list'
| 'state' | 'state'
| 'ticket' | 'ticket'
| 'uritoken'
/** /**
* The account_objects command returns the raw ledger format for all objects * The account_objects command returns the raw ledger format for all objects
@@ -78,6 +80,7 @@ type AccountObject =
| SignerList | SignerList
| RippleState | RippleState
| Ticket | Ticket
| URIToken
/** /**
* Response expected from an {@link AccountObjectsRequest}. * Response expected from an {@link AccountObjectsRequest}.

View File

@@ -79,6 +79,11 @@ export interface LedgerEntryRequest extends BaseRequest {
} }
| string | string
/**
* The object ID of a transaction emitted by the ledger entry.
*/
emitted_txn?: string
/** /**
* The Escrow object to retrieve. If a string, must be the object ID of the * The Escrow object to retrieve. If a string, must be the object ID of the
* escrow, as hexadecimal. If an object, requires owner and seq sub-fields. * escrow, as hexadecimal. If an object, requires owner and seq sub-fields.
@@ -92,6 +97,36 @@ export interface LedgerEntryRequest extends BaseRequest {
} }
| string | string
/**
* The hash of the Hook object to retrieve.
*/
hook_definition?: string
/**
* The Hook object to retrieve. If a string, must be the object ID of the Hook.
* If an object, requires `account` sub-field.
*/
hook?:
| {
/** The account of the Hook object. */
account: string
}
| string
/**
* Object specifying the HookState object to retrieve. Requires the sub-fields
* `account`, `key`, and `namespace_id` to uniquely specify the HookState entry
* to retrieve.
*/
hook_state?: {
/** The account of the Hook object. */
account: string
/** The key of the state. */
key: string
/** The namespace of the state. */
namespace_id: string
}
/** /**
* The Offer object to retrieve. If a string, interpret as the unique object * The Offer object to retrieve. If a string, interpret as the unique object
* ID to the Offer. If an object, requires the sub-fields `account` and `seq` * ID to the Offer. If an object, requires the sub-fields `account` and `seq`
@@ -137,40 +172,20 @@ export interface LedgerEntryRequest extends BaseRequest {
ticket_sequence: number ticket_sequence: number
} }
| string | string
/**
* The object ID of a transaction emitted by the ledger entry.
*/
emitted_txn?: string
/** /**
* The hash of the Hook object to retrieve. * The URIToken object to retrieve. If a string, must be the object ID of the
* URIToken, as hexadecimal. If an object, the `issuer` and `uri`
* sub-fields are required to uniquely specify the URIToken entry.
*/ */
hook_definition?: string uri_token?:
/**
* The Hook object to retrieve. If a string, must be the object ID of the Hook.
* If an object, requires `account` sub-field.
*/
hook?:
| { | {
/** The account of the Hook object. */ /** The issuer of the URIToken object. */
account: string issuer: string
/** The URIToken uri string (ascii). */
uri: string
} }
| string | string
/**
* Object specifying the HookState object to retrieve. Requires the sub-fields
* `account`, `key`, and `namespace_id` to uniquely specify the HookState entry
* to retrieve.
*/
hook_state?: {
/** The account of the Hook object. */
account: string
/** The key of the state. */
key: string
/** The namespace of the state. */
namespace_id: string
}
} }
/** /**

View File

@@ -10,6 +10,7 @@ import {
IssuedCurrencyAmount, IssuedCurrencyAmount,
Memo, Memo,
Signer, Signer,
EmitDetails,
} from '../common' } from '../common'
import { onlyHasFields } from '../utils' import { onlyHasFields } from '../utils'
@@ -173,6 +174,10 @@ export interface BaseTransaction {
* The hook parameters of the transaction. * The hook parameters of the transaction.
*/ */
HookParameters?: HookParameter[] HookParameters?: HookParameter[]
/**
* The hook parameters of the transaction.
*/
EmitDetails?: EmitDetails
} }
/** /**

View File

@@ -41,7 +41,7 @@ export interface SetHook extends BaseTransaction {
Flags?: number | SetHookFlagsInterface Flags?: number | SetHookFlagsInterface
} }
const MAX_HOOKS = 4 const MAX_HOOKS = 10
const HEX_REGEX = /^[0-9A-Fa-f]{64}$/u const HEX_REGEX = /^[0-9A-Fa-f]{64}$/u
/** /**

View File

@@ -83,7 +83,7 @@ export function hashSignedTx(tx: Transaction | string): string {
txObject = tx txObject = tx
} }
if (txObject.TxnSignature === undefined && txObject.Signers === undefined) { if (!txObject.EmitDetails && txObject.TxnSignature === undefined && txObject.Signers === undefined) {
throw new ValidationError('The transaction must be signed to hash it.') throw new ValidationError('The transaction must be signed to hash it.')
} }

View File

@@ -6,6 +6,8 @@
import { decodeAccountID } from '@transia/ripple-address-codec' import { decodeAccountID } from '@transia/ripple-address-codec'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import { convertStringToHex } from '../stringConversion'
import hashLedger, { import hashLedger, {
hashLedgerHeader, hashLedgerHeader,
hashSignedTx, hashSignedTx,
@@ -184,4 +186,18 @@ export function hashPaymentChannel(
) )
} }
/**
* Compute the Hash of an URIToken LedgerEntry.
*
* @param issuer - Address of the issuer of the URIToken.
* @param uri - string uri of the URIToken (not the hex).
* @returns The hash of the URIToken LedgerEntry.
* @category Utilities
*/
export function hashURIToken(issuer: string, uri: string): string {
return sha512Half(
ledgerSpaceHex('uriToken') + addressToHex(issuer) + convertStringToHex(uri),
)
}
export { hashLedgerHeader, hashSignedTx, hashLedger, hashStateTree, hashTxTree } export { hashLedgerHeader, hashSignedTx, hashLedger, hashStateTree, hashTxTree }

View File

@@ -28,6 +28,7 @@ const ledgerSpaces = {
signerList: 'S', signerList: 'S',
paychan: 'x', paychan: 'x',
check: 'C', check: 'C',
uriToken: 'U',
depositPreauth: 'p', depositPreauth: 'p',
} }

View File

@@ -39,6 +39,7 @@ import {
hashLedgerHeader, hashLedgerHeader,
hashEscrow, hashEscrow,
hashPaymentChannel, hashPaymentChannel,
hashURIToken,
} from './hashes' } from './hashes'
import { calculateHookOn, hexHookParameters, TTS } from './hooks' import { calculateHookOn, hexHookParameters, TTS } from './hooks'
import parseNFTokenID from './parseNFTokenID' import parseNFTokenID from './parseNFTokenID'
@@ -173,6 +174,7 @@ const hashes = {
hashLedgerHeader, hashLedgerHeader,
hashEscrow, hashEscrow,
hashPaymentChannel, hashPaymentChannel,
hashURIToken,
} }
export { export {

View File

@@ -69,7 +69,7 @@ describe('SetHook', function () {
) )
}) })
it(`throws w/ maximum of 4 members allowed in Hooks`, function () { it(`throws w/ maximum of 10 members allowed in Hooks`, function () {
setHookTx.Hooks = [] setHookTx.Hooks = []
const hook = { const hook = {
Hook: { Hook: {
@@ -88,8 +88,14 @@ describe('SetHook', function () {
setHookTx.Hooks.push(hook) setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook) setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook) setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
const errorMessage = 'SetHook: maximum of 4 hooks allowed in Hooks' const errorMessage = 'SetHook: maximum of 10 hooks allowed in Hooks'
assert.throws( assert.throws(
() => validateSetHook(setHookTx), () => validateSetHook(setHookTx),
ValidationError, ValidationError,

View File

@@ -15,6 +15,7 @@ import {
hashAccountRoot, hashAccountRoot,
hashOfferId, hashOfferId,
hashSignerListId, hashSignerListId,
hashURIToken,
} from '../../src/utils/hashes' } from '../../src/utils/hashes'
import fixtures from '../fixtures/rippled' import fixtures from '../fixtures/rippled'
import { assertResultMatch } from '../testUtils' import { assertResultMatch } from '../testUtils'
@@ -143,6 +144,16 @@ describe('Hashes', function () {
assert.equal(actualEntryHash, expectedEntryHash) assert.equal(actualEntryHash, expectedEntryHash)
}) })
it('calcURITokenEntryHash', function () {
const issuer = 'rDx69ebzbowuqztksVDmZXjizTd12BVr4x'
const uri = 'ipfs://cid'
const expectedEntryHash =
'AFC4233E5C4094952DEF5483DC41488C8744D1268F897C0CB25DE66399591399'
const actualEntryHash = hashURIToken(issuer, uri)
assert.equal(actualEntryHash, expectedEntryHash)
})
it('Hash a signed transaction correctly', function () { it('Hash a signed transaction correctly', function () {
const expected_hash = const expected_hash =
'458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2' '458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2'