use anyhow::Result;
use fuels::{
core::Configurables,
prelude::*,
tx::StorageSlot,
types::transaction_builders::Blob,
};
pub fn build_loader_blobs(
bytecode: Vec<u8>,
salt: Salt,
storage_slots: Vec<StorageSlot>,
configurables: impl Into<Configurables>,
max_words_per_blob: usize,
) -> Result<(Vec<Blob>, Blob)> {
let loader = Contract::regular(bytecode, salt, storage_slots)
.with_configurables(configurables)
.convert_to_loader(max_words_per_blob)?;
let data_blobs = loader.blobs().to_vec();
let loader_blob = Blob::new(loader.code());
Ok((data_blobs, loader_blob))
}
pub async fn upload_loader_blobs<W>(
deployer_wallet: &W,
data_blobs: Vec<Blob>,
loader_blob: Blob,
) -> Result<BlobId>
where
W: Account,
{
let provider = deployer_wallet.try_provider()?;
for data_blob in data_blobs {
if provider.blob_exists(data_blob.id()).await? {
continue;
}
upload_single_blob(deployer_wallet, data_blob).await?;
}
let loader_blob_id = loader_blob.id();
if !provider.blob_exists(loader_blob_id).await? {
upload_single_blob(deployer_wallet, loader_blob).await?;
}
Ok(loader_blob_id)
}
async fn upload_single_blob<W>(deployer_wallet: &W, blob: Blob) -> Result<()>
where
W: Account,
{
let mut builder = BlobTransactionBuilder::default().with_blob(blob);
deployer_wallet.adjust_for_fee(&mut builder, 0).await?;
deployer_wallet.add_witnesses(&mut builder)?;
let tx = builder.build(&deployer_wallet.try_provider()?).await?;
deployer_wallet
.try_provider()?
.send_transaction_and_await_commit(tx)
.await?
.check(None)?;
Ok(())
}