Skip to content

Commit 2fac981

Browse files
committed
v0.18.0: TonRecipes.TelegramNumbers and TonRecipes.TelegramUsernames
1 parent 0b34aa3 commit 2fac981

File tree

9 files changed

+378
-159
lines changed

9 files changed

+378
-159
lines changed

TonLibDotNet.Demo/Samples/Recipes/TelemintGetAllInfo.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,20 @@ public async Task Run(bool inMainnet)
2626

2727
var domain = "dolboeb.t.me";
2828

29-
var ti = await TonRecipes.Telemint.GetAllInfoByName(tonClient, domain);
29+
var ti = await TonRecipes.TelegramUsernames.GetAllInfoByName(tonClient, domain);
3030

3131
// Output as JSON because I'm too lazy to write separate lines for each field.
3232
logger.LogInformation(
3333
"Info about '{Domain}':\r\n{Json}",
3434
domain,
3535
JsonSerializer.Serialize(ti, new JsonSerializerOptions() { WriteIndented = true }));
36+
37+
var number = "+888 0000 8888";
38+
ti = await TonRecipes.TelegramNumbers.GetAllInfoByName(tonClient, number);
39+
logger.LogInformation(
40+
"Info about '{Domain}':\r\n{Json}",
41+
number,
42+
JsonSerializer.Serialize(ti, new JsonSerializerOptions() { WriteIndented = true }));
3643
}
3744
}
3845
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
namespace TonLibDotNet.Recipes
2+
{
3+
[Collection(TonClientMainnetCollection.Definition)]
4+
public class TelegramNumbersRecipes_Tests
5+
{
6+
private readonly Func<Task<ITonClient>> getTonClient;
7+
8+
private readonly TelegramNumbersRecipes instance = TelegramNumbersRecipes.Instance;
9+
10+
private const string ValidName = "88800008888";
11+
private const string ValidNameAddress = "EQByytVzsVlfuuIALs0b6X_0SrXHXNqBRXPf4S1P6Nm6ZNF4";
12+
13+
public TelegramNumbersRecipes_Tests(TonClientMainnetFixture fixture)
14+
{
15+
getTonClient = fixture.GetTonClient;
16+
}
17+
18+
[Theory]
19+
[InlineData("88800008888", "88800008888")]
20+
[InlineData("+888 0000 8888", "88800008888")]
21+
[InlineData("+888-0000-8888", "88800008888")]
22+
[InlineData("+888 (0000) 8888", "88800008888")]
23+
[InlineData("888 8888 8888 8888", "888888888888888")]
24+
public void NormalizeNameWorks(string name, string expected)
25+
{
26+
Assert.True(instance.TryNormalizeName(name, out var normalizedName));
27+
Assert.Equal(expected, normalizedName);
28+
}
29+
30+
[Fact]
31+
public void NormalizeNameRejectsEmpty()
32+
{
33+
Assert.Throws<ArgumentNullException>(() => instance.TryNormalizeName(null, out _));
34+
Assert.Throws<ArgumentNullException>(() => instance.TryNormalizeName(string.Empty, out _));
35+
}
36+
37+
[Theory]
38+
[InlineData("888~00008888")]
39+
[InlineData("888a00008888")]
40+
[InlineData("77700008888")]
41+
public void NormalizeNameRejectsInvalid(string name)
42+
{
43+
Assert.False(instance.TryNormalizeName(name, out _));
44+
}
45+
46+
[Theory]
47+
[InlineData(ValidName)]
48+
public async Task ResolveMinted(string name)
49+
{
50+
var tonClient = await getTonClient();
51+
52+
var adr = await instance.GetNftAddress(tonClient, name);
53+
Assert.Equal(ValidNameAddress, adr);
54+
}
55+
56+
[Fact]
57+
public async Task ResolveNotMinted()
58+
{
59+
var tonClient = await getTonClient();
60+
61+
// Does not exist as NFT at time of writing this test
62+
var adr = await instance.GetNftAddress(tonClient, "888 8888 8888 8888");
63+
64+
// How to get expected value?
65+
// Replace with Assert.Equal if you know how.
66+
Assert.False(string.IsNullOrEmpty(adr));
67+
}
68+
69+
[Fact]
70+
public async Task GetTokenNameWorks()
71+
{
72+
var tonClient = await getTonClient();
73+
var dn = await instance.GetTokenName(tonClient, ValidNameAddress);
74+
Assert.Equal(ValidName, dn);
75+
}
76+
77+
[Fact]
78+
public async Task GetAllInfoWorks()
79+
{
80+
var tonClient = await getTonClient();
81+
var ti = await instance.GetAllInfo(tonClient, ValidNameAddress);
82+
Assert.NotNull(ti);
83+
}
84+
85+
[Fact]
86+
public async Task GetAllInfoByNameWorks()
87+
{
88+
var tonClient = await getTonClient();
89+
var ti = await instance.GetAllInfoByName(tonClient, ValidName);
90+
Assert.NotNull(ti);
91+
}
92+
}
93+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
namespace TonLibDotNet.Recipes
2+
{
3+
[Collection(TonClientMainnetCollection.Definition)]
4+
public class TelegramUsernamesRecipes_Tests
5+
{
6+
private readonly Func<Task<ITonClient>> getTonClient;
7+
8+
private readonly TelegramUsernamesRecipes instance = TelegramUsernamesRecipes.Instance;
9+
10+
private const string ValidNameFull = "welcome.t.me";
11+
private const string ValidNameShort = "welcome";
12+
private const string ValidNameAddress = "EQAngajSUhC0DfUN1OHp33-6w06Mt33fjm4KcwzMU3bGXx_E";
13+
14+
public TelegramUsernamesRecipes_Tests(TonClientMainnetFixture fixture)
15+
{
16+
getTonClient = fixture.GetTonClient;
17+
}
18+
19+
[Theory]
20+
[InlineData("wElCoMe.t.me", "welcome")]
21+
[InlineData("wELCOME.T.ME.", "welcome")]
22+
[InlineData("welcome", "welcome")]
23+
[InlineData("welcome.", "welcome")]
24+
[InlineData("not-yet-minted-name.t.me", "not-yet-minted-name")]
25+
public void NormalizeNameWorks(string name, string expected)
26+
{
27+
Assert.True(instance.TryNormalizeName(name, out var normalizedName));
28+
Assert.Equal(expected, normalizedName);
29+
}
30+
31+
[Fact]
32+
public void NormalizeNameRejectsEmpty()
33+
{
34+
Assert.Throws<ArgumentNullException>(() => instance.TryNormalizeName(null, out _));
35+
Assert.Throws<ArgumentNullException>(() => instance.TryNormalizeName(string.Empty, out _));
36+
}
37+
38+
[Theory]
39+
[InlineData("subdomain.domain.t.me")]
40+
[InlineData("subdomain.domain")]
41+
[InlineData("welcome.ton")]
42+
public void NormalizeNameRejectsInvalid(string name)
43+
{
44+
Assert.False(instance.TryNormalizeName(name, out _));
45+
}
46+
47+
[Theory]
48+
[InlineData(ValidNameFull)]
49+
[InlineData(ValidNameShort)]
50+
public async Task ResolveMinted(string name)
51+
{
52+
var tonClient = await getTonClient();
53+
54+
var adr = await instance.GetNftAddress(tonClient, name);
55+
Assert.Equal(ValidNameAddress, adr);
56+
}
57+
58+
[Fact]
59+
public async Task ResolveNotMinted()
60+
{
61+
var tonClient = await getTonClient();
62+
63+
// Does not exist as NFT at time of writing this test
64+
var adr = await instance.GetNftAddress(tonClient, "not-yet-minted-name.t.me");
65+
66+
// How to get expected value?
67+
// Replace with Assert.Equal if you know how.
68+
Assert.False(string.IsNullOrEmpty(adr));
69+
}
70+
71+
[Fact]
72+
public async Task GetFullDomainWorks()
73+
{
74+
var tonClient = await getTonClient();
75+
var dn = await instance.GetFullDomain(tonClient, ValidNameAddress);
76+
Assert.Equal(ValidNameFull, dn);
77+
}
78+
79+
[Fact]
80+
public async Task GetTokenNameWorks()
81+
{
82+
var tonClient = await getTonClient();
83+
var dn = await instance.GetTokenName(tonClient, ValidNameAddress);
84+
Assert.Equal(ValidNameShort, dn);
85+
}
86+
87+
[Fact]
88+
public async Task GetAllInfoWorks()
89+
{
90+
var tonClient = await getTonClient();
91+
var ti = await instance.GetAllInfo(tonClient, ValidNameAddress);
92+
Assert.NotNull(ti);
93+
}
94+
95+
[Fact]
96+
public async Task GetAllInfoByNameWorks()
97+
{
98+
var tonClient = await getTonClient();
99+
var ti = await instance.GetAllInfoByName(tonClient, ValidNameFull);
100+
Assert.NotNull(ti);
101+
}
102+
}
103+
}

TonLibDotNet.Tests/Recipes/TelemintRecipes_Tests.cs

Lines changed: 0 additions & 94 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace TonLibDotNet.Recipes
4+
{
5+
/// <inheritdoc />
6+
public class TelegramNumbersRecipes : TelemintRecipes
7+
{
8+
public static readonly TelegramNumbersRecipes Instance = new();
9+
10+
public override string CollectionAddress => "EQAOQdwdw8kGftJCSFgOErM1mBjYPe4DBPq8-AhF6vr9si5N";
11+
12+
/// <inheritdoc />
13+
/// <remarks>
14+
/// <para>Valid numers starts with '888' (or '+888') and must contain up to 16 digits, and optional delimiters (<b>+</b>, <b>(</b>, <b>)</b> and <b>-</b>).</para>
15+
/// </remarks>
16+
/// <exception cref="ArgumentNullException">Provided <paramref name="name"/> is null or empty or whitespace.</exception>
17+
public override bool TryNormalizeName(string name, [NotNullWhen(true)] out string normalizedName)
18+
{
19+
if (string.IsNullOrWhiteSpace(name))
20+
{
21+
throw new ArgumentNullException(nameof(name));
22+
}
23+
24+
normalizedName = string.Empty;
25+
26+
const int maxLen = 16; // currently numbers contain 7 or 11 digits, but will add a bit for future
27+
var len = 0;
28+
Span<char> chars = stackalloc char[maxLen];
29+
30+
foreach (var ch in name)
31+
{
32+
switch (ch)
33+
{
34+
case '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9':
35+
if (len >= maxLen)
36+
{
37+
return false;
38+
}
39+
40+
chars[len++] = ch;
41+
continue;
42+
case ' ' or '+' or '-' or '(' or ')':
43+
continue;
44+
default:
45+
return false;
46+
}
47+
}
48+
49+
if (!chars.StartsWith("888"))
50+
{
51+
return false;
52+
}
53+
54+
normalizedName = chars[..len].ToString();
55+
return true;
56+
}
57+
58+
/// <summary>
59+
/// ⚠ Original 'get_full_domain' method had been excluded from contract code.
60+
/// </summary>
61+
/// <remarks>
62+
/// Will always throw <see cref="NotImplementedException"/>.
63+
/// </remarks>
64+
/// <exception cref="NotImplementedException">Always.</exception>
65+
[Obsolete("Original 'get_full_domain' method had been excluded from contract code.")]
66+
public new Task<string> GetFullDomain(ITonClient tonClient, string nftAddress)
67+
{
68+
throw new NotImplementedException("Original 'get_full_domain' method had been excluded from contract code.");
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)