diff --git a/package.json b/package.json index b23c881c..9bd9a488 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "@mui/lab": "5.0.0-alpha.134", "@mui/material": "^5.15.14", "@mui/x-date-pickers": "^6.19.5", - "@polkadot/api": "11.2.1", + "@polkadot/api": "12.0.2", "@polkadot/extension-dapp": "0.47.3", "@polkadot/extension-inject": "0.47.3", "@polkadot/react-identicon": "^3.6.6", - "@polkadot/types": "11.2.1", + "@polkadot/types": "12.0.2", "@polkadot/ui-keyring": "3.6.6", "@polkadot/util": "12.6.2", "@polkadot/util-crypto": "^12.6.2", @@ -79,4 +79,4 @@ "typescript": "^4.7.4", "webpack": "^5.81.0" } -} +} \ No newline at end of file diff --git a/src/components/Modals/Orders/Contribution/index.tsx b/src/components/Modals/Orders/Contribution/index.tsx index 145d9a3f..a36f9904 100644 --- a/src/components/Modals/Orders/Contribution/index.tsx +++ b/src/components/Modals/Orders/Contribution/index.tsx @@ -20,7 +20,7 @@ import { useRegionXApi, useRelayApi } from '@/contexts/apis'; import { ApiState } from '@/contexts/apis/types'; import { useOrders } from '@/contexts/orders'; import { useToast } from '@/contexts/toast'; -import { Order } from '@/models'; +import { Order, RELAY_ASSET_ID } from '@/models'; import styles from './index.module.scss'; @@ -99,7 +99,8 @@ export const ContributionModal = ({ toastError(`Failed to contribute to an order ${e}`); setWorking(false); }, - } + }, + RELAY_ASSET_ID ); } catch (e: any) { setWorking(false); diff --git a/src/components/Modals/Orders/OrderCreation/index.tsx b/src/components/Modals/Orders/OrderCreation/index.tsx index d37db411..dc0c8173 100644 --- a/src/components/Modals/Orders/OrderCreation/index.tsx +++ b/src/components/Modals/Orders/OrderCreation/index.tsx @@ -33,6 +33,7 @@ import { useSaleInfo } from '@/contexts/sales'; import { useToast } from '@/contexts/toast'; import styles from './index.module.scss'; +import { RELAY_ASSET_ID } from '@/models'; interface OrderCreationModalProps { open: boolean; @@ -138,7 +139,8 @@ export const OrderCreationModal = ({ toastError(`Failed to create a new order ${e}`); setWorking(false); }, - } + }, + RELAY_ASSET_ID ); } catch (e: any) { toastError(`Failed to create a new order. ${e.toString()}`); diff --git a/src/components/Modals/Regions/Purchase/index.tsx b/src/components/Modals/Regions/Purchase/index.tsx index 2e6a66d9..acdb7105 100644 --- a/src/components/Modals/Regions/Purchase/index.tsx +++ b/src/components/Modals/Regions/Purchase/index.tsx @@ -13,7 +13,7 @@ import { ApiState } from '@/contexts/apis/types'; import { useMarket } from '@/contexts/market'; import { useRegions } from '@/contexts/regions'; import { useToast } from '@/contexts/toast'; -import { Listing } from '@/models'; +import { Listing, RELAY_ASSET_ID } from '@/models'; interface PurchaseModalProps { open: boolean; @@ -87,15 +87,15 @@ export const PurchaseModal = ({ }, error: (e) => { toastError( - `Failed to purchase the region. Error: ${ - e.errorMessage === 'Error' - ? 'Please check your balance.' - : e.errorMessage + `Failed to purchase the region. Error: ${e.errorMessage === 'Error' + ? 'Please check your balance.' + : e.errorMessage }` ); setWorking(false); }, - } + }, + RELAY_ASSET_ID ); }; @@ -113,6 +113,9 @@ export const PurchaseModal = ({ pb: '1rem', }} > + purchaseRegion()} variant='contained' @@ -120,9 +123,6 @@ export const PurchaseModal = ({ > Purchase - ); diff --git a/src/components/Modals/Regions/Sell/index.tsx b/src/components/Modals/Regions/Sell/index.tsx index 8e47bbda..49b11051 100644 --- a/src/components/Modals/Regions/Sell/index.tsx +++ b/src/components/Modals/Regions/Sell/index.tsx @@ -22,7 +22,7 @@ import { ApiState } from '@/contexts/apis/types'; import { useMarket } from '@/contexts/market'; import { useRegions } from '@/contexts/regions'; import { useToast } from '@/contexts/toast'; -import { RegionMetadata } from '@/models'; +import { RELAY_ASSET_ID, RegionMetadata } from '@/models'; interface SellModalProps { open: boolean; @@ -119,7 +119,8 @@ export const SellModal = ({ ); setWorking(false); }, - } + }, + RELAY_ASSET_ID ); }; diff --git a/src/components/Regions/IsmpRegionCard/index.tsx b/src/components/Regions/IsmpRegionCard/index.tsx index 04ee9725..7b04990c 100644 --- a/src/components/Regions/IsmpRegionCard/index.tsx +++ b/src/components/Regions/IsmpRegionCard/index.tsx @@ -23,7 +23,7 @@ import { useRegionXApi } from '@/contexts/apis/RegionXApi'; import { ApiState } from '@/contexts/apis/types'; import { useRegions } from '@/contexts/regions'; import { useToast } from '@/contexts/toast'; -import { ISMPRecordStatus, RegionMetadata } from '@/models'; +import { ISMPRecordStatus, RELAY_ASSET_ID, RegionMetadata } from '@/models'; import styles from './index.module.scss'; @@ -199,7 +199,8 @@ export const IsmpRegionCard = ({ regionMetadata }: IsmpRegionProps) => { error: (e) => { toastError(`Failed to request the region record. ${e}`); }, - } + }, + RELAY_ASSET_ID ); }; diff --git a/src/contexts/apis/RegionXApi/index.tsx b/src/contexts/apis/RegionXApi/index.tsx index 48d6b750..f03e8046 100644 --- a/src/contexts/apis/RegionXApi/index.tsx +++ b/src/contexts/apis/RegionXApi/index.tsx @@ -78,6 +78,16 @@ const customRpc = { }, }; +const signedExtensions = { + ChargeAssetTxPayment: { + extrinsic: { + tip: 'Compact', + assetId: 'Option', + }, + payload: {}, + }, +}; + const defaultValue = { state: { ...initialState }, disconnectRegionX: (): void => { @@ -123,7 +133,7 @@ const RegionXApiContextProvider = (props: any) => { } catch { /** empty error handler */ } - connect(state, url, dispatch, true, types, customRpc); + connect(state, url, dispatch, true, types, customRpc, signedExtensions); } }, [network, state]); diff --git a/src/contexts/apis/common.ts b/src/contexts/apis/common.ts index b02c0d8a..89757106 100644 --- a/src/contexts/apis/common.ts +++ b/src/contexts/apis/common.ts @@ -94,7 +94,8 @@ export const connect = ( dispatch: any, newSocket: boolean, types?: any, - customRpc?: any + customRpc?: any, + signedExtensions?: any ) => { const { apiState, jsonrpc } = state; @@ -106,6 +107,7 @@ export const connect = ( provider, rpc: { ...jsonrpc, ...customRpc }, types, + signedExtensions, }); dispatch({ type: 'CONNECT_INIT', socket }); diff --git a/src/hooks/submitExtrinsic.ts b/src/hooks/submitExtrinsic.ts index 6570e508..f6518508 100644 --- a/src/hooks/submitExtrinsic.ts +++ b/src/hooks/submitExtrinsic.ts @@ -4,7 +4,8 @@ import { useConfirm } from 'material-ui-confirm'; import { getBalanceString, sendTx } from '@/utils/functions'; -import { TxStatusHandlers } from '@/models'; +import { NATIVE_ASSET_ID, TxStatusHandlers } from '@/models'; +import { numberToU8a } from '@polkadot/util'; export const useSubmitExtrinsic = () => { const confirm = useConfirm(); @@ -15,9 +16,14 @@ export const useSubmitExtrinsic = () => { tx: SubmittableExtrinsic<'promise', ISubmittableResult>, account: AddressOrPair, signer: Signer, - handlers: TxStatusHandlers + handlers: TxStatusHandlers, + feePaymentAsset: number = NATIVE_ASSET_ID ) => { - const info = await tx.paymentInfo(account.toString()); + console.log(feePaymentAsset); + const info = await tx.paymentInfo( + account.toString(), + feePaymentAsset == NATIVE_ASSET_ID ? {} : { assetId: numberToU8a(feePaymentAsset) } + ); const { partialFee } = info.toPrimitive() as any; confirm({ description: `Estimated gas fee: ${getBalanceString( @@ -25,7 +31,7 @@ export const useSubmitExtrinsic = () => { decimals, symbol )}`, - }).then(() => sendTx(tx, account, signer, handlers)); + }).then(() => sendTx(tx, account, signer, handlers, feePaymentAsset)); }; return { submitExtrinsicWithFeeInfo }; diff --git a/src/models/common/consts.ts b/src/models/common/consts.ts index d1bfa492..e740bf33 100644 --- a/src/models/common/consts.ts +++ b/src/models/common/consts.ts @@ -25,3 +25,6 @@ export const SAFE_XCM_VERSION = 3; export const BROKER_PALLET_ID = 50; export const POOLING_TASK_ID = 0; + +export const NATIVE_ASSET_ID = 0; +export const RELAY_ASSET_ID = 1; diff --git a/src/pages/marketplace.tsx b/src/pages/marketplace.tsx index 94d0db5a..469e122e 100644 --- a/src/pages/marketplace.tsx +++ b/src/pages/marketplace.tsx @@ -29,7 +29,12 @@ import { useRegionXApi } from '@/contexts/apis/RegionXApi'; import { ApiState } from '@/contexts/apis/types'; import { useMarket } from '@/contexts/market'; import { useToast } from '@/contexts/toast'; -import { ContextStatus, Listing, MarketFilterOptions } from '@/models'; +import { + ContextStatus, + Listing, + MarketFilterOptions, + RELAY_ASSET_ID, +} from '@/models'; // eslint-disable-next-line no-unused-vars enum SortOption { @@ -130,7 +135,8 @@ const Marketplace = () => { ); setWorking(false); }, - } + }, + RELAY_ASSET_ID ); }; diff --git a/src/utils/functions/api.ts b/src/utils/functions/api.ts index b85a8c54..e45b36e0 100644 --- a/src/utils/functions/api.ts +++ b/src/utils/functions/api.ts @@ -1,18 +1,25 @@ import { AddressOrPair, SubmittableExtrinsic } from '@polkadot/api/types'; import { ISubmittableResult, Signer } from '@polkadot/types/types'; -import { TxStatusHandlers } from '@/models'; +import { NATIVE_ASSET_ID, TxStatusHandlers } from '@/models'; +import { numberToHex, numberToU8a } from '@polkadot/util'; export const sendTx = async ( tx: SubmittableExtrinsic<'promise', ISubmittableResult>, account: AddressOrPair, signer: Signer, - handlers: TxStatusHandlers + handlers: TxStatusHandlers, + feePaymentAsset: number = NATIVE_ASSET_ID ) => { + const options = + feePaymentAsset == NATIVE_ASSET_ID + ? { signer } + : { signer, assetId: 1, withSignedTransaction: true }; + try { const unsub = await tx.signAndSend( account, - { signer }, + options, ({ status, events }) => { if (status.isReady) handlers.ready(); else if (status.isInBlock) handlers.inBlock(); @@ -30,6 +37,7 @@ export const sendTx = async ( } ); } catch (e) { + console.log(e); handlers.error(e); } finally { handlers.finally && handlers.finally();