packages feed

morley-client 0.3.0 → 0.3.1

raw patch · 38 files changed

+1043/−417 lines, 38 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Morley.Client: AliasTxRollup :: Text -> KindedAddress 'AddressKindTxRollup -> TezosClientError
- Morley.Client: revealKey :: HasTezosClient m => ImplicitAlias -> Maybe ScrubbedBytes -> m ()
- Morley.Client.Action: revealKeyUnlessRevealed :: (WithClientLog env m, HasTezosRpc m, HasTezosClient m) => ImplicitAddress -> Maybe ScrubbedBytes -> m ()
- Morley.Client.Action.Common: revealKeyUnlessRevealed :: (WithClientLog env m, HasTezosRpc m, HasTezosClient m) => ImplicitAddress -> Maybe ScrubbedBytes -> m ()
- Morley.Client.TezosClient: AliasTxRollup :: Text -> KindedAddress 'AddressKindTxRollup -> TezosClientError
- Morley.Client.TezosClient.Class: revealKey :: HasTezosClient m => ImplicitAlias -> Maybe ScrubbedBytes -> m ()
- Morley.Client.TezosClient.Impl: AliasTxRollup :: Text -> KindedAddress 'AddressKindTxRollup -> TezosClientError
- Morley.Client.Types: instance Universum.TypeOps.Each '[Morley.Client.Types.ToJSONObject] '[Morley.Client.Types.TransferInfo i, Morley.Client.Types.OriginationInfo i, Morley.Client.Types.RevealInfo i, Morley.Client.Types.DelegationInfo i] => Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.Types.OperationInfo i)
+ Morley.Client: AddressWithAlias :: KindedAddress kind -> Alias kind -> AddressWithAlias kind
+ Morley.Client: GetAllTicketBalancesResponse :: ContractAddress -> Expression -> Expression -> TezosNat -> GetAllTicketBalancesResponse
+ Morley.Client: GetTicketBalance :: ContractAddress -> Expression -> Expression -> GetTicketBalance
+ Morley.Client: OpTransferTicket :: TransferTicketInfo i -> OperationInfo i
+ Morley.Client: REEmptyImplicitContract :: ImplicitAddress -> RunError
+ Morley.Client: [awaAddress] :: AddressWithAlias kind -> KindedAddress kind
+ Morley.Client: [awaAlias] :: AddressWithAlias kind -> Alias kind
+ Morley.Client: [gatbrAmount] :: GetAllTicketBalancesResponse -> TezosNat
+ Morley.Client: [gatbrContentType] :: GetAllTicketBalancesResponse -> Expression
+ Morley.Client: [gatbrContent] :: GetAllTicketBalancesResponse -> Expression
+ Morley.Client: [gatbrTicketer] :: GetAllTicketBalancesResponse -> ContractAddress
+ Morley.Client: [gtbContentType] :: GetTicketBalance -> Expression
+ Morley.Client: [gtbContent] :: GetTicketBalance -> Expression
+ Morley.Client: [gtbTicketer] :: GetTicketBalance -> ContractAddress
+ Morley.Client: data AddressWithAlias kind
+ Morley.Client: data GetAllTicketBalancesResponse
+ Morley.Client: data GetTicketBalance
+ Morley.Client: getAllTicketBalances :: HasTezosRpc m => ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client: getAllTicketBalancesAtBlock :: HasTezosRpc m => BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client: getPublicKey :: HasTezosClient m => ImplicitAddressWithAlias -> m PublicKey
+ Morley.Client: getTicketBalance :: HasTezosRpc m => L1Address -> GetTicketBalance -> m Natural
+ Morley.Client: getTicketBalanceAtBlock :: HasTezosRpc m => BlockId -> Address -> GetTicketBalance -> m Natural
+ Morley.Client: resolveAddressWithAlias :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (ResolvedAddressAndAlias addressOrAlias)
+ Morley.Client: resolveAddressWithAliasMaybe :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
+ Morley.Client: type ContractAddressWithAlias = AddressWithAlias 'AddressKindContract
+ Morley.Client: type ImplicitAddressWithAlias = AddressWithAlias 'AddressKindImplicit
+ Morley.Client.Action.Batched: delegateM :: DelegationData -> OperationsBatch ()
+ Morley.Client.Action.Common: TransferTicketData :: Value t -> Address -> Natural -> Address -> EpName -> Maybe Mutez -> TransferTicketData
+ Morley.Client.Action.Common: [ttdDestination] :: TransferTicketData -> Address
+ Morley.Client.Action.Common: [ttdEntrypoint] :: TransferTicketData -> EpName
+ Morley.Client.Action.Common: [ttdMbFee] :: TransferTicketData -> Maybe Mutez
+ Morley.Client.Action.Common: [ttdTicketAmount] :: TransferTicketData -> Natural
+ Morley.Client.Action.Common: [ttdTicketContents] :: TransferTicketData -> Value t
+ Morley.Client.Action.Common: [ttdTicketTicketer] :: TransferTicketData -> Address
+ Morley.Client.Action.Common: buildTxTicketDataWithAlias :: Maybe Text -> TransferTicketData -> Builder
+ Morley.Client.Action.Common: data TransferTicketData
+ Morley.Client.Action.Reveal: revealKeyOp :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => PublicKey -> Maybe Mutez -> m OperationHash
+ Morley.Client.Action.Reveal: revealKeyUnlessRevealedOp :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => PublicKey -> Maybe Mutez -> m ()
+ Morley.Client.Action.Reveal: revealKeyUnlessRevealedWithFee :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> Maybe Mutez -> m ()
+ Morley.Client.Action.Reveal: revealKeyWithFee :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> Maybe Mutez -> m OperationHash
+ Morley.Client.Action.Transaction: TransferTicketData :: Value t -> Address -> Natural -> Address -> EpName -> Maybe Mutez -> TransferTicketData
+ Morley.Client.Action.Transaction: [ttdDestination] :: TransferTicketData -> Address
+ Morley.Client.Action.Transaction: [ttdEntrypoint] :: TransferTicketData -> EpName
+ Morley.Client.Action.Transaction: [ttdMbFee] :: TransferTicketData -> Maybe Mutez
+ Morley.Client.Action.Transaction: [ttdTicketAmount] :: TransferTicketData -> Natural
+ Morley.Client.Action.Transaction: [ttdTicketContents] :: TransferTicketData -> Value t
+ Morley.Client.Action.Transaction: [ttdTicketTicketer] :: TransferTicketData -> Address
+ Morley.Client.Action.Transaction: data TransferTicketData
+ Morley.Client.Action.Transaction: transferTicket :: forall m t env kind. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, ParameterScope t, Comparable t) => ImplicitAddressWithAlias -> KindedAddress kind -> ContractAddress -> Value t -> Natural -> EpName -> Maybe Mutez -> m (OperationHash, [IntOpEvent])
+ Morley.Client.App: getAllTicketBalancesAtBlockImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client.App: getTicketBalanceAtBlockImpl :: (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> Address -> GetTicketBalance -> m Natural
+ Morley.Client.Parser: TicketBalanceArgs :: ContractAddress -> Value -> Ty -> TicketBalanceArgs
+ Morley.Client.Parser: TransferTicketArgs :: ImplicitAddressOrAlias -> Value -> Ty -> ContractAddressOrAlias -> Natural -> SomeAddressOrAlias -> Maybe Mutez -> TransferTicketArgs
+ Morley.Client.Parser: [AllTicketBalances] :: ContractAddressOrAlias -> ClientArgsRaw
+ Morley.Client.Parser: [TicketBalance] :: SomeAddressOrAlias -> TicketBalanceArgs -> ClientArgsRaw
+ Morley.Client.Parser: [TransferTicket] :: TransferTicketArgs -> ClientArgsRaw
+ Morley.Client.Parser: [tbaContentType] :: TicketBalanceArgs -> Ty
+ Morley.Client.Parser: [tbaContent] :: TicketBalanceArgs -> Value
+ Morley.Client.Parser: [tbaTicketer] :: TicketBalanceArgs -> ContractAddress
+ Morley.Client.Parser: [ttaDestination] :: TransferTicketArgs -> SomeAddressOrAlias
+ Morley.Client.Parser: [ttaMbFee] :: TransferTicketArgs -> Maybe Mutez
+ Morley.Client.Parser: [ttaSender] :: TransferTicketArgs -> ImplicitAddressOrAlias
+ Morley.Client.Parser: [ttaTicketAmount] :: TransferTicketArgs -> Natural
+ Morley.Client.Parser: [ttaTicketContents] :: TransferTicketArgs -> Value
+ Morley.Client.Parser: [ttaTicketTicketer] :: TransferTicketArgs -> ContractAddressOrAlias
+ Morley.Client.Parser: [ttaTicketType] :: TransferTicketArgs -> Ty
+ Morley.Client.Parser: data TicketBalanceArgs
+ Morley.Client.Parser: data TransferTicketArgs
+ Morley.Client.RPC.API: [getAllTicketBalancesAtBlock] :: NodeMethods m -> BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client.RPC.API: [getTicketBalanceAtBlock] :: NodeMethods m -> BlockId -> Address -> GetTicketBalance -> m TezosNat
+ Morley.Client.RPC.Class: getAllTicketBalancesAtBlock :: HasTezosRpc m => BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client.RPC.Class: getTicketBalanceAtBlock :: HasTezosRpc m => BlockId -> Address -> GetTicketBalance -> m Natural
+ Morley.Client.RPC.Getters: contractStateResolver :: HasTezosRpc m => BlockId -> ContractAddress -> m (Maybe ContractState)
+ Morley.Client.RPC.Getters: getAllTicketBalances :: HasTezosRpc m => ContractAddress -> m [GetAllTicketBalancesResponse]
+ Morley.Client.RPC.Getters: getTicketBalance :: HasTezosRpc m => L1Address -> GetTicketBalance -> m Natural
+ Morley.Client.RPC.Types: GetAllTicketBalancesResponse :: ContractAddress -> Expression -> Expression -> TezosNat -> GetAllTicketBalancesResponse
+ Morley.Client.RPC.Types: GetTicketBalance :: ContractAddress -> Expression -> Expression -> GetTicketBalance
+ Morley.Client.RPC.Types: REEmptyImplicitContract :: ImplicitAddress -> RunError
+ Morley.Client.RPC.Types: TransferTicketOperation :: Expression -> Expression -> Address -> TezosNat -> Address -> Text -> TransferTicketOperation
+ Morley.Client.RPC.Types: [gatbrAmount] :: GetAllTicketBalancesResponse -> TezosNat
+ Morley.Client.RPC.Types: [gatbrContentType] :: GetAllTicketBalancesResponse -> Expression
+ Morley.Client.RPC.Types: [gatbrContent] :: GetAllTicketBalancesResponse -> Expression
+ Morley.Client.RPC.Types: [gatbrTicketer] :: GetAllTicketBalancesResponse -> ContractAddress
+ Morley.Client.RPC.Types: [gtbContentType] :: GetTicketBalance -> Expression
+ Morley.Client.RPC.Types: [gtbContent] :: GetTicketBalance -> Expression
+ Morley.Client.RPC.Types: [gtbTicketer] :: GetTicketBalance -> ContractAddress
+ Morley.Client.RPC.Types: [ttoDestination] :: TransferTicketOperation -> Address
+ Morley.Client.RPC.Types: [ttoEntrypoint] :: TransferTicketOperation -> Text
+ Morley.Client.RPC.Types: [ttoTicketAmount] :: TransferTicketOperation -> TezosNat
+ Morley.Client.RPC.Types: [ttoTicketContents] :: TransferTicketOperation -> Expression
+ Morley.Client.RPC.Types: [ttoTicketTicketer] :: TransferTicketOperation -> Address
+ Morley.Client.RPC.Types: [ttoTicketTy] :: TransferTicketOperation -> Expression
+ Morley.Client.RPC.Types: data GetAllTicketBalancesResponse
+ Morley.Client.RPC.Types: data GetTicketBalance
+ Morley.Client.RPC.Types: data TransferTicketOperation
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.FromJSON.FromJSON Morley.Client.RPC.Types.GetAllTicketBalancesResponse
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.ToJSON.ToJSON Morley.Client.RPC.Types.GetTicketBalance
+ Morley.Client.RPC.Types: instance Data.Aeson.Types.ToJSON.ToJSON Morley.Client.RPC.Types.TransferTicketOperation
+ Morley.Client.RPC.Types: instance Morley.Client.Types.ToJSONObject Morley.Client.RPC.Types.TransferTicketOperation
+ Morley.Client.TezosClient: resolveAddressWithAlias :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (ResolvedAddressAndAlias addressOrAlias)
+ Morley.Client.TezosClient: resolveAddressWithAliasMaybe :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
+ Morley.Client.TezosClient.Class: getPublicKey :: HasTezosClient m => ImplicitAddressWithAlias -> m PublicKey
+ Morley.Client.TezosClient.Impl: resolveAddressWithAlias :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (ResolvedAddressAndAlias addressOrAlias)
+ Morley.Client.TezosClient.Impl: resolveAddressWithAliasEither :: forall m env. (Resolve addressOrAlias, HasTezosClient m, MonadThrow m, WithClientLog env m) => addressOrAlias -> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
+ Morley.Client.TezosClient.Impl: resolveAddressWithAliasMaybe :: forall addressOrAlias m env. (HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias) => addressOrAlias -> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
+ Morley.Client.TezosClient.Impl: revealKeyUnlessRevealed :: (WithClientLog env m, HasTezosRpc m, MonadIO m, HasTezosClientEnv env) => ImplicitAddressWithAlias -> Maybe ScrubbedBytes -> m ()
+ Morley.Client.Types: AddressWithAlias :: KindedAddress kind -> Alias kind -> AddressWithAlias kind
+ Morley.Client.Types: OpTransferTicket :: TransferTicketInfo i -> OperationInfo i
+ Morley.Client.Types: [awaAddress] :: AddressWithAlias kind -> KindedAddress kind
+ Morley.Client.Types: [awaAlias] :: AddressWithAlias kind -> Alias kind
+ Morley.Client.Types: _OpTransferTicket :: forall i_aGJ8. Prism' (OperationInfo i_aGJ8) (TransferTicketInfo i_aGJ8)
+ Morley.Client.Types: data AddressWithAlias kind
+ Morley.Client.Types: instance Formatting.Buildable.Buildable (Morley.Client.Types.AddressWithAlias kind)
+ Morley.Client.Types: instance GHC.Classes.Eq (Morley.Client.Types.AddressWithAlias kind)
+ Morley.Client.Types: instance GHC.Show.Show (Morley.Client.Types.AddressWithAlias kind)
+ Morley.Client.Types: instance Lorentz.Address.ToAddress (Morley.Client.Types.AddressWithAlias kind)
+ Morley.Client.Types: instance Lorentz.Address.ToTAddress cp vd (Morley.Tezos.Address.KindedAddress kind) => Lorentz.Address.ToTAddress cp vd (Morley.Client.Types.AddressWithAlias kind)
+ Morley.Client.Types: instance Universum.TypeOps.Each '[Morley.Client.Types.ToJSONObject] '[Morley.Client.Types.TransferInfo i, Morley.Client.Types.TransferTicketInfo i, Morley.Client.Types.OriginationInfo i, Morley.Client.Types.RevealInfo i, Morley.Client.Types.DelegationInfo i] => Data.Aeson.Types.ToJSON.ToJSON (Morley.Client.Types.OperationInfo i)
+ Morley.Client.Types: type ContractAddressWithAlias = AddressWithAlias 'AddressKindContract
+ Morley.Client.Types: type ImplicitAddressWithAlias = AddressWithAlias 'AddressKindImplicit
- Morley.Client: genFreshKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddress
+ Morley.Client: genFreshKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddressWithAlias
- Morley.Client: genKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddress
+ Morley.Client: genKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddressWithAlias
- Morley.Client: getKeyPassword :: HasTezosClient m => ImplicitAddress -> m (Maybe ScrubbedBytes)
+ Morley.Client: getKeyPassword :: HasTezosClient m => ImplicitAddressWithAlias -> m (Maybe ScrubbedBytes)
- Morley.Client: signBytes :: HasTezosClient m => ImplicitAddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
+ Morley.Client: signBytes :: HasTezosClient m => ImplicitAddressWithAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
- Morley.Client.Action.Batched: runOperationsBatch :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> OperationsBatch a -> m (Maybe OperationHash, a)
+ Morley.Client.Action.Batched: runOperationsBatch :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> OperationsBatch a -> m (Maybe OperationHash, a)
- Morley.Client.Action.Delegation: registerDelegateOp :: (HasTezosRpc m, HasTezosClient m, MonadReader env m, HasLog env Message m) => KeyHash -> m OperationHash
+ Morley.Client.Action.Delegation: registerDelegateOp :: (HasTezosRpc m, HasTezosClient m, MonadReader env m, HasLog env Message m) => ImplicitAddressWithAlias -> m OperationHash
- Morley.Client.Action.Delegation: setDelegateOp :: (HasTezosRpc m, HasTezosClient m, MonadReader env m, HasLog env Message m) => ImplicitAddressOrAlias -> Maybe KeyHash -> m OperationHash
+ Morley.Client.Action.Delegation: setDelegateOp :: (HasTezosRpc m, HasTezosClient m, MonadReader env m, HasLog env Message m) => ImplicitAddressWithAlias -> Maybe KeyHash -> m OperationHash
- Morley.Client.Action.Operation: dryRunOperationsNonEmpty :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> NonEmpty (OperationInfo ClientInput) -> m (NonEmpty (AppliedResult, TezosMutez))
+ Morley.Client.Action.Operation: dryRunOperationsNonEmpty :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> NonEmpty (OperationInfo ClientInput) -> m (NonEmpty (AppliedResult, TezosMutez))
- Morley.Client.Action.Operation: runOperations :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> [OperationInfo ClientInput] -> m (Maybe OperationHash, [OperationInfo Result])
+ Morley.Client.Action.Operation: runOperations :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [OperationInfo ClientInput] -> m (Maybe OperationHash, [OperationInfo Result])
- Morley.Client.Action.Operation: runOperationsNonEmpty :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> NonEmpty (OperationInfo ClientInput) -> m (OperationHash, NonEmpty (OperationInfo Result))
+ Morley.Client.Action.Operation: runOperationsNonEmpty :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> NonEmpty (OperationInfo ClientInput) -> m (OperationHash, NonEmpty (OperationInfo Result))
- Morley.Client.Action.Origination: lOriginateContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: lOriginateContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Origination: lOriginateContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
+ Morley.Client.Action.Origination: lOriginateContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
- Morley.Client.Action.Origination: lOriginateLargeContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameterFull cp) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: lOriginateLargeContract :: forall m cp st vd env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceStorage st, NiceParameter cp) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract cp st vd -> st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Origination: lOriginateLargeContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
+ Morley.Client.Action.Origination: lOriginateLargeContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
- Morley.Client.Action.Origination: originateContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: originateContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Origination: originateContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
+ Morley.Client.Action.Origination: originateContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
- Morley.Client.Action.Origination: originateLargeContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: originateLargeContract :: forall m cp st env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, StorageScope st, ParameterScope cp) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract cp st -> Value st -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Origination: originateLargeContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressOrAlias -> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
+ Morley.Client.Action.Origination: originateLargeContracts :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
- Morley.Client.Action.Origination: originateLargeUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: originateLargeUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Origination: originateUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => AliasBehavior -> ContractAlias -> ImplicitAddressOrAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
+ Morley.Client.Action.Origination: originateUntypedContract :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => AliasBehavior -> ContractAlias -> ImplicitAddressWithAlias -> Mutez -> Contract -> Value -> Maybe Mutez -> Maybe KeyHash -> m (OperationHash, ContractAddress)
- Morley.Client.Action.Reveal: revealKey :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => PublicKey -> Maybe Mutez -> m OperationHash
+ Morley.Client.Action.Reveal: revealKey :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> m OperationHash
- Morley.Client.Action.Reveal: revealKeyUnlessRevealed :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => PublicKey -> Maybe Mutez -> m ()
+ Morley.Client.Action.Reveal: revealKeyUnlessRevealed :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> m ()
- Morley.Client.Action.Transaction: lRunTransactions :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddress -> [LTransactionData] -> m (Maybe (OperationHash, [OperationInfo Result]))
+ Morley.Client.Action.Transaction: lRunTransactions :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [LTransactionData] -> m (Maybe (OperationHash, [OperationInfo Result]))
- Morley.Client.Action.Transaction: lTransfer :: forall m t env kind. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceParameter t, L1AddressKind kind) => ImplicitAddress -> KindedAddress kind -> Mutez -> EpName -> t -> Maybe Mutez -> m (OperationHash, [IntOpEvent])
+ Morley.Client.Action.Transaction: lTransfer :: forall m t env kind. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, NiceParameter t, L1AddressKind kind) => ImplicitAddressWithAlias -> KindedAddress kind -> Mutez -> EpName -> t -> Maybe Mutez -> m (OperationHash, [IntOpEvent])
- Morley.Client.Action.Transaction: runTransactions :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddress -> [TransactionData] -> m (Maybe (OperationHash, [OperationInfo Result]))
+ Morley.Client.Action.Transaction: runTransactions :: forall m env. (HasTezosRpc m, HasTezosClient m, WithClientLog env m) => ImplicitAddressWithAlias -> [TransactionData] -> m (Maybe (OperationHash, [OperationInfo Result]))
- Morley.Client.Action.Transaction: transfer :: forall m t env kind. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, ParameterScope t, L1AddressKind kind) => ImplicitAddress -> KindedAddress kind -> Mutez -> EpName -> Value t -> Maybe Mutez -> m (OperationHash, [IntOpEvent])
+ Morley.Client.Action.Transaction: transfer :: forall m t env kind. (HasTezosRpc m, HasTezosClient m, WithClientLog env m, ParameterScope t, L1AddressKind kind) => ImplicitAddressWithAlias -> KindedAddress kind -> Mutez -> EpName -> Value t -> Maybe Mutez -> m (OperationHash, [IntOpEvent])
- Morley.Client.RPC.API: NodeMethods :: (BlockId -> m Text) -> (BlockId -> ImplicitAddress -> m TezosInt64) -> (BlockId -> ContractAddress -> m OriginationScript) -> (BlockId -> ContractAddress -> m Expression) -> (BlockId -> m BlockConstants) -> (BlockId -> m BlockHeader) -> (BlockId -> m ProtocolParameters) -> (BlockId -> m [[BlockOperation]]) -> (BlockId -> m [[OperationHash]]) -> (BlockId -> ContractAddress -> GetBigMap -> m GetBigMapResult) -> (BlockId -> Natural -> Text -> m Expression) -> (BlockId -> Natural -> Maybe Natural -> Maybe Natural -> m Expression) -> (BlockId -> Address -> m TezosMutez) -> (BlockId -> L1Address -> m (Maybe KeyHash)) -> (BlockId -> CalcSize -> m ScriptSize) -> (BlockId -> ForgeOperation -> m HexJSONByteString) -> (BlockId -> RunOperation -> m RunOperationResult) -> (BlockId -> [PreApplyOperation] -> m [RunOperationResult]) -> (BlockId -> RunCode -> m RunCodeResult) -> (BlockId -> ImplicitAddress -> m (Maybe PublicKey)) -> m Text -> (HexJSONByteString -> m OperationHash) -> NodeMethods m
+ Morley.Client.RPC.API: NodeMethods :: (BlockId -> m Text) -> (BlockId -> ImplicitAddress -> m TezosInt64) -> (BlockId -> ContractAddress -> m OriginationScript) -> (BlockId -> ContractAddress -> m Expression) -> (BlockId -> Address -> GetTicketBalance -> m TezosNat) -> (BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]) -> (BlockId -> m BlockConstants) -> (BlockId -> m BlockHeader) -> (BlockId -> m ProtocolParameters) -> (BlockId -> m [[BlockOperation]]) -> (BlockId -> m [[OperationHash]]) -> (BlockId -> ContractAddress -> GetBigMap -> m GetBigMapResult) -> (BlockId -> Natural -> Text -> m Expression) -> (BlockId -> Natural -> Maybe Natural -> Maybe Natural -> m Expression) -> (BlockId -> Address -> m TezosMutez) -> (BlockId -> L1Address -> m (Maybe KeyHash)) -> (BlockId -> CalcSize -> m ScriptSize) -> (BlockId -> ForgeOperation -> m HexJSONByteString) -> (BlockId -> RunOperation -> m RunOperationResult) -> (BlockId -> [PreApplyOperation] -> m [RunOperationResult]) -> (BlockId -> RunCode -> m RunCodeResult) -> (BlockId -> ImplicitAddress -> m (Maybe PublicKey)) -> m Text -> (HexJSONByteString -> m OperationHash) -> NodeMethods m
- Morley.Client.TezosClient.Class: genFreshKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddress
+ Morley.Client.TezosClient.Class: genFreshKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddressWithAlias
- Morley.Client.TezosClient.Class: genKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddress
+ Morley.Client.TezosClient.Class: genKey :: HasTezosClient m => ImplicitAlias -> m ImplicitAddressWithAlias
- Morley.Client.TezosClient.Class: getKeyPassword :: HasTezosClient m => ImplicitAddress -> m (Maybe ScrubbedBytes)
+ Morley.Client.TezosClient.Class: getKeyPassword :: HasTezosClient m => ImplicitAddressWithAlias -> m (Maybe ScrubbedBytes)
- Morley.Client.TezosClient.Class: signBytes :: HasTezosClient m => ImplicitAddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
+ Morley.Client.TezosClient.Class: signBytes :: HasTezosClient m => ImplicitAddressWithAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
- Morley.Client.TezosClient.Impl: getKeyPassword :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadMask m, HasTezosClient m) => ImplicitAddress -> m (Maybe ScrubbedBytes)
+ Morley.Client.TezosClient.Impl: getKeyPassword :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadMask m) => ImplicitAlias -> m (Maybe ScrubbedBytes)
- Morley.Client.TezosClient.Impl: getPublicKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, HasTezosClient m) => ImplicitAddressOrAlias -> m PublicKey
+ Morley.Client.TezosClient.Impl: getPublicKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => ImplicitAlias -> m PublicKey
- Morley.Client.TezosClient.Impl: getSecretKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, HasTezosClient m) => ImplicitAddressOrAlias -> m SecretKey
+ Morley.Client.TezosClient.Impl: getSecretKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => ImplicitAlias -> m SecretKey
- Morley.Client.TezosClient.Impl: importKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> ImplicitAlias -> SecretKey -> m ImplicitAlias
+ Morley.Client.TezosClient.Impl: importKey :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => Bool -> ImplicitAlias -> SecretKey -> m ImplicitAddressWithAlias
- Morley.Client.TezosClient.Impl: signBytes :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, HasTezosClient m) => ImplicitAddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
+ Morley.Client.TezosClient.Impl: signBytes :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m) => ImplicitAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
- Morley.Client.TezosClient.Impl: type family ResolvedAlias addressOrAlias :: Type;
+ Morley.Client.TezosClient.Impl: type family ResolvedAddressAndAlias addressOrAlias :: Type;
- Morley.Client.Types: _OpDelegation :: forall i_aNUu. Prism' (OperationInfo i_aNUu) (DelegationInfo i_aNUu)
+ Morley.Client.Types: _OpDelegation :: forall i_aGJ8. Prism' (OperationInfo i_aGJ8) (DelegationInfo i_aGJ8)
- Morley.Client.Types: _OpOriginate :: forall i_aNUu. Prism' (OperationInfo i_aNUu) (OriginationInfo i_aNUu)
+ Morley.Client.Types: _OpOriginate :: forall i_aGJ8. Prism' (OperationInfo i_aGJ8) (OriginationInfo i_aGJ8)
- Morley.Client.Types: _OpReveal :: forall i_aNUu. Prism' (OperationInfo i_aNUu) (RevealInfo i_aNUu)
+ Morley.Client.Types: _OpReveal :: forall i_aGJ8. Prism' (OperationInfo i_aGJ8) (RevealInfo i_aGJ8)
- Morley.Client.Types: _OpTransfer :: forall i_aNUu. Prism' (OperationInfo i_aNUu) (TransferInfo i_aNUu)
+ Morley.Client.Types: _OpTransfer :: forall i_aGJ8. Prism' (OperationInfo i_aGJ8) (TransferInfo i_aGJ8)
- Morley.Client.Util: withAmount :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) Mutez
+ Morley.Client.Util: withAmount :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) Mutez
- Morley.Client.Util: withBalance :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) Mutez
+ Morley.Client.Util: withBalance :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) Mutez
- Morley.Client.Util: withLevel :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) (Maybe Natural)
+ Morley.Client.Util: withLevel :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) (Maybe Natural)
- Morley.Client.Util: withNow :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) (Maybe Timestamp)
+ Morley.Client.Util: withNow :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) (Maybe Timestamp)
- Morley.Client.Util: withSender :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) (Maybe ImplicitAddress)
+ Morley.Client.Util: withSender :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) (Maybe ImplicitAddress)
- Morley.Client.Util: withSource :: forall cp_a1HvI st_a1HvJ. Lens' (RunContractParameters cp_a1HvI st_a1HvJ) (Maybe ImplicitAddress)
+ Morley.Client.Util: withSource :: forall cp_a1MRU st_a1MRV. Lens' (RunContractParameters cp_a1MRU st_a1MRV) (Maybe ImplicitAddress)

Files

CHANGES.md view
@@ -1,5 +1,48 @@ <!-- Unreleased: append new entries here --> ++0.3.1+=====+* [!1331](https://gitlab.com/morley-framework/morley/-/merge_requests/1331)+  Support implicit account tickets+  + New `transfer-ticket` CLI command;+  + New operation type, `OpTransferTicket`;+  + Add `ToTAddress` instance for `AddressWithAlias`;+* [!1330](https://gitlab.com/morley-framework/morley/-/merge_requests/1330)+  Support ticket balance queries+* [!1328](https://gitlab.com/morley-framework/morley/-/merge_requests/1328)+  Kill support for TORUs, minimal sr1 address support, tz4 address support+* [!1329](https://gitlab.com/morley-framework/morley/-/merge_requests/1329)+  Fix gas limit computation+  + Fixes a bug where in some cases batched transfer could exceed hard gas+    limit.+* [!1313](https://gitlab.com/morley-framework/morley/-/merge_requests/1313)+  Add `contractStateResolver` getter to build Morley interpreter's+  `ContractState` from chain.+* [!1315](https://gitlab.com/morley-framework/morley/-/merge_requests/1315)+  Avoid redundant calls to octez-client address store+  + Introduce `AddressWithAlias` and ways to resolve it (i.e.+    `resolveAddressWithAlias`/`-Either`/`-Maybe`)+  + Make RPC revelation and delegation more efficient, deprecate less efficient+   `revealKeyOp` and `revealKeyUnlessRevealedOp`+  + Use `AddressWithAlias` in critical code paths and key generators+  + Add batched delegation+* [!1304](https://gitlab.com/morley-framework/morley/-/merge_requests/1304)+  Relax lOriginateLargeContract constraints+  + Now requires `NiceParameter` like other origination functions instead of+    `NiceParameterFull`+* [!1286](https://gitlab.com/morley-framework/morley/-/merge_requests/1286)+  Use RPC revealing in `runOperationsNonEmptyHelper`+  + Replace `revealKey` with `getPublicKey` in `HasTezosClient`.+  + Move `Morley.Client.Action.Common.revealKeyUnlessRevealed` to+    `TezosClient.Impl`.+  + Implement key revealing in `runOperationsNonEmptyHelper` via prepending the+    reveal operation to the batch.+  + Rename `Morley.Client.Action.Reveal.revealKey*` to `*Op`, since those inject+    raw revelation **op**erations.+  + Introduce utility versions of `Morley.Client.Action.Reveal.revealKey*` that+    get the key using `getPublicKey`.+ 0.3.0 ===== * [!1281](https://gitlab.com/morley-framework/morley/-/merge_requests/1281)
LICENSE view
@@ -1,5 +1,5 @@ MIT License-Copyright (c) 2021-2022 Oxhead Alpha+Copyright (c) 2021-2023 Oxhead Alpha Copyright (c) 2019-2021 Tocqueville Group  Permission is hereby granted, free of charge, to any person obtaining a copy
README.md view
@@ -1,3 +1,7 @@+> :warning: **Note: this project is being deprecated.**+>+> It will no longer be maintained after the activation of protocol "N" on the Tezos mainnet.+ # Morley-client  This package implements a client to interact with the Tezos blockchain.
app/Main.hs view
@@ -8,7 +8,9 @@ import Control.Exception.Safe (throwString) import Data.Aeson qualified as Aeson import Data.Default (def)-import Fmt (blockListF, pretty)+import Data.Singletons (demote, fromSing)+import Data.Type.Equality (pattern Refl)+import Fmt (blockListF, build, nameF, pretty, (+|), (|+)) import GHC.IO.Encoding (setFileSystemEncoding) import Options.Applicative qualified as Opt import System.IO (utf8)@@ -17,14 +19,16 @@ import Morley.Client.Parser import Morley.Client.RPC import Morley.Client.Util (extractAddressesFromValue)+import Morley.Micheline (fromExpression, toExpression, unStringEncode) import Morley.Michelson.Runtime (prepareContract)-import Morley.Michelson.TypeCheck-  (typeCheckContract, typeCheckContractAndStorage, typeCheckingWith, typeVerifyParameter)+import Morley.Michelson.TypeCheck qualified as TC import Morley.Michelson.Typed (Contract, Contract'(..), SomeContract(..))+import Morley.Michelson.Typed qualified as T import Morley.Michelson.Typed.Value (Value'(..)) import Morley.Michelson.Untyped qualified as U import Morley.Tezos.Address import Morley.Tezos.Core (prettyTez)+import Morley.Util.Constrained import Morley.Util.Exception (throwLeft) import Morley.Util.Main (wrapMain) @@ -34,8 +38,9 @@     Originate OriginateArgs{..} -> do       contract <- liftIO $ prepareContract oaMbContractFile       let originator = oaOriginateFrom+      originatorAA <- resolveAddressWithAlias originator       (operationHash, contractAddr) <--        originateUntypedContract OverwriteDuplicateAlias oaContractName originator oaInitialBalance+        originateUntypedContract OverwriteDuplicateAlias oaContractName originatorAA oaInitialBalance           contract oaInitialStorage oaMbFee oaDelegate        putTextLn "Contract was successfully deployed."@@ -43,32 +48,64 @@       putTextLn $ "Contract address: " <> formatAddress contractAddr      Transfer TransferArgs{..} -> do-      sendAddress <- resolveAddress taSender+      sendAddress <- resolveAddressWithAlias taSender       destAddress <- resolveAddress taDestination-      (operationHash :: OperationHash, contractEvents :: [IntOpEvent]) <- case destAddress of-        Constrained destContract@ContractAddress{} -> do-          contract <- getContract destContract-          SomeContract fullContract <--            throwLeft $ pure $ typeCheckingWith def $ typeCheckContract contract-          case fullContract of-            (Contract{} :: Contract cp st) -> do-              let addrs = extractAddressesFromValue taParameter & mapMaybe \case-                    MkAddress x@ContractAddress{} -> Just x-                    _ -> Nothing-              tcOriginatedContracts <- getContractsParameterTypes addrs-              parameter <- throwLeft $ pure $ typeCheckingWith def $-                typeVerifyParameter @cp tcOriginatedContracts taParameter-              transfer sendAddress destContract taAmount U.DefEpName parameter taMbFee-        Constrained destImplicit@ImplicitAddress {} -> case taParameter of-          U.ValueUnit -> transfer sendAddress destImplicit taAmount U.DefEpName VUnit Nothing-          _ -> throwString ("The transaction parameter must be 'Unit' "-            <> "when transferring to an implicit account")+      (operationHash, contractEvents) :: (OperationHash, [IntOpEvent]) <-+        withConstrained destAddress \case+          destContract@ContractAddress{} -> do+            contract <- getContract destContract+            SomeContract (Contract{} :: Contract cp st) <-+              throwLeft $ pure $ TC.typeCheckingWith def $ TC.typeCheckContract contract+            let addrs = extractAddressesFromValue taParameter & mapMaybe \case+                  MkAddress x@ContractAddress{} -> Just x+                  _ -> Nothing+            tcOriginatedContracts <- getContractsParameterTypes addrs+            parameter <- throwLeft $ pure $ TC.typeCheckingWith def $+              TC.typeVerifyParameter @cp tcOriginatedContracts taParameter+            transfer sendAddress destContract taAmount U.DefEpName parameter taMbFee+          destImplicit@ImplicitAddress {} -> case taParameter of+            U.ValueUnit -> transfer sendAddress destImplicit taAmount U.DefEpName VUnit Nothing+            _ -> throwString ("The transaction parameter must be 'Unit' "+              <> "when transferring to an implicit account")        putTextLn $ "Transaction was successfully sent.\nOperation hash " <> pretty operationHash <> "."       unless (null contractEvents) do         putTextLn $ "Additionally, the following contract events were emitted:"         putTextLn $ pretty $ blockListF contractEvents +    TransferTicket TransferTicketArgs{..} -> T.withUType ttaTicketType \(_ :: T.Notes t) -> do+      T.Dict <- throwLeft $ pure $ first (TC.UnsupportedTypeForScope (demote @t))+        $ T.checkScope @(T.ParameterScope t, T.Comparable t)+      sendAddress <- resolveAddressWithAlias ttaSender+      destAddress <- resolveAddress ttaDestination+      ticketer <- resolveAddress ttaTicketTicketer+      (operationHash, contractEvents) :: (OperationHash, [IntOpEvent]) <-+        withConstrained destAddress \case+          destContract@ContractAddress{} -> do+            contract <- getContract destContract+            SomeContract (Contract{} :: Contract cp st) <-+              throwLeft $ pure $ TC.typeCheckingWith def $ TC.typeCheckContract contract+            Constrained (_ :: T.SingT t') :: Constrained T.SingI T.SingT <- case T.sing @cp of+              T.STTicket x -> pure $ Constrained @T.SingI x+              x -> throwM $ TC.TcContractError @U.ExpandedOp+                ("Expected contract to accept tickets, but it had type " <> pretty (fromSing x))+                $ Just $ TC.UnexpectedType (one $ one $ "ticket 'a")+            Refl <- T.requireEq @t @t' $ throwM . TC.TypeEqError+            parameter <- throwLeft $ pure $ TC.typeCheckingWith def $ do+              TC.typeCheckValue @t' ttaTicketContents+            transferTicket @_ @t' sendAddress destContract ticketer parameter ttaTicketAmount+              U.DefEpName ttaMbFee+          destImplicit@ImplicitAddress{} -> do+            parameter <- throwLeft $ pure $ TC.typeCheckingWith def $+                  TC.typeCheckValue @t ttaTicketContents+            transferTicket sendAddress destImplicit ticketer parameter ttaTicketAmount+                  U.DefEpName ttaMbFee++      putTextLn $ "Tickets successfully sent.\nOperation hash " <> pretty operationHash <> "."+      unless (null contractEvents) do+        putTextLn $ "Additionally, the following contract events were emitted:"+        putTextLn $ pretty $ blockListF contractEvents+     GetBalance addrOrAlias -> do       balance <- getBalance =<< resolveAddress addrOrAlias       putTextLn $ prettyTez balance@@ -79,8 +116,8 @@      GetScriptSize GetScriptSizeArgs{..} -> do       contract <- liftIO $ prepareContract (Just ssScriptFile)-      void . throwLeft . pure . typeCheckingWith def $-        typeCheckContractAndStorage contract ssStorage+      void . throwLeft . pure . TC.typeCheckingWith def $+        TC.typeCheckContractAndStorage contract ssStorage       size <- computeUntypedContractSize contract ssStorage       print size @@ -95,6 +132,25 @@             OtherOpResp -> putTextLn "Non-transaction operation"           putTextLn ""       putTextLn "——————————————————————————————————————————————————\n"+    TicketBalance owner' TicketBalanceArgs{..} -> do+      owner <- resolveAddress owner'+      bal <- getTicketBalance owner GetTicketBalance+        { gtbContent = toExpression tbaContent+        , gtbContentType = toExpression tbaContentType+        , gtbTicketer = tbaTicketer+        }+      print bal+    AllTicketBalances owner' -> do+      owner <- resolveAddress owner'+      bals <- getAllTicketBalances owner+      forM_ bals \GetAllTicketBalancesResponse{..} -> do+        content <- either throwM pure $ fromExpression @U.Value gatbrContent+        ty <- either throwM pure $ fromExpression @U.Ty gatbrContentType+        putTextLn $ pretty @Text $+          nameF "Ticketer" (build gatbrTicketer) |+ ", "+          +| nameF "content" (build content) |+ ", "+          +| nameF "type" (build ty) |+ ", "+          +| nameF "amount" (build $ unStringEncode gatbrAmount)  main :: IO () main = wrapMain $ do
morley-client.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           morley-client-version:        0.3.0+version:        0.3.1 synopsis:       Client to interact with the Tezos blockchain description:    A client to interact with the Tezos blockchain, by use of the octez-node RPC and/or of the octez-client binary. category:       Blockchain@@ -13,7 +13,7 @@ bug-reports:    https://gitlab.com/morley-framework/morley/-/issues author:         Serokell, Tocqueville Group maintainer:     Serokell <hi@serokell.io>-copyright:      2019-2021 Tocqueville Group, 2021-2022 Oxhead Alpha+copyright:      2019-2021 Tocqueville Group, 2021-2023 Oxhead Alpha license:        MIT license-file:   LICENSE build-type:     Simple@@ -228,6 +228,7 @@     , morley-prelude     , optparse-applicative     , safe-exceptions+    , singletons   default-language: Haskell2010  test-suite morley-client-test@@ -245,6 +246,7 @@       Test.ParameterTypeGet       Test.Parser       Test.ReadBigMapValue+      Test.Resolve       Test.Transaction       Test.Util       TestM@@ -313,7 +315,6 @@     , bytestring     , co-log     , co-log-core-    , containers     , exceptions     , fmt     , hex-text
src/Morley/Client.hs view
@@ -51,6 +51,10 @@   , getDelegate   , runCode   , getManagerKey+  , getTicketBalance+  , getAllTicketBalances+  , GetTicketBalance (..)+  , GetAllTicketBalancesResponse (..)    -- ** Errors   , ClientRpcError (..)@@ -74,11 +78,16 @@   , getAliasMaybe   , resolveAddress   , resolveAddressMaybe+  , resolveAddressWithAlias+  , resolveAddressWithAliasMaybe   , TezosClientError (..)   , AliasBehavior (..)    -- * Util   , disableAlphanetWarning+  , AddressWithAlias(..)+  , ImplicitAddressWithAlias+  , ContractAddressWithAlias    -- * Reexports   , Opt.ParserInfo -- Needed for tests
src/Morley/Client/Action.hs view
@@ -10,13 +10,14 @@   , module Morley.Client.Action.Origination   , module Morley.Client.Action.Transaction   , module Morley.Client.Action.SizeCalculation+  , module Morley.Client.Action.Reveal   , ClientInput-  , revealKeyUnlessRevealed   ) where -import Morley.Client.Action.Common (ClientInput, revealKeyUnlessRevealed)+import Morley.Client.Action.Common (ClientInput) import Morley.Client.Action.Delegation import Morley.Client.Action.Operation import Morley.Client.Action.Origination+import Morley.Client.Action.Reveal import Morley.Client.Action.SizeCalculation import Morley.Client.Action.Transaction
src/Morley/Client/Action/Batched.hs view
@@ -7,6 +7,7 @@   , originateContractM   , runTransactionM   , revealKeyM+  , delegateM   , runOperationsBatch   ) where @@ -21,7 +22,6 @@ import Morley.Client.TezosClient import Morley.Client.Types import Morley.Tezos.Address-import Morley.Tezos.Address.Alias import Morley.Util.Batching  {- | Where the batched operations occur.@@ -79,13 +79,17 @@ revealKeyM :: RevealData -> OperationsBatch () revealKeyM = runOperationM OpReveal _OpReveal +-- | Perform delegation within a batch.+delegateM :: DelegationData -> OperationsBatch ()+delegateM = runOperationM OpDelegation _OpDelegation+ -- | Execute a batch. runOperationsBatch   :: ( HasTezosRpc m      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> OperationsBatch a   -> m (Maybe OperationHash, a) runOperationsBatch sender (OperationsBatch batch) =
src/Morley/Client/Action/Common.hs view
@@ -8,11 +8,13 @@   , TD (..)   , TransactionData(..)   , OriginationData(..)+  , TransferTicketData(..)   , RevealData(..)   , DelegationData(..)   , ClientInput   , addOperationPrefix   , buildTxDataWithAlias+  , buildTxTicketDataWithAlias   , getAppliedResults   , computeFee   , computeStorageLimit@@ -23,18 +25,15 @@   , updateCommonData   , toParametersInternals   , mkOriginationScript-  , revealKeyUnlessRevealed   , handleOperationResult   , runErrorsToClientError   ) where  import Control.Lens (Prism')-import Data.ByteArray (ScrubbedBytes) import Data.ByteString (cons) import Data.Default (def) import Fmt (Buildable(..), Builder, (+|), (|+)) -import Morley.Client.Logging (WithClientLog, logDebug) import Morley.Client.RPC.Class import Morley.Client.RPC.Error import Morley.Client.RPC.Getters@@ -92,6 +91,19 @@     buildMbAlias :: Maybe Text -> Builder     buildMbAlias = maybe "" $ \a -> " (" +| a |+ ")" +-- | Builds 'TransactionData' with additional info about receiver's alias, if present.+buildTxTicketDataWithAlias :: Maybe Text -> TransferTicketData -> Builder+buildTxTicketDataWithAlias mbAlias+  (TransferTicketData contents ticketer amount dest ep _mbFee) =+  "To: " +| dest |+ buildMbAlias mbAlias |+ ". EP: " +| ep+  |+ ". Ticketer: " +| ticketer+  |+ " contents: " +| contents+  |+ " amount: " +| amount+  |+ ""+  where+    buildMbAlias :: Maybe Text -> Builder+    buildMbAlias = maybe "" $ \a -> " (" +| a |+ ")"+ -- | Data for a single origination in a batch data OriginationData =   forall cp st. (ParameterScope cp, StorageScope st) => OriginationData@@ -116,10 +128,20 @@   , rdMbFee :: Maybe Mutez   } +data TransferTicketData = forall t. (ParameterScope t, Comparable t) => TransferTicketData+  { ttdTicketContents :: T.Value t+  , ttdTicketTicketer :: Address+  , ttdTicketAmount :: Natural+  , ttdDestination :: Address+  , ttdEntrypoint :: EpName+  , ttdMbFee :: Maybe Mutez+  }+ -- | Standard operation input in morley-client interface. data ClientInput instance OperationInfoDescriptor ClientInput where   type TransferInfo ClientInput = TransactionData+  type TransferTicketInfo ClientInput = TransferTicketData   type OriginationInfo ClientInput = OriginationData   type RevealInfo ClientInput = RevealData   type DelegationInfo ClientInput = DelegationData@@ -253,21 +275,6 @@     findError :: Prism' RunError a -> Maybe a     findError prism = fmap head . nonEmpty . mapMaybe (preview prism) $ errs --- | Reveal key for implicit address if necessary.------ Throws an error if given address is a contract address.-revealKeyUnlessRevealed-  :: (WithClientLog env m, HasTezosRpc m, HasTezosClient m)-  => ImplicitAddress-  -> Maybe ScrubbedBytes-  -> m ()-revealKeyUnlessRevealed addr mbPassword = do-  alias <- getAlias $ AddressResolved addr-  mbManagerKey <- getManagerKey addr-  case mbManagerKey of-    Nothing -> revealKey alias mbPassword-    Just _  -> logDebug $ alias |+ " alias has already revealed key"- -- | Compute fee for operation. computeFee :: FeeConstants -> Int -> TezosInt64 -> Mutez computeFee FeeConstants{..} opSize gasLimit =@@ -342,4 +349,11 @@  prepareOpForInjection :: ByteString -> Signature -> ByteString prepareOpForInjection operationHex signature' =-  operationHex <> signatureToBytes signature'+  operationHex <> prefix <> signatureToBytes signature'+  where+    prefix+      -- Apparently, because BLS signature is longer than other ones, this hacky+      -- workaround is employed. This may or may not come up elsewhere.+      -- see https://gitlab.com/tezos/tezos/-/merge_requests/5444+      | SignatureBLS{} <- signature' = "\xff\x03"+      | otherwise = mempty
src/Morley/Client/Action/Delegation.hs view
@@ -16,7 +16,6 @@ import Morley.Client.TezosClient.Class import Morley.Client.Types import Morley.Tezos.Address-import Morley.Tezos.Address.Alias import Morley.Tezos.Crypto  -- | Set or revoke a delegate for the sender.@@ -47,7 +46,7 @@      , HasTezosClient m      , MonadReader env m      , HasLog env Message m)-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> Maybe KeyHash   -> m OperationHash setDelegateOp sender delegate =@@ -60,6 +59,8 @@      , HasTezosClient m      , MonadReader env m      , HasLog env Message m)-  => KeyHash+  => ImplicitAddressWithAlias   -> m OperationHash-registerDelegateOp sender = setDelegateOp (AddressResolved . ImplicitAddress $ sender) (Just sender)+registerDelegateOp sender = do+  let senderKh = unImplicitAddress $ awaAddress sender+  setDelegateOp sender (Just senderKh)
src/Morley/Client/Action/Operation.hs view
@@ -13,8 +13,9 @@ import Control.Lens (has, (%=), (&~)) import Data.List (zipWith4) import Data.List.NonEmpty qualified as NE+import Data.Map qualified as Map import Data.Ratio ((%))-import Data.Singletons (Sing, SingI, sing)+import Data.Singletons (Sing, SingI, demote, sing) import Data.Text qualified as T import Fmt (blockListF, blockListF', listF, nameF, pretty, (+|), (|+)) @@ -26,7 +27,9 @@ import Morley.Client.RPC.Types import Morley.Client.TezosClient import Morley.Client.Types-import Morley.Micheline (StringEncode(..), TezosInt64, TezosMutez(..))+import Morley.Client.Util (epNameToTezosEp)+import Morley.Micheline (StringEncode(..), TezosInt64, TezosMutez(..), toExpression)+import Morley.Michelson.Typed (Value) import Morley.Tezos.Address import Morley.Tezos.Address.Alias import Morley.Tezos.Core@@ -39,33 +42,32 @@ data Result instance OperationInfoDescriptor Result where   type TransferInfo Result = [IntOpEvent]+  type TransferTicketInfo Result = [IntOpEvent]   type OriginationInfo Result = ContractAddress   type RevealInfo Result = ()   type DelegationInfo Result = ()  logOperations-  :: forall (runMode :: RunMode) env m kind.+  :: forall env m kind.      ( WithClientLog env m      , HasTezosClient m-     , MonadThrow m-     , SingI runMode -- We don't ask aliases with @octez-client@ in 'DryRun' mode-     , L1AddressKind kind      )-  => AddressOrAlias kind+  => AddressWithAlias kind   -> NonEmpty (OperationInfo ClientInput)   -> m () logOperations sender ops = do-  let runMode = sing @runMode--      opName =+  let opName =         if | all (has _OpTransfer) ops -> "transactions"            | all (has _OpOriginate) ops -> "originations"            | all (has _OpReveal) ops -> "reveals"+           | all (has _OpTransferTicket) ops -> "ticket transfers"            | otherwise -> "operations"        buildOp = \case         (OpTransfer tx, mbAlias) ->           buildTxDataWithAlias mbAlias tx+        (OpTransferTicket tx, mbAlias) ->+          buildTxTicketDataWithAlias mbAlias tx         (OpOriginate orig, _) ->           odName orig |+ " (temporary alias)"         (OpReveal rv, mbAlias) ->@@ -73,28 +75,29 @@         (OpDelegation delegate, mbAlias) ->           "Key Hash " +| ddDelegate delegate |+ maybe "" (\a -> " (" +| a |+ ")") mbAlias -  sender' <- case sender of-    addr@AddressResolved{} -> case runMode of-      SRealRun -> AddressAlias <$> getAlias sender-      SDryRun  -> pure addr-    alias -> pure alias+  let needsAliasStore = (`any` ops) \case+        OpTransfer{} -> True+        OpTransferTicket{} -> True+        OpOriginate{} -> False+        OpReveal{} -> True+        OpDelegation{} -> True -  aliases <- case runMode of-    SRealRun ->-      forM ops $ \case-        OpTransfer (TransactionData tx) -> withConstrained (tdReceiver tx) $-          fmap (Just . pretty) . getAlias . AddressResolved-        OpOriginate _ ->-          pure Nothing-        OpReveal r ->-          Just . pretty <$> (getAlias . AddressResolved . mkKeyAddress $ rdPublicKey r)-        OpDelegation d ->-          maybe (pure Nothing)-                (fmap (Just . pretty) . getAlias . AddressResolved . ImplicitAddress) $ ddDelegate d-    SDryRun -> pure $ ops $> Nothing+  anas <- if needsAliasStore+    then Map.fromList . fmap swap <$> getAliasesAndAddresses+    else pure mempty +  let mbAlias :: KindedAddress k -> Maybe Text+      mbAlias addr = Map.lookup (pretty addr) anas++  let aliases = ops <&> \case+        OpTransfer (TransactionData tx) -> withConstrained (tdReceiver tx) mbAlias+        OpTransferTicket TransferTicketData{..} -> withConstrained ttdDestination mbAlias+        OpOriginate _ -> Nothing+        OpReveal r -> mbAlias . mkKeyAddress $ rdPublicKey r+        OpDelegation d -> mbAlias . ImplicitAddress =<< ddDelegate d+   logInfo $ T.strip $ -- strip trailing newline-    "Running " +| opName +| " by " +| sender' |+ ":\n" +|+    "Running " +| opName +| " by " +| sender |+ ":\n" +|     blockListF' "-" buildOp (ops `NE.zip` aliases)  -- | Perform sequence of operations.@@ -107,7 +110,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> [OperationInfo ClientInput]   -> m (Maybe OperationHash, [OperationInfo Result]) runOperations sender operations = case operations of@@ -130,7 +133,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> NonEmpty (OperationInfo ClientInput)   -> m (OperationHash, NonEmpty (OperationInfo Result)) runOperationsNonEmpty sender operations =@@ -172,7 +175,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> NonEmpty (OperationInfo ClientInput)   -> m (NonEmpty (AppliedResult, TezosMutez)) dryRunOperationsNonEmpty sender operations =@@ -189,11 +192,16 @@      , SingI runMode      )   => Natural-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> NonEmpty (OperationInfo ClientInput)   -> m (RunResult runMode)-runOperationsNonEmptyHelper retryCount sender operations = do-  logOperations @runMode sender operations+runOperationsNonEmptyHelper retryCount sender@(AddressWithAlias senderAddress _) operations' = do+  operations <- fromMaybe operations' <$> runMaybeT do+    guard $ isRealRun @runMode && mayNeedSenderRevealing (toList operations')+    Nothing <- lift $ getManagerKey senderAddress+    pk <- lift $ getPublicKey sender+    pure $ OpReveal (RevealData pk Nothing) :| toList operations'+  logOperations sender operations   -- If we intend to fail on duplicate aliases, we want to fail now, rather than   -- after contract origination.   forM_ operations $ \case@@ -201,11 +209,7 @@       resolved <- resolveAddressMaybe (AddressAlias odName)       whenJust resolved $ const $ throwM $ DuplicateAlias (unAlias odName)     _ -> pass-  senderAddress <- resolveAddress sender-  mbPassword <- getKeyPassword senderAddress-  when (isRealRun @runMode && mayNeedSenderRevealing (toList operations)) $-    revealKeyUnlessRevealed senderAddress mbPassword-+  mbPassword <- getKeyPassword sender   pp <- getProtocolParameters   OperationConstants{..} <- preProcessOperation senderAddress @@ -216,6 +220,16 @@           , toAmount = TezosMutez tdAmount           , toParameters = toParametersInternals tdEpName tdParam           }+        OpTransferTicket (TransferTicketData {..})+          | _ :: Value t <- ttdTicketContents ->+          OpTransferTicket TransferTicketOperation+          { ttoTicketContents = toExpression ttdTicketContents+          , ttoTicketTy       = toExpression (demote @t)+          , ttoTicketTicketer = ttdTicketTicketer+          , ttoTicketAmount   = StringEncode ttdTicketAmount+          , ttoDestination    = ttdDestination+          , ttoEntrypoint     = epNameToTezosEp ttdEntrypoint+          }         OpOriginate OriginationData{..} ->           OpOriginate OriginationOperation           { ooBalance = TezosMutez odBalance@@ -239,6 +253,7 @@   let opsToRun = NE.zipWith convertOps (1 :| [(2 :: TezosInt64)..]) operations       mbFees = operations <&> \case         OpTransfer (TransactionData TD {..}) -> tdMbFee+        OpTransferTicket TransferTicketData{..} -> ttdMbFee         OpOriginate OriginationData{..} -> odMbFee         OpReveal RevealData{..} -> rdMbFee         OpDelegation DelegationData {..} -> ddMbFee@@ -277,11 +292,12 @@           -- @gasSafetyGuard@ is added to origination operations and transfers to non-implicit           -- accounts, see https://gitlab.com/tezos/tezos/-/blob/v13.0/src/proto_013_PtJakart/lib_client/injection.ml#L750           additionalGas = case internalOp of+            OpTransferTicket{} -> gasSafetyGuard             OpOriginate _ -> gasSafetyGuard             OpTransfer (TransactionOperation {..}) -> case toDestination of               MkAddress ImplicitAddress{} -> 0               MkAddress ContractAddress{} -> gasSafetyGuard-              MkAddress TxRollupAddress{} -> gasSafetyGuard+              MkAddress SmartRollupAddress{} -> gasSafetyGuard             OpReveal _ -> 0             OpDelegation _ -> 0       let storageLimit = computeStorageLimit [ar] pp + 20@@ -356,13 +372,18 @@       operationHash <- waitForOperation $ injectOperation (HexJSONByteString signedOp)       let contractAddrs = arOriginatedContracts <$> ars2       opsRes <- forM (NE.zip operations contractAddrs) $ \case-        (OpTransfer _, []) ->-          return $ OpTransfer $ mapMaybe iopsDataToEmitOp iopsData         (OpTransfer _, addrs) -> do-          logInfo . T.strip $-            "The following contracts were originated during transactions: " +|-            listF addrs |+ ""+          unless (null addrs) $+            logInfo . T.strip $+              "The following contracts were originated during transactions: " +|+              listF addrs |+ ""           return $ OpTransfer $ mapMaybe iopsDataToEmitOp iopsData+        (OpTransferTicket _, addrs) -> do+          unless (null addrs) $+            logInfo . T.strip $+              "The following contracts were originated during transactions: " +|+              listF addrs |+ ""+          return $ OpTransferTicket $ mapMaybe iopsDataToEmitOp iopsData         (OpOriginate _, []) ->           throwM RpcOriginatedNoContracts         (OpOriginate OriginationData{..}, [addr]) -> do@@ -393,6 +414,7 @@     mayNeedSenderRevealing :: [OperationInfo i] -> Bool     mayNeedSenderRevealing = any \case       OpTransfer{} -> True+      OpTransferTicket{} -> True       OpOriginate{} -> True       OpReveal{} -> False       OpDelegation{} -> True
src/Morley/Client/Action/Origination.hs view
@@ -54,15 +54,16 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> [OriginationData]   -> m (Maybe OperationHash, [ContractAddress]) originateContracts sender originations = do   (opHash, res) <- runOperations sender (OpOriginate <$> originations)-  return (opHash, fromOrigination <$> res)+  return (opHash, getOriginations res)   where-    fromOrigination = \case-      OpOriginate r -> r+    getOriginations = mapMaybe \case+      OpOriginate r -> Just r+      OpReveal{} -> Nothing       _ -> error "Unexpectedly not origination"  -- | Originate single contract@@ -76,7 +77,7 @@      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> Contract cp st   -> Value st@@ -96,7 +97,7 @@      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> U.Contract   -> U.Value@@ -116,7 +117,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> [LOriginationData]   -> m (Maybe OperationHash, [ContractAddress]) lOriginateContracts sender' originations =@@ -133,7 +134,7 @@      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> L.Contract cp st vd   -> st@@ -156,11 +157,10 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> [OriginationData]   -> m (Maybe OperationHash, [ContractAddress])-originateLargeContracts sender' largeOriginations = do-  senderAddress <- resolveAddress sender'+originateLargeContracts sender'@(AddressWithAlias senderAddress _) largeOriginations = do   -- calculate large contract originators   let originators = map mkLargeOriginationData largeOriginations   -- originate them. Note: we use the operation hash from here even tho the@@ -172,7 +172,7 @@   -- Note: it is not possible to run these all at once, because the node won't   -- accept a transaction batch where the sum of the storage cost is over 16k,   -- so here we need to run them one by one.-  mapM_ (runTransactions senderAddress . (: [])) . concat $+  mapM_ (runTransactions sender' . (: [])) . concat $     zipWith mkLargeOriginatorTransactions originatorsAddr originators   -- get the addresses of the originated large contracts back from the originators   -- and remember their addresses with their aliases@@ -190,7 +190,7 @@      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> Contract cp st   -> Value st@@ -210,7 +210,7 @@      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> U.Contract   -> U.Value@@ -230,7 +230,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddressOrAlias+  => ImplicitAddressWithAlias   -> [LOriginationData]   -> m (Maybe OperationHash, [ContractAddress]) lOriginateLargeContracts sender' originations =@@ -243,11 +243,11 @@      , HasTezosClient m      , WithClientLog env m      , NiceStorage st-     , NiceParameterFull cp+     , NiceParameter cp      )   => AliasBehavior   -> ContractAlias-  -> ImplicitAddressOrAlias+  -> ImplicitAddressWithAlias   -> Mutez   -> L.Contract cp st vd   -> st@@ -263,7 +263,7 @@ --------------------------------------------------------------------------------  -- | Lorentz version of 'OriginationData'-data LOriginationData = forall cp st vd. (NiceParameterFull cp, NiceStorage st)+data LOriginationData = forall cp st vd. (NiceParameter cp, NiceStorage st)   => LOriginationData   { lodAliasBehavior :: AliasBehavior   , lodName :: ContractAlias
src/Morley/Client/Action/Origination/Large.hs view
@@ -38,7 +38,7 @@  import Data.ByteString.Lazy qualified as LBS -import Lorentz+import Lorentz hiding (bytes) import Morley.Client.Action.Common import Morley.Client.RPC.Class import Morley.Client.RPC.Error
src/Morley/Client/Action/Reveal.hs view
@@ -5,32 +5,66 @@ module Morley.Client.Action.Reveal   ( RevealData (..)   , revealKey+  , revealKeyWithFee   , revealKeyUnlessRevealed+  , revealKeyUnlessRevealedWithFee+  , revealKeyOp+  , revealKeyUnlessRevealedOp   ) where  import Fmt ((|+)) -import Morley.Client.Action.Common hiding (revealKeyUnlessRevealed)+import Morley.Client.Action.Common import Morley.Client.Action.Operation import Morley.Client.Logging import Morley.Client.RPC.Class import Morley.Client.RPC.Error import Morley.Client.RPC.Getters import Morley.Client.RPC.Types-import Morley.Client.TezosClient (HasTezosClient)+import Morley.Client.TezosClient.Class (HasTezosClient(getPublicKey))+import Morley.Client.TezosClient.Impl (getAlias) import Morley.Client.Types-import Morley.Tezos.Address (mkKeyAddress)+import Morley.Tezos.Address import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (Mutez) import Morley.Tezos.Crypto (PublicKey) +-- | Resolve the public key of an implicit address and reveal it.+revealKey+  :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m)+  => ImplicitAddressWithAlias -> m OperationHash+revealKey = (`revealKeyWithFee` Nothing)++-- | Version of 'revealKey' with explicit fee.+revealKeyWithFee+  :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m)+  => ImplicitAddressWithAlias -> Maybe Mutez -> m OperationHash+revealKeyWithFee sender mbFee = do+  pk <- getPublicKey sender+  runRevealOperationRaw sender pk mbFee++-- | Resolve the public key of an implicit address and reveal it, unless already+-- revealed.+revealKeyUnlessRevealed+  :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m)+  => ImplicitAddressWithAlias -> m ()+revealKeyUnlessRevealed = (`revealKeyUnlessRevealedWithFee` Nothing)++-- | Version of 'revealKeyUnlessRevealed' with explicit fee.+revealKeyUnlessRevealedWithFee+  :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m)+  => ImplicitAddressWithAlias -> Maybe Mutez -> m ()+revealKeyUnlessRevealedWithFee sender mbFee = do+  pk <- getPublicKey sender+  handleAlreadyRevealed (flip (runRevealOperationRaw sender) mbFee) pk+ -- | Reveal given key. -- -- Note that sender is implicitly defined by the key being revealed, as you can -- only reveal your own key. -- -- This is a variation of key revealing method that tries to use solely RPC.-revealKey+revealKeyOp -- TODO [#873] remove HasTezosClient dependency   :: forall m env.      ( HasTezosRpc m@@ -40,16 +74,18 @@   => PublicKey   -> Maybe Mutez   -> m OperationHash-revealKey rdPublicKey rdMbFee =-  fmap fst . runOperationsNonEmpty (AddressResolved sender) . one $ OpReveal RevealData{..}+revealKeyOp pk mbFee = do+  senderAlias <- getAlias $ AddressResolved senderAddress+  runRevealOperationRaw (AddressWithAlias senderAddress senderAlias) pk mbFee   where-    sender = mkKeyAddress rdPublicKey+    senderAddress = mkKeyAddress pk+{-# DEPRECATED revealKeyOp "Prefer using 'revealKeyWithFee', as it's a lot more efficient" #-}  -- | Reveal given key. -- -- Note that sender is implicitly defined by the key being revealed, as you can -- only reveal your own key.-revealKeyUnlessRevealed+revealKeyUnlessRevealedOp -- TODO [#873] remove HasTezosClient dependency   :: forall m env.      ( HasTezosRpc m@@ -59,14 +95,31 @@   => PublicKey   -> Maybe Mutez   -> m ()-revealKeyUnlessRevealed key mbFee = do+revealKeyUnlessRevealedOp key mbFee = handleAlreadyRevealed (flip revealKeyOp mbFee) key+{-# DEPRECATED revealKeyUnlessRevealedOp+  "Prefer using 'revealKeyUnlessRevealedWithFee', as it's a lot more efficient" #-}++-- Internals++handleAlreadyRevealed+  :: (HasTezosRpc m, WithClientLog env m)+  => (PublicKey -> m a) -> PublicKey -> m ()+handleAlreadyRevealed doReveal key = do+  let sender = mkKeyAddress key   -- An optimization for the average case, but we can't rely on it in   -- distributed environment-  let sender = mkKeyAddress key   getManagerKey sender >>= \case     Just _  -> logDebug $ sender |+ " address has already revealed key"-    Nothing -> ignoreAlreadyRevealedError . void $ revealKey key mbFee+    Nothing -> ignoreAlreadyRevealedError . void $ doReveal key   where     ignoreAlreadyRevealedError = flip catch \case       RunCodeErrors [PreviouslyRevealedKey _] -> pass       e -> throwM e++-- | Note that sender and rdPublicKey must be consistent, otherwise network will+-- reject the operation+runRevealOperationRaw+  :: (HasTezosRpc m, HasTezosClient m, WithClientLog env m)+  => ImplicitAddressWithAlias -> PublicKey -> Maybe Mutez -> m OperationHash+runRevealOperationRaw sender rdPublicKey rdMbFee =+  fmap fst . runOperationsNonEmpty sender . one $ OpReveal RevealData{..}
src/Morley/Client/Action/Transaction.hs view
@@ -9,11 +9,13 @@   -- * Transfer   , transfer   , lTransfer+  , transferTicket    -- Datatypes for batch transactions   , TD (..)   , LTransactionData (..)   , TransactionData (..)+  , TransferTicketData (..)   ) where  import Lorentz.Constraints@@ -28,7 +30,6 @@ import Morley.Michelson.Typed.Scope import Morley.Michelson.Untyped.Entrypoints import Morley.Tezos.Address-import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (Mutez)  -- | Perform sequence of transactions to the contract. Returns operation hash@@ -39,7 +40,7 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddress -> [TransactionData]+  => ImplicitAddressWithAlias -> [TransactionData]   -> m (Maybe (OperationHash, [OperationInfo Result])) runTransactions sender transactions = runMaybeT do   ts <- hoistMaybe $ nonEmpty transactions@@ -53,10 +54,10 @@      , HasTezosClient m      , WithClientLog env m      )-  => ImplicitAddress -> NonEmpty TransactionData+  => ImplicitAddressWithAlias -> NonEmpty TransactionData   -> m (OperationHash, NonEmpty (OperationInfo Result)) runTransactionsNonEmpty sender =-  runOperationsNonEmpty (AddressResolved sender) . map OpTransfer+  runOperationsNonEmpty sender . map OpTransfer  -- | Lorentz version of 'TransactionData'. data LTransactionData where@@ -71,7 +72,7 @@     , HasTezosClient m     , WithClientLog env m     )-  => ImplicitAddress+  => ImplicitAddressWithAlias   -> [LTransactionData]   -> m (Maybe (OperationHash, [OperationInfo Result])) lRunTransactions sender transactions =@@ -89,7 +90,7 @@     , ParameterScope t     , L1AddressKind kind     )-  => ImplicitAddress+  => ImplicitAddressWithAlias   -> KindedAddress kind   -> Mutez   -> EpName@@ -103,6 +104,32 @@       OpTransfer i -> i       _ -> [] +transferTicket+  :: forall m t env kind.+    ( HasTezosRpc m+    , HasTezosClient m+    , WithClientLog env m+    , ParameterScope t+    , Comparable t+    )+  => ImplicitAddressWithAlias -- ^ Sender+  -> KindedAddress kind -- ^ Destination+  -> ContractAddress -- ^ Ticketer+  -> T.Value t -- ^ Ticket value+  -> Natural -- ^ Ticket amount+  -> EpName -- ^ Destination entrypoint+  -> Maybe Mutez -- ^ Fee+  -> m (OperationHash, [IntOpEvent])+transferTicket from (Constrained -> ttdDestination)+  (Constrained -> ttdTicketTicketer) ttdTicketContents+  ttdTicketAmount ttdEntrypoint ttdMbFee =+  (fmap . second) (getEvents . toList) . runOperationsNonEmpty from . one . OpTransferTicket $+    TransferTicketData{..}+  where+    getEvents = concatMap \case+      OpTransferTicket i -> i+      _ -> []+ lTransfer   :: forall m t env kind.     ( HasTezosRpc m@@ -111,7 +138,7 @@     , NiceParameter t     , L1AddressKind kind     )-  => ImplicitAddress+  => ImplicitAddressWithAlias   -> KindedAddress kind   -> Mutez   -> EpName
src/Morley/Client/App.hs view
@@ -33,6 +33,8 @@   , getChainIdImpl   , getDelegateImpl   , waitForOperationImpl+  , getTicketBalanceAtBlockImpl+  , getAllTicketBalancesAtBlockImpl    -- * Timeouts and retries   , retryOnTimeout@@ -64,7 +66,7 @@ import Morley.Client.Logging (WithClientLog, logDebug) import Morley.Client.RPC import Morley.Client.RPC.API qualified as API-import Morley.Micheline (Expression, TezosInt64, TezosNat, unTezosMutez)+import Morley.Micheline (Expression, TezosInt64, TezosNat, unStringEncode, unTezosMutez) import Morley.Tezos.Address import Morley.Tezos.Core (ChainId, Mutez, parseChainId) import Morley.Tezos.Crypto (KeyHash, PublicKey)@@ -190,6 +192,17 @@   (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> Address -> m Mutez getBalanceImpl =   retryOnceOnTimeout ... fmap unTezosMutez ... API.getBalance API.nodeMethods++getTicketBalanceAtBlockImpl ::+  (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> Address -> GetTicketBalance -> m Natural+getTicketBalanceAtBlockImpl =+  retryOnceOnTimeout ... fmap unStringEncode ... API.getTicketBalanceAtBlock API.nodeMethods++getAllTicketBalancesAtBlockImpl+  :: (RunClient m, MonadUnliftIO m, MonadCatch m)+  => BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]+getAllTicketBalancesAtBlockImpl =+  retryOnceOnTimeout ... API.getAllTicketBalancesAtBlock API.nodeMethods  getDelegateImpl ::   (RunClient m, MonadUnliftIO m, MonadCatch m) => BlockId -> L1Address -> m (Maybe KeyHash)
src/Morley/Client/Full.hs view
@@ -38,6 +38,7 @@ import Morley.Client.TezosClient.Impl (getTezosClientConfig) import Morley.Client.TezosClient.Impl qualified as TezosClient import Morley.Client.TezosClient.Types+import Morley.Client.Types import Morley.Tezos.Crypto (Signature(..)) import Morley.Tezos.Crypto.Ed25519 qualified as Ed25519 import Morley.Util.Lens (makeLensesWith, postfixLFields)@@ -78,19 +79,17 @@   setLogAction action mce = mce { mceLogAction = action }  instance HasTezosClient MorleyClientM where-  signBytes senderAlias mbPassword opHash = retryOnceOnTimeout $ do+  signBytes (AddressWithAlias _ senderAlias) mbPassword opHash = retryOnceOnTimeout $ do     env <- ask     case mceSecretKey env of       Just sk -> pure . SignatureEd25519 $ Ed25519.sign sk opHash       Nothing -> TezosClient.signBytes senderAlias mbPassword opHash   rememberContract = failOnTimeout ... TezosClient.rememberContract   getAliasesAndAddresses = retryOnceOnTimeout ... TezosClient.getAliasesAndAddresses-  genFreshKey = retryOnceOnTimeout ... TezosClient.genFreshKey-  genKey = failOnTimeout ... TezosClient.genKey-  -- Key revealing cannot be safely retried, so we're not trying to recover it-  -- from @ECONNRESET@.-  revealKey = failOnTimeout ... TezosClient.revealKey-  getKeyPassword = retryOnceOnTimeout . TezosClient.getKeyPassword+  genKey alias = flip AddressWithAlias alias <$> TezosClient.genKey alias+  genFreshKey alias = flip AddressWithAlias alias <$> TezosClient.genFreshKey alias+  getKeyPassword (AddressWithAlias _ alias) = retryOnceOnTimeout $ TezosClient.getKeyPassword alias+  getPublicKey (AddressWithAlias _ alias) = TezosClient.getPublicKey alias  instance RunClient MorleyClientM where   runRequestAcceptStatus :: Maybe [Status] -> Request -> MorleyClientM Response@@ -123,6 +122,8 @@   getChainId = getChainIdImpl   getManagerKeyAtBlock = getManagerKeyImpl   waitForOperation = (asks mceClientEnv >>=) . waitForOperationImpl+  getTicketBalanceAtBlock = getTicketBalanceAtBlockImpl+  getAllTicketBalancesAtBlock = getAllTicketBalancesAtBlockImpl   -- | Construct 'MorleyClientEnv'.
src/Morley/Client/OnlyRPC.hs view
@@ -27,8 +27,8 @@ import Morley.Client.RPC.Class (HasTezosRpc(..)) import Morley.Client.RPC.HttpClient (newClientEnv) import Morley.Client.TezosClient.Class (HasTezosClient(..))+import Morley.Client.Types import Morley.Tezos.Address-import Morley.Tezos.Address.Alias import Morley.Tezos.Crypto (SecretKey, sign, toPublic)  ----------------@@ -109,13 +109,11 @@  -- [#652] We may implement more methods here if the need arises. instance HasTezosClient MorleyOnlyRpcM where-  signBytes sender _password opHash = case sender of-    AddressAlias {} -> throwM $ UnsupportedByOnlyRPC "signBytes (AddressAlias _)"-    AddressResolved address -> do-      env <- ask-      case moreSecretKeys env ^. at address of-        Nothing -> throwM $ UnknownSecretKeyFor address-        Just secretKey -> liftIO $ sign secretKey opHash+  signBytes (AddressWithAlias sender _) _password opHash = do+    env <- ask+    case moreSecretKeys env ^. at sender of+      Nothing -> throwM $ UnknownSecretKeyFor sender+      Just secretKey -> liftIO $ sign secretKey opHash    -- In RPC-only mode we only use unencrypted in-memory passwords.   getKeyPassword _ = pure Nothing@@ -135,7 +133,8 @@   -- Actions that are not supported and simply throw exceptions.   genKey _ = throwM $ UnsupportedByOnlyRPC "genKey"   genFreshKey _ = throwM $ UnsupportedByOnlyRPC "genFreshKey"-  revealKey _ _ = throwM $ UnsupportedByOnlyRPC "revealKey"+  getPublicKey (AddressWithAlias addr _) = asks moreSecretKeys >>=+    maybe (throwM $ UnknownSecretKeyFor addr) (pure . toPublic) . view (at addr)  instance RunClient MorleyOnlyRpcM where   runRequestAcceptStatus statuses req = do@@ -167,3 +166,5 @@   getChainId = getChainIdImpl   getManagerKeyAtBlock = getManagerKeyImpl   waitForOperation = (asks moreClientEnv >>=) . waitForOperationImpl+  getTicketBalanceAtBlock = getTicketBalanceAtBlockImpl+  getAllTicketBalancesAtBlock = getAllTicketBalancesAtBlockImpl
src/Morley/Client/Parser.hs view
@@ -7,6 +7,8 @@   , OriginateArgs (..)   , TransferArgs (..)   , GetScriptSizeArgs (..)+  , TicketBalanceArgs (..)+  , TransferTicketArgs (..)   , addressOrAliasOption   , clientConfigParser   , morleyClientInfo@@ -47,9 +49,12 @@   Originate :: OriginateArgs -> ClientArgsRaw   GetScriptSize :: GetScriptSizeArgs -> ClientArgsRaw   Transfer :: TransferArgs -> ClientArgsRaw+  TransferTicket :: TransferTicketArgs -> ClientArgsRaw   GetBalance :: L1AddressKind kind => AddressOrAlias kind -> ClientArgsRaw   GetBlockHeader :: BlockId -> ClientArgsRaw   GetBlockOperations :: BlockId -> ClientArgsRaw+  TicketBalance :: SomeAddressOrAlias -> TicketBalanceArgs -> ClientArgsRaw+  AllTicketBalances :: ContractAddressOrAlias -> ClientArgsRaw  data OriginateArgs = OriginateArgs   { oaMbContractFile :: Maybe FilePath@@ -74,6 +79,16 @@   , taMbFee :: Maybe Mutez   } +data TransferTicketArgs = TransferTicketArgs+  { ttaSender         :: ImplicitAddressOrAlias+  , ttaTicketContents :: U.Value+  , ttaTicketType     :: U.Ty+  , ttaTicketTicketer :: ContractAddressOrAlias+  , ttaTicketAmount   :: Natural+  , ttaDestination    :: SomeAddressOrAlias+  , ttaMbFee          :: Maybe Mutez+  }+ morleyClientInfo :: Opt.ParserInfo ClientArgs morleyClientInfo =   parserInfo@@ -131,6 +146,25 @@                       \By default fee will be computed automatically."             ) +data TicketBalanceArgs = TicketBalanceArgs+  { tbaTicketer :: ContractAddress+  , tbaContent :: U.Value+  , tbaContentType :: U.Ty+  }++getTicketBalanceOption :: Opt.Parser TicketBalanceArgs+getTicketBalanceOption = do+  tbaTicketer <- mkCLOptionParser Nothing+    (#name :! "ticketer")+    (#help :! "The contract that issued the ticket.")+  tbaContentType <- mkCLOptionParser Nothing+    (#name :! "content-type")+    (#help :! "Content type.")+  tbaContent <- valueOption Nothing+    (#name :! "content")+    (#help :! "Ticket content.")+  pure TicketBalanceArgs{..}+ -- | Generic parser to read an option of 'BlockId' type. blockIdOption   :: Maybe BlockId@@ -143,12 +177,27 @@ argsRawParser = subparser $ mconcat   [ originateCmd   , transferCmd+  , transferTicketCmd   , getBalanceCmd   , getScriptSizeCmd   , getBlockHeaderCmd   , getBlockOperationsCmd+  , getTicketBalanceCmd+  , getAllTicketBalancesCmd   ]   where+    ownerOption f = f+      Nothing+      (#name :! "owner")+      (#help :! "Ticket owner")+    getTicketBalanceCmd =+      mkCommandParser "ticket-balance"+      (TicketBalance <$> ownerOption someAddressOrAliasOption <*> getTicketBalanceOption)+      "Get ticket balance for specific tickets"+    getAllTicketBalancesCmd =+      mkCommandParser "all-ticket-balances"+      (AllTicketBalances <$> ownerOption addressOrAliasOption)+      "Get all ticket balances"     originateCmd =       mkCommandParser "originate"       (Originate <$> originateArgsOption)@@ -157,6 +206,10 @@       mkCommandParser "transfer"       (Transfer <$> transferArgsOption)       "Perform a transfer to the given contract with given amount and parameter."+    transferTicketCmd =+      mkCommandParser "transfer-ticket"+      (TransferTicket <$> transferTicketArgsOption)+      "Perform a ticket transfer to the given contract with given amount and parameter."     getBalanceCmd =       mkCommandParser "get-balance"       ((GetBalance <$>@@ -266,6 +319,29 @@       (#help :! "Transfer parameter.")   taMbFee <- feeOption   pure $ TransferArgs {..}++transferTicketArgsOption :: Opt.Parser TransferTicketArgs+transferTicketArgsOption = do+  ttaSender <- addressOrAliasOption Nothing+    ! #name "from"+    ! #help "Address or alias from which transfer is performed."+  ttaTicketAmount <- mkCLOptionParser Nothing+    ! #name "amount"+    ! #help "Ticket amount."+  ttaTicketContents <- mkCLOptionParser Nothing+    ! #name "value"+    ! #help "Ticket value."+  ttaTicketType <- mkCLOptionParser Nothing+    ! #name "type"+    ! #help "Ticket type."+  ttaTicketTicketer <- mkCLOptionParser Nothing+    ! #name "ticketer"+    ! #help "Ticketer address or alias."+  ttaDestination <- someAddressOrAliasOption Nothing+    ! #name "to"+    ! #help "Address or alias of the transfer's destination."+  ttaMbFee <- feeOption+  pure $ TransferTicketArgs {..}  usageDoc :: Doc usageDoc = mconcat
src/Morley/Client/RPC/API.hs view
@@ -8,6 +8,7 @@   , monitorHeads   ) where +import Data.Coerce (coerce) import Network.HTTP.Types.Status (Status(..)) import Servant.API   (Capture, Get, JSON, NewlineFraming, Post, QueryParam, ReqBody, SourceIO, StreamGet,@@ -17,7 +18,7 @@  import Morley.Client.RPC.QueryFixedParam import Morley.Client.RPC.Types-import Morley.Micheline (Expression, TezosInt64, TezosMutez)+import Morley.Micheline (Expression, TezosInt64, TezosMutez, TezosNat) import Morley.Tezos.Address import Morley.Tezos.Address.Kinds import Morley.Tezos.Crypto (KeyHash, PublicKey)@@ -39,6 +40,12 @@     Capture "block_id" BlockId :> "context" :> "contracts" :> Capture "contract" ContractAddress'       :> "storage" :> Get '[JSON] Expression :<|> +    Capture "block_id" BlockId :> "context" :> "contracts" :> Capture "contract" Address'+      :> "ticket_balance" :> ReqBody '[JSON] GetTicketBalance :> Post '[JSON] TezosNat :<|>++    Capture "block_id" BlockId :> "context" :> "contracts" :> Capture "contract" ContractAddress'+      :> "all_ticket_balances" :> Get '[JSON] [GetAllTicketBalancesResponse] :<|>+     Capture "block_id" BlockId :> Get '[JSON] BlockConstants :<|>      Capture "block_id" BlockId :> "header" :> Get '[JSON] BlockHeader :<|>@@ -130,6 +137,8 @@   , getCounter :: BlockId -> ImplicitAddress -> m TezosInt64   , getScript :: BlockId -> ContractAddress -> m OriginationScript   , getStorageAtBlock :: BlockId -> ContractAddress -> m Expression+  , getTicketBalanceAtBlock :: BlockId -> Address -> GetTicketBalance -> m TezosNat+  , getAllTicketBalancesAtBlock :: BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]   , getBlockConstants :: BlockId -> m BlockConstants   , getBlockHeader :: BlockId -> m BlockHeader   , getProtocolParameters :: BlockId -> m ProtocolParameters@@ -156,39 +165,33 @@  nodeMethods :: forall m. (MonadCatch m, RunClient m) => NodeMethods m nodeMethods = NodeMethods-  { getCounter        = withKindedAddress' getCounter'-  , getScript         = withKindedAddress' getScript'-  , getStorageAtBlock = withKindedAddress' getStorageAtBlock'-  , getBigMap         = withKindedAddress' getBigMap'-  , getBalance        = withAddress' getBalance'-  , getDelegate       = \block (Constrained addr) -> do+  { getDelegate       = \block (Constrained addr) -> do       result <- try $ getDelegate' block (Address' $ MkAddress addr)       case result of         Left (FailureResponse _ Response{responseStatusCode=Status{statusCode = 404}})           -> pure Nothing         Left err -> throwM err         Right res -> pure $ Just res-  , getManagerKey     = withKindedAddress' getManagerKey'   , ..   }   where-    withKindedAddress' f blockId = f blockId . KindedAddress'-    withAddress' f blockId = f blockId . Address'     (getBlockHash-        :<|> getCounter'-        :<|> getScript'-        :<|> getStorageAtBlock'+        :<|> (coerce -> getCounter)+        :<|> (coerce -> getScript)+        :<|> (coerce -> getStorageAtBlock)+        :<|> (coerce -> getTicketBalanceAtBlock)+        :<|> (coerce -> getAllTicketBalancesAtBlock)         :<|> getBlockConstants         :<|> getBlockHeader         :<|> getProtocolParameters         :<|> getBlockOperations         :<|> getBlockOperationHashes-        :<|> getBigMap'+        :<|> (coerce -> getBigMap)         :<|> getBigMapValueAtBlock         :<|> getBigMapValuesAtBlock-        :<|> getBalance'+        :<|> (coerce -> getBalance)         :<|> getDelegate'-        :<|> getManagerKey'+        :<|> (coerce -> getManagerKey)         :<|> getScriptSizeAtBlock         :<|> forgeOperation         :<|> runOperation
src/Morley/Client/RPC/Class.hs view
@@ -83,3 +83,12 @@   -- ^ Blocks until an operation with the given hash is included into the chain.   -- The first argument is the action that puts the operation on the chain.   -- Returns the hash of the included operation.+  getTicketBalanceAtBlock :: BlockId -> Address -> GetTicketBalance -> m Natural+  -- ^ Access the contract's or implicit account's balance of ticket with+  -- specified ticketer, content type, and content.+  getAllTicketBalancesAtBlock+    :: BlockId+    -> ContractAddress+    -> m [GetAllTicketBalancesResponse]+  -- ^ Access the complete list of tickets owned by the given contract by+  -- scanning the contract's storage.
src/Morley/Client/RPC/Getters.hs view
@@ -31,6 +31,9 @@   , getDelegate   , runCode   , getManagerKey+  , contractStateResolver+  , getTicketBalance+  , getAllTicketBalances   ) where  import Data.Map as Map (fromList)@@ -42,6 +45,8 @@ import Lorentz (NicePackedValue, NiceUnpackedValue, valueToScriptExpr) import Lorentz.Value import Morley.Micheline+import Morley.Michelson.Runtime.GState (ContractState(..))+import Morley.Michelson.TypeCheck (typeCheckContract, typeCheckingWith) import Morley.Michelson.TypeCheck.TypeCheck   (SomeParamType(..), TcOriginatedContracts, mkSomeParamType) import Morley.Michelson.Typed@@ -260,3 +265,29 @@  getManagerKey :: HasTezosRpc m => ImplicitAddress -> m (Maybe PublicKey) getManagerKey = getManagerKeyAtBlock HeadId++-- | Get 'ContractState' for a given t'ContractAddress' at a given 'BlockId'.+-- Can be used with the morley interpreter to add some network interoperability.+contractStateResolver :: HasTezosRpc m => BlockId -> ContractAddress -> m (Maybe ContractState)+contractStateResolver blkId addr = handleStatusCode 404 (pure Nothing) $ Just <$> do+  block <- BlockHashId <$> getBlockHash blkId+  uContract <- throwLeft $ fromExpression . osCode <$> getContractScriptAtBlock block addr+  csBalance <- getBalanceAtBlock block $ Constrained addr+  csDelegate <- getDelegateAtBlock block $ Constrained addr+  SomeContract csContract@Contract{} <-+    either throwM pure . typeCheckingWith def $ typeCheckContract uContract+  csStorage <- throwLeft $ fromExpression <$> getContractStorageAtBlock block addr+  pure ContractState{..}++getTicketBalance+  :: HasTezosRpc m+  => L1Address -- ^ Ticket owner+  -> GetTicketBalance -- ^ Ticket description+  -> m Natural+getTicketBalance = getTicketBalanceAtBlock HeadId . toAddress++getAllTicketBalances+  :: HasTezosRpc m+  => ContractAddress -- ^ Ticket owner+  -> m [GetAllTicketBalancesResponse]+getAllTicketBalances = getAllTicketBalancesAtBlock HeadId
src/Morley/Client/RPC/Types.hs view
@@ -52,8 +52,11 @@   , RunOperationResult (..)   , RPCInput   , TransactionOperation (..)+  , TransferTicketOperation (..)   , WithCommonOperationData (..)   , MonitorHeadsStep(..)+  , GetTicketBalance (..)+  , GetAllTicketBalancesResponse (..)   , mkCommonOperationData    -- * Errors@@ -122,6 +125,7 @@ data RPCInput instance OperationInfoDescriptor RPCInput where   type TransferInfo RPCInput = TransactionOperation+  type TransferTicketInfo RPCInput = TransferTicketOperation   type OriginationInfo RPCInput = OriginationOperation   type RevealInfo RPCInput = RevealOperation   type DelegationInfo RPCInput = DelegationOperation@@ -401,6 +405,7 @@   | IllTypedData Expression Expression   | BadStack BadStackInformation   | ForbiddenZeroAmountTicket+  | REEmptyImplicitContract ImplicitAddress   deriving stock Show  instance FromJSON RunError where@@ -441,6 +446,7 @@       , "unregistered_delegate" ~> UnregisteredDelegate <$> o .: "hash"       , "no_deletion" ~> FailedUnDelegation <$> o .: "delegate"       , "delegate.already_active" ~> pure DelegateAlreadyActive+      , "empty_implicit_contract" ~> REEmptyImplicitContract <$> o .: "implicit"       , "ill_typed_contract" ~> IllTypedContract <$> o .: "ill_typed_code"       , "ill_typed_data" ~> IllTypedData <$> o .: "expected_type" <*> o .: "ill_typed_expression"       , "bad_stack" ~> BadStack <$> parseJSON (Object o)@@ -515,6 +521,8 @@       "Failed to withdraw delegation for: " +| addr |+ ""     DelegateAlreadyActive ->       "Delegate already active"+    REEmptyImplicitContract addr ->+      "Empty implicit contract (" +| addr |+ ")"     IllTypedContract expr ->       "Ill typed contract: " +| expr |+ ""     IllTypedData expected ill_typed ->@@ -661,8 +669,8 @@ -- -- \[ -- \mathrm{min}\left(\mathbf{hard\_gas\_limit\_per\_operation},--- \left\lceil \frac{\mathbf{hard\_gas\_limit\_per\_block}}--- {num\_operations}\right\rceil\right)+-- \left\lfloor \frac{\mathbf{hard\_gas\_limit\_per\_block}}+-- {num\_operations}\right\rfloor\right) -- \] -- -- This works well enough for the case of many small operations, but will break@@ -694,7 +702,7 @@       | Just numOp <- argF #num_operations mNumOp       , numOp > 0       = StringEncode $-          min (unStringEncode ppHardGasLimitPerOperation) $ ceiling $+          min (unStringEncode ppHardGasLimitPerOperation) $ floor $             unStringEncode ppHardGasLimitPerBlock % numOp       | otherwise = ppHardGasLimitPerOperation @@ -739,6 +747,15 @@   , toParameters :: ParametersInternal   } +data TransferTicketOperation = TransferTicketOperation+  { ttoTicketContents :: Expression+  , ttoTicketTy :: Expression+  , ttoTicketTicketer :: Address+  , ttoTicketAmount :: TezosNat+  , ttoDestination :: Address+  , ttoEntrypoint :: Text+  }+ data OriginationScript = OriginationScript   { osCode :: Expression   , osStorage :: Expression@@ -824,6 +841,19 @@   , rcPayer :: Maybe ImplicitAddress   } +data GetTicketBalance = GetTicketBalance+  { gtbTicketer :: ContractAddress+  , gtbContentType :: Expression+  , gtbContent :: Expression+  }++data GetAllTicketBalancesResponse = GetAllTicketBalancesResponse+  { gatbrTicketer :: ContractAddress+  , gatbrContentType :: Expression+  , gatbrContent :: Expression+  , gatbrAmount :: TezosNat+  }+ -- | Result storage of @run_code@ RPC endpoint call. -- -- Actual resulting JSON has more contents, but currently we're interested@@ -854,6 +884,18 @@     ] instance ToJSONObject TransactionOperation +instance ToJSON TransferTicketOperation where+  toJSON TransferTicketOperation{..} = object $+    [ "kind" .= String "transfer_ticket"+    , "ticket_contents" .= ttoTicketContents+    , "ticket_ty"       .= ttoTicketTy+    , "ticket_ticketer" .= ttoTicketTicketer+    , "ticket_amount"   .= ttoTicketAmount+    , "destination"     .= ttoDestination+    , "entrypoint"      .= ttoEntrypoint+    ]+instance ToJSONObject TransferTicketOperation+ instance FromJSON TransactionOperation where   parseJSON = withObject "TransactionOperation" $ \obj -> do     toAmount <- obj .: "amount"@@ -905,8 +947,10 @@  deriveToJSON morleyClientAesonOptions ''RunOperation deriveToJSON morleyClientAesonOptions ''GetBigMap+deriveToJSON morleyClientAesonOptions ''GetTicketBalance deriveToJSON morleyClientAesonOptions ''CalcSize deriveToJSON morleyClientAesonOptions{omitNothingFields = True} ''RunCode+deriveFromJSON morleyClientAesonOptions ''GetAllTicketBalancesResponse deriveFromJSON morleyClientAesonOptions ''BlockHeaderNoHash deriveFromJSON morleyClientAesonOptions ''ScriptSize deriveFromJSON morleyClientAesonOptions ''BlockConstants
src/Morley/Client/TezosClient.hs view
@@ -13,6 +13,8 @@   , ResolveError(..)   , resolveAddress   , resolveAddressMaybe+  , resolveAddressWithAlias+  , resolveAddressWithAliasMaybe   , getAlias   , getAliasMaybe   ) where
src/Morley/Client/TezosClient/Class.hs view
@@ -11,6 +11,7 @@  import Data.ByteArray (ScrubbedBytes) +import Morley.Client.Types import Morley.Tezos.Address import Morley.Tezos.Address.Alias import Morley.Tezos.Crypto@@ -32,18 +33,20 @@  -- | Type class that provides interaction with @octez-client@ binary class (Monad m) => HasTezosClient m where-  signBytes :: ImplicitAddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature+  signBytes+    :: ImplicitAddressWithAlias+    -> Maybe ScrubbedBytes+    -> ByteString+    -> m Signature   -- ^ Sign an operation with @octez-client@.-  genKey :: ImplicitAlias -> m ImplicitAddress+  genKey :: ImplicitAlias -> m ImplicitAddressWithAlias   -- ^ Generate a secret key and store it with given alias.   -- If a key with this alias already exists, the corresponding address   -- will be returned and no state will be changed.-  genFreshKey :: ImplicitAlias -> m ImplicitAddress+  genFreshKey :: ImplicitAlias -> m ImplicitAddressWithAlias   -- ^ Generate a secret key and store it with given alias.   -- Unlike 'genKey' this function overwrites   -- the existing key when given alias is already stored.-  revealKey :: ImplicitAlias -> Maybe ScrubbedBytes -> m ()-  -- ^ Reveal public key associated with given implicit account.   rememberContract :: AliasBehavior -> ContractAddress -> ContractAlias -> m ()   -- ^ Associate the given contract with alias.   -- The 'Bool' variable indicates whether or not we should replace already@@ -58,9 +61,11 @@   -- > ("key:abc", "tz1...")   --   -- TODO [#910]: Cache this and turn it into a 'Morley.Util.Bimap'.-  getKeyPassword :: ImplicitAddress -> m (Maybe ScrubbedBytes)+  getKeyPassword :: ImplicitAddressWithAlias -> m (Maybe ScrubbedBytes)   -- ^ Get password for secret key associated with given address   -- in case this key is password-protected. Obtained password is used   -- in two places:   --   * 1) In @signBytes@ call.   --   * 2) in @revealKey@ call.+  getPublicKey :: ImplicitAddressWithAlias -> m PublicKey+  -- ^ Get a public key for an implicit address or alias.
src/Morley/Client/TezosClient/Impl.hs view
@@ -13,6 +13,7 @@   , genKey   , genFreshKey   , revealKey+  , revealKeyUnlessRevealed   , ResolveError(..)   , Resolve(..)   , resolveAddress@@ -28,6 +29,8 @@   , getKeyPassword   , registerDelegate   , getAliasesAndAddresses+  , resolveAddressWithAlias+  , resolveAddressWithAliasMaybe    -- * Internals   , findAddress@@ -55,11 +58,14 @@ import Data.Singletons (demote) import Lorentz.Value import Morley.Client.Logging+import Morley.Client.RPC.Class (HasTezosRpc)+import Morley.Client.RPC.Getters (getManagerKey) import Morley.Client.RPC.Types import Morley.Client.TezosClient.Class (AliasBehavior(..)) import Morley.Client.TezosClient.Class qualified as Class (HasTezosClient(..)) import Morley.Client.TezosClient.Parser import Morley.Client.TezosClient.Types+import Morley.Client.Types import Morley.Client.Util (readScrubbedBytes, scrubbedBytesToString) import Morley.Micheline import Morley.Michelson.Typed.Scope@@ -67,6 +73,7 @@ import Morley.Tezos.Address.Alias import Morley.Tezos.Address.Kinds import Morley.Tezos.Crypto+import Morley.Util.Constrained import Morley.Util.Interpolate (itu) import Morley.Util.Peano import Morley.Util.Sing (castSing)@@ -132,10 +139,6 @@   | AmbiguousAlias Text ContractAddress ImplicitAddress   -- ^ Expected an alias to be associated with either an implicit address or a   -- contract address, but it was associated with both.-  | AliasTxRollup Text (KindedAddress 'AddressKindTxRollup)-  -- ^ Expected an alias to be associated with either-  -- an implicit address or a contract address,-  -- but it was associated with a transaction rollup address.   | ResolveError ResolveError  deriving stock instance Show TezosClientError@@ -190,11 +193,6 @@           * and an implicit address: #{implicitAddr}         Use '#{contractPrefix}:#{aliasText}' or '#{implicitPrefix}:#{aliasText}' to disambiguate.         |]-    AliasTxRollup aliasText txRollupAddr ->-      [itu|-        Expected the alias '#{aliasText}' to be assigned to either a contract or an implicit account,-        but it's assigned to a transaction rollup address: #{txRollupAddr}.-        |]     ResolveError err -> build err  ----------------------------------------------------------------------------@@ -210,14 +208,13 @@ -- | Sign an arbtrary bytestring using @octez-client@. -- Secret key of the address corresponding to give 'AddressOrAlias' must be known. signBytes-  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, Class.HasTezosClient m)-  => ImplicitAddressOrAlias+  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)+  => ImplicitAlias   -> Maybe ScrubbedBytes   -> ByteString   -> m Signature-signBytes signer mbPassword opHash = do-  signerAlias <- getAlias signer-  logDebug $ "Signing for " <> pretty signer+signBytes signerAlias mbPassword opHash = do+  logDebug $ "Signing for " <> pretty signerAlias   output <- callTezosClientStrict     ["sign", "bytes", toCmdArg opHash, "for", toCmdArg signerAlias] MockupMode mbPassword   liftIO case T.stripPrefix "Signature: " output of@@ -300,6 +297,18 @@    logDebug $ "Successfully revealed key for " +| alias |+ "" +-- | Reveal key for implicit address if necessary.+revealKeyUnlessRevealed+  :: (WithClientLog env m, HasTezosRpc m, MonadIO m, HasTezosClientEnv env)+  => ImplicitAddressWithAlias+  -> Maybe ScrubbedBytes+  -> m ()+revealKeyUnlessRevealed (AddressWithAlias addr alias) mbPassword = do+  mbManagerKey <- getManagerKey addr+  case mbManagerKey of+    Nothing -> revealKey alias mbPassword+    Just _  -> logDebug $ alias |+ " alias has already revealed key"+ -- | Register alias as delegate registerDelegate   :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)@@ -329,11 +338,10 @@  -- | Return 'PublicKey' corresponding to given 'AddressOrAlias'. getPublicKey-  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, Class.HasTezosClient m)-  => ImplicitAddressOrAlias+  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)+  => ImplicitAlias   -> m PublicKey-getPublicKey addrOrAlias = do-  alias <- getAlias addrOrAlias+getPublicKey alias = do   logDebug $ "Getting " +| alias |+ " public key"   output <- callTezosClientStrict ["show", "address", toCmdArg alias] MockupMode Nothing   liftIO case lines output of@@ -347,11 +355,10 @@  -- | Return 'SecretKey' corresponding to given 'AddressOrAlias'. getSecretKey-  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, Class.HasTezosClient m)-  => ImplicitAddressOrAlias+  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m)+  => ImplicitAlias   -> m SecretKey-getSecretKey addrOrAlias = do-  alias <- getAlias addrOrAlias+getSecretKey alias = do   logDebug $ "Getting " +| alias |+ " secret key"   output <- callTezosClientStrict ["show", "address", toCmdArg alias, "--show-secret"] MockupMode Nothing   liftIO case lines output of@@ -393,7 +400,7 @@   => Bool   -> ImplicitAlias   -> SecretKey-  -> m ImplicitAlias+  -> m ImplicitAddressWithAlias importKey replaceExisting name key = do   let     isAlreadyExistsError = T.isInfixOf "already exists"@@ -403,7 +410,7 @@     callTezosClient errHandler     (if replaceExisting then args <> ["--force"] else args)     MockupMode Nothing-  pure name+  pure $ AddressWithAlias (mkKeyAddress (toPublic key)) name  -- | Read @octez-client@ configuration. getTezosClientConfig :: FilePath -> Maybe FilePath -> IO TezosClientConfig@@ -488,25 +495,21 @@ -- | Get password for secret key associated with given address -- in case this key is password-protected getKeyPassword-  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadMask m, Class.HasTezosClient m)-  => ImplicitAddress -> m (Maybe ScrubbedBytes)-getKeyPassword key = (getAlias $ AddressResolved key) >>= getKeyPassword'-  where-    getKeyPassword'-      :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadCatch m, MonadMask m)-      => ImplicitAlias -> m (Maybe ScrubbedBytes)-    getKeyPassword' alias = do-      output <- callTezosClientStrict [ "show", "address", pretty alias, "-S"] MockupMode Nothing-      encryptionType <--        case parseSecretKeyEncryption output of-          Right t -> return t-          Left err -> throwM $ TezosClientParseEncryptionTypeError output $ pretty err-      case encryptionType of-        EncryptedKey -> do-          putTextLn $ "Please enter password for '" <> pretty alias <> "':"-          Just <$> withoutEcho readScrubbedBytes-        _ -> pure Nothing+  :: (WithClientLog env m, HasTezosClientEnv env, MonadIO m, MonadMask m)+  => ImplicitAlias -> m (Maybe ScrubbedBytes)+getKeyPassword alias = do+  output <- callTezosClientStrict [ "show", "address", pretty alias, "-S"] MockupMode Nothing+  encryptionType <-+    case parseSecretKeyEncryption output of+      Right t -> return t+      Left err -> throwM $ TezosClientParseEncryptionTypeError output $ pretty err+  case encryptionType of+    EncryptedKey -> do+      putTextLn $ "Please enter password for '" <> pretty alias <> "':"+      Just <$> withoutEcho readScrubbedBytes+    _ -> pure Nothing +  where     -- Hide entered password     withoutEcho :: (MonadIO m, MonadMask m) => m a -> m a     withoutEcho action = do@@ -666,6 +669,7 @@ class Resolve addressOrAlias where   type ResolvedAddress addressOrAlias :: Type   type ResolvedAlias addressOrAlias :: Type+  type ResolvedAddressAndAlias addressOrAlias :: Type    -- | Looks up the address associated with the given @addressOrAlias@.   --@@ -698,9 +702,17 @@     => addressOrAlias     -> m (Either ResolveError (ResolvedAlias addressOrAlias)) +  -- | Resolve both address and alias at the same time+  resolveAddressWithAliasEither+    :: forall m env+     . (Class.HasTezosClient m, MonadThrow m, WithClientLog env m)+    => addressOrAlias+    -> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))+ instance Resolve (AddressOrAlias kind) where   type ResolvedAddress (AddressOrAlias kind) = KindedAddress kind   type ResolvedAlias (AddressOrAlias kind) = Alias kind+  type ResolvedAddressAndAlias (AddressOrAlias kind) = AddressWithAlias kind    resolveAddressEither     :: (Class.HasTezosClient m, MonadThrow m, WithClientLog env m)@@ -738,9 +750,13 @@           let aliasTextWithoutPrefix = fromMaybe aliasText $ T.stripPrefix "key:" aliasText           pure $ Right $ mkAlias @kind aliasTextWithoutPrefix \\ addressKindSanity addr +  resolveAddressWithAliasEither addr =+    (liftA2 . liftA2) AddressWithAlias (resolveAddressEither addr) (getAliasEither addr)+ instance Resolve SomeAddressOrAlias where   type ResolvedAddress SomeAddressOrAlias = L1Address   type ResolvedAlias SomeAddressOrAlias = SomeAlias+  type ResolvedAddressAndAlias SomeAddressOrAlias = Constrained L1AddressKind AddressWithAlias    resolveAddressEither     :: (Class.HasTezosClient m, MonadThrow m, WithClientLog env m)@@ -761,12 +777,35 @@     SAOAKindSpecified aoa -> do       fmap SomeAlias         <$> getAliasEither aoa \\ addressOrAliasKindSanity aoa-    aoa@(SAOAKindUnspecified aliasText) -> do+    aoa@SAOAKindUnspecified{} -> runExceptT do       -- Find out whether this alias is associated with an implicit address or a contract,       -- and return an @Alias kind@ of the correct kind.-      resolveAddressEither aoa <&> fmap-        \(Constrained (addr :: KindedAddress kind)) ->-          SomeAlias $ mkAlias @kind aliasText \\ addressKindSanity addr+      ExceptT (resolveAddressWithAliasEither aoa) <&> foldConstrained (SomeAlias . awaAlias)++  resolveAddressWithAliasEither addr = runExceptT case addr of+    SAOAKindSpecified aoa -> do+      kaddr <- ExceptT $ resolveAddressEither aoa+      kalias <- ExceptT $ getAliasEither aoa+      pure $ Constrained (AddressWithAlias kaddr kalias) \\ addressOrAliasKindSanity aoa+    aoa@(SAOAKindUnspecified aliasText) -> do+      ExceptT (resolveAddressEither aoa) <&> foldConstrained+        \kaddr -> Constrained $ AddressWithAlias kaddr $ mkAlias aliasText \\ addressKindSanity kaddr++-- | Looks up the address and alias with the given @addressOrAlias@.+resolveAddressWithAlias+  :: forall addressOrAlias m env+   . (Class.HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias)+  => addressOrAlias+  -> m (ResolvedAddressAndAlias addressOrAlias)+resolveAddressWithAlias = resolveAddressWithAliasEither >=> either (throwM . ResolveError) pure++-- | Looks up the address and alias with the given @addressOrAlias@.+resolveAddressWithAliasMaybe+  :: forall addressOrAlias m env+   . (Class.HasTezosClient m, MonadThrow m, WithClientLog env m, Resolve addressOrAlias)+  => addressOrAlias+  -> m (Maybe (ResolvedAddressAndAlias addressOrAlias))+resolveAddressWithAliasMaybe = fmap rightToMaybe . resolveAddressWithAliasEither  -- | Looks up the address associated with the given @addressOrAlias@. --
src/Morley/Client/TezosClient/Types.hs view
@@ -5,7 +5,6 @@  module Morley.Client.TezosClient.Types   ( CmdArg (..)-  -- , addressResolved   , CalcOriginationFeeData (..)   , CalcTransferFeeData (..)   , TezosClientConfig (..)@@ -27,7 +26,6 @@ import Servant.Client (BaseUrl(..), showBaseUrl) import Text.Hex (encodeHex) --- import Lorentz (ToAddress, toAddress) import Morley.Client.RPC.Types (OperationHash) import Morley.Client.Util import Morley.Micheline
src/Morley/Client/Types.hs view
@@ -5,26 +5,38 @@   ( ToJSONObject   , OperationInfoDescriptor (..)   , OperationInfo (..)+  , AddressWithAlias(..)+  , ImplicitAddressWithAlias+  , ContractAddressWithAlias   , _OpTransfer   , _OpOriginate   , _OpReveal   , _OpDelegation+  , _OpTransferTicket   ) where  import Control.Lens (makePrisms) import Data.Aeson (ToJSON(..))+import Fmt (Buildable(..), (+|), (|+)) +import Lorentz (ToAddress(..), ToTAddress(..))+import Morley.Tezos.Address+import Morley.Tezos.Address.Alias+import Morley.Tezos.Address.Kinds+ -- | Designates types whose 'ToJSON' instance produces only 'Data.Aeson.Object's. class ToJSON a => ToJSONObject a  class OperationInfoDescriptor (i :: Type) where   type family TransferInfo i :: Type+  type family TransferTicketInfo i :: Type   type family OriginationInfo i :: Type   type family RevealInfo i :: Type   type family DelegationInfo i :: Type  data OperationInfo i   = OpTransfer (TransferInfo i)+  | OpTransferTicket (TransferTicketInfo i)   | OpOriginate (OriginationInfo i)   | OpReveal (RevealInfo i)   | OpDelegation (DelegationInfo i)@@ -32,13 +44,33 @@ -- Requiring 'ToJSONObject' in superclass as those different types of operation -- must be distinguishable and that is usually done by a special field instance-  Each '[ToJSONObject] [TransferInfo i, OriginationInfo i, RevealInfo i, DelegationInfo i] =>+  Each '[ToJSONObject]+    [TransferInfo i, TransferTicketInfo i, OriginationInfo i, RevealInfo i, DelegationInfo i] =>   ToJSON (OperationInfo i) where   toJSON = \case     OpTransfer op -> toJSON op+    OpTransferTicket op -> toJSON op     OpOriginate op -> toJSON op     OpReveal op -> toJSON op     OpDelegation op -> toJSON op instance ToJSON (OperationInfo i) => ToJSONObject (OperationInfo i)  makePrisms ''OperationInfo++data AddressWithAlias kind = AddressWithAlias+  { awaAddress :: KindedAddress kind+  , awaAlias :: Alias kind+  }+  deriving stock (Show, Eq)++instance ToAddress (AddressWithAlias kind) where+  toAddress = toAddress . awaAddress++instance ToTAddress cp vd (KindedAddress kind) => ToTAddress cp vd (AddressWithAlias kind) where+  toTAddress = toTAddress . awaAddress++instance Buildable (AddressWithAlias kind) where+  build (AddressWithAlias addr alias) = addr |+ " (" +| alias |+ ")"++type ImplicitAddressWithAlias = AddressWithAlias 'AddressKindImplicit+type ContractAddressWithAlias = AddressWithAlias 'AddressKindContract
test/Test/BigMapGet.hs view
@@ -5,7 +5,7 @@   ( test_BigMapGetUnit   ) where -import Data.Map (lookup)+import Control.Lens (at) import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow) import Test.Tasty (TestTree, testGroup)@@ -28,15 +28,15 @@ bigMapGetHandlers = defaultHandlers   { hGetContractBigMap = \blkId addr GetBigMap{..} -> do       assertHeadBlockId blkId-      st <- get-      case lookup addr (fsContracts st) of+      use (fsContractsL . at addr) >>= \case         Nothing -> throwM $ UnknownAccount $ Constrained addr         Just AccountState{..} -> case asAccountData of           ContractData _ mbBigMap -> case mbBigMap of             Nothing -> throwM $ ContractDoesntHaveBigMap $ MkAddress addr-            Just ContractStateBigMap{..} -> case lookup (encodeBase58Check $ expressionToScriptExpr bmKey) csbmMap of-              Nothing -> pure GetBigMapNotFound-              Just serializedValue -> pure $ GetBigMapResult $ decodeExpression serializedValue+            Just ContractStateBigMap{..} ->+              case csbmMap ^. at (encodeBase58Check $ expressionToScriptExpr bmKey)  of+                Nothing -> pure GetBigMapNotFound+                Just serializedValue -> pure $ GetBigMapResult $ decodeExpression serializedValue   }  fakeStateWithBigMapContract
test/Test/Fees.hs view
@@ -14,9 +14,8 @@ import Morley.Client.Action.Origination import Morley.Client.Action.Transaction import Morley.Client.RPC.Types-import Morley.Michelson.Runtime.GState (genesisAddress1)+import Morley.Client.Types import Morley.Michelson.Untyped.Entrypoints-import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (tz) import Test.Addresses import Test.Util@@ -26,7 +25,7 @@   :: FakeState fakeState = defaultFakeState   { fsContracts = fromList $ one $ (contractAddress2, dumbContractState)-  , fsImplicits = fromList $ one (genesisAddress1, dumbImplicitState)+  , fsImplicits = fromList $ one $ second revealKeyState $ genesisState @1   }  countForgesHandlers :: Handlers $ TestT (State Word)@@ -48,7 +47,7 @@                 { arConsumedMilliGas = 10100000                 , arStorageSize = 250                 , arPaidStorageDiff = 250-                , arOriginatedContracts = originatedContracts+                , arOriginatedContracts = concatMap arOriginatedContracts originatedContracts                 , arAllocatedDestinationContracts = 0                 }             , rmInternalOperationResults = []@@ -82,7 +81,7 @@   [ testCase "One transaction" $       let forgeCalls =             runForgesCountingTest $-              lTransfer genesisAddress1 contractAddress2+              lTransfer addr1 contractAddress2                 [tz|10u|] DefEpName () Nothing       in forgeCalls @?= sum           [ 2  -- for fees adjustment@@ -94,7 +93,7 @@       let forgeCalls =             runForgesCountingTest $               lOriginateContract OverwriteDuplicateAlias "c"-                (AddressResolved genesisAddress1) [tz|10u|]+                addr1 [tz|10u|]                 averageContract () Nothing Nothing       in forgeCalls @?= sum           [ 2  -- for fees adjustment@@ -103,3 +102,6 @@           ]    ]++addr1 :: ImplicitAddressWithAlias+addr1 = addrAndAliasFromGenesisState @1
test/Test/KeyRevealing.hs view
@@ -13,17 +13,13 @@ import Morley.Client import Morley.Michelson.Runtime.GState (genesisAddress1) import Morley.Michelson.Typed-import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core (tz) import Test.Util import TestM  fakeState :: FakeState fakeState = defaultFakeState-  { fsImplicits = one ( genesisAddress1-                      , dumbImplicitState-                          { asAccountData = ImplicitData $ Just dumbManagerKey }-                      )+  { fsImplicits = one $ second revealKeyState $ genesisState @1   }  test_keyRevealing :: TestTree@@ -31,14 +27,14 @@   [ testCase "Manager key for new address is revealed only once for transfer" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $ do       senderAddress <- genKey "sender"-      dummyTransfer genesisAddress1 senderAddress-      mbManagerKey <- getManagerKey senderAddress+      dummyTransfer addr1 $ awaAddress senderAddress+      mbManagerKey <- getManagerKey $ awaAddress senderAddress        when (isJust mbManagerKey) $         fail "Manager key was expected not to be revealed, but it's revealed."        dummyTransfer senderAddress genesisAddress1-      mbManagerKey' <- getManagerKey senderAddress+      mbManagerKey' <- getManagerKey $ awaAddress senderAddress        when (isNothing mbManagerKey') $         fail "Manager key was expected to be revealed, but it's not revealed."@@ -50,16 +46,16 @@   , testCase "Manager key for new address is revealed only once for origination" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $ do       originatorAddress <- genKey "originator"-      dummyTransfer genesisAddress1 originatorAddress+      dummyTransfer addr1 $ awaAddress originatorAddress -      mbManagerKey <- getManagerKey originatorAddress+      mbManagerKey <- getManagerKey $ awaAddress originatorAddress        when (isJust mbManagerKey) $         fail "Manager key was expected not to be revealed, but it's revealed."        originateDummy originatorAddress -      mbManagerKey' <- getManagerKey originatorAddress+      mbManagerKey' <- getManagerKey $ awaAddress originatorAddress       when (isNothing mbManagerKey') $         fail "Manager key was expected to be revealed, but it's not revealed." @@ -68,17 +64,18 @@         (originateDummy originatorAddress)   ]   where+    addr1 = addrAndAliasFromGenesisState @1     dummyTransfer from to =       void $ transfer from to [tz|10u|] DefEpName (toVal ()) Nothing      originateDummy addr =-      lOriginateContract OverwriteDuplicateAlias "dummy" (AddressResolved addr) [tz|10u|]+      lOriginateContract OverwriteDuplicateAlias "dummy" addr [tz|10u|]       dumbLorentzContract () Nothing Nothing  -- | Handlers which don't allow to reveal key. noRevealHandlers :: (Monad m) => TestHandlers m noRevealHandlers = TestHandlers $ chainOperationHandlers-  { hRevealKey = \_ _ -> throwM $ UnexpectedClientCall "revealKey" }+  { hGetPublicKey = \_ -> throwM $ UnexpectedClientCall "getPublicKey" }  dumbLorentzContract :: L.Contract Integer () () dumbLorentzContract = L.defaultContract $
test/Test/Origination.hs view
@@ -5,15 +5,13 @@   ( test_lRunTransactionsUnit   ) where -import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow)+import Test.HUnit (Assertion, assertFailure) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (testCase)  import Lorentz qualified as L import Morley.Client-import Morley.Michelson.Runtime.GState (genesisAddress1, genesisAddress3)-import Morley.Tezos.Address.Alias (AddressOrAlias(..)) import Morley.Tezos.Core import Test.Addresses import Test.Util@@ -23,7 +21,7 @@   :: FakeState fakeState = defaultFakeState   { fsContracts = fromList $ one $ (contractAddress2, dumbContractState)-  , fsImplicits = fromList $ one $ (genesisAddress1, dumbImplicitState)+  , fsImplicits = fromList $ one $ genesisState @1   }  dumbLorentzContract :: L.Contract Integer () ()@@ -34,14 +32,17 @@ test_lRunTransactionsUnit = testGroup "Mock test transaction sending"   [ testCase "Successful origination" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $-      lOriginateContract OverwriteDuplicateAlias "dummy" (AddressResolved genesisAddress1) [tz|100500u|]+      lOriginateContract OverwriteDuplicateAlias "dummy" addr1 [tz|100500u|]       dumbLorentzContract () Nothing Nothing   , testCase "Originator doesn't exist" $ handleUnknownContract $     runFakeTest chainOperationHandlers fakeState $-      lOriginateContract OverwriteDuplicateAlias "dummy" (AddressResolved genesisAddress3) [tz|100500u|]+      lOriginateContract OverwriteDuplicateAlias "dummy" addr3 [tz|100500u|]       dumbLorentzContract () Nothing Nothing   ]   where+    addr1 = addrAndAliasFromGenesisState @1+    addr3 = addrAndAliasFromGenesisState @3+     handleSuccess :: Either SomeException a -> Assertion     handleSuccess (Right _) = pass     handleSuccess (Left e) = assertFailure $ displayException e@@ -51,5 +52,5 @@       assertFailure "Origination unexpectedly didn't fail."     handleUnknownContract (Left e) =       shouldThrow (throwM e) $ \case-        ResolveError REAddressNotFound{} -> True+        UnknownAccount{} -> True         _ -> False
test/Test/ParameterTypeGet.hs view
@@ -5,7 +5,6 @@   ( test_parameterTypeGetUnit   ) where -import Data.Map as Map (empty) import Test.HUnit (Assertion, assertEqual, assertFailure) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (testCase)@@ -15,7 +14,6 @@ import Morley.Client.RPC.Getters import Morley.Client.RPC.Types import Morley.Micheline-import Morley.Michelson.Runtime.GState (genesisAddress1) import Morley.Michelson.TypeCheck.TypeCheck (SomeParamType, mkSomeParamType) import Morley.Michelson.Typed import Morley.Michelson.Untyped qualified as U@@ -56,7 +54,7 @@     [ (smartContractAddr1, buildSmartContractState "lol" (testContract @Natural))     , (smartContractAddr2, buildSmartContractState "kek" (testContract @Bool))     ]-  , fsImplicits = fromList $ one (genesisAddress1, dumbImplicitState)+  , fsImplicits = fromList $ one $ genesisState @1   }  test_parameterTypeGetUnit :: TestTree@@ -74,7 +72,7 @@     (runFakeTest chainOperationHandlers fakeStateWithSmartContracts $       getContractsParameterTypes       [smartContractAddr3]-    ) $ Map.empty+    ) mempty   ]   where     expectContractMap
+ test/Test/Resolve.hs view
@@ -0,0 +1,117 @@+-- SPDX-FileCopyrightText: 2023 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++module Test.Resolve+  ( test_Resolve_calls+  ) where++import Test.HUnit ((@?=))+import Test.Tasty (TestTree)+import Test.Tasty.HUnit (testCase)++import Lorentz qualified as L+import Morley.Client (AliasBehavior(..))+import Morley.Client.Action.Batched+import Morley.Client.Action.Common+import Morley.Client.Action.Delegation+import Morley.Client.Action.Origination+import Morley.Client.Action.Reveal+import Morley.Client.Action.Transaction+import Morley.Client.Types+import Morley.Michelson.Untyped.Entrypoints+import Morley.Tezos.Address+import Morley.Tezos.Core (tz)+import Test.Addresses+import Test.Util+import TestM++fakeState :: Bool -> FakeState+fakeState initRevealed = defaultFakeState+  { fsContracts = fromList $ one $ (contractAddress2, dumbContractState)+  , fsImplicits = fromList $ one $ second revelation $ genesisState @1+  }+  where+    revelation | initRevealed = revealKeyState+               | otherwise = id++countAliasStoreCalls :: Handlers (TestT (State Word))+countAliasStoreCalls = chainOperationHandlers+  { hGetAliasesAndAddresses = do+      liftToFakeTest $ modify (+1)+      hGetAliasesAndAddresses chainOperationHandlers+  }++runAliasStoreCounterTest :: HasCallStack => Bool -> TestT (State Word) a -> Word+runAliasStoreCounterTest initRevealed action = do+  let (res, count) =+        usingState 0 $ runFakeTestT countAliasStoreCalls (fakeState initRevealed) action+  case res of+    Left e -> error . toText $ "Test action failed: " <> displayException e+    Right _ -> count++averageContract :: L.Contract () () ()+averageContract = L.defaultContract $ L.car L.# L.nil L.# L.pair++test_Resolve_calls :: [TestTree]+test_Resolve_calls =+  [ testCase "One transaction" $+      let storeCalls =+            runAliasStoreCounterTest True $+              lTransfer addr1 contractAddress2+                [tz|10u|] DefEpName () Nothing+      in storeCalls @?= 1 -- one call in operations log.++  , testCase "One origination"+      let storeCalls =+            runAliasStoreCounterTest True $+              lOriginateContract OverwriteDuplicateAlias "c"+                addr1 [tz|10u|]+                averageContract () Nothing Nothing+      in storeCalls @?= 0++  , testCase "One revelation"+      let storeCalls =+            runAliasStoreCounterTest False $ revealKey addr1+      in storeCalls @?= 1 -- one call in operations log.++  , testCase "One delegation"+      let storeCalls =+            runAliasStoreCounterTest True $ registerDelegateOp addr1+      in storeCalls @?= 1 -- one call in operations log.++  , testCase "Mix"+      let storeCalls = runAliasStoreCounterTest False do+            revealKeyUnlessRevealed addr1+            registerDelegateOp addr1+            lOriginateContract OverwriteDuplicateAlias "c" addr1 [tz|10u|] averageContract ()+              Nothing Nothing+            lTransfer addr1 contractAddress2 [tz|10u|] DefEpName () Nothing+      in storeCalls @?= 3 -- one per injection except origination++  , testCase "Batch"+      let storeCalls = runAliasStoreCounterTest False do+            void $ runOperationsBatch addr1 $ do+              delegateM $ DelegationData (Just $ unImplicitAddress $ awaAddress addr1) Nothing+              originateContractM OriginationData+                { odAliasBehavior = OverwriteDuplicateAlias+                , odName = "c"+                , odContract = L.toMichelsonContract averageContract+                , odStorage = L.toVal ()+                , odDelegate = Nothing+                , odMbFee = Nothing+                , odBalance = [tz|10u|] }+              runTransactionM $ TransactionData TD+                { tdParam = L.toVal ()+                , tdReceiver = Constrained contractAddress2+                , tdAmount = [tz|10u|]+                , tdEpName = DefEpName+                , tdMbFee = Nothing+                }+              pure ()+      in storeCalls @?= 1 -- one per batch+++  ]++addr1 :: ImplicitAddressWithAlias+addr1 = addrAndAliasFromGenesisState @1
test/Test/Transaction.hs view
@@ -5,14 +5,13 @@   ( test_lRunTransactionsUnit   ) where -import Test.HUnit (Assertion, assertFailure) import Test.Hspec.Expectations (shouldThrow)+import Test.HUnit (Assertion, assertFailure) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (testCase) -import Morley.Client (ResolveError(..), TezosClientError(..)) import Morley.Client.Action.Transaction-import Morley.Michelson.Runtime.GState (genesisAddress1, genesisAddress3)+import Morley.Michelson.Runtime.GState (genesisAddress3) import Morley.Michelson.Untyped.Entrypoints import Morley.Tezos.Core (tz) import Test.Addresses@@ -23,25 +22,27 @@   :: FakeState fakeState = defaultFakeState   { fsContracts = fromList $ one (contractAddress2, dumbContractState)-  , fsImplicits = fromList $ one (genesisAddress1, dumbImplicitState)+  , fsImplicits = fromList $ one $ genesisState @1   }  test_lRunTransactionsUnit :: TestTree test_lRunTransactionsUnit = testGroup "Fake test transaction sending"   [ testCase "Successful transaction" $ handleSuccess $     runFakeTest chainOperationHandlers fakeState $-      lTransfer genesisAddress1 contractAddress2+      lTransfer addr1 contractAddress2         [tz|10u|] DefEpName () Nothing   , testCase "Sender doesn't exist" $ handleUnknownContract $     runFakeTest chainOperationHandlers fakeState $-      lTransfer genesisAddress3 contractAddress2+      lTransfer addr3 contractAddress2         [tz|10u|] DefEpName () Nothing   , testCase "Destination doesn't exist" $ handleUnknownContract $     runFakeTest chainOperationHandlers fakeState $-      lTransfer genesisAddress1 genesisAddress3+      lTransfer addr1 genesisAddress3         [tz|10u|] DefEpName () Nothing   ]   where+    addr1 = addrAndAliasFromGenesisState @1+    addr3 = addrAndAliasFromGenesisState @3     handleSuccess :: Either SomeException a -> Assertion     handleSuccess (Right _) = pass     handleSuccess (Left e) = assertFailure $ displayException e@@ -51,5 +52,5 @@       assertFailure "Transaction sending unexpectedly didn't fail."     handleUnknownContract (Left e) =       shouldThrow (throwM e) $ \case-        ResolveError REAddressNotFound{} -> True+        UnknownAccount{} -> True         _ -> False
test/Test/Util.hs view
@@ -5,10 +5,11 @@ module Test.Util   ( chainOperationHandlers   , dumbContractState-  , dumbImplicitState-  , dumbManagerKey   , mapToContractStateBigMap   , handleGetBigMapValue+  , genesisState+  , revealKeyState+  , addrAndAliasFromGenesisState      -- * Internals   , handleRunOperationInternal@@ -16,11 +17,9 @@   ) where  import Control.Exception.Safe (throwString)-import Control.Lens (at, (?~))+import Control.Lens (at, (?=), (?~)) import Data.Aeson (encode)-import Data.ByteArray (ScrubbedBytes) import Data.ByteString.Lazy qualified as LBS (toStrict)-import Data.Map as Map (elems, insert, lookup, toList) import Data.Singletons (demote) import Fmt (pretty, (+|), (|+)) import Network.HTTP.Types.Status (status404)@@ -36,6 +35,7 @@ import Morley.Client.TezosClient (AliasBehavior(..), TezosClientError(DuplicateAlias)) import Morley.Client.Types import Morley.Micheline+import Morley.Michelson.Runtime.GState import Morley.Michelson.Typed import Morley.Tezos.Address import Morley.Tezos.Address.Alias@@ -43,6 +43,8 @@ import Morley.Tezos.Crypto import Morley.Tezos.Crypto.Ed25519 qualified as Ed25519 import Morley.Util.ByteString+import Morley.Util.Peano+import Morley.Util.SizedList qualified as Sized import TestM  -- | Function to convert given map to big map representation@@ -54,8 +56,7 @@   { csbmKeyType = toExpression $ demote @(ToT k)   , csbmValueType = toExpression $ demote @(ToT v)   , csbmMap = fromList $-    map (bimap (encodeBase58Check . valueToScriptExpr) lEncodeValue) $-    Map.toList map'+      map (bimap (encodeBase58Check . valueToScriptExpr) lEncodeValue) $ toPairs map'   , csbmId = bigMapId   } @@ -72,12 +73,12 @@       Nothing   } -dumbImplicitState :: AccountState 'AddressKindImplicit-dumbImplicitState = AccountState+dumbImplicitState :: PublicKey -> (ImplicitAddress, AccountState 'AddressKindImplicit)+dumbImplicitState pk = (mkKeyAddress pk, AccountState   { asCounter = 100500   , asAlias = "genesis1"-  , asAccountData = ImplicitData Nothing-  }+  , asAccountData = ImplicitData pk Nothing+  })  -- | Fake handlers used for transaction sending and contract origination. chainOperationHandlers :: Monad m => Handlers (TestT m)@@ -99,22 +100,24 @@   , hGetKeyPassword = \_ -> pure Nothing   , hGenKey = handleGenKey   , hGetManagerKey = handleGetManagerKey-  , hRevealKey = handleRevealKey+  , hGetPublicKey = handleGetPublicKey   }   where     testSecretKey :: Ed25519.SecretKey     testSecretKey = Ed25519.detSecretKey "\001\002\003\004" -mkRunOperationResult :: [ContractAddress] -> RunOperationResult-mkRunOperationResult originatedContracts = RunOperationResult-  { rrOperationContents =-    one $ OperationContent $ RunMetadata-      { rmOperationResult = OperationApplied $-        AppliedResult 100500 100500 100500 originatedContracts 0-      , rmInternalOperationResults = []-      }+mkRunOperationResult :: NonEmpty AppliedResult -> RunOperationResult+mkRunOperationResult results = RunOperationResult+  { rrOperationContents = results <&> \ar ->+      OperationContent $ RunMetadata+        { rmOperationResult = OperationApplied ar+        , rmInternalOperationResults = []+        }   } +mkAppliedResult :: [ContractAddress] -> AppliedResult+mkAppliedResult originatedContracts = AppliedResult 100500 100500 100500 originatedContracts 0+ handleGetBlockHash :: Monad m => BlockId -> TestT m BlockHash handleGetBlockHash blkId = do   unless (blkId == FinalHeadId) do@@ -130,8 +133,7 @@   => BlockId -> ImplicitAddress -> m TezosInt64 handleGetCounter blk addr = do   assertHeadBlockId blk-  FakeState{..} <- get-  case lookup addr fsImplicits of+  use (fsImplicitsL . at addr) >>= \case     Nothing -> throwM $ UnknownAccount $ Constrained addr     Just AccountState{..} -> pure $ asCounter @@ -160,8 +162,7 @@   -- https://web.archive.org/web/20220305165609/https://tezos.gitlab.io/protocols/tenderbake.html   unless (roiBranch roOperation == fsFinalHeadBlock) do     throwM $ InvalidBranch $ roiBranch roOperation-  originatedContracts <- handleRunOperationInternal roOperation-  pure $ mkRunOperationResult originatedContracts+  mkRunOperationResult <$> handleRunOperationInternal roOperation  handlePreApplyOperation :: Monad m => BlockId -> PreApplyOperation -> TestT m RunOperationResult handlePreApplyOperation blk PreApplyOperation{..} = do@@ -174,8 +175,8 @@   -- https://web.archive.org/web/20220305165609/https://tezos.gitlab.io/protocols/tenderbake.html   unless (paoBranch == fsFinalHeadBlock) do     throwM $ InvalidBranch paoBranch-  originatedContracts <- concatMapM handleTransactionOrOrigination paoContents-  pure $ mkRunOperationResult originatedContracts+  results <- handleOperationInput paoContents+  pure $ mkRunOperationResult results  handleForgeOperation :: Monad m => BlockId -> ForgeOperation -> TestT m HexJSONByteString handleForgeOperation blkId op = do@@ -187,42 +188,40 @@     throwM $ InvalidBranch $ foBranch op   pure . HexJSONByteString . LBS.toStrict . encode $ op -handleRunOperationInternal :: Monad m => RunOperationInternal -> TestT m [ContractAddress]-handleRunOperationInternal RunOperationInternal{..} = do-  concatMapM handleTransactionOrOrigination roiContents+handleRunOperationInternal :: Monad m => RunOperationInternal -> TestT m (NonEmpty AppliedResult)+handleRunOperationInternal RunOperationInternal{roiContents} = handleOperationInput roiContents +handleOperationInput :: Monad m => NonEmpty OperationInput -> TestT m (NonEmpty AppliedResult)+handleOperationInput (c :| cs) =+  (:|) <$> go c 1 <*> zipWithM go cs [2, 3..]+  where go = fmap mkAppliedResult ... handleTransactionOrOrigination+ handleTransactionOrOrigination-  :: (Monad m, HasCallStack) => OperationInput -> TestT m [ContractAddress]-handleTransactionOrOrigination op = do+  :: forall m. (Monad m, HasCallStack) => OperationInput -> TezosInt64 -> TestT m [ContractAddress]+handleTransactionOrOrigination op n = do   FakeState{..} <- get+  AccountState{..} <-+    maybe (throwM $ UnknownAccount $ Constrained codSource) pure $ fsImplicits ^. at codSource+  unless ((asCounter + n) == codCounter) $ throwM CounterMismatch+  let checkContractExists :: Address -> TestT m ()+      checkContractExists dest'@(MkAddress dest) = case dest of+        ContractAddress{} -> when (isNothing $ fsContracts ^. at dest) $+          throwM $ UnknownAccount dest'+        ImplicitAddress{} -> when (isNothing $ fsImplicits ^. at dest) $+          throwM $ UnknownAccount dest'+        SmartRollupAddress{} -> error "smart rollup unsupported"   case wcoCustom op of-    -- Ensure that transaction sender exists-    OpTransfer TransactionOperation{..} -> case lookup codSource fsImplicits of-      Nothing -> throwM $ UnknownAccount $ Constrained codSource-      Just AccountState{..} -> do-        -- Ensure that sender counter matches-        unless (asCounter + 1 == codCounter) (throwM CounterMismatch)-        case toDestination of-          MkAddress dest@ContractAddress{} ->-            case lookup dest fsContracts of-              Nothing -> throwM $ UnknownAccount $ Constrained dest-              Just _ -> pure []-          MkAddress dest@ImplicitAddress{} ->-            case lookup dest fsImplicits of-              Nothing -> throwM $ UnknownAccount $ Constrained dest-              Just _ -> pure []-          MkAddress TxRollupAddress{} -> error "tx rollup unsupported"-    -- Ensure that originator exists-    OpOriginate _ -> case lookup codSource fsImplicits of-      Nothing -> throwM $ UnknownAccount $ Constrained codSource-      Just AccountState{..} -> do-        -- Ensure that originator counter matches-        unless (asCounter + 1 == codCounter) (throwM CounterMismatch)-        pure [dummyContractAddr]-      where-        dummyContractAddr = [ta|KT1LZwEZqbqtLYhwzaidBp6So9LgYDpkpEv7|]-    OpReveal _ ->-      -- We do not care about reveals at the moment+    OpTransfer TransactionOperation{toDestination} -> do+      checkContractExists toDestination+      pure []+    OpTransferTicket TransferTicketOperation{ttoDestination} -> do+      checkContractExists ttoDestination+      pure []+    OpOriginate{} ->+      pure [[ta|KT1LZwEZqbqtLYhwzaidBp6So9LgYDpkpEv7|]]+    OpReveal RevealOperation{..} -> do+      let addr = mkKeyAddress roPublicKey+      modify $ fsImplicitsL . at addr %~ fmap revealKeyState       return []     OpDelegation _ ->       -- We do not care about delegations at the moment@@ -244,8 +243,7 @@   -> m OriginationScript handleGetContractScript blockId addr = do   assertHeadBlockId blockId-  FakeState{..} <- get-  case lookup addr fsContracts of+  use (fsContractsL . at addr) >>= \case     Nothing -> throwM $ err404 path     Just AccountState{..} -> case asAccountData of       ContractData script _ -> pure script@@ -259,7 +257,7 @@    let allBigMaps :: [ContractStateBigMap] =         catMaybes $-          Map.elems (fsContracts st) <&> \cs -> case (asAccountData cs) of+          toList (fsContracts st) <&> \cs -> case (asAccountData cs) of             ContractData _ bigMapMaybe -> bigMapMaybe    -- Check if a big_map with the given ID exists and, if so, check@@ -267,7 +265,7 @@   case find (\bigMap -> csbmId bigMap == bigMapId) allBigMaps of     Nothing -> throwM $ err404 path     Just bigMap ->-      case lookup scriptExpr (csbmMap bigMap ) of+      case csbmMap bigMap ^. at scriptExpr of         Nothing -> throwM $ err404 path         Just serializedValue -> pure $ decodeExpression serializedValue   where@@ -278,25 +276,22 @@ handleRememberContract replaceExisting addr alias = do   let     cs = dumbContractState { asAlias = alias }-    remember addr' cs' FakeState{..} =-      modify $ \s -> s { fsContracts = insert addr' cs' fsContracts }+    remember addr' cs' = fsContractsL . at addr' ?= cs' -  st@FakeState{..} <- get-  case lookup addr fsContracts of-    Nothing -> remember addr cs st+  use (fsContractsL . at addr) >>= \case+    Nothing -> remember addr cs     _       -> case replaceExisting of       KeepDuplicateAlias -> pass-      OverwriteDuplicateAlias -> remember addr cs st+      OverwriteDuplicateAlias -> remember addr cs       ForbidDuplicateAlias -> throwM $ DuplicateAlias $ unAlias alias -handleGenKey :: Monad m => ImplicitAlias -> TestT m ImplicitAddress+handleGenKey :: Monad m => ImplicitAlias -> TestT m ImplicitAddressWithAlias handleGenKey alias = do   let-    addr = detGenKeyAddress (encodeUtf8 $ unAlias alias)-    newAccountState = dumbImplicitState { asAlias =  alias }-  modify $ \s ->-    s & fsImplicitsL . at addr ?~ newAccountState-  pure addr+    pk = toPublic . detSecretKey . encodeUtf8 $ unAlias alias+    (addr, newAccountState) = dumbImplicitState pk+  modify $ fsImplicitsL . at addr ?~ newAccountState{ asAlias = alias }+  pure $ AddressWithAlias addr alias  handleGetAliasesAndAddresses   :: forall m. Monad m@@ -307,7 +302,7 @@   where     convert :: Map (KindedAddress kind) (AccountState kind) -> [(Text, Text)]     convert m =-      Map.toList m <&> \(addr, AccountState{asAlias}) -> (pretty asAlias, pretty addr)+      toPairs m <&> \(addr, AccountState{asAlias}) -> (pretty asAlias, pretty addr)  handleGetManagerKey :: (Monad m) => BlockId -> ImplicitAddress -> TestT m (Maybe PublicKey) handleGetManagerKey blk addr = do@@ -315,8 +310,7 @@   s <- get   let mbCs = s ^. fsImplicitsL . at addr   case mbCs of-    Just AccountState{..} -> case asAccountData of-      ImplicitData mbManagerKey -> pure mbManagerKey+    Just AccountState{..} -> pure $ idManagerKey asAccountData     Nothing -> throwM $ UnknownAccount $ Constrained addr  -- In scenarios where the system under test checks for 404 errors, we@@ -339,25 +333,32 @@       , responseBody = "Contract with given address not found"       } -handleRevealKey :: Monad m => ImplicitAlias -> Maybe ScrubbedBytes -> TestT m ()-handleRevealKey alias _ = do-  accounts <- gets (Map.toList . fsImplicits)-  let accounts' = filter (\(_, AccountState{..}) -> asAlias == alias) accounts+handleGetPublicKey :: Monad m => ImplicitAddressWithAlias -> TestT m PublicKey+handleGetPublicKey aaa@(AddressWithAlias addr alias) = do+  accounts <- gets (toPairs . fsImplicits)+  let accounts' = filter check accounts+      check (addr', AccountState{..}) =  addr' == addr && asAlias == alias   case accounts' of-    []  -> throwM $ UnknownAlias alias-    [(addr, cs@AccountState{..})] ->-      case asAccountData of-        ImplicitData (Just _) ->-          throwM $ AlreadyRevealed $ MkAddress addr-        ImplicitData Nothing ->-            -- We don't care about the public key itself, but only its presence.-            let newAccountState = cs { asAccountData = ImplicitData $ Just dumbManagerKey }-            in modify $ \s -> s & fsImplicitsL . at addr ?~ newAccountState+    []  -> throwM $ UnknownAccount $ Constrained addr+    [(_, AccountState{..})] -> pure $ idPublicKey asAccountData     _   ->-      error $ "Multiple accounts have alias '" +| alias |++      error $ "Multiple accounts found for '" +| aaa |+         "'. This is most likely a bug in tests." --- | Dummy public key used in fake tests.-dumbManagerKey :: PublicKey-dumbManagerKey = fromRight (error "impossible") $ parsePublicKey-  "edpkuwTWKgQNnhR5v17H2DYHbfcxYepARyrPGbf1tbMoGQAj8Ljr3V"+genesisPk :: forall n. (SingIPeano n, ToPeano 10 > ToPeano n ~ 'True) => PublicKey+genesisPk = toPublic $ Sized.index @n genesisSecrets++genesisState+  :: forall n. (SingIPeano n, ToPeano 10 > ToPeano n ~ 'True)+  => (ImplicitAddress, AccountState 'AddressKindImplicit)+genesisState = dumbImplicitState $ genesisPk @n++addrAndAliasFromGenesisState+  :: forall n. (SingIPeano n, ToPeano 10 > ToPeano n ~ 'True)+  => ImplicitAddressWithAlias+addrAndAliasFromGenesisState =+  let (addr, AccountState{asAlias}) = genesisState @n+  in AddressWithAlias addr asAlias++revealKeyState :: AccountState 'AddressKindImplicit -> AccountState 'AddressKindImplicit+revealKeyState = asAccountDataL %~ \x@ImplicitData{..} -> x{ idManagerKey = Just idPublicKey }
test/TestM.hs view
@@ -23,6 +23,8 @@    -- * Lens   , fsImplicitsL+  , fsContractsL+  , asAccountDataL   ) where  import Colog.Core.Class (HasLog(..))@@ -78,16 +80,18 @@   , hGetChainId :: m ChainId   , hGetManagerKey :: BlockId -> ImplicitAddress -> m (Maybe PublicKey)   , hGetDelegateAtBlock :: BlockId -> L1Address -> m (Maybe KeyHash)+  , hGetTicketBalanceAtBlock :: BlockId -> Address -> GetTicketBalance ->  m Natural+  , hGetAllTicketBalancesAtBlock :: BlockId -> ContractAddress -> m [GetAllTicketBalancesResponse]    -- HasTezosClient-  , hSignBytes :: ImplicitAddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature-  , hGenKey :: ImplicitAlias -> m ImplicitAddress-  , hGenFreshKey :: ImplicitAlias -> m ImplicitAddress-  , hRevealKey :: ImplicitAlias -> Maybe ScrubbedBytes -> m ()+  , hSignBytes :: ImplicitAddressWithAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature+  , hGenKey :: ImplicitAlias -> m ImplicitAddressWithAlias+  , hGenFreshKey :: ImplicitAlias -> m ImplicitAddressWithAlias+  , hGetPublicKey :: ImplicitAddressWithAlias -> m PublicKey   , hWaitForOperation :: m OperationHash -> m OperationHash   , hRememberContract :: AliasBehavior -> ContractAddress -> ContractAlias -> m ()   , hGetAliasesAndAddresses :: m [(Text, Text)]-  , hGetKeyPassword :: ImplicitAddress -> m (Maybe ScrubbedBytes)+  , hGetKeyPassword :: ImplicitAddressWithAlias -> m (Maybe ScrubbedBytes)    -- HasLog   , hLogAction :: ClientLogAction m@@ -120,12 +124,15 @@   , hSignBytes = \_ _ _ -> throwM $ UnexpectedClientCall "signBytes"   , hGenKey = \_ -> throwM $ UnexpectedClientCall "genKey"   , hGenFreshKey = \_ -> throwM $ UnexpectedRpcCall "genFreshKey"-  , hRevealKey = \_ _ -> throwM $ UnexpectedClientCall "revealKey"+  , hGetPublicKey = \_ -> throwM $ UnexpectedClientCall "getPublicKey"   , hWaitForOperation = \_ -> throwM $ UnexpectedRpcCall "waitForOperation"-  , hRememberContract = \_ _ _ -> throwM $ UnexpectedClientCall "hRememberContract"+  , hRememberContract = \_ _ _ -> throwM $ UnexpectedClientCall "rememberContract"   , hGetAliasesAndAddresses = throwM $ UnexpectedRpcCall "getAliasesAndAddresses"   , hGetKeyPassword = \_ -> throwM $ UnexpectedClientCall "getKeyPassword" +  , hGetTicketBalanceAtBlock = \_ _ _ -> throwM $ UnexpectedClientCall "getTicketBalanceAtBlock"+  , hGetAllTicketBalancesAtBlock = \_ _ -> throwM $ UnexpectedClientCall "getAllTicketBalancesAtBlock"+   , hLogAction = mempty   } @@ -138,8 +145,14 @@   }  data AccountData k where-  ContractData :: OriginationScript -> Maybe ContractStateBigMap -> AccountData 'AddressKindContract-  ImplicitData :: Maybe PublicKey -> AccountData 'AddressKindImplicit+  ContractData ::+    { cdScript :: OriginationScript+    , cdBigMap :: Maybe ContractStateBigMap+    } -> AccountData 'AddressKindContract+  ImplicitData ::+    { idPublicKey :: PublicKey+    , idManagerKey :: Maybe PublicKey+    } -> AccountData 'AddressKindImplicit  -- | Type to represent big_map in @AccountState@. data ContractStateBigMap = ContractStateBigMap@@ -218,11 +231,9 @@  -- | Various fake test errors. data TestError-  = AlreadyRevealed Address-  | UnexpectedRpcCall Text+  = UnexpectedRpcCall Text   | UnexpectedClientCall Text   | UnknownAccount Address-  | UnknownAlias ImplicitAlias   | ContractDoesntHaveBigMap Address   | InvalidChainId   | InvalidProtocol@@ -247,9 +258,6 @@   genFreshKey alias = do     h <- getHandler hGenFreshKey     h alias-  revealKey alias mbPassword = do-    h <- getHandler hRevealKey-    h alias mbPassword   rememberContract replaceExisting addr alias = do     h <- getHandler hRememberContract     h replaceExisting addr alias@@ -258,6 +266,9 @@   getKeyPassword addr = do     h <- getHandler hGetKeyPassword     h addr+  getPublicKey addrOrAlias = do+    h <- getHandler hGetPublicKey+    h addrOrAlias  instance Monad m => HasTezosRpc (TestT m) where   getBlockHash block = do@@ -327,5 +338,12 @@   waitForOperation opHash = do     h <- getHandler hWaitForOperation     h opHash+  getTicketBalanceAtBlock block addr args = do+    h <- getHandler hGetTicketBalanceAtBlock+    h block addr args+  getAllTicketBalancesAtBlock block addr = do+    h <- getHandler hGetAllTicketBalancesAtBlock+    h block addr -makeLensesFor [("fsImplicits", "fsImplicitsL")] ''FakeState+makeLensesFor [("fsImplicits", "fsImplicitsL"), ("fsContracts", "fsContractsL")] ''FakeState+makeLensesFor [("asAccountData", "asAccountDataL")] ''AccountState
test/data/constants.json view
@@ -9,34 +9,35 @@   "max_allowed_global_constants_depth": 10000,   "cache_layout_size": 3,   "michelson_maximum_type_size": 2001,-  "sc_max_wrapped_proof_binary_size": 30000,-  "sc_rollup_message_size_limit": 4096,+  "smart_rollup_max_wrapped_proof_binary_size": 30000,+  "smart_rollup_message_size_limit": 4096,+  "smart_rollup_max_number_of_messages_per_level": "1000000",   "preserved_cycles": 3,-  "blocks_per_cycle": 4096,-  "blocks_per_commitment": 32,-  "nonce_revelation_threshold": 256,-  "blocks_per_stake_snapshot": 256,+  "blocks_per_cycle": 8192,+  "blocks_per_commitment": 64,+  "nonce_revelation_threshold": 512,+  "blocks_per_stake_snapshot": 512,   "cycles_per_voting_period": 1,   "hard_gas_limit_per_operation": "1040000",-  "hard_gas_limit_per_block": "5200000",+  "hard_gas_limit_per_block": "2600000",   "proof_of_work_threshold": "-1",   "minimal_stake": "6000000000",-  "vdf_difficulty": "2000000000",+  "vdf_difficulty": "10000000000",   "seed_nonce_revelation_tip": "125000",   "origination_size": 257,-  "baking_reward_fixed_portion": "10000000",-  "baking_reward_bonus_per_slot": "4286",-  "endorsing_reward_per_slot": "2857",+  "baking_reward_fixed_portion": "2666666",+  "baking_reward_bonus_per_slot": "1143",+  "endorsing_reward_per_slot": "761",   "cost_per_byte": "250",   "hard_storage_limit_per_operation": "60000",   "quorum_min": 2000,   "quorum_max": 7000,   "min_proposal_quorum": 500,-  "liquidity_baking_subsidy": "2500000",+  "liquidity_baking_subsidy": "666666",   "liquidity_baking_toggle_ema_threshold": 1000000000,-  "max_operations_time_to_live": 120,-  "minimal_block_delay": "15",-  "delay_increment_per_round": "5",+  "max_operations_time_to_live": 240,+  "minimal_block_delay": "8",+  "delay_increment_per_round": "3",   "consensus_committee_size": 7000,   "consensus_threshold": 4667,   "minimal_participation_ratio": {@@ -54,7 +55,7 @@   "cache_script_size": 100000000,   "cache_stake_distribution_cycles": 8,   "cache_sampler_state_cycles": 8,-  "tx_rollup_enable": true,+  "tx_rollup_enable": false,   "tx_rollup_origination_size": 4000,   "tx_rollup_hard_size_limit_per_inbox": 500000,   "tx_rollup_hard_size_limit_per_message": 5000,@@ -72,25 +73,26 @@   "dal_parametric": {     "feature_enable": false,     "number_of_slots": 256,-    "number_of_shards": 2048,-    "endorsement_lag": 1,+    "attestation_lag": 1,     "availability_threshold": 50,-    "slot_size": 1048576,     "redundancy_factor": 16,-    "page_size": 4096+    "page_size": 4096,+    "slot_size": 1048576,+    "number_of_shards": 2048   },-  "sc_rollup_enable": false,-  "sc_rollup_origination_size": 6314,-  "sc_rollup_challenge_window_in_blocks": 20160,-  "sc_rollup_max_number_of_messages_per_commitment_period": 300000000,-  "sc_rollup_stake_amount": "10000000000",-  "sc_rollup_commitment_period_in_blocks": 30,-  "sc_rollup_max_lookahead_in_blocks": 30000,-  "sc_rollup_max_active_outbox_levels": 20160,-  "sc_rollup_max_outbox_messages_per_level": 100,-  "sc_rollup_number_of_sections_in_dissection": 32,-  "sc_rollup_timeout_period_in_blocks": 20160,-  "sc_rollup_max_number_of_cemented_commitments": 5,+  "smart_rollup_enable": true,+  "smart_rollup_arith_pvm_enable": false,+  "smart_rollup_origination_size": 6314,+  "smart_rollup_challenge_window_in_blocks": 40,+  "smart_rollup_stake_amount": "10000000000",+  "smart_rollup_commitment_period_in_blocks": 20,+  "smart_rollup_max_lookahead_in_blocks": 30000,+  "smart_rollup_max_active_outbox_levels": 20160,+  "smart_rollup_max_outbox_messages_per_level": 100,+  "smart_rollup_number_of_sections_in_dissection": 32,+  "smart_rollup_timeout_period_in_blocks": 500,+  "smart_rollup_max_number_of_cemented_commitments": 5,+  "smart_rollup_max_number_of_parallel_games": 32,   "zk_rollup_enable": false,   "zk_rollup_origination_size": 4000,   "zk_rollup_min_pending_to_process": 10