Skip to content

Commit

Permalink
Merge branch 'staging' into hotfix/rmv-anchor-wallet-copy
Browse files Browse the repository at this point in the history
  • Loading branch information
Bhargavamacha authored Jun 7, 2024
2 parents 5f8730d + ca8b26a commit a532241
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 11 deletions.
133 changes: 133 additions & 0 deletions clients/rwa-token-sdk/src/asset-controller/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {
getAssetControllerProgram,
getTrackerAccountPda,
} from "./utils";
import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js";
import { getPolicyAccount, getPolicyEngineAccount, PolicyAccount, PolicyEngineAccount } from "../policy-engine";
import { DataAccount, DataRegistryAccount, getDataAccountsWithFilter, getDataRegistryAccount } from "../data-registry";
import { getIdentityAccount, getIdentityRegistryAccount, IdentityAccount, IdentityRegistryAccount } from "../identity-registry";

/**
* Retrieves a asset controller account associated with a specific asset mint.
Expand All @@ -23,6 +27,46 @@ export async function getAssetControllerAccount(
.catch(() => undefined);
}

export interface AssetControllerDataFilter {
assetMint?: string;
authority?: string;
delegate?: string;
owner?: string;
}

export const ASSET_CONTROLLER_ASSET_MINT_OFFSET = 9;
export const ASSET_CONTROLLER_AUTHORITY_OFFSET = 41;
export const ASSET_CONTROLLER_DELEGATE_OFFSET = 73;

/**
* Retrieves a asset controller account associated with a specific asset mint.
* @param assetMint - The string representation of the asset mint.
* @returns A promise resolving to the fetched asset controller account, or `undefined` if it doesn't exist.
*/
export async function getAssetControllerAccountsWithFilter(
filter: Omit<AssetControllerDataFilter, "owner">,
provider: AnchorProvider
): Promise<AssetControllerAccount[] | undefined> {
const { assetMint, authority, delegate } = filter;
const assetProgram = getAssetControllerProgram(provider);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
filters.push({ memcmp: { offset: ASSET_CONTROLLER_ASSET_MINT_OFFSET, bytes: new PublicKey(assetMint).toBase58() } });
}
if (authority) {
filters.push({ memcmp: { offset: ASSET_CONTROLLER_AUTHORITY_OFFSET, bytes: new PublicKey(authority).toBase58() } });
}
if (delegate) {
filters.push({ memcmp: { offset: ASSET_CONTROLLER_DELEGATE_OFFSET, bytes: new PublicKey(delegate).toBase58() } });
}
const assetAccounts = await provider.connection.getProgramAccounts(assetProgram.programId, {
filters,
});
return assetAccounts.map((account) =>
assetProgram.coder.accounts.decode("AssetControllerAccount", account.account.data)
);
}

/**
* Retrieves a tracker account pda associated with a specific asset mint and owner.
* @param assetMint - The string representation of the asset mint.
Expand All @@ -41,3 +85,92 @@ export async function getTrackerAccount(
.then((account) => account)
.catch(() => undefined);
}

export const TRACKER_ACCOUNT_ASSET_MINT_OFFSET = 9;
export const TRACKER_ACCOUNT_OWNER_OFFSET = 41;

/**
* Retrieves all tracker accounts associated with a specific asset mint.
* @param assetMint - The string representation of the asset mint.
* @returns A promise resolving to the fetched tracker accounts, or `undefined` if it doesn't exist.
*/
export async function getTrackerAccountsWithFilter(
filter: Omit<AssetControllerDataFilter, "authority" | "delegate">,
provider: AnchorProvider
): Promise<TrackerAccount[] | undefined> {
const { assetMint, owner } = filter;
const assetProgram = getAssetControllerProgram(provider);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
filters.push({ memcmp: { offset: TRACKER_ACCOUNT_ASSET_MINT_OFFSET, bytes: new PublicKey(assetMint).toBase58() } });
}
if (owner) {
filters.push({ memcmp: { offset: TRACKER_ACCOUNT_OWNER_OFFSET, bytes: new PublicKey(owner).toBase58() } });
}
const trackerAccounts = await provider.connection.getProgramAccounts(assetProgram.programId, {
filters,
});
return trackerAccounts.map((account) =>
assetProgram.coder.accounts.decode("TrackerAccount", account.account.data)
);
}

export interface RwaAccounts {
assetMint: string;
assetController?: AssetControllerAccount;
tracker?: TrackerAccount;
policyEngine?: PolicyEngineAccount;
policyAccount?: PolicyAccount;
dataRegistry?: DataRegistryAccount;
dataAccounts?: DataAccount[];
identityRegistry?: IdentityRegistryAccount;
identity?: IdentityAccount;
}


/**
* Retrieves all RWA accounts associated with a specific asset mint.
* @param assetMints - The string representation of the asset mint.
* @returns A promise resolving to the fetched RWA accounts, or `undefined` if it doesn't exist.
*/
export async function getRwaAccountsWithMints(
assetMints: string[],
provider: AnchorProvider,
owner?: string,
): Promise<RwaAccounts[]> {
const accounts: RwaAccounts[] = [];
for (const assetMint of assetMints) {
const assetController = getAssetControllerAccount(assetMint, provider);
const tracker = owner ? getTrackerAccount(assetMint, owner, provider) : undefined;
const policyEngine = getPolicyEngineAccount(assetMint, provider);
const policyAccount = getPolicyAccount(assetMint, provider);
const dataRegistry = getDataRegistryAccount(assetMint, provider);
const dataAccounts = getDataAccountsWithFilter({ assetMint }, provider);
const identityRegistry = getIdentityRegistryAccount(assetMint, provider);
const identity = owner ? getIdentityAccount(assetMint, owner, provider) : undefined;

const [resolvedAssetController, resolvedTracker, resolvedPolicyEngine, resolvedPolicyAccount, resolvedDataRegistry, resolvedDataAccounts, resolvedIdentityRegistry, resolvedIdentity] = await Promise.all([
assetController,
tracker,
policyEngine,
policyAccount,
dataRegistry,
dataAccounts,
identityRegistry,
identity
]);

accounts.push({
assetMint,
assetController: resolvedAssetController,
tracker: resolvedTracker,
policyEngine: resolvedPolicyEngine,
policyAccount: resolvedPolicyAccount,
dataRegistry: resolvedDataRegistry,
dataAccounts: resolvedDataAccounts,
identityRegistry: resolvedIdentityRegistry,
identity: resolvedIdentity,
});
}
return accounts;
}
70 changes: 63 additions & 7 deletions clients/rwa-token-sdk/src/data-registry/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type AnchorProvider } from "@coral-xyz/anchor";
import { type DataRegistryAccount, type DataAccount } from "./types";
import { getDataRegistryPda, getDataRegistryProgram } from "./utils";
import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js";

/**
* Retrieves data registry account associated with a specific asset mint.
Expand All @@ -15,17 +16,72 @@ export async function getDataRegistryAccount(assetMint: string, provider: Anchor
.catch(() => undefined);
}

export interface DataRegistryFilter {
assetMint?: string;
authority?: string;
delegate?: string;
}

export const DATA_REGISTRY_ASSET_MINT_OFFSET = 9;
export const DATA_REGISTRY_AUTHORITY_OFFSET = 41;
export const DATA_REGISTRY_DELEGATE_OFFSET = 73;

/**
* Retrieves all data accounts associated with a specific asset mint.
* Retrieves data registry account associated with a specific asset mint.
* @param assetMint - The string representation of the asset mint.
* @returns A promise resolving to an array of {@link DataAccount}, or `undefined` if it doesn't exist.
* @returns A promise resolving to the fetched data registry account, or `undefined` if it doesn't exist.
*/
export async function getDataAccounts(assetMint: string, provider: AnchorProvider): Promise<DataAccount[] | undefined> {
export async function getDataRegistryAccountsWithFilter(
filter: DataRegistryFilter,
provider: AnchorProvider
): Promise<DataRegistryAccount[] | undefined> {
const { assetMint, authority, delegate } = filter;
const dataRegistryProgram = getDataRegistryProgram(provider);
const dataRegistryPda = getDataRegistryPda(assetMint);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
filters.push({ memcmp: { offset: DATA_REGISTRY_ASSET_MINT_OFFSET, bytes: new PublicKey(assetMint).toBase58() } });
}
if (authority) {
filters.push({ memcmp: { offset: DATA_REGISTRY_AUTHORITY_OFFSET, bytes: new PublicKey(authority).toBase58() } });
}
if (delegate) {
filters.push({ memcmp: { offset: DATA_REGISTRY_DELEGATE_OFFSET, bytes: new PublicKey(delegate).toBase58() } });
}
const dataAccounts = await provider.connection.getProgramAccounts(dataRegistryProgram.programId, {
filters:
[{ memcmp: { offset: 9, bytes: dataRegistryPda.toBase58() } }],
filters,
});
return dataAccounts.map(account => dataRegistryProgram.coder.accounts.decode("DataAccount", account.account.data));
return dataAccounts.map(account => dataRegistryProgram.coder.accounts.decode("DataRegistryAccount", account.account.data));
}

export interface DataAccountFilter {
assetMint?: string;
registry?: string;
type?: string;
}

export const DATA_ACCOUNT_REGISTRY_OFFSET = 9;
export const DATA_ACCOUNT_TYPE_OFFSET = 41;

/**
* Retrieves all data accounts associated with a specific asset mint and owner.
* @param assetMint - The string representation of the asset mint.
*/
export async function getDataAccountsWithFilter(filter: DataAccountFilter, provider: AnchorProvider): Promise<DataAccount[] | undefined> {
const { assetMint, registry, type } = filter;
const dataRegistryProgram = getDataRegistryProgram(provider);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
const dataRegistryPda = getDataRegistryPda(assetMint);
filters.push({ memcmp: { offset: DATA_ACCOUNT_REGISTRY_OFFSET, bytes: dataRegistryPda.toBase58() } });
}
if (registry) {
filters.push({ memcmp: { offset: DATA_ACCOUNT_REGISTRY_OFFSET, bytes: new PublicKey(registry).toBase58() } });
}
if (type) {
filters.push({ memcmp: { offset: DATA_ACCOUNT_TYPE_OFFSET, bytes: new PublicKey(type).toBase58() } });
}
const dataAccounts = await provider.connection.getProgramAccounts(dataRegistryProgram.programId, {
filters,
});
return dataAccounts.map(account => dataRegistryProgram.coder.accounts.decode("DataAccount", account.account.data));
}
83 changes: 82 additions & 1 deletion clients/rwa-token-sdk/src/identity-registry/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getIdentityRegistryPda,
getIdentityRegistryProgram,
} from "./utils";
import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js";

/**
* Retrieves identity registry account associated with a specific asset mint.
Expand All @@ -23,8 +24,47 @@ export async function getIdentityRegistryAccount(
.catch(() => undefined);
}

export interface IdentityRegistryFilter {
assetMint?: string;
authority?: string;
delegate?: string;
}

export const IDENTITY_REGISTRY_ASSET_MINT_OFFSET = 9;
export const IDENTITY_REGISTRY_AUTHORITY_OFFSET = 41;
export const IDENTITY_REGISTRY_DELEGATE_OFFSET = 73;

/**
* Retrieves all identity accounts associated with a specific asset mint and owner.
* Retrieves identity registry account associated with a specific asset mint.
* @param assetMint - The string representation of the asset mint.
* @returns A promise resolving to {@link IdentityRegistryAccount}, or `undefined` if it doesn't exist.
*/
export async function getIdentityRegistryAccountsWithFilter(
filter: IdentityRegistryFilter,
provider: AnchorProvider
): Promise<IdentityRegistryAccount[] | undefined> {
const { assetMint, authority, delegate } = filter;
const identityRegistryProgram = getIdentityRegistryProgram(provider);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
filters.push({ memcmp: { offset: IDENTITY_REGISTRY_ASSET_MINT_OFFSET, bytes: new PublicKey(assetMint).toBase58() } });
}
if (authority) {
filters.push({ memcmp: { offset: IDENTITY_REGISTRY_AUTHORITY_OFFSET, bytes: new PublicKey(authority).toBase58() } });
}
if (delegate) {
filters.push({ memcmp: { offset: IDENTITY_REGISTRY_DELEGATE_OFFSET, bytes: new PublicKey(delegate).toBase58() } });
}
const identityAccounts = await provider.connection.getProgramAccounts(identityRegistryProgram.programId, {
filters,
});
return identityAccounts.map((account) =>
identityRegistryProgram.coder.accounts.decode("IdentityRegistryAccount", account.account.data)
);
}

/**
* Retrieves a identity account associated with a specific asset mint and owner.
* @param assetMint - The string representation of the asset mint.
* @param owner - The string representation of the asset owner.
* @returns A promise resolving to the {@link IdentityAccount}, or `undefined` if it doesn't exist.
Expand All @@ -41,3 +81,44 @@ export async function getIdentityAccount(
.then((account) => account)
.catch(() => undefined);
}

export interface IdentityAccountFilter {
assetMint?: string;
registry?: string;
owner?: string;
}

export const IDENTITY_ACCOUNT_REGISTRY_OFFSET = 9;
export const IDENTITY_ACCOUNT_OWNER_OFFSET = 41;

/**
* Retrieves all identity accounts associated with a specific asset mint and owner.
* @param assetMint - The string representation of the asset mint.
* @param owner - The string representation of the asset owner.
* @returns A promise resolving to the {@link IdentityAccount}, or `undefined` if it doesn't exist.
*/
export async function getIdentityAccountsWithFilter(
filter: IdentityAccountFilter,
provider: AnchorProvider
): Promise<IdentityAccount[] | undefined> {
const { assetMint, registry, owner } = filter;
const identityRegistryProgram = getIdentityRegistryProgram(provider);
const filters: GetProgramAccountsFilter[] = [];
if (assetMint) {
const identityRegistryPda = getIdentityRegistryPda(assetMint);
filters.push({ memcmp: { offset: IDENTITY_ACCOUNT_REGISTRY_OFFSET, bytes: identityRegistryPda.toBase58() } });
}
if (registry) {
filters.push({ memcmp: { offset: IDENTITY_ACCOUNT_REGISTRY_OFFSET, bytes: new PublicKey(registry).toBase58() } });
}
if (owner) {
filters.push({ memcmp: { offset: IDENTITY_ACCOUNT_OWNER_OFFSET, bytes: new PublicKey(owner).toBase58() } });
}
const identityAccounts = await provider.connection.getProgramAccounts(identityRegistryProgram.programId, {
filters,
});
return identityAccounts.map((account) =>
identityRegistryProgram.coder.accounts.decode("IdentityAccount", account.account.data)
);
}

Loading

0 comments on commit a532241

Please sign in to comment.