Skip to content

Instantly share code, notes, and snippets.

@snowkidind
Last active September 24, 2020 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snowkidind/82900f7fc5afb1e7783ef1ec1dab6111 to your computer and use it in GitHub Desktop.
Save snowkidind/82900f7fc5afb1e7783ef1ec1dab6111 to your computer and use it in GitHub Desktop.
OMG Network custom transaction example part 2
/*
* deliverableWithFee.js
*
* Storefront application where user purchases ERC20, 721 and
* pays fees in the network's native fee curency.
* Modified version of community-points::transaction.js
* See also
* keny@eastcoastbands.com
*/
/*
Copyright 2020 OmiseGO Pte Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const BN = require('bn.js');
const {transaction} = require('@omisego/omg-js-util');
const NULL_METADATA = '0x0000000000000000000000000000000000000000000000000000000000000000';
module.exports = {
create: function (
from,
to,
spendUtxos,
spendAmount,
metadata,
spendToken,
feeUtxos,
feeAmount,
feeOwner,
markupOwner,
markupAmount
) {
if (!spendUtxos || spendUtxos.length === 0) {
throw new Error('spendUtxos is empty')
}
if (!feeUtxos || feeUtxos.length === 0) {
throw new Error('feeUtxos is empty')
}
spendAmount = BN.isBN(spendAmount) ? spendAmount : new BN(spendAmount.toString());
feeAmount = BN.isBN(feeAmount) ? feeAmount : new BN(feeAmount.toString());
markupAmount = BN.isBN(markupAmount) ? markupAmount : new BN(markupAmount.toString());
const spendTotal = this.totalAmount(spendUtxos);
if (spendTotal.lt(spendAmount)) {
throw new Error('Insufficient inputs to cover spend')
}
const markupTotal = this.totalAmount(feeUtxos);
if (markupTotal.lt(markupAmount)) {
throw new Error('Insufficient inputs to cover markup')
}
const feeFunds = this.totalAmount(feeUtxos);
const encodedMetadata = metadata
? transaction.encodeMetadata(metadata)
: NULL_METADATA;
// Construct the tx body
const txBody = {
inputs: [...spendUtxos, ...feeUtxos],
outputs: [
{
outputType: 1,
outputGuard: to,
currency: spendToken,
amount: spendAmount
},
{
outputType: 1,
outputGuard: markupOwner,
currency: feeUtxos[0].currency,
amount: markupAmount
}
],
metadata: encodedMetadata
};
// change output erc20
if (spendTotal.gt(spendAmount)) {
const changeAmount = spendTotal.sub(spendAmount);
txBody.outputs.push({
outputType: 1,
outputGuard: from,
currency: spendToken,
amount: changeAmount
})
}
// fee change output
const feeChange = feeFunds.sub(markupAmount).sub(feeAmount);
if (feeChange > 0){
txBody.outputs.push({
outputType: 1,
outputGuard: feeOwner,
currency: feeUtxos[0].currency,
amount: feeChange
})
}
return txBody
},
totalAmount: (utxos) => {
return utxos.reduce((prev, curr) => {
return prev.add(new BN(curr.amount.toString()))
}, new BN(0))
},
getTypedData: (txBody, verifyingContract) => {
return transaction.getTypedData(txBody, verifyingContract)
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment