How do I use 'create_account_and_claim' - nearprotocol

I've had some success creating accounts using create_account with the JSON RPC.
I've read from the co-founder of NEAR that we can create accounts and generate links for those accounts to be claimed.
The documentation doesn't mention it, I guess they're updating.
When I try to use call it I get an error saying left and right accounts don't match

NEAR Linkdrop contract README has the description on the high-level: https://github.com/near/near-linkdrop
Receiver, that doesn't have NEAR:
Receives link to the wallet with privkey1.
Wallet creates new key pair for this user (or they generate it via HSM) (pk2, privkey2).
Enters the new_account_id receiver want for their new account.
Wallet creates a transaction to create_account_and_claim(new_account_id, pk2).
Contract creates new account with new_account_id name and pk2 as full access key and transfers NEAR that Sender sent.
P.S. This linkdrop contract is exactly the one that is deployed to the account that is named near on mainnet.

Related

Bad ATA account

When using metaplex auction-house contract, some users are unable to complete a sell command.
Confirmed that if the same NFT is sent to a different wallet, that wallet can sell just fine.
The issue seems to be bad ATA.
Initially , the ATA account that returned via https://github.com/metaplex-foundation/metaplex/blob/b7760611d0838307757b831505eaaffee25b1b2a/js/packages/cli/src/auction-house-cli.ts#L260 didn't have owner or token inside.
See failure:
https://explorer.solana.com/tx/4Y6ZBqeWH1yFvaEJ2Hv6mkCxqdVNt9GQ9iHq15PoJY5JVxmTzHJx3MSKABchMBaY3Jd5WY4HpeN4a9bSTQKEJv1Z
When sent to another wallet, was able to complete just fine.
https://explorer.solana.com/tx/GUybhU53qY56bu4j2raQyp7uecGLgaFge6GBvRNtX1u8gqDzocKk8MDg52upZV985UPW8FAregpwTv7JGyWdNwf
After manually setting up the ATA, still didn't help.
https://explorer.solana.com/address/Cu6Dru1j6PZa3f9K2acuqsHcaVDRxniFVqPPk7WX7RaC
Seems like due toe the token being 0.
Tried finding the correct ATA by using getTokenLargestAccounts but then I'm getting 0x12c which says PublicKeyMismatch.
Would love some help in finding a stable way to complete this, this is happening to many users sporadically.
The code that you linked, getATAForMint, does not actually create the ATA, which is why owner and token weren't populated.
The succeeding transaction that you linked correctly creates the ATA, which is why it succeeds.
So one way to resolve this is:
Before doing a transfer to your user, check that an account exists at the address, perhaps by calling getAccountInfo on the ATA: https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
checking that the owner field is the token program, given by TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA. More info about ownership at: https://docs.solana.com/developing/programming-model/accounts#ownership-and-assignment-to-programs
if the account exists, great, nothing to do. If it doesn't exist, then you have to add an instruction to create the associated token account, ie. through some call like this: https://github.com/solana-labs/solana-program-library/blob/8eb2c3ce60bfe943e277eb172ba8e9ce9b6bdae6/token/js/client/token.js#L494

How to verify public address owner with crypto wallets

I am currently thinking about creating a dapp that connects to a phantom wallet on solana. A user account will be created upon connection Signup/Login a User. I'm not sure how to verify the public address. Wallets will pass information to the frontend and i would have to forward this information to the backend, thus it is manipulable and useless... How do I prevent people from sending fake addresses to the server and signing up to any account they want? I thought about signing a message but why is this not done on e.g. opensea.io(Eth/Metamask)?
How do I prevent people from sending fake addresses to the server and signing up to any account they want?
Make them sign a message.
I thought about signing a message but why is this not done on e.g. opensea.io(Eth/Metamask)?
This is not done on OpenSea because OpenSea does not create or manage user accounts for its users. The app relies entirely on the PKI of the user's Web3 provider (such as MetaMask).
Ask yourself why you need to create a user account for your users on your backend. If you need to create such an account, then make the user sign a message. If you don't need to create a user account, then just let the user authenticate directly with the blockchain using their own PKI like OpenSea does.
Why not create the Keypair (public + private key) in the backend itself? Since you're creating a new account on signup. Send a request to the backend and create account and return the public key to the user.
But instead of doing this. You can ask the user to create a new wallet and singup using something like a phantom wallet. Did that help?

How to add a ledger-enabled account created outside of near wallet to the near wallet?

I have an account which was initially created via near-cli.
I then geneated a ledger key:
near generate-key key --useLedgerKey="44'/397'/0'/0'/2'"
And added it to the account:
near add-key <account_id> <the key from the previous step>
I now open the wallet, click "Access your account", "Ledger Recovery", "Sign in with Ledger", "Sign In".
At this stage it asks me to confirm the public key, though doesn't really show which public key I am approving. I approve it on the ledger.
It asks me for the account id, I enter it. It says "user found".
I confirm, and it errors out with "No accounts are associated with this Ledger device. You must first create an account, then add this Ledger to it to login."
How do I get around it? Am I using the wrong path when generating the key?
Currently, the NEAR Wallet only supports the default Ledger path:
"44'/397'/0'/0'/1'"
If you add the public key that corresponds to this HD path to your account, you should be able to login successfully.
near generate-key key --useLedgerKey="44'/397'/0'/0'/1'"
Unfortunately this is not supported yet. Current Ledger support in wallet is limited to use 44'/397'/0'/0'/1' HD key path. This is going to change in later releases.
In the meanwhile if you want to stake your tokens from multiple such accounts you might find this tool useful:
http://multistaker.near.org/
The NEAR wallet now supports the updated flow which allows you to create your account using any ledger path from the CLI (as per your question), fund that account or implicit account (the 64 char nonsense string) with at least 1 NEAR and then add that account to your NEAR wallet. You can't add without funding the account since it takes NEAR to make the add.
To add to the wallet, on the wallet dropdown select "Import Account" and then click "Advanced Options" to bring up the HD path selector. Select the right HD path, plug in the ledger and good to go.
ATM Chrome isn't working with the wallet as per this post but firefox does.
There is currently an open path to import a private key into the NEAR Wallet. To my understanding, the wallet then creates another new keypair on the fly and adds it as a full access keypair, such that the wallet doesn't actually use or store the private key you just sent it after this transaction.
https://wallet.near.org/auto-import-secret-key#YOUR_ACCOUNT_ID/YOUR_PRIVATE_KEY
See also How to import an account into the NEAR wallet using only the private key (no seedphrase)

Can a contract remove itself in NEAR Protocol?

I want to design the flow of upgrading a locked contract.
(A locked contract is the one that has no access keys allowing to alter the code; e.g. the full access key is removed once the code is deployed).
By design, there are no keys that can sign the transaction on behalf of the account to initiate the account deletion for a locked account, but I wonder if the code deployed on the account (the contract code) can still remove itself (self-destroy) [I assume it is possible since it seems that it can issue receipts from self to self].
Would the following upgrade strategy work?
Initial phase:
Create an account
Deploy code with some upgradability helpers
Lock the account (remove the full access key)
Upgrade:
Create a new account
Deploy new code to the new account
Lock the new account
Call the migration method, which reaches to the old version (via a cross-contract call) and requests to transfer the ownership (give all the data and remove itself)
It seems that some sort of owner validation will need to be implemented in the upgradability helpers to make sure that only an owner can transfer the ownership from the old version to the new one, but that is another question; first, I want to know if a contract can destroy itself.
I believe it is possible. You can have a method that uses promise_batch_action_delete_account to delete self and then add an access key to the contract that allows it to call that method.
Delete contracts or accounts using
Promise::new(contract_id).delete_account(beneficiary_id);
Reference: https://docs.rs/near-sdk/3.1.0/near_sdk/struct.Promise.html#method.delete_account
Source code: https://github.com/near/near-sdk-rs/blob/9d99077c6acfde68c06845f2a1eb2b5ed7983401/near-sdk/src/promise.rs#L309

How do I sign a message with a newly created Near account in a 3rd party app?

I'm setting up a new Near account, and I want to use its keys to sign a message in an app I'm building. How can I do this?
I used the wallet.nearprotocol.com page to create an account. Then, I used nearlib to connect to the testnet, and verify the account's balance and public keys.
But I couldn't find a way to add the account into the localStorage key store or otherwise access a method to sign a message. Nor could I find a wallet plugin or extension that would provide me access.
Generally the idea is that you never transfer given private key between 2 devices / security contexts.
So normally instead of getting private key out of wallet you just want to generate new key pair and request wallet to add public key.
https://github.com/nearprotocol/nearlib/blob/master/src.ts/wallet-account.ts provides relatively easy way to do it for webapp.
Note that it limits access to a give contract ID, so if you need unrestricted access you basically just need to omit contractId.
See examples at https://near.dev/ for WalletAccount usage.

Resources