Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78bae497ba | ||
|
|
3e425bf8e6 | ||
|
|
4dca5b21a6 | ||
|
|
42c79e93dc | ||
|
|
2951b5533c | ||
|
|
fe8751eeae | ||
|
|
a0cd47ec35 | ||
|
|
3902e7aba4 |
@@ -1,5 +1,12 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
"./express": {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.7.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#128](https://github.com/thirdweb-dev/js/pull/128) [`4dca5b2`](https://github.com/thirdweb-dev/js/commit/4dca5b21a66fe8ff4c4b24663e1b9ad6c446b7e2) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - Add new documentation for detectable features
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 0.7.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.7.12",
|
||||
"version": "0.7.13",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -70,13 +70,13 @@ export async function detectExtensions(options: any) {
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -115,13 +115,13 @@ const NETWORK_INFO_HOOKS = ["useChainId", "useNetwork", "useNetworkMismatch"];
|
||||
|
||||
const CUSTOM_CONTRACT_HOOKS = [
|
||||
"useContract",
|
||||
"useContractData",
|
||||
"useContractRead",
|
||||
"useContractWrite",
|
||||
"useAllContractEvents",
|
||||
"useContractEvents",
|
||||
"useContractType",
|
||||
"useContractPublishMetadata",
|
||||
"useContractMetadata",
|
||||
"useContractCall",
|
||||
];
|
||||
|
||||
const CONTRACT_SETTINGS_HOOKS = [
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#131](https://github.com/thirdweb-dev/js/pull/131) [`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix editing releases from the dashboard
|
||||
|
||||
- [#124](https://github.com/thirdweb-dev/js/pull/124) [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add feature detection for Ownable
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,7 +20,7 @@
|
||||
"build": "tsc && preconstruct build",
|
||||
"test:all": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000 --parallel './test/**/*.test.ts'",
|
||||
"test": "make test",
|
||||
"test:single": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000 --"
|
||||
"test:single": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
} from "./erc1155-features";
|
||||
import {
|
||||
FEATURE_METADATA,
|
||||
FEATURE_OWNER,
|
||||
FEATURE_PERMISSIONS,
|
||||
FEATURE_PLATFORM_FEE,
|
||||
FEATURE_PRIMARY_SALE,
|
||||
@@ -74,7 +75,8 @@ export type Feature =
|
||||
| typeof FEATURE_PLATFORM_FEE
|
||||
| typeof FEATURE_PRIMARY_SALE
|
||||
| typeof FEATURE_PERMISSIONS
|
||||
| typeof FEATURE_METADATA;
|
||||
| typeof FEATURE_METADATA
|
||||
| typeof FEATURE_OWNER;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -100,4 +102,5 @@ export const SUPPORTED_FEATURES: Record<string, Feature> = {
|
||||
[FEATURE_PRIMARY_SALE.name]: FEATURE_PRIMARY_SALE,
|
||||
[FEATURE_PERMISSIONS.name]: FEATURE_PERMISSIONS,
|
||||
[FEATURE_METADATA.name]: FEATURE_METADATA,
|
||||
[FEATURE_OWNER.name]: FEATURE_OWNER,
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import IPermissionsAbi from "@thirdweb-dev/contracts-js/dist/abis/IPermissions.j
|
||||
import IThirdwebPlatformFeeAbi from "@thirdweb-dev/contracts-js/dist/abis/IPlatformFee.json";
|
||||
import IThirdwebPrimarySaleAbi from "@thirdweb-dev/contracts-js/dist/abis/IPrimarySale.json";
|
||||
import IThirdwebRoyaltyAbi from "@thirdweb-dev/contracts-js/dist/abis/IRoyalty.json";
|
||||
import IOwnableAbi from "@thirdweb-dev/contracts-js/dist/abis/Ownable.json";
|
||||
|
||||
export const FEATURE_ROYALTY = {
|
||||
name: "Royalty",
|
||||
@@ -58,3 +59,14 @@ export const FEATURE_METADATA = {
|
||||
abis: [IContractMetadataAbi],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
export const FEATURE_OWNER = {
|
||||
name: "Ownable",
|
||||
namespace: "owner",
|
||||
docLinks: {
|
||||
sdk: "sdk.owner",
|
||||
contracts: "Ownable",
|
||||
},
|
||||
abis: [IOwnableAbi],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -2,7 +2,18 @@ import { ALL_ROLES, assertEnabled, detectContractFeature } from "../common";
|
||||
import { FEATURE_TOKEN } from "../constants/erc20-features";
|
||||
import { FEATURE_NFT } from "../constants/erc721-features";
|
||||
import { FEATURE_EDITION } from "../constants/erc1155-features";
|
||||
import { ContractEncoder, NetworkOrSignerOrProvider } from "../core";
|
||||
import {
|
||||
FEATURE_OWNER,
|
||||
FEATURE_PERMISSIONS,
|
||||
FEATURE_PLATFORM_FEE,
|
||||
FEATURE_PRIMARY_SALE,
|
||||
FEATURE_ROYALTY,
|
||||
} from "../constants/thirdweb-features";
|
||||
import {
|
||||
ContractEncoder,
|
||||
ContractOwner,
|
||||
NetworkOrSignerOrProvider,
|
||||
} from "../core";
|
||||
import { ContractEvents } from "../core/classes/contract-events";
|
||||
import { ContractInterceptor } from "../core/classes/contract-interceptor";
|
||||
import { ContractMetadata } from "../core/classes/contract-metadata";
|
||||
@@ -25,6 +36,7 @@ import type {
|
||||
IPlatformFee,
|
||||
IPrimarySale,
|
||||
IRoyalty,
|
||||
Ownable,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import { IStorage } from "@thirdweb-dev/storage";
|
||||
import { BaseContract, CallOverrides, ContractInterface } from "ethers";
|
||||
@@ -44,10 +56,10 @@ import { BaseContract, CallOverrides, ContractInterface } from "ethers";
|
||||
* await contract.call("myCustomFunction", param1, param2);
|
||||
*
|
||||
* // if your contract follows the ERC721 standard, contract.nft will be present
|
||||
* const allNFTs = await contract.nft.query.all()
|
||||
* const allNFTs = await contract.erc721.query.all()
|
||||
*
|
||||
* // if your contract extends IMintableERC721, contract.nft.mint() will be available
|
||||
* const tx = await contract.nft.mint({
|
||||
* const tx = await contract.erc721.mint({
|
||||
* name: "Cool NFT",
|
||||
* image: readFileSync("some_image.png"),
|
||||
* });
|
||||
@@ -60,7 +72,6 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
{
|
||||
private contractWrapper;
|
||||
private storage;
|
||||
private options;
|
||||
|
||||
// utilities
|
||||
public events: ContractEvents<TContract>;
|
||||
@@ -69,37 +80,62 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
public estimator: GasCostEstimator<TContract>;
|
||||
public publishedMetadata: ContractPublishedMetadata<TContract>;
|
||||
public abi: ContractInterface;
|
||||
|
||||
// features
|
||||
public metadata: ContractMetadata<BaseContract, any>;
|
||||
public royalties: ContractRoyalty<IRoyalty, any> | undefined;
|
||||
public roles: ContractRoles<IPermissions, any> | undefined;
|
||||
public sales: ContractPrimarySale<IPrimarySale> | undefined;
|
||||
public platformFees: ContractPlatformFee<IPlatformFee> | undefined;
|
||||
|
||||
private token: Erc20 | undefined;
|
||||
private nft: Erc721 | undefined;
|
||||
private edition: Erc1155 | undefined;
|
||||
/**
|
||||
* Handle royalties
|
||||
*/
|
||||
get royalties(): ContractRoyalty<IRoyalty, any> {
|
||||
return assertEnabled(this.detectRoyalties(), FEATURE_ROYALTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle permissions
|
||||
*/
|
||||
get roles(): ContractRoles<IPermissions, any> {
|
||||
return assertEnabled(this.detectRoles(), FEATURE_PERMISSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle primary sales
|
||||
*/
|
||||
get sales(): ContractPrimarySale<IPrimarySale> {
|
||||
return assertEnabled(this.detectPrimarySales(), FEATURE_PRIMARY_SALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle platform fees
|
||||
*/
|
||||
get platformFees(): ContractPlatformFee<IPlatformFee> {
|
||||
return assertEnabled(this.detectPlatformFees(), FEATURE_PLATFORM_FEE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and get the owner of the contract
|
||||
*/
|
||||
get owner(): ContractOwner<Ownable> {
|
||||
return assertEnabled(this.detectOwnable(), FEATURE_OWNER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-detects ERC20 standard functions.
|
||||
*/
|
||||
get erc20(): Erc20 {
|
||||
return assertEnabled(this.token, FEATURE_TOKEN);
|
||||
return assertEnabled(this.detectErc20(), FEATURE_TOKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-detects ERC721 standard functions.
|
||||
*/
|
||||
get erc721(): Erc721 {
|
||||
return assertEnabled(this.nft, FEATURE_NFT);
|
||||
return assertEnabled(this.detectErc721(), FEATURE_NFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-detects ERC1155 standard functions.
|
||||
*/
|
||||
get erc1155(): Erc1155 {
|
||||
return assertEnabled(this.edition, FEATURE_EDITION);
|
||||
return assertEnabled(this.detectErc1155(), FEATURE_EDITION);
|
||||
}
|
||||
|
||||
constructor(
|
||||
@@ -115,7 +151,6 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
options,
|
||||
),
|
||||
) {
|
||||
this.options = options;
|
||||
this.storage = storage;
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.abi = abi;
|
||||
@@ -134,16 +169,6 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
CustomContractSchema,
|
||||
this.storage,
|
||||
);
|
||||
|
||||
// feature detection
|
||||
this.royalties = this.detectRoyalties();
|
||||
this.roles = this.detectRoles();
|
||||
this.sales = this.detectPrimarySales();
|
||||
this.platformFees = this.detectPlatformFees();
|
||||
|
||||
this.token = this.detectErc20();
|
||||
this.nft = this.detectErc721();
|
||||
this.edition = this.detectErc1155();
|
||||
}
|
||||
|
||||
onNetworkUpdated(network: NetworkOrSignerOrProvider): void {
|
||||
@@ -247,4 +272,11 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectOwnable() {
|
||||
if (detectContractFeature<Ownable>(this.contractWrapper, "Ownable")) {
|
||||
return new ContractOwner(this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
detectContractFeature,
|
||||
ExtensionNotImplementedError,
|
||||
fetchContractMetadataFromAddress,
|
||||
hasFunction,
|
||||
} from "../../common";
|
||||
@@ -141,7 +142,7 @@ export class ContractMetadata<
|
||||
z.output<TSchema["output"]>
|
||||
>;
|
||||
} else {
|
||||
throw new Error("Contract does not support updating contract metadata");
|
||||
throw new ExtensionNotImplementedError(FEATURE_METADATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { FEATURE_OWNER } from "../../constants/thirdweb-features";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResult } from "../types";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import type { Ownable } from "@thirdweb-dev/contracts-js";
|
||||
|
||||
/**
|
||||
* Encodes and decodes Contract functions
|
||||
* @public
|
||||
*/
|
||||
export class ContractOwner<TContract extends Ownable>
|
||||
implements DetectableFeature
|
||||
{
|
||||
featureName = FEATURE_OWNER.name;
|
||||
private contractWrapper;
|
||||
|
||||
constructor(contractWrapper: ContractWrapper<TContract>) {
|
||||
this.contractWrapper = contractWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current owner of the contract
|
||||
* @returns the owner address
|
||||
*/
|
||||
public async get(): Promise<string> {
|
||||
return this.contractWrapper.readContract.owner();
|
||||
}
|
||||
|
||||
/**
|
||||
* set tje new owner of the contract
|
||||
*/
|
||||
public async set(address: string): Promise<TransactionResult> {
|
||||
return {
|
||||
receipt: await this.contractWrapper.sendTransaction("setOwner", [
|
||||
address,
|
||||
]),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,10 @@ export class ContractPublisher extends RPCConnectionHandler {
|
||||
|
||||
const fullMetadata = FullPublishMetadataSchemaInput.parse({
|
||||
...extraMetadata,
|
||||
...predeployMetadata,
|
||||
metadataUri: predeployMetadata.metadataUri,
|
||||
bytecodeUri: predeployMetadata.bytecodeUri,
|
||||
name: predeployMetadata.name,
|
||||
analytics: predeployMetadata.analytics,
|
||||
publisher,
|
||||
});
|
||||
const fullMetadataUri = await this.storage.uploadMetadata(fullMetadata);
|
||||
|
||||
@@ -41,3 +41,4 @@ export * from "./contract-events";
|
||||
export * from "./contract-interceptor";
|
||||
export * from "./contract-platform-fee";
|
||||
export * from "./contract-published-metadata";
|
||||
export * from "./contract-owner";
|
||||
|
||||
@@ -32,7 +32,7 @@ describe("Custom Contracts", async () => {
|
||||
let sdk: ThirdwebSDK;
|
||||
let simpleContractUri: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
before(async () => {
|
||||
[adminWallet, samWallet, bobWallet] = signers;
|
||||
sdk = new ThirdwebSDK(adminWallet);
|
||||
simpleContractUri =
|
||||
@@ -227,7 +227,14 @@ describe("Custom Contracts", async () => {
|
||||
const c = await sdk.getContractFromAbi("", VoteERC20__factory.abi);
|
||||
invariant(c, "Contract undefined");
|
||||
invariant(c.metadata, "Metadata undefined");
|
||||
expect(c.roles).to.eq(undefined);
|
||||
try {
|
||||
c.roles.get("admin");
|
||||
} catch (e) {
|
||||
expectError(
|
||||
e,
|
||||
"contract does not implement the 'PermissionsEnumerable' Extension",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("should detect feature: erc20", async () => {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @thirdweb-dev/solana
|
||||
|
||||
## 0.2.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#129](https://github.com/thirdweb-dev/js/pull/129) [`a0cd47e`](https://github.com/thirdweb-dev/js/commit/a0cd47ec3596d23f974e58d668ce02e34bfe3528) Thanks [@jnsdls](https://github.com/jnsdls)! - explicitly export the program schemata from the package
|
||||
|
||||
- [#132](https://github.com/thirdweb-dev/js/pull/132) [`3e425bf`](https://github.com/thirdweb-dev/js/commit/3e425bf8e65db99fc4043ea5d2bc4b863eabce52) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Get account type for a given address
|
||||
|
||||
- [#130](https://github.com/thirdweb-dev/js/pull/130) [`2951b55`](https://github.com/thirdweb-dev/js/commit/2951b5533c13d1d7633c491df7e5710b0a6608dd) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - New return type for `registry.getAccountsForWallet`
|
||||
|
||||
## 0.2.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/solana",
|
||||
"version": "0.2.9",
|
||||
"version": "0.2.10",
|
||||
"description": "thirdweb Solana SDK",
|
||||
"main": "dist/thirdweb-dev-solana.cjs.js",
|
||||
"module": "dist/thirdweb-dev-solana.esm.js",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { WalletAccount } from "../types/common";
|
||||
import {
|
||||
CandyMachine,
|
||||
Metadata,
|
||||
Metaplex,
|
||||
TokenMetadataProgram,
|
||||
@@ -6,18 +8,6 @@ import {
|
||||
import { TokenStandard } from "@metaplex-foundation/mpl-token-metadata";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
export type WalletAccount = {
|
||||
type: "nft-collection" | "nft-drop" | "token";
|
||||
address: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type RelevantWalletAccounts = {
|
||||
tokens: string[];
|
||||
nftCollections: string[];
|
||||
drops: string[];
|
||||
};
|
||||
|
||||
export class Registry {
|
||||
private metaplex: Metaplex;
|
||||
|
||||
@@ -25,7 +15,40 @@ export class Registry {
|
||||
this.metaplex = metaplex;
|
||||
}
|
||||
|
||||
public async getAccountsForWallet(walletAddress: string) {
|
||||
public async getAccountType(address: string) {
|
||||
try {
|
||||
const metadata = await this.metaplex
|
||||
.nfts()
|
||||
.findByMint({ mintAddress: new PublicKey(address) })
|
||||
.run();
|
||||
if (metadata) {
|
||||
if (metadata.collectionDetails) {
|
||||
return "nft-collection";
|
||||
} else {
|
||||
if (metadata.tokenStandard === TokenStandard.Fungible) {
|
||||
return "token";
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
try {
|
||||
const candyMachine = await this.metaplex
|
||||
.candyMachines()
|
||||
.findByAddress({ address: new PublicKey(address) })
|
||||
.run();
|
||||
if (candyMachine) {
|
||||
return "nft-drop";
|
||||
}
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public async getAccountsForWallet(
|
||||
walletAddress: string,
|
||||
): Promise<WalletAccount[]> {
|
||||
const pubKeys = await this.getMetadataAddressesForWallet(walletAddress);
|
||||
const metadatas = await this.metaplex
|
||||
.nfts()
|
||||
@@ -40,45 +63,53 @@ export class Registry {
|
||||
})
|
||||
.run();
|
||||
|
||||
return metadatas.reduce(
|
||||
(accounts, mintMetadata) => {
|
||||
return metadatas
|
||||
.map((mintMetadata) => {
|
||||
const meta = mintMetadata as Metadata;
|
||||
if (!meta) {
|
||||
return accounts;
|
||||
return undefined;
|
||||
}
|
||||
if (meta?.collectionDetails) {
|
||||
// check if it's part of a candy machine
|
||||
const drop = candyMachines.find(
|
||||
(candyMachine) =>
|
||||
candyMachine.collectionMintAddress?.toBase58() ===
|
||||
meta.mintAddress.toBase58(),
|
||||
);
|
||||
const drop = this.getDropForCollection(candyMachines, meta);
|
||||
if (drop) {
|
||||
accounts.drops.push(drop.address.toBase58());
|
||||
return {
|
||||
type: "nft-drop",
|
||||
address: drop.address.toBase58(),
|
||||
name: meta.name,
|
||||
};
|
||||
} else {
|
||||
accounts.nftCollections.push(meta.mintAddress.toBase58());
|
||||
return {
|
||||
type: "nft-collection",
|
||||
address: meta.mintAddress.toBase58(),
|
||||
name: meta.name,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (meta.tokenStandard === TokenStandard.Fungible) {
|
||||
accounts.tokens.push(meta.mintAddress.toBase58());
|
||||
return {
|
||||
type: "token",
|
||||
address: meta.mintAddress.toBase58(),
|
||||
name: meta.name,
|
||||
};
|
||||
}
|
||||
}
|
||||
return accounts;
|
||||
},
|
||||
{
|
||||
tokens: [],
|
||||
nftCollections: [],
|
||||
drops: [],
|
||||
} as RelevantWalletAccounts,
|
||||
})
|
||||
.filter((account) => account !== undefined) as WalletAccount[];
|
||||
}
|
||||
|
||||
private getDropForCollection(candyMachines: CandyMachine[], meta: Metadata) {
|
||||
return candyMachines.find(
|
||||
(candyMachine) =>
|
||||
candyMachine.collectionMintAddress?.toBase58() ===
|
||||
meta.mintAddress.toBase58(),
|
||||
);
|
||||
}
|
||||
|
||||
public async getMetadataAddressesForWallet(walletAddress: string) {
|
||||
const mints = await TokenMetadataProgram.metadataV1Accounts(this.metaplex)
|
||||
return await TokenMetadataProgram.metadataV1Accounts(this.metaplex)
|
||||
.selectMint()
|
||||
.whereCreator(1, new PublicKey(walletAddress))
|
||||
.getDataAsPublicKeys();
|
||||
|
||||
return mints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,3 +6,10 @@ export * from "./classes/user-wallet";
|
||||
export * from "./contracts/nft-collection";
|
||||
// sdk
|
||||
export * from "./sdk";
|
||||
|
||||
//schema for dashboard use
|
||||
export {
|
||||
TokenMetadataInputSchema,
|
||||
NFTCollectionMetadataInputSchema,
|
||||
} from "./types/contracts";
|
||||
export { NFTDropContractSchema } from "./types/contracts/nft-drop";
|
||||
|
||||
@@ -69,3 +69,9 @@ export type TransactionResult = {
|
||||
};
|
||||
|
||||
export type WalletSigner = Signer | WalletAdapter;
|
||||
export type AccountType = "nft-collection" | "nft-drop" | "token";
|
||||
export type WalletAccount = {
|
||||
type: AccountType;
|
||||
address: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Amman } from "@metaplex-foundation/amman-client";
|
||||
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { Connection, Keypair } from "@solana/web3.js";
|
||||
|
||||
const createTestSDK = async (
|
||||
export const createTestSDK = async (
|
||||
solsToAirdrop: number = 100,
|
||||
): Promise<ThirdwebSDK> => {
|
||||
const connection = new Connection("http://localhost:8899", "confirmed");
|
||||
|
||||
@@ -1,34 +1,56 @@
|
||||
import { sdk } from "./before-setup";
|
||||
import { ThirdwebSDK } from "../src/index";
|
||||
import { createTestSDK } from "./before-setup";
|
||||
import { expect } from "chai";
|
||||
|
||||
describe("Registry", async () => {
|
||||
let nftColl: string;
|
||||
let nftDrop: string;
|
||||
let token: string;
|
||||
let freshSDK: ThirdwebSDK;
|
||||
|
||||
before(async () => {
|
||||
await sdk.deployer.createNftCollection({
|
||||
name: "Test Collection",
|
||||
freshSDK = await createTestSDK();
|
||||
nftColl = await freshSDK.deployer.createNftCollection({
|
||||
name: "Reg Test Collection",
|
||||
description: "Test Description",
|
||||
symbol: "TC",
|
||||
});
|
||||
await sdk.deployer.createToken({
|
||||
name: "Test Token",
|
||||
token = await freshSDK.deployer.createToken({
|
||||
name: "Reg Test Token",
|
||||
initialSupply: 100,
|
||||
});
|
||||
await sdk.deployer.createNftDrop({
|
||||
name: "Test Drop",
|
||||
nftDrop = await freshSDK.deployer.createNftDrop({
|
||||
name: "Reg Test Drop",
|
||||
});
|
||||
});
|
||||
|
||||
it("should fetch accounts grouped by type", async () => {
|
||||
const t = await sdk.registry.getAccountsForWallet(
|
||||
sdk.wallet.getAddress() || "",
|
||||
const t = await freshSDK.registry.getAccountsForWallet(
|
||||
freshSDK.wallet.getAddress() || "",
|
||||
);
|
||||
const colls = t.nftCollections[0];
|
||||
const nftCollection = await sdk.getNFTCollection(colls);
|
||||
expect((await nftCollection.getMetadata()).name).to.eq("Test Collection");
|
||||
t.forEach((account) => {
|
||||
switch (account.type) {
|
||||
case "nft-collection":
|
||||
expect(account.name).to.equal("Reg Test Collection");
|
||||
expect(account.address).to.equal(nftColl);
|
||||
break;
|
||||
case "nft-drop":
|
||||
expect(account.name).to.equal("Reg Test Drop");
|
||||
expect(account.address).to.equal(nftDrop);
|
||||
break;
|
||||
case "token":
|
||||
expect(account.name).to.equal("Reg Test Token");
|
||||
expect(account.address).to.equal(token);
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const token = await sdk.getToken(t.tokens[0]);
|
||||
expect((await token.getMetadata()).name).to.eq("Test Token");
|
||||
|
||||
const drop = await sdk.getNFTDrop(t.drops[0]);
|
||||
expect((await drop.getMetadata()).name).to.eq("Test Drop");
|
||||
it("should resolve account addresses", async () => {
|
||||
expect(await freshSDK.registry.getAccountType(nftColl)).to.eq(
|
||||
"nft-collection",
|
||||
);
|
||||
expect(await freshSDK.registry.getAccountType(nftDrop)).to.eq("nft-drop");
|
||||
expect(await freshSDK.registry.getAccountType(token)).to.eq("token");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user