Skip to content
Snippets Groups Projects
  • Francisco Aguirre's avatar
    Change `XcmDryRunApi::dry_run_extrinsic` to take a call instead (#4621) · d5053ac4
    Francisco Aguirre authored
    
    Follow-up to the new `XcmDryRunApi` runtime API introduced in
    https://github.com/paritytech/polkadot-sdk/pull/3872.
    
    Taking an extrinsic means the frontend has to sign first to dry-run and
    once again to submit.
    This is bad UX which is solved by taking an `origin` and a `call`.
    This also has the benefit of being able to dry-run as any account, since
    it needs no signature.
    
    This is a breaking change since I changed `dry_run_extrinsic` to
    `dry_run_call`, however, this API is still only on testnets.
    The crates are bumped accordingly.
    
    As a part of this PR, I changed the name of the API from `XcmDryRunApi`
    to just `DryRunApi`, since it can be used for general dry-running :)
    
    Step towards https://github.com/paritytech/polkadot-sdk/issues/690.
    
    Example of calling the API with PAPI, not the best code, just testing :)
    
    ```ts
    // We just build a call, the arguments make it look very big though.
    const call = localApi.tx.XcmPallet.transfer_assets({
      dest: XcmVersionedLocation.V4({ parents: 0, interior: XcmV4Junctions.X1(XcmV4Junction.Parachain(1000)) }),
      beneficiary: XcmVersionedLocation.V4({ parents: 0, interior: XcmV4Junctions.X1(XcmV4Junction.AccountId32({ network: undefined, id: Binary.fromBytes(encodeAccount(account.address)) })) }),
      weight_limit: XcmV3WeightLimit.Unlimited(),
      assets: XcmVersionedAssets.V4([{
        id: { parents: 0, interior: XcmV4Junctions.Here() },
        fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n) }
      ]),
      fee_asset_item: 0,
    });
    // We call the API passing in a signed origin 
    const result = await localApi.apis.XcmDryRunApi.dry_run_call(
      WestendRuntimeOriginCaller.system(DispatchRawOrigin.Signed(account.address)),
      call.decodedCall
    );
    if (result.success && result.value.execution_result.success) {
      // We find the forwarded XCM we want. The first one going to AssetHub in this case.
      const xcmsToAssetHub = result.value.forwarded_xcms.find(([location, _]) => (
        location.type === "V4" &&
          location.value.parents === 0 &&
          location.value.interior.type === "X1"
          && location.value.interior.value.type === "Parachain"
          && location.value.interior.value.value === 1000
      ))!;
    
      // We can even find the delivery fees for that forwarded XCM.
      const deliveryFeesQuery = await localApi.apis.XcmPaymentApi.query_delivery_fees(xcmsToAssetHub[0], xcmsToAssetHub[1][0]);
    
      if (deliveryFeesQuery.success) {
        const amount = deliveryFeesQuery.value.type === "V4" && deliveryFeesQuery.value.value[0].fun.type === "Fungible" && deliveryFeesQuery.value.value[0].fun.value.valueOf() || 0n;
        // We store them in state somewhere.
        setDeliveryFees(formatAmount(BigInt(amount)));
      }
    }
    ```
    
    ---------
    
    Co-authored-by: default avatarBastian Köcher <git@kchr.de>
    Unverified
    d5053ac4
Code owners
Assign users and groups as approvers for specific file changes. Learn more.