# アセット（NFT）の管理

このガイドでは、OCAP クライアントを使用して、アセットとしても知られる非代替性トークン（NFT）のライフサイクル全体を管理するための包括的なウォークスルーを提供します。新しいアセットをゼロから作成し、そのプロパティを更新し、標準化されたミントのためのアセットファクトリーを設立し、そのファクトリーから新しいアセットを取得する方法を学びます。


## 新しいアセットの作成

`createAsset` メソッドを使用して、ブロックチェーン上にユニークでスタンドアロンなアセットを作成できます。各アセットには、その初期プロパティから派生したユニークなオンチェーンアドレスが割り当てられます。

```javascript icon=logos:javascript
const { wallet } = getWallet(); // ユーザーのウォレットオブジェクト

async function createNewAsset() {
  try {
    const [hash, address] = await client.createAsset({
      moniker: 'My Unique Digital Artwork',
      data: {
        typeUrl: 'json',
        value: { 
          description: 'A one-of-a-kind piece created by Artist X.',
          imageUrl: 'https://example.com/path/to/image.png',
        },
      },
      readonly: true,
      transferrable: true,
      wallet: wallet,
    });

    console.log(`アセット作成トランザクションが送信されました: ${hash}`);
    console.log(`新しいアセットのアドレス: ${address}`);
    return address;
  } catch (error) {
    console.error('アセットの作成中にエラーが発生しました:', error);
  }
}

createNewAsset();
```

### パラメータ

<x-field-group>
  <x-field data-name="moniker" data-type="string" data-required="true" data-desc="アセットの名前。"></x-field>
  <x-field data-name="parent" data-type="string" data-default="''" data-required="false" data-desc="親アセットのアドレス（もしあれば）。"></x-field>
  <x-field data-name="data" data-type="object" data-required="true" data-desc="アセットのデータペイロード。typeUrlとvalueを含める必要があります。"></x-field>
  <x-field data-name="readonly" data-type="boolean" data-default="false" data-required="false" data-desc="trueの場合、アセットは作成後に更新できません。"></x-field>
  <x-field data-name="transferrable" data-type="boolean" data-default="true" data-required="false" data-desc="trueの場合、アセットは別のアカウントに転送できます。"></x-field>
  <x-field data-name="ttl" data-type="number" data-default="0" data-required="false" data-desc="アセットの初回消費後の生存期間（秒単位）。"></x-field>
  <x-field data-name="display" data-type="object" data-required="false" data-desc="アセットの表示情報を含むオブジェクト。"></x-field>
  <x-field data-name="endpoint" data-type="object" data-required="false" data-desc="アセットのエンドポイント詳細を含むオブジェクト。"></x-field>
  <x-field data-name="tags" data-type="string[]" data-default="[]" data-required="false" data-desc="アセットを分類するための文字列の配列。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="アセットの初期所有者のウォレットオブジェクト。"></x-field>
  <x-field data-name="delegator" data-type="string" data-default="''" data-required="false" data-desc="委任によってこのトランザクションを承認したアカウントのアドレス。"></x-field>
</x-field-group>

### 戻り値

トランザクションハッシュと新しいアセットのオンチェーンアドレスを含む配列に解決される `Promise`。

<x-field data-name="response" data-type="Promise<[string, string]>" data-desc="[transactionHash, assetAddress]"></x-field>

---


## 既存アセットの更新

アセットが `readonly: false` で作成された場合、`updateAsset` メソッドを使用してその `moniker` と `data` フィールドを変更できます。アセットは、そのユニークなアドレスによって識別されます。

```javascript icon=logos:javascript
const { wallet } = getWallet(); // ユーザーのウォレットオブジェクト
const assetAddress = 'z362...'; // 更新するアセットのアドレス

async function updateExistingAsset() {
  try {
    const hash = await client.updateAsset({
      address: assetAddress,
      moniker: 'My Updated Digital Artwork',
      data: {
        typeUrl: 'json',
        value: { 
          description: 'An updated description for my unique piece.',
          imageUrl: 'https://example.com/path/to/new_image.png',
        },
      },
      wallet: wallet,
    });

    console.log(`アセット更新トランザクションが送信されました: ${hash}`);
  } catch (error) {
    console.error('アセットの更新中にエラーが発生しました:', error);
  }
}

updateExistingAsset();
```

### パラメータ

<x-field-group>
  <x-field data-name="address" data-type="string" data-required="true" data-desc="更新するアセットのオンチェーンアドレス。"></x-field>
  <x-field data-name="moniker" data-type="string" data-required="true" data-desc="アセットの新しい名前。"></x-field>
  <x-field data-name="data" data-type="object" data-required="true" data-desc="アセットの更新されたデータペイロード。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="現在のアセット所有者のウォレットオブジェクト。"></x-field>
</x-field-group>

### 戻り値

トランザクションハッシュに解決される `Promise`。

<x-field data-name="response" data-type="Promise<string>" data-desc="transactionHash"></x-field>

---


## アセットファクトリーの作成

アセットファクトリーは、複数の類似したアセットを作成するためのテンプレートです。新しいアセットをミントするための構造、ルール、ロジックを定義し、それぞれを個別に作成するよりも効率的です。これは、イベントチケット、証明書、コレクティブルの発行などのユースケースに最適です。

```javascript icon=logos:javascript
const { wallet } = getWallet(); // ファクトリー所有者のウォレット

const factoryDefinition = {
  name: 'Conference Ticket Factory',
  description: 'Mints tickets for the 2024 Tech Conference.',
  limit: 1000, // 最大1000枚のチケットがミント可能
  input: {
    // アセットのミントに必要なデータを定義
    type: 'object',
    properties: {
      attendeeName: { type: 'string' },
      ticketType: { type: 'string', enum: ['General', 'VIP'] },
    },
  },
  output: {
    // ミントされるアセットの構造を定義
    moniker: 'Ticket for {{attendeeName}}',
    description: '{{ticketType}} admission for the 2024 Tech Conference.',
    transferrable: false, // チケットは譲渡不可
  },
  hooks: [],
};

async function createFactory() {
  try {
    const [hash, factoryAddress] = await client.createAssetFactory({
      factory: factoryDefinition,
      wallet: wallet,
    });

    console.log(`ファクトリー作成トランザクションが送信されました: ${hash}`);
    console.log(`新しいファクトリーのアドレス: ${factoryAddress}`);
  } catch (error) {
    console.error('アセットファクトリーの作成中にエラーが発生しました:', error);
  }
}

createFactory();
```

### パラメータ

<x-field-group>
  <x-field data-name="factory" data-type="object" data-required="true" data-desc="ファクトリーのプロパティとミントロジックを定義するオブジェクト。">
    <x-field data-name="name" data-type="string" data-required="true" data-desc="ファクトリーの名前。"></x-field>
    <x-field data-name="description" data-type="string" data-required="true" data-desc="ファクトリーの目的の説明。"></x-field>
    <x-field data-name="limit" data-type="number" data-default="0" data-required="false" data-desc="このファクトリーからミントできるアセットの最大数。0は無制限を意味します。"></x-field>
    <x-field data-name="trustedIssuers" data-type="string[]" data-required="false" data-desc="このファクトリーからのミントを許可されたアカウントアドレスのリスト。"></x-field>
    <x-field data-name="input" data-type="object" data-required="true" data-desc="アセットをミントするために必要な入力データを定義します。"></x-field>
    <x-field data-name="output" data-type="object" data-required="true" data-desc="ミントされるアセットの構造とプロパティを定義します。"></x-field>
    <x-field data-name="hooks" data-type="object[]" data-required="false" data-desc="ミントプロセス中に実行するフックのリスト。"></x-field>
    <x-field data-name="data" data-type="object" data-required="false" data-desc="ファクトリーと共に保存する追加の任意のデータ。"></x-field>
  </x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="ファクトリー所有者のウォレットオブジェクト。"></x-field>
</x-field-group>

### 戻り値

トランザクションハッシュと新しいファクトリーのオンチェーンアドレスを含む配列に解決される `Promise`。

<x-field data-name="response" data-type="Promise<[string, string]>" data-desc="[transactionHash, factoryAddress]"></x-field>

---


## ファクトリーからのアセットの取得

ファクトリーからアセットを取得するのは2段階のプロセスです。まず、ミントデータを準備し、これにより作成されるアセットをプレビューできます。次に、トランザクションをブロックチェーンに送信して、アセットを正式に取得します。

この分離は、アプリケーションがユーザーに最終的なトランザクションに署名して送信する前に何を受け取るかを表示できるため便利です。

### ステップ1：アセットデータの準備

`preMintAsset` メソッドは、ファクトリーアドレスとユーザーが提供した入力値を受け取り、最終的なアセットデータを生成します。これはオフチェーンで行われ、トランザクションは不要です。

```javascript icon=logos:javascript
const factoryAddress = 'z2...'; // 以前に作成されたファクトリーのアドレス
const { wallet: issuerWallet } = getIssuerWallet(); // ファクトリーの所有者または信頼された発行者
const { wallet: userWallet } = getUserWallet(); // 新しいアセットを所有するユーザー

async function prepareAssetForMinting() {
  try {
    const mintingData = await client.preMintAsset({
      factory: factoryAddress,
      inputs: {
        attendeeName: 'John Doe',
        ticketType: 'VIP',
      },
      owner: userWallet.address,
      wallet: issuerWallet,
    });

    console.log('ミント用のアセットデータを準備しました:', mintingData);
    return mintingData;
  } catch (error) {
    console.error('アセットの準備中にエラーが発生しました:', error);
  }
}
```

### ステップ2：トランザクションの送信

ミントデータが準備されると、ユーザー（将来のアセット所有者）が `acquireAsset` トランザクションに署名して送信します。`preMintAsset` からの `itx` オブジェクトがペイロードとして使用されます。

```javascript icon=logos:javascript
async function acquireNewAsset() {
  // まず、ステップ1からミントデータを取得します
  const itx = await prepareAssetForMinting();
  if (!itx) return;

  try {
    const hash = await client.acquireAsset({
      itx: itx,
      wallet: userWallet, // ユーザーのウォレットがトランザクションに署名します
    });

    console.log(`アセット取得トランザクションが送信されました: ${hash}`);
    console.log(`新しいアセットは次のアドレスで利用可能になります: ${itx.address}`);
  } catch (error) {
    console.error('アセットの取得中にエラーが発生しました:', error);
  }
}

acquireNewAsset();
```

### `acquireAsset` のパラメータ

<x-field-group>
  <x-field data-name="itx" data-type="object" data-required="true" data-desc="`preMintAsset` メソッドから返される内部トランザクションオブジェクト。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="アセットを取得するユーザーのウォレット。"></x-field>
  <x-field data-name="delegator" data-type="string" data-default="''" data-required="false" data-desc="委任によってこのトランザクションを承認したアカウントのアドレス。"></x-field>
</x-field-group>

### 戻り値

`acquireAsset` 操作のトランザクションハッシュに解決される `Promise`。

<x-field data-name="response" data-type="Promise<string>" data-desc="transactionHash"></x-field>

---


## ファクトリーからのアセットのミント

ユーザー主導の `acquireAsset` フローに加えて、承認された発行者（ファクトリー所有者や信頼された発行者など）がアセットをミントし、ユーザーのアカウントに直接送信できます。このプロセスでも `preMintAsset` を使用してデータを準備しますが、最終的なトランザクションは発行者によって署名された `mintAsset` です。

このフローは、エアドロップ、証明書の授与、または受け取るユーザーが最終的なトランザクションを開始する必要がない場合に便利です。

### ステップ1：アセットデータの準備

このステップは取得フローと同じです。発行者は `preMintAsset` を呼び出して、トランザクションペイロード（`itx`）をオフチェーンで生成します。

```javascript icon=logos:javascript
const factoryAddress = 'z2...'; // ファクトリーのアドレス
const { wallet: issuerWallet } = getIssuerWallet(); // ファクトリーの所有者または信頼された発行者
const userAddress = 'z1...'; // アセットを受け取るユーザーのアドレス

async function prepareAssetForMinting() {
  try {
    const mintingData = await client.preMintAsset({
      factory: factoryAddress,
      inputs: {
        attendeeName: 'Jane Smith',
        ticketType: 'General',
      },
      owner: userAddress,
      wallet: issuerWallet, // ここでは発行者のウォレットが使用されます
    });

    console.log('ミント用のアセットデータを準備しました:', mintingData);
    return mintingData;
  } catch (error) {
    console.error('アセットの準備中にエラーが発生しました:', error);
  }
}
```

### ステップ2：ミントトランザクションの送信

発行者は準備された `itx` オブジェクトを使用して `mintAsset` を呼び出します。トランザクションは発行者のウォレットで署名され、新しく作成されたアセットは前のステップで指定された所有者に割り当てられます。

```javascript icon=logos:javascript
async function mintNewAsset() {
  // まず、ステップ1からミントデータを取得します
  const itx = await prepareAssetForMinting();
  if (!itx) return;

  try {
    // 発行者のウォレットがトランザクションに署名します
    const hash = await client.mintAsset({
      itx: itx,
      wallet: issuerWallet,
    });

    console.log(`アセットミントトランザクションが送信されました: ${hash}`);
    console.log(`${userAddress} 向けの新しいアセットは次のアドレスで利用可能になります: ${itx.address}`);
  } catch (error) {
    console.error('アセットのミント中にエラーが発生しました:', error);
  }
}

mintNewAsset();
```

### `mintAsset` のパラメータ

<x-field-group>
  <x-field data-name="itx" data-type="object" data-required="true" data-desc="`preMintAsset` メソッドから返される内部トランザクションオブジェクト。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="アセットをミントする発行者のウォレット。"></x-field>
</x-field-group>

### 戻り値

`mintAsset` 操作のトランザクションハッシュに解決される `Promise`。

<x-field data-name="response" data-type="Promise<string>" data-desc="transactionHash"></x-field>
