@@ -7,7 +7,6 @@ use mina_p2p_messages::v2::MinaBaseUserCommandStableV2;
77use mina_p2p_messages:: v2:: MinaBaseZkappCommandTStableV1WireStableV1 ;
88use mina_p2p_messages:: v2:: TokenIdKeyHash ;
99use node:: rpc:: RpcTransactionInjectResponse ;
10- use node:: rpc:: RpcTransactionInjectedCommand ;
1110use node:: rpc:: { GetBlockQuery , RpcGetBlockResponse , RpcTransactionStatusGetResponse } ;
1211use node:: {
1312 account:: AccountPublicKey ,
@@ -74,6 +73,12 @@ pub enum ConversionError {
7473 FieldHelpers ( #[ from] FieldHelpersError ) ,
7574}
7675
76+ impl From < ConversionError > for Error {
77+ fn from ( value : ConversionError ) -> Self {
78+ Error :: Conversion ( value)
79+ }
80+ }
81+
7782struct Context ( RpcSender ) ;
7883
7984impl juniper:: Context for Context { }
@@ -316,6 +321,56 @@ impl Query {
316321 }
317322}
318323
324+ async fn inject_tx < R > (
325+ cmd : MinaBaseUserCommandStableV2 ,
326+ context : & Context ,
327+ ) -> juniper:: FieldResult < R >
328+ where
329+ R : TryFrom < MinaBaseUserCommandStableV2 > ,
330+ {
331+ let res: RpcTransactionInjectResponse = context
332+ . 0
333+ . oneshot_request ( RpcRequest :: TransactionInject ( vec ! [ cmd] ) )
334+ . await
335+ . ok_or ( Error :: StateMachineEmptyResponse ) ?;
336+
337+ match res {
338+ RpcTransactionInjectResponse :: Success ( res) => {
339+ let cmd: MinaBaseUserCommandStableV2 = match res. first ( ) . cloned ( ) {
340+ Some ( cmd) => cmd. into ( ) ,
341+ _ => unreachable ! ( ) ,
342+ } ;
343+ cmd. try_into ( ) . map_err ( |_| {
344+ FieldError :: new (
345+ "Failed to convert transaction to the required type" . to_string ( ) ,
346+ graphql_value ! ( null) ,
347+ )
348+ } )
349+ }
350+ RpcTransactionInjectResponse :: Rejected ( rejected) => {
351+ let error_list = rejected
352+ . into_iter ( )
353+ . map ( |( _, err) | graphql_value ! ( { "message" : err. to_string( ) } ) )
354+ . collect :: < Vec < _ > > ( ) ;
355+
356+ Err ( FieldError :: new (
357+ "Transaction rejected" ,
358+ graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
359+ ) )
360+ }
361+ RpcTransactionInjectResponse :: Failure ( failure) => {
362+ let error_list = failure
363+ . into_iter ( )
364+ . map ( |err| graphql_value ! ( { "message" : err. to_string( ) } ) )
365+ . collect :: < Vec < _ > > ( ) ;
366+
367+ Err ( FieldError :: new (
368+ "Transaction failed" ,
369+ graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
370+ ) )
371+ }
372+ }
373+ }
319374#[ derive( Clone , Debug ) ]
320375struct Mutation ;
321376
@@ -325,50 +380,44 @@ impl Mutation {
325380 input : zkapp:: SendZkappInput ,
326381 context : & Context ,
327382 ) -> juniper:: FieldResult < zkapp:: GraphQLSendZkappResponse > {
328- let res: RpcTransactionInjectResponse = context
383+ inject_tx ( input. try_into ( ) ?, context) . await
384+ }
385+
386+ async fn send_payment (
387+ input : user_command:: InputGraphQLPayment ,
388+ signature : user_command:: UserCommandSignature ,
389+ context : & Context ,
390+ ) -> juniper:: FieldResult < user_command:: GraphQLSendPaymentResponse > {
391+ // Grab the sender's account to get the infered nonce
392+ let token_id = TokenIdKeyHash :: default ( ) ;
393+ let public_key = AccountPublicKey :: from_str ( & input. from )
394+ . map_err ( |e| Error :: Conversion ( ConversionError :: Base58Check ( e) ) ) ?;
395+
396+ let accounts: Vec < Account > = context
329397 . 0
330- . oneshot_request ( RpcRequest :: TransactionInject ( vec ! [ input. try_into( ) ?] ) )
398+ . oneshot_request ( RpcRequest :: LedgerAccountsGet (
399+ AccountQuery :: PubKeyWithTokenId ( public_key, token_id) ,
400+ ) )
331401 . await
332402 . ok_or ( Error :: StateMachineEmptyResponse ) ?;
333403
334- match res {
335- RpcTransactionInjectResponse :: Success ( res) => {
336- let zkapp_cmd: MinaBaseUserCommandStableV2 = match res. first ( ) . cloned ( ) {
337- Some ( RpcTransactionInjectedCommand :: Zkapp ( zkapp_cmd) ) => zkapp_cmd. into ( ) ,
338- _ => unreachable ! ( ) ,
339- } ;
340- Ok ( zkapp_cmd. try_into ( ) ?)
341- }
342- RpcTransactionInjectResponse :: Rejected ( rejected) => {
343- let error_list = rejected
344- . into_iter ( )
345- . map ( |( _, err) | graphql_value ! ( { "message" : err. to_string( ) } ) )
346- . collect :: < Vec < _ > > ( ) ;
347-
348- Err ( FieldError :: new (
349- "Transaction rejected" ,
350- graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
351- ) )
352- }
353- RpcTransactionInjectResponse :: Failure ( failure) => {
354- let error_list = failure
355- . into_iter ( )
356- . map ( |err| graphql_value ! ( { "message" : err. to_string( ) } ) )
357- . collect :: < Vec < _ > > ( ) ;
358-
359- Err ( FieldError :: new (
360- "Transaction failed" ,
361- graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
362- ) )
363- }
364- }
404+ let infered_nonce = accounts
405+ . first ( )
406+ . ok_or ( Error :: StateMachineEmptyResponse ) ?
407+ . nonce ;
408+
409+ let command = input
410+ . create_user_command ( infered_nonce, signature)
411+ . map_err ( Error :: Conversion ) ?;
412+
413+ inject_tx ( command, context) . await
365414 }
366415
367- async fn send_payment (
368- input : user_command:: InputGraphQLPayment ,
416+ async fn send_delegation (
417+ input : user_command:: InputGraphQLDelegation ,
369418 signature : user_command:: UserCommandSignature ,
370419 context : & Context ,
371- ) -> juniper:: FieldResult < user_command:: GraphQLSendPaymentResponse > {
420+ ) -> juniper:: FieldResult < user_command:: GraphQLSendDelegationResponse > {
372421 // Payment commands are always for the default (MINA) token
373422 let token_id = TokenIdKeyHash :: default ( ) ;
374423 let public_key = AccountPublicKey :: from_str ( & input. from ) ?;
@@ -388,43 +437,7 @@ impl Mutation {
388437 . nonce ;
389438 let command = input. create_user_command ( infered_nonce, signature) ?;
390439
391- let res: RpcTransactionInjectResponse = context
392- . 0
393- . oneshot_request ( RpcRequest :: TransactionInject ( vec ! [ command] ) )
394- . await
395- . ok_or ( Error :: StateMachineEmptyResponse ) ?;
396-
397- match res {
398- RpcTransactionInjectResponse :: Success ( res) => {
399- let payment_cmd: MinaBaseUserCommandStableV2 = match res. first ( ) . cloned ( ) {
400- Some ( RpcTransactionInjectedCommand :: Payment ( payment) ) => payment. into ( ) ,
401- _ => unreachable ! ( ) ,
402- } ;
403- Ok ( payment_cmd. try_into ( ) ?)
404- }
405- RpcTransactionInjectResponse :: Rejected ( rejected) => {
406- let error_list = rejected
407- . into_iter ( )
408- . map ( |( _, err) | graphql_value ! ( { "message" : err. to_string( ) } ) )
409- . collect :: < Vec < _ > > ( ) ;
410-
411- Err ( FieldError :: new (
412- "Transaction rejected" ,
413- graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
414- ) )
415- }
416- RpcTransactionInjectResponse :: Failure ( failure) => {
417- let error_list = failure
418- . into_iter ( )
419- . map ( |err| graphql_value ! ( { "message" : err. to_string( ) } ) )
420- . collect :: < Vec < _ > > ( ) ;
421-
422- Err ( FieldError :: new (
423- "Transaction failed" ,
424- graphql_value ! ( juniper:: Value :: List ( error_list) ) ,
425- ) )
426- }
427- }
440+ inject_tx ( command, context) . await
428441 }
429442}
430443
0 commit comments