Skip to content

art-by-city/sdk

Repository files navigation

Art By City SDK

Requirements

Node 18 LTS

Install

npm i @artbycity/sdk

API

Creating a Client

The client comes with defaults built in to use either arweave.net or, if being served from a permaweb dapp, the current gateway.

import ArtByCity from '@artbycity/sdk'

const abc = new ArtByCity()

You can optionally pass your own instance of the Arweave client.

import ArtByCity from '@artbycity/sdk'
import Arweave from 'arweave'

const arweave = Arweave.init({})
const abc = new ArtByCity(arweave)

You can optionally override the ArtByCity client default configuration. All configuration overrides are optional and have defaults depending on environment.

import ArtByCity, { ArtByCityConfig } from '@artbycity/sdk'
import Arweave from 'arweave'

const arweave = Arweave.init({})
const config: Partial<ArtByCityConfig> = {
  environment: 'development', // 'development' | 'staging' | 'production'
  contracts: {
    usernames: '<local-usernames-contract-txid>',
    curation: {
      ownable: '<local-ownable-curation-contract-src-txid>',
      whitelist: '<local-whitelist-curation-contract-src-txid>',
      collaborative: '<local-collaborative-curation-contract-src-txid>',
      collaborativeWhitelist: 
        '<local-collaborative-whitelist-curation-contract-src-txid>'
    }
  },
  cache: {
    type: 'disabled' // 'memcache' | 'disabled'
  }
}
const abc = new ArtByCity(arweave)

Authenticated Client

Some API interfaces are only available to the client after calling connect() which transforms the ArtByCity client into an AuthenticatedArtByCityClient.

const jwk: JWKInterface = {} /* your arweave wallet JWK */
const authenticated = new ArtByCity().connect(jwk)

Alternatively, in the browser you can call connect() without any arguments to use window.arweaveWallet.

const authenticated = new ArtByCity().connect()

Typically, you'll only use connect() in a chain to method calls that require a wallet as detailed below.

Curations

For curation contracts sources, see ArtByCity Curation Contracts.

Curation State Type Reference

type BaseCurationMetadata = {
  [key: string]: any
}

type BaseCurationState = {
  title: string
  metadata: BaseCurationMetadata
  items: string[]
  hidden: string[]
}

type OwnableState = {
  owner: string
}

type WhitelistState = {
  addressWhitelist: string[]
}

type AccessControlState<Roles extends string | number | symbol> = {
  roles: {
    [role in Roles]: string[]
  }
}

/* Ownable Curation Contract State */
type OwnableCurationState = OwnableState & BaseCurationState

/* Whitelist Curation Contract State */
type WhitelistCurationState = OwnableCurationState & WhitelistState

/* Collaborative Curation Contract State */
type CollaborativeCurationState =
  OwnableCurationState & AccessControlState<'curator'>

/* Collaborative Whitelist Curation Contract State */
type CollaborativeWhitelistCurationState =
  CollaborativeCurationState & WhitelistCurationState

Create a Curation

Creates a curation, returning the curationId (smartweave initialization transaction id). owner and title are required, while everything else is optional. You can set the initial state of the contract through these options.

If description is defined, it will be copied to metadata['description'].

type CurationType =
  | 'ownable'
  | 'whitelist' 
  | 'collaborative'
  | 'collaborative-whitelist'

interface CurationCreationOptions {
  owner: string
  title: string
  description?: string
  topic?: string
  metadata?: BaseCurationMetadata
  items?: []
  hidden?: []
  addressWhitelist?: []
  roles?: {
    curator: []
  }
}

const abc = new ArtByCity()

const owner: string = '<an arweave address>'
const title: string = 'My Curation'
const description: string = 'This is a curation description'
const type: CurationType = 'ownable'
const opts: CurationCreationOptions = {
  owner,
  title,
  description
}

const curationId = await abc.connect().curations.create(type, opts)

Fetch a Curation

Fetch a curation by curationId. This returns the Warp Contract with a union state common to all curation contracts.

In the future, this interface will change.

const abc = new ArtByCity()

const curationId: string = '<curation tx id>'

const curation = abc.curations.get(curationId)
const { cachedValue: { state } } = await curation.readState()

If you know the type of curation, you could provide that to the Warp Contract. In the future, this interface will change.

const curation =
  abc.curations.get<CollaborativeWhitelistCurationState>(curationId)

Query Curations by Creator

Query curations deployed by address. Returns { curations: ArdbTransaction[] }.

Note: if the owner has been transferred or set to a different address than the deployer on initial deployment, the curation will not match this query result. This function is intended to search on creator / initial deployer of curations.

const { curations } = await abc.curations.createdBy(address)

Legacy

The SDK contains a legacy module providing read-only interfaces for consuming legacy Art By City publications and related entities (avatars, profiles, likes, tips, usernames, etc.)

Querying

const abc = new ArtByCity()

const limit: number | 'all' = 'all'
const address: string = '<an arweave address>'

const {
  publications,
  cursor
} = await abc.legacy.queryPublications(limit, address)
const {
  bundles,
  cursor
} = await abc.legacy.queryPublicationBundles(limit, address)

const publicationId: string = publications[0].id

const { likes: sentLikes, cursor } =
  await abc.legacy.queryLikes(address, 'sent')
const { likes: receivedLikes, cursor } =
  await abc.legacy.queryLikes(address, 'received')
const { likes: likesForPublication, cursor } =
  await abc.legacy.queryLikesForPublication(publicationId)
const { tips: sentTips, cursor } = await abc.legacy.queryTips(address, 'sent')
const { tips: receivedTips, cursor } =
  await abc.legacy.queryTips(address, 'received')

/* Query functions have optional arguments for limit, cursor, and cache */
const allCacheBustedLikesSent = await abc.legacy.queryLikes(
  address,
  'sent',
  'all',
  undefined,
  false
)

Fetching

const abc = new ArtByCity()

const address: string = '<an arweave address>'
const publicationId: string = '<an arweave txid of a publication manifest>'
const slug: string = 'my-cool-artwork' // url slug of a publication

const avatar = await abc.legacy.fetchAvatar(address)
const profile = await abc.legacy.fetchProfile(address)
const publication = await abc.legacy.fetchPublication(publicationId)
const publicationBySlug = await abc.legacy.fetchPublicationBySlug(slug)
const publicationBySlugOrId =
  await abc.legacy.fetchPublicationBySlugOrId(slug) // or publicationId

Usernames

const abc = new ArtByCity()

const address: string = '<an arweave address>'
const username: string = 'jim'

const { username, address } = await abc.usernames.resolve(username)
const { username, address } = await abc.usernames.resolve(address)
const resolvedAddress =
  await abc.usernames.resolveAddressFromUsername(username)
const resolvedUsername =
  await abc.usernames.resolveUsernameFromAddress(address)