Startrail APIs
  • 🛫Startrail PORT: All in one document for API/SDK
    • 🔀URL per environment
  • Issue transfer api
    • 📬Issue & Transfer SRR (NFT)
      • Request Signed URL for Upload/Download Files
      • File Information Metadata
      • Issue & Transfer
      • Webhook Setup
    • 📂Collection
      • Create Collection
      • Get Collection of LUW
    • 📢Change Logs
      • v1.2.0
      • v1.1.0
      • v1.0.1
  • Metadata Schema
    • 🪅Startrail Registry (SRR)
      • Version 2.2
      • Version 2.1
      • Version 2.0
    • 📤Transfer
      • Version 1.2
      • Version 1.1
      • Version 1.0
    • ☸️Custom History
      • Custom History of Exhibition
        • Version 1.2
      • Custom History of Auction
        • Version 1.3
      • Custom History of Appraisal
        • Version 1.1
      • Custom History of Restoration
        • Version 1.0
      • Custom History of Offchain
        • Version 1.1
  • Get SRR API
    • Get Owned SRRs
    • Get SRR by Collection contract address and Token Id
      • 🚫Get SRR by Token Id
    • Description Of SRR Data
  • Ethereum Signature Validator API
    • 🔏Ethereum Signature Validator API
      • Change Logs
  • Startrail SDK Js
    • 🔰Introduction
    • 🏃Getting Started
      • RPC endpoint and chainId
    • 💳Wallet Methods
    • 🔮Startrail API Methods
      • Add Custom Histories To SRRs
      • Approve SRR By Commitment
      • Bulk
      • Check ERC2981 Royalty
      • Create Collection
      • Convert Metadata
      • Create SRR
      • Transfer Collection Ownership
      • Transfer SRR To Ethereum Address
      • Transfer From With Provenance
      • Update Metadata
    • 📱Login Providers
      • Interface
      • Whitelabeling/Customizing
        • Email Password
      • Hints
      • Multi Factor Account Management
    • 🦊MetaMask
    • 🎎Authentication Integration
    • 👾Errors
    • 📢Change logs
      • v1.35.0
      • v1.34.0
      • v1.33.2
      • v1.33.1
      • v1.32.0
      • v1.31.1
      • v1.30.6
      • v1.30.5
      • v1.30.4
      • v1.30.3
      • v1.30.2
      • v1.30.1
      • v1.30.0
      • v1.29.1
      • v1.29.0
      • v1.28.2
      • v1.28.1
      • v1.28.0
      • v1.27.1
      • v1.27.0
      • v1.26.0
      • v1.25.2(Security Patch)
  • Startrail API
    • 💱Transfer SRR Ownership By RevealHash
    • Get Transaction Data
    • Get Metadata By tokenid
  • Subgraph
    • 📊A introduction of subgraph
    • How to retrieve SRR metadata
Powered by GitBook

©2023 Startbahn, Inc.

On this page
  • UML Diagram
  • Endpoints Used
  • Required Permissions
  • Required Headers
  • Complete Code Example

Was this helpful?

  1. Issue transfer api

Issue & Transfer SRR (NFT)

PreviousURL per environmentNextRequest Signed URL for Upload/Download Files

Last updated 7 months ago

Was this helpful?

If you have any concerns, please .

By using the API/SDK in this document in any way, you agree to . Please read these Terms carefully before using the API/SDK.

UML Diagram

Endpoints Used

Please note that we may add a new field. So make sure that your implementation can support accepting new fields without breaking your implementation. In case we remove the field, we will deprecate it first and let you know beforehand.

Required Permissions

  • You need to have a Licensed User

    • See issuer-address in the following Required Headers section.

  • You need to have an API Key

    • See commerce-api-key in the following Required Headers section.

Required Headers

header
value

issuer-address

The Ethereum address of your LUW

commerce-api-key

The API key you generated in the web application

Content-Type

application/json

accept

application/json

Complete Code Example

In this example, we will do

  1. Get a signed URL to upload 1 file

  2. Upload 1 file using a signed URL

  3. Check the file readiness

  4. To simplify the example, we use the same uploaded file's final URL for

    • contract terms

    • thumbnail

    • attachment file

Note:

  • This example does not cover the webhook on the client’s side that Startbahn API will call when issuance or mining failure happens.

    • save it as example.ts

    npx ts-node ./script-address/example.ts
import fs from 'fs'
import fetch from 'node-fetch'
import { v4 as uuidv4 } from 'uuid'

main('issuerAddress', 'artistAddress', 'apiKey', 'receiverAddress') // Use your staging credential to test

async function main(
  luwIssuer: string,
  luwArtist: string,
  apiKey: string,
  toAddress: string | undefined
) {
  console.log('Starting the issue API example')
  const headersCommerceApi = {
    'Content-Type': 'application/json',
    accept: 'application/json',
    'commerce-api-key': apiKey,
    'issuer-address': luwIssuer,
  }

  /////////////////////////
  // GENERATE SIGNED URL //
  // STEP 7 - 8          //
  /////////////////////////
  console.log('Starting to generate signed URL')
  const signedUrlEndpoint =
    'https://api-stg.startrail.startbahn.jp/port/api/v1/commerce/signedUrls'
  const fileName = `test-${uuidv4()}.txt`
  const fileWs = fs.createWriteStream(fileName)
  fileWs.write('test')
  fileWs.end()
  const requestBodySignedUrl = {
    payload: [
      {
        filename: fileName,
        category: 'artwork',
      },
    ],
    action: 'write',
  }

  const responseSignedUrl = await fetch(signedUrlEndpoint, {
    method: 'POST',
    body: JSON.stringify(requestBodySignedUrl),
    headers: headersCommerceApi,
  })

  if (!responseSignedUrl.ok) {
    console.log('handle the error')
  }

  const jsonSignedUrlResponse = await responseSignedUrl.json()
  
  const contentType = jsonSignedUrlResponse.results[0].contentType
  
  // Upload the file to the Signed URL
  // example using cURL
  // `curl -X PUT -H 'Content-Type: text/plain' --upload-file my-file.txt '${res.url}
  const signedUrl = jsonSignedUrlResponse.results[0].url

  // save res.finalUrl and use it for Issue endpoint
  const finalUrl = jsonSignedUrlResponse.results[0].finalUrl

  /////////////////////////////
  // UPLOAD USING SIGNED URL //
  // STEP 9                  //
  /////////////////////////////
  console.log('Starting to upload the file')
  const fileRs = fs.createReadStream(fileName)
  const responseUpload = await fetch(signedUrl, {
    method: 'PUT',
    headers: {
      'Content-Type': contentType,
    },
    body: fileRs,
  })

  if (!responseUpload.ok) {
    console.log('handle the error')
  }

  ///////////////////////////
  // CHECK FILE READINESS  //
  // STEP 11 - 12          //
  ///////////////////////////
  console.log('Starting to check the file readiness')
  await sleep(360000) // wait to make sure the hash is calculated
  const fileInfoEndpoint =
    'https://api-stg.startrail.startbahn.jp/port/api/v1/commerce/fileMetadata'
  const requestBodyFileInfo = {
    payload: [
      {
        filename: fileName,
        category: 'artwork',
      },
    ],
  }

  const responseFileInfo = await fetch(fileInfoEndpoint, {
    method: 'POST',
    body: JSON.stringify(requestBodyFileInfo),
    headers: headersCommerceApi,
  })

  if (!responseFileInfo.ok) {
    console.log('handle the error')
  }

  const jsonFileInfoResponse = await responseFileInfo.json()
  const calculatedHash = jsonFileInfoResponse.results[0].hash
  if (!calculatedHash) {
    console.log('There is error in hash calculation, contact Startbahn')
  }

  //////////////////
  // ISSUE SRR    //
  // STEP 13 - 16 //
  //////////////////
  console.log('Starting to issuen an SRR')
  const issueEndpoint =
    'https://api-stg.startrail.startbahn.jp/port/api/v1/commerce/srrs'

  const singlePayload: any = {
    externalId: uuidv4(),
    artistAddress: luwArtist,
    isPrimaryIssuer: true,
    lockExternalTransfer: false,
    // If the uploaded file is thumbnail or contract terms, it should be put on the metadata
    metadata: randomizeMetadata(finalUrl, finalUrl),
    attachmentFiles: [
      {
        name: requestBodyFileInfo.payload[0].filename,
        // If the uploaded file is an attachment file, put it in this field
        url: finalUrl,
        category: requestBodyFileInfo.payload[0].category,
      },
    ],
  }

  if (toAddress) {
    singlePayload.to = toAddress
  }
  const requestBodyissue = {
    payload: [singlePayload],
  }

  const responseIssue = await fetch(issueEndpoint, {
    method: 'POST',
    body: JSON.stringify(requestBodyissue),
    headers: headersCommerceApi,
  })

  if (!responseIssue.ok) {
    console.log('handle the error')
  }

  const jsonIssueResponse = await responseIssue.json()
  console.log(jsonIssueResponse)
}

async function sleep(milliseconds: number): Promise<NodeJS.Timeout> {
  return new Promise((resolve) => setTimeout(resolve, milliseconds))
}

function randomizeMetadata(
  thumbnailURL: string,
  contractTermsFileURL: string
) {
  return {
    $schema:
      'https://api.startrail.io/api/v1/schema/registry-record-metadata.v2.1.schema.json',
    $schemaIntegrity:
      'sha256-15f8e99eb9d4292287282942db2f2de9bbcc4761c555c6f7da23feec010c1221',
    title: {
      en: 'A title-' + uuidv4(),
      ja: 'タイトル-' + uuidv4(),
      zh: '一个标题-' + uuidv4(),
    },
    size: {
      width: 200.0,
      height: 400.0,
      depth: 12.4,
      unit: 'pixel',
      flexibleDescription: {
        en: 'flexibleDescription comes here',
        ja: '自由だーーー',
      },
    },
    medium: {
      en: 'Oil on canvas',
      ja: 'キャンバスに油彩',
      zh: '布面油画',
    },
    edition: {
      uniqueness: 'unique work',
      proofType: 'ED',
      number: 1,
      totalNumber: 3,
      note: {
        en: 'some extra notes in 1 or more languages',
      },
    },
    contractTerms: {
      royaltyRate: 15.7,
      fileURL: contractTermsFileURL,
    },
    note: {
      en: 'note',
      zh: '注意',
    },
    thumbnailURL,
    yearOfCreation: {
      en: 'around 2010-2020',
      ja: '2010年から2020年頃',
    },
    isDigital: true,
    name: 'some nft name',
    description: 'some nft description',
    image:
      'https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png',
    external_url: 'https://startrail.io/',
  }
}

Steps 7 - 8:

Step 9: Upload file to Google Cloud Storage, use Signed URL as the endpoint,

Steps 11 - 12:

Steps 13 - 16:

Step 17:

You may need and to run it

📬
Request Signed URL for Upload/Download Files
Google Documentation
File Information Metadata
Issue & Transfer SRR
Webhook Setup
TS-Node
NPX
contact us
Startrail PORT API/SDK Terms of Service