Skip to main content

xrpl_wasm_stdlib/core/
keylets.rs

1use crate::core::types::account_id::AccountID;
2use crate::core::types::currency::Currency;
3use crate::core::types::issue::Issue;
4use crate::core::types::mpt_id::MptId;
5use crate::host;
6use crate::host::Result;
7use crate::host::error_codes::match_result_code_with_expected_bytes;
8
9pub const XRPL_KEYLET_SIZE: usize = 32;
10// Type aliases for specific keylets, all currently using the same underlying array type.
11pub type KeyletBytes = [u8; XRPL_KEYLET_SIZE];
12
13/// Generates an account keylet for a given XRP Ledger account.
14///
15/// Account keylets are used to reference account entries in the XRP Ledger's state data.
16/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
17///
18/// # Arguments
19///
20/// * `account_id` - Reference to an `AccountID` representing the XRP Ledger account
21///
22/// # Returns
23///
24/// * `Result<KeyletBytes>` - On success, returns a 32-byte account keylet.
25///   On failure, returns an `Error` with the corresponding error code.
26///
27/// # Safety
28///
29/// This function makes unsafe FFI calls to the host environment through
30/// the `host::account_keylet` function, though the unsafe code is contained
31/// within the closure passed to `create_keylet_from_host_call`.
32///
33/// # Example
34///
35/// ```rust
36///
37/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
38/// use xrpl_wasm_stdlib::core::keylets::account_keylet;
39/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
40/// fn main() -> Result<(), Box<dyn std::error::Error>> {
41///   let account:AccountID = AccountID::from(
42///     *b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3"
43///   );
44///   match account_keylet(&account){
45///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
46///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
47///     }
48///     xrpl_wasm_stdlib::host::Result::Err(e) => {
49///       let _ = trace_num("Error assembling keylet", e.code() as i64);
50///     }
51///   }
52///   Ok(())
53/// }
54/// ```
55pub fn account_keylet(account_id: &AccountID) -> Result<KeyletBytes> {
56    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
57        host::account_keylet(
58            account_id.0.as_ptr(), // Assuming AccountID is a tuple struct like AccountID(bytes)
59            account_id.0.len(),
60            keylet_buffer_ptr,
61            keylet_buffer_len,
62        )
63    })
64}
65
66/// Generates an AMM keylet for a given pair of accounts and currency code.
67///
68/// An AMM keylet is used to reference AMM entries in the XRP Ledger.
69///
70/// # Arguments
71///
72/// * `issue1` - The first Issue in the AMM relationship
73/// * `issue2` - The second Issue in the AMM relationship
74///
75/// # Returns
76///
77/// * `Result<KeyletBytes>` - On success, returns a 32-byte AMM keylet.
78///   On failure, returns an `Error` with the corresponding error code.
79///
80/// # Safety
81///
82/// This function makes unsafe FFI calls to the host environment through
83/// the `host::amm_keylet` function.
84///
85/// # Example
86///
87/// ```rust
88/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
89/// use xrpl_wasm_stdlib::core::types::issue::{Issue, XrpIssue, IouIssue};
90/// use xrpl_wasm_stdlib::core::types::currency::Currency;
91/// use xrpl_wasm_stdlib::core::keylets::amm_keylet;
92/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
93/// fn main() -> Result<(), Box<dyn std::error::Error>> {
94///  let issue1: Issue = Issue::XRP(XrpIssue {});
95///  let issuer: AccountID =
96///    AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
97///  let currency = b"RLUSD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; // RLUSD currency code
98///  let currency: Currency = Currency::from(*currency);
99///  let issue2 = Issue::IOU(IouIssue::new(issuer, currency));
100///  match amm_keylet(&issue1, &issue2) {
101///    xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
102///      let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
103///    }
104///    xrpl_wasm_stdlib::host::Result::Err(e) => {
105///      let _ = trace_num("Error assembling keylet", e.code() as i64);
106///    }
107///  }
108///  Ok(())
109/// }
110/// ```
111pub fn amm_keylet(issue1: &Issue, issue2: &Issue) -> Result<KeyletBytes> {
112    let issue1_bytes = issue1.as_bytes();
113    let issue2_bytes = issue2.as_bytes();
114    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
115        host::amm_keylet(
116            issue1_bytes.as_ptr(),
117            issue1_bytes.len(),
118            issue2_bytes.as_ptr(),
119            issue2_bytes.len(),
120            keylet_buffer_ptr,
121            keylet_buffer_len,
122        )
123    })
124}
125
126/// Generates an check keylet for a given owner and sequence in the XRP Ledger.
127///
128/// Check keylets are used to reference check entries in the XRP Ledger's state data.
129/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
130///
131/// # Arguments
132///
133/// * `owner` - Reference to an `AccountID` representing the check owner's account
134/// * `seq` - The account sequence associated with the check entry
135///
136/// # Returns
137///
138/// * `Result<KeyletBytes>` - On success, returns a 32-byte check keylet.
139///   On failure, returns an `Error` with the corresponding error code.
140///
141/// # Safety
142///
143/// This function makes unsafe FFI calls to the host environment through
144/// the `host::check_keylet` function, though the unsafe code is contained
145/// within the closure passed to `create_keylet_from_host_call`.
146///
147/// # Example
148///
149/// ```rust
150/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
151/// use xrpl_wasm_stdlib::core::keylets::check_keylet;
152/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
153///
154/// fn main() -> Result<(), Box<dyn std::error::Error>> {
155///   let owner: AccountID =
156///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
157///   let sequence = 12345;
158///   match check_keylet(&owner, sequence) {
159///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
160///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
161///     }
162///     xrpl_wasm_stdlib::host::Result::Err(e) => {
163///       let _ = trace_num("Error assembling keylet", e.code() as i64);
164///     }
165///   }
166///   Ok(())
167///}
168/// ```
169pub fn check_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
170    let seq_bytes = seq.to_le_bytes();
171    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
172        host::check_keylet(
173            owner.0.as_ptr(),
174            owner.0.len(),
175            seq_bytes.as_ptr(),
176            seq_bytes.len(),
177            keylet_buffer_ptr,
178            keylet_buffer_len,
179        )
180    })
181}
182
183/// Generates a credential keylet for a given subject, issuer, and credential type.
184///
185/// A credential keylet is used to reference credential entries in the XRP Ledger.
186///
187/// # Arguments
188///
189/// * `subject` - The AccountID of the subject for whom the credential is issued
190/// * `issuer` - The AccountID of the entity issuing the credential
191/// * `credential_type` - A byte slice representing the type of credential
192///
193/// # Returns
194///
195/// * `Result<KeyletBytes>` - On success, returns a 32-byte credential keylet.
196///   On failure, returns an `Error` with the corresponding error code.
197///
198/// # Safety
199///
200/// This function makes unsafe FFI calls to the host environment through
201/// the `host::credential_keylet` function.
202///
203/// # Example
204///
205/// ```rust
206/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
207/// use xrpl_wasm_stdlib::core::keylets::credential_keylet;
208/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
209/// fn main() -> Result<(), Box<dyn std::error::Error>> {
210///     let subject: AccountID =
211///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
212///     let issuer: AccountID =
213///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
214///     let cred_type: &[u8] = b"termsandconditions";
215///     match credential_keylet(&subject, &issuer, cred_type) {
216///       xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
217///         let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
218///       }
219///       xrpl_wasm_stdlib::host::Result::Err(e) => {
220///         let _ = trace_num("Error assembling keylet", e.code() as i64);
221///       }
222///     }
223///     Ok(())
224/// }
225/// ```
226pub fn credential_keylet(
227    subject: &AccountID,
228    issuer: &AccountID,
229    credential_type: &[u8],
230) -> Result<KeyletBytes> {
231    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
232        host::credential_keylet(
233            subject.0.as_ptr(),
234            subject.0.len(),
235            issuer.0.as_ptr(),
236            issuer.0.len(),
237            credential_type.as_ptr(),
238            credential_type.len(),
239            keylet_buffer_ptr,
240            keylet_buffer_len,
241        )
242    })
243}
244
245/// Generates a delegate keylet for a given given account and authorized account.
246///
247/// A delegate keylet is used to reference delegate entries in the XRP Ledger.
248///
249/// # Arguments
250///
251/// * `account` - The AccountID of the account that is delegating permissions
252/// * `authorize` - The AccountID of the account that is delegated to
253///
254/// # Returns
255///
256/// * `Result<KeyletBytes>` - On success, returns a 32-byte delegate keylet.
257///   On failure, returns an `Error` with the corresponding error code.
258///
259/// # Safety
260///
261/// This function makes unsafe FFI calls to the host environment through
262/// the `host::delegate_keylet` function.
263///
264/// # Example
265///
266/// ```rust
267/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
268/// use xrpl_wasm_stdlib::core::keylets::delegate_keylet;
269/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
270/// fn main() -> Result<(), Box<dyn std::error::Error>> {
271///     let account: AccountID =
272///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
273///     let authorize: AccountID =
274///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
275///     match delegate_keylet(&account, &authorize) {
276///       xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
277///         let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
278///       }
279///       xrpl_wasm_stdlib::host::Result::Err(e) => {
280///         let _ = trace_num("Error assembling keylet", e.code() as i64);
281///       }
282///     }
283///     Ok(())
284/// }
285/// ```
286pub fn delegate_keylet(account: &AccountID, authorize: &AccountID) -> Result<KeyletBytes> {
287    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
288        host::delegate_keylet(
289            account.0.as_ptr(),
290            account.0.len(),
291            authorize.0.as_ptr(),
292            authorize.0.len(),
293            keylet_buffer_ptr,
294            keylet_buffer_len,
295        )
296    })
297}
298
299/// Generates a deposit preauth keylet for a given account and authorized account.
300///
301/// A deposit preauth keylet is used to reference deposit preauth entries in the XRP Ledger.
302///
303/// # Arguments
304///
305/// * `account` - The AccountID of the account that is doing the pre-authorizing
306/// * `authorize` - The AccountID of the account that is pre-authorizing
307///
308/// # Returns
309///
310/// * `Result<KeyletBytes>` - On success, returns a 32-byte deposit preauth keylet.
311///   On failure, returns an `Error` with the corresponding error code.
312///
313/// # Safety
314///
315/// This function makes unsafe FFI calls to the host environment through
316/// the `host::deposit_preauth_keylet` function.
317///
318/// # Example
319///
320/// ```rust
321/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
322/// use xrpl_wasm_stdlib::core::keylets::deposit_preauth_keylet;
323/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
324/// fn main() -> Result<(), Box<dyn std::error::Error>> {
325///     let account: AccountID =
326///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
327///     let authorize: AccountID =
328///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
329///     match deposit_preauth_keylet(&account, &authorize) {
330///       xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
331///         let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
332///       }
333///       xrpl_wasm_stdlib::host::Result::Err(e) => {
334///         let _ = trace_num("Error assembling keylet", e.code() as i64);
335///       }
336///     }
337///     Ok(())
338/// }
339/// ```
340pub fn deposit_preauth_keylet(account: &AccountID, authorize: &AccountID) -> Result<KeyletBytes> {
341    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
342        host::deposit_preauth_keylet(
343            account.0.as_ptr(),
344            account.0.len(),
345            authorize.0.as_ptr(),
346            authorize.0.len(),
347            keylet_buffer_ptr,
348            keylet_buffer_len,
349        )
350    })
351}
352
353/// Generates a DID keylet for a given XRP Ledger account.
354///
355/// DID keylets are used to reference DID entries in the XRP Ledger's state data.
356/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
357///
358/// # Arguments
359///
360/// * `account_id` - Reference to an `AccountID` representing the XRP Ledger account
361///
362/// # Returns
363///
364/// * `Result<KeyletBytes>` - On success, returns a 32-byte DID keylet.
365///   On failure, returns an `Error` with the corresponding error code.
366///
367/// # Safety
368///
369/// This function makes unsafe FFI calls to the host environment through
370/// the `host::did_keylet` function, though the unsafe code is contained
371/// within the closure passed to `create_keylet_from_host_call`.
372///
373/// # Example
374///
375/// ```rust
376///
377/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
378/// use xrpl_wasm_stdlib::core::keylets::did_keylet;
379/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
380/// fn main() -> Result<(), Box<dyn std::error::Error>> {
381///   let account:AccountID = AccountID::from(
382///     *b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3"
383///   );
384///   match did_keylet(&account){
385///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
386///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
387///     }
388///     xrpl_wasm_stdlib::host::Result::Err(e) => {
389///       let _ = trace_num("Error assembling keylet", e.code() as i64);
390///     }
391///   }
392///   Ok(())
393/// }
394/// ```
395pub fn did_keylet(account_id: &AccountID) -> Result<KeyletBytes> {
396    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
397        host::did_keylet(
398            account_id.0.as_ptr(),
399            account_id.0.len(),
400            keylet_buffer_ptr,
401            keylet_buffer_len,
402        )
403    })
404}
405
406/// Generates an escrow keylet for a given owner and sequence in the XRP Ledger.
407///
408/// Escrow keylets are used to reference escrow entries in the XRP Ledger's state data.
409/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
410///
411/// # Arguments
412///
413/// * `owner` - Reference to an `AccountID` representing the escrow owner's account
414/// * `seq` - The account sequence associated with the escrow entry
415///
416/// # Returns
417///
418/// * `Result<KeyletBytes>` - On success, returns a 32-byte escrow keylet.
419///   On failure, returns an `Error` with the corresponding error code.
420///
421/// # Safety
422///
423/// This function makes unsafe FFI calls to the host environment through
424/// the `host::escrow_keylet` function, though the unsafe code is contained
425/// within the closure passed to `create_keylet_from_host_call`.
426///
427/// # Example
428///
429/// ```rust
430/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
431/// use xrpl_wasm_stdlib::core::keylets::escrow_keylet;
432/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
433///
434/// fn main() -> Result<(), Box<dyn std::error::Error>> {
435///   let owner: AccountID =
436///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
437///   let sequence = 12345;
438///   match escrow_keylet(&owner, sequence) {
439///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
440///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
441///     }
442///     xrpl_wasm_stdlib::host::Result::Err(e) => {
443///       let _ = trace_num("Error assembling keylet", e.code() as i64);
444///     }
445///   }
446///   Ok(())
447///}
448/// ```
449pub fn escrow_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
450    let seq_bytes = seq.to_le_bytes();
451    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
452        host::escrow_keylet(
453            owner.0.as_ptr(),
454            owner.0.len(),
455            seq_bytes.as_ptr(),
456            seq_bytes.len(),
457            keylet_buffer_ptr,
458            keylet_buffer_len,
459        )
460    })
461}
462
463/// Generates a trustline keylet for a given pair of accounts and currency code.
464///
465/// A trustline keylet is used to reference trustline entries in the XRP Ledger.
466///
467/// # Arguments
468///
469/// * `account` - The first AccountID in the trustline relationship
470/// * `account2` - The second AccountID in the trustline relationship
471/// * `currency` - The Currency for the trustline
472///
473/// # Returns
474///
475/// * `Result<KeyletBytes>` - On success, returns a 32-byte trustline keylet.
476///   On failure, returns an `Error` with the corresponding error code.
477///
478/// # Safety
479///
480/// This function makes unsafe FFI calls to the host environment through
481/// the `host::line_keylet` function.
482///
483/// # Example
484///
485/// ```rust
486/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
487/// use xrpl_wasm_stdlib::core::types::currency::Currency;
488/// use xrpl_wasm_stdlib::core::keylets::line_keylet;
489/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
490/// fn main() -> Result<(), Box<dyn std::error::Error>> {
491///  let account1: AccountID =
492///    AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
493///  let account2: AccountID =
494///    AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
495///  let currency = b"RLUSD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; // RLUSD currency code
496///  let currency: Currency = Currency::from(*currency);
497///  match line_keylet(&account1, &account2, &currency) {
498///    xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
499///      let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
500///    }
501///    xrpl_wasm_stdlib::host::Result::Err(e) => {
502///      let _ = trace_num("Error assembling keylet", e.code() as i64);
503///    }
504///  }
505///  Ok(())
506/// }
507/// ```
508pub fn line_keylet(
509    account1: &AccountID,
510    account2: &AccountID,
511    currency: &Currency,
512) -> Result<KeyletBytes> {
513    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
514        host::line_keylet(
515            account1.0.as_ptr(),
516            account1.0.len(),
517            account2.0.as_ptr(),
518            account2.0.len(),
519            currency.0.as_ptr(),
520            currency.0.len(),
521            keylet_buffer_ptr,
522            keylet_buffer_len,
523        )
524    })
525}
526
527/// Generates an MPT issuance keylet for a given owner and sequence in the XRP Ledger.
528///
529/// MPT issuance keylets are used to reference MPT issuance entries in the XRP Ledger's state data.
530/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
531///
532/// # Arguments
533///
534/// * `owner` - Reference to an `AccountID` representing the MPT issuer's account
535/// * `seq` - The account sequence associated with the MPT issuance entry
536///
537/// # Returns
538///
539/// * `Result<KeyletBytes>` - On success, returns a 32-byte MPT issuance keylet.
540///   On failure, returns an `Error` with the corresponding error code.
541///
542/// # Safety
543///
544/// This function makes unsafe FFI calls to the host environment through
545/// the `host::mpt_issuance_keylet` function, though the unsafe code is contained
546/// within the closure passed to `create_keylet_from_host_call`.
547///
548/// # Example
549///
550/// ```rust
551/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
552/// use xrpl_wasm_stdlib::core::keylets::mpt_issuance_keylet;
553/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
554///
555/// fn main() -> Result<(), Box<dyn std::error::Error>> {
556///   let owner: AccountID =
557///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
558///   let sequence = 12345;
559///   match mpt_issuance_keylet(&owner, sequence) {
560///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
561///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
562///     }
563///     xrpl_wasm_stdlib::host::Result::Err(e) => {
564///       let _ = trace_num("Error assembling keylet", e.code() as i64);
565///     }
566///   }
567///   Ok(())
568///}
569/// ```
570pub fn mpt_issuance_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
571    let seq_bytes = seq.to_le_bytes();
572    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
573        host::mpt_issuance_keylet(
574            owner.0.as_ptr(),
575            owner.0.len(),
576            seq_bytes.as_ptr(),
577            seq_bytes.len(),
578            keylet_buffer_ptr,
579            keylet_buffer_len,
580        )
581    })
582}
583
584/// Generates an MPToken keylet for a given MPT ID and holder.
585///
586/// An MPToken keylet is used to reference MPToken entries in the XRP Ledger.
587///
588/// # Arguments
589///
590/// * `mptid` - The MPT ID that the MPToken is associated with
591/// * `holder` - The AccountID of the account that holds the MPToken
592///
593/// # Returns
594///
595/// * `Result<KeyletBytes>` - On success, returns a 32-byte MPToken keylet.
596///   On failure, returns an `Error` with the corresponding error code.
597///
598/// # Safety
599///
600/// This function makes unsafe FFI calls to the host environment through
601/// the `host::mptoken_keylet` function.
602///
603/// # Example
604///
605/// ```rust
606/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
607/// use xrpl_wasm_stdlib::core::types::mpt_id::MptId;
608/// use xrpl_wasm_stdlib::core::keylets::mptoken_keylet;
609/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
610/// fn main() -> Result<(), Box<dyn std::error::Error>> {
611///     let issuer: AccountID =
612///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
613///     let mptid: MptId = MptId::new(1, issuer);
614///     let holder: AccountID =
615///         AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
616///     match mptoken_keylet(&mptid, &holder) {
617///       xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
618///         let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
619///       }
620///       xrpl_wasm_stdlib::host::Result::Err(e) => {
621///         let _ = trace_num("Error assembling keylet", e.code() as i64);
622///       }
623///     }
624///     Ok(())
625/// }
626/// ```
627pub fn mptoken_keylet(mptid: &MptId, holder: &AccountID) -> Result<KeyletBytes> {
628    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
629        host::mptoken_keylet(
630            mptid.as_bytes().as_ptr(),
631            mptid.as_bytes().len(),
632            holder.0.as_ptr(),
633            holder.0.len(),
634            keylet_buffer_ptr,
635            keylet_buffer_len,
636        )
637    })
638}
639
640/// Generates an NFT offer keylet for a given owner and sequence in the XRP Ledger.
641///
642/// NFT offer keylets are used to reference NFT offer entries in the XRP Ledger's state data.
643/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
644///
645/// # Arguments
646///
647/// * `owner` - Reference to an `AccountID` representing the NFT offer owner's account
648/// * `seq` - The account sequence associated with the NFT offer entry
649///
650/// # Returns
651///
652/// * `Result<KeyletBytes>` - On success, returns a 32-byte NFT offer keylet.
653///   On failure, returns an `Error` with the corresponding error code.
654///
655/// # Safety
656///
657/// This function makes unsafe FFI calls to the host environment through
658/// the `host::nft_offer_keylet` function, though the unsafe code is contained
659/// within the closure passed to `create_keylet_from_host_call`.
660///
661/// # Example
662///
663/// ```rust
664/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
665/// use xrpl_wasm_stdlib::core::keylets::nft_offer_keylet;
666/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
667///
668/// fn main() -> Result<(), Box<dyn std::error::Error>> {
669///   let owner: AccountID =
670///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
671///   let sequence = 12345;
672///   match nft_offer_keylet(&owner, sequence) {
673///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
674///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
675///     }
676///     xrpl_wasm_stdlib::host::Result::Err(e) => {
677///       let _ = trace_num("Error assembling keylet", e.code() as i64);
678///     }
679///   }
680///   Ok(())
681///}
682/// ```
683pub fn nft_offer_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
684    let seq_bytes = seq.to_le_bytes();
685    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
686        host::nft_offer_keylet(
687            owner.0.as_ptr(),
688            owner.0.len(),
689            seq_bytes.as_ptr(),
690            seq_bytes.len(),
691            keylet_buffer_ptr,
692            keylet_buffer_len,
693        )
694    })
695}
696
697/// Generates an offer keylet for a given owner and sequence in the XRP Ledger.
698///
699/// Offer keylets are used to reference offer entries in the XRP Ledger's state data.
700/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
701///
702/// # Arguments
703///
704/// * `owner` - Reference to an `AccountID` representing the offer owner's account
705/// * `seq` - The account sequence associated with the offer entry
706///
707/// # Returns
708///
709/// * `Result<KeyletBytes>` - On success, returns a 32-byte offer keylet.
710///   On failure, returns an `Error` with the corresponding error code.
711///
712/// # Safety
713///
714/// This function makes unsafe FFI calls to the host environment through
715/// the `host::offer_keylet` function, though the unsafe code is contained
716/// within the closure passed to `create_keylet_from_host_call`.
717///
718/// # Example
719///
720/// ```rust
721/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
722/// use xrpl_wasm_stdlib::core::keylets::offer_keylet;
723/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
724///
725/// fn main() -> Result<(), Box<dyn std::error::Error>> {
726///   let owner: AccountID =
727///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
728///   let sequence = 12345;
729///   match offer_keylet(&owner, sequence) {
730///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
731///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
732///     }
733///     xrpl_wasm_stdlib::host::Result::Err(e) => {
734///       let _ = trace_num("Error assembling keylet", e.code() as i64);
735///     }
736///   }
737///   Ok(())
738///}
739/// ```
740pub fn offer_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
741    let seq_bytes = seq.to_le_bytes();
742    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
743        host::offer_keylet(
744            owner.0.as_ptr(),
745            owner.0.len(),
746            seq_bytes.as_ptr(),
747            seq_bytes.len(),
748            keylet_buffer_ptr,
749            keylet_buffer_len,
750        )
751    })
752}
753
754/// Generates an oracle keylet for a given owner and document ID in the XRP Ledger.
755///
756/// Oracle keylets are used to reference oracle entries in the XRP Ledger's state data.
757/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
758///
759/// # Arguments
760///
761/// * `owner` - Reference to an `AccountID` representing the oracle owner's account
762/// * `document_id` - An integer identifier for the oracle document
763///
764/// # Returns
765///
766/// * `Result<KeyletBytes>` - On success, returns a 32-byte oracle keylet.
767///   On failure, returns an `Error` with the corresponding error code.
768///
769/// # Safety
770///
771/// This function makes unsafe FFI calls to the host environment through
772/// the `host::oracle_keylet` function, though the unsafe code is contained
773/// within the closure passed to `create_keylet_from_host_call`.
774///
775/// # Example
776///
777/// ```rust
778/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
779/// use xrpl_wasm_stdlib::core::keylets::oracle_keylet;
780/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
781///
782/// fn main() -> Result<(), Box<dyn std::error::Error>> {
783///   let owner: AccountID =
784///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
785///   let document_id = 12345;
786///   match oracle_keylet(&owner, document_id) {
787///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
788///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
789///     }
790///     xrpl_wasm_stdlib::host::Result::Err(e) => {
791///       let _ = trace_num("Error assembling keylet", e.code() as i64);
792///     }
793///   }
794///   Ok(())
795///}
796/// ```
797pub fn oracle_keylet(owner: &AccountID, document_id: u32) -> Result<KeyletBytes> {
798    let document_id_bytes = document_id.to_le_bytes();
799    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
800        host::oracle_keylet(
801            owner.0.as_ptr(),
802            owner.0.len(),
803            document_id_bytes.as_ptr(),
804            document_id_bytes.len(),
805            keylet_buffer_ptr,
806            keylet_buffer_len,
807        )
808    })
809}
810
811/// Generates a payment channel keylet for a given owner and sequence in the XRP Ledger.
812///
813/// Payment channel keylets are used to reference payment channel entries in the XRP Ledger's state data.
814/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
815///
816/// # Arguments
817///
818/// * `account` - Reference to an `AccountID` representing the payment channel sender's account
819/// * `destination` - Reference to an `AccountID` representing the payment channel's destination
820/// * `seq` - The account sequence associated with the payment channel entry
821///
822/// # Returns
823///
824/// * `Result<KeyletBytes>` - On success, returns a 32-byte payment channel keylet.
825///   On failure, returns an `Error` with the corresponding error code.
826///
827/// # Safety
828///
829/// This function makes unsafe FFI calls to the host environment through
830/// the `host::paychan_keylet` function, though the unsafe code is contained
831/// within the closure passed to `create_keylet_from_host_call`.
832///
833/// # Example
834///
835/// ```rust
836/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
837/// use xrpl_wasm_stdlib::core::keylets::paychan_keylet;
838/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
839///
840/// fn main() -> Result<(), Box<dyn std::error::Error>> {
841///   let account: AccountID =
842///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
843///   let destination: AccountID =
844///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
845///   let sequence = 12345;
846///   match paychan_keylet(&account, &destination, sequence) {
847///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
848///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
849///     }
850///     xrpl_wasm_stdlib::host::Result::Err(e) => {
851///       let _ = trace_num("Error assembling keylet", e.code() as i64);
852///     }
853///   }
854///   Ok(())
855///}
856/// ```
857pub fn paychan_keylet(
858    account: &AccountID,
859    destination: &AccountID,
860    seq: u32,
861) -> Result<KeyletBytes> {
862    let seq_bytes = seq.to_le_bytes();
863    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
864        host::paychan_keylet(
865            account.0.as_ptr(),
866            account.0.len(),
867            destination.0.as_ptr(),
868            destination.0.len(),
869            seq_bytes.as_ptr(),
870            seq_bytes.len(),
871            keylet_buffer_ptr,
872            keylet_buffer_len,
873        )
874    })
875}
876
877/// Generates a permissioned domain keylet for a given owner and sequence in the XRP Ledger.
878///
879/// Permissioned domain keylets are used to reference permissioned domain entries in the XRP Ledger's state data.
880/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
881///
882/// # Arguments
883///
884/// * `account` - Reference to an `AccountID` representing the permissioned domain's owner
885/// * `seq` - The account sequence associated with the permissioned domain entry
886///
887/// # Returns
888///
889/// * `Result<KeyletBytes>` - On success, returns a 32-byte permissioned domain keylet.
890///   On failure, returns an `Error` with the corresponding error code.
891///
892/// # Safety
893///
894/// This function makes unsafe FFI calls to the host environment through
895/// the `host::permissioned_domain_keylet` function, though the unsafe code is contained
896/// within the closure passed to `create_keylet_from_host_call`.
897///
898/// # Example
899///
900/// ```rust
901/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
902/// use xrpl_wasm_stdlib::core::keylets::permissioned_domain_keylet;
903/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
904///
905/// fn main() -> Result<(), Box<dyn std::error::Error>> {
906///   let account: AccountID =
907///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
908///   let sequence = 12345;
909///   match permissioned_domain_keylet(&account, sequence) {
910///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
911///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
912///     }
913///     xrpl_wasm_stdlib::host::Result::Err(e) => {
914///       let _ = trace_num("Error assembling keylet", e.code() as i64);
915///     }
916///   }
917///   Ok(())
918///}
919/// ```
920pub fn permissioned_domain_keylet(account: &AccountID, seq: u32) -> Result<KeyletBytes> {
921    let seq_bytes = seq.to_le_bytes();
922    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
923        host::permissioned_domain_keylet(
924            account.0.as_ptr(),
925            account.0.len(),
926            seq_bytes.as_ptr(),
927            seq_bytes.len(),
928            keylet_buffer_ptr,
929            keylet_buffer_len,
930        )
931    })
932}
933
934/// Generates a signer entry keylet for a given XRP Ledger account.
935///
936/// signer entry keylets are used to reference signer entries in the XRP Ledger's state data.
937/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
938///
939/// # Arguments
940///
941/// * `account_id` - Reference to an `AccountID` representing the XRP Ledger account
942///
943/// # Returns
944///
945/// * `Result<KeyletBytes>` - On success, returns a 32-byte signer entry keylet.
946///   On failure, returns an `Error` with the corresponding error code.
947///
948/// # Safety
949///
950/// This function makes unsafe FFI calls to the host environment through
951/// the `host::signers_keylet` function, though the unsafe code is contained
952/// within the closure passed to `create_keylet_from_host_call`.
953///
954/// # Example
955///
956/// ```rust
957///
958/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
959/// use xrpl_wasm_stdlib::core::keylets::signers_keylet;
960/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
961/// fn main() -> Result<(), Box<dyn std::error::Error>> {
962///   let account:AccountID = AccountID::from(
963///     *b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3"
964///   );
965///   match signers_keylet(&account){
966///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
967///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
968///     }
969///     xrpl_wasm_stdlib::host::Result::Err(e) => {
970///       let _ = trace_num("Error assembling keylet", e.code() as i64);
971///     }
972///   }
973///   Ok(())
974/// }
975/// ```
976pub fn signers_keylet(account_id: &AccountID) -> Result<KeyletBytes> {
977    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
978        host::signers_keylet(
979            account_id.0.as_ptr(),
980            account_id.0.len(),
981            keylet_buffer_ptr,
982            keylet_buffer_len,
983        )
984    })
985}
986
987/// Generates a ticket keylet for a given owner and sequence in the XRP Ledger.
988///
989/// Ticket keylets are used to reference ticket entries in the XRP Ledger's state data.
990/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
991///
992/// # Arguments
993///
994/// * `owner` - Reference to an `AccountID` representing the ticket owner's account
995/// * `seq` - The account sequence associated with the ticket entry
996///
997/// # Returns
998///
999/// * `Result<KeyletBytes>` - On success, returns a 32-byte ticket keylet.
1000///   On failure, returns an `Error` with the corresponding error code.
1001///
1002/// # Safety
1003///
1004/// This function makes unsafe FFI calls to the host environment through
1005/// the `host::ticket_keylet` function, though the unsafe code is contained
1006/// within the closure passed to `create_keylet_from_host_call`.
1007///
1008/// # Example
1009///
1010/// ```rust
1011/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
1012/// use xrpl_wasm_stdlib::core::keylets::ticket_keylet;
1013/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
1014///
1015/// fn main() -> Result<(), Box<dyn std::error::Error>> {
1016///   let owner: AccountID =
1017///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
1018///   let sequence = 12345;
1019///   match ticket_keylet(&owner, sequence) {
1020///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
1021///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
1022///     }
1023///     xrpl_wasm_stdlib::host::Result::Err(e) => {
1024///       let _ = trace_num("Error assembling keylet", e.code() as i64);
1025///     }
1026///   }
1027///   Ok(())
1028///}
1029/// ```
1030pub fn ticket_keylet(owner: &AccountID, seq: u32) -> Result<KeyletBytes> {
1031    let seq_bytes = seq.to_le_bytes();
1032    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
1033        host::ticket_keylet(
1034            owner.0.as_ptr(),
1035            owner.0.len(),
1036            seq_bytes.as_ptr(),
1037            seq_bytes.len(),
1038            keylet_buffer_ptr,
1039            keylet_buffer_len,
1040        )
1041    })
1042}
1043
1044/// Generates a vault keylet for a given owner and sequence in the XRP Ledger.
1045///
1046/// Vault keylets are used to reference vault entries in the XRP Ledger's state data.
1047/// This function uses the generic `create_keylet_from_host_call` helper to manage the FFI interaction.
1048///
1049/// # Arguments
1050///
1051/// * `account` - Reference to an `AccountID` representing the vault's owner
1052/// * `seq` - The account sequence associated with the vault entry
1053///
1054/// # Returns
1055///
1056/// * `Result<KeyletBytes>` - On success, returns a 32-byte vault keylet.
1057///   On failure, returns an `Error` with the corresponding error code.
1058///
1059/// # Safety
1060///
1061/// This function makes unsafe FFI calls to the host environment through
1062/// the `host::vault_keylet` function, though the unsafe code is contained
1063/// within the closure passed to `create_keylet_from_host_call`.
1064///
1065/// # Example
1066///
1067/// ```rust
1068/// use xrpl_wasm_stdlib::core::types::account_id::AccountID;
1069/// use xrpl_wasm_stdlib::core::keylets::vault_keylet;
1070/// use xrpl_wasm_stdlib::host::trace::{DataRepr, trace_data, trace_num};
1071///
1072/// fn main() -> Result<(), Box<dyn std::error::Error>> {
1073///   let account: AccountID =
1074///       AccountID::from(*b"\xd5\xb9\x84VP\x9f \xb5'\x9d\x1eJ.\xe8\xb2\xaa\x82\xaec\xe3");
1075///   let sequence = 12345;
1076///   match vault_keylet(&account, sequence) {
1077///     xrpl_wasm_stdlib::host::Result::Ok(keylet) => {
1078///       let _ = trace_data("Generated keylet", &keylet, DataRepr::AsHex);
1079///     }
1080///     xrpl_wasm_stdlib::host::Result::Err(e) => {
1081///       let _ = trace_num("Error assembling keylet", e.code() as i64);
1082///     }
1083///   }
1084///   Ok(())
1085///}
1086/// ```
1087pub fn vault_keylet(account: &AccountID, seq: u32) -> Result<KeyletBytes> {
1088    let seq_bytes = seq.to_le_bytes();
1089    create_keylet_from_host_call(|keylet_buffer_ptr, keylet_buffer_len| unsafe {
1090        host::vault_keylet(
1091            account.0.as_ptr(),
1092            account.0.len(),
1093            seq_bytes.as_ptr(),
1094            seq_bytes.len(),
1095            keylet_buffer_ptr,
1096            keylet_buffer_len,
1097        )
1098    })
1099}
1100
1101/// Generic helper function to create a keylet by calling a host function.
1102///
1103/// This function handles the common tasks of:
1104/// - Initializing the keylet output buffer.
1105/// - Invoking the provided `host_call` closure (which performs the unsafe host FFI call).
1106/// - Converting the host call's `i32` result code into a `Result<KeyletBytes, Error>`.
1107///
1108/// # Arguments
1109///
1110/// * `host_call`: A closure that takes a mutable pointer to the output buffer (`*mut u8`)
1111///   and its length (`usize`), performs the specific host FFI call, and returns an `i32` status
1112///   code.
1113fn create_keylet_from_host_call<F>(host_call: F) -> Result<KeyletBytes>
1114where
1115    F: FnOnce(*mut u8, usize) -> i32,
1116{
1117    let mut keylet_buffer: KeyletBytes = [0; XRPL_KEYLET_SIZE];
1118    let result_code: i32 = host_call(keylet_buffer.as_mut_ptr(), keylet_buffer.len());
1119
1120    match_result_code_with_expected_bytes(result_code, XRPL_KEYLET_SIZE, || keylet_buffer)
1121}