Skip to content

Commit

Permalink
Support fork deployment (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
broody authored Jan 10, 2024
1 parent 3ef31c4 commit 562b6ae
Show file tree
Hide file tree
Showing 11 changed files with 374 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ tracing = "0.1.34"
urlencoding = "2"
webbrowser = "0.8"
starknet = "0.6.0"
url = "2.2.2"

[[bin]]
name = "slot"
Expand Down
207 changes: 207 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18357,6 +18357,114 @@
"ofType": null
}
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "blockTime",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "forkRpcUrl",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "forkBlockNumber",
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "accounts",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "invokeMaxSteps",
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "validateMaxSteps",
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "disableFee",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "gasPrice",
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "chainId",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
],
"inputFields": [],
Expand Down Expand Up @@ -19262,6 +19370,85 @@
}
}
},
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "name",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
},
{
"defaultValue": null,
"description": null,
"name": "forkName",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
},
{
"defaultValue": null,
"description": null,
"name": "forkBlockNumber",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
}
},
{
"defaultValue": null,
"description": null,
"name": "tier",
"type": {
"kind": "ENUM",
"name": "DeploymentTier",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "wait",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
}
],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "forkDeployment",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "UNION",
"name": "DeploymentConfig",
"ofType": null
}
}
},
{
"args": [
{
Expand Down Expand Up @@ -36878,6 +37065,26 @@
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "forkRpcUrl",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
"name": "forkBlockNumber",
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
}
},
{
"defaultValue": null,
"description": null,
Expand Down
4 changes: 3 additions & 1 deletion src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ impl ApiClient {
.map_err(ApiError::ReqwestError)?;

if res.status() == 403 {
return Err(ApiError::CredentialsError(anyhow::anyhow!("Invalid token, authenticate with `slot auth login`")));
return Err(ApiError::CredentialsError(anyhow::anyhow!(
"Invalid token, authenticate with `slot auth login`"
)));
}

let res: Response<R> = res.json().await.map_err(ApiError::ReqwestError)?;
Expand Down
9 changes: 1 addition & 8 deletions src/command/deployments/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ use crate::{
},
};

use super::services::CreateServiceCommands;

type Long = u64;
use super::{services::CreateServiceCommands, Long, Tier};

#[derive(GraphQLQuery)]
#[graphql(
Expand All @@ -25,11 +23,6 @@ type Long = u64;
)]
pub struct CreateDeployment;

#[derive(clap::ValueEnum, Clone, Debug, serde::Serialize)]
pub enum Tier {
Basic,
}

#[derive(Debug, Args)]
#[command(next_help_heading = "Create options")]
pub struct CreateArgs {
Expand Down
20 changes: 20 additions & 0 deletions src/command/deployments/fork.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
mutation ForkDeployment(
$project: String!
$forkName: String!
$forkBlockNumber: Long!
$tier: DeploymentTier!
$wait: Boolean
) {
forkDeployment(
name: $project
forkName: $forkName
forkBlockNumber: $forkBlockNumber
tier: $tier
wait: $wait
) {
__typename
... on KatanaConfig {
rpc
}
}
}
97 changes: 97 additions & 0 deletions src/command/deployments/fork.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#![allow(clippy::enum_variant_names)]

use anyhow::Result;
use clap::Args;
use graphql_client::{GraphQLQuery, Response};
use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider};
use url::Url;

use crate::{
api::ApiClient,
command::deployments::fork::fork_deployment::{
DeploymentTier, ForkDeploymentForkDeployment::KatanaConfig, Variables,
},
};

use super::{services::ForkServiceCommands, Long, Tier};

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "src/command/deployments/fork.graphql",
response_derives = "Debug"
)]
pub struct ForkDeployment;

#[derive(Debug, Args)]
#[command(next_help_heading = "Fork options")]
pub struct ForkArgs {
#[arg(help = "The name of the project to fork.")]
pub project: String,
#[arg(short, long, default_value = "basic")]
#[arg(value_name = "tier")]
#[arg(help = "Deployment tier.")]
pub tier: Tier,

#[command(subcommand)]
fork_commands: ForkServiceCommands,
}

impl ForkArgs {
pub async fn run(&self) -> Result<()> {
let (fork_name, fork_block_number) = self.fork_config().await?;

let tier = match &self.tier {
Tier::Basic => DeploymentTier::basic,
};

let request_body = ForkDeployment::build_query(Variables {
project: self.project.clone(),
fork_name: fork_name.clone(),
fork_block_number,
tier,
wait: Some(true),
});

let client = ApiClient::new();
let res: Response<fork_deployment::ResponseData> = client.post(&request_body).await?;
if let Some(errors) = res.errors.clone() {
for err in errors {
println!("Error: {}", err.message);
}
}

if let Some(data) = res.data {
println!("Fork success 🚀");
if let KatanaConfig(config) = data.fork_deployment {
println!("\nEndpoints:");
println!(" RPC: {}", config.rpc);
println!(
"\nStream logs with `slot deployments logs {} katana -f`",
fork_name
);
}
}

Ok(())
}

async fn fork_config(&self) -> Result<(String, u64)> {
match &self.fork_commands {
ForkServiceCommands::Katana(config) => {
let block_number = if let Some(block_number) = config.fork_block_number {
block_number
} else {
// Workaround to get latest block number. Perhaps Katana could default to latest if none is supplied
let rpc_client = JsonRpcClient::new(HttpTransport::new(Url::parse(&format!(
"https://api.cartridge.gg/x/{}/katana",
self.project
))?));
rpc_client.block_number().await?
};

Ok((config.fork_name.clone(), block_number))
}
}
}
}
Loading

0 comments on commit 562b6ae

Please sign in to comment.