1- use std:: collections:: { BTreeMap , HashMap } ;
1+ use std:: collections:: HashMap ;
22use std:: fs:: { self , File } ;
33use std:: io:: { prelude:: * , BufReader , Read } ;
44use std:: path:: PathBuf ;
55use std:: { env, process} ;
66
77use crate :: poke:: load_session;
88use crate :: integrate:: { self , DevnetOrchestrator } ;
9+ use crate :: publish:: { self , Network , publish_contracts} ;
910use crate :: test:: run_tests;
1011use crate :: types:: { MainConfig , MainConfigFile , RequirementConfig } ;
1112use crate :: {
1213 generate:: {
1314 self ,
1415 changes:: { Changes , TOMLEdition } ,
1516 } ,
16- utils:: mnemonic,
17- } ;
18-
19- use clarity_repl:: clarity:: codec:: transaction:: {
20- StacksTransaction , StacksTransactionSigner , TransactionAnchorMode , TransactionAuth ,
21- TransactionPayload , TransactionPostConditionMode , TransactionPublicKeyEncoding ,
22- TransactionSmartContract , TransactionSpendingCondition ,
23- } ;
24- use clarity_repl:: clarity:: codec:: StacksMessageCodec ;
25- use clarity_repl:: {
26- clarity:: {
27- codec:: {
28- transaction:: {
29- RecoverableSignature , SinglesigHashMode , SinglesigSpendingCondition ,
30- TransactionVersion ,
31- } ,
32- StacksString ,
33- } ,
34- util:: {
35- address:: AddressHashMode ,
36- secp256k1:: { Secp256k1PrivateKey , Secp256k1PublicKey } ,
37- StacksAddress ,
38- } ,
39- } ,
40- repl,
4117} ;
18+ use clarity_repl:: repl;
4219
4320use clap:: Clap ;
44- use secp256k1:: { PublicKey , SecretKey } ;
45- use tiny_hderive:: bip32:: ExtendedPrivKey ;
4621use toml;
4722
4823#[ derive( Clap ) ]
@@ -75,7 +50,7 @@ enum Command {
7550 /// Execute Clarinet Extension
7651 #[ clap( name = "run" ) ]
7752 Run ( Run ) ,
78- /// Devnet subcommand
53+ /// Work on contracts integration
7954 #[ clap( name = "integrate" ) ]
8055 Integrate ( Integrate ) ,
8156}
@@ -97,18 +72,12 @@ enum Contract {
9772struct GenerateProject {
9873 /// Project's name
9974 pub name : String ,
100- /// Print debug info
101- #[ clap( short = 'd' ) ]
102- pub debug : bool ,
10375}
10476
10577#[ derive( Clap ) ]
10678struct NewContract {
10779 /// Contract's name
10880 pub name : String ,
109- /// Print debug info
110- #[ clap( short = 'd' ) ]
111- pub debug : bool ,
11281 /// Path to Clarinet.toml
11382 #[ clap( long = "manifest-path" ) ]
11483 pub manifest_path : Option < String > ,
@@ -118,9 +87,6 @@ struct NewContract {
11887struct LinkContract {
11988 /// Contract id
12089 pub contract_id : String ,
121- /// Print debug info
122- #[ clap( short = 'd' ) ]
123- pub debug : bool ,
12490 /// Path to Clarinet.toml
12591 #[ clap( long = "manifest-path" ) ]
12692 pub manifest_path : Option < String > ,
@@ -130,9 +96,6 @@ struct LinkContract {
13096struct ForkContract {
13197 /// Contract id
13298 pub contract_id : String ,
133- /// Print debug info
134- #[ clap( short = 'd' ) ]
135- pub debug : bool ,
13699 /// Path to Clarinet.toml
137100 #[ clap( long = "manifest-path" ) ]
138101 pub manifest_path : Option < String > ,
@@ -143,29 +106,20 @@ struct ForkContract {
143106
144107#[ derive( Clap ) ]
145108struct Poke {
146- /// Print debug info
147- #[ clap( short = 'd' ) ]
148- pub debug : bool ,
149109 /// Path to Clarinet.toml
150110 #[ clap( long = "manifest-path" ) ]
151111 pub manifest_path : Option < String > ,
152112}
153113
154114#[ derive( Clap ) ]
155115struct Integrate {
156- /// Print debug info
157- #[ clap( short = 'd' ) ]
158- pub debug : bool ,
159116 /// Path to Clarinet.toml
160117 #[ clap( long = "manifest-path" ) ]
161118 pub manifest_path : Option < String > ,
162119}
163120
164121#[ derive( Clap ) ]
165122struct Test {
166- /// Print debug info
167- #[ clap( short = 'd' ) ]
168- pub debug : bool ,
169123 /// Generate coverage
170124 #[ clap( long = "coverage" ) ]
171125 pub coverage : bool ,
@@ -181,9 +135,6 @@ struct Test {
181135
182136#[ derive( Clap ) ]
183137struct Run {
184- /// Print debug info
185- #[ clap( short = 'd' ) ]
186- pub debug : bool ,
187138 /// Script to run
188139 pub script : String ,
189140 /// Path to Clarinet.toml
@@ -212,9 +163,6 @@ struct Publish {
212163
213164#[ derive( Clap ) ]
214165struct Check {
215- /// Print debug info
216- #[ clap( short = 'd' ) ]
217- pub debug : bool ,
218166 /// Path to Clarinet.toml
219167 #[ clap( long = "manifest-path" ) ]
220168 pub manifest_path : Option < String > ,
@@ -357,169 +305,32 @@ pub fn main() {
357305 }
358306 Command :: Publish ( deploy) => {
359307 let manifest_path = get_manifest_path_or_exit ( deploy. manifest_path ) ;
360- let start_repl = false ;
361- let mode = if deploy. mocknet == true {
362- "mocknet"
308+
309+ let network = if deploy. devnet == true {
310+ Network :: Devnet
363311 } else if deploy. testnet == true {
364- "testnet"
365- } else {
312+ Network :: Testnet
313+ } else if deploy. mainnet == true {
314+ // Network::Mainnet
366315 // TODO(ludo): before supporting mainnet deployments, we want to add a pass
367- // making sure that addresses are consistent.
368- panic ! ( "Target deployment must be specified with --mocknet or --testnet" )
369- } ;
370- let res = load_session ( manifest_path, start_repl, mode. into ( ) ) ;
371- if let Err ( e) = res {
372- println ! ( "{}" , e) ;
373- return ;
374- }
375- let settings = res. unwrap ( ) ;
376-
377- let mut deployers_nonces = BTreeMap :: new ( ) ;
378- let mut deployers_lookup = BTreeMap :: new ( ) ;
379- for account in settings. initial_accounts . iter ( ) {
380- if account. name == "deployer" {
381- deployers_lookup. insert ( "*" , account. clone ( ) ) ;
382- }
383- }
384-
385- #[ derive( Deserialize , Debug ) ]
386- struct Balance {
387- balance : String ,
388- nonce : u64 ,
389- balance_proof : String ,
390- nonce_proof : String ,
391- }
392-
393- let host = if mode == "mocknet" {
394- "http://localhost:20443"
316+ // making sure that addresses are consistent + handle other hard coded flags.
317+ // Search for "mainnet handling".
318+ panic ! ( "Target deployment must be specified with --devnet, --testnet, --mainnet" )
395319 } else {
396- "https://stacks-node-api.testnet.stacks.co"
320+ panic ! ( "Target deployment must be specified with --devnet, --testnet, --mainnet" )
321+ } ;
322+ match publish_contracts ( manifest_path, network) {
323+ Ok ( results) => println ! ( "{}" , results. join( "\n " ) ) ,
324+ Err ( e) => println ! ( "{}" , e)
397325 } ;
398-
399- for initial_contract in settings. initial_contracts . iter ( ) {
400- let contract_name = initial_contract. name . clone ( ) . unwrap ( ) ;
401-
402- let payload = TransactionSmartContract {
403- name : contract_name. as_str ( ) . into ( ) ,
404- code_body : StacksString :: from_string ( & initial_contract. code ) . unwrap ( ) ,
405- } ;
406-
407- let deployer = match deployers_lookup. get ( contract_name. as_str ( ) ) {
408- Some ( deployer) => deployer,
409- None => deployers_lookup. get ( "*" ) . unwrap ( ) ,
410- } ;
411-
412- let bip39_seed =
413- match mnemonic:: get_bip39_seed_from_mnemonic ( & deployer. mnemonic , "" ) {
414- Ok ( bip39_seed) => bip39_seed,
415- Err ( _) => panic ! ( ) ,
416- } ;
417- let ext =
418- ExtendedPrivKey :: derive ( & bip39_seed[ ..] , deployer. derivation . as_str ( ) ) . unwrap ( ) ;
419- let secret_key = SecretKey :: parse_slice ( & ext. secret ( ) ) . unwrap ( ) ;
420- let public_key = PublicKey :: from_secret_key ( & secret_key) ;
421-
422- let wrapped_public_key =
423- Secp256k1PublicKey :: from_slice ( & public_key. serialize_compressed ( ) ) . unwrap ( ) ;
424- let wrapped_secret_key = Secp256k1PrivateKey :: from_slice ( & ext. secret ( ) ) . unwrap ( ) ;
425-
426- let anchor_mode = TransactionAnchorMode :: Any ;
427- let tx_fee = 200 + initial_contract. code . len ( ) as u64 ;
428-
429- let nonce = match deployers_nonces. get ( & deployer. name ) {
430- Some ( nonce) => * nonce,
431- None => {
432- let request_url = format ! (
433- "{host}/v2/accounts/{addr}" ,
434- host = host,
435- addr = deployer. address,
436- ) ;
437-
438- let response: Balance = reqwest:: blocking:: get ( & request_url)
439- . expect ( "Unable to retrieve account" )
440- . json ( )
441- . expect ( "Unable to parse contract" ) ;
442- let nonce = response. nonce ;
443- deployers_nonces. insert ( deployer. name . clone ( ) , nonce) ;
444- nonce
445- }
446- } ;
447-
448- let signer_addr = StacksAddress :: from_public_keys (
449- 0 ,
450- & AddressHashMode :: SerializeP2PKH ,
451- 1 ,
452- & vec ! [ wrapped_public_key] ,
453- )
454- . unwrap ( ) ;
455-
456- let spending_condition =
457- TransactionSpendingCondition :: Singlesig ( SinglesigSpendingCondition {
458- signer : signer_addr. bytes . clone ( ) ,
459- nonce : nonce,
460- tx_fee : tx_fee,
461- hash_mode : SinglesigHashMode :: P2PKH ,
462- key_encoding : TransactionPublicKeyEncoding :: Compressed ,
463- signature : RecoverableSignature :: empty ( ) ,
464- } ) ;
465-
466- let auth = TransactionAuth :: Standard ( spending_condition) ;
467- let unsigned_tx = StacksTransaction {
468- version : TransactionVersion :: Testnet ,
469- chain_id : 0x80000000 , // MAINNET=0x00000001
470- auth : auth,
471- anchor_mode : anchor_mode,
472- post_condition_mode : TransactionPostConditionMode :: Deny ,
473- post_conditions : vec ! [ ] ,
474- payload : TransactionPayload :: SmartContract ( payload) ,
475- } ;
476-
477- let mut unsigned_tx_bytes = vec ! [ ] ;
478- unsigned_tx
479- . consensus_serialize ( & mut unsigned_tx_bytes)
480- . expect ( "FATAL: invalid transaction" ) ;
481-
482- let mut tx_signer = StacksTransactionSigner :: new ( & unsigned_tx) ;
483- tx_signer. sign_origin ( & wrapped_secret_key) . unwrap ( ) ;
484- let signed_tx = tx_signer. get_tx ( ) . unwrap ( ) ;
485-
486- let tx_bytes = signed_tx. serialize_to_vec ( ) ;
487- let client = reqwest:: blocking:: Client :: new ( ) ;
488- let path = format ! ( "{}/v2/transactions" , host) ;
489- let res = client
490- . post ( & path)
491- . header ( "Content-Type" , "application/octet-stream" )
492- . body ( tx_bytes)
493- . send ( )
494- . unwrap ( ) ;
495-
496- if !res. status ( ) . is_success ( ) {
497- println ! ( "{}" , res. text( ) . unwrap( ) ) ;
498- panic ! ( )
499- }
500- let txid: String = res. json ( ) . unwrap ( ) ;
501-
502- println ! (
503- "Deploying {} (txid: {}, nonce: {})" ,
504- contract_name, txid, nonce
505- ) ;
506- deployers_nonces. insert ( deployer. name . clone ( ) , nonce + 1 ) ;
507- }
508- // If mocknet, we should be pulling all the links.
509- // Get ordered list of contracts
510- // For each contract, get the nonce of the account deploying (if unknown)
511- // Create a StacksTransaction with the contract, the name.
512- // Sign the transaction
513- // Send the transaction
514326 }
515327 Command :: Integrate ( cmd) => {
516328 let manifest_path = get_manifest_path_or_exit ( cmd. manifest_path ) ;
517329 println ! (
518330 "Start orchestrating stacks-node, stacks-blockchain-api, bitcoind, bitcoin explorer, stacks-explorer"
519331 ) ;
520332 let mut devnet = DevnetOrchestrator :: new ( manifest_path) ;
521- let devnet_event_tx = devnet. event_tx . clone ( ) ;
522- integrate:: run_devnet ( & mut devnet) ;
333+ integrate:: run_devnet ( devnet) ;
523334 }
524335 } ;
525336}
0 commit comments