How to retrieve the top N accounts for an SPL token by quantity? - solana

Suppose I have an SPL token $TOKEN.
Let's say that 100 different accounts hold $TOKEN in associated token accounts. They hold different quantities of the token. For example, the distribution may look like this:
Account 00...01 holds 1 $TOKEN
Account 00...02 holds 2 $TOKEN
...
Account 00...99 holds 99 $TOKEN
I want to know who the top N token holders are by $TOKEN quantity. For example, if N = 3, I want to return these accounts in this order:
Account 00...99
Account 00...98
Account 00...97
Is there a way to easily retrieve this information?

This endpoint will return the 20 largest token accounts for the specified mint: https://docs.solana.com/developing/clients/jsonrpc-api#gettokenlargestaccounts

Related

Given an array of usernames, how do I retrieve only their details from a Model in Laravel?

Lets say I want to retrieve a user with a username $username, normally I will do Model::where('username',$username)->first(); Now, how should I do in order to get all the users given an array of usernames? Like $users = ['enock', 'Erick','Simon'];?
I have tried whereIn like Model::whereIn('username', $users)->get() but this returns the details of the first username alone and not the others yet I want all the users to be returned.
I had space before the second username " Yonetim"
$usernames = ["Simon"," Yonetim"];
$users= User::whereIn('username', $usernames)->get();
return $users;
So this is still the correct way of doing it Model::whereIn('username', $usernames)->get();

How should I store multiple sessions in Redis?

I am new to the Redis. I want to store the user id / session token pairs on the Redis. But, A user can have multiple session tokens. For example, you might think that when the user changes their password, I want to delete all session pairs of this user. Also, each session pair must have an expiration date. The method to be recommended should not spoil this.
How can I do this most effectively and correctly?
Thanks in advance.
you can use sorted set for this
key: user:<id>:tokens
member name is token, member score is its expire timestamp
add a new token zadd <key> <token> <expire_timestamp>
to get all tokens for user zrange user:1:tokens 0 -1. Add WITHSCORES if you need expiration timestamp along with the token.
to get tokens with valid time zrangebyscore <key> <current_ts> +inf
to delete all tokens del <key>
Example of cleanup code
async function getTokens(userId) {
const lastCleanupTsKey = `user:${userId}:tokens:cleants`
const tokenKey = `user:${userId}:tokens`
cosnt [[lastCleanTimestamp, err1], [size, err2] = await redis.pipeline()
.get(lastCleanupTsKey)
.zcount(tokenKey)
.exec()
if (!lastCleanTimestamp) {
await redis.set(lastCleanupTsKey, <current_timestamp>)
}
if (size !== null && size > CLEANUP_SIZE_THRES_HOLD) { // you can also check if lastCleanup is more than 5 minutes for example here.
await redis.ZREMRANGEBYSCORE(tokenKey, '-inf', <current_timestamp>)
}
// do your logic
}

How to get isFeatureEnabled to return the same value for all users in the same organization?

Let's say I have a small business product that we are selling to organizations. How do I ensure that all users in the same organization get the same experience?
For example, let's say I have the following two users (user with id 123 and user with id 456) who belong to the same organization (organization with id 789).
Calling isFeatureEnabled('my_feature', userId) returns different values for the different users.
How do I ensure that user 123 and 456 get the same experience since they belong to the same organization?
There are a few ways you can do this depending on the use case. The full API signature of isFeatureEnabled is the following:
isFeatureEnabled(feature_key, userId, attributes)
where in general:
isFeatureEnabled(
'my_feature', // feature key identifier linking feature to Optimizely UI
'123', // userId parameter used as input to random bucketing
{ 'organizationId': '789' } // attributes used for non-random targeting
)
--
Use Case 1: If you want to manually select one-by-one which organization gets the feature enabled, you should use audience targeting via attributes.
You can pass in the organizationId as an attribute and setup an audience to target all visitors that are in that organization.
isFeatureEnabled('my_feature', '123', { organizationId: '789' } ); // User 123
isFeatureEnabled('my_feature', '456', { organizationId: '789' } ); // User 456
For instructions on how to setup the attributes and audiences in the Optimizely UI for this use case, follow this documentation article.
Using attributes and audiences allows you to enable or disable a feature for specific organizations one-by-one. However, this approach does not allow you to randomly rollout to a percentage of the possible organizationIds or do an A/B test on a random sampling of organizationIds.
--
Use Case 2: If you want to run rollout to a random sampling of organizationIds or run an A/B test where a random set of organizations get a particular experience you should pass in the organizationId as the userId parameter to the isFeatureEnabled API:
isFeatureEnabled('my_feature', '789'); // User 123
isFeatureEnabled('my_feature', '789'); // User 456
The userId parameter to isFeatureEnabled is used to randomly bucket the user. Since the userId can accept any string, using the organizationId in this case ensures that both user 123 and 456 will get bucketed into the same experience.
--
Use Case 3: If you want to be able to both run an A/B test across organizations but also have the ability to target only certain organizations, you should combine the methods of the two uses above like the following:
isFeatureEnabled('my_feature', '789', { companyId: '789' } ); // User 123
isFeatureEnabled('my_feature', '789', { companyId: '789' } ); // User 456
This way allows you to manually (rather than randomly) select one-by-one which customer should see an experience or be eligible for an experiment while also allowing you to rollout randomly across organizations or run an A/B test across organizations.

Customize Passport Queries time of authenticating

For every request I found that 4 queries are fired to validate the user and the token. Among them one is to fetch the user (select * from user) based on the user id. This queries are fired by Passport/Laravel But what I want is to modify this query to add one status field check also to check if any user become invalid during the token validity period. If we only check with the id then if any user become inactive(By changing status then also we will not be able to stop the user as deleting the token for the user is not a good solution for me).
Queries Fired on every request by Passport Laravel:
select * from oauth_access_tokens where id = ?
select * from user where id = ? limit 1 ["2"]
select * from oauth_access_tokens where id = ?
select * from oauth_clients where id = ?
So, can anyone tell me how to change the 'select * from user where id' query in passport at time of Token validation.
You can add this method on your User model (or any model you're authenticating with passport)
...
public function findForPassport($username)
{
return $user = (new self)->where('email', $username)->where('is_active', 1)->first();
}
...
of course you can modify is_active by whichever column you are using (and/or any query constraint for that matter), as long as it returns Illuminate\Contracts\Auth\Authenticatable contract.
I wouldn't try and modify passports default behaviour as I have no idea what else it might impact both now and in future upgrades.
Your best bet might be to hook into the passport events and apply you business logic to a listener that is called when the events are fired

How is remember token generated?

I have remeber_token field in the users table. And i'm pretty much confused on how it is generated? because i can see two different types of tokens in the database for two different users.
mFqEE5PUS4ZlOdQ51WEomGqJ1vFQCzw6zumvvW8rkpBUclC161HtvK8LsXXP
and the other of kind:
78x6c35esh2Ya0g4fb1d9
How is it so? And are remember token and forgot password token generated with different algorithms?
I looked into the code and it has the following function to generate the token
protected function refreshRememberToken(AuthenticatableContract $user)
{
$user->setRememberToken($token = Str::random(60));
$this->provider->updateRememberToken($user, $token);
}
from the docs:
str_random()
The str_random function generates a random string of the specified length. This function uses PHP's random_bytes function:
your token
mFqEE5PUS4ZlOdQ51WEomGqJ1vFQCzw6zumvvW8rkpBUclC161HtvK8LsXXP
has 60 letters, i dont know why the other token has less.

Resources