Bad ATA account - solana

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

Related

Get token list from connected solana wallet and create an array

I'm trying to figure out how to take the connected wallet, from the solana wallet-adapter and grab all the spl-tokens (NFTs specifically but that filter doesn't have to happen) and create an array with the token mint addresses. I'm fairly new to coding in general, so please bear with me. I was able to grab the wallet address (publickey) just fine, but cannot seem to get the token addresses from that wallet. I'm currently working in react with typescript files.
I've tried going through the Moralis Solana API https://docs.moralis.io/moralis-dapp/solana-sdk/account
but wasn't returning anything even when logging to the console. I also had some type problems, but I believe I worked those out.
You can probably use this
https://solana-labs.github.io/solana-web3.js/classes/Connection.html#getTokenAccountsByOwner
or this
https://solana-labs.github.io/solana-web3.js/classes/Connection.html#getTokenLargestAccounts

A deleted testnet account gets fully restored

I'm currently playing some stuffs with Near (testnet) following an example on github/Learn-NEAR/starter--near-sdk-as.
I accidentally deleted my account - quantransedev. After that I re-created with the same account name with new passphrase of course. I noticed the newly created account had everything the old one had. It seemed like a restore account.
Is this an expected behavior? it doesn't make sense to me at all in terms of security. Please advise.
https://explorer.testnet.near.org/accounts/quantransedev.testnet
https://explorer.testnet.near.org/transactions/3GTFEzvTfDiAxm8fdpZeWP7NjRFTjFJaDYQNX6ANAUns
This is expected behavior - when you delete an account it does not delete all the things this account owns or controls. That needs to be done manually before account is deleted.
Account deletion just deletes the information about this specific account state on-chain.
When you recreate the account - it will actually be back to controlling whatever was linking to it by account id.
Generally, if you delete account - that name and things it owns are up for grubs for anyone else, so account deletion should be done very careful.
Filed two issues to improve experience here:
https://github.com/near/nearcore/issues/5816
https://github.com/near/near-cli/issues/900
The account had been deleted and the remaining funds were burnt since the beneficiary account did not exist (the account got removed before the transfer was initiated). You can also confirm that the account had actually been removed by reviewing the next transactions (deletion of other accounts with beneficiary account id set to quantransedev.testnet) did not succeed to transfer the remaining tokens from the removed accounts (the tokens got burnt).
You had had to re-create the account explicitly from scratch: https://explorer.testnet.near.org/transactions/CroKF7ipwM3fDgH5ogVrnWS6JSmnhvjkaJNDqiWzjsm2 to gain control over the account id. Before that moment, the account did not exist on the chain. Explorer, however, keeps track of all the ever-existing accounts on the network, which might have confused you.

Google Assistant Smart Home : agentUserId definition may be incorrect

As per Google Assistant documentation for Smart Home, the agentUserId used in action.devices.QUERY is defined to 'Reflects the unique (and immutable) user ID on the agent's platform. The string is opaque to Google, so if there's an immutable form vs a mutable form on the agent side, use the immutable form (e.g. an account number rather than email)'
However there can be cases where the same device (with same agent user id) is attached to multiple Google Assistant accounts and in such cases a DISCONNECT request may result is ceasing report state for all accounts. The solution will be to add some unique ID corresponding to the Google Assistant account, however such information is not available in any request.
Has anyone seen similar issue and is my understanding incorrect?
The agentUserId is meant to be the user account on the smart home platform. SHP user '1234' may have a vacuum and two lights, but could be linked to multiple Google accounts.
During the account linking process, you would be expected to give a refresh and access tokens to allow for Google to have authorized control over these devices. If you assign unique access tokens for each Google account that signs in, you'd be able to determine which Google account the request is coming from.
At that point, once the user disconnects, you can use the access token in the request header to associate that with a specific Google account and only disable reporting for that account while not affecting other accounts.
So, yes the solution is to have a unique ID connecting to the account. While this is not passed in the agent ID, there is already a mechanism to make this association through the authorization system.
Alternatively, you could append a key in the agentUserId, ie. '1234-user#gmail.com'. However, this may have unintended impacts in the Home Graph. In a multi-user home, you may end up seeing the devices duplicated because Google doesn't have the right information to deduplicate.

How to cache PFUser locally if it fails to sign up due to internet failure?

My app creates a PFUser in order to differentiate each sending devices. I am not using PFUser.enableautomaticuser() for some technical reason.
Also, I am using local datastore by calling Parse.enableLocalDatastore()
When internet is down and app fails to sign up using
user.signUpInBackgroundWithBlock()
it won't save this user locally either. The created PFUser is discarded, calling PFUser.currentUser() returns nil.
Then how to cache created user locally when internet is unavailable? Thank you very much!
I ended up using PFUser.enableautomaticuser() and then make changes to PFUser.currentUser().
At last I will attempt to signUp, if failed, I will call saveEventually() so that next user logs in. They will retain the previous PFUser reference, so that their information won't be lost in case the user starts the application without internet.

Implementing Security for Ajax calls

I am facing difficulty in making my Ajax request secure.
The problem is Data tampering. I have read about this problem and it is suggested that never trust the information what ever is coming from client. It can be very well changed using fiddler or any such tool. We need to validate in server side as well. But my question is how to validate.
Let's see one example.
Suppose I have Employee information in database and I have exposed one method GetEmployeeDetailByEmployeeId. Before any employee make this request he will be authenticated with userId and password and authorized whether user of this type are allowed to make this request or not.
But if one employee gives employeeId of some other employee, he will actually gets the data which he is not supposed to see. To fix this issue we have two solution
1. We should check the request against the database, whether the information requested by the person is meant for him or he is the manager of that guy
2. We should somehow validate in app layer itself whether we should reject the call or not.
First approach is performance intensive where I have to make database request and finding the association of record, also it will add cost to development.
Pls suggest which way to go and do we have any better solution to solve this kind of problem.
Clearly you need to check it at your back-end side, otherwise your application is likely to exploit by a kid.
Update
you need to implement an authorisation mechanism in your back-end, then after you load the permissions at the beginning, you can add it to the user session, so you don't need to look-up the database each time, you just need to check the user permission against the task required permission.
More
To implement the authentication mechanism: Goal, user can see it's own profile but supervisor can see everyone within his department.
user A has the user_id already loaded at the session, let say user_id = 123
user A can only request his information so if (user_id == req_user_id) then show the information, otherwise show error.
user B has the permission value of 100, let's call him supervisor then. Now if (user_id == req_profile_id) is not true we will check the permission. Let say the task permission for this particular task is 10 so if (user_perm >= task_perm), go ahead and check the department, if both the requested user and current user are at the same department, then show the information, otherwise show an error.
this should works based on your information.

Resources