Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
@monaxlabs/aspen-sdk
Advanced tools
This is the Aspen Javascript SDK the Aspen publishing and trading platform (https://aspenft.io/).
This is the Aspen Javascript SDK the Aspen publishing and trading platform (https://aspenft.io/).
Use this library to publish NFT collections and mint directly from your projects site or airdrop from backend services. Crypto and Fiat supported.
The SDK allows you to interact with our APIs and our Aspen-published smart contracts. Allowing you to integrate server-side definition and publishing of NFT contracts and configure NFT drops as well as client-side integration with the Aspen smart contracts to mint/claim NFTs for ERC721 and ERC1155 contracts. Features include:
tokenId
allocation for ERC721The SDK is packaged ECMAScript modules consumable by browsers and recent versions of NodeJS (versions >= 16).
Aspen and the Aspen SDK currently support the Ethereum based networks:
And their respective test networks
From your Javascript project root:
# pnpm
pnpm add @monaxlabs/aspen-sdk
# yarn
yarn add @monaxlabs/aspen-sdk
# npm
npm install @monaxlabs/aspen-sdk
The Aspen SDK is split into a client-side smart contract library and API clients requiring secrets that should only be run from secure backend services.
@monaxlabs/aspen-sdk/dist/contracts
@monaxlabs/aspen-sdk/dist/apis
We also package a TheGraph subgraph at @monaxlabs/aspen-sdk/dist/claimgraph
to provide tracking of claims during a live drop.
Our publishing and gating APIs can be authenticated using a basic auth username and password.
To do so you must obtain credentials (please use this request form) and include them in an JSON object with this schema:
{
"production": {
"publishing": {
"baseUrl": "https://publishing.aspenft.io",
"name": "username",
"password": "password"
},
"gating": {
"baseUrl": "https://identity.aspenft.io",
"name": "username",
"password": "password"
}
}
}
Then you can authenticate (once, globally): with:
import { authenticateAll, authenticateAllFromFile } from '@monaxlabs/aspen-sdk/dist/apis';
const creds = {
production: {
publishing: {
baseUrl: 'https://publishing.aspenft.io',
name: 'username',
password: 'password',
},
gating: {
baseUrl: 'https://identity.aspenft.io',
name: 'username',
password: 'password',
},
},
};
const environment = 'production';
async function authenticate(): Promise<void> {
await authenticateAll(environment, creds);
// Or via environment variables with fallback to file storage:
await authenticateAllFromFile(environment, 'credentials.json', 'CREDENTIALS_ENV_VAR_NAME');
}
Interacting with the Aspen suite of smart contracts is handled via the CollectionContract
class. In order to use it pass an ethers.js compatible Provider
.
The CollectionContract
is able to dynamically introspect contracts on live networks and determine their feature suite. It abstracts over both ERC721 and ERC1155 contracts.
You can obtain one via a variety of browser wallet plugins, most commonly MetaMask or using some test helpers and a local private key.
For testing and integration purposes you can provide Ethereum web3 JSON-RPC URLs, and local private keys to our getProvider
function. The provider config is defined by:
{
"providerUrls": {
"Mumbai": "",
"Mainnet": "",
"Goerli": "",
"Polygon": ""
},
"privateKeys": {
"Mumbai": "",
"Mainnet": "",
"Goerli": "",
"Polygon": ""
}
}
CollectionContract
You can establish a connection with a contract by passing a provider and the contract address to the CollectionContract
constructor. When contract.load()
as called the contract is queried using some introspection interfaces to discover which Aspen features are supported. Features are individual units of functionality that are semantically versioned.
import { CollectionContract } from '@monaxlabs/aspen-sdk/dist/apis';
async function getCollectionContract(): Promise<CollectionContract> {
// Use a local testing account to obtain an ethers.js Provider
const network = 'Mumbai';
const providerConfig = await getProviderConfig('providers.json');
const provider = await getProvider(network, providerConfig);
// Generate local signers
const userSigners = generateAccounts(numAccounts, { mnemonic: demoMnemonic, provider });
// Obtain a CollectionContract - introspects contract and loads available smart contract features
const contract = await CollectionContract.from(provider, collectionAddress);
}
As well as discovering the specific features implemented the token standard implemented by the contract is also established which is one of:
There are five Aspen NFT contract feature families supported by the Aspen SDK:
Each of these features comprises a set of utility methods that interact with contracts. Where possible we maintain backward-compatibility of certain feature functions across previous versions of our smart contracts. As we develop and improve our contracts newer collections may have additional functionality.
You can interact with features by accessing the corresponding feature property on the CollectionContract
. Some examples:
import { NATIVE_TOKEN } from '@monaxlabs/aspen-sdk/dist/contract';
async function main(): Promise<void> {
// Assume that a CollectionContract has be instantiated and loaded
const contract = await CollectionContract.from(provider, collectionAddress);
// Access the conditions feature and determine if it is supported
const isSupported: boolean = contract.conditions.supported;
// If the collection is an ERC721 then tokenId should be null (the tokenId will be dynamically allocated on calim),
// otherwise for ERC1155 it must be specified
const tokenId = 0;
if (isSupported) {
// Get the current claim conditions (needed in order to claim).
const conditions = await contract.conditions.getState(receiver, tokenId);
if (conditions.claimState !== 'ok') {
throw new Error(`Not okay to mint based on user restrictions and claim phase`);
}
// Use the metadata feature to access the tokenURI
const tokenUri = await contract.metadata.getTokenUri(tokenId);
// Accept agreement terms (if/when enabled on the contract) by passing a signer for the acceptee
await contract.agreements.acceptTerms(signer);
// Claim (mint) a token be calling the NFT contract (
contract.claims.claim(
// An ether.js signer
signer,
{
// The receipient of the token
receiver,
// The tokenId if the contract is an ERC1155 null/ignored otherwise
tokenId,
// The quantity of tokens to claim if ERC721 then a run of tokenIds will be issued, if ERC1155 then the recipients
// balance will increase by quantity
quantity,
// The remaining fields must match those specified by the conditions in the active claim phase
// An ERC20 token contract address if payment is in ERC20 or the constant NATIVE_TOKEN
// (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) to indicate payment in native eth/matic
currency: conditions.currency,
// The price of the token
pricePerToken: conditions.pricePerToken,
// allowlist proofs
proofs: conditions.allowlist.proofs,
proofMaxQuantityPerTransaction: conditions.allowlist.proofMaxQuantityPerTransaction,
},
);
}
}
CollectionContract
functionsactiveClaimConditions
and userClaimConditions
and computes whether the current user-account is able to claim.Our NFT contracts support a linear (one-at-a-time) sequence of claim phases. Each phase can have its own set of rules for how the contract will mint tokens. Each phase has a defined start time and will last until the next consecutive phase begins if a next phase is defined. The phase is defined by a ClaimCondition
which contains (amongst other things):
You can see an example phases definition here.
In order to know whether it is possible for a particular (Ethereum) account to claim you must know the active claim condition. In particular, you must know:
NATIVE_TOKEN
or an ERC20 contract address)Here we describe integrating the headline features of the SDK. Namely defining and publishing an NFT drop collection and allowing users to mint from a client-side browser application.
You can see working code examples for the flows listed below in the SDK monorepo examples directory.
Collections can be defined and deployed by our publishing API. The steps are as follows:
Each of these steps is achieved by calling various endpoints on our publishing API. The OpenAPI specs for these APIs are available on NPM at @monaxlabs/spec. Our Typescript APIs are generated from these specs with some additional helpers
Once authenticated as above you can access each of the publishing APIs service objects and call the endpoints statically. The process is:
import {
Chain,
CollectionActionsService,
CollectionInfoService,
CollectionResponse,
CollectionService,
CollectionTokenPhasesService,
} from '@monaxlabs/aspen-sdk/dist/apis/publishing';
import { waitForCompletion } from './waiter';
// For brevity most arguments for each method are elided in the code below, but they are all easily discovered
// by looking at the included types for each method
export async function deployCollection(): Promise<CollectionResponse> {
// We specify the type of NFT contract we want be specifying either 'CedarERC721Drop' or 'CedarERC1155Drop' for
// contracName
const contractName: 'CedarERC721Drop' | 'CedarERC1155Drop' = 'CedarERC721Drop';
// Begin defining the collection, choosing the type of contract desired and other basic metadata and limits
const collection = await CollectionService.postCollection({
requestBody: {
//
contractName,
},
});
// Additional calls are made using the collections pre-deployment GUID identifier
const collectionGuid = collection.guid;
// This call defines a single token, call once for each token (or token class in the case of ERC1155) you wish to define
await TokenService.postToken({});
// Optionally configure royalties
CollectionService.postCollectionRoyaltyrecipients({});
// Optionally define and enable legal terms
const { web2Url } = await CollectionService.postCollectionTerms({ guid: collectionGuid });
await CollectionService.postCollectionTermsEnable({ guid: collectionGuid, status: true });
// Provide collection metadata that will be displayed on marketplaces
await CollectionInfoService.postCollectionInfo({});
// Now the collection is fully staged we can deploy it to chain
// Deploy the collection
await CollectionActionsService.postCollectionDeploy({ guid: collectionGuid });
// This is an async process and we can poll it for the transaction to be confirmed on chain using this helper
await waitForCompletion(CollectionActionsService.getCollectionDeploy, { guid: collectionGuid });
// The collection is now deployed, but no tokens will yet be defined. To do this we call the mint that will upload
// metadata to our CDN and IPFS and then define each tokenId
await CollectionActionsService.postCollectionMint({ guid: collectionGuid });
// Once again we wait for the transactions to be confirmed
await waitForCompletion(CollectionActionsService.getCollectionMint, { guid: collectionGuid });
// Finally we return the collection data stored by the publishing API
return CollectionService.getCollectionById({ guid: collectionGuid });
}
The aim of this integration is to place a 'mint' button on our drop page. The necessary steps for claiming a token using the SDK is given below, but a fully worked up example in React can be found in our SDK examples directory here. Our SDK is agnostic of any Javascript framework you choose to use and should work in the same way within a browser or NodeJS environment.
import { CollectionContract, parse, Address, NATIVE_TOKEN } from '@monaxlabs/aspen-sdk/dist/contracts/address';
import { BigNumberish } from 'ethers';
async function main(contract: CollectionContract): Promise<void> {
const claimingAccount: Address = parse(Address, '0x92380354b9f2334a9c78c0686645db04d52972bc');
// Depending on whether ERC721 or ERC1155
const tokenId: null | BigNumberish = 2;
// Get the active claim phase from the contract
const conditions = await contract.conditions.getState(claimingAccount, tokenId);
if (conditions.claimState !== 'ok') {
throw new Error(`Not okay to mint based on user restrictions and claim phase`);
}
// Finally claim
await contract.claims.claim(
// The signer for the user entitled to claim
signer,
{
conditionId: conditions.activeClaimConditionId
// Usually this is the address of the signer above unless the claimant would like the NFT to be deposited elsewhere
receiver: claimingAccount,
// tokenId if ERC1155, null if ERC721
tokenId,
// Quantity to claim (multiple tokens can be claimed in a single call for both ERC721 and ERC1155)
quantity: BigNumber.from(1),
// price details
currency: conditions.currency,
pricePerToken: conditions.pricePerToken,
// allowlist proofs
proofs: conditions.allowlist.proofs,
proofMaxQuantityPerTransaction: conditions.allowlist.proofMaxQuantityPerTransaction,
}
);
}
Tokens can be issued using the publishing API directly. This skips claim conditions and allows issuing a token based on a fiat payment provider or for dynamics use cases.
import { authenticate, issueToken, PublishingAPI } from '@monaxlabs/aspen-sdk/dist/apis';
async function main(): Promise<void> {
await authenticate(PublishingAPI.OpenAPI, {
baseUrl: PUBLISHING_API_BASEURI,
name: PUBLISHING_API_USERNAME,
password: PUBLISHING_API_PASSWORD,
});
await issueToken(collectionGuid, {
to: wallet,
tokenId: Number.parseInt(tokenId),
});
}
See a complete webhook example here
Please see https://github.com/monax/aspen-sdk for working code examples and their documentation.
FAQs
This is the Aspen Javascript SDK the Aspen publishing and trading platform (https://aspenft.io/).
The npm package @monaxlabs/aspen-sdk receives a total of 11 weekly downloads. As such, @monaxlabs/aspen-sdk popularity was classified as not popular.
We found that @monaxlabs/aspen-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.