Concept of Token Program & Associated Token Account Program - c#

I'm trying to send a token [USDT] from one wallet to another. But I think I'm having some trouble understanding the concept of Associated Token Account [ATA]
According to my understanding:
1 - Every wallet account that wants to keep, receive or send tokens, must register in the account for these tokens in the network?
2 - The sending person can register the account of the receiving person
3- Are these concepts correct?
All of the above are done by the following instructions =>
AssociatedTokenAccountProgram.CreateAssociatedTokenAccount
4 - Once the recipient's wallet address is registered, can send the tokens to him via instructions =>
TokenProgram.Transfer
Account ownerAccount = wallet.Account;
PublicKey UsdtAddress = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
PublicKey ToAddress = new PublicKey("CDQ3Gya9QermsPzU3cTNW9QPLbMVLbALQ2S8AwbruVJ");
var Transaction = new TransactionBuilder().
SetRecentBlockHash(blockHash.Result.Value.Blockhash).
SetFeePayer(wallet.Account).
AddInstruction(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
ownerAccount, // Sender Account [Wallet Owner] ?
UsdtAddress, // Tether Address On-Chain ?
ToAddress)). // The Recipient Wallet Address ?
AddInstruction(TokenProgram.Transfer(
ownerAccount,
ToAddress,
100,
ownerAccount)).
Build(new List<Account> { ownerAccount });
var txReq = await rpcClient.SendTransactionAsync(Transaction);
I'm so sorry for the long wait, but after a lot of attempts, all of them were unsuccessful, I really think I need someone to explain how sending tokens works.

After a long struggle I was able to reach some results, I will leave this comment as a solution to the problem and an understanding of how things work, and if it contains some errors, please do not hesitate to leave an explanation and a correction for this
Let's agree on some concepts first:
1- Wallet account is a normal account, owned by the system Program and called [account owner]
2- The person who owns the private key is known as the authority
3 - Each token has an account on the chain, has its own owner and authority
what is happening now ?
If you want to own some of these tokens for the first time, you must create an account known as Associated Token Account
Associated Token Account: It is simply an account within the network that associates each wallet with a special and unique address of a token!! Is this clear??
Your wallet number => Associated Token Account <= token account number
G1G2G3G4 => A1T2A3T4 <= USDTADDRESS243
Its job is to save and store data for a specific wallet address with a specific token address, such as quantity, balance and many other features that I have not seen yet
The first time you will send these tokens to an account that does not contain [ATA], you will build instructions to create [ATA] for this account, and attach instructions directly to send the tokens with the same transaction, this structure worked for me,
Finally: It is possible to know the Associated Token Account for a wallet simply, because we will need to send the tokens with the Associated Tokens and not the addresses of the main wallets
Here is the code to create a Associated Token Account and send some USDT to the address:
PublicKey UsdtAddress = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
//The [ATA] for my public address in the USDT token account = Sender
Account ownerAccount = wallet.Account;
var FromAssociatedTokenAccount=AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(ownerAccount,UsdtAddress);
//The [ATA] for Receiver public address in the USDT token account = Sender = Receiver
PublicKey ToAddress = new PublicKey("DqiE6PDXPFMMDC2jzoqY45VEqyEzdGd5qauVCQY8s3A7");
var ToAssociatedTokenAccount = AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(ToAddress, UsdtAddress);
//Note that a ToAssociatedTokenAccount can be defined, with the possibility that it is not registered/created on-Chain
var blockHash = await rpcClient.GetRecentBlockHashAsync();
var Transaction = new TransactionBuilder().
SetRecentBlockHash(blockHash.Result.Value.Blockhash).
SetFeePayer(ownerAccount).
AddInstruction(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
ownerAccount,
ToAddress,
UsdtAddress)).
AddInstruction(TokenProgram.Transfer(
FromAssociatedTokenAccount,
ToAssociatedTokenAccount,
1,
ownerAccount)).
Build(new List<Account> { ownerAccount });
var txReq = await rpcClient.SendTransactionAsync(Transaction);
So finally, please bring a cup of coffee and read this article, I think it is good to clarify some concepts about the Solana Blockchain :
https://www.brianfriel.xyz/how-to-create-a-token-on-solana/

Related

Following a course on building website - can't understand a block of code

I'm trying to learn ASP.NET.
There's a course that I'm following and I can't really understand a few things.
Here's the code, in a controller:
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
{
var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);
if (userFromRepo == null)
{
return Unauthorized();
}
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
new Claim(ClaimTypes.Name, userFromRepo.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSetings:Token").Value));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
v
var tokenDescriptor = new SecurityTokenDescriptor{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(new {
token = tokenHandler.WriteToken(token)
});
}
I can't understand the claims array. I've been searching online for a while, and I don't get it. Why do I need it and how does it work?
I've found this to be quite useful, but I still don't
What is the claims in ASP .NET Identity
fully understand it.
Can anybody help me get this concept? Why do we need it and how does it work?
Thanks.
What are claims?
Assuming you are an officer at the boder and your job is to issue immigration permit
to immigrants. Before you issue a permit to anyone, the person must be able to
identify himself that he really belongs to the country which he is claiming
to come from. That person might bring his Certificate of birth, National Id
Card, Visa or any authorized means of Identification. Those things are called
claims. The person has to show you something which he has to prove to you that
really he is from that country. Sometimes, one claim presented is enough.
At another country, they might say that you provide at least three claims
(i.e means of identification) before they issue you this permit just to make
it tough for countries with higher security issues.
That array could simply just have one claim inside, you could choose to put
as much claims as you wish and make other rules internally to make your
system more tough and secure. Its up to you.
The best example is the driving license.
A driving license can have the following claims
Name
Birthday
Allowed to drive a car
Allowed to drive a motorcycle
Allowed to dive a truck
Allowed to dive a bus
...
When the police stops you in your vehicle it will validate if you are authorised to drive the specific vehicle and if the issuer is to be trusted before allowing you to continue your journey. To get more info you could read this article.
The same concept goes with claim based authorisation. A specific user can have different claims that can grant him access to different functionalities.
When you connect an authorization provider like Facebook or Google, you can ask for specific claims, not very application needs a birthdate to function, while some others might need it to verify if the user is of legal age.

How to add contact from two different Telegram servers?

Adding a contact from a country like Iran to a telegram account from Canada, causes an error says:
Unfortunately -name- has not joined telegram yet. But you can send
them an invitation.
I think that's because there are two different accounts from two different servers that aren't synced well.
Sometimes Iranian account can add Canadian account, and then Canadian can add Iranian as well, even if Iranian deletes Canadian from contacts. Or if a third person share their contacts or forward a message from one to another, they can add each other. I think these signs shows that telegram servers are not synced well.
As I'm using TLsharp to accomplish that, I can add two telegram accounts, one plays as that third person role, and shares Iranian contact to Canadian, and then he can save that contact.
My step by step plan is:
What I have is an Iranian Telegram account and Canadian one.
Iranian Customer opens my web site.
she/he fills telegram phone number field and submits.
we are going to start sending message in telegram by Canadian account.
try to add contact by Canadian account.
If failed, try to add contact by Iranian account. Else, we are done!
Share contact to Canadian Account.
Add contact by Canadian account.
My problem is:
how to have multiple telegram accounts in my code, because session file name is always "session.dat"
how to share contact in TLSharp
I can't forward message because there isn't any message yet. We should start messaging.
I also tried retrieving UserId and AccessHash by Iranian account, and using by Canadian account in this method:
await client.SendMessageAsync(new TLInputPeerUser() { UserId = xxx, AccessHash= yyyy}, "Hello");
but it has PEER_ID_INVALID error. (That is not true, I just took UserId from telegram!)
The problem is in number of contacts!
Telegram only supports about 1000 contacts (I found it experimental, there isn't any official source to prove this), and it will show you error when you want to add more contacts.
Trying to delete some contacts and reduce the count to 900, allowed me to add new contacts. So, the problem is not in telegram servers, it is in number of contacts limitation. Maybe they have a line of code like this:
Contact[] contacts = new Contact[1000]; //LOL
And for other two questions:
how to have multiple telegram accounts in my code, because session
file name is always "session.dat"
TLSharp.Core.TelegramClient clientAlt = new TLSharp.Core.TelegramClient(api_id, api_hash, sessionUserId: "sessionAlt");
There isn't any good documentation for TLSharp, but the problem solved by using sessionUserId as an optional parameter.
how to share contact in TLSharp?
TLInputMediaContact contact = new TLInputMediaContact()
{
FirstName = FirstName,
LastName = LastName,
PhoneNumber = PhoneNumber
};
TLRequestSendMedia req = new TLRequestSendMedia()
{
Media = contact,
Peer = new TLInputPeerUser() { UserId = AnotherTelegramAccountUserID.Id },
RandomId = UniqueNumber_ToPreventDuplicateMessages,
};
await clientAlt.SendRequestAsync<TLUpdates>(req);

ASP.NET Boilerplate Allow Self-Provisioning Tenant Registration

so im trying to create a SaaS application with ASP.NET Boilerplate, and i come into some problem as follows:
As i observe the framework, i noted that the "RegisterAsync" function in UserRegistrationManager create user based on the currently active tenant. It means if i currently log in on tenant '1', then when i register new user, the new user will have tenantId '1'. On the other hand, when i currently not logged in, if i register a new user, the app will show exception 'cannot register host user'.
public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string phoneNumber, string userName, string plainPassword, bool isEmailConfirmed)
{
CheckForTenant();
var tenant = await GetActiveTenantAsync();
var user = new User
{
TenantId = tenant.Id,
Name = name,
Surname = surname,
EmailAddress = emailAddress,
PhoneNumber = phoneNumber,
IsActive = true,
UserName = userName,
IsEmailConfirmed = isEmailConfirmed,
Roles = new List<UserRole>()
};
return user;
}
private void CheckForTenant()
{
if (!AbpSession.TenantId.HasValue)
{
throw new InvalidOperationException("Can not register host users!");
}
}
The application that i want to build requires the function for new user to be able to sign up along with free trial and then paid subscription. So i think that the new user should be able to create tenant by themself. So if the new user register, they will be forced to create new tenant before they can do any other thing in the app.
The problem is that the tenantId column in User table cannot be null, so i can register without tenant. Im thinking of assign all newly created user to 'Default' tenant at first, but i think that this was not the best practices.
Is there any way to overcome this problem or any references about that? Thanks in advance!
Based on my empirical SaaS Application development experience, a typical Self-Signup flow in Multi-Tenant applications would be like the one given below
User opts to self-signin
Allow the user to pick a subscription plan (most likely a trial plan)
Get the Company Name (tenant name) as part of the signup flow
Create a new tenant that has the subscription (2)
Add the signup user as the administrator for that tenant
In case of a trial plan, set up the suitable request handler to keep validating if the tenant has crossed the subscribed number of trial days, in that case, force redirect to payment page or signout
If the user has opted to Signup for a paid subscription (during signup), after provisioning the tenant go to the payment page. Once payment succeeds, capture the transactionid and allow the user to login and use the application.
The flow that you wanted to be using is straightforward
Build a custom self-signup process, obtain the company name (Tenant Name)
Also capture the emailid of the user that is performing the sign-up
Create the tenant based on info from (1)
Set the administrator for the tenant based on the info from (2)
All your API calls should be working fine.
Note
Have a separate Self-Signup Service like (TenantSelfRegistrationService) so that you can allow anonymous access to that service.
In terms of security, set captcha and set rate-limits or CSRF Tokens etc to enforce security in the signup process.
Hope this clarifies
I looked at the code and the documentation and I think you should never allow an unknown user to create new tenants. This should happen by a person who has the correct authorization to create tenants. This is a user that exists in the host tenant.
You as admin in the host tenant need to create tenant for somebody else and add them as admin for that tenant.
Registering users is then done through the normal way with the register webpage running for that tenant.
How to do that, I leave to you to figure out with the documentation of boilerplate itself! Documentation

Adding Bank Account in Stripe.NET for Managed Account

I've searched through the documentation on both the Stripe website and JaymeDavis' GitHub and still cannot manage to figure out if I'm correctly creating a bank account for a managed stripe account. From Stripe's website, it's clear this is what I need...
curl https://api.stripe.com/v1/accounts/acct_1032D82eZvKYlo2C/external_accounts \
-u sk_test_xxxxxxxxxxxxxxxxxxxxxx: \
-d external_account=btok_xxxxxxxxxxxxxxxxxxx
I have the token (btok....) returned from Stipe.js, and I have the account ID used in the curl link for the managed account, as well as the secret key. However, I cannot figure out what the process is to execute this in C#
My guess so far has been:
//Sample code for creating a managed account
StripeAccountService stripeAccountService = new StripeAccountService();
StripeAccountCreateOptions managedAccountCreateOption = new StripeAccountCreateOptions();
managedAccountCreateOption.Managed = true;
managedAccountCreateOption.Country = "US";
StripeRequestOptions connectAccountRequest = new StripeRequestOptions();
connectAccountRequest.ApiKey = ConfigurationManager.AppSettings["StripeApiKey"];
Stripe.StripeAccount response = stripeAccountService.Create(managedAccountCreateOption, connectAccountRequest);
// ADD Bank Account
var myAccount = new StripeAccountUpdateOptions();
myAccount.ExternalBankAccount.TokenId = "SampleToken";
var accountService = new StripeAccountService();
Stripe.StripeAccount bankAccount = accountService.Update(response.Id, myAccount);
The problem I'm having here is with adding the bank account. I want to create the bank account separately so that I can save the last 4 digits of a card/bank account (non-sensitive data) used in payouts in our database. The way above simply adds a single bank account to the managed user, and will not work as I would like to add multiple bank accounts for payouts. Any sample code in adding a bank account to an already existing managed account would help immensely (i.e. create a bank account with the token returned from Stripe.js, then in a separate action add this bank account to the managed user account so that I can grab the last 4 digits of this bank account as well as any additional accounts that are added in this way in the future). Thank you in advance for your help and time!
You can just retrieve a Managed Account instead of creating one, i.e.:
StripeAccount response = accountService.Get(accountId);
From there you can add additional Bank Accounts. The result of that API call is a BankAccount, and you should be able to access the last4 from there.

google activity api limit result userid not working

i try to limit the list activity to a specific user but i always get the same results. i've tried users email address and the user id from the user list api function, both are not working.
i found a an open issue here, without an answer: https://code.google.com/p/google-apps-script-issues/issues/detail?can=2&start=0&num=100&q=&colspec=Stars%20Opened%20ID%20Type%20Status%20Summary%20Component%20Owner&groupby=&sort=&id=4974
my code:
ActivitiesResource.ListRequest listRequest = service.Activities.List();
listRequest.Source = "drive.google.com";
listRequest.DriveAncestorId = "root";
listRequest.UserId = "users email or Id";
listRequest.PageSize = 10;
IList<Activity> activities = listRequest.Execute().Activities;
additional info - i'm using a service account to authenticate
thanks
It is currently not possible to filter by user ID. Don't want to get into too many details, but the userId field has a different purpose that was never fully realized. Right now it's effectively ignored.

Categories