diff --git a/src/components/cards/NavMenuCard/NavMenuCard.tsx b/src/components/cards/NavMenuCard/NavMenuCard.tsx index cded33137..c5d6ce75d 100644 --- a/src/components/cards/NavMenuCard/NavMenuCard.tsx +++ b/src/components/cards/NavMenuCard/NavMenuCard.tsx @@ -75,7 +75,7 @@ function NavMenuCard() { buildIOBalanceQuery({ address: walletAddress.toString(), arioContract, - meta: [arioProcessId, aoNetwork.CU_URL], + meta: [arioProcessId, aoNetwork.ARIO.CU_URL], }), ); const arBalance = await queryClient.fetchQuery( diff --git a/src/components/devtools/NetworkSettings.tsx b/src/components/devtools/NetworkSettings.tsx index c53b3b881..1559a3459 100644 --- a/src/components/devtools/NetworkSettings.tsx +++ b/src/components/devtools/NetworkSettings.tsx @@ -28,12 +28,23 @@ function NetworkSettings() { const [{ wallet }] = useWalletState(); const [newGateway, setNewGateway] = useState(gateway); const [validGateway, setValidGateway] = useState(true); - const [newCuUrl, setNewCuUrl] = useState(NETWORK_DEFAULTS.AO.CU_URL); - const [validCuUrl, setValidCuUrl] = useState(true); - const [newMuUrl, setNewMuUrl] = useState(NETWORK_DEFAULTS.AO.MU_URL); + + const [newARIOCuUrl, setNewARIOCuUrl] = useState( + NETWORK_DEFAULTS.AO.ARIO.CU_URL, + ); + const [validARIOCuUrl, setValidARIOCuUrl] = useState(true); + + const [newANTCuUrl, setNewANTCuUrl] = useState( + NETWORK_DEFAULTS.AO.ANT.CU_URL, + ); + const [validANTCuUrl, setValidANTCuUrl] = useState(true); + + const [newMuUrl, setNewMuUrl] = useState( + NETWORK_DEFAULTS.AO.ARIO.MU_URL, + ); const [validMuUrl, setValidMuUrl] = useState(true); const [newSuAddress, setNewSuAddress] = useState( - NETWORK_DEFAULTS.AO.SCHEDULER, + NETWORK_DEFAULTS.AO.ARIO.SCHEDULER, ); const [validSuAddress, setValidSuAddress] = useState(true); const [showGatewayModal, setShowGatewayModal] = useState(false); @@ -44,16 +55,16 @@ function NetworkSettings() { setValidGateway(true); updateGateway(NETWORK_DEFAULTS.ARWEAVE.HOST); // ao network - setNewCuUrl(NETWORK_DEFAULTS.AO.CU_URL); - setValidCuUrl(true); - setNewMuUrl(NETWORK_DEFAULTS.AO.MU_URL); + setNewARIOCuUrl(NETWORK_DEFAULTS.AO.ARIO.CU_URL); + setValidARIOCuUrl(true); + setNewMuUrl(NETWORK_DEFAULTS.AO.ARIO.MU_URL); setValidMuUrl(true); - setNewSuAddress(NETWORK_DEFAULTS.AO.SCHEDULER); + setNewSuAddress(NETWORK_DEFAULTS.AO.ARIO.SCHEDULER); setValidSuAddress(true); - updateAoNetwork({ - CU_URL: NETWORK_DEFAULTS.AO.CU_URL, - MU_URL: NETWORK_DEFAULTS.AO.MU_URL, - SCHEDULER: NETWORK_DEFAULTS.AO.SCHEDULER, + updateARIOAoNetwork({ + CU_URL: NETWORK_DEFAULTS.AO.ARIO.CU_URL, + MU_URL: NETWORK_DEFAULTS.AO.ARIO.MU_URL, + SCHEDULER: NETWORK_DEFAULTS.AO.ARIO.SCHEDULER, }); } @@ -63,13 +74,13 @@ function NetworkSettings() { }, [gateway]); useEffect(() => { - setNewCuUrl(aoNetwork.CU_URL); - setValidCuUrl(true); - setNewMuUrl(aoNetwork.MU_URL); + setNewARIOCuUrl(aoNetwork.ARIO.CU_URL); + setValidARIOCuUrl(true); + setNewMuUrl(aoNetwork.ARIO.MU_URL); setValidMuUrl(true); - setNewSuAddress(aoNetwork.SCHEDULER); + setNewSuAddress(aoNetwork.ARIO.SCHEDULER); setValidSuAddress(true); - }, [aoNetwork]); + }, [aoNetwork.ARIO]); async function updateGateway(gate: string) { try { @@ -93,7 +104,7 @@ function NetworkSettings() { } } - function updateAoNetwork(config: { + function updateARIOAoNetwork(config: { CU_URL?: string; MU_URL?: string; SCHEDULER?: string; @@ -101,8 +112,7 @@ function NetworkSettings() { try { const newConfig = { ...aoNetwork, - ...config, - GATEWAY_URL: gateway, + ...{ ARIO: { ...aoNetwork.ARIO, ...config, GATEWAY_URL: gateway } }, }; dispatchGlobalState({ type: 'setAONetwork', @@ -111,11 +121,11 @@ function NetworkSettings() { const ao = connect({ GATEWAY_URL: 'https://' + gateway, - CU_URL: newConfig.CU_URL, - MU_URL: newConfig.MU_URL, + CU_URL: newConfig.ARIO.CU_URL, + MU_URL: newConfig.ARIO.MU_URL, }); dispatchGlobalState({ - type: 'setAoClient', + type: 'setARIOAoClient', payload: ao, }); dispatchArIOContract({ @@ -133,6 +143,30 @@ function NetworkSettings() { } } + function updateANTAoNetwork(config: { CU_URL?: string }) { + try { + const newConfig = { + ...aoNetwork, + ...{ ANT: { ...aoNetwork.ANT, ...config } }, + }; + dispatchGlobalState({ + type: 'setAONetwork', + payload: newConfig, + }); + + const ao = connect({ + GATEWAY_URL: 'https://' + gateway, + CU_URL: newConfig.ANT.CU_URL, + }); + dispatchGlobalState({ + type: 'setANTAoClient', + payload: ao, + }); + } catch (error) { + eventEmitter.emit('error', error); + } + } + return (
@@ -208,42 +242,90 @@ function NetworkSettings() { } /> - CU URL:{' '} - {aoNetwork.CU_URL} + ARIO CU URL:{' '} + {aoNetwork.ARIO.CU_URL} { - setValidCuUrl(isValidURL(e.target.value.trim())); - setNewCuUrl(e.target.value.trim()); + setValidARIOCuUrl(isValidURL(e.target.value.trim())); + setNewARIOCuUrl(e.target.value.trim()); }} - onClear={() => setNewCuUrl('')} + onClear={() => setNewARIOCuUrl('')} onPressEnter={(e) => - updateAoNetwork({ + updateARIOAoNetwork({ CU_URL: e.currentTarget.value.trim(), }) } variant="outlined" - status={validCuUrl ? '' : 'error'} + status={validARIOCuUrl ? '' : 'error'} addonAfter={
+
+ } + /> + + ANT CU URL:{' '} + {aoNetwork.ANT.CU_URL} + + { + setValidANTCuUrl(isValidURL(e.target.value.trim())); + setNewANTCuUrl(e.target.value.trim()); + }} + onClear={() => setNewANTCuUrl('')} + onPressEnter={(e) => + updateANTAoNetwork({ + CU_URL: e.currentTarget.value.trim(), + }) + } + variant="outlined" + status={validANTCuUrl ? '' : 'error'} + addonAfter={ +
+ + - ), - dataIndex: 'name', - key: 'name', - align: 'left', - width: '18%', - className: 'grey manage-assets-table-header', - ellipsis: true, - onHeaderCell: () => { - return { - onClick: () => { - rows.sort((a: UndernameMetadata, b: UndernameMetadata) => - // by default we sort by name - !sortAscending - ? a.name.localeCompare(b.name) - : b.name.localeCompare(a.name), - ); - // forces update of rows - setRows([...rows]); - setSortOrder(!sortAscending); - }, - }; - }, - render: (val: string, row: UndernameMetadata) => ( - - {val} - - ), - }, - { - title: ( - - ), - dataIndex: 'targetID', - key: 'targetID', - align: 'left', - width: '18%', - className: 'grey manage-assets-table-header', - render: (val: string) => - val === 'N/A' || !isArweaveTransactionID(val) ? ( - val - ) : ( - - ), - onHeaderCell: () => { - return { - onClick: () => { - rows.sort((a: any, b: any) => - sortAscending - ? a.targetID.localeCompare(b.targetID) - : b.targetID.localeCompare(a.targetID), - ); - // forces update of rows - setRows([...rows]); - setSortOrder(!sortAscending); - }, - }; - }, - }, - { - title: ( - - ), - dataIndex: 'ttlSeconds', - key: 'ttlSeconds', - align: 'left', - width: '18%', - className: 'grey manage-assets-table-header', - render: (val: string) => val, - onHeaderCell: () => { - return { - onClick: () => { - rows.sort((a: any, b: any) => - sortAscending - ? a.ttlSeconds - b.ttlSeconds - : b.ttlSeconds - a.ttlSeconds, - ); - // forces update of rows - setRows([...rows]); - setSortOrder(!sortAscending); - }, - }; - }, - }, - { - title: ( -
- - {searchOpen ? ( - - setSearchText(e)} - catchInvalidInput={true} - showValidationIcon={false} - placeholder={'Search for a name'} - maxCharLength={61} - wrapperCustomStyle={{ - position: 'relative', - boxSizing: 'border-box', - }} - inputCustomStyle={{ - width: '100%', - minWidth: '100px', - overflow: 'hidden', - fontSize: '13px', - outline: 'none', - color: 'white', - alignContent: 'center', - borderBottom: 'none', - boxSizing: 'border-box', - background: 'transparent', - borderRadius: 'var(--corner-radius)', - border: 'none', - paddingRight: '10px', - }} - customPattern={ARNS_NAME_REGEX_PARTIAL} - validationPredicates={{}} - /> - - - ) : ( - <> - )} -
- ), - className: 'manage-assets-table-header', - render: (value, row) => ( -
- {isAuthorized && ( - <> - - - - - - - - - )} -
- ), - align: 'right', - width: '10%', - key: 'action', - dataIndex: 'action', - }, - ]; - return newColumns; - } - - async function fetchUndernameRows( - id?: ArweaveTransactionID, - name?: string, - ): Promise { - let processId: ArweaveTransactionID | undefined = undefined; - if (id) { - processId = id; - } else if (name) { - const arnsRecord = domains[name]; - if (arnsRecord) - processId = new ArweaveTransactionID(arnsRecord.processId); - } - - if (!processId) { - setIsLoading(false); - return; - } - setIsLoading(true); - const domain = Object.keys(domains).find( - (d) => domains[d].processId === processId?.toString(), - ); - const state = await ANT.init({ - processId: processId.toString(), - }).getState(); - - const rows = Object.entries(state.Records) - .map(([name, record]) => - name === '@' - ? undefined - : { - domain, - name, - targetID: record.transactionId, - ttlSeconds: record.ttlSeconds, - status: 0, - key: name, - }, - ) - .filter((row) => row !== undefined) - .sort((a, b) => a!.status - b!.status); - setRows(rows as UndernameMetadata[]); - const authorized = walletAddress - ? state.Controllers.includes(walletAddress.toString()) || - state.Owner === walletAddress.toString() - : false; - setIsAuthorized(authorized); - setIsLoading(false); - } - - return { - isLoading, - columns, - rows: filteredResults.length ? filteredResults : rows, - sortField, - sortAscending, - selectedRow, - action, - setAction: (action: UNDERNAME_TABLE_ACTIONS | undefined) => - setAction(action), - refresh: () => fetchUndernameRows(id, name), - }; -} diff --git a/src/state/actions/dispatchANTInteraction.ts b/src/state/actions/dispatchANTInteraction.ts index ca4b5a662..936771a7c 100644 --- a/src/state/actions/dispatchANTInteraction.ts +++ b/src/state/actions/dispatchANTInteraction.ts @@ -1,4 +1,11 @@ -import { ANT, ARIO, AoMessageResult, ContractSigner } from '@ar.io/sdk/web'; +import { + ANT, + AOProcess, + ARIO, + AoClient, + AoMessageResult, + ContractSigner, +} from '@ar.io/sdk/web'; import { TransactionAction } from '@src/state/reducers/TransactionReducer'; import { ANT_INTERACTION_TYPES, ContractInteraction } from '@src/types'; import { lowerCaseDomain } from '@src/utils'; @@ -13,6 +20,7 @@ export default async function dispatchANTInteraction({ signer, owner, dispatch, + ao, }: { payload: Record; workflowName: ANT_INTERACTION_TYPES; @@ -20,6 +28,7 @@ export default async function dispatchANTInteraction({ owner: string; processId: string; dispatch: Dispatch; + ao: AoClient; }): Promise { let result: AoMessageResult | undefined = undefined; const aoCongestedTimeout = setTimeout( @@ -29,7 +38,7 @@ export default async function dispatchANTInteraction({ 1000 * 10, ); const antProcess = ANT.init({ - processId: processId, + process: new AOProcess({ processId, ao }), signer, }); const dispatchSigningMessage = (message?: string) => { diff --git a/src/state/actions/dispatchANTUpdate.ts b/src/state/actions/dispatchANTUpdate.ts index 88c6bfdae..704589948 100644 --- a/src/state/actions/dispatchANTUpdate.ts +++ b/src/state/actions/dispatchANTUpdate.ts @@ -1,4 +1,4 @@ -import { ANT } from '@ar.io/sdk'; +import { ANT, AOProcess, AoClient } from '@ar.io/sdk'; import { AoAddress } from '@src/types'; import eventEmitter from '@src/utils/events'; import { buildAntStateQuery } from '@src/utils/network'; @@ -12,23 +12,27 @@ export async function dispatchANTUpdate({ processId, walletAddress, dispatch, + ao, }: { queryClient: QueryClient; processId: string; walletAddress: AoAddress; dispatch: Dispatch; + ao: AoClient; }) { try { dispatch({ type: 'setLoading', payload: true, }); - const antStateQuery = buildAntStateQuery({ processId }); + const antStateQuery = buildAntStateQuery({ processId, ao }); const state = await queryClient.fetchQuery(antStateQuery); const handlers = await queryClient.fetchQuery({ queryKey: ['handlers', processId], queryFn: async () => { - return await ANT.init({ processId }).getHandlers().catch(console.error); + return await ANT.init({ process: new AOProcess({ processId, ao }) }) + .getHandlers() + .catch(console.error); }, }); diff --git a/src/state/actions/dispatchArIOInteraction.ts b/src/state/actions/dispatchArIOInteraction.ts index c58662b78..cccc44dec 100644 --- a/src/state/actions/dispatchArIOInteraction.ts +++ b/src/state/actions/dispatchArIOInteraction.ts @@ -31,6 +31,7 @@ export default async function dispatchArIOInteraction({ dispatch, signer, ao, + antAo, scheduler = DEFAULT_SCHEDULER_ID, }: { payload: Record; @@ -41,6 +42,7 @@ export default async function dispatchArIOInteraction({ dispatch: Dispatch; signer?: ContractSigner; ao?: AoClient; + antAo?: AoClient; scheduler?: string; }): Promise { let result: AoMessageResult | undefined = undefined; @@ -157,7 +159,7 @@ export default async function dispatchArIOInteraction({ const antProcess = ANT.init({ signer, process: new AOProcess({ - ao, + ao: antAo, processId: payload.antProcessId, }), }); diff --git a/src/state/actions/dispatchArNSUpdate.ts b/src/state/actions/dispatchArNSUpdate.ts index 5b6ed0359..25638a5ac 100644 --- a/src/state/actions/dispatchArNSUpdate.ts +++ b/src/state/actions/dispatchArNSUpdate.ts @@ -1,5 +1,6 @@ import { ANT, + AOProcess, AoANTHandler, AoANTState, AoClient, @@ -20,12 +21,14 @@ export function dispatchArNSUpdate({ walletAddress, arioProcessId, ao, + antAo, }: { emitter: ArNSEventEmitter; dispatch: Dispatch; walletAddress: AoAddress; arioProcessId: string; ao: AoClient; + antAo: AoClient; }) { dispatch({ type: 'setDomains', payload: {} }); dispatch({ type: 'setAnts', payload: {} }); @@ -64,7 +67,7 @@ export function dispatchArNSUpdate({ } return await ANT.init({ - processId: id, + process: new AOProcess({ processId: id, ao: antAo }), }) .getHandlers() .catch(console.error); diff --git a/src/state/contexts/GlobalState.tsx b/src/state/contexts/GlobalState.tsx index b366c45cc..5b235a6e4 100644 --- a/src/state/contexts/GlobalState.tsx +++ b/src/state/contexts/GlobalState.tsx @@ -18,7 +18,7 @@ import React, { import { ArweaveCompositeDataProvider } from '../../services/arweave/ArweaveCompositeDataProvider'; import { SimpleArweaveDataProvider } from '../../services/arweave/SimpleArweaveDataProvider'; import { - AO_CU_URL, + ARIO_AO_CU_URL, ARIO_PROCESS_ID, ARWEAVE_HOST, DEFAULT_ARWEAVE, @@ -31,7 +31,7 @@ export const defaultArIO = ARIO.init({ process: new AOProcess({ processId: ARIO_PROCESS_ID, ao: connect({ - CU_URL: AO_CU_URL, + CU_URL: ARIO_AO_CU_URL, }), }), }); @@ -40,11 +40,17 @@ export type GlobalState = { arioTicker: string; gateway: string; aoNetwork: { - CU_URL: string; - MU_URL: string; - SCHEDULER: string; + ARIO: { + CU_URL: string; + MU_URL: string; + SCHEDULER: string; + }; + ANT: { + CU_URL: string; + }; }; aoClient: AoClient; + antAoClient: AoClient; arioProcessId: string; blockHeight?: number; lastBlockUpdateTimestamp?: number; @@ -57,7 +63,8 @@ const initialState: GlobalState = { arioTicker: 'ARIO', gateway: ARWEAVE_HOST, aoNetwork: NETWORK_DEFAULTS.AO, - aoClient: connect(NETWORK_DEFAULTS.AO), + aoClient: connect(NETWORK_DEFAULTS.AO.ARIO), + antAoClient: connect(NETWORK_DEFAULTS.AO.ANT), blockHeight: undefined, lastBlockUpdateTimestamp: undefined, arweaveDataProvider: new ArweaveCompositeDataProvider({ diff --git a/src/state/reducers/GlobalReducer.ts b/src/state/reducers/GlobalReducer.ts index 6a7b324a4..372771dec 100644 --- a/src/state/reducers/GlobalReducer.ts +++ b/src/state/reducers/GlobalReducer.ts @@ -14,13 +14,16 @@ export type GlobalAction = | { type: 'setAONetwork'; payload: { - CU_URL?: string; - MU_URL?: string; - SCHEDULER?: string; + ARIO?: { CU_URL: string; MU_URL: string; SCHEDULER: string }; + ANT?: { CU_URL: string }; }; } | { - type: 'setAoClient'; + type: 'setARIOAoClient'; + payload: AoClient; + } + | { + type: 'setANTAoClient'; payload: AoClient; } | { @@ -59,11 +62,16 @@ export const reducer = ( ...action.payload, }, }; - case 'setAoClient': + case 'setARIOAoClient': return { ...state, aoClient: action.payload, }; + case 'setANTAoClient': + return { + ...state, + antAoClient: action.payload, + }; case 'setBlockHeight': return { ...state, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index ce0132595..e3d243759 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -92,13 +92,25 @@ export const ARIO_PROCESS_ID = process.env.VITE_ARIO_PROCESS_ID || arioDevnetProcessId; export const DEFAULT_ANT_LUA_ID = ANT_LUA_ID; -export const AO_CU_URL = process.env.VITE_AO_CU_URL || 'https://cu.ardrive.io'; +export const ARIO_AO_CU_URL = + process.env.VITE_ARIO_AO_CU_URL || 'https://cu.ardrive.io'; + +export const ANT_AO_CU_URL = + process.env.VITE_ARIO_AO_CU_URL || 'https://cu.ao-testnet.xyz'; export const NETWORK_DEFAULTS = { AO: { - CU_URL: AO_CU_URL, // ao public cu: https://cu.ao-testnet.xyz - MU_URL: 'https://mu.ao-testnet.xyz', - SCHEDULER: DEFAULT_SCHEDULER_ID, + ARIO: { + CU_URL: ARIO_AO_CU_URL, // ao public cu: https://cu.ao-testnet.xyz + MU_URL: 'https://mu.ao-testnet.xyz', + SCHEDULER: DEFAULT_SCHEDULER_ID, + }, + + ANT: { + CU_URL: ANT_AO_CU_URL, + MU_URL: 'https://mu.ao-testnet.xyz', + SCHEDULER: DEFAULT_SCHEDULER_ID, + }, }, ARWEAVE: { HOST: ARWEAVE_HOST, diff --git a/src/utils/network.ts b/src/utils/network.ts index fa060f370..a239fd69d 100644 --- a/src/utils/network.ts +++ b/src/utils/network.ts @@ -1,8 +1,10 @@ import { ANT, + AOProcess, AoANTState, AoARIORead, AoArNSNameData, + AoClient, fetchAllArNSRecords, mARIOToken, } from '@ar.io/sdk/web'; @@ -46,9 +48,11 @@ export const queryClient = new QueryClient({ export function buildAntStateQuery({ processId, + ao, meta, }: { processId: string; + ao: AoClient; meta?: string[]; }): { queryKey: ['ant', string] | string[]; @@ -60,7 +64,7 @@ export function buildAntStateQuery({ queryFn: async () => { if (!processId) return null; if (isArweaveTransactionID(processId)) { - const ant = ANT.init({ processId }); + const ant = ANT.init({ process: new AOProcess({ processId, ao }) }); return ant.getState().catch((e) => { eventEmitter.emit( 'error',