Withdrawing NEP5 Tokens

Withdrawing NEP5 tokens is performed by invoking the contract using the withdraw method and specifying the DEX contract to be brought on as a witness to the contract. The script hash of the account making the withdraw, the assetId to withdraw, the quantity, and validUntilBlockIndex are added to the transaction as attributes.

import {
  u,
  wallet,
} from '@cityofzion/neon-js';

const TX_ATTR_USAGE_SIGNATURE_REQUEST_TYPE = 0xA1;
const SIGNATUREREQUESTTYPE_WITHDRAWSTEP_WITHDRAW = '92';
const TX_ATTR_USAGE_WITHDRAW_SCRIPT_HASH = 0xA2;
const TX_ATTR_USAGE_WITHDRAW_NEP5_ASSET_ID = 0xA4;
const TX_ATTR_USAGE_WITHDRAW_AMOUNT = 0xA5;
const TX_ATTR_USAGE_WITHDRAW_VALIDUNTIL = 0xA6;

function withdrawNep5Asset(accountScriptHash, assetId, quantity, validUntilBlockIndex, gasFee=0) {
    const validUntilValue = validUntilBlockIndex * 0.00000001;
    const attribs = [
      [TX_ATTR_USAGE_SIGNATURE_REQUEST_TYPE, SIGNATUREREQUESTTYPE_WITHDRAWSTEP_WITHDRAW.padEnd(64, '0')],
      [TX_ATTR_USAGE_WITHDRAW_SCRIPT_HASH, u.reverseHex(accountScriptHash).padEnd(64, '0')],
      [TX_ATTR_USAGE_WITHDRAW_NEP5_ASSET_ID, u.reverseHex(assetId).padEnd(64, '0')],
      [TX_ATTR_USAGE_WITHDRAW_AMOUNT, u.num2fixed8(quantity).padEnd(64, '0')],
      [TX_ATTR_USAGE_WITHDRAW_VALIDUNTIL, u.num2fixed8(validUntilValue).padEnd(64, '0')]
    ];
  executeContractTransaction('withdraw', [], 0, 0, gasFee, true, attribs);
}

// Example invoking to withdraw 100 APH

const APH_HASH = 'a0777c3ce2b169d4a23bcba4565e3225a0122d95';
const account = new wallet.Account(wif); 
const accountScriptHash = wallet.getScriptHashFromAddress(account.address);
const currentBlockNumber = 3464266; // TODO: Get Current Block Index from RPC
withdrawNep5Asset(accountScriptHash, APH_HASH, 100, currentBlockNumber + 20);

Note: A reasonable value for the validUntilBlockIndex is the current block index + 20