Skip to content

Commit

Permalink
Added a new API to update a topic (#493)
Browse files Browse the repository at this point in the history
Signed-off-by: Himalayan Dev <[email protected]>
  • Loading branch information
himalayan-dev authored Jul 11, 2024
1 parent 7906a11 commit 8416eb2
Show file tree
Hide file tree
Showing 10 changed files with 472 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*-
*
* Hedera Wallet Snap
*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { FC, useContext, useRef, useState } from 'react';
import {
MetaMaskContext,
MetamaskActions,
} from '../../../contexts/MetamaskContext';
import useModal from '../../../hooks/useModal';
import { Account, UpdateTopicRequestParams } from '../../../types/snap';
import { shouldDisplayReconnectButton, updateTopic } from '../../../utils';
import { Card, SendHelloButton } from '../../base';
import ExternalAccount, {
GetExternalAccountRef,
} from '../../sections/ExternalAccount';

type Props = {
network: string;
mirrorNodeUrl: string;
setAccountInfo: React.Dispatch<React.SetStateAction<Account>>;
};

const UpdateTopic: FC<Props> = ({ network, mirrorNodeUrl, setAccountInfo }) => {
const [state, dispatch] = useContext(MetaMaskContext);
const [loading, setLoading] = useState(false);
const { showModal } = useModal();
const [topicID, setTopicID] = useState('');
const [memo, setMemo] = useState('');

const externalAccountRef = useRef<GetExternalAccountRef>(null);

const handleUpdateTopicClick = async () => {
setLoading(true);
try {
const externalAccountParams =
externalAccountRef.current?.handleGetAccountParams();

const updateTopicParams = {
topicID,
memo,
} as UpdateTopicRequestParams;

const response: any = await updateTopic(
network,
mirrorNodeUrl,
updateTopicParams,
externalAccountParams,
);

const { receipt, currentAccount } = response;

setAccountInfo(currentAccount);
console.log('receipt: ', receipt);

showModal({
title: 'Transaction Receipt',
content: JSON.stringify({ receipt }, null, 4),
});
} catch (e) {
console.error(e);
dispatch({ type: MetamaskActions.SetError, payload: e });
}
setLoading(false);
};

return (
<Card
content={{
title: 'hcs/updateTopic',
description: 'Update an existing topic',
form: (
<>
<ExternalAccount ref={externalAccountRef} />
<label>
Topic ID:
<input
type="text"
style={{ width: '100%' }}
value={topicID}
placeholder="Enter topic ID"
onChange={(e) => setTopicID(e.target.value)}
/>
</label>
<br />
<label>
Memo (optional):
<input
type="text"
style={{ width: '100%' }}
value={memo}
placeholder="Enter memo"
onChange={(e) => setMemo(e.target.value)}
/>
</label>
<br />
</>
),
button: (
<SendHelloButton
buttonText="Update Topic"
onClick={handleUpdateTopicClick}
disabled={!state.installedSnap}
loading={loading}
/>
),
}}
disabled={!state.installedSnap}
fullWidth={
state.isFlask &&
Boolean(state.installedSnap) &&
!shouldDisplayReconnectButton(state.installedSnap)
}
/>
);
};

export { UpdateTopic };
7 changes: 7 additions & 0 deletions packages/hedera-wallet-snap/packages/site/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import Tokens from '../components/cards/Tokens';
import { TransferCrypto } from '../components/cards/TransferCrypto';
import { UnstakeHbar } from '../components/cards/UnstakeHbar';
import { CreateTopic } from '../components/cards/hcs/CreateTopic';
import { UpdateTopic } from '../components/cards/hcs/UpdateTopic';
import { CallSmartContractFunction } from '../components/cards/hscs/CallSmartContractFunction';
import { CreateSmartContract } from '../components/cards/hscs/CreateSmartContract';
import { DeleteSmartContract } from '../components/cards/hscs/DeleteSmartContract';
Expand Down Expand Up @@ -201,6 +202,12 @@ const Index = () => {
setAccountInfo={setAccountInfo}
/>

<UpdateTopic
network={currentNetwork.value}
mirrorNodeUrl={mirrorNodeUrl}
setAccountInfo={setAccountInfo}
/>

<GetAccountInfo
network={currentNetwork.value}
mirrorNodeUrl={mirrorNodeUrl}
Expand Down
10 changes: 10 additions & 0 deletions packages/hedera-wallet-snap/packages/site/src/types/snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,13 @@ export type CreateTopicRequestParams = {
autoRenewPeriod?: number;
autoRenewAccount?: string;
};

export type UpdateTopicRequestParams = {
topicID: string;
memo?: string;
expirationTime?: number;
adminKey?: string;
submitKey?: string;
autoRenewPeriod?: number;
autoRenewAccount?: string;
};
31 changes: 31 additions & 0 deletions packages/hedera-wallet-snap/packages/site/src/utils/snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import type {
UpdateSmartContractRequestParams,
UpdateTokenFeeScheduleRequestParams,
UpdateTokenRequestParams,
UpdateTopicRequestParams,
WipeTokenRequestParams,
} from '../types/snap';

Expand Down Expand Up @@ -1255,4 +1256,34 @@ export const createTopic = async (
});
};

/**
* Invoke the "updateTopic" method from the snap.
* @param network
* @param mirrorNodeUrl
* @param updateTopicRequestParams
* @param externalAccountparams
*/
export const updateTopic = async (
network: string,
mirrorNodeUrl: string,
updateTopicRequestParams: UpdateTopicRequestParams,
externalAccountparams?: ExternalAccountParams,
) => {
return await window.ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId: defaultSnapOrigin,
request: {
method: 'hcs/updateTopic',
params: {
network,
mirrorNodeUrl,
...updateTopicRequestParams,
...externalAccountparams,
},
},
},
});
};

export const isLocalSnap = (snapId: string) => snapId.startsWith('local:');
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "git+https://github.com/hashgraph/hedera-metamask-snaps.git"
},
"source": {
"shasum": "B7AY3TIR598Hpkjge9P0Cw6ChbU+qAuxaIoFAfuedgk=",
"shasum": "7F6ZMyGJ7JdoSJw0AFaTI3DY6emq2nGBb2cvg9FZ6io=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*-
*
* Hedera Wallet Snap
*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import type { Client } from '@hashgraph/sdk';
import { PublicKey, TopicUpdateTransaction } from '@hashgraph/sdk';
import type { TxReceipt } from '../../types/hedera';
import { Utils } from '../../utils/Utils';

export class UpdateTopicCommand {
readonly #topicID: string;

readonly #memo: string | undefined;

readonly #expirationTime: number | undefined;

readonly #adminKey: string | undefined;

readonly #submitKey: string | undefined;

readonly #autoRenewPeriod: number | undefined;

readonly #autoRenewAccount: string | undefined;

constructor(
topicID: string,
memo?: string,
expirationTime?: number,
adminKey?: string,
submitKey?: string,
autoRenewPeriod?: number,
autoRenewAccount?: string,
) {
this.#topicID = topicID;
this.#memo = memo;
this.#expirationTime = expirationTime;
this.#adminKey = adminKey;
this.#submitKey = submitKey;
this.#autoRenewPeriod = autoRenewPeriod;
this.#autoRenewAccount = autoRenewAccount;
}

public async execute(client: Client): Promise<TxReceipt> {
const transaction = new TopicUpdateTransaction().setTopicId(this.#topicID);

if (this.#memo) {
transaction.setTopicMemo(this.#memo);
}
if (this.#adminKey) {
transaction.setAdminKey(PublicKey.fromString(this.#adminKey));
}
if (this.#submitKey) {
transaction.setSubmitKey(PublicKey.fromString(this.#submitKey));
}
if (this.#autoRenewPeriod) {
transaction.setAutoRenewPeriod(this.#autoRenewPeriod);
}
if (this.#autoRenewAccount) {
transaction.setAutoRenewAccountId(this.#autoRenewAccount);
}
if (this.#expirationTime) {
transaction.setExpirationTime(new Date(this.#expirationTime));
}

return await Utils.executeTransaction(client, transaction);
}
}
Loading

0 comments on commit 8416eb2

Please sign in to comment.