mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-23 08:32:23 +03:00
app_store: publish updates and getnameerror
This commit is contained in:
parent
62bac1e59f
commit
2e6091e205
@ -16,6 +16,7 @@ use std::str::FromStr;
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum AppStoreLogError {
|
pub enum AppStoreLogError {
|
||||||
NoBlockNumber,
|
NoBlockNumber,
|
||||||
|
GetNameError,
|
||||||
DecodeLogError,
|
DecodeLogError,
|
||||||
PackageHashMismatch,
|
PackageHashMismatch,
|
||||||
InvalidPublisherName,
|
InvalidPublisherName,
|
||||||
@ -28,6 +29,7 @@ impl std::fmt::Display for AppStoreLogError {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
AppStoreLogError::NoBlockNumber => write!(f, "log with no block number"),
|
AppStoreLogError::NoBlockNumber => write!(f, "log with no block number"),
|
||||||
|
AppStoreLogError::GetNameError => write!(f, "no corresponding name for namehash found"),
|
||||||
AppStoreLogError::DecodeLogError => write!(f, "error decoding log data"),
|
AppStoreLogError::DecodeLogError => write!(f, "error decoding log data"),
|
||||||
AppStoreLogError::PackageHashMismatch => write!(f, "mismatched package hash"),
|
AppStoreLogError::PackageHashMismatch => write!(f, "mismatched package hash"),
|
||||||
AppStoreLogError::InvalidPublisherName => write!(f, "invalid publisher name"),
|
AppStoreLogError::InvalidPublisherName => write!(f, "invalid publisher name"),
|
||||||
@ -371,8 +373,8 @@ impl State {
|
|||||||
|
|
||||||
// use kns_indexer to convert nodehash to a kimap name
|
// use kns_indexer to convert nodehash to a kimap name
|
||||||
let package_full_path =
|
let package_full_path =
|
||||||
net::get_name(¬e.nodehash.to_string(), log.block_number, Some(5))
|
net::get_name(¬e.nodehash.to_string(), log.block_number, Some(10))
|
||||||
.ok_or(AppStoreLogError::DecodeLogError)?;
|
.ok_or(AppStoreLogError::GetNameError)?;
|
||||||
|
|
||||||
// the app store exclusively looks for ~metadata-uri postings: if one is
|
// the app store exclusively looks for ~metadata-uri postings: if one is
|
||||||
// observed, we then *query* for ~metadata-hash to verify the content
|
// observed, we then *query* for ~metadata-hash to verify the content
|
||||||
|
@ -2,7 +2,7 @@ import { parseAbi } from "viem";
|
|||||||
|
|
||||||
export { encodeMulticalls, encodeIntoMintCall } from "./helpers";
|
export { encodeMulticalls, encodeIntoMintCall } from "./helpers";
|
||||||
|
|
||||||
export const KINOMAP: `0x${string}` = "0x0165878A594ca255338adfa4d48449f69242Eb8F";
|
export const KINOMAP: `0x${string}` = "0x7290Aa297818d0b9660B2871Bb87f85a3f9B4559";
|
||||||
export const MULTICALL: `0x${string}` = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
export const MULTICALL: `0x${string}` = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||||
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0x58790D9957ECE58607A4b58308BBD5FE1a2e4789";
|
export const KINO_ACCOUNT_IMPL: `0x${string}` = "0x58790D9957ECE58607A4b58308BBD5FE1a2e4789";
|
||||||
|
|
||||||
|
@ -10,8 +10,6 @@ import {
|
|||||||
import { WagmiProvider, http } from 'wagmi';
|
import { WagmiProvider, http } from 'wagmi';
|
||||||
import {
|
import {
|
||||||
optimism,
|
optimism,
|
||||||
anvil,
|
|
||||||
mainnet
|
|
||||||
} from 'wagmi/chains';
|
} from 'wagmi/chains';
|
||||||
import {
|
import {
|
||||||
QueryClientProvider,
|
QueryClientProvider,
|
||||||
@ -27,9 +25,7 @@ const config = getDefaultConfig({
|
|||||||
chains: [optimism],
|
chains: [optimism],
|
||||||
ssr: false,
|
ssr: false,
|
||||||
transports: {
|
transports: {
|
||||||
[anvil.id]: http(),
|
|
||||||
[optimism.id]: http(),
|
[optimism.id]: http(),
|
||||||
[mainnet.id]: http(),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ export default function PublishPage() {
|
|||||||
const [publisherId, setPublisherId] = useState<string>(window.our?.node || "");
|
const [publisherId, setPublisherId] = useState<string>(window.our?.node || "");
|
||||||
const [metadataUrl, setMetadataUrl] = useState<string>("");
|
const [metadataUrl, setMetadataUrl] = useState<string>("");
|
||||||
const [metadataHash, setMetadataHash] = useState<string>("");
|
const [metadataHash, setMetadataHash] = useState<string>("");
|
||||||
const [isUpdate, setIsUpdate] = useState<boolean>(false);
|
|
||||||
const [myPublishedApps, setMyPublishedApps] = useState<AppInfo[]>([]);
|
const [myPublishedApps, setMyPublishedApps] = useState<AppInfo[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -33,7 +32,6 @@ export default function PublishPage() {
|
|||||||
if (app) {
|
if (app) {
|
||||||
setPackageName(app.package);
|
setPackageName(app.package);
|
||||||
setPublisherId(app.publisher);
|
setPublisherId(app.publisher);
|
||||||
setIsUpdate(true);
|
|
||||||
}
|
}
|
||||||
}, [state])
|
}, [state])
|
||||||
|
|
||||||
@ -65,26 +63,39 @@ export default function PublishPage() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (!publicClient) {
|
if (!publicClient || !address) {
|
||||||
openConnectModal?.();
|
openConnectModal?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = window.our?.node || "0x";
|
|
||||||
let metadata = metadataHash;
|
|
||||||
|
|
||||||
if (isUpdate) {
|
|
||||||
node = `${packageName}.${window.our?.node || "0x"}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check if the package already exists and get its TBA
|
||||||
let data = await publicClient.readContract({
|
let data = await publicClient.readContract({
|
||||||
abi: kinomapAbi,
|
abi: kinomapAbi,
|
||||||
address: KINOMAP,
|
address: KINOMAP,
|
||||||
functionName: 'get',
|
functionName: 'get',
|
||||||
args: [kinohash(node)]
|
args: [kinohash(`${packageName}.${publisherId}`)]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let [tba, owner, _data] = data as [string, string, string];
|
||||||
|
let isUpdate = Boolean(tba && tba !== '0x' && owner === address);
|
||||||
|
let currentTBA = isUpdate ? tba as `0x${string}` : null;
|
||||||
|
|
||||||
|
// If the package doesn't exist, check for the publisher's TBA
|
||||||
|
if (!currentTBA) {
|
||||||
|
data = await publicClient.readContract({
|
||||||
|
abi: kinomapAbi,
|
||||||
|
address: KINOMAP,
|
||||||
|
functionName: 'get',
|
||||||
|
args: [kinohash(publisherId)]
|
||||||
|
});
|
||||||
|
|
||||||
|
[tba, owner, _data] = data as [string, string, string];
|
||||||
|
isUpdate = false; // It's a new package, but we might have a publisher TBA
|
||||||
|
currentTBA = (tba && tba !== '0x') ? tba as `0x${string}` : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let metadata = metadataHash;
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
const metadataResponse = await fetch(metadataUrl);
|
const metadataResponse = await fetch(metadataUrl);
|
||||||
await metadataResponse.json(); // confirm it's valid JSON
|
await metadataResponse.json(); // confirm it's valid JSON
|
||||||
@ -93,13 +104,11 @@ export default function PublishPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const multicall = encodeMulticalls(metadataUrl, metadata);
|
const multicall = encodeMulticalls(metadataUrl, metadata);
|
||||||
const args = isUpdate ? multicall : encodeIntoMintCall(multicall, address!, packageName);
|
const args = isUpdate ? multicall : encodeIntoMintCall(multicall, address, packageName);
|
||||||
|
|
||||||
const [tba, _owner, _data] = data || [];
|
|
||||||
|
|
||||||
writeContract({
|
writeContract({
|
||||||
abi: mechAbi,
|
abi: mechAbi,
|
||||||
address: tba as `0x${string}`,
|
address: currentTBA || KINOMAP,
|
||||||
functionName: 'execute',
|
functionName: 'execute',
|
||||||
args: [
|
args: [
|
||||||
isUpdate ? MULTICALL : KINOMAP,
|
isUpdate ? MULTICALL : KINOMAP,
|
||||||
@ -115,13 +124,12 @@ export default function PublishPage() {
|
|||||||
setPublisherId(window.our?.node || "");
|
setPublisherId(window.our?.node || "");
|
||||||
setMetadataUrl("");
|
setMetadataUrl("");
|
||||||
setMetadataHash("");
|
setMetadataHash("");
|
||||||
setIsUpdate(false);
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[publicClient, openConnectModal, packageName, publisherId, address, metadataUrl, metadataHash, isUpdate, writeContract]
|
[publicClient, openConnectModal, packageName, publisherId, address, metadataUrl, metadataHash, writeContract]
|
||||||
);
|
);
|
||||||
|
|
||||||
const unpublishPackage = useCallback(
|
const unpublishPackage = useCallback(
|
||||||
@ -132,17 +140,19 @@ export default function PublishPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = `${packageName}.${window.our?.node || "0x"}`;
|
|
||||||
const nodehash = kinohash(node);
|
|
||||||
|
|
||||||
const data = await publicClient.readContract({
|
const data = await publicClient.readContract({
|
||||||
abi: kinomapAbi,
|
abi: kinomapAbi,
|
||||||
address: KINOMAP,
|
address: KINOMAP,
|
||||||
functionName: 'get',
|
functionName: 'get',
|
||||||
args: [nodehash]
|
args: [kinohash(`${packageName}.${publisherName}`)]
|
||||||
});
|
});
|
||||||
|
|
||||||
const [tba, _owner, _data] = data || [];
|
const [tba, _owner, _data] = data as [string, string, string];
|
||||||
|
|
||||||
|
if (!tba || tba === '0x') {
|
||||||
|
console.error("No TBA found for this package");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const multicall = encodeMulticalls("", "");
|
const multicall = encodeMulticalls("", "");
|
||||||
|
|
||||||
@ -165,20 +175,6 @@ export default function PublishPage() {
|
|||||||
[publicClient, openConnectModal, writeContract]
|
[publicClient, openConnectModal, writeContract]
|
||||||
);
|
);
|
||||||
|
|
||||||
const checkIfUpdate = useCallback(() => {
|
|
||||||
if (isUpdate) return;
|
|
||||||
|
|
||||||
if (
|
|
||||||
packageName &&
|
|
||||||
publisherId &&
|
|
||||||
apps.find(
|
|
||||||
(app) => app.package === packageName && app.publisher === publisherId
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
setIsUpdate(true);
|
|
||||||
}
|
|
||||||
}, [apps, packageName, publisherId, isUpdate]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="publish-page">
|
<div className="publish-page">
|
||||||
<h1>Publish Package</h1>
|
<h1>Publish Package</h1>
|
||||||
@ -200,15 +196,6 @@ export default function PublishPage() {
|
|||||||
<div className="message info">Approve connection in your wallet</div>
|
<div className="message info">Approve connection in your wallet</div>
|
||||||
) : (
|
) : (
|
||||||
<form className="publish-form" onSubmit={publishPackage}>
|
<form className="publish-form" onSubmit={publishPackage}>
|
||||||
<div className="form-group">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
id="update"
|
|
||||||
checked={isUpdate}
|
|
||||||
onChange={() => setIsUpdate(!isUpdate)}
|
|
||||||
/>
|
|
||||||
<label htmlFor="update">Update existing package</label>
|
|
||||||
</div>
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="package-name">Package Name</label>
|
<label htmlFor="package-name">Package Name</label>
|
||||||
<input
|
<input
|
||||||
@ -218,7 +205,6 @@ export default function PublishPage() {
|
|||||||
placeholder="my-package"
|
placeholder="my-package"
|
||||||
value={packageName}
|
value={packageName}
|
||||||
onChange={(e) => setPackageName(e.target.value)}
|
onChange={(e) => setPackageName(e.target.value)}
|
||||||
onBlur={checkIfUpdate}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@ -229,7 +215,6 @@ export default function PublishPage() {
|
|||||||
required
|
required
|
||||||
value={publisherId}
|
value={publisherId}
|
||||||
onChange={(e) => setPublisherId(e.target.value)}
|
onChange={(e) => setPublisherId(e.target.value)}
|
||||||
onBlur={checkIfUpdate}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@ -265,7 +250,7 @@ export default function PublishPage() {
|
|||||||
|
|
||||||
{isConfirmed && (
|
{isConfirmed && (
|
||||||
<div className="message success">
|
<div className="message success">
|
||||||
Package {isUpdate ? 'updated' : 'published'} successfully!
|
Package published successfully!
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{error && (
|
{error && (
|
||||||
|
Loading…
Reference in New Issue
Block a user