Display project URLs in Overview tab (#20)
All checks were successful
Lint / lint (20.x) (push) Successful in 4m32s
All checks were successful
Lint / lint (20.x) (push) Successful in 4m32s
Part of [Service provider auctions for web deployments](https://www.notion.so/Service-provider-auctions-for-web-deployments-104a6b22d47280dbad51d28aa3a91d75) - Fix project create not working after failed tx - Poll for project details for auction details - Update wallet connect metadata ![image](/attachments/cd0217c9-8a2f-4bc5-ad4c-2654fa92f958) Co-authored-by: Neeraj <neeraj.rtly@gmail.com> Co-authored-by: Shreerang Kale <shreerangkale@gmail.com> Co-authored-by: IshaVenikar <ishavenikar7@gmail.com> Reviewed-on: #20
This commit is contained in:
parent
0f18bc978e
commit
05bd766133
@ -140,6 +140,7 @@ export class Database {
|
|||||||
)
|
)
|
||||||
.leftJoinAndSelect('deployments.createdBy', 'user')
|
.leftJoinAndSelect('deployments.createdBy', 'user')
|
||||||
.leftJoinAndSelect('deployments.domain', 'domain')
|
.leftJoinAndSelect('deployments.domain', 'domain')
|
||||||
|
.leftJoinAndSelect('deployments.deployer', 'deployer')
|
||||||
.leftJoinAndSelect('project.owner', 'owner')
|
.leftJoinAndSelect('project.owner', 'owner')
|
||||||
.leftJoinAndSelect('project.deployers', 'deployers')
|
.leftJoinAndSelect('project.deployers', 'deployers')
|
||||||
.leftJoinAndSelect('project.organization', 'organization')
|
.leftJoinAndSelect('project.organization', 'organization')
|
||||||
|
@ -143,6 +143,7 @@ type Deployer {
|
|||||||
paymentAddress: String
|
paymentAddress: String
|
||||||
createdAt: String!
|
createdAt: String!
|
||||||
updatedAt: String!
|
updatedAt: String!
|
||||||
|
baseDomain: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthResult {
|
type AuthResult {
|
||||||
|
@ -70,6 +70,7 @@ const Configure = () => {
|
|||||||
maxPrice: DEFAULT_MAX_PRICE,
|
maxPrice: DEFAULT_MAX_PRICE,
|
||||||
lrn: '',
|
lrn: '',
|
||||||
numProviders: 1,
|
numProviders: 1,
|
||||||
|
variables: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -173,100 +174,110 @@ const Configure = () => {
|
|||||||
|
|
||||||
const handleFormSubmit = useCallback(
|
const handleFormSubmit = useCallback(
|
||||||
async (createFormData: FieldValues) => {
|
async (createFormData: FieldValues) => {
|
||||||
const deployerLrn = createFormData.lrn;
|
try {
|
||||||
const deployer = deployers.find(
|
const deployerLrn = createFormData.lrn;
|
||||||
(deployer) => deployer.deployerLrn === deployerLrn,
|
const deployer = deployers.find(
|
||||||
);
|
(deployer) => deployer.deployerLrn === deployerLrn,
|
||||||
|
|
||||||
let amount: string;
|
|
||||||
let senderAddress: string;
|
|
||||||
let txHash: string;
|
|
||||||
if (createFormData.option === 'LRN' && !deployer?.minimumPayment) {
|
|
||||||
toast({
|
|
||||||
id: 'no-payment-required',
|
|
||||||
title: 'No payment required. Deploying app...',
|
|
||||||
variant: 'info',
|
|
||||||
onDismiss: dismiss,
|
|
||||||
});
|
|
||||||
|
|
||||||
txHash = '';
|
|
||||||
senderAddress = '';
|
|
||||||
} else {
|
|
||||||
if (!selectedAccount) return;
|
|
||||||
|
|
||||||
senderAddress = selectedAccount.split(':')[2];
|
|
||||||
|
|
||||||
if (createFormData.option === 'LRN') {
|
|
||||||
amount = deployer?.minimumPayment!;
|
|
||||||
} else {
|
|
||||||
amount = (
|
|
||||||
createFormData.numProviders * createFormData.maxPrice
|
|
||||||
).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
const amountToBePaid = amount.replace(/\D/g, '').toString();
|
|
||||||
|
|
||||||
const txHashResponse = await cosmosSendTokensHandler(
|
|
||||||
selectedAccount,
|
|
||||||
amountToBePaid,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!txHashResponse) {
|
let amount: string;
|
||||||
console.error('Tx not successful');
|
let senderAddress: string;
|
||||||
return;
|
let txHash: string;
|
||||||
|
if (createFormData.option === 'LRN' && !deployer?.minimumPayment) {
|
||||||
|
toast({
|
||||||
|
id: 'no-payment-required',
|
||||||
|
title: 'No payment required. Deploying app...',
|
||||||
|
variant: 'info',
|
||||||
|
onDismiss: dismiss,
|
||||||
|
});
|
||||||
|
|
||||||
|
txHash = '';
|
||||||
|
senderAddress = '';
|
||||||
|
} else {
|
||||||
|
if (!selectedAccount) return;
|
||||||
|
|
||||||
|
senderAddress = selectedAccount.split(':')[2];
|
||||||
|
|
||||||
|
if (createFormData.option === 'LRN') {
|
||||||
|
amount = deployer?.minimumPayment!;
|
||||||
|
} else {
|
||||||
|
amount = (
|
||||||
|
createFormData.numProviders * createFormData.maxPrice
|
||||||
|
).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const amountToBePaid = amount.replace(/\D/g, '').toString();
|
||||||
|
|
||||||
|
const txHashResponse = await cosmosSendTokensHandler(
|
||||||
|
selectedAccount,
|
||||||
|
amountToBePaid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!txHashResponse) {
|
||||||
|
console.error('Tx not successful');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
txHash = txHashResponse;
|
||||||
|
|
||||||
|
const isTxHashValid = await verifyTx(
|
||||||
|
senderAddress,
|
||||||
|
txHash,
|
||||||
|
amountToBePaid.toString(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isTxHashValid === false) {
|
||||||
|
console.error('Invalid Tx hash', txHash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
txHash = txHashResponse;
|
const environmentVariables = createFormData.variables.map(
|
||||||
|
(variable: any) => {
|
||||||
|
return {
|
||||||
|
key: variable.key,
|
||||||
|
value: variable.value,
|
||||||
|
environments: Object.entries(createFormData.environment)
|
||||||
|
.filter(([, value]) => value === true)
|
||||||
|
.map(([key]) => key.charAt(0).toUpperCase() + key.slice(1)),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const isTxHashValid = await verifyTx(
|
const projectId = await createProject(
|
||||||
|
createFormData,
|
||||||
|
environmentVariables,
|
||||||
senderAddress,
|
senderAddress,
|
||||||
txHash,
|
txHash,
|
||||||
amountToBePaid.toString(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isTxHashValid === false) {
|
await client.getEnvironmentVariables(projectId);
|
||||||
console.error('Invalid Tx hash', txHash);
|
|
||||||
return;
|
if (templateId) {
|
||||||
|
createFormData.option === 'Auction'
|
||||||
|
? navigate(
|
||||||
|
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
|
||||||
|
)
|
||||||
|
: navigate(
|
||||||
|
`/${orgSlug}/projects/create/template/deploy?projectId=${projectId}&templateId=${templateId}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
createFormData.option === 'Auction'
|
||||||
|
? navigate(
|
||||||
|
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
|
||||||
|
)
|
||||||
|
: navigate(
|
||||||
|
`/${orgSlug}/projects/create/deploy?projectId=${projectId}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
const environmentVariables = createFormData.variables.map(
|
toast({
|
||||||
(variable: any) => {
|
id: 'error-deploying-app',
|
||||||
return {
|
title: 'Error deploying app',
|
||||||
key: variable.key,
|
variant: 'error',
|
||||||
value: variable.value,
|
onDismiss: dismiss,
|
||||||
environments: Object.entries(createFormData.environment)
|
});
|
||||||
.filter(([, value]) => value === true)
|
|
||||||
.map(([key]) => key.charAt(0).toUpperCase() + key.slice(1)),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const projectId = await createProject(
|
|
||||||
createFormData,
|
|
||||||
environmentVariables,
|
|
||||||
senderAddress,
|
|
||||||
txHash,
|
|
||||||
);
|
|
||||||
|
|
||||||
await client.getEnvironmentVariables(projectId);
|
|
||||||
|
|
||||||
if (templateId) {
|
|
||||||
createFormData.option === 'Auction'
|
|
||||||
? navigate(
|
|
||||||
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
|
|
||||||
)
|
|
||||||
: navigate(
|
|
||||||
`/${orgSlug}/projects/create/template/deploy?projectId=${projectId}&templateId=${templateId}`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
createFormData.option === 'Auction'
|
|
||||||
? navigate(
|
|
||||||
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
|
|
||||||
)
|
|
||||||
: navigate(
|
|
||||||
`/${orgSlug}/projects/create/deploy?projectId=${projectId}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[client, createProject, dismiss, toast],
|
[client, createProject, dismiss, toast],
|
||||||
@ -281,10 +292,13 @@ const Configure = () => {
|
|||||||
setSelectedAccount(account);
|
setSelectedAccount(account);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onDeployerChange = useCallback((selectedLrn: string) => {
|
const onDeployerChange = useCallback(
|
||||||
const deployer = deployers.find((d) => d.deployerLrn === selectedLrn);
|
(selectedLrn: string) => {
|
||||||
setSelectedDeployer(deployer);
|
const deployer = deployers.find((d) => d.deployerLrn === selectedLrn);
|
||||||
}, [deployers]);
|
setSelectedDeployer(deployer);
|
||||||
|
},
|
||||||
|
[deployers],
|
||||||
|
);
|
||||||
|
|
||||||
const cosmosSendTokensHandler = useCallback(
|
const cosmosSendTokensHandler = useCallback(
|
||||||
async (selectedAccount: string, amount: string) => {
|
async (selectedAccount: string, amount: string) => {
|
||||||
@ -496,8 +510,7 @@ const Configure = () => {
|
|||||||
<EnvironmentVariablesForm />
|
<EnvironmentVariablesForm />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedOption === 'LRN' &&
|
{selectedOption === 'LRN' && !selectedDeployer?.minimumPayment ? (
|
||||||
!selectedDeployer?.minimumPayment ? (
|
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
{...buttonSize}
|
{...buttonSize}
|
||||||
|
@ -42,31 +42,31 @@ export const AuctionCard = ({ project }: { project: Project }) => {
|
|||||||
<LoadingIcon className="animate-spin" />
|
<LoadingIcon className="animate-spin" />
|
||||||
);
|
);
|
||||||
|
|
||||||
const checkAuctionStatus = useCallback(async () => {
|
const checkAuctionStatus = useCallback(async () => {
|
||||||
const result = await client.getAuctionData(project.auctionId);
|
const result = await client.getAuctionData(project.auctionId);
|
||||||
setAuctionStatus(result.status);
|
setAuctionStatus(result.status);
|
||||||
setAuctionDetails(result);
|
setAuctionDetails(result);
|
||||||
setDeployers(project.deployers);
|
}, [project.auctionId, project.deployers, project.fundsReleased]);
|
||||||
setFundsStatus(project.fundsReleased);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchUpdatedProject = useCallback(async () => {
|
||||||
if (auctionStatus !== 'completed') {
|
const updatedProject = await client.getProject(project.id);
|
||||||
checkAuctionStatus();
|
setDeployers(updatedProject.project!.deployers!);
|
||||||
const intervalId = setInterval(checkAuctionStatus, WAIT_DURATION);
|
setFundsStatus(updatedProject.project!.fundsReleased!);
|
||||||
return () => clearInterval(intervalId);
|
}, [project.id]);
|
||||||
}
|
|
||||||
|
|
||||||
if (auctionStatus === 'completed') {
|
const fetchData = useCallback(async () => {
|
||||||
const fetchUpdatedProject = async () => {
|
await Promise.all([checkAuctionStatus(), fetchUpdatedProject()]);
|
||||||
// Wait for 5 secs since the project is not immediately updated with deployer LRNs
|
}, [checkAuctionStatus, fetchUpdatedProject]);
|
||||||
await new Promise((resolve) => setTimeout(resolve, WAIT_DURATION));
|
|
||||||
const updatedProject = await client.getProject(project.id);
|
useEffect(() => {
|
||||||
setDeployers(updatedProject.project?.deployers || []);
|
fetchData();
|
||||||
};
|
|
||||||
fetchUpdatedProject();
|
const timerId = setInterval(() => {
|
||||||
}
|
fetchData();
|
||||||
}, [auctionStatus, client]);
|
}, WAIT_DURATION);
|
||||||
|
|
||||||
|
return () => clearInterval(timerId);
|
||||||
|
}, [fetchData]);
|
||||||
|
|
||||||
const renderAuctionStatus = useCallback(
|
const renderAuctionStatus = useCallback(
|
||||||
() => (
|
() => (
|
||||||
@ -134,7 +134,7 @@ export const AuctionCard = ({ project }: { project: Project }) => {
|
|||||||
size="xs"
|
size="xs"
|
||||||
type={fundsStatus ? 'positive' : 'emphasized'}
|
type={fundsStatus ? 'positive' : 'emphasized'}
|
||||||
>
|
>
|
||||||
{fundsStatus ? 'RELEASED' : 'LOCKED'}
|
{fundsStatus ? 'RELEASED' : 'WAITING'}
|
||||||
</Tag>
|
</Tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,8 +31,8 @@ const axiosInstance = axios.create({
|
|||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
const metadata = {
|
const metadata = {
|
||||||
name: 'Web3Modal',
|
name: 'Deploy App Auth',
|
||||||
description: 'Snowball Web3Modal',
|
description: '',
|
||||||
url: window.location.origin,
|
url: window.location.origin,
|
||||||
icons: ['https://avatars.githubusercontent.com/u/37784886'],
|
icons: ['https://avatars.githubusercontent.com/u/37784886'],
|
||||||
};
|
};
|
||||||
|
@ -41,6 +41,7 @@ const deployment: Deployment = {
|
|||||||
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
||||||
deployerLrn: 'lrn://example/deployers/webapp-deployer-api.example.com',
|
deployerLrn: 'lrn://example/deployers/webapp-deployer-api.example.com',
|
||||||
minimumPayment: '1000alnt',
|
minimumPayment: '1000alnt',
|
||||||
|
baseDomain: 'pwa.example.com',
|
||||||
},
|
},
|
||||||
status: DeploymentStatus.Ready,
|
status: DeploymentStatus.Ready,
|
||||||
createdBy: {
|
createdBy: {
|
||||||
|
@ -129,16 +129,16 @@ const OverviewTabPanel = () => {
|
|||||||
<Heading className="text-lg leading-6 font-medium truncate">
|
<Heading className="text-lg leading-6 font-medium truncate">
|
||||||
{project.name}
|
{project.name}
|
||||||
</Heading>
|
</Heading>
|
||||||
{project.baseDomains &&
|
{project.deployments &&
|
||||||
project.baseDomains.length > 0 &&
|
project.deployments.length > 0 &&
|
||||||
project.baseDomains.map((baseDomain, index) => (
|
project.deployments.map((deployment, index) => (
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
key={index}
|
key={index}
|
||||||
href={`https://${project.name.toLowerCase()}.${baseDomain}`}
|
href={`https://${project.name.toLowerCase()}.${deployment.deployer.baseDomain}`}
|
||||||
className="text-sm text-elements-low-em tracking-tight truncate"
|
className="text-sm text-elements-low-em tracking-tight truncate"
|
||||||
>
|
>
|
||||||
{baseDomain}
|
{deployment.deployer.baseDomain}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
|
@ -107,6 +107,7 @@ export const deployment0: Deployment = {
|
|||||||
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
||||||
deployerLrn: 'lrn://deployer.apps.snowballtools.com ',
|
deployerLrn: 'lrn://deployer.apps.snowballtools.com ',
|
||||||
minimumPayment: '1000alnt',
|
minimumPayment: '1000alnt',
|
||||||
|
baseDomain: 'pwa.example.com',
|
||||||
},
|
},
|
||||||
applicationDeploymentRequestId:
|
applicationDeploymentRequestId:
|
||||||
'bafyreiaycvq6imoppnpwdve4smj6t6ql5svt5zl3x6rimu4qwyzgjorize',
|
'bafyreiaycvq6imoppnpwdve4smj6t6ql5svt5zl3x6rimu4qwyzgjorize',
|
||||||
@ -134,6 +135,7 @@ export const project: Project = {
|
|||||||
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu',
|
||||||
deployerLrn: 'lrn://deployer.apps.snowballtools.com ',
|
deployerLrn: 'lrn://deployer.apps.snowballtools.com ',
|
||||||
minimumPayment: '1000alnt',
|
minimumPayment: '1000alnt',
|
||||||
|
baseDomain: 'pwa.example.com',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
paymentAddress: '0x657868687686rb4787987br8497298r79284797487',
|
paymentAddress: '0x657868687686rb4787987br8497298r79284797487',
|
||||||
|
@ -57,6 +57,9 @@ query ($projectId: String!) {
|
|||||||
commitHash
|
commitHash
|
||||||
createdAt
|
createdAt
|
||||||
environment
|
environment
|
||||||
|
deployer {
|
||||||
|
baseDomain
|
||||||
|
}
|
||||||
domain {
|
domain {
|
||||||
status
|
status
|
||||||
branch
|
branch
|
||||||
|
@ -119,6 +119,7 @@ export type Deployer = {
|
|||||||
deployerLrn: string;
|
deployerLrn: string;
|
||||||
deployerId: string;
|
deployerId: string;
|
||||||
deployerApiUrl: string;
|
deployerApiUrl: string;
|
||||||
|
baseDomain: string;
|
||||||
minimumPayment: string | null;
|
minimumPayment: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user