Skip to content

Commit f22eafa

Browse files
Merge pull request #2 from 0xxCodemonkey/CosmWasm_v1__secretjs_v1.4
CosmWasm v1 secretjs v1.4
2 parents dad1d7b + d70003e commit f22eafa

85 files changed

Lines changed: 2958 additions & 3263 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NuGet_README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Secret.NET Core Library
2-
Secret.NET (port of the [secret.js](https://github.com/scrtlabs/secret.js) Client) is an .NET SDK for writing applications that interact with the [Secret Network blockchain](https://scrt.network/).
2+
Secret.NET (port of the [secret.js](https://github.com/scrtlabs/secret.js) Client) is a .NET Client to interact with the [Secret Network blockchain](https://scrt.network/) (L1 / Cosmos based), the first privacy smart contract blockchain that processes and stores data on-chain in encrypted form (SGX).
3+
This allows [unique use cases](https://docs.scrt.network/secret-network-documentation/secret-network-overview/use-cases) like Secret NFTs where you can store public and private data e.g., Encryption Keys, passwords or other secrets.
34

45
# Key Features
56
- Written in .NET 6 including MAUI Support.
@@ -11,16 +12,16 @@ Secret.NET (port of the [secret.js](https://github.com/scrtlabs/secret.js) Clien
1112
- The SDK has a wallet built in and does not currently require / support external wallets.
1213
- Custom APIs / clients for specific smart contracts can be easily created (see packages for tokens / SNIP20 or NFT / SNIP721).
1314

15+
All information and documentation is available in the [**GitHub repository**](https://github.com/0xxCodemonkey/SecretNET).
16+
1417
:information_source: This library is still in beta (as [secret.js](https://github.com/scrtlabs/secret.js)), APIs may break. Beta testers are welcome!
1518

1619
## Additional packages
1720
In addition to the Secret.NET Core Library, the following complementary packages are available:
1821
- [**Full SNIP-20 (Token) client**](https://github.com/0xxCodemonkey/SecretNET.SNIP20), which exposes all methods of the [SNIP-20 reference implementation](https://github.com/scrtlabs/snip20-reference-impl).
1922
- [**Full SNIP-721 / SNIP-722 (NFT) client**](https://github.com/0xxCodemonkey/SecretNET.SNIP721), which exposes all methods of the [SNIP-721 reference implementation](https://github.com/baedrik/snip721-reference-impl).
2023

21-
2224
## Links
23-
2425
- [GitHub](https://github.com/0xxCodemonkey/SecretNET)
2526
- [Secret Network - Secret Network is the first blockchain with customizable privacy.](https://scrt.network/)
2627
- [Secret Network - Documentation](https://docs.scrt.network/secret-network-documentation/)

README.md

Lines changed: 555 additions & 35 deletions
Large diffs are not rendered by default.
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
global using Newtonsoft.Json;
2+
3+
// SecretNET
4+
global using SecretNET;
5+
global using SecretNET.Tx;
6+
global using SecretNET.Common;
7+
global using SecretNET.Common.Storage;
8+
using System.Reflection.Metadata;
9+
10+
11+
// See https://aka.ms/new-console-template for more information
12+
13+
#region *** Helper functions / Objects ***
14+
15+
Action<string> writeHeadline = (text) =>
16+
{
17+
Console.ForegroundColor = ConsoleColor.Cyan;
18+
Console.WriteLine($"\r\n**************** {text} ****************\r\n");
19+
Console.ForegroundColor = ConsoleColor.White;
20+
};
21+
22+
Action<string, SecretTx> logSecretTx = (name, tx) =>
23+
{
24+
Console.WriteLine($"{name} Txhash: {tx?.Txhash}");
25+
Console.ForegroundColor = ConsoleColor.Gray;
26+
Console.WriteLine($"(Gas used: {tx.GasUsed} - Gas wanted {tx.GasWanted})");
27+
Console.ForegroundColor = ConsoleColor.White;
28+
29+
//Console.WriteLine($"\r\nCodeId: {JsonConvert.SerializeObject(tx.GetResponseJson(), Formatting.Indented)}");
30+
31+
if (tx is SingleSecretTx<Secret.Compute.V1Beta1.MsgStoreCodeResponse>)
32+
{
33+
Console.WriteLine($"\r\nCodeId: {((SingleSecretTx<Secret.Compute.V1Beta1.MsgStoreCodeResponse>)tx).Response.CodeId}");
34+
}
35+
36+
if (tx is SingleSecretTx<Secret.Compute.V1Beta1.MsgInstantiateContractResponse>)
37+
{
38+
Console.WriteLine($"\r\nContractAddress: {((SingleSecretTx<Secret.Compute.V1Beta1.MsgInstantiateContractResponse>)tx)?.Response?.Address}");
39+
}
40+
41+
if (tx != null && (tx.Code > 0 || (tx.Exceptions?.Any()).GetValueOrDefault()))
42+
{
43+
Console.ForegroundColor = ConsoleColor.Red;
44+
if (tx.Code > 0 && !string.IsNullOrWhiteSpace(tx.Codespace))
45+
{
46+
Console.WriteLine($"\r\n!!!!!!!!!!!! Something went wrong => Code: {tx.Code}; Codespace: {tx.Codespace} !!!!!!!!!!!!");
47+
}
48+
if ((tx.Exceptions?.Any()).GetValueOrDefault())
49+
{
50+
foreach (var ex in tx.Exceptions)
51+
{
52+
Console.WriteLine($"\r\n!!!!!!!!!!!! Exception: {ex.Message} !!!!!!!!!!!!");
53+
}
54+
}
55+
Console.WriteLine($"\r\n{tx.RawLog}");
56+
Console.ForegroundColor = ConsoleColor.White;
57+
Console.ReadLine();
58+
}
59+
};
60+
61+
// TxOptions
62+
var txOptions = new TxOptions()
63+
{
64+
GasLimit = 60_000,
65+
GasPriceInFeeDenom = 0.26F
66+
};
67+
68+
var txOptionsExecute = new TxOptions()
69+
{
70+
GasLimit = 300_000,
71+
GasPriceInFeeDenom = 0.26F
72+
};
73+
74+
var txOptionsUpload = new TxOptions()
75+
{
76+
GasLimit = 12_000_000,
77+
GasPriceInFeeDenom = 0.26F
78+
};
79+
80+
#endregion
81+
82+
writeHeadline("Setup SecretNetworkClient / Wallet");
83+
84+
//var storageProvider = new InMemoryOnlyStorage(); // Temporary and most likely only for DEV
85+
var storageProvider = new AesEncryptedFileStorage("","SuperSecurePassword");
86+
var createWalletOptions = new CreateWalletOptions(storageProvider);
87+
88+
Wallet wallet = null;
89+
if (await storageProvider.HasPrivateKey())
90+
{
91+
var storedMnemonic = await storageProvider.GetFirstMnemonic();
92+
wallet = await Wallet.Create(storedMnemonic, options: createWalletOptions);
93+
}
94+
else
95+
{
96+
wallet = await Wallet.Create(options: createWalletOptions);
97+
98+
Console.WriteLine("Please first fund the wallet with some SCRT via https://faucet.pulsar.scrttestnet.com/ ");
99+
Console.ReadLine();
100+
}
101+
102+
var gprcUrl = "https://grpc.testnet.secretsaturn.net"; // get from https://github.com/scrtlabs/api-registry
103+
var chainId = "pulsar-2";
104+
105+
var createClientOptions = new CreateClientOptions(gprcUrl, chainId, wallet);
106+
var secretClient = new SecretNetworkClient(createClientOptions);
107+
108+
Console.WriteLine("wallet.Address: " + wallet.Address);
109+
110+
111+
#region *** Get Balance ***
112+
113+
// *** Get Balance (1000000 uscrt == 1 SCRT) ***
114+
115+
writeHeadline("Get Balance");
116+
117+
var response = await secretClient.Query.Bank.Balance(wallet.Address);
118+
Console.WriteLine($"Balance: {(float.Parse(response.Amount) / 1000000f)} SCRT");
119+
120+
//Console.ReadLine();
121+
122+
#endregion
123+
124+
#region *** Get Subacccount and Send $SCRT ***
125+
126+
// Send SCRT
127+
var subaccountWallet = await wallet.GetSubaccount(1);
128+
Console.WriteLine($"\r\nSubaccount.Address: {subaccountWallet.Address}");
129+
130+
var sendResponse = await secretClient.Tx.Bank.Send(toAddress: subaccountWallet.Address, amount: 1000000, denom: null);
131+
Console.WriteLine($"BroadcastResponse: {(sendResponse.Code == 0 ? "Success" : "Error (see log)")}");
132+
133+
var r1 = await secretClient.Query.Bank.Balance(subaccountWallet.Address);
134+
Console.WriteLine($"Subaccount Balance: {(float.Parse(r1.Amount) / 1000000f)} SCRT\r\n");
135+
136+
//Console.ReadLine();
137+
138+
#endregion
139+
140+
#region *** Simulate and broadcast a complex transaction ***
141+
142+
var sendToAlice = new Cosmos.Bank.V1Beta1.MsgSend()
143+
{
144+
FromAddress = wallet.Address,
145+
ToAddress = subaccountWallet.Address
146+
};
147+
sendToAlice.Amount.Add(new Cosmos.Base.V1Beta1.Coin() { Amount = "1", Denom = "uscrt" });
148+
149+
var sendToEve = new Cosmos.Bank.V1Beta1.MsgSend()
150+
{
151+
FromAddress = wallet.Address,
152+
ToAddress = subaccountWallet.Address // use the same address for simplicity
153+
};
154+
sendToEve.Amount.Add(new Cosmos.Base.V1Beta1.Coin() { Amount = "1", Denom = "uscrt" });
155+
156+
var messages = new[] { sendToAlice, sendToEve };
157+
158+
var simulate = await secretClient.Tx.Simulate(messages);
159+
160+
Console.WriteLine($"Simulate => GasUsed {simulate.GasInfo.GasUsed} uscrt");
161+
162+
var tx = await secretClient.Tx.Broadcast(messages, new TxOptions
163+
{
164+
// Adjust gasLimit up by 10% to account for gas estimation error
165+
GasLimit = (int)Math.Ceiling(simulate.GasInfo.GasUsed * 1.1),
166+
});
167+
168+
logSecretTx("Broadcast result", tx);
169+
170+
//Console.ReadLine();
171+
172+
#endregion
173+
174+
#region *** Auth ***
175+
176+
// *** Get Account ***
177+
178+
writeHeadline("Get Account");
179+
180+
var accountResponse = await secretClient.Query.Auth.Account(wallet.Address);
181+
Console.WriteLine("AccountResponse:\r\n" + JsonConvert.SerializeObject(accountResponse, Formatting.Indented) + "\r\n");
182+
183+
//Console.ReadLine();
184+
185+
#endregion
186+
187+
#region *** Codes ***
188+
189+
// *** Get Codes with source ***
190+
191+
writeHeadline("Get my Codes with source");
192+
193+
var codesResponse = await secretClient.Query.Compute.Codes();
194+
var withSource = codesResponse.Where(c => !string.IsNullOrWhiteSpace(c.Source) && c.CreatorAddress == wallet.Address).ToList();
195+
Console.WriteLine($"My Codes with source (Count: {withSource.Count} ):\r\n" + JsonConvert.SerializeObject(withSource, Formatting.Indented) + "\r\n");
196+
197+
//Console.ReadLine();
198+
199+
#endregion
200+
201+
#region *** Smart Contract (Upload, Init, Query, Execute) ***
202+
203+
// *** Smart Contract (Upload, Init, Query, Execute) ***
204+
205+
writeHeadline("Upload Contract (mysimplecounter.wasm.gz)");
206+
207+
// *** Upload Contract ***
208+
// https://secretjs.scrt.network/#secretjstxcomputestorecode
209+
210+
byte[] wasmByteCode = File.ReadAllBytes(@"..\..\..\..\..\Resources\mysimplecounter.wasm.gz");
211+
212+
// MsgStoreCode
213+
var msgStoreCodeCounter = new MsgStoreCode(wasmByteCode,
214+
source: "https://github.com/scrtlabs/secret-template", // Source is a valid absolute HTTPS URI to the contract's source code, optional
215+
builder: "enigmampc/secret-contract-optimizer:latest" // Builder is a valid docker image name with tag, optional
216+
);
217+
218+
var storeCodeResponse = await secretClient.Tx.Compute.StoreCode(msgStoreCodeCounter, txOptions: txOptionsUpload);
219+
logSecretTx("StoreCodeResponse", storeCodeResponse);
220+
221+
// *** Init Contract ***
222+
writeHeadline("Init Contract with CodeId " + storeCodeResponse.Response.CodeId);
223+
224+
string? contractAddress = null;
225+
string contractCodeHash = null;
226+
if (storeCodeResponse.Response.CodeId > 0)
227+
{
228+
var codeId = storeCodeResponse.Response.CodeId;
229+
contractCodeHash = await secretClient.Query.Compute.GetCodeHashByCodeId(codeId);
230+
231+
var msgInitContract = new MsgInstantiateContract(
232+
codeId: codeId,
233+
label: $"MySimpleCouter {codeId}",
234+
initMsg: new { count = 100 },
235+
codeHash: contractCodeHash); // optional but way faster
236+
237+
var initContractResponse = await secretClient.Tx.Compute.InstantiateContract(msgInitContract, txOptions: txOptionsUpload);
238+
logSecretTx("InstantiateContract", initContractResponse);
239+
240+
contractAddress = initContractResponse?.Response?.Address;
241+
242+
Console.WriteLine("Contract CodeHash: " + contractCodeHash);
243+
Console.WriteLine("Contract Address: " + contractAddress);
244+
245+
}
246+
247+
//Console.ReadLine();
248+
249+
#region *** Query Contract ***
250+
251+
//string contractAddress = "Set manual if needed";
252+
//string contractCodeHash = "Set manual if needed";
253+
254+
// *** Query Contract ***
255+
256+
writeHeadline("Query Contract with address " + contractAddress);
257+
258+
var queryMsg = new { get_count = new { } };
259+
260+
Console.WriteLine("Query : " + JsonConvert.SerializeObject(queryMsg, Formatting.Indented) + "\r\n");
261+
262+
var queryContractResult = await secretClient.Query.Compute.QueryContract<object>(contractAddress, queryMsg, contractCodeHash);
263+
Console.WriteLine("QueryContractResult:\r\n " + queryContractResult.Response);
264+
265+
//Console.ReadLine();
266+
267+
#endregion
268+
269+
#region *** Execute Contract ***
270+
271+
// *** Execute Contract ***
272+
273+
writeHeadline("Execute Contract with address " + contractAddress);
274+
275+
var executeMsg = new { increment = new { } };
276+
277+
Console.WriteLine("Execute : " + JsonConvert.SerializeObject(executeMsg, Formatting.Indented) + "\r\n");
278+
279+
var msgExecuteContract = new MsgExecuteContract(contractAddress: contractAddress, msg: executeMsg, codeHash: contractCodeHash, sender: null, sentFunds: null);
280+
281+
var executeContractResponse = await secretClient.Tx.Compute.ExecuteContract(msgExecuteContract, txOptionsExecute);
282+
logSecretTx("ExecuteContract", executeContractResponse);
283+
284+
Thread.Sleep(1000); // give some time to let it settle
285+
286+
var queryContractResult2 = await secretClient.Query.Compute.QueryContract<object>(contractAddress, queryMsg, contractCodeHash);
287+
Console.WriteLine("\r\nQueryContractResult (again) :\r\n " + queryContractResult2.Response);
288+
289+
Console.ReadLine();
290+
291+
#endregion
292+
293+
#endregion
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\..\src\SecretNET.csproj" />
12+
</ItemGroup>
13+
14+
</Project>

resources/mysimplecounter.wasm.gz

40 KB
Binary file not shown.
145 KB
Binary file not shown.
225 KB
Binary file not shown.

src/Api/ComputeMsgToNonce.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
namespace SecretNET.Api;
1+
using System.Collections.Concurrent;
2+
3+
namespace SecretNET.Api;
24

35
/// <summary>
46
/// Dictionary which assigns messages index to nonce.
57
/// </summary>
6-
public class ComputeMsgToNonce : Dictionary<int, byte[]>
8+
public class ComputeMsgToNonce : ConcurrentDictionary<int, byte[]>
79
{
810

911
}

src/Api/CosmosSdkException.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace SecretNET.Api;
1+
using Cosmos.Base.Abci.V1Beta1;
2+
3+
namespace SecretNET.Api;
24

35
/// <summary>
46
/// Class CosmosSdkException.
@@ -23,7 +25,7 @@ public class CosmosSdkException : Exception
2325
/// Gets the get tx response.
2426
/// </summary>
2527
/// <value>The get tx response.</value>
26-
public GetTxResponse GetTxResponse { get; private set; }
28+
public TxResponse TxResponse { get; private set; }
2729

2830
/// <summary>
2931
/// Gets the raw log.
@@ -36,9 +38,9 @@ public string RawLog
3638
{
3739
return BroadcastTxResponse?.TxResponse?.RawLog;
3840
}
39-
if (GetTxResponse?.TxResponse?.RawLog != null)
41+
if (TxResponse?.RawLog != null)
4042
{
41-
return GetTxResponse?.TxResponse?.RawLog;
43+
return TxResponse?.RawLog;
4244
}
4345
return null;
4446
}
@@ -60,10 +62,10 @@ public CosmosSdkException(CosmosSdkErrorEnum cosmosSdkErrorEnum, BroadcastTxResp
6062
/// </summary>
6163
/// <param name="cosmosSdkErrorEnum">The cosmos SDK error enum.</param>
6264
/// <param name="response">The response.</param>
63-
public CosmosSdkException(CosmosSdkErrorEnum cosmosSdkErrorEnum, GetTxResponse response) : base(SetErrorMessage(cosmosSdkErrorEnum))
65+
public CosmosSdkException(CosmosSdkErrorEnum cosmosSdkErrorEnum, TxResponse response) : base(SetErrorMessage(cosmosSdkErrorEnum))
6466
{
6567
CosmosSdkErrorEnum = cosmosSdkErrorEnum;
66-
GetTxResponse = response;
68+
TxResponse = response;
6769
}
6870

6971
// https://github.com/cosmos/cosmos-sdk/blob/main/types/errors/errors.go

0 commit comments

Comments
 (0)