Working with Game Assets

Creating an Asset Directly

GameShift allows you to programmatically create on-chain game assets by providing data to an API call, or through an asset template.

To create an asset directly, make a POST http request to https://api.gameshift.dev/assets:

curl --request POST \
     --url https://api.gameshift.dev/assets \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your key here>' \
     --data '
{
  "details": {
    "description": "Example description",
    "imageUrl": "https://solana.com/src/img/branding/solanaLogoMark.png",
    "name": "Example Asset",
    "attributes": [
      {
        "displayType": "Formatted Attribute Name",
        "traitType": "attribute-name",
        "value": "attribute-value"
      }
    ]
  },
  "destinationUserReferenceId": "exampleUserId"
}
'

Assets require the following values in the “details” object:

  • description: 64-character string providing information about the asset, which may be displayed to the user later

  • name: 32-character string that identifies the asset, which may be displayed to the user later

  • imageUrl: direct link to the image representing the asset

An asset’s details also supports additional properties called “attributes”. Each “attribute” contains:

  • displayType: a formatted title

  • traitType: a code-appropriate name

  • value: attribute’s value

Finally, specify the user receiving the asset by setting destinationUserReferenceId to an existing referenceId

If successful, you’ll receive a response reflecting the newly-created asset.

{
  "id": "dcde5bc8-b30b-46b6-b4da-0763953b2484",
  "collectionId": "36c97125-04a5-4dc3-b92a-029d74a42287",
  "attributes": [
    {
      "displayType": "Formatted Attribute Name",
      "traitType": "attribute-name",
      "value": "attribute-value"
    }
  ],
  "name": "Example Asset",
  "description": "Example description",
  "imageUrl": "https://solana.com/src/img/branding/solanaLogoMark.png",
  "status": "Processing",
  "owner": {}
}

Newly created assets remain in a “Processing” state until created on-chain. Poll for the latest status of an asset by making a GET http request to https://api.gameshift.dev/assets/{the-id-of-the-asset}:

{
  "id": "dcde5bc8-b30b-46b6-b4da-0763953b2484",
  "collectionId": "36c97125-04a5-4dc3-b92a-029d74a42287",
  "attributes": [
    {
      "displayType": "Formatted Attribute Name",
      "traitType": "attribute-name",
      "value": "attribute-value"
    }
  ],
  "name": "Example Asset",
  "description": "Example description",
  "imageUrl": "https://solana.com/src/img/branding/solanaLogoMark.png",
  "status": "Committed",
  "owner": {
    "address": "<user’s on-chain wallet address>",
    "referenceId": "exampleUserId"
  }
}

Assets committed to the blockchain include the owner’s wallet address and their referenceId.

Created assets are assigned to collections. You can create your own collections (see “Creating Collections”) and pass its id when creating an asset to assign an asset to it. If you do not provide a collectionId, the asset will be created under the default collection.

Modifying an Asset

Assets can be modified by making a PUT http request to https://api.gameshift.dev/assets/{the-id-of-the-asset}:

curl --request PUT \
     --url https://api.gameshift.dev/assets/dcde5bc8-b30b-46b6-b4da-0763953b2484 \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "imageUrl": "updated-img-url",
  "attributes": [
    {
      "traitType": "trait-1",
      "value": "value-1"
    }
  ]
}
'

Not all fields are modifiable. The fields you can change are:

  • imageUrl: You can set this field to change the underlying image of the Asset
  • attributes: You can set this field to entirely replace the existing set of attributes for the Asset

Creating an Asset with Templates

Templates create assets by using pre-populated asset details to create and assign assets. Creating a template is similar to creating an asset; however, there’s no need for a referenceId, since the asset doesn’t exist yet.

Create a template by making a POST http request to https://api.gameshift.dev/asset-templates:

curl --request POST \
     --url https://api.gameshift.dev/asset-templates \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your key here>' \
     --data '
{
  "sourceImage": "https://solana.com/src/img/branding/solanaLogoMark.png",
  "description": "Example description",
  "name": "Example Template",
  "attributes": [
    {
      "displayType": "Formatted Attribute Name",
      "traitType": "attribute-name",
      "value": "attribute-type"
    }
  ]
}
'

Once you create a template, you’ll receive a reference to that template:

{
  "id": "6ba6e801-258c-4d5d-86b9-4f65c522bb1c",
  "name": "Example Template",
  "description": "Example description",
  "sourceImage": "https://solana.com/src/img/branding/solanaLogoMark.png",
  "attributes": [
    {
      "displayType": "Formatted Attribute Name",
      "traitType": "attribute-name",
      "value": "attribute-type"
    }
  ]
}

Create an asset from that template by making a POST http request to https://api.gameshift.dev/asset-templates/{the-template-id}/assets. Include your template’s id in the API’s URL.

curl --request POST \
     --url https://api.gameshift.dev/asset-templates/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/assets \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "destinationUserReferenceId": "exampleUserId"
}
'

Creating Collections

Collections help you create logical groupings for your assets that also exist on-chain. Any assets you create are assigned to a default collection, but you can create your own.

Create a collection by making a POST http request to https://api.gameshift.dev/asset-collections:

curl --request POST \
     --url https://api.gameshift.dev/asset-collections \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "name": "New Example Collection",
  "description": "An example collection",
  "imageUrl": "https://solana.com/src/img/branding/solanaLogoMark.png"
}
'

Collections require the following:

  • name: 32-character string that identifies the collection

  • description: 64-character string providing information about the collection

  • imageUrl: direct link to the image representing the collection

Transferring Assets

Assets can be transferred only with the asset owner’s permission. Asset transfers consist of a request to transfer from an asset owner, followed by a consenting response from that user. Assets can be transferred between users registered by you on GameShift, or from a GameShift-registered user to an arbitrary blockchain wallet address.

Initiate a transfer between users by making a POST http request to https://api.gameshift.dev/assets/{id-of-the-asset}/transfer:

curl --request POST \
     --url https://api.gameshift.dev/assets/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/transfer \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "onBehalfOf": "exampleUserId",
  "destinationUserReferenceId": "anotherExampleUserId"
}
'

You must provide values for the following fields:

  • onBehalfOf: current owner of the asset

  • destinationUserReferenceId: the user intended to receive the asset

Initiate a transfer to an arbitrary blockchain wallet address by making a GET http request to the same endpoint and with destinationWallet instead of a user’s id:

curl --request POST \
     --url https://api.gameshift.dev/assets/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/transfer \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "onBehalfOf": "exampleUserId",
  "destinationWallet": "example-wallet-address"
}
'

All requests return a “consent URL”- a link that the asset owner must visit to provide consent for the transaction.

https://app.gameshift.dev/consent?transaction=726e9605-fd51-47f2-a183-97261027799f

When the asset owner visits the URL, they’ll be asked for permission to complete the transaction.

img img

Once permission is granted, the owner receives a one-time-passcode (OTP) delivered to their email. The OTP must be entered into the consent form to complete the transfer.

Lending Assets

Assets can be easily lent and borrowed between users by creating a lending grant that reflects an agreement between two users to lend/borrow and asset. The lender can revoke the lending grant at any time, but while an asset is lent, the owner cannot transfer or sell the asset. While the lending grant is active, the borrower is considered by GameShift as the holder of the asset. Note that assets that are lent out currently remain in the lender's on-chain wallet, so on-chain analytics will not recognize the effect of the lending grant.

Initiate lending an Asset by making a POST http request to https://api.gameshift.dev/assets/{id-of-the-asset}/lend:

curl --request POST \
     --url https://api.gameshift.dev/assets/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/lend \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "lenderReferenceId": "current-owner",
  "borrowerReferenceId": "borrower-id"
}
'

You must provide the following fields:

  • lenderReferenceId: the current owner of the asset
  • borrowerReferenceId: the user intending to borrow the asset

You can also provide the following optional fields:

  • expiration: the date and time (representing in ms) that the grant should expire. If left blank, will default to 30days from the request date.

On a successful request, you'll receive a reference for the lending grant:

{
  "id": "string",
  "assetId": "string",
  "ownerReferenceId": "string",
  "borrowerReferenceId": "string",
  "expiration": "2023-12-14T22:35:14.292Z",
  "created": "2023-12-14T22:35:14.292Z",
  "status": "Pending",
  "lender": {
    "referenceId": "string",
    "address": "string",
    "email": "string"
  },
  "borrower": {
    "referenceId": "string",
    "address": "string",
    "email": "string"
  },
  "environment": {},
  "projectId": "string"
}

Once a lending grant is created, it must be accepted by the user intending to borrow the asset. You can make a request to accept the grant by making a POST http request to https://api.gameshift.dev/lending-grants/{id-of-the-lending-grant}/accept:

curl --request POST \
     --url https://api.gameshift.dev/lending-grants/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/accept \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "borrowerReferenceId": "borrower-id"
}
'

You can also return the asset to the original owner at any time by making a POST http request to https://api.gameshift.dev/lending-grants/{id-of-the-lending-grant}/return:

curl --request POST \
     --url https://api.gameshift.dev/lending-grants/6ba6e801-258c-4d5d-86b9-4f65c522bb1c/return \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "borrowerReferenceId": "borrower-id"
}
'

Alternatively, you can cancel the grant. This would represent the original owner reclaiming their borrowed asset. You can initiate this cancel by making a DELETE http request to https://api.gameshift.dev/lending-grants/{id}:

curl --request DELETE \
     --url https://api.gameshift.dev/lending-grants/6ba6e801-258c-4d5d-86b9-4f65c522bb1c \
     --header 'content-type: application/json' \
     --header 'x-api-key: <your api key>' \
     --data '
{
  "lenderReferenceId": "current-owner"
}
'