Skip to content

Commit b43e893

Browse files
authored
feat: add sample implementations for chrysalis (#186)
1 parent f17feda commit b43e893

File tree

4 files changed

+287
-1
lines changed

4 files changed

+287
-1
lines changed

Chrysalis.sln

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Microsoft Visual Studio Solution File, Format Version 12.00
1+
Microsoft Visual Studio Solution File, Format Version 12.00
22
# Visual Studio Version 17
33
VisualStudioVersion = 17.5.2.0
44
MinimumVisualStudioVersion = 10.0.40219.1
@@ -30,6 +30,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chrysalis", "src\Chrysalis\
3030
EndProject
3131
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chrysalis.Cbor.Cli", "src\Chrysalis.Cbor.Cli\Chrysalis.Cbor.Cli.csproj", "{AAA5EC06-8030-067F-F416-55899E16F81D}"
3232
EndProject
33+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chrysalis.Cli", "src\Chrysalis.Cli\Chrysalis.Cli.csproj", "{FC919DAE-1852-426C-927B-84008F2D94AC}"
34+
EndProject
3335
Global
3436
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3537
Debug|Any CPU = Debug|Any CPU
@@ -88,6 +90,10 @@ Global
8890
{AAA5EC06-8030-067F-F416-55899E16F81D}.Debug|Any CPU.Build.0 = Debug|Any CPU
8991
{AAA5EC06-8030-067F-F416-55899E16F81D}.Release|Any CPU.ActiveCfg = Release|Any CPU
9092
{AAA5EC06-8030-067F-F416-55899E16F81D}.Release|Any CPU.Build.0 = Release|Any CPU
93+
{FC919DAE-1852-426C-927B-84008F2D94AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
94+
{FC919DAE-1852-426C-927B-84008F2D94AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
95+
{FC919DAE-1852-426C-927B-84008F2D94AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
96+
{FC919DAE-1852-426C-927B-84008F2D94AC}.Release|Any CPU.Build.0 = Release|Any CPU
9197
EndGlobalSection
9298
GlobalSection(SolutionProperties) = preSolution
9399
HideSolutionNode = FALSE
@@ -106,6 +112,7 @@ Global
106112
{B21321B2-B922-17F1-73AC-209864816DB5} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
107113
{50A6DD83-F98B-5B07-D208-21D95359EFDC} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
108114
{AAA5EC06-8030-067F-F416-55899E16F81D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
115+
{FC919DAE-1852-426C-927B-84008F2D94AC} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
109116
EndGlobalSection
110117
GlobalSection(ExtensibilityGlobals) = postSolution
111118
SolutionGuid = {A298013F-F39C-4701-8D24-C3EB97C657A1}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\Chrysalis.Network\Chrysalis.Network.csproj" />
12+
<ProjectReference Include="..\Chrysalis.Wallet\Chrysalis.Wallet.csproj" />
13+
</ItemGroup>
14+
15+
16+
</Project>

src/Chrysalis.Cli/NodeService.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
using Chrysalis.Network.Cbor.Common;
3+
using Chrysalis.Network.Cbor.LocalStateQuery;
4+
using Chrysalis.Network.MiniProtocols.Extensions;
5+
using Chrysalis.Network.Multiplexer;
6+
using Chrysalis.Wallet.Models.Addresses;
7+
8+
namespace Chrysalis.Cli;
9+
10+
public class NodeService(string socketPath)
11+
{
12+
private readonly string _socketPath = socketPath;
13+
14+
public async Task<Tip> GetTipAsync()
15+
{
16+
NodeClient client = await NodeClient.ConnectAsync(_socketPath);
17+
await client.StartAsync();
18+
Tip tip = await client.LocalStateQuery.GetTipAsync();
19+
return tip;
20+
}
21+
22+
public async Task<ProtocolParams> GetCurrentProtocolParamsAsync()
23+
{
24+
NodeClient client = await NodeClient.ConnectAsync(_socketPath);
25+
await client.StartAsync();
26+
CurrentProtocolParamsResponse currentProtocolParams = await client.LocalStateQuery.GetCurrentProtocolParamsAsync();
27+
return currentProtocolParams.ProtocolParams;
28+
}
29+
30+
public async Task<UtxoByAddressResponse> GetUtxoByAddressAsync(string address)
31+
{
32+
NodeClient client = await NodeClient.ConnectAsync(_socketPath);
33+
await client.StartAsync();
34+
Address addr = new(address);
35+
UtxoByAddressResponse utxos = await client.LocalStateQuery.GetUtxosByAddressAsync([addr.ToBytes()]);
36+
return utxos;
37+
}
38+
39+
}
40+

src/Chrysalis.Cli/Program.cs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
using System;
2+
using System.Text.Json;
3+
using Chrysalis.Cbor.Extensions.Cardano.Core.Common;
4+
using Chrysalis.Cbor.Extensions.Cardano.Core.Transaction;
5+
using Chrysalis.Cbor.Serialization;
6+
using Chrysalis.Cbor.Types;
7+
using Chrysalis.Cbor.Types.Cardano.Core.Common;
8+
using Chrysalis.Cbor.Types.Cardano.Core.Governance;
9+
using Chrysalis.Cbor.Types.Cardano.Core.Header;
10+
using Chrysalis.Cbor.Types.Cardano.Core.Protocol;
11+
using Chrysalis.Cbor.Types.Cardano.Core.Transaction;
12+
using Chrysalis.Cli;
13+
using Chrysalis.Network.Cbor.Common;
14+
using Chrysalis.Network.Cbor.LocalStateQuery;
15+
16+
bool exitProgram = false;
17+
18+
NodeService nodeService = new("/tmp/preview-node.socket");
19+
var options = new JsonSerializerOptions
20+
{
21+
WriteIndented = true,
22+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
23+
};
24+
25+
while (!exitProgram)
26+
{
27+
Console.WriteLine("===== Chrysalis =====");
28+
Console.WriteLine("1. Fetch Tip");
29+
Console.WriteLine("2. Fetch Protocol Parameters");
30+
Console.WriteLine("3. Fetch UTxOs by Address");
31+
Console.WriteLine("0. Exit");
32+
Console.Write("\nEnter your choice: ");
33+
34+
// Get user input
35+
string input = Console.ReadLine() ?? "";
36+
37+
switch (input)
38+
{
39+
case "1":
40+
Console.WriteLine("\n====================================================================\n");
41+
Tip tip = await nodeService.GetTipAsync();
42+
Console.Write($"Current tip: ");
43+
Console.Write(Convert.ToHexString(tip.Slot.Hash));
44+
Console.Write($" at slot ");
45+
Console.WriteLine(tip.Slot.Slot);
46+
Console.WriteLine("");
47+
48+
break;
49+
case "2":
50+
ProtocolParams protocolParams = await nodeService.GetCurrentProtocolParamsAsync();
51+
var (
52+
minFeeA,
53+
minFeeB,
54+
maxBlockBodySize,
55+
maxTransactionSize,
56+
maxBlockHeaderSize,
57+
keyDeposit,
58+
poolDeposit,
59+
maximumEpoch,
60+
desiredNumberOfStakePools,
61+
poolPledgeInfluence,
62+
expansionRate,
63+
treasuryGrowthRate,
64+
protocolVersion,
65+
minPoolCost,
66+
adaPerUTxOByte,
67+
costModelsForScriptLanguage,
68+
executionCosts,
69+
maxTxExUnits,
70+
maxBlockExUnits,
71+
maxValueSize,
72+
collateralPercentage,
73+
maxCollateralInputs,
74+
poolVotingThresholds,
75+
drepVotingThresholds,
76+
minCommitteeSize,
77+
committeeTermLimit,
78+
governanceActionValidityPeriod,
79+
governanceActionDeposit,
80+
drepDeposit,
81+
drepInactivityPeriod,
82+
minFeeRefScriptCostPerByte
83+
) = protocolParams;
84+
85+
var propertyDict = new Dictionary<string, object?>
86+
{
87+
{ nameof(ProtocolParams.MinFeeA), minFeeA },
88+
{ nameof(ProtocolParams.MinFeeB), minFeeB },
89+
{ nameof(ProtocolParams.MaxBlockBodySize), maxBlockBodySize },
90+
{ nameof(ProtocolParams.MaxTransactionSize), maxTransactionSize },
91+
{ nameof(ProtocolParams.MaxBlockHeaderSize), maxBlockHeaderSize },
92+
{ nameof(ProtocolParams.KeyDeposit), keyDeposit },
93+
{ nameof(ProtocolParams.PoolDeposit), poolDeposit },
94+
{ nameof(ProtocolParams.MaximumEpoch), maximumEpoch },
95+
{ nameof(ProtocolParams.DesiredNumberOfStakePools), desiredNumberOfStakePools },
96+
{ nameof(ProtocolParams.PoolPledgeInfluence), poolPledgeInfluence },
97+
{ nameof(ProtocolParams.ExpansionRate), expansionRate },
98+
{ nameof(ProtocolParams.TreasuryGrowthRate), treasuryGrowthRate },
99+
{ nameof(ProtocolParams.ProtocolVersion), protocolVersion },
100+
{ nameof(ProtocolParams.MinPoolCost), minPoolCost },
101+
{ nameof(ProtocolParams.AdaPerUTxOByte), adaPerUTxOByte },
102+
{ nameof(ProtocolParams.CostModelsForScriptLanguage), costModelsForScriptLanguage },
103+
{ nameof(ProtocolParams.ExecutionCosts), executionCosts },
104+
{ nameof(ProtocolParams.MaxTxExUnits), maxTxExUnits },
105+
{ nameof(ProtocolParams.MaxBlockExUnits), maxBlockExUnits },
106+
{ nameof(ProtocolParams.MaxValueSize), maxValueSize },
107+
{ nameof(ProtocolParams.CollateralPercentage), collateralPercentage },
108+
{ nameof(ProtocolParams.MaxCollateralInputs), maxCollateralInputs },
109+
{ nameof(ProtocolParams.PoolVotingThresholds), poolVotingThresholds },
110+
{ nameof(ProtocolParams.DRepVotingThresholds), drepVotingThresholds },
111+
{ nameof(ProtocolParams.MinCommitteeSize), minCommitteeSize },
112+
{ nameof(ProtocolParams.CommitteeTermLimit), committeeTermLimit },
113+
{ nameof(ProtocolParams.GovernanceActionValidityPeriod), governanceActionValidityPeriod },
114+
{ nameof(ProtocolParams.GovernanceActionDeposit), governanceActionDeposit },
115+
{ nameof(ProtocolParams.DRepDeposit), drepDeposit },
116+
{ nameof(ProtocolParams.DRepInactivityPeriod), drepInactivityPeriod },
117+
{ nameof(ProtocolParams.MinFeeRefScriptCostPerByte), minFeeRefScriptCostPerByte }
118+
};
119+
120+
foreach (var kvp in propertyDict)
121+
{
122+
if (kvp.Value is PoolVotingThresholds || kvp.Value is DRepVotingThresholds)
123+
{
124+
continue;
125+
}
126+
Console.Write($"{kvp.Key}: ");
127+
if (kvp.Value is CborRationalNumber rationalNumber)
128+
{
129+
Console.WriteLine($"{(decimal)rationalNumber.Numerator / rationalNumber.Denominator}");
130+
continue;
131+
}
132+
else if (kvp.Value is ProtocolVersion)
133+
{
134+
continue;
135+
}
136+
else if (kvp.Value is CostMdls costMdls)
137+
{
138+
foreach (var costMdl in costMdls.Value)
139+
{
140+
Console.WriteLine($"{costMdl.Key}: [");
141+
foreach (var item in costMdl.Value.Value)
142+
{
143+
Console.WriteLine($"\t{item}, ");
144+
}
145+
Console.WriteLine("]");
146+
}
147+
continue;
148+
}
149+
else if (kvp.Value is ExUnitPrices exUnitPrices)
150+
{
151+
Console.WriteLine($"Mem Price: {(decimal)exUnitPrices.MemPrice.Numerator / exUnitPrices.StepPrice.Denominator}, CPU Price: {(decimal)exUnitPrices.StepPrice.Numerator / exUnitPrices.StepPrice.Denominator}");
152+
continue;
153+
}
154+
else if (kvp.Value is ExUnits exUnits)
155+
{
156+
Console.WriteLine($"Mem: {exUnits.Mem}, CPU: {exUnits.Steps}");
157+
continue;
158+
}
159+
160+
161+
Console.WriteLine(kvp.Value?.ToString() ?? "null");
162+
Console.ResetColor();
163+
}
164+
165+
Console.WriteLine("\n\n");
166+
Console.ResetColor();
167+
168+
169+
break;
170+
171+
case "3":
172+
173+
Console.Write("Enter address: ");
174+
string address = Console.ReadLine() ?? "";
175+
176+
Console.WriteLine($"Querying UTXOs for address: {address}");
177+
var utxos = await nodeService.GetUtxoByAddressAsync(address);
178+
Console.WriteLine("[");
179+
foreach (var utxo in utxos.Utxos)
180+
{
181+
Console.WriteLine(" {");
182+
Console.WriteLine(" transactionId: " + Convert.ToHexString(utxo.Key.TransactionId));
183+
Console.WriteLine(" index: " + utxo.Key.Index);
184+
Console.WriteLine(" amount: {");
185+
Console.WriteLine(" Lovelace: " + utxo.Value.Amount().Lovelace());
186+
if (utxo.Value.Amount() is LovelaceWithMultiAsset lovelaceWithMultiAsset)
187+
{
188+
foreach (var asset in lovelaceWithMultiAsset.MultiAsset.Value)
189+
{
190+
Console.Write($" {Convert.ToHexString(asset.Key)} : ");
191+
Console.WriteLine("{");
192+
foreach (var token in asset.Value.Value)
193+
{
194+
Console.WriteLine($" {Convert.ToHexString(token.Key)} : {token.Value}");
195+
}
196+
Console.WriteLine(" }");
197+
}
198+
}
199+
Console.WriteLine(" }");
200+
if(utxo.Value.DatumOption() is not null)
201+
{
202+
Console.WriteLine(" datum: " + CborSerializer.Serialize(utxo.Value.DatumOption()!));
203+
}
204+
if(utxo.Value.ScriptRef() is not null)
205+
{
206+
Console.WriteLine(" scriptRef: " + Convert.ToHexString(utxo.Value.ScriptRef()!));
207+
}
208+
209+
}
210+
Console.WriteLine(" },");
211+
212+
break;
213+
214+
case "0":
215+
exitProgram = true;
216+
break;
217+
218+
default:
219+
Console.WriteLine("Invalid option. Press any key to continue...");
220+
Console.ReadKey();
221+
break;
222+
}
223+
}

0 commit comments

Comments
 (0)