Skip to content

Commit

Permalink
CardanoSharp.Koios.SDK integration for important query and transactio…
Browse files Browse the repository at this point in the history
…n commands

New commands via Koios integration:
- query tip --network <network>
- query protocol-parameters --network <network>
- query info account --network <network>--stake-address <bech32_stake_address>
- query asset account --network <network> --stake-address <bech32_stake_address>
- query info address --network <network> --address <bech32_payment_address>
- query info transaction --network <network> --tx-id <transaction_hash>
 - transaction submit --network <network> --cbor-hex <hex_string>
  • Loading branch information
safestak-keith authored May 23, 2022
1 parent aecfa61 commit 7625b2e
Show file tree
Hide file tree
Showing 47 changed files with 1,520 additions and 146 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,10 @@ jobs:
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Set release outputs
- name: Set release params
id: release-params
run: |
VERSION_TAG=$(git describe --tags --abbrev=0)
RELEASE_NAME="cscli-$VERSION_TAG-${{ matrix.target }}"
echo "::set-output name=release_name::$RELEASE_NAME"
echo "::set-output name=release_name::cscli-$(git describe --tags --abbrev=0)-${{ matrix.target }}"
- name: Build
shell: bash
Expand Down
247 changes: 215 additions & 32 deletions README.md

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions Src/ConsoleTool/BackendGateway.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using CardanoSharp.Wallet.Enums;
using Refit;

namespace Cscli.ConsoleTool.Koios
{
public static class BackendGateway
{
public static T GetBackendClient<T>(NetworkType networkType) =>
RestService.For<T>(GetBaseUrlForNetwork(networkType));

private static string GetBaseUrlForNetwork(NetworkType networkType) => networkType switch
{
NetworkType.Mainnet => "https://api.koios.rest/api/v0",
NetworkType.Testnet => "https://testnet.koios.rest/api/v0",
_ => throw new ArgumentException($"{nameof(networkType)} {networkType} is invalid", nameof(networkType))
};
}
}
3 changes: 0 additions & 3 deletions Src/ConsoleTool/CardanoNodeTypes.cs

This file was deleted.

33 changes: 27 additions & 6 deletions Src/ConsoleTool/CommandParser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Cscli.ConsoleTool.Commands;
using Cscli.ConsoleTool.Crypto;
using Cscli.ConsoleTool.Query;
using Cscli.ConsoleTool.Transaction;
using Cscli.ConsoleTool.Wallet;
using Microsoft.Extensions.Configuration;
using System.Text;

Expand Down Expand Up @@ -41,9 +44,9 @@ private static ICommand ParseCommands(string intent, string[] args) =>
args[0] switch
{
"wallet" => ParseWalletCommands(intent, args),
//"query" => ParseQueryCommands(intent, args), // TODO: query via Blockfrost/Koios integration
//"tx" => ParseTxCommands(intent, args), // TODO: Easier Tx creation and submission via Blockfrost/Koios integration
"bech32" or "blake2b" => ParseEncodingHashingCommands(intent, args),
"query" => ParseQueryCommands(intent, args),
"transaction" => ParseTransactionCommands(intent, args),
"bech32" or "blake2b" => ParseCryptoCommands(intent, args),
_ => new ShowInvalidArgumentCommand(intent)
};

Expand All @@ -60,7 +63,26 @@ private static ICommand ParseWalletCommands(string intent, string[] args) =>
_ => new ShowInvalidArgumentCommand(intent)
};

private static ICommand ParseEncodingHashingCommands(string intent, string[] args) =>
private static ICommand ParseQueryCommands(string intent, string[] args) =>
intent switch
{
"query tip" => BuildCommand<QueryTipCommand>(args),
"query protocol-parameters" => BuildCommand<QueryProtocolParametersCommand>(args),
"query info account" => BuildCommand<QueryAccountInfoCommand>(args),
"query asset account" => BuildCommand<QueryAccountAssetCommand>(args),
"query info address" => BuildCommand<QueryAddressInfoCommand>(args),
"query info transaction" => BuildCommand<QueryTransactionInfoCommand>(args),
_ => new ShowInvalidArgumentCommand(intent)
};

private static ICommand ParseTransactionCommands(string intent, string[] args) =>
intent switch
{
"transaction submit" => BuildCommand<SubmitTransactionCommand>(args),
_ => new ShowInvalidArgumentCommand(intent)
};

private static ICommand ParseCryptoCommands(string intent, string[] args) =>
intent switch
{
"bech32 encode" => BuildCommand<EncodeBech32Command>(args),
Expand All @@ -69,7 +91,6 @@ private static ICommand ParseEncodingHashingCommands(string intent, string[] arg
_ => new ShowInvalidArgumentCommand(intent)
};


private static ICommand BuildCommand<T>(
string[] args)
where T : ICommand
Expand Down
10 changes: 7 additions & 3 deletions Src/ConsoleTool/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace Cscli.ConsoleTool;

Expand Down Expand Up @@ -31,7 +32,8 @@ public static class Constants
public static readonly JsonSerializerOptions SerialiserOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
// Commandline args switch mappings
public static Dictionary<string, string> SwitchMappings => new()
Expand All @@ -45,7 +47,9 @@ public static class Constants
{ "--stake-account-index", "stakeAccountIndex" },
{ "--stake-address-index", "stakeAddressIndex" },
{ "--payment-address-type", "paymentAddressType" },
{ "--network-tag", "networkTag" },
{ "--stake-address", "stakeAddress" },
{ "--cbor-hex", "cborHex" },
{ "--tx-id", "txId" },
//{ "--output-format", "outputFormat" },
};
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using CardanoSharp.Wallet.Encoding;
using CardanoSharp.Wallet.Extensions;

namespace Cscli.ConsoleTool.Commands;
namespace Cscli.ConsoleTool.Crypto;

public class DecodeBech32Command : ICommand
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using CardanoSharp.Wallet.Encoding;

namespace Cscli.ConsoleTool.Commands;
namespace Cscli.ConsoleTool.Crypto;

public class EncodeBech32Command : ICommand
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using CardanoSharp.Wallet.Extensions;
using System.Collections.Immutable;

namespace Cscli.ConsoleTool.Commands;
namespace Cscli.ConsoleTool.Crypto;

public class HashBlake2bCommand : ICommand
{
Expand Down
5 changes: 3 additions & 2 deletions Src/ConsoleTool/Cscli.ConsoleTool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
<None Include="..\..\README.md" Link="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CardanoSharp.Wallet" Version="2.1.0" />
<PackageReference Include="CardanoSharp.Koios.Sdk" Version="4.2.0" />
<PackageReference Include="CardanoSharp.Wallet" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.2">
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
15 changes: 15 additions & 0 deletions Src/ConsoleTool/DomainTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Cscli.ConsoleTool;

public record struct Utxo(string TxHash, int OutputIndex, TokenBundle TokenBundle);

public record struct TokenBundle(long LovelaceValue, NativeAssetValue[] NativeAssets);

public record struct NativeAssetValue(string PolicyId, string AssetNameHex, long Quantity);

public record WalletInfo(AccountInfo[] Accounts);

public record AccountInfo(string StakeAddress, string PaymentAddress, Utxo[] Utxos);

public record AddressInfo(string PaymentAddress, string? StakeAddress, Utxo[] Utxos);

public record TextEnvelope(string? Type, string? Description, string? CborHex);
3 changes: 1 addition & 2 deletions Src/ConsoleTool/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"profiles": {
"Cscli.ConsoleTool": {
"commandName": "Project",
"commandLineArgs": "bech32 encode --value 00e3f81c986990cfd80283944858ae50c2d82f6a79d330ce7014e0b7fd9df9179beb0ce89f84025e02ae11c18b3003e7690149caa662fafd01 --prefix addr_test"
"commandName": "Project"
}
}
}
107 changes: 107 additions & 0 deletions Src/ConsoleTool/Query/QueryAccountAssetCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using CardanoSharp.Koios.Sdk;
using CardanoSharp.Wallet;
using CardanoSharp.Wallet.Encoding;
using CardanoSharp.Wallet.Enums;
using CardanoSharp.Wallet.Models.Addresses;
using Cscli.ConsoleTool.Koios;
using System.Text.Json;
using static Cscli.ConsoleTool.Constants;

namespace Cscli.ConsoleTool.Query;

public class QueryAccountAssetCommand : ICommand
{
public string StakeAddress { get; init; } = string.Empty;
public string Address { get; init; } = string.Empty;
public string? Network { get; init; }

public async ValueTask<CommandResult> ExecuteAsync(CancellationToken ct)
{
var (isValid, networkType, stakeAddress, errors) = Validate();
if (!isValid || stakeAddress == null)
{
return CommandResult.FailureInvalidOptions(
string.Join(Environment.NewLine, errors));
}

var accountClient = BackendGateway.GetBackendClient<IAccountClient>(networkType);
try
{
var assets = await accountClient.GetStakeAssets(stakeAddress.ToString()).ConfigureAwait(false);
var json = JsonSerializer.Serialize(assets, SerialiserOptions);
return CommandResult.Success(json);
}
catch (Exception ex)
{
return CommandResult.FailureUnhandledException("Unexpected error", ex);
}
}

private (
bool isValid,
NetworkType derivedNetworkType,
Address? derivedStakeAddress,
IReadOnlyCollection<string> validationErrors) Validate()
{
var validationErrors = new List<string>();
if (!Enum.TryParse<NetworkType>(Network, ignoreCase: true, out var networkType))
{
validationErrors.Add(
$"Invalid option --network must be either testnet or mainnet");
}
var stakeAddressArgumentExists = !string.IsNullOrWhiteSpace(StakeAddress);
var paymentAddressArgumentExists = !string.IsNullOrWhiteSpace(Address);
if (!stakeAddressArgumentExists && !paymentAddressArgumentExists
|| stakeAddressArgumentExists && paymentAddressArgumentExists)
{
validationErrors.Add(
"Invalid option, one of either --stake-address or --address is required");
return (!validationErrors.Any(), networkType, null, validationErrors);
}
if (stakeAddressArgumentExists)
{
if (!Bech32.IsValid(StakeAddress))
{
validationErrors.Add(
$"Invalid option --stake-address {StakeAddress} is invalid");
}
else
{
var stakeAddress = new Address(StakeAddress);
if (stakeAddress.AddressType != AddressType.Reward || stakeAddress.NetworkType != networkType)
{
validationErrors.Add(
$"Invalid option --stake-address {StakeAddress} is invalid for {Network}");
}
else
{
return (!validationErrors.Any(), networkType, stakeAddress, validationErrors);
}
}
}
if (paymentAddressArgumentExists)
{
if (!Bech32.IsValid(Address))
{
validationErrors.Add(
$"Invalid option --address {Address} is not a base address with attached staking credentials");
}
else
{
var addressService = new AddressService();
var address = new Address(Address);
if (address.AddressType != AddressType.Base || address.NetworkType != networkType)
{
validationErrors.Add(
$"Invalid option --address {Address} is not a base address with attached staking credentials for {Network}");
}
else
{
var stakeAddress = addressService.ExtractRewardAddress(address);
return (!validationErrors.Any(), networkType, stakeAddress, validationErrors);
}
}
}
return (!validationErrors.Any(), networkType, null, validationErrors);
}
}
Loading

0 comments on commit 7625b2e

Please sign in to comment.