use std::{path::PathBuf, str::FromStr};
use autonomi::{AttoTokens, Bytes, Chunk, Multiaddr, Signature};
use napi::bindgen_prelude::*;
use napi_derive::napi;
use tokio::sync::Mutex;
fn map_error<E>(err: E) -> napi::Error
where
E: std::error::Error,
{
let mut err_str = String::new();
err_str.push_str(&format!("{err:?}: {err}\n"));
let mut source = err.source();
while let Some(err) = source {
err_str.push_str(&format!(" Caused by: {err:?}: {err}\n"));
source = err.source();
}
napi::Error::new(Status::GenericFailure, err_str)
}
fn big_int_to_u64(value: BigInt, arg: &str) -> Result<u64> {
let (_signed, value, losless) = value.get_u64();
if !losless {
return Err(napi::Error::new(
Status::InvalidArg,
format!("expected `{arg}` to fit in a u64"),
));
}
Ok(value)
}
fn uint8_array_to_array<const LEN: usize>(value: Uint8Array, arg: &str) -> Result<[u8; LEN]> {
value.as_ref().try_into().map_err(|_err| {
napi::Error::new(
Status::InvalidArg,
format!(
"`{arg}` is expected to be a {LEN}-byte array, but is {} bytes long",
value.len()
),
)
})
}
#[napi]
pub struct Client(autonomi::Client);
#[napi]
impl Client {
#[napi(factory)]
pub async fn init() -> Result<Self> {
let client = autonomi::Client::init().await.map_err(map_error)?;
Ok(Self(client))
}
#[napi(factory)]
pub async fn init_local() -> Result<Self> {
let client = autonomi::Client::init_local().await.map_err(map_error)?;
Ok(Self(client))
}
#[napi(factory)]
pub async fn init_alpha() -> Result<Self> {
let client = autonomi::Client::init_alpha().await.map_err(map_error)?;
Ok(Self(client))
}
#[napi]
pub async fn init_with_peers(peers: Vec<String>) -> Result<Self> {
let peers = peers
.iter()
.map(|p| Multiaddr::from_str(p))
.collect::<std::result::Result<Vec<Multiaddr>, _>>()
.map_err(map_error)?;
let client = autonomi::Client::init_with_peers(peers)
.await
.map_err(map_error)?;
Ok(Self(client))
}
#[napi]
pub fn evm_network(&self) -> Network {
Network(self.0.evm_network().clone())
}
#[napi]
pub async fn chunk_get(&self, addr: &ChunkAddress) -> Result<Buffer> {
let chunk = self.0.chunk_get(&addr.0).await.map_err(map_error)?;
Ok(Buffer::from(chunk.value.to_vec()))
}
#[napi]
pub async fn chunk_put(
&self,
data: Buffer,
payment_option: &PaymentOption,
) -> Result<tuple_result::ChunkPut> {
let chunk = Chunk::new(Bytes::from(data.as_ref().to_vec()));
let (cost, addr) = self
.0
.chunk_put(&chunk, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::ChunkPut { cost, addr })
}
#[napi]
pub async fn chunk_cost(&self, addr: &ChunkAddress) -> Result< String> {
let cost = self.0.chunk_cost(&addr.0).await.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn graph_entry_get(&self, address: &GraphEntryAddress) -> Result<GraphEntry> {
let graph_entry = self
.0
.graph_entry_get(&address.0)
.await
.map_err(map_error)?;
Ok(GraphEntry(graph_entry))
}
#[napi]
pub async fn graph_entry_check_existance(&self, address: &GraphEntryAddress) -> Result<bool> {
let exists = self
.0
.graph_entry_check_existence(&address.0)
.await
.map_err(map_error)?;
Ok(exists)
}
#[napi]
pub async fn graph_entry_put(
&self,
entry: &GraphEntry,
payment_option: &PaymentOption,
) -> Result< tuple_result::GraphEntryPut> {
let (cost, addr) = self
.0
.graph_entry_put(entry.0.clone(), payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::GraphEntryPut { cost, addr })
}
#[napi]
pub async fn graph_entry_cost(&self, key: &PublicKey) -> Result< String> {
self.0
.graph_entry_cost(&key.0)
.await
.map(|c| c.to_string())
.map_err(map_error)
}
#[napi]
pub async fn pointer_get(&self, address: &PointerAddress) -> Result<Pointer> {
self.0
.pointer_get(&address.0)
.await
.map(Pointer)
.map_err(map_error)
}
#[napi]
pub async fn pointer_check_existance(&self, address: &PointerAddress) -> Result<bool> {
self.0
.pointer_check_existence(&address.0)
.await
.map_err(map_error)
}
#[napi]
pub fn pointer_verify(pointer: &Pointer) -> Result<()> {
autonomi::Client::pointer_verify(&pointer.0).map_err(map_error)
}
#[napi]
pub async fn pointer_put(
&self,
pointer: &Pointer,
payment_option: &PaymentOption,
) -> Result< tuple_result::PointerPut> {
let (cost, addr) = self
.0
.pointer_put(pointer.0.clone(), payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::PointerPut { cost, addr })
}
#[napi]
pub async fn pointer_create(
&self,
owner: &SecretKey,
target: &PointerTarget,
payment_option: &PaymentOption,
) -> Result< tuple_result::PointerPut> {
let (cost, addr) = self
.0
.pointer_create(&owner.0, target.0.clone(), payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::PointerPut { cost, addr })
}
#[napi]
pub async fn pointer_update(&self, owner: &SecretKey, target: &PointerTarget) -> Result<()> {
self.0
.pointer_update(&owner.0, target.0.clone())
.await
.map_err(map_error)
}
#[napi]
pub async fn pointer_cost(&self, key: &PublicKey) -> Result< String> {
let cost = self.0.pointer_cost(&key.0).await.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn scratchpad_get_from_public_key(
&self,
public_key: &PublicKey,
) -> Result<Scratchpad> {
self.0
.scratchpad_get_from_public_key(&public_key.0)
.await
.map(Scratchpad)
.map_err(map_error)
}
#[napi]
pub async fn scratchpad_get(&self, address: &ScratchpadAddress) -> Result<Scratchpad> {
self.0
.scratchpad_get(&address.0)
.await
.map(Scratchpad)
.map_err(map_error)
}
#[napi]
pub async fn scratchpad_check_existance(&self, address: &ScratchpadAddress) -> Result<bool> {
self.0
.scratchpad_check_existence(&address.0)
.await
.map_err(map_error)
}
#[napi]
pub fn scratchpad_verify(scratchpad: &Scratchpad) -> Result<()> {
autonomi::Client::scratchpad_verify(&scratchpad.0).map_err(map_error)
}
#[napi]
pub async fn scratchpad_put(
&self,
scratchpad: &Scratchpad,
payment_option: &PaymentOption,
) -> Result< tuple_result::ScratchpadPut> {
let (cost, addr) = self
.0
.scratchpad_put(scratchpad.0.clone(), payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::ScratchpadPut { cost, addr })
}
#[napi]
pub async fn scratchpad_create(
&self,
owner: &SecretKey,
content_type: BigInt, initial_data: Buffer,
payment_option: &PaymentOption,
) -> Result< tuple_result::ScratchpadPut> {
let content_type = big_int_to_u64(content_type, "content_type")?;
let (cost, addr) = self
.0
.scratchpad_create(
&owner.0,
content_type,
&Bytes::copy_from_slice(&initial_data),
payment_option.0.clone(),
)
.await
.map_err(map_error)?;
Ok(tuple_result::ScratchpadPut { cost, addr })
}
#[napi]
pub async fn scratchpad_update(
&self,
owner: &SecretKey,
content_type: BigInt, data: Buffer,
) -> Result<()> {
let content_type = big_int_to_u64(content_type, "content_type")?;
self.0
.scratchpad_update(&owner.0, content_type, &Bytes::copy_from_slice(&data))
.await
.map_err(map_error)
}
#[napi]
pub async fn scratchpad_cost(&self, owner: &PublicKey) -> Result< String> {
let cost = self.0.scratchpad_cost(&owner.0).await.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn data_get(&self, data_map: &DataMapChunk) -> Result<Buffer> {
let data = self.0.data_get(&data_map.0).await.map_err(map_error)?;
Ok(Buffer::from(data.as_ref()))
}
#[napi]
pub async fn data_put(
&self,
data: Buffer,
payment_option: &PaymentOption,
) -> Result< tuple_result::DataPutResult> {
let data = Bytes::copy_from_slice(&data);
let (cost, data_map) = self
.0
.data_put(data, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DataPutResult { cost, data_map })
}
#[napi]
pub async fn data_get_public(&self, addr: &DataAddress) -> Result<Buffer> {
let data = self.0.data_get_public(&addr.0).await.map_err(map_error)?;
Ok(Buffer::from(data.as_ref()))
}
#[napi]
pub async fn data_put_public(
&self,
data: Buffer,
payment_option: &PaymentOption,
) -> Result< tuple_result::DataPutPublicResult> {
let data = Bytes::copy_from_slice(&data);
let (cost, addr) = self
.0
.data_put_public(data, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DataPutPublicResult { cost, addr })
}
#[napi]
pub async fn data_cost(&self, data: Buffer) -> Result< String> {
let cost = self
.0
.data_cost(Bytes::copy_from_slice(&data))
.await
.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn archive_get(&self, addr: &PrivateArchiveDataMap) -> Result<PrivateArchive> {
let archive = self.0.archive_get(&addr.0).await.map_err(map_error)?;
Ok(PrivateArchive(archive))
}
#[napi]
pub async fn archive_put(
&self,
archive: &PrivateArchive,
payment_option: &PaymentOption,
) -> Result< tuple_result::ArchivePutResult> {
let (cost, data_map) = self
.0
.archive_put(&archive.0, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::ArchivePutResult { cost, data_map })
}
#[napi]
pub async fn archive_get_public(&self, addr: &ArchiveAddress) -> Result<PublicArchive> {
let archive = self
.0
.archive_get_public(&addr.0)
.await
.map_err(map_error)?;
Ok(PublicArchive(archive))
}
#[napi]
pub async fn archive_put_public(
&self,
archive: &PublicArchive,
payment_option: &PaymentOption,
) -> Result< tuple_result::ArchivePutPublicResult> {
let (cost, addr) = self
.0
.archive_put_public(&archive.0, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::ArchivePutPublicResult { cost, addr })
}
#[napi]
pub async fn archive_cost(&self, archive: &PublicArchive) -> Result< String> {
let cost = self
.0
.archive_cost(&archive.0.clone())
.await
.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn file_download(
&self,
data_map: &DataMapChunk,
to_dest: String,
) -> Result<()> {
let to_dest = PathBuf::from(to_dest);
self.0
.file_download(&data_map.0, to_dest)
.await
.map_err(map_error)
}
#[napi]
pub async fn dir_download(
&self,
archive_access: &PrivateArchiveDataMap,
to_dest: String,
) -> Result<()> {
let to_dest = PathBuf::from(to_dest);
self.0
.dir_download(&archive_access.0, to_dest)
.await
.map_err(map_error)
}
#[napi]
pub async fn dir_content_upload(
&self,
dir_path: String,
payment_option: &PaymentOption,
) -> Result< tuple_result::DirContentUpload> {
let dir_path = PathBuf::from(dir_path);
let (cost, archive) = self
.0
.dir_content_upload(dir_path, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DirContentUpload { cost, archive })
}
#[napi]
pub async fn dir_upload(
&self,
dir_path: String,
payment_option: &PaymentOption,
) -> Result< tuple_result::DirUpload> {
let dir_path = PathBuf::from(dir_path);
let (cost, data_map) = self
.0
.dir_upload(dir_path, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DirUpload { cost, data_map })
}
#[napi]
pub async fn file_content_upload(
&self,
path: String,
payment_option: &PaymentOption,
) -> Result< tuple_result::FileContentUpload> {
let path = PathBuf::from(path);
let (cost, data_map) = self
.0
.file_content_upload(path, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::FileContentUpload { cost, data_map })
}
#[napi]
pub async fn file_download_public(
&self,
data_addr: &DataAddress,
to_dest: String,
) -> Result<()> {
let to_dest = PathBuf::from(to_dest);
self.0
.file_download_public(&data_addr.0, to_dest)
.await
.map_err(map_error)
}
#[napi]
pub async fn dir_download_public(
&self,
archive_addr: &ArchiveAddress,
to_dest: String,
) -> Result<()> {
let to_dest = PathBuf::from(to_dest);
self.0
.dir_download_public(&archive_addr.0, to_dest)
.await
.map_err(map_error)
}
#[napi]
pub async fn dir_content_upload_public(
&self,
dir_path: String,
payment_option: &PaymentOption,
) -> Result< tuple_result::DirContentUploadPublic> {
let dir_path = PathBuf::from(dir_path);
let (cost, archive) = self
.0
.dir_content_upload_public(dir_path, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DirContentUploadPublic { cost, archive })
}
#[napi]
pub async fn dir_upload_public(
&self,
dir_path: String,
payment_option: &PaymentOption,
) -> Result< tuple_result::DirUploadPublic> {
let dir_path = PathBuf::from(dir_path);
let (cost, addr) = self
.0
.dir_upload_public(dir_path, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::DirUploadPublic { cost, addr })
}
#[napi]
pub async fn file_content_upload_public(
&self,
_path: String,
_payment_option: &PaymentOption,
) -> Result< tuple_result::FileContentUploadPublic> {
todo!()
}
#[napi]
pub async fn file_cost(&self, path: String) -> Result< String> {
let cost = self
.0
.file_cost(&PathBuf::from(path))
.await
.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn get_user_data_from_vault(&self, secret_key: &VaultSecretKey) -> Result<UserData> {
self.0
.get_user_data_from_vault(&secret_key.0)
.await
.map(UserData)
.map_err(map_error)
}
#[napi]
pub async fn put_user_data_to_vault(
&self,
secret_key: &VaultSecretKey,
payment_option: &PaymentOption,
user_data: &UserData,
) -> Result< String> {
self.0
.put_user_data_to_vault(&secret_key.0, payment_option.0.clone(), user_data.0.clone())
.await
.map(|c| c.to_string())
.map_err(map_error)
}
#[napi]
pub async fn fetch_and_decrypt_vault(
&self,
secret_key: &VaultSecretKey,
) -> Result< tuple_result::FetchAndDecryptVault> {
let (data, content_type) = self
.0
.fetch_and_decrypt_vault(&secret_key.0)
.await
.map_err(map_error)?;
Ok(tuple_result::FetchAndDecryptVault { data, content_type })
}
#[napi]
pub async fn vault_cost(
&self,
owner: &VaultSecretKey,
max_size: BigInt,
) -> Result< String> {
let max_size = big_int_to_u64(max_size, "max_size")?;
let cost = self
.0
.vault_cost(&owner.0.clone(), max_size)
.await
.map_err(map_error)?;
Ok(cost.to_string())
}
#[napi]
pub async fn write_bytes_to_vault(
&self,
data: Buffer,
payment_option: &PaymentOption,
secret_key: &VaultSecretKey,
content_type: &VaultContentType,
) -> Result< String> {
let data = Bytes::copy_from_slice(&data);
self.0
.write_bytes_to_vault(
data,
payment_option.0.clone(),
&secret_key.0,
content_type.0,
)
.await
.map(|c| c.to_string())
.map_err(map_error)
}
#[napi]
pub fn register_history(&self, addr: &RegisterAddress) -> RegisterHistory {
let history = self.0.register_history(&addr.0);
RegisterHistory(Mutex::new(history))
}
#[napi]
pub fn register_key_from_name(owner: &SecretKey, name: String) -> SecretKey {
let key = autonomi::Client::register_key_from_name(&owner.0, &name);
SecretKey(key)
}
#[napi]
pub fn register_value_from_bytes(bytes: &[u8]) -> Result< Uint8Array> {
autonomi::Client::register_value_from_bytes(bytes)
.map(Uint8Array::from)
.map_err(map_error)
}
#[napi]
pub async fn register_create(
&self,
owner: &SecretKey,
initial_value: Uint8Array,
payment_option: &PaymentOption,
) -> Result< tuple_result::RegisterCreate> {
let initial_value: [u8; 32] = uint8_array_to_array(initial_value, "initial_value")?;
let (cost, addr) = self
.0
.register_create(&owner.0, initial_value, payment_option.0.clone())
.await
.map_err(map_error)?;
Ok(tuple_result::RegisterCreate { cost, addr })
}
#[napi]
pub async fn register_update(
&self,
owner: &SecretKey,
new_value: Uint8Array,
payment_option: &PaymentOption,
) -> Result< String> {
let new_value: [u8; 32] = uint8_array_to_array(new_value, "new_value")?;
self.0
.register_update(&owner.0, new_value, payment_option.0.clone())
.await
.map(|c| c.to_string())
.map_err(map_error)
}
#[napi]
pub async fn register_get(
&self,
addr: &RegisterAddress,
) -> Result< Uint8Array> {
self.0
.register_get(&addr.0)
.await
.map(Uint8Array::from)
.map_err(map_error)
}
#[napi]
pub async fn register_cost(&self, owner: &PublicKey) -> Result< String> {
let cost = self
.0
.register_cost(&owner.0.clone())
.await
.map_err(map_error)?;
Ok(cost.to_string())
}
}
pub mod tuple_result {
use super::*;
#[napi]
pub struct ChunkPut {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::ChunkAddress, }
#[napi]
impl ChunkPut {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> ChunkAddress {
ChunkAddress(self.addr)
}
}
#[napi]
pub struct GraphEntryPut {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::GraphEntryAddress,
}
#[napi]
impl GraphEntryPut {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> GraphEntryAddress {
GraphEntryAddress(self.addr)
}
}
#[napi]
pub struct ScratchpadPut {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::ScratchpadAddress,
}
#[napi]
impl ScratchpadPut {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> ScratchpadAddress {
ScratchpadAddress(self.addr)
}
}
#[napi]
pub struct PointerPut {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::PointerAddress,
}
#[napi]
impl PointerPut {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> PointerAddress {
PointerAddress(self.addr)
}
}
#[napi]
pub struct DataPutResult {
pub(crate) cost: AttoTokens,
pub(crate) data_map: autonomi::data::private::DataMapChunk,
}
#[napi]
impl DataPutResult {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn data_map(&self) -> DataMapChunk {
DataMapChunk(self.data_map.clone())
}
}
#[napi]
pub struct DataPutPublicResult {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::data::DataAddress,
}
#[napi]
impl DataPutPublicResult {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> DataAddress {
DataAddress(self.addr)
}
}
#[napi]
pub struct ArchivePutResult {
pub(crate) cost: AttoTokens,
pub(crate) data_map: autonomi::files::archive_private::PrivateArchiveDataMap,
}
#[napi]
impl ArchivePutResult {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn data_map(&self) -> PrivateArchiveDataMap {
PrivateArchiveDataMap(self.data_map.clone())
}
}
#[napi]
pub struct ArchivePutPublicResult {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::data::DataAddress,
}
#[napi]
impl ArchivePutPublicResult {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> DataAddress {
DataAddress(self.addr)
}
}
#[napi]
pub struct DirContentUpload {
pub(crate) cost: AttoTokens,
pub(crate) archive: autonomi::files::PrivateArchive,
}
#[napi]
impl DirContentUpload {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn archive(&self) -> PrivateArchive {
PrivateArchive(self.archive.clone())
}
}
#[napi]
pub struct DirUpload {
pub(crate) cost: AttoTokens,
pub(crate) data_map: autonomi::data::private::DataMapChunk,
}
#[napi]
impl DirUpload {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn data_map(&self) -> DataMapChunk {
DataMapChunk(self.data_map.clone())
}
}
#[napi]
pub struct FileContentUpload {
pub(crate) cost: AttoTokens,
pub(crate) data_map: autonomi::data::private::DataMapChunk,
}
#[napi]
impl FileContentUpload {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn data_map(&self) -> DataMapChunk {
DataMapChunk(self.data_map.clone())
}
}
#[napi]
pub struct DirContentUploadPublic {
pub(crate) cost: AttoTokens,
pub(crate) archive: autonomi::files::PublicArchive,
}
#[napi]
impl DirContentUploadPublic {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> PublicArchive {
PublicArchive(self.archive.clone())
}
}
#[napi]
pub struct DirUploadPublic {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::files::archive_public::ArchiveAddress,
}
#[napi]
impl DirUploadPublic {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> ArchiveAddress {
ArchiveAddress(self.addr)
}
}
#[napi]
pub struct FileContentUploadPublic {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::PointerAddress,
}
#[napi]
impl FileContentUploadPublic {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> PointerAddress {
PointerAddress(self.addr)
}
}
#[napi]
pub struct FetchAndDecryptVault {
pub(crate) data: Bytes,
pub(crate) content_type: autonomi::vault::VaultContentType,
}
#[napi]
impl FetchAndDecryptVault {
#[napi(getter)]
pub fn data(&self) -> Buffer {
Buffer::from(self.data.as_ref())
}
#[napi(getter)]
pub fn content_type(&self) -> u64 {
self.content_type
}
}
#[napi]
pub struct RegisterCreate {
pub(crate) cost: AttoTokens,
pub(crate) addr: autonomi::register::RegisterAddress,
}
#[napi]
impl RegisterCreate {
#[napi(getter)]
pub fn cost(&self) -> String {
self.cost.to_string()
}
#[napi(getter)]
pub fn addr(&self) -> RegisterAddress {
RegisterAddress(self.addr)
}
}
#[napi]
pub struct GraphEntryDescendant {
pub(crate) public_key: autonomi::PublicKey,
pub(crate) content: [u8; 32],
}
#[napi]
impl GraphEntryDescendant {
#[napi(getter)]
pub fn public_key(&self) -> PublicKey {
PublicKey(self.public_key)
}
#[napi(getter)]
pub fn content(&self) -> Uint8Array {
Uint8Array::from(self.content.as_ref())
}
}
#[napi(object)]
pub struct ArchiveFile {
pub path: String,
pub created: BigInt,
pub modified: BigInt,
pub size: BigInt,
pub extra: Option<String>,
}
}
#[napi]
pub struct XorName(autonomi::XorName);
#[napi]
impl XorName {
#[napi(factory)]
pub fn from_content(content: &[u8]) -> Self {
Self(autonomi::XorName::from_content_parts(&[content]))
}
#[napi(factory)]
pub fn random() -> Self {
Self(autonomi::XorName::random(&mut rand::thread_rng()))
}
}
#[napi]
pub struct ChunkAddress(autonomi::ChunkAddress);
#[napi]
impl ChunkAddress {
#[napi(constructor)]
pub fn new(xor_name: &XorName) -> Self {
Self(autonomi::ChunkAddress::new(xor_name.0))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(*self.0.xorname())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let addr = autonomi::ChunkAddress::from_hex(&hex).map_err(map_error)?;
Ok(Self(addr))
}
}
#[napi]
pub struct GraphEntryAddress(autonomi::GraphEntryAddress);
#[napi]
impl GraphEntryAddress {
#[napi(constructor)]
pub fn new(owner: &PublicKey) -> Self {
Self(autonomi::GraphEntryAddress::new(owner.0))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(self.0.xorname())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let addr = autonomi::GraphEntryAddress::from_hex(&hex).map_err(map_error)?;
Ok(Self(addr))
}
}
#[napi]
pub struct DataAddress(autonomi::data::DataAddress);
#[napi]
impl DataAddress {
#[napi(constructor)]
pub fn new(xor_name: &XorName) -> Self {
Self(autonomi::data::DataAddress::new(xor_name.0))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(*self.0.xorname())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
autonomi::data::DataAddress::from_hex(&hex)
.map(Self)
.map_err(map_error)
}
}
#[napi]
pub struct ArchiveAddress(autonomi::files::archive_public::ArchiveAddress);
#[napi]
impl ArchiveAddress {
#[napi(constructor)]
pub fn new(xor_name: &XorName) -> Self {
Self(autonomi::files::archive_public::ArchiveAddress::new(
xor_name.0,
))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(*self.0.xorname())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
autonomi::files::archive_public::ArchiveAddress::from_hex(&hex)
.map(Self)
.map_err(map_error)
}
}
#[napi]
pub struct Wallet(autonomi::Wallet);
#[napi]
impl Wallet {
pub fn new_with_random_wallet(network: autonomi::Network) -> Self {
Wallet(autonomi::Wallet::new_with_random_wallet(network))
}
#[napi(factory)]
pub fn new_from_private_key(network: &Network, private_key: String) -> Result<Self> {
let wallet = autonomi::Wallet::new_from_private_key(network.0.clone(), &private_key)
.map_err(map_error)?;
Ok(Self(wallet))
}
#[napi]
pub fn address(&self) -> String {
self.0.address().to_string()
}
pub fn network(&self) -> Network {
Network(self.0.network().clone())
}
#[napi]
pub async fn balance(&self) -> Result<String> {
let balance = self.0.balance_of_tokens().await.map_err(map_error)?;
Ok(balance.to_string())
}
#[napi]
pub async fn balance_of_gas(&self) -> Result<String> {
let balance = self.0.balance_of_gas_tokens().await.map_err(map_error)?;
Ok(balance.to_string())
}
#[napi]
pub fn set_transaction_config(&mut self, config: &TransactionConfig) {
self.0.set_transaction_config(config.0.clone())
}
}
#[napi]
pub struct TransactionConfig(autonomi::TransactionConfig);
#[napi]
impl TransactionConfig {
#[napi(factory)]
pub fn auto() -> Self {
Self(autonomi::TransactionConfig {
max_fee_per_gas: autonomi::MaxFeePerGas::Auto,
})
}
#[napi(factory)]
pub fn limited_auto(limit: BigInt) -> Result<Self> {
let (_signed, value, lossless) = limit.get_u128();
if !lossless {
return Err(napi::Error::new(
Status::InvalidArg,
"expected limit to fit in a u128",
));
}
Ok(Self(autonomi::TransactionConfig {
max_fee_per_gas: autonomi::MaxFeePerGas::LimitedAuto(value),
}))
}
#[napi(factory)]
pub fn unlimited() -> Self {
Self(autonomi::TransactionConfig {
max_fee_per_gas: autonomi::MaxFeePerGas::Unlimited,
})
}
#[napi(factory)]
pub fn custom(fee: BigInt) -> Result<Self> {
let (_signed, value, lossless) = fee.get_u128();
if !lossless {
return Err(napi::Error::new(
Status::InvalidArg,
"expected fee to fit in a u128",
));
}
Ok(Self(autonomi::TransactionConfig {
max_fee_per_gas: autonomi::MaxFeePerGas::Custom(value),
}))
}
}
#[napi]
pub struct PaymentOption(autonomi::client::payment::PaymentOption);
#[napi]
impl PaymentOption {
#[napi(factory)]
pub fn from_wallet(wallet: &Wallet) -> Self {
Self(autonomi::client::payment::PaymentOption::from(&wallet.0))
}
#[napi(factory)]
pub fn from_receipt() -> Self {
unimplemented!()
}
}
#[napi]
pub struct Network(autonomi::Network);
#[napi]
impl Network {
#[napi(constructor)]
pub fn new(local: bool) -> Result<Self> {
let network = autonomi::Network::new(local).map_err(map_error)?;
Ok(Self(network))
}
}
#[napi]
pub struct PublicKey(autonomi::PublicKey);
#[napi]
impl PublicKey {
#[napi]
pub fn to_bytes(&self) -> Uint8Array {
Uint8Array::from(self.0.to_bytes())
}
#[napi(factory)]
pub fn from_bytes(bytes: Uint8Array) -> Result<Self> {
let bytes = uint8_array_to_array(bytes, "bytes")?;
let key = autonomi::PublicKey::from_bytes(bytes).map_err(map_error)?;
Ok(Self(key))
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let key = autonomi::PublicKey::from_hex(&hex).map_err(map_error)?;
Ok(Self(key))
}
}
#[napi]
pub struct SecretKey(autonomi::SecretKey);
#[napi]
impl SecretKey {
#[napi(factory)]
pub fn random() -> Self {
Self(autonomi::SecretKey::random())
}
#[napi]
pub fn public_key(&self) -> PublicKey {
PublicKey(self.0.public_key())
}
#[napi]
pub fn to_bytes(&self) -> Uint8Array {
Uint8Array::from(self.0.to_bytes())
}
#[napi(factory)]
pub fn from_bytes(bytes: Uint8Array) -> Result<Self> {
let bytes = uint8_array_to_array(bytes, "bytes")?;
let key = autonomi::SecretKey::from_bytes(bytes).map_err(map_error)?;
Ok(Self(key))
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let key = autonomi::SecretKey::from_hex(&hex).map_err(map_error)?;
Ok(Self(key))
}
}
#[napi]
pub struct GraphEntry(autonomi::GraphEntry);
#[napi]
impl GraphEntry {
#[napi(constructor)]
pub fn new(
owner: &SecretKey,
parents: Vec<&PublicKey>,
content: Uint8Array,
descendants: Vec<(&PublicKey, Uint8Array)>,
) -> Result<Self> {
let content: [u8; 32] = uint8_array_to_array(content, "content")?;
let parents = parents.iter().map(|p| p.0).collect();
let descendants = descendants
.iter()
.map(|(pk, content)| {
let content_array: [u8; 32] = uint8_array_to_array(content.clone(), "content")?;
Ok((pk.0, content_array))
})
.collect::<Result<Vec<(autonomi::PublicKey, [u8; 32])>>>()?;
Ok(Self(autonomi::GraphEntry::new(
&owner.0,
parents,
content,
descendants,
)))
}
#[napi(factory)]
pub fn new_with_signature(
owner: &PublicKey,
parents: Vec<&PublicKey>,
content: Uint8Array,
descendants: Vec<(&PublicKey, Uint8Array)>,
signature: Uint8Array,
) -> Result<Self> {
let content: [u8; 32] = uint8_array_to_array(content, "content")?;
let parents = parents.iter().map(|p| p.0).collect();
let descendants_result: Result<Vec<(autonomi::PublicKey, [u8; 32])>> = descendants
.iter()
.map(|(pk, content)| {
let content_array: [u8; 32] = uint8_array_to_array(content.clone(), "content")?;
Ok((pk.0, content_array))
})
.collect();
let descendants = descendants_result?;
let signature = uint8_array_to_array(signature, "signature")?;
let signature = Signature::from_bytes(signature).map_err(map_error)?;
Ok(Self(autonomi::GraphEntry::new_with_signature(
owner.0,
parents,
content,
descendants,
signature,
)))
}
#[napi]
pub fn address(&self) -> GraphEntryAddress {
GraphEntryAddress(self.0.address())
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(self.0.owner)
}
#[napi]
pub fn parents(&self) -> Vec<PublicKey> {
self.0.parents.iter().map(|p| PublicKey(*p)).collect()
}
#[napi]
pub fn content(&self) -> Buffer {
Buffer::from(self.0.content.to_vec())
}
#[napi]
pub fn descendants(&self) -> Vec<tuple_result::GraphEntryDescendant> {
self.0
.descendants
.iter()
.map(|(pk, data)| tuple_result::GraphEntryDescendant {
public_key: *pk,
content: *data,
})
.collect()
}
#[napi]
pub fn bytes_for_signature(&self) -> Buffer {
Buffer::from(self.0.bytes_for_signature())
}
#[napi]
pub fn verify_signature(&self) -> bool {
self.0.verify_signature()
}
#[napi]
pub fn size(&self) -> usize {
self.0.size()
}
#[napi(getter)]
pub fn signature(&self) -> Uint8Array {
Uint8Array::from(self.0.signature.to_bytes())
}
#[napi]
pub fn is_too_big(&self) -> bool {
self.0.is_too_big()
}
}
#[napi]
pub struct Pointer(autonomi::Pointer);
#[napi]
impl Pointer {
#[napi(constructor)]
pub fn new(owner: &SecretKey, counter: BigInt, target: &PointerTarget) -> Result<Self> {
let counter = big_int_to_u64(counter, "counter")?;
Ok(Pointer(autonomi::Pointer::new(
&owner.0,
counter,
target.0.clone(),
)))
}
#[napi]
pub fn address(&self) -> PointerAddress {
PointerAddress(self.0.address())
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(*self.0.owner())
}
#[napi]
pub fn target(&self) -> PointerTarget {
PointerTarget(self.0.target().clone())
}
#[napi]
pub fn bytes_for_signature(&self) -> Buffer {
Buffer::from(self.0.bytes_for_signature())
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(self.0.xorname())
}
#[napi]
pub fn counter(&self) -> u64 {
self.0.counter()
}
#[napi]
pub fn verify_signature(&self) -> bool {
self.0.verify_signature()
}
#[napi]
pub fn size() -> usize {
autonomi::Pointer::size()
}
}
#[napi]
pub struct PointerTarget(autonomi::pointer::PointerTarget);
#[napi]
impl PointerTarget {
#[napi]
pub fn xorname(&self) -> XorName {
XorName(self.0.xorname())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory, js_name = "ChunkAddress")]
pub fn from_chunk_address(addr: &ChunkAddress) -> Self {
Self(autonomi::pointer::PointerTarget::ChunkAddress(addr.0))
}
#[napi(factory, js_name = "GraphEntryAddress")]
pub fn from_graph_entry_address(addr: &GraphEntryAddress) -> Self {
Self(autonomi::pointer::PointerTarget::GraphEntryAddress(addr.0))
}
#[napi(factory, js_name = "PointerAddress")]
pub fn from_pointer_address(addr: &PointerAddress) -> Self {
Self(autonomi::pointer::PointerTarget::PointerAddress(addr.0))
}
#[napi(factory, js_name = "ScratchpadAddress")]
pub fn from_scratchpad_address(addr: &ScratchpadAddress) -> Self {
Self(autonomi::pointer::PointerTarget::ScratchpadAddress(addr.0))
}
}
#[napi]
pub struct PointerAddress(autonomi::PointerAddress);
#[napi]
impl PointerAddress {
#[napi(constructor)]
pub fn new(owner: &PublicKey) -> Self {
Self(autonomi::PointerAddress::new(owner.0))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(self.0.xorname())
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(*self.0.owner())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let addr = autonomi::PointerAddress::from_hex(&hex).map_err(map_error)?;
Ok(Self(addr))
}
}
#[napi]
pub struct Scratchpad(autonomi::Scratchpad);
#[napi]
impl Scratchpad {
#[napi(constructor)]
pub fn new(
owner: &SecretKey,
data_encoding: BigInt, data: Buffer,
counter: BigInt, ) -> Result<Self> {
let data_encoding = big_int_to_u64(data_encoding, "data_encoding")?;
let counter = big_int_to_u64(counter, "counter")?;
let data = Bytes::copy_from_slice(&data);
Ok(Self(autonomi::Scratchpad::new(
&owner.0,
data_encoding,
&data,
counter,
)))
}
#[napi]
pub fn address(&self) -> ScratchpadAddress {
ScratchpadAddress(*self.0.address())
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(*self.0.owner())
}
#[napi]
pub fn data_encoding(&self) -> u64 {
self.0.data_encoding()
}
#[napi]
pub fn decrypt_data(&self, key: &SecretKey) -> Result<Buffer> {
let data = self.0.decrypt_data(&key.0).map_err(map_error)?;
Ok(Buffer::from(data.to_vec()))
}
#[napi]
pub fn counter(&self) -> u64 {
self.0.counter()
}
#[napi]
pub fn verify_signature(&self) -> bool {
self.0.verify_signature()
}
}
#[napi]
pub struct ScratchpadAddress(autonomi::ScratchpadAddress);
#[napi]
impl ScratchpadAddress {
#[napi(constructor)]
pub fn new(owner: &PublicKey) -> Self {
Self(autonomi::ScratchpadAddress::new(owner.0))
}
#[napi]
pub fn xorname(&self) -> XorName {
XorName(self.0.xorname())
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(*self.0.owner())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let addr = autonomi::ScratchpadAddress::from_hex(&hex).map_err(map_error)?;
Ok(Self(addr))
}
}
#[napi]
pub struct DataMapChunk(autonomi::data::private::DataMapChunk);
#[napi]
pub struct PrivateArchiveDataMap(autonomi::files::archive_private::PrivateArchiveDataMap);
#[napi]
impl PrivateArchiveDataMap {
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let data_map = autonomi::files::archive_private::PrivateArchiveDataMap::from_hex(&hex)
.map_err(map_error)?;
Ok(Self(data_map))
}
}
#[napi]
pub struct PrivateArchive(autonomi::files::PrivateArchive);
#[napi]
impl PrivateArchive {
#[napi(constructor)]
#[allow(clippy::new_without_default, reason = "`Default` not useful")]
pub fn new() -> Self {
Self(autonomi::files::PrivateArchive::new())
}
#[napi]
pub fn add_file(&mut self, path: String, data_map: &DataMapChunk, metadata: &Metadata) {
self.0
.add_file(PathBuf::from(path), data_map.0.clone(), metadata.0.clone());
}
#[napi]
pub fn rename_file(&mut self, old_path: String, new_path: String) -> Result<()> {
self.0
.rename_file(&PathBuf::from(old_path), &PathBuf::from(new_path))
.map_err(map_error)
}
#[napi]
pub fn files(&self) -> Vec<tuple_result::ArchiveFile> {
self.0
.files()
.into_iter()
.map(|(path, meta)| tuple_result::ArchiveFile {
path: path.to_string_lossy().to_string(),
created: BigInt::from(meta.created),
modified: BigInt::from(meta.modified),
size: BigInt::from(meta.size),
extra: meta.extra.clone(),
})
.collect()
}
#[napi]
pub fn data_maps(&self) -> Vec<DataMapChunk> {
self.0.data_maps().into_iter().map(DataMapChunk).collect()
}
#[napi]
pub fn to_bytes(&self) -> Result<Buffer> {
let bytes = self.0.to_bytes().map_err(|e| {
napi::Error::new(
Status::GenericFailure,
format!("Failed to serialize archive: {e:?}"),
)
})?;
Ok(Buffer::from(bytes.to_vec()))
}
#[napi(factory)]
pub fn from_bytes(data: Buffer) -> Result<Self> {
let bytes = Bytes::from(data.as_ref().to_vec());
let archive = autonomi::files::PrivateArchive::from_bytes(bytes).map_err(|e| {
napi::Error::new(
Status::GenericFailure,
format!("Failed to deserialize archive: {e:?}"),
)
})?;
Ok(Self(archive))
}
#[napi]
pub fn merge(&mut self, other: &PrivateArchive) {
self.0.merge(&other.0);
}
}
#[napi]
pub struct VaultSecretKey(autonomi::vault::VaultSecretKey);
#[napi]
pub struct UserData(autonomi::vault::UserData);
#[napi]
pub struct VaultContentType(autonomi::vault::VaultContentType);
#[napi]
pub struct Metadata(autonomi::files::Metadata);
#[napi]
impl Metadata {
#[napi(factory)]
pub fn new_with_size(size: BigInt) -> Result<Self> {
let size = big_int_to_u64(size, "size")?;
Ok(Self(autonomi::files::Metadata::new_with_size(size)))
}
#[napi(factory)]
pub fn with_custom_fields(
created: BigInt,
modified: BigInt,
size: BigInt,
extra: Option<String>,
) -> Result<Self> {
let created = big_int_to_u64(created, "created")?;
let modified = big_int_to_u64(modified, "modified")?;
let size = big_int_to_u64(size, "size")?;
Ok(Self(autonomi::files::Metadata {
created,
modified,
size,
extra,
}))
}
#[napi(factory)]
pub fn empty() -> Self {
Self(autonomi::files::Metadata::empty())
}
#[napi(getter)]
pub fn created(&self) -> u64 {
self.0.created
}
#[napi(getter)]
pub fn modified(&self) -> u64 {
self.0.modified
}
#[napi(getter)]
pub fn size(&self) -> u64 {
self.0.size
}
#[napi(getter)]
pub fn extra(&self) -> Option<String> {
self.0.extra.clone()
}
}
#[napi]
pub struct RegisterAddress(autonomi::register::RegisterAddress);
#[napi]
impl RegisterAddress {
#[napi(constructor)]
pub fn new(owner: &PublicKey) -> Self {
Self(autonomi::register::RegisterAddress::new(owner.0))
}
#[napi]
pub fn owner(&self) -> PublicKey {
PublicKey(self.0.owner())
}
#[napi]
pub fn to_underlying_graph_root(&self) -> GraphEntryAddress {
GraphEntryAddress(self.0.to_underlying_graph_root())
}
#[napi]
pub fn to_underlying_head_pointer(&self) -> PointerAddress {
PointerAddress(self.0.to_underlying_head_pointer())
}
#[napi]
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
#[napi(factory)]
pub fn from_hex(hex: String) -> Result<Self> {
let addr = autonomi::register::RegisterAddress::from_hex(&hex).map_err(map_error)?;
Ok(Self(addr))
}
}
#[napi]
pub struct RegisterHistory(Mutex<autonomi::register::RegisterHistory>);
#[napi]
impl RegisterHistory {
#[allow(clippy::new_without_default, reason = "`Default` not useful")]
#[napi(constructor)]
pub fn new() -> Self {
unimplemented!()
}
#[napi]
pub async fn next(&self) -> Result<Option<Uint8Array>> {
self.0
.lock()
.await
.next()
.await
.map(|v| v.map(Uint8Array::from))
.map_err(map_error)
}
#[napi]
pub async fn collect(&self) -> Result<Vec<Uint8Array>> {
let values = self.0.lock().await.collect().await.map_err(map_error)?;
let values = values.into_iter().map(Uint8Array::from).collect();
Ok(values)
}
}
#[napi]
pub struct PublicArchive(autonomi::files::PublicArchive);
#[napi]
impl PublicArchive {
#[napi(constructor)]
#[allow(clippy::new_without_default, reason = "`Default` not useful")]
pub fn new() -> Self {
Self(autonomi::files::PublicArchive::new())
}
#[napi]
pub fn add_file(&mut self, path: String, data_addr: &DataAddress, metadata: &Metadata) {
self.0
.add_file(PathBuf::from(path), data_addr.0, metadata.0.clone());
}
#[napi]
pub fn rename_file(&mut self, old_path: String, new_path: String) -> Result<()> {
self.0
.rename_file(&PathBuf::from(old_path), &PathBuf::from(new_path))
.map_err(map_error)
}
#[napi]
pub fn files(&self) -> Vec<tuple_result::ArchiveFile> {
self.0
.files()
.into_iter()
.map(|(path, meta)| tuple_result::ArchiveFile {
path: path.to_string_lossy().to_string(),
created: BigInt::from(meta.created),
modified: BigInt::from(meta.modified),
size: BigInt::from(meta.size),
extra: meta.extra.clone(),
})
.collect()
}
#[napi]
pub fn addresses(&self) -> Vec<DataAddress> {
self.0.addresses().into_iter().map(DataAddress).collect()
}
#[napi]
pub fn to_bytes(&self) -> Result<Buffer> {
let bytes = self.0.to_bytes().map_err(|e| {
napi::Error::new(
Status::GenericFailure,
format!("Failed to serialize archive: {e:?}"),
)
})?;
Ok(Buffer::from(bytes.to_vec()))
}
#[napi(factory)]
pub fn from_bytes(data: Buffer) -> Result<Self> {
let bytes = Bytes::from(data.as_ref().to_vec());
let archive = autonomi::files::PublicArchive::from_bytes(bytes).map_err(|e| {
napi::Error::new(
Status::GenericFailure,
format!("Failed to deserialize archive: {e:?}"),
)
})?;
Ok(Self(archive))
}
#[napi]
pub fn merge(&mut self, other: &PublicArchive) {
self.0.merge(&other.0);
}
}