@renproject/rentx
Version:
XState Statemachines for tracking RenVM transactions reactively
124 lines (121 loc) • 5.18 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.burnConfig = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
/*
Sample burnChainMap / releaseChainMap implementations
We don't implement these to prevent mandating specific chains
const burnChainMap: BurnMachineContext["fromChainMap"] = {
ethereum: (context): MintChain<any> => {
return Ethereum(context.providers.ethereum, RenNetwork.Testnet).Account(
{
address: context.tx.userAddress,
value: context.tx.suggestedAmount,
}
) as MintChain<any>;
},
};
const releaseChainMap: BurnMachineContext["toChainMap"] = {
bitcoin: (context): LockChain => {
return Bitcoin().Address(context.tx.destAddress) as any;
},
};
*/
const burnAndRelease = (context) => __awaiter(void 0, void 0, void 0, function* () {
const txHash = Object.keys(context.tx.transactions)[0];
return yield context.sdk.burnAndRelease(Object.assign({ asset: "BTC", to: context.toChainMap[context.tx.destNetwork](context), from: context.fromChainMap[context.tx.sourceNetwork](context) }, (txHash ? { txHash } : {})));
});
// Format a transaction and prompt the user to sign
const txCreator = (context) => __awaiter(void 0, void 0, void 0, function* () {
const asset = context.tx.sourceAsset;
let suggestedAmount = new bignumber_js_1.default(Number(context.tx.targetAmount) * 1e8)
.decimalPlaces(8)
.toFixed();
try {
const fees = yield context.sdk.getFees();
suggestedAmount = new bignumber_js_1.default(Math.floor(fees[asset.toLowerCase()].release +
Number(context.tx.targetAmount) * 1e8))
.decimalPlaces(0)
.toFixed();
}
catch (e) { }
const newTx = Object.assign(Object.assign({}, context.tx), { suggestedAmount });
context.tx = newTx;
const burn = yield burnAndRelease(context);
// We immediately submit the burn request
const hash = yield new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield burn
.burn()
.on("transactionHash", (hash) => resolve(hash));
}
catch (e) {
reject(e);
}
}));
return Object.assign(Object.assign({}, newTx), { transactions: {
[hash]: {
sourceTxHash: hash,
sourceTxConfs: 0,
sourceTxAmount: Number(suggestedAmount),
rawSourceTx: {},
},
} });
});
const burnTransactionListener = (context) => (callback, _receive) => {
const cleaners = [];
burnAndRelease(context).then((burn) => __awaiter(void 0, void 0, void 0, function* () {
let confirmations = 0;
const tx = Object.values(context.tx.transactions)[0];
const burnRef = burn.burn();
const burnListener = (confs) => {
confirmations = confs;
callback({
type: "CONFIRMATION",
data: Object.assign(Object.assign({}, tx), { sourceTxConfs: confs }),
});
};
cleaners.push(() => {
burnRef._cancel();
burnRef.removeListener("confirmation", burnListener);
});
yield (burnRef === null || burnRef === void 0 ? void 0 : burnRef.on("confirmation", burnListener).catch((error) => callback({ type: "BURN_ERROR", data: error })));
const releaseListener = (status) => status === "confirming"
? console.log(`confirming (${confirmations}/15)`)
: console.log(status);
const hashListener = (hash) => console.log("hash", hash);
const releaseRef = burn.release();
cleaners.push(() => {
releaseRef._cancel();
releaseRef.removeListener("status", releaseListener);
releaseRef.removeListener("txHash", hashListener);
});
yield releaseRef
.on("status", releaseListener)
.on("txHash", hashListener)
.catch((error) => callback({ type: "RELEASE_ERROR", data: error }));
}));
return () => {
for (let i of cleaners) {
i();
}
};
};
exports.burnConfig = {
services: {
burnCreator: txCreator,
burnListener: burnTransactionListener,
},
};