• useCreateMirror is React Hook that allows you to mirror a Lens publication.

    You MUST be authenticated via useLogin to use this hook.

    Returns UseDeferredTask<MirrorAsyncResult, BroadcastingError | InsufficientGasError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, CreateMirrorArgs>

    Example

    const { execute, error, loading } = useCreateMirror();
    

    Basic usage

    const { execute, error, loading } = useCreateMirror();

    const mirror = () => {
    const result = await execute({
    mirrorOn: publicationId, // the publication ID to mirror
    });
    }

    Failure scenarios

    You can handle possible failure scenarios by checking the result value.

    const { execute, error, loading } = useCreateMirror();

    const mirror = async () => {
    const result = await execute({
    mirrorOn: publicationId,
    });

    if (result.isFailure()) {
    switch (result.error.name) {
    case 'BroadcastingError':
    console.log('There was an error broadcasting the transaction', error.message);
    break;

    case 'PendingSigningRequestError':
    console.log(
    'There is a pending signing request in your wallet. ' +
    'Approve it or discard it and try again.'
    );
    break;

    case 'WalletConnectionError':
    console.log('There was an error connecting to your wallet', error.message);
    break;

    case 'UserRejectedError':
    // the user decided to not sign, usually this is silently ignored by UIs
    break;
    }
    return;
    }
    };

    At this point the mirror creation is completed from an end-user perspective but, in case of on-chain TX, this is not necessarily mined and indexed (yet). See the following section.

    Wait for completion

    In case of successful submission, the result value can be used to wait for the mirror to be fully processed.

    This gives you an opportunity to decide what UX to provide to the end-user.

    For example if the mirror is on-chain it might take a while to be mined and indexed. So you might want to show a loading indicator or let the user navigate away from the page.

    const { execute, error, loading } = useCreateMirror();

    const mirror = async () => {
    const result = await execute({
    mirrorOn: publicationId,
    });

    if (result.isFailure()) {
    // handle failure scenarios
    return;
    }

    // this might take a while, depends on the type of tx (on-chain or Momoka)
    // and the congestion of the network
    const completion = await result.value.waitForCompletion();

    if (completion.isFailure()) {
    console.log('There was an processing the transaction', completion.error.message);
    return;
    }

    // the mirror is now ready to be used
    const mirror = completion.value;
    console.log('Mirror created', mirror);
    };

    Self-funded approach

    In case you want to pay for the transaction gas costs yourself, you can do so by setting the sponsored parameter to false:

    const mirror = async (publicationId: PublicationId) => {
    const result = await execute({
    mirrorOn: publicationId,
    sponsored: false,
    });

    if (result.isFailure()) {
    switch (result.error.name) {
    case 'InsufficientGasError':
    console.log('You do not have enough funds to pay for the transaction cost.');
    break;

    // ...
    }
    return;
    }

    // ...
    }

    The example above shows how to detect when the user does not have enough funds to pay for the transaction cost.

    Self-funded fallback

    If for some reason the Lens API cannot sponsor the transaction, the hook will fail with a BroadcastingError with one of the following reasons:

    In those cases you can retry the transaction as self-funded like in the following example:

    const mirror = async (publicationId: PublicationId) => {
    const sponsoredResult = await execute({
    mirrorOn: publicationId,
    sponsored: false,
    });

    if (sponsoredResult.isFailure()) {
    switch (sponsoredResult.error.name) {
    case 'BroadcastingError':
    if ([BroadcastingErrorReason.NOT_SPONSORED, BroadcastingErrorReason.RATE_LIMITED].includes(sponsoredResult.error.reason)) {

    const chargedResult = = await execute({
    mirrorOn: publicationId,
    sponsored: false,
    });

    // continue with chargedResult as in the previous example
    }
    break;

    // ...
    }
    }

    We omitted the handling of the BroadcastingErrorReason.APP_NOT_ALLOWED error because it's usually something that builder will face when deploying their app to production using the Production Lens API.

    It just requires the app to apply for whitelisting. See https://docs.lens.xyz/docs/gasless-and-signless#whitelisting-your-app.