Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const { default: Neon, api, wallet } = require("@cityofzion/neon-js");
const sendingKey =
"9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69";
const receivingAddress = "ASo1RcNVLiV3yQ8j3ZyZv5EWfqBBT8s2Yd";
const network = "TestNet";
/**
## Creating intents
To send an asset, we first have to create an `Intent`. Intents represent the instructions to send assets to a specific address.
> Do note that intents are only used for UTXO assets. If you are looking to send NEP5 tokens, this is not the correct way.
*/
// We want to send 1 NEO and 1 GAS to ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW
const intent = api.makeIntent({ NEO: 1, GAS: 0.00000001 }, receivingAddress);
console.log("\n\n--- Intents ---");
intent.forEach(i => console.log(i));
/**
To add more intents, simple use`api.makeIntent` to create your intents. The method returns an array of intent objects so make sure to concatenate them together.
## Selecting the API provider and network
We need to decide which provider shall we use. In this example, I shall be using `TestNet` with neoscan. As `TestNet` is built into the `neon-js` networks, we can retrieve it using its name `TestNet` instead of stating a url. For other networks such as your own private network, you will input the url of your private neoscan (for example, https://localhost:4000/api/main_net)
*/
const apiProvider = new api.neoscan.instance(network);
console.log("\n\n--- API Provider ---");
console.log(apiProvider);
const send = async ({ net, asset, amount, receiver, address, wif }) => {
if (![GAS, NEO].includes(asset)) {
throw new Error(`Invalid asset: ${asset}`);
}
// TODO check if user has enough balance
if (!wallet.isAddress(receiver)) {
throw new Error(`Invalid script hash: "${receiver}"`);
}
if (amount <= 0) {
throw new Error(`Invalid amount: "${amount}"`);
}
const selectedAsset = asset === NEO ? 'NEO' : 'GAS';
const intents = await api.makeIntent({ [selectedAsset]: amount }, receiver);
const config = {
net,
address,
privateKey: new wallet.Account(wif).privateKey,
intents
};
const { response: { result, txid } } = await Neon.sendAsset(config);
if (!result) {
throw new Error('Invocation failed.');
}
return txid;
};
return flatMap(assetEntries, ({ address, amount, symbol }) =>
api.makeIntent({ [symbol]: toNumber(amount) }, address),
)
export default async function sendAsset({ net, asset, amount, receiver, address, wif }) {
if (!keys(ASSETS).includes(asset)) {
throw new Error(`Invalid asset: ${asset}`);
}
if (!wallet.isAddress(receiver)) {
throw new Error(`Invalid script hash: "${receiver}"`);
}
if (amount <= 0) {
throw new Error(`Invalid amount: "${amount}"`);
}
const selectedAsset = ASSETS[asset];
const intents = await api.makeIntent({ [selectedAsset]: amount }, receiver);
const config = {
net,
address,
privateKey: new wallet.Account(wif).privateKey,
intents
};
const { response: { result, txid } } = await api.sendAsset(config, api.neoscan);
if (!result) {
throw new Error('Invocation failed.');
}
return txid;
}
const config = {
net,
url,
address,
script: createScript(scriptHash, operation, args, encodeArgs),
privateKey: wif,
publicKey,
signingFunction,
gas: 0,
fees: fee
};
if (assets) {
const scAddress = wallet.getAddressFromScriptHash(scriptHash);
const intentConfig = mapKeys(formatAssets(assets), (value, key) => ASSETS[key].symbol);
config.intents = api.makeIntent(intentConfig, scAddress);
}
const {
response: { result, txid }
} = await api.doInvoke(config, api.neoscan);
if (!result) {
throw new Error('Invocation failed.');
}
return txid;
}
const send = async () => {
const url = await doGetRPCEndpoint(net);
const config = {
net,
url,
address,
privateKey: wif,
publicKey,
signingFunction,
fees: fee
};
if (keys(ASSETS).includes(asset)) {
const selectedAsset = ASSETS[asset].symbol;
const intents = api.makeIntent({ [selectedAsset]: amount }, receiver);
const balance = await getBalance(net, address);
const transaction = tx.Transaction.createContractTx(balance, intents, {}, fee);
if (typeof remark === 'string') {
transaction.addRemark(remark);
} else if (Array.isArray(remark)) {
for (let i = 0; i < remark.length; i += 1) {
transaction.addAttribute(tx.TxAttrUsage.Remark + i, remark[i]);
}
}
return doSendAsset({ ...config, balance, tx: transaction }, api.neoscan);
} else {
const script = createScript(
asset,
'transfer',
privateKey,
signingFunction
}) {
const url = await getRPCEndpoint(net);
const {
response: { result }
} = await api.sendAsset(
{
net,
url,
address,
publicKey,
privateKey,
signingFunction,
intents: api.makeIntent({ NEO: balance }, address)
},
api.neoscan
);
if (!result) {
throw new Error('Transaction rejected by blockchain');
}
return result.response;
}