Symbol-SDK@3.2.2でNEMる02 -転送トランザクション-

3.2.2になって、`deadlineSeconds`を渡すだけになったので少し簡単になりました。

:::note warn
ただ、現在のテストネットは12、3秒遅れているので、そのままトランザクションを投げるとエラー`FAILURE_TIMESTAMP_TOO_FAR_IN_FUTURE`が出ます。パソコンの時間を1分ほど遅らせるか、`symbol-sdk\src\nem\Network.js`にあるエポックタイムを13秒ほど先にする必要があります。
:::

```nemTransferTx.ts
import { PrivateKey, PublicKey, utils } from 'symbol-sdk'
import {
  Address,
  descriptors,
  models,
  NemFacade,
  Network,
  TransactionFactory,
} from 'symbol-sdk/nem'
import { SymConst } from '../SymConst.js'

const facade = new NemFacade(Network.TESTNET.name)

// アカウント
const aliceAccount = facade.createAccount(
  new PrivateKey(SymConst.ALICE_PRIVATE_KEY)
)
const bobPublicKey = new PublicKey(utils.hexToUint8(SymConst.BOB_PUBLIC_KEY))
const bobAddress = new Address(facade.network.publicKeyToAddress(bobPublicKey))

// 転送トランザクション
const transferTxDescriptor = new descriptors.TransferTransactionV1Descriptor(
  bobAddress,
  new models.Amount(1_000000n),
  new descriptors.MessageDescriptor(
    models.MessageType.PLAIN,
    '初めての転送トランザクション'
  )
)
const transferTx = facade.createTransactionFromTypedDescriptor(
  transferTxDescriptor,
  aliceAccount.publicKey,
  150000n, // fee: https://nemproject.github.io/#transaction-fees
  60 * 60 * 2
)

// アリス署名
const sig = aliceAccount.signTransaction(transferTx)
const payloadJson = TransactionFactory.attachSignature(transferTx, sig)
console.log(`txHash: ${facade.hashTransaction(transferTx)}`)
console.log(`txSize: ${transferTx.size}`)

// RESTにアナウンス
const transactionsResponse = await fetch(
  new URL('/transaction/announce', 'http://95.216.73.243:7890'),
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: payloadJson,
  }
)
console.log((await transactionsResponse.json()).message)
```
※`ALICE_PRIVATE_KEY`と`BOB_PUBLIC_KEY`は、16進文字列を渡してるだけです。

ほぼ、Symbolと同じ書き方で転送トランザクションを発行することが出来ます。

## 参考：Symbolで同じ事をする場合

```symTransferTx.ts
import { PrivateKey, PublicKey, utils } from 'symbol-sdk'
import {
  Address,
  Network,
  SymbolFacade,
  SymbolTransactionFactory,
  descriptors,
  generateNamespacePath,
  models,
} from 'symbol-sdk/symbol'
import { SymConst } from '../SymConst.js'

const facade = new SymbolFacade(Network.TESTNET.name)

// アカウント
const aliceAccount = facade.createAccount(
  new PrivateKey(SymConst.ALICE_PRIVATE_KEY)
)
const bobPublicKey = new PublicKey(utils.hexToUint8(SymConst.BOB_PUBLIC_KEY))
const bobAddress = new Address(facade.network.publicKeyToAddress(bobPublicKey))

// 転送トランザクション
const namespaceIds = generateNamespacePath('symbol.xym')
const namespaceId = namespaceIds[namespaceIds.length - 1]
const transferTxDescriptor = new descriptors.TransferTransactionV1Descriptor(
  bobAddress,
  [
    new descriptors.UnresolvedMosaicDescriptor(
      new models.UnresolvedMosaicId(namespaceId),
      new models.Amount(1_000000n)
    ),
  ],
  '\0初めての転送トランザクション'
)
const transferTx = facade.createTransactionFromTypedDescriptor(
  transferTxDescriptor,
  aliceAccount.publicKey,
  100, // feeMultiplier
  60 * 60 * 2
)

// アリス署名
const sig = aliceAccount.signTransaction(transferTx)
const payloadJson = SymbolTransactionFactory.attachSignature(transferTx, sig)
console.log(`txHash: ${facade.hashTransaction(transferTx)}`)
console.log(`txSize: ${transferTx.size}`)

// RESTにアナウンス
const transactionsResponse = await fetch(
  new URL('/transactions', 'http://node-t.sixis.xyz:3000'),
  {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: payloadJson,
  }
)
console.log((await transactionsResponse.json()).message)
```