When this requirement arises, I though it should be a matter of reading it from context or so on. Anyway, then I realized it’s not available and no straightforward way of doing it. So I would suggest below two ways to do that based on your circumstance.
If you really want to retrieve dynamically, there is one other way.
IWorkflowContext context = ExecutionContext.GetExtension<IWorkflowContext>(); context.OrganizationName
This attribute gives you the unique name of the instance.
While this is unique to instance, you are able to write a case statement etc. to retrieve the correct URL. This is good because your system will switch dynamically to correct URL but you are keeping URLs in the code itself. This means if you add new environment you need to modify the code and re-deploy the assembly.