diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 27762509..0af5195f 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -47,3 +47,12 @@ export { SetHook } from './setHook' export { SignerListSet } from './signerListSet' export { TicketCreate } from './ticketCreate' export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet' +export { + URITokenMintFlagsInterface, + URITokenMintFlags, + URITokenMint, +} from './uriTokenMint' +export { URITokenBurn } from './uriTokenBurn' +export { URITokenCreateSellOffer } from './uriTokenCreateSellOffer' +export { URITokenBuy } from './uriTokenBuy' +export { URITokenCancelSellOffer } from './uriTokenCancelSellOffer' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index 9ec3beed..a9470392 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -48,6 +48,17 @@ import { SetRegularKey, validateSetRegularKey } from './setRegularKey' import { SignerListSet, validateSignerListSet } from './signerListSet' import { TicketCreate, validateTicketCreate } from './ticketCreate' import { TrustSet, validateTrustSet } from './trustSet' +import { URITokenBurn, validateURITokenBurn } from './uriTokenBurn' +import { URITokenBuy, validateURITokenBuy } from './uriTokenBuy' +import { + URITokenCancelSellOffer, + validateURITokenCancelSellOffer, +} from './uriTokenCancelSellOffer' +import { + URITokenCreateSellOffer, + validateURITokenCreateSellOffer, +} from './uriTokenCreateSellOffer' +import { URITokenMint, validateURITokenMint } from './uriTokenMint' /** * @category Transaction Models @@ -78,6 +89,11 @@ export type Transaction = | SignerListSet | TicketCreate | TrustSet + | URITokenBurn + | URITokenBuy + | URITokenCancelSellOffer + | URITokenMint + | URITokenCreateSellOffer /** * @category Transaction Models @@ -206,6 +222,26 @@ export function validate(transaction: Record): void { validateTrustSet(tx) break + case 'URITokenMint': + validateURITokenMint(tx) + break + + case 'URITokenBurn': + validateURITokenBurn(tx) + break + + case 'URITokenCreateSellOffer': + validateURITokenCreateSellOffer(tx) + break + + case 'URITokenBuy': + validateURITokenBuy(tx) + break + + case 'URITokenCancelSellOffer': + validateURITokenCancelSellOffer(tx) + break + default: throw new ValidationError( `Invalid field TransactionType: ${tx.TransactionType}`, diff --git a/packages/xrpl/src/models/transactions/uriTokenBurn.ts b/packages/xrpl/src/models/transactions/uriTokenBurn.ts new file mode 100644 index 00000000..dbf64b97 --- /dev/null +++ b/packages/xrpl/src/models/transactions/uriTokenBurn.ts @@ -0,0 +1,60 @@ +import { ValidationError } from '../../errors' + +import { BaseTransaction, validateBaseTransaction } from './common' + +/** + * Map of flags to boolean values representing {@link URITokenBurn} transaction + * flags. + * + * @category Transaction Flags + * + * @example + * ```typescript + * const tx: URITokenBurn = { + * Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * TransactionType: 'URITokenBurn', + * } + * + * // Autofill the tx to see how flags actually look compared to the interface usage. + * const autofilledTx = await client.autofill(tx) + * console.log(autofilledTx) + * // { + * // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * // TransactionType: 'URITokenBurn', + * // Sequence: 21970384, + * // Fee: '12', + * // LastLedgerSequence: 21970404 + * // } + * ``` + */ + +/** + * An URITokenBurn transaction is effectively a limit order . It defines an + * intent to exchange currencies, and creates an Offer object if not completely. + * Fulfilled when placed. Offers can be partially fulfilled. + * + * @category Transaction Models + */ +export interface URITokenBurn extends BaseTransaction { + TransactionType: 'URITokenBurn' + /** + * Identifies the URIToken object to be removed by the transaction. + */ + URITokenID: string +} + +/** + * Verify the form and type of an URITokenBurn at runtime. + * + * @param tx - An URITokenBurn Transaction. + * @throws When the URITokenBurn is Malformed. + */ +export function validateURITokenBurn(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.URITokenID == null) { + throw new ValidationError('NFTokenBurn: missing field URITokenID') + } +} diff --git a/packages/xrpl/src/models/transactions/uriTokenBuy.ts b/packages/xrpl/src/models/transactions/uriTokenBuy.ts new file mode 100644 index 00000000..e59be8b5 --- /dev/null +++ b/packages/xrpl/src/models/transactions/uriTokenBuy.ts @@ -0,0 +1,83 @@ +import { ValidationError } from '../../errors' +import { Amount } from '../common' + +import { BaseTransaction, isAmount, validateBaseTransaction } from './common' + +/** + * Map of flags to boolean values representing {@link URITokenBuy} transaction + * flags. + * + * @category Transaction Flags + * + * @example + * ```typescript + * const tx: URITokenBuy = { + * Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * Amount: '1000000', + * TransactionType: 'URITokenBuy', + * } + * + * // Autofill the tx to see how flags actually look compared to the interface usage. + * const autofilledTx = await client.autofill(tx) + * console.log(autofilledTx) + * // { + * // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * // Amount: '1000000', + * // TransactionType: 'URITokenBuy', + * // Sequence: 21970384, + * // Fee: '12', + * // LastLedgerSequence: 21970404 + * // } + * ``` + */ + +/** + * An URITokenBuy transaction is effectively a limit order . It defines an + * intent to exchange currencies, and creates an Offer object if not completely. + * Fulfilled when placed. Offers can be partially fulfilled. + * + * @category Transaction Models + */ +export interface URITokenBuy extends BaseTransaction { + TransactionType: 'URITokenBuy' + /** + * Identifies the URITokenID of the NFToken object that the + * offer references. + */ + URITokenID: string + /** + * Indicates the amount expected or offered for the Token. + * + * The amount must be non-zero, except when this is a sell + * offer and the asset is XRP. This would indicate that the current + * owner of the token is giving it away free, either to anyone at all, + * or to the account identified by the Destination field. + */ + Amount: Amount +} + +/** + * Verify the form and type of an URITokenBuy at runtime. + * + * @param tx - An URITokenBuy Transaction. + * @throws When the URITokenBuy is Malformed. + */ +export function validateURITokenBuy(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.Account === tx.Destination) { + throw new ValidationError( + 'URITokenBuy: Destination and Account must not be equal', + ) + } + + if (tx.URITokenID == null) { + throw new ValidationError('URITokenBuy: missing field URITokenID') + } + + if (!isAmount(tx.Amount)) { + throw new ValidationError('URITokenBuy: invalid Amount') + } +} diff --git a/packages/xrpl/src/models/transactions/uriTokenCancelSellOffer.ts b/packages/xrpl/src/models/transactions/uriTokenCancelSellOffer.ts new file mode 100644 index 00000000..d93bebc5 --- /dev/null +++ b/packages/xrpl/src/models/transactions/uriTokenCancelSellOffer.ts @@ -0,0 +1,65 @@ +import { ValidationError } from '../../errors' + +import { BaseTransaction, validateBaseTransaction } from './common' + +/** + * Map of flags to boolean values representing {@link URITokenCancelSellOffer} transaction + * flags. + * + * @category Transaction Flags + * + * @example + * ```typescript + * const tx: URITokenCancelSellOffer = { + * Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * TransactionType: 'URITokenCancelSellOffer', + * } + * + * // Autofill the tx to see how flags actually look compared to the interface usage. + * const autofilledTx = await client.autofill(tx) + * console.log(autofilledTx) + * // { + * // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * // TransactionType: 'URITokenCancelSellOffer', + * // Sequence: 21970384, + * // Fee: '12', + * // LastLedgerSequence: 21970404 + * // } + * ``` + */ + +/** + * An URITokenCancelSellOffer transaction is effectively a limit order . It defines an + * intent to exchange currencies, and creates an Offer object if not completely. + * Fulfilled when placed. Offers can be partially fulfilled. + * + * @category Transaction Models + */ +export interface URITokenCancelSellOffer extends BaseTransaction { + TransactionType: 'URITokenCancelSellOffer' + /** + * Identifies the URITokenID of the NFToken object that the + * offer references. + */ + URITokenID: string +} + +/** + * Verify the form and type of an URITokenCancelSellOffer at runtime. + * + * @param tx - An URITokenCancelSellOffer Transaction. + * @throws When the URITokenCancelSellOffer is Malformed. + */ +export function validateURITokenCancelSellOffer( + tx: Record, +): void { + validateBaseTransaction(tx) + + if (tx.URITokenID == null) { + throw new ValidationError( + 'URITokenCancelSellOffer: missing field URITokenID', + ) + } +} diff --git a/packages/xrpl/src/models/transactions/uriTokenCreateSellOffer.ts b/packages/xrpl/src/models/transactions/uriTokenCreateSellOffer.ts new file mode 100644 index 00000000..fff32164 --- /dev/null +++ b/packages/xrpl/src/models/transactions/uriTokenCreateSellOffer.ts @@ -0,0 +1,93 @@ +import { ValidationError } from '../../errors' +import { Amount } from '../common' + +import { BaseTransaction, isAmount, validateBaseTransaction } from './common' + +/** + * Map of flags to boolean values representing {@link URITokenCreateSellOffer} transaction + * flags. + * + * @category Transaction Flags + * + * @example + * ```typescript + * const tx: URITokenCreateSellOffer = { + * Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * Amount: '1000000', + * TransactionType: 'URITokenCreateSellOffer', + * } + * + * // Autofill the tx to see how flags actually look compared to the interface usage. + * const autofilledTx = await client.autofill(tx) + * console.log(autofilledTx) + * // { + * // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB', + * // Amount: '1000000', + * // TransactionType: 'URITokenCreateSellOffer', + * // Sequence: 21970384, + * // Fee: '12', + * // LastLedgerSequence: 21970404 + * // } + * ``` + */ + +/** + * An URITokenCreateSellOffer transaction is effectively a limit order . It defines an + * intent to exchange currencies, and creates an Offer object if not completely. + * Fulfilled when placed. Offers can be partially fulfilled. + * + * @category Transaction Models + */ +export interface URITokenCreateSellOffer extends BaseTransaction { + TransactionType: 'URITokenCreateSellOffer' + /** + * Identifies the URITokenID of the NFToken object that the + * offer references. + */ + URITokenID: string + /** + * Indicates the amount expected or offered for the Token. + * + * The amount must be non-zero, except when this is a sell + * offer and the asset is XRP. This would indicate that the current + * owner of the token is giving it away free, either to anyone at all, + * or to the account identified by the Destination field. + */ + Amount: Amount + /** + * If present, indicates that this offer may only be + * accepted by the specified account. Attempts by other + * accounts to accept this offer MUST fail. + */ + Destination?: string +} + +/** + * Verify the form and type of an URITokenCreateSellOffer at runtime. + * + * @param tx - An URITokenCreateSellOffer Transaction. + * @throws When the URITokenCreateSellOffer is Malformed. + */ +export function validateURITokenCreateSellOffer( + tx: Record, +): void { + validateBaseTransaction(tx) + + if (tx.Account === tx.Destination) { + throw new ValidationError( + 'URITokenCreateSellOffer: Destination and Account must not be equal', + ) + } + + if (tx.URITokenID == null) { + throw new ValidationError( + 'URITokenCreateSellOffer: missing field URITokenID', + ) + } + + if (!isAmount(tx.Amount)) { + throw new ValidationError('URITokenCreateSellOffer: invalid Amount') + } +} diff --git a/packages/xrpl/src/models/transactions/uriTokenMint.ts b/packages/xrpl/src/models/transactions/uriTokenMint.ts new file mode 100644 index 00000000..4ac5bf58 --- /dev/null +++ b/packages/xrpl/src/models/transactions/uriTokenMint.ts @@ -0,0 +1,92 @@ +import { ValidationError } from '../../errors' +import { isHex } from '../utils' + +import { BaseTransaction, GlobalFlags, validateBaseTransaction } from './common' + +/** + * Transaction Flags for an URITokenMint Transaction. + * + * @category Transaction Flags + */ +export enum URITokenMintFlags { + /** + * If set, indicates that the minted token may be burned by the issuer even + * if the issuer does not currently hold the token. The current holder of + * the token may always burn it. + */ + tfBurnable = 0x00000001, +} + +/** + * Map of flags to boolean values representing {@link URITokenMint} transaction + * flags. + * + * @category Transaction Flags + * + * @example + * ```typescript + * const tx: URITokenMint = { + * Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * URI: '697066733A2F2F434944', + * TransactionType: 'URITokenMint', + * Flags: { + * tfBurnable: true, + * }, + * } + * + * // Autofill the tx to see how flags actually look compared to the interface usage. + * const autofilledTx = await client.autofill(tx) + * console.log(autofilledTx) + * // { + * // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd', + * // URI: '697066733A2F2F434944', + * // TransactionType: 'URITokenMint', + * // Flags: 0, + * // Sequence: 21970384, + * // Fee: '12', + * // LastLedgerSequence: 21970404 + * // } + * ``` + */ +export interface URITokenMintFlagsInterface extends GlobalFlags { + tfBurnable?: boolean +} + +/** + * An URITokenMint transaction is effectively a limit order . It defines an + * intent to exchange currencies, and creates an Offer object if not completely. + * Fulfilled when placed. Offers can be partially fulfilled. + * + * @category Transaction Models + */ +export interface URITokenMint extends BaseTransaction { + TransactionType: 'URITokenMint' + Flags?: number | URITokenMintFlagsInterface + /** + * URI that points to the data and/or metadata associated with the NFT. + * This field need not be an HTTP or HTTPS URL; it could be an IPFS URI, a + * magnet link, immediate data encoded as an RFC2379 "data" URL, or even an + * opaque issuer-specific encoding. The URI is NOT checked for validity, but + * the field is limited to a maximum length of 256 bytes. + * + * This field must be hex-encoded. You can use `convertStringToHex` to + * convert this field to the proper encoding. + */ + URI: string + + Digest?: string +} + +/** + * Verify the form and type of an URITokenMint at runtime. + * + * @param tx - An URITokenMint Transaction. + * @throws When the URITokenMint is Malformed. + */ +export function validateURITokenMint(tx: Record): void { + validateBaseTransaction(tx) + + if (typeof tx.URI === 'string' && !isHex(tx.URI)) { + throw new ValidationError('URITokenMint: URI must be in hex format') + } +}